[Spice-commits] 468 commits - .gitignore .mailmap LICENSE MAINTAINERS Makefile Makefile.objs VERSION aio-posix.c aio-win32.c arch_init.c async.c audio/audio.c audio/noaudio.c audio/spiceaudio.c audio/wavaudio.c backends/baum.c block.c block/Makefile.objs block/backup.c block/blkdebug.c block/commit.c block/curl.c block/gluster.c block/iscsi.c block/linux-aio.c block/mirror.c block/nbd.c block/qcow2-cache.c block/qcow2-cluster.c block/qcow2-refcount.c block/qcow2-snapshot.c block/qcow2.c block/qcow2.h block/qed.c block/raw.c block/raw_bsd.c block/rbd.c block/sheepdog.c block/ssh.c block/stream.c block/vmdk.c block/win32-aio.c blockdev.c blockjob.c configure cpu-exec.c cpus.c cputlb.c default-configs/arm-softmmu.mak default-configs/i386-softmmu.mak default-configs/mips-softmmu.mak default-configs/mips64-softmmu.mak default-configs/mips64el-softmmu.mak default-configs/mipsel-softmmu.mak default-configs/x86_64-softmmu.mak disas.c disas/ppc.c dma-helpers.c docs/q35-chipset.cfg docs/specs dump.c exec.c gdbstub.c hmp-commands.hx hmp.c hw/9pfs hw/acpi hw/alpha hw/arm hw/audio hw/block hw/bt hw/char hw/core hw/cpu hw/cris hw/display hw/dma hw/i386 hw/ide hw/input hw/intc hw/isa hw/lm32 hw/m68k hw/microblaze hw/mips hw/misc hw/net hw/nvram hw/openrisc hw/pci hw/pci-bridge hw/pci-host hw/ppc hw/s390x hw/scsi hw/sd hw/sh4 hw/sparc hw/sparc64 hw/timer hw/tpm hw/unicore32 hw/usb hw/virtio hw/watchdog hw/xtensa include/block include/elf.h include/exec include/hw include/monitor include/qapi include/qemu include/qom include/sysemu include/ui ioport.c kvm-all.c kvm-stub.c libcacard/card_7816.c libcacard/card_7816t.h linux-headers/asm-powerpc linux-user/elfload.c linux-user/main.c linux-user/syscall.c main-loop.c memory.c memory_mapping.c migration-exec.c migration-fd.c migration-rdma.c migration-tcp.c migration-unix.c migration.c monitor.c nbd.c net/dump.c net/net.c net/socket.c pc-bios/README pc-bios/openbios-ppc pc-bios/openbios-sparc32 pc-bios/openbios-sparc64 po/de _DE.po po/fr_FR.po po/hu.po po/it.po po/messages.po po/tr.po qapi/opts-visitor.c qemu-char.c qemu-coroutine-io.c qemu-coroutine-sleep.c qemu-img.c qemu-io-cmds.c qemu-io.c qemu-nbd.c qemu-timer.c qmp-commands.hx qom/cpu.c qom/object.c qtest.c readline.c roms/openbios savevm.c scripts/disas-objdump.pl scripts/qapi-types.py scripts/qapi.py scripts/switch-timer-api slirp/arp_table.c slirp/if.c slirp/misc.c slirp/slirp.c slirp/socket.c stubs/clock-warp.c stubs/dump.c target-alpha/helper.h target-alpha/sys_helper.c target-alpha/translate.c target-arm/cpu-qom.h target-arm/cpu.c target-arm/cpu.h target-arm/helper.c target-arm/machine.c target-arm/translate.c target-cris/translate.c target-i386/Makefile.objs target-i386/arch_dump.c target-i386/cpu-qom.h target-i386/cpu.c target-i386/cpu.h target-i386/helper.c target-i386/hyperv.c target-i386/hyperv.h target-i386/kvm.c target-i386/machine.c target-i386/misc_helper.c target-i386/translate.c target-lm32/op_helper.c target-lm32/translat e.c target-m68k/translate.c target-microblaze/translate.c target-mips/helper.c target-mips/op_helper.c target-mips/translate.c target-mips/translate_init.c target-moxie/helper.c target-moxie/translate.c target-openrisc/translate.c target-ppc/cpu-models.c target-ppc/cpu-models.h target-ppc/cpu.h target-ppc/excp_helper.c target-ppc/kvm.c target-ppc/kvm_ppc.c target-ppc/mmu_helper.c target-ppc/translate.c target-ppc/translate_init.c target-s390x/Makefile.objs target-s390x/arch_dump.c target-s390x/cpu-qom.h target-s390x/cpu.c target-s390x/cpu.h target-s390x/ioinst.c target-s390x/kvm.c target-s390x/misc_helper.c target-s390x/translate.c target-sh4/translate.c target-sparc/translate.c target-unicore32/op_helper.c target-unicore32/translate.c target-xtensa/cpu.h target-xtensa/op_helper.c target-xtensa/translate.c tcg/aarch64 tcg/arm tcg/hppa tcg/i386 tcg/ia64 tcg/mips tcg/optimize.c tcg/ppc tcg/ppc64 tcg/s390 tcg/sparc tcg/tcg-op.h tcg/tcg-opc.h tcg/tcg.c tcg/tcg.h tcg/tci tci.c te sts/.gitignore tests/Makefile tests/libqtest.h tests/qapi-schema tests/qemu-iotests tests/tcg tests/test-aio.c tests/test-opts-visitor.c tests/test-qdev-global-props.c tests/test-thread-pool.c thread-pool.c trace-events translate-all.c ui/console.c ui/gtk.c ui/input.c ui/spice-core.c ui/vnc-auth-sasl.h ui/vnc-auth-vencrypt.c ui/vnc-ws.c util/iov.c util/qemu-option.c util/qemu-thread-posix.c version.rc vl.c xen-all.c

Gerd Hoffmann kraxel at kemper.freedesktop.org
Tue Sep 10 02:58:25 PDT 2013


 .gitignore                                  |    3 
 .mailmap                                    |    3 
 LICENSE                                     |   15 
 MAINTAINERS                                 |   19 
 Makefile                                    |    9 
 Makefile.objs                               |    5 
 VERSION                                     |    2 
 aio-posix.c                                 |   54 -
 aio-win32.c                                 |   57 +
 arch_init.c                                 |   30 -
 async.c                                     |   24 
 audio/audio.c                               |    6 
 audio/noaudio.c                             |    4 
 audio/spiceaudio.c                          |    4 
 audio/wavaudio.c                            |    2 
 backends/baum.c                             |   16 
 block.c                                     |   96 ++-
 block/Makefile.objs                         |    2 
 block/backup.c                              |    6 
 block/blkdebug.c                            |    1 
 block/commit.c                              |    2 
 block/curl.c                                |   31 -
 block/gluster.c                             |   36 -
 block/iscsi.c                               |   28 
 block/linux-aio.c                           |   18 
 block/mirror.c                              |   10 
 block/nbd.c                                 |   18 
 block/qcow2-cache.c                         |   17 
 block/qcow2-cluster.c                       |   25 
 block/qcow2-refcount.c                      |  533 ++++++++++++++++-
 block/qcow2-snapshot.c                      |   22 
 block/qcow2.c                               |   88 ++
 block/qcow2.h                               |   53 +
 block/qed.c                                 |   10 
 block/raw.c                                 |  169 -----
 block/raw_bsd.c                             |  186 ++++++
 block/rbd.c                                 |   16 
 block/sheepdog.c                            |   35 -
 block/ssh.c                                 |   12 
 block/stream.c                              |    8 
 block/vmdk.c                                |  151 +++--
 block/win32-aio.c                           |   10 
 blockdev.c                                  |   19 
 blockjob.c                                  |    4 
 configure                                   |  150 +++--
 cpu-exec.c                                  |    4 
 cpus.c                                      |  224 ++++---
 cputlb.c                                    |    2 
 default-configs/arm-softmmu.mak             |    4 
 default-configs/i386-softmmu.mak            |    1 
 default-configs/mips-softmmu.mak            |    1 
 default-configs/mips64-softmmu.mak          |    1 
 default-configs/mips64el-softmmu.mak        |    1 
 default-configs/mipsel-softmmu.mak          |    1 
 default-configs/x86_64-softmmu.mak          |    1 
 disas.c                                     |   47 +
 disas/ppc.c                                 |    3 
 dma-helpers.c                               |    1 
 docs/q35-chipset.cfg                        |   23 
 docs/specs/qcow2.txt                        |    7 
 dump.c                                      |  179 +++---
 exec.c                                      |   50 -
 gdbstub.c                                   |   20 
 hmp-commands.hx                             |    6 
 hmp.c                                       |    8 
 hw/9pfs/virtio-9p-device.c                  |    3 
 hw/acpi/core.c                              |    8 
 hw/acpi/piix4.c                             |   22 
 hw/alpha/dp264.c                            |    1 
 hw/alpha/typhoon.c                          |  204 +++++-
 hw/arm/Makefile.objs                        |    2 
 hw/arm/armv7m.c                             |    5 
 hw/arm/boot.c                               |    2 
 hw/arm/collie.c                             |    1 
 hw/arm/exynos4210.c                         |   16 
 hw/arm/exynos4_boards.c                     |    2 
 hw/arm/gumstix.c                            |    2 
 hw/arm/highbank.c                           |    6 
 hw/arm/integratorcp.c                       |    8 
 hw/arm/kzm.c                                |    9 
 hw/arm/mainstone.c                          |    1 
 hw/arm/musicpal.c                           |    5 
 hw/arm/nseries.c                            |    6 
 hw/arm/omap1.c                              |   60 +-
 hw/arm/omap2.c                              |    8 
 hw/arm/omap_sx1.c                           |    2 
 hw/arm/palm.c                               |    1 
 hw/arm/pic_cpu.c                            |   68 --
 hw/arm/pxa2xx.c                             |   63 +-
 hw/arm/realview.c                           |    8 
 hw/arm/spitz.c                              |   10 
 hw/arm/stellaris.c                          |   12 
 hw/arm/strongarm.c                          |   40 -
 hw/arm/tosa.c                               |    1 
 hw/arm/versatilepb.c                        |    9 
 hw/arm/vexpress.c                           |   10 
 hw/arm/xilinx_zynq.c                        |    8 
 hw/arm/z2.c                                 |    1 
 hw/audio/adlib.c                            |    4 
 hw/audio/intel-hda.c                        |   10 
 hw/audio/intel-hda.h                        |    2 
 hw/audio/sb16.c                             |    6 
 hw/block/Makefile.objs                      |    1 
 hw/block/dataplane/virtio-blk.c             |   25 
 hw/block/fdc.c                              |    6 
 hw/block/nvme.c                             |   20 
 hw/block/pc_sysfw.c                         |  308 ----------
 hw/block/pflash_cfi01.c                     |    2 
 hw/block/pflash_cfi02.c                     |   12 
 hw/bt/hci-csr.c                             |    4 
 hw/bt/hci.c                                 |   38 -
 hw/bt/l2cap.c                               |    8 
 hw/char/cadence_uart.c                      |   12 
 hw/char/ipack.c                             |    5 
 hw/char/ipack.h                             |    3 
 hw/char/sclpconsole.c                       |   18 
 hw/char/serial.c                            |   27 
 hw/char/spapr_vty.c                         |    2 
 hw/char/tpci200.c                           |    2 
 hw/char/virtio-console.c                    |    1 
 hw/char/virtio-serial-bus.c                 |   14 
 hw/core/loader.c                            |   56 +
 hw/core/null-machine.c                      |    1 
 hw/core/ptimer.c                            |   18 
 hw/core/qdev-properties.c                   |   20 
 hw/core/qdev.c                              |   15 
 hw/core/sysbus.c                            |    4 
 hw/cpu/Makefile.objs                        |    4 
 hw/cpu/a15mpcore.c                          |   17 
 hw/cpu/icc_bus.c                            |    3 
 hw/cris/axis_dev88.c                        |    1 
 hw/display/qxl-logger.c                     |    2 
 hw/display/qxl.c                            |    2 
 hw/display/vga.c                            |    6 
 hw/dma/pl330.c                              |    6 
 hw/dma/rc4030.c                             |    4 
 hw/dma/soc_dma.c                            |    8 
 hw/dma/xilinx_axidma.c                      |    7 
 hw/i386/Makefile.objs                       |    1 
 hw/i386/kvm/apic.c                          |    2 
 hw/i386/kvm/clock.c                         |    2 
 hw/i386/kvm/i8254.c                         |    6 
 hw/i386/kvm/pci-assign.c                    |    9 
 hw/i386/kvmvapic.c                          |    2 
 hw/i386/pc.c                                |   24 
 hw/i386/pc_piix.c                           |  232 +++----
 hw/i386/pc_q35.c                            |   86 +-
 hw/i386/pc_sysfw.c                          |  188 ++++++
 hw/i386/xen_domainbuild.c                   |    6 
 hw/i386/xen_machine_pv.c                    |    1 
 hw/ide/ahci.c                               |    2 
 hw/ide/cmd646.c                             |    2 
 hw/ide/core.c                               |    6 
 hw/ide/internal.h                           |    3 
 hw/ide/isa.c                                |    2 
 hw/ide/macio.c                              |    2 
 hw/ide/mmio.c                               |    2 
 hw/ide/piix.c                               |    2 
 hw/ide/qdev.c                               |    5 
 hw/ide/via.c                                |    2 
 hw/input/hid.c                              |   10 
 hw/input/lm832x.c                           |    8 
 hw/input/tsc2005.c                          |   16 
 hw/input/tsc210x.c                          |   32 -
 hw/intc/apic.c                              |   16 
 hw/intc/apic_common.c                       |    2 
 hw/intc/armv7m_nvic.c                       |   16 
 hw/intc/i8259.c                             |    4 
 hw/intc/xics.c                              |   23 
 hw/isa/i82378.c                             |  215 +------
 hw/lm32/lm32_boards.c                       |    2 
 hw/lm32/milkymist.c                         |    1 
 hw/m68k/an5206.c                            |    1 
 hw/m68k/dummy_m68k.c                        |    1 
 hw/m68k/mcf5208.c                           |    1 
 hw/microblaze/petalogix_ml605_mmu.c         |    1 
 hw/microblaze/petalogix_s3adsp1800_mmu.c    |    1 
 hw/mips/cputimer.c                          |   16 
 hw/mips/mips_fulong2e.c                     |    9 
 hw/mips/mips_jazz.c                         |   10 
 hw/mips/mips_malta.c                        |   54 +
 hw/mips/mips_mipssim.c                      |    8 
 hw/mips/mips_r4k.c                          |    5 
 hw/misc/arm_sysctl.c                        |    2 
 hw/misc/macio/cuda.c                        |   38 -
 hw/misc/macio/macio.c                       |   17 
 hw/misc/pvpanic.c                           |   25 
 hw/misc/vfio.c                              |   18 
 hw/net/dp8393x.c                            |   20 
 hw/net/e1000.c                              |   12 
 hw/net/lan9118.c                            |    4 
 hw/net/pcnet-pci.c                          |    4 
 hw/net/pcnet.c                              |   14 
 hw/net/rtl8139.c                            |   28 
 hw/net/virtio-net.c                         |   20 
 hw/net/xilinx_axienet.c                     |    6 
 hw/nvram/fw_cfg.c                           |    2 
 hw/openrisc/cputimer.c                      |   10 
 hw/openrisc/openrisc_sim.c                  |    4 
 hw/openrisc/pic_cpu.c                       |   17 
 hw/pci-bridge/i82801b11.c                   |    1 
 hw/pci-host/piix.c                          |    9 
 hw/pci-host/prep.c                          |    6 
 hw/pci-host/q35.c                           |   10 
 hw/pci-host/versatile.c                     |    4 
 hw/pci/pci.c                                |   28 
 hw/pci/pci_bridge.c                         |    3 
 hw/pci/pci_host.c                           |   11 
 hw/ppc/e500.c                               |   85 ++
 hw/ppc/e500.h                               |   13 
 hw/ppc/e500plat.c                           |   15 
 hw/ppc/mac_newworld.c                       |    4 
 hw/ppc/mac_oldworld.c                       |    4 
 hw/ppc/mpc8544ds.c                          |   15 
 hw/ppc/ppc.c                                |   66 +-
 hw/ppc/ppc405_boards.c                      |   41 -
 hw/ppc/ppc405_uc.c                          |   24 
 hw/ppc/ppc440_bamboo.c                      |    1 
 hw/ppc/ppc_booke.c                          |   10 
 hw/ppc/prep.c                               |    4 
 hw/ppc/spapr.c                              |   47 +
 hw/ppc/spapr_hcall.c                        |   50 +
 hw/ppc/spapr_iommu.c                        |   71 --
 hw/ppc/spapr_pci.c                          |   73 --
 hw/ppc/spapr_rtas.c                         |   23 
 hw/ppc/virtex_ml507.c                       |   30 -
 hw/s390x/css.c                              |    2 
 hw/s390x/event-facility.c                   |    4 
 hw/s390x/s390-virtio-bus.c                  |   24 
 hw/s390x/s390-virtio-ccw.c                  |   16 
 hw/s390x/s390-virtio.c                      |    1 
 hw/s390x/virtio-ccw.c                       |   26 
 hw/scsi/esp-pci.c                           |    2 
 hw/scsi/esp.c                               |    2 
 hw/scsi/lsi53c895a.c                        |    2 
 hw/scsi/megasas.c                           |    3 
 hw/scsi/scsi-bus.c                          |    6 
 hw/scsi/spapr_vscsi.c                       |    3 
 hw/scsi/virtio-scsi.c                       |    3 
 hw/scsi/vmw_pvscsi.c                        |    3 
 hw/sd/sdhci.c                               |   28 
 hw/sh4/r2d.c                                |    1 
 hw/sh4/shix.c                               |    1 
 hw/sparc/leon3.c                            |    1 
 hw/sparc/sun4m.c                            |  131 +---
 hw/sparc64/sun4u.c                          |   82 +-
 hw/timer/arm_mptimer.c                      |   12 
 hw/timer/arm_timer.c                        |    1 
 hw/timer/cadence_ttc.c                      |    6 
 hw/timer/etraxfs_timer.c                    |    2 
 hw/timer/exynos4210_mct.c                   |    3 
 hw/timer/exynos4210_pwm.c                   |    1 
 hw/timer/exynos4210_rtc.c                   |    4 
 hw/timer/grlib_gptimer.c                    |    2 
 hw/timer/hpet.c                             |   20 
 hw/timer/i8254.c                            |   26 
 hw/timer/i8254_common.c                     |    4 
 hw/timer/imx_epit.c                         |   95 +--
 hw/timer/imx_gpt.c                          |    1 
 hw/timer/lm32_timer.c                       |    1 
 hw/timer/m48t59.c                           |   18 
 hw/timer/mc146818rtc.c                      |   50 -
 hw/timer/omap_gptimer.c                     |   24 
 hw/timer/omap_synctimer.c                   |    2 
 hw/timer/pl031.c                            |   19 
 hw/timer/puv3_ost.c                         |    1 
 hw/timer/pxa2xx_timer.c                     |   34 -
 hw/timer/sh_timer.c                         |    1 
 hw/timer/slavio_timer.c                     |    1 
 hw/timer/tusb6010.c                         |   12 
 hw/timer/twl92230.c                         |   14 
 hw/timer/xilinx_timer.c                     |    1 
 hw/tpm/tpm_tis.c                            |    1 
 hw/unicore32/puv3.c                         |    1 
 hw/usb/bus.c                                |    5 
 hw/usb/core.c                               |    7 
 hw/usb/dev-hid.c                            |    2 
 hw/usb/dev-hub.c                            |    7 
 hw/usb/dev-smartcard-reader.c               |    3 
 hw/usb/dev-storage.c                        |    6 
 hw/usb/dev-uas.c                            |   18 
 hw/usb/hcd-ehci.c                           |   12 
 hw/usb/hcd-musb.c                           |    8 
 hw/usb/hcd-ohci.c                           |  191 ++++--
 hw/usb/hcd-uhci.c                           |   24 
 hw/usb/hcd-xhci.c                           |  117 ++-
 hw/usb/host-libusb.c                        |    6 
 hw/usb/host-linux.c                         |    6 
 hw/usb/redirect.c                           |   17 
 hw/virtio/dataplane/vring.c                 |    1 
 hw/virtio/vhost.c                           |    1 
 hw/virtio/virtio-balloon.c                  |    8 
 hw/virtio/virtio-mmio.c                     |   13 
 hw/virtio/virtio-pci.c                      |   31 -
 hw/virtio/virtio-rng.c                      |   14 
 hw/virtio/virtio.c                          |   19 
 hw/watchdog/wdt_i6300esb.c                  |    6 
 hw/watchdog/wdt_ib700.c                     |   10 
 hw/xtensa/pic_cpu.c                         |   10 
 hw/xtensa/xtensa_lx60.c                     |    2 
 hw/xtensa/xtensa_sim.c                      |    1 
 include/block/aio.h                         |   64 +-
 include/block/block.h                       |    1 
 include/block/block_int.h                   |    4 
 include/block/blockjob.h                    |    2 
 include/block/coroutine.h                   |    3 
 include/elf.h                               |    6 
 include/exec/exec-all.h                     |  100 +--
 include/exec/gen-icount.h                   |    4 
 include/exec/ioport.h                       |    4 
 include/exec/softmmu_defs.h                 |   37 -
 include/exec/softmmu_exec.h                 |    3 
 include/exec/softmmu_template.h             |  371 +++++-------
 include/hw/acpi/acpi.h                      |    2 
 include/hw/arm/arm.h                        |    5 
 include/hw/boards.h                         |    7 
 include/hw/bt.h                             |    8 
 include/hw/i386/pc.h                        |   23 
 include/hw/isa/isa.h                        |    2 
 include/hw/loader.h                         |    1 
 include/hw/pci-host/spapr.h                 |    8 
 include/hw/pci/pci.h                        |    3 
 include/hw/ppc/spapr.h                      |   21 
 include/hw/qdev-core.h                      |    2 
 include/hw/scsi/scsi.h                      |    4 
 include/hw/usb.h                            |    3 
 include/hw/virtio/virtio.h                  |    1 
 include/monitor/monitor.h                   |    1 
 include/monitor/readline.h                  |    3 
 include/qapi/opts-visitor.h                 |    6 
 include/qemu/option.h                       |    1 
 include/qemu/ratelimit.h                    |    2 
 include/qemu/thread-posix.h                 |    2 
 include/qemu/timer.h                        |  676 ++++++++++++++++++++--
 include/qemu/typedefs.h                     |    3 
 include/qom/cpu.h                           |   22 
 include/qom/object.h                        |   13 
 include/sysemu/char.h                       |    1 
 include/sysemu/dump.h                       |    4 
 include/sysemu/kvm.h                        |    3 
 include/sysemu/memory_mapping.h             |   30 -
 include/sysemu/sysemu.h                     |    3 
 include/ui/qemu-spice.h                     |    2 
 ioport.c                                    |   16 
 kvm-all.c                                   |   60 --
 kvm-stub.c                                  |    3 
 libcacard/card_7816.c                       |    2 
 libcacard/card_7816t.h                      |    2 
 linux-headers/asm-powerpc/epapr_hcalls.h    |    4 
 linux-user/elfload.c                        |    2 
 linux-user/main.c                           |   10 
 linux-user/syscall.c                        |   17 
 main-loop.c                                 |   66 +-
 memory.c                                    |    3 
 memory_mapping.c                            |  128 +++-
 migration-exec.c                            |    1 
 migration-fd.c                              |    1 
 migration-rdma.c                            |  387 +++++++++---
 migration-tcp.c                             |    1 
 migration-unix.c                            |    1 
 migration.c                                 |   22 
 monitor.c                                   |  481 ++++++++++------
 nbd.c                                       |    1 
 net/dump.c                                  |    2 
 net/net.c                                   |    1 
 net/socket.c                                |    1 
 pc-bios/README                              |    4 
 pc-bios/openbios-ppc                        |binary
 pc-bios/openbios-sparc32                    |binary
 pc-bios/openbios-sparc64                    |binary
 po/de_DE.po                                 |   36 -
 po/fr_FR.po                                 |   36 -
 po/hu.po                                    |   36 -
 po/it.po                                    |   36 -
 po/messages.po                              |   40 -
 po/tr.po                                    |   36 -
 qapi/opts-visitor.c                         |  184 +++++-
 qemu-char.c                                 |   56 +
 qemu-coroutine-io.c                         |    1 
 qemu-coroutine-sleep.c                      |   10 
 qemu-img.c                                  |   21 
 qemu-io-cmds.c                              |    1 
 qemu-io.c                                   |    4 
 qemu-nbd.c                                  |    1 
 qemu-timer.c                                |  834 +++++++++-------------------
 qmp-commands.hx                             |   38 -
 qom/cpu.c                                   |   32 -
 qom/object.c                                |   23 
 qtest.c                                     |   18 
 readline.c                                  |    5 
 roms/openbios                               |    2 
 savevm.c                                    |   24 
 scripts/disas-objdump.pl                    |   99 +++
 scripts/qapi-types.py                       |   19 
 scripts/qapi.py                             |    2 
 scripts/switch-timer-api                    |  178 +++++
 slirp/arp_table.c                           |    4 
 slirp/if.c                                  |    2 
 slirp/misc.c                                |    1 
 slirp/slirp.c                               |    4 
 slirp/socket.c                              |    2 
 stubs/clock-warp.c                          |    2 
 stubs/dump.c                                |    3 
 target-alpha/helper.h                       |    2 
 target-alpha/sys_helper.c                   |   29 
 target-alpha/translate.c                    |   88 ++
 target-arm/cpu-qom.h                        |    9 
 target-arm/cpu.c                            |   67 ++
 target-arm/cpu.h                            |   27 
 target-arm/helper.c                         |  310 ++++++++++
 target-arm/machine.c                        |    8 
 target-arm/translate.c                      |   22 
 target-cris/translate.c                     |    2 
 target-i386/Makefile.objs                   |    2 
 target-i386/arch_dump.c                     |   10 
 target-i386/cpu-qom.h                       |    4 
 target-i386/cpu.c                           |  208 ++++++
 target-i386/cpu.h                           |  185 +++---
 target-i386/helper.c                        |    3 
 target-i386/hyperv.c                        |   64 --
 target-i386/hyperv.h                        |   45 -
 target-i386/kvm.c                           |  175 +++++
 target-i386/machine.c                       |   66 ++
 target-i386/misc_helper.c                   |    2 
 target-i386/translate.c                     |    2 
 target-lm32/op_helper.c                     |    2 
 target-lm32/translate.c                     |    2 
 target-m68k/translate.c                     |    2 
 target-microblaze/translate.c               |    2 
 target-mips/helper.c                        |    2 
 target-mips/op_helper.c                     |   10 
 target-mips/translate.c                     |   62 +-
 target-mips/translate_init.c                |    7 
 target-moxie/helper.c                       |    1 
 target-moxie/translate.c                    |    2 
 target-openrisc/translate.c                 |    2 
 target-ppc/cpu-models.c                     |   13 
 target-ppc/cpu-models.h                     |    4 
 target-ppc/cpu.h                            |    2 
 target-ppc/excp_helper.c                    |   12 
 target-ppc/kvm.c                            |    8 
 target-ppc/kvm_ppc.c                        |    7 
 target-ppc/mmu_helper.c                     |    4 
 target-ppc/translate.c                      |    6 
 target-ppc/translate_init.c                 |  111 +++
 target-s390x/Makefile.objs                  |    2 
 target-s390x/arch_dump.c                    |  213 +++++++
 target-s390x/cpu-qom.h                      |   11 
 target-s390x/cpu.c                          |   58 +
 target-s390x/cpu.h                          |   20 
 target-s390x/ioinst.c                       |   65 +-
 target-s390x/kvm.c                          |  104 +--
 target-s390x/misc_helper.c                  |   76 ++
 target-s390x/translate.c                    |    8 
 target-sh4/translate.c                      |    2 
 target-sparc/translate.c                    |    2 
 target-unicore32/op_helper.c                |    2 
 target-unicore32/translate.c                |    2 
 target-xtensa/cpu.h                         |    4 
 target-xtensa/op_helper.c                   |    8 
 target-xtensa/translate.c                   |   69 +-
 tcg/aarch64/tcg-target.c                    |    8 
 tcg/aarch64/tcg-target.h                    |    7 
 tcg/arm/tcg-target.c                        |   14 
 tcg/arm/tcg-target.h                        |   11 
 tcg/hppa/tcg-target.c                       |   16 
 tcg/hppa/tcg-target.h                       |    9 
 tcg/i386/tcg-target.c                       |  363 +++++-------
 tcg/i386/tcg-target.h                       |   17 
 tcg/ia64/tcg-target.c                       |   21 
 tcg/ia64/tcg-target.h                       |    7 
 tcg/mips/tcg-target.c                       |  247 +++++---
 tcg/mips/tcg-target.h                       |   59 +
 tcg/optimize.c                              |   43 +
 tcg/ppc/tcg-target.c                        |   12 
 tcg/ppc/tcg-target.h                        |    4 
 tcg/ppc64/tcg-target.c                      |   45 -
 tcg/ppc64/tcg-target.h                      |    8 
 tcg/s390/tcg-target.c                       |   13 
 tcg/s390/tcg-target.h                       |    7 
 tcg/sparc/tcg-target.c                      |   12 
 tcg/sparc/tcg-target.h                      |   24 
 tcg/tcg-op.h                                |   42 +
 tcg/tcg-opc.h                               |    4 
 tcg/tcg.c                                   |  113 ++-
 tcg/tcg.h                                   |  114 ++-
 tcg/tci/tcg-target.c                        |   16 
 tcg/tci/tcg-target.h                        |   18 
 tci.c                                       |    4 
 tests/.gitignore                            |    1 
 tests/Makefile                              |   13 
 tests/libqtest.h                            |   24 
 tests/qapi-schema/qapi-schema-test.json     |   15 
 tests/qapi-schema/qapi-schema-test.out      |    6 
 tests/qemu-iotests/031.out                  |   12 
 tests/qemu-iotests/036.out                  |    2 
 tests/qemu-iotests/051.out                  |   65 +-
 tests/qemu-iotests/059                      |   72 ++
 tests/qemu-iotests/059.out                  |   20 
 tests/qemu-iotests/060                      |  111 +++
 tests/qemu-iotests/060.out                  |   44 +
 tests/qemu-iotests/062                      |   64 ++
 tests/qemu-iotests/062.out                  |    9 
 tests/qemu-iotests/common.filter            |    3 
 tests/qemu-iotests/common.rc                |    6 
 tests/qemu-iotests/group                    |    3 
 tests/tcg/mips/mips32-dsp/dpsq_s_w_ph.c     |   10 
 tests/tcg/mips/mips32-dsp/maq_s_w_phl.c     |   16 
 tests/tcg/mips/mips32-dsp/maq_s_w_phr.c     |   24 
 tests/tcg/mips/mips32-dspr2/dpaqx_sa_w_ph.c |   12 
 tests/tcg/mips/mips32-dspr2/dpsqx_s_w_ph.c  |    8 
 tests/tcg/xtensa/Makefile                   |   21 
 tests/tcg/xtensa/test_extui.S               |   26 
 tests/test-aio.c                            |  214 +++++--
 tests/test-opts-visitor.c                   |  275 +++++++++
 tests/test-qdev-global-props.c              |  180 ++++++
 tests/test-thread-pool.c                    |   27 
 thread-pool.c                               |   12 
 trace-events                                |   13 
 translate-all.c                             |    4 
 ui/console.c                                |   30 -
 ui/gtk.c                                    |    4 
 ui/input.c                                  |    6 
 ui/spice-core.c                             |   15 
 ui/vnc-auth-sasl.h                          |    1 
 ui/vnc-auth-vencrypt.c                      |    2 
 ui/vnc-ws.c                                 |    1 
 util/iov.c                                  |    6 
 util/qemu-option.c                          |   18 
 util/qemu-thread-posix.c                    |   28 
 version.rc                                  |    2 
 vl.c                                        |   29 
 xen-all.c                                   |   12 
 533 files changed, 10620 insertions(+), 5880 deletions(-)

New commits:
commit 94c2b6aff43cdfcfdfb552773a6b6b973a72ef0b
Author: Paul Burton <paul.burton at imgtec.com>
Date:   Fri Sep 6 13:57:44 2013 +0100

    mips_malta: support up to 2GiB RAM
    
    A Malta board can support up to 2GiB of RAM. Since the unmapped kseg0/1
    regions are only 512MiB large & the latter 256MiB of those are taken up
    by the IO region, access to RAM beyond 256MiB must be done through a
    mapped region. In the case of a Linux guest this means we need to use
    highmem.
    
    The mainline Linux kernel does not support highmem for Malta at this
    time, however this can be tested using the linux-mti-3.8 kernel branch
    available from:
    
      git://git.linux-mips.org/pub/scm/linux-mti.git
    
    You should be able to boot a Linux kernel built from the linux-mti-3.8
    branch, with CONFIG_HIGHMEM enabled, using 2GiB RAM by passing "-m 2G"
    to QEMU and appending the following kernel parameters:
    
      mem=256m at 0x0 mem=256m at 0x90000000 mem=1536m at 0x20000000
    
    Note that the upper half of the physical address space of a Malta
    mirrors the lower half (hence the 2GiB limit) except that the IO region
    (0x10000000-0x1fffffff in the lower half) is not mirrored in the upper
    half. That is, physical addresses 0x90000000-0x9fffffff access RAM
    rather than the IO region, resulting in a physical address space
    resembling the following:
    
      0x00000000 -> 0x0fffffff  RAM
      0x10000000 -> 0x1fffffff  I/O
      0x20000000 -> 0x7fffffff  RAM
      0x80000000 -> 0x8fffffff  RAM (mirror of 0x00000000 -> 0x0fffffff)
      0x90000000 -> 0x9fffffff  RAM
      0xa0000000 -> 0xffffffff  RAM (mirror of 0x20000000 -> 0x7fffffff)
    
    The second mem parameter provided to the kernel above accesses the
    second 256MiB of RAM through the upper half of the physical address
    space, making use of the aliasing described above in order to avoid
    the IO region and use the whole 2GiB RAM.
    
    The memory setup may be seen as 'backwards' in this commit since the
    'real' memory is mapped in the upper half of the physical address space
    and the lower half contains the aliases. On real hardware it would be
    typical to see the upper half of the physical address space as the alias
    since the bus addresses generated match the lower half of the physical
    address space. However since the memory accessible in the upper half of
    the physical address space is uninterrupted by the IO region it is
    easiest to map the RAM as a whole there, and functionally it makes no
    difference to the target code.
    
    Due to the requirements of accessing the second 256MiB of RAM through
    a mapping to the upper half of the physical address space it is usual
    for the bootloader to indicate a maximum of 256MiB memory to a kernel.
    This allows kernels which do not support such access to boot on systems
    with more than 256MiB of RAM. It is also the behaviour assumed by Linux.
    QEMUs small generated bootloader is modified to provide this behaviour.
    
    Signed-off-by: Paul Burton <paul.burton at imgtec.com>
    Signed-off-by: Yongbok Kim <yongbok.kim at imgtec.com>
    Reviewed-by: Aurelien Jarno <aurelien at aurel32.net>
    Signed-off-by: Aurelien Jarno <aurelien at aurel32.net>

diff --git a/hw/mips/mips_malta.c b/hw/mips/mips_malta.c
index ae0921c..05c8771 100644
--- a/hw/mips/mips_malta.c
+++ b/hw/mips/mips_malta.c
@@ -827,7 +827,8 @@ static int64_t load_kernel (void)
     }
 
     prom_set(prom_buf, prom_index++, "memsize");
-    prom_set(prom_buf, prom_index++, "%i", loaderparams.ram_size);
+    prom_set(prom_buf, prom_index++, "%i",
+             MIN(loaderparams.ram_size, 256 << 20));
     prom_set(prom_buf, prom_index++, "modetty0");
     prom_set(prom_buf, prom_index++, "38400n8r");
     prom_set(prom_buf, prom_index++, NULL);
@@ -884,7 +885,9 @@ void mips_malta_init(QEMUMachineInitArgs *args)
     char *filename;
     pflash_t *fl;
     MemoryRegion *system_memory = get_system_memory();
-    MemoryRegion *ram = g_new(MemoryRegion, 1);
+    MemoryRegion *ram_high = g_new(MemoryRegion, 1);
+    MemoryRegion *ram_low_preio = g_new(MemoryRegion, 1);
+    MemoryRegion *ram_low_postio;
     MemoryRegion *bios, *bios_copy = g_new(MemoryRegion, 1);
     target_long bios_size = FLASH_SIZE;
     const size_t smbus_eeprom_size = 8 * 256;
@@ -951,15 +954,32 @@ void mips_malta_init(QEMUMachineInitArgs *args)
     env = &cpu->env;
 
     /* allocate RAM */
-    if (ram_size > (256 << 20)) {
+    if (ram_size > (2048u << 20)) {
         fprintf(stderr,
-                "qemu: Too much memory for this machine: %d MB, maximum 256 MB\n",
+                "qemu: Too much memory for this machine: %d MB, maximum 2048 MB\n",
                 ((unsigned int)ram_size / (1 << 20)));
         exit(1);
     }
-    memory_region_init_ram(ram, NULL, "mips_malta.ram", ram_size);
-    vmstate_register_ram_global(ram);
-    memory_region_add_subregion(system_memory, 0, ram);
+
+    /* register RAM at high address where it is undisturbed by IO */
+    memory_region_init_ram(ram_high, NULL, "mips_malta.ram", ram_size);
+    vmstate_register_ram_global(ram_high);
+    memory_region_add_subregion(system_memory, 0x80000000, ram_high);
+
+    /* alias for pre IO hole access */
+    memory_region_init_alias(ram_low_preio, NULL, "mips_malta_low_preio.ram",
+                             ram_high, 0, MIN(ram_size, (256 << 20)));
+    memory_region_add_subregion(system_memory, 0, ram_low_preio);
+
+    /* alias for post IO hole access, if there is enough RAM */
+    if (ram_size > (512 << 20)) {
+        ram_low_postio = g_new(MemoryRegion, 1);
+        memory_region_init_alias(ram_low_postio, NULL,
+                                 "mips_malta_low_postio.ram",
+                                 ram_high, 512 << 20,
+                                 ram_size - (512 << 20));
+        memory_region_add_subregion(system_memory, 512 << 20, ram_low_postio);
+    }
 
     /* generate SPD EEPROM data */
     generate_eeprom_spd(&smbus_eeprom_buf[0 * 256], ram_size);
@@ -992,7 +1012,7 @@ void mips_malta_init(QEMUMachineInitArgs *args)
     fl_idx++;
     if (kernel_filename) {
         /* Write a small bootloader to the flash location. */
-        loaderparams.ram_size = ram_size;
+        loaderparams.ram_size = MIN(ram_size, 256 << 20);
         loaderparams.kernel_filename = kernel_filename;
         loaderparams.kernel_cmdline = kernel_cmdline;
         loaderparams.initrd_filename = initrd_filename;
commit df7131623daf4823e087eb1128f6c1c351519774
Merge: 863a834 2641689
Author: Anthony Liguori <anthony at codemonkey.ws>
Date:   Thu Sep 5 13:38:53 2013 -0500

    Merge remote-tracking branch 'bonzini/iommu-for-anthony' into staging
    
    # By Jan Kiszka (2) and others
    # Via Paolo Bonzini
    * bonzini/iommu-for-anthony:
      exec: do tcg_commit only when tcg_enabled
      Revert "memory: Return -1 again on reads from unsigned regions"
      memory: Provide separate handling of unassigned io ports accesses
      exec: check offset_within_address_space for register subpage
      exec: fix writing to MMIO area with non-power-of-two length
    
    Message-id: 1378401455-583-1-git-send-email-pbonzini at redhat.com

commit 2641689a37144b201814f39046e36eb285498cbe
Author: liguang <lig.fnst at cn.fujitsu.com>
Date:   Wed Sep 4 14:37:33 2013 +0800

    exec: do tcg_commit only when tcg_enabled
    
    Signed-off-by: liguang <lig.fnst at cn.fujitsu.com>
    Signed-off-by: Paolo Bonzini <pbonzini at redhat.com>

diff --git a/exec.c b/exec.c
index 3859b02..030118e 100644
--- a/exec.c
+++ b/exec.c
@@ -1810,7 +1810,9 @@ static void memory_map_init(void)
     address_space_init(&address_space_io, system_io, "I/O");
 
     memory_listener_register(&core_memory_listener, &address_space_memory);
-    memory_listener_register(&tcg_memory_listener, &address_space_memory);
+    if (tcg_enabled()) {
+        memory_listener_register(&tcg_memory_listener, &address_space_memory);
+    }
 }
 
 MemoryRegion *get_system_memory(void)
commit 68a7439a150d6b4da99082ab454b9328b151bc25
Author: Jan Kiszka <jan.kiszka at siemens.com>
Date:   Mon Sep 2 18:43:31 2013 +0200

    Revert "memory: Return -1 again on reads from unsigned regions"
    
    This reverts commit 9b8c69243585a32d14b9bb9fcd52c37b0b5a1b71.
    
    The commit was wrong: We only return -1 on invalid accesses, not on
    valid but unbacked ones. This broke various corner cases.
    
    Cc: qemu-stable at nongnu.org
    Signed-off-by: Jan Kiszka <jan.kiszka at siemens.com>
    Signed-off-by: Paolo Bonzini <pbonzini at redhat.com>

diff --git a/memory.c b/memory.c
index 886f838..5a10fd0 100644
--- a/memory.c
+++ b/memory.c
@@ -872,7 +872,7 @@ static uint64_t unassigned_mem_read(void *opaque, hwaddr addr,
     if (current_cpu != NULL) {
         cpu_unassigned_access(current_cpu, addr, false, false, 0, size);
     }
-    return -1ULL;
+    return 0;
 }
 
 static void unassigned_mem_write(void *opaque, hwaddr addr,
commit 3bb28b7208b349e7a1b326e3c6ef9efac1d462bf
Author: Jan Kiszka <jan.kiszka at siemens.com>
Date:   Mon Sep 2 18:43:30 2013 +0200

    memory: Provide separate handling of unassigned io ports accesses
    
    Accesses to unassigned io ports shall return -1 on read and be ignored
    on write. Ensure these properties via dedicated ops, decoupling us from
    the memory core's handling of unassigned accesses.
    
    Cc: qemu-stable at nongnu.org
    Signed-off-by: Jan Kiszka <jan.kiszka at siemens.com>
    Signed-off-by: Paolo Bonzini <pbonzini at redhat.com>

diff --git a/exec.c b/exec.c
index e6f04d8..3859b02 100644
--- a/exec.c
+++ b/exec.c
@@ -1805,7 +1805,8 @@ static void memory_map_init(void)
     address_space_init(&address_space_memory, system_memory, "memory");
 
     system_io = g_malloc(sizeof(*system_io));
-    memory_region_init(system_io, NULL, "io", 65536);
+    memory_region_init_io(system_io, NULL, &unassigned_io_ops, NULL, "io",
+                          65536);
     address_space_init(&address_space_io, system_io, "I/O");
 
     memory_listener_register(&core_memory_listener, &address_space_memory);
diff --git a/include/exec/ioport.h b/include/exec/ioport.h
index bdd4e96..b3848be 100644
--- a/include/exec/ioport.h
+++ b/include/exec/ioport.h
@@ -45,6 +45,10 @@ typedef struct MemoryRegionPortio {
 
 #define PORTIO_END_OF_LIST() { }
 
+#ifndef CONFIG_USER_ONLY
+extern const MemoryRegionOps unassigned_io_ops;
+#endif
+
 void cpu_outb(pio_addr_t addr, uint8_t val);
 void cpu_outw(pio_addr_t addr, uint16_t val);
 void cpu_outl(pio_addr_t addr, uint32_t val);
diff --git a/ioport.c b/ioport.c
index 79b7f1a..707cce8 100644
--- a/ioport.c
+++ b/ioport.c
@@ -44,6 +44,22 @@ typedef struct MemoryRegionPortioList {
     MemoryRegionPortio ports[];
 } MemoryRegionPortioList;
 
+static uint64_t unassigned_io_read(void *opaque, hwaddr addr, unsigned size)
+{
+    return -1ULL;
+}
+
+static void unassigned_io_write(void *opaque, hwaddr addr, uint64_t val,
+                                unsigned size)
+{
+}
+
+const MemoryRegionOps unassigned_io_ops = {
+    .read = unassigned_io_read,
+    .write = unassigned_io_write,
+    .endianness = DEVICE_NATIVE_ENDIAN,
+};
+
 void cpu_outb(pio_addr_t addr, uint8_t val)
 {
     LOG_IOPORT("outb: %04"FMT_pioaddr" %02"PRIx8"\n", addr, val);
commit 88266249701032211c1d7449460d063fbc01bf12
Author: Hu Tao <hutao at cn.fujitsu.com>
Date:   Thu Aug 29 18:21:16 2013 +0800

    exec: check offset_within_address_space for register subpage
    
    If offset_within_address_space falls in a page, then we register a
    subpage. So check offset_within_address_space rather than
    offset_within_region.
    
    Cc: qemu-stable at nongnu.org
    Cc: Paolo Bonzini <pbonzini at redhat.com>
    Cc: Richard Henderson <rth at twiddle.net>
    Cc: "Andreas Färber" <afaerber at suse.de>
    Cc: Peter Maydell <peter.maydell at linaro.org>
    Cc: Blue Swirl <blauwirbel at gmail.com>
    Signed-off-by: Hu Tao <hutao at cn.fujitsu.com>
    Signed-off-by: Paolo Bonzini <pbonzini at redhat.com>

diff --git a/exec.c b/exec.c
index b52ec80..e6f04d8 100644
--- a/exec.c
+++ b/exec.c
@@ -854,7 +854,7 @@ static void mem_add(MemoryListener *listener, MemoryRegionSection *section)
         now = remain;
         if (int128_lt(remain.size, page_size)) {
             register_subpage(d, &now);
-        } else if (remain.offset_within_region & ~TARGET_PAGE_MASK) {
+        } else if (remain.offset_within_address_space & ~TARGET_PAGE_MASK) {
             now.size = page_size;
             register_subpage(d, &now);
         } else {
commit 098178f2749a63fbbb1a626dcc7d939d5cb2bde7
Author: Paolo Bonzini <pbonzini at redhat.com>
Date:   Mon Jul 29 14:27:39 2013 +0200

    exec: fix writing to MMIO area with non-power-of-two length
    
    The problem is introduced by commit 2332616 (exec: Support 64-bit
    operations in address_space_rw, 2013-07-08).  Before that commit,
    memory_access_size would only return 1/2/4.
    
    Since alignment is already handled above, reduce l to the largest
    power of two that is smaller than l.
    
    Cc: qemu-stable at nongnu.org
    Reported-by: Oleksii Shevchuk <alxchk at gmail.com>
    Tested-by: Oleksii Shevchuk <alxchk at gmail.com>
    Signed-off-by: Paolo Bonzini <pbonzini at redhat.com>

diff --git a/exec.c b/exec.c
index 87b0b39..b52ec80 100644
--- a/exec.c
+++ b/exec.c
@@ -1913,6 +1913,9 @@ static int memory_access_size(MemoryRegion *mr, unsigned l, hwaddr addr)
     if (l > access_size_max) {
         l = access_size_max;
     }
+    if (l & (l - 1)) {
+        l = 1 << (qemu_fls(l) - 1);
+    }
 
     return l;
 }
commit 863a83415750a2ee75ac1fb31405c11e71bf990b
Author: Anthony Liguori <anthony at codemonkey.ws>
Date:   Thu Sep 5 09:40:02 2013 -0500

    Update mailmap
    
    This makes get_maintainers.pl behave a little better.
    
    Reported-by: Peter Maydell <peter.maydell at linaro.org>
    Signed-off-by: Anthony Liguori <anthony at codemonkey.ws>

diff --git a/.mailmap b/.mailmap
index 7b91a95..28defa1 100644
--- a/.mailmap
+++ b/.mailmap
@@ -3,6 +3,7 @@
 #
 Andrzej Zaborowski <balrogg at gmail.com> balrog <balrog at c046a42c-6fe2-441c-8c8c-71466251a162>
 Anthony Liguori <anthony at codemonkey.ws> aliguori <aliguori at c046a42c-6fe2-441c-8c8c-71466251a162>
+Anthony Liguori <anthony at codemonkey.ws> Anthony Liguori <aliguori at us.ibm.com>
 Aurelien Jarno <aurelien at aurel32.net> aurel32 <aurel32 at c046a42c-6fe2-441c-8c8c-71466251a162>
 Blue Swirl <blauwirbel at gmail.com> blueswir1 <blueswir1 at c046a42c-6fe2-441c-8c8c-71466251a162>
 Edgar E. Iglesias <edgar.iglesias at gmail.com> edgar_igl <edgar_igl at c046a42c-6fe2-441c-8c8c-71466251a162>
commit aaa6a40194e9f204cb853f64ef3c1e170bb014e8
Merge: bb7d4d8 5e891bf
Author: Anthony Liguori <anthony at codemonkey.ws>
Date:   Tue Sep 3 12:33:32 2013 -0500

    Merge remote-tracking branch 'afaerber/tags/qom-cpu-for-anthony' into staging
    
    QOM CPUState refactorings / X86CPU
    
    * Conversion of global CPU list to QTAILQ - preparing for CPU hot-unplug
    * Document X86CPU magic numbers for CPUID cache info
    
    # gpg: Signature made Tue 03 Sep 2013 10:59:22 AM CDT using RSA key ID 3E7E013F
    # gpg: Can't check signature: public key not found
    
    # By Andreas Färber (3) and Eduardo Habkost (1)
    # Via Andreas Färber
    * afaerber/tags/qom-cpu-for-anthony:
      target-i386: Use #defines instead of magic numbers for CPUID cache info
      cpu: Replace qemu_for_each_cpu()
      cpu: Use QTAILQ for CPU list
      a15mpcore: Use qemu_get_cpu() for generic timers

commit bb7d4d82b63bbde06c5584f94bfd9ba3b3e5ff3f
Merge: 5a93d5c ca0eca9
Author: Anthony Liguori <anthony at codemonkey.ws>
Date:   Tue Sep 3 12:32:45 2013 -0500

    Merge remote-tracking branch 'kwolf/for-anthony' into staging
    
    # By Max Reitz (11) and others
    # Via Kevin Wolf
    * kwolf/for-anthony: (26 commits)
      qemu-iotests: Overlapping cluster allocations
      qcow2_check: Mark image consistent
      qcow2-refcount: Repair shared refcount blocks
      qcow2-refcount: Repair OFLAG_COPIED errors
      qcow2-refcount: Move OFLAG_COPIED checks
      qcow2: Employ metadata overlap checks
      qcow2: Metadata overlap checks
      qcow2: Add corrupt bit
      qemu-iotests: Snapshotting zero clusters
      qcow2-refcount: Snapshot update for zero clusters
      option: Add assigned flag to QEMUOptionParameter
      gluster: Abort on AIO completion failure
      block: Remove old raw driver
      switch raw block driver from "raw.o" to "raw_bsd.o"
      raw_bsd: register bdrv_raw
      raw_bsd: add raw_create_options
      raw_bsd: introduce "special members"
      raw_bsd: add raw_create()
      raw_bsd: emit debug events in bdrv_co_readv() and bdrv_co_writev()
      add skeleton for BSD licensed "raw" BlockDriver
      ...
    
    Message-id: 1378111792-20436-1-git-send-email-kwolf at redhat.com
    Signed-off-by: Anthony Liguori <anthony at codemonkey.ws>

commit 5a93d5c2abc719bd44f6c9fbeed88d3cae712606
Merge: 9ea0f58 fcdda21
Author: Anthony Liguori <anthony at codemonkey.ws>
Date:   Tue Sep 3 12:31:43 2013 -0500

    Merge remote-tracking branch 'mjt/trivial-patches' into staging
    
    # By Stefan Weil (6) and others
    # Via Michael Tokarev
    * mjt/trivial-patches:
      aio / timers: use g_usleep() not sleep()
      adlib: sort offsets in portio registration
      qmp: fix integer usage in examples
      tci: Remove function tcg_out64 (fix broken build)
      target-arm: Report unimplemented opcodes (LOG_UNIMP)
      pflash_cfi02.c: fix debug macro
      configure: Remove unneeded redirections of stderr (pkg-config --exists)
      configure: Remove unneeded redirections of stderr (pkg-config --cflags, --libs)
      configure: Don't write .pyc files by default (python -B)
      curl: qemu_bh_new() can never return NULL
      slirp/arp_table.c: Avoid shifting into sign bit of signed integers
      configure: disable clang -Wstring-plus-int warning
      rdma: silly ipv6 bugfix
      misc: Fix some typos in names and comments
      slirp: Port redirection option behave differently on Linux and Windows
    
    Message-id: 1378119695-14568-1-git-send-email-mjt at msgid.tls.msk.ru
    Signed-off-by: Anthony Liguori <anthony at codemonkey.ws>

commit 9ea0f58fc723daeb9e1dba9a762269e8cbbd1b73
Merge: 9889e04 31efd2e
Author: Anthony Liguori <anthony at codemonkey.ws>
Date:   Tue Sep 3 12:31:30 2013 -0500

    Merge remote-tracking branch 'kraxel/usb.88' into staging
    
    # By Gerd Hoffmann (10) and Marcel Apfelbaum (1)
    # Via Gerd Hoffmann
    * kraxel/usb.88:
      usb/dev-hid: Modified usb-tablet category from Misc to Input
      Revert "usb-hub: report status changes only once"
      usb-hub: add tracepoint for status reports
      usb: parallelize usb3 streams
      uas: add property for request logging
      xhci: reset port when disabling slot
      xhci: emulate intr endpoint intervals correctly
      xhci: fix endpoint interval calculation
      xhci: add port to slot_address tracepoint
      xhci: add tracepoint for endpoint state changes
      xhci: remove leftover debug printf
    
    Message-id: 1378117055-29620-1-git-send-email-kraxel at redhat.com
    Signed-off-by: Anthony Liguori <anthony at codemonkey.ws>

commit 9889e04ac193cad7fa0526573ce0cc752dcabb99
Merge: 5cff81f 23fe2b3
Author: Anthony Liguori <anthony at codemonkey.ws>
Date:   Tue Sep 3 12:31:07 2013 -0500

    Merge remote-tracking branch 'mst/tags/for_anthony' into staging
    
    pc,pci,virtio fixes and cleanups
    
    This includes pc and pci cleanups and enhancements,
    and a virtio bugfix for level interrupts.
    
    Signed-off-by: Michael S. Tsirkin <mst at redhat.com>
    
    # gpg: Signature made Sun 01 Sep 2013 03:15:36 AM CDT using RSA key ID D28D5469
    # gpg: Can't check signature: public key not found
    
    # By Michael S. Tsirkin (3) and others
    # Via Michael S. Tsirkin
    * mst/tags/for_anthony:
      virtio_pci: fix level interrupts with irqfd
      pc: reduce duplication, fix PIIX descriptions
      hw: Clean up bogus default boot order
      pci: add config space access traces
      pc: fix regression for 64 bit PCI memory
      pci: Introduce helper to retrieve a PCI device's DMA address space
    
    Message-id: 1378023590-11109-1-git-send-email-mst at redhat.com
    Signed-off-by: Anthony Liguori <anthony at codemonkey.ws>

commit 5cff81f098a57762ab937bfbedb298e658af2c7f
Merge: 545825d 520902a
Author: Anthony Liguori <anthony at codemonkey.ws>
Date:   Tue Sep 3 12:30:51 2013 -0500

    Merge remote-tracking branch 'afaerber/tags/qom-devices-for-anthony' into staging
    
    QOM device refactorings
    
    * Fix QOM and ISA documentation errors
    * Extend object_initialize() et al. to check the instance size
    
    # gpg: Signature made Fri 30 Aug 2013 02:19:48 PM CDT using RSA key ID 3E7E013F
    # gpg: Can't check signature: public key not found
    
    # By Andreas Färber (14) and others
    # Via Andreas Färber
    * afaerber/tags/qom-devices-for-anthony:
      isa: Fix documentation of isa_register_portio_list()
      qom: Assert instance size in object_initialize_with_type()
      qom: Pass available size to object_initialize()
      qdev: Pass size to qbus_create_inplace()
      virtio-mmio: Pass size to virtio_mmio_bus_new()
      virtio-ccw: Pass size to virtio_ccw_bus_new()
      s390-virtio-bus: Pass size to virtio_s390_bus_new()
      virtio-pci: Pass size to virtio_pci_bus_new()
      usb: Pass size to usb_bus_new()
      scsi: Pass size to scsi_bus_new()
      pci: Pass size to pci_bus_new_inplace()
      ide: Pass size to ide_bus_new()
      ipack: Pass size to ipack_bus_new_inplace()
      intel-hda: Pass size to hda_codec_bus_init()
      qom: Fix object_initialize_with_type() argument name in documentation
      virtio: Remove unnecessary OBJECT() casts
      object: Fix typo in qom/object.h

commit 5e891bf8fd509c4d83cb95d352d88effb20720b1
Author: Eduardo Habkost <ehabkost at redhat.com>
Date:   Tue Aug 27 12:24:37 2013 -0300

    target-i386: Use #defines instead of magic numbers for CPUID cache info
    
    This is an attempt to make the CPUID cache topology code clearer, by
    replacing the magic numbers in the code with #defines, and moving all
    the cache information to the same place in the file.
    
    I took care of comparing the assembly output of compiling
    target-i386/cpu.c before and after applying this change, to make sure
    not a single bit was changed on cpu_x86_cpuid() before and after
    applying this patch (unfortunately I had to manually check existing
    differences, because of __LINE__ expansions on
    object_class_dynamic_cast_assert() calls).
    
    This even keeps the code bug-compatible with the previous version: today
    the cache information returned on AMD cache information leaves (CPUID
    0x80000005 & 0x80000006) do not match the information returned on CPUID
    leaves 2 and 4. The L2 cache information on CPUID leaf 2 also doesn't
    match the information on CPUID leaf 2. The new constants should make it
    easier to eventually fix those inconsistencies. All inconsistencies I
    have found are documented in code comments.
    
    Signed-off-by: Eduardo Habkost <ehabkost at redhat.com>
    Reviewed-by: liguang <lig.fnst at cn.fujitsu.com>
    Signed-off-by: Andreas Färber <afaerber at suse.de>

diff --git a/target-i386/cpu.c b/target-i386/cpu.c
index 42c5de0..c36345e 100644
--- a/target-i386/cpu.c
+++ b/target-i386/cpu.c
@@ -48,6 +48,118 @@
 #include "hw/i386/apic_internal.h"
 #endif
 
+
+/* Cache topology CPUID constants: */
+
+/* CPUID Leaf 2 Descriptors */
+
+#define CPUID_2_L1D_32KB_8WAY_64B 0x2c
+#define CPUID_2_L1I_32KB_8WAY_64B 0x30
+#define CPUID_2_L2_2MB_8WAY_64B   0x7d
+
+
+/* CPUID Leaf 4 constants: */
+
+/* EAX: */
+#define CPUID_4_TYPE_DCACHE  1
+#define CPUID_4_TYPE_ICACHE  2
+#define CPUID_4_TYPE_UNIFIED 3
+
+#define CPUID_4_LEVEL(l)          ((l) << 5)
+
+#define CPUID_4_SELF_INIT_LEVEL (1 << 8)
+#define CPUID_4_FULLY_ASSOC     (1 << 9)
+
+/* EDX: */
+#define CPUID_4_NO_INVD_SHARING (1 << 0)
+#define CPUID_4_INCLUSIVE       (1 << 1)
+#define CPUID_4_COMPLEX_IDX     (1 << 2)
+
+#define ASSOC_FULL 0xFF
+
+/* AMD associativity encoding used on CPUID Leaf 0x80000006: */
+#define AMD_ENC_ASSOC(a) (a <=   1 ? a   : \
+                          a ==   2 ? 0x2 : \
+                          a ==   4 ? 0x4 : \
+                          a ==   8 ? 0x6 : \
+                          a ==  16 ? 0x8 : \
+                          a ==  32 ? 0xA : \
+                          a ==  48 ? 0xB : \
+                          a ==  64 ? 0xC : \
+                          a ==  96 ? 0xD : \
+                          a == 128 ? 0xE : \
+                          a == ASSOC_FULL ? 0xF : \
+                          0 /* invalid value */)
+
+
+/* Definitions of the hardcoded cache entries we expose: */
+
+/* L1 data cache: */
+#define L1D_LINE_SIZE         64
+#define L1D_ASSOCIATIVITY      8
+#define L1D_SETS              64
+#define L1D_PARTITIONS         1
+/* Size = LINE_SIZE*ASSOCIATIVITY*SETS*PARTITIONS = 32KiB */
+#define L1D_DESCRIPTOR CPUID_2_L1D_32KB_8WAY_64B
+/*FIXME: CPUID leaf 0x80000005 is inconsistent with leaves 2 & 4 */
+#define L1D_LINES_PER_TAG      1
+#define L1D_SIZE_KB_AMD       64
+#define L1D_ASSOCIATIVITY_AMD  2
+
+/* L1 instruction cache: */
+#define L1I_LINE_SIZE         64
+#define L1I_ASSOCIATIVITY      8
+#define L1I_SETS              64
+#define L1I_PARTITIONS         1
+/* Size = LINE_SIZE*ASSOCIATIVITY*SETS*PARTITIONS = 32KiB */
+#define L1I_DESCRIPTOR CPUID_2_L1I_32KB_8WAY_64B
+/*FIXME: CPUID leaf 0x80000005 is inconsistent with leaves 2 & 4 */
+#define L1I_LINES_PER_TAG      1
+#define L1I_SIZE_KB_AMD       64
+#define L1I_ASSOCIATIVITY_AMD  2
+
+/* Level 2 unified cache: */
+#define L2_LINE_SIZE          64
+#define L2_ASSOCIATIVITY      16
+#define L2_SETS             4096
+#define L2_PARTITIONS          1
+/* Size = LINE_SIZE*ASSOCIATIVITY*SETS*PARTITIONS = 4MiB */
+/*FIXME: CPUID leaf 2 descriptor is inconsistent with CPUID leaf 4 */
+#define L2_DESCRIPTOR CPUID_2_L2_2MB_8WAY_64B
+/*FIXME: CPUID leaf 0x80000006 is inconsistent with leaves 2 & 4 */
+#define L2_LINES_PER_TAG       1
+#define L2_SIZE_KB_AMD       512
+
+/* No L3 cache: */
+#define L3_SIZE_KB             0 /* disabled */
+#define L3_ASSOCIATIVITY       0 /* disabled */
+#define L3_LINES_PER_TAG       0 /* disabled */
+#define L3_LINE_SIZE           0 /* disabled */
+
+/* TLB definitions: */
+
+#define L1_DTLB_2M_ASSOC       1
+#define L1_DTLB_2M_ENTRIES   255
+#define L1_DTLB_4K_ASSOC       1
+#define L1_DTLB_4K_ENTRIES   255
+
+#define L1_ITLB_2M_ASSOC       1
+#define L1_ITLB_2M_ENTRIES   255
+#define L1_ITLB_4K_ASSOC       1
+#define L1_ITLB_4K_ENTRIES   255
+
+#define L2_DTLB_2M_ASSOC       0 /* disabled */
+#define L2_DTLB_2M_ENTRIES     0 /* disabled */
+#define L2_DTLB_4K_ASSOC       4
+#define L2_DTLB_4K_ENTRIES   512
+
+#define L2_ITLB_2M_ASSOC       0 /* disabled */
+#define L2_ITLB_2M_ENTRIES     0 /* disabled */
+#define L2_ITLB_4K_ASSOC       4
+#define L2_ITLB_4K_ENTRIES   512
+
+
+
 static void x86_cpu_vendor_words2str(char *dst, uint32_t vendor1,
                                      uint32_t vendor2, uint32_t vendor3)
 {
@@ -1950,10 +2062,12 @@ void cpu_x86_cpuid(CPUX86State *env, uint32_t index, uint32_t count,
         break;
     case 2:
         /* cache info: needed for Pentium Pro compatibility */
-        *eax = 1;
+        *eax = 1; /* Number of CPUID[EAX=2] calls required */
         *ebx = 0;
         *ecx = 0;
-        *edx = 0x2c307d;
+        *edx = (L1D_DESCRIPTOR << 16) | \
+               (L1I_DESCRIPTOR <<  8) | \
+               (L2_DESCRIPTOR);
         break;
     case 4:
         /* cache info: needed for Core compatibility */
@@ -1964,25 +2078,37 @@ void cpu_x86_cpuid(CPUX86State *env, uint32_t index, uint32_t count,
         }
         switch (count) {
             case 0: /* L1 dcache info */
-                *eax |= 0x0000121;
-                *ebx = 0x1c0003f;
-                *ecx = 0x000003f;
-                *edx = 0x0000001;
+                *eax |= CPUID_4_TYPE_DCACHE | \
+                        CPUID_4_LEVEL(1) | \
+                        CPUID_4_SELF_INIT_LEVEL;
+                *ebx = (L1D_LINE_SIZE - 1) | \
+                       ((L1D_PARTITIONS - 1) << 12) | \
+                       ((L1D_ASSOCIATIVITY - 1) << 22);
+                *ecx = L1D_SETS - 1;
+                *edx = CPUID_4_NO_INVD_SHARING;
                 break;
             case 1: /* L1 icache info */
-                *eax |= 0x0000122;
-                *ebx = 0x1c0003f;
-                *ecx = 0x000003f;
-                *edx = 0x0000001;
+                *eax |= CPUID_4_TYPE_ICACHE | \
+                        CPUID_4_LEVEL(1) | \
+                        CPUID_4_SELF_INIT_LEVEL;
+                *ebx = (L1I_LINE_SIZE - 1) | \
+                       ((L1I_PARTITIONS - 1) << 12) | \
+                       ((L1I_ASSOCIATIVITY - 1) << 22);
+                *ecx = L1I_SETS - 1;
+                *edx = CPUID_4_NO_INVD_SHARING;
                 break;
             case 2: /* L2 cache info */
-                *eax |= 0x0000143;
+                *eax |= CPUID_4_TYPE_UNIFIED | \
+                        CPUID_4_LEVEL(2) | \
+                        CPUID_4_SELF_INIT_LEVEL;
                 if (cs->nr_threads > 1) {
                     *eax |= (cs->nr_threads - 1) << 14;
                 }
-                *ebx = 0x3c0003f;
-                *ecx = 0x0000fff;
-                *edx = 0x0000001;
+                *ebx = (L2_LINE_SIZE - 1) | \
+                       ((L2_PARTITIONS - 1) << 12) | \
+                       ((L2_ASSOCIATIVITY - 1) << 22);
+                *ecx = L2_SETS - 1;
+                *edx = CPUID_4_NO_INVD_SHARING;
                 break;
             default: /* end of info */
                 *eax = 0;
@@ -2102,17 +2228,31 @@ void cpu_x86_cpuid(CPUX86State *env, uint32_t index, uint32_t count,
         break;
     case 0x80000005:
         /* cache info (L1 cache) */
-        *eax = 0x01ff01ff;
-        *ebx = 0x01ff01ff;
-        *ecx = 0x40020140;
-        *edx = 0x40020140;
+        *eax = (L1_DTLB_2M_ASSOC << 24) | (L1_DTLB_2M_ENTRIES << 16) | \
+               (L1_ITLB_2M_ASSOC <<  8) | (L1_ITLB_2M_ENTRIES);
+        *ebx = (L1_DTLB_4K_ASSOC << 24) | (L1_DTLB_4K_ENTRIES << 16) | \
+               (L1_ITLB_4K_ASSOC <<  8) | (L1_ITLB_4K_ENTRIES);
+        *ecx = (L1D_SIZE_KB_AMD << 24) | (L1D_ASSOCIATIVITY_AMD << 16) | \
+               (L1D_LINES_PER_TAG << 8) | (L1D_LINE_SIZE);
+        *edx = (L1I_SIZE_KB_AMD << 24) | (L1I_ASSOCIATIVITY_AMD << 16) | \
+               (L1I_LINES_PER_TAG << 8) | (L1I_LINE_SIZE);
         break;
     case 0x80000006:
         /* cache info (L2 cache) */
-        *eax = 0;
-        *ebx = 0x42004200;
-        *ecx = 0x02008140;
-        *edx = 0;
+        *eax = (AMD_ENC_ASSOC(L2_DTLB_2M_ASSOC) << 28) | \
+               (L2_DTLB_2M_ENTRIES << 16) | \
+               (AMD_ENC_ASSOC(L2_ITLB_2M_ASSOC) << 12) | \
+               (L2_ITLB_2M_ENTRIES);
+        *ebx = (AMD_ENC_ASSOC(L2_DTLB_4K_ASSOC) << 28) | \
+               (L2_DTLB_4K_ENTRIES << 16) | \
+               (AMD_ENC_ASSOC(L2_ITLB_4K_ASSOC) << 12) | \
+               (L2_ITLB_4K_ENTRIES);
+        *ecx = (L2_SIZE_KB_AMD << 16) | \
+               (AMD_ENC_ASSOC(L2_ASSOCIATIVITY) << 12) | \
+               (L2_LINES_PER_TAG << 8) | (L2_LINE_SIZE);
+        *edx = ((L3_SIZE_KB/512) << 18) | \
+               (AMD_ENC_ASSOC(L3_ASSOCIATIVITY) << 12) | \
+               (L3_LINES_PER_TAG << 8) | (L3_LINE_SIZE);
         break;
     case 0x80000008:
         /* virtual & phys address size in low 2 bytes. */
commit 38fcbd3f08375eb2986b9b63ccd4f593e71aa99d
Author: Andreas Färber <afaerber at suse.de>
Date:   Sun Jul 7 19:50:23 2013 +0200

    cpu: Replace qemu_for_each_cpu()
    
    It was introduced to loop over CPUs from target-independent code, but
    since commit 182735efaf956ccab50b6d74a4fed163e0f35660 target-independent
    CPUState is used.
    
    A loop can be considered more efficient than function calls in a loop,
    and CPU_FOREACH() hides implementation details just as well, so use that
    instead.
    
    Suggested-by: Markus Armbruster <armbru at redhat.com>
    Acked-by: Michael S. Tsirkin <mst at redhat.com>
    Signed-off-by: Andreas Färber <afaerber at suse.de>

diff --git a/arch_init.c b/arch_init.c
index 0471cd5..e47e139 100644
--- a/arch_init.c
+++ b/arch_init.c
@@ -1196,15 +1196,14 @@ static void mig_sleep_cpu(void *opq)
    much time in the VM. The migration thread will try to catchup.
    Workload will experience a performance drop.
 */
-static void mig_throttle_cpu_down(CPUState *cpu, void *data)
-{
-    async_run_on_cpu(cpu, mig_sleep_cpu, NULL);
-}
-
 static void mig_throttle_guest_down(void)
 {
+    CPUState *cpu;
+
     qemu_mutex_lock_iothread();
-    qemu_for_each_cpu(mig_throttle_cpu_down, NULL);
+    CPU_FOREACH(cpu) {
+        async_run_on_cpu(cpu, mig_sleep_cpu, NULL);
+    }
     qemu_mutex_unlock_iothread();
 }
 
diff --git a/cpus.c b/cpus.c
index 363d392..e566297 100644
--- a/cpus.c
+++ b/cpus.c
@@ -854,12 +854,6 @@ static void *qemu_dummy_cpu_thread_fn(void *arg)
 
 static void tcg_exec_all(void);
 
-static void tcg_signal_cpu_creation(CPUState *cpu, void *data)
-{
-    cpu->thread_id = qemu_get_thread_id();
-    cpu->created = true;
-}
-
 static void *qemu_tcg_cpu_thread_fn(void *arg)
 {
     CPUState *cpu = arg;
@@ -868,7 +862,10 @@ static void *qemu_tcg_cpu_thread_fn(void *arg)
     qemu_thread_get_self(cpu->thread);
 
     qemu_mutex_lock(&qemu_global_mutex);
-    qemu_for_each_cpu(tcg_signal_cpu_creation, NULL);
+    CPU_FOREACH(cpu) {
+        cpu->thread_id = qemu_get_thread_id();
+        cpu->created = true;
+    }
     qemu_cond_signal(&qemu_cpu_cond);
 
     /* wait for initial kick-off after machine start */
diff --git a/exec.c b/exec.c
index ca2a504..87b0b39 100644
--- a/exec.c
+++ b/exec.c
@@ -362,15 +362,6 @@ CPUState *qemu_get_cpu(int index)
     return NULL;
 }
 
-void qemu_for_each_cpu(void (*func)(CPUState *cpu, void *data), void *data)
-{
-    CPUState *cpu;
-
-    CPU_FOREACH(cpu) {
-        func(cpu, data);
-    }
-}
-
 void cpu_exec_init(CPUArchState *env)
 {
     CPUState *cpu = ENV_GET_CPU(env);
diff --git a/hw/acpi/piix4.c b/hw/acpi/piix4.c
index 613d987..0b8d1d9 100644
--- a/hw/acpi/piix4.c
+++ b/hw/acpi/piix4.c
@@ -667,22 +667,14 @@ static void piix4_cpu_added_req(Notifier *n, void *opaque)
     piix4_cpu_hotplug_req(s, CPU(opaque), PLUG);
 }
 
-static void piix4_init_cpu_status(CPUState *cpu, void *data)
-{
-    CPUStatus *g = (CPUStatus *)data;
-    CPUClass *k = CPU_GET_CLASS(cpu);
-    int64_t id = k->get_arch_id(cpu);
-
-    g_assert((id / 8) < PIIX4_PROC_LEN);
-    g->sts[id / 8] |= (1 << (id % 8));
-}
-
 static int piix4_device_hotplug(DeviceState *qdev, PCIDevice *dev,
                                 PCIHotplugState state);
 
 static void piix4_acpi_system_hot_add_init(MemoryRegion *parent,
                                            PCIBus *bus, PIIX4PMState *s)
 {
+    CPUState *cpu;
+
     memory_region_init_io(&s->io_gpe, OBJECT(s), &piix4_gpe_ops, s,
                           "acpi-gpe0", GPE_LEN);
     memory_region_add_subregion(parent, GPE_BASE, &s->io_gpe);
@@ -693,7 +685,13 @@ static void piix4_acpi_system_hot_add_init(MemoryRegion *parent,
                                 &s->io_pci);
     pci_bus_hotplug(bus, piix4_device_hotplug, DEVICE(s));
 
-    qemu_for_each_cpu(piix4_init_cpu_status, &s->gpe_cpu);
+    CPU_FOREACH(cpu) {
+        CPUClass *cc = CPU_GET_CLASS(cpu);
+        int64_t id = cc->get_arch_id(cpu);
+
+        g_assert((id / 8) < PIIX4_PROC_LEN);
+        s->gpe_cpu.sts[id / 8] |= (1 << (id % 8));
+    }
     memory_region_init_io(&s->io_cpu, OBJECT(s), &cpu_hotplug_ops, s,
                           "acpi-cpu-hotplug", PIIX4_PROC_LEN);
     memory_region_add_subregion(parent, PIIX4_PROC_BASE, &s->io_cpu);
diff --git a/include/qom/cpu.h b/include/qom/cpu.h
index 79f7c87..7739e00 100644
--- a/include/qom/cpu.h
+++ b/include/qom/cpu.h
@@ -403,15 +403,6 @@ void run_on_cpu(CPUState *cpu, void (*func)(void *data), void *data);
 void async_run_on_cpu(CPUState *cpu, void (*func)(void *data), void *data);
 
 /**
- * qemu_for_each_cpu:
- * @func: The function to be executed.
- * @data: Data to pass to the function.
- *
- * Executes @func for each CPU.
- */
-void qemu_for_each_cpu(void (*func)(CPUState *cpu, void *data), void *data);
-
-/**
  * qemu_get_cpu:
  * @index: The CPUState at cpu_index value of the CPU to obtain.
  *
diff --git a/qom/cpu.c b/qom/cpu.c
index e71e57b..fa7ec6b 100644
--- a/qom/cpu.c
+++ b/qom/cpu.c
@@ -25,30 +25,18 @@
 #include "qemu/log.h"
 #include "sysemu/sysemu.h"
 
-typedef struct CPUExistsArgs {
-    int64_t id;
-    bool found;
-} CPUExistsArgs;
-
-static void cpu_exist_cb(CPUState *cpu, void *data)
-{
-    CPUClass *klass = CPU_GET_CLASS(cpu);
-    CPUExistsArgs *arg = data;
-
-    if (klass->get_arch_id(cpu) == arg->id) {
-        arg->found = true;
-    }
-}
-
 bool cpu_exists(int64_t id)
 {
-    CPUExistsArgs data = {
-        .id = id,
-        .found = false,
-    };
+    CPUState *cpu;
+
+    CPU_FOREACH(cpu) {
+        CPUClass *cc = CPU_GET_CLASS(cpu);
 
-    qemu_for_each_cpu(cpu_exist_cb, &data);
-    return data.found;
+        if (cc->get_arch_id(cpu) == id) {
+            return true;
+        }
+    }
+    return false;
 }
 
 bool cpu_paging_enabled(const CPUState *cpu)
commit bdc44640cb33c90809376a262df871a1144d339a
Author: Andreas Färber <afaerber at suse.de>
Date:   Mon Jun 24 23:50:24 2013 +0200

    cpu: Use QTAILQ for CPU list
    
    Introduce CPU_FOREACH(), CPU_FOREACH_SAFE() and CPU_NEXT() shorthand
    macros.
    
    Signed-off-by: Andreas Färber <afaerber at suse.de>

diff --git a/cpus.c b/cpus.c
index d74cc11..363d392 100644
--- a/cpus.c
+++ b/cpus.c
@@ -86,7 +86,7 @@ static bool all_cpu_threads_idle(void)
 {
     CPUState *cpu;
 
-    for (cpu = first_cpu; cpu != NULL; cpu = cpu->next_cpu) {
+    CPU_FOREACH(cpu) {
         if (!cpu_thread_is_idle(cpu)) {
             return false;
         }
@@ -416,7 +416,7 @@ void hw_error(const char *fmt, ...)
     fprintf(stderr, "qemu: hardware error: ");
     vfprintf(stderr, fmt, ap);
     fprintf(stderr, "\n");
-    for (cpu = first_cpu; cpu != NULL; cpu = cpu->next_cpu) {
+    CPU_FOREACH(cpu) {
         fprintf(stderr, "CPU #%d:\n", cpu->cpu_index);
         cpu_dump_state(cpu, stderr, fprintf, CPU_DUMP_FPU);
     }
@@ -428,7 +428,7 @@ void cpu_synchronize_all_states(void)
 {
     CPUState *cpu;
 
-    for (cpu = first_cpu; cpu; cpu = cpu->next_cpu) {
+    CPU_FOREACH(cpu) {
         cpu_synchronize_state(cpu);
     }
 }
@@ -437,7 +437,7 @@ void cpu_synchronize_all_post_reset(void)
 {
     CPUState *cpu;
 
-    for (cpu = first_cpu; cpu; cpu = cpu->next_cpu) {
+    CPU_FOREACH(cpu) {
         cpu_synchronize_post_reset(cpu);
     }
 }
@@ -446,7 +446,7 @@ void cpu_synchronize_all_post_init(void)
 {
     CPUState *cpu;
 
-    for (cpu = first_cpu; cpu; cpu = cpu->next_cpu) {
+    CPU_FOREACH(cpu) {
         cpu_synchronize_post_init(cpu);
     }
 }
@@ -760,7 +760,7 @@ static void qemu_tcg_wait_io_event(void)
         qemu_cond_wait(&qemu_io_proceeded_cond, &qemu_global_mutex);
     }
 
-    for (cpu = first_cpu; cpu != NULL; cpu = cpu->next_cpu) {
+    CPU_FOREACH(cpu) {
         qemu_wait_io_event_common(cpu);
     }
 }
@@ -872,11 +872,11 @@ static void *qemu_tcg_cpu_thread_fn(void *arg)
     qemu_cond_signal(&qemu_cpu_cond);
 
     /* wait for initial kick-off after machine start */
-    while (first_cpu->stopped) {
+    while (QTAILQ_FIRST(&cpus)->stopped) {
         qemu_cond_wait(tcg_halt_cond, &qemu_global_mutex);
 
         /* process any pending work */
-        for (cpu = first_cpu; cpu != NULL; cpu = cpu->next_cpu) {
+        CPU_FOREACH(cpu) {
             qemu_wait_io_event_common(cpu);
         }
     }
@@ -991,13 +991,12 @@ void qemu_mutex_unlock_iothread(void)
 
 static int all_vcpus_paused(void)
 {
-    CPUState *cpu = first_cpu;
+    CPUState *cpu;
 
-    while (cpu) {
+    CPU_FOREACH(cpu) {
         if (!cpu->stopped) {
             return 0;
         }
-        cpu = cpu->next_cpu;
     }
 
     return 1;
@@ -1005,23 +1004,20 @@ static int all_vcpus_paused(void)
 
 void pause_all_vcpus(void)
 {
-    CPUState *cpu = first_cpu;
+    CPUState *cpu;
 
     qemu_clock_enable(QEMU_CLOCK_VIRTUAL, false);
-    while (cpu) {
+    CPU_FOREACH(cpu) {
         cpu->stop = true;
         qemu_cpu_kick(cpu);
-        cpu = cpu->next_cpu;
     }
 
     if (qemu_in_vcpu_thread()) {
         cpu_stop_current();
         if (!kvm_enabled()) {
-            cpu = first_cpu;
-            while (cpu) {
+            CPU_FOREACH(cpu) {
                 cpu->stop = false;
                 cpu->stopped = true;
-                cpu = cpu->next_cpu;
             }
             return;
         }
@@ -1029,10 +1025,8 @@ void pause_all_vcpus(void)
 
     while (!all_vcpus_paused()) {
         qemu_cond_wait(&qemu_pause_cond, &qemu_global_mutex);
-        cpu = first_cpu;
-        while (cpu) {
+        CPU_FOREACH(cpu) {
             qemu_cpu_kick(cpu);
-            cpu = cpu->next_cpu;
         }
     }
 }
@@ -1046,12 +1040,11 @@ void cpu_resume(CPUState *cpu)
 
 void resume_all_vcpus(void)
 {
-    CPUState *cpu = first_cpu;
+    CPUState *cpu;
 
     qemu_clock_enable(QEMU_CLOCK_VIRTUAL, true);
-    while (cpu) {
+    CPU_FOREACH(cpu) {
         cpu_resume(cpu);
-        cpu = cpu->next_cpu;
     }
 }
 
@@ -1215,7 +1208,7 @@ static void tcg_exec_all(void)
     if (next_cpu == NULL) {
         next_cpu = first_cpu;
     }
-    for (; next_cpu != NULL && !exit_request; next_cpu = next_cpu->next_cpu) {
+    for (; next_cpu != NULL && !exit_request; next_cpu = CPU_NEXT(next_cpu)) {
         CPUState *cpu = next_cpu;
         CPUArchState *env = cpu->env_ptr;
 
@@ -1240,7 +1233,7 @@ void set_numa_modes(void)
     CPUState *cpu;
     int i;
 
-    for (cpu = first_cpu; cpu != NULL; cpu = cpu->next_cpu) {
+    CPU_FOREACH(cpu) {
         for (i = 0; i < nb_numa_nodes; i++) {
             if (test_bit(cpu->cpu_index, node_cpumask[i])) {
                 cpu->numa_node = i;
@@ -1262,7 +1255,7 @@ CpuInfoList *qmp_query_cpus(Error **errp)
     CpuInfoList *head = NULL, *cur_item = NULL;
     CPUState *cpu;
 
-    for (cpu = first_cpu; cpu != NULL; cpu = cpu->next_cpu) {
+    CPU_FOREACH(cpu) {
         CpuInfoList *info;
 #if defined(TARGET_I386)
         X86CPU *x86_cpu = X86_CPU(cpu);
@@ -1391,7 +1384,7 @@ void qmp_inject_nmi(Error **errp)
 #if defined(TARGET_I386)
     CPUState *cs;
 
-    for (cs = first_cpu; cs != NULL; cs = cs->next_cpu) {
+    CPU_FOREACH(cs) {
         X86CPU *cpu = X86_CPU(cs);
         CPUX86State *env = &cpu->env;
 
@@ -1405,7 +1398,7 @@ void qmp_inject_nmi(Error **errp)
     CPUState *cs;
     S390CPU *cpu;
 
-    for (cs = first_cpu; cs != NULL; cs = cs->next_cpu) {
+    CPU_FOREACH(cs) {
         cpu = S390_CPU(cs);
         if (cpu->env.cpu_num == monitor_get_cpu_index()) {
             if (s390_cpu_restart(S390_CPU(cs)) == -1) {
diff --git a/cputlb.c b/cputlb.c
index 977c0ca..19ecf60 100644
--- a/cputlb.c
+++ b/cputlb.c
@@ -189,7 +189,7 @@ void cpu_tlb_reset_dirty_all(ram_addr_t start1, ram_addr_t length)
     CPUState *cpu;
     CPUArchState *env;
 
-    for (cpu = first_cpu; cpu != NULL; cpu = cpu->next_cpu) {
+    CPU_FOREACH(cpu) {
         int mmu_idx;
 
         env = cpu->env_ptr;
diff --git a/dump.c b/dump.c
index c0dae2c..846155c 100644
--- a/dump.c
+++ b/dump.c
@@ -277,7 +277,7 @@ static int write_elf64_notes(DumpState *s)
     int ret;
     int id;
 
-    for (cpu = first_cpu; cpu != NULL; cpu = cpu->next_cpu) {
+    CPU_FOREACH(cpu) {
         id = cpu_index(cpu);
         ret = cpu_write_elf64_note(fd_write_vmcore, cpu, id, s);
         if (ret < 0) {
@@ -286,7 +286,7 @@ static int write_elf64_notes(DumpState *s)
         }
     }
 
-    for (cpu = first_cpu; cpu != NULL; cpu = cpu->next_cpu) {
+    CPU_FOREACH(cpu) {
         ret = cpu_write_elf64_qemunote(fd_write_vmcore, cpu, s);
         if (ret < 0) {
             dump_error(s, "dump: failed to write CPU status.\n");
@@ -327,7 +327,7 @@ static int write_elf32_notes(DumpState *s)
     int ret;
     int id;
 
-    for (cpu = first_cpu; cpu != NULL; cpu = cpu->next_cpu) {
+    CPU_FOREACH(cpu) {
         id = cpu_index(cpu);
         ret = cpu_write_elf32_note(fd_write_vmcore, cpu, id, s);
         if (ret < 0) {
@@ -336,7 +336,7 @@ static int write_elf32_notes(DumpState *s)
         }
     }
 
-    for (cpu = first_cpu; cpu != NULL; cpu = cpu->next_cpu) {
+    CPU_FOREACH(cpu) {
         ret = cpu_write_elf32_qemunote(fd_write_vmcore, cpu, s);
         if (ret < 0) {
             dump_error(s, "dump: failed to write CPU status.\n");
@@ -734,7 +734,7 @@ static int dump_init(DumpState *s, int fd, bool paging, bool has_filter,
      */
     cpu_synchronize_all_states();
     nr_cpus = 0;
-    for (cpu = first_cpu; cpu != NULL; cpu = cpu->next_cpu) {
+    CPU_FOREACH(cpu) {
         nr_cpus++;
     }
 
diff --git a/exec.c b/exec.c
index 3ca9381..ca2a504 100644
--- a/exec.c
+++ b/exec.c
@@ -69,7 +69,7 @@ static MemoryRegion io_mem_unassigned;
 
 #endif
 
-CPUState *first_cpu;
+struct CPUTailQ cpus = QTAILQ_HEAD_INITIALIZER(cpus);
 /* current CPU in the current thread. It is only valid inside
    cpu_exec() */
 DEFINE_TLS(CPUState *, current_cpu);
@@ -351,26 +351,23 @@ const VMStateDescription vmstate_cpu_common = {
 
 CPUState *qemu_get_cpu(int index)
 {
-    CPUState *cpu = first_cpu;
+    CPUState *cpu;
 
-    while (cpu) {
+    CPU_FOREACH(cpu) {
         if (cpu->cpu_index == index) {
-            break;
+            return cpu;
         }
-        cpu = cpu->next_cpu;
     }
 
-    return cpu;
+    return NULL;
 }
 
 void qemu_for_each_cpu(void (*func)(CPUState *cpu, void *data), void *data)
 {
     CPUState *cpu;
 
-    cpu = first_cpu;
-    while (cpu) {
+    CPU_FOREACH(cpu) {
         func(cpu, data);
-        cpu = cpu->next_cpu;
     }
 }
 
@@ -378,17 +375,14 @@ void cpu_exec_init(CPUArchState *env)
 {
     CPUState *cpu = ENV_GET_CPU(env);
     CPUClass *cc = CPU_GET_CLASS(cpu);
-    CPUState **pcpu;
+    CPUState *some_cpu;
     int cpu_index;
 
 #if defined(CONFIG_USER_ONLY)
     cpu_list_lock();
 #endif
-    cpu->next_cpu = NULL;
-    pcpu = &first_cpu;
     cpu_index = 0;
-    while (*pcpu != NULL) {
-        pcpu = &(*pcpu)->next_cpu;
+    CPU_FOREACH(some_cpu) {
         cpu_index++;
     }
     cpu->cpu_index = cpu_index;
@@ -398,7 +392,7 @@ void cpu_exec_init(CPUArchState *env)
 #ifndef CONFIG_USER_ONLY
     cpu->thread_id = qemu_get_thread_id();
 #endif
-    *pcpu = cpu;
+    QTAILQ_INSERT_TAIL(&cpus, cpu, node);
 #if defined(CONFIG_USER_ONLY)
     cpu_list_unlock();
 #endif
@@ -1762,7 +1756,7 @@ static void tcg_commit(MemoryListener *listener)
     /* since each CPU stores ram addresses in its TLB cache, we must
        reset the modified entries */
     /* XXX: slow ! */
-    for (cpu = first_cpu; cpu != NULL; cpu = cpu->next_cpu) {
+    CPU_FOREACH(cpu) {
         CPUArchState *env = cpu->env_ptr;
 
         tlb_flush(env, 1);
diff --git a/gdbstub.c b/gdbstub.c
index 9d067d6..2b7f22b 100644
--- a/gdbstub.c
+++ b/gdbstub.c
@@ -648,7 +648,7 @@ static int gdb_breakpoint_insert(target_ulong addr, target_ulong len, int type)
     switch (type) {
     case GDB_BREAKPOINT_SW:
     case GDB_BREAKPOINT_HW:
-        for (cpu = first_cpu; cpu != NULL; cpu = cpu->next_cpu) {
+        CPU_FOREACH(cpu) {
             env = cpu->env_ptr;
             err = cpu_breakpoint_insert(env, addr, BP_GDB, NULL);
             if (err)
@@ -659,7 +659,7 @@ static int gdb_breakpoint_insert(target_ulong addr, target_ulong len, int type)
     case GDB_WATCHPOINT_WRITE:
     case GDB_WATCHPOINT_READ:
     case GDB_WATCHPOINT_ACCESS:
-        for (cpu = first_cpu; cpu != NULL; cpu = cpu->next_cpu) {
+        CPU_FOREACH(cpu) {
             env = cpu->env_ptr;
             err = cpu_watchpoint_insert(env, addr, len, xlat_gdb_type[type],
                                         NULL);
@@ -686,7 +686,7 @@ static int gdb_breakpoint_remove(target_ulong addr, target_ulong len, int type)
     switch (type) {
     case GDB_BREAKPOINT_SW:
     case GDB_BREAKPOINT_HW:
-        for (cpu = first_cpu; cpu != NULL; cpu = cpu->next_cpu) {
+        CPU_FOREACH(cpu) {
             env = cpu->env_ptr;
             err = cpu_breakpoint_remove(env, addr, BP_GDB);
             if (err)
@@ -697,7 +697,7 @@ static int gdb_breakpoint_remove(target_ulong addr, target_ulong len, int type)
     case GDB_WATCHPOINT_WRITE:
     case GDB_WATCHPOINT_READ:
     case GDB_WATCHPOINT_ACCESS:
-        for (cpu = first_cpu; cpu != NULL; cpu = cpu->next_cpu) {
+        CPU_FOREACH(cpu) {
             env = cpu->env_ptr;
             err = cpu_watchpoint_remove(env, addr, len, xlat_gdb_type[type]);
             if (err)
@@ -720,7 +720,7 @@ static void gdb_breakpoint_remove_all(void)
         return;
     }
 
-    for (cpu = first_cpu; cpu != NULL; cpu = cpu->next_cpu) {
+    CPU_FOREACH(cpu) {
         env = cpu->env_ptr;
         cpu_breakpoint_remove_all(env, BP_GDB);
 #ifndef CONFIG_USER_ONLY
@@ -744,7 +744,7 @@ static CPUState *find_cpu(uint32_t thread_id)
 {
     CPUState *cpu;
 
-    for (cpu = first_cpu; cpu != NULL; cpu = cpu->next_cpu) {
+    CPU_FOREACH(cpu) {
         if (cpu_index(cpu) == thread_id) {
             return cpu;
         }
@@ -1070,7 +1070,7 @@ static int gdb_handle_packet(GDBState *s, const char *line_buf)
             if (s->query_cpu) {
                 snprintf(buf, sizeof(buf), "m%x", cpu_index(s->query_cpu));
                 put_packet(s, buf);
-                s->query_cpu = s->query_cpu->next_cpu;
+                s->query_cpu = CPU_NEXT(s->query_cpu);
             } else
                 put_packet(s, "l");
             break;
diff --git a/hw/arm/boot.c b/hw/arm/boot.c
index 2cbeefd..1e313af 100644
--- a/hw/arm/boot.c
+++ b/hw/arm/boot.c
@@ -468,7 +468,7 @@ void arm_load_kernel(ARMCPU *cpu, struct arm_boot_info *info)
     }
     info->is_linux = is_linux;
 
-    for (; cs; cs = cs->next_cpu) {
+    for (; cs; cs = CPU_NEXT(cs)) {
         cpu = ARM_CPU(cs);
         cpu->env.boot_info = info;
         qemu_register_reset(do_cpu_reset, cpu);
diff --git a/hw/i386/kvm/clock.c b/hw/i386/kvm/clock.c
index e89e2f7..92aabb8 100644
--- a/hw/i386/kvm/clock.c
+++ b/hw/i386/kvm/clock.c
@@ -59,7 +59,7 @@ static void kvmclock_vm_state_change(void *opaque, int running,
         if (!cap_clock_ctrl) {
             return;
         }
-        for (cpu = first_cpu; cpu != NULL; cpu = cpu->next_cpu) {
+        CPU_FOREACH(cpu) {
             ret = kvm_vcpu_ioctl(cpu, KVM_KVMCLOCK_CTRL, 0);
             if (ret) {
                 if (ret != -EINVAL) {
diff --git a/hw/i386/kvmvapic.c b/hw/i386/kvmvapic.c
index 15beb80..d3a6fbe 100644
--- a/hw/i386/kvmvapic.c
+++ b/hw/i386/kvmvapic.c
@@ -498,7 +498,7 @@ static void vapic_enable_tpr_reporting(bool enable)
     X86CPU *cpu;
     CPUX86State *env;
 
-    for (cs = first_cpu; cs != NULL; cs = cs->next_cpu) {
+    CPU_FOREACH(cs) {
         cpu = X86_CPU(cs);
         env = &cpu->env;
         info.apic = env->apic_state;
diff --git a/hw/i386/pc.c b/hw/i386/pc.c
index 3a620a1..0c313fe 100644
--- a/hw/i386/pc.c
+++ b/hw/i386/pc.c
@@ -191,13 +191,12 @@ static void pic_irq_request(void *opaque, int irq, int level)
 
     DPRINTF("pic_irqs: %s irq %d\n", level? "raise" : "lower", irq);
     if (env->apic_state) {
-        while (cs) {
+        CPU_FOREACH(cs) {
             cpu = X86_CPU(cs);
             env = &cpu->env;
             if (apic_accept_pic_intr(env->apic_state)) {
                 apic_deliver_pic_intr(env->apic_state, level);
             }
-            cs = cs->next_cpu;
         }
     } else {
         if (level) {
diff --git a/hw/ppc/e500.c b/hw/ppc/e500.c
index 9059ff9..cfdd84b 100644
--- a/hw/ppc/e500.c
+++ b/hw/ppc/e500.c
@@ -540,7 +540,7 @@ static DeviceState *ppce500_init_mpic_kvm(PPCE500Params *params,
         return NULL;
     }
 
-    for (cs = first_cpu; cs != NULL; cs = cs->next_cpu) {
+    CPU_FOREACH(cs) {
         if (kvm_openpic_connect_vcpu(dev, cs)) {
             fprintf(stderr, "%s: failed to connect vcpu to irqchip\n",
                     __func__);
diff --git a/hw/ppc/ppc.c b/hw/ppc/ppc.c
index 59b41cb..bf2d3d4 100644
--- a/hw/ppc/ppc.c
+++ b/hw/ppc/ppc.c
@@ -443,7 +443,7 @@ void ppce500_set_mpic_proxy(bool enabled)
 {
     CPUState *cs;
 
-    for (cs = first_cpu; cs != NULL; cs = cs->next_cpu) {
+    CPU_FOREACH(cs) {
         PowerPCCPU *cpu = POWERPC_CPU(cs);
 
         cpu->env.mpic_proxy = enabled;
diff --git a/hw/ppc/spapr.c b/hw/ppc/spapr.c
index 04f0ee3..8c6e296 100644
--- a/hw/ppc/spapr.c
+++ b/hw/ppc/spapr.c
@@ -187,7 +187,7 @@ static int spapr_fixup_cpu_dt(void *fdt, sPAPREnvironment *spapr)
 
     assert(spapr->cpu_model);
 
-    for (cpu = first_cpu; cpu != NULL; cpu = cpu->next_cpu) {
+    CPU_FOREACH(cpu) {
         uint32_t associativity[] = {cpu_to_be32(0x5),
                                     cpu_to_be32(0x0),
                                     cpu_to_be32(0x0),
@@ -351,7 +351,7 @@ static void *spapr_create_fdt_skel(const char *cpu_model,
     /* This is needed during FDT finalization */
     spapr->cpu_model = g_strdup(modelname);
 
-    for (cs = first_cpu; cs != NULL; cs = cs->next_cpu) {
+    CPU_FOREACH(cs) {
         PowerPCCPU *cpu = POWERPC_CPU(cs);
         CPUPPCState *env = &cpu->env;
         PowerPCCPUClass *pcc = POWERPC_CPU_GET_CLASS(cs);
diff --git a/hw/ppc/spapr_hcall.c b/hw/ppc/spapr_hcall.c
index 89e6a00..f10ba8a 100644
--- a/hw/ppc/spapr_hcall.c
+++ b/hw/ppc/spapr_hcall.c
@@ -679,7 +679,7 @@ static target_ulong h_set_mode(PowerPCCPU *cpu, sPAPREnvironment *spapr,
 
         switch (mflags) {
         case H_SET_MODE_ENDIAN_BIG:
-            for (cs = first_cpu; cs != NULL; cs = cs->next_cpu) {
+            CPU_FOREACH(cs) {
                 PowerPCCPU *cp = POWERPC_CPU(cs);
                 CPUPPCState *env = &cp->env;
                 env->spr[SPR_LPCR] &= ~LPCR_ILE;
@@ -688,7 +688,7 @@ static target_ulong h_set_mode(PowerPCCPU *cpu, sPAPREnvironment *spapr,
             break;
 
         case H_SET_MODE_ENDIAN_LITTLE:
-            for (cs = first_cpu; cs != NULL; cs = cs->next_cpu) {
+            CPU_FOREACH(cs) {
                 PowerPCCPU *cp = POWERPC_CPU(cs);
                 CPUPPCState *env = &cp->env;
                 env->spr[SPR_LPCR] |= LPCR_ILE;
diff --git a/include/qom/cpu.h b/include/qom/cpu.h
index 3e49936..79f7c87 100644
--- a/include/qom/cpu.h
+++ b/include/qom/cpu.h
@@ -23,6 +23,7 @@
 #include <signal.h>
 #include "hw/qdev-core.h"
 #include "exec/hwaddr.h"
+#include "qemu/queue.h"
 #include "qemu/thread.h"
 #include "qemu/tls.h"
 #include "qemu/typedefs.h"
@@ -190,7 +191,7 @@ struct CPUState {
     struct GDBRegisterState *gdb_regs;
     int gdb_num_regs;
     int gdb_num_g_regs;
-    CPUState *next_cpu;
+    QTAILQ_ENTRY(CPUState) node;
 
     int kvm_fd;
     bool kvm_vcpu_dirty;
@@ -202,7 +203,13 @@ struct CPUState {
     uint32_t halted; /* used by alpha, cris, ppc TCG */
 };
 
-extern CPUState *first_cpu;
+QTAILQ_HEAD(CPUTailQ, CPUState);
+extern struct CPUTailQ cpus;
+#define CPU_NEXT(cpu) QTAILQ_NEXT(cpu, node)
+#define CPU_FOREACH(cpu) QTAILQ_FOREACH(cpu, &cpus, node)
+#define CPU_FOREACH_SAFE(cpu, next_cpu) \
+    QTAILQ_FOREACH_SAFE(cpu, &cpus, node, next_cpu)
+#define first_cpu QTAILQ_FIRST(&cpus)
 
 DECLARE_TLS(CPUState *, current_cpu);
 #define current_cpu tls_var(current_cpu)
diff --git a/kvm-all.c b/kvm-all.c
index 875e32e..c29a015 100644
--- a/kvm-all.c
+++ b/kvm-all.c
@@ -1925,7 +1925,7 @@ int kvm_insert_breakpoint(CPUState *cpu, target_ulong addr,
         }
     }
 
-    for (cpu = first_cpu; cpu != NULL; cpu = cpu->next_cpu) {
+    CPU_FOREACH(cpu) {
         err = kvm_update_guest_debug(cpu, 0);
         if (err) {
             return err;
@@ -1965,7 +1965,7 @@ int kvm_remove_breakpoint(CPUState *cpu, target_ulong addr,
         }
     }
 
-    for (cpu = first_cpu; cpu != NULL; cpu = cpu->next_cpu) {
+    CPU_FOREACH(cpu) {
         err = kvm_update_guest_debug(cpu, 0);
         if (err) {
             return err;
@@ -1982,7 +1982,7 @@ void kvm_remove_all_breakpoints(CPUState *cpu)
     QTAILQ_FOREACH_SAFE(bp, &s->kvm_sw_breakpoints, entry, next) {
         if (kvm_arch_remove_sw_breakpoint(cpu, bp) != 0) {
             /* Try harder to find a CPU that currently sees the breakpoint. */
-            for (cpu = first_cpu; cpu != NULL; cpu = cpu->next_cpu) {
+            CPU_FOREACH(cpu) {
                 if (kvm_arch_remove_sw_breakpoint(cpu, bp) == 0) {
                     break;
                 }
@@ -1993,7 +1993,7 @@ void kvm_remove_all_breakpoints(CPUState *cpu)
     }
     kvm_arch_remove_all_hw_breakpoints();
 
-    for (cpu = first_cpu; cpu != NULL; cpu = cpu->next_cpu) {
+    CPU_FOREACH(cpu) {
         kvm_update_guest_debug(cpu, 0);
     }
 }
diff --git a/linux-user/elfload.c b/linux-user/elfload.c
index 7ce2eab..72d9270 100644
--- a/linux-user/elfload.c
+++ b/linux-user/elfload.c
@@ -2668,7 +2668,7 @@ static int fill_note_info(struct elf_note_info *info,
 
     /* read and fill status of all threads */
     cpu_list_lock();
-    for (cpu = first_cpu; cpu != NULL; cpu = cpu->next_cpu) {
+    CPU_FOREACH(cpu) {
         if (cpu == thread_cpu) {
             continue;
         }
diff --git a/linux-user/main.c b/linux-user/main.c
index 03859bc..5c2f7b2 100644
--- a/linux-user/main.c
+++ b/linux-user/main.c
@@ -117,10 +117,14 @@ void fork_end(int child)
 {
     mmap_fork_end(child);
     if (child) {
+        CPUState *cpu, *next_cpu;
         /* Child processes created by fork() only have a single thread.
            Discard information about the parent threads.  */
-        first_cpu = thread_cpu;
-        first_cpu->next_cpu = NULL;
+        CPU_FOREACH_SAFE(cpu, next_cpu) {
+            if (cpu != thread_cpu) {
+                QTAILQ_REMOVE(&cpus, thread_cpu, node);
+            }
+        }
         pending_cpus = 0;
         pthread_mutex_init(&exclusive_lock, NULL);
         pthread_mutex_init(&cpu_list_mutex, NULL);
@@ -154,7 +158,7 @@ static inline void start_exclusive(void)
 
     pending_cpus = 1;
     /* Make all other cpus stop executing.  */
-    for (other_cpu = first_cpu; other_cpu; other_cpu = other_cpu->next_cpu) {
+    CPU_FOREACH(other_cpu) {
         if (other_cpu->running) {
             pending_cpus++;
             cpu_exit(other_cpu);
diff --git a/linux-user/syscall.c b/linux-user/syscall.c
index f986548..ecead51 100644
--- a/linux-user/syscall.c
+++ b/linux-user/syscall.c
@@ -5113,25 +5113,12 @@ abi_long do_syscall(void *cpu_env, int num, abi_long arg1,
            Do thread termination if we have more then one thread.  */
         /* FIXME: This probably breaks if a signal arrives.  We should probably
            be disabling signals.  */
-        if (first_cpu->next_cpu) {
+        if (CPU_NEXT(first_cpu)) {
             TaskState *ts;
-            CPUState **lastp;
-            CPUState *p;
 
             cpu_list_lock();
-            lastp = &first_cpu;
-            p = first_cpu;
-            while (p && p != cpu) {
-                lastp = &p->next_cpu;
-                p = p->next_cpu;
-            }
-            /* If we didn't find the CPU for this thread then something is
-               horribly wrong.  */
-            if (!p) {
-                abort();
-            }
             /* Remove the CPU from the list.  */
-            *lastp = p->next_cpu;
+            QTAILQ_REMOVE(&cpus, cpu, node);
             cpu_list_unlock();
             ts = ((CPUArchState *)cpu_env)->opaque;
             if (ts->child_tidptr) {
diff --git a/memory_mapping.c b/memory_mapping.c
index eeeeb44..87a6ed5 100644
--- a/memory_mapping.c
+++ b/memory_mapping.c
@@ -270,7 +270,7 @@ static CPUState *find_paging_enabled_cpu(CPUState *start_cpu)
 {
     CPUState *cpu;
 
-    for (cpu = start_cpu; cpu != NULL; cpu = cpu->next_cpu) {
+    CPU_FOREACH(cpu) {
         if (cpu_paging_enabled(cpu)) {
             return cpu;
         }
@@ -289,7 +289,8 @@ void qemu_get_guest_memory_mapping(MemoryMappingList *list,
 
     first_paging_enabled_cpu = find_paging_enabled_cpu(first_cpu);
     if (first_paging_enabled_cpu) {
-        for (cpu = first_paging_enabled_cpu; cpu != NULL; cpu = cpu->next_cpu) {
+        for (cpu = first_paging_enabled_cpu; cpu != NULL;
+             cpu = CPU_NEXT(cpu)) {
             Error *err = NULL;
             cpu_get_memory_mapping(cpu, list, &err);
             if (err) {
diff --git a/monitor.c b/monitor.c
index 0aeaf6c..683babf 100644
--- a/monitor.c
+++ b/monitor.c
@@ -2002,7 +2002,7 @@ static void do_info_numa(Monitor *mon, const QDict *qdict)
     monitor_printf(mon, "%d nodes\n", nb_numa_nodes);
     for (i = 0; i < nb_numa_nodes; i++) {
         monitor_printf(mon, "node %d cpus:", i);
-        for (cpu = first_cpu; cpu != NULL; cpu = cpu->next_cpu) {
+        CPU_FOREACH(cpu) {
             if (cpu->numa_node == i) {
                 monitor_printf(mon, " %d", cpu->cpu_index);
             }
diff --git a/target-i386/helper.c b/target-i386/helper.c
index bf3e2ac..7c58e27 100644
--- a/target-i386/helper.c
+++ b/target-i386/helper.c
@@ -1231,8 +1231,7 @@ void cpu_x86_inject_mce(Monitor *mon, X86CPU *cpu, int bank,
         params.mcg_status = MCG_STATUS_MCIP | MCG_STATUS_RIPV;
         params.addr = 0;
         params.misc = 0;
-        for (other_cs = first_cpu; other_cs != NULL;
-             other_cs = other_cs->next_cpu) {
+        CPU_FOREACH(other_cs) {
             if (other_cs == cs) {
                 continue;
             }
diff --git a/target-i386/misc_helper.c b/target-i386/misc_helper.c
index 957926c..93933fd 100644
--- a/target-i386/misc_helper.c
+++ b/target-i386/misc_helper.c
@@ -610,7 +610,7 @@ void helper_mwait(CPUX86State *env, int next_eip_addend)
     cpu = x86_env_get_cpu(env);
     cs = CPU(cpu);
     /* XXX: not complete but not completely erroneous */
-    if (cs->cpu_index != 0 || cs->next_cpu != NULL) {
+    if (cs->cpu_index != 0 || CPU_NEXT(cs) != NULL) {
         /* more than one CPU: do not sleep because another CPU may
            wake this one */
     } else {
diff --git a/target-mips/op_helper.c b/target-mips/op_helper.c
index b828375..8e3a6d7 100644
--- a/target-mips/op_helper.c
+++ b/target-mips/op_helper.c
@@ -1699,15 +1699,14 @@ target_ulong helper_dvpe(CPUMIPSState *env)
     CPUState *other_cs = first_cpu;
     target_ulong prev = env->mvp->CP0_MVPControl;
 
-    do {
+    CPU_FOREACH(other_cs) {
         MIPSCPU *other_cpu = MIPS_CPU(other_cs);
         /* Turn off all VPEs except the one executing the dvpe.  */
         if (&other_cpu->env != env) {
             other_cpu->env.mvp->CP0_MVPControl &= ~(1 << CP0MVPCo_EVP);
             mips_vpe_sleep(other_cpu);
         }
-        other_cs = other_cs->next_cpu;
-    } while (other_cs);
+    }
     return prev;
 }
 
@@ -1716,7 +1715,7 @@ target_ulong helper_evpe(CPUMIPSState *env)
     CPUState *other_cs = first_cpu;
     target_ulong prev = env->mvp->CP0_MVPControl;
 
-    do {
+    CPU_FOREACH(other_cs) {
         MIPSCPU *other_cpu = MIPS_CPU(other_cs);
 
         if (&other_cpu->env != env
@@ -1726,8 +1725,7 @@ target_ulong helper_evpe(CPUMIPSState *env)
             other_cpu->env.mvp->CP0_MVPControl |= (1 << CP0MVPCo_EVP);
             mips_vpe_wake(other_cpu); /* And wake it up.  */
         }
-        other_cs = other_cs->next_cpu;
-    } while (other_cs);
+    }
     return prev;
 }
 #endif /* !CONFIG_USER_ONLY */
diff --git a/target-ppc/excp_helper.c b/target-ppc/excp_helper.c
index e957761..c959460 100644
--- a/target-ppc/excp_helper.c
+++ b/target-ppc/excp_helper.c
@@ -1002,7 +1002,7 @@ void helper_msgsnd(target_ulong rb)
         return;
     }
 
-    for (cs = first_cpu; cs != NULL; cs = cs->next_cpu) {
+    CPU_FOREACH(cs) {
         PowerPCCPU *cpu = POWERPC_CPU(cs);
         CPUPPCState *cenv = &cpu->env;
 
diff --git a/target-s390x/misc_helper.c b/target-s390x/misc_helper.c
index 4afd7da..1690907 100644
--- a/target-s390x/misc_helper.c
+++ b/target-s390x/misc_helper.c
@@ -183,12 +183,12 @@ uint32_t HELPER(servc)(CPUS390XState *env, uint64_t r1, uint64_t r2)
 #ifndef CONFIG_USER_ONLY
 static void cpu_reset_all(void)
 {
-    CPUState *cpu;
+    CPUState *cs;
     S390CPUClass *scc;
 
-    for (cpu = first_cpu; cpu; cpu = cpu->next_cpu) {
-        scc = S390_CPU_GET_CLASS(CPU(cpu));
-        scc->cpu_reset(CPU(cpu));
+    CPU_FOREACH(cs) {
+        scc = S390_CPU_GET_CLASS(cs);
+        scc->cpu_reset(cs);
     }
 }
 
diff --git a/translate-all.c b/translate-all.c
index 3b5fc7c..2c923c6 100644
--- a/translate-all.c
+++ b/translate-all.c
@@ -696,7 +696,7 @@ void tb_flush(CPUArchState *env1)
     }
     tcg_ctx.tb_ctx.nb_tbs = 0;
 
-    for (cpu = first_cpu; cpu != NULL; cpu = cpu->next_cpu) {
+    CPU_FOREACH(cpu) {
         CPUArchState *env = cpu->env_ptr;
 
         memset(env->tb_jmp_cache, 0, TB_JMP_CACHE_SIZE * sizeof(void *));
@@ -850,7 +850,7 @@ void tb_phys_invalidate(TranslationBlock *tb, tb_page_addr_t page_addr)
 
     /* remove the TB from the hash list */
     h = tb_jmp_cache_hash_func(tb->pc);
-    for (cpu = first_cpu; cpu != NULL; cpu = cpu->next_cpu) {
+    CPU_FOREACH(cpu) {
         CPUArchState *env = cpu->env_ptr;
 
         if (env->tb_jmp_cache[h] == tb) {
commit 27013bf20d5d93ac75d398aa3608604e8ad91b5a
Author: Andreas Färber <afaerber at suse.de>
Date:   Wed Aug 21 18:36:35 2013 +0200

    a15mpcore: Use qemu_get_cpu() for generic timers
    
    This simplifies the loop and aids with refactoring of CPU list.
    
    Requested-by: Peter Maydell <peter.maydell at linaro.org>
    Signed-off-by: Andreas Färber <afaerber at suse.de>

diff --git a/hw/cpu/a15mpcore.c b/hw/cpu/a15mpcore.c
index af182da..9abba67 100644
--- a/hw/cpu/a15mpcore.c
+++ b/hw/cpu/a15mpcore.c
@@ -50,7 +50,6 @@ static int a15mp_priv_init(SysBusDevice *dev)
     SysBusDevice *busdev;
     const char *gictype = "arm_gic";
     int i;
-    CPUState *cpu;
 
     if (kvm_irqchip_in_kernel()) {
         gictype = "kvm-arm-gic";
@@ -72,8 +71,8 @@ static int a15mp_priv_init(SysBusDevice *dev)
     /* Wire the outputs from each CPU's generic timer to the
      * appropriate GIC PPI inputs
      */
-    for (i = 0, cpu = first_cpu; i < s->num_cpu; i++, cpu = cpu->next_cpu) {
-        DeviceState *cpudev = DEVICE(cpu);
+    for (i = 0; i < s->num_cpu; i++) {
+        DeviceState *cpudev = DEVICE(qemu_get_cpu(i));
         int ppibase = s->num_irq - 32 + i * 32;
         /* physical timer; we wire it up to the non-secure timer's ID,
          * since a real A15 always has TrustZone but QEMU doesn't.
commit 545825d4cda03ea292b7788b3401b99860efe8bc
Merge: 32f3bd6 6fb5874
Author: Aurelien Jarno <aurelien at aurel32.net>
Date:   Tue Sep 3 01:35:43 2013 +0200

    Merge branch 'tcg-next' of git://github.com/rth7680/qemu
    
    * 'tcg-next' of git://github.com/rth7680/qemu: (29 commits)
      tcg-i386: Make use of zero-extended memory helper routines
      tcg: Introduce zero and sign-extended versions of load helpers
      exec: Split softmmu_defs.h
      target: Include softmmu_exec.h where forgotten
      exec: Rename USUFFIX to LSUFFIX
      tcg-i386: Don't perform GETPC adjustment in TCG code
      exec: Reorganize the GETRA/GETPC macros
      configure: Allow x32 as a host
      tcg-i386: Adjust tcg_out_tlb_load for x32
      tcg-i386: Use intptr_t appropriately
      tcg: Fix jit debug for x32
      tcg: Use appropriate types in tcg_reg_alloc_call
      tcg: Change tcg_out_ld/st offset to intptr_t
      tcg: Change tcg_gen_exit_tb argument to uintptr_t
      tcg: Use uintptr_t in TCGHelperInfo
      tcg: Change relocation offsets to intptr_t
      tcg: Change memory offsets to intptr_t
      tcg: Change frame pointer offsets to intptr_t
      tcg: Define TCG_ptr properly
      tcg: Define TCG_TYPE_PTR properly
      ...

diff --cc tcg/mips/tcg-target.h
index 76ee831,a820328..c372522
--- a/tcg/mips/tcg-target.h
+++ b/tcg/mips/tcg-target.h
@@@ -110,15 -89,30 +110,17 @@@ extern bool use_mips32r2_instructions
  #define TCG_TARGET_HAS_eqv_i32          0
  #define TCG_TARGET_HAS_nand_i32         0
  #define TCG_TARGET_HAS_muls2_i32        1
+ #define TCG_TARGET_HAS_muluh_i32        1
+ #define TCG_TARGET_HAS_mulsh_i32        1
  
 -/* optional instructions only implemented on MIPS4, MIPS32 and Loongson 2 */
 -#if (defined(__mips_isa_rev) && (__mips_isa_rev >= 1)) || \
 -    defined(_MIPS_ARCH_LOONGSON2E) || defined(_MIPS_ARCH_LOONGSON2F) || \
 -    defined(_MIPS_ARCH_MIPS4)
 -#define TCG_TARGET_HAS_movcond_i32      1
 -#else
 -#define TCG_TARGET_HAS_movcond_i32      0
 -#endif
 -
 -/* optional instructions only implemented on MIPS32R2 */
 -#if defined(__mips_isa_rev) && (__mips_isa_rev >= 2)
 -#define TCG_TARGET_HAS_bswap16_i32      1
 -#define TCG_TARGET_HAS_bswap32_i32      1
 -#define TCG_TARGET_HAS_rot_i32          1
 -#define TCG_TARGET_HAS_deposit_i32      1
 -#else
 -#define TCG_TARGET_HAS_bswap16_i32      0
 -#define TCG_TARGET_HAS_bswap32_i32      0
 -#define TCG_TARGET_HAS_rot_i32          0
 -#define TCG_TARGET_HAS_deposit_i32      0
 -#endif
 +/* optional instructions detected at runtime */
 +#define TCG_TARGET_HAS_movcond_i32      use_movnz_instructions
 +#define TCG_TARGET_HAS_bswap16_i32      use_mips32r2_instructions
 +#define TCG_TARGET_HAS_bswap32_i32      use_mips32r2_instructions
 +#define TCG_TARGET_HAS_deposit_i32      use_mips32r2_instructions
 +#define TCG_TARGET_HAS_ext8s_i32        use_mips32r2_instructions
 +#define TCG_TARGET_HAS_ext16s_i32       use_mips32r2_instructions
 +#define TCG_TARGET_HAS_rot_i32          use_mips32r2_instructions
  
  /* optional instructions automatically implemented */
  #define TCG_TARGET_HAS_neg_i32          0 /* sub  rd, zero, rt   */
commit 32f3bd6d4d6d6f835cbc2b9241fe8c32d2898d73
Merge: 3207bf2 7e47226
Author: Aurelien Jarno <aurelien at aurel32.net>
Date:   Tue Sep 3 01:35:25 2013 +0200

    Merge branch 'ppc-for-upstream' of git://github.com/agraf/qemu
    
    * 'ppc-for-upstream' of git://github.com/agraf/qemu:
      PPC: spapr: iommu: rework traces
      spapr: add "stop-self" RTAS call required to support hot CPU unplug
      PPC: KVM: Compile fix for qemu_notify_event
      pseries: Add H_SET_MODE hcall to change guest exception endianness
      xics: move registration of global state to realize()
      spapr-pci: rework MSI/MSIX
      target-ppc: Use #define instead of opencoding SLB valid bit
      spapr-pci: fix config space access to support bridges
      target-ppc: fix bit extraction for FPBF and FPL
      ppc405_boards: Don't enforce presence of firmware for qtest
      ppc405_uc: Disable debug output
      ppc405_boards: Disable debug output
      ppc: virtex_ml507: QEMU_OPTION_dtb support for this machine.
      disas/ppc.c: Fix little endian disassembly
      target-ppc: POWER7 supports the MSR_LE bit
      target-ppc: USE LPCR_ILE to control exception endian on POWER7
      pseries: Fix stalls on hypervisor virtual console
      PPC: E500: Generate device tree on reset

commit 3207bf2549a1a84c577d2f6a481192566a059163
Author: Aurelien Jarno <aurelien at aurel32.net>
Date:   Thu Aug 15 17:57:59 2013 +0200

    tcg/mips: only enable ext8s/ext16s ops on MIPS32R2
    
    On MIPS ext8s and ext16s ops are implemented with a dedicated
    instruction only on MIPS32R2, otherwise the same kind of implementation
    than at TCG level (shift left followed by shift right) is used.
    
    Change that by only implementing the ext8s and ext16s ops on MIPS32R2 so
    that optimizations can be done by the optimizer. Use an inline version to
    avoid having to test again for MIPS32R2 instructions. Keep the shift
    implementation for the ld/st routines.
    
    Reviewed-by: Richard Henderson <rth at twiddle.net>
    Signed-off-by: Aurelien Jarno <aurelien at aurel32.net>

diff --git a/tcg/mips/tcg-target.c b/tcg/mips/tcg-target.c
index daaf722..f32bea7 100644
--- a/tcg/mips/tcg-target.c
+++ b/tcg/mips/tcg-target.c
@@ -1515,10 +1515,10 @@ static inline void tcg_out_op(TCGContext *s, TCGOpcode opc,
         break;
 
     case INDEX_op_ext8s_i32:
-        tcg_out_ext8s(s, args[0], args[1]);
+        tcg_out_opc_reg(s, OPC_SEB, args[0], 0, args[1]);
         break;
     case INDEX_op_ext16s_i32:
-        tcg_out_ext16s(s, args[0], args[1]);
+        tcg_out_opc_reg(s, OPC_SEH, args[0], 0, args[1]);
         break;
 
     case INDEX_op_deposit_i32:
diff --git a/tcg/mips/tcg-target.h b/tcg/mips/tcg-target.h
index 43072e3..76ee831 100644
--- a/tcg/mips/tcg-target.h
+++ b/tcg/mips/tcg-target.h
@@ -105,8 +105,6 @@ extern bool use_mips32r2_instructions;
 #define TCG_TARGET_HAS_rem_i32          1
 #define TCG_TARGET_HAS_not_i32          1
 #define TCG_TARGET_HAS_nor_i32          1
-#define TCG_TARGET_HAS_ext8s_i32        1
-#define TCG_TARGET_HAS_ext16s_i32       1
 #define TCG_TARGET_HAS_andc_i32         0
 #define TCG_TARGET_HAS_orc_i32          0
 #define TCG_TARGET_HAS_eqv_i32          0
@@ -118,6 +116,8 @@ extern bool use_mips32r2_instructions;
 #define TCG_TARGET_HAS_bswap16_i32      use_mips32r2_instructions
 #define TCG_TARGET_HAS_bswap32_i32      use_mips32r2_instructions
 #define TCG_TARGET_HAS_deposit_i32      use_mips32r2_instructions
+#define TCG_TARGET_HAS_ext8s_i32        use_mips32r2_instructions
+#define TCG_TARGET_HAS_ext16s_i32       use_mips32r2_instructions
 #define TCG_TARGET_HAS_rot_i32          use_mips32r2_instructions
 
 /* optional instructions automatically implemented */
commit df81ff51d50b22c52e609e13d5292d09e4634659
Author: Aurelien Jarno <aurelien at aurel32.net>
Date:   Wed Aug 28 13:51:40 2013 +0200

    tcg/mips: inline bswap16/bswap32 ops
    
    Use an inline version for the bswap16 and bswap32 ops to avoid
    testing for MIPS32R2 instructions availability, as these ops are
    only available in that case.
    
    Reviewed-by: Richard Henderson <rth at twiddle.net>
    Signed-off-by: Aurelien Jarno <aurelien at aurel32.net>

diff --git a/tcg/mips/tcg-target.c b/tcg/mips/tcg-target.c
index 9b518c2..daaf722 100644
--- a/tcg/mips/tcg-target.c
+++ b/tcg/mips/tcg-target.c
@@ -1506,13 +1506,12 @@ static inline void tcg_out_op(TCGContext *s, TCGOpcode opc,
         }
         break;
 
-    /* The bswap routines do not work on non-R2 CPU. In that case
-       we let TCG generating the corresponding code. */
     case INDEX_op_bswap16_i32:
-        tcg_out_bswap16(s, args[0], args[1]);
+        tcg_out_opc_reg(s, OPC_WSBH, args[0], 0, args[1]);
         break;
     case INDEX_op_bswap32_i32:
-        tcg_out_bswap32(s, args[0], args[1]);
+        tcg_out_opc_reg(s, OPC_WSBH, args[0], 0, args[1]);
+        tcg_out_opc_sa(s, OPC_ROTR, args[0], args[0], 16);
         break;
 
     case INDEX_op_ext8s_i32:
commit 988902fc3bc599f7431461b790f3d63d3a2357f9
Author: Aurelien Jarno <aurelien at aurel32.net>
Date:   Thu Aug 15 17:57:59 2013 +0200

    tcg/mips: detect available host instructions at runtime
    
    Now that TCG supports enabling and disabling ops at runtime, it's
    possible to detect the available host instructions at runtime, and
    enable the corresponding ops accordingly.
    
    Unfortunately it's not easy to probe for available instructions on
    MIPS, the information is partially available in /proc/cpuinfo, and
    not available in AUXV. This patch therefore probes for the instructions
    by trying to execute them and by catching a possible SIGILL signal.
    
    Reviewed-by: Richard Henderson <rth at twiddle.net>
    Signed-off-by: Aurelien Jarno <aurelien at aurel32.net>

diff --git a/tcg/mips/tcg-target.c b/tcg/mips/tcg-target.c
index 793532e..9b518c2 100644
--- a/tcg/mips/tcg-target.c
+++ b/tcg/mips/tcg-target.c
@@ -422,83 +422,83 @@ static inline void tcg_out_movi(TCGContext *s, TCGType type,
 
 static inline void tcg_out_bswap16(TCGContext *s, TCGReg ret, TCGReg arg)
 {
-#if defined(__mips_isa_rev) && (__mips_isa_rev >= 2)
-    tcg_out_opc_reg(s, OPC_WSBH, ret, 0, arg);
-#else
-    /* ret and arg can't be register at */
-    if (ret == TCG_REG_AT || arg == TCG_REG_AT) {
-        tcg_abort();
-    }
+    if (use_mips32r2_instructions) {
+        tcg_out_opc_reg(s, OPC_WSBH, ret, 0, arg);
+    } else {
+        /* ret and arg can't be register at */
+        if (ret == TCG_REG_AT || arg == TCG_REG_AT) {
+            tcg_abort();
+        }
 
-    tcg_out_opc_sa(s, OPC_SRL, TCG_REG_AT, arg, 8);
-    tcg_out_opc_sa(s, OPC_SLL, ret, arg, 8);
-    tcg_out_opc_imm(s, OPC_ANDI, ret, ret, 0xff00);
-    tcg_out_opc_reg(s, OPC_OR, ret, ret, TCG_REG_AT);
-#endif
+        tcg_out_opc_sa(s, OPC_SRL, TCG_REG_AT, arg, 8);
+        tcg_out_opc_sa(s, OPC_SLL, ret, arg, 8);
+        tcg_out_opc_imm(s, OPC_ANDI, ret, ret, 0xff00);
+        tcg_out_opc_reg(s, OPC_OR, ret, ret, TCG_REG_AT);
+    }
 }
 
 static inline void tcg_out_bswap16s(TCGContext *s, TCGReg ret, TCGReg arg)
 {
-#if defined(__mips_isa_rev) && (__mips_isa_rev >= 2)
-    tcg_out_opc_reg(s, OPC_WSBH, ret, 0, arg);
-    tcg_out_opc_reg(s, OPC_SEH, ret, 0, ret);
-#else
-    /* ret and arg can't be register at */
-    if (ret == TCG_REG_AT || arg == TCG_REG_AT) {
-        tcg_abort();
-    }
+    if (use_mips32r2_instructions) {
+        tcg_out_opc_reg(s, OPC_WSBH, ret, 0, arg);
+        tcg_out_opc_reg(s, OPC_SEH, ret, 0, ret);
+    } else {
+        /* ret and arg can't be register at */
+        if (ret == TCG_REG_AT || arg == TCG_REG_AT) {
+            tcg_abort();
+        }
 
-    tcg_out_opc_sa(s, OPC_SRL, TCG_REG_AT, arg, 8);
-    tcg_out_opc_sa(s, OPC_SLL, ret, arg, 24);
-    tcg_out_opc_sa(s, OPC_SRA, ret, ret, 16);
-    tcg_out_opc_reg(s, OPC_OR, ret, ret, TCG_REG_AT);
-#endif
+        tcg_out_opc_sa(s, OPC_SRL, TCG_REG_AT, arg, 8);
+        tcg_out_opc_sa(s, OPC_SLL, ret, arg, 24);
+        tcg_out_opc_sa(s, OPC_SRA, ret, ret, 16);
+        tcg_out_opc_reg(s, OPC_OR, ret, ret, TCG_REG_AT);
+    }
 }
 
 static inline void tcg_out_bswap32(TCGContext *s, TCGReg ret, TCGReg arg)
 {
-#if defined(__mips_isa_rev) && (__mips_isa_rev >= 2)
-    tcg_out_opc_reg(s, OPC_WSBH, ret, 0, arg);
-    tcg_out_opc_sa(s, OPC_ROTR, ret, ret, 16);
-#else
-    /* ret and arg must be different and can't be register at */
-    if (ret == arg || ret == TCG_REG_AT || arg == TCG_REG_AT) {
-        tcg_abort();
-    }
+    if (use_mips32r2_instructions) {
+        tcg_out_opc_reg(s, OPC_WSBH, ret, 0, arg);
+        tcg_out_opc_sa(s, OPC_ROTR, ret, ret, 16);
+    } else {
+        /* ret and arg must be different and can't be register at */
+        if (ret == arg || ret == TCG_REG_AT || arg == TCG_REG_AT) {
+            tcg_abort();
+        }
 
-    tcg_out_opc_sa(s, OPC_SLL, ret, arg, 24);
+        tcg_out_opc_sa(s, OPC_SLL, ret, arg, 24);
 
-    tcg_out_opc_sa(s, OPC_SRL, TCG_REG_AT, arg, 24);
-    tcg_out_opc_reg(s, OPC_OR, ret, ret, TCG_REG_AT);
+        tcg_out_opc_sa(s, OPC_SRL, TCG_REG_AT, arg, 24);
+        tcg_out_opc_reg(s, OPC_OR, ret, ret, TCG_REG_AT);
 
-    tcg_out_opc_imm(s, OPC_ANDI, TCG_REG_AT, arg, 0xff00);
-    tcg_out_opc_sa(s, OPC_SLL, TCG_REG_AT, TCG_REG_AT, 8);
-    tcg_out_opc_reg(s, OPC_OR, ret, ret, TCG_REG_AT);
+        tcg_out_opc_imm(s, OPC_ANDI, TCG_REG_AT, arg, 0xff00);
+        tcg_out_opc_sa(s, OPC_SLL, TCG_REG_AT, TCG_REG_AT, 8);
+        tcg_out_opc_reg(s, OPC_OR, ret, ret, TCG_REG_AT);
 
-    tcg_out_opc_sa(s, OPC_SRL, TCG_REG_AT, arg, 8);
-    tcg_out_opc_imm(s, OPC_ANDI, TCG_REG_AT, TCG_REG_AT, 0xff00);
-    tcg_out_opc_reg(s, OPC_OR, ret, ret, TCG_REG_AT);
-#endif
+        tcg_out_opc_sa(s, OPC_SRL, TCG_REG_AT, arg, 8);
+        tcg_out_opc_imm(s, OPC_ANDI, TCG_REG_AT, TCG_REG_AT, 0xff00);
+        tcg_out_opc_reg(s, OPC_OR, ret, ret, TCG_REG_AT);
+    }
 }
 
 static inline void tcg_out_ext8s(TCGContext *s, TCGReg ret, TCGReg arg)
 {
-#if defined(__mips_isa_rev) && (__mips_isa_rev >= 2)
-    tcg_out_opc_reg(s, OPC_SEB, ret, 0, arg);
-#else
-    tcg_out_opc_sa(s, OPC_SLL, ret, arg, 24);
-    tcg_out_opc_sa(s, OPC_SRA, ret, ret, 24);
-#endif
+    if (use_mips32r2_instructions) {
+        tcg_out_opc_reg(s, OPC_SEB, ret, 0, arg);
+    } else {
+        tcg_out_opc_sa(s, OPC_SLL, ret, arg, 24);
+        tcg_out_opc_sa(s, OPC_SRA, ret, ret, 24);
+    }
 }
 
 static inline void tcg_out_ext16s(TCGContext *s, TCGReg ret, TCGReg arg)
 {
-#if defined(__mips_isa_rev) && (__mips_isa_rev >= 2)
-    tcg_out_opc_reg(s, OPC_SEH, ret, 0, arg);
-#else
-    tcg_out_opc_sa(s, OPC_SLL, ret, arg, 16);
-    tcg_out_opc_sa(s, OPC_SRA, ret, ret, 16);
-#endif
+    if (use_mips32r2_instructions) {
+        tcg_out_opc_reg(s, OPC_SEH, ret, 0, arg);
+    } else {
+        tcg_out_opc_sa(s, OPC_SLL, ret, arg, 16);
+        tcg_out_opc_sa(s, OPC_SRA, ret, ret, 16);
+    }
 }
 
 static inline void tcg_out_ldst(TCGContext *s, int opc, TCGArg arg,
@@ -1406,12 +1406,12 @@ static inline void tcg_out_op(TCGContext *s, TCGOpcode opc,
         tcg_out_mov(s, TCG_TYPE_I32, args[0], TCG_REG_AT);
         break;
     case INDEX_op_mul_i32:
-#if defined(__mips_isa_rev) && (__mips_isa_rev >= 1)
-        tcg_out_opc_reg(s, OPC_MUL, args[0], args[1], args[2]);
-#else
-        tcg_out_opc_reg(s, OPC_MULT, 0, args[1], args[2]);
-        tcg_out_opc_reg(s, OPC_MFLO, args[0], 0, 0);
-#endif
+        if (use_mips32_instructions) {
+            tcg_out_opc_reg(s, OPC_MUL, args[0], args[1], args[2]);
+        } else {
+            tcg_out_opc_reg(s, OPC_MULT, 0, args[1], args[2]);
+            tcg_out_opc_reg(s, OPC_MFLO, args[0], 0, 0);
+        }
         break;
     case INDEX_op_muls2_i32:
         tcg_out_opc_reg(s, OPC_MULT, 0, args[2], args[3]);
@@ -1617,29 +1617,19 @@ static const TCGTargetOpDef mips_op_defs[] = {
     { INDEX_op_shl_i32, { "r", "rZ", "ri" } },
     { INDEX_op_shr_i32, { "r", "rZ", "ri" } },
     { INDEX_op_sar_i32, { "r", "rZ", "ri" } },
-#if TCG_TARGET_HAS_rot_i32
     { INDEX_op_rotr_i32, { "r", "rZ", "ri" } },
     { INDEX_op_rotl_i32, { "r", "rZ", "ri" } },
-#endif
 
-#if TCG_TARGET_HAS_bswap16_i32
     { INDEX_op_bswap16_i32, { "r", "r" } },
-#endif
-#if TCG_TARGET_HAS_bswap32_i32
     { INDEX_op_bswap32_i32, { "r", "r" } },
-#endif
 
     { INDEX_op_ext8s_i32, { "r", "rZ" } },
     { INDEX_op_ext16s_i32, { "r", "rZ" } },
 
-#if TCG_TARGET_HAS_deposit_i32
     { INDEX_op_deposit_i32, { "r", "0", "rZ" } },
-#endif
 
     { INDEX_op_brcond_i32, { "rZ", "rZ" } },
-#if TCG_TARGET_HAS_movcond_i32
     { INDEX_op_movcond_i32, { "r", "rZ", "rZ", "rZ", "0" } },
-#endif
     { INDEX_op_setcond_i32, { "r", "rZ", "rZ" } },
     { INDEX_op_setcond2_i32, { "r", "rZ", "rZ", "rZ", "rZ" } },
 
@@ -1688,6 +1678,86 @@ static int tcg_target_callee_save_regs[] = {
     TCG_REG_RA,       /* should be last for ABI compliance */
 };
 
+/* The Linux kernel doesn't provide any information about the available
+   instruction set. Probe it using a signal handler. */
+
+#include <signal.h>
+
+#ifndef use_movnz_instructions
+bool use_movnz_instructions = false;
+#endif
+
+#ifndef use_mips32_instructions
+bool use_mips32_instructions = false;
+#endif
+
+#ifndef use_mips32r2_instructions
+bool use_mips32r2_instructions = false;
+#endif
+
+static volatile sig_atomic_t got_sigill;
+
+static void sigill_handler(int signo, siginfo_t *si, void *data)
+{
+    /* Skip the faulty instruction */
+    ucontext_t *uc = (ucontext_t *)data;
+    uc->uc_mcontext.pc += 4;
+
+    got_sigill = 1;
+}
+
+static void tcg_target_detect_isa(void)
+{
+    struct sigaction sa_old, sa_new;
+
+    memset(&sa_new, 0, sizeof(sa_new));
+    sa_new.sa_flags = SA_SIGINFO;
+    sa_new.sa_sigaction = sigill_handler;
+    sigaction(SIGILL, &sa_new, &sa_old);
+
+    /* Probe for movn/movz, necessary to implement movcond. */
+#ifndef use_movnz_instructions
+    got_sigill = 0;
+    asm volatile(".set push\n"
+                 ".set mips32\n"
+                 "movn $zero, $zero, $zero\n"
+                 "movz $zero, $zero, $zero\n"
+                 ".set pop\n"
+                 : : : );
+    use_movnz_instructions = !got_sigill;
+#endif
+
+    /* Probe for MIPS32 instructions. As no subsetting is allowed
+       by the specification, it is only necessary to probe for one
+       of the instructions. */
+#ifndef use_mips32_instructions
+    got_sigill = 0;
+    asm volatile(".set push\n"
+                 ".set mips32\n"
+                 "mul $zero, $zero\n"
+                 ".set pop\n"
+                 : : : );
+    use_mips32_instructions = !got_sigill;
+#endif
+
+    /* Probe for MIPS32r2 instructions if MIPS32 instructions are
+       available. As no subsetting is allowed by the specification,
+       it is only necessary to probe for one of the instructions. */
+#ifndef use_mips32r2_instructions
+    if (use_mips32_instructions) {
+        got_sigill = 0;
+        asm volatile(".set push\n"
+                     ".set mips32r2\n"
+                     "seb $zero, $zero\n"
+                     ".set pop\n"
+                     : : : );
+        use_mips32r2_instructions = !got_sigill;
+    }
+#endif
+
+    sigaction(SIGILL, &sa_old, NULL);
+}
+
 /* Generate global QEMU prologue and epilogue code */
 static void tcg_target_qemu_prologue(TCGContext *s)
 {
@@ -1727,6 +1797,7 @@ static void tcg_target_qemu_prologue(TCGContext *s)
 
 static void tcg_target_init(TCGContext *s)
 {
+    tcg_target_detect_isa();
     tcg_regset_set(tcg_target_available_regs[TCG_TYPE_I32], 0xffffffff);
     tcg_regset_set(tcg_target_call_clobber_regs,
                    (1 << TCG_REG_V0) |
diff --git a/tcg/mips/tcg-target.h b/tcg/mips/tcg-target.h
index a438950..43072e3 100644
--- a/tcg/mips/tcg-target.h
+++ b/tcg/mips/tcg-target.h
@@ -77,6 +77,29 @@ typedef enum {
 #define TCG_TARGET_CALL_STACK_OFFSET 16
 #define TCG_TARGET_CALL_ALIGN_ARGS 1
 
+/* MOVN/MOVZ instructions detection */
+#if (defined(__mips_isa_rev) && (__mips_isa_rev >= 1)) || \
+    defined(_MIPS_ARCH_LOONGSON2E) || defined(_MIPS_ARCH_LOONGSON2F) || \
+    defined(_MIPS_ARCH_MIPS4)
+#define use_movnz_instructions  1
+#else
+extern bool use_movnz_instructions;
+#endif
+
+/* MIPS32 instruction set detection */
+#if defined(__mips_isa_rev) && (__mips_isa_rev >= 1)
+#define use_mips32_instructions  1
+#else
+extern bool use_mips32_instructions;
+#endif
+
+/* MIPS32R2 instruction set detection */
+#if defined(__mips_isa_rev) && (__mips_isa_rev >= 2)
+#define use_mips32r2_instructions  1
+#else
+extern bool use_mips32r2_instructions;
+#endif
+
 /* optional instructions */
 #define TCG_TARGET_HAS_div_i32          1
 #define TCG_TARGET_HAS_rem_i32          1
@@ -90,27 +113,12 @@ typedef enum {
 #define TCG_TARGET_HAS_nand_i32         0
 #define TCG_TARGET_HAS_muls2_i32        1
 
-/* optional instructions only implemented on MIPS4, MIPS32 and Loongson 2 */
-#if (defined(__mips_isa_rev) && (__mips_isa_rev >= 1)) || \
-    defined(_MIPS_ARCH_LOONGSON2E) || defined(_MIPS_ARCH_LOONGSON2F) || \
-    defined(_MIPS_ARCH_MIPS4)
-#define TCG_TARGET_HAS_movcond_i32      1
-#else
-#define TCG_TARGET_HAS_movcond_i32      0
-#endif
-
-/* optional instructions only implemented on MIPS32R2 */
-#if defined(__mips_isa_rev) && (__mips_isa_rev >= 2)
-#define TCG_TARGET_HAS_bswap16_i32      1
-#define TCG_TARGET_HAS_bswap32_i32      1
-#define TCG_TARGET_HAS_rot_i32          1
-#define TCG_TARGET_HAS_deposit_i32      1
-#else
-#define TCG_TARGET_HAS_bswap16_i32      0
-#define TCG_TARGET_HAS_bswap32_i32      0
-#define TCG_TARGET_HAS_rot_i32          0
-#define TCG_TARGET_HAS_deposit_i32      0
-#endif
+/* optional instructions detected at runtime */
+#define TCG_TARGET_HAS_movcond_i32      use_movnz_instructions
+#define TCG_TARGET_HAS_bswap16_i32      use_mips32r2_instructions
+#define TCG_TARGET_HAS_bswap32_i32      use_mips32r2_instructions
+#define TCG_TARGET_HAS_deposit_i32      use_mips32r2_instructions
+#define TCG_TARGET_HAS_rot_i32          use_mips32r2_instructions
 
 /* optional instructions automatically implemented */
 #define TCG_TARGET_HAS_neg_i32          0 /* sub  rd, zero, rt   */
commit 6fb5874590589585cdcad4ca2431d9d8d4d491b1
Author: Richard Henderson <rth at twiddle.net>
Date:   Thu Aug 29 15:00:16 2013 -0700

    tcg-i386: Make use of zero-extended memory helper routines
    
    For 8 and 16-bit unsigned loads, rely on the zero-extension
    from the helper and use a smaller 32-bit move insn.
    
    Reviewed-by: Aurelien Jarno <aurelien at aurel32.net>
    Signed-off-by: Richard Henderson <rth at twiddle.net>

diff --git a/tcg/i386/tcg-target.c b/tcg/i386/tcg-target.c
index 3ee54f1..c1f0741 100644
--- a/tcg/i386/tcg-target.c
+++ b/tcg/i386/tcg-target.c
@@ -1531,20 +1531,17 @@ static void tcg_out_qemu_ld_slow_path(TCGContext *s, TCGLabelQemuLdst *l)
     case 1 | 4:
         tcg_out_ext16s(s, data_reg, TCG_REG_EAX, P_REXW);
         break;
-    case 0:
-        tcg_out_ext8u(s, data_reg, TCG_REG_EAX);
-        break;
-    case 1:
-        tcg_out_ext16u(s, data_reg, TCG_REG_EAX);
-        break;
-    case 2:
-        tcg_out_mov(s, TCG_TYPE_I32, data_reg, TCG_REG_EAX);
-        break;
 #if TCG_TARGET_REG_BITS == 64
     case 2 | 4:
         tcg_out_ext32s(s, data_reg, TCG_REG_EAX);
         break;
 #endif
+    case 0:
+    case 1:
+        /* Note that the helpers have zero-extended to tcg_target_long.  */
+    case 2:
+        tcg_out_mov(s, TCG_TYPE_I32, data_reg, TCG_REG_EAX);
+        break;
     case 3:
         if (TCG_TARGET_REG_BITS == 64) {
             tcg_out_mov(s, TCG_TYPE_I64, data_reg, TCG_REG_RAX);
commit c8f94df5934afd9b2011773aaee0fdef714ff573
Author: Richard Henderson <rth at twiddle.net>
Date:   Tue Aug 27 14:09:14 2013 -0700

    tcg: Introduce zero and sign-extended versions of load helpers
    
    Reviewed-by: Aurelien Jarno <aurelien at aurel32.net>
    Signed-off-by: Richard Henderson <rth at twiddle.net>

diff --git a/include/exec/softmmu_template.h b/include/exec/softmmu_template.h
index f9922e2..5bbc56a 100644
--- a/include/exec/softmmu_template.h
+++ b/include/exec/softmmu_template.h
@@ -29,23 +29,39 @@
 #if DATA_SIZE == 8
 #define SUFFIX q
 #define LSUFFIX q
-#define DATA_TYPE uint64_t
+#define SDATA_TYPE  int64_t
 #elif DATA_SIZE == 4
 #define SUFFIX l
 #define LSUFFIX l
-#define DATA_TYPE uint32_t
+#define SDATA_TYPE  int32_t
 #elif DATA_SIZE == 2
 #define SUFFIX w
 #define LSUFFIX uw
-#define DATA_TYPE uint16_t
+#define SDATA_TYPE  int16_t
 #elif DATA_SIZE == 1
 #define SUFFIX b
 #define LSUFFIX ub
-#define DATA_TYPE uint8_t
+#define SDATA_TYPE  int8_t
 #else
 #error unsupported data size
 #endif
 
+#define DATA_TYPE   glue(u, SDATA_TYPE)
+
+/* For the benefit of TCG generated code, we want to avoid the complication
+   of ABI-specific return type promotion and always return a value extended
+   to the register size of the host.  This is tcg_target_long, except in the
+   case of a 32-bit host and 64-bit data, and for that we always have
+   uint64_t.  Don't bother with this widened value for SOFTMMU_CODE_ACCESS.  */
+#if defined(SOFTMMU_CODE_ACCESS) || DATA_SIZE == 8
+# define WORD_TYPE  DATA_TYPE
+# define USUFFIX    SUFFIX
+#else
+# define WORD_TYPE  tcg_target_ulong
+# define USUFFIX    glue(u, SUFFIX)
+# define SSUFFIX    glue(s, SUFFIX)
+#endif
+
 #ifdef SOFTMMU_CODE_ACCESS
 #define READ_ACCESS_TYPE 2
 #define ADDR_READ addr_code
@@ -77,10 +93,10 @@ static inline DATA_TYPE glue(io_read, SUFFIX)(CPUArchState *env,
 #ifdef SOFTMMU_CODE_ACCESS
 static
 #endif
-DATA_TYPE
-glue(glue(helper_ret_ld, SUFFIX), MMUSUFFIX)(CPUArchState *env,
-                                             target_ulong addr, int mmu_idx,
-                                             uintptr_t retaddr)
+WORD_TYPE
+glue(glue(helper_ret_ld, USUFFIX), MMUSUFFIX)(CPUArchState *env,
+                                              target_ulong addr, int mmu_idx,
+                                              uintptr_t retaddr)
 {
     int index = (addr >> TARGET_PAGE_BITS) & (CPU_TLB_SIZE - 1);
     target_ulong tlb_addr = env->tlb_table[mmu_idx][index].ADDR_READ;
@@ -126,9 +142,9 @@ glue(glue(helper_ret_ld, SUFFIX), MMUSUFFIX)(CPUArchState *env,
         addr2 = addr1 + DATA_SIZE;
         /* Note the adjustment at the beginning of the function.
            Undo that for the recursion.  */
-        res1 = glue(glue(helper_ret_ld, SUFFIX), MMUSUFFIX)
+        res1 = glue(glue(helper_ret_ld, USUFFIX), MMUSUFFIX)
             (env, addr1, mmu_idx, retaddr + GETPC_ADJ);
-        res2 = glue(glue(helper_ret_ld, SUFFIX), MMUSUFFIX)
+        res2 = glue(glue(helper_ret_ld, USUFFIX), MMUSUFFIX)
             (env, addr2, mmu_idx, retaddr + GETPC_ADJ);
         shift = (addr & (DATA_SIZE - 1)) * 8;
 #ifdef TARGET_WORDS_BIGENDIAN
@@ -147,19 +163,33 @@ glue(glue(helper_ret_ld, SUFFIX), MMUSUFFIX)(CPUArchState *env,
 #endif
 
     haddr = addr + env->tlb_table[mmu_idx][index].addend;
-    return glue(glue(ld, LSUFFIX), _raw)((uint8_t *)haddr);
+    /* Note that ldl_raw is defined with type "int".  */
+    return (DATA_TYPE) glue(glue(ld, LSUFFIX), _raw)((uint8_t *)haddr);
 }
 
 DATA_TYPE
 glue(glue(helper_ld, SUFFIX), MMUSUFFIX)(CPUArchState *env, target_ulong addr,
                                          int mmu_idx)
 {
-    return glue(glue(helper_ret_ld, SUFFIX), MMUSUFFIX)(env, addr, mmu_idx,
+    return glue(glue(helper_ret_ld, USUFFIX), MMUSUFFIX)(env, addr, mmu_idx,
                                                         GETRA_EXT());
 }
 
 #ifndef SOFTMMU_CODE_ACCESS
 
+/* Provide signed versions of the load routines as well.  We can of course
+   avoid this for 64-bit data, or for 32-bit data on 32-bit host.  */
+#if DATA_SIZE * 8 < TCG_TARGET_REG_BITS
+WORD_TYPE
+glue(glue(helper_ret_ld, SSUFFIX), MMUSUFFIX)(CPUArchState *env,
+                                              target_ulong addr, int mmu_idx,
+                                              uintptr_t retaddr)
+{
+    return (SDATA_TYPE) glue(glue(helper_ret_ld, USUFFIX), MMUSUFFIX)
+        (env, addr, mmu_idx, retaddr);
+}
+#endif
+
 static inline void glue(io_write, SUFFIX)(CPUArchState *env,
                                           hwaddr physaddr,
                                           DATA_TYPE val,
@@ -267,3 +297,7 @@ glue(glue(helper_st, SUFFIX), MMUSUFFIX)(CPUArchState *env, target_ulong addr,
 #undef LSUFFIX
 #undef DATA_SIZE
 #undef ADDR_READ
+#undef WORD_TYPE
+#undef SDATA_TYPE
+#undef USUFFIX
+#undef SSUFFIX
diff --git a/tcg/i386/tcg-target.c b/tcg/i386/tcg-target.c
index a0cfe88..3ee54f1 100644
--- a/tcg/i386/tcg-target.c
+++ b/tcg/i386/tcg-target.c
@@ -1025,9 +1025,9 @@ static void tcg_out_jmp(TCGContext *s, uintptr_t dest)
  *                                     int mmu_idx, uintptr_t ra)
  */
 static const void * const qemu_ld_helpers[4] = {
-    helper_ret_ldb_mmu,
-    helper_ret_ldw_mmu,
-    helper_ret_ldl_mmu,
+    helper_ret_ldub_mmu,
+    helper_ret_lduw_mmu,
+    helper_ret_ldul_mmu,
     helper_ret_ldq_mmu,
 };
 
diff --git a/tcg/tcg.h b/tcg/tcg.h
index 30ec952..902c751 100644
--- a/tcg/tcg.h
+++ b/tcg/tcg.h
@@ -754,15 +754,24 @@ void tcg_out_tb_finalize(TCGContext *s);
  * Memory helpers that will be used by TCG generated code.
  */
 #ifdef CONFIG_SOFTMMU
-uint8_t helper_ret_ldb_mmu(CPUArchState *env, target_ulong addr,
-                           int mmu_idx, uintptr_t retaddr);
-uint16_t helper_ret_ldw_mmu(CPUArchState *env, target_ulong addr,
-                            int mmu_idx, uintptr_t retaddr);
-uint32_t helper_ret_ldl_mmu(CPUArchState *env, target_ulong addr,
-                            int mmu_idx, uintptr_t retaddr);
+/* Value zero-extended to tcg register size.  */
+tcg_target_ulong helper_ret_ldub_mmu(CPUArchState *env, target_ulong addr,
+                                     int mmu_idx, uintptr_t retaddr);
+tcg_target_ulong helper_ret_lduw_mmu(CPUArchState *env, target_ulong addr,
+                                     int mmu_idx, uintptr_t retaddr);
+tcg_target_ulong helper_ret_ldul_mmu(CPUArchState *env, target_ulong addr,
+                                     int mmu_idx, uintptr_t retaddr);
 uint64_t helper_ret_ldq_mmu(CPUArchState *env, target_ulong addr,
                             int mmu_idx, uintptr_t retaddr);
 
+/* Value sign-extended to tcg register size.  */
+tcg_target_ulong helper_ret_ldsb_mmu(CPUArchState *env, target_ulong addr,
+                                     int mmu_idx, uintptr_t retaddr);
+tcg_target_ulong helper_ret_ldsw_mmu(CPUArchState *env, target_ulong addr,
+                                     int mmu_idx, uintptr_t retaddr);
+tcg_target_ulong helper_ret_ldsl_mmu(CPUArchState *env, target_ulong addr,
+                                     int mmu_idx, uintptr_t retaddr);
+
 void helper_ret_stb_mmu(CPUArchState *env, target_ulong addr, uint8_t val,
                         int mmu_idx, uintptr_t retaddr);
 void helper_ret_stw_mmu(CPUArchState *env, target_ulong addr, uint16_t val,
commit e58eb534133f8ccaa957a33a06ccdb9129f2c842
Author: Richard Henderson <rth at twiddle.net>
Date:   Tue Aug 27 13:13:44 2013 -0700

    exec: Split softmmu_defs.h
    
    The _cmmu helpers can be moved to exec-all.h.  The helpers that are
    used from TCG will shortly need access to tcg_target_long so move
    their declarations into tcg.h.
    
    This requires minor include adjustments to all TCG backends.
    
    Reviewed-by: Aurelien Jarno <aurelien at aurel32.net>
    Signed-off-by: Richard Henderson <rth at twiddle.net>

diff --git a/include/exec/exec-all.h b/include/exec/exec-all.h
index 6f71a4f..beb4149 100644
--- a/include/exec/exec-all.h
+++ b/include/exec/exec-all.h
@@ -377,7 +377,10 @@ bool io_mem_write(struct MemoryRegion *mr, hwaddr addr,
 void tlb_fill(CPUArchState *env1, target_ulong addr, int is_write, int mmu_idx,
               uintptr_t retaddr);
 
-#include "exec/softmmu_defs.h"
+uint8_t helper_ldb_cmmu(CPUArchState *env, target_ulong addr, int mmu_idx);
+uint16_t helper_ldw_cmmu(CPUArchState *env, target_ulong addr, int mmu_idx);
+uint32_t helper_ldl_cmmu(CPUArchState *env, target_ulong addr, int mmu_idx);
+uint64_t helper_ldq_cmmu(CPUArchState *env, target_ulong addr, int mmu_idx);
 
 #define ACCESS_TYPE (NB_MMU_MODES + 1)
 #define MEMSUFFIX _code
diff --git a/include/exec/softmmu_defs.h b/include/exec/softmmu_defs.h
deleted file mode 100644
index e55e717..0000000
--- a/include/exec/softmmu_defs.h
+++ /dev/null
@@ -1,49 +0,0 @@
-/*
- *  Software MMU support
- *
- * Declare helpers used by TCG for qemu_ld/st ops.
- *
- * Used by softmmu_exec.h, TCG targets and exec-all.h.
- *
- */
-#ifndef SOFTMMU_DEFS_H
-#define SOFTMMU_DEFS_H
-
-uint8_t helper_ret_ldb_mmu(CPUArchState *env, target_ulong addr,
-                           int mmu_idx, uintptr_t retaddr);
-uint16_t helper_ret_ldw_mmu(CPUArchState *env, target_ulong addr,
-                            int mmu_idx, uintptr_t retaddr);
-uint32_t helper_ret_ldl_mmu(CPUArchState *env, target_ulong addr,
-                            int mmu_idx, uintptr_t retaddr);
-uint64_t helper_ret_ldq_mmu(CPUArchState *env, target_ulong addr,
-                            int mmu_idx, uintptr_t retaddr);
-
-void helper_ret_stb_mmu(CPUArchState *env, target_ulong addr, uint8_t val,
-                        int mmu_idx, uintptr_t retaddr);
-void helper_ret_stw_mmu(CPUArchState *env, target_ulong addr, uint16_t val,
-                        int mmu_idx, uintptr_t retaddr);
-void helper_ret_stl_mmu(CPUArchState *env, target_ulong addr, uint32_t val,
-                        int mmu_idx, uintptr_t retaddr);
-void helper_ret_stq_mmu(CPUArchState *env, target_ulong addr, uint64_t val,
-                        int mmu_idx, uintptr_t retaddr);
-
-uint8_t helper_ldb_mmu(CPUArchState *env, target_ulong addr, int mmu_idx);
-uint16_t helper_ldw_mmu(CPUArchState *env, target_ulong addr, int mmu_idx);
-uint32_t helper_ldl_mmu(CPUArchState *env, target_ulong addr, int mmu_idx);
-uint64_t helper_ldq_mmu(CPUArchState *env, target_ulong addr, int mmu_idx);
-
-void helper_stb_mmu(CPUArchState *env, target_ulong addr,
-                    uint8_t val, int mmu_idx);
-void helper_stw_mmu(CPUArchState *env, target_ulong addr,
-                    uint16_t val, int mmu_idx);
-void helper_stl_mmu(CPUArchState *env, target_ulong addr,
-                    uint32_t val, int mmu_idx);
-void helper_stq_mmu(CPUArchState *env, target_ulong addr,
-                    uint64_t val, int mmu_idx);
-
-uint8_t helper_ldb_cmmu(CPUArchState *env, target_ulong addr, int mmu_idx);
-uint16_t helper_ldw_cmmu(CPUArchState *env, target_ulong addr, int mmu_idx);
-uint32_t helper_ldl_cmmu(CPUArchState *env, target_ulong addr, int mmu_idx);
-uint64_t helper_ldq_cmmu(CPUArchState *env, target_ulong addr, int mmu_idx);
-
-#endif /* SOFTMMU_DEFS_H */
diff --git a/include/exec/softmmu_exec.h b/include/exec/softmmu_exec.h
index 3e4e886..6fde154 100644
--- a/include/exec/softmmu_exec.h
+++ b/include/exec/softmmu_exec.h
@@ -19,7 +19,8 @@
 #define ldul_executive  ldl_executive
 #define ldul_supervisor ldl_supervisor
 
-#include "exec/softmmu_defs.h"
+/* The memory helpers for tcg-generated code need tcg_target_long etc.  */
+#include "tcg.h"
 
 #define ACCESS_TYPE 0
 #define MEMSUFFIX MMU_MODE0_SUFFIX
diff --git a/tcg/aarch64/tcg-target.c b/tcg/aarch64/tcg-target.c
index c472a4a..6379df1 100644
--- a/tcg/aarch64/tcg-target.c
+++ b/tcg/aarch64/tcg-target.c
@@ -778,8 +778,6 @@ static inline void tcg_out_nop(TCGContext *s)
 }
 
 #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] = {
diff --git a/tcg/arm/tcg-target.c b/tcg/arm/tcg-target.c
index 5d2db36..eb0e84c 100644
--- a/tcg/arm/tcg-target.c
+++ b/tcg/arm/tcg-target.c
@@ -1058,8 +1058,6 @@ static inline void tcg_out_goto_label(TCGContext *s, int cond, int label_index)
 
 #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] = {
diff --git a/tcg/hppa/tcg-target.c b/tcg/hppa/tcg-target.c
index 0150e62..236b39c 100644
--- a/tcg/hppa/tcg-target.c
+++ b/tcg/hppa/tcg-target.c
@@ -910,8 +910,6 @@ static void tcg_out_movcond(TCGContext *s, int cond, TCGArg ret,
 }
 
 #if defined(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] = {
diff --git a/tcg/i386/tcg-target.c b/tcg/i386/tcg-target.c
index 28ed55a..a0cfe88 100644
--- a/tcg/i386/tcg-target.c
+++ b/tcg/i386/tcg-target.c
@@ -1021,9 +1021,6 @@ static void tcg_out_jmp(TCGContext *s, uintptr_t dest)
 }
 
 #if defined(CONFIG_SOFTMMU)
-
-#include "exec/softmmu_defs.h"
-
 /* helper signature: helper_ret_ld_mmu(CPUState *env, target_ulong addr,
  *                                     int mmu_idx, uintptr_t ra)
  */
diff --git a/tcg/ia64/tcg-target.c b/tcg/ia64/tcg-target.c
index 0a3ff70..cd4f1ae 100644
--- a/tcg/ia64/tcg-target.c
+++ b/tcg/ia64/tcg-target.c
@@ -1490,9 +1490,6 @@ static inline void tcg_out_movcond(TCGContext *s, TCGCond cond, TCGArg ret,
 }
 
 #if defined(CONFIG_SOFTMMU)
-
-#include "exec/softmmu_defs.h"
-
 /* Load and compare a TLB entry, and return the result in (p6, p7).
    R2 is loaded with the address of the addend TLB entry.
    R57 is loaded with the address, zero extented on 32-bit targets. */
diff --git a/tcg/mips/tcg-target.c b/tcg/mips/tcg-target.c
index 6bf7dba..3c2b394 100644
--- a/tcg/mips/tcg-target.c
+++ b/tcg/mips/tcg-target.c
@@ -919,9 +919,6 @@ static void tcg_out_setcond2(TCGContext *s, TCGCond cond, TCGReg ret,
 }
 
 #if defined(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] = {
diff --git a/tcg/ppc/tcg-target.c b/tcg/ppc/tcg-target.c
index f45ce7c..2595556 100644
--- a/tcg/ppc/tcg-target.c
+++ b/tcg/ppc/tcg-target.c
@@ -549,8 +549,6 @@ static void add_qemu_ldst_label (TCGContext *s,
     label->label_ptr[0] = label_ptr;
 }
 
-#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] = {
diff --git a/tcg/ppc64/tcg-target.c b/tcg/ppc64/tcg-target.c
index c5cfe82..0bd1e0c 100644
--- a/tcg/ppc64/tcg-target.c
+++ b/tcg/ppc64/tcg-target.c
@@ -750,9 +750,6 @@ static void tcg_out_ldsta(TCGContext *s, TCGReg ret, TCGReg addr,
 }
 
 #if defined (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] = {
diff --git a/tcg/s390/tcg-target.c b/tcg/s390/tcg-target.c
index a1dcb3d..1b44aee 100644
--- a/tcg/s390/tcg-target.c
+++ b/tcg/s390/tcg-target.c
@@ -315,9 +315,6 @@ static const uint8_t tcg_cond_to_ltr_cond[] = {
 };
 
 #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] = {
diff --git a/tcg/sparc/tcg-target.c b/tcg/sparc/tcg-target.c
index 5eb8c76..9574954 100644
--- a/tcg/sparc/tcg-target.c
+++ b/tcg/sparc/tcg-target.c
@@ -831,8 +831,6 @@ static void tcg_target_qemu_prologue(TCGContext *s)
 
 #if defined(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] = {
diff --git a/tcg/tcg.h b/tcg/tcg.h
index d27df66..30ec952 100644
--- a/tcg/tcg.h
+++ b/tcg/tcg.h
@@ -21,6 +21,10 @@
  * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
  * THE SOFTWARE.
  */
+
+#ifndef TCG_H
+#define TCG_H
+
 #include "qemu-common.h"
 
 #include "tcg-target.h"
@@ -745,3 +749,42 @@ void tcg_register_jit(void *buf, size_t buf_size);
 /* Generate TB finalization at the end of block */
 void tcg_out_tb_finalize(TCGContext *s);
 #endif
+
+/*
+ * Memory helpers that will be used by TCG generated code.
+ */
+#ifdef CONFIG_SOFTMMU
+uint8_t helper_ret_ldb_mmu(CPUArchState *env, target_ulong addr,
+                           int mmu_idx, uintptr_t retaddr);
+uint16_t helper_ret_ldw_mmu(CPUArchState *env, target_ulong addr,
+                            int mmu_idx, uintptr_t retaddr);
+uint32_t helper_ret_ldl_mmu(CPUArchState *env, target_ulong addr,
+                            int mmu_idx, uintptr_t retaddr);
+uint64_t helper_ret_ldq_mmu(CPUArchState *env, target_ulong addr,
+                            int mmu_idx, uintptr_t retaddr);
+
+void helper_ret_stb_mmu(CPUArchState *env, target_ulong addr, uint8_t val,
+                        int mmu_idx, uintptr_t retaddr);
+void helper_ret_stw_mmu(CPUArchState *env, target_ulong addr, uint16_t val,
+                        int mmu_idx, uintptr_t retaddr);
+void helper_ret_stl_mmu(CPUArchState *env, target_ulong addr, uint32_t val,
+                        int mmu_idx, uintptr_t retaddr);
+void helper_ret_stq_mmu(CPUArchState *env, target_ulong addr, uint64_t val,
+                        int mmu_idx, uintptr_t retaddr);
+
+uint8_t helper_ldb_mmu(CPUArchState *env, target_ulong addr, int mmu_idx);
+uint16_t helper_ldw_mmu(CPUArchState *env, target_ulong addr, int mmu_idx);
+uint32_t helper_ldl_mmu(CPUArchState *env, target_ulong addr, int mmu_idx);
+uint64_t helper_ldq_mmu(CPUArchState *env, target_ulong addr, int mmu_idx);
+
+void helper_stb_mmu(CPUArchState *env, target_ulong addr,
+                    uint8_t val, int mmu_idx);
+void helper_stw_mmu(CPUArchState *env, target_ulong addr,
+                    uint16_t val, int mmu_idx);
+void helper_stl_mmu(CPUArchState *env, target_ulong addr,
+                    uint32_t val, int mmu_idx);
+void helper_stq_mmu(CPUArchState *env, target_ulong addr,
+                    uint64_t val, int mmu_idx);
+#endif /* CONFIG_SOFTMMU */
+
+#endif /* TCG_H */
commit b1669e5e321a0a96a07ec1f7a82ce8f4b25ddfd5
Author: Richard Henderson <rth at twiddle.net>
Date:   Tue Aug 27 13:03:27 2013 -0700

    target: Include softmmu_exec.h where forgotten
    
    Several targets forgot to include softmmu_exec.h, which would
    break them with a header cleanup to follow.
    
    Reviewed-by: Aurelien Jarno <aurelien at aurel32.net>
    Signed-off-by: Richard Henderson <rth at twiddle.net>

diff --git a/target-lm32/op_helper.c b/target-lm32/op_helper.c
index 2dab9f2..8f5ef55 100644
--- a/target-lm32/op_helper.c
+++ b/target-lm32/op_helper.c
@@ -6,6 +6,8 @@
 #include "hw/lm32/lm32_pic.h"
 #include "hw/char/lm32_juart.h"
 
+#include "exec/softmmu_exec.h"
+
 #if !defined(CONFIG_USER_ONLY)
 #define MMUSUFFIX _mmu
 #define SHIFT 0
diff --git a/target-moxie/helper.c b/target-moxie/helper.c
index b12e4ff..7859102 100644
--- a/target-moxie/helper.c
+++ b/target-moxie/helper.c
@@ -25,6 +25,7 @@
 #include "cpu.h"
 #include "mmu.h"
 #include "exec/exec-all.h"
+#include "exec/softmmu_exec.h"
 #include "qemu/host-utils.h"
 #include "helper.h"
 
diff --git a/target-ppc/mmu_helper.c b/target-ppc/mmu_helper.c
index 5dd4e05..44f04e5 100644
--- a/target-ppc/mmu_helper.c
+++ b/target-ppc/mmu_helper.c
@@ -2871,6 +2871,8 @@ void helper_booke206_tlbflush(CPUPPCState *env, uint32_t type)
 
 /*****************************************************************************/
 
+#include "exec/softmmu_exec.h"
+
 #define MMUSUFFIX _mmu
 
 #define SHIFT 0
diff --git a/target-unicore32/op_helper.c b/target-unicore32/op_helper.c
index 6443ffe..4f9f41e 100644
--- a/target-unicore32/op_helper.c
+++ b/target-unicore32/op_helper.c
@@ -239,6 +239,8 @@ uint32_t HELPER(ror_cc)(CPUUniCore32State *env, uint32_t x, uint32_t i)
 }
 
 #ifndef CONFIG_USER_ONLY
+#include "exec/softmmu_exec.h"
+
 #define MMUSUFFIX _mmu
 
 #define SHIFT 0
diff --git a/target-xtensa/op_helper.c b/target-xtensa/op_helper.c
index 01123af..cf97025 100644
--- a/target-xtensa/op_helper.c
+++ b/target-xtensa/op_helper.c
@@ -28,6 +28,7 @@
 #include "cpu.h"
 #include "helper.h"
 #include "qemu/host-utils.h"
+#include "exec/softmmu_exec.h"
 
 static void do_unaligned_access(CPUXtensaState *env,
         target_ulong addr, int is_write, int is_user, uintptr_t retaddr);
commit 701e3a5cc02fd52ba59894781e78d433ec043772
Author: Richard Henderson <rth at twiddle.net>
Date:   Tue Aug 27 11:31:48 2013 -0700

    exec: Rename USUFFIX to LSUFFIX
    
    In a following patch, there will be confusion between multiple "unsigned"
    suffixes; rename this one so as to imply "load".
    
    Reviewed-by: Aurelien Jarno <aurelien at aurel32.net>
    Signed-off-by: Richard Henderson <rth at twiddle.net>

diff --git a/include/exec/softmmu_template.h b/include/exec/softmmu_template.h
index 2fc6ea3..f9922e2 100644
--- a/include/exec/softmmu_template.h
+++ b/include/exec/softmmu_template.h
@@ -28,19 +28,19 @@
 
 #if DATA_SIZE == 8
 #define SUFFIX q
-#define USUFFIX q
+#define LSUFFIX q
 #define DATA_TYPE uint64_t
 #elif DATA_SIZE == 4
 #define SUFFIX l
-#define USUFFIX l
+#define LSUFFIX l
 #define DATA_TYPE uint32_t
 #elif DATA_SIZE == 2
 #define SUFFIX w
-#define USUFFIX uw
+#define LSUFFIX uw
 #define DATA_TYPE uint16_t
 #elif DATA_SIZE == 1
 #define SUFFIX b
-#define USUFFIX ub
+#define LSUFFIX ub
 #define DATA_TYPE uint8_t
 #else
 #error unsupported data size
@@ -147,7 +147,7 @@ glue(glue(helper_ret_ld, SUFFIX), MMUSUFFIX)(CPUArchState *env,
 #endif
 
     haddr = addr + env->tlb_table[mmu_idx][index].addend;
-    return glue(glue(ld, USUFFIX), _raw)((uint8_t *)haddr);
+    return glue(glue(ld, LSUFFIX), _raw)((uint8_t *)haddr);
 }
 
 DATA_TYPE
@@ -264,6 +264,6 @@ glue(glue(helper_st, SUFFIX), MMUSUFFIX)(CPUArchState *env, target_ulong addr,
 #undef SHIFT
 #undef DATA_TYPE
 #undef SUFFIX
-#undef USUFFIX
+#undef LSUFFIX
 #undef DATA_SIZE
 #undef ADDR_READ
commit 5bcebc253c1637d3a5b957abc7460c49a670c4de
Author: Richard Henderson <rth at twiddle.net>
Date:   Tue Aug 27 10:47:49 2013 -0700

    tcg-i386: Don't perform GETPC adjustment in TCG code
    
    Since we now perform it inside the helper, no need to do it here.
    This also lets us perform a tail-call from the store slow path to
    the helper.
    
    Reviewed-by: Aurelien Jarno <aurelien at aurel32.net>
    Signed-off-by: Richard Henderson <rth at twiddle.net>

diff --git a/tcg/i386/tcg-target.c b/tcg/i386/tcg-target.c
index cde134f..28ed55a 100644
--- a/tcg/i386/tcg-target.c
+++ b/tcg/i386/tcg-target.c
@@ -1481,12 +1481,6 @@ static void add_qemu_ldst_label(TCGContext *s,
     }
 }
 
-/* See the GETPC definition in include/exec/exec-all.h.  */
-static inline uintptr_t do_getpc(uint8_t *raddr)
-{
-    return (uintptr_t)raddr - 1;
-}
-
 /*
  * Generate code for the slow path for a load at the end of block
  */
@@ -1520,14 +1514,14 @@ static void tcg_out_qemu_ld_slow_path(TCGContext *s, TCGLabelQemuLdst *l)
         tcg_out_sti(s, TCG_TYPE_I32, TCG_REG_ESP, ofs, l->mem_index);
         ofs += 4;
 
-        tcg_out_sti(s, TCG_TYPE_I32, TCG_REG_ESP, ofs, do_getpc(l->raddr));
+        tcg_out_sti(s, TCG_TYPE_I32, TCG_REG_ESP, ofs, (uintptr_t)l->raddr);
     } else {
         tcg_out_mov(s, TCG_TYPE_PTR, tcg_target_call_iarg_regs[0], TCG_AREG0);
         /* The second argument is already loaded with addrlo.  */
         tcg_out_movi(s, TCG_TYPE_I32, tcg_target_call_iarg_regs[2],
                      l->mem_index);
         tcg_out_movi(s, TCG_TYPE_PTR, tcg_target_call_iarg_regs[3],
-                     do_getpc(l->raddr));
+                     (uintptr_t)l->raddr);
     }
 
     tcg_out_calli(s, (uintptr_t)qemu_ld_helpers[s_bits]);
@@ -1582,6 +1576,7 @@ static void tcg_out_qemu_st_slow_path(TCGContext *s, TCGLabelQemuLdst *l)
     int opc = l->opc;
     int s_bits = opc & 3;
     uint8_t **label_ptr = &l->label_ptr[0];
+    TCGReg retaddr;
 
     /* resolve label address */
     *(uint32_t *)label_ptr[0] = (uint32_t)(s->code_ptr - label_ptr[0] - 4);
@@ -1614,10 +1609,10 @@ static void tcg_out_qemu_st_slow_path(TCGContext *s, TCGLabelQemuLdst *l)
         tcg_out_sti(s, TCG_TYPE_I32, TCG_REG_ESP, ofs, l->mem_index);
         ofs += 4;
 
-        tcg_out_sti(s, TCG_TYPE_I32, TCG_REG_ESP, ofs, do_getpc(l->raddr));
+        retaddr = TCG_REG_EAX;
+        tcg_out_movi(s, TCG_TYPE_I32, retaddr, (uintptr_t)l->raddr);
+        tcg_out_st(s, TCG_TYPE_I32, retaddr, TCG_REG_ESP, ofs);
     } else {
-        uintptr_t pc;
-
         tcg_out_mov(s, TCG_TYPE_PTR, tcg_target_call_iarg_regs[0], TCG_AREG0);
         /* The second argument is already loaded with addrlo.  */
         tcg_out_mov(s, (opc == 3 ? TCG_TYPE_I64 : TCG_TYPE_I32),
@@ -1625,19 +1620,19 @@ static void tcg_out_qemu_st_slow_path(TCGContext *s, TCGLabelQemuLdst *l)
         tcg_out_movi(s, TCG_TYPE_I32, tcg_target_call_iarg_regs[3],
                      l->mem_index);
 
-        pc = do_getpc(l->raddr);
         if (ARRAY_SIZE(tcg_target_call_iarg_regs) > 4) {
-            tcg_out_movi(s, TCG_TYPE_PTR, tcg_target_call_iarg_regs[4], pc);
-        } else if (pc == (int32_t)pc) {
-            tcg_out_sti(s, TCG_TYPE_PTR, TCG_REG_ESP, 0, pc);
+            retaddr = tcg_target_call_iarg_regs[4];
+            tcg_out_movi(s, TCG_TYPE_PTR, retaddr, (uintptr_t)l->raddr);
         } else {
-            tcg_out_movi(s, TCG_TYPE_PTR, TCG_REG_RAX, pc);
-            tcg_out_st(s, TCG_TYPE_PTR, TCG_REG_RAX, TCG_REG_ESP, 0);
+            retaddr = TCG_REG_RAX;
+            tcg_out_movi(s, TCG_TYPE_PTR, retaddr, (uintptr_t)l->raddr);
+            tcg_out_st(s, TCG_TYPE_PTR, retaddr, TCG_REG_ESP, 0);
         }
     }
 
-    tcg_out_calli(s, (uintptr_t)qemu_st_helpers[s_bits]);
-    tcg_out_jmp(s, (uintptr_t)l->raddr);
+    /* "Tail call" to the helper, with the return address back inline.  */
+    tcg_out_push(s, retaddr);
+    tcg_out_jmp(s, (uintptr_t)qemu_st_helpers[s_bits]);
 }
 
 /*
commit 0f842f8a246f2b5b51a11c13f933bf7a90ae8e96
Author: Richard Henderson <rth at twiddle.net>
Date:   Tue Aug 27 10:22:54 2013 -0700

    exec: Reorganize the GETRA/GETPC macros
    
    Always define GETRA; use __builtin_extract_return_addr, rather than
    having a special case for s390.  Split GETPC_ADJ out of GETPC; use 2
    universally, rather than having a special case for arm.
    
    Rename GETPC_LDST to GETRA_LDST to indicate that it does not
    contain the GETPC_ADJ value.  Likewise with GETPC_EXT to GETRA_EXT.
    
    Perform the GETPC_ADJ adjustment inside helper_ret_ld/st.  This will
    allow backends to pass along the "true" return address rather than
    the massaged GETPC value.  In the meantime, double application of
    GETPC_ADJ does not hurt, since the call insn in all ISAs is at least
    4 bytes long.
    
    Reviewed-by: Aurelien Jarno <aurelien at aurel32.net>
    Signed-off-by: Richard Henderson <rth at twiddle.net>

diff --git a/include/exec/exec-all.h b/include/exec/exec-all.h
index ffb69a4..6f71a4f 100644
--- a/include/exec/exec-all.h
+++ b/include/exec/exec-all.h
@@ -295,47 +295,42 @@ static inline void tb_add_jump(TranslationBlock *tb, int n,
     }
 }
 
-/* The return address may point to the start of the next instruction.
-   Subtracting one gets us the call instruction itself.  */
+/* GETRA is the true target of the return instruction that we'll execute,
+   defined here for simplicity of defining the follow-up macros.  */
 #if defined(CONFIG_TCG_INTERPRETER)
 extern uintptr_t tci_tb_ptr;
-# define GETPC() tci_tb_ptr
-#elif defined(__s390__) && !defined(__s390x__)
-# define GETPC() \
-    (((uintptr_t)__builtin_return_address(0) & 0x7fffffffUL) - 1)
-#elif defined(__arm__)
-/* Thumb return addresses have the low bit set, so we need to subtract two.
-   This is still safe in ARM mode because instructions are 4 bytes.  */
-# define GETPC() ((uintptr_t)__builtin_return_address(0) - 2)
+# define GETRA() tci_tb_ptr
+#else
+# define GETRA() \
+    ((uintptr_t)__builtin_extract_return_addr(__builtin_return_address(0)))
+#endif
+
+/* The true return address will often point to a host insn that is part of
+   the next translated guest insn.  Adjust the address backward to point to
+   the middle of the call insn.  Subtracting one would do the job except for
+   several compressed mode architectures (arm, mips) which set the low bit
+   to indicate the compressed mode; subtracting two works around that.  It
+   is also the case that there are no host isas that contain a call insn
+   smaller than 4 bytes, so we don't worry about special-casing this.  */
+#if defined(CONFIG_TCG_INTERPRETER)
+# define GETPC_ADJ   0
 #else
-# define GETPC() ((uintptr_t)__builtin_return_address(0) - 1)
+# define GETPC_ADJ   2
 #endif
 
+#define GETPC()  (GETRA() - GETPC_ADJ)
+
+/* The LDST optimizations splits code generation into fast and slow path.
+   In some implementations, we pass the "logical" return address manually;
+   in others, we must infer the logical return from the true return.  */
 #if defined(CONFIG_QEMU_LDST_OPTIMIZATION) && defined(CONFIG_SOFTMMU)
-/* qemu_ld/st optimization split code generation to fast and slow path, thus,
-   it needs special handling for an MMU helper which is called from the slow
-   path, to get the fast path's pc without any additional argument.
-   It uses a tricky solution which embeds the fast path pc into the slow path.
-
-   Code flow in slow path:
-   (1) pre-process
-   (2) call MMU helper
-   (3) jump to (5)
-   (4) fast path information (implementation specific)
-   (5) post-process (e.g. stack adjust)
-   (6) jump to corresponding code of the next of fast path
- */
-# if defined(__i386__) || defined(__x86_64__)
-#  define GETPC_EXT()  GETPC()
-# elif defined (_ARCH_PPC) && !defined (_ARCH_PPC64)
-#  define GETRA() ((uintptr_t)__builtin_return_address(0))
-#  define GETPC_LDST() ((uintptr_t) ((*(int32_t *)(GETRA() - 4)) - 1))
+# if defined (_ARCH_PPC) && !defined (_ARCH_PPC64)
+#  define GETRA_LDST(RA)   (*(int32_t *)((RA) - 4))
 # elif defined(__arm__)
 /* We define two insns between the return address and the branch back to
    straight-line.  Find and decode that branch insn.  */
-#  define GETRA()       ((uintptr_t)__builtin_return_address(0))
-#  define GETPC_LDST()  tcg_getpc_ldst(GETRA())
-static inline uintptr_t tcg_getpc_ldst(uintptr_t ra)
+#  define GETRA_LDST(RA)   tcg_getra_ldst(RA)
+static inline uintptr_t tcg_getra_ldst(uintptr_t ra)
 {
     int32_t b;
     ra += 8;                    /* skip the two insns */
@@ -343,33 +338,32 @@ static inline uintptr_t tcg_getpc_ldst(uintptr_t ra)
     b = (b << 8) >> (8 - 2);    /* extract the displacement */
     ra += 8;                    /* branches are relative to pc+8 */
     ra += b;                    /* apply the displacement */
-    ra -= 4;                    /* return a pointer into the current opcode,
-                                   not the start of the next opcode  */
     return ra;
 }
 # elif defined(__aarch64__)
-#  define GETRA()       ((uintptr_t)__builtin_return_address(0))
-#  define GETPC_LDST()  tcg_getpc_ldst(GETRA())
-static inline uintptr_t tcg_getpc_ldst(uintptr_t ra)
+#  define GETRA_LDST(RA)  tcg_getra_ldst(RA)
+static inline uintptr_t tcg_getra_ldst(uintptr_t ra)
 {
     int32_t b;
     ra += 4;                    /* skip one instruction */
     b = *(int32_t *)ra;         /* load the branch insn */
     b = (b << 6) >> (6 - 2);    /* extract the displacement */
     ra += b;                    /* apply the displacement  */
-    ra -= 4;                    /* return a pointer into the current opcode,
-                                   not the start of the next opcode  */
     return ra;
 }
-# else
-#  error "CONFIG_QEMU_LDST_OPTIMIZATION needs GETPC_LDST() implementation!"
 # endif
+#endif /* CONFIG_QEMU_LDST_OPTIMIZATION */
+
+/* ??? Delete these once they are no longer used.  */
 bool is_tcg_gen_code(uintptr_t pc_ptr);
-# ifndef GETPC_EXT
-#  define GETPC_EXT() (is_tcg_gen_code(GETRA()) ? GETPC_LDST() : GETPC())
-# endif
+#ifdef GETRA_LDST
+# define GETRA_EXT()  tcg_getra_ext(GETRA())
+static inline uintptr_t tcg_getra_ext(uintptr_t ra)
+{
+    return is_tcg_gen_code(ra) ? GETRA_LDST(ra) : ra;
+}
 #else
-# define GETPC_EXT() GETPC()
+# define GETRA_EXT()  GETRA()
 #endif
 
 #if !defined(CONFIG_USER_ONLY)
diff --git a/include/exec/softmmu_template.h b/include/exec/softmmu_template.h
index eaca9e1..2fc6ea3 100644
--- a/include/exec/softmmu_template.h
+++ b/include/exec/softmmu_template.h
@@ -86,6 +86,9 @@ glue(glue(helper_ret_ld, SUFFIX), MMUSUFFIX)(CPUArchState *env,
     target_ulong tlb_addr = env->tlb_table[mmu_idx][index].ADDR_READ;
     uintptr_t haddr;
 
+    /* Adjust the given return address.  */
+    retaddr -= GETPC_ADJ;
+
     /* If the TLB entry is for a different page, reload and try again.  */
     if ((addr & TARGET_PAGE_MASK)
          != (tlb_addr & (TARGET_PAGE_MASK | TLB_INVALID_MASK))) {
@@ -121,10 +124,12 @@ glue(glue(helper_ret_ld, SUFFIX), MMUSUFFIX)(CPUArchState *env,
 #endif
         addr1 = addr & ~(DATA_SIZE - 1);
         addr2 = addr1 + DATA_SIZE;
-        res1 = glue(glue(helper_ret_ld, SUFFIX), MMUSUFFIX)(env, addr1,
-                                                            mmu_idx, retaddr);
-        res2 = glue(glue(helper_ret_ld, SUFFIX), MMUSUFFIX)(env, addr2,
-                                                            mmu_idx, retaddr);
+        /* Note the adjustment at the beginning of the function.
+           Undo that for the recursion.  */
+        res1 = glue(glue(helper_ret_ld, SUFFIX), MMUSUFFIX)
+            (env, addr1, mmu_idx, retaddr + GETPC_ADJ);
+        res2 = glue(glue(helper_ret_ld, SUFFIX), MMUSUFFIX)
+            (env, addr2, mmu_idx, retaddr + GETPC_ADJ);
         shift = (addr & (DATA_SIZE - 1)) * 8;
 #ifdef TARGET_WORDS_BIGENDIAN
         res = (res1 << shift) | (res2 >> ((DATA_SIZE * 8) - shift));
@@ -150,7 +155,7 @@ glue(glue(helper_ld, SUFFIX), MMUSUFFIX)(CPUArchState *env, target_ulong addr,
                                          int mmu_idx)
 {
     return glue(glue(helper_ret_ld, SUFFIX), MMUSUFFIX)(env, addr, mmu_idx,
-                                                        GETPC_EXT());
+                                                        GETRA_EXT());
 }
 
 #ifndef SOFTMMU_CODE_ACCESS
@@ -182,6 +187,9 @@ glue(glue(helper_ret_st, SUFFIX), MMUSUFFIX)(CPUArchState *env,
     target_ulong tlb_addr = env->tlb_table[mmu_idx][index].addr_write;
     uintptr_t haddr;
 
+    /* Adjust the given return address.  */
+    retaddr -= GETPC_ADJ;
+
     /* If the TLB entry is for a different page, reload and try again.  */
     if ((addr & TARGET_PAGE_MASK)
         != (tlb_addr & (TARGET_PAGE_MASK | TLB_INVALID_MASK))) {
@@ -223,8 +231,10 @@ glue(glue(helper_ret_st, SUFFIX), MMUSUFFIX)(CPUArchState *env,
 #else
             uint8_t val8 = val >> (i * 8);
 #endif
+            /* Note the adjustment at the beginning of the function.
+               Undo that for the recursion.  */
             glue(helper_ret_stb, MMUSUFFIX)(env, addr + i, val8,
-                                            mmu_idx, retaddr);
+                                            mmu_idx, retaddr + GETPC_ADJ);
         }
         return;
     }
@@ -245,7 +255,7 @@ glue(glue(helper_st, SUFFIX), MMUSUFFIX)(CPUArchState *env, target_ulong addr,
                                          DATA_TYPE val, int mmu_idx)
 {
     glue(glue(helper_ret_st, SUFFIX), MMUSUFFIX)(env, addr, val, mmu_idx,
-                                                 GETPC_EXT());
+                                                 GETRA_EXT());
 }
 
 #endif /* !defined(SOFTMMU_CODE_ACCESS) */
commit c72b26ec92eb93a92852ab1d23acb5a945de5062
Author: Richard Henderson <rth at twiddle.net>
Date:   Tue Aug 20 12:20:05 2013 -0700

    configure: Allow x32 as a host
    
    Reviewed-by: Aurelien Jarno <aurelien at aurel32.net>
    Signed-off-by: Richard Henderson <rth at twiddle.net>

diff --git a/configure b/configure
index 0a55c20..af6b048 100755
--- a/configure
+++ b/configure
@@ -362,7 +362,11 @@ if test ! -z "$cpu" ; then
 elif check_define __i386__ ; then
   cpu="i386"
 elif check_define __x86_64__ ; then
-  cpu="x86_64"
+  if check_define __ILP32__ ; then
+    cpu="x32"
+  else
+    cpu="x86_64"
+  fi
 elif check_define __sparc__ ; then
   if check_define __arch64__ ; then
     cpu="sparc64"
@@ -399,7 +403,7 @@ ARCH=
 # Normalise host CPU name and set ARCH.
 # Note that this case should only have supported host CPUs, not guests.
 case "$cpu" in
-  ia64|ppc|ppc64|s390|s390x|sparc64)
+  ia64|ppc|ppc64|s390|s390x|sparc64|x32)
     cpu="$cpu"
   ;;
   i386|i486|i586|i686|i86pc|BePC)
@@ -550,7 +554,7 @@ Haiku)
   kvm="yes"
   vhost_net="yes"
   vhost_scsi="yes"
-  if [ "$cpu" = "i386" -o "$cpu" = "x86_64" ] ; then
+  if [ "$cpu" = "i386" -o "$cpu" = "x86_64" -o "$cpu" = "x32" ] ; then
     audio_possible_drivers="$audio_possible_drivers fmod"
   fi
   QEMU_INCLUDES="-I\$(SRC_PATH)/linux-headers -I$(pwd)/linux-headers $QEMU_INCLUDES"
@@ -977,6 +981,11 @@ case "$cpu" in
            LDFLAGS="-m64 $LDFLAGS"
            cc_i386='$(CC) -m32'
            ;;
+    x32)
+           CPU_CFLAGS="-mx32"
+           LDFLAGS="-mx32 $LDFLAGS"
+           cc_i386='$(CC) -m32'
+           ;;
     # No special flags required for other host CPUs
 esac
 
@@ -1251,7 +1260,7 @@ fi
 
 if test "$pie" = ""; then
   case "$cpu-$targetos" in
-    i386-Linux|x86_64-Linux|i386-OpenBSD|x86_64-OpenBSD)
+    i386-Linux|x86_64-Linux|x32-Linux|i386-OpenBSD|x86_64-OpenBSD)
       ;;
     *)
       pie="no"
@@ -3506,7 +3515,7 @@ fi
 if test "$pie" = "no" ; then
   textseg_addr=
   case "$cpu" in
-    arm | hppa | i386 | m68k | ppc | ppc64 | s390* | sparc | sparc64 | x86_64)
+    arm | hppa | i386 | m68k | ppc | ppc64 | s390* | sparc | sparc64 | x86_64 | x32)
       textseg_addr=0x60000000
       ;;
     mips)
@@ -3681,7 +3690,7 @@ echo "libs_softmmu=$libs_softmmu" >> $config_host_mak
 echo "ARCH=$ARCH" >> $config_host_mak
 
 case "$cpu" in
-  arm|i386|x86_64|ppc|aarch64)
+  arm|i386|x86_64|x32|ppc|aarch64)
     # The TCG interpreter currently does not support ld/st optimization.
     if test "$tcg_interpreter" = "no" ; then
         echo "CONFIG_QEMU_LDST_OPTIMIZATION=y" >> $config_host_mak
@@ -4116,7 +4125,7 @@ elif test "$ARCH" = "sparc64" ; then
   QEMU_INCLUDES="-I\$(SRC_PATH)/tcg/sparc $QEMU_INCLUDES"
 elif test "$ARCH" = "s390x" ; then
   QEMU_INCLUDES="-I\$(SRC_PATH)/tcg/s390 $QEMU_INCLUDES"
-elif test "$ARCH" = "x86_64" ; then
+elif test "$ARCH" = "x86_64" -o "$ARCH" = "x32" ; then
   QEMU_INCLUDES="-I\$(SRC_PATH)/tcg/i386 $QEMU_INCLUDES"
 else
   QEMU_INCLUDES="-I\$(SRC_PATH)/tcg/\$(ARCH) $QEMU_INCLUDES"
@@ -4178,7 +4187,7 @@ fi
 if test "$linux" = "yes" ; then
   mkdir -p linux-headers
   case "$cpu" in
-  i386|x86_64)
+  i386|x86_64|x32)
     linux_arch=x86
     ;;
   ppcemb|ppc|ppc64)
@@ -4444,7 +4453,7 @@ for i in $ARCH $TARGET_BASE_ARCH ; do
     echo "CONFIG_HPPA_DIS=y"  >> $config_target_mak
     echo "CONFIG_HPPA_DIS=y"  >> config-all-disas.mak
   ;;
-  i386|x86_64)
+  i386|x86_64|x32)
     echo "CONFIG_I386_DIS=y"  >> $config_target_mak
     echo "CONFIG_I386_DIS=y"  >> config-all-disas.mak
   ;;
commit d5dad3be314dfec80ebb1c69266ae62edfea1850
Author: Richard Henderson <rth at twiddle.net>
Date:   Tue Aug 20 16:50:38 2013 -0700

    tcg-i386: Adjust tcg_out_tlb_load for x32
    
    Reviewed-by: Aurelien Jarno <aurelien at aurel32.net>
    Signed-off-by: Richard Henderson <rth at twiddle.net>

diff --git a/tcg/i386/tcg-target.c b/tcg/i386/tcg-target.c
index 247c9d2..cde134f 100644
--- a/tcg/i386/tcg-target.c
+++ b/tcg/i386/tcg-target.c
@@ -1085,33 +1085,46 @@ static inline void tcg_out_tlb_load(TCGContext *s, int addrlo_idx,
     const int addrlo = args[addrlo_idx];
     const int r0 = TCG_REG_L0;
     const int r1 = TCG_REG_L1;
-    TCGType type = TCG_TYPE_I32;
-    int rexw = 0;
+    TCGType ttype = TCG_TYPE_I32;
+    TCGType htype = TCG_TYPE_I32;
+    int trexw = 0, hrexw = 0;
 
-    if (TCG_TARGET_REG_BITS == 64 && TARGET_LONG_BITS == 64) {
-        type = TCG_TYPE_I64;
-        rexw = P_REXW;
+    if (TCG_TARGET_REG_BITS == 64) {
+        if (TARGET_LONG_BITS == 64) {
+            ttype = TCG_TYPE_I64;
+            trexw = P_REXW;
+        }
+        if (TCG_TYPE_PTR == TCG_TYPE_I64) {
+            htype = TCG_TYPE_I64;
+            hrexw = P_REXW;
+        }
     }
 
-    tcg_out_mov(s, type, r0, addrlo);
-    tcg_out_mov(s, type, r1, addrlo);
+    tcg_out_mov(s, htype, r0, addrlo);
+    tcg_out_mov(s, ttype, r1, addrlo);
 
-    tcg_out_shifti(s, SHIFT_SHR + rexw, r0,
+    tcg_out_shifti(s, SHIFT_SHR + hrexw, r0,
                    TARGET_PAGE_BITS - CPU_TLB_ENTRY_BITS);
 
-    tgen_arithi(s, ARITH_AND + rexw, r1,
+    tgen_arithi(s, ARITH_AND + trexw, r1,
                 TARGET_PAGE_MASK | ((1 << s_bits) - 1), 0);
-    tgen_arithi(s, ARITH_AND + rexw, r0,
+    tgen_arithi(s, ARITH_AND + hrexw, r0,
                 (CPU_TLB_SIZE - 1) << CPU_TLB_ENTRY_BITS, 0);
 
-    tcg_out_modrm_sib_offset(s, OPC_LEA + P_REXW, r0, TCG_AREG0, r0, 0,
+    tcg_out_modrm_sib_offset(s, OPC_LEA + hrexw, r0, TCG_AREG0, r0, 0,
                              offsetof(CPUArchState, tlb_table[mem_index][0])
                              + which);
 
     /* cmp 0(r0), r1 */
-    tcg_out_modrm_offset(s, OPC_CMP_GvEv + rexw, r1, r0, 0);
+    tcg_out_modrm_offset(s, OPC_CMP_GvEv + trexw, r1, r0, 0);
 
-    tcg_out_mov(s, type, r1, addrlo);
+    /* Prepare for both the fast path add of the tlb addend, and the slow
+       path function argument setup.  There are two cases worth note:
+       For 32-bit guest and x86_64 host, MOVL zero-extends the guest address
+       before the fastpath ADDQ below.  For 64-bit guest and x32 host, MOVQ
+       copies the entire guest address for the slow path, while truncation
+       for the 32-bit host happens with the fastpath ADDL below.  */
+    tcg_out_mov(s, ttype, r1, addrlo);
 
     /* jne slow_path */
     tcg_out_opc(s, OPC_JCC_long + JCC_JNE, 0, 0, 0);
@@ -1131,7 +1144,7 @@ static inline void tcg_out_tlb_load(TCGContext *s, int addrlo_idx,
     /* TLB Hit.  */
 
     /* add addend(r0), r1 */
-    tcg_out_modrm_offset(s, OPC_ADD_GvEv + P_REXW, r1, r0,
+    tcg_out_modrm_offset(s, OPC_ADD_GvEv + hrexw, r1, r0,
                          offsetof(CPUTLBEntry, addend) - which);
 }
 #elif defined(__x86_64__) && defined(__linux__)
commit 357e3d8a297003f9d79f08e45a79a73eb2d12f5b
Author: Richard Henderson <rth at twiddle.net>
Date:   Tue Aug 20 15:37:16 2013 -0700

    tcg-i386: Use intptr_t appropriately
    
    Reviewed-by: Aurelien Jarno <aurelien at aurel32.net>
    Signed-off-by: Richard Henderson <rth at twiddle.net>

diff --git a/tcg/i386/tcg-target.c b/tcg/i386/tcg-target.c
index 70e80f9..247c9d2 100644
--- a/tcg/i386/tcg-target.c
+++ b/tcg/i386/tcg-target.c
@@ -430,8 +430,7 @@ static void tcg_out_modrm(TCGContext *s, int opc, int r, int rm)
    that will follow the instruction.  */
 
 static void tcg_out_modrm_sib_offset(TCGContext *s, int opc, int r, int rm,
-                                     int index, int shift,
-                                     tcg_target_long offset)
+                                     int index, int shift, intptr_t offset)
 {
     int mod, len;
 
@@ -439,8 +438,8 @@ static void tcg_out_modrm_sib_offset(TCGContext *s, int opc, int r, int rm,
         if (TCG_TARGET_REG_BITS == 64) {
             /* Try for a rip-relative addressing mode.  This has replaced
                the 32-bit-mode absolute addressing encoding.  */
-            tcg_target_long pc = (tcg_target_long)s->code_ptr + 5 + ~rm;
-            tcg_target_long disp = offset - pc;
+            intptr_t pc = (intptr_t)s->code_ptr + 5 + ~rm;
+            intptr_t disp = offset - pc;
             if (disp == (int32_t)disp) {
                 tcg_out_opc(s, opc, r, 0, 0);
                 tcg_out8(s, (LOWREGMASK(r) << 3) | 5);
@@ -514,7 +513,7 @@ static void tcg_out_modrm_sib_offset(TCGContext *s, int opc, int r, int rm,
 
 /* A simplification of the above with no index or shift.  */
 static inline void tcg_out_modrm_offset(TCGContext *s, int opc, int r,
-                                        int rm, tcg_target_long offset)
+                                        int rm, intptr_t offset)
 {
     tcg_out_modrm_sib_offset(s, opc, r, rm, -1, 0, offset);
 }
@@ -559,7 +558,7 @@ static void tcg_out_movi(TCGContext *s, TCGType type,
     }
 
     /* Try a 7 byte pc-relative lea before the 10 byte movq.  */
-    diff = arg - ((tcg_target_long)s->code_ptr + 7);
+    diff = arg - ((uintptr_t)s->code_ptr + 7);
     if (diff == (int32_t)diff) {
         tcg_out_opc(s, OPC_LEA | P_REXW, ret, 0, 0);
         tcg_out8(s, (LOWREGMASK(ret) << 3) | 5);
@@ -757,7 +756,7 @@ static void tcg_out_jxx(TCGContext *s, int opc, int label_index, int small)
     TCGLabel *l = &s->labels[label_index];
 
     if (l->has_value) {
-        val = l->u.value - (tcg_target_long)s->code_ptr;
+        val = l->u.value - (intptr_t)s->code_ptr;
         val1 = val - 2;
         if ((int8_t)val1 == val1) {
             if (opc == -1) {
@@ -997,9 +996,9 @@ static void tcg_out_movcond64(TCGContext *s, TCGCond cond, TCGArg dest,
 }
 #endif
 
-static void tcg_out_branch(TCGContext *s, int call, tcg_target_long dest)
+static void tcg_out_branch(TCGContext *s, int call, uintptr_t dest)
 {
-    tcg_target_long disp = dest - (tcg_target_long)s->code_ptr - 5;
+    intptr_t disp = dest - (intptr_t)s->code_ptr - 5;
 
     if (disp == (int32_t)disp) {
         tcg_out_opc(s, call ? OPC_CALL_Jz : OPC_JMP_long, 0, 0, 0);
@@ -1011,12 +1010,12 @@ static void tcg_out_branch(TCGContext *s, int call, tcg_target_long dest)
     }
 }
 
-static inline void tcg_out_calli(TCGContext *s, tcg_target_long dest)
+static inline void tcg_out_calli(TCGContext *s, uintptr_t dest)
 {
     tcg_out_branch(s, 1, dest);
 }
 
-static void tcg_out_jmp(TCGContext *s, tcg_target_long dest)
+static void tcg_out_jmp(TCGContext *s, uintptr_t dest)
 {
     tcg_out_branch(s, 0, dest);
 }
@@ -1154,8 +1153,7 @@ static inline void setup_guest_base_seg(void) { }
 #endif /* SOFTMMU */
 
 static void tcg_out_qemu_ld_direct(TCGContext *s, int datalo, int datahi,
-                                   int base, tcg_target_long ofs, int seg,
-                                   int sizeop)
+                                   int base, intptr_t ofs, int seg, int sizeop)
 {
 #ifdef TARGET_WORDS_BIGENDIAN
     const int bswap = 1;
@@ -1305,7 +1303,7 @@ static void tcg_out_qemu_ld(TCGContext *s, const TCGArg *args,
 }
 
 static void tcg_out_qemu_st_direct(TCGContext *s, int datalo, int datahi,
-                                   int base, tcg_target_long ofs, int seg,
+                                   int base, intptr_t ofs, int seg,
                                    int sizeop)
 {
 #ifdef TARGET_WORDS_BIGENDIAN
@@ -1519,7 +1517,7 @@ static void tcg_out_qemu_ld_slow_path(TCGContext *s, TCGLabelQemuLdst *l)
                      do_getpc(l->raddr));
     }
 
-    tcg_out_calli(s, (tcg_target_long)qemu_ld_helpers[s_bits]);
+    tcg_out_calli(s, (uintptr_t)qemu_ld_helpers[s_bits]);
 
     data_reg = l->datalo_reg;
     switch(opc) {
@@ -1560,7 +1558,7 @@ static void tcg_out_qemu_ld_slow_path(TCGContext *s, TCGLabelQemuLdst *l)
     }
 
     /* Jump to the code corresponding to next IR of qemu_st */
-    tcg_out_jmp(s, (tcg_target_long)l->raddr);
+    tcg_out_jmp(s, (uintptr_t)l->raddr);
 }
 
 /*
@@ -1625,9 +1623,8 @@ static void tcg_out_qemu_st_slow_path(TCGContext *s, TCGLabelQemuLdst *l)
         }
     }
 
-    tcg_out_calli(s, (tcg_target_long)qemu_st_helpers[s_bits]);
-
-    tcg_out_jmp(s, (tcg_target_long)l->raddr);
+    tcg_out_calli(s, (uintptr_t)qemu_st_helpers[s_bits]);
+    tcg_out_jmp(s, (uintptr_t)l->raddr);
 }
 
 /*
@@ -1668,7 +1665,7 @@ static inline void tcg_out_op(TCGContext *s, TCGOpcode opc,
     switch(opc) {
     case INDEX_op_exit_tb:
         tcg_out_movi(s, TCG_TYPE_PTR, TCG_REG_EAX, args[0]);
-        tcg_out_jmp(s, (tcg_target_long) tb_ret_addr);
+        tcg_out_jmp(s, (uintptr_t)tb_ret_addr);
         break;
     case INDEX_op_goto_tb:
         if (s->tb_jmp_offset) {
@@ -1679,7 +1676,7 @@ static inline void tcg_out_op(TCGContext *s, TCGOpcode opc,
         } else {
             /* indirect jump method */
             tcg_out_modrm_offset(s, OPC_GRP5, EXT5_JMPN_Ev, -1,
-                                 (tcg_target_long)(s->tb_next + args[0]));
+                                 (intptr_t)(s->tb_next + args[0]));
         }
         s->tb_next_offset[args[0]] = s->code_ptr - s->code_buf;
         break;
@@ -2372,7 +2369,7 @@ static DebugFrame debug_frame = {
 #if defined(ELF_HOST_MACHINE)
 void tcg_register_jit(void *buf, size_t buf_size)
 {
-    debug_frame.fde.func_start = (tcg_target_long) buf;
+    debug_frame.fde.func_start = (uintptr_t)buf;
     debug_frame.fde.func_len = buf_size;
 
     tcg_register_jit_int(buf, buf_size, &debug_frame, sizeof(debug_frame));
commit edee2579ae3722d28756ce04ec665ea9522d8600
Author: Richard Henderson <rth at twiddle.net>
Date:   Tue Aug 20 17:20:30 2013 -0700

    tcg: Fix jit debug for x32
    
    Reviewed-by: Aurelien Jarno <aurelien at aurel32.net>
    Signed-off-by: Richard Henderson <rth at twiddle.net>

diff --git a/tcg/tcg.c b/tcg/tcg.c
index 99f3b2c..fd7fb6b 100644
--- a/tcg/tcg.c
+++ b/tcg/tcg.c
@@ -49,10 +49,10 @@
 
 #include "tcg-op.h"
 
-#if TCG_TARGET_REG_BITS == 64
-# define ELF_CLASS  ELFCLASS64
-#else
+#if UINTPTR_MAX == UINT32_MAX
 # define ELF_CLASS  ELFCLASS32
+#else
+# define ELF_CLASS  ELFCLASS64
 #endif
 #ifdef HOST_WORDS_BIGENDIAN
 # define ELF_DATA   ELFDATA2MSB
@@ -82,8 +82,8 @@ typedef struct {
 typedef struct QEMU_PACKED {
     uint32_t len __attribute__((aligned((sizeof(void *)))));
     uint32_t cie_offset;
-    tcg_target_long func_start;
-    tcg_target_long func_len;
+    uintptr_t func_start;
+    uintptr_t func_len;
 } DebugFrameFDEHeader;
 
 static void tcg_register_jit_int(void *buf, size_t size,
commit d3452f1f40956e50142d32afbc021c53026a1770
Author: Richard Henderson <rth at twiddle.net>
Date:   Tue Aug 20 17:12:38 2013 -0700

    tcg: Use appropriate types in tcg_reg_alloc_call
    
    Reviewed-by: Aurelien Jarno <aurelien at aurel32.net>
    Signed-off-by: Richard Henderson <rth at twiddle.net>

diff --git a/tcg/tcg.c b/tcg/tcg.c
index 7ba9208..99f3b2c 100644
--- a/tcg/tcg.c
+++ b/tcg/tcg.c
@@ -2070,7 +2070,9 @@ static int tcg_reg_alloc_call(TCGContext *s, const TCGOpDef *def,
     int nb_iargs, nb_oargs, flags, nb_regs, i, reg, nb_params;
     TCGArg arg, func_arg;
     TCGTemp *ts;
-    tcg_target_long stack_offset, call_stack_size, func_addr;
+    intptr_t stack_offset;
+    size_t call_stack_size;
+    uintptr_t func_addr;
     int const_func_arg, allocate_args;
     TCGRegSet allocated_regs;
     const TCGArgConstraint *arg_ct;
commit a05b5b9be0fec96c89e00abaa964be7ce9e661ac
Author: Richard Henderson <rth at twiddle.net>
Date:   Tue Aug 20 17:07:26 2013 -0700

    tcg: Change tcg_out_ld/st offset to intptr_t
    
    Reviewed-by: Aurelien Jarno <aurelien at aurel32.net>
    Signed-off-by: Richard Henderson <rth at twiddle.net>

diff --git a/tcg/aarch64/tcg-target.c b/tcg/aarch64/tcg-target.c
index 7dde210..c472a4a 100644
--- a/tcg/aarch64/tcg-target.c
+++ b/tcg/aarch64/tcg-target.c
@@ -423,14 +423,14 @@ static inline void tcg_out_mov(TCGContext *s,
 }
 
 static inline void tcg_out_ld(TCGContext *s, TCGType type, TCGReg arg,
-                              TCGReg arg1, tcg_target_long arg2)
+                              TCGReg arg1, intptr_t 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)
+                              TCGReg arg1, intptr_t arg2)
 {
     tcg_out_ldst(s, (type == TCG_TYPE_I64) ? LDST_64 : LDST_32, LDST_ST,
                  arg, arg1, arg2);
diff --git a/tcg/arm/tcg-target.c b/tcg/arm/tcg-target.c
index e93c67f..5d2db36 100644
--- a/tcg/arm/tcg-target.c
+++ b/tcg/arm/tcg-target.c
@@ -2065,13 +2065,13 @@ static void tcg_target_init(TCGContext *s)
 }
 
 static inline void tcg_out_ld(TCGContext *s, TCGType type, TCGReg arg,
-                              TCGReg arg1, tcg_target_long arg2)
+                              TCGReg arg1, intptr_t arg2)
 {
     tcg_out_ld32u(s, COND_AL, arg, arg1, arg2);
 }
 
 static inline void tcg_out_st(TCGContext *s, TCGType type, TCGReg arg,
-                              TCGReg arg1, tcg_target_long arg2)
+                              TCGReg arg1, intptr_t arg2)
 {
     tcg_out_st32(s, COND_AL, arg, arg1, arg2);
 }
diff --git a/tcg/hppa/tcg-target.c b/tcg/hppa/tcg-target.c
index f770250..0150e62 100644
--- a/tcg/hppa/tcg-target.c
+++ b/tcg/hppa/tcg-target.c
@@ -392,14 +392,14 @@ static void tcg_out_ldst(TCGContext *s, int ret, int addr,
 
 /* This function is required by tcg.c.  */
 static inline void tcg_out_ld(TCGContext *s, TCGType type, TCGReg ret,
-                              TCGReg arg1, tcg_target_long arg2)
+                              TCGReg arg1, intptr_t arg2)
 {
     tcg_out_ldst(s, ret, arg1, arg2, INSN_LDW);
 }
 
 /* This function is required by tcg.c.  */
 static inline void tcg_out_st(TCGContext *s, TCGType type, TCGReg ret,
-                              TCGReg arg1, tcg_target_long arg2)
+                              TCGReg arg1, intptr_t arg2)
 {
     tcg_out_ldst(s, ret, arg1, arg2, INSN_STW);
 }
diff --git a/tcg/i386/tcg-target.c b/tcg/i386/tcg-target.c
index 031df71..70e80f9 100644
--- a/tcg/i386/tcg-target.c
+++ b/tcg/i386/tcg-target.c
@@ -595,14 +595,14 @@ static inline void tcg_out_pop(TCGContext *s, int reg)
 }
 
 static inline void tcg_out_ld(TCGContext *s, TCGType type, TCGReg ret,
-                              TCGReg arg1, tcg_target_long arg2)
+                              TCGReg arg1, intptr_t arg2)
 {
     int opc = OPC_MOVL_GvEv + (type == TCG_TYPE_I64 ? P_REXW : 0);
     tcg_out_modrm_offset(s, opc, ret, arg1, arg2);
 }
 
 static inline void tcg_out_st(TCGContext *s, TCGType type, TCGReg arg,
-                              TCGReg arg1, tcg_target_long arg2)
+                              TCGReg arg1, intptr_t arg2)
 {
     int opc = OPC_MOVL_EvGv + (type == TCG_TYPE_I64 ? P_REXW : 0);
     tcg_out_modrm_offset(s, opc, arg, arg1, arg2);
diff --git a/tcg/ia64/tcg-target.c b/tcg/ia64/tcg-target.c
index c499ee8..0a3ff70 100644
--- a/tcg/ia64/tcg-target.c
+++ b/tcg/ia64/tcg-target.c
@@ -993,7 +993,7 @@ static inline void tcg_out_st_rel(TCGContext *s, uint64_t opc_m4, TCGArg arg,
 }
 
 static inline void tcg_out_ld(TCGContext *s, TCGType type, TCGReg arg,
-                              TCGReg arg1, tcg_target_long arg2)
+                              TCGReg arg1, intptr_t arg2)
 {
     if (type == TCG_TYPE_I32) {
         tcg_out_ld_rel(s, OPC_LD4_M1, arg, arg1, arg2);
@@ -1003,7 +1003,7 @@ static inline void tcg_out_ld(TCGContext *s, TCGType type, TCGReg arg,
 }
 
 static inline void tcg_out_st(TCGContext *s, TCGType type, TCGReg arg,
-                              TCGReg arg1, tcg_target_long arg2)
+                              TCGReg arg1, intptr_t arg2)
 {
     if (type == TCG_TYPE_I32) {
         tcg_out_st_rel(s, OPC_ST4_M4, arg, arg1, arg2);
diff --git a/tcg/mips/tcg-target.c b/tcg/mips/tcg-target.c
index f7ea140..6bf7dba 100644
--- a/tcg/mips/tcg-target.c
+++ b/tcg/mips/tcg-target.c
@@ -514,13 +514,13 @@ static inline void tcg_out_ldst(TCGContext *s, int opc, TCGArg arg,
 }
 
 static inline void tcg_out_ld(TCGContext *s, TCGType type, TCGReg arg,
-                              TCGReg arg1, tcg_target_long arg2)
+                              TCGReg arg1, intptr_t arg2)
 {
     tcg_out_ldst(s, OPC_LW, arg, arg1, arg2);
 }
 
 static inline void tcg_out_st(TCGContext *s, TCGType type, TCGReg arg,
-                              TCGReg arg1, tcg_target_long arg2)
+                              TCGReg arg1, intptr_t arg2)
 {
     tcg_out_ldst(s, OPC_SW, arg, arg1, arg2);
 }
diff --git a/tcg/ppc/tcg-target.c b/tcg/ppc/tcg-target.c
index 4d6ee1e..f45ce7c 100644
--- a/tcg/ppc/tcg-target.c
+++ b/tcg/ppc/tcg-target.c
@@ -1062,14 +1062,14 @@ static void tcg_target_qemu_prologue (TCGContext *s)
 #endif
 }
 
-static void tcg_out_ld (TCGContext *s, TCGType type, TCGReg ret, TCGReg arg1,
-                        tcg_target_long arg2)
+static void tcg_out_ld(TCGContext *s, TCGType type, TCGReg ret, TCGReg arg1,
+                       intptr_t arg2)
 {
     tcg_out_ldst (s, ret, arg1, arg2, LWZ, LWZX);
 }
 
-static void tcg_out_st (TCGContext *s, TCGType type, TCGReg arg, TCGReg arg1,
-                        tcg_target_long arg2)
+static void tcg_out_st(TCGContext *s, TCGType type, TCGReg arg, TCGReg arg1,
+                       intptr_t arg2)
 {
     tcg_out_ldst (s, arg, arg1, arg2, STW, STWX);
 }
diff --git a/tcg/ppc64/tcg-target.c b/tcg/ppc64/tcg-target.c
index 62af42c..c5cfe82 100644
--- a/tcg/ppc64/tcg-target.c
+++ b/tcg/ppc64/tcg-target.c
@@ -1072,8 +1072,8 @@ static void tcg_target_qemu_prologue (TCGContext *s)
     tcg_out32(s, BCLR | BO_ALWAYS);
 }
 
-static void tcg_out_ld (TCGContext *s, TCGType type, TCGReg ret, TCGReg arg1,
-                        tcg_target_long arg2)
+static void tcg_out_ld(TCGContext *s, TCGType type, TCGReg ret, TCGReg arg1,
+                       intptr_t arg2)
 {
     if (type == TCG_TYPE_I32)
         tcg_out_ldst (s, ret, arg1, arg2, LWZ, LWZX);
@@ -1081,8 +1081,8 @@ static void tcg_out_ld (TCGContext *s, TCGType type, TCGReg ret, TCGReg arg1,
         tcg_out_ldsta (s, ret, arg1, arg2, LD, LDX);
 }
 
-static void tcg_out_st (TCGContext *s, TCGType type, TCGReg arg, TCGReg arg1,
-                        tcg_target_long arg2)
+static void tcg_out_st(TCGContext *s, TCGType type, TCGReg arg, TCGReg arg1,
+                       intptr_t arg2)
 {
     if (type == TCG_TYPE_I32)
         tcg_out_ldst (s, arg, arg1, arg2, STW, STWX);
diff --git a/tcg/s390/tcg-target.c b/tcg/s390/tcg-target.c
index adf7099..a1dcb3d 100644
--- a/tcg/s390/tcg-target.c
+++ b/tcg/s390/tcg-target.c
@@ -771,7 +771,7 @@ static void tcg_out_mem(TCGContext *s, S390Opcode opc_rx, S390Opcode opc_rxy,
 
 /* load data without address translation or endianness conversion */
 static inline void tcg_out_ld(TCGContext *s, TCGType type, TCGReg data,
-                              TCGReg base, tcg_target_long ofs)
+                              TCGReg base, intptr_t ofs)
 {
     if (type == TCG_TYPE_I32) {
         tcg_out_mem(s, RX_L, RXY_LY, data, base, TCG_REG_NONE, ofs);
@@ -781,7 +781,7 @@ static inline void tcg_out_ld(TCGContext *s, TCGType type, TCGReg data,
 }
 
 static inline void tcg_out_st(TCGContext *s, TCGType type, TCGReg data,
-                              TCGReg base, tcg_target_long ofs)
+                              TCGReg base, intptr_t ofs)
 {
     if (type == TCG_TYPE_I32) {
         tcg_out_mem(s, RX_ST, RXY_STY, data, base, TCG_REG_NONE, ofs);
diff --git a/tcg/sparc/tcg-target.c b/tcg/sparc/tcg-target.c
index 9f2e2c9..5eb8c76 100644
--- a/tcg/sparc/tcg-target.c
+++ b/tcg/sparc/tcg-target.c
@@ -436,13 +436,13 @@ static inline void tcg_out_ldst(TCGContext *s, int ret, int addr,
 }
 
 static inline void tcg_out_ld(TCGContext *s, TCGType type, TCGReg ret,
-                              TCGReg arg1, tcg_target_long arg2)
+                              TCGReg arg1, intptr_t arg2)
 {
     tcg_out_ldst(s, ret, arg1, arg2, (type == TCG_TYPE_I32 ? LDUW : LDX));
 }
 
 static inline void tcg_out_st(TCGContext *s, TCGType type, TCGReg arg,
-                              TCGReg arg1, tcg_target_long arg2)
+                              TCGReg arg1, intptr_t arg2)
 {
     tcg_out_ldst(s, arg, arg1, arg2, (type == TCG_TYPE_I32 ? STW : STX));
 }
diff --git a/tcg/tcg.c b/tcg/tcg.c
index 714b0c7..7ba9208 100644
--- a/tcg/tcg.c
+++ b/tcg/tcg.c
@@ -93,14 +93,14 @@ static void tcg_register_jit_int(void *buf, size_t size,
 /* Forward declarations for functions declared and used in tcg-target.c. */
 static int target_parse_constraint(TCGArgConstraint *ct, const char **pct_str);
 static void tcg_out_ld(TCGContext *s, TCGType type, TCGReg ret, TCGReg arg1,
-                       tcg_target_long arg2);
+                       intptr_t arg2);
 static void tcg_out_mov(TCGContext *s, TCGType type, TCGReg ret, TCGReg arg);
 static void tcg_out_movi(TCGContext *s, TCGType type,
                          TCGReg ret, tcg_target_long arg);
 static void tcg_out_op(TCGContext *s, TCGOpcode opc, const TCGArg *args,
                        const int *const_args);
 static void tcg_out_st(TCGContext *s, TCGType type, TCGReg arg, TCGReg arg1,
-                       tcg_target_long arg2);
+                       intptr_t arg2);
 static int tcg_target_const_match(tcg_target_long val,
                                   const TCGArgConstraint *arg_ct);
 
diff --git a/tcg/tci/tcg-target.c b/tcg/tci/tcg-target.c
index 49be6a5..281d7d5 100644
--- a/tcg/tci/tcg-target.c
+++ b/tcg/tci/tcg-target.c
@@ -488,7 +488,7 @@ static void tci_out_label(TCGContext *s, TCGArg arg)
 }
 
 static void tcg_out_ld(TCGContext *s, TCGType type, TCGReg ret, TCGReg arg1,
-                       tcg_target_long arg2)
+                       intptr_t arg2)
 {
     uint8_t *old_code_ptr = s->code_ptr;
     if (type == TCG_TYPE_I32) {
@@ -842,7 +842,7 @@ static void tcg_out_op(TCGContext *s, TCGOpcode opc, const TCGArg *args,
 }
 
 static void tcg_out_st(TCGContext *s, TCGType type, TCGReg arg, TCGReg arg1,
-                       tcg_target_long arg2)
+                       intptr_t arg2)
 {
     uint8_t *old_code_ptr = s->code_ptr;
     if (type == TCG_TYPE_I32) {
commit 8cfd04959a023f87e1e6727e608a20f168441370
Author: Richard Henderson <rth at twiddle.net>
Date:   Tue Aug 20 15:53:10 2013 -0700

    tcg: Change tcg_gen_exit_tb argument to uintptr_t
    
    And update all users.
    
    Reviewed-by: Aurelien Jarno <aurelien at aurel32.net>
    Signed-off-by: Richard Henderson <rth at twiddle.net>

diff --git a/include/exec/gen-icount.h b/include/exec/gen-icount.h
index 4fc7b29..39a6b61 100644
--- a/include/exec/gen-icount.h
+++ b/include/exec/gen-icount.h
@@ -39,12 +39,12 @@ static inline void gen_tb_start(void)
 static void gen_tb_end(TranslationBlock *tb, int num_insns)
 {
     gen_set_label(exitreq_label);
-    tcg_gen_exit_tb((tcg_target_long)tb + TB_EXIT_REQUESTED);
+    tcg_gen_exit_tb((uintptr_t)tb + TB_EXIT_REQUESTED);
 
     if (use_icount) {
         *icount_arg = num_insns;
         gen_set_label(icount_label);
-        tcg_gen_exit_tb((tcg_target_long)tb + TB_EXIT_ICOUNT_EXPIRED);
+        tcg_gen_exit_tb((uintptr_t)tb + TB_EXIT_ICOUNT_EXPIRED);
     }
 }
 
diff --git a/target-alpha/translate.c b/target-alpha/translate.c
index 309dea6..28ce436 100644
--- a/target-alpha/translate.c
+++ b/target-alpha/translate.c
@@ -415,7 +415,7 @@ static ExitStatus gen_bdirect(DisasContext *ctx, int ra, int32_t disp)
     } else if (use_goto_tb(ctx, dest)) {
         tcg_gen_goto_tb(0);
         tcg_gen_movi_i64(cpu_pc, dest);
-        tcg_gen_exit_tb((tcg_target_long)ctx->tb);
+        tcg_gen_exit_tb((uintptr_t)ctx->tb);
         return EXIT_GOTO_TB;
     } else {
         tcg_gen_movi_i64(cpu_pc, dest);
@@ -434,12 +434,12 @@ static ExitStatus gen_bcond_internal(DisasContext *ctx, TCGCond cond,
 
         tcg_gen_goto_tb(0);
         tcg_gen_movi_i64(cpu_pc, ctx->pc);
-        tcg_gen_exit_tb((tcg_target_long)ctx->tb);
+        tcg_gen_exit_tb((uintptr_t)ctx->tb);
 
         gen_set_label(lab_true);
         tcg_gen_goto_tb(1);
         tcg_gen_movi_i64(cpu_pc, dest);
-        tcg_gen_exit_tb((tcg_target_long)ctx->tb + 1);
+        tcg_gen_exit_tb((uintptr_t)ctx->tb + 1);
 
         return EXIT_GOTO_TB;
     } else {
@@ -1629,7 +1629,7 @@ static ExitStatus gen_call_pal(DisasContext *ctx, int palcode)
            we change the PAL base register.  */
         if (!ctx->singlestep_enabled && !(ctx->tb->cflags & CF_LAST_IO)) {
             tcg_gen_goto_tb(0);
-            tcg_gen_exit_tb((tcg_target_long)ctx->tb);
+            tcg_gen_exit_tb((uintptr_t)ctx->tb);
             return EXIT_GOTO_TB;
         }
 
diff --git a/target-arm/translate.c b/target-arm/translate.c
index d1e8538..9160ced 100644
--- a/target-arm/translate.c
+++ b/target-arm/translate.c
@@ -3356,7 +3356,7 @@ static inline void gen_goto_tb(DisasContext *s, int n, uint32_t dest)
     if ((tb->pc & TARGET_PAGE_MASK) == (dest & TARGET_PAGE_MASK)) {
         tcg_gen_goto_tb(n);
         gen_set_pc_im(dest);
-        tcg_gen_exit_tb((tcg_target_long)tb + n);
+        tcg_gen_exit_tb((uintptr_t)tb + n);
     } else {
         gen_set_pc_im(dest);
         tcg_gen_exit_tb(0);
diff --git a/target-cris/translate.c b/target-cris/translate.c
index 2a4beeb..617e1b4 100644
--- a/target-cris/translate.c
+++ b/target-cris/translate.c
@@ -558,7 +558,7 @@ static void gen_goto_tb(DisasContext *dc, int n, target_ulong dest)
     if ((tb->pc & TARGET_PAGE_MASK) == (dest & TARGET_PAGE_MASK)) {
         tcg_gen_goto_tb(n);
         tcg_gen_movi_tl(env_pc, dest);
-                tcg_gen_exit_tb((tcg_target_long)tb + n);
+                tcg_gen_exit_tb((uintptr_t)tb + n);
     } else {
         tcg_gen_movi_tl(env_pc, dest);
         tcg_gen_exit_tb(0);
diff --git a/target-i386/translate.c b/target-i386/translate.c
index 065a9d3..6d87900 100644
--- a/target-i386/translate.c
+++ b/target-i386/translate.c
@@ -2413,7 +2413,7 @@ static inline void gen_goto_tb(DisasContext *s, int tb_num, target_ulong eip)
         /* jump to same page: we can use a direct jump */
         tcg_gen_goto_tb(tb_num);
         gen_jmp_im(eip);
-        tcg_gen_exit_tb((tcg_target_long)tb + tb_num);
+        tcg_gen_exit_tb((uintptr_t)tb + tb_num);
     } else {
         /* jump to another page: currently not optimized */
         gen_jmp_im(eip);
diff --git a/target-lm32/translate.c b/target-lm32/translate.c
index 1247287..6ea0ecd 100644
--- a/target-lm32/translate.c
+++ b/target-lm32/translate.c
@@ -129,7 +129,7 @@ static void gen_goto_tb(DisasContext *dc, int n, target_ulong dest)
             likely(!dc->singlestep_enabled)) {
         tcg_gen_goto_tb(n);
         tcg_gen_movi_tl(cpu_pc, dest);
-        tcg_gen_exit_tb((tcg_target_long)tb + n);
+        tcg_gen_exit_tb((uintptr_t)tb + n);
     } else {
         tcg_gen_movi_tl(cpu_pc, dest);
         if (dc->singlestep_enabled) {
diff --git a/target-m68k/translate.c b/target-m68k/translate.c
index d562eeb..0be0a96 100644
--- a/target-m68k/translate.c
+++ b/target-m68k/translate.c
@@ -869,7 +869,7 @@ static void gen_jmp_tb(DisasContext *s, int n, uint32_t dest)
                (s->pc & TARGET_PAGE_MASK) == (dest & TARGET_PAGE_MASK)) {
         tcg_gen_goto_tb(n);
         tcg_gen_movi_i32(QREG_PC, dest);
-        tcg_gen_exit_tb((tcg_target_long)tb + n);
+        tcg_gen_exit_tb((uintptr_t)tb + n);
     } else {
         gen_jmp_im(s, dest);
         tcg_gen_exit_tb(0);
diff --git a/target-microblaze/translate.c b/target-microblaze/translate.c
index cd43577..0673176 100644
--- a/target-microblaze/translate.c
+++ b/target-microblaze/translate.c
@@ -138,7 +138,7 @@ static void gen_goto_tb(DisasContext *dc, int n, target_ulong dest)
     if ((tb->pc & TARGET_PAGE_MASK) == (dest & TARGET_PAGE_MASK)) {
         tcg_gen_goto_tb(n);
         tcg_gen_movi_tl(cpu_SR[SR_PC], dest);
-        tcg_gen_exit_tb((tcg_target_long)tb + n);
+        tcg_gen_exit_tb((uintptr_t)tb + n);
     } else {
         tcg_gen_movi_tl(cpu_SR[SR_PC], dest);
         tcg_gen_exit_tb(0);
diff --git a/target-mips/translate.c b/target-mips/translate.c
index e2eb908..ad43d59 100644
--- a/target-mips/translate.c
+++ b/target-mips/translate.c
@@ -3581,7 +3581,7 @@ static inline void gen_goto_tb(DisasContext *ctx, int n, target_ulong dest)
         likely(!ctx->singlestep_enabled)) {
         tcg_gen_goto_tb(n);
         gen_save_pc(dest);
-        tcg_gen_exit_tb((tcg_target_long)tb + n);
+        tcg_gen_exit_tb((uintptr_t)tb + n);
     } else {
         gen_save_pc(dest);
         if (ctx->singlestep_enabled) {
diff --git a/target-moxie/translate.c b/target-moxie/translate.c
index 8cc0bb7..a93196f 100644
--- a/target-moxie/translate.c
+++ b/target-moxie/translate.c
@@ -135,7 +135,7 @@ static inline void gen_goto_tb(CPUMoxieState *env, DisasContext *ctx,
         !ctx->singlestep_enabled) {
         tcg_gen_goto_tb(n);
         tcg_gen_movi_i32(cpu_pc, dest);
-        tcg_gen_exit_tb((tcg_target_long)tb + n);
+        tcg_gen_exit_tb((uintptr_t)tb + n);
     } else {
         tcg_gen_movi_i32(cpu_pc, dest);
         if (ctx->singlestep_enabled) {
diff --git a/target-openrisc/translate.c b/target-openrisc/translate.c
index a6050ba..723b77d 100644
--- a/target-openrisc/translate.c
+++ b/target-openrisc/translate.c
@@ -198,7 +198,7 @@ static void gen_goto_tb(DisasContext *dc, int n, target_ulong dest)
                                        likely(!dc->singlestep_enabled)) {
         tcg_gen_movi_tl(cpu_pc, dest);
         tcg_gen_goto_tb(n);
-        tcg_gen_exit_tb((tcg_target_long)tb + n);
+        tcg_gen_exit_tb((uintptr_t)tb + n);
     } else {
         tcg_gen_movi_tl(cpu_pc, dest);
         if (dc->singlestep_enabled) {
diff --git a/target-ppc/translate.c b/target-ppc/translate.c
index f07d70d..2ffb270 100644
--- a/target-ppc/translate.c
+++ b/target-ppc/translate.c
@@ -3551,7 +3551,7 @@ static inline void gen_goto_tb(DisasContext *ctx, int n, target_ulong dest)
         likely(!ctx->singlestep_enabled)) {
         tcg_gen_goto_tb(n);
         tcg_gen_movi_tl(cpu_nip, dest & ~3);
-        tcg_gen_exit_tb((tcg_target_long)tb + n);
+        tcg_gen_exit_tb((uintptr_t)tb + n);
     } else {
         tcg_gen_movi_tl(cpu_nip, dest & ~3);
         if (unlikely(ctx->singlestep_enabled)) {
diff --git a/target-s390x/translate.c b/target-s390x/translate.c
index 1fb76c5..afe90eb 100644
--- a/target-s390x/translate.c
+++ b/target-s390x/translate.c
@@ -1169,7 +1169,7 @@ static ExitStatus help_goto_direct(DisasContext *s, uint64_t dest)
         update_cc_op(s);
         tcg_gen_goto_tb(0);
         tcg_gen_movi_i64(psw_addr, dest);
-        tcg_gen_exit_tb((tcg_target_long)s->tb);
+        tcg_gen_exit_tb((uintptr_t)s->tb);
         return EXIT_GOTO_TB;
     } else {
         tcg_gen_movi_i64(psw_addr, dest);
@@ -1227,13 +1227,13 @@ static ExitStatus help_branch(DisasContext *s, DisasCompare *c,
             /* Branch not taken.  */
             tcg_gen_goto_tb(0);
             tcg_gen_movi_i64(psw_addr, s->next_pc);
-            tcg_gen_exit_tb((tcg_target_long)s->tb + 0);
+            tcg_gen_exit_tb((uintptr_t)s->tb + 0);
 
             /* Branch taken.  */
             gen_set_label(lab);
             tcg_gen_goto_tb(1);
             tcg_gen_movi_i64(psw_addr, dest);
-            tcg_gen_exit_tb((tcg_target_long)s->tb + 1);
+            tcg_gen_exit_tb((uintptr_t)s->tb + 1);
 
             ret = EXIT_GOTO_TB;
         } else {
@@ -1256,7 +1256,7 @@ static ExitStatus help_branch(DisasContext *s, DisasCompare *c,
             update_cc_op(s);
             tcg_gen_goto_tb(0);
             tcg_gen_movi_i64(psw_addr, s->next_pc);
-            tcg_gen_exit_tb((tcg_target_long)s->tb + 0);
+            tcg_gen_exit_tb((uintptr_t)s->tb + 0);
 
             gen_set_label(lab);
             if (is_imm) {
diff --git a/target-sh4/translate.c b/target-sh4/translate.c
index 59f3d47..c06b29f 100644
--- a/target-sh4/translate.c
+++ b/target-sh4/translate.c
@@ -186,7 +186,7 @@ static void gen_goto_tb(DisasContext * ctx, int n, target_ulong dest)
 	/* Use a direct jump if in same page and singlestep not enabled */
         tcg_gen_goto_tb(n);
         tcg_gen_movi_i32(cpu_pc, dest);
-        tcg_gen_exit_tb((tcg_target_long)tb + n);
+        tcg_gen_exit_tb((uintptr_t)tb + n);
     } else {
         tcg_gen_movi_i32(cpu_pc, dest);
         if (ctx->singlestep_enabled)
diff --git a/target-sparc/translate.c b/target-sparc/translate.c
index 093e0e2..36615f1 100644
--- a/target-sparc/translate.c
+++ b/target-sparc/translate.c
@@ -322,7 +322,7 @@ static inline void gen_goto_tb(DisasContext *s, int tb_num,
         tcg_gen_goto_tb(tb_num);
         tcg_gen_movi_tl(cpu_pc, pc);
         tcg_gen_movi_tl(cpu_npc, npc);
-        tcg_gen_exit_tb((tcg_target_long)tb + tb_num);
+        tcg_gen_exit_tb((uintptr_t)tb + tb_num);
     } else {
         /* jump to another page: currently not optimized */
         tcg_gen_movi_tl(cpu_pc, pc);
diff --git a/target-unicore32/translate.c b/target-unicore32/translate.c
index 68be1c6..1246895 100644
--- a/target-unicore32/translate.c
+++ b/target-unicore32/translate.c
@@ -1100,7 +1100,7 @@ static inline void gen_goto_tb(DisasContext *s, int n, uint32_t dest)
     if ((tb->pc & TARGET_PAGE_MASK) == (dest & TARGET_PAGE_MASK)) {
         tcg_gen_goto_tb(n);
         gen_set_pc_im(dest);
-        tcg_gen_exit_tb((tcg_target_long)tb + n);
+        tcg_gen_exit_tb((uintptr_t)tb + n);
     } else {
         gen_set_pc_im(dest);
         tcg_gen_exit_tb(0);
diff --git a/target-xtensa/translate.c b/target-xtensa/translate.c
index 504cc53..24343bd 100644
--- a/target-xtensa/translate.c
+++ b/target-xtensa/translate.c
@@ -400,7 +400,7 @@ static void gen_jump_slot(DisasContext *dc, TCGv dest, int slot)
     } else {
         if (slot >= 0) {
             tcg_gen_goto_tb(slot);
-            tcg_gen_exit_tb((tcg_target_long)dc->tb + slot);
+            tcg_gen_exit_tb((uintptr_t)dc->tb + slot);
         } else {
             tcg_gen_exit_tb(0);
         }
diff --git a/tcg/tcg-op.h b/tcg/tcg-op.h
index 3de7545..bb30a7c 100644
--- a/tcg/tcg-op.h
+++ b/tcg/tcg-op.h
@@ -2631,7 +2631,7 @@ static inline void tcg_gen_debug_insn_start(uint64_t pc)
 #endif
 }
 
-static inline void tcg_gen_exit_tb(tcg_target_long val)
+static inline void tcg_gen_exit_tb(uintptr_t val)
 {
     tcg_gen_op1i(INDEX_op_exit_tb, val);
 }
commit 48bc6bab479e5abb542119f3974603afd882c246
Author: Richard Henderson <rth at twiddle.net>
Date:   Tue Aug 20 15:38:41 2013 -0700

    tcg: Use uintptr_t in TCGHelperInfo
    
    Reviewed-by: Aurelien Jarno <aurelien at aurel32.net>
    Signed-off-by: Richard Henderson <rth at twiddle.net>

diff --git a/tcg/tcg.c b/tcg/tcg.c
index 75df845..714b0c7 100644
--- a/tcg/tcg.c
+++ b/tcg/tcg.c
@@ -634,7 +634,7 @@ void tcg_register_helper(void *func, const char *name)
         s->helpers = realloc(s->helpers, n * sizeof(TCGHelperInfo));
         s->allocated_helpers = n;
     }
-    s->helpers[s->nb_helpers].func = (tcg_target_ulong)func;
+    s->helpers[s->nb_helpers].func = (uintptr_t)func;
     s->helpers[s->nb_helpers].name = name;
     s->nb_helpers++;
 }
@@ -864,11 +864,11 @@ static int helper_cmp(const void *p1, const void *p2)
 }
 
 /* find helper definition (Note: A hash table would be better) */
-static TCGHelperInfo *tcg_find_helper(TCGContext *s, tcg_target_ulong val)
+static TCGHelperInfo *tcg_find_helper(TCGContext *s, uintptr_t val)
 {
     int m, m_min, m_max;
     TCGHelperInfo *th;
-    tcg_target_ulong v;
+    uintptr_t v;
 
     if (unlikely(!s->helpers_sorted)) {
         qsort(s->helpers, s->nb_helpers, sizeof(TCGHelperInfo), 
diff --git a/tcg/tcg.h b/tcg/tcg.h
index 715812a..d27df66 100644
--- a/tcg/tcg.h
+++ b/tcg/tcg.h
@@ -402,7 +402,7 @@ typedef struct TCGTemp {
 } TCGTemp;
 
 typedef struct TCGHelperInfo {
-    tcg_target_ulong func;
+    uintptr_t func;
     const char *name;
 } TCGHelperInfo;
 
commit 2ba7fae29ec63acf2ce77d20d4146fa224bf2338
Author: Richard Henderson <rth at twiddle.net>
Date:   Tue Aug 20 15:30:10 2013 -0700

    tcg: Change relocation offsets to intptr_t
    
    Reviewed-by: Aurelien Jarno <aurelien at aurel32.net>
    Signed-off-by: Richard Henderson <rth at twiddle.net>

diff --git a/tcg/aarch64/tcg-target.c b/tcg/aarch64/tcg-target.c
index 41a17f8..7dde210 100644
--- a/tcg/aarch64/tcg-target.c
+++ b/tcg/aarch64/tcg-target.c
@@ -88,7 +88,7 @@ static inline void reloc_pc19(void *code_ptr, tcg_target_long target)
 }
 
 static inline void patch_reloc(uint8_t *code_ptr, int type,
-                               tcg_target_long value, tcg_target_long addend)
+                               intptr_t value, intptr_t addend)
 {
     value += addend;
 
diff --git a/tcg/arm/tcg-target.c b/tcg/arm/tcg-target.c
index 6c4854d..e93c67f 100644
--- a/tcg/arm/tcg-target.c
+++ b/tcg/arm/tcg-target.c
@@ -108,21 +108,21 @@ static const int tcg_target_call_oarg_regs[2] = {
 
 #define TCG_REG_TMP  TCG_REG_R12
 
-static inline void reloc_abs32(void *code_ptr, tcg_target_long target)
+static inline void reloc_abs32(void *code_ptr, intptr_t target)
 {
     *(uint32_t *) code_ptr = target;
 }
 
-static inline void reloc_pc24(void *code_ptr, tcg_target_long target)
+static inline void reloc_pc24(void *code_ptr, intptr_t target)
 {
-    uint32_t offset = ((target - ((tcg_target_long) code_ptr + 8)) >> 2);
+    uint32_t offset = ((target - ((intptr_t)code_ptr + 8)) >> 2);
 
     *(uint32_t *) code_ptr = ((*(uint32_t *) code_ptr) & ~0xffffff)
                              | (offset & 0xffffff);
 }
 
 static void patch_reloc(uint8_t *code_ptr, int type,
-                tcg_target_long value, tcg_target_long addend)
+                        intptr_t value, intptr_t addend)
 {
     switch (type) {
     case R_ARM_ABS32:
diff --git a/tcg/hppa/tcg-target.c b/tcg/hppa/tcg-target.c
index e5aed91..f770250 100644
--- a/tcg/hppa/tcg-target.c
+++ b/tcg/hppa/tcg-target.c
@@ -149,14 +149,14 @@ static int reassemble_21(int as21)
 #define R_PARISC_PCREL12F  R_PARISC_NONE
 
 static void patch_reloc(uint8_t *code_ptr, int type,
-                        tcg_target_long value, tcg_target_long addend)
+                        intptr_t value, intptr_t addend)
 {
     uint32_t *insn_ptr = (uint32_t *)code_ptr;
     uint32_t insn = *insn_ptr;
-    tcg_target_long pcrel;
+    intptr_t pcrel;
 
     value += addend;
-    pcrel = (value - ((tcg_target_long)code_ptr + 8)) >> 2;
+    pcrel = (value - ((intptr_t)code_ptr + 8)) >> 2;
 
     switch (type) {
     case R_PARISC_PCREL12F:
diff --git a/tcg/i386/tcg-target.c b/tcg/i386/tcg-target.c
index 12a7ca3..031df71 100644
--- a/tcg/i386/tcg-target.c
+++ b/tcg/i386/tcg-target.c
@@ -112,7 +112,7 @@ static bool have_cmov;
 static uint8_t *tb_ret_addr;
 
 static void patch_reloc(uint8_t *code_ptr, int type,
-                        tcg_target_long value, tcg_target_long addend)
+                        intptr_t value, intptr_t addend)
 {
     value += addend;
     switch(type) {
diff --git a/tcg/ia64/tcg-target.c b/tcg/ia64/tcg-target.c
index 2373d9e..c499ee8 100644
--- a/tcg/ia64/tcg-target.c
+++ b/tcg/ia64/tcg-target.c
@@ -668,16 +668,16 @@ static inline uint64_t tcg_opc_x3(int qp, uint64_t opc, uint64_t imm)
  * Relocations
  */
 
-static inline void reloc_pcrel21b (void *pc, tcg_target_long target)
+static inline void reloc_pcrel21b(void *pc, intptr_t target)
 {
     uint64_t imm;
     int64_t disp;
     int slot;
 
-    slot = (tcg_target_long) pc & 3;
-    pc = (void *)((tcg_target_long) pc & ~3);
+    slot = (intptr_t)pc & 3;
+    pc = (void *)((intptr_t)pc & ~3);
 
-    disp = target - (tcg_target_long) pc;
+    disp = target - (intptr_t)pc;
     imm = (uint64_t) disp >> 4;
 
     switch(slot) {
@@ -728,12 +728,12 @@ static inline uint64_t get_reloc_pcrel21b (void *pc)
     }
 }
 
-static inline void reloc_pcrel60b (void *pc, tcg_target_long target)
+static inline void reloc_pcrel60b(void *pc, intptr_t target)
 {
     int64_t disp;
     uint64_t imm;
 
-    disp = target - (tcg_target_long) pc;
+    disp = target - (intptr_t)pc;
     imm = (uint64_t) disp >> 4;
 
     *(uint64_t *)(pc + 8) = (*(uint64_t *)(pc + 8) & 0xf700000fff800000ull)
@@ -759,7 +759,7 @@ static inline uint64_t get_reloc_pcrel60b (void *pc)
 
 
 static void patch_reloc(uint8_t *code_ptr, int type,
-                        tcg_target_long value, tcg_target_long addend)
+                        intptr_t value, intptr_t addend)
 {
     value += addend;
     switch (type) {
diff --git a/tcg/mips/tcg-target.c b/tcg/mips/tcg-target.c
index 31cd514..f7ea140 100644
--- a/tcg/mips/tcg-target.c
+++ b/tcg/mips/tcg-target.c
@@ -108,33 +108,33 @@ static const TCGReg tcg_target_call_oarg_regs[2] = {
 
 static uint8_t *tb_ret_addr;
 
-static inline uint32_t reloc_lo16_val (void *pc, tcg_target_long target)
+static inline uint32_t reloc_lo16_val(void *pc, intptr_t target)
 {
     return target & 0xffff;
 }
 
-static inline void reloc_lo16 (void *pc, tcg_target_long target)
+static inline void reloc_lo16(void *pc, intptr_t target)
 {
     *(uint32_t *) pc = (*(uint32_t *) pc & ~0xffff)
                        | reloc_lo16_val(pc, target);
 }
 
-static inline uint32_t reloc_hi16_val (void *pc, tcg_target_long target)
+static inline uint32_t reloc_hi16_val(void *pc, intptr_t target)
 {
     return (target >> 16) & 0xffff;
 }
 
-static inline void reloc_hi16 (void *pc, tcg_target_long target)
+static inline void reloc_hi16(void *pc, intptr_t target)
 {
     *(uint32_t *) pc = (*(uint32_t *) pc & ~0xffff)
                        | reloc_hi16_val(pc, target);
 }
 
-static inline uint32_t reloc_pc16_val (void *pc, tcg_target_long target)
+static inline uint32_t reloc_pc16_val(void *pc, intptr_t target)
 {
     int32_t disp;
 
-    disp = target - (tcg_target_long) pc - 4;
+    disp = target - (intptr_t)pc - 4;
     if (disp != (disp << 14) >> 14) {
         tcg_abort ();
     }
@@ -157,14 +157,14 @@ static inline uint32_t reloc_26_val (void *pc, tcg_target_long target)
     return (target >> 2) & 0x3ffffff;
 }
 
-static inline void reloc_pc26 (void *pc, tcg_target_long target)
+static inline void reloc_pc26(void *pc, intptr_t target)
 {
     *(uint32_t *) pc = (*(uint32_t *) pc & ~0x3ffffff)
                        | reloc_26_val(pc, target);
 }
 
 static void patch_reloc(uint8_t *code_ptr, int type,
-                        tcg_target_long value, tcg_target_long addend)
+                        intptr_t value, intptr_t addend)
 {
     value += addend;
     switch(type) {
diff --git a/tcg/ppc/tcg-target.c b/tcg/ppc/tcg-target.c
index 453ab6b..4d6ee1e 100644
--- a/tcg/ppc/tcg-target.c
+++ b/tcg/ppc/tcg-target.c
@@ -204,7 +204,7 @@ static void reloc_pc14 (void *pc, tcg_target_long target)
 }
 
 static void patch_reloc(uint8_t *code_ptr, int type,
-                        tcg_target_long value, tcg_target_long addend)
+                        intptr_t value, intptr_t addend)
 {
     value += addend;
     switch (type) {
diff --git a/tcg/ppc64/tcg-target.c b/tcg/ppc64/tcg-target.c
index 939f7cb..62af42c 100644
--- a/tcg/ppc64/tcg-target.c
+++ b/tcg/ppc64/tcg-target.c
@@ -208,7 +208,7 @@ static void reloc_pc14 (void *pc, tcg_target_long target)
 }
 
 static void patch_reloc (uint8_t *code_ptr, int type,
-                         tcg_target_long value, tcg_target_long addend)
+                         intptr_t value, intptr_t addend)
 {
     value += addend;
     switch (type) {
diff --git a/tcg/s390/tcg-target.c b/tcg/s390/tcg-target.c
index f229f1c..adf7099 100644
--- a/tcg/s390/tcg-target.c
+++ b/tcg/s390/tcg-target.c
@@ -351,10 +351,10 @@ static uint8_t *tb_ret_addr;
 static uint64_t facilities;
 
 static void patch_reloc(uint8_t *code_ptr, int type,
-                        tcg_target_long value, tcg_target_long addend)
+                        intptr_t value, intptr_t addend)
 {
-    tcg_target_long code_ptr_tl = (tcg_target_long)code_ptr;
-    tcg_target_long pcrel2;
+    intptr_t code_ptr_tl = (intptr_t)code_ptr;
+    intptr_t pcrel2;
 
     /* ??? Not the usual definition of "addend".  */
     pcrel2 = (value - (code_ptr_tl + addend)) >> 1;
diff --git a/tcg/sparc/tcg-target.c b/tcg/sparc/tcg-target.c
index 5bfd29c..9f2e2c9 100644
--- a/tcg/sparc/tcg-target.c
+++ b/tcg/sparc/tcg-target.c
@@ -252,7 +252,7 @@ static inline int check_fit_i32(uint32_t val, unsigned int bits)
 }
 
 static void patch_reloc(uint8_t *code_ptr, int type,
-                        tcg_target_long value, tcg_target_long addend)
+                        intptr_t value, intptr_t addend)
 {
     uint32_t insn;
     value += addend;
@@ -264,7 +264,7 @@ static void patch_reloc(uint8_t *code_ptr, int type,
         *(uint32_t *)code_ptr = value;
         break;
     case R_SPARC_WDISP16:
-        value -= (long)code_ptr;
+        value -= (intptr_t)code_ptr;
         if (!check_fit_tl(value >> 2, 16)) {
             tcg_abort();
         }
@@ -274,7 +274,7 @@ static void patch_reloc(uint8_t *code_ptr, int type,
         *(uint32_t *)code_ptr = insn;
         break;
     case R_SPARC_WDISP19:
-        value -= (long)code_ptr;
+        value -= (intptr_t)code_ptr;
         if (!check_fit_tl(value >> 2, 19)) {
             tcg_abort();
         }
diff --git a/tcg/tcg.c b/tcg/tcg.c
index 251d390..75df845 100644
--- a/tcg/tcg.c
+++ b/tcg/tcg.c
@@ -66,7 +66,7 @@
 static void tcg_target_init(TCGContext *s);
 static void tcg_target_qemu_prologue(TCGContext *s);
 static void patch_reloc(uint8_t *code_ptr, int type, 
-                        tcg_target_long value, tcg_target_long addend);
+                        intptr_t value, intptr_t addend);
 
 /* The CIE and FDE header definitions will be common to all hosts.  */
 typedef struct {
@@ -143,7 +143,7 @@ static inline void tcg_out64(TCGContext *s, uint64_t v)
 /* label relocation processing */
 
 static void tcg_out_reloc(TCGContext *s, uint8_t *code_ptr, int type,
-                          int label_index, long addend)
+                          int label_index, intptr_t addend)
 {
     TCGLabel *l;
     TCGRelocation *r;
@@ -169,11 +169,12 @@ static void tcg_out_label(TCGContext *s, int label_index, void *ptr)
 {
     TCGLabel *l;
     TCGRelocation *r;
-    tcg_target_long value = (tcg_target_long)ptr;
+    intptr_t value = (intptr_t)ptr;
 
     l = &s->labels[label_index];
-    if (l->has_value)
+    if (l->has_value) {
         tcg_abort();
+    }
     r = l->u.first_reloc;
     while (r != NULL) {
         patch_reloc(r->ptr, r->type, value, r->addend);
diff --git a/tcg/tcg.h b/tcg/tcg.h
index 8fe8069..715812a 100644
--- a/tcg/tcg.h
+++ b/tcg/tcg.h
@@ -139,13 +139,13 @@ typedef struct TCGRelocation {
     struct TCGRelocation *next;
     int type;
     uint8_t *ptr;
-    tcg_target_long addend;
+    intptr_t addend;
 } TCGRelocation; 
 
 typedef struct TCGLabel {
     int has_value;
     union {
-        tcg_target_ulong value;
+        uintptr_t value;
         TCGRelocation *first_reloc;
     } u;
 } TCGLabel;
diff --git a/tcg/tci/tcg-target.c b/tcg/tci/tcg-target.c
index e118bc7..49be6a5 100644
--- a/tcg/tci/tcg-target.c
+++ b/tcg/tci/tcg-target.c
@@ -370,7 +370,7 @@ static const char *const tcg_target_reg_names[TCG_TARGET_NB_REGS] = {
 #endif
 
 static void patch_reloc(uint8_t *code_ptr, int type,
-                        tcg_target_long value, tcg_target_long addend)
+                        intptr_t value, intptr_t addend)
 {
     /* tcg_out_reloc always uses the same type, addend. */
     assert(type == sizeof(tcg_target_long));
commit 2f2f244d02a2cb28db7ce790576ade08fc3a54bf
Author: Richard Henderson <rth at twiddle.net>
Date:   Tue Aug 20 15:17:25 2013 -0700

    tcg: Change memory offsets to intptr_t
    
    Reviewed-by: Aurelien Jarno <aurelien at aurel32.net>
    Signed-off-by: Richard Henderson <rth at twiddle.net>

diff --git a/tcg/tcg.c b/tcg/tcg.c
index 240e6f4..251d390 100644
--- a/tcg/tcg.c
+++ b/tcg/tcg.c
@@ -389,7 +389,7 @@ TCGv_i64 tcg_global_reg_new_i64(int reg, const char *name)
 }
 
 static inline int tcg_global_mem_new_internal(TCGType type, int reg,
-                                              tcg_target_long offset,
+                                              intptr_t offset,
                                               const char *name)
 {
     TCGContext *s = &tcg_ctx;
@@ -449,21 +449,15 @@ static inline int tcg_global_mem_new_internal(TCGType type, int reg,
     return idx;
 }
 
-TCGv_i32 tcg_global_mem_new_i32(int reg, tcg_target_long offset,
-                                const char *name)
+TCGv_i32 tcg_global_mem_new_i32(int reg, intptr_t offset, const char *name)
 {
-    int idx;
-
-    idx = tcg_global_mem_new_internal(TCG_TYPE_I32, reg, offset, name);
+    int idx = tcg_global_mem_new_internal(TCG_TYPE_I32, reg, offset, name);
     return MAKE_TCGV_I32(idx);
 }
 
-TCGv_i64 tcg_global_mem_new_i64(int reg, tcg_target_long offset,
-                                const char *name)
+TCGv_i64 tcg_global_mem_new_i64(int reg, intptr_t offset, const char *name)
 {
-    int idx;
-
-    idx = tcg_global_mem_new_internal(TCG_TYPE_I64, reg, offset, name);
+    int idx = tcg_global_mem_new_internal(TCG_TYPE_I64, reg, offset, name);
     return MAKE_TCGV_I64(idx);
 }
 
diff --git a/tcg/tcg.h b/tcg/tcg.h
index b7e112e..8fe8069 100644
--- a/tcg/tcg.h
+++ b/tcg/tcg.h
@@ -388,7 +388,7 @@ typedef struct TCGTemp {
     int reg;
     tcg_target_long val;
     int mem_reg;
-    tcg_target_long mem_offset;
+    intptr_t mem_offset;
     unsigned int fixed_reg:1;
     unsigned int mem_coherent:1;
     unsigned int mem_allocated:1;
@@ -533,8 +533,7 @@ int tcg_gen_code_search_pc(TCGContext *s, uint8_t *gen_code_buf, long offset);
 void tcg_set_frame(TCGContext *s, int reg, intptr_t start, intptr_t size);
 
 TCGv_i32 tcg_global_reg_new_i32(int reg, const char *name);
-TCGv_i32 tcg_global_mem_new_i32(int reg, tcg_target_long offset,
-                                const char *name);
+TCGv_i32 tcg_global_mem_new_i32(int reg, intptr_t offset, const char *name);
 TCGv_i32 tcg_temp_new_internal_i32(int temp_local);
 static inline TCGv_i32 tcg_temp_new_i32(void)
 {
@@ -548,8 +547,7 @@ void tcg_temp_free_i32(TCGv_i32 arg);
 char *tcg_get_arg_str_i32(TCGContext *s, char *buf, int buf_size, TCGv_i32 arg);
 
 TCGv_i64 tcg_global_reg_new_i64(int reg, const char *name);
-TCGv_i64 tcg_global_mem_new_i64(int reg, tcg_target_long offset,
-                                const char *name);
+TCGv_i64 tcg_global_mem_new_i64(int reg, intptr_t offset, const char *name);
 TCGv_i64 tcg_temp_new_internal_i64(int temp_local);
 static inline TCGv_i64 tcg_temp_new_i64(void)
 {
commit e2c6d1b42d34539120c3cee159dcd9e32cba7d3b
Author: Richard Henderson <rth at twiddle.net>
Date:   Tue Aug 20 15:12:31 2013 -0700

    tcg: Change frame pointer offsets to intptr_t
    
    Reviewed-by: Aurelien Jarno <aurelien at aurel32.net>
    Signed-off-by: Richard Henderson <rth at twiddle.net>

diff --git a/tcg/tcg.c b/tcg/tcg.c
index 65cffca..240e6f4 100644
--- a/tcg/tcg.c
+++ b/tcg/tcg.c
@@ -306,8 +306,7 @@ void tcg_prologue_init(TCGContext *s)
 #endif
 }
 
-void tcg_set_frame(TCGContext *s, int reg,
-                   tcg_target_long start, tcg_target_long size)
+void tcg_set_frame(TCGContext *s, int reg, intptr_t start, intptr_t size)
 {
     s->frame_start = start;
     s->frame_end = start + size;
@@ -1613,7 +1612,7 @@ static void temp_allocate_frame(TCGContext *s, int temp)
     ts->mem_offset = s->current_frame_offset;
     ts->mem_reg = s->frame_reg;
     ts->mem_allocated = 1;
-    s->current_frame_offset += (tcg_target_long)sizeof(tcg_target_long);
+    s->current_frame_offset += sizeof(tcg_target_long);
 }
 
 /* sync register 'reg' by saving it to the corresponding temporary */
diff --git a/tcg/tcg.h b/tcg/tcg.h
index bb215a7..b7e112e 100644
--- a/tcg/tcg.h
+++ b/tcg/tcg.h
@@ -435,9 +435,9 @@ struct TCGContext {
        into account fixed registers */
     int reg_to_temp[TCG_TARGET_NB_REGS];
     TCGRegSet reserved_regs;
-    tcg_target_long current_frame_offset;
-    tcg_target_long frame_start;
-    tcg_target_long frame_end;
+    intptr_t current_frame_offset;
+    intptr_t frame_start;
+    intptr_t frame_end;
     int frame_reg;
 
     uint8_t *code_ptr;
@@ -530,8 +530,7 @@ void tcg_func_start(TCGContext *s);
 int tcg_gen_code(TCGContext *s, uint8_t *gen_code_buf);
 int tcg_gen_code_search_pc(TCGContext *s, uint8_t *gen_code_buf, long offset);
 
-void tcg_set_frame(TCGContext *s, int reg,
-                   tcg_target_long start, tcg_target_long size);
+void tcg_set_frame(TCGContext *s, int reg, intptr_t start, intptr_t size);
 
 TCGv_i32 tcg_global_reg_new_i32(int reg, const char *name);
 TCGv_i32 tcg_global_mem_new_i32(int reg, tcg_target_long offset,
commit 8b73d49f53e1a1d1571ac783ec028ff27befd93e
Author: Richard Henderson <rth at twiddle.net>
Date:   Tue Aug 20 15:07:08 2013 -0700

    tcg: Define TCG_ptr properly
    
    Reviewed-by: Aurelien Jarno <aurelien at aurel32.net>
    Signed-off-by: Richard Henderson <rth at twiddle.net>

diff --git a/tcg/tcg.h b/tcg/tcg.h
index 7a6f2e5..bb215a7 100644
--- a/tcg/tcg.h
+++ b/tcg/tcg.h
@@ -645,11 +645,11 @@ do {\
 
 void tcg_add_target_add_op_defs(const TCGTargetOpDef *tdefs);
 
-#if TCG_TARGET_REG_BITS == 32
+#if UINTPTR_MAX == UINT32_MAX
 #define TCGV_NAT_TO_PTR(n) MAKE_TCGV_PTR(GET_TCGV_I32(n))
 #define TCGV_PTR_TO_NAT(n) MAKE_TCGV_I32(GET_TCGV_PTR(n))
 
-#define tcg_const_ptr(V) TCGV_NAT_TO_PTR(tcg_const_i32((tcg_target_long)(V)))
+#define tcg_const_ptr(V) TCGV_NAT_TO_PTR(tcg_const_i32((intptr_t)(V)))
 #define tcg_global_reg_new_ptr(R, N) \
     TCGV_NAT_TO_PTR(tcg_global_reg_new_i32((R), (N)))
 #define tcg_global_mem_new_ptr(R, O, N) \
@@ -660,7 +660,7 @@ void tcg_add_target_add_op_defs(const TCGTargetOpDef *tdefs);
 #define TCGV_NAT_TO_PTR(n) MAKE_TCGV_PTR(GET_TCGV_I64(n))
 #define TCGV_PTR_TO_NAT(n) MAKE_TCGV_I64(GET_TCGV_PTR(n))
 
-#define tcg_const_ptr(V) TCGV_NAT_TO_PTR(tcg_const_i64((tcg_target_long)(V)))
+#define tcg_const_ptr(V) TCGV_NAT_TO_PTR(tcg_const_i64((intptr_t)(V)))
 #define tcg_global_reg_new_ptr(R, N) \
     TCGV_NAT_TO_PTR(tcg_global_reg_new_i64((R), (N)))
 #define tcg_global_mem_new_ptr(R, O, N) \
commit d289837eef3550ac156082d812231ec5dfe79501
Author: Richard Henderson <rth at twiddle.net>
Date:   Tue Aug 20 14:48:46 2013 -0700

    tcg: Define TCG_TYPE_PTR properly
    
    Reviewed-by: Aurelien Jarno <aurelien at aurel32.net>
    Signed-off-by: Richard Henderson <rth at twiddle.net>

diff --git a/tcg/tcg.h b/tcg/tcg.h
index 8a5e55b..7a6f2e5 100644
--- a/tcg/tcg.h
+++ b/tcg/tcg.h
@@ -178,9 +178,12 @@ typedef enum TCGType {
     TCG_TYPE_REG = TCG_TYPE_I64,
 #endif
 
-    /* An alias for the size of the native pointer.  We don't currently
-       support any hosts with 64-bit registers and 32-bit pointers.  */
-    TCG_TYPE_PTR = TCG_TYPE_REG,
+    /* An alias for the size of the native pointer.  */
+#if UINTPTR_MAX == UINT32_MAX
+    TCG_TYPE_PTR = TCG_TYPE_I32,
+#else
+    TCG_TYPE_PTR = TCG_TYPE_I64,
+#endif
 
     /* An alias for the size of the target "long", aka register.  */
 #if TARGET_LONG_BITS == 64
commit 78cd7b835e13bee4416782b6ed41e9bef76e3cfc
Author: Richard Henderson <rth at twiddle.net>
Date:   Tue Aug 20 14:41:29 2013 -0700

    tcg: Allow TCG_TARGET_REG_BITS to be specified independantly
    
    There are several hosts for which it would be useful to use the
    available 64-bit registers in a 32-bit pointer environment.
    
    Reviewed-by: Aurelien Jarno <aurelien at aurel32.net>
    Signed-off-by: Richard Henderson <rth at twiddle.net>

diff --git a/tcg/hppa/tcg-target.c b/tcg/hppa/tcg-target.c
index 68f77ba..e5aed91 100644
--- a/tcg/hppa/tcg-target.c
+++ b/tcg/hppa/tcg-target.c
@@ -22,6 +22,10 @@
  * THE SOFTWARE.
  */
 
+#if TCG_TARGET_REG_BITS != 32
+#error unsupported
+#endif
+
 #ifndef NDEBUG
 static const char * const tcg_target_reg_names[TCG_TARGET_NB_REGS] = {
     "%r0", "%r1", "%rp", "%r3", "%r4", "%r5", "%r6", "%r7",
diff --git a/tcg/hppa/tcg-target.h b/tcg/hppa/tcg-target.h
index be5895f..122edce 100644
--- a/tcg/hppa/tcg-target.h
+++ b/tcg/hppa/tcg-target.h
@@ -25,10 +25,6 @@
 #ifndef TCG_TARGET_HPPA
 #define TCG_TARGET_HPPA 1
 
-#if TCG_TARGET_REG_BITS != 32
-#error unsupported
-#endif
-
 #define TCG_TARGET_WORDS_BIGENDIAN
 
 #define TCG_TARGET_NB_REGS 32
diff --git a/tcg/i386/tcg-target.h b/tcg/i386/tcg-target.h
index 1f6c7eb..d32d7ef 100644
--- a/tcg/i386/tcg-target.h
+++ b/tcg/i386/tcg-target.h
@@ -24,12 +24,14 @@
 #ifndef TCG_TARGET_I386 
 #define TCG_TARGET_I386 1
 
-//#define TCG_TARGET_WORDS_BIGENDIAN
+#undef TCG_TARGET_WORDS_BIGENDIAN
 
-#if TCG_TARGET_REG_BITS == 64
-# define TCG_TARGET_NB_REGS 16
+#ifdef __x86_64__
+# define TCG_TARGET_REG_BITS  64
+# define TCG_TARGET_NB_REGS   16
 #else
-# define TCG_TARGET_NB_REGS 8
+# define TCG_TARGET_REG_BITS  32
+# define TCG_TARGET_NB_REGS    8
 #endif
 
 typedef enum {
diff --git a/tcg/sparc/tcg-target.h b/tcg/sparc/tcg-target.h
index c0d3abc..2edf858 100644
--- a/tcg/sparc/tcg-target.h
+++ b/tcg/sparc/tcg-target.h
@@ -24,6 +24,14 @@
 #ifndef TCG_TARGET_SPARC 
 #define TCG_TARGET_SPARC 1
 
+#if UINTPTR_MAX == UINT32_MAX
+# define TCG_TARGET_REG_BITS 32
+#elif UINTPTR_MAX == UINT64_MAX
+# define TCG_TARGET_REG_BITS 64
+#else
+# error Unknown pointer size for tcg target
+#endif
+
 #define TCG_TARGET_WORDS_BIGENDIAN
 
 #define TCG_TARGET_NB_REGS 32
diff --git a/tcg/tcg.h b/tcg/tcg.h
index 2fce485..8a5e55b 100644
--- a/tcg/tcg.h
+++ b/tcg/tcg.h
@@ -23,13 +23,17 @@
  */
 #include "qemu-common.h"
 
-/* Target word size (must be identical to pointer size). */
-#if UINTPTR_MAX == UINT32_MAX
-# define TCG_TARGET_REG_BITS 32
-#elif UINTPTR_MAX == UINT64_MAX
-# define TCG_TARGET_REG_BITS 64
-#else
-# error Unknown pointer size for tcg target
+#include "tcg-target.h"
+
+/* Default target word size to pointer size.  */
+#ifndef TCG_TARGET_REG_BITS
+# if UINTPTR_MAX == UINT32_MAX
+#  define TCG_TARGET_REG_BITS 32
+# elif UINTPTR_MAX == UINT64_MAX
+#  define TCG_TARGET_REG_BITS 64
+# else
+#  error Unknown pointer size for tcg target
+# endif
 #endif
 
 #if TCG_TARGET_REG_BITS == 32
@@ -46,7 +50,6 @@ typedef uint64_t tcg_target_ulong;
 #error unsupported
 #endif
 
-#include "tcg-target.h"
 #include "tcg-runtime.h"
 
 #if TCG_TARGET_NB_REGS <= 32
diff --git a/tcg/tci/tcg-target.h b/tcg/tci/tcg-target.h
index 02e0da1..c2ecfbe 100644
--- a/tcg/tci/tcg-target.h
+++ b/tcg/tci/tcg-target.h
@@ -44,6 +44,14 @@
 
 #define TCG_TARGET_INTERPRETER 1
 
+#if UINTPTR_MAX == UINT32_MAX
+# define TCG_TARGET_REG_BITS 32
+#elif UINTPTR_MAX == UINT64_MAX
+# define TCG_TARGET_REG_BITS 64
+#else
+# error Unknown pointer size for tci target
+#endif
+
 #ifdef CONFIG_DEBUG_TCG
 /* Enable debug output. */
 #define CONFIG_DEBUG_TCG_INTERPRETER
commit 3e9bd63acf145bb2d3da277ee85167878ade53bd
Author: Richard Henderson <rth at twiddle.net>
Date:   Tue Aug 20 14:40:25 2013 -0700

    tcg: Fix next_tb type in cpu_exec
    
    Reviewed-by: Aurelien Jarno <aurelien at aurel32.net>
    Signed-off-by: Richard Henderson <rth at twiddle.net>

diff --git a/cpu-exec.c b/cpu-exec.c
index 14af2ed..5a43995 100644
--- a/cpu-exec.c
+++ b/cpu-exec.c
@@ -209,7 +209,7 @@ int cpu_exec(CPUArchState *env)
     int ret, interrupt_request;
     TranslationBlock *tb;
     uint8_t *tc_ptr;
-    tcg_target_ulong next_tb;
+    uintptr_t next_tb;
 
     if (cpu->halted) {
         if (!cpu_has_work(cpu)) {
commit 04d5a1da70dfe1a3a5ac5b5a8e7a7b8136d3a985
Author: Richard Henderson <rth at twiddle.net>
Date:   Tue Aug 20 14:35:34 2013 -0700

    tcg: Change tcg_qemu_tb_exec return to uintptr_t
    
    Reviewed-by: Aurelien Jarno <aurelien at aurel32.net>
    Signed-off-by: Richard Henderson <rth at twiddle.net>

diff --git a/cpu-exec.c b/cpu-exec.c
index 301be28..14af2ed 100644
--- a/cpu-exec.c
+++ b/cpu-exec.c
@@ -53,7 +53,7 @@ void cpu_resume_from_signal(CPUArchState *env, void *puc)
 static inline tcg_target_ulong cpu_tb_exec(CPUState *cpu, uint8_t *tb_ptr)
 {
     CPUArchState *env = cpu->env_ptr;
-    tcg_target_ulong next_tb = tcg_qemu_tb_exec(env, tb_ptr);
+    uintptr_t next_tb = tcg_qemu_tb_exec(env, tb_ptr);
     if ((next_tb & TB_EXIT_MASK) > TB_EXIT_IDX1) {
         /* We didn't start executing this TB (eg because the instruction
          * counter hit zero); we must restore the guest PC to the address
diff --git a/tcg/ppc/tcg-target.h b/tcg/ppc/tcg-target.h
index 613c5ff..c9f8ff5 100644
--- a/tcg/ppc/tcg-target.h
+++ b/tcg/ppc/tcg-target.h
@@ -102,7 +102,7 @@ typedef enum {
 #define TCG_AREG0 TCG_REG_R27
 
 #define tcg_qemu_tb_exec(env, tb_ptr) \
-    ((long __attribute__ ((longcall)) \
+    ((uintptr_t __attribute__ ((longcall)) \
       (*)(void *, void *))tcg_ctx.code_gen_prologue)(env, tb_ptr)
 
 #endif
diff --git a/tcg/tcg.h b/tcg/tcg.h
index 3f869dd..2fce485 100644
--- a/tcg/tcg.h
+++ b/tcg/tcg.h
@@ -733,8 +733,7 @@ TCGv_i64 tcg_const_local_i64(int64_t val);
 
 #if !defined(tcg_qemu_tb_exec)
 # define tcg_qemu_tb_exec(env, tb_ptr) \
-    ((tcg_target_ulong (*)(void *, void *))tcg_ctx.code_gen_prologue)(env, \
-                                                                      tb_ptr)
+    ((uintptr_t (*)(void *, void *))tcg_ctx.code_gen_prologue)(env, tb_ptr)
 #endif
 
 void tcg_register_jit(void *buf, size_t buf_size);
diff --git a/tcg/tci/tcg-target.h b/tcg/tci/tcg-target.h
index e284972..02e0da1 100644
--- a/tcg/tci/tcg-target.h
+++ b/tcg/tci/tcg-target.h
@@ -169,7 +169,7 @@ typedef enum {
 
 void tci_disas(uint8_t opc);
 
-tcg_target_ulong tcg_qemu_tb_exec(CPUArchState *env, uint8_t *tb_ptr);
+uintptr_t tcg_qemu_tb_exec(CPUArchState *env, uint8_t *tb_ptr);
 #define tcg_qemu_tb_exec tcg_qemu_tb_exec
 
 static inline void flush_icache_range(uintptr_t start, uintptr_t stop)
diff --git a/tci.c b/tci.c
index c742c8d..18c888e 100644
--- a/tci.c
+++ b/tci.c
@@ -434,11 +434,11 @@ static bool tci_compare64(uint64_t u0, uint64_t u1, TCGCond condition)
 }
 
 /* Interpret pseudo code in tb. */
-tcg_target_ulong tcg_qemu_tb_exec(CPUArchState *env, uint8_t *tb_ptr)
+uintptr_t tcg_qemu_tb_exec(CPUArchState *env, uint8_t *tb_ptr)
 {
     long tcg_temps[CPU_TEMP_BUF_NLONGS];
     uintptr_t sp_value = (uintptr_t)(tcg_temps + CPU_TEMP_BUF_NLONGS);
-    tcg_target_ulong next_tb = 0;
+    uintptr_t next_tb = 0;
 
     tci_reg[TCG_AREG0] = (tcg_target_ulong)env;
     tci_reg[TCG_REG_CALL_STACK] = sp_value;
commit b93949ef6a5dea2b22987f2aa3028068e751a7e4
Author: Richard Henderson <rth at twiddle.net>
Date:   Tue Aug 20 14:22:50 2013 -0700

    tcg: Change flush_icache_range arguments to uintptr_t
    
    Reviewed-by: Aurelien Jarno <aurelien at aurel32.net>
    Signed-off-by: Richard Henderson <rth at twiddle.net>

diff --git a/tcg/aarch64/tcg-target.h b/tcg/aarch64/tcg-target.h
index 26ee28b..d3a1bc2 100644
--- a/tcg/aarch64/tcg-target.h
+++ b/tcg/aarch64/tcg-target.h
@@ -96,8 +96,7 @@ enum {
     TCG_AREG0 = TCG_REG_X19,
 };
 
-static inline void flush_icache_range(tcg_target_ulong start,
-                                      tcg_target_ulong stop)
+static inline void flush_icache_range(uintptr_t start, uintptr_t stop)
 {
     __builtin___clear_cache((char *)start, (char *)stop);
 }
diff --git a/tcg/arm/tcg-target.h b/tcg/arm/tcg-target.h
index ed48092..9482bfa 100644
--- a/tcg/arm/tcg-target.h
+++ b/tcg/arm/tcg-target.h
@@ -92,15 +92,14 @@ enum {
     TCG_AREG0 = TCG_REG_R6,
 };
 
-static inline void flush_icache_range(tcg_target_ulong start,
-                                      tcg_target_ulong stop)
+static inline void flush_icache_range(uintptr_t start, uintptr_t stop)
 {
 #if QEMU_GNUC_PREREQ(4, 1)
     __builtin___clear_cache((char *) start, (char *) stop);
 #else
-    register unsigned long _beg __asm ("a1") = start;
-    register unsigned long _end __asm ("a2") = stop;
-    register unsigned long _flg __asm ("a3") = 0;
+    register uintptr_t _beg __asm("a1") = start;
+    register uintptr_t _end __asm("a2") = stop;
+    register uintptr_t _flg __asm("a3") = 0;
     __asm __volatile__ ("swi 0x9f0002" : : "r" (_beg), "r" (_end), "r" (_flg));
 #endif
 }
diff --git a/tcg/hppa/tcg-target.h b/tcg/hppa/tcg-target.h
index 0f6f2ff..be5895f 100644
--- a/tcg/hppa/tcg-target.h
+++ b/tcg/hppa/tcg-target.h
@@ -111,8 +111,7 @@ typedef enum {
 #define TCG_AREG0 TCG_REG_R17
 
 
-static inline void flush_icache_range(tcg_target_ulong start,
-                                      tcg_target_ulong stop)
+static inline void flush_icache_range(uintptr_t start, uintptr_t stop)
 {
     start &= ~31;
     while (start <= stop) {
diff --git a/tcg/i386/tcg-target.h b/tcg/i386/tcg-target.h
index b7d1a55..1f6c7eb 100644
--- a/tcg/i386/tcg-target.h
+++ b/tcg/i386/tcg-target.h
@@ -139,8 +139,7 @@ typedef enum {
 # define TCG_AREG0 TCG_REG_EBP
 #endif
 
-static inline void flush_icache_range(tcg_target_ulong start,
-                                      tcg_target_ulong stop)
+static inline void flush_icache_range(uintptr_t start, uintptr_t stop)
 {
 }
 
diff --git a/tcg/ia64/tcg-target.h b/tcg/ia64/tcg-target.h
index ee6b2c8..4330c9c 100644
--- a/tcg/ia64/tcg-target.h
+++ b/tcg/ia64/tcg-target.h
@@ -162,8 +162,7 @@ typedef enum {
 
 #define TCG_AREG0 TCG_REG_R7
 
-static inline void flush_icache_range(tcg_target_ulong start,
-                                      tcg_target_ulong stop)
+static inline void flush_icache_range(uintptr_t start, uintptr_t stop)
 {
     start = start & ~(32UL - 1UL);
     stop = (stop + (32UL - 1UL)) & ~(32UL - 1UL);
diff --git a/tcg/mips/tcg-target.h b/tcg/mips/tcg-target.h
index 7ef79e0..a820328 100644
--- a/tcg/mips/tcg-target.h
+++ b/tcg/mips/tcg-target.h
@@ -127,8 +127,7 @@ typedef enum {
 #include <sys/cachectl.h>
 #endif
 
-static inline void flush_icache_range(tcg_target_ulong start,
-                                      tcg_target_ulong stop)
+static inline void flush_icache_range(uintptr_t start, uintptr_t stop)
 {
     cacheflush ((void *)start, stop-start, ICACHE);
 }
diff --git a/tcg/s390/tcg-target.h b/tcg/s390/tcg-target.h
index b02f170..6142fb2 100644
--- a/tcg/s390/tcg-target.h
+++ b/tcg/s390/tcg-target.h
@@ -114,8 +114,7 @@ enum {
     TCG_AREG0 = TCG_REG_R10,
 };
 
-static inline void flush_icache_range(tcg_target_ulong start,
-                                      tcg_target_ulong stop)
+static inline void flush_icache_range(uintptr_t start, uintptr_t stop)
 {
 }
 
diff --git a/tcg/sparc/tcg-target.h b/tcg/sparc/tcg-target.h
index 1a696bc..c0d3abc 100644
--- a/tcg/sparc/tcg-target.h
+++ b/tcg/sparc/tcg-target.h
@@ -142,16 +142,12 @@ typedef enum {
 
 #define TCG_AREG0 TCG_REG_I0
 
-static inline void flush_icache_range(tcg_target_ulong start,
-                                      tcg_target_ulong stop)
+static inline void flush_icache_range(uintptr_t start, uintptr_t stop)
 {
-    unsigned long p;
-
-    p = start & ~(8UL - 1UL);
-    stop = (stop + (8UL - 1UL)) & ~(8UL - 1UL);
-
-    for (; p < stop; p += 8)
+    uintptr_t p;
+    for (p = start & -8; p < (stop + 7) & -8; p += 8) {
         __asm__ __volatile__("flush\t%0" : : "r" (p));
+    }
 }
 
 #endif
diff --git a/tcg/tcg.c b/tcg/tcg.c
index 541a442..65cffca 100644
--- a/tcg/tcg.c
+++ b/tcg/tcg.c
@@ -293,8 +293,7 @@ void tcg_prologue_init(TCGContext *s)
     s->code_buf = s->code_gen_prologue;
     s->code_ptr = s->code_buf;
     tcg_target_qemu_prologue(s);
-    flush_icache_range((tcg_target_ulong)s->code_buf,
-                       (tcg_target_ulong)s->code_ptr);
+    flush_icache_range((uintptr_t)s->code_buf, (uintptr_t)s->code_ptr);
 
 #ifdef DEBUG_DISAS
     if (qemu_loglevel_mask(CPU_LOG_TB_OUT_ASM)) {
@@ -2415,8 +2414,7 @@ int tcg_gen_code(TCGContext *s, uint8_t *gen_code_buf)
     tcg_gen_code_common(s, gen_code_buf, -1);
 
     /* flush instruction cache */
-    flush_icache_range((tcg_target_ulong)gen_code_buf,
-                       (tcg_target_ulong)s->code_ptr);
+    flush_icache_range((uintptr_t)gen_code_buf, (uintptr_t)s->code_ptr);
 
     return s->code_ptr -  gen_code_buf;
 }
diff --git a/tcg/tci/tcg-target.h b/tcg/tci/tcg-target.h
index ff12b4b..e284972 100644
--- a/tcg/tci/tcg-target.h
+++ b/tcg/tci/tcg-target.h
@@ -172,8 +172,7 @@ void tci_disas(uint8_t opc);
 tcg_target_ulong tcg_qemu_tb_exec(CPUArchState *env, uint8_t *tb_ptr);
 #define tcg_qemu_tb_exec tcg_qemu_tb_exec
 
-static inline void flush_icache_range(tcg_target_ulong start,
-                                      tcg_target_ulong stop)
+static inline void flush_icache_range(uintptr_t start, uintptr_t stop)
 {
 }
 
commit 35aa3fb38753bd1557af8370994ce6c5b599e65c
Author: Richard Henderson <rth at twiddle.net>
Date:   Tue Aug 20 13:53:25 2013 -0700

    qtest: Fix FMT_timeval vs time_t
    
    Since FMT_timeval unconditionally uses %ld for both tv_sec and tv_usec,
    and already casts tv_usec to long, also cast tv_sec to long.
    
    Cc: Andreas Färber <afaerber at suse.de>
    Reviewed-by: Aurelien Jarno <aurelien at aurel32.net>
    Signed-off-by: Richard Henderson <rth at twiddle.net>

diff --git a/qtest.c b/qtest.c
index ef671fb..584c707 100644
--- a/qtest.c
+++ b/qtest.c
@@ -177,7 +177,7 @@ static void qtest_send_prefix(CharDriverState *chr)
 
     qtest_get_time(&tv);
     fprintf(qtest_log_fp, "[S +" FMT_timeval "] ",
-            tv.tv_sec, (long) tv.tv_usec);
+            (long) tv.tv_sec, (long) tv.tv_usec);
 }
 
 static void GCC_FMT_ATTR(2, 3) qtest_send(CharDriverState *chr,
@@ -225,7 +225,7 @@ static void qtest_process_command(CharDriverState *chr, gchar **words)
 
         qtest_get_time(&tv);
         fprintf(qtest_log_fp, "[R +" FMT_timeval "]",
-                tv.tv_sec, (long) tv.tv_usec);
+                (long) tv.tv_sec, (long) tv.tv_usec);
         for (i = 0; words[i]; i++) {
             fprintf(qtest_log_fp, " %s", words[i]);
         }
@@ -485,7 +485,7 @@ static void qtest_event(void *opaque, int event)
         qtest_opened = true;
         if (qtest_log_fp) {
             fprintf(qtest_log_fp, "[I " FMT_timeval "] OPENED\n",
-                    start_time.tv_sec, (long) start_time.tv_usec);
+                    (long) start_time.tv_sec, (long) start_time.tv_usec);
         }
         break;
     case CHR_EVENT_CLOSED:
@@ -494,7 +494,7 @@ static void qtest_event(void *opaque, int event)
             qemu_timeval tv;
             qtest_get_time(&tv);
             fprintf(qtest_log_fp, "[I +" FMT_timeval "] CLOSED\n",
-                    tv.tv_sec, (long) tv.tv_usec);
+                    (long) tv.tv_sec, (long) tv.tv_usec);
         }
         break;
     default:
commit 01547f7f9283e416578323e5d5df3327ed4df3ee
Author: Richard Henderson <rth at twiddle.net>
Date:   Wed Aug 14 15:22:46 2013 -0700

    tcg: Constant fold div, rem
    
    Reviewed-by: Aurelien Jarno <aurelien at aurel32.net>
    Signed-off-by: Richard Henderson <rth at twiddle.net>

diff --git a/tcg/optimize.c b/tcg/optimize.c
index e8dedf3..b29bf25 100644
--- a/tcg/optimize.c
+++ b/tcg/optimize.c
@@ -304,6 +304,25 @@ static TCGArg do_constant_folding_2(TCGOpcode op, TCGArg x, TCGArg y)
         muls64(&l64, &h64, x, y);
         return h64;
 
+    case INDEX_op_div_i32:
+        /* Avoid crashing on divide by zero, otherwise undefined.  */
+        return (int32_t)x / ((int32_t)y ? : 1);
+    case INDEX_op_divu_i32:
+        return (uint32_t)x / ((uint32_t)y ? : 1);
+    case INDEX_op_div_i64:
+        return (int64_t)x / ((int64_t)y ? : 1);
+    case INDEX_op_divu_i64:
+        return (uint64_t)x / ((uint64_t)y ? : 1);
+
+    case INDEX_op_rem_i32:
+        return (int32_t)x % ((int32_t)y ? : 1);
+    case INDEX_op_remu_i32:
+        return (uint32_t)x % ((uint32_t)y ? : 1);
+    case INDEX_op_rem_i64:
+        return (int64_t)x % ((int64_t)y ? : 1);
+    case INDEX_op_remu_i64:
+        return (uint64_t)x % ((uint64_t)y ? : 1);
+
     default:
         fprintf(stderr,
                 "Unrecognized operation %d in do_constant_folding.\n", op);
@@ -902,6 +921,10 @@ static TCGArg *tcg_constant_folding(TCGContext *s, uint16_t *tcg_opc_ptr,
         CASE_OP_32_64(nor):
         CASE_OP_32_64(muluh):
         CASE_OP_32_64(mulsh):
+        CASE_OP_32_64(div):
+        CASE_OP_32_64(divu):
+        CASE_OP_32_64(rem):
+        CASE_OP_32_64(remu):
             if (temps[args[1]].state == TCG_TEMP_CONST
                 && temps[args[2]].state == TCG_TEMP_CONST) {
                 s->gen_opc_buf[op_index] = op_to_movi(op);
commit 32f5717f07e5f801e482052311d21a4223fc78f1
Author: Richard Henderson <rth at twiddle.net>
Date:   Wed Aug 14 14:46:08 2013 -0700

    tcg-ppc64: Implement muluh, mulsh
    
    Using these instead of mulu2 and muls2 lets us avoid having to argument
    overlap analysis in the backend.  Normal register allocation will DTRT.
    
    Reviewed-by: Aurelien Jarno <aurelien at aurel32.net>
    Signed-off-by: Richard Henderson <rth at twiddle.net>

diff --git a/tcg/ppc64/tcg-target.c b/tcg/ppc64/tcg-target.c
index 0678de2..939f7cb 100644
--- a/tcg/ppc64/tcg-target.c
+++ b/tcg/ppc64/tcg-target.c
@@ -1975,29 +1975,11 @@ static void tcg_out_op (TCGContext *s, TCGOpcode opc, const TCGArg *args,
         }
         break;
 
-    case INDEX_op_mulu2_i64:
-    case INDEX_op_muls2_i64:
-        {
-            int oph = (opc == INDEX_op_mulu2_i64 ? MULHDU : MULHD);
-            TCGReg outl = args[0], outh = args[1];
-            a0 = args[2], a1 = args[3];
-
-            if (outl == a0 || outl == a1) {
-                if (outh == a0 || outh == a1) {
-                    outl = TCG_REG_R0;
-                } else {
-                    tcg_out32(s, oph | TAB(outh, a0, a1));
-                    oph = 0;
-                }
-            }
-            tcg_out32(s, MULLD | TAB(outl, a0, a1));
-            if (oph != 0) {
-                tcg_out32(s, oph | TAB(outh, a0, a1));
-            }
-            if (outl != args[0]) {
-                tcg_out_mov(s, TCG_TYPE_I64, args[0], outl);
-            }
-        }
+    case INDEX_op_muluh_i64:
+        tcg_out32(s, MULHDU | TAB(args[0], args[1], args[2]));
+        break;
+    case INDEX_op_mulsh_i64:
+        tcg_out32(s, MULHD | TAB(args[0], args[1], args[2]));
         break;
 
     default:
@@ -2124,8 +2106,8 @@ static const TCGTargetOpDef ppc_op_defs[] = {
 
     { 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" } },
+    { INDEX_op_mulsh_i64, { "r", "r", "r" } },
+    { INDEX_op_muluh_i64, { "r", "r", "r" } },
 
     { -1 },
 };
diff --git a/tcg/ppc64/tcg-target.h b/tcg/ppc64/tcg-target.h
index 0789daf..fa4b9da 100644
--- a/tcg/ppc64/tcg-target.h
+++ b/tcg/ppc64/tcg-target.h
@@ -118,10 +118,10 @@ typedef enum {
 #define TCG_TARGET_HAS_movcond_i64      1
 #define TCG_TARGET_HAS_add2_i64         1
 #define TCG_TARGET_HAS_sub2_i64         1
-#define TCG_TARGET_HAS_mulu2_i64        1
-#define TCG_TARGET_HAS_muls2_i64        1
-#define TCG_TARGET_HAS_muluh_i64        0
-#define TCG_TARGET_HAS_mulsh_i64        0
+#define TCG_TARGET_HAS_mulu2_i64        0
+#define TCG_TARGET_HAS_muls2_i64        0
+#define TCG_TARGET_HAS_muluh_i64        1
+#define TCG_TARGET_HAS_mulsh_i64        1
 
 #define TCG_AREG0 TCG_REG_R27
 
commit 3c9a8f17560794ad23889318cc42894c6e592cc3
Author: Richard Henderson <rth at twiddle.net>
Date:   Wed Aug 14 14:41:43 2013 -0700

    tcg-mips: Implement mulsh, muluh
    
    With the optimization in tcg_liveness_analysis,
    we can avoid the MFLO when it is unused.
    
    Reviewed-by: Aurelien Jarno <aurelien at aurel32.net>
    Signed-off-by: Richard Henderson <rth at twiddle.net>

diff --git a/tcg/mips/tcg-target.c b/tcg/mips/tcg-target.c
index 793532e..31cd514 100644
--- a/tcg/mips/tcg-target.c
+++ b/tcg/mips/tcg-target.c
@@ -1423,6 +1423,14 @@ static inline void tcg_out_op(TCGContext *s, TCGOpcode opc,
         tcg_out_opc_reg(s, OPC_MFLO, args[0], 0, 0);
         tcg_out_opc_reg(s, OPC_MFHI, args[1], 0, 0);
         break;
+    case INDEX_op_mulsh_i32:
+        tcg_out_opc_reg(s, OPC_MULT, 0, args[1], args[2]);
+        tcg_out_opc_reg(s, OPC_MFHI, args[0], 0, 0);
+        break;
+    case INDEX_op_muluh_i32:
+        tcg_out_opc_reg(s, OPC_MULTU, 0, args[1], args[2]);
+        tcg_out_opc_reg(s, OPC_MFHI, args[0], 0, 0);
+        break;
     case INDEX_op_div_i32:
         tcg_out_opc_reg(s, OPC_DIV, 0, args[1], args[2]);
         tcg_out_opc_reg(s, OPC_MFLO, args[0], 0, 0);
@@ -1602,6 +1610,8 @@ static const TCGTargetOpDef mips_op_defs[] = {
     { INDEX_op_mul_i32, { "r", "rZ", "rZ" } },
     { INDEX_op_muls2_i32, { "r", "r", "rZ", "rZ" } },
     { INDEX_op_mulu2_i32, { "r", "r", "rZ", "rZ" } },
+    { INDEX_op_mulsh_i32, { "r", "rZ", "rZ" } },
+    { INDEX_op_muluh_i32, { "r", "rZ", "rZ" } },
     { INDEX_op_div_i32, { "r", "rZ", "rZ" } },
     { INDEX_op_divu_i32, { "r", "rZ", "rZ" } },
     { INDEX_op_rem_i32, { "r", "rZ", "rZ" } },
diff --git a/tcg/mips/tcg-target.h b/tcg/mips/tcg-target.h
index 6cb7c2f..7ef79e0 100644
--- a/tcg/mips/tcg-target.h
+++ b/tcg/mips/tcg-target.h
@@ -89,8 +89,8 @@ typedef enum {
 #define TCG_TARGET_HAS_eqv_i32          0
 #define TCG_TARGET_HAS_nand_i32         0
 #define TCG_TARGET_HAS_muls2_i32        1
-#define TCG_TARGET_HAS_muluh_i32        0
-#define TCG_TARGET_HAS_mulsh_i32        0
+#define TCG_TARGET_HAS_muluh_i32        1
+#define TCG_TARGET_HAS_mulsh_i32        1
 
 /* optional instructions only implemented on MIPS4, MIPS32 and Loongson 2 */
 #if (defined(__mips_isa_rev) && (__mips_isa_rev >= 1)) || \
commit 03271524b66dfc979cc0412bdb5d8d617426b644
Author: Richard Henderson <rth at twiddle.net>
Date:   Wed Aug 14 14:35:56 2013 -0700

    tcg: Add muluh and mulsh opcodes
    
    Use them in places where mulu2 and muls2 are used.
    Optimize mulx2 with dead low part to mulxh.
    
    Reviewed-by: Aurelien Jarno <aurelien at aurel32.net>
    Signed-off-by: Richard Henderson <rth at twiddle.net>

diff --git a/tcg/aarch64/tcg-target.h b/tcg/aarch64/tcg-target.h
index 51e5092..26ee28b 100644
--- a/tcg/aarch64/tcg-target.h
+++ b/tcg/aarch64/tcg-target.h
@@ -61,6 +61,8 @@ typedef enum {
 #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_muluh_i32        0
+#define TCG_TARGET_HAS_mulsh_i32        0
 
 #define TCG_TARGET_HAS_div_i64          0
 #define TCG_TARGET_HAS_rem_i64          0
@@ -87,6 +89,8 @@ typedef enum {
 #define TCG_TARGET_HAS_sub2_i64         0
 #define TCG_TARGET_HAS_mulu2_i64        0
 #define TCG_TARGET_HAS_muls2_i64        0
+#define TCG_TARGET_HAS_muluh_i64        0
+#define TCG_TARGET_HAS_mulsh_i64        0
 
 enum {
     TCG_AREG0 = TCG_REG_X19,
diff --git a/tcg/arm/tcg-target.h b/tcg/arm/tcg-target.h
index 5cd9d6a..ed48092 100644
--- a/tcg/arm/tcg-target.h
+++ b/tcg/arm/tcg-target.h
@@ -80,6 +80,8 @@ extern bool use_idiv_instructions;
 #define TCG_TARGET_HAS_deposit_i32      1
 #define TCG_TARGET_HAS_movcond_i32      1
 #define TCG_TARGET_HAS_muls2_i32        1
+#define TCG_TARGET_HAS_muluh_i32        0
+#define TCG_TARGET_HAS_mulsh_i32        0
 #define TCG_TARGET_HAS_div_i32          use_idiv_instructions
 #define TCG_TARGET_HAS_rem_i32          0
 
diff --git a/tcg/hppa/tcg-target.h b/tcg/hppa/tcg-target.h
index 25467bd..0f6f2ff 100644
--- a/tcg/hppa/tcg-target.h
+++ b/tcg/hppa/tcg-target.h
@@ -100,6 +100,8 @@ typedef enum {
 #define TCG_TARGET_HAS_deposit_i32      1
 #define TCG_TARGET_HAS_movcond_i32      1
 #define TCG_TARGET_HAS_muls2_i32        0
+#define TCG_TARGET_HAS_muluh_i32        0
+#define TCG_TARGET_HAS_mulsh_i32        0
 
 /* optional instructions automatically implemented */
 #define TCG_TARGET_HAS_neg_i32          0 /* sub rd, 0, rs */
diff --git a/tcg/i386/tcg-target.h b/tcg/i386/tcg-target.h
index e3f6bb9..b7d1a55 100644
--- a/tcg/i386/tcg-target.h
+++ b/tcg/i386/tcg-target.h
@@ -96,6 +96,8 @@ typedef enum {
 #define TCG_TARGET_HAS_sub2_i32         1
 #define TCG_TARGET_HAS_mulu2_i32        1
 #define TCG_TARGET_HAS_muls2_i32        1
+#define TCG_TARGET_HAS_muluh_i32        0
+#define TCG_TARGET_HAS_mulsh_i32        0
 
 #if TCG_TARGET_REG_BITS == 64
 #define TCG_TARGET_HAS_div2_i64         1
@@ -122,6 +124,8 @@ typedef enum {
 #define TCG_TARGET_HAS_sub2_i64         1
 #define TCG_TARGET_HAS_mulu2_i64        1
 #define TCG_TARGET_HAS_muls2_i64        1
+#define TCG_TARGET_HAS_muluh_i64        0
+#define TCG_TARGET_HAS_mulsh_i64        0
 #endif
 
 #define TCG_TARGET_deposit_i32_valid(ofs, len) \
diff --git a/tcg/ia64/tcg-target.h b/tcg/ia64/tcg-target.h
index f32d519..ee6b2c8 100644
--- a/tcg/ia64/tcg-target.h
+++ b/tcg/ia64/tcg-target.h
@@ -146,6 +146,10 @@ typedef enum {
 #define TCG_TARGET_HAS_mulu2_i64        0
 #define TCG_TARGET_HAS_muls2_i32        0
 #define TCG_TARGET_HAS_muls2_i64        0
+#define TCG_TARGET_HAS_muluh_i32        0
+#define TCG_TARGET_HAS_muluh_i64        0
+#define TCG_TARGET_HAS_mulsh_i32        0
+#define TCG_TARGET_HAS_mulsh_i64        0
 
 #define TCG_TARGET_deposit_i32_valid(ofs, len) ((len) <= 16)
 #define TCG_TARGET_deposit_i64_valid(ofs, len) ((len) <= 16)
diff --git a/tcg/mips/tcg-target.h b/tcg/mips/tcg-target.h
index a438950..6cb7c2f 100644
--- a/tcg/mips/tcg-target.h
+++ b/tcg/mips/tcg-target.h
@@ -89,6 +89,8 @@ typedef enum {
 #define TCG_TARGET_HAS_eqv_i32          0
 #define TCG_TARGET_HAS_nand_i32         0
 #define TCG_TARGET_HAS_muls2_i32        1
+#define TCG_TARGET_HAS_muluh_i32        0
+#define TCG_TARGET_HAS_mulsh_i32        0
 
 /* optional instructions only implemented on MIPS4, MIPS32 and Loongson 2 */
 #if (defined(__mips_isa_rev) && (__mips_isa_rev >= 1)) || \
diff --git a/tcg/optimize.c b/tcg/optimize.c
index b35868a..e8dedf3 100644
--- a/tcg/optimize.c
+++ b/tcg/optimize.c
@@ -198,6 +198,8 @@ static TCGOpcode op_to_mov(TCGOpcode op)
 
 static TCGArg do_constant_folding_2(TCGOpcode op, TCGArg x, TCGArg y)
 {
+    uint64_t l64, h64;
+
     switch (op) {
     CASE_OP_32_64(add):
         return x + y;
@@ -290,6 +292,18 @@ static TCGArg do_constant_folding_2(TCGOpcode op, TCGArg x, TCGArg y)
     case INDEX_op_ext32u_i64:
         return (uint32_t)x;
 
+    case INDEX_op_muluh_i32:
+        return ((uint64_t)(uint32_t)x * (uint32_t)y) >> 32;
+    case INDEX_op_mulsh_i32:
+        return ((int64_t)(int32_t)x * (int32_t)y) >> 32;
+
+    case INDEX_op_muluh_i64:
+        mulu64(&l64, &h64, x, y);
+        return h64;
+    case INDEX_op_mulsh_i64:
+        muls64(&l64, &h64, x, y);
+        return h64;
+
     default:
         fprintf(stderr,
                 "Unrecognized operation %d in do_constant_folding.\n", op);
@@ -531,6 +545,8 @@ static TCGArg *tcg_constant_folding(TCGContext *s, uint16_t *tcg_opc_ptr,
         CASE_OP_32_64(eqv):
         CASE_OP_32_64(nand):
         CASE_OP_32_64(nor):
+        CASE_OP_32_64(muluh):
+        CASE_OP_32_64(mulsh):
             swap_commutative(args[0], &args[1], &args[2]);
             break;
         CASE_OP_32_64(brcond):
@@ -771,6 +787,8 @@ static TCGArg *tcg_constant_folding(TCGContext *s, uint16_t *tcg_opc_ptr,
         switch (op) {
         CASE_OP_32_64(and):
         CASE_OP_32_64(mul):
+        CASE_OP_32_64(muluh):
+        CASE_OP_32_64(mulsh):
             if ((temps[args[2]].state == TCG_TEMP_CONST
                 && temps[args[2]].val == 0)) {
                 s->gen_opc_buf[op_index] = op_to_movi(op);
@@ -882,6 +900,8 @@ static TCGArg *tcg_constant_folding(TCGContext *s, uint16_t *tcg_opc_ptr,
         CASE_OP_32_64(eqv):
         CASE_OP_32_64(nand):
         CASE_OP_32_64(nor):
+        CASE_OP_32_64(muluh):
+        CASE_OP_32_64(mulsh):
             if (temps[args[1]].state == TCG_TEMP_CONST
                 && temps[args[2]].state == TCG_TEMP_CONST) {
                 s->gen_opc_buf[op_index] = op_to_movi(op);
diff --git a/tcg/ppc/tcg-target.h b/tcg/ppc/tcg-target.h
index b42d97c..613c5ff 100644
--- a/tcg/ppc/tcg-target.h
+++ b/tcg/ppc/tcg-target.h
@@ -96,6 +96,8 @@ typedef enum {
 #define TCG_TARGET_HAS_deposit_i32      1
 #define TCG_TARGET_HAS_movcond_i32      1
 #define TCG_TARGET_HAS_muls2_i32        0
+#define TCG_TARGET_HAS_muluh_i32        0
+#define TCG_TARGET_HAS_mulsh_i32        0
 
 #define TCG_AREG0 TCG_REG_R27
 
diff --git a/tcg/ppc64/tcg-target.h b/tcg/ppc64/tcg-target.h
index 48fc6e2..0789daf 100644
--- a/tcg/ppc64/tcg-target.h
+++ b/tcg/ppc64/tcg-target.h
@@ -95,6 +95,8 @@ typedef enum {
 #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_muluh_i32        0
+#define TCG_TARGET_HAS_mulsh_i32        0
 
 #define TCG_TARGET_HAS_div_i64          1
 #define TCG_TARGET_HAS_rem_i64          0
@@ -118,6 +120,8 @@ typedef enum {
 #define TCG_TARGET_HAS_sub2_i64         1
 #define TCG_TARGET_HAS_mulu2_i64        1
 #define TCG_TARGET_HAS_muls2_i64        1
+#define TCG_TARGET_HAS_muluh_i64        0
+#define TCG_TARGET_HAS_mulsh_i64        0
 
 #define TCG_AREG0 TCG_REG_R27
 
diff --git a/tcg/s390/tcg-target.h b/tcg/s390/tcg-target.h
index 42ca36c..b02f170 100644
--- a/tcg/s390/tcg-target.h
+++ b/tcg/s390/tcg-target.h
@@ -69,6 +69,8 @@ typedef enum TCGReg {
 #define TCG_TARGET_HAS_sub2_i32         1
 #define TCG_TARGET_HAS_mulu2_i32        0
 #define TCG_TARGET_HAS_muls2_i32        0
+#define TCG_TARGET_HAS_muluh_i32        0
+#define TCG_TARGET_HAS_mulsh_i32        0
 
 #define TCG_TARGET_HAS_div2_i64         1
 #define TCG_TARGET_HAS_rot_i64          1
@@ -94,6 +96,8 @@ typedef enum TCGReg {
 #define TCG_TARGET_HAS_sub2_i64         1
 #define TCG_TARGET_HAS_mulu2_i64        1
 #define TCG_TARGET_HAS_muls2_i64        0
+#define TCG_TARGET_HAS_muluh_i64        0
+#define TCG_TARGET_HAS_mulsh_i64        0
 
 extern bool tcg_target_deposit_valid(int ofs, int len);
 #define TCG_TARGET_deposit_i32_valid  tcg_target_deposit_valid
diff --git a/tcg/sparc/tcg-target.h b/tcg/sparc/tcg-target.h
index dab52d7..1a696bc 100644
--- a/tcg/sparc/tcg-target.h
+++ b/tcg/sparc/tcg-target.h
@@ -107,6 +107,8 @@ typedef enum {
 #define TCG_TARGET_HAS_sub2_i32         1
 #define TCG_TARGET_HAS_mulu2_i32        1
 #define TCG_TARGET_HAS_muls2_i32        0
+#define TCG_TARGET_HAS_muluh_i32        0
+#define TCG_TARGET_HAS_mulsh_i32        0
 
 #if TCG_TARGET_REG_BITS == 64
 #define TCG_TARGET_HAS_div_i64          1
@@ -134,6 +136,8 @@ typedef enum {
 #define TCG_TARGET_HAS_sub2_i64         0
 #define TCG_TARGET_HAS_mulu2_i64        0
 #define TCG_TARGET_HAS_muls2_i64        0
+#define TCG_TARGET_HAS_muluh_i64        0
+#define TCG_TARGET_HAS_mulsh_i64        0
 #endif
 
 #define TCG_AREG0 TCG_REG_I0
diff --git a/tcg/tcg-op.h b/tcg/tcg-op.h
index 364964d..3de7545 100644
--- a/tcg/tcg-op.h
+++ b/tcg/tcg-op.h
@@ -1039,10 +1039,18 @@ static inline void tcg_gen_mul_i64(TCGv_i64 ret, TCGv_i64 arg1, TCGv_i64 arg2)
     t0 = tcg_temp_new_i64();
     t1 = tcg_temp_new_i32();
 
-    tcg_gen_op4_i32(INDEX_op_mulu2_i32, TCGV_LOW(t0), TCGV_HIGH(t0),
-                    TCGV_LOW(arg1), TCGV_LOW(arg2));
-    /* Allow the optimizer room to replace mulu2 with two moves.  */
-    tcg_gen_op0(INDEX_op_nop);
+    if (TCG_TARGET_HAS_mulu2_i32) {
+        tcg_gen_op4_i32(INDEX_op_mulu2_i32, TCGV_LOW(t0), TCGV_HIGH(t0),
+                        TCGV_LOW(arg1), TCGV_LOW(arg2));
+        /* Allow the optimizer room to replace mulu2 with two moves.  */
+        tcg_gen_op0(INDEX_op_nop);
+    } else {
+        tcg_debug_assert(TCG_TARGET_HAS_muluh_i32);
+        tcg_gen_op3_i32(INDEX_op_mul_i32, TCGV_LOW(t0),
+                        TCGV_LOW(arg1), TCGV_LOW(arg2));
+        tcg_gen_op3_i32(INDEX_op_muluh_i32, TCGV_HIGH(t0),
+                        TCGV_LOW(arg1), TCGV_LOW(arg2));
+    }
 
     tcg_gen_mul_i32(t1, TCGV_LOW(arg1), TCGV_HIGH(arg2));
     tcg_gen_add_i32(TCGV_HIGH(t0), TCGV_HIGH(t0), t1);
@@ -2401,6 +2409,12 @@ static inline void tcg_gen_mulu2_i32(TCGv_i32 rl, TCGv_i32 rh,
         tcg_gen_op4_i32(INDEX_op_mulu2_i32, rl, rh, arg1, arg2);
         /* Allow the optimizer room to replace mulu2 with two moves.  */
         tcg_gen_op0(INDEX_op_nop);
+    } else if (TCG_TARGET_HAS_muluh_i32) {
+        TCGv_i32 t = tcg_temp_new_i32();
+        tcg_gen_op3_i32(INDEX_op_mul_i32, t, arg1, arg2);
+        tcg_gen_op3_i32(INDEX_op_muluh_i32, rh, arg1, arg2);
+        tcg_gen_mov_i32(rl, t);
+        tcg_temp_free_i32(t);
     } else {
         TCGv_i64 t0 = tcg_temp_new_i64();
         TCGv_i64 t1 = tcg_temp_new_i64();
@@ -2420,6 +2434,12 @@ static inline void tcg_gen_muls2_i32(TCGv_i32 rl, TCGv_i32 rh,
         tcg_gen_op4_i32(INDEX_op_muls2_i32, rl, rh, arg1, arg2);
         /* Allow the optimizer room to replace muls2 with two moves.  */
         tcg_gen_op0(INDEX_op_nop);
+    } else if (TCG_TARGET_HAS_mulsh_i32) {
+        TCGv_i32 t = tcg_temp_new_i32();
+        tcg_gen_op3_i32(INDEX_op_mul_i32, t, arg1, arg2);
+        tcg_gen_op3_i32(INDEX_op_mulsh_i32, rh, arg1, arg2);
+        tcg_gen_mov_i32(rl, t);
+        tcg_temp_free_i32(t);
     } else if (TCG_TARGET_REG_BITS == 32 && TCG_TARGET_HAS_mulu2_i32) {
         TCGv_i32 t0 = tcg_temp_new_i32();
         TCGv_i32 t1 = tcg_temp_new_i32();
@@ -2499,6 +2519,12 @@ static inline void tcg_gen_mulu2_i64(TCGv_i64 rl, TCGv_i64 rh,
         tcg_gen_op4_i64(INDEX_op_mulu2_i64, rl, rh, arg1, arg2);
         /* Allow the optimizer room to replace mulu2 with two moves.  */
         tcg_gen_op0(INDEX_op_nop);
+    } else if (TCG_TARGET_HAS_muluh_i64) {
+        TCGv_i64 t = tcg_temp_new_i64();
+        tcg_gen_op3_i64(INDEX_op_mul_i64, t, arg1, arg2);
+        tcg_gen_op3_i64(INDEX_op_muluh_i64, rh, arg1, arg2);
+        tcg_gen_mov_i64(rl, t);
+        tcg_temp_free_i64(t);
     } else if (TCG_TARGET_HAS_mulu2_i64) {
         TCGv_i64 t0 = tcg_temp_new_i64();
         TCGv_i64 t1 = tcg_temp_new_i64();
@@ -2540,6 +2566,12 @@ static inline void tcg_gen_muls2_i64(TCGv_i64 rl, TCGv_i64 rh,
         tcg_gen_op4_i64(INDEX_op_muls2_i64, rl, rh, arg1, arg2);
         /* Allow the optimizer room to replace muls2 with two moves.  */
         tcg_gen_op0(INDEX_op_nop);
+    } else if (TCG_TARGET_HAS_mulsh_i64) {
+        TCGv_i64 t = tcg_temp_new_i64();
+        tcg_gen_op3_i64(INDEX_op_mul_i64, t, arg1, arg2);
+        tcg_gen_op3_i64(INDEX_op_mulsh_i64, rh, arg1, arg2);
+        tcg_gen_mov_i64(rl, t);
+        tcg_temp_free_i64(t);
     } else {
         TCGv_i64 t0 = tcg_temp_new_i64();
         int sizemask = 0;
diff --git a/tcg/tcg-opc.h b/tcg/tcg-opc.h
index a8af5b9..a75c29d 100644
--- a/tcg/tcg-opc.h
+++ b/tcg/tcg-opc.h
@@ -91,6 +91,8 @@ DEF(add2_i32, 2, 4, 0, IMPL(TCG_TARGET_HAS_add2_i32))
 DEF(sub2_i32, 2, 4, 0, IMPL(TCG_TARGET_HAS_sub2_i32))
 DEF(mulu2_i32, 2, 2, 0, IMPL(TCG_TARGET_HAS_mulu2_i32))
 DEF(muls2_i32, 2, 2, 0, IMPL(TCG_TARGET_HAS_muls2_i32))
+DEF(muluh_i32, 1, 2, 0, IMPL(TCG_TARGET_HAS_muluh_i32))
+DEF(mulsh_i32, 1, 2, 0, IMPL(TCG_TARGET_HAS_mulsh_i32))
 DEF(brcond2_i32, 0, 4, 2, TCG_OPF_BB_END | IMPL(TCG_TARGET_REG_BITS == 32))
 DEF(setcond2_i32, 1, 4, 1, IMPL(TCG_TARGET_REG_BITS == 32))
 
@@ -167,6 +169,8 @@ DEF(add2_i64, 2, 4, 0, IMPL64 | IMPL(TCG_TARGET_HAS_add2_i64))
 DEF(sub2_i64, 2, 4, 0, IMPL64 | IMPL(TCG_TARGET_HAS_sub2_i64))
 DEF(mulu2_i64, 2, 2, 0, IMPL64 | IMPL(TCG_TARGET_HAS_mulu2_i64))
 DEF(muls2_i64, 2, 2, 0, IMPL64 | IMPL(TCG_TARGET_HAS_muls2_i64))
+DEF(muluh_i64, 1, 2, 0, IMPL(TCG_TARGET_HAS_muluh_i64))
+DEF(mulsh_i64, 1, 2, 0, IMPL(TCG_TARGET_HAS_mulsh_i64))
 
 /* QEMU specific */
 #if TARGET_LONG_BITS > TCG_TARGET_REG_BITS
diff --git a/tcg/tcg.c b/tcg/tcg.c
index 19bd5a3..541a442 100644
--- a/tcg/tcg.c
+++ b/tcg/tcg.c
@@ -1252,12 +1252,13 @@ static inline void tcg_la_bb_end(TCGContext *s, uint8_t *dead_temps,
 static void tcg_liveness_analysis(TCGContext *s)
 {
     int i, op_index, nb_args, nb_iargs, nb_oargs, arg, nb_ops;
-    TCGOpcode op, op_new;
+    TCGOpcode op, op_new, op_new2;
     TCGArg *args;
     const TCGOpDef *def;
     uint8_t *dead_temps, *mem_temps;
     uint16_t dead_args;
     uint8_t sync_args;
+    bool have_op_new2;
     
     s->gen_opc_ptr++; /* skip end */
 
@@ -1394,29 +1395,52 @@ static void tcg_liveness_analysis(TCGContext *s)
             goto do_not_remove;
 
         case INDEX_op_mulu2_i32:
+            op_new = INDEX_op_mul_i32;
+            op_new2 = INDEX_op_muluh_i32;
+            have_op_new2 = TCG_TARGET_HAS_muluh_i32;
+            goto do_mul2;
         case INDEX_op_muls2_i32:
             op_new = INDEX_op_mul_i32;
+            op_new2 = INDEX_op_mulsh_i32;
+            have_op_new2 = TCG_TARGET_HAS_mulsh_i32;
             goto do_mul2;
         case INDEX_op_mulu2_i64:
+            op_new = INDEX_op_mul_i64;
+            op_new2 = INDEX_op_muluh_i64;
+            have_op_new2 = TCG_TARGET_HAS_muluh_i64;
+            goto do_mul2;
         case INDEX_op_muls2_i64:
             op_new = INDEX_op_mul_i64;
+            op_new2 = INDEX_op_mulsh_i64;
+            have_op_new2 = TCG_TARGET_HAS_mulsh_i64;
+            goto do_mul2;
         do_mul2:
             args -= 4;
             nb_iargs = 2;
             nb_oargs = 2;
-            /* Likewise, test for the high part of the operation dead.  */
             if (dead_temps[args[1]] && !mem_temps[args[1]]) {
                 if (dead_temps[args[0]] && !mem_temps[args[0]]) {
+                    /* Both parts of the operation are dead.  */
                     goto do_remove;
                 }
+                /* The high part of the operation is dead; generate the low. */
                 s->gen_opc_buf[op_index] = op = op_new;
                 args[1] = args[2];
                 args[2] = args[3];
-                assert(s->gen_opc_buf[op_index + 1] == INDEX_op_nop);
-                tcg_set_nop(s, s->gen_opc_buf + op_index + 1, args + 3, 1);
-                /* Fall through and mark the single-word operation live.  */
-                nb_oargs = 1;
+            } else if (have_op_new2 && dead_temps[args[0]]
+                       && !mem_temps[args[0]]) {
+                /* The low part of the operation is dead; generate the high.  */
+                s->gen_opc_buf[op_index] = op = op_new2;
+                args[0] = args[1];
+                args[1] = args[2];
+                args[2] = args[3];
+            } else {
+                goto do_not_remove;
             }
+            assert(s->gen_opc_buf[op_index + 1] == INDEX_op_nop);
+            tcg_set_nop(s, s->gen_opc_buf + op_index + 1, args + 3, 1);
+            /* Mark the single-word operation live.  */
+            nb_oargs = 1;
             goto do_not_remove;
 
         default:
diff --git a/tcg/tcg.h b/tcg/tcg.h
index f3f9889..3f869dd 100644
--- a/tcg/tcg.h
+++ b/tcg/tcg.h
@@ -85,6 +85,8 @@ typedef uint64_t TCGRegSet;
 #define TCG_TARGET_HAS_sub2_i64         0
 #define TCG_TARGET_HAS_mulu2_i64        0
 #define TCG_TARGET_HAS_muls2_i64        0
+#define TCG_TARGET_HAS_muluh_i64        0
+#define TCG_TARGET_HAS_mulsh_i64        0
 /* Turn some undef macros into true macros.  */
 #define TCG_TARGET_HAS_add2_i32         1
 #define TCG_TARGET_HAS_sub2_i32         1
diff --git a/tcg/tci/tcg-target.h b/tcg/tci/tcg-target.h
index d7fc14e..ff12b4b 100644
--- a/tcg/tci/tcg-target.h
+++ b/tcg/tci/tcg-target.h
@@ -76,6 +76,8 @@
 #define TCG_TARGET_HAS_rot_i32          1
 #define TCG_TARGET_HAS_movcond_i32      0
 #define TCG_TARGET_HAS_muls2_i32        0
+#define TCG_TARGET_HAS_muluh_i32        0
+#define TCG_TARGET_HAS_mulsh_i32        0
 
 #if TCG_TARGET_REG_BITS == 64
 #define TCG_TARGET_HAS_bswap16_i64      1
@@ -100,13 +102,14 @@
 #define TCG_TARGET_HAS_rot_i64          1
 #define TCG_TARGET_HAS_movcond_i64      0
 #define TCG_TARGET_HAS_muls2_i64        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_add2_i64         0
 #define TCG_TARGET_HAS_sub2_i64         0
 #define TCG_TARGET_HAS_mulu2_i64        0
+#define TCG_TARGET_HAS_muluh_i64        0
+#define TCG_TARGET_HAS_mulsh_i64        0
 #endif /* TCG_TARGET_REG_BITS == 64 */
 
 /* Number of registers available.
commit 31efd2e883018b4c079ad082105bc161fbb3fef8
Author: Marcel Apfelbaum <marcel.a at redhat.com>
Date:   Thu Aug 22 20:11:36 2013 +0300

    usb/dev-hid: Modified usb-tablet category from Misc to Input
    
    usb-tablet device was wrongly assigned to Misc category
    
    Reported-by: Markus Armbruster <armbru at redhat.com>
    Cc: qemu-stable at nongnu.org
    Signed-off-by: Marcel Apfelbaum <marcel.a at redhat.com>
    Reviewed-by: Andreas Färber <afaerber at suse.de>
    Signed-off-by: Gerd Hoffmann <kraxel at redhat.com>

diff --git a/hw/usb/dev-hid.c b/hw/usb/dev-hid.c
index 66c6331..5956720 100644
--- a/hw/usb/dev-hid.c
+++ b/hw/usb/dev-hid.c
@@ -658,7 +658,7 @@ static void usb_tablet_class_initfn(ObjectClass *klass, void *data)
     uc->product_desc   = "QEMU USB Tablet";
     dc->vmsd = &vmstate_usb_ptr;
     dc->props = usb_tablet_properties;
-    set_bit(DEVICE_CATEGORY_MISC, dc->categories);
+    set_bit(DEVICE_CATEGORY_INPUT, dc->categories);
 }
 
 static const TypeInfo usb_tablet_info = {
commit bdebd6ee81f4d849aa8541c289203e3992450db0
Author: Gerd Hoffmann <kraxel at redhat.com>
Date:   Tue Aug 27 17:00:04 2013 +0200

    Revert "usb-hub: report status changes only once"
    
    This reverts commit a309ee6e0a256f690760abfba44fceaa52a7c2f3.
    
    This isn't in line with the usb specification and adds regressions,
    win7 fails to drive the usb hub for example.
    
    Was added because it "solved" the issue of hubs interacting badly
    with the xhci host controller.  Now with the root cause being fixed
    in xhci (commit <FIXME>) we can revert this one.
    
    Cc: qemu-stable at nongnu.org
    Signed-off-by: Gerd Hoffmann <kraxel at redhat.com>

diff --git a/hw/usb/dev-hub.c b/hw/usb/dev-hub.c
index 54f63c0..58647b4 100644
--- a/hw/usb/dev-hub.c
+++ b/hw/usb/dev-hub.c
@@ -33,7 +33,6 @@ typedef struct USBHubPort {
     USBPort port;
     uint16_t wPortStatus;
     uint16_t wPortChange;
-    uint16_t wPortChange_reported;
 } USBHubPort;
 
 typedef struct USBHubState {
@@ -468,11 +467,8 @@ static void usb_hub_handle_data(USBDevice *dev, USBPacket *p)
             status = 0;
             for(i = 0; i < NUM_PORTS; i++) {
                 port = &s->ports[i];
-                if (port->wPortChange &&
-                    port->wPortChange_reported != port->wPortChange) {
+                if (port->wPortChange)
                     status |= (1 << (i + 1));
-                }
-                port->wPortChange_reported = port->wPortChange;
             }
             if (status != 0) {
                 trace_usb_hub_status_report(s->dev.addr, status);
commit b8cbc1374acdc1d8081f1dc57ef1249d263cf389
Author: Gerd Hoffmann <kraxel at redhat.com>
Date:   Tue Aug 27 16:59:37 2013 +0200

    usb-hub: add tracepoint for status reports
    
    Signed-off-by: Gerd Hoffmann <kraxel at redhat.com>

diff --git a/hw/usb/dev-hub.c b/hw/usb/dev-hub.c
index e865a98..54f63c0 100644
--- a/hw/usb/dev-hub.c
+++ b/hw/usb/dev-hub.c
@@ -475,6 +475,7 @@ static void usb_hub_handle_data(USBDevice *dev, USBPacket *p)
                 port->wPortChange_reported = port->wPortChange;
             }
             if (status != 0) {
+                trace_usb_hub_status_report(s->dev.addr, status);
                 for(i = 0; i < n; i++) {
                     buf[i] = status >> (8 * i);
                 }
diff --git a/trace-events b/trace-events
index f849807..754c28c 100644
--- a/trace-events
+++ b/trace-events
@@ -411,6 +411,7 @@ usb_hub_set_port_feature(int addr, int nr, const char *f) "dev %d, port %d, feat
 usb_hub_clear_port_feature(int addr, int nr, const char *f) "dev %d, port %d, feature %s"
 usb_hub_attach(int addr, int nr) "dev %d, port %d"
 usb_hub_detach(int addr, int nr) "dev %d, port %d"
+usb_hub_status_report(int addr, int status) "dev %d, status 0x%x"
 
 # hw/usb/dev-uas.c
 usb_uas_reset(int addr) "dev %d"
commit c96c41ed0d38d68a6c8b6f84751afebafeae31be
Author: Gerd Hoffmann <kraxel at redhat.com>
Date:   Tue Aug 27 15:25:24 2013 +0200

    usb: parallelize usb3 streams
    
    usb3 bulk endpoints with streams are implicitly pipelined now,
    so the requests will actually be processed in parallel.  Also
    allow them to complete out-of-order.
    
    Fixes stalls in the uas driver.
    
    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 05948ca..31960c2 100644
--- a/hw/usb/core.c
+++ b/hw/usb/core.c
@@ -403,7 +403,7 @@ void usb_handle_packet(USBDevice *dev, USBPacket *p)
         p->ep->halted = false;
     }
 
-    if (QTAILQ_EMPTY(&p->ep->queue) || p->ep->pipeline) {
+    if (QTAILQ_EMPTY(&p->ep->queue) || p->ep->pipeline || p->stream) {
         usb_process_one(p);
         if (p->status == USB_RET_ASYNC) {
             /* hcd drivers cannot handle async for isoc */
@@ -420,7 +420,8 @@ void usb_handle_packet(USBDevice *dev, USBPacket *p)
              * When pipelining is enabled usb-devices must always return async,
              * otherwise packets can complete out of order!
              */
-            assert(!p->ep->pipeline || QTAILQ_EMPTY(&p->ep->queue));
+            assert(p->stream || !p->ep->pipeline ||
+                   QTAILQ_EMPTY(&p->ep->queue));
             if (p->status != USB_RET_NAK) {
                 usb_packet_set_state(p, USB_PACKET_COMPLETE);
             }
@@ -434,7 +435,7 @@ void usb_packet_complete_one(USBDevice *dev, USBPacket *p)
 {
     USBEndpoint *ep = p->ep;
 
-    assert(QTAILQ_FIRST(&ep->queue) == p);
+    assert(p->stream || QTAILQ_FIRST(&ep->queue) == p);
     assert(p->status != USB_RET_ASYNC && p->status != USB_RET_NAK);
 
     if (p->status != USB_RET_SUCCESS ||
commit 1556a8fc38dbf4e950c50427192a3a37cdea3cba
Author: Gerd Hoffmann <kraxel at redhat.com>
Date:   Tue Aug 27 14:54:44 2013 +0200

    uas: add property for request logging
    
    Signed-off-by: Gerd Hoffmann <kraxel at redhat.com>

diff --git a/hw/usb/dev-uas.c b/hw/usb/dev-uas.c
index 63ad12e..8701292 100644
--- a/hw/usb/dev-uas.c
+++ b/hw/usb/dev-uas.c
@@ -113,6 +113,9 @@ struct UASDevice {
     QTAILQ_HEAD(, UASStatus)  results;
     QTAILQ_HEAD(, UASRequest) requests;
 
+    /* properties */
+    uint32_t                  requestlog;
+
     /* usb 2.0 only */
     USBPacket                 *status2;
     UASRequest                *datain2;
@@ -692,9 +695,9 @@ static void usb_uas_command(UASDevice *uas, uas_ui *ui)
     req->req = scsi_req_new(req->dev, req->tag,
                             usb_uas_get_lun(req->lun),
                             ui->command.cdb, req);
-#if 1
-    scsi_req_print(req->req);
-#endif
+    if (uas->requestlog) {
+        scsi_req_print(req->req);
+    }
     len = scsi_req_enqueue(req->req);
     if (len) {
         req->data_size = len;
@@ -902,6 +905,11 @@ static const VMStateDescription vmstate_usb_uas = {
     }
 };
 
+static Property uas_properties[] = {
+    DEFINE_PROP_UINT32("log-scsi-req", UASDevice, requestlog, 0),
+    DEFINE_PROP_END_OF_LIST(),
+};
+
 static void usb_uas_class_initfn(ObjectClass *klass, void *data)
 {
     DeviceClass *dc = DEVICE_CLASS(klass);
@@ -919,6 +927,7 @@ static void usb_uas_class_initfn(ObjectClass *klass, void *data)
     set_bit(DEVICE_CATEGORY_STORAGE, dc->categories);
     dc->fw_name = "storage";
     dc->vmsd = &vmstate_usb_uas;
+    dc->props = uas_properties;
 }
 
 static const TypeInfo uas_info = {
commit 5c67dd7b4884979a2613a4702ac1ab68b0e6a16e
Author: Gerd Hoffmann <kraxel at redhat.com>
Date:   Wed Aug 28 11:47:09 2013 +0200

    xhci: reset port when disabling slot
    
    Cc: qemu-stable at nongnu.org
    Signed-off-by: Gerd Hoffmann <kraxel at redhat.com>

diff --git a/hw/usb/hcd-xhci.c b/hw/usb/hcd-xhci.c
index 2e2eb55..10c938a 100644
--- a/hw/usb/hcd-xhci.c
+++ b/hw/usb/hcd-xhci.c
@@ -2123,6 +2123,7 @@ static TRBCCode xhci_disable_slot(XHCIState *xhci, unsigned int slotid)
 
     xhci->slots[slotid-1].enabled = 0;
     xhci->slots[slotid-1].addressed = 0;
+    xhci->slots[slotid-1].uport = NULL;
     return CC_SUCCESS;
 }
 
commit 4d7a81c06f5f17e019a2d3a18300500bd64f6f40
Author: Gerd Hoffmann <kraxel at redhat.com>
Date:   Wed Aug 28 11:38:44 2013 +0200

    xhci: emulate intr endpoint intervals correctly
    
    Respect the interval for interrupt endpoints, so we don't finish
    transfers as fast as possible but at the rate configured by the guest.
    
    Fixes guest deadlocks triggered by interrupt storms.
    
    Cc:
    Signed-off-by: Gerd Hoffmann <kraxel at redhat.com>

diff --git a/hw/usb/hcd-xhci.c b/hw/usb/hcd-xhci.c
index 3826979..2e2eb55 100644
--- a/hw/usb/hcd-xhci.c
+++ b/hw/usb/hcd-xhci.c
@@ -355,6 +355,7 @@ typedef struct XHCITransfer {
     unsigned int streamid;
     bool in_xfer;
     bool iso_xfer;
+    bool timed_xfer;
 
     unsigned int trb_count;
     unsigned int trb_alloced;
@@ -1820,6 +1821,7 @@ static int xhci_fire_ctl_transfer(XHCIState *xhci, XHCITransfer *xfer)
 
     xfer->in_xfer = bmRequestType & USB_DIR_IN;
     xfer->iso_xfer = false;
+    xfer->timed_xfer = false;
 
     if (xhci_setup_packet(xfer) < 0) {
         return -1;
@@ -1835,6 +1837,17 @@ static int xhci_fire_ctl_transfer(XHCIState *xhci, XHCITransfer *xfer)
     return 0;
 }
 
+static void xhci_calc_intr_kick(XHCIState *xhci, XHCITransfer *xfer,
+                                XHCIEPContext *epctx, uint64_t mfindex)
+{
+    uint64_t asap = ((mfindex + epctx->interval - 1) &
+                     ~(epctx->interval-1));
+    uint64_t kick = epctx->mfindex_last + epctx->interval;
+
+    assert(epctx->interval != 0);
+    xfer->mfindex_kick = MAX(asap, kick);
+}
+
 static void xhci_calc_iso_kick(XHCIState *xhci, XHCITransfer *xfer,
                                XHCIEPContext *epctx, uint64_t mfindex)
 {
@@ -1857,8 +1870,8 @@ static void xhci_calc_iso_kick(XHCIState *xhci, XHCITransfer *xfer,
     }
 }
 
-static void xhci_check_iso_kick(XHCIState *xhci, XHCITransfer *xfer,
-                                XHCIEPContext *epctx, uint64_t mfindex)
+static void xhci_check_intr_iso_kick(XHCIState *xhci, XHCITransfer *xfer,
+                                     XHCIEPContext *epctx, uint64_t mfindex)
 {
     if (xfer->mfindex_kick > mfindex) {
         timer_mod(epctx->kick_timer, qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL) +
@@ -1883,18 +1896,30 @@ static int xhci_submit(XHCIState *xhci, XHCITransfer *xfer, XHCIEPContext *epctx
     switch(epctx->type) {
     case ET_INTR_OUT:
     case ET_INTR_IN:
+        xfer->pkts = 0;
+        xfer->iso_xfer = false;
+        xfer->timed_xfer = true;
+        mfindex = xhci_mfindex_get(xhci);
+        xhci_calc_intr_kick(xhci, xfer, epctx, mfindex);
+        xhci_check_intr_iso_kick(xhci, xfer, epctx, mfindex);
+        if (xfer->running_retry) {
+            return -1;
+        }
+        break;
     case ET_BULK_OUT:
     case ET_BULK_IN:
         xfer->pkts = 0;
         xfer->iso_xfer = false;
+        xfer->timed_xfer = false;
         break;
     case ET_ISO_OUT:
     case ET_ISO_IN:
         xfer->pkts = 1;
         xfer->iso_xfer = true;
+        xfer->timed_xfer = true;
         mfindex = xhci_mfindex_get(xhci);
         xhci_calc_iso_kick(xhci, xfer, epctx, mfindex);
-        xhci_check_iso_kick(xhci, xfer, epctx, mfindex);
+        xhci_check_intr_iso_kick(xhci, xfer, epctx, mfindex);
         if (xfer->running_retry) {
             return -1;
         }
@@ -1955,13 +1980,18 @@ static void xhci_kick_ep(XHCIState *xhci, unsigned int slotid,
 
         trace_usb_xhci_xfer_retry(xfer);
         assert(xfer->running_retry);
-        if (xfer->iso_xfer) {
-            /* retry delayed iso transfer */
+        if (xfer->timed_xfer) {
+            /* time to kick the transfer? */
             mfindex = xhci_mfindex_get(xhci);
-            xhci_check_iso_kick(xhci, xfer, epctx, mfindex);
+            xhci_check_intr_iso_kick(xhci, xfer, epctx, mfindex);
             if (xfer->running_retry) {
                 return;
             }
+            xfer->timed_xfer = 0;
+            xfer->running_retry = 1;
+        }
+        if (xfer->iso_xfer) {
+            /* retry iso transfer */
             if (xhci_setup_packet(xfer) < 0) {
                 return;
             }
@@ -2047,7 +2077,7 @@ static void xhci_kick_ep(XHCIState *xhci, unsigned int slotid,
                 epctx->next_xfer = (epctx->next_xfer + 1) % TD_QUEUE;
                 ep = xfer->packet.ep;
             } else {
-                if (!xfer->iso_xfer) {
+                if (!xfer->timed_xfer) {
                     fprintf(stderr, "xhci: error firing data transfer\n");
                 }
             }
commit ca7162782a293f525633e5816470498dd86a51cf
Author: Gerd Hoffmann <kraxel at redhat.com>
Date:   Wed Aug 28 11:39:02 2013 +0200

    xhci: fix endpoint interval calculation
    
    Cc: qemu-stable at nongnu.org
    Signed-off-by: Gerd Hoffmann <kraxel at redhat.com>

diff --git a/hw/usb/hcd-xhci.c b/hw/usb/hcd-xhci.c
index 4d693bc..3826979 100644
--- a/hw/usb/hcd-xhci.c
+++ b/hw/usb/hcd-xhci.c
@@ -1274,7 +1274,7 @@ static void xhci_init_epctx(XHCIEPContext *epctx,
         epctx->ring.ccs = ctx[2] & 1;
     }
 
-    epctx->interval = 1 << (ctx[0] >> 16) & 0xff;
+    epctx->interval = 1 << ((ctx[0] >> 16) & 0xff);
 }
 
 static TRBCCode xhci_enable_ep(XHCIState *xhci, unsigned int slotid,
commit 65d81ed402d3b78b6ffbade36a09ea53e41614d2
Author: Gerd Hoffmann <kraxel at redhat.com>
Date:   Wed Aug 28 11:46:45 2013 +0200

    xhci: add port to slot_address tracepoint
    
    Signed-off-by: Gerd Hoffmann <kraxel at redhat.com>

diff --git a/hw/usb/hcd-xhci.c b/hw/usb/hcd-xhci.c
index 83161b9..4d693bc 100644
--- a/hw/usb/hcd-xhci.c
+++ b/hw/usb/hcd-xhci.c
@@ -2135,7 +2135,6 @@ static TRBCCode xhci_address_slot(XHCIState *xhci, unsigned int slotid,
     int i;
     TRBCCode res;
 
-    trace_usb_xhci_slot_address(slotid);
     assert(slotid >= 1 && slotid <= xhci->numslots);
 
     dcbaap = xhci_addr64(xhci->dcbaap_low, xhci->dcbaap_high);
@@ -2168,6 +2167,7 @@ static TRBCCode xhci_address_slot(XHCIState *xhci, unsigned int slotid,
         fprintf(stderr, "xhci: port not found\n");
         return CC_TRB_ERROR;
     }
+    trace_usb_xhci_slot_address(slotid, uport->path);
 
     dev = uport->dev;
     if (!dev) {
diff --git a/trace-events b/trace-events
index eb8eaef..f849807 100644
--- a/trace-events
+++ b/trace-events
@@ -371,7 +371,7 @@ usb_xhci_port_link(uint32_t port, uint32_t pls) "port %d, pls %d"
 usb_xhci_port_notify(uint32_t port, uint32_t pls) "port %d, bits %x"
 usb_xhci_slot_enable(uint32_t slotid) "slotid %d"
 usb_xhci_slot_disable(uint32_t slotid) "slotid %d"
-usb_xhci_slot_address(uint32_t slotid) "slotid %d"
+usb_xhci_slot_address(uint32_t slotid, const char *port) "slotid %d, port %s"
 usb_xhci_slot_configure(uint32_t slotid) "slotid %d"
 usb_xhci_slot_evaluate(uint32_t slotid) "slotid %d"
 usb_xhci_slot_reset(uint32_t slotid) "slotid %d"
commit 1c82392a158471355aa6d1922df2d1545bb16b95
Author: Gerd Hoffmann <kraxel at redhat.com>
Date:   Wed Apr 24 15:01:25 2013 +0200

    xhci: add tracepoint for endpoint state changes
    
    Signed-off-by: Gerd Hoffmann <kraxel at redhat.com>

diff --git a/hw/usb/hcd-xhci.c b/hw/usb/hcd-xhci.c
index 57c06e7..83161b9 100644
--- a/hw/usb/hcd-xhci.c
+++ b/hw/usb/hcd-xhci.c
@@ -586,6 +586,14 @@ static const char *TRBCCode_names[] = {
     [CC_SPLIT_TRANSACTION_ERROR]       = "CC_SPLIT_TRANSACTION_ERROR",
 };
 
+static const char *ep_state_names[] = {
+    [EP_DISABLED] = "disabled",
+    [EP_RUNNING]  = "running",
+    [EP_HALTED]   = "halted",
+    [EP_STOPPED]  = "stopped",
+    [EP_ERROR]    = "error",
+};
+
 static const char *lookup_name(uint32_t index, const char **list, uint32_t llen)
 {
     if (index >= llen || list[index] == NULL) {
@@ -606,6 +614,12 @@ static const char *event_name(XHCIEvent *event)
                        ARRAY_SIZE(TRBCCode_names));
 }
 
+static const char *ep_state_name(uint32_t state)
+{
+    return lookup_name(state, ep_state_names,
+                       ARRAY_SIZE(ep_state_names));
+}
+
 static uint64_t xhci_mfindex_get(XHCIState *xhci)
 {
     int64_t now = qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL);
@@ -1203,6 +1217,11 @@ static void xhci_set_ep_state(XHCIState *xhci, XHCIEPContext *epctx,
     }
 
     xhci_dma_write_u32s(xhci, epctx->pctx, ctx, sizeof(ctx));
+    if (epctx->state != state) {
+        trace_usb_xhci_ep_state(epctx->slotid, epctx->epid,
+                                ep_state_name(epctx->state),
+                                ep_state_name(state));
+    }
     epctx->state = state;
 }
 
diff --git a/trace-events b/trace-events
index 3856b5c..eb8eaef 100644
--- a/trace-events
+++ b/trace-events
@@ -381,6 +381,7 @@ usb_xhci_ep_set_dequeue(uint32_t slotid, uint32_t epid, uint32_t streamid, uint6
 usb_xhci_ep_kick(uint32_t slotid, uint32_t epid, uint32_t streamid) "slotid %d, epid %d, streamid %d"
 usb_xhci_ep_stop(uint32_t slotid, uint32_t epid) "slotid %d, epid %d"
 usb_xhci_ep_reset(uint32_t slotid, uint32_t epid) "slotid %d, epid %d"
+usb_xhci_ep_state(uint32_t slotid, uint32_t epid, const char *os, const char *ns) "slotid %d, epid %d, %s -> %s"
 usb_xhci_xfer_start(void *xfer, uint32_t slotid, uint32_t epid, uint32_t streamid) "%p: slotid %d, epid %d, streamid %d"
 usb_xhci_xfer_async(void *xfer) "%p"
 usb_xhci_xfer_nak(void *xfer) "%p"
commit 5219042274fa2f993c25202680eeaea42193389d
Author: Gerd Hoffmann <kraxel at redhat.com>
Date:   Tue Aug 27 14:47:15 2013 +0200

    xhci: remove leftover debug printf
    
    Signed-off-by: Gerd Hoffmann <kraxel at redhat.com>

diff --git a/hw/usb/hcd-xhci.c b/hw/usb/hcd-xhci.c
index be6b86e..57c06e7 100644
--- a/hw/usb/hcd-xhci.c
+++ b/hw/usb/hcd-xhci.c
@@ -1164,8 +1164,6 @@ static XHCIStreamContext *xhci_find_stream(XHCIEPContext *epctx,
 
     if (sctx->sct == -1) {
         xhci_dma_read_u32s(epctx->xhci, sctx->pctx, ctx, sizeof(ctx));
-        fprintf(stderr, "%s: init sctx #%d @ " DMA_ADDR_FMT ": %08x %08x\n",
-                __func__, streamid, sctx->pctx, ctx[0], ctx[1]);
         sct = (ctx[0] >> 1) & 0x07;
         if (epctx->lsa && sct != 1) {
             *cc_error = CC_INVALID_STREAM_TYPE_ERROR;
commit ca0eca91b65c34d6e5f5c77d5c18ed3de5b26139
Author: Max Reitz <mreitz at redhat.com>
Date:   Fri Aug 30 14:34:31 2013 +0200

    qemu-iotests: Overlapping cluster allocations
    
    A new test on corrupted images with overlapping cluster allocations.
    
    Signed-off-by: Max Reitz <mreitz at redhat.com>
    Signed-off-by: Kevin Wolf <kwolf at redhat.com>

diff --git a/tests/qemu-iotests/060 b/tests/qemu-iotests/060
new file mode 100755
index 0000000..65bb09f
--- /dev/null
+++ b/tests/qemu-iotests/060
@@ -0,0 +1,111 @@
+#!/bin/bash
+#
+# Test case for image corruption (overlapping data structures) in qcow2
+#
+# 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=mreitz 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
+
+# This tests qocw2-specific low-level functionality
+_supported_fmt qcow2
+_supported_proto generic
+_supported_os Linux
+
+rt_offset=65536  # 0x10000 (XXX: just an assumption)
+rb_offset=131072 # 0x20000 (XXX: just an assumption)
+l1_offset=196608 # 0x30000 (XXX: just an assumption)
+l2_offset=262144 # 0x40000 (XXX: just an assumption)
+
+IMGOPTS="compat=1.1"
+
+echo
+echo "=== Testing L2 reference into L1 ==="
+echo
+_make_test_img 64M
+# Link first L1 entry (first L2 table) onto itself
+# (Note the MSb in the L1 entry is set, ensuring the refcount is one - else any
+# later write will result in a COW operation, effectively ruining this attempt
+# on image corruption)
+poke_file "$TEST_IMG" "$l1_offset" "\x80\x00\x00\x00\x00\x03\x00\x00"
+_check_test_img
+
+# The corrupt bit should not be set anyway
+./qcow2.py "$TEST_IMG" dump-header | grep incompatible_features
+
+# Try to write something, thereby forcing the corrupt bit to be set
+$QEMU_IO -c "write -P 0x2a 0 512" "$TEST_IMG" | _filter_qemu_io
+
+# The corrupt bit must now be set
+./qcow2.py "$TEST_IMG" dump-header | grep incompatible_features
+
+# Try to open the image R/W (which should fail)
+$QEMU_IO -c "read 0 512" "$TEST_IMG" 2>&1 | _filter_qemu_io | sed -e "s/can't open device .*$/can't open device/"
+
+# Try to open it RO (which should succeed)
+$QEMU_IO -c "read 0 512" -r "$TEST_IMG" | _filter_qemu_io
+
+# We could now try to fix the image, but this would probably fail (how should an
+# L2 table linked onto the L1 table be fixed?)
+
+echo
+echo "=== Testing cluster data reference into refcount block ==="
+echo
+_make_test_img 64M
+# Allocate L2 table
+truncate -s "$(($l2_offset+65536))" "$TEST_IMG"
+poke_file "$TEST_IMG" "$l1_offset" "\x80\x00\x00\x00\x00\x04\x00\x00"
+# Mark cluster as used
+poke_file "$TEST_IMG" "$(($rb_offset+8))" "\x00\x01"
+# Redirect new data cluster onto refcount block
+poke_file "$TEST_IMG" "$l2_offset" "\x80\x00\x00\x00\x00\x02\x00\x00"
+_check_test_img
+./qcow2.py "$TEST_IMG" dump-header | grep incompatible_features
+$QEMU_IO -c "write -P 0x2a 0 512" "$TEST_IMG" | _filter_qemu_io
+./qcow2.py "$TEST_IMG" dump-header | grep incompatible_features
+
+# Try to fix it
+_check_test_img -r all
+
+# The corrupt bit should be cleared
+./qcow2.py "$TEST_IMG" dump-header | grep incompatible_features
+
+# Look if it's really really fixed
+$QEMU_IO -c "write -P 0x2a 0 512" "$TEST_IMG" | _filter_qemu_io
+./qcow2.py "$TEST_IMG" dump-header | grep incompatible_features
+
+# success, all done
+echo "*** done"
+rm -f $seq.full
+status=0
diff --git a/tests/qemu-iotests/060.out b/tests/qemu-iotests/060.out
new file mode 100644
index 0000000..ca4583a
--- /dev/null
+++ b/tests/qemu-iotests/060.out
@@ -0,0 +1,44 @@
+QA output created by 060
+
+=== Testing L2 reference into L1 ===
+
+Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=67108864 
+ERROR cluster 3 refcount=1 reference=3
+
+1 errors were found on the image.
+Data may be corrupted, or further writes to the image may corrupt it.
+incompatible_features     0x0
+qcow2: Preventing invalid write on metadata (overlaps with active L1 table); image marked as corrupt.
+write failed: Input/output error
+incompatible_features     0x2
+qcow2: Image is corrupt; cannot be opened read/write.
+qemu-io: can't open device
+no file open, try 'help open'
+read 512/512 bytes at offset 0
+512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+
+=== Testing cluster data reference into refcount block ===
+
+Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=67108864 
+ERROR refcount block 0 refcount=2
+ERROR cluster 2 refcount=1 reference=2
+
+2 errors were found on the image.
+Data may be corrupted, or further writes to the image may corrupt it.
+incompatible_features     0x0
+qcow2: Preventing invalid write on metadata (overlaps with refcount block); image marked as corrupt.
+write failed: Input/output error
+incompatible_features     0x2
+Repairing refcount block 0 refcount=2
+The following inconsistencies were found and repaired:
+
+    0 leaked clusters
+    1 corruptions
+
+Double checking the fixed image now...
+No errors were found on the image.
+incompatible_features     0x0
+wrote 512/512 bytes at offset 0
+512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+incompatible_features     0x0
+*** done
diff --git a/tests/qemu-iotests/group b/tests/qemu-iotests/group
index fb13792..b696242 100644
--- a/tests/qemu-iotests/group
+++ b/tests/qemu-iotests/group
@@ -64,4 +64,5 @@
 055 rw auto
 056 rw auto backing
 059 rw auto
+060 rw auto
 062 rw auto
commit 24530f3e060c71b6c57c7a70336f08a13a8b0a3d
Author: Max Reitz <mreitz at redhat.com>
Date:   Fri Aug 30 14:34:30 2013 +0200

    qcow2_check: Mark image consistent
    
    If no corruptions remain after an image repair (and no errors have been
    encountered), clear the corrupt flag in qcow2_check.
    
    Signed-off-by: Max Reitz <mreitz at redhat.com>
    Signed-off-by: Kevin Wolf <kwolf at redhat.com>

diff --git a/block/qcow2.c b/block/qcow2.c
index 05e002d..4bc679a 100644
--- a/block/qcow2.c
+++ b/block/qcow2.c
@@ -312,7 +312,11 @@ static int qcow2_check(BlockDriverState *bs, BdrvCheckResult *result,
     }
 
     if (fix && result->check_errors == 0 && result->corruptions == 0) {
-        return qcow2_mark_clean(bs);
+        ret = qcow2_mark_clean(bs);
+        if (ret < 0) {
+            return ret;
+        }
+        return qcow2_mark_consistent(bs);
     }
     return ret;
 }
commit afa50193cde574528a130a25544fd6f3aa8da069
Author: Max Reitz <mreitz at redhat.com>
Date:   Mon Sep 2 09:25:10 2013 +0200

    qcow2-refcount: Repair shared refcount blocks
    
    If the refcount of a refcount block is greater than one, we can at least
    try to repair that problem by duplicating the affected block.
    
    Signed-off-by: Max Reitz <mreitz at redhat.com>
    Signed-off-by: Kevin Wolf <kwolf at redhat.com>

diff --git a/block/blkdebug.c b/block/blkdebug.c
index ccb627a..5d33e03 100644
--- a/block/blkdebug.c
+++ b/block/blkdebug.c
@@ -168,6 +168,7 @@ static const char *event_names[BLKDBG_EVENT_MAX] = {
 
     [BLKDBG_REFTABLE_LOAD]                  = "reftable_load",
     [BLKDBG_REFTABLE_GROW]                  = "reftable_grow",
+    [BLKDBG_REFTABLE_UPDATE]                = "reftable_update",
 
     [BLKDBG_REFBLOCK_LOAD]                  = "refblock_load",
     [BLKDBG_REFBLOCK_UPDATE]                = "refblock_update",
diff --git a/block/qcow2-refcount.c b/block/qcow2-refcount.c
index 2276b6f..ba129de 100644
--- a/block/qcow2-refcount.c
+++ b/block/qcow2-refcount.c
@@ -1338,6 +1338,121 @@ fail:
 }
 
 /*
+ * Writes one sector of the refcount table to the disk
+ */
+#define RT_ENTRIES_PER_SECTOR (512 / sizeof(uint64_t))
+static int write_reftable_entry(BlockDriverState *bs, int rt_index)
+{
+    BDRVQcowState *s = bs->opaque;
+    uint64_t buf[RT_ENTRIES_PER_SECTOR];
+    int rt_start_index;
+    int i, ret;
+
+    rt_start_index = rt_index & ~(RT_ENTRIES_PER_SECTOR - 1);
+    for (i = 0; i < RT_ENTRIES_PER_SECTOR; i++) {
+        buf[i] = cpu_to_be64(s->refcount_table[rt_start_index + i]);
+    }
+
+    ret = qcow2_pre_write_overlap_check(bs,
+            QCOW2_OL_DEFAULT & ~QCOW2_OL_REFCOUNT_TABLE,
+            s->refcount_table_offset + rt_start_index * sizeof(uint64_t),
+            sizeof(buf));
+    if (ret < 0) {
+        return ret;
+    }
+
+    BLKDBG_EVENT(bs->file, BLKDBG_REFTABLE_UPDATE);
+    ret = bdrv_pwrite_sync(bs->file, s->refcount_table_offset +
+            rt_start_index * sizeof(uint64_t), buf, sizeof(buf));
+    if (ret < 0) {
+        return ret;
+    }
+
+    return 0;
+}
+
+/*
+ * Allocates a new cluster for the given refcount block (represented by its
+ * offset in the image file) and copies the current content there. This function
+ * does _not_ decrement the reference count for the currently occupied cluster.
+ *
+ * This function prints an informative message to stderr on error (and returns
+ * -errno); on success, 0 is returned.
+ */
+static int64_t realloc_refcount_block(BlockDriverState *bs, int reftable_index,
+                                      uint64_t offset)
+{
+    BDRVQcowState *s = bs->opaque;
+    int64_t new_offset = 0;
+    void *refcount_block = NULL;
+    int ret;
+
+    /* allocate new refcount block */
+    new_offset = qcow2_alloc_clusters(bs, s->cluster_size);
+    if (new_offset < 0) {
+        fprintf(stderr, "Could not allocate new cluster: %s\n",
+                strerror(-new_offset));
+        ret = new_offset;
+        goto fail;
+    }
+
+    /* fetch current refcount block content */
+    ret = qcow2_cache_get(bs, s->refcount_block_cache, offset, &refcount_block);
+    if (ret < 0) {
+        fprintf(stderr, "Could not fetch refcount block: %s\n", strerror(-ret));
+        goto fail;
+    }
+
+    /* new block has not yet been entered into refcount table, therefore it is
+     * no refcount block yet (regarding this check) */
+    ret = qcow2_pre_write_overlap_check(bs, QCOW2_OL_DEFAULT, new_offset,
+            s->cluster_size);
+    if (ret < 0) {
+        fprintf(stderr, "Could not write refcount block; metadata overlap "
+                "check failed: %s\n", strerror(-ret));
+        /* the image will be marked corrupt, so don't even attempt on freeing
+         * the cluster */
+        new_offset = 0;
+        goto fail;
+    }
+
+    /* write to new block */
+    ret = bdrv_write(bs->file, new_offset / BDRV_SECTOR_SIZE, refcount_block,
+            s->cluster_sectors);
+    if (ret < 0) {
+        fprintf(stderr, "Could not write refcount block: %s\n", strerror(-ret));
+        goto fail;
+    }
+
+    /* update refcount table */
+    assert(!(new_offset & (s->cluster_size - 1)));
+    s->refcount_table[reftable_index] = new_offset;
+    ret = write_reftable_entry(bs, reftable_index);
+    if (ret < 0) {
+        fprintf(stderr, "Could not update refcount table: %s\n",
+                strerror(-ret));
+        goto fail;
+    }
+
+fail:
+    if (new_offset && (ret < 0)) {
+        qcow2_free_clusters(bs, new_offset, s->cluster_size,
+                QCOW2_DISCARD_ALWAYS);
+    }
+    if (refcount_block) {
+        if (ret < 0) {
+            qcow2_cache_put(bs, s->refcount_block_cache, &refcount_block);
+        } else {
+            ret = qcow2_cache_put(bs, s->refcount_block_cache, &refcount_block);
+        }
+    }
+    if (ret < 0) {
+        return ret;
+    }
+    return new_offset;
+}
+
+/*
  * Checks an image for refcount consistency.
  *
  * Returns 0 if no errors are found, the number of errors in case the image is
@@ -1413,10 +1528,39 @@ int qcow2_check_refcounts(BlockDriverState *bs, BdrvCheckResult *res,
             inc_refcounts(bs, res, refcount_table, nb_clusters,
                 offset, s->cluster_size);
             if (refcount_table[cluster] != 1) {
-                fprintf(stderr, "ERROR refcount block %" PRId64
+                fprintf(stderr, "%s refcount block %" PRId64
                     " refcount=%d\n",
+                    fix & BDRV_FIX_ERRORS ? "Repairing" :
+                                            "ERROR",
                     i, refcount_table[cluster]);
-                res->corruptions++;
+
+                if (fix & BDRV_FIX_ERRORS) {
+                    int64_t new_offset;
+
+                    new_offset = realloc_refcount_block(bs, i, offset);
+                    if (new_offset < 0) {
+                        res->corruptions++;
+                        continue;
+                    }
+
+                    /* update refcounts */
+                    if ((new_offset >> s->cluster_bits) >= nb_clusters) {
+                        /* increase refcount_table size if necessary */
+                        int old_nb_clusters = nb_clusters;
+                        nb_clusters = (new_offset >> s->cluster_bits) + 1;
+                        refcount_table = g_realloc(refcount_table,
+                                nb_clusters * sizeof(uint16_t));
+                        memset(&refcount_table[old_nb_clusters], 0, (nb_clusters
+                                - old_nb_clusters) * sizeof(uint16_t));
+                    }
+                    refcount_table[cluster]--;
+                    inc_refcounts(bs, res, refcount_table, nb_clusters,
+                            new_offset, s->cluster_size);
+
+                    res->corruptions_fixed++;
+                } else {
+                    res->corruptions++;
+                }
             }
         }
     }
diff --git a/include/block/block.h b/include/block/block.h
index 742fce5..e6b391c 100644
--- a/include/block/block.h
+++ b/include/block/block.h
@@ -413,6 +413,7 @@ typedef enum {
 
     BLKDBG_REFTABLE_LOAD,
     BLKDBG_REFTABLE_GROW,
+    BLKDBG_REFTABLE_UPDATE,
 
     BLKDBG_REFBLOCK_LOAD,
     BLKDBG_REFBLOCK_UPDATE,
commit 7e472264e9e2727bc7d08fe6f012db76e1c1a193
Author: Alexey Kardashevskiy <aik at ozlabs.ru>
Date:   Thu Aug 29 18:05:00 2013 +1000

    PPC: spapr: iommu: rework traces
    
    This converts old style fprintf to traces.
    
    Signed-off-by: Alexey Kardashevskiy <aik at ozlabs.ru>
    [agraf: change patch subject]
    Signed-off-by: Alexander Graf <agraf at suse.de>

diff --git a/hw/ppc/spapr_iommu.c b/hw/ppc/spapr_iommu.c
index 3d4a1fc..ef45f4f 100644
--- a/hw/ppc/spapr_iommu.c
+++ b/hw/ppc/spapr_iommu.c
@@ -22,13 +22,12 @@
 #include "kvm_ppc.h"
 #include "sysemu/dma.h"
 #include "exec/address-spaces.h"
+#include "trace.h"
 
 #include "hw/ppc/spapr.h"
 
 #include <libfdt.h>
 
-/* #define DEBUG_TCE */
-
 enum sPAPRTCEAccess {
     SPAPR_TCE_FAULT = 0,
     SPAPR_TCE_RO = 1,
@@ -61,44 +60,28 @@ static IOMMUTLBEntry spapr_tce_translate_iommu(MemoryRegion *iommu, hwaddr addr)
 {
     sPAPRTCETable *tcet = container_of(iommu, sPAPRTCETable, iommu);
     uint64_t tce;
-
-#ifdef DEBUG_TCE
-    fprintf(stderr, "spapr_tce_translate liobn=0x%" PRIx32 " addr=0x"
-            DMA_ADDR_FMT "\n", tcet->liobn, addr);
-#endif
+    IOMMUTLBEntry ret = {
+        .target_as = &address_space_memory,
+        .iova = 0,
+        .translated_addr = 0,
+        .addr_mask = ~(hwaddr)0,
+        .perm = IOMMU_NONE,
+    };
 
     if (tcet->bypass) {
-        return (IOMMUTLBEntry) {
-            .target_as = &address_space_memory,
-            .iova = 0,
-            .translated_addr = 0,
-            .addr_mask = ~(hwaddr)0,
-            .perm = IOMMU_RW,
-        };
-    }
-
-    /* Check if we are in bound */
-    if (addr >= tcet->window_size) {
-#ifdef DEBUG_TCE
-        fprintf(stderr, "spapr_tce_translate out of bounds\n");
-#endif
-        return (IOMMUTLBEntry) { .perm = IOMMU_NONE };
+        ret.perm = IOMMU_RW;
+    } else if (addr < tcet->window_size) {
+        /* Check if we are in bound */
+        tce = tcet->table[addr >> SPAPR_TCE_PAGE_SHIFT];
+        ret.iova = addr & ~SPAPR_TCE_PAGE_MASK;
+        ret.translated_addr = tce & ~SPAPR_TCE_PAGE_MASK;
+        ret.addr_mask = SPAPR_TCE_PAGE_MASK;
+        ret.perm = tce;
     }
+    trace_spapr_iommu_xlate(tcet->liobn, addr, ret.iova, ret.perm,
+                            ret.addr_mask);
 
-    tce = tcet->table[addr >> SPAPR_TCE_PAGE_SHIFT];
-
-#ifdef DEBUG_TCE
-    fprintf(stderr, " ->  *paddr=0x%llx, *len=0x%llx\n",
-            (tce & ~SPAPR_TCE_PAGE_MASK), SPAPR_TCE_PAGE_MASK + 1);
-#endif
-
-    return (IOMMUTLBEntry) {
-        .target_as = &address_space_memory,
-        .iova = addr & ~SPAPR_TCE_PAGE_MASK,
-        .translated_addr = tce & ~SPAPR_TCE_PAGE_MASK,
-        .addr_mask = SPAPR_TCE_PAGE_MASK,
-        .perm = tce,
-    };
+    return ret;
 }
 
 static int spapr_tce_table_pre_load(void *opaque)
@@ -150,10 +133,7 @@ static int spapr_tce_table_realize(DeviceState *dev)
     }
     tcet->nb_table = tcet->window_size >> SPAPR_TCE_PAGE_SHIFT;
 
-#ifdef DEBUG_TCE
-    fprintf(stderr, "spapr_iommu: New TCE table @ %p, liobn=0x%x, "
-            "table @ %p, fd=%d\n", tcet, liobn, tcet->table, tcet->fd);
-#endif
+    trace_spapr_iommu_new_table(tcet->liobn, tcet, tcet->table, tcet->fd);
 
     memory_region_init_iommu(&tcet->iommu, OBJECT(dev), &spapr_iommu_ops,
                              "iommu-spapr", UINT64_MAX);
@@ -250,20 +230,17 @@ static target_ulong h_put_tce(PowerPCCPU *cpu, sPAPREnvironment *spapr,
     target_ulong liobn = args[0];
     target_ulong ioba = args[1];
     target_ulong tce = args[2];
+    target_ulong ret = H_PARAMETER;
     sPAPRTCETable *tcet = spapr_tce_find_by_liobn(liobn);
 
     ioba &= ~(SPAPR_TCE_PAGE_SIZE - 1);
 
     if (tcet) {
-        return put_tce_emu(tcet, ioba, tce);
+        ret = put_tce_emu(tcet, ioba, tce);
     }
-#ifdef DEBUG_TCE
-    fprintf(stderr, "%s on liobn=" TARGET_FMT_lx /*%s*/
-            "  ioba 0x" TARGET_FMT_lx "  TCE 0x" TARGET_FMT_lx "\n",
-            __func__, liobn, /*dev->qdev.id, */ioba, tce);
-#endif
+    trace_spapr_iommu_put(liobn, ioba, tce, ret);
 
-    return H_PARAMETER;
+    return ret;
 }
 
 int spapr_dma_dt(void *fdt, int node_off, const char *propname,
diff --git a/trace-events b/trace-events
index 3856b5c..aaad356 100644
--- a/trace-events
+++ b/trace-events
@@ -1133,6 +1133,11 @@ xics_ics_write_xive(int nr, int srcno, int server, uint8_t priority) "ics_write_
 xics_ics_reject(int nr, int srcno) "reject irq %#x [src %d]"
 xics_ics_eoi(int nr) "ics_eoi: irq %#x"
 
+# hw/ppc/spapr_iommu.c
+spapr_iommu_put(uint64_t liobn, uint64_t ioba, uint64_t tce, uint64_t ret) "liobn=%"PRIx64" ioba=0x%"PRIx64" tce=0x%"PRIx64" ret=%"PRId64
+spapr_iommu_xlate(uint64_t liobn, uint64_t ioba, uint64_t tce, unsigned perm, unsigned pgsize) "liobn=%"PRIx64" 0x%"PRIx64" -> 0x%"PRIx64" perm=%u mask=%x"
+spapr_iommu_new_table(uint64_t liobn, void *tcet, void *table, int fd) "liobn=%"PRIx64" tcet=%p table=%p fd=%d"
+
 # util/hbitmap.c
 hbitmap_iter_skip_words(const void *hb, void *hbi, uint64_t pos, unsigned long cur) "hb %p hbi %p pos %"PRId64" cur 0x%lx"
 hbitmap_reset(void *hb, uint64_t start, uint64_t count, uint64_t sbit, uint64_t ebit) "hb %p items %"PRIu64",%"PRIu64" bits %"PRIu64"..%"PRIu64
commit 59760f2dba6b5729bbbef113c0dc142bf9ec94d3
Author: Alexey Kardashevskiy <aik at ozlabs.ru>
Date:   Fri Aug 30 16:11:56 2013 +1000

    spapr: add "stop-self" RTAS call required to support hot CPU unplug
    
    PAPR+ requires two RTAS calls to be supported by the hypervisor in
    order to allow hotplugging VCPUs from the guest. The "start-cpu" RTAS
    call was already there but "stop-self" was not.
    
    This adds the "stop-self" RTAS call.
    
    Signed-off-by: Alexey Kardashevskiy <aik at ozlabs.ru>
    Signed-off-by: Alexander Graf <agraf at suse.de>

diff --git a/hw/ppc/spapr_rtas.c b/hw/ppc/spapr_rtas.c
index 394ce05..eb542f2 100644
--- a/hw/ppc/spapr_rtas.c
+++ b/hw/ppc/spapr_rtas.c
@@ -202,6 +202,28 @@ static void rtas_start_cpu(PowerPCCPU *cpu_, sPAPREnvironment *spapr,
     rtas_st(rets, 0, -3);
 }
 
+static void rtas_stop_self(PowerPCCPU *cpu, sPAPREnvironment *spapr,
+                           uint32_t token, uint32_t nargs,
+                           target_ulong args,
+                           uint32_t nret, target_ulong rets)
+{
+    CPUState *cs = CPU(cpu);
+    CPUPPCState *env = &cpu->env;
+
+    cs->halted = 1;
+    cpu_exit(cs);
+    /*
+     * While stopping a CPU, the guest calls H_CPPR which
+     * effectively disables interrupts on XICS level.
+     * However decrementer interrupts in TCG can still
+     * wake the CPU up so here we disable interrupts in MSR
+     * as well.
+     * As rtas_start_cpu() resets the whole MSR anyway, there is
+     * no need to bother with specific bits, we just clear it.
+     */
+    env->msr = 0;
+}
+
 static struct rtas_call {
     const char *name;
     spapr_rtas_fn fn;
@@ -322,6 +344,7 @@ static void core_rtas_register_types(void)
     spapr_rtas_register("query-cpu-stopped-state",
                         rtas_query_cpu_stopped_state);
     spapr_rtas_register("start-cpu", rtas_start_cpu);
+    spapr_rtas_register("stop-self", rtas_stop_self);
 }
 
 type_init(core_rtas_register_types)
commit 7bb438b6a102766ac58e1a2981f8749e4515aa01
Author: Alexander Graf <agraf at suse.de>
Date:   Thu Aug 29 02:00:16 2013 +0200

    PPC: KVM: Compile fix for qemu_notify_event
    
    The function qemu_notify_event is defined by a header that we don't
    include in the PPC KVM code. Include it to get the code building
    again.
    
      target-ppc/kvm_ppc.c: In function 'kvmppc_timer_hack':
      target-ppc/kvm_ppc.c:26:5: error: implicit declaration of function 'qemu_notify_event' [-Werror=implicit-function-declaration]
      target-ppc/kvm_ppc.c:26:5: error: nested extern declaration of 'qemu_notify_event' [-Werror=nested-externs]
    
    Signed-off-by: Alexander Graf <agraf at suse.de>

diff --git a/target-ppc/kvm_ppc.c b/target-ppc/kvm_ppc.c
index 9b83655..f769acd 100644
--- a/target-ppc/kvm_ppc.c
+++ b/target-ppc/kvm_ppc.c
@@ -15,6 +15,7 @@
 #include "qemu/timer.h"
 #include "kvm_ppc.h"
 #include "sysemu/device_tree.h"
+#include "qemu/main-loop.h"
 
 #define PROC_DEVTREE_PATH "/proc/device-tree"
 
commit 42561bf2e464a2d682707af1640fc2db1e937c42
Author: Anton Blanchard <anton at samba.org>
Date:   Mon Aug 19 21:04:20 2013 +1000

    pseries: Add H_SET_MODE hcall to change guest exception endianness
    
    H_SET_MODE is used for controlling various partition settings. One
    of these settings is the endianness a guest takes its exceptions in.
    
    Signed-off-by: Anton Blanchard <anton at samba.org>
    [agraf: fix whitespace]
    Signed-off-by: Alexander Graf <agraf at suse.de>

diff --git a/hw/ppc/spapr.c b/hw/ppc/spapr.c
index 1ce9b0b..04f0ee3 100644
--- a/hw/ppc/spapr.c
+++ b/hw/ppc/spapr.c
@@ -282,7 +282,7 @@ static void *spapr_create_fdt_skel(const char *cpu_model,
     uint32_t start_prop = cpu_to_be32(initrd_base);
     uint32_t end_prop = cpu_to_be32(initrd_base + initrd_size);
     char hypertas_prop[] = "hcall-pft\0hcall-term\0hcall-dabr\0hcall-interrupt"
-        "\0hcall-tce\0hcall-vio\0hcall-splpar\0hcall-bulk";
+        "\0hcall-tce\0hcall-vio\0hcall-splpar\0hcall-bulk\0hcall-set-mode";
     char qemu_hypertas_prop[] = "hcall-memop1";
     uint32_t refpoints[] = {cpu_to_be32(0x4), cpu_to_be32(0x4)};
     uint32_t interrupt_server_ranges_prop[] = {0, cpu_to_be32(smp_cpus)};
diff --git a/hw/ppc/spapr_hcall.c b/hw/ppc/spapr_hcall.c
index 67d6cd9..89e6a00 100644
--- a/hw/ppc/spapr_hcall.c
+++ b/hw/ppc/spapr_hcall.c
@@ -657,6 +657,54 @@ static target_ulong h_logical_dcbf(PowerPCCPU *cpu, sPAPREnvironment *spapr,
     return H_SUCCESS;
 }
 
+static target_ulong h_set_mode(PowerPCCPU *cpu, sPAPREnvironment *spapr,
+                               target_ulong opcode, target_ulong *args)
+{
+    CPUState *cs;
+    target_ulong mflags = args[0];
+    target_ulong resource = args[1];
+    target_ulong value1 = args[2];
+    target_ulong value2 = args[3];
+    target_ulong ret = H_P2;
+
+    if (resource == H_SET_MODE_ENDIAN) {
+        if (value1) {
+            ret = H_P3;
+            goto out;
+        }
+        if (value2) {
+            ret = H_P4;
+            goto out;
+        }
+
+        switch (mflags) {
+        case H_SET_MODE_ENDIAN_BIG:
+            for (cs = first_cpu; cs != NULL; cs = cs->next_cpu) {
+                PowerPCCPU *cp = POWERPC_CPU(cs);
+                CPUPPCState *env = &cp->env;
+                env->spr[SPR_LPCR] &= ~LPCR_ILE;
+            }
+            ret = H_SUCCESS;
+            break;
+
+        case H_SET_MODE_ENDIAN_LITTLE:
+            for (cs = first_cpu; cs != NULL; cs = cs->next_cpu) {
+                PowerPCCPU *cp = POWERPC_CPU(cs);
+                CPUPPCState *env = &cp->env;
+                env->spr[SPR_LPCR] |= LPCR_ILE;
+            }
+            ret = H_SUCCESS;
+            break;
+
+        default:
+            ret = H_UNSUPPORTED_FLAG;
+        }
+    }
+
+out:
+    return ret;
+}
+
 static spapr_hcall_fn papr_hypercall_table[(MAX_HCALL_OPCODE / 4) + 1];
 static spapr_hcall_fn kvmppc_hypercall_table[KVMPPC_HCALL_MAX - KVMPPC_HCALL_BASE + 1];
 
@@ -734,6 +782,8 @@ static void hypercall_register_types(void)
 
     /* qemu/KVM-PPC specific hcalls */
     spapr_register_hypercall(KVMPPC_H_RTAS, h_rtas);
+
+    spapr_register_hypercall(H_SET_MODE, h_set_mode);
 }
 
 type_init(hypercall_register_types)
diff --git a/include/hw/ppc/spapr.h b/include/hw/ppc/spapr.h
index 41b0466..e37b419 100644
--- a/include/hw/ppc/spapr.h
+++ b/include/hw/ppc/spapr.h
@@ -111,6 +111,15 @@ typedef struct sPAPREnvironment {
 #define H_NOT_ENOUGH_RESOURCES -44
 #define H_R_STATE         -45
 #define H_RESCINDEND      -46
+#define H_P2              -55
+#define H_P3              -56
+#define H_P4              -57
+#define H_P5              -58
+#define H_P6              -59
+#define H_P7              -60
+#define H_P8              -61
+#define H_P9              -62
+#define H_UNSUPPORTED_FLAG -256
 #define H_MULTI_THREADS_ACTIVE -9005
 
 
@@ -145,6 +154,11 @@ typedef struct sPAPREnvironment {
 #define H_PP1             (1ULL<<(63-62))
 #define H_PP2             (1ULL<<(63-63))
 
+/* H_SET_MODE flags */
+#define H_SET_MODE_ENDIAN        4
+#define H_SET_MODE_ENDIAN_BIG    0
+#define H_SET_MODE_ENDIAN_LITTLE 1
+
 /* VASI States */
 #define H_VASI_INVALID    0
 #define H_VASI_ENABLED    1
@@ -269,7 +283,8 @@ typedef struct sPAPREnvironment {
 #define H_GET_EM_PARMS          0x2B8
 #define H_SET_MPP               0x2D0
 #define H_GET_MPP               0x2D4
-#define MAX_HCALL_OPCODE        H_GET_MPP
+#define H_SET_MODE              0x31C
+#define MAX_HCALL_OPCODE        H_SET_MODE
 
 /* The hcalls above are standardized in PAPR and implemented by pHyp
  * as well.
commit 33a0e5d8c555091eef6944595d8787cb9274e451
Author: Alexey Kardashevskiy <aik at ozlabs.ru>
Date:   Mon Aug 19 15:55:21 2013 +1000

    xics: move registration of global state to realize()
    
    Registration of global state belongs into realize so move it there.
    
    Signed-off-by: Alexey Kardashevskiy <aik at ozlabs.ru>
    Reviewed-by: Andreas Färber <afaerber at suse.de>
    Signed-off-by: Alexander Graf <agraf at suse.de>

diff --git a/hw/intc/xics.c b/hw/intc/xics.c
index 6b3c071..31868c4 100644
--- a/hw/intc/xics.c
+++ b/hw/intc/xics.c
@@ -642,6 +642,17 @@ static void xics_realize(DeviceState *dev, Error **errp)
     ICSState *ics = icp->ics;
     int i;
 
+    /* Registration of global state belongs into realize */
+    spapr_rtas_register("ibm,set-xive", rtas_set_xive);
+    spapr_rtas_register("ibm,get-xive", rtas_get_xive);
+    spapr_rtas_register("ibm,int-off", rtas_int_off);
+    spapr_rtas_register("ibm,int-on", rtas_int_on);
+
+    spapr_register_hypercall(H_CPPR, h_cppr);
+    spapr_register_hypercall(H_IPI, h_ipi);
+    spapr_register_hypercall(H_XIRR, h_xirr);
+    spapr_register_hypercall(H_EOI, h_eoi);
+
     ics->nr_irqs = icp->nr_irqs;
     ics->offset = XICS_IRQ_BASE;
     ics->icp = icp;
@@ -678,16 +689,6 @@ static void xics_class_init(ObjectClass *oc, void *data)
     dc->realize = xics_realize;
     dc->props = xics_properties;
     dc->reset = xics_reset;
-
-    spapr_rtas_register("ibm,set-xive", rtas_set_xive);
-    spapr_rtas_register("ibm,get-xive", rtas_get_xive);
-    spapr_rtas_register("ibm,int-off", rtas_int_off);
-    spapr_rtas_register("ibm,int-on", rtas_int_on);
-
-    spapr_register_hypercall(H_CPPR, h_cppr);
-    spapr_register_hypercall(H_IPI, h_ipi);
-    spapr_register_hypercall(H_XIRR, h_xirr);
-    spapr_register_hypercall(H_EOI, h_eoi);
 }
 
 static const TypeInfo xics_info = {
commit f1c2dc7c866a939c39c14729290a21309a1c8a38
Author: Alexey Kardashevskiy <aik at ozlabs.ru>
Date:   Fri Jul 12 17:38:24 2013 +1000

    spapr-pci: rework MSI/MSIX
    
    On the sPAPR platform a guest allocates MSI/MSIX vectors via RTAS
    hypercalls which return global IRQ numbers to a guest so it only
    operates with those and never touches MSIMessage.
    
    Therefore MSIMessage handling is completely hidden in QEMU.
    
    Previously every sPAPR PCI host bridge implemented its own MSI window
    to catch msi_notify()/msix_notify() calls from QEMU devices (virtio-pci
    or vfio) and route them to the guest via qemu_pulse_irq().
    MSIMessage used to be encoded as:
    	.addr - address within the PHB MSI window;
    	.data - the device index on PHB plus vector number.
    The MSI MR write function translated this MSIMessage to a global IRQ
    number and called qemu_pulse_irq().
    
    However the total number of IRQs is not really big (at the moment it is
    1024 IRQs starting from 4096) and even 16bit data field of MSIMessage
    seems to be enough to store an IRQ number there.
    
    This simplifies MSI handling in sPAPR PHB. Specifically, this does:
    1. remove a MSI window from a PHB;
    2. add a single memory region for all MSIs to sPAPREnvironment
    and spapr_pci_msi_init() to initialize it;
    3. encode MSIMessage as:
        * .addr - a fixed address of SPAPR_PCI_MSI_WINDOW==0x40000000000ULL;
        * .data as an IRQ number.
    4. change IRQ allocator to align first IRQ number in a block for MSI.
    MSI uses lower bits to specify the vector number so the first IRQ has to
    be aligned. MSIX does not need any special allocator though.
    
    Signed-off-by: Alexey Kardashevskiy <aik at ozlabs.ru>
    Reviewed-by: Anthony Liguori <aliguori at us.ibm.com>
    Acked-by: Michael S. Tsirkin <mst at redhat.com>
    Signed-off-by: Alexander Graf <agraf at suse.de>

diff --git a/hw/ppc/spapr.c b/hw/ppc/spapr.c
index 4b566aa..1ce9b0b 100644
--- a/hw/ppc/spapr.c
+++ b/hw/ppc/spapr.c
@@ -88,6 +88,9 @@ int spapr_allocate_irq(int hint, bool lsi)
 
     if (hint) {
         irq = hint;
+        if (hint >= spapr->next_irq) {
+            spapr->next_irq = hint + 1;
+        }
         /* FIXME: we should probably check for collisions somehow */
     } else {
         irq = spapr->next_irq++;
@@ -103,22 +106,39 @@ int spapr_allocate_irq(int hint, bool lsi)
     return irq;
 }
 
-/* Allocate block of consequtive IRQs, returns a number of the first */
-int spapr_allocate_irq_block(int num, bool lsi)
+/*
+ * Allocate block of consequtive IRQs, returns a number of the first.
+ * If msi==true, aligns the first IRQ number to num.
+ */
+int spapr_allocate_irq_block(int num, bool lsi, bool msi)
 {
     int first = -1;
-    int i;
+    int i, hint = 0;
+
+    /*
+     * MSIMesage::data is used for storing VIRQ so
+     * it has to be aligned to num to support multiple
+     * MSI vectors. MSI-X is not affected by this.
+     * The hint is used for the first IRQ, the rest should
+     * be allocated continously.
+     */
+    if (msi) {
+        assert((num == 1) || (num == 2) || (num == 4) ||
+               (num == 8) || (num == 16) || (num == 32));
+        hint = (spapr->next_irq + num - 1) & ~(num - 1);
+    }
 
     for (i = 0; i < num; ++i) {
         int irq;
 
-        irq = spapr_allocate_irq(0, lsi);
+        irq = spapr_allocate_irq(hint, lsi);
         if (!irq) {
             return -1;
         }
 
         if (0 == i) {
             first = irq;
+            hint = 0;
         }
 
         /* If the above doesn't create a consecutive block then that's
@@ -1214,6 +1234,7 @@ static void ppc_spapr_init(QEMUMachineInitArgs *args)
     spapr_create_nvram(spapr);
 
     /* Set up PCI */
+    spapr_pci_msi_init(spapr, SPAPR_PCI_MSI_WINDOW);
     spapr_pci_rtas_init();
 
     phb = spapr_create_phb(spapr, 0);
diff --git a/hw/ppc/spapr_pci.c b/hw/ppc/spapr_pci.c
index 65be265..9b6ee32 100644
--- a/hw/ppc/spapr_pci.c
+++ b/hw/ppc/spapr_pci.c
@@ -250,11 +250,11 @@ static int spapr_msicfg_find(sPAPRPHBState *phb, uint32_t config_addr,
  * This is required for msi_notify()/msix_notify() which
  * will write at the addresses via spapr_msi_write().
  */
-static void spapr_msi_setmsg(PCIDevice *pdev, hwaddr addr,
-                             bool msix, unsigned req_num)
+static void spapr_msi_setmsg(PCIDevice *pdev, hwaddr addr, bool msix,
+                             unsigned first_irq, unsigned req_num)
 {
     unsigned i;
-    MSIMessage msg = { .address = addr, .data = 0 };
+    MSIMessage msg = { .address = addr, .data = first_irq };
 
     if (!msix) {
         msi_set_message(pdev, msg);
@@ -262,8 +262,7 @@ static void spapr_msi_setmsg(PCIDevice *pdev, hwaddr addr,
         return;
     }
 
-    for (i = 0; i < req_num; ++i) {
-        msg.address = addr | (i << 2);
+    for (i = 0; i < req_num; ++i, ++msg.data) {
         msix_set_message(pdev, i, msg);
         trace_spapr_pci_msi_setup(pdev->name, i, msg.address);
     }
@@ -343,7 +342,8 @@ static void rtas_ibm_change_msi(PowerPCCPU *cpu, sPAPREnvironment *spapr,
 
     /* There is no cached config, allocate MSIs */
     if (!phb->msi_table[ndev].nvec) {
-        irq = spapr_allocate_irq_block(req_num, false);
+        irq = spapr_allocate_irq_block(req_num, false,
+                                       ret_intr_type == RTAS_TYPE_MSI);
         if (irq < 0) {
             fprintf(stderr, "Cannot allocate MSIs for device#%d", ndev);
             rtas_st(rets, 0, -1); /* Hardware error */
@@ -355,8 +355,8 @@ static void rtas_ibm_change_msi(PowerPCCPU *cpu, sPAPREnvironment *spapr,
     }
 
     /* Setup MSI/MSIX vectors in the device (via cfgspace or MSIX BAR) */
-    spapr_msi_setmsg(pdev, phb->msi_win_addr | (ndev << 16),
-                     ret_intr_type == RTAS_TYPE_MSIX, req_num);
+    spapr_msi_setmsg(pdev, spapr->msi_win_addr, ret_intr_type == RTAS_TYPE_MSIX,
+                     phb->msi_table[ndev].irq, req_num);
 
     rtas_st(rets, 0, 0);
     rtas_st(rets, 1, req_num);
@@ -442,10 +442,7 @@ static void pci_spapr_set_irq(void *opaque, int irq_num, int level)
 static void spapr_msi_write(void *opaque, hwaddr addr,
                             uint64_t data, unsigned size)
 {
-    sPAPRPHBState *phb = opaque;
-    int ndev = addr >> 16;
-    int vec = ((addr & 0xFFFF) >> 2) | data;
-    uint32_t irq = phb->msi_table[ndev].irq + vec;
+    uint32_t irq = data;
 
     trace_spapr_pci_msi_write(addr, data, irq);
 
@@ -459,6 +456,23 @@ static const MemoryRegionOps spapr_msi_ops = {
     .endianness = DEVICE_LITTLE_ENDIAN
 };
 
+void spapr_pci_msi_init(sPAPREnvironment *spapr, hwaddr addr)
+{
+    /*
+     * As MSI/MSIX interrupts trigger by writing at MSI/MSIX vectors,
+     * we need to allocate some memory to catch those writes coming
+     * from msi_notify()/msix_notify().
+     * As MSIMessage:addr is going to be the same and MSIMessage:data
+     * is going to be a VIRQ number, 4 bytes of the MSI MR will only
+     * be used.
+     */
+    spapr->msi_win_addr = addr;
+    memory_region_init_io(&spapr->msiwindow, NULL, &spapr_msi_ops, spapr,
+                          "msi", getpagesize());
+    memory_region_add_subregion(get_system_memory(), spapr->msi_win_addr,
+                                &spapr->msiwindow);
+}
+
 /*
  * PHB PCI device
  */
@@ -484,8 +498,7 @@ static int spapr_phb_init(SysBusDevice *s)
 
         if ((sphb->buid != -1) || (sphb->dma_liobn != -1)
             || (sphb->mem_win_addr != -1)
-            || (sphb->io_win_addr != -1)
-            || (sphb->msi_win_addr != -1)) {
+            || (sphb->io_win_addr != -1)) {
             fprintf(stderr, "Either \"index\" or other parameters must"
                     " be specified for PAPR PHB, not both\n");
             return -1;
@@ -498,7 +511,6 @@ static int spapr_phb_init(SysBusDevice *s)
             + sphb->index * SPAPR_PCI_WINDOW_SPACING;
         sphb->mem_win_addr = windows_base + SPAPR_PCI_MMIO_WIN_OFF;
         sphb->io_win_addr = windows_base + SPAPR_PCI_IO_WIN_OFF;
-        sphb->msi_win_addr = windows_base + SPAPR_PCI_MSI_WIN_OFF;
     }
 
     if (sphb->buid == -1) {
@@ -521,11 +533,6 @@ static int spapr_phb_init(SysBusDevice *s)
         return -1;
     }
 
-    if (sphb->msi_win_addr == -1) {
-        fprintf(stderr, "MSI window address not specified for PHB\n");
-        return -1;
-    }
-
     if (find_phb(spapr, sphb->buid)) {
         fprintf(stderr, "PCI host bridges must have unique BUIDs\n");
         return -1;
@@ -565,18 +572,6 @@ static int spapr_phb_init(SysBusDevice *s)
                              get_system_io(), 0, SPAPR_PCI_IO_WIN_SIZE);
     memory_region_add_subregion(get_system_memory(), sphb->io_win_addr,
                                 &sphb->iowindow);
-
-    /* As MSI/MSIX interrupts trigger by writing at MSI/MSIX vectors,
-     * we need to allocate some memory to catch those writes coming
-     * from msi_notify()/msix_notify() */
-    if (msi_supported) {
-        sprintf(namebuf, "%s.msi", sphb->dtbusname);
-        memory_region_init_io(&sphb->msiwindow, OBJECT(sphb), &spapr_msi_ops, sphb,
-                              namebuf, SPAPR_MSIX_MAX_DEVS * 0x10000);
-        memory_region_add_subregion(get_system_memory(), sphb->msi_win_addr,
-                                    &sphb->msiwindow);
-    }
-
     /*
      * Selecting a busname is more complex than you'd think, due to
      * interacting constraints.  If the user has specified an id
@@ -651,7 +646,6 @@ static Property spapr_phb_properties[] = {
     DEFINE_PROP_HEX64("io_win_addr", sPAPRPHBState, io_win_addr, -1),
     DEFINE_PROP_HEX64("io_win_size", sPAPRPHBState, io_win_size,
                       SPAPR_PCI_IO_WIN_SIZE),
-    DEFINE_PROP_HEX64("msi_win_addr", sPAPRPHBState, msi_win_addr, -1),
     DEFINE_PROP_END_OF_LIST(),
 };
 
@@ -693,7 +687,6 @@ static const VMStateDescription vmstate_spapr_pci = {
         VMSTATE_UINT64_EQUAL(mem_win_size, sPAPRPHBState),
         VMSTATE_UINT64_EQUAL(io_win_addr, sPAPRPHBState),
         VMSTATE_UINT64_EQUAL(io_win_size, sPAPRPHBState),
-        VMSTATE_UINT64_EQUAL(msi_win_addr, sPAPRPHBState),
         VMSTATE_STRUCT_ARRAY(lsi_table, sPAPRPHBState, PCI_NUM_PINS, 0,
                              vmstate_spapr_pci_lsi, struct spapr_pci_lsi),
         VMSTATE_STRUCT_ARRAY(msi_table, sPAPRPHBState, SPAPR_MSIX_MAX_DEVS, 0,
diff --git a/include/hw/pci-host/spapr.h b/include/hw/pci-host/spapr.h
index 93f9511..970b4a9 100644
--- a/include/hw/pci-host/spapr.h
+++ b/include/hw/pci-host/spapr.h
@@ -43,8 +43,7 @@ typedef struct sPAPRPHBState {
 
     MemoryRegion memspace, iospace;
     hwaddr mem_win_addr, mem_win_size, io_win_addr, io_win_size;
-    hwaddr msi_win_addr;
-    MemoryRegion memwindow, iowindow, msiwindow;
+    MemoryRegion memwindow, iowindow;
 
     uint32_t dma_liobn;
     uint64_t dma_window_start;
@@ -73,7 +72,8 @@ typedef struct sPAPRPHBState {
 #define SPAPR_PCI_MMIO_WIN_SIZE      0x20000000
 #define SPAPR_PCI_IO_WIN_OFF         0x80000000
 #define SPAPR_PCI_IO_WIN_SIZE        0x10000
-#define SPAPR_PCI_MSI_WIN_OFF        0x90000000
+
+#define SPAPR_PCI_MSI_WINDOW         0x40000000000ULL
 
 #define SPAPR_PCI_MEM_WIN_BUS_OFFSET 0x80000000ULL
 
@@ -88,6 +88,8 @@ int spapr_populate_pci_dt(sPAPRPHBState *phb,
                           uint32_t xics_phandle,
                           void *fdt);
 
+void spapr_pci_msi_init(sPAPREnvironment *spapr, hwaddr addr);
+
 void spapr_pci_rtas_init(void);
 
 #endif /* __HW_SPAPR_PCI_H__ */
diff --git a/include/hw/ppc/spapr.h b/include/hw/ppc/spapr.h
index 9fc1972..41b0466 100644
--- a/include/hw/ppc/spapr.h
+++ b/include/hw/ppc/spapr.h
@@ -13,6 +13,8 @@ struct sPAPRNVRAM;
 typedef struct sPAPREnvironment {
     struct VIOsPAPRBus *vio_bus;
     QLIST_HEAD(, sPAPRPHBState) phbs;
+    hwaddr msi_win_addr;
+    MemoryRegion msiwindow;
     struct sPAPRNVRAM *nvram;
     XICSState *icp;
 
@@ -303,7 +305,7 @@ target_ulong spapr_hypercall(PowerPCCPU *cpu, target_ulong opcode,
                              target_ulong *args);
 
 int spapr_allocate_irq(int hint, bool lsi);
-int spapr_allocate_irq_block(int num, bool lsi);
+int spapr_allocate_irq_block(int num, bool lsi, bool msi);
 
 static inline int spapr_allocate_msi(int hint)
 {
commit a3cedb541ca3ecc82040f597a4054419fdb22fa5
Author: Aneesh Kumar K.V <aneesh.kumar at linux.vnet.ibm.com>
Date:   Tue Aug 20 16:19:24 2013 +0530

    target-ppc: Use #define instead of opencoding SLB valid bit
    
    Use SLB_ESID_V instead of (1 << 27) in the code
    
    Reviewed-by: Andreas Färber <afaerber at suse.de>
    Signed-off-by: Aneesh Kumar K.V <aneesh.kumar at linux.vnet.ibm.com>
    Signed-off-by: Alexander Graf <agraf at suse.de>

diff --git a/target-ppc/mmu_helper.c b/target-ppc/mmu_helper.c
index 5dd4e05..9c9132e 100644
--- a/target-ppc/mmu_helper.c
+++ b/target-ppc/mmu_helper.c
@@ -2061,7 +2061,7 @@ void helper_store_sr(CPUPPCState *env, target_ulong srnum, target_ulong value)
         /* ESID = srnum */
         rb |= ((uint32_t)srnum & 0xf) << 28;
         /* Set the valid bit */
-        rb |= 1 << 27;
+        rb |= SLB_ESID_V;
         /* Index = ESID */
         rb |= (uint32_t)srnum;
 
commit 5dac82ce0d8716b54f73f96bf50811644a76e5c2
Author: Alexey Kardashevskiy <aik at ozlabs.ru>
Date:   Wed Aug 21 16:02:15 2013 +1000

    spapr-pci: fix config space access to support bridges
    
    spapr-pci config space accessors use find_dev() to find a PCI device.
    However find_dev() only searched on a primary bus and did not do
    recursive search through secondary buses so config space access was not
    possible for devices other that on a primary bus.
    
    This fixed find_dev() by using the PCI API pci_find_device() function.
    This effectively enabled pci bridges on spapr.
    
    Signed-off-by: Alexey Kardashevskiy <aik at ozlabs.ru>
    Acked-by: Michael S. Tsirkin <mst at redhat.com>
    Signed-off-by: Alexander Graf <agraf at suse.de>

diff --git a/hw/ppc/spapr_pci.c b/hw/ppc/spapr_pci.c
index 1ca35a0..65be265 100644
--- a/hw/ppc/spapr_pci.c
+++ b/hw/ppc/spapr_pci.c
@@ -65,22 +65,14 @@ static PCIDevice *find_dev(sPAPREnvironment *spapr, uint64_t buid,
 {
     sPAPRPHBState *sphb = find_phb(spapr, buid);
     PCIHostState *phb = PCI_HOST_BRIDGE(sphb);
-    BusState *bus = BUS(phb->bus);
-    BusChild *kid;
+    int bus_num = (config_addr >> 16) & 0xFF;
     int devfn = (config_addr >> 8) & 0xFF;
 
     if (!phb) {
         return NULL;
     }
 
-    QTAILQ_FOREACH(kid, &bus->children, sibling) {
-        PCIDevice *dev = (PCIDevice *)kid->child;
-        if (dev->devfn == devfn) {
-            return dev;
-        }
-    }
-
-    return NULL;
+    return pci_find_device(phb->bus, bus_num, devfn);
 }
 
 static uint32_t rtas_pci_cfgaddr(uint32_t arg)
commit 779f659021d1754117bce1aab9370dc22f37ae07
Author: Aurelien Jarno <aurelien at aurel32.net>
Date:   Thu Aug 15 13:32:38 2013 +0200

    target-ppc: fix bit extraction for FPBF and FPL
    
    Bit extraction for the FP BF and L field of the MTFSFI and MTFSF
    instructions is wrong and doesn't match the reference manual (which
    explain the bit number in big endian format). It has been broken in
    commit 7d08d85645def18eac2a9d672c1868a35e0bcf79.
    
    This patch fixes this, which in turn fixes the problem reported by
    Khem Raj about the floor() function of libm.
    
    Reported-by: Khem Raj <raj.khem at gmail.com>
    Signed-off-by: Aurelien Jarno <aurelien at aurel32.net>
    CC: qemu-stable at nongnu.org (1.6)
    Signed-off-by: Alexander Graf <agraf at suse.de>

diff --git a/target-ppc/translate.c b/target-ppc/translate.c
index f07d70d..41f4048 100644
--- a/target-ppc/translate.c
+++ b/target-ppc/translate.c
@@ -428,9 +428,9 @@ EXTRACT_HELPER(CRM, 12, 8);
 EXTRACT_HELPER(SR, 16, 4);
 
 /* mtfsf/mtfsfi */
-EXTRACT_HELPER(FPBF, 19, 3);
+EXTRACT_HELPER(FPBF, 23, 3);
 EXTRACT_HELPER(FPIMM, 12, 4);
-EXTRACT_HELPER(FPL, 21, 1);
+EXTRACT_HELPER(FPL, 25, 1);
 EXTRACT_HELPER(FPFLM, 17, 8);
 EXTRACT_HELPER(FPW, 16, 1);
 
commit ad9990acc5ac29ce505fbb2b955928ce335eddfd
Author: Andreas Färber <afaerber at suse.de>
Date:   Mon Aug 5 15:27:23 2013 +0200

    ppc405_boards: Don't enforce presence of firmware for qtest
    
    Adopt error_report() while at it.
    
    Signed-off-by: Andreas Färber <afaerber at suse.de>
    Signed-off-by: Alexander Graf <agraf at suse.de>

diff --git a/hw/ppc/ppc405_boards.c b/hw/ppc/ppc405_boards.c
index 807ada0..75b2177 100644
--- a/hw/ppc/ppc405_boards.c
+++ b/hw/ppc/ppc405_boards.c
@@ -27,9 +27,11 @@
 #include "hw/timer/m48t59.h"
 #include "hw/block/flash.h"
 #include "sysemu/sysemu.h"
+#include "sysemu/qtest.h"
 #include "block/block.h"
 #include "hw/boards.h"
 #include "qemu/log.h"
+#include "qemu/error-report.h"
 #include "hw/loader.h"
 #include "sysemu/blockdev.h"
 #include "exec/address-spaces.h"
@@ -252,17 +254,20 @@ static void ref405ep_init(QEMUMachineInitArgs *args)
         if (filename) {
             bios_size = load_image(filename, memory_region_get_ram_ptr(bios));
             g_free(filename);
+            if (bios_size < 0 || bios_size > BIOS_SIZE) {
+                error_report("Could not load PowerPC BIOS '%s'", bios_name);
+                exit(1);
+            }
+            bios_size = (bios_size + 0xfff) & ~0xfff;
+            memory_region_add_subregion(sysmem, (uint32_t)(-bios_size), bios);
+        } else if (!qtest_enabled() || kernel_filename != NULL) {
+            error_report("Could not load PowerPC BIOS '%s'", bios_name);
+            exit(1);
         } else {
+            /* Avoid an uninitialized variable warning */
             bios_size = -1;
         }
-        if (bios_size < 0 || bios_size > BIOS_SIZE) {
-            fprintf(stderr, "qemu: could not load PowerPC bios '%s'\n",
-                    bios_name);
-            exit(1);
-        }
-        bios_size = (bios_size + 0xfff) & ~0xfff;
         memory_region_set_readonly(bios, true);
-        memory_region_add_subregion(sysmem, (uint32_t)(-bios_size), bios);
     }
     /* Register FPGA */
 #ifdef DEBUG_BOARD_INIT
@@ -569,17 +574,17 @@ static void taihu_405ep_init(QEMUMachineInitArgs *args)
         if (filename) {
             bios_size = load_image(filename, memory_region_get_ram_ptr(bios));
             g_free(filename);
-        } else {
-            bios_size = -1;
-        }
-        if (bios_size < 0 || bios_size > BIOS_SIZE) {
-            fprintf(stderr, "qemu: could not load PowerPC bios '%s'\n",
-                    bios_name);
+            if (bios_size < 0 || bios_size > BIOS_SIZE) {
+                error_report("Could not load PowerPC BIOS '%s'", bios_name);
+                exit(1);
+            }
+            bios_size = (bios_size + 0xfff) & ~0xfff;
+            memory_region_add_subregion(sysmem, (uint32_t)(-bios_size), bios);
+        } else if (!qtest_enabled()) {
+            error_report("Could not load PowerPC BIOS '%s'", bios_name);
             exit(1);
         }
-        bios_size = (bios_size + 0xfff) & ~0xfff;
         memory_region_set_readonly(bios, true);
-        memory_region_add_subregion(sysmem, (uint32_t)(-bios_size), bios);
     }
     /* Register Linux flash */
     dinfo = drive_get(IF_PFLASH, 0, fl_idx);
commit 0d84382ed96cb2cfc3bc5be34d3a045eeb69c9dc
Author: Andreas Färber <afaerber at suse.de>
Date:   Mon Aug 5 15:27:22 2013 +0200

    ppc405_uc: Disable debug output
    
    Signed-off-by: Andreas Färber <afaerber at suse.de>
    Signed-off-by: Alexander Graf <agraf at suse.de>

diff --git a/hw/ppc/ppc405_uc.c b/hw/ppc/ppc405_uc.c
index 0ef5254..6d6a7f1 100644
--- a/hw/ppc/ppc405_uc.c
+++ b/hw/ppc/ppc405_uc.c
@@ -30,15 +30,15 @@
 #include "qemu/log.h"
 #include "exec/address-spaces.h"
 
-#define DEBUG_OPBA
-#define DEBUG_SDRAM
-#define DEBUG_GPIO
-#define DEBUG_SERIAL
-#define DEBUG_OCM
+//#define DEBUG_OPBA
+//#define DEBUG_SDRAM
+//#define DEBUG_GPIO
+//#define DEBUG_SERIAL
+//#define DEBUG_OCM
 //#define DEBUG_I2C
-#define DEBUG_GPT
-#define DEBUG_MAL
-#define DEBUG_CLOCKS
+//#define DEBUG_GPT
+//#define DEBUG_MAL
+//#define DEBUG_CLOCKS
 //#define DEBUG_CLOCKS_LL
 
 ram_addr_t ppc405_set_bootinfo (CPUPPCState *env, ppc4xx_bd_info_t *bd,
commit bf2ed917d77489189e7bcfea629ca030c8e2639d
Author: Andreas Färber <afaerber at suse.de>
Date:   Mon Aug 5 15:27:21 2013 +0200

    ppc405_boards: Disable debug output
    
    Also move one stray debug output into an #ifdef.
    
    Signed-off-by: Andreas Färber <afaerber at suse.de>
    Signed-off-by: Alexander Graf <agraf at suse.de>

diff --git a/hw/ppc/ppc405_boards.c b/hw/ppc/ppc405_boards.c
index f74e5e5..807ada0 100644
--- a/hw/ppc/ppc405_boards.c
+++ b/hw/ppc/ppc405_boards.c
@@ -42,7 +42,7 @@
 
 #define USE_FLASH_BIOS
 
-#define DEBUG_BOARD_INIT
+//#define DEBUG_BOARD_INIT
 
 /*****************************************************************************/
 /* PPC405EP reference board (IBM) */
@@ -353,9 +353,9 @@ static void ref405ep_init(QEMUMachineInitArgs *args)
         bdloc = 0;
     }
 #ifdef DEBUG_BOARD_INIT
+    printf("bdloc " RAM_ADDR_FMT "\n", bdloc);
     printf("%s: Done\n", __func__);
 #endif
-    printf("bdloc " RAM_ADDR_FMT "\n", bdloc);
 }
 
 static QEMUMachine ref405ep_machine = {
commit daf285b6063f20c328f03d6185bbfe9b81ce5fe2
Author: Efimov Vasily <real at ispras.ru>
Date:   Wed Aug 14 17:26:08 2013 +0400

    ppc: virtex_ml507: QEMU_OPTION_dtb support for this machine.
    
    QEMU has 'dtb' option for specifing the device tree file for the kernel.
    The patch adds support for this option to the 'virtex_ml507' machine
    implementation.
    
    Signed-off-by: Efimov Vasily <real at ispras.ru>
    Signed-off-by: Alexander Graf <agraf at suse.de>

diff --git a/hw/ppc/virtex_ml507.c b/hw/ppc/virtex_ml507.c
index 08e77fb..e9468b1 100644
--- a/hw/ppc/virtex_ml507.c
+++ b/hw/ppc/virtex_ml507.c
@@ -141,22 +141,31 @@ static int xilinx_load_device_tree(hwaddr addr,
 {
     char *path;
     int fdt_size;
-    void *fdt;
+    void *fdt = NULL;
     int r;
+    const char *dtb_filename;
 
-    /* Try the local "ppc.dtb" override.  */
-    fdt = load_device_tree("ppc.dtb", &fdt_size);
-    if (!fdt) {
-        path = qemu_find_file(QEMU_FILE_TYPE_BIOS, BINARY_DEVICE_TREE_FILE);
-        if (path) {
-            fdt = load_device_tree(path, &fdt_size);
-            g_free(path);
+    dtb_filename = qemu_opt_get(qemu_get_machine_opts(), "dtb");
+    if (dtb_filename) {
+        fdt = load_device_tree(dtb_filename, &fdt_size);
+        if (!fdt) {
+            error_report("Error while loading device tree file '%s'",
+                dtb_filename);
         }
+    } else {
+        /* Try the local "ppc.dtb" override.  */
+        fdt = load_device_tree("ppc.dtb", &fdt_size);
         if (!fdt) {
-            return 0;
+            path = qemu_find_file(QEMU_FILE_TYPE_BIOS, BINARY_DEVICE_TREE_FILE);
+            if (path) {
+                fdt = load_device_tree(path, &fdt_size);
+                g_free(path);
+            }
         }
     }
-
+    if (!fdt) {
+        return 0;
+    }
     r = qemu_devtree_setprop_string(fdt, "/chosen", "bootargs", kernel_cmdline);
     if (r < 0)
         fprintf(stderr, "couldn't set /chosen/bootargs\n");
commit 95f5b6e3af28a24f97b25649e12f586e19e8a4a1
Author: Anton Blanchard <anton at samba.org>
Date:   Wed Aug 7 10:47:03 2013 +1000

    disas/ppc.c: Fix little endian disassembly
    
    Use info->endian to select the endian of the instruction to
    be disassembled.
    
    Signed-off-by: Anton Blanchard <anton at samba.org>
    Reviewed-by: Anthony Liguori <aliguori at us.ibm.com>
    Signed-off-by: Alexander Graf <agraf at suse.de>

diff --git a/disas/ppc.c b/disas/ppc.c
index c149506..99c4cbc 100644
--- a/disas/ppc.c
+++ b/disas/ppc.c
@@ -5157,7 +5157,8 @@ int
 print_insn_ppc (bfd_vma memaddr, struct disassemble_info *info)
 {
   int dialect = (char *) info->private_data - (char *) 0;
-  return print_insn_powerpc (memaddr, info, 1, dialect);
+  return print_insn_powerpc (memaddr, info, info->endian == BFD_ENDIAN_BIG,
+                             dialect);
 }
 
 /* Print a big endian PowerPC instruction.  */
commit bb429d224733c263456c105eab93cd2b5e55add2
Author: Anton Blanchard <anton at samba.org>
Date:   Wed Aug 7 10:47:00 2013 +1000

    target-ppc: POWER7 supports the MSR_LE bit
    
    Add MSR_LE to the msr_mask for POWER7.
    
    Signed-off-by: Anton Blanchard <anton at samba.org>
    Reviewed-by: Anthony Liguori <aliguori at us.ibm.com>
    Signed-off-by: Alexander Graf <agraf at suse.de>

diff --git a/target-ppc/translate_init.c b/target-ppc/translate_init.c
index 609f797..d2645ba 100644
--- a/target-ppc/translate_init.c
+++ b/target-ppc/translate_init.c
@@ -7227,7 +7227,7 @@ POWERPC_FAMILY(POWER7)(ObjectClass *oc, void *data)
                        PPC_SEGMENT_64B | PPC_SLBI |
                        PPC_POPCNTB | PPC_POPCNTWD;
     pcc->insns_flags2 = PPC2_VSX | PPC2_DFP | PPC2_DBRX | PPC2_ISA205;
-    pcc->msr_mask = 0x800000000204FF36ULL;
+    pcc->msr_mask = 0x800000000204FF37ULL;
     pcc->mmu_model = POWERPC_MMU_2_06;
 #if defined(CONFIG_SOFTMMU)
     pcc->handle_mmu_fault = ppc_hash64_handle_mmu_fault;
commit 1e0c7e554e449abb7bf759339ca2cf8cda232532
Author: Anton Blanchard <anton at samba.org>
Date:   Wed Aug 7 10:47:01 2013 +1000

    target-ppc: USE LPCR_ILE to control exception endian on POWER7
    
    On POWER7, LPCR_ILE is used to control what endian guests take
    their exceptions in so use it instead of MSR_ILE.
    
    Signed-off-by: Anton Blanchard <anton at samba.org>
    Reviewed-by: Anthony Liguori <aliguori at us.ibm.com>
    Signed-off-by: Alexander Graf <agraf at suse.de>

diff --git a/target-ppc/cpu.h b/target-ppc/cpu.h
index 711db08..422a6bb 100644
--- a/target-ppc/cpu.h
+++ b/target-ppc/cpu.h
@@ -453,6 +453,8 @@ struct ppc_slb_t {
 #define MSR_RI   1  /* Recoverable interrupt                        1        */
 #define MSR_LE   0  /* Little-endian mode                           1 hflags */
 
+#define LPCR_ILE (1 << (63-38))
+
 #define msr_sf   ((env->msr >> MSR_SF)   & 1)
 #define msr_isf  ((env->msr >> MSR_ISF)  & 1)
 #define msr_shv  ((env->msr >> MSR_SHV)  & 1)
diff --git a/target-ppc/excp_helper.c b/target-ppc/excp_helper.c
index e9fcad8..e957761 100644
--- a/target-ppc/excp_helper.c
+++ b/target-ppc/excp_helper.c
@@ -611,9 +611,19 @@ static inline void powerpc_excp(PowerPCCPU *cpu, int excp_model, int excp)
         tlb_flush(env, 1);
     }
 
+#ifdef TARGET_PPC64
+    if (excp_model == POWERPC_EXCP_POWER7) {
+        if (env->spr[SPR_LPCR] & LPCR_ILE) {
+            new_msr |= (target_ulong)1 << MSR_LE;
+        }
+    } else if (msr_ile) {
+        new_msr |= (target_ulong)1 << MSR_LE;
+    }
+#else
     if (msr_ile) {
         new_msr |= (target_ulong)1 << MSR_LE;
     }
+#endif
 
     /* Jump to handler */
     vector = env->excp_vectors[excp];
commit 7770b6f78a2d655e03852a5de238f5926c92be6a
Author: Anton Blanchard <anton at samba.org>
Date:   Tue Aug 13 14:10:04 2013 +1000

    pseries: Fix stalls on hypervisor virtual console
    
    A number of users are reporting stalls when using the pseries
    hypervisor virtual console.
    
    A simple test case is to paste 15 or 17 characters at a time
    into the console. Pasting 15 characters at a time works fine
    but pasting 17 characters hangs for a random amount of time.
    Other activity (network, qemu monitor etc) unblocks it.
    
    If qemu-char tries to send more than 16 characters at once,
    vty_can_receive returns false. At this point we have to
    wait for the guest to consume that output. Everything is good
    so far.
    
    The problem occurs when the the guest does consume the output.
    We need to signal back to the qemu-char layer that we are
    ready for more input. Without this we block until something
    else kicks us (eg network activity).
    
    Signed-off-by: Anton Blanchard <anton at samba.org>
    Signed-off-by: Alexander Graf <agraf at suse.de>

diff --git a/hw/char/spapr_vty.c b/hw/char/spapr_vty.c
index a799721..9c2aef8 100644
--- a/hw/char/spapr_vty.c
+++ b/hw/char/spapr_vty.c
@@ -47,6 +47,8 @@ static int vty_getchars(VIOsPAPRDevice *sdev, uint8_t *buf, int max)
         buf[n++] = dev->buf[dev->out++ % VTERM_BUFSIZE];
     }
 
+    qemu_chr_accept_input(dev->chardev);
+
     return n;
 }
 
commit 28290f37e20cda27574f15be9e9499493e3d0fe8
Author: Alexander Graf <agraf at suse.de>
Date:   Fri Jul 19 12:56:24 2013 +0200

    PPC: E500: Generate device tree on reset
    
    Today we generate the device tree once on machine initialization and then
    store the finalized blob in memory to reload it on reset.
    
    This is bad for 2 reasons. First we potentially waste a bunch of RAM for no
    good reason, as we have all information required to regenerate the device
    tree available anyways.
    
    The second reason is even more important. On machine init when we generate
    the device tree for the first time, we don't have all of the devices fully
    initialized yet. But the device tree needs to potentially walk devices to
    put information about them into the device tree.
    
    Move the generation into a reset function. That way we just generate it new
    every time we reset, solving both of the above issues.
    
    Signed-off-by: Alexander Graf <agraf at suse.de>

diff --git a/hw/ppc/e500.c b/hw/ppc/e500.c
index e79612b..9059ff9 100644
--- a/hw/ppc/e500.c
+++ b/hw/ppc/e500.c
@@ -123,13 +123,14 @@ static void dt_serial_create(void *fdt, unsigned long long offset,
     }
 }
 
-static int ppce500_load_device_tree(CPUPPCState *env,
-                                    QEMUMachineInitArgs *args,
+static int ppce500_load_device_tree(QEMUMachineInitArgs *args,
                                     PPCE500Params *params,
                                     hwaddr addr,
                                     hwaddr initrd_base,
-                                    hwaddr initrd_size)
+                                    hwaddr initrd_size,
+                                    bool dry_run)
 {
+    CPUPPCState *env = first_cpu->env_ptr;
     int ret = -1;
     uint64_t mem_reg_property[] = { 0, cpu_to_be64(args->ram_size) };
     int fdt_size;
@@ -369,12 +370,10 @@ static int ppce500_load_device_tree(CPUPPCState *env,
     }
 
 done:
-    qemu_devtree_dumpdtb(fdt, fdt_size);
-    ret = rom_add_blob_fixed(BINARY_DEVICE_TREE_FILE, fdt, fdt_size, addr);
-    if (ret < 0) {
-        goto out;
+    if (!dry_run) {
+        qemu_devtree_dumpdtb(fdt, fdt_size);
+        cpu_physical_memory_write(addr, fdt, fdt_size);
     }
-    g_free(fdt);
     ret = fdt_size;
 
 out:
@@ -383,6 +382,41 @@ out:
     return ret;
 }
 
+typedef struct DeviceTreeParams {
+    QEMUMachineInitArgs args;
+    PPCE500Params params;
+    hwaddr addr;
+    hwaddr initrd_base;
+    hwaddr initrd_size;
+} DeviceTreeParams;
+
+static void ppce500_reset_device_tree(void *opaque)
+{
+    DeviceTreeParams *p = opaque;
+    ppce500_load_device_tree(&p->args, &p->params, p->addr, p->initrd_base,
+                             p->initrd_size, false);
+}
+
+static int ppce500_prep_device_tree(QEMUMachineInitArgs *args,
+                                    PPCE500Params *params,
+                                    hwaddr addr,
+                                    hwaddr initrd_base,
+                                    hwaddr initrd_size)
+{
+    DeviceTreeParams *p = g_new(DeviceTreeParams, 1);
+    p->args = *args;
+    p->params = *params;
+    p->addr = addr;
+    p->initrd_base = initrd_base;
+    p->initrd_size = initrd_size;
+
+    qemu_register_reset(ppce500_reset_device_tree, p);
+
+    /* Issue the device tree loader once, so that we get the size of the blob */
+    return ppce500_load_device_tree(args, params, addr, initrd_base,
+                                    initrd_size, true);
+}
+
 /* Create -kernel TLB entries for BookE.  */
 static inline hwaddr booke206_page_size_to_tlb(uint64_t size)
 {
@@ -746,7 +780,7 @@ void ppce500_init(QEMUMachineInitArgs *args, PPCE500Params *params)
         struct boot_info *boot_info;
         int dt_size;
 
-        dt_size = ppce500_load_device_tree(env, args, params, dt_base,
+        dt_size = ppce500_prep_device_tree(args, params, dt_base,
                                            initrd_base, initrd_size);
         if (dt_size < 0) {
             fprintf(stderr, "couldn't load device tree\n");
commit fcdda211f9239f4218f96cdc336a482f7103d90b
Author: Alex Bligh <alex at alex.org.uk>
Date:   Thu Aug 29 23:32:14 2013 +0100

    aio / timers: use g_usleep() not sleep()
    
    sleep() apparently doesn't exist under mingw. Use g_usleep for
    portability.
    
    Signed-off-by: Alex Bligh <alex at alex.org.uk>
    Reviewed-by: Stefan Weil <sw at weilnetz.de>
    Signed-off-by: Michael Tokarev <mjt at tls.msk.ru>

diff --git a/tests/test-aio.c b/tests/test-aio.c
index 07a1f61..532a1de 100644
--- a/tests/test-aio.c
+++ b/tests/test-aio.c
@@ -396,7 +396,7 @@ static void test_timer_schedule(void)
     g_assert(!aio_poll(ctx, false));
     g_assert_cmpint(data.n, ==, 0);
 
-    sleep(1);
+    g_usleep(1 * G_USEC_PER_SEC);
     g_assert_cmpint(data.n, ==, 0);
 
     g_assert(aio_poll(ctx, false));
@@ -729,7 +729,7 @@ static void test_source_timer_schedule(void)
 
     g_assert_cmpint(data.n, ==, 0);
 
-    sleep(1);
+    g_usleep(1 * G_USEC_PER_SEC);
     g_assert_cmpint(data.n, ==, 0);
 
     g_assert(g_main_context_iteration(NULL, false));
@@ -739,7 +739,7 @@ static void test_source_timer_schedule(void)
     do {
         g_assert(g_main_context_iteration(NULL, true));
     } while (qemu_clock_get_ns(data.clock_type) <= expiry);
-    sleep(1);
+    g_usleep(1 * G_USEC_PER_SEC);
     g_main_context_iteration(NULL, false);
 
     g_assert_cmpint(data.n, ==, 2);
commit 2b21fb57af305f17841d79e7e2e02ad1aec3f5ca
Author: Hervé Poussineau <hpoussin at reactos.org>
Date:   Wed Aug 14 11:49:04 2013 +0200

    adlib: sort offsets in portio registration
    
    This fixes the following assert when -device adlib is used:
    ioport.c:240: portio_list_add: Assertion `pio->offset >= off_last' failed.
    
    Signed-off-by: Hervé Poussineau <hpoussin at reactos.org>
    Signed-off-by: Michael Tokarev <mjt at tls.msk.ru>

diff --git a/hw/audio/adlib.c b/hw/audio/adlib.c
index 0c79247..bd8e9d9 100644
--- a/hw/audio/adlib.c
+++ b/hw/audio/adlib.c
@@ -284,9 +284,9 @@ static void Adlib_fini (AdlibState *s)
 }
 
 static MemoryRegionPortio adlib_portio_list[] = {
-    { 0x388, 4, 1, .read = adlib_read, .write = adlib_write, },
     { 0, 4, 1, .read = adlib_read, .write = adlib_write, },
     { 0, 2, 1, .read = adlib_read, .write = adlib_write, },
+    { 0x388, 4, 1, .read = adlib_read, .write = adlib_write, },
     PORTIO_END_OF_LIST(),
 };
 
commit 586b546657da7a762106abb5056d90a140d1a2f5
Author: Eric Blake <eblake at redhat.com>
Date:   Fri Aug 30 14:44:11 2013 -0600

    qmp: fix integer usage in examples
    
    Per the qapi schema, block_set_io_throttle takes most arguments
    as ints, not strings.
    
    * qmp-commands.hx (block_set_io_throttle): Use correct type.  Fix
    whitespace and a copy-paste bug in the process.
    
    Signed-off-by: Eric Blake <eblake at redhat.com>
    Reviewed-by: Benoit Canet <benoit at irqsave.net>
    Signed-off-by: Michael Tokarev <mjt at tls.msk.ru>

diff --git a/qmp-commands.hx b/qmp-commands.hx
index bb09e72..8a8f342 100644
--- a/qmp-commands.hx
+++ b/qmp-commands.hx
@@ -1402,22 +1402,22 @@ Change I/O throttle limits for a block drive.
 Arguments:
 
 - "device": device name (json-string)
-- "bps":  total throughput limit in bytes per second(json-int)
-- "bps_rd":  read throughput limit in bytes per second(json-int)
-- "bps_wr":  read throughput limit in bytes per second(json-int)
-- "iops":  total I/O operations per second(json-int)
-- "iops_rd":  read I/O operations per second(json-int)
-- "iops_wr":  write I/O operations per second(json-int)
+- "bps": total throughput limit in bytes per second (json-int)
+- "bps_rd": read throughput limit in bytes per second (json-int)
+- "bps_wr": write throughput limit in bytes per second (json-int)
+- "iops": total I/O operations per second (json-int)
+- "iops_rd": read I/O operations per second (json-int)
+- "iops_wr": write I/O operations per second (json-int)
 
 Example:
 
 -> { "execute": "block_set_io_throttle", "arguments": { "device": "virtio0",
-                                               "bps": "1000000",
-                                               "bps_rd": "0",
-                                               "bps_wr": "0",
-                                               "iops": "0",
-                                               "iops_rd": "0",
-                                               "iops_wr": "0" } }
+                                               "bps": 1000000,
+                                               "bps_rd": 0,
+                                               "bps_wr": 0,
+                                               "iops": 0,
+                                               "iops_rd": 0,
+                                               "iops_wr": 0 } }
 <- { "return": {} }
 
 EQMP
@@ -1791,7 +1791,7 @@ Each json-object contain the following:
                  - "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)
+                                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
commit a32b12741bf45bf3f46bffe5a79cb2548a060cd8
Author: Stefan Weil <sw at weilnetz.de>
Date:   Wed Aug 28 19:28:06 2013 +0200

    tci: Remove function tcg_out64 (fix broken build)
    
    Commit ac26eb69a311396668809eadbf7ff4e623447d4c added tcg_out64 to tcg/tcg.c.
    tcg/tci/tcg-target.c already had a nearly identical implementation which is
    now removed to fix a compiler error.
    
    Signed-off-by: Stefan Weil <sw at weilnetz.de>
    Reviewed-by: Richard Henderson <rth at twiddle.net>
    Signed-off-by: Michael Tokarev <mjt at tls.msk.ru>

diff --git a/tcg/tci/tcg-target.c b/tcg/tci/tcg-target.c
index e118bc7..eb23832 100644
--- a/tcg/tci/tcg-target.c
+++ b/tcg/tci/tcg-target.c
@@ -415,13 +415,6 @@ static void tcg_out_i(TCGContext *s, tcg_target_ulong v)
     s->code_ptr += sizeof(tcg_target_ulong);
 }
 
-/* Write 64 bit value. */
-static void tcg_out64(TCGContext *s, uint64_t v)
-{
-    *(uint64_t *)s->code_ptr = v;
-    s->code_ptr += sizeof(v);
-}
-
 /* Write opcode. */
 static void tcg_out_op_t(TCGContext *s, TCGOpcode op)
 {
commit e0c270d946dc8efd723129b6a9d956b3084b55b1
Author: Stefan Weil <sw at weilnetz.de>
Date:   Wed Aug 28 06:39:56 2013 +0200

    target-arm: Report unimplemented opcodes (LOG_UNIMP)
    
    These unimplemented opcodes are handled like illegal opcodes, but
    they are used in existing code. We should at least report when they
    are executed.
    
    Signed-off-by: Stefan Weil <sw at weilnetz.de>
    Reviewed-by: Peter Maydell <peter.maydell at linaro.org>
    Signed-off-by: Michael Tokarev <mjt at tls.msk.ru>

diff --git a/target-arm/translate.c b/target-arm/translate.c
index d1e8538..92d9f16 100644
--- a/target-arm/translate.c
+++ b/target-arm/translate.c
@@ -6715,6 +6715,7 @@ static void disas_arm_insn(CPUARMState * env, DisasContext *s)
             /* setend */
             if (((insn >> 9) & 1) != s->bswap_code) {
                 /* Dynamic endianness switching not implemented. */
+                qemu_log_mask(LOG_UNIMP, "arm: unimplemented setend\n");
                 goto illegal_op;
             }
             return;
@@ -8740,6 +8741,8 @@ static int disas_thumb2_insn(CPUARMState *env, DisasContext *s, uint16_t insn_hw
 
                 if (insn & (1 << 26)) {
                     /* Secure monitor call (v6Z) */
+                    qemu_log_mask(LOG_UNIMP,
+                                  "arm: unimplemented secure monitor call\n");
                     goto illegal_op; /* not implemented.  */
                 } else {
                     op = (insn >> 20) & 7;
@@ -9779,6 +9782,7 @@ static void disas_thumb_insn(CPUARMState *env, DisasContext *s)
                 ARCH(6);
                 if (((insn >> 3) & 1) != s->bswap_code) {
                     /* Dynamic endianness switching not implemented. */
+                    qemu_log_mask(LOG_UNIMP, "arm: unimplemented setend\n");
                     goto illegal_op;
                 }
                 break;
commit 56f99ea19b5ae71cfdc0bd147cba372da3b63c44
Author: Antony Pavlov <antonynpavlov at gmail.com>
Date:   Wed Aug 28 07:59:37 2013 +0400

    pflash_cfi02.c: fix debug macro
    
    If PFLASH_DEBUG is enabled then we have some build errors:
    
    hw/block/pflash_cfi02.c: In function ‘pflash_timer’:
    hw/block/pflash_cfi02.c:128:5: error: expected ‘)’ before string constant
    hw/block/pflash_cfi02.c:128:5: error: too few arguments to function ‘fprintf’
    
    This patch fixes the problem.
    
    Signed-off-by: Antony Pavlov <antonynpavlov at gmail.com>
    Signed-off-by: Michael Tokarev <mjt at tls.msk.ru>

diff --git a/hw/block/pflash_cfi02.c b/hw/block/pflash_cfi02.c
index 99445b0..8d4b828 100644
--- a/hw/block/pflash_cfi02.c
+++ b/hw/block/pflash_cfi02.c
@@ -47,7 +47,7 @@
 #ifdef PFLASH_DEBUG
 #define DPRINTF(fmt, ...)                                  \
 do {                                                       \
-    fprintf(stderr "PFLASH: " fmt , ## __VA_ARGS__);       \
+    fprintf(stderr, "PFLASH: " fmt , ## __VA_ARGS__);       \
 } while (0)
 #else
 #define DPRINTF(fmt, ...) do { } while (0)
commit 65d5d3f92246f056a45e4ddc6f13487de39cd47c
Author: Stefan Weil <sw at weilnetz.de>
Date:   Tue Aug 27 21:09:13 2013 +0200

    configure: Remove unneeded redirections of stderr (pkg-config --exists)
    
    Predicate options (--exists, --atleast-version, ...) of pkg-config dont't
    print error messages to stderr, so redirecting stderr is not necessary.
    
    Combining a predicate option with --modversion is not necessary for tests.
    Instead of testing with --modversion, --exists can be used.
    
    Signed-off-by: Stefan Weil <sw at weilnetz.de>
    Signed-off-by: Michael Tokarev <mjt at tls.msk.ru>

diff --git a/configure b/configure
index 9748dee..43c0d21 100755
--- a/configure
+++ b/configure
@@ -1470,7 +1470,7 @@ libs_softmmu="$libs_softmmu -lz"
 # libseccomp check
 
 if test "$seccomp" != "no" ; then
-    if $pkg_config --atleast-version=2.1.0 libseccomp --modversion >/dev/null 2>&1; then
+    if $pkg_config --atleast-version=2.1.0 libseccomp; then
         libs_softmmu="$libs_softmmu `$pkg_config --libs libseccomp`"
         QEMU_CFLAGS="$QEMU_CFLAGS `$pkg_config --cflags libseccomp`"
 	seccomp="yes"
@@ -1722,7 +1722,7 @@ if test "`basename $sdl_config`" != sdl-config && ! has ${sdl_config}; then
   sdl_config=sdl-config
 fi
 
-if $pkg_config sdl --modversion >/dev/null 2>&1; then
+if $pkg_config sdl --exists; then
   sdlconfig="$pkg_config sdl"
   _sdlversion=`$sdlconfig --modversion 2>/dev/null | sed 's/[^0-9]//g'`
 elif has ${sdl_config}; then
@@ -1908,7 +1908,7 @@ int main(void) {
     return png_ptr != 0;
 }
 EOF
-  if $pkg_config libpng --modversion >/dev/null 2>&1; then
+  if $pkg_config libpng --exists; then
     vnc_png_cflags=`$pkg_config libpng --cflags`
     vnc_png_libs=`$pkg_config libpng --libs`
   else
@@ -2187,7 +2187,7 @@ fi
 ##########################################
 # curl probe
 if test "$curl" != "no" ; then
-  if $pkg_config libcurl --modversion >/dev/null 2>&1; then
+  if $pkg_config libcurl --exists; then
     curlconfig="$pkg_config libcurl"
   else
     curlconfig=curl-config
@@ -2239,8 +2239,7 @@ if test "$mingw32" = yes; then
 else
     glib_req_ver=2.12
 fi
-if $pkg_config --atleast-version=$glib_req_ver gthread-2.0 > /dev/null 2>&1
-then
+if $pkg_config --atleast-version=$glib_req_ver gthread-2.0; then
     glib_cflags=`$pkg_config --cflags gthread-2.0`
     glib_libs=`$pkg_config --libs gthread-2.0`
     LIBS="$glib_libs $LIBS"
@@ -2371,8 +2370,7 @@ fi
 # libssh2 probe
 min_libssh2_version=1.2.8
 if test "$libssh2" != "no" ; then
-  if $pkg_config --atleast-version=$min_libssh2_version libssh2 >/dev/null 2>&1
-  then
+  if $pkg_config --atleast-version=$min_libssh2_version libssh2; then
     libssh2_cflags=`$pkg_config libssh2 --cflags`
     libssh2_libs=`$pkg_config libssh2 --libs`
     libssh2=yes
@@ -2590,14 +2588,14 @@ fi
 ##########################################
 # glusterfs probe
 if test "$glusterfs" != "no" ; then
-  if $pkg_config --atleast-version=3 glusterfs-api >/dev/null 2>&1; then
+  if $pkg_config --atleast-version=3 glusterfs-api; then
     glusterfs="yes"
     glusterfs_cflags=`$pkg_config --cflags glusterfs-api`
     glusterfs_libs=`$pkg_config --libs glusterfs-api`
     CFLAGS="$CFLAGS $glusterfs_cflags"
     libs_tools="$glusterfs_libs $libs_tools"
     libs_softmmu="$glusterfs_libs $libs_softmmu"
-    if $pkg_config --atleast-version=5 glusterfs-api >/dev/null 2>&1; then
+    if $pkg_config --atleast-version=5 glusterfs-api; then
       glusterfs_discard="yes"
     fi
   else
@@ -2960,7 +2958,7 @@ if test "$libiscsi" != "no" ; then
 #include <iscsi/iscsi.h>
 int main(void) { iscsi_unmap_sync(NULL,0,0,0,NULL,0); return 0; }
 EOF
-  if $pkg_config --atleast-version=1.7.0 libiscsi --modversion >/dev/null 2>&1; then
+  if $pkg_config --atleast-version=1.7.0 libiscsi; then
     libiscsi="yes"
     libiscsi_cflags=$($pkg_config --cflags libiscsi)
     libiscsi_libs=$($pkg_config --libs libiscsi)
@@ -3030,8 +3028,8 @@ int main(void) { spice_server_new(); return 0; }
 EOF
   spice_cflags=$($pkg_config --cflags spice-protocol spice-server 2>/dev/null)
   spice_libs=$($pkg_config --libs spice-protocol spice-server 2>/dev/null)
-  if $pkg_config --atleast-version=0.12.0 spice-server >/dev/null 2>&1 && \
-     $pkg_config --atleast-version=0.12.3 spice-protocol > /dev/null 2>&1 && \
+  if $pkg_config --atleast-version=0.12.0 spice-server && \
+     $pkg_config --atleast-version=0.12.3 spice-protocol && \
      compile_prog "$spice_cflags" "$spice_libs" ; then
     spice="yes"
     libs_softmmu="$libs_softmmu $spice_libs"
@@ -3066,7 +3064,7 @@ EOF
         test_cflags="-Werror $test_cflags"
     fi
     if test -n "$libtool" &&
-            $pkg_config --atleast-version=3.12.8 nss >/dev/null 2>&1 && \
+       $pkg_config --atleast-version=3.12.8 nss && \
       compile_prog "$test_cflags" "$libcacard_libs"; then
         smartcard_nss="yes"
         QEMU_CFLAGS="$QEMU_CFLAGS $libcacard_cflags"
@@ -3082,7 +3080,7 @@ fi
 
 # check for libusb
 if test "$libusb" != "no" ; then
-    if $pkg_config --atleast-version=1.0.13 libusb-1.0 >/dev/null 2>&1 ; then
+    if $pkg_config --atleast-version=1.0.13 libusb-1.0; then
         libusb="yes"
 	usb="libusb"
         libusb_cflags=$($pkg_config --cflags libusb-1.0)
@@ -3099,7 +3097,7 @@ fi
 
 # check for usbredirparser for usb network redirection support
 if test "$usb_redir" != "no" ; then
-    if $pkg_config --atleast-version=0.6 libusbredirparser-0.5 >/dev/null 2>&1 ; then
+    if $pkg_config --atleast-version=0.6 libusbredirparser-0.5; then
         usb_redir="yes"
         usb_redir_cflags=$($pkg_config --cflags libusbredirparser-0.5)
         usb_redir_libs=$($pkg_config --libs libusbredirparser-0.5)
commit ca871ec8612cc0e95a02de83a3bdd01514e5733b
Author: Stefan Weil <sw at weilnetz.de>
Date:   Tue Aug 27 21:09:12 2013 +0200

    configure: Remove unneeded redirections of stderr (pkg-config --cflags, --libs)
    
    For existing libraries, pkg-config --cflags and pkg-config --libs won't
    print error messages to stderr, so redirecting stderr is not necessary.
    
    Signed-off-by: Stefan Weil <sw at weilnetz.de>
    Signed-off-by: Michael Tokarev <mjt at tls.msk.ru>

diff --git a/configure b/configure
index 391b204..9748dee 100755
--- a/configure
+++ b/configure
@@ -1704,10 +1704,10 @@ if test "$gtk" != "no"; then
         fi
         gtk="no"
     else
-	gtk_cflags=`$pkg_config --cflags $gtkpackage 2>/dev/null`
-	gtk_libs=`$pkg_config --libs $gtkpackage 2>/dev/null`
-	vte_cflags=`$pkg_config --cflags $vtepackage 2>/dev/null`
-	vte_libs=`$pkg_config --libs $vtepackage 2>/dev/null`
+	gtk_cflags=`$pkg_config --cflags $gtkpackage`
+	gtk_libs=`$pkg_config --libs $gtkpackage`
+	vte_cflags=`$pkg_config --cflags $vtepackage`
+	vte_libs=`$pkg_config --libs $vtepackage`
 	libs_softmmu="$gtk_libs $vte_libs $libs_softmmu"
 	gtk="yes"
     fi
@@ -1909,8 +1909,8 @@ int main(void) {
 }
 EOF
   if $pkg_config libpng --modversion >/dev/null 2>&1; then
-    vnc_png_cflags=`$pkg_config libpng --cflags 2> /dev/null`
-    vnc_png_libs=`$pkg_config libpng --libs 2> /dev/null`
+    vnc_png_cflags=`$pkg_config libpng --cflags`
+    vnc_png_libs=`$pkg_config libpng --libs`
   else
     vnc_png_cflags=""
     vnc_png_libs="-lpng"
@@ -2241,8 +2241,8 @@ else
 fi
 if $pkg_config --atleast-version=$glib_req_ver gthread-2.0 > /dev/null 2>&1
 then
-    glib_cflags=`$pkg_config --cflags gthread-2.0 2>/dev/null`
-    glib_libs=`$pkg_config --libs gthread-2.0 2>/dev/null`
+    glib_cflags=`$pkg_config --cflags gthread-2.0`
+    glib_libs=`$pkg_config --libs gthread-2.0`
     LIBS="$glib_libs $LIBS"
     libs_qga="$glib_libs $libs_qga"
 else
@@ -2271,8 +2271,8 @@ if test "$pixman" = "none"; then
   pixman_cflags=
   pixman_libs=
 elif test "$pixman" = "system"; then
-  pixman_cflags=`$pkg_config --cflags pixman-1 2>/dev/null`
-  pixman_libs=`$pkg_config --libs pixman-1 2>/dev/null`
+  pixman_cflags=`$pkg_config --cflags pixman-1`
+  pixman_libs=`$pkg_config --libs pixman-1`
 else
   if test ! -d ${source_path}/pixman/pixman; then
     error_exit "pixman not present. Your options:" \
@@ -2592,8 +2592,8 @@ fi
 if test "$glusterfs" != "no" ; then
   if $pkg_config --atleast-version=3 glusterfs-api >/dev/null 2>&1; then
     glusterfs="yes"
-    glusterfs_cflags=`$pkg_config --cflags glusterfs-api 2>/dev/null`
-    glusterfs_libs=`$pkg_config --libs glusterfs-api 2>/dev/null`
+    glusterfs_cflags=`$pkg_config --cflags glusterfs-api`
+    glusterfs_libs=`$pkg_config --libs glusterfs-api`
     CFLAGS="$CFLAGS $glusterfs_cflags"
     libs_tools="$glusterfs_libs $libs_tools"
     libs_softmmu="$glusterfs_libs $libs_softmmu"
@@ -2962,8 +2962,8 @@ int main(void) { iscsi_unmap_sync(NULL,0,0,0,NULL,0); return 0; }
 EOF
   if $pkg_config --atleast-version=1.7.0 libiscsi --modversion >/dev/null 2>&1; then
     libiscsi="yes"
-    libiscsi_cflags=$($pkg_config --cflags libiscsi 2>/dev/null)
-    libiscsi_libs=$($pkg_config --libs libiscsi 2>/dev/null)
+    libiscsi_cflags=$($pkg_config --cflags libiscsi)
+    libiscsi_libs=$($pkg_config --libs libiscsi)
     CFLAGS="$CFLAGS $libiscsi_cflags"
     LIBS="$LIBS $libiscsi_libs"
   elif compile_prog "" "-liscsi" ; then
@@ -3085,8 +3085,8 @@ if test "$libusb" != "no" ; then
     if $pkg_config --atleast-version=1.0.13 libusb-1.0 >/dev/null 2>&1 ; then
         libusb="yes"
 	usb="libusb"
-        libusb_cflags=$($pkg_config --cflags libusb-1.0 2>/dev/null)
-        libusb_libs=$($pkg_config --libs libusb-1.0 2>/dev/null)
+        libusb_cflags=$($pkg_config --cflags libusb-1.0)
+        libusb_libs=$($pkg_config --libs libusb-1.0)
         QEMU_CFLAGS="$QEMU_CFLAGS $libusb_cflags"
         libs_softmmu="$libs_softmmu $libusb_libs"
     else
@@ -3101,8 +3101,8 @@ fi
 if test "$usb_redir" != "no" ; then
     if $pkg_config --atleast-version=0.6 libusbredirparser-0.5 >/dev/null 2>&1 ; then
         usb_redir="yes"
-        usb_redir_cflags=$($pkg_config --cflags libusbredirparser-0.5 2>/dev/null)
-        usb_redir_libs=$($pkg_config --libs libusbredirparser-0.5 2>/dev/null)
+        usb_redir_cflags=$($pkg_config --cflags libusbredirparser-0.5)
+        usb_redir_libs=$($pkg_config --libs libusbredirparser-0.5)
         QEMU_CFLAGS="$QEMU_CFLAGS $usb_redir_cflags"
         libs_softmmu="$libs_softmmu $usb_redir_libs"
     else
commit 1d984a67a95d88f3e708b077dab8adeb47c38c93
Author: Stefan Weil <sw at weilnetz.de>
Date:   Tue Aug 27 15:12:41 2013 +0200

    configure: Don't write .pyc files by default (python -B)
    
    When a Python script is run, Python normally writes bytecode into a .pyc file.
    QEMU's build process uses several Python scripts which are called from
    configure or make.
    
    The generated .pyc files take disk space without being of much use, because
    those scripts are short, not time critical and only called a few times.
    
    Python's option -B disables writing of .pyc files. QEMU now uses "python -B"
    as default, but it is still possible to choose a different call by passing
    --python=PYTHON to configure.
    
    Signed-off-by: Stefan Weil <sw at weilnetz.de>
    Signed-off-by: Michael Tokarev <mjt at tls.msk.ru>

diff --git a/configure b/configure
index 03157c7..391b204 100755
--- a/configure
+++ b/configure
@@ -568,7 +568,7 @@ fi
 
 : ${make=${MAKE-make}}
 : ${install=${INSTALL-install}}
-: ${python=${PYTHON-python}}
+: ${python=${PYTHON-python -B}}
 : ${smbd=${SMBD-/usr/sbin/smbd}}
 
 # Default objcc to clang if available, otherwise use CC
@@ -1349,7 +1349,7 @@ fi
 
 # Note that if the Python conditional here evaluates True we will exit
 # with status 1 which is a shell 'false' value.
-if ! "$python" -c 'import sys; sys.exit(sys.version_info < (2,4) or sys.version_info >= (3,))'; then
+if ! $python -c 'import sys; sys.exit(sys.version_info < (2,4) or sys.version_info >= (3,))'; then
   error_exit "Cannot use '$python', Python 2.4 or later is required." \
       "Note that Python 3 or later is not yet supported." \
       "Use --python=/path/to/python to specify a supported Python."
commit 5b21a2ae4dea72d9aa68e0385fc0548971e929f4
Author: Stefan Hajnoczi <stefanha at redhat.com>
Date:   Mon Aug 26 13:38:50 2013 +0200

    curl: qemu_bh_new() can never return NULL
    
    Drop error code path which cannot be taken since qemu_bh_new() does not
    return NULL.
    
    Signed-off-by: Stefan Hajnoczi <stefanha at redhat.com>
    Reviewed-by: Paolo Bonzini <pbonzini at redhat.com>
    Signed-off-by: Michael Tokarev <mjt at tls.msk.ru>

diff --git a/block/curl.c b/block/curl.c
index e566855..ca2cedc 100644
--- a/block/curl.c
+++ b/block/curl.c
@@ -572,12 +572,6 @@ static BlockDriverAIOCB *curl_aio_readv(BlockDriverState *bs,
     acb->nb_sectors = nb_sectors;
 
     acb->bh = qemu_bh_new(curl_readv_bh_cb, acb);
-
-    if (!acb->bh) {
-        DPRINTF("CURL: qemu_bh_new failed\n");
-        return NULL;
-    }
-
     qemu_bh_schedule(acb->bh);
     return &acb->common;
 }
commit ed6bc28e8a448b9005af50eed12893c5f7711c6e
Author: Peter Maydell <peter.maydell at linaro.org>
Date:   Fri Aug 23 17:36:48 2013 +0100

    slirp/arp_table.c: Avoid shifting into sign bit of signed integers
    
    "0xf << 28" shifts right into the sign bit, since 0xf is a signed
    integer. Use the 'U' suffix to force an unsigned shift to avoid
    this undefined behaviour and a clang sanitizer warning.
    
    Signed-off-by: Peter Maydell <peter.maydell at linaro.org>
    Reviewed-by: Eric Blake <eblake at redhat.com>
    Acked-by: Jan Kiszka <jan.kiszka at siemens.com>
    Signed-off-by: Michael Tokarev <mjt at tls.msk.ru>

diff --git a/slirp/arp_table.c b/slirp/arp_table.c
index bf698c1..ecdb0ba 100644
--- a/slirp/arp_table.c
+++ b/slirp/arp_table.c
@@ -38,7 +38,7 @@ void arp_table_add(Slirp *slirp, uint32_t ip_addr, uint8_t ethaddr[ETH_ALEN])
                 ethaddr[3], ethaddr[4], ethaddr[5]));
 
     /* Check 0.0.0.0/8 invalid source-only addresses */
-    if ((ip_addr & htonl(~(0xf << 28))) == 0) {
+    if ((ip_addr & htonl(~(0xfU << 28))) == 0) {
         return;
     }
 
@@ -74,7 +74,7 @@ bool arp_table_search(Slirp *slirp, uint32_t ip_addr,
     DEBUG_ARG("ip = 0x%x", ip_addr);
 
     /* Check 0.0.0.0/8 invalid source-only addresses */
-    assert((ip_addr & htonl(~(0xf << 28))) != 0);
+    assert((ip_addr & htonl(~(0xfU << 28))) != 0);
 
     /* If broadcast address */
     if (ip_addr == 0xffffffff || ip_addr == broadcast_addr) {
commit 714290979abf551d5116346e4fbd3d54eb24bd12
Author: Peter Maydell <peter.maydell at linaro.org>
Date:   Mon Aug 5 20:16:40 2013 +0100

    configure: disable clang -Wstring-plus-int warning
    
    Some versions of clang will warn about adding integers to strings:
    
    disas/i386.c:4753:23: error: adding 'char' to a string does not append
          to the string [-Werror,-Wstring-plus-int]
          oappend ("%es:" + intel_syntax);
                   ~~~~~~~^~~~~~~~~~~~~~
    disas/i386.c:4753:23: note: use array indexing to silence this warning
          oappend ("%es:" + intel_syntax);
                          ^
                   &      [             ]
    
    disas/i386.c uses this idiom to to skip a "%" prefix if using intel
    rather than AT&T syntax. This seems like a reasonable  thing to do,
    and I don't think anybody contributing to QEMU is likely to believe
    that '+' is a string concatenation operator in C, so just disable
    -Wstring-plus-int.
    
    Signed-off-by: Peter Maydell <peter.maydell at linaro.org>
    Signed-off-by: Michael Tokarev <mjt at tls.msk.ru>

diff --git a/configure b/configure
index 0a55c20..03157c7 100755
--- a/configure
+++ b/configure
@@ -1204,6 +1204,7 @@ gcc_flags="-Wformat-security -Wformat-y2k -Winit-self -Wignored-qualifiers $gcc_
 gcc_flags="-Wmissing-include-dirs -Wempty-body -Wnested-externs $gcc_flags"
 gcc_flags="-Wendif-labels $gcc_flags"
 gcc_flags="-Wno-initializer-overrides $gcc_flags"
+gcc_flags="-Wno-string-plus-int $gcc_flags"
 # Note that we do not add -Werror to gcc_flags here, because that would
 # enable it for all configure tests. If a configure test failed due
 # to -Werror this would just silently disable some features,
commit c89aa2f1851b08c3efa8a1070c0a6b9a36e1227f
Author: Michael R. Hines <mrhines at us.ibm.com>
Date:   Sun Aug 18 22:27:08 2013 -0400

    rdma: silly ipv6 bugfix
    
    My bad - but it's very important for us to warn the user that
    IPv6 is broken on RoCE in linux right now, until linux releases
    a fixed version.
    
    Signed-off-by: Michael R. Hines <mrhines at us.ibm.com>
    Signed-off-by: Michael Tokarev <mjt at tls.msk.ru>

diff --git a/migration-rdma.c b/migration-rdma.c
index f540366..05a155b 100644
--- a/migration-rdma.c
+++ b/migration-rdma.c
@@ -920,9 +920,11 @@ static int qemu_rdma_resolve_host(RDMAContext *rdma, Error **errp)
         ret = rdma_resolve_addr(rdma->cm_id, NULL, e->ai_dst_addr,
                 RDMA_RESOLVE_TIMEOUT_MS);
         if (!ret) {
-            ret = qemu_rdma_broken_ipv6_kernel(errp, rdma->cm_id->verbs);
-            if (ret) {
-                continue;
+            if (e->ai_family == AF_INET6) {
+                ret = qemu_rdma_broken_ipv6_kernel(errp, rdma->cm_id->verbs);
+                if (ret) {
+                    continue;
+                }
             }
             goto route;
         }
commit 4c293dc6e4cf0421e13870962e1e8ccbb810b2a6
Author: Stefan Weil <sw at weilnetz.de>
Date:   Sun Aug 18 19:40:06 2013 +0200

    misc: Fix some typos in names and comments
    
    Most typos were found using a modified version of codespell:
    
    accross -> across
    issueing -> issuing
    TICNT_THRESHHOLD -> TICNT_THRESHOLD
    bandwith -> bandwidth
    VCARD_7816_PROPIETARY -> VCARD_7816_PROPRIETARY
    occured -> occurred
    gaurantee -> guarantee
    sofware -> software
    
    Signed-off-by: Stefan Weil <sw at weilnetz.de>
    Signed-off-by: Michael Tokarev <mjt at tls.msk.ru>

diff --git a/block/backup.c b/block/backup.c
index e12b3b1..23c7264 100644
--- a/block/backup.c
+++ b/block/backup.c
@@ -290,7 +290,7 @@ static void coroutine_fn backup_run(void *opaque)
 
                 for (i = 0; i < BACKUP_SECTORS_PER_CLUSTER;) {
                     /* bdrv_co_is_allocated() only returns true/false based
-                     * on the first set of sectors it comes accross that
+                     * on the first set of sectors it comes across that
                      * are are all in the same state.
                      * For that reason we must verify each sector in the
                      * backup cluster length.  We end up copying more than
diff --git a/hw/s390x/css.c b/hw/s390x/css.c
index 93b0b97..101da63 100644
--- a/hw/s390x/css.c
+++ b/hw/s390x/css.c
@@ -124,7 +124,7 @@ static void sch_handle_clear_func(SubchDev *sch)
     /* Path management: In our simple css, we always choose the only path. */
     path = 0x80;
 
-    /* Reset values prior to 'issueing the clear signal'. */
+    /* Reset values prior to 'issuing the clear signal'. */
     p->lpum = 0;
     p->pom = 0xff;
     s->flags &= ~SCSW_FLAGS_MASK_PNO;
diff --git a/hw/timer/exynos4210_rtc.c b/hw/timer/exynos4210_rtc.c
index 3f2c8c5..026f81a 100644
--- a/hw/timer/exynos4210_rtc.c
+++ b/hw/timer/exynos4210_rtc.c
@@ -67,7 +67,7 @@
 #define     CURTICNT        0x0090
 
 #define     TICK_TIMER_ENABLE   0x0100
-#define     TICNT_THRESHHOLD    2
+#define     TICNT_THRESHOLD     2
 
 
 #define     RTC_ENABLE          0x0001
@@ -429,7 +429,7 @@ static void exynos4210_rtc_write(void *opaque, hwaddr offset,
         s->reg_rtccon = value;
         break;
     case TICCNT:
-        if (value > TICNT_THRESHHOLD) {
+        if (value > TICNT_THRESHOLD) {
             s->reg_ticcnt = value;
         } else {
             fprintf(stderr,
diff --git a/include/hw/bt.h b/include/hw/bt.h
index 830af94..3f365bc 100644
--- a/include/hw/bt.h
+++ b/include/hw/bt.h
@@ -640,8 +640,8 @@ typedef struct {
 #define OCF_SETUP_SYNC_CONN		0x0028
 typedef struct {
     uint16_t	handle;
-    uint32_t	tx_bandwith;
-    uint32_t	rx_bandwith;
+    uint32_t	tx_bandwidth;
+    uint32_t	rx_bandwidth;
     uint16_t	max_latency;
     uint16_t	voice_setting;
     uint8_t	retrans_effort;
@@ -652,8 +652,8 @@ typedef struct {
 #define OCF_ACCEPT_SYNC_CONN_REQ	0x0029
 typedef struct {
     bdaddr_t	bdaddr;
-    uint32_t	tx_bandwith;
-    uint32_t	rx_bandwith;
+    uint32_t	tx_bandwidth;
+    uint32_t	rx_bandwidth;
     uint16_t	max_latency;
     uint16_t	voice_setting;
     uint8_t	retrans_effort;
diff --git a/libcacard/card_7816.c b/libcacard/card_7816.c
index 8d06326..c28bb60 100644
--- a/libcacard/card_7816.c
+++ b/libcacard/card_7816.c
@@ -232,7 +232,7 @@ vcard_apdu_set_class(VCardAPDU *apdu) {
     case 0xf0:
     default:
         apdu->a_gen_type =
-            (apdu->a_cla == 0xff) ? VCARD_7816_PTS : VCARD_7816_PROPIETARY;
+            (apdu->a_cla == 0xff) ? VCARD_7816_PTS : VCARD_7816_PROPRIETARY;
         break;
     }
     return VCARD7816_STATUS_SUCCESS;
diff --git a/libcacard/card_7816t.h b/libcacard/card_7816t.h
index 9333285..8eef0ce 100644
--- a/libcacard/card_7816t.h
+++ b/libcacard/card_7816t.h
@@ -43,7 +43,7 @@ typedef enum {
     VCARD_7816_ISO,
     VCARD_7816_RFU,
     VCARD_7816_PTS,
-    VCARD_7816_PROPIETARY
+    VCARD_7816_PROPRIETARY
 } VCardAPDUType;
 
 
diff --git a/linux-headers/asm-powerpc/epapr_hcalls.h b/linux-headers/asm-powerpc/epapr_hcalls.h
index 06f7247..33b3f89 100644
--- a/linux-headers/asm-powerpc/epapr_hcalls.h
+++ b/linux-headers/asm-powerpc/epapr_hcalls.h
@@ -78,7 +78,7 @@
 #define EV_SUCCESS		0
 #define EV_EPERM		1	/* Operation not permitted */
 #define EV_ENOENT		2	/*  Entry Not Found */
-#define EV_EIO			3	/* I/O error occured */
+#define EV_EIO			3	/* I/O error occurred */
 #define EV_EAGAIN		4	/* The operation had insufficient
 					 * resources to complete and should be
 					 * retried
@@ -89,7 +89,7 @@
 #define EV_ENODEV		7	/* No such device */
 #define EV_EINVAL		8	/* An argument supplied to the hcall
 					   was out of range or invalid */
-#define EV_INTERNAL		9	/* An internal error occured */
+#define EV_INTERNAL		9	/* An internal error occurred */
 #define EV_CONFIG		10	/* A configuration error was detected */
 #define EV_INVALID_STATE	11	/* The object is in an invalid state */
 #define EV_UNIMPLEMENTED	12	/* Unimplemented hypercall */
diff --git a/migration-rdma.c b/migration-rdma.c
index 3d1266f..f540366 100644
--- a/migration-rdma.c
+++ b/migration-rdma.c
@@ -756,7 +756,7 @@ static void qemu_rdma_dump_gid(const char *who, struct rdma_cm_id *id)
  * connections (both IPv4 and IPv6) if the destination machine does not have
  * a regular infiniband network available for use.
  *
- * The only way to gaurantee that an error is thrown for broken kernels is
+ * The only way to guarantee that an error is thrown for broken kernels is
  * for the management software to choose a *specific* interface at bind time
  * and validate what time of hardware it is.
  *
@@ -778,7 +778,7 @@ static void qemu_rdma_dump_gid(const char *who, struct rdma_cm_id *id)
  * Infiniband. 
  *
  * If we detect that we have a *pure* RoCE environment, then we can safely
- * thrown an error even if the management sofware has specified '[::]' as the
+ * thrown an error even if the management software has specified '[::]' as the
  * bind address.
  *
  * However, if there is are multiple hetergeneous devices, then we cannot make
@@ -801,7 +801,7 @@ static int qemu_rdma_broken_ipv6_kernel(Error **errp, struct ibv_context *verbs)
      * devices (non-ethernet).
      * 
      * If not, then we can safely proceed with the migration.
-     * Otherwise, there are no gaurantees until the bug is fixed in linux.
+     * Otherwise, there are no guarantees until the bug is fixed in linux.
      */
     if (!verbs) {
 	    int num_devices, x;
commit efcb7e45290ecc8633f7c5bdf02ac86f6289fa7d
Author: Taimoor Mirza <tmirza at codesourcery.com>
Date:   Thu Aug 15 23:13:28 2013 +0500

    slirp: Port redirection option behave differently on Linux and Windows
    
    port redirection code uses SO_REUSEADDR socket option before binding to
    host port. Behavior of SO_REUSEADDR is different on Windows and Linux.
    Relaunching QEMU with same host and guest port redirection values on Linux
    throws error but on Windows it does not throw any error.
    Problem is discussed in http://lists.gnu.org/archive/html/qemu-devel/2013-04/msg03089.html
    
    Signed-off-by: Taimoor Mirza <tmirza at codesourcery.com>
    Signed-off-by: Michael Tokarev <mjt at tls.msk.ru>

diff --git a/slirp/socket.c b/slirp/socket.c
index 8e8819c..25d60e7 100644
--- a/slirp/socket.c
+++ b/slirp/socket.c
@@ -627,7 +627,9 @@ tcp_listen(Slirp *slirp, uint32_t haddr, u_int hport, uint32_t laddr,
 	addr.sin_port = hport;
 
 	if (((s = qemu_socket(AF_INET,SOCK_STREAM,0)) < 0) ||
+#ifndef _WIN32
 	    (qemu_setsockopt(s, SOL_SOCKET, SO_REUSEADDR, &opt, sizeof(int)) < 0) ||
+#endif
 	    (bind(s,(struct sockaddr *)&addr, sizeof(addr)) < 0) ||
 	    (listen(s,1) < 0)) {
 		int tmperrno = errno; /* Don't clobber the real reason we failed */
commit 23fe2b3f9e7df8da53ac1bc32c6875254911d7f4
Author: Michael S. Tsirkin <mst at redhat.com>
Date:   Sun Sep 1 11:03:45 2013 +0300

    virtio_pci: fix level interrupts with irqfd
    
    commit 62c96360ae7f2c7a8b029277fbb7cb082fdef7fd
        virtio-pci: fix level interrupts
    only helps systems without irqfd: on systems with irqfd support we
    passed in flag requesting irqfd even when msix is disabled.
    
    As a result, for level interrupts we didn't install an fd handler so
    unmasking an fd had no effect.
    
    Fix this up.
    
    Cc: qemu-stable at nongnu.org
    Signed-off-by: Michael S. Tsirkin <mst at redhat.com>

diff --git a/hw/virtio/virtio-pci.c b/hw/virtio/virtio-pci.c
index d37037e..41b96ce 100644
--- a/hw/virtio/virtio-pci.c
+++ b/hw/virtio/virtio-pci.c
@@ -799,8 +799,7 @@ static int virtio_pci_set_guest_notifiers(DeviceState *d, int nvqs, bool assign)
             break;
         }
 
-        r = virtio_pci_set_guest_notifier(d, n, assign,
-                                          kvm_msi_via_irqfd_enabled());
+        r = virtio_pci_set_guest_notifier(d, n, assign, with_irqfd);
         if (r < 0) {
             goto assign_error;
         }
commit a0dba644c139907ccf6735c505fbd254010d6938
Author: Michael S. Tsirkin <mst at redhat.com>
Date:   Tue Aug 27 09:48:06 2013 +0300

    pc: reduce duplication, fix PIIX descriptions
    
    We have a lot of code duplication between machine types,
    this increases with each new machine type
    and each new field.
    
    This has already introduced a minor bug: description
    for pc-1.3 says "Standard PC" while description for
    pc-1.4 is "Standard PC (i440FX + PIIX, 1996)"
    which makes you think 1.3 is somehow more standard,
    or newer, while in fact it's a revision of the same PC.
    
    This patch addresses this issue by using macros, along
    the lines used by PC_COMPAT_X_X - only for
    non-property options.
    
    The approach can extend to non-PC machine types.
    
    Cc: Paolo Bonzini <pbonzini at redhat.com>
    Signed-off-by: Michael S. Tsirkin <mst at redhat.com>

diff --git a/hw/i386/pc_piix.c b/hw/i386/pc_piix.c
index aa0a39a..275e395 100644
--- a/hw/i386/pc_piix.c
+++ b/hw/i386/pc_piix.c
@@ -334,36 +334,39 @@ static void pc_xen_hvm_init(QEMUMachineInitArgs *args)
 }
 #endif
 
+#define PC_I440FX_MACHINE_OPTIONS \
+    PC_DEFAULT_MACHINE_OPTIONS, \
+    .desc = "Standard PC (i440FX + PIIX, 1996)", \
+    .hot_add_cpu = pc_hot_add_cpu
+
+#define PC_I440FX_1_6_MACHINE_OPTIONS PC_I440FX_MACHINE_OPTIONS
+
 static QEMUMachine pc_i440fx_machine_v1_6 = {
+    PC_I440FX_1_6_MACHINE_OPTIONS,
     .name = "pc-i440fx-1.6",
     .alias = "pc",
-    .desc = "Standard PC (i440FX + PIIX, 1996)",
     .init = pc_init_pci_1_6,
-    .hot_add_cpu = pc_hot_add_cpu,
-    .max_cpus = 255,
     .is_default = 1,
-    .default_boot_order = "cad",
 };
 
 static QEMUMachine pc_i440fx_machine_v1_5 = {
+    PC_I440FX_1_6_MACHINE_OPTIONS,
     .name = "pc-i440fx-1.5",
-    .desc = "Standard PC (i440FX + PIIX, 1996)",
     .init = pc_init_pci_1_5,
-    .hot_add_cpu = pc_hot_add_cpu,
-    .max_cpus = 255,
     .compat_props = (GlobalProperty[]) {
         PC_COMPAT_1_5,
         { /* end of list */ }
     },
-    .default_boot_order = "cad",
 };
 
+#define PC_I440FX_1_4_MACHINE_OPTIONS \
+    PC_I440FX_1_6_MACHINE_OPTIONS, \
+    .hot_add_cpu = NULL
+
 static QEMUMachine pc_i440fx_machine_v1_4 = {
+    PC_I440FX_1_4_MACHINE_OPTIONS,
     .name = "pc-i440fx-1.4",
-    .desc = "Standard PC (i440FX + PIIX, 1996)",
     .init = pc_init_pci_1_4,
-    .max_cpus = 255,
-    .default_boot_order = "cad",
     .compat_props = (GlobalProperty[]) {
         PC_COMPAT_1_4,
         { /* end of list */ }
@@ -391,11 +394,9 @@ static QEMUMachine pc_i440fx_machine_v1_4 = {
         }
 
 static QEMUMachine pc_machine_v1_3 = {
+    PC_I440FX_1_4_MACHINE_OPTIONS,
     .name = "pc-1.3",
-    .desc = "Standard PC",
     .init = pc_init_pci_1_3,
-    .max_cpus = 255,
-    .default_boot_order = "cad",
     .compat_props = (GlobalProperty[]) {
         PC_COMPAT_1_3,
         { /* end of list */ }
@@ -430,12 +431,13 @@ static QEMUMachine pc_machine_v1_3 = {
             .value    = "off",\
         }
 
+#define PC_I440FX_1_2_MACHINE_OPTIONS \
+    PC_I440FX_1_4_MACHINE_OPTIONS, \
+    .init = pc_init_pci_1_2
+
 static QEMUMachine pc_machine_v1_2 = {
+    PC_I440FX_1_2_MACHINE_OPTIONS,
     .name = "pc-1.2",
-    .desc = "Standard PC",
-    .init = pc_init_pci_1_2,
-    .max_cpus = 255,
-    .default_boot_order = "cad",
     .compat_props = (GlobalProperty[]) {
         PC_COMPAT_1_2,
         { /* end of list */ }
@@ -475,11 +477,8 @@ static QEMUMachine pc_machine_v1_2 = {
         }
 
 static QEMUMachine pc_machine_v1_1 = {
+    PC_I440FX_1_2_MACHINE_OPTIONS,
     .name = "pc-1.1",
-    .desc = "Standard PC",
-    .init = pc_init_pci_1_2,
-    .max_cpus = 255,
-    .default_boot_order = "cad",
     .compat_props = (GlobalProperty[]) {
         PC_COMPAT_1_1,
         { /* end of list */ }
@@ -507,11 +506,8 @@ static QEMUMachine pc_machine_v1_1 = {
         }
 
 static QEMUMachine pc_machine_v1_0 = {
+    PC_I440FX_1_2_MACHINE_OPTIONS,
     .name = "pc-1.0",
-    .desc = "Standard PC",
-    .init = pc_init_pci_1_2,
-    .max_cpus = 255,
-    .default_boot_order = "cad",
     .compat_props = (GlobalProperty[]) {
         PC_COMPAT_1_0,
         { /* end of list */ }
@@ -523,11 +519,8 @@ static QEMUMachine pc_machine_v1_0 = {
         PC_COMPAT_1_0
 
 static QEMUMachine pc_machine_v0_15 = {
+    PC_I440FX_1_2_MACHINE_OPTIONS,
     .name = "pc-0.15",
-    .desc = "Standard PC",
-    .init = pc_init_pci_1_2,
-    .max_cpus = 255,
-    .default_boot_order = "cad",
     .compat_props = (GlobalProperty[]) {
         PC_COMPAT_0_15,
         { /* end of list */ }
@@ -556,11 +549,8 @@ static QEMUMachine pc_machine_v0_15 = {
         }
 
 static QEMUMachine pc_machine_v0_14 = {
+    PC_I440FX_1_2_MACHINE_OPTIONS,
     .name = "pc-0.14",
-    .desc = "Standard PC",
-    .init = pc_init_pci_1_2,
-    .max_cpus = 255,
-    .default_boot_order = "cad",
     .compat_props = (GlobalProperty[]) {
         PC_COMPAT_0_14, 
         {
@@ -589,12 +579,13 @@ static QEMUMachine pc_machine_v0_14 = {
             .value    = stringify(1),\
         }
 
+#define PC_I440FX_0_13_MACHINE_OPTIONS \
+    PC_I440FX_1_2_MACHINE_OPTIONS, \
+    .init = pc_init_pci_no_kvmclock
+
 static QEMUMachine pc_machine_v0_13 = {
+    PC_I440FX_0_13_MACHINE_OPTIONS,
     .name = "pc-0.13",
-    .desc = "Standard PC",
-    .init = pc_init_pci_no_kvmclock,
-    .max_cpus = 255,
-    .default_boot_order = "cad",
     .compat_props = (GlobalProperty[]) {
         PC_COMPAT_0_13,
         {
@@ -640,11 +631,8 @@ static QEMUMachine pc_machine_v0_13 = {
         }
 
 static QEMUMachine pc_machine_v0_12 = {
+    PC_I440FX_0_13_MACHINE_OPTIONS,
     .name = "pc-0.12",
-    .desc = "Standard PC",
-    .init = pc_init_pci_no_kvmclock,
-    .max_cpus = 255,
-    .default_boot_order = "cad",
     .compat_props = (GlobalProperty[]) {
         PC_COMPAT_0_12,
         {
@@ -674,11 +662,8 @@ static QEMUMachine pc_machine_v0_12 = {
         }
 
 static QEMUMachine pc_machine_v0_11 = {
+    PC_I440FX_0_13_MACHINE_OPTIONS,
     .name = "pc-0.11",
-    .desc = "Standard PC, qemu 0.11",
-    .init = pc_init_pci_no_kvmclock,
-    .max_cpus = 255,
-    .default_boot_order = "cad",
     .compat_props = (GlobalProperty[]) {
         PC_COMPAT_0_11,
         {
@@ -696,11 +681,8 @@ static QEMUMachine pc_machine_v0_11 = {
 };
 
 static QEMUMachine pc_machine_v0_10 = {
+    PC_I440FX_0_13_MACHINE_OPTIONS,
     .name = "pc-0.10",
-    .desc = "Standard PC, qemu 0.10",
-    .init = pc_init_pci_no_kvmclock,
-    .max_cpus = 255,
-    .default_boot_order = "cad",
     .compat_props = (GlobalProperty[]) {
         PC_COMPAT_0_11,
         {
@@ -730,11 +712,11 @@ static QEMUMachine pc_machine_v0_10 = {
 };
 
 static QEMUMachine isapc_machine = {
+    PC_COMMON_MACHINE_OPTIONS,
     .name = "isapc",
     .desc = "ISA-only PC",
     .init = pc_init_isa,
     .max_cpus = 1,
-    .default_boot_order = "cad",
     .compat_props = (GlobalProperty[]) {
         { /* end of list */ }
     },
@@ -742,12 +724,12 @@ static QEMUMachine isapc_machine = {
 
 #ifdef CONFIG_XEN
 static QEMUMachine xenfv_machine = {
+    PC_COMMON_MACHINE_OPTIONS,
     .name = "xenfv",
     .desc = "Xen Fully-virtualized PC",
     .init = pc_xen_hvm_init,
     .max_cpus = HVM_MAX_VCPUS,
     .default_machine_opts = "accel=xen",
-    .default_boot_order = "cad",
 };
 #endif
 
diff --git a/hw/i386/pc_q35.c b/hw/i386/pc_q35.c
index 291ad97..d7b7c3b 100644
--- a/hw/i386/pc_q35.c
+++ b/hw/i386/pc_q35.c
@@ -253,35 +253,38 @@ static void pc_q35_init_1_4(QEMUMachineInitArgs *args)
     pc_q35_init(args);
 }
 
+#define PC_Q35_MACHINE_OPTIONS \
+    PC_DEFAULT_MACHINE_OPTIONS, \
+    .desc = "Standard PC (Q35 + ICH9, 2009)", \
+    .hot_add_cpu = pc_hot_add_cpu
+
+#define PC_Q35_1_6_MACHINE_OPTIONS PC_Q35_MACHINE_OPTIONS
+
 static QEMUMachine pc_q35_machine_v1_6 = {
+    PC_Q35_1_6_MACHINE_OPTIONS,
     .name = "pc-q35-1.6",
     .alias = "q35",
-    .desc = "Standard PC (Q35 + ICH9, 2009)",
     .init = pc_q35_init_1_6,
-    .hot_add_cpu = pc_hot_add_cpu,
-    .max_cpus = 255,
-    .default_boot_order = "cad",
 };
 
 static QEMUMachine pc_q35_machine_v1_5 = {
+    PC_Q35_1_6_MACHINE_OPTIONS,
     .name = "pc-q35-1.5",
-    .desc = "Standard PC (Q35 + ICH9, 2009)",
     .init = pc_q35_init_1_5,
-    .hot_add_cpu = pc_hot_add_cpu,
-    .max_cpus = 255,
-    .default_boot_order = "cad",
     .compat_props = (GlobalProperty[]) {
         PC_COMPAT_1_5,
         { /* end of list */ }
     },
 };
 
+#define PC_Q35_1_4_MACHINE_OPTIONS \
+    PC_Q35_1_6_MACHINE_OPTIONS, \
+    .hot_add_cpu = NULL
+
 static QEMUMachine pc_q35_machine_v1_4 = {
+    PC_Q35_1_4_MACHINE_OPTIONS,
     .name = "pc-q35-1.4",
-    .desc = "Standard PC (Q35 + ICH9, 2009)",
     .init = pc_q35_init_1_4,
-    .max_cpus = 255,
-    .default_boot_order = "cad",
     .compat_props = (GlobalProperty[]) {
         PC_COMPAT_1_4,
         { /* end of list */ }
diff --git a/include/hw/i386/pc.h b/include/hw/i386/pc.h
index 475ba9e..7fb04d8 100644
--- a/include/hw/i386/pc.h
+++ b/include/hw/i386/pc.h
@@ -325,4 +325,12 @@ int e820_add_entry(uint64_t, uint64_t, uint32_t);
             .value    = stringify(0),\
         }
 
+#define PC_COMMON_MACHINE_OPTIONS \
+    .default_boot_order = "cad"
+
+#define PC_DEFAULT_MACHINE_OPTIONS \
+    PC_COMMON_MACHINE_OPTIONS, \
+    .hot_add_cpu = pc_hot_add_cpu, \
+    .max_cpus = 255
+
 #endif
commit 520902a656f21bdd4f212bfa55bc35c3e567affc
Author: Hervé Poussineau <hpoussin at reactos.org>
Date:   Tue Aug 13 12:38:34 2013 +0200

    isa: Fix documentation of isa_register_portio_list()
    
    Commit b40acf9 (ioport: Switch dispatching to memory core layer,
    2013-06-24) removed all instances of old_portio.
    
    Signed-off-by: Hervé Poussineau <hpoussin at reactos.org>
    Acked-by: Paolo Bonzini <pbonzini at redhat.com>
    Signed-off-by: Andreas Färber <afaerber at suse.de>

diff --git a/include/hw/isa/isa.h b/include/hw/isa/isa.h
index 495bcf3..fa45a5b 100644
--- a/include/hw/isa/isa.h
+++ b/include/hw/isa/isa.h
@@ -78,7 +78,7 @@ void isa_register_ioport(ISADevice *dev, MemoryRegion *io, uint16_t start);
  * @dev: the ISADevice against which these are registered; may be NULL.
  * @start: the base I/O port against which the portio->offset is applied.
  * @portio: the ports, sorted by offset.
- * @opaque: passed into the old_portio callbacks.
+ * @opaque: passed into the portio callbacks.
  * @name: passed into memory_region_init_io.
  */
 void isa_register_portio_list(ISADevice *dev, uint16_t start,
commit 5b9237f67c499fa4e20bb9bd29c7ce54afe79cb7
Author: Andreas Färber <afaerber at suse.de>
Date:   Fri Aug 30 18:28:37 2013 +0200

    qom: Assert instance size in object_initialize_with_type()
    
    This catches objects initializing beyond allocated memory, e.g.,
    when subtypes get extended with instance state of their own.
    
    Suggested-by: Peter Maydell <peter.maydell at linaro.org>
    Signed-off-by: Andreas Färber <afaerber at suse.de>

diff --git a/include/qom/object.h b/include/qom/object.h
index 13847fb..1a7b71a 100644
--- a/include/qom/object.h
+++ b/include/qom/object.h
@@ -586,13 +586,14 @@ Object *object_new_with_type(Type type);
 /**
  * object_initialize_with_type:
  * @data: A pointer to the memory to be used for the object.
+ * @size: The maximum size available at @data for the object.
  * @type: The type of the object to instantiate.
  *
  * This function will initialize an object.  The memory for the object should
  * have already been allocated.  The returned object has a reference count of 1,
  * and will be finalized when the last reference is dropped.
  */
-void object_initialize_with_type(void *data, Type type);
+void object_initialize_with_type(void *data, size_t size, Type type);
 
 /**
  * object_initialize:
diff --git a/qom/object.c b/qom/object.c
index 1635422..e90e382 100644
--- a/qom/object.c
+++ b/qom/object.c
@@ -311,7 +311,7 @@ static void object_post_init_with_type(Object *obj, TypeImpl *ti)
     }
 }
 
-void object_initialize_with_type(void *data, TypeImpl *type)
+void object_initialize_with_type(void *data, size_t size, TypeImpl *type)
 {
     Object *obj = data;
 
@@ -320,6 +320,7 @@ void object_initialize_with_type(void *data, TypeImpl *type)
 
     g_assert(type->instance_size >= sizeof(Object));
     g_assert(type->abstract == false);
+    g_assert(size >= type->instance_size);
 
     memset(obj, 0, type->instance_size);
     obj->class = type->class;
@@ -333,7 +334,7 @@ void object_initialize(void *data, size_t size, const char *typename)
 {
     TypeImpl *type = type_get_by_name(typename);
 
-    object_initialize_with_type(data, type);
+    object_initialize_with_type(data, size, type);
 }
 
 static inline bool object_property_is_child(ObjectProperty *prop)
@@ -424,7 +425,7 @@ Object *object_new_with_type(Type type)
     type_initialize(type);
 
     obj = g_malloc(type->instance_size);
-    object_initialize_with_type(obj, type);
+    object_initialize_with_type(obj, type->instance_size, type);
     obj->free = g_free;
 
     return obj;
commit 213f0c4f619dda7a56612353009e6f30d3348206
Author: Andreas Färber <afaerber at suse.de>
Date:   Fri Aug 23 19:37:12 2013 +0200

    qom: Pass available size to object_initialize()
    
    To be passed on to object_initialize_with_type().
    
    Acked-by: Cornelia Huck <cornelia.huck at de.ibm.com> (virtio-ccw)
    Signed-off-by: Andreas Färber <afaerber at suse.de>

diff --git a/hw/core/qdev.c b/hw/core/qdev.c
index 81874da..533f6dd 100644
--- a/hw/core/qdev.c
+++ b/hw/core/qdev.c
@@ -473,7 +473,7 @@ static void bus_unparent(Object *obj)
 void qbus_create_inplace(void *bus, size_t size, const char *typename,
                          DeviceState *parent, const char *name)
 {
-    object_initialize(bus, typename);
+    object_initialize(bus, size, typename);
     qbus_realize(bus, parent, name);
 }
 
diff --git a/hw/dma/xilinx_axidma.c b/hw/dma/xilinx_axidma.c
index 59e8e35..d67c5f1 100644
--- a/hw/dma/xilinx_axidma.c
+++ b/hw/dma/xilinx_axidma.c
@@ -579,8 +579,10 @@ static void xilinx_axidma_init(Object *obj)
                              (Object **) &s->tx_control_dev, &errp);
     assert_no_error(errp);
 
-    object_initialize(&s->rx_data_dev, TYPE_XILINX_AXI_DMA_DATA_STREAM);
-    object_initialize(&s->rx_control_dev, TYPE_XILINX_AXI_DMA_CONTROL_STREAM);
+    object_initialize(&s->rx_data_dev, sizeof(s->rx_data_dev),
+                      TYPE_XILINX_AXI_DMA_DATA_STREAM);
+    object_initialize(&s->rx_control_dev, sizeof(s->rx_control_dev),
+                      TYPE_XILINX_AXI_DMA_CONTROL_STREAM);
     object_property_add_child(OBJECT(s), "axistream-connected-target",
                               (Object *)&s->rx_data_dev, &errp);
     assert_no_error(errp);
diff --git a/hw/intc/xics.c b/hw/intc/xics.c
index 6b3c071..b96b041 100644
--- a/hw/intc/xics.c
+++ b/hw/intc/xics.c
@@ -650,7 +650,7 @@ static void xics_realize(DeviceState *dev, Error **errp)
     icp->ss = g_malloc0(icp->nr_servers*sizeof(ICPState));
     for (i = 0; i < icp->nr_servers; i++) {
         char buffer[32];
-        object_initialize(&icp->ss[i], TYPE_ICP);
+        object_initialize(&icp->ss[i], sizeof(icp->ss[i]), TYPE_ICP);
         snprintf(buffer, sizeof(buffer), "icp[%d]", i);
         object_property_add_child(OBJECT(icp), buffer, OBJECT(&icp->ss[i]), NULL);
         qdev_init_nofail(DEVICE(&icp->ss[i]));
diff --git a/hw/misc/macio/macio.c b/hw/misc/macio/macio.c
index 9cc33d8..7f99aa0 100644
--- a/hw/misc/macio/macio.c
+++ b/hw/misc/macio/macio.c
@@ -202,11 +202,12 @@ static int macio_oldworld_initfn(PCIDevice *d)
     return 0;
 }
 
-static void macio_init_ide(MacIOState *s, MACIOIDEState *ide, int index)
+static void macio_init_ide(MacIOState *s, MACIOIDEState *ide, size_t ide_size,
+                           int index)
 {
     gchar *name;
 
-    object_initialize(ide, TYPE_MACIO_IDE);
+    object_initialize(ide, ide_size, TYPE_MACIO_IDE);
     qdev_set_parent_bus(DEVICE(ide), sysbus_get_default());
     memory_region_add_subregion(&s->bar, 0x1f000 + ((index + 1) * 0x1000),
                                 &ide->mem);
@@ -224,13 +225,13 @@ static void macio_oldworld_init(Object *obj)
 
     qdev_init_gpio_out(DEVICE(obj), os->irqs, ARRAY_SIZE(os->irqs));
 
-    object_initialize(&os->nvram, TYPE_MACIO_NVRAM);
+    object_initialize(&os->nvram, sizeof(os->nvram), TYPE_MACIO_NVRAM);
     dev = DEVICE(&os->nvram);
     qdev_prop_set_uint32(dev, "size", 0x2000);
     qdev_prop_set_uint32(dev, "it_shift", 4);
 
     for (i = 0; i < 2; i++) {
-        macio_init_ide(s, &os->ide[i], i);
+        macio_init_ide(s, &os->ide[i], sizeof(os->ide[i]), i);
     }
 }
 
@@ -310,7 +311,7 @@ static void macio_newworld_init(Object *obj)
     qdev_init_gpio_out(DEVICE(obj), ns->irqs, ARRAY_SIZE(ns->irqs));
 
     for (i = 0; i < 2; i++) {
-        macio_init_ide(s, &ns->ide[i], i);
+        macio_init_ide(s, &ns->ide[i], sizeof(ns->ide[i]), i);
     }
 }
 
@@ -321,7 +322,7 @@ static void macio_instance_init(Object *obj)
 
     memory_region_init(&s->bar, NULL, "macio", 0x80000);
 
-    object_initialize(&s->cuda, TYPE_CUDA);
+    object_initialize(&s->cuda, sizeof(s->cuda), TYPE_CUDA);
     qdev_set_parent_bus(DEVICE(&s->cuda), sysbus_get_default());
     object_property_add_child(obj, "cuda", OBJECT(&s->cuda), NULL);
 
diff --git a/hw/net/xilinx_axienet.c b/hw/net/xilinx_axienet.c
index f173429..3eb7715 100644
--- a/hw/net/xilinx_axienet.c
+++ b/hw/net/xilinx_axienet.c
@@ -990,8 +990,10 @@ static void xilinx_enet_init(Object *obj)
                              (Object **) &s->tx_control_dev, &errp);
     assert_no_error(errp);
 
-    object_initialize(&s->rx_data_dev, TYPE_XILINX_AXI_ENET_DATA_STREAM);
-    object_initialize(&s->rx_control_dev, TYPE_XILINX_AXI_ENET_CONTROL_STREAM);
+    object_initialize(&s->rx_data_dev, sizeof(s->rx_data_dev),
+                      TYPE_XILINX_AXI_ENET_DATA_STREAM);
+    object_initialize(&s->rx_control_dev, sizeof(s->rx_control_dev),
+                      TYPE_XILINX_AXI_ENET_CONTROL_STREAM);
     object_property_add_child(OBJECT(s), "axistream-connected-target",
                               (Object *)&s->rx_data_dev, &errp);
     assert_no_error(errp);
diff --git a/hw/pci-host/prep.c b/hw/pci-host/prep.c
index a62236b..0e71fdb 100644
--- a/hw/pci-host/prep.c
+++ b/hw/pci-host/prep.c
@@ -159,7 +159,7 @@ static void raven_pcihost_initfn(Object *obj)
                         address_space_mem, address_space_io, 0, TYPE_PCI_BUS);
     h->bus = &s->pci_bus;
 
-    object_initialize(&s->pci_dev, TYPE_RAVEN_PCI_DEVICE);
+    object_initialize(&s->pci_dev, sizeof(s->pci_dev), TYPE_RAVEN_PCI_DEVICE);
     pci_dev = DEVICE(&s->pci_dev);
     qdev_set_parent_bus(pci_dev, BUS(&s->pci_bus));
     object_property_set_int(OBJECT(&s->pci_dev), PCI_DEVFN(0, 0), "addr",
diff --git a/hw/pci-host/q35.c b/hw/pci-host/q35.c
index 12314d8..e7d9712 100644
--- a/hw/pci-host/q35.c
+++ b/hw/pci-host/q35.c
@@ -133,7 +133,7 @@ static void q35_host_initfn(Object *obj)
     memory_region_init_io(&phb->data_mem, obj, &pci_host_data_le_ops, phb,
                           "pci-conf-data", 4);
 
-    object_initialize(&s->mch, TYPE_MCH_PCI_DEVICE);
+    object_initialize(&s->mch, sizeof(s->mch), TYPE_MCH_PCI_DEVICE);
     object_property_add_child(OBJECT(s), "mch", OBJECT(&s->mch), NULL);
     qdev_prop_set_uint32(DEVICE(&s->mch), "addr", PCI_DEVFN(0, 0));
     qdev_prop_set_bit(DEVICE(&s->mch), "multifunction", false);
diff --git a/hw/pci-host/versatile.c b/hw/pci-host/versatile.c
index 4b9359c..6b28929 100644
--- a/hw/pci-host/versatile.c
+++ b/hw/pci-host/versatile.c
@@ -389,7 +389,7 @@ static void pci_vpb_init(Object *obj)
                         PCI_DEVFN(11, 0), TYPE_PCI_BUS);
     h->bus = &s->pci_bus;
 
-    object_initialize(&s->pci_dev, TYPE_VERSATILE_PCI_HOST);
+    object_initialize(&s->pci_dev, sizeof(s->pci_dev), TYPE_VERSATILE_PCI_HOST);
     qdev_set_parent_bus(DEVICE(&s->pci_dev), BUS(&s->pci_bus));
 
     /* Window sizes for VersatilePB; realview_pci's init will override */
diff --git a/hw/s390x/s390-virtio-bus.c b/hw/s390x/s390-virtio-bus.c
index f68341a..6a83111 100644
--- a/hw/s390x/s390-virtio-bus.c
+++ b/hw/s390x/s390-virtio-bus.c
@@ -171,7 +171,7 @@ static int s390_virtio_net_init(VirtIOS390Device *s390_dev)
 static void s390_virtio_net_instance_init(Object *obj)
 {
     VirtIONetS390 *dev = VIRTIO_NET_S390(obj);
-    object_initialize(&dev->vdev, TYPE_VIRTIO_NET);
+    object_initialize(&dev->vdev, sizeof(dev->vdev), TYPE_VIRTIO_NET);
     object_property_add_child(obj, "virtio-backend", OBJECT(&dev->vdev), NULL);
 }
 
@@ -190,7 +190,7 @@ static int s390_virtio_blk_init(VirtIOS390Device *s390_dev)
 static void s390_virtio_blk_instance_init(Object *obj)
 {
     VirtIOBlkS390 *dev = VIRTIO_BLK_S390(obj);
-    object_initialize(&dev->vdev, TYPE_VIRTIO_BLK);
+    object_initialize(&dev->vdev, sizeof(dev->vdev), TYPE_VIRTIO_BLK);
     object_property_add_child(obj, "virtio-backend", OBJECT(&dev->vdev), NULL);
 }
 
@@ -231,7 +231,7 @@ static int s390_virtio_serial_init(VirtIOS390Device *s390_dev)
 static void s390_virtio_serial_instance_init(Object *obj)
 {
     VirtIOSerialS390 *dev = VIRTIO_SERIAL_S390(obj);
-    object_initialize(&dev->vdev, TYPE_VIRTIO_SERIAL);
+    object_initialize(&dev->vdev, sizeof(dev->vdev), TYPE_VIRTIO_SERIAL);
     object_property_add_child(obj, "virtio-backend", OBJECT(&dev->vdev), NULL);
 }
 
@@ -263,7 +263,7 @@ static int s390_virtio_scsi_init(VirtIOS390Device *s390_dev)
 static void s390_virtio_scsi_instance_init(Object *obj)
 {
     VirtIOSCSIS390 *dev = VIRTIO_SCSI_S390(obj);
-    object_initialize(&dev->vdev, TYPE_VIRTIO_SCSI);
+    object_initialize(&dev->vdev, sizeof(dev->vdev), TYPE_VIRTIO_SCSI);
     object_property_add_child(obj, "virtio-backend", OBJECT(&dev->vdev), NULL);
 }
 
@@ -284,7 +284,7 @@ static int s390_vhost_scsi_init(VirtIOS390Device *s390_dev)
 static void s390_vhost_scsi_instance_init(Object *obj)
 {
     VHostSCSIS390 *dev = VHOST_SCSI_S390(obj);
-    object_initialize(&dev->vdev, TYPE_VHOST_SCSI);
+    object_initialize(&dev->vdev, sizeof(dev->vdev), TYPE_VHOST_SCSI);
     object_property_add_child(obj, "virtio-backend", OBJECT(&dev->vdev), NULL);
 }
 #endif
@@ -310,7 +310,7 @@ static int s390_virtio_rng_init(VirtIOS390Device *s390_dev)
 static void s390_virtio_rng_instance_init(Object *obj)
 {
     VirtIORNGS390 *dev = VIRTIO_RNG_S390(obj);
-    object_initialize(&dev->vdev, TYPE_VIRTIO_RNG);
+    object_initialize(&dev->vdev, sizeof(dev->vdev), TYPE_VIRTIO_RNG);
     object_property_add_child(obj, "virtio-backend", OBJECT(&dev->vdev), NULL);
     object_property_add_link(obj, "rng", TYPE_RNG_BACKEND,
                              (Object **)&dev->vdev.conf.rng, NULL);
diff --git a/hw/s390x/virtio-ccw.c b/hw/s390x/virtio-ccw.c
index feb0a9e..cd67db5 100644
--- a/hw/s390x/virtio-ccw.c
+++ b/hw/s390x/virtio-ccw.c
@@ -660,7 +660,7 @@ static int virtio_ccw_net_init(VirtioCcwDevice *ccw_dev)
 static void virtio_ccw_net_instance_init(Object *obj)
 {
     VirtIONetCcw *dev = VIRTIO_NET_CCW(obj);
-    object_initialize(&dev->vdev, TYPE_VIRTIO_NET);
+    object_initialize(&dev->vdev, sizeof(dev->vdev), TYPE_VIRTIO_NET);
     object_property_add_child(obj, "virtio-backend", OBJECT(&dev->vdev), NULL);
 }
 
@@ -680,7 +680,7 @@ static int virtio_ccw_blk_init(VirtioCcwDevice *ccw_dev)
 static void virtio_ccw_blk_instance_init(Object *obj)
 {
     VirtIOBlkCcw *dev = VIRTIO_BLK_CCW(obj);
-    object_initialize(&dev->vdev, TYPE_VIRTIO_BLK);
+    object_initialize(&dev->vdev, sizeof(dev->vdev), TYPE_VIRTIO_BLK);
     object_property_add_child(obj, "virtio-backend", OBJECT(&dev->vdev), NULL);
 }
 
@@ -713,7 +713,7 @@ static int virtio_ccw_serial_init(VirtioCcwDevice *ccw_dev)
 static void virtio_ccw_serial_instance_init(Object *obj)
 {
     VirtioSerialCcw *dev = VIRTIO_SERIAL_CCW(obj);
-    object_initialize(&dev->vdev, TYPE_VIRTIO_SERIAL);
+    object_initialize(&dev->vdev, sizeof(dev->vdev), TYPE_VIRTIO_SERIAL);
     object_property_add_child(obj, "virtio-backend", OBJECT(&dev->vdev), NULL);
 }
 
@@ -759,7 +759,7 @@ static void balloon_ccw_stats_set_poll_interval(Object *obj, struct Visitor *v,
 static void virtio_ccw_balloon_instance_init(Object *obj)
 {
     VirtIOBalloonCcw *dev = VIRTIO_BALLOON_CCW(obj);
-    object_initialize(&dev->vdev, TYPE_VIRTIO_BALLOON);
+    object_initialize(&dev->vdev, sizeof(dev->vdev), TYPE_VIRTIO_BALLOON);
     object_property_add_child(obj, "virtio-backend", OBJECT(&dev->vdev), NULL);
 
     object_property_add(obj, "guest-stats", "guest statistics",
@@ -799,7 +799,7 @@ static int virtio_ccw_scsi_init(VirtioCcwDevice *ccw_dev)
 static void virtio_ccw_scsi_instance_init(Object *obj)
 {
     VirtIOSCSICcw *dev = VIRTIO_SCSI_CCW(obj);
-    object_initialize(&dev->vdev, TYPE_VIRTIO_SCSI);
+    object_initialize(&dev->vdev, sizeof(dev->vdev), TYPE_VIRTIO_SCSI);
     object_property_add_child(obj, "virtio-backend", OBJECT(&dev->vdev), NULL);
 }
 
@@ -820,7 +820,7 @@ static int vhost_ccw_scsi_init(VirtioCcwDevice *ccw_dev)
 static void vhost_ccw_scsi_instance_init(Object *obj)
 {
     VHostSCSICcw *dev = VHOST_SCSI_CCW(obj);
-    object_initialize(&dev->vdev, TYPE_VHOST_SCSI);
+    object_initialize(&dev->vdev, sizeof(dev->vdev), TYPE_VHOST_SCSI);
     object_property_add_child(obj, "virtio-backend", OBJECT(&dev->vdev), NULL);
 }
 #endif
@@ -1171,7 +1171,7 @@ static const TypeInfo vhost_ccw_scsi = {
 static void virtio_ccw_rng_instance_init(Object *obj)
 {
     VirtIORNGCcw *dev = VIRTIO_RNG_CCW(obj);
-    object_initialize(&dev->vdev, TYPE_VIRTIO_RNG);
+    object_initialize(&dev->vdev, sizeof(dev->vdev), TYPE_VIRTIO_RNG);
     object_property_add_child(obj, "virtio-backend", OBJECT(&dev->vdev), NULL);
     object_property_add_link(obj, "rng", TYPE_RNG_BACKEND,
                              (Object **)&dev->vdev.conf.rng, NULL);
diff --git a/hw/virtio/virtio-pci.c b/hw/virtio/virtio-pci.c
index 63884fe..14fd65e 100644
--- a/hw/virtio/virtio-pci.c
+++ b/hw/virtio/virtio-pci.c
@@ -919,7 +919,7 @@ static void virtio_9p_pci_class_init(ObjectClass *klass, void *data)
 static void virtio_9p_pci_instance_init(Object *obj)
 {
     V9fsPCIState *dev = VIRTIO_9P_PCI(obj);
-    object_initialize(&dev->vdev, TYPE_VIRTIO_9P);
+    object_initialize(&dev->vdev, sizeof(dev->vdev), TYPE_VIRTIO_9P);
     object_property_add_child(obj, "virtio-backend", OBJECT(&dev->vdev), NULL);
 }
 
@@ -1079,7 +1079,7 @@ static void virtio_blk_pci_class_init(ObjectClass *klass, void *data)
 static void virtio_blk_pci_instance_init(Object *obj)
 {
     VirtIOBlkPCI *dev = VIRTIO_BLK_PCI(obj);
-    object_initialize(&dev->vdev, TYPE_VIRTIO_BLK);
+    object_initialize(&dev->vdev, sizeof(dev->vdev), TYPE_VIRTIO_BLK);
     object_property_add_child(obj, "virtio-backend", OBJECT(&dev->vdev), NULL);
 }
 
@@ -1149,7 +1149,7 @@ static void virtio_scsi_pci_class_init(ObjectClass *klass, void *data)
 static void virtio_scsi_pci_instance_init(Object *obj)
 {
     VirtIOSCSIPCI *dev = VIRTIO_SCSI_PCI(obj);
-    object_initialize(&dev->vdev, TYPE_VIRTIO_SCSI);
+    object_initialize(&dev->vdev, sizeof(dev->vdev), TYPE_VIRTIO_SCSI);
     object_property_add_child(obj, "virtio-backend", OBJECT(&dev->vdev), NULL);
 }
 
@@ -1206,7 +1206,7 @@ static void vhost_scsi_pci_class_init(ObjectClass *klass, void *data)
 static void vhost_scsi_pci_instance_init(Object *obj)
 {
     VHostSCSIPCI *dev = VHOST_SCSI_PCI(obj);
-    object_initialize(&dev->vdev, TYPE_VHOST_SCSI);
+    object_initialize(&dev->vdev, sizeof(dev->vdev), TYPE_VHOST_SCSI);
     object_property_add_child(obj, "virtio-backend", OBJECT(&dev->vdev), NULL);
 }
 
@@ -1287,7 +1287,7 @@ static void virtio_balloon_pci_class_init(ObjectClass *klass, void *data)
 static void virtio_balloon_pci_instance_init(Object *obj)
 {
     VirtIOBalloonPCI *dev = VIRTIO_BALLOON_PCI(obj);
-    object_initialize(&dev->vdev, TYPE_VIRTIO_BALLOON);
+    object_initialize(&dev->vdev, sizeof(dev->vdev), TYPE_VIRTIO_BALLOON);
     object_property_add_child(obj, "virtio-backend", OBJECT(&dev->vdev), NULL);
 
     object_property_add(obj, "guest-stats", "guest statistics",
@@ -1373,7 +1373,7 @@ static void virtio_serial_pci_class_init(ObjectClass *klass, void *data)
 static void virtio_serial_pci_instance_init(Object *obj)
 {
     VirtIOSerialPCI *dev = VIRTIO_SERIAL_PCI(obj);
-    object_initialize(&dev->vdev, TYPE_VIRTIO_SERIAL);
+    object_initialize(&dev->vdev, sizeof(dev->vdev), TYPE_VIRTIO_SERIAL);
     object_property_add_child(obj, "virtio-backend", OBJECT(&dev->vdev), NULL);
 }
 
@@ -1432,7 +1432,7 @@ static void virtio_net_pci_class_init(ObjectClass *klass, void *data)
 static void virtio_net_pci_instance_init(Object *obj)
 {
     VirtIONetPCI *dev = VIRTIO_NET_PCI(obj);
-    object_initialize(&dev->vdev, TYPE_VIRTIO_NET);
+    object_initialize(&dev->vdev, sizeof(dev->vdev), TYPE_VIRTIO_NET);
     object_property_add_child(obj, "virtio-backend", OBJECT(&dev->vdev), NULL);
 }
 
@@ -1488,7 +1488,7 @@ static void virtio_rng_pci_class_init(ObjectClass *klass, void *data)
 static void virtio_rng_initfn(Object *obj)
 {
     VirtIORngPCI *dev = VIRTIO_RNG_PCI(obj);
-    object_initialize(&dev->vdev, TYPE_VIRTIO_RNG);
+    object_initialize(&dev->vdev, sizeof(dev->vdev), TYPE_VIRTIO_RNG);
     object_property_add_child(obj, "virtio-backend", OBJECT(&dev->vdev), NULL);
     object_property_add_link(obj, "rng", TYPE_RNG_BACKEND,
                              (Object **)&dev->vdev.conf.rng, NULL);
diff --git a/include/qom/object.h b/include/qom/object.h
index c463ced..13847fb 100644
--- a/include/qom/object.h
+++ b/include/qom/object.h
@@ -597,13 +597,14 @@ void object_initialize_with_type(void *data, Type type);
 /**
  * object_initialize:
  * @obj: A pointer to the memory to be used for the object.
+ * @size: The maximum size available at @obj for the object.
  * @typename: The name of the type of the object to instantiate.
  *
  * This function will initialize an object.  The memory for the object should
  * have already been allocated.  The returned object has a reference count of 1,
  * and will be finalized when the last reference is dropped.
  */
-void object_initialize(void *obj, const char *typename);
+void object_initialize(void *obj, size_t size, const char *typename);
 
 /**
  * object_dynamic_cast:
diff --git a/qom/object.c b/qom/object.c
index 74fd241..1635422 100644
--- a/qom/object.c
+++ b/qom/object.c
@@ -329,7 +329,7 @@ void object_initialize_with_type(void *data, TypeImpl *type)
     object_post_init_with_type(obj, type);
 }
 
-void object_initialize(void *data, const char *typename)
+void object_initialize(void *data, size_t size, const char *typename)
 {
     TypeImpl *type = type_get_by_name(typename);
 
commit fb17dfe0575243a3f60dcefca37fa82ae682f146
Author: Andreas Färber <afaerber at suse.de>
Date:   Sat Aug 24 00:02:27 2013 +0200

    qdev: Pass size to qbus_create_inplace()
    
    To be passed to object_initialize().
    
    Since commit 39355c3826f5d9a2eb1ce3dc9b4cdd68893769d6 the argument is
    void*, so drop some superfluous (BusState *) casts or direct parent
    field usages.
    
    Signed-off-by: Andreas Färber <afaerber at suse.de>

diff --git a/hw/audio/intel-hda.c b/hw/audio/intel-hda.c
index 6849c73..a6666c6 100644
--- a/hw/audio/intel-hda.c
+++ b/hw/audio/intel-hda.c
@@ -44,7 +44,7 @@ void hda_codec_bus_init(DeviceState *dev, HDACodecBus *bus, size_t bus_size,
                         hda_codec_response_func response,
                         hda_codec_xfer_func xfer)
 {
-    qbus_create_inplace(&bus->qbus, TYPE_HDA_BUS, dev, NULL);
+    qbus_create_inplace(bus, bus_size, TYPE_HDA_BUS, dev, NULL);
     bus->response = response;
     bus->xfer = xfer;
 }
diff --git a/hw/char/ipack.c b/hw/char/ipack.c
index 5fb7073..b7e45be 100644
--- a/hw/char/ipack.c
+++ b/hw/char/ipack.c
@@ -29,7 +29,7 @@ void ipack_bus_new_inplace(IPackBus *bus, size_t bus_size,
                            const char *name, uint8_t n_slots,
                            qemu_irq_handler handler)
 {
-    qbus_create_inplace(&bus->qbus, TYPE_IPACK_BUS, parent, name);
+    qbus_create_inplace(bus, bus_size, TYPE_IPACK_BUS, parent, name);
     bus->n_slots = n_slots;
     bus->set_irq = handler;
 }
diff --git a/hw/char/virtio-serial-bus.c b/hw/char/virtio-serial-bus.c
index f23f555..703f026 100644
--- a/hw/char/virtio-serial-bus.c
+++ b/hw/char/virtio-serial-bus.c
@@ -911,8 +911,8 @@ static int virtio_serial_device_init(VirtIODevice *vdev)
                 sizeof(struct virtio_console_config));
 
     /* Spawn a new virtio-serial bus on which the ports will ride as devices */
-    qbus_create_inplace(&vser->bus.qbus, TYPE_VIRTIO_SERIAL_BUS, qdev,
-                        vdev->bus_name);
+    qbus_create_inplace(&vser->bus, sizeof(vser->bus), TYPE_VIRTIO_SERIAL_BUS,
+                        qdev, vdev->bus_name);
     vser->bus.qbus.allow_hotplug = 1;
     vser->bus.vser = vser;
     QTAILQ_INIT(&vser->ports);
diff --git a/hw/core/qdev.c b/hw/core/qdev.c
index 758de9f..81874da 100644
--- a/hw/core/qdev.c
+++ b/hw/core/qdev.c
@@ -470,7 +470,7 @@ static void bus_unparent(Object *obj)
     }
 }
 
-void qbus_create_inplace(void *bus, const char *typename,
+void qbus_create_inplace(void *bus, size_t size, const char *typename,
                          DeviceState *parent, const char *name)
 {
     object_initialize(bus, typename);
diff --git a/hw/core/sysbus.c b/hw/core/sysbus.c
index 9004d8c..b84cd4a 100644
--- a/hw/core/sysbus.c
+++ b/hw/core/sysbus.c
@@ -276,8 +276,8 @@ static void main_system_bus_create(void)
     /* assign main_system_bus before qbus_create_inplace()
      * in order to make "if (bus != sysbus_get_default())" work */
     main_system_bus = g_malloc0(system_bus_info.instance_size);
-    qbus_create_inplace(main_system_bus, TYPE_SYSTEM_BUS, NULL,
-                        "main-system-bus");
+    qbus_create_inplace(main_system_bus, system_bus_info.instance_size,
+                        TYPE_SYSTEM_BUS, NULL, "main-system-bus");
     OBJECT(main_system_bus)->free = g_free;
     object_property_add_child(container_get(qdev_get_machine(),
                                             "/unattached"),
diff --git a/hw/cpu/icc_bus.c b/hw/cpu/icc_bus.c
index 8748cc5..9a4ea7e 100644
--- a/hw/cpu/icc_bus.c
+++ b/hw/cpu/icc_bus.c
@@ -90,7 +90,8 @@ static void icc_bridge_init(Object *obj)
     ICCBridgeState *s = ICC_BRIGDE(obj);
     SysBusDevice *sb = SYS_BUS_DEVICE(obj);
 
-    qbus_create_inplace(&s->icc_bus, TYPE_ICC_BUS, DEVICE(s), "icc");
+    qbus_create_inplace(&s->icc_bus, sizeof(s->icc_bus), TYPE_ICC_BUS,
+                        DEVICE(s), "icc");
 
     /* Do not change order of registering regions,
      * APIC must be first registered region, board maps it by 0 index
diff --git a/hw/ide/qdev.c b/hw/ide/qdev.c
index 8be76ab..18c4b7e 100644
--- a/hw/ide/qdev.c
+++ b/hw/ide/qdev.c
@@ -50,7 +50,7 @@ static const TypeInfo ide_bus_info = {
 void ide_bus_new(IDEBus *idebus, size_t idebus_size, DeviceState *dev,
                  int bus_id, int max_units)
 {
-    qbus_create_inplace(&idebus->qbus, TYPE_IDE_BUS, dev, NULL);
+    qbus_create_inplace(idebus, idebus_size, TYPE_IDE_BUS, dev, NULL);
     idebus->bus_id = bus_id;
     idebus->max_units = max_units;
 }
diff --git a/hw/misc/macio/cuda.c b/hw/misc/macio/cuda.c
index c811b95..bc71aa7 100644
--- a/hw/misc/macio/cuda.c
+++ b/hw/misc/macio/cuda.c
@@ -711,8 +711,8 @@ static void cuda_initfn(Object *obj)
         s->timers[i].index = i;
     }
 
-    qbus_create_inplace((BusState *)&s->adb_bus, TYPE_ADB_BUS, DEVICE(obj),
-                        "adb.0");
+    qbus_create_inplace(&s->adb_bus, sizeof(s->adb_bus), TYPE_ADB_BUS,
+                        DEVICE(obj), "adb.0");
 }
 
 static void cuda_class_init(ObjectClass *oc, void *data)
diff --git a/hw/pci/pci.c b/hw/pci/pci.c
index 397555c..e688f4a 100644
--- a/hw/pci/pci.c
+++ b/hw/pci/pci.c
@@ -318,7 +318,7 @@ void pci_bus_new_inplace(PCIBus *bus, size_t bus_size, DeviceState *parent,
                          MemoryRegion *address_space_io,
                          uint8_t devfn_min, const char *typename)
 {
-    qbus_create_inplace(bus, typename, parent, name);
+    qbus_create_inplace(bus, bus_size, typename, parent, name);
     pci_bus_init(bus, parent, name, address_space_mem,
                  address_space_io, devfn_min);
 }
diff --git a/hw/pci/pci_bridge.c b/hw/pci/pci_bridge.c
index a90671d..e6b22b8 100644
--- a/hw/pci/pci_bridge.c
+++ b/hw/pci/pci_bridge.c
@@ -367,7 +367,8 @@ int pci_bridge_initfn(PCIDevice *dev, const char *typename)
 	    br->bus_name = dev->qdev.id;
     }
 
-    qbus_create_inplace(&sec_bus->qbus, typename, &dev->qdev, br->bus_name);
+    qbus_create_inplace(sec_bus, sizeof(br->sec_bus), typename, DEVICE(dev),
+                        br->bus_name);
     sec_bus->parent_dev = dev;
     sec_bus->map_irq = br->map_irq ? br->map_irq : pci_swizzle_map_irq_fn;
     sec_bus->address_space_mem = &br->address_space_mem;
diff --git a/hw/s390x/event-facility.c b/hw/s390x/event-facility.c
index 0faade0..a3aceef 100644
--- a/hw/s390x/event-facility.c
+++ b/hw/s390x/event-facility.c
@@ -324,8 +324,8 @@ static int init_event_facility(S390SCLPDevice *sdev)
     sdev->event_pending = event_pending;
 
     /* Spawn a new sclp-events facility */
-    qbus_create_inplace(&event_facility->sbus.qbus,
-                        TYPE_SCLP_EVENTS_BUS, (DeviceState *)sdev, NULL);
+    qbus_create_inplace(&event_facility->sbus, sizeof(event_facility->sbus),
+                        TYPE_SCLP_EVENTS_BUS, DEVICE(sdev), NULL);
     event_facility->sbus.qbus.allow_hotplug = 0;
     event_facility->qdev = (DeviceState *) sdev;
 
diff --git a/hw/s390x/s390-virtio-bus.c b/hw/s390x/s390-virtio-bus.c
index 579adbc..f68341a 100644
--- a/hw/s390x/s390-virtio-bus.c
+++ b/hw/s390x/s390-virtio-bus.c
@@ -699,8 +699,8 @@ static void virtio_s390_bus_new(VirtioBusState *bus, size_t bus_size,
     BusState *qbus;
     char virtio_bus_name[] = "virtio-bus";
 
-    qbus_create_inplace((BusState *)bus, TYPE_VIRTIO_S390_BUS, qdev,
-                        virtio_bus_name);
+    qbus_create_inplace(bus, bus_size, TYPE_VIRTIO_S390_BUS,
+                        qdev, virtio_bus_name);
     qbus = BUS(bus);
     qbus->allow_hotplug = 1;
 }
diff --git a/hw/s390x/virtio-ccw.c b/hw/s390x/virtio-ccw.c
index 36cbf42..feb0a9e 100644
--- a/hw/s390x/virtio-ccw.c
+++ b/hw/s390x/virtio-ccw.c
@@ -1297,8 +1297,8 @@ static void virtio_ccw_bus_new(VirtioBusState *bus, size_t bus_size,
     BusState *qbus;
     char virtio_bus_name[] = "virtio-bus";
 
-    qbus_create_inplace((BusState *)bus, TYPE_VIRTIO_CCW_BUS, qdev,
-                        virtio_bus_name);
+    qbus_create_inplace(bus, bus_size, TYPE_VIRTIO_CCW_BUS,
+                        qdev, virtio_bus_name);
     qbus = BUS(bus);
     qbus->allow_hotplug = 1;
 }
diff --git a/hw/scsi/scsi-bus.c b/hw/scsi/scsi-bus.c
index 968bf23..5cd6137 100644
--- a/hw/scsi/scsi-bus.c
+++ b/hw/scsi/scsi-bus.c
@@ -75,7 +75,7 @@ static void scsi_device_unit_attention_reported(SCSIDevice *s)
 void scsi_bus_new(SCSIBus *bus, size_t bus_size, DeviceState *host,
                   const SCSIBusInfo *info, const char *bus_name)
 {
-    qbus_create_inplace(&bus->qbus, TYPE_SCSI_BUS, host, bus_name);
+    qbus_create_inplace(bus, bus_size, TYPE_SCSI_BUS, host, bus_name);
     bus->busnr = next_scsi_bus++;
     bus->info = info;
     bus->qbus.allow_hotplug = 1;
diff --git a/hw/usb/bus.c b/hw/usb/bus.c
index 6aee262..82ca6a1 100644
--- a/hw/usb/bus.c
+++ b/hw/usb/bus.c
@@ -70,7 +70,7 @@ const VMStateDescription vmstate_usb_device = {
 void usb_bus_new(USBBus *bus, size_t bus_size,
                  USBBusOps *ops, DeviceState *host)
 {
-    qbus_create_inplace(&bus->qbus, TYPE_USB_BUS, host, NULL);
+    qbus_create_inplace(bus, bus_size, TYPE_USB_BUS, host, NULL);
     bus->ops = ops;
     bus->busnr = next_usb_bus++;
     bus->qbus.allow_hotplug = 1; /* Yes, we can */
diff --git a/hw/usb/dev-smartcard-reader.c b/hw/usb/dev-smartcard-reader.c
index 2233c54..8c7a61e 100644
--- a/hw/usb/dev-smartcard-reader.c
+++ b/hw/usb/dev-smartcard-reader.c
@@ -1309,7 +1309,8 @@ static int ccid_initfn(USBDevice *dev)
 
     usb_desc_create_serial(dev);
     usb_desc_init(dev);
-    qbus_create_inplace(&s->bus.qbus, TYPE_CCID_BUS, &dev->qdev, NULL);
+    qbus_create_inplace(&s->bus, sizeof(s->bus), TYPE_CCID_BUS, DEVICE(dev),
+                        NULL);
     s->intr = usb_ep_get(dev, USB_TOKEN_IN, CCID_INT_IN_EP);
     s->bus.qbus.allow_hotplug = 1;
     s->card = NULL;
diff --git a/hw/virtio/virtio-mmio.c b/hw/virtio/virtio-mmio.c
index 692979e..29cf284 100644
--- a/hw/virtio/virtio-mmio.c
+++ b/hw/virtio/virtio-mmio.c
@@ -392,7 +392,7 @@ static void virtio_mmio_bus_new(VirtioBusState *bus, size_t bus_size,
     DeviceState *qdev = DEVICE(dev);
     BusState *qbus;
 
-    qbus_create_inplace((BusState *)bus, TYPE_VIRTIO_MMIO_BUS, qdev, NULL);
+    qbus_create_inplace(bus, bus_size, TYPE_VIRTIO_MMIO_BUS, qdev, NULL);
     qbus = BUS(bus);
     qbus->allow_hotplug = 0;
 }
diff --git a/hw/virtio/virtio-pci.c b/hw/virtio/virtio-pci.c
index 606b4d4..63884fe 100644
--- a/hw/virtio/virtio-pci.c
+++ b/hw/virtio/virtio-pci.c
@@ -1512,7 +1512,7 @@ static void virtio_pci_bus_new(VirtioBusState *bus, size_t bus_size,
     BusState *qbus;
     char virtio_bus_name[] = "virtio-bus";
 
-    qbus_create_inplace((BusState *)bus, TYPE_VIRTIO_PCI_BUS, qdev,
+    qbus_create_inplace(bus, bus_size, TYPE_VIRTIO_PCI_BUS, qdev,
                         virtio_bus_name);
     qbus = BUS(bus);
     qbus->allow_hotplug = 1;
diff --git a/include/hw/qdev-core.h b/include/hw/qdev-core.h
index 46972f4..a62f231 100644
--- a/include/hw/qdev-core.h
+++ b/include/hw/qdev-core.h
@@ -264,7 +264,7 @@ DeviceState *qdev_find_recursive(BusState *bus, const char *id);
 typedef int (qbus_walkerfn)(BusState *bus, void *opaque);
 typedef int (qdev_walkerfn)(DeviceState *dev, void *opaque);
 
-void qbus_create_inplace(void *bus, const char *typename,
+void qbus_create_inplace(void *bus, size_t size, const char *typename,
                          DeviceState *parent, const char *name);
 BusState *qbus_create(const char *typename, DeviceState *parent, const char *name);
 /* Returns > 0 if either devfn or busfn skip walk somewhere in cursion,
commit e5f720391e0628131cb6548b3d27be6aa56ae7d4
Author: Andreas Färber <afaerber at suse.de>
Date:   Fri Aug 23 20:33:55 2013 +0200

    virtio-mmio: Pass size to virtio_mmio_bus_new()
    
    To be passed to qbus_create_initialize().
    
    Reviewed-by: Wenchao Xia <xiawenc at linux.vnet.ibm.com>
    Signed-off-by: Andreas Färber <afaerber at suse.de>

diff --git a/hw/virtio/virtio-mmio.c b/hw/virtio/virtio-mmio.c
index 4bd2953..692979e 100644
--- a/hw/virtio/virtio-mmio.c
+++ b/hw/virtio/virtio-mmio.c
@@ -89,7 +89,8 @@ typedef struct {
     VirtioBusState bus;
 } VirtIOMMIOProxy;
 
-static void virtio_mmio_bus_new(VirtioBusState *bus, VirtIOMMIOProxy *dev);
+static void virtio_mmio_bus_new(VirtioBusState *bus, size_t bus_size,
+                                VirtIOMMIOProxy *dev);
 
 static uint64_t virtio_mmio_read(void *opaque, hwaddr offset, unsigned size)
 {
@@ -360,7 +361,7 @@ static void virtio_mmio_realizefn(DeviceState *d, Error **errp)
     VirtIOMMIOProxy *proxy = VIRTIO_MMIO(d);
     SysBusDevice *sbd = SYS_BUS_DEVICE(d);
 
-    virtio_mmio_bus_new(&proxy->bus, proxy);
+    virtio_mmio_bus_new(&proxy->bus, sizeof(proxy->bus), proxy);
     sysbus_init_irq(sbd, &proxy->irq);
     memory_region_init_io(&proxy->iomem, OBJECT(d), &virtio_mem_ops, proxy,
                           TYPE_VIRTIO_MMIO, 0x200);
@@ -385,7 +386,8 @@ static const TypeInfo virtio_mmio_info = {
 
 /* virtio-mmio-bus. */
 
-static void virtio_mmio_bus_new(VirtioBusState *bus, VirtIOMMIOProxy *dev)
+static void virtio_mmio_bus_new(VirtioBusState *bus, size_t bus_size,
+                                VirtIOMMIOProxy *dev)
 {
     DeviceState *qdev = DEVICE(dev);
     BusState *qbus;
commit 1bf4d7aad61f47b3da52c4aff239fd94be320727
Author: Andreas Färber <afaerber at suse.de>
Date:   Fri Aug 23 20:27:30 2013 +0200

    virtio-ccw: Pass size to virtio_ccw_bus_new()
    
    To be passed to qbus_create_inplace().
    
    Reviewed-by: Wenchao Xia <xiawenc at linux.vnet.ibm.com>
    Acked-by: Cornelia Huck <cornelia.huck at de.ibm.com>
    Signed-off-by: Andreas Färber <afaerber at suse.de>

diff --git a/hw/s390x/virtio-ccw.c b/hw/s390x/virtio-ccw.c
index e3b207f..36cbf42 100644
--- a/hw/s390x/virtio-ccw.c
+++ b/hw/s390x/virtio-ccw.c
@@ -27,7 +27,8 @@
 #include "virtio-ccw.h"
 #include "trace.h"
 
-static void virtio_ccw_bus_new(VirtioBusState *bus, VirtioCcwDevice *dev);
+static void virtio_ccw_bus_new(VirtioBusState *bus, size_t bus_size,
+                               VirtioCcwDevice *dev);
 
 static int virtual_css_bus_reset(BusState *qbus)
 {
@@ -1209,7 +1210,7 @@ static int virtio_ccw_busdev_init(DeviceState *dev)
     VirtioCcwDevice *_dev = (VirtioCcwDevice *)dev;
     VirtIOCCWDeviceClass *_info = VIRTIO_CCW_DEVICE_GET_CLASS(dev);
 
-    virtio_ccw_bus_new(&_dev->bus, _dev);
+    virtio_ccw_bus_new(&_dev->bus, sizeof(_dev->bus), _dev);
 
     return _info->init(_dev);
 }
@@ -1289,7 +1290,8 @@ static const TypeInfo virtual_css_bridge_info = {
 
 /* virtio-ccw-bus */
 
-static void virtio_ccw_bus_new(VirtioBusState *bus, VirtioCcwDevice *dev)
+static void virtio_ccw_bus_new(VirtioBusState *bus, size_t bus_size,
+                               VirtioCcwDevice *dev)
 {
     DeviceState *qdev = DEVICE(dev);
     BusState *qbus;
commit 5d6c0c49136e2615c0cd60cda523e8dc8cd65ed7
Author: Andreas Färber <afaerber at suse.de>
Date:   Fri Aug 23 20:25:57 2013 +0200

    s390-virtio-bus: Pass size to virtio_s390_bus_new()
    
    To be passed to qbus_create_inplace().
    
    Reviewed-by: Wenchao Xia <xiawenc at linux.vnet.ibm.com>
    Signed-off-by: Andreas Färber <afaerber at suse.de>

diff --git a/hw/s390x/s390-virtio-bus.c b/hw/s390x/s390-virtio-bus.c
index e46b8c8..579adbc 100644
--- a/hw/s390x/s390-virtio-bus.c
+++ b/hw/s390x/s390-virtio-bus.c
@@ -47,7 +47,8 @@
 
 #define VIRTIO_EXT_CODE   0x2603
 
-static void virtio_s390_bus_new(VirtioBusState *bus, VirtIOS390Device *dev);
+static void virtio_s390_bus_new(VirtioBusState *bus, size_t bus_size,
+                                VirtIOS390Device *dev);
 
 static const TypeInfo s390_virtio_bus_info = {
     .name = TYPE_S390_VIRTIO_BUS,
@@ -585,7 +586,7 @@ static int s390_virtio_busdev_init(DeviceState *dev)
     VirtIOS390Device *_dev = (VirtIOS390Device *)dev;
     VirtIOS390DeviceClass *_info = VIRTIO_S390_DEVICE_GET_CLASS(dev);
 
-    virtio_s390_bus_new(&_dev->bus, _dev);
+    virtio_s390_bus_new(&_dev->bus, sizeof(_dev->bus), _dev);
 
     return _info->init(_dev);
 }
@@ -691,7 +692,8 @@ static const TypeInfo s390_virtio_bridge_info = {
 
 /* virtio-s390-bus */
 
-static void virtio_s390_bus_new(VirtioBusState *bus, VirtIOS390Device *dev)
+static void virtio_s390_bus_new(VirtioBusState *bus, size_t bus_size,
+                                VirtIOS390Device *dev)
 {
     DeviceState *qdev = DEVICE(dev);
     BusState *qbus;
commit ac7af1120f589a5385e39b3decc3d2d944a4d656
Author: Andreas Färber <afaerber at suse.de>
Date:   Fri Aug 23 20:35:18 2013 +0200

    virtio-pci: Pass size to virtio_pci_bus_new()
    
    To be passed to qbus_create_inplace().
    
    Reviewed-by: Wenchao Xia <xiawenc at linux.vnet.ibm.com>
    Signed-off-by: Andreas Färber <afaerber at suse.de>

diff --git a/hw/virtio/virtio-pci.c b/hw/virtio/virtio-pci.c
index 8df43d6..606b4d4 100644
--- a/hw/virtio/virtio-pci.c
+++ b/hw/virtio/virtio-pci.c
@@ -92,7 +92,8 @@
 /* HACK for virtio to determine if it's running a big endian guest */
 bool virtio_is_big_endian(void);
 
-static void virtio_pci_bus_new(VirtioBusState *bus, VirtIOPCIProxy *dev);
+static void virtio_pci_bus_new(VirtioBusState *bus, size_t bus_size,
+                               VirtIOPCIProxy *dev);
 
 /* virtio device */
 /* DeviceState to VirtIOPCIProxy. For use off data-path. TODO: use QOM. */
@@ -986,7 +987,7 @@ static int virtio_pci_init(PCIDevice *pci_dev)
 {
     VirtIOPCIProxy *dev = VIRTIO_PCI(pci_dev);
     VirtioPCIClass *k = VIRTIO_PCI_GET_CLASS(pci_dev);
-    virtio_pci_bus_new(&dev->bus, dev);
+    virtio_pci_bus_new(&dev->bus, sizeof(dev->bus), dev);
     if (k->init != NULL) {
         return k->init(dev);
     }
@@ -1504,7 +1505,8 @@ static const TypeInfo virtio_rng_pci_info = {
 
 /* virtio-pci-bus */
 
-static void virtio_pci_bus_new(VirtioBusState *bus, VirtIOPCIProxy *dev)
+static void virtio_pci_bus_new(VirtioBusState *bus, size_t bus_size,
+                               VirtIOPCIProxy *dev)
 {
     DeviceState *qdev = DEVICE(dev);
     BusState *qbus;
commit c889b3a55d5d1d18042693cbe2f8f05465914ff4
Author: Andreas Färber <afaerber at suse.de>
Date:   Fri Aug 23 20:32:04 2013 +0200

    usb: Pass size to usb_bus_new()
    
    To be passed to qbus_create_inplace().
    
    Use DEVICE() cast to avoid a direct parent field access.
    
    Reviewed-by: Wenchao Xia <xiawenc at linux.vnet.ibm.com>
    Signed-off-by: Andreas Färber <afaerber at suse.de>

diff --git a/hw/usb/bus.c b/hw/usb/bus.c
index f83d1de..6aee262 100644
--- a/hw/usb/bus.c
+++ b/hw/usb/bus.c
@@ -67,7 +67,8 @@ const VMStateDescription vmstate_usb_device = {
     }
 };
 
-void usb_bus_new(USBBus *bus, USBBusOps *ops, DeviceState *host)
+void usb_bus_new(USBBus *bus, size_t bus_size,
+                 USBBusOps *ops, DeviceState *host)
 {
     qbus_create_inplace(&bus->qbus, TYPE_USB_BUS, host, NULL);
     bus->ops = ops;
diff --git a/hw/usb/hcd-ehci.c b/hw/usb/hcd-ehci.c
index e5523d5..137e200 100644
--- a/hw/usb/hcd-ehci.c
+++ b/hw/usb/hcd-ehci.c
@@ -2520,7 +2520,7 @@ void usb_ehci_realize(EHCIState *s, DeviceState *dev, Error **errp)
         return;
     }
 
-    usb_bus_new(&s->bus, &ehci_bus_ops, dev);
+    usb_bus_new(&s->bus, sizeof(s->bus), &ehci_bus_ops, dev);
     for (i = 0; i < s->portnr; i++) {
         usb_register_port(&s->bus, &s->ports[i], s, i, &ehci_port_ops,
                           USB_SPEED_MASK_HIGH);
diff --git a/hw/usb/hcd-musb.c b/hw/usb/hcd-musb.c
index f91aa55..66bc61a 100644
--- a/hw/usb/hcd-musb.c
+++ b/hw/usb/hcd-musb.c
@@ -383,7 +383,7 @@ struct MUSBState *musb_init(DeviceState *parent_device, int gpio_base)
 
     musb_reset(s);
 
-    usb_bus_new(&s->bus, &musb_bus_ops, parent_device);
+    usb_bus_new(&s->bus, sizeof(s->bus), &musb_bus_ops, parent_device);
     usb_register_port(&s->bus, &s->port, s, 0, &musb_port_ops,
                       USB_SPEED_MASK_LOW | USB_SPEED_MASK_FULL);
 
diff --git a/hw/usb/hcd-ohci.c b/hw/usb/hcd-ohci.c
index 39a25a7..35f0878 100644
--- a/hw/usb/hcd-ohci.c
+++ b/hw/usb/hcd-ohci.c
@@ -1881,7 +1881,7 @@ static int usb_ohci_init(OHCIState *ohci, DeviceState *dev,
             return -1;
         }
     } else {
-        usb_bus_new(&ohci->bus, &ohci_bus_ops, dev);
+        usb_bus_new(&ohci->bus, sizeof(ohci->bus), &ohci_bus_ops, dev);
         for (i = 0; i < num_ports; i++) {
             usb_register_port(&ohci->bus, &ohci->rhport[i].port,
                               ohci, i, &ohci_port_ops,
diff --git a/hw/usb/hcd-uhci.c b/hw/usb/hcd-uhci.c
index 578b949..becc7fa 100644
--- a/hw/usb/hcd-uhci.c
+++ b/hw/usb/hcd-uhci.c
@@ -1254,7 +1254,7 @@ static int usb_uhci_common_initfn(PCIDevice *dev)
             return -1;
         }
     } else {
-        usb_bus_new(&s->bus, &uhci_bus_ops, &s->dev.qdev);
+        usb_bus_new(&s->bus, sizeof(s->bus), &uhci_bus_ops, DEVICE(dev));
         for (i = 0; i < NB_PORTS; i++) {
             usb_register_port(&s->bus, &s->ports[i].port, s, i, &uhci_port_ops,
                               USB_SPEED_MASK_LOW | USB_SPEED_MASK_FULL);
diff --git a/hw/usb/hcd-xhci.c b/hw/usb/hcd-xhci.c
index be6b86e..d5c6588 100644
--- a/hw/usb/hcd-xhci.c
+++ b/hw/usb/hcd-xhci.c
@@ -3309,7 +3309,7 @@ static void usb_xhci_init(XHCIState *xhci)
     usbports = MAX(xhci->numports_2, xhci->numports_3);
     xhci->numports = xhci->numports_2 + xhci->numports_3;
 
-    usb_bus_new(&xhci->bus, &xhci_bus_ops, dev);
+    usb_bus_new(&xhci->bus, sizeof(xhci->bus), &xhci_bus_ops, dev);
 
     for (i = 0; i < usbports; i++) {
         speedmask = 0;
diff --git a/include/hw/usb.h b/include/hw/usb.h
index 901b0da..1b8acba 100644
--- a/include/hw/usb.h
+++ b/include/hw/usb.h
@@ -496,7 +496,8 @@ struct USBBusOps {
     void (*wakeup_endpoint)(USBBus *bus, USBEndpoint *ep, unsigned int stream);
 };
 
-void usb_bus_new(USBBus *bus, USBBusOps *ops, DeviceState *host);
+void usb_bus_new(USBBus *bus, size_t bus_size,
+                 USBBusOps *ops, DeviceState *host);
 USBBus *usb_bus_find(int busnr);
 void usb_legacy_register(const char *typename, const char *usbdevice_name,
                          USBDevice *(*usbdevice_init)(USBBus *bus,
commit b1187b51ff5563135da0a9e5c855d7876ab1a926
Author: Andreas Färber <afaerber at suse.de>
Date:   Fri Aug 23 20:30:03 2013 +0200

    scsi: Pass size to scsi_bus_new()
    
    To be passed to qbus_create_inplace().
    
    Use DEVICE() casts instead of direct parent field access.
    
    Reviewed-by: Wenchao Xia <xiawenc at linux.vnet.ibm.com>
    Acked-by: Paolo Bonzini <pbonzini at redhat.com>
    Signed-off-by: Andreas Färber <afaerber at suse.de>

diff --git a/hw/scsi/esp-pci.c b/hw/scsi/esp-pci.c
index d7ec173..99bf8ec 100644
--- a/hw/scsi/esp-pci.c
+++ b/hw/scsi/esp-pci.c
@@ -363,7 +363,7 @@ static int esp_pci_scsi_init(PCIDevice *dev)
     pci_register_bar(dev, 0, PCI_BASE_ADDRESS_SPACE_IO, &pci->io);
     s->irq = dev->irq[0];
 
-    scsi_bus_new(&s->bus, d, &esp_pci_scsi_info, NULL);
+    scsi_bus_new(&s->bus, sizeof(s->bus), d, &esp_pci_scsi_info, NULL);
     if (!d->hotplugged) {
         scsi_bus_legacy_handle_cmdline(&s->bus, &err);
         if (err != NULL) {
diff --git a/hw/scsi/esp.c b/hw/scsi/esp.c
index 101e957..2d150bf 100644
--- a/hw/scsi/esp.c
+++ b/hw/scsi/esp.c
@@ -688,7 +688,7 @@ static void sysbus_esp_realize(DeviceState *dev, Error **errp)
 
     qdev_init_gpio_in(dev, sysbus_esp_gpio_demux, 2);
 
-    scsi_bus_new(&s->bus, dev, &esp_scsi_info, NULL);
+    scsi_bus_new(&s->bus, sizeof(s->bus), dev, &esp_scsi_info, NULL);
     scsi_bus_legacy_handle_cmdline(&s->bus, &err);
     if (err != NULL) {
         error_propagate(errp, err);
diff --git a/hw/scsi/lsi53c895a.c b/hw/scsi/lsi53c895a.c
index 611f2aa..0c36842 100644
--- a/hw/scsi/lsi53c895a.c
+++ b/hw/scsi/lsi53c895a.c
@@ -2117,7 +2117,7 @@ static int lsi_scsi_init(PCIDevice *dev)
     pci_register_bar(dev, 2, PCI_BASE_ADDRESS_SPACE_MEMORY, &s->ram_io);
     QTAILQ_INIT(&s->queue);
 
-    scsi_bus_new(&s->bus, d, &lsi_scsi_info, NULL);
+    scsi_bus_new(&s->bus, sizeof(s->bus), d, &lsi_scsi_info, NULL);
     if (!d->hotplugged) {
         scsi_bus_legacy_handle_cmdline(&s->bus, &err);
         if (err != NULL) {
diff --git a/hw/scsi/megasas.c b/hw/scsi/megasas.c
index a6d5285..09b51b3 100644
--- a/hw/scsi/megasas.c
+++ b/hw/scsi/megasas.c
@@ -2171,7 +2171,8 @@ static int megasas_scsi_init(PCIDevice *dev)
         s->frames[i].state = s;
     }
 
-    scsi_bus_new(&s->bus, DEVICE(dev), &megasas_scsi_info, NULL);
+    scsi_bus_new(&s->bus, sizeof(s->bus), DEVICE(dev),
+                 &megasas_scsi_info, NULL);
     if (!d->hotplugged) {
         scsi_bus_legacy_handle_cmdline(&s->bus, &err);
         if (err != NULL) {
diff --git a/hw/scsi/scsi-bus.c b/hw/scsi/scsi-bus.c
index fbf9173..968bf23 100644
--- a/hw/scsi/scsi-bus.c
+++ b/hw/scsi/scsi-bus.c
@@ -72,8 +72,8 @@ static void scsi_device_unit_attention_reported(SCSIDevice *s)
 }
 
 /* Create a scsi bus, and attach devices to it.  */
-void scsi_bus_new(SCSIBus *bus, DeviceState *host, const SCSIBusInfo *info,
-                  const char *bus_name)
+void scsi_bus_new(SCSIBus *bus, size_t bus_size, DeviceState *host,
+                  const SCSIBusInfo *info, const char *bus_name)
 {
     qbus_create_inplace(&bus->qbus, TYPE_SCSI_BUS, host, bus_name);
     bus->busnr = next_scsi_bus++;
diff --git a/hw/scsi/spapr_vscsi.c b/hw/scsi/spapr_vscsi.c
index e9090e5..b2fcd4b 100644
--- a/hw/scsi/spapr_vscsi.c
+++ b/hw/scsi/spapr_vscsi.c
@@ -1020,7 +1020,8 @@ static int spapr_vscsi_init(VIOsPAPRDevice *dev)
 
     dev->crq.SendFunc = vscsi_do_crq;
 
-    scsi_bus_new(&s->bus, &dev->qdev, &vscsi_scsi_info, NULL);
+    scsi_bus_new(&s->bus, sizeof(s->bus), DEVICE(dev),
+                 &vscsi_scsi_info, NULL);
     if (!dev->qdev.hotplugged) {
         scsi_bus_legacy_handle_cmdline(&s->bus, &err);
         if (err != NULL) {
diff --git a/hw/scsi/virtio-scsi.c b/hw/scsi/virtio-scsi.c
index 05da56b..3bd690d 100644
--- a/hw/scsi/virtio-scsi.c
+++ b/hw/scsi/virtio-scsi.c
@@ -627,7 +627,8 @@ static int virtio_scsi_device_init(VirtIODevice *vdev)
         return ret;
     }
 
-    scsi_bus_new(&s->bus, qdev, &virtio_scsi_scsi_info, vdev->bus_name);
+    scsi_bus_new(&s->bus, sizeof(s->bus), qdev,
+                 &virtio_scsi_scsi_info, vdev->bus_name);
 
     if (!qdev->hotplugged) {
         scsi_bus_legacy_handle_cmdline(&s->bus, &err);
diff --git a/hw/scsi/vmw_pvscsi.c b/hw/scsi/vmw_pvscsi.c
index d42b359..819d671 100644
--- a/hw/scsi/vmw_pvscsi.c
+++ b/hw/scsi/vmw_pvscsi.c
@@ -1088,7 +1088,8 @@ pvscsi_init(PCIDevice *pci_dev)
         return -ENOMEM;
     }
 
-    scsi_bus_new(&s->bus, &pci_dev->qdev, &pvscsi_scsi_info, NULL);
+    scsi_bus_new(&s->bus, sizeof(s->bus), DEVICE(pci_dev),
+                 &pvscsi_scsi_info, NULL);
     pvscsi_reset_state(s);
 
     return 0;
diff --git a/hw/usb/dev-storage.c b/hw/usb/dev-storage.c
index a8dc2fa..1d81ac2 100644
--- a/hw/usb/dev-storage.c
+++ b/hw/usb/dev-storage.c
@@ -618,7 +618,8 @@ static int usb_msd_initfn_storage(USBDevice *dev)
 
     usb_desc_create_serial(dev);
     usb_desc_init(dev);
-    scsi_bus_new(&s->bus, &s->dev.qdev, &usb_msd_scsi_info_storage, NULL);
+    scsi_bus_new(&s->bus, sizeof(s->bus), DEVICE(dev),
+                 &usb_msd_scsi_info_storage, NULL);
     scsi_dev = scsi_bus_legacy_add_drive(&s->bus, bs, 0, !!s->removable,
                                          s->conf.bootindex, dev->serial,
                                          &err);
@@ -646,7 +647,8 @@ static int usb_msd_initfn_bot(USBDevice *dev)
 
     usb_desc_create_serial(dev);
     usb_desc_init(dev);
-    scsi_bus_new(&s->bus, &s->dev.qdev, &usb_msd_scsi_info_bot, NULL);
+    scsi_bus_new(&s->bus, sizeof(s->bus), DEVICE(dev),
+                 &usb_msd_scsi_info_bot, NULL);
     s->bus.qbus.allow_hotplug = 0;
     usb_msd_handle_reset(dev);
 
diff --git a/hw/usb/dev-uas.c b/hw/usb/dev-uas.c
index 63ad12e..1569d6e 100644
--- a/hw/usb/dev-uas.c
+++ b/hw/usb/dev-uas.c
@@ -888,7 +888,8 @@ static int usb_uas_init(USBDevice *dev)
     QTAILQ_INIT(&uas->requests);
     uas->status_bh = qemu_bh_new(usb_uas_send_status_bh, uas);
 
-    scsi_bus_new(&uas->bus, &uas->dev.qdev, &usb_uas_scsi_info, NULL);
+    scsi_bus_new(&uas->bus, sizeof(uas->bus), DEVICE(dev),
+                 &usb_uas_scsi_info, NULL);
 
     return 0;
 }
diff --git a/include/hw/scsi/scsi.h b/include/hw/scsi/scsi.h
index 8786531..1b66510 100644
--- a/include/hw/scsi/scsi.h
+++ b/include/hw/scsi/scsi.h
@@ -152,8 +152,8 @@ struct SCSIBus {
     const SCSIBusInfo *info;
 };
 
-void scsi_bus_new(SCSIBus *bus, DeviceState *host, const SCSIBusInfo *info,
-                  const char *bus_name);
+void scsi_bus_new(SCSIBus *bus, size_t bus_size, DeviceState *host,
+                  const SCSIBusInfo *info, const char *bus_name);
 
 static inline SCSIBus *scsi_bus_from_device(SCSIDevice *d)
 {
commit dd301ca607feddab3b44f927cd36aee004c40e1a
Author: Andreas Färber <afaerber at suse.de>
Date:   Fri Aug 23 20:23:55 2013 +0200

    pci: Pass size to pci_bus_new_inplace()
    
    To be passed to qbus_create_inplace().
    
    Reviewed-by: Wenchao Xia <xiawenc at linux.vnet.ibm.com>
    Signed-off-by: Andreas Färber <afaerber at suse.de>

diff --git a/hw/pci-host/prep.c b/hw/pci-host/prep.c
index e120058..a62236b 100644
--- a/hw/pci-host/prep.c
+++ b/hw/pci-host/prep.c
@@ -155,7 +155,7 @@ static void raven_pcihost_initfn(Object *obj)
     MemoryRegion *address_space_io = get_system_io();
     DeviceState *pci_dev;
 
-    pci_bus_new_inplace(&s->pci_bus, DEVICE(obj), NULL,
+    pci_bus_new_inplace(&s->pci_bus, sizeof(s->pci_bus), DEVICE(obj), NULL,
                         address_space_mem, address_space_io, 0, TYPE_PCI_BUS);
     h->bus = &s->pci_bus;
 
diff --git a/hw/pci-host/versatile.c b/hw/pci-host/versatile.c
index 9238d39..4b9359c 100644
--- a/hw/pci-host/versatile.c
+++ b/hw/pci-host/versatile.c
@@ -384,7 +384,7 @@ static void pci_vpb_init(Object *obj)
     memory_region_init(&s->pci_io_space, OBJECT(s), "pci_io", 1ULL << 32);
     memory_region_init(&s->pci_mem_space, OBJECT(s), "pci_mem", 1ULL << 32);
 
-    pci_bus_new_inplace(&s->pci_bus, DEVICE(obj), "pci",
+    pci_bus_new_inplace(&s->pci_bus, sizeof(s->pci_bus), DEVICE(obj), "pci",
                         &s->pci_mem_space, &s->pci_io_space,
                         PCI_DEVFN(11, 0), TYPE_PCI_BUS);
     h->bus = &s->pci_bus;
diff --git a/hw/pci/pci.c b/hw/pci/pci.c
index 4c004f5..397555c 100644
--- a/hw/pci/pci.c
+++ b/hw/pci/pci.c
@@ -312,7 +312,7 @@ bool pci_bus_is_root(PCIBus *bus)
     return !bus->parent_dev;
 }
 
-void pci_bus_new_inplace(PCIBus *bus, DeviceState *parent,
+void pci_bus_new_inplace(PCIBus *bus, size_t bus_size, DeviceState *parent,
                          const char *name,
                          MemoryRegion *address_space_mem,
                          MemoryRegion *address_space_io,
diff --git a/include/hw/pci/pci.h b/include/hw/pci/pci.h
index ccec2ba..051b6ed 100644
--- a/include/hw/pci/pci.h
+++ b/include/hw/pci/pci.h
@@ -348,7 +348,7 @@ typedef int (*pci_hotplug_fn)(DeviceState *qdev, PCIDevice *pci_dev,
 
 bool pci_bus_is_express(PCIBus *bus);
 bool pci_bus_is_root(PCIBus *bus);
-void pci_bus_new_inplace(PCIBus *bus, DeviceState *parent,
+void pci_bus_new_inplace(PCIBus *bus, size_t bus_size, DeviceState *parent,
                          const char *name,
                          MemoryRegion *address_space_mem,
                          MemoryRegion *address_space_io,
commit c6baf942e084e0bc40ee37c8d8672ac9c5ea270b
Author: Andreas Färber <afaerber at suse.de>
Date:   Fri Aug 23 20:18:50 2013 +0200

    ide: Pass size to ide_bus_new()
    
    To be passed to qbus_create_inplace().
    
    Reviewed-by: Wenchao Xia <xiawenc at linux.vnet.ibm.com>
    Signed-off-by: Andreas Färber <afaerber at suse.de>

diff --git a/hw/ide/ahci.c b/hw/ide/ahci.c
index bba150f..a71a4ca 100644
--- a/hw/ide/ahci.c
+++ b/hw/ide/ahci.c
@@ -1175,7 +1175,7 @@ void ahci_init(AHCIState *s, DeviceState *qdev, AddressSpace *as, int ports)
     for (i = 0; i < s->ports; i++) {
         AHCIDevice *ad = &s->dev[i];
 
-        ide_bus_new(&ad->port, qdev, i, 1);
+        ide_bus_new(&ad->port, sizeof(ad->port), qdev, i, 1);
         ide_init2(&ad->port, irqs[i]);
 
         ad->hba = s;
diff --git a/hw/ide/cmd646.c b/hw/ide/cmd646.c
index d6ef799..0500a7a 100644
--- a/hw/ide/cmd646.c
+++ b/hw/ide/cmd646.c
@@ -289,7 +289,7 @@ static int pci_cmd646_ide_initfn(PCIDevice *dev)
 
     irq = qemu_allocate_irqs(cmd646_set_irq, d, 2);
     for (i = 0; i < 2; i++) {
-        ide_bus_new(&d->bus[i], DEVICE(dev), i, 2);
+        ide_bus_new(&d->bus[i], sizeof(d->bus[i]), DEVICE(dev), i, 2);
         ide_init2(&d->bus[i], irq[i]);
 
         bmdma_init(&d->bus[i], &d->bmdma[i], d);
diff --git a/hw/ide/internal.h b/hw/ide/internal.h
index 048a052..5d1cf87 100644
--- a/hw/ide/internal.h
+++ b/hw/ide/internal.h
@@ -576,7 +576,8 @@ void ide_atapi_cmd(IDEState *s);
 void ide_atapi_cmd_reply_end(IDEState *s);
 
 /* hw/ide/qdev.c */
-void ide_bus_new(IDEBus *idebus, DeviceState *dev, int bus_id, int max_units);
+void ide_bus_new(IDEBus *idebus, size_t idebus_size, DeviceState *dev,
+                 int bus_id, int max_units);
 IDEDevice *ide_create_drive(IDEBus *bus, int unit, DriveInfo *drive);
 
 #endif /* HW_IDE_INTERNAL_H */
diff --git a/hw/ide/isa.c b/hw/ide/isa.c
index bbc8c6b..afc24d4 100644
--- a/hw/ide/isa.c
+++ b/hw/ide/isa.c
@@ -70,7 +70,7 @@ static void isa_ide_realizefn(DeviceState *dev, Error **errp)
     ISADevice *isadev = ISA_DEVICE(dev);
     ISAIDEState *s = ISA_IDE(dev);
 
-    ide_bus_new(&s->bus, dev, 0, 2);
+    ide_bus_new(&s->bus, sizeof(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);
diff --git a/hw/ide/macio.c b/hw/ide/macio.c
index ef4ba2b..da94580 100644
--- a/hw/ide/macio.c
+++ b/hw/ide/macio.c
@@ -547,7 +547,7 @@ static void macio_ide_initfn(Object *obj)
     SysBusDevice *d = SYS_BUS_DEVICE(obj);
     MACIOIDEState *s = MACIO_IDE(obj);
 
-    ide_bus_new(&s->bus, DEVICE(obj), 0, 2);
+    ide_bus_new(&s->bus, sizeof(s->bus), DEVICE(obj), 0, 2);
     memory_region_init_io(&s->mem, obj, &pmac_ide_ops, s, "pmac-ide", 0x1000);
     sysbus_init_mmio(d, &s->mem);
     sysbus_init_irq(d, &s->irq);
diff --git a/hw/ide/mmio.c b/hw/ide/mmio.c
index d251ff9..9f66a52 100644
--- a/hw/ide/mmio.c
+++ b/hw/ide/mmio.c
@@ -137,7 +137,7 @@ static void mmio_ide_initfn(Object *obj)
     SysBusDevice *d = SYS_BUS_DEVICE(obj);
     MMIOState *s = MMIO_IDE(obj);
 
-    ide_bus_new(&s->bus, DEVICE(obj), 0, 2);
+    ide_bus_new(&s->bus, sizeof(s->bus), DEVICE(obj), 0, 2);
     sysbus_init_irq(d, &s->irq);
 }
 
diff --git a/hw/ide/piix.c b/hw/ide/piix.c
index e6e6c0b..ab36749 100644
--- a/hw/ide/piix.c
+++ b/hw/ide/piix.c
@@ -136,7 +136,7 @@ static void pci_piix_init_ports(PCIIDEState *d) {
     int i;
 
     for (i = 0; i < 2; i++) {
-        ide_bus_new(&d->bus[i], DEVICE(d), i, 2);
+        ide_bus_new(&d->bus[i], sizeof(d->bus[i]), DEVICE(d), i, 2);
         ide_init_ioport(&d->bus[i], NULL, port_info[i].iobase,
                         port_info[i].iobase2);
         ide_init2(&d->bus[i], isa_get_irq(NULL, port_info[i].isairq));
diff --git a/hw/ide/qdev.c b/hw/ide/qdev.c
index 1d84e15..8be76ab 100644
--- a/hw/ide/qdev.c
+++ b/hw/ide/qdev.c
@@ -47,7 +47,8 @@ static const TypeInfo ide_bus_info = {
     .class_init = ide_bus_class_init,
 };
 
-void ide_bus_new(IDEBus *idebus, DeviceState *dev, int bus_id, int max_units)
+void ide_bus_new(IDEBus *idebus, size_t idebus_size, DeviceState *dev,
+                 int bus_id, int max_units)
 {
     qbus_create_inplace(&idebus->qbus, TYPE_IDE_BUS, dev, NULL);
     idebus->bus_id = bus_id;
diff --git a/hw/ide/via.c b/hw/ide/via.c
index e5fb297..99468c7 100644
--- a/hw/ide/via.c
+++ b/hw/ide/via.c
@@ -159,7 +159,7 @@ static void vt82c686b_init_ports(PCIIDEState *d) {
     int i;
 
     for (i = 0; i < 2; i++) {
-        ide_bus_new(&d->bus[i], DEVICE(d), i, 2);
+        ide_bus_new(&d->bus[i], sizeof(d->bus[i]), DEVICE(d), i, 2);
         ide_init_ioport(&d->bus[i], NULL, port_info[i].iobase,
                         port_info[i].iobase2);
         ide_init2(&d->bus[i], isa_get_irq(NULL, port_info[i].isairq));
commit 77cbb28a5b90dbd183e1139734bcc2ac9ecbdd6a
Author: Andreas Färber <afaerber at suse.de>
Date:   Fri Aug 23 20:07:28 2013 +0200

    ipack: Pass size to ipack_bus_new_inplace()
    
    To be passed to qbus_create_inplace().
    
    Simplify DEVICE() cast to avoid parent field access.
    
    Reviewed-by: Wenchao Xia <xiawenc at linux.vnet.ibm.com>
    Signed-off-by: Andreas Färber <afaerber at suse.de>

diff --git a/hw/char/ipack.c b/hw/char/ipack.c
index f890471..5fb7073 100644
--- a/hw/char/ipack.c
+++ b/hw/char/ipack.c
@@ -24,7 +24,8 @@ IPackDevice *ipack_device_find(IPackBus *bus, int32_t slot)
     return NULL;
 }
 
-void ipack_bus_new_inplace(IPackBus *bus, DeviceState *parent,
+void ipack_bus_new_inplace(IPackBus *bus, size_t bus_size,
+                           DeviceState *parent,
                            const char *name, uint8_t n_slots,
                            qemu_irq_handler handler)
 {
diff --git a/hw/char/ipack.h b/hw/char/ipack.h
index f2b7a12..f8dc0f2 100644
--- a/hw/char/ipack.h
+++ b/hw/char/ipack.h
@@ -72,7 +72,8 @@ extern const VMStateDescription vmstate_ipack_device;
     VMSTATE_STRUCT(_field, _state, 1, vmstate_ipack_device, IPackDevice)
 
 IPackDevice *ipack_device_find(IPackBus *bus, int32_t slot);
-void ipack_bus_new_inplace(IPackBus *bus, DeviceState *parent,
+void ipack_bus_new_inplace(IPackBus *bus, size_t bus_size,
+                           DeviceState *parent,
                            const char *name, uint8_t n_slots,
                            qemu_irq_handler handler);
 
diff --git a/hw/char/tpci200.c b/hw/char/tpci200.c
index d9e17b2..e04ff26 100644
--- a/hw/char/tpci200.c
+++ b/hw/char/tpci200.c
@@ -607,7 +607,7 @@ static int tpci200_initfn(PCIDevice *pci_dev)
     pci_register_bar(&s->dev, 4, PCI_BASE_ADDRESS_SPACE_MEMORY, &s->las2);
     pci_register_bar(&s->dev, 5, PCI_BASE_ADDRESS_SPACE_MEMORY, &s->las3);
 
-    ipack_bus_new_inplace(&s->bus, DEVICE(&s->dev), NULL,
+    ipack_bus_new_inplace(&s->bus, sizeof(s->bus), DEVICE(pci_dev), NULL,
                           N_MODULES, tpci200_set_irq);
 
     return 0;
commit ab809e84a722f8fa1bcdeac5e3ebae10d90fb788
Author: Andreas Färber <afaerber at suse.de>
Date:   Fri Aug 23 20:05:16 2013 +0200

    intel-hda: Pass size to hda_codec_bus_init()
    
    To be passed to qbus_create_inplace().
    
    Reviewed-by: Wenchao Xia <xiawenc at linux.vnet.ibm.com>
    Signed-off-by: Andreas Färber <afaerber at suse.de>

diff --git a/hw/audio/intel-hda.c b/hw/audio/intel-hda.c
index 78f9d28..6849c73 100644
--- a/hw/audio/intel-hda.c
+++ b/hw/audio/intel-hda.c
@@ -40,7 +40,7 @@ static const TypeInfo hda_codec_bus_info = {
     .instance_size = sizeof(HDACodecBus),
 };
 
-void hda_codec_bus_init(DeviceState *dev, HDACodecBus *bus,
+void hda_codec_bus_init(DeviceState *dev, HDACodecBus *bus, size_t bus_size,
                         hda_codec_response_func response,
                         hda_codec_xfer_func xfer)
 {
@@ -1142,7 +1142,7 @@ static int intel_hda_init(PCIDevice *pci)
         msi_init(&d->pci, 0x50, 1, true, false);
     }
 
-    hda_codec_bus_init(DEVICE(pci), &d->codecs,
+    hda_codec_bus_init(DEVICE(pci), &d->codecs, sizeof(d->codecs),
                        intel_hda_response, intel_hda_xfer);
 
     return 0;
diff --git a/hw/audio/intel-hda.h b/hw/audio/intel-hda.h
index 2544f0a..d784bcf 100644
--- a/hw/audio/intel-hda.h
+++ b/hw/audio/intel-hda.h
@@ -48,7 +48,7 @@ struct HDACodecDevice {
     uint32_t            cad;    /* codec address */
 };
 
-void hda_codec_bus_init(DeviceState *dev, HDACodecBus *bus,
+void hda_codec_bus_init(DeviceState *dev, HDACodecBus *bus, size_t bus_size,
                         hda_codec_response_func response,
                         hda_codec_xfer_func xfer);
 HDACodecDevice *hda_codec_find(HDACodecBus *bus, uint32_t cad);
commit 53caad9a31bed10f59c70406001b9217bda2d111
Author: Andreas Färber <afaerber at suse.de>
Date:   Sat Aug 24 01:12:33 2013 +0200

    qom: Fix object_initialize_with_type() argument name in documentation
    
    @obj -> @data.
    
    Reviewed-by: Wenchao Xia <xiawenc at linux.vnet.ibm.com>
    Signed-off-by: Andreas Färber <afaerber at suse.de>

diff --git a/include/qom/object.h b/include/qom/object.h
index 48109de..c463ced 100644
--- a/include/qom/object.h
+++ b/include/qom/object.h
@@ -585,7 +585,7 @@ Object *object_new_with_type(Type type);
 
 /**
  * object_initialize_with_type:
- * @obj: A pointer to the memory to be used for the object.
+ * @data: A pointer to the memory to be used for the object.
  * @type: The type of the object to instantiate.
  *
  * This function will initialize an object.  The memory for the object should
commit e65177a87f22b98b3b82433d05a18a2c4a3714da
Author: Peter Maydell <peter.maydell at linaro.org>
Date:   Fri Aug 23 14:38:55 2013 +0100

    virtio: Remove unnecessary OBJECT() casts
    
    There's no need to cast the first argument of object_initialize()
    to Object. Remove these unnecessary casts.
    
    Signed-off-by: Peter Maydell <peter.maydell at linaro.org>
    Signed-off-by: Andreas Färber <afaerber at suse.de>

diff --git a/hw/s390x/s390-virtio-bus.c b/hw/s390x/s390-virtio-bus.c
index f0aa941..e46b8c8 100644
--- a/hw/s390x/s390-virtio-bus.c
+++ b/hw/s390x/s390-virtio-bus.c
@@ -170,7 +170,7 @@ static int s390_virtio_net_init(VirtIOS390Device *s390_dev)
 static void s390_virtio_net_instance_init(Object *obj)
 {
     VirtIONetS390 *dev = VIRTIO_NET_S390(obj);
-    object_initialize(OBJECT(&dev->vdev), TYPE_VIRTIO_NET);
+    object_initialize(&dev->vdev, TYPE_VIRTIO_NET);
     object_property_add_child(obj, "virtio-backend", OBJECT(&dev->vdev), NULL);
 }
 
@@ -189,7 +189,7 @@ static int s390_virtio_blk_init(VirtIOS390Device *s390_dev)
 static void s390_virtio_blk_instance_init(Object *obj)
 {
     VirtIOBlkS390 *dev = VIRTIO_BLK_S390(obj);
-    object_initialize(OBJECT(&dev->vdev), TYPE_VIRTIO_BLK);
+    object_initialize(&dev->vdev, TYPE_VIRTIO_BLK);
     object_property_add_child(obj, "virtio-backend", OBJECT(&dev->vdev), NULL);
 }
 
@@ -230,7 +230,7 @@ static int s390_virtio_serial_init(VirtIOS390Device *s390_dev)
 static void s390_virtio_serial_instance_init(Object *obj)
 {
     VirtIOSerialS390 *dev = VIRTIO_SERIAL_S390(obj);
-    object_initialize(OBJECT(&dev->vdev), TYPE_VIRTIO_SERIAL);
+    object_initialize(&dev->vdev, TYPE_VIRTIO_SERIAL);
     object_property_add_child(obj, "virtio-backend", OBJECT(&dev->vdev), NULL);
 }
 
@@ -262,7 +262,7 @@ static int s390_virtio_scsi_init(VirtIOS390Device *s390_dev)
 static void s390_virtio_scsi_instance_init(Object *obj)
 {
     VirtIOSCSIS390 *dev = VIRTIO_SCSI_S390(obj);
-    object_initialize(OBJECT(&dev->vdev), TYPE_VIRTIO_SCSI);
+    object_initialize(&dev->vdev, TYPE_VIRTIO_SCSI);
     object_property_add_child(obj, "virtio-backend", OBJECT(&dev->vdev), NULL);
 }
 
@@ -283,7 +283,7 @@ static int s390_vhost_scsi_init(VirtIOS390Device *s390_dev)
 static void s390_vhost_scsi_instance_init(Object *obj)
 {
     VHostSCSIS390 *dev = VHOST_SCSI_S390(obj);
-    object_initialize(OBJECT(&dev->vdev), TYPE_VHOST_SCSI);
+    object_initialize(&dev->vdev, TYPE_VHOST_SCSI);
     object_property_add_child(obj, "virtio-backend", OBJECT(&dev->vdev), NULL);
 }
 #endif
@@ -309,7 +309,7 @@ static int s390_virtio_rng_init(VirtIOS390Device *s390_dev)
 static void s390_virtio_rng_instance_init(Object *obj)
 {
     VirtIORNGS390 *dev = VIRTIO_RNG_S390(obj);
-    object_initialize(OBJECT(&dev->vdev), TYPE_VIRTIO_RNG);
+    object_initialize(&dev->vdev, TYPE_VIRTIO_RNG);
     object_property_add_child(obj, "virtio-backend", OBJECT(&dev->vdev), NULL);
     object_property_add_link(obj, "rng", TYPE_RNG_BACKEND,
                              (Object **)&dev->vdev.conf.rng, NULL);
diff --git a/hw/s390x/virtio-ccw.c b/hw/s390x/virtio-ccw.c
index 8835bd4..e3b207f 100644
--- a/hw/s390x/virtio-ccw.c
+++ b/hw/s390x/virtio-ccw.c
@@ -659,7 +659,7 @@ static int virtio_ccw_net_init(VirtioCcwDevice *ccw_dev)
 static void virtio_ccw_net_instance_init(Object *obj)
 {
     VirtIONetCcw *dev = VIRTIO_NET_CCW(obj);
-    object_initialize(OBJECT(&dev->vdev), TYPE_VIRTIO_NET);
+    object_initialize(&dev->vdev, TYPE_VIRTIO_NET);
     object_property_add_child(obj, "virtio-backend", OBJECT(&dev->vdev), NULL);
 }
 
@@ -679,7 +679,7 @@ static int virtio_ccw_blk_init(VirtioCcwDevice *ccw_dev)
 static void virtio_ccw_blk_instance_init(Object *obj)
 {
     VirtIOBlkCcw *dev = VIRTIO_BLK_CCW(obj);
-    object_initialize(OBJECT(&dev->vdev), TYPE_VIRTIO_BLK);
+    object_initialize(&dev->vdev, TYPE_VIRTIO_BLK);
     object_property_add_child(obj, "virtio-backend", OBJECT(&dev->vdev), NULL);
 }
 
@@ -712,7 +712,7 @@ static int virtio_ccw_serial_init(VirtioCcwDevice *ccw_dev)
 static void virtio_ccw_serial_instance_init(Object *obj)
 {
     VirtioSerialCcw *dev = VIRTIO_SERIAL_CCW(obj);
-    object_initialize(OBJECT(&dev->vdev), TYPE_VIRTIO_SERIAL);
+    object_initialize(&dev->vdev, TYPE_VIRTIO_SERIAL);
     object_property_add_child(obj, "virtio-backend", OBJECT(&dev->vdev), NULL);
 }
 
@@ -758,7 +758,7 @@ static void balloon_ccw_stats_set_poll_interval(Object *obj, struct Visitor *v,
 static void virtio_ccw_balloon_instance_init(Object *obj)
 {
     VirtIOBalloonCcw *dev = VIRTIO_BALLOON_CCW(obj);
-    object_initialize(OBJECT(&dev->vdev), TYPE_VIRTIO_BALLOON);
+    object_initialize(&dev->vdev, TYPE_VIRTIO_BALLOON);
     object_property_add_child(obj, "virtio-backend", OBJECT(&dev->vdev), NULL);
 
     object_property_add(obj, "guest-stats", "guest statistics",
@@ -798,7 +798,7 @@ static int virtio_ccw_scsi_init(VirtioCcwDevice *ccw_dev)
 static void virtio_ccw_scsi_instance_init(Object *obj)
 {
     VirtIOSCSICcw *dev = VIRTIO_SCSI_CCW(obj);
-    object_initialize(OBJECT(&dev->vdev), TYPE_VIRTIO_SCSI);
+    object_initialize(&dev->vdev, TYPE_VIRTIO_SCSI);
     object_property_add_child(obj, "virtio-backend", OBJECT(&dev->vdev), NULL);
 }
 
@@ -819,7 +819,7 @@ static int vhost_ccw_scsi_init(VirtioCcwDevice *ccw_dev)
 static void vhost_ccw_scsi_instance_init(Object *obj)
 {
     VHostSCSICcw *dev = VHOST_SCSI_CCW(obj);
-    object_initialize(OBJECT(&dev->vdev), TYPE_VHOST_SCSI);
+    object_initialize(&dev->vdev, TYPE_VHOST_SCSI);
     object_property_add_child(obj, "virtio-backend", OBJECT(&dev->vdev), NULL);
 }
 #endif
@@ -1170,7 +1170,7 @@ static const TypeInfo vhost_ccw_scsi = {
 static void virtio_ccw_rng_instance_init(Object *obj)
 {
     VirtIORNGCcw *dev = VIRTIO_RNG_CCW(obj);
-    object_initialize(OBJECT(&dev->vdev), TYPE_VIRTIO_RNG);
+    object_initialize(&dev->vdev, TYPE_VIRTIO_RNG);
     object_property_add_child(obj, "virtio-backend", OBJECT(&dev->vdev), NULL);
     object_property_add_link(obj, "rng", TYPE_RNG_BACKEND,
                              (Object **)&dev->vdev.conf.rng, NULL);
diff --git a/hw/virtio/virtio-pci.c b/hw/virtio/virtio-pci.c
index f2c489b..8df43d6 100644
--- a/hw/virtio/virtio-pci.c
+++ b/hw/virtio/virtio-pci.c
@@ -918,7 +918,7 @@ static void virtio_9p_pci_class_init(ObjectClass *klass, void *data)
 static void virtio_9p_pci_instance_init(Object *obj)
 {
     V9fsPCIState *dev = VIRTIO_9P_PCI(obj);
-    object_initialize(OBJECT(&dev->vdev), TYPE_VIRTIO_9P);
+    object_initialize(&dev->vdev, TYPE_VIRTIO_9P);
     object_property_add_child(obj, "virtio-backend", OBJECT(&dev->vdev), NULL);
 }
 
@@ -1078,7 +1078,7 @@ static void virtio_blk_pci_class_init(ObjectClass *klass, void *data)
 static void virtio_blk_pci_instance_init(Object *obj)
 {
     VirtIOBlkPCI *dev = VIRTIO_BLK_PCI(obj);
-    object_initialize(OBJECT(&dev->vdev), TYPE_VIRTIO_BLK);
+    object_initialize(&dev->vdev, TYPE_VIRTIO_BLK);
     object_property_add_child(obj, "virtio-backend", OBJECT(&dev->vdev), NULL);
 }
 
@@ -1148,7 +1148,7 @@ static void virtio_scsi_pci_class_init(ObjectClass *klass, void *data)
 static void virtio_scsi_pci_instance_init(Object *obj)
 {
     VirtIOSCSIPCI *dev = VIRTIO_SCSI_PCI(obj);
-    object_initialize(OBJECT(&dev->vdev), TYPE_VIRTIO_SCSI);
+    object_initialize(&dev->vdev, TYPE_VIRTIO_SCSI);
     object_property_add_child(obj, "virtio-backend", OBJECT(&dev->vdev), NULL);
 }
 
@@ -1205,7 +1205,7 @@ static void vhost_scsi_pci_class_init(ObjectClass *klass, void *data)
 static void vhost_scsi_pci_instance_init(Object *obj)
 {
     VHostSCSIPCI *dev = VHOST_SCSI_PCI(obj);
-    object_initialize(OBJECT(&dev->vdev), TYPE_VHOST_SCSI);
+    object_initialize(&dev->vdev, TYPE_VHOST_SCSI);
     object_property_add_child(obj, "virtio-backend", OBJECT(&dev->vdev), NULL);
 }
 
@@ -1286,7 +1286,7 @@ static void virtio_balloon_pci_class_init(ObjectClass *klass, void *data)
 static void virtio_balloon_pci_instance_init(Object *obj)
 {
     VirtIOBalloonPCI *dev = VIRTIO_BALLOON_PCI(obj);
-    object_initialize(OBJECT(&dev->vdev), TYPE_VIRTIO_BALLOON);
+    object_initialize(&dev->vdev, TYPE_VIRTIO_BALLOON);
     object_property_add_child(obj, "virtio-backend", OBJECT(&dev->vdev), NULL);
 
     object_property_add(obj, "guest-stats", "guest statistics",
@@ -1372,7 +1372,7 @@ static void virtio_serial_pci_class_init(ObjectClass *klass, void *data)
 static void virtio_serial_pci_instance_init(Object *obj)
 {
     VirtIOSerialPCI *dev = VIRTIO_SERIAL_PCI(obj);
-    object_initialize(OBJECT(&dev->vdev), TYPE_VIRTIO_SERIAL);
+    object_initialize(&dev->vdev, TYPE_VIRTIO_SERIAL);
     object_property_add_child(obj, "virtio-backend", OBJECT(&dev->vdev), NULL);
 }
 
@@ -1431,7 +1431,7 @@ static void virtio_net_pci_class_init(ObjectClass *klass, void *data)
 static void virtio_net_pci_instance_init(Object *obj)
 {
     VirtIONetPCI *dev = VIRTIO_NET_PCI(obj);
-    object_initialize(OBJECT(&dev->vdev), TYPE_VIRTIO_NET);
+    object_initialize(&dev->vdev, TYPE_VIRTIO_NET);
     object_property_add_child(obj, "virtio-backend", OBJECT(&dev->vdev), NULL);
 }
 
@@ -1487,7 +1487,7 @@ static void virtio_rng_pci_class_init(ObjectClass *klass, void *data)
 static void virtio_rng_initfn(Object *obj)
 {
     VirtIORngPCI *dev = VIRTIO_RNG_PCI(obj);
-    object_initialize(OBJECT(&dev->vdev), TYPE_VIRTIO_RNG);
+    object_initialize(&dev->vdev, TYPE_VIRTIO_RNG);
     object_property_add_child(obj, "virtio-backend", OBJECT(&dev->vdev), NULL);
     object_property_add_link(obj, "rng", TYPE_RNG_BACKEND,
                              (Object **)&dev->vdev.conf.rng, NULL);
commit 70392912eddf4e19801b2e96c0156fea634b4e59
Author: Peter Chubb <peter.chubb at nicta.com.au>
Date:   Wed Aug 7 12:31:55 2013 +1000

    object: Fix typo in qom/object.h
    
    There's been a cut-and-paste error, it looks like, in the documentation
    in qom/object.h.
    
    Signed-off-by: Peter Chubb <peter.chubb at nicta.com.au>
    Signed-off-by: Andreas Färber <afaerber at suse.de>

diff --git a/include/qom/object.h b/include/qom/object.h
index 9b69065..48109de 100644
--- a/include/qom/object.h
+++ b/include/qom/object.h
@@ -249,7 +249,7 @@ typedef struct InterfaceInfo InterfaceInfo;
  *     MyClass parent_class;
  *
  *     MyDoSomething parent_do_something;
- * } MyClass;
+ * } DerivedClass;
  *
  * static void derived_do_something(MyState *obj)
  * {
commit 4ff78e0dbcd5c795962567fdc1b31e9e03c55b07
Merge: b95fdc0 7ca0e06
Author: Anthony Liguori <anthony at codemonkey.ws>
Date:   Fri Aug 30 12:26:04 2013 -0500

    Merge remote-tracking branch 'luiz/queue/qmp' into staging
    
    # By Wenchao Xia (15) and Stefan Weil (1)
    # Via Luiz Capitulino
    * luiz/queue/qmp:
      monitor: improve auto complete of "help" for single command in sub group
      monitor: allow "help" show message for single command in sub group
      monitor: support sub command in auto completion
      monitor: refine monitor_find_completion()
      monitor: support sub command in help
      monitor: refine parse_cmdline()
      monitor: code move for parse_cmdline()
      monitor: avoid direct use of global variable *mon_cmds
      monitor: split off monitor_data_init()
      monitor: call sortcmdlist() only one time
      monitor: avoid use of global *cur_mon in readline_completion()
      monitor: avoid use of global *cur_mon in monitor_find_completion()
      monitor: avoid use of global *cur_mon in block_completion_it()
      monitor: avoid use of global *cur_mon in file_completion()
      monitor: avoid use of global *cur_mon in cmd_completion()
      monitor: Add missing attributes to local function
    
    Message-id: 1377865357-6742-1-git-send-email-lcapitulino at redhat.com

commit b95fdc0e99e9b5c98bb8e2aee9eaffe160f1031b
Merge: b5d54bd 7f7f975
Author: Anthony Liguori <anthony at codemonkey.ws>
Date:   Fri Aug 30 12:25:56 2013 -0500

    Merge remote-tracking branch 'borntraeger/tags/kdump' into staging
    
    This is a set of patches dealing with kdump support for s390x/kvm.
    kdump on s390x uses subcode 1 of diagnose 0x308 to put the hardware
    in a defined state. This is different from a full reset, since it
    does not touch all CPU registers.
    These patches define the cpu resets, the subsystem reset a load
    function and also wires up the "nmi" command to issue a RESTART
    interrupt as defined in the z/Architecture principles of operation.
    
    This allows recent guest kernels with properly setup userspace
    to trigger kdump:
    - via guest crash
    - via nmi from the host
    
    # gpg: Signature made Fri 30 Aug 2013 07:19:18 AM CDT using RSA key ID B5A61C7C
    # gpg: Can't check signature: public key not found
    
    # By Christian Borntraeger (5) and Eugene (jno) Dvurechenski (2)
    # Via Christian Borntraeger
    * borntraeger/tags/kdump:
      s390: wire up nmi command to raise a RESTART interrupt on S390
      s390: Implement load normal reset
      s390/cpu: split CPU reset into architectured functions
      s390: provide a cpu load normal function
      s390: provide I/O subsystem reset
      s390/kvm: basic implementation of diagnose 308 subcode 6
      s390x/kvm: Fix switch/case indentation for handle_diag
    
    Message-id: 1377810649-47484-1-git-send-email-borntraeger at de.ibm.com

commit e23e400ec62a03dea58ddb38479b4f1ef86f556d
Author: Max Reitz <mreitz at redhat.com>
Date:   Fri Aug 30 14:34:28 2013 +0200

    qcow2-refcount: Repair OFLAG_COPIED errors
    
    Since the OFLAG_COPIED checks are now executed after the refcounts have
    been repaired (if repairing), it is safe to assume that they are correct
    but the OFLAG_COPIED flag may be not. Therefore, if its value differs
    from what it should be (considering the according refcount), that
    discrepancy can be repaired by correctly setting (or clearing that flag.
    
    Signed-off-by: Max Reitz <mreitz at redhat.com>
    Signed-off-by: Kevin Wolf <kwolf at redhat.com>

diff --git a/block/qcow2-cluster.c b/block/qcow2-cluster.c
index 7c248aa..2d5aa92 100644
--- a/block/qcow2-cluster.c
+++ b/block/qcow2-cluster.c
@@ -145,7 +145,7 @@ static int l2_load(BlockDriverState *bs, uint64_t l2_offset,
  * and we really don't want bdrv_pread to perform a read-modify-write)
  */
 #define L1_ENTRIES_PER_SECTOR (512 / 8)
-static int write_l1_entry(BlockDriverState *bs, int l1_index)
+int qcow2_write_l1_entry(BlockDriverState *bs, int l1_index)
 {
     BDRVQcowState *s = bs->opaque;
     uint64_t buf[L1_ENTRIES_PER_SECTOR];
@@ -254,7 +254,7 @@ static int l2_allocate(BlockDriverState *bs, int l1_index, uint64_t **table)
     /* update the L1 entry */
     trace_qcow2_l2_allocate_write_l1(bs, l1_index);
     s->l1_table[l1_index] = l2_offset | QCOW_OFLAG_COPIED;
-    ret = write_l1_entry(bs, l1_index);
+    ret = qcow2_write_l1_entry(bs, l1_index);
     if (ret < 0) {
         goto fail;
     }
diff --git a/block/qcow2-refcount.c b/block/qcow2-refcount.c
index aa4b98d..2276b6f 100644
--- a/block/qcow2-refcount.c
+++ b/block/qcow2-refcount.c
@@ -1225,7 +1225,8 @@ fail:
  * been already detected and sufficiently signaled by the calling function
  * (qcow2_check_refcounts) by the time this function is called).
  */
-static int check_oflag_copied(BlockDriverState *bs, BdrvCheckResult *res)
+static int check_oflag_copied(BlockDriverState *bs, BdrvCheckResult *res,
+                              BdrvCheckMode fix)
 {
     BDRVQcowState *s = bs->opaque;
     uint64_t *l2_table = qemu_blockalign(bs, s->cluster_size);
@@ -1236,6 +1237,7 @@ static int check_oflag_copied(BlockDriverState *bs, BdrvCheckResult *res)
     for (i = 0; i < s->l1_size; i++) {
         uint64_t l1_entry = s->l1_table[i];
         uint64_t l2_offset = l1_entry & L1E_OFFSET_MASK;
+        bool l2_dirty = false;
 
         if (!l2_offset) {
             continue;
@@ -1247,10 +1249,24 @@ static int check_oflag_copied(BlockDriverState *bs, BdrvCheckResult *res)
             continue;
         }
         if ((refcount == 1) != ((l1_entry & QCOW_OFLAG_COPIED) != 0)) {
-            fprintf(stderr, "ERROR OFLAG_COPIED L2 cluster: l1_index=%d "
+            fprintf(stderr, "%s OFLAG_COPIED L2 cluster: l1_index=%d "
                     "l1_entry=%" PRIx64 " refcount=%d\n",
+                    fix & BDRV_FIX_ERRORS ? "Repairing" :
+                                            "ERROR",
                     i, l1_entry, refcount);
-            res->corruptions++;
+            if (fix & BDRV_FIX_ERRORS) {
+                s->l1_table[i] = refcount == 1
+                               ? l1_entry |  QCOW_OFLAG_COPIED
+                               : l1_entry & ~QCOW_OFLAG_COPIED;
+                ret = qcow2_write_l1_entry(bs, i);
+                if (ret < 0) {
+                    res->check_errors++;
+                    goto fail;
+                }
+                res->corruptions_fixed++;
+            } else {
+                res->corruptions++;
+            }
         }
 
         ret = bdrv_pread(bs->file, l2_offset, l2_table,
@@ -1275,13 +1291,43 @@ static int check_oflag_copied(BlockDriverState *bs, BdrvCheckResult *res)
                     continue;
                 }
                 if ((refcount == 1) != ((l2_entry & QCOW_OFLAG_COPIED) != 0)) {
-                    fprintf(stderr, "ERROR OFLAG_COPIED data cluster: "
+                    fprintf(stderr, "%s OFLAG_COPIED data cluster: "
                             "l2_entry=%" PRIx64 " refcount=%d\n",
+                            fix & BDRV_FIX_ERRORS ? "Repairing" :
+                                                    "ERROR",
                             l2_entry, refcount);
-                    res->corruptions++;
+                    if (fix & BDRV_FIX_ERRORS) {
+                        l2_table[j] = cpu_to_be64(refcount == 1
+                                    ? l2_entry |  QCOW_OFLAG_COPIED
+                                    : l2_entry & ~QCOW_OFLAG_COPIED);
+                        l2_dirty = true;
+                        res->corruptions_fixed++;
+                    } else {
+                        res->corruptions++;
+                    }
                 }
             }
         }
+
+        if (l2_dirty) {
+            ret = qcow2_pre_write_overlap_check(bs,
+                    QCOW2_OL_DEFAULT & ~QCOW2_OL_ACTIVE_L2, l2_offset,
+                    s->cluster_size);
+            if (ret < 0) {
+                fprintf(stderr, "ERROR: Could not write L2 table; metadata "
+                        "overlap check failed: %s\n", strerror(-ret));
+                res->check_errors++;
+                goto fail;
+            }
+
+            ret = bdrv_pwrite(bs->file, l2_offset, l2_table, s->cluster_size);
+            if (ret < 0) {
+                fprintf(stderr, "ERROR: Could not write L2 table: %s\n",
+                        strerror(-ret));
+                res->check_errors++;
+                goto fail;
+            }
+        }
     }
 
     ret = 0;
@@ -1427,7 +1473,7 @@ int qcow2_check_refcounts(BlockDriverState *bs, BdrvCheckResult *res,
     }
 
     /* check OFLAG_COPIED */
-    ret = check_oflag_copied(bs, res);
+    ret = check_oflag_copied(bs, res, fix);
     if (ret < 0) {
         goto fail;
     }
diff --git a/block/qcow2.h b/block/qcow2.h
index d4448c6..1000239 100644
--- a/block/qcow2.h
+++ b/block/qcow2.h
@@ -432,6 +432,7 @@ int qcow2_pre_write_overlap_check(BlockDriverState *bs, int chk, int64_t offset,
 /* qcow2-cluster.c functions */
 int qcow2_grow_l1_table(BlockDriverState *bs, uint64_t min_size,
                         bool exact_size);
+int qcow2_write_l1_entry(BlockDriverState *bs, int l1_index);
 void qcow2_l2_cache_reset(BlockDriverState *bs);
 int qcow2_decompress_cluster(BlockDriverState *bs, uint64_t cluster_offset);
 void qcow2_encrypt_sectors(BDRVQcowState *s, int64_t sector_num,
commit 4f6ed88c03c4026e31ce152ea760a0da839f0dda
Author: Max Reitz <mreitz at redhat.com>
Date:   Fri Aug 30 14:34:27 2013 +0200

    qcow2-refcount: Move OFLAG_COPIED checks
    
    Move the OFLAG_COPIED checks out of check_refcounts_l1 and
    check_refcounts_l2 and after the actual refcount checks/fixes (since the
    refcounts might actually change there).
    
    Signed-off-by: Max Reitz <mreitz at redhat.com>
    Signed-off-by: Kevin Wolf <kwolf at redhat.com>

diff --git a/block/qcow2-refcount.c b/block/qcow2-refcount.c
index 8ee2f13..aa4b98d 100644
--- a/block/qcow2-refcount.c
+++ b/block/qcow2-refcount.c
@@ -1053,7 +1053,7 @@ static int check_refcounts_l2(BlockDriverState *bs, BdrvCheckResult *res,
     BDRVQcowState *s = bs->opaque;
     uint64_t *l2_table, l2_entry;
     uint64_t next_contiguous_offset = 0;
-    int i, l2_size, nb_csectors, refcount;
+    int i, l2_size, nb_csectors;
 
     /* Read L2 table from disk */
     l2_size = s->l2_size * sizeof(uint64_t);
@@ -1105,23 +1105,8 @@ static int check_refcounts_l2(BlockDriverState *bs, BdrvCheckResult *res,
 
         case QCOW2_CLUSTER_NORMAL:
         {
-            /* QCOW_OFLAG_COPIED must be set iff refcount == 1 */
             uint64_t offset = l2_entry & L2E_OFFSET_MASK;
 
-            if (flags & CHECK_OFLAG_COPIED) {
-                refcount = get_refcount(bs, offset >> s->cluster_bits);
-                if (refcount < 0) {
-                    fprintf(stderr, "Can't get refcount for offset %"
-                        PRIx64 ": %s\n", l2_entry, strerror(-refcount));
-                    goto fail;
-                }
-                if ((refcount == 1) != ((l2_entry & QCOW_OFLAG_COPIED) != 0)) {
-                    fprintf(stderr, "ERROR OFLAG_COPIED: offset=%"
-                        PRIx64 " refcount=%d\n", l2_entry, refcount);
-                    res->corruptions++;
-                }
-            }
-
             if (flags & CHECK_FRAG_INFO) {
                 res->bfi.allocated_clusters++;
                 if (next_contiguous_offset &&
@@ -1178,7 +1163,7 @@ static int check_refcounts_l1(BlockDriverState *bs,
 {
     BDRVQcowState *s = bs->opaque;
     uint64_t *l1_table, l2_offset, l1_size2;
-    int i, refcount, ret;
+    int i, ret;
 
     l1_size2 = l1_size * sizeof(uint64_t);
 
@@ -1202,22 +1187,6 @@ static int check_refcounts_l1(BlockDriverState *bs,
     for(i = 0; i < l1_size; i++) {
         l2_offset = l1_table[i];
         if (l2_offset) {
-            /* QCOW_OFLAG_COPIED must be set iff refcount == 1 */
-            if (flags & CHECK_OFLAG_COPIED) {
-                refcount = get_refcount(bs, (l2_offset & ~QCOW_OFLAG_COPIED)
-                    >> s->cluster_bits);
-                if (refcount < 0) {
-                    fprintf(stderr, "Can't get refcount for l2_offset %"
-                        PRIx64 ": %s\n", l2_offset, strerror(-refcount));
-                    goto fail;
-                }
-                if ((refcount == 1) != ((l2_offset & QCOW_OFLAG_COPIED) != 0)) {
-                    fprintf(stderr, "ERROR OFLAG_COPIED: l2_offset=%" PRIx64
-                        " refcount=%d\n", l2_offset, refcount);
-                    res->corruptions++;
-                }
-            }
-
             /* Mark L2 table as used */
             l2_offset &= L1E_OFFSET_MASK;
             inc_refcounts(bs, res, refcount_table, refcount_table_size,
@@ -1249,6 +1218,80 @@ fail:
 }
 
 /*
+ * Checks the OFLAG_COPIED flag for all L1 and L2 entries.
+ *
+ * This function does not print an error message nor does it increment
+ * check_errors if get_refcount fails (this is because such an error will have
+ * been already detected and sufficiently signaled by the calling function
+ * (qcow2_check_refcounts) by the time this function is called).
+ */
+static int check_oflag_copied(BlockDriverState *bs, BdrvCheckResult *res)
+{
+    BDRVQcowState *s = bs->opaque;
+    uint64_t *l2_table = qemu_blockalign(bs, s->cluster_size);
+    int ret;
+    int refcount;
+    int i, j;
+
+    for (i = 0; i < s->l1_size; i++) {
+        uint64_t l1_entry = s->l1_table[i];
+        uint64_t l2_offset = l1_entry & L1E_OFFSET_MASK;
+
+        if (!l2_offset) {
+            continue;
+        }
+
+        refcount = get_refcount(bs, l2_offset >> s->cluster_bits);
+        if (refcount < 0) {
+            /* don't print message nor increment check_errors */
+            continue;
+        }
+        if ((refcount == 1) != ((l1_entry & QCOW_OFLAG_COPIED) != 0)) {
+            fprintf(stderr, "ERROR OFLAG_COPIED L2 cluster: l1_index=%d "
+                    "l1_entry=%" PRIx64 " refcount=%d\n",
+                    i, l1_entry, refcount);
+            res->corruptions++;
+        }
+
+        ret = bdrv_pread(bs->file, l2_offset, l2_table,
+                         s->l2_size * sizeof(uint64_t));
+        if (ret < 0) {
+            fprintf(stderr, "ERROR: Could not read L2 table: %s\n",
+                    strerror(-ret));
+            res->check_errors++;
+            goto fail;
+        }
+
+        for (j = 0; j < s->l2_size; j++) {
+            uint64_t l2_entry = be64_to_cpu(l2_table[j]);
+            uint64_t data_offset = l2_entry & L2E_OFFSET_MASK;
+            int cluster_type = qcow2_get_cluster_type(l2_entry);
+
+            if ((cluster_type == QCOW2_CLUSTER_NORMAL) ||
+                ((cluster_type == QCOW2_CLUSTER_ZERO) && (data_offset != 0))) {
+                refcount = get_refcount(bs, data_offset >> s->cluster_bits);
+                if (refcount < 0) {
+                    /* don't print message nor increment check_errors */
+                    continue;
+                }
+                if ((refcount == 1) != ((l2_entry & QCOW_OFLAG_COPIED) != 0)) {
+                    fprintf(stderr, "ERROR OFLAG_COPIED data cluster: "
+                            "l2_entry=%" PRIx64 " refcount=%d\n",
+                            l2_entry, refcount);
+                    res->corruptions++;
+                }
+            }
+        }
+    }
+
+    ret = 0;
+
+fail:
+    qemu_vfree(l2_table);
+    return ret;
+}
+
+/*
  * Checks an image for refcount consistency.
  *
  * Returns 0 if no errors are found, the number of errors in case the image is
@@ -1383,6 +1426,12 @@ int qcow2_check_refcounts(BlockDriverState *bs, BdrvCheckResult *res,
         }
     }
 
+    /* check OFLAG_COPIED */
+    ret = check_oflag_copied(bs, res);
+    if (ret < 0) {
+        goto fail;
+    }
+
     res->image_end_offset = (highest_cluster + 1) * s->cluster_size;
     ret = 0;
 
commit cf93980e775b709ec8f33f55846e6dcf1c7a612c
Author: Max Reitz <mreitz at redhat.com>
Date:   Fri Aug 30 14:34:26 2013 +0200

    qcow2: Employ metadata overlap checks
    
    The pre-write overlap check function is now called before most of the
    qcow2 writes (aborting it on collision or other error).
    
    Signed-off-by: Max Reitz <mreitz at redhat.com>
    Signed-off-by: Kevin Wolf <kwolf at redhat.com>

diff --git a/block/qcow2-cache.c b/block/qcow2-cache.c
index 2f3114e..7bcae09 100644
--- a/block/qcow2-cache.c
+++ b/block/qcow2-cache.c
@@ -115,6 +115,23 @@ static int qcow2_cache_entry_flush(BlockDriverState *bs, Qcow2Cache *c, int i)
     }
 
     if (c == s->refcount_block_cache) {
+        ret = qcow2_pre_write_overlap_check(bs,
+                QCOW2_OL_DEFAULT & ~QCOW2_OL_REFCOUNT_BLOCK,
+                c->entries[i].offset, s->cluster_size);
+    } else if (c == s->l2_table_cache) {
+        ret = qcow2_pre_write_overlap_check(bs,
+                QCOW2_OL_DEFAULT & ~QCOW2_OL_ACTIVE_L2,
+                c->entries[i].offset, s->cluster_size);
+    } else {
+        ret = qcow2_pre_write_overlap_check(bs, QCOW2_OL_DEFAULT,
+                c->entries[i].offset, s->cluster_size);
+    }
+
+    if (ret < 0) {
+        return ret;
+    }
+
+    if (c == s->refcount_block_cache) {
         BLKDBG_EVENT(bs->file, BLKDBG_REFBLOCK_UPDATE_PART);
     } else if (c == s->l2_table_cache) {
         BLKDBG_EVENT(bs->file, BLKDBG_L2_UPDATE);
diff --git a/block/qcow2-cluster.c b/block/qcow2-cluster.c
index cca76d4..7c248aa 100644
--- a/block/qcow2-cluster.c
+++ b/block/qcow2-cluster.c
@@ -80,6 +80,14 @@ int qcow2_grow_l1_table(BlockDriverState *bs, uint64_t min_size,
         goto fail;
     }
 
+    /* the L1 position has not yet been updated, so these clusters must
+     * indeed be completely free */
+    ret = qcow2_pre_write_overlap_check(bs, QCOW2_OL_DEFAULT,
+                                        new_l1_table_offset, new_l1_size2);
+    if (ret < 0) {
+        goto fail;
+    }
+
     BLKDBG_EVENT(bs->file, BLKDBG_L1_GROW_WRITE_TABLE);
     for(i = 0; i < s->l1_size; i++)
         new_l1_table[i] = cpu_to_be64(new_l1_table[i]);
@@ -149,6 +157,13 @@ static int write_l1_entry(BlockDriverState *bs, int l1_index)
         buf[i] = cpu_to_be64(s->l1_table[l1_start_index + i]);
     }
 
+    ret = qcow2_pre_write_overlap_check(bs,
+            QCOW2_OL_DEFAULT & ~QCOW2_OL_ACTIVE_L1,
+            s->l1_table_offset + 8 * l1_start_index, sizeof(buf));
+    if (ret < 0) {
+        return ret;
+    }
+
     BLKDBG_EVENT(bs->file, BLKDBG_L1_UPDATE);
     ret = bdrv_pwrite_sync(bs->file, s->l1_table_offset + 8 * l1_start_index,
         buf, sizeof(buf));
@@ -368,6 +383,12 @@ static int coroutine_fn copy_sectors(BlockDriverState *bs,
                         &s->aes_encrypt_key);
     }
 
+    ret = qcow2_pre_write_overlap_check(bs, QCOW2_OL_DEFAULT,
+            cluster_offset + n_start * BDRV_SECTOR_SIZE, n * BDRV_SECTOR_SIZE);
+    if (ret < 0) {
+        goto out;
+    }
+
     BLKDBG_EVENT(bs->file, BLKDBG_COW_WRITE);
     ret = bdrv_co_writev(bs->file, (cluster_offset >> 9) + n_start, n, &qiov);
     if (ret < 0) {
diff --git a/block/qcow2-snapshot.c b/block/qcow2-snapshot.c
index 0caac90..e7e6013 100644
--- a/block/qcow2-snapshot.c
+++ b/block/qcow2-snapshot.c
@@ -189,6 +189,15 @@ static int qcow2_write_snapshots(BlockDriverState *bs)
         return ret;
     }
 
+    /* The snapshot list position has not yet been updated, so these clusters
+     * must indeed be completely free */
+    ret = qcow2_pre_write_overlap_check(bs, QCOW2_OL_DEFAULT, offset,
+                                        s->snapshots_size);
+    if (ret < 0) {
+        return ret;
+    }
+
+
     /* Write all snapshots to the new list */
     for(i = 0; i < s->nb_snapshots; i++) {
         sn = s->snapshots + i;
@@ -363,6 +372,12 @@ int qcow2_snapshot_create(BlockDriverState *bs, QEMUSnapshotInfo *sn_info)
         l1_table[i] = cpu_to_be64(s->l1_table[i]);
     }
 
+    ret = qcow2_pre_write_overlap_check(bs, QCOW2_OL_DEFAULT,
+            sn->l1_table_offset, s->l1_size * sizeof(uint64_t));
+    if (ret < 0) {
+        goto fail;
+    }
+
     ret = bdrv_pwrite(bs->file, sn->l1_table_offset, l1_table,
                       s->l1_size * sizeof(uint64_t));
     if (ret < 0) {
@@ -475,6 +490,13 @@ int qcow2_snapshot_goto(BlockDriverState *bs, const char *snapshot_id)
         goto fail;
     }
 
+    ret = qcow2_pre_write_overlap_check(bs,
+            QCOW2_OL_DEFAULT & ~QCOW2_OL_ACTIVE_L1,
+            s->l1_table_offset, cur_l1_bytes);
+    if (ret < 0) {
+        goto fail;
+    }
+
     ret = bdrv_pwrite_sync(bs->file, s->l1_table_offset, sn_l1_table,
                            cur_l1_bytes);
     if (ret < 0) {
diff --git a/block/qcow2.c b/block/qcow2.c
index fe91568..05e002d 100644
--- a/block/qcow2.c
+++ b/block/qcow2.c
@@ -624,6 +624,8 @@ static int qcow2_open(BlockDriverState *bs, QDict *options, int flags)
     qcow2_free_snapshots(bs);
     qcow2_refcount_close(bs);
     g_free(s->l1_table);
+    /* else pre-write overlap checks in cache_destroy may crash */
+    s->l1_table = NULL;
     if (s->l2_table_cache) {
         qcow2_cache_destroy(bs, s->l2_table_cache);
     }
@@ -923,6 +925,13 @@ static coroutine_fn int qcow2_co_writev(BlockDriverState *bs,
                 cur_nr_sectors * 512);
         }
 
+        ret = qcow2_pre_write_overlap_check(bs, QCOW2_OL_DEFAULT,
+                cluster_offset + index_in_cluster * BDRV_SECTOR_SIZE,
+                cur_nr_sectors * BDRV_SECTOR_SIZE);
+        if (ret < 0) {
+            goto fail;
+        }
+
         qemu_co_mutex_unlock(&s->lock);
         BLKDBG_EVENT(bs->file, BLKDBG_WRITE_AIO);
         trace_qcow2_writev_data(qemu_coroutine_self(),
@@ -989,6 +998,8 @@ static void qcow2_close(BlockDriverState *bs)
 {
     BDRVQcowState *s = bs->opaque;
     g_free(s->l1_table);
+    /* else pre-write overlap checks in cache_destroy may crash */
+    s->l1_table = NULL;
 
     qcow2_cache_flush(bs, s->l2_table_cache);
     qcow2_cache_flush(bs, s->refcount_block_cache);
@@ -1668,6 +1679,14 @@ static int qcow2_write_compressed(BlockDriverState *bs, int64_t sector_num,
 
     if (ret != Z_STREAM_END || out_len >= s->cluster_size) {
         /* could not compress: write normal cluster */
+
+        ret = qcow2_pre_write_overlap_check(bs, QCOW2_OL_DEFAULT,
+                sector_num * BDRV_SECTOR_SIZE,
+                s->cluster_sectors * BDRV_SECTOR_SIZE);
+        if (ret < 0) {
+            goto fail;
+        }
+
         ret = bdrv_write(bs, sector_num, buf, s->cluster_sectors);
         if (ret < 0) {
             goto fail;
@@ -1680,6 +1699,13 @@ static int qcow2_write_compressed(BlockDriverState *bs, int64_t sector_num,
             goto fail;
         }
         cluster_offset &= s->cluster_offset_mask;
+
+        ret = qcow2_pre_write_overlap_check(bs, QCOW2_OL_DEFAULT,
+                cluster_offset, out_len);
+        if (ret < 0) {
+            goto fail;
+        }
+
         BLKDBG_EVENT(bs->file, BLKDBG_WRITE_COMPRESSED);
         ret = bdrv_pwrite(bs->file, cluster_offset, out_buf, out_len);
         if (ret < 0) {
commit a40f1c2add4d5f58d594f810fe36cabcf32bc4b0
Author: Max Reitz <mreitz at redhat.com>
Date:   Fri Aug 30 14:34:25 2013 +0200

    qcow2: Metadata overlap checks
    
    Two new functions are added; the first one checks a given range in the
    image file for overlaps with metadata (main header, L1 tables, L2
    tables, refcount table and blocks).
    
    The second one should be used immediately before writing to the image
    file as it calls the first function and, upon collision, marks the
    image as corrupt and makes the BDS unusable, thereby preventing
    further access.
    
    Both functions take a bitmask argument specifying the structures which
    should be checked for overlaps, making it possible to also check
    metadata writes against colliding with other structures.
    
    Signed-off-by: Max Reitz <mreitz at redhat.com>
    Signed-off-by: Kevin Wolf <kwolf at redhat.com>

diff --git a/block/qcow2-refcount.c b/block/qcow2-refcount.c
index a61224a..8ee2f13 100644
--- a/block/qcow2-refcount.c
+++ b/block/qcow2-refcount.c
@@ -25,6 +25,8 @@
 #include "qemu-common.h"
 #include "block/block_int.h"
 #include "block/qcow2.h"
+#include "qemu/range.h"
+#include "qapi/qmp/types.h"
 
 static int64_t alloc_clusters_noref(BlockDriverState *bs, int64_t size);
 static int QEMU_WARN_UNUSED_RESULT update_refcount(BlockDriverState *bs,
@@ -1390,3 +1392,173 @@ fail:
     return ret;
 }
 
+#define overlaps_with(ofs, sz) \
+    ranges_overlap(offset, size, ofs, sz)
+
+/*
+ * Checks if the given offset into the image file is actually free to use by
+ * looking for overlaps with important metadata sections (L1/L2 tables etc.),
+ * i.e. a sanity check without relying on the refcount tables.
+ *
+ * The chk parameter specifies exactly what checks to perform (being a bitmask
+ * of QCow2MetadataOverlap values).
+ *
+ * Returns:
+ * - 0 if writing to this offset will not affect the mentioned metadata
+ * - a positive QCow2MetadataOverlap value indicating one overlapping section
+ * - a negative value (-errno) indicating an error while performing a check,
+ *   e.g. when bdrv_read failed on QCOW2_OL_INACTIVE_L2
+ */
+int qcow2_check_metadata_overlap(BlockDriverState *bs, int chk, int64_t offset,
+                                 int64_t size)
+{
+    BDRVQcowState *s = bs->opaque;
+    int i, j;
+
+    if (!size) {
+        return 0;
+    }
+
+    if (chk & QCOW2_OL_MAIN_HEADER) {
+        if (offset < s->cluster_size) {
+            return QCOW2_OL_MAIN_HEADER;
+        }
+    }
+
+    /* align range to test to cluster boundaries */
+    size = align_offset(offset_into_cluster(s, offset) + size, s->cluster_size);
+    offset = start_of_cluster(s, offset);
+
+    if ((chk & QCOW2_OL_ACTIVE_L1) && s->l1_size) {
+        if (overlaps_with(s->l1_table_offset, s->l1_size * sizeof(uint64_t))) {
+            return QCOW2_OL_ACTIVE_L1;
+        }
+    }
+
+    if ((chk & QCOW2_OL_REFCOUNT_TABLE) && s->refcount_table_size) {
+        if (overlaps_with(s->refcount_table_offset,
+            s->refcount_table_size * sizeof(uint64_t))) {
+            return QCOW2_OL_REFCOUNT_TABLE;
+        }
+    }
+
+    if ((chk & QCOW2_OL_SNAPSHOT_TABLE) && s->snapshots_size) {
+        if (overlaps_with(s->snapshots_offset, s->snapshots_size)) {
+            return QCOW2_OL_SNAPSHOT_TABLE;
+        }
+    }
+
+    if ((chk & QCOW2_OL_INACTIVE_L1) && s->snapshots) {
+        for (i = 0; i < s->nb_snapshots; i++) {
+            if (s->snapshots[i].l1_size &&
+                overlaps_with(s->snapshots[i].l1_table_offset,
+                s->snapshots[i].l1_size * sizeof(uint64_t))) {
+                return QCOW2_OL_INACTIVE_L1;
+            }
+        }
+    }
+
+    if ((chk & QCOW2_OL_ACTIVE_L2) && s->l1_table) {
+        for (i = 0; i < s->l1_size; i++) {
+            if ((s->l1_table[i] & L1E_OFFSET_MASK) &&
+                overlaps_with(s->l1_table[i] & L1E_OFFSET_MASK,
+                s->cluster_size)) {
+                return QCOW2_OL_ACTIVE_L2;
+            }
+        }
+    }
+
+    if ((chk & QCOW2_OL_REFCOUNT_BLOCK) && s->refcount_table) {
+        for (i = 0; i < s->refcount_table_size; i++) {
+            if ((s->refcount_table[i] & REFT_OFFSET_MASK) &&
+                overlaps_with(s->refcount_table[i] & REFT_OFFSET_MASK,
+                s->cluster_size)) {
+                return QCOW2_OL_REFCOUNT_BLOCK;
+            }
+        }
+    }
+
+    if ((chk & QCOW2_OL_INACTIVE_L2) && s->snapshots) {
+        for (i = 0; i < s->nb_snapshots; i++) {
+            uint64_t l1_ofs = s->snapshots[i].l1_table_offset;
+            uint32_t l1_sz  = s->snapshots[i].l1_size;
+            uint64_t *l1 = g_malloc(l1_sz * sizeof(uint64_t));
+            int ret;
+
+            ret = bdrv_read(bs->file, l1_ofs / BDRV_SECTOR_SIZE, (uint8_t *)l1,
+                            l1_sz * sizeof(uint64_t) / BDRV_SECTOR_SIZE);
+
+            if (ret < 0) {
+                g_free(l1);
+                return ret;
+            }
+
+            for (j = 0; j < l1_sz; j++) {
+                if ((l1[j] & L1E_OFFSET_MASK) &&
+                    overlaps_with(l1[j] & L1E_OFFSET_MASK, s->cluster_size)) {
+                    g_free(l1);
+                    return QCOW2_OL_INACTIVE_L2;
+                }
+            }
+
+            g_free(l1);
+        }
+    }
+
+    return 0;
+}
+
+static const char *metadata_ol_names[] = {
+    [QCOW2_OL_MAIN_HEADER_BITNR]    = "qcow2_header",
+    [QCOW2_OL_ACTIVE_L1_BITNR]      = "active L1 table",
+    [QCOW2_OL_ACTIVE_L2_BITNR]      = "active L2 table",
+    [QCOW2_OL_REFCOUNT_TABLE_BITNR] = "refcount table",
+    [QCOW2_OL_REFCOUNT_BLOCK_BITNR] = "refcount block",
+    [QCOW2_OL_SNAPSHOT_TABLE_BITNR] = "snapshot table",
+    [QCOW2_OL_INACTIVE_L1_BITNR]    = "inactive L1 table",
+    [QCOW2_OL_INACTIVE_L2_BITNR]    = "inactive L2 table",
+};
+
+/*
+ * First performs a check for metadata overlaps (through
+ * qcow2_check_metadata_overlap); if that fails with a negative value (error
+ * while performing a check), that value is returned. If an impending overlap
+ * is detected, the BDS will be made unusable, the qcow2 file marked corrupt
+ * and -EIO returned.
+ *
+ * Returns 0 if there were neither overlaps nor errors while checking for
+ * overlaps; or a negative value (-errno) on error.
+ */
+int qcow2_pre_write_overlap_check(BlockDriverState *bs, int chk, int64_t offset,
+                                  int64_t size)
+{
+    int ret = qcow2_check_metadata_overlap(bs, chk, offset, size);
+
+    if (ret < 0) {
+        return ret;
+    } else if (ret > 0) {
+        int metadata_ol_bitnr = ffs(ret) - 1;
+        char *message;
+        QObject *data;
+
+        assert(metadata_ol_bitnr < QCOW2_OL_MAX_BITNR);
+
+        fprintf(stderr, "qcow2: Preventing invalid write on metadata (overlaps "
+                "with %s); image marked as corrupt.\n",
+                metadata_ol_names[metadata_ol_bitnr]);
+        message = g_strdup_printf("Prevented %s overwrite",
+                metadata_ol_names[metadata_ol_bitnr]);
+        data = qobject_from_jsonf("{ 'device': %s, 'msg': %s, 'offset': %"
+                PRId64 ", 'size': %" PRId64 " }", bs->device_name, message,
+                offset, size);
+        monitor_protocol_event(QEVENT_BLOCK_IMAGE_CORRUPTED, data);
+        g_free(message);
+        qobject_decref(data);
+
+        qcow2_mark_corrupt(bs);
+        bs->drv = NULL; /* make BDS unusable */
+        return -EIO;
+    }
+
+    return 0;
+}
diff --git a/block/qcow2.h b/block/qcow2.h
index 32ecb33..d4448c6 100644
--- a/block/qcow2.h
+++ b/block/qcow2.h
@@ -289,6 +289,40 @@ enum {
     QCOW2_CLUSTER_ZERO
 };
 
+typedef enum QCow2MetadataOverlap {
+    QCOW2_OL_MAIN_HEADER_BITNR    = 0,
+    QCOW2_OL_ACTIVE_L1_BITNR      = 1,
+    QCOW2_OL_ACTIVE_L2_BITNR      = 2,
+    QCOW2_OL_REFCOUNT_TABLE_BITNR = 3,
+    QCOW2_OL_REFCOUNT_BLOCK_BITNR = 4,
+    QCOW2_OL_SNAPSHOT_TABLE_BITNR = 5,
+    QCOW2_OL_INACTIVE_L1_BITNR    = 6,
+    QCOW2_OL_INACTIVE_L2_BITNR    = 7,
+
+    QCOW2_OL_MAX_BITNR            = 8,
+
+    QCOW2_OL_NONE           = 0,
+    QCOW2_OL_MAIN_HEADER    = (1 << QCOW2_OL_MAIN_HEADER_BITNR),
+    QCOW2_OL_ACTIVE_L1      = (1 << QCOW2_OL_ACTIVE_L1_BITNR),
+    QCOW2_OL_ACTIVE_L2      = (1 << QCOW2_OL_ACTIVE_L2_BITNR),
+    QCOW2_OL_REFCOUNT_TABLE = (1 << QCOW2_OL_REFCOUNT_TABLE_BITNR),
+    QCOW2_OL_REFCOUNT_BLOCK = (1 << QCOW2_OL_REFCOUNT_BLOCK_BITNR),
+    QCOW2_OL_SNAPSHOT_TABLE = (1 << QCOW2_OL_SNAPSHOT_TABLE_BITNR),
+    QCOW2_OL_INACTIVE_L1    = (1 << QCOW2_OL_INACTIVE_L1_BITNR),
+    /* NOTE: Checking overlaps with inactive L2 tables will result in bdrv
+     * reads. */
+    QCOW2_OL_INACTIVE_L2    = (1 << QCOW2_OL_INACTIVE_L2_BITNR),
+} QCow2MetadataOverlap;
+
+/* Perform all overlap checks which don't require disk access */
+#define QCOW2_OL_CACHED \
+    (QCOW2_OL_MAIN_HEADER | QCOW2_OL_ACTIVE_L1 | QCOW2_OL_ACTIVE_L2 | \
+     QCOW2_OL_REFCOUNT_TABLE | QCOW2_OL_REFCOUNT_BLOCK | \
+     QCOW2_OL_SNAPSHOT_TABLE | QCOW2_OL_INACTIVE_L1)
+
+/* The default checks to perform */
+#define QCOW2_OL_DEFAULT QCOW2_OL_CACHED
+
 #define L1E_OFFSET_MASK 0x00ffffffffffff00ULL
 #define L2E_OFFSET_MASK 0x00ffffffffffff00ULL
 #define L2E_COMPRESSED_OFFSET_SIZE_MASK 0x3fffffffffffffffULL
@@ -390,6 +424,11 @@ int qcow2_check_refcounts(BlockDriverState *bs, BdrvCheckResult *res,
 
 void qcow2_process_discards(BlockDriverState *bs, int ret);
 
+int qcow2_check_metadata_overlap(BlockDriverState *bs, int chk, int64_t offset,
+                                 int64_t size);
+int qcow2_pre_write_overlap_check(BlockDriverState *bs, int chk, int64_t offset,
+                                  int64_t size);
+
 /* qcow2-cluster.c functions */
 int qcow2_grow_l1_table(BlockDriverState *bs, uint64_t min_size,
                         bool exact_size);
diff --git a/include/monitor/monitor.h b/include/monitor/monitor.h
index 1942cc4..10fa0e3 100644
--- a/include/monitor/monitor.h
+++ b/include/monitor/monitor.h
@@ -48,6 +48,7 @@ typedef enum MonitorEvent {
     QEVENT_BALLOON_CHANGE,
     QEVENT_SPICE_MIGRATE_COMPLETED,
     QEVENT_GUEST_PANICKED,
+    QEVENT_BLOCK_IMAGE_CORRUPTED,
 
     /* Add to 'monitor_event_names' array in monitor.c when
      * defining new events here */
diff --git a/monitor.c b/monitor.c
index ee9744c..2c542e1 100644
--- a/monitor.c
+++ b/monitor.c
@@ -504,6 +504,7 @@ static const char *monitor_event_names[] = {
     [QEVENT_BALLOON_CHANGE] = "BALLOON_CHANGE",
     [QEVENT_SPICE_MIGRATE_COMPLETED] = "SPICE_MIGRATE_COMPLETED",
     [QEVENT_GUEST_PANICKED] = "GUEST_PANICKED",
+    [QEVENT_BLOCK_IMAGE_CORRUPTED] = "BLOCK_IMAGE_CORRUPTED",
 };
 QEMU_BUILD_BUG_ON(ARRAY_SIZE(monitor_event_names) != QEVENT_MAX)
 
commit 69c98726537627e708abb8fcb33e3a2b10e40bf1
Author: Max Reitz <mreitz at redhat.com>
Date:   Fri Aug 30 14:34:24 2013 +0200

    qcow2: Add corrupt bit
    
    This adds an incompatible bit indicating corruption to qcow2. Any image
    with this bit set may not be written to unless for repairing (and
    subsequently clearing the bit if the repair has been successful).
    
    Signed-off-by: Max Reitz <mreitz at redhat.com>
    Signed-off-by: Kevin Wolf <kwolf at redhat.com>

diff --git a/block/qcow2.c b/block/qcow2.c
index 5e5f413..fe91568 100644
--- a/block/qcow2.c
+++ b/block/qcow2.c
@@ -272,6 +272,37 @@ static int qcow2_mark_clean(BlockDriverState *bs)
     return 0;
 }
 
+/*
+ * Marks the image as corrupt.
+ */
+int qcow2_mark_corrupt(BlockDriverState *bs)
+{
+    BDRVQcowState *s = bs->opaque;
+
+    s->incompatible_features |= QCOW2_INCOMPAT_CORRUPT;
+    return qcow2_update_header(bs);
+}
+
+/*
+ * Marks the image as consistent, i.e., unsets the corrupt bit, and flushes
+ * before if necessary.
+ */
+int qcow2_mark_consistent(BlockDriverState *bs)
+{
+    BDRVQcowState *s = bs->opaque;
+
+    if (s->incompatible_features & QCOW2_INCOMPAT_CORRUPT) {
+        int ret = bdrv_flush(bs);
+        if (ret < 0) {
+            return ret;
+        }
+
+        s->incompatible_features &= ~QCOW2_INCOMPAT_CORRUPT;
+        return qcow2_update_header(bs);
+    }
+    return 0;
+}
+
 static int qcow2_check(BlockDriverState *bs, BdrvCheckResult *result,
                        BdrvCheckMode fix)
 {
@@ -402,6 +433,17 @@ static int qcow2_open(BlockDriverState *bs, QDict *options, int flags)
         goto fail;
     }
 
+    if (s->incompatible_features & QCOW2_INCOMPAT_CORRUPT) {
+        /* Corrupt images may not be written to unless they are being repaired
+         */
+        if ((flags & BDRV_O_RDWR) && !(flags & BDRV_O_CHECK)) {
+            error_report("qcow2: Image is corrupt; cannot be opened "
+                    "read/write.");
+            ret = -EACCES;
+            goto fail;
+        }
+    }
+
     /* Check support for various header values */
     if (header.refcount_order != 4) {
         report_unsupported(bs, "%d bit reference counts",
@@ -1130,6 +1172,11 @@ int qcow2_update_header(BlockDriverState *bs)
             .name = "dirty bit",
         },
         {
+            .type = QCOW2_FEAT_TYPE_INCOMPATIBLE,
+            .bit  = QCOW2_INCOMPAT_CORRUPT_BITNR,
+            .name = "corrupt bit",
+        },
+        {
             .type = QCOW2_FEAT_TYPE_COMPATIBLE,
             .bit  = QCOW2_COMPAT_LAZY_REFCOUNTS_BITNR,
             .name = "lazy refcounts",
diff --git a/block/qcow2.h b/block/qcow2.h
index 365a17e..32ecb33 100644
--- a/block/qcow2.h
+++ b/block/qcow2.h
@@ -119,9 +119,12 @@ enum {
 /* Incompatible feature bits */
 enum {
     QCOW2_INCOMPAT_DIRTY_BITNR   = 0,
+    QCOW2_INCOMPAT_CORRUPT_BITNR = 1,
     QCOW2_INCOMPAT_DIRTY         = 1 << QCOW2_INCOMPAT_DIRTY_BITNR,
+    QCOW2_INCOMPAT_CORRUPT       = 1 << QCOW2_INCOMPAT_CORRUPT_BITNR,
 
-    QCOW2_INCOMPAT_MASK          = QCOW2_INCOMPAT_DIRTY,
+    QCOW2_INCOMPAT_MASK          = QCOW2_INCOMPAT_DIRTY
+                                 | QCOW2_INCOMPAT_CORRUPT,
 };
 
 /* Compatible feature bits */
@@ -361,6 +364,8 @@ int qcow2_backing_read1(BlockDriverState *bs, QEMUIOVector *qiov,
                   int64_t sector_num, int nb_sectors);
 
 int qcow2_mark_dirty(BlockDriverState *bs);
+int qcow2_mark_corrupt(BlockDriverState *bs);
+int qcow2_mark_consistent(BlockDriverState *bs);
 int qcow2_update_header(BlockDriverState *bs);
 
 /* qcow2-refcount.c functions */
diff --git a/docs/specs/qcow2.txt b/docs/specs/qcow2.txt
index 36a559d..33eca36 100644
--- a/docs/specs/qcow2.txt
+++ b/docs/specs/qcow2.txt
@@ -80,7 +80,12 @@ in the description of a field.
                                 tables to repair refcounts before accessing the
                                 image.
 
-                    Bits 1-63:  Reserved (set to 0)
+                    Bit 1:      Corrupt bit.  If this bit is set then any data
+                                structure may be corrupt and the image must not
+                                be written to (unless for regaining
+                                consistency).
+
+                    Bits 2-63:  Reserved (set to 0)
 
          80 -  87:  compatible_features
                     Bitmask of compatible features. An implementation can
diff --git a/tests/qemu-iotests/031.out b/tests/qemu-iotests/031.out
index 796c993..a943344 100644
--- a/tests/qemu-iotests/031.out
+++ b/tests/qemu-iotests/031.out
@@ -54,7 +54,7 @@ header_length             72
 
 Header extension:
 magic                     0x6803f857
-length                    96
+length                    144
 data                      <binary>
 
 Header extension:
@@ -68,7 +68,7 @@ No errors were found on the image.
 
 magic                     0x514649fb
 version                   2
-backing_file_offset       0xf8
+backing_file_offset       0x128
 backing_file_size         0x17
 cluster_bits              16
 size                      67108864
@@ -92,7 +92,7 @@ data                      'host_device'
 
 Header extension:
 magic                     0x6803f857
-length                    96
+length                    144
 data                      <binary>
 
 Header extension:
@@ -155,7 +155,7 @@ header_length             104
 
 Header extension:
 magic                     0x6803f857
-length                    96
+length                    144
 data                      <binary>
 
 Header extension:
@@ -169,7 +169,7 @@ No errors were found on the image.
 
 magic                     0x514649fb
 version                   3
-backing_file_offset       0x118
+backing_file_offset       0x148
 backing_file_size         0x17
 cluster_bits              16
 size                      67108864
@@ -193,7 +193,7 @@ data                      'host_device'
 
 Header extension:
 magic                     0x6803f857
-length                    96
+length                    144
 data                      <binary>
 
 Header extension:
diff --git a/tests/qemu-iotests/036.out b/tests/qemu-iotests/036.out
index 063ca22..55a3e6e 100644
--- a/tests/qemu-iotests/036.out
+++ b/tests/qemu-iotests/036.out
@@ -46,7 +46,7 @@ header_length             104
 
 Header extension:
 magic                     0x6803f857
-length                    96
+length                    144
 data                      <binary>
 
 *** done
commit 449df7063815489a0b091bcb3afa9ae80ae3acbf
Author: Max Reitz <mreitz at redhat.com>
Date:   Fri Aug 30 10:40:15 2013 +0200

    qemu-iotests: Snapshotting zero clusters
    
    This test creates an image with unallocated zero clusters, then creates
    a snapshot. Afterwards, there should be neither any errors nor leaks.
    
    Signed-off-by: Max Reitz <mreitz at redhat.com>
    Signed-off-by: Kevin Wolf <kwolf at redhat.com>

diff --git a/tests/qemu-iotests/062 b/tests/qemu-iotests/062
new file mode 100755
index 0000000..0511246
--- /dev/null
+++ b/tests/qemu-iotests/062
@@ -0,0 +1,64 @@
+#!/bin/bash
+#
+# Test case for snapshotting images with unallocated zero clusters in
+# qcow2
+#
+# 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=mreitz 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
+
+# This tests qocw2-specific low-level functionality
+_supported_fmt qcow2
+_supported_proto generic
+_supported_os Linux
+
+IMGOPTS="compat=1.1"
+IMG_SIZE=64M
+
+echo
+echo "=== Testing snapshotting an image with zero clusters ==="
+echo
+_make_test_img $IMG_SIZE
+# Write some zero clusters
+$QEMU_IO -c "write -z 0 256k" "$TEST_IMG" | _filter_qemu_io
+# Create a snapshot
+$QEMU_IMG snapshot -c foo "$TEST_IMG"
+# Check the image (there shouldn't be any errors or leaks)
+_check_test_img
+
+# success, all done
+echo "*** done"
+rm -f $seq.full
+status=0
diff --git a/tests/qemu-iotests/062.out b/tests/qemu-iotests/062.out
new file mode 100644
index 0000000..442d761
--- /dev/null
+++ b/tests/qemu-iotests/062.out
@@ -0,0 +1,9 @@
+QA output created by 062
+
+=== Testing snapshotting an image with zero clusters ===
+
+Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=67108864 
+wrote 262144/262144 bytes at offset 0
+256 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+No errors were found on the image.
+*** done
diff --git a/tests/qemu-iotests/group b/tests/qemu-iotests/group
index 93ace2e..fb13792 100644
--- a/tests/qemu-iotests/group
+++ b/tests/qemu-iotests/group
@@ -64,3 +64,4 @@
 055 rw auto
 056 rw auto backing
 059 rw auto
+062 rw auto
commit 8b81a7b6ba8686f35f9cb0acdd54004d63206f03
Author: Max Reitz <mreitz at redhat.com>
Date:   Fri Aug 30 10:40:14 2013 +0200

    qcow2-refcount: Snapshot update for zero clusters
    
    Account for all cluster types in qcow2_update_snapshot_refcounts;
    this prevents this function from updating the refcount of unallocated
    zero clusters which effectively led to wrong adjustments of the refcount
    of cluster 0 (the main qcow2 header). This in turn resulted in images
    with (unallocated) zero clusters having a cluster 0 refcount greater
    than one after creating a snapshot.
    
    Signed-off-by: Max Reitz <mreitz at redhat.com>
    Signed-off-by: Kevin Wolf <kwolf at redhat.com>

diff --git a/block/qcow2-refcount.c b/block/qcow2-refcount.c
index 1244693..a61224a 100644
--- a/block/qcow2-refcount.c
+++ b/block/qcow2-refcount.c
@@ -861,11 +861,14 @@ int qcow2_update_snapshot_refcount(BlockDriverState *bs,
             }
 
             for(j = 0; j < s->l2_size; j++) {
+                uint64_t cluster_index;
+
                 offset = be64_to_cpu(l2_table[j]);
-                if (offset != 0) {
-                    old_offset = offset;
-                    offset &= ~QCOW_OFLAG_COPIED;
-                    if (offset & QCOW_OFLAG_COMPRESSED) {
+                old_offset = offset;
+                offset &= ~QCOW_OFLAG_COPIED;
+
+                switch (qcow2_get_cluster_type(offset)) {
+                    case QCOW2_CLUSTER_COMPRESSED:
                         nb_csectors = ((offset >> s->csize_shift) &
                                        s->csize_mask) + 1;
                         if (addend != 0) {
@@ -880,8 +883,16 @@ int qcow2_update_snapshot_refcount(BlockDriverState *bs,
                         }
                         /* compressed clusters are never modified */
                         refcount = 2;
-                    } else {
-                        uint64_t cluster_index = (offset & L2E_OFFSET_MASK) >> s->cluster_bits;
+                        break;
+
+                    case QCOW2_CLUSTER_NORMAL:
+                    case QCOW2_CLUSTER_ZERO:
+                        cluster_index = (offset & L2E_OFFSET_MASK) >> s->cluster_bits;
+                        if (!cluster_index) {
+                            /* unallocated */
+                            refcount = 0;
+                            break;
+                        }
                         if (addend != 0) {
                             refcount = update_cluster_refcount(bs, cluster_index, addend,
                                                                QCOW2_DISCARD_SNAPSHOT);
@@ -893,19 +904,26 @@ int qcow2_update_snapshot_refcount(BlockDriverState *bs,
                             ret = refcount;
                             goto fail;
                         }
-                    }
+                        break;
 
-                    if (refcount == 1) {
-                        offset |= QCOW_OFLAG_COPIED;
-                    }
-                    if (offset != old_offset) {
-                        if (addend > 0) {
-                            qcow2_cache_set_dependency(bs, s->l2_table_cache,
-                                s->refcount_block_cache);
-                        }
-                        l2_table[j] = cpu_to_be64(offset);
-                        qcow2_cache_entry_mark_dirty(s->l2_table_cache, l2_table);
+                    case QCOW2_CLUSTER_UNALLOCATED:
+                        refcount = 0;
+                        break;
+
+                    default:
+                        abort();
+                }
+
+                if (refcount == 1) {
+                    offset |= QCOW_OFLAG_COPIED;
+                }
+                if (offset != old_offset) {
+                    if (addend > 0) {
+                        qcow2_cache_set_dependency(bs, s->l2_table_cache,
+                            s->refcount_block_cache);
                     }
+                    l2_table[j] = cpu_to_be64(offset);
+                    qcow2_cache_entry_mark_dirty(s->l2_table_cache, l2_table);
                 }
             }
 
commit d4ca092a423f1f853a99357bab01a168bb57d625
Author: Max Reitz <mreitz at redhat.com>
Date:   Thu Aug 29 11:15:44 2013 +0200

    option: Add assigned flag to QEMUOptionParameter
    
    Adds an "assigned" flag to QEMUOptionParameter which is cleared at the
    beginning of parse_option_parameters and set on (successful)
    set_option_parameter and set_option_parameter_int.
    
    Signed-off-by: Max Reitz <mreitz at redhat.com>
    Signed-off-by: Kevin Wolf <kwolf at redhat.com>

diff --git a/include/qemu/option.h b/include/qemu/option.h
index 7a58e47..63db4cc 100644
--- a/include/qemu/option.h
+++ b/include/qemu/option.h
@@ -46,6 +46,7 @@ typedef struct QEMUOptionParameter {
         char* s;
     } value;
     const char *help;
+    bool assigned;
 } QEMUOptionParameter;
 
 
diff --git a/util/qemu-option.c b/util/qemu-option.c
index 4ebdc4c..e0844a9 100644
--- a/util/qemu-option.c
+++ b/util/qemu-option.c
@@ -275,6 +275,8 @@ int set_option_parameter(QEMUOptionParameter *list, const char *name,
         return -1;
     }
 
+    list->assigned = true;
+
     return 0;
 }
 
@@ -306,6 +308,8 @@ int set_option_parameter_int(QEMUOptionParameter *list, const char *name,
         return -1;
     }
 
+    list->assigned = true;
+
     return 0;
 }
 
@@ -397,6 +401,7 @@ QEMUOptionParameter *parse_option_parameters(const char *param,
     char value[256];
     char *param_delim, *value_delim;
     char next_delim;
+    int i;
 
     if (list == NULL) {
         return NULL;
@@ -406,6 +411,10 @@ QEMUOptionParameter *parse_option_parameters(const char *param,
         dest = allocated = append_option_parameters(NULL, list);
     }
 
+    for (i = 0; dest[i].name; i++) {
+        dest[i].assigned = false;
+    }
+
     while (*param) {
 
         // Find parameter name and value in the string
commit 9faa574f7d07109e2256c0b4b63e8711d650f2d8
Author: Bharata B Rao <bharata at linux.vnet.ibm.com>
Date:   Tue Aug 27 13:45:41 2013 +0530

    gluster: Abort on AIO completion failure
    
    Currently if gluster AIO callback thread fails to notify the QEMU thread about
    AIO completion, we try graceful recovery by marking the disk drive as
    inaccessible. This error recovery code is race-prone as found by Asias and
    Stefan. However as found out by Paolo, this kind of error is impossible and
    hence simplify the code that handles this error recovery.
    
    Signed-off-by: Bharata B Rao <bharata at linux.vnet.ibm.com>
    Reviewed-by: Stefan Hajnoczi <stefanha at redhat.com>
    Signed-off-by: Kevin Wolf <kwolf at redhat.com>

diff --git a/block/gluster.c b/block/gluster.c
index 46f36f8..dbb03f4 100644
--- a/block/gluster.c
+++ b/block/gluster.c
@@ -427,20 +427,9 @@ static void gluster_finish_aiocb(struct glfs_fd *fd, ssize_t ret, void *arg)
         /*
          * Gluster AIO callback thread failed to notify the waiting
          * QEMU thread about IO completion.
-         *
-         * Complete this IO request and make the disk inaccessible for
-         * subsequent reads and writes.
          */
-        error_report("Gluster failed to notify QEMU about IO completion");
-
-        qemu_mutex_lock_iothread(); /* We are in gluster thread context */
-        acb->common.cb(acb->common.opaque, -EIO);
-        qemu_aio_release(acb);
-        close(s->fds[GLUSTER_FD_READ]);
-        close(s->fds[GLUSTER_FD_WRITE]);
-        qemu_aio_set_fd_handler(s->fds[GLUSTER_FD_READ], NULL, NULL, NULL);
-        bs->drv = NULL; /* Make the disk inaccessible */
-        qemu_mutex_unlock_iothread();
+        error_report("Gluster AIO completion failed: %s", strerror(errno));
+        abort();
     }
 }
 
commit e5b1d99f5528315dc77aab369ae060d7cbad1e2a
Author: Kevin Wolf <kwolf at redhat.com>
Date:   Wed Aug 28 15:15:52 2013 +0200

    block: Remove old raw driver
    
    This is unused code now.
    
    Signed-off-by: Kevin Wolf <kwolf at redhat.com>

diff --git a/block/raw.c b/block/raw.c
deleted file mode 100644
index 4751825..0000000
--- a/block/raw.c
+++ /dev/null
@@ -1,192 +0,0 @@
-/*
- * Block driver for RAW format
- *
- * Copyright (c) 2006 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 "qemu-common.h"
-#include "block/block_int.h"
-#include "qemu/module.h"
-
-static int raw_open(BlockDriverState *bs, QDict *options, int flags)
-{
-    bs->sg = bs->file->sg;
-    return 0;
-}
-
-/* We have nothing to do for raw reopen, stubs just return
- * success */
-static int raw_reopen_prepare(BDRVReopenState *state,
-                              BlockReopenQueue *queue,  Error **errp)
-{
-    return 0;
-}
-
-static int coroutine_fn raw_co_readv(BlockDriverState *bs, int64_t sector_num,
-                                     int nb_sectors, QEMUIOVector *qiov)
-{
-    BLKDBG_EVENT(bs->file, BLKDBG_READ_AIO);
-    return bdrv_co_readv(bs->file, sector_num, nb_sectors, qiov);
-}
-
-static int coroutine_fn raw_co_writev(BlockDriverState *bs, int64_t sector_num,
-                                      int nb_sectors, QEMUIOVector *qiov)
-{
-    BLKDBG_EVENT(bs->file, BLKDBG_WRITE_AIO);
-    return bdrv_co_writev(bs->file, sector_num, nb_sectors, qiov);
-}
-
-static void raw_close(BlockDriverState *bs)
-{
-}
-
-static int coroutine_fn raw_co_is_allocated(BlockDriverState *bs,
-                                            int64_t sector_num,
-                                            int nb_sectors, int *pnum)
-{
-    return bdrv_co_is_allocated(bs->file, sector_num, nb_sectors, pnum);
-}
-
-static int coroutine_fn raw_co_write_zeroes(BlockDriverState *bs,
-                                            int64_t sector_num,
-                                            int nb_sectors)
-{
-    return bdrv_co_write_zeroes(bs->file, sector_num, nb_sectors);
-}
-
-static int64_t raw_getlength(BlockDriverState *bs)
-{
-    return bdrv_getlength(bs->file);
-}
-
-static int raw_truncate(BlockDriverState *bs, int64_t offset)
-{
-    return bdrv_truncate(bs->file, offset);
-}
-
-static int raw_probe(const uint8_t *buf, int buf_size, const char *filename)
-{
-   return 1; /* everything can be opened as raw image */
-}
-
-static int coroutine_fn raw_co_discard(BlockDriverState *bs,
-                                       int64_t sector_num, int nb_sectors)
-{
-    return bdrv_co_discard(bs->file, sector_num, nb_sectors);
-}
-
-static int raw_is_inserted(BlockDriverState *bs)
-{
-    return bdrv_is_inserted(bs->file);
-}
-
-static int raw_media_changed(BlockDriverState *bs)
-{
-    return bdrv_media_changed(bs->file);
-}
-
-static void raw_eject(BlockDriverState *bs, bool eject_flag)
-{
-    bdrv_eject(bs->file, eject_flag);
-}
-
-static void raw_lock_medium(BlockDriverState *bs, bool locked)
-{
-    bdrv_lock_medium(bs->file, locked);
-}
-
-static int raw_ioctl(BlockDriverState *bs, unsigned long int req, void *buf)
-{
-   return bdrv_ioctl(bs->file, req, buf);
-}
-
-static BlockDriverAIOCB *raw_aio_ioctl(BlockDriverState *bs,
-        unsigned long int req, void *buf,
-        BlockDriverCompletionFunc *cb, void *opaque)
-{
-   return bdrv_aio_ioctl(bs->file, req, buf, cb, opaque);
-}
-
-static int raw_create(const char *filename, QEMUOptionParameter *options)
-{
-    return bdrv_create_file(filename, options);
-}
-
-static QEMUOptionParameter raw_create_options[] = {
-    {
-        .name = BLOCK_OPT_SIZE,
-        .type = OPT_SIZE,
-        .help = "Virtual disk size"
-    },
-    { NULL }
-};
-
-static int raw_has_zero_init(BlockDriverState *bs)
-{
-    return bdrv_has_zero_init(bs->file);
-}
-
-static int raw_get_info(BlockDriverState *bs, BlockDriverInfo *bdi)
-{
-    return bdrv_get_info(bs->file, bdi);
-}
-
-static BlockDriver bdrv_raw = {
-    .format_name        = "raw",
-
-    /* It's really 0, but we need to make g_malloc() happy */
-    .instance_size      = 1,
-
-    .bdrv_open          = raw_open,
-    .bdrv_close         = raw_close,
-
-    .bdrv_reopen_prepare  = raw_reopen_prepare,
-
-    .bdrv_co_readv          = raw_co_readv,
-    .bdrv_co_writev         = raw_co_writev,
-    .bdrv_co_is_allocated   = raw_co_is_allocated,
-    .bdrv_co_write_zeroes   = raw_co_write_zeroes,
-    .bdrv_co_discard        = raw_co_discard,
-
-    .bdrv_probe         = raw_probe,
-    .bdrv_getlength     = raw_getlength,
-    .bdrv_get_info      = raw_get_info,
-    .bdrv_truncate      = raw_truncate,
-
-    .bdrv_is_inserted   = raw_is_inserted,
-    .bdrv_media_changed = raw_media_changed,
-    .bdrv_eject         = raw_eject,
-    .bdrv_lock_medium   = raw_lock_medium,
-
-    .bdrv_ioctl         = raw_ioctl,
-    .bdrv_aio_ioctl     = raw_aio_ioctl,
-
-    .bdrv_create        = raw_create,
-    .create_options     = raw_create_options,
-    .bdrv_has_zero_init = raw_has_zero_init,
-};
-
-static void bdrv_raw_init(void)
-{
-    bdrv_register(&bdrv_raw);
-}
-
-block_init(bdrv_raw_init);
commit 7a6d3fc594d1166ec78a6b74ba76753078de0de5
Author: Laszlo Ersek <lersek at redhat.com>
Date:   Wed Aug 21 12:41:23 2013 +0200

    switch raw block driver from "raw.o" to "raw_bsd.o"
    
    "Incoming" function prototypes and "outgoing" function calls must match
    reality. Implemented using the "struct BlockDriver" definition in
    "include/block/block_int.h", and gcc errors & warnings.
    
    v1->v2:
    
    On 08/20/13 09:51, Kevin Wolf wrote:
    > Am 18.08.2013 um 16:29 hat Paolo Bonzini geschrieben:
    >> Il 16/08/2013 16:15, Laszlo Ersek ha scritto:
    >>> +static int raw_reopen_prepare(BDRVReopenState *reopen_state,
    >>> +                              BlockReopenQueue *queue, Error **errp)
    >>>  {
    >>> -    return bdrv_reopen_prepare(bs->file);
    >>> +    BDRVReopenState tmp = *reopen_state;
    >>> +
    >>> +    tmp.bs = tmp.bs->file;
    >>> +    return bdrv_reopen_prepare(&tmp, queue, errp);
    >>>  }
    >>
    >> This should just return zero, my fault.
    >
    > Which is because bdrv_reopen_queue() already queues bs->file for reopen.
    > The simple return 0; implementation is shared by all other format drivers
    > that support reopening images.
    
    Signed-off-by: Laszlo Ersek <lersek at redhat.com>
    Signed-off-by: Kevin Wolf <kwolf at redhat.com>

diff --git a/block/Makefile.objs b/block/Makefile.objs
index 4cf9aa4..3bb85b5 100644
--- a/block/Makefile.objs
+++ b/block/Makefile.objs
@@ -1,4 +1,4 @@
-block-obj-y += raw.o cow.o qcow.o vdi.o vmdk.o cloop.o dmg.o bochs.o vpc.o vvfat.o
+block-obj-y += raw_bsd.o cow.o qcow.o vdi.o vmdk.o cloop.o dmg.o bochs.o vpc.o vvfat.o
 block-obj-y += qcow2.o qcow2-refcount.o qcow2-cluster.o qcow2-snapshot.o qcow2-cache.o
 block-obj-y += qed.o qed-gencb.o qed-l2-cache.o qed-table.o qed-cluster.o
 block-obj-y += qed-check.o
diff --git a/block/raw_bsd.c b/block/raw_bsd.c
index 2dc1921..ab2b0fd 100644
--- a/block/raw_bsd.c
+++ b/block/raw_bsd.c
@@ -29,7 +29,7 @@
 #include "block/block_int.h"
 #include "qemu/option.h"
 
-static const QEMUOptionParameter raw_create_options[] = {
+static QEMUOptionParameter raw_create_options[] = {
     {
         .name = BLOCK_OPT_SIZE,
         .type = OPT_SIZE,
@@ -38,104 +38,114 @@ static const QEMUOptionParameter raw_create_options[] = {
     { 0 }
 };
 
-static TYPE raw_reopen_prepare(BlockDriverState *bs)
+static int raw_reopen_prepare(BDRVReopenState *reopen_state,
+                              BlockReopenQueue *queue, Error **errp)
 {
-    return bdrv_reopen_prepare(bs->file);
+    return 0;
 }
 
-static TYPE raw_co_readv(BlockDriverState *bs)
+static int coroutine_fn raw_co_readv(BlockDriverState *bs, int64_t sector_num,
+                                     int nb_sectors, QEMUIOVector *qiov)
 {
     BLKDBG_EVENT(bs->file, BLKDBG_READ_AIO);
-    return bdrv_co_readv(bs->file);
+    return bdrv_co_readv(bs->file, sector_num, nb_sectors, qiov);
 }
 
-static TYPE raw_co_writev(BlockDriverState *bs)
+static int coroutine_fn raw_co_writev(BlockDriverState *bs, int64_t sector_num,
+                                      int nb_sectors, QEMUIOVector *qiov)
 {
     BLKDBG_EVENT(bs->file, BLKDBG_WRITE_AIO);
-    return bdrv_co_writev(bs->file);
+    return bdrv_co_writev(bs->file, sector_num, nb_sectors, qiov);
 }
 
-static TYPE raw_co_is_allocated(BlockDriverState *bs)
+static int coroutine_fn raw_co_is_allocated(BlockDriverState *bs,
+                                            int64_t sector_num, int nb_sectors,
+                                            int *pnum)
 {
-    return bdrv_co_is_allocated(bs->file);
+    return bdrv_co_is_allocated(bs->file, sector_num, nb_sectors, pnum);
 }
 
-static TYPE raw_co_write_zeroes(BlockDriverState *bs)
+static int coroutine_fn raw_co_write_zeroes(BlockDriverState *bs,
+                                            int64_t sector_num, int nb_sectors)
 {
-    return bdrv_co_write_zeroes(bs->file);
+    return bdrv_co_write_zeroes(bs->file, sector_num, nb_sectors);
 }
 
-static TYPE raw_co_discard(BlockDriverState *bs)
+static int coroutine_fn raw_co_discard(BlockDriverState *bs,
+                                       int64_t sector_num, int nb_sectors)
 {
-    return bdrv_co_discard(bs->file);
+    return bdrv_co_discard(bs->file, sector_num, nb_sectors);
 }
 
-static TYPE raw_getlength(BlockDriverState *bs)
+static int64_t raw_getlength(BlockDriverState *bs)
 {
     return bdrv_getlength(bs->file);
 }
 
-static TYPE raw_get_info(BlockDriverState *bs)
+static int raw_get_info(BlockDriverState *bs, BlockDriverInfo *bdi)
 {
-    return bdrv_get_info(bs->file);
+    return bdrv_get_info(bs->file, bdi);
 }
 
-static TYPE raw_truncate(BlockDriverState *bs)
+static int raw_truncate(BlockDriverState *bs, int64_t offset)
 {
-    return bdrv_truncate(bs->file);
+    return bdrv_truncate(bs->file, offset);
 }
 
-static TYPE raw_is_inserted(BlockDriverState *bs)
+static int raw_is_inserted(BlockDriverState *bs)
 {
     return bdrv_is_inserted(bs->file);
 }
 
-static TYPE raw_media_changed(BlockDriverState *bs)
+static int raw_media_changed(BlockDriverState *bs)
 {
     return bdrv_media_changed(bs->file);
 }
 
-static TYPE raw_eject(BlockDriverState *bs)
+static void raw_eject(BlockDriverState *bs, bool eject_flag)
 {
-    return bdrv_eject(bs->file);
+    bdrv_eject(bs->file, eject_flag);
 }
 
-static TYPE raw_lock_medium(BlockDriverState *bs)
+static void raw_lock_medium(BlockDriverState *bs, bool locked)
 {
-    return bdrv_lock_medium(bs->file);
+    bdrv_lock_medium(bs->file, locked);
 }
 
-static TYPE raw_ioctl(BlockDriverState *bs)
+static int raw_ioctl(BlockDriverState *bs, unsigned long int req, void *buf)
 {
-    return bdrv_ioctl(bs->file);
+    return bdrv_ioctl(bs->file, req, buf);
 }
 
-static TYPE raw_aio_ioctl(BlockDriverState *bs)
+static BlockDriverAIOCB *raw_aio_ioctl(BlockDriverState *bs,
+                                       unsigned long int req, void *buf,
+                                       BlockDriverCompletionFunc *cb,
+                                       void *opaque)
 {
-    return bdrv_aio_ioctl(bs->file);
+    return bdrv_aio_ioctl(bs->file, req, buf, cb, opaque);
 }
 
-static TYPE raw_has_zero_init(BlockDriverState *bs)
+static int raw_has_zero_init(BlockDriverState *bs)
 {
     return bdrv_has_zero_init(bs->file);
 }
 
-static TYPE raw_create(void)
+static int raw_create(const char *filename, QEMUOptionParameter *options)
 {
-    return bdrv_create_file();
+    return bdrv_create_file(filename, options);
 }
 
-static int raw_open(BlockDriverState *bs)
+static int raw_open(BlockDriverState *bs, QDict *options, int flags)
 {
     bs->sg = bs->file->sg;
     return 0;
 }
 
-static void raw_close(void)
+static void raw_close(BlockDriverState *bs)
 {
 }
 
-static int raw_probe(void)
+static int raw_probe(const uint8_t *buf, int buf_size, const char *filename)
 {
     /* smallest possible positive score so that raw is used if and only if no
      * other block driver works
commit 775d6afd5cd66f2154a81f5de9d3dd7297a35072
Author: Laszlo Ersek <lersek at redhat.com>
Date:   Wed Aug 21 12:41:22 2013 +0200

    raw_bsd: register bdrv_raw
    
    On 08/05/13 15:03, Paolo Bonzini wrote:
    >
    > [...]
    >
    > 5) Formats are registered with bdrv_register (takes a BlockDriver*). You
    > also need to pass the caller of bdrv_register to block_init.
    
    Fill in the BlockDriver structure with the raw_*() functions that have
    been added to "block/raw_bsd.c", in the order the fields are defined in
    "include/block/block_int.h".
    
    I needed more explanation / naming examples for registering the driver
    than what Paolo gave me, so I copied / adapted from "block/qcow2.c". The
    parts I took as basis for modification are blamed on
    
        commit 5efa9d5a8b18841c9c62208a494d7f519238979a
        Author: Anthony Liguori <aliguori at us.ibm.com>
        Date:   Sat May 9 17:03:42 2009 -0500
    
            Convert block infrastructure to use new module init functionality
    
        commit 20d97356c9df6d68fbd37d6334fdb7063f24eab6
        Author: Blue Swirl <blauwirbel at gmail.com>
        Date:   Fri Apr 23 20:19:47 2010 +0000
    
            Fix OpenBSD build
    
    Signed-off-by: Laszlo Ersek <lersek at redhat.com>
    Signed-off-by: Kevin Wolf <kwolf at redhat.com>

diff --git a/block/raw_bsd.c b/block/raw_bsd.c
index b70245d..2dc1921 100644
--- a/block/raw_bsd.c
+++ b/block/raw_bsd.c
@@ -2,6 +2,7 @@
  *
  * Copyright (C) 2010, 2013, Red Hat, Inc.
  * Copyright (C) 2010, Blue Swirl <blauwirbel at gmail.com>
+ * Copyright (C) 2009, Anthony Liguori <aliguori at us.ibm.com>
  *
  * Author:
  *   Laszlo Ersek <lersek at redhat.com>
@@ -124,11 +125,6 @@ static TYPE raw_create(void)
     return bdrv_create_file();
 }
 
-static const char *raw_format_name(void)
-{
-    return "raw";
-}
-
 static int raw_open(BlockDriverState *bs)
 {
     bs->sg = bs->file->sg;
@@ -146,3 +142,35 @@ static int raw_probe(void)
      */
     return 1;
 }
+
+static BlockDriver bdrv_raw = {
+    .format_name          = "raw",
+    .bdrv_probe           = &raw_probe,
+    .bdrv_reopen_prepare  = &raw_reopen_prepare,
+    .bdrv_open            = &raw_open,
+    .bdrv_close           = &raw_close,
+    .bdrv_create          = &raw_create,
+    .bdrv_co_readv        = &raw_co_readv,
+    .bdrv_co_writev       = &raw_co_writev,
+    .bdrv_co_write_zeroes = &raw_co_write_zeroes,
+    .bdrv_co_discard      = &raw_co_discard,
+    .bdrv_co_is_allocated = &raw_co_is_allocated,
+    .bdrv_truncate        = &raw_truncate,
+    .bdrv_getlength       = &raw_getlength,
+    .bdrv_get_info        = &raw_get_info,
+    .bdrv_is_inserted     = &raw_is_inserted,
+    .bdrv_media_changed   = &raw_media_changed,
+    .bdrv_eject           = &raw_eject,
+    .bdrv_lock_medium     = &raw_lock_medium,
+    .bdrv_ioctl           = &raw_ioctl,
+    .bdrv_aio_ioctl       = &raw_aio_ioctl,
+    .create_options       = &raw_create_options[0],
+    .bdrv_has_zero_init   = &raw_has_zero_init
+};
+
+static void bdrv_raw_init(void)
+{
+    bdrv_register(&bdrv_raw);
+}
+
+block_init(bdrv_raw_init);
commit ff369a483df89cc6ca510b0c3ab9afe9cf0bdfdc
Author: Laszlo Ersek <lersek at redhat.com>
Date:   Wed Aug 21 12:41:21 2013 +0200

    raw_bsd: add raw_create_options
    
    On 08/05/13 15:03, Paolo Bonzini wrote:
    >
    > [...]
    >
    > 4) There is another member, .create_options, which is an array of
    > QEMUOptionParameter structs, terminated by an all-zero item.  The only
    > option you need is for the virtual disk size.  You will find something
    > to copy from in other block drivers, for example block/qcow2.c.
    
    Code taken and adapted from "block/qcow2.c", as suggested. The code being
    copied/modified is blamed on
    
        commit 20d97356c9df6d68fbd37d6334fdb7063f24eab6
        Author: Blue Swirl <blauwirbel at gmail.com>
        Date:   Fri Apr 23 20:19:47 2010 +0000
    
            Fix OpenBSD build
    
    and
    
        commit 7c80ab3f21f0b1342f23057d4345ae266c7348d9
        Author: Jes Sorensen <Jes.Sorensen at redhat.com>
        Date:   Fri Dec 17 16:02:39 2010 +0100
    
            block/qcow2.c: rename qcow_ functions to qcow2_
    
    Signed-off-by: Laszlo Ersek <lersek at redhat.com>
    Signed-off-by: Kevin Wolf <kwolf at redhat.com>

diff --git a/block/raw_bsd.c b/block/raw_bsd.c
index b1d7209..b70245d 100644
--- a/block/raw_bsd.c
+++ b/block/raw_bsd.c
@@ -1,6 +1,7 @@
 /* BlockDriver implementation for "raw"
  *
- * Copyright (C) 2013, Red Hat, Inc.
+ * Copyright (C) 2010, 2013, Red Hat, Inc.
+ * Copyright (C) 2010, Blue Swirl <blauwirbel at gmail.com>
  *
  * Author:
  *   Laszlo Ersek <lersek at redhat.com>
@@ -25,6 +26,16 @@
  */
 
 #include "block/block_int.h"
+#include "qemu/option.h"
+
+static const QEMUOptionParameter raw_create_options[] = {
+    {
+        .name = BLOCK_OPT_SIZE,
+        .type = OPT_SIZE,
+        .help = "Virtual disk size"
+    },
+    { 0 }
+};
 
 static TYPE raw_reopen_prepare(BlockDriverState *bs)
 {
commit 01dd96d8f4f253ee29b4e0362a73c5f43bdc0b18
Author: Laszlo Ersek <lersek at redhat.com>
Date:   Wed Aug 21 12:41:20 2013 +0200

    raw_bsd: introduce "special members"
    
    On 08/05/13 15:03, Paolo Bonzini wrote:
    >
    > [...]
    >
    > 3) These members are special
    >
    >     .format_name   is the string "raw"
    >     .bdrv_open     raw_open should set bs->sg to bs->file->sg and return 0
    >     .bdrv_close    raw_close should do nothing
    >     .bdrv_probe    raw_probe should just return 1.
    
    v1->v2:
    
    On 08/20/13 10:11, Kevin Wolf wrote:
    > Am 16.08.2013 um 16:15 hat Laszlo Ersek geschrieben:
    
    >> +static int raw_probe(void)
    >> +{
    >> +    return 1;
    >> +}
    >
    > Maybe add a comment here like "smallest possible positive score so that
    > raw is used if and only if no other block driver works".
    
    Signed-off-by: Laszlo Ersek <lersek at redhat.com>
    Signed-off-by: Kevin Wolf <kwolf at redhat.com>

diff --git a/block/raw_bsd.c b/block/raw_bsd.c
index 5bcbe71..b1d7209 100644
--- a/block/raw_bsd.c
+++ b/block/raw_bsd.c
@@ -112,3 +112,26 @@ static TYPE raw_create(void)
 {
     return bdrv_create_file();
 }
+
+static const char *raw_format_name(void)
+{
+    return "raw";
+}
+
+static int raw_open(BlockDriverState *bs)
+{
+    bs->sg = bs->file->sg;
+    return 0;
+}
+
+static void raw_close(void)
+{
+}
+
+static int raw_probe(void)
+{
+    /* smallest possible positive score so that raw is used if and only if no
+     * other block driver works
+     */
+    return 1;
+}
commit 1565262c370195f1d7781d98f78fa002ab16b385
Author: Laszlo Ersek <lersek at redhat.com>
Date:   Wed Aug 21 12:41:19 2013 +0200

    raw_bsd: add raw_create()
    
    On 08/05/13 15:03, Paolo Bonzini wrote:
    >
    > [...]
    >
    > 2) This is also a simple forwarder function:
    >
    >     .bdrv_create
    >
    > but there is no BlockDriverState argument so the forwarded-to function
    > does not have a bs->file argument either.  The forwarded-to function is
    > bdrv_create_file.
    
    Signed-off-by: Laszlo Ersek <lersek at redhat.com>
    Signed-off-by: Kevin Wolf <kwolf at redhat.com>

diff --git a/block/raw_bsd.c b/block/raw_bsd.c
index 19091a3..5bcbe71 100644
--- a/block/raw_bsd.c
+++ b/block/raw_bsd.c
@@ -108,3 +108,7 @@ static TYPE raw_has_zero_init(BlockDriverState *bs)
     return bdrv_has_zero_init(bs->file);
 }
 
+static TYPE raw_create(void)
+{
+    return bdrv_create_file();
+}
commit 9eaafd90d14b6049cc1d0e0b6c712459d447363c
Author: Laszlo Ersek <lersek at redhat.com>
Date:   Wed Aug 21 12:41:18 2013 +0200

    raw_bsd: emit debug events in bdrv_co_readv() and bdrv_co_writev()
    
    On 08/05/13 15:03, Paolo Bonzini wrote:
    >
    > [...]
    >
    > 1) BlockDriver is a struct in which these function members are
    > interesting:
    >
    >     .bdrv_reopen_prepare
    >     .bdrv_co_readv
    >     .bdrv_co_writev
    >     .bdrv_co_is_allocated
    >     .bdrv_co_write_zeroes
    >     .bdrv_co_discard
    >     .bdrv_getlength
    >     .bdrv_get_info
    >     .bdrv_truncate
    >     .bdrv_is_inserted
    >     .bdrv_media_changed
    >     .bdrv_eject
    >     .bdrv_lock_medium
    >     .bdrv_ioctl
    >     .bdrv_aio_ioctl
    >     .bdrv_has_zero_init
    >
    > They should be implemented as simple forwarders (see above). There are
    > 16 functions listed here, you can easily see how this already accounts
    > for 100+ SLOC roughly...
    >
    > The implementations of bdrv_co_readv and bdrv_co_writev should also call
    > BLKDBG_EVENT on bs->file too, before forwarding to bs->file.  The events
    > to be generated are BLKDBG_READ_AIO and BLKDBG_WRITE_AIO.
    
    Signed-off-by: Laszlo Ersek <lersek at redhat.com>
    Signed-off-by: Kevin Wolf <kwolf at redhat.com>

diff --git a/block/raw_bsd.c b/block/raw_bsd.c
index 5c17d53..19091a3 100644
--- a/block/raw_bsd.c
+++ b/block/raw_bsd.c
@@ -33,11 +33,13 @@ static TYPE raw_reopen_prepare(BlockDriverState *bs)
 
 static TYPE raw_co_readv(BlockDriverState *bs)
 {
+    BLKDBG_EVENT(bs->file, BLKDBG_READ_AIO);
     return bdrv_co_readv(bs->file);
 }
 
 static TYPE raw_co_writev(BlockDriverState *bs)
 {
+    BLKDBG_EVENT(bs->file, BLKDBG_WRITE_AIO);
     return bdrv_co_writev(bs->file);
 }
 
commit e1c66c6d82fe5988d66531febc27ef8480c44c8a
Author: Laszlo Ersek <lersek at redhat.com>
Date:   Wed Aug 21 12:41:17 2013 +0200

    add skeleton for BSD licensed "raw" BlockDriver
    
    On 08/05/13 15:03, Paolo Bonzini wrote:
    >
    >
    > ----- Original Message -----
    >> From: "Laszlo Ersek" <lersek at redhat.com>
    >> To: "Paolo Bonzini" <pbonzini at redhat.com>
    >> Sent: Monday, August 5, 2013 2:43:46 PM
    >> Subject: Re: [PATCH 1/2] raw: add license header
    >>
    >> On 08/02/13 00:27, Paolo Bonzini wrote:
    >>> On 08/01/2013 10:13 AM, Christoph Hellwig wrote:
    >>>> On Wed, Jul 31, 2013 at 08:19:51AM +0200, Paolo Bonzini wrote:
    >>>>> Most of the block layer is under the BSD license, thus it is
    >>>>> reasonable to license block/raw.c the same way.  CCed people should
    >>>>> ACK by replying with a Signed-off-by line.
    >>>>
    >>>> The coded was intended to be GPLv2.
    >>>
    >>> Laszlo, would you be willing to do clean-room reverse engineering?
    >>>
    >>> (No rants, please. :))
    >>
    >> What's the scope exactly?
    >
    > It's quite small, it's a file full of forwarders like
    >
    > static void raw_foo(BlockDriverState *bs)
    > {
    >     return bdrv_foo(bs->file);
    > }
    >
    > It's 170 lines of code, all as boring as this.  I only picked you
    > because I'm quite certain you have never seen the file (and the answer
    > confirmed it).
    >
    > Basically:
    >
    > 1) BlockDriver is a struct in which these function members are
    > interesting:
    >
    >     .bdrv_reopen_prepare
    >     .bdrv_co_readv
    >     .bdrv_co_writev
    >     .bdrv_co_is_allocated
    >     .bdrv_co_write_zeroes
    >     .bdrv_co_discard
    >     .bdrv_getlength
    >     .bdrv_get_info
    >     .bdrv_truncate
    >     .bdrv_is_inserted
    >     .bdrv_media_changed
    >     .bdrv_eject
    >     .bdrv_lock_medium
    >     .bdrv_ioctl
    >     .bdrv_aio_ioctl
    >     .bdrv_has_zero_init
    >
    > They should be implemented as simple forwarders (see above).
    > There are 16 functions listed here, you can easily see how this
    > already accounts for 100+ SLOC roughly...
    >
    > The implementations of bdrv_co_readv and bdrv_co_writev should also
    > call BLKDBG_EVENT on bs->file too, before forwarding to bs->file.  The
    > events to be generated are BLKDBG_READ_AIO and BLKDBG_WRITE_AIO.
    >
    > 2) This is also a simple forwarder function:
    >
    >     .bdrv_create
    >
    > but there is no BlockDriverState argument so the forwarded-to function
    > does not have a bs->file argument either.  The forwarded-to function
    > is bdrv_create_file.
    >
    > 3) These members are special
    >
    >     .format_name   is the string "raw"
    >     .bdrv_open     raw_open should set bs->sg to bs->file->sg and return 0
    >     .bdrv_close    raw_close should do nothing
    >     .bdrv_probe    raw_probe should just return 1.
    >
    > 4) There is another member, .create_options, which is an array of
    > QEMUOptionParameter structs, terminated by an all-zero item.  The only
    > option you need is for the virtual disk size.  You will find something
    > to copy from in other block drivers, for example block/qcow2.c.
    >
    > 5) Formats are registered with bdrv_register (takes a BlockDriver*).
    > You also need to pass the caller of bdrv_register to block_init.
    >
    > 6) I'm not sure how to organize the patch series, so I'll leave this to
    > your creativity.  I guess in this case move/copy detection of git should
    > be disabled.  I would definitely include this spec in the commit
    > message as a proof of clean-room reverse engineering.
    >
    > 7) Remember a BSD header like the one in block.c.
    >
    > Paolo
    
    This patch implements the email up to the paragraph ending with "100+ SLOC
    roughly". The skeleton is generated from the list there, with a simple
    shell loop using "sed" and the raw_foo() template.
    
    The BSD license block is copied (and reflowed) from
    "util/qemu-progress.c".
    
    Signed-off-by: Laszlo Ersek <lersek at redhat.com>
    Signed-off-by: Kevin Wolf <kwolf at redhat.com>

diff --git a/block/raw_bsd.c b/block/raw_bsd.c
new file mode 100644
index 0000000..5c17d53
--- /dev/null
+++ b/block/raw_bsd.c
@@ -0,0 +1,108 @@
+/* BlockDriver implementation for "raw"
+ *
+ * Copyright (C) 2013, Red Hat, Inc.
+ *
+ * Author:
+ *   Laszlo Ersek <lersek at redhat.com>
+ *
+ * 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/block_int.h"
+
+static TYPE raw_reopen_prepare(BlockDriverState *bs)
+{
+    return bdrv_reopen_prepare(bs->file);
+}
+
+static TYPE raw_co_readv(BlockDriverState *bs)
+{
+    return bdrv_co_readv(bs->file);
+}
+
+static TYPE raw_co_writev(BlockDriverState *bs)
+{
+    return bdrv_co_writev(bs->file);
+}
+
+static TYPE raw_co_is_allocated(BlockDriverState *bs)
+{
+    return bdrv_co_is_allocated(bs->file);
+}
+
+static TYPE raw_co_write_zeroes(BlockDriverState *bs)
+{
+    return bdrv_co_write_zeroes(bs->file);
+}
+
+static TYPE raw_co_discard(BlockDriverState *bs)
+{
+    return bdrv_co_discard(bs->file);
+}
+
+static TYPE raw_getlength(BlockDriverState *bs)
+{
+    return bdrv_getlength(bs->file);
+}
+
+static TYPE raw_get_info(BlockDriverState *bs)
+{
+    return bdrv_get_info(bs->file);
+}
+
+static TYPE raw_truncate(BlockDriverState *bs)
+{
+    return bdrv_truncate(bs->file);
+}
+
+static TYPE raw_is_inserted(BlockDriverState *bs)
+{
+    return bdrv_is_inserted(bs->file);
+}
+
+static TYPE raw_media_changed(BlockDriverState *bs)
+{
+    return bdrv_media_changed(bs->file);
+}
+
+static TYPE raw_eject(BlockDriverState *bs)
+{
+    return bdrv_eject(bs->file);
+}
+
+static TYPE raw_lock_medium(BlockDriverState *bs)
+{
+    return bdrv_lock_medium(bs->file);
+}
+
+static TYPE raw_ioctl(BlockDriverState *bs)
+{
+    return bdrv_ioctl(bs->file);
+}
+
+static TYPE raw_aio_ioctl(BlockDriverState *bs)
+{
+    return bdrv_aio_ioctl(bs->file);
+}
+
+static TYPE raw_has_zero_init(BlockDriverState *bs)
+{
+    return bdrv_has_zero_init(bs->file);
+}
+
commit 127c84e1a52f11bf418cc2d3bf804da5091a190a
Author: Peter Maydell <peter.maydell at linaro.org>
Date:   Fri Aug 23 17:35:45 2013 +0100

    block/qcow2.h: Avoid "1LL << 63" (shifts into sign bit)
    
    The expression "1LL << 63" tries to shift the 1 into the sign bit of a
    'long long', which provokes a clang sanitizer warning:
    
    runtime error: left shift of 1 by 63 places cannot be represented in type 'long long'
    
    Use "1ULL << 63" as the definition of QCOW_OFLAG_COPIED instead
    to avoid this. For consistency, we also update the other QCOW_OFLAG
    definitions to use the ULL suffix rather than LL, though only the
    shift by 63 is undefined behaviour.
    
    Signed-off-by: Peter Maydell <peter.maydell at linaro.org>
    Reviewed-by: Eric Blake <eblake at redhat.com>
    Signed-off-by: Kevin Wolf <kwolf at redhat.com>

diff --git a/block/qcow2.h b/block/qcow2.h
index dba9771..365a17e 100644
--- a/block/qcow2.h
+++ b/block/qcow2.h
@@ -40,11 +40,11 @@
 #define QCOW_MAX_CRYPT_CLUSTERS 32
 
 /* indicate that the refcount of the referenced cluster is exactly one. */
-#define QCOW_OFLAG_COPIED     (1LL << 63)
+#define QCOW_OFLAG_COPIED     (1ULL << 63)
 /* indicate that the cluster is compressed (they never have the copied flag) */
-#define QCOW_OFLAG_COMPRESSED (1LL << 62)
+#define QCOW_OFLAG_COMPRESSED (1ULL << 62)
 /* The cluster reads as all zeros */
-#define QCOW_OFLAG_ZERO (1LL << 0)
+#define QCOW_OFLAG_ZERO (1ULL << 0)
 
 #define REFCOUNT_SHIFT 1 /* refcount size is 2 bytes */
 
commit cccc30b4ad5d9835f5525d94210c8de26f4f5f94
Author: Kevin Wolf <kwolf at redhat.com>
Date:   Wed Aug 28 16:12:20 2013 +0200

    qemu-iotests: Update reference output for 051
    
    Signed-off-by: Kevin Wolf <kwolf at redhat.com>

diff --git a/tests/qemu-iotests/051.out b/tests/qemu-iotests/051.out
index 5582ed3..86e989c 100644
--- a/tests/qemu-iotests/051.out
+++ b/tests/qemu-iotests/051.out
@@ -85,7 +85,6 @@ QEMU_PROG: -drive if=virtio: Device 'virtio-blk-pci' could not be initialized
 Testing: -drive if=scsi
 QEMU X.Y.Z monitor - type 'help' for more information
 (qemu) QEMU_PROG: -drive if=scsi: Device needs media, but drive is empty
-QEMU_PROG: -drive if=scsi: Device initialization failed.
 QEMU_PROG: Device initialization failed.
 QEMU_PROG: Initialization of device lsi53c895a failed
 
commit c0447d870b25cd95af2630ab3d376321bd6e820a
Author: Kevin Wolf <kwolf at redhat.com>
Date:   Wed Aug 28 09:50:40 2013 +0200

    Revert "block: Disable driver-specific options for 1.6"
    
    This reverts commit 8afaefb8919dc8746a57c450a758717c516c7b0a.
    
    Signed-off-by: Kevin Wolf <kwolf at redhat.com>

diff --git a/blockdev.c b/blockdev.c
index 121520e..e70e16e 100644
--- a/blockdev.c
+++ b/blockdev.c
@@ -46,7 +46,6 @@
 
 static QTAILQ_HEAD(drivelist, DriveInfo) drives = QTAILQ_HEAD_INITIALIZER(drives);
 extern QemuOptsList qemu_common_drive_opts;
-extern QemuOptsList qemu_old_drive_opts;
 
 static const char *const if_name[IF_COUNT] = {
     [IF_NONE] = "none",
@@ -755,26 +754,6 @@ DriveInfo *drive_init(QemuOpts *all_opts, BlockInterfaceType block_default_type)
 {
     const char *value;
 
-    /*
-     * Check that only old options are used by copying into a QemuOpts with
-     * stricter checks. Going through a QDict seems to be the easiest way to
-     * achieve this...
-     */
-    QemuOpts* check_opts;
-    QDict *qdict;
-    Error *local_err = NULL;
-
-    qdict = qemu_opts_to_qdict(all_opts, NULL);
-    check_opts = qemu_opts_from_qdict(&qemu_old_drive_opts, qdict, &local_err);
-    QDECREF(qdict);
-
-    if (error_is_set(&local_err)) {
-        qerror_report_err(local_err);
-        error_free(local_err);
-        return NULL;
-    }
-    qemu_opts_del(check_opts);
-
     /* Change legacy command line options into QMP ones */
     qemu_opt_rename(all_opts, "iops", "throttling.iops-total");
     qemu_opt_rename(all_opts, "iops_rd", "throttling.iops-read");
@@ -2001,128 +1980,6 @@ QemuOptsList qemu_common_drive_opts = {
     },
 };
 
-QemuOptsList qemu_old_drive_opts = {
-    .name = "drive",
-    .head = QTAILQ_HEAD_INITIALIZER(qemu_old_drive_opts.head),
-    .desc = {
-        {
-            .name = "bus",
-            .type = QEMU_OPT_NUMBER,
-            .help = "bus number",
-        },{
-            .name = "unit",
-            .type = QEMU_OPT_NUMBER,
-            .help = "unit number (i.e. lun for scsi)",
-        },{
-            .name = "if",
-            .type = QEMU_OPT_STRING,
-            .help = "interface (ide, scsi, sd, mtd, floppy, pflash, virtio)",
-        },{
-            .name = "index",
-            .type = QEMU_OPT_NUMBER,
-            .help = "index number",
-        },{
-            .name = "cyls",
-            .type = QEMU_OPT_NUMBER,
-            .help = "number of cylinders (ide disk geometry)",
-        },{
-            .name = "heads",
-            .type = QEMU_OPT_NUMBER,
-            .help = "number of heads (ide disk geometry)",
-        },{
-            .name = "secs",
-            .type = QEMU_OPT_NUMBER,
-            .help = "number of sectors (ide disk geometry)",
-        },{
-            .name = "trans",
-            .type = QEMU_OPT_STRING,
-            .help = "chs translation (auto, lba. none)",
-        },{
-            .name = "media",
-            .type = QEMU_OPT_STRING,
-            .help = "media type (disk, cdrom)",
-        },{
-            .name = "snapshot",
-            .type = QEMU_OPT_BOOL,
-            .help = "enable/disable snapshot mode",
-        },{
-            .name = "file",
-            .type = QEMU_OPT_STRING,
-            .help = "disk image",
-        },{
-            .name = "discard",
-            .type = QEMU_OPT_STRING,
-            .help = "discard operation (ignore/off, unmap/on)",
-        },{
-            .name = "cache",
-            .type = QEMU_OPT_STRING,
-            .help = "host cache usage (none, writeback, writethrough, "
-                    "directsync, unsafe)",
-        },{
-            .name = "aio",
-            .type = QEMU_OPT_STRING,
-            .help = "host AIO implementation (threads, native)",
-        },{
-            .name = "format",
-            .type = QEMU_OPT_STRING,
-            .help = "disk format (raw, qcow2, ...)",
-        },{
-            .name = "serial",
-            .type = QEMU_OPT_STRING,
-            .help = "disk serial number",
-        },{
-            .name = "rerror",
-            .type = QEMU_OPT_STRING,
-            .help = "read error action",
-        },{
-            .name = "werror",
-            .type = QEMU_OPT_STRING,
-            .help = "write error action",
-        },{
-            .name = "addr",
-            .type = QEMU_OPT_STRING,
-            .help = "pci address (virtio only)",
-        },{
-            .name = "readonly",
-            .type = QEMU_OPT_BOOL,
-            .help = "open drive file as read-only",
-        },{
-            .name = "iops",
-            .type = QEMU_OPT_NUMBER,
-            .help = "limit total I/O operations per second",
-        },{
-            .name = "iops_rd",
-            .type = QEMU_OPT_NUMBER,
-            .help = "limit read operations per second",
-        },{
-            .name = "iops_wr",
-            .type = QEMU_OPT_NUMBER,
-            .help = "limit write operations per second",
-        },{
-            .name = "bps",
-            .type = QEMU_OPT_NUMBER,
-            .help = "limit total bytes per second",
-        },{
-            .name = "bps_rd",
-            .type = QEMU_OPT_NUMBER,
-            .help = "limit read bytes per second",
-        },{
-            .name = "bps_wr",
-            .type = QEMU_OPT_NUMBER,
-            .help = "limit write bytes per second",
-        },{
-            .name = "copy-on-read",
-            .type = QEMU_OPT_BOOL,
-            .help = "copy read data from backing file into image file",
-        },{
-            .name = "boot",
-            .type = QEMU_OPT_BOOL,
-            .help = "(deprecated, ignored)",
-        },
-        { /* end of list */ }
-    },
-};
-
 QemuOptsList qemu_drive_opts = {
     .name = "drive",
     .head = QTAILQ_HEAD_INITIALIZER(qemu_drive_opts.head),
diff --git a/tests/qemu-iotests/group b/tests/qemu-iotests/group
index 43c05d6..93ace2e 100644
--- a/tests/qemu-iotests/group
+++ b/tests/qemu-iotests/group
@@ -57,7 +57,7 @@
 048 img auto quick
 049 rw auto
 050 rw auto backing quick
-#051 rw auto
+051 rw auto
 052 rw auto backing
 053 rw auto
 054 rw auto
commit 015370301fd90ea5d17522eba00ae2797569ce8b
Author: Kevin Wolf <kwolf at redhat.com>
Date:   Tue Jul 2 12:18:18 2013 +0200

    qapi-types.py: Split off generate_struct_fields()
    
    Signed-off-by: Kevin Wolf <kwolf at redhat.com>
    Reviewed-by: Eric Blake <eblake at redhat.com>

diff --git a/scripts/qapi-types.py b/scripts/qapi-types.py
index 5ee46ea..86de980 100644
--- a/scripts/qapi-types.py
+++ b/scripts/qapi-types.py
@@ -57,12 +57,8 @@ typedef struct %(name)sList
 ''',
                  name=name)
 
-def generate_struct(structname, fieldname, members):
-    ret = mcgen('''
-struct %(name)s
-{
-''',
-          name=structname)
+def generate_struct_fields(members):
+    ret = ''
 
     for argname, argentry, optional, structured in parse_args(members):
         if optional:
@@ -80,6 +76,17 @@ struct %(name)s
 ''',
                      c_type=c_type(argentry), c_name=c_var(argname))
 
+    return ret
+
+def generate_struct(structname, fieldname, members):
+    ret = mcgen('''
+struct %(name)s
+{
+''',
+          name=structname)
+
+    ret += generate_struct_fields(members)
+
     if len(fieldname):
         fieldname = " " + fieldname
     ret += mcgen('''
commit 09da4a72926e2d0af0e5f0cb967ab0dd345311f4
Author: Kevin Wolf <kwolf at redhat.com>
Date:   Mon Apr 15 10:59:42 2013 +0200

    block: Remove redundant assertion
    
    The failing condition is checked immediately before the assertion, so
    keeping the assertion is kind of redundant.
    
    Signed-off-by: Kevin Wolf <kwolf at redhat.com>

diff --git a/block.c b/block.c
index a387c1a..26639e8 100644
--- a/block.c
+++ b/block.c
@@ -743,7 +743,6 @@ static int bdrv_open_common(BlockDriverState *bs, BlockDriverState *file,
             ret = -EINVAL;
             goto free_and_fail;
         }
-        assert(file != NULL);
         bs->file = file;
         ret = drv->bdrv_open(bs, options, open_flags);
     }
commit 9117b47717ad208b12786ce88eacb013f9b3dd1c
Author: Kevin Wolf <kwolf at redhat.com>
Date:   Mon Aug 19 10:38:01 2013 +0200

    qcow2: Change default for new images to compat=1.1
    
    By the time that qemu 1.7 will be released, enough time will have passed
    since qemu 1.1, which is the first version to understand version 3
    images, that changing the default shouldn't hurt many people any more
    and the benefits of using the new format outweigh the pain.
    
    qemu-iotests already runs with compat=1.1 by default.
    
    Signed-off-by: Kevin Wolf <kwolf at redhat.com>
    Reviewed-by: Eric Blake <eblake at redhat.com>

diff --git a/block/qcow2.c b/block/qcow2.c
index 78097e5..5e5f413 100644
--- a/block/qcow2.c
+++ b/block/qcow2.c
@@ -1429,7 +1429,9 @@ static int qcow2_create(const char *filename, QEMUOptionParameter *options)
                 return -EINVAL;
             }
         } else if (!strcmp(options->name, BLOCK_OPT_COMPAT_LEVEL)) {
-            if (!options->value.s || !strcmp(options->value.s, "0.10")) {
+            if (!options->value.s) {
+                /* keep the default */
+            } else if (!strcmp(options->value.s, "0.10")) {
                 version = 2;
             } else if (!strcmp(options->value.s, "1.1")) {
                 version = 3;
commit 7f7f975295bc19829b3bd26cadc7f1c9eadb7c6b
Author: Eugene (jno) Dvurechenski <jno at linux.vnet.ibm.com>
Date:   Wed Dec 5 15:50:07 2012 +0100

    s390: wire up nmi command to raise a RESTART interrupt on S390
    
    There is the 'nmi' command that is used to trigger a guest dump via kdump feature on x86.
    s390 uses RESTART interrupt to trigger kdump.
    So, this patch provides a mean to use 'nmi' command on s390 to raise RESTART interrupt.
    
    The CPU to receive the RESTART interrupt is the "default" one.
    
    There is an infrastructure to select the "default" CPU using 'cpu' command.
    The 'info cpus' command can be used to see which one is the "default".
    
    In order to wire up the RESTART to 'nmi' command we had to:
    1. implement the kvm_s390_cpu_restart function by exporting the existing code
    2. implement s390_cpu_restart function as kvm-aware wrapper
    3. modify the qmp_inject_nmi function to enable (for s390) the scan for
       "default" CPU and call s390_cpu_restart for it;
    3. fix some messages.
    
    Signed-off-by: Eugene (jno) Dvurechenski <jno at linux.vnet.ibm.com>
    Signed-off-by: Christian Borntraeger <borntraeger at de.ibm.com>
    Acked-by: Alexander Graf <agraf at suse.de>

diff --git a/cpus.c b/cpus.c
index b9e5685..d74cc11 100644
--- a/cpus.c
+++ b/cpus.c
@@ -1401,6 +1401,20 @@ void qmp_inject_nmi(Error **errp)
             apic_deliver_nmi(env->apic_state);
         }
     }
+#elif defined(TARGET_S390X)
+    CPUState *cs;
+    S390CPU *cpu;
+
+    for (cs = first_cpu; cs != NULL; cs = cs->next_cpu) {
+        cpu = S390_CPU(cs);
+        if (cpu->env.cpu_num == monitor_get_cpu_index()) {
+            if (s390_cpu_restart(S390_CPU(cs)) == -1) {
+                error_set(errp, QERR_UNSUPPORTED);
+                return;
+            }
+            break;
+        }
+    }
 #else
     error_set(errp, QERR_UNSUPPORTED);
 #endif
diff --git a/hmp-commands.hx b/hmp-commands.hx
index 8c6b91a..628807f 100644
--- a/hmp-commands.hx
+++ b/hmp-commands.hx
@@ -822,7 +822,7 @@ The values that can be specified here depend on the machine type, but are
 the same that can be specified in the @code{-boot} command line option.
 ETEXI
 
-#if defined(TARGET_I386)
+#if defined(TARGET_I386) || defined(TARGET_S390X)
     {
         .name       = "nmi",
         .args_type  = "",
@@ -834,7 +834,7 @@ ETEXI
 STEXI
 @item nmi @var{cpu}
 @findex nmi
-Inject an NMI on the given CPU (x86 only).
+Inject an NMI (x86) or RESTART (s390x) on the given CPU.
 
 ETEXI
 
diff --git a/qmp-commands.hx b/qmp-commands.hx
index cf47e3f..bb09e72 100644
--- a/qmp-commands.hx
+++ b/qmp-commands.hx
@@ -487,7 +487,7 @@ Example:
 <- { "return": {} }
 
 Note: inject-nmi fails when the guest doesn't support injecting.
-      Currently, only x86 guests do.
+      Currently, only x86 (NMI) and s390x (RESTART) guests do.
 
 EQMP
 
diff --git a/target-s390x/cpu.h b/target-s390x/cpu.h
index b866ea1..8be5648 100644
--- a/target-s390x/cpu.h
+++ b/target-s390x/cpu.h
@@ -1069,6 +1069,7 @@ void kvm_s390_enable_css_support(S390CPU *cpu);
 int kvm_s390_get_registers_partial(CPUState *cpu);
 int kvm_s390_assign_subch_ioeventfd(EventNotifier *notifier, uint32_t sch,
                                     int vq, bool assign);
+int kvm_s390_cpu_restart(S390CPU *cpu);
 #else
 static inline void kvm_s390_io_interrupt(S390CPU *cpu,
                                         uint16_t subchannel_id,
@@ -1093,8 +1094,20 @@ static inline int kvm_s390_assign_subch_ioeventfd(EventNotifier *notifier,
 {
     return -ENOSYS;
 }
+static inline int kvm_s390_cpu_restart(S390CPU *cpu)
+{
+    return -ENOSYS;
+}
 #endif
 
+static inline int s390_cpu_restart(S390CPU *cpu)
+{
+    if (kvm_enabled()) {
+        return kvm_s390_cpu_restart(cpu);
+    }
+    return -ENOSYS;
+}
+
 static inline void s390_io_interrupt(S390CPU *cpu,
                                      uint16_t subchannel_id,
                                      uint16_t subchannel_nr,
diff --git a/target-s390x/kvm.c b/target-s390x/kvm.c
index c7fcdfa..185c8f5 100644
--- a/target-s390x/kvm.c
+++ b/target-s390x/kvm.c
@@ -612,12 +612,12 @@ static int handle_diag(S390CPU *cpu, struct kvm_run *run, int ipb_code)
     return r;
 }
 
-static int s390_cpu_restart(S390CPU *cpu)
+int kvm_s390_cpu_restart(S390CPU *cpu)
 {
     kvm_s390_interrupt(cpu, KVM_S390_RESTART, 0);
     s390_add_running_cpu(cpu);
     qemu_cpu_kick(CPU(cpu));
-    DPRINTF("DONE: SIGP cpu restart: %p\n", &cpu->env);
+    DPRINTF("DONE: KVM cpu restart: %p\n", &cpu->env);
     return 0;
 }
 
@@ -686,7 +686,7 @@ static int handle_sigp(S390CPU *cpu, struct kvm_run *run, uint8_t ipa1)
 
     switch (order_code) {
         case SIGP_RESTART:
-            r = s390_cpu_restart(target_cpu);
+            r = kvm_s390_cpu_restart(target_cpu);
             break;
         case SIGP_STORE_STATUS_ADDR:
             r = s390_store_status(target_env, parameter);
commit f077847572708bbb3dd22bbc91ac6a277046e827
Author: Christian Borntraeger <borntraeger at de.ibm.com>
Date:   Thu Jul 25 16:57:45 2013 +0200

    s390: Implement load normal reset
    
    kdump on s390 uses a load normal reset to bring the system in a defined
    state by doing a subsystem reset. The issuing CPUs will have an initial
    CPU reset, all other CPUs will have a CPU reset as defined in POP (no
    register content will change).
    
    Implement this as architectured.
    
    Signed-off-by: Christian Borntraeger <borntraeger at de.ibm.com>

diff --git a/target-s390x/misc_helper.c b/target-s390x/misc_helper.c
index 9b4423a..4afd7da 100644
--- a/target-s390x/misc_helper.c
+++ b/target-s390x/misc_helper.c
@@ -31,6 +31,7 @@
 
 #if !defined(CONFIG_USER_ONLY)
 #include "exec/softmmu_exec.h"
+#include "sysemu/cpus.h"
 #include "sysemu/sysemu.h"
 #endif
 
@@ -180,6 +181,32 @@ uint32_t HELPER(servc)(CPUS390XState *env, uint64_t r1, uint64_t r2)
 }
 
 #ifndef CONFIG_USER_ONLY
+static void cpu_reset_all(void)
+{
+    CPUState *cpu;
+    S390CPUClass *scc;
+
+    for (cpu = first_cpu; cpu; cpu = cpu->next_cpu) {
+        scc = S390_CPU_GET_CLASS(CPU(cpu));
+        scc->cpu_reset(CPU(cpu));
+    }
+}
+
+static int load_normal_reset(S390CPU *cpu)
+{
+    S390CPUClass *scc = S390_CPU_GET_CLASS(cpu);
+
+    pause_all_vcpus();
+    cpu_synchronize_all_states();
+    cpu_reset_all();
+    io_subsystem_reset();
+    scc->initial_cpu_reset(CPU(cpu));
+    scc->load_normal(CPU(cpu));
+    cpu_synchronize_all_post_reset();
+    resume_all_vcpus();
+    return 0;
+}
+
 #define DIAG_308_RC_NO_CONF         0x0102
 #define DIAG_308_RC_INVALID         0x0402
 void handle_diag_308(CPUS390XState *env, uint64_t r1, uint64_t r3)
@@ -198,6 +225,9 @@ void handle_diag_308(CPUS390XState *env, uint64_t r1, uint64_t r3)
     }
 
     switch (subcode) {
+    case 1:
+        load_normal_reset(s390_env_get_cpu(env));
+        break;
     case 5:
         if ((r1 & 1) || (addr & 0x0fffULL)) {
             program_interrupt(env, PGM_SPECIFICATION, ILEN_LATER_INC);
commit f5ae2a4fd8d573cfebaf24220e2920bb5074d9a6
Author: Christian Borntraeger <borntraeger at de.ibm.com>
Date:   Fri Jun 28 10:51:09 2013 +0200

    s390/cpu: split CPU reset into architectured functions
    
    s390 provides several CPU resets:
    - CPU reset, clears interrupts, stop processing, clears TLB, but does
      not touch registers
    - initial CPU reset, like CPU reset, but also clears PSW, prefix, FPC,
      timer and control registers. It does not touch gprs, fprs and acrs (!)
    - Power on reset: the full monty
    
    wire up CPUClass reset to the full monty, but provide the lesser resets
    as part of S390CPUClass.
    
    Signed-off-by: Christian Borntraeger <borntraeger at de.ibm.com>

diff --git a/target-s390x/cpu-qom.h b/target-s390x/cpu-qom.h
index 2dc1750..ac0460e 100644
--- a/target-s390x/cpu-qom.h
+++ b/target-s390x/cpu-qom.h
@@ -37,6 +37,8 @@
  * @parent_realize: The parent class' realize handler.
  * @parent_reset: The parent class' reset handler.
  * @load_normal: Performs a load normal.
+ * @cpu_reset: Performs a CPU reset.
+ * @initial_cpu_reset: Performs an initial CPU reset.
  *
  * An S/390 CPU model.
  */
@@ -48,6 +50,8 @@ typedef struct S390CPUClass {
     DeviceRealize parent_realize;
     void (*parent_reset)(CPUState *cpu);
     void (*load_normal)(CPUState *cpu);
+    void (*cpu_reset)(CPUState *cpu);
+    void (*initial_cpu_reset)(CPUState *cpu);
 } S390CPUClass;
 
 /**
diff --git a/target-s390x/cpu.c b/target-s390x/cpu.c
index 69f5e10..3c89f8a 100644
--- a/target-s390x/cpu.c
+++ b/target-s390x/cpu.c
@@ -76,7 +76,7 @@ static void s390_cpu_load_normal(CPUState *s)
 }
 #endif
 
-/* CPUClass::reset() */
+/* S390CPUClass::cpu_reset() */
 static void s390_cpu_reset(CPUState *s)
 {
     S390CPU *cpu = S390_CPU(s);
@@ -84,6 +84,37 @@ static void s390_cpu_reset(CPUState *s)
     CPUS390XState *env = &cpu->env;
 
     s390_del_running_cpu(cpu);
+    scc->parent_reset(s);
+#if !defined(CONFIG_USER_ONLY)
+    s->halted = 1;
+#endif
+    tlb_flush(env, 1);
+}
+
+/* S390CPUClass::initial_reset() */
+static void s390_cpu_initial_reset(CPUState *s)
+{
+    S390CPU *cpu = S390_CPU(s);
+    CPUS390XState *env = &cpu->env;
+
+    s390_cpu_reset(s);
+    /* initial reset does not touch regs,fregs and aregs */
+    memset(&env->fpc, 0, offsetof(CPUS390XState, breakpoints) -
+                         offsetof(CPUS390XState, fpc));
+
+    /* architectured initial values for CR 0 and 14 */
+    env->cregs[0] = CR0_RESET;
+    env->cregs[14] = CR14_RESET;
+}
+
+/* CPUClass:reset() */
+static void s390_cpu_full_reset(CPUState *s)
+{
+    S390CPU *cpu = S390_CPU(s);
+    S390CPUClass *scc = S390_CPU_GET_CLASS(cpu);
+    CPUS390XState *env = &cpu->env;
+
+    s390_del_running_cpu(cpu);
 
     scc->parent_reset(s);
 
@@ -183,8 +214,9 @@ static void s390_cpu_class_init(ObjectClass *oc, void *data)
 #if !defined(CONFIG_USER_ONLY)
     scc->load_normal = s390_cpu_load_normal;
 #endif
-    cc->reset = s390_cpu_reset;
-
+    scc->cpu_reset = s390_cpu_reset;
+    scc->initial_cpu_reset = s390_cpu_initial_reset;
+    cc->reset = s390_cpu_full_reset;
     cc->do_interrupt = s390_cpu_do_interrupt;
     cc->dump_state = s390_cpu_dump_state;
     cc->set_pc = s390_cpu_set_pc;
commit 7ca0e061044615e39eab2b22b8fc2791a4d77c34
Author: Wenchao Xia <xiawenc at linux.vnet.ibm.com>
Date:   Tue Aug 27 20:38:27 2013 +0800

    monitor: improve auto complete of "help" for single command in sub group
    
    Now special case "help *" in auto completion can work with sub commands,
    such as "help info u*".
    
    Signed-off-by: Wenchao Xia <xiawenc at linux.vnet.ibm.com>
    Reviewed-by: Eric Blake <eblake at redhat.com>
    Signed-off-by: Luiz Capitulino <lcapitulino at redhat.com>

diff --git a/monitor.c b/monitor.c
index 721c74d..0aeaf6c 100644
--- a/monitor.c
+++ b/monitor.c
@@ -4330,10 +4330,8 @@ static void monitor_find_completion_by_table(Monitor *mon,
                     cmd_completion(mon, str, QKeyCode_lookup[i]);
                 }
             } else if (!strcmp(cmd->name, "help|?")) {
-                readline_set_completion_index(mon->rs, strlen(str));
-                for (cmd = cmd_table; cmd->name != NULL; cmd++) {
-                    cmd_completion(mon, str, cmd->name);
-                }
+                monitor_find_completion_by_table(mon, cmd_table,
+                                                 &args[1], nb_args - 1);
             }
             break;
         default:
commit 129be006d63ba90b788de6b1610892e02ef5eaba
Author: Wenchao Xia <xiawenc at linux.vnet.ibm.com>
Date:   Tue Aug 27 20:38:26 2013 +0800

    monitor: allow "help" show message for single command in sub group
    
    A new parameter type 'S' is introduced to allow user input any string.
    "help info block" works normal now.
    
    Signed-off-by: Wenchao Xia <xiawenc at linux.vnet.ibm.com>
    Reviewed-by: Eric Blake <eblake at redhat.com>
    Signed-off-by: Luiz Capitulino <lcapitulino at redhat.com>

diff --git a/hmp-commands.hx b/hmp-commands.hx
index 8c6b91a..c161fe9 100644
--- a/hmp-commands.hx
+++ b/hmp-commands.hx
@@ -11,7 +11,7 @@ ETEXI
 
     {
         .name       = "help|?",
-        .args_type  = "name:s?",
+        .args_type  = "name:S?",
         .params     = "[cmd]",
         .help       = "show the help",
         .mhandler.cmd = do_help_cmd,
diff --git a/monitor.c b/monitor.c
index c44c711..721c74d 100644
--- a/monitor.c
+++ b/monitor.c
@@ -83,6 +83,7 @@
  * 'F'          filename
  * 'B'          block device name
  * 's'          string (accept optional quote)
+ * 'S'          it just appends the rest of the string (accept optional quote)
  * 'O'          option string of the form NAME=VALUE,...
  *              parsed according to QemuOptsList given by its name
  *              Example: 'device:O' uses qemu_device_opts.
@@ -4047,6 +4048,31 @@ static const mon_cmd_t *monitor_parse_command(Monitor *mon,
                 }
             }
             break;
+        case 'S':
+            {
+                /* package all remaining string */
+                int len;
+
+                while (qemu_isspace(*p)) {
+                    p++;
+                }
+                if (*typestr == '?') {
+                    typestr++;
+                    if (*p == '\0') {
+                        /* no remaining string: NULL argument */
+                        break;
+                    }
+                }
+                len = strlen(p);
+                if (len <= 0) {
+                    monitor_printf(mon, "%s: string expected\n",
+                                   cmdname);
+                    break;
+                }
+                qdict_put(qdict, key, qstring_from_str(p));
+                p += len;
+            }
+            break;
         default:
         bad_type:
             monitor_printf(mon, "%s: unknown type '%c'\n", cmdname, c);
@@ -4294,6 +4320,7 @@ static void monitor_find_completion_by_table(Monitor *mon,
             bdrv_iterate(block_completion_it, &mbs);
             break;
         case 's':
+        case 'S':
             if (!strcmp(cmd->name, "sendkey")) {
                 char *sep = strrchr(str, '-');
                 if (sep)
commit d903a779cf2f1fa5cd12076411a00b835f1b7b26
Author: Wenchao Xia <xiawenc at linux.vnet.ibm.com>
Date:   Tue Aug 27 20:38:25 2013 +0800

    monitor: support sub command in auto completion
    
    This patch allows auto completion work normal for sub command case,
    "info block [DEVICE]" can auto complete now, by re-enter the completion
    function. In original code "info" is treated as a special case, now it
    is treated as a sub command group, global variable info_cmds is not used
    any more.
    
    "help" command is still treated as a special case, since it is not a sub
    command group but want to auto complete command in root command table.
    
    Signed-off-by: Wenchao Xia <xiawenc at linux.vnet.ibm.com>
    Reviewed-by: Eric Blake <eblake at redhat.com>
    Signed-off-by: Luiz Capitulino <lcapitulino at redhat.com>

diff --git a/monitor.c b/monitor.c
index 424d30c..c44c711 100644
--- a/monitor.c
+++ b/monitor.c
@@ -4262,6 +4262,12 @@ static void monitor_find_completion_by_table(Monitor *mon,
             return;
         }
 
+        if (cmd->sub_table) {
+            /* do the job again */
+            return monitor_find_completion_by_table(mon, cmd->sub_table,
+                                                    &args[1], nb_args - 1);
+        }
+
         ptype = next_arg_type(cmd->args_type);
         for(i = 0; i < nb_args - 2; i++) {
             if (*ptype != '\0') {
@@ -4288,13 +4294,7 @@ static void monitor_find_completion_by_table(Monitor *mon,
             bdrv_iterate(block_completion_it, &mbs);
             break;
         case 's':
-            /* XXX: more generic ? */
-            if (!strcmp(cmd->name, "info")) {
-                readline_set_completion_index(mon->rs, strlen(str));
-                for(cmd = info_cmds; cmd->name != NULL; cmd++) {
-                    cmd_completion(mon, str, cmd->name);
-                }
-            } else if (!strcmp(cmd->name, "sendkey")) {
+            if (!strcmp(cmd->name, "sendkey")) {
                 char *sep = strrchr(str, '-');
                 if (sep)
                     str = sep + 1;
commit c35b6400338897847bbab1b0f65d89552636579a
Author: Wenchao Xia <xiawenc at linux.vnet.ibm.com>
Date:   Tue Aug 27 20:38:24 2013 +0800

    monitor: refine monitor_find_completion()
    
    In order to support sub command in auto completion, a reentrant function
    is needed, so monitor_find_completion() is split into two parts. The
    first part does parsing of user input which need to be done only once,
    the second part does the auto completion job according to the parsing
    result, which contains the necessary code to support sub command and
    works as the reentrant function. The global "info_cmds" is still used
    in second part, which will be replaced by sub command code later.
    
    Signed-off-by: Wenchao Xia <xiawenc at linux.vnet.ibm.com>
    Reviewed-by: Eric Blake <eblake at redhat.com>
    Signed-off-by: Luiz Capitulino <lcapitulino at redhat.com>

diff --git a/monitor.c b/monitor.c
index 39c8753..424d30c 100644
--- a/monitor.c
+++ b/monitor.c
@@ -4230,34 +4230,17 @@ static const char *next_arg_type(const char *typestr)
     return (p != NULL ? ++p : typestr);
 }
 
-static void monitor_find_completion(Monitor *mon,
-                                    const char *cmdline)
+static void monitor_find_completion_by_table(Monitor *mon,
+                                             const mon_cmd_t *cmd_table,
+                                             char **args,
+                                             int nb_args)
 {
     const char *cmdname;
-    char *args[MAX_ARGS];
-    int nb_args, i, len;
+    int i;
     const char *ptype, *str;
     const mon_cmd_t *cmd;
     MonitorBlockComplete mbs;
 
-    if (parse_cmdline(cmdline, &nb_args, args) < 0) {
-        return;
-    }
-#ifdef DEBUG_COMPLETION
-    for (i = 0; i < nb_args; i++) {
-        monitor_printf(mon, "arg%d = '%s'\n", i, args[i]);
-    }
-#endif
-
-    /* if the line ends with a space, it means we want to complete the
-       next arg */
-    len = strlen(cmdline);
-    if (len > 0 && qemu_isspace(cmdline[len - 1])) {
-        if (nb_args >= MAX_ARGS) {
-            goto cleanup;
-        }
-        args[nb_args++] = g_strdup("");
-    }
     if (nb_args <= 1) {
         /* command completion */
         if (nb_args == 0)
@@ -4265,18 +4248,18 @@ static void monitor_find_completion(Monitor *mon,
         else
             cmdname = args[0];
         readline_set_completion_index(mon->rs, strlen(cmdname));
-        for (cmd = mon->cmd_table; cmd->name != NULL; cmd++) {
+        for (cmd = cmd_table; cmd->name != NULL; cmd++) {
             cmd_completion(mon, cmdname, cmd->name);
         }
     } else {
         /* find the command */
-        for (cmd = mon->cmd_table; cmd->name != NULL; cmd++) {
+        for (cmd = cmd_table; cmd->name != NULL; cmd++) {
             if (compare_cmd(args[0], cmd->name)) {
                 break;
             }
         }
         if (!cmd->name) {
-            goto cleanup;
+            return;
         }
 
         ptype = next_arg_type(cmd->args_type);
@@ -4321,7 +4304,7 @@ static void monitor_find_completion(Monitor *mon,
                 }
             } else if (!strcmp(cmd->name, "help|?")) {
                 readline_set_completion_index(mon->rs, strlen(str));
-                for (cmd = mon->cmd_table; cmd->name != NULL; cmd++) {
+                for (cmd = cmd_table; cmd->name != NULL; cmd++) {
                     cmd_completion(mon, str, cmd->name);
                 }
             }
@@ -4330,6 +4313,36 @@ static void monitor_find_completion(Monitor *mon,
             break;
         }
     }
+}
+
+static void monitor_find_completion(Monitor *mon,
+                                    const char *cmdline)
+{
+    char *args[MAX_ARGS];
+    int nb_args, len;
+
+    /* 1. parse the cmdline */
+    if (parse_cmdline(cmdline, &nb_args, args) < 0) {
+        return;
+    }
+#ifdef DEBUG_COMPLETION
+    for (i = 0; i < nb_args; i++) {
+        monitor_printf(mon, "arg%d = '%s'\n", i, args[i]);
+    }
+#endif
+
+    /* if the line ends with a space, it means we want to complete the
+       next arg */
+    len = strlen(cmdline);
+    if (len > 0 && qemu_isspace(cmdline[len - 1])) {
+        if (nb_args >= MAX_ARGS) {
+            goto cleanup;
+        }
+        args[nb_args++] = g_strdup("");
+    }
+
+    /* 2. auto complete according to args */
+    monitor_find_completion_by_table(mon, mon->cmd_table, args, nb_args);
 
 cleanup:
     free_cmdline_args(args, nb_args);
commit 66855495fbcca9411a21e6eba6a3a0385007c96d
Author: Wenchao Xia <xiawenc at linux.vnet.ibm.com>
Date:   Tue Aug 27 20:38:23 2013 +0800

    monitor: support sub command in help
    
    The old code in help_cmd() uses global 'info_cmds' and treats it as a
    special case. Actually 'info_cmds' is a sub command group of 'mon_cmds',
    in order to avoid direct use of it, help_cmd() needs to change its work
    mechanism to support sub command and not treat it as a special case
    any more.
    
    To support sub command, help_cmd() will first parse the input and then call
    help_cmd_dump(), which works as a reentrant function. When it meets a sub
    command, it simply enters the function again. Since help dumping needs to
    know whole input to printf full help message include prefix, for example,
    "help info block" need to printf prefix "info", so help_cmd_dump() takes all
    args from input and extra parameter arg_index to identify the progress.
    Another function help_cmd_dump_one() is introduced to printf the prefix
    and command's help message.
    
    Now help supports sub command, so later if another sub command group is
    added in any depth, help will automatically work for it. Still "help info
    block" will show error since command parser reject additional parameter,
    which can be improved later. "log" is still treated as a special case.
    
    Signed-off-by: Wenchao Xia <xiawenc at linux.vnet.ibm.com>
    Signed-off-by: Luiz Capitulino <lcapitulino at redhat.com>

diff --git a/monitor.c b/monitor.c
index aae1bab..39c8753 100644
--- a/monitor.c
+++ b/monitor.c
@@ -880,33 +880,75 @@ static int parse_cmdline(const char *cmdline,
     return -1;
 }
 
+static void help_cmd_dump_one(Monitor *mon,
+                              const mon_cmd_t *cmd,
+                              char **prefix_args,
+                              int prefix_args_nb)
+{
+    int i;
+
+    for (i = 0; i < prefix_args_nb; i++) {
+        monitor_printf(mon, "%s ", prefix_args[i]);
+    }
+    monitor_printf(mon, "%s %s -- %s\n", cmd->name, cmd->params, cmd->help);
+}
+
+/* @args[@arg_index] is the valid command need to find in @cmds */
 static void help_cmd_dump(Monitor *mon, const mon_cmd_t *cmds,
-                          const char *prefix, const char *name)
+                          char **args, int nb_args, int arg_index)
 {
     const mon_cmd_t *cmd;
 
-    for(cmd = cmds; cmd->name != NULL; cmd++) {
-        if (!name || !strcmp(name, cmd->name))
-            monitor_printf(mon, "%s%s %s -- %s\n", prefix, cmd->name,
-                           cmd->params, cmd->help);
+    /* No valid arg need to compare with, dump all in *cmds */
+    if (arg_index >= nb_args) {
+        for (cmd = cmds; cmd->name != NULL; cmd++) {
+            help_cmd_dump_one(mon, cmd, args, arg_index);
+        }
+        return;
+    }
+
+    /* Find one entry to dump */
+    for (cmd = cmds; cmd->name != NULL; cmd++) {
+        if (compare_cmd(args[arg_index], cmd->name)) {
+            if (cmd->sub_table) {
+                /* continue with next arg */
+                help_cmd_dump(mon, cmd->sub_table,
+                              args, nb_args, arg_index + 1);
+            } else {
+                help_cmd_dump_one(mon, cmd, args, arg_index);
+            }
+            break;
+        }
     }
 }
 
 static void help_cmd(Monitor *mon, const char *name)
 {
-    if (name && !strcmp(name, "info")) {
-        help_cmd_dump(mon, info_cmds, "info ", NULL);
-    } else {
-        help_cmd_dump(mon, mon->cmd_table, "", name);
-        if (name && !strcmp(name, "log")) {
+    char *args[MAX_ARGS];
+    int nb_args = 0;
+
+    /* 1. parse user input */
+    if (name) {
+        /* special case for log, directly dump and return */
+        if (!strcmp(name, "log")) {
             const QEMULogItem *item;
             monitor_printf(mon, "Log items (comma separated):\n");
             monitor_printf(mon, "%-10s %s\n", "none", "remove all logs");
             for (item = qemu_log_items; item->mask != 0; item++) {
                 monitor_printf(mon, "%-10s %s\n", item->name, item->help);
             }
+            return;
+        }
+
+        if (parse_cmdline(name, &nb_args, args) < 0) {
+            return;
         }
     }
+
+    /* 2. dump the contents according to parsed args */
+    help_cmd_dump(mon, mon->cmd_table, args, nb_args, 0);
+
+    free_cmdline_args(args, nb_args);
 }
 
 static void do_help_cmd(Monitor *mon, const QDict *qdict)
commit dcc70cdf0932172fc5cf27617a3b033ca58d0176
Author: Wenchao Xia <xiawenc at linux.vnet.ibm.com>
Date:   Tue Aug 27 20:38:22 2013 +0800

    monitor: refine parse_cmdline()
    
    Since this function will be used by help_cmd() later, so improve
    it to make it more generic and easier to use. free_cmdline_args()
    is added too as paired function to free the result.
    
    One change of this function is that, when the valid args in input
    exceed the limit of MAX_ARGS, it fails now, instead of return with
    MAX_ARGS of parsed args in old code. This should not impact much
    since it is rare that user input many args in monitor's "help" and
    auto complete scenario.
    
    Signed-off-by: Wenchao Xia <xiawenc at linux.vnet.ibm.com>
    Reviewed-by: Eric Blake <eblake at redhat.com>
    Signed-off-by: Luiz Capitulino <lcapitulino at redhat.com>

diff --git a/monitor.c b/monitor.c
index 7612147..aae1bab 100644
--- a/monitor.c
+++ b/monitor.c
@@ -821,9 +821,33 @@ static int get_str(char *buf, int buf_size, const char **pp)
 
 #define MAX_ARGS 16
 
-/* NOTE: this parser is an approximate form of the real command parser */
-static void parse_cmdline(const char *cmdline,
-                          int *pnb_args, char **args)
+static void free_cmdline_args(char **args, int nb_args)
+{
+    int i;
+
+    assert(nb_args <= MAX_ARGS);
+
+    for (i = 0; i < nb_args; i++) {
+        g_free(args[i]);
+    }
+
+}
+
+/*
+ * Parse the command line to get valid args.
+ * @cmdline: command line to be parsed.
+ * @pnb_args: location to store the number of args, must NOT be NULL.
+ * @args: location to store the args, which should be freed by caller, must
+ *        NOT be NULL.
+ *
+ * Returns 0 on success, negative on failure.
+ *
+ * NOTE: this parser is an approximate form of the real command parser. Number
+ *       of args have a limit of MAX_ARGS. If cmdline contains more, it will
+ *       return with failure.
+ */
+static int parse_cmdline(const char *cmdline,
+                         int *pnb_args, char **args)
 {
     const char *p;
     int nb_args, ret;
@@ -839,16 +863,21 @@ static void parse_cmdline(const char *cmdline,
             break;
         }
         if (nb_args >= MAX_ARGS) {
-            break;
+            goto fail;
         }
         ret = get_str(buf, sizeof(buf), &p);
-        args[nb_args] = g_strdup(buf);
-        nb_args++;
         if (ret < 0) {
-            break;
+            goto fail;
         }
+        args[nb_args] = g_strdup(buf);
+        nb_args++;
     }
     *pnb_args = nb_args;
+    return 0;
+
+ fail:
+    free_cmdline_args(args, nb_args);
+    return -1;
 }
 
 static void help_cmd_dump(Monitor *mon, const mon_cmd_t *cmds,
@@ -4169,7 +4198,9 @@ static void monitor_find_completion(Monitor *mon,
     const mon_cmd_t *cmd;
     MonitorBlockComplete mbs;
 
-    parse_cmdline(cmdline, &nb_args, args);
+    if (parse_cmdline(cmdline, &nb_args, args) < 0) {
+        return;
+    }
 #ifdef DEBUG_COMPLETION
     for (i = 0; i < nb_args; i++) {
         monitor_printf(mon, "arg%d = '%s'\n", i, args[i]);
@@ -4259,9 +4290,7 @@ static void monitor_find_completion(Monitor *mon,
     }
 
 cleanup:
-    for (i = 0; i < nb_args; i++) {
-        g_free(args[i]);
-    }
+    free_cmdline_args(args, nb_args);
 }
 
 static int monitor_can_read(void *opaque)
commit f5438c0500bb22c97b30987d2e0eab953416c7c5
Author: Wenchao Xia <xiawenc at linux.vnet.ibm.com>
Date:   Tue Aug 27 20:38:21 2013 +0800

    monitor: code move for parse_cmdline()
    
    help_cmd() need this function later, so move it. get_str() is called by
    parse_cmdline() so it is moved also. Some code style error reported by
    check script, is also fixed.
    
    Signed-off-by: Wenchao Xia <xiawenc at linux.vnet.ibm.com>
    Reviewed-by: Eric Blake <eblake at redhat.com>
    Signed-off-by: Luiz Capitulino <lcapitulino at redhat.com>

diff --git a/monitor.c b/monitor.c
index ce2a1ee..7612147 100644
--- a/monitor.c
+++ b/monitor.c
@@ -753,6 +753,104 @@ static int compare_cmd(const char *name, const char *list)
     return 0;
 }
 
+static int get_str(char *buf, int buf_size, const char **pp)
+{
+    const char *p;
+    char *q;
+    int c;
+
+    q = buf;
+    p = *pp;
+    while (qemu_isspace(*p)) {
+        p++;
+    }
+    if (*p == '\0') {
+    fail:
+        *q = '\0';
+        *pp = p;
+        return -1;
+    }
+    if (*p == '\"') {
+        p++;
+        while (*p != '\0' && *p != '\"') {
+            if (*p == '\\') {
+                p++;
+                c = *p++;
+                switch (c) {
+                case 'n':
+                    c = '\n';
+                    break;
+                case 'r':
+                    c = '\r';
+                    break;
+                case '\\':
+                case '\'':
+                case '\"':
+                    break;
+                default:
+                    qemu_printf("unsupported escape code: '\\%c'\n", c);
+                    goto fail;
+                }
+                if ((q - buf) < buf_size - 1) {
+                    *q++ = c;
+                }
+            } else {
+                if ((q - buf) < buf_size - 1) {
+                    *q++ = *p;
+                }
+                p++;
+            }
+        }
+        if (*p != '\"') {
+            qemu_printf("unterminated string\n");
+            goto fail;
+        }
+        p++;
+    } else {
+        while (*p != '\0' && !qemu_isspace(*p)) {
+            if ((q - buf) < buf_size - 1) {
+                *q++ = *p;
+            }
+            p++;
+        }
+    }
+    *q = '\0';
+    *pp = p;
+    return 0;
+}
+
+#define MAX_ARGS 16
+
+/* NOTE: this parser is an approximate form of the real command parser */
+static void parse_cmdline(const char *cmdline,
+                          int *pnb_args, char **args)
+{
+    const char *p;
+    int nb_args, ret;
+    char buf[1024];
+
+    p = cmdline;
+    nb_args = 0;
+    for (;;) {
+        while (qemu_isspace(*p)) {
+            p++;
+        }
+        if (*p == '\0') {
+            break;
+        }
+        if (nb_args >= MAX_ARGS) {
+            break;
+        }
+        ret = get_str(buf, sizeof(buf), &p);
+        args[nb_args] = g_strdup(buf);
+        nb_args++;
+        if (ret < 0) {
+            break;
+        }
+    }
+    *pnb_args = nb_args;
+}
+
 static void help_cmd_dump(Monitor *mon, const mon_cmd_t *cmds,
                           const char *prefix, const char *name)
 {
@@ -3434,71 +3532,6 @@ static int get_double(Monitor *mon, double *pval, const char **pp)
     return 0;
 }
 
-static int get_str(char *buf, int buf_size, const char **pp)
-{
-    const char *p;
-    char *q;
-    int c;
-
-    q = buf;
-    p = *pp;
-    while (qemu_isspace(*p))
-        p++;
-    if (*p == '\0') {
-    fail:
-        *q = '\0';
-        *pp = p;
-        return -1;
-    }
-    if (*p == '\"') {
-        p++;
-        while (*p != '\0' && *p != '\"') {
-            if (*p == '\\') {
-                p++;
-                c = *p++;
-                switch(c) {
-                case 'n':
-                    c = '\n';
-                    break;
-                case 'r':
-                    c = '\r';
-                    break;
-                case '\\':
-                case '\'':
-                case '\"':
-                    break;
-                default:
-                    qemu_printf("unsupported escape code: '\\%c'\n", c);
-                    goto fail;
-                }
-                if ((q - buf) < buf_size - 1) {
-                    *q++ = c;
-                }
-            } else {
-                if ((q - buf) < buf_size - 1) {
-                    *q++ = *p;
-                }
-                p++;
-            }
-        }
-        if (*p != '\"') {
-            qemu_printf("unterminated string\n");
-            goto fail;
-        }
-        p++;
-    } else {
-        while (*p != '\0' && !qemu_isspace(*p)) {
-            if ((q - buf) < buf_size - 1) {
-                *q++ = *p;
-            }
-            p++;
-        }
-    }
-    *q = '\0';
-    *pp = p;
-    return 0;
-}
-
 /*
  * Store the command-name in cmdname, and return a pointer to
  * the remaining of the command string.
@@ -3555,8 +3588,6 @@ static char *key_get_info(const char *type, char **key)
 static int default_fmt_format = 'x';
 static int default_fmt_size = 4;
 
-#define MAX_ARGS 16
-
 static int is_valid_option(const char *c, const char *typestr)
 {
     char option[3];
@@ -4122,32 +4153,6 @@ static void block_completion_it(void *opaque, BlockDriverState *bs)
     }
 }
 
-/* NOTE: this parser is an approximate form of the real command parser */
-static void parse_cmdline(const char *cmdline,
-                         int *pnb_args, char **args)
-{
-    const char *p;
-    int nb_args, ret;
-    char buf[1024];
-
-    p = cmdline;
-    nb_args = 0;
-    for(;;) {
-        while (qemu_isspace(*p))
-            p++;
-        if (*p == '\0')
-            break;
-        if (nb_args >= MAX_ARGS)
-            break;
-        ret = get_str(buf, sizeof(buf), &p);
-        args[nb_args] = g_strdup(buf);
-        nb_args++;
-        if (ret < 0)
-            break;
-    }
-    *pnb_args = nb_args;
-}
-
 static const char *next_arg_type(const char *typestr)
 {
     const char *p = strchr(typestr, ':');
commit 7717239dc1778e94a6210e62e1ec2ba720168eec
Author: Wenchao Xia <xiawenc at linux.vnet.ibm.com>
Date:   Tue Aug 27 20:38:20 2013 +0800

    monitor: avoid direct use of global variable *mon_cmds
    
    New member *cmd_table is added in structure Monitor to avoid direct usage of
    *mon_cmds. Now monitor have an associated command table, when global variable
    *info_cmds is also discarded, structure Monitor would gain full control about
    how to deal with user input.
    
    Signed-off-by: Wenchao Xia <xiawenc at linux.vnet.ibm.com>
    Signed-off-by: Luiz Capitulino <lcapitulino at redhat.com>

diff --git a/monitor.c b/monitor.c
index 1f645e1..ce2a1ee 100644
--- a/monitor.c
+++ b/monitor.c
@@ -195,6 +195,7 @@ struct Monitor {
     CPUState *mon_cpu;
     BlockDriverCompletionFunc *password_completion_cb;
     void *password_opaque;
+    mon_cmd_t *cmd_table;
     QError *error;
     QLIST_HEAD(,mon_fd_t) fds;
     QLIST_ENTRY(Monitor) entry;
@@ -687,6 +688,8 @@ static void monitor_data_init(Monitor *mon)
 {
     memset(mon, 0, sizeof(Monitor));
     mon->outbuf = qstring_new();
+    /* Use *mon_cmds by default. */
+    mon->cmd_table = mon_cmds;
 }
 
 static void monitor_data_destroy(Monitor *mon)
@@ -767,7 +770,7 @@ static void help_cmd(Monitor *mon, const char *name)
     if (name && !strcmp(name, "info")) {
         help_cmd_dump(mon, info_cmds, "info ", NULL);
     } else {
-        help_cmd_dump(mon, mon_cmds, "", name);
+        help_cmd_dump(mon, mon->cmd_table, "", name);
         if (name && !strcmp(name, "log")) {
             const QEMULogItem *item;
             monitor_printf(mon, "Log items (comma separated):\n");
@@ -3995,7 +3998,7 @@ static void handle_user_command(Monitor *mon, const char *cmdline)
 
     qdict = qdict_new();
 
-    cmd = monitor_parse_command(mon, cmdline, 0, mon_cmds, qdict);
+    cmd = monitor_parse_command(mon, cmdline, 0, mon->cmd_table, qdict);
     if (!cmd)
         goto out;
 
@@ -4184,12 +4187,12 @@ static void monitor_find_completion(Monitor *mon,
         else
             cmdname = args[0];
         readline_set_completion_index(mon->rs, strlen(cmdname));
-        for(cmd = mon_cmds; cmd->name != NULL; cmd++) {
+        for (cmd = mon->cmd_table; cmd->name != NULL; cmd++) {
             cmd_completion(mon, cmdname, cmd->name);
         }
     } else {
         /* find the command */
-        for (cmd = mon_cmds; cmd->name != NULL; cmd++) {
+        for (cmd = mon->cmd_table; cmd->name != NULL; cmd++) {
             if (compare_cmd(args[0], cmd->name)) {
                 break;
             }
@@ -4240,7 +4243,7 @@ static void monitor_find_completion(Monitor *mon,
                 }
             } else if (!strcmp(cmd->name, "help|?")) {
                 readline_set_completion_index(mon->rs, strlen(str));
-                for (cmd = mon_cmds; cmd->name != NULL; cmd++) {
+                for (cmd = mon->cmd_table; cmd->name != NULL; cmd++) {
                     cmd_completion(mon, str, cmd->name);
                 }
             }
commit b01fe89e91268c6b02720735643020746610e6d8
Author: Wenchao Xia <xiawenc at linux.vnet.ibm.com>
Date:   Tue Aug 27 20:38:19 2013 +0800

    monitor: split off monitor_data_init()
    
    In qmp_human_monitor_command(), the monitor need to initialized for
    basic functionalities, and later more init code will be added, so
    split off this function. Note that it is different with QMP mode
    monitor which accept json string from monitor's input,
    qmp_human_monitor_command() retrieve the human style command from
    QMP input, then send the command to a normal mode monitor.
    
    Signed-off-by: Wenchao Xia <xiawenc at linux.vnet.ibm.com>
    Signed-off-by: Luiz Capitulino <lcapitulino at redhat.com>

diff --git a/monitor.c b/monitor.c
index 457948d..1f645e1 100644
--- a/monitor.c
+++ b/monitor.c
@@ -683,14 +683,24 @@ static int do_qmp_capabilities(Monitor *mon, const QDict *params,
 
 static void handle_user_command(Monitor *mon, const char *cmdline);
 
+static void monitor_data_init(Monitor *mon)
+{
+    memset(mon, 0, sizeof(Monitor));
+    mon->outbuf = qstring_new();
+}
+
+static void monitor_data_destroy(Monitor *mon)
+{
+    QDECREF(mon->outbuf);
+}
+
 char *qmp_human_monitor_command(const char *command_line, bool has_cpu_index,
                                 int64_t cpu_index, Error **errp)
 {
     char *output = NULL;
     Monitor *old_mon, hmp;
 
-    memset(&hmp, 0, sizeof(hmp));
-    hmp.outbuf = qstring_new();
+    monitor_data_init(&hmp);
     hmp.skip_flush = true;
 
     old_mon = cur_mon;
@@ -716,7 +726,7 @@ char *qmp_human_monitor_command(const char *command_line, bool has_cpu_index,
     }
 
 out:
-    QDECREF(hmp.outbuf);
+    monitor_data_destroy(&hmp);
     return output;
 }
 
@@ -4767,8 +4777,8 @@ void monitor_init(CharDriverState *chr, int flags)
         is_first_init = 0;
     }
 
-    mon = g_malloc0(sizeof(*mon));
-    mon->outbuf = qstring_new();
+    mon = g_malloc(sizeof(*mon));
+    monitor_data_init(mon);
 
     mon->chr = chr;
     mon->flags = flags;
commit d038317c357efef9d8d362e526c5f5071f505a04
Author: Wenchao Xia <xiawenc at linux.vnet.ibm.com>
Date:   Tue Aug 27 20:38:18 2013 +0800

    monitor: call sortcmdlist() only one time
    
    It doesn't need to be done for every monitor, so change it.
    
    Signed-off-by: Wenchao Xia <xiawenc at linux.vnet.ibm.com>
    Signed-off-by: Luiz Capitulino <lcapitulino at redhat.com>

diff --git a/monitor.c b/monitor.c
index b8f79a5..457948d 100644
--- a/monitor.c
+++ b/monitor.c
@@ -4763,6 +4763,7 @@ void monitor_init(CharDriverState *chr, int flags)
 
     if (is_first_init) {
         monitor_protocol_event_init();
+        sortcmdlist();
         is_first_init = 0;
     }
 
@@ -4792,8 +4793,6 @@ void monitor_init(CharDriverState *chr, int flags)
     QLIST_INSERT_HEAD(&mon_list, mon, entry);
     if (!default_mon || (flags & MONITOR_IS_DEFAULT))
         default_mon = mon;
-
-    sortcmdlist();
 }
 
 static void bdrv_password_cb(Monitor *mon, const char *password, void *opaque)
commit d1a9756ab8c2c2578cbcb325efffe0b0af916944
Author: Wenchao Xia <xiawenc at linux.vnet.ibm.com>
Date:   Tue Aug 27 20:38:17 2013 +0800

    monitor: avoid use of global *cur_mon in readline_completion()
    
    Now all completion functions do not use *cur_mon any more, instead
    they use rs->mon. In short, structure ReadLineState decide where
    the complete action would be taken now.
    
    Tested with the case that qemu have two telnet monitors, auto
    completion function works normal.
    
    Signed-off-by: Wenchao Xia <xiawenc at linux.vnet.ibm.com>
    Reviewed-by: Eric Blake <eblake at redhat.com>
    Signed-off-by: Luiz Capitulino <lcapitulino at redhat.com>

diff --git a/readline.c b/readline.c
index c91b324..abf27dd 100644
--- a/readline.c
+++ b/readline.c
@@ -276,7 +276,6 @@ void readline_set_completion_index(ReadLineState *rs, int index)
 
 static void readline_completion(ReadLineState *rs)
 {
-    Monitor *mon = cur_mon;
     int len, i, j, max_width, nb_cols, max_prefix;
     char *cmdline;
 
@@ -300,7 +299,7 @@ static void readline_completion(ReadLineState *rs)
         if (len > 0 && rs->completions[0][len - 1] != '/')
             readline_insert_char(rs, ' ');
     } else {
-        monitor_printf(mon, "\n");
+        monitor_printf(rs->mon, "\n");
         max_width = 0;
         max_prefix = 0;	
         for(i = 0; i < rs->nb_completions; i++) {
commit d2674b2cf7db7dce865f3c2b89f0e36d1657a3b5
Author: Wenchao Xia <xiawenc at linux.vnet.ibm.com>
Date:   Tue Aug 27 20:38:16 2013 +0800

    monitor: avoid use of global *cur_mon in monitor_find_completion()
    
    Parameter *mon is added, and local variable *mon added in previous patch
    is removed. The caller readline_completion(), pass rs->mon as value, which
    should be initialized in readline_init() called by monitor_init().
    
    Signed-off-by: Wenchao Xia <xiawenc at linux.vnet.ibm.com>
    Reviewed-by: Eric Blake <eblake at redhat.com>
    Signed-off-by: Luiz Capitulino <lcapitulino at redhat.com>

diff --git a/include/monitor/readline.h b/include/monitor/readline.h
index fc9806e..0faf6e1 100644
--- a/include/monitor/readline.h
+++ b/include/monitor/readline.h
@@ -8,7 +8,8 @@
 #define READLINE_MAX_COMPLETIONS 256
 
 typedef void ReadLineFunc(Monitor *mon, const char *str, void *opaque);
-typedef void ReadLineCompletionFunc(const char *cmdline);
+typedef void ReadLineCompletionFunc(Monitor *mon,
+                                    const char *cmdline);
 
 typedef struct ReadLineState {
     char cmd_buf[READLINE_CMD_BUF_SIZE + 1];
diff --git a/monitor.c b/monitor.c
index d01aa62..b8f79a5 100644
--- a/monitor.c
+++ b/monitor.c
@@ -4141,20 +4141,20 @@ static const char *next_arg_type(const char *typestr)
     return (p != NULL ? ++p : typestr);
 }
 
-static void monitor_find_completion(const char *cmdline)
+static void monitor_find_completion(Monitor *mon,
+                                    const char *cmdline)
 {
     const char *cmdname;
     char *args[MAX_ARGS];
     int nb_args, i, len;
     const char *ptype, *str;
     const mon_cmd_t *cmd;
-    Monitor *mon = cur_mon;
     MonitorBlockComplete mbs;
 
     parse_cmdline(cmdline, &nb_args, args);
 #ifdef DEBUG_COMPLETION
-    for(i = 0; i < nb_args; i++) {
-        monitor_printf(cur_mon, "arg%d = '%s'\n", i, (char *)args[i]);
+    for (i = 0; i < nb_args; i++) {
+        monitor_printf(mon, "arg%d = '%s'\n", i, args[i]);
     }
 #endif
 
@@ -4173,7 +4173,7 @@ static void monitor_find_completion(const char *cmdline)
             cmdname = "";
         else
             cmdname = args[0];
-        readline_set_completion_index(cur_mon->rs, strlen(cmdname));
+        readline_set_completion_index(mon->rs, strlen(cmdname));
         for(cmd = mon_cmds; cmd->name != NULL; cmd++) {
             cmd_completion(mon, cmdname, cmd->name);
         }
@@ -4203,7 +4203,7 @@ static void monitor_find_completion(const char *cmdline)
         switch(*ptype) {
         case 'F':
             /* file completion */
-            readline_set_completion_index(cur_mon->rs, strlen(str));
+            readline_set_completion_index(mon->rs, strlen(str));
             file_completion(mon, str);
             break;
         case 'B':
@@ -4216,7 +4216,7 @@ static void monitor_find_completion(const char *cmdline)
         case 's':
             /* XXX: more generic ? */
             if (!strcmp(cmd->name, "info")) {
-                readline_set_completion_index(cur_mon->rs, strlen(str));
+                readline_set_completion_index(mon->rs, strlen(str));
                 for(cmd = info_cmds; cmd->name != NULL; cmd++) {
                     cmd_completion(mon, str, cmd->name);
                 }
@@ -4224,12 +4224,12 @@ static void monitor_find_completion(const char *cmdline)
                 char *sep = strrchr(str, '-');
                 if (sep)
                     str = sep + 1;
-                readline_set_completion_index(cur_mon->rs, strlen(str));
+                readline_set_completion_index(mon->rs, strlen(str));
                 for (i = 0; i < Q_KEY_CODE_MAX; i++) {
                     cmd_completion(mon, str, QKeyCode_lookup[i]);
                 }
             } else if (!strcmp(cmd->name, "help|?")) {
-                readline_set_completion_index(cur_mon->rs, strlen(str));
+                readline_set_completion_index(mon->rs, strlen(str));
                 for (cmd = mon_cmds; cmd->name != NULL; cmd++) {
                     cmd_completion(mon, str, cmd->name);
                 }
diff --git a/readline.c b/readline.c
index 1c0f7ee..c91b324 100644
--- a/readline.c
+++ b/readline.c
@@ -285,7 +285,7 @@ static void readline_completion(ReadLineState *rs)
     cmdline = g_malloc(rs->cmd_buf_index + 1);
     memcpy(cmdline, rs->cmd_buf, rs->cmd_buf_index);
     cmdline[rs->cmd_buf_index] = '\0';
-    rs->completion_finder(cmdline);
+    rs->completion_finder(rs->mon, cmdline);
     g_free(cmdline);
 
     /* no completion found */
commit 599a926abcf581732d449163a96fd9a4cc80091a
Author: Wenchao Xia <xiawenc at linux.vnet.ibm.com>
Date:   Tue Aug 27 20:38:15 2013 +0800

    monitor: avoid use of global *cur_mon in block_completion_it()
    
    Signed-off-by: Wenchao Xia <xiawenc at linux.vnet.ibm.com>
    Reviewed-by: Eric Blake <eblake at redhat.com>
    Signed-off-by: Luiz Capitulino <lcapitulino at redhat.com>

diff --git a/monitor.c b/monitor.c
index 3a0b40c..d01aa62 100644
--- a/monitor.c
+++ b/monitor.c
@@ -4091,14 +4091,21 @@ static void file_completion(Monitor *mon, const char *input)
     closedir(ffs);
 }
 
+typedef struct MonitorBlockComplete {
+    Monitor *mon;
+    const char *input;
+} MonitorBlockComplete;
+
 static void block_completion_it(void *opaque, BlockDriverState *bs)
 {
     const char *name = bdrv_get_device_name(bs);
-    const char *input = opaque;
+    MonitorBlockComplete *mbc = opaque;
+    Monitor *mon = mbc->mon;
+    const char *input = mbc->input;
 
     if (input[0] == '\0' ||
         !strncmp(name, (char *)input, strlen(input))) {
-        readline_add_completion(cur_mon->rs, name);
+        readline_add_completion(mon->rs, name);
     }
 }
 
@@ -4142,6 +4149,7 @@ static void monitor_find_completion(const char *cmdline)
     const char *ptype, *str;
     const mon_cmd_t *cmd;
     Monitor *mon = cur_mon;
+    MonitorBlockComplete mbs;
 
     parse_cmdline(cmdline, &nb_args, args);
 #ifdef DEBUG_COMPLETION
@@ -4200,8 +4208,10 @@ static void monitor_find_completion(const char *cmdline)
             break;
         case 'B':
             /* block device name completion */
-            readline_set_completion_index(cur_mon->rs, strlen(str));
-            bdrv_iterate(block_completion_it, (void *)str);
+            mbs.mon = mon;
+            mbs.input = str;
+            readline_set_completion_index(mon->rs, strlen(str));
+            bdrv_iterate(block_completion_it, &mbs);
             break;
         case 's':
             /* XXX: more generic ? */
commit cb8f68b104f8d14f0ad856012cac7bd27f183799
Author: Wenchao Xia <xiawenc at linux.vnet.ibm.com>
Date:   Tue Aug 27 20:38:14 2013 +0800

    monitor: avoid use of global *cur_mon in file_completion()
    
    Signed-off-by: Wenchao Xia <xiawenc at linux.vnet.ibm.com>
    Reviewed-by: Eric Blake <eblake at redhat.com>
    Signed-off-by: Luiz Capitulino <lcapitulino at redhat.com>

diff --git a/monitor.c b/monitor.c
index 770ab6e..3a0b40c 100644
--- a/monitor.c
+++ b/monitor.c
@@ -4035,7 +4035,7 @@ static void cmd_completion(Monitor *mon, const char *name, const char *list)
     }
 }
 
-static void file_completion(const char *input)
+static void file_completion(Monitor *mon, const char *input)
 {
     DIR *ffs;
     struct dirent *d;
@@ -4058,7 +4058,7 @@ static void file_completion(const char *input)
         pstrcpy(file_prefix, sizeof(file_prefix), p + 1);
     }
 #ifdef DEBUG_COMPLETION
-    monitor_printf(cur_mon, "input='%s' path='%s' prefix='%s'\n",
+    monitor_printf(mon, "input='%s' path='%s' prefix='%s'\n",
                    input, path, file_prefix);
 #endif
     ffs = opendir(path);
@@ -4085,7 +4085,7 @@ static void file_completion(const char *input)
             if (stat(file, &sb) == 0 && S_ISDIR(sb.st_mode)) {
                 pstrcat(file, sizeof(file), "/");
             }
-            readline_add_completion(cur_mon->rs, file);
+            readline_add_completion(mon->rs, file);
         }
     }
     closedir(ffs);
@@ -4196,7 +4196,7 @@ static void monitor_find_completion(const char *cmdline)
         case 'F':
             /* file completion */
             readline_set_completion_index(cur_mon->rs, strlen(str));
-            file_completion(str);
+            file_completion(mon, str);
             break;
         case 'B':
             /* block device name completion */
commit cd5c6bba1b75d4faebb58345d2661d5e42600fab
Author: Wenchao Xia <xiawenc at linux.vnet.ibm.com>
Date:   Tue Aug 27 20:38:13 2013 +0800

    monitor: avoid use of global *cur_mon in cmd_completion()
    
    A new local variable *mon is added in monitor_find_completion()
    to make compile pass, which will be removed later in
    conversion patch for monitor_find_completion().
    
    Signed-off-by: Wenchao Xia <xiawenc at linux.vnet.ibm.com>
    Reviewed-by: Eric Blake <eblake at redhat.com>
    Signed-off-by: Luiz Capitulino <lcapitulino at redhat.com>

diff --git a/monitor.c b/monitor.c
index 8c23e29..770ab6e 100644
--- a/monitor.c
+++ b/monitor.c
@@ -4009,7 +4009,7 @@ out:
     QDECREF(qdict);
 }
 
-static void cmd_completion(const char *name, const char *list)
+static void cmd_completion(Monitor *mon, const char *name, const char *list)
 {
     const char *p, *pstart;
     char cmd[128];
@@ -4027,7 +4027,7 @@ static void cmd_completion(const char *name, const char *list)
         memcpy(cmd, pstart, len);
         cmd[len] = '\0';
         if (name[0] == '\0' || !strncmp(name, cmd, strlen(name))) {
-            readline_add_completion(cur_mon->rs, cmd);
+            readline_add_completion(mon->rs, cmd);
         }
         if (*p == '\0')
             break;
@@ -4141,6 +4141,7 @@ static void monitor_find_completion(const char *cmdline)
     int nb_args, i, len;
     const char *ptype, *str;
     const mon_cmd_t *cmd;
+    Monitor *mon = cur_mon;
 
     parse_cmdline(cmdline, &nb_args, args);
 #ifdef DEBUG_COMPLETION
@@ -4166,7 +4167,7 @@ static void monitor_find_completion(const char *cmdline)
             cmdname = args[0];
         readline_set_completion_index(cur_mon->rs, strlen(cmdname));
         for(cmd = mon_cmds; cmd->name != NULL; cmd++) {
-            cmd_completion(cmdname, cmd->name);
+            cmd_completion(mon, cmdname, cmd->name);
         }
     } else {
         /* find the command */
@@ -4207,7 +4208,7 @@ static void monitor_find_completion(const char *cmdline)
             if (!strcmp(cmd->name, "info")) {
                 readline_set_completion_index(cur_mon->rs, strlen(str));
                 for(cmd = info_cmds; cmd->name != NULL; cmd++) {
-                    cmd_completion(str, cmd->name);
+                    cmd_completion(mon, str, cmd->name);
                 }
             } else if (!strcmp(cmd->name, "sendkey")) {
                 char *sep = strrchr(str, '-');
@@ -4215,12 +4216,12 @@ static void monitor_find_completion(const char *cmdline)
                     str = sep + 1;
                 readline_set_completion_index(cur_mon->rs, strlen(str));
                 for (i = 0; i < Q_KEY_CODE_MAX; i++) {
-                    cmd_completion(str, QKeyCode_lookup[i]);
+                    cmd_completion(mon, str, QKeyCode_lookup[i]);
                 }
             } else if (!strcmp(cmd->name, "help|?")) {
                 readline_set_completion_index(cur_mon->rs, strlen(str));
                 for (cmd = mon_cmds; cmd->name != NULL; cmd++) {
-                    cmd_completion(str, cmd->name);
+                    cmd_completion(mon, str, cmd->name);
                 }
             }
             break;
commit 9c3175cc15fbe8d3528375d1389dad40b19b7665
Author: Stefan Weil <sw at weilnetz.de>
Date:   Thu Aug 22 21:30:09 2013 +0200

    monitor: Add missing attributes to local function
    
    Function expr_error gets a format string and variable arguments like printf.
    It also never returns. Add the necessary attributes.
    
    Signed-off-by: Stefan Weil <sw at weilnetz.de>
    Signed-off-by: Luiz Capitulino <lcapitulino at redhat.com>

diff --git a/monitor.c b/monitor.c
index ee9744c..8c23e29 100644
--- a/monitor.c
+++ b/monitor.c
@@ -3171,7 +3171,8 @@ static const MonitorDef monitor_defs[] = {
     { NULL },
 };
 
-static void expr_error(Monitor *mon, const char *fmt, ...)
+static void GCC_FMT_ATTR(2, 3) QEMU_NORETURN
+expr_error(Monitor *mon, const char *fmt, ...)
 {
     va_list ap;
     va_start(ap, fmt);
commit 29c6157ca7bfa036a8c59805c1a1d76ba9a2a851
Author: Christian Borntraeger <borntraeger at de.ibm.com>
Date:   Thu Jul 25 16:45:51 2013 +0200

    s390: provide a cpu load normal function
    
    Some code needs to perform an IPL-like bootup that mimics the
    ESA (31bit) restart. Provide a cpu class method that does so.
    
    Signed-off-by: Christian Borntraeger <borntraeger at de.ibm.com>
    Acked-by: Alexander Graf <agraf at suse.de>

diff --git a/target-s390x/cpu-qom.h b/target-s390x/cpu-qom.h
index cbe2341..2dc1750 100644
--- a/target-s390x/cpu-qom.h
+++ b/target-s390x/cpu-qom.h
@@ -36,6 +36,7 @@
  * S390CPUClass:
  * @parent_realize: The parent class' realize handler.
  * @parent_reset: The parent class' reset handler.
+ * @load_normal: Performs a load normal.
  *
  * An S/390 CPU model.
  */
@@ -46,6 +47,7 @@ typedef struct S390CPUClass {
 
     DeviceRealize parent_realize;
     void (*parent_reset)(CPUState *cpu);
+    void (*load_normal)(CPUState *cpu);
 } S390CPUClass;
 
 /**
diff --git a/target-s390x/cpu.c b/target-s390x/cpu.c
index 5cc9938..69f5e10 100644
--- a/target-s390x/cpu.c
+++ b/target-s390x/cpu.c
@@ -65,6 +65,17 @@ static void s390_cpu_set_pc(CPUState *cs, vaddr value)
     cpu->env.psw.addr = value;
 }
 
+#if !defined(CONFIG_USER_ONLY)
+/* S390CPUClass::load_normal() */
+static void s390_cpu_load_normal(CPUState *s)
+{
+    S390CPU *cpu = S390_CPU(s);
+    cpu->env.psw.addr = ldl_phys(4) & PSW_MASK_ESA_ADDR;
+    cpu->env.psw.mask = PSW_MASK_32 | PSW_MASK_64;
+    s390_add_running_cpu(cpu);
+}
+#endif
+
 /* CPUClass::reset() */
 static void s390_cpu_reset(CPUState *s)
 {
@@ -169,6 +180,9 @@ static void s390_cpu_class_init(ObjectClass *oc, void *data)
     dc->realize = s390_cpu_realizefn;
 
     scc->parent_reset = cc->reset;
+#if !defined(CONFIG_USER_ONLY)
+    scc->load_normal = s390_cpu_load_normal;
+#endif
     cc->reset = s390_cpu_reset;
 
     cc->do_interrupt = s390_cpu_do_interrupt;
diff --git a/target-s390x/cpu.h b/target-s390x/cpu.h
index af9de5e..b866ea1 100644
--- a/target-s390x/cpu.h
+++ b/target-s390x/cpu.h
@@ -228,6 +228,8 @@ typedef struct CPUS390XState {
 #undef PSW_MASK_CC
 #undef PSW_MASK_PM
 #undef PSW_MASK_64
+#undef PSW_MASK_32
+#undef PSW_MASK_ESA_ADDR
 
 #define PSW_MASK_PER            0x4000000000000000ULL
 #define PSW_MASK_DAT            0x0400000000000000ULL
@@ -243,6 +245,7 @@ typedef struct CPUS390XState {
 #define PSW_MASK_PM             0x00000F0000000000ULL
 #define PSW_MASK_64             0x0000000100000000ULL
 #define PSW_MASK_32             0x0000000080000000ULL
+#define PSW_MASK_ESA_ADDR       0x000000007fffffffULL
 
 #undef PSW_ASC_PRIMARY
 #undef PSW_ASC_ACCREG
commit 4e872a3fb024f0d742ef6b48be3afaab2c4453fc
Author: Christian Borntraeger <borntraeger at de.ibm.com>
Date:   Thu Jul 25 16:37:37 2013 +0200

    s390: provide I/O subsystem reset
    
    Provide a function that resets the I/O subsystem.
    
    Signed-off-by: Christian Borntraeger <borntraeger at de.ibm.com>
    Acked-by: Alexander Graf <agraf at suse.de>

diff --git a/hw/s390x/s390-virtio-ccw.c b/hw/s390x/s390-virtio-ccw.c
index aebbbf1..8fd46a9 100644
--- a/hw/s390x/s390-virtio-ccw.c
+++ b/hw/s390x/s390-virtio-ccw.c
@@ -17,6 +17,21 @@
 #include "css.h"
 #include "virtio-ccw.h"
 
+void io_subsystem_reset(void)
+{
+    DeviceState *css, *sclp;
+
+    css = DEVICE(object_resolve_path_type("", "virtual-css-bridge", NULL));
+    if (css) {
+        qdev_reset_all(css);
+    }
+    sclp = DEVICE(object_resolve_path_type("",
+                  "s390-sclp-event-facility", NULL));
+    if (sclp) {
+        qdev_reset_all(sclp);
+    }
+}
+
 static int virtio_ccw_hcall_notify(const uint64_t *args)
 {
     uint64_t subch_id = args[0];
diff --git a/target-s390x/cpu.h b/target-s390x/cpu.h
index 0878ab6..af9de5e 100644
--- a/target-s390x/cpu.h
+++ b/target-s390x/cpu.h
@@ -400,6 +400,7 @@ void cpu_unlock(void);
 typedef struct SubchDev SubchDev;
 
 #ifndef CONFIG_USER_ONLY
+extern void io_subsystem_reset(void);
 SubchDev *css_find_subch(uint8_t m, uint8_t cssid, uint8_t ssid,
                          uint16_t schid);
 bool css_subch_visible(SubchDev *sch);
commit 268846ba93de2529630d623b6ded72cee1221106
Author: Eugene (jno) Dvurechenski <jno at linux.vnet.ibm.com>
Date:   Wed Jun 19 17:27:15 2013 +0200

    s390/kvm: basic implementation of diagnose 308 subcode 6
    
    Linux uses a check for subcode 6 to decide if other subcodes are
    available. Provide a minimal implementation for subcode 6, as well
    as for subcode 5.
    
    Signed-off-by: Eugene (jno) Dvurechenski <jno at linux.vnet.ibm.com>
    Reviewed-by: Cornelia Huck <cornelia.huck at de.ibm.com>
    Signed-off-by: Christian Borntraeger <borntraeger at de.ibm.com>
    [Move code from kvm.c into misc_helper.c]

diff --git a/target-s390x/cpu.h b/target-s390x/cpu.h
index 65bef86..0878ab6 100644
--- a/target-s390x/cpu.h
+++ b/target-s390x/cpu.h
@@ -1047,6 +1047,9 @@ uint32_t set_cc_nz_f64(float64 v);
 uint32_t set_cc_nz_f128(float128 v);
 
 /* misc_helper.c */
+#ifndef CONFIG_USER_ONLY
+void handle_diag_308(CPUS390XState *env, uint64_t r1, uint64_t r3);
+#endif
 void program_interrupt(CPUS390XState *env, uint32_t code, int ilen);
 void QEMU_NORETURN runtime_exception(CPUS390XState *env, int excp,
                                      uintptr_t retaddr);
diff --git a/target-s390x/kvm.c b/target-s390x/kvm.c
index ed80154..c7fcdfa 100644
--- a/target-s390x/kvm.c
+++ b/target-s390x/kvm.c
@@ -72,6 +72,7 @@
 #define PRIV_XSCH                       0x76
 #define PRIV_SQBS                       0x8a
 #define PRIV_EQBS                       0x9c
+#define DIAG_IPL                        0x308
 #define DIAG_KVM_HYPERCALL              0x500
 #define DIAG_KVM_BREAKPOINT             0x501
 
@@ -578,11 +579,24 @@ static int handle_hypercall(S390CPU *cpu, struct kvm_run *run)
     return 0;
 }
 
+static void kvm_handle_diag_308(S390CPU *cpu, struct kvm_run *run)
+{
+    uint64_t r1, r3;
+
+    cpu_synchronize_state(CPU(cpu));
+    r1 = (run->s390_sieic.ipa & 0x00f0) >> 8;
+    r3 = run->s390_sieic.ipa & 0x000f;
+    handle_diag_308(&cpu->env, r1, r3);
+}
+
 static int handle_diag(S390CPU *cpu, struct kvm_run *run, int ipb_code)
 {
     int r = 0;
 
     switch (ipb_code) {
+    case DIAG_IPL:
+        kvm_handle_diag_308(cpu, run);
+        break;
     case DIAG_KVM_HYPERCALL:
         r = handle_hypercall(cpu, run);
         break;
diff --git a/target-s390x/misc_helper.c b/target-s390x/misc_helper.c
index 454960a..9b4423a 100644
--- a/target-s390x/misc_helper.c
+++ b/target-s390x/misc_helper.c
@@ -179,6 +179,46 @@ uint32_t HELPER(servc)(CPUS390XState *env, uint64_t r1, uint64_t r2)
     return r;
 }
 
+#ifndef CONFIG_USER_ONLY
+#define DIAG_308_RC_NO_CONF         0x0102
+#define DIAG_308_RC_INVALID         0x0402
+void handle_diag_308(CPUS390XState *env, uint64_t r1, uint64_t r3)
+{
+    uint64_t addr =  env->regs[r1];
+    uint64_t subcode = env->regs[r3];
+
+    if (env->psw.mask & PSW_MASK_PSTATE) {
+        program_interrupt(env, PGM_PRIVILEGED, ILEN_LATER_INC);
+        return;
+    }
+
+    if ((subcode & ~0x0ffffULL) || (subcode > 6)) {
+        program_interrupt(env, PGM_SPECIFICATION, ILEN_LATER_INC);
+        return;
+    }
+
+    switch (subcode) {
+    case 5:
+        if ((r1 & 1) || (addr & 0x0fffULL)) {
+            program_interrupt(env, PGM_SPECIFICATION, ILEN_LATER_INC);
+            return;
+        }
+        env->regs[r1+1] = DIAG_308_RC_INVALID;
+        return;
+    case 6:
+        if ((r1 & 1) || (addr & 0x0fffULL)) {
+            program_interrupt(env, PGM_SPECIFICATION, ILEN_LATER_INC);
+            return;
+        }
+        env->regs[r1+1] = DIAG_308_RC_NO_CONF;
+        return;
+    default:
+        hw_error("Unhandled diag308 subcode %" PRIx64, subcode);
+        break;
+    }
+}
+#endif
+
 /* DIAG */
 uint64_t HELPER(diag)(CPUS390XState *env, uint32_t num, uint64_t mem,
                       uint64_t code)
commit 39fbc5c62ce83f34e7f5b62238305d83ce8b4489
Author: Christian Borntraeger <borntraeger at de.ibm.com>
Date:   Fri Aug 30 11:06:56 2013 +0200

    s390x/kvm: Fix switch/case indentation for handle_diag
    
    This alignes case statements to switch statements in the handle_diag
    function as mandated by coding style.
    
    Signed-off-by: Christian Borntraeger <borntraeger at de.ibm.com>

diff --git a/target-s390x/kvm.c b/target-s390x/kvm.c
index 26d18e3..ed80154 100644
--- a/target-s390x/kvm.c
+++ b/target-s390x/kvm.c
@@ -583,16 +583,16 @@ static int handle_diag(S390CPU *cpu, struct kvm_run *run, int ipb_code)
     int r = 0;
 
     switch (ipb_code) {
-        case DIAG_KVM_HYPERCALL:
-            r = handle_hypercall(cpu, run);
-            break;
-        case DIAG_KVM_BREAKPOINT:
-            sleep(10);
-            break;
-        default:
-            DPRINTF("KVM: unknown DIAG: 0x%x\n", ipb_code);
-            r = -1;
-            break;
+    case DIAG_KVM_HYPERCALL:
+        r = handle_hypercall(cpu, run);
+        break;
+    case DIAG_KVM_BREAKPOINT:
+        sleep(10);
+        break;
+    default:
+        DPRINTF("KVM: unknown DIAG: 0x%x\n", ipb_code);
+        r = -1;
+        break;
     }
 
     return r;
commit b5d54bd42158b90b239bb6ce9c13072eb3a53fd2
Merge: e560992 821c808
Author: Anthony Liguori <anthony at codemonkey.ws>
Date:   Thu Aug 29 17:21:51 2013 -0500

    Merge remote-tracking branch 'qemu-kvm/uq/master' into stable-1.5
    
    * qemu-kvm/uq/master:
      kvm-stub: fix compilation
      kvm: shorten the parameter list for get_real_device()
      kvm: i386: fix LAPIC TSC deadline timer save/restore
      kvm-all.c: max_cpus should not exceed KVM vcpu limit
      kvm: Simplify kvm_handle_io
      kvm: x86: fix setting IA32_FEATURE_CONTROL with nested VMX disabled
      kvm: add KVM_IRQFD_FLAG_RESAMPLE support
      kvm: migrate vPMU state
      target-i386: remove tabs from target-i386/cpu.h
      Initialize IA32_FEATURE_CONTROL MSR in reset and migration
    
    Conflicts:
    	target-i386/cpu.h
    	target-i386/kvm.c
    
    aliguori: fixup trivial conflicts due to whitespace and added cpu
              argument
    
    Signed-off-by: Anthony Liguori <anthony at codemonkey.ws>

diff --cc target-i386/kvm.c
index 0b6eb01,58f7bb7..749aa09
--- a/target-i386/kvm.c
+++ b/target-i386/kvm.c
@@@ -1130,13 -1159,44 +1175,44 @@@ static int kvm_put_msrs(X86CPU *cpu, in
              kvm_msr_entry_set(&msrs[n++], MSR_KVM_STEAL_TIME,
                                env->steal_time_msr);
          }
+         if (has_msr_architectural_pmu) {
+             /* Stop the counter.  */
+             kvm_msr_entry_set(&msrs[n++], MSR_CORE_PERF_FIXED_CTR_CTRL, 0);
+             kvm_msr_entry_set(&msrs[n++], MSR_CORE_PERF_GLOBAL_CTRL, 0);
+ 
+             /* Set the counter values.  */
+             for (i = 0; i < MAX_FIXED_COUNTERS; i++) {
+                 kvm_msr_entry_set(&msrs[n++], MSR_CORE_PERF_FIXED_CTR0 + i,
+                                   env->msr_fixed_counters[i]);
+             }
+             for (i = 0; i < num_architectural_pmu_counters; i++) {
+                 kvm_msr_entry_set(&msrs[n++], MSR_P6_PERFCTR0 + i,
+                                   env->msr_gp_counters[i]);
+                 kvm_msr_entry_set(&msrs[n++], MSR_P6_EVNTSEL0 + i,
+                                   env->msr_gp_evtsel[i]);
+             }
+             kvm_msr_entry_set(&msrs[n++], MSR_CORE_PERF_GLOBAL_STATUS,
+                               env->msr_global_status);
+             kvm_msr_entry_set(&msrs[n++], MSR_CORE_PERF_GLOBAL_OVF_CTRL,
+                               env->msr_global_ovf_ctrl);
+ 
+             /* Now start the PMU.  */
+             kvm_msr_entry_set(&msrs[n++], MSR_CORE_PERF_FIXED_CTR_CTRL,
+                               env->msr_fixed_ctr_ctrl);
+             kvm_msr_entry_set(&msrs[n++], MSR_CORE_PERF_GLOBAL_CTRL,
+                               env->msr_global_ctrl);
+         }
 -        if (hyperv_hypercall_available()) {
 +        if (hyperv_hypercall_available(cpu)) {
              kvm_msr_entry_set(&msrs[n++], HV_X64_MSR_GUEST_OS_ID, 0);
              kvm_msr_entry_set(&msrs[n++], HV_X64_MSR_HYPERCALL, 0);
          }
 -        if (hyperv_vapic_recommended()) {
 +        if (cpu->hyperv_vapic) {
              kvm_msr_entry_set(&msrs[n++], HV_X64_MSR_APIC_ASSIST_PAGE, 0);
          }
+         if (has_msr_feature_control) {
+             kvm_msr_entry_set(&msrs[n++], MSR_IA32_FEATURE_CONTROL,
+                               env->msr_ia32_feature_control);
+         }
      }
      if (env->mcg_cap) {
          int i;
commit e560992f21437380857ae490c907810d99459df5
Merge: 3e998a7 92f1623
Author: Anthony Liguori <anthony at codemonkey.ws>
Date:   Thu Aug 29 17:20:17 2013 -0500

    Merge remote-tracking branch 'sweil/mingw' into stable-1.5
    
    # By Stefan Weil
    # Via Stefan Weil
    * sweil/mingw:
      gtk: Remove unused include statements which are not portable
      w32: Add an icon resource
      w32: Fix broken out-of-tree builds (missing version.o)
    
    Message-id: 1377607132-21336-1-git-send-email-sw at weilnetz.de
    Signed-off-by: Anthony Liguori <anthony at codemonkey.ws>

commit 3e998a778846de4ea24188278f18e4191a56412e
Merge: 584950f 1ae2757
Author: Anthony Liguori <anthony at codemonkey.ws>
Date:   Thu Aug 29 17:19:19 2013 -0500

    Merge remote-tracking branch 'mst/tags/for_anthony' into stable-1.5
    
    pc,pci,virtio fixes and cleanups
    
    This includes pc and pci cleanups, future-proofing of ROM files,
    and a virtio bugfix correcting splice on virtio console.
    
    Signed-off-by: Michael S. Tsirkin <mst at redhat.com>
    
    # gpg: Signature made Mon 26 Aug 2013 01:34:20 AM CDT using RSA key ID D28D5469
    # gpg: Can't check signature: public key not found
    
    # By Markus Armbruster (5) and others
    # Via Michael S. Tsirkin
    * mst/tags/for_anthony:
      virtio: virtqueue_get_avail_bytes: fix desc_pa when loop over the indirect descriptor table
      pc_piix: Kill pc_init1() memory region args
      pc: pc_compat_1_4() now can call pc_compat_1_5()
      pc: Create pc_compat_*() functions
      pc: Kill pc_init_pci_1_0()
      pc: Don't explode QEMUMachineInitArgs into local variables needlessly
      pc: Don't prematurely explode QEMUMachineInitArgs
      ppc: Don't duplicate QEMUMachineInitArgs in PPCE500Params
      ppc: Don't explode QEMUMachineInitArgs into local variables needlessly
      sun4: Don't prematurely explode QEMUMachineInitArgs
      q35: Add PCIe switch to example q35 configuration
      loader: store FW CFG ROM files in RAM
      arch_init: align MR size to target page size
      pc: cleanup 1.4 compat support
    
    Message-id: 1377535318-30491-1-git-send-email-mst at redhat.com

commit 584950fd4e4d6ca580800e46f1b41cf1b0b4236c
Author: Richard Henderson <rth at twiddle.net>
Date:   Thu Aug 29 08:21:37 2013 -0700

    tcg-i386: Remove abort from GETPC_LDST
    
    Indeed, remove it entirely and remove the is_tcg_gen_code check
    from GETPC_EXT.
    
    Fixes https://bugs.launchpad.net/qemu/+bug/1218098 wherein a call
    to a "normal" helper function performed a sequence of tail calls
    all the way into the memory helper functions, leading to a stack
    frame in which the memory helper function appeared to be called
    directly from tcg.
    
    Signed-off-by: Richard Henderson <rth at twiddle.net>

diff --git a/include/exec/exec-all.h b/include/exec/exec-all.h
index b70028a..ffb69a4 100644
--- a/include/exec/exec-all.h
+++ b/include/exec/exec-all.h
@@ -326,9 +326,7 @@ extern uintptr_t tci_tb_ptr;
    (6) jump to corresponding code of the next of fast path
  */
 # if defined(__i386__) || defined(__x86_64__)
-#  define GETRA() ((uintptr_t)__builtin_return_address(0))
-/* The return address argument for ldst is passed directly.  */
-#  define GETPC_LDST()  (abort(), 0)
+#  define GETPC_EXT()  GETPC()
 # elif defined (_ARCH_PPC) && !defined (_ARCH_PPC64)
 #  define GETRA() ((uintptr_t)__builtin_return_address(0))
 #  define GETPC_LDST() ((uintptr_t) ((*(int32_t *)(GETRA() - 4)) - 1))
@@ -349,7 +347,7 @@ static inline uintptr_t tcg_getpc_ldst(uintptr_t ra)
                                    not the start of the next opcode  */
     return ra;
 }
-#elif defined(__aarch64__)
+# elif defined(__aarch64__)
 #  define GETRA()       ((uintptr_t)__builtin_return_address(0))
 #  define GETPC_LDST()  tcg_getpc_ldst(GETRA())
 static inline uintptr_t tcg_getpc_ldst(uintptr_t ra)
@@ -367,7 +365,9 @@ static inline uintptr_t tcg_getpc_ldst(uintptr_t ra)
 #  error "CONFIG_QEMU_LDST_OPTIMIZATION needs GETPC_LDST() implementation!"
 # endif
 bool is_tcg_gen_code(uintptr_t pc_ptr);
-# define GETPC_EXT() (is_tcg_gen_code(GETRA()) ? GETPC_LDST() : GETPC())
+# ifndef GETPC_EXT
+#  define GETPC_EXT() (is_tcg_gen_code(GETRA()) ? GETPC_LDST() : GETPC())
+# endif
 #else
 # define GETPC_EXT() GETPC()
 #endif
commit 951fab990db05d47ab9da5e72521e406c73a3eb9
Author: James Hogan <james.hogan at imgtec.com>
Date:   Tue Aug 27 17:48:36 2013 +0100

    target-mips: fix get_physical_address() #if 0 build error
    
    In get_physical_address() is a qemu_log() call inside an #if 0 block.
    When enabled the following build error is hit:
    
    target-mips/helper.c In function ‘get_physical_address’:
    target-mips/helper.c:220:13: error: format ‘%x’ expects argument of type ‘unsigned int’, but argument 5 has type ‘hwaddr’ [-Werror=format]
    
    Fix the *physical (hwaddr) formatting by using "%"HWADDR_PRIx instead of
    TARGET_FMT_lx.
    
    Signed-off-by: James Hogan <james.hogan at imgtec.com>
    Cc: Aurelien Jarno <aurelien at aurel32.net>
    Signed-off-by: Yongbok Kim <yongbok.kim at imgtec.com>
    Signed-off-by: Aurelien Jarno <aurelien at aurel32.net>

diff --git a/target-mips/helper.c b/target-mips/helper.c
index 6feef7b..33e0e88 100644
--- a/target-mips/helper.c
+++ b/target-mips/helper.c
@@ -193,7 +193,7 @@ static int get_physical_address (CPUMIPSState *env, hwaddr *physical,
         }
     }
 #if 0
-    qemu_log(TARGET_FMT_lx " %d %d => " TARGET_FMT_lx " %d (%d)\n",
+    qemu_log(TARGET_FMT_lx " %d %d => %" HWADDR_PRIx " %d (%d)\n",
             address, rw, access_type, *physical, *prot, ret);
 #endif
 
commit 821c808bd1863efc2c1e977800ae77db633a185c
Author: Paolo Bonzini <pbonzini at redhat.com>
Date:   Tue Aug 27 17:13:44 2013 +0200

    kvm-stub: fix compilation
    
    Non-KVM targets fail compilation on the uq/master branch.
    Fix the prototype of kvm_irqchip_add_irqfd_notifier to match
    the one in kvm-all.c.
    
    Signed-off-by: Paolo Bonzini <pbonzini at redhat.com>
    Signed-off-by: Gleb Natapov <gleb at redhat.com>

diff --git a/kvm-stub.c b/kvm-stub.c
index 7b2233a..806b044 100644
--- a/kvm-stub.c
+++ b/kvm-stub.c
@@ -135,7 +135,8 @@ int kvm_irqchip_update_msi_route(KVMState *s, int virq, MSIMessage msg)
     return -ENOSYS;
 }
 
-int kvm_irqchip_add_irqfd_notifier(KVMState *s, EventNotifier *n, int virq)
+int kvm_irqchip_add_irqfd_notifier(KVMState *s, EventNotifier *n,
+                                   EventNotifier *rn, int virq)
 {
     return -ENOSYS;
 }
commit c16547326988cc321c9bff43ed91cbe753e52892
Author: Markus Armbruster <armbru at redhat.com>
Date:   Fri Aug 16 13:13:50 2013 +0200

    hw: Clean up bogus default boot order
    
    We set default boot order "cad" in every single machine definition
    except "pseries" and "moxiesim", even though very few boards actually
    care for boot order, and "cad" makes sense for even fewer.
    
    Machines that care:
    
    * pc and its variants
    
      Accept up to three letters 'a', 'b' (undocumented alias for 'a'),
      'c', 'd' and 'n'.  Reject all others (fatal with -boot).
    
    * nseries (n800, n810)
    
      Check whether order starts with 'n'.  Silently ignored otherwise.
    
    * prep, g3beige, mac99
    
      Extract the first character the machine understands (subset of
      'a'..'f').  Silently ignored otherwise.
    
    * spapr
    
      Accept an arbitrary string (vl.c restricts it to contain only
      'a'..'p', no duplicates).
    
    * sun4[mdc]
    
      Use the first character.  Silently ignored otherwise.
    
    Strip characters these machines ignore from their default boot order.
    
    For all other machines, remove the unused default boot order
    alltogether.
    
    Note that my rename of QEMUMachine member boot_order to
    default_boot_order and QEMUMachineInitArgs member boot_device to
    boot_order has a welcome side effect: it makes every use of boot
    orders visible in this patch, for easy review.
    
    Signed-off-by: Markus Armbruster <armbru at redhat.com>
    Reviewed-by: Laszlo Ersek <lersek at redhat.com>
    Signed-off-by: Michael S. Tsirkin <mst at redhat.com>

diff --git a/hw/alpha/dp264.c b/hw/alpha/dp264.c
index 95fde61..20795ac 100644
--- a/hw/alpha/dp264.c
+++ b/hw/alpha/dp264.c
@@ -173,7 +173,6 @@ static QEMUMachine clipper_machine = {
     .init = clipper_init,
     .max_cpus = 4,
     .is_default = 1,
-    DEFAULT_MACHINE_OPTIONS,
 };
 
 static void clipper_machine_init(void)
diff --git a/hw/arm/collie.c b/hw/arm/collie.c
index a19857a..8878b0e 100644
--- a/hw/arm/collie.c
+++ b/hw/arm/collie.c
@@ -62,7 +62,6 @@ static QEMUMachine collie_machine = {
     .name = "collie",
     .desc = "Collie PDA (SA-1110)",
     .init = collie_init,
-    DEFAULT_MACHINE_OPTIONS,
 };
 
 static void collie_machine_init(void)
diff --git a/hw/arm/exynos4_boards.c b/hw/arm/exynos4_boards.c
index 7c90b2d..2929f9f 100644
--- a/hw/arm/exynos4_boards.c
+++ b/hw/arm/exynos4_boards.c
@@ -150,14 +150,12 @@ static QEMUMachine exynos4_machines[EXYNOS4_NUM_OF_BOARDS] = {
         .desc = "Samsung NURI board (Exynos4210)",
         .init = nuri_init,
         .max_cpus = EXYNOS4210_NCPUS,
-        DEFAULT_MACHINE_OPTIONS,
     },
     [EXYNOS4_BOARD_SMDKC210] = {
         .name = "smdkc210",
         .desc = "Samsung SMDKC210 board (Exynos4210)",
         .init = smdkc210_init,
         .max_cpus = EXYNOS4210_NCPUS,
-        DEFAULT_MACHINE_OPTIONS,
     },
 };
 
diff --git a/hw/arm/gumstix.c b/hw/arm/gumstix.c
index b8cab10..e97fbbd 100644
--- a/hw/arm/gumstix.c
+++ b/hw/arm/gumstix.c
@@ -122,14 +122,12 @@ static QEMUMachine connex_machine = {
     .name = "connex",
     .desc = "Gumstix Connex (PXA255)",
     .init = connex_init,
-    DEFAULT_MACHINE_OPTIONS,
 };
 
 static QEMUMachine verdex_machine = {
     .name = "verdex",
     .desc = "Gumstix Verdex (PXA270)",
     .init = verdex_init,
-    DEFAULT_MACHINE_OPTIONS,
 };
 
 static void gumstix_machine_init(void)
diff --git a/hw/arm/highbank.c b/hw/arm/highbank.c
index f733a6c..fe98ef1 100644
--- a/hw/arm/highbank.c
+++ b/hw/arm/highbank.c
@@ -363,7 +363,6 @@ static QEMUMachine highbank_machine = {
     .init = highbank_init,
     .block_default_type = IF_SCSI,
     .max_cpus = 4,
-    DEFAULT_MACHINE_OPTIONS,
 };
 
 static QEMUMachine midway_machine = {
@@ -372,7 +371,6 @@ static QEMUMachine midway_machine = {
     .init = midway_init,
     .block_default_type = IF_SCSI,
     .max_cpus = 4,
-    DEFAULT_MACHINE_OPTIONS,
 };
 
 static void calxeda_machines_init(void)
diff --git a/hw/arm/integratorcp.c b/hw/arm/integratorcp.c
index 59c3726..2ef93ed 100644
--- a/hw/arm/integratorcp.c
+++ b/hw/arm/integratorcp.c
@@ -526,7 +526,6 @@ static QEMUMachine integratorcp_machine = {
     .desc = "ARM Integrator/CP (ARM926EJ-S)",
     .init = integratorcp_init,
     .is_default = 1,
-    DEFAULT_MACHINE_OPTIONS,
 };
 
 static void integratorcp_machine_init(void)
diff --git a/hw/arm/kzm.c b/hw/arm/kzm.c
index a248bf0..99d33cb 100644
--- a/hw/arm/kzm.c
+++ b/hw/arm/kzm.c
@@ -144,7 +144,6 @@ static QEMUMachine kzm_machine = {
     .name = "kzm",
     .desc = "ARM KZM Emulation Baseboard (ARM1136)",
     .init = kzm_init,
-    DEFAULT_MACHINE_OPTIONS,
 };
 
 static void kzm_machine_init(void)
diff --git a/hw/arm/mainstone.c b/hw/arm/mainstone.c
index 8e5fc26..b244f7e 100644
--- a/hw/arm/mainstone.c
+++ b/hw/arm/mainstone.c
@@ -179,7 +179,6 @@ static QEMUMachine mainstone2_machine = {
     .name = "mainstone",
     .desc = "Mainstone II (PXA27x)",
     .init = mainstone_init,
-    DEFAULT_MACHINE_OPTIONS,
 };
 
 static void mainstone_machine_init(void)
diff --git a/hw/arm/musicpal.c b/hw/arm/musicpal.c
index 4404b8d..023e875 100644
--- a/hw/arm/musicpal.c
+++ b/hw/arm/musicpal.c
@@ -1729,7 +1729,6 @@ static QEMUMachine musicpal_machine = {
     .name = "musicpal",
     .desc = "Marvell 88w8618 / MusicPal (ARM926EJ-S)",
     .init = musicpal_init,
-    DEFAULT_MACHINE_OPTIONS,
 };
 
 static void musicpal_machine_init(void)
diff --git a/hw/arm/nseries.c b/hw/arm/nseries.c
index f6c9dc0..9ef31ca 100644
--- a/hw/arm/nseries.c
+++ b/hw/arm/nseries.c
@@ -1340,7 +1340,7 @@ static void n8x0_init(QEMUMachineInitArgs *args,
     }
 
     if (option_rom[0].name &&
-        (args->boot_device[0] == 'n' || !args->kernel_filename)) {
+        (args->boot_order[0] == 'n' || !args->kernel_filename)) {
         uint8_t nolo_tags[0x10000];
         /* No, wait, better start at the ROM.  */
         s->mpu->cpu->env.regs[15] = OMAP2_Q2_BASE + 0x400000;
@@ -1396,14 +1396,14 @@ static QEMUMachine n800_machine = {
     .name = "n800",
     .desc = "Nokia N800 tablet aka. RX-34 (OMAP2420)",
     .init = n800_init,
-    DEFAULT_MACHINE_OPTIONS,
+    .default_boot_order = "",
 };
 
 static QEMUMachine n810_machine = {
     .name = "n810",
     .desc = "Nokia N810 tablet aka. RX-44 (OMAP2420)",
     .init = n810_init,
-    DEFAULT_MACHINE_OPTIONS,
+    .default_boot_order = "",
 };
 
 static void nseries_machine_init(void)
diff --git a/hw/arm/omap_sx1.c b/hw/arm/omap_sx1.c
index 05b0353..b0f8664 100644
--- a/hw/arm/omap_sx1.c
+++ b/hw/arm/omap_sx1.c
@@ -219,14 +219,12 @@ static QEMUMachine sx1_machine_v2 = {
     .name = "sx1",
     .desc = "Siemens SX1 (OMAP310) V2",
     .init = sx1_init_v2,
-    DEFAULT_MACHINE_OPTIONS,
 };
 
 static QEMUMachine sx1_machine_v1 = {
     .name = "sx1-v1",
     .desc = "Siemens SX1 (OMAP310) V1",
     .init = sx1_init_v1,
-    DEFAULT_MACHINE_OPTIONS,
 };
 
 static void sx1_machine_init(void)
diff --git a/hw/arm/palm.c b/hw/arm/palm.c
index cdc3c3a..3e39044 100644
--- a/hw/arm/palm.c
+++ b/hw/arm/palm.c
@@ -273,7 +273,6 @@ static QEMUMachine palmte_machine = {
     .name = "cheetah",
     .desc = "Palm Tungsten|E aka. Cheetah PDA (OMAP310)",
     .init = palmte_init,
-    DEFAULT_MACHINE_OPTIONS,
 };
 
 static void palmte_machine_init(void)
diff --git a/hw/arm/realview.c b/hw/arm/realview.c
index 82ec02d..8d845dd 100644
--- a/hw/arm/realview.c
+++ b/hw/arm/realview.c
@@ -369,7 +369,6 @@ static QEMUMachine realview_eb_machine = {
     .desc = "ARM RealView Emulation Baseboard (ARM926EJ-S)",
     .init = realview_eb_init,
     .block_default_type = IF_SCSI,
-    DEFAULT_MACHINE_OPTIONS,
 };
 
 static QEMUMachine realview_eb_mpcore_machine = {
@@ -378,14 +377,12 @@ static QEMUMachine realview_eb_mpcore_machine = {
     .init = realview_eb_mpcore_init,
     .block_default_type = IF_SCSI,
     .max_cpus = 4,
-    DEFAULT_MACHINE_OPTIONS,
 };
 
 static QEMUMachine realview_pb_a8_machine = {
     .name = "realview-pb-a8",
     .desc = "ARM RealView Platform Baseboard for Cortex-A8",
     .init = realview_pb_a8_init,
-    DEFAULT_MACHINE_OPTIONS,
 };
 
 static QEMUMachine realview_pbx_a9_machine = {
@@ -394,7 +391,6 @@ static QEMUMachine realview_pbx_a9_machine = {
     .init = realview_pbx_a9_init,
     .block_default_type = IF_SCSI,
     .max_cpus = 4,
-    DEFAULT_MACHINE_OPTIONS,
 };
 
 static void realview_machine_init(void)
diff --git a/hw/arm/spitz.c b/hw/arm/spitz.c
index 34f9582..a532cf6 100644
--- a/hw/arm/spitz.c
+++ b/hw/arm/spitz.c
@@ -966,28 +966,24 @@ static QEMUMachine akitapda_machine = {
     .name = "akita",
     .desc = "Akita PDA (PXA270)",
     .init = akita_init,
-    DEFAULT_MACHINE_OPTIONS,
 };
 
 static QEMUMachine spitzpda_machine = {
     .name = "spitz",
     .desc = "Spitz PDA (PXA270)",
     .init = spitz_init,
-    DEFAULT_MACHINE_OPTIONS,
 };
 
 static QEMUMachine borzoipda_machine = {
     .name = "borzoi",
     .desc = "Borzoi PDA (PXA270)",
     .init = borzoi_init,
-    DEFAULT_MACHINE_OPTIONS,
 };
 
 static QEMUMachine terrierpda_machine = {
     .name = "terrier",
     .desc = "Terrier PDA (PXA270)",
     .init = terrier_init,
-    DEFAULT_MACHINE_OPTIONS,
 };
 
 static void spitz_machine_init(void)
diff --git a/hw/arm/stellaris.c b/hw/arm/stellaris.c
index 79f6b4e..49be8fd 100644
--- a/hw/arm/stellaris.c
+++ b/hw/arm/stellaris.c
@@ -1348,14 +1348,12 @@ static QEMUMachine lm3s811evb_machine = {
     .name = "lm3s811evb",
     .desc = "Stellaris LM3S811EVB",
     .init = lm3s811evb_init,
-    DEFAULT_MACHINE_OPTIONS,
 };
 
 static QEMUMachine lm3s6965evb_machine = {
     .name = "lm3s6965evb",
     .desc = "Stellaris LM3S6965EVB",
     .init = lm3s6965evb_init,
-    DEFAULT_MACHINE_OPTIONS,
 };
 
 static void stellaris_machine_init(void)
diff --git a/hw/arm/tosa.c b/hw/arm/tosa.c
index 47d1f4f..c00d8c2 100644
--- a/hw/arm/tosa.c
+++ b/hw/arm/tosa.c
@@ -251,7 +251,6 @@ static QEMUMachine tosapda_machine = {
     .name = "tosa",
     .desc = "Tosa PDA (PXA255)",
     .init = tosa_init,
-    DEFAULT_MACHINE_OPTIONS,
 };
 
 static void tosapda_machine_init(void)
diff --git a/hw/arm/versatilepb.c b/hw/arm/versatilepb.c
index 4a6fcee..f7e8b7e 100644
--- a/hw/arm/versatilepb.c
+++ b/hw/arm/versatilepb.c
@@ -367,7 +367,6 @@ static QEMUMachine versatilepb_machine = {
     .desc = "ARM Versatile/PB (ARM926EJ-S)",
     .init = vpb_init,
     .block_default_type = IF_SCSI,
-    DEFAULT_MACHINE_OPTIONS,
 };
 
 static QEMUMachine versatileab_machine = {
@@ -375,7 +374,6 @@ static QEMUMachine versatileab_machine = {
     .desc = "ARM Versatile/AB (ARM926EJ-S)",
     .init = vab_init,
     .block_default_type = IF_SCSI,
-    DEFAULT_MACHINE_OPTIONS,
 };
 
 static void versatile_machine_init(void)
diff --git a/hw/arm/vexpress.c b/hw/arm/vexpress.c
index fbd71a7..f48de00 100644
--- a/hw/arm/vexpress.c
+++ b/hw/arm/vexpress.c
@@ -647,7 +647,6 @@ static QEMUMachine vexpress_a9_machine = {
     .init = vexpress_a9_init,
     .block_default_type = IF_SCSI,
     .max_cpus = 4,
-    DEFAULT_MACHINE_OPTIONS,
 };
 
 static QEMUMachine vexpress_a15_machine = {
@@ -656,7 +655,6 @@ static QEMUMachine vexpress_a15_machine = {
     .init = vexpress_a15_init,
     .block_default_type = IF_SCSI,
     .max_cpus = 4,
-    DEFAULT_MACHINE_OPTIONS,
 };
 
 static void vexpress_machine_init(void)
diff --git a/hw/arm/xilinx_zynq.c b/hw/arm/xilinx_zynq.c
index 0f18c85..46924a0 100644
--- a/hw/arm/xilinx_zynq.c
+++ b/hw/arm/xilinx_zynq.c
@@ -233,7 +233,6 @@ static QEMUMachine zynq_machine = {
     .block_default_type = IF_SCSI,
     .max_cpus = 1,
     .no_sdcard = 1,
-    DEFAULT_MACHINE_OPTIONS,
 };
 
 static void zynq_machine_init(void)
diff --git a/hw/arm/z2.c b/hw/arm/z2.c
index 07a127b..2e0d5d4 100644
--- a/hw/arm/z2.c
+++ b/hw/arm/z2.c
@@ -373,7 +373,6 @@ static QEMUMachine z2_machine = {
     .name = "z2",
     .desc = "Zipit Z2 (PXA27x)",
     .init = z2_init,
-    DEFAULT_MACHINE_OPTIONS,
 };
 
 static void z2_machine_init(void)
diff --git a/hw/core/null-machine.c b/hw/core/null-machine.c
index bdf109f..d813c08 100644
--- a/hw/core/null-machine.c
+++ b/hw/core/null-machine.c
@@ -24,7 +24,6 @@ static QEMUMachine machine_none = {
     .desc = "empty machine",
     .init = machine_none_init,
     .max_cpus = 0,
-    DEFAULT_MACHINE_OPTIONS,
 };
 
 static void register_machines(void)
diff --git a/hw/cris/axis_dev88.c b/hw/cris/axis_dev88.c
index 9104d61..03058d3 100644
--- a/hw/cris/axis_dev88.c
+++ b/hw/cris/axis_dev88.c
@@ -355,7 +355,6 @@ static QEMUMachine axisdev88_machine = {
     .desc = "AXIS devboard 88",
     .init = axisdev88_init,
     .is_default = 1,
-    DEFAULT_MACHINE_OPTIONS,
 };
 
 static void axisdev88_machine_init(void)
diff --git a/hw/i386/pc_piix.c b/hw/i386/pc_piix.c
index 3c36a2a..aa0a39a 100644
--- a/hw/i386/pc_piix.c
+++ b/hw/i386/pc_piix.c
@@ -204,7 +204,7 @@ static void pc_init1(QEMUMachineInitArgs *args,
         }
     }
 
-    pc_cmos_init(below_4g_mem_size, above_4g_mem_size, args->boot_device,
+    pc_cmos_init(below_4g_mem_size, above_4g_mem_size, args->boot_order,
                  floppy, idebus[0], idebus[1], rtc_state);
 
     if (pci_enabled && usb_enabled(false)) {
@@ -342,7 +342,7 @@ static QEMUMachine pc_i440fx_machine_v1_6 = {
     .hot_add_cpu = pc_hot_add_cpu,
     .max_cpus = 255,
     .is_default = 1,
-    DEFAULT_MACHINE_OPTIONS,
+    .default_boot_order = "cad",
 };
 
 static QEMUMachine pc_i440fx_machine_v1_5 = {
@@ -355,7 +355,7 @@ static QEMUMachine pc_i440fx_machine_v1_5 = {
         PC_COMPAT_1_5,
         { /* end of list */ }
     },
-    DEFAULT_MACHINE_OPTIONS,
+    .default_boot_order = "cad",
 };
 
 static QEMUMachine pc_i440fx_machine_v1_4 = {
@@ -363,11 +363,11 @@ static QEMUMachine pc_i440fx_machine_v1_4 = {
     .desc = "Standard PC (i440FX + PIIX, 1996)",
     .init = pc_init_pci_1_4,
     .max_cpus = 255,
+    .default_boot_order = "cad",
     .compat_props = (GlobalProperty[]) {
         PC_COMPAT_1_4,
         { /* end of list */ }
     },
-    DEFAULT_MACHINE_OPTIONS,
 };
 
 #define PC_COMPAT_1_3 \
@@ -395,11 +395,11 @@ static QEMUMachine pc_machine_v1_3 = {
     .desc = "Standard PC",
     .init = pc_init_pci_1_3,
     .max_cpus = 255,
+    .default_boot_order = "cad",
     .compat_props = (GlobalProperty[]) {
         PC_COMPAT_1_3,
         { /* end of list */ }
     },
-    DEFAULT_MACHINE_OPTIONS,
 };
 
 #define PC_COMPAT_1_2 \
@@ -435,11 +435,11 @@ static QEMUMachine pc_machine_v1_2 = {
     .desc = "Standard PC",
     .init = pc_init_pci_1_2,
     .max_cpus = 255,
+    .default_boot_order = "cad",
     .compat_props = (GlobalProperty[]) {
         PC_COMPAT_1_2,
         { /* end of list */ }
     },
-    DEFAULT_MACHINE_OPTIONS,
 };
 
 #define PC_COMPAT_1_1 \
@@ -479,11 +479,11 @@ static QEMUMachine pc_machine_v1_1 = {
     .desc = "Standard PC",
     .init = pc_init_pci_1_2,
     .max_cpus = 255,
+    .default_boot_order = "cad",
     .compat_props = (GlobalProperty[]) {
         PC_COMPAT_1_1,
         { /* end of list */ }
     },
-    DEFAULT_MACHINE_OPTIONS,
 };
 
 #define PC_COMPAT_1_0 \
@@ -511,12 +511,12 @@ static QEMUMachine pc_machine_v1_0 = {
     .desc = "Standard PC",
     .init = pc_init_pci_1_2,
     .max_cpus = 255,
+    .default_boot_order = "cad",
     .compat_props = (GlobalProperty[]) {
         PC_COMPAT_1_0,
         { /* end of list */ }
     },
     .hw_version = "1.0",
-    DEFAULT_MACHINE_OPTIONS,
 };
 
 #define PC_COMPAT_0_15 \
@@ -527,12 +527,12 @@ static QEMUMachine pc_machine_v0_15 = {
     .desc = "Standard PC",
     .init = pc_init_pci_1_2,
     .max_cpus = 255,
+    .default_boot_order = "cad",
     .compat_props = (GlobalProperty[]) {
         PC_COMPAT_0_15,
         { /* end of list */ }
     },
     .hw_version = "0.15",
-    DEFAULT_MACHINE_OPTIONS,
 };
 
 #define PC_COMPAT_0_14 \
@@ -560,6 +560,7 @@ static QEMUMachine pc_machine_v0_14 = {
     .desc = "Standard PC",
     .init = pc_init_pci_1_2,
     .max_cpus = 255,
+    .default_boot_order = "cad",
     .compat_props = (GlobalProperty[]) {
         PC_COMPAT_0_14, 
         {
@@ -574,7 +575,6 @@ static QEMUMachine pc_machine_v0_14 = {
         { /* end of list */ }
     },
     .hw_version = "0.14",
-    DEFAULT_MACHINE_OPTIONS,
 };
 
 #define PC_COMPAT_0_13 \
@@ -594,6 +594,7 @@ static QEMUMachine pc_machine_v0_13 = {
     .desc = "Standard PC",
     .init = pc_init_pci_no_kvmclock,
     .max_cpus = 255,
+    .default_boot_order = "cad",
     .compat_props = (GlobalProperty[]) {
         PC_COMPAT_0_13,
         {
@@ -612,7 +613,6 @@ static QEMUMachine pc_machine_v0_13 = {
         { /* end of list */ }
     },
     .hw_version = "0.13",
-    DEFAULT_MACHINE_OPTIONS,
 };
 
 #define PC_COMPAT_0_12 \
@@ -644,6 +644,7 @@ static QEMUMachine pc_machine_v0_12 = {
     .desc = "Standard PC",
     .init = pc_init_pci_no_kvmclock,
     .max_cpus = 255,
+    .default_boot_order = "cad",
     .compat_props = (GlobalProperty[]) {
         PC_COMPAT_0_12,
         {
@@ -658,7 +659,6 @@ static QEMUMachine pc_machine_v0_12 = {
         { /* end of list */ }
     },
     .hw_version = "0.12",
-    DEFAULT_MACHINE_OPTIONS,
 };
 
 #define PC_COMPAT_0_11 \
@@ -678,6 +678,7 @@ static QEMUMachine pc_machine_v0_11 = {
     .desc = "Standard PC, qemu 0.11",
     .init = pc_init_pci_no_kvmclock,
     .max_cpus = 255,
+    .default_boot_order = "cad",
     .compat_props = (GlobalProperty[]) {
         PC_COMPAT_0_11,
         {
@@ -692,7 +693,6 @@ static QEMUMachine pc_machine_v0_11 = {
         { /* end of list */ }
     },
     .hw_version = "0.11",
-    DEFAULT_MACHINE_OPTIONS,
 };
 
 static QEMUMachine pc_machine_v0_10 = {
@@ -700,6 +700,7 @@ static QEMUMachine pc_machine_v0_10 = {
     .desc = "Standard PC, qemu 0.10",
     .init = pc_init_pci_no_kvmclock,
     .max_cpus = 255,
+    .default_boot_order = "cad",
     .compat_props = (GlobalProperty[]) {
         PC_COMPAT_0_11,
         {
@@ -726,7 +727,6 @@ static QEMUMachine pc_machine_v0_10 = {
         { /* end of list */ }
     },
     .hw_version = "0.10",
-    DEFAULT_MACHINE_OPTIONS,
 };
 
 static QEMUMachine isapc_machine = {
@@ -734,10 +734,10 @@ static QEMUMachine isapc_machine = {
     .desc = "ISA-only PC",
     .init = pc_init_isa,
     .max_cpus = 1,
+    .default_boot_order = "cad",
     .compat_props = (GlobalProperty[]) {
         { /* end of list */ }
     },
-    DEFAULT_MACHINE_OPTIONS,
 };
 
 #ifdef CONFIG_XEN
@@ -747,7 +747,7 @@ static QEMUMachine xenfv_machine = {
     .init = pc_xen_hvm_init,
     .max_cpus = HVM_MAX_VCPUS,
     .default_machine_opts = "accel=xen",
-    DEFAULT_MACHINE_OPTIONS,
+    .default_boot_order = "cad",
 };
 #endif
 
diff --git a/hw/i386/pc_q35.c b/hw/i386/pc_q35.c
index 198c785..291ad97 100644
--- a/hw/i386/pc_q35.c
+++ b/hw/i386/pc_q35.c
@@ -200,7 +200,7 @@ static void pc_q35_init(QEMUMachineInitArgs *args)
                                     0xb100),
                       8, NULL, 0);
 
-    pc_cmos_init(below_4g_mem_size, above_4g_mem_size, args->boot_device,
+    pc_cmos_init(below_4g_mem_size, above_4g_mem_size, args->boot_order,
                  floppy, idebus[0], idebus[1], rtc_state);
 
     /* the rest devices to which pci devfn is automatically assigned */
@@ -260,7 +260,7 @@ static QEMUMachine pc_q35_machine_v1_6 = {
     .init = pc_q35_init_1_6,
     .hot_add_cpu = pc_hot_add_cpu,
     .max_cpus = 255,
-    DEFAULT_MACHINE_OPTIONS,
+    .default_boot_order = "cad",
 };
 
 static QEMUMachine pc_q35_machine_v1_5 = {
@@ -269,11 +269,11 @@ static QEMUMachine pc_q35_machine_v1_5 = {
     .init = pc_q35_init_1_5,
     .hot_add_cpu = pc_hot_add_cpu,
     .max_cpus = 255,
+    .default_boot_order = "cad",
     .compat_props = (GlobalProperty[]) {
         PC_COMPAT_1_5,
         { /* end of list */ }
     },
-    DEFAULT_MACHINE_OPTIONS,
 };
 
 static QEMUMachine pc_q35_machine_v1_4 = {
@@ -281,11 +281,11 @@ static QEMUMachine pc_q35_machine_v1_4 = {
     .desc = "Standard PC (Q35 + ICH9, 2009)",
     .init = pc_q35_init_1_4,
     .max_cpus = 255,
+    .default_boot_order = "cad",
     .compat_props = (GlobalProperty[]) {
         PC_COMPAT_1_4,
         { /* end of list */ }
     },
-    DEFAULT_MACHINE_OPTIONS,
 };
 
 static void pc_q35_machine_init(void)
diff --git a/hw/i386/xen_machine_pv.c b/hw/i386/xen_machine_pv.c
index 9f2e291..9adb57f 100644
--- a/hw/i386/xen_machine_pv.c
+++ b/hw/i386/xen_machine_pv.c
@@ -99,7 +99,6 @@ static QEMUMachine xenpv_machine = {
     .init = xen_init_pv,
     .max_cpus = 1,
     .default_machine_opts = "accel=xen",
-    DEFAULT_MACHINE_OPTIONS,
 };
 
 static void xenpv_machine_init(void)
diff --git a/hw/lm32/lm32_boards.c b/hw/lm32/lm32_boards.c
index 62003b8..c032bb8 100644
--- a/hw/lm32/lm32_boards.c
+++ b/hw/lm32/lm32_boards.c
@@ -289,7 +289,6 @@ static QEMUMachine lm32_evr_machine = {
     .desc = "LatticeMico32 EVR32 eval system",
     .init = lm32_evr_init,
     .is_default = 1,
-    DEFAULT_MACHINE_OPTIONS,
 };
 
 static QEMUMachine lm32_uclinux_machine = {
@@ -297,7 +296,6 @@ static QEMUMachine lm32_uclinux_machine = {
     .desc = "lm32 platform for uClinux and u-boot by Theobroma Systems",
     .init = lm32_uclinux_init,
     .is_default = 0,
-    DEFAULT_MACHINE_OPTIONS,
 };
 
 static void lm32_machine_init(void)
diff --git a/hw/lm32/milkymist.c b/hw/lm32/milkymist.c
index 7ceedb8..f1744ec 100644
--- a/hw/lm32/milkymist.c
+++ b/hw/lm32/milkymist.c
@@ -208,7 +208,6 @@ static QEMUMachine milkymist_machine = {
     .desc = "Milkymist One",
     .init = milkymist_init,
     .is_default = 0,
-    DEFAULT_MACHINE_OPTIONS,
 };
 
 static void milkymist_machine_init(void)
diff --git a/hw/m68k/an5206.c b/hw/m68k/an5206.c
index 0c03a87..a8eee44 100644
--- a/hw/m68k/an5206.c
+++ b/hw/m68k/an5206.c
@@ -89,7 +89,6 @@ static QEMUMachine an5206_machine = {
     .name = "an5206",
     .desc = "Arnewsh 5206",
     .init = an5206_init,
-    DEFAULT_MACHINE_OPTIONS,
 };
 
 static void an5206_machine_init(void)
diff --git a/hw/m68k/dummy_m68k.c b/hw/m68k/dummy_m68k.c
index f4ed7c6..86e2e6e 100644
--- a/hw/m68k/dummy_m68k.c
+++ b/hw/m68k/dummy_m68k.c
@@ -73,7 +73,6 @@ static QEMUMachine dummy_m68k_machine = {
     .name = "dummy",
     .desc = "Dummy board",
     .init = dummy_m68k_init,
-    DEFAULT_MACHINE_OPTIONS,
 };
 
 static void dummy_m68k_machine_init(void)
diff --git a/hw/m68k/mcf5208.c b/hw/m68k/mcf5208.c
index 9cf000f..fb96fe8 100644
--- a/hw/m68k/mcf5208.c
+++ b/hw/m68k/mcf5208.c
@@ -295,7 +295,6 @@ static QEMUMachine mcf5208evb_machine = {
     .desc = "MCF5206EVB",
     .init = mcf5208evb_init,
     .is_default = 1,
-    DEFAULT_MACHINE_OPTIONS,
 };
 
 static void mcf5208evb_machine_init(void)
diff --git a/hw/microblaze/petalogix_ml605_mmu.c b/hw/microblaze/petalogix_ml605_mmu.c
index 989da25..e003c7c 100644
--- a/hw/microblaze/petalogix_ml605_mmu.c
+++ b/hw/microblaze/petalogix_ml605_mmu.c
@@ -186,7 +186,6 @@ static QEMUMachine petalogix_ml605_machine = {
     .desc = "PetaLogix linux refdesign for xilinx ml605 little endian",
     .init = petalogix_ml605_init,
     .is_default = 0,
-    DEFAULT_MACHINE_OPTIONS,
 };
 
 static void petalogix_ml605_machine_init(void)
diff --git a/hw/microblaze/petalogix_s3adsp1800_mmu.c b/hw/microblaze/petalogix_s3adsp1800_mmu.c
index a461494..00af2b5 100644
--- a/hw/microblaze/petalogix_s3adsp1800_mmu.c
+++ b/hw/microblaze/petalogix_s3adsp1800_mmu.c
@@ -116,7 +116,6 @@ static QEMUMachine petalogix_s3adsp1800_machine = {
     .desc = "PetaLogix linux refdesign for xilinx Spartan 3ADSP1800",
     .init = petalogix_s3adsp1800_init,
     .is_default = 1,
-    DEFAULT_MACHINE_OPTIONS,
 };
 
 static void petalogix_s3adsp1800_machine_init(void)
diff --git a/hw/mips/mips_fulong2e.c b/hw/mips/mips_fulong2e.c
index e8d5dd0..9ef3a97 100644
--- a/hw/mips/mips_fulong2e.c
+++ b/hw/mips/mips_fulong2e.c
@@ -403,7 +403,6 @@ static QEMUMachine mips_fulong2e_machine = {
     .name = "fulong2e",
     .desc = "Fulong 2e mini pc",
     .init = mips_fulong2e_init,
-    DEFAULT_MACHINE_OPTIONS,
 };
 
 static void mips_fulong2e_machine_init(void)
diff --git a/hw/mips/mips_jazz.c b/hw/mips/mips_jazz.c
index d748ded..49bdd02 100644
--- a/hw/mips/mips_jazz.c
+++ b/hw/mips/mips_jazz.c
@@ -327,7 +327,6 @@ static QEMUMachine mips_magnum_machine = {
     .desc = "MIPS Magnum",
     .init = mips_magnum_init,
     .block_default_type = IF_SCSI,
-    DEFAULT_MACHINE_OPTIONS,
 };
 
 static QEMUMachine mips_pica61_machine = {
@@ -335,7 +334,6 @@ static QEMUMachine mips_pica61_machine = {
     .desc = "Acer Pica 61",
     .init = mips_pica61_init,
     .block_default_type = IF_SCSI,
-    DEFAULT_MACHINE_OPTIONS,
 };
 
 static void mips_jazz_machine_init(void)
diff --git a/hw/mips/mips_malta.c b/hw/mips/mips_malta.c
index f8d064c..ae0921c 100644
--- a/hw/mips/mips_malta.c
+++ b/hw/mips/mips_malta.c
@@ -1136,7 +1136,6 @@ static QEMUMachine mips_malta_machine = {
     .init = mips_malta_init,
     .max_cpus = 16,
     .is_default = 1,
-    DEFAULT_MACHINE_OPTIONS,
 };
 
 static void mips_malta_register_types(void)
diff --git a/hw/mips/mips_mipssim.c b/hw/mips/mips_mipssim.c
index 297f01e..242bab9 100644
--- a/hw/mips/mips_mipssim.c
+++ b/hw/mips/mips_mipssim.c
@@ -232,7 +232,6 @@ static QEMUMachine mips_mipssim_machine = {
     .name = "mipssim",
     .desc = "MIPS MIPSsim platform",
     .init = mips_mipssim_init,
-    DEFAULT_MACHINE_OPTIONS,
 };
 
 static void mips_mipssim_machine_init(void)
diff --git a/hw/mips/mips_r4k.c b/hw/mips/mips_r4k.c
index 044f232..e94b543 100644
--- a/hw/mips/mips_r4k.c
+++ b/hw/mips/mips_r4k.c
@@ -306,7 +306,6 @@ static QEMUMachine mips_machine = {
     .name = "mips",
     .desc = "mips r4k platform",
     .init = mips_r4k_init,
-    DEFAULT_MACHINE_OPTIONS,
 };
 
 static void mips_machine_init(void)
diff --git a/hw/openrisc/openrisc_sim.c b/hw/openrisc/openrisc_sim.c
index a08f27c..2a2d077 100644
--- a/hw/openrisc/openrisc_sim.c
+++ b/hw/openrisc/openrisc_sim.c
@@ -139,7 +139,6 @@ static QEMUMachine openrisc_sim_machine = {
     .init = openrisc_sim_init,
     .max_cpus = 1,
     .is_default = 1,
-    DEFAULT_MACHINE_OPTIONS,
 };
 
 static void openrisc_sim_machine_init(void)
diff --git a/hw/ppc/e500plat.c b/hw/ppc/e500plat.c
index bf65b69..2e964b2 100644
--- a/hw/ppc/e500plat.c
+++ b/hw/ppc/e500plat.c
@@ -51,7 +51,6 @@ static QEMUMachine e500plat_machine = {
     .desc = "generic paravirt e500 platform",
     .init = e500plat_init,
     .max_cpus = 32,
-    DEFAULT_MACHINE_OPTIONS,
 };
 
 static void e500plat_machine_init(void)
diff --git a/hw/ppc/mac_newworld.c b/hw/ppc/mac_newworld.c
index 7ef806e..5e79575 100644
--- a/hw/ppc/mac_newworld.c
+++ b/hw/ppc/mac_newworld.c
@@ -147,7 +147,7 @@ static void ppc_core99_init(QEMUMachineInitArgs *args)
     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;
+    const char *boot_device = args->boot_order;
     PowerPCCPU *cpu = NULL;
     CPUPPCState *env = NULL;
     char *filename;
@@ -477,7 +477,7 @@ static QEMUMachine core99_machine = {
     .desc = "Mac99 based PowerMAC",
     .init = ppc_core99_init,
     .max_cpus = MAX_CPUS,
-    DEFAULT_MACHINE_OPTIONS,
+    .default_boot_order = "cd",
 };
 
 static void core99_machine_init(void)
diff --git a/hw/ppc/mac_oldworld.c b/hw/ppc/mac_oldworld.c
index 42bb9d5..2f27754 100644
--- a/hw/ppc/mac_oldworld.c
+++ b/hw/ppc/mac_oldworld.c
@@ -78,7 +78,7 @@ static void ppc_heathrow_init(QEMUMachineInitArgs *args)
     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;
+    const char *boot_device = args->boot_order;
     MemoryRegion *sysmem = get_system_memory();
     PowerPCCPU *cpu = NULL;
     CPUPPCState *env = NULL;
@@ -350,7 +350,7 @@ static QEMUMachine heathrow_machine = {
 #ifndef TARGET_PPC64
     .is_default = 1,
 #endif
-    DEFAULT_MACHINE_OPTIONS,
+    .default_boot_order = "cd", /* TOFIX "cad" when Mac floppy is implemented */
 };
 
 static void heathrow_machine_init(void)
diff --git a/hw/ppc/mpc8544ds.c b/hw/ppc/mpc8544ds.c
index 1888e75..edcc0be 100644
--- a/hw/ppc/mpc8544ds.c
+++ b/hw/ppc/mpc8544ds.c
@@ -44,7 +44,6 @@ static QEMUMachine ppce500_machine = {
     .desc = "mpc8544ds",
     .init = mpc8544ds_init,
     .max_cpus = 15,
-    DEFAULT_MACHINE_OPTIONS,
 };
 
 static void ppce500_machine_init(void)
diff --git a/hw/ppc/ppc405_boards.c b/hw/ppc/ppc405_boards.c
index f74e5e5..43a83ca 100644
--- a/hw/ppc/ppc405_boards.c
+++ b/hw/ppc/ppc405_boards.c
@@ -362,7 +362,6 @@ static QEMUMachine ref405ep_machine = {
     .name = "ref405ep",
     .desc = "ref405ep",
     .init = ref405ep_init,
-    DEFAULT_MACHINE_OPTIONS,
 };
 
 /*****************************************************************************/
@@ -650,7 +649,6 @@ static QEMUMachine taihu_machine = {
     .name = "taihu",
     .desc = "taihu",
     .init = taihu_405ep_init,
-    DEFAULT_MACHINE_OPTIONS,
 };
 
 static void ppc405_machine_init(void)
diff --git a/hw/ppc/ppc440_bamboo.c b/hw/ppc/ppc440_bamboo.c
index 369ab9e..655e499 100644
--- a/hw/ppc/ppc440_bamboo.c
+++ b/hw/ppc/ppc440_bamboo.c
@@ -296,7 +296,6 @@ static QEMUMachine bamboo_machine = {
     .name = "bamboo",
     .desc = "bamboo",
     .init = bamboo_init,
-    DEFAULT_MACHINE_OPTIONS,
 };
 
 static void bamboo_machine_init(void)
diff --git a/hw/ppc/prep.c b/hw/ppc/prep.c
index 7e04b1a..aad0f69 100644
--- a/hw/ppc/prep.c
+++ b/hw/ppc/prep.c
@@ -452,7 +452,7 @@ static void ppc_prep_init(QEMUMachineInitArgs *args)
     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;
+    const char *boot_device = args->boot_order;
     MemoryRegion *sysmem = get_system_memory();
     PowerPCCPU *cpu = NULL;
     CPUPPCState *env = NULL;
@@ -691,7 +691,7 @@ static QEMUMachine prep_machine = {
     .desc = "PowerPC PREP platform",
     .init = ppc_prep_init,
     .max_cpus = MAX_CPUS,
-    DEFAULT_MACHINE_OPTIONS,
+    .default_boot_order = "cad",
 };
 
 static void prep_machine_init(void)
diff --git a/hw/ppc/spapr.c b/hw/ppc/spapr.c
index 16bfab9..3a2b381 100644
--- a/hw/ppc/spapr.c
+++ b/hw/ppc/spapr.c
@@ -1071,7 +1071,7 @@ static void ppc_spapr_init(QEMUMachineInitArgs *args)
     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;
+    const char *boot_device = args->boot_order;
     PowerPCCPU *cpu;
     CPUPPCState *env;
     PCIHostState *phb;
@@ -1325,7 +1325,7 @@ static QEMUMachine spapr_machine = {
     .block_default_type = IF_SCSI,
     .max_cpus = MAX_CPUS,
     .no_parallel = 1,
-    .boot_order = NULL,
+    .default_boot_order = NULL,
 };
 
 static void spapr_machine_init(void)
diff --git a/hw/ppc/virtex_ml507.c b/hw/ppc/virtex_ml507.c
index 08e77fb..7250f51 100644
--- a/hw/ppc/virtex_ml507.c
+++ b/hw/ppc/virtex_ml507.c
@@ -245,7 +245,6 @@ static QEMUMachine virtex_machine = {
     .name = "virtex-ml507",
     .desc = "Xilinx Virtex ML507 reference design",
     .init = virtex_init,
-    DEFAULT_MACHINE_OPTIONS,
 };
 
 static void virtex_machine_init(void)
diff --git a/hw/s390x/s390-virtio-ccw.c b/hw/s390x/s390-virtio-ccw.c
index aebbbf1..e2681a6 100644
--- a/hw/s390x/s390-virtio-ccw.c
+++ b/hw/s390x/s390-virtio-ccw.c
@@ -126,7 +126,6 @@ static QEMUMachine ccw_machine = {
     .no_sdcard = 1,
     .use_sclp = 1,
     .max_cpus = 255,
-    DEFAULT_MACHINE_OPTIONS,
 };
 
 static void ccw_machine_init(void)
diff --git a/hw/s390x/s390-virtio.c b/hw/s390x/s390-virtio.c
index 439d732..7adf92a 100644
--- a/hw/s390x/s390-virtio.c
+++ b/hw/s390x/s390-virtio.c
@@ -293,7 +293,6 @@ static QEMUMachine s390_machine = {
     .use_virtcon = 1,
     .max_cpus = 255,
     .is_default = 1,
-    DEFAULT_MACHINE_OPTIONS,
 };
 
 static void s390_machine_init(void)
diff --git a/hw/sh4/r2d.c b/hw/sh4/r2d.c
index 98b3408..7b1de85 100644
--- a/hw/sh4/r2d.c
+++ b/hw/sh4/r2d.c
@@ -356,7 +356,6 @@ static QEMUMachine r2d_machine = {
     .name = "r2d",
     .desc = "r2d-plus board",
     .init = r2d_init,
-    DEFAULT_MACHINE_OPTIONS,
 };
 
 static void r2d_machine_init(void)
diff --git a/hw/sh4/shix.c b/hw/sh4/shix.c
index 84dd666..1ff37f5 100644
--- a/hw/sh4/shix.c
+++ b/hw/sh4/shix.c
@@ -96,7 +96,6 @@ static QEMUMachine shix_machine = {
     .desc = "shix card",
     .init = shix_init,
     .is_default = 1,
-    DEFAULT_MACHINE_OPTIONS,
 };
 
 static void shix_machine_init(void)
diff --git a/hw/sparc/leon3.c b/hw/sparc/leon3.c
index 5ef282f..390f3e4 100644
--- a/hw/sparc/leon3.c
+++ b/hw/sparc/leon3.c
@@ -216,7 +216,6 @@ static QEMUMachine leon3_generic_machine = {
     .name     = "leon3_generic",
     .desc     = "Leon-3 generic",
     .init     = leon3_generic_hw_init,
-    DEFAULT_MACHINE_OPTIONS,
 };
 
 static void leon3_machine_init(void)
diff --git a/hw/sparc/sun4m.c b/hw/sparc/sun4m.c
index 36ef36f..a0d366c 100644
--- a/hw/sparc/sun4m.c
+++ b/hw/sparc/sun4m.c
@@ -996,7 +996,7 @@ static void sun4m_hw_init(const struct sun4m_hwdef *hwdef,
                                     args->ram_size);
 
     nvram_init(nvram, (uint8_t *)&nd_table[0].macaddr, args->kernel_cmdline,
-               args->boot_device, args->ram_size, kernel_size, graphic_width,
+               args->boot_order, args->ram_size, kernel_size, graphic_width,
                graphic_height, graphic_depth, hwdef->nvram_machine_id,
                "Sun4m");
 
@@ -1027,7 +1027,7 @@ static void sun4m_hw_init(const struct sun4m_hwdef *hwdef,
     }
     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, args->boot_device[0]);
+    fw_cfg_add_i16(fw_cfg, FW_CFG_BOOT_DEVICE, args->boot_order[0]);
     qemu_register_boot_set(fw_cfg_boot_set, fw_cfg);
 }
 
@@ -1348,7 +1348,7 @@ static QEMUMachine ss5_machine = {
     .init = ss5_init,
     .block_default_type = IF_SCSI,
     .is_default = 1,
-    DEFAULT_MACHINE_OPTIONS,
+    .default_boot_order = "c",
 };
 
 static QEMUMachine ss10_machine = {
@@ -1357,7 +1357,7 @@ static QEMUMachine ss10_machine = {
     .init = ss10_init,
     .block_default_type = IF_SCSI,
     .max_cpus = 4,
-    DEFAULT_MACHINE_OPTIONS,
+    .default_boot_order = "c",
 };
 
 static QEMUMachine ss600mp_machine = {
@@ -1366,7 +1366,7 @@ static QEMUMachine ss600mp_machine = {
     .init = ss600mp_init,
     .block_default_type = IF_SCSI,
     .max_cpus = 4,
-    DEFAULT_MACHINE_OPTIONS,
+    .default_boot_order = "c",
 };
 
 static QEMUMachine ss20_machine = {
@@ -1375,7 +1375,7 @@ static QEMUMachine ss20_machine = {
     .init = ss20_init,
     .block_default_type = IF_SCSI,
     .max_cpus = 4,
-    DEFAULT_MACHINE_OPTIONS,
+    .default_boot_order = "c",
 };
 
 static QEMUMachine voyager_machine = {
@@ -1383,7 +1383,7 @@ static QEMUMachine voyager_machine = {
     .desc = "Sun4m platform, SPARCstation Voyager",
     .init = vger_init,
     .block_default_type = IF_SCSI,
-    DEFAULT_MACHINE_OPTIONS,
+    .default_boot_order = "c",
 };
 
 static QEMUMachine ss_lx_machine = {
@@ -1391,7 +1391,7 @@ static QEMUMachine ss_lx_machine = {
     .desc = "Sun4m platform, SPARCstation LX",
     .init = ss_lx_init,
     .block_default_type = IF_SCSI,
-    DEFAULT_MACHINE_OPTIONS,
+    .default_boot_order = "c",
 };
 
 static QEMUMachine ss4_machine = {
@@ -1399,7 +1399,7 @@ static QEMUMachine ss4_machine = {
     .desc = "Sun4m platform, SPARCstation 4",
     .init = ss4_init,
     .block_default_type = IF_SCSI,
-    DEFAULT_MACHINE_OPTIONS,
+    .default_boot_order = "c",
 };
 
 static QEMUMachine scls_machine = {
@@ -1407,7 +1407,7 @@ static QEMUMachine scls_machine = {
     .desc = "Sun4m platform, SPARCClassic",
     .init = scls_init,
     .block_default_type = IF_SCSI,
-    DEFAULT_MACHINE_OPTIONS,
+    .default_boot_order = "c",
 };
 
 static QEMUMachine sbook_machine = {
@@ -1415,7 +1415,7 @@ static QEMUMachine sbook_machine = {
     .desc = "Sun4m platform, SPARCbook",
     .init = sbook_init,
     .block_default_type = IF_SCSI,
-    DEFAULT_MACHINE_OPTIONS,
+    .default_boot_order = "c",
 };
 
 static void sun4m_register_types(void)
diff --git a/hw/sparc64/sun4u.c b/hw/sparc64/sun4u.c
index 8bd7fb9..e7a4893 100644
--- a/hw/sparc64/sun4u.c
+++ b/hw/sparc64/sun4u.c
@@ -881,7 +881,7 @@ static void sun4uv_init(MemoryRegion *address_space_mem,
                                     &kernel_addr, &kernel_entry);
 
     sun4u_NVRAM_set_params(nvram, NVRAM_SIZE, "Sun4u", args->ram_size,
-                           args->boot_device,
+                           args->boot_order,
                            kernel_addr, kernel_size,
                            args->kernel_cmdline,
                            initrd_addr, initrd_size,
@@ -906,7 +906,7 @@ static void sun4uv_init(MemoryRegion *address_space_mem,
     }
     fw_cfg_add_i64(fw_cfg, FW_CFG_INITRD_ADDR, initrd_addr);
     fw_cfg_add_i64(fw_cfg, FW_CFG_INITRD_SIZE, initrd_size);
-    fw_cfg_add_i16(fw_cfg, FW_CFG_BOOT_DEVICE, args->boot_device[0]);
+    fw_cfg_add_i16(fw_cfg, FW_CFG_BOOT_DEVICE, args->boot_order[0]);
 
     fw_cfg_add_i16(fw_cfg, FW_CFG_SPARC64_WIDTH, graphic_width);
     fw_cfg_add_i16(fw_cfg, FW_CFG_SPARC64_HEIGHT, graphic_height);
@@ -969,7 +969,7 @@ static QEMUMachine sun4u_machine = {
     .init = sun4u_init,
     .max_cpus = 1, // XXX for now
     .is_default = 1,
-    DEFAULT_MACHINE_OPTIONS,
+    .default_boot_order = "c",
 };
 
 static QEMUMachine sun4v_machine = {
@@ -977,7 +977,7 @@ static QEMUMachine sun4v_machine = {
     .desc = "Sun4v platform",
     .init = sun4v_init,
     .max_cpus = 1, // XXX for now
-    DEFAULT_MACHINE_OPTIONS,
+    .default_boot_order = "c",
 };
 
 static QEMUMachine niagara_machine = {
@@ -985,7 +985,7 @@ static QEMUMachine niagara_machine = {
     .desc = "Sun4v platform, Niagara",
     .init = niagara_init,
     .max_cpus = 1, // XXX for now
-    DEFAULT_MACHINE_OPTIONS,
+    .default_boot_order = "c",
 };
 
 static void sun4u_register_types(void)
diff --git a/hw/unicore32/puv3.c b/hw/unicore32/puv3.c
index 5ff0dc9..a900061 100644
--- a/hw/unicore32/puv3.c
+++ b/hw/unicore32/puv3.c
@@ -128,7 +128,6 @@ static QEMUMachine puv3_machine = {
     .desc = "PKUnity Version-3 based on UniCore32",
     .init = puv3_init,
     .is_default = 1,
-    DEFAULT_MACHINE_OPTIONS,
 };
 
 static void puv3_machine_init(void)
diff --git a/hw/xtensa/xtensa_lx60.c b/hw/xtensa/xtensa_lx60.c
index 1138666..22e124d 100644
--- a/hw/xtensa/xtensa_lx60.c
+++ b/hw/xtensa/xtensa_lx60.c
@@ -297,7 +297,6 @@ static QEMUMachine xtensa_lx60_machine = {
     .desc = "lx60 EVB (" XTENSA_DEFAULT_CPU_MODEL ")",
     .init = xtensa_lx60_init,
     .max_cpus = 4,
-    DEFAULT_MACHINE_OPTIONS,
 };
 
 static QEMUMachine xtensa_lx200_machine = {
@@ -305,7 +304,6 @@ static QEMUMachine xtensa_lx200_machine = {
     .desc = "lx200 EVB (" XTENSA_DEFAULT_CPU_MODEL ")",
     .init = xtensa_lx200_init,
     .max_cpus = 4,
-    DEFAULT_MACHINE_OPTIONS,
 };
 
 static void xtensa_lx_machines_init(void)
diff --git a/hw/xtensa/xtensa_sim.c b/hw/xtensa/xtensa_sim.c
index ea91162..1192ce7 100644
--- a/hw/xtensa/xtensa_sim.c
+++ b/hw/xtensa/xtensa_sim.c
@@ -108,7 +108,6 @@ static QEMUMachine xtensa_sim_machine = {
     .is_default = true,
     .init = xtensa_sim_init,
     .max_cpus = 4,
-    DEFAULT_MACHINE_OPTIONS,
 };
 
 static void xtensa_sim_machine_init(void)
diff --git a/include/hw/boards.h b/include/hw/boards.h
index fb7c6f1..5a7ae9f 100644
--- a/include/hw/boards.h
+++ b/include/hw/boards.h
@@ -6,12 +6,9 @@
 #include "sysemu/blockdev.h"
 #include "hw/qdev.h"
 
-#define DEFAULT_MACHINE_OPTIONS \
-    .boot_order = "cad"
-
 typedef struct QEMUMachineInitArgs {
     ram_addr_t ram_size;
-    const char *boot_device;
+    const char *boot_order;
     const char *kernel_filename;
     const char *kernel_cmdline;
     const char *initrd_filename;
@@ -42,7 +39,7 @@ typedef struct QEMUMachine {
         no_sdcard:1;
     int is_default;
     const char *default_machine_opts;
-    const char *boot_order;
+    const char *default_boot_order;
     GlobalProperty *compat_props;
     struct QEMUMachine *next;
     const char *hw_version;
diff --git a/vl.c b/vl.c
index f422a1c..2624c0f 100644
--- a/vl.c
+++ b/vl.c
@@ -4121,7 +4121,7 @@ int main(int argc, char **argv, char **envp)
     kernel_cmdline = qemu_opt_get(machine_opts, "append");
 
     if (!boot_order) {
-        boot_order = machine->boot_order;
+        boot_order = machine->default_boot_order;
     }
     opts = qemu_opts_find(qemu_find_opts("boot-opts"), NULL);
     if (opts) {
@@ -4309,7 +4309,7 @@ int main(int argc, char **argv, char **envp)
     qdev_machine_init();
 
     QEMUMachineInitArgs args = { .ram_size = ram_size,
-                                 .boot_device = boot_order,
+                                 .boot_order = boot_order,
                                  .kernel_filename = kernel_filename,
                                  .kernel_cmdline = kernel_cmdline,
                                  .initrd_filename = initrd_filename,
commit 3bf4dfdd1110de84ca0cecff0679cf7da90bfbfe
Author: Alexey Kardashevskiy <aik at ozlabs.ru>
Date:   Wed Aug 21 14:42:06 2013 +1000

    pci: add config space access traces
    
    This adds pci_cfg_read and pci_cfg_write traces for config spaces
    accesses.
    
    Signed-off-by: Alexey Kardashevskiy <aik at ozlabs.ru>
    Signed-off-by: Michael S. Tsirkin <mst at redhat.com>

diff --git a/hw/pci/pci_host.c b/hw/pci/pci_host.c
index 7dd9b25..77c7d1f 100644
--- a/hw/pci/pci_host.c
+++ b/hw/pci/pci_host.c
@@ -20,6 +20,7 @@
 
 #include "hw/pci/pci.h"
 #include "hw/pci/pci_host.h"
+#include "trace.h"
 
 /* debug PCI */
 //#define DEBUG_PCI
@@ -51,14 +52,22 @@ void pci_host_config_write_common(PCIDevice *pci_dev, uint32_t addr,
                                   uint32_t limit, uint32_t val, uint32_t len)
 {
     assert(len <= 4);
+    trace_pci_cfg_write(pci_dev->name, PCI_SLOT(pci_dev->devfn),
+                        PCI_FUNC(pci_dev->devfn), addr, val);
     pci_dev->config_write(pci_dev, addr, val, MIN(len, limit - addr));
 }
 
 uint32_t pci_host_config_read_common(PCIDevice *pci_dev, uint32_t addr,
                                      uint32_t limit, uint32_t len)
 {
+    uint32_t ret;
+
     assert(len <= 4);
-    return pci_dev->config_read(pci_dev, addr, MIN(len, limit - addr));
+    ret = pci_dev->config_read(pci_dev, addr, MIN(len, limit - addr));
+    trace_pci_cfg_read(pci_dev->name, PCI_SLOT(pci_dev->devfn),
+                       PCI_FUNC(pci_dev->devfn), addr, ret);
+
+    return ret;
 }
 
 void pci_data_write(PCIBus *s, uint32_t addr, uint32_t val, int len)
diff --git a/trace-events b/trace-events
index 3856b5c..9d1d1df 100644
--- a/trace-events
+++ b/trace-events
@@ -1176,3 +1176,7 @@ object_class_dynamic_cast_assert(const char *type, const char *target, const cha
 # hw/xen/xen_pvdevice.c
 xen_pv_mmio_read(uint64_t addr) "WARNING: read from Xen PV Device MMIO space (address %"PRIx64")"
 xen_pv_mmio_write(uint64_t addr) "WARNING: write to Xen PV Device MMIO space (address %"PRIx64")"
+
+# hw/pci/pci_host.c
+pci_cfg_read(const char *dev, unsigned devid, unsigned fnid, unsigned offs, unsigned val) "%s %02u:%u @0x%x -> 0x%x"
+pci_cfg_write(const char *dev, unsigned devid, unsigned fnid, unsigned offs, unsigned val) "%s %02u:%u @0x%x <- 0x%x"
commit 92f1623663a8797e68a043ec401a740746439f29
Author: Stefan Weil <sw at weilnetz.de>
Date:   Sun Aug 18 09:26:34 2013 +0200

    gtk: Remove unused include statements which are not portable
    
    These include files don't exist for MinGW and are not needed for Linux
    (and hopefully for other hosts as well), so remove them.
    
    Signed-off-by: Stefan Weil <sw at weilnetz.de>

diff --git a/ui/gtk.c b/ui/gtk.c
index c38146f..b5f4f0b 100644
--- a/ui/gtk.c
+++ b/ui/gtk.c
@@ -51,10 +51,6 @@
 #include <glib/gi18n.h>
 #include <locale.h>
 #include <vte/vte.h>
-#include <sys/types.h>
-#include <sys/socket.h>
-#include <sys/un.h>
-#include <sys/wait.h>
 #include <math.h>
 
 #include "ui/console.h"
commit 487cddb2bf3f429953dc5b3252d2a3b83d7200c5
Author: Stefan Weil <sw at weilnetz.de>
Date:   Sat Aug 17 09:32:04 2013 +0200

    w32: Add an icon resource
    
    The QEMU mascot which was already used for the NSIS installer
    is now used for all QEMU executables.
    
    Signed-off-by: Stefan Weil <sw at weilnetz.de>

diff --git a/version.rc b/version.rc
index 82e10ec..a50d62f 100644
--- a/version.rc
+++ b/version.rc
@@ -26,3 +26,5 @@ FILESUBTYPE VFT2_UNKNOWN
     VALUE "Translation", 0x0409, 1252
   }
 }
+
+IDI_ICON1 ICON "pc-bios/qemu-nsis.ico"
commit 7e75e33e7886314490305f181065b8b4ec916a8a
Author: Stefan Weil <sw at weilnetz.de>
Date:   Fri Aug 16 21:51:53 2013 +0200

    w32: Fix broken out-of-tree builds (missing version.o)
    
    Commit 0b516ef0dfad9a7b34c675c98e8ec92ab4d38466 added version.o to all
    executables, but broke out-of-tree builds: for those builds the pattern
    rule %.o: %.rc from rules.mak does not match, so version.o was no longer
    built.
    
    Adding explicit build rules fixes this.
    
    Reported-by: Michael Roth <mdroth at linux.vnet.ibm.com>
    Signed-off-by: Stefan Weil <sw at weilnetz.de>
    Tested-by: Michael Roth <mdroth at linux.vnet.ibm.com>

diff --git a/Makefile b/Makefile
index 4d257f1..806946e 100644
--- a/Makefile
+++ b/Makefile
@@ -168,7 +168,9 @@ recurse-all: $(SUBDIR_RULES) $(ROMSUBDIR_RULES)
 bt-host.o: QEMU_CFLAGS += $(BLUEZ_CFLAGS)
 
 $(BUILD_DIR)/version.o: $(SRC_PATH)/version.rc $(BUILD_DIR)/config-host.h | $(BUILD_DIR)/version.lo
+	$(call quiet-command,$(WINDRES) -I$(BUILD_DIR) -o $@ $<,"  RC    version.o")
 $(BUILD_DIR)/version.lo: $(SRC_PATH)/version.rc $(BUILD_DIR)/config-host.h
+	$(call quiet-command,$(WINDRES) -I$(BUILD_DIR) -o $@ $<,"  RC    version.lo")
 
 Makefile: $(version-obj-y) $(version-lobj-y)
 
commit 1466cef32dd5e7ef3c6477e96d85d92302ad02e3
Author: Michael S. Tsirkin <mst at redhat.com>
Date:   Tue Aug 27 08:37:26 2013 +0300

    pc: fix regression for 64 bit PCI memory
    
    commit 398489018183d613306ab022653552247d93919f
        pc: limit 64 bit hole to 2G by default
    introduced a way for management to control
    the window allocated to the 64 bit PCI hole.
    
    This is useful, but existing management tools do not know how to set
    this property.  As a result, e.g. specifying a large ivshmem device with
    size > 4G is broken by default.  For example this configuration no
    longer works:
    
    -device ivshmem,size=4294967296,chardev=cfoo
    -chardev socket,path=/tmp/sock,id=cfoo,server,nowait
    
    Fix this by detecting that hole size was not specified
    and defaulting to the backwards-compatible value of 1 << 62.
    
    Cc: qemu-stable at nongnu.org
    Cc: Igor Mammedov <imammedo at redhat.com>
    Signed-off-by: Michael S. Tsirkin <mst at redhat.com>

diff --git a/hw/pci-host/piix.c b/hw/pci-host/piix.c
index dc1718f..221d82b 100644
--- a/hw/pci-host/piix.c
+++ b/hw/pci-host/piix.c
@@ -320,6 +320,7 @@ PCIBus *i440fx_init(PCII440FXState **pi440fx_state,
     PCII440FXState *f;
     unsigned i;
     I440FXState *i440fx;
+    uint64_t pci_hole64_size;
 
     dev = qdev_create(NULL, TYPE_I440FX_PCI_HOST_BRIDGE);
     s = PCI_HOST_BRIDGE(dev);
@@ -351,13 +352,15 @@ PCIBus *i440fx_init(PCII440FXState **pi440fx_state,
                              pci_hole_start, pci_hole_size);
     memory_region_add_subregion(f->system_memory, pci_hole_start, &f->pci_hole);
 
+    pci_hole64_size = pci_host_get_hole64_size(i440fx->pci_hole64_size);
+
     pc_init_pci64_hole(&i440fx->pci_info, 0x100000000ULL + above_4g_mem_size,
-                       i440fx->pci_hole64_size);
+                       pci_hole64_size);
     memory_region_init_alias(&f->pci_hole_64bit, OBJECT(d), "pci-hole64",
                              f->pci_address_space,
                              i440fx->pci_info.w64.begin,
-                             i440fx->pci_hole64_size);
-    if (i440fx->pci_hole64_size) {
+                             pci_hole64_size);
+    if (pci_hole64_size) {
         memory_region_add_subregion(f->system_memory,
                                     i440fx->pci_info.w64.begin,
                                     &f->pci_hole_64bit);
diff --git a/hw/pci-host/q35.c b/hw/pci-host/q35.c
index 12314d8..4febd24 100644
--- a/hw/pci-host/q35.c
+++ b/hw/pci-host/q35.c
@@ -320,6 +320,7 @@ static int mch_init(PCIDevice *d)
 {
     int i;
     MCHPCIState *mch = MCH_PCI_DEVICE(d);
+    uint64_t pci_hole64_size;
 
     /* setup pci memory regions */
     memory_region_init_alias(&mch->pci_hole, OBJECT(mch), "pci-hole",
@@ -329,13 +330,14 @@ static int mch_init(PCIDevice *d)
     memory_region_add_subregion(mch->system_memory, mch->below_4g_mem_size,
                                 &mch->pci_hole);
 
+    pci_hole64_size = pci_host_get_hole64_size(mch->pci_hole64_size);
     pc_init_pci64_hole(&mch->pci_info, 0x100000000ULL + mch->above_4g_mem_size,
-                       mch->pci_hole64_size);
+                       pci_hole64_size);
     memory_region_init_alias(&mch->pci_hole_64bit, OBJECT(mch), "pci-hole64",
                              mch->pci_address_space,
                              mch->pci_info.w64.begin,
-                             mch->pci_hole64_size);
-    if (mch->pci_hole64_size) {
+                             pci_hole64_size);
+    if (pci_hole64_size) {
         memory_region_add_subregion(mch->system_memory,
                                     mch->pci_info.w64.begin,
                                     &mch->pci_hole_64bit);
diff --git a/include/hw/i386/pc.h b/include/hw/i386/pc.h
index f79d478..475ba9e 100644
--- a/include/hw/i386/pc.h
+++ b/include/hw/i386/pc.h
@@ -106,7 +106,16 @@ PcGuestInfo *pc_guest_info_init(ram_addr_t below_4g_mem_size,
 #define PCI_HOST_PROP_PCI_HOLE64_START "pci-hole64-start"
 #define PCI_HOST_PROP_PCI_HOLE64_END   "pci-hole64-end"
 #define PCI_HOST_PROP_PCI_HOLE64_SIZE  "pci-hole64-size"
-#define DEFAULT_PCI_HOLE64_SIZE (1ULL << 31)
+#define DEFAULT_PCI_HOLE64_SIZE (~0x0ULL)
+
+static inline uint64_t pci_host_get_hole64_size(uint64_t pci_hole64_size)
+{
+    if (pci_hole64_size == DEFAULT_PCI_HOLE64_SIZE) {
+        return 1ULL << 62;
+    } else {
+        return pci_hole64_size;
+    }
+}
 
 void pc_init_pci64_hole(PcPciInfo *pci_info, uint64_t pci_hole64_start,
                         uint64_t pci_hole64_size);
commit 9eda7d373e9c691c070eddcbe3467b991f67f6bd
Author: Alexey Kardashevskiy <aik at ozlabs.ru>
Date:   Sat Aug 10 01:09:08 2013 +1000

    pci: Introduce helper to retrieve a PCI device's DMA address space
    
    A PCI device's DMA address space (possibly an IOMMU) is returned by a
    method on the PCIBus.  At the moment that only has one caller, so the
    method is simply open coded.  We'll need another caller for VFIO, so
    this patch introduces a helper/wrapper function.
    
    If IOMMU is not set, the pci_device_iommu_address_space() function
    returns the parent's IOMMU skipping the "bus master" address space as
    otherwise proper emulation would require more effort for no benefit.
    
    Signed-off-by: David Gibson <david at gibson.dropbear.id.au>
    [aik: added inheritance from parent if iommu is not set for the current bus]
    Signed-off-by: Alexey Kardashevskiy <aik at ozlabs.ru>
    Signed-off-by: Michael S. Tsirkin <mst at redhat.com>

diff --git a/hw/pci/pci.c b/hw/pci/pci.c
index 4c004f5..8c33352 100644
--- a/hw/pci/pci.c
+++ b/hw/pci/pci.c
@@ -812,12 +812,7 @@ static PCIDevice *do_pci_register_device(PCIDevice *pci_dev, PCIBus *bus,
     }
 
     pci_dev->bus = bus;
-    if (bus->iommu_fn) {
-        dma_as = bus->iommu_fn(bus, bus->iommu_opaque, devfn);
-    } else {
-        /* FIXME: inherit memory region from bus creator */
-        dma_as = &address_space_memory;
-    }
+    dma_as = pci_device_iommu_address_space(pci_dev);
 
     memory_region_init_alias(&pci_dev->bus_master_enable_region,
                              OBJECT(pci_dev), "bus master",
@@ -2239,6 +2234,23 @@ static void pci_device_class_init(ObjectClass *klass, void *data)
     k->props = pci_props;
 }
 
+AddressSpace *pci_device_iommu_address_space(PCIDevice *dev)
+{
+    PCIBus *bus = PCI_BUS(dev->bus);
+
+    if (bus->iommu_fn) {
+        return bus->iommu_fn(bus, bus->iommu_opaque, dev->devfn);
+    }
+
+    if (bus->parent_dev) {
+        /** We are ignoring the bus master DMA bit of the bridge
+         *  as it would complicate things such as VFIO for no good reason */
+        return pci_device_iommu_address_space(bus->parent_dev);
+    }
+
+    return &address_space_memory;
+}
+
 void pci_setup_iommu(PCIBus *bus, PCIIOMMUFunc fn, void *opaque)
 {
     bus->iommu_fn = fn;
diff --git a/include/hw/pci/pci.h b/include/hw/pci/pci.h
index ccec2ba..2374aa9 100644
--- a/include/hw/pci/pci.h
+++ b/include/hw/pci/pci.h
@@ -405,6 +405,7 @@ void pci_device_deassert_intx(PCIDevice *dev);
 
 typedef AddressSpace *(*PCIIOMMUFunc)(PCIBus *, void *, int);
 
+AddressSpace *pci_device_iommu_address_space(PCIDevice *dev);
 void pci_setup_iommu(PCIBus *bus, PCIIOMMUFunc fn, void *opaque);
 
 static inline void
commit 401c227b0a1134245ec61c6c5a9997cfc963c8e4
Author: Richard Henderson <rth at twiddle.net>
Date:   Thu Jul 25 07:16:52 2013 -1000

    tcg-i386: Use new return-argument ld/st helpers
    
    Discontinue the jump-around-jump-to-jump scheme, trading it for a single
    immediate move instruction.  The two extra jumps always consume 7 bytes,
    whereas the immediate move is either 5 or 7 bytes depending on where the
    code_gen_buffer gets located.
    
    Signed-off-by: Richard Henderson <rth at twiddle.net>

diff --git a/include/exec/exec-all.h b/include/exec/exec-all.h
index 5920f73..b70028a 100644
--- a/include/exec/exec-all.h
+++ b/include/exec/exec-all.h
@@ -326,18 +326,9 @@ extern uintptr_t tci_tb_ptr;
    (6) jump to corresponding code of the next of fast path
  */
 # if defined(__i386__) || defined(__x86_64__)
-/* To avoid broken disassembling, long jmp is used for embedding fast path pc,
-   so that the destination is the next code of fast path, though this jmp is
-   never executed.
-
-   call MMU helper
-   jmp POST_PROC (2byte)    <- GETRA()
-   jmp NEXT_CODE (5byte)
-   POST_PROCESS ...         <- GETRA() + 7
- */
 #  define GETRA() ((uintptr_t)__builtin_return_address(0))
-#  define GETPC_LDST() ((uintptr_t)(GETRA() + 7 + \
-                                    *(int32_t *)((void *)GETRA() + 3) - 1))
+/* The return address argument for ldst is passed directly.  */
+#  define GETPC_LDST()  (abort(), 0)
 # elif defined (_ARCH_PPC) && !defined (_ARCH_PPC64)
 #  define GETRA() ((uintptr_t)__builtin_return_address(0))
 #  define GETPC_LDST() ((uintptr_t) ((*(int32_t *)(GETRA() - 4)) - 1))
diff --git a/tcg/i386/tcg-target.c b/tcg/i386/tcg-target.c
index fba50f8..12a7ca3 100644
--- a/tcg/i386/tcg-target.c
+++ b/tcg/i386/tcg-target.c
@@ -190,11 +190,11 @@ static int target_parse_constraint(TCGArgConstraint *ct, const char **pct_str)
         /* qemu_ld/st address constraint */
     case 'L':
         ct->ct |= TCG_CT_REG;
-#if TCG_TARGET_REG_BITS == 64
+        if (TCG_TARGET_REG_BITS == 64) {
             tcg_regset_set32(ct->u.regs, 0, 0xffff);
-#else
+        } else {
             tcg_regset_set32(ct->u.regs, 0, 0xff);
-#endif
+        }
         tcg_regset_reset_reg(ct->u.regs, TCG_REG_L0);
         tcg_regset_reset_reg(ct->u.regs, TCG_REG_L1);
         break;
@@ -1025,22 +1025,24 @@ static void tcg_out_jmp(TCGContext *s, tcg_target_long dest)
 
 #include "exec/softmmu_defs.h"
 
-/* helper signature: helper_ld_mmu(CPUState *env, target_ulong addr,
-   int mmu_idx) */
-static const void *qemu_ld_helpers[4] = {
-    helper_ldb_mmu,
-    helper_ldw_mmu,
-    helper_ldl_mmu,
-    helper_ldq_mmu,
+/* helper signature: helper_ret_ld_mmu(CPUState *env, target_ulong addr,
+ *                                     int mmu_idx, uintptr_t ra)
+ */
+static const void * const qemu_ld_helpers[4] = {
+    helper_ret_ldb_mmu,
+    helper_ret_ldw_mmu,
+    helper_ret_ldl_mmu,
+    helper_ret_ldq_mmu,
 };
 
-/* helper signature: helper_st_mmu(CPUState *env, target_ulong addr,
-   uintxx_t val, int mmu_idx) */
-static const void *qemu_st_helpers[4] = {
-    helper_stb_mmu,
-    helper_stw_mmu,
-    helper_stl_mmu,
-    helper_stq_mmu,
+/* helper signature: helper_ret_st_mmu(CPUState *env, target_ulong addr,
+ *                                     uintxx_t val, int mmu_idx, uintptr_t ra)
+ */
+static const void * const qemu_st_helpers[4] = {
+    helper_ret_stb_mmu,
+    helper_ret_stw_mmu,
+    helper_ret_stl_mmu,
+    helper_ret_stq_mmu,
 };
 
 static void add_qemu_ldst_label(TCGContext *s,
@@ -1468,6 +1470,12 @@ static void add_qemu_ldst_label(TCGContext *s,
     }
 }
 
+/* See the GETPC definition in include/exec/exec-all.h.  */
+static inline uintptr_t do_getpc(uint8_t *raddr)
+{
+    return (uintptr_t)raddr - 1;
+}
+
 /*
  * Generate code for the slow path for a load at the end of block
  */
@@ -1499,33 +1507,20 @@ static void tcg_out_qemu_ld_slow_path(TCGContext *s, TCGLabelQemuLdst *l)
         }
 
         tcg_out_sti(s, TCG_TYPE_I32, TCG_REG_ESP, ofs, l->mem_index);
+        ofs += 4;
+
+        tcg_out_sti(s, TCG_TYPE_I32, TCG_REG_ESP, ofs, do_getpc(l->raddr));
     } else {
-        tcg_out_mov(s, TCG_TYPE_I64, tcg_target_call_iarg_regs[0], TCG_AREG0);
+        tcg_out_mov(s, TCG_TYPE_PTR, tcg_target_call_iarg_regs[0], TCG_AREG0);
         /* The second argument is already loaded with addrlo.  */
         tcg_out_movi(s, TCG_TYPE_I32, tcg_target_call_iarg_regs[2],
                      l->mem_index);
+        tcg_out_movi(s, TCG_TYPE_PTR, tcg_target_call_iarg_regs[3],
+                     do_getpc(l->raddr));
     }
 
-    /* Code generation of qemu_ld/st's slow path calling MMU helper
-
-       PRE_PROC ...
-       call MMU helper
-       jmp POST_PROC (2b) : short forward jump <- GETRA()
-       jmp next_code (5b) : dummy long backward jump which is never executed
-       POST_PROC ... : do post-processing <- GETRA() + 7
-       jmp next_code : jump to the code corresponding to next IR of qemu_ld/st
-    */
-
     tcg_out_calli(s, (tcg_target_long)qemu_ld_helpers[s_bits]);
 
-    /* Jump to post-processing code */
-    tcg_out8(s, OPC_JMP_short);
-    tcg_out8(s, 5);
-    /* Dummy backward jump having information of fast path'pc for MMU helpers */
-    tcg_out8(s, OPC_JMP_long);
-    *(int32_t *)s->code_ptr = (int32_t)(l->raddr - s->code_ptr - 4);
-    s->code_ptr += 4;
-
     data_reg = l->datalo_reg;
     switch(opc) {
     case 0 | 4:
@@ -1606,36 +1601,32 @@ static void tcg_out_qemu_st_slow_path(TCGContext *s, TCGLabelQemuLdst *l)
         }
 
         tcg_out_sti(s, TCG_TYPE_I32, TCG_REG_ESP, ofs, l->mem_index);
+        ofs += 4;
+
+        tcg_out_sti(s, TCG_TYPE_I32, TCG_REG_ESP, ofs, do_getpc(l->raddr));
     } else {
-        tcg_out_mov(s, TCG_TYPE_I64, tcg_target_call_iarg_regs[0], TCG_AREG0);
+        uintptr_t pc;
+
+        tcg_out_mov(s, TCG_TYPE_PTR, tcg_target_call_iarg_regs[0], TCG_AREG0);
         /* The second argument is already loaded with addrlo.  */
         tcg_out_mov(s, (opc == 3 ? TCG_TYPE_I64 : TCG_TYPE_I32),
                     tcg_target_call_iarg_regs[2], l->datalo_reg);
         tcg_out_movi(s, TCG_TYPE_I32, tcg_target_call_iarg_regs[3],
                      l->mem_index);
-    }
 
-    /* Code generation of qemu_ld/st's slow path calling MMU helper
-
-       PRE_PROC ...
-       call MMU helper
-       jmp POST_PROC (2b) : short forward jump <- GETRA()
-       jmp next_code (5b) : dummy long backward jump which is never executed
-       POST_PROC ... : do post-processing <- GETRA() + 7
-       jmp next_code : jump to the code corresponding to next IR of qemu_ld/st
-    */
+        pc = do_getpc(l->raddr);
+        if (ARRAY_SIZE(tcg_target_call_iarg_regs) > 4) {
+            tcg_out_movi(s, TCG_TYPE_PTR, tcg_target_call_iarg_regs[4], pc);
+        } else if (pc == (int32_t)pc) {
+            tcg_out_sti(s, TCG_TYPE_PTR, TCG_REG_ESP, 0, pc);
+        } else {
+            tcg_out_movi(s, TCG_TYPE_PTR, TCG_REG_RAX, pc);
+            tcg_out_st(s, TCG_TYPE_PTR, TCG_REG_RAX, TCG_REG_ESP, 0);
+        }
+    }
 
     tcg_out_calli(s, (tcg_target_long)qemu_st_helpers[s_bits]);
 
-    /* Jump to post-processing code */
-    tcg_out8(s, OPC_JMP_short);
-    tcg_out8(s, 5);
-    /* Dummy backward jump having information of fast path'pc for MMU helpers */
-    tcg_out8(s, OPC_JMP_long);
-    *(int32_t *)s->code_ptr = (int32_t)(l->raddr - s->code_ptr - 4);
-    s->code_ptr += 4;
-
-    /* Jump to the code corresponding to next IR of qemu_st */
     tcg_out_jmp(s, (tcg_target_long)l->raddr);
 }
 
commit aac1fb0576e5bea72681e91c38caffc17741eb80
Author: Richard Henderson <rth at twiddle.net>
Date:   Fri Jul 26 08:29:15 2013 -1000

    tcg: Tidy softmmu_template.h
    
    Avoid a loop in the tlb_fill path; the fill will either succeed or
    generate an exception.
    
    Inline the slow_ld/st function; it was a complete copy of the main
    helper except for the actual cross-page unaligned code, and the
    compiler was inlining it anyway.
    
    Add unlikely markers optimizing for the most common case of simple
    tlb miss.
    
    Make sure the compiler can optimize away the unaligned paths for a
    1 byte access.
    
    Reviewed-by: Aurelien Jarno <aurelien at aurel32.net>
    Signed-off-by: Richard Henderson <rth at twiddle.net>

diff --git a/include/exec/softmmu_template.h b/include/exec/softmmu_template.h
index 7d8bcb5..eaca9e1 100644
--- a/include/exec/softmmu_template.h
+++ b/include/exec/softmmu_template.h
@@ -54,10 +54,6 @@
 #define ADDR_READ addr_read
 #endif
 
-static DATA_TYPE glue(glue(slow_ld, SUFFIX), MMUSUFFIX)(CPUArchState *env,
-                                                        target_ulong addr,
-                                                        int mmu_idx,
-                                                        uintptr_t retaddr);
 static inline DATA_TYPE glue(io_read, SUFFIX)(CPUArchState *env,
                                               hwaddr physaddr,
                                               target_ulong addr,
@@ -86,52 +82,67 @@ glue(glue(helper_ret_ld, SUFFIX), MMUSUFFIX)(CPUArchState *env,
                                              target_ulong addr, int mmu_idx,
                                              uintptr_t retaddr)
 {
-    DATA_TYPE res;
-    int index;
-    target_ulong tlb_addr;
-    hwaddr ioaddr;
+    int index = (addr >> TARGET_PAGE_BITS) & (CPU_TLB_SIZE - 1);
+    target_ulong tlb_addr = env->tlb_table[mmu_idx][index].ADDR_READ;
+    uintptr_t haddr;
 
-    /* test if there is match for unaligned or IO access */
-    /* XXX: could done more in memory macro in a non portable way */
-    index = (addr >> TARGET_PAGE_BITS) & (CPU_TLB_SIZE - 1);
- redo:
-    tlb_addr = env->tlb_table[mmu_idx][index].ADDR_READ;
-    if ((addr & TARGET_PAGE_MASK) == (tlb_addr & (TARGET_PAGE_MASK | TLB_INVALID_MASK))) {
-        if (tlb_addr & ~TARGET_PAGE_MASK) {
-            /* IO access */
-            if ((addr & (DATA_SIZE - 1)) != 0)
-                goto do_unaligned_access;
-            ioaddr = env->iotlb[mmu_idx][index];
-            res = glue(io_read, SUFFIX)(env, ioaddr, addr, retaddr);
-        } else if (((addr & ~TARGET_PAGE_MASK) + DATA_SIZE - 1) >= TARGET_PAGE_SIZE) {
-            /* slow unaligned access (it spans two pages or IO) */
-        do_unaligned_access:
+    /* If the TLB entry is for a different page, reload and try again.  */
+    if ((addr & TARGET_PAGE_MASK)
+         != (tlb_addr & (TARGET_PAGE_MASK | TLB_INVALID_MASK))) {
 #ifdef ALIGNED_ONLY
+        if ((addr & (DATA_SIZE - 1)) != 0) {
             do_unaligned_access(env, addr, READ_ACCESS_TYPE, mmu_idx, retaddr);
+        }
 #endif
-            res = glue(glue(slow_ld, SUFFIX), MMUSUFFIX)(env, addr,
-                                                         mmu_idx, retaddr);
-        } else {
-            /* unaligned/aligned access in the same page */
-            uintptr_t addend;
-#ifdef ALIGNED_ONLY
-            if ((addr & (DATA_SIZE - 1)) != 0) {
-                do_unaligned_access(env, addr, READ_ACCESS_TYPE, mmu_idx, retaddr);
-            }
-#endif
-            addend = env->tlb_table[mmu_idx][index].addend;
-            res = glue(glue(ld, USUFFIX), _raw)((uint8_t *)(intptr_t)
-                                                (addr + addend));
+        tlb_fill(env, addr, READ_ACCESS_TYPE, mmu_idx, retaddr);
+        tlb_addr = env->tlb_table[mmu_idx][index].ADDR_READ;
+    }
+
+    /* Handle an IO access.  */
+    if (unlikely(tlb_addr & ~TARGET_PAGE_MASK)) {
+        hwaddr ioaddr;
+        if ((addr & (DATA_SIZE - 1)) != 0) {
+            goto do_unaligned_access;
         }
-    } else {
+        ioaddr = env->iotlb[mmu_idx][index];
+        return glue(io_read, SUFFIX)(env, ioaddr, addr, retaddr);
+    }
+
+    /* Handle slow unaligned access (it spans two pages or IO).  */
+    if (DATA_SIZE > 1
+        && unlikely((addr & ~TARGET_PAGE_MASK) + DATA_SIZE - 1
+                    >= TARGET_PAGE_SIZE)) {
+        target_ulong addr1, addr2;
+        DATA_TYPE res1, res2, res;
+        unsigned shift;
+    do_unaligned_access:
 #ifdef ALIGNED_ONLY
-        if ((addr & (DATA_SIZE - 1)) != 0)
-            do_unaligned_access(env, addr, READ_ACCESS_TYPE, mmu_idx, retaddr);
+        do_unaligned_access(env, addr, READ_ACCESS_TYPE, mmu_idx, retaddr);
 #endif
-        tlb_fill(env, addr, READ_ACCESS_TYPE, mmu_idx, retaddr);
-        goto redo;
+        addr1 = addr & ~(DATA_SIZE - 1);
+        addr2 = addr1 + DATA_SIZE;
+        res1 = glue(glue(helper_ret_ld, SUFFIX), MMUSUFFIX)(env, addr1,
+                                                            mmu_idx, retaddr);
+        res2 = glue(glue(helper_ret_ld, SUFFIX), MMUSUFFIX)(env, addr2,
+                                                            mmu_idx, retaddr);
+        shift = (addr & (DATA_SIZE - 1)) * 8;
+#ifdef TARGET_WORDS_BIGENDIAN
+        res = (res1 << shift) | (res2 >> ((DATA_SIZE * 8) - shift));
+#else
+        res = (res1 >> shift) | (res2 << ((DATA_SIZE * 8) - shift));
+#endif
+        return res;
+    }
+
+    /* Handle aligned access or unaligned access in the same page.  */
+#ifdef ALIGNED_ONLY
+    if ((addr & (DATA_SIZE - 1)) != 0) {
+        do_unaligned_access(env, addr, READ_ACCESS_TYPE, mmu_idx, retaddr);
     }
-    return res;
+#endif
+
+    haddr = addr + env->tlb_table[mmu_idx][index].addend;
+    return glue(glue(ld, USUFFIX), _raw)((uint8_t *)haddr);
 }
 
 DATA_TYPE
@@ -142,66 +153,8 @@ glue(glue(helper_ld, SUFFIX), MMUSUFFIX)(CPUArchState *env, target_ulong addr,
                                                         GETPC_EXT());
 }
 
-/* handle all unaligned cases */
-static DATA_TYPE
-glue(glue(slow_ld, SUFFIX), MMUSUFFIX)(CPUArchState *env,
-                                       target_ulong addr,
-                                       int mmu_idx,
-                                       uintptr_t retaddr)
-{
-    DATA_TYPE res, res1, res2;
-    int index, shift;
-    hwaddr ioaddr;
-    target_ulong tlb_addr, addr1, addr2;
-
-    index = (addr >> TARGET_PAGE_BITS) & (CPU_TLB_SIZE - 1);
- redo:
-    tlb_addr = env->tlb_table[mmu_idx][index].ADDR_READ;
-    if ((addr & TARGET_PAGE_MASK) == (tlb_addr & (TARGET_PAGE_MASK | TLB_INVALID_MASK))) {
-        if (tlb_addr & ~TARGET_PAGE_MASK) {
-            /* IO access */
-            if ((addr & (DATA_SIZE - 1)) != 0)
-                goto do_unaligned_access;
-            ioaddr = env->iotlb[mmu_idx][index];
-            res = glue(io_read, SUFFIX)(env, ioaddr, addr, retaddr);
-        } else if (((addr & ~TARGET_PAGE_MASK) + DATA_SIZE - 1) >= TARGET_PAGE_SIZE) {
-        do_unaligned_access:
-            /* slow unaligned access (it spans two pages) */
-            addr1 = addr & ~(DATA_SIZE - 1);
-            addr2 = addr1 + DATA_SIZE;
-            res1 = glue(glue(slow_ld, SUFFIX), MMUSUFFIX)(env, addr1,
-                                                          mmu_idx, retaddr);
-            res2 = glue(glue(slow_ld, SUFFIX), MMUSUFFIX)(env, addr2,
-                                                          mmu_idx, retaddr);
-            shift = (addr & (DATA_SIZE - 1)) * 8;
-#ifdef TARGET_WORDS_BIGENDIAN
-            res = (res1 << shift) | (res2 >> ((DATA_SIZE * 8) - shift));
-#else
-            res = (res1 >> shift) | (res2 << ((DATA_SIZE * 8) - shift));
-#endif
-            res = (DATA_TYPE)res;
-        } else {
-            /* unaligned/aligned access in the same page */
-            uintptr_t addend = env->tlb_table[mmu_idx][index].addend;
-            res = glue(glue(ld, USUFFIX), _raw)((uint8_t *)(intptr_t)
-                                                (addr + addend));
-        }
-    } else {
-        /* the page is not in the TLB : fill it */
-        tlb_fill(env, addr, READ_ACCESS_TYPE, mmu_idx, retaddr);
-        goto redo;
-    }
-    return res;
-}
-
 #ifndef SOFTMMU_CODE_ACCESS
 
-static void glue(glue(slow_st, SUFFIX), MMUSUFFIX)(CPUArchState *env,
-                                                   target_ulong addr,
-                                                   DATA_TYPE val,
-                                                   int mmu_idx,
-                                                   uintptr_t retaddr);
-
 static inline void glue(io_write, SUFFIX)(CPUArchState *env,
                                           hwaddr physaddr,
                                           DATA_TYPE val,
@@ -225,48 +178,66 @@ glue(glue(helper_ret_st, SUFFIX), MMUSUFFIX)(CPUArchState *env,
                                              target_ulong addr, DATA_TYPE val,
                                              int mmu_idx, uintptr_t retaddr)
 {
-    hwaddr ioaddr;
-    target_ulong tlb_addr;
-    int index;
+    int index = (addr >> TARGET_PAGE_BITS) & (CPU_TLB_SIZE - 1);
+    target_ulong tlb_addr = env->tlb_table[mmu_idx][index].addr_write;
+    uintptr_t haddr;
 
-    index = (addr >> TARGET_PAGE_BITS) & (CPU_TLB_SIZE - 1);
- redo:
-    tlb_addr = env->tlb_table[mmu_idx][index].addr_write;
-    if ((addr & TARGET_PAGE_MASK) == (tlb_addr & (TARGET_PAGE_MASK | TLB_INVALID_MASK))) {
-        if (tlb_addr & ~TARGET_PAGE_MASK) {
-            /* IO access */
-            if ((addr & (DATA_SIZE - 1)) != 0)
-                goto do_unaligned_access;
-            ioaddr = env->iotlb[mmu_idx][index];
-            glue(io_write, SUFFIX)(env, ioaddr, val, addr, retaddr);
-        } else if (((addr & ~TARGET_PAGE_MASK) + DATA_SIZE - 1) >= TARGET_PAGE_SIZE) {
-        do_unaligned_access:
+    /* If the TLB entry is for a different page, reload and try again.  */
+    if ((addr & TARGET_PAGE_MASK)
+        != (tlb_addr & (TARGET_PAGE_MASK | TLB_INVALID_MASK))) {
 #ifdef ALIGNED_ONLY
+        if ((addr & (DATA_SIZE - 1)) != 0) {
             do_unaligned_access(env, addr, 1, mmu_idx, retaddr);
+        }
 #endif
-            glue(glue(slow_st, SUFFIX), MMUSUFFIX)(env, addr, val,
-                                                   mmu_idx, retaddr);
-        } else {
-            /* aligned/unaligned access in the same page */
-            uintptr_t addend;
+        tlb_fill(env, addr, 1, mmu_idx, retaddr);
+        tlb_addr = env->tlb_table[mmu_idx][index].addr_write;
+    }
+
+    /* Handle an IO access.  */
+    if (unlikely(tlb_addr & ~TARGET_PAGE_MASK)) {
+        hwaddr ioaddr;
+        if ((addr & (DATA_SIZE - 1)) != 0) {
+            goto do_unaligned_access;
+        }
+        ioaddr = env->iotlb[mmu_idx][index];
+        glue(io_write, SUFFIX)(env, ioaddr, val, addr, retaddr);
+        return;
+    }
+
+    /* Handle slow unaligned access (it spans two pages or IO).  */
+    if (DATA_SIZE > 1
+        && unlikely((addr & ~TARGET_PAGE_MASK) + DATA_SIZE - 1
+                     >= TARGET_PAGE_SIZE)) {
+        int i;
+    do_unaligned_access:
 #ifdef ALIGNED_ONLY
-            if ((addr & (DATA_SIZE - 1)) != 0) {
-                do_unaligned_access(env, addr, 1, mmu_idx, retaddr);
-            }
+        do_unaligned_access(env, addr, 1, mmu_idx, retaddr);
+#endif
+        /* XXX: not efficient, but simple */
+        /* Note: relies on the fact that tlb_fill() does not remove the
+         * previous page from the TLB cache.  */
+        for (i = DATA_SIZE - 1; i >= 0; i--) {
+#ifdef TARGET_WORDS_BIGENDIAN
+            uint8_t val8 = val >> (((DATA_SIZE - 1) * 8) - (i * 8));
+#else
+            uint8_t val8 = val >> (i * 8);
 #endif
-            addend = env->tlb_table[mmu_idx][index].addend;
-            glue(glue(st, SUFFIX), _raw)((uint8_t *)(intptr_t)
-                                         (addr + addend), val);
+            glue(helper_ret_stb, MMUSUFFIX)(env, addr + i, val8,
+                                            mmu_idx, retaddr);
         }
-    } else {
-        /* the page is not in the TLB : fill it */
+        return;
+    }
+
+    /* Handle aligned access or unaligned access in the same page.  */
 #ifdef ALIGNED_ONLY
-        if ((addr & (DATA_SIZE - 1)) != 0)
-            do_unaligned_access(env, addr, 1, mmu_idx, retaddr);
-#endif
-        tlb_fill(env, addr, 1, mmu_idx, retaddr);
-        goto redo;
+    if ((addr & (DATA_SIZE - 1)) != 0) {
+        do_unaligned_access(env, addr, 1, mmu_idx, retaddr);
     }
+#endif
+
+    haddr = addr + env->tlb_table[mmu_idx][index].addend;
+    glue(glue(st, SUFFIX), _raw)((uint8_t *)haddr, val);
 }
 
 void
@@ -277,56 +248,6 @@ glue(glue(helper_st, SUFFIX), MMUSUFFIX)(CPUArchState *env, target_ulong addr,
                                                  GETPC_EXT());
 }
 
-/* handles all unaligned cases */
-static void glue(glue(slow_st, SUFFIX), MMUSUFFIX)(CPUArchState *env,
-                                                   target_ulong addr,
-                                                   DATA_TYPE val,
-                                                   int mmu_idx,
-                                                   uintptr_t retaddr)
-{
-    hwaddr ioaddr;
-    target_ulong tlb_addr;
-    int index, i;
-
-    index = (addr >> TARGET_PAGE_BITS) & (CPU_TLB_SIZE - 1);
- redo:
-    tlb_addr = env->tlb_table[mmu_idx][index].addr_write;
-    if ((addr & TARGET_PAGE_MASK) == (tlb_addr & (TARGET_PAGE_MASK | TLB_INVALID_MASK))) {
-        if (tlb_addr & ~TARGET_PAGE_MASK) {
-            /* IO access */
-            if ((addr & (DATA_SIZE - 1)) != 0)
-                goto do_unaligned_access;
-            ioaddr = env->iotlb[mmu_idx][index];
-            glue(io_write, SUFFIX)(env, ioaddr, val, addr, retaddr);
-        } else if (((addr & ~TARGET_PAGE_MASK) + DATA_SIZE - 1) >= TARGET_PAGE_SIZE) {
-        do_unaligned_access:
-            /* XXX: not efficient, but simple */
-            /* Note: relies on the fact that tlb_fill() does not remove the
-             * previous page from the TLB cache.  */
-            for(i = DATA_SIZE - 1; i >= 0; i--) {
-#ifdef TARGET_WORDS_BIGENDIAN
-                glue(slow_stb, MMUSUFFIX)(env, addr + i,
-                                          val >> (((DATA_SIZE - 1) * 8) - (i * 8)),
-                                          mmu_idx, retaddr);
-#else
-                glue(slow_stb, MMUSUFFIX)(env, addr + i,
-                                          val >> (i * 8),
-                                          mmu_idx, retaddr);
-#endif
-            }
-        } else {
-            /* aligned/unaligned access in the same page */
-            uintptr_t addend = env->tlb_table[mmu_idx][index].addend;
-            glue(glue(st, SUFFIX), _raw)((uint8_t *)(intptr_t)
-                                         (addr + addend), val);
-        }
-    } else {
-        /* the page is not in the TLB : fill it */
-        tlb_fill(env, addr, 1, mmu_idx, retaddr);
-        goto redo;
-    }
-}
-
 #endif /* !defined(SOFTMMU_CODE_ACCESS) */
 
 #undef READ_ACCESS_TYPE
commit e25c3887e6ac50e7a0c42a2f597b088a27d5bb5d
Author: Richard Henderson <rth at twiddle.net>
Date:   Wed Jul 24 14:54:12 2013 -1000

    tcg: Add mmu helpers that take a return address argument
    
    Allow the code that tcg generates to be less obtuse, passing in
    the return address directly instead of computing it in the helper.
    
    Maintain the old entrance point unchanged as an alternate entry point.
    
    Delete the helper_st*_cmmu prototypes; the implementations did not exist.
    
    Signed-off-by: Richard Henderson <rth at twiddle.net>

diff --git a/include/exec/softmmu_defs.h b/include/exec/softmmu_defs.h
index 1f25e33..e55e717 100644
--- a/include/exec/softmmu_defs.h
+++ b/include/exec/softmmu_defs.h
@@ -9,29 +9,41 @@
 #ifndef SOFTMMU_DEFS_H
 #define SOFTMMU_DEFS_H
 
+uint8_t helper_ret_ldb_mmu(CPUArchState *env, target_ulong addr,
+                           int mmu_idx, uintptr_t retaddr);
+uint16_t helper_ret_ldw_mmu(CPUArchState *env, target_ulong addr,
+                            int mmu_idx, uintptr_t retaddr);
+uint32_t helper_ret_ldl_mmu(CPUArchState *env, target_ulong addr,
+                            int mmu_idx, uintptr_t retaddr);
+uint64_t helper_ret_ldq_mmu(CPUArchState *env, target_ulong addr,
+                            int mmu_idx, uintptr_t retaddr);
+
+void helper_ret_stb_mmu(CPUArchState *env, target_ulong addr, uint8_t val,
+                        int mmu_idx, uintptr_t retaddr);
+void helper_ret_stw_mmu(CPUArchState *env, target_ulong addr, uint16_t val,
+                        int mmu_idx, uintptr_t retaddr);
+void helper_ret_stl_mmu(CPUArchState *env, target_ulong addr, uint32_t val,
+                        int mmu_idx, uintptr_t retaddr);
+void helper_ret_stq_mmu(CPUArchState *env, target_ulong addr, uint64_t val,
+                        int mmu_idx, uintptr_t retaddr);
+
 uint8_t helper_ldb_mmu(CPUArchState *env, target_ulong addr, int mmu_idx);
-void helper_stb_mmu(CPUArchState *env, target_ulong addr, uint8_t val,
-                    int mmu_idx);
 uint16_t helper_ldw_mmu(CPUArchState *env, target_ulong addr, int mmu_idx);
-void helper_stw_mmu(CPUArchState *env, target_ulong addr, uint16_t val,
-                    int mmu_idx);
 uint32_t helper_ldl_mmu(CPUArchState *env, target_ulong addr, int mmu_idx);
-void helper_stl_mmu(CPUArchState *env, target_ulong addr, uint32_t val,
-                    int mmu_idx);
 uint64_t helper_ldq_mmu(CPUArchState *env, target_ulong addr, int mmu_idx);
-void helper_stq_mmu(CPUArchState *env, target_ulong addr, uint64_t val,
-                    int mmu_idx);
+
+void helper_stb_mmu(CPUArchState *env, target_ulong addr,
+                    uint8_t val, int mmu_idx);
+void helper_stw_mmu(CPUArchState *env, target_ulong addr,
+                    uint16_t val, int mmu_idx);
+void helper_stl_mmu(CPUArchState *env, target_ulong addr,
+                    uint32_t val, int mmu_idx);
+void helper_stq_mmu(CPUArchState *env, target_ulong addr,
+                    uint64_t val, int mmu_idx);
 
 uint8_t helper_ldb_cmmu(CPUArchState *env, target_ulong addr, int mmu_idx);
-void helper_stb_cmmu(CPUArchState *env, target_ulong addr, uint8_t val,
-int mmu_idx);
 uint16_t helper_ldw_cmmu(CPUArchState *env, target_ulong addr, int mmu_idx);
-void helper_stw_cmmu(CPUArchState *env, target_ulong addr, uint16_t val,
-                     int mmu_idx);
 uint32_t helper_ldl_cmmu(CPUArchState *env, target_ulong addr, int mmu_idx);
-void helper_stl_cmmu(CPUArchState *env, target_ulong addr, uint32_t val,
-                     int mmu_idx);
 uint64_t helper_ldq_cmmu(CPUArchState *env, target_ulong addr, int mmu_idx);
-void helper_stq_cmmu(CPUArchState *env, target_ulong addr, uint64_t val,
-                     int mmu_idx);
-#endif
+
+#endif /* SOFTMMU_DEFS_H */
diff --git a/include/exec/softmmu_template.h b/include/exec/softmmu_template.h
index 8584902..7d8bcb5 100644
--- a/include/exec/softmmu_template.h
+++ b/include/exec/softmmu_template.h
@@ -78,15 +78,18 @@ static inline DATA_TYPE glue(io_read, SUFFIX)(CPUArchState *env,
 }
 
 /* handle all cases except unaligned access which span two pages */
+#ifdef SOFTMMU_CODE_ACCESS
+static
+#endif
 DATA_TYPE
-glue(glue(helper_ld, SUFFIX), MMUSUFFIX)(CPUArchState *env, target_ulong addr,
-                                         int mmu_idx)
+glue(glue(helper_ret_ld, SUFFIX), MMUSUFFIX)(CPUArchState *env,
+                                             target_ulong addr, int mmu_idx,
+                                             uintptr_t retaddr)
 {
     DATA_TYPE res;
     int index;
     target_ulong tlb_addr;
     hwaddr ioaddr;
-    uintptr_t retaddr;
 
     /* test if there is match for unaligned or IO access */
     /* XXX: could done more in memory macro in a non portable way */
@@ -98,13 +101,11 @@ glue(glue(helper_ld, SUFFIX), MMUSUFFIX)(CPUArchState *env, target_ulong addr,
             /* IO access */
             if ((addr & (DATA_SIZE - 1)) != 0)
                 goto do_unaligned_access;
-            retaddr = GETPC_EXT();
             ioaddr = env->iotlb[mmu_idx][index];
             res = glue(io_read, SUFFIX)(env, ioaddr, addr, retaddr);
         } else if (((addr & ~TARGET_PAGE_MASK) + DATA_SIZE - 1) >= TARGET_PAGE_SIZE) {
             /* slow unaligned access (it spans two pages or IO) */
         do_unaligned_access:
-            retaddr = GETPC_EXT();
 #ifdef ALIGNED_ONLY
             do_unaligned_access(env, addr, READ_ACCESS_TYPE, mmu_idx, retaddr);
 #endif
@@ -115,7 +116,6 @@ glue(glue(helper_ld, SUFFIX), MMUSUFFIX)(CPUArchState *env, target_ulong addr,
             uintptr_t addend;
 #ifdef ALIGNED_ONLY
             if ((addr & (DATA_SIZE - 1)) != 0) {
-                retaddr = GETPC_EXT();
                 do_unaligned_access(env, addr, READ_ACCESS_TYPE, mmu_idx, retaddr);
             }
 #endif
@@ -124,8 +124,6 @@ glue(glue(helper_ld, SUFFIX), MMUSUFFIX)(CPUArchState *env, target_ulong addr,
                                                 (addr + addend));
         }
     } else {
-        /* the page is not in the TLB : fill it */
-        retaddr = GETPC_EXT();
 #ifdef ALIGNED_ONLY
         if ((addr & (DATA_SIZE - 1)) != 0)
             do_unaligned_access(env, addr, READ_ACCESS_TYPE, mmu_idx, retaddr);
@@ -136,6 +134,14 @@ glue(glue(helper_ld, SUFFIX), MMUSUFFIX)(CPUArchState *env, target_ulong addr,
     return res;
 }
 
+DATA_TYPE
+glue(glue(helper_ld, SUFFIX), MMUSUFFIX)(CPUArchState *env, target_ulong addr,
+                                         int mmu_idx)
+{
+    return glue(glue(helper_ret_ld, SUFFIX), MMUSUFFIX)(env, addr, mmu_idx,
+                                                        GETPC_EXT());
+}
+
 /* handle all unaligned cases */
 static DATA_TYPE
 glue(glue(slow_ld, SUFFIX), MMUSUFFIX)(CPUArchState *env,
@@ -214,13 +220,13 @@ static inline void glue(io_write, SUFFIX)(CPUArchState *env,
     io_mem_write(mr, physaddr, val, 1 << SHIFT);
 }
 
-void glue(glue(helper_st, SUFFIX), MMUSUFFIX)(CPUArchState *env,
-                                              target_ulong addr, DATA_TYPE val,
-                                              int mmu_idx)
+void
+glue(glue(helper_ret_st, SUFFIX), MMUSUFFIX)(CPUArchState *env,
+                                             target_ulong addr, DATA_TYPE val,
+                                             int mmu_idx, uintptr_t retaddr)
 {
     hwaddr ioaddr;
     target_ulong tlb_addr;
-    uintptr_t retaddr;
     int index;
 
     index = (addr >> TARGET_PAGE_BITS) & (CPU_TLB_SIZE - 1);
@@ -231,12 +237,10 @@ void glue(glue(helper_st, SUFFIX), MMUSUFFIX)(CPUArchState *env,
             /* IO access */
             if ((addr & (DATA_SIZE - 1)) != 0)
                 goto do_unaligned_access;
-            retaddr = GETPC_EXT();
             ioaddr = env->iotlb[mmu_idx][index];
             glue(io_write, SUFFIX)(env, ioaddr, val, addr, retaddr);
         } else if (((addr & ~TARGET_PAGE_MASK) + DATA_SIZE - 1) >= TARGET_PAGE_SIZE) {
         do_unaligned_access:
-            retaddr = GETPC_EXT();
 #ifdef ALIGNED_ONLY
             do_unaligned_access(env, addr, 1, mmu_idx, retaddr);
 #endif
@@ -247,7 +251,6 @@ void glue(glue(helper_st, SUFFIX), MMUSUFFIX)(CPUArchState *env,
             uintptr_t addend;
 #ifdef ALIGNED_ONLY
             if ((addr & (DATA_SIZE - 1)) != 0) {
-                retaddr = GETPC_EXT();
                 do_unaligned_access(env, addr, 1, mmu_idx, retaddr);
             }
 #endif
@@ -257,7 +260,6 @@ void glue(glue(helper_st, SUFFIX), MMUSUFFIX)(CPUArchState *env,
         }
     } else {
         /* the page is not in the TLB : fill it */
-        retaddr = GETPC_EXT();
 #ifdef ALIGNED_ONLY
         if ((addr & (DATA_SIZE - 1)) != 0)
             do_unaligned_access(env, addr, 1, mmu_idx, retaddr);
@@ -267,6 +269,14 @@ void glue(glue(helper_st, SUFFIX), MMUSUFFIX)(CPUArchState *env,
     }
 }
 
+void
+glue(glue(helper_st, SUFFIX), MMUSUFFIX)(CPUArchState *env, target_ulong addr,
+                                         DATA_TYPE val, int mmu_idx)
+{
+    glue(glue(helper_ret_st, SUFFIX), MMUSUFFIX)(env, addr, val, mmu_idx,
+                                                 GETPC_EXT());
+}
+
 /* handles all unaligned cases */
 static void glue(glue(slow_st, SUFFIX), MMUSUFFIX)(CPUArchState *env,
                                                    target_ulong addr,
commit c6f29ff096d9e956df94db20fe49275c35f601fb
Author: Richard Henderson <rth at twiddle.net>
Date:   Thu Jul 25 06:33:33 2013 -1000

    tcg-i386: Tidy qemu_ld/st slow path
    
    Use existing stack space for arguments; don't push/pop.
    Use less ifdefs and more C ifs.
    
    Signed-off-by: Richard Henderson <rth at twiddle.net>

diff --git a/tcg/i386/tcg-target.c b/tcg/i386/tcg-target.c
index 8226171..fba50f8 100644
--- a/tcg/i386/tcg-target.c
+++ b/tcg/i386/tcg-target.c
@@ -608,6 +608,14 @@ static inline void tcg_out_st(TCGContext *s, TCGType type, TCGReg arg,
     tcg_out_modrm_offset(s, opc, arg, arg1, arg2);
 }
 
+static inline void tcg_out_sti(TCGContext *s, TCGType type, TCGReg base,
+                               tcg_target_long ofs, tcg_target_long val)
+{
+    int opc = OPC_MOVL_EvIz + (type == TCG_TYPE_I64 ? P_REXW : 0);
+    tcg_out_modrm_offset(s, opc, 0, base, ofs);
+    tcg_out32(s, val);
+}
+
 static void tcg_out_shifti(TCGContext *s, int subopc, int reg, int count)
 {
     /* Propagate an opcode prefix, such as P_DATA16.  */
@@ -1463,22 +1471,12 @@ static void add_qemu_ldst_label(TCGContext *s,
 /*
  * Generate code for the slow path for a load at the end of block
  */
-static void tcg_out_qemu_ld_slow_path(TCGContext *s, TCGLabelQemuLdst *label)
+static void tcg_out_qemu_ld_slow_path(TCGContext *s, TCGLabelQemuLdst *l)
 {
-    int s_bits;
-    int opc = label->opc;
-    int mem_index = label->mem_index;
-#if TCG_TARGET_REG_BITS == 32
-    int stack_adjust;
-    int addrlo_reg = label->addrlo_reg;
-    int addrhi_reg = label->addrhi_reg;
-#endif
-    int data_reg = label->datalo_reg;
-    int data_reg2 = label->datahi_reg;
-    uint8_t *raddr = label->raddr;
-    uint8_t **label_ptr = &label->label_ptr[0];
-
-    s_bits = opc & 3;
+    int opc = l->opc;
+    int s_bits = opc & 3;
+    TCGReg data_reg;
+    uint8_t **label_ptr = &l->label_ptr[0];
 
     /* resolve label address */
     *(uint32_t *)label_ptr[0] = (uint32_t)(s->code_ptr - label_ptr[0] - 4);
@@ -1486,22 +1484,27 @@ static void tcg_out_qemu_ld_slow_path(TCGContext *s, TCGLabelQemuLdst *label)
         *(uint32_t *)label_ptr[1] = (uint32_t)(s->code_ptr - label_ptr[1] - 4);
     }
 
-#if TCG_TARGET_REG_BITS == 32
-    tcg_out_pushi(s, mem_index);
-    stack_adjust = 4;
-    if (TARGET_LONG_BITS == 64) {
-        tcg_out_push(s, addrhi_reg);
-        stack_adjust += 4;
+    if (TCG_TARGET_REG_BITS == 32) {
+        int ofs = 0;
+
+        tcg_out_st(s, TCG_TYPE_PTR, TCG_AREG0, TCG_REG_ESP, ofs);
+        ofs += 4;
+
+        tcg_out_st(s, TCG_TYPE_I32, l->addrlo_reg, TCG_REG_ESP, ofs);
+        ofs += 4;
+
+        if (TARGET_LONG_BITS == 64) {
+            tcg_out_st(s, TCG_TYPE_I32, l->addrhi_reg, TCG_REG_ESP, ofs);
+            ofs += 4;
+        }
+
+        tcg_out_sti(s, TCG_TYPE_I32, TCG_REG_ESP, ofs, l->mem_index);
+    } else {
+        tcg_out_mov(s, TCG_TYPE_I64, tcg_target_call_iarg_regs[0], TCG_AREG0);
+        /* The second argument is already loaded with addrlo.  */
+        tcg_out_movi(s, TCG_TYPE_I32, tcg_target_call_iarg_regs[2],
+                     l->mem_index);
     }
-    tcg_out_push(s, addrlo_reg);
-    stack_adjust += 4;
-    tcg_out_push(s, TCG_AREG0);
-    stack_adjust += 4;
-#else
-    tcg_out_mov(s, TCG_TYPE_I64, tcg_target_call_iarg_regs[0], TCG_AREG0);
-    /* The second argument is already loaded with addrlo.  */
-    tcg_out_movi(s, TCG_TYPE_I32, tcg_target_call_iarg_regs[2], mem_index);
-#endif
 
     /* Code generation of qemu_ld/st's slow path calling MMU helper
 
@@ -1520,18 +1523,10 @@ static void tcg_out_qemu_ld_slow_path(TCGContext *s, TCGLabelQemuLdst *label)
     tcg_out8(s, 5);
     /* Dummy backward jump having information of fast path'pc for MMU helpers */
     tcg_out8(s, OPC_JMP_long);
-    *(int32_t *)s->code_ptr = (int32_t)(raddr - s->code_ptr - 4);
+    *(int32_t *)s->code_ptr = (int32_t)(l->raddr - s->code_ptr - 4);
     s->code_ptr += 4;
 
-#if TCG_TARGET_REG_BITS == 32
-    if (stack_adjust == (TCG_TARGET_REG_BITS / 8)) {
-        /* Pop and discard.  This is 2 bytes smaller than the add.  */
-        tcg_out_pop(s, TCG_REG_ECX);
-    } else if (stack_adjust != 0) {
-        tcg_out_addi(s, TCG_REG_CALL_STACK, stack_adjust);
-    }
-#endif
-
+    data_reg = l->datalo_reg;
     switch(opc) {
     case 0 | 4:
         tcg_out_ext8s(s, data_reg, TCG_REG_EAX, P_REXW);
@@ -1559,10 +1554,10 @@ static void tcg_out_qemu_ld_slow_path(TCGContext *s, TCGLabelQemuLdst *label)
         } else if (data_reg == TCG_REG_EDX) {
             /* xchg %edx, %eax */
             tcg_out_opc(s, OPC_XCHG_ax_r32 + TCG_REG_EDX, 0, 0, 0);
-            tcg_out_mov(s, TCG_TYPE_I32, data_reg2, TCG_REG_EAX);
+            tcg_out_mov(s, TCG_TYPE_I32, l->datahi_reg, TCG_REG_EAX);
         } else {
             tcg_out_mov(s, TCG_TYPE_I32, data_reg, TCG_REG_EAX);
-            tcg_out_mov(s, TCG_TYPE_I32, data_reg2, TCG_REG_EDX);
+            tcg_out_mov(s, TCG_TYPE_I32, l->datahi_reg, TCG_REG_EDX);
         }
         break;
     default:
@@ -1570,28 +1565,17 @@ static void tcg_out_qemu_ld_slow_path(TCGContext *s, TCGLabelQemuLdst *label)
     }
 
     /* Jump to the code corresponding to next IR of qemu_st */
-    tcg_out_jmp(s, (tcg_target_long)raddr);
+    tcg_out_jmp(s, (tcg_target_long)l->raddr);
 }
 
 /*
  * Generate code for the slow path for a store at the end of block
  */
-static void tcg_out_qemu_st_slow_path(TCGContext *s, TCGLabelQemuLdst *label)
+static void tcg_out_qemu_st_slow_path(TCGContext *s, TCGLabelQemuLdst *l)
 {
-    int s_bits;
-    int stack_adjust;
-    int opc = label->opc;
-    int mem_index = label->mem_index;
-    int data_reg = label->datalo_reg;
-#if TCG_TARGET_REG_BITS == 32
-    int data_reg2 = label->datahi_reg;
-    int addrlo_reg = label->addrlo_reg;
-    int addrhi_reg = label->addrhi_reg;
-#endif
-    uint8_t *raddr = label->raddr;
-    uint8_t **label_ptr = &label->label_ptr[0];
-
-    s_bits = opc & 3;
+    int opc = l->opc;
+    int s_bits = opc & 3;
+    uint8_t **label_ptr = &l->label_ptr[0];
 
     /* resolve label address */
     *(uint32_t *)label_ptr[0] = (uint32_t)(s->code_ptr - label_ptr[0] - 4);
@@ -1599,31 +1583,37 @@ static void tcg_out_qemu_st_slow_path(TCGContext *s, TCGLabelQemuLdst *label)
         *(uint32_t *)label_ptr[1] = (uint32_t)(s->code_ptr - label_ptr[1] - 4);
     }
 
-#if TCG_TARGET_REG_BITS == 32
-    tcg_out_pushi(s, mem_index);
-    stack_adjust = 4;
-    if (opc == 3) {
-        tcg_out_push(s, data_reg2);
-        stack_adjust += 4;
-    }
-    tcg_out_push(s, data_reg);
-    stack_adjust += 4;
-    if (TARGET_LONG_BITS == 64) {
-        tcg_out_push(s, addrhi_reg);
-        stack_adjust += 4;
+    if (TCG_TARGET_REG_BITS == 32) {
+        int ofs = 0;
+
+        tcg_out_st(s, TCG_TYPE_PTR, TCG_AREG0, TCG_REG_ESP, ofs);
+        ofs += 4;
+
+        tcg_out_st(s, TCG_TYPE_I32, l->addrlo_reg, TCG_REG_ESP, ofs);
+        ofs += 4;
+
+        if (TARGET_LONG_BITS == 64) {
+            tcg_out_st(s, TCG_TYPE_I32, l->addrhi_reg, TCG_REG_ESP, ofs);
+            ofs += 4;
+        }
+
+        tcg_out_st(s, TCG_TYPE_I32, l->datalo_reg, TCG_REG_ESP, ofs);
+        ofs += 4;
+
+        if (opc == 3) {
+            tcg_out_st(s, TCG_TYPE_I32, l->datahi_reg, TCG_REG_ESP, ofs);
+            ofs += 4;
+        }
+
+        tcg_out_sti(s, TCG_TYPE_I32, TCG_REG_ESP, ofs, l->mem_index);
+    } else {
+        tcg_out_mov(s, TCG_TYPE_I64, tcg_target_call_iarg_regs[0], TCG_AREG0);
+        /* The second argument is already loaded with addrlo.  */
+        tcg_out_mov(s, (opc == 3 ? TCG_TYPE_I64 : TCG_TYPE_I32),
+                    tcg_target_call_iarg_regs[2], l->datalo_reg);
+        tcg_out_movi(s, TCG_TYPE_I32, tcg_target_call_iarg_regs[3],
+                     l->mem_index);
     }
-    tcg_out_push(s, addrlo_reg);
-    stack_adjust += 4;
-    tcg_out_push(s, TCG_AREG0);
-    stack_adjust += 4;
-#else
-    tcg_out_mov(s, TCG_TYPE_I64, tcg_target_call_iarg_regs[0], TCG_AREG0);
-    /* The second argument is already loaded with addrlo.  */
-    tcg_out_mov(s, (opc == 3 ? TCG_TYPE_I64 : TCG_TYPE_I32),
-                tcg_target_call_iarg_regs[2], data_reg);
-    tcg_out_movi(s, TCG_TYPE_I32, tcg_target_call_iarg_regs[3], mem_index);
-    stack_adjust = 0;
-#endif
 
     /* Code generation of qemu_ld/st's slow path calling MMU helper
 
@@ -1642,18 +1632,11 @@ static void tcg_out_qemu_st_slow_path(TCGContext *s, TCGLabelQemuLdst *label)
     tcg_out8(s, 5);
     /* Dummy backward jump having information of fast path'pc for MMU helpers */
     tcg_out8(s, OPC_JMP_long);
-    *(int32_t *)s->code_ptr = (int32_t)(raddr - s->code_ptr - 4);
+    *(int32_t *)s->code_ptr = (int32_t)(l->raddr - s->code_ptr - 4);
     s->code_ptr += 4;
 
-    if (stack_adjust == (TCG_TARGET_REG_BITS / 8)) {
-        /* Pop and discard.  This is 2 bytes smaller than the add.  */
-        tcg_out_pop(s, TCG_REG_ECX);
-    } else if (stack_adjust != 0) {
-        tcg_out_addi(s, TCG_REG_CALL_STACK, stack_adjust);
-    }
-
     /* Jump to the code corresponding to next IR of qemu_st */
-    tcg_out_jmp(s, (tcg_target_long)raddr);
+    tcg_out_jmp(s, (tcg_target_long)l->raddr);
 }
 
 /*
commit 8023ccda079624221e618efeb537b41c70407469
Author: Richard Henderson <rth at twiddle.net>
Date:   Thu Jul 25 10:00:41 2013 -1000

    tcg-i386: Try pc-relative lea for constant formation
    
    Use a 7 byte lea before the ultimate 10 byte movq.
    
    Signed-off-by: Richard Henderson <rth at twiddle.net>

diff --git a/tcg/i386/tcg-target.c b/tcg/i386/tcg-target.c
index 841bd75..8226171 100644
--- a/tcg/i386/tcg-target.c
+++ b/tcg/i386/tcg-target.c
@@ -541,19 +541,34 @@ static inline void tcg_out_mov(TCGContext *s, TCGType type,
 static void tcg_out_movi(TCGContext *s, TCGType type,
                          TCGReg ret, tcg_target_long arg)
 {
+    tcg_target_long diff;
+
     if (arg == 0) {
         tgen_arithr(s, ARITH_XOR, ret, ret);
         return;
-    } else if (arg == (uint32_t)arg || type == TCG_TYPE_I32) {
+    }
+    if (arg == (uint32_t)arg || type == TCG_TYPE_I32) {
         tcg_out_opc(s, OPC_MOVL_Iv + LOWREGMASK(ret), 0, ret, 0);
         tcg_out32(s, arg);
-    } else if (arg == (int32_t)arg) {
+        return;
+    }
+    if (arg == (int32_t)arg) {
         tcg_out_modrm(s, OPC_MOVL_EvIz + P_REXW, 0, ret);
         tcg_out32(s, arg);
-    } else {
-        tcg_out_opc(s, OPC_MOVL_Iv + P_REXW + LOWREGMASK(ret), 0, ret, 0);
-        tcg_out64(s, arg);
+        return;
     }
+
+    /* Try a 7 byte pc-relative lea before the 10 byte movq.  */
+    diff = arg - ((tcg_target_long)s->code_ptr + 7);
+    if (diff == (int32_t)diff) {
+        tcg_out_opc(s, OPC_LEA | P_REXW, ret, 0, 0);
+        tcg_out8(s, (LOWREGMASK(ret) << 3) | 5);
+        tcg_out32(s, diff);
+        return;
+    }
+
+    tcg_out_opc(s, OPC_MOVL_Iv + P_REXW + LOWREGMASK(ret), 0, ret, 0);
+    tcg_out64(s, arg);
 }
 
 static inline void tcg_out_pushi(TCGContext *s, tcg_target_long val)
commit ac26eb69a311396668809eadbf7ff4e623447d4c
Author: Richard Henderson <rth at twiddle.net>
Date:   Thu Jul 25 09:42:17 2013 -1000

    tcg-i386: Add and use tcg_out64
    
    No point in splitting the write into 32-bit pieces.
    
    Reviewed-by: Aurelien Jarno <aurelien at aurel32.net>
    Signed-off-by: Richard Henderson <rth at twiddle.net>

diff --git a/tcg/i386/tcg-target.c b/tcg/i386/tcg-target.c
index 87eeab3..841bd75 100644
--- a/tcg/i386/tcg-target.c
+++ b/tcg/i386/tcg-target.c
@@ -552,8 +552,7 @@ static void tcg_out_movi(TCGContext *s, TCGType type,
         tcg_out32(s, arg);
     } else {
         tcg_out_opc(s, OPC_MOVL_Iv + P_REXW + LOWREGMASK(ret), 0, ret, 0);
-        tcg_out32(s, arg);
-        tcg_out32(s, arg >> 31 >> 1);
+        tcg_out64(s, arg);
     }
 }
 
diff --git a/tcg/tcg.c b/tcg/tcg.c
index 42c95af..19bd5a3 100644
--- a/tcg/tcg.c
+++ b/tcg/tcg.c
@@ -133,6 +133,13 @@ static inline void tcg_out32(TCGContext *s, uint32_t v)
     s->code_ptr = p + 4;
 }
 
+static inline void tcg_out64(TCGContext *s, uint64_t v)
+{
+    uint8_t *p = s->code_ptr;
+    *(uint64_t *)p = v;
+    s->code_ptr = p + 8;
+}
+
 /* label relocation processing */
 
 static void tcg_out_reloc(TCGContext *s, uint8_t *code_ptr, int type,
commit 2bb8656dadcaa521a9699ab2a2632b68da36c998
Author: Richard Henderson <rth at twiddle.net>
Date:   Wed Aug 14 09:46:38 2013 -0700

    tcg: Tidy generated code for tcg_outN
    
    Aliasing was forcing s->code_ptr to be re-read after the store.
    Keep the pointer in a local variable to help the compiler.
    
    Signed-off-by: Richard Henderson <rth at twiddle.net>

diff --git a/tcg/tcg.c b/tcg/tcg.c
index dac8224..42c95af 100644
--- a/tcg/tcg.c
+++ b/tcg/tcg.c
@@ -121,14 +121,16 @@ static inline void tcg_out8(TCGContext *s, uint8_t v)
 
 static inline void tcg_out16(TCGContext *s, uint16_t v)
 {
-    *(uint16_t *)s->code_ptr = v;
-    s->code_ptr += 2;
+    uint8_t *p = s->code_ptr;
+    *(uint16_t *)p = v;
+    s->code_ptr = p + 2;
 }
 
 static inline void tcg_out32(TCGContext *s, uint32_t v)
 {
-    *(uint32_t *)s->code_ptr = v;
-    s->code_ptr += 4;
+    uint8_t *p = s->code_ptr;
+    *(uint32_t *)p = v;
+    s->code_ptr = p + 4;
 }
 
 /* label relocation processing */
commit f7ad538e1ea130c8b6f3abb06ad6c856242c799e
Merge: e3f024a b10577d
Author: Anthony Liguori <anthony at codemonkey.ws>
Date:   Mon Aug 26 09:19:50 2013 -0500

    Merge remote-tracking branch 'stefanha/block' into staging
    
    # By Alex Bligh (32) and others
    # Via Stefan Hajnoczi
    * stefanha/block: (42 commits)
      win32-aio: drop win32_aio_flush_cb()
      aio-win32: replace incorrect AioHandler->opaque usage with ->e
      aio / timers: remove dummy_io_handler_flush from tests/test-aio.c
      aio / timers: Remove legacy interface
      aio / timers: Switch entire codebase to the new timer API
      aio / timers: Add scripts/switch-timer-api
      aio / timers: Add test harness for AioContext timers
      aio / timers: convert block_job_sleep_ns and co_sleep_ns to new API
      aio / timers: Convert rtc_clock to be a QEMUClockType
      aio / timers: Remove main_loop_timerlist
      aio / timers: Rearrange timer.h & make legacy functions call non-legacy
      aio / timers: Add qemu_clock_get_ms and qemu_clock_get_ms
      aio / timers: Remove legacy qemu_clock_deadline & qemu_timerlist_deadline
      aio / timers: Remove alarm timers
      aio / timers: Add documentation and new format calls
      aio / timers: Use all timerlists in icount warp calculations
      aio / timers: Introduce new API timer_new and friends
      aio / timers: On timer modification, qemu_notify or aio_notify
      aio / timers: Convert mainloop to use timeout
      aio / timers: Convert aio_poll to use AioContext timers' deadline
      ...
    
    Message-id: 1377202298-22896-1-git-send-email-stefanha at redhat.com
    Signed-off-by: Anthony Liguori <anthony at codemonkey.ws>

commit e3f024aec29a2e3eff46138687e2ecba7631c645
Merge: 42eed42 73c30df
Author: Anthony Liguori <anthony at codemonkey.ws>
Date:   Mon Aug 26 09:19:36 2013 -0500

    Merge remote-tracking branch 'afaerber/tags/0.15-maintainer-for-anthony' into staging
    
    MAINTAINERS update for stable-0.15
    
    # gpg: Signature made Thu 22 Aug 2013 10:59:31 AM CDT using RSA key ID 3E7E013F
    # gpg: Can't check signature: public key not found
    
    # By Andreas Färber
    # Via Andreas Färber
    * afaerber/tags/0.15-maintainer-for-anthony:
      MAINTAINERS: Take over 0.15 maintenance

commit 1ae2757c6c4525c9b42f408c86818f843bad7418
Author: yinyin <yin.yin at cs2c.com.cn>
Date:   Thu Aug 22 14:47:16 2013 +0800

    virtio: virtqueue_get_avail_bytes: fix desc_pa when loop over the indirect descriptor table
    
    virtqueue_get_avail_bytes: when found a indirect desc, we need loop over it.
               /* loop over the indirect descriptor table */
               indirect = 1;
               max = vring_desc_len(desc_pa, i) / sizeof(VRingDesc);
               num_bufs = i = 0;
               desc_pa = vring_desc_addr(desc_pa, i);
    But, It init i to 0, then use i to update desc_pa. so we will always get:
    desc_pa = vring_desc_addr(desc_pa, 0);
    the last two line should swap.
    
    Cc: qemu-stable at nongnu.org
    Signed-off-by: Yin Yin <yin.yin at cs2c.com.cn>
    Reviewed-by: Stefan Hajnoczi <stefanha at redhat.com>
    Signed-off-by: Michael S. Tsirkin <mst at redhat.com>

diff --git a/hw/virtio/virtio.c b/hw/virtio/virtio.c
index f03c45d..2f1e73b 100644
--- a/hw/virtio/virtio.c
+++ b/hw/virtio/virtio.c
@@ -377,8 +377,8 @@ void virtqueue_get_avail_bytes(VirtQueue *vq, unsigned int *in_bytes,
             /* loop over the indirect descriptor table */
             indirect = 1;
             max = vring_desc_len(desc_pa, i) / sizeof(VRingDesc);
-            num_bufs = i = 0;
             desc_pa = vring_desc_addr(desc_pa, i);
+            num_bufs = i = 0;
         }
 
         do {
commit 42eed424e1ea6469ce73cb2fdddb0d31bebb686a
Author: Richard Henderson <rth at twiddle.net>
Date:   Fri Aug 16 23:29:47 2013 -0700

    disas-objdump: Pass --adjust-vma to objdump
    
    This gives the dumped blob its correct address during disassembly,
    which makes pc-relative insns much easier to interpret.
    
    Signed-off-by: Richard Henderson <rth at twiddle.net>
    Signed-off-by: Edgar E. Iglesias <edgar.iglesias at gmail.com>

diff --git a/scripts/disas-objdump.pl b/scripts/disas-objdump.pl
index c66a629..8f7e818 100755
--- a/scripts/disas-objdump.pl
+++ b/scripts/disas-objdump.pl
@@ -29,7 +29,7 @@ sub mkobjcommand ($$) {
     my ($cmd, $mach) = @_;
     return 0 if !$mach;
     $cmd = $aobjdump if !$cmd;
-    return "$cmd -m $mach --disassemble-all -b binary $outname";
+    return "$cmd -m $mach --disassemble-all -b binary";
 }
 
 $objdump[1] = mkobjcommand($hobjdump, $hmachine);
@@ -38,6 +38,7 @@ $objdump[2] = mkobjcommand($tobjdump, $tmachine);
 # Zero-initialize current dumping state.
 my $mem = "";
 my $inobjd = 0;
+my $vma = 0;
 
 sub objcommand {
     my $ret = $objdump[$inobjd];
@@ -50,7 +51,7 @@ sub objcommand {
 }
 
 while (<>) {
-    # Collect the data from the relevant OBJD-* lines.
+    # Collect the data from the relevant OBJD-* lines ...
     if (/^OBJD-H: /) {
         die "Internal error" if $inobjd == 2;
         $mem = $mem . pack("H*", substr($_, 8, -1));
@@ -68,8 +69,12 @@ while (<>) {
         truncate $outh, 0;
         syswrite $outh, $mem;
 
+        my $cmd = objcommand();
+        $cmd = $cmd . " --adjust-vma=" . $vma if $vma;
+        $cmd = $cmd . " " . $outname;
+
         # Pipe from objdump...
-        open IN, "-|", objcommand();
+        open IN, "-|", $cmd;
 
         # ... copying all but the first 7 lines of boilerplate to our stdout.
 	my $i = 0;
@@ -81,6 +86,13 @@ while (<>) {
 
         $mem = "";
         $inobjd = 0;
+        $vma = 0;
+    }
+    # The line before "OBJD-*" will be of the form "0x<hex>+: +\n".
+    # Extract the value for passing to --adjust-vma.
+    elsif (/^(0x[0-9a-fA-F]+):\s*$/) {
+        $vma = $1;
+        print;
     } else {
         print;
     }
commit 8dc6d24091edc34be1f989a2d92703130760401f
Author: Richard Henderson <rth at twiddle.net>
Date:   Fri Aug 16 23:29:46 2013 -0700

    disas: Add disas-objdump.pl
    
    The script massages the output produced for architectures that are
    not supported internally by qemu though an external objdump program
    for disassembly.
    
    Signed-off-by: Richard Henderson <rth at twiddle.net>
    Signed-off-by: Edgar E. Iglesias <edgar.iglesias at gmail.com>

diff --git a/scripts/disas-objdump.pl b/scripts/disas-objdump.pl
new file mode 100755
index 0000000..c66a629
--- /dev/null
+++ b/scripts/disas-objdump.pl
@@ -0,0 +1,87 @@
+#!/usr/bin/perl -w
+
+use File::Temp qw/ tempfile /;
+use Getopt::Long;
+
+# Default to the system objdump if a cross-compiler edition not given.
+my $aobjdump = "objdump";
+my $hobjdump = "";
+my $tobjdump = "";
+my $hmachine = "";
+my $tmachine = "";
+
+GetOptions ('O|objdump=s' => \$aobjdump,
+            'host-objdump=s' => \$hobjdump,
+            'target-objdump=s' => \$tobjdump,
+            'h|host-machine=s' => \$hmachine,
+            't|target-machine=s' => \$tmachine);
+
+# But we can't default the machines.  Sanity check that we've at least one.
+die "No host or target machine type" if !$hmachine && !$tmachine;
+
+# Reuse one temp file for all of the hunks.
+my ($outh, $outname) = tempfile();
+binmode($outh);
+END { unlink $outname; }
+
+# Pre-construct the command-lines for executing the dump.
+sub mkobjcommand ($$) {
+    my ($cmd, $mach) = @_;
+    return 0 if !$mach;
+    $cmd = $aobjdump if !$cmd;
+    return "$cmd -m $mach --disassemble-all -b binary $outname";
+}
+
+$objdump[1] = mkobjcommand($hobjdump, $hmachine);
+$objdump[2] = mkobjcommand($tobjdump, $tmachine);
+
+# Zero-initialize current dumping state.
+my $mem = "";
+my $inobjd = 0;
+
+sub objcommand {
+    my $ret = $objdump[$inobjd];
+    if (!$ret) {
+        die "Host machine type not specified" if $inobjd == 1;
+        die "Target machine type not specified" if $inobjd == 2;
+        die "Internal error";
+    }
+    return $ret;
+}
+
+while (<>) {
+    # Collect the data from the relevant OBJD-* lines.
+    if (/^OBJD-H: /) {
+        die "Internal error" if $inobjd == 2;
+        $mem = $mem . pack("H*", substr($_, 8, -1));
+        $inobjd = 1;
+    } elsif (/^OBJD-T: /) {
+        die "Internal error" if $inobjd == 1;
+        $mem = $mem . pack("H*", substr($_, 8, -1));
+        $inobjd = 2;
+    }
+    # ... which will always be followed by a blank line,
+    # at which point we should produce our dump.
+    elsif ($inobjd) {
+        # Rewrite the temp file in one go; it will usually be small.
+        sysseek $outh, 0, 0;
+        truncate $outh, 0;
+        syswrite $outh, $mem;
+
+        # Pipe from objdump...
+        open IN, "-|", objcommand();
+
+        # ... copying all but the first 7 lines of boilerplate to our stdout.
+	my $i = 0;
+	while (<IN>) {
+	    print if (++$i > 7);
+        }
+        close IN;
+        print "\n";
+
+        $mem = "";
+        $inobjd = 0;
+    } else {
+        print;
+    }
+}
commit c46ffd57a3e2c36c241b4c676aa7d9c706eb2dc3
Author: Richard Henderson <rth at twiddle.net>
Date:   Fri Aug 16 23:29:45 2013 -0700

    disas: Implement fallback to dump object code as hex
    
    The OBJD-[HT] tags will be used by a script to run the hex blob
    through objdump --disassemble.
    
    Signed-off-by: Richard Henderson <rth at twiddle.net>
    Signed-off-by: Edgar E. Iglesias <edgar.iglesias at gmail.com>

diff --git a/disas.c b/disas.c
index 71007fb..0203ef2 100644
--- a/disas.c
+++ b/disas.c
@@ -158,6 +158,35 @@ print_insn_thumb1(bfd_vma pc, disassemble_info *info)
 }
 #endif
 
+static int print_insn_objdump(bfd_vma pc, disassemble_info *info,
+                              const char *prefix)
+{
+    int i, n = info->buffer_length;
+    uint8_t *buf = g_malloc(n);
+
+    info->read_memory_func(pc, buf, n, info);
+
+    for (i = 0; i < n; ++i) {
+        if (i % 32 == 0) {
+            info->fprintf_func(info->stream, "\n%s: ", prefix);
+        }
+        info->fprintf_func(info->stream, "%02x", buf[i]);
+    }
+
+    g_free(buf);
+    return n;
+}
+
+static int print_insn_od_host(bfd_vma pc, disassemble_info *info)
+{
+    return print_insn_objdump(pc, info, "OBJD-H");
+}
+
+static int print_insn_od_target(bfd_vma pc, disassemble_info *info)
+{
+    return print_insn_objdump(pc, info, "OBJD-T");
+}
+
 /* Disassemble this for me please... (debugging). 'flags' has the following
    values:
     i386 - 1 means 16 bit code, 2 means 64 bit code
@@ -171,7 +200,7 @@ void target_disas(FILE *out, CPUArchState *env, target_ulong code,
     target_ulong pc;
     int count;
     CPUDebug s;
-    int (*print_insn)(bfd_vma pc, disassemble_info *info);
+    int (*print_insn)(bfd_vma pc, disassemble_info *info) = NULL;
 
     INIT_DISASSEMBLE_INFO(s.info, out, fprintf);
 
@@ -263,11 +292,10 @@ void target_disas(FILE *out, CPUArchState *env, target_ulong code,
 #elif defined(TARGET_LM32)
     s.info.mach = bfd_mach_lm32;
     print_insn = print_insn_lm32;
-#else
-    fprintf(out, "0x" TARGET_FMT_lx
-	    ": Asm output not supported on this arch\n", code);
-    return;
 #endif
+    if (print_insn == NULL) {
+        print_insn = print_insn_od_target;
+    }
 
     for (pc = code; size > 0; pc += count, size -= count) {
 	fprintf(out, "0x" TARGET_FMT_lx ":  ", pc);
@@ -303,7 +331,7 @@ void disas(FILE *out, void *code, unsigned long size)
     uintptr_t pc;
     int count;
     CPUDebug s;
-    int (*print_insn)(bfd_vma pc, disassemble_info *info);
+    int (*print_insn)(bfd_vma pc, disassemble_info *info) = NULL;
 
     INIT_DISASSEMBLE_INFO(s.info, out, fprintf);
     s.info.print_address_func = generic_print_host_address;
@@ -347,11 +375,10 @@ void disas(FILE *out, void *code, unsigned long size)
     print_insn = print_insn_hppa;
 #elif defined(__ia64__)
     print_insn = print_insn_ia64;
-#else
-    fprintf(out, "0x%lx: Asm output not supported on this arch\n",
-	    (long) code);
-    return;
 #endif
+    if (print_insn == NULL) {
+        print_insn = print_insn_od_host;
+    }
     for (pc = (uintptr_t)code; size > 0; pc += count, size -= count) {
         fprintf(out, "0x%08" PRIxPTR ":  ", pc);
         count = print_insn(pc, &s.info);
commit 867c47cbba5d5ff8f27cc22634f30da56d09c2c4
Author: Wei Yang <weiyang at linux.vnet.ibm.com>
Date:   Thu Aug 22 18:40:12 2013 +0200

    kvm: shorten the parameter list for get_real_device()
    
    get_real_device() has 5 parameters with the last 4 is contained in the first
    structure.
    
    This patch removes the last 4 parameters and directly use them from the first
    parameter.
    
    Acked-by: Alex Williamson <alex.williamson at redhat.com>
    Signed-off-by: Wei Yang <weiyang at linux.vnet.ibm.com>
    Signed-off-by: Paolo Bonzini <pbonzini at redhat.com>

diff --git a/hw/i386/kvm/pci-assign.c b/hw/i386/kvm/pci-assign.c
index ff33dc8..73941b2 100644
--- a/hw/i386/kvm/pci-assign.c
+++ b/hw/i386/kvm/pci-assign.c
@@ -568,8 +568,7 @@ static int get_real_device_id(const char *devpath, uint16_t *val)
     return get_real_id(devpath, "device", val);
 }
 
-static int get_real_device(AssignedDevice *pci_dev, uint16_t r_seg,
-                           uint8_t r_bus, uint8_t r_dev, uint8_t r_func)
+static int get_real_device(AssignedDevice *pci_dev)
 {
     char dir[128], name[128];
     int fd, r = 0, v;
@@ -582,7 +581,8 @@ static int get_real_device(AssignedDevice *pci_dev, uint16_t r_seg,
     dev->region_number = 0;
 
     snprintf(dir, sizeof(dir), "/sys/bus/pci/devices/%04x:%02x:%02x.%x/",
-             r_seg, r_bus, r_dev, r_func);
+             pci_dev->host.domain, pci_dev->host.bus,
+             pci_dev->host.slot, pci_dev->host.function);
 
     snprintf(name, sizeof(name), "%sconfig", dir);
 
@@ -1769,8 +1769,7 @@ static int assigned_initfn(struct PCIDevice *pci_dev)
     memcpy(dev->emulate_config_write, dev->emulate_config_read,
            sizeof(dev->emulate_config_read));
 
-    if (get_real_device(dev, dev->host.domain, dev->host.bus,
-                        dev->host.slot, dev->host.function)) {
+    if (get_real_device(dev)) {
         error_report("pci-assign: Error: Couldn't get real device (%s)!",
                      dev->dev.qdev.id);
         goto out;
commit b10577df13fa4a1b38ea6c1ea7b66c6dfd90a07a
Author: Stefan Hajnoczi <stefanha at redhat.com>
Date:   Thu Aug 22 15:28:36 2013 +0200

    win32-aio: drop win32_aio_flush_cb()
    
    The io_flush argument to qemu_aio_set_event_notifier() has been removed
    since the block layer learnt to drain requests by itself.  Fix the
    Windows build for win32-aio.o by updating the
    qemu_aio_set_event_notifier() call and dropping win32_aio_flush_cb().
    
    Reviewed-by: Stefan Weil <sw at weilnetz.de>
    Signed-off-by: Stefan Hajnoczi <stefanha at redhat.com>

diff --git a/block/win32-aio.c b/block/win32-aio.c
index fcb7c75..5d1d199 100644
--- a/block/win32-aio.c
+++ b/block/win32-aio.c
@@ -105,13 +105,6 @@ static void win32_aio_completion_cb(EventNotifier *e)
     }
 }
 
-static int win32_aio_flush_cb(EventNotifier *e)
-{
-    QEMUWin32AIOState *s = container_of(e, QEMUWin32AIOState, e);
-
-    return (s->count > 0) ? 1 : 0;
-}
-
 static void win32_aio_cancel(BlockDriverAIOCB *blockacb)
 {
     QEMUWin32AIOCB *waiocb = (QEMUWin32AIOCB *)blockacb;
@@ -201,8 +194,7 @@ QEMUWin32AIOState *win32_aio_init(void)
         goto out_close_efd;
     }
 
-    qemu_aio_set_event_notifier(&s->e, win32_aio_completion_cb,
-                                win32_aio_flush_cb);
+    qemu_aio_set_event_notifier(&s->e, win32_aio_completion_cb);
 
     return s;
 
commit 8b2d42d273ed0df2a34cfa29f47bc1f8cc3abb26
Author: Stefan Hajnoczi <stefanha at redhat.com>
Date:   Thu Aug 22 15:28:35 2013 +0200

    aio-win32: replace incorrect AioHandler->opaque usage with ->e
    
    The AioHandler->opaque field does not exist in aio-win32.c.  The code
    that uses it was incorrectly copied from aio-posix.c.  For Windows we
    can use AioHandler->e to match against AioContext->notifier.
    
    This patch fixes the Windows build for aio-win32.o.
    
    Reviewed-by: Stefan Weil <sw at weilnetz.de>
    Signed-off-by: Stefan Hajnoczi <stefanha at redhat.com>

diff --git a/aio-win32.c b/aio-win32.c
index 721fc25..f9cfbb7 100644
--- a/aio-win32.c
+++ b/aio-win32.c
@@ -129,7 +129,7 @@ bool aio_poll(AioContext *ctx, bool blocking)
             node->io_notify(node->e);
 
             /* aio_notify() does not count as progress */
-            if (node->opaque != &ctx->notifier) {
+            if (node->e != &ctx->notifier) {
                 progress = true;
             }
         }
@@ -195,7 +195,7 @@ bool aio_poll(AioContext *ctx, bool blocking)
                 node->io_notify(node->e);
 
                 /* aio_notify() does not count as progress */
-                if (node->opaque != &ctx->notifier) {
+                if (node->e != &ctx->notifier) {
                     progress = true;
                 }
             }
commit 91c68f143d6e707c5783b162292dce38ae358c19
Author: Alex Bligh <alex at alex.org.uk>
Date:   Thu Aug 22 19:59:16 2013 +0100

    aio / timers: remove dummy_io_handler_flush from tests/test-aio.c
    
    Remove dummy_io_handler_flush from tests/test-aio.c as it does
    nothing now.
    
    Signed-off-by: Alex Bligh <alex at alex.org.uk>
    Signed-off-by: Stefan Hajnoczi <stefanha at redhat.com>

diff --git a/tests/test-aio.c b/tests/test-aio.c
index 3ad2294..07a1f61 100644
--- a/tests/test-aio.c
+++ b/tests/test-aio.c
@@ -77,11 +77,6 @@ static void dummy_io_handler_read(void *opaque)
 {
 }
 
-static int dummy_io_handler_flush(void *opaque)
-{
-    return 1;
-}
-
 static void bh_delete_cb(void *opaque)
 {
     BHTestData *data = opaque;
@@ -382,7 +377,7 @@ static void test_timer_schedule(void)
      */
     g_assert(!pipe2(pipefd, O_NONBLOCK));
     aio_set_fd_handler(ctx, pipefd[0],
-                       dummy_io_handler_read, NULL, dummy_io_handler_flush);
+                       dummy_io_handler_read, NULL, NULL);
     aio_poll(ctx, false);
 
     aio_timer_init(ctx, &data.timer, data.clock_type,
@@ -723,7 +718,7 @@ static void test_source_timer_schedule(void)
      */
     g_assert(!pipe2(pipefd, O_NONBLOCK));
     aio_set_fd_handler(ctx, pipefd[0],
-                       dummy_io_handler_read, NULL, dummy_io_handler_flush);
+                       dummy_io_handler_read, NULL, NULL);
     do {} while (g_main_context_iteration(NULL, false));
 
     aio_timer_init(ctx, &data.timer, data.clock_type,
commit b4049b74b97f30fe944c63b5f158ec9e87bd2593
Author: Alex Bligh <alex at alex.org.uk>
Date:   Wed Aug 21 16:03:09 2013 +0100

    aio / timers: Remove legacy interface
    
    Remove the legacy interface from include/qemu/timers.h.
    
    Ensure struct QEMUClock is not exposed at all.
    
    Signed-off-by: Alex Bligh <alex at alex.org.uk>
    Signed-off-by: Stefan Hajnoczi <stefanha at redhat.com>

diff --git a/include/qemu/timer.h b/include/qemu/timer.h
index 705463a..e4934dd 100644
--- a/include/qemu/timer.h
+++ b/include/qemu/timer.h
@@ -45,7 +45,6 @@ typedef enum {
     QEMU_CLOCK_MAX
 } QEMUClockType;
 
-typedef struct QEMUClock QEMUClock;
 typedef struct QEMUTimerList QEMUTimerList;
 
 struct QEMUTimerListGroup {
@@ -67,20 +66,10 @@ struct QEMUTimer {
 extern QEMUTimerListGroup main_loop_tlg;
 
 /*
- * QEMUClock & QEMUClockType
+ * QEMUClockType
  */
 
-/**
- * qemu_clock_ptr:
- * @type: type of clock
- *
- * Translate a clock type into a pointer to QEMUClock object.
- *
- * Returns: a pointer to the QEMUClock object
- */
-QEMUClock *qemu_clock_ptr(QEMUClockType type);
-
-/**
+/*
  * qemu_clock_get_ns;
  * @type: the clock type
  *
@@ -655,205 +644,6 @@ static inline int64_t get_ticks_per_sec(void)
     return 1000000000LL;
 }
 
-/**************************************************
- * LEGACY API SECTION
- *
- * All these calls will be deleted in due course
- */
-
-/* These three clocks are maintained here with separate variable
- * names for compatibility only.
- */
-#define rt_clock (qemu_clock_ptr(QEMU_CLOCK_REALTIME))
-#define vm_clock (qemu_clock_ptr(QEMU_CLOCK_VIRTUAL))
-#define host_clock (qemu_clock_ptr(QEMU_CLOCK_HOST))
-
-/** LEGACY
- * qemu_get_clock_ns:
- * @clock: the clock to operate on
- *
- * Get the nanosecond value of a clock
- *
- * Returns: the clock value in nanoseconds
- */
-int64_t qemu_get_clock_ns(QEMUClock *clock);
-
-/** LEGACY
- * qemu_get_clock_ms:
- * @clock: the clock to operate on
- *
- * Get the millisecond value of a clock
- *
- * Returns: the clock value in milliseconds
- */
-static inline int64_t qemu_get_clock_ms(QEMUClock *clock)
-{
-    return qemu_get_clock_ns(clock) / SCALE_MS;
-}
-
-/** LEGACY
- * qemu_register_clock_reset_notifier:
- * @clock: the clock to operate on
- * @notifier: the notifier function
- *
- * Register a notifier function to call when the clock
- * concerned is reset.
- */
-void qemu_register_clock_reset_notifier(QEMUClock *clock,
-                                        Notifier *notifier);
-
-/** LEGACY
- * qemu_unregister_clock_reset_notifier:
- * @clock: the clock to operate on
- * @notifier: the notifier function
- *
- * Unregister a notifier function to call when the clock
- * concerned is reset.
- */
-void qemu_unregister_clock_reset_notifier(QEMUClock *clock,
-                                          Notifier *notifier);
-
-/** LEGACY
- * qemu_new_timer:
- * @clock: the clock to operate on
- * @scale: the scale of the clock
- * @cb: the callback function to call when the timer expires
- * @opaque: an opaque pointer to pass to the callback
- *
- * Produce a new timer attached to clock @clock. This is a legacy
- * function. Use timer_new instead.
- *
- * Returns: a pointer to the new timer allocated.
- */
-QEMUTimer *qemu_new_timer(QEMUClock *clock, int scale,
-                          QEMUTimerCB *cb, void *opaque);
-
-/** LEGACY
- * qemu_free_timer:
- * @ts: the timer to operate on
- *
- * free the timer @ts. @ts must not be active.
- *
- * This is a legacy function. Use timer_free instead.
- */
-static inline void qemu_free_timer(QEMUTimer *ts)
-{
-    timer_free(ts);
-}
-
-/** LEGACY
- * qemu_del_timer:
- * @ts: the timer to operate on
- *
- * Delete a timer. This makes it inactive. It does not free
- * memory.
- *
- * This is a legacy function. Use timer_del instead.
- */
-static inline void qemu_del_timer(QEMUTimer *ts)
-{
-    timer_del(ts);
-}
-
-/** LEGACY
- * qemu_mod_timer_ns:
- * @ts: the timer to operate on
- * @expire_time: the expiry time in nanoseconds
- *
- * Modify a timer such that the expiry time is @expire_time
- * as measured in nanoseconds
- *
- * This is a legacy function. Use timer_mod_ns.
- */
-static inline void qemu_mod_timer_ns(QEMUTimer *ts, int64_t expire_time)
-{
-    timer_mod_ns(ts, expire_time);
-}
-
-/** LEGACY
- * qemu_mod_timer:
- * @ts: the timer to operate on
- * @expire_time: the expiry time
- *
- * Modify a timer such that the expiry time is @expire_time
- * as measured in the timer's scale
- *
- * This is a legacy function. Use timer_mod.
- */
-static inline void qemu_mod_timer(QEMUTimer *ts, int64_t expire_time)
-{
-    timer_mod(ts, expire_time);
-}
-
-/** LEGACY
- * qemu_run_timers:
- * @clock: clock on which to operate
- *
- * Run all the timers associated with the default timer list
- * of a clock.
- *
- * Returns: true if any timer ran.
- */
-bool qemu_run_timers(QEMUClock *clock);
-
-/** LEGACY
- * qemu_new_timer_ns:
- * @clock: the clock to associate with the timer
- * @callback: the callback to call when the timer expires
- * @opaque: the opaque pointer to pass to the callback
- *
- * Create a new timer with nanosecond scale on the default timer list
- * associated with the clock.
- *
- * Returns: a pointer to the newly created timer
- */
-static inline QEMUTimer *qemu_new_timer_ns(QEMUClock *clock, QEMUTimerCB *cb,
-                                           void *opaque)
-{
-    return qemu_new_timer(clock, SCALE_NS, cb, opaque);
-}
-
-/** LEGACY
- * qemu_new_timer_us:
- * @clock: the clock to associate with the timer
- * @callback: the callback to call when the timer expires
- * @opaque: the opaque pointer to pass to the callback
- *
- * Create a new timer with microsecond scale on the default timer list
- * associated with the clock.
- *
- * Returns: a pointer to the newly created timer
- */
-static inline QEMUTimer *qemu_new_timer_us(QEMUClock *clock,
-                                           QEMUTimerCB *cb,
-                                           void *opaque)
-{
-    return qemu_new_timer(clock, SCALE_US, cb, opaque);
-}
-
-/** LEGACY
- * qemu_new_timer_ms:
- * @clock: the clock to associate with the timer
- * @callback: the callback to call when the timer expires
- * @opaque: the opaque pointer to pass to the callback
- *
- * Create a new timer with millisecond scale on the default timer list
- * associated with the clock.
- *
- * Returns: a pointer to the newly created timer
- */
-static inline QEMUTimer *qemu_new_timer_ms(QEMUClock *clock,
-                                           QEMUTimerCB *cb,
-                                           void *opaque)
-{
-    return qemu_new_timer(clock, SCALE_MS, cb, opaque);
-}
-
-/****************************************************
- * END OF LEGACY API SECTION
- */
-
-
 /*
  * Low level clock functions
  */
diff --git a/qemu-timer.c b/qemu-timer.c
index ed1763f..95ff47f 100644
--- a/qemu-timer.c
+++ b/qemu-timer.c
@@ -44,7 +44,7 @@
 /***********************************************************/
 /* timers */
 
-struct QEMUClock {
+typedef struct QEMUClock {
     QLIST_HEAD(, QEMUTimerList) timerlists;
 
     NotifierList reset_notifiers;
@@ -52,7 +52,7 @@ struct QEMUClock {
 
     QEMUClockType type;
     bool enabled;
-};
+} QEMUClock;
 
 QEMUTimerListGroup main_loop_tlg;
 QEMUClock qemu_clocks[QEMU_CLOCK_MAX];
@@ -80,7 +80,7 @@ struct QEMUTimerList {
  *
  * Returns: a pointer to the QEMUClock object
  */
-QEMUClock *qemu_clock_ptr(QEMUClockType type)
+static inline QEMUClock *qemu_clock_ptr(QEMUClockType type)
 {
     return &qemu_clocks[type];
 }
@@ -291,13 +291,6 @@ void timer_init(QEMUTimer *ts,
     ts->scale = scale;
 }
 
-QEMUTimer *qemu_new_timer(QEMUClock *clock, int scale,
-                          QEMUTimerCB *cb, void *opaque)
-{
-    return timer_new_tl(main_loop_tlg.tl[clock->type],
-                     scale, cb, opaque);
-}
-
 void timer_free(QEMUTimer *ts)
 {
     g_free(ts);
@@ -407,11 +400,6 @@ bool qemu_clock_run_timers(QEMUClockType type)
     return timerlist_run_timers(main_loop_tlg.tl[type]);
 }
 
-bool qemu_run_timers(QEMUClock *clock)
-{
-    return qemu_clock_run_timers(clock->type);
-}
-
 void timerlistgroup_init(QEMUTimerListGroup *tlg,
                          QEMUTimerListNotifyCB *cb, void *opaque)
 {
@@ -479,11 +467,6 @@ int64_t qemu_clock_get_ns(QEMUClockType type)
     }
 }
 
-int64_t qemu_get_clock_ns(QEMUClock *clock)
-{
-    return qemu_clock_get_ns(clock->type);
-}
-
 void qemu_clock_register_reset_notifier(QEMUClockType type,
                                         Notifier *notifier)
 {
@@ -497,18 +480,6 @@ void qemu_clock_unregister_reset_notifier(QEMUClockType type,
     notifier_remove(notifier);
 }
 
-void qemu_register_clock_reset_notifier(QEMUClock *clock,
-                                        Notifier *notifier)
-{
-    qemu_clock_register_reset_notifier(clock->type, notifier);
-}
-
-void qemu_unregister_clock_reset_notifier(QEMUClock *clock,
-                                          Notifier *notifier)
-{
-    qemu_clock_unregister_reset_notifier(clock->type, notifier);
-}
-
 void init_clocks(void)
 {
     QEMUClockType type;
commit bc72ad67543f5c5d39c005ff0ca72da37642a1fb
Author: Alex Bligh <alex at alex.org.uk>
Date:   Wed Aug 21 16:03:08 2013 +0100

    aio / timers: Switch entire codebase to the new timer API
    
    This is an autogenerated patch using scripts/switch-timer-api.
    
    Switch the entire code base to using the new timer API.
    
    Note this patch may introduce some line length issues.
    
    Signed-off-by: Alex Bligh <alex at alex.org.uk>
    Signed-off-by: Stefan Hajnoczi <stefanha at redhat.com>

diff --git a/arch_init.c b/arch_init.c
index 68a7ab7..2eaa286 100644
--- a/arch_init.c
+++ b/arch_init.c
@@ -392,7 +392,7 @@ static void migration_bitmap_sync(void)
     }
 
     if (!start_time) {
-        start_time = qemu_get_clock_ms(rt_clock);
+        start_time = qemu_clock_get_ms(QEMU_CLOCK_REALTIME);
     }
 
     trace_migration_bitmap_sync_start();
@@ -410,7 +410,7 @@ static void migration_bitmap_sync(void)
     trace_migration_bitmap_sync_end(migration_dirty_pages
                                     - num_dirty_pages_init);
     num_dirty_pages_period += migration_dirty_pages - num_dirty_pages_init;
-    end_time = qemu_get_clock_ms(rt_clock);
+    end_time = qemu_clock_get_ms(QEMU_CLOCK_REALTIME);
 
     /* more than 1 second = 1000 millisecons */
     if (end_time > start_time + 1000) {
@@ -672,7 +672,7 @@ static int ram_save_iterate(QEMUFile *f, void *opaque)
 
     ram_control_before_iterate(f, RAM_CONTROL_ROUND);
 
-    t0 = qemu_get_clock_ns(rt_clock);
+    t0 = qemu_clock_get_ns(QEMU_CLOCK_REALTIME);
     i = 0;
     while ((ret = qemu_file_rate_limit(f)) == 0) {
         int bytes_sent;
@@ -691,7 +691,7 @@ static int ram_save_iterate(QEMUFile *f, void *opaque)
            iterations
         */
         if ((i & 63) == 0) {
-            uint64_t t1 = (qemu_get_clock_ns(rt_clock) - t0) / 1000000;
+            uint64_t t1 = (qemu_clock_get_ns(QEMU_CLOCK_REALTIME) - t0) / 1000000;
             if (t1 > MAX_WAIT) {
                 DPRINTF("big wait: %" PRIu64 " milliseconds, %d iterations\n",
                         t1, i);
@@ -1217,11 +1217,11 @@ static void check_guest_throttling(void)
     }
 
     if (!t0)  {
-        t0 = qemu_get_clock_ns(rt_clock);
+        t0 = qemu_clock_get_ns(QEMU_CLOCK_REALTIME);
         return;
     }
 
-    t1 = qemu_get_clock_ns(rt_clock);
+    t1 = qemu_clock_get_ns(QEMU_CLOCK_REALTIME);
 
     /* If it has been more than 40 ms since the last time the guest
      * was throttled then do it again.
diff --git a/audio/audio.c b/audio/audio.c
index 02bb886..af4cdf6 100644
--- a/audio/audio.c
+++ b/audio/audio.c
@@ -1124,10 +1124,10 @@ static int audio_is_timer_needed (void)
 static void audio_reset_timer (AudioState *s)
 {
     if (audio_is_timer_needed ()) {
-        qemu_mod_timer (s->ts, qemu_get_clock_ns (vm_clock) + 1);
+        timer_mod (s->ts, qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL) + 1);
     }
     else {
-        qemu_del_timer (s->ts);
+        timer_del (s->ts);
     }
 }
 
@@ -1834,7 +1834,7 @@ static void audio_init (void)
     QLIST_INIT (&s->cap_head);
     atexit (audio_atexit);
 
-    s->ts = qemu_new_timer_ns (vm_clock, audio_timer, s);
+    s->ts = timer_new_ns(QEMU_CLOCK_VIRTUAL, audio_timer, s);
     if (!s->ts) {
         hw_error("Could not create audio timer\n");
     }
diff --git a/audio/noaudio.c b/audio/noaudio.c
index 9f23aa2..cb38662 100644
--- a/audio/noaudio.c
+++ b/audio/noaudio.c
@@ -46,7 +46,7 @@ static int no_run_out (HWVoiceOut *hw, int live)
     int64_t ticks;
     int64_t bytes;
 
-    now = qemu_get_clock_ns (vm_clock);
+    now = qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL);
     ticks = now - no->old_ticks;
     bytes = muldiv64 (ticks, hw->info.bytes_per_second, get_ticks_per_sec ());
     bytes = audio_MIN (bytes, INT_MAX);
@@ -102,7 +102,7 @@ static int no_run_in (HWVoiceIn *hw)
     int samples = 0;
 
     if (dead) {
-        int64_t now = qemu_get_clock_ns (vm_clock);
+        int64_t now = qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL);
         int64_t ticks = now - no->old_ticks;
         int64_t bytes =
             muldiv64 (ticks, hw->info.bytes_per_second, get_ticks_per_sec ());
diff --git a/audio/spiceaudio.c b/audio/spiceaudio.c
index bc24557..5af436c 100644
--- a/audio/spiceaudio.c
+++ b/audio/spiceaudio.c
@@ -81,7 +81,7 @@ static void spice_audio_fini (void *opaque)
 static void rate_start (SpiceRateCtl *rate)
 {
     memset (rate, 0, sizeof (*rate));
-    rate->start_ticks = qemu_get_clock_ns (vm_clock);
+    rate->start_ticks = qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL);
 }
 
 static int rate_get_samples (struct audio_pcm_info *info, SpiceRateCtl *rate)
@@ -91,7 +91,7 @@ static int rate_get_samples (struct audio_pcm_info *info, SpiceRateCtl *rate)
     int64_t bytes;
     int64_t samples;
 
-    now = qemu_get_clock_ns (vm_clock);
+    now = qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL);
     ticks = now - rate->start_ticks;
     bytes = muldiv64 (ticks, info->bytes_per_second, get_ticks_per_sec ());
     samples = (bytes - rate->bytes_sent) >> info->shift;
diff --git a/audio/wavaudio.c b/audio/wavaudio.c
index 950fa8f..6846a1a 100644
--- a/audio/wavaudio.c
+++ b/audio/wavaudio.c
@@ -52,7 +52,7 @@ static int wav_run_out (HWVoiceOut *hw, int live)
     int rpos, decr, samples;
     uint8_t *dst;
     struct st_sample *src;
-    int64_t now = qemu_get_clock_ns (vm_clock);
+    int64_t now = qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL);
     int64_t ticks = now - wav->old_ticks;
     int64_t bytes =
         muldiv64 (ticks, hw->info.bytes_per_second, get_ticks_per_sec ());
diff --git a/backends/baum.c b/backends/baum.c
index b08e1d5..1132899 100644
--- a/backends/baum.c
+++ b/backends/baum.c
@@ -315,7 +315,7 @@ static int baum_eat_packet(BaumDriverState *baum, const uint8_t *buf, int len)
         if (*cur++ != ESC) { \
             DPRINTF("Broken packet %#2x, tossing\n", req); \
             if (timer_pending(baum->cellCount_timer)) {    \
-                qemu_del_timer(baum->cellCount_timer);     \
+                timer_del(baum->cellCount_timer);     \
                 baum_cellCount_timer_cb(baum);             \
             } \
             return (cur - 2 - buf); \
@@ -334,7 +334,7 @@ static int baum_eat_packet(BaumDriverState *baum, const uint8_t *buf, int len)
         int i;
 
         /* Allow 100ms to complete the DisplayData packet */
-        qemu_mod_timer(baum->cellCount_timer, qemu_get_clock_ns(vm_clock) +
+        timer_mod(baum->cellCount_timer, qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL) +
                        get_ticks_per_sec() / 10);
         for (i = 0; i < baum->x * baum->y ; i++) {
             EAT(c);
@@ -348,7 +348,7 @@ static int baum_eat_packet(BaumDriverState *baum, const uint8_t *buf, int len)
                 c = '?';
             text[i] = c;
         }
-        qemu_del_timer(baum->cellCount_timer);
+        timer_del(baum->cellCount_timer);
 
         memset(zero, 0, sizeof(zero));
 
@@ -553,7 +553,7 @@ static void baum_close(struct CharDriverState *chr)
 {
     BaumDriverState *baum = chr->opaque;
 
-    qemu_free_timer(baum->cellCount_timer);
+    timer_free(baum->cellCount_timer);
     if (baum->brlapi) {
         brlapi__closeConnection(baum->brlapi);
         g_free(baum->brlapi);
@@ -588,7 +588,7 @@ CharDriverState *chr_baum_init(void)
         goto fail_handle;
     }
 
-    baum->cellCount_timer = qemu_new_timer_ns(vm_clock, baum_cellCount_timer_cb, baum);
+    baum->cellCount_timer = timer_new_ns(QEMU_CLOCK_VIRTUAL, baum_cellCount_timer_cb, baum);
 
     if (brlapi__getDisplaySize(handle, &baum->x, &baum->y) == -1) {
         brlapi_perror("baum_init: brlapi_getDisplaySize");
@@ -614,7 +614,7 @@ CharDriverState *chr_baum_init(void)
     return chr;
 
 fail:
-    qemu_free_timer(baum->cellCount_timer);
+    timer_free(baum->cellCount_timer);
     brlapi__closeConnection(handle);
 fail_handle:
     g_free(handle);
diff --git a/block.c b/block.c
index 1615d89..a387c1a 100644
--- a/block.c
+++ b/block.c
@@ -130,8 +130,8 @@ void bdrv_io_limits_disable(BlockDriverState *bs)
     do {} while (qemu_co_enter_next(&bs->throttled_reqs));
 
     if (bs->block_timer) {
-        qemu_del_timer(bs->block_timer);
-        qemu_free_timer(bs->block_timer);
+        timer_del(bs->block_timer);
+        timer_free(bs->block_timer);
         bs->block_timer = NULL;
     }
 
@@ -148,7 +148,7 @@ static void bdrv_block_timer(void *opaque)
 
 void bdrv_io_limits_enable(BlockDriverState *bs)
 {
-    bs->block_timer = qemu_new_timer_ns(vm_clock, bdrv_block_timer, bs);
+    bs->block_timer = timer_new_ns(QEMU_CLOCK_VIRTUAL, bdrv_block_timer, bs);
     bs->io_limits_enabled = true;
 }
 
@@ -180,8 +180,8 @@ static void bdrv_io_limits_intercept(BlockDriverState *bs,
      */
 
     while (bdrv_exceed_io_limits(bs, nb_sectors, is_write, &wait_time)) {
-        qemu_mod_timer(bs->block_timer,
-                       wait_time + qemu_get_clock_ns(vm_clock));
+        timer_mod(bs->block_timer,
+                       wait_time + qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL));
         qemu_co_queue_wait_insert_head(&bs->throttled_reqs);
     }
 
@@ -3747,7 +3747,7 @@ static bool bdrv_exceed_io_limits(BlockDriverState *bs, int nb_sectors,
     double   elapsed_time;
     int      bps_ret, iops_ret;
 
-    now = qemu_get_clock_ns(vm_clock);
+    now = qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL);
     if (now > bs->slice_end) {
         bs->slice_start = now;
         bs->slice_end   = now + BLOCK_IO_SLICE_TIME;
@@ -3767,7 +3767,7 @@ static bool bdrv_exceed_io_limits(BlockDriverState *bs, int nb_sectors,
             *wait = max_wait;
         }
 
-        now = qemu_get_clock_ns(vm_clock);
+        now = qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL);
         if (bs->slice_end < now + max_wait) {
             bs->slice_end = now + max_wait;
         }
diff --git a/block/iscsi.c b/block/iscsi.c
index 47a3adc..2bbee1f 100644
--- a/block/iscsi.c
+++ b/block/iscsi.c
@@ -960,7 +960,7 @@ static void iscsi_nop_timed_event(void *opaque)
         return;
     }
 
-    qemu_mod_timer(iscsilun->nop_timer, qemu_get_clock_ms(rt_clock) + NOP_INTERVAL);
+    timer_mod(iscsilun->nop_timer, qemu_clock_get_ms(QEMU_CLOCK_REALTIME) + NOP_INTERVAL);
     iscsi_set_events(iscsilun);
 }
 #endif
@@ -1173,8 +1173,8 @@ static int iscsi_open(BlockDriverState *bs, QDict *options, int flags)
 
 #if defined(LIBISCSI_FEATURE_NOP_COUNTER)
     /* Set up a timer for sending out iSCSI NOPs */
-    iscsilun->nop_timer = qemu_new_timer_ms(rt_clock, iscsi_nop_timed_event, iscsilun);
-    qemu_mod_timer(iscsilun->nop_timer, qemu_get_clock_ms(rt_clock) + NOP_INTERVAL);
+    iscsilun->nop_timer = timer_new_ms(QEMU_CLOCK_REALTIME, iscsi_nop_timed_event, iscsilun);
+    timer_mod(iscsilun->nop_timer, qemu_clock_get_ms(QEMU_CLOCK_REALTIME) + NOP_INTERVAL);
 #endif
 
 out:
@@ -1204,8 +1204,8 @@ static void iscsi_close(BlockDriverState *bs)
     struct iscsi_context *iscsi = iscsilun->iscsi;
 
     if (iscsilun->nop_timer) {
-        qemu_del_timer(iscsilun->nop_timer);
-        qemu_free_timer(iscsilun->nop_timer);
+        timer_del(iscsilun->nop_timer);
+        timer_free(iscsilun->nop_timer);
     }
     qemu_aio_set_fd_handler(iscsi_get_fd(iscsi), NULL, NULL, NULL);
     iscsi_destroy_context(iscsi);
@@ -1267,8 +1267,8 @@ static int iscsi_create(const char *filename, QEMUOptionParameter *options)
         goto out;
     }
     if (iscsilun->nop_timer) {
-        qemu_del_timer(iscsilun->nop_timer);
-        qemu_free_timer(iscsilun->nop_timer);
+        timer_del(iscsilun->nop_timer);
+        timer_free(iscsilun->nop_timer);
     }
     if (iscsilun->type != TYPE_DISK) {
         ret = -ENODEV;
diff --git a/block/mirror.c b/block/mirror.c
index ead567e..86de458 100644
--- a/block/mirror.c
+++ b/block/mirror.c
@@ -356,7 +356,7 @@ static void coroutine_fn mirror_run(void *opaque)
     }
 
     bdrv_dirty_iter_init(bs, &s->hbi);
-    last_pause_ns = qemu_get_clock_ns(rt_clock);
+    last_pause_ns = qemu_clock_get_ns(QEMU_CLOCK_REALTIME);
     for (;;) {
         uint64_t delay_ns;
         int64_t cnt;
@@ -374,7 +374,7 @@ static void coroutine_fn mirror_run(void *opaque)
          * We do so every SLICE_TIME nanoseconds, or when there is an error,
          * or when the source is clean, whichever comes first.
          */
-        if (qemu_get_clock_ns(rt_clock) - last_pause_ns < SLICE_TIME &&
+        if (qemu_clock_get_ns(QEMU_CLOCK_REALTIME) - last_pause_ns < SLICE_TIME &&
             s->common.iostatus == BLOCK_DEVICE_IO_STATUS_OK) {
             if (s->in_flight == MAX_IN_FLIGHT || s->buf_free_count == 0 ||
                 (cnt == 0 && s->in_flight > 0)) {
@@ -454,7 +454,7 @@ static void coroutine_fn mirror_run(void *opaque)
             s->common.cancelled = false;
             break;
         }
-        last_pause_ns = qemu_get_clock_ns(rt_clock);
+        last_pause_ns = qemu_clock_get_ns(QEMU_CLOCK_REALTIME);
     }
 
 immediate_exit:
diff --git a/block/qed.c b/block/qed.c
index f767b05..cc904c4 100644
--- a/block/qed.c
+++ b/block/qed.c
@@ -353,10 +353,10 @@ static void qed_start_need_check_timer(BDRVQEDState *s)
 {
     trace_qed_start_need_check_timer(s);
 
-    /* Use vm_clock so we don't alter the image file while suspended for
+    /* Use QEMU_CLOCK_VIRTUAL so we don't alter the image file while suspended for
      * migration.
      */
-    qemu_mod_timer(s->need_check_timer, qemu_get_clock_ns(vm_clock) +
+    timer_mod(s->need_check_timer, qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL) +
                    get_ticks_per_sec() * QED_NEED_CHECK_TIMEOUT);
 }
 
@@ -364,7 +364,7 @@ static void qed_start_need_check_timer(BDRVQEDState *s)
 static void qed_cancel_need_check_timer(BDRVQEDState *s)
 {
     trace_qed_cancel_need_check_timer(s);
-    qemu_del_timer(s->need_check_timer);
+    timer_del(s->need_check_timer);
 }
 
 static void bdrv_qed_rebind(BlockDriverState *bs)
@@ -494,7 +494,7 @@ static int bdrv_qed_open(BlockDriverState *bs, QDict *options, int flags)
         }
     }
 
-    s->need_check_timer = qemu_new_timer_ns(vm_clock,
+    s->need_check_timer = timer_new_ns(QEMU_CLOCK_VIRTUAL,
                                             qed_need_check_timer_cb, s);
 
 out:
@@ -518,7 +518,7 @@ static void bdrv_qed_close(BlockDriverState *bs)
     BDRVQEDState *s = bs->opaque;
 
     qed_cancel_need_check_timer(s);
-    qemu_free_timer(s->need_check_timer);
+    timer_free(s->need_check_timer);
 
     /* Ensure writes reach stable storage */
     bdrv_flush(bs->file);
diff --git a/blockdev.c b/blockdev.c
index d3500c6..121520e 100644
--- a/blockdev.c
+++ b/blockdev.c
@@ -1299,7 +1299,7 @@ void qmp_block_set_io_throttle(const char *device, int64_t bps, int64_t bps_rd,
         bdrv_io_limits_disable(bs);
     } else {
         if (bs->block_timer) {
-            qemu_mod_timer(bs->block_timer, qemu_get_clock_ns(vm_clock));
+            timer_mod(bs->block_timer, qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL));
         }
     }
 }
diff --git a/hmp.c b/hmp.c
index c45514b..fcca6ae 100644
--- a/hmp.c
+++ b/hmp.c
@@ -1195,13 +1195,13 @@ static void hmp_migrate_status_cb(void *opaque)
             monitor_flush(status->mon);
         }
 
-        qemu_mod_timer(status->timer, qemu_get_clock_ms(rt_clock) + 1000);
+        timer_mod(status->timer, qemu_clock_get_ms(QEMU_CLOCK_REALTIME) + 1000);
     } else {
         if (status->is_block_migration) {
             monitor_printf(status->mon, "\n");
         }
         monitor_resume(status->mon);
-        qemu_del_timer(status->timer);
+        timer_del(status->timer);
         g_free(status);
     }
 
@@ -1235,9 +1235,9 @@ void hmp_migrate(Monitor *mon, const QDict *qdict)
         status = g_malloc0(sizeof(*status));
         status->mon = mon;
         status->is_block_migration = blk || inc;
-        status->timer = qemu_new_timer_ms(rt_clock, hmp_migrate_status_cb,
+        status->timer = timer_new_ms(QEMU_CLOCK_REALTIME, hmp_migrate_status_cb,
                                           status);
-        qemu_mod_timer(status->timer, qemu_get_clock_ms(rt_clock));
+        timer_mod(status->timer, qemu_clock_get_ms(QEMU_CLOCK_REALTIME));
     }
 }
 
diff --git a/hw/acpi/core.c b/hw/acpi/core.c
index b07feda..7467b88 100644
--- a/hw/acpi/core.c
+++ b/hw/acpi/core.c
@@ -433,9 +433,9 @@ void acpi_pm_tmr_update(ACPIREGS *ar, bool enable)
     if (enable) {
         expire_time = muldiv64(ar->tmr.overflow_time, get_ticks_per_sec(),
                                PM_TIMER_FREQUENCY);
-        qemu_mod_timer(ar->tmr.timer, expire_time);
+        timer_mod(ar->tmr.timer, expire_time);
     } else {
-        qemu_del_timer(ar->tmr.timer);
+        timer_del(ar->tmr.timer);
     }
 }
 
@@ -481,7 +481,7 @@ void acpi_pm_tmr_init(ACPIREGS *ar, acpi_update_sci_fn update_sci,
                       MemoryRegion *parent)
 {
     ar->tmr.update_sci = update_sci;
-    ar->tmr.timer = qemu_new_timer_ns(vm_clock, acpi_pm_tmr_timer, ar);
+    ar->tmr.timer = timer_new_ns(QEMU_CLOCK_VIRTUAL, acpi_pm_tmr_timer, ar);
     memory_region_init_io(&ar->tmr.io, memory_region_owner(parent),
                           &acpi_pm_tmr_ops, ar, "acpi-tmr", 4);
     memory_region_add_subregion(parent, 8, &ar->tmr.io);
@@ -490,7 +490,7 @@ void acpi_pm_tmr_init(ACPIREGS *ar, acpi_update_sci_fn update_sci,
 void acpi_pm_tmr_reset(ACPIREGS *ar)
 {
     ar->tmr.overflow_time = 0;
-    qemu_del_timer(ar->tmr.timer);
+    timer_del(ar->tmr.timer);
 }
 
 /* ACPI PM1aCNT */
diff --git a/hw/alpha/typhoon.c b/hw/alpha/typhoon.c
index 2450045..aac9a32 100644
--- a/hw/alpha/typhoon.c
+++ b/hw/alpha/typhoon.c
@@ -833,7 +833,7 @@ PCIBus *typhoon_init(ram_addr_t ram_size, ISABus **isa_bus,
         AlphaCPU *cpu = cpus[i];
         s->cchip.cpu[i] = cpu;
         if (cpu != NULL) {
-            cpu->alarm_timer = qemu_new_timer_ns(vm_clock,
+            cpu->alarm_timer = timer_new_ns(QEMU_CLOCK_VIRTUAL,
                                                  typhoon_alarm_timer,
                                                  (void *)((uintptr_t)s + i));
         }
diff --git a/hw/arm/omap1.c b/hw/arm/omap1.c
index 864c07e..47511d2 100644
--- a/hw/arm/omap1.c
+++ b/hw/arm/omap1.c
@@ -99,7 +99,7 @@ struct omap_mpu_timer_s {
 
 static inline uint32_t omap_timer_read(struct omap_mpu_timer_s *timer)
 {
-    uint64_t distance = qemu_get_clock_ns(vm_clock) - timer->time;
+    uint64_t distance = qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL) - timer->time;
 
     if (timer->st && timer->enable && timer->rate)
         return timer->val - muldiv64(distance >> (timer->ptv + 1),
@@ -111,7 +111,7 @@ static inline uint32_t omap_timer_read(struct omap_mpu_timer_s *timer)
 static inline void omap_timer_sync(struct omap_mpu_timer_s *timer)
 {
     timer->val = omap_timer_read(timer);
-    timer->time = qemu_get_clock_ns(vm_clock);
+    timer->time = qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL);
 }
 
 static inline void omap_timer_update(struct omap_mpu_timer_s *timer)
@@ -130,11 +130,11 @@ static inline void omap_timer_update(struct omap_mpu_timer_s *timer)
          * in a busy loop when it wants to sleep just a couple of CPU
          * ticks.  */
         if (expires > (get_ticks_per_sec() >> 10) || timer->ar)
-            qemu_mod_timer(timer->timer, timer->time + expires);
+            timer_mod(timer->timer, timer->time + expires);
         else
             qemu_bh_schedule(timer->tick);
     } else
-        qemu_del_timer(timer->timer);
+        timer_del(timer->timer);
 }
 
 static void omap_timer_fire(void *opaque)
@@ -240,7 +240,7 @@ static const MemoryRegionOps omap_mpu_timer_ops = {
 
 static void omap_mpu_timer_reset(struct omap_mpu_timer_s *s)
 {
-    qemu_del_timer(s->timer);
+    timer_del(s->timer);
     s->enable = 0;
     s->reset_val = 31337;
     s->val = 0;
@@ -259,7 +259,7 @@ static struct omap_mpu_timer_s *omap_mpu_timer_init(MemoryRegion *system_memory,
 
     s->irq = irq;
     s->clk = clk;
-    s->timer = qemu_new_timer_ns(vm_clock, omap_timer_tick, s);
+    s->timer = timer_new_ns(QEMU_CLOCK_VIRTUAL, omap_timer_tick, s);
     s->tick = qemu_bh_new(omap_timer_fire, s);
     omap_mpu_timer_reset(s);
     omap_timer_clk_setup(s);
@@ -363,7 +363,7 @@ static const MemoryRegionOps omap_wd_timer_ops = {
 
 static void omap_wd_timer_reset(struct omap_watchdog_timer_s *s)
 {
-    qemu_del_timer(s->timer.timer);
+    timer_del(s->timer.timer);
     if (!s->mode)
         omap_clk_get(s->timer.clk);
     s->mode = 1;
@@ -388,7 +388,7 @@ static struct omap_watchdog_timer_s *omap_wd_timer_init(MemoryRegion *memory,
 
     s->timer.irq = irq;
     s->timer.clk = clk;
-    s->timer.timer = qemu_new_timer_ns(vm_clock, omap_timer_tick, &s->timer);
+    s->timer.timer = timer_new_ns(QEMU_CLOCK_VIRTUAL, omap_timer_tick, &s->timer);
     omap_wd_timer_reset(s);
     omap_timer_clk_setup(&s->timer);
 
@@ -475,7 +475,7 @@ static const MemoryRegionOps omap_os_timer_ops = {
 
 static void omap_os_timer_reset(struct omap_32khz_timer_s *s)
 {
-    qemu_del_timer(s->timer.timer);
+    timer_del(s->timer.timer);
     s->timer.enable = 0;
     s->timer.it_ena = 0;
     s->timer.reset_val = 0x00ffffff;
@@ -494,7 +494,7 @@ static struct omap_32khz_timer_s *omap_os_timer_init(MemoryRegion *memory,
 
     s->timer.irq = irq;
     s->timer.clk = clk;
-    s->timer.timer = qemu_new_timer_ns(vm_clock, omap_timer_tick, &s->timer);
+    s->timer.timer = timer_new_ns(QEMU_CLOCK_VIRTUAL, omap_timer_tick, &s->timer);
     omap_os_timer_reset(s);
     omap_timer_clk_setup(&s->timer);
 
@@ -600,7 +600,7 @@ static void omap_ulpd_pm_write(void *opaque, hwaddr addr,
     case 0x10:	/* GAUGING_CTRL */
         /* Bits 0 and 1 seem to be confused in the OMAP 310 TRM */
         if ((s->ulpd_pm_regs[addr >> 2] ^ value) & 1) {
-            now = qemu_get_clock_ns(vm_clock);
+            now = qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL);
 
             if (value & 1)
                 s->ulpd_gauge_start = now;
@@ -2881,7 +2881,7 @@ static void omap_rtc_tick(void *opaque)
     if (s->auto_comp && !s->current_tm.tm_sec && !s->current_tm.tm_min)
         s->tick += s->comp_reg * 1000 / 32768;
 
-    qemu_mod_timer(s->clk, s->tick);
+    timer_mod(s->clk, s->tick);
 }
 
 static void omap_rtc_reset(struct omap_rtc_s *s)
@@ -3009,7 +3009,7 @@ static void omap_mcbsp_source_tick(void *opaque)
     s->rx_req = s->rx_rate << bps[(s->rcr[0] >> 5) & 7];
 
     omap_mcbsp_rx_newdata(s);
-    qemu_mod_timer(s->source_timer, qemu_get_clock_ns(vm_clock) +
+    timer_mod(s->source_timer, qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL) +
                    get_ticks_per_sec());
 }
 
@@ -3025,7 +3025,7 @@ static void omap_mcbsp_rx_start(struct omap_mcbsp_s *s)
 
 static void omap_mcbsp_rx_stop(struct omap_mcbsp_s *s)
 {
-    qemu_del_timer(s->source_timer);
+    timer_del(s->source_timer);
 }
 
 static void omap_mcbsp_rx_done(struct omap_mcbsp_s *s)
@@ -3055,7 +3055,7 @@ static void omap_mcbsp_sink_tick(void *opaque)
     s->tx_req = s->tx_rate << bps[(s->xcr[0] >> 5) & 7];
 
     omap_mcbsp_tx_newdata(s);
-    qemu_mod_timer(s->sink_timer, qemu_get_clock_ns(vm_clock) +
+    timer_mod(s->sink_timer, qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL) +
                    get_ticks_per_sec());
 }
 
@@ -3082,7 +3082,7 @@ static void omap_mcbsp_tx_stop(struct omap_mcbsp_s *s)
 {
     s->tx_req = 0;
     omap_mcbsp_tx_done(s);
-    qemu_del_timer(s->sink_timer);
+    timer_del(s->sink_timer);
 }
 
 static void omap_mcbsp_req_update(struct omap_mcbsp_s *s)
@@ -3432,8 +3432,8 @@ static void omap_mcbsp_reset(struct omap_mcbsp_s *s)
     s->rx_req = 0;
     s->tx_rate = 0;
     s->rx_rate = 0;
-    qemu_del_timer(s->source_timer);
-    qemu_del_timer(s->sink_timer);
+    timer_del(s->source_timer);
+    timer_del(s->sink_timer);
 }
 
 static struct omap_mcbsp_s *omap_mcbsp_init(MemoryRegion *system_memory,
@@ -3448,8 +3448,8 @@ static struct omap_mcbsp_s *omap_mcbsp_init(MemoryRegion *system_memory,
     s->rxirq = rxirq;
     s->txdrq = dma[0];
     s->rxdrq = dma[1];
-    s->sink_timer = qemu_new_timer_ns(vm_clock, omap_mcbsp_sink_tick, s);
-    s->source_timer = qemu_new_timer_ns(vm_clock, omap_mcbsp_source_tick, s);
+    s->sink_timer = timer_new_ns(QEMU_CLOCK_VIRTUAL, omap_mcbsp_sink_tick, s);
+    s->source_timer = timer_new_ns(QEMU_CLOCK_VIRTUAL, omap_mcbsp_source_tick, s);
     omap_mcbsp_reset(s);
 
     memory_region_init_io(&s->iomem, NULL, &omap_mcbsp_ops, s, "omap-mcbsp", 0x800);
@@ -3503,9 +3503,9 @@ static void omap_lpg_tick(void *opaque)
     struct omap_lpg_s *s = opaque;
 
     if (s->cycle)
-        qemu_mod_timer(s->tm, qemu_get_clock_ms(vm_clock) + s->period - s->on);
+        timer_mod(s->tm, qemu_clock_get_ms(QEMU_CLOCK_VIRTUAL) + s->period - s->on);
     else
-        qemu_mod_timer(s->tm, qemu_get_clock_ms(vm_clock) + s->on);
+        timer_mod(s->tm, qemu_clock_get_ms(QEMU_CLOCK_VIRTUAL) + s->on);
 
     s->cycle = !s->cycle;
     printf("%s: LED is %s\n", __FUNCTION__, s->cycle ? "on" : "off");
@@ -3527,7 +3527,7 @@ static void omap_lpg_update(struct omap_lpg_s *s)
                         per[(s->control >> 3) & 7], 256) : 0;	/* ONCTRL */
     }
 
-    qemu_del_timer(s->tm);
+    timer_del(s->tm);
     if (on == period && s->on < s->period)
         printf("%s: LED is on\n", __FUNCTION__);
     else if (on == 0 && s->on)
@@ -3623,7 +3623,7 @@ static struct omap_lpg_s *omap_lpg_init(MemoryRegion *system_memory,
     struct omap_lpg_s *s = (struct omap_lpg_s *)
             g_malloc0(sizeof(struct omap_lpg_s));
 
-    s->tm = qemu_new_timer_ms(vm_clock, omap_lpg_tick, s);
+    s->tm = timer_new_ms(QEMU_CLOCK_VIRTUAL, omap_lpg_tick, s);
 
     omap_lpg_reset(s);
 
diff --git a/hw/arm/pxa2xx.c b/hw/arm/pxa2xx.c
index 331bc72..02b7016 100644
--- a/hw/arm/pxa2xx.c
+++ b/hw/arm/pxa2xx.c
@@ -335,7 +335,7 @@ static int pxa2xx_cpccnt_read(CPUARMState *env, const ARMCPRegInfo *ri,
 {
     PXA2xxState *s = (PXA2xxState *)ri->opaque;
     if (s->pmnc & 1) {
-        *value = qemu_get_clock_ns(vm_clock);
+        *value = qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL);
     } else {
         *value = 0;
     }
@@ -870,43 +870,43 @@ static inline void pxa2xx_rtc_alarm_update(PXA2xxRTCState *s,
                 uint32_t rtsr)
 {
     if ((rtsr & (1 << 2)) && !(rtsr & (1 << 0)))
-        qemu_mod_timer(s->rtc_hz, s->last_hz +
+        timer_mod(s->rtc_hz, s->last_hz +
                 (((s->rtar - s->last_rcnr) * 1000 *
                   ((s->rttr & 0xffff) + 1)) >> 15));
     else
-        qemu_del_timer(s->rtc_hz);
+        timer_del(s->rtc_hz);
 
     if ((rtsr & (1 << 5)) && !(rtsr & (1 << 4)))
-        qemu_mod_timer(s->rtc_rdal1, s->last_hz +
+        timer_mod(s->rtc_rdal1, s->last_hz +
                 (((s->rdar1 - s->last_rdcr) * 1000 *
                   ((s->rttr & 0xffff) + 1)) >> 15)); /* TODO: fixup */
     else
-        qemu_del_timer(s->rtc_rdal1);
+        timer_del(s->rtc_rdal1);
 
     if ((rtsr & (1 << 7)) && !(rtsr & (1 << 6)))
-        qemu_mod_timer(s->rtc_rdal2, s->last_hz +
+        timer_mod(s->rtc_rdal2, s->last_hz +
                 (((s->rdar2 - s->last_rdcr) * 1000 *
                   ((s->rttr & 0xffff) + 1)) >> 15)); /* TODO: fixup */
     else
-        qemu_del_timer(s->rtc_rdal2);
+        timer_del(s->rtc_rdal2);
 
     if ((rtsr & 0x1200) == 0x1200 && !(rtsr & (1 << 8)))
-        qemu_mod_timer(s->rtc_swal1, s->last_sw +
+        timer_mod(s->rtc_swal1, s->last_sw +
                         (s->swar1 - s->last_swcr) * 10); /* TODO: fixup */
     else
-        qemu_del_timer(s->rtc_swal1);
+        timer_del(s->rtc_swal1);
 
     if ((rtsr & 0x1800) == 0x1800 && !(rtsr & (1 << 10)))
-        qemu_mod_timer(s->rtc_swal2, s->last_sw +
+        timer_mod(s->rtc_swal2, s->last_sw +
                         (s->swar2 - s->last_swcr) * 10); /* TODO: fixup */
     else
-        qemu_del_timer(s->rtc_swal2);
+        timer_del(s->rtc_swal2);
 
     if ((rtsr & 0xc000) == 0xc000 && !(rtsr & (1 << 13)))
-        qemu_mod_timer(s->rtc_pi, s->last_pi +
+        timer_mod(s->rtc_pi, s->last_pi +
                         (s->piar & 0xffff) - s->last_rtcpicr);
     else
-        qemu_del_timer(s->rtc_pi);
+        timer_del(s->rtc_pi);
 }
 
 static inline void pxa2xx_rtc_hz_tick(void *opaque)
diff --git a/hw/arm/spitz.c b/hw/arm/spitz.c
index 34f9582..9b9ce95 100644
--- a/hw/arm/spitz.c
+++ b/hw/arm/spitz.c
@@ -393,7 +393,7 @@ static void spitz_keyboard_tick(void *opaque)
             s->fifopos = 0;
     }
 
-    qemu_mod_timer(s->kbdtimer, qemu_get_clock_ns(vm_clock) +
+    timer_mod(s->kbdtimer, qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL) +
                    get_ticks_per_sec() / 32);
 }
 
@@ -485,7 +485,7 @@ static void spitz_keyboard_register(PXA2xxState *cpu)
         qdev_connect_gpio_out(cpu->gpio, spitz_gpio_key_strobe[i],
                 qdev_get_gpio_in(dev, i));
 
-    qemu_mod_timer(s->kbdtimer, qemu_get_clock_ns(vm_clock));
+    timer_mod(s->kbdtimer, qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL));
 
     qemu_add_kbd_event_handler(spitz_keyboard_handler, s);
 }
@@ -505,7 +505,7 @@ static int spitz_keyboard_init(SysBusDevice *sbd)
 
     spitz_keyboard_pre_map(s);
 
-    s->kbdtimer = qemu_new_timer_ns(vm_clock, spitz_keyboard_tick, s);
+    s->kbdtimer = timer_new_ns(QEMU_CLOCK_VIRTUAL, spitz_keyboard_tick, s);
     qdev_init_gpio_in(dev, spitz_keyboard_strobe, SPITZ_KEY_STROBE_NUM);
     qdev_init_gpio_out(dev, s->sense, SPITZ_KEY_SENSE_NUM);
 
diff --git a/hw/arm/stellaris.c b/hw/arm/stellaris.c
index 79f6b4e..3237b30 100644
--- a/hw/arm/stellaris.c
+++ b/hw/arm/stellaris.c
@@ -78,14 +78,14 @@ static void gptm_update_irq(gptm_state *s)
 
 static void gptm_stop(gptm_state *s, int n)
 {
-    qemu_del_timer(s->timer[n]);
+    timer_del(s->timer[n]);
 }
 
 static void gptm_reload(gptm_state *s, int n, int reset)
 {
     int64_t tick;
     if (reset)
-        tick = qemu_get_clock_ns(vm_clock);
+        tick = qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL);
     else
         tick = s->tick[n];
 
@@ -103,7 +103,7 @@ static void gptm_reload(gptm_state *s, int n, int reset)
         hw_error("TODO: 16-bit timer mode 0x%x\n", s->mode[n]);
     }
     s->tick[n] = tick;
-    qemu_mod_timer(s->timer[n], tick);
+    timer_mod(s->timer[n], tick);
 }
 
 static void gptm_tick(void *opaque)
@@ -318,8 +318,8 @@ static int stellaris_gptm_init(SysBusDevice *sbd)
     sysbus_init_mmio(sbd, &s->iomem);
 
     s->opaque[0] = s->opaque[1] = s;
-    s->timer[0] = qemu_new_timer_ns(vm_clock, gptm_tick, &s->opaque[0]);
-    s->timer[1] = qemu_new_timer_ns(vm_clock, gptm_tick, &s->opaque[1]);
+    s->timer[0] = timer_new_ns(QEMU_CLOCK_VIRTUAL, gptm_tick, &s->opaque[0]);
+    s->timer[1] = timer_new_ns(QEMU_CLOCK_VIRTUAL, gptm_tick, &s->opaque[1]);
     vmstate_register(dev, -1, &vmstate_stellaris_gptm, s);
     return 0;
 }
diff --git a/hw/arm/strongarm.c b/hw/arm/strongarm.c
index 6528cc0..170d0ce 100644
--- a/hw/arm/strongarm.c
+++ b/hw/arm/strongarm.c
@@ -278,17 +278,17 @@ static void strongarm_rtc_hzupdate(StrongARMRTCState *s)
 static inline void strongarm_rtc_timer_update(StrongARMRTCState *s)
 {
     if ((s->rtsr & RTSR_HZE) && !(s->rtsr & RTSR_HZ)) {
-        qemu_mod_timer(s->rtc_hz, s->last_hz + 1000);
+        timer_mod(s->rtc_hz, s->last_hz + 1000);
     } else {
-        qemu_del_timer(s->rtc_hz);
+        timer_del(s->rtc_hz);
     }
 
     if ((s->rtsr & RTSR_ALE) && !(s->rtsr & RTSR_AL)) {
-        qemu_mod_timer(s->rtc_alarm, s->last_hz +
+        timer_mod(s->rtc_alarm, s->last_hz +
                 (((s->rtar - s->last_rcnr) * 1000 *
                   ((s->rttr & 0xffff) + 1)) >> 15));
     } else {
-        qemu_del_timer(s->rtc_alarm);
+        timer_del(s->rtc_alarm);
     }
 }
 
@@ -1085,8 +1085,8 @@ static void strongarm_uart_receive(void *opaque, const uint8_t *buf, int size)
     }
 
     /* call the timeout receive callback in 3 char transmit time */
-    qemu_mod_timer(s->rx_timeout_timer,
-                    qemu_get_clock_ns(vm_clock) + s->char_transmit_time * 3);
+    timer_mod(s->rx_timeout_timer,
+                    qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL) + s->char_transmit_time * 3);
 
     strongarm_uart_update_status(s);
     strongarm_uart_update_int_status(s);
@@ -1107,7 +1107,7 @@ static void strongarm_uart_event(void *opaque, int event)
 static void strongarm_uart_tx(void *opaque)
 {
     StrongARMUARTState *s = opaque;
-    uint64_t new_xmit_ts = qemu_get_clock_ns(vm_clock);
+    uint64_t new_xmit_ts = qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL);
 
     if (s->utcr3 & UTCR3_LBM) /* loopback */ {
         strongarm_uart_receive(s, &s->tx_fifo[s->tx_start], 1);
@@ -1118,7 +1118,7 @@ static void strongarm_uart_tx(void *opaque)
     s->tx_start = (s->tx_start + 1) % 8;
     s->tx_len--;
     if (s->tx_len) {
-        qemu_mod_timer(s->tx_timer, new_xmit_ts + s->char_transmit_time);
+        timer_mod(s->tx_timer, new_xmit_ts + s->char_transmit_time);
     }
     strongarm_uart_update_status(s);
     strongarm_uart_update_int_status(s);
@@ -1237,8 +1237,8 @@ static int strongarm_uart_init(SysBusDevice *dev)
     sysbus_init_mmio(dev, &s->iomem);
     sysbus_init_irq(dev, &s->irq);
 
-    s->rx_timeout_timer = qemu_new_timer_ns(vm_clock, strongarm_uart_rx_to, s);
-    s->tx_timer = qemu_new_timer_ns(vm_clock, strongarm_uart_tx, s);
+    s->rx_timeout_timer = timer_new_ns(QEMU_CLOCK_VIRTUAL, strongarm_uart_rx_to, s);
+    s->tx_timer = timer_new_ns(QEMU_CLOCK_VIRTUAL, strongarm_uart_tx, s);
 
     if (s->chr) {
         qemu_chr_add_handlers(s->chr,
@@ -1282,8 +1282,8 @@ static int strongarm_uart_post_load(void *opaque, int version_id)
 
     /* restart rx timeout timer */
     if (s->rx_len) {
-        qemu_mod_timer(s->rx_timeout_timer,
-                qemu_get_clock_ns(vm_clock) + s->char_transmit_time * 3);
+        timer_mod(s->rx_timeout_timer,
+                qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL) + s->char_transmit_time * 3);
     }
 
     return 0;
diff --git a/hw/audio/adlib.c b/hw/audio/adlib.c
index 0421d47..0c79247 100644
--- a/hw/audio/adlib.c
+++ b/hw/audio/adlib.c
@@ -173,7 +173,7 @@ static void timer_handler (int c, double interval_Sec)
     s->ticking[n] = 1;
 #ifdef DEBUG
     interval = get_ticks_per_sec () * interval_Sec;
-    exp = qemu_get_clock_ns (vm_clock) + interval;
+    exp = qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL) + interval;
     s->exp[n] = exp;
 #endif
 
diff --git a/hw/audio/intel-hda.c b/hw/audio/intel-hda.c
index 32e44ad..78f9d28 100644
--- a/hw/audio/intel-hda.c
+++ b/hw/audio/intel-hda.c
@@ -526,7 +526,7 @@ static void intel_hda_get_wall_clk(IntelHDAState *d, const IntelHDAReg *reg)
 {
     int64_t ns;
 
-    ns = qemu_get_clock_ns(vm_clock) - d->wall_base_ns;
+    ns = qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL) - d->wall_base_ns;
     d->wall_clk = (uint32_t)(ns * 24 / 1000);  /* 24 MHz */
 }
 
@@ -1111,7 +1111,7 @@ static void intel_hda_reset(DeviceState *dev)
     HDACodecDevice *cdev;
 
     intel_hda_regs_reset(d);
-    d->wall_base_ns = qemu_get_clock_ns(vm_clock);
+    d->wall_base_ns = qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL);
 
     /* reset codecs */
     QTAILQ_FOREACH(kid, &d->codecs.qbus.children, sibling) {
diff --git a/hw/audio/sb16.c b/hw/audio/sb16.c
index 3e58688..db79131 100644
--- a/hw/audio/sb16.c
+++ b/hw/audio/sb16.c
@@ -768,9 +768,9 @@ static void complete (SB16State *s)
                 }
                 else {
                     if (s->aux_ts) {
-                        qemu_mod_timer (
+                        timer_mod (
                             s->aux_ts,
-                            qemu_get_clock_ns (vm_clock) + ticks
+                            qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL) + ticks
                             );
                     }
                 }
@@ -1378,7 +1378,7 @@ static void sb16_realizefn (DeviceState *dev, Error **errp)
     s->csp_regs[9] = 0xf8;
 
     reset_mixer (s);
-    s->aux_ts = qemu_new_timer_ns (vm_clock, aux_timer, s);
+    s->aux_ts = timer_new_ns(QEMU_CLOCK_VIRTUAL, aux_timer, s);
     if (!s->aux_ts) {
         dolog ("warning: Could not create auxiliary timer\n");
     }
diff --git a/hw/block/fdc.c b/hw/block/fdc.c
index e35ed2e..c5a6c21 100644
--- a/hw/block/fdc.c
+++ b/hw/block/fdc.c
@@ -1647,8 +1647,8 @@ static void fdctrl_handle_readid(FDCtrl *fdctrl, int direction)
     FDrive *cur_drv = get_cur_drv(fdctrl);
 
     cur_drv->head = (fdctrl->fifo[1] >> 2) & 1;
-    qemu_mod_timer(fdctrl->result_timer,
-                   qemu_get_clock_ns(vm_clock) + (get_ticks_per_sec() / 50));
+    timer_mod(fdctrl->result_timer,
+                   qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL) + (get_ticks_per_sec() / 50));
 }
 
 static void fdctrl_handle_format_track(FDCtrl *fdctrl, int direction)
@@ -2108,7 +2108,7 @@ static void fdctrl_realize_common(FDCtrl *fdctrl, Error **errp)
     FLOPPY_DPRINTF("init controller\n");
     fdctrl->fifo = qemu_memalign(512, FD_SECTOR_LEN);
     fdctrl->fifo_size = 512;
-    fdctrl->result_timer = qemu_new_timer_ns(vm_clock,
+    fdctrl->result_timer = timer_new_ns(QEMU_CLOCK_VIRTUAL,
                                              fdctrl_result_timer, fdctrl);
 
     fdctrl->version = 0x90; /* Intel 82078 controller */
diff --git a/hw/block/nvme.c b/hw/block/nvme.c
index 0263e5c..5dee229 100644
--- a/hw/block/nvme.c
+++ b/hw/block/nvme.c
@@ -187,7 +187,7 @@ 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);
+    timer_mod(cq->timer, qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL) + 500);
 }
 
 static void nvme_rw_cb(void *opaque, int ret)
@@ -264,8 +264,8 @@ static uint16_t nvme_io_cmd(NvmeCtrl *n, NvmeCmd *cmd, NvmeRequest *req)
 static void nvme_free_sq(NvmeSQueue *sq, NvmeCtrl *n)
 {
     n->sq[sq->sqid] = NULL;
-    qemu_del_timer(sq->timer);
-    qemu_free_timer(sq->timer);
+    timer_del(sq->timer);
+    timer_free(sq->timer);
     g_free(sq->io_req);
     if (sq->sqid) {
         g_free(sq);
@@ -327,7 +327,7 @@ static void nvme_init_sq(NvmeSQueue *sq, NvmeCtrl *n, uint64_t dma_addr,
         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);
+    sq->timer = timer_new_ns(QEMU_CLOCK_VIRTUAL, nvme_process_sq, sq);
 
     assert(n->cq[cqid]);
     cq = n->cq[cqid];
@@ -369,8 +369,8 @@ static uint16_t nvme_create_sq(NvmeCtrl *n, NvmeCmd *cmd)
 static void nvme_free_cq(NvmeCQueue *cq, NvmeCtrl *n)
 {
     n->cq[cq->cqid] = NULL;
-    qemu_del_timer(cq->timer);
-    qemu_free_timer(cq->timer);
+    timer_del(cq->timer);
+    timer_free(cq->timer);
     msix_vector_unuse(&n->parent_obj, cq->vector);
     if (cq->cqid) {
         g_free(cq);
@@ -410,7 +410,7 @@ static void nvme_init_cq(NvmeCQueue *cq, NvmeCtrl *n, uint64_t dma_addr,
     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);
+    cq->timer = timer_new_ns(QEMU_CLOCK_VIRTUAL, nvme_post_cqes, cq);
 }
 
 static uint16_t nvme_create_cq(NvmeCtrl *n, NvmeCmd *cmd)
@@ -691,9 +691,9 @@ static void nvme_process_db(NvmeCtrl *n, hwaddr addr, int val)
         if (start_sqs) {
             NvmeSQueue *sq;
             QTAILQ_FOREACH(sq, &cq->sq_list, entry) {
-                qemu_mod_timer(sq->timer, qemu_get_clock_ns(vm_clock) + 500);
+                timer_mod(sq->timer, qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL) + 500);
             }
-            qemu_mod_timer(cq->timer, qemu_get_clock_ns(vm_clock) + 500);
+            timer_mod(cq->timer, qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL) + 500);
         }
 
         if (cq->tail != cq->head) {
@@ -714,7 +714,7 @@ static void nvme_process_db(NvmeCtrl *n, hwaddr addr, int val)
         }
 
         sq->tail = new_tail;
-        qemu_mod_timer(sq->timer, qemu_get_clock_ns(vm_clock) + 500);
+        timer_mod(sq->timer, qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL) + 500);
     }
 }
 
diff --git a/hw/block/pflash_cfi01.c b/hw/block/pflash_cfi01.c
index 825011d..018a967 100644
--- a/hw/block/pflash_cfi01.c
+++ b/hw/block/pflash_cfi01.c
@@ -613,7 +613,7 @@ static void pflash_cfi01_realize(DeviceState *dev, Error **errp)
         pfl->ro = 0;
     }
 
-    pfl->timer = qemu_new_timer_ns(vm_clock, pflash_timer, pfl);
+    pfl->timer = timer_new_ns(QEMU_CLOCK_VIRTUAL, pflash_timer, pfl);
     pfl->wcycle = 0;
     pfl->cmd = 0;
     pfl->status = 0;
diff --git a/hw/block/pflash_cfi02.c b/hw/block/pflash_cfi02.c
index 9fc02e3..99445b0 100644
--- a/hw/block/pflash_cfi02.c
+++ b/hw/block/pflash_cfi02.c
@@ -430,8 +430,8 @@ static void pflash_write (pflash_t *pfl, hwaddr offset,
             }
             pfl->status = 0x00;
             /* Let's wait 5 seconds before chip erase is done */
-            qemu_mod_timer(pfl->timer,
-                           qemu_get_clock_ns(vm_clock) + (get_ticks_per_sec() * 5));
+            timer_mod(pfl->timer,
+                           qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL) + (get_ticks_per_sec() * 5));
             break;
         case 0x30:
             /* Sector erase */
@@ -445,8 +445,8 @@ static void pflash_write (pflash_t *pfl, hwaddr offset,
             }
             pfl->status = 0x00;
             /* Let's wait 1/2 second before sector erase is done */
-            qemu_mod_timer(pfl->timer,
-                           qemu_get_clock_ns(vm_clock) + (get_ticks_per_sec() / 2));
+            timer_mod(pfl->timer,
+                           qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL) + (get_ticks_per_sec() / 2));
             break;
         default:
             DPRINTF("%s: invalid command %02x (wc 5)\n", __func__, cmd);
@@ -633,7 +633,7 @@ static void pflash_cfi02_realize(DeviceState *dev, Error **errp)
         pfl->ro = 0;
     }
 
-    pfl->timer = qemu_new_timer_ns(vm_clock, pflash_timer, pfl);
+    pfl->timer = timer_new_ns(QEMU_CLOCK_VIRTUAL, pflash_timer, pfl);
     pfl->wcycle = 0;
     pfl->cmd = 0;
     pfl->status = 0;
diff --git a/hw/bt/hci-csr.c b/hw/bt/hci-csr.c
index 16a25cb..7b9b916 100644
--- a/hw/bt/hci-csr.c
+++ b/hw/bt/hci-csr.c
@@ -87,7 +87,7 @@ static inline void csrhci_fifo_wake(struct csrhci_s *s)
     }
 
     if (s->out_len)
-        qemu_mod_timer(s->out_tm, qemu_get_clock_ns(vm_clock) + s->baud_delay);
+        timer_mod(s->out_tm, qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL) + s->baud_delay);
 }
 
 #define csrhci_out_packetz(s, len) memset(csrhci_out_packet(s, len), 0, len)
@@ -446,7 +446,7 @@ CharDriverState *uart_hci_init(qemu_irq wakeup)
     s->hci->evt_recv = csrhci_out_hci_packet_event;
     s->hci->acl_recv = csrhci_out_hci_packet_acl;
 
-    s->out_tm = qemu_new_timer_ns(vm_clock, csrhci_out_tick, s);
+    s->out_tm = timer_new_ns(QEMU_CLOCK_VIRTUAL, csrhci_out_tick, s);
     s->pins = qemu_allocate_irqs(csrhci_pins, s, __csrhci_pins);
     csrhci_reset(s);
 
diff --git a/hw/bt/hci.c b/hw/bt/hci.c
index b53cd5d..d1c0604 100644
--- a/hw/bt/hci.c
+++ b/hw/bt/hci.c
@@ -576,7 +576,7 @@ static void bt_hci_inquiry_result(struct bt_hci_s *hci,
 
 static void bt_hci_mod_timer_1280ms(QEMUTimer *timer, int period)
 {
-    qemu_mod_timer(timer, qemu_get_clock_ns(vm_clock) +
+    timer_mod(timer, qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL) +
                    muldiv64(period << 7, get_ticks_per_sec(), 100));
 }
 
@@ -657,7 +657,7 @@ static void bt_hci_lmp_link_establish(struct bt_hci_s *hci,
     if (master) {
         link->acl_mode = acl_active;
         hci->lm.handle[hci->lm.last_handle].acl_mode_timer =
-                qemu_new_timer_ns(vm_clock, bt_hci_mode_tick, link);
+                timer_new_ns(QEMU_CLOCK_VIRTUAL, bt_hci_mode_tick, link);
     }
 }
 
@@ -667,8 +667,8 @@ static void bt_hci_lmp_link_teardown(struct bt_hci_s *hci, uint16_t handle)
     hci->lm.handle[handle].link = NULL;
 
     if (bt_hci_role_master(hci, handle)) {
-        qemu_del_timer(hci->lm.handle[handle].acl_mode_timer);
-        qemu_free_timer(hci->lm.handle[handle].acl_mode_timer);
+        timer_del(hci->lm.handle[handle].acl_mode_timer);
+        timer_free(hci->lm.handle[handle].acl_mode_timer);
     }
 }
 
@@ -1080,7 +1080,7 @@ static int bt_hci_mode_change(struct bt_hci_s *hci, uint16_t handle,
 
     bt_hci_event_status(hci, HCI_SUCCESS);
 
-    qemu_mod_timer(link->acl_mode_timer, qemu_get_clock_ns(vm_clock) +
+    timer_mod(link->acl_mode_timer, qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL) +
                    muldiv64(interval * 625, get_ticks_per_sec(), 1000000));
     bt_hci_lmp_mode_change_master(hci, link->link, mode, interval);
 
@@ -1103,7 +1103,7 @@ static int bt_hci_mode_cancel(struct bt_hci_s *hci, uint16_t handle, int mode)
 
     bt_hci_event_status(hci, HCI_SUCCESS);
 
-    qemu_del_timer(link->acl_mode_timer);
+    timer_del(link->acl_mode_timer);
     bt_hci_lmp_mode_change_master(hci, link->link, acl_active, 0);
 
     return 0;
@@ -1146,10 +1146,10 @@ static void bt_hci_reset(struct bt_hci_s *hci)
     hci->psb_handle = 0x000;
     hci->asb_handle = 0x000;
 
-    /* XXX: qemu_del_timer(sl->acl_mode_timer); for all links */
-    qemu_del_timer(hci->lm.inquiry_done);
-    qemu_del_timer(hci->lm.inquiry_next);
-    qemu_del_timer(hci->conn_accept_timer);
+    /* XXX: timer_del(sl->acl_mode_timer); for all links */
+    timer_del(hci->lm.inquiry_done);
+    timer_del(hci->lm.inquiry_next);
+    timer_del(hci->conn_accept_timer);
 }
 
 static void bt_hci_read_local_version_rp(struct bt_hci_s *hci)
@@ -1514,7 +1514,7 @@ static void bt_submit_hci(struct HCIInfo *info,
         }
 
         hci->lm.inquire = 0;
-        qemu_del_timer(hci->lm.inquiry_done);
+        timer_del(hci->lm.inquiry_done);
         bt_hci_event_complete_status(hci, HCI_SUCCESS);
         break;
 
@@ -1552,8 +1552,8 @@ static void bt_submit_hci(struct HCIInfo *info,
             break;
         }
         hci->lm.inquire = 0;
-        qemu_del_timer(hci->lm.inquiry_done);
-        qemu_del_timer(hci->lm.inquiry_next);
+        timer_del(hci->lm.inquiry_done);
+        timer_del(hci->lm.inquiry_next);
         bt_hci_event_complete_status(hci, HCI_SUCCESS);
         break;
 
@@ -2141,10 +2141,10 @@ struct HCIInfo *bt_new_hci(struct bt_scatternet_s *net)
 {
     struct bt_hci_s *s = g_malloc0(sizeof(struct bt_hci_s));
 
-    s->lm.inquiry_done = qemu_new_timer_ns(vm_clock, bt_hci_inquiry_done, s);
-    s->lm.inquiry_next = qemu_new_timer_ns(vm_clock, bt_hci_inquiry_next, s);
+    s->lm.inquiry_done = timer_new_ns(QEMU_CLOCK_VIRTUAL, bt_hci_inquiry_done, s);
+    s->lm.inquiry_next = timer_new_ns(QEMU_CLOCK_VIRTUAL, bt_hci_inquiry_next, s);
     s->conn_accept_timer =
-            qemu_new_timer_ns(vm_clock, bt_hci_conn_accept_timeout, s);
+            timer_new_ns(QEMU_CLOCK_VIRTUAL, bt_hci_conn_accept_timeout, s);
 
     s->evt_packet = bt_hci_evt_packet;
     s->evt_submit = bt_hci_evt_submit;
@@ -2209,9 +2209,9 @@ static void bt_hci_done(struct HCIInfo *info)
      * s->device.lmp_connection_complete to free the remaining bits once
      * hci->lm.awaiting_bdaddr[] is empty.  */
 
-    qemu_free_timer(hci->lm.inquiry_done);
-    qemu_free_timer(hci->lm.inquiry_next);
-    qemu_free_timer(hci->conn_accept_timer);
+    timer_free(hci->lm.inquiry_done);
+    timer_free(hci->lm.inquiry_next);
+    timer_free(hci->conn_accept_timer);
 
     g_free(hci);
 }
diff --git a/hw/bt/l2cap.c b/hw/bt/l2cap.c
index 521587a..2301d6f 100644
--- a/hw/bt/l2cap.c
+++ b/hw/bt/l2cap.c
@@ -166,9 +166,9 @@ static void l2cap_retransmission_timer_update(struct l2cap_chan_s *ch)
 {
 #if 0
     if (ch->mode != L2CAP_MODE_BASIC && ch->rexmit)
-        qemu_mod_timer(ch->retransmission_timer);
+        timer_mod(ch->retransmission_timer);
     else
-        qemu_del_timer(ch->retransmission_timer);
+        timer_del(ch->retransmission_timer);
 #endif
 }
 
@@ -176,9 +176,9 @@ static void l2cap_monitor_timer_update(struct l2cap_chan_s *ch)
 {
 #if 0
     if (ch->mode != L2CAP_MODE_BASIC && !ch->rexmit)
-        qemu_mod_timer(ch->monitor_timer);
+        timer_mod(ch->monitor_timer);
     else
-        qemu_del_timer(ch->monitor_timer);
+        timer_del(ch->monitor_timer);
 #endif
 }
 
diff --git a/hw/char/cadence_uart.c b/hw/char/cadence_uart.c
index 3c2e960..f8ccbdd 100644
--- a/hw/char/cadence_uart.c
+++ b/hw/char/cadence_uart.c
@@ -141,9 +141,9 @@ static void fifo_trigger_update(void *opaque)
 
 static void uart_tx_redo(UartState *s)
 {
-    uint64_t new_tx_time = qemu_get_clock_ns(vm_clock);
+    uint64_t new_tx_time = qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL);
 
-    qemu_mod_timer(s->tx_time_handle, new_tx_time + s->char_tx_time);
+    timer_mod(s->tx_time_handle, new_tx_time + s->char_tx_time);
 
     s->r[R_SR] |= UART_SR_INTR_TEMPTY;
 
@@ -265,7 +265,7 @@ static void uart_ctrl_update(UartState *s)
 static void uart_write_rx_fifo(void *opaque, const uint8_t *buf, int size)
 {
     UartState *s = (UartState *)opaque;
-    uint64_t new_rx_time = qemu_get_clock_ns(vm_clock);
+    uint64_t new_rx_time = qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL);
     int i;
 
     if ((s->r[R_CR] & UART_CR_RX_DIS) || !(s->r[R_CR] & UART_CR_RX_EN)) {
@@ -291,7 +291,7 @@ static void uart_write_rx_fifo(void *opaque, const uint8_t *buf, int size)
                 s->r[R_SR] |= UART_SR_INTR_RTRIG;
             }
         }
-        qemu_mod_timer(s->fifo_trigger_handle, new_rx_time +
+        timer_mod(s->fifo_trigger_handle, new_rx_time +
                                                 (s->char_tx_time * 4));
     }
     uart_update_status(s);
@@ -452,10 +452,10 @@ static int cadence_uart_init(SysBusDevice *dev)
     sysbus_init_mmio(dev, &s->iomem);
     sysbus_init_irq(dev, &s->irq);
 
-    s->fifo_trigger_handle = qemu_new_timer_ns(vm_clock,
+    s->fifo_trigger_handle = timer_new_ns(QEMU_CLOCK_VIRTUAL,
             (QEMUTimerCB *)fifo_trigger_update, s);
 
-    s->tx_time_handle = qemu_new_timer_ns(vm_clock,
+    s->tx_time_handle = timer_new_ns(QEMU_CLOCK_VIRTUAL,
             (QEMUTimerCB *)uart_tx_write, s);
 
     s->char_tx_time = (get_ticks_per_sec() / 9600) * 10;
diff --git a/hw/char/serial.c b/hw/char/serial.c
index 6025592..3978020 100644
--- a/hw/char/serial.c
+++ b/hw/char/serial.c
@@ -188,7 +188,7 @@ static void serial_update_msl(SerialState *s)
     uint8_t omsr;
     int flags;
 
-    qemu_del_timer(s->modem_status_poll);
+    timer_del(s->modem_status_poll);
 
     if (qemu_chr_fe_ioctl(s->chr,CHR_IOCTL_SERIAL_GET_TIOCM, &flags) == -ENOTSUP) {
         s->poll_msl = -1;
@@ -215,7 +215,7 @@ static void serial_update_msl(SerialState *s)
        We'll be lazy and poll only every 10ms, and only poll it at all if MSI interrupts are turned on */
 
     if (s->poll_msl)
-        qemu_mod_timer(s->modem_status_poll, qemu_get_clock_ns(vm_clock) + get_ticks_per_sec() / 100);
+        timer_mod(s->modem_status_poll, qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL) + get_ticks_per_sec() / 100);
 }
 
 static gboolean serial_xmit(GIOChannel *chan, GIOCondition cond, void *opaque)
@@ -252,7 +252,7 @@ static gboolean serial_xmit(GIOChannel *chan, GIOCondition cond, void *opaque)
         s->tsr_retry = 0;
     }
 
-    s->last_xmit_ts = qemu_get_clock_ns(vm_clock);
+    s->last_xmit_ts = qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL);
 
     if (s->lsr & UART_LSR_THRE) {
         s->lsr |= UART_LSR_TEMT;
@@ -306,7 +306,7 @@ static void serial_ioport_write(void *opaque, hwaddr addr, uint64_t val,
                      s->poll_msl = 1;
                      serial_update_msl(s);
                 } else {
-                     qemu_del_timer(s->modem_status_poll);
+                     timer_del(s->modem_status_poll);
                      s->poll_msl = 0;
                 }
             }
@@ -329,7 +329,7 @@ static void serial_ioport_write(void *opaque, hwaddr addr, uint64_t val,
         /* FIFO clear */
 
         if (val & UART_FCR_RFR) {
-            qemu_del_timer(s->fifo_timeout_timer);
+            timer_del(s->fifo_timeout_timer);
             s->timeout_ipending=0;
             fifo8_reset(&s->recv_fifo);
         }
@@ -397,7 +397,7 @@ static void serial_ioport_write(void *opaque, hwaddr addr, uint64_t val,
                 qemu_chr_fe_ioctl(s->chr,CHR_IOCTL_SERIAL_SET_TIOCM, &flags);
                 /* Update the modem status after a one-character-send wait-time, since there may be a response
                    from the device/computer at the other end of the serial line */
-                qemu_mod_timer(s->modem_status_poll, qemu_get_clock_ns(vm_clock) + s->char_transmit_time);
+                timer_mod(s->modem_status_poll, qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL) + s->char_transmit_time);
             }
         }
         break;
@@ -429,7 +429,7 @@ static uint64_t serial_ioport_read(void *opaque, hwaddr addr, unsigned size)
                 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);
+                    timer_mod(s->fifo_timeout_timer, qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL) + s->char_transmit_time * 4);
                 }
                 s->timeout_ipending = 0;
             } else {
@@ -556,7 +556,7 @@ static void serial_receive1(void *opaque, const uint8_t *buf, int size)
         }
         s->lsr |= UART_LSR_DR;
         /* call the timeout receive callback in 4 char transmit time */
-        qemu_mod_timer(s->fifo_timeout_timer, qemu_get_clock_ns (vm_clock) + s->char_transmit_time * 4);
+        timer_mod(s->fifo_timeout_timer, qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL) + s->char_transmit_time * 4);
     } else {
         if (s->lsr & UART_LSR_DR)
             s->lsr |= UART_LSR_OE;
@@ -635,7 +635,7 @@ static void serial_reset(void *opaque)
     fifo8_reset(&s->recv_fifo);
     fifo8_reset(&s->xmit_fifo);
 
-    s->last_xmit_ts = qemu_get_clock_ns(vm_clock);
+    s->last_xmit_ts = qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL);
 
     s->thr_ipending = 0;
     s->last_break_enable = 0;
@@ -649,9 +649,9 @@ void serial_realize_core(SerialState *s, Error **errp)
         return;
     }
 
-    s->modem_status_poll = qemu_new_timer_ns(vm_clock, (QEMUTimerCB *) serial_update_msl, s);
+    s->modem_status_poll = timer_new_ns(QEMU_CLOCK_VIRTUAL, (QEMUTimerCB *) serial_update_msl, s);
 
-    s->fifo_timeout_timer = qemu_new_timer_ns(vm_clock, (QEMUTimerCB *) fifo_timeout_int, s);
+    s->fifo_timeout_timer = timer_new_ns(QEMU_CLOCK_VIRTUAL, (QEMUTimerCB *) fifo_timeout_int, s);
     qemu_register_reset(serial_reset, s);
 
     qemu_chr_add_handlers(s->chr, serial_can_receive1, serial_receive1,
diff --git a/hw/char/virtio-serial-bus.c b/hw/char/virtio-serial-bus.c
index da417c7..f23f555 100644
--- a/hw/char/virtio-serial-bus.c
+++ b/hw/char/virtio-serial-bus.c
@@ -603,7 +603,7 @@ static void virtio_serial_post_load_timer_cb(void *opaque)
         }
     }
     g_free(s->post_load->connected);
-    qemu_free_timer(s->post_load->timer);
+    timer_free(s->post_load->timer);
     g_free(s->post_load);
     s->post_load = NULL;
 }
@@ -618,7 +618,7 @@ static int fetch_active_ports_list(QEMUFile *f, int version_id,
     s->post_load->connected =
         g_malloc0(sizeof(*s->post_load->connected) * nr_active_ports);
 
-    s->post_load->timer = qemu_new_timer_ns(vm_clock,
+    s->post_load->timer = timer_new_ns(QEMU_CLOCK_VIRTUAL,
                                             virtio_serial_post_load_timer_cb,
                                             s);
 
@@ -660,7 +660,7 @@ static int fetch_active_ports_list(QEMUFile *f, int version_id,
             }
         }
     }
-    qemu_mod_timer(s->post_load->timer, 1);
+    timer_mod(s->post_load->timer, 1);
     return 0;
 }
 
@@ -999,8 +999,8 @@ static int virtio_serial_device_exit(DeviceState *dev)
     g_free(vser->ports_map);
     if (vser->post_load) {
         g_free(vser->post_load->connected);
-        qemu_del_timer(vser->post_load->timer);
-        qemu_free_timer(vser->post_load->timer);
+        timer_del(vser->post_load->timer);
+        timer_free(vser->post_load->timer);
         g_free(vser->post_load);
     }
     virtio_cleanup(vdev);
diff --git a/hw/core/ptimer.c b/hw/core/ptimer.c
index 4bc96c9..3036bde 100644
--- a/hw/core/ptimer.c
+++ b/hw/core/ptimer.c
@@ -48,7 +48,7 @@ static void ptimer_reload(ptimer_state *s)
     if (s->period_frac) {
         s->next_event += ((int64_t)s->period_frac * s->delta) >> 32;
     }
-    qemu_mod_timer(s->timer, s->next_event);
+    timer_mod(s->timer, s->next_event);
 }
 
 static void ptimer_tick(void *opaque)
@@ -69,7 +69,7 @@ uint64_t ptimer_get_count(ptimer_state *s)
     uint64_t counter;
 
     if (s->enabled) {
-        now = qemu_get_clock_ns(vm_clock);
+        now = qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL);
         /* Figure out the current counter value.  */
         if (now - s->next_event > 0
             || s->period == 0) {
@@ -123,7 +123,7 @@ void ptimer_set_count(ptimer_state *s, uint64_t count)
 {
     s->delta = count;
     if (s->enabled) {
-        s->next_event = qemu_get_clock_ns(vm_clock);
+        s->next_event = qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL);
         ptimer_reload(s);
     }
 }
@@ -138,7 +138,7 @@ void ptimer_run(ptimer_state *s, int oneshot)
         return;
     }
     s->enabled = oneshot ? 2 : 1;
-    s->next_event = qemu_get_clock_ns(vm_clock);
+    s->next_event = qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL);
     ptimer_reload(s);
 }
 
@@ -150,7 +150,7 @@ void ptimer_stop(ptimer_state *s)
         return;
 
     s->delta = ptimer_get_count(s);
-    qemu_del_timer(s->timer);
+    timer_del(s->timer);
     s->enabled = 0;
 }
 
@@ -160,7 +160,7 @@ void ptimer_set_period(ptimer_state *s, int64_t period)
     s->period = period;
     s->period_frac = 0;
     if (s->enabled) {
-        s->next_event = qemu_get_clock_ns(vm_clock);
+        s->next_event = qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL);
         ptimer_reload(s);
     }
 }
@@ -171,7 +171,7 @@ void ptimer_set_freq(ptimer_state *s, uint32_t freq)
     s->period = 1000000000ll / freq;
     s->period_frac = (1000000000ll << 32) / freq;
     if (s->enabled) {
-        s->next_event = qemu_get_clock_ns(vm_clock);
+        s->next_event = qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL);
         ptimer_reload(s);
     }
 }
@@ -197,7 +197,7 @@ void ptimer_set_limit(ptimer_state *s, uint64_t limit, int reload)
     if (reload)
         s->delta = limit;
     if (s->enabled && reload) {
-        s->next_event = qemu_get_clock_ns(vm_clock);
+        s->next_event = qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL);
         ptimer_reload(s);
     }
 }
@@ -226,6 +226,6 @@ ptimer_state *ptimer_init(QEMUBH *bh)
 
     s = (ptimer_state *)g_malloc0(sizeof(ptimer_state));
     s->bh = bh;
-    s->timer = qemu_new_timer_ns(vm_clock, ptimer_tick, s);
+    s->timer = timer_new_ns(QEMU_CLOCK_VIRTUAL, ptimer_tick, s);
     return s;
 }
diff --git a/hw/display/qxl-logger.c b/hw/display/qxl-logger.c
index 3cd85d9..c900c2c 100644
--- a/hw/display/qxl-logger.c
+++ b/hw/display/qxl-logger.c
@@ -242,7 +242,7 @@ int qxl_log_command(PCIQXLDevice *qxl, const char *ring, QXLCommandExt *ext)
     if (!qxl->cmdlog) {
         return 0;
     }
-    fprintf(stderr, "%" PRId64 " qxl-%d/%s:", qemu_get_clock_ns(vm_clock),
+    fprintf(stderr, "%" PRId64 " qxl-%d/%s:", qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL),
             qxl->id, ring);
     fprintf(stderr, " cmd @ 0x%" PRIx64 " %s%s", ext->cmd.data,
             qxl_name(qxl_type, ext->cmd.type),
diff --git a/hw/display/qxl.c b/hw/display/qxl.c
index c537057..7649f2b 100644
--- a/hw/display/qxl.c
+++ b/hw/display/qxl.c
@@ -1596,7 +1596,7 @@ async_common:
         trace_qxl_io_log(d->id, d->ram->log_buf);
         if (d->guestdebug) {
             fprintf(stderr, "qxl/guest-%d: %" PRId64 ": %s", d->id,
-                    qemu_get_clock_ns(vm_clock), d->ram->log_buf);
+                    qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL), d->ram->log_buf);
         }
         break;
     case QXL_IO_RESET:
diff --git a/hw/display/vga.c b/hw/display/vga.c
index 06f44a8..7b91d9c 100644
--- a/hw/display/vga.c
+++ b/hw/display/vga.c
@@ -318,7 +318,7 @@ static uint8_t vga_precise_retrace(VGACommonState *s)
         int cur_line, cur_line_char, cur_char;
         int64_t cur_tick;
 
-        cur_tick = qemu_get_clock_ns(vm_clock);
+        cur_tick = qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL);
 
         cur_char = (cur_tick / r->ticks_per_char) % r->total_chars;
         cur_line = cur_char / r->htotal;
@@ -1304,7 +1304,7 @@ static void vga_draw_text(VGACommonState *s, int full_update)
     uint32_t *ch_attr_ptr;
     vga_draw_glyph8_func *vga_draw_glyph8;
     vga_draw_glyph9_func *vga_draw_glyph9;
-    int64_t now = qemu_get_clock_ms(vm_clock);
+    int64_t now = qemu_clock_get_ms(QEMU_CLOCK_VIRTUAL);
 
     /* compute font data address (in plane 2) */
     v = s->sr[VGA_SEQ_CHARACTER_MAP];
@@ -1907,7 +1907,7 @@ static void vga_update_display(void *opaque)
         }
         if (graphic_mode != s->graphic_mode) {
             s->graphic_mode = graphic_mode;
-            s->cursor_blink_time = qemu_get_clock_ms(vm_clock);
+            s->cursor_blink_time = qemu_clock_get_ms(QEMU_CLOCK_VIRTUAL);
             full_update = 1;
         }
         switch(graphic_mode) {
diff --git a/hw/dma/pl330.c b/hw/dma/pl330.c
index ddcc413..401399d 100644
--- a/hw/dma/pl330.c
+++ b/hw/dma/pl330.c
@@ -1256,7 +1256,7 @@ static void pl330_dma_stop_irq(void *opaque, int irq, int level)
 
     if (s->periph_busy[irq] != level) {
         s->periph_busy[irq] = level;
-        qemu_mod_timer(s->timer, qemu_get_clock_ns(vm_clock));
+        timer_mod(s->timer, qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL));
     }
 }
 
@@ -1519,7 +1519,7 @@ static void pl330_reset(DeviceState *d)
         s->periph_busy[i] = 0;
     }
 
-    qemu_del_timer(s->timer);
+    timer_del(s->timer);
 }
 
 static void pl330_realize(DeviceState *dev, Error **errp)
@@ -1532,7 +1532,7 @@ static void pl330_realize(DeviceState *dev, Error **errp)
                           "dma", PL330_IOMEM_SIZE);
     sysbus_init_mmio(SYS_BUS_DEVICE(dev), &s->iomem);
 
-    s->timer = qemu_new_timer_ns(vm_clock, pl330_exec_cycle_timer, s);
+    s->timer = timer_new_ns(QEMU_CLOCK_VIRTUAL, pl330_exec_cycle_timer, s);
 
     s->cfg[0] = (s->mgr_ns_at_rst ? 0x4 : 0) |
                 (s->num_periph_req > 0 ? 1 : 0) |
diff --git a/hw/dma/rc4030.c b/hw/dma/rc4030.c
index 4ec433f..af26632 100644
--- a/hw/dma/rc4030.c
+++ b/hw/dma/rc4030.c
@@ -107,7 +107,7 @@ static void set_next_tick(rc4030State *s)
 
     tm_hz = 1000 / (s->itr + 1);
 
-    qemu_mod_timer(s->periodic_timer, qemu_get_clock_ns(vm_clock) +
+    timer_mod(s->periodic_timer, qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL) +
                    get_ticks_per_sec() / tm_hz);
 }
 
@@ -806,7 +806,7 @@ void *rc4030_init(qemu_irq timer, qemu_irq jazz_bus,
     *irqs = qemu_allocate_irqs(rc4030_irq_jazz_request, s, 16);
     *dmas = rc4030_allocate_dmas(s, 4);
 
-    s->periodic_timer = qemu_new_timer_ns(vm_clock, rc4030_periodic_timer, s);
+    s->periodic_timer = timer_new_ns(QEMU_CLOCK_VIRTUAL, rc4030_periodic_timer, s);
     s->timer_irq = timer;
     s->jazz_bus_irq = jazz_bus;
 
diff --git a/hw/dma/soc_dma.c b/hw/dma/soc_dma.c
index 5e3491d..c06aabb 100644
--- a/hw/dma/soc_dma.c
+++ b/hw/dma/soc_dma.c
@@ -84,10 +84,10 @@ struct dma_s {
 
 static void soc_dma_ch_schedule(struct soc_dma_ch_s *ch, int delay_bytes)
 {
-    int64_t now = qemu_get_clock_ns(vm_clock);
+    int64_t now = qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL);
     struct dma_s *dma = (struct dma_s *) ch->dma;
 
-    qemu_mod_timer(ch->timer, now + delay_bytes / dma->channel_freq);
+    timer_mod(ch->timer, now + delay_bytes / dma->channel_freq);
 }
 
 static void soc_dma_ch_run(void *opaque)
@@ -217,7 +217,7 @@ void soc_dma_set_request(struct soc_dma_ch_s *ch, int level)
         ch->enable = level;
 
         if (!ch->enable)
-            qemu_del_timer(ch->timer);
+            timer_del(ch->timer);
         else if (!ch->running)
             soc_dma_ch_run(ch);
         else
@@ -246,7 +246,7 @@ struct soc_dma_s *soc_dma_init(int n)
     for (i = 0; i < n; i ++) {
         s->ch[i].dma = &s->soc;
         s->ch[i].num = i;
-        s->ch[i].timer = qemu_new_timer_ns(vm_clock, soc_dma_ch_run, &s->ch[i]);
+        s->ch[i].timer = timer_new_ns(QEMU_CLOCK_VIRTUAL, soc_dma_ch_run, &s->ch[i]);
     }
 
     soc_dma_reset(&s->soc);
diff --git a/hw/i386/kvm/apic.c b/hw/i386/kvm/apic.c
index 179b806..5609063 100644
--- a/hw/i386/kvm/apic.c
+++ b/hw/i386/kvm/apic.c
@@ -79,7 +79,7 @@ void kvm_get_apic_state(DeviceState *d, struct kvm_lapic_state *kapic)
     v = (s->divide_conf & 3) | ((s->divide_conf >> 1) & 4);
     s->count_shift = (v + 1) & 7;
 
-    s->initial_count_load_time = qemu_get_clock_ns(vm_clock);
+    s->initial_count_load_time = qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL);
     apic_next_timer(s, s->initial_count_load_time);
 }
 
diff --git a/hw/i386/kvm/i8254.c b/hw/i386/kvm/i8254.c
index c1f4094..20b6457 100644
--- a/hw/i386/kvm/i8254.c
+++ b/hw/i386/kvm/i8254.c
@@ -65,12 +65,12 @@ static void kvm_pit_update_clock_offset(KVMPITState *s)
 
     /*
      * Measure the delta between CLOCK_MONOTONIC, the base used for
-     * kvm_pit_channel_state::count_load_time, and vm_clock. Take the
+     * kvm_pit_channel_state::count_load_time, and QEMU_CLOCK_VIRTUAL. Take the
      * minimum of several samples to filter out scheduling noise.
      */
     clock_offset = INT64_MAX;
     for (i = 0; i < CALIBRATION_ROUNDS; i++) {
-        offset = qemu_get_clock_ns(vm_clock);
+        offset = qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL);
         clock_gettime(CLOCK_MONOTONIC, &ts);
         offset -= ts.tv_nsec;
         offset -= (int64_t)ts.tv_sec * 1000000000;
@@ -194,7 +194,7 @@ static void kvm_pit_set_gate(PITCommonState *s, PITChannelState *sc, int val)
     case 5:
         if (sc->gate < val) {
             /* restart counting on rising edge */
-            sc->count_load_time = qemu_get_clock_ns(vm_clock);
+            sc->count_load_time = qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL);
         }
         break;
     }
diff --git a/hw/i386/xen_domainbuild.c b/hw/i386/xen_domainbuild.c
index 4e2cf95..c0ab753 100644
--- a/hw/i386/xen_domainbuild.c
+++ b/hw/i386/xen_domainbuild.c
@@ -148,7 +148,7 @@ static void xen_domain_poll(void *opaque)
         goto quit;
     }
 
-    qemu_mod_timer(xen_poll, qemu_get_clock_ms(rt_clock) + 1000);
+    timer_mod(xen_poll, qemu_clock_get_ms(QEMU_CLOCK_REALTIME) + 1000);
     return;
 
 quit:
@@ -290,8 +290,8 @@ int xen_domain_build_pv(const char *kernel, const char *ramdisk,
         goto err;
     }
 
-    xen_poll = qemu_new_timer_ms(rt_clock, xen_domain_poll, NULL);
-    qemu_mod_timer(xen_poll, qemu_get_clock_ms(rt_clock) + 1000);
+    xen_poll = timer_new_ms(QEMU_CLOCK_REALTIME, xen_domain_poll, NULL);
+    timer_mod(xen_poll, qemu_clock_get_ms(QEMU_CLOCK_REALTIME) + 1000);
     return 0;
 
 err:
diff --git a/hw/ide/core.c b/hw/ide/core.c
index a73af72..399b1ba 100644
--- a/hw/ide/core.c
+++ b/hw/ide/core.c
@@ -768,8 +768,8 @@ static void ide_sector_write_cb(void *opaque, int ret)
            that at the expense of slower write performances. Use this
            option _only_ to install Windows 2000. You must disable it
            for normal use. */
-        qemu_mod_timer(s->sector_write_timer,
-                       qemu_get_clock_ns(vm_clock) + (get_ticks_per_sec() / 1000));
+        timer_mod(s->sector_write_timer,
+                       qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL) + (get_ticks_per_sec() / 1000));
     } else {
         ide_set_irq(s->bus);
     }
@@ -2163,7 +2163,7 @@ static void ide_init1(IDEBus *bus, int unit)
     s->smart_selftest_data = qemu_blockalign(s->bs, 512);
     memset(s->smart_selftest_data, 0, 512);
 
-    s->sector_write_timer = qemu_new_timer_ns(vm_clock,
+    s->sector_write_timer = timer_new_ns(QEMU_CLOCK_VIRTUAL,
                                            ide_sector_write_timer_cb, s);
 }
 
diff --git a/hw/input/hid.c b/hw/input/hid.c
index 14b3125..bb0fa6a 100644
--- a/hw/input/hid.c
+++ b/hw/input/hid.c
@@ -85,8 +85,8 @@ static void hid_idle_timer(void *opaque)
 static void hid_del_idle_timer(HIDState *hs)
 {
     if (hs->idle_timer) {
-        qemu_del_timer(hs->idle_timer);
-        qemu_free_timer(hs->idle_timer);
+        timer_del(hs->idle_timer);
+        timer_free(hs->idle_timer);
         hs->idle_timer = NULL;
     }
 }
@@ -94,12 +94,12 @@ static void hid_del_idle_timer(HIDState *hs)
 void hid_set_next_idle(HIDState *hs)
 {
     if (hs->idle) {
-        uint64_t expire_time = qemu_get_clock_ns(vm_clock) +
+        uint64_t expire_time = qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL) +
                                get_ticks_per_sec() * hs->idle * 4 / 1000;
         if (!hs->idle_timer) {
-            hs->idle_timer = qemu_new_timer_ns(vm_clock, hid_idle_timer, hs);
+            hs->idle_timer = timer_new_ns(QEMU_CLOCK_VIRTUAL, hid_idle_timer, hs);
         }
-        qemu_mod_timer_ns(hs->idle_timer, expire_time);
+        timer_mod_ns(hs->idle_timer, expire_time);
     } else {
         hid_del_idle_timer(hs);
     }
diff --git a/hw/input/lm832x.c b/hw/input/lm832x.c
index bacbeb2..f583cf0 100644
--- a/hw/input/lm832x.c
+++ b/hw/input/lm832x.c
@@ -365,7 +365,7 @@ static void lm_kbd_write(LM823KbdState *s, int reg, int byte, uint8_t value)
             break;
         }
 
-        qemu_del_timer(s->pwm.tm[(value & 3) - 1]);
+        timer_del(s->pwm.tm[(value & 3) - 1]);
         break;
 
     case LM832x_GENERAL_ERROR:
@@ -463,9 +463,9 @@ static int lm8323_init(I2CSlave *i2c)
     LM823KbdState *s = FROM_I2C_SLAVE(LM823KbdState, i2c);
 
     s->model = 0x8323;
-    s->pwm.tm[0] = qemu_new_timer_ns(vm_clock, lm_kbd_pwm0_tick, s);
-    s->pwm.tm[1] = qemu_new_timer_ns(vm_clock, lm_kbd_pwm1_tick, s);
-    s->pwm.tm[2] = qemu_new_timer_ns(vm_clock, lm_kbd_pwm2_tick, s);
+    s->pwm.tm[0] = timer_new_ns(QEMU_CLOCK_VIRTUAL, lm_kbd_pwm0_tick, s);
+    s->pwm.tm[1] = timer_new_ns(QEMU_CLOCK_VIRTUAL, lm_kbd_pwm1_tick, s);
+    s->pwm.tm[2] = timer_new_ns(QEMU_CLOCK_VIRTUAL, lm_kbd_pwm2_tick, s);
     qdev_init_gpio_out(&i2c->qdev, &s->nirq, 1);
 
     lm_kbd_reset(s);
diff --git a/hw/input/tsc2005.c b/hw/input/tsc2005.c
index fa9714b..21d4f4d 100644
--- a/hw/input/tsc2005.c
+++ b/hw/input/tsc2005.c
@@ -201,7 +201,7 @@ static void tsc2005_write(TSC2005State *s, int reg, uint16_t data)
             fprintf(stderr, "%s: touchscreen sense %sabled\n",
                             __FUNCTION__, s->enabled ? "en" : "dis");
             if (s->busy && !s->enabled)
-                qemu_del_timer(s->timer);
+                timer_del(s->timer);
             s->busy &= s->enabled;
         }
         s->nextprecision = (data >> 13) & 1;
@@ -290,8 +290,8 @@ static void tsc2005_pin_update(TSC2005State *s)
     s->precision = s->nextprecision;
     s->function = s->nextfunction;
     s->pdst = !s->pnd0;	/* Synchronised on internal clock */
-    expires = qemu_get_clock_ns(vm_clock) + (get_ticks_per_sec() >> 7);
-    qemu_mod_timer(s->timer, expires);
+    expires = qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL) + (get_ticks_per_sec() >> 7);
+    timer_mod(s->timer, expires);
 }
 
 static void tsc2005_reset(TSC2005State *s)
@@ -337,7 +337,7 @@ static uint8_t tsc2005_txrx_word(void *opaque, uint8_t value)
                     fprintf(stderr, "%s: touchscreen sense %sabled\n",
                                     __FUNCTION__, s->enabled ? "en" : "dis");
                     if (s->busy && !s->enabled)
-                        qemu_del_timer(s->timer);
+                        timer_del(s->timer);
                     s->busy &= s->enabled;
                 }
                 tsc2005_pin_update(s);
@@ -529,7 +529,7 @@ void *tsc2005_init(qemu_irq pintdav)
     s->y = 240;
     s->pressure = 0;
     s->precision = s->nextprecision = 0;
-    s->timer = qemu_new_timer_ns(vm_clock, tsc2005_timer_tick, s);
+    s->timer = timer_new_ns(QEMU_CLOCK_VIRTUAL, tsc2005_timer_tick, s);
     s->pint = pintdav;
     s->model = 0x2005;
 
diff --git a/hw/input/tsc210x.c b/hw/input/tsc210x.c
index 96fdb84..485c9e5 100644
--- a/hw/input/tsc210x.c
+++ b/hw/input/tsc210x.c
@@ -503,9 +503,9 @@ static uint16_t tsc2102_audio_register_read(TSC210xState *s, int reg)
         l_ch = 1;
         r_ch = 1;
         if (s->softstep && !(s->dac_power & (1 << 10))) {
-            l_ch = (qemu_get_clock_ns(vm_clock) >
+            l_ch = (qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL) >
                             s->volume_change + TSC_SOFTSTEP_DELAY);
-            r_ch = (qemu_get_clock_ns(vm_clock) >
+            r_ch = (qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL) >
                             s->volume_change + TSC_SOFTSTEP_DELAY);
         }
 
@@ -514,7 +514,7 @@ static uint16_t tsc2102_audio_register_read(TSC210xState *s, int reg)
     case 0x05:	/* Stereo DAC Power Control */
         return 0x2aa0 | s->dac_power |
                 (((s->dac_power & (1 << 10)) &&
-                  (qemu_get_clock_ns(vm_clock) >
+                  (qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL) >
                    s->powerdown + TSC_POWEROFF_DELAY)) << 6);
 
     case 0x06:	/* Audio Control 3 */
@@ -594,7 +594,7 @@ static void tsc2102_control_register_write(
         s->host_mode = value >> 15;
         s->enabled = !(value & 0x4000);
         if (s->busy && !s->enabled)
-            qemu_del_timer(s->timer);
+            timer_del(s->timer);
         s->busy &= s->enabled;
         s->nextfunction = (value >> 10) & 0xf;
         s->nextprecision = (value >> 8) & 3;
@@ -629,7 +629,7 @@ static void tsc2102_control_register_write(
     case 0x04:	/* Reset */
         if (value == 0xbb00) {
             if (s->busy)
-                qemu_del_timer(s->timer);
+                timer_del(s->timer);
             tsc210x_reset(s);
 #ifdef TSC_VERBOSE
         } else {
@@ -695,7 +695,7 @@ static void tsc2102_audio_register_write(
 
     case 0x02:	/* DAC Volume Control */
         s->volume = value;
-        s->volume_change = qemu_get_clock_ns(vm_clock);
+        s->volume_change = qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL);
         return;
 
     case 0x03:
@@ -717,7 +717,7 @@ static void tsc2102_audio_register_write(
 
     case 0x05:	/* Stereo DAC Power Control */
         if ((value & ~s->dac_power) & (1 << 10))
-            s->powerdown = qemu_get_clock_ns(vm_clock);
+            s->powerdown = qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL);
 
         s->dac_power = value & 0x9543;
 #ifdef TSC_VERBOSE
@@ -864,8 +864,8 @@ static void tsc210x_pin_update(TSC210xState *s)
     s->busy = 1;
     s->precision = s->nextprecision;
     s->function = s->nextfunction;
-    expires = qemu_get_clock_ns(vm_clock) + (get_ticks_per_sec() >> 10);
-    qemu_mod_timer(s->timer, expires);
+    expires = qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL) + (get_ticks_per_sec() >> 10);
+    timer_mod(s->timer, expires);
 }
 
 static uint16_t tsc210x_read(TSC210xState *s)
@@ -1005,7 +1005,7 @@ static void tsc210x_i2s_set_rate(TSC210xState *s, int in, int out)
 static void tsc210x_save(QEMUFile *f, void *opaque)
 {
     TSC210xState *s = (TSC210xState *) opaque;
-    int64_t now = qemu_get_clock_ns(vm_clock);
+    int64_t now = qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL);
     int i;
 
     qemu_put_be16(f, s->x);
@@ -1051,7 +1051,7 @@ static void tsc210x_save(QEMUFile *f, void *opaque)
 static int tsc210x_load(QEMUFile *f, void *opaque, int version_id)
 {
     TSC210xState *s = (TSC210xState *) opaque;
-    int64_t now = qemu_get_clock_ns(vm_clock);
+    int64_t now = qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL);
     int i;
 
     s->x = qemu_get_be16(f);
@@ -1111,7 +1111,7 @@ uWireSlave *tsc2102_init(qemu_irq pint)
     s->y = 160;
     s->pressure = 0;
     s->precision = s->nextprecision = 0;
-    s->timer = qemu_new_timer_ns(vm_clock, tsc210x_timer_tick, s);
+    s->timer = timer_new_ns(QEMU_CLOCK_VIRTUAL, tsc210x_timer_tick, s);
     s->pint = pint;
     s->model = 0x2102;
     s->name = "tsc2102";
@@ -1160,7 +1160,7 @@ uWireSlave *tsc2301_init(qemu_irq penirq, qemu_irq kbirq, qemu_irq dav)
     s->y = 240;
     s->pressure = 0;
     s->precision = s->nextprecision = 0;
-    s->timer = qemu_new_timer_ns(vm_clock, tsc210x_timer_tick, s);
+    s->timer = timer_new_ns(QEMU_CLOCK_VIRTUAL, tsc210x_timer_tick, s);
     s->pint = penirq;
     s->kbint = kbirq;
     s->davint = dav;
diff --git a/hw/intc/apic.c b/hw/intc/apic.c
index 5e3b96e..a913186 100644
--- a/hw/intc/apic.c
+++ b/hw/intc/apic.c
@@ -606,7 +606,7 @@ static uint32_t apic_get_current_count(APICCommonState *s)
 {
     int64_t d;
     uint32_t val;
-    d = (qemu_get_clock_ns(vm_clock) - s->initial_count_load_time) >>
+    d = (qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL) - s->initial_count_load_time) >>
         s->count_shift;
     if (s->lvt[APIC_LVT_TIMER] & APIC_LVT_TIMER_PERIODIC) {
         /* periodic */
@@ -623,9 +623,9 @@ static uint32_t apic_get_current_count(APICCommonState *s)
 static void apic_timer_update(APICCommonState *s, int64_t current_time)
 {
     if (apic_next_timer(s, current_time)) {
-        qemu_mod_timer(s->timer, s->next_time);
+        timer_mod(s->timer, s->next_time);
     } else {
-        qemu_del_timer(s->timer);
+        timer_del(s->timer);
     }
 }
 
@@ -822,7 +822,7 @@ static void apic_mem_writel(void *opaque, hwaddr addr, uint32_t val)
             int n = index - 0x32;
             s->lvt[n] = val;
             if (n == APIC_LVT_TIMER) {
-                apic_timer_update(s, qemu_get_clock_ns(vm_clock));
+                apic_timer_update(s, qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL));
             } else if (n == APIC_LVT_LINT0 && apic_check_pic(s)) {
                 apic_update_irq(s);
             }
@@ -830,7 +830,7 @@ static void apic_mem_writel(void *opaque, hwaddr addr, uint32_t val)
         break;
     case 0x38:
         s->initial_count = val;
-        s->initial_count_load_time = qemu_get_clock_ns(vm_clock);
+        s->initial_count_load_time = qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL);
         apic_timer_update(s, s->initial_count_load_time);
         break;
     case 0x39:
@@ -857,9 +857,9 @@ static void apic_pre_save(APICCommonState *s)
 static void apic_post_load(APICCommonState *s)
 {
     if (s->timer_expiry != -1) {
-        qemu_mod_timer(s->timer, s->timer_expiry);
+        timer_mod(s->timer, s->timer_expiry);
     } else {
-        qemu_del_timer(s->timer);
+        timer_del(s->timer);
     }
 }
 
@@ -876,7 +876,7 @@ static void apic_init(APICCommonState *s)
     memory_region_init_io(&s->io_memory, OBJECT(s), &apic_io_ops, s, "apic-msi",
                           APIC_SPACE_SIZE);
 
-    s->timer = qemu_new_timer_ns(vm_clock, apic_timer, s);
+    s->timer = timer_new_ns(QEMU_CLOCK_VIRTUAL, apic_timer, s);
     local_apics[s->idx] = s;
 
     msi_supported = true;
diff --git a/hw/intc/apic_common.c b/hw/intc/apic_common.c
index b03e904..a0beb10 100644
--- a/hw/intc/apic_common.c
+++ b/hw/intc/apic_common.c
@@ -198,7 +198,7 @@ void apic_init_reset(DeviceState *d)
     s->wait_for_sipi = 1;
 
     if (s->timer) {
-        qemu_del_timer(s->timer);
+        timer_del(s->timer);
     }
     s->timer_expiry = -1;
 }
diff --git a/hw/intc/armv7m_nvic.c b/hw/intc/armv7m_nvic.c
index 178344b..6066fa6 100644
--- a/hw/intc/armv7m_nvic.c
+++ b/hw/intc/armv7m_nvic.c
@@ -78,9 +78,9 @@ static inline int64_t systick_scale(nvic_state *s)
 static void systick_reload(nvic_state *s, int reset)
 {
     if (reset)
-        s->systick.tick = qemu_get_clock_ns(vm_clock);
+        s->systick.tick = qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL);
     s->systick.tick += (s->systick.reload + 1) * systick_scale(s);
-    qemu_mod_timer(s->systick.timer, s->systick.tick);
+    timer_mod(s->systick.timer, s->systick.tick);
 }
 
 static void systick_timer_tick(void * opaque)
@@ -103,7 +103,7 @@ static void systick_reset(nvic_state *s)
     s->systick.control = 0;
     s->systick.reload = 0;
     s->systick.tick = 0;
-    qemu_del_timer(s->systick.timer);
+    timer_del(s->systick.timer);
 }
 
 /* The external routines use the hardware vector numbering, ie. the first
@@ -158,7 +158,7 @@ static uint32_t nvic_readl(nvic_state *s, uint32_t offset)
             int64_t t;
             if ((s->systick.control & SYSTICK_ENABLE) == 0)
                 return 0;
-            t = qemu_get_clock_ns(vm_clock);
+            t = qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL);
             if (t >= s->systick.tick)
                 return 0;
             val = ((s->systick.tick - (t + 1)) / systick_scale(s)) + 1;
@@ -290,16 +290,16 @@ static void nvic_writel(nvic_state *s, uint32_t offset, uint32_t value)
         s->systick.control &= 0xfffffff8;
         s->systick.control |= value & 7;
         if ((oldval ^ value) & SYSTICK_ENABLE) {
-            int64_t now = qemu_get_clock_ns(vm_clock);
+            int64_t now = qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL);
             if (value & SYSTICK_ENABLE) {
                 if (s->systick.tick) {
                     s->systick.tick += now;
-                    qemu_mod_timer(s->systick.timer, s->systick.tick);
+                    timer_mod(s->systick.timer, s->systick.tick);
                 } else {
                     systick_reload(s, 1);
                 }
             } else {
-                qemu_del_timer(s->systick.timer);
+                timer_del(s->systick.timer);
                 s->systick.tick -= now;
                 if (s->systick.tick < 0)
                   s->systick.tick = 0;
@@ -511,7 +511,7 @@ static void armv7m_nvic_realize(DeviceState *dev, Error **errp)
      * by the v7M architecture.
      */
     memory_region_add_subregion(get_system_memory(), 0xe000e000, &s->container);
-    s->systick.timer = qemu_new_timer_ns(vm_clock, systick_timer_tick, s);
+    s->systick.timer = timer_new_ns(QEMU_CLOCK_VIRTUAL, systick_timer_tick, s);
 }
 
 static void armv7m_nvic_instance_init(Object *obj)
diff --git a/hw/intc/i8259.c b/hw/intc/i8259.c
index 1415bda..c6f248b 100644
--- a/hw/intc/i8259.c
+++ b/hw/intc/i8259.c
@@ -150,7 +150,7 @@ static void pic_set_irq(void *opaque, int irq, int level)
 #endif
 #ifdef DEBUG_IRQ_LATENCY
     if (level) {
-        irq_time[irq_index] = qemu_get_clock_ns(vm_clock);
+        irq_time[irq_index] = qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL);
     }
 #endif
 
@@ -228,7 +228,7 @@ int pic_read_irq(DeviceState *d)
 #ifdef DEBUG_IRQ_LATENCY
     printf("IRQ%d latency=%0.3fus\n",
            irq,
-           (double)(qemu_get_clock_ns(vm_clock) -
+           (double)(qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL) -
                     irq_time[irq]) * 1000000.0 / get_ticks_per_sec());
 #endif
     DPRINTF("pic_interrupt: irq=%d\n", irq);
diff --git a/hw/mips/cputimer.c b/hw/mips/cputimer.c
index 739bbac..c8b4b00 100644
--- a/hw/mips/cputimer.c
+++ b/hw/mips/cputimer.c
@@ -47,11 +47,11 @@ static void cpu_mips_timer_update(CPUMIPSState *env)
     uint64_t now, next;
     uint32_t wait;
 
-    now = qemu_get_clock_ns(vm_clock);
+    now = qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL);
     wait = env->CP0_Compare - env->CP0_Count -
 	    (uint32_t)muldiv64(now, TIMER_FREQ, get_ticks_per_sec());
     next = now + muldiv64(wait, get_ticks_per_sec(), TIMER_FREQ);
-    qemu_mod_timer(env->timer, next);
+    timer_mod(env->timer, next);
 }
 
 /* Expire the timer.  */
@@ -71,7 +71,7 @@ uint32_t cpu_mips_get_count (CPUMIPSState *env)
     } else {
         uint64_t now;
 
-        now = qemu_get_clock_ns(vm_clock);
+        now = qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL);
         if (timer_pending(env->timer)
             && timer_expired(env->timer, now)) {
             /* The timer has already expired.  */
@@ -90,7 +90,7 @@ void cpu_mips_store_count (CPUMIPSState *env, uint32_t count)
     else {
         /* Store new count register */
         env->CP0_Count =
-            count - (uint32_t)muldiv64(qemu_get_clock_ns(vm_clock),
+            count - (uint32_t)muldiv64(qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL),
                                        TIMER_FREQ, get_ticks_per_sec());
         /* Update timer timer */
         cpu_mips_timer_update(env);
@@ -115,7 +115,7 @@ void cpu_mips_start_count(CPUMIPSState *env)
 void cpu_mips_stop_count(CPUMIPSState *env)
 {
     /* Store the current value */
-    env->CP0_Count += (uint32_t)muldiv64(qemu_get_clock_ns(vm_clock),
+    env->CP0_Count += (uint32_t)muldiv64(qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL),
                                          TIMER_FREQ, get_ticks_per_sec());
 }
 
@@ -141,7 +141,7 @@ static void mips_timer_cb (void *opaque)
 
 void cpu_mips_clock_init (CPUMIPSState *env)
 {
-    env->timer = qemu_new_timer_ns(vm_clock, &mips_timer_cb, env);
+    env->timer = timer_new_ns(QEMU_CLOCK_VIRTUAL, &mips_timer_cb, env);
     env->CP0_Compare = 0;
     cpu_mips_store_count(env, 1);
 }
diff --git a/hw/misc/arm_sysctl.c b/hw/misc/arm_sysctl.c
index 4a911d4..0fc26d2 100644
--- a/hw/misc/arm_sysctl.c
+++ b/hw/misc/arm_sysctl.c
@@ -170,7 +170,7 @@ static uint64_t arm_sysctl_read(void *opaque, hwaddr offset,
     case 0x58: /* BOOTCS */
         return 0;
     case 0x5c: /* 24MHz */
-        return muldiv64(qemu_get_clock_ns(vm_clock), 24000000, get_ticks_per_sec());
+        return muldiv64(qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL), 24000000, get_ticks_per_sec());
     case 0x60: /* MISC */
         return 0;
     case 0x84: /* PROCID0 */
diff --git a/hw/misc/macio/cuda.c b/hw/misc/macio/cuda.c
index c0fd7da..c811b95 100644
--- a/hw/misc/macio/cuda.c
+++ b/hw/misc/macio/cuda.c
@@ -128,7 +128,7 @@ static unsigned int get_counter(CUDATimer *s)
     int64_t d;
     unsigned int counter;
 
-    d = muldiv64(qemu_get_clock_ns(vm_clock) - s->load_time,
+    d = muldiv64(qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL) - s->load_time,
                  CUDA_TIMER_FREQ, get_ticks_per_sec());
     if (s->index == 0) {
         /* the timer goes down from latch to -1 (period of latch + 2) */
@@ -147,7 +147,7 @@ static unsigned int get_counter(CUDATimer *s)
 static void set_counter(CUDAState *s, CUDATimer *ti, unsigned int val)
 {
     CUDA_DPRINTF("T%d.counter=%d\n", 1 + (ti->timer == NULL), val);
-    ti->load_time = qemu_get_clock_ns(vm_clock);
+    ti->load_time = qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL);
     ti->counter_value = val;
     cuda_timer_update(s, ti, ti->load_time);
 }
@@ -191,10 +191,10 @@ static void cuda_timer_update(CUDAState *s, CUDATimer *ti,
     if (!ti->timer)
         return;
     if ((s->acr & T1MODE) != T1MODE_CONT) {
-        qemu_del_timer(ti->timer);
+        timer_del(ti->timer);
     } else {
         ti->next_irq_time = get_next_irq_time(ti, current_time);
-        qemu_mod_timer(ti->timer, ti->next_irq_time);
+        timer_mod(ti->timer, ti->next_irq_time);
     }
 }
 
@@ -304,7 +304,7 @@ static void cuda_writeb(void *opaque, hwaddr addr, uint32_t val)
         break;
     case 4:
         s->timers[0].latch = (s->timers[0].latch & 0xff00) | val;
-        cuda_timer_update(s, &s->timers[0], qemu_get_clock_ns(vm_clock));
+        cuda_timer_update(s, &s->timers[0], qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL));
         break;
     case 5:
         s->timers[0].latch = (s->timers[0].latch & 0xff) | (val << 8);
@@ -313,12 +313,12 @@ static void cuda_writeb(void *opaque, hwaddr addr, uint32_t val)
         break;
     case 6:
         s->timers[0].latch = (s->timers[0].latch & 0xff00) | val;
-        cuda_timer_update(s, &s->timers[0], qemu_get_clock_ns(vm_clock));
+        cuda_timer_update(s, &s->timers[0], qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL));
         break;
     case 7:
         s->timers[0].latch = (s->timers[0].latch & 0xff) | (val << 8);
         s->ifr &= ~T1_INT;
-        cuda_timer_update(s, &s->timers[0], qemu_get_clock_ns(vm_clock));
+        cuda_timer_update(s, &s->timers[0], qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL));
         break;
     case 8:
         s->timers[1].latch = val;
@@ -332,7 +332,7 @@ static void cuda_writeb(void *opaque, hwaddr addr, uint32_t val)
         break;
     case 11:
         s->acr = val;
-        cuda_timer_update(s, &s->timers[0], qemu_get_clock_ns(vm_clock));
+        cuda_timer_update(s, &s->timers[0], qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL));
         cuda_update(s);
         break;
     case 12:
@@ -463,8 +463,8 @@ static void cuda_adb_poll(void *opaque)
         obuf[1] = 0x40; /* polled data */
         cuda_send_packet_to_host(s, obuf, olen + 2);
     }
-    qemu_mod_timer(s->adb_poll_timer,
-                   qemu_get_clock_ns(vm_clock) +
+    timer_mod(s->adb_poll_timer,
+                   qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL) +
                    (get_ticks_per_sec() / CUDA_ADB_POLL_FREQ));
 }
 
@@ -481,11 +481,11 @@ static void cuda_receive_packet(CUDAState *s,
         if (autopoll != s->autopoll) {
             s->autopoll = autopoll;
             if (autopoll) {
-                qemu_mod_timer(s->adb_poll_timer,
-                               qemu_get_clock_ns(vm_clock) +
+                timer_mod(s->adb_poll_timer,
+                               qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL) +
                                (get_ticks_per_sec() / CUDA_ADB_POLL_FREQ));
             } else {
-                qemu_del_timer(s->adb_poll_timer);
+                timer_del(s->adb_poll_timer);
             }
         }
         obuf[0] = CUDA_PACKET;
@@ -494,14 +494,14 @@ static void cuda_receive_packet(CUDAState *s,
         break;
     case CUDA_SET_TIME:
         ti = (((uint32_t)data[1]) << 24) + (((uint32_t)data[2]) << 16) + (((uint32_t)data[3]) << 8) + data[4];
-        s->tick_offset = ti - (qemu_get_clock_ns(vm_clock) / get_ticks_per_sec());
+        s->tick_offset = ti - (qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL) / get_ticks_per_sec());
         obuf[0] = CUDA_PACKET;
         obuf[1] = 0;
         obuf[2] = 0;
         cuda_send_packet_to_host(s, obuf, 3);
         break;
     case CUDA_GET_TIME:
-        ti = s->tick_offset + (qemu_get_clock_ns(vm_clock) / get_ticks_per_sec());
+        ti = s->tick_offset + (qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL) / get_ticks_per_sec());
         obuf[0] = CUDA_PACKET;
         obuf[1] = 0;
         obuf[2] = 0;
@@ -689,12 +689,12 @@ static void cuda_realizefn(DeviceState *dev, Error **errp)
     CUDAState *s = CUDA(dev);
     struct tm tm;
 
-    s->timers[0].timer = qemu_new_timer_ns(vm_clock, cuda_timer1, s);
+    s->timers[0].timer = timer_new_ns(QEMU_CLOCK_VIRTUAL, cuda_timer1, s);
 
     qemu_get_timedate(&tm, 0);
     s->tick_offset = (uint32_t)mktimegm(&tm) + RTC_OFFSET;
 
-    s->adb_poll_timer = qemu_new_timer_ns(vm_clock, cuda_adb_poll, s);
+    s->adb_poll_timer = timer_new_ns(QEMU_CLOCK_VIRTUAL, cuda_adb_poll, s);
 }
 
 static void cuda_initfn(Object *obj)
diff --git a/hw/misc/macio/macio.c b/hw/misc/macio/macio.c
index c0d0bf7..9cc33d8 100644
--- a/hw/misc/macio/macio.c
+++ b/hw/misc/macio/macio.c
@@ -245,10 +245,10 @@ static uint64_t timer_read(void *opaque, hwaddr addr, unsigned size)
 
     switch (addr) {
     case 0x38:
-        value = qemu_get_clock_ns(vm_clock);
+        value = qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL);
         break;
     case 0x3c:
-        value = qemu_get_clock_ns(vm_clock) >> 32;
+        value = qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL) >> 32;
         break;
     }
 
diff --git a/hw/misc/vfio.c b/hw/misc/vfio.c
index 017e693..d215e29 100644
--- a/hw/misc/vfio.c
+++ b/hw/misc/vfio.c
@@ -276,8 +276,8 @@ static void vfio_intx_mmap_enable(void *opaque)
     VFIODevice *vdev = opaque;
 
     if (vdev->intx.pending) {
-        qemu_mod_timer(vdev->intx.mmap_timer,
-                       qemu_get_clock_ms(vm_clock) + vdev->intx.mmap_timeout);
+        timer_mod(vdev->intx.mmap_timer,
+                       qemu_clock_get_ms(QEMU_CLOCK_VIRTUAL) + vdev->intx.mmap_timeout);
         return;
     }
 
@@ -300,8 +300,8 @@ static void vfio_intx_interrupt(void *opaque)
     qemu_set_irq(vdev->pdev.irq[vdev->intx.pin], 1);
     vfio_mmap_set_enabled(vdev, false);
     if (vdev->intx.mmap_timeout) {
-        qemu_mod_timer(vdev->intx.mmap_timer,
-                       qemu_get_clock_ms(vm_clock) + vdev->intx.mmap_timeout);
+        timer_mod(vdev->intx.mmap_timer,
+                       qemu_clock_get_ms(QEMU_CLOCK_VIRTUAL) + vdev->intx.mmap_timeout);
     }
 }
 
@@ -543,7 +543,7 @@ static void vfio_disable_intx(VFIODevice *vdev)
 {
     int fd;
 
-    qemu_del_timer(vdev->intx.mmap_timer);
+    timer_del(vdev->intx.mmap_timer);
     vfio_disable_intx_kvm(vdev);
     vfio_disable_irqindex(vdev, VFIO_PCI_INTX_IRQ_INDEX);
     vdev->intx.pending = false;
@@ -3176,7 +3176,7 @@ static int vfio_initfn(PCIDevice *pdev)
     }
 
     if (vfio_pci_read_config(&vdev->pdev, PCI_INTERRUPT_PIN, 1)) {
-        vdev->intx.mmap_timer = qemu_new_timer_ms(vm_clock,
+        vdev->intx.mmap_timer = timer_new_ms(QEMU_CLOCK_VIRTUAL,
                                                   vfio_intx_mmap_enable, vdev);
         pci_device_set_intx_routing_notifier(&vdev->pdev, vfio_update_irq);
         ret = vfio_enable_intx(vdev);
@@ -3210,7 +3210,7 @@ static void vfio_exitfn(PCIDevice *pdev)
     pci_device_set_intx_routing_notifier(&vdev->pdev, NULL);
     vfio_disable_interrupts(vdev);
     if (vdev->intx.mmap_timer) {
-        qemu_free_timer(vdev->intx.mmap_timer);
+        timer_free(vdev->intx.mmap_timer);
     }
     vfio_teardown_msi(vdev);
     vfio_unmap_bars(vdev);
diff --git a/hw/net/dp8393x.c b/hw/net/dp8393x.c
index 049aa70..789d385 100644
--- a/hw/net/dp8393x.c
+++ b/hw/net/dp8393x.c
@@ -274,7 +274,7 @@ static void do_read_rra(dp8393xState *s)
 
 static void do_software_reset(dp8393xState *s)
 {
-    qemu_del_timer(s->watchdog);
+    timer_del(s->watchdog);
 
     s->regs[SONIC_CR] &= ~(SONIC_CR_LCAM | SONIC_CR_RRRA | SONIC_CR_TXP | SONIC_CR_HTX);
     s->regs[SONIC_CR] |= SONIC_CR_RST | SONIC_CR_RXDIS;
@@ -286,14 +286,14 @@ static void set_next_tick(dp8393xState *s)
     int64_t delay;
 
     if (s->regs[SONIC_CR] & SONIC_CR_STP) {
-        qemu_del_timer(s->watchdog);
+        timer_del(s->watchdog);
         return;
     }
 
     ticks = s->regs[SONIC_WT1] << 16 | s->regs[SONIC_WT0];
-    s->wt_last_update = qemu_get_clock_ns(vm_clock);
+    s->wt_last_update = qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL);
     delay = get_ticks_per_sec() * ticks / 5000000;
-    qemu_mod_timer(s->watchdog, s->wt_last_update + delay);
+    timer_mod(s->watchdog, s->wt_last_update + delay);
 }
 
 static void update_wt_regs(dp8393xState *s)
@@ -302,11 +302,11 @@ static void update_wt_regs(dp8393xState *s)
     uint32_t val;
 
     if (s->regs[SONIC_CR] & SONIC_CR_STP) {
-        qemu_del_timer(s->watchdog);
+        timer_del(s->watchdog);
         return;
     }
 
-    elapsed = s->wt_last_update - qemu_get_clock_ns(vm_clock);
+    elapsed = s->wt_last_update - qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL);
     val = s->regs[SONIC_WT1] << 16 | s->regs[SONIC_WT0];
     val -= elapsed / 5000000;
     s->regs[SONIC_WT1] = (val >> 16) & 0xffff;
@@ -838,7 +838,7 @@ static ssize_t nic_receive(NetClientState *nc, const uint8_t * buf, size_t size)
 static void nic_reset(void *opaque)
 {
     dp8393xState *s = opaque;
-    qemu_del_timer(s->watchdog);
+    timer_del(s->watchdog);
 
     s->regs[SONIC_CR] = SONIC_CR_RST | SONIC_CR_STP | SONIC_CR_RXDIS;
     s->regs[SONIC_DCR] &= ~(SONIC_DCR_EXBUS | SONIC_DCR_LBR);
@@ -866,8 +866,8 @@ static void nic_cleanup(NetClientState *nc)
     memory_region_del_subregion(s->address_space, &s->mmio);
     memory_region_destroy(&s->mmio);
 
-    qemu_del_timer(s->watchdog);
-    qemu_free_timer(s->watchdog);
+    timer_del(s->watchdog);
+    timer_free(s->watchdog);
 
     g_free(s);
 }
@@ -896,7 +896,7 @@ void dp83932_init(NICInfo *nd, hwaddr base, int it_shift,
     s->memory_rw = memory_rw;
     s->it_shift = it_shift;
     s->irq = irq;
-    s->watchdog = qemu_new_timer_ns(vm_clock, dp8393x_watchdog, s);
+    s->watchdog = timer_new_ns(QEMU_CLOCK_VIRTUAL, dp8393x_watchdog, s);
     s->regs[SONIC_SR] = 0x0004; /* only revision recognized by Linux */
 
     s->conf.macaddr = nd->macaddr;
diff --git a/hw/net/e1000.c b/hw/net/e1000.c
index fdb1f89..f5ebed4 100644
--- a/hw/net/e1000.c
+++ b/hw/net/e1000.c
@@ -190,7 +190,7 @@ set_phy_ctrl(E1000State *s, int index, uint16_t val)
         e1000_link_down(s);
         s->phy_reg[PHY_STATUS] &= ~MII_SR_AUTONEG_COMPLETE;
         DBGOUT(PHY, "Start link auto negotiation\n");
-        qemu_mod_timer(s->autoneg_timer, qemu_get_clock_ms(vm_clock) + 500);
+        timer_mod(s->autoneg_timer, qemu_clock_get_ms(QEMU_CLOCK_VIRTUAL) + 500);
     }
 }
 
@@ -306,7 +306,7 @@ static void e1000_reset(void *opaque)
     uint8_t *macaddr = d->conf.macaddr.a;
     int i;
 
-    qemu_del_timer(d->autoneg_timer);
+    timer_del(d->autoneg_timer);
     memset(d->phy_reg, 0, sizeof d->phy_reg);
     memmove(d->phy_reg, phy_reg_init, sizeof phy_reg_init);
     memset(d->mac_reg, 0, sizeof d->mac_reg);
@@ -1184,7 +1184,7 @@ static int e1000_post_load(void *opaque, int version_id)
         s->phy_reg[PHY_CTRL] & MII_CR_RESTART_AUTO_NEG &&
         !(s->phy_reg[PHY_STATUS] & MII_SR_AUTONEG_COMPLETE)) {
         nc->link_down = false;
-        qemu_mod_timer(s->autoneg_timer, qemu_get_clock_ms(vm_clock) + 500);
+        timer_mod(s->autoneg_timer, qemu_clock_get_ms(QEMU_CLOCK_VIRTUAL) + 500);
     }
 
     return 0;
@@ -1314,8 +1314,8 @@ pci_e1000_uninit(PCIDevice *dev)
 {
     E1000State *d = E1000(dev);
 
-    qemu_del_timer(d->autoneg_timer);
-    qemu_free_timer(d->autoneg_timer);
+    timer_del(d->autoneg_timer);
+    timer_free(d->autoneg_timer);
     memory_region_destroy(&d->mmio);
     memory_region_destroy(&d->io);
     qemu_del_nic(d->nic);
@@ -1370,7 +1370,7 @@ static int pci_e1000_init(PCIDevice *pci_dev)
 
     add_boot_device_path(d->conf.bootindex, dev, "/ethernet-phy at 0");
 
-    d->autoneg_timer = qemu_new_timer_ms(vm_clock, e1000_autoneg_timer, d);
+    d->autoneg_timer = timer_new_ms(QEMU_CLOCK_VIRTUAL, e1000_autoneg_timer, d);
 
     return 0;
 }
diff --git a/hw/net/lan9118.c b/hw/net/lan9118.c
index 2c838f6..2315f99 100644
--- a/hw/net/lan9118.c
+++ b/hw/net/lan9118.c
@@ -439,7 +439,7 @@ static void lan9118_reset(DeviceState *d)
     s->afc_cfg = 0;
     s->e2p_cmd = 0;
     s->e2p_data = 0;
-    s->free_timer_start = qemu_get_clock_ns(vm_clock) / 40;
+    s->free_timer_start = qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL) / 40;
 
     ptimer_stop(s->timer);
     ptimer_set_count(s->timer, 0xffff);
@@ -1236,7 +1236,7 @@ static uint64_t lan9118_readl(void *opaque, hwaddr offset,
     case CSR_WORD_SWAP:
         return s->word_swap;
     case CSR_FREE_RUN:
-        return (qemu_get_clock_ns(vm_clock) / 40) - s->free_timer_start;
+        return (qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL) / 40) - s->free_timer_start;
     case CSR_RX_DROP:
         /* TODO: Implement dropped frames counter.  */
         return 0;
diff --git a/hw/net/pcnet-pci.c b/hw/net/pcnet-pci.c
index 2c2301c..a893165 100644
--- a/hw/net/pcnet-pci.c
+++ b/hw/net/pcnet-pci.c
@@ -284,8 +284,8 @@ static void pci_pcnet_uninit(PCIDevice *dev)
 
     memory_region_destroy(&d->state.mmio);
     memory_region_destroy(&d->io_bar);
-    qemu_del_timer(d->state.poll_timer);
-    qemu_free_timer(d->state.poll_timer);
+    timer_del(d->state.poll_timer);
+    timer_free(d->state.poll_timer);
     qemu_del_nic(d->state.nic);
 }
 
diff --git a/hw/net/pcnet.c b/hw/net/pcnet.c
index 63aa73a..7cb47b3 100644
--- a/hw/net/pcnet.c
+++ b/hw/net/pcnet.c
@@ -1331,7 +1331,7 @@ static void pcnet_poll_timer(void *opaque)
 {
     PCNetState *s = opaque;
 
-    qemu_del_timer(s->poll_timer);
+    timer_del(s->poll_timer);
 
     if (CSR_TDMD(s)) {
         pcnet_transmit(s);
@@ -1340,7 +1340,7 @@ static void pcnet_poll_timer(void *opaque)
     pcnet_update_irq(s);
 
     if (!CSR_STOP(s) && !CSR_SPND(s) && !CSR_DPOLL(s)) {
-        uint64_t now = qemu_get_clock_ns(vm_clock) * 33;
+        uint64_t now = qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL) * 33;
         if (!s->timer || !now)
             s->timer = now;
         else {
@@ -1351,8 +1351,8 @@ static void pcnet_poll_timer(void *opaque)
             } else
                 CSR_POLL(s) = t;
         }
-        qemu_mod_timer(s->poll_timer,
-            pcnet_get_next_poll_time(s,qemu_get_clock_ns(vm_clock)));
+        timer_mod(s->poll_timer,
+            pcnet_get_next_poll_time(s,qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL)));
     }
 }
 
@@ -1731,7 +1731,7 @@ int pcnet_common_init(DeviceState *dev, PCNetState *s, NetClientInfo *info)
     int i;
     uint16_t checksum;
 
-    s->poll_timer = qemu_new_timer_ns(vm_clock, pcnet_poll_timer, s);
+    s->poll_timer = timer_new_ns(QEMU_CLOCK_VIRTUAL, pcnet_poll_timer, s);
 
     qemu_macaddr_default_if_unset(&s->conf.macaddr);
     s->nic = qemu_new_nic(info, &s->conf, object_get_typename(OBJECT(dev)), dev->id, s);
diff --git a/hw/net/rtl8139.c b/hw/net/rtl8139.c
index ee3b690..c31199f 100644
--- a/hw/net/rtl8139.c
+++ b/hw/net/rtl8139.c
@@ -2648,7 +2648,7 @@ static void rtl8139_IntrMask_write(RTL8139State *s, uint32_t val)
 
     s->IntrMask = val;
 
-    rtl8139_set_next_tctr_time(s, qemu_get_clock_ns(vm_clock));
+    rtl8139_set_next_tctr_time(s, qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL));
     rtl8139_update_irq(s);
 
 }
@@ -2689,7 +2689,7 @@ static void rtl8139_IntrStatus_write(RTL8139State *s, uint32_t val)
      * and probably emulated is slower is better to assume this resetting was
      * done before testing on previous rtl8139_update_irq lead to IRQ losing
      */
-    rtl8139_set_next_tctr_time(s, qemu_get_clock_ns(vm_clock));
+    rtl8139_set_next_tctr_time(s, qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL));
     rtl8139_update_irq(s);
 
 #endif
@@ -2697,7 +2697,7 @@ static void rtl8139_IntrStatus_write(RTL8139State *s, uint32_t val)
 
 static uint32_t rtl8139_IntrStatus_read(RTL8139State *s)
 {
-    rtl8139_set_next_tctr_time(s, qemu_get_clock_ns(vm_clock));
+    rtl8139_set_next_tctr_time(s, qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL));
 
     uint32_t ret = s->IntrStatus;
 
@@ -2913,7 +2913,7 @@ static void rtl8139_set_next_tctr_time(RTL8139State *s, int64_t current_time)
     s->TimerExpire = next_time;
 
     if ((s->IntrMask & PCSTimeout) != 0 && (s->IntrStatus & PCSTimeout) == 0) {
-        qemu_mod_timer(s->timer, next_time);
+        timer_mod(s->timer, next_time);
     }
 }
 
@@ -2960,7 +2960,7 @@ static void rtl8139_io_writel(void *opaque, uint8_t addr, uint32_t val)
 
         case Timer:
             DPRINTF("TCTR Timer reset on write\n");
-            s->TCTR_base = qemu_get_clock_ns(vm_clock);
+            s->TCTR_base = qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL);
             rtl8139_set_next_tctr_time(s, s->TCTR_base);
             break;
 
@@ -2968,7 +2968,7 @@ static void rtl8139_io_writel(void *opaque, uint8_t addr, uint32_t val)
             DPRINTF("FlashReg TimerInt write val=0x%08x\n", val);
             if (s->TimerInt != val) {
                 s->TimerInt = val;
-                rtl8139_set_next_tctr_time(s, qemu_get_clock_ns(vm_clock));
+                rtl8139_set_next_tctr_time(s, qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL));
             }
             break;
 
@@ -3183,7 +3183,7 @@ static uint32_t rtl8139_io_readl(void *opaque, uint8_t addr)
             break;
 
         case Timer:
-            ret = muldiv64(qemu_get_clock_ns(vm_clock) - s->TCTR_base,
+            ret = muldiv64(qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL) - s->TCTR_base,
                            PCI_FREQUENCY, get_ticks_per_sec());
             DPRINTF("TCTR Timer read val=0x%08x\n", ret);
             break;
@@ -3245,7 +3245,7 @@ static uint32_t rtl8139_mmio_readl(void *opaque, hwaddr addr)
 static int rtl8139_post_load(void *opaque, int version_id)
 {
     RTL8139State* s = opaque;
-    rtl8139_set_next_tctr_time(s, qemu_get_clock_ns(vm_clock));
+    rtl8139_set_next_tctr_time(s, qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL));
     if (version_id < 4) {
         s->cplus_enabled = s->CpCmd != 0;
     }
@@ -3275,7 +3275,7 @@ static const VMStateDescription vmstate_rtl8139_hotplug_ready ={
 static void rtl8139_pre_save(void *opaque)
 {
     RTL8139State* s = opaque;
-    int64_t current_time = qemu_get_clock_ns(vm_clock);
+    int64_t current_time = qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL);
 
     /* set IntrStatus correctly */
     rtl8139_set_next_tctr_time(s, current_time);
@@ -3446,7 +3446,7 @@ static void rtl8139_timer(void *opaque)
 
     s->IntrStatus |= PCSTimeout;
     rtl8139_update_irq(s);
-    rtl8139_set_next_tctr_time(s, qemu_get_clock_ns(vm_clock));
+    rtl8139_set_next_tctr_time(s, qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL));
 }
 
 static void rtl8139_cleanup(NetClientState *nc)
@@ -3466,8 +3466,8 @@ static void pci_rtl8139_uninit(PCIDevice *dev)
         g_free(s->cplus_txbuffer);
         s->cplus_txbuffer = NULL;
     }
-    qemu_del_timer(s->timer);
-    qemu_free_timer(s->timer);
+    timer_del(s->timer);
+    timer_free(s->timer);
     qemu_del_nic(s->nic);
 }
 
@@ -3535,8 +3535,8 @@ static int pci_rtl8139_init(PCIDevice *dev)
     s->cplus_txbuffer_offset = 0;
 
     s->TimerExpire = 0;
-    s->timer = qemu_new_timer_ns(vm_clock, rtl8139_timer, s);
-    rtl8139_set_next_tctr_time(s, qemu_get_clock_ns(vm_clock));
+    s->timer = timer_new_ns(QEMU_CLOCK_VIRTUAL, rtl8139_timer, s);
+    rtl8139_set_next_tctr_time(s, qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL));
 
     add_boot_device_path(s->conf.bootindex, d, "/ethernet-phy at 0");
 
diff --git a/hw/net/virtio-net.c b/hw/net/virtio-net.c
index aa1880c..dd41008 100644
--- a/hw/net/virtio-net.c
+++ b/hw/net/virtio-net.c
@@ -162,14 +162,14 @@ static void virtio_net_set_status(struct VirtIODevice *vdev, uint8_t status)
 
         if (virtio_net_started(n, queue_status) && !n->vhost_started) {
             if (q->tx_timer) {
-                qemu_mod_timer(q->tx_timer,
-                               qemu_get_clock_ns(vm_clock) + n->tx_timeout);
+                timer_mod(q->tx_timer,
+                               qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL) + n->tx_timeout);
             } else {
                 qemu_bh_schedule(q->tx_bh);
             }
         } else {
             if (q->tx_timer) {
-                qemu_del_timer(q->tx_timer);
+                timer_del(q->tx_timer);
             } else {
                 qemu_bh_cancel(q->tx_bh);
             }
@@ -1131,12 +1131,12 @@ static void virtio_net_handle_tx_timer(VirtIODevice *vdev, VirtQueue *vq)
 
     if (q->tx_waiting) {
         virtio_queue_set_notification(vq, 1);
-        qemu_del_timer(q->tx_timer);
+        timer_del(q->tx_timer);
         q->tx_waiting = 0;
         virtio_net_flush_tx(q);
     } else {
-        qemu_mod_timer(q->tx_timer,
-                       qemu_get_clock_ns(vm_clock) + n->tx_timeout);
+        timer_mod(q->tx_timer,
+                       qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL) + n->tx_timeout);
         q->tx_waiting = 1;
         virtio_queue_set_notification(vq, 0);
     }
@@ -1233,7 +1233,7 @@ static void virtio_net_set_multiqueue(VirtIONet *n, int multiqueue)
         if (n->vqs[i].tx_timer) {
             n->vqs[i].tx_vq =
                 virtio_add_queue(vdev, 256, virtio_net_handle_tx_timer);
-            n->vqs[i].tx_timer = qemu_new_timer_ns(vm_clock,
+            n->vqs[i].tx_timer = timer_new_ns(QEMU_CLOCK_VIRTUAL,
                                                    virtio_net_tx_timer,
                                                    &n->vqs[i]);
         } else {
@@ -1513,7 +1513,7 @@ static int virtio_net_device_init(VirtIODevice *vdev)
     if (n->net_conf.tx && !strcmp(n->net_conf.tx, "timer")) {
         n->vqs[0].tx_vq = virtio_add_queue(vdev, 256,
                                            virtio_net_handle_tx_timer);
-        n->vqs[0].tx_timer = qemu_new_timer_ns(vm_clock, virtio_net_tx_timer,
+        n->vqs[0].tx_timer = timer_new_ns(QEMU_CLOCK_VIRTUAL, virtio_net_tx_timer,
                                                &n->vqs[0]);
     } else {
         n->vqs[0].tx_vq = virtio_add_queue(vdev, 256,
@@ -1598,8 +1598,8 @@ static int virtio_net_device_exit(DeviceState *qdev)
         qemu_purge_queued_packets(nc);
 
         if (q->tx_timer) {
-            qemu_del_timer(q->tx_timer);
-            qemu_free_timer(q->tx_timer);
+            timer_del(q->tx_timer);
+            timer_free(q->tx_timer);
         } else {
             qemu_bh_delete(q->tx_bh);
         }
diff --git a/hw/openrisc/cputimer.c b/hw/openrisc/cputimer.c
index 9a09f5c..988ca20 100644
--- a/hw/openrisc/cputimer.c
+++ b/hw/openrisc/cputimer.c
@@ -33,9 +33,9 @@ void cpu_openrisc_count_update(OpenRISCCPU *cpu)
     uint64_t now, next;
     uint32_t wait;
 
-    now = qemu_get_clock_ns(vm_clock);
+    now = qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL);
     if (!is_counting) {
-        qemu_del_timer(cpu->env.timer);
+        timer_del(cpu->env.timer);
         last_clk = now;
         return;
     }
@@ -52,7 +52,7 @@ void cpu_openrisc_count_update(OpenRISCCPU *cpu)
     }
 
     next = now + muldiv64(wait, get_ticks_per_sec(), TIMER_FREQ);
-    qemu_mod_timer(cpu->env.timer, next);
+    timer_mod(cpu->env.timer, next);
 }
 
 void cpu_openrisc_count_start(OpenRISCCPU *cpu)
@@ -72,7 +72,7 @@ static void openrisc_timer_cb(void *opaque)
     OpenRISCCPU *cpu = opaque;
 
     if ((cpu->env.ttmr & TTMR_IE) &&
-         timer_expired(cpu->env.timer, qemu_get_clock_ns(vm_clock))) {
+         timer_expired(cpu->env.timer, qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL))) {
         CPUState *cs = CPU(cpu);
 
         cpu->env.ttmr |= TTMR_IP;
@@ -97,7 +97,7 @@ static void openrisc_timer_cb(void *opaque)
 
 void cpu_openrisc_clock_init(OpenRISCCPU *cpu)
 {
-    cpu->env.timer = qemu_new_timer_ns(vm_clock, &openrisc_timer_cb, cpu);
+    cpu->env.timer = timer_new_ns(QEMU_CLOCK_VIRTUAL, &openrisc_timer_cb, cpu);
     cpu->env.ttmr = 0x00000000;
     cpu->env.ttcr = 0x00000000;
 }
diff --git a/hw/ppc/ppc.c b/hw/ppc/ppc.c
index e1c095c..59b41cb 100644
--- a/hw/ppc/ppc.c
+++ b/hw/ppc/ppc.c
@@ -471,7 +471,7 @@ uint64_t cpu_ppc_load_tbl (CPUPPCState *env)
         return env->spr[SPR_TBL];
     }
 
-    tb = cpu_ppc_get_tb(tb_env, qemu_get_clock_ns(vm_clock), tb_env->tb_offset);
+    tb = cpu_ppc_get_tb(tb_env, qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL), tb_env->tb_offset);
     LOG_TB("%s: tb %016" PRIx64 "\n", __func__, tb);
 
     return tb;
@@ -482,7 +482,7 @@ static inline uint32_t _cpu_ppc_load_tbu(CPUPPCState *env)
     ppc_tb_t *tb_env = env->tb_env;
     uint64_t tb;
 
-    tb = cpu_ppc_get_tb(tb_env, qemu_get_clock_ns(vm_clock), tb_env->tb_offset);
+    tb = cpu_ppc_get_tb(tb_env, qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL), tb_env->tb_offset);
     LOG_TB("%s: tb %016" PRIx64 "\n", __func__, tb);
 
     return tb >> 32;
@@ -510,9 +510,9 @@ void cpu_ppc_store_tbl (CPUPPCState *env, uint32_t value)
     ppc_tb_t *tb_env = env->tb_env;
     uint64_t tb;
 
-    tb = cpu_ppc_get_tb(tb_env, qemu_get_clock_ns(vm_clock), tb_env->tb_offset);
+    tb = cpu_ppc_get_tb(tb_env, qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL), tb_env->tb_offset);
     tb &= 0xFFFFFFFF00000000ULL;
-    cpu_ppc_store_tb(tb_env, qemu_get_clock_ns(vm_clock),
+    cpu_ppc_store_tb(tb_env, qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL),
                      &tb_env->tb_offset, tb | (uint64_t)value);
 }
 
@@ -521,9 +521,9 @@ static inline void _cpu_ppc_store_tbu(CPUPPCState *env, uint32_t value)
     ppc_tb_t *tb_env = env->tb_env;
     uint64_t tb;
 
-    tb = cpu_ppc_get_tb(tb_env, qemu_get_clock_ns(vm_clock), tb_env->tb_offset);
+    tb = cpu_ppc_get_tb(tb_env, qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL), tb_env->tb_offset);
     tb &= 0x00000000FFFFFFFFULL;
-    cpu_ppc_store_tb(tb_env, qemu_get_clock_ns(vm_clock),
+    cpu_ppc_store_tb(tb_env, qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL),
                      &tb_env->tb_offset, ((uint64_t)value << 32) | tb);
 }
 
@@ -537,7 +537,7 @@ uint64_t cpu_ppc_load_atbl (CPUPPCState *env)
     ppc_tb_t *tb_env = env->tb_env;
     uint64_t tb;
 
-    tb = cpu_ppc_get_tb(tb_env, qemu_get_clock_ns(vm_clock), tb_env->atb_offset);
+    tb = cpu_ppc_get_tb(tb_env, qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL), tb_env->atb_offset);
     LOG_TB("%s: tb %016" PRIx64 "\n", __func__, tb);
 
     return tb;
@@ -548,7 +548,7 @@ uint32_t cpu_ppc_load_atbu (CPUPPCState *env)
     ppc_tb_t *tb_env = env->tb_env;
     uint64_t tb;
 
-    tb = cpu_ppc_get_tb(tb_env, qemu_get_clock_ns(vm_clock), tb_env->atb_offset);
+    tb = cpu_ppc_get_tb(tb_env, qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL), tb_env->atb_offset);
     LOG_TB("%s: tb %016" PRIx64 "\n", __func__, tb);
 
     return tb >> 32;
@@ -559,9 +559,9 @@ void cpu_ppc_store_atbl (CPUPPCState *env, uint32_t value)
     ppc_tb_t *tb_env = env->tb_env;
     uint64_t tb;
 
-    tb = cpu_ppc_get_tb(tb_env, qemu_get_clock_ns(vm_clock), tb_env->atb_offset);
+    tb = cpu_ppc_get_tb(tb_env, qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL), tb_env->atb_offset);
     tb &= 0xFFFFFFFF00000000ULL;
-    cpu_ppc_store_tb(tb_env, qemu_get_clock_ns(vm_clock),
+    cpu_ppc_store_tb(tb_env, qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL),
                      &tb_env->atb_offset, tb | (uint64_t)value);
 }
 
@@ -570,9 +570,9 @@ void cpu_ppc_store_atbu (CPUPPCState *env, uint32_t value)
     ppc_tb_t *tb_env = env->tb_env;
     uint64_t tb;
 
-    tb = cpu_ppc_get_tb(tb_env, qemu_get_clock_ns(vm_clock), tb_env->atb_offset);
+    tb = cpu_ppc_get_tb(tb_env, qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL), tb_env->atb_offset);
     tb &= 0x00000000FFFFFFFFULL;
-    cpu_ppc_store_tb(tb_env, qemu_get_clock_ns(vm_clock),
+    cpu_ppc_store_tb(tb_env, qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL),
                      &tb_env->atb_offset, ((uint64_t)value << 32) | tb);
 }
 
@@ -583,7 +583,7 @@ static void cpu_ppc_tb_stop (CPUPPCState *env)
 
     /* If the time base is already frozen, do nothing */
     if (tb_env->tb_freq != 0) {
-        vmclk = qemu_get_clock_ns(vm_clock);
+        vmclk = qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL);
         /* Get the time base */
         tb = cpu_ppc_get_tb(tb_env, vmclk, tb_env->tb_offset);
         /* Get the alternate time base */
@@ -605,7 +605,7 @@ static void cpu_ppc_tb_start (CPUPPCState *env)
 
     /* If the time base is not frozen, do nothing */
     if (tb_env->tb_freq == 0) {
-        vmclk = qemu_get_clock_ns(vm_clock);
+        vmclk = qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL);
         /* Get the time base from tb_offset */
         tb = tb_env->tb_offset;
         /* Get the alternate time base from atb_offset */
@@ -625,7 +625,7 @@ static inline uint32_t _cpu_ppc_load_decr(CPUPPCState *env, uint64_t next)
     uint32_t decr;
     int64_t diff;
 
-    diff = next - qemu_get_clock_ns(vm_clock);
+    diff = next - qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL);
     if (diff >= 0) {
         decr = muldiv64(diff, tb_env->decr_freq, get_ticks_per_sec());
     } else if (tb_env->flags & PPC_TIMER_BOOKE) {
@@ -661,7 +661,7 @@ uint64_t cpu_ppc_load_purr (CPUPPCState *env)
     ppc_tb_t *tb_env = env->tb_env;
     uint64_t diff;
 
-    diff = qemu_get_clock_ns(vm_clock) - tb_env->purr_start;
+    diff = qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL) - tb_env->purr_start;
 
     return tb_env->purr_load + muldiv64(diff, tb_env->tb_freq, get_ticks_per_sec());
 }
@@ -701,7 +701,7 @@ static void __cpu_ppc_store_decr(PowerPCCPU *cpu, uint64_t *nextp,
         return;
     }
 
-    now = qemu_get_clock_ns(vm_clock);
+    now = qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL);
     next = now + muldiv64(value, get_ticks_per_sec(), tb_env->decr_freq);
     if (is_excp) {
         next += *nextp - now;
@@ -711,7 +711,7 @@ static void __cpu_ppc_store_decr(PowerPCCPU *cpu, uint64_t *nextp,
     }
     *nextp = next;
     /* Adjust timer */
-    qemu_mod_timer(timer, next);
+    timer_mod(timer, next);
 
     /* If we set a negative value and the decrementer was positive, raise an
      * exception.
@@ -776,7 +776,7 @@ static void cpu_ppc_store_purr(PowerPCCPU *cpu, uint64_t value)
     ppc_tb_t *tb_env = cpu->env.tb_env;
 
     tb_env->purr_load = value;
-    tb_env->purr_start = qemu_get_clock_ns(vm_clock);
+    tb_env->purr_start = qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL);
 }
 
 static void cpu_ppc_set_tb_clk (void *opaque, uint32_t freq)
@@ -806,11 +806,11 @@ clk_setup_cb cpu_ppc_tb_init (CPUPPCState *env, uint32_t freq)
     env->tb_env = tb_env;
     tb_env->flags = PPC_DECR_UNDERFLOW_TRIGGERED;
     /* Create new timer */
-    tb_env->decr_timer = qemu_new_timer_ns(vm_clock, &cpu_ppc_decr_cb, cpu);
+    tb_env->decr_timer = timer_new_ns(QEMU_CLOCK_VIRTUAL, &cpu_ppc_decr_cb, cpu);
     if (0) {
         /* XXX: find a suitable condition to enable the hypervisor decrementer
          */
-        tb_env->hdecr_timer = qemu_new_timer_ns(vm_clock, &cpu_ppc_hdecr_cb,
+        tb_env->hdecr_timer = timer_new_ns(QEMU_CLOCK_VIRTUAL, &cpu_ppc_hdecr_cb,
                                                 cpu);
     } else {
         tb_env->hdecr_timer = NULL;
@@ -877,7 +877,7 @@ static void cpu_4xx_fit_cb (void *opaque)
     cpu = ppc_env_get_cpu(env);
     tb_env = env->tb_env;
     ppc40x_timer = tb_env->opaque;
-    now = qemu_get_clock_ns(vm_clock);
+    now = qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL);
     switch ((env->spr[SPR_40x_TCR] >> 24) & 0x3) {
     case 0:
         next = 1 << 9;
@@ -898,7 +898,7 @@ static void cpu_4xx_fit_cb (void *opaque)
     next = now + muldiv64(next, get_ticks_per_sec(), tb_env->tb_freq);
     if (next == now)
         next++;
-    qemu_mod_timer(ppc40x_timer->fit_timer, next);
+    timer_mod(ppc40x_timer->fit_timer, next);
     env->spr[SPR_40x_TSR] |= 1 << 26;
     if ((env->spr[SPR_40x_TCR] >> 23) & 0x1) {
         ppc_set_irq(cpu, PPC_INTERRUPT_FIT, 1);
@@ -920,18 +920,18 @@ static void start_stop_pit (CPUPPCState *env, ppc_tb_t *tb_env, int is_excp)
         (is_excp && !((env->spr[SPR_40x_TCR] >> 22) & 0x1))) {
         /* Stop PIT */
         LOG_TB("%s: stop PIT\n", __func__);
-        qemu_del_timer(tb_env->decr_timer);
+        timer_del(tb_env->decr_timer);
     } else {
         LOG_TB("%s: start PIT %016" PRIx64 "\n",
                     __func__, ppc40x_timer->pit_reload);
-        now = qemu_get_clock_ns(vm_clock);
+        now = qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL);
         next = now + muldiv64(ppc40x_timer->pit_reload,
                               get_ticks_per_sec(), tb_env->decr_freq);
         if (is_excp)
             next += tb_env->decr_next - now;
         if (next == now)
             next++;
-        qemu_mod_timer(tb_env->decr_timer, next);
+        timer_mod(tb_env->decr_timer, next);
         tb_env->decr_next = next;
     }
 }
@@ -973,7 +973,7 @@ static void cpu_4xx_wdt_cb (void *opaque)
     cpu = ppc_env_get_cpu(env);
     tb_env = env->tb_env;
     ppc40x_timer = tb_env->opaque;
-    now = qemu_get_clock_ns(vm_clock);
+    now = qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL);
     switch ((env->spr[SPR_40x_TCR] >> 30) & 0x3) {
     case 0:
         next = 1 << 17;
@@ -999,12 +999,12 @@ static void cpu_4xx_wdt_cb (void *opaque)
     switch ((env->spr[SPR_40x_TSR] >> 30) & 0x3) {
     case 0x0:
     case 0x1:
-        qemu_mod_timer(ppc40x_timer->wdt_timer, next);
+        timer_mod(ppc40x_timer->wdt_timer, next);
         ppc40x_timer->wdt_next = next;
         env->spr[SPR_40x_TSR] |= 1 << 31;
         break;
     case 0x2:
-        qemu_mod_timer(ppc40x_timer->wdt_timer, next);
+        timer_mod(ppc40x_timer->wdt_timer, next);
         ppc40x_timer->wdt_next = next;
         env->spr[SPR_40x_TSR] |= 1 << 30;
         if ((env->spr[SPR_40x_TCR] >> 27) & 0x1) {
@@ -1076,11 +1076,11 @@ clk_setup_cb ppc_40x_timers_init (CPUPPCState *env, uint32_t freq,
     LOG_TB("%s freq %" PRIu32 "\n", __func__, freq);
     if (ppc40x_timer != NULL) {
         /* We use decr timer for PIT */
-        tb_env->decr_timer = qemu_new_timer_ns(vm_clock, &cpu_4xx_pit_cb, env);
+        tb_env->decr_timer = timer_new_ns(QEMU_CLOCK_VIRTUAL, &cpu_4xx_pit_cb, env);
         ppc40x_timer->fit_timer =
-            qemu_new_timer_ns(vm_clock, &cpu_4xx_fit_cb, env);
+            timer_new_ns(QEMU_CLOCK_VIRTUAL, &cpu_4xx_fit_cb, env);
         ppc40x_timer->wdt_timer =
-            qemu_new_timer_ns(vm_clock, &cpu_4xx_wdt_cb, env);
+            timer_new_ns(QEMU_CLOCK_VIRTUAL, &cpu_4xx_wdt_cb, env);
         ppc40x_timer->decr_excp = decr_excp;
     }
 
diff --git a/hw/ppc/ppc405_uc.c b/hw/ppc/ppc405_uc.c
index 290f71a..0ef5254 100644
--- a/hw/ppc/ppc405_uc.c
+++ b/hw/ppc/ppc405_uc.c
@@ -1348,7 +1348,7 @@ static uint32_t ppc4xx_gpt_readl (void *opaque, hwaddr addr)
     switch (addr) {
     case 0x00:
         /* Time base counter */
-        ret = muldiv64(qemu_get_clock_ns(vm_clock) + gpt->tb_offset,
+        ret = muldiv64(qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL) + gpt->tb_offset,
                        gpt->tb_freq, get_ticks_per_sec());
         break;
     case 0x10:
@@ -1405,7 +1405,7 @@ static void ppc4xx_gpt_writel (void *opaque,
     case 0x00:
         /* Time base counter */
         gpt->tb_offset = muldiv64(value, get_ticks_per_sec(), gpt->tb_freq)
-            - qemu_get_clock_ns(vm_clock);
+            - qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL);
         ppc4xx_gpt_compute_timer(gpt);
         break;
     case 0x10:
@@ -1476,7 +1476,7 @@ static void ppc4xx_gpt_reset (void *opaque)
     int i;
 
     gpt = opaque;
-    qemu_del_timer(gpt->timer);
+    timer_del(gpt->timer);
     gpt->oe = 0x00000000;
     gpt->ol = 0x00000000;
     gpt->im = 0x00000000;
@@ -1497,7 +1497,7 @@ static void ppc4xx_gpt_init(hwaddr base, qemu_irq irqs[5])
     for (i = 0; i < 5; i++) {
         gpt->irqs[i] = irqs[i];
     }
-    gpt->timer = qemu_new_timer_ns(vm_clock, &ppc4xx_gpt_cb, gpt);
+    gpt->timer = timer_new_ns(QEMU_CLOCK_VIRTUAL, &ppc4xx_gpt_cb, gpt);
 #ifdef DEBUG_GPT
     printf("%s: offset " TARGET_FMT_plx "\n", __func__, base);
 #endif
diff --git a/hw/ppc/ppc_booke.c b/hw/ppc/ppc_booke.c
index 000c27f..8bbfc72 100644
--- a/hw/ppc/ppc_booke.c
+++ b/hw/ppc/ppc_booke.c
@@ -136,7 +136,7 @@ static void booke_update_fixed_timer(CPUPPCState         *env,
     uint64_t period;
     uint64_t now;
 
-    now = qemu_get_clock_ns(vm_clock);
+    now = qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL);
     tb  = cpu_ppc_get_tb(tb_env, now, tb_env->tb_offset);
     period = 1ULL << target_bit;
     delta_tick = period - (tb & (period - 1));
@@ -167,7 +167,7 @@ static void booke_update_fixed_timer(CPUPPCState         *env,
         (*next)++;
     }
 
-    qemu_mod_timer(timer, *next);
+    timer_mod(timer, *next);
 }
 
 static void booke_decr_cb(void *opaque)
@@ -303,12 +303,12 @@ void ppc_booke_timers_init(PowerPCCPU *cpu, uint32_t freq, uint32_t flags)
     tb_env->tb_freq    = freq;
     tb_env->decr_freq  = freq;
     tb_env->opaque     = booke_timer;
-    tb_env->decr_timer = qemu_new_timer_ns(vm_clock, &booke_decr_cb, cpu);
+    tb_env->decr_timer = timer_new_ns(QEMU_CLOCK_VIRTUAL, &booke_decr_cb, cpu);
 
     booke_timer->fit_timer =
-        qemu_new_timer_ns(vm_clock, &booke_fit_cb, cpu);
+        timer_new_ns(QEMU_CLOCK_VIRTUAL, &booke_fit_cb, cpu);
     booke_timer->wdt_timer =
-        qemu_new_timer_ns(vm_clock, &booke_wdt_cb, cpu);
+        timer_new_ns(QEMU_CLOCK_VIRTUAL, &booke_wdt_cb, cpu);
 
     ret = kvmppc_booke_watchdog_enable(cpu);
 
diff --git a/hw/ppc/spapr.c b/hw/ppc/spapr.c
index 16bfab9..4b566aa 100644
--- a/hw/ppc/spapr.c
+++ b/hw/ppc/spapr.c
@@ -789,7 +789,7 @@ static void htab_save_first_pass(QEMUFile *f, sPAPREnvironment *spapr,
 {
     int htabslots = HTAB_SIZE(spapr) / HASH_PTE_SIZE_64;
     int index = spapr->htab_save_index;
-    int64_t starttime = qemu_get_clock_ns(rt_clock);
+    int64_t starttime = qemu_clock_get_ns(QEMU_CLOCK_REALTIME);
 
     assert(spapr->htab_first_pass);
 
@@ -820,7 +820,7 @@ static void htab_save_first_pass(QEMUFile *f, sPAPREnvironment *spapr,
             qemu_put_buffer(f, HPTE(spapr->htab, chunkstart),
                             HASH_PTE_SIZE_64 * n_valid);
 
-            if ((qemu_get_clock_ns(rt_clock) - starttime) > max_ns) {
+            if ((qemu_clock_get_ns(QEMU_CLOCK_REALTIME) - starttime) > max_ns) {
                 break;
             }
         }
@@ -841,7 +841,7 @@ static int htab_save_later_pass(QEMUFile *f, sPAPREnvironment *spapr,
     int htabslots = HTAB_SIZE(spapr) / HASH_PTE_SIZE_64;
     int examined = 0, sent = 0;
     int index = spapr->htab_save_index;
-    int64_t starttime = qemu_get_clock_ns(rt_clock);
+    int64_t starttime = qemu_clock_get_ns(QEMU_CLOCK_REALTIME);
 
     assert(!spapr->htab_first_pass);
 
@@ -886,7 +886,7 @@ static int htab_save_later_pass(QEMUFile *f, sPAPREnvironment *spapr,
                             HASH_PTE_SIZE_64 * n_valid);
             sent += index - chunkstart;
 
-            if (!final && (qemu_get_clock_ns(rt_clock) - starttime) > max_ns) {
+            if (!final && (qemu_clock_get_ns(QEMU_CLOCK_REALTIME) - starttime) > max_ns) {
                 break;
             }
         }
diff --git a/hw/sd/sdhci.c b/hw/sd/sdhci.c
index d2dbddc..1483e19 100644
--- a/hw/sd/sdhci.c
+++ b/hw/sd/sdhci.c
@@ -134,8 +134,8 @@ static void sdhci_raise_insertion_irq(void *opaque)
     SDHCIState *s = (SDHCIState *)opaque;
 
     if (s->norintsts & SDHC_NIS_REMOVE) {
-        qemu_mod_timer(s->insert_timer,
-                       qemu_get_clock_ns(vm_clock) + SDHC_INSERTION_DELAY);
+        timer_mod(s->insert_timer,
+                       qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL) + SDHC_INSERTION_DELAY);
     } else {
         s->prnsts = 0x1ff0000;
         if (s->norintstsen & SDHC_NISEN_INSERT) {
@@ -152,8 +152,8 @@ static void sdhci_insert_eject_cb(void *opaque, int irq, int level)
 
     if ((s->norintsts & SDHC_NIS_REMOVE) && level) {
         /* Give target some time to notice card ejection */
-        qemu_mod_timer(s->insert_timer,
-                       qemu_get_clock_ns(vm_clock) + SDHC_INSERTION_DELAY);
+        timer_mod(s->insert_timer,
+                       qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL) + SDHC_INSERTION_DELAY);
     } else {
         if (level) {
             s->prnsts = 0x1ff0000;
@@ -186,8 +186,8 @@ static void sdhci_card_readonly_cb(void *opaque, int irq, int level)
 
 static void sdhci_reset(SDHCIState *s)
 {
-    qemu_del_timer(s->insert_timer);
-    qemu_del_timer(s->transfer_timer);
+    timer_del(s->insert_timer);
+    timer_del(s->transfer_timer);
     /* Set all registers to 0. Capabilities registers are not cleared
      * and assumed to always preserve their value, given to them during
      * initialization */
@@ -764,8 +764,8 @@ static void sdhci_do_adma(SDHCIState *s)
     }
 
     /* we have unfinished business - reschedule to continue ADMA */
-    qemu_mod_timer(s->transfer_timer,
-                   qemu_get_clock_ns(vm_clock) + SDHC_TRANSFER_DELAY);
+    timer_mod(s->transfer_timer,
+                   qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL) + SDHC_TRANSFER_DELAY);
 }
 
 /* Perform data transfer according to controller configuration */
@@ -1170,18 +1170,18 @@ static void sdhci_initfn(Object *obj)
     s->ro_cb = qemu_allocate_irqs(sdhci_card_readonly_cb, s, 1)[0];
     sd_set_cb(s->card, s->ro_cb, s->eject_cb);
 
-    s->insert_timer = qemu_new_timer_ns(vm_clock, sdhci_raise_insertion_irq, s);
-    s->transfer_timer = qemu_new_timer_ns(vm_clock, sdhci_do_data_transfer, s);
+    s->insert_timer = timer_new_ns(QEMU_CLOCK_VIRTUAL, sdhci_raise_insertion_irq, s);
+    s->transfer_timer = timer_new_ns(QEMU_CLOCK_VIRTUAL, sdhci_do_data_transfer, s);
 }
 
 static void sdhci_uninitfn(Object *obj)
 {
     SDHCIState *s = SDHCI(obj);
 
-    qemu_del_timer(s->insert_timer);
-    qemu_free_timer(s->insert_timer);
-    qemu_del_timer(s->transfer_timer);
-    qemu_free_timer(s->transfer_timer);
+    timer_del(s->insert_timer);
+    timer_free(s->insert_timer);
+    timer_del(s->transfer_timer);
+    timer_free(s->transfer_timer);
     qemu_free_irqs(&s->eject_cb);
     qemu_free_irqs(&s->ro_cb);
 
diff --git a/hw/sparc64/sun4u.c b/hw/sparc64/sun4u.c
index 2165bb0..50a9f24 100644
--- a/hw/sparc64/sun4u.c
+++ b/hw/sparc64/sun4u.c
@@ -387,9 +387,9 @@ static CPUTimer *cpu_timer_create(const char *name, SPARCCPU *cpu,
     timer->disabled_mask = disabled_mask;
 
     timer->disabled = 1;
-    timer->clock_offset = qemu_get_clock_ns(vm_clock);
+    timer->clock_offset = qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL);
 
-    timer->qtimer = qemu_new_timer_ns(vm_clock, cb, cpu);
+    timer->qtimer = timer_new_ns(QEMU_CLOCK_VIRTUAL, cb, cpu);
 
     return timer;
 }
@@ -397,9 +397,9 @@ static CPUTimer *cpu_timer_create(const char *name, SPARCCPU *cpu,
 static void cpu_timer_reset(CPUTimer *timer)
 {
     timer->disabled = 1;
-    timer->clock_offset = qemu_get_clock_ns(vm_clock);
+    timer->clock_offset = qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL);
 
-    qemu_del_timer(timer->qtimer);
+    timer_del(timer->qtimer);
 }
 
 static void main_cpu_reset(void *opaque)
@@ -495,7 +495,7 @@ void cpu_tick_set_count(CPUTimer *timer, uint64_t count)
     uint64_t real_count = count & ~timer->disabled_mask;
     uint64_t disabled_bit = count & timer->disabled_mask;
 
-    int64_t vm_clock_offset = qemu_get_clock_ns(vm_clock) -
+    int64_t vm_clock_offset = qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL) -
                     cpu_to_timer_ticks(real_count, timer->frequency);
 
     TIMER_DPRINTF("%s set_count count=0x%016lx (%s) p=%p\n",
@@ -509,7 +509,7 @@ void cpu_tick_set_count(CPUTimer *timer, uint64_t count)
 uint64_t cpu_tick_get_count(CPUTimer *timer)
 {
     uint64_t real_count = timer_to_cpu_ticks(
-                    qemu_get_clock_ns(vm_clock) - timer->clock_offset,
+                    qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL) - timer->clock_offset,
                     timer->frequency);
 
     TIMER_DPRINTF("%s get_count count=0x%016lx (%s) p=%p\n",
@@ -524,7 +524,7 @@ uint64_t cpu_tick_get_count(CPUTimer *timer)
 
 void cpu_tick_set_limit(CPUTimer *timer, uint64_t limit)
 {
-    int64_t now = qemu_get_clock_ns(vm_clock);
+    int64_t now = qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL);
 
     uint64_t real_limit = limit & ~timer->disabled_mask;
     timer->disabled = (limit & timer->disabled_mask) ? 1 : 0;
@@ -548,11 +548,11 @@ void cpu_tick_set_limit(CPUTimer *timer, uint64_t limit)
     if (!real_limit) {
         TIMER_DPRINTF("%s set_limit limit=ZERO - not starting timer\n",
                 timer->name);
-        qemu_del_timer(timer->qtimer);
+        timer_del(timer->qtimer);
     } else if (timer->disabled) {
-        qemu_del_timer(timer->qtimer);
+        timer_del(timer->qtimer);
     } else {
-        qemu_mod_timer(timer->qtimer, expires);
+        timer_mod(timer->qtimer, expires);
     }
 }
 
diff --git a/hw/timer/arm_mptimer.c b/hw/timer/arm_mptimer.c
index 9277315..8020c9f 100644
--- a/hw/timer/arm_mptimer.c
+++ b/hw/timer/arm_mptimer.c
@@ -81,10 +81,10 @@ static void timerblock_reload(TimerBlock *tb, int restart)
         return;
     }
     if (restart) {
-        tb->tick = qemu_get_clock_ns(vm_clock);
+        tb->tick = qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL);
     }
     tb->tick += (int64_t)tb->count * timerblock_scale(tb);
-    qemu_mod_timer(tb->timer, tb->tick);
+    timer_mod(tb->timer, tb->tick);
 }
 
 static void timerblock_tick(void *opaque)
@@ -113,7 +113,7 @@ static uint64_t timerblock_read(void *opaque, hwaddr addr,
             return 0;
         }
         /* Slow and ugly, but hopefully won't happen too often.  */
-        val = tb->tick - qemu_get_clock_ns(vm_clock);
+        val = tb->tick - qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL);
         val /= timerblock_scale(tb);
         if (val < 0) {
             val = 0;
@@ -140,7 +140,7 @@ static void timerblock_write(void *opaque, hwaddr addr,
     case 4: /* Counter.  */
         if ((tb->control & 1) && tb->count) {
             /* Cancel the previous timer.  */
-            qemu_del_timer(tb->timer);
+            timer_del(tb->timer);
         }
         tb->count = value;
         if (tb->control & 1) {
@@ -211,7 +211,7 @@ static void timerblock_reset(TimerBlock *tb)
     tb->status = 0;
     tb->tick = 0;
     if (tb->timer) {
-        qemu_del_timer(tb->timer);
+        timer_del(tb->timer);
     }
 }
 
@@ -248,7 +248,7 @@ static int arm_mptimer_init(SysBusDevice *dev)
     sysbus_init_mmio(dev, &s->iomem);
     for (i = 0; i < s->num_cpu; i++) {
         TimerBlock *tb = &s->timerblock[i];
-        tb->timer = qemu_new_timer_ns(vm_clock, timerblock_tick, tb);
+        tb->timer = timer_new_ns(QEMU_CLOCK_VIRTUAL, timerblock_tick, tb);
         sysbus_init_irq(dev, &tb->irq);
         memory_region_init_io(&tb->iomem, OBJECT(s), &timerblock_ops, tb,
                               "arm_mptimer_timerblock", 0x20);
diff --git a/hw/timer/cadence_ttc.c b/hw/timer/cadence_ttc.c
index 888f9ce..a279bce 100644
--- a/hw/timer/cadence_ttc.c
+++ b/hw/timer/cadence_ttc.c
@@ -172,7 +172,7 @@ static void cadence_timer_run(CadenceTimerState *s)
     event_interval = next_value - (int64_t)s->reg_value;
     event_interval = (event_interval < 0) ? -event_interval : event_interval;
 
-    qemu_mod_timer(s->timer, s->cpu_time +
+    timer_mod(s->timer, s->cpu_time +
                 cadence_timer_get_ns(s, event_interval));
 }
 
@@ -184,7 +184,7 @@ static void cadence_timer_sync(CadenceTimerState *s)
             (int64_t)s->reg_interval + 1 : 0x10000ULL) << 16;
     uint64_t old_time = s->cpu_time;
 
-    s->cpu_time = qemu_get_clock_ns(vm_clock);
+    s->cpu_time = qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL);
     DB_PRINT("cpu time: %lld ns\n", (long long)old_time);
 
     if (!s->cpu_time_valid || old_time == s->cpu_time) {
@@ -401,7 +401,7 @@ static void cadence_timer_init(uint32_t freq, CadenceTimerState *s)
 
     cadence_timer_reset(s);
 
-    s->timer = qemu_new_timer_ns(vm_clock, cadence_timer_tick, s);
+    s->timer = timer_new_ns(QEMU_CLOCK_VIRTUAL, cadence_timer_tick, s);
 }
 
 static int cadence_ttc_init(SysBusDevice *dev)
diff --git a/hw/timer/etraxfs_timer.c b/hw/timer/etraxfs_timer.c
index a38d9e4..aee4990 100644
--- a/hw/timer/etraxfs_timer.c
+++ b/hw/timer/etraxfs_timer.c
@@ -93,7 +93,7 @@ timer_read(void *opaque, hwaddr addr, unsigned int size)
         r = ptimer_get_count(t->ptimer_t1);
         break;
     case R_TIME:
-        r = qemu_get_clock_ns(vm_clock) / 10;
+        r = qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL) / 10;
         break;
     case RW_INTR_MASK:
         r = t->rw_intr_mask;
diff --git a/hw/timer/exynos4210_mct.c b/hw/timer/exynos4210_mct.c
index 13b1889..86f4fcd 100644
--- a/hw/timer/exynos4210_mct.c
+++ b/hw/timer/exynos4210_mct.c
@@ -906,7 +906,7 @@ static void exynos4210_ltick_event(void *opaque)
         /* raise interrupt if enabled */
         if (s->reg.int_enb & L_INT_INTENB_ICNTEIE) {
 #ifdef DEBUG_MCT
-            time2[s->id] = qemu_get_clock_ns(vm_clock);
+            time2[s->id] = qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL);
             DPRINTF("local timer[%d] IRQ: %llx\n", s->id,
                     time2[s->id] - time1[s->id]);
             time1[s->id] = time2[s->id];
diff --git a/hw/timer/hpet.c b/hw/timer/hpet.c
index 648b383..fcd22ae 100644
--- a/hw/timer/hpet.c
+++ b/hw/timer/hpet.c
@@ -152,7 +152,7 @@ static int deactivating_bit(uint64_t old, uint64_t new, uint64_t mask)
 
 static uint64_t hpet_get_ticks(HPETState *s)
 {
-    return ns_to_ticks(qemu_get_clock_ns(vm_clock) + s->hpet_offset);
+    return ns_to_ticks(qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL) + s->hpet_offset);
 }
 
 /*
@@ -233,7 +233,7 @@ static int hpet_post_load(void *opaque, int version_id)
     HPETState *s = opaque;
 
     /* Recalculate the offset between the main counter and guest time */
-    s->hpet_offset = ticks_to_ns(s->hpet_counter) - qemu_get_clock_ns(vm_clock);
+    s->hpet_offset = ticks_to_ns(s->hpet_counter) - qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL);
 
     /* Push number of timers into capability returned via HPET_ID */
     s->capability &= ~HPET_ID_NUM_TIM_MASK;
@@ -332,12 +332,12 @@ static void hpet_timer(void *opaque)
             }
         }
         diff = hpet_calculate_diff(t, cur_tick);
-        qemu_mod_timer(t->qemu_timer,
-                       qemu_get_clock_ns(vm_clock) + (int64_t)ticks_to_ns(diff));
+        timer_mod(t->qemu_timer,
+                       qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL) + (int64_t)ticks_to_ns(diff));
     } else if (t->config & HPET_TN_32BIT && !timer_is_periodic(t)) {
         if (t->wrap_flag) {
             diff = hpet_calculate_diff(t, cur_tick);
-            qemu_mod_timer(t->qemu_timer, qemu_get_clock_ns(vm_clock) +
+            timer_mod(t->qemu_timer, qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL) +
                            (int64_t)ticks_to_ns(diff));
             t->wrap_flag = 0;
         }
@@ -365,13 +365,13 @@ static void hpet_set_timer(HPETTimer *t)
             t->wrap_flag = 1;
         }
     }
-    qemu_mod_timer(t->qemu_timer,
-                   qemu_get_clock_ns(vm_clock) + (int64_t)ticks_to_ns(diff));
+    timer_mod(t->qemu_timer,
+                   qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL) + (int64_t)ticks_to_ns(diff));
 }
 
 static void hpet_del_timer(HPETTimer *t)
 {
-    qemu_del_timer(t->qemu_timer);
+    timer_del(t->qemu_timer);
     update_irq(t, 0);
 }
 
@@ -567,7 +567,7 @@ static void hpet_ram_write(void *opaque, hwaddr addr,
             if (activating_bit(old_val, new_val, HPET_CFG_ENABLE)) {
                 /* Enable main counter and interrupt generation. */
                 s->hpet_offset =
-                    ticks_to_ns(s->hpet_counter) - qemu_get_clock_ns(vm_clock);
+                    ticks_to_ns(s->hpet_counter) - qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL);
                 for (i = 0; i < s->num_timers; i++) {
                     if ((&s->timer[i])->cmp != ~0ULL) {
                         hpet_set_timer(&s->timer[i]);
@@ -726,7 +726,7 @@ static void hpet_realize(DeviceState *dev, Error **errp)
     }
     for (i = 0; i < HPET_MAX_TIMERS; i++) {
         timer = &s->timer[i];
-        timer->qemu_timer = qemu_new_timer_ns(vm_clock, hpet_timer, timer);
+        timer->qemu_timer = timer_new_ns(QEMU_CLOCK_VIRTUAL, hpet_timer, timer);
         timer->tn = i;
         timer->state = s;
     }
diff --git a/hw/timer/i8254.c b/hw/timer/i8254.c
index cd52140..cdbf481 100644
--- a/hw/timer/i8254.c
+++ b/hw/timer/i8254.c
@@ -51,7 +51,7 @@ static int pit_get_count(PITChannelState *s)
     uint64_t d;
     int counter;
 
-    d = muldiv64(qemu_get_clock_ns(vm_clock) - s->count_load_time, PIT_FREQ,
+    d = muldiv64(qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL) - s->count_load_time, PIT_FREQ,
                  get_ticks_per_sec());
     switch(s->mode) {
     case 0:
@@ -85,7 +85,7 @@ static void pit_set_channel_gate(PITCommonState *s, PITChannelState *sc,
     case 5:
         if (sc->gate < val) {
             /* restart counting on rising edge */
-            sc->count_load_time = qemu_get_clock_ns(vm_clock);
+            sc->count_load_time = qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL);
             pit_irq_timer_update(sc, sc->count_load_time);
         }
         break;
@@ -93,7 +93,7 @@ static void pit_set_channel_gate(PITCommonState *s, PITChannelState *sc,
     case 3:
         if (sc->gate < val) {
             /* restart counting on rising edge */
-            sc->count_load_time = qemu_get_clock_ns(vm_clock);
+            sc->count_load_time = qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL);
             pit_irq_timer_update(sc, sc->count_load_time);
         }
         /* XXX: disable/enable counting */
@@ -106,7 +106,7 @@ static inline void pit_load_count(PITChannelState *s, int val)
 {
     if (val == 0)
         val = 0x10000;
-    s->count_load_time = qemu_get_clock_ns(vm_clock);
+    s->count_load_time = qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL);
     s->count = val;
     pit_irq_timer_update(s, s->count_load_time);
 }
@@ -143,7 +143,7 @@ static void pit_ioport_write(void *opaque, hwaddr addr,
                         /* XXX: add BCD and null count */
                         s->status =
                             (pit_get_out(s,
-                                         qemu_get_clock_ns(vm_clock)) << 7) |
+                                         qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL)) << 7) |
                             (s->rw_mode << 4) |
                             (s->mode << 1) |
                             s->bcd;
@@ -260,9 +260,9 @@ static void pit_irq_timer_update(PITChannelState *s, int64_t current_time)
 #endif
     s->next_transition_time = expire_time;
     if (expire_time != -1)
-        qemu_mod_timer(s->irq_timer, expire_time);
+        timer_mod(s->irq_timer, expire_time);
     else
-        qemu_del_timer(s->irq_timer);
+        timer_del(s->irq_timer);
 }
 
 static void pit_irq_timer(void *opaque)
@@ -281,7 +281,7 @@ static void pit_reset(DeviceState *dev)
 
     s = &pit->channels[0];
     if (!s->irq_disabled) {
-        qemu_mod_timer(s->irq_timer, s->next_transition_time);
+        timer_mod(s->irq_timer, s->next_transition_time);
     }
 }
 
@@ -294,10 +294,10 @@ static void pit_irq_control(void *opaque, int n, int enable)
 
     if (enable) {
         s->irq_disabled = 0;
-        pit_irq_timer_update(s, qemu_get_clock_ns(vm_clock));
+        pit_irq_timer_update(s, qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL));
     } else {
         s->irq_disabled = 1;
-        qemu_del_timer(s->irq_timer);
+        timer_del(s->irq_timer);
     }
 }
 
@@ -316,9 +316,9 @@ static void pit_post_load(PITCommonState *s)
     PITChannelState *sc = &s->channels[0];
 
     if (sc->next_transition_time != -1) {
-        qemu_mod_timer(sc->irq_timer, sc->next_transition_time);
+        timer_mod(sc->irq_timer, sc->next_transition_time);
     } else {
-        qemu_del_timer(sc->irq_timer);
+        timer_del(sc->irq_timer);
     }
 }
 
@@ -330,7 +330,7 @@ static void pit_realizefn(DeviceState *dev, Error **err)
 
     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);
+    s->irq_timer = timer_new_ns(QEMU_CLOCK_VIRTUAL, pit_irq_timer, s);
     qdev_init_gpio_out(dev, &s->irq, 1);
 
     memory_region_init_io(&pit->ioports, OBJECT(pit), &pit_ioport_ops,
diff --git a/hw/timer/i8254_common.c b/hw/timer/i8254_common.c
index 4e5bf0b..e8fb971 100644
--- a/hw/timer/i8254_common.c
+++ b/hw/timer/i8254_common.c
@@ -136,7 +136,7 @@ void pit_get_channel_info_common(PITCommonState *s, PITChannelState *sc,
     info->gate = sc->gate;
     info->mode = sc->mode;
     info->initial_count = sc->count;
-    info->out = pit_get_out(sc, qemu_get_clock_ns(vm_clock));
+    info->out = pit_get_out(sc, qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL));
 }
 
 void pit_get_channel_info(ISADevice *dev, int channel, PITChannelInfo *info)
@@ -157,7 +157,7 @@ void pit_reset_common(PITCommonState *pit)
         s = &pit->channels[i];
         s->mode = 3;
         s->gate = (i != 2);
-        s->count_load_time = qemu_get_clock_ns(vm_clock);
+        s->count_load_time = qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL);
         s->count = 0x10000;
         if (i == 0 && !s->irq_disabled) {
             s->next_transition_time =
diff --git a/hw/timer/m48t59.c b/hw/timer/m48t59.c
index 098e5ad..d3d78ec 100644
--- a/hw/timer/m48t59.c
+++ b/hw/timer/m48t59.c
@@ -137,7 +137,7 @@ static void alarm_cb (void *opaque)
         /* Repeat once a second */
         next_time = 1;
     }
-    qemu_mod_timer(NVRAM->alrm_timer, qemu_clock_get_ns(rtc_clock) +
+    timer_mod(NVRAM->alrm_timer, qemu_clock_get_ns(rtc_clock) +
                     next_time * 1000);
     qemu_set_irq(NVRAM->IRQ, 0);
 }
@@ -146,10 +146,10 @@ static void set_alarm(M48t59State *NVRAM)
 {
     int diff;
     if (NVRAM->alrm_timer != NULL) {
-        qemu_del_timer(NVRAM->alrm_timer);
+        timer_del(NVRAM->alrm_timer);
         diff = qemu_timedate_diff(&NVRAM->alarm) - NVRAM->time_offset;
         if (diff > 0)
-            qemu_mod_timer(NVRAM->alrm_timer, diff * 1000);
+            timer_mod(NVRAM->alrm_timer, diff * 1000);
     }
 }
 
@@ -188,10 +188,10 @@ static void set_up_watchdog(M48t59State *NVRAM, uint8_t value)
 
     NVRAM->buffer[0x1FF0] &= ~0x80;
     if (NVRAM->wd_timer != NULL) {
-        qemu_del_timer(NVRAM->wd_timer);
+        timer_del(NVRAM->wd_timer);
         if (value != 0) {
             interval = (1 << (2 * (value & 0x03))) * ((value >> 2) & 0x1F);
-            qemu_mod_timer(NVRAM->wd_timer, ((uint64_t)time(NULL) * 1000) +
+            timer_mod(NVRAM->wd_timer, ((uint64_t)time(NULL) * 1000) +
                            ((interval * 1000) >> 4));
         }
     }
@@ -609,10 +609,10 @@ static void m48t59_reset_common(M48t59State *NVRAM)
     NVRAM->addr = 0;
     NVRAM->lock = 0;
     if (NVRAM->alrm_timer != NULL)
-        qemu_del_timer(NVRAM->alrm_timer);
+        timer_del(NVRAM->alrm_timer);
 
     if (NVRAM->wd_timer != NULL)
-        qemu_del_timer(NVRAM->wd_timer);
+        timer_del(NVRAM->wd_timer);
 }
 
 static void m48t59_reset_isa(DeviceState *d)
@@ -701,7 +701,7 @@ static void m48t59_realize_common(M48t59State *s, Error **errp)
     s->buffer = g_malloc0(s->size);
     if (s->model == 59) {
         s->alrm_timer = timer_new_ns(rtc_clock, &alarm_cb, s);
-        s->wd_timer = qemu_new_timer_ns(vm_clock, &watchdog_cb, s);
+        s->wd_timer = timer_new_ns(QEMU_CLOCK_VIRTUAL, &watchdog_cb, s);
     }
     qemu_get_timedate(&s->alarm, 0);
 
diff --git a/hw/timer/mc146818rtc.c b/hw/timer/mc146818rtc.c
index 1c6bb29..7230a6e 100644
--- a/hw/timer/mc146818rtc.c
+++ b/hw/timer/mc146818rtc.c
@@ -113,13 +113,13 @@ static uint64_t get_guest_rtc_ns(RTCState *s)
 static void rtc_coalesced_timer_update(RTCState *s)
 {
     if (s->irq_coalesced == 0) {
-        qemu_del_timer(s->coalesced_timer);
+        timer_del(s->coalesced_timer);
     } else {
         /* divide each RTC interval to 2 - 8 smaller intervals */
         int c = MIN(s->irq_coalesced, 7) + 1; 
         int64_t next_clock = qemu_clock_get_ns(rtc_clock) +
             muldiv64(s->period / c, get_ticks_per_sec(), RTC_CLOCK_RATE);
-        qemu_mod_timer(s->coalesced_timer, next_clock);
+        timer_mod(s->coalesced_timer, next_clock);
     }
 }
 
@@ -169,12 +169,12 @@ static void periodic_timer_update(RTCState *s, int64_t current_time)
         next_irq_clock = (cur_clock & ~(period - 1)) + period;
         s->next_periodic_time =
             muldiv64(next_irq_clock, get_ticks_per_sec(), RTC_CLOCK_RATE) + 1;
-        qemu_mod_timer(s->periodic_timer, s->next_periodic_time);
+        timer_mod(s->periodic_timer, s->next_periodic_time);
     } else {
 #ifdef TARGET_I386
         s->irq_coalesced = 0;
 #endif
-        qemu_del_timer(s->periodic_timer);
+        timer_del(s->periodic_timer);
     }
 }
 
@@ -222,17 +222,17 @@ static void check_update_timer(RTCState *s)
      * from occurring, because the time of day is not updated.
      */
     if ((s->cmos_data[RTC_REG_A] & 0x60) == 0x60) {
-        qemu_del_timer(s->update_timer);
+        timer_del(s->update_timer);
         return;
     }
     if ((s->cmos_data[RTC_REG_C] & REG_C_UF) &&
         (s->cmos_data[RTC_REG_B] & REG_B_SET)) {
-        qemu_del_timer(s->update_timer);
+        timer_del(s->update_timer);
         return;
     }
     if ((s->cmos_data[RTC_REG_C] & REG_C_UF) &&
         (s->cmos_data[RTC_REG_C] & REG_C_AF)) {
-        qemu_del_timer(s->update_timer);
+        timer_del(s->update_timer);
         return;
     }
 
@@ -253,7 +253,7 @@ static void check_update_timer(RTCState *s)
         next_update_time = s->next_alarm_time;
     }
     if (next_update_time != timer_expire_time_ns(s->update_timer)) {
-        qemu_mod_timer(s->update_timer, next_update_time);
+        timer_mod(s->update_timer, next_update_time);
     }
 }
 
diff --git a/hw/timer/omap_gptimer.c b/hw/timer/omap_gptimer.c
index ac389d8..016207f 100644
--- a/hw/timer/omap_gptimer.c
+++ b/hw/timer/omap_gptimer.c
@@ -103,7 +103,7 @@ static inline uint32_t omap_gp_timer_read(struct omap_gp_timer_s *timer)
     uint64_t distance;
 
     if (timer->st && timer->rate) {
-        distance = qemu_get_clock_ns(vm_clock) - timer->time;
+        distance = qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL) - timer->time;
         distance = muldiv64(distance, timer->rate, timer->ticks_per_sec);
 
         if (distance >= 0xffffffff - timer->val)
@@ -118,7 +118,7 @@ static inline void omap_gp_timer_sync(struct omap_gp_timer_s *timer)
 {
     if (timer->st) {
         timer->val = omap_gp_timer_read(timer);
-        timer->time = qemu_get_clock_ns(vm_clock);
+        timer->time = qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL);
     }
 }
 
@@ -129,17 +129,17 @@ static inline void omap_gp_timer_update(struct omap_gp_timer_s *timer)
     if (timer->st && timer->rate) {
         expires = muldiv64(0x100000000ll - timer->val,
                         timer->ticks_per_sec, timer->rate);
-        qemu_mod_timer(timer->timer, timer->time + expires);
+        timer_mod(timer->timer, timer->time + expires);
 
         if (timer->ce && timer->match_val >= timer->val) {
             matches = muldiv64(timer->match_val - timer->val,
                             timer->ticks_per_sec, timer->rate);
-            qemu_mod_timer(timer->match, timer->time + matches);
+            timer_mod(timer->match, timer->time + matches);
         } else
-            qemu_del_timer(timer->match);
+            timer_del(timer->match);
     } else {
-        qemu_del_timer(timer->timer);
-        qemu_del_timer(timer->match);
+        timer_del(timer->timer);
+        timer_del(timer->match);
         omap_gp_timer_out(timer, timer->scpwm);
     }
 }
@@ -164,7 +164,7 @@ static void omap_gp_timer_tick(void *opaque)
         timer->val = 0;
     } else {
         timer->val = timer->load_val;
-        timer->time = qemu_get_clock_ns(vm_clock);
+        timer->time = qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL);
     }
 
     if (timer->trigger == gpt_trigger_overflow ||
@@ -406,7 +406,7 @@ static void omap_gp_timer_write(void *opaque, hwaddr addr,
         break;
 
     case 0x28:	/* TCRR */
-        s->time = qemu_get_clock_ns(vm_clock);
+        s->time = qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL);
         s->val = value;
         omap_gp_timer_update(s);
         break;
@@ -416,7 +416,7 @@ static void omap_gp_timer_write(void *opaque, hwaddr addr,
         break;
 
     case 0x30:	/* TTGR */
-        s->time = qemu_get_clock_ns(vm_clock);
+        s->time = qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL);
         s->val = s->load_val;
         omap_gp_timer_update(s);
         break;
@@ -474,8 +474,8 @@ struct omap_gp_timer_s *omap_gp_timer_init(struct omap_target_agent_s *ta,
     s->ta = ta;
     s->irq = irq;
     s->clk = fclk;
-    s->timer = qemu_new_timer_ns(vm_clock, omap_gp_timer_tick, s);
-    s->match = qemu_new_timer_ns(vm_clock, omap_gp_timer_match, s);
+    s->timer = timer_new_ns(QEMU_CLOCK_VIRTUAL, omap_gp_timer_tick, s);
+    s->match = timer_new_ns(QEMU_CLOCK_VIRTUAL, omap_gp_timer_match, s);
     s->in = qemu_allocate_irqs(omap_gp_timer_input, s, 1)[0];
     omap_gp_timer_reset(s);
     omap_gp_timer_clk_setup(s);
diff --git a/hw/timer/omap_synctimer.c b/hw/timer/omap_synctimer.c
index a12aca2..8e50488 100644
--- a/hw/timer/omap_synctimer.c
+++ b/hw/timer/omap_synctimer.c
@@ -28,7 +28,7 @@ struct omap_synctimer_s {
 
 /* 32-kHz Sync Timer of the OMAP2 */
 static uint32_t omap_synctimer_read(struct omap_synctimer_s *s) {
-    return muldiv64(qemu_get_clock_ns(vm_clock), 0x8000, get_ticks_per_sec());
+    return muldiv64(qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL), 0x8000, get_ticks_per_sec());
 }
 
 void omap_synctimer_reset(struct omap_synctimer_s *s)
diff --git a/hw/timer/pl031.c b/hw/timer/pl031.c
index e398a67..65928a4 100644
--- a/hw/timer/pl031.c
+++ b/hw/timer/pl031.c
@@ -91,11 +91,11 @@ static void pl031_set_alarm(PL031State *s)
     ticks = s->mr - pl031_get_count(s);
     DPRINTF("Alarm set in %ud ticks\n", ticks);
     if (ticks == 0) {
-        qemu_del_timer(s->timer);
+        timer_del(s->timer);
         pl031_interrupt(s);
     } else {
         int64_t now = qemu_clock_get_ns(rtc_clock);
-        qemu_mod_timer(s->timer, now + (int64_t)ticks * get_ticks_per_sec());
+        timer_mod(s->timer, now + (int64_t)ticks * get_ticks_per_sec());
     }
 }
 
@@ -213,8 +213,8 @@ static void pl031_pre_save(void *opaque)
     PL031State *s = opaque;
 
     /* tick_offset is base_time - rtc_clock base time.  Instead, we want to
-     * store the base time relative to the vm_clock for backwards-compatibility.  */
-    int64_t delta = qemu_clock_get_ns(rtc_clock) - qemu_get_clock_ns(vm_clock);
+     * store the base time relative to the QEMU_CLOCK_VIRTUAL for backwards-compatibility.  */
+    int64_t delta = qemu_clock_get_ns(rtc_clock) - qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL);
     s->tick_offset_vmstate = s->tick_offset + delta / get_ticks_per_sec();
 }
 
@@ -222,7 +222,7 @@ static int pl031_post_load(void *opaque, int version_id)
 {
     PL031State *s = opaque;
 
-    int64_t delta = qemu_clock_get_ns(rtc_clock) - qemu_get_clock_ns(vm_clock);
+    int64_t delta = qemu_clock_get_ns(rtc_clock) - qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL);
     s->tick_offset = s->tick_offset_vmstate - delta / get_ticks_per_sec();
     pl031_set_alarm(s);
     return 0;
diff --git a/hw/timer/pxa2xx_timer.c b/hw/timer/pxa2xx_timer.c
index cdabccd..0f546c4 100644
--- a/hw/timer/pxa2xx_timer.c
+++ b/hw/timer/pxa2xx_timer.c
@@ -123,7 +123,7 @@ static void pxa2xx_timer_update(void *opaque, uint64_t now_qemu)
     for (i = 0; i < 4; i ++) {
         new_qemu = now_qemu + muldiv64((uint32_t) (s->timer[i].value - now_vm),
                         get_ticks_per_sec(), s->freq);
-        qemu_mod_timer(s->timer[i].qtimer, new_qemu);
+        timer_mod(s->timer[i].qtimer, new_qemu);
     }
 }
 
@@ -141,7 +141,7 @@ static void pxa2xx_timer_update4(void *opaque, uint64_t now_qemu, int n)
         counter = counters[n];
 
     if (!s->tm4[counter].freq) {
-        qemu_del_timer(s->tm4[n].tm.qtimer);
+        timer_del(s->tm4[n].tm.qtimer);
         return;
     }
 
@@ -151,7 +151,7 @@ static void pxa2xx_timer_update4(void *opaque, uint64_t now_qemu, int n)
 
     new_qemu = now_qemu + muldiv64((uint32_t) (s->tm4[n].tm.value - now_vm),
                     get_ticks_per_sec(), s->tm4[counter].freq);
-    qemu_mod_timer(s->tm4[n].tm.qtimer, new_qemu);
+    timer_mod(s->tm4[n].tm.qtimer, new_qemu);
 }
 
 static uint64_t pxa2xx_timer_read(void *opaque, hwaddr offset,
@@ -188,7 +188,7 @@ static uint64_t pxa2xx_timer_read(void *opaque, hwaddr offset,
             goto badreg;
         return s->tm4[tm].tm.value;
     case OSCR:
-        return s->clock + muldiv64(qemu_get_clock_ns(vm_clock) -
+        return s->clock + muldiv64(qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL) -
                         s->lastload, s->freq, get_ticks_per_sec());
     case OSCR11: tm ++;
         /* fall through */
@@ -211,7 +211,7 @@ static uint64_t pxa2xx_timer_read(void *opaque, hwaddr offset,
         if ((tm == 9 - 4 || tm == 11 - 4) && (s->tm4[tm].control & (1 << 9))) {
             if (s->tm4[tm - 1].freq)
                 s->snapshot = s->tm4[tm - 1].clock + muldiv64(
-                                qemu_get_clock_ns(vm_clock) -
+                                qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL) -
                                 s->tm4[tm - 1].lastload,
                                 s->tm4[tm - 1].freq, get_ticks_per_sec());
             else
@@ -220,7 +220,7 @@ static uint64_t pxa2xx_timer_read(void *opaque, hwaddr offset,
 
         if (!s->tm4[tm].freq)
             return s->tm4[tm].clock;
-        return s->tm4[tm].clock + muldiv64(qemu_get_clock_ns(vm_clock) -
+        return s->tm4[tm].clock + muldiv64(qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL) -
                         s->tm4[tm].lastload, s->tm4[tm].freq, get_ticks_per_sec());
     case OIER:
         return s->irq_enabled;
@@ -271,7 +271,7 @@ static void pxa2xx_timer_write(void *opaque, hwaddr offset,
         /* fall through */
     case OSMR0:
         s->timer[tm].value = value;
-        pxa2xx_timer_update(s, qemu_get_clock_ns(vm_clock));
+        pxa2xx_timer_update(s, qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL));
         break;
     case OSMR11: tm ++;
         /* fall through */
@@ -291,11 +291,11 @@ static void pxa2xx_timer_write(void *opaque, hwaddr offset,
         if (!pxa2xx_timer_has_tm4(s))
             goto badreg;
         s->tm4[tm].tm.value = value;
-        pxa2xx_timer_update4(s, qemu_get_clock_ns(vm_clock), tm);
+        pxa2xx_timer_update4(s, qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL), tm);
         break;
     case OSCR:
         s->oldclock = s->clock;
-        s->lastload = qemu_get_clock_ns(vm_clock);
+        s->lastload = qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL);
         s->clock = value;
         pxa2xx_timer_update(s, s->lastload);
         break;
@@ -317,7 +317,7 @@ static void pxa2xx_timer_write(void *opaque, hwaddr offset,
         if (!pxa2xx_timer_has_tm4(s))
             goto badreg;
         s->tm4[tm].oldclock = s->tm4[tm].clock;
-        s->tm4[tm].lastload = qemu_get_clock_ns(vm_clock);
+        s->tm4[tm].lastload = qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL);
         s->tm4[tm].clock = value;
         pxa2xx_timer_update4(s, s->tm4[tm].lastload, tm);
         break;
@@ -351,7 +351,7 @@ static void pxa2xx_timer_write(void *opaque, hwaddr offset,
             s->tm4[tm].freq = pxa2xx_timer4_freq[value & 7];
         else {
             s->tm4[tm].freq = 0;
-            pxa2xx_timer_update4(s, qemu_get_clock_ns(vm_clock), tm);
+            pxa2xx_timer_update4(s, qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL), tm);
         }
         break;
     case OMCR11: tm ++;
@@ -370,7 +370,7 @@ static void pxa2xx_timer_write(void *opaque, hwaddr offset,
                     pxa2xx_timer4_freq[(value & (1 << 8)) ?  0 : (value & 7)];
         else {
             s->tm4[tm].freq = 0;
-            pxa2xx_timer_update4(s, qemu_get_clock_ns(vm_clock), tm);
+            pxa2xx_timer_update4(s, qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL), tm);
         }
         break;
     default:
@@ -411,7 +411,7 @@ static void pxa2xx_timer_tick4(void *opaque)
     if (t->control & (1 << 3))
         t->clock = 0;
     if (t->control & (1 << 6))
-        pxa2xx_timer_update4(i, qemu_get_clock_ns(vm_clock), t->tm.num - 4);
+        pxa2xx_timer_update4(i, qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL), t->tm.num - 4);
     if (i->events & 0xff0)
         qemu_irq_raise(i->irq4);
 }
@@ -422,7 +422,7 @@ static int pxa25x_timer_post_load(void *opaque, int version_id)
     int64_t now;
     int i;
 
-    now = qemu_get_clock_ns(vm_clock);
+    now = qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL);
     pxa2xx_timer_update(s, now);
 
     if (pxa2xx_timer_has_tm4(s))
@@ -440,7 +440,7 @@ static int pxa2xx_timer_init(SysBusDevice *dev)
     s->irq_enabled = 0;
     s->oldclock = 0;
     s->clock = 0;
-    s->lastload = qemu_get_clock_ns(vm_clock);
+    s->lastload = qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL);
     s->reset3 = 0;
 
     for (i = 0; i < 4; i ++) {
@@ -448,7 +448,7 @@ static int pxa2xx_timer_init(SysBusDevice *dev)
         sysbus_init_irq(dev, &s->timer[i].irq);
         s->timer[i].info = s;
         s->timer[i].num = i;
-        s->timer[i].qtimer = qemu_new_timer_ns(vm_clock,
+        s->timer[i].qtimer = timer_new_ns(QEMU_CLOCK_VIRTUAL,
                         pxa2xx_timer_tick, &s->timer[i]);
     }
     if (s->flags & (1 << PXA2XX_TIMER_HAVE_TM4)) {
@@ -460,7 +460,7 @@ static int pxa2xx_timer_init(SysBusDevice *dev)
             s->tm4[i].tm.num = i + 4;
             s->tm4[i].freq = 0;
             s->tm4[i].control = 0x0;
-            s->tm4[i].tm.qtimer = qemu_new_timer_ns(vm_clock,
+            s->tm4[i].tm.qtimer = timer_new_ns(QEMU_CLOCK_VIRTUAL,
                         pxa2xx_timer_tick4, &s->tm4[i]);
         }
     }
diff --git a/hw/timer/tusb6010.c b/hw/timer/tusb6010.c
index c48ecf8..bd2a89e 100644
--- a/hw/timer/tusb6010.c
+++ b/hw/timer/tusb6010.c
@@ -516,11 +516,11 @@ static void tusb_async_writew(void *opaque, hwaddr addr,
     case TUSB_DEV_OTG_TIMER:
         s->otg_timer_val = value;
         if (value & TUSB_DEV_OTG_TIMER_ENABLE)
-            qemu_mod_timer(s->otg_timer, qemu_get_clock_ns(vm_clock) +
+            timer_mod(s->otg_timer, qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL) +
                             muldiv64(TUSB_DEV_OTG_TIMER_VAL(value),
                                      get_ticks_per_sec(), TUSB_DEVCLOCK));
         else
-            qemu_del_timer(s->otg_timer);
+            timer_del(s->otg_timer);
         break;
 
     case TUSB_PRCM_CONF:
@@ -728,8 +728,8 @@ static void tusb6010_power(TUSBState *s, int on)
         /* Pull the interrupt down after TUSB6010 comes up.  */
         s->intr_ok = 0;
         tusb_intr_update(s);
-        qemu_mod_timer(s->pwr_timer,
-                       qemu_get_clock_ns(vm_clock) + get_ticks_per_sec() / 2);
+        timer_mod(s->pwr_timer,
+                       qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL) + get_ticks_per_sec() / 2);
     }
 }
 
@@ -783,8 +783,8 @@ static int tusb6010_init(SysBusDevice *sbd)
     DeviceState *dev = DEVICE(sbd);
     TUSBState *s = TUSB(dev);
 
-    s->otg_timer = qemu_new_timer_ns(vm_clock, tusb_otg_tick, s);
-    s->pwr_timer = qemu_new_timer_ns(vm_clock, tusb_power_tick, s);
+    s->otg_timer = timer_new_ns(QEMU_CLOCK_VIRTUAL, tusb_otg_tick, s);
+    s->pwr_timer = timer_new_ns(QEMU_CLOCK_VIRTUAL, tusb_power_tick, s);
     memory_region_init_io(&s->iomem[1], OBJECT(s), &tusb_async_ops, s,
                           "tusb-async", UINT32_MAX);
     sysbus_init_mmio(sbd, &s->iomem[0]);
diff --git a/hw/timer/twl92230.c b/hw/timer/twl92230.c
index 431677e..f3ea365 100644
--- a/hw/timer/twl92230.c
+++ b/hw/timer/twl92230.c
@@ -73,12 +73,12 @@ static inline void menelaus_update(MenelausState *s)
 static inline void menelaus_rtc_start(MenelausState *s)
 {
     s->rtc.next += qemu_clock_get_ms(rtc_clock);
-    qemu_mod_timer(s->rtc.hz_tm, s->rtc.next);
+    timer_mod(s->rtc.hz_tm, s->rtc.next);
 }
 
 static inline void menelaus_rtc_stop(MenelausState *s)
 {
-    qemu_del_timer(s->rtc.hz_tm);
+    timer_del(s->rtc.hz_tm);
     s->rtc.next -= qemu_clock_get_ms(rtc_clock);
     if (s->rtc.next < 1)
         s->rtc.next = 1;
@@ -102,7 +102,7 @@ static void menelaus_rtc_hz(void *opaque)
     s->rtc.next_comp --;
     s->rtc.alm_sec --;
     s->rtc.next += 1000;
-    qemu_mod_timer(s->rtc.hz_tm, s->rtc.next);
+    timer_mod(s->rtc.hz_tm, s->rtc.next);
     if ((s->rtc.ctrl >> 3) & 3) {				/* EVERY */
         menelaus_rtc_update(s);
         if (((s->rtc.ctrl >> 3) & 3) == 1 && !s->rtc.tm.tm_sec)
diff --git a/hw/usb/hcd-ehci.c b/hw/usb/hcd-ehci.c
index 010a0d0..e5523d5 100644
--- a/hw/usb/hcd-ehci.c
+++ b/hw/usb/hcd-ehci.c
@@ -150,7 +150,7 @@ typedef enum {
 #define NLPTR_TYPE_FSTN          3     // frame span traversal node
 
 #define SET_LAST_RUN_CLOCK(s) \
-    (s)->last_run_ns = qemu_get_clock_ns(vm_clock);
+    (s)->last_run_ns = qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL);
 
 /* nifty macros from Arnon's EHCI version  */
 #define get_field(data, field) \
@@ -958,7 +958,7 @@ static void ehci_reset(void *opaque)
     }
     ehci_queues_rip_all(s, 0);
     ehci_queues_rip_all(s, 1);
-    qemu_del_timer(s->frame_timer);
+    timer_del(s->frame_timer);
     qemu_bh_cancel(s->async_bh);
 }
 
@@ -2296,7 +2296,7 @@ static void ehci_frame_timer(void *opaque)
     int uframes, skipped_uframes;
     int i;
 
-    t_now = qemu_get_clock_ns(vm_clock);
+    t_now = qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL);
     ns_elapsed = t_now - ehci->last_run_ns;
     uframes = ns_elapsed / UFRAME_TIMER_NS;
 
@@ -2374,7 +2374,7 @@ static void ehci_frame_timer(void *opaque)
             expire_time = t_now + (get_ticks_per_sec()
                                * (ehci->async_stepdown+1) / FRAME_TIMER_FREQ);
         }
-        qemu_mod_timer(ehci->frame_timer, expire_time);
+        timer_mod(ehci->frame_timer, expire_time);
     }
 }
 
@@ -2527,7 +2527,7 @@ void usb_ehci_realize(EHCIState *s, DeviceState *dev, Error **errp)
         s->ports[i].dev = 0;
     }
 
-    s->frame_timer = qemu_new_timer_ns(vm_clock, ehci_frame_timer, s);
+    s->frame_timer = timer_new_ns(QEMU_CLOCK_VIRTUAL, ehci_frame_timer, s);
     s->async_bh = qemu_bh_new(ehci_frame_timer, s);
 
     qemu_register_reset(ehci_reset, s);
diff --git a/hw/usb/hcd-musb.c b/hw/usb/hcd-musb.c
index 7968e17..f91aa55 100644
--- a/hw/usb/hcd-musb.c
+++ b/hw/usb/hcd-musb.c
@@ -558,9 +558,9 @@ static void musb_schedule_cb(USBPort *port, USBPacket *packey)
         return musb_cb_tick(ep);
 
     if (!ep->intv_timer[dir])
-        ep->intv_timer[dir] = qemu_new_timer_ns(vm_clock, musb_cb_tick, ep);
+        ep->intv_timer[dir] = timer_new_ns(QEMU_CLOCK_VIRTUAL, musb_cb_tick, ep);
 
-    qemu_mod_timer(ep->intv_timer[dir], qemu_get_clock_ns(vm_clock) +
+    timer_mod(ep->intv_timer[dir], qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL) +
                    muldiv64(timeout, get_ticks_per_sec(), 8000));
 }
 
@@ -962,7 +962,7 @@ static void musb_write_fifo(MUSBEndPoint *ep, uint8_t value)
 static void musb_ep_frame_cancel(MUSBEndPoint *ep, int dir)
 {
     if (ep->intv_timer[dir])
-        qemu_del_timer(ep->intv_timer[dir]);
+        timer_del(ep->intv_timer[dir]);
 }
 
 /* Bus control */
diff --git a/hw/usb/hcd-ohci.c b/hw/usb/hcd-ohci.c
index d7836d6..39a25a7 100644
--- a/hw/usb/hcd-ohci.c
+++ b/hw/usb/hcd-ohci.c
@@ -1251,8 +1251,8 @@ static int ohci_service_ed_list(OHCIState *ohci, uint32_t head, int completion)
 /* Generate a SOF event, and set a timer for EOF */
 static void ohci_sof(OHCIState *ohci)
 {
-    ohci->sof_time = qemu_get_clock_ns(vm_clock);
-    qemu_mod_timer(ohci->eof_timer, ohci->sof_time + usb_frame_time);
+    ohci->sof_time = qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL);
+    timer_mod(ohci->eof_timer, ohci->sof_time + usb_frame_time);
     ohci_set_interrupt(ohci, OHCI_INTR_SF);
 }
 
@@ -1349,12 +1349,12 @@ static void ohci_frame_boundary(void *opaque)
  */
 static int ohci_bus_start(OHCIState *ohci)
 {
-    ohci->eof_timer = qemu_new_timer_ns(vm_clock,
+    ohci->eof_timer = timer_new_ns(QEMU_CLOCK_VIRTUAL,
                     ohci_frame_boundary,
                     ohci);
 
     if (ohci->eof_timer == NULL) {
-        fprintf(stderr, "usb-ohci: %s: qemu_new_timer_ns failed\n", ohci->name);
+        fprintf(stderr, "usb-ohci: %s: timer_new_ns failed\n", ohci->name);
         ohci_die(ohci);
         return 0;
     }
@@ -1370,7 +1370,7 @@ static int ohci_bus_start(OHCIState *ohci)
 static void ohci_bus_stop(OHCIState *ohci)
 {
     if (ohci->eof_timer)
-        qemu_del_timer(ohci->eof_timer);
+        timer_del(ohci->eof_timer);
     ohci->eof_timer = NULL;
 }
 
@@ -1474,7 +1474,7 @@ static uint32_t ohci_get_frame_remaining(OHCIState *ohci)
     /* Being in USB operational state guarnatees sof_time was
      * set already.
      */
-    tks = qemu_get_clock_ns(vm_clock) - ohci->sof_time;
+    tks = qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL) - ohci->sof_time;
 
     /* avoid muldiv if possible */
     if (tks >= usb_frame_time)
diff --git a/hw/usb/hcd-uhci.c b/hw/usb/hcd-uhci.c
index ec51883..578b949 100644
--- a/hw/usb/hcd-uhci.c
+++ b/hw/usb/hcd-uhci.c
@@ -433,7 +433,7 @@ static int uhci_post_load(void *opaque, int version_id)
     UHCIState *s = opaque;
 
     if (version_id < 2) {
-        s->expire_time = qemu_get_clock_ns(vm_clock) +
+        s->expire_time = qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL) +
             (get_ticks_per_sec() / FRAME_TIMER_FREQ);
     }
     return 0;
@@ -476,9 +476,9 @@ static void uhci_port_write(void *opaque, hwaddr addr,
         if ((val & UHCI_CMD_RS) && !(s->cmd & UHCI_CMD_RS)) {
             /* start frame processing */
             trace_usb_uhci_schedule_start();
-            s->expire_time = qemu_get_clock_ns(vm_clock) +
+            s->expire_time = qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL) +
                 (get_ticks_per_sec() / FRAME_TIMER_FREQ);
-            qemu_mod_timer(s->frame_timer, s->expire_time);
+            timer_mod(s->frame_timer, s->expire_time);
             s->status &= ~UHCI_STS_HCHALTED;
         } else if (!(val & UHCI_CMD_RS)) {
             s->status |= UHCI_STS_HCHALTED;
@@ -1161,7 +1161,7 @@ static void uhci_frame_timer(void *opaque)
     if (!(s->cmd & UHCI_CMD_RS)) {
         /* Full stop */
         trace_usb_uhci_schedule_stop();
-        qemu_del_timer(s->frame_timer);
+        timer_del(s->frame_timer);
         uhci_async_cancel_all(s);
         /* set hchalted bit in status - UHCI11D 2.1.2 */
         s->status |= UHCI_STS_HCHALTED;
@@ -1170,7 +1170,7 @@ static void uhci_frame_timer(void *opaque)
 
     /* We still store expire_time in our state, for migration */
     t_last_run = s->expire_time - frame_t;
-    t_now = qemu_get_clock_ns(vm_clock);
+    t_now = qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL);
 
     /* Process up to MAX_FRAMES_PER_TICK frames */
     frames = (t_now - t_last_run) / frame_t;
@@ -1204,7 +1204,7 @@ static void uhci_frame_timer(void *opaque)
     }
     s->pending_int_mask = 0;
 
-    qemu_mod_timer(s->frame_timer, t_now + frame_t);
+    timer_mod(s->frame_timer, t_now + frame_t);
 }
 
 static const MemoryRegionOps uhci_ioport_ops = {
@@ -1261,7 +1261,7 @@ static int usb_uhci_common_initfn(PCIDevice *dev)
         }
     }
     s->bh = qemu_bh_new(uhci_bh, s);
-    s->frame_timer = qemu_new_timer_ns(vm_clock, uhci_frame_timer, s);
+    s->frame_timer = timer_new_ns(QEMU_CLOCK_VIRTUAL, uhci_frame_timer, s);
     s->num_ports_vmstate = NB_PORTS;
     QTAILQ_INIT(&s->queues);
 
diff --git a/hw/usb/hcd-xhci.c b/hw/usb/hcd-xhci.c
index 58c88b8..be6b86e 100644
--- a/hw/usb/hcd-xhci.c
+++ b/hw/usb/hcd-xhci.c
@@ -608,7 +608,7 @@ static const char *event_name(XHCIEvent *event)
 
 static uint64_t xhci_mfindex_get(XHCIState *xhci)
 {
-    int64_t now = qemu_get_clock_ns(vm_clock);
+    int64_t now = qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL);
     return (now - xhci->mfindex_start) / 125000;
 }
 
@@ -619,12 +619,12 @@ static void xhci_mfwrap_update(XHCIState *xhci)
     int64_t now;
 
     if ((xhci->usbcmd & bits) == bits) {
-        now = qemu_get_clock_ns(vm_clock);
+        now = qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL);
         mfindex = ((now - xhci->mfindex_start) / 125000) & 0x3fff;
         left = 0x4000 - mfindex;
-        qemu_mod_timer(xhci->mfwrap_timer, now + left * 125000);
+        timer_mod(xhci->mfwrap_timer, now + left * 125000);
     } else {
-        qemu_del_timer(xhci->mfwrap_timer);
+        timer_del(xhci->mfwrap_timer);
     }
 }
 
@@ -1086,7 +1086,7 @@ static void xhci_run(XHCIState *xhci)
 {
     trace_usb_xhci_run();
     xhci->usbsts &= ~USBSTS_HCH;
-    xhci->mfindex_start = qemu_get_clock_ns(vm_clock);
+    xhci->mfindex_start = qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL);
 }
 
 static void xhci_stop(XHCIState *xhci)
@@ -1229,7 +1229,7 @@ static XHCIEPContext *xhci_alloc_epctx(XHCIState *xhci,
     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);
+    epctx->kick_timer = timer_new_ns(QEMU_CLOCK_VIRTUAL, xhci_ep_kick_timer, epctx);
 
     return epctx;
 }
@@ -1304,7 +1304,7 @@ static int xhci_ep_nuke_one_xfer(XHCITransfer *t)
         XHCIEPContext *epctx = t->xhci->slots[t->slotid-1].eps[t->epid-1];
         if (epctx) {
             epctx->retry = NULL;
-            qemu_del_timer(epctx->kick_timer);
+            timer_del(epctx->kick_timer);
         }
         t->running_retry = 0;
     }
@@ -1380,7 +1380,7 @@ static TRBCCode xhci_disable_ep(XHCIState *xhci, unsigned int slotid,
 
     xhci_set_ep_state(xhci, epctx, NULL, EP_DISABLED);
 
-    qemu_free_timer(epctx->kick_timer);
+    timer_free(epctx->kick_timer);
     g_free(epctx);
     slot->eps[epid-1] = NULL;
 
@@ -1844,12 +1844,12 @@ static void xhci_check_iso_kick(XHCIState *xhci, XHCITransfer *xfer,
                                 XHCIEPContext *epctx, uint64_t mfindex)
 {
     if (xfer->mfindex_kick > mfindex) {
-        qemu_mod_timer(epctx->kick_timer, qemu_get_clock_ns(vm_clock) +
+        timer_mod(epctx->kick_timer, qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL) +
                        (xfer->mfindex_kick - mfindex) * 125000);
         xfer->running_retry = 1;
     } else {
         epctx->mfindex_last = xfer->mfindex_kick;
-        qemu_del_timer(epctx->kick_timer);
+        timer_del(epctx->kick_timer);
         xfer->running_retry = 0;
     }
 }
@@ -2745,7 +2745,7 @@ static void xhci_reset(DeviceState *dev)
         xhci->intr[i].ev_buffer_get = 0;
     }
 
-    xhci->mfindex_start = qemu_get_clock_ns(vm_clock);
+    xhci->mfindex_start = qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL);
     xhci_mfwrap_update(xhci);
 }
 
@@ -3366,7 +3366,7 @@ static int usb_xhci_initfn(struct PCIDevice *dev)
         xhci->numslots = 1;
     }
 
-    xhci->mfwrap_timer = qemu_new_timer_ns(vm_clock, xhci_mfwrap_timer, xhci);
+    xhci->mfwrap_timer = timer_new_ns(QEMU_CLOCK_VIRTUAL, xhci_mfwrap_timer, xhci);
 
     xhci->irq = dev->irq[0];
 
@@ -3451,7 +3451,7 @@ static int usb_xhci_post_load(void *opaque, int version_id)
             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));
+                timer_mod(epctx->kick_timer, qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL));
             }
         }
     }
diff --git a/hw/usb/host-libusb.c b/hw/usb/host-libusb.c
index f660770..128955d 100644
--- a/hw/usb/host-libusb.c
+++ b/hw/usb/host-libusb.c
@@ -1462,7 +1462,7 @@ static void usb_host_auto_check(void *unused)
         if (unconnected == 0) {
             /* nothing to watch */
             if (usb_auto_timer) {
-                qemu_del_timer(usb_auto_timer);
+                timer_del(usb_auto_timer);
                 trace_usb_host_auto_scan_disabled();
             }
             return;
@@ -1474,13 +1474,13 @@ static void usb_host_auto_check(void *unused)
         usb_vmstate = qemu_add_vm_change_state_handler(usb_host_vm_state, NULL);
     }
     if (!usb_auto_timer) {
-        usb_auto_timer = qemu_new_timer_ms(rt_clock, usb_host_auto_check, NULL);
+        usb_auto_timer = timer_new_ms(QEMU_CLOCK_REALTIME, usb_host_auto_check, NULL);
         if (!usb_auto_timer) {
             return;
         }
         trace_usb_host_auto_scan_enabled();
     }
-    qemu_mod_timer(usb_auto_timer, qemu_get_clock_ms(rt_clock) + 2000);
+    timer_mod(usb_auto_timer, qemu_clock_get_ms(QEMU_CLOCK_REALTIME) + 2000);
 }
 
 void usb_host_info(Monitor *mon, const QDict *qdict)
diff --git a/hw/usb/host-linux.c b/hw/usb/host-linux.c
index 7901f4c..65cd3b4 100644
--- a/hw/usb/host-linux.c
+++ b/hw/usb/host-linux.c
@@ -1754,7 +1754,7 @@ static void usb_host_auto_check(void *unused)
         if (unconnected == 0) {
             /* nothing to watch */
             if (usb_auto_timer) {
-                qemu_del_timer(usb_auto_timer);
+                timer_del(usb_auto_timer);
                 trace_usb_host_auto_scan_disabled();
             }
             return;
@@ -1765,13 +1765,13 @@ static void usb_host_auto_check(void *unused)
         usb_vmstate = qemu_add_vm_change_state_handler(usb_host_vm_state, NULL);
     }
     if (!usb_auto_timer) {
-        usb_auto_timer = qemu_new_timer_ms(rt_clock, usb_host_auto_check, NULL);
+        usb_auto_timer = timer_new_ms(QEMU_CLOCK_REALTIME, usb_host_auto_check, NULL);
         if (!usb_auto_timer) {
             return;
         }
         trace_usb_host_auto_scan_enabled();
     }
-    qemu_mod_timer(usb_auto_timer, qemu_get_clock_ms(rt_clock) + 2000);
+    timer_mod(usb_auto_timer, qemu_clock_get_ms(QEMU_CLOCK_REALTIME) + 2000);
 }
 
 #ifndef CONFIG_USB_LIBUSB
diff --git a/hw/usb/redirect.c b/hw/usb/redirect.c
index 8fee3d3..287a505 100644
--- a/hw/usb/redirect.c
+++ b/hw/usb/redirect.c
@@ -1297,7 +1297,7 @@ static int usbredir_initfn(USBDevice *udev)
     }
 
     dev->chardev_close_bh = qemu_bh_new(usbredir_chardev_close_bh, dev);
-    dev->attach_timer = qemu_new_timer_ms(vm_clock, usbredir_do_attach, dev);
+    dev->attach_timer = timer_new_ms(QEMU_CLOCK_VIRTUAL, usbredir_do_attach, dev);
 
     packet_id_queue_init(&dev->cancelled, dev, "cancelled");
     packet_id_queue_init(&dev->already_in_flight, dev, "already-in-flight");
@@ -1338,8 +1338,8 @@ static void usbredir_handle_destroy(USBDevice *udev)
     /* Note must be done after qemu_chr_close, as that causes a close event */
     qemu_bh_delete(dev->chardev_close_bh);
 
-    qemu_del_timer(dev->attach_timer);
-    qemu_free_timer(dev->attach_timer);
+    timer_del(dev->attach_timer);
+    timer_free(dev->attach_timer);
 
     usbredir_cleanup_device_queues(dev);
 
@@ -1548,7 +1548,7 @@ static void usbredir_device_connect(void *priv,
     }
 
     usbredir_check_bulk_receiving(dev);
-    qemu_mod_timer(dev->attach_timer, dev->next_attach_time);
+    timer_mod(dev->attach_timer, dev->next_attach_time);
 }
 
 static void usbredir_device_disconnect(void *priv)
@@ -1556,7 +1556,7 @@ static void usbredir_device_disconnect(void *priv)
     USBRedirDevice *dev = priv;
 
     /* Stop any pending attaches */
-    qemu_del_timer(dev->attach_timer);
+    timer_del(dev->attach_timer);
 
     if (dev->dev.attached) {
         DPRINTF("detaching device\n");
@@ -1565,7 +1565,7 @@ static void usbredir_device_disconnect(void *priv)
          * Delay next usb device attach to give the guest a chance to see
          * see the detach / attach in case of quick close / open succession
          */
-        dev->next_attach_time = qemu_get_clock_ms(vm_clock) + 200;
+        dev->next_attach_time = qemu_clock_get_ms(QEMU_CLOCK_VIRTUAL) + 200;
     }
 
     /* Reset state so that the next dev connected starts with a clean slate */
diff --git a/hw/virtio/virtio-balloon.c b/hw/virtio/virtio-balloon.c
index aac7f83..9504877 100644
--- a/hw/virtio/virtio-balloon.c
+++ b/hw/virtio/virtio-balloon.c
@@ -78,8 +78,8 @@ static bool balloon_stats_enabled(const VirtIOBalloon *s)
 static void balloon_stats_destroy_timer(VirtIOBalloon *s)
 {
     if (balloon_stats_enabled(s)) {
-        qemu_del_timer(s->stats_timer);
-        qemu_free_timer(s->stats_timer);
+        timer_del(s->stats_timer);
+        timer_free(s->stats_timer);
         s->stats_timer = NULL;
         s->stats_poll_interval = 0;
     }
@@ -87,7 +87,7 @@ static void balloon_stats_destroy_timer(VirtIOBalloon *s)
 
 static void balloon_stats_change_timer(VirtIOBalloon *s, int secs)
 {
-    qemu_mod_timer(s->stats_timer, qemu_get_clock_ms(vm_clock) + secs * 1000);
+    timer_mod(s->stats_timer, qemu_clock_get_ms(QEMU_CLOCK_VIRTUAL) + secs * 1000);
 }
 
 static void balloon_stats_poll_cb(void *opaque)
@@ -173,7 +173,7 @@ static void balloon_stats_set_poll_interval(Object *obj, struct Visitor *v,
 
     /* create a new timer */
     g_assert(s->stats_timer == NULL);
-    s->stats_timer = qemu_new_timer_ms(vm_clock, balloon_stats_poll_cb, s);
+    s->stats_timer = timer_new_ms(QEMU_CLOCK_VIRTUAL, balloon_stats_poll_cb, s);
     s->stats_poll_interval = value;
     balloon_stats_change_timer(s, 0);
 }
diff --git a/hw/virtio/virtio-rng.c b/hw/virtio/virtio-rng.c
index bac8421..314e393 100644
--- a/hw/virtio/virtio-rng.c
+++ b/hw/virtio/virtio-rng.c
@@ -129,8 +129,8 @@ static void check_rate_limit(void *opaque)
 
     vrng->quota_remaining = vrng->conf.max_bytes;
     virtio_rng_process(vrng);
-    qemu_mod_timer(vrng->rate_limit_timer,
-                   qemu_get_clock_ms(vm_clock) + vrng->conf.period_ms);
+    timer_mod(vrng->rate_limit_timer,
+                   qemu_clock_get_ms(QEMU_CLOCK_VIRTUAL) + vrng->conf.period_ms);
 }
 
 static int virtio_rng_device_init(VirtIODevice *vdev)
@@ -172,11 +172,11 @@ static int virtio_rng_device_init(VirtIODevice *vdev)
     assert(vrng->conf.max_bytes <= INT64_MAX);
     vrng->quota_remaining = vrng->conf.max_bytes;
 
-    vrng->rate_limit_timer = qemu_new_timer_ms(vm_clock,
+    vrng->rate_limit_timer = timer_new_ms(QEMU_CLOCK_VIRTUAL,
                                                check_rate_limit, vrng);
 
-    qemu_mod_timer(vrng->rate_limit_timer,
-                   qemu_get_clock_ms(vm_clock) + vrng->conf.period_ms);
+    timer_mod(vrng->rate_limit_timer,
+                   qemu_clock_get_ms(QEMU_CLOCK_VIRTUAL) + vrng->conf.period_ms);
 
     register_savevm(qdev, "virtio-rng", -1, 1, virtio_rng_save,
                     virtio_rng_load, vrng);
@@ -189,8 +189,8 @@ static int virtio_rng_device_exit(DeviceState *qdev)
     VirtIORNG *vrng = VIRTIO_RNG(qdev);
     VirtIODevice *vdev = VIRTIO_DEVICE(qdev);
 
-    qemu_del_timer(vrng->rate_limit_timer);
-    qemu_free_timer(vrng->rate_limit_timer);
+    timer_del(vrng->rate_limit_timer);
+    timer_free(vrng->rate_limit_timer);
     unregister_savevm(qdev, "virtio-rng", vrng);
     virtio_cleanup(vdev);
     return 0;
diff --git a/hw/watchdog/wdt_i6300esb.c b/hw/watchdog/wdt_i6300esb.c
index 2e064ba..36d3887 100644
--- a/hw/watchdog/wdt_i6300esb.c
+++ b/hw/watchdog/wdt_i6300esb.c
@@ -130,7 +130,7 @@ static void i6300esb_restart_timer(I6300State *d, int stage)
 
     i6300esb_debug("stage %d, timeout %" PRIi64 "\n", d->stage, timeout);
 
-    qemu_mod_timer(d->timer, qemu_get_clock_ns(vm_clock) + timeout);
+    timer_mod(d->timer, qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL) + timeout);
 }
 
 /* This is called when the guest disables the watchdog. */
@@ -138,7 +138,7 @@ static void i6300esb_disable_timer(I6300State *d)
 {
     i6300esb_debug("timer disabled\n");
 
-    qemu_del_timer(d->timer);
+    timer_del(d->timer);
 }
 
 static void i6300esb_reset(DeviceState *dev)
@@ -414,7 +414,7 @@ static int i6300esb_init(PCIDevice *dev)
 
     i6300esb_debug("I6300State = %p\n", d);
 
-    d->timer = qemu_new_timer_ns(vm_clock, i6300esb_timer_expired, d);
+    d->timer = timer_new_ns(QEMU_CLOCK_VIRTUAL, i6300esb_timer_expired, d);
     d->previous_reboot_flag = 0;
 
     memory_region_init_io(&d->io_mem, OBJECT(d), &i6300esb_ops, d,
diff --git a/hw/watchdog/wdt_ib700.c b/hw/watchdog/wdt_ib700.c
index e97b4c3..bc994a4 100644
--- a/hw/watchdog/wdt_ib700.c
+++ b/hw/watchdog/wdt_ib700.c
@@ -62,7 +62,7 @@ static void ib700_write_enable_reg(void *vp, uint32_t addr, uint32_t data)
     ib700_debug("addr = %x, data = %x\n", addr, data);
 
     timeout = (int64_t) time_map[data & 0xF] * get_ticks_per_sec();
-    qemu_mod_timer(s->timer, qemu_get_clock_ns (vm_clock) + timeout);
+    timer_mod(s->timer, qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL) + timeout);
 }
 
 /* A write (of any value) to this register disables the timer. */
@@ -72,7 +72,7 @@ static void ib700_write_disable_reg(void *vp, uint32_t addr, uint32_t data)
 
     ib700_debug("addr = %x, data = %x\n", addr, data);
 
-    qemu_del_timer(s->timer);
+    timer_del(s->timer);
 }
 
 /* This is called when the watchdog expires. */
@@ -83,7 +83,7 @@ static void ib700_timer_expired(void *vp)
     ib700_debug("watchdog expired\n");
 
     watchdog_perform_action();
-    qemu_del_timer(s->timer);
+    timer_del(s->timer);
 }
 
 static const VMStateDescription vmstate_ib700 = {
@@ -110,7 +110,7 @@ static void wdt_ib700_realize(DeviceState *dev, Error **errp)
 
     ib700_debug("watchdog init\n");
 
-    s->timer = qemu_new_timer_ns(vm_clock, ib700_timer_expired, s);
+    s->timer = timer_new_ns(QEMU_CLOCK_VIRTUAL, ib700_timer_expired, s);
 
     portio_list_init(port_list, OBJECT(s), wdt_portio_list, s, "ib700");
     portio_list_add(port_list, isa_address_space_io(&s->parent_obj), 0);
@@ -122,7 +122,7 @@ static void wdt_ib700_reset(DeviceState *dev)
 
     ib700_debug("watchdog reset\n");
 
-    qemu_del_timer(s->timer);
+    timer_del(s->timer);
 }
 
 static WatchdogTimerModel model = {
diff --git a/hw/xtensa/pic_cpu.c b/hw/xtensa/pic_cpu.c
index 7f015ff..e2005bd 100644
--- a/hw/xtensa/pic_cpu.c
+++ b/hw/xtensa/pic_cpu.c
@@ -52,11 +52,11 @@ void check_interrupts(CPUXtensaState *env)
     uint32_t int_set_enabled = env->sregs[INTSET] & env->sregs[INTENABLE];
     int level;
 
-    /* If the CPU is halted advance CCOUNT according to the vm_clock time
+    /* If the CPU is halted advance CCOUNT according to the QEMU_CLOCK_VIRTUAL time
      * elapsed since the moment when it was advanced last time.
      */
     if (cs->halted) {
-        int64_t now = qemu_get_clock_ns(vm_clock);
+        int64_t now = qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL);
 
         xtensa_advance_ccount(env,
                 muldiv64(now - env->halt_clock,
@@ -119,7 +119,7 @@ void xtensa_rearm_ccompare_timer(CPUXtensaState *env)
         }
     }
     env->wake_ccount = wake_ccount;
-    qemu_mod_timer(env->ccompare_timer, env->halt_clock +
+    timer_mod(env->ccompare_timer, env->halt_clock +
             muldiv64(wake_ccount - env->sregs[CCOUNT],
                 1000000, env->config->clock_freq_khz));
 }
@@ -131,7 +131,7 @@ static void xtensa_ccompare_cb(void *opaque)
     CPUState *cs = CPU(cpu);
 
     if (cs->halted) {
-        env->halt_clock = qemu_get_clock_ns(vm_clock);
+        env->halt_clock = qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL);
         xtensa_advance_ccount(env, env->wake_ccount - env->sregs[CCOUNT]);
         if (!cpu_has_work(cs)) {
             env->sregs[CCOUNT] = env->wake_ccount + 1;
@@ -149,7 +149,7 @@ void xtensa_irq_init(CPUXtensaState *env)
     if (xtensa_option_enabled(env->config, XTENSA_OPTION_TIMER_INTERRUPT) &&
             env->config->nccompare > 0) {
         env->ccompare_timer =
-            qemu_new_timer_ns(vm_clock, &xtensa_ccompare_cb, cpu);
+            timer_new_ns(QEMU_CLOCK_VIRTUAL, &xtensa_ccompare_cb, cpu);
     }
 }
 
diff --git a/include/hw/acpi/acpi.h b/include/hw/acpi/acpi.h
index 635be7b..51733d3 100644
--- a/include/hw/acpi/acpi.h
+++ b/include/hw/acpi/acpi.h
@@ -136,7 +136,7 @@ void acpi_pm_tmr_reset(ACPIREGS *ar);
 #include "qemu/timer.h"
 static inline int64_t acpi_pm_tmr_get_clock(void)
 {
-    return muldiv64(qemu_get_clock_ns(vm_clock), PM_TIMER_FREQUENCY,
+    return muldiv64(qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL), PM_TIMER_FREQUENCY,
                     get_ticks_per_sec());
 }
 
diff --git a/include/qemu/ratelimit.h b/include/qemu/ratelimit.h
index d1610f1..d413a4a 100644
--- a/include/qemu/ratelimit.h
+++ b/include/qemu/ratelimit.h
@@ -23,7 +23,7 @@ typedef struct {
 
 static inline int64_t ratelimit_calculate_delay(RateLimit *limit, uint64_t n)
 {
-    int64_t now = qemu_get_clock_ns(rt_clock);
+    int64_t now = qemu_clock_get_ns(QEMU_CLOCK_REALTIME);
 
     if (limit->next_slice_time < now) {
         limit->next_slice_time = now + limit->slice_ns;
diff --git a/migration.c b/migration.c
index ac200ed..200d404 100644
--- a/migration.c
+++ b/migration.c
@@ -198,7 +198,7 @@ MigrationInfo *qmp_query_migrate(Error **errp)
         info->has_status = true;
         info->status = g_strdup("active");
         info->has_total_time = true;
-        info->total_time = qemu_get_clock_ms(rt_clock)
+        info->total_time = qemu_clock_get_ms(QEMU_CLOCK_REALTIME)
             - s->total_time;
         info->has_expected_downtime = true;
         info->expected_downtime = s->expected_downtime;
@@ -376,7 +376,7 @@ static MigrationState *migrate_init(const MigrationParams *params)
     s->state = MIG_STATE_SETUP;
     trace_migrate_set_state(MIG_STATE_SETUP);
 
-    s->total_time = qemu_get_clock_ms(rt_clock);
+    s->total_time = qemu_clock_get_ms(QEMU_CLOCK_REALTIME);
     return s;
 }
 
@@ -545,8 +545,8 @@ int64_t migrate_xbzrle_cache_size(void)
 static void *migration_thread(void *opaque)
 {
     MigrationState *s = opaque;
-    int64_t initial_time = qemu_get_clock_ms(rt_clock);
-    int64_t setup_start = qemu_get_clock_ms(host_clock);
+    int64_t initial_time = qemu_clock_get_ms(QEMU_CLOCK_REALTIME);
+    int64_t setup_start = qemu_clock_get_ms(QEMU_CLOCK_HOST);
     int64_t initial_bytes = 0;
     int64_t max_size = 0;
     int64_t start_time = initial_time;
@@ -555,7 +555,7 @@ static void *migration_thread(void *opaque)
     DPRINTF("beginning savevm\n");
     qemu_savevm_state_begin(s->file, &s->params);
 
-    s->setup_time = qemu_get_clock_ms(host_clock) - setup_start;
+    s->setup_time = qemu_clock_get_ms(QEMU_CLOCK_HOST) - setup_start;
     migrate_set_state(s, MIG_STATE_SETUP, MIG_STATE_ACTIVE);
 
     DPRINTF("setup complete\n");
@@ -575,7 +575,7 @@ static void *migration_thread(void *opaque)
 
                 DPRINTF("done iterating\n");
                 qemu_mutex_lock_iothread();
-                start_time = qemu_get_clock_ms(rt_clock);
+                start_time = qemu_clock_get_ms(QEMU_CLOCK_REALTIME);
                 qemu_system_wakeup_request(QEMU_WAKEUP_REASON_OTHER);
                 old_vm_running = runstate_is_running();
 
@@ -602,7 +602,7 @@ static void *migration_thread(void *opaque)
             migrate_set_state(s, MIG_STATE_ACTIVE, MIG_STATE_ERROR);
             break;
         }
-        current_time = qemu_get_clock_ms(rt_clock);
+        current_time = qemu_clock_get_ms(QEMU_CLOCK_REALTIME);
         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;
@@ -633,7 +633,7 @@ static void *migration_thread(void *opaque)
 
     qemu_mutex_lock_iothread();
     if (s->state == MIG_STATE_COMPLETED) {
-        int64_t end_time = qemu_get_clock_ms(rt_clock);
+        int64_t end_time = qemu_clock_get_ms(QEMU_CLOCK_REALTIME);
         s->total_time = end_time - s->total_time;
         s->downtime = end_time - start_time;
         runstate_set(RUN_STATE_POSTMIGRATE);
diff --git a/monitor.c b/monitor.c
index 5dc0aa9..b6659df 100644
--- a/monitor.c
+++ b/monitor.c
@@ -537,7 +537,7 @@ monitor_protocol_event_queue(MonitorEvent event,
                              QObject *data)
 {
     MonitorEventState *evstate;
-    int64_t now = qemu_get_clock_ns(rt_clock);
+    int64_t now = qemu_clock_get_ns(QEMU_CLOCK_REALTIME);
     assert(event < QEVENT_MAX);
 
     qemu_mutex_lock(&monitor_event_state_lock);
@@ -564,7 +564,7 @@ monitor_protocol_event_queue(MonitorEvent event,
                 qobject_decref(evstate->data);
             } else {
                 int64_t then = evstate->last + evstate->rate;
-                qemu_mod_timer_ns(evstate->timer, then);
+                timer_mod_ns(evstate->timer, then);
             }
             evstate->data = data;
             qobject_incref(evstate->data);
@@ -584,7 +584,7 @@ monitor_protocol_event_queue(MonitorEvent event,
 static void monitor_protocol_event_handler(void *opaque)
 {
     MonitorEventState *evstate = opaque;
-    int64_t now = qemu_get_clock_ns(rt_clock);
+    int64_t now = qemu_clock_get_ns(QEMU_CLOCK_REALTIME);
 
     qemu_mutex_lock(&monitor_event_state_lock);
 
@@ -622,7 +622,7 @@ monitor_protocol_event_throttle(MonitorEvent event,
     trace_monitor_protocol_event_throttle(event, rate);
     evstate->event = event;
     evstate->rate = rate * SCALE_MS;
-    evstate->timer = qemu_new_timer(rt_clock,
+    evstate->timer = timer_new(QEMU_CLOCK_REALTIME,
                                     SCALE_MS,
                                     monitor_protocol_event_handler,
                                     evstate);
diff --git a/net/dump.c b/net/dump.c
index 4119721..9d3a09e 100644
--- a/net/dump.c
+++ b/net/dump.c
@@ -69,7 +69,7 @@ static ssize_t dump_receive(NetClientState *nc, const uint8_t *buf, size_t size)
         return size;
     }
 
-    ts = muldiv64(qemu_get_clock_ns(vm_clock), 1000000, get_ticks_per_sec());
+    ts = muldiv64(qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL), 1000000, get_ticks_per_sec());
     caplen = size > s->pcap_caplen ? s->pcap_caplen : size;
 
     hdr.ts.tv_sec = ts / 1000000 + s->start_ts;
diff --git a/qemu-char.c b/qemu-char.c
index 1be1cf6..d7abf9a 100644
--- a/qemu-char.c
+++ b/qemu-char.c
@@ -281,7 +281,7 @@ static int mux_chr_write(CharDriverState *chr, const uint8_t *buf, int len)
                 int64_t ti;
                 int secs;
 
-                ti = qemu_get_clock_ms(rt_clock);
+                ti = qemu_clock_get_ms(QEMU_CLOCK_REALTIME);
                 if (d->timestamps_start == -1)
                     d->timestamps_start = ti;
                 ti -= d->timestamps_start;
diff --git a/qtest.c b/qtest.c
index 9c50ab0..ef671fb 100644
--- a/qtest.c
+++ b/qtest.c
@@ -47,7 +47,7 @@ static bool qtest_opened;
  *
  * Clock management:
  *
- * The qtest client is completely in charge of the vm_clock.  qtest commands
+ * The qtest client is completely in charge of the QEMU_CLOCK_VIRTUAL.  qtest commands
  * let you adjust the value of the clock (monotonically).  All the commands
  * return the current value of the clock in nanoseconds.
  *
@@ -414,9 +414,9 @@ static void qtest_process_command(CharDriverState *chr, gchar **words)
         } else {
             ns = qemu_clock_deadline_ns_all(QEMU_CLOCK_VIRTUAL);
         }
-        qtest_clock_warp(qemu_get_clock_ns(vm_clock) + ns);
+        qtest_clock_warp(qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL) + ns);
         qtest_send_prefix(chr);
-        qtest_send(chr, "OK %"PRIi64"\n", (int64_t)qemu_get_clock_ns(vm_clock));
+        qtest_send(chr, "OK %"PRIi64"\n", (int64_t)qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL));
     } else if (strcmp(words[0], "clock_set") == 0) {
         int64_t ns;
 
@@ -424,7 +424,7 @@ static void qtest_process_command(CharDriverState *chr, gchar **words)
         ns = strtoll(words[1], NULL, 0);
         qtest_clock_warp(ns);
         qtest_send_prefix(chr);
-        qtest_send(chr, "OK %"PRIi64"\n", (int64_t)qemu_get_clock_ns(vm_clock));
+        qtest_send(chr, "OK %"PRIi64"\n", (int64_t)qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL));
     } else {
         qtest_send_prefix(chr);
         qtest_send(chr, "FAIL Unknown command `%s'\n", words[0]);
diff --git a/savevm.c b/savevm.c
index cad6ba6..c536aa4 100644
--- a/savevm.c
+++ b/savevm.c
@@ -97,18 +97,18 @@ static void qemu_announce_self_once(void *opaque)
 
     if (--count) {
         /* delay 50ms, 150ms, 250ms, ... */
-        qemu_mod_timer(timer, qemu_get_clock_ms(rt_clock) +
+        timer_mod(timer, qemu_clock_get_ms(QEMU_CLOCK_REALTIME) +
                        50 + (SELF_ANNOUNCE_ROUNDS - count - 1) * 100);
     } else {
-	    qemu_del_timer(timer);
-	    qemu_free_timer(timer);
+	    timer_del(timer);
+	    timer_free(timer);
     }
 }
 
 void qemu_announce_self(void)
 {
 	static QEMUTimer *timer;
-	timer = qemu_new_timer_ms(rt_clock, qemu_announce_self_once, &timer);
+	timer = timer_new_ms(QEMU_CLOCK_REALTIME, qemu_announce_self_once, &timer);
 	qemu_announce_self_once(&timer);
 }
 
@@ -993,9 +993,9 @@ void timer_get(QEMUFile *f, QEMUTimer *ts)
 
     expire_time = qemu_get_be64(f);
     if (expire_time != -1) {
-        qemu_mod_timer_ns(ts, expire_time);
+        timer_mod_ns(ts, expire_time);
     } else {
-        qemu_del_timer(ts);
+        timer_del(ts);
     }
 }
 
@@ -2387,7 +2387,7 @@ void do_savevm(Monitor *mon, const QDict *qdict)
     qemu_gettimeofday(&tv);
     sn->date_sec = tv.tv_sec;
     sn->date_nsec = tv.tv_usec * 1000;
-    sn->vm_clock_nsec = qemu_get_clock_ns(vm_clock);
+    sn->vm_clock_nsec = qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL);
 
     if (name) {
         ret = bdrv_snapshot_find(bs, old_sn, name);
diff --git a/slirp/if.c b/slirp/if.c
index dcd5faf..87ca8a5 100644
--- a/slirp/if.c
+++ b/slirp/if.c
@@ -154,7 +154,7 @@ diddit:
  */
 void if_start(Slirp *slirp)
 {
-    uint64_t now = qemu_get_clock_ns(rt_clock);
+    uint64_t now = qemu_clock_get_ns(QEMU_CLOCK_REALTIME);
     bool from_batchq, next_from_batchq;
     struct mbuf *ifm, *ifm_next, *ifqt;
 
diff --git a/slirp/slirp.c b/slirp/slirp.c
index 80b28ea..5c3dabb 100644
--- a/slirp/slirp.c
+++ b/slirp/slirp.c
@@ -448,7 +448,7 @@ void slirp_pollfds_poll(GArray *pollfds, int select_error)
         return;
     }
 
-    curtime = qemu_get_clock_ms(rt_clock);
+    curtime = qemu_clock_get_ms(QEMU_CLOCK_REALTIME);
 
     QTAILQ_FOREACH(slirp, &slirp_instances, entry) {
         /*
@@ -787,7 +787,7 @@ int if_encap(Slirp *slirp, struct mbuf *ifm)
             ifm->arp_requested = true;
 
             /* Expire request and drop outgoing packet after 1 second */
-            ifm->expiration_date = qemu_get_clock_ns(rt_clock) + 1000000000ULL;
+            ifm->expiration_date = qemu_clock_get_ns(QEMU_CLOCK_REALTIME) + 1000000000ULL;
         }
         return 0;
     } else {
diff --git a/target-alpha/sys_helper.c b/target-alpha/sys_helper.c
index 552100c..035810c 100644
--- a/target-alpha/sys_helper.c
+++ b/target-alpha/sys_helper.c
@@ -30,9 +30,9 @@ uint64_t helper_load_pcc(CPUAlphaState *env)
        In order to make OS-level time accounting work with the RPCC,
        present it with a well-timed clock fixed at 250MHz.  */
     return (((uint64_t)env->pcc_ofs << 32)
-            | (uint32_t)(qemu_get_clock_ns(vm_clock) >> 2));
+            | (uint32_t)(qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL) >> 2));
 #else
-    /* In user-mode, vm_clock doesn't exist.  Just pass through the host cpu
+    /* In user-mode, QEMU_CLOCK_VIRTUAL doesn't exist.  Just pass through the host cpu
        clock ticks.  Also, don't bother taking PCC_OFS into account.  */
     return (uint32_t)cpu_get_real_ticks();
 #endif
@@ -88,7 +88,7 @@ void helper_halt(uint64_t restart)
 
 uint64_t helper_get_vmtime(void)
 {
-    return qemu_get_clock_ns(vm_clock);
+    return qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL);
 }
 
 uint64_t helper_get_walltime(void)
@@ -102,9 +102,9 @@ void helper_set_alarm(CPUAlphaState *env, uint64_t expire)
 
     if (expire) {
         env->alarm_expire = expire;
-        qemu_mod_timer(cpu->alarm_timer, expire);
+        timer_mod(cpu->alarm_timer, expire);
     } else {
-        qemu_del_timer(cpu->alarm_timer);
+        timer_del(cpu->alarm_timer);
     }
 }
 
diff --git a/target-arm/cpu.c b/target-arm/cpu.c
index f01ce03..b2556c6 100644
--- a/target-arm/cpu.c
+++ b/target-arm/cpu.c
@@ -204,9 +204,9 @@ static void arm_cpu_initfn(Object *obj)
         qdev_init_gpio_in(DEVICE(cpu), arm_cpu_set_irq, 2);
     }
 
-    cpu->gt_timer[GTIMER_PHYS] = qemu_new_timer(vm_clock, GTIMER_SCALE,
+    cpu->gt_timer[GTIMER_PHYS] = timer_new(QEMU_CLOCK_VIRTUAL, GTIMER_SCALE,
                                                 arm_gt_ptimer_cb, cpu);
-    cpu->gt_timer[GTIMER_VIRT] = qemu_new_timer(vm_clock, GTIMER_SCALE,
+    cpu->gt_timer[GTIMER_VIRT] = timer_new(QEMU_CLOCK_VIRTUAL, GTIMER_SCALE,
                                                 arm_gt_vtimer_cb, cpu);
     qdev_init_gpio_out(DEVICE(cpu), cpu->gt_timer_outputs,
                        ARRAY_SIZE(cpu->gt_timer_outputs));
diff --git a/target-arm/helper.c b/target-arm/helper.c
index f4e1b06..e51ef20 100644
--- a/target-arm/helper.c
+++ b/target-arm/helper.c
@@ -699,7 +699,7 @@ static const ARMCPRegInfo v6k_cp_reginfo[] = {
 
 static uint64_t gt_get_countervalue(CPUARMState *env)
 {
-    return qemu_get_clock_ns(vm_clock) / GTIMER_SCALE;
+    return qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL) / GTIMER_SCALE;
 }
 
 static void gt_recalc_timer(ARMCPU *cpu, int timeridx)
@@ -733,12 +733,12 @@ static void gt_recalc_timer(ARMCPU *cpu, int timeridx)
         if (nexttick > INT64_MAX / GTIMER_SCALE) {
             nexttick = INT64_MAX / GTIMER_SCALE;
         }
-        qemu_mod_timer(cpu->gt_timer[timeridx], nexttick);
+        timer_mod(cpu->gt_timer[timeridx], nexttick);
     } else {
         /* Timer disabled: ISTATUS and timer output always clear */
         gt->ctl &= ~4;
         qemu_set_irq(cpu->gt_timer_outputs[timeridx], 0);
-        qemu_del_timer(cpu->gt_timer[timeridx]);
+        timer_del(cpu->gt_timer[timeridx]);
     }
 }
 
@@ -758,7 +758,7 @@ static void gt_cnt_reset(CPUARMState *env, const ARMCPRegInfo *ri)
     ARMCPU *cpu = arm_env_get_cpu(env);
     int timeridx = ri->opc1 & 1;
 
-    qemu_del_timer(cpu->gt_timer[timeridx]);
+    timer_del(cpu->gt_timer[timeridx]);
 }
 
 static int gt_cnt_read(CPUARMState *env, const ARMCPRegInfo *ri,
@@ -941,7 +941,7 @@ static const ARMCPRegInfo generic_timer_cp_reginfo[] = {
 
 #else
 /* In user-mode none of the generic timer registers are accessible,
- * and their implementation depends on vm_clock and qdev gpio outputs,
+ * and their implementation depends on QEMU_CLOCK_VIRTUAL and qdev gpio outputs,
  * so instead just don't register any of them.
  */
 static const ARMCPRegInfo generic_timer_cp_reginfo[] = {
diff --git a/target-ppc/kvm.c b/target-ppc/kvm.c
index 30a870e..8a196c6 100644
--- a/target-ppc/kvm.c
+++ b/target-ppc/kvm.c
@@ -419,7 +419,7 @@ int kvm_arch_init_vcpu(CPUState *cs)
         return ret;
     }
 
-    idle_timer = qemu_new_timer_ns(vm_clock, kvm_kick_cpu, cpu);
+    idle_timer = timer_new_ns(QEMU_CLOCK_VIRTUAL, kvm_kick_cpu, cpu);
 
     /* Some targets support access to KVM's guest TLB. */
     switch (cenv->mmu_model) {
@@ -1136,7 +1136,7 @@ void kvm_arch_pre_run(CPUState *cs, struct kvm_run *run)
         }
 
         /* Always wake up soon in case the interrupt was level based */
-        qemu_mod_timer(idle_timer, qemu_get_clock_ns(vm_clock) +
+        timer_mod(idle_timer, qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL) +
                        (get_ticks_per_sec() / 50));
     }
 
@@ -1807,7 +1807,7 @@ int kvmppc_get_htab_fd(bool write)
 
 int kvmppc_save_htab(QEMUFile *f, int fd, size_t bufsize, int64_t max_ns)
 {
-    int64_t starttime = qemu_get_clock_ns(rt_clock);
+    int64_t starttime = qemu_clock_get_ns(QEMU_CLOCK_REALTIME);
     uint8_t buf[bufsize];
     ssize_t rc;
 
@@ -1823,7 +1823,7 @@ int kvmppc_save_htab(QEMUFile *f, int fd, size_t bufsize, int64_t max_ns)
         }
     } while ((rc != 0)
              && ((max_ns < 0)
-                 || ((qemu_get_clock_ns(rt_clock) - starttime) < max_ns)));
+                 || ((qemu_clock_get_ns(QEMU_CLOCK_REALTIME) - starttime) < max_ns)));
 
     return (rc == 0) ? 1 : 0;
 }
diff --git a/target-ppc/kvm_ppc.c b/target-ppc/kvm_ppc.c
index 1b192a8..9b83655 100644
--- a/target-ppc/kvm_ppc.c
+++ b/target-ppc/kvm_ppc.c
@@ -24,7 +24,7 @@ static unsigned int kvmppc_timer_rate;
 static void kvmppc_timer_hack(void *opaque)
 {
     qemu_notify_event();
-    qemu_mod_timer(kvmppc_timer, qemu_get_clock_ns(vm_clock) + kvmppc_timer_rate);
+    timer_mod(kvmppc_timer, qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL) + kvmppc_timer_rate);
 }
 
 void kvmppc_init(void)
@@ -34,7 +34,7 @@ void kvmppc_init(void)
      * run. So, until QEMU gains IO threads, we create this timer to ensure
      * that the device model gets a chance to run. */
     kvmppc_timer_rate = get_ticks_per_sec() / 10;
-    kvmppc_timer = qemu_new_timer_ns(vm_clock, &kvmppc_timer_hack, NULL);
-    qemu_mod_timer(kvmppc_timer, qemu_get_clock_ns(vm_clock) + kvmppc_timer_rate);
+    kvmppc_timer = timer_new_ns(QEMU_CLOCK_VIRTUAL, &kvmppc_timer_hack, NULL);
+    timer_mod(kvmppc_timer, qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL) + kvmppc_timer_rate);
 }
 
diff --git a/target-s390x/cpu.c b/target-s390x/cpu.c
index 6be6c08..5cc9938 100644
--- a/target-s390x/cpu.c
+++ b/target-s390x/cpu.c
@@ -129,8 +129,8 @@ static void s390_cpu_initfn(Object *obj)
     env->tod_offset = TOD_UNIX_EPOCH +
                       (time2tod(mktimegm(&tm)) * 1000000000ULL);
     env->tod_basetime = 0;
-    env->tod_timer = qemu_new_timer_ns(vm_clock, s390x_tod_timer, cpu);
-    env->cpu_timer = qemu_new_timer_ns(vm_clock, s390x_cpu_timer, cpu);
+    env->tod_timer = timer_new_ns(QEMU_CLOCK_VIRTUAL, s390x_tod_timer, cpu);
+    env->cpu_timer = timer_new_ns(QEMU_CLOCK_VIRTUAL, s390x_cpu_timer, cpu);
     /* set CPUState::halted state to 1 to avoid decrementing the running
      * cpu counter in s390_cpu_reset to a negative number at
      * initial ipl */
diff --git a/target-s390x/misc_helper.c b/target-s390x/misc_helper.c
index 09301d0..454960a 100644
--- a/target-s390x/misc_helper.c
+++ b/target-s390x/misc_helper.c
@@ -225,7 +225,7 @@ static inline uint64_t clock_value(CPUS390XState *env)
     uint64_t time;
 
     time = env->tod_offset +
-        time2tod(qemu_get_clock_ns(vm_clock) - env->tod_basetime);
+        time2tod(qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL) - env->tod_basetime);
 
     return time;
 }
@@ -248,7 +248,7 @@ void HELPER(sckc)(CPUS390XState *env, uint64_t time)
     /* nanoseconds */
     time = (time * 125) >> 9;
 
-    qemu_mod_timer(env->tod_timer, qemu_get_clock_ns(vm_clock) + time);
+    timer_mod(env->tod_timer, qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL) + time);
 }
 
 /* Store Clock Comparator */
@@ -268,7 +268,7 @@ void HELPER(spt)(CPUS390XState *env, uint64_t time)
     /* nanoseconds */
     time = (time * 125) >> 9;
 
-    qemu_mod_timer(env->cpu_timer, qemu_get_clock_ns(vm_clock) + time);
+    timer_mod(env->cpu_timer, qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL) + time);
 }
 
 /* Store CPU Timer */
diff --git a/target-xtensa/op_helper.c b/target-xtensa/op_helper.c
index 6ca912c..01123af 100644
--- a/target-xtensa/op_helper.c
+++ b/target-xtensa/op_helper.c
@@ -390,7 +390,7 @@ void HELPER(waiti)(CPUXtensaState *env, uint32_t pc, uint32_t intlevel)
     }
 
     cpu = CPU(xtensa_env_get_cpu(env));
-    env->halt_clock = qemu_get_clock_ns(vm_clock);
+    env->halt_clock = qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL);
     cpu->halted = 1;
     if (xtensa_option_enabled(env->config, XTENSA_OPTION_TIMER_INTERRUPT)) {
         xtensa_rearm_ccompare_timer(env);
diff --git a/tests/libqtest.h b/tests/libqtest.h
index 0f6aade..a6e99bd 100644
--- a/tests/libqtest.h
+++ b/tests/libqtest.h
@@ -258,9 +258,9 @@ void qtest_memwrite(QTestState *s, uint64_t addr, const void *data, size_t size)
  * qtest_clock_step_next:
  * @s: #QTestState instance to operate on.
  *
- * Advance the vm_clock to the next deadline.
+ * Advance the QEMU_CLOCK_VIRTUAL to the next deadline.
  *
- * Returns: The current value of the vm_clock in nanoseconds.
+ * Returns: The current value of the QEMU_CLOCK_VIRTUAL in nanoseconds.
  */
 int64_t qtest_clock_step_next(QTestState *s);
 
@@ -269,9 +269,9 @@ int64_t qtest_clock_step_next(QTestState *s);
  * @s: QTestState instance to operate on.
  * @step: Number of nanoseconds to advance the clock by.
  *
- * Advance the vm_clock by @step nanoseconds.
+ * Advance the QEMU_CLOCK_VIRTUAL by @step nanoseconds.
  *
- * Returns: The current value of the vm_clock in nanoseconds.
+ * Returns: The current value of the QEMU_CLOCK_VIRTUAL in nanoseconds.
  */
 int64_t qtest_clock_step(QTestState *s, int64_t step);
 
@@ -280,9 +280,9 @@ int64_t qtest_clock_step(QTestState *s, int64_t step);
  * @s: QTestState instance to operate on.
  * @val: Nanoseconds value to advance the clock to.
  *
- * Advance the vm_clock to @val nanoseconds since the VM was launched.
+ * Advance the QEMU_CLOCK_VIRTUAL to @val nanoseconds since the VM was launched.
  *
- * Returns: The current value of the vm_clock in nanoseconds.
+ * Returns: The current value of the QEMU_CLOCK_VIRTUAL in nanoseconds.
  */
 int64_t qtest_clock_set(QTestState *s, int64_t val);
 
@@ -584,9 +584,9 @@ static inline void memwrite(uint64_t addr, const void *data, size_t size)
 /**
  * clock_step_next:
  *
- * Advance the vm_clock to the next deadline.
+ * Advance the QEMU_CLOCK_VIRTUAL to the next deadline.
  *
- * Returns: The current value of the vm_clock in nanoseconds.
+ * Returns: The current value of the QEMU_CLOCK_VIRTUAL in nanoseconds.
  */
 static inline int64_t clock_step_next(void)
 {
@@ -597,9 +597,9 @@ static inline int64_t clock_step_next(void)
  * clock_step:
  * @step: Number of nanoseconds to advance the clock by.
  *
- * Advance the vm_clock by @step nanoseconds.
+ * Advance the QEMU_CLOCK_VIRTUAL by @step nanoseconds.
  *
- * Returns: The current value of the vm_clock in nanoseconds.
+ * Returns: The current value of the QEMU_CLOCK_VIRTUAL in nanoseconds.
  */
 static inline int64_t clock_step(int64_t step)
 {
@@ -610,9 +610,9 @@ static inline int64_t clock_step(int64_t step)
  * clock_set:
  * @val: Nanoseconds value to advance the clock to.
  *
- * Advance the vm_clock to @val nanoseconds since the VM was launched.
+ * Advance the QEMU_CLOCK_VIRTUAL to @val nanoseconds since the VM was launched.
  *
- * Returns: The current value of the vm_clock in nanoseconds.
+ * Returns: The current value of the QEMU_CLOCK_VIRTUAL in nanoseconds.
  */
 static inline int64_t clock_set(int64_t val)
 {
diff --git a/ui/console.c b/ui/console.c
index e3e8297..aad4fc9 100644
--- a/ui/console.c
+++ b/ui/console.c
@@ -208,8 +208,8 @@ static void gui_update(void *opaque)
         }
         trace_console_refresh(interval);
     }
-    ds->last_update = qemu_get_clock_ms(rt_clock);
-    qemu_mod_timer(ds->gui_timer, ds->last_update + interval);
+    ds->last_update = qemu_clock_get_ms(QEMU_CLOCK_REALTIME);
+    timer_mod(ds->gui_timer, ds->last_update + interval);
 }
 
 static void gui_setup_refresh(DisplayState *ds)
@@ -232,12 +232,12 @@ static void gui_setup_refresh(DisplayState *ds)
     }
 
     if (need_timer && ds->gui_timer == NULL) {
-        ds->gui_timer = qemu_new_timer_ms(rt_clock, gui_update, ds);
-        qemu_mod_timer(ds->gui_timer, qemu_get_clock_ms(rt_clock));
+        ds->gui_timer = timer_new_ms(QEMU_CLOCK_REALTIME, gui_update, ds);
+        timer_mod(ds->gui_timer, qemu_clock_get_ms(QEMU_CLOCK_REALTIME));
     }
     if (!need_timer && ds->gui_timer != NULL) {
-        qemu_del_timer(ds->gui_timer);
-        qemu_free_timer(ds->gui_timer);
+        timer_del(ds->gui_timer);
+        timer_free(ds->gui_timer);
         ds->gui_timer = NULL;
     }
 
@@ -1040,7 +1040,7 @@ void console_select(unsigned int index)
         DisplayState *ds = s->ds;
 
         if (active_console && active_console->cursor_timer) {
-            qemu_del_timer(active_console->cursor_timer);
+            timer_del(active_console->cursor_timer);
         }
         active_console = s;
         if (ds->have_gfx) {
@@ -1059,8 +1059,8 @@ void console_select(unsigned int index)
             dpy_text_resize(s, s->width, s->height);
         }
         if (s->cursor_timer) {
-            qemu_mod_timer(s->cursor_timer,
-                   qemu_get_clock_ms(rt_clock) + CONSOLE_CURSOR_PERIOD / 2);
+            timer_mod(s->cursor_timer,
+                   qemu_clock_get_ms(QEMU_CLOCK_REALTIME) + CONSOLE_CURSOR_PERIOD / 2);
         }
     }
 }
@@ -1105,7 +1105,7 @@ static void kbd_send_chars(void *opaque)
     /* characters are pending: we send them a bit later (XXX:
        horrible, should change char device API) */
     if (s->out_fifo.count > 0) {
-        qemu_mod_timer(s->kbd_timer, qemu_get_clock_ms(rt_clock) + 1);
+        timer_mod(s->kbd_timer, qemu_clock_get_ms(QEMU_CLOCK_REALTIME) + 1);
     }
 }
 
@@ -1366,7 +1366,7 @@ void update_displaychangelistener(DisplayChangeListener *dcl,
 
     dcl->update_interval = interval;
     if (!ds->refreshing && ds->update_interval > interval) {
-        qemu_mod_timer(ds->gui_timer, ds->last_update + interval);
+        timer_mod(ds->gui_timer, ds->last_update + interval);
     }
 }
 
@@ -1691,8 +1691,8 @@ static void text_console_update_cursor(void *opaque)
 
     s->cursor_visible_phase = !s->cursor_visible_phase;
     graphic_hw_invalidate(s);
-    qemu_mod_timer(s->cursor_timer,
-                   qemu_get_clock_ms(rt_clock) + CONSOLE_CURSOR_PERIOD / 2);
+    timer_mod(s->cursor_timer,
+                   qemu_clock_get_ms(QEMU_CLOCK_REALTIME) + CONSOLE_CURSOR_PERIOD / 2);
 }
 
 static const GraphicHwOps text_console_ops = {
@@ -1712,7 +1712,7 @@ static void text_console_do_init(CharDriverState *chr, DisplayState *ds)
 
     s->out_fifo.buf = s->out_fifo_buf;
     s->out_fifo.buf_size = sizeof(s->out_fifo_buf);
-    s->kbd_timer = qemu_new_timer_ms(rt_clock, kbd_send_chars, s);
+    s->kbd_timer = timer_new_ms(QEMU_CLOCK_REALTIME, kbd_send_chars, s);
     s->ds = ds;
 
     s->y_displayed = 0;
@@ -1729,7 +1729,7 @@ static void text_console_do_init(CharDriverState *chr, DisplayState *ds)
     }
 
     s->cursor_timer =
-        qemu_new_timer_ms(rt_clock, text_console_update_cursor, s);
+        timer_new_ms(QEMU_CLOCK_REALTIME, text_console_update_cursor, s);
 
     s->hw_ops = &text_console_ops;
     s->hw = s;
diff --git a/ui/input.c b/ui/input.c
index 92c44ca..10d8c05 100644
--- a/ui/input.c
+++ b/ui/input.c
@@ -277,11 +277,11 @@ void qmp_send_key(KeyValueList *keys, bool has_hold_time, int64_t hold_time,
     KeyValueList *p;
 
     if (!key_timer) {
-        key_timer = qemu_new_timer_ns(vm_clock, release_keys, NULL);
+        key_timer = timer_new_ns(QEMU_CLOCK_VIRTUAL, release_keys, NULL);
     }
 
     if (keycodes != NULL) {
-        qemu_del_timer(key_timer);
+        timer_del(key_timer);
         release_keys(NULL);
     }
 
@@ -308,7 +308,7 @@ void qmp_send_key(KeyValueList *keys, bool has_hold_time, int64_t hold_time,
     }
 
     /* delayed key up events */
-    qemu_mod_timer(key_timer, qemu_get_clock_ns(vm_clock) +
+    timer_mod(key_timer, qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL) +
                    muldiv64(get_ticks_per_sec(), hold_time, 1000));
 }
 
diff --git a/ui/spice-core.c b/ui/spice-core.c
index bd7a248..3a2cd7e 100644
--- a/ui/spice-core.c
+++ b/ui/spice-core.c
@@ -63,25 +63,25 @@ static SpiceTimer *timer_add(SpiceTimerFunc func, void *opaque)
     SpiceTimer *timer;
 
     timer = g_malloc0(sizeof(*timer));
-    timer->timer = qemu_new_timer_ms(rt_clock, func, opaque);
+    timer->timer = timer_new_ms(QEMU_CLOCK_REALTIME, func, opaque);
     QTAILQ_INSERT_TAIL(&timers, timer, next);
     return timer;
 }
 
 static void timer_start(SpiceTimer *timer, uint32_t ms)
 {
-    qemu_mod_timer(timer->timer, qemu_get_clock_ms(rt_clock) + ms);
+    timer_mod(timer->timer, qemu_clock_get_ms(QEMU_CLOCK_REALTIME) + ms);
 }
 
 static void timer_cancel(SpiceTimer *timer)
 {
-    qemu_del_timer(timer->timer);
+    timer_del(timer->timer);
 }
 
 static void timer_remove(SpiceTimer *timer)
 {
-    qemu_del_timer(timer->timer);
-    qemu_free_timer(timer->timer);
+    timer_del(timer->timer);
+    timer_free(timer->timer);
     QTAILQ_REMOVE(&timers, timer, next);
     g_free(timer);
 }
diff --git a/xen-all.c b/xen-all.c
index 21246e0..eb13111 100644
--- a/xen-all.c
+++ b/xen-all.c
@@ -606,8 +606,8 @@ static ioreq_t *cpu_get_ioreq(XenIOState *state)
 
     port = xc_evtchn_pending(state->xce_handle);
     if (port == state->bufioreq_local_port) {
-        qemu_mod_timer(state->buffered_io_timer,
-                BUFFER_IO_MAX_DELAY + qemu_get_clock_ms(rt_clock));
+        timer_mod(state->buffered_io_timer,
+                BUFFER_IO_MAX_DELAY + qemu_clock_get_ms(QEMU_CLOCK_REALTIME));
         return NULL;
     }
 
@@ -828,10 +828,10 @@ static void handle_buffered_io(void *opaque)
     XenIOState *state = opaque;
 
     if (handle_buffered_iopage(state)) {
-        qemu_mod_timer(state->buffered_io_timer,
-                BUFFER_IO_MAX_DELAY + qemu_get_clock_ms(rt_clock));
+        timer_mod(state->buffered_io_timer,
+                BUFFER_IO_MAX_DELAY + qemu_clock_get_ms(QEMU_CLOCK_REALTIME));
     } else {
-        qemu_del_timer(state->buffered_io_timer);
+        timer_del(state->buffered_io_timer);
         xc_evtchn_unmask(state->xce_handle, state->bufioreq_local_port);
     }
 }
@@ -962,7 +962,7 @@ static void xen_main_loop_prepare(XenIOState *state)
         evtchn_fd = xc_evtchn_fd(state->xce_handle);
     }
 
-    state->buffered_io_timer = qemu_new_timer_ms(rt_clock, handle_buffered_io,
+    state->buffered_io_timer = timer_new_ms(QEMU_CLOCK_REALTIME, handle_buffered_io,
                                                  state);
 
     if (evtchn_fd != -1) {
commit fe10ab540bcc2c5e4ac15ae686008c4a17a95c69
Author: Alex Bligh <alex at alex.org.uk>
Date:   Wed Aug 21 16:03:07 2013 +0100

    aio / timers: Add scripts/switch-timer-api
    
    Add scripts/switch-timer-api to programatically rewrite source
    files to use the new timer system.
    
    Signed-off-by: Alex Bligh <alex at alex.org.uk>
    Signed-off-by: Stefan Hajnoczi <stefanha at redhat.com>

diff --git a/scripts/switch-timer-api b/scripts/switch-timer-api
new file mode 100755
index 0000000..a369a08
--- /dev/null
+++ b/scripts/switch-timer-api
@@ -0,0 +1,178 @@
+#!/usr/bin/perl
+
+use strict;
+use warnings;
+use Getopt::Long;
+use FindBin;
+
+my @legacy = qw(qemu_clock_ptr qemu_get_clock_ns qemu_get_clock_ms qemu_register_clock_reset_notifier qemu_unregister_clock_reset_notifier qemu_new_timer qemu_free_timer qemu_del_timer qemu_mod_timer_ns qemu_mod_timer qemu_run_timers qemu_new_timer_ns qemu_new_timer_us qemu_new_timer_ms);
+my $legacyre = '\b('.join('|', @legacy).')\b';
+my $option_git;
+my $option_dryrun;
+my $option_quiet;
+my $option_rtc;
+my $suffix=".tmp.$$";
+my @files;
+my $getfiles = 'git grep -l -E \'\b((host|rt|vm|rtc)_clock\b|qemu_\w*timer)\' | egrep \'\.[ch]$\' | egrep -v \'qemu-timer\.c$|include/qemu/timer\.h$\'';
+
+sub Syntax
+{
+    print STDERR <<STOP;
+Usage: $FindBin::Script [options] FILE ...
+
+Translate each FILE to the new Qemu timer API. If no files
+are passed, a reasonable guess is taken.
+
+Options:
+  -q, --quiet     Do not show warnings etc
+  -d, --dry-run   Do a dry run
+  -g, --git       Generate a git commit for each change
+  -r, --rtc       Only fix up rtc usage
+  -h, --help      Print this message
+
+STOP
+return;
+}
+
+sub ParseOptions
+{
+    if (!GetOptions (
+	     "dry-run|d" => \$option_dryrun,
+             "git|g" => \$option_git,
+	     "quiet|q" => \$option_quiet,
+	     "rtc|r" => \$option_rtc,
+             "help|h" => sub { Syntax(); exit(0); }
+        ))
+    {
+        Syntax();
+        die "Bad options";
+    }
+
+    if ($#ARGV >=0)
+    {
+	@files = @ARGV;
+    }
+    else
+    {
+	@files = split(/\s+/, `$getfiles`);
+    }
+
+    foreach my $file (@files)
+    {
+	die "Cannot find $file" unless (-f $file && -r $file);
+    }
+}
+
+sub DoWarn
+{
+    my $text = shift @_;
+    my $line = shift @_;
+    return if ($option_quiet);
+    chomp ($line);
+    print STDERR "$text\n";
+    print STDERR "$line\n\n";
+}
+
+sub Process
+{
+    my $ifn = shift @_;
+    my $ofn = $ifn.$suffix;
+
+    my $intext;
+    my $outtext;
+    my $linenum = 0;
+
+    open my $input, "<", $ifn || die "Cannot open $ifn for read: $!";
+
+    while (<$input>)
+    {
+	my $line = $_;
+	$intext .= $line;
+	$linenum++;
+
+	# fix the specific uses
+	unless ($option_rtc)
+	{
+	    $line =~ s/\bqemu_new_timer(_[num]s)\s*\((vm_|rt_|host_)clock\b/timer_new$1(XXX_$2clock/g;
+	    $line =~ s/\bqemu_new_timer\s*\((vm_|rt_|host_)clock\b/timer_new(XXX_$1clock/g;
+	    $line =~ s/\bqemu_get_clock(_[num]s)\s*\((vm_|rt_|host_)clock\b/qemu_clock_get$1(XXX_$2clock/g;
+	}
+
+	# rtc is different
+	$line =~ s/\bqemu_new_timer(_[num]s)\s*\(rtc_clock\b/timer_new$1(rtc_clock/g;
+	$line =~ s/\bqemu_new_timer\s*\(rtc_clock\b/timer_new(rtc_clock/g;
+	$line =~ s/\bqemu_get_clock(_[num]s)\s*\(rtc_clock\b/qemu_clock_get$1(rtc_clock/g;
+	$line =~ s/\bqemu_register_clock_reset_notifier\s*\(rtc_clock\b/qemu_register_clock_reset_notifier(qemu_clock_ptr(rtc_clock)/g;
+
+	unless ($option_rtc)
+	{
+	    # fix up comments
+	    $line =~ s/\b(vm_|rt_|host_)clock\b/XXX_$1clock/g if ($line =~ m,^[/ ]+\*,);
+
+	    # spurious fprintf error reporting
+	    $line =~ s/: qemu_new_timer_ns failed/: timer_new_ns failed/g;
+
+	    # these have just changed name
+	    $line =~ s/\bqemu_mod_timer\b/timer_mod/g;
+	    $line =~ s/\bqemu_mod_timer_(ns|us|ms)\b/timer_mod_$1/g;
+	    $line =~ s/\bqemu_free_timer\b/timer_free/g;
+	    $line =~ s/\bqemu_del_timer\b/timer_del/g;
+	}
+
+	# fix up rtc_clock
+	$line =~ s/QEMUClock \*rtc_clock;/QEMUClockType rtc_clock;/g;
+	$line =~ s/\brtc_clock = (vm_|rt_|host_)clock\b/rtc_clock = XXX_$1clock/g;
+
+	unless ($option_rtc)
+	{
+	    # replace any more general uses
+	    $line =~ s/\b(vm_|rt_|host_)clock\b/qemu_clock_ptr(XXX_$1clock)/g;
+	}
+
+	# fix up the place holders
+	$line =~ s/\bXXX_vm_clock\b/QEMU_CLOCK_VIRTUAL/g;
+	$line =~ s/\bXXX_rt_clock\b/QEMU_CLOCK_REALTIME/g;
+	$line =~ s/\bXXX_host_clock\b/QEMU_CLOCK_HOST/g;
+
+	unless ($option_rtc)
+	{
+	    DoWarn("$ifn:$linenum WARNING: timer $1 not fixed up", $line) if ($line =~ /\b((vm_|rt_|host_)clock)\b/);
+	    DoWarn("$ifn:$linenum WARNING: function $1 not fixed up", $line) if ($line =~ /\b(qemu_new_timer\w+)\b/);
+	    DoWarn("$ifn:$linenum WARNING: legacy function $1 remains", $line) if ($line =~ /$legacyre/o);
+	}
+
+	$outtext .= $line;
+    }
+
+    close $input;
+
+    if ($intext ne $outtext)
+    {
+	print STDERR "Patching $ifn\n" unless ($option_quiet);
+	unless ($option_dryrun)
+	{
+	    open my $output, ">", $ofn || die "Cannot open $ofn for write: $!";
+	    print $output $outtext;
+	    close $output;
+	    rename ($ofn, $ifn) || die "Cannot rename temp file to $ifn: $!";
+	    return 1;
+	}
+    }
+    return 0;
+}
+
+sub DoCommit
+{
+    my $file = shift @_;
+    open (my $git, "| git commit -F - $file") || die "Cannot run git commit on $file: $!";
+    print $git "timers api: use new timer api in $file\n\nConvert $file to use new timer API.\nThis is an automated commit made by scripts/switch-timer-api\n";
+    close ($git);
+}
+
+ParseOptions;
+
+foreach my $file (@files)
+{
+    my $changed = Process ($file);
+    DoCommit($file) if ($changed && $option_git);
+}
commit b53edf971f060389179b2935ca09e2cd9f9a728b
Author: Alex Bligh <alex at alex.org.uk>
Date:   Wed Aug 21 16:03:06 2013 +0100

    aio / timers: Add test harness for AioContext timers
    
    Add a test harness for AioContext timers. The g_source equivalent is
    unsatisfactory as it suffers from false wakeups.
    
    Signed-off-by: Alex Bligh <alex at alex.org.uk>
    Signed-off-by: Stefan Hajnoczi <stefanha at redhat.com>

diff --git a/tests/test-aio.c b/tests/test-aio.c
index e1f394b..3ad2294 100644
--- a/tests/test-aio.c
+++ b/tests/test-aio.c
@@ -47,6 +47,15 @@ typedef struct {
     int max;
 } BHTestData;
 
+typedef struct {
+    QEMUTimer timer;
+    QEMUClockType clock_type;
+    int n;
+    int max;
+    int64_t ns;
+    AioContext *ctx;
+} TimerTestData;
+
 static void bh_test_cb(void *opaque)
 {
     BHTestData *data = opaque;
@@ -55,6 +64,24 @@ static void bh_test_cb(void *opaque)
     }
 }
 
+static void timer_test_cb(void *opaque)
+{
+    TimerTestData *data = opaque;
+    if (++data->n < data->max) {
+        timer_mod(&data->timer,
+                  qemu_clock_get_ns(data->clock_type) + data->ns);
+    }
+}
+
+static void dummy_io_handler_read(void *opaque)
+{
+}
+
+static int dummy_io_handler_flush(void *opaque)
+{
+    return 1;
+}
+
 static void bh_delete_cb(void *opaque)
 {
     BHTestData *data = opaque;
@@ -343,6 +370,64 @@ static void test_wait_event_notifier_noflush(void)
     event_notifier_cleanup(&data.e);
 }
 
+static void test_timer_schedule(void)
+{
+    TimerTestData data = { .n = 0, .ctx = ctx, .ns = SCALE_MS * 750LL,
+                           .max = 2,
+                           .clock_type = QEMU_CLOCK_VIRTUAL };
+    int pipefd[2];
+
+    /* aio_poll will not block to wait for timers to complete unless it has
+     * an fd to wait on. Fixing this breaks other tests. So create a dummy one.
+     */
+    g_assert(!pipe2(pipefd, O_NONBLOCK));
+    aio_set_fd_handler(ctx, pipefd[0],
+                       dummy_io_handler_read, NULL, dummy_io_handler_flush);
+    aio_poll(ctx, false);
+
+    aio_timer_init(ctx, &data.timer, data.clock_type,
+                   SCALE_NS, timer_test_cb, &data);
+    timer_mod(&data.timer,
+              qemu_clock_get_ns(data.clock_type) +
+              data.ns);
+
+    g_assert_cmpint(data.n, ==, 0);
+
+    /* timer_mod may well cause an event notifer to have gone off,
+     * so clear that
+     */
+    do {} while (aio_poll(ctx, false));
+
+    g_assert(!aio_poll(ctx, false));
+    g_assert_cmpint(data.n, ==, 0);
+
+    sleep(1);
+    g_assert_cmpint(data.n, ==, 0);
+
+    g_assert(aio_poll(ctx, false));
+    g_assert_cmpint(data.n, ==, 1);
+
+    /* timer_mod called by our callback */
+    do {} while (aio_poll(ctx, false));
+
+    g_assert(!aio_poll(ctx, false));
+    g_assert_cmpint(data.n, ==, 1);
+
+    g_assert(aio_poll(ctx, true));
+    g_assert_cmpint(data.n, ==, 2);
+
+    /* As max is now 2, an event notifier should not have gone off */
+
+    g_assert(!aio_poll(ctx, false));
+    g_assert_cmpint(data.n, ==, 2);
+
+    aio_set_fd_handler(ctx, pipefd[0], NULL, NULL, NULL);
+    close(pipefd[0]);
+    close(pipefd[1]);
+
+    timer_del(&data.timer);
+}
+
 /* Now the same tests, using the context as a GSource.  They are
  * very similar to the ones above, with g_main_context_iteration
  * replacing aio_poll.  However:
@@ -625,6 +710,53 @@ static void test_source_wait_event_notifier_noflush(void)
     event_notifier_cleanup(&data.e);
 }
 
+static void test_source_timer_schedule(void)
+{
+    TimerTestData data = { .n = 0, .ctx = ctx, .ns = SCALE_MS * 750LL,
+                           .max = 2,
+                           .clock_type = QEMU_CLOCK_VIRTUAL };
+    int pipefd[2];
+    int64_t expiry;
+
+    /* aio_poll will not block to wait for timers to complete unless it has
+     * an fd to wait on. Fixing this breaks other tests. So create a dummy one.
+     */
+    g_assert(!pipe2(pipefd, O_NONBLOCK));
+    aio_set_fd_handler(ctx, pipefd[0],
+                       dummy_io_handler_read, NULL, dummy_io_handler_flush);
+    do {} while (g_main_context_iteration(NULL, false));
+
+    aio_timer_init(ctx, &data.timer, data.clock_type,
+                   SCALE_NS, timer_test_cb, &data);
+    expiry = qemu_clock_get_ns(data.clock_type) +
+        data.ns;
+    timer_mod(&data.timer, expiry);
+
+    g_assert_cmpint(data.n, ==, 0);
+
+    sleep(1);
+    g_assert_cmpint(data.n, ==, 0);
+
+    g_assert(g_main_context_iteration(NULL, false));
+    g_assert_cmpint(data.n, ==, 1);
+
+    /* The comment above was not kidding when it said this wakes up itself */
+    do {
+        g_assert(g_main_context_iteration(NULL, true));
+    } while (qemu_clock_get_ns(data.clock_type) <= expiry);
+    sleep(1);
+    g_main_context_iteration(NULL, false);
+
+    g_assert_cmpint(data.n, ==, 2);
+
+    aio_set_fd_handler(ctx, pipefd[0], NULL, NULL, NULL);
+    close(pipefd[0]);
+    close(pipefd[1]);
+
+    timer_del(&data.timer);
+}
+
+
 /* End of tests.  */
 
 int main(int argc, char **argv)
@@ -653,6 +785,7 @@ int main(int argc, char **argv)
     g_test_add_func("/aio/event/wait",              test_wait_event_notifier);
     g_test_add_func("/aio/event/wait/no-flush-cb",  test_wait_event_notifier_noflush);
     g_test_add_func("/aio/event/flush",             test_flush_event_notifier);
+    g_test_add_func("/aio/timer/schedule",          test_timer_schedule);
 
     g_test_add_func("/aio-gsource/notify",                  test_source_notify);
     g_test_add_func("/aio-gsource/flush",                   test_source_flush);
@@ -667,5 +800,6 @@ int main(int argc, char **argv)
     g_test_add_func("/aio-gsource/event/wait",              test_source_wait_event_notifier);
     g_test_add_func("/aio-gsource/event/wait/no-flush-cb",  test_source_wait_event_notifier_noflush);
     g_test_add_func("/aio-gsource/event/flush",             test_source_flush_event_notifier);
+    g_test_add_func("/aio-gsource/timer/schedule",          test_source_timer_schedule);
     return g_test_run();
 }
commit 7483d1e54700156e4c22e2e1b5d85de6eb92fdcf
Author: Alex Bligh <alex at alex.org.uk>
Date:   Wed Aug 21 16:03:05 2013 +0100

    aio / timers: convert block_job_sleep_ns and co_sleep_ns to new API
    
    Convert block_job_sleep_ns and co_sleep_ns to use the new timer
    API.
    
    Signed-off-by: Alex Bligh <alex at alex.org.uk>
    Signed-off-by: Stefan Hajnoczi <stefanha at redhat.com>

diff --git a/block/backup.c b/block/backup.c
index 6ae8a05..e12b3b1 100644
--- a/block/backup.c
+++ b/block/backup.c
@@ -272,9 +272,9 @@ static void coroutine_fn backup_run(void *opaque)
                 uint64_t delay_ns = ratelimit_calculate_delay(
                         &job->limit, job->sectors_read);
                 job->sectors_read = 0;
-                block_job_sleep_ns(&job->common, rt_clock, delay_ns);
+                block_job_sleep_ns(&job->common, QEMU_CLOCK_REALTIME, delay_ns);
             } else {
-                block_job_sleep_ns(&job->common, rt_clock, 0);
+                block_job_sleep_ns(&job->common, QEMU_CLOCK_REALTIME, 0);
             }
 
             if (block_job_is_cancelled(&job->common)) {
diff --git a/block/commit.c b/block/commit.c
index 2227fc2..51a1ab3 100644
--- a/block/commit.c
+++ b/block/commit.c
@@ -103,7 +103,7 @@ wait:
         /* Note that even when no rate limit is applied we need to yield
          * with no pending I/O here so that bdrv_drain_all() returns.
          */
-        block_job_sleep_ns(&s->common, rt_clock, delay_ns);
+        block_job_sleep_ns(&s->common, QEMU_CLOCK_REALTIME, delay_ns);
         if (block_job_is_cancelled(&s->common)) {
             break;
         }
diff --git a/block/mirror.c b/block/mirror.c
index bed4a7e..ead567e 100644
--- a/block/mirror.c
+++ b/block/mirror.c
@@ -439,13 +439,13 @@ static void coroutine_fn mirror_run(void *opaque)
                 delay_ns = 0;
             }
 
-            block_job_sleep_ns(&s->common, rt_clock, delay_ns);
+            block_job_sleep_ns(&s->common, QEMU_CLOCK_REALTIME, delay_ns);
             if (block_job_is_cancelled(&s->common)) {
                 break;
             }
         } else if (!should_complete) {
             delay_ns = (s->in_flight == 0 && cnt == 0 ? SLICE_TIME : 0);
-            block_job_sleep_ns(&s->common, rt_clock, delay_ns);
+            block_job_sleep_ns(&s->common, QEMU_CLOCK_REALTIME, delay_ns);
         } else if (cnt == 0) {
             /* The two disks are in sync.  Exit and report successful
              * completion.
diff --git a/block/stream.c b/block/stream.c
index db49b4d..9982125 100644
--- a/block/stream.c
+++ b/block/stream.c
@@ -114,7 +114,7 @@ wait:
         /* Note that even when no rate limit is applied we need to yield
          * with no pending I/O here so that bdrv_drain_all() returns.
          */
-        block_job_sleep_ns(&s->common, rt_clock, delay_ns);
+        block_job_sleep_ns(&s->common, QEMU_CLOCK_REALTIME, delay_ns);
         if (block_job_is_cancelled(&s->common)) {
             break;
         }
diff --git a/blockjob.c b/blockjob.c
index ca80df1..7edc945 100644
--- a/blockjob.c
+++ b/blockjob.c
@@ -187,7 +187,7 @@ int block_job_cancel_sync(BlockJob *job)
     return (data.cancelled && data.ret == 0) ? -ECANCELED : data.ret;
 }
 
-void block_job_sleep_ns(BlockJob *job, QEMUClock *clock, int64_t ns)
+void block_job_sleep_ns(BlockJob *job, QEMUClockType type, int64_t ns)
 {
     assert(job->busy);
 
@@ -200,7 +200,7 @@ void block_job_sleep_ns(BlockJob *job, QEMUClock *clock, int64_t ns)
     if (block_job_is_paused(job)) {
         qemu_coroutine_yield();
     } else {
-        co_sleep_ns(clock, ns);
+        co_sleep_ns(type, ns);
     }
     job->busy = true;
 }
diff --git a/include/block/blockjob.h b/include/block/blockjob.h
index c290d07..d530409 100644
--- a/include/block/blockjob.h
+++ b/include/block/blockjob.h
@@ -141,7 +141,7 @@ void *block_job_create(const BlockJobType *job_type, BlockDriverState *bs,
  * Put the job to sleep (assuming that it wasn't canceled) for @ns
  * nanoseconds.  Canceling the job will interrupt the wait immediately.
  */
-void block_job_sleep_ns(BlockJob *job, QEMUClock *clock, int64_t ns);
+void block_job_sleep_ns(BlockJob *job, QEMUClockType type, int64_t ns);
 
 /**
  * block_job_completed:
diff --git a/include/block/coroutine.h b/include/block/coroutine.h
index 17f5851..4232569 100644
--- a/include/block/coroutine.h
+++ b/include/block/coroutine.h
@@ -213,7 +213,7 @@ void qemu_co_rwlock_unlock(CoRwlock *lock);
  * Note this function uses timers and hence only works when a main loop is in
  * use.  See main-loop.h and do not use from qemu-tool programs.
  */
-void coroutine_fn co_sleep_ns(QEMUClock *clock, int64_t ns);
+void coroutine_fn co_sleep_ns(QEMUClockType type, int64_t ns);
 
 /**
  * Yield until a file descriptor becomes readable
diff --git a/qemu-coroutine-sleep.c b/qemu-coroutine-sleep.c
index 169ce5c..f6db978 100644
--- a/qemu-coroutine-sleep.c
+++ b/qemu-coroutine-sleep.c
@@ -26,14 +26,14 @@ static void co_sleep_cb(void *opaque)
     qemu_coroutine_enter(sleep_cb->co, NULL);
 }
 
-void coroutine_fn co_sleep_ns(QEMUClock *clock, int64_t ns)
+void coroutine_fn co_sleep_ns(QEMUClockType type, int64_t ns)
 {
     CoSleepCB sleep_cb = {
         .co = qemu_coroutine_self(),
     };
-    sleep_cb.ts = qemu_new_timer(clock, SCALE_NS, co_sleep_cb, &sleep_cb);
-    qemu_mod_timer(sleep_cb.ts, qemu_get_clock_ns(clock) + ns);
+    sleep_cb.ts = timer_new(type, SCALE_NS, co_sleep_cb, &sleep_cb);
+    timer_mod(sleep_cb.ts, qemu_clock_get_ns(type) + ns);
     qemu_coroutine_yield();
-    qemu_del_timer(sleep_cb.ts);
-    qemu_free_timer(sleep_cb.ts);
+    timer_del(sleep_cb.ts);
+    timer_free(sleep_cb.ts);
 }
commit 884f17c235095af99b92dd8cd10bb824a5b0f777
Author: Alex Bligh <alex at alex.org.uk>
Date:   Wed Aug 21 16:03:04 2013 +0100

    aio / timers: Convert rtc_clock to be a QEMUClockType
    
    Convert rtc_clock to be a QEMUClockType
    
    Move rtc_clock users to use the new API
    
    Signed-off-by: Alex Bligh <alex at alex.org.uk>
    Signed-off-by: Stefan Hajnoczi <stefanha at redhat.com>

diff --git a/hw/arm/omap1.c b/hw/arm/omap1.c
index b6a0b27..864c07e 100644
--- a/hw/arm/omap1.c
+++ b/hw/arm/omap1.c
@@ -2894,7 +2894,7 @@ static void omap_rtc_reset(struct omap_rtc_s *s)
     s->pm_am = 0;
     s->auto_comp = 0;
     s->round = 0;
-    s->tick = qemu_get_clock_ms(rtc_clock);
+    s->tick = qemu_clock_get_ms(rtc_clock);
     memset(&s->alarm_tm, 0, sizeof(s->alarm_tm));
     s->alarm_tm.tm_mday = 0x01;
     s->status = 1 << 7;
@@ -2915,7 +2915,7 @@ static struct omap_rtc_s *omap_rtc_init(MemoryRegion *system_memory,
 
     s->irq = timerirq;
     s->alarm = alarmirq;
-    s->clk = qemu_new_timer_ms(rtc_clock, omap_rtc_tick, s);
+    s->clk = timer_new_ms(rtc_clock, omap_rtc_tick, s);
 
     omap_rtc_reset(s);
 
diff --git a/hw/arm/pxa2xx.c b/hw/arm/pxa2xx.c
index 17ddd3f..331bc72 100644
--- a/hw/arm/pxa2xx.c
+++ b/hw/arm/pxa2xx.c
@@ -842,7 +842,7 @@ static inline void pxa2xx_rtc_int_update(PXA2xxRTCState *s)
 
 static void pxa2xx_rtc_hzupdate(PXA2xxRTCState *s)
 {
-    int64_t rt = qemu_get_clock_ms(rtc_clock);
+    int64_t rt = qemu_clock_get_ms(rtc_clock);
     s->last_rcnr += ((rt - s->last_hz) << 15) /
             (1000 * ((s->rttr & 0xffff) + 1));
     s->last_rdcr += ((rt - s->last_hz) << 15) /
@@ -852,7 +852,7 @@ static void pxa2xx_rtc_hzupdate(PXA2xxRTCState *s)
 
 static void pxa2xx_rtc_swupdate(PXA2xxRTCState *s)
 {
-    int64_t rt = qemu_get_clock_ms(rtc_clock);
+    int64_t rt = qemu_clock_get_ms(rtc_clock);
     if (s->rtsr & (1 << 12))
         s->last_swcr += (rt - s->last_sw) / 10;
     s->last_sw = rt;
@@ -860,7 +860,7 @@ static void pxa2xx_rtc_swupdate(PXA2xxRTCState *s)
 
 static void pxa2xx_rtc_piupdate(PXA2xxRTCState *s)
 {
-    int64_t rt = qemu_get_clock_ms(rtc_clock);
+    int64_t rt = qemu_clock_get_ms(rtc_clock);
     if (s->rtsr & (1 << 15))
         s->last_swcr += rt - s->last_pi;
     s->last_pi = rt;
@@ -986,16 +986,19 @@ static uint64_t pxa2xx_rtc_read(void *opaque, hwaddr addr,
     case PIAR:
         return s->piar;
     case RCNR:
-        return s->last_rcnr + ((qemu_get_clock_ms(rtc_clock) - s->last_hz) << 15) /
-                (1000 * ((s->rttr & 0xffff) + 1));
+        return s->last_rcnr +
+            ((qemu_clock_get_ms(rtc_clock) - s->last_hz) << 15) /
+            (1000 * ((s->rttr & 0xffff) + 1));
     case RDCR:
-        return s->last_rdcr + ((qemu_get_clock_ms(rtc_clock) - s->last_hz) << 15) /
-                (1000 * ((s->rttr & 0xffff) + 1));
+        return s->last_rdcr +
+            ((qemu_clock_get_ms(rtc_clock) - s->last_hz) << 15) /
+            (1000 * ((s->rttr & 0xffff) + 1));
     case RYCR:
         return s->last_rycr;
     case SWCR:
         if (s->rtsr & (1 << 12))
-            return s->last_swcr + (qemu_get_clock_ms(rtc_clock) - s->last_sw) / 10;
+            return s->last_swcr +
+                (qemu_clock_get_ms(rtc_clock) - s->last_sw) / 10;
         else
             return s->last_swcr;
     default:
@@ -1135,14 +1138,14 @@ static int pxa2xx_rtc_init(SysBusDevice *dev)
     s->last_swcr = (tm.tm_hour << 19) |
             (tm.tm_min << 13) | (tm.tm_sec << 7);
     s->last_rtcpicr = 0;
-    s->last_hz = s->last_sw = s->last_pi = qemu_get_clock_ms(rtc_clock);
-
-    s->rtc_hz    = qemu_new_timer_ms(rtc_clock, pxa2xx_rtc_hz_tick,    s);
-    s->rtc_rdal1 = qemu_new_timer_ms(rtc_clock, pxa2xx_rtc_rdal1_tick, s);
-    s->rtc_rdal2 = qemu_new_timer_ms(rtc_clock, pxa2xx_rtc_rdal2_tick, s);
-    s->rtc_swal1 = qemu_new_timer_ms(rtc_clock, pxa2xx_rtc_swal1_tick, s);
-    s->rtc_swal2 = qemu_new_timer_ms(rtc_clock, pxa2xx_rtc_swal2_tick, s);
-    s->rtc_pi    = qemu_new_timer_ms(rtc_clock, pxa2xx_rtc_pi_tick,    s);
+    s->last_hz = s->last_sw = s->last_pi = qemu_clock_get_ms(rtc_clock);
+
+    s->rtc_hz    = timer_new_ms(rtc_clock, pxa2xx_rtc_hz_tick,    s);
+    s->rtc_rdal1 = timer_new_ms(rtc_clock, pxa2xx_rtc_rdal1_tick, s);
+    s->rtc_rdal2 = timer_new_ms(rtc_clock, pxa2xx_rtc_rdal2_tick, s);
+    s->rtc_swal1 = timer_new_ms(rtc_clock, pxa2xx_rtc_swal1_tick, s);
+    s->rtc_swal2 = timer_new_ms(rtc_clock, pxa2xx_rtc_swal2_tick, s);
+    s->rtc_pi    = timer_new_ms(rtc_clock, pxa2xx_rtc_pi_tick,    s);
 
     sysbus_init_irq(dev, &s->rtc_irq);
 
diff --git a/hw/arm/strongarm.c b/hw/arm/strongarm.c
index 7b8ef8c..6528cc0 100644
--- a/hw/arm/strongarm.c
+++ b/hw/arm/strongarm.c
@@ -269,7 +269,7 @@ static inline void strongarm_rtc_int_update(StrongARMRTCState *s)
 
 static void strongarm_rtc_hzupdate(StrongARMRTCState *s)
 {
-    int64_t rt = qemu_get_clock_ms(rtc_clock);
+    int64_t rt = qemu_clock_get_ms(rtc_clock);
     s->last_rcnr += ((rt - s->last_hz) << 15) /
             (1000 * ((s->rttr & 0xffff) + 1));
     s->last_hz = rt;
@@ -322,7 +322,7 @@ static uint64_t strongarm_rtc_read(void *opaque, hwaddr addr,
         return s->rtar;
     case RCNR:
         return s->last_rcnr +
-                ((qemu_get_clock_ms(rtc_clock) - s->last_hz) << 15) /
+                ((qemu_clock_get_ms(rtc_clock) - s->last_hz) << 15) /
                 (1000 * ((s->rttr & 0xffff) + 1));
     default:
         printf("%s: Bad register 0x" TARGET_FMT_plx "\n", __func__, addr);
@@ -388,10 +388,10 @@ static int strongarm_rtc_init(SysBusDevice *dev)
     qemu_get_timedate(&tm, 0);
 
     s->last_rcnr = (uint32_t) mktimegm(&tm);
-    s->last_hz = qemu_get_clock_ms(rtc_clock);
+    s->last_hz = qemu_clock_get_ms(rtc_clock);
 
-    s->rtc_alarm = qemu_new_timer_ms(rtc_clock, strongarm_rtc_alarm_tick, s);
-    s->rtc_hz = qemu_new_timer_ms(rtc_clock, strongarm_rtc_hz_tick, s);
+    s->rtc_alarm = timer_new_ms(rtc_clock, strongarm_rtc_alarm_tick, s);
+    s->rtc_hz = timer_new_ms(rtc_clock, strongarm_rtc_hz_tick, s);
 
     sysbus_init_irq(dev, &s->rtc_irq);
     sysbus_init_irq(dev, &s->rtc_hz_irq);
diff --git a/hw/timer/m48t59.c b/hw/timer/m48t59.c
index 0cc9e5b..098e5ad 100644
--- a/hw/timer/m48t59.c
+++ b/hw/timer/m48t59.c
@@ -137,7 +137,7 @@ static void alarm_cb (void *opaque)
         /* Repeat once a second */
         next_time = 1;
     }
-    qemu_mod_timer(NVRAM->alrm_timer, qemu_get_clock_ns(rtc_clock) +
+    qemu_mod_timer(NVRAM->alrm_timer, qemu_clock_get_ns(rtc_clock) +
                     next_time * 1000);
     qemu_set_irq(NVRAM->IRQ, 0);
 }
@@ -700,7 +700,7 @@ static void m48t59_realize_common(M48t59State *s, Error **errp)
 {
     s->buffer = g_malloc0(s->size);
     if (s->model == 59) {
-        s->alrm_timer = qemu_new_timer_ns(rtc_clock, &alarm_cb, s);
+        s->alrm_timer = timer_new_ns(rtc_clock, &alarm_cb, s);
         s->wd_timer = qemu_new_timer_ns(vm_clock, &watchdog_cb, s);
     }
     qemu_get_timedate(&s->alarm, 0);
diff --git a/hw/timer/mc146818rtc.c b/hw/timer/mc146818rtc.c
index d12f6e7..1c6bb29 100644
--- a/hw/timer/mc146818rtc.c
+++ b/hw/timer/mc146818rtc.c
@@ -102,7 +102,7 @@ static inline bool rtc_running(RTCState *s)
 static uint64_t get_guest_rtc_ns(RTCState *s)
 {
     uint64_t guest_rtc;
-    uint64_t guest_clock = qemu_get_clock_ns(rtc_clock);
+    uint64_t guest_clock = qemu_clock_get_ns(rtc_clock);
 
     guest_rtc = s->base_rtc * NSEC_PER_SEC
                  + guest_clock - s->last_update + s->offset;
@@ -117,7 +117,7 @@ static void rtc_coalesced_timer_update(RTCState *s)
     } else {
         /* divide each RTC interval to 2 - 8 smaller intervals */
         int c = MIN(s->irq_coalesced, 7) + 1; 
-        int64_t next_clock = qemu_get_clock_ns(rtc_clock) +
+        int64_t next_clock = qemu_clock_get_ns(rtc_clock) +
             muldiv64(s->period / c, get_ticks_per_sec(), RTC_CLOCK_RATE);
         qemu_mod_timer(s->coalesced_timer, next_clock);
     }
@@ -238,7 +238,7 @@ static void check_update_timer(RTCState *s)
 
     guest_nsec = get_guest_rtc_ns(s) % NSEC_PER_SEC;
     /* if UF is clear, reprogram to next second */
-    next_update_time = qemu_get_clock_ns(rtc_clock)
+    next_update_time = qemu_clock_get_ns(rtc_clock)
         + NSEC_PER_SEC - guest_nsec;
 
     /* Compute time of next alarm.  One second is already accounted
@@ -371,7 +371,7 @@ static void rtc_update_timer(void *opaque)
     rtc_update_time(s);
     s->cmos_data[RTC_REG_A] &= ~REG_A_UIP;
 
-    if (qemu_get_clock_ns(rtc_clock) >= s->next_alarm_time) {
+    if (qemu_clock_get_ns(rtc_clock) >= s->next_alarm_time) {
         irqs |= REG_C_AF;
         if (s->cmos_data[RTC_REG_B] & REG_B_AIE) {
             qemu_system_wakeup_request(QEMU_WAKEUP_REASON_RTC);
@@ -445,7 +445,7 @@ static void cmos_ioport_write(void *opaque, hwaddr addr,
             /* UIP bit is read only */
             s->cmos_data[RTC_REG_A] = (data & ~REG_A_UIP) |
                 (s->cmos_data[RTC_REG_A] & REG_A_UIP);
-            periodic_timer_update(s, qemu_get_clock_ns(rtc_clock));
+            periodic_timer_update(s, qemu_clock_get_ns(rtc_clock));
             check_update_timer(s);
             break;
         case RTC_REG_B:
@@ -475,7 +475,7 @@ static void cmos_ioport_write(void *opaque, hwaddr addr,
                 qemu_irq_lower(s->irq);
             }
             s->cmos_data[RTC_REG_B] = data;
-            periodic_timer_update(s, qemu_get_clock_ns(rtc_clock));
+            periodic_timer_update(s, qemu_clock_get_ns(rtc_clock));
             check_update_timer(s);
             break;
         case RTC_REG_C:
@@ -535,7 +535,7 @@ static void rtc_set_time(RTCState *s)
 
     rtc_get_time(s, &tm);
     s->base_rtc = mktimegm(&tm);
-    s->last_update = qemu_get_clock_ns(rtc_clock);
+    s->last_update = qemu_clock_get_ns(rtc_clock);
 
     rtc_change_mon_event(&tm);
 }
@@ -590,7 +590,8 @@ static int update_in_progress(RTCState *s)
     if (timer_pending(s->update_timer)) {
         int64_t next_update_time = timer_expire_time_ns(s->update_timer);
         /* Latch UIP until the timer expires.  */
-        if (qemu_get_clock_ns(rtc_clock) >= (next_update_time - UIP_HOLD_LENGTH)) {
+        if (qemu_clock_get_ns(rtc_clock) >=
+            (next_update_time - UIP_HOLD_LENGTH)) {
             s->cmos_data[RTC_REG_A] |= REG_A_UIP;
             return 1;
         }
@@ -695,7 +696,7 @@ static void rtc_set_date_from_host(ISADevice *dev)
     qemu_get_timedate(&tm, 0);
 
     s->base_rtc = mktimegm(&tm);
-    s->last_update = qemu_get_clock_ns(rtc_clock);
+    s->last_update = qemu_clock_get_ns(rtc_clock);
     s->offset = 0;
 
     /* set the CMOS date */
@@ -843,7 +844,7 @@ static void rtc_realizefn(DeviceState *dev, Error **errp)
     switch (s->lost_tick_policy) {
     case LOST_TICK_SLEW:
         s->coalesced_timer =
-            qemu_new_timer_ns(rtc_clock, rtc_coalesced_timer, s);
+            timer_new_ns(rtc_clock, rtc_coalesced_timer, s);
         break;
     case LOST_TICK_DISCARD:
         break;
@@ -853,12 +854,13 @@ static void rtc_realizefn(DeviceState *dev, Error **errp)
     }
 #endif
 
-    s->periodic_timer = qemu_new_timer_ns(rtc_clock, rtc_periodic_timer, s);
-    s->update_timer = qemu_new_timer_ns(rtc_clock, rtc_update_timer, s);
+    s->periodic_timer = timer_new_ns(rtc_clock, rtc_periodic_timer, s);
+    s->update_timer = timer_new_ns(rtc_clock, rtc_update_timer, s);
     check_update_timer(s);
 
     s->clock_reset_notifier.notify = rtc_notify_clock_reset;
-    qemu_register_clock_reset_notifier(rtc_clock, &s->clock_reset_notifier);
+    qemu_clock_register_reset_notifier(QEMU_CLOCK_REALTIME,
+                                       &s->clock_reset_notifier);
 
     s->suspend_notifier.notify = rtc_notify_suspend;
     qemu_register_suspend_notifier(&s->suspend_notifier);
diff --git a/hw/timer/pl031.c b/hw/timer/pl031.c
index d5e2f3e..e398a67 100644
--- a/hw/timer/pl031.c
+++ b/hw/timer/pl031.c
@@ -78,7 +78,7 @@ static void pl031_interrupt(void * opaque)
 
 static uint32_t pl031_get_count(PL031State *s)
 {
-    int64_t now = qemu_get_clock_ns(rtc_clock);
+    int64_t now = qemu_clock_get_ns(rtc_clock);
     return s->tick_offset + now / get_ticks_per_sec();
 }
 
@@ -94,7 +94,7 @@ static void pl031_set_alarm(PL031State *s)
         qemu_del_timer(s->timer);
         pl031_interrupt(s);
     } else {
-        int64_t now = qemu_get_clock_ns(rtc_clock);
+        int64_t now = qemu_clock_get_ns(rtc_clock);
         qemu_mod_timer(s->timer, now + (int64_t)ticks * get_ticks_per_sec());
     }
 }
@@ -201,9 +201,10 @@ static int pl031_init(SysBusDevice *dev)
 
     sysbus_init_irq(dev, &s->irq);
     qemu_get_timedate(&tm, 0);
-    s->tick_offset = mktimegm(&tm) - qemu_get_clock_ns(rtc_clock) / get_ticks_per_sec();
+    s->tick_offset = mktimegm(&tm) -
+        qemu_clock_get_ns(rtc_clock) / get_ticks_per_sec();
 
-    s->timer = qemu_new_timer_ns(rtc_clock, pl031_interrupt, s);
+    s->timer = timer_new_ns(rtc_clock, pl031_interrupt, s);
     return 0;
 }
 
@@ -213,7 +214,7 @@ static void pl031_pre_save(void *opaque)
 
     /* tick_offset is base_time - rtc_clock base time.  Instead, we want to
      * store the base time relative to the vm_clock for backwards-compatibility.  */
-    int64_t delta = qemu_get_clock_ns(rtc_clock) - qemu_get_clock_ns(vm_clock);
+    int64_t delta = qemu_clock_get_ns(rtc_clock) - qemu_get_clock_ns(vm_clock);
     s->tick_offset_vmstate = s->tick_offset + delta / get_ticks_per_sec();
 }
 
@@ -221,7 +222,7 @@ static int pl031_post_load(void *opaque, int version_id)
 {
     PL031State *s = opaque;
 
-    int64_t delta = qemu_get_clock_ns(rtc_clock) - qemu_get_clock_ns(vm_clock);
+    int64_t delta = qemu_clock_get_ns(rtc_clock) - qemu_get_clock_ns(vm_clock);
     s->tick_offset = s->tick_offset_vmstate - delta / get_ticks_per_sec();
     pl031_set_alarm(s);
     return 0;
diff --git a/hw/timer/twl92230.c b/hw/timer/twl92230.c
index b730d85..431677e 100644
--- a/hw/timer/twl92230.c
+++ b/hw/timer/twl92230.c
@@ -72,14 +72,14 @@ static inline void menelaus_update(MenelausState *s)
 
 static inline void menelaus_rtc_start(MenelausState *s)
 {
-    s->rtc.next += qemu_get_clock_ms(rtc_clock);
+    s->rtc.next += qemu_clock_get_ms(rtc_clock);
     qemu_mod_timer(s->rtc.hz_tm, s->rtc.next);
 }
 
 static inline void menelaus_rtc_stop(MenelausState *s)
 {
     qemu_del_timer(s->rtc.hz_tm);
-    s->rtc.next -= qemu_get_clock_ms(rtc_clock);
+    s->rtc.next -= qemu_clock_get_ms(rtc_clock);
     if (s->rtc.next < 1)
         s->rtc.next = 1;
 }
@@ -782,7 +782,7 @@ static void menelaus_pre_save(void *opaque)
 {
     MenelausState *s = opaque;
     /* Should be <= 1000 */
-    s->rtc_next_vmstate =  s->rtc.next - qemu_get_clock_ms(rtc_clock);
+    s->rtc_next_vmstate =  s->rtc.next - qemu_clock_get_ms(rtc_clock);
 }
 
 static int menelaus_post_load(void *opaque, int version_id)
@@ -843,7 +843,7 @@ static int twl92230_init(I2CSlave *i2c)
 {
     MenelausState *s = FROM_I2C_SLAVE(MenelausState, i2c);
 
-    s->rtc.hz_tm = qemu_new_timer_ms(rtc_clock, menelaus_rtc_hz, s);
+    s->rtc.hz_tm = timer_new_ms(rtc_clock, menelaus_rtc_hz, s);
     /* Three output pins plus one interrupt pin.  */
     qdev_init_gpio_out(&i2c->qdev, s->out, 4);
 
diff --git a/include/sysemu/sysemu.h b/include/sysemu/sysemu.h
index d7a77b6..b1aa059 100644
--- a/include/sysemu/sysemu.h
+++ b/include/sysemu/sysemu.h
@@ -124,7 +124,7 @@ extern int boot_menu;
 extern uint8_t *boot_splash_filedata;
 extern size_t boot_splash_filedata_size;
 extern uint8_t qemu_extra_params_fw[2];
-extern QEMUClock *rtc_clock;
+extern QEMUClockType rtc_clock;
 
 #define MAX_NODES 64
 #define MAX_CPUMASK_BITS 255
diff --git a/target-alpha/sys_helper.c b/target-alpha/sys_helper.c
index 97cf9eb..552100c 100644
--- a/target-alpha/sys_helper.c
+++ b/target-alpha/sys_helper.c
@@ -93,7 +93,7 @@ uint64_t helper_get_vmtime(void)
 
 uint64_t helper_get_walltime(void)
 {
-    return qemu_get_clock_ns(rtc_clock);
+    return qemu_clock_get_ns(rtc_clock);
 }
 
 void helper_set_alarm(CPUAlphaState *env, uint64_t expire)
diff --git a/vl.c b/vl.c
index 4c68668..99e1c98 100644
--- a/vl.c
+++ b/vl.c
@@ -196,7 +196,7 @@ NICInfo nd_table[MAX_NICS];
 int autostart;
 static int rtc_utc = 1;
 static int rtc_date_offset = -1; /* -1 means no change */
-QEMUClock *rtc_clock;
+QEMUClockType rtc_clock;
 int vga_interface_type = VGA_NONE;
 static int full_screen = 0;
 static int no_frame = 0;
@@ -805,11 +805,11 @@ static void configure_rtc(QemuOpts *opts)
     value = qemu_opt_get(opts, "clock");
     if (value) {
         if (!strcmp(value, "host")) {
-            rtc_clock = host_clock;
+            rtc_clock = QEMU_CLOCK_HOST;
         } else if (!strcmp(value, "rt")) {
-            rtc_clock = rt_clock;
+            rtc_clock = QEMU_CLOCK_REALTIME;
         } else if (!strcmp(value, "vm")) {
-            rtc_clock = vm_clock;
+            rtc_clock = QEMU_CLOCK_VIRTUAL;
         } else {
             fprintf(stderr, "qemu: invalid option value '%s'\n", value);
             exit(1);
@@ -2965,7 +2965,7 @@ int main(int argc, char **argv, char **envp)
     runstate_init();
 
     init_clocks();
-    rtc_clock = host_clock;
+    rtc_clock = QEMU_CLOCK_HOST;
 
     qemu_cache_utils_init(envp);
 
commit 7bf8fbde449600926370f744b2b3d9cc819ca74f
Author: Alex Bligh <alex at alex.org.uk>
Date:   Wed Aug 21 16:03:03 2013 +0100

    aio / timers: Remove main_loop_timerlist
    
    Now we have timerlistgroups implemented and main_loop_tlg, we
    no longer need the concept of a default timer list associated
    with each clock. Remove it and simplify initialisation of
    clocks and timer lists.
    
    Signed-off-by: Alex Bligh <alex at alex.org.uk>
    Signed-off-by: Stefan Hajnoczi <stefanha at redhat.com>

diff --git a/include/qemu/timer.h b/include/qemu/timer.h
index 35556e7..705463a 100644
--- a/include/qemu/timer.h
+++ b/include/qemu/timer.h
@@ -65,7 +65,6 @@ struct QEMUTimer {
 };
 
 extern QEMUTimerListGroup main_loop_tlg;
-extern QEMUClock *qemu_clocks[QEMU_CLOCK_MAX];
 
 /*
  * QEMUClock & QEMUClockType
@@ -79,10 +78,7 @@ extern QEMUClock *qemu_clocks[QEMU_CLOCK_MAX];
  *
  * Returns: a pointer to the QEMUClock object
  */
-static inline QEMUClock *qemu_clock_ptr(QEMUClockType type)
-{
-    return qemu_clocks[type];
-}
+QEMUClock *qemu_clock_ptr(QEMUClockType type);
 
 /**
  * qemu_clock_get_ns;
diff --git a/qemu-timer.c b/qemu-timer.c
index 14794b8..ed1763f 100644
--- a/qemu-timer.c
+++ b/qemu-timer.c
@@ -45,7 +45,6 @@
 /* timers */
 
 struct QEMUClock {
-    QEMUTimerList *main_loop_timerlist;
     QLIST_HEAD(, QEMUTimerList) timerlists;
 
     NotifierList reset_notifiers;
@@ -56,7 +55,7 @@ struct QEMUClock {
 };
 
 QEMUTimerListGroup main_loop_tlg;
-QEMUClock *qemu_clocks[QEMU_CLOCK_MAX];
+QEMUClock qemu_clocks[QEMU_CLOCK_MAX];
 
 /* A QEMUTimerList is a list of timers attached to a clock. More
  * than one QEMUTimerList can be attached to each clock, for instance
@@ -73,24 +72,30 @@ struct QEMUTimerList {
     void *notify_opaque;
 };
 
+/**
+ * qemu_clock_ptr:
+ * @type: type of clock
+ *
+ * Translate a clock type into a pointer to QEMUClock object.
+ *
+ * Returns: a pointer to the QEMUClock object
+ */
+QEMUClock *qemu_clock_ptr(QEMUClockType type)
+{
+    return &qemu_clocks[type];
+}
+
 static bool timer_expired_ns(QEMUTimer *timer_head, int64_t current_time)
 {
     return timer_head && (timer_head->expire_time <= current_time);
 }
 
-static QEMUTimerList *timerlist_new_from_clock(QEMUClock *clock,
-                                               QEMUTimerListNotifyCB *cb,
-                                               void *opaque)
+QEMUTimerList *timerlist_new(QEMUClockType type,
+                             QEMUTimerListNotifyCB *cb,
+                             void *opaque)
 {
     QEMUTimerList *timer_list;
-
-    /* Assert if we do not have a clock. If you see this
-     * assertion in means that the clocks have not been
-     * initialised before a timerlist is needed. This
-     * normally happens if an AioContext is used before
-     * init_clocks() is called within main().
-     */
-    assert(clock);
+    QEMUClock *clock = qemu_clock_ptr(type);
 
     timer_list = g_malloc0(sizeof(QEMUTimerList));
     timer_list->clock = clock;
@@ -100,36 +105,25 @@ static QEMUTimerList *timerlist_new_from_clock(QEMUClock *clock,
     return timer_list;
 }
 
-QEMUTimerList *timerlist_new(QEMUClockType type,
-                             QEMUTimerListNotifyCB *cb, void *opaque)
-{
-    return timerlist_new_from_clock(qemu_clock_ptr(type), cb, opaque);
-}
-
 void timerlist_free(QEMUTimerList *timer_list)
 {
     assert(!timerlist_has_timers(timer_list));
     if (timer_list->clock) {
         QLIST_REMOVE(timer_list, list);
-        if (timer_list->clock->main_loop_timerlist == timer_list) {
-            timer_list->clock->main_loop_timerlist = NULL;
-        }
     }
     g_free(timer_list);
 }
 
-static QEMUClock *qemu_clock_new(QEMUClockType type)
+static void qemu_clock_init(QEMUClockType type)
 {
-    QEMUClock *clock;
+    QEMUClock *clock = qemu_clock_ptr(type);
 
-    clock = g_malloc0(sizeof(QEMUClock));
     clock->type = type;
     clock->enabled = true;
     clock->last = INT64_MIN;
     QLIST_INIT(&clock->timerlists);
     notifier_list_init(&clock->reset_notifiers);
-    clock->main_loop_timerlist = timerlist_new_from_clock(clock, NULL, NULL);
-    return clock;
+    main_loop_tlg.tl[type] = timerlist_new(type, NULL, NULL);
 }
 
 bool qemu_clock_use_for_deadline(QEMUClockType type)
@@ -164,7 +158,7 @@ bool timerlist_has_timers(QEMUTimerList *timer_list)
 bool qemu_clock_has_timers(QEMUClockType type)
 {
     return timerlist_has_timers(
-        qemu_clock_ptr(type)->main_loop_timerlist);
+        main_loop_tlg.tl[type]);
 }
 
 bool timerlist_expired(QEMUTimerList *timer_list)
@@ -177,7 +171,7 @@ bool timerlist_expired(QEMUTimerList *timer_list)
 bool qemu_clock_expired(QEMUClockType type)
 {
     return timerlist_expired(
-        qemu_clock_ptr(type)->main_loop_timerlist);
+        main_loop_tlg.tl[type]);
 }
 
 /*
@@ -227,7 +221,7 @@ QEMUClockType timerlist_get_clock(QEMUTimerList *timer_list)
 
 QEMUTimerList *qemu_clock_get_main_loop_timerlist(QEMUClockType type)
 {
-    return qemu_clock_ptr(type)->main_loop_timerlist;
+    return main_loop_tlg.tl[type];
 }
 
 void timerlist_notify(QEMUTimerList *timer_list)
@@ -300,7 +294,7 @@ void timer_init(QEMUTimer *ts,
 QEMUTimer *qemu_new_timer(QEMUClock *clock, int scale,
                           QEMUTimerCB *cb, void *opaque)
 {
-    return timer_new_tl(clock->main_loop_timerlist,
+    return timer_new_tl(main_loop_tlg.tl[clock->type],
                      scale, cb, opaque);
 }
 
@@ -410,7 +404,7 @@ bool timerlist_run_timers(QEMUTimerList *timer_list)
 
 bool qemu_clock_run_timers(QEMUClockType type)
 {
-    return timerlist_run_timers(qemu_clock_ptr(type)->main_loop_timerlist);
+    return timerlist_run_timers(main_loop_tlg.tl[type]);
 }
 
 bool qemu_run_timers(QEMUClock *clock)
@@ -519,10 +513,7 @@ void init_clocks(void)
 {
     QEMUClockType type;
     for (type = 0; type < QEMU_CLOCK_MAX; type++) {
-        if (!qemu_clocks[type]) {
-            qemu_clocks[type] = qemu_clock_new(type);
-            main_loop_tlg.tl[type] = qemu_clocks[type]->main_loop_timerlist;
-        }
+        qemu_clock_init(type);
     }
 
 #ifdef CONFIG_PRCTL_PR_SET_TIMERSLACK
commit 40daca54cd94678273c81dca8c0adefa297da5ea
Author: Alex Bligh <alex at alex.org.uk>
Date:   Wed Aug 21 16:03:02 2013 +0100

    aio / timers: Rearrange timer.h & make legacy functions call non-legacy
    
    Rearrange timer.h so it is in order by function type.
    
    Make legacy functions call non-legacy functions rather than vice-versa.
    
    Convert cpus.c to use new API.
    
    Signed-off-by: Alex Bligh <alex at alex.org.uk>
    Signed-off-by: Stefan Hajnoczi <stefanha at redhat.com>

diff --git a/cpus.c b/cpus.c
index 254eb4c..b9e5685 100644
--- a/cpus.c
+++ b/cpus.c
@@ -207,7 +207,7 @@ static void icount_adjust(void)
         return;
     }
     cur_time = cpu_get_clock();
-    cur_icount = qemu_get_clock_ns(vm_clock);
+    cur_icount = qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL);
     delta = cur_icount - cur_time;
     /* FIXME: This is a very crude algorithm, somewhat prone to oscillation.  */
     if (delta > 0
@@ -228,15 +228,16 @@ static void icount_adjust(void)
 
 static void icount_adjust_rt(void *opaque)
 {
-    qemu_mod_timer(icount_rt_timer,
-                   qemu_get_clock_ms(rt_clock) + 1000);
+    timer_mod(icount_rt_timer,
+                   qemu_clock_get_ms(QEMU_CLOCK_REALTIME) + 1000);
     icount_adjust();
 }
 
 static void icount_adjust_vm(void *opaque)
 {
-    qemu_mod_timer(icount_vm_timer,
-                   qemu_get_clock_ns(vm_clock) + get_ticks_per_sec() / 10);
+    timer_mod(icount_vm_timer,
+                   qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL) +
+                   get_ticks_per_sec() / 10);
     icount_adjust();
 }
 
@@ -252,22 +253,22 @@ static void icount_warp_rt(void *opaque)
     }
 
     if (runstate_is_running()) {
-        int64_t clock = qemu_get_clock_ns(rt_clock);
+        int64_t clock = qemu_clock_get_ns(QEMU_CLOCK_REALTIME);
         int64_t warp_delta = clock - vm_clock_warp_start;
         if (use_icount == 1) {
             qemu_icount_bias += warp_delta;
         } else {
             /*
-             * In adaptive mode, do not let the vm_clock run too
+             * In adaptive mode, do not let QEMU_CLOCK_VIRTUAL run too
              * far ahead of real time.
              */
             int64_t cur_time = cpu_get_clock();
-            int64_t cur_icount = qemu_get_clock_ns(vm_clock);
+            int64_t cur_icount = qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL);
             int64_t delta = cur_time - cur_icount;
             qemu_icount_bias += MIN(warp_delta, delta);
         }
-        if (qemu_clock_expired(vm_clock)) {
-            qemu_clock_notify(vm_clock);
+        if (qemu_clock_expired(QEMU_CLOCK_VIRTUAL)) {
+            qemu_clock_notify(QEMU_CLOCK_VIRTUAL);
         }
     }
     vm_clock_warp_start = -1;
@@ -275,19 +276,19 @@ static void icount_warp_rt(void *opaque)
 
 void qtest_clock_warp(int64_t dest)
 {
-    int64_t clock = qemu_get_clock_ns(vm_clock);
+    int64_t clock = qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL);
     assert(qtest_enabled());
     while (clock < dest) {
-        int64_t deadline = qemu_clock_deadline_ns_all(vm_clock);
+        int64_t deadline = qemu_clock_deadline_ns_all(QEMU_CLOCK_VIRTUAL);
         int64_t warp = MIN(dest - clock, deadline);
         qemu_icount_bias += warp;
-        qemu_run_timers(vm_clock);
-        clock = qemu_get_clock_ns(vm_clock);
+        qemu_clock_run_timers(QEMU_CLOCK_VIRTUAL);
+        clock = qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL);
     }
-    qemu_clock_notify(vm_clock);
+    qemu_clock_notify(QEMU_CLOCK_VIRTUAL);
 }
 
-void qemu_clock_warp(QEMUClock *clock)
+void qemu_clock_warp(QEMUClockType type)
 {
     int64_t deadline;
 
@@ -296,20 +297,20 @@ void qemu_clock_warp(QEMUClock *clock)
      * applicable to other clocks.  But a clock argument removes the
      * need for if statements all over the place.
      */
-    if (clock != vm_clock || !use_icount) {
+    if (type != QEMU_CLOCK_VIRTUAL || !use_icount) {
         return;
     }
 
     /*
-     * If the CPUs have been sleeping, advance the vm_clock timer now.  This
-     * ensures that the deadline for the timer is computed correctly below.
+     * If the CPUs have been sleeping, advance QEMU_CLOCK_VIRTUAL timer now.
+     * This ensures that the deadline for the timer is computed correctly below.
      * This also makes sure that the insn counter is synchronized before the
      * CPU starts running, in case the CPU is woken by an event other than
-     * the earliest vm_clock timer.
+     * the earliest QEMU_CLOCK_VIRTUAL timer.
      */
     icount_warp_rt(NULL);
-    if (!all_cpu_threads_idle() || !qemu_clock_has_timers(vm_clock)) {
-        qemu_del_timer(icount_warp_timer);
+    if (!all_cpu_threads_idle() || !qemu_clock_has_timers(QEMU_CLOCK_VIRTUAL)) {
+        timer_del(icount_warp_timer);
         return;
     }
 
@@ -318,12 +319,12 @@ void qemu_clock_warp(QEMUClock *clock)
 	return;
     }
 
-    vm_clock_warp_start = qemu_get_clock_ns(rt_clock);
+    vm_clock_warp_start = qemu_clock_get_ns(QEMU_CLOCK_REALTIME);
     /* We want to use the earliest deadline from ALL vm_clocks */
-    deadline = qemu_clock_deadline_ns_all(vm_clock);
+    deadline = qemu_clock_deadline_ns_all(QEMU_CLOCK_VIRTUAL);
 
     /* Maintain prior (possibly buggy) behaviour where if no deadline
-     * was set (as there is no vm_clock timer) or it is more than
+     * was set (as there is no QEMU_CLOCK_VIRTUAL timer) or it is more than
      * INT32_MAX nanoseconds ahead, we still use INT32_MAX
      * nanoseconds.
      */
@@ -333,24 +334,25 @@ void qemu_clock_warp(QEMUClock *clock)
 
     if (deadline > 0) {
         /*
-         * Ensure the vm_clock proceeds even when the virtual CPU goes to
+         * Ensure QEMU_CLOCK_VIRTUAL proceeds even when the virtual CPU goes to
          * sleep.  Otherwise, the CPU might be waiting for a future timer
          * interrupt to wake it up, but the interrupt never comes because
          * the vCPU isn't running any insns and thus doesn't advance the
-         * vm_clock.
+         * QEMU_CLOCK_VIRTUAL.
          *
          * An extreme solution for this problem would be to never let VCPUs
-         * sleep in icount mode if there is a pending vm_clock timer; rather
-         * time could just advance to the next vm_clock event.  Instead, we
-         * do stop VCPUs and only advance vm_clock after some "real" time,
-         * (related to the time left until the next event) has passed.  This
-         * rt_clock timer will do this.  This avoids that the warps are too
-         * visible externally---for example, you will not be sending network
-         * packets continuously instead of every 100ms.
+         * sleep in icount mode if there is a pending QEMU_CLOCK_VIRTUAL
+         * timer; rather time could just advance to the next QEMU_CLOCK_VIRTUAL
+         * event.  Instead, we do stop VCPUs and only advance QEMU_CLOCK_VIRTUAL
+         * after some e"real" time, (related to the time left until the next
+         * event) has passed. The QEMU_CLOCK_REALTIME timer will do this.
+         * This avoids that the warps are visible externally; for example,
+         * you will not be sending network packets continuously instead of
+         * every 100ms.
          */
-        qemu_mod_timer(icount_warp_timer, vm_clock_warp_start + deadline);
+        timer_mod(icount_warp_timer, vm_clock_warp_start + deadline);
     } else if (deadline == 0) {
-        qemu_clock_notify(vm_clock);
+        qemu_clock_notify(QEMU_CLOCK_VIRTUAL);
     }
 }
 
@@ -374,7 +376,8 @@ void configure_icount(const char *option)
         return;
     }
 
-    icount_warp_timer = qemu_new_timer_ns(rt_clock, icount_warp_rt, NULL);
+    icount_warp_timer = timer_new_ns(QEMU_CLOCK_REALTIME,
+                                          icount_warp_rt, NULL);
     if (strcmp(option, "auto") != 0) {
         icount_time_shift = strtol(option, NULL, 0);
         use_icount = 1;
@@ -392,12 +395,15 @@ void configure_icount(const char *option)
        the virtual time trigger catches emulated time passing too fast.
        Realtime triggers occur even when idle, so use them less frequently
        than VM triggers.  */
-    icount_rt_timer = qemu_new_timer_ms(rt_clock, icount_adjust_rt, NULL);
-    qemu_mod_timer(icount_rt_timer,
-                   qemu_get_clock_ms(rt_clock) + 1000);
-    icount_vm_timer = qemu_new_timer_ns(vm_clock, icount_adjust_vm, NULL);
-    qemu_mod_timer(icount_vm_timer,
-                   qemu_get_clock_ns(vm_clock) + get_ticks_per_sec() / 10);
+    icount_rt_timer = timer_new_ms(QEMU_CLOCK_REALTIME,
+                                        icount_adjust_rt, NULL);
+    timer_mod(icount_rt_timer,
+                   qemu_clock_get_ms(QEMU_CLOCK_REALTIME) + 1000);
+    icount_vm_timer = timer_new_ns(QEMU_CLOCK_VIRTUAL,
+                                        icount_adjust_vm, NULL);
+    timer_mod(icount_vm_timer,
+                   qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL) +
+                   get_ticks_per_sec() / 10);
 }
 
 /***********************************************************/
@@ -746,7 +752,7 @@ static void qemu_tcg_wait_io_event(void)
     while (all_cpu_threads_idle()) {
        /* Start accounting real time to the virtual clock if the CPUs
           are idle.  */
-        qemu_clock_warp(vm_clock);
+        qemu_clock_warp(QEMU_CLOCK_VIRTUAL);
         qemu_cond_wait(tcg_halt_cond, &qemu_global_mutex);
     }
 
@@ -879,10 +885,10 @@ static void *qemu_tcg_cpu_thread_fn(void *arg)
         tcg_exec_all();
 
         if (use_icount) {
-            int64_t deadline = qemu_clock_deadline_ns_all(vm_clock);
+            int64_t deadline = qemu_clock_deadline_ns_all(QEMU_CLOCK_VIRTUAL);
 
             if (deadline == 0) {
-                qemu_clock_notify(vm_clock);
+                qemu_clock_notify(QEMU_CLOCK_VIRTUAL);
             }
         }
         qemu_tcg_wait_io_event();
@@ -1001,7 +1007,7 @@ void pause_all_vcpus(void)
 {
     CPUState *cpu = first_cpu;
 
-    qemu_clock_enable(vm_clock, false);
+    qemu_clock_enable(QEMU_CLOCK_VIRTUAL, false);
     while (cpu) {
         cpu->stop = true;
         qemu_cpu_kick(cpu);
@@ -1042,7 +1048,7 @@ void resume_all_vcpus(void)
 {
     CPUState *cpu = first_cpu;
 
-    qemu_clock_enable(vm_clock, true);
+    qemu_clock_enable(QEMU_CLOCK_VIRTUAL, true);
     while (cpu) {
         cpu_resume(cpu);
         cpu = cpu->next_cpu;
@@ -1166,10 +1172,10 @@ static int tcg_cpu_exec(CPUArchState *env)
         qemu_icount -= (env->icount_decr.u16.low + env->icount_extra);
         env->icount_decr.u16.low = 0;
         env->icount_extra = 0;
-        deadline = qemu_clock_deadline_ns_all(vm_clock);
+        deadline = qemu_clock_deadline_ns_all(QEMU_CLOCK_VIRTUAL);
 
         /* Maintain prior (possibly buggy) behaviour where if no deadline
-         * was set (as there is no vm_clock timer) or it is more than
+         * was set (as there is no QEMU_CLOCK_VIRTUAL timer) or it is more than
          * INT32_MAX nanoseconds ahead, we still use INT32_MAX
          * nanoseconds.
          */
@@ -1203,8 +1209,8 @@ static void tcg_exec_all(void)
 {
     int r;
 
-    /* Account partial waits to the vm_clock.  */
-    qemu_clock_warp(vm_clock);
+    /* Account partial waits to QEMU_CLOCK_VIRTUAL.  */
+    qemu_clock_warp(QEMU_CLOCK_VIRTUAL);
 
     if (next_cpu == NULL) {
         next_cpu = first_cpu;
@@ -1213,7 +1219,7 @@ static void tcg_exec_all(void)
         CPUState *cpu = next_cpu;
         CPUArchState *env = cpu->env_ptr;
 
-        qemu_clock_enable(vm_clock,
+        qemu_clock_enable(QEMU_CLOCK_VIRTUAL,
                           (cpu->singlestep_enabled & SSTEP_NOTIMER) == 0);
 
         if (cpu_can_run(cpu)) {
diff --git a/hw/acpi/piix4.c b/hw/acpi/piix4.c
index c885690..613d987 100644
--- a/hw/acpi/piix4.c
+++ b/hw/acpi/piix4.c
@@ -263,7 +263,7 @@ static int acpi_load_old(QEMUFile *f, void *opaque, int version_id)
         return ret;
     }
 
-    qemu_get_timer(f, s->ar.tmr.timer);
+    timer_get(f, s->ar.tmr.timer);
     qemu_get_sbe64s(f, &s->ar.tmr.overflow_time);
 
     qemu_get_be16s(f, (uint16_t *)s->ar.gpe.sts);
diff --git a/hw/input/tsc2005.c b/hw/input/tsc2005.c
index ebd1b7e..fa9714b 100644
--- a/hw/input/tsc2005.c
+++ b/hw/input/tsc2005.c
@@ -449,7 +449,7 @@ static void tsc2005_save(QEMUFile *f, void *opaque)
     qemu_put_be16s(f, &s->dav);
     qemu_put_be16s(f, &s->data);
 
-    qemu_put_timer(f, s->timer);
+    timer_put(f, s->timer);
     qemu_put_byte(f, s->enabled);
     qemu_put_byte(f, s->host_mode);
     qemu_put_byte(f, s->function);
@@ -490,7 +490,7 @@ static int tsc2005_load(QEMUFile *f, void *opaque, int version_id)
     qemu_get_be16s(f, &s->dav);
     qemu_get_be16s(f, &s->data);
 
-    qemu_get_timer(f, s->timer);
+    timer_get(f, s->timer);
     s->enabled = qemu_get_byte(f);
     s->host_mode = qemu_get_byte(f);
     s->function = qemu_get_byte(f);
diff --git a/hw/input/tsc210x.c b/hw/input/tsc210x.c
index 0067f98..96fdb84 100644
--- a/hw/input/tsc210x.c
+++ b/hw/input/tsc210x.c
@@ -1020,7 +1020,7 @@ static void tsc210x_save(QEMUFile *f, void *opaque)
     qemu_put_byte(f, s->irq);
     qemu_put_be16s(f, &s->dav);
 
-    qemu_put_timer(f, s->timer);
+    timer_put(f, s->timer);
     qemu_put_byte(f, s->enabled);
     qemu_put_byte(f, s->host_mode);
     qemu_put_byte(f, s->function);
@@ -1066,7 +1066,7 @@ static int tsc210x_load(QEMUFile *f, void *opaque, int version_id)
     s->irq = qemu_get_byte(f);
     qemu_get_be16s(f, &s->dav);
 
-    qemu_get_timer(f, s->timer);
+    timer_get(f, s->timer);
     s->enabled = qemu_get_byte(f);
     s->host_mode = qemu_get_byte(f);
     s->function = qemu_get_byte(f);
diff --git a/hw/sparc64/sun4u.c b/hw/sparc64/sun4u.c
index a7214a3..2165bb0 100644
--- a/hw/sparc64/sun4u.c
+++ b/hw/sparc64/sun4u.c
@@ -363,7 +363,7 @@ void cpu_put_timer(QEMUFile *f, CPUTimer *s)
     qemu_put_be64s(f, &s->disabled_mask);
     qemu_put_sbe64s(f, &s->clock_offset);
 
-    qemu_put_timer(f, s->qtimer);
+    timer_put(f, s->qtimer);
 }
 
 void cpu_get_timer(QEMUFile *f, CPUTimer *s)
@@ -373,7 +373,7 @@ void cpu_get_timer(QEMUFile *f, CPUTimer *s)
     qemu_get_be64s(f, &s->disabled_mask);
     qemu_get_sbe64s(f, &s->clock_offset);
 
-    qemu_get_timer(f, s->qtimer);
+    timer_get(f, s->qtimer);
 }
 
 static CPUTimer *cpu_timer_create(const char *name, SPARCCPU *cpu,
diff --git a/include/qemu/timer.h b/include/qemu/timer.h
index 5c30f91..35556e7 100644
--- a/include/qemu/timer.h
+++ b/include/qemu/timer.h
@@ -23,16 +23,12 @@
  * machine is stopped. The real time clock has a frequency of 1000
  * Hz.
  *
- * Formerly rt_clock
- *
  * @QEMU_CLOCK_VIRTUAL: virtual clock
  *
  * The virtual clock is only run during the emulation. It is stopped
  * when the virtual machine is stopped. Virtual timers use a high
  * precision clock, usually cpu cycles (use ticks_per_sec).
  *
- * Formerly vm_clock
- *
  * @QEMU_CLOCK_HOST: host clock
  *
  * The host clock should be use for device models that emulate accurate
@@ -40,8 +36,6 @@
  * is suspended, and it will reflect system time changes the host may
  * undergo (e.g. due to NTP). The host clock has the same precision as
  * the virtual clock.
- *
- * Formerly host_clock
  */
 
 typedef enum {
@@ -73,6 +67,10 @@ struct QEMUTimer {
 extern QEMUTimerListGroup main_loop_tlg;
 extern QEMUClock *qemu_clocks[QEMU_CLOCK_MAX];
 
+/*
+ * QEMUClock & QEMUClockType
+ */
+
 /**
  * qemu_clock_ptr:
  * @type: type of clock
@@ -86,23 +84,6 @@ static inline QEMUClock *qemu_clock_ptr(QEMUClockType type)
     return qemu_clocks[type];
 }
 
-/* These three clocks are maintained here with separate variable
- * names for compatibility only.
- */
-#define rt_clock (qemu_clock_ptr(QEMU_CLOCK_REALTIME))
-#define vm_clock (qemu_clock_ptr(QEMU_CLOCK_VIRTUAL))
-#define host_clock (qemu_clock_ptr(QEMU_CLOCK_HOST))
-
-/**
- * qemu_get_clock_ns:
- * @clock: the clock to operate on
- *
- * Get the nanosecond value of a clock
- *
- * Returns: the clock value in nanoseconds
- */
-int64_t qemu_get_clock_ns(QEMUClock *clock);
-
 /**
  * qemu_clock_get_ns;
  * @type: the clock type
@@ -112,10 +93,7 @@ int64_t qemu_get_clock_ns(QEMUClock *clock);
  *
  * Returns: the clock value in nanoseconds
  */
-static inline int64_t qemu_clock_get_ns(QEMUClockType type)
-{
-    return qemu_get_clock_ns(qemu_clock_ptr(type));
-}
+int64_t qemu_clock_get_ns(QEMUClockType type);
 
 /**
  * qemu_clock_get_ms;
@@ -147,7 +125,7 @@ static inline int64_t qemu_clock_get_us(QEMUClockType type)
 
 /**
  * qemu_clock_has_timers:
- * @clock: the clock to operate on
+ * @type: the clock type
  *
  * Determines whether a clock's default timer list
  * has timers attached
@@ -155,11 +133,11 @@ static inline int64_t qemu_clock_get_us(QEMUClockType type)
  * Returns: true if the clock's default timer list
  * has timers attached
  */
-bool qemu_clock_has_timers(QEMUClock *clock);
+bool qemu_clock_has_timers(QEMUClockType type);
 
 /**
  * qemu_clock_expired:
- * @clock: the clock to operate on
+ * @type: the clock type
  *
  * Determines whether a clock's default timer list
  * has an expired clock.
@@ -167,23 +145,11 @@ bool qemu_clock_has_timers(QEMUClock *clock);
  * Returns: true if the clock's default timer list has
  * an expired timer
  */
-bool qemu_clock_expired(QEMUClock *clock);
-
-/**
- * qemu_clock_deadline_ns:
- * @clock: the clock to operate on
- *
- * Calculate the timeout of the earliest expiring timer
- * on the default timer list associated with the clock
- * in nanoseconds, or -1 if no timer is set to expire.
- *
- * Returns: time until expiry in nanoseconds or -1
- */
-int64_t qemu_clock_deadline_ns(QEMUClock *clock);
+bool qemu_clock_expired(QEMUClockType type);
 
 /**
  * qemu_clock_use_for_deadline:
- * @clock: the clock to operate on
+ * @type: the clock type
  *
  * Determine whether a clock should be used for deadline
  * calculations. Some clocks, for instance vm_clock with
@@ -195,11 +161,11 @@ int64_t qemu_clock_deadline_ns(QEMUClock *clock);
  * Returns: true if the clock runs in nanoseconds and
  * should be used for a deadline.
  */
-bool qemu_clock_use_for_deadline(QEMUClock *clock);
+bool qemu_clock_use_for_deadline(QEMUClockType type);
 
 /**
- * qemu_clock_use_for_deadline:
- * @clock: the clock to operate on
+ * qemu_clock_deadline_ns_all:
+ * @type: the clock type
  *
  * Calculate the deadline across all timer lists associated
  * with a clock (as opposed to just the default one)
@@ -207,26 +173,90 @@ bool qemu_clock_use_for_deadline(QEMUClock *clock);
  *
  * Returns: time until expiry in nanoseconds or -1
  */
-int64_t qemu_clock_deadline_ns_all(QEMUClock *clock);
+int64_t qemu_clock_deadline_ns_all(QEMUClockType type);
 
 /**
  * qemu_clock_get_main_loop_timerlist:
- * @clock: the clock to operate on
+ * @type: the clock type
  *
  * Return the default timer list assocatiated with a clock.
  *
  * Returns: the default timer list
  */
-QEMUTimerList *qemu_clock_get_main_loop_timerlist(QEMUClock *clock);
+QEMUTimerList *qemu_clock_get_main_loop_timerlist(QEMUClockType type);
 
 /**
  * qemu_clock_nofify:
- * @clock: the clock to operate on
+ * @type: the clock type
  *
  * Call the notifier callback connected with the default timer
  * list linked to the clock, or qemu_notify() if none.
  */
-void qemu_clock_notify(QEMUClock *clock);
+void qemu_clock_notify(QEMUClockType type);
+
+/**
+ * qemu_clock_enable:
+ * @type: the clock type
+ * @enabled: true to enable, false to disable
+ *
+ * Enable or disable a clock
+ */
+void qemu_clock_enable(QEMUClockType type, bool enabled);
+
+/**
+ * qemu_clock_warp:
+ * @type: the clock type
+ *
+ * Warp a clock to a new value
+ */
+void qemu_clock_warp(QEMUClockType type);
+
+/**
+ * qemu_clock_register_reset_notifier:
+ * @type: the clock type
+ * @notifier: the notifier function
+ *
+ * Register a notifier function to call when the clock
+ * concerned is reset.
+ */
+void qemu_clock_register_reset_notifier(QEMUClockType type,
+                                        Notifier *notifier);
+
+/**
+ * qemu_clock_unregister_reset_notifier:
+ * @type: the clock type
+ * @notifier: the notifier function
+ *
+ * Unregister a notifier function to call when the clock
+ * concerned is reset.
+ */
+void qemu_clock_unregister_reset_notifier(QEMUClockType type,
+                                          Notifier *notifier);
+
+/**
+ * qemu_clock_run_timers:
+ * @type: clock on which to operate
+ *
+ * Run all the timers associated with the default timer list
+ * of a clock.
+ *
+ * Returns: true if any timer ran.
+ */
+bool qemu_clock_run_timers(QEMUClockType type);
+
+/**
+ * qemu_clock_run_all_timers:
+ *
+ * Run all the timers associated with the default timer list
+ * of every clock.
+ *
+ * Returns: true if any timer ran.
+ */
+bool qemu_clock_run_all_timers(void);
+
+/*
+ * QEMUTimerList
+ */
 
 /**
  * timerlist_new:
@@ -286,14 +316,15 @@ bool timerlist_expired(QEMUTimerList *timer_list);
 int64_t timerlist_deadline_ns(QEMUTimerList *timer_list);
 
 /**
- * timerlist_getclock:
+ * timerlist_get_clock:
  * @timer_list: the timer list to operate on
  *
- * Determine the clock associated with a timer list.
+ * Determine the clock type associated with a timer list.
  *
- * Returns: the clock associated with the timer list.
+ * Returns: the clock type associated with the
+ * timer list.
  */
-QEMUClock *timerlist_get_clock(QEMUTimerList *timer_list);
+QEMUClockType timerlist_get_clock(QEMUTimerList *timer_list);
 
 /**
  * timerlist_run_timers:
@@ -313,6 +344,10 @@ bool timerlist_run_timers(QEMUTimerList *timer_list);
  */
 void timerlist_notify(QEMUTimerList *timer_list);
 
+/*
+ * QEMUTimerListGroup
+ */
+
 /**
  * timerlistgroup_init:
  * @tlg: the timer list group
@@ -363,82 +398,9 @@ bool timerlistgroup_run_timers(QEMUTimerListGroup *tlg);
  */
 int64_t timerlistgroup_deadline_ns(QEMUTimerListGroup *tlg);
 
-/**
- * qemu_timeout_ns_to_ms:
- * @ns: nanosecond timeout value
- *
- * Convert a nanosecond timeout value (or -1) to
- * a millisecond value (or -1), always rounding up.
- *
- * Returns: millisecond timeout value
- */
-int qemu_timeout_ns_to_ms(int64_t ns);
-
-/**
- * qemu_poll_ns:
- * @fds: Array of file descriptors
- * @nfds: number of file descriptors
- * @timeout: timeout in nanoseconds
- *
- * Perform a poll like g_poll but with a timeout in nanoseconds.
- * See g_poll documentation for further details.
- *
- * Returns: number of fds ready
- */
-int qemu_poll_ns(GPollFD *fds, guint nfds, int64_t timeout);
-
-/**
- * qemu_clock_enable:
- * @clock: the clock to operate on
- * @enabled: true to enable, false to disable
- *
- * Enable or disable a clock
- */
-void qemu_clock_enable(QEMUClock *clock, bool enabled);
-
-/**
- * qemu_clock_warp:
- * @clock: the clock to operate on
- *
- * Warp a clock to a new value
- */
-void qemu_clock_warp(QEMUClock *clock);
-
-/**
- * qemu_register_clock_reset_notifier:
- * @clock: the clock to operate on
- * @notifier: the notifier function
- *
- * Register a notifier function to call when the clock
- * concerned is reset.
- */
-void qemu_register_clock_reset_notifier(QEMUClock *clock, Notifier *notifier);
-
-/**
- * qemu_unregister_clock_reset_notifier:
- * @clock: the clock to operate on
- * @notifier: the notifier function
- *
- * Unregister a notifier function to call when the clock
- * concerned is reset.
- */
-void qemu_unregister_clock_reset_notifier(QEMUClock *clock,
-                                          Notifier *notifier);
-
-/**
- * qemu_new_timer:
- * @clock: the clock to operate on
- * @scale: the scale of the clock
- * @cb: the callback function to call when the timer expires
- * @opaque: an opaque pointer to pass to the callback
- *
- * Produce a new timer attached to clock @clock. This is a legacy
- * function. Use timer_new instead.
- *
- * Returns: a pointer to the new timer allocated.
+/*
+ * QEMUTimer
  */
-QEMUTimer *qemu_new_timer(QEMUClock *clock, int scale,
-                          QEMUTimerCB *cb, void *opaque);
 
 /**
  * timer_init:
@@ -502,102 +464,94 @@ static inline QEMUTimer *timer_new(QEMUClockType type, int scale,
 }
 
 /**
- * qemu_free_timer:
- * @ts: the timer to operate on
- *
- * free the timer @ts. @ts must not be active.
+ * timer_new_ns:
+ * @clock: the clock to associate with the timer
+ * @callback: the callback to call when the timer expires
+ * @opaque: the opaque pointer to pass to the callback
  *
- * This is a legacy function. Use timer_free instead.
- */
-void qemu_free_timer(QEMUTimer *ts);
-
-/**
- * timer_free:
- * @ts: the timer to operate on
+ * Create a new timer with nanosecond scale on the default timer list
+ * associated with the clock.
  *
- * free the timer @ts. @ts must not be active.
+ * Returns: a pointer to the newly created timer
  */
-static inline void timer_free(QEMUTimer *ts)
+static inline QEMUTimer *timer_new_ns(QEMUClockType type, QEMUTimerCB *cb,
+                                      void *opaque)
 {
-    qemu_free_timer(ts);
+    return timer_new(type, SCALE_NS, cb, opaque);
 }
 
 /**
- * qemu_del_timer:
- * @ts: the timer to operate on
+ * timer_new_us:
+ * @clock: the clock to associate with the timer
+ * @callback: the callback to call when the timer expires
+ * @opaque: the opaque pointer to pass to the callback
  *
- * Delete a timer. This makes it inactive. It does not free
- * memory.
+ * Create a new timer with microsecond scale on the default timer list
+ * associated with the clock.
  *
- * This is a legacy function. Use timer_del instead.
+ * Returns: a pointer to the newly created timer
  */
-void qemu_del_timer(QEMUTimer *ts);
+static inline QEMUTimer *timer_new_us(QEMUClockType type, QEMUTimerCB *cb,
+                                      void *opaque)
+{
+    return timer_new(type, SCALE_US, cb, opaque);
+}
 
 /**
- * timer_del:
- * @ts: the timer to operate on
+ * timer_new_ms:
+ * @clock: the clock to associate with the timer
+ * @callback: the callback to call when the timer expires
+ * @opaque: the opaque pointer to pass to the callback
  *
- * Delete a timer. This makes it inactive. It does not free
- * memory.
+ * Create a new timer with millisecond scale on the default timer list
+ * associated with the clock.
+ *
+ * Returns: a pointer to the newly created timer
  */
-static inline void timer_del(QEMUTimer *ts)
+static inline QEMUTimer *timer_new_ms(QEMUClockType type, QEMUTimerCB *cb,
+                                      void *opaque)
 {
-    qemu_del_timer(ts);
+    return timer_new(type, SCALE_MS, cb, opaque);
 }
 
 /**
- * qemu_mod_timer_ns:
- * @ts: the timer to operate on
- * @expire_time: the expiry time in nanoseconds
- *
- * Modify a timer such that the expiry time is @expire_time
- * as measured in nanoseconds
+ * timer_free:
+ * @ts: the timer
  *
- * This is a legacy function. Use timer_mod_ns.
+ * Free a timer (it must not be on the active list)
  */
-void qemu_mod_timer_ns(QEMUTimer *ts, int64_t expire_time);
+void timer_free(QEMUTimer *ts);
 
 /**
- * timer_mod_ns:
- * @ts: the timer to operate on
- * @expire_time: the expiry time in nanoseconds
+ * timer_del:
+ * @ts: the timer
  *
- * Modify a timer such that the expiry time is @expire_time
- * as measured in nanoseconds
+ * Delete a timer from the active list.
  */
-static inline void timer_mod_ns(QEMUTimer *ts, int64_t expire_time)
-{
-    qemu_mod_timer_ns(ts, expire_time);
-}
+void timer_del(QEMUTimer *ts);
 
 /**
- * qemu_mod_timer:
- * @ts: the timer to operate on
- * @expire_time: the expiry time
- *
- * Modify a timer such that the expiry time is @expire_time
- * as measured in the timer's scale
+ * timer_mod_ns:
+ * @ts: the timer
+ * @expire_time: the expiry time in nanoseconds
  *
- * This is a legacy function. Use timer_mod.
+ * Modify a timer to expire at @expire_time
  */
-void qemu_mod_timer(QEMUTimer *ts, int64_t expire_time);
+void timer_mod_ns(QEMUTimer *ts, int64_t expire_time);
 
 /**
  * timer_mod:
- * @ts: the timer to operate on
- * @expire_time: the expiry time in nanoseconds
+ * @ts: the timer
+ * @expire_time: the expire time in the units associated with the timer
  *
- * Modify a timer such that the expiry time is @expire_time
- * as measured in the timer's scale
+ * Modify a timer to expiry at @expire_time, taking into
+ * account the scale associated with the timer.
  */
-static inline void timer_mod(QEMUTimer *ts, int64_t expire_time)
-{
-    qemu_mod_timer(ts, expire_time);
-}
+void timer_mod(QEMUTimer *ts, int64_t expire_timer);
 
 /**
  * timer_pending:
- * @ts: the timer to operate on
+ * @ts: the timer
  *
  * Determines whether a timer is pending (i.e. is on the
  * active list of timers, whether or not it has not yet expired).
@@ -608,7 +562,7 @@ bool timer_pending(QEMUTimer *ts);
 
 /**
  * timer_expired:
- * @ts: the timer to operate on
+ * @ts: the timer
  *
  * Determines whether a timer has expired.
  *
@@ -618,45 +572,57 @@ bool timer_expired(QEMUTimer *timer_head, int64_t current_time);
 
 /**
  * timer_expire_time_ns:
- * @ts: the timer to operate on
+ * @ts: the timer
  *
- * Determines the time until a timer expires
+ * Determine the expiry time of a timer
  *
- * Returns: the time (in nanoseonds) until a timer expires
+ * Returns: the expiry time in nanoseconds
  */
 uint64_t timer_expire_time_ns(QEMUTimer *ts);
 
 /**
- * qemu_run_timers:
- * @clock: clock on which to operate
- *
- * Run all the timers associated with the default timer list
- * of a clock.
+ * timer_get:
+ * @f: the file
+ * @ts: the timer
  *
- * Returns: true if any timer ran.
+ * Read a timer @ts from a file @f
  */
-bool qemu_run_timers(QEMUClock *clock);
+void timer_get(QEMUFile *f, QEMUTimer *ts);
 
 /**
- * qemu_run_all_timers:
+ * timer_put:
+ * @f: the file
+ * @ts: the timer
+ */
+void timer_put(QEMUFile *f, QEMUTimer *ts);
+
+/*
+ * General utility functions
+ */
+
+/**
+ * qemu_timeout_ns_to_ms:
+ * @ns: nanosecond timeout value
  *
- * Run all the timers associated with the default timer list
- * of every clock.
+ * Convert a nanosecond timeout value (or -1) to
+ * a millisecond value (or -1), always rounding up.
  *
- * Returns: true if any timer ran.
+ * Returns: millisecond timeout value
  */
-bool qemu_run_all_timers(void);
+int qemu_timeout_ns_to_ms(int64_t ns);
 
 /**
- * initclocks:
+ * qemu_poll_ns:
+ * @fds: Array of file descriptors
+ * @nfds: number of file descriptors
+ * @timeout: timeout in nanoseconds
  *
- * Initialise the clock & timer infrastructure
+ * Perform a poll like g_poll but with a timeout in nanoseconds.
+ * See g_poll documentation for further details.
+ *
+ * Returns: number of fds ready
  */
-void init_clocks(void);
-
-int64_t cpu_get_ticks(void);
-void cpu_enable_ticks(void);
-void cpu_disable_ticks(void);
+int qemu_poll_ns(GPollFD *fds, guint nfds, int64_t timeout);
 
 /**
  * qemu_soonest_timeout:
@@ -678,59 +644,181 @@ static inline int64_t qemu_soonest_timeout(int64_t timeout1, int64_t timeout2)
 }
 
 /**
- * qemu_new_timer_ns:
- * @clock: the clock to associate with the timer
- * @callback: the callback to call when the timer expires
- * @opaque: the opaque pointer to pass to the callback
+ * initclocks:
  *
- * Create a new timer with nanosecond scale on the default timer list
- * associated with the clock.
+ * Initialise the clock & timer infrastructure
+ */
+void init_clocks(void);
+
+int64_t cpu_get_ticks(void);
+void cpu_enable_ticks(void);
+void cpu_disable_ticks(void);
+
+static inline int64_t get_ticks_per_sec(void)
+{
+    return 1000000000LL;
+}
+
+/**************************************************
+ * LEGACY API SECTION
  *
- * Returns: a pointer to the newly created timer
+ * All these calls will be deleted in due course
  */
-static inline QEMUTimer *qemu_new_timer_ns(QEMUClock *clock, QEMUTimerCB *cb,
-                                           void *opaque)
+
+/* These three clocks are maintained here with separate variable
+ * names for compatibility only.
+ */
+#define rt_clock (qemu_clock_ptr(QEMU_CLOCK_REALTIME))
+#define vm_clock (qemu_clock_ptr(QEMU_CLOCK_VIRTUAL))
+#define host_clock (qemu_clock_ptr(QEMU_CLOCK_HOST))
+
+/** LEGACY
+ * qemu_get_clock_ns:
+ * @clock: the clock to operate on
+ *
+ * Get the nanosecond value of a clock
+ *
+ * Returns: the clock value in nanoseconds
+ */
+int64_t qemu_get_clock_ns(QEMUClock *clock);
+
+/** LEGACY
+ * qemu_get_clock_ms:
+ * @clock: the clock to operate on
+ *
+ * Get the millisecond value of a clock
+ *
+ * Returns: the clock value in milliseconds
+ */
+static inline int64_t qemu_get_clock_ms(QEMUClock *clock)
 {
-    return qemu_new_timer(clock, SCALE_NS, cb, opaque);
+    return qemu_get_clock_ns(clock) / SCALE_MS;
 }
 
-/**
- * timer_new_ns:
- * @clock: the clock to associate with the timer
- * @callback: the callback to call when the timer expires
- * @opaque: the opaque pointer to pass to the callback
+/** LEGACY
+ * qemu_register_clock_reset_notifier:
+ * @clock: the clock to operate on
+ * @notifier: the notifier function
  *
- * Create a new timer with nanosecond scale on the default timer list
- * associated with the clock.
+ * Register a notifier function to call when the clock
+ * concerned is reset.
+ */
+void qemu_register_clock_reset_notifier(QEMUClock *clock,
+                                        Notifier *notifier);
+
+/** LEGACY
+ * qemu_unregister_clock_reset_notifier:
+ * @clock: the clock to operate on
+ * @notifier: the notifier function
  *
- * Returns: a pointer to the newly created timer
+ * Unregister a notifier function to call when the clock
+ * concerned is reset.
  */
-static inline QEMUTimer *timer_new_ns(QEMUClockType type, QEMUTimerCB *cb,
-                                      void *opaque)
+void qemu_unregister_clock_reset_notifier(QEMUClock *clock,
+                                          Notifier *notifier);
+
+/** LEGACY
+ * qemu_new_timer:
+ * @clock: the clock to operate on
+ * @scale: the scale of the clock
+ * @cb: the callback function to call when the timer expires
+ * @opaque: an opaque pointer to pass to the callback
+ *
+ * Produce a new timer attached to clock @clock. This is a legacy
+ * function. Use timer_new instead.
+ *
+ * Returns: a pointer to the new timer allocated.
+ */
+QEMUTimer *qemu_new_timer(QEMUClock *clock, int scale,
+                          QEMUTimerCB *cb, void *opaque);
+
+/** LEGACY
+ * qemu_free_timer:
+ * @ts: the timer to operate on
+ *
+ * free the timer @ts. @ts must not be active.
+ *
+ * This is a legacy function. Use timer_free instead.
+ */
+static inline void qemu_free_timer(QEMUTimer *ts)
 {
-    return timer_new(type, SCALE_NS, cb, opaque);
+    timer_free(ts);
 }
 
-/**
- * qemu_new_timer_us:
+/** LEGACY
+ * qemu_del_timer:
+ * @ts: the timer to operate on
+ *
+ * Delete a timer. This makes it inactive. It does not free
+ * memory.
+ *
+ * This is a legacy function. Use timer_del instead.
+ */
+static inline void qemu_del_timer(QEMUTimer *ts)
+{
+    timer_del(ts);
+}
+
+/** LEGACY
+ * qemu_mod_timer_ns:
+ * @ts: the timer to operate on
+ * @expire_time: the expiry time in nanoseconds
+ *
+ * Modify a timer such that the expiry time is @expire_time
+ * as measured in nanoseconds
+ *
+ * This is a legacy function. Use timer_mod_ns.
+ */
+static inline void qemu_mod_timer_ns(QEMUTimer *ts, int64_t expire_time)
+{
+    timer_mod_ns(ts, expire_time);
+}
+
+/** LEGACY
+ * qemu_mod_timer:
+ * @ts: the timer to operate on
+ * @expire_time: the expiry time
+ *
+ * Modify a timer such that the expiry time is @expire_time
+ * as measured in the timer's scale
+ *
+ * This is a legacy function. Use timer_mod.
+ */
+static inline void qemu_mod_timer(QEMUTimer *ts, int64_t expire_time)
+{
+    timer_mod(ts, expire_time);
+}
+
+/** LEGACY
+ * qemu_run_timers:
+ * @clock: clock on which to operate
+ *
+ * Run all the timers associated with the default timer list
+ * of a clock.
+ *
+ * Returns: true if any timer ran.
+ */
+bool qemu_run_timers(QEMUClock *clock);
+
+/** LEGACY
+ * qemu_new_timer_ns:
  * @clock: the clock to associate with the timer
  * @callback: the callback to call when the timer expires
  * @opaque: the opaque pointer to pass to the callback
  *
- * Create a new timer with microsecond scale on the default timer list
+ * Create a new timer with nanosecond scale on the default timer list
  * associated with the clock.
  *
  * Returns: a pointer to the newly created timer
  */
-static inline QEMUTimer *qemu_new_timer_us(QEMUClock *clock,
-                                           QEMUTimerCB *cb,
+static inline QEMUTimer *qemu_new_timer_ns(QEMUClock *clock, QEMUTimerCB *cb,
                                            void *opaque)
 {
-    return qemu_new_timer(clock, SCALE_US, cb, opaque);
+    return qemu_new_timer(clock, SCALE_NS, cb, opaque);
 }
 
-/**
- * timer_new_us:
+/** LEGACY
+ * qemu_new_timer_us:
  * @clock: the clock to associate with the timer
  * @callback: the callback to call when the timer expires
  * @opaque: the opaque pointer to pass to the callback
@@ -740,13 +828,14 @@ static inline QEMUTimer *qemu_new_timer_us(QEMUClock *clock,
  *
  * Returns: a pointer to the newly created timer
  */
-static inline QEMUTimer *timer_new_us(QEMUClockType type, QEMUTimerCB *cb,
-                                      void *opaque)
+static inline QEMUTimer *qemu_new_timer_us(QEMUClock *clock,
+                                           QEMUTimerCB *cb,
+                                           void *opaque)
 {
-    return timer_new(type, SCALE_US, cb, opaque);
+    return qemu_new_timer(clock, SCALE_US, cb, opaque);
 }
 
-/**
+/** LEGACY
  * qemu_new_timer_ms:
  * @clock: the clock to associate with the timer
  * @callback: the callback to call when the timer expires
@@ -764,32 +853,14 @@ static inline QEMUTimer *qemu_new_timer_ms(QEMUClock *clock,
     return qemu_new_timer(clock, SCALE_MS, cb, opaque);
 }
 
-/**
- * timer_new_ms:
- * @clock: the clock to associate with the timer
- * @callback: the callback to call when the timer expires
- * @opaque: the opaque pointer to pass to the callback
- *
- * Create a new timer with millisecond scale on the default timer list
- * associated with the clock.
- *
- * Returns: a pointer to the newly created timer
+/****************************************************
+ * END OF LEGACY API SECTION
  */
-static inline QEMUTimer *timer_new_ms(QEMUClockType type, QEMUTimerCB *cb,
-                                      void *opaque)
-{
-    return timer_new(type, SCALE_MS, cb, opaque);
-}
 
-static inline int64_t qemu_get_clock_ms(QEMUClock *clock)
-{
-    return qemu_get_clock_ns(clock) / SCALE_MS;
-}
 
-static inline int64_t get_ticks_per_sec(void)
-{
-    return 1000000000LL;
-}
+/*
+ * Low level clock functions
+ */
 
 /* real time host monotonic timer */
 static inline int64_t get_clock_realtime(void)
@@ -834,9 +905,6 @@ static inline int64_t get_clock(void)
 }
 #endif
 
-void qemu_get_timer(QEMUFile *f, QEMUTimer *ts);
-void qemu_put_timer(QEMUFile *f, QEMUTimer *ts);
-
 /* icount */
 int64_t cpu_get_icount(void);
 int64_t cpu_get_clock(void);
diff --git a/main-loop.c b/main-loop.c
index 543a01f..1c38ea2 100644
--- a/main-loop.c
+++ b/main-loop.c
@@ -487,7 +487,7 @@ int main_loop_wait(int nonblocking)
     slirp_pollfds_poll(gpollfds, (ret < 0));
 #endif
 
-    qemu_run_all_timers();
+    qemu_clock_run_all_timers();
 
     return ret;
 }
diff --git a/qemu-timer.c b/qemu-timer.c
index b6f9304..14794b8 100644
--- a/qemu-timer.c
+++ b/qemu-timer.c
@@ -132,25 +132,27 @@ static QEMUClock *qemu_clock_new(QEMUClockType type)
     return clock;
 }
 
-bool qemu_clock_use_for_deadline(QEMUClock *clock)
+bool qemu_clock_use_for_deadline(QEMUClockType type)
 {
-    return !(use_icount && (clock->type == QEMU_CLOCK_VIRTUAL));
+    return !(use_icount && (type == QEMU_CLOCK_VIRTUAL));
 }
 
-void qemu_clock_notify(QEMUClock *clock)
+void qemu_clock_notify(QEMUClockType type)
 {
     QEMUTimerList *timer_list;
+    QEMUClock *clock = qemu_clock_ptr(type);
     QLIST_FOREACH(timer_list, &clock->timerlists, list) {
         timerlist_notify(timer_list);
     }
 }
 
-void qemu_clock_enable(QEMUClock *clock, bool enabled)
+void qemu_clock_enable(QEMUClockType type, bool enabled)
 {
+    QEMUClock *clock = qemu_clock_ptr(type);
     bool old = clock->enabled;
     clock->enabled = enabled;
     if (enabled && !old) {
-        qemu_clock_notify(clock);
+        qemu_clock_notify(type);
     }
 }
 
@@ -159,21 +161,23 @@ bool timerlist_has_timers(QEMUTimerList *timer_list)
     return !!timer_list->active_timers;
 }
 
-bool qemu_clock_has_timers(QEMUClock *clock)
+bool qemu_clock_has_timers(QEMUClockType type)
 {
-    return timerlist_has_timers(clock->main_loop_timerlist);
+    return timerlist_has_timers(
+        qemu_clock_ptr(type)->main_loop_timerlist);
 }
 
 bool timerlist_expired(QEMUTimerList *timer_list)
 {
     return (timer_list->active_timers &&
             timer_list->active_timers->expire_time <
-            qemu_get_clock_ns(timer_list->clock));
+            qemu_clock_get_ns(timer_list->clock->type));
 }
 
-bool qemu_clock_expired(QEMUClock *clock)
+bool qemu_clock_expired(QEMUClockType type)
 {
-    return timerlist_expired(clock->main_loop_timerlist);
+    return timerlist_expired(
+        qemu_clock_ptr(type)->main_loop_timerlist);
 }
 
 /*
@@ -190,7 +194,7 @@ int64_t timerlist_deadline_ns(QEMUTimerList *timer_list)
     }
 
     delta = timer_list->active_timers->expire_time -
-        qemu_get_clock_ns(timer_list->clock);
+        qemu_clock_get_ns(timer_list->clock->type);
 
     if (delta <= 0) {
         return 0;
@@ -199,20 +203,16 @@ int64_t timerlist_deadline_ns(QEMUTimerList *timer_list)
     return delta;
 }
 
-int64_t qemu_clock_deadline_ns(QEMUClock *clock)
-{
-    return timerlist_deadline_ns(clock->main_loop_timerlist);
-}
-
 /* Calculate the soonest deadline across all timerlists attached
  * to the clock. This is used for the icount timeout so we
  * ignore whether or not the clock should be used in deadline
  * calculations.
  */
-int64_t qemu_clock_deadline_ns_all(QEMUClock *clock)
+int64_t qemu_clock_deadline_ns_all(QEMUClockType type)
 {
     int64_t deadline = -1;
     QEMUTimerList *timer_list;
+    QEMUClock *clock = qemu_clock_ptr(type);
     QLIST_FOREACH(timer_list, &clock->timerlists, list) {
         deadline = qemu_soonest_timeout(deadline,
                                         timerlist_deadline_ns(timer_list));
@@ -220,14 +220,14 @@ int64_t qemu_clock_deadline_ns_all(QEMUClock *clock)
     return deadline;
 }
 
-QEMUClock *timerlist_get_clock(QEMUTimerList *timer_list)
+QEMUClockType timerlist_get_clock(QEMUTimerList *timer_list)
 {
-    return timer_list->clock;
+    return timer_list->clock->type;
 }
 
-QEMUTimerList *qemu_clock_get_main_loop_timerlist(QEMUClock *clock)
+QEMUTimerList *qemu_clock_get_main_loop_timerlist(QEMUClockType type)
 {
-    return clock->main_loop_timerlist;
+    return qemu_clock_ptr(type)->main_loop_timerlist;
 }
 
 void timerlist_notify(QEMUTimerList *timer_list)
@@ -304,13 +304,13 @@ QEMUTimer *qemu_new_timer(QEMUClock *clock, int scale,
                      scale, cb, opaque);
 }
 
-void qemu_free_timer(QEMUTimer *ts)
+void timer_free(QEMUTimer *ts)
 {
     g_free(ts);
 }
 
 /* stop a timer, but do not dealloc it */
-void qemu_del_timer(QEMUTimer *ts)
+void timer_del(QEMUTimer *ts)
 {
     QEMUTimer **pt, *t;
 
@@ -331,11 +331,11 @@ void qemu_del_timer(QEMUTimer *ts)
 
 /* modify the current timer so that it will be fired when current_time
    >= expire_time. The corresponding callback will be called. */
-void qemu_mod_timer_ns(QEMUTimer *ts, int64_t expire_time)
+void timer_mod_ns(QEMUTimer *ts, int64_t expire_time)
 {
     QEMUTimer **pt, *t;
 
-    qemu_del_timer(ts);
+    timer_del(ts);
 
     /* add the timer in the sorted list */
     /* NOTE: this code must be signal safe because
@@ -355,14 +355,14 @@ void qemu_mod_timer_ns(QEMUTimer *ts, int64_t expire_time)
     /* Rearm if necessary  */
     if (pt == &ts->timer_list->active_timers) {
         /* Interrupt execution to force deadline recalculation.  */
-        qemu_clock_warp(ts->timer_list->clock);
+        qemu_clock_warp(ts->timer_list->clock->type);
         timerlist_notify(ts->timer_list);
     }
 }
 
-void qemu_mod_timer(QEMUTimer *ts, int64_t expire_time)
+void timer_mod(QEMUTimer *ts, int64_t expire_time)
 {
-    qemu_mod_timer_ns(ts, expire_time * ts->scale);
+    timer_mod_ns(ts, expire_time * ts->scale);
 }
 
 bool timer_pending(QEMUTimer *ts)
@@ -391,7 +391,7 @@ bool timerlist_run_timers(QEMUTimerList *timer_list)
         return progress;
     }
 
-    current_time = qemu_get_clock_ns(timer_list->clock);
+    current_time = qemu_clock_get_ns(timer_list->clock->type);
     for(;;) {
         ts = timer_list->active_timers;
         if (!timer_expired_ns(ts, current_time)) {
@@ -408,9 +408,14 @@ bool timerlist_run_timers(QEMUTimerList *timer_list)
     return progress;
 }
 
+bool qemu_clock_run_timers(QEMUClockType type)
+{
+    return timerlist_run_timers(qemu_clock_ptr(type)->main_loop_timerlist);
+}
+
 bool qemu_run_timers(QEMUClock *clock)
 {
-    return timerlist_run_timers(clock->main_loop_timerlist);
+    return qemu_clock_run_timers(clock->type);
 }
 
 void timerlistgroup_init(QEMUTimerListGroup *tlg,
@@ -445,7 +450,7 @@ int64_t timerlistgroup_deadline_ns(QEMUTimerListGroup *tlg)
     int64_t deadline = -1;
     QEMUClockType type;
     for (type = 0; type < QEMU_CLOCK_MAX; type++) {
-        if (qemu_clock_use_for_deadline(tlg->tl[type]->clock)) {
+        if (qemu_clock_use_for_deadline(tlg->tl[type]->clock->type)) {
             deadline = qemu_soonest_timeout(deadline,
                                             timerlist_deadline_ns(
                                                 tlg->tl[type]));
@@ -454,11 +459,12 @@ int64_t timerlistgroup_deadline_ns(QEMUTimerListGroup *tlg)
     return deadline;
 }
 
-int64_t qemu_get_clock_ns(QEMUClock *clock)
+int64_t qemu_clock_get_ns(QEMUClockType type)
 {
     int64_t now, last;
+    QEMUClock *clock = qemu_clock_ptr(type);
 
-    switch(clock->type) {
+    switch (type) {
     case QEMU_CLOCK_REALTIME:
         return get_clock();
     default:
@@ -479,16 +485,36 @@ int64_t qemu_get_clock_ns(QEMUClock *clock)
     }
 }
 
-void qemu_register_clock_reset_notifier(QEMUClock *clock, Notifier *notifier)
+int64_t qemu_get_clock_ns(QEMUClock *clock)
 {
+    return qemu_clock_get_ns(clock->type);
+}
+
+void qemu_clock_register_reset_notifier(QEMUClockType type,
+                                        Notifier *notifier)
+{
+    QEMUClock *clock = qemu_clock_ptr(type);
     notifier_list_add(&clock->reset_notifiers, notifier);
 }
 
-void qemu_unregister_clock_reset_notifier(QEMUClock *clock, Notifier *notifier)
+void qemu_clock_unregister_reset_notifier(QEMUClockType type,
+                                          Notifier *notifier)
 {
     notifier_remove(notifier);
 }
 
+void qemu_register_clock_reset_notifier(QEMUClock *clock,
+                                        Notifier *notifier)
+{
+    qemu_clock_register_reset_notifier(clock->type, notifier);
+}
+
+void qemu_unregister_clock_reset_notifier(QEMUClock *clock,
+                                          Notifier *notifier)
+{
+    qemu_clock_unregister_reset_notifier(clock->type, notifier);
+}
+
 void init_clocks(void)
 {
     QEMUClockType type;
@@ -509,13 +535,13 @@ uint64_t timer_expire_time_ns(QEMUTimer *ts)
     return timer_pending(ts) ? ts->expire_time : -1;
 }
 
-bool qemu_run_all_timers(void)
+bool qemu_clock_run_all_timers(void)
 {
     bool progress = false;
     QEMUClockType type;
 
     for (type = 0; type < QEMU_CLOCK_MAX; type++) {
-        progress |= qemu_run_timers(qemu_clock_ptr(type));
+        progress |= qemu_clock_run_timers(type);
     }
 
     return progress;
diff --git a/qtest.c b/qtest.c
index c038e24..9c50ab0 100644
--- a/qtest.c
+++ b/qtest.c
@@ -412,7 +412,7 @@ static void qtest_process_command(CharDriverState *chr, gchar **words)
         if (words[1]) {
             ns = strtoll(words[1], NULL, 0);
         } else {
-            ns = qemu_clock_deadline_ns_all(vm_clock);
+            ns = qemu_clock_deadline_ns_all(QEMU_CLOCK_VIRTUAL);
         }
         qtest_clock_warp(qemu_get_clock_ns(vm_clock) + ns);
         qtest_send_prefix(chr);
diff --git a/savevm.c b/savevm.c
index 38c3093..cad6ba6 100644
--- a/savevm.c
+++ b/savevm.c
@@ -979,7 +979,7 @@ uint64_t qemu_get_be64(QEMUFile *f)
 
 /* timer */
 
-void qemu_put_timer(QEMUFile *f, QEMUTimer *ts)
+void timer_put(QEMUFile *f, QEMUTimer *ts)
 {
     uint64_t expire_time;
 
@@ -987,7 +987,7 @@ void qemu_put_timer(QEMUFile *f, QEMUTimer *ts)
     qemu_put_be64(f, expire_time);
 }
 
-void qemu_get_timer(QEMUFile *f, QEMUTimer *ts)
+void timer_get(QEMUFile *f, QEMUTimer *ts)
 {
     uint64_t expire_time;
 
@@ -1339,14 +1339,14 @@ const VMStateInfo vmstate_info_float64 = {
 static int get_timer(QEMUFile *f, void *pv, size_t size)
 {
     QEMUTimer *v = pv;
-    qemu_get_timer(f, v);
+    timer_get(f, v);
     return 0;
 }
 
 static void put_timer(QEMUFile *f, void *pv, size_t size)
 {
     QEMUTimer *v = pv;
-    qemu_put_timer(f, v);
+    timer_put(f, v);
 }
 
 const VMStateInfo vmstate_info_timer = {
diff --git a/stubs/clock-warp.c b/stubs/clock-warp.c
index b64c462..5565118 100644
--- a/stubs/clock-warp.c
+++ b/stubs/clock-warp.c
@@ -1,7 +1,7 @@
 #include "qemu-common.h"
 #include "qemu/timer.h"
 
-void qemu_clock_warp(QEMUClock *clock)
+void qemu_clock_warp(QEMUClockType type)
 {
 }
 
commit 55a197dab4d26e6dcd2b539320b7daf68cf8c967
Author: Alex Bligh <alex at alex.org.uk>
Date:   Wed Aug 21 16:03:01 2013 +0100

    aio / timers: Add qemu_clock_get_ms and qemu_clock_get_ms
    
    Add utility functions qemu_clock_get_ms and qemu_clock_get_us
    
    Signed-off-by: Alex Bligh <alex at alex.org.uk>
    Signed-off-by: Stefan Hajnoczi <stefanha at redhat.com>

diff --git a/include/qemu/timer.h b/include/qemu/timer.h
index 21f4810..5c30f91 100644
--- a/include/qemu/timer.h
+++ b/include/qemu/timer.h
@@ -118,6 +118,34 @@ static inline int64_t qemu_clock_get_ns(QEMUClockType type)
 }
 
 /**
+ * qemu_clock_get_ms;
+ * @type: the clock type
+ *
+ * Get the millisecond value of a clock with
+ * type @type
+ *
+ * Returns: the clock value in milliseconds
+ */
+static inline int64_t qemu_clock_get_ms(QEMUClockType type)
+{
+    return qemu_clock_get_ns(type) / SCALE_MS;
+}
+
+/**
+ * qemu_clock_get_us;
+ * @type: the clock type
+ *
+ * Get the microsecond value of a clock with
+ * type @type
+ *
+ * Returns: the clock value in microseconds
+ */
+static inline int64_t qemu_clock_get_us(QEMUClockType type)
+{
+    return qemu_clock_get_ns(type) / SCALE_US;
+}
+
+/**
  * qemu_clock_has_timers:
  * @clock: the clock to operate on
  *
commit 63111b69cce420886ba7bfb8e367bd6c6969c1b6
Author: Alex Bligh <alex at alex.org.uk>
Date:   Wed Aug 21 16:03:00 2013 +0100

    aio / timers: Remove legacy qemu_clock_deadline & qemu_timerlist_deadline
    
    Remove qemu_clock_deadline and qemu_timerlist_deadline now we are using
    the ns functions throughout.
    
    Signed-off-by: Alex Bligh <alex at alex.org.uk>
    Signed-off-by: Stefan Hajnoczi <stefanha at redhat.com>

diff --git a/include/qemu/timer.h b/include/qemu/timer.h
index d0fb7b6..21f4810 100644
--- a/include/qemu/timer.h
+++ b/include/qemu/timer.h
@@ -140,7 +140,6 @@ bool qemu_clock_has_timers(QEMUClock *clock);
  * an expired timer
  */
 bool qemu_clock_expired(QEMUClock *clock);
-int64_t qemu_clock_deadline(QEMUClock *clock);
 
 /**
  * qemu_clock_deadline_ns:
@@ -246,21 +245,6 @@ bool timerlist_has_timers(QEMUTimerList *timer_list);
 bool timerlist_expired(QEMUTimerList *timer_list);
 
 /**
- * timerlist_deadline:
- * @timer_list: the timer list to operate on
- *
- * Determine the deadline for a timer_list. This is
- * a legacy function which returns INT32_MAX if the
- * timer list has no timers or if the earliest timer
- * expires later than INT32_MAX nanoseconds away.
- *
- * Returns: the number of nanoseconds until the earliest
- * timer expires or INT32_MAX in the situations listed
- * above
- */
-int64_t timerlist_deadline(QEMUTimerList *timer_list);
-
-/**
  * timerlist_deadline_ns:
  * @timer_list: the timer list to operate on
  *
diff --git a/qemu-timer.c b/qemu-timer.c
index 8ea8211..b6f9304 100644
--- a/qemu-timer.c
+++ b/qemu-timer.c
@@ -176,26 +176,6 @@ bool qemu_clock_expired(QEMUClock *clock)
     return timerlist_expired(clock->main_loop_timerlist);
 }
 
-int64_t timerlist_deadline(QEMUTimerList *timer_list)
-{
-    /* To avoid problems with overflow limit this to 2^32.  */
-    int64_t delta = INT32_MAX;
-
-    if (timer_list->clock->enabled && timer_list->active_timers) {
-        delta = timer_list->active_timers->expire_time -
-            qemu_get_clock_ns(timer_list->clock);
-    }
-    if (delta < 0) {
-        delta = 0;
-    }
-    return delta;
-}
-
-int64_t qemu_clock_deadline(QEMUClock *clock)
-{
-    return timerlist_deadline(clock->main_loop_timerlist);
-}
-
 /*
  * As above, but return -1 for no deadline, and do not cap to 2^32
  * as we know the result is always positive.
commit 6d327171551a12b937c5718073b9848d0274c74d
Author: Alex Bligh <alex at alex.org.uk>
Date:   Wed Aug 21 16:02:59 2013 +0100

    aio / timers: Remove alarm timers
    
    Remove alarm timers from qemu-timers.c now we use g_poll / ppoll
    instead.
    
    Signed-off-by: Alex Bligh <alex at alex.org.uk>
    Signed-off-by: Stefan Hajnoczi <stefanha at redhat.com>

diff --git a/include/qemu/timer.h b/include/qemu/timer.h
index 84b35c8..d0fb7b6 100644
--- a/include/qemu/timer.h
+++ b/include/qemu/timer.h
@@ -635,9 +635,6 @@ bool qemu_run_timers(QEMUClock *clock);
  */
 bool qemu_run_all_timers(void);
 
-void configure_alarms(char const *opt);
-int init_timer_alarm(void);
-
 /**
  * initclocks:
  *
diff --git a/main-loop.c b/main-loop.c
index 2866d95..543a01f 100644
--- a/main-loop.c
+++ b/main-loop.c
@@ -131,10 +131,6 @@ int qemu_init_main_loop(void)
     GSource *src;
 
     init_clocks();
-    if (init_timer_alarm() < 0) {
-        fprintf(stderr, "could not initialize alarm timer\n");
-        exit(1);
-    }
 
     ret = qemu_signal_init();
     if (ret) {
diff --git a/qemu-timer.c b/qemu-timer.c
index b56bfde..8ea8211 100644
--- a/qemu-timer.c
+++ b/qemu-timer.c
@@ -33,10 +33,6 @@
 #include <pthread.h>
 #endif
 
-#ifdef _WIN32
-#include <mmsystem.h>
-#endif
-
 #ifdef CONFIG_PPOLL
 #include <poll.h>
 #endif
@@ -77,174 +73,11 @@ struct QEMUTimerList {
     void *notify_opaque;
 };
 
-struct qemu_alarm_timer {
-    char const *name;
-    int (*start)(struct qemu_alarm_timer *t);
-    void (*stop)(struct qemu_alarm_timer *t);
-    void (*rearm)(struct qemu_alarm_timer *t, int64_t nearest_delta_ns);
-#if defined(__linux__)
-    timer_t timer;
-    int fd;
-#elif defined(_WIN32)
-    HANDLE timer;
-#endif
-    bool expired;
-    bool pending;
-};
-
-static struct qemu_alarm_timer *alarm_timer;
-
 static bool timer_expired_ns(QEMUTimer *timer_head, int64_t current_time)
 {
     return timer_head && (timer_head->expire_time <= current_time);
 }
 
-static int64_t qemu_next_alarm_deadline(void)
-{
-    int64_t delta = INT64_MAX;
-    int64_t rtdelta;
-    int64_t hdelta;
-
-    if (!use_icount && vm_clock->enabled &&
-        vm_clock->main_loop_timerlist->active_timers) {
-        delta = vm_clock->main_loop_timerlist->active_timers->expire_time -
-            qemu_get_clock_ns(vm_clock);
-    }
-    if (host_clock->enabled &&
-        host_clock->main_loop_timerlist->active_timers) {
-        hdelta = host_clock->main_loop_timerlist->active_timers->expire_time -
-            qemu_get_clock_ns(host_clock);
-        if (hdelta < delta) {
-            delta = hdelta;
-        }
-    }
-    if (rt_clock->enabled &&
-        rt_clock->main_loop_timerlist->active_timers) {
-        rtdelta = (rt_clock->main_loop_timerlist->active_timers->expire_time -
-                   qemu_get_clock_ns(rt_clock));
-        if (rtdelta < delta) {
-            delta = rtdelta;
-        }
-    }
-
-    return delta;
-}
-
-static void qemu_rearm_alarm_timer(struct qemu_alarm_timer *t)
-{
-    int64_t nearest_delta_ns = qemu_next_alarm_deadline();
-    if (nearest_delta_ns < INT64_MAX) {
-        t->rearm(t, nearest_delta_ns);
-    }
-}
-
-/* TODO: MIN_TIMER_REARM_NS should be optimized */
-#define MIN_TIMER_REARM_NS 250000
-
-#ifdef _WIN32
-
-static int mm_start_timer(struct qemu_alarm_timer *t);
-static void mm_stop_timer(struct qemu_alarm_timer *t);
-static void mm_rearm_timer(struct qemu_alarm_timer *t, int64_t delta);
-
-static int win32_start_timer(struct qemu_alarm_timer *t);
-static void win32_stop_timer(struct qemu_alarm_timer *t);
-static void win32_rearm_timer(struct qemu_alarm_timer *t, int64_t delta);
-
-#else
-
-static int unix_start_timer(struct qemu_alarm_timer *t);
-static void unix_stop_timer(struct qemu_alarm_timer *t);
-static void unix_rearm_timer(struct qemu_alarm_timer *t, int64_t delta);
-
-#ifdef __linux__
-
-static int dynticks_start_timer(struct qemu_alarm_timer *t);
-static void dynticks_stop_timer(struct qemu_alarm_timer *t);
-static void dynticks_rearm_timer(struct qemu_alarm_timer *t, int64_t delta);
-
-#endif /* __linux__ */
-
-#endif /* _WIN32 */
-
-static struct qemu_alarm_timer alarm_timers[] = {
-#ifndef _WIN32
-#ifdef __linux__
-    {"dynticks", dynticks_start_timer,
-     dynticks_stop_timer, dynticks_rearm_timer},
-#endif
-    {"unix", unix_start_timer, unix_stop_timer, unix_rearm_timer},
-#else
-    {"mmtimer", mm_start_timer, mm_stop_timer, mm_rearm_timer},
-    {"dynticks", win32_start_timer, win32_stop_timer, win32_rearm_timer},
-#endif
-    {NULL, }
-};
-
-static void show_available_alarms(void)
-{
-    int i;
-
-    printf("Available alarm timers, in order of precedence:\n");
-    for (i = 0; alarm_timers[i].name; i++)
-        printf("%s\n", alarm_timers[i].name);
-}
-
-void configure_alarms(char const *opt)
-{
-    int i;
-    int cur = 0;
-    int count = ARRAY_SIZE(alarm_timers) - 1;
-    char *arg;
-    char *name;
-    struct qemu_alarm_timer tmp;
-
-    if (is_help_option(opt)) {
-        show_available_alarms();
-        exit(0);
-    }
-
-    arg = g_strdup(opt);
-
-    /* Reorder the array */
-    name = strtok(arg, ",");
-    while (name) {
-        for (i = 0; i < count && alarm_timers[i].name; i++) {
-            if (!strcmp(alarm_timers[i].name, name))
-                break;
-        }
-
-        if (i == count) {
-            fprintf(stderr, "Unknown clock %s\n", name);
-            goto next;
-        }
-
-        if (i < cur)
-            /* Ignore */
-            goto next;
-
-	/* Swap */
-        tmp = alarm_timers[i];
-        alarm_timers[i] = alarm_timers[cur];
-        alarm_timers[cur] = tmp;
-
-        cur++;
-next:
-        name = strtok(NULL, ",");
-    }
-
-    g_free(arg);
-
-    if (cur) {
-        /* Disable remaining timers */
-        for (i = cur; i < count; i++)
-            alarm_timers[i].name = NULL;
-    } else {
-        show_available_alarms();
-        exit(1);
-    }
-}
-
 static QEMUTimerList *timerlist_new_from_clock(QEMUClock *clock,
                                                QEMUTimerListNotifyCB *cb,
                                                void *opaque)
@@ -318,7 +151,6 @@ void qemu_clock_enable(QEMUClock *clock, bool enabled)
     clock->enabled = enabled;
     if (enabled && !old) {
         qemu_clock_notify(clock);
-        qemu_rearm_alarm_timer(alarm_timer);
     }
 }
 
@@ -542,9 +374,6 @@ void qemu_mod_timer_ns(QEMUTimer *ts, int64_t expire_time)
 
     /* Rearm if necessary  */
     if (pt == &ts->timer_list->active_timers) {
-        if (!alarm_timer->pending) {
-            qemu_rearm_alarm_timer(alarm_timer);
-        }
         /* Interrupt execution to force deadline recalculation.  */
         qemu_clock_warp(ts->timer_list->clock);
         timerlist_notify(ts->timer_list);
@@ -703,338 +532,11 @@ uint64_t timer_expire_time_ns(QEMUTimer *ts)
 bool qemu_run_all_timers(void)
 {
     bool progress = false;
-    alarm_timer->pending = false;
-
-    /* vm time timers */
     QEMUClockType type;
+
     for (type = 0; type < QEMU_CLOCK_MAX; type++) {
         progress |= qemu_run_timers(qemu_clock_ptr(type));
     }
 
-    /* rearm timer, if not periodic */
-    if (alarm_timer->expired) {
-        alarm_timer->expired = false;
-        qemu_rearm_alarm_timer(alarm_timer);
-    }
-
     return progress;
 }
-
-#ifdef _WIN32
-static void CALLBACK host_alarm_handler(PVOID lpParam, BOOLEAN unused)
-#else
-static void host_alarm_handler(int host_signum)
-#endif
-{
-    struct qemu_alarm_timer *t = alarm_timer;
-    if (!t)
-	return;
-
-    t->expired = true;
-    t->pending = true;
-    qemu_notify_event();
-}
-
-#if defined(__linux__)
-
-#include "qemu/compatfd.h"
-
-static int dynticks_start_timer(struct qemu_alarm_timer *t)
-{
-    struct sigevent ev;
-    timer_t host_timer;
-    struct sigaction act;
-
-    sigfillset(&act.sa_mask);
-    act.sa_flags = 0;
-    act.sa_handler = host_alarm_handler;
-
-    sigaction(SIGALRM, &act, NULL);
-
-    /* 
-     * Initialize ev struct to 0 to avoid valgrind complaining
-     * about uninitialized data in timer_create call
-     */
-    memset(&ev, 0, sizeof(ev));
-    ev.sigev_value.sival_int = 0;
-    ev.sigev_notify = SIGEV_SIGNAL;
-#ifdef CONFIG_SIGEV_THREAD_ID
-    if (qemu_signalfd_available()) {
-        ev.sigev_notify = SIGEV_THREAD_ID;
-        ev._sigev_un._tid = qemu_get_thread_id();
-    }
-#endif /* CONFIG_SIGEV_THREAD_ID */
-    ev.sigev_signo = SIGALRM;
-
-    if (timer_create(CLOCK_REALTIME, &ev, &host_timer)) {
-        perror("timer_create");
-        return -1;
-    }
-
-    t->timer = host_timer;
-
-    return 0;
-}
-
-static void dynticks_stop_timer(struct qemu_alarm_timer *t)
-{
-    timer_t host_timer = t->timer;
-
-    timer_delete(host_timer);
-}
-
-static void dynticks_rearm_timer(struct qemu_alarm_timer *t,
-                                 int64_t nearest_delta_ns)
-{
-    timer_t host_timer = t->timer;
-    struct itimerspec timeout;
-    int64_t current_ns;
-
-    if (nearest_delta_ns < MIN_TIMER_REARM_NS)
-        nearest_delta_ns = MIN_TIMER_REARM_NS;
-
-    /* check whether a timer is already running */
-    if (timer_gettime(host_timer, &timeout)) {
-        perror("gettime");
-        fprintf(stderr, "Internal timer error: aborting\n");
-        exit(1);
-    }
-    current_ns = timeout.it_value.tv_sec * 1000000000LL + timeout.it_value.tv_nsec;
-    if (current_ns && current_ns <= nearest_delta_ns)
-        return;
-
-    timeout.it_interval.tv_sec = 0;
-    timeout.it_interval.tv_nsec = 0; /* 0 for one-shot timer */
-    timeout.it_value.tv_sec =  nearest_delta_ns / 1000000000;
-    timeout.it_value.tv_nsec = nearest_delta_ns % 1000000000;
-    if (timer_settime(host_timer, 0 /* RELATIVE */, &timeout, NULL)) {
-        perror("settime");
-        fprintf(stderr, "Internal timer error: aborting\n");
-        exit(1);
-    }
-}
-
-#endif /* defined(__linux__) */
-
-#if !defined(_WIN32)
-
-static int unix_start_timer(struct qemu_alarm_timer *t)
-{
-    struct sigaction act;
-
-    /* timer signal */
-    sigfillset(&act.sa_mask);
-    act.sa_flags = 0;
-    act.sa_handler = host_alarm_handler;
-
-    sigaction(SIGALRM, &act, NULL);
-    return 0;
-}
-
-static void unix_rearm_timer(struct qemu_alarm_timer *t,
-                             int64_t nearest_delta_ns)
-{
-    struct itimerval itv;
-    int err;
-
-    if (nearest_delta_ns < MIN_TIMER_REARM_NS)
-        nearest_delta_ns = MIN_TIMER_REARM_NS;
-
-    itv.it_interval.tv_sec = 0;
-    itv.it_interval.tv_usec = 0; /* 0 for one-shot timer */
-    itv.it_value.tv_sec =  nearest_delta_ns / 1000000000;
-    itv.it_value.tv_usec = (nearest_delta_ns % 1000000000) / 1000;
-    err = setitimer(ITIMER_REAL, &itv, NULL);
-    if (err) {
-        perror("setitimer");
-        fprintf(stderr, "Internal timer error: aborting\n");
-        exit(1);
-    }
-}
-
-static void unix_stop_timer(struct qemu_alarm_timer *t)
-{
-    struct itimerval itv;
-
-    memset(&itv, 0, sizeof(itv));
-    setitimer(ITIMER_REAL, &itv, NULL);
-}
-
-#endif /* !defined(_WIN32) */
-
-
-#ifdef _WIN32
-
-static MMRESULT mm_timer;
-static TIMECAPS mm_tc;
-
-static void CALLBACK mm_alarm_handler(UINT uTimerID, UINT uMsg,
-                                      DWORD_PTR dwUser, DWORD_PTR dw1,
-                                      DWORD_PTR dw2)
-{
-    struct qemu_alarm_timer *t = alarm_timer;
-    if (!t) {
-        return;
-    }
-    t->expired = true;
-    t->pending = true;
-    qemu_notify_event();
-}
-
-static int mm_start_timer(struct qemu_alarm_timer *t)
-{
-    timeGetDevCaps(&mm_tc, sizeof(mm_tc));
-    return 0;
-}
-
-static void mm_stop_timer(struct qemu_alarm_timer *t)
-{
-    if (mm_timer) {
-        timeKillEvent(mm_timer);
-    }
-}
-
-static void mm_rearm_timer(struct qemu_alarm_timer *t, int64_t delta)
-{
-    int64_t nearest_delta_ms = delta / 1000000;
-    if (nearest_delta_ms < mm_tc.wPeriodMin) {
-        nearest_delta_ms = mm_tc.wPeriodMin;
-    } else if (nearest_delta_ms > mm_tc.wPeriodMax) {
-        nearest_delta_ms = mm_tc.wPeriodMax;
-    }
-
-    if (mm_timer) {
-        timeKillEvent(mm_timer);
-    }
-    mm_timer = timeSetEvent((UINT)nearest_delta_ms,
-                            mm_tc.wPeriodMin,
-                            mm_alarm_handler,
-                            (DWORD_PTR)t,
-                            TIME_ONESHOT | TIME_CALLBACK_FUNCTION);
-
-    if (!mm_timer) {
-        fprintf(stderr, "Failed to re-arm win32 alarm timer\n");
-        timeEndPeriod(mm_tc.wPeriodMin);
-        exit(1);
-    }
-}
-
-static int win32_start_timer(struct qemu_alarm_timer *t)
-{
-    HANDLE hTimer;
-    BOOLEAN success;
-
-    /* If you call ChangeTimerQueueTimer on a one-shot timer (its period
-       is zero) that has already expired, the timer is not updated.  Since
-       creating a new timer is relatively expensive, set a bogus one-hour
-       interval in the dynticks case.  */
-    success = CreateTimerQueueTimer(&hTimer,
-                          NULL,
-                          host_alarm_handler,
-                          t,
-                          1,
-                          3600000,
-                          WT_EXECUTEINTIMERTHREAD);
-
-    if (!success) {
-        fprintf(stderr, "Failed to initialize win32 alarm timer: %ld\n",
-                GetLastError());
-        return -1;
-    }
-
-    t->timer = hTimer;
-    return 0;
-}
-
-static void win32_stop_timer(struct qemu_alarm_timer *t)
-{
-    HANDLE hTimer = t->timer;
-
-    if (hTimer) {
-        DeleteTimerQueueTimer(NULL, hTimer, NULL);
-    }
-}
-
-static void win32_rearm_timer(struct qemu_alarm_timer *t,
-                              int64_t nearest_delta_ns)
-{
-    HANDLE hTimer = t->timer;
-    int64_t nearest_delta_ms;
-    BOOLEAN success;
-
-    nearest_delta_ms = nearest_delta_ns / 1000000;
-    if (nearest_delta_ms < 1) {
-        nearest_delta_ms = 1;
-    }
-    /* ULONG_MAX can be 32 bit */
-    if (nearest_delta_ms > ULONG_MAX) {
-        nearest_delta_ms = ULONG_MAX;
-    }
-    success = ChangeTimerQueueTimer(NULL,
-                                    hTimer,
-                                    (unsigned long) nearest_delta_ms,
-                                    3600000);
-
-    if (!success) {
-        fprintf(stderr, "Failed to rearm win32 alarm timer: %ld\n",
-                GetLastError());
-        exit(-1);
-    }
-
-}
-
-#endif /* _WIN32 */
-
-static void quit_timers(void)
-{
-    struct qemu_alarm_timer *t = alarm_timer;
-    alarm_timer = NULL;
-    t->stop(t);
-}
-
-#ifdef CONFIG_POSIX
-static void reinit_timers(void)
-{
-    struct qemu_alarm_timer *t = alarm_timer;
-    t->stop(t);
-    if (t->start(t)) {
-        fprintf(stderr, "Internal timer error: aborting\n");
-        exit(1);
-    }
-    qemu_rearm_alarm_timer(t);
-}
-#endif /* CONFIG_POSIX */
-
-int init_timer_alarm(void)
-{
-    struct qemu_alarm_timer *t = NULL;
-    int i, err = -1;
-
-    if (alarm_timer) {
-        return 0;
-    }
-
-    for (i = 0; alarm_timers[i].name; i++) {
-        t = &alarm_timers[i];
-
-        err = t->start(t);
-        if (!err)
-            break;
-    }
-
-    if (err) {
-        err = -ENOENT;
-        goto fail;
-    }
-
-    atexit(quit_timers);
-#ifdef CONFIG_POSIX
-    pthread_atfork(NULL, NULL, reinit_timers);
-#endif
-    alarm_timer = t;
-    return 0;
-
-fail:
-    return err;
-}
-
diff --git a/vl.c b/vl.c
index f422a1c..4c68668 100644
--- a/vl.c
+++ b/vl.c
@@ -3714,7 +3714,9 @@ int main(int argc, char **argv, char **envp)
                 old_param = 1;
                 break;
             case QEMU_OPTION_clock:
-                configure_alarms(optarg);
+                /* Clock options no longer exist.  Keep this option for
+                 * backward compatibility.
+                 */
                 break;
             case QEMU_OPTION_startdate:
                 configure_rtc_date_offset(optarg, 1);
commit 54904d2a9165bd34dee0f076826b308be2498fe0
Author: Alex Bligh <alex at alex.org.uk>
Date:   Wed Aug 21 16:02:58 2013 +0100

    aio / timers: Add documentation and new format calls
    
    Add documentation for existing qemu timer calls. Add new format
    calls of the format timer_XXX rather than qemu_XXX_timer
    for consistency.
    
    Signed-off-by: Alex Bligh <alex at alex.org.uk>
    Signed-off-by: Stefan Hajnoczi <stefanha at redhat.com>

diff --git a/include/qemu/timer.h b/include/qemu/timer.h
index 1265ad2..84b35c8 100644
--- a/include/qemu/timer.h
+++ b/include/qemu/timer.h
@@ -93,8 +93,52 @@ static inline QEMUClock *qemu_clock_ptr(QEMUClockType type)
 #define vm_clock (qemu_clock_ptr(QEMU_CLOCK_VIRTUAL))
 #define host_clock (qemu_clock_ptr(QEMU_CLOCK_HOST))
 
+/**
+ * qemu_get_clock_ns:
+ * @clock: the clock to operate on
+ *
+ * Get the nanosecond value of a clock
+ *
+ * Returns: the clock value in nanoseconds
+ */
 int64_t qemu_get_clock_ns(QEMUClock *clock);
+
+/**
+ * qemu_clock_get_ns;
+ * @type: the clock type
+ *
+ * Get the nanosecond value of a clock with
+ * type @type
+ *
+ * Returns: the clock value in nanoseconds
+ */
+static inline int64_t qemu_clock_get_ns(QEMUClockType type)
+{
+    return qemu_get_clock_ns(qemu_clock_ptr(type));
+}
+
+/**
+ * qemu_clock_has_timers:
+ * @clock: the clock to operate on
+ *
+ * Determines whether a clock's default timer list
+ * has timers attached
+ *
+ * Returns: true if the clock's default timer list
+ * has timers attached
+ */
 bool qemu_clock_has_timers(QEMUClock *clock);
+
+/**
+ * qemu_clock_expired:
+ * @clock: the clock to operate on
+ *
+ * Determines whether a clock's default timer list
+ * has an expired clock.
+ *
+ * Returns: true if the clock's default timer list has
+ * an expired timer
+ */
 bool qemu_clock_expired(QEMUClock *clock);
 int64_t qemu_clock_deadline(QEMUClock *clock);
 
@@ -294,7 +338,7 @@ void timerlistgroup_deinit(QEMUTimerListGroup *tlg);
 bool timerlistgroup_run_timers(QEMUTimerListGroup *tlg);
 
 /**
- * timerlistgroup_deadline_ns
+ * timerlistgroup_deadline_ns:
  * @tlg: the timer list group
  *
  * Determine the deadline of the soonest timer to
@@ -330,13 +374,57 @@ int qemu_timeout_ns_to_ms(int64_t ns);
  * Returns: number of fds ready
  */
 int qemu_poll_ns(GPollFD *fds, guint nfds, int64_t timeout);
+
+/**
+ * qemu_clock_enable:
+ * @clock: the clock to operate on
+ * @enabled: true to enable, false to disable
+ *
+ * Enable or disable a clock
+ */
 void qemu_clock_enable(QEMUClock *clock, bool enabled);
+
+/**
+ * qemu_clock_warp:
+ * @clock: the clock to operate on
+ *
+ * Warp a clock to a new value
+ */
 void qemu_clock_warp(QEMUClock *clock);
 
+/**
+ * qemu_register_clock_reset_notifier:
+ * @clock: the clock to operate on
+ * @notifier: the notifier function
+ *
+ * Register a notifier function to call when the clock
+ * concerned is reset.
+ */
 void qemu_register_clock_reset_notifier(QEMUClock *clock, Notifier *notifier);
+
+/**
+ * qemu_unregister_clock_reset_notifier:
+ * @clock: the clock to operate on
+ * @notifier: the notifier function
+ *
+ * Unregister a notifier function to call when the clock
+ * concerned is reset.
+ */
 void qemu_unregister_clock_reset_notifier(QEMUClock *clock,
                                           Notifier *notifier);
 
+/**
+ * qemu_new_timer:
+ * @clock: the clock to operate on
+ * @scale: the scale of the clock
+ * @cb: the callback function to call when the timer expires
+ * @opaque: an opaque pointer to pass to the callback
+ *
+ * Produce a new timer attached to clock @clock. This is a legacy
+ * function. Use timer_new instead.
+ *
+ * Returns: a pointer to the new timer allocated.
+ */
 QEMUTimer *qemu_new_timer(QEMUClock *clock, int scale,
                           QEMUTimerCB *cb, void *opaque);
 
@@ -401,21 +489,21 @@ static inline QEMUTimer *timer_new(QEMUClockType type, int scale,
     return timer_new_tl(main_loop_tlg.tl[type], scale, cb, opaque);
 }
 
+/**
+ * qemu_free_timer:
+ * @ts: the timer to operate on
+ *
+ * free the timer @ts. @ts must not be active.
+ *
+ * This is a legacy function. Use timer_free instead.
+ */
 void qemu_free_timer(QEMUTimer *ts);
-void qemu_del_timer(QEMUTimer *ts);
-void qemu_mod_timer_ns(QEMUTimer *ts, int64_t expire_time);
-void qemu_mod_timer(QEMUTimer *ts, int64_t expire_time);
-bool timer_pending(QEMUTimer *ts);
-bool timer_expired(QEMUTimer *timer_head, int64_t current_time);
-uint64_t timer_expire_time_ns(QEMUTimer *ts);
-
-/* New format calling conventions for timers */
 
 /**
  * timer_free:
- * @ts: the timer
+ * @ts: the timer to operate on
  *
- * Free a timer (it must not be on the active list)
+ * free the timer @ts. @ts must not be active.
  */
 static inline void timer_free(QEMUTimer *ts)
 {
@@ -423,10 +511,22 @@ static inline void timer_free(QEMUTimer *ts)
 }
 
 /**
+ * qemu_del_timer:
+ * @ts: the timer to operate on
+ *
+ * Delete a timer. This makes it inactive. It does not free
+ * memory.
+ *
+ * This is a legacy function. Use timer_del instead.
+ */
+void qemu_del_timer(QEMUTimer *ts);
+
+/**
  * timer_del:
- * @ts: the timer
+ * @ts: the timer to operate on
  *
- * Delete a timer from the active list.
+ * Delete a timer. This makes it inactive. It does not free
+ * memory.
  */
 static inline void timer_del(QEMUTimer *ts)
 {
@@ -434,11 +534,24 @@ static inline void timer_del(QEMUTimer *ts)
 }
 
 /**
+ * qemu_mod_timer_ns:
+ * @ts: the timer to operate on
+ * @expire_time: the expiry time in nanoseconds
+ *
+ * Modify a timer such that the expiry time is @expire_time
+ * as measured in nanoseconds
+ *
+ * This is a legacy function. Use timer_mod_ns.
+ */
+void qemu_mod_timer_ns(QEMUTimer *ts, int64_t expire_time);
+
+/**
  * timer_mod_ns:
- * @ts: the timer
+ * @ts: the timer to operate on
  * @expire_time: the expiry time in nanoseconds
  *
- * Modify a timer to expire at @expire_time
+ * Modify a timer such that the expiry time is @expire_time
+ * as measured in nanoseconds
  */
 static inline void timer_mod_ns(QEMUTimer *ts, int64_t expire_time)
 {
@@ -446,19 +559,62 @@ static inline void timer_mod_ns(QEMUTimer *ts, int64_t expire_time)
 }
 
 /**
+ * qemu_mod_timer:
+ * @ts: the timer to operate on
+ * @expire_time: the expiry time
+ *
+ * Modify a timer such that the expiry time is @expire_time
+ * as measured in the timer's scale
+ *
+ * This is a legacy function. Use timer_mod.
+ */
+void qemu_mod_timer(QEMUTimer *ts, int64_t expire_time);
+
+/**
  * timer_mod:
- * @ts: the timer
- * @expire_time: the expire time in the units associated with the timer
+ * @ts: the timer to operate on
+ * @expire_time: the expiry time in nanoseconds
  *
- * Modify a timer to expiry at @expire_time, taking into
- * account the scale associated with the timer.
+ * Modify a timer such that the expiry time is @expire_time
+ * as measured in the timer's scale
  */
-static inline void timer_mod(QEMUTimer *ts, int64_t expire_timer)
+static inline void timer_mod(QEMUTimer *ts, int64_t expire_time)
 {
-    qemu_mod_timer(ts, expire_timer);
+    qemu_mod_timer(ts, expire_time);
 }
 
 /**
+ * timer_pending:
+ * @ts: the timer to operate on
+ *
+ * Determines whether a timer is pending (i.e. is on the
+ * active list of timers, whether or not it has not yet expired).
+ *
+ * Returns: true if the timer is pending
+ */
+bool timer_pending(QEMUTimer *ts);
+
+/**
+ * timer_expired:
+ * @ts: the timer to operate on
+ *
+ * Determines whether a timer has expired.
+ *
+ * Returns: true if the timer has expired
+ */
+bool timer_expired(QEMUTimer *timer_head, int64_t current_time);
+
+/**
+ * timer_expire_time_ns:
+ * @ts: the timer to operate on
+ *
+ * Determines the time until a timer expires
+ *
+ * Returns: the time (in nanoseonds) until a timer expires
+ */
+uint64_t timer_expire_time_ns(QEMUTimer *ts);
+
+/**
  * qemu_run_timers:
  * @clock: clock on which to operate
  *
@@ -480,9 +636,15 @@ bool qemu_run_timers(QEMUClock *clock);
 bool qemu_run_all_timers(void);
 
 void configure_alarms(char const *opt);
-void init_clocks(void);
 int init_timer_alarm(void);
 
+/**
+ * initclocks:
+ *
+ * Initialise the clock & timer infrastructure
+ */
+void init_clocks(void);
+
 int64_t cpu_get_ticks(void);
 void cpu_enable_ticks(void);
 void cpu_disable_ticks(void);
commit ac70aafc28bec4d1014082f0c6659a368c5a95bd
Author: Alex Bligh <alex at alex.org.uk>
Date:   Wed Aug 21 16:02:57 2013 +0100

    aio / timers: Use all timerlists in icount warp calculations
    
    Notify all timerlists derived from vm_clock in icount warp
    calculations.
    
    When calculating timer delay based on vm_clock deadline, use
    all timerlists.
    
    For compatibility, maintain an apparent bug where when using
    icount, if no vm_clock timer was set, qemu_clock_deadline
    would return INT32_MAX and always set an icount clock expiry
    about 2 seconds ahead.
    
    NB: thread safety - when different timerlists sit on different
    threads, this will need some locking.
    
    Signed-off-by: Alex Bligh <alex at alex.org.uk>
    Signed-off-by: Stefan Hajnoczi <stefanha at redhat.com>

diff --git a/cpus.c b/cpus.c
index 70cc617..254eb4c 100644
--- a/cpus.c
+++ b/cpus.c
@@ -267,7 +267,7 @@ static void icount_warp_rt(void *opaque)
             qemu_icount_bias += MIN(warp_delta, delta);
         }
         if (qemu_clock_expired(vm_clock)) {
-            qemu_notify_event();
+            qemu_clock_notify(vm_clock);
         }
     }
     vm_clock_warp_start = -1;
@@ -278,13 +278,13 @@ void qtest_clock_warp(int64_t dest)
     int64_t clock = qemu_get_clock_ns(vm_clock);
     assert(qtest_enabled());
     while (clock < dest) {
-        int64_t deadline = qemu_clock_deadline(vm_clock);
+        int64_t deadline = qemu_clock_deadline_ns_all(vm_clock);
         int64_t warp = MIN(dest - clock, deadline);
         qemu_icount_bias += warp;
         qemu_run_timers(vm_clock);
         clock = qemu_get_clock_ns(vm_clock);
     }
-    qemu_notify_event();
+    qemu_clock_notify(vm_clock);
 }
 
 void qemu_clock_warp(QEMUClock *clock)
@@ -319,7 +319,18 @@ void qemu_clock_warp(QEMUClock *clock)
     }
 
     vm_clock_warp_start = qemu_get_clock_ns(rt_clock);
-    deadline = qemu_clock_deadline(vm_clock);
+    /* We want to use the earliest deadline from ALL vm_clocks */
+    deadline = qemu_clock_deadline_ns_all(vm_clock);
+
+    /* Maintain prior (possibly buggy) behaviour where if no deadline
+     * was set (as there is no vm_clock timer) or it is more than
+     * INT32_MAX nanoseconds ahead, we still use INT32_MAX
+     * nanoseconds.
+     */
+    if ((deadline < 0) || (deadline > INT32_MAX)) {
+        deadline = INT32_MAX;
+    }
+
     if (deadline > 0) {
         /*
          * Ensure the vm_clock proceeds even when the virtual CPU goes to
@@ -338,8 +349,8 @@ void qemu_clock_warp(QEMUClock *clock)
          * packets continuously instead of every 100ms.
          */
         qemu_mod_timer(icount_warp_timer, vm_clock_warp_start + deadline);
-    } else {
-        qemu_notify_event();
+    } else if (deadline == 0) {
+        qemu_clock_notify(vm_clock);
     }
 }
 
@@ -866,8 +877,13 @@ static void *qemu_tcg_cpu_thread_fn(void *arg)
 
     while (1) {
         tcg_exec_all();
-        if (use_icount && qemu_clock_deadline(vm_clock) <= 0) {
-            qemu_notify_event();
+
+        if (use_icount) {
+            int64_t deadline = qemu_clock_deadline_ns_all(vm_clock);
+
+            if (deadline == 0) {
+                qemu_clock_notify(vm_clock);
+            }
         }
         qemu_tcg_wait_io_event();
     }
@@ -1145,11 +1161,23 @@ static int tcg_cpu_exec(CPUArchState *env)
 #endif
     if (use_icount) {
         int64_t count;
+        int64_t deadline;
         int decr;
         qemu_icount -= (env->icount_decr.u16.low + env->icount_extra);
         env->icount_decr.u16.low = 0;
         env->icount_extra = 0;
-        count = qemu_icount_round(qemu_clock_deadline(vm_clock));
+        deadline = qemu_clock_deadline_ns_all(vm_clock);
+
+        /* Maintain prior (possibly buggy) behaviour where if no deadline
+         * was set (as there is no vm_clock timer) or it is more than
+         * INT32_MAX nanoseconds ahead, we still use INT32_MAX
+         * nanoseconds.
+         */
+        if ((deadline < 0) || (deadline > INT32_MAX)) {
+            deadline = INT32_MAX;
+        }
+
+        count = qemu_icount_round(deadline);
         qemu_icount += count;
         decr = (count > 0xffff) ? 0xffff : count;
         count -= decr;
diff --git a/include/qemu/timer.h b/include/qemu/timer.h
index 2053244..1265ad2 100644
--- a/include/qemu/timer.h
+++ b/include/qemu/timer.h
@@ -103,6 +103,7 @@ int64_t qemu_clock_deadline(QEMUClock *clock);
  * @clock: the clock to operate on
  *
  * Calculate the timeout of the earliest expiring timer
+ * on the default timer list associated with the clock
  * in nanoseconds, or -1 if no timer is set to expire.
  *
  * Returns: time until expiry in nanoseconds or -1
@@ -126,6 +127,18 @@ int64_t qemu_clock_deadline_ns(QEMUClock *clock);
 bool qemu_clock_use_for_deadline(QEMUClock *clock);
 
 /**
+ * qemu_clock_use_for_deadline:
+ * @clock: the clock to operate on
+ *
+ * Calculate the deadline across all timer lists associated
+ * with a clock (as opposed to just the default one)
+ * in nanoseconds, or -1 if no timer is set to expire.
+ *
+ * Returns: time until expiry in nanoseconds or -1
+ */
+int64_t qemu_clock_deadline_ns_all(QEMUClock *clock);
+
+/**
  * qemu_clock_get_main_loop_timerlist:
  * @clock: the clock to operate on
  *
diff --git a/qemu-timer.c b/qemu-timer.c
index 746ba8b..b56bfde 100644
--- a/qemu-timer.c
+++ b/qemu-timer.c
@@ -392,6 +392,22 @@ int64_t qemu_clock_deadline_ns(QEMUClock *clock)
     return timerlist_deadline_ns(clock->main_loop_timerlist);
 }
 
+/* Calculate the soonest deadline across all timerlists attached
+ * to the clock. This is used for the icount timeout so we
+ * ignore whether or not the clock should be used in deadline
+ * calculations.
+ */
+int64_t qemu_clock_deadline_ns_all(QEMUClock *clock)
+{
+    int64_t deadline = -1;
+    QEMUTimerList *timer_list;
+    QLIST_FOREACH(timer_list, &clock->timerlists, list) {
+        deadline = qemu_soonest_timeout(deadline,
+                                        timerlist_deadline_ns(timer_list));
+    }
+    return deadline;
+}
+
 QEMUClock *timerlist_get_clock(QEMUTimerList *timer_list)
 {
     return timer_list->clock;
diff --git a/qtest.c b/qtest.c
index 74f1842..c038e24 100644
--- a/qtest.c
+++ b/qtest.c
@@ -412,7 +412,7 @@ static void qtest_process_command(CharDriverState *chr, gchar **words)
         if (words[1]) {
             ns = strtoll(words[1], NULL, 0);
         } else {
-            ns = qemu_clock_deadline(vm_clock);
+            ns = qemu_clock_deadline_ns_all(vm_clock);
         }
         qtest_clock_warp(qemu_get_clock_ns(vm_clock) + ns);
         qtest_send_prefix(chr);
commit a3a726ae09cdf6d277ac88cd725cf50d5849db2c
Author: Alex Bligh <alex at alex.org.uk>
Date:   Wed Aug 21 16:02:56 2013 +0100

    aio / timers: Introduce new API timer_new and friends
    
    Introduce new API for creating timers - timer_new and
    _ns, _ms, _us derivatives.
    
    Signed-off-by: Alex Bligh <alex at alex.org.uk>
    Signed-off-by: Stefan Hajnoczi <stefanha at redhat.com>

diff --git a/include/qemu/timer.h b/include/qemu/timer.h
index 3fa9fa7..2053244 100644
--- a/include/qemu/timer.h
+++ b/include/qemu/timer.h
@@ -370,6 +370,24 @@ static inline QEMUTimer *timer_new_tl(QEMUTimerList *timer_list,
     return ts;
 }
 
+/**
+ * timer_new:
+ * @type: the clock type to use
+ * @scale: the scale value for the tiemr
+ * @cb: the callback to be called when the timer expires
+ * @opaque: the opaque pointer to be passed to the callback
+ *
+ * Creeate a new timer and associate it with the default
+ * timer list for the clock type @type.
+ *
+ * Returns: a pointer to the timer
+ */
+static inline QEMUTimer *timer_new(QEMUClockType type, int scale,
+                                   QEMUTimerCB *cb, void *opaque)
+{
+    return timer_new_tl(main_loop_tlg.tl[type], scale, cb, opaque);
+}
+
 void qemu_free_timer(QEMUTimer *ts);
 void qemu_del_timer(QEMUTimer *ts);
 void qemu_mod_timer_ns(QEMUTimer *ts, int64_t expire_time);
@@ -493,6 +511,23 @@ static inline QEMUTimer *qemu_new_timer_ns(QEMUClock *clock, QEMUTimerCB *cb,
 }
 
 /**
+ * timer_new_ns:
+ * @clock: the clock to associate with the timer
+ * @callback: the callback to call when the timer expires
+ * @opaque: the opaque pointer to pass to the callback
+ *
+ * Create a new timer with nanosecond scale on the default timer list
+ * associated with the clock.
+ *
+ * Returns: a pointer to the newly created timer
+ */
+static inline QEMUTimer *timer_new_ns(QEMUClockType type, QEMUTimerCB *cb,
+                                      void *opaque)
+{
+    return timer_new(type, SCALE_NS, cb, opaque);
+}
+
+/**
  * qemu_new_timer_us:
  * @clock: the clock to associate with the timer
  * @callback: the callback to call when the timer expires
@@ -511,6 +546,23 @@ static inline QEMUTimer *qemu_new_timer_us(QEMUClock *clock,
 }
 
 /**
+ * timer_new_us:
+ * @clock: the clock to associate with the timer
+ * @callback: the callback to call when the timer expires
+ * @opaque: the opaque pointer to pass to the callback
+ *
+ * Create a new timer with microsecond scale on the default timer list
+ * associated with the clock.
+ *
+ * Returns: a pointer to the newly created timer
+ */
+static inline QEMUTimer *timer_new_us(QEMUClockType type, QEMUTimerCB *cb,
+                                      void *opaque)
+{
+    return timer_new(type, SCALE_US, cb, opaque);
+}
+
+/**
  * qemu_new_timer_ms:
  * @clock: the clock to associate with the timer
  * @callback: the callback to call when the timer expires
@@ -528,6 +580,23 @@ static inline QEMUTimer *qemu_new_timer_ms(QEMUClock *clock,
     return qemu_new_timer(clock, SCALE_MS, cb, opaque);
 }
 
+/**
+ * timer_new_ms:
+ * @clock: the clock to associate with the timer
+ * @callback: the callback to call when the timer expires
+ * @opaque: the opaque pointer to pass to the callback
+ *
+ * Create a new timer with millisecond scale on the default timer list
+ * associated with the clock.
+ *
+ * Returns: a pointer to the newly created timer
+ */
+static inline QEMUTimer *timer_new_ms(QEMUClockType type, QEMUTimerCB *cb,
+                                      void *opaque)
+{
+    return timer_new(type, SCALE_MS, cb, opaque);
+}
+
 static inline int64_t qemu_get_clock_ms(QEMUClock *clock)
 {
     return qemu_get_clock_ns(clock) / SCALE_MS;
commit b1bbfe72ec1ebf302d97f886cc646466c0abd679
Author: Alex Bligh <alex at alex.org.uk>
Date:   Wed Aug 21 16:02:55 2013 +0100

    aio / timers: On timer modification, qemu_notify or aio_notify
    
    On qemu_mod_timer_ns, ensure qemu_notify or aio_notify is called to
    end the appropriate poll(), irrespective of use_icount value.
    
    On qemu_clock_enable, ensure qemu_notify or aio_notify is called for
    all QEMUTimerLists attached to the QEMUClock.
    
    Signed-off-by: Alex Bligh <alex at alex.org.uk>
    Signed-off-by: Stefan Hajnoczi <stefanha at redhat.com>

diff --git a/include/qemu/timer.h b/include/qemu/timer.h
index cb7321c..3fa9fa7 100644
--- a/include/qemu/timer.h
+++ b/include/qemu/timer.h
@@ -136,6 +136,15 @@ bool qemu_clock_use_for_deadline(QEMUClock *clock);
 QEMUTimerList *qemu_clock_get_main_loop_timerlist(QEMUClock *clock);
 
 /**
+ * qemu_clock_nofify:
+ * @clock: the clock to operate on
+ *
+ * Call the notifier callback connected with the default timer
+ * list linked to the clock, or qemu_notify() if none.
+ */
+void qemu_clock_notify(QEMUClock *clock);
+
+/**
  * timerlist_new:
  * @type: the clock type to associate with the timerlist
  * @cb: the callback to call on notification
diff --git a/qemu-timer.c b/qemu-timer.c
index ffdc28a..746ba8b 100644
--- a/qemu-timer.c
+++ b/qemu-timer.c
@@ -304,11 +304,20 @@ bool qemu_clock_use_for_deadline(QEMUClock *clock)
     return !(use_icount && (clock->type == QEMU_CLOCK_VIRTUAL));
 }
 
+void qemu_clock_notify(QEMUClock *clock)
+{
+    QEMUTimerList *timer_list;
+    QLIST_FOREACH(timer_list, &clock->timerlists, list) {
+        timerlist_notify(timer_list);
+    }
+}
+
 void qemu_clock_enable(QEMUClock *clock, bool enabled)
 {
     bool old = clock->enabled;
     clock->enabled = enabled;
     if (enabled && !old) {
+        qemu_clock_notify(clock);
         qemu_rearm_alarm_timer(alarm_timer);
     }
 }
@@ -522,9 +531,7 @@ void qemu_mod_timer_ns(QEMUTimer *ts, int64_t expire_time)
         }
         /* Interrupt execution to force deadline recalculation.  */
         qemu_clock_warp(ts->timer_list->clock);
-        if (use_icount) {
-            timerlist_notify(ts->timer_list);
-        }
+        timerlist_notify(ts->timer_list);
     }
 }
 
commit 7b595f35d89d73bc69c35bf3980a89c420e8a44b
Author: Alex Bligh <alex at alex.org.uk>
Date:   Wed Aug 21 16:02:54 2013 +0100

    aio / timers: Convert mainloop to use timeout
    
    Convert mainloop to use timeout from default timerlist group
    (i.e. the current 3 static timers)
    
    main-loop.c produces a (possibly spurious) warning about
    multiple iterations. Adapt the way this works for a signed
    timeout and make the warning a bit safer.
    
    Signed-off-by: Alex Bligh <alex at alex.org.uk>
    Signed-off-by: Stefan Hajnoczi <stefanha at redhat.com>

diff --git a/main-loop.c b/main-loop.c
index 2d9774e..2866d95 100644
--- a/main-loop.c
+++ b/main-loop.c
@@ -155,10 +155,11 @@ static int max_priority;
 static int glib_pollfds_idx;
 static int glib_n_poll_fds;
 
-static void glib_pollfds_fill(uint32_t *cur_timeout)
+static void glib_pollfds_fill(int64_t *cur_timeout)
 {
     GMainContext *context = g_main_context_default();
     int timeout = 0;
+    int64_t timeout_ns;
     int n;
 
     g_main_context_prepare(context, &max_priority);
@@ -174,9 +175,13 @@ static void glib_pollfds_fill(uint32_t *cur_timeout)
                                  glib_n_poll_fds);
     } while (n != glib_n_poll_fds);
 
-    if (timeout >= 0 && timeout < *cur_timeout) {
-        *cur_timeout = timeout;
+    if (timeout < 0) {
+        timeout_ns = -1;
+    } else {
+        timeout_ns = (int64_t)timeout * (int64_t)SCALE_MS;
     }
+
+    *cur_timeout = qemu_soonest_timeout(timeout_ns, *cur_timeout);
 }
 
 static void glib_pollfds_poll(void)
@@ -191,7 +196,7 @@ static void glib_pollfds_poll(void)
 
 #define MAX_MAIN_LOOP_SPIN (1000)
 
-static int os_host_main_loop_wait(uint32_t timeout)
+static int os_host_main_loop_wait(int64_t timeout)
 {
     int ret;
     static int spin_counter;
@@ -204,7 +209,7 @@ static int os_host_main_loop_wait(uint32_t timeout)
      * print a message to the screen.  If we run into this condition, create
      * a fake timeout in order to give the VCPU threads a chance to run.
      */
-    if (spin_counter > MAX_MAIN_LOOP_SPIN) {
+    if (!timeout && (spin_counter > MAX_MAIN_LOOP_SPIN)) {
         static bool notified;
 
         if (!notified) {
@@ -214,19 +219,19 @@ static int os_host_main_loop_wait(uint32_t timeout)
             notified = true;
         }
 
-        timeout = 1;
+        timeout = SCALE_MS;
     }
 
-    if (timeout > 0) {
+    if (timeout) {
         spin_counter = 0;
         qemu_mutex_unlock_iothread();
     } else {
         spin_counter++;
     }
 
-    ret = g_poll((GPollFD *)gpollfds->data, gpollfds->len, timeout);
+    ret = qemu_poll_ns((GPollFD *)gpollfds->data, gpollfds->len, timeout);
 
-    if (timeout > 0) {
+    if (timeout) {
         qemu_mutex_lock_iothread();
     }
 
@@ -373,7 +378,7 @@ static void pollfds_poll(GArray *pollfds, int nfds, fd_set *rfds,
     }
 }
 
-static int os_host_main_loop_wait(uint32_t timeout)
+static int os_host_main_loop_wait(int64_t timeout)
 {
     GMainContext *context = g_main_context_default();
     GPollFD poll_fds[1024 * 2]; /* this is probably overkill */
@@ -382,6 +387,7 @@ static int os_host_main_loop_wait(uint32_t timeout)
     PollingEntry *pe;
     WaitObjects *w = &wait_objects;
     gint poll_timeout;
+    int64_t poll_timeout_ns;
     static struct timeval tv0;
     fd_set rfds, wfds, xfds;
     int nfds;
@@ -419,12 +425,17 @@ static int os_host_main_loop_wait(uint32_t timeout)
         poll_fds[n_poll_fds + i].events = G_IO_IN;
     }
 
-    if (poll_timeout < 0 || timeout < poll_timeout) {
-        poll_timeout = timeout;
+    if (poll_timeout < 0) {
+        poll_timeout_ns = -1;
+    } else {
+        poll_timeout_ns = (int64_t)poll_timeout * (int64_t)SCALE_MS;
     }
 
+    poll_timeout_ns = qemu_soonest_timeout(poll_timeout_ns, timeout);
+
     qemu_mutex_unlock_iothread();
-    g_poll_ret = g_poll(poll_fds, n_poll_fds + w->num, poll_timeout);
+    g_poll_ret = qemu_poll_ns(poll_fds, n_poll_fds + w->num, poll_timeout_ns);
+
     qemu_mutex_lock_iothread();
     if (g_poll_ret > 0) {
         for (i = 0; i < w->num; i++) {
@@ -449,6 +460,7 @@ int main_loop_wait(int nonblocking)
 {
     int ret;
     uint32_t timeout = UINT32_MAX;
+    int64_t timeout_ns;
 
     if (nonblocking) {
         timeout = 0;
@@ -462,7 +474,18 @@ int main_loop_wait(int nonblocking)
     slirp_pollfds_fill(gpollfds);
 #endif
     qemu_iohandler_fill(gpollfds);
-    ret = os_host_main_loop_wait(timeout);
+
+    if (timeout == UINT32_MAX) {
+        timeout_ns = -1;
+    } else {
+        timeout_ns = (uint64_t)timeout * (int64_t)(SCALE_MS);
+    }
+
+    timeout_ns = qemu_soonest_timeout(timeout_ns,
+                                      timerlistgroup_deadline_ns(
+                                          &main_loop_tlg));
+
+    ret = os_host_main_loop_wait(timeout_ns);
     qemu_iohandler_poll(gpollfds, ret);
 #ifdef CONFIG_SLIRP
     slirp_pollfds_poll(gpollfds, (ret < 0));
commit 438e1f47e7db042a10458f70aaa6197aff5d84df
Author: Alex Bligh <alex at alex.org.uk>
Date:   Wed Aug 21 16:02:53 2013 +0100

    aio / timers: Convert aio_poll to use AioContext timers' deadline
    
    Convert aio_poll to use deadline based on AioContext's timers.
    
    aio_poll has been changed to return accurately whether progress
    has occurred. Prior to this commit, aio_poll always returned
    true if g_poll was entered, whether or not any progress was
    made. This required a change to tests/test-aio.c where an
    assert was backwards.
    
    Signed-off-by: Alex Bligh <alex at alex.org.uk>
    Signed-off-by: Stefan Hajnoczi <stefanha at redhat.com>

diff --git a/aio-posix.c b/aio-posix.c
index 2440eb9..bd06f33 100644
--- a/aio-posix.c
+++ b/aio-posix.c
@@ -165,6 +165,10 @@ static bool aio_dispatch(AioContext *ctx)
             g_free(tmp);
         }
     }
+
+    /* Run our timers */
+    progress |= timerlistgroup_run_timers(&ctx->tlg);
+
     return progress;
 }
 
@@ -219,9 +223,9 @@ bool aio_poll(AioContext *ctx, bool blocking)
     }
 
     /* wait until next event */
-    ret = g_poll((GPollFD *)ctx->pollfds->data,
-                 ctx->pollfds->len,
-                 blocking ? -1 : 0);
+    ret = qemu_poll_ns((GPollFD *)ctx->pollfds->data,
+                         ctx->pollfds->len,
+                         blocking ? timerlistgroup_deadline_ns(&ctx->tlg) : 0);
 
     /* if we have any readable fds, dispatch event */
     if (ret > 0) {
@@ -232,9 +236,11 @@ bool aio_poll(AioContext *ctx, bool blocking)
                 node->pfd.revents = pfd->revents;
             }
         }
-        if (aio_dispatch(ctx)) {
-            progress = true;
-        }
+    }
+
+    /* Run dispatch even if there were no readable fds to run timers */
+    if (aio_dispatch(ctx)) {
+        progress = true;
     }
 
     return progress;
diff --git a/aio-win32.c b/aio-win32.c
index 78b2801..721fc25 100644
--- a/aio-win32.c
+++ b/aio-win32.c
@@ -95,6 +95,7 @@ bool aio_poll(AioContext *ctx, bool blocking)
     HANDLE events[MAXIMUM_WAIT_OBJECTS + 1];
     bool progress;
     int count;
+    int timeout;
 
     progress = false;
 
@@ -108,6 +109,9 @@ bool aio_poll(AioContext *ctx, bool blocking)
         progress = true;
     }
 
+    /* Run timers */
+    progress |= timerlistgroup_run_timers(&ctx->tlg);
+
     /*
      * Then dispatch any pending callbacks from the GSource.
      *
@@ -164,8 +168,11 @@ bool aio_poll(AioContext *ctx, bool blocking)
 
     /* wait until next event */
     while (count > 0) {
-        int timeout = blocking ? INFINITE : 0;
-        int ret = WaitForMultipleObjects(count, events, FALSE, timeout);
+        int ret;
+
+        timeout = blocking ?
+            qemu_timeout_ns_to_ms(timerlistgroup_deadline_ns(&ctx->tlg)) : 0;
+        ret = WaitForMultipleObjects(count, events, FALSE, timeout);
 
         /* if we have any signaled events, dispatch event */
         if ((DWORD) (ret - WAIT_OBJECT_0) >= count) {
@@ -208,5 +215,14 @@ bool aio_poll(AioContext *ctx, bool blocking)
         events[ret - WAIT_OBJECT_0] = events[--count];
     }
 
+    if (blocking) {
+        /* Run the timers a second time. We do this because otherwise aio_wait
+         * will not note progress - and will stop a drain early - if we have
+         * a timer that was not ready to run entering g_poll but is ready
+         * after g_poll. This will only do anything if a timer has expired.
+         */
+        progress |= timerlistgroup_run_timers(&ctx->tlg);
+    }
+
     return progress;
 }
commit 4e29e8311a53025a06433382768b82111c0bb80c
Author: Alex Bligh <alex at alex.org.uk>
Date:   Wed Aug 21 16:02:52 2013 +0100

    aio / timers: Add aio_timer_init & aio_timer_new wrappers
    
    Add aio_timer_init and aio_timer_new wrapper functions.
    
    Signed-off-by: Alex Bligh <alex at alex.org.uk>
    Signed-off-by: Stefan Hajnoczi <stefanha at redhat.com>

diff --git a/include/block/aio.h b/include/block/aio.h
index 06f3aad..2efdf41 100644
--- a/include/block/aio.h
+++ b/include/block/aio.h
@@ -246,4 +246,47 @@ void qemu_aio_set_fd_handler(int fd,
                              void *opaque);
 #endif
 
+/**
+ * aio_timer_new:
+ * @ctx: the aio context
+ * @type: the clock type
+ * @scale: the scale
+ * @cb: the callback to call on timer expiry
+ * @opaque: the opaque pointer to pass to the callback
+ *
+ * Allocate a new timer attached to the context @ctx.
+ * The function is responsible for memory allocation.
+ *
+ * The preferred interface is aio_timer_init. Use that
+ * unless you really need dynamic memory allocation.
+ *
+ * Returns: a pointer to the new timer
+ */
+static inline QEMUTimer *aio_timer_new(AioContext *ctx, QEMUClockType type,
+                                       int scale,
+                                       QEMUTimerCB *cb, void *opaque)
+{
+    return timer_new_tl(ctx->tlg.tl[type], scale, cb, opaque);
+}
+
+/**
+ * aio_timer_init:
+ * @ctx: the aio context
+ * @ts: the timer
+ * @type: the clock type
+ * @scale: the scale
+ * @cb: the callback to call on timer expiry
+ * @opaque: the opaque pointer to pass to the callback
+ *
+ * Initialise a new timer attached to the context @ctx.
+ * The caller is responsible for memory allocation.
+ */
+static inline void aio_timer_init(AioContext *ctx,
+                                  QEMUTimer *ts, QEMUClockType type,
+                                  int scale,
+                                  QEMUTimerCB *cb, void *opaque)
+{
+    timer_init(ts, ctx->tlg.tl[type], scale, cb, opaque);
+}
+
 #endif
commit 533a8cf3506172fe1966abc6875c65494378321e
Author: Alex Bligh <alex at alex.org.uk>
Date:   Wed Aug 21 16:02:51 2013 +0100

    aio / timers: aio_ctx_prepare sets timeout from AioContext timers
    
    Calculate the timeout in aio_ctx_prepare taking into account
    the timers attached to the AioContext.
    
    Alter aio_ctx_check similarly.
    
    Signed-off-by: Alex Bligh <alex at alex.org.uk>
    Signed-off-by: Stefan Hajnoczi <stefanha at redhat.com>

diff --git a/async.c b/async.c
index cff0ab9..5fb3fa6 100644
--- a/async.c
+++ b/async.c
@@ -150,7 +150,10 @@ aio_ctx_prepare(GSource *source, gint    *timeout)
 {
     AioContext *ctx = (AioContext *) source;
     QEMUBH *bh;
+    int deadline;
 
+    /* We assume there is no timeout already supplied */
+    *timeout = -1;
     for (bh = ctx->first_bh; bh; bh = bh->next) {
         if (!bh->deleted && bh->scheduled) {
             if (bh->idle) {
@@ -166,6 +169,14 @@ aio_ctx_prepare(GSource *source, gint    *timeout)
         }
     }
 
+    deadline = qemu_timeout_ns_to_ms(timerlistgroup_deadline_ns(&ctx->tlg));
+    if (deadline == 0) {
+        *timeout = 0;
+        return true;
+    } else {
+        *timeout = qemu_soonest_timeout(*timeout, deadline);
+    }
+
     return false;
 }
 
@@ -180,7 +191,7 @@ aio_ctx_check(GSource *source)
             return true;
 	}
     }
-    return aio_pending(ctx);
+    return aio_pending(ctx) || (timerlistgroup_deadline_ns(&ctx->tlg) == 0);
 }
 
 static gboolean
commit d5541d86806acc2e1a3cf9e1402370ba884e9fe1
Author: Alex Bligh <alex at alex.org.uk>
Date:   Wed Aug 21 16:02:50 2013 +0100

    aio / timers: Add a notify callback to QEMUTimerList
    
    Add a notify pointer to QEMUTimerList so it knows what to notify
    on a timer change.
    
    Signed-off-by: Alex Bligh <alex at alex.org.uk>
    Signed-off-by: Stefan Hajnoczi <stefanha at redhat.com>

diff --git a/async.c b/async.c
index cd4a489..cff0ab9 100644
--- a/async.c
+++ b/async.c
@@ -234,6 +234,11 @@ void aio_notify(AioContext *ctx)
     event_notifier_set(&ctx->notifier);
 }
 
+static void aio_timerlist_notify(void *opaque)
+{
+    aio_notify(opaque);
+}
+
 AioContext *aio_context_new(void)
 {
     AioContext *ctx;
@@ -245,7 +250,7 @@ AioContext *aio_context_new(void)
     aio_set_event_notifier(ctx, &ctx->notifier, 
                            (EventNotifierHandler *)
                            event_notifier_test_and_clear);
-    timerlistgroup_init(&ctx->tlg);
+    timerlistgroup_init(&ctx->tlg, aio_timerlist_notify, ctx);
 
     return ctx;
 }
diff --git a/include/qemu/timer.h b/include/qemu/timer.h
index 6f1ec76..cb7321c 100644
--- a/include/qemu/timer.h
+++ b/include/qemu/timer.h
@@ -59,6 +59,7 @@ struct QEMUTimerListGroup {
 };
 
 typedef void QEMUTimerCB(void *opaque);
+typedef void QEMUTimerListNotifyCB(void *opaque);
 
 struct QEMUTimer {
     int64_t expire_time;        /* in nanoseconds */
@@ -137,13 +138,16 @@ QEMUTimerList *qemu_clock_get_main_loop_timerlist(QEMUClock *clock);
 /**
  * timerlist_new:
  * @type: the clock type to associate with the timerlist
+ * @cb: the callback to call on notification
+ * @opaque: the opaque pointer to pass to the callback
  *
  * Create a new timerlist associated with the clock of
  * type @type.
  *
  * Returns: a pointer to the QEMUTimerList created
  */
-QEMUTimerList *timerlist_new(QEMUClockType type);
+QEMUTimerList *timerlist_new(QEMUClockType type,
+                             QEMUTimerListNotifyCB *cb, void *opaque);
 
 /**
  * timerlist_free:
@@ -224,13 +228,28 @@ QEMUClock *timerlist_get_clock(QEMUTimerList *timer_list);
 bool timerlist_run_timers(QEMUTimerList *timer_list);
 
 /**
+ * timerlist_notify:
+ * @timer_list: the timer list to use
+ *
+ * call the notifier callback associated with the timer list.
+ */
+void timerlist_notify(QEMUTimerList *timer_list);
+
+/**
  * timerlistgroup_init:
  * @tlg: the timer list group
+ * @cb: the callback to call when a notify is required
+ * @opaque: the opaque pointer to be passed to the callback.
  *
  * Initialise a timer list group. This must already be
- * allocated in memory and zeroed.
- */
-void timerlistgroup_init(QEMUTimerListGroup *tlg);
+ * allocated in memory and zeroed. The notifier callback is
+ * called whenever a clock in the timer list group is
+ * reenabled or whenever a timer associated with any timer
+ * list is modified. If @cb is specified as null, qemu_notify()
+ * is used instead.
+ */
+void timerlistgroup_init(QEMUTimerListGroup *tlg,
+                         QEMUTimerListNotifyCB *cb, void *opaque);
 
 /**
  * timerlistgroup_deinit:
diff --git a/qemu-timer.c b/qemu-timer.c
index c5e456e..ffdc28a 100644
--- a/qemu-timer.c
+++ b/qemu-timer.c
@@ -73,6 +73,8 @@ struct QEMUTimerList {
     QEMUClock *clock;
     QEMUTimer *active_timers;
     QLIST_ENTRY(QEMUTimerList) list;
+    QEMUTimerListNotifyCB *notify_cb;
+    void *notify_opaque;
 };
 
 struct qemu_alarm_timer {
@@ -243,7 +245,9 @@ next:
     }
 }
 
-static QEMUTimerList *timerlist_new_from_clock(QEMUClock *clock)
+static QEMUTimerList *timerlist_new_from_clock(QEMUClock *clock,
+                                               QEMUTimerListNotifyCB *cb,
+                                               void *opaque)
 {
     QEMUTimerList *timer_list;
 
@@ -257,13 +261,16 @@ static QEMUTimerList *timerlist_new_from_clock(QEMUClock *clock)
 
     timer_list = g_malloc0(sizeof(QEMUTimerList));
     timer_list->clock = clock;
+    timer_list->notify_cb = cb;
+    timer_list->notify_opaque = opaque;
     QLIST_INSERT_HEAD(&clock->timerlists, timer_list, list);
     return timer_list;
 }
 
-QEMUTimerList *timerlist_new(QEMUClockType type)
+QEMUTimerList *timerlist_new(QEMUClockType type,
+                             QEMUTimerListNotifyCB *cb, void *opaque)
 {
-    return timerlist_new_from_clock(qemu_clock_ptr(type));
+    return timerlist_new_from_clock(qemu_clock_ptr(type), cb, opaque);
 }
 
 void timerlist_free(QEMUTimerList *timer_list)
@@ -288,7 +295,7 @@ static QEMUClock *qemu_clock_new(QEMUClockType type)
     clock->last = INT64_MIN;
     QLIST_INIT(&clock->timerlists);
     notifier_list_init(&clock->reset_notifiers);
-    clock->main_loop_timerlist = timerlist_new_from_clock(clock);
+    clock->main_loop_timerlist = timerlist_new_from_clock(clock, NULL, NULL);
     return clock;
 }
 
@@ -386,6 +393,15 @@ QEMUTimerList *qemu_clock_get_main_loop_timerlist(QEMUClock *clock)
     return clock->main_loop_timerlist;
 }
 
+void timerlist_notify(QEMUTimerList *timer_list)
+{
+    if (timer_list->notify_cb) {
+        timer_list->notify_cb(timer_list->notify_opaque);
+    } else {
+        qemu_notify_event();
+    }
+}
+
 /* Transition function to convert a nanosecond timeout to ms
  * This is used where a system does not support ppoll
  */
@@ -507,7 +523,7 @@ void qemu_mod_timer_ns(QEMUTimer *ts, int64_t expire_time)
         /* Interrupt execution to force deadline recalculation.  */
         qemu_clock_warp(ts->timer_list->clock);
         if (use_icount) {
-            qemu_notify_event();
+            timerlist_notify(ts->timer_list);
         }
     }
 }
@@ -565,11 +581,12 @@ bool qemu_run_timers(QEMUClock *clock)
     return timerlist_run_timers(clock->main_loop_timerlist);
 }
 
-void timerlistgroup_init(QEMUTimerListGroup *tlg)
+void timerlistgroup_init(QEMUTimerListGroup *tlg,
+                         QEMUTimerListNotifyCB *cb, void *opaque)
 {
     QEMUClockType type;
     for (type = 0; type < QEMU_CLOCK_MAX; type++) {
-        tlg->tl[type] = timerlist_new(type);
+        tlg->tl[type] = timerlist_new(type, cb, opaque);
     }
 }
 
commit dae21b98b973e8d878a92b44f70a51aa8d4c739b
Author: Alex Bligh <alex at alex.org.uk>
Date:   Wed Aug 21 16:02:49 2013 +0100

    aio / timers: Add QEMUTimerListGroup to AioContext
    
    Add a QEMUTimerListGroup each AioContext (meaning a QEMUTimerList
    associated with each clock is added) and delete it when the
    AioContext is freed.
    
    Signed-off-by: Alex Bligh <alex at alex.org.uk>
    Signed-off-by: Stefan Hajnoczi <stefanha at redhat.com>

diff --git a/async.c b/async.c
index 9791d8e..cd4a489 100644
--- a/async.c
+++ b/async.c
@@ -205,6 +205,7 @@ aio_ctx_finalize(GSource     *source)
     event_notifier_cleanup(&ctx->notifier);
     qemu_mutex_destroy(&ctx->bh_lock);
     g_array_free(ctx->pollfds, TRUE);
+    timerlistgroup_deinit(&ctx->tlg);
 }
 
 static GSourceFuncs aio_source_funcs = {
@@ -244,6 +245,7 @@ AioContext *aio_context_new(void)
     aio_set_event_notifier(ctx, &ctx->notifier, 
                            (EventNotifierHandler *)
                            event_notifier_test_and_clear);
+    timerlistgroup_init(&ctx->tlg);
 
     return ctx;
 }
diff --git a/include/block/aio.h b/include/block/aio.h
index 1e3ed1c..06f3aad 100644
--- a/include/block/aio.h
+++ b/include/block/aio.h
@@ -19,6 +19,7 @@
 #include "qemu/queue.h"
 #include "qemu/event_notifier.h"
 #include "qemu/thread.h"
+#include "qemu/timer.h"
 
 typedef struct BlockDriverAIOCB BlockDriverAIOCB;
 typedef void BlockDriverCompletionFunc(void *opaque, int ret);
@@ -73,6 +74,9 @@ struct AioContext {
 
     /* Thread pool for performing work and receiving completion callbacks */
     struct ThreadPool *thread_pool;
+
+    /* TimerLists for calling timers - one per clock type */
+    QEMUTimerListGroup tlg;
 };
 
 /**
diff --git a/tests/test-aio.c b/tests/test-aio.c
index 1ab5637..e1f394b 100644
--- a/tests/test-aio.c
+++ b/tests/test-aio.c
@@ -12,6 +12,7 @@
 
 #include <glib.h>
 #include "block/aio.h"
+#include "qemu/timer.h"
 
 AioContext *ctx;
 
@@ -630,6 +631,8 @@ int main(int argc, char **argv)
 {
     GSource *src;
 
+    init_clocks();
+
     ctx = aio_context_new();
     src = aio_get_g_source(ctx);
     g_source_attach(src, NULL);
diff --git a/tests/test-thread-pool.c b/tests/test-thread-pool.c
index 8188d1a..c1f8e13 100644
--- a/tests/test-thread-pool.c
+++ b/tests/test-thread-pool.c
@@ -3,6 +3,7 @@
 #include "block/aio.h"
 #include "block/thread-pool.h"
 #include "block/block.h"
+#include "qemu/timer.h"
 
 static AioContext *ctx;
 static ThreadPool *pool;
@@ -205,6 +206,8 @@ int main(int argc, char **argv)
 {
     int ret;
 
+    init_clocks();
+
     ctx = aio_context_new();
     pool = aio_get_thread_pool(ctx);
 
commit 754d6a544d044bddeef87e9a63b4f511f59f3c4e
Author: Alex Bligh <alex at alex.org.uk>
Date:   Wed Aug 21 16:02:48 2013 +0100

    aio / timers: Add QEMUTimerListGroup and helper functions
    
    Add QEMUTimerListGroup and helper functions, to represent
    a QEMUTimerList associated with each clock. Add a default
    QEMUTimerListGroup representing the default timer lists
    which are not associated with any other object (e.g.
    an AioContext as added by future patches).
    
    Signed-off-by: Alex Bligh <alex at alex.org.uk>
    Signed-off-by: Stefan Hajnoczi <stefanha at redhat.com>

diff --git a/include/qemu/timer.h b/include/qemu/timer.h
index d4b643f..6f1ec76 100644
--- a/include/qemu/timer.h
+++ b/include/qemu/timer.h
@@ -53,6 +53,11 @@ typedef enum {
 
 typedef struct QEMUClock QEMUClock;
 typedef struct QEMUTimerList QEMUTimerList;
+
+struct QEMUTimerListGroup {
+    QEMUTimerList *tl[QEMU_CLOCK_MAX];
+};
+
 typedef void QEMUTimerCB(void *opaque);
 
 struct QEMUTimer {
@@ -64,6 +69,7 @@ struct QEMUTimer {
     int scale;
 };
 
+extern QEMUTimerListGroup main_loop_tlg;
 extern QEMUClock *qemu_clocks[QEMU_CLOCK_MAX];
 
 /**
@@ -218,6 +224,49 @@ QEMUClock *timerlist_get_clock(QEMUTimerList *timer_list);
 bool timerlist_run_timers(QEMUTimerList *timer_list);
 
 /**
+ * timerlistgroup_init:
+ * @tlg: the timer list group
+ *
+ * Initialise a timer list group. This must already be
+ * allocated in memory and zeroed.
+ */
+void timerlistgroup_init(QEMUTimerListGroup *tlg);
+
+/**
+ * timerlistgroup_deinit:
+ * @tlg: the timer list group
+ *
+ * Deinitialise a timer list group. This must already be
+ * initialised. Note the memory is not freed.
+ */
+void timerlistgroup_deinit(QEMUTimerListGroup *tlg);
+
+/**
+ * timerlistgroup_run_timers:
+ * @tlg: the timer list group
+ *
+ * Run the timers associated with a timer list group.
+ * This will run timers on multiple clocks.
+ *
+ * Returns: true if any timer callback ran
+ */
+bool timerlistgroup_run_timers(QEMUTimerListGroup *tlg);
+
+/**
+ * timerlistgroup_deadline_ns
+ * @tlg: the timer list group
+ *
+ * Determine the deadline of the soonest timer to
+ * expire associated with any timer list linked to
+ * the timer list group. Only clocks suitable for
+ * deadline calculation are included.
+ *
+ * Returns: the deadline in nanoseconds or -1 if no
+ * timers are to expire.
+ */
+int64_t timerlistgroup_deadline_ns(QEMUTimerListGroup *tlg);
+
+/**
  * qemu_timeout_ns_to_ms:
  * @ns: nanosecond timeout value
  *
diff --git a/include/qemu/typedefs.h b/include/qemu/typedefs.h
index cae94ff..3205540 100644
--- a/include/qemu/typedefs.h
+++ b/include/qemu/typedefs.h
@@ -4,6 +4,7 @@
 /* A load of opaque types so that device init declarations don't have to
    pull in all the real definitions.  */
 typedef struct QEMUTimer QEMUTimer;
+typedef struct QEMUTimerListGroup QEMUTimerListGroup;
 typedef struct QEMUFile QEMUFile;
 typedef struct QEMUBH QEMUBH;
 
diff --git a/qemu-timer.c b/qemu-timer.c
index b045184..c5e456e 100644
--- a/qemu-timer.c
+++ b/qemu-timer.c
@@ -59,6 +59,7 @@ struct QEMUClock {
     bool enabled;
 };
 
+QEMUTimerListGroup main_loop_tlg;
 QEMUClock *qemu_clocks[QEMU_CLOCK_MAX];
 
 /* A QEMUTimerList is a list of timers attached to a clock. More
@@ -564,6 +565,46 @@ bool qemu_run_timers(QEMUClock *clock)
     return timerlist_run_timers(clock->main_loop_timerlist);
 }
 
+void timerlistgroup_init(QEMUTimerListGroup *tlg)
+{
+    QEMUClockType type;
+    for (type = 0; type < QEMU_CLOCK_MAX; type++) {
+        tlg->tl[type] = timerlist_new(type);
+    }
+}
+
+void timerlistgroup_deinit(QEMUTimerListGroup *tlg)
+{
+    QEMUClockType type;
+    for (type = 0; type < QEMU_CLOCK_MAX; type++) {
+        timerlist_free(tlg->tl[type]);
+    }
+}
+
+bool timerlistgroup_run_timers(QEMUTimerListGroup *tlg)
+{
+    QEMUClockType type;
+    bool progress = false;
+    for (type = 0; type < QEMU_CLOCK_MAX; type++) {
+        progress |= timerlist_run_timers(tlg->tl[type]);
+    }
+    return progress;
+}
+
+int64_t timerlistgroup_deadline_ns(QEMUTimerListGroup *tlg)
+{
+    int64_t deadline = -1;
+    QEMUClockType type;
+    for (type = 0; type < QEMU_CLOCK_MAX; type++) {
+        if (qemu_clock_use_for_deadline(tlg->tl[type]->clock)) {
+            deadline = qemu_soonest_timeout(deadline,
+                                            timerlist_deadline_ns(
+                                                tlg->tl[type]));
+        }
+    }
+    return deadline;
+}
+
 int64_t qemu_get_clock_ns(QEMUClock *clock)
 {
     int64_t now, last;
@@ -605,6 +646,7 @@ void init_clocks(void)
     for (type = 0; type < QEMU_CLOCK_MAX; type++) {
         if (!qemu_clocks[type]) {
             qemu_clocks[type] = qemu_clock_new(type);
+            main_loop_tlg.tl[type] = qemu_clocks[type]->main_loop_timerlist;
         }
     }
 
commit 6a1751b7aad6e38e9d1ae6bcea72fa28bf6cc5fb
Author: Alex Bligh <alex at alex.org.uk>
Date:   Wed Aug 21 16:02:47 2013 +0100

    aio / timers: Untangle include files
    
    include/qemu/timer.h has no need to include main-loop.h and
    doing so causes an issue for the next patch. Unfortunately
    various files assume including timers.h will pull in main-loop.h.
    Untangle this mess.
    
    Signed-off-by: Alex Bligh <alex at alex.org.uk>
    Signed-off-by: Stefan Hajnoczi <stefanha at redhat.com>

diff --git a/dma-helpers.c b/dma-helpers.c
index 499550f..c9620a5 100644
--- a/dma-helpers.c
+++ b/dma-helpers.c
@@ -11,6 +11,7 @@
 #include "trace.h"
 #include "qemu/range.h"
 #include "qemu/thread.h"
+#include "qemu/main-loop.h"
 
 /* #define DEBUG_IOMMU */
 
diff --git a/hw/dma/xilinx_axidma.c b/hw/dma/xilinx_axidma.c
index a48e3ba..59e8e35 100644
--- a/hw/dma/xilinx_axidma.c
+++ b/hw/dma/xilinx_axidma.c
@@ -27,6 +27,7 @@
 #include "hw/ptimer.h"
 #include "qemu/log.h"
 #include "qapi/qmp/qerror.h"
+#include "qemu/main-loop.h"
 
 #include "hw/stream.h"
 
diff --git a/hw/timer/arm_timer.c b/hw/timer/arm_timer.c
index acfea59..a47afde 100644
--- a/hw/timer/arm_timer.c
+++ b/hw/timer/arm_timer.c
@@ -12,6 +12,7 @@
 #include "qemu-common.h"
 #include "hw/qdev.h"
 #include "hw/ptimer.h"
+#include "qemu/main-loop.h"
 
 /* Common timer implementation.  */
 
diff --git a/hw/timer/exynos4210_mct.c b/hw/timer/exynos4210_mct.c
index a8009a4..13b1889 100644
--- a/hw/timer/exynos4210_mct.c
+++ b/hw/timer/exynos4210_mct.c
@@ -54,6 +54,7 @@
 
 #include "hw/sysbus.h"
 #include "qemu/timer.h"
+#include "qemu/main-loop.h"
 #include "qemu-common.h"
 #include "hw/ptimer.h"
 
diff --git a/hw/timer/exynos4210_pwm.c b/hw/timer/exynos4210_pwm.c
index a52f0f6..1aa8f4d 100644
--- a/hw/timer/exynos4210_pwm.c
+++ b/hw/timer/exynos4210_pwm.c
@@ -23,6 +23,7 @@
 #include "hw/sysbus.h"
 #include "qemu/timer.h"
 #include "qemu-common.h"
+#include "qemu/main-loop.h"
 #include "hw/ptimer.h"
 
 #include "hw/arm/exynos4210.h"
diff --git a/hw/timer/grlib_gptimer.c b/hw/timer/grlib_gptimer.c
index 7c1055a..74c16d6 100644
--- a/hw/timer/grlib_gptimer.c
+++ b/hw/timer/grlib_gptimer.c
@@ -25,6 +25,8 @@
 #include "hw/sysbus.h"
 #include "qemu/timer.h"
 #include "hw/ptimer.h"
+#include "qemu/timer.h"
+#include "qemu/main-loop.h"
 
 #include "trace.h"
 
diff --git a/hw/timer/imx_epit.c b/hw/timer/imx_epit.c
index dc73d65..0dbe15c 100644
--- a/hw/timer/imx_epit.c
+++ b/hw/timer/imx_epit.c
@@ -18,6 +18,7 @@
 #include "hw/ptimer.h"
 #include "hw/sysbus.h"
 #include "hw/arm/imx.h"
+#include "qemu/main-loop.h"
 
 #define TYPE_IMX_EPIT "imx.epit"
 
diff --git a/hw/timer/imx_gpt.c b/hw/timer/imx_gpt.c
index 87db0e1..f2d1975 100644
--- a/hw/timer/imx_gpt.c
+++ b/hw/timer/imx_gpt.c
@@ -18,6 +18,7 @@
 #include "hw/ptimer.h"
 #include "hw/sysbus.h"
 #include "hw/arm/imx.h"
+#include "qemu/main-loop.h"
 
 #define TYPE_IMX_GPT "imx.gpt"
 
diff --git a/hw/timer/lm32_timer.c b/hw/timer/lm32_timer.c
index 986e6a1..8ed138c 100644
--- a/hw/timer/lm32_timer.c
+++ b/hw/timer/lm32_timer.c
@@ -27,6 +27,7 @@
 #include "qemu/timer.h"
 #include "hw/ptimer.h"
 #include "qemu/error-report.h"
+#include "qemu/main-loop.h"
 
 #define DEFAULT_FREQUENCY (50*1000000)
 
diff --git a/hw/timer/puv3_ost.c b/hw/timer/puv3_ost.c
index 4bd2b76..fa9eefd 100644
--- a/hw/timer/puv3_ost.c
+++ b/hw/timer/puv3_ost.c
@@ -10,6 +10,7 @@
  */
 #include "hw/sysbus.h"
 #include "hw/ptimer.h"
+#include "qemu/main-loop.h"
 
 #undef DEBUG_PUV3
 #include "hw/unicore32/puv3.h"
diff --git a/hw/timer/sh_timer.c b/hw/timer/sh_timer.c
index 251a10d..07f0670 100644
--- a/hw/timer/sh_timer.c
+++ b/hw/timer/sh_timer.c
@@ -11,6 +11,7 @@
 #include "hw/hw.h"
 #include "hw/sh4/sh.h"
 #include "qemu/timer.h"
+#include "qemu/main-loop.h"
 #include "exec/address-spaces.h"
 #include "hw/ptimer.h"
 
diff --git a/hw/timer/slavio_timer.c b/hw/timer/slavio_timer.c
index 33e8f6c..f75b914 100644
--- a/hw/timer/slavio_timer.c
+++ b/hw/timer/slavio_timer.c
@@ -27,6 +27,7 @@
 #include "hw/ptimer.h"
 #include "hw/sysbus.h"
 #include "trace.h"
+#include "qemu/main-loop.h"
 
 /*
  * Registers of hardware timer in sun4m.
diff --git a/hw/timer/xilinx_timer.c b/hw/timer/xilinx_timer.c
index 5f2c902..6113b97 100644
--- a/hw/timer/xilinx_timer.c
+++ b/hw/timer/xilinx_timer.c
@@ -25,6 +25,7 @@
 #include "hw/sysbus.h"
 #include "hw/ptimer.h"
 #include "qemu/log.h"
+#include "qemu/main-loop.h"
 
 #define D(x)
 
diff --git a/hw/tpm/tpm_tis.c b/hw/tpm/tpm_tis.c
index abe384b..6f0a4d2 100644
--- a/hw/tpm/tpm_tis.c
+++ b/hw/tpm/tpm_tis.c
@@ -28,6 +28,7 @@
 #include "hw/pci/pci_ids.h"
 #include "tpm_tis.h"
 #include "qemu-common.h"
+#include "qemu/main-loop.h"
 
 /*#define DEBUG_TIS */
 
diff --git a/hw/usb/hcd-uhci.c b/hw/usb/hcd-uhci.c
index ac82833..ec51883 100644
--- a/hw/usb/hcd-uhci.c
+++ b/hw/usb/hcd-uhci.c
@@ -32,6 +32,7 @@
 #include "qemu/iov.h"
 #include "sysemu/dma.h"
 #include "trace.h"
+#include "qemu/main-loop.h"
 
 //#define DEBUG
 //#define DEBUG_DUMP_DATA
diff --git a/include/block/aio.h b/include/block/aio.h
index 5743bf1..1e3ed1c 100644
--- a/include/block/aio.h
+++ b/include/block/aio.h
@@ -14,6 +14,7 @@
 #ifndef QEMU_AIO_H
 #define QEMU_AIO_H
 
+#include "qemu/typedefs.h"
 #include "qemu-common.h"
 #include "qemu/queue.h"
 #include "qemu/event_notifier.h"
@@ -42,7 +43,7 @@ typedef struct AioHandler AioHandler;
 typedef void QEMUBHFunc(void *opaque);
 typedef void IOHandler(void *opaque);
 
-typedef struct AioContext {
+struct AioContext {
     GSource source;
 
     /* The list of registered AIO handlers */
@@ -72,7 +73,7 @@ typedef struct AioContext {
 
     /* Thread pool for performing work and receiving completion callbacks */
     struct ThreadPool *thread_pool;
-} AioContext;
+};
 
 /**
  * aio_context_new: Allocate a new AioContext.
diff --git a/include/block/block_int.h b/include/block/block_int.h
index 74b0689..8012e25 100644
--- a/include/block/block_int.h
+++ b/include/block/block_int.h
@@ -34,6 +34,7 @@
 #include "monitor/monitor.h"
 #include "qemu/hbitmap.h"
 #include "block/snapshot.h"
+#include "qemu/main-loop.h"
 
 #define BLOCK_FLAG_ENCRYPT          1
 #define BLOCK_FLAG_COMPAT6          4
diff --git a/include/block/coroutine.h b/include/block/coroutine.h
index 1f2db3e..17f5851 100644
--- a/include/block/coroutine.h
+++ b/include/block/coroutine.h
@@ -16,6 +16,7 @@
 #define QEMU_COROUTINE_H
 
 #include <stdbool.h>
+#include "qemu/typedefs.h"
 #include "qemu/queue.h"
 #include "qemu/timer.h"
 
diff --git a/include/qemu/timer.h b/include/qemu/timer.h
index b4a7ba0..d4b643f 100644
--- a/include/qemu/timer.h
+++ b/include/qemu/timer.h
@@ -3,7 +3,6 @@
 
 #include "qemu/typedefs.h"
 #include "qemu-common.h"
-#include "qemu/main-loop.h"
 #include "qemu/notify.h"
 
 /* timers */
diff --git a/include/qemu/typedefs.h b/include/qemu/typedefs.h
index ac9f8d4..cae94ff 100644
--- a/include/qemu/typedefs.h
+++ b/include/qemu/typedefs.h
@@ -7,6 +7,8 @@ typedef struct QEMUTimer QEMUTimer;
 typedef struct QEMUFile QEMUFile;
 typedef struct QEMUBH QEMUBH;
 
+typedef struct AioContext AioContext;
+
 struct Monitor;
 typedef struct Monitor Monitor;
 typedef struct MigrationParams MigrationParams;
diff --git a/migration-exec.c b/migration-exec.c
index deab4e3..4790247 100644
--- a/migration-exec.c
+++ b/migration-exec.c
@@ -17,6 +17,7 @@
 
 #include "qemu-common.h"
 #include "qemu/sockets.h"
+#include "qemu/main-loop.h"
 #include "migration/migration.h"
 #include "migration/qemu-file.h"
 #include "block/block.h"
diff --git a/migration-fd.c b/migration-fd.c
index 3d4613c..d2e523a 100644
--- a/migration-fd.c
+++ b/migration-fd.c
@@ -14,6 +14,7 @@
  */
 
 #include "qemu-common.h"
+#include "qemu/main-loop.h"
 #include "qemu/sockets.h"
 #include "migration/migration.h"
 #include "monitor/monitor.h"
diff --git a/migration-tcp.c b/migration-tcp.c
index b20ee58..782572d 100644
--- a/migration-tcp.c
+++ b/migration-tcp.c
@@ -18,6 +18,7 @@
 #include "migration/migration.h"
 #include "migration/qemu-file.h"
 #include "block/block.h"
+#include "qemu/main-loop.h"
 
 //#define DEBUG_MIGRATION_TCP
 
diff --git a/migration-unix.c b/migration-unix.c
index 94b7022..651fc5b 100644
--- a/migration-unix.c
+++ b/migration-unix.c
@@ -15,6 +15,7 @@
 
 #include "qemu-common.h"
 #include "qemu/sockets.h"
+#include "qemu/main-loop.h"
 #include "migration/migration.h"
 #include "migration/qemu-file.h"
 #include "block/block.h"
diff --git a/migration.c b/migration.c
index 1402fa7..ac200ed 100644
--- a/migration.c
+++ b/migration.c
@@ -14,6 +14,7 @@
  */
 
 #include "qemu-common.h"
+#include "qemu/main-loop.h"
 #include "migration/migration.h"
 #include "monitor/monitor.h"
 #include "migration/qemu-file.h"
diff --git a/nbd.c b/nbd.c
index 2606403..0fd0583 100644
--- a/nbd.c
+++ b/nbd.c
@@ -38,6 +38,7 @@
 
 #include "qemu/sockets.h"
 #include "qemu/queue.h"
+#include "qemu/main-loop.h"
 
 //#define DEBUG_NBD
 
diff --git a/net/net.c b/net/net.c
index c0d61bf..1148592 100644
--- a/net/net.c
+++ b/net/net.c
@@ -36,6 +36,7 @@
 #include "qmp-commands.h"
 #include "hw/qdev.h"
 #include "qemu/iov.h"
+#include "qemu/main-loop.h"
 #include "qapi-visit.h"
 #include "qapi/opts-visitor.h"
 #include "qapi/dealloc-visitor.h"
diff --git a/net/socket.c b/net/socket.c
index 87af1d3..e61309d 100644
--- a/net/socket.c
+++ b/net/socket.c
@@ -31,6 +31,7 @@
 #include "qemu/option.h"
 #include "qemu/sockets.h"
 #include "qemu/iov.h"
+#include "qemu/main-loop.h"
 
 typedef struct NetSocketState {
     NetClientState nc;
diff --git a/qemu-coroutine-io.c b/qemu-coroutine-io.c
index c4df35a..054ca70 100644
--- a/qemu-coroutine-io.c
+++ b/qemu-coroutine-io.c
@@ -26,6 +26,7 @@
 #include "qemu/sockets.h"
 #include "block/coroutine.h"
 #include "qemu/iov.h"
+#include "qemu/main-loop.h"
 
 ssize_t coroutine_fn
 qemu_co_sendv_recvv(int sockfd, struct iovec *iov, unsigned iov_cnt,
diff --git a/qemu-io-cmds.c b/qemu-io-cmds.c
index ffbcf31..f91b6c4 100644
--- a/qemu-io-cmds.c
+++ b/qemu-io-cmds.c
@@ -10,6 +10,7 @@
 
 #include "qemu-io.h"
 #include "block/block_int.h"
+#include "qemu/main-loop.h"
 
 #define CMD_NOFILE_OK   0x01
 
diff --git a/qemu-nbd.c b/qemu-nbd.c
index 9c31d45..f044546 100644
--- a/qemu-nbd.c
+++ b/qemu-nbd.c
@@ -19,6 +19,7 @@
 #include "qemu-common.h"
 #include "block/block.h"
 #include "block/nbd.h"
+#include "qemu/main-loop.h"
 
 #include <stdarg.h>
 #include <stdio.h>
diff --git a/slirp/misc.c b/slirp/misc.c
index 0bcc481..c0d4899 100644
--- a/slirp/misc.c
+++ b/slirp/misc.c
@@ -9,6 +9,7 @@
 #include <libslirp.h>
 
 #include "monitor/monitor.h"
+#include "qemu/main-loop.h"
 
 #ifdef DEBUG
 int slirp_debug = DBG_CALL|DBG_MISC|DBG_ERROR;
diff --git a/thread-pool.c b/thread-pool.c
index 5025567..3735fd3 100644
--- a/thread-pool.c
+++ b/thread-pool.c
@@ -23,6 +23,7 @@
 #include "block/block_int.h"
 #include "qemu/event_notifier.h"
 #include "block/thread-pool.h"
+#include "qemu/main-loop.h"
 
 static void do_spawn_thread(ThreadPool *pool);
 
diff --git a/ui/vnc-auth-sasl.h b/ui/vnc-auth-sasl.h
index 8091d68..3f59da6 100644
--- a/ui/vnc-auth-sasl.h
+++ b/ui/vnc-auth-sasl.h
@@ -33,6 +33,7 @@ typedef struct VncStateSASL VncStateSASL;
 typedef struct VncDisplaySASL VncDisplaySASL;
 
 #include "qemu/acl.h"
+#include "qemu/main-loop.h"
 
 struct VncStateSASL {
     sasl_conn_t *conn;
diff --git a/ui/vnc-auth-vencrypt.c b/ui/vnc-auth-vencrypt.c
index c59b188..bc7032e 100644
--- a/ui/vnc-auth-vencrypt.c
+++ b/ui/vnc-auth-vencrypt.c
@@ -25,7 +25,7 @@
  */
 
 #include "vnc.h"
-
+#include "qemu/main-loop.h"
 
 static void start_auth_vencrypt_subauth(VncState *vs)
 {
diff --git a/ui/vnc-ws.c b/ui/vnc-ws.c
index df89315..e304baf 100644
--- a/ui/vnc-ws.c
+++ b/ui/vnc-ws.c
@@ -19,6 +19,7 @@
  */
 
 #include "vnc.h"
+#include "qemu/main-loop.h"
 
 #ifdef CONFIG_VNC_TLS
 #include "qemu/sockets.h"
commit ff83c66eccf5b5f6b6530d504e3be41559250dcb
Author: Alex Bligh <alex at alex.org.uk>
Date:   Wed Aug 21 16:02:46 2013 +0100

    aio / timers: Split QEMUClock into QEMUClock and QEMUTimerList
    
    Split QEMUClock into QEMUClock and QEMUTimerList so that we can
    have more than one QEMUTimerList associated with the same clock.
    
    Introduce a main_loop_timerlist concept and make existing
    qemu_clock_* calls that actually should operate on a QEMUTimerList
    call the relevant QEMUTimerList implementations, using the clock's
    default timerlist. This vastly reduces the invasiveness of this
    change and means the API stays constant for existing users.
    
    Introduce a list of QEMUTimerLists associated with each clock
    so that reenabling the clock can cause all the notifiers
    to be called. Note the code to do the notifications is added
    in a later patch.
    
    Switch QEMUClockType to an enum. Remove global variables vm_clock,
    host_clock and rt_clock and add compatibility defines. Do not
    fix qemu_next_alarm_deadline as it's going to be deleted.
    
    Add qemu_clock_use_for_deadline to indicate whether a particular
    clock should be used for deadline calculations. When use_icount
    is true, vm_clock should not be used for deadline calculations
    as it does not contain a nanosecond count. Instead, icount
    timeouts come from the execution thread doing aio_notify or
    qemu_notify as appropriate. This function is used in the next
    patch.
    
    Signed-off-by: Alex Bligh <alex at alex.org.uk>
    Signed-off-by: Stefan Hajnoczi <stefanha at redhat.com>

diff --git a/include/qemu/timer.h b/include/qemu/timer.h
index 962eca8..b4a7ba0 100644
--- a/include/qemu/timer.h
+++ b/include/qemu/timer.h
@@ -1,6 +1,7 @@
 #ifndef QEMU_TIMER_H
 #define QEMU_TIMER_H
 
+#include "qemu/typedefs.h"
 #include "qemu-common.h"
 #include "qemu/main-loop.h"
 #include "qemu/notify.h"
@@ -11,34 +12,84 @@
 #define SCALE_US 1000
 #define SCALE_NS 1
 
-#define QEMU_CLOCK_REALTIME 0
-#define QEMU_CLOCK_VIRTUAL  1
-#define QEMU_CLOCK_HOST     2
+/**
+ * QEMUClockType:
+ *
+ * The following clock types are available:
+ *
+ * @QEMU_CLOCK_REALTIME: Real time clock
+ *
+ * The real time clock should be used only for stuff which does not
+ * change the virtual machine state, as it is run even if the virtual
+ * machine is stopped. The real time clock has a frequency of 1000
+ * Hz.
+ *
+ * Formerly rt_clock
+ *
+ * @QEMU_CLOCK_VIRTUAL: virtual clock
+ *
+ * The virtual clock is only run during the emulation. It is stopped
+ * when the virtual machine is stopped. Virtual timers use a high
+ * precision clock, usually cpu cycles (use ticks_per_sec).
+ *
+ * Formerly vm_clock
+ *
+ * @QEMU_CLOCK_HOST: host clock
+ *
+ * The host clock should be use for device models that emulate accurate
+ * real time sources. It will continue to run when the virtual machine
+ * is suspended, and it will reflect system time changes the host may
+ * undergo (e.g. due to NTP). The host clock has the same precision as
+ * the virtual clock.
+ *
+ * Formerly host_clock
+ */
+
+typedef enum {
+    QEMU_CLOCK_REALTIME = 0,
+    QEMU_CLOCK_VIRTUAL = 1,
+    QEMU_CLOCK_HOST = 2,
+    QEMU_CLOCK_MAX
+} QEMUClockType;
 
 typedef struct QEMUClock QEMUClock;
+typedef struct QEMUTimerList QEMUTimerList;
 typedef void QEMUTimerCB(void *opaque);
 
-/* The real time clock should be used only for stuff which does not
-   change the virtual machine state, as it is run even if the virtual
-   machine is stopped. The real time clock has a frequency of 1000
-   Hz. */
-extern QEMUClock *rt_clock;
+struct QEMUTimer {
+    int64_t expire_time;        /* in nanoseconds */
+    QEMUTimerList *timer_list;
+    QEMUTimerCB *cb;
+    void *opaque;
+    QEMUTimer *next;
+    int scale;
+};
+
+extern QEMUClock *qemu_clocks[QEMU_CLOCK_MAX];
 
-/* The virtual clock is only run during the emulation. It is stopped
-   when the virtual machine is stopped. Virtual timers use a high
-   precision clock, usually cpu cycles (use ticks_per_sec). */
-extern QEMUClock *vm_clock;
+/**
+ * qemu_clock_ptr:
+ * @type: type of clock
+ *
+ * Translate a clock type into a pointer to QEMUClock object.
+ *
+ * Returns: a pointer to the QEMUClock object
+ */
+static inline QEMUClock *qemu_clock_ptr(QEMUClockType type)
+{
+    return qemu_clocks[type];
+}
 
-/* The host clock should be use for device models that emulate accurate
-   real time sources. It will continue to run when the virtual machine
-   is suspended, and it will reflect system time changes the host may
-   undergo (e.g. due to NTP). The host clock has the same precision as
-   the virtual clock. */
-extern QEMUClock *host_clock;
+/* These three clocks are maintained here with separate variable
+ * names for compatibility only.
+ */
+#define rt_clock (qemu_clock_ptr(QEMU_CLOCK_REALTIME))
+#define vm_clock (qemu_clock_ptr(QEMU_CLOCK_VIRTUAL))
+#define host_clock (qemu_clock_ptr(QEMU_CLOCK_HOST))
 
 int64_t qemu_get_clock_ns(QEMUClock *clock);
-int64_t qemu_clock_has_timers(QEMUClock *clock);
-int64_t qemu_clock_expired(QEMUClock *clock);
+bool qemu_clock_has_timers(QEMUClock *clock);
+bool qemu_clock_expired(QEMUClock *clock);
 int64_t qemu_clock_deadline(QEMUClock *clock);
 
 /**
@@ -53,6 +104,121 @@ int64_t qemu_clock_deadline(QEMUClock *clock);
 int64_t qemu_clock_deadline_ns(QEMUClock *clock);
 
 /**
+ * qemu_clock_use_for_deadline:
+ * @clock: the clock to operate on
+ *
+ * Determine whether a clock should be used for deadline
+ * calculations. Some clocks, for instance vm_clock with
+ * use_icount set, do not count in nanoseconds. Such clocks
+ * are not used for deadline calculations, and are presumed
+ * to interrupt any poll using qemu_notify/aio_notify
+ * etc.
+ *
+ * Returns: true if the clock runs in nanoseconds and
+ * should be used for a deadline.
+ */
+bool qemu_clock_use_for_deadline(QEMUClock *clock);
+
+/**
+ * qemu_clock_get_main_loop_timerlist:
+ * @clock: the clock to operate on
+ *
+ * Return the default timer list assocatiated with a clock.
+ *
+ * Returns: the default timer list
+ */
+QEMUTimerList *qemu_clock_get_main_loop_timerlist(QEMUClock *clock);
+
+/**
+ * timerlist_new:
+ * @type: the clock type to associate with the timerlist
+ *
+ * Create a new timerlist associated with the clock of
+ * type @type.
+ *
+ * Returns: a pointer to the QEMUTimerList created
+ */
+QEMUTimerList *timerlist_new(QEMUClockType type);
+
+/**
+ * timerlist_free:
+ * @timer_list: the timer list to free
+ *
+ * Frees a timer_list. It must have no active timers.
+ */
+void timerlist_free(QEMUTimerList *timer_list);
+
+/**
+ * timerlist_has_timers:
+ * @timer_list: the timer list to operate on
+ *
+ * Determine whether a timer list has active timers
+ *
+ * Returns: true if the timer list has timers.
+ */
+bool timerlist_has_timers(QEMUTimerList *timer_list);
+
+/**
+ * timerlist_expired:
+ * @timer_list: the timer list to operate on
+ *
+ * Determine whether a timer list has any timers which
+ * are expired.
+ *
+ * Returns: true if the timer list has timers which
+ * have expired.
+ */
+bool timerlist_expired(QEMUTimerList *timer_list);
+
+/**
+ * timerlist_deadline:
+ * @timer_list: the timer list to operate on
+ *
+ * Determine the deadline for a timer_list. This is
+ * a legacy function which returns INT32_MAX if the
+ * timer list has no timers or if the earliest timer
+ * expires later than INT32_MAX nanoseconds away.
+ *
+ * Returns: the number of nanoseconds until the earliest
+ * timer expires or INT32_MAX in the situations listed
+ * above
+ */
+int64_t timerlist_deadline(QEMUTimerList *timer_list);
+
+/**
+ * timerlist_deadline_ns:
+ * @timer_list: the timer list to operate on
+ *
+ * Determine the deadline for a timer_list, i.e.
+ * the number of nanoseconds until the first timer
+ * expires. Return -1 if there are no timers.
+ *
+ * Returns: the number of nanoseconds until the earliest
+ * timer expires -1 if none
+ */
+int64_t timerlist_deadline_ns(QEMUTimerList *timer_list);
+
+/**
+ * timerlist_getclock:
+ * @timer_list: the timer list to operate on
+ *
+ * Determine the clock associated with a timer list.
+ *
+ * Returns: the clock associated with the timer list.
+ */
+QEMUClock *timerlist_get_clock(QEMUTimerList *timer_list);
+
+/**
+ * timerlist_run_timers:
+ * @timer_list: the timer list to use
+ *
+ * Call all expired timers associated with the timer list.
+ *
+ * Returns: true if any timer expired
+ */
+bool timerlist_run_timers(QEMUTimerList *timer_list);
+
+/**
  * qemu_timeout_ns_to_ms:
  * @ns: nanosecond timeout value
  *
@@ -84,6 +250,50 @@ void qemu_unregister_clock_reset_notifier(QEMUClock *clock,
 
 QEMUTimer *qemu_new_timer(QEMUClock *clock, int scale,
                           QEMUTimerCB *cb, void *opaque);
+
+/**
+ * timer_init:
+ * @ts: the timer to be initialised
+ * @timer_list: the timer list to attach the timer to
+ * @scale: the scale value for the tiemr
+ * @cb: the callback to be called when the timer expires
+ * @opaque: the opaque pointer to be passed to the callback
+ *
+ * Initialise a new timer and associate it with @timer_list.
+ * The caller is responsible for allocating the memory.
+ *
+ * You need not call an explicit deinit call. Simply make
+ * sure it is not on a list with timer_del.
+ */
+void timer_init(QEMUTimer *ts,
+                QEMUTimerList *timer_list, int scale,
+                QEMUTimerCB *cb, void *opaque);
+
+/**
+ * timer_new_tl:
+ * @timer_list: the timer list to attach the timer to
+ * @scale: the scale value for the tiemr
+ * @cb: the callback to be called when the timer expires
+ * @opaque: the opaque pointer to be passed to the callback
+ *
+ * Creeate a new timer and associate it with @timer_list.
+ * The memory is allocated by the function.
+ *
+ * This is not the preferred interface unless you know you
+ * are going to call timer_free. Use timer_init instead.
+ *
+ * Returns: a pointer to the timer
+ */
+static inline QEMUTimer *timer_new_tl(QEMUTimerList *timer_list,
+                                      int scale,
+                                      QEMUTimerCB *cb,
+                                      void *opaque)
+{
+    QEMUTimer *ts = g_malloc0(sizeof(QEMUTimer));
+    timer_init(ts, timer_list, scale, cb, opaque);
+    return ts;
+}
+
 void qemu_free_timer(QEMUTimer *ts);
 void qemu_del_timer(QEMUTimer *ts);
 void qemu_mod_timer_ns(QEMUTimer *ts, int64_t expire_time);
@@ -92,11 +302,61 @@ bool timer_pending(QEMUTimer *ts);
 bool timer_expired(QEMUTimer *timer_head, int64_t current_time);
 uint64_t timer_expire_time_ns(QEMUTimer *ts);
 
+/* New format calling conventions for timers */
+
+/**
+ * timer_free:
+ * @ts: the timer
+ *
+ * Free a timer (it must not be on the active list)
+ */
+static inline void timer_free(QEMUTimer *ts)
+{
+    qemu_free_timer(ts);
+}
+
+/**
+ * timer_del:
+ * @ts: the timer
+ *
+ * Delete a timer from the active list.
+ */
+static inline void timer_del(QEMUTimer *ts)
+{
+    qemu_del_timer(ts);
+}
+
+/**
+ * timer_mod_ns:
+ * @ts: the timer
+ * @expire_time: the expiry time in nanoseconds
+ *
+ * Modify a timer to expire at @expire_time
+ */
+static inline void timer_mod_ns(QEMUTimer *ts, int64_t expire_time)
+{
+    qemu_mod_timer_ns(ts, expire_time);
+}
+
+/**
+ * timer_mod:
+ * @ts: the timer
+ * @expire_time: the expire time in the units associated with the timer
+ *
+ * Modify a timer to expiry at @expire_time, taking into
+ * account the scale associated with the timer.
+ */
+static inline void timer_mod(QEMUTimer *ts, int64_t expire_timer)
+{
+    qemu_mod_timer(ts, expire_timer);
+}
+
 /**
  * qemu_run_timers:
  * @clock: clock on which to operate
  *
- * Run all the timers associated with a clock.
+ * Run all the timers associated with the default timer list
+ * of a clock.
  *
  * Returns: true if any timer ran.
  */
@@ -105,7 +365,8 @@ bool qemu_run_timers(QEMUClock *clock);
 /**
  * qemu_run_all_timers:
  *
- * Run all the timers associated with every clock.
+ * Run all the timers associated with the default timer list
+ * of every clock.
  *
  * Returns: true if any timer ran.
  */
@@ -138,13 +399,54 @@ static inline int64_t qemu_soonest_timeout(int64_t timeout1, int64_t timeout2)
     return ((uint64_t) timeout1 < (uint64_t) timeout2) ? timeout1 : timeout2;
 }
 
+/**
+ * qemu_new_timer_ns:
+ * @clock: the clock to associate with the timer
+ * @callback: the callback to call when the timer expires
+ * @opaque: the opaque pointer to pass to the callback
+ *
+ * Create a new timer with nanosecond scale on the default timer list
+ * associated with the clock.
+ *
+ * Returns: a pointer to the newly created timer
+ */
 static inline QEMUTimer *qemu_new_timer_ns(QEMUClock *clock, QEMUTimerCB *cb,
                                            void *opaque)
 {
     return qemu_new_timer(clock, SCALE_NS, cb, opaque);
 }
 
-static inline QEMUTimer *qemu_new_timer_ms(QEMUClock *clock, QEMUTimerCB *cb,
+/**
+ * qemu_new_timer_us:
+ * @clock: the clock to associate with the timer
+ * @callback: the callback to call when the timer expires
+ * @opaque: the opaque pointer to pass to the callback
+ *
+ * Create a new timer with microsecond scale on the default timer list
+ * associated with the clock.
+ *
+ * Returns: a pointer to the newly created timer
+ */
+static inline QEMUTimer *qemu_new_timer_us(QEMUClock *clock,
+                                           QEMUTimerCB *cb,
+                                           void *opaque)
+{
+    return qemu_new_timer(clock, SCALE_US, cb, opaque);
+}
+
+/**
+ * qemu_new_timer_ms:
+ * @clock: the clock to associate with the timer
+ * @callback: the callback to call when the timer expires
+ * @opaque: the opaque pointer to pass to the callback
+ *
+ * Create a new timer with millisecond scale on the default timer list
+ * associated with the clock.
+ *
+ * Returns: a pointer to the newly created timer
+ */
+static inline QEMUTimer *qemu_new_timer_ms(QEMUClock *clock,
+                                           QEMUTimerCB *cb,
                                            void *opaque)
 {
     return qemu_new_timer(clock, SCALE_MS, cb, opaque);
diff --git a/qemu-timer.c b/qemu-timer.c
index 52a1947..b045184 100644
--- a/qemu-timer.c
+++ b/qemu-timer.c
@@ -49,22 +49,29 @@
 /* timers */
 
 struct QEMUClock {
-    QEMUTimer *active_timers;
+    QEMUTimerList *main_loop_timerlist;
+    QLIST_HEAD(, QEMUTimerList) timerlists;
 
     NotifierList reset_notifiers;
     int64_t last;
 
-    int type;
+    QEMUClockType type;
     bool enabled;
 };
 
-struct QEMUTimer {
-    int64_t expire_time;	/* in nanoseconds */
+QEMUClock *qemu_clocks[QEMU_CLOCK_MAX];
+
+/* A QEMUTimerList is a list of timers attached to a clock. More
+ * than one QEMUTimerList can be attached to each clock, for instance
+ * used by different AioContexts / threads. Each clock also has
+ * a list of the QEMUTimerLists associated with it, in order that
+ * reenabling the clock can call all the notifiers.
+ */
+
+struct QEMUTimerList {
     QEMUClock *clock;
-    QEMUTimerCB *cb;
-    void *opaque;
-    QEMUTimer *next;
-    int scale;
+    QEMUTimer *active_timers;
+    QLIST_ENTRY(QEMUTimerList) list;
 };
 
 struct qemu_alarm_timer {
@@ -93,21 +100,25 @@ static int64_t qemu_next_alarm_deadline(void)
 {
     int64_t delta = INT64_MAX;
     int64_t rtdelta;
+    int64_t hdelta;
 
-    if (!use_icount && vm_clock->enabled && vm_clock->active_timers) {
-        delta = vm_clock->active_timers->expire_time -
-                     qemu_get_clock_ns(vm_clock);
+    if (!use_icount && vm_clock->enabled &&
+        vm_clock->main_loop_timerlist->active_timers) {
+        delta = vm_clock->main_loop_timerlist->active_timers->expire_time -
+            qemu_get_clock_ns(vm_clock);
     }
-    if (host_clock->enabled && host_clock->active_timers) {
-        int64_t hdelta = host_clock->active_timers->expire_time -
-                 qemu_get_clock_ns(host_clock);
+    if (host_clock->enabled &&
+        host_clock->main_loop_timerlist->active_timers) {
+        hdelta = host_clock->main_loop_timerlist->active_timers->expire_time -
+            qemu_get_clock_ns(host_clock);
         if (hdelta < delta) {
             delta = hdelta;
         }
     }
-    if (rt_clock->enabled && rt_clock->active_timers) {
-        rtdelta = (rt_clock->active_timers->expire_time -
-                 qemu_get_clock_ns(rt_clock));
+    if (rt_clock->enabled &&
+        rt_clock->main_loop_timerlist->active_timers) {
+        rtdelta = (rt_clock->main_loop_timerlist->active_timers->expire_time -
+                   qemu_get_clock_ns(rt_clock));
         if (rtdelta < delta) {
             delta = rtdelta;
         }
@@ -231,11 +242,42 @@ next:
     }
 }
 
-QEMUClock *rt_clock;
-QEMUClock *vm_clock;
-QEMUClock *host_clock;
+static QEMUTimerList *timerlist_new_from_clock(QEMUClock *clock)
+{
+    QEMUTimerList *timer_list;
+
+    /* Assert if we do not have a clock. If you see this
+     * assertion in means that the clocks have not been
+     * initialised before a timerlist is needed. This
+     * normally happens if an AioContext is used before
+     * init_clocks() is called within main().
+     */
+    assert(clock);
+
+    timer_list = g_malloc0(sizeof(QEMUTimerList));
+    timer_list->clock = clock;
+    QLIST_INSERT_HEAD(&clock->timerlists, timer_list, list);
+    return timer_list;
+}
+
+QEMUTimerList *timerlist_new(QEMUClockType type)
+{
+    return timerlist_new_from_clock(qemu_clock_ptr(type));
+}
 
-static QEMUClock *qemu_clock_new(int type)
+void timerlist_free(QEMUTimerList *timer_list)
+{
+    assert(!timerlist_has_timers(timer_list));
+    if (timer_list->clock) {
+        QLIST_REMOVE(timer_list, list);
+        if (timer_list->clock->main_loop_timerlist == timer_list) {
+            timer_list->clock->main_loop_timerlist = NULL;
+        }
+    }
+    g_free(timer_list);
+}
+
+static QEMUClock *qemu_clock_new(QEMUClockType type)
 {
     QEMUClock *clock;
 
@@ -243,10 +285,17 @@ static QEMUClock *qemu_clock_new(int type)
     clock->type = type;
     clock->enabled = true;
     clock->last = INT64_MIN;
+    QLIST_INIT(&clock->timerlists);
     notifier_list_init(&clock->reset_notifiers);
+    clock->main_loop_timerlist = timerlist_new_from_clock(clock);
     return clock;
 }
 
+bool qemu_clock_use_for_deadline(QEMUClock *clock)
+{
+    return !(use_icount && (clock->type == QEMU_CLOCK_VIRTUAL));
+}
+
 void qemu_clock_enable(QEMUClock *clock, bool enabled)
 {
     bool old = clock->enabled;
@@ -256,24 +305,36 @@ void qemu_clock_enable(QEMUClock *clock, bool enabled)
     }
 }
 
-int64_t qemu_clock_has_timers(QEMUClock *clock)
+bool timerlist_has_timers(QEMUTimerList *timer_list)
 {
-    return !!clock->active_timers;
+    return !!timer_list->active_timers;
 }
 
-int64_t qemu_clock_expired(QEMUClock *clock)
+bool qemu_clock_has_timers(QEMUClock *clock)
 {
-    return (clock->active_timers &&
-            clock->active_timers->expire_time < qemu_get_clock_ns(clock));
+    return timerlist_has_timers(clock->main_loop_timerlist);
 }
 
-int64_t qemu_clock_deadline(QEMUClock *clock)
+bool timerlist_expired(QEMUTimerList *timer_list)
+{
+    return (timer_list->active_timers &&
+            timer_list->active_timers->expire_time <
+            qemu_get_clock_ns(timer_list->clock));
+}
+
+bool qemu_clock_expired(QEMUClock *clock)
+{
+    return timerlist_expired(clock->main_loop_timerlist);
+}
+
+int64_t timerlist_deadline(QEMUTimerList *timer_list)
 {
     /* To avoid problems with overflow limit this to 2^32.  */
     int64_t delta = INT32_MAX;
 
-    if (clock->enabled && clock->active_timers) {
-        delta = clock->active_timers->expire_time - qemu_get_clock_ns(clock);
+    if (timer_list->clock->enabled && timer_list->active_timers) {
+        delta = timer_list->active_timers->expire_time -
+            qemu_get_clock_ns(timer_list->clock);
     }
     if (delta < 0) {
         delta = 0;
@@ -281,20 +342,26 @@ int64_t qemu_clock_deadline(QEMUClock *clock)
     return delta;
 }
 
+int64_t qemu_clock_deadline(QEMUClock *clock)
+{
+    return timerlist_deadline(clock->main_loop_timerlist);
+}
+
 /*
  * As above, but return -1 for no deadline, and do not cap to 2^32
  * as we know the result is always positive.
  */
 
-int64_t qemu_clock_deadline_ns(QEMUClock *clock)
+int64_t timerlist_deadline_ns(QEMUTimerList *timer_list)
 {
     int64_t delta;
 
-    if (!clock->enabled || !clock->active_timers) {
+    if (!timer_list->clock->enabled || !timer_list->active_timers) {
         return -1;
     }
 
-    delta = clock->active_timers->expire_time - qemu_get_clock_ns(clock);
+    delta = timer_list->active_timers->expire_time -
+        qemu_get_clock_ns(timer_list->clock);
 
     if (delta <= 0) {
         return 0;
@@ -303,6 +370,21 @@ int64_t qemu_clock_deadline_ns(QEMUClock *clock)
     return delta;
 }
 
+int64_t qemu_clock_deadline_ns(QEMUClock *clock)
+{
+    return timerlist_deadline_ns(clock->main_loop_timerlist);
+}
+
+QEMUClock *timerlist_get_clock(QEMUTimerList *timer_list)
+{
+    return timer_list->clock;
+}
+
+QEMUTimerList *qemu_clock_get_main_loop_timerlist(QEMUClock *clock)
+{
+    return clock->main_loop_timerlist;
+}
+
 /* Transition function to convert a nanosecond timeout to ms
  * This is used where a system does not support ppoll
  */
@@ -351,17 +433,21 @@ int qemu_poll_ns(GPollFD *fds, guint nfds, int64_t timeout)
 }
 
 
-QEMUTimer *qemu_new_timer(QEMUClock *clock, int scale,
-                          QEMUTimerCB *cb, void *opaque)
+void timer_init(QEMUTimer *ts,
+                QEMUTimerList *timer_list, int scale,
+                QEMUTimerCB *cb, void *opaque)
 {
-    QEMUTimer *ts;
-
-    ts = g_malloc0(sizeof(QEMUTimer));
-    ts->clock = clock;
+    ts->timer_list = timer_list;
     ts->cb = cb;
     ts->opaque = opaque;
     ts->scale = scale;
-    return ts;
+}
+
+QEMUTimer *qemu_new_timer(QEMUClock *clock, int scale,
+                          QEMUTimerCB *cb, void *opaque)
+{
+    return timer_new_tl(clock->main_loop_timerlist,
+                     scale, cb, opaque);
 }
 
 void qemu_free_timer(QEMUTimer *ts)
@@ -376,7 +462,7 @@ void qemu_del_timer(QEMUTimer *ts)
 
     /* NOTE: this code must be signal safe because
        timer_expired() can be called from a signal. */
-    pt = &ts->clock->active_timers;
+    pt = &ts->timer_list->active_timers;
     for(;;) {
         t = *pt;
         if (!t)
@@ -400,7 +486,7 @@ void qemu_mod_timer_ns(QEMUTimer *ts, int64_t expire_time)
     /* add the timer in the sorted list */
     /* NOTE: this code must be signal safe because
        timer_expired() can be called from a signal. */
-    pt = &ts->clock->active_timers;
+    pt = &ts->timer_list->active_timers;
     for(;;) {
         t = *pt;
         if (!timer_expired_ns(t, expire_time)) {
@@ -413,12 +499,12 @@ void qemu_mod_timer_ns(QEMUTimer *ts, int64_t expire_time)
     *pt = ts;
 
     /* Rearm if necessary  */
-    if (pt == &ts->clock->active_timers) {
+    if (pt == &ts->timer_list->active_timers) {
         if (!alarm_timer->pending) {
             qemu_rearm_alarm_timer(alarm_timer);
         }
         /* Interrupt execution to force deadline recalculation.  */
-        qemu_clock_warp(ts->clock);
+        qemu_clock_warp(ts->timer_list->clock);
         if (use_icount) {
             qemu_notify_event();
         }
@@ -433,7 +519,7 @@ void qemu_mod_timer(QEMUTimer *ts, int64_t expire_time)
 bool timer_pending(QEMUTimer *ts)
 {
     QEMUTimer *t;
-    for (t = ts->clock->active_timers; t != NULL; t = t->next) {
+    for (t = ts->timer_list->active_timers; t != NULL; t = t->next) {
         if (t == ts) {
             return true;
         }
@@ -446,23 +532,24 @@ bool timer_expired(QEMUTimer *timer_head, int64_t current_time)
     return timer_expired_ns(timer_head, current_time * timer_head->scale);
 }
 
-bool qemu_run_timers(QEMUClock *clock)
+bool timerlist_run_timers(QEMUTimerList *timer_list)
 {
     QEMUTimer *ts;
     int64_t current_time;
     bool progress = false;
    
-    if (!clock->enabled)
+    if (!timer_list->clock->enabled) {
         return progress;
+    }
 
-    current_time = qemu_get_clock_ns(clock);
+    current_time = qemu_get_clock_ns(timer_list->clock);
     for(;;) {
-        ts = clock->active_timers;
+        ts = timer_list->active_timers;
         if (!timer_expired_ns(ts, current_time)) {
             break;
         }
         /* remove timer from the list before calling the callback */
-        clock->active_timers = ts->next;
+        timer_list->active_timers = ts->next;
         ts->next = NULL;
 
         /* run the callback (the timer list can be modified) */
@@ -472,6 +559,11 @@ bool qemu_run_timers(QEMUClock *clock)
     return progress;
 }
 
+bool qemu_run_timers(QEMUClock *clock)
+{
+    return timerlist_run_timers(clock->main_loop_timerlist);
+}
+
 int64_t qemu_get_clock_ns(QEMUClock *clock)
 {
     int64_t now, last;
@@ -509,11 +601,13 @@ void qemu_unregister_clock_reset_notifier(QEMUClock *clock, Notifier *notifier)
 
 void init_clocks(void)
 {
-    if (!rt_clock) {
-        rt_clock = qemu_clock_new(QEMU_CLOCK_REALTIME);
-        vm_clock = qemu_clock_new(QEMU_CLOCK_VIRTUAL);
-        host_clock = qemu_clock_new(QEMU_CLOCK_HOST);
+    QEMUClockType type;
+    for (type = 0; type < QEMU_CLOCK_MAX; type++) {
+        if (!qemu_clocks[type]) {
+            qemu_clocks[type] = qemu_clock_new(type);
+        }
     }
+
 #ifdef CONFIG_PRCTL_PR_SET_TIMERSLACK
     prctl(PR_SET_TIMERSLACK, 1, 0, 0, 0);
 #endif
@@ -530,9 +624,10 @@ bool qemu_run_all_timers(void)
     alarm_timer->pending = false;
 
     /* vm time timers */
-    progress |= qemu_run_timers(vm_clock);
-    progress |= qemu_run_timers(rt_clock);
-    progress |= qemu_run_timers(host_clock);
+    QEMUClockType type;
+    for (type = 0; type < QEMU_CLOCK_MAX; type++) {
+        progress |= qemu_run_timers(qemu_clock_ptr(type));
+    }
 
     /* rearm timer, if not periodic */
     if (alarm_timer->expired) {
commit f9a976b7408f061fc7fc48b14d16797ed6f8fd97
Author: Alex Bligh <alex at alex.org.uk>
Date:   Wed Aug 21 16:02:45 2013 +0100

    aio / timers: Make qemu_run_timers and qemu_run_all_timers return progress
    
    Make qemu_run_timers and qemu_run_all_timers return progress
    so that aio_poll etc. can determine whether a timer has been
    run.
    
    Signed-off-by: Alex Bligh <alex at alex.org.uk>
    Signed-off-by: Stefan Hajnoczi <stefanha at redhat.com>

diff --git a/include/qemu/timer.h b/include/qemu/timer.h
index e4a6479..962eca8 100644
--- a/include/qemu/timer.h
+++ b/include/qemu/timer.h
@@ -92,8 +92,25 @@ bool timer_pending(QEMUTimer *ts);
 bool timer_expired(QEMUTimer *timer_head, int64_t current_time);
 uint64_t timer_expire_time_ns(QEMUTimer *ts);
 
-void qemu_run_timers(QEMUClock *clock);
-void qemu_run_all_timers(void);
+/**
+ * qemu_run_timers:
+ * @clock: clock on which to operate
+ *
+ * Run all the timers associated with a clock.
+ *
+ * Returns: true if any timer ran.
+ */
+bool qemu_run_timers(QEMUClock *clock);
+
+/**
+ * qemu_run_all_timers:
+ *
+ * Run all the timers associated with every clock.
+ *
+ * Returns: true if any timer ran.
+ */
+bool qemu_run_all_timers(void);
+
 void configure_alarms(char const *opt);
 void init_clocks(void);
 int init_timer_alarm(void);
diff --git a/qemu-timer.c b/qemu-timer.c
index 74f904b..52a1947 100644
--- a/qemu-timer.c
+++ b/qemu-timer.c
@@ -446,13 +446,14 @@ bool timer_expired(QEMUTimer *timer_head, int64_t current_time)
     return timer_expired_ns(timer_head, current_time * timer_head->scale);
 }
 
-void qemu_run_timers(QEMUClock *clock)
+bool qemu_run_timers(QEMUClock *clock)
 {
     QEMUTimer *ts;
     int64_t current_time;
+    bool progress = false;
    
     if (!clock->enabled)
-        return;
+        return progress;
 
     current_time = qemu_get_clock_ns(clock);
     for(;;) {
@@ -466,7 +467,9 @@ void qemu_run_timers(QEMUClock *clock)
 
         /* run the callback (the timer list can be modified) */
         ts->cb(ts->opaque);
+        progress = true;
     }
+    return progress;
 }
 
 int64_t qemu_get_clock_ns(QEMUClock *clock)
@@ -521,20 +524,23 @@ uint64_t timer_expire_time_ns(QEMUTimer *ts)
     return timer_pending(ts) ? ts->expire_time : -1;
 }
 
-void qemu_run_all_timers(void)
+bool qemu_run_all_timers(void)
 {
+    bool progress = false;
     alarm_timer->pending = false;
 
     /* vm time timers */
-    qemu_run_timers(vm_clock);
-    qemu_run_timers(rt_clock);
-    qemu_run_timers(host_clock);
+    progress |= qemu_run_timers(vm_clock);
+    progress |= qemu_run_timers(rt_clock);
+    progress |= qemu_run_timers(host_clock);
 
     /* rearm timer, if not periodic */
     if (alarm_timer->expired) {
         alarm_timer->expired = false;
         qemu_rearm_alarm_timer(alarm_timer);
     }
+
+    return progress;
 }
 
 #ifdef _WIN32
commit cd758dd0acaaf1f76f9727d4409915f3293db07a
Author: Alex Bligh <alex at alex.org.uk>
Date:   Wed Aug 21 16:02:44 2013 +0100

    aio / timers: Add prctl(PR_SET_TIMERSLACK, 1, ...) to reduce timer slack
    
    Where supported, called prctl(PR_SET_TIMERSLACK, 1, ...) to
    set one nanosecond timer slack to increase precision of timer
    calls.
    
    Signed-off-by: Alex Bligh <alex at alex.org.uk>
    Signed-off-by: Stefan Hajnoczi <stefanha at redhat.com>

diff --git a/configure b/configure
index 5659412..0a55c20 100755
--- a/configure
+++ b/configure
@@ -2834,6 +2834,21 @@ if compile_prog "" "" ; then
   ppoll=yes
 fi
 
+# check for prctl(PR_SET_TIMERSLACK , ... ) support
+prctl_pr_set_timerslack=no
+cat > $TMPC << EOF
+#include <sys/prctl.h>
+
+int main(void)
+{
+    prctl(PR_SET_TIMERSLACK, 1, 0, 0, 0);
+    return 0;
+}
+EOF
+if compile_prog "" "" ; then
+  prctl_pr_set_timerslack=yes
+fi
+
 # check for epoll support
 epoll=no
 cat > $TMPC << EOF
@@ -3833,6 +3848,9 @@ fi
 if test "$ppoll" = "yes" ; then
   echo "CONFIG_PPOLL=y" >> $config_host_mak
 fi
+if test "$prctl_pr_set_timerslack" = "yes" ; then
+  echo "CONFIG_PRCTL_PR_SET_TIMERSLACK=y" >> $config_host_mak
+fi
 if test "$epoll" = "yes" ; then
   echo "CONFIG_EPOLL=y" >> $config_host_mak
 fi
diff --git a/qemu-timer.c b/qemu-timer.c
index 120d58f..74f904b 100644
--- a/qemu-timer.c
+++ b/qemu-timer.c
@@ -41,6 +41,10 @@
 #include <poll.h>
 #endif
 
+#ifdef CONFIG_PRCTL_PR_SET_TIMERSLACK
+#include <sys/prctl.h>
+#endif
+
 /***********************************************************/
 /* timers */
 
@@ -507,6 +511,9 @@ void init_clocks(void)
         vm_clock = qemu_clock_new(QEMU_CLOCK_VIRTUAL);
         host_clock = qemu_clock_new(QEMU_CLOCK_HOST);
     }
+#ifdef CONFIG_PRCTL_PR_SET_TIMERSLACK
+    prctl(PR_SET_TIMERSLACK, 1, 0, 0, 0);
+#endif
 }
 
 uint64_t timer_expire_time_ns(QEMUTimer *ts)
commit 4e0c6529fcb5ccbed5eb2c4f094264eb447d49ea
Author: Alex Bligh <alex at alex.org.uk>
Date:   Wed Aug 21 16:02:43 2013 +0100

    aio / timers: add ppoll support with qemu_poll_ns
    
    Add qemu_poll_ns which works like g_poll but takes a nanosecond
    timeout.
    
    Signed-off-by: Alex Bligh <alex at alex.org.uk>
    Signed-off-by: Stefan Hajnoczi <stefanha at redhat.com>

diff --git a/configure b/configure
index 18fa608..5659412 100755
--- a/configure
+++ b/configure
@@ -2818,6 +2818,22 @@ if compile_prog "" "" ; then
   dup3=yes
 fi
 
+# check for ppoll support
+ppoll=no
+cat > $TMPC << EOF
+#include <poll.h>
+
+int main(void)
+{
+    struct pollfd pfd = { .fd = 0, .events = 0, .revents = 0 };
+    ppoll(&pfd, 1, 0, 0);
+    return 0;
+}
+EOF
+if compile_prog "" "" ; then
+  ppoll=yes
+fi
+
 # check for epoll support
 epoll=no
 cat > $TMPC << EOF
@@ -3814,6 +3830,9 @@ fi
 if test "$dup3" = "yes" ; then
   echo "CONFIG_DUP3=y" >> $config_host_mak
 fi
+if test "$ppoll" = "yes" ; then
+  echo "CONFIG_PPOLL=y" >> $config_host_mak
+fi
 if test "$epoll" = "yes" ; then
   echo "CONFIG_EPOLL=y" >> $config_host_mak
 fi
diff --git a/include/qemu/timer.h b/include/qemu/timer.h
index e0a51a1..e4a6479 100644
--- a/include/qemu/timer.h
+++ b/include/qemu/timer.h
@@ -63,6 +63,18 @@ int64_t qemu_clock_deadline_ns(QEMUClock *clock);
  */
 int qemu_timeout_ns_to_ms(int64_t ns);
 
+/**
+ * qemu_poll_ns:
+ * @fds: Array of file descriptors
+ * @nfds: number of file descriptors
+ * @timeout: timeout in nanoseconds
+ *
+ * Perform a poll like g_poll but with a timeout in nanoseconds.
+ * See g_poll documentation for further details.
+ *
+ * Returns: number of fds ready
+ */
+int qemu_poll_ns(GPollFD *fds, guint nfds, int64_t timeout);
 void qemu_clock_enable(QEMUClock *clock, bool enabled);
 void qemu_clock_warp(QEMUClock *clock);
 
diff --git a/qemu-timer.c b/qemu-timer.c
index be29adf..120d58f 100644
--- a/qemu-timer.c
+++ b/qemu-timer.c
@@ -37,6 +37,10 @@
 #include <mmsystem.h>
 #endif
 
+#ifdef CONFIG_PPOLL
+#include <poll.h>
+#endif
+
 /***********************************************************/
 /* timers */
 
@@ -323,6 +327,26 @@ int qemu_timeout_ns_to_ms(int64_t ns)
 }
 
 
+/* qemu implementation of g_poll which uses a nanosecond timeout but is
+ * otherwise identical to g_poll
+ */
+int qemu_poll_ns(GPollFD *fds, guint nfds, int64_t timeout)
+{
+#ifdef CONFIG_PPOLL
+    if (timeout < 0) {
+        return ppoll((struct pollfd *)fds, nfds, NULL, NULL);
+    } else {
+        struct timespec ts;
+        ts.tv_sec = timeout / 1000000000LL;
+        ts.tv_nsec = timeout % 1000000000LL;
+        return ppoll((struct pollfd *)fds, nfds, &ts, NULL);
+    }
+#else
+    return g_poll(fds, nfds, qemu_timeout_ns_to_ms(timeout));
+#endif
+}
+
+
 QEMUTimer *qemu_new_timer(QEMUClock *clock, int scale,
                           QEMUTimerCB *cb, void *opaque)
 {
commit 73c30df69ce1f6767a7dba29b2411329de102847
Author: Andreas Färber <afaerber at suse.de>
Date:   Fri Apr 13 17:54:02 2012 +0200

    MAINTAINERS: Take over 0.15 maintenance
    
    SUSE is shipping qemu-kvm 0.15.1 with SLES 11 SP2 so we will be actively
    tracking all KVM-related issues. Therefore upgrade to Supported.
    
    Signed-off-by: Andreas Färber <afaerber at suse.de>

diff --git a/MAINTAINERS b/MAINTAINERS
index 70a3370..d128ed0 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -852,8 +852,9 @@ S: Orphan
 
 Stable 0.15
 L: qemu-stable at nongnu.org
+M: Andreas Färber <afaerber at suse.de>
 T: git git://git.qemu.org/qemu-stable-0.15.git
-S: Orphan
+S: Supported
 
 Stable 0.14
 L: qemu-stable at nongnu.org
commit 5211333bf77d5199d5f27cd306b2798d90a4c8fc
Merge: 9fe4806 21e0043
Author: Anthony Liguori <anthony at codemonkey.ws>
Date:   Thu Aug 22 09:29:25 2013 -0500

    Merge remote-tracking branch 'luiz/queue/qmp' into staging
    
    # By Laszlo Ersek (8) and others
    # Via Luiz Capitulino
    * luiz/queue/qmp:
      scripts/qapi.py: Avoid syntax not supported by Python 2.4
      monitor: print the invalid char in error message
      OptsVisitor: introduce unit tests, with test cases for range flattening
      add "test-int128" and "test-bitops" to .gitignore
      OptsVisitor: don't try to flatten overlong integer ranges
      OptsVisitor: opts_type_uint64(): recognize intervals when LM_IN_PROGRESS
      OptsVisitor: rebase opts_type_uint64() to parse_uint_full()
      OptsVisitor: opts_type_int(): recognize intervals when LM_IN_PROGRESS
      OptsVisitor: introduce list modes for interval flattening
      OptsVisitor: introduce basic list modes
      Convert stderr message calling error_get_pretty() to error_report()
    
    Message-id: 1377015041-6567-1-git-send-email-lcapitulino at redhat.com
    Signed-off-by: Anthony Liguori <anthony at codemonkey.ws>

commit 9fe480695ad8c9126ac8f318a0241e10aad7a25b
Merge: ecfe10c 7717f24
Author: Anthony Liguori <anthony at codemonkey.ws>
Date:   Thu Aug 22 09:29:13 2013 -0500

    Merge remote-tracking branch 'jliu/or32' into staging
    
    # By Jia Liu
    # Via Jia Liu
    * jliu/or32:
      hw/openrisc: Avoid undefined shift in openrisc_pic_cpu_handler()
      hw/openrisc: Fix masking in openrisc_pic_cpu_handler()
      hw/openrisc: Avoid using uninitialised variable 'entry'
    
    Message-id: 1377050811-11116-1-git-send-email-proljc at gmail.com
    Signed-off-by: Anthony Liguori <anthony at codemonkey.ws>

commit 043a7e1f8f66f3089ef0158aea00203e4591ba8d
Author: Alex Bligh <alex at alex.org.uk>
Date:   Wed Aug 21 16:02:42 2013 +0100

    aio / timers: Consistent treatment of disabled clocks for deadlines
    
    Make treatment of disabled clocks consistent in deadline calculation
    
    Signed-off-by: Alex Bligh <alex at alex.org.uk>
    Signed-off-by: Stefan Hajnoczi <stefanha at redhat.com>

diff --git a/qemu-timer.c b/qemu-timer.c
index df8f12b..be29adf 100644
--- a/qemu-timer.c
+++ b/qemu-timer.c
@@ -264,7 +264,7 @@ int64_t qemu_clock_deadline(QEMUClock *clock)
     /* To avoid problems with overflow limit this to 2^32.  */
     int64_t delta = INT32_MAX;
 
-    if (clock->active_timers) {
+    if (clock->enabled && clock->active_timers) {
         delta = clock->active_timers->expire_time - qemu_get_clock_ns(clock);
     }
     if (delta < 0) {
commit 02a03a9f12ec2fe68c9fed84fa8607a5326e2b65
Author: Alex Bligh <alex at alex.org.uk>
Date:   Wed Aug 21 16:02:41 2013 +0100

    aio / timers: add qemu-timer.c utility functions
    
    Add utility functions to qemu-timer.c for nanosecond timing.
    
    Add qemu_clock_deadline_ns to calculate deadlines to
    nanosecond accuracy.
    
    Add utility function qemu_soonest_timeout to calculate soonest deadline.
    
    Add qemu_timeout_ns_to_ms to convert a timeout in nanoseconds back to
    milliseconds for when ppoll is not used.
    
    Signed-off-by: Alex Bligh <alex at alex.org.uk>
    Signed-off-by: Stefan Hajnoczi <stefanha at redhat.com>

diff --git a/include/qemu/timer.h b/include/qemu/timer.h
index da43cbe..e0a51a1 100644
--- a/include/qemu/timer.h
+++ b/include/qemu/timer.h
@@ -40,6 +40,29 @@ int64_t qemu_get_clock_ns(QEMUClock *clock);
 int64_t qemu_clock_has_timers(QEMUClock *clock);
 int64_t qemu_clock_expired(QEMUClock *clock);
 int64_t qemu_clock_deadline(QEMUClock *clock);
+
+/**
+ * qemu_clock_deadline_ns:
+ * @clock: the clock to operate on
+ *
+ * Calculate the timeout of the earliest expiring timer
+ * in nanoseconds, or -1 if no timer is set to expire.
+ *
+ * Returns: time until expiry in nanoseconds or -1
+ */
+int64_t qemu_clock_deadline_ns(QEMUClock *clock);
+
+/**
+ * qemu_timeout_ns_to_ms:
+ * @ns: nanosecond timeout value
+ *
+ * Convert a nanosecond timeout value (or -1) to
+ * a millisecond value (or -1), always rounding up.
+ *
+ * Returns: millisecond timeout value
+ */
+int qemu_timeout_ns_to_ms(int64_t ns);
+
 void qemu_clock_enable(QEMUClock *clock, bool enabled);
 void qemu_clock_warp(QEMUClock *clock);
 
@@ -67,6 +90,25 @@ int64_t cpu_get_ticks(void);
 void cpu_enable_ticks(void);
 void cpu_disable_ticks(void);
 
+/**
+ * qemu_soonest_timeout:
+ * @timeout1: first timeout in nanoseconds (or -1 for infinite)
+ * @timeout2: second timeout in nanoseconds (or -1 for infinite)
+ *
+ * Calculates the soonest of two timeout values. -1 means infinite, which
+ * is later than any other value.
+ *
+ * Returns: soonest timeout value in nanoseconds (or -1 for infinite)
+ */
+static inline int64_t qemu_soonest_timeout(int64_t timeout1, int64_t timeout2)
+{
+    /* we can abuse the fact that -1 (which means infinite) is a maximal
+     * value when cast to unsigned. As this is disgusting, it's kept in
+     * one inline function.
+     */
+    return ((uint64_t) timeout1 < (uint64_t) timeout2) ? timeout1 : timeout2;
+}
+
 static inline QEMUTimer *qemu_new_timer_ns(QEMUClock *clock, QEMUTimerCB *cb,
                                            void *opaque)
 {
diff --git a/qemu-timer.c b/qemu-timer.c
index 4117add..df8f12b 100644
--- a/qemu-timer.c
+++ b/qemu-timer.c
@@ -273,6 +273,56 @@ int64_t qemu_clock_deadline(QEMUClock *clock)
     return delta;
 }
 
+/*
+ * As above, but return -1 for no deadline, and do not cap to 2^32
+ * as we know the result is always positive.
+ */
+
+int64_t qemu_clock_deadline_ns(QEMUClock *clock)
+{
+    int64_t delta;
+
+    if (!clock->enabled || !clock->active_timers) {
+        return -1;
+    }
+
+    delta = clock->active_timers->expire_time - qemu_get_clock_ns(clock);
+
+    if (delta <= 0) {
+        return 0;
+    }
+
+    return delta;
+}
+
+/* Transition function to convert a nanosecond timeout to ms
+ * This is used where a system does not support ppoll
+ */
+int qemu_timeout_ns_to_ms(int64_t ns)
+{
+    int64_t ms;
+    if (ns < 0) {
+        return -1;
+    }
+
+    if (!ns) {
+        return 0;
+    }
+
+    /* Always round up, because it's better to wait too long than to wait too
+     * little and effectively busy-wait
+     */
+    ms = (ns + SCALE_MS - 1) / SCALE_MS;
+
+    /* To avoid overflow problems, limit this to 2^31, i.e. approx 25 days */
+    if (ms > (int64_t) INT32_MAX) {
+        ms = INT32_MAX;
+    }
+
+    return (int) ms;
+}
+
+
 QEMUTimer *qemu_new_timer(QEMUClock *clock, int scale,
                           QEMUTimerCB *cb, void *opaque)
 {
commit 58ac56b9ad53b006396523639bb7d7043edc56bf
Author: Alex Bligh <alex at alex.org.uk>
Date:   Wed Aug 21 16:02:40 2013 +0100

    aio / timers: Rename qemu_new_clock and expose clock types
    
    Rename qemu_new_clock to qemu_clock_new.
    
    Expose clock types.
    
    Signed-off-by: Alex Bligh <alex at alex.org.uk>
    Signed-off-by: Stefan Hajnoczi <stefanha at redhat.com>

diff --git a/include/qemu/timer.h b/include/qemu/timer.h
index a9afdb3..da43cbe 100644
--- a/include/qemu/timer.h
+++ b/include/qemu/timer.h
@@ -11,6 +11,10 @@
 #define SCALE_US 1000
 #define SCALE_NS 1
 
+#define QEMU_CLOCK_REALTIME 0
+#define QEMU_CLOCK_VIRTUAL  1
+#define QEMU_CLOCK_HOST     2
+
 typedef struct QEMUClock QEMUClock;
 typedef void QEMUTimerCB(void *opaque);
 
diff --git a/qemu-timer.c b/qemu-timer.c
index 682c50f..4117add 100644
--- a/qemu-timer.c
+++ b/qemu-timer.c
@@ -40,10 +40,6 @@
 /***********************************************************/
 /* timers */
 
-#define QEMU_CLOCK_REALTIME 0
-#define QEMU_CLOCK_VIRTUAL  1
-#define QEMU_CLOCK_HOST     2
-
 struct QEMUClock {
     QEMUTimer *active_timers;
 
@@ -231,7 +227,7 @@ QEMUClock *rt_clock;
 QEMUClock *vm_clock;
 QEMUClock *host_clock;
 
-static QEMUClock *qemu_new_clock(int type)
+static QEMUClock *qemu_clock_new(int type)
 {
     QEMUClock *clock;
 
@@ -433,9 +429,9 @@ void qemu_unregister_clock_reset_notifier(QEMUClock *clock, Notifier *notifier)
 void init_clocks(void)
 {
     if (!rt_clock) {
-        rt_clock = qemu_new_clock(QEMU_CLOCK_REALTIME);
-        vm_clock = qemu_new_clock(QEMU_CLOCK_VIRTUAL);
-        host_clock = qemu_new_clock(QEMU_CLOCK_HOST);
+        rt_clock = qemu_clock_new(QEMU_CLOCK_REALTIME);
+        vm_clock = qemu_clock_new(QEMU_CLOCK_VIRTUAL);
+        host_clock = qemu_clock_new(QEMU_CLOCK_HOST);
     }
 }
 
commit e93379b039030c68d85693a4bee2b76f814108d2
Author: Alex Bligh <alex at alex.org.uk>
Date:   Wed Aug 21 16:02:39 2013 +0100

    aio / timers: Rename qemu_timer_* functions
    
    Rename four functions in preparation for new API.
    
    Rename qemu_timer_expired to timer_expired
    Rename qemu_timer_expire_time_ns to timer_expire_time_ns
    Rename qemu_timer_pending to timer_pending
    Rename qemu_timer_expired_ns to timer_expired_ns
    
    Signed-off-by: Alex Bligh <alex at alex.org.uk>
    Signed-off-by: Stefan Hajnoczi <stefanha at redhat.com>

diff --git a/backends/baum.c b/backends/baum.c
index 62aa784..b08e1d5 100644
--- a/backends/baum.c
+++ b/backends/baum.c
@@ -314,9 +314,9 @@ static int baum_eat_packet(BaumDriverState *baum, const uint8_t *buf, int len)
             return 0; \
         if (*cur++ != ESC) { \
             DPRINTF("Broken packet %#2x, tossing\n", req); \
-		if (qemu_timer_pending(baum->cellCount_timer)) { \
-                qemu_del_timer(baum->cellCount_timer); \
-                baum_cellCount_timer_cb(baum); \
+            if (timer_pending(baum->cellCount_timer)) {    \
+                qemu_del_timer(baum->cellCount_timer);     \
+                baum_cellCount_timer_cb(baum);             \
             } \
             return (cur - 2 - buf); \
         } \
diff --git a/hw/input/tsc2005.c b/hw/input/tsc2005.c
index a771cd5..ebd1b7e 100644
--- a/hw/input/tsc2005.c
+++ b/hw/input/tsc2005.c
@@ -513,7 +513,7 @@ static int tsc2005_load(QEMUFile *f, void *opaque, int version_id)
     for (i = 0; i < 8; i ++)
         s->tr[i] = qemu_get_be32(f);
 
-    s->busy = qemu_timer_pending(s->timer);
+    s->busy = timer_pending(s->timer);
     tsc2005_pin_update(s);
 
     return 0;
diff --git a/hw/input/tsc210x.c b/hw/input/tsc210x.c
index 9b854e7..0067f98 100644
--- a/hw/input/tsc210x.c
+++ b/hw/input/tsc210x.c
@@ -1093,7 +1093,7 @@ static int tsc210x_load(QEMUFile *f, void *opaque, int version_id)
     for (i = 0; i < 0x14; i ++)
         qemu_get_be16s(f, &s->filter_data[i]);
 
-    s->busy = qemu_timer_pending(s->timer);
+    s->busy = timer_pending(s->timer);
     qemu_set_irq(s->pint, !s->irq);
     qemu_set_irq(s->davint, !s->dav);
 
diff --git a/hw/mips/cputimer.c b/hw/mips/cputimer.c
index e0266bf..739bbac 100644
--- a/hw/mips/cputimer.c
+++ b/hw/mips/cputimer.c
@@ -72,8 +72,8 @@ uint32_t cpu_mips_get_count (CPUMIPSState *env)
         uint64_t now;
 
         now = qemu_get_clock_ns(vm_clock);
-        if (qemu_timer_pending(env->timer)
-            && qemu_timer_expired(env->timer, now)) {
+        if (timer_pending(env->timer)
+            && timer_expired(env->timer, now)) {
             /* The timer has already expired.  */
             cpu_mips_timer_expire(env);
         }
diff --git a/hw/openrisc/cputimer.c b/hw/openrisc/cputimer.c
index 4144b34..9a09f5c 100644
--- a/hw/openrisc/cputimer.c
+++ b/hw/openrisc/cputimer.c
@@ -72,7 +72,7 @@ static void openrisc_timer_cb(void *opaque)
     OpenRISCCPU *cpu = opaque;
 
     if ((cpu->env.ttmr & TTMR_IE) &&
-         qemu_timer_expired(cpu->env.timer, qemu_get_clock_ns(vm_clock))) {
+         timer_expired(cpu->env.timer, qemu_get_clock_ns(vm_clock))) {
         CPUState *cs = CPU(cpu);
 
         cpu->env.ttmr |= TTMR_IP;
diff --git a/hw/timer/mc146818rtc.c b/hw/timer/mc146818rtc.c
index 3c3baac..d12f6e7 100644
--- a/hw/timer/mc146818rtc.c
+++ b/hw/timer/mc146818rtc.c
@@ -252,7 +252,7 @@ static void check_update_timer(RTCState *s)
          * the alarm time.  */
         next_update_time = s->next_alarm_time;
     }
-    if (next_update_time != qemu_timer_expire_time_ns(s->update_timer)) {
+    if (next_update_time != timer_expire_time_ns(s->update_timer)) {
         qemu_mod_timer(s->update_timer, next_update_time);
     }
 }
@@ -587,8 +587,8 @@ static int update_in_progress(RTCState *s)
     if (!rtc_running(s)) {
         return 0;
     }
-    if (qemu_timer_pending(s->update_timer)) {
-        int64_t next_update_time = qemu_timer_expire_time_ns(s->update_timer);
+    if (timer_pending(s->update_timer)) {
+        int64_t next_update_time = timer_expire_time_ns(s->update_timer);
         /* Latch UIP until the timer expires.  */
         if (qemu_get_clock_ns(rtc_clock) >= (next_update_time - UIP_HOLD_LENGTH)) {
             s->cmos_data[RTC_REG_A] |= REG_A_UIP;
diff --git a/hw/usb/redirect.c b/hw/usb/redirect.c
index e3b9f32..8fee3d3 100644
--- a/hw/usb/redirect.c
+++ b/hw/usb/redirect.c
@@ -1493,7 +1493,7 @@ static void usbredir_device_connect(void *priv,
     USBRedirDevice *dev = priv;
     const char *speed;
 
-    if (qemu_timer_pending(dev->attach_timer) || dev->dev.attached) {
+    if (timer_pending(dev->attach_timer) || dev->dev.attached) {
         ERROR("Received device connect while already connected\n");
         return;
     }
@@ -1588,7 +1588,7 @@ static void usbredir_interface_info(void *priv,
      * If we receive interface info after the device has already been
      * connected (ie on a set_config), re-check interface dependent things.
      */
-    if (qemu_timer_pending(dev->attach_timer) || dev->dev.attached) {
+    if (timer_pending(dev->attach_timer) || dev->dev.attached) {
         usbredir_check_bulk_receiving(dev);
         if (usbredir_check_filter(dev)) {
             ERROR("Device no longer matches filter after interface info "
diff --git a/include/qemu/timer.h b/include/qemu/timer.h
index 9dd206c..a9afdb3 100644
--- a/include/qemu/timer.h
+++ b/include/qemu/timer.h
@@ -49,9 +49,9 @@ void qemu_free_timer(QEMUTimer *ts);
 void qemu_del_timer(QEMUTimer *ts);
 void qemu_mod_timer_ns(QEMUTimer *ts, int64_t expire_time);
 void qemu_mod_timer(QEMUTimer *ts, int64_t expire_time);
-bool qemu_timer_pending(QEMUTimer *ts);
-bool qemu_timer_expired(QEMUTimer *timer_head, int64_t current_time);
-uint64_t qemu_timer_expire_time_ns(QEMUTimer *ts);
+bool timer_pending(QEMUTimer *ts);
+bool timer_expired(QEMUTimer *timer_head, int64_t current_time);
+uint64_t timer_expire_time_ns(QEMUTimer *ts);
 
 void qemu_run_timers(QEMUClock *clock);
 void qemu_run_all_timers(void);
diff --git a/qemu-timer.c b/qemu-timer.c
index b2d95e2..682c50f 100644
--- a/qemu-timer.c
+++ b/qemu-timer.c
@@ -80,7 +80,7 @@ struct qemu_alarm_timer {
 
 static struct qemu_alarm_timer *alarm_timer;
 
-static bool qemu_timer_expired_ns(QEMUTimer *timer_head, int64_t current_time)
+static bool timer_expired_ns(QEMUTimer *timer_head, int64_t current_time)
 {
     return timer_head && (timer_head->expire_time <= current_time);
 }
@@ -301,7 +301,7 @@ void qemu_del_timer(QEMUTimer *ts)
     QEMUTimer **pt, *t;
 
     /* NOTE: this code must be signal safe because
-       qemu_timer_expired() can be called from a signal. */
+       timer_expired() can be called from a signal. */
     pt = &ts->clock->active_timers;
     for(;;) {
         t = *pt;
@@ -325,11 +325,11 @@ void qemu_mod_timer_ns(QEMUTimer *ts, int64_t expire_time)
 
     /* add the timer in the sorted list */
     /* NOTE: this code must be signal safe because
-       qemu_timer_expired() can be called from a signal. */
+       timer_expired() can be called from a signal. */
     pt = &ts->clock->active_timers;
     for(;;) {
         t = *pt;
-        if (!qemu_timer_expired_ns(t, expire_time)) {
+        if (!timer_expired_ns(t, expire_time)) {
             break;
         }
         pt = &t->next;
@@ -356,7 +356,7 @@ void qemu_mod_timer(QEMUTimer *ts, int64_t expire_time)
     qemu_mod_timer_ns(ts, expire_time * ts->scale);
 }
 
-bool qemu_timer_pending(QEMUTimer *ts)
+bool timer_pending(QEMUTimer *ts)
 {
     QEMUTimer *t;
     for (t = ts->clock->active_timers; t != NULL; t = t->next) {
@@ -367,9 +367,9 @@ bool qemu_timer_pending(QEMUTimer *ts)
     return false;
 }
 
-bool qemu_timer_expired(QEMUTimer *timer_head, int64_t current_time)
+bool timer_expired(QEMUTimer *timer_head, int64_t current_time)
 {
-    return qemu_timer_expired_ns(timer_head, current_time * timer_head->scale);
+    return timer_expired_ns(timer_head, current_time * timer_head->scale);
 }
 
 void qemu_run_timers(QEMUClock *clock)
@@ -383,7 +383,7 @@ void qemu_run_timers(QEMUClock *clock)
     current_time = qemu_get_clock_ns(clock);
     for(;;) {
         ts = clock->active_timers;
-        if (!qemu_timer_expired_ns(ts, current_time)) {
+        if (!timer_expired_ns(ts, current_time)) {
             break;
         }
         /* remove timer from the list before calling the callback */
@@ -439,9 +439,9 @@ void init_clocks(void)
     }
 }
 
-uint64_t qemu_timer_expire_time_ns(QEMUTimer *ts)
+uint64_t timer_expire_time_ns(QEMUTimer *ts)
 {
-    return qemu_timer_pending(ts) ? ts->expire_time : -1;
+    return timer_pending(ts) ? ts->expire_time : -1;
 }
 
 void qemu_run_all_timers(void)
diff --git a/savevm.c b/savevm.c
index 03fc4d9..38c3093 100644
--- a/savevm.c
+++ b/savevm.c
@@ -983,7 +983,7 @@ void qemu_put_timer(QEMUFile *f, QEMUTimer *ts)
 {
     uint64_t expire_time;
 
-    expire_time = qemu_timer_expire_time_ns(ts);
+    expire_time = timer_expire_time_ns(ts);
     qemu_put_be64(f, expire_time);
 }
 
commit 04d542c8b826a1196ca4f03f5a35d83035976bd1
Author: Paolo Bonzini <pbonzini at redhat.com>
Date:   Mon Aug 19 18:54:28 2013 +0800

    vmdk: support vmfs files
    
    VMware ESX hosts also use different create and extent types for flat
    files, respectively "vmfs" and "VMFS".  This is not documented, but it
    can be found at http://kb.vmware.com/kb/10002511 (Recreating a missing
    virtual machine disk (VMDK) descriptor file).
    
    Signed-off-by: Paolo Bonzini <pbonzini at redhat.com>
    Signed-off-by: Fam Zheng <famz at redhat.com>
    Signed-off-by: Stefan Hajnoczi <stefanha at redhat.com>

diff --git a/block/vmdk.c b/block/vmdk.c
index 3986d1d..63b489d 100644
--- a/block/vmdk.c
+++ b/block/vmdk.c
@@ -719,7 +719,7 @@ static int vmdk_parse_extents(const char *desc, BlockDriverState *bs,
 
         if (sectors <= 0 ||
             (strcmp(type, "FLAT") && strcmp(type, "SPARSE") &&
-             strcmp(type, "VMFSSPARSE")) ||
+             strcmp(type, "VMFS") && strcmp(type, "VMFSSPARSE")) ||
             (strcmp(access, "RW"))) {
             goto next_line;
         }
@@ -732,7 +732,7 @@ static int vmdk_parse_extents(const char *desc, BlockDriverState *bs,
         }
 
         /* save to extents array */
-        if (!strcmp(type, "FLAT")) {
+        if (!strcmp(type, "FLAT") || !strcmp(type, "VMFS")) {
             /* FLAT extent */
             VmdkExtent *extent;
 
@@ -790,6 +790,7 @@ static int vmdk_open_desc_file(BlockDriverState *bs, int flags,
         goto exit;
     }
     if (strcmp(ct, "monolithicFlat") &&
+        strcmp(ct, "vmfs") &&
         strcmp(ct, "vmfsSparse") &&
         strcmp(ct, "twoGbMaxExtentSparse") &&
         strcmp(ct, "twoGbMaxExtentFlat")) {
commit daac8fdc68c5f0118ce24fcac5873ddaa0d0c9f9
Author: Fam Zheng <famz at redhat.com>
Date:   Mon Aug 19 18:54:27 2013 +0800

    vmdk: support vmfsSparse files
    
    VMware ESX hosts use a variant of the VMDK3 format, identified by the
    vmfsSparse create type ad the VMFSSPARSE extent type.
    
    It has 16 KB grain tables (L2) and a variable-size grain directory (L1).
    In addition, the grain size is always 512, but that is not a problem
    because it is included in the header.
    
    The format of the extents is documented in the VMDK spec.  The format
    of the descriptor file is not documented precisely, but it can be
    found at http://kb.vmware.com/kb/10026353 (Recreating a missing virtual
    machine disk (VMDK) descriptor file for delta disks).
    
    With these patches, vmfsSparse files only work if opened through the
    descriptor file.  Data files without descriptor files, as far as I
    could understand, are not supported by ESX.
    
    Signed-off-by: Paolo Bonzini <pbonzini at redhat.com>
    Signed-off-by: Fam Zheng <famz at redhat.com>
    
    --
    v2: Rebase to patch 01.
        Change le64_to_cpu to le32_to_cpu.
        Rename vmdk_open_vmdk3 to vmdk_open_vmfs_sparse, which represents the
        current usage of this format.
    
    Signed-off-by: Fam Zheng <famz at redhat.com>
    Signed-off-by: Stefan Hajnoczi <stefanha at redhat.com>

diff --git a/block/vmdk.c b/block/vmdk.c
index 4d282a6..3986d1d 100644
--- a/block/vmdk.c
+++ b/block/vmdk.c
@@ -481,9 +481,9 @@ static int vmdk_init_tables(BlockDriverState *bs, VmdkExtent *extent)
     return ret;
 }
 
-static int vmdk_open_vmdk3(BlockDriverState *bs,
-                           BlockDriverState *file,
-                           int flags)
+static int vmdk_open_vmfs_sparse(BlockDriverState *bs,
+                                 BlockDriverState *file,
+                                 int flags)
 {
     int ret;
     uint32_t magic;
@@ -674,7 +674,7 @@ static int vmdk_open_sparse(BlockDriverState *bs,
     magic = be32_to_cpu(magic);
     switch (magic) {
         case VMDK3_MAGIC:
-            return vmdk_open_vmdk3(bs, file, flags);
+            return vmdk_open_vmfs_sparse(bs, file, flags);
             break;
         case VMDK4_MAGIC:
             return vmdk_open_vmdk4(bs, file, flags);
@@ -718,7 +718,8 @@ static int vmdk_parse_extents(const char *desc, BlockDriverState *bs,
         }
 
         if (sectors <= 0 ||
-            (strcmp(type, "FLAT") && strcmp(type, "SPARSE")) ||
+            (strcmp(type, "FLAT") && strcmp(type, "SPARSE") &&
+             strcmp(type, "VMFSSPARSE")) ||
             (strcmp(access, "RW"))) {
             goto next_line;
         }
@@ -741,8 +742,8 @@ static int vmdk_parse_extents(const char *desc, BlockDriverState *bs,
                 return ret;
             }
             extent->flat_start_offset = flat_offset << 9;
-        } else if (!strcmp(type, "SPARSE")) {
-            /* SPARSE extent */
+        } else if (!strcmp(type, "SPARSE") || !strcmp(type, "VMFSSPARSE")) {
+            /* SPARSE extent and VMFSSPARSE extent are both "COWD" sparse file*/
             ret = vmdk_open_sparse(bs, extent_file, bs->open_flags);
             if (ret) {
                 bdrv_delete(extent_file);
@@ -789,6 +790,7 @@ static int vmdk_open_desc_file(BlockDriverState *bs, int flags,
         goto exit;
     }
     if (strcmp(ct, "monolithicFlat") &&
+        strcmp(ct, "vmfsSparse") &&
         strcmp(ct, "twoGbMaxExtentSparse") &&
         strcmp(ct, "twoGbMaxExtentFlat")) {
         fprintf(stderr,
@@ -1381,7 +1383,6 @@ static int coroutine_fn vmdk_co_write_zeroes(BlockDriverState *bs,
     return ret;
 }
 
-
 static int vmdk_create_extent(const char *filename, int64_t filesize,
                               bool flat, bool compress, bool zeroed_grain)
 {
commit f6b61e54bdd5b9ef46837c15547e1819b3bb4f37
Author: Fam Zheng <famz at redhat.com>
Date:   Mon Aug 19 18:54:26 2013 +0800

    vmdk: fix L1 and L2 table size in vmdk3 open
    
    VMDK3 header has the field l1dir_size, but vmdk_open_vmdk3 hardcoded the
    value. This patch honors the header field.
    
    And the L2 table size is 4096 according to VMDK spec[1], instead of
    1 << 9 (512).
    
    [1]:
    http://www.vmware.com/support/developer/vddk/vmdk_50_technote.pdf?src=vmdk
    
    Signed-off-by: Fam Zheng <famz at redhat.com>
    Signed-off-by: Stefan Hajnoczi <stefanha at redhat.com>

diff --git a/block/vmdk.c b/block/vmdk.c
index f8c0a4e..4d282a6 100644
--- a/block/vmdk.c
+++ b/block/vmdk.c
@@ -494,14 +494,14 @@ static int vmdk_open_vmdk3(BlockDriverState *bs,
     if (ret < 0) {
         return ret;
     }
-
-    ret = vmdk_add_extent(bs,
-                             bs->file, false,
-                             le32_to_cpu(header.disk_sectors),
-                             le32_to_cpu(header.l1dir_offset) << 9,
-                             0, 1 << 6, 1 << 9,
-                             le32_to_cpu(header.granularity),
-                             &extent);
+    ret = vmdk_add_extent(bs, file, false,
+                          le32_to_cpu(header.disk_sectors),
+                          le32_to_cpu(header.l1dir_offset) << 9,
+                          0,
+                          le32_to_cpu(header.l1dir_size),
+                          4096,
+                          le32_to_cpu(header.granularity),
+                          &extent);
     if (ret < 0) {
         return ret;
     }
commit b0651b8c246d0d9e6ad0831b3e34fd756016ad7e
Author: Fam Zheng <famz at redhat.com>
Date:   Mon Aug 19 18:54:25 2013 +0800

    vmdk: Move l1_size check into vmdk_add_extent()
    
    This header check is common to VMDK3 and VMDK4, so move it into
    vmdk_add_extent().
    
    Signed-off-by: Fam Zheng <famz at redhat.com>
    Signed-off-by: Stefan Hajnoczi <stefanha at redhat.com>

diff --git a/block/vmdk.c b/block/vmdk.c
index 346bb5c..f8c0a4e 100644
--- a/block/vmdk.c
+++ b/block/vmdk.c
@@ -401,6 +401,14 @@ static int vmdk_add_extent(BlockDriverState *bs,
         error_report("invalid granularity, image may be corrupt");
         return -EINVAL;
     }
+    if (l1_size > 512 * 1024 * 1024) {
+        /* Although with big capacity and small l1_entry_sectors, we can get a
+         * big l1_size, we don't want unbounded value to allocate the table.
+         * Limit it to 512M, which is 16PB for default cluster and L2 table
+         * size */
+        error_report("L1 size too big");
+        return -EFBIG;
+    }
 
     s->extents = g_realloc(s->extents,
                               (s->num_extents + 1) * sizeof(VmdkExtent));
@@ -598,14 +606,6 @@ static int vmdk_open_vmdk4(BlockDriverState *bs,
     }
     l1_size = (le64_to_cpu(header.capacity) + l1_entry_sectors - 1)
                 / l1_entry_sectors;
-    if (l1_size > 512 * 1024 * 1024) {
-        /* although with big capacity and small l1_entry_sectors, we can get a
-         * big l1_size, we don't want unbounded value to allocate the table.
-         * Limit it to 512M, which is 16PB for default cluster and L2 table
-         * size */
-        error_report("L1 size too big");
-        return -EFBIG;
-    }
     if (le32_to_cpu(header.flags) & VMDK4_FLAG_RGD) {
         l1_backup_offset = le64_to_cpu(header.rgd_offset) << 9;
     }
commit 7780d47211bde838c7f7e9330608e5397219066e
Author: Fam Zheng <famz at redhat.com>
Date:   Thu Aug 22 15:36:59 2013 +0800

    block: better error message for read only format name
    
    When user tries to use read-only whitelist format in the command line
    option, failure message was "'foo' invalid format". It might be invalid
    only for writable, but valid for read-only, so it is confusing. Give the
    user easier to understand information.
    
    Signed-off-by: Fam Zheng <famz at redhat.com>
    Signed-off-by: Stefan Hajnoczi <stefanha at redhat.com>

diff --git a/blockdev.c b/blockdev.c
index bc7016a..d3500c6 100644
--- a/blockdev.c
+++ b/blockdev.c
@@ -487,7 +487,11 @@ static DriveInfo *blockdev_init(QemuOpts *all_opts,
 
         drv = bdrv_find_whitelisted_format(buf, ro);
         if (!drv) {
-            error_report("'%s' invalid format", buf);
+            if (!ro && bdrv_find_whitelisted_format(buf, !ro)) {
+                error_report("'%s' can be only used as read-only device.", buf);
+            } else {
+                error_report("'%s' invalid format", buf);
+            }
             return NULL;
         }
     }
commit 893a8f6220368a9ebff9a74bd48359928545cf6a
Author: MORITA Kazutaka <morita.kazutaka at lab.ntt.co.jp>
Date:   Tue Aug 6 09:53:40 2013 +0800

    block: Produce zeros when protocols reading beyond end of file
    
    While Asias is debugging an issue creating qcow2 images on top of
    non-file protocols.  It boils down to this example using NBD:
    
    $ qemu-io -c 'open -g nbd+unix:///?socket=/tmp/nbd.sock' -c 'read -v 0 512'
    
    Notice the open -g option to set bs->growable.  This means you can
    read/write beyond end of file.  Reading beyond end of file is supposed
    to produce zeroes.
    
    We rely on this behavior in qcow2_create2() during qcow2 image
    creation.  We create a new file and then write the qcow2 header
    structure using bdrv_pwrite().  Since QCowHeader is not a multiple of
    sector size, block.c first uses bdrv_read() on the empty file to fetch
    the first sector (should be all zeroes).
    
    Here is the output from the qemu-io NBD example above:
    
    $ qemu-io -c 'open -g nbd+unix:///?socket=/tmp/nbd.sock' -c 'read -v 0 512'
    00000000:  ab ab ab ab ab ab ab ab ab ab ab ab ab ab ab ab  ................
    00000010:  ab ab ab ab ab ab ab ab ab ab ab ab ab ab ab ab  ................
    00000020:  ab ab ab ab ab ab ab ab ab ab ab ab ab ab ab ab  ................
    ...
    
    We are not zeroing the buffer!  As a result qcow2 image creation on top
    of protocols is not guaranteed to work even when file creation is
    supported by the protocol.
    
    [Adapted this patch to use bs->zero_beyond_eof.
    -- Stefan]
    
    Signed-off-by: MORITA Kazutaka <morita.kazutaka at lab.ntt.co.jp>
    Signed-off-by: Asias He <asias at redhat.com>
    Signed-off-by: Stefan Hajnoczi <stefanha at redhat.com>

diff --git a/block.c b/block.c
index e655052..1615d89 100644
--- a/block.c
+++ b/block.c
@@ -2571,7 +2571,35 @@ static int coroutine_fn bdrv_co_do_readv(BlockDriverState *bs,
         }
     }
 
-    ret = drv->bdrv_co_readv(bs, sector_num, nb_sectors, qiov);
+    if (!(bs->zero_beyond_eof && bs->growable)) {
+        ret = drv->bdrv_co_readv(bs, sector_num, nb_sectors, qiov);
+    } else {
+        /* Read zeros after EOF of growable BDSes */
+        int64_t len, total_sectors, max_nb_sectors;
+
+        len = bdrv_getlength(bs);
+        if (len < 0) {
+            ret = len;
+            goto out;
+        }
+
+        total_sectors = len >> BDRV_SECTOR_BITS;
+        max_nb_sectors = MAX(0, total_sectors - sector_num);
+        if (max_nb_sectors > 0) {
+            ret = drv->bdrv_co_readv(bs, sector_num,
+                                     MIN(nb_sectors, max_nb_sectors), qiov);
+        } else {
+            ret = 0;
+        }
+
+        /* Reading beyond end of file is supposed to produce zeroes */
+        if (ret == 0 && total_sectors < sector_num + nb_sectors) {
+            uint64_t offset = MAX(0, total_sectors - sector_num);
+            uint64_t bytes = (sector_num + nb_sectors - offset) *
+                              BDRV_SECTOR_SIZE;
+            qemu_iovec_memset(qiov, offset * BDRV_SECTOR_SIZE, 0, bytes);
+        }
+    }
 
 out:
     tracked_request_end(&req);
commit 0d51b4debee6fb322751a57097a1d675c7a7c38d
Author: Asias He <asias at redhat.com>
Date:   Thu Aug 22 15:24:14 2013 +0800

    block: Introduce bs->zero_beyond_eof
    
    In 4146b46c42e0989cb5842e04d88ab6ccb1713a48 (block: Produce zeros when
    protocols reading beyond end of file), we break qemu-iotests ./check
    -qcow2 022. This happens because qcow2 temporarily sets ->growable = 1
    for vmstate accesses (which are stored beyond the end of regular image
    data).
    
    We introduce the bs->zero_beyond_eof to allow qcow2_load_vmstate() to
    disable ->zero_beyond_eof temporarily in addition to enable ->growable.
    
    [Since the broken patch "block: Produce zeros when protocols reading
    beyond end of file" has not been merged yet, I have applied this fix
    *first* and will then apply the next patch to keep the tree bisectable.
    -- Stefan]
    
    Suggested-by: Stefan Hajnoczi <stefanha at redhat.com>
    Signed-off-by: Asias He <asias at redhat.com>
    Signed-off-by: Stefan Hajnoczi <stefanha at redhat.com>

diff --git a/block.c b/block.c
index 45a545b..e655052 100644
--- a/block.c
+++ b/block.c
@@ -706,6 +706,7 @@ static int bdrv_open_common(BlockDriverState *bs, BlockDriverState *file,
 
     bs->open_flags = flags;
     bs->buffer_alignment = 512;
+    bs->zero_beyond_eof = true;
     open_flags = bdrv_open_flags(bs, flags);
     bs->read_only = !(open_flags & BDRV_O_RDWR);
 
@@ -1402,6 +1403,7 @@ void bdrv_close(BlockDriverState *bs)
         bs->valid_key = 0;
         bs->sg = 0;
         bs->growable = 0;
+        bs->zero_beyond_eof = false;
         QDECREF(bs->options);
         bs->options = NULL;
 
diff --git a/block/qcow2.c b/block/qcow2.c
index 42ea7ec..78097e5 100644
--- a/block/qcow2.c
+++ b/block/qcow2.c
@@ -1722,12 +1722,15 @@ static int qcow2_load_vmstate(BlockDriverState *bs, uint8_t *buf,
 {
     BDRVQcowState *s = bs->opaque;
     int growable = bs->growable;
+    bool zero_beyond_eof = bs->zero_beyond_eof;
     int ret;
 
     BLKDBG_EVENT(bs->file, BLKDBG_VMSTATE_LOAD);
     bs->growable = 1;
+    bs->zero_beyond_eof = false;
     ret = bdrv_pread(bs, qcow2_vm_state_offset(s) + pos, buf, size);
     bs->growable = growable;
+    bs->zero_beyond_eof = zero_beyond_eof;
 
     return ret;
 }
diff --git a/include/block/block_int.h b/include/block/block_int.h
index e45f2a0..74b0689 100644
--- a/include/block/block_int.h
+++ b/include/block/block_int.h
@@ -281,6 +281,9 @@ struct BlockDriverState {
     /* Whether the disk can expand beyond total_sectors */
     int growable;
 
+    /* Whether produces zeros when read beyond eof */
+    bool zero_beyond_eof;
+
     /* the memory alignment required for the buffers handled by this driver */
     int buffer_alignment;
 
commit 1e0995561959645e218bb5e4afb6ad3d47b33396
Author: Eduardo Habkost <ehabkost at redhat.com>
Date:   Wed Aug 21 15:14:45 2013 -0300

    pc_piix: Kill pc_init1() memory region args
    
    All callers always use the same values (get_system_memory(),
    get_system_io()), so the parameters are pointless.
    
    If one day we decide to eliminate get_system_memory() and
    get_system_io(), we will be able to do that more easily by adding the
    values to struct QEMUMachineInitArgs.
    
    Signed-off-by: Eduardo Habkost <ehabkost at redhat.com>
    Signed-off-by: Michael S. Tsirkin <mst at redhat.com>

diff --git a/hw/i386/pc_piix.c b/hw/i386/pc_piix.c
index d3d4893..3c36a2a 100644
--- a/hw/i386/pc_piix.c
+++ b/hw/i386/pc_piix.c
@@ -62,11 +62,11 @@ static bool has_pci_info = true;
 
 /* PC hardware initialisation */
 static void pc_init1(QEMUMachineInitArgs *args,
-                     MemoryRegion *system_memory,
-                     MemoryRegion *system_io,
                      int pci_enabled,
                      int kvmclock_enabled)
 {
+    MemoryRegion *system_memory = get_system_memory();
+    MemoryRegion *system_io = get_system_io();
     int i;
     ram_addr_t below_4g_mem_size, above_4g_mem_size;
     PCIBus *pci_bus;
@@ -233,7 +233,7 @@ static void pc_init1(QEMUMachineInitArgs *args,
 
 static void pc_init_pci(QEMUMachineInitArgs *args)
 {
-    pc_init1(args, get_system_memory(), get_system_io(), 1, 1);
+    pc_init1(args, 1, 1);
 }
 
 static void pc_compat_1_6(QEMUMachineInitArgs *args)
@@ -306,7 +306,7 @@ static void pc_init_pci_no_kvmclock(QEMUMachineInitArgs *args)
     has_pci_info = false;
     disable_kvm_pv_eoi();
     enable_compat_apic_id_mode();
-    pc_init1(args, get_system_memory(), get_system_io(), 1, 0);
+    pc_init1(args, 1, 0);
 }
 
 static void pc_init_isa(QEMUMachineInitArgs *args)
@@ -317,7 +317,7 @@ static void pc_init_isa(QEMUMachineInitArgs *args)
     }
     disable_kvm_pv_eoi();
     enable_compat_apic_id_mode();
-    pc_init1(args, get_system_memory(), get_system_io(), 0, 1);
+    pc_init1(args, 0, 1);
 }
 
 #ifdef CONFIG_XEN
commit 396f79f45ea75bd1c421522f29b4f91d490df7cc
Author: Eduardo Habkost <ehabkost at redhat.com>
Date:   Wed Aug 21 15:14:44 2013 -0300

    pc: pc_compat_1_4() now can call pc_compat_1_5()
    
    It just needs to set has_pvpanic=false after calling it. This way, it
    won't be a special case anymore.
    
    Signed-off-by: Eduardo Habkost <ehabkost at redhat.com>
    Signed-off-by: Michael S. Tsirkin <mst at redhat.com>

diff --git a/hw/i386/pc_piix.c b/hw/i386/pc_piix.c
index a5e5bec..d3d4893 100644
--- a/hw/i386/pc_piix.c
+++ b/hw/i386/pc_piix.c
@@ -250,8 +250,8 @@ static void pc_compat_1_5(QEMUMachineInitArgs *args)
 
 static void pc_compat_1_4(QEMUMachineInitArgs *args)
 {
-    /* 1.5 was special - it enabled pvpanic in builtin machine */
-    pc_compat_1_6(args);
+    pc_compat_1_5(args);
+    has_pvpanic = false;
     x86_cpu_compat_set_features("n270", FEAT_1_ECX, 0, CPUID_EXT_MOVBE);
     x86_cpu_compat_set_features("Westmere", FEAT_1_ECX, 0, CPUID_EXT_PCLMULQDQ);
 }
diff --git a/hw/i386/pc_q35.c b/hw/i386/pc_q35.c
index f5e0b94..198c785 100644
--- a/hw/i386/pc_q35.c
+++ b/hw/i386/pc_q35.c
@@ -229,8 +229,8 @@ static void pc_compat_1_5(QEMUMachineInitArgs *args)
 
 static void pc_compat_1_4(QEMUMachineInitArgs *args)
 {
-    /* 1.5 was special - it enabled pvpanic in builtin machine */
-    pc_compat_1_6(args);
+    pc_compat_1_5(args);
+    has_pvpanic = false;
     x86_cpu_compat_set_features("n270", FEAT_1_ECX, 0, CPUID_EXT_MOVBE);
     x86_cpu_compat_set_features("Westmere", FEAT_1_ECX, 0, CPUID_EXT_PCLMULQDQ);
 }
commit 89b439f3136644b07c2e25bb4ceeb9466ae23fe5
Author: Eduardo Habkost <ehabkost at redhat.com>
Date:   Wed Aug 21 15:14:43 2013 -0300

    pc: Create pc_compat_*() functions
    
    Making the older compat functions call the newer compat functions at the
    beginning allows the older functions undo what's done by newer compat
    functions. e.g.: pc_compat_1_4() will be able to call pc_compat_1_5()
    and then set has_pvpanic=false.
    
    Signed-off-by: Eduardo Habkost <ehabkost at redhat.com>
    Signed-off-by: Michael S. Tsirkin <mst at redhat.com>

diff --git a/hw/i386/pc_piix.c b/hw/i386/pc_piix.c
index dd730b1..a5e5bec 100644
--- a/hw/i386/pc_piix.c
+++ b/hw/i386/pc_piix.c
@@ -236,38 +236,68 @@ static void pc_init_pci(QEMUMachineInitArgs *args)
     pc_init1(args, get_system_memory(), get_system_io(), 1, 1);
 }
 
-static void pc_init_pci_1_6(QEMUMachineInitArgs *args)
+static void pc_compat_1_6(QEMUMachineInitArgs *args)
 {
     has_pci_info = false;
     rom_file_in_ram = false;
-    pc_init_pci(args);
 }
 
-static void pc_init_pci_1_5(QEMUMachineInitArgs *args)
+static void pc_compat_1_5(QEMUMachineInitArgs *args)
 {
+    pc_compat_1_6(args);
     has_pvpanic = true;
-    pc_init_pci_1_6(args);
 }
 
-static void pc_init_pci_1_4(QEMUMachineInitArgs *args)
+static void pc_compat_1_4(QEMUMachineInitArgs *args)
 {
+    /* 1.5 was special - it enabled pvpanic in builtin machine */
+    pc_compat_1_6(args);
     x86_cpu_compat_set_features("n270", FEAT_1_ECX, 0, CPUID_EXT_MOVBE);
     x86_cpu_compat_set_features("Westmere", FEAT_1_ECX, 0, CPUID_EXT_PCLMULQDQ);
-    /* 1.5 was special - it enabled pvpanic in builtin machine */
-    pc_init_pci_1_6(args);
 }
 
-static void pc_init_pci_1_3(QEMUMachineInitArgs *args)
+static void pc_compat_1_3(QEMUMachineInitArgs *args)
 {
+    pc_compat_1_4(args);
     enable_compat_apic_id_mode();
-    pc_init_pci_1_4(args);
+}
+
+/* PC compat function for pc-0.14 to pc-1.2 */
+static void pc_compat_1_2(QEMUMachineInitArgs *args)
+{
+    pc_compat_1_3(args);
+    disable_kvm_pv_eoi();
+}
+
+static void pc_init_pci_1_6(QEMUMachineInitArgs *args)
+{
+    pc_compat_1_6(args);
+    pc_init_pci(args);
+}
+
+static void pc_init_pci_1_5(QEMUMachineInitArgs *args)
+{
+    pc_compat_1_5(args);
+    pc_init_pci(args);
+}
+
+static void pc_init_pci_1_4(QEMUMachineInitArgs *args)
+{
+    pc_compat_1_4(args);
+    pc_init_pci(args);
+}
+
+static void pc_init_pci_1_3(QEMUMachineInitArgs *args)
+{
+    pc_compat_1_3(args);
+    pc_init_pci(args);
 }
 
 /* PC machine init function for pc-0.14 to pc-1.2 */
 static void pc_init_pci_1_2(QEMUMachineInitArgs *args)
 {
-    disable_kvm_pv_eoi();
-    pc_init_pci_1_3(args);
+    pc_compat_1_2(args);
+    pc_init_pci(args);
 }
 
 /* PC init function for pc-0.10 to pc-0.13, and reused by xenfv */
diff --git a/hw/i386/pc_q35.c b/hw/i386/pc_q35.c
index 4847f46..f5e0b94 100644
--- a/hw/i386/pc_q35.c
+++ b/hw/i386/pc_q35.c
@@ -215,25 +215,42 @@ static void pc_q35_init(QEMUMachineInitArgs *args)
     }
 }
 
-static void pc_q35_init_1_6(QEMUMachineInitArgs *args)
+static void pc_compat_1_6(QEMUMachineInitArgs *args)
 {
     has_pci_info = false;
     rom_file_in_ram = false;
-    pc_q35_init(args);
 }
 
-static void pc_q35_init_1_5(QEMUMachineInitArgs *args)
+static void pc_compat_1_5(QEMUMachineInitArgs *args)
 {
+    pc_compat_1_6(args);
     has_pvpanic = true;
-    pc_q35_init_1_6(args);
 }
 
-static void pc_q35_init_1_4(QEMUMachineInitArgs *args)
+static void pc_compat_1_4(QEMUMachineInitArgs *args)
 {
+    /* 1.5 was special - it enabled pvpanic in builtin machine */
+    pc_compat_1_6(args);
     x86_cpu_compat_set_features("n270", FEAT_1_ECX, 0, CPUID_EXT_MOVBE);
     x86_cpu_compat_set_features("Westmere", FEAT_1_ECX, 0, CPUID_EXT_PCLMULQDQ);
-    /* 1.5 was special - it enabled pvpanic in builtin machine */
-    pc_q35_init_1_6(args);
+}
+
+static void pc_q35_init_1_6(QEMUMachineInitArgs *args)
+{
+    pc_compat_1_6(args);
+    pc_q35_init(args);
+}
+
+static void pc_q35_init_1_5(QEMUMachineInitArgs *args)
+{
+    pc_compat_1_5(args);
+    pc_q35_init(args);
+}
+
+static void pc_q35_init_1_4(QEMUMachineInitArgs *args)
+{
+    pc_compat_1_4(args);
+    pc_q35_init(args);
 }
 
 static QEMUMachine pc_q35_machine_v1_6 = {
commit 43a52ce65736adf9def7c2a9e5ba409814eb5dae
Author: Eduardo Habkost <ehabkost at redhat.com>
Date:   Wed Aug 21 15:14:42 2013 -0300

    pc: Kill pc_init_pci_1_0()
    
    The pc_init_pci_1_2()/pc_init_pci_1_0() split was made on commit
    6fd028f64f662c801fd5a54d0e3a1d2baeee93ea, in preparation for commit
    9953f8822cc316eec9962f0a2858c3439a80adec. The latter was reverted, so there's
    no reason to keep two separate functions that do exactly the same, anymore.
    
    Signed-off-by: Eduardo Habkost <ehabkost at redhat.com>
    Cc: Markus Armbruster <armbru at redhat.com>
    Signed-off-by: Michael S. Tsirkin <mst at redhat.com>

diff --git a/hw/i386/pc_piix.c b/hw/i386/pc_piix.c
index bbefea6..dd730b1 100644
--- a/hw/i386/pc_piix.c
+++ b/hw/i386/pc_piix.c
@@ -263,19 +263,13 @@ static void pc_init_pci_1_3(QEMUMachineInitArgs *args)
     pc_init_pci_1_4(args);
 }
 
-/* PC machine init function for pc-1.1 to pc-1.2 */
+/* PC machine init function for pc-0.14 to pc-1.2 */
 static void pc_init_pci_1_2(QEMUMachineInitArgs *args)
 {
     disable_kvm_pv_eoi();
     pc_init_pci_1_3(args);
 }
 
-/* PC machine init function for pc-0.14 to pc-1.0 */
-static void pc_init_pci_1_0(QEMUMachineInitArgs *args)
-{
-    pc_init_pci_1_2(args);
-}
-
 /* PC init function for pc-0.10 to pc-0.13, and reused by xenfv */
 static void pc_init_pci_no_kvmclock(QEMUMachineInitArgs *args)
 {
@@ -485,7 +479,7 @@ static QEMUMachine pc_machine_v1_1 = {
 static QEMUMachine pc_machine_v1_0 = {
     .name = "pc-1.0",
     .desc = "Standard PC",
-    .init = pc_init_pci_1_0,
+    .init = pc_init_pci_1_2,
     .max_cpus = 255,
     .compat_props = (GlobalProperty[]) {
         PC_COMPAT_1_0,
@@ -501,7 +495,7 @@ static QEMUMachine pc_machine_v1_0 = {
 static QEMUMachine pc_machine_v0_15 = {
     .name = "pc-0.15",
     .desc = "Standard PC",
-    .init = pc_init_pci_1_0,
+    .init = pc_init_pci_1_2,
     .max_cpus = 255,
     .compat_props = (GlobalProperty[]) {
         PC_COMPAT_0_15,
@@ -534,7 +528,7 @@ static QEMUMachine pc_machine_v0_15 = {
 static QEMUMachine pc_machine_v0_14 = {
     .name = "pc-0.14",
     .desc = "Standard PC",
-    .init = pc_init_pci_1_0,
+    .init = pc_init_pci_1_2,
     .max_cpus = 255,
     .compat_props = (GlobalProperty[]) {
         PC_COMPAT_0_14, 
commit 3b6fb9cab2e64804cdab5a61d1298ffd8b8dff85
Author: Markus Armbruster <armbru at redhat.com>
Date:   Wed Aug 21 15:14:41 2013 -0300

    pc: Don't explode QEMUMachineInitArgs into local variables needlessly
    
    Don't explode when the variable is used just a few times, and never
    changed.
    
    Signed-off-by: Markus Armbruster <armbru at redhat.com>
    Reviewed-by: Laszlo Ersek <lersek at redhat.com>
    Reviewed-by: Eduardo Habkost <ehabkost at redhat.com>
    Signed-off-by: Michael S. Tsirkin <mst at redhat.com>

diff --git a/hw/i386/pc_q35.c b/hw/i386/pc_q35.c
index 533a2d6..4847f46 100644
--- a/hw/i386/pc_q35.c
+++ b/hw/i386/pc_q35.c
@@ -53,12 +53,6 @@ static bool has_pci_info = true;
 /* PC hardware initialisation */
 static void pc_q35_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;
     ram_addr_t below_4g_mem_size, above_4g_mem_size;
     Q35PCIHost *q35_host;
     PCIHostState *phb;
@@ -86,17 +80,17 @@ static void pc_q35_init(QEMUMachineInitArgs *args)
     object_property_add_child(qdev_get_machine(), "icc-bridge",
                               OBJECT(icc_bridge), NULL);
 
-    pc_cpus_init(cpu_model, icc_bridge);
+    pc_cpus_init(args->cpu_model, icc_bridge);
     pc_acpi_init("q35-acpi-dsdt.aml");
 
     kvmclock_create();
 
-    if (ram_size >= 0xb0000000) {
-        above_4g_mem_size = ram_size - 0xb0000000;
+    if (args->ram_size >= 0xb0000000) {
+        above_4g_mem_size = args->ram_size - 0xb0000000;
         below_4g_mem_size = 0xb0000000;
     } else {
         above_4g_mem_size = 0;
-        below_4g_mem_size = ram_size;
+        below_4g_mem_size = args->ram_size;
     }
 
     /* pci enabled */
@@ -115,8 +109,10 @@ static void pc_q35_init(QEMUMachineInitArgs *args)
 
     /* allocate ram and load rom/bios */
     if (!xen_enabled()) {
-        pc_memory_init(get_system_memory(), kernel_filename, kernel_cmdline,
-                       initrd_filename, below_4g_mem_size, above_4g_mem_size,
+        pc_memory_init(get_system_memory(),
+                       args->kernel_filename, args->kernel_cmdline,
+                       args->initrd_filename,
+                       below_4g_mem_size, above_4g_mem_size,
                        rom_memory, &ram_memory, guest_info);
     }
 
@@ -204,7 +200,7 @@ static void pc_q35_init(QEMUMachineInitArgs *args)
                                     0xb100),
                       8, NULL, 0);
 
-    pc_cmos_init(below_4g_mem_size, above_4g_mem_size, boot_device,
+    pc_cmos_init(below_4g_mem_size, above_4g_mem_size, args->boot_device,
                  floppy, idebus[0], idebus[1], rtc_state);
 
     /* the rest devices to which pci devfn is automatically assigned */
commit 5650f5f48bfe2a684138505aae008dc4440202f1
Author: Markus Armbruster <armbru at redhat.com>
Date:   Wed Aug 21 15:14:40 2013 -0300

    pc: Don't prematurely explode QEMUMachineInitArgs
    
    Don't explode QEMUMachineInitArgs before passing it to pc_init1().
    
    Signed-off-by: Markus Armbruster <armbru at redhat.com>
    Reviewed-by: Laszlo Ersek <lersek at redhat.com>
    Reviewed-by: Eduardo Habkost <ehabkost at redhat.com>
    Signed-off-by: Michael S. Tsirkin <mst at redhat.com>

diff --git a/hw/i386/pc_piix.c b/hw/i386/pc_piix.c
index 4591027..bbefea6 100644
--- a/hw/i386/pc_piix.c
+++ b/hw/i386/pc_piix.c
@@ -61,14 +61,9 @@ static bool has_pvpanic;
 static bool has_pci_info = true;
 
 /* PC hardware initialisation */
-static void pc_init1(MemoryRegion *system_memory,
+static void pc_init1(QEMUMachineInitArgs *args,
+                     MemoryRegion *system_memory,
                      MemoryRegion *system_io,
-                     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,
                      int pci_enabled,
                      int kvmclock_enabled)
 {
@@ -103,18 +98,18 @@ static void pc_init1(MemoryRegion *system_memory,
     object_property_add_child(qdev_get_machine(), "icc-bridge",
                               OBJECT(icc_bridge), NULL);
 
-    pc_cpus_init(cpu_model, icc_bridge);
+    pc_cpus_init(args->cpu_model, icc_bridge);
 
     if (kvm_enabled() && kvmclock_enabled) {
         kvmclock_create();
     }
 
-    if (ram_size >= 0xe0000000 ) {
-        above_4g_mem_size = ram_size - 0xe0000000;
+    if (args->ram_size >= 0xe0000000) {
+        above_4g_mem_size = args->ram_size - 0xe0000000;
         below_4g_mem_size = 0xe0000000;
     } else {
         above_4g_mem_size = 0;
-        below_4g_mem_size = ram_size;
+        below_4g_mem_size = args->ram_size;
     }
 
     if (pci_enabled) {
@@ -133,7 +128,8 @@ static void pc_init1(MemoryRegion *system_memory,
     /* allocate ram and load rom/bios */
     if (!xen_enabled()) {
         fw_cfg = pc_memory_init(system_memory,
-                       kernel_filename, kernel_cmdline, initrd_filename,
+                       args->kernel_filename, args->kernel_cmdline,
+                       args->initrd_filename,
                        below_4g_mem_size, above_4g_mem_size,
                        rom_memory, &ram_memory, guest_info);
     }
@@ -149,7 +145,7 @@ static void pc_init1(MemoryRegion *system_memory,
 
     if (pci_enabled) {
         pci_bus = i440fx_init(&i440fx_state, &piix3_devfn, &isa_bus, gsi,
-                              system_memory, system_io, ram_size,
+                              system_memory, system_io, args->ram_size,
                               below_4g_mem_size,
                               0x100000000ULL - below_4g_mem_size,
                               above_4g_mem_size,
@@ -208,7 +204,7 @@ static void pc_init1(MemoryRegion *system_memory,
         }
     }
 
-    pc_cmos_init(below_4g_mem_size, above_4g_mem_size, boot_device,
+    pc_cmos_init(below_4g_mem_size, above_4g_mem_size, args->boot_device,
                  floppy, idebus[0], idebus[1], rtc_state);
 
     if (pci_enabled && usb_enabled(false)) {
@@ -237,17 +233,7 @@ static void pc_init1(MemoryRegion *system_memory,
 
 static void pc_init_pci(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;
-    pc_init1(get_system_memory(),
-             get_system_io(),
-             ram_size, boot_device,
-             kernel_filename, kernel_cmdline,
-             initrd_filename, cpu_model, 1, 1);
+    pc_init1(args, get_system_memory(), get_system_io(), 1, 1);
 }
 
 static void pc_init_pci_1_6(QEMUMachineInitArgs *args)
@@ -293,40 +279,21 @@ static void pc_init_pci_1_0(QEMUMachineInitArgs *args)
 /* PC init function for pc-0.10 to pc-0.13, and reused by xenfv */
 static void pc_init_pci_no_kvmclock(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;
     has_pci_info = false;
     disable_kvm_pv_eoi();
     enable_compat_apic_id_mode();
-    pc_init1(get_system_memory(),
-             get_system_io(),
-             ram_size, boot_device,
-             kernel_filename, kernel_cmdline,
-             initrd_filename, cpu_model, 1, 0);
+    pc_init1(args, get_system_memory(), get_system_io(), 1, 0);
 }
 
 static void pc_init_isa(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;
     has_pci_info = false;
-    if (cpu_model == NULL)
-        cpu_model = "486";
+    if (!args->cpu_model) {
+        args->cpu_model = "486";
+    }
     disable_kvm_pv_eoi();
     enable_compat_apic_id_mode();
-    pc_init1(get_system_memory(),
-             get_system_io(),
-             ram_size, boot_device,
-             kernel_filename, kernel_cmdline,
-             initrd_filename, cpu_model, 0, 1);
+    pc_init1(args, get_system_memory(), get_system_io(), 0, 1);
 }
 
 #ifdef CONFIG_XEN
commit 92238367450d26eced103736ae555997ea3162c2
Author: Markus Armbruster <armbru at redhat.com>
Date:   Fri Aug 16 13:13:49 2013 +0200

    ppc: Don't duplicate QEMUMachineInitArgs in PPCE500Params
    
    Pass on the generic arguments unadulterated, and the machine-specific
    ones as separate argument.
    
    Signed-off-by: Markus Armbruster <armbru at redhat.com>
    Acked-by: Alexander Graf <agraf at suse.de>
    Reviewed-by: Laszlo Ersek <lersek at redhat.com>
    Signed-off-by: Michael S. Tsirkin <mst at redhat.com>

diff --git a/hw/ppc/e500.c b/hw/ppc/e500.c
index f00a62a..e79612b 100644
--- a/hw/ppc/e500.c
+++ b/hw/ppc/e500.c
@@ -124,13 +124,14 @@ static void dt_serial_create(void *fdt, unsigned long long offset,
 }
 
 static int ppce500_load_device_tree(CPUPPCState *env,
+                                    QEMUMachineInitArgs *args,
                                     PPCE500Params *params,
                                     hwaddr addr,
                                     hwaddr initrd_base,
                                     hwaddr initrd_size)
 {
     int ret = -1;
-    uint64_t mem_reg_property[] = { 0, cpu_to_be64(params->ram_size) };
+    uint64_t mem_reg_property[] = { 0, cpu_to_be64(args->ram_size) };
     int fdt_size;
     void *fdt;
     uint8_t hypercall[16];
@@ -205,7 +206,7 @@ static int ppce500_load_device_tree(CPUPPCState *env,
     }
 
     ret = qemu_devtree_setprop_string(fdt, "/chosen", "bootargs",
-                                      params->kernel_cmdline);
+                                      args->kernel_cmdline);
     if (ret < 0)
         fprintf(stderr, "couldn't set /chosen/bootargs\n");
 
@@ -559,7 +560,7 @@ static qemu_irq *ppce500_init_mpic(PPCE500Params *params, MemoryRegion *ccsr,
     return mpic;
 }
 
-void ppce500_init(PPCE500Params *params)
+void ppce500_init(QEMUMachineInitArgs *args, PPCE500Params *params)
 {
     MemoryRegion *address_space_mem = get_system_memory();
     MemoryRegion *ram = g_new(MemoryRegion, 1);
@@ -584,8 +585,8 @@ void ppce500_init(PPCE500Params *params)
     PPCE500CCSRState *ccsr;
 
     /* Setup CPUs */
-    if (params->cpu_model == NULL) {
-        params->cpu_model = "e500v2_v30";
+    if (args->cpu_model == NULL) {
+        args->cpu_model = "e500v2_v30";
     }
 
     irqs = g_malloc0(smp_cpus * sizeof(qemu_irq *));
@@ -595,7 +596,7 @@ void ppce500_init(PPCE500Params *params)
         CPUState *cs;
         qemu_irq *input;
 
-        cpu = cpu_ppc_init(params->cpu_model);
+        cpu = cpu_ppc_init(args->cpu_model);
         if (cpu == NULL) {
             fprintf(stderr, "Unable to initialize CPU!\n");
             exit(1);
@@ -634,7 +635,7 @@ void ppce500_init(PPCE500Params *params)
 
     /* Fixup Memory size on a alignment boundary */
     ram_size &= ~(RAM_SIZES_ALIGN - 1);
-    params->ram_size = ram_size;
+    args->ram_size = ram_size;
 
     /* Register Memory */
     memory_region_init_ram(ram, NULL, "mpc8544ds.ram", ram_size);
@@ -701,11 +702,11 @@ void ppce500_init(PPCE500Params *params)
     sysbus_create_simple("e500-spin", MPC8544_SPIN_BASE, NULL);
 
     /* Load kernel. */
-    if (params->kernel_filename) {
-        kernel_size = load_uimage(params->kernel_filename, &entry,
+    if (args->kernel_filename) {
+        kernel_size = load_uimage(args->kernel_filename, &entry,
                                   &loadaddr, NULL);
         if (kernel_size < 0) {
-            kernel_size = load_elf(params->kernel_filename, NULL, NULL,
+            kernel_size = load_elf(args->kernel_filename, NULL, NULL,
                                    &elf_entry, &elf_lowaddr, NULL, 1,
                                    ELF_MACHINE, 0);
             entry = elf_entry;
@@ -714,7 +715,7 @@ void ppce500_init(PPCE500Params *params)
         /* XXX try again as binary */
         if (kernel_size < 0) {
             fprintf(stderr, "qemu: could not load kernel '%s'\n",
-                    params->kernel_filename);
+                    args->kernel_filename);
             exit(1);
         }
 
@@ -726,14 +727,14 @@ void ppce500_init(PPCE500Params *params)
     }
 
     /* Load initrd. */
-    if (params->initrd_filename) {
+    if (args->initrd_filename) {
         initrd_base = (cur_base + INITRD_LOAD_PAD) & ~INITRD_PAD_MASK;
-        initrd_size = load_image_targphys(params->initrd_filename, initrd_base,
+        initrd_size = load_image_targphys(args->initrd_filename, initrd_base,
                                           ram_size - initrd_base);
 
         if (initrd_size < 0) {
             fprintf(stderr, "qemu: could not load initial ram disk '%s'\n",
-                    params->initrd_filename);
+                    args->initrd_filename);
             exit(1);
         }
 
@@ -741,12 +742,12 @@ void ppce500_init(PPCE500Params *params)
     }
 
     /* If we're loading a kernel directly, we must load the device tree too. */
-    if (params->kernel_filename) {
+    if (args->kernel_filename) {
         struct boot_info *boot_info;
         int dt_size;
 
-        dt_size = ppce500_load_device_tree(env, params, dt_base, initrd_base,
-                                           initrd_size);
+        dt_size = ppce500_load_device_tree(env, args, params, dt_base,
+                                           initrd_base, initrd_size);
         if (dt_size < 0) {
             fprintf(stderr, "couldn't load device tree\n");
             exit(1);
diff --git a/hw/ppc/e500.h b/hw/ppc/e500.h
index 226c93d..52726a2 100644
--- a/hw/ppc/e500.h
+++ b/hw/ppc/e500.h
@@ -1,25 +1,18 @@
 #ifndef PPCE500_H
 #define PPCE500_H
 
+#include "hw/boards.h"
+
 typedef struct PPCE500Params {
-    /* Standard QEMU machine init params */
-    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;
     int pci_first_slot;
     int pci_nr_slots;
 
-    /* e500-specific params */
-
     /* required -- must at least add toplevel board compatible */
     void (*fixup_devtree)(struct PPCE500Params *params, void *fdt);
 
     int mpic_version;
 } PPCE500Params;
 
-void ppce500_init(PPCE500Params *params);
+void ppce500_init(QEMUMachineInitArgs *args, PPCE500Params *params);
 
 #endif
diff --git a/hw/ppc/e500plat.c b/hw/ppc/e500plat.c
index a78de07..bf65b69 100644
--- a/hw/ppc/e500plat.c
+++ b/hw/ppc/e500plat.c
@@ -31,12 +31,6 @@ static void e500plat_fixup_devtree(PPCE500Params *params, void *fdt)
 static void e500plat_init(QEMUMachineInitArgs *args)
 {
     PPCE500Params params = {
-        .ram_size = args->ram_size,
-        .boot_device = args->boot_device,
-        .kernel_filename = args->kernel_filename,
-        .kernel_cmdline = args->kernel_cmdline,
-        .initrd_filename = args->initrd_filename,
-        .cpu_model = args->cpu_model,
         .pci_first_slot = 0x1,
         .pci_nr_slots = PCI_SLOT_MAX - 1,
         .fixup_devtree = e500plat_fixup_devtree,
@@ -49,7 +43,7 @@ static void e500plat_init(QEMUMachineInitArgs *args)
         params.mpic_version = OPENPIC_MODEL_FSL_MPIC_20;
     }
 
-    ppce500_init(&params);
+    ppce500_init(args, &params);
 }
 
 static QEMUMachine e500plat_machine = {
diff --git a/hw/ppc/mpc8544ds.c b/hw/ppc/mpc8544ds.c
index 4e551af..1888e75 100644
--- a/hw/ppc/mpc8544ds.c
+++ b/hw/ppc/mpc8544ds.c
@@ -29,19 +29,13 @@ static void mpc8544ds_fixup_devtree(PPCE500Params *params, void *fdt)
 static void mpc8544ds_init(QEMUMachineInitArgs *args)
 {
     PPCE500Params params = {
-        .ram_size = args->ram_size,
-        .boot_device = args->boot_device,
-        .kernel_filename = args->kernel_filename,
-        .kernel_cmdline = args->kernel_cmdline,
-        .initrd_filename = args->initrd_filename,
-        .cpu_model = args->cpu_model,
         .pci_first_slot = 0x11,
         .pci_nr_slots = 2,
         .fixup_devtree = mpc8544ds_fixup_devtree,
         .mpic_version = OPENPIC_MODEL_FSL_MPIC_20,
     };
 
-    ppce500_init(&params);
+    ppce500_init(args, &params);
 }
 
 
commit ee87e32f830b4e22c02038de963bb9f72b55896f
Author: Markus Armbruster <armbru at redhat.com>
Date:   Fri Aug 16 13:13:48 2013 +0200

    ppc: Don't explode QEMUMachineInitArgs into local variables needlessly
    
    Don't explode when the variable is used just once, and never changed.
    
    Signed-off-by: Markus Armbruster <armbru at redhat.com>
    Acked-by: Alexander Graf <agraf at suse.de>
    Reviewed-by: Laszlo Ersek <lersek at redhat.com>
    Signed-off-by: Michael S. Tsirkin <mst at redhat.com>

diff --git a/hw/ppc/e500plat.c b/hw/ppc/e500plat.c
index c852995..a78de07 100644
--- a/hw/ppc/e500plat.c
+++ b/hw/ppc/e500plat.c
@@ -30,19 +30,13 @@ static void e500plat_fixup_devtree(PPCE500Params *params, void *fdt)
 
 static void e500plat_init(QEMUMachineInitArgs *args)
 {
-    ram_addr_t ram_size = args->ram_size;
-    const char *boot_device = args->boot_device;
-    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;
     PPCE500Params params = {
-        .ram_size = ram_size,
-        .boot_device = boot_device,
-        .kernel_filename = kernel_filename,
-        .kernel_cmdline = kernel_cmdline,
-        .initrd_filename = initrd_filename,
-        .cpu_model = cpu_model,
+        .ram_size = args->ram_size,
+        .boot_device = args->boot_device,
+        .kernel_filename = args->kernel_filename,
+        .kernel_cmdline = args->kernel_cmdline,
+        .initrd_filename = args->initrd_filename,
+        .cpu_model = args->cpu_model,
         .pci_first_slot = 0x1,
         .pci_nr_slots = PCI_SLOT_MAX - 1,
         .fixup_devtree = e500plat_fixup_devtree,
diff --git a/hw/ppc/mpc8544ds.c b/hw/ppc/mpc8544ds.c
index 444da02..4e551af 100644
--- a/hw/ppc/mpc8544ds.c
+++ b/hw/ppc/mpc8544ds.c
@@ -28,19 +28,13 @@ static void mpc8544ds_fixup_devtree(PPCE500Params *params, void *fdt)
 
 static void mpc8544ds_init(QEMUMachineInitArgs *args)
 {
-    ram_addr_t ram_size = args->ram_size;
-    const char *boot_device = args->boot_device;
-    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;
     PPCE500Params params = {
-        .ram_size = ram_size,
-        .boot_device = boot_device,
-        .kernel_filename = kernel_filename,
-        .kernel_cmdline = kernel_cmdline,
-        .initrd_filename = initrd_filename,
-        .cpu_model = cpu_model,
+        .ram_size = args->ram_size,
+        .boot_device = args->boot_device,
+        .kernel_filename = args->kernel_filename,
+        .kernel_cmdline = args->kernel_cmdline,
+        .initrd_filename = args->initrd_filename,
+        .cpu_model = args->cpu_model,
         .pci_first_slot = 0x11,
         .pci_nr_slots = 2,
         .fixup_devtree = mpc8544ds_fixup_devtree,
commit 6b63ef4d0f225810b74281e6689a4d5695860c08
Author: Markus Armbruster <armbru at redhat.com>
Date:   Fri Aug 16 13:13:47 2013 +0200

    sun4: Don't prematurely explode QEMUMachineInitArgs
    
    Don't explode QEMUMachineInitArgs before passing it to
    sun4m_hw_init(), sun4uv_init().
    
    Signed-off-by: Markus Armbruster <armbru at redhat.com>
    Reviewed-by: Laszlo Ersek <lersek at redhat.com>
    Signed-off-by: Michael S. Tsirkin <mst at redhat.com>

diff --git a/hw/sparc/sun4m.c b/hw/sparc/sun4m.c
index 942ca37..36ef36f 100644
--- a/hw/sparc/sun4m.c
+++ b/hw/sparc/sun4m.c
@@ -836,12 +836,10 @@ static void dummy_fdc_tc(void *opaque, int irq, int level)
 {
 }
 
-static void sun4m_hw_init(const struct sun4m_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)
+static void sun4m_hw_init(const struct sun4m_hwdef *hwdef,
+                          QEMUMachineInitArgs *args)
 {
+    const char *cpu_model = args->cpu_model;
     unsigned int i;
     void *iommu, *espdma, *ledma, *nvram;
     qemu_irq *cpu_irqs[MAX_CPUS], slavio_irq[32], slavio_cpu_irq[MAX_CPUS],
@@ -867,10 +865,10 @@ static void sun4m_hw_init(const struct sun4m_hwdef *hwdef, ram_addr_t RAM_size,
 
 
     /* set up devices */
-    ram_init(0, RAM_size, hwdef->max_mem);
+    ram_init(0, args->ram_size, hwdef->max_mem);
     /* models without ECC don't trap when missing ram is accessed */
     if (!hwdef->ecc_base) {
-        empty_slot_init(RAM_size, hwdef->max_mem - RAM_size);
+        empty_slot_init(args->ram_size, hwdef->max_mem - args->ram_size);
     }
 
     prom_init(hwdef->slavio_base, bios_name);
@@ -993,11 +991,12 @@ static void sun4m_hw_init(const struct sun4m_hwdef *hwdef, ram_addr_t RAM_size,
         empty_slot_init(hwdef->bpp_base, 0x20);
     }
 
-    kernel_size = sun4m_load_kernel(kernel_filename, initrd_filename,
-                                    RAM_size);
+    kernel_size = sun4m_load_kernel(args->kernel_filename,
+                                    args->initrd_filename,
+                                    args->ram_size);
 
-    nvram_init(nvram, (uint8_t *)&nd_table[0].macaddr, kernel_cmdline,
-               boot_device, RAM_size, kernel_size, graphic_width,
+    nvram_init(nvram, (uint8_t *)&nd_table[0].macaddr, args->kernel_cmdline,
+               args->boot_device, args->ram_size, kernel_size, graphic_width,
                graphic_height, graphic_depth, hwdef->nvram_machine_id,
                "Sun4m");
 
@@ -1015,19 +1014,20 @@ static void sun4m_hw_init(const struct sun4m_hwdef *hwdef, ram_addr_t RAM_size,
     fw_cfg_add_i16(fw_cfg, FW_CFG_SUN4M_HEIGHT, graphic_height);
     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) {
+    if (args->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);
+        pstrcpy_targphys("cmdline", CMDLINE_ADDR, TARGET_PAGE_SIZE,
+                         args->kernel_cmdline);
+        fw_cfg_add_string(fw_cfg, FW_CFG_CMDLINE_DATA, args->kernel_cmdline);
         fw_cfg_add_i32(fw_cfg, FW_CFG_CMDLINE_SIZE,
-                       strlen(kernel_cmdline) + 1);
+                       strlen(args->kernel_cmdline) + 1);
     } else {
         fw_cfg_add_i32(fw_cfg, FW_CFG_KERNEL_CMDLINE, 0);
         fw_cfg_add_i32(fw_cfg, FW_CFG_CMDLINE_SIZE, 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]);
+    fw_cfg_add_i16(fw_cfg, FW_CFG_BOOT_DEVICE, args->boot_device[0]);
     qemu_register_boot_set(fw_cfg_boot_set, fw_cfg);
 }
 
@@ -1291,118 +1291,55 @@ static const struct sun4m_hwdef sun4m_hwdefs[] = {
 /* SPARCstation 5 hardware initialisation */
 static void ss5_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;
-    sun4m_hw_init(&sun4m_hwdefs[0], RAM_size, boot_device, kernel_filename,
-                  kernel_cmdline, initrd_filename, cpu_model);
+    sun4m_hw_init(&sun4m_hwdefs[0], args);
 }
 
 /* SPARCstation 10 hardware initialisation */
 static void ss10_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;
-    sun4m_hw_init(&sun4m_hwdefs[1], RAM_size, boot_device, kernel_filename,
-                  kernel_cmdline, initrd_filename, cpu_model);
+    sun4m_hw_init(&sun4m_hwdefs[1], args);
 }
 
 /* SPARCserver 600MP hardware initialisation */
 static void ss600mp_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;
-    sun4m_hw_init(&sun4m_hwdefs[2], RAM_size, boot_device, kernel_filename,
-                  kernel_cmdline, initrd_filename, cpu_model);
+    sun4m_hw_init(&sun4m_hwdefs[2], args);
 }
 
 /* SPARCstation 20 hardware initialisation */
 static void ss20_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;
-    sun4m_hw_init(&sun4m_hwdefs[3], RAM_size, boot_device, kernel_filename,
-                  kernel_cmdline, initrd_filename, cpu_model);
+    sun4m_hw_init(&sun4m_hwdefs[3], args);
 }
 
 /* SPARCstation Voyager hardware initialisation */
 static void vger_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;
-    sun4m_hw_init(&sun4m_hwdefs[4], RAM_size, boot_device, kernel_filename,
-                  kernel_cmdline, initrd_filename, cpu_model);
+    sun4m_hw_init(&sun4m_hwdefs[4], args);
 }
 
 /* SPARCstation LX hardware initialisation */
 static void ss_lx_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;
-    sun4m_hw_init(&sun4m_hwdefs[5], RAM_size, boot_device, kernel_filename,
-                  kernel_cmdline, initrd_filename, cpu_model);
+    sun4m_hw_init(&sun4m_hwdefs[5], args);
 }
 
 /* SPARCstation 4 hardware initialisation */
 static void ss4_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;
-    sun4m_hw_init(&sun4m_hwdefs[6], RAM_size, boot_device, kernel_filename,
-                  kernel_cmdline, initrd_filename, cpu_model);
+    sun4m_hw_init(&sun4m_hwdefs[6], args);
 }
 
 /* SPARCClassic hardware initialisation */
 static void scls_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;
-    sun4m_hw_init(&sun4m_hwdefs[7], RAM_size, boot_device, kernel_filename,
-                  kernel_cmdline, initrd_filename, cpu_model);
+    sun4m_hw_init(&sun4m_hwdefs[7], args);
 }
 
 /* SPARCbook hardware initialisation */
 static void sbook_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;
-    sun4m_hw_init(&sun4m_hwdefs[8], RAM_size, boot_device, kernel_filename,
-                  kernel_cmdline, initrd_filename, cpu_model);
+    sun4m_hw_init(&sun4m_hwdefs[8], args);
 }
 
 static QEMUMachine ss5_machine = {
diff --git a/hw/sparc64/sun4u.c b/hw/sparc64/sun4u.c
index a7214a3..8bd7fb9 100644
--- a/hw/sparc64/sun4u.c
+++ b/hw/sparc64/sun4u.c
@@ -811,10 +811,7 @@ static SPARCCPU *cpu_devinit(const char *cpu_model, const struct hwdef *hwdef)
 }
 
 static void sun4uv_init(MemoryRegion *address_space_mem,
-                        ram_addr_t RAM_size,
-                        const char *boot_devices,
-                        const char *kernel_filename, const char *kernel_cmdline,
-                        const char *initrd_filename, const char *cpu_model,
+                        QEMUMachineInitArgs *args,
                         const struct hwdef *hwdef)
 {
     SPARCCPU *cpu;
@@ -829,10 +826,10 @@ static void sun4uv_init(MemoryRegion *address_space_mem,
     FWCfgState *fw_cfg;
 
     /* init CPUs */
-    cpu = cpu_devinit(cpu_model, hwdef);
+    cpu = cpu_devinit(args->cpu_model, hwdef);
 
     /* set up devices */
-    ram_init(0, RAM_size);
+    ram_init(0, args->ram_size);
 
     prom_init(hwdef->prom_addr, bios_name);
 
@@ -878,13 +875,15 @@ static void sun4uv_init(MemoryRegion *address_space_mem,
 
     initrd_size = 0;
     initrd_addr = 0;
-    kernel_size = sun4u_load_kernel(kernel_filename, initrd_filename,
+    kernel_size = sun4u_load_kernel(args->kernel_filename,
+                                    args->initrd_filename,
                                     ram_size, &initrd_size, &initrd_addr,
                                     &kernel_addr, &kernel_entry);
 
-    sun4u_NVRAM_set_params(nvram, NVRAM_SIZE, "Sun4u", RAM_size, boot_devices,
+    sun4u_NVRAM_set_params(nvram, NVRAM_SIZE, "Sun4u", args->ram_size,
+                           args->boot_device,
                            kernel_addr, kernel_size,
-                           kernel_cmdline,
+                           args->kernel_cmdline,
                            initrd_addr, initrd_size,
                            /* XXX: need an option to load a NVRAM image */
                            0,
@@ -898,16 +897,16 @@ static void sun4uv_init(MemoryRegion *address_space_mem,
     fw_cfg_add_i16(fw_cfg, FW_CFG_MACHINE_ID, hwdef->machine_id);
     fw_cfg_add_i64(fw_cfg, FW_CFG_KERNEL_ADDR, kernel_entry);
     fw_cfg_add_i64(fw_cfg, FW_CFG_KERNEL_SIZE, kernel_size);
-    if (kernel_cmdline) {
+    if (args->kernel_cmdline) {
         fw_cfg_add_i32(fw_cfg, FW_CFG_CMDLINE_SIZE,
-                       strlen(kernel_cmdline) + 1);
-        fw_cfg_add_string(fw_cfg, FW_CFG_CMDLINE_DATA, kernel_cmdline);
+                       strlen(args->kernel_cmdline) + 1);
+        fw_cfg_add_string(fw_cfg, FW_CFG_CMDLINE_DATA, args->kernel_cmdline);
     } else {
         fw_cfg_add_i32(fw_cfg, FW_CFG_CMDLINE_SIZE, 0);
     }
     fw_cfg_add_i64(fw_cfg, FW_CFG_INITRD_ADDR, initrd_addr);
     fw_cfg_add_i64(fw_cfg, FW_CFG_INITRD_SIZE, initrd_size);
-    fw_cfg_add_i16(fw_cfg, FW_CFG_BOOT_DEVICE, boot_devices[0]);
+    fw_cfg_add_i16(fw_cfg, FW_CFG_BOOT_DEVICE, args->boot_device[0]);
 
     fw_cfg_add_i16(fw_cfg, FW_CFG_SPARC64_WIDTH, graphic_width);
     fw_cfg_add_i16(fw_cfg, FW_CFG_SPARC64_HEIGHT, graphic_height);
@@ -949,40 +948,19 @@ static const struct hwdef hwdefs[] = {
 /* Sun4u hardware initialisation */
 static void sun4u_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_devices = args->boot_device;
-    sun4uv_init(get_system_memory(), RAM_size, boot_devices, kernel_filename,
-                kernel_cmdline, initrd_filename, cpu_model, &hwdefs[0]);
+    sun4uv_init(get_system_memory(), args, &hwdefs[0]);
 }
 
 /* Sun4v hardware initialisation */
 static void sun4v_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_devices = args->boot_device;
-    sun4uv_init(get_system_memory(), RAM_size, boot_devices, kernel_filename,
-                kernel_cmdline, initrd_filename, cpu_model, &hwdefs[1]);
+    sun4uv_init(get_system_memory(), args, &hwdefs[1]);
 }
 
 /* Niagara hardware initialisation */
 static void niagara_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_devices = args->boot_device;
-    sun4uv_init(get_system_memory(), RAM_size, boot_devices, kernel_filename,
-                kernel_cmdline, initrd_filename, cpu_model, &hwdefs[2]);
+    sun4uv_init(get_system_memory(), args, &hwdefs[2]);
 }
 
 static QEMUMachine sun4u_machine = {
commit 8ad1898cf1f5314731123afce057e5cf74fd2f01
Author: Kevin Wolf <kwolf at redhat.com>
Date:   Mon Aug 19 10:38:01 2013 +0200

    qcow2: Change default for new images to compat=1.1
    
    By the time that qemu 1.7 will be released, enough time will have passed
    since qemu 1.1, which is the first version to understand version 3
    images, that changing the default shouldn't hurt many people any more
    and the benefits of using the new format outweigh the pain.
    
    qemu-iotests already runs with compat=1.1 by default.
    
    Signed-off-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: Stefan Hajnoczi <stefanha at redhat.com>

diff --git a/block/qcow2.c b/block/qcow2.c
index 3376901..42ea7ec 100644
--- a/block/qcow2.c
+++ b/block/qcow2.c
@@ -1402,7 +1402,7 @@ static int qcow2_create(const char *filename, QEMUOptionParameter *options)
     int flags = 0;
     size_t cluster_size = DEFAULT_CLUSTER_SIZE;
     int prealloc = 0;
-    int version = 2;
+    int version = 3;
 
     /* Read out options */
     while (options && options->name) {
commit 4b38e989b43e84c485f676f2039f21b15da439fe
Author: Alex Williamson <alex.williamson at redhat.com>
Date:   Tue Aug 20 12:21:57 2013 -0600

    q35: Add PCIe switch to example q35 configuration
    
    Signed-off-by: Alex Williamson <alex.williamson at redhat.com>
    Signed-off-by: Michael S. Tsirkin <mst at redhat.com>

diff --git a/docs/q35-chipset.cfg b/docs/q35-chipset.cfg
index 1b6efc0..e4ddb7d 100644
--- a/docs/q35-chipset.cfg
+++ b/docs/q35-chipset.cfg
@@ -91,6 +91,29 @@
   port = "4"
   chassis = "4"
 
+##
+# Example PCIe switch with two downstream ports
+#
+#[device "pcie-switch-upstream-port-1"]
+#  driver = "x3130-upstream"
+#  bus = "ich9-pcie-port-4"
+#  addr = "00.0"
+#
+#[device "pcie-switch-downstream-port-1-1"]
+#  driver = "xio3130-downstream"
+#  multifunction = "on"
+#  bus = "pcie-switch-upstream-port-1"
+#  addr = "00.0"
+#  port = "1"
+#  chassis = "5"
+#
+#[device "pcie-switch-downstream-port-1-2"]
+#  driver = "xio3130-downstream"
+#  multifunction = "on"
+#  bus = "pcie-switch-upstream-port-1"
+#  addr = "00.1"
+#  port = "1"
+#  chassis = "6"
 
 [device "ich9-ehci-1"]
   driver = "ich9-usb-ehci1"
commit 7717f248eebdcfe6de400404d0cf65dcb3633308
Author: Jia Liu <proljc at gmail.com>
Date:   Wed Aug 21 09:31:36 2013 +0800

    hw/openrisc: Avoid undefined shift in openrisc_pic_cpu_handler()
    
    In C99 signed shift (1 << 31) is undefined behavior, since the result
    exceeds INT_MAX.  Use 1U instead and move the shift after the check.
    
    Signed-off-by: Xi Wang <xi.wang at gmail.com>
    Acked-by: Jia Liu <proljc at gmail.com>

diff --git a/hw/openrisc/pic_cpu.c b/hw/openrisc/pic_cpu.c
index 3fcee02..2af1d60 100644
--- a/hw/openrisc/pic_cpu.c
+++ b/hw/openrisc/pic_cpu.c
@@ -26,12 +26,14 @@ static void openrisc_pic_cpu_handler(void *opaque, int irq, int level)
 {
     OpenRISCCPU *cpu = (OpenRISCCPU *)opaque;
     CPUState *cs = CPU(cpu);
-    uint32_t irq_bit = 1 << irq;
+    uint32_t irq_bit;
 
     if (irq > 31 || irq < 0) {
         return;
     }
 
+    irq_bit = 1U << irq;
+
     if (level) {
         cpu->env.picsr |= irq_bit;
     } else {
commit ed396e2b2d256c1628de7c11841b509455a76c03
Author: Jia Liu <proljc at gmail.com>
Date:   Wed Aug 21 09:23:10 2013 +0800

    hw/openrisc: Fix masking in openrisc_pic_cpu_handler()
    
    Consider the masking of PICSR and PICMR:
    
        ((cpu->env.picsr && (1 << i)) && (cpu->env.picmr && (1 << i)))
    
    To correctly mask bits, we should use the bitwise AND "&" rather than
    the logical AND "&&".  Also, the loop is not necessary for masking.
    Simply use (cpu->env.picsr & cpu->env.picmr).
    
    Signed-off-by: Xi Wang <xi.wang at gmail.com>
    Acked-by: Jia Liu <proljc at gmail.com>

diff --git a/hw/openrisc/pic_cpu.c b/hw/openrisc/pic_cpu.c
index ca0b7c1..3fcee02 100644
--- a/hw/openrisc/pic_cpu.c
+++ b/hw/openrisc/pic_cpu.c
@@ -26,7 +26,6 @@ static void openrisc_pic_cpu_handler(void *opaque, int irq, int level)
 {
     OpenRISCCPU *cpu = (OpenRISCCPU *)opaque;
     CPUState *cs = CPU(cpu);
-    int i;
     uint32_t irq_bit = 1 << irq;
 
     if (irq > 31 || irq < 0) {
@@ -39,13 +38,11 @@ static void openrisc_pic_cpu_handler(void *opaque, int irq, int level)
         cpu->env.picsr &= ~irq_bit;
     }
 
-    for (i = 0; i < 32; i++) {
-        if ((cpu->env.picsr && (1 << i)) && (cpu->env.picmr && (1 << i))) {
-            cpu_interrupt(cs, CPU_INTERRUPT_HARD);
-        } else {
-            cpu_reset_interrupt(cs, CPU_INTERRUPT_HARD);
-            cpu->env.picsr &= ~(1 << i);
-        }
+    if (cpu->env.picsr & cpu->env.picmr) {
+        cpu_interrupt(cs, CPU_INTERRUPT_HARD);
+    } else {
+        cpu_reset_interrupt(cs, CPU_INTERRUPT_HARD);
+        cpu->env.picsr = 0;
     }
 }
 
commit b6d9766ddf5453e79e0c66c9348728ba44ba115f
Author: Jia Liu <proljc at gmail.com>
Date:   Wed Aug 21 08:54:29 2013 +0800

    hw/openrisc: Avoid using uninitialised variable 'entry'
    
    clang warns that cpu_openrisc_load_kernel() can use 'entry' uninitialized:
    
    hw/openrisc/openrisc_sim.c:69:9: error: variable 'entry' is used uninitialized
    whenever '&&' condition is false [-Werror,-Wsometimes-uninitialized]
    
        if (kernel_filename && !qtest_enabled()) {
            ^~~~~~~~~~~~~~~
    hw/openrisc/openrisc_sim.c:91:19: note: uninitialized use occurs here
        cpu->env.pc = entry;
                      ^~~~~
    
    Fix this by not attempting to change the CPU's starting PC unless
    we actually loaded a kernel.
    
    Signed-off-by: Peter Maydell <peter.maydell at linaro.org>
    Reviewed-by: Jia Liu <proljc at gmail.com>

diff --git a/hw/openrisc/openrisc_sim.c b/hw/openrisc/openrisc_sim.c
index a08f27c..28fa41d 100644
--- a/hw/openrisc/openrisc_sim.c
+++ b/hw/openrisc/openrisc_sim.c
@@ -86,9 +86,8 @@ static void cpu_openrisc_load_kernel(ram_addr_t ram_size,
                     kernel_filename);
             exit(1);
         }
+        cpu->env.pc = entry;
     }
-
-    cpu->env.pc = entry;
 }
 
 static void openrisc_sim_init(QEMUMachineInitArgs *args)
commit 04920fc0faa4760f9c4fc0e73b992b768099be70
Author: Michael S. Tsirkin <mst at redhat.com>
Date:   Mon Aug 19 17:26:55 2013 +0300

    loader: store FW CFG ROM files in RAM
    
    ROM files that are put in FW CFG are copied to guest ram, by BIOS, but
    they are not backed by RAM so they don't get migrated.
    
    Each time we change two bytes in such a ROM this breaks cross-version
    migration: since we can migrate after BIOS has read the first byte but
    before it has read the second one, getting an inconsistent state.
    
    Future-proof this by creating, for each such ROM,
    an MR serving as the backing store.
    This MR is never mapped into guest memory, but it's registered
    as RAM so it's migrated with the guest.
    
    Naturally, this only helps for -M 1.7 and up, older machine types
    will still have the cross-version migration bug.
    Luckily the race window for the problem to trigger is very small,
    which is also likely why we didn't notice the cross-version
    migration bug in testing yet.
    
    Signed-off-by: Michael S. Tsirkin <mst at redhat.com>
    Reviewed-by: Laszlo Ersek <lersek at redhat.com>

diff --git a/hw/core/loader.c b/hw/core/loader.c
index 6875b7e..7b3d3ee 100644
--- a/hw/core/loader.c
+++ b/hw/core/loader.c
@@ -54,6 +54,8 @@
 
 #include <zlib.h>
 
+bool rom_file_in_ram = true;
+
 static int roms_loaded;
 
 /* return the size or -1 if error */
@@ -576,6 +578,7 @@ struct Rom {
     size_t datasize;
 
     uint8_t *data;
+    MemoryRegion *mr;
     int isrom;
     char *fw_dir;
     char *fw_file;
@@ -605,6 +608,21 @@ static void rom_insert(Rom *rom)
     QTAILQ_INSERT_TAIL(&roms, rom, next);
 }
 
+static void *rom_set_mr(Rom *rom, Object *owner, const char *name)
+{
+    void *data;
+
+    rom->mr = g_malloc(sizeof(*rom->mr));
+    memory_region_init_ram(rom->mr, owner, name, rom->datasize);
+    memory_region_set_readonly(rom->mr, true);
+    vmstate_register_ram_global(rom->mr);
+
+    data = memory_region_get_ram_ptr(rom->mr);
+    memcpy(data, rom->data, rom->datasize);
+
+    return data;
+}
+
 int rom_add_file(const char *file, const char *fw_dir,
                  hwaddr addr, int32_t bootindex)
 {
@@ -646,6 +664,7 @@ int rom_add_file(const char *file, const char *fw_dir,
     if (rom->fw_file && fw_cfg) {
         const char *basename;
         char fw_file_name[56];
+        void *data;
 
         basename = strrchr(rom->fw_file, '/');
         if (basename) {
@@ -655,8 +674,15 @@ int rom_add_file(const char *file, const char *fw_dir,
         }
         snprintf(fw_file_name, sizeof(fw_file_name), "%s/%s", rom->fw_dir,
                  basename);
-        fw_cfg_add_file(fw_cfg, fw_file_name, rom->data, rom->romsize);
         snprintf(devpath, sizeof(devpath), "/rom@%s", fw_file_name);
+
+        if (rom_file_in_ram) {
+            data = rom_set_mr(rom, OBJECT(fw_cfg), devpath);
+        } else {
+            data = rom->data;
+        }
+
+        fw_cfg_add_file(fw_cfg, fw_file_name, data, rom->romsize);
     } else {
         snprintf(devpath, sizeof(devpath), "/rom@" TARGET_FMT_plx, addr);
     }
@@ -731,7 +757,12 @@ static void rom_reset(void *unused)
         if (rom->data == NULL) {
             continue;
         }
-        cpu_physical_memory_write_rom(rom->addr, rom->data, rom->datasize);
+        if (rom->mr) {
+            void *host = memory_region_get_ram_ptr(rom->mr);
+            memcpy(host, rom->data, rom->datasize);
+        } else {
+            cpu_physical_memory_write_rom(rom->addr, rom->data, rom->datasize);
+        }
         if (rom->isrom) {
             /* rom needs to be written only once */
             g_free(rom->data);
@@ -781,6 +812,9 @@ static Rom *find_rom(hwaddr addr)
         if (rom->fw_file) {
             continue;
         }
+        if (rom->mr) {
+            continue;
+        }
         if (rom->addr > addr) {
             continue;
         }
@@ -808,6 +842,9 @@ int rom_copy(uint8_t *dest, hwaddr addr, size_t size)
         if (rom->fw_file) {
             continue;
         }
+        if (rom->mr) {
+            continue;
+        }
         if (rom->addr + rom->romsize < addr) {
             continue;
         }
@@ -866,7 +903,13 @@ void do_info_roms(Monitor *mon, const QDict *qdict)
     Rom *rom;
 
     QTAILQ_FOREACH(rom, &roms, next) {
-        if (!rom->fw_file) {
+        if (rom->mr) {
+            monitor_printf(mon, "%s"
+                           " size=0x%06zx name=\"%s\"\n",
+                           rom->mr->name,
+                           rom->romsize,
+                           rom->name);
+        } else if (!rom->fw_file) {
             monitor_printf(mon, "addr=" TARGET_FMT_plx
                            " size=0x%06zx mem=%s name=\"%s\"\n",
                            rom->addr, rom->romsize,
diff --git a/hw/i386/pc_piix.c b/hw/i386/pc_piix.c
index 46f1fd7..4591027 100644
--- a/hw/i386/pc_piix.c
+++ b/hw/i386/pc_piix.c
@@ -25,6 +25,7 @@
 #include <glib.h>
 
 #include "hw/hw.h"
+#include "hw/loader.h"
 #include "hw/i386/pc.h"
 #include "hw/i386/apic.h"
 #include "hw/pci/pci.h"
@@ -252,6 +253,7 @@ static void pc_init_pci(QEMUMachineInitArgs *args)
 static void pc_init_pci_1_6(QEMUMachineInitArgs *args)
 {
     has_pci_info = false;
+    rom_file_in_ram = false;
     pc_init_pci(args);
 }
 
diff --git a/hw/i386/pc_q35.c b/hw/i386/pc_q35.c
index ab0aa70..533a2d6 100644
--- a/hw/i386/pc_q35.c
+++ b/hw/i386/pc_q35.c
@@ -28,6 +28,7 @@
  * THE SOFTWARE.
  */
 #include "hw/hw.h"
+#include "hw/loader.h"
 #include "sysemu/arch_init.h"
 #include "hw/i2c/smbus.h"
 #include "hw/boards.h"
@@ -221,6 +222,7 @@ static void pc_q35_init(QEMUMachineInitArgs *args)
 static void pc_q35_init_1_6(QEMUMachineInitArgs *args)
 {
     has_pci_info = false;
+    rom_file_in_ram = false;
     pc_q35_init(args);
 }
 
diff --git a/include/hw/loader.h b/include/hw/loader.h
index eb9c9a3..6145736 100644
--- a/include/hw/loader.h
+++ b/include/hw/loader.h
@@ -36,6 +36,7 @@ void pstrcpy_targphys(const char *name,
                       hwaddr dest, int buf_size,
                       const char *source);
 
+extern bool rom_file_in_ram;
 
 int rom_add_file(const char *file, const char *fw_dir,
                  hwaddr addr, int32_t bootindex);
commit 0851c9f75ccb0baf28f5bf901b9ffe3c91fcf969
Author: Michael S. Tsirkin <mst at redhat.com>
Date:   Mon Aug 19 17:26:52 2013 +0300

    arch_init: align MR size to target page size
    
    Migration code assumes that each MR is a multiple of TARGET_PAGE_SIZE:
    MR size is divided by TARGET_PAGE_SIZE, so if it isn't migration
    never completes.
    But this isn't really required for regions set up with
    memory_region_init_ram, since that calls qemu_ram_alloc
    which aligns size up using TARGET_PAGE_ALIGN.
    
    Align MR size up to full target page sizes, this way
    migration completes even if we create a RAM MR
    which is not a full target page size.
    
    Signed-off-by: Michael S. Tsirkin <mst at redhat.com>
    Reviewed-by: Laszlo Ersek <lersek at redhat.com>

diff --git a/arch_init.c b/arch_init.c
index 68a7ab7..ac8eb59 100644
--- a/arch_init.c
+++ b/arch_init.c
@@ -342,7 +342,8 @@ ram_addr_t migration_bitmap_find_and_reset_dirty(MemoryRegion *mr,
 {
     unsigned long base = mr->ram_addr >> TARGET_PAGE_BITS;
     unsigned long nr = base + (start >> TARGET_PAGE_BITS);
-    unsigned long size = base + (int128_get64(mr->size) >> TARGET_PAGE_BITS);
+    uint64_t mr_size = TARGET_PAGE_ALIGN(memory_region_size(mr));
+    unsigned long size = base + (mr_size >> TARGET_PAGE_BITS);
 
     unsigned long next;
 
commit c0b4cc1f9f4df9d7459dc778e64f00a4e781fd88
Author: Michael S. Tsirkin <mst at redhat.com>
Date:   Sun Aug 18 16:50:02 2013 +0300

    pc: cleanup 1.4 compat support
    
    Make 1.4 compat code call the 1.6 one, reducing
    code duplication. Add comment explaining why we can't
    make 1.4 call 1.5 as usual.
    
    Signed-off-by: Michael S. Tsirkin <mst at redhat.com>
    Reviewed-by: Andreas Färber <afaerber at suse.de>
    Reviewed-by: Eduardo Habkost <ehabkost at redhat.com>

diff --git a/hw/i386/pc_piix.c b/hw/i386/pc_piix.c
index 6e1e654..46f1fd7 100644
--- a/hw/i386/pc_piix.c
+++ b/hw/i386/pc_piix.c
@@ -265,8 +265,8 @@ static void pc_init_pci_1_4(QEMUMachineInitArgs *args)
 {
     x86_cpu_compat_set_features("n270", FEAT_1_ECX, 0, CPUID_EXT_MOVBE);
     x86_cpu_compat_set_features("Westmere", FEAT_1_ECX, 0, CPUID_EXT_PCLMULQDQ);
-    has_pci_info = false;
-    pc_init_pci(args);
+    /* 1.5 was special - it enabled pvpanic in builtin machine */
+    pc_init_pci_1_6(args);
 }
 
 static void pc_init_pci_1_3(QEMUMachineInitArgs *args)
diff --git a/hw/i386/pc_q35.c b/hw/i386/pc_q35.c
index 10e770e..ab0aa70 100644
--- a/hw/i386/pc_q35.c
+++ b/hw/i386/pc_q35.c
@@ -234,8 +234,8 @@ static void pc_q35_init_1_4(QEMUMachineInitArgs *args)
 {
     x86_cpu_compat_set_features("n270", FEAT_1_ECX, 0, CPUID_EXT_MOVBE);
     x86_cpu_compat_set_features("Westmere", FEAT_1_ECX, 0, CPUID_EXT_PCLMULQDQ);
-    has_pci_info = false;
-    pc_q35_init(args);
+    /* 1.5 was special - it enabled pvpanic in builtin machine */
+    pc_q35_init_1_6(args);
 }
 
 static QEMUMachine pc_q35_machine_v1_6 = {
commit 7477cd3897082d2650d520a4e9aa7f8affa3dd5d
Author: Marcelo Tosatti <mtosatti at redhat.com>
Date:   Mon Aug 19 14:13:42 2013 -0300

    kvm: i386: fix LAPIC TSC deadline timer save/restore
    
    The configuration of the timer represented by MSR_IA32_TSCDEADLINE depends on:
    
    - APIC LVT Timer register.
    - TSC value.
    
    Change the order to respect the dependency.
    
    Signed-off-by: Marcelo Tosatti <mtosatti at redhat.com>
    Signed-off-by: Paolo Bonzini <pbonzini at redhat.com>

diff --git a/target-i386/kvm.c b/target-i386/kvm.c
index 7bb8455..58f7bb7 100644
--- a/target-i386/kvm.c
+++ b/target-i386/kvm.c
@@ -1073,6 +1073,26 @@ static void kvm_msr_entry_set(struct kvm_msr_entry *entry,
     entry->data = value;
 }
 
+static int kvm_put_tscdeadline_msr(X86CPU *cpu)
+{
+    CPUX86State *env = &cpu->env;
+    struct {
+        struct kvm_msrs info;
+        struct kvm_msr_entry entries[1];
+    } msr_data;
+    struct kvm_msr_entry *msrs = msr_data.entries;
+
+    if (!has_msr_tsc_deadline) {
+        return 0;
+    }
+
+    kvm_msr_entry_set(&msrs[0], MSR_IA32_TSCDEADLINE, env->tsc_deadline);
+
+    msr_data.info.nmsrs = 1;
+
+    return kvm_vcpu_ioctl(CPU(cpu), KVM_SET_MSRS, &msr_data);
+}
+
 static int kvm_put_msrs(X86CPU *cpu, int level)
 {
     CPUX86State *env = &cpu->env;
@@ -1096,9 +1116,6 @@ static int kvm_put_msrs(X86CPU *cpu, int level)
     if (has_msr_tsc_adjust) {
         kvm_msr_entry_set(&msrs[n++], MSR_TSC_ADJUST, env->tsc_adjust);
     }
-    if (has_msr_tsc_deadline) {
-        kvm_msr_entry_set(&msrs[n++], MSR_IA32_TSCDEADLINE, env->tsc_deadline);
-    }
     if (has_msr_misc_enable) {
         kvm_msr_entry_set(&msrs[n++], MSR_IA32_MISC_ENABLE,
                           env->msr_ia32_misc_enable);
@@ -1808,6 +1825,12 @@ int kvm_arch_put_registers(CPUState *cpu, int level)
             return ret;
         }
     }
+
+    ret = kvm_put_tscdeadline_msr(x86_cpu);
+    if (ret < 0) {
+        return ret;
+    }
+
     ret = kvm_put_vcpu_events(x86_cpu, level);
     if (ret < 0) {
         return ret;
commit 7dc52526850849e8e0fe56ced809d0798481a2f6
Author: Marcelo Tosatti <mtosatti at redhat.com>
Date:   Mon Aug 12 16:56:31 2013 -0300

    kvm-all.c: max_cpus should not exceed KVM vcpu limit
    
    maxcpus, which specifies the maximum number of hotpluggable CPUs,
    should not exceed KVM's vcpu limit.
    
    Signed-off-by: Marcelo Tosatti <mtosatti at redhat.com>
    [Reword message. - Paolo]
    Signed-off-by: Paolo Bonzini <pbonzini at redhat.com>

diff --git a/kvm-all.c b/kvm-all.c
index ef52a0f..a2d4978 100644
--- a/kvm-all.c
+++ b/kvm-all.c
@@ -1400,6 +1400,13 @@ int kvm_init(void)
         goto err;
     }
 
+    if (max_cpus > max_vcpus) {
+        ret = -EINVAL;
+        fprintf(stderr, "Number of hotpluggable cpus requested (%d) exceeds max cpus "
+                "supported by KVM (%d)\n", max_cpus, max_vcpus);
+        goto err;
+    }
+
     s->vmfd = kvm_ioctl(s, KVM_CREATE_VM, 0);
     if (s->vmfd < 0) {
 #ifdef TARGET_S390X
commit 354678c5ce162649906e4e1be2859f3df372668f
Author: Jan Kiszka <jan.kiszka at siemens.com>
Date:   Tue Aug 13 14:43:57 2013 +0200

    kvm: Simplify kvm_handle_io
    
    Now that cpu_in/out is just a wrapper around address_space_rw, we can
    also call the latter directly. As host endianness == guest endianness,
    there is no need for the memory access helpers st*_p/ld*_p as well.
    
    Signed-off-by: Jan Kiszka <jan.kiszka at siemens.com>
    Signed-off-by: Paolo Bonzini <pbonzini at redhat.com>

diff --git a/kvm-all.c b/kvm-all.c
index bfa4aac..ef52a0f 100644
--- a/kvm-all.c
+++ b/kvm-all.c
@@ -1508,32 +1508,8 @@ static void kvm_handle_io(uint16_t port, void *data, int direction, int size,
     uint8_t *ptr = data;
 
     for (i = 0; i < count; i++) {
-        if (direction == KVM_EXIT_IO_IN) {
-            switch (size) {
-            case 1:
-                stb_p(ptr, cpu_inb(port));
-                break;
-            case 2:
-                stw_p(ptr, cpu_inw(port));
-                break;
-            case 4:
-                stl_p(ptr, cpu_inl(port));
-                break;
-            }
-        } else {
-            switch (size) {
-            case 1:
-                cpu_outb(port, ldub_p(ptr));
-                break;
-            case 2:
-                cpu_outw(port, lduw_p(ptr));
-                break;
-            case 4:
-                cpu_outl(port, ldl_p(ptr));
-                break;
-            }
-        }
-
+        address_space_rw(&address_space_io, port, ptr, size,
+                         direction == KVM_EXIT_IO_OUT);
         ptr += size;
     }
 }
commit df67696e97d3edd0cb1683bf2eb3b3236bd9a5ed
Author: Liu Jinsong <jinsong.liu at intel.com>
Date:   Mon Aug 19 09:33:30 2013 +0800

    kvm: x86: fix setting IA32_FEATURE_CONTROL with nested VMX disabled
    
    This patch is to fix the bug https://bugs.launchpad.net/qemu-kvm/+bug/1207623
    
    IA32_FEATURE_CONTROL is pointless if not expose VMX or SMX bits to
    cpuid.1.ecx of vcpu. Current qemu-kvm will error return when kvm_put_msrs
    or kvm_get_msrs.
    
    Signed-off-by: Liu Jinsong <jinsong.liu at intel.com>
    Signed-off-by: Paolo Bonzini <pbonzini at redhat.com>

diff --git a/target-i386/kvm.c b/target-i386/kvm.c
index 513ae52..7bb8455 100644
--- a/target-i386/kvm.c
+++ b/target-i386/kvm.c
@@ -65,6 +65,7 @@ static bool has_msr_star;
 static bool has_msr_hsave_pa;
 static bool has_msr_tsc_adjust;
 static bool has_msr_tsc_deadline;
+static bool has_msr_feature_control;
 static bool has_msr_async_pf_en;
 static bool has_msr_pv_eoi_en;
 static bool has_msr_misc_enable;
@@ -666,6 +667,12 @@ int kvm_arch_init_vcpu(CPUState *cs)
 
     qemu_add_vm_change_state_handler(cpu_update_state, env);
 
+    c = cpuid_find_entry(&cpuid_data.cpuid, 1, 0);
+    if (c) {
+        has_msr_feature_control = !!(c->ecx & CPUID_EXT_VMX) ||
+                                  !!(c->ecx & CPUID_EXT_SMX);
+    }
+
     cpuid_data.cpuid.padding = 0;
     r = kvm_vcpu_ioctl(cs, KVM_SET_CPUID2, &cpuid_data);
     if (r) {
@@ -1169,7 +1176,10 @@ static int kvm_put_msrs(X86CPU *cpu, int level)
         if (hyperv_vapic_recommended()) {
             kvm_msr_entry_set(&msrs[n++], HV_X64_MSR_APIC_ASSIST_PAGE, 0);
         }
-        kvm_msr_entry_set(&msrs[n++], MSR_IA32_FEATURE_CONTROL, env->msr_ia32_feature_control);
+        if (has_msr_feature_control) {
+            kvm_msr_entry_set(&msrs[n++], MSR_IA32_FEATURE_CONTROL,
+                              env->msr_ia32_feature_control);
+        }
     }
     if (env->mcg_cap) {
         int i;
@@ -1394,7 +1404,9 @@ static int kvm_get_msrs(X86CPU *cpu)
     if (has_msr_misc_enable) {
         msrs[n++].index = MSR_IA32_MISC_ENABLE;
     }
-    msrs[n++].index = MSR_IA32_FEATURE_CONTROL;
+    if (has_msr_feature_control) {
+        msrs[n++].index = MSR_IA32_FEATURE_CONTROL;
+    }
 
     if (!env->tsc_valid) {
         msrs[n++].index = MSR_IA32_TSC;
@@ -1509,6 +1521,7 @@ static int kvm_get_msrs(X86CPU *cpu)
             break;
         case MSR_IA32_FEATURE_CONTROL:
             env->msr_ia32_feature_control = msrs[i].data;
+            break;
         default:
             if (msrs[i].index >= MSR_MC0_CTL &&
                 msrs[i].index < MSR_MC0_CTL + (env->mcg_cap & 0xff) * 4) {
commit ecfe10c9a6f9bc77d0e4b7eb5d0f5d61e8fbaed8
Merge: 9176e8f 2300581
Author: Anthony Liguori <anthony at codemonkey.ws>
Date:   Tue Aug 20 11:23:52 2013 -0500

    Merge remote-tracking branch 'pmaydell/tags/pull-target-arm-20130820' into staging
    
    target-arm queue
    
    # gpg: Signature made Tue 20 Aug 2013 08:56:28 AM CDT using RSA key ID 14360CDE
    # gpg: Can't check signature: public key not found
    
    # By Peter Maydell (20) and Peter Chubb (1)
    # Via Peter Maydell
    * pmaydell/tags/pull-target-arm-20130820: (21 commits)
      hw/timer/imx_epit: Simplify and fix imx_epit implementation
      default-configs: Fix A9MP and A15MP config names
      hw/cpu/a15mpcore: Wire generic timer outputs to GIC inputs
      target-arm: Implement the generic timer
      target-arm: Support coprocessor registers which do I/O
      target-arm: Allow raw_read() and raw_write() to handle 64 bit regs
      hw/arm/pic_cpu: Remove the now-unneeded arm_pic_init_cpu()
      hw/arm/xilinx_zynq: Don't use arm_pic_init_cpu()
      hw/arm/vexpress: Don't use arm_pic_init_cpu()
      hw/arm/versatilepb: Don't use arm_pic_init_cpu()
      hw/arm/strongarm: Don't use arm_pic_init_cpu()
      hw/arm/realview: Don't use arm_pic_init_cpu()
      hw/arm/omap*: Don't use arm_pic_init_cpu()
      hw/arm/musicpal: Don't use arm_pic_init_cpu()
      hw/arm/kzm: Don't use arm_pic_init_cpu()
      hw/arm/integratorcp: Don't use arm_pic_init_cpu()
      hw/arm/highbank: Don't use arm_pic_init_cpu()
      hw/arm/exynos4210: Don't use arm_pic_init_cpu()
      hw/arm/armv7m: Don't use arm_pic_init_cpu()
      target-arm: Make IRQ and FIQ gpio lines on the CPU object
      ...
    
    Message-id: 1377007680-4934-1-git-send-email-peter.maydell at linaro.org
    Signed-off-by: Anthony Liguori <anthony at codemonkey.ws>

commit 21e0043bada1a24ae2ba6cd0051e104c0cbf9634
Author: Peter Maydell <peter.maydell at linaro.org>
Date:   Tue Aug 20 15:50:15 2013 +0100

    scripts/qapi.py: Avoid syntax not supported by Python 2.4
    
    The Python "except Foo as x" syntax was only introduced in
    Python 2.6, but we aim to support Python 2.4 and later.
    Use the old-style "except Foo, x" syntax instead, thus
    fixing configure/compile on systems with older Python.
    
    Signed-off-by: Peter Maydell <peter.maydell at linaro.org>
    Signed-off-by: Luiz Capitulino <lcapitulino at redhat.com>

diff --git a/scripts/qapi.py b/scripts/qapi.py
index 0ebea94..1069310 100644
--- a/scripts/qapi.py
+++ b/scripts/qapi.py
@@ -161,7 +161,7 @@ class QAPISchema:
 def parse_schema(fp):
     try:
         schema = QAPISchema(fp)
-    except QAPISchemaError as e:
+    except QAPISchemaError, e:
         print >>sys.stderr, e
         exit(1)
 
commit 277acfe8b38de35be8cb6e274678b5a7919c2d44
Author: Fam Zheng <famz at redhat.com>
Date:   Tue Aug 20 10:58:21 2013 +0800

    monitor: print the invalid char in error message
    
    It's more friendly to print which char is invalid to user, especially
    when user tries to input a float value and expect the monitor to round
    it to int. Since we don't round float number when we look for a integer,
    telling which char is invalid is less confusing.
    
    Signed-off-by: Fam Zheng <famz at redhat.com>
    Reviewed-by: Markus Armbruster <armbru at redhat.com>
    Reviewed-by: Eric Blake <eblake at redhat.com>
    Signed-off-by: Luiz Capitulino <lcapitulino at redhat.com>

diff --git a/monitor.c b/monitor.c
index 5dc0aa9..da9c9a2 100644
--- a/monitor.c
+++ b/monitor.c
@@ -3171,9 +3171,13 @@ static const MonitorDef monitor_defs[] = {
     { NULL },
 };
 
-static void expr_error(Monitor *mon, const char *msg)
+static void expr_error(Monitor *mon, const char *fmt, ...)
 {
-    monitor_printf(mon, "%s\n", msg);
+    va_list ap;
+    va_start(ap, fmt);
+    monitor_vprintf(mon, fmt, ap);
+    monitor_printf(mon, "\n");
+    va_end(ap);
     siglongjmp(expr_env, 1);
 }
 
@@ -3291,7 +3295,7 @@ static int64_t expr_unary(Monitor *mon)
             expr_error(mon, "number too large");
         }
         if (pch == p) {
-            expr_error(mon, "invalid char in expression");
+            expr_error(mon, "invalid char '%c' in expression", *p);
         }
         pch = p;
         while (qemu_isspace(*pch))
commit 3953e3a5d34fa7caffc3e32eae4270b2d810d966
Author: Laszlo Ersek <lersek at redhat.com>
Date:   Tue Aug 20 00:35:40 2013 +0200

    OptsVisitor: introduce unit tests, with test cases for range flattening
    
    According to commit 4f193e34
    ("tests: Use qapi-schema-test.json as schema parser test")
    the "tests/qapi-schema/qapi-schema-test.out" file must be updated as well.
    
    Signed-off-by: Laszlo Ersek <lersek at redhat.com>
    Tested-by: Wanlong Gao <gaowanlong at cn.fujitsu.com>
    Signed-off-by: Luiz Capitulino <lcapitulino at redhat.com>

diff --git a/.gitignore b/.gitignore
index a8e0f17..d2c5c2f 100644
--- a/.gitignore
+++ b/.gitignore
@@ -48,6 +48,7 @@ QMP/qmp-commands.txt
 test-bitops
 test-coroutine
 test-int128
+test-opts-visitor
 test-qmp-input-visitor
 test-qmp-output-visitor
 test-string-input-visitor
diff --git a/tests/Makefile b/tests/Makefile
index b0200fd..baba9e9 100644
--- a/tests/Makefile
+++ b/tests/Makefile
@@ -23,6 +23,8 @@ check-unit-y += tests/test-string-input-visitor$(EXESUF)
 gcov-files-test-string-input-visitor-y = qapi/string-input-visitor.c
 check-unit-y += tests/test-string-output-visitor$(EXESUF)
 gcov-files-test-string-output-visitor-y = qapi/string-output-visitor.c
+check-unit-y += tests/test-opts-visitor$(EXESUF)
+gcov-files-test-opts-visitor-y = qapi/opts-visitor.c
 check-unit-y += tests/test-coroutine$(EXESUF)
 gcov-files-test-coroutine-y = coroutine-$(CONFIG_COROUTINE_BACKEND).c
 check-unit-y += tests/test-visitor-serialization$(EXESUF)
@@ -100,7 +102,8 @@ test-obj-y = tests/check-qint.o tests/check-qstring.o tests/check-qdict.o \
 	tests/test-string-input-visitor.o tests/test-qmp-output-visitor.o \
 	tests/test-qmp-input-visitor.o tests/test-qmp-input-strict.o \
 	tests/test-qmp-commands.o tests/test-visitor-serialization.o \
-	tests/test-x86-cpuid.o tests/test-mul64.o tests/test-int128.o
+	tests/test-x86-cpuid.o tests/test-mul64.o tests/test-int128.o \
+	tests/test-opts-visitor.o
 
 test-qapi-obj-y = tests/test-qapi-visit.o tests/test-qapi-types.o
 
@@ -148,6 +151,7 @@ tests/test-qmp-input-visitor$(EXESUF): tests/test-qmp-input-visitor.o $(test-qap
 tests/test-qmp-input-strict$(EXESUF): tests/test-qmp-input-strict.o $(test-qapi-obj-y) libqemuutil.a libqemustub.a
 tests/test-qmp-commands$(EXESUF): tests/test-qmp-commands.o tests/test-qmp-marshal.o $(test-qapi-obj-y) qapi-types.o qapi-visit.o libqemuutil.a libqemustub.a
 tests/test-visitor-serialization$(EXESUF): tests/test-visitor-serialization.o $(test-qapi-obj-y) libqemuutil.a libqemustub.a
+tests/test-opts-visitor$(EXESUF): tests/test-opts-visitor.o $(test-qapi-obj-y) libqemuutil.a libqemustub.a
 
 tests/test-mul64$(EXESUF): tests/test-mul64.o libqemuutil.a
 tests/test-bitops$(EXESUF): tests/test-bitops.o libqemuutil.a
diff --git a/tests/qapi-schema/qapi-schema-test.json b/tests/qapi-schema/qapi-schema-test.json
index 4434fa3..fe5af75 100644
--- a/tests/qapi-schema/qapi-schema-test.json
+++ b/tests/qapi-schema/qapi-schema-test.json
@@ -51,3 +51,18 @@
 { 'command': 'user_def_cmd', 'data': {} }
 { 'command': 'user_def_cmd1', 'data': {'ud1a': 'UserDefOne'} }
 { 'command': 'user_def_cmd2', 'data': {'ud1a': 'UserDefOne', 'ud1b': 'UserDefOne'}, 'returns': 'UserDefTwo' }
+
+# For testing integer range flattening in opts-visitor. The following schema
+# corresponds to the option format:
+#
+# -userdef i64=3-6,i64=-5--1,u64=2,u16=1,u16=7-12
+#
+# For simplicity, this example doesn't use [type=]discriminator nor optargs
+# specific to discriminator values.
+{ 'type': 'UserDefOptions',
+  'data': {
+    '*i64' : [ 'int'    ],
+    '*u64' : [ 'uint64' ],
+    '*u16' : [ 'uint16' ],
+    '*i64x':   'int'     ,
+    '*u64x':   'uint64'  } }
diff --git a/tests/qapi-schema/qapi-schema-test.out b/tests/qapi-schema/qapi-schema-test.out
index fb00344..3851880 100644
--- a/tests/qapi-schema/qapi-schema-test.out
+++ b/tests/qapi-schema/qapi-schema-test.out
@@ -9,11 +9,13 @@
  OrderedDict([('union', 'UserDefNativeListUnion'), ('data', OrderedDict([('integer', ['int']), ('s8', ['int8']), ('s16', ['int16']), ('s32', ['int32']), ('s64', ['int64']), ('u8', ['uint8']), ('u16', ['uint16']), ('u32', ['uint32']), ('u64', ['uint64']), ('number', ['number']), ('boolean', ['bool']), ('string', ['str'])]))]),
  OrderedDict([('command', 'user_def_cmd'), ('data', OrderedDict())]),
  OrderedDict([('command', 'user_def_cmd1'), ('data', OrderedDict([('ud1a', 'UserDefOne')]))]),
- OrderedDict([('command', 'user_def_cmd2'), ('data', OrderedDict([('ud1a', 'UserDefOne'), ('ud1b', 'UserDefOne')])), ('returns', 'UserDefTwo')])]
+ OrderedDict([('command', 'user_def_cmd2'), ('data', OrderedDict([('ud1a', 'UserDefOne'), ('ud1b', 'UserDefOne')])), ('returns', 'UserDefTwo')]),
+ OrderedDict([('type', 'UserDefOptions'), ('data', OrderedDict([('*i64', ['int']), ('*u64', ['uint64']), ('*u16', ['uint16']), ('*i64x', 'int'), ('*u64x', 'uint64')]))])]
 ['EnumOne', 'UserDefUnionKind', 'UserDefNativeListUnionKind']
 [OrderedDict([('type', 'NestedEnumsOne'), ('data', OrderedDict([('enum1', 'EnumOne'), ('*enum2', 'EnumOne'), ('enum3', 'EnumOne'), ('*enum4', 'EnumOne')]))]),
  OrderedDict([('type', 'UserDefOne'), ('data', OrderedDict([('integer', 'int'), ('string', 'str'), ('*enum1', 'EnumOne')]))]),
  OrderedDict([('type', 'UserDefTwo'), ('data', OrderedDict([('string', 'str'), ('dict', OrderedDict([('string', 'str'), ('dict', OrderedDict([('userdef', 'UserDefOne'), ('string', 'str')])), ('*dict2', OrderedDict([('userdef', 'UserDefOne'), ('string', 'str')]))]))]))]),
  OrderedDict([('type', 'UserDefNested'), ('data', OrderedDict([('string0', 'str'), ('dict1', OrderedDict([('string1', 'str'), ('dict2', OrderedDict([('userdef1', 'UserDefOne'), ('string2', 'str')])), ('*dict3', OrderedDict([('userdef2', 'UserDefOne'), ('string3', 'str')]))]))]))]),
  OrderedDict([('type', 'UserDefA'), ('data', OrderedDict([('boolean', 'bool')]))]),
- OrderedDict([('type', 'UserDefB'), ('data', OrderedDict([('integer', 'int')]))])]
+ OrderedDict([('type', 'UserDefB'), ('data', OrderedDict([('integer', 'int')]))]),
+ OrderedDict([('type', 'UserDefOptions'), ('data', OrderedDict([('*i64', ['int']), ('*u64', ['uint64']), ('*u16', ['uint16']), ('*i64x', 'int'), ('*u64x', 'uint64')]))])]
diff --git a/tests/test-opts-visitor.c b/tests/test-opts-visitor.c
new file mode 100644
index 0000000..9f902b5
--- /dev/null
+++ b/tests/test-opts-visitor.c
@@ -0,0 +1,275 @@
+/*
+ * Options Visitor unit-tests.
+ *
+ * Copyright (C) 2013 Red Hat, Inc.
+ *
+ * Authors:
+ *   Laszlo Ersek <lersek at redhat.com> (based on test-string-output-visitor)
+ *
+ * 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 <glib.h>
+
+#include "qemu/config-file.h"     /* qemu_add_opts() */
+#include "qemu/option.h"          /* qemu_opts_parse() */
+#include "qapi/opts-visitor.h"    /* opts_visitor_new() */
+#include "test-qapi-visit.h"      /* visit_type_UserDefOptions() */
+#include "qapi/dealloc-visitor.h" /* qapi_dealloc_visitor_new() */
+
+static QemuOptsList userdef_opts = {
+    .name = "userdef",
+    .head = QTAILQ_HEAD_INITIALIZER(userdef_opts.head),
+    .desc = { { 0 } } /* validated with OptsVisitor */
+};
+
+/* fixture (= glib test case context) and test case manipulation */
+
+typedef struct OptsVisitorFixture {
+    UserDefOptions *userdef;
+    Error *err;
+} OptsVisitorFixture;
+
+
+static void
+setup_fixture(OptsVisitorFixture *f, gconstpointer test_data)
+{
+    const char *opts_string = test_data;
+    QemuOpts *opts;
+    OptsVisitor *ov;
+
+    opts = qemu_opts_parse(qemu_find_opts("userdef"), opts_string, 0);
+    g_assert(opts != NULL);
+
+    ov = opts_visitor_new(opts);
+    visit_type_UserDefOptions(opts_get_visitor(ov), &f->userdef, NULL,
+                              &f->err);
+    opts_visitor_cleanup(ov);
+    qemu_opts_del(opts);
+}
+
+
+static void
+teardown_fixture(OptsVisitorFixture *f, gconstpointer test_data)
+{
+    if (f->userdef != NULL) {
+        QapiDeallocVisitor *dv;
+
+        dv = qapi_dealloc_visitor_new();
+        visit_type_UserDefOptions(qapi_dealloc_get_visitor(dv), &f->userdef,
+                                  NULL, NULL);
+        qapi_dealloc_visitor_cleanup(dv);
+    }
+    error_free(f->err);
+}
+
+
+static void
+add_test(const char *testpath,
+         void (*test_func)(OptsVisitorFixture *f, gconstpointer test_data),
+         gconstpointer test_data)
+{
+    g_test_add(testpath, OptsVisitorFixture, test_data, setup_fixture,
+               test_func, teardown_fixture);
+}
+
+/* test output evaluation */
+
+static void
+expect_ok(OptsVisitorFixture *f, gconstpointer test_data)
+{
+    g_assert(f->err == NULL);
+    g_assert(f->userdef != NULL);
+}
+
+
+static void
+expect_fail(OptsVisitorFixture *f, gconstpointer test_data)
+{
+    g_assert(f->err != NULL);
+
+    /* The error message is printed when this test utility is invoked directly
+     * (ie. without gtester) and the --verbose flag is passed:
+     *
+     * tests/test-opts-visitor --verbose
+     */
+    g_test_message("'%s': %s", (const char *)test_data,
+                   error_get_pretty(f->err));
+}
+
+
+static void
+test_value(OptsVisitorFixture *f, gconstpointer test_data)
+{
+    uint64_t magic, bitval;
+    intList *i64;
+    uint64List *u64;
+    uint16List *u16;
+
+    expect_ok(f, test_data);
+
+    magic = 0;
+    for (i64 = f->userdef->i64; i64 != NULL; i64 = i64->next) {
+        g_assert(-16 <= i64->value && i64->value < 64-16);
+        bitval = 1ull << (i64->value + 16);
+        g_assert((magic & bitval) == 0);
+        magic |= bitval;
+    }
+    g_assert(magic == 0xDEADBEEF);
+
+    magic = 0;
+    for (u64 = f->userdef->u64; u64 != NULL; u64 = u64->next) {
+        g_assert(u64->value < 64);
+        bitval = 1ull << u64->value;
+        g_assert((magic & bitval) == 0);
+        magic |= bitval;
+    }
+    g_assert(magic == 0xBADC0FFEE0DDF00D);
+
+    magic = 0;
+    for (u16 = f->userdef->u16; u16 != NULL; u16 = u16->next) {
+        g_assert(u16->value < 64);
+        bitval = 1ull << u16->value;
+        g_assert((magic & bitval) == 0);
+        magic |= bitval;
+    }
+    g_assert(magic == 0xD15EA5E);
+}
+
+
+static void
+expect_i64_min(OptsVisitorFixture *f, gconstpointer test_data)
+{
+    expect_ok(f, test_data);
+    g_assert(f->userdef->has_i64);
+    g_assert(f->userdef->i64->next == NULL);
+    g_assert(f->userdef->i64->value == INT64_MIN);
+}
+
+
+static void
+expect_i64_max(OptsVisitorFixture *f, gconstpointer test_data)
+{
+    expect_ok(f, test_data);
+    g_assert(f->userdef->has_i64);
+    g_assert(f->userdef->i64->next == NULL);
+    g_assert(f->userdef->i64->value == INT64_MAX);
+}
+
+
+static void
+expect_zero(OptsVisitorFixture *f, gconstpointer test_data)
+{
+    expect_ok(f, test_data);
+    g_assert(f->userdef->has_u64);
+    g_assert(f->userdef->u64->next == NULL);
+    g_assert(f->userdef->u64->value == 0);
+}
+
+
+static void
+expect_u64_max(OptsVisitorFixture *f, gconstpointer test_data)
+{
+    expect_ok(f, test_data);
+    g_assert(f->userdef->has_u64);
+    g_assert(f->userdef->u64->next == NULL);
+    g_assert(f->userdef->u64->value == UINT64_MAX);
+}
+
+/* test cases */
+
+int
+main(int argc, char **argv)
+{
+    g_test_init(&argc, &argv, NULL);
+
+    qemu_add_opts(&userdef_opts);
+
+    /* Three hexadecimal magic numbers, "dead beef", "bad coffee, odd food" and
+     * "disease", from
+     * <http://en.wikipedia.org/wiki/Magic_number_%28programming%29>, were
+     * converted to binary and dissected into bit ranges. Each magic number is
+     * going to be recomposed using the lists called "i64", "u64" and "u16",
+     * respectively.
+     *
+     * (Note that these types pertain to the individual bit shift counts, not
+     * the magic numbers themselves; the intent is to exercise opts_type_int()
+     * and opts_type_uint64().)
+     *
+     * The "i64" shift counts have been decreased by 16 (decimal) in order to
+     * test negative values as well. Finally, the full list of QemuOpt elements
+     * has been permuted with "shuf".
+     *
+     * Both "i64" and "u64" have some (distinct) single-element ranges
+     * represented as both "a" and "a-a". "u16" is a special case of "i64" (see
+     * visit_type_uint16()), so it wouldn't add a separate test in this regard.
+     */
+
+    add_test("/visitor/opts/flatten/value", &test_value,
+             "i64=-1-0,u64=12-16,u64=2-3,i64=-11--9,u64=57,u16=9,i64=5-5,"
+             "u16=1-4,u16=20,u64=63-63,i64=-16--13,u64=50-52,i64=14-15,u16=11,"
+             "i64=7,u16=18,i64=2-3,u16=6,u64=54-55,u64=0,u64=18-20,u64=33-43,"
+             "i64=9-12,u16=26-27,u64=59-61,u16=13-16,u64=29-31,u64=22-23,"
+             "u16=24,i64=-7--3");
+
+    add_test("/visitor/opts/i64/val1/errno",    &expect_fail,
+             "i64=0x8000000000000000");
+    add_test("/visitor/opts/i64/val1/empty",    &expect_fail, "i64=");
+    add_test("/visitor/opts/i64/val1/trailing", &expect_fail, "i64=5z");
+    add_test("/visitor/opts/i64/nonlist",       &expect_fail, "i64x=5-6");
+    add_test("/visitor/opts/i64/val2/errno",    &expect_fail,
+             "i64=0x7fffffffffffffff-0x8000000000000000");
+    add_test("/visitor/opts/i64/val2/empty",    &expect_fail, "i64=5-");
+    add_test("/visitor/opts/i64/val2/trailing", &expect_fail, "i64=5-6z");
+    add_test("/visitor/opts/i64/range/empty",   &expect_fail, "i64=6-5");
+    add_test("/visitor/opts/i64/range/minval",  &expect_i64_min,
+             "i64=-0x8000000000000000--0x8000000000000000");
+    add_test("/visitor/opts/i64/range/maxval",  &expect_i64_max,
+             "i64=0x7fffffffffffffff-0x7fffffffffffffff");
+
+    add_test("/visitor/opts/u64/val1/errno",    &expect_fail, "u64=-1");
+    add_test("/visitor/opts/u64/val1/empty",    &expect_fail, "u64=");
+    add_test("/visitor/opts/u64/val1/trailing", &expect_fail, "u64=5z");
+    add_test("/visitor/opts/u64/nonlist",       &expect_fail, "u64x=5-6");
+    add_test("/visitor/opts/u64/val2/errno",    &expect_fail,
+             "u64=0xffffffffffffffff-0x10000000000000000");
+    add_test("/visitor/opts/u64/val2/empty",    &expect_fail, "u64=5-");
+    add_test("/visitor/opts/u64/val2/trailing", &expect_fail, "u64=5-6z");
+    add_test("/visitor/opts/u64/range/empty",   &expect_fail, "u64=6-5");
+    add_test("/visitor/opts/u64/range/minval",  &expect_zero, "u64=0-0");
+    add_test("/visitor/opts/u64/range/maxval",  &expect_u64_max,
+             "u64=0xffffffffffffffff-0xffffffffffffffff");
+
+    /* Test maximum range sizes. The macro value is open-coded here
+     * *intentionally*; the test case must use concrete values by design. If
+     * OPTS_VISITOR_RANGE_MAX is changed, the following values need to be
+     * recalculated as well. The assert and this comment should help with it.
+     */
+    g_assert(OPTS_VISITOR_RANGE_MAX == 65536);
+
+    /* The unsigned case is simple, a u64-u64 difference can always be
+     * represented as a u64.
+     */
+    add_test("/visitor/opts/u64/range/max",  &expect_ok,   "u64=0-65535");
+    add_test("/visitor/opts/u64/range/2big", &expect_fail, "u64=0-65536");
+
+    /* The same cannot be said about an i64-i64 difference. */
+    add_test("/visitor/opts/i64/range/max/pos/a", &expect_ok,
+             "i64=0x7fffffffffff0000-0x7fffffffffffffff");
+    add_test("/visitor/opts/i64/range/max/pos/b", &expect_ok,
+             "i64=0x7ffffffffffeffff-0x7ffffffffffffffe");
+    add_test("/visitor/opts/i64/range/2big/pos",  &expect_fail,
+             "i64=0x7ffffffffffeffff-0x7fffffffffffffff");
+    add_test("/visitor/opts/i64/range/max/neg/a", &expect_ok,
+             "i64=-0x8000000000000000--0x7fffffffffff0001");
+    add_test("/visitor/opts/i64/range/max/neg/b", &expect_ok,
+             "i64=-0x7fffffffffffffff--0x7fffffffffff0000");
+    add_test("/visitor/opts/i64/range/2big/neg",  &expect_fail,
+             "i64=-0x8000000000000000--0x7fffffffffff0000");
+    add_test("/visitor/opts/i64/range/2big/full", &expect_fail,
+             "i64=-0x8000000000000000-0x7fffffffffffffff");
+
+    g_test_run();
+    return 0;
+}
commit 99351c8472f76552c059a5dd382860229d647c4f
Author: Laszlo Ersek <lersek at redhat.com>
Date:   Tue Aug 20 00:35:39 2013 +0200

    add "test-int128" and "test-bitops" to .gitignore
    
    "test-int128" was probably missed in commit 6046c620
    ("int128: optimize and add test cases").
    
    "test-bitops" was probably missed in commit 3464700f
    ("tests: Add test-bitops.c with some sextract tests").
    
    Signed-off-by: Laszlo Ersek <lersek at redhat.com>
    Tested-by: Wanlong Gao <gaowanlong at cn.fujitsu.com>
    Signed-off-by: Luiz Capitulino <lcapitulino at redhat.com>

diff --git a/.gitignore b/.gitignore
index 0fe114d..a8e0f17 100644
--- a/.gitignore
+++ b/.gitignore
@@ -45,7 +45,9 @@ qemu-bridge-helper
 qemu-monitor.texi
 vscclient
 QMP/qmp-commands.txt
+test-bitops
 test-coroutine
+test-int128
 test-qmp-input-visitor
 test-qmp-output-visitor
 test-string-input-visitor
commit 15a849be100b54776bcf63193c3fea598666030f
Author: Laszlo Ersek <lersek at redhat.com>
Date:   Tue Aug 20 00:35:38 2013 +0200

    OptsVisitor: don't try to flatten overlong integer ranges
    
    Prevent mistyped command line options from incurring high memory and CPU
    usage at startup. 64K elements in a range should be enough for everyone
    (TM).
    
    The OPTS_VISITOR_RANGE_MAX macro is public so that unit tests can
    construct corner cases with it.
    
    Signed-off-by: Laszlo Ersek <lersek at redhat.com>
    Tested-by: Wanlong Gao <gaowanlong at cn.fujitsu.com>
    Signed-off-by: Luiz Capitulino <lcapitulino at redhat.com>

diff --git a/include/qapi/opts-visitor.h b/include/qapi/opts-visitor.h
index 5939eee..fd48c14 100644
--- a/include/qapi/opts-visitor.h
+++ b/include/qapi/opts-visitor.h
@@ -16,6 +16,12 @@
 #include "qapi/visitor.h"
 #include "qemu/option.h"
 
+/* Inclusive upper bound on the size of any flattened range. This is a safety
+ * (= anti-annoyance) measure; wrong ranges should not cause long startup
+ * delays nor exhaust virtual memory.
+ */
+#define OPTS_VISITOR_RANGE_MAX 65536
+
 typedef struct OptsVisitor OptsVisitor;
 
 /* Contrarily to qemu-option.c::parse_option_number(), OptsVisitor's "int"
diff --git a/qapi/opts-visitor.c b/qapi/opts-visitor.c
index d54d373..96ed858 100644
--- a/qapi/opts-visitor.c
+++ b/qapi/opts-visitor.c
@@ -384,7 +384,9 @@ opts_type_int(Visitor *v, int64_t *obj, const char *name, Error **errp)
             str = endptr + 1;
             val2 = strtoll(str, &endptr, 0);
             if (errno == 0 && endptr > str && *endptr == '\0' &&
-                INT64_MIN <= val2 && val2 <= INT64_MAX && val <= val2) {
+                INT64_MIN <= val2 && val2 <= INT64_MAX && val <= val2 &&
+                (val > INT64_MAX - OPTS_VISITOR_RANGE_MAX ||
+                 val2 < val + OPTS_VISITOR_RANGE_MAX)) {
                 ov->range_next.s = val;
                 ov->range_limit.s = val2;
                 ov->list_mode = LM_SIGNED_INTERVAL;
@@ -435,7 +437,8 @@ opts_type_uint64(Visitor *v, uint64_t *obj, const char *name, Error **errp)
 
             str = endptr + 1;
             if (parse_uint_full(str, &val2, 0) == 0 &&
-                val2 <= UINT64_MAX && val <= val2) {
+                val2 <= UINT64_MAX && val <= val2 &&
+                val2 - val < OPTS_VISITOR_RANGE_MAX) {
                 ov->range_next.u = val;
                 ov->range_limit.u = val2;
                 ov->list_mode = LM_UNSIGNED_INTERVAL;
commit 581a8a800070500527f6c75e5d6b75134c2b5a9d
Author: Laszlo Ersek <lersek at redhat.com>
Date:   Tue Aug 20 00:35:37 2013 +0200

    OptsVisitor: opts_type_uint64(): recognize intervals when LM_IN_PROGRESS
    
    When a well-formed range value, bounded by unsigned integers, is
    encountered while processing a repeated option, enter LM_UNSIGNED_INTERVAL
    and return the low bound.
    
    Signed-off-by: Laszlo Ersek <lersek at redhat.com>
    Tested-by: Wanlong Gao <gaowanlong at cn.fujitsu.com>
    Signed-off-by: Luiz Capitulino <lcapitulino at redhat.com>

diff --git a/qapi/opts-visitor.c b/qapi/opts-visitor.c
index d8f9a0e..d54d373 100644
--- a/qapi/opts-visitor.c
+++ b/qapi/opts-visitor.c
@@ -408,6 +408,7 @@ opts_type_uint64(Visitor *v, uint64_t *obj, const char *name, Error **errp)
     const QemuOpt *opt;
     const char *str;
     unsigned long long val;
+    char *endptr;
 
     if (ov->list_mode == LM_UNSIGNED_INTERVAL) {
         *obj = ov->range_next.u;
@@ -420,13 +421,34 @@ opts_type_uint64(Visitor *v, uint64_t *obj, const char *name, Error **errp)
     }
     str = opt->str;
 
-    if (parse_uint_full(str, &val, 0) == 0 && val <= UINT64_MAX) {
-        *obj = val;
-        processed(ov, name);
-        return;
+    /* we've gotten past lookup_scalar() */
+    assert(ov->list_mode == LM_NONE || ov->list_mode == LM_IN_PROGRESS);
+
+    if (parse_uint(str, &val, &endptr, 0) == 0 && val <= UINT64_MAX) {
+        if (*endptr == '\0') {
+            *obj = val;
+            processed(ov, name);
+            return;
+        }
+        if (*endptr == '-' && ov->list_mode == LM_IN_PROGRESS) {
+            unsigned long long val2;
+
+            str = endptr + 1;
+            if (parse_uint_full(str, &val2, 0) == 0 &&
+                val2 <= UINT64_MAX && val <= val2) {
+                ov->range_next.u = val;
+                ov->range_limit.u = val2;
+                ov->list_mode = LM_UNSIGNED_INTERVAL;
+
+                /* as if entering on the top */
+                *obj = ov->range_next.u;
+                return;
+            }
+        }
     }
     error_set(errp, QERR_INVALID_PARAMETER_VALUE, opt->name,
-              "an uint64 value");
+              (ov->list_mode == LM_NONE) ? "a uint64 value" :
+                                           "a uint64 value or range");
 }
 
 
commit 62d090e23fc17e4e60725ead0dff8902f8e66b52
Author: Laszlo Ersek <lersek at redhat.com>
Date:   Tue Aug 20 00:35:36 2013 +0200

    OptsVisitor: rebase opts_type_uint64() to parse_uint_full()
    
    Simplify the code in preparation for the next patch.
    
    Signed-off-by: Laszlo Ersek <lersek at redhat.com>
    Tested-by: Wanlong Gao <gaowanlong at cn.fujitsu.com>
    Signed-off-by: Luiz Capitulino <lcapitulino at redhat.com>

diff --git a/qapi/opts-visitor.c b/qapi/opts-visitor.c
index 90be583..d8f9a0e 100644
--- a/qapi/opts-visitor.c
+++ b/qapi/opts-visitor.c
@@ -407,6 +407,7 @@ opts_type_uint64(Visitor *v, uint64_t *obj, const char *name, Error **errp)
     OptsVisitor *ov = DO_UPCAST(OptsVisitor, visitor, v);
     const QemuOpt *opt;
     const char *str;
+    unsigned long long val;
 
     if (ov->list_mode == LM_UNSIGNED_INTERVAL) {
         *obj = ov->range_next.u;
@@ -417,26 +418,12 @@ opts_type_uint64(Visitor *v, uint64_t *obj, const char *name, Error **errp)
     if (!opt) {
         return;
     }
-
     str = opt->str;
-    if (str != NULL) {
-        while (isspace((unsigned char)*str)) {
-            ++str;
-        }
-
-        if (*str != '-' && *str != '\0') {
-            unsigned long long val;
-            char *endptr;
 
-            /* non-empty, non-negative subject sequence */
-            errno = 0;
-            val = strtoull(str, &endptr, 0);
-            if (*endptr == '\0' && errno == 0 && val <= UINT64_MAX) {
-                *obj = val;
-                processed(ov, name);
-                return;
-            }
-        }
+    if (parse_uint_full(str, &val, 0) == 0 && val <= UINT64_MAX) {
+        *obj = val;
+        processed(ov, name);
+        return;
     }
     error_set(errp, QERR_INVALID_PARAMETER_VALUE, opt->name,
               "an uint64 value");
commit 1e1c555a49175e2298eaa156e008a92d207bf812
Author: Laszlo Ersek <lersek at redhat.com>
Date:   Tue Aug 20 00:35:35 2013 +0200

    OptsVisitor: opts_type_int(): recognize intervals when LM_IN_PROGRESS
    
    When a well-formed range value, bounded by signed integers, is encountered
    while processing a repeated option, enter LM_SIGNED_INTERVAL and return
    the low bound.
    
    Signed-off-by: Laszlo Ersek <lersek at redhat.com>
    Tested-by: Wanlong Gao <gaowanlong at cn.fujitsu.com>
    Signed-off-by: Luiz Capitulino <lcapitulino at redhat.com>

diff --git a/qapi/opts-visitor.c b/qapi/opts-visitor.c
index c2a57bd..90be583 100644
--- a/qapi/opts-visitor.c
+++ b/qapi/opts-visitor.c
@@ -367,15 +367,37 @@ opts_type_int(Visitor *v, int64_t *obj, const char *name, Error **errp)
     }
     str = opt->str ? opt->str : "";
 
+    /* we've gotten past lookup_scalar() */
+    assert(ov->list_mode == LM_NONE || ov->list_mode == LM_IN_PROGRESS);
+
     errno = 0;
     val = strtoll(str, &endptr, 0);
-    if (*str != '\0' && *endptr == '\0' && errno == 0 && INT64_MIN <= val &&
-        val <= INT64_MAX) {
-        *obj = val;
-        processed(ov, name);
-        return;
+    if (errno == 0 && endptr > str && INT64_MIN <= val && val <= INT64_MAX) {
+        if (*endptr == '\0') {
+            *obj = val;
+            processed(ov, name);
+            return;
+        }
+        if (*endptr == '-' && ov->list_mode == LM_IN_PROGRESS) {
+            long long val2;
+
+            str = endptr + 1;
+            val2 = strtoll(str, &endptr, 0);
+            if (errno == 0 && endptr > str && *endptr == '\0' &&
+                INT64_MIN <= val2 && val2 <= INT64_MAX && val <= val2) {
+                ov->range_next.s = val;
+                ov->range_limit.s = val2;
+                ov->list_mode = LM_SIGNED_INTERVAL;
+
+                /* as if entering on the top */
+                *obj = ov->range_next.s;
+                return;
+            }
+        }
     }
-    error_set(errp, QERR_INVALID_PARAMETER_VALUE, opt->name, "an int64 value");
+    error_set(errp, QERR_INVALID_PARAMETER_VALUE, opt->name,
+              (ov->list_mode == LM_NONE) ? "an int64 value" :
+                                           "an int64 value or range");
 }
 
 
commit d8754f40acb2d30e4735cdcd21a16e7ac29264a3
Author: Laszlo Ersek <lersek at redhat.com>
Date:   Tue Aug 20 00:35:34 2013 +0200

    OptsVisitor: introduce list modes for interval flattening
    
    The new modes are equal-rank, exclusive alternatives of LM_IN_PROGRESS.
    Teach opts_next_list(), opts_type_int() and opts_type_uint64() to handle
    them.
    
    Also enumerate explicitly what functions are valid to call in what modes:
    - opts_next_list() is valid to call while flattening a range,
    - opts_end_list(): ditto,
    - lookup_scalar() is invalid to call during flattening; generated qapi
      traversal code must continue asking for the same kind of signed/unsigned
      list element until the interval is fully flattened,
    - processed(): ditto.
    
    List mode restrictions are always formulated in positive / inclusive
    sense. The restrictions for lookup_scalar() and processed() are
    automatically satisfied by current qapi traversals if the schema to build
    is compatible with OptsVisitor.
    
    The new list modes are not entered yet.
    
    Signed-off-by: Laszlo Ersek <lersek at redhat.com>
    Tested-by: Wanlong Gao <gaowanlong at cn.fujitsu.com>
    Signed-off-by: Luiz Capitulino <lcapitulino at redhat.com>

diff --git a/qapi/opts-visitor.c b/qapi/opts-visitor.c
index 29fd1ab..c2a57bd 100644
--- a/qapi/opts-visitor.c
+++ b/qapi/opts-visitor.c
@@ -22,7 +22,32 @@ enum ListMode
 {
     LM_NONE,             /* not traversing a list of repeated options */
     LM_STARTED,          /* opts_start_list() succeeded */
-    LM_IN_PROGRESS       /* opts_next_list() has been called */
+
+    LM_IN_PROGRESS,      /* opts_next_list() has been called.
+                          *
+                          * Generating the next list link will consume the most
+                          * recently parsed QemuOpt instance of the repeated
+                          * option.
+                          *
+                          * Parsing a value into the list link will examine the
+                          * next QemuOpt instance of the repeated option, and
+                          * possibly enter LM_SIGNED_INTERVAL or
+                          * LM_UNSIGNED_INTERVAL.
+                          */
+
+    LM_SIGNED_INTERVAL,  /* opts_next_list() has been called.
+                          *
+                          * Generating the next list link will consume the most
+                          * recently stored element from the signed interval,
+                          * parsed from the most recent QemuOpt instance of the
+                          * repeated option. This may consume QemuOpt itself
+                          * and return to LM_IN_PROGRESS.
+                          *
+                          * Parsing a value into the list link will store the
+                          * next element of the signed interval.
+                          */
+
+    LM_UNSIGNED_INTERVAL /* Same as above, only for an unsigned interval. */
 };
 
 typedef enum ListMode ListMode;
@@ -47,6 +72,15 @@ struct OptsVisitor
     ListMode list_mode;
     GQueue *repeated_opts;
 
+    /* When parsing a list of repeating options as integers, values of the form
+     * "a-b", representing a closed interval, are allowed. Elements in the
+     * range are generated individually.
+     */
+    union {
+        int64_t s;
+        uint64_t u;
+    } range_next, range_limit;
+
     /* If "opts_root->id" is set, reinstantiate it as a fake QemuOpt for
      * uniformity. Only its "name" and "str" fields are set. "fake_id_opt" does
      * not survive or escape the OptsVisitor object.
@@ -185,6 +219,22 @@ opts_next_list(Visitor *v, GenericList **list, Error **errp)
         link = list;
         break;
 
+    case LM_SIGNED_INTERVAL:
+    case LM_UNSIGNED_INTERVAL:
+        link = &(*list)->next;
+
+        if (ov->list_mode == LM_SIGNED_INTERVAL) {
+            if (ov->range_next.s < ov->range_limit.s) {
+                ++ov->range_next.s;
+                break;
+            }
+        } else if (ov->range_next.u < ov->range_limit.u) {
+            ++ov->range_next.u;
+            break;
+        }
+        ov->list_mode = LM_IN_PROGRESS;
+        /* range has been completed, fall through in order to pop option */
+
     case LM_IN_PROGRESS: {
         const QemuOpt *opt;
 
@@ -211,7 +261,10 @@ opts_end_list(Visitor *v, Error **errp)
 {
     OptsVisitor *ov = DO_UPCAST(OptsVisitor, visitor, v);
 
-    assert(ov->list_mode == LM_STARTED || ov->list_mode == LM_IN_PROGRESS);
+    assert(ov->list_mode == LM_STARTED ||
+           ov->list_mode == LM_IN_PROGRESS ||
+           ov->list_mode == LM_SIGNED_INTERVAL ||
+           ov->list_mode == LM_UNSIGNED_INTERVAL);
     ov->repeated_opts = NULL;
     ov->list_mode = LM_NONE;
 }
@@ -303,6 +356,11 @@ opts_type_int(Visitor *v, int64_t *obj, const char *name, Error **errp)
     long long val;
     char *endptr;
 
+    if (ov->list_mode == LM_SIGNED_INTERVAL) {
+        *obj = ov->range_next.s;
+        return;
+    }
+
     opt = lookup_scalar(ov, name, errp);
     if (!opt) {
         return;
@@ -328,6 +386,11 @@ opts_type_uint64(Visitor *v, uint64_t *obj, const char *name, Error **errp)
     const QemuOpt *opt;
     const char *str;
 
+    if (ov->list_mode == LM_UNSIGNED_INTERVAL) {
+        *obj = ov->range_next.u;
+        return;
+    }
+
     opt = lookup_scalar(ov, name, errp);
     if (!opt) {
         return;
commit d95704341280fc521dc2b16bbbc5858f6647e2c3
Author: Laszlo Ersek <lersek at redhat.com>
Date:   Tue Aug 20 00:35:33 2013 +0200

    OptsVisitor: introduce basic list modes
    
    We're going to need more state while processing a list of repeated
    options. This change eliminates "repeated_opts_first" and adds a new state
    variable:
    
      list_mode       repeated_opts  repeated_opts_first
      --------------  -------------  -------------------
      LM_NONE         NULL           false
      LM_STARTED      non-NULL       true
      LM_IN_PROGRESS  non-NULL       false
    
    Additionally, it is documented that lookup_scalar() and processed(), both
    called by opts_type_XXX(), are invalid in LM_STARTED -- generated qapi
    code calls opts_next_list() to allocate the very first link before trying
    to parse a scalar into it. List mode restrictions are expressed in
    positive / inclusive form.
    
    Signed-off-by: Laszlo Ersek <lersek at redhat.com>
    Tested-by: Wanlong Gao <gaowanlong at cn.fujitsu.com>
    Signed-off-by: Luiz Capitulino <lcapitulino at redhat.com>

diff --git a/qapi/opts-visitor.c b/qapi/opts-visitor.c
index 174bd8b..29fd1ab 100644
--- a/qapi/opts-visitor.c
+++ b/qapi/opts-visitor.c
@@ -1,7 +1,7 @@
 /*
  * Options Visitor
  *
- * Copyright Red Hat, Inc. 2012
+ * Copyright Red Hat, Inc. 2012, 2013
  *
  * Author: Laszlo Ersek <lersek at redhat.com>
  *
@@ -18,6 +18,15 @@
 #include "qapi/visitor-impl.h"
 
 
+enum ListMode
+{
+    LM_NONE,             /* not traversing a list of repeated options */
+    LM_STARTED,          /* opts_start_list() succeeded */
+    LM_IN_PROGRESS       /* opts_next_list() has been called */
+};
+
+typedef enum ListMode ListMode;
+
 struct OptsVisitor
 {
     Visitor visitor;
@@ -35,8 +44,8 @@ struct OptsVisitor
     /* The list currently being traversed with opts_start_list() /
      * opts_next_list(). The list must have a struct element type in the
      * schema, with a single mandatory scalar member. */
+    ListMode list_mode;
     GQueue *repeated_opts;
-    bool repeated_opts_first;
 
     /* If "opts_root->id" is set, reinstantiate it as a fake QemuOpt for
      * uniformity. Only its "name" and "str" fields are set. "fake_id_opt" does
@@ -156,9 +165,11 @@ opts_start_list(Visitor *v, const char *name, Error **errp)
     OptsVisitor *ov = DO_UPCAST(OptsVisitor, visitor, v);
 
     /* we can't traverse a list in a list */
-    assert(ov->repeated_opts == NULL);
+    assert(ov->list_mode == LM_NONE);
     ov->repeated_opts = lookup_distinct(ov, name, errp);
-    ov->repeated_opts_first = (ov->repeated_opts != NULL);
+    if (ov->repeated_opts != NULL) {
+        ov->list_mode = LM_STARTED;
+    }
 }
 
 
@@ -168,10 +179,13 @@ opts_next_list(Visitor *v, GenericList **list, Error **errp)
     OptsVisitor *ov = DO_UPCAST(OptsVisitor, visitor, v);
     GenericList **link;
 
-    if (ov->repeated_opts_first) {
-        ov->repeated_opts_first = false;
+    switch (ov->list_mode) {
+    case LM_STARTED:
+        ov->list_mode = LM_IN_PROGRESS;
         link = list;
-    } else {
+        break;
+
+    case LM_IN_PROGRESS: {
         const QemuOpt *opt;
 
         opt = g_queue_pop_head(ov->repeated_opts);
@@ -180,6 +194,11 @@ opts_next_list(Visitor *v, GenericList **list, Error **errp)
             return NULL;
         }
         link = &(*list)->next;
+        break;
+    }
+
+    default:
+        abort();
     }
 
     *link = g_malloc0(sizeof **link);
@@ -192,14 +211,16 @@ opts_end_list(Visitor *v, Error **errp)
 {
     OptsVisitor *ov = DO_UPCAST(OptsVisitor, visitor, v);
 
+    assert(ov->list_mode == LM_STARTED || ov->list_mode == LM_IN_PROGRESS);
     ov->repeated_opts = NULL;
+    ov->list_mode = LM_NONE;
 }
 
 
 static const QemuOpt *
 lookup_scalar(const OptsVisitor *ov, const char *name, Error **errp)
 {
-    if (ov->repeated_opts == NULL) {
+    if (ov->list_mode == LM_NONE) {
         GQueue *list;
 
         /* the last occurrence of any QemuOpt takes effect when queried by name
@@ -207,6 +228,7 @@ lookup_scalar(const OptsVisitor *ov, const char *name, Error **errp)
         list = lookup_distinct(ov, name, errp);
         return list ? g_queue_peek_tail(list) : NULL;
     }
+    assert(ov->list_mode == LM_IN_PROGRESS);
     return g_queue_peek_head(ov->repeated_opts);
 }
 
@@ -214,9 +236,12 @@ lookup_scalar(const OptsVisitor *ov, const char *name, Error **errp)
 static void
 processed(OptsVisitor *ov, const char *name)
 {
-    if (ov->repeated_opts == NULL) {
+    if (ov->list_mode == LM_NONE) {
         g_hash_table_remove(ov->unprocessed_opts, name);
+        return;
     }
+    assert(ov->list_mode == LM_IN_PROGRESS);
+    /* do nothing */
 }
 
 
@@ -365,7 +390,7 @@ opts_start_optional(Visitor *v, bool *present, const char *name,
     OptsVisitor *ov = DO_UPCAST(OptsVisitor, visitor, v);
 
     /* we only support a single mandatory scalar field in a list node */
-    assert(ov->repeated_opts == NULL);
+    assert(ov->list_mode == LM_NONE);
     *present = (lookup_distinct(ov, name, NULL) != NULL);
 }
 
commit 4a44d85e28bd282f53ccf0fa933dd71b8744a229
Author: Seiji Aguchi <seiji.aguchi at hds.com>
Date:   Mon Aug 5 15:40:44 2013 -0400

    Convert stderr message calling error_get_pretty() to error_report()
    
    Convert stderr messages calling error_get_pretty()
    to error_report().
    
    Timestamp is prepended by -msg timstamp option with it.
    
    Per Markus's comment below, A conversion from fprintf() to
    error_report() is always an improvement, regardless of
    error_get_pretty().
    
    http://marc.info/?l=qemu-devel&m=137513283408601&w=2
    
    But, it is not reasonable to convert them at one time
    because fprintf() is used everwhere in qemu.
    
    So, it should be done step by step with avoiding regression.
    
    Signed-off-by: Seiji Aguchi <seiji.aguchi at hds.com>
    Reviewed-by: Laszlo Ersek <lersek at redhat.com>
    Signed-off-by: Luiz Capitulino <lcapitulino at redhat.com>

diff --git a/arch_init.c b/arch_init.c
index 68a7ab7..94d45e1 100644
--- a/arch_init.c
+++ b/arch_init.c
@@ -1125,8 +1125,8 @@ void do_acpitable_option(const QemuOpts *opts)
 
     acpi_table_add(opts, &err);
     if (err) {
-        fprintf(stderr, "Wrong acpi table provided: %s\n",
-                error_get_pretty(err));
+        error_report("Wrong acpi table provided: %s",
+                     error_get_pretty(err));
         error_free(err);
         exit(1);
     }
diff --git a/hw/char/serial.c b/hw/char/serial.c
index 6025592..a31eb57 100644
--- a/hw/char/serial.c
+++ b/hw/char/serial.c
@@ -27,6 +27,7 @@
 #include "sysemu/char.h"
 #include "qemu/timer.h"
 #include "exec/address-spaces.h"
+#include "qemu/error-report.h"
 
 //#define DEBUG_SERIAL
 
@@ -696,7 +697,7 @@ SerialState *serial_init(int base, qemu_irq irq, int baudbase,
     s->chr = chr;
     serial_realize_core(s, &err);
     if (err != NULL) {
-        fprintf(stderr, "%s\n", error_get_pretty(err));
+        error_report("%s", error_get_pretty(err));
         error_free(err);
         exit(1);
     }
@@ -760,7 +761,7 @@ SerialState *serial_mm_init(MemoryRegion *address_space,
 
     serial_realize_core(s, &err);
     if (err != NULL) {
-        fprintf(stderr, "%s\n", error_get_pretty(err));
+        error_report("%s", error_get_pretty(err));
         error_free(err);
         exit(1);
     }
diff --git a/hw/i386/pc.c b/hw/i386/pc.c
index e8bc8ce..3a620a1 100644
--- a/hw/i386/pc.c
+++ b/hw/i386/pc.c
@@ -978,7 +978,7 @@ void pc_cpus_init(const char *cpu_model, DeviceState *icc_bridge)
         cpu = pc_new_cpu(cpu_model, x86_cpu_apic_id_from_index(i),
                          icc_bridge, &error);
         if (error) {
-            fprintf(stderr, "%s\n", error_get_pretty(error));
+            error_report("%s", error_get_pretty(error));
             error_free(error);
             exit(1);
         }
@@ -1096,8 +1096,8 @@ void pc_acpi_init(const char *default_dsdt)
 
         acpi_table_add(opts, &err);
         if (err) {
-            fprintf(stderr, "WARNING: failed to load %s: %s\n", filename,
-                    error_get_pretty(err));
+            error_report("WARNING: failed to load %s: %s", filename,
+                         error_get_pretty(err));
             error_free(err);
         }
         g_free(arg);
diff --git a/qemu-char.c b/qemu-char.c
index 1be1cf6..5446b88 100644
--- a/qemu-char.c
+++ b/qemu-char.c
@@ -3344,7 +3344,7 @@ CharDriverState *qemu_chr_new(const char *label, const char *filename, void (*in
 
     chr = qemu_chr_new_from_opts(opts, init, &err);
     if (error_is_set(&err)) {
-        fprintf(stderr, "%s\n", error_get_pretty(err));
+        error_report("%s", error_get_pretty(err));
         error_free(err);
     }
     if (chr && qemu_opt_get_bool(opts, "mux", 0)) {
diff --git a/target-i386/cpu.c b/target-i386/cpu.c
index 6e38252..42c5de0 100644
--- a/target-i386/cpu.c
+++ b/target-i386/cpu.c
@@ -1852,7 +1852,7 @@ X86CPU *cpu_x86_init(const char *cpu_model)
 
 out:
     if (error) {
-        fprintf(stderr, "%s\n", error_get_pretty(error));
+        error_report("%s", error_get_pretty(error));
         error_free(error);
         if (cpu != NULL) {
             object_unref(OBJECT(cpu));
diff --git a/target-ppc/translate_init.c b/target-ppc/translate_init.c
index 13b290c..609f797 100644
--- a/target-ppc/translate_init.c
+++ b/target-ppc/translate_init.c
@@ -27,6 +27,7 @@
 #include "cpu-models.h"
 #include "mmu-hash32.h"
 #include "mmu-hash64.h"
+#include "qemu/error-report.h"
 
 //#define PPC_DUMP_CPU
 //#define PPC_DEBUG_SPR
@@ -8281,7 +8282,7 @@ PowerPCCPU *cpu_ppc_init(const char *cpu_model)
 
     object_property_set_bool(OBJECT(cpu), true, "realized", &err);
     if (err != NULL) {
-        fprintf(stderr, "%s\n", error_get_pretty(err));
+        error_report("%s", error_get_pretty(err));
         error_free(err);
         object_unref(OBJECT(cpu));
         return NULL;
diff --git a/vl.c b/vl.c
index f422a1c..1c283c9 100644
--- a/vl.c
+++ b/vl.c
@@ -2393,7 +2393,7 @@ static int chardev_init_func(QemuOpts *opts, void *opaque)
 
     qemu_chr_new_from_opts(opts, NULL, &local_err);
     if (error_is_set(&local_err)) {
-        fprintf(stderr, "%s\n", error_get_pretty(local_err));
+        error_report("%s", error_get_pretty(local_err));
         error_free(local_err);
         return -1;
     }
@@ -4375,8 +4375,8 @@ int main(int argc, char **argv, char **envp)
         vnc_display_init(ds);
         vnc_display_open(ds, vnc_display, &local_err);
         if (local_err != NULL) {
-            fprintf(stderr, "Failed to start VNC server on `%s': %s\n",
-                    vnc_display, error_get_pretty(local_err));
+            error_report("Failed to start VNC server on `%s': %s",
+                         vnc_display, error_get_pretty(local_err));
             error_free(local_err);
             exit(1);
         }
@@ -4419,7 +4419,8 @@ int main(int argc, char **argv, char **envp)
         Error *local_err = NULL;
         qemu_start_incoming_migration(incoming, &local_err);
         if (local_err) {
-            fprintf(stderr, "-incoming %s: %s\n", incoming, error_get_pretty(local_err));
+            error_report("-incoming %s: %s", incoming,
+                         error_get_pretty(local_err));
             error_free(local_err);
             exit(1);
         }
commit 9176e8fb8f78206bd4039f001aca0d931a47d663
Merge: 72420ce f2e5dca
Author: Anthony Liguori <anthony at codemonkey.ws>
Date:   Tue Aug 20 09:52:18 2013 -0500

    Merge remote-tracking branch 'stefanha/block-next' into staging
    
    # By Stefan Hajnoczi
    # Via Stefan Hajnoczi
    * stefanha/block-next:
      aio: drop io_flush argument
      tests: drop event_active_cb()
      thread-pool: drop thread_pool_active()
      dataplane/virtio-blk: drop flush_true() and flush_io()
      block/ssh: drop return_true()
      block/sheepdog: drop have_co_req() and aio_flush_request()
      block/rbd: drop qemu_rbd_aio_flush_cb()
      block/nbd: drop nbd_have_request()
      block/linux-aio: drop qemu_laio_completion_cb()
      block/iscsi: drop iscsi_process_flush()
      block/gluster: drop qemu_gluster_aio_flush_cb()
      block/curl: drop curl_aio_flush()
      aio: stop using .io_flush()
      tests: adjust test-thread-pool to new aio_poll() semantics
      tests: adjust test-aio to new aio_poll() semantics
      dataplane/virtio-blk: check exit conditions before aio_poll()
      block: stop relying on io_flush() in bdrv_drain_all()
      block: ensure bdrv_drain_all() works during bdrv_delete()
    
    Message-id: 1376921877-9576-1-git-send-email-stefanha at redhat.com
    Signed-off-by: Anthony Liguori <anthony at codemonkey.ws>

commit 72420ce9f0bafef7d55563a8bd14237a5fe88a87
Merge: 237e4f9 b83c4db
Author: Anthony Liguori <anthony at codemonkey.ws>
Date:   Tue Aug 20 09:52:07 2013 -0500

    Merge remote-tracking branch 'rth/axp-next' into staging
    
    # By Richard Henderson
    # Via Richard Henderson
    * rth/axp-next:
      target-alpha: Implement the typhoon iommu
      target-alpha: Consider the superpage when threading and ending TBs
      target-alpha: Use goto_tb in call_pal
      target-alpha: Implement call_pal without an exception
    
    Message-id: 1376720412-2165-1-git-send-email-rth at twiddle.net
    Signed-off-by: Anthony Liguori <anthony at codemonkey.ws>

commit 237e4f92a81696e5359766a7f19a77a9ff1d02e5
Merge: bc02fb3 321bc0b
Author: Anthony Liguori <anthony at codemonkey.ws>
Date:   Tue Aug 20 09:51:53 2013 -0500

    Merge remote-tracking branch 'afaerber/tags/qom-cpu-for-anthony' into staging
    
    QOM CPUState refactorings / X86CPU
    
    * gdbstub coprocessor register count bugfix
    * QOM instance_post_init infrastructure to override dynamic properties
    * X86CPU HyperV preparations for CPU subclasses
    
    # gpg: Signature made Fri 16 Aug 2013 11:49:02 AM CDT using RSA key ID 3E7E013F
    # gpg: Can't check signature: public key not found
    
    # By Eduardo Habkost (3) and others
    # Via Andreas Färber
    * afaerber/tags/qom-cpu-for-anthony:
      cpus: Use cpu_is_stopped() efficiently
      target-i386: Move hyperv_* static globals to X86CPU
      qdev: Set globals in instance_post_init function
      qom: Introduce instance_post_init hook
      tests: Unit tests for qdev global properties handling
      gdbstub: Fix gdb_register_coprocessor() register counting

commit 230058106ab26de9b876158dbe27d60719f01f51
Author: Peter Chubb <peter.chubb at nicta.com.au>
Date:   Tue Aug 20 14:54:32 2013 +0100

    hw/timer/imx_epit: Simplify and fix imx_epit implementation
    
    When imx_epit.c was last refactored, a common usecase (comparison
    register zero) broke.  This patch fixes that, and simplifies the code
    yet more.  It also fixes a major thinko in the reset path --- the
    wrong bits in the control register were being cleared.
    
    Signed-off-by: Peter Chubb <peter.chubb at nicta.com.au>
    Reviewed-by: Jean-Christophe DUBOIS <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 117dc7b..dc73d65 100644
--- a/hw/timer/imx_epit.c
+++ b/hw/timer/imx_epit.c
@@ -43,7 +43,7 @@ static char const *imx_epit_reg_name(uint32_t reg)
 }
 
 #  define DPRINTF(fmt, args...) \
-          do { printf("%s: " fmt , __func__, ##args); } while (0)
+    do { fprintf(stderr, "%s: " fmt , __func__, ##args); } while (0)
 #else
 #  define DPRINTF(fmt, args...) do {} while (0)
 #endif
@@ -152,7 +152,7 @@ static void imx_epit_reset(DeviceState *dev)
     /*
      * 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->cr &= (CR_EN|CR_ENMOD|CR_STOPEN|CR_DOZEN|CR_WAITEN|CR_DBGEN);
     s->sr = 0;
     s->lr = TIMER_MAX;
     s->cmp = 0;
@@ -167,7 +167,7 @@ static void imx_epit_reset(DeviceState *dev)
     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);
+        ptimer_run(s->timer_reload, 0);
     }
 }
 
@@ -218,17 +218,17 @@ static uint64_t imx_epit_read(void *opaque, hwaddr offset, unsigned size)
 
 static void imx_epit_reload_compare_timer(IMXEPITState *s)
 {
-    if ((s->cr & CR_OCIEN) && s->cmp) {
-        /* if the compare feature is on */
+    if ((s->cr & (CR_EN | CR_OCIEN)) == (CR_EN | CR_OCIEN))  {
+        /* if the compare feature is on and timers are running */
         uint32_t tmp = imx_epit_update_count(s);
+        uint64_t next;
         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);
-            }
+            /* It'll fire in this round of the timer */
+            next = tmp - s->cmp;
+        } else { /* catch it next time around */
+            next = tmp - s->cmp + ((s->cr & CR_RLD) ? TIMER_MAX : s->lr);
         }
+        ptimer_set_count(s->timer_cmp, next);
     }
 }
 
@@ -237,11 +237,14 @@ static void imx_epit_write(void *opaque, hwaddr offset, uint64_t value,
 {
     IMXEPITState *s = IMX_EPIT(opaque);
     uint32_t reg = offset >> 2;
+    uint64_t oldcr;
 
     DPRINTF("(%s, value = 0x%08x)\n", imx_epit_reg_name(reg), (uint32_t)value);
 
     switch (reg) {
     case 0: /* CR */
+
+        oldcr = s->cr;
         s->cr = value & 0x03ffffff;
         if (s->cr & CR_SWR) {
             /* handle the reset */
@@ -250,22 +253,35 @@ static void imx_epit_write(void *opaque, hwaddr offset, uint64_t value,
             imx_epit_set_freq(s);
         }
 
-        if (s->freq && (s->cr & CR_EN)) {
+        if (s->freq && (s->cr & CR_EN) && !(oldcr & CR_EN)) {
             if (s->cr & CR_ENMOD) {
                 if (s->cr & CR_RLD) {
                     ptimer_set_limit(s->timer_reload, s->lr, 1);
+                    ptimer_set_limit(s->timer_cmp, s->lr, 1);
                 } else {
                     ptimer_set_limit(s->timer_reload, TIMER_MAX, 1);
+                    ptimer_set_limit(s->timer_cmp, TIMER_MAX, 1);
                 }
             }
 
             imx_epit_reload_compare_timer(s);
-
-            ptimer_run(s->timer_reload, 1);
-        } else {
+            ptimer_run(s->timer_reload, 0);
+            if (s->cr & CR_OCIEN) {
+                ptimer_run(s->timer_cmp, 0);
+            } else {
+                ptimer_stop(s->timer_cmp);
+            }
+        } else if (!(s->cr & CR_EN)) {
             /* stop both timers */
             ptimer_stop(s->timer_reload);
             ptimer_stop(s->timer_cmp);
+        } else  if (s->cr & CR_OCIEN) {
+            if (!(oldcr & CR_OCIEN)) {
+                imx_epit_reload_compare_timer(s);
+                ptimer_run(s->timer_cmp, 0);
+            }
+        } else {
+            ptimer_stop(s->timer_cmp);
         }
         break;
 
@@ -284,13 +300,13 @@ static void imx_epit_write(void *opaque, hwaddr offset, uint64_t value,
             /* 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);
+            ptimer_set_limit(s->timer_cmp, s->lr, 0);
         } 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_epit_reload_compare_timer(s);
-
         break;
 
     case 3: /* CMP */
@@ -306,51 +322,14 @@ static void imx_epit_write(void *opaque, hwaddr offset, uint64_t value,
         break;
     }
 }
-
-static void imx_epit_timeout(void *opaque)
-{
-    IMXEPITState *s = IMX_EPIT(opaque);
-
-    DPRINTF("\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_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("s->lr < s->cmp\n");
-        }
-    }
-}
-
 static void imx_epit_cmp(void *opaque)
 {
     IMXEPITState *s = IMX_EPIT(opaque);
 
-    DPRINTF("\n");
-
-    ptimer_stop(s->timer_cmp);
+    DPRINTF("sr was %d\n", s->sr);
 
-    /* compare register is not 0 */
-    if (s->cmp) {
-        s->sr = 1;
-        imx_epit_update_int(s);
-    }
+    s->sr = 1;
+    imx_epit_update_int(s);
 }
 
 void imx_timerp_create(const hwaddr addr, qemu_irq irq, DeviceState *ccm)
@@ -400,8 +379,7 @@ static void imx_epit_realize(DeviceState *dev, Error **errp)
                           0x00001000);
     sysbus_init_mmio(sbd, &s->iomem);
 
-    bh = qemu_bh_new(imx_epit_timeout, s);
-    s->timer_reload = ptimer_init(bh);
+    s->timer_reload = ptimer_init(NULL);
 
     bh = qemu_bh_new(imx_epit_cmp, s);
     s->timer_cmp = ptimer_init(bh);
commit 66aae5e1ecc38e8658c5cc69a0b3ceeb4967619c
Author: Peter Maydell <peter.maydell at linaro.org>
Date:   Tue Aug 20 14:54:32 2013 +0100

    default-configs: Fix A9MP and A15MP config names
    
    When individual CONFIG_ switches for the A9MPcore and A15MPcore
    devices were created, they were inadvertently given incorrect names
    (CONFIG_ARM9MPCORE and CONFIG_ARM15MPCORE). These CPUs are
    "Cortex-A9MP" and "Cortex-A15MP", and in particular the ARM9 is
    a different (rather older) CPU than the Cortex-A9. Rename the
    CONFIG_ switches to bring them into line with the source file
    names and CPU names.
    
    Signed-off-by: Peter Maydell <peter.maydell at linaro.org>
    Message-id: 1376056215-26391-1-git-send-email-peter.maydell at linaro.org

diff --git a/default-configs/arm-softmmu.mak b/default-configs/arm-softmmu.mak
index 27cbe3d..ac0815d 100644
--- a/default-configs/arm-softmmu.mak
+++ b/default-configs/arm-softmmu.mak
@@ -34,9 +34,9 @@ CONFIG_PFLASH_CFI02=y
 CONFIG_MICRODRIVE=y
 CONFIG_USB_MUSB=y
 
-CONFIG_ARM9MPCORE=y
 CONFIG_ARM11MPCORE=y
-CONFIG_ARM15MPCORE=y
+CONFIG_A9MPCORE=y
+CONFIG_A15MPCORE=y
 
 CONFIG_ARM_GIC=y
 CONFIG_ARM_GIC_KVM=$(CONFIG_KVM)
diff --git a/hw/cpu/Makefile.objs b/hw/cpu/Makefile.objs
index 4461ece..df287c1 100644
--- a/hw/cpu/Makefile.objs
+++ b/hw/cpu/Makefile.objs
@@ -1,5 +1,5 @@
 obj-$(CONFIG_ARM11MPCORE) += arm11mpcore.o
-obj-$(CONFIG_ARM9MPCORE) += a9mpcore.o
-obj-$(CONFIG_ARM15MPCORE) += a15mpcore.o
+obj-$(CONFIG_A9MPCORE) += a9mpcore.o
+obj-$(CONFIG_A15MPCORE) += a15mpcore.o
 obj-$(CONFIG_ICC_BUS) += icc_bus.o
 
commit 6033e840c7b1db1055d02199fa3a28a4fd7b2386
Author: Peter Maydell <peter.maydell at linaro.org>
Date:   Tue Aug 20 14:54:32 2013 +0100

    hw/cpu/a15mpcore: Wire generic timer outputs to GIC inputs
    
    Now our A15 CPU implements the generic timers, we can wire them
    up to the appropriate inputs on the GIC.
    
    Signed-off-by: Peter Maydell <peter.maydell at linaro.org>
    Tested-by: Laurent Desnogues <laurent.desnogues at gmail.com>
    Message-id: 1376065080-26661-5-git-send-email-peter.maydell at linaro.org

diff --git a/hw/cpu/a15mpcore.c b/hw/cpu/a15mpcore.c
index 4f37964..af182da 100644
--- a/hw/cpu/a15mpcore.c
+++ b/hw/cpu/a15mpcore.c
@@ -49,6 +49,8 @@ static int a15mp_priv_init(SysBusDevice *dev)
     A15MPPrivState *s = A15MPCORE_PRIV(dev);
     SysBusDevice *busdev;
     const char *gictype = "arm_gic";
+    int i;
+    CPUState *cpu;
 
     if (kvm_irqchip_in_kernel()) {
         gictype = "kvm-arm-gic";
@@ -67,6 +69,22 @@ static int a15mp_priv_init(SysBusDevice *dev)
     /* Pass through inbound GPIO lines to the GIC */
     qdev_init_gpio_in(DEVICE(dev), a15mp_priv_set_irq, s->num_irq - 32);
 
+    /* Wire the outputs from each CPU's generic timer to the
+     * appropriate GIC PPI inputs
+     */
+    for (i = 0, cpu = first_cpu; i < s->num_cpu; i++, cpu = cpu->next_cpu) {
+        DeviceState *cpudev = DEVICE(cpu);
+        int ppibase = s->num_irq - 32 + i * 32;
+        /* physical timer; we wire it up to the non-secure timer's ID,
+         * since a real A15 always has TrustZone but QEMU doesn't.
+         */
+        qdev_connect_gpio_out(cpudev, 0,
+                              qdev_get_gpio_in(s->gic, ppibase + 30));
+        /* virtual timer */
+        qdev_connect_gpio_out(cpudev, 1,
+                              qdev_get_gpio_in(s->gic, ppibase + 27));
+    }
+
     /* Memory map (addresses are offsets from PERIPHBASE):
      *  0x0000-0x0fff -- reserved
      *  0x1000-0x1fff -- GIC Distributor
commit 55d284af8e31bbdf4d545cb2d6481cd0367680fb
Author: Peter Maydell <peter.maydell at linaro.org>
Date:   Tue Aug 20 14:54:31 2013 +0100

    target-arm: Implement the generic timer
    
    The ARMv7 architecture specifies a 'generic timer' which is implemented
    via cp15 registers. Newer kernels will prefer to use this rather than
    a devboard-level timer. Implement the generic timer for TCG; for KVM
    we will already use the hardware's virtualized timer for this.
    
    Signed-off-by: Peter Maydell <peter.maydell at linaro.org>
    Tested-by: Laurent Desnogues <laurent.desnogues at gmail.com>
    Message-id: 1376065080-26661-4-git-send-email-peter.maydell at linaro.org

diff --git a/target-arm/cpu-qom.h b/target-arm/cpu-qom.h
index cf36587..9f47bae 100644
--- a/target-arm/cpu-qom.h
+++ b/target-arm/cpu-qom.h
@@ -86,6 +86,11 @@ typedef struct ARMCPU {
     uint64_t *cpreg_vmstate_values;
     int32_t cpreg_vmstate_array_len;
 
+    /* Timers used by the generic (architected) timer */
+    QEMUTimer *gt_timer[NUM_GTIMERS];
+    /* GPIO outputs for generic timer */
+    qemu_irq gt_timer_outputs[NUM_GTIMERS];
+
     /* The instance init functions for implementation-specific subclasses
      * set these fields to specify the implementation-dependent values of
      * various constant registers and reset values of non-constant
@@ -152,4 +157,8 @@ hwaddr arm_cpu_get_phys_page_debug(CPUState *cpu, vaddr addr);
 int arm_cpu_gdb_read_register(CPUState *cpu, uint8_t *buf, int reg);
 int arm_cpu_gdb_write_register(CPUState *cpu, uint8_t *buf, int reg);
 
+/* Callback functions for the generic timer's timers. */
+void arm_gt_ptimer_cb(void *opaque);
+void arm_gt_vtimer_cb(void *opaque);
+
 #endif
diff --git a/target-arm/cpu.c b/target-arm/cpu.c
index 6f56aa8..f01ce03 100644
--- a/target-arm/cpu.c
+++ b/target-arm/cpu.c
@@ -203,6 +203,13 @@ static void arm_cpu_initfn(Object *obj)
     } else {
         qdev_init_gpio_in(DEVICE(cpu), arm_cpu_set_irq, 2);
     }
+
+    cpu->gt_timer[GTIMER_PHYS] = qemu_new_timer(vm_clock, GTIMER_SCALE,
+                                                arm_gt_ptimer_cb, cpu);
+    cpu->gt_timer[GTIMER_VIRT] = qemu_new_timer(vm_clock, GTIMER_SCALE,
+                                                arm_gt_vtimer_cb, cpu);
+    qdev_init_gpio_out(DEVICE(cpu), cpu->gt_timer_outputs,
+                       ARRAY_SIZE(cpu->gt_timer_outputs));
 #endif
 
     if (tcg_enabled() && !inited) {
diff --git a/target-arm/cpu.h b/target-arm/cpu.h
index c2cb534..f2abdf3 100644
--- a/target-arm/cpu.h
+++ b/target-arm/cpu.h
@@ -79,6 +79,21 @@ struct arm_boot_info;
    s<2n+1> maps to the most significant half of d<n>
  */
 
+/* CPU state for each instance of a generic timer (in cp15 c14) */
+typedef struct ARMGenericTimer {
+    uint64_t cval; /* Timer CompareValue register */
+    uint32_t ctl; /* Timer Control register */
+} ARMGenericTimer;
+
+#define GTIMER_PHYS 0
+#define GTIMER_VIRT 1
+#define NUM_GTIMERS 2
+
+/* Scale factor for generic timers, ie number of ns per tick.
+ * This gives a 62.5MHz timer.
+ */
+#define GTIMER_SCALE 16
+
 typedef struct CPUARMState {
     /* Regs for current mode.  */
     uint32_t regs[16];
@@ -146,6 +161,9 @@ typedef struct CPUARMState {
         uint32_t c13_tls1; /* User RW Thread register.  */
         uint32_t c13_tls2; /* User RO Thread register.  */
         uint32_t c13_tls3; /* Privileged Thread register.  */
+        uint32_t c14_cntfrq; /* Counter Frequency register */
+        uint32_t c14_cntkctl; /* Timer Control register */
+        ARMGenericTimer c14_timer[NUM_GTIMERS];
         uint32_t c15_cpar; /* XScale Coprocessor Access Register */
         uint32_t c15_ticonfig; /* TI925T configuration byte.  */
         uint32_t c15_i_max; /* Maximum D-cache dirty line index.  */
diff --git a/target-arm/helper.c b/target-arm/helper.c
index f8689e2..f4e1b06 100644
--- a/target-arm/helper.c
+++ b/target-arm/helper.c
@@ -695,15 +695,261 @@ static const ARMCPRegInfo v6k_cp_reginfo[] = {
     REGINFO_SENTINEL
 };
 
+#ifndef CONFIG_USER_ONLY
+
+static uint64_t gt_get_countervalue(CPUARMState *env)
+{
+    return qemu_get_clock_ns(vm_clock) / GTIMER_SCALE;
+}
+
+static void gt_recalc_timer(ARMCPU *cpu, int timeridx)
+{
+    ARMGenericTimer *gt = &cpu->env.cp15.c14_timer[timeridx];
+
+    if (gt->ctl & 1) {
+        /* Timer enabled: calculate and set current ISTATUS, irq, and
+         * reset timer to when ISTATUS next has to change
+         */
+        uint64_t count = gt_get_countervalue(&cpu->env);
+        /* Note that this must be unsigned 64 bit arithmetic: */
+        int istatus = count >= gt->cval;
+        uint64_t nexttick;
+
+        gt->ctl = deposit32(gt->ctl, 2, 1, istatus);
+        qemu_set_irq(cpu->gt_timer_outputs[timeridx],
+                     (istatus && !(gt->ctl & 2)));
+        if (istatus) {
+            /* Next transition is when count rolls back over to zero */
+            nexttick = UINT64_MAX;
+        } else {
+            /* Next transition is when we hit cval */
+            nexttick = gt->cval;
+        }
+        /* Note that the desired next expiry time might be beyond the
+         * signed-64-bit range of a QEMUTimer -- in this case we just
+         * set the timer for as far in the future as possible. When the
+         * timer expires we will reset the timer for any remaining period.
+         */
+        if (nexttick > INT64_MAX / GTIMER_SCALE) {
+            nexttick = INT64_MAX / GTIMER_SCALE;
+        }
+        qemu_mod_timer(cpu->gt_timer[timeridx], nexttick);
+    } else {
+        /* Timer disabled: ISTATUS and timer output always clear */
+        gt->ctl &= ~4;
+        qemu_set_irq(cpu->gt_timer_outputs[timeridx], 0);
+        qemu_del_timer(cpu->gt_timer[timeridx]);
+    }
+}
+
+static int gt_cntfrq_read(CPUARMState *env, const ARMCPRegInfo *ri,
+                          uint64_t *value)
+{
+    /* Not visible from PL0 if both PL0PCTEN and PL0VCTEN are zero */
+    if (arm_current_pl(env) == 0 && !extract32(env->cp15.c14_cntkctl, 0, 2)) {
+        return EXCP_UDEF;
+    }
+    *value = env->cp15.c14_cntfrq;
+    return 0;
+}
+
+static void gt_cnt_reset(CPUARMState *env, const ARMCPRegInfo *ri)
+{
+    ARMCPU *cpu = arm_env_get_cpu(env);
+    int timeridx = ri->opc1 & 1;
+
+    qemu_del_timer(cpu->gt_timer[timeridx]);
+}
+
+static int gt_cnt_read(CPUARMState *env, const ARMCPRegInfo *ri,
+                       uint64_t *value)
+{
+    int timeridx = ri->opc1 & 1;
+
+    if (arm_current_pl(env) == 0 &&
+        !extract32(env->cp15.c14_cntkctl, timeridx, 1)) {
+        return EXCP_UDEF;
+    }
+    *value = gt_get_countervalue(env);
+    return 0;
+}
+
+static int gt_cval_read(CPUARMState *env, const ARMCPRegInfo *ri,
+                        uint64_t *value)
+{
+    int timeridx = ri->opc1 & 1;
+
+    if (arm_current_pl(env) == 0 &&
+        !extract32(env->cp15.c14_cntkctl, 9 - timeridx, 1)) {
+        return EXCP_UDEF;
+    }
+    *value = env->cp15.c14_timer[timeridx].cval;
+    return 0;
+}
+
+static int gt_cval_write(CPUARMState *env, const ARMCPRegInfo *ri,
+                         uint64_t value)
+{
+    int timeridx = ri->opc1 & 1;
+
+    env->cp15.c14_timer[timeridx].cval = value;
+    gt_recalc_timer(arm_env_get_cpu(env), timeridx);
+    return 0;
+}
+static int gt_tval_read(CPUARMState *env, const ARMCPRegInfo *ri,
+                        uint64_t *value)
+{
+    int timeridx = ri->crm & 1;
+
+    if (arm_current_pl(env) == 0 &&
+        !extract32(env->cp15.c14_cntkctl, 9 - timeridx, 1)) {
+        return EXCP_UDEF;
+    }
+    *value = (uint32_t)(env->cp15.c14_timer[timeridx].cval -
+                        gt_get_countervalue(env));
+    return 0;
+}
+
+static int gt_tval_write(CPUARMState *env, const ARMCPRegInfo *ri,
+                         uint64_t value)
+{
+    int timeridx = ri->crm & 1;
+
+    env->cp15.c14_timer[timeridx].cval = gt_get_countervalue(env) +
+        + sextract64(value, 0, 32);
+    gt_recalc_timer(arm_env_get_cpu(env), timeridx);
+    return 0;
+}
+
+static int gt_ctl_read(CPUARMState *env, const ARMCPRegInfo *ri,
+                       uint64_t *value)
+{
+    int timeridx = ri->crm & 1;
+
+    if (arm_current_pl(env) == 0 &&
+        !extract32(env->cp15.c14_cntkctl, 9 - timeridx, 1)) {
+        return EXCP_UDEF;
+    }
+    *value = env->cp15.c14_timer[timeridx].ctl;
+    return 0;
+}
+
+static int gt_ctl_write(CPUARMState *env, const ARMCPRegInfo *ri,
+                        uint64_t value)
+{
+    ARMCPU *cpu = arm_env_get_cpu(env);
+    int timeridx = ri->crm & 1;
+    uint32_t oldval = env->cp15.c14_timer[timeridx].ctl;
+
+    env->cp15.c14_timer[timeridx].ctl = value & 3;
+    if ((oldval ^ value) & 1) {
+        /* Enable toggled */
+        gt_recalc_timer(cpu, timeridx);
+    } else if ((oldval & value) & 2) {
+        /* IMASK toggled: don't need to recalculate,
+         * just set the interrupt line based on ISTATUS
+         */
+        qemu_set_irq(cpu->gt_timer_outputs[timeridx],
+                     (oldval & 4) && (value & 2));
+    }
+    return 0;
+}
+
+void arm_gt_ptimer_cb(void *opaque)
+{
+    ARMCPU *cpu = opaque;
+
+    gt_recalc_timer(cpu, GTIMER_PHYS);
+}
+
+void arm_gt_vtimer_cb(void *opaque)
+{
+    ARMCPU *cpu = opaque;
+
+    gt_recalc_timer(cpu, GTIMER_VIRT);
+}
+
 static const ARMCPRegInfo generic_timer_cp_reginfo[] = {
-    /* Dummy implementation: RAZ/WI the whole crn=14 space */
-    { .name = "GENERIC_TIMER", .cp = 15, .crn = 14,
-      .crm = CP_ANY, .opc1 = CP_ANY, .opc2 = CP_ANY,
-      .access = PL1_RW, .type = ARM_CP_CONST | ARM_CP_NO_MIGRATE,
-      .resetvalue = 0 },
+    /* Note that CNTFRQ is purely reads-as-written for the benefit
+     * of software; writing it doesn't actually change the timer frequency.
+     * Our reset value matches the fixed frequency we implement the timer at.
+     */
+    { .name = "CNTFRQ", .cp = 15, .crn = 14, .crm = 0, .opc1 = 0, .opc2 = 0,
+      .access = PL1_RW | PL0_R,
+      .fieldoffset = offsetof(CPUARMState, cp15.c14_cntfrq),
+      .resetvalue = (1000 * 1000 * 1000) / GTIMER_SCALE,
+      .readfn = gt_cntfrq_read, .raw_readfn = raw_read,
+    },
+    /* overall control: mostly access permissions */
+    { .name = "CNTKCTL", .cp = 15, .crn = 14, .crm = 1, .opc1 = 0, .opc2 = 0,
+      .access = PL1_RW,
+      .fieldoffset = offsetof(CPUARMState, cp15.c14_cntkctl),
+      .resetvalue = 0,
+    },
+    /* per-timer control */
+    { .name = "CNTP_CTL", .cp = 15, .crn = 14, .crm = 2, .opc1 = 0, .opc2 = 1,
+      .type = ARM_CP_IO, .access = PL1_RW | PL0_R,
+      .fieldoffset = offsetof(CPUARMState, cp15.c14_timer[GTIMER_PHYS].ctl),
+      .resetvalue = 0,
+      .readfn = gt_ctl_read, .writefn = gt_ctl_write,
+      .raw_readfn = raw_read, .raw_writefn = raw_write,
+    },
+    { .name = "CNTV_CTL", .cp = 15, .crn = 14, .crm = 3, .opc1 = 0, .opc2 = 1,
+      .type = ARM_CP_IO, .access = PL1_RW | PL0_R,
+      .fieldoffset = offsetof(CPUARMState, cp15.c14_timer[GTIMER_VIRT].ctl),
+      .resetvalue = 0,
+      .readfn = gt_ctl_read, .writefn = gt_ctl_write,
+      .raw_readfn = raw_read, .raw_writefn = raw_write,
+    },
+    /* TimerValue views: a 32 bit downcounting view of the underlying state */
+    { .name = "CNTP_TVAL", .cp = 15, .crn = 14, .crm = 2, .opc1 = 0, .opc2 = 0,
+      .type = ARM_CP_NO_MIGRATE | ARM_CP_IO, .access = PL1_RW | PL0_R,
+      .readfn = gt_tval_read, .writefn = gt_tval_write,
+    },
+    { .name = "CNTV_TVAL", .cp = 15, .crn = 14, .crm = 3, .opc1 = 0, .opc2 = 0,
+      .type = ARM_CP_NO_MIGRATE | ARM_CP_IO, .access = PL1_RW | PL0_R,
+      .readfn = gt_tval_read, .writefn = gt_tval_write,
+    },
+    /* The counter itself */
+    { .name = "CNTPCT", .cp = 15, .crm = 14, .opc1 = 0,
+      .access = PL0_R, .type = ARM_CP_64BIT | ARM_CP_NO_MIGRATE | ARM_CP_IO,
+      .readfn = gt_cnt_read, .resetfn = gt_cnt_reset,
+    },
+    { .name = "CNTVCT", .cp = 15, .crm = 14, .opc1 = 1,
+      .access = PL0_R, .type = ARM_CP_64BIT | ARM_CP_NO_MIGRATE | ARM_CP_IO,
+      .readfn = gt_cnt_read, .resetfn = gt_cnt_reset,
+    },
+    /* Comparison value, indicating when the timer goes off */
+    { .name = "CNTP_CVAL", .cp = 15, .crm = 14, .opc1 = 2,
+      .access = PL1_RW | PL0_R,
+      .type = ARM_CP_64BIT | ARM_CP_IO,
+      .fieldoffset = offsetof(CPUARMState, cp15.c14_timer[GTIMER_PHYS].cval),
+      .resetvalue = 0,
+      .readfn = gt_cval_read, .writefn = gt_cval_write,
+      .raw_readfn = raw_read, .raw_writefn = raw_write,
+    },
+    { .name = "CNTV_CVAL", .cp = 15, .crm = 14, .opc1 = 3,
+      .access = PL1_RW | PL0_R,
+      .type = ARM_CP_64BIT | ARM_CP_IO,
+      .fieldoffset = offsetof(CPUARMState, cp15.c14_timer[GTIMER_VIRT].cval),
+      .resetvalue = 0,
+      .readfn = gt_cval_read, .writefn = gt_cval_write,
+      .raw_readfn = raw_read, .raw_writefn = raw_write,
+    },
     REGINFO_SENTINEL
 };
 
+#else
+/* In user-mode none of the generic timer registers are accessible,
+ * and their implementation depends on vm_clock and qdev gpio outputs,
+ * so instead just don't register any of them.
+ */
+static const ARMCPRegInfo generic_timer_cp_reginfo[] = {
+    REGINFO_SENTINEL
+};
+
+#endif
+
 static int par_write(CPUARMState *env, const ARMCPRegInfo *ri, uint64_t value)
 {
     if (arm_feature(env, ARM_FEATURE_LPAE)) {
diff --git a/target-arm/machine.c b/target-arm/machine.c
index 6d4c2d4..5b6f375 100644
--- a/target-arm/machine.c
+++ b/target-arm/machine.c
@@ -222,9 +222,9 @@ static int cpu_post_load(void *opaque, int version_id)
 
 const VMStateDescription vmstate_arm_cpu = {
     .name = "cpu",
-    .version_id = 12,
-    .minimum_version_id = 12,
-    .minimum_version_id_old = 12,
+    .version_id = 13,
+    .minimum_version_id = 13,
+    .minimum_version_id_old = 13,
     .pre_save = cpu_pre_save,
     .post_load = cpu_post_load,
     .fields = (VMStateField[]) {
@@ -257,6 +257,8 @@ const VMStateDescription vmstate_arm_cpu = {
         VMSTATE_UINT32(env.exclusive_val, ARMCPU),
         VMSTATE_UINT32(env.exclusive_high, ARMCPU),
         VMSTATE_UINT64(env.features, ARMCPU),
+        VMSTATE_TIMER(gt_timer[GTIMER_PHYS], ARMCPU),
+        VMSTATE_TIMER(gt_timer[GTIMER_VIRT], ARMCPU),
         VMSTATE_END_OF_LIST()
     },
     .subsections = (VMStateSubsection[]) {
commit 2452731c883cb0acd4e47b23039c46cd880cf2c6
Author: Peter Maydell <peter.maydell at linaro.org>
Date:   Tue Aug 20 14:54:31 2013 +0100

    target-arm: Support coprocessor registers which do I/O
    
    Add an ARM_CP_IO flag which an ARMCPRegInfo definition can use to
    indicate that the register's implementation does I/O and thus
    its accesses need to be surrounded by gen_io_start()/gen_io_end()
    in order for icount to work. Most notably, cp registers which
    implement clocks or timers need this.
    
    Signed-off-by: Peter Maydell <peter.maydell at linaro.org>
    Tested-by: Laurent Desnogues <laurent.desnogues at gmail.com>
    Reviewed-by: Edgar E. Iglesias <edgar.iglesias at gmail.com>
    Message-id: 1376065080-26661-3-git-send-email-peter.maydell at linaro.org

diff --git a/target-arm/cpu.h b/target-arm/cpu.h
index dffeec7..c2cb534 100644
--- a/target-arm/cpu.h
+++ b/target-arm/cpu.h
@@ -472,6 +472,9 @@ static inline uint64_t cpreg_to_kvm_id(uint32_t cpregid)
  * old must have the OVERRIDE bit set.
  * NO_MIGRATE indicates that this register should be ignored for migration;
  * (eg because any state is accessed via some other coprocessor register).
+ * IO indicates that this register does I/O and therefore its accesses
+ * need to be surrounded by gen_io_start()/gen_io_end(). In particular,
+ * registers which implement clocks or timers require this.
  */
 #define ARM_CP_SPECIAL 1
 #define ARM_CP_CONST 2
@@ -479,13 +482,14 @@ static inline uint64_t cpreg_to_kvm_id(uint32_t cpregid)
 #define ARM_CP_SUPPRESS_TB_END 8
 #define ARM_CP_OVERRIDE 16
 #define ARM_CP_NO_MIGRATE 32
+#define ARM_CP_IO 64
 #define ARM_CP_NOP (ARM_CP_SPECIAL | (1 << 8))
 #define ARM_CP_WFI (ARM_CP_SPECIAL | (2 << 8))
 #define ARM_LAST_SPECIAL ARM_CP_WFI
 /* Used only as a terminator for ARMCPRegInfo lists */
 #define ARM_CP_SENTINEL 0xffff
 /* Mask of only the flag bits in a type field */
-#define ARM_CP_FLAG_MASK 0x3f
+#define ARM_CP_FLAG_MASK 0x7f
 
 /* Return true if cptype is a valid type field. This is used to try to
  * catch errors where the sentinel has been accidentally left off the end
diff --git a/target-arm/translate.c b/target-arm/translate.c
index 6db4c50..d1e8538 100644
--- a/target-arm/translate.c
+++ b/target-arm/translate.c
@@ -6280,6 +6280,10 @@ static int disas_coproc_insn(CPUARMState * env, DisasContext *s, uint32_t insn)
             break;
         }
 
+        if (use_icount && (ri->type & ARM_CP_IO)) {
+            gen_io_start();
+        }
+
         if (isread) {
             /* Read */
             if (is64) {
@@ -6369,14 +6373,20 @@ static int disas_coproc_insn(CPUARMState * env, DisasContext *s, uint32_t insn)
                     store_cpu_offset(tmp, ri->fieldoffset);
                 }
             }
+        }
+
+        if (use_icount && (ri->type & ARM_CP_IO)) {
+            /* I/O operations must end the TB here (whether read or write) */
+            gen_io_end();
+            gen_lookup_tb(s);
+        } else if (!isread && !(ri->type & ARM_CP_SUPPRESS_TB_END)) {
             /* We default to ending the TB on a coprocessor register write,
              * but allow this to be suppressed by the register definition
              * (usually only necessary to work around guest bugs).
              */
-            if (!(ri->type & ARM_CP_SUPPRESS_TB_END)) {
-                gen_lookup_tb(s);
-            }
+            gen_lookup_tb(s);
         }
+
         return 0;
     }
 
commit 22d9e1a986a671ebfacb21555b7533336f3e8259
Author: Peter Maydell <peter.maydell at linaro.org>
Date:   Tue Aug 20 14:54:31 2013 +0100

    target-arm: Allow raw_read() and raw_write() to handle 64 bit regs
    
    Extend the raw_read() and raw_write() helper accessors so that
    they can be used for 64 bit registers as well as 32 bit registers.
    
    Signed-off-by: Peter Maydell <peter.maydell at linaro.org>
    Tested-by: Laurent Desnogues <laurent.desnogues at gmail.com>
    Reviewed-by: Edgar E. Iglesias <edgar.iglesias at gmail.com>
    Message-id: 1376065080-26661-2-git-send-email-peter.maydell at linaro.org

diff --git a/target-arm/helper.c b/target-arm/helper.c
index 6d9026d..f8689e2 100644
--- a/target-arm/helper.c
+++ b/target-arm/helper.c
@@ -67,14 +67,22 @@ static int vfp_gdb_set_reg(CPUARMState *env, uint8_t *buf, int reg)
 static int raw_read(CPUARMState *env, const ARMCPRegInfo *ri,
                     uint64_t *value)
 {
-    *value = CPREG_FIELD32(env, ri);
+    if (ri->type & ARM_CP_64BIT) {
+        *value = CPREG_FIELD64(env, ri);
+    } else {
+        *value = CPREG_FIELD32(env, ri);
+    }
     return 0;
 }
 
 static int raw_write(CPUARMState *env, const ARMCPRegInfo *ri,
                      uint64_t value)
 {
-    CPREG_FIELD32(env, ri) = value;
+    if (ri->type & ARM_CP_64BIT) {
+        CPREG_FIELD64(env, ri) = value;
+    } else {
+        CPREG_FIELD32(env, ri) = value;
+    }
     return 0;
 }
 
commit b643e4b90bb0b70adde97a09349d8ca7067309d9
Author: Peter Maydell <peter.maydell at linaro.org>
Date:   Tue Aug 20 14:54:31 2013 +0100

    hw/arm/pic_cpu: Remove the now-unneeded arm_pic_init_cpu()
    
    Now all the boards have been converted arm_pic_init_cpu()
    is unused and can just be deleted.
    
    Signed-off-by: Peter Maydell <peter.maydell at linaro.org>
    Message-id: 1375977856-25046-15-git-send-email-peter.maydell at linaro.org

diff --git a/hw/arm/Makefile.objs b/hw/arm/Makefile.objs
index 9e3a06f..3671b42 100644
--- a/hw/arm/Makefile.objs
+++ b/hw/arm/Makefile.objs
@@ -1,6 +1,6 @@
 obj-y += boot.o collie.o exynos4_boards.o gumstix.o highbank.o
 obj-y += integratorcp.o kzm.o mainstone.o musicpal.o nseries.o
-obj-y += omap_sx1.o palm.o pic_cpu.o realview.o spitz.o stellaris.o
+obj-y += omap_sx1.o palm.o realview.o spitz.o stellaris.o
 obj-y += tosa.o versatilepb.o vexpress.o xilinx_zynq.o z2.o
 
 obj-y += armv7m.o exynos4210.o pxa2xx.o pxa2xx_gpio.o pxa2xx_pic.o
diff --git a/hw/arm/pic_cpu.c b/hw/arm/pic_cpu.c
deleted file mode 100644
index 9c36273..0000000
--- a/hw/arm/pic_cpu.c
+++ /dev/null
@@ -1,25 +0,0 @@
-/*
- * Generic ARM Programmable Interrupt Controller support.
- *
- * Copyright (c) 2006 CodeSourcery.
- * Written by Paul Brook
- *
- * This code is licensed under the LGPL
- */
-
-#include "hw/hw.h"
-#include "hw/arm/arm.h"
-
-/* Backwards compatibility shim; this can disappear when all
- * board models have been updated to get IRQ and FIQ lines directly
- * from the ARMCPU object rather than by calling this function.
- */
-qemu_irq *arm_pic_init_cpu(ARMCPU *cpu)
-{
-    DeviceState *dev = DEVICE(cpu);
-    qemu_irq *irqs = g_new(qemu_irq, 2);
-
-    irqs[0] = qdev_get_gpio_in(dev, ARM_CPU_IRQ);
-    irqs[1] = qdev_get_gpio_in(dev, ARM_CPU_FIQ);
-    return irqs;
-}
diff --git a/include/hw/arm/arm.h b/include/hw/arm/arm.h
index bae87c6..ecbbba8 100644
--- a/include/hw/arm/arm.h
+++ b/include/hw/arm/arm.h
@@ -14,11 +14,6 @@
 #include "exec/memory.h"
 #include "hw/irq.h"
 
-/* The CPU is also modelled as an interrupt controller.  */
-#define ARM_PIC_CPU_IRQ 0
-#define ARM_PIC_CPU_FIQ 1
-qemu_irq *arm_pic_init_cpu(ARMCPU *cpu);
-
 /* armv7m.c */
 qemu_irq *armv7m_init(MemoryRegion *address_space_mem,
                       int flash_size, int sram_size,
commit e4a6540dedc6ec109a9ece3f8d83a143b7bde4e6
Author: Peter Maydell <peter.maydell at linaro.org>
Date:   Tue Aug 20 14:54:30 2013 +0100

    hw/arm/xilinx_zynq: Don't use arm_pic_init_cpu()
    
    Drop the now-deprecated arm_pic_init_cpu() in favour of directly
    getting the IRQ line from the ARMCPU object.
    
    Signed-off-by: Peter Maydell <peter.maydell at linaro.org>
    Message-id: 1375977856-25046-14-git-send-email-peter.maydell at linaro.org

diff --git a/hw/arm/xilinx_zynq.c b/hw/arm/xilinx_zynq.c
index 3444823..0f18c85 100644
--- a/hw/arm/xilinx_zynq.c
+++ b/hw/arm/xilinx_zynq.c
@@ -108,11 +108,9 @@ static void zynq_init(QEMUMachineInitArgs *args)
     MemoryRegion *ocm_ram = g_new(MemoryRegion, 1);
     DeviceState *dev;
     SysBusDevice *busdev;
-    qemu_irq *irqp;
     qemu_irq pic[64];
     NICInfo *nd;
     int n;
-    qemu_irq cpu_irq;
 
     if (!cpu_model) {
         cpu_model = "cortex-a9";
@@ -123,8 +121,6 @@ static void zynq_init(QEMUMachineInitArgs *args)
         fprintf(stderr, "Unable to find CPU definition\n");
         exit(1);
     }
-    irqp = arm_pic_init_cpu(cpu);
-    cpu_irq = irqp[ARM_PIC_CPU_IRQ];
 
     /* max 2GB ram */
     if (ram_size > 0x80000000) {
@@ -159,7 +155,8 @@ static void zynq_init(QEMUMachineInitArgs *args)
     qdev_init_nofail(dev);
     busdev = SYS_BUS_DEVICE(dev);
     sysbus_mmio_map(busdev, 0, 0xF8F00000);
-    sysbus_connect_irq(busdev, 0, cpu_irq);
+    sysbus_connect_irq(busdev, 0,
+                       qdev_get_gpio_in(DEVICE(cpu), ARM_CPU_IRQ));
 
     for (n = 0; n < 64; n++) {
         pic[n] = qdev_get_gpio_in(dev, n);
commit fe9120a5d1117523282b44e8aa0027ab2b8a4408
Author: Peter Maydell <peter.maydell at linaro.org>
Date:   Tue Aug 20 14:54:30 2013 +0100

    hw/arm/vexpress: Don't use arm_pic_init_cpu()
    
    Drop the now-deprecated arm_pic_init_cpu() in favour of directly
    getting the IRQ line from the ARMCPU object.
    
    Signed-off-by: Peter Maydell <peter.maydell at linaro.org>
    Message-id: 1375977856-25046-13-git-send-email-peter.maydell at linaro.org

diff --git a/hw/arm/vexpress.c b/hw/arm/vexpress.c
index 9586e38..fbd71a7 100644
--- a/hw/arm/vexpress.c
+++ b/hw/arm/vexpress.c
@@ -183,7 +183,6 @@ static void a9_daughterboard_init(const VEDBoardInfo *daughterboard,
     MemoryRegion *lowram = g_new(MemoryRegion, 1);
     DeviceState *dev;
     SysBusDevice *busdev;
-    qemu_irq *irqp;
     int n;
     qemu_irq cpu_irq[4];
     ram_addr_t low_ram_size;
@@ -198,8 +197,7 @@ static void a9_daughterboard_init(const VEDBoardInfo *daughterboard,
             fprintf(stderr, "Unable to find CPU definition\n");
             exit(1);
         }
-        irqp = arm_pic_init_cpu(cpu);
-        cpu_irq[n] = irqp[ARM_PIC_CPU_IRQ];
+        cpu_irq[n] = qdev_get_gpio_in(DEVICE(cpu), ARM_CPU_IRQ);
     }
 
     if (ram_size > 0x40000000) {
@@ -312,15 +310,13 @@ static void a15_daughterboard_init(const VEDBoardInfo *daughterboard,
 
     for (n = 0; n < smp_cpus; n++) {
         ARMCPU *cpu;
-        qemu_irq *irqp;
 
         cpu = cpu_arm_init(cpu_model);
         if (!cpu) {
             fprintf(stderr, "Unable to find CPU definition\n");
             exit(1);
         }
-        irqp = arm_pic_init_cpu(cpu);
-        cpu_irq[n] = irqp[ARM_PIC_CPU_IRQ];
+        cpu_irq[n] = qdev_get_gpio_in(DEVICE(cpu), ARM_CPU_IRQ);
     }
 
     {
commit bace999f8a03c226eecad3c170def644f0551c50
Author: Peter Maydell <peter.maydell at linaro.org>
Date:   Tue Aug 20 14:54:30 2013 +0100

    hw/arm/versatilepb: Don't use arm_pic_init_cpu()
    
    Drop the now-deprecated arm_pic_init_cpu() in favour of directly
    getting the IRQ line from the ARMCPU object.
    
    Signed-off-by: Peter Maydell <peter.maydell at linaro.org>
    Message-id: 1375977856-25046-12-git-send-email-peter.maydell at linaro.org

diff --git a/hw/arm/versatilepb.c b/hw/arm/versatilepb.c
index b48d84c..4a6fcee 100644
--- a/hw/arm/versatilepb.c
+++ b/hw/arm/versatilepb.c
@@ -178,7 +178,6 @@ static void versatile_init(QEMUMachineInitArgs *args, int board_id)
     ARMCPU *cpu;
     MemoryRegion *sysmem = get_system_memory();
     MemoryRegion *ram = g_new(MemoryRegion, 1);
-    qemu_irq *cpu_pic;
     qemu_irq pic[32];
     qemu_irq sic[32];
     DeviceState *dev, *sysctl;
@@ -211,10 +210,10 @@ static void versatile_init(QEMUMachineInitArgs *args, int board_id)
     qdev_init_nofail(sysctl);
     sysbus_mmio_map(SYS_BUS_DEVICE(sysctl), 0, 0x10000000);
 
-    cpu_pic = arm_pic_init_cpu(cpu);
     dev = sysbus_create_varargs("pl190", 0x10140000,
-                                cpu_pic[ARM_PIC_CPU_IRQ],
-                                cpu_pic[ARM_PIC_CPU_FIQ], NULL);
+                                qdev_get_gpio_in(DEVICE(cpu), ARM_CPU_IRQ),
+                                qdev_get_gpio_in(DEVICE(cpu), ARM_CPU_FIQ),
+                                NULL);
     for (n = 0; n < 32; n++) {
         pic[n] = qdev_get_gpio_in(dev, n);
     }
commit 4f071cf9b53a236469500f08033335cc726db9b0
Author: Peter Maydell <peter.maydell at linaro.org>
Date:   Tue Aug 20 14:54:30 2013 +0100

    hw/arm/strongarm: Don't use arm_pic_init_cpu()
    
    Drop the now-deprecated arm_pic_init_cpu() in favour of directly
    getting the IRQ line from the ARMCPU object.
    
    Signed-off-by: Peter Maydell <peter.maydell at linaro.org>
    Message-id: 1375977856-25046-11-git-send-email-peter.maydell at linaro.org

diff --git a/hw/arm/strongarm.c b/hw/arm/strongarm.c
index 82a9492..7b8ef8c 100644
--- a/hw/arm/strongarm.c
+++ b/hw/arm/strongarm.c
@@ -1588,7 +1588,6 @@ StrongARMState *sa1110_init(MemoryRegion *sysmem,
                             unsigned int sdram_size, const char *rev)
 {
     StrongARMState *s;
-    qemu_irq *pic;
     int i;
 
     s = g_malloc0(sizeof(StrongARMState));
@@ -1613,9 +1612,10 @@ StrongARMState *sa1110_init(MemoryRegion *sysmem,
     vmstate_register_ram_global(&s->sdram);
     memory_region_add_subregion(sysmem, SA_SDCS0, &s->sdram);
 
-    pic = arm_pic_init_cpu(s->cpu);
     s->pic = sysbus_create_varargs("strongarm_pic", 0x90050000,
-                    pic[ARM_PIC_CPU_IRQ], pic[ARM_PIC_CPU_FIQ], NULL);
+                    qdev_get_gpio_in(DEVICE(s->cpu), ARM_CPU_IRQ),
+                    qdev_get_gpio_in(DEVICE(s->cpu), ARM_CPU_FIQ),
+                    NULL);
 
     sysbus_create_varargs("pxa25x-timer", 0x90000000,
                     qdev_get_gpio_in(s->pic, SA_PIC_OSTC0),
commit 033ee5a5ac5dd01bcea76a6427d95f5390af43ca
Author: Peter Maydell <peter.maydell at linaro.org>
Date:   Tue Aug 20 14:54:30 2013 +0100

    hw/arm/realview: Don't use arm_pic_init_cpu()
    
    Drop the now-deprecated arm_pic_init_cpu() in favour of directly
    getting the IRQ line from the ARMCPU object.
    
    Signed-off-by: Peter Maydell <peter.maydell at linaro.org>
    Message-id: 1375977856-25046-10-git-send-email-peter.maydell at linaro.org

diff --git a/hw/arm/realview.c b/hw/arm/realview.c
index 3060f48..82ec02d 100644
--- a/hw/arm/realview.c
+++ b/hw/arm/realview.c
@@ -56,7 +56,6 @@ static void realview_init(QEMUMachineInitArgs *args,
     MemoryRegion *ram_hack = g_new(MemoryRegion, 1);
     DeviceState *dev, *sysctl, *gpio2, *pl041;
     SysBusDevice *busdev;
-    qemu_irq *irqp;
     qemu_irq pic[64];
     qemu_irq mmc_irq[2];
     PCIBus *pci_bus = NULL;
@@ -92,8 +91,7 @@ static void realview_init(QEMUMachineInitArgs *args,
             fprintf(stderr, "Unable to find CPU definition\n");
             exit(1);
         }
-        irqp = arm_pic_init_cpu(cpu);
-        cpu_irq[n] = irqp[ARM_PIC_CPU_IRQ];
+        cpu_irq[n] = qdev_get_gpio_in(DEVICE(cpu), ARM_CPU_IRQ);
     }
     env = &cpu->env;
     if (arm_feature(env, ARM_FEATURE_V7)) {
commit 437f0f10a42dc2a0236a79e0bba39a32af4d73f8
Author: Peter Maydell <peter.maydell at linaro.org>
Date:   Tue Aug 20 14:54:29 2013 +0100

    hw/arm/omap*: Don't use arm_pic_init_cpu()
    
    Drop the now-deprecated arm_pic_init_cpu() in favour of directly
    getting the IRQ line from the ARMCPU object.
    
    Signed-off-by: Peter Maydell <peter.maydell at linaro.org>
    Message-id: 1375977856-25046-9-git-send-email-peter.maydell at linaro.org

diff --git a/hw/arm/omap1.c b/hw/arm/omap1.c
index 19be5fc..b6a0b27 100644
--- a/hw/arm/omap1.c
+++ b/hw/arm/omap1.c
@@ -3827,7 +3827,6 @@ struct omap_mpu_state_s *omap310_mpu_init(MemoryRegion *system_memory,
     int i;
     struct omap_mpu_state_s *s = (struct omap_mpu_state_s *)
             g_malloc0(sizeof(struct omap_mpu_state_s));
-    qemu_irq *cpu_irq;
     qemu_irq dma_irqs[6];
     DriveInfo *dinfo;
     SysBusDevice *busdev;
@@ -3860,14 +3859,15 @@ struct omap_mpu_state_s *omap310_mpu_init(MemoryRegion *system_memory,
 
     omap_clkm_init(system_memory, 0xfffece00, 0xe1008000, s);
 
-    cpu_irq = arm_pic_init_cpu(s->cpu);
     s->ih[0] = qdev_create(NULL, "omap-intc");
     qdev_prop_set_uint32(s->ih[0], "size", 0x100);
     qdev_prop_set_ptr(s->ih[0], "clk", omap_findclk(s, "arminth_ck"));
     qdev_init_nofail(s->ih[0]);
     busdev = SYS_BUS_DEVICE(s->ih[0]);
-    sysbus_connect_irq(busdev, 0, cpu_irq[ARM_PIC_CPU_IRQ]);
-    sysbus_connect_irq(busdev, 1, cpu_irq[ARM_PIC_CPU_FIQ]);
+    sysbus_connect_irq(busdev, 0,
+                       qdev_get_gpio_in(DEVICE(s->cpu), ARM_CPU_IRQ));
+    sysbus_connect_irq(busdev, 1,
+                       qdev_get_gpio_in(DEVICE(s->cpu), ARM_CPU_FIQ));
     sysbus_mmio_map(busdev, 0, 0xfffecb00);
     s->ih[1] = qdev_create(NULL, "omap-intc");
     qdev_prop_set_uint32(s->ih[1], "size", 0x800);
diff --git a/hw/arm/omap2.c b/hw/arm/omap2.c
index ec9610b..36efde0 100644
--- a/hw/arm/omap2.c
+++ b/hw/arm/omap2.c
@@ -2244,7 +2244,6 @@ struct omap_mpu_state_s *omap2420_mpu_init(MemoryRegion *sysmem,
 {
     struct omap_mpu_state_s *s = (struct omap_mpu_state_s *)
             g_malloc0(sizeof(struct omap_mpu_state_s));
-    qemu_irq *cpu_irq;
     qemu_irq dma_irqs[4];
     DriveInfo *dinfo;
     int i;
@@ -2277,15 +2276,16 @@ struct omap_mpu_state_s *omap2420_mpu_init(MemoryRegion *sysmem,
     s->l4 = omap_l4_init(sysmem, OMAP2_L4_BASE, 54);
 
     /* Actually mapped at any 2K boundary in the ARM11 private-peripheral if */
-    cpu_irq = arm_pic_init_cpu(s->cpu);
     s->ih[0] = qdev_create(NULL, "omap2-intc");
     qdev_prop_set_uint8(s->ih[0], "revision", 0x21);
     qdev_prop_set_ptr(s->ih[0], "fclk", omap_findclk(s, "mpu_intc_fclk"));
     qdev_prop_set_ptr(s->ih[0], "iclk", omap_findclk(s, "mpu_intc_iclk"));
     qdev_init_nofail(s->ih[0]);
     busdev = SYS_BUS_DEVICE(s->ih[0]);
-    sysbus_connect_irq(busdev, 0, cpu_irq[ARM_PIC_CPU_IRQ]);
-    sysbus_connect_irq(busdev, 1, cpu_irq[ARM_PIC_CPU_FIQ]);
+    sysbus_connect_irq(busdev, 0,
+                       qdev_get_gpio_in(DEVICE(s->cpu), ARM_CPU_IRQ));
+    sysbus_connect_irq(busdev, 1,
+                       qdev_get_gpio_in(DEVICE(s->cpu), ARM_CPU_FIQ));
     sysbus_mmio_map(busdev, 0, 0x480fe000);
     s->prcm = omap_prcm_init(omap_l4tao(s->l4, 3),
                              qdev_get_gpio_in(s->ih[0],
commit fcef61ec6bfaf96eeee0fb3024dd7ec8437ffa65
Author: Peter Maydell <peter.maydell at linaro.org>
Date:   Tue Aug 20 14:54:29 2013 +0100

    hw/arm/musicpal: Don't use arm_pic_init_cpu()
    
    Drop the now-deprecated arm_pic_init_cpu() in favour of directly
    getting the IRQ line from the ARMCPU object.
    
    Signed-off-by: Peter Maydell <peter.maydell at linaro.org>
    Message-id: 1375977856-25046-8-git-send-email-peter.maydell at linaro.org

diff --git a/hw/arm/musicpal.c b/hw/arm/musicpal.c
index d715143..4404b8d 100644
--- a/hw/arm/musicpal.c
+++ b/hw/arm/musicpal.c
@@ -1586,7 +1586,6 @@ static void musicpal_init(QEMUMachineInitArgs *args)
     const char *kernel_cmdline = args->kernel_cmdline;
     const char *initrd_filename = args->initrd_filename;
     ARMCPU *cpu;
-    qemu_irq *cpu_pic;
     qemu_irq pic[32];
     DeviceState *dev;
     DeviceState *i2c_dev;
@@ -1610,7 +1609,6 @@ static void musicpal_init(QEMUMachineInitArgs *args)
         fprintf(stderr, "Unable to find CPU definition\n");
         exit(1);
     }
-    cpu_pic = arm_pic_init_cpu(cpu);
 
     /* For now we use a fixed - the original - RAM size */
     memory_region_init_ram(ram, NULL, "musicpal.ram", MP_RAM_DEFAULT_SIZE);
@@ -1622,7 +1620,7 @@ static void musicpal_init(QEMUMachineInitArgs *args)
     memory_region_add_subregion(address_space_mem, MP_SRAM_BASE, sram);
 
     dev = sysbus_create_simple(TYPE_MV88W8618_PIC, MP_PIC_BASE,
-                               cpu_pic[ARM_PIC_CPU_IRQ]);
+                               qdev_get_gpio_in(DEVICE(cpu), ARM_CPU_IRQ));
     for (i = 0; i < 32; i++) {
         pic[i] = qdev_get_gpio_in(dev, i);
     }
commit 2f69ba1736e9460aa04c46790c1d34edfbee563a
Author: Peter Maydell <peter.maydell at linaro.org>
Date:   Tue Aug 20 14:54:29 2013 +0100

    hw/arm/kzm: Don't use arm_pic_init_cpu()
    
    Drop the now-deprecated arm_pic_init_cpu() in favour of directly
    getting the IRQ line from the ARMCPU object.
    
    Signed-off-by: Peter Maydell <peter.maydell at linaro.org>
    Message-id: 1375977856-25046-7-git-send-email-peter.maydell at linaro.org

diff --git a/hw/arm/kzm.c b/hw/arm/kzm.c
index bd6c05c..a248bf0 100644
--- a/hw/arm/kzm.c
+++ b/hw/arm/kzm.c
@@ -82,7 +82,6 @@ static void kzm_init(QEMUMachineInitArgs *args)
     MemoryRegion *ram = g_new(MemoryRegion, 1);
     MemoryRegion *sram = g_new(MemoryRegion, 1);
     MemoryRegion *ram_alias = g_new(MemoryRegion, 1);
-    qemu_irq *cpu_pic;
     DeviceState *dev;
     DeviceState *ccm;
 
@@ -108,11 +107,10 @@ static void kzm_init(QEMUMachineInitArgs *args)
     memory_region_init_ram(sram, NULL, "kzm.sram", 0x4000);
     memory_region_add_subregion(address_space_mem, 0x1FFFC000, sram);
 
-    cpu_pic = arm_pic_init_cpu(cpu);
     dev = sysbus_create_varargs("imx_avic", 0x68000000,
-                                cpu_pic[ARM_PIC_CPU_IRQ],
-                                cpu_pic[ARM_PIC_CPU_FIQ], NULL);
-
+                                qdev_get_gpio_in(DEVICE(cpu), ARM_CPU_IRQ),
+                                qdev_get_gpio_in(DEVICE(cpu), ARM_CPU_FIQ),
+                                NULL);
 
     imx_serial_create(0, 0x43f90000, qdev_get_gpio_in(dev, 45));
     imx_serial_create(1, 0x43f94000, qdev_get_gpio_in(dev, 32));
commit 99d228d6e9b08488d62029c438f8381b8c72d109
Author: Peter Maydell <peter.maydell at linaro.org>
Date:   Tue Aug 20 14:54:29 2013 +0100

    hw/arm/integratorcp: Don't use arm_pic_init_cpu()
    
    Drop the now-deprecated arm_pic_init_cpu() in favour of directly
    getting the IRQ line from the ARMCPU object.
    
    Signed-off-by: Peter Maydell <peter.maydell at linaro.org>
    Message-id: 1375977856-25046-6-git-send-email-peter.maydell at linaro.org

diff --git a/hw/arm/integratorcp.c b/hw/arm/integratorcp.c
index d518188..59c3726 100644
--- a/hw/arm/integratorcp.c
+++ b/hw/arm/integratorcp.c
@@ -465,7 +465,6 @@ static void integratorcp_init(QEMUMachineInitArgs *args)
     MemoryRegion *ram = g_new(MemoryRegion, 1);
     MemoryRegion *ram_alias = g_new(MemoryRegion, 1);
     qemu_irq pic[32];
-    qemu_irq *cpu_pic;
     DeviceState *dev;
     int i;
 
@@ -493,10 +492,10 @@ static void integratorcp_init(QEMUMachineInitArgs *args)
     qdev_init_nofail(dev);
     sysbus_mmio_map((SysBusDevice *)dev, 0, 0x10000000);
 
-    cpu_pic = arm_pic_init_cpu(cpu);
     dev = sysbus_create_varargs(TYPE_INTEGRATOR_PIC, 0x14000000,
-                                cpu_pic[ARM_PIC_CPU_IRQ],
-                                cpu_pic[ARM_PIC_CPU_FIQ], NULL);
+                                qdev_get_gpio_in(DEVICE(cpu), ARM_CPU_IRQ),
+                                qdev_get_gpio_in(DEVICE(cpu), ARM_CPU_FIQ),
+                                NULL);
     for (i = 0; i < 32; i++) {
         pic[i] = qdev_get_gpio_in(dev, i);
     }
commit 9188dbf71accf9d97f2e434380ea210ba75705ca
Author: Peter Maydell <peter.maydell at linaro.org>
Date:   Tue Aug 20 14:54:29 2013 +0100

    hw/arm/highbank: Don't use arm_pic_init_cpu()
    
    Drop the now-deprecated arm_pic_init_cpu() in favour of directly
    getting the IRQ line from the ARMCPU object.
    
    Signed-off-by: Peter Maydell <peter.maydell at linaro.org>
    Message-id: 1375977856-25046-5-git-send-email-peter.maydell at linaro.org

diff --git a/hw/arm/highbank.c b/hw/arm/highbank.c
index 35d5511..f733a6c 100644
--- a/hw/arm/highbank.c
+++ b/hw/arm/highbank.c
@@ -209,7 +209,6 @@ static void calxeda_init(QEMUMachineInitArgs *args, enum cxmachines machine)
     const char *initrd_filename = args->initrd_filename;
     DeviceState *dev = NULL;
     SysBusDevice *busdev;
-    qemu_irq *irqp;
     qemu_irq pic[128];
     int n;
     qemu_irq cpu_irq[4];
@@ -239,8 +238,7 @@ static void calxeda_init(QEMUMachineInitArgs *args, enum cxmachines machine)
 
         /* This will become a QOM property eventually */
         cpu->reset_cbar = GIC_BASE_ADDR;
-        irqp = arm_pic_init_cpu(cpu);
-        cpu_irq[n] = irqp[ARM_PIC_CPU_IRQ];
+        cpu_irq[n] = qdev_get_gpio_in(DEVICE(cpu), ARM_CPU_IRQ);
     }
 
     sysmem = get_system_memory();
commit ad666d91f43574fb200c738bc793023ae23d24a5
Author: Peter Maydell <peter.maydell at linaro.org>
Date:   Tue Aug 20 14:54:28 2013 +0100

    hw/arm/exynos4210: Don't use arm_pic_init_cpu()
    
    Drop the now-deprecated arm_pic_init_cpu() in favour of directly
    getting the IRQ line from the ARMCPU object.
    
    Signed-off-by: Peter Maydell <peter.maydell at linaro.org>
    Message-id: 1375977856-25046-4-git-send-email-peter.maydell at linaro.org

diff --git a/hw/arm/exynos4210.c b/hw/arm/exynos4210.c
index 216b9b7..4ebb938 100644
--- a/hw/arm/exynos4210.c
+++ b/hw/arm/exynos4210.c
@@ -137,10 +137,8 @@ void exynos4210_write_secondary(ARMCPU *cpu,
 Exynos4210State *exynos4210_init(MemoryRegion *system_mem,
         unsigned long ram_size)
 {
-    qemu_irq cpu_irq[EXYNOS4210_NCPUS];
     int i, n;
     Exynos4210State *s = g_new(Exynos4210State, 1);
-    qemu_irq *irqp;
     qemu_irq gate_irq[EXYNOS4210_NCPUS][EXYNOS4210_IRQ_GATE_NINPUTS];
     unsigned long mem_size;
     DeviceState *dev;
@@ -152,15 +150,6 @@ Exynos4210State *exynos4210_init(MemoryRegion *system_mem,
             fprintf(stderr, "Unable to find CPU %d definition\n", n);
             exit(1);
         }
-
-        /* Create PIC controller for each processor instance */
-        irqp = arm_pic_init_cpu(s->cpu[n]);
-
-        /*
-         * Get GICs gpio_in cpu_irq to connect a combiner to them later.
-         * Use only IRQ for a while.
-         */
-        cpu_irq[n] = irqp[ARM_PIC_CPU_IRQ];
     }
 
     /*** IRQs ***/
@@ -178,8 +167,9 @@ Exynos4210State *exynos4210_init(MemoryRegion *system_mem,
         }
         busdev = SYS_BUS_DEVICE(dev);
 
-        /* Connect IRQ Gate output to cpu_irq */
-        sysbus_connect_irq(busdev, 0, cpu_irq[i]);
+        /* Connect IRQ Gate output to CPU's IRQ line */
+        sysbus_connect_irq(busdev, 0,
+                           qdev_get_gpio_in(DEVICE(s->cpu[i]), ARM_CPU_IRQ));
     }
 
     /* Private memory region and Internal GIC */
commit de3a658f5b1d4ea290cb4369c55e83fdead81933
Author: Peter Maydell <peter.maydell at linaro.org>
Date:   Tue Aug 20 14:54:28 2013 +0100

    hw/arm/armv7m: Don't use arm_pic_init_cpu()
    
    Drop the now-deprecated arm_pic_init_cpu() in favour of directly
    getting the IRQ line from the ARMCPU object.
    
    Signed-off-by: Peter Maydell <peter.maydell at linaro.org>
    Message-id: 1375977856-25046-3-git-send-email-peter.maydell at linaro.org

diff --git a/hw/arm/armv7m.c b/hw/arm/armv7m.c
index 82d36fb..89a9015 100644
--- a/hw/arm/armv7m.c
+++ b/hw/arm/armv7m.c
@@ -173,7 +173,6 @@ qemu_irq *armv7m_init(MemoryRegion *address_space_mem,
     DeviceState *nvic;
     /* FIXME: make this local state.  */
     static qemu_irq pic[64];
-    qemu_irq *cpu_pic;
     int image_size;
     uint64_t entry;
     uint64_t lowaddr;
@@ -221,8 +220,8 @@ qemu_irq *armv7m_init(MemoryRegion *address_space_mem,
     nvic = qdev_create(NULL, "armv7m_nvic");
     env->nvic = nvic;
     qdev_init_nofail(nvic);
-    cpu_pic = arm_pic_init_cpu(cpu);
-    sysbus_connect_irq(SYS_BUS_DEVICE(nvic), 0, cpu_pic[ARM_PIC_CPU_IRQ]);
+    sysbus_connect_irq(SYS_BUS_DEVICE(nvic), 0,
+                       qdev_get_gpio_in(DEVICE(cpu), ARM_CPU_IRQ));
     for (i = 0; i < 64; i++) {
         pic[i] = qdev_get_gpio_in(nvic, i);
     }
commit 7c1840b686e34ed138414ff0fe395a63f031387e
Author: Peter Maydell <peter.maydell at linaro.org>
Date:   Tue Aug 20 14:54:28 2013 +0100

    target-arm: Make IRQ and FIQ gpio lines on the CPU object
    
    Now that ARMCPU is a subclass of DeviceState, we can make the
    CPU's inbound IRQ and FIQ lines be simply gpio lines, which
    means we can remove the odd arm_pic shim.
    
    We retain the arm_pic_init_cpu() function as a backwards
    compatibility shim layer so we can convert the board models
    to get the IRQ and FIQ lines directly from the ARMCPU
    object one at a time.
    
    Signed-off-by: Peter Maydell <peter.maydell at linaro.org>
    Message-id: 1375977856-25046-2-git-send-email-peter.maydell at linaro.org

diff --git a/hw/arm/pic_cpu.c b/hw/arm/pic_cpu.c
index 875280a..9c36273 100644
--- a/hw/arm/pic_cpu.c
+++ b/hw/arm/pic_cpu.c
@@ -9,60 +9,17 @@
 
 #include "hw/hw.h"
 #include "hw/arm/arm.h"
-#include "sysemu/kvm.h"
-
-/* Input 0 is IRQ and input 1 is FIQ.  */
-static void arm_pic_cpu_handler(void *opaque, int irq, int level)
-{
-    ARMCPU *cpu = opaque;
-    CPUState *cs = CPU(cpu);
-
-    switch (irq) {
-    case ARM_PIC_CPU_IRQ:
-        if (level) {
-            cpu_interrupt(cs, CPU_INTERRUPT_HARD);
-        } else {
-            cpu_reset_interrupt(cs, CPU_INTERRUPT_HARD);
-        }
-        break;
-    case ARM_PIC_CPU_FIQ:
-        if (level) {
-            cpu_interrupt(cs, CPU_INTERRUPT_FIQ);
-        } else {
-            cpu_reset_interrupt(cs, CPU_INTERRUPT_FIQ);
-        }
-        break;
-    default:
-        hw_error("arm_pic_cpu_handler: Bad interrupt line %d\n", irq);
-    }
-}
-
-static void kvm_arm_pic_cpu_handler(void *opaque, int irq, int level)
-{
-#ifdef CONFIG_KVM
-    ARMCPU *cpu = opaque;
-    CPUState *cs = CPU(cpu);
-    int kvm_irq = KVM_ARM_IRQ_TYPE_CPU << KVM_ARM_IRQ_TYPE_SHIFT;
-
-    switch (irq) {
-    case ARM_PIC_CPU_IRQ:
-        kvm_irq |= KVM_ARM_IRQ_CPU_IRQ;
-        break;
-    case ARM_PIC_CPU_FIQ:
-        kvm_irq |= KVM_ARM_IRQ_CPU_FIQ;
-        break;
-    default:
-        hw_error("kvm_arm_pic_cpu_handler: Bad interrupt line %d\n", irq);
-    }
-    kvm_irq |= cs->cpu_index << KVM_ARM_IRQ_VCPU_SHIFT;
-    kvm_set_irq(kvm_state, kvm_irq, level ? 1 : 0);
-#endif
-}
 
+/* Backwards compatibility shim; this can disappear when all
+ * board models have been updated to get IRQ and FIQ lines directly
+ * from the ARMCPU object rather than by calling this function.
+ */
 qemu_irq *arm_pic_init_cpu(ARMCPU *cpu)
 {
-    if (kvm_enabled()) {
-        return qemu_allocate_irqs(kvm_arm_pic_cpu_handler, cpu, 2);
-    }
-    return qemu_allocate_irqs(arm_pic_cpu_handler, cpu, 2);
+    DeviceState *dev = DEVICE(cpu);
+    qemu_irq *irqs = g_new(qemu_irq, 2);
+
+    irqs[0] = qdev_get_gpio_in(dev, ARM_CPU_IRQ);
+    irqs[1] = qdev_get_gpio_in(dev, ARM_CPU_FIQ);
+    return irqs;
 }
diff --git a/target-arm/cpu.c b/target-arm/cpu.c
index 5a7566b..6f56aa8 100644
--- a/target-arm/cpu.c
+++ b/target-arm/cpu.c
@@ -23,7 +23,9 @@
 #if !defined(CONFIG_USER_ONLY)
 #include "hw/loader.h"
 #endif
+#include "hw/arm/arm.h"
 #include "sysemu/sysemu.h"
+#include "sysemu/kvm.h"
 
 static void arm_cpu_set_pc(CPUState *cs, vaddr value)
 {
@@ -129,6 +131,55 @@ static void arm_cpu_reset(CPUState *s)
     tb_flush(env);
 }
 
+#ifndef CONFIG_USER_ONLY
+static void arm_cpu_set_irq(void *opaque, int irq, int level)
+{
+    ARMCPU *cpu = opaque;
+    CPUState *cs = CPU(cpu);
+
+    switch (irq) {
+    case ARM_CPU_IRQ:
+        if (level) {
+            cpu_interrupt(cs, CPU_INTERRUPT_HARD);
+        } else {
+            cpu_reset_interrupt(cs, CPU_INTERRUPT_HARD);
+        }
+        break;
+    case ARM_CPU_FIQ:
+        if (level) {
+            cpu_interrupt(cs, CPU_INTERRUPT_FIQ);
+        } else {
+            cpu_reset_interrupt(cs, CPU_INTERRUPT_FIQ);
+        }
+        break;
+    default:
+        hw_error("arm_cpu_set_irq: Bad interrupt line %d\n", irq);
+    }
+}
+
+static void arm_cpu_kvm_set_irq(void *opaque, int irq, int level)
+{
+#ifdef CONFIG_KVM
+    ARMCPU *cpu = opaque;
+    CPUState *cs = CPU(cpu);
+    int kvm_irq = KVM_ARM_IRQ_TYPE_CPU << KVM_ARM_IRQ_TYPE_SHIFT;
+
+    switch (irq) {
+    case ARM_CPU_IRQ:
+        kvm_irq |= KVM_ARM_IRQ_CPU_IRQ;
+        break;
+    case ARM_CPU_FIQ:
+        kvm_irq |= KVM_ARM_IRQ_CPU_FIQ;
+        break;
+    default:
+        hw_error("arm_cpu_kvm_set_irq: Bad interrupt line %d\n", irq);
+    }
+    kvm_irq |= cs->cpu_index << KVM_ARM_IRQ_VCPU_SHIFT;
+    kvm_set_irq(kvm_state, kvm_irq, level ? 1 : 0);
+#endif
+}
+#endif
+
 static inline void set_feature(CPUARMState *env, int feature)
 {
     env->features |= 1ULL << feature;
@@ -145,6 +196,15 @@ static void arm_cpu_initfn(Object *obj)
     cpu->cp_regs = g_hash_table_new_full(g_int_hash, g_int_equal,
                                          g_free, g_free);
 
+#ifndef CONFIG_USER_ONLY
+    /* Our inbound IRQ and FIQ lines */
+    if (kvm_enabled()) {
+        qdev_init_gpio_in(DEVICE(cpu), arm_cpu_kvm_set_irq, 2);
+    } else {
+        qdev_init_gpio_in(DEVICE(cpu), arm_cpu_set_irq, 2);
+    }
+#endif
+
     if (tcg_enabled() && !inited) {
         inited = true;
         arm_translate_init();
diff --git a/target-arm/cpu.h b/target-arm/cpu.h
index b2dc494..dffeec7 100644
--- a/target-arm/cpu.h
+++ b/target-arm/cpu.h
@@ -58,6 +58,9 @@
 /* ARM-specific interrupt pending bits.  */
 #define CPU_INTERRUPT_FIQ   CPU_INTERRUPT_TGT_EXT_1
 
+/* Meanings of the ARMCPU object's two inbound GPIO lines */
+#define ARM_CPU_IRQ 0
+#define ARM_CPU_FIQ 1
 
 typedef void ARMWriteCPFunc(void *opaque, int cp_info,
                             int srcreg, int operand, uint32_t value);
commit 3f1beaca88bffa4828cc86beb89ff70474516d91
Author: Peter Maydell <peter.maydell at linaro.org>
Date:   Tue Aug 20 14:54:28 2013 +0100

    target-arm: Implement 'int' loglevel
    
    The 'int' loglevel for recording interrupts and exceptions
    requires support in the target-specific code. Implement
    it for ARM. This improves debug logging in some situations
    that were otherwise pretty opaque, such as when we fault
    trying to execute at an exception vector address, which
    would otherwise cause an infinite loop of taking exceptions
    without any indication in the debug log of what was going on.
    
    Signed-off-by: Peter Maydell <peter.maydell at linaro.org>
    Reviewed-by: Richard Henderson <rth at twiddle.net>
    Message-id: 1375700771-21665-1-git-send-email-peter.maydell at linaro.org

diff --git a/target-arm/helper.c b/target-arm/helper.c
index 4968391..6d9026d 100644
--- a/target-arm/helper.c
+++ b/target-arm/helper.c
@@ -1974,6 +1974,37 @@ static void do_v7m_exception_exit(CPUARMState *env)
        pointer.  */
 }
 
+/* Exception names for debug logging; note that not all of these
+ * precisely correspond to architectural exceptions.
+ */
+static const char * const excnames[] = {
+    [EXCP_UDEF] = "Undefined Instruction",
+    [EXCP_SWI] = "SVC",
+    [EXCP_PREFETCH_ABORT] = "Prefetch Abort",
+    [EXCP_DATA_ABORT] = "Data Abort",
+    [EXCP_IRQ] = "IRQ",
+    [EXCP_FIQ] = "FIQ",
+    [EXCP_BKPT] = "Breakpoint",
+    [EXCP_EXCEPTION_EXIT] = "QEMU v7M exception exit",
+    [EXCP_KERNEL_TRAP] = "QEMU intercept of kernel commpage",
+    [EXCP_STREX] = "QEMU intercept of STREX",
+};
+
+static inline void arm_log_exception(int idx)
+{
+    if (qemu_loglevel_mask(CPU_LOG_INT)) {
+        const char *exc = NULL;
+
+        if (idx >= 0 && idx < ARRAY_SIZE(excnames)) {
+            exc = excnames[idx];
+        }
+        if (!exc) {
+            exc = "unknown";
+        }
+        qemu_log_mask(CPU_LOG_INT, "Taking exception %d [%s]\n", idx, exc);
+    }
+}
+
 void arm_v7m_cpu_do_interrupt(CPUState *cs)
 {
     ARMCPU *cpu = ARM_CPU(cs);
@@ -1982,6 +2013,8 @@ void arm_v7m_cpu_do_interrupt(CPUState *cs)
     uint32_t lr;
     uint32_t addr;
 
+    arm_log_exception(env->exception_index);
+
     lr = 0xfffffff1;
     if (env->v7m.current_sp)
         lr |= 4;
@@ -2011,6 +2044,7 @@ void arm_v7m_cpu_do_interrupt(CPUState *cs)
             if (nr == 0xab) {
                 env->regs[15] += 2;
                 env->regs[0] = do_arm_semihosting(env);
+                qemu_log_mask(CPU_LOG_INT, "...handled as semihosting call\n");
                 return;
             }
         }
@@ -2064,6 +2098,8 @@ void arm_cpu_do_interrupt(CPUState *cs)
 
     assert(!IS_M(env));
 
+    arm_log_exception(env->exception_index);
+
     /* TODO: Vectored interrupt controller.  */
     switch (env->exception_index) {
     case EXCP_UDEF:
@@ -2091,6 +2127,7 @@ void arm_cpu_do_interrupt(CPUState *cs)
                     || (mask == 0xab && env->thumb))
                   && (env->uncached_cpsr & CPSR_M) != ARM_CPU_MODE_USR) {
                 env->regs[0] = do_arm_semihosting(env);
+                qemu_log_mask(CPU_LOG_INT, "...handled as semihosting call\n");
                 return;
             }
         }
@@ -2108,18 +2145,23 @@ void arm_cpu_do_interrupt(CPUState *cs)
                   && (env->uncached_cpsr & CPSR_M) != ARM_CPU_MODE_USR) {
                 env->regs[15] += 2;
                 env->regs[0] = do_arm_semihosting(env);
+                qemu_log_mask(CPU_LOG_INT, "...handled as semihosting call\n");
                 return;
             }
         }
         env->cp15.c5_insn = 2;
         /* Fall through to prefetch abort.  */
     case EXCP_PREFETCH_ABORT:
+        qemu_log_mask(CPU_LOG_INT, "...with IFSR 0x%x IFAR 0x%x\n",
+                      env->cp15.c5_insn, env->cp15.c6_insn);
         new_mode = ARM_CPU_MODE_ABT;
         addr = 0x0c;
         mask = CPSR_A | CPSR_I;
         offset = 4;
         break;
     case EXCP_DATA_ABORT:
+        qemu_log_mask(CPU_LOG_INT, "...with DFSR 0x%x DFAR 0x%x\n",
+                      env->cp15.c5_data, env->cp15.c6_data);
         new_mode = ARM_CPU_MODE_ABT;
         addr = 0x10;
         mask = CPSR_A | CPSR_I;
commit f2e5dca46b5ba4588c0756c5f272123585cbbf23
Author: Stefan Hajnoczi <stefanha at redhat.com>
Date:   Thu Apr 11 17:26:25 2013 +0200

    aio: drop io_flush argument
    
    The .io_flush() handler no longer exists and has no users.  Drop the
    io_flush argument to aio_set_fd_handler() and related functions.
    
    The AioFlushEventNotifierHandler and AioFlushHandler typedefs are no
    longer used and are dropped too.
    
    Reviewed-by: Paolo Bonzini <pbonzini at redhat.com>
    Signed-off-by: Stefan Hajnoczi <stefanha at redhat.com>

diff --git a/aio-posix.c b/aio-posix.c
index 7d66048..2440eb9 100644
--- a/aio-posix.c
+++ b/aio-posix.c
@@ -46,7 +46,6 @@ void aio_set_fd_handler(AioContext *ctx,
                         int fd,
                         IOHandler *io_read,
                         IOHandler *io_write,
-                        AioFlushHandler *io_flush,
                         void *opaque)
 {
     AioHandler *node;
@@ -95,12 +94,10 @@ void aio_set_fd_handler(AioContext *ctx,
 
 void aio_set_event_notifier(AioContext *ctx,
                             EventNotifier *notifier,
-                            EventNotifierHandler *io_read,
-                            AioFlushEventNotifierHandler *io_flush)
+                            EventNotifierHandler *io_read)
 {
     aio_set_fd_handler(ctx, event_notifier_get_fd(notifier),
-                       (IOHandler *)io_read, NULL,
-                       (AioFlushHandler *)io_flush, notifier);
+                       (IOHandler *)io_read, NULL, notifier);
 }
 
 bool aio_pending(AioContext *ctx)
diff --git a/aio-win32.c b/aio-win32.c
index 4309c16..78b2801 100644
--- a/aio-win32.c
+++ b/aio-win32.c
@@ -30,8 +30,7 @@ struct AioHandler {
 
 void aio_set_event_notifier(AioContext *ctx,
                             EventNotifier *e,
-                            EventNotifierHandler *io_notify,
-                            AioFlushEventNotifierHandler *io_flush)
+                            EventNotifierHandler *io_notify)
 {
     AioHandler *node;
 
diff --git a/async.c b/async.c
index 5ce3633..9791d8e 100644
--- a/async.c
+++ b/async.c
@@ -201,7 +201,7 @@ aio_ctx_finalize(GSource     *source)
     AioContext *ctx = (AioContext *) source;
 
     thread_pool_free(ctx->thread_pool);
-    aio_set_event_notifier(ctx, &ctx->notifier, NULL, NULL);
+    aio_set_event_notifier(ctx, &ctx->notifier, NULL);
     event_notifier_cleanup(&ctx->notifier);
     qemu_mutex_destroy(&ctx->bh_lock);
     g_array_free(ctx->pollfds, TRUE);
@@ -243,7 +243,7 @@ AioContext *aio_context_new(void)
     event_notifier_init(&ctx->notifier, false);
     aio_set_event_notifier(ctx, &ctx->notifier, 
                            (EventNotifierHandler *)
-                           event_notifier_test_and_clear, NULL);
+                           event_notifier_test_and_clear);
 
     return ctx;
 }
diff --git a/block/curl.c b/block/curl.c
index 5999924..e566855 100644
--- a/block/curl.c
+++ b/block/curl.c
@@ -93,17 +93,16 @@ static int curl_sock_cb(CURL *curl, curl_socket_t fd, int action,
     DPRINTF("CURL (AIO): Sock action %d on fd %d\n", action, fd);
     switch (action) {
         case CURL_POLL_IN:
-            qemu_aio_set_fd_handler(fd, curl_multi_do, NULL, NULL, s);
+            qemu_aio_set_fd_handler(fd, curl_multi_do, NULL, s);
             break;
         case CURL_POLL_OUT:
-            qemu_aio_set_fd_handler(fd, NULL, curl_multi_do, NULL, s);
+            qemu_aio_set_fd_handler(fd, NULL, curl_multi_do, s);
             break;
         case CURL_POLL_INOUT:
-            qemu_aio_set_fd_handler(fd, curl_multi_do, curl_multi_do,
-                                    NULL, s);
+            qemu_aio_set_fd_handler(fd, curl_multi_do, curl_multi_do, s);
             break;
         case CURL_POLL_REMOVE:
-            qemu_aio_set_fd_handler(fd, NULL, NULL, NULL, NULL);
+            qemu_aio_set_fd_handler(fd, NULL, NULL, NULL);
             break;
     }
 
diff --git a/block/gluster.c b/block/gluster.c
index 3cb7500..46f36f8 100644
--- a/block/gluster.c
+++ b/block/gluster.c
@@ -339,7 +339,7 @@ static int qemu_gluster_open(BlockDriverState *bs,  QDict *options,
     }
     fcntl(s->fds[GLUSTER_FD_READ], F_SETFL, O_NONBLOCK);
     qemu_aio_set_fd_handler(s->fds[GLUSTER_FD_READ],
-        qemu_gluster_aio_event_reader, NULL, NULL, s);
+        qemu_gluster_aio_event_reader, NULL, s);
 
 out:
     qemu_opts_del(opts);
@@ -438,8 +438,7 @@ static void gluster_finish_aiocb(struct glfs_fd *fd, ssize_t ret, void *arg)
         qemu_aio_release(acb);
         close(s->fds[GLUSTER_FD_READ]);
         close(s->fds[GLUSTER_FD_WRITE]);
-        qemu_aio_set_fd_handler(s->fds[GLUSTER_FD_READ], NULL, NULL, NULL,
-            NULL);
+        qemu_aio_set_fd_handler(s->fds[GLUSTER_FD_READ], NULL, NULL, NULL);
         bs->drv = NULL; /* Make the disk inaccessible */
         qemu_mutex_unlock_iothread();
     }
@@ -595,7 +594,7 @@ static void qemu_gluster_close(BlockDriverState *bs)
 
     close(s->fds[GLUSTER_FD_READ]);
     close(s->fds[GLUSTER_FD_WRITE]);
-    qemu_aio_set_fd_handler(s->fds[GLUSTER_FD_READ], NULL, NULL, NULL, NULL);
+    qemu_aio_set_fd_handler(s->fds[GLUSTER_FD_READ], NULL, NULL, NULL);
 
     if (s->fd) {
         glfs_close(s->fd);
diff --git a/block/iscsi.c b/block/iscsi.c
index 180b827..47a3adc 100644
--- a/block/iscsi.c
+++ b/block/iscsi.c
@@ -159,7 +159,6 @@ iscsi_set_events(IscsiLun *iscsilun)
         qemu_aio_set_fd_handler(iscsi_get_fd(iscsi),
                       iscsi_process_read,
                       (ev & POLLOUT) ? iscsi_process_write : NULL,
-                      NULL,
                       iscsilun);
 
     }
@@ -1208,7 +1207,7 @@ static void iscsi_close(BlockDriverState *bs)
         qemu_del_timer(iscsilun->nop_timer);
         qemu_free_timer(iscsilun->nop_timer);
     }
-    qemu_aio_set_fd_handler(iscsi_get_fd(iscsi), NULL, NULL, NULL, NULL);
+    qemu_aio_set_fd_handler(iscsi_get_fd(iscsi), NULL, NULL, NULL);
     iscsi_destroy_context(iscsi);
     memset(iscsilun, 0, sizeof(IscsiLun));
 }
diff --git a/block/linux-aio.c b/block/linux-aio.c
index d9128f3..53434e2 100644
--- a/block/linux-aio.c
+++ b/block/linux-aio.c
@@ -190,8 +190,7 @@ void *laio_init(void)
         goto out_close_efd;
     }
 
-    qemu_aio_set_event_notifier(&s->e, qemu_laio_completion_cb,
-                                NULL);
+    qemu_aio_set_event_notifier(&s->e, qemu_laio_completion_cb);
 
     return s;
 
diff --git a/block/nbd.c b/block/nbd.c
index f1619f9..691066f 100644
--- a/block/nbd.c
+++ b/block/nbd.c
@@ -334,8 +334,7 @@ static int nbd_co_send_request(BDRVNBDState *s, struct nbd_request *request,
 
     qemu_co_mutex_lock(&s->send_mutex);
     s->send_coroutine = qemu_coroutine_self();
-    qemu_aio_set_fd_handler(s->sock, nbd_reply_ready, nbd_restart_write,
-                            NULL, s);
+    qemu_aio_set_fd_handler(s->sock, nbd_reply_ready, nbd_restart_write, s);
     if (qiov) {
         if (!s->is_unix) {
             socket_set_cork(s->sock, 1);
@@ -354,8 +353,7 @@ static int nbd_co_send_request(BDRVNBDState *s, struct nbd_request *request,
     } else {
         rc = nbd_send_request(s->sock, request);
     }
-    qemu_aio_set_fd_handler(s->sock, nbd_reply_ready, NULL,
-                            NULL, s);
+    qemu_aio_set_fd_handler(s->sock, nbd_reply_ready, NULL, s);
     s->send_coroutine = NULL;
     qemu_co_mutex_unlock(&s->send_mutex);
     return rc;
@@ -431,8 +429,7 @@ static int nbd_establish_connection(BlockDriverState *bs)
     /* Now that we're connected, set the socket to be non-blocking and
      * kick the reply mechanism.  */
     qemu_set_nonblock(sock);
-    qemu_aio_set_fd_handler(sock, nbd_reply_ready, NULL,
-                            NULL, s);
+    qemu_aio_set_fd_handler(sock, nbd_reply_ready, NULL, s);
 
     s->sock = sock;
     s->size = size;
@@ -452,7 +449,7 @@ static void nbd_teardown_connection(BlockDriverState *bs)
     request.len = 0;
     nbd_send_request(s->sock, &request);
 
-    qemu_aio_set_fd_handler(s->sock, NULL, NULL, NULL, NULL);
+    qemu_aio_set_fd_handler(s->sock, NULL, NULL, NULL);
     closesocket(s->sock);
 }
 
diff --git a/block/rbd.c b/block/rbd.c
index 71b4a0c..e798e19 100644
--- a/block/rbd.c
+++ b/block/rbd.c
@@ -545,7 +545,7 @@ static int qemu_rbd_open(BlockDriverState *bs, QDict *options, int flags)
     fcntl(s->fds[0], F_SETFL, O_NONBLOCK);
     fcntl(s->fds[1], F_SETFL, O_NONBLOCK);
     qemu_aio_set_fd_handler(s->fds[RBD_FD_READ], qemu_rbd_aio_event_reader,
-                            NULL, NULL, s);
+                            NULL, s);
 
 
     qemu_opts_del(opts);
@@ -569,7 +569,7 @@ static void qemu_rbd_close(BlockDriverState *bs)
 
     close(s->fds[0]);
     close(s->fds[1]);
-    qemu_aio_set_fd_handler(s->fds[RBD_FD_READ], NULL, NULL, NULL, NULL);
+    qemu_aio_set_fd_handler(s->fds[RBD_FD_READ], NULL, NULL, NULL);
 
     rbd_close(s->image);
     rados_ioctx_destroy(s->io_ctx);
diff --git a/block/sheepdog.c b/block/sheepdog.c
index 3fb4361..1ad4d07 100644
--- a/block/sheepdog.c
+++ b/block/sheepdog.c
@@ -531,14 +531,14 @@ static coroutine_fn void do_co_req(void *opaque)
     unsigned int *rlen = srco->rlen;
 
     co = qemu_coroutine_self();
-    qemu_aio_set_fd_handler(sockfd, NULL, restart_co_req, NULL, co);
+    qemu_aio_set_fd_handler(sockfd, NULL, restart_co_req, co);
 
     ret = send_co_req(sockfd, hdr, data, wlen);
     if (ret < 0) {
         goto out;
     }
 
-    qemu_aio_set_fd_handler(sockfd, restart_co_req, NULL, NULL, co);
+    qemu_aio_set_fd_handler(sockfd, restart_co_req, NULL, co);
 
     ret = qemu_co_recv(sockfd, hdr, sizeof(*hdr));
     if (ret < sizeof(*hdr)) {
@@ -563,7 +563,7 @@ static coroutine_fn void do_co_req(void *opaque)
 out:
     /* there is at most one request for this sockfd, so it is safe to
      * set each handler to NULL. */
-    qemu_aio_set_fd_handler(sockfd, NULL, NULL, NULL, NULL);
+    qemu_aio_set_fd_handler(sockfd, NULL, NULL, NULL);
 
     srco->ret = ret;
     srco->finished = true;
@@ -804,7 +804,7 @@ static int get_sheep_fd(BDRVSheepdogState *s)
         return fd;
     }
 
-    qemu_aio_set_fd_handler(fd, co_read_response, NULL, NULL, s);
+    qemu_aio_set_fd_handler(fd, co_read_response, NULL, s);
     return fd;
 }
 
@@ -1054,8 +1054,7 @@ static int coroutine_fn add_aio_request(BDRVSheepdogState *s, AIOReq *aio_req,
 
     qemu_co_mutex_lock(&s->lock);
     s->co_send = qemu_coroutine_self();
-    qemu_aio_set_fd_handler(s->fd, co_read_response, co_write_request,
-                            NULL, s);
+    qemu_aio_set_fd_handler(s->fd, co_read_response, co_write_request, s);
     socket_set_cork(s->fd, 1);
 
     /* send a header */
@@ -1076,8 +1075,7 @@ static int coroutine_fn add_aio_request(BDRVSheepdogState *s, AIOReq *aio_req,
     }
 
     socket_set_cork(s->fd, 0);
-    qemu_aio_set_fd_handler(s->fd, co_read_response, NULL,
-                            NULL, s);
+    qemu_aio_set_fd_handler(s->fd, co_read_response, NULL, s);
     qemu_co_mutex_unlock(&s->lock);
 
     return 0;
@@ -1335,7 +1333,7 @@ static int sd_open(BlockDriverState *bs, QDict *options, int flags)
     g_free(buf);
     return 0;
 out:
-    qemu_aio_set_fd_handler(s->fd, NULL, NULL, NULL, NULL);
+    qemu_aio_set_fd_handler(s->fd, NULL, NULL, NULL);
     if (s->fd >= 0) {
         closesocket(s->fd);
     }
@@ -1563,7 +1561,7 @@ static void sd_close(BlockDriverState *bs)
         error_report("%s, %s", sd_strerror(rsp->result), s->name);
     }
 
-    qemu_aio_set_fd_handler(s->fd, NULL, NULL, NULL, NULL);
+    qemu_aio_set_fd_handler(s->fd, NULL, NULL, NULL);
     closesocket(s->fd);
     g_free(s->host_spec);
 }
diff --git a/block/ssh.c b/block/ssh.c
index e149da9..27691b4 100644
--- a/block/ssh.c
+++ b/block/ssh.c
@@ -758,13 +758,13 @@ static coroutine_fn void set_fd_handler(BDRVSSHState *s)
     DPRINTF("s->sock=%d rd_handler=%p wr_handler=%p", s->sock,
             rd_handler, wr_handler);
 
-    qemu_aio_set_fd_handler(s->sock, rd_handler, wr_handler, NULL, co);
+    qemu_aio_set_fd_handler(s->sock, rd_handler, wr_handler, co);
 }
 
 static coroutine_fn void clear_fd_handler(BDRVSSHState *s)
 {
     DPRINTF("s->sock=%d", s->sock);
-    qemu_aio_set_fd_handler(s->sock, NULL, NULL, NULL, NULL);
+    qemu_aio_set_fd_handler(s->sock, NULL, NULL, NULL);
 }
 
 /* A non-blocking call returned EAGAIN, so yield, ensuring the
diff --git a/hw/block/dataplane/virtio-blk.c b/hw/block/dataplane/virtio-blk.c
index 82131b1..5a96ccd 100644
--- a/hw/block/dataplane/virtio-blk.c
+++ b/hw/block/dataplane/virtio-blk.c
@@ -472,7 +472,7 @@ void virtio_blk_data_plane_start(VirtIOBlockDataPlane *s)
         exit(1);
     }
     s->host_notifier = *virtio_queue_get_host_notifier(vq);
-    aio_set_event_notifier(s->ctx, &s->host_notifier, handle_notify, NULL);
+    aio_set_event_notifier(s->ctx, &s->host_notifier, handle_notify);
 
     /* Set up ioqueue */
     ioq_init(&s->ioqueue, s->fd, REQ_MAX);
@@ -480,7 +480,7 @@ void virtio_blk_data_plane_start(VirtIOBlockDataPlane *s)
         ioq_put_iocb(&s->ioqueue, &s->requests[i].iocb);
     }
     s->io_notifier = *ioq_get_notifier(&s->ioqueue);
-    aio_set_event_notifier(s->ctx, &s->io_notifier, handle_io, NULL);
+    aio_set_event_notifier(s->ctx, &s->io_notifier, handle_io);
 
     s->started = true;
     trace_virtio_blk_data_plane_start(s);
@@ -512,10 +512,10 @@ void virtio_blk_data_plane_stop(VirtIOBlockDataPlane *s)
         qemu_thread_join(&s->thread);
     }
 
-    aio_set_event_notifier(s->ctx, &s->io_notifier, NULL, NULL);
+    aio_set_event_notifier(s->ctx, &s->io_notifier, NULL);
     ioq_cleanup(&s->ioqueue);
 
-    aio_set_event_notifier(s->ctx, &s->host_notifier, NULL, NULL);
+    aio_set_event_notifier(s->ctx, &s->host_notifier, NULL);
     k->set_host_notifier(qbus->parent, 0, false);
 
     aio_context_unref(s->ctx);
diff --git a/include/block/aio.h b/include/block/aio.h
index cc77771..5743bf1 100644
--- a/include/block/aio.h
+++ b/include/block/aio.h
@@ -74,9 +74,6 @@ typedef struct AioContext {
     struct ThreadPool *thread_pool;
 } AioContext;
 
-/* Returns 1 if there are still outstanding AIO requests; 0 otherwise */
-typedef int (AioFlushEventNotifierHandler)(EventNotifier *e);
-
 /**
  * aio_context_new: Allocate a new AioContext.
  *
@@ -198,9 +195,6 @@ bool aio_pending(AioContext *ctx);
 bool aio_poll(AioContext *ctx, bool blocking);
 
 #ifdef CONFIG_POSIX
-/* Returns 1 if there are still outstanding AIO requests; 0 otherwise */
-typedef int (AioFlushHandler)(void *opaque);
-
 /* Register a file descriptor and associated callbacks.  Behaves very similarly
  * to qemu_set_fd_handler2.  Unlike qemu_set_fd_handler2, these callbacks will
  * be invoked when using qemu_aio_wait().
@@ -212,7 +206,6 @@ void aio_set_fd_handler(AioContext *ctx,
                         int fd,
                         IOHandler *io_read,
                         IOHandler *io_write,
-                        AioFlushHandler *io_flush,
                         void *opaque);
 #endif
 
@@ -225,8 +218,7 @@ void aio_set_fd_handler(AioContext *ctx,
  */
 void aio_set_event_notifier(AioContext *ctx,
                             EventNotifier *notifier,
-                            EventNotifierHandler *io_read,
-                            AioFlushEventNotifierHandler *io_flush);
+                            EventNotifierHandler *io_read);
 
 /* Return a GSource that lets the main loop poll the file descriptors attached
  * to this AioContext.
@@ -240,14 +232,12 @@ struct ThreadPool *aio_get_thread_pool(AioContext *ctx);
 
 bool qemu_aio_wait(void);
 void qemu_aio_set_event_notifier(EventNotifier *notifier,
-                                 EventNotifierHandler *io_read,
-                                 AioFlushEventNotifierHandler *io_flush);
+                                 EventNotifierHandler *io_read);
 
 #ifdef CONFIG_POSIX
 void qemu_aio_set_fd_handler(int fd,
                              IOHandler *io_read,
                              IOHandler *io_write,
-                             AioFlushHandler *io_flush,
                              void *opaque);
 #endif
 
diff --git a/main-loop.c b/main-loop.c
index a44fff6..2d9774e 100644
--- a/main-loop.c
+++ b/main-loop.c
@@ -489,17 +489,14 @@ bool qemu_aio_wait(void)
 void qemu_aio_set_fd_handler(int fd,
                              IOHandler *io_read,
                              IOHandler *io_write,
-                             AioFlushHandler *io_flush,
                              void *opaque)
 {
-    aio_set_fd_handler(qemu_aio_context, fd, io_read, io_write, io_flush,
-                       opaque);
+    aio_set_fd_handler(qemu_aio_context, fd, io_read, io_write, opaque);
 }
 #endif
 
 void qemu_aio_set_event_notifier(EventNotifier *notifier,
-                                 EventNotifierHandler *io_read,
-                                 AioFlushEventNotifierHandler *io_flush)
+                                 EventNotifierHandler *io_read)
 {
-    aio_set_event_notifier(qemu_aio_context, notifier, io_read, io_flush);
+    aio_set_event_notifier(qemu_aio_context, notifier, io_read);
 }
diff --git a/tests/test-aio.c b/tests/test-aio.c
index 7b2892a..1ab5637 100644
--- a/tests/test-aio.c
+++ b/tests/test-aio.c
@@ -233,11 +233,11 @@ static void test_set_event_notifier(void)
 {
     EventNotifierTestData data = { .n = 0, .active = 0 };
     event_notifier_init(&data.e, false);
-    aio_set_event_notifier(ctx, &data.e, event_ready_cb, NULL);
+    aio_set_event_notifier(ctx, &data.e, event_ready_cb);
     g_assert(!aio_poll(ctx, false));
     g_assert_cmpint(data.n, ==, 0);
 
-    aio_set_event_notifier(ctx, &data.e, NULL, NULL);
+    aio_set_event_notifier(ctx, &data.e, NULL);
     g_assert(!aio_poll(ctx, false));
     g_assert_cmpint(data.n, ==, 0);
     event_notifier_cleanup(&data.e);
@@ -247,7 +247,7 @@ static void test_wait_event_notifier(void)
 {
     EventNotifierTestData data = { .n = 0, .active = 1 };
     event_notifier_init(&data.e, false);
-    aio_set_event_notifier(ctx, &data.e, event_ready_cb, NULL);
+    aio_set_event_notifier(ctx, &data.e, event_ready_cb);
     g_assert(!aio_poll(ctx, false));
     g_assert_cmpint(data.n, ==, 0);
     g_assert_cmpint(data.active, ==, 1);
@@ -261,7 +261,7 @@ static void test_wait_event_notifier(void)
     g_assert_cmpint(data.n, ==, 1);
     g_assert_cmpint(data.active, ==, 0);
 
-    aio_set_event_notifier(ctx, &data.e, NULL, NULL);
+    aio_set_event_notifier(ctx, &data.e, NULL);
     g_assert(!aio_poll(ctx, false));
     g_assert_cmpint(data.n, ==, 1);
 
@@ -272,7 +272,7 @@ static void test_flush_event_notifier(void)
 {
     EventNotifierTestData data = { .n = 0, .active = 10, .auto_set = true };
     event_notifier_init(&data.e, false);
-    aio_set_event_notifier(ctx, &data.e, event_ready_cb, NULL);
+    aio_set_event_notifier(ctx, &data.e, event_ready_cb);
     g_assert(!aio_poll(ctx, false));
     g_assert_cmpint(data.n, ==, 0);
     g_assert_cmpint(data.active, ==, 10);
@@ -288,7 +288,7 @@ static void test_flush_event_notifier(void)
     g_assert_cmpint(data.active, ==, 0);
     g_assert(!aio_poll(ctx, false));
 
-    aio_set_event_notifier(ctx, &data.e, NULL, NULL);
+    aio_set_event_notifier(ctx, &data.e, NULL);
     g_assert(!aio_poll(ctx, false));
     event_notifier_cleanup(&data.e);
 }
@@ -299,7 +299,7 @@ static void test_wait_event_notifier_noflush(void)
     EventNotifierTestData dummy = { .n = 0, .active = 1 };
 
     event_notifier_init(&data.e, false);
-    aio_set_event_notifier(ctx, &data.e, event_ready_cb, NULL);
+    aio_set_event_notifier(ctx, &data.e, event_ready_cb);
 
     g_assert(!aio_poll(ctx, false));
     g_assert_cmpint(data.n, ==, 0);
@@ -312,7 +312,7 @@ static void test_wait_event_notifier_noflush(void)
 
     /* An active event notifier forces aio_poll to look at EventNotifiers.  */
     event_notifier_init(&dummy.e, false);
-    aio_set_event_notifier(ctx, &dummy.e, event_ready_cb, NULL);
+    aio_set_event_notifier(ctx, &dummy.e, event_ready_cb);
 
     event_notifier_set(&data.e);
     g_assert(aio_poll(ctx, false));
@@ -332,10 +332,10 @@ static void test_wait_event_notifier_noflush(void)
     g_assert_cmpint(dummy.n, ==, 1);
     g_assert_cmpint(dummy.active, ==, 0);
 
-    aio_set_event_notifier(ctx, &dummy.e, NULL, NULL);
+    aio_set_event_notifier(ctx, &dummy.e, NULL);
     event_notifier_cleanup(&dummy.e);
 
-    aio_set_event_notifier(ctx, &data.e, NULL, NULL);
+    aio_set_event_notifier(ctx, &data.e, NULL);
     g_assert(!aio_poll(ctx, false));
     g_assert_cmpint(data.n, ==, 2);
 
@@ -515,11 +515,11 @@ static void test_source_set_event_notifier(void)
 {
     EventNotifierTestData data = { .n = 0, .active = 0 };
     event_notifier_init(&data.e, false);
-    aio_set_event_notifier(ctx, &data.e, event_ready_cb, NULL);
+    aio_set_event_notifier(ctx, &data.e, event_ready_cb);
     while (g_main_context_iteration(NULL, false));
     g_assert_cmpint(data.n, ==, 0);
 
-    aio_set_event_notifier(ctx, &data.e, NULL, NULL);
+    aio_set_event_notifier(ctx, &data.e, NULL);
     while (g_main_context_iteration(NULL, false));
     g_assert_cmpint(data.n, ==, 0);
     event_notifier_cleanup(&data.e);
@@ -529,7 +529,7 @@ static void test_source_wait_event_notifier(void)
 {
     EventNotifierTestData data = { .n = 0, .active = 1 };
     event_notifier_init(&data.e, false);
-    aio_set_event_notifier(ctx, &data.e, event_ready_cb, NULL);
+    aio_set_event_notifier(ctx, &data.e, event_ready_cb);
     g_assert(g_main_context_iteration(NULL, false));
     g_assert_cmpint(data.n, ==, 0);
     g_assert_cmpint(data.active, ==, 1);
@@ -543,7 +543,7 @@ static void test_source_wait_event_notifier(void)
     g_assert_cmpint(data.n, ==, 1);
     g_assert_cmpint(data.active, ==, 0);
 
-    aio_set_event_notifier(ctx, &data.e, NULL, NULL);
+    aio_set_event_notifier(ctx, &data.e, NULL);
     while (g_main_context_iteration(NULL, false));
     g_assert_cmpint(data.n, ==, 1);
 
@@ -554,7 +554,7 @@ static void test_source_flush_event_notifier(void)
 {
     EventNotifierTestData data = { .n = 0, .active = 10, .auto_set = true };
     event_notifier_init(&data.e, false);
-    aio_set_event_notifier(ctx, &data.e, event_ready_cb, NULL);
+    aio_set_event_notifier(ctx, &data.e, event_ready_cb);
     g_assert(g_main_context_iteration(NULL, false));
     g_assert_cmpint(data.n, ==, 0);
     g_assert_cmpint(data.active, ==, 10);
@@ -570,7 +570,7 @@ static void test_source_flush_event_notifier(void)
     g_assert_cmpint(data.active, ==, 0);
     g_assert(!g_main_context_iteration(NULL, false));
 
-    aio_set_event_notifier(ctx, &data.e, NULL, NULL);
+    aio_set_event_notifier(ctx, &data.e, NULL);
     while (g_main_context_iteration(NULL, false));
     event_notifier_cleanup(&data.e);
 }
@@ -581,7 +581,7 @@ static void test_source_wait_event_notifier_noflush(void)
     EventNotifierTestData dummy = { .n = 0, .active = 1 };
 
     event_notifier_init(&data.e, false);
-    aio_set_event_notifier(ctx, &data.e, event_ready_cb, NULL);
+    aio_set_event_notifier(ctx, &data.e, event_ready_cb);
 
     while (g_main_context_iteration(NULL, false));
     g_assert_cmpint(data.n, ==, 0);
@@ -594,7 +594,7 @@ static void test_source_wait_event_notifier_noflush(void)
 
     /* An active event notifier forces aio_poll to look at EventNotifiers.  */
     event_notifier_init(&dummy.e, false);
-    aio_set_event_notifier(ctx, &dummy.e, event_ready_cb, NULL);
+    aio_set_event_notifier(ctx, &dummy.e, event_ready_cb);
 
     event_notifier_set(&data.e);
     g_assert(g_main_context_iteration(NULL, false));
@@ -614,10 +614,10 @@ static void test_source_wait_event_notifier_noflush(void)
     g_assert_cmpint(dummy.n, ==, 1);
     g_assert_cmpint(dummy.active, ==, 0);
 
-    aio_set_event_notifier(ctx, &dummy.e, NULL, NULL);
+    aio_set_event_notifier(ctx, &dummy.e, NULL);
     event_notifier_cleanup(&dummy.e);
 
-    aio_set_event_notifier(ctx, &data.e, NULL, NULL);
+    aio_set_event_notifier(ctx, &data.e, NULL);
     while (g_main_context_iteration(NULL, false));
     g_assert_cmpint(data.n, ==, 2);
 
diff --git a/thread-pool.c b/thread-pool.c
index 096f007..5025567 100644
--- a/thread-pool.c
+++ b/thread-pool.c
@@ -303,8 +303,7 @@ static void thread_pool_init_one(ThreadPool *pool, AioContext *ctx)
     QLIST_INIT(&pool->head);
     QTAILQ_INIT(&pool->request_list);
 
-    aio_set_event_notifier(ctx, &pool->notifier, event_notifier_ready,
-                           NULL);
+    aio_set_event_notifier(ctx, &pool->notifier, event_notifier_ready);
 }
 
 ThreadPool *thread_pool_new(AioContext *ctx)
@@ -338,7 +337,7 @@ void thread_pool_free(ThreadPool *pool)
 
     qemu_mutex_unlock(&pool->lock);
 
-    aio_set_event_notifier(pool->ctx, &pool->notifier, NULL, NULL);
+    aio_set_event_notifier(pool->ctx, &pool->notifier, NULL);
     qemu_sem_destroy(&pool->sem);
     qemu_cond_destroy(&pool->check_cancel);
     qemu_cond_destroy(&pool->worker_stopped);
commit 1b9ecdb16475485dffbcac7ff7f36dafa9e3cfd2
Author: Stefan Hajnoczi <stefanha at redhat.com>
Date:   Tue Apr 16 16:46:15 2013 +0200

    tests: drop event_active_cb()
    
    Drop the io_flush argument to aio_set_event_notifier().
    
    Reviewed-by: Paolo Bonzini <pbonzini at redhat.com>
    Signed-off-by: Stefan Hajnoczi <stefanha at redhat.com>

diff --git a/tests/test-aio.c b/tests/test-aio.c
index 1251952..7b2892a 100644
--- a/tests/test-aio.c
+++ b/tests/test-aio.c
@@ -65,12 +65,6 @@ static void bh_delete_cb(void *opaque)
     }
 }
 
-static int event_active_cb(EventNotifier *e)
-{
-    EventNotifierTestData *data = container_of(e, EventNotifierTestData, e);
-    return data->active > 0;
-}
-
 static void event_ready_cb(EventNotifier *e)
 {
     EventNotifierTestData *data = container_of(e, EventNotifierTestData, e);
@@ -239,7 +233,7 @@ static void test_set_event_notifier(void)
 {
     EventNotifierTestData data = { .n = 0, .active = 0 };
     event_notifier_init(&data.e, false);
-    aio_set_event_notifier(ctx, &data.e, event_ready_cb, event_active_cb);
+    aio_set_event_notifier(ctx, &data.e, event_ready_cb, NULL);
     g_assert(!aio_poll(ctx, false));
     g_assert_cmpint(data.n, ==, 0);
 
@@ -253,7 +247,7 @@ static void test_wait_event_notifier(void)
 {
     EventNotifierTestData data = { .n = 0, .active = 1 };
     event_notifier_init(&data.e, false);
-    aio_set_event_notifier(ctx, &data.e, event_ready_cb, event_active_cb);
+    aio_set_event_notifier(ctx, &data.e, event_ready_cb, NULL);
     g_assert(!aio_poll(ctx, false));
     g_assert_cmpint(data.n, ==, 0);
     g_assert_cmpint(data.active, ==, 1);
@@ -278,7 +272,7 @@ static void test_flush_event_notifier(void)
 {
     EventNotifierTestData data = { .n = 0, .active = 10, .auto_set = true };
     event_notifier_init(&data.e, false);
-    aio_set_event_notifier(ctx, &data.e, event_ready_cb, event_active_cb);
+    aio_set_event_notifier(ctx, &data.e, event_ready_cb, NULL);
     g_assert(!aio_poll(ctx, false));
     g_assert_cmpint(data.n, ==, 0);
     g_assert_cmpint(data.active, ==, 10);
@@ -318,7 +312,7 @@ static void test_wait_event_notifier_noflush(void)
 
     /* An active event notifier forces aio_poll to look at EventNotifiers.  */
     event_notifier_init(&dummy.e, false);
-    aio_set_event_notifier(ctx, &dummy.e, event_ready_cb, event_active_cb);
+    aio_set_event_notifier(ctx, &dummy.e, event_ready_cb, NULL);
 
     event_notifier_set(&data.e);
     g_assert(aio_poll(ctx, false));
@@ -521,7 +515,7 @@ static void test_source_set_event_notifier(void)
 {
     EventNotifierTestData data = { .n = 0, .active = 0 };
     event_notifier_init(&data.e, false);
-    aio_set_event_notifier(ctx, &data.e, event_ready_cb, event_active_cb);
+    aio_set_event_notifier(ctx, &data.e, event_ready_cb, NULL);
     while (g_main_context_iteration(NULL, false));
     g_assert_cmpint(data.n, ==, 0);
 
@@ -535,7 +529,7 @@ static void test_source_wait_event_notifier(void)
 {
     EventNotifierTestData data = { .n = 0, .active = 1 };
     event_notifier_init(&data.e, false);
-    aio_set_event_notifier(ctx, &data.e, event_ready_cb, event_active_cb);
+    aio_set_event_notifier(ctx, &data.e, event_ready_cb, NULL);
     g_assert(g_main_context_iteration(NULL, false));
     g_assert_cmpint(data.n, ==, 0);
     g_assert_cmpint(data.active, ==, 1);
@@ -560,7 +554,7 @@ static void test_source_flush_event_notifier(void)
 {
     EventNotifierTestData data = { .n = 0, .active = 10, .auto_set = true };
     event_notifier_init(&data.e, false);
-    aio_set_event_notifier(ctx, &data.e, event_ready_cb, event_active_cb);
+    aio_set_event_notifier(ctx, &data.e, event_ready_cb, NULL);
     g_assert(g_main_context_iteration(NULL, false));
     g_assert_cmpint(data.n, ==, 0);
     g_assert_cmpint(data.active, ==, 10);
@@ -600,7 +594,7 @@ static void test_source_wait_event_notifier_noflush(void)
 
     /* An active event notifier forces aio_poll to look at EventNotifiers.  */
     event_notifier_init(&dummy.e, false);
-    aio_set_event_notifier(ctx, &dummy.e, event_ready_cb, event_active_cb);
+    aio_set_event_notifier(ctx, &dummy.e, event_ready_cb, NULL);
 
     event_notifier_set(&data.e);
     g_assert(g_main_context_iteration(NULL, false));
commit bb52b14be163cc91409017639b8df32c99c1563a
Author: Stefan Hajnoczi <stefanha at redhat.com>
Date:   Thu Apr 11 17:22:08 2013 +0200

    thread-pool: drop thread_pool_active()
    
    .io_flush() is no longer called so drop thread_pool_active().  The block
    layer is the only thread-pool.c user and it already tracks in-flight
    requests, therefore we do not need thread_pool_active().
    
    Signed-off-by: Stefan Hajnoczi <stefanha at redhat.com>

diff --git a/thread-pool.c b/thread-pool.c
index 0ebd4c2..096f007 100644
--- a/thread-pool.c
+++ b/thread-pool.c
@@ -197,12 +197,6 @@ restart:
     }
 }
 
-static int thread_pool_active(EventNotifier *notifier)
-{
-    ThreadPool *pool = container_of(notifier, ThreadPool, notifier);
-    return !QLIST_EMPTY(&pool->head);
-}
-
 static void thread_pool_cancel(BlockDriverAIOCB *acb)
 {
     ThreadPoolElement *elem = (ThreadPoolElement *)acb;
@@ -310,7 +304,7 @@ static void thread_pool_init_one(ThreadPool *pool, AioContext *ctx)
     QTAILQ_INIT(&pool->request_list);
 
     aio_set_event_notifier(ctx, &pool->notifier, event_notifier_ready,
-                           thread_pool_active);
+                           NULL);
 }
 
 ThreadPool *thread_pool_new(AioContext *ctx)
commit ce689368bb453b0b21e73c77182a9d9bef8c0b84
Author: Stefan Hajnoczi <stefanha at redhat.com>
Date:   Thu Apr 11 17:20:03 2013 +0200

    dataplane/virtio-blk: drop flush_true() and flush_io()
    
    .io_flush() is no longer called so drop flush_true() and flush_io().
    
    Signed-off-by: Stefan Hajnoczi <stefanha at redhat.com>

diff --git a/hw/block/dataplane/virtio-blk.c b/hw/block/dataplane/virtio-blk.c
index 5bd5eed..82131b1 100644
--- a/hw/block/dataplane/virtio-blk.c
+++ b/hw/block/dataplane/virtio-blk.c
@@ -261,11 +261,6 @@ static int process_request(IOQueue *ioq, struct iovec iov[],
     }
 }
 
-static int flush_true(EventNotifier *e)
-{
-    return true;
-}
-
 static void handle_notify(EventNotifier *e)
 {
     VirtIOBlockDataPlane *s = container_of(e, VirtIOBlockDataPlane,
@@ -345,14 +340,6 @@ static void handle_notify(EventNotifier *e)
     }
 }
 
-static int flush_io(EventNotifier *e)
-{
-    VirtIOBlockDataPlane *s = container_of(e, VirtIOBlockDataPlane,
-                                           io_notifier);
-
-    return s->num_reqs > 0;
-}
-
 static void handle_io(EventNotifier *e)
 {
     VirtIOBlockDataPlane *s = container_of(e, VirtIOBlockDataPlane,
@@ -485,7 +472,7 @@ void virtio_blk_data_plane_start(VirtIOBlockDataPlane *s)
         exit(1);
     }
     s->host_notifier = *virtio_queue_get_host_notifier(vq);
-    aio_set_event_notifier(s->ctx, &s->host_notifier, handle_notify, flush_true);
+    aio_set_event_notifier(s->ctx, &s->host_notifier, handle_notify, NULL);
 
     /* Set up ioqueue */
     ioq_init(&s->ioqueue, s->fd, REQ_MAX);
@@ -493,7 +480,7 @@ void virtio_blk_data_plane_start(VirtIOBlockDataPlane *s)
         ioq_put_iocb(&s->ioqueue, &s->requests[i].iocb);
     }
     s->io_notifier = *ioq_get_notifier(&s->ioqueue);
-    aio_set_event_notifier(s->ctx, &s->io_notifier, handle_io, flush_io);
+    aio_set_event_notifier(s->ctx, &s->io_notifier, handle_io, NULL);
 
     s->started = true;
     trace_virtio_blk_data_plane_start(s);
commit f0d35765998bb527013b7f06521fa4b3de352f58
Author: Stefan Hajnoczi <stefanha at redhat.com>
Date:   Tue Apr 16 13:12:28 2013 +0200

    block/ssh: drop return_true()
    
    .io_flush() is no longer called so drop return_true().
    
    Signed-off-by: Stefan Hajnoczi <stefanha at redhat.com>

diff --git a/block/ssh.c b/block/ssh.c
index d7e7bf8..e149da9 100644
--- a/block/ssh.c
+++ b/block/ssh.c
@@ -740,14 +740,6 @@ static void restart_coroutine(void *opaque)
     qemu_coroutine_enter(co, NULL);
 }
 
-/* Always true because when we have called set_fd_handler there is
- * always a request being processed.
- */
-static int return_true(void *opaque)
-{
-    return 1;
-}
-
 static coroutine_fn void set_fd_handler(BDRVSSHState *s)
 {
     int r;
@@ -766,7 +758,7 @@ static coroutine_fn void set_fd_handler(BDRVSSHState *s)
     DPRINTF("s->sock=%d rd_handler=%p wr_handler=%p", s->sock,
             rd_handler, wr_handler);
 
-    qemu_aio_set_fd_handler(s->sock, rd_handler, wr_handler, return_true, co);
+    qemu_aio_set_fd_handler(s->sock, rd_handler, wr_handler, NULL, co);
 }
 
 static coroutine_fn void clear_fd_handler(BDRVSSHState *s)
commit d6d94c678503fd1eceb51b9652b4e0dfd9543475
Author: Stefan Hajnoczi <stefanha at redhat.com>
Date:   Thu Apr 11 17:18:18 2013 +0200

    block/sheepdog: drop have_co_req() and aio_flush_request()
    
    .io_flush() is no longer called so drop have_co_req() and
    aio_flush_request().
    
    Signed-off-by: Stefan Hajnoczi <stefanha at redhat.com>

diff --git a/block/sheepdog.c b/block/sheepdog.c
index afe0533..3fb4361 100644
--- a/block/sheepdog.c
+++ b/block/sheepdog.c
@@ -509,13 +509,6 @@ static void restart_co_req(void *opaque)
     qemu_coroutine_enter(co, NULL);
 }
 
-static int have_co_req(void *opaque)
-{
-    /* this handler is set only when there is a pending request, so
-     * always returns 1. */
-    return 1;
-}
-
 typedef struct SheepdogReqCo {
     int sockfd;
     SheepdogReq *hdr;
@@ -538,14 +531,14 @@ static coroutine_fn void do_co_req(void *opaque)
     unsigned int *rlen = srco->rlen;
 
     co = qemu_coroutine_self();
-    qemu_aio_set_fd_handler(sockfd, NULL, restart_co_req, have_co_req, co);
+    qemu_aio_set_fd_handler(sockfd, NULL, restart_co_req, NULL, co);
 
     ret = send_co_req(sockfd, hdr, data, wlen);
     if (ret < 0) {
         goto out;
     }
 
-    qemu_aio_set_fd_handler(sockfd, restart_co_req, NULL, have_co_req, co);
+    qemu_aio_set_fd_handler(sockfd, restart_co_req, NULL, NULL, co);
 
     ret = qemu_co_recv(sockfd, hdr, sizeof(*hdr));
     if (ret < sizeof(*hdr)) {
@@ -796,14 +789,6 @@ static void co_write_request(void *opaque)
     qemu_coroutine_enter(s->co_send, NULL);
 }
 
-static int aio_flush_request(void *opaque)
-{
-    BDRVSheepdogState *s = opaque;
-
-    return !QLIST_EMPTY(&s->inflight_aio_head) ||
-        !QLIST_EMPTY(&s->pending_aio_head);
-}
-
 /*
  * Return a socket discriptor to read/write objects.
  *
@@ -819,7 +804,7 @@ static int get_sheep_fd(BDRVSheepdogState *s)
         return fd;
     }
 
-    qemu_aio_set_fd_handler(fd, co_read_response, NULL, aio_flush_request, s);
+    qemu_aio_set_fd_handler(fd, co_read_response, NULL, NULL, s);
     return fd;
 }
 
@@ -1070,7 +1055,7 @@ static int coroutine_fn add_aio_request(BDRVSheepdogState *s, AIOReq *aio_req,
     qemu_co_mutex_lock(&s->lock);
     s->co_send = qemu_coroutine_self();
     qemu_aio_set_fd_handler(s->fd, co_read_response, co_write_request,
-                            aio_flush_request, s);
+                            NULL, s);
     socket_set_cork(s->fd, 1);
 
     /* send a header */
@@ -1092,7 +1077,7 @@ static int coroutine_fn add_aio_request(BDRVSheepdogState *s, AIOReq *aio_req,
 
     socket_set_cork(s->fd, 0);
     qemu_aio_set_fd_handler(s->fd, co_read_response, NULL,
-                            aio_flush_request, s);
+                            NULL, s);
     qemu_co_mutex_unlock(&s->lock);
 
     return 0;
commit 5d289cc7243be53d409ee3b79dd4fd363806f8b6
Author: Stefan Hajnoczi <stefanha at redhat.com>
Date:   Thu Apr 11 17:16:29 2013 +0200

    block/rbd: drop qemu_rbd_aio_flush_cb()
    
    .io_flush() is no longer called so drop qemu_rbd_aio_flush_cb().
    qemu_aio_count is unused now so drop it too.
    
    Signed-off-by: Stefan Hajnoczi <stefanha at redhat.com>

diff --git a/block/rbd.c b/block/rbd.c
index cb71751..71b4a0c 100644
--- a/block/rbd.c
+++ b/block/rbd.c
@@ -100,7 +100,6 @@ typedef struct BDRVRBDState {
     rados_ioctx_t io_ctx;
     rbd_image_t image;
     char name[RBD_MAX_IMAGE_NAME_SIZE];
-    int qemu_aio_count;
     char *snap;
     int event_reader_pos;
     RADOSCB *event_rcb;
@@ -428,19 +427,11 @@ static void qemu_rbd_aio_event_reader(void *opaque)
             if (s->event_reader_pos == sizeof(s->event_rcb)) {
                 s->event_reader_pos = 0;
                 qemu_rbd_complete_aio(s->event_rcb);
-                s->qemu_aio_count--;
             }
         }
     } while (ret < 0 && errno == EINTR);
 }
 
-static int qemu_rbd_aio_flush_cb(void *opaque)
-{
-    BDRVRBDState *s = opaque;
-
-    return (s->qemu_aio_count > 0);
-}
-
 /* TODO Convert to fine grained options */
 static QemuOptsList runtime_opts = {
     .name = "rbd",
@@ -554,7 +545,7 @@ static int qemu_rbd_open(BlockDriverState *bs, QDict *options, int flags)
     fcntl(s->fds[0], F_SETFL, O_NONBLOCK);
     fcntl(s->fds[1], F_SETFL, O_NONBLOCK);
     qemu_aio_set_fd_handler(s->fds[RBD_FD_READ], qemu_rbd_aio_event_reader,
-                            NULL, qemu_rbd_aio_flush_cb, s);
+                            NULL, NULL, s);
 
 
     qemu_opts_del(opts);
@@ -741,8 +732,6 @@ static BlockDriverAIOCB *rbd_start_aio(BlockDriverState *bs,
     off = sector_num * BDRV_SECTOR_SIZE;
     size = nb_sectors * BDRV_SECTOR_SIZE;
 
-    s->qemu_aio_count++; /* All the RADOSCB */
-
     rcb = g_malloc(sizeof(RADOSCB));
     rcb->done = 0;
     rcb->acb = acb;
@@ -779,7 +768,6 @@ static BlockDriverAIOCB *rbd_start_aio(BlockDriverState *bs,
 
 failed:
     g_free(rcb);
-    s->qemu_aio_count--;
     qemu_aio_release(acb);
     return NULL;
 }
commit bed2e759eb642931e0ebb95ea99580c27f57560e
Author: Stefan Hajnoczi <stefanha at redhat.com>
Date:   Thu Apr 11 17:15:03 2013 +0200

    block/nbd: drop nbd_have_request()
    
    .io_flush() is no longer called so drop nbd_have_request().  We cannot
    drop in_flight since it is still used by other block/nbd.c code.
    
    Signed-off-by: Stefan Hajnoczi <stefanha at redhat.com>

diff --git a/block/nbd.c b/block/nbd.c
index 9c480b8..f1619f9 100644
--- a/block/nbd.c
+++ b/block/nbd.c
@@ -279,13 +279,6 @@ static void nbd_coroutine_start(BDRVNBDState *s, struct nbd_request *request)
     request->handle = INDEX_TO_HANDLE(s, i);
 }
 
-static int nbd_have_request(void *opaque)
-{
-    BDRVNBDState *s = opaque;
-
-    return s->in_flight > 0;
-}
-
 static void nbd_reply_ready(void *opaque)
 {
     BDRVNBDState *s = opaque;
@@ -342,7 +335,7 @@ static int nbd_co_send_request(BDRVNBDState *s, struct nbd_request *request,
     qemu_co_mutex_lock(&s->send_mutex);
     s->send_coroutine = qemu_coroutine_self();
     qemu_aio_set_fd_handler(s->sock, nbd_reply_ready, nbd_restart_write,
-                            nbd_have_request, s);
+                            NULL, s);
     if (qiov) {
         if (!s->is_unix) {
             socket_set_cork(s->sock, 1);
@@ -362,7 +355,7 @@ static int nbd_co_send_request(BDRVNBDState *s, struct nbd_request *request,
         rc = nbd_send_request(s->sock, request);
     }
     qemu_aio_set_fd_handler(s->sock, nbd_reply_ready, NULL,
-                            nbd_have_request, s);
+                            NULL, s);
     s->send_coroutine = NULL;
     qemu_co_mutex_unlock(&s->send_mutex);
     return rc;
@@ -439,7 +432,7 @@ static int nbd_establish_connection(BlockDriverState *bs)
      * kick the reply mechanism.  */
     qemu_set_nonblock(sock);
     qemu_aio_set_fd_handler(sock, nbd_reply_ready, NULL,
-                            nbd_have_request, s);
+                            NULL, s);
 
     s->sock = sock;
     s->size = size;
commit 94473d0c0624822f6325918eb5bfe2d8a001206a
Author: Stefan Hajnoczi <stefanha at redhat.com>
Date:   Thu Apr 11 17:12:33 2013 +0200

    block/linux-aio: drop qemu_laio_completion_cb()
    
    .io_flush() is no longer called so drop qemu_laio_completion_cb().  It
    turns out that count is now unused so drop that too.
    
    Signed-off-by: Stefan Hajnoczi <stefanha at redhat.com>

diff --git a/block/linux-aio.c b/block/linux-aio.c
index ee0f8d1..d9128f3 100644
--- a/block/linux-aio.c
+++ b/block/linux-aio.c
@@ -39,7 +39,6 @@ struct qemu_laiocb {
 struct qemu_laio_state {
     io_context_t ctx;
     EventNotifier e;
-    int count;
 };
 
 static inline ssize_t io_event_ret(struct io_event *ev)
@@ -55,8 +54,6 @@ static void qemu_laio_process_completion(struct qemu_laio_state *s,
 {
     int ret;
 
-    s->count--;
-
     ret = laiocb->ret;
     if (ret != -ECANCELED) {
         if (ret == laiocb->nbytes) {
@@ -101,13 +98,6 @@ static void qemu_laio_completion_cb(EventNotifier *e)
     }
 }
 
-static int qemu_laio_flush_cb(EventNotifier *e)
-{
-    struct qemu_laio_state *s = container_of(e, struct qemu_laio_state, e);
-
-    return (s->count > 0) ? 1 : 0;
-}
-
 static void laio_cancel(BlockDriverAIOCB *blockacb)
 {
     struct qemu_laiocb *laiocb = (struct qemu_laiocb *)blockacb;
@@ -177,14 +167,11 @@ BlockDriverAIOCB *laio_submit(BlockDriverState *bs, void *aio_ctx, int fd,
         goto out_free_aiocb;
     }
     io_set_eventfd(&laiocb->iocb, event_notifier_get_fd(&s->e));
-    s->count++;
 
     if (io_submit(s->ctx, 1, &iocbs) < 0)
-        goto out_dec_count;
+        goto out_free_aiocb;
     return &laiocb->common;
 
-out_dec_count:
-    s->count--;
 out_free_aiocb:
     qemu_aio_release(laiocb);
     return NULL;
@@ -204,7 +191,7 @@ void *laio_init(void)
     }
 
     qemu_aio_set_event_notifier(&s->e, qemu_laio_completion_cb,
-                                qemu_laio_flush_cb);
+                                NULL);
 
     return s;
 
commit 70ecdc6e4e7f91e7d88540f19fb0f56f9e6f54a0
Author: Stefan Hajnoczi <stefanha at redhat.com>
Date:   Thu Apr 11 17:09:59 2013 +0200

    block/iscsi: drop iscsi_process_flush()
    
    .io_flush() is no longer called so drop iscsi_process_flush().
    
    Signed-off-by: Stefan Hajnoczi <stefanha at redhat.com>

diff --git a/block/iscsi.c b/block/iscsi.c
index e7c1c2b..180b827 100644
--- a/block/iscsi.c
+++ b/block/iscsi.c
@@ -146,13 +146,6 @@ static const AIOCBInfo iscsi_aiocb_info = {
 static void iscsi_process_read(void *arg);
 static void iscsi_process_write(void *arg);
 
-static int iscsi_process_flush(void *arg)
-{
-    IscsiLun *iscsilun = arg;
-
-    return iscsi_queue_length(iscsilun->iscsi) > 0;
-}
-
 static void
 iscsi_set_events(IscsiLun *iscsilun)
 {
@@ -166,7 +159,7 @@ iscsi_set_events(IscsiLun *iscsilun)
         qemu_aio_set_fd_handler(iscsi_get_fd(iscsi),
                       iscsi_process_read,
                       (ev & POLLOUT) ? iscsi_process_write : NULL,
-                      iscsi_process_flush,
+                      NULL,
                       iscsilun);
 
     }
commit 372835fbc3f288671cfc926c9e438a4659c9125f
Author: Stefan Hajnoczi <stefanha at redhat.com>
Date:   Thu Apr 11 17:07:43 2013 +0200

    block/gluster: drop qemu_gluster_aio_flush_cb()
    
    Since .io_flush() is no longer called we do not need
    qemu_gluster_aio_flush_cb() anymore.  It turns out that qemu_aio_count
    is unused now and can be dropped.
    
    Thanks to Bharata B Rao <bharata at linux.vnet.ibm.com> for catching a
    build failure with CONFIG_GLUSTERFS_DISCARD, which has been fixed.
    
    Signed-off-by: Stefan Hajnoczi <stefanha at redhat.com>

diff --git a/block/gluster.c b/block/gluster.c
index 645b7f1..3cb7500 100644
--- a/block/gluster.c
+++ b/block/gluster.c
@@ -32,7 +32,6 @@ typedef struct BDRVGlusterState {
     struct glfs *glfs;
     int fds[2];
     struct glfs_fd *fd;
-    int qemu_aio_count;
     int event_reader_pos;
     GlusterAIOCB *event_acb;
 } BDRVGlusterState;
@@ -247,7 +246,6 @@ static void qemu_gluster_complete_aio(GlusterAIOCB *acb, BDRVGlusterState *s)
         ret = -EIO; /* Partial read/write - fail it */
     }
 
-    s->qemu_aio_count--;
     qemu_aio_release(acb);
     cb(opaque, ret);
     if (finished) {
@@ -275,13 +273,6 @@ static void qemu_gluster_aio_event_reader(void *opaque)
     } while (ret < 0 && errno == EINTR);
 }
 
-static int qemu_gluster_aio_flush_cb(void *opaque)
-{
-    BDRVGlusterState *s = opaque;
-
-    return (s->qemu_aio_count > 0);
-}
-
 /* TODO Convert to fine grained options */
 static QemuOptsList runtime_opts = {
     .name = "gluster",
@@ -348,7 +339,7 @@ static int qemu_gluster_open(BlockDriverState *bs,  QDict *options,
     }
     fcntl(s->fds[GLUSTER_FD_READ], F_SETFL, O_NONBLOCK);
     qemu_aio_set_fd_handler(s->fds[GLUSTER_FD_READ],
-        qemu_gluster_aio_event_reader, NULL, qemu_gluster_aio_flush_cb, s);
+        qemu_gluster_aio_event_reader, NULL, NULL, s);
 
 out:
     qemu_opts_del(opts);
@@ -445,7 +436,6 @@ static void gluster_finish_aiocb(struct glfs_fd *fd, ssize_t ret, void *arg)
         qemu_mutex_lock_iothread(); /* We are in gluster thread context */
         acb->common.cb(acb->common.opaque, -EIO);
         qemu_aio_release(acb);
-        s->qemu_aio_count--;
         close(s->fds[GLUSTER_FD_READ]);
         close(s->fds[GLUSTER_FD_WRITE]);
         qemu_aio_set_fd_handler(s->fds[GLUSTER_FD_READ], NULL, NULL, NULL,
@@ -467,7 +457,6 @@ static BlockDriverAIOCB *qemu_gluster_aio_rw(BlockDriverState *bs,
 
     offset = sector_num * BDRV_SECTOR_SIZE;
     size = nb_sectors * BDRV_SECTOR_SIZE;
-    s->qemu_aio_count++;
 
     acb = qemu_aio_get(&gluster_aiocb_info, bs, cb, opaque);
     acb->size = size;
@@ -488,7 +477,6 @@ static BlockDriverAIOCB *qemu_gluster_aio_rw(BlockDriverState *bs,
     return &acb->common;
 
 out:
-    s->qemu_aio_count--;
     qemu_aio_release(acb);
     return NULL;
 }
@@ -531,7 +519,6 @@ static BlockDriverAIOCB *qemu_gluster_aio_flush(BlockDriverState *bs,
     acb->size = 0;
     acb->ret = 0;
     acb->finished = NULL;
-    s->qemu_aio_count++;
 
     ret = glfs_fsync_async(s->fd, &gluster_finish_aiocb, acb);
     if (ret < 0) {
@@ -540,7 +527,6 @@ static BlockDriverAIOCB *qemu_gluster_aio_flush(BlockDriverState *bs,
     return &acb->common;
 
 out:
-    s->qemu_aio_count--;
     qemu_aio_release(acb);
     return NULL;
 }
@@ -563,7 +549,6 @@ static BlockDriverAIOCB *qemu_gluster_aio_discard(BlockDriverState *bs,
     acb->size = 0;
     acb->ret = 0;
     acb->finished = NULL;
-    s->qemu_aio_count++;
 
     ret = glfs_discard_async(s->fd, offset, size, &gluster_finish_aiocb, acb);
     if (ret < 0) {
@@ -572,7 +557,6 @@ static BlockDriverAIOCB *qemu_gluster_aio_discard(BlockDriverState *bs,
     return &acb->common;
 
 out:
-    s->qemu_aio_count--;
     qemu_aio_release(acb);
     return NULL;
 }
commit bc02fb304c6cc0f1dd0809545d226df2d6f5c093
Author: Anthony Liguori <anthony at codemonkey.ws>
Date:   Mon Aug 19 08:49:37 2013 -0500

    Change email address
    
    My IBM email address will be unaccessible after August 23rd, 2013.
    
    Signed-off-by: Anthony Liguori <anthony at codemonkey.ws>

diff --git a/.mailmap b/.mailmap
index 9797802..7b91a95 100644
--- a/.mailmap
+++ b/.mailmap
@@ -2,7 +2,7 @@
 # into proper addresses so that they are counted properly in git shortlog output.
 #
 Andrzej Zaborowski <balrogg at gmail.com> balrog <balrog at c046a42c-6fe2-441c-8c8c-71466251a162>
-Anthony Liguori <aliguori at us.ibm.com> aliguori <aliguori at c046a42c-6fe2-441c-8c8c-71466251a162>
+Anthony Liguori <anthony at codemonkey.ws> aliguori <aliguori at c046a42c-6fe2-441c-8c8c-71466251a162>
 Aurelien Jarno <aurelien at aurel32.net> aurel32 <aurel32 at c046a42c-6fe2-441c-8c8c-71466251a162>
 Blue Swirl <blauwirbel at gmail.com> blueswir1 <blueswir1 at c046a42c-6fe2-441c-8c8c-71466251a162>
 Edgar E. Iglesias <edgar.iglesias at gmail.com> edgar_igl <edgar_igl at c046a42c-6fe2-441c-8c8c-71466251a162>
diff --git a/MAINTAINERS b/MAINTAINERS
index 654e2cb..70a3370 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -50,7 +50,7 @@ Descriptions of section entries:
 
 General Project Administration
 ------------------------------
-M: Anthony Liguori <aliguori at us.ibm.com>
+M: Anthony Liguori <anthony at codemonkey.ws>
 M: Paul Brook <paul at codesourcery.com>
 
 Guest CPU cores (TCG):
@@ -509,7 +509,7 @@ F: hw/unicore32/
 X86 Machines
 ------------
 PC
-M: Anthony Liguori <aliguori at us.ibm.com>
+M: Anthony Liguori <anthony at codemonkey.ws>
 S: Supported
 F: hw/i386/pc.[ch]
 F: hw/i386/pc_piix.c
@@ -593,7 +593,7 @@ S: Supported
 F: hw/*/*vhost*
 
 virtio
-M: Anthony Liguori <aliguori at us.ibm.com>
+M: Anthony Liguori <anthony at codemonkey.ws>
 S: Supported
 F: hw/*/virtio*
 
@@ -651,7 +651,7 @@ F: block/
 F: hw/block/
 
 Character Devices
-M: Anthony Liguori <aliguori at us.ibm.com>
+M: Anthony Liguori <anthony at codemonkey.ws>
 S: Maintained
 F: qemu-char.c
 
@@ -689,7 +689,7 @@ F: audio/spiceaudio.c
 F: hw/display/qxl*
 
 Graphics
-M: Anthony Liguori <aliguori at us.ibm.com>
+M: Anthony Liguori <anthony at codemonkey.ws>
 S: Maintained
 F: ui/
 
@@ -699,7 +699,7 @@ S: Odd Fixes
 F: ui/cocoa.m
 
 Main loop
-M: Anthony Liguori <aliguori at us.ibm.com>
+M: Anthony Liguori <anthony at codemonkey.ws>
 S: Supported
 F: vl.c
 
@@ -711,7 +711,7 @@ F: hmp.c
 F: hmp-commands.hx
 
 Network device layer
-M: Anthony Liguori <aliguori at us.ibm.com>
+M: Anthony Liguori <anthony at codemonkey.ws>
 M: Stefan Hajnoczi <stefanha at redhat.com>
 S: Maintained
 F: net/
commit 0d1460226fb05c92fa3ad869ca39090ff13cf6bc
Author: Stefan Hajnoczi <stefanha at redhat.com>
Date:   Thu Apr 11 17:04:23 2013 +0200

    block/curl: drop curl_aio_flush()
    
    .io_flush() is no longer called so drop curl_aio_flush().  The acb[]
    array that the function checks is still used in other parts of
    block/curl.c.  Therefore we cannot remove acb[], it is needed.
    
    Signed-off-by: Stefan Hajnoczi <stefanha at redhat.com>

diff --git a/block/curl.c b/block/curl.c
index 82d39ff..5999924 100644
--- a/block/curl.c
+++ b/block/curl.c
@@ -86,7 +86,6 @@ typedef struct BDRVCURLState {
 
 static void curl_clean_state(CURLState *s);
 static void curl_multi_do(void *arg);
-static int curl_aio_flush(void *opaque);
 
 static int curl_sock_cb(CURL *curl, curl_socket_t fd, int action,
                         void *s, void *sp)
@@ -94,14 +93,14 @@ static int curl_sock_cb(CURL *curl, curl_socket_t fd, int action,
     DPRINTF("CURL (AIO): Sock action %d on fd %d\n", action, fd);
     switch (action) {
         case CURL_POLL_IN:
-            qemu_aio_set_fd_handler(fd, curl_multi_do, NULL, curl_aio_flush, s);
+            qemu_aio_set_fd_handler(fd, curl_multi_do, NULL, NULL, s);
             break;
         case CURL_POLL_OUT:
-            qemu_aio_set_fd_handler(fd, NULL, curl_multi_do, curl_aio_flush, s);
+            qemu_aio_set_fd_handler(fd, NULL, curl_multi_do, NULL, s);
             break;
         case CURL_POLL_INOUT:
             qemu_aio_set_fd_handler(fd, curl_multi_do, curl_multi_do,
-                                    curl_aio_flush, s);
+                                    NULL, s);
             break;
         case CURL_POLL_REMOVE:
             qemu_aio_set_fd_handler(fd, NULL, NULL, NULL, NULL);
@@ -495,21 +494,6 @@ out_noclean:
     return -EINVAL;
 }
 
-static int curl_aio_flush(void *opaque)
-{
-    BDRVCURLState *s = opaque;
-    int i, j;
-
-    for (i=0; i < CURL_NUM_STATES; i++) {
-        for(j=0; j < CURL_NUM_ACB; j++) {
-            if (s->states[i].acb[j]) {
-                return 1;
-            }
-        }
-    }
-    return 0;
-}
-
 static void curl_aio_cancel(BlockDriverAIOCB *blockacb)
 {
     // Do we have to implement canceling? Seems to work without...
commit 164a101f28a53cd3db60ed874e7c3630e7988ed8
Author: Stefan Hajnoczi <stefanha at redhat.com>
Date:   Thu Apr 11 16:56:50 2013 +0200

    aio: stop using .io_flush()
    
    Now that aio_poll() users check their termination condition themselves,
    it is no longer necessary to call .io_flush() handlers.
    
    The behavior of aio_poll() changes as follows:
    
    1. .io_flush() is no longer invoked and file descriptors are *always*
    monitored.  Previously returning 0 from .io_flush() would skip this file
    descriptor.
    
    Due to this change it is essential to check that requests are pending
    before calling qemu_aio_wait().  Failure to do so means we block, for
    example, waiting for an idle iSCSI socket to become readable when there
    are no requests.  Currently all qemu_aio_wait()/aio_poll() callers check
    before calling.
    
    2. aio_poll() now returns true if progress was made (BH or fd handlers
    executed) and false otherwise.  Previously it would return true whenever
    'busy', which means that .io_flush() returned true.  The 'busy' concept
    no longer exists so just progress is returned.
    
    Due to this change we need to update tests/test-aio.c which asserts
    aio_poll() return values.  Note that QEMU doesn't actually rely on these
    return values so only tests/test-aio.c cares.
    
    Note that ctx->notifier, the EventNotifier fd used for aio_notify(), is
    now handled as a special case.  This is a little ugly but maintains
    aio_poll() semantics, i.e. aio_notify() does not count as 'progress' and
    aio_poll() avoids blocking when the user has not set any fd handlers yet.
    
    Patches after this remove .io_flush() handler code until we can finally
    drop the io_flush arguments to aio_set_fd_handler() and friends.
    
    Reviewed-by: Paolo Bonzini <pbonzini at redhat.com>
    Signed-off-by: Stefan Hajnoczi <stefanha at redhat.com>

diff --git a/aio-posix.c b/aio-posix.c
index b68eccd..7d66048 100644
--- a/aio-posix.c
+++ b/aio-posix.c
@@ -23,7 +23,6 @@ struct AioHandler
     GPollFD pfd;
     IOHandler *io_read;
     IOHandler *io_write;
-    AioFlushHandler *io_flush;
     int deleted;
     int pollfds_idx;
     void *opaque;
@@ -84,7 +83,6 @@ void aio_set_fd_handler(AioContext *ctx,
         /* Update handler with latest information */
         node->io_read = io_read;
         node->io_write = io_write;
-        node->io_flush = io_flush;
         node->opaque = opaque;
         node->pollfds_idx = -1;
 
@@ -147,7 +145,11 @@ static bool aio_dispatch(AioContext *ctx)
             (revents & (G_IO_IN | G_IO_HUP | G_IO_ERR)) &&
             node->io_read) {
             node->io_read(node->opaque);
-            progress = true;
+
+            /* aio_notify() does not count as progress */
+            if (node->opaque != &ctx->notifier) {
+                progress = true;
+            }
         }
         if (!node->deleted &&
             (revents & (G_IO_OUT | G_IO_ERR)) &&
@@ -173,7 +175,7 @@ bool aio_poll(AioContext *ctx, bool blocking)
 {
     AioHandler *node;
     int ret;
-    bool busy, progress;
+    bool progress;
 
     progress = false;
 
@@ -200,20 +202,8 @@ bool aio_poll(AioContext *ctx, bool blocking)
     g_array_set_size(ctx->pollfds, 0);
 
     /* fill pollfds */
-    busy = false;
     QLIST_FOREACH(node, &ctx->aio_handlers, node) {
         node->pollfds_idx = -1;
-
-        /* If there aren't pending AIO operations, don't invoke callbacks.
-         * Otherwise, if there are no AIO requests, qemu_aio_wait() would
-         * wait indefinitely.
-         */
-        if (!node->deleted && node->io_flush) {
-            if (node->io_flush(node->opaque) == 0) {
-                continue;
-            }
-            busy = true;
-        }
         if (!node->deleted && node->pfd.events) {
             GPollFD pfd = {
                 .fd = node->pfd.fd,
@@ -226,8 +216,8 @@ bool aio_poll(AioContext *ctx, bool blocking)
 
     ctx->walking_handlers--;
 
-    /* No AIO operations?  Get us out of here */
-    if (!busy) {
+    /* early return if we only have the aio_notify() fd */
+    if (ctx->pollfds->len == 1) {
         return progress;
     }
 
@@ -250,6 +240,5 @@ bool aio_poll(AioContext *ctx, bool blocking)
         }
     }
 
-    assert(progress || busy);
-    return true;
+    return progress;
 }
diff --git a/aio-win32.c b/aio-win32.c
index 38723bf..4309c16 100644
--- a/aio-win32.c
+++ b/aio-win32.c
@@ -23,7 +23,6 @@
 struct AioHandler {
     EventNotifier *e;
     EventNotifierHandler *io_notify;
-    AioFlushEventNotifierHandler *io_flush;
     GPollFD pfd;
     int deleted;
     QLIST_ENTRY(AioHandler) node;
@@ -73,7 +72,6 @@ void aio_set_event_notifier(AioContext *ctx,
         }
         /* Update handler with latest information */
         node->io_notify = io_notify;
-        node->io_flush = io_flush;
     }
 
     aio_notify(ctx);
@@ -96,7 +94,7 @@ bool aio_poll(AioContext *ctx, bool blocking)
 {
     AioHandler *node;
     HANDLE events[MAXIMUM_WAIT_OBJECTS + 1];
-    bool busy, progress;
+    bool progress;
     int count;
 
     progress = false;
@@ -126,7 +124,11 @@ bool aio_poll(AioContext *ctx, bool blocking)
         if (node->pfd.revents && node->io_notify) {
             node->pfd.revents = 0;
             node->io_notify(node->e);
-            progress = true;
+
+            /* aio_notify() does not count as progress */
+            if (node->opaque != &ctx->notifier) {
+                progress = true;
+            }
         }
 
         tmp = node;
@@ -147,19 +149,8 @@ bool aio_poll(AioContext *ctx, bool blocking)
     ctx->walking_handlers++;
 
     /* fill fd sets */
-    busy = false;
     count = 0;
     QLIST_FOREACH(node, &ctx->aio_handlers, node) {
-        /* If there aren't pending AIO operations, don't invoke callbacks.
-         * Otherwise, if there are no AIO requests, qemu_aio_wait() would
-         * wait indefinitely.
-         */
-        if (!node->deleted && node->io_flush) {
-            if (node->io_flush(node->e) == 0) {
-                continue;
-            }
-            busy = true;
-        }
         if (!node->deleted && node->io_notify) {
             events[count++] = event_notifier_get_handle(node->e);
         }
@@ -167,8 +158,8 @@ bool aio_poll(AioContext *ctx, bool blocking)
 
     ctx->walking_handlers--;
 
-    /* No AIO operations?  Get us out of here */
-    if (!busy) {
+    /* early return if we only have the aio_notify() fd */
+    if (count == 1) {
         return progress;
     }
 
@@ -196,7 +187,11 @@ bool aio_poll(AioContext *ctx, bool blocking)
                 event_notifier_get_handle(node->e) == events[ret - WAIT_OBJECT_0] &&
                 node->io_notify) {
                 node->io_notify(node->e);
-                progress = true;
+
+                /* aio_notify() does not count as progress */
+                if (node->opaque != &ctx->notifier) {
+                    progress = true;
+                }
             }
 
             tmp = node;
@@ -214,6 +209,5 @@ bool aio_poll(AioContext *ctx, bool blocking)
         events[ret - WAIT_OBJECT_0] = events[--count];
     }
 
-    assert(progress || busy);
-    return true;
+    return progress;
 }
diff --git a/tests/test-aio.c b/tests/test-aio.c
index 20bf5e6..1251952 100644
--- a/tests/test-aio.c
+++ b/tests/test-aio.c
@@ -254,7 +254,7 @@ static void test_wait_event_notifier(void)
     EventNotifierTestData data = { .n = 0, .active = 1 };
     event_notifier_init(&data.e, false);
     aio_set_event_notifier(ctx, &data.e, event_ready_cb, event_active_cb);
-    g_assert(aio_poll(ctx, false));
+    g_assert(!aio_poll(ctx, false));
     g_assert_cmpint(data.n, ==, 0);
     g_assert_cmpint(data.active, ==, 1);
 
@@ -279,7 +279,7 @@ static void test_flush_event_notifier(void)
     EventNotifierTestData data = { .n = 0, .active = 10, .auto_set = true };
     event_notifier_init(&data.e, false);
     aio_set_event_notifier(ctx, &data.e, event_ready_cb, event_active_cb);
-    g_assert(aio_poll(ctx, false));
+    g_assert(!aio_poll(ctx, false));
     g_assert_cmpint(data.n, ==, 0);
     g_assert_cmpint(data.active, ==, 10);
 
@@ -313,7 +313,7 @@ static void test_wait_event_notifier_noflush(void)
     /* Until there is an active descriptor, aio_poll may or may not call
      * event_ready_cb.  Still, it must not block.  */
     event_notifier_set(&data.e);
-    g_assert(!aio_poll(ctx, true));
+    g_assert(aio_poll(ctx, true));
     data.n = 0;
 
     /* An active event notifier forces aio_poll to look at EventNotifiers.  */
@@ -323,13 +323,13 @@ static void test_wait_event_notifier_noflush(void)
     event_notifier_set(&data.e);
     g_assert(aio_poll(ctx, false));
     g_assert_cmpint(data.n, ==, 1);
-    g_assert(aio_poll(ctx, false));
+    g_assert(!aio_poll(ctx, false));
     g_assert_cmpint(data.n, ==, 1);
 
     event_notifier_set(&data.e);
     g_assert(aio_poll(ctx, false));
     g_assert_cmpint(data.n, ==, 2);
-    g_assert(aio_poll(ctx, false));
+    g_assert(!aio_poll(ctx, false));
     g_assert_cmpint(data.n, ==, 2);
 
     event_notifier_set(&dummy.e);
commit 35ecde26018207fe723bec6efbd340db6e9c2d53
Author: Stefan Hajnoczi <stefanha at redhat.com>
Date:   Tue Apr 16 17:49:42 2013 +0200

    tests: adjust test-thread-pool to new aio_poll() semantics
    
    aio_poll(ctx, true) will soon block when fd handlers have been set.
    Previously aio_poll() would return early if all .io_flush() returned
    false.  This means we need to check the equivalent of the .io_flush()
    condition *before* calling aio_poll(ctx, true) to avoid deadlock.
    
    Reviewed-by: Paolo Bonzini <pbonzini at redhat.com>
    Signed-off-by: Stefan Hajnoczi <stefanha at redhat.com>

diff --git a/tests/test-thread-pool.c b/tests/test-thread-pool.c
index b62338f..8188d1a 100644
--- a/tests/test-thread-pool.c
+++ b/tests/test-thread-pool.c
@@ -40,19 +40,13 @@ static void done_cb(void *opaque, int ret)
     active--;
 }
 
-/* Wait until all aio and bh activity has finished */
-static void qemu_aio_wait_all(void)
-{
-    while (aio_poll(ctx, true)) {
-        /* Do nothing */
-    }
-}
-
 static void test_submit(void)
 {
     WorkerTestData data = { .n = 0 };
     thread_pool_submit(pool, worker_cb, &data);
-    qemu_aio_wait_all();
+    while (data.n == 0) {
+        aio_poll(ctx, true);
+    }
     g_assert_cmpint(data.n, ==, 1);
 }
 
@@ -65,7 +59,9 @@ static void test_submit_aio(void)
     /* The callbacks are not called until after the first wait.  */
     active = 1;
     g_assert_cmpint(data.ret, ==, -EINPROGRESS);
-    qemu_aio_wait_all();
+    while (data.ret == -EINPROGRESS) {
+        aio_poll(ctx, true);
+    }
     g_assert_cmpint(active, ==, 0);
     g_assert_cmpint(data.n, ==, 1);
     g_assert_cmpint(data.ret, ==, 0);
@@ -103,7 +99,9 @@ static void test_submit_co(void)
 
     /* qemu_aio_wait_all will execute the rest of the coroutine.  */
 
-    qemu_aio_wait_all();
+    while (data.ret == -EINPROGRESS) {
+        aio_poll(ctx, true);
+    }
 
     /* Back here after the coroutine has finished.  */
 
@@ -187,7 +185,9 @@ static void test_cancel(void)
     }
 
     /* Finish execution and execute any remaining callbacks.  */
-    qemu_aio_wait_all();
+    while (active > 0) {
+        aio_poll(ctx, true);
+    }
     g_assert_cmpint(active, ==, 0);
     for (i = 0; i < 100; i++) {
         if (data[i].n == 3) {
commit 24d1a6d9d5f5b3da868724dd3c6f56893e0693da
Author: Stefan Hajnoczi <stefanha at redhat.com>
Date:   Wed Apr 17 11:01:02 2013 +0200

    tests: adjust test-aio to new aio_poll() semantics
    
    aio_poll(ctx, true) will soon block if any fd handlers have been set.
    Previously it would only block when .io_flush() returned true.
    
    This means that callers must check their wait condition *before*
    aio_poll() to avoid deadlock.
    
    Reviewed-by: Paolo Bonzini <pbonzini at redhat.com>
    Signed-off-by: Stefan Hajnoczi <stefanha at redhat.com>

diff --git a/tests/test-aio.c b/tests/test-aio.c
index c173870..20bf5e6 100644
--- a/tests/test-aio.c
+++ b/tests/test-aio.c
@@ -15,6 +15,13 @@
 
 AioContext *ctx;
 
+typedef struct {
+    EventNotifier e;
+    int n;
+    int active;
+    bool auto_set;
+} EventNotifierTestData;
+
 /* Wait until there are no more BHs or AIO requests */
 static void wait_for_aio(void)
 {
@@ -23,6 +30,14 @@ static void wait_for_aio(void)
     }
 }
 
+/* Wait until event notifier becomes inactive */
+static void wait_until_inactive(EventNotifierTestData *data)
+{
+    while (data->active > 0) {
+        aio_poll(ctx, true);
+    }
+}
+
 /* Simple callbacks for testing.  */
 
 typedef struct {
@@ -50,13 +65,6 @@ static void bh_delete_cb(void *opaque)
     }
 }
 
-typedef struct {
-    EventNotifier e;
-    int n;
-    int active;
-    bool auto_set;
-} EventNotifierTestData;
-
 static int event_active_cb(EventNotifier *e)
 {
     EventNotifierTestData *data = container_of(e, EventNotifierTestData, e);
@@ -281,7 +289,7 @@ static void test_flush_event_notifier(void)
     g_assert_cmpint(data.active, ==, 9);
     g_assert(aio_poll(ctx, false));
 
-    wait_for_aio();
+    wait_until_inactive(&data);
     g_assert_cmpint(data.n, ==, 10);
     g_assert_cmpint(data.active, ==, 0);
     g_assert(!aio_poll(ctx, false));
@@ -325,7 +333,7 @@ static void test_wait_event_notifier_noflush(void)
     g_assert_cmpint(data.n, ==, 2);
 
     event_notifier_set(&dummy.e);
-    wait_for_aio();
+    wait_until_inactive(&dummy);
     g_assert_cmpint(data.n, ==, 2);
     g_assert_cmpint(dummy.n, ==, 1);
     g_assert_cmpint(dummy.active, ==, 0);
commit bf0da4df83e8af7ec02e3809f3dd30cc0a42e4bc
Author: Stefan Hajnoczi <stefanha at redhat.com>
Date:   Thu Apr 11 17:24:08 2013 +0200

    dataplane/virtio-blk: check exit conditions before aio_poll()
    
    Check exit conditions before entering blocking aio_poll().  This is
    mainly for consistency since it's unlikely that we are stopping in the
    first event loop iteration.
    
    Signed-off-by: Stefan Hajnoczi <stefanha at redhat.com>

diff --git a/hw/block/dataplane/virtio-blk.c b/hw/block/dataplane/virtio-blk.c
index 411becc..5bd5eed 100644
--- a/hw/block/dataplane/virtio-blk.c
+++ b/hw/block/dataplane/virtio-blk.c
@@ -376,9 +376,9 @@ static void *data_plane_thread(void *opaque)
 {
     VirtIOBlockDataPlane *s = opaque;
 
-    do {
+    while (!s->stopping || s->num_reqs > 0) {
         aio_poll(s->ctx, true);
-    } while (!s->stopping || s->num_reqs > 0);
+    }
     return NULL;
 }
 
commit 88266f5aa70fa71fd5cc20aa4dbeb7a7bd8d2e92
Author: Stefan Hajnoczi <stefanha at redhat.com>
Date:   Thu Apr 11 15:41:13 2013 +0200

    block: stop relying on io_flush() in bdrv_drain_all()
    
    If a block driver has no file descriptors to monitor but there are still
    active requests, it can return 1 from .io_flush().  This is used to spin
    during synchronous I/O.
    
    Stop relying on .io_flush() and instead check
    QLIST_EMPTY(&bs->tracked_requests) to decide whether there are active
    requests.
    
    This is the first step in removing .io_flush() so that event loops no
    longer need to have the concept of synchronous I/O.  Eventually we may
    be able to kill synchronous I/O completely by running everything in a
    coroutine, but that is future work.
    
    Note this patch moves bs->throttled_reqs initialization to bdrv_new() so
    that bdrv_requests_pending(bs) can safely access it.  In practice bs is
    g_malloc0() so the memory is already zeroed but it's safer to initialize
    the queue properly.
    
    We also need to fix up block/stream.c:close_unused_images() to prevent
    traversing a dangling pointer while it rearranges the backing file
    chain.  This is necessary since the new bdrv_drain_all() traverses the
    backing file chain.
    
    Signed-off-by: Stefan Hajnoczi <stefanha at redhat.com>

diff --git a/block.c b/block.c
index d5ce8d3..45a545b 100644
--- a/block.c
+++ b/block.c
@@ -148,7 +148,6 @@ static void bdrv_block_timer(void *opaque)
 
 void bdrv_io_limits_enable(BlockDriverState *bs)
 {
-    qemu_co_queue_init(&bs->throttled_reqs);
     bs->block_timer = qemu_new_timer_ns(vm_clock, bdrv_block_timer, bs);
     bs->io_limits_enabled = true;
 }
@@ -306,6 +305,7 @@ BlockDriverState *bdrv_new(const char *device_name)
     bdrv_iostatus_disable(bs);
     notifier_list_init(&bs->close_notifiers);
     notifier_with_return_list_init(&bs->before_write_notifiers);
+    qemu_co_queue_init(&bs->throttled_reqs);
 
     return bs;
 }
@@ -1428,6 +1428,35 @@ void bdrv_close_all(void)
     }
 }
 
+/* Check if any requests are in-flight (including throttled requests) */
+static bool bdrv_requests_pending(BlockDriverState *bs)
+{
+    if (!QLIST_EMPTY(&bs->tracked_requests)) {
+        return true;
+    }
+    if (!qemu_co_queue_empty(&bs->throttled_reqs)) {
+        return true;
+    }
+    if (bs->file && bdrv_requests_pending(bs->file)) {
+        return true;
+    }
+    if (bs->backing_hd && bdrv_requests_pending(bs->backing_hd)) {
+        return true;
+    }
+    return false;
+}
+
+static bool bdrv_requests_pending_all(void)
+{
+    BlockDriverState *bs;
+    QTAILQ_FOREACH(bs, &bdrv_states, list) {
+        if (bdrv_requests_pending(bs)) {
+            return true;
+        }
+    }
+    return false;
+}
+
 /*
  * Wait for pending requests to complete across all BlockDriverStates
  *
@@ -1442,12 +1471,11 @@ void bdrv_close_all(void)
  */
 void bdrv_drain_all(void)
 {
+    /* Always run first iteration so any pending completion BHs run */
+    bool busy = true;
     BlockDriverState *bs;
-    bool busy;
-
-    do {
-        busy = qemu_aio_wait();
 
+    while (busy) {
         /* FIXME: We do not have timer support here, so this is effectively
          * a busy wait.
          */
@@ -1456,12 +1484,9 @@ void bdrv_drain_all(void)
                 busy = true;
             }
         }
-    } while (busy);
 
-    /* If requests are still pending there is a bug somewhere */
-    QTAILQ_FOREACH(bs, &bdrv_states, list) {
-        assert(QLIST_EMPTY(&bs->tracked_requests));
-        assert(qemu_co_queue_empty(&bs->throttled_reqs));
+        busy = bdrv_requests_pending_all();
+        busy |= aio_poll(qemu_get_aio_context(), busy);
     }
 }
 
diff --git a/block/stream.c b/block/stream.c
index 7fe9e48..db49b4d 100644
--- a/block/stream.c
+++ b/block/stream.c
@@ -57,6 +57,11 @@ static void close_unused_images(BlockDriverState *top, BlockDriverState *base,
     BlockDriverState *intermediate;
     intermediate = top->backing_hd;
 
+    /* Must assign before bdrv_delete() to prevent traversing dangling pointer
+     * while we delete backing image instances.
+     */
+    top->backing_hd = base;
+
     while (intermediate) {
         BlockDriverState *unused;
 
@@ -70,7 +75,6 @@ static void close_unused_images(BlockDriverState *top, BlockDriverState *base,
         unused->backing_hd = NULL;
         bdrv_delete(unused);
     }
-    top->backing_hd = base;
 }
 
 static void coroutine_fn stream_run(void *opaque)
commit e1b5c52e04d04bb93546c6e37e8884889d047cb1
Author: Stefan Hajnoczi <stefanha at redhat.com>
Date:   Thu Jun 27 15:32:26 2013 +0200

    block: ensure bdrv_drain_all() works during bdrv_delete()
    
    In bdrv_delete() make sure to call bdrv_make_anon() *after* bdrv_close()
    so that the device is still seen by bdrv_drain_all() when iterating
    bdrv_states.
    
    Cc: qemu-stable at nongnu.org
    Signed-off-by: Stefan Hajnoczi <stefanha at redhat.com>

diff --git a/block.c b/block.c
index 01b66d8..d5ce8d3 100644
--- a/block.c
+++ b/block.c
@@ -1606,11 +1606,11 @@ void bdrv_delete(BlockDriverState *bs)
     assert(!bs->job);
     assert(!bs->in_use);
 
+    bdrv_close(bs);
+
     /* remove from list, if necessary */
     bdrv_make_anon(bs);
 
-    bdrv_close(bs);
-
     g_free(bs);
 }
 
commit b83c4db89561e78ca5a1808329cbf937c6d75cc3
Author: Richard Henderson <rth at twiddle.net>
Date:   Sun Aug 4 15:27:13 2013 -1000

    target-alpha: Implement the typhoon iommu
    
    Signed-off-by: Richard Henderson <rth at twiddle.net>

diff --git a/hw/alpha/typhoon.c b/hw/alpha/typhoon.c
index b7fb044..2450045 100644
--- a/hw/alpha/typhoon.c
+++ b/hw/alpha/typhoon.c
@@ -26,9 +26,9 @@ typedef struct TyphoonCchip {
 } TyphoonCchip;
 
 typedef struct TyphoonWindow {
-    uint32_t base_addr;
-    uint32_t mask;
-    uint32_t translated_base_pfn;
+    uint64_t wba;
+    uint64_t wsm;
+    uint64_t tba;
 } TyphoonWindow;
  
 typedef struct TyphoonPchip {
@@ -37,6 +37,10 @@ typedef struct TyphoonPchip {
     MemoryRegion reg_mem;
     MemoryRegion reg_io;
     MemoryRegion reg_conf;
+
+    AddressSpace iommu_as;
+    MemoryRegion iommu;
+
     uint64_t ctl;
     TyphoonWindow win[4];
 } TyphoonPchip;
@@ -209,53 +213,53 @@ static uint64_t pchip_read(void *opaque, hwaddr addr, unsigned size)
     switch (addr) {
     case 0x0000:
         /* WSBA0: Window Space Base Address Register.  */
-        ret = s->pchip.win[0].base_addr;
+        ret = s->pchip.win[0].wba;
         break;
     case 0x0040:
         /* WSBA1 */
-        ret = s->pchip.win[1].base_addr;
+        ret = s->pchip.win[1].wba;
         break;
     case 0x0080:
         /* WSBA2 */
-        ret = s->pchip.win[2].base_addr;
+        ret = s->pchip.win[2].wba;
         break;
     case 0x00c0:
         /* WSBA3 */
-        ret = s->pchip.win[3].base_addr;
+        ret = s->pchip.win[3].wba;
         break;
 
     case 0x0100:
         /* WSM0: Window Space Mask Register.  */
-        ret = s->pchip.win[0].mask;
+        ret = s->pchip.win[0].wsm;
         break;
     case 0x0140:
         /* WSM1 */
-        ret = s->pchip.win[1].mask;
+        ret = s->pchip.win[1].wsm;
         break;
     case 0x0180:
         /* WSM2 */
-        ret = s->pchip.win[2].mask;
+        ret = s->pchip.win[2].wsm;
         break;
     case 0x01c0:
         /* WSM3 */
-        ret = s->pchip.win[3].mask;
+        ret = s->pchip.win[3].wsm;
         break;
 
     case 0x0200:
         /* TBA0: Translated Base Address Register.  */
-        ret = (uint64_t)s->pchip.win[0].translated_base_pfn << 10;
+        ret = s->pchip.win[0].tba;
         break;
     case 0x0240:
         /* TBA1 */
-        ret = (uint64_t)s->pchip.win[1].translated_base_pfn << 10;
+        ret = s->pchip.win[1].tba;
         break;
     case 0x0280:
         /* TBA2 */
-        ret = (uint64_t)s->pchip.win[2].translated_base_pfn << 10;
+        ret = s->pchip.win[2].tba;
         break;
     case 0x02c0:
         /* TBA3 */
-        ret = (uint64_t)s->pchip.win[3].translated_base_pfn << 10;
+        ret = s->pchip.win[3].tba;
         break;
 
     case 0x0300:
@@ -458,53 +462,53 @@ static void pchip_write(void *opaque, hwaddr addr,
     switch (addr) {
     case 0x0000:
         /* WSBA0: Window Space Base Address Register.  */
-        s->pchip.win[0].base_addr = val;
+        s->pchip.win[0].wba = val & 0xfff00003u;
         break;
     case 0x0040:
         /* WSBA1 */
-        s->pchip.win[1].base_addr = val;
+        s->pchip.win[1].wba = val & 0xfff00003u;
         break;
     case 0x0080:
         /* WSBA2 */
-        s->pchip.win[2].base_addr = val;
+        s->pchip.win[2].wba = val & 0xfff00003u;
         break;
     case 0x00c0:
         /* WSBA3 */
-        s->pchip.win[3].base_addr = val;
+        s->pchip.win[3].wba = (val & 0x80fff00001ull) | 2;
         break;
 
     case 0x0100:
         /* WSM0: Window Space Mask Register.  */
-        s->pchip.win[0].mask = val;
+        s->pchip.win[0].wsm = val & 0xfff00000u;
         break;
     case 0x0140:
         /* WSM1 */
-        s->pchip.win[1].mask = val;
+        s->pchip.win[1].wsm = val & 0xfff00000u;
         break;
     case 0x0180:
         /* WSM2 */
-        s->pchip.win[2].mask = val;
+        s->pchip.win[2].wsm = val & 0xfff00000u;
         break;
     case 0x01c0:
         /* WSM3 */
-        s->pchip.win[3].mask = val;
+        s->pchip.win[3].wsm = val & 0xfff00000u;
         break;
 
     case 0x0200:
         /* TBA0: Translated Base Address Register.  */
-        s->pchip.win[0].translated_base_pfn = val >> 10;
+        s->pchip.win[0].tba = val & 0x7fffffc00ull;
         break;
     case 0x0240:
         /* TBA1 */
-        s->pchip.win[1].translated_base_pfn = val >> 10;
+        s->pchip.win[1].tba = val & 0x7fffffc00ull;
         break;
     case 0x0280:
         /* TBA2 */
-        s->pchip.win[2].translated_base_pfn = val >> 10;
+        s->pchip.win[2].tba = val & 0x7fffffc00ull;
         break;
     case 0x02c0:
         /* TBA3 */
-        s->pchip.win[3].translated_base_pfn = val >> 10;
+        s->pchip.win[3].tba = val & 0x7fffffc00ull;
         break;
 
     case 0x0300:
@@ -512,7 +516,6 @@ static void pchip_write(void *opaque, hwaddr addr,
         oldval = s->pchip.ctl;
         oldval &= ~0x00001cff0fc7ffull;       /* RW fields */
         oldval |= val & 0x00001cff0fc7ffull;
-
         s->pchip.ctl = oldval;
         break;
 
@@ -593,6 +596,140 @@ static const MemoryRegionOps pchip_ops = {
     },
 };
 
+/* A subroutine of typhoon_translate_iommu that builds an IOMMUTLBEntry
+   using the given translated address and mask.  */
+static bool make_iommu_tlbe(hwaddr taddr, hwaddr mask, IOMMUTLBEntry *ret)
+{
+    *ret = (IOMMUTLBEntry) {
+        .target_as = &address_space_memory,
+        .translated_addr = taddr,
+        .addr_mask = mask,
+        .perm = IOMMU_RW,
+    };
+    return true;
+}
+
+/* A subroutine of typhoon_translate_iommu that handles scatter-gather
+   translation, given the address of the PTE.  */
+static bool pte_translate(hwaddr pte_addr, IOMMUTLBEntry *ret)
+{
+    uint64_t pte = ldq_phys(pte_addr);
+
+    /* Check valid bit.  */
+    if ((pte & 1) == 0) {
+        return false;
+    }
+
+    return make_iommu_tlbe((pte & 0x3ffffe) << 12, 0x1fff, ret);
+}
+
+/* A subroutine of typhoon_translate_iommu that handles one of the
+   four single-address-cycle translation windows.  */
+static bool window_translate(TyphoonWindow *win, hwaddr addr,
+                             IOMMUTLBEntry *ret)
+{
+    uint32_t wba = win->wba;
+    uint64_t wsm = win->wsm;
+    uint64_t tba = win->tba;
+    uint64_t wsm_ext = wsm | 0xfffff;
+
+    /* Check for window disabled.  */
+    if ((wba & 1) == 0) {
+        return false;
+    }
+
+    /* Check for window hit.  */
+    if ((addr & ~wsm_ext) != (wba & 0xfff00000u)) {
+        return false;
+    }
+
+    if (wba & 2) {
+        /* Scatter-gather translation.  */
+        hwaddr pte_addr;
+
+        /* See table 10-6, Generating PTE address for PCI DMA Address.  */
+        pte_addr  = tba & ~(wsm >> 10);
+        pte_addr |= (addr & (wsm | 0xfe000)) >> 10;
+        return pte_translate(pte_addr, ret);
+    } else {
+	/* Direct-mapped translation.  */
+	return make_iommu_tlbe(tba & ~wsm_ext, wsm_ext, ret);
+    }
+}
+
+/* Handle PCI-to-system address translation.  */
+/* TODO: A translation failure here ought to set PCI error codes on the
+   Pchip and generate a machine check interrupt.  */
+static IOMMUTLBEntry typhoon_translate_iommu(MemoryRegion *iommu, hwaddr addr)
+{
+    TyphoonPchip *pchip = container_of(iommu, TyphoonPchip, iommu);
+    IOMMUTLBEntry ret;
+    int i;
+
+    if (addr <= 0xffffffffu) {
+        /* Single-address cycle.  */
+
+        /* Check for the Window Hole, inhibiting matching.  */
+        if ((pchip->ctl & 0x20)
+            && addr >= 0x80000
+            && addr <= 0xfffff) {
+            goto failure;
+        }
+
+        /* Check the first three windows.  */
+        for (i = 0; i < 3; ++i) {
+            if (window_translate(&pchip->win[i], addr, &ret)) {
+                goto success;
+            }
+        }
+
+        /* Check the fourth window for DAC disable.  */
+        if ((pchip->win[3].wba & 0x80000000000ull) == 0
+	    && window_translate(&pchip->win[3], addr, &ret)) {
+            goto success;
+        }
+    } else {
+        /* Double-address cycle.  */
+
+        if (addr >= 0x10000000000ull && addr < 0x20000000000ull) {
+            /* Check for the DMA monster window.  */
+            if (pchip->ctl & 0x40) {
+                /* See 10.1.4.4; in particular <39:35> is ignored.  */
+                make_iommu_tlbe(0, 0x007ffffffffull, &ret);
+		goto success;
+            }
+        }
+
+        if (addr >= 0x80000000000 && addr <= 0xfffffffffff) {
+            /* Check the fourth window for DAC enable and window enable.  */
+            if ((pchip->win[3].wba & 0x80000000001ull) == 0x80000000001ull) {
+                uint64_t pte_addr;
+
+                pte_addr  = pchip->win[3].tba & 0x7ffc00000ull;
+                pte_addr |= (addr & 0xffffe000u) >> 10;
+                if (pte_translate(pte_addr, &ret)) {
+			goto success;
+		}
+            }
+        }
+    }
+
+ failure:
+    ret = (IOMMUTLBEntry) { .perm = IOMMU_NONE };
+ success:
+    return ret;
+}
+
+static const MemoryRegionIOMMUOps typhoon_iommu_ops = {
+    .translate = typhoon_translate_iommu,
+};
+
+static AddressSpace *typhoon_pci_dma_iommu(PCIBus *bus, void *opaque, int devfn)
+{
+    TyphoonState *s = opaque;
+    return &s->pchip.iommu_as;
+}
+
 static void typhoon_set_irq(void *opaque, int irq, int level)
 {
     TyphoonState *s = opaque;
@@ -688,6 +825,9 @@ PCIBus *typhoon_init(ram_addr_t ram_size, ISABus **isa_bus,
     s = TYPHOON_PCI_HOST_BRIDGE(dev);
     phb = PCI_HOST_BRIDGE(dev);
 
+    s->cchip.misc = 0x800000000ull; /* Revision: Typhoon.  */
+    s->pchip.win[3].wba = 2;        /* Window 3 SG always enabled. */
+
     /* Remember the CPUs so that we can deliver interrupts to them.  */
     for (i = 0; i < 4; i++) {
         AlphaCPU *cpu = cpus[i];
@@ -746,6 +886,12 @@ PCIBus *typhoon_init(ram_addr_t ram_size, ISABus **isa_bus,
                          0, 64, TYPE_PCI_BUS);
     phb->bus = b;
 
+    /* Host memory as seen from the PCI side, via the IOMMU.  */
+    memory_region_init_iommu(&s->pchip.iommu, OBJECT(s), &typhoon_iommu_ops,
+                             "iommu-typhoon", UINT64_MAX);
+    address_space_init(&s->pchip.iommu_as, &s->pchip.iommu, "pchip0-pci");
+    pci_setup_iommu(b, typhoon_pci_dma_iommu, s);
+
     /* Pchip0 PCI special/interrupt acknowledge, 0x801.F800.0000, 64MB.  */
     memory_region_init_io(&s->pchip.reg_iack, OBJECT(s), &alpha_pci_iack_ops,
                           b, "pci0-iack", 64*MB);
commit b114b68adf12a5333bb95b252aed6309cf0c0e5f
Author: Richard Henderson <rth at twiddle.net>
Date:   Fri Jul 26 14:05:08 2013 -1000

    target-alpha: Consider the superpage when threading and ending TBs
    
    This allows significantly more threading, and occasionally larger TBs,
    when processing code for the kernel and PALcode.
    
    Signed-off-by: Richard Henderson <rth at twiddle.net>

diff --git a/target-alpha/translate.c b/target-alpha/translate.c
index f172670..309dea6 100644
--- a/target-alpha/translate.c
+++ b/target-alpha/translate.c
@@ -379,13 +379,26 @@ static ExitStatus gen_store_conditional(DisasContext *ctx, int ra, int rb,
 #endif
 }
 
-static int use_goto_tb(DisasContext *ctx, uint64_t dest)
+static bool in_superpage(DisasContext *ctx, int64_t addr)
 {
-    /* Check for the dest on the same page as the start of the TB.  We
-       also want to suppress goto_tb in the case of single-steping and IO.  */
-    return (((ctx->tb->pc ^ dest) & TARGET_PAGE_MASK) == 0
-            && !ctx->singlestep_enabled
-            && !(ctx->tb->cflags & CF_LAST_IO));
+    return ((ctx->tb->flags & TB_FLAGS_USER_MODE) == 0
+            && addr < 0
+            && ((addr >> 41) & 3) == 2
+            && addr >> TARGET_VIRT_ADDR_SPACE_BITS == addr >> 63);
+}
+
+static bool use_goto_tb(DisasContext *ctx, uint64_t dest)
+{
+    /* Suppress goto_tb in the case of single-steping and IO.  */
+    if (ctx->singlestep_enabled || (ctx->tb->cflags & CF_LAST_IO)) {
+        return false;
+    }
+    /* If the destination is in the superpage, the page perms can't change.  */
+    if (in_superpage(ctx, dest)) {
+        return true;
+    }
+    /* Check for the dest on the same page as the start of the TB.  */
+    return ((ctx->tb->pc ^ dest) & TARGET_PAGE_MASK) == 0;
 }
 
 static ExitStatus gen_bdirect(DisasContext *ctx, int ra, int32_t disp)
@@ -3431,6 +3444,7 @@ static inline void gen_intermediate_code_internal(AlphaCPU *cpu,
     CPUAlphaState *env = &cpu->env;
     DisasContext ctx, *ctxp = &ctx;
     target_ulong pc_start;
+    target_ulong pc_mask;
     uint32_t insn;
     uint16_t *gen_opc_end;
     CPUBreakpoint *bp;
@@ -3460,8 +3474,15 @@ static inline void gen_intermediate_code_internal(AlphaCPU *cpu,
 
     num_insns = 0;
     max_insns = tb->cflags & CF_COUNT_MASK;
-    if (max_insns == 0)
+    if (max_insns == 0) {
         max_insns = CF_COUNT_MASK;
+    }
+
+    if (in_superpage(&ctx, pc_start)) {
+        pc_mask = (1ULL << 41) - 1;
+    } else {
+        pc_mask = ~TARGET_PAGE_MASK;
+    }
 
     gen_tb_start();
     do {
@@ -3499,7 +3520,7 @@ static inline void gen_intermediate_code_internal(AlphaCPU *cpu,
         /* If we reach a page boundary, are single stepping,
            or exhaust instruction count, stop generation.  */
         if (ret == NO_EXIT
-            && ((ctx.pc & (TARGET_PAGE_SIZE - 1)) == 0
+            && ((ctx.pc & pc_mask) == 0
                 || tcg_ctx.gen_opc_ptr >= gen_opc_end
                 || num_insns >= max_insns
                 || singlestep
commit a9ead832617195a9b0727557c94dda776f8e8074
Author: Richard Henderson <rth at twiddle.net>
Date:   Fri Jul 26 12:00:32 2013 -1000

    target-alpha: Use goto_tb in call_pal
    
    With appropriate flushing when the PALBR changes, the target of
    a CALL_PAL is so predictable we can chain to it.
    
    Signed-off-by: Richard Henderson <rth at twiddle.net>

diff --git a/target-alpha/helper.h b/target-alpha/helper.h
index 5529c17..732b701 100644
--- a/target-alpha/helper.h
+++ b/target-alpha/helper.h
@@ -112,6 +112,7 @@ DEF_HELPER_3(stq_c_phys, i64, env, i64, i64)
 
 DEF_HELPER_FLAGS_1(tbia, TCG_CALL_NO_RWG, void, env)
 DEF_HELPER_FLAGS_2(tbis, TCG_CALL_NO_RWG, void, env, i64)
+DEF_HELPER_FLAGS_1(tb_flush, TCG_CALL_NO_RWG, void, env)
 
 DEF_HELPER_1(halt, void, i64);
 
diff --git a/target-alpha/sys_helper.c b/target-alpha/sys_helper.c
index ce51ed6..97cf9eb 100644
--- a/target-alpha/sys_helper.c
+++ b/target-alpha/sys_helper.c
@@ -72,6 +72,11 @@ void helper_tbis(CPUAlphaState *env, uint64_t p)
     tlb_flush_page(env, p);
 }
 
+void helper_tb_flush(CPUAlphaState *env)
+{
+    tb_flush(env);
+}
+
 void helper_halt(uint64_t restart)
 {
     if (restart) {
diff --git a/target-alpha/translate.c b/target-alpha/translate.c
index 59389a2..f172670 100644
--- a/target-alpha/translate.c
+++ b/target-alpha/translate.c
@@ -1609,6 +1609,17 @@ static ExitStatus gen_call_pal(DisasContext *ctx, int palcode)
 
         tcg_temp_free(entry);
         tcg_temp_free(pc);
+
+        /* Since the destination is running in PALmode, we don't really
+           need the page permissions check.  We'll see the existance of
+           the page when we create the TB, and we'll flush all TBs if
+           we change the PAL base register.  */
+        if (!ctx->singlestep_enabled && !(ctx->tb->cflags & CF_LAST_IO)) {
+            tcg_gen_goto_tb(0);
+            tcg_gen_exit_tb((tcg_target_long)ctx->tb);
+            return EXIT_GOTO_TB;
+        }
+
         return EXIT_PC_UPDATED;
     }
 #endif
@@ -1727,6 +1738,15 @@ static ExitStatus gen_mtpr(DisasContext *ctx, int rb, int regno)
         gen_helper_set_alarm(cpu_env, tmp);
         break;
 
+    case 7:
+        /* PALBR */
+        tcg_gen_st_i64(tmp, cpu_env, offsetof(CPUAlphaState, palbr));
+        /* Changing the PAL base register implies un-chaining all of the TBs
+           that ended with a CALL_PAL.  Since the base register usually only
+           changes during boot, flushing everything works well.  */
+        gen_helper_tb_flush(cpu_env);
+        return EXIT_PC_STALE;
+
     default:
         /* The basic registers are data only, and unknown registers
            are read-zero, write-ignore.  */
commit ba96394e20ad033a10eb790fdf2377e2a8892feb
Author: Richard Henderson <rth at twiddle.net>
Date:   Fri Jul 26 11:22:21 2013 -1000

    target-alpha: Implement call_pal without an exception
    
    The destination of the call_pal, and the cpu state, is very predictable;
    there's no need for exiting the cpu loop.
    
    Signed-off-by: Richard Henderson <rth at twiddle.net>

diff --git a/target-alpha/helper.h b/target-alpha/helper.h
index 0e425cf..5529c17 100644
--- a/target-alpha/helper.h
+++ b/target-alpha/helper.h
@@ -99,6 +99,7 @@ DEF_HELPER_FLAGS_2(ieee_input_cmp, TCG_CALL_NO_WG, void, env, i64)
 
 #if !defined (CONFIG_USER_ONLY)
 DEF_HELPER_2(hw_ret, void, env, i64)
+DEF_HELPER_3(call_pal, void, env, i64, i64)
 
 DEF_HELPER_1(ldl_phys, i64, i64)
 DEF_HELPER_1(ldq_phys, i64, i64)
diff --git a/target-alpha/sys_helper.c b/target-alpha/sys_helper.c
index bd94597..ce51ed6 100644
--- a/target-alpha/sys_helper.c
+++ b/target-alpha/sys_helper.c
@@ -51,6 +51,17 @@ void helper_hw_ret(CPUAlphaState *env, uint64_t a)
     }
 }
 
+void helper_call_pal(CPUAlphaState *env, uint64_t pc, uint64_t entry_ofs)
+{
+    int pal_mode = env->pal_mode;
+    env->exc_addr = pc | pal_mode;
+    env->pc = env->palbr + entry_ofs;
+    if (!pal_mode) {
+        env->pal_mode = 1;
+        swap_shadow_regs(env);
+    }
+}
+
 void helper_tbia(CPUAlphaState *env)
 {
     tlb_flush(env, 1);
@@ -91,4 +102,5 @@ void helper_set_alarm(CPUAlphaState *env, uint64_t expire)
         qemu_del_timer(cpu->alarm_timer);
     }
 }
+
 #endif /* CONFIG_USER_ONLY */
diff --git a/target-alpha/translate.c b/target-alpha/translate.c
index 0efd559..59389a2 100644
--- a/target-alpha/translate.c
+++ b/target-alpha/translate.c
@@ -1521,7 +1521,8 @@ static ExitStatus gen_call_pal(DisasContext *ctx, int palcode)
             tcg_gen_mov_i64(cpu_unique, cpu_ir[IR_A0]);
             break;
         default:
-            return gen_excp(ctx, EXCP_CALL_PAL, palcode & 0xbf);
+            palcode &= 0xbf;
+            goto do_call_pal;
         }
         return NO_EXIT;
     }
@@ -1586,13 +1587,31 @@ static ExitStatus gen_call_pal(DisasContext *ctx, int palcode)
             break;
 
         default:
-            return gen_excp(ctx, EXCP_CALL_PAL, palcode & 0x3f);
+            palcode &= 0x3f;
+            goto do_call_pal;
         }
         return NO_EXIT;
     }
 #endif
-
     return gen_invalid(ctx);
+
+ do_call_pal:
+#ifdef CONFIG_USER_ONLY
+    return gen_excp(ctx, EXCP_CALL_PAL, palcode);
+#else
+    {
+        TCGv pc = tcg_const_i64(ctx->pc);
+        TCGv entry = tcg_const_i64(palcode & 0x80
+                                   ? 0x2000 + (palcode - 0x80) * 64
+                                   : 0x1000 + palcode * 64);
+
+        gen_helper_call_pal(cpu_env, pc, entry);
+
+        tcg_temp_free(entry);
+        tcg_temp_free(pc);
+        return EXIT_PC_UPDATED;
+    }
+#endif
 }
 
 #ifndef CONFIG_USER_ONLY
commit 321bc0b2b27aa2dd64bf12e0e2a0f323a4903ecf
Author: Tiejun Chen <tiejun.chen at windriver.com>
Date:   Fri Aug 2 09:43:09 2013 +0800

    cpus: Use cpu_is_stopped() efficiently
    
    It makes more sense and will make things simpler later.
    
    Signed-off-by: Tiejun Chen <tiejun.chen at windriver.com>
    Signed-off-by: Andreas Färber <afaerber at suse.de>

diff --git a/cpus.c b/cpus.c
index 0f65e76..70cc617 100644
--- a/cpus.c
+++ b/cpus.c
@@ -62,12 +62,17 @@
 
 static CPUState *next_cpu;
 
+bool cpu_is_stopped(CPUState *cpu)
+{
+    return cpu->stopped || !runstate_is_running();
+}
+
 static bool cpu_thread_is_idle(CPUState *cpu)
 {
     if (cpu->stop || cpu->queued_work_first) {
         return false;
     }
-    if (cpu->stopped || !runstate_is_running()) {
+    if (cpu_is_stopped(cpu)) {
         return true;
     }
     if (!cpu->halted || qemu_cpu_has_work(cpu) ||
@@ -429,11 +434,6 @@ void cpu_synchronize_all_post_init(void)
     }
 }
 
-bool cpu_is_stopped(CPUState *cpu)
-{
-    return !runstate_is_running() || cpu->stopped;
-}
-
 static int do_vm_stop(RunState state)
 {
     int ret = 0;
@@ -457,7 +457,7 @@ static bool cpu_can_run(CPUState *cpu)
     if (cpu->stop) {
         return false;
     }
-    if (cpu->stopped || !runstate_is_running()) {
+    if (cpu_is_stopped(cpu)) {
         return false;
     }
     return true;
commit 92067bf4bfa144ea3967a9951808f5e587bdab18
Author: Igor Mammedov <imammedo at redhat.com>
Date:   Wed Jun 5 15:18:40 2013 +0200

    target-i386: Move hyperv_* static globals to X86CPU
    
    - since hyperv_* helper functions are used only in target-i386/kvm.c
      move them there as static helpers
    
    Requested-by: Eduardo Habkost <ehabkost at redhat.com>
    Signed-off-by: Igor Mammedov <imammedo at redhat.com>
    Signed-off-by: Andreas Färber <afaerber at suse.de>

diff --git a/target-i386/Makefile.objs b/target-i386/Makefile.objs
index 3b629d4d..da1fc40 100644
--- a/target-i386/Makefile.objs
+++ b/target-i386/Makefile.objs
@@ -3,7 +3,7 @@ obj-y += excp_helper.o fpu_helper.o cc_helper.o int_helper.o svm_helper.o
 obj-y += smm_helper.o misc_helper.o mem_helper.o seg_helper.o
 obj-y += gdbstub.o
 obj-$(CONFIG_SOFTMMU) += machine.o arch_memory_mapping.o arch_dump.o
-obj-$(CONFIG_KVM) += kvm.o hyperv.o
+obj-$(CONFIG_KVM) += kvm.o
 obj-$(CONFIG_NO_KVM) += kvm-stub.o
 obj-$(CONFIG_LINUX_USER) += ioport-user.o
 obj-$(CONFIG_BSD_USER) += ioport-user.o
diff --git a/target-i386/cpu-qom.h b/target-i386/cpu-qom.h
index 53b4c34..c4447c2 100644
--- a/target-i386/cpu-qom.h
+++ b/target-i386/cpu-qom.h
@@ -66,6 +66,10 @@ typedef struct X86CPU {
 
     CPUX86State env;
 
+    bool hyperv_vapic;
+    bool hyperv_relaxed_timing;
+    int hyperv_spinlock_attempts;
+
     /* Features that were filtered out because of missing host capabilities */
     uint32_t filtered_features[FEATURE_WORDS];
 
diff --git a/target-i386/cpu.c b/target-i386/cpu.c
index 2efbeca..6e38252 100644
--- a/target-i386/cpu.c
+++ b/target-i386/cpu.c
@@ -35,8 +35,6 @@
 #include "qapi/visitor.h"
 #include "sysemu/arch_init.h"
 
-#include "hyperv.h"
-
 #include "hw/hw.h"
 #if defined(CONFIG_KVM)
 #include <linux/kvm_para.h>
@@ -1591,12 +1589,19 @@ static void cpu_x86_parse_featurestr(X86CPU *cpu, char *features, Error **errp)
                 object_property_parse(OBJECT(cpu), num, "tsc-frequency", errp);
             } else if (!strcmp(featurestr, "hv-spinlocks")) {
                 char *err;
+                const int min = 0xFFF;
                 numvalue = strtoul(val, &err, 0);
                 if (!*val || *err) {
                     error_setg(errp, "bad numerical value %s", val);
                     goto out;
                 }
-                hyperv_set_spinlock_retries(numvalue);
+                if (numvalue < min) {
+                    fprintf(stderr, "hv-spinlocks value shall always be >= 0x%x"
+                            ", fixup will be removed in future versions\n",
+                            min);
+                    numvalue = min;
+                }
+                cpu->hyperv_spinlock_attempts = numvalue;
             } else {
                 error_setg(errp, "unrecognized feature %s", featurestr);
                 goto out;
@@ -1606,9 +1611,9 @@ static void cpu_x86_parse_featurestr(X86CPU *cpu, char *features, Error **errp)
         } else if (!strcmp(featurestr, "enforce")) {
             check_cpuid = enforce_cpuid = 1;
         } else if (!strcmp(featurestr, "hv_relaxed")) {
-            hyperv_enable_relaxed_timing(true);
+            cpu->hyperv_relaxed_timing = true;
         } else if (!strcmp(featurestr, "hv_vapic")) {
-            hyperv_enable_vapic_recommended(true);
+            cpu->hyperv_vapic = true;
         } else {
             error_setg(errp, "feature string `%s' not in format (+feature|"
                        "-feature|feature=xyz)", featurestr);
@@ -2489,6 +2494,7 @@ static void x86_cpu_initfn(Object *obj)
                         x86_cpu_get_feature_words,
                         NULL, NULL, (void *)cpu->filtered_features, NULL);
 
+    cpu->hyperv_spinlock_attempts = HYPERV_SPINLOCK_NEVER_RETRY;
     env->cpuid_apic_id = x86_cpu_apic_id_from_index(cs->cpu_index);
 
     /* init various static tables used in TCG mode */
diff --git a/target-i386/cpu.h b/target-i386/cpu.h
index cedefdc..8a3d0fd 100644
--- a/target-i386/cpu.h
+++ b/target-i386/cpu.h
@@ -549,6 +549,10 @@ typedef uint32_t FeatureWordArray[FEATURE_WORDS];
 #define CPUID_MWAIT_IBE     (1 << 1) /* Interrupts can exit capability */
 #define CPUID_MWAIT_EMX     (1 << 0) /* enumeration supported */
 
+#ifndef HYPERV_SPINLOCK_NEVER_RETRY
+#define HYPERV_SPINLOCK_NEVER_RETRY             0xFFFFFFFF
+#endif
+
 #define EXCP00_DIVZ	0
 #define EXCP01_DB	1
 #define EXCP02_NMI	2
diff --git a/target-i386/hyperv.c b/target-i386/hyperv.c
deleted file mode 100644
index f284e99..0000000
--- a/target-i386/hyperv.c
+++ /dev/null
@@ -1,64 +0,0 @@
-/*
- * QEMU Hyper-V support
- *
- * Copyright Red Hat, Inc. 2011
- *
- * Author: Vadim Rozenfeld     <vrozenfe at redhat.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 "hyperv.h"
-
-static bool hyperv_vapic;
-static bool hyperv_relaxed_timing;
-static int hyperv_spinlock_attempts = HYPERV_SPINLOCK_NEVER_RETRY;
-
-void hyperv_enable_vapic_recommended(bool val)
-{
-    hyperv_vapic = val;
-}
-
-void hyperv_enable_relaxed_timing(bool val)
-{
-    hyperv_relaxed_timing = val;
-}
-
-void hyperv_set_spinlock_retries(int val)
-{
-    hyperv_spinlock_attempts = val;
-    if (hyperv_spinlock_attempts < 0xFFF) {
-        hyperv_spinlock_attempts = 0xFFF;
-    }
-}
-
-bool hyperv_enabled(void)
-{
-    return hyperv_hypercall_available() || hyperv_relaxed_timing_enabled();
-}
-
-bool hyperv_hypercall_available(void)
-{
-    if (hyperv_vapic ||
-        (hyperv_spinlock_attempts != HYPERV_SPINLOCK_NEVER_RETRY)) {
-      return true;
-    }
-    return false;
-}
-
-bool hyperv_vapic_recommended(void)
-{
-    return hyperv_vapic;
-}
-
-bool hyperv_relaxed_timing_enabled(void)
-{
-    return hyperv_relaxed_timing;
-}
-
-int hyperv_get_spinlock_retries(void)
-{
-    return hyperv_spinlock_attempts;
-}
diff --git a/target-i386/hyperv.h b/target-i386/hyperv.h
deleted file mode 100644
index bacb1d4..0000000
--- a/target-i386/hyperv.h
+++ /dev/null
@@ -1,45 +0,0 @@
-/*
- * QEMU Hyper-V support
- *
- * Copyright Red Hat, Inc. 2011
- *
- * Author: Vadim Rozenfeld     <vrozenfe at redhat.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.
- *
- */
-
-#ifndef QEMU_HW_HYPERV_H
-#define QEMU_HW_HYPERV_H 1
-
-#include "qemu-common.h"
-#ifdef CONFIG_KVM
-#include <asm/hyperv.h>
-#endif
-
-#ifndef HYPERV_SPINLOCK_NEVER_RETRY
-#define HYPERV_SPINLOCK_NEVER_RETRY             0xFFFFFFFF
-#endif
-
-#ifndef KVM_CPUID_SIGNATURE_NEXT
-#define KVM_CPUID_SIGNATURE_NEXT                0x40000100
-#endif
-
-#if !defined(CONFIG_USER_ONLY) && defined(CONFIG_KVM)
-void hyperv_enable_vapic_recommended(bool val);
-void hyperv_enable_relaxed_timing(bool val);
-void hyperv_set_spinlock_retries(int val);
-#else
-static inline void hyperv_enable_vapic_recommended(bool val) { }
-static inline void hyperv_enable_relaxed_timing(bool val) { }
-static inline void hyperv_set_spinlock_retries(int val) { }
-#endif
-
-bool hyperv_enabled(void);
-bool hyperv_hypercall_available(void);
-bool hyperv_vapic_recommended(void);
-bool hyperv_relaxed_timing_enabled(void);
-int hyperv_get_spinlock_retries(void);
-
-#endif /* QEMU_HW_HYPERV_H */
diff --git a/target-i386/kvm.c b/target-i386/kvm.c
index 376fc70..0b6eb01 100644
--- a/target-i386/kvm.c
+++ b/target-i386/kvm.c
@@ -31,7 +31,7 @@
 #include "hw/i386/pc.h"
 #include "hw/i386/apic.h"
 #include "exec/ioport.h"
-#include "hyperv.h"
+#include <asm/hyperv.h>
 #include "hw/pci/pci.h"
 
 //#define DEBUG_KVM
@@ -420,6 +420,22 @@ unsigned long kvm_arch_vcpu_id(CPUState *cs)
     return cpu->env.cpuid_apic_id;
 }
 
+#ifndef KVM_CPUID_SIGNATURE_NEXT
+#define KVM_CPUID_SIGNATURE_NEXT                0x40000100
+#endif
+
+static bool hyperv_hypercall_available(X86CPU *cpu)
+{
+    return cpu->hyperv_vapic ||
+           (cpu->hyperv_spinlock_attempts != HYPERV_SPINLOCK_NEVER_RETRY);
+}
+
+static bool hyperv_enabled(X86CPU *cpu)
+{
+    return hyperv_hypercall_available(cpu) ||
+           cpu->hyperv_relaxed_timing;
+}
+
 #define KVM_MAX_CPUID_ENTRIES  100
 
 int kvm_arch_init_vcpu(CPUState *cs)
@@ -442,7 +458,7 @@ int kvm_arch_init_vcpu(CPUState *cs)
     c = &cpuid_data.entries[cpuid_i++];
     memset(c, 0, sizeof(*c));
     c->function = KVM_CPUID_SIGNATURE;
-    if (!hyperv_enabled()) {
+    if (!hyperv_enabled(cpu)) {
         memcpy(signature, "KVMKVMKVM\0\0\0", 12);
         c->eax = 0;
     } else {
@@ -458,7 +474,7 @@ int kvm_arch_init_vcpu(CPUState *cs)
     c->function = KVM_CPUID_FEATURES;
     c->eax = env->features[FEAT_KVM];
 
-    if (hyperv_enabled()) {
+    if (hyperv_enabled(cpu)) {
         memcpy(signature, "Hv#1\0\0\0\0\0\0\0\0", 12);
         c->eax = signature[0];
 
@@ -471,10 +487,10 @@ int kvm_arch_init_vcpu(CPUState *cs)
         c = &cpuid_data.entries[cpuid_i++];
         memset(c, 0, sizeof(*c));
         c->function = HYPERV_CPUID_FEATURES;
-        if (hyperv_relaxed_timing_enabled()) {
+        if (cpu->hyperv_relaxed_timing) {
             c->eax |= HV_X64_MSR_HYPERCALL_AVAILABLE;
         }
-        if (hyperv_vapic_recommended()) {
+        if (cpu->hyperv_vapic) {
             c->eax |= HV_X64_MSR_HYPERCALL_AVAILABLE;
             c->eax |= HV_X64_MSR_APIC_ACCESS_AVAILABLE;
         }
@@ -482,13 +498,13 @@ int kvm_arch_init_vcpu(CPUState *cs)
         c = &cpuid_data.entries[cpuid_i++];
         memset(c, 0, sizeof(*c));
         c->function = HYPERV_CPUID_ENLIGHTMENT_INFO;
-        if (hyperv_relaxed_timing_enabled()) {
+        if (cpu->hyperv_relaxed_timing) {
             c->eax |= HV_X64_RELAXED_TIMING_RECOMMENDED;
         }
-        if (hyperv_vapic_recommended()) {
+        if (cpu->hyperv_vapic) {
             c->eax |= HV_X64_APIC_ACCESS_RECOMMENDED;
         }
-        c->ebx = hyperv_get_spinlock_retries();
+        c->ebx = cpu->hyperv_spinlock_attempts;
 
         c = &cpuid_data.entries[cpuid_i++];
         memset(c, 0, sizeof(*c));
@@ -1114,11 +1130,11 @@ static int kvm_put_msrs(X86CPU *cpu, int level)
             kvm_msr_entry_set(&msrs[n++], MSR_KVM_STEAL_TIME,
                               env->steal_time_msr);
         }
-        if (hyperv_hypercall_available()) {
+        if (hyperv_hypercall_available(cpu)) {
             kvm_msr_entry_set(&msrs[n++], HV_X64_MSR_GUEST_OS_ID, 0);
             kvm_msr_entry_set(&msrs[n++], HV_X64_MSR_HYPERCALL, 0);
         }
-        if (hyperv_vapic_recommended()) {
+        if (cpu->hyperv_vapic) {
             kvm_msr_entry_set(&msrs[n++], HV_X64_MSR_APIC_ASSIST_PAGE, 0);
         }
     }
commit 99a0b03650176340ab6667fa1e5711a4552d4494
Author: Eduardo Habkost <ehabkost at redhat.com>
Date:   Wed Jul 10 17:08:42 2013 -0300

    qdev: Set globals in instance_post_init function
    
    This way, properties registered in the instance_init function of
    child classes will be handled properly by qdev_prop_set_globals(), too.
    
    Includes a unit test for the new functionality.
    
    Signed-off-by: Eduardo Habkost <ehabkost at redhat.com>
    Signed-off-by: Andreas Färber <afaerber at suse.de>

diff --git a/hw/core/qdev.c b/hw/core/qdev.c
index 9190a7e..758de9f 100644
--- a/hw/core/qdev.c
+++ b/hw/core/qdev.c
@@ -752,7 +752,6 @@ static void device_initfn(Object *obj)
         }
         class = object_class_get_parent(class);
     } while (class != object_class_by_name(TYPE_DEVICE));
-    qdev_prop_set_globals(dev, &err);
     if (err != NULL) {
         qerror_report_err(err);
         error_free(err);
@@ -764,6 +763,15 @@ static void device_initfn(Object *obj)
     assert_no_error(err);
 }
 
+static void device_post_init(Object *obj)
+{
+    DeviceState *dev = DEVICE(obj);
+    Error *err = NULL;
+
+    qdev_prop_set_globals(dev, &err);
+    assert_no_error(err);
+}
+
 /* Unlink device from bus and free the structure.  */
 static void device_finalize(Object *obj)
 {
@@ -853,6 +861,7 @@ static const TypeInfo device_type_info = {
     .parent = TYPE_OBJECT,
     .instance_size = sizeof(DeviceState),
     .instance_init = device_initfn,
+    .instance_post_init = device_post_init,
     .instance_finalize = device_finalize,
     .class_base_init = device_class_base_init,
     .class_init = device_class_init,
diff --git a/tests/test-qdev-global-props.c b/tests/test-qdev-global-props.c
index 08dfc87..e4ad173 100644
--- a/tests/test-qdev-global-props.c
+++ b/tests/test-qdev-global-props.c
@@ -26,6 +26,8 @@
 #include <stdint.h>
 
 #include "hw/qdev.h"
+#include "qom/object.h"
+#include "qapi/visitor.h"
 
 
 #define TYPE_STATIC_PROPS "static_prop_type"
@@ -91,15 +93,86 @@ static void test_static_globalprop(void)
     g_assert_cmpuint(mt->prop2, ==, PROP_DEFAULT);
 }
 
+#define TYPE_DYNAMIC_PROPS "dynamic-prop-type"
+#define DYNAMIC_TYPE(obj) \
+    OBJECT_CHECK(MyType, (obj), TYPE_DYNAMIC_PROPS)
+
+static void prop1_accessor(Object *obj,
+                           Visitor *v,
+                           void *opaque,
+                           const char *name,
+                           Error **errp)
+{
+    MyType *mt = DYNAMIC_TYPE(obj);
+
+    visit_type_uint32(v, &mt->prop1, name, errp);
+}
+
+static void prop2_accessor(Object *obj,
+                           Visitor *v,
+                           void *opaque,
+                           const char *name,
+                           Error **errp)
+{
+    MyType *mt = DYNAMIC_TYPE(obj);
+
+    visit_type_uint32(v, &mt->prop2, name, errp);
+}
+
+static void dynamic_instance_init(Object *obj)
+{
+    object_property_add(obj, "prop1", "uint32", prop1_accessor, prop1_accessor,
+                        NULL, NULL, NULL);
+    object_property_add(obj, "prop2", "uint32", prop2_accessor, prop2_accessor,
+                        NULL, NULL, NULL);
+}
+
+static void dynamic_class_init(ObjectClass *oc, void *data)
+{
+    DeviceClass *dc = DEVICE_CLASS(oc);
+
+    dc->realize = NULL;
+}
+
+
+static const TypeInfo dynamic_prop_type = {
+    .name = TYPE_DYNAMIC_PROPS,
+    .parent = TYPE_DEVICE,
+    .instance_size = sizeof(MyType),
+    .instance_init = dynamic_instance_init,
+    .class_init = dynamic_class_init,
+};
+
+/* Test setting of static property using global properties */
+static void test_dynamic_globalprop(void)
+{
+    MyType *mt;
+    static GlobalProperty props[] = {
+        { TYPE_DYNAMIC_PROPS, "prop1", "101" },
+        { TYPE_DYNAMIC_PROPS, "prop2", "102" },
+        {}
+    };
+
+    qdev_prop_register_global_list(props);
+
+    mt = DYNAMIC_TYPE(object_new(TYPE_DYNAMIC_PROPS));
+    qdev_init_nofail(DEVICE(mt));
+
+    g_assert_cmpuint(mt->prop1, ==, 101);
+    g_assert_cmpuint(mt->prop2, ==, 102);
+}
+
 int main(int argc, char **argv)
 {
     g_test_init(&argc, &argv, NULL);
 
     module_call_init(MODULE_INIT_QOM);
     type_register_static(&static_prop_type);
+    type_register_static(&dynamic_prop_type);
 
     g_test_add_func("/qdev/properties/static/default", test_static_prop);
     g_test_add_func("/qdev/properties/static/global", test_static_globalprop);
+    g_test_add_func("/qdev/properties/dynamic/global", test_dynamic_globalprop);
 
     g_test_run();
 
commit 8231c2dd220336bbc7522c490d95742f6ba0adae
Author: Eduardo Habkost <ehabkost at redhat.com>
Date:   Wed Jul 10 17:08:41 2013 -0300

    qom: Introduce instance_post_init hook
    
    This will allow classes to specify a function to be called after all
    instance_init functions were called.
    
    This will be used by DeviceState to call qdev_prop_set_globals() at the
    right moment.
    
    Signed-off-by: Eduardo Habkost <ehabkost at redhat.com>
    Signed-off-by: Andreas Färber <afaerber at suse.de>

diff --git a/include/qom/object.h b/include/qom/object.h
index 23fc048..9b69065 100644
--- a/include/qom/object.h
+++ b/include/qom/object.h
@@ -398,6 +398,8 @@ struct Object
  * @instance_init: This function is called to initialize an object.  The parent
  *   class will have already been initialized so the type is only responsible
  *   for initializing its own members.
+ * @instance_post_init: This function is called to finish initialization of
+ *   an object, after all @instance_init functions were called.
  * @instance_finalize: This function is called during object destruction.  This
  *   is called before the parent @instance_finalize function has been called.
  *   An object should only free the members that are unique to its type in this
@@ -433,6 +435,7 @@ struct TypeInfo
 
     size_t instance_size;
     void (*instance_init)(Object *obj);
+    void (*instance_post_init)(Object *obj);
     void (*instance_finalize)(Object *obj);
 
     bool abstract;
diff --git a/qom/object.c b/qom/object.c
index b2479d1..74fd241 100644
--- a/qom/object.c
+++ b/qom/object.c
@@ -51,6 +51,7 @@ struct TypeImpl
     void *class_data;
 
     void (*instance_init)(Object *obj);
+    void (*instance_post_init)(Object *obj);
     void (*instance_finalize)(Object *obj);
 
     bool abstract;
@@ -111,6 +112,7 @@ static TypeImpl *type_register_internal(const TypeInfo *info)
     ti->class_data = info->class_data;
 
     ti->instance_init = info->instance_init;
+    ti->instance_post_init = info->instance_post_init;
     ti->instance_finalize = info->instance_finalize;
 
     ti->abstract = info->abstract;
@@ -298,6 +300,17 @@ static void object_init_with_type(Object *obj, TypeImpl *ti)
     }
 }
 
+static void object_post_init_with_type(Object *obj, TypeImpl *ti)
+{
+    if (ti->instance_post_init) {
+        ti->instance_post_init(obj);
+    }
+
+    if (type_has_parent(ti)) {
+        object_post_init_with_type(obj, type_get_parent(ti));
+    }
+}
+
 void object_initialize_with_type(void *data, TypeImpl *type)
 {
     Object *obj = data;
@@ -313,6 +326,7 @@ void object_initialize_with_type(void *data, TypeImpl *type)
     object_ref(obj);
     QTAILQ_INIT(&obj->properties);
     object_init_with_type(obj, type);
+    object_post_init_with_type(obj, type);
 }
 
 void object_initialize(void *data, const char *typename)
commit 747b0cb4b51296e85add0a23d5fc1d24e250ec08
Author: Eduardo Habkost <ehabkost at redhat.com>
Date:   Wed Jul 10 17:08:40 2013 -0300

    tests: Unit tests for qdev global properties handling
    
    This tests the qdev global-properties handling code.
    
    Signed-off-by: Eduardo Habkost <ehabkost at redhat.com>
    Signed-off-by: Andreas Färber <afaerber at suse.de>

diff --git a/tests/.gitignore b/tests/.gitignore
index fb05c2a..d11cc22 100644
--- a/tests/.gitignore
+++ b/tests/.gitignore
@@ -11,6 +11,7 @@ test-iov
 test-mul64
 test-qapi-types.[ch]
 test-qapi-visit.[ch]
+test-qdev-global-props
 test-qmp-commands.h
 test-qmp-commands
 test-qmp-input-strict
diff --git a/tests/Makefile b/tests/Makefile
index d044908..b0200fd 100644
--- a/tests/Makefile
+++ b/tests/Makefile
@@ -48,6 +48,7 @@ check-unit-y += tests/test-int128$(EXESUF)
 # all code tested by test-int128 is inside int128.h
 gcov-files-test-int128-y =
 check-unit-y += tests/test-bitops$(EXESUF)
+check-unit-y += tests/test-qdev-global-props$(EXESUF)
 
 check-block-$(CONFIG_POSIX) += tests/qemu-iotests-quick.sh
 
@@ -123,6 +124,12 @@ tests/test-x86-cpuid$(EXESUF): tests/test-x86-cpuid.o
 tests/test-xbzrle$(EXESUF): tests/test-xbzrle.o xbzrle.o page_cache.o libqemuutil.a
 tests/test-cutils$(EXESUF): tests/test-cutils.o util/cutils.o
 tests/test-int128$(EXESUF): tests/test-int128.o
+tests/test-qdev-global-props$(EXESUF): tests/test-qdev-global-props.o \
+	hw/core/qdev.o hw/core/qdev-properties.o \
+	hw/core/irq.o \
+	qom/object.o qom/container.o qom/qom-qobject.o \
+	$(test-qapi-obj-y) \
+	libqemuutil.a libqemustub.a
 
 tests/test-qapi-types.c tests/test-qapi-types.h :\
 $(SRC_PATH)/tests/qapi-schema/qapi-schema-test.json $(SRC_PATH)/scripts/qapi-types.py
diff --git a/tests/test-qdev-global-props.c b/tests/test-qdev-global-props.c
new file mode 100644
index 0000000..08dfc87
--- /dev/null
+++ b/tests/test-qdev-global-props.c
@@ -0,0 +1,107 @@
+/*
+ *  Test code for qdev global-properties handling
+ *
+ *  Copyright (c) 2012 Red Hat Inc.
+ *
+ * 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 <glib.h>
+#include <stdint.h>
+
+#include "hw/qdev.h"
+
+
+#define TYPE_STATIC_PROPS "static_prop_type"
+#define STATIC_TYPE(obj) \
+    OBJECT_CHECK(MyType, (obj), TYPE_STATIC_PROPS)
+
+#define PROP_DEFAULT 100
+
+typedef struct MyType {
+    DeviceState parent_obj;
+
+    uint32_t prop1;
+    uint32_t prop2;
+} MyType;
+
+static Property static_props[] = {
+    DEFINE_PROP_UINT32("prop1", MyType, prop1, PROP_DEFAULT),
+    DEFINE_PROP_UINT32("prop2", MyType, prop2, PROP_DEFAULT),
+    DEFINE_PROP_END_OF_LIST()
+};
+
+static void static_prop_class_init(ObjectClass *oc, void *data)
+{
+    DeviceClass *dc = DEVICE_CLASS(oc);
+
+    dc->realize = NULL;
+    dc->props = static_props;
+}
+
+static const TypeInfo static_prop_type = {
+    .name = TYPE_STATIC_PROPS,
+    .parent = TYPE_DEVICE,
+    .instance_size = sizeof(MyType),
+    .class_init = static_prop_class_init,
+};
+
+/* Test simple static property setting to default value */
+static void test_static_prop(void)
+{
+    MyType *mt;
+
+    mt = STATIC_TYPE(object_new(TYPE_STATIC_PROPS));
+    qdev_init_nofail(DEVICE(mt));
+
+    g_assert_cmpuint(mt->prop1, ==, PROP_DEFAULT);
+}
+
+/* Test setting of static property using global properties */
+static void test_static_globalprop(void)
+{
+    MyType *mt;
+    static GlobalProperty props[] = {
+        { TYPE_STATIC_PROPS, "prop1", "200" },
+        {}
+    };
+
+    qdev_prop_register_global_list(props);
+
+    mt = STATIC_TYPE(object_new(TYPE_STATIC_PROPS));
+    qdev_init_nofail(DEVICE(mt));
+
+    g_assert_cmpuint(mt->prop1, ==, 200);
+    g_assert_cmpuint(mt->prop2, ==, PROP_DEFAULT);
+}
+
+int main(int argc, char **argv)
+{
+    g_test_init(&argc, &argv, NULL);
+
+    module_call_init(MODULE_INIT_QOM);
+    type_register_static(&static_prop_type);
+
+    g_test_add_func("/qdev/properties/static/default", test_static_prop);
+    g_test_add_func("/qdev/properties/static/global", test_static_globalprop);
+
+    g_test_run();
+
+    return 0;
+}
commit 35143f0164e6933a85c7c2b8a89a040d881a9151
Author: Andreas Färber <afaerber at suse.de>
Date:   Mon Aug 12 18:09:47 2013 +0200

    gdbstub: Fix gdb_register_coprocessor() register counting
    
    Commit a0e372f0c49ac01faeaeb73a6e8f50e8ac615f34 reorganized the register
    counting for GDB. While it seems correct not to let the total number of
    registers skyrocket in an SMP scenario through a static variable, the
    distinction between total register count and 'g' packet register count
    (last_reg vs. num_g_regs) got lost among the way.
    
    Fix this by introducing CPUState::gdb_num_g_regs and using that in
    gdb_handle_packet().
    
    Reported-by: Aneesh Kumar K.V <aneesh.kumar at linux.vnet.ibm.com>
    Cc: qemu-stable at nongnu.org (stable-1.6)
    Tested-by: Aneesh Kumar K.V <aneesh.kumar at linux.vnet.ibm.com>
    Tested-by: Max Filippov <jcmvbkbc at gmail.com>
    Tested-by: Peter Maydell <peter.maydell at linaro.org>
    Signed-off-by: Andreas Färber <afaerber at suse.de>

diff --git a/gdbstub.c b/gdbstub.c
index 1af25a6..9d067d6 100644
--- a/gdbstub.c
+++ b/gdbstub.c
@@ -621,6 +621,8 @@ void gdb_register_coprocessor(CPUState *cpu,
         if (g_pos != s->base_reg) {
             fprintf(stderr, "Error: Bad gdb register numbering for '%s'\n"
                     "Expected %d got %d\n", xml, g_pos, s->base_reg);
+        } else {
+            cpu->gdb_num_g_regs = cpu->gdb_num_regs;
         }
     }
 }
@@ -902,7 +904,7 @@ static int gdb_handle_packet(GDBState *s, const char *line_buf)
     case 'g':
         cpu_synchronize_state(s->g_cpu);
         len = 0;
-        for (addr = 0; addr < s->g_cpu->gdb_num_regs; addr++) {
+        for (addr = 0; addr < s->g_cpu->gdb_num_g_regs; addr++) {
             reg_size = gdb_read_register(s->g_cpu, mem_buf + len, addr);
             len += reg_size;
         }
@@ -914,7 +916,7 @@ static int gdb_handle_packet(GDBState *s, const char *line_buf)
         registers = mem_buf;
         len = strlen(p) / 2;
         hextomem((uint8_t *)registers, p, len);
-        for (addr = 0; addr < s->g_cpu->gdb_num_regs && len > 0; addr++) {
+        for (addr = 0; addr < s->g_cpu->gdb_num_g_regs && len > 0; addr++) {
             reg_size = gdb_write_register(s->g_cpu, registers, addr);
             len -= reg_size;
             registers += reg_size;
diff --git a/include/qom/cpu.h b/include/qom/cpu.h
index 0d6e95c..3e49936 100644
--- a/include/qom/cpu.h
+++ b/include/qom/cpu.h
@@ -152,6 +152,7 @@ struct kvm_run;
  * @current_tb: Currently executing TB.
  * @gdb_regs: Additional GDB registers.
  * @gdb_num_regs: Number of total registers accessible to GDB.
+ * @gdb_num_g_regs: Number of registers in GDB 'g' packets.
  * @next_cpu: Next CPU sharing TB cache.
  * @kvm_fd: vCPU file descriptor for KVM.
  *
@@ -188,6 +189,7 @@ struct CPUState {
     struct TranslationBlock *current_tb;
     struct GDBRegisterState *gdb_regs;
     int gdb_num_regs;
+    int gdb_num_g_regs;
     CPUState *next_cpu;
 
     int kvm_fd;
diff --git a/qom/cpu.c b/qom/cpu.c
index aa95108..e71e57b 100644
--- a/qom/cpu.c
+++ b/qom/cpu.c
@@ -240,7 +240,7 @@ static void cpu_common_initfn(Object *obj)
     CPUState *cpu = CPU(obj);
     CPUClass *cc = CPU_GET_CLASS(obj);
 
-    cpu->gdb_num_regs = cc->gdb_num_core_regs;
+    cpu->gdb_num_regs = cpu->gdb_num_g_regs = cc->gdb_num_core_regs;
 }
 
 static int64_t cpu_common_get_arch_id(CPUState *cpu)
commit f202039811d8746b0586d2fd5f61de6c8cf68056
Author: Anthony Liguori <aliguori at us.ibm.com>
Date:   Thu Aug 15 15:41:13 2013 -0500

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

diff --git a/VERSION b/VERSION
index dc1e644..0a8112b 100644
--- a/VERSION
+++ b/VERSION
@@ -1 +1 @@
-1.6.0
+1.6.50
commit 1ee2daeb6448312d6d0e22175f5c1b9b01f8974c
Author: Anthony Liguori <aliguori at us.ibm.com>
Date:   Thu Aug 15 10:40:51 2013 -0500

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

diff --git a/VERSION b/VERSION
index daeb9f5..dc1e644 100644
--- a/VERSION
+++ b/VERSION
@@ -1 +1 @@
-1.5.93
+1.6.0
commit cc413a39355ed910f22f8f0be5e233c08a0773a0
Author: Aurelien Jarno <aurelien at aurel32.net>
Date:   Mon Aug 12 21:34:53 2013 +0200

    mips_malta: do not raise exceptions when accessing invalid memory
    
    Since commit c658b94f6e8c206c59d02aa6fbac285b86b53d2c, MIPS raises
    exceptions when accessing invalid memory. This is not the correct
    behaviour for MIPS Malta Core LV, as the GT-64120A system controller
    just ignore undecoded access. This feature is used by the Linux kernel
    to probe for some devices.
    
    Emulate the correct behaviour in QEMU by adding an empty slot covering
    the entire memory space decoded by the GT-64120A.
    
    Tested-by: Stefan Weil <sw at weilnetz.de>
    Signed-off-by: Aurelien Jarno <aurelien at aurel32.net>

diff --git a/default-configs/mips-softmmu.mak b/default-configs/mips-softmmu.mak
index 926709a..71177ef 100644
--- a/default-configs/mips-softmmu.mak
+++ b/default-configs/mips-softmmu.mak
@@ -34,3 +34,4 @@ CONFIG_JAZZ_LED=y
 CONFIG_MC146818RTC=y
 CONFIG_VT82C686=y
 CONFIG_ISA_TESTDEV=y
+CONFIG_EMPTY_SLOT=y
diff --git a/default-configs/mips64-softmmu.mak b/default-configs/mips64-softmmu.mak
index 0ef3f09..617301b 100644
--- a/default-configs/mips64-softmmu.mak
+++ b/default-configs/mips64-softmmu.mak
@@ -34,3 +34,4 @@ CONFIG_JAZZ_LED=y
 CONFIG_MC146818RTC=y
 CONFIG_VT82C686=y
 CONFIG_ISA_TESTDEV=y
+CONFIG_EMPTY_SLOT=y
diff --git a/default-configs/mips64el-softmmu.mak b/default-configs/mips64el-softmmu.mak
index 6089318..317b151 100644
--- a/default-configs/mips64el-softmmu.mak
+++ b/default-configs/mips64el-softmmu.mak
@@ -36,3 +36,4 @@ CONFIG_JAZZ_LED=y
 CONFIG_MC146818RTC=y
 CONFIG_VT82C686=y
 CONFIG_ISA_TESTDEV=y
+CONFIG_EMPTY_SLOT=y
diff --git a/default-configs/mipsel-softmmu.mak b/default-configs/mipsel-softmmu.mak
index cd59e24..532a9ae 100644
--- a/default-configs/mipsel-softmmu.mak
+++ b/default-configs/mipsel-softmmu.mak
@@ -34,3 +34,4 @@ CONFIG_JAZZ_LED=y
 CONFIG_MC146818RTC=y
 CONFIG_VT82C686=y
 CONFIG_ISA_TESTDEV=y
+CONFIG_EMPTY_SLOT=y
diff --git a/hw/mips/mips_malta.c b/hw/mips/mips_malta.c
index 0f5de33..f8d064c 100644
--- a/hw/mips/mips_malta.c
+++ b/hw/mips/mips_malta.c
@@ -50,6 +50,7 @@
 #include "qemu/host-utils.h"
 #include "sysemu/qtest.h"
 #include "qemu/error-report.h"
+#include "hw/empty_slot.h"
 
 //#define DEBUG_BOARD_INIT
 
@@ -908,6 +909,11 @@ void mips_malta_init(QEMUMachineInitArgs *args)
     DeviceState *dev = qdev_create(NULL, TYPE_MIPS_MALTA);
     MaltaState *s = MIPS_MALTA(dev);
 
+    /* The whole address space decoded by the GT-64120A doesn't generate
+       exception when accessing invalid memory. Create an empty slot to
+       emulate this feature. */
+    empty_slot_init(0, 0x20000000);
+
     qdev_init_nofail(dev);
 
     /* Make sure the first 3 serial ports are associated with a device. */
commit 8b7a5415f9297c1fbae5bff28dcb059d50c1b045
Author: M. Mohan Kumar <mohan at in.ibm.com>
Date:   Wed Aug 14 17:56:41 2013 +0530

    block: Dont ignore previously set bdrv_flags
    
    bdrv_flags is set by bdrv_parse_discard_flags(), but later it is reset
    to zero.
    
    Signed-off-by: M. Mohan Kumar <mohan at in.ibm.com>
    Message-id: 1376483201-13466-1-git-send-email-mohan at in.ibm.com
    Signed-off-by: Anthony Liguori <aliguori at us.ibm.com>

diff --git a/blockdev.c b/blockdev.c
index e174b7d..bc7016a 100644
--- a/blockdev.c
+++ b/blockdev.c
@@ -454,7 +454,6 @@ static DriveInfo *blockdev_init(QemuOpts *all_opts,
         }
     }
 
-    bdrv_flags = 0;
     if (qemu_opt_get_bool(opts, "cache.writeback", true)) {
         bdrv_flags |= BDRV_O_CACHE_WB;
     }
commit 3a3567d337d3ee6fb2e2fcc1d27cd045ed97ae9b
Author: James Hogan <james.hogan at imgtec.com>
Date:   Thu Aug 8 12:09:38 2013 +0100

    qemu-char: fix infinite recursion connecting to monitor pty
    
    Since commit bd5c51e (qemu-char: don't issue CHR_EVENT_OPEN in a BH), an
    infinite recursion occurs when putting the monitor on a pty (-monitor
    pty) and connecting a terminal to the slave port.
    
    This is because of the qemu_chr_be_event(s, CHR_EVENT_OPENED) added to
    qemu_chr_be_generic_open(). This event is captured by monitor_event()
    which prints a welcome message to the character device. The flush of
    that welcome message retriggers another open event in pty_chr_state()
    because it checks s->connected, but only sets it to 1 after calling
    qemu_chr_be_generic_open().
    
    I've fixed this by setting s->connected = 1 before the call to
    qemu_chr_be_generic_open() instead of after, so that the recursive
    pty_chr_state() doesn't call it again.
    
    An example snippet of repeating backtrace:
     ...
     #107486 0x007aec58 in monitor_flush (mon=0xf418b0) at qemu/monitor.c:288
     #107487 0x007aee7c in monitor_puts (mon=0xf418b0, str=0x1176d07 "") at qemu/monitor.c:322
     #107488 0x007aef20 in monitor_vprintf (mon=0xf418b0, fmt=0x8d4820 "QEMU %s monitor - type 'help' for more information\n",
         ap=0x7f432be0) at qemu/monitor.c:339
     #107489 0x007aefac in monitor_printf (mon=0xf418b0, fmt=0x8d4820 "QEMU %s monitor - type 'help' for more information\n")
         at qemu/monitor.c:347
     #107490 0x007ba4bc in monitor_event (opaque=0xf418b0, event=2) at qemu/monitor.c:4699
     #107491 0x00684c28 in qemu_chr_be_event (s=0xf37788, event=2) at qemu/qemu-char.c:108
     #107492 0x00684c70 in qemu_chr_be_generic_open (s=0xf37788) at qemu/qemu-char.c:113
     #107493 0x006880a4 in pty_chr_state (chr=0xf37788, connected=1) at qemu/qemu-char.c:1145
     #107494 0x00687fa4 in pty_chr_update_read_handler (chr=0xf37788) at qemu/qemu-char.c:1121
     #107495 0x00687c9c in pty_chr_write (chr=0xf37788, buf=0x70b3c008 <Address 0x70b3c008 out of bounds>, len=538720)
         at qemu/qemu-char.c:1063
     #107496 0x00684cc4 in qemu_chr_fe_write (s=0xf37788, buf=0x70b3c008 <Address 0x70b3c008 out of bounds>, len=538720)
         at qemu/qemu-char.c:118
     ...
    
    Signed-off-by: James Hogan <james.hogan at imgtec.com>
    Tested-by: Michael Roth <mdroth at linux.vnet.ibm.com>
    Message-id: 1375960178-10882-1-git-send-email-james.hogan at imgtec.com
    Cc: Michael Roth <mdroth at linux.vnet.ibm.com>
    Cc: Anthony Liguori <aliguori at us.ibm.com>
    Signed-off-by: Anthony Liguori <aliguori at us.ibm.com>

diff --git a/qemu-char.c b/qemu-char.c
index 16f3ad7..1be1cf6 100644
--- a/qemu-char.c
+++ b/qemu-char.c
@@ -1142,8 +1142,8 @@ static void pty_chr_state(CharDriverState *chr, int connected)
             s->timer_tag = 0;
         }
         if (!s->connected) {
-            qemu_chr_be_generic_open(chr);
             s->connected = 1;
+            qemu_chr_be_generic_open(chr);
             s->fd_tag = io_add_watch_poll(s->fd, pty_chr_read_poll, pty_chr_read, chr);
         }
     }
commit 02653c5ea77bc3837376232ce508b7dd3e358ca1
Author: Anthony Liguori <aliguori at us.ibm.com>
Date:   Tue Aug 13 09:02:52 2013 -0500

    pvpanic: fix bad merge
    
    Context matching caused the 'has_pvpanic = true' to be applied to
    the 1.6 machine type instead of the 1.5 machine type.
    
    Reported-by: Markus Armbruster <armbru at redhat.com>
    Reported-by: Michael S. Tsirkin <mst at redhat.com>
    Signed-off-by: Anthony Liguori <aliguori at us.ibm.com>

diff --git a/hw/i386/pc_piix.c b/hw/i386/pc_piix.c
index 55c24f2..6e1e654 100644
--- a/hw/i386/pc_piix.c
+++ b/hw/i386/pc_piix.c
@@ -252,12 +252,12 @@ static void pc_init_pci(QEMUMachineInitArgs *args)
 static void pc_init_pci_1_6(QEMUMachineInitArgs *args)
 {
     has_pci_info = false;
-    has_pvpanic = true;
     pc_init_pci(args);
 }
 
 static void pc_init_pci_1_5(QEMUMachineInitArgs *args)
 {
+    has_pvpanic = true;
     pc_init_pci_1_6(args);
 }
 
diff --git a/hw/i386/pc_q35.c b/hw/i386/pc_q35.c
index bd25071..10e770e 100644
--- a/hw/i386/pc_q35.c
+++ b/hw/i386/pc_q35.c
@@ -221,12 +221,12 @@ static void pc_q35_init(QEMUMachineInitArgs *args)
 static void pc_q35_init_1_6(QEMUMachineInitArgs *args)
 {
     has_pci_info = false;
-    has_pvpanic = true;
     pc_q35_init(args);
 }
 
 static void pc_q35_init_1_5(QEMUMachineInitArgs *args)
 {
+    has_pvpanic = true;
     pc_q35_init_1_6(args);
 }
 
commit 328465fd9f3a628ab320b5959d68d3d49df58fa6
Author: Anthony Liguori <aliguori at us.ibm.com>
Date:   Mon Aug 12 15:03:36 2013 -0500

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

diff --git a/VERSION b/VERSION
index fc7c9a4..daeb9f5 100644
--- a/VERSION
+++ b/VERSION
@@ -1 +1 @@
-1.5.92
+1.5.93
commit 9d054ea543c2f94ddea5db29cc908899a188c07d
Merge: 9fb7aaa 5638370
Author: Anthony Liguori <aliguori at us.ibm.com>
Date:   Mon Aug 12 15:03:20 2013 -0500

    Merge remote-tracking branch 'afaerber/tags/qom-cpu-for-anthony' into staging
    
    QOM CPUState refactorings
    
    * Fix X86CPU Westmere CPUID for pc-*-1.4 and older
    
    * afaerber/tags/qom-cpu-for-anthony:
      pc: Remove PCLMULQDQ from Westmere on pc-*-1.4 and older
    
    Conflicts:
    	hw/i386/pc_piix.c
    	hw/i386/pc_q35.c
    
    Signed-off-by: Anthony Liguori <aliguori at us.ibm.com>

diff --cc hw/i386/pc_piix.c
index 7ad7c0b,1329f97..55c24f2
--- a/hw/i386/pc_piix.c
+++ b/hw/i386/pc_piix.c
@@@ -263,9 -263,10 +263,10 @@@ static void pc_init_pci_1_5(QEMUMachine
  
  static void pc_init_pci_1_4(QEMUMachineInitArgs *args)
  {
 -    has_pvpanic = false;
      x86_cpu_compat_set_features("n270", FEAT_1_ECX, 0, CPUID_EXT_MOVBE);
+     x86_cpu_compat_set_features("Westmere", FEAT_1_ECX, 0, CPUID_EXT_PCLMULQDQ);
 -    pc_init_pci_1_5(args);
 +    has_pci_info = false;
 +    pc_init_pci(args);
  }
  
  static void pc_init_pci_1_3(QEMUMachineInitArgs *args)
diff --cc hw/i386/pc_q35.c
index 6c7b401,1d84ead..bd25071
--- a/hw/i386/pc_q35.c
+++ b/hw/i386/pc_q35.c
@@@ -232,9 -231,10 +232,10 @@@ static void pc_q35_init_1_5(QEMUMachine
  
  static void pc_q35_init_1_4(QEMUMachineInitArgs *args)
  {
 -    has_pvpanic = false;
      x86_cpu_compat_set_features("n270", FEAT_1_ECX, 0, CPUID_EXT_MOVBE);
+     x86_cpu_compat_set_features("Westmere", FEAT_1_ECX, 0, CPUID_EXT_PCLMULQDQ);
 -    pc_q35_init_1_5(args);
 +    has_pci_info = false;
 +    pc_q35_init(args);
  }
  
  static QEMUMachine pc_q35_machine_v1_6 = {
commit 9fb7aaaf4c58c9108327f0ae4766087e3e496b47
Author: Anthony Liguori <aliguori at us.ibm.com>
Date:   Mon Aug 12 09:01:44 2013 -0500

    pc: drop external DSDT loading
    
    This breaks migration and is unneeded with modern SeaBIOS.
    
    Signed-off-by: Anthony Liguori <aliguori at us.ibm.com>
    Message-id: 1376316104-11269-1-git-send-email-aliguori at us.ibm.com

diff --git a/hw/i386/pc_piix.c b/hw/i386/pc_piix.c
index ec7f13f..7ad7c0b 100644
--- a/hw/i386/pc_piix.c
+++ b/hw/i386/pc_piix.c
@@ -103,7 +103,6 @@ static void pc_init1(MemoryRegion *system_memory,
                               OBJECT(icc_bridge), NULL);
 
     pc_cpus_init(cpu_model, icc_bridge);
-    pc_acpi_init("acpi-dsdt.aml");
 
     if (kvm_enabled() && kvmclock_enabled) {
         kvmclock_create();
commit a5d3f640a0fa56eaed712c9361150568e32e1d08
Author: Marcel Apfelbaum <marcel.a at redhat.com>
Date:   Sun Aug 11 18:10:43 2013 +0300

    hw/misc: make pvpanic known to user
    
    This patch is based on Hu Tao's:
    http://lists.nongnu.org/archive/html/qemu-devel/2013-08/msg00125.html
    
    The pvpanic device may be enabled now with "-device pvpanic"
    from command line.
    
    Signed-off-by: Marcel Apfelbaum <marcel.a at redhat.com>
    Reviewed-by: Hu Tao <hutao at cn.fujitsu.com>
    Message-id: 1376233843-19410-3-git-send-email-marcel.a at redhat.com
    Signed-off-by: Anthony Liguori <aliguori at us.ibm.com>

diff --git a/hw/misc/pvpanic.c b/hw/misc/pvpanic.c
index 7bb49a5..b64e3bb 100644
--- a/hw/misc/pvpanic.c
+++ b/hw/misc/pvpanic.c
@@ -97,29 +97,24 @@ static void pvpanic_isa_realizefn(DeviceState *dev, Error **errp)
 {
     ISADevice *d = ISA_DEVICE(dev);
     PVPanicState *s = ISA_PVPANIC_DEVICE(dev);
+    FWCfgState *fw_cfg = fw_cfg_find();
+    uint16_t *pvpanic_port;
 
-    isa_register_ioport(d, &s->io, s->ioport);
-}
+    if (!fw_cfg) {
+        return;
+    }
 
-static void pvpanic_fw_cfg(ISADevice *dev, FWCfgState *fw_cfg)
-{
-    PVPanicState *s = ISA_PVPANIC_DEVICE(dev);
-    uint16_t *pvpanic_port = g_malloc(sizeof(*pvpanic_port));
+    pvpanic_port = g_malloc(sizeof(*pvpanic_port));
     *pvpanic_port = cpu_to_le16(s->ioport);
-
     fw_cfg_add_file(fw_cfg, "etc/pvpanic-port", pvpanic_port,
                     sizeof(*pvpanic_port));
+
+    isa_register_ioport(d, &s->io, s->ioport);
 }
 
 void pvpanic_init(ISABus *bus)
 {
-    ISADevice *dev;
-    FWCfgState *fw_cfg = fw_cfg_find();
-    if (!fw_cfg) {
-        return;
-    }
-    dev = isa_create_simple (bus, TYPE_ISA_PVPANIC_DEVICE);
-    pvpanic_fw_cfg(dev, fw_cfg);
+    isa_create_simple(bus, TYPE_ISA_PVPANIC_DEVICE);
 }
 
 static Property pvpanic_isa_properties[] = {
@@ -132,8 +127,8 @@ static void pvpanic_isa_class_init(ObjectClass *klass, void *data)
     DeviceClass *dc = DEVICE_CLASS(klass);
 
     dc->realize = pvpanic_isa_realizefn;
-    dc->no_user = 1;
     dc->props = pvpanic_isa_properties;
+    set_bit(DEVICE_CATEGORY_MISC, dc->categories);
 }
 
 static TypeInfo pvpanic_isa_info = {
commit 7f3e341a008c585deed174eaf1f826c88c67948a
Author: Marcel Apfelbaum <marcel.a at redhat.com>
Date:   Sun Aug 11 18:10:42 2013 +0300

    hw/misc: don't create pvpanic device by default
    
    This patch is based on Hu Tao's:
    http://lists.nongnu.org/archive/html/qemu-devel/2013-08/msg00124.html
    
    No need to hard-code pvpanic as part of the machine.
    It can be added with "-device pvpanic" from command line (The next patch).
    Anyway, for backport compatibility it is still part of 1.5
    machine.
    
    Signed-off-by: Marcel Apfelbaum <marcel.a at redhat.com>
    Reviewed-by: Hu Tao <hutao at cn.fujitsu.com>
    Message-id: 1376233843-19410-2-git-send-email-marcel.a at redhat.com
    Signed-off-by: Anthony Liguori <aliguori at us.ibm.com>

diff --git a/hw/i386/pc_piix.c b/hw/i386/pc_piix.c
index a19e172..ec7f13f 100644
--- a/hw/i386/pc_piix.c
+++ b/hw/i386/pc_piix.c
@@ -56,7 +56,7 @@ static const int ide_iobase[MAX_IDE_BUS] = { 0x1f0, 0x170 };
 static const int ide_iobase2[MAX_IDE_BUS] = { 0x3f6, 0x376 };
 static const int ide_irq[MAX_IDE_BUS] = { 14, 15 };
 
-static bool has_pvpanic = true;
+static bool has_pvpanic;
 static bool has_pci_info = true;
 
 /* PC hardware initialisation */
@@ -253,6 +253,7 @@ static void pc_init_pci(QEMUMachineInitArgs *args)
 static void pc_init_pci_1_6(QEMUMachineInitArgs *args)
 {
     has_pci_info = false;
+    has_pvpanic = true;
     pc_init_pci(args);
 }
 
@@ -263,9 +264,9 @@ static void pc_init_pci_1_5(QEMUMachineInitArgs *args)
 
 static void pc_init_pci_1_4(QEMUMachineInitArgs *args)
 {
-    has_pvpanic = false;
     x86_cpu_compat_set_features("n270", FEAT_1_ECX, 0, CPUID_EXT_MOVBE);
-    pc_init_pci_1_5(args);
+    has_pci_info = false;
+    pc_init_pci(args);
 }
 
 static void pc_init_pci_1_3(QEMUMachineInitArgs *args)
@@ -296,7 +297,6 @@ static void pc_init_pci_no_kvmclock(QEMUMachineInitArgs *args)
     const char *kernel_cmdline = args->kernel_cmdline;
     const char *initrd_filename = args->initrd_filename;
     const char *boot_device = args->boot_device;
-    has_pvpanic = false;
     has_pci_info = false;
     disable_kvm_pv_eoi();
     enable_compat_apic_id_mode();
@@ -315,7 +315,6 @@ static void pc_init_isa(QEMUMachineInitArgs *args)
     const char *kernel_cmdline = args->kernel_cmdline;
     const char *initrd_filename = args->initrd_filename;
     const char *boot_device = args->boot_device;
-    has_pvpanic = false;
     has_pci_info = false;
     if (cpu_model == NULL)
         cpu_model = "486";
diff --git a/hw/i386/pc_q35.c b/hw/i386/pc_q35.c
index be6013f..6c7b401 100644
--- a/hw/i386/pc_q35.c
+++ b/hw/i386/pc_q35.c
@@ -46,7 +46,7 @@
 /* ICH9 AHCI has 6 ports */
 #define MAX_SATA_PORTS     6
 
-static bool has_pvpanic = true;
+static bool has_pvpanic;
 static bool has_pci_info = true;
 
 /* PC hardware initialisation */
@@ -221,6 +221,7 @@ static void pc_q35_init(QEMUMachineInitArgs *args)
 static void pc_q35_init_1_6(QEMUMachineInitArgs *args)
 {
     has_pci_info = false;
+    has_pvpanic = true;
     pc_q35_init(args);
 }
 
@@ -231,9 +232,9 @@ static void pc_q35_init_1_5(QEMUMachineInitArgs *args)
 
 static void pc_q35_init_1_4(QEMUMachineInitArgs *args)
 {
-    has_pvpanic = false;
     x86_cpu_compat_set_features("n270", FEAT_1_ECX, 0, CPUID_EXT_MOVBE);
-    pc_q35_init_1_5(args);
+    has_pci_info = false;
+    pc_q35_init(args);
 }
 
 static QEMUMachine pc_q35_machine_v1_6 = {
commit 56383703c060777fd01aaf8d63d5f46d660e9fb9
Author: Eduardo Habkost <ehabkost at redhat.com>
Date:   Fri Aug 9 11:11:36 2013 -0300

    pc: Remove PCLMULQDQ from Westmere on pc-*-1.4 and older
    
    Commit 41cb383f42d0cb51d8e3e25e3ecebc954dd4196f made a guest-visible
    change by adding the PCLMULQDQ bit to Westmere without adding
    compatibility code to keep the ABI for older machine-types.
    Fix it by adding the missing compat code.
    
    Signed-off-by: Eduardo Habkost <ehabkost 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 a19e172..1329f97 100644
--- a/hw/i386/pc_piix.c
+++ b/hw/i386/pc_piix.c
@@ -265,6 +265,7 @@ static void pc_init_pci_1_4(QEMUMachineInitArgs *args)
 {
     has_pvpanic = false;
     x86_cpu_compat_set_features("n270", FEAT_1_ECX, 0, CPUID_EXT_MOVBE);
+    x86_cpu_compat_set_features("Westmere", FEAT_1_ECX, 0, CPUID_EXT_PCLMULQDQ);
     pc_init_pci_1_5(args);
 }
 
diff --git a/hw/i386/pc_q35.c b/hw/i386/pc_q35.c
index be6013f..1d84ead 100644
--- a/hw/i386/pc_q35.c
+++ b/hw/i386/pc_q35.c
@@ -233,6 +233,7 @@ static void pc_q35_init_1_4(QEMUMachineInitArgs *args)
 {
     has_pvpanic = false;
     x86_cpu_compat_set_features("n270", FEAT_1_ECX, 0, CPUID_EXT_MOVBE);
+    x86_cpu_compat_set_features("Westmere", FEAT_1_ECX, 0, CPUID_EXT_PCLMULQDQ);
     pc_q35_init_1_5(args);
 }
 
commit 8f3067bd86485f8cd03abc940ddb2b8467ef3627
Author: Michael R. Hines <mrhines at us.ibm.com>
Date:   Fri Aug 9 16:05:45 2013 -0400

    rdma: remaining documentation fixes
    
    Was missing 'setup-time' in some of the QMP documentation...
    
    Signed-off-by: Michael R. Hines <mrhines at us.ibm.com>
    Reviewed-by: Eric Blake <eblake at redhat.com>
    Message-id: 1376078746-24948-7-git-send-email-mrhines at linux.vnet.ibm.com
    Signed-off-by: Anthony Liguori <aliguori at us.ibm.com>

diff --git a/qmp-commands.hx b/qmp-commands.hx
index 2e59b0d..cf47e3f 100644
--- a/qmp-commands.hx
+++ b/qmp-commands.hx
@@ -2621,6 +2621,12 @@ The main json-object contains the following:
 - "total-time": total amount of ms since migration started.  If
                 migration has ended, it returns the total migration
                 time (json-int)
+- "setup-time" amount of setup time in milliseconds _before_ the
+               iterations begin but _after_ the QMP command is issued.
+               This is designed to provide an accounting of any activities
+               (such as RDMA pinning) which may be expensive, but do not 
+               actually occur during the iterative migration rounds 
+               themselves. (json-int)
 - "downtime": only present when migration has finished correctly
               total amount in ms for downtime that happened (json-int)
 - "expected-downtime": only present while migration is active
@@ -2674,6 +2680,7 @@ Examples:
           "remaining":123,
           "total":246,
           "total-time":12345,
+          "setup-time":12345,
           "downtime":12345,
           "duplicate":123,
           "normal":123,
@@ -2698,6 +2705,7 @@ Examples:
             "remaining":123,
             "total":246,
             "total-time":12345,
+            "setup-time":12345,
             "expected-downtime":12345,
             "duplicate":123,
             "normal":123,
@@ -2717,6 +2725,7 @@ Examples:
             "remaining":1053304,
             "transferred":3720,
             "total-time":12345,
+            "setup-time":12345,
             "expected-downtime":12345,
             "duplicate":123,
             "normal":123,
@@ -2742,6 +2751,7 @@ Examples:
             "remaining":1053304,
             "transferred":3720,
             "total-time":12345,
+            "setup-time":12345,
             "expected-downtime":12345,
             "duplicate":10,
             "normal":3333,
commit 7fc5b13fd7b05babc7bcad9dcb8281ae202a9494
Author: Michael R. Hines <mrhines at us.ibm.com>
Date:   Fri Aug 9 16:05:44 2013 -0400

    rdma: IPv6 over Ethernet (RoCE) is broken in linux - workaround
    
    We've gotten reports from multiple testers (including Frank Yangjie
    and myself) that RDMA IPv6 support over RocE (Ethernet) is broken
    in linux.
    
    A patch to Linux is still in review:
    
    http://comments.gmane.org/gmane.linux.drivers.rdma/16448
    
    If the user is listening on '[::]', then we will not have a opened a device
    yet and have no way of verifying if the device is RoCE or not.
    
    In this case, the source VM will throw an error for ALL types of
    connections (both IPv4 and IPv6) if the destination machine does not have
    a regular infiniband network available for use.
    
    The only way to gaurantee that an error is thrown for broken kernels is
    for the management software to choose a *specific* interface at bind time
    and validate what time of hardware it is.
    
    Unfortunately, this puts the user in a fix:
    
     If the source VM connects with an IPv4 address without knowing that the
     destination has bound to '[::]' the migration will unconditionally fail
     unless the management software is not explicitly listening on the the IPv4
     address while using a RoCE-based device.
    
     If the source VM connects with an IPv6 address, then we're OK because we can
     throw an error on the source (and similarly on the destination).
    
     But in mixed environments, this will be broken for a while until it is fixed
     inside linux.
    
    We do provide a *tiny* bit of help in mixed environments, though in this patch:
    
    We can list all of the devices in the system and check to see if all the
    devices are RoCE or Infiniband.
    
    If we detect that we have a *pure* RoCE environment, then we can safely
    thrown an error even if the management sofware has specified '[::]' as the
    bind address.
    
    However, if there is are multiple hetergeneous devices, then we cannot make
    this assumption and the user just has to be sure they know what they are doing.
    
    Signed-off-by: Michael R. Hines <mrhines at us.ibm.com>
    Message-id: 1376078746-24948-6-git-send-email-mrhines at linux.vnet.ibm.com
    Signed-off-by: Anthony Liguori <aliguori at us.ibm.com>

diff --git a/migration-rdma.c b/migration-rdma.c
index d71cca5..3d1266f 100644
--- a/migration-rdma.c
+++ b/migration-rdma.c
@@ -707,15 +707,27 @@ static int __qemu_rdma_delete_block(RDMAContext *rdma, ram_addr_t block_offset)
  */
 static void qemu_rdma_dump_id(const char *who, struct ibv_context *verbs)
 {
+    struct ibv_port_attr port;
+
+    if (ibv_query_port(verbs, 1, &port)) {
+        fprintf(stderr, "FAILED TO QUERY PORT INFORMATION!\n");
+        return;
+    }
+
     printf("%s RDMA Device opened: kernel name %s "
            "uverbs device name %s, "
-           "infiniband_verbs class device path %s,"
-           " infiniband class device path %s\n",
+           "infiniband_verbs class device path %s, "
+           "infiniband class device path %s, "
+           "transport: (%d) %s\n",
                 who,
                 verbs->device->name,
                 verbs->device->dev_name,
                 verbs->device->dev_path,
-                verbs->device->ibdev_path);
+                verbs->device->ibdev_path,
+                port.link_layer,
+                (port.link_layer == IBV_LINK_LAYER_INFINIBAND) ? "Infiniband" :
+                 ((port.link_layer == IBV_LINK_LAYER_ETHERNET) 
+                    ? "Ethernet" : "Unknown"));
 }
 
 /*
@@ -733,6 +745,132 @@ static void qemu_rdma_dump_gid(const char *who, struct rdma_cm_id *id)
 }
 
 /*
+ * As of now, IPv6 over RoCE / iWARP is not supported by linux.
+ * We will try the next addrinfo struct, and fail if there are
+ * no other valid addresses to bind against.
+ *
+ * If user is listening on '[::]', then we will not have a opened a device
+ * yet and have no way of verifying if the device is RoCE or not.
+ *
+ * In this case, the source VM will throw an error for ALL types of
+ * connections (both IPv4 and IPv6) if the destination machine does not have
+ * a regular infiniband network available for use.
+ *
+ * The only way to gaurantee that an error is thrown for broken kernels is
+ * for the management software to choose a *specific* interface at bind time
+ * and validate what time of hardware it is.
+ *
+ * Unfortunately, this puts the user in a fix:
+ * 
+ *  If the source VM connects with an IPv4 address without knowing that the
+ *  destination has bound to '[::]' the migration will unconditionally fail
+ *  unless the management software is explicitly listening on the the IPv4
+ *  address while using a RoCE-based device.
+ *
+ *  If the source VM connects with an IPv6 address, then we're OK because we can
+ *  throw an error on the source (and similarly on the destination).
+ * 
+ *  But in mixed environments, this will be broken for a while until it is fixed
+ *  inside linux.
+ *
+ * We do provide a *tiny* bit of help in this function: We can list all of the
+ * devices in the system and check to see if all the devices are RoCE or
+ * Infiniband. 
+ *
+ * If we detect that we have a *pure* RoCE environment, then we can safely
+ * thrown an error even if the management sofware has specified '[::]' as the
+ * bind address.
+ *
+ * However, if there is are multiple hetergeneous devices, then we cannot make
+ * this assumption and the user just has to be sure they know what they are
+ * doing.
+ *
+ * Patches are being reviewed on linux-rdma.
+ */
+static int qemu_rdma_broken_ipv6_kernel(Error **errp, struct ibv_context *verbs)
+{
+    struct ibv_port_attr port_attr;
+
+    /* This bug only exists in linux, to our knowledge. */
+#ifdef CONFIG_LINUX
+
+    /* 
+     * Verbs are only NULL if management has bound to '[::]'.
+     * 
+     * Let's iterate through all the devices and see if there any pure IB
+     * devices (non-ethernet).
+     * 
+     * If not, then we can safely proceed with the migration.
+     * Otherwise, there are no gaurantees until the bug is fixed in linux.
+     */
+    if (!verbs) {
+	    int num_devices, x;
+        struct ibv_device ** dev_list = ibv_get_device_list(&num_devices);
+        bool roce_found = false;
+        bool ib_found = false;
+
+        for (x = 0; x < num_devices; x++) {
+            verbs = ibv_open_device(dev_list[x]);
+
+            if (ibv_query_port(verbs, 1, &port_attr)) {
+                ibv_close_device(verbs);
+                ERROR(errp, "Could not query initial IB port");
+                return -EINVAL;
+            }
+
+            if (port_attr.link_layer == IBV_LINK_LAYER_INFINIBAND) {
+                ib_found = true;
+            } else if (port_attr.link_layer == IBV_LINK_LAYER_ETHERNET) {
+                roce_found = true;
+            }
+
+            ibv_close_device(verbs);
+
+        }
+
+        if (roce_found) {
+            if (ib_found) {
+                fprintf(stderr, "WARN: migrations may fail:"
+                                " IPv6 over RoCE / iWARP in linux"
+                                " is broken. But since you appear to have a"
+                                " mixed RoCE / IB environment, be sure to only"
+                                " migrate over the IB fabric until the kernel "
+                                " fixes the bug.\n");
+            } else {
+                ERROR(errp, "You only have RoCE / iWARP devices in your systems"
+                            " and your management software has specified '[::]'"
+                            ", but IPv6 over RoCE / iWARP is not supported in Linux.");
+                return -ENONET;
+            }
+        }
+
+        return 0;
+    }
+
+    /*
+     * If we have a verbs context, that means that some other than '[::]' was
+     * used by the management software for binding. In which case we can actually 
+     * warn the user about a potential broken kernel;
+     */
+
+    /* IB ports start with 1, not 0 */
+    if (ibv_query_port(verbs, 1, &port_attr)) {
+        ERROR(errp, "Could not query initial IB port");
+        return -EINVAL;
+    }
+
+    if (port_attr.link_layer == IBV_LINK_LAYER_ETHERNET) {
+        ERROR(errp, "Linux kernel's RoCE / iWARP does not support IPv6 "
+                    "(but patches on linux-rdma in progress)");
+        return -ENONET;
+    }
+
+#endif
+
+    return 0;
+}
+
+/*
  * Figure out which RDMA device corresponds to the requested IP hostname
  * Also create the initial connection manager identifiers for opening
  * the connection.
@@ -740,22 +878,22 @@ static void qemu_rdma_dump_gid(const char *who, struct rdma_cm_id *id)
 static int qemu_rdma_resolve_host(RDMAContext *rdma, Error **errp)
 {
     int ret;
-    struct addrinfo *res;
+    struct rdma_addrinfo *res;
     char port_str[16];
     struct rdma_cm_event *cm_event;
     char ip[40] = "unknown";
-    struct addrinfo *e;
+    struct rdma_addrinfo *e;
 
     if (rdma->host == NULL || !strcmp(rdma->host, "")) {
         ERROR(errp, "RDMA hostname has not been set");
-        return -1;
+        return -EINVAL;
     }
 
     /* create CM channel */
     rdma->channel = rdma_create_event_channel();
     if (!rdma->channel) {
         ERROR(errp, "could not create CM channel");
-        return -1;
+        return -EINVAL;
     }
 
     /* create CM id */
@@ -768,21 +906,24 @@ static int qemu_rdma_resolve_host(RDMAContext *rdma, Error **errp)
     snprintf(port_str, 16, "%d", rdma->port);
     port_str[15] = '\0';
 
-    ret = getaddrinfo(rdma->host, port_str, NULL, &res);
+    ret = rdma_getaddrinfo(rdma->host, port_str, NULL, &res);
     if (ret < 0) {
-        ERROR(errp, "could not getaddrinfo address %s", rdma->host);
+        ERROR(errp, "could not rdma_getaddrinfo address %s", rdma->host);
         goto err_resolve_get_addr;
     }
 
     for (e = res; e != NULL; e = e->ai_next) {
         inet_ntop(e->ai_family,
-            &((struct sockaddr_in *) e->ai_addr)->sin_addr, ip, sizeof ip);
+            &((struct sockaddr_in *) e->ai_dst_addr)->sin_addr, ip, sizeof ip);
         DPRINTF("Trying %s => %s\n", rdma->host, ip);
 
-        /* resolve the first address */
-        ret = rdma_resolve_addr(rdma->cm_id, NULL, e->ai_addr,
+        ret = rdma_resolve_addr(rdma->cm_id, NULL, e->ai_dst_addr,
                 RDMA_RESOLVE_TIMEOUT_MS);
         if (!ret) {
+            ret = qemu_rdma_broken_ipv6_kernel(errp, rdma->cm_id->verbs);
+            if (ret) {
+                continue;
+            }
             goto route;
         }
     }
@@ -803,6 +944,7 @@ route:
         ERROR(errp, "result not equal to event_addr_resolved %s",
                 rdma_event_str(cm_event->event));
         perror("rdma_resolve_addr");
+        ret = -EINVAL;
         goto err_resolve_get_addr;
     }
     rdma_ack_cm_event(cm_event);
@@ -823,6 +965,7 @@ route:
         ERROR(errp, "result not equal to event_route_resolved: %s",
                         rdma_event_str(cm_event->event));
         rdma_ack_cm_event(cm_event);
+        ret = -EINVAL;
         goto err_resolve_get_addr;
     }
     rdma_ack_cm_event(cm_event);
@@ -837,8 +980,7 @@ err_resolve_get_addr:
 err_resolve_create_id:
     rdma_destroy_event_channel(rdma->channel);
     rdma->channel = NULL;
-
-    return -1;
+    return ret;
 }
 
 /*
@@ -2266,7 +2408,7 @@ static int qemu_rdma_dest_init(RDMAContext *rdma, Error **errp)
     int ret = -EINVAL, idx;
     struct rdma_cm_id *listen_id;
     char ip[40] = "unknown";
-    struct addrinfo *res;
+    struct rdma_addrinfo *res;
     char port_str[16];
 
     for (idx = 0; idx < RDMA_WRID_MAX; idx++) {
@@ -2298,20 +2440,27 @@ static int qemu_rdma_dest_init(RDMAContext *rdma, Error **errp)
     port_str[15] = '\0';
 
     if (rdma->host && strcmp("", rdma->host)) {
-        struct addrinfo *e;
+        struct rdma_addrinfo *e;
 
-        ret = getaddrinfo(rdma->host, port_str, NULL, &res);
+        ret = rdma_getaddrinfo(rdma->host, port_str, NULL, &res);
         if (ret < 0) {
-            ERROR(errp, "could not getaddrinfo address %s", rdma->host);
+            ERROR(errp, "could not rdma_getaddrinfo address %s", rdma->host);
             goto err_dest_init_bind_addr;
         }
 
         for (e = res; e != NULL; e = e->ai_next) {
             inet_ntop(e->ai_family,
-                &((struct sockaddr_in *) e->ai_addr)->sin_addr, ip, sizeof ip);
+                &((struct sockaddr_in *) e->ai_dst_addr)->sin_addr, ip, sizeof ip);
             DPRINTF("Trying %s => %s\n", rdma->host, ip);
-            ret = rdma_bind_addr(listen_id, e->ai_addr);
+            ret = rdma_bind_addr(listen_id, e->ai_dst_addr);
             if (!ret) {
+                if (e->ai_family == AF_INET6) {
+                    ret = qemu_rdma_broken_ipv6_kernel(errp, listen_id->verbs);
+                    if (ret) {
+                        continue;
+                    }
+                }
+                    
                 goto listen;
             }
         }
commit 6470215b794d6d9f9ffbd82f669645715eb014f8
Author: Michael R. Hines <mrhines at us.ibm.com>
Date:   Fri Aug 9 16:05:43 2013 -0400

    rdma: proper getaddrinfo() handling
    
    getaddrinfo() already knows what it's doing,
    but it can potentially return multiple addresses.
    We need to handle that...
    
    Reviewed-by: Orit Wasserman <owasserm at redhat.com>
    Signed-off-by: Michael R. Hines <mrhines at us.ibm.com>
    Message-id: 1376078746-24948-5-git-send-email-mrhines at linux.vnet.ibm.com
    Signed-off-by: Anthony Liguori <aliguori at us.ibm.com>

diff --git a/migration-rdma.c b/migration-rdma.c
index 30e08cd..d71cca5 100644
--- a/migration-rdma.c
+++ b/migration-rdma.c
@@ -392,7 +392,6 @@ typedef struct RDMAContext {
     uint64_t unregistrations[RDMA_SIGNALED_SEND_MAX];
 
     GHashTable *blockmap;
-    bool ipv6;
 } RDMAContext;
 
 /*
@@ -745,7 +744,7 @@ static int qemu_rdma_resolve_host(RDMAContext *rdma, Error **errp)
     char port_str[16];
     struct rdma_cm_event *cm_event;
     char ip[40] = "unknown";
-    int af = rdma->ipv6 ? PF_INET6 : PF_INET;
+    struct addrinfo *e;
 
     if (rdma->host == NULL || !strcmp(rdma->host, "")) {
         ERROR(errp, "RDMA hostname has not been set");
@@ -775,18 +774,23 @@ static int qemu_rdma_resolve_host(RDMAContext *rdma, Error **errp)
         goto err_resolve_get_addr;
     }
 
-    inet_ntop(af, &((struct sockaddr_in *) res->ai_addr)->sin_addr,
-                                ip, sizeof ip);
-    DPRINTF("%s => %s\n", rdma->host, ip);
+    for (e = res; e != NULL; e = e->ai_next) {
+        inet_ntop(e->ai_family,
+            &((struct sockaddr_in *) e->ai_addr)->sin_addr, ip, sizeof ip);
+        DPRINTF("Trying %s => %s\n", rdma->host, ip);
 
-    /* resolve the first address */
-    ret = rdma_resolve_addr(rdma->cm_id, NULL, res->ai_addr,
-            RDMA_RESOLVE_TIMEOUT_MS);
-    if (ret) {
-        ERROR(errp, "could not resolve address %s", rdma->host);
-        goto err_resolve_get_addr;
+        /* resolve the first address */
+        ret = rdma_resolve_addr(rdma->cm_id, NULL, e->ai_addr,
+                RDMA_RESOLVE_TIMEOUT_MS);
+        if (!ret) {
+            goto route;
+        }
     }
 
+    ERROR(errp, "could not resolve address %s", rdma->host);
+    goto err_resolve_get_addr;
+
+route:
     qemu_rdma_dump_gid("source_resolve_addr", rdma->cm_id);
 
     ret = rdma_get_cm_event(rdma->channel, &cm_event);
@@ -2260,8 +2264,6 @@ err_rdma_source_connect:
 static int qemu_rdma_dest_init(RDMAContext *rdma, Error **errp)
 {
     int ret = -EINVAL, idx;
-    int af = rdma->ipv6 ? PF_INET6 : PF_INET;
-    struct sockaddr_in sin;
     struct rdma_cm_id *listen_id;
     char ip[40] = "unknown";
     struct addrinfo *res;
@@ -2292,35 +2294,36 @@ static int qemu_rdma_dest_init(RDMAContext *rdma, Error **errp)
         goto err_dest_init_create_listen_id;
     }
 
-    memset(&sin, 0, sizeof(sin));
-    sin.sin_family = af;
-    sin.sin_port = htons(rdma->port);
     snprintf(port_str, 16, "%d", rdma->port);
     port_str[15] = '\0';
 
     if (rdma->host && strcmp("", rdma->host)) {
+        struct addrinfo *e;
+
         ret = getaddrinfo(rdma->host, port_str, NULL, &res);
         if (ret < 0) {
             ERROR(errp, "could not getaddrinfo address %s", rdma->host);
             goto err_dest_init_bind_addr;
         }
 
+        for (e = res; e != NULL; e = e->ai_next) {
+            inet_ntop(e->ai_family,
+                &((struct sockaddr_in *) e->ai_addr)->sin_addr, ip, sizeof ip);
+            DPRINTF("Trying %s => %s\n", rdma->host, ip);
+            ret = rdma_bind_addr(listen_id, e->ai_addr);
+            if (!ret) {
+                goto listen;
+            }
+        }
 
-        inet_ntop(af, &((struct sockaddr_in *) res->ai_addr)->sin_addr,
-                                    ip, sizeof ip);
+        ERROR(errp, "Error: could not rdma_bind_addr!");
+        goto err_dest_init_bind_addr;
     } else {
         ERROR(errp, "migration host and port not specified!");
         ret = -EINVAL;
         goto err_dest_init_bind_addr;
     }
-
-    DPRINTF("%s => %s\n", rdma->host, ip);
-
-    ret = rdma_bind_addr(listen_id, res->ai_addr);
-    if (ret) {
-        ERROR(errp, "Error: could not rdma_bind_addr!");
-        goto err_dest_init_bind_addr;
-    }
+listen:
 
     rdma->listen_id = listen_id;
     qemu_rdma_dump_gid("dest_init", listen_id);
@@ -2351,7 +2354,6 @@ static void *qemu_rdma_data_init(const char *host_port, Error **errp)
         if (addr != NULL) {
             rdma->port = atoi(addr->port);
             rdma->host = g_strdup(addr->host);
-            rdma->ipv6 = addr->ipv6;
         } else {
             ERROR(errp, "bad RDMA migration address '%s'", host_port);
             g_free(rdma);
commit 88571882516a7cb4291a329c537eb79fd126e1f2
Author: Isaku Yamahata <yamahata at private.email.ne.jp>
Date:   Fri Aug 9 16:05:42 2013 -0400

    rdma: check if RDMAControlHeader::len match transferred byte
    
    RDMAControlHeader::len is provided from remote, so check if the value
    match the actual transferred byte_len.
    
    Reviewed-by: Orit Wasserman <owasserm at redhat.com>
    Reviewed-by: Michael R. Hines <mrhines at us.ibm.com>
    Signed-off-by: Isaku Yamahata <yamahata at private.email.ne.jp>
    Signed-off-by: Michael R. Hines <mrhines at us.ibm.com>
    Message-id: 1376078746-24948-4-git-send-email-mrhines at linux.vnet.ibm.com
    Signed-off-by: Anthony Liguori <aliguori at us.ibm.com>

diff --git a/migration-rdma.c b/migration-rdma.c
index ebe1f55..30e08cd 100644
--- a/migration-rdma.c
+++ b/migration-rdma.c
@@ -1214,7 +1214,8 @@ static void qemu_rdma_signal_unregister(RDMAContext *rdma, uint64_t index,
  * (of any kind) has completed.
  * Return the work request ID that completed.
  */
-static uint64_t qemu_rdma_poll(RDMAContext *rdma, uint64_t *wr_id_out)
+static uint64_t qemu_rdma_poll(RDMAContext *rdma, uint64_t *wr_id_out,
+                               uint32_t *byte_len)
 {
     int ret;
     struct ibv_wc wc;
@@ -1285,6 +1286,9 @@ static uint64_t qemu_rdma_poll(RDMAContext *rdma, uint64_t *wr_id_out)
     }
 
     *wr_id_out = wc.wr_id;
+    if (byte_len) {
+        *byte_len = wc.byte_len;
+    }
 
     return  0;
 }
@@ -1302,7 +1306,8 @@ static uint64_t qemu_rdma_poll(RDMAContext *rdma, uint64_t *wr_id_out)
  * completions only need to be recorded, but do not actually
  * need further processing.
  */
-static int qemu_rdma_block_for_wrid(RDMAContext *rdma, int wrid_requested)
+static int qemu_rdma_block_for_wrid(RDMAContext *rdma, int wrid_requested,
+                                    uint32_t *byte_len)
 {
     int num_cq_events = 0, ret = 0;
     struct ibv_cq *cq;
@@ -1314,7 +1319,7 @@ static int qemu_rdma_block_for_wrid(RDMAContext *rdma, int wrid_requested)
     }
     /* poll cq first */
     while (wr_id != wrid_requested) {
-        ret = qemu_rdma_poll(rdma, &wr_id_in);
+        ret = qemu_rdma_poll(rdma, &wr_id_in, byte_len);
         if (ret < 0) {
             return ret;
         }
@@ -1356,7 +1361,7 @@ static int qemu_rdma_block_for_wrid(RDMAContext *rdma, int wrid_requested)
         }
 
         while (wr_id != wrid_requested) {
-            ret = qemu_rdma_poll(rdma, &wr_id_in);
+            ret = qemu_rdma_poll(rdma, &wr_id_in, byte_len);
             if (ret < 0) {
                 goto err_block_for_wrid;
             }
@@ -1442,7 +1447,7 @@ static int qemu_rdma_post_send_control(RDMAContext *rdma, uint8_t *buf,
         return ret;
     }
 
-    ret = qemu_rdma_block_for_wrid(rdma, RDMA_WRID_SEND_CONTROL);
+    ret = qemu_rdma_block_for_wrid(rdma, RDMA_WRID_SEND_CONTROL, NULL);
     if (ret < 0) {
         fprintf(stderr, "rdma migration: send polling control error!\n");
     }
@@ -1483,7 +1488,9 @@ static int qemu_rdma_post_recv_control(RDMAContext *rdma, int idx)
 static int qemu_rdma_exchange_get_response(RDMAContext *rdma,
                 RDMAControlHeader *head, int expecting, int idx)
 {
-    int ret = qemu_rdma_block_for_wrid(rdma, RDMA_WRID_RECV_CONTROL + idx);
+    uint32_t byte_len;
+    int ret = qemu_rdma_block_for_wrid(rdma, RDMA_WRID_RECV_CONTROL + idx,
+                                       &byte_len);
 
     if (ret < 0) {
         fprintf(stderr, "rdma migration: recv polling control error!\n");
@@ -1509,6 +1516,11 @@ static int qemu_rdma_exchange_get_response(RDMAContext *rdma,
         fprintf(stderr, "too long length: %d\n", head->len);
         return -EINVAL;
     }
+    if (sizeof(*head) + head->len != byte_len) {
+        fprintf(stderr, "Malformed length: %d byte_len %d\n",
+                head->len, byte_len);
+        return -EINVAL;
+    }
 
     return 0;
 }
@@ -1738,7 +1750,7 @@ retry:
                 count++, current_index, chunk,
                 sge.addr, length, rdma->nb_sent, block->nb_chunks);
 
-        ret = qemu_rdma_block_for_wrid(rdma, RDMA_WRID_RDMA_WRITE);
+        ret = qemu_rdma_block_for_wrid(rdma, RDMA_WRID_RDMA_WRITE, NULL);
 
         if (ret < 0) {
             fprintf(stderr, "Failed to Wait for previous write to complete "
@@ -1882,7 +1894,7 @@ retry:
 
     if (ret == ENOMEM) {
         DDPRINTF("send queue is full. wait a little....\n");
-        ret = qemu_rdma_block_for_wrid(rdma, RDMA_WRID_RDMA_WRITE);
+        ret = qemu_rdma_block_for_wrid(rdma, RDMA_WRID_RDMA_WRITE, NULL);
         if (ret < 0) {
             fprintf(stderr, "rdma migration: failed to make "
                             "room in full send queue! %d\n", ret);
@@ -2471,7 +2483,7 @@ static int qemu_rdma_drain_cq(QEMUFile *f, RDMAContext *rdma)
     }
 
     while (rdma->nb_sent) {
-        ret = qemu_rdma_block_for_wrid(rdma, RDMA_WRID_RDMA_WRITE);
+        ret = qemu_rdma_block_for_wrid(rdma, RDMA_WRID_RDMA_WRITE, NULL);
         if (ret < 0) {
             fprintf(stderr, "rdma migration: complete polling error!\n");
             return -EIO;
@@ -2607,7 +2619,7 @@ static size_t qemu_rdma_save_page(QEMUFile *f, void *opaque,
      */
     while (1) {
         uint64_t wr_id, wr_id_in;
-        int ret = qemu_rdma_poll(rdma, &wr_id_in);
+        int ret = qemu_rdma_poll(rdma, &wr_id_in, NULL);
         if (ret < 0) {
             fprintf(stderr, "rdma migration: polling error! %d\n", ret);
             goto err;
commit 6f1484edadba57f2800dc04ae3527ee4b6dac7ef
Author: Isaku Yamahata <yamahata at private.email.ne.jp>
Date:   Fri Aug 9 16:05:41 2013 -0400

    rdma: validate RDMAControlHeader::len
    
    RMDAControlHeader::len is provided from remote, so validate it.
    
    Reviewed-by: Orit Wasserman <owasserm at redhat.com>
    Reviewed-by: Michael R. Hines <mrhines at us.ibm.com>
    Signed-off-by: Isaku Yamahata <yamahata at private.email.ne.jp>
    Signed-off-by: Michael R. Hines <mrhines at us.ibm.com>
    Message-id: 1376078746-24948-3-git-send-email-mrhines at linux.vnet.ibm.com
    Signed-off-by: Anthony Liguori <aliguori at us.ibm.com>

diff --git a/migration-rdma.c b/migration-rdma.c
index 6721266..ebe1f55 100644
--- a/migration-rdma.c
+++ b/migration-rdma.c
@@ -1424,6 +1424,7 @@ static int qemu_rdma_post_send_control(RDMAContext *rdma, uint8_t *buf,
      * The copy makes the RDMAControlHeader simpler to manipulate
      * for the time being.
      */
+    assert(head->len <= RDMA_CONTROL_MAX_BUFFER - sizeof(*head));
     memcpy(wr->control, head, sizeof(RDMAControlHeader));
     control_to_network((void *) wr->control);
 
@@ -1504,6 +1505,10 @@ static int qemu_rdma_exchange_get_response(RDMAContext *rdma,
                 control_desc[head->type], head->type, head->len);
         return -EIO;
     }
+    if (head->len > RDMA_CONTROL_MAX_BUFFER - sizeof(*head)) {
+        fprintf(stderr, "too long length: %d\n", head->len);
+        return -EINVAL;
+    }
 
     return 0;
 }
commit 885e8f984ea846e79a39ddc4f066f4dd3d04b264
Author: Isaku Yamahata <yamahata at private.email.ne.jp>
Date:   Fri Aug 9 16:05:40 2013 -0400

    rdma: use resp.len after validation in qemu_rdma_registration_stop
    
    resp.len is given from remote host. So should be validated before use.
    Otherwise memcpy can access beyond the buffer.
    
    Cc: Michael R. Hines <mrhines at us.ibm.com>
    Reviewed-by: Orit Wasserman <owasserm at redhat.com>
    Reviewed-by: Michael R. Hines <mrhines at us.ibm.com>
    Signed-off-by: Isaku Yamahata <yamahata at private.email.ne.jp>
    Signed-off-by: Michael R. Hines <mrhines at us.ibm.com>
    Message-id: 1376078746-24948-2-git-send-email-mrhines at linux.vnet.ibm.com
    Signed-off-by: Anthony Liguori <aliguori at us.ibm.com>

diff --git a/migration-rdma.c b/migration-rdma.c
index 3a380d4..6721266 100644
--- a/migration-rdma.c
+++ b/migration-rdma.c
@@ -3045,10 +3045,6 @@ static int qemu_rdma_registration_stop(QEMUFile *f, void *opaque,
             return ret;
         }
 
-        qemu_rdma_move_header(rdma, reg_result_idx, &resp);
-        memcpy(rdma->block,
-            rdma->wr_data[reg_result_idx].control_curr, resp.len);
-
         nb_remote_blocks = resp.len / sizeof(RDMARemoteBlock);
 
         /*
@@ -3070,6 +3066,9 @@ static int qemu_rdma_registration_stop(QEMUFile *f, void *opaque,
             return -EINVAL;
         }
 
+        qemu_rdma_move_header(rdma, reg_result_idx, &resp);
+        memcpy(rdma->block,
+            rdma->wr_data[reg_result_idx].control_curr, resp.len);
         for (i = 0; i < nb_remote_blocks; i++) {
             network_to_remote_block(&rdma->block[i]);
 
commit 6dd2a5c98a6b1c9189d342bcc3493c9b5dd1217e
Author: Paolo Bonzini <pbonzini at redhat.com>
Date:   Fri Aug 9 12:35:02 2013 -0500

    pc_sysfw: do not make it a device anymore
    
    Move the code to hw/i386, the sole remaining property is available
    as !pci_enabled.
    
    Signed-off-by: Paolo Bonzini <pbonzini at redhat.com>
    Signed-off-by: Markus Armbruster <armbru at redhat.com>
    Message-id: 1376069702-22330-4-git-send-email-aliguori at us.ibm.com
    
    Rebased.
    
    Signed-off-by: Markus Armbruster <armbru at redhat.com>
    Signed-off-by: Anthony Liguori <aliguori at us.ibm.com>

diff --git a/default-configs/i386-softmmu.mak b/default-configs/i386-softmmu.mak
index 4a0fc9c..37ef90f 100644
--- a/default-configs/i386-softmmu.mak
+++ b/default-configs/i386-softmmu.mak
@@ -33,7 +33,6 @@ CONFIG_MC146818RTC=y
 CONFIG_PAM=y
 CONFIG_PCI_PIIX=y
 CONFIG_WDT_IB700=y
-CONFIG_PC_SYSFW=y
 CONFIG_XEN_I386=$(CONFIG_XEN)
 CONFIG_ISA_DEBUG=y
 CONFIG_ISA_TESTDEV=y
diff --git a/default-configs/x86_64-softmmu.mak b/default-configs/x86_64-softmmu.mak
index 10bb0c6..31bddce 100644
--- a/default-configs/x86_64-softmmu.mak
+++ b/default-configs/x86_64-softmmu.mak
@@ -33,7 +33,6 @@ CONFIG_MC146818RTC=y
 CONFIG_PAM=y
 CONFIG_PCI_PIIX=y
 CONFIG_WDT_IB700=y
-CONFIG_PC_SYSFW=y
 CONFIG_XEN_I386=$(CONFIG_XEN)
 CONFIG_ISA_DEBUG=y
 CONFIG_ISA_TESTDEV=y
diff --git a/hw/block/Makefile.objs b/hw/block/Makefile.objs
index 25acc67..bf46f03 100644
--- a/hw/block/Makefile.objs
+++ b/hw/block/Makefile.objs
@@ -7,7 +7,6 @@ common-obj-$(CONFIG_PFLASH_CFI02) += pflash_cfi02.o
 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/pc_sysfw.c b/hw/block/pc_sysfw.c
deleted file mode 100644
index 1902cab..0000000
--- a/hw/block/pc_sysfw.c
+++ /dev/null
@@ -1,234 +0,0 @@
-/*
- * QEMU PC System Firmware
- *
- * Copyright (c) 2003-2004 Fabrice Bellard
- * Copyright (c) 2011-2012 Intel Corporation
- *
- * 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 "sysemu/blockdev.h"
-#include "qemu/error-report.h"
-#include "hw/sysbus.h"
-#include "hw/hw.h"
-#include "hw/i386/pc.h"
-#include "hw/boards.h"
-#include "hw/loader.h"
-#include "sysemu/sysemu.h"
-#include "hw/block/flash.h"
-#include "sysemu/kvm.h"
-
-#define BIOS_FILENAME "bios.bin"
-
-typedef struct PcSysFwDevice {
-    SysBusDevice busdev;
-    uint8_t isapc_ram_fw;
-} PcSysFwDevice;
-
-static void pc_isa_bios_init(MemoryRegion *rom_memory,
-                             MemoryRegion *flash_mem,
-                             int ram_size)
-{
-    int isa_bios_size;
-    MemoryRegion *isa_bios;
-    uint64_t flash_size;
-    void *flash_ptr, *isa_bios_ptr;
-
-    flash_size = memory_region_size(flash_mem);
-
-    /* map the last 128KB of the BIOS in ISA space */
-    isa_bios_size = flash_size;
-    if (isa_bios_size > (128 * 1024)) {
-        isa_bios_size = 128 * 1024;
-    }
-    isa_bios = g_malloc(sizeof(*isa_bios));
-    memory_region_init_ram(isa_bios, NULL, "isa-bios", isa_bios_size);
-    vmstate_register_ram_global(isa_bios);
-    memory_region_add_subregion_overlap(rom_memory,
-                                        0x100000 - isa_bios_size,
-                                        isa_bios,
-                                        1);
-
-    /* copy ISA rom image from top of flash memory */
-    flash_ptr = memory_region_get_ram_ptr(flash_mem);
-    isa_bios_ptr = memory_region_get_ram_ptr(isa_bios);
-    memcpy(isa_bios_ptr,
-           ((uint8_t*)flash_ptr) + (flash_size - isa_bios_size),
-           isa_bios_size);
-
-    memory_region_set_readonly(isa_bios, true);
-}
-
-static void pc_system_flash_init(MemoryRegion *rom_memory,
-                                 DriveInfo *pflash_drv)
-{
-    BlockDriverState *bdrv;
-    int64_t size;
-    hwaddr phys_addr;
-    int sector_bits, sector_size;
-    pflash_t *system_flash;
-    MemoryRegion *flash_mem;
-
-    bdrv = pflash_drv->bdrv;
-    size = bdrv_getlength(pflash_drv->bdrv);
-    sector_bits = 12;
-    sector_size = 1 << sector_bits;
-
-    if ((size % sector_size) != 0) {
-        fprintf(stderr,
-                "qemu: PC system firmware (pflash) must be a multiple of 0x%x\n",
-                sector_size);
-        exit(1);
-    }
-
-    phys_addr = 0x100000000ULL - size;
-    system_flash = pflash_cfi01_register(phys_addr, NULL, "system.flash", size,
-                                         bdrv, sector_size, size >> sector_bits,
-                                         1, 0x0000, 0x0000, 0x0000, 0x0000, 0);
-    flash_mem = pflash_cfi01_get_memory(system_flash);
-
-    pc_isa_bios_init(rom_memory, flash_mem, size);
-}
-
-static void old_pc_system_rom_init(MemoryRegion *rom_memory, bool isapc_ram_fw)
-{
-    char *filename;
-    MemoryRegion *bios, *isa_bios;
-    int bios_size, isa_bios_size;
-    int ret;
-
-    /* BIOS load */
-    if (bios_name == NULL) {
-        bios_name = BIOS_FILENAME;
-    }
-    filename = qemu_find_file(QEMU_FILE_TYPE_BIOS, bios_name);
-    if (filename) {
-        bios_size = get_image_size(filename);
-    } else {
-        bios_size = -1;
-    }
-    if (bios_size <= 0 ||
-        (bios_size % 65536) != 0) {
-        goto bios_error;
-    }
-    bios = g_malloc(sizeof(*bios));
-    memory_region_init_ram(bios, NULL, "pc.bios", bios_size);
-    vmstate_register_ram_global(bios);
-    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:
-        fprintf(stderr, "qemu: could not load PC BIOS '%s'\n", bios_name);
-        exit(1);
-    }
-    if (filename) {
-        g_free(filename);
-    }
-
-    /* map the last 128KB of the BIOS in ISA space */
-    isa_bios_size = bios_size;
-    if (isa_bios_size > (128 * 1024)) {
-        isa_bios_size = 128 * 1024;
-    }
-    isa_bios = g_malloc(sizeof(*isa_bios));
-    memory_region_init_alias(isa_bios, NULL, "isa-bios", bios,
-                             bios_size - isa_bios_size, isa_bios_size);
-    memory_region_add_subregion_overlap(rom_memory,
-                                        0x100000 - isa_bios_size,
-                                        isa_bios,
-                                        1);
-    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,
-                                (uint32_t)(-bios_size),
-                                bios);
-}
-
-void pc_system_firmware_init(MemoryRegion *rom_memory)
-{
-    DriveInfo *pflash_drv;
-    PcSysFwDevice *sysfw_dev;
-
-    /*
-     * TODO This device exists only so that users can switch between
-     * use of flash and ROM for the BIOS.  The ability to switch was
-     * created because flash doesn't work with KVM.  Once it does, we
-     * should drop this device.
-     */
-    sysfw_dev = (PcSysFwDevice*) qdev_create(NULL, "pc-sysfw");
-
-    qdev_init_nofail(DEVICE(sysfw_dev));
-
-    pflash_drv = drive_get(IF_PFLASH, 0, 0);
-
-    if (sysfw_dev->isapc_ram_fw || pflash_drv == NULL) {
-        /* When a pflash drive is not found, use rom-mode */
-        old_pc_system_rom_init(rom_memory, sysfw_dev->isapc_ram_fw);
-        return;
-    }
-
-    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);
-    }
-
-    pc_system_flash_init(rom_memory, pflash_drv);
-}
-
-static Property pcsysfw_properties[] = {
-    DEFINE_PROP_UINT8("isapc_ram_fw", PcSysFwDevice, isapc_ram_fw, 0),
-    DEFINE_PROP_END_OF_LIST(),
-};
-
-static int pcsysfw_init(DeviceState *dev)
-{
-    return 0;
-}
-
-static void pcsysfw_class_init (ObjectClass *klass, void *data)
-{
-    DeviceClass *dc = DEVICE_CLASS (klass);
-
-    set_bit(DEVICE_CATEGORY_STORAGE, dc->categories);
-    dc->desc = "PC System Firmware";
-    dc->init = pcsysfw_init;
-    dc->props = pcsysfw_properties;
-}
-
-static const TypeInfo pcsysfw_info = {
-    .name          = "pc-sysfw",
-    .parent        = TYPE_SYS_BUS_DEVICE,
-    .instance_size = sizeof (PcSysFwDevice),
-    .class_init    = pcsysfw_class_init,
-};
-
-static void pcsysfw_register (void)
-{
-    type_register_static (&pcsysfw_info);
-}
-
-type_init (pcsysfw_register);
-
diff --git a/hw/i386/Makefile.objs b/hw/i386/Makefile.objs
index 205d22e..45e6165 100644
--- a/hw/i386/Makefile.objs
+++ b/hw/i386/Makefile.objs
@@ -1,6 +1,7 @@
 obj-$(CONFIG_KVM) += kvm/
 obj-y += multiboot.o smbios.o
 obj-y += pc.o pc_piix.o pc_q35.o
+obj-y += pc_sysfw.o
 obj-$(CONFIG_XEN) += xen_domainbuild.o xen_machine_pv.o
 
 obj-y += kvmvapic.o
diff --git a/hw/i386/pc.c b/hw/i386/pc.c
index 6a0b042..e8bc8ce 100644
--- a/hw/i386/pc.c
+++ b/hw/i386/pc.c
@@ -1145,7 +1145,7 @@ FWCfgState *pc_memory_init(MemoryRegion *system_memory,
 
 
     /* Initialize PC system firmware */
-    pc_system_firmware_init(rom_memory);
+    pc_system_firmware_init(rom_memory, guest_info->isapc_ram_fw);
 
     option_rom_mr = g_malloc(sizeof(*option_rom_mr));
     memory_region_init_ram(option_rom_mr, NULL, "pc.rom", PC_ROM_SIZE);
diff --git a/hw/i386/pc_piix.c b/hw/i386/pc_piix.c
index cd88df9..a19e172 100644
--- a/hw/i386/pc_piix.c
+++ b/hw/i386/pc_piix.c
@@ -128,6 +128,7 @@ static void pc_init1(MemoryRegion *system_memory,
 
     guest_info = pc_guest_info_init(below_4g_mem_size, above_4g_mem_size);
     guest_info->has_pci_info = has_pci_info;
+    guest_info->isapc_ram_fw = !pci_enabled;
 
     /* allocate ram and load rom/bios */
     if (!xen_enabled()) {
@@ -742,11 +743,6 @@ static QEMUMachine isapc_machine = {
     .init = pc_init_isa,
     .max_cpus = 1,
     .compat_props = (GlobalProperty[]) {
-        {
-            .driver   = "pc-sysfw",
-            .property = "isapc_ram_fw",
-            .value    = stringify(1),
-        },
         { /* end of list */ }
     },
     DEFAULT_MACHINE_OPTIONS,
diff --git a/hw/i386/pc_q35.c b/hw/i386/pc_q35.c
index 6bfc2ca..be6013f 100644
--- a/hw/i386/pc_q35.c
+++ b/hw/i386/pc_q35.c
@@ -110,6 +110,7 @@ static void pc_q35_init(QEMUMachineInitArgs *args)
 
     guest_info = pc_guest_info_init(below_4g_mem_size, above_4g_mem_size);
     guest_info->has_pci_info = has_pci_info;
+    guest_info->isapc_ram_fw = false;
 
     /* allocate ram and load rom/bios */
     if (!xen_enabled()) {
diff --git a/hw/i386/pc_sysfw.c b/hw/i386/pc_sysfw.c
new file mode 100644
index 0000000..8246a1b
--- /dev/null
+++ b/hw/i386/pc_sysfw.c
@@ -0,0 +1,188 @@
+/*
+ * QEMU PC System Firmware
+ *
+ * Copyright (c) 2003-2004 Fabrice Bellard
+ * Copyright (c) 2011-2012 Intel Corporation
+ *
+ * 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 "sysemu/blockdev.h"
+#include "qemu/error-report.h"
+#include "hw/sysbus.h"
+#include "hw/hw.h"
+#include "hw/i386/pc.h"
+#include "hw/boards.h"
+#include "hw/loader.h"
+#include "sysemu/sysemu.h"
+#include "hw/block/flash.h"
+#include "sysemu/kvm.h"
+
+#define BIOS_FILENAME "bios.bin"
+
+typedef struct PcSysFwDevice {
+    SysBusDevice busdev;
+    uint8_t isapc_ram_fw;
+} PcSysFwDevice;
+
+static void pc_isa_bios_init(MemoryRegion *rom_memory,
+                             MemoryRegion *flash_mem,
+                             int ram_size)
+{
+    int isa_bios_size;
+    MemoryRegion *isa_bios;
+    uint64_t flash_size;
+    void *flash_ptr, *isa_bios_ptr;
+
+    flash_size = memory_region_size(flash_mem);
+
+    /* map the last 128KB of the BIOS in ISA space */
+    isa_bios_size = flash_size;
+    if (isa_bios_size > (128 * 1024)) {
+        isa_bios_size = 128 * 1024;
+    }
+    isa_bios = g_malloc(sizeof(*isa_bios));
+    memory_region_init_ram(isa_bios, NULL, "isa-bios", isa_bios_size);
+    vmstate_register_ram_global(isa_bios);
+    memory_region_add_subregion_overlap(rom_memory,
+                                        0x100000 - isa_bios_size,
+                                        isa_bios,
+                                        1);
+
+    /* copy ISA rom image from top of flash memory */
+    flash_ptr = memory_region_get_ram_ptr(flash_mem);
+    isa_bios_ptr = memory_region_get_ram_ptr(isa_bios);
+    memcpy(isa_bios_ptr,
+           ((uint8_t*)flash_ptr) + (flash_size - isa_bios_size),
+           isa_bios_size);
+
+    memory_region_set_readonly(isa_bios, true);
+}
+
+static void pc_system_flash_init(MemoryRegion *rom_memory,
+                                 DriveInfo *pflash_drv)
+{
+    BlockDriverState *bdrv;
+    int64_t size;
+    hwaddr phys_addr;
+    int sector_bits, sector_size;
+    pflash_t *system_flash;
+    MemoryRegion *flash_mem;
+
+    bdrv = pflash_drv->bdrv;
+    size = bdrv_getlength(pflash_drv->bdrv);
+    sector_bits = 12;
+    sector_size = 1 << sector_bits;
+
+    if ((size % sector_size) != 0) {
+        fprintf(stderr,
+                "qemu: PC system firmware (pflash) must be a multiple of 0x%x\n",
+                sector_size);
+        exit(1);
+    }
+
+    phys_addr = 0x100000000ULL - size;
+    system_flash = pflash_cfi01_register(phys_addr, NULL, "system.flash", size,
+                                         bdrv, sector_size, size >> sector_bits,
+                                         1, 0x0000, 0x0000, 0x0000, 0x0000, 0);
+    flash_mem = pflash_cfi01_get_memory(system_flash);
+
+    pc_isa_bios_init(rom_memory, flash_mem, size);
+}
+
+static void old_pc_system_rom_init(MemoryRegion *rom_memory, bool isapc_ram_fw)
+{
+    char *filename;
+    MemoryRegion *bios, *isa_bios;
+    int bios_size, isa_bios_size;
+    int ret;
+
+    /* BIOS load */
+    if (bios_name == NULL) {
+        bios_name = BIOS_FILENAME;
+    }
+    filename = qemu_find_file(QEMU_FILE_TYPE_BIOS, bios_name);
+    if (filename) {
+        bios_size = get_image_size(filename);
+    } else {
+        bios_size = -1;
+    }
+    if (bios_size <= 0 ||
+        (bios_size % 65536) != 0) {
+        goto bios_error;
+    }
+    bios = g_malloc(sizeof(*bios));
+    memory_region_init_ram(bios, NULL, "pc.bios", bios_size);
+    vmstate_register_ram_global(bios);
+    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:
+        fprintf(stderr, "qemu: could not load PC BIOS '%s'\n", bios_name);
+        exit(1);
+    }
+    if (filename) {
+        g_free(filename);
+    }
+
+    /* map the last 128KB of the BIOS in ISA space */
+    isa_bios_size = bios_size;
+    if (isa_bios_size > (128 * 1024)) {
+        isa_bios_size = 128 * 1024;
+    }
+    isa_bios = g_malloc(sizeof(*isa_bios));
+    memory_region_init_alias(isa_bios, NULL, "isa-bios", bios,
+                             bios_size - isa_bios_size, isa_bios_size);
+    memory_region_add_subregion_overlap(rom_memory,
+                                        0x100000 - isa_bios_size,
+                                        isa_bios,
+                                        1);
+    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,
+                                (uint32_t)(-bios_size),
+                                bios);
+}
+
+void pc_system_firmware_init(MemoryRegion *rom_memory, bool isapc_ram_fw)
+{
+    DriveInfo *pflash_drv;
+
+    pflash_drv = drive_get(IF_PFLASH, 0, 0);
+
+    if (isapc_ram_fw || pflash_drv == NULL) {
+        /* When a pflash drive is not found, use rom-mode */
+        old_pc_system_rom_init(rom_memory, isapc_ram_fw);
+        return;
+    }
+
+    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);
+    }
+
+    pc_system_flash_init(rom_memory, pflash_drv);
+}
diff --git a/include/hw/i386/pc.h b/include/hw/i386/pc.h
index 3a0c4e3..f79d478 100644
--- a/include/hw/i386/pc.h
+++ b/include/hw/i386/pc.h
@@ -19,6 +19,7 @@ typedef struct PcPciInfo {
 
 struct PcGuestInfo {
     bool has_pci_info;
+    bool isapc_ram_fw;
     FWCfgState *fw_cfg;
 };
 
@@ -200,7 +201,8 @@ static inline bool isa_ne2000_init(ISABus *bus, int base, int irq, NICInfo *nd)
 }
 
 /* pc_sysfw.c */
-void pc_system_firmware_init(MemoryRegion *rom_memory);
+void pc_system_firmware_init(MemoryRegion *rom_memory,
+                             bool isapc_ram_fw);
 
 /* pvpanic.c */
 void pvpanic_init(ISABus *bus);
commit a904410af5f1ed6ff031e9e4119ca2f5d99647ce
Author: Paolo Bonzini <pbonzini at redhat.com>
Date:   Fri Aug 9 12:35:01 2013 -0500

    pc_sysfw: remove the rom_only property
    
    With the new semantics of pc_sysfw (no -pflash implies "old-style" ROM setup,
    -pflash implies "new-style" ROM setup), there is no need anymore for a compat
    property.  Old machines simply will never use -pflash, and thus will always
    use old-style setup.
    
    Signed-off-by: Paolo Bonzini <pbonzini at redhat.com>
    Message-id: 1376069702-22330-3-git-send-email-aliguori at us.ibm.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 71ee631..1902cab 100644
--- a/hw/block/pc_sysfw.c
+++ b/hw/block/pc_sysfw.c
@@ -38,7 +38,6 @@
 
 typedef struct PcSysFwDevice {
     SysBusDevice busdev;
-    uint8_t rom_only;
     uint8_t isapc_ram_fw;
 } PcSysFwDevice;
 
@@ -76,39 +75,6 @@ static void pc_isa_bios_init(MemoryRegion *rom_memory,
     memory_region_set_readonly(isa_bios, true);
 }
 
-static void pc_fw_add_pflash_drv(void)
-{
-    QemuOpts *opts;
-    QEMUMachine *machine;
-    char *filename;
-
-    if (bios_name == NULL) {
-        bios_name = BIOS_FILENAME;
-    }
-    filename = qemu_find_file(QEMU_FILE_TYPE_BIOS, bios_name);
-    if (!filename) {
-        error_report("Can't open BIOS image %s", bios_name);
-        exit(1);
-    }
-
-    opts = drive_add(IF_PFLASH, -1, filename, "readonly=on");
-
-    g_free(filename);
-
-    if (opts == NULL) {
-      return;
-    }
-
-    machine = find_default_machine();
-    if (machine == NULL) {
-      return;
-    }
-
-    if (!drive_init(opts, machine->block_default_type)) {
-        qemu_opts_del(opts);
-    }
-}
-
 static void pc_system_flash_init(MemoryRegion *rom_memory,
                                  DriveInfo *pflash_drv)
 {
@@ -216,40 +182,24 @@ void pc_system_firmware_init(MemoryRegion *rom_memory)
 
     pflash_drv = drive_get(IF_PFLASH, 0, 0);
 
-    if (pflash_drv == NULL) {
+    if (sysfw_dev->isapc_ram_fw || 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
-       the bios filename. */
-    if (pflash_drv == NULL) {
-        pc_fw_add_pflash_drv();
-        pflash_drv = drive_get(IF_PFLASH, 0, 0);
-    }
-
-    if (pflash_drv != NULL) {
-        pc_system_flash_init(rom_memory, pflash_drv);
-    } else {
-        fprintf(stderr, "qemu: PC system firmware (pflash) not available\n");
+    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);
     }
+
+    pc_system_flash_init(rom_memory, pflash_drv);
 }
 
 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 95c45b8..cd88df9 100644
--- a/hw/i386/pc_piix.c
+++ b/hw/i386/pc_piix.c
@@ -496,10 +496,6 @@ static QEMUMachine pc_machine_v1_1 = {
 #define PC_COMPAT_1_0 \
         PC_COMPAT_1_1,\
         {\
-            .driver   = "pc-sysfw",\
-            .property = "rom_only",\
-            .value    = stringify(1),\
-        }, {\
             .driver   = TYPE_ISA_FDC,\
             .property = "check_media_rate",\
             .value    = "off",\
@@ -748,11 +744,6 @@ static QEMUMachine isapc_machine = {
     .compat_props = (GlobalProperty[]) {
         {
             .driver   = "pc-sysfw",
-            .property = "rom_only",
-            .value    = stringify(1),
-        },
-        {
-            .driver   = "pc-sysfw",
             .property = "isapc_ram_fw",
             .value    = stringify(1),
         },
commit 133bb095acf536f85e7e57821596c8c844aaa583
Author: Paolo Bonzini <pbonzini at redhat.com>
Date:   Fri Aug 9 12:35:00 2013 -0500

    sysfw: remove read-only pc_sysfw_flash_vs_rom_bug_compatible
    
    The variable is not written anymore.
    
    This cleans up after 9e1c2ec (which accidentally left variable
    pc_sysfw_flash_vs_rom_bug_compatible behind, value always zero), and
    buries dead code from commit dafb82e (which resurrected the pc_sysfw
    code for pc_sysfw_flash_vs_rom_bug_compatible by mistake).
    
    Signed-off-by: Paolo Bonzini <pbonzini at redhat.com>
    Message-id: 1376069702-22330-2-git-send-email-aliguori at us.ibm.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 7db68f0..71ee631 100644
--- a/hw/block/pc_sysfw.c
+++ b/hw/block/pc_sysfw.c
@@ -199,12 +199,6 @@ static void old_pc_system_rom_init(MemoryRegion *rom_memory, bool isapc_ram_fw)
                                 bios);
 }
 
-/*
- * Bug-compatible flash vs. ROM selection enabled?
- * A few older machines enable this.
- */
-bool pc_sysfw_flash_vs_rom_bug_compatible;
-
 void pc_system_firmware_init(MemoryRegion *rom_memory)
 {
     DriveInfo *pflash_drv;
@@ -222,25 +216,7 @@ void pc_system_firmware_init(MemoryRegion *rom_memory)
 
     pflash_drv = drive_get(IF_PFLASH, 0, 0);
 
-    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) {
+    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()) {
commit 0b516ef0dfad9a7b34c675c98e8ec92ab4d38466
Author: Stefan Weil <sw at weilnetz.de>
Date:   Thu Aug 8 20:18:07 2013 +0200

    w32: Add missing version.o to all executables (fix regression)
    
    QEMU executables for w32, w64 had included meta information built from
    version.rc. These rules were changed several times some months ago.
    
    The latest version added version.o to the tools, but not to the system
    emulations.
    
    This patch adds the meta information to all system emulations again.
    
    Signed-off-by: Stefan Weil <sw at weilnetz.de>
    Message-id: 1375985887-3984-1-git-send-email-sw at weilnetz.de
    Signed-off-by: Anthony Liguori <aliguori at us.ibm.com>

diff --git a/Makefile b/Makefile
index 29f1043..4d257f1 100644
--- a/Makefile
+++ b/Makefile
@@ -167,11 +167,8 @@ recurse-all: $(SUBDIR_RULES) $(ROMSUBDIR_RULES)
 
 bt-host.o: QEMU_CFLAGS += $(BLUEZ_CFLAGS)
 
-version.o: $(SRC_PATH)/version.rc config-host.h | version.lo
-version.lo: $(SRC_PATH)/version.rc config-host.h
-
-version-obj-$(CONFIG_WIN32) += version.o
-version-lobj-$(CONFIG_WIN32) += version.lo
+$(BUILD_DIR)/version.o: $(SRC_PATH)/version.rc $(BUILD_DIR)/config-host.h | $(BUILD_DIR)/version.lo
+$(BUILD_DIR)/version.lo: $(SRC_PATH)/version.rc $(BUILD_DIR)/config-host.h
 
 Makefile: $(version-obj-y) $(version-lobj-y)
 
diff --git a/Makefile.objs b/Makefile.objs
index 9928542..f46a4cd 100644
--- a/Makefile.objs
+++ b/Makefile.objs
@@ -99,6 +99,11 @@ common-obj-y += qom/
 common-obj-y += disas/
 
 ######################################################################
+# Resource file for Windows executables
+version-obj-$(CONFIG_WIN32) += $(BUILD_DIR)/version.o
+version-lobj-$(CONFIG_WIN32) += $(BUILD_DIR)/version.lo
+
+######################################################################
 # guest agent
 
 # FIXME: a few definitions from qapi-types.o/qapi-visit.o are needed
commit cb77d1925ac4d673e19be58aa39fc53c5d2fed10
Author: Markus Armbruster <armbru at redhat.com>
Date:   Fri Aug 2 09:34:00 2013 +0200

    qemu-option: Guard against qemu_opts_set_defaults() misuse
    
    Commit 6d4cd40 fixed qemu_opts_set_defaults() for an existing corner
    case, but broke it for another one that can't be reached in current
    code.
    
    Quote from its commit message:
    
        I believe [opts_parse()] attempts to do the following:
    
            If options don't yet exist, create new options
            Else, if defaults, modify the existing options
            Else, if list->merge_lists, modify the existing options
            Else, fail
    
    The only caller that passes true for defaults is
    qemu_opts_set_defaults().
    
    The commit message then claims:
    
        A straightforward call of qemu_opts_create() does exactly that.
    
    Wrong.  When !list->merge_lists, and the option string doesn't contain
    id=, and options without ID exist, then we don't actually modify the
    existing options, we create new ones.
    
    Not reachable, because we never pass lists with !list->merge_lists to
    qemu_opts_set_defaults().
    
    Guard against possible (if unlikely) future misuse with assert().
    
    Reported-by: Peter Maydell <peter.maydell at linaro.org>
    Signed-off-by: Markus Armbruster <armbru at redhat.com>
    Reviewed-by: Eric Blake <eblake at redhat.com>
    Message-id: 1375428840-5275-1-git-send-email-armbru at redhat.com
    Signed-off-by: Anthony Liguori <aliguori at us.ibm.com>

diff --git a/util/qemu-option.c b/util/qemu-option.c
index 7a1552a..4ebdc4c 100644
--- a/util/qemu-option.c
+++ b/util/qemu-option.c
@@ -928,6 +928,15 @@ static QemuOpts *opts_parse(QemuOptsList *list, const char *params,
         get_opt_value(value, sizeof(value), p+4);
         id = value;
     }
+
+    /*
+     * This code doesn't work for defaults && !list->merge_lists: when
+     * params has no id=, and list has an element with !opts->id, it
+     * appends a new element instead of returning the existing opts.
+     * However, we got no use for this case.  Guard against possible
+     * (if unlikely) future misuse:
+     */
+    assert(!defaults || list->merge_lists);
     opts = qemu_opts_create(list, id, !defaults, &local_err);
     if (opts == NULL) {
         if (error_is_set(&local_err)) {
commit 8571fa57cd0426f40629ab77444704745631f168
Author: Paolo Bonzini <pbonzini at redhat.com>
Date:   Wed Jul 31 08:19:52 2013 +0200

    LICENSE: clarify
    
    1) The GPL says that "if the Program does not specify a version number
    of this License, you may choose any version ever published by the Free
    Software Foundation".  This is not true, QEMU includes parts that are
    v2-only.
    
    2) Provide a default for files with no licensing information.
    
    3) It is not just hardware emulation that is under BSD license.
    
    4) Restrict GPLv2-only contributions to user mode emulation (due to
    code from Linux) and PCI passthrough (due to code from Neocleus).
    
    5) The rules were initially set by Fabrice but are being amended by
    other people (already in commit ee12e1f, LICENSE: There is no libqemu.a
    anymore, 2011-11-15).  Do not put words in his mouth.
    
    Signed-off-by: Paolo Bonzini <pbonzini at redhat.com>
    Acked-by: Andreas Färber <afaerber at suse.de>
    Message-id: 1375251592-2537-3-git-send-email-pbonzini at redhat.com
    Signed-off-by: Anthony Liguori <aliguori at us.ibm.com>

diff --git a/LICENSE b/LICENSE
index acae9a3..da70e94 100644
--- a/LICENSE
+++ b/LICENSE
@@ -1,16 +1,21 @@
 The following points clarify the QEMU license:
 
-1) QEMU as a whole is released under the GNU General Public License
+1) QEMU as a whole is released under the GNU General Public License,
+version 2.
 
 2) Parts of QEMU have specific licenses which are compatible with the
-GNU General Public License. Hence each source file contains its own
-licensing information.
+GNU General Public License, version 2. Hence each source file contains
+its own licensing information.  Source files with no licensing information
+are released under the GNU General Public License, version 2 or (at your
+option) any later version.
 
-Many hardware device emulation sources are released under the BSD license.
+As of July 2013, contributions under version 2 of the GNU General Public
+License (and no later version) are only accepted for the following files
+or directories: bsd-user/, linux-user/, hw/misc/vfio.c, hw/xen/xen_pt*.
 
 3) The Tiny Code Generator (TCG) is released under the BSD license
    (see license headers in files).
 
 4) QEMU is a trademark of Fabrice Bellard.
 
-Fabrice Bellard.
+Fabrice Bellard and the QEMU team
commit 7748c1bd50bd1b7f2b414acc2cf2e975be92deff
Author: Paolo Bonzini <pbonzini at redhat.com>
Date:   Wed Jul 31 08:19:51 2013 +0200

    raw: add license header
    
    Most of the block layer is under the BSD license, thus it is reasonable
    to license block/raw.c the same way.  CCed people should ACK by replying
    with a Signed-off-by line.
    
    Cc: Christoph Hellwig <hch at lst.de>
    Cc: Kevin Wolf <kwolf at redhat.com>
    Cc: Anthony Liguori <aliguori at us.ibm.com>
    Cc: Markus Armbruster <armbru at redhat.com>
    Cc: Stefan Hajnoczi <stefanha at redhat.com>
    Cc: Luiz Capitulino <lcapitulino at redhat.com>
    Cc: Jeff Cody <jcody at redhat.com>
    Cc: Peter Lieven <pl at kamp.de>
    Signed-off-by: Paolo Bonzini <pbonzini at redhat.com>
    Signed-off-by: Peter Lieven <pl at kamp.de>
    Signed-off-by: Kevin Wolf <kwolf at redhat.com>
    Signed-off-by: Jeff Cody <jcody at redhat.com>
    Signed-off-by: Luiz Capitulino <lcapitulino at redhat.com>
    Signed-off-by: Markus Armbruster <armbru at redhat.com>
    Signed-off-by: Stefan Hajnoczi <stefanha at redhat.com>
    Message-id: 1375251592-2537-2-git-send-email-pbonzini at redhat.com
    Signed-off-by: Anthony Liguori <aliguori at us.ibm.com>

diff --git a/block/raw.c b/block/raw.c
index f1682d4..4751825 100644
--- a/block/raw.c
+++ b/block/raw.c
@@ -1,3 +1,26 @@
+/*
+ * Block driver for RAW format
+ *
+ * Copyright (c) 2006 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 "qemu-common.h"
 #include "block/block_int.h"
commit 3ee1ee80d22b3153dd6cbd3bec6d48a026eac31c
Merge: 6624fec 3561ba1
Author: Anthony Liguori <aliguori at us.ibm.com>
Date:   Mon Aug 12 08:32:55 2013 -0500

    Merge remote-tracking branch 'mst/tags/for_anthony' into staging
    
    pci,virtio fixes for 1.6
    
    This includes some last-minute bugfixes for 1.6.
    All very small patches that also look very safe to me.
    
    Signed-off-by: Michael S. Tsirkin <mst at redhat.com>
    
    # gpg: Signature made Mon 12 Aug 2013 04:28:57 AM CDT using RSA key ID D28D5469
    # gpg: Can't check signature: public key not found
    
    # By Michael S. Tsirkin (2) and others
    # Via Michael S. Tsirkin
    * mst/tags/for_anthony:
      vhost: clear signalled_used_valid on vhost stop
      virtio: clear signalled_used_valid when switching from dataplane
      i82801b11: Fix i82801b11 PCI host bridge config space
      pc: disable pci-info for 1.6
    
    Message-id: 1376308831-19978-1-git-send-email-mst at redhat.com
    Signed-off-by: Anthony Liguori <aliguori at us.ibm.com>

commit 6624fecd8e4df6be13f86846abce979702917931
Merge: 3bba9c1 f7b803b
Author: Anthony Liguori <aliguori at us.ibm.com>
Date:   Mon Aug 12 08:32:43 2013 -0500

    Merge remote-tracking branch 'pmaydell/tags/pull-arm-devs-20130812' into staging
    
    arm-devs queue
    
    # gpg: Signature made Mon 12 Aug 2013 05:58:14 AM CDT using RSA key ID 14360CDE
    # gpg: Can't check signature: public key not found
    
    # By Peter Maydell
    # Via Peter Maydell
    * pmaydell/tags/pull-arm-devs-20130812:
      hw/virtio/virtio-mmio: Make QueueNumMax read 0 for unavailable queues
      hw/virtio/virtio: Don't allow guests to add/remove queues
    
    Message-id: 1376305261-29561-1-git-send-email-peter.maydell at linaro.org
    Signed-off-by: Anthony Liguori <aliguori at us.ibm.com>

commit 3bba9c115ba31f53fb9fc0a2711bf36c0ed6f031
Merge: 4a9a887 6db5f5d
Author: Anthony Liguori <aliguori at us.ibm.com>
Date:   Mon Aug 12 08:32:36 2013 -0500

    Merge remote-tracking branch 'kwolf/for-anthony' into staging
    
    # By Mike Qiu
    # Via Kevin Wolf
    * kwolf/for-anthony:
      block: Bugfix 'format' and 'snapshot' used in drive option
    
    Message-id: 1376071141-3214-1-git-send-email-kwolf at redhat.com
    Signed-off-by: Anthony Liguori <aliguori at us.ibm.com>

commit 4a9a8876a14653fd03918945dbb96de3e84b3e3f
Merge: 283c873 56c4bfb
Author: Anthony Liguori <aliguori at us.ibm.com>
Date:   Mon Aug 12 08:30:49 2013 -0500

    Merge remote-tracking branch 'luiz/queue/qmp' into staging
    
    # By Laszlo Ersek
    # Via Luiz Capitulino
    * luiz/queue/qmp:
      dump: rebase from host-private RAMBlock offsets to guest-physical addresses
      dump: populate guest_phys_blocks
      dump: introduce GuestPhysBlockList
      dump: clamp guest-provided mapping lengths to ramblock sizes
    
    Message-id: 1375974809-1757-1-git-send-email-lcapitulino at redhat.com
    Signed-off-by: Anthony Liguori <aliguori at us.ibm.com>

commit 283c8733b5a2e7ecd9a681656690ffef8dd675ae
Merge: 2aa09da dad5b9e
Author: Anthony Liguori <aliguori at us.ibm.com>
Date:   Mon Aug 12 08:30:39 2013 -0500

    Merge remote-tracking branch 'kraxel/usb.87' into staging
    
    # By Gerd Hoffmann
    # Via Gerd Hoffmann
    * kraxel/usb.87:
      xhci: implement warm port reset
    
    Message-id: 1375961495-20970-1-git-send-email-kraxel at redhat.com
    Signed-off-by: Anthony Liguori <aliguori at us.ibm.com>

commit 2aa09da823c258b3636d0e73527510cd196c68e4
Merge: 9b9734e 2e985fe
Author: Anthony Liguori <aliguori at us.ibm.com>
Date:   Mon Aug 12 08:28:56 2013 -0500

    Merge remote-tracking branch 'origin/master' into staging
    
    * origin/master:
      mips: revert commit b332d24a8e1290954029814d09156b06ede358e2
      tcg/mips: fix invalid op definition errors
    
    Necessary because patches got pushed by Aurelien before I pushed
    the -rc2 tag.
    
    Signed-off-by: Anthony Liguori <aliguori at us.ibm.com>

commit f7b803b377f74f7e109559e8e64f04c4c1fcd86b
Author: Peter Maydell <peter.maydell at linaro.org>
Date:   Fri Jul 26 16:41:28 2013 +0100

    hw/virtio/virtio-mmio: Make QueueNumMax read 0 for unavailable queues
    
    The virtio-mmio spec says that QueueNumMax must read zero for queues
    which are unavailable; implement this, rather than always returning
    VIRTQUEUE_MAX_SIZE.
    
    Signed-off-by: Peter Maydell <peter.maydell at linaro.org>
    Message-id: 1374853288-9912-3-git-send-email-peter.maydell at linaro.org
    Reviewed-by: Michael S. Tsirkin <mst at redhat.com>

diff --git a/hw/virtio/virtio-mmio.c b/hw/virtio/virtio-mmio.c
index 88cf994..4bd2953 100644
--- a/hw/virtio/virtio-mmio.c
+++ b/hw/virtio/virtio-mmio.c
@@ -151,6 +151,9 @@ static uint64_t virtio_mmio_read(void *opaque, hwaddr offset, unsigned size)
         }
         return proxy->host_features;
     case VIRTIO_MMIO_QUEUENUMMAX:
+        if (!virtio_queue_get_num(vdev, vdev->queue_sel)) {
+            return 0;
+        }
         return VIRTQUEUE_MAX_SIZE;
     case VIRTIO_MMIO_QUEUEPFN:
         return virtio_queue_get_addr(vdev, vdev->queue_sel)
commit 3561ba14188b3c1e54246ed6db97896bbc082d2f
Author: Michael S. Tsirkin <mst at redhat.com>
Date:   Mon Aug 12 12:21:36 2013 +0300

    vhost: clear signalled_used_valid on vhost stop
    
    When vhost device stops, its implementation synchronizes kernel state
    back to virtio.c so we can continue emulating the device
    in userspace.
    
    This patch ensures that virtio.c's signalled_used_valid flag is reset so
    that userspace does not suppress guest notifications due to stale
    signalled_used values.
    
    Cc: qemu-stable at nongnu.org
    Signed-off-by: Michael S. Tsirkin <mst at redhat.com>

diff --git a/hw/virtio/vhost.c b/hw/virtio/vhost.c
index 8f6ab13..9e336ad 100644
--- a/hw/virtio/vhost.c
+++ b/hw/virtio/vhost.c
@@ -762,6 +762,7 @@ static void vhost_virtqueue_stop(struct vhost_dev *dev,
         fflush(stderr);
     }
     virtio_queue_set_last_avail_idx(vdev, idx, state.num);
+    virtio_queue_invalidate_signalled_used(vdev, idx);
     assert (r >= 0);
     cpu_physical_memory_unmap(vq->ring, virtio_queue_get_ring_size(vdev, idx),
                               0, virtio_queue_get_ring_size(vdev, idx));
commit 6793dfd1b6a99a79b9f2e3c4d6625ccd6513f240
Author: Stefan Hajnoczi <stefanha at redhat.com>
Date:   Mon Aug 12 11:08:09 2013 +0200

    virtio: clear signalled_used_valid when switching from dataplane
    
    When the dataplane thread stops, its vring.c implementation synchronizes
    vring state back to virtio.c so we can continue emulating the virtio
    device.
    
    This patch ensures that virtio.c's signalled_used_valid flag is reset so
    that we do not suppress guest notifications due to stale signalled_used
    values.
    
    Suggested-by: Kevin Wolf <kwolf at redhat.com>
    Signed-off-by: Stefan Hajnoczi <stefanha at redhat.com>
    Signed-off-by: Michael S. Tsirkin <mst at redhat.com>

diff --git a/hw/virtio/dataplane/vring.c b/hw/virtio/dataplane/vring.c
index 82cc151..351a343 100644
--- a/hw/virtio/dataplane/vring.c
+++ b/hw/virtio/dataplane/vring.c
@@ -52,6 +52,7 @@ bool vring_setup(Vring *vring, VirtIODevice *vdev, int n)
 void vring_teardown(Vring *vring, VirtIODevice *vdev, int n)
 {
     virtio_queue_set_last_avail_idx(vdev, n, vring->last_avail_idx);
+    virtio_queue_invalidate_signalled_used(vdev, n);
 
     hostmem_finalize(&vring->hostmem);
 }
diff --git a/hw/virtio/virtio.c b/hw/virtio/virtio.c
index 09f62c6..706bdf4 100644
--- a/hw/virtio/virtio.c
+++ b/hw/virtio/virtio.c
@@ -1059,6 +1059,11 @@ void virtio_queue_set_last_avail_idx(VirtIODevice *vdev, int n, uint16_t idx)
     vdev->vq[n].last_avail_idx = idx;
 }
 
+void virtio_queue_invalidate_signalled_used(VirtIODevice *vdev, int n)
+{
+    vdev->vq[n].signalled_used_valid = false;
+}
+
 VirtQueue *virtio_get_queue(VirtIODevice *vdev, int n)
 {
     return vdev->vq + n;
diff --git a/include/hw/virtio/virtio.h b/include/hw/virtio/virtio.h
index d7e9e0f..a90522d 100644
--- a/include/hw/virtio/virtio.h
+++ b/include/hw/virtio/virtio.h
@@ -237,6 +237,7 @@ hwaddr virtio_queue_get_used_size(VirtIODevice *vdev, int n);
 hwaddr virtio_queue_get_ring_size(VirtIODevice *vdev, int n);
 uint16_t virtio_queue_get_last_avail_idx(VirtIODevice *vdev, int n);
 void virtio_queue_set_last_avail_idx(VirtIODevice *vdev, int n, uint16_t idx);
+void virtio_queue_invalidate_signalled_used(VirtIODevice *vdev, int n);
 VirtQueue *virtio_get_queue(VirtIODevice *vdev, int n);
 uint16_t virtio_get_queue_index(VirtQueue *vq);
 int virtio_queue_get_id(VirtQueue *vq);
commit 4965b7f056177ddfb816319e9ff5e766898d0bc5
Author: Gerd Hoffmann <kraxel at redhat.com>
Date:   Mon Aug 5 16:36:40 2013 +0200

    i82801b11: Fix i82801b11 PCI host bridge config space
    
    pci_bridge_write_config() was not being used.
    
    Cc: qemu-stable at nongnu.org
    Signed-off-by: Gerd Hoffmann <kraxel at redhat.com>
    Signed-off-by: Andreas Färber <afaerber at suse.de>
    Signed-off-by: Michael S. Tsirkin <mst at redhat.com>

diff --git a/hw/pci-bridge/i82801b11.c b/hw/pci-bridge/i82801b11.c
index 8a5e426..14cd7fd 100644
--- a/hw/pci-bridge/i82801b11.c
+++ b/hw/pci-bridge/i82801b11.c
@@ -90,6 +90,7 @@ static void i82801b11_bridge_class_init(ObjectClass *klass, void *data)
     k->device_id = PCI_DEVICE_ID_INTEL_82801BA_11;
     k->revision = ICH9_D2P_A2_REVISION;
     k->init = i82801b11_bridge_initfn;
+    k->config_write = pci_bridge_write_config;
     set_bit(DEVICE_CATEGORY_BRIDGE, dc->categories);
 }
 
commit 9604f70fdf8e21ec0dbf6eac5e59a0eb8beadd64
Author: Michael S. Tsirkin <mst at redhat.com>
Date:   Thu Aug 1 15:39:11 2013 +0300

    pc: disable pci-info for 1.6
    
    The BIOS that we ship in 1.6 does not use pci info
    from host (yet). Several issues turned up
    (e.g. around winXP boot crashes). So it's safest to disable that
    interface for 1.6 machine types for now, leave it on for 1.7
    as we have enough time to fix issues if any.
    
    Reviewed-by: Richard Henderson <rth at twiddle.net>
    Reviewed-by: Andreas Färber <afaerber at suse.de>
    Signed-off-by: Michael S. Tsirkin <mst at redhat.com>

diff --git a/hw/i386/pc_piix.c b/hw/i386/pc_piix.c
index ab25458..95c45b8 100644
--- a/hw/i386/pc_piix.c
+++ b/hw/i386/pc_piix.c
@@ -249,12 +249,17 @@ static void pc_init_pci(QEMUMachineInitArgs *args)
              initrd_filename, cpu_model, 1, 1);
 }
 
-static void pc_init_pci_1_5(QEMUMachineInitArgs *args)
+static void pc_init_pci_1_6(QEMUMachineInitArgs *args)
 {
     has_pci_info = false;
     pc_init_pci(args);
 }
 
+static void pc_init_pci_1_5(QEMUMachineInitArgs *args)
+{
+    pc_init_pci_1_6(args);
+}
+
 static void pc_init_pci_1_4(QEMUMachineInitArgs *args)
 {
     has_pvpanic = false;
@@ -340,7 +345,7 @@ static QEMUMachine pc_i440fx_machine_v1_6 = {
     .name = "pc-i440fx-1.6",
     .alias = "pc",
     .desc = "Standard PC (i440FX + PIIX, 1996)",
-    .init = pc_init_pci,
+    .init = pc_init_pci_1_6,
     .hot_add_cpu = pc_hot_add_cpu,
     .max_cpus = 255,
     .is_default = 1,
diff --git a/hw/i386/pc_q35.c b/hw/i386/pc_q35.c
index 2f35d12..6bfc2ca 100644
--- a/hw/i386/pc_q35.c
+++ b/hw/i386/pc_q35.c
@@ -217,12 +217,17 @@ static void pc_q35_init(QEMUMachineInitArgs *args)
     }
 }
 
-static void pc_q35_init_1_5(QEMUMachineInitArgs *args)
+static void pc_q35_init_1_6(QEMUMachineInitArgs *args)
 {
     has_pci_info = false;
     pc_q35_init(args);
 }
 
+static void pc_q35_init_1_5(QEMUMachineInitArgs *args)
+{
+    pc_q35_init_1_6(args);
+}
+
 static void pc_q35_init_1_4(QEMUMachineInitArgs *args)
 {
     has_pvpanic = false;
@@ -234,7 +239,7 @@ static QEMUMachine pc_q35_machine_v1_6 = {
     .name = "pc-q35-1.6",
     .alias = "q35",
     .desc = "Standard PC (Q35 + ICH9, 2009)",
-    .init = pc_q35_init,
+    .init = pc_q35_init_1_6,
     .hot_add_cpu = pc_hot_add_cpu,
     .max_cpus = 255,
     DEFAULT_MACHINE_OPTIONS,
commit ca916d3729564d0eb3c2374a96903f7e8aced8a7
Author: Vincenzo Maffione <v.maffione at gmail.com>
Date:   Mon Jul 22 11:51:33 2013 +0200

    kvm: add KVM_IRQFD_FLAG_RESAMPLE support
    
    Added an EventNotifier* parameter to
    kvm-all.c:kvm_irqchip_add_irqfd_notifier(), in order to give KVM
    another eventfd to be used as "resamplefd". See the documentation
    in the linux kernel sources in Documentation/virtual/kvm/api.txt
    (section 4.75) for more details.
    When the added parameter is passed NULL, the behaviour of the
    function is unchanged with respect to the previous versions.
    
    Reviewed-by: Paolo Bonzini <pbonzini at redhat.com>
    Signed-off-by: Vincenzo Maffione <v.maffione at gmail.com>
    Signed-off-by: Paolo Bonzini <pbonzini at redhat.com>

diff --git a/hw/misc/vfio.c b/hw/misc/vfio.c
index ad8ce77..54af34a 100644
--- a/hw/misc/vfio.c
+++ b/hw/misc/vfio.c
@@ -646,7 +646,7 @@ static int vfio_msix_vector_do_use(PCIDevice *pdev, unsigned int nr,
     vector->virq = msg ? kvm_irqchip_add_msi_route(kvm_state, *msg) : -1;
     if (vector->virq < 0 ||
         kvm_irqchip_add_irqfd_notifier(kvm_state, &vector->interrupt,
-                                       vector->virq) < 0) {
+                                       NULL, vector->virq) < 0) {
         if (vector->virq >= 0) {
             kvm_irqchip_release_virq(kvm_state, vector->virq);
             vector->virq = -1;
@@ -814,7 +814,7 @@ retry:
         vector->virq = kvm_irqchip_add_msi_route(kvm_state, msg);
         if (vector->virq < 0 ||
             kvm_irqchip_add_irqfd_notifier(kvm_state, &vector->interrupt,
-                                           vector->virq) < 0) {
+                                           NULL, vector->virq) < 0) {
             qemu_set_fd_handler(event_notifier_get_fd(&vector->interrupt),
                                 vfio_msi_interrupt, NULL, vector);
         }
diff --git a/hw/virtio/virtio-pci.c b/hw/virtio/virtio-pci.c
index c38cfd1..c4db407 100644
--- a/hw/virtio/virtio-pci.c
+++ b/hw/virtio/virtio-pci.c
@@ -508,7 +508,7 @@ static int kvm_virtio_pci_irqfd_use(VirtIOPCIProxy *proxy,
     VirtQueue *vq = virtio_get_queue(proxy->vdev, queue_no);
     EventNotifier *n = virtio_queue_get_guest_notifier(vq);
     int ret;
-    ret = kvm_irqchip_add_irqfd_notifier(kvm_state, n, irqfd->virq);
+    ret = kvm_irqchip_add_irqfd_notifier(kvm_state, n, NULL, irqfd->virq);
     return ret;
 }
 
diff --git a/include/sysemu/kvm.h b/include/sysemu/kvm.h
index f8ac448..ce3efaf 100644
--- a/include/sysemu/kvm.h
+++ b/include/sysemu/kvm.h
@@ -309,7 +309,8 @@ int kvm_irqchip_add_msi_route(KVMState *s, MSIMessage msg);
 int kvm_irqchip_update_msi_route(KVMState *s, int virq, MSIMessage msg);
 void kvm_irqchip_release_virq(KVMState *s, int virq);
 
-int kvm_irqchip_add_irqfd_notifier(KVMState *s, EventNotifier *n, int virq);
+int kvm_irqchip_add_irqfd_notifier(KVMState *s, EventNotifier *n,
+                                   EventNotifier *rn, int virq);
 int kvm_irqchip_remove_irqfd_notifier(KVMState *s, EventNotifier *n, int virq);
 void kvm_pc_gsi_handler(void *opaque, int n, int level);
 void kvm_pc_setup_irq_routing(bool pci_enabled);
diff --git a/kvm-all.c b/kvm-all.c
index 4fb4ccb..bfa4aac 100644
--- a/kvm-all.c
+++ b/kvm-all.c
@@ -1230,7 +1230,8 @@ int kvm_irqchip_update_msi_route(KVMState *s, int virq, MSIMessage msg)
     return kvm_update_routing_entry(s, &kroute);
 }
 
-static int kvm_irqchip_assign_irqfd(KVMState *s, int fd, int virq, bool assign)
+static int kvm_irqchip_assign_irqfd(KVMState *s, int fd, int rfd, int virq,
+                                    bool assign)
 {
     struct kvm_irqfd irqfd = {
         .fd = fd,
@@ -1238,6 +1239,11 @@ static int kvm_irqchip_assign_irqfd(KVMState *s, int fd, int virq, bool assign)
         .flags = assign ? 0 : KVM_IRQFD_FLAG_DEASSIGN,
     };
 
+    if (rfd != -1) {
+        irqfd.flags |= KVM_IRQFD_FLAG_RESAMPLE;
+        irqfd.resamplefd = rfd;
+    }
+
     if (!kvm_irqfds_enabled()) {
         return -ENOSYS;
     }
@@ -1276,14 +1282,17 @@ int kvm_irqchip_update_msi_route(KVMState *s, int virq, MSIMessage msg)
 }
 #endif /* !KVM_CAP_IRQ_ROUTING */
 
-int kvm_irqchip_add_irqfd_notifier(KVMState *s, EventNotifier *n, int virq)
+int kvm_irqchip_add_irqfd_notifier(KVMState *s, EventNotifier *n,
+                                   EventNotifier *rn, int virq)
 {
-    return kvm_irqchip_assign_irqfd(s, event_notifier_get_fd(n), virq, true);
+    return kvm_irqchip_assign_irqfd(s, event_notifier_get_fd(n),
+           rn ? event_notifier_get_fd(rn) : -1, virq, true);
 }
 
 int kvm_irqchip_remove_irqfd_notifier(KVMState *s, EventNotifier *n, int virq)
 {
-    return kvm_irqchip_assign_irqfd(s, event_notifier_get_fd(n), virq, false);
+    return kvm_irqchip_assign_irqfd(s, event_notifier_get_fd(n), -1, virq,
+           false);
 }
 
 static int kvm_irqchip_create(KVMState *s)
commit 0d89436786b02a9e7d561c4d7dc4982e4a2739db
Author: Paolo Bonzini <pbonzini at redhat.com>
Date:   Thu Jul 25 17:05:22 2013 +0200

    kvm: migrate vPMU state
    
    Reviewed-by: Gleb Natapov <gnatapov at redhat.com>
    Signed-off-by: Paolo Bonzini <pbonzini at redhat.com>

diff --git a/target-i386/cpu.h b/target-i386/cpu.h
index af4c0f7..31de265 100644
--- a/target-i386/cpu.h
+++ b/target-i386/cpu.h
@@ -305,6 +305,8 @@
 #define MSR_TSC_ADJUST                  0x0000003b
 #define MSR_IA32_TSCDEADLINE            0x6e0
 
+#define MSR_P6_PERFCTR0                 0xc1
+
 #define MSR_MTRRcap                     0xfe
 #define MSR_MTRRcap_VCNT                8
 #define MSR_MTRRcap_FIXRANGE_SUPPORT    (1 << 8)
@@ -318,6 +320,8 @@
 #define MSR_MCG_STATUS                  0x17a
 #define MSR_MCG_CTL                     0x17b
 
+#define MSR_P6_EVNTSEL0                 0x186
+
 #define MSR_IA32_PERF_STATUS            0x198
 
 #define MSR_IA32_MISC_ENABLE            0x1a0
@@ -343,6 +347,14 @@
 
 #define MSR_MTRRdefType                 0x2ff
 
+#define MSR_CORE_PERF_FIXED_CTR0        0x309
+#define MSR_CORE_PERF_FIXED_CTR1        0x30a
+#define MSR_CORE_PERF_FIXED_CTR2        0x30b
+#define MSR_CORE_PERF_FIXED_CTR_CTRL    0x38d
+#define MSR_CORE_PERF_GLOBAL_STATUS     0x38e
+#define MSR_CORE_PERF_GLOBAL_CTRL       0x38f
+#define MSR_CORE_PERF_GLOBAL_OVF_CTRL   0x390
+
 #define MSR_MC0_CTL                     0x400
 #define MSR_MC0_STATUS                  0x401
 #define MSR_MC0_ADDR                    0x402
@@ -721,6 +733,9 @@ typedef struct {
 #define CPU_NB_REGS CPU_NB_REGS32
 #endif
 
+#define MAX_FIXED_COUNTERS 3
+#define MAX_GP_COUNTERS    (MSR_IA32_PERF_STATUS - MSR_P6_EVNTSEL0)
+
 #define NB_MMU_MODES 3
 
 typedef enum TPRAccess {
@@ -816,6 +831,14 @@ typedef struct CPUX86State {
     uint64_t msr_ia32_misc_enable;
     uint64_t msr_ia32_feature_control;
 
+    uint64_t msr_fixed_ctr_ctrl;
+    uint64_t msr_global_ctrl;
+    uint64_t msr_global_status;
+    uint64_t msr_global_ovf_ctrl;
+    uint64_t msr_fixed_counters[MAX_FIXED_COUNTERS];
+    uint64_t msr_gp_counters[MAX_GP_COUNTERS];
+    uint64_t msr_gp_evtsel[MAX_GP_COUNTERS];
+
     /* exception/interrupt handling */
     int error_code;
     int exception_is_int;
diff --git a/target-i386/kvm.c b/target-i386/kvm.c
index 84ac00a..513ae52 100644
--- a/target-i386/kvm.c
+++ b/target-i386/kvm.c
@@ -71,6 +71,9 @@ static bool has_msr_misc_enable;
 static bool has_msr_kvm_steal_time;
 static int lm_capable_kernel;
 
+static bool has_msr_architectural_pmu;
+static uint32_t num_architectural_pmu_counters;
+
 bool kvm_allows_irq0_override(void)
 {
     return !kvm_irqchip_in_kernel() || kvm_has_gsi_routing();
@@ -581,6 +584,25 @@ int kvm_arch_init_vcpu(CPUState *cs)
             break;
         }
     }
+
+    if (limit >= 0x0a) {
+        uint32_t ver;
+
+        cpu_x86_cpuid(env, 0x0a, 0, &ver, &unused, &unused, &unused);
+        if ((ver & 0xff) > 0) {
+            has_msr_architectural_pmu = true;
+            num_architectural_pmu_counters = (ver & 0xff00) >> 8;
+
+            /* Shouldn't be more than 32, since that's the number of bits
+             * available in EBX to tell us _which_ counters are available.
+             * Play it safe.
+             */
+            if (num_architectural_pmu_counters > MAX_GP_COUNTERS) {
+                num_architectural_pmu_counters = MAX_GP_COUNTERS;
+            }
+        }
+    }
+
     cpu_x86_cpuid(env, 0x80000000, 0, &limit, &unused, &unused, &unused);
 
     for (i = 0x80000000; i <= limit; i++) {
@@ -1052,7 +1074,7 @@ static int kvm_put_msrs(X86CPU *cpu, int level)
         struct kvm_msr_entry entries[100];
     } msr_data;
     struct kvm_msr_entry *msrs = msr_data.entries;
-    int n = 0;
+    int n = 0, i;
 
     kvm_msr_entry_set(&msrs[n++], MSR_IA32_SYSENTER_CS, env->sysenter_cs);
     kvm_msr_entry_set(&msrs[n++], MSR_IA32_SYSENTER_ESP, env->sysenter_esp);
@@ -1094,9 +1116,8 @@ static int kvm_put_msrs(X86CPU *cpu, int level)
         }
     }
     /*
-     * The following paravirtual MSRs have side effects on the guest or are
-     * too heavy for normal writeback. Limit them to reset or full state
-     * updates.
+     * The following MSRs have side effects on the guest or are too heavy
+     * for normal writeback. Limit them to reset or full state updates.
      */
     if (level >= KVM_PUT_RESET_STATE) {
         kvm_msr_entry_set(&msrs[n++], MSR_KVM_SYSTEM_TIME,
@@ -1114,6 +1135,33 @@ static int kvm_put_msrs(X86CPU *cpu, int level)
             kvm_msr_entry_set(&msrs[n++], MSR_KVM_STEAL_TIME,
                               env->steal_time_msr);
         }
+        if (has_msr_architectural_pmu) {
+            /* Stop the counter.  */
+            kvm_msr_entry_set(&msrs[n++], MSR_CORE_PERF_FIXED_CTR_CTRL, 0);
+            kvm_msr_entry_set(&msrs[n++], MSR_CORE_PERF_GLOBAL_CTRL, 0);
+
+            /* Set the counter values.  */
+            for (i = 0; i < MAX_FIXED_COUNTERS; i++) {
+                kvm_msr_entry_set(&msrs[n++], MSR_CORE_PERF_FIXED_CTR0 + i,
+                                  env->msr_fixed_counters[i]);
+            }
+            for (i = 0; i < num_architectural_pmu_counters; i++) {
+                kvm_msr_entry_set(&msrs[n++], MSR_P6_PERFCTR0 + i,
+                                  env->msr_gp_counters[i]);
+                kvm_msr_entry_set(&msrs[n++], MSR_P6_EVNTSEL0 + i,
+                                  env->msr_gp_evtsel[i]);
+            }
+            kvm_msr_entry_set(&msrs[n++], MSR_CORE_PERF_GLOBAL_STATUS,
+                              env->msr_global_status);
+            kvm_msr_entry_set(&msrs[n++], MSR_CORE_PERF_GLOBAL_OVF_CTRL,
+                              env->msr_global_ovf_ctrl);
+
+            /* Now start the PMU.  */
+            kvm_msr_entry_set(&msrs[n++], MSR_CORE_PERF_FIXED_CTR_CTRL,
+                              env->msr_fixed_ctr_ctrl);
+            kvm_msr_entry_set(&msrs[n++], MSR_CORE_PERF_GLOBAL_CTRL,
+                              env->msr_global_ctrl);
+        }
         if (hyperv_hypercall_available()) {
             kvm_msr_entry_set(&msrs[n++], HV_X64_MSR_GUEST_OS_ID, 0);
             kvm_msr_entry_set(&msrs[n++], HV_X64_MSR_HYPERCALL, 0);
@@ -1372,6 +1420,19 @@ static int kvm_get_msrs(X86CPU *cpu)
     if (has_msr_kvm_steal_time) {
         msrs[n++].index = MSR_KVM_STEAL_TIME;
     }
+    if (has_msr_architectural_pmu) {
+        msrs[n++].index = MSR_CORE_PERF_FIXED_CTR_CTRL;
+        msrs[n++].index = MSR_CORE_PERF_GLOBAL_CTRL;
+        msrs[n++].index = MSR_CORE_PERF_GLOBAL_STATUS;
+        msrs[n++].index = MSR_CORE_PERF_GLOBAL_OVF_CTRL;
+        for (i = 0; i < MAX_FIXED_COUNTERS; i++) {
+            msrs[n++].index = MSR_CORE_PERF_FIXED_CTR0 + i;
+        }
+        for (i = 0; i < num_architectural_pmu_counters; i++) {
+            msrs[n++].index = MSR_P6_PERFCTR0 + i;
+            msrs[n++].index = MSR_P6_EVNTSEL0 + i;
+        }
+    }
 
     if (env->mcg_cap) {
         msrs[n++].index = MSR_MCG_STATUS;
@@ -1388,7 +1449,8 @@ static int kvm_get_msrs(X86CPU *cpu)
     }
 
     for (i = 0; i < ret; i++) {
-        switch (msrs[i].index) {
+        uint32_t index = msrs[i].index;
+        switch (index) {
         case MSR_IA32_SYSENTER_CS:
             env->sysenter_cs = msrs[i].data;
             break;
@@ -1462,6 +1524,27 @@ static int kvm_get_msrs(X86CPU *cpu)
         case MSR_KVM_STEAL_TIME:
             env->steal_time_msr = msrs[i].data;
             break;
+        case MSR_CORE_PERF_FIXED_CTR_CTRL:
+            env->msr_fixed_ctr_ctrl = msrs[i].data;
+            break;
+        case MSR_CORE_PERF_GLOBAL_CTRL:
+            env->msr_global_ctrl = msrs[i].data;
+            break;
+        case MSR_CORE_PERF_GLOBAL_STATUS:
+            env->msr_global_status = msrs[i].data;
+            break;
+        case MSR_CORE_PERF_GLOBAL_OVF_CTRL:
+            env->msr_global_ovf_ctrl = msrs[i].data;
+            break;
+        case MSR_CORE_PERF_FIXED_CTR0 ... MSR_CORE_PERF_FIXED_CTR0 + MAX_FIXED_COUNTERS - 1:
+            env->msr_fixed_counters[index - MSR_CORE_PERF_FIXED_CTR0] = msrs[i].data;
+            break;
+        case MSR_P6_PERFCTR0 ... MSR_P6_PERFCTR0 + MAX_GP_COUNTERS - 1:
+            env->msr_gp_counters[index - MSR_P6_PERFCTR0] = msrs[i].data;
+            break;
+        case MSR_P6_EVNTSEL0 ... MSR_P6_EVNTSEL0 + MAX_GP_COUNTERS - 1:
+            env->msr_gp_evtsel[index - MSR_P6_EVNTSEL0] = msrs[i].data;
+            break;
         }
     }
 
diff --git a/target-i386/machine.c b/target-i386/machine.c
index 0d2088e..dc81cde 100644
--- a/target-i386/machine.c
+++ b/target-i386/machine.c
@@ -465,6 +465,47 @@ static const VMStateDescription vmstate_msr_ia32_feature_control = {
     }
 };
 
+static bool pmu_enable_needed(void *opaque)
+{
+    X86CPU *cpu = opaque;
+    CPUX86State *env = &cpu->env;
+    int i;
+
+    if (env->msr_fixed_ctr_ctrl || env->msr_global_ctrl ||
+        env->msr_global_status || env->msr_global_ovf_ctrl) {
+        return true;
+    }
+    for (i = 0; i < MAX_FIXED_COUNTERS; i++) {
+        if (env->msr_fixed_counters[i]) {
+            return true;
+        }
+    }
+    for (i = 0; i < MAX_GP_COUNTERS; i++) {
+        if (env->msr_gp_counters[i] || env->msr_gp_evtsel[i]) {
+            return true;
+        }
+    }
+
+    return false;
+}
+
+static const VMStateDescription vmstate_msr_architectural_pmu = {
+    .name = "cpu/msr_architectural_pmu",
+    .version_id = 1,
+    .minimum_version_id = 1,
+    .minimum_version_id_old = 1,
+    .fields      = (VMStateField []) {
+        VMSTATE_UINT64(env.msr_fixed_ctr_ctrl, X86CPU),
+        VMSTATE_UINT64(env.msr_global_ctrl, X86CPU),
+        VMSTATE_UINT64(env.msr_global_status, X86CPU),
+        VMSTATE_UINT64(env.msr_global_ovf_ctrl, X86CPU),
+        VMSTATE_UINT64_ARRAY(env.msr_fixed_counters, X86CPU, MAX_FIXED_COUNTERS),
+        VMSTATE_UINT64_ARRAY(env.msr_gp_counters, X86CPU, MAX_GP_COUNTERS),
+        VMSTATE_UINT64_ARRAY(env.msr_gp_evtsel, X86CPU, MAX_GP_COUNTERS),
+        VMSTATE_END_OF_LIST()
+    }
+};
+
 const VMStateDescription vmstate_x86_cpu = {
     .name = "cpu",
     .version_id = 12,
@@ -593,6 +634,9 @@ const VMStateDescription vmstate_x86_cpu = {
         }, {
             .vmsd = &vmstate_msr_ia32_feature_control,
             .needed = feature_control_needed,
+        }, {
+            .vmsd = &vmstate_msr_architectural_pmu,
+            .needed = pmu_enable_needed,
         } , {
             /* empty */
         }
commit e4a09c9637f13a744ad7e2bc5223df05ac582c0d
Author: Paolo Bonzini <pbonzini at redhat.com>
Date:   Thu Jul 25 17:05:21 2013 +0200

    target-i386: remove tabs from target-i386/cpu.h
    
    Signed-off-by: Paolo Bonzini <pbonzini at redhat.com>

diff --git a/target-i386/cpu.h b/target-i386/cpu.h
index 3a52f94..af4c0f7 100644
--- a/target-i386/cpu.h
+++ b/target-i386/cpu.h
@@ -37,9 +37,9 @@
 #define TARGET_HAS_ICE 1
 
 #ifdef TARGET_X86_64
-#define ELF_MACHINE	EM_X86_64
+#define ELF_MACHINE     EM_X86_64
 #else
-#define ELF_MACHINE	EM_386
+#define ELF_MACHINE     EM_386
 #endif
 
 #define CPUArchState struct CPUX86State
@@ -98,10 +98,10 @@
 #define DESC_TSS_BUSY_MASK (1 << 9)
 
 /* eflags masks */
-#define CC_C   	0x0001
-#define CC_P 	0x0004
-#define CC_A	0x0010
-#define CC_Z	0x0040
+#define CC_C    0x0001
+#define CC_P    0x0004
+#define CC_A    0x0010
+#define CC_Z    0x0040
 #define CC_S    0x0080
 #define CC_O    0x0800
 
@@ -109,14 +109,14 @@
 #define IOPL_SHIFT 12
 #define VM_SHIFT   17
 
-#define TF_MASK 		0x00000100
-#define IF_MASK 		0x00000200
-#define DF_MASK 		0x00000400
-#define IOPL_MASK		0x00003000
-#define NT_MASK	         	0x00004000
-#define RF_MASK			0x00010000
-#define VM_MASK			0x00020000
-#define AC_MASK			0x00040000
+#define TF_MASK                 0x00000100
+#define IF_MASK                 0x00000200
+#define DF_MASK                 0x00000400
+#define IOPL_MASK               0x00003000
+#define NT_MASK                 0x00004000
+#define RF_MASK                 0x00010000
+#define VM_MASK                 0x00020000
+#define AC_MASK                 0x00040000
 #define VIF_MASK                0x00080000
 #define VIP_MASK                0x00100000
 #define ID_MASK                 0x00200000
@@ -238,28 +238,28 @@
 #define DR7_TYPE_IO_RW       0x2
 #define DR7_TYPE_DATA_RW     0x3
 
-#define PG_PRESENT_BIT	0
-#define PG_RW_BIT	1
-#define PG_USER_BIT	2
-#define PG_PWT_BIT	3
-#define PG_PCD_BIT	4
-#define PG_ACCESSED_BIT	5
-#define PG_DIRTY_BIT	6
-#define PG_PSE_BIT	7
-#define PG_GLOBAL_BIT	8
-#define PG_NX_BIT	63
+#define PG_PRESENT_BIT  0
+#define PG_RW_BIT       1
+#define PG_USER_BIT     2
+#define PG_PWT_BIT      3
+#define PG_PCD_BIT      4
+#define PG_ACCESSED_BIT 5
+#define PG_DIRTY_BIT    6
+#define PG_PSE_BIT      7
+#define PG_GLOBAL_BIT   8
+#define PG_NX_BIT       63
 
 #define PG_PRESENT_MASK  (1 << PG_PRESENT_BIT)
-#define PG_RW_MASK	 (1 << PG_RW_BIT)
-#define PG_USER_MASK	 (1 << PG_USER_BIT)
-#define PG_PWT_MASK	 (1 << PG_PWT_BIT)
-#define PG_PCD_MASK	 (1 << PG_PCD_BIT)
+#define PG_RW_MASK       (1 << PG_RW_BIT)
+#define PG_USER_MASK     (1 << PG_USER_BIT)
+#define PG_PWT_MASK      (1 << PG_PWT_BIT)
+#define PG_PCD_MASK      (1 << PG_PCD_BIT)
 #define PG_ACCESSED_MASK (1 << PG_ACCESSED_BIT)
-#define PG_DIRTY_MASK	 (1 << PG_DIRTY_BIT)
-#define PG_PSE_MASK	 (1 << PG_PSE_BIT)
-#define PG_GLOBAL_MASK	 (1 << PG_GLOBAL_BIT)
+#define PG_DIRTY_MASK    (1 << PG_DIRTY_BIT)
+#define PG_PSE_MASK      (1 << PG_PSE_BIT)
+#define PG_GLOBAL_MASK   (1 << PG_GLOBAL_BIT)
 #define PG_HI_USER_MASK  0x7ff0000000000000LL
-#define PG_NX_MASK	 (1LL << PG_NX_BIT)
+#define PG_NX_MASK       (1LL << PG_NX_BIT)
 
 #define PG_ERROR_W_BIT     1
 
@@ -269,32 +269,32 @@
 #define PG_ERROR_RSVD_MASK 0x08
 #define PG_ERROR_I_D_MASK  0x10
 
-#define MCG_CTL_P	(1ULL<<8)   /* MCG_CAP register available */
-#define MCG_SER_P	(1ULL<<24) /* MCA recovery/new status bits */
+#define MCG_CTL_P       (1ULL<<8)   /* MCG_CAP register available */
+#define MCG_SER_P       (1ULL<<24) /* MCA recovery/new status bits */
 
-#define MCE_CAP_DEF	(MCG_CTL_P|MCG_SER_P)
-#define MCE_BANKS_DEF	10
+#define MCE_CAP_DEF     (MCG_CTL_P|MCG_SER_P)
+#define MCE_BANKS_DEF   10
 
-#define MCG_STATUS_RIPV	(1ULL<<0)   /* restart ip valid */
-#define MCG_STATUS_EIPV	(1ULL<<1)   /* ip points to correct instruction */
-#define MCG_STATUS_MCIP	(1ULL<<2)   /* machine check in progress */
+#define MCG_STATUS_RIPV (1ULL<<0)   /* restart ip valid */
+#define MCG_STATUS_EIPV (1ULL<<1)   /* ip points to correct instruction */
+#define MCG_STATUS_MCIP (1ULL<<2)   /* machine check in progress */
 
-#define MCI_STATUS_VAL	(1ULL<<63)  /* valid error */
-#define MCI_STATUS_OVER	(1ULL<<62)  /* previous errors lost */
-#define MCI_STATUS_UC	(1ULL<<61)  /* uncorrected error */
-#define MCI_STATUS_EN	(1ULL<<60)  /* error enabled */
-#define MCI_STATUS_MISCV (1ULL<<59) /* misc error reg. valid */
-#define MCI_STATUS_ADDRV (1ULL<<58) /* addr reg. valid */
-#define MCI_STATUS_PCC	(1ULL<<57)  /* processor context corrupt */
-#define MCI_STATUS_S	(1ULL<<56)  /* Signaled machine check */
-#define MCI_STATUS_AR	(1ULL<<55)  /* Action required */
+#define MCI_STATUS_VAL   (1ULL<<63)  /* valid error */
+#define MCI_STATUS_OVER  (1ULL<<62)  /* previous errors lost */
+#define MCI_STATUS_UC    (1ULL<<61)  /* uncorrected error */
+#define MCI_STATUS_EN    (1ULL<<60)  /* error enabled */
+#define MCI_STATUS_MISCV (1ULL<<59)  /* misc error reg. valid */
+#define MCI_STATUS_ADDRV (1ULL<<58)  /* addr reg. valid */
+#define MCI_STATUS_PCC   (1ULL<<57)  /* processor context corrupt */
+#define MCI_STATUS_S     (1ULL<<56)  /* Signaled machine check */
+#define MCI_STATUS_AR    (1ULL<<55)  /* Action required */
 
 /* MISC register defines */
-#define MCM_ADDR_SEGOFF	0	/* segment offset */
-#define MCM_ADDR_LINEAR	1	/* linear address */
-#define MCM_ADDR_PHYS	2	/* physical address */
-#define MCM_ADDR_MEM	3	/* memory address */
-#define MCM_ADDR_GENERIC 7	/* generic */
+#define MCM_ADDR_SEGOFF  0      /* segment offset */
+#define MCM_ADDR_LINEAR  1      /* linear address */
+#define MCM_ADDR_PHYS    2      /* physical address */
+#define MCM_ADDR_MEM     3      /* memory address */
+#define MCM_ADDR_GENERIC 7      /* generic */
 
 #define MSR_IA32_TSC                    0x10
 #define MSR_IA32_APICBASE               0x1b
@@ -305,10 +305,10 @@
 #define MSR_TSC_ADJUST                  0x0000003b
 #define MSR_IA32_TSCDEADLINE            0x6e0
 
-#define MSR_MTRRcap			0xfe
-#define MSR_MTRRcap_VCNT		8
-#define MSR_MTRRcap_FIXRANGE_SUPPORT	(1 << 8)
-#define MSR_MTRRcap_WC_SUPPORTED	(1 << 10)
+#define MSR_MTRRcap                     0xfe
+#define MSR_MTRRcap_VCNT                8
+#define MSR_MTRRcap_FIXRANGE_SUPPORT    (1 << 8)
+#define MSR_MTRRcap_WC_SUPPORTED        (1 << 10)
 
 #define MSR_IA32_SYSENTER_CS            0x174
 #define MSR_IA32_SYSENTER_ESP           0x175
@@ -320,33 +320,33 @@
 
 #define MSR_IA32_PERF_STATUS            0x198
 
-#define MSR_IA32_MISC_ENABLE		0x1a0
+#define MSR_IA32_MISC_ENABLE            0x1a0
 /* Indicates good rep/movs microcode on some processors: */
 #define MSR_IA32_MISC_ENABLE_DEFAULT    1
 
-#define MSR_MTRRphysBase(reg)		(0x200 + 2 * (reg))
-#define MSR_MTRRphysMask(reg)		(0x200 + 2 * (reg) + 1)
-
-#define MSR_MTRRfix64K_00000		0x250
-#define MSR_MTRRfix16K_80000		0x258
-#define MSR_MTRRfix16K_A0000		0x259
-#define MSR_MTRRfix4K_C0000		0x268
-#define MSR_MTRRfix4K_C8000		0x269
-#define MSR_MTRRfix4K_D0000		0x26a
-#define MSR_MTRRfix4K_D8000		0x26b
-#define MSR_MTRRfix4K_E0000		0x26c
-#define MSR_MTRRfix4K_E8000		0x26d
-#define MSR_MTRRfix4K_F0000		0x26e
-#define MSR_MTRRfix4K_F8000		0x26f
+#define MSR_MTRRphysBase(reg)           (0x200 + 2 * (reg))
+#define MSR_MTRRphysMask(reg)           (0x200 + 2 * (reg) + 1)
+
+#define MSR_MTRRfix64K_00000            0x250
+#define MSR_MTRRfix16K_80000            0x258
+#define MSR_MTRRfix16K_A0000            0x259
+#define MSR_MTRRfix4K_C0000             0x268
+#define MSR_MTRRfix4K_C8000             0x269
+#define MSR_MTRRfix4K_D0000             0x26a
+#define MSR_MTRRfix4K_D8000             0x26b
+#define MSR_MTRRfix4K_E0000             0x26c
+#define MSR_MTRRfix4K_E8000             0x26d
+#define MSR_MTRRfix4K_F0000             0x26e
+#define MSR_MTRRfix4K_F8000             0x26f
 
 #define MSR_PAT                         0x277
 
-#define MSR_MTRRdefType			0x2ff
+#define MSR_MTRRdefType                 0x2ff
 
-#define MSR_MC0_CTL			0x400
-#define MSR_MC0_STATUS			0x401
-#define MSR_MC0_ADDR			0x402
-#define MSR_MC0_MISC			0x403
+#define MSR_MC0_CTL                     0x400
+#define MSR_MC0_STATUS                  0x401
+#define MSR_MC0_ADDR                    0x402
+#define MSR_MC0_MISC                    0x403
 
 #define MSR_EFER                        0xc0000080
 
@@ -550,24 +550,24 @@ typedef uint32_t FeatureWordArray[FEATURE_WORDS];
 #define CPUID_MWAIT_IBE     (1 << 1) /* Interrupts can exit capability */
 #define CPUID_MWAIT_EMX     (1 << 0) /* enumeration supported */
 
-#define EXCP00_DIVZ	0
-#define EXCP01_DB	1
-#define EXCP02_NMI	2
-#define EXCP03_INT3	3
-#define EXCP04_INTO	4
-#define EXCP05_BOUND	5
-#define EXCP06_ILLOP	6
-#define EXCP07_PREX	7
-#define EXCP08_DBLE	8
-#define EXCP09_XERR	9
-#define EXCP0A_TSS	10
-#define EXCP0B_NOSEG	11
-#define EXCP0C_STACK	12
-#define EXCP0D_GPF	13
-#define EXCP0E_PAGE	14
-#define EXCP10_COPR	16
-#define EXCP11_ALGN	17
-#define EXCP12_MCHK	18
+#define EXCP00_DIVZ     0
+#define EXCP01_DB       1
+#define EXCP02_NMI      2
+#define EXCP03_INT3     3
+#define EXCP04_INTO     4
+#define EXCP05_BOUND    5
+#define EXCP06_ILLOP    6
+#define EXCP07_PREX     7
+#define EXCP08_DBLE     8
+#define EXCP09_XERR     9
+#define EXCP0A_TSS      10
+#define EXCP0B_NOSEG    11
+#define EXCP0C_STACK    12
+#define EXCP0D_GPF      13
+#define EXCP0E_PAGE     14
+#define EXCP10_COPR     16
+#define EXCP11_ALGN     17
+#define EXCP12_MCHK     18
 
 #define EXCP_SYSCALL    0x100 /* only happens in user only emulation
                                  for syscall instruction */
@@ -1087,7 +1087,7 @@ static inline CPUX86State *cpu_init(const char *cpu_model)
 #define cpu_gen_code cpu_x86_gen_code
 #define cpu_signal_handler cpu_x86_signal_handler
 #define cpu_list x86_cpu_list
-#define cpudef_setup	x86_cpudef_setup
+#define cpudef_setup x86_cpudef_setup
 
 /* MMU modes definitions */
 #define MMU_MODE0_SUFFIX _kernel
commit 6db5f5d68e2ffc430ba0511e23fc36c7363510f1
Author: Mike Qiu <qiudayu at linux.vnet.ibm.com>
Date:   Thu Aug 8 10:45:16 2013 -0400

    block: Bugfix 'format' and 'snapshot' used in drive option
    
    When use -drive file='xxx',format=qcow2,snapshot=on the error
    message "Can't use snapshot=on with driver-specific options"
    can be show, and fail to start the qemu.
    
    This should not be happened, and there is no file.driver option
    in qemu command line.
    
    It is because the commit 74fe54f2a1b5c4f4498a8fe521e1dfc936656cd4,
    it puts 'driver' option if the command line use 'format' option.
    
    This patch is to solve this bug.
    
    Signed-off-by: Mike Qiu <qiudayu at linux.vnet.ibm.com>
    Signed-off-by: Kevin Wolf <kwolf at redhat.com>

diff --git a/blockdev.c b/blockdev.c
index 41b0a49..e174b7d 100644
--- a/blockdev.c
+++ b/blockdev.c
@@ -340,6 +340,7 @@ static DriveInfo *blockdev_init(QemuOpts *all_opts,
     QDict *bs_opts;
     const char *id;
     bool has_driver_specific_opts;
+    BlockDriver *drv = NULL;
 
     translation = BIOS_ATA_TRANSLATION_AUTO;
     media = MEDIA_DISK;
@@ -485,7 +486,11 @@ static DriveInfo *blockdev_init(QemuOpts *all_opts,
             return NULL;
         }
 
-        qdict_put(bs_opts, "driver", qstring_from_str(buf));
+        drv = bdrv_find_whitelisted_format(buf, ro);
+        if (!drv) {
+            error_report("'%s' invalid format", buf);
+            return NULL;
+        }
     }
 
     /* disk I/O throttling */
@@ -700,12 +705,13 @@ static DriveInfo *blockdev_init(QemuOpts *all_opts,
     }
 
     QINCREF(bs_opts);
-    ret = bdrv_open(dinfo->bdrv, file, bs_opts, bdrv_flags, NULL);
+    ret = bdrv_open(dinfo->bdrv, file, bs_opts, bdrv_flags, drv);
 
     if (ret < 0) {
         if (ret == -EMEDIUMTYPE) {
             error_report("could not open disk image %s: not in %s format",
-                         file ?: dinfo->id, qdict_get_str(bs_opts, "driver"));
+                         file ?: dinfo->id, drv ? drv->format_name :
+                         qdict_get_str(bs_opts, "driver"));
         } else {
             error_report("could not open disk image %s: %s",
                          file ?: dinfo->id, strerror(-ret));
commit f6049f4483d61fa911a0693c2c48ce8308451d33
Author: Peter Maydell <peter.maydell at linaro.org>
Date:   Fri Jul 26 16:41:27 2013 +0100

    hw/virtio/virtio: Don't allow guests to add/remove queues
    
    A queue size of 0 is used to indicate a nonexistent queue, so
    don't allow the guest to flip a queue between zero-size and
    non-zero-size. Don't permit setting of negative queue sizes
    either.
    
    Signed-off-by: Peter Maydell <peter.maydell at linaro.org>
    Message-id: 1374853288-9912-2-git-send-email-peter.maydell at linaro.org
    Reviewed-by: Michael S. Tsirkin <mst at redhat.com>

diff --git a/hw/virtio/virtio.c b/hw/virtio/virtio.c
index 09f62c6..60653f7 100644
--- a/hw/virtio/virtio.c
+++ b/hw/virtio/virtio.c
@@ -673,10 +673,16 @@ hwaddr virtio_queue_get_addr(VirtIODevice *vdev, int n)
 
 void virtio_queue_set_num(VirtIODevice *vdev, int n, int num)
 {
-    if (num <= VIRTQUEUE_MAX_SIZE) {
-        vdev->vq[n].vring.num = num;
-        virtqueue_init(&vdev->vq[n]);
+    /* Don't allow guest to flip queue between existent and
+     * nonexistent states, or to set it to an invalid size.
+     */
+    if (!!num != !!vdev->vq[n].vring.num ||
+        num > VIRTQUEUE_MAX_SIZE ||
+        num < 0) {
+        return;
     }
+    vdev->vq[n].vring.num = num;
+    virtqueue_init(&vdev->vq[n]);
 }
 
 int virtio_queue_get_num(VirtIODevice *vdev, int n)
commit 2e985fe000e73097e325e18b943e8babfa96c35c
Author: Aurelien Jarno <aurelien at aurel32.net>
Date:   Sat Aug 3 16:03:18 2013 +0200

    mips: revert commit b332d24a8e1290954029814d09156b06ede358e2
    
    Now that this code path is not triggered anymore during the tests,
    revert commit b332d24a8e1290954029814d09156b06ede358e2. Booting a MIPS
    target without kernel nor bios doesn't really make sense. At the same
    time replace fprintf(stderr, ...) by error_report().
    
    Reviewed-by: Andreas Färber <afaerber at suse.de>
    Signed-off-by: Aurelien Jarno <aurelien at aurel32.net>

diff --git a/hw/mips/mips_fulong2e.c b/hw/mips/mips_fulong2e.c
index b13750d..e8d5dd0 100644
--- a/hw/mips/mips_fulong2e.c
+++ b/hw/mips/mips_fulong2e.c
@@ -44,6 +44,7 @@
 #include "sysemu/blockdev.h"
 #include "exec/address-spaces.h"
 #include "sysemu/qtest.h"
+#include "qemu/error-report.h"
 
 #define DEBUG_FULONG2E_INIT
 
@@ -335,7 +336,8 @@ static void mips_fulong2e_init(QEMUMachineInitArgs *args)
 
         if ((bios_size < 0 || bios_size > BIOS_SIZE) &&
             !kernel_filename && !qtest_enabled()) {
-            fprintf(stderr, "qemu: Warning, could not load MIPS bios '%s'\n", bios_name);
+            error_report("Could not load MIPS bios '%s'", bios_name);
+            exit(1);
         }
     }
 
diff --git a/hw/mips/mips_jazz.c b/hw/mips/mips_jazz.c
index 36677cc..d748ded 100644
--- a/hw/mips/mips_jazz.c
+++ b/hw/mips/mips_jazz.c
@@ -43,6 +43,7 @@
 #include "hw/sysbus.h"
 #include "exec/address-spaces.h"
 #include "sysemu/qtest.h"
+#include "qemu/error-report.h"
 
 enum jazz_model_e
 {
@@ -178,8 +179,8 @@ static void mips_jazz_init(MemoryRegion *address_space,
         bios_size = -1;
     }
     if ((bios_size < 0 || bios_size > MAGNUM_BIOS_SIZE) && !qtest_enabled()) {
-        fprintf(stderr, "qemu: Warning, could not load MIPS bios '%s'\n",
-                bios_name);
+        error_report("Could not load MIPS bios '%s'", bios_name);
+        exit(1);
     }
 
     /* Init CPU internal devices */
diff --git a/hw/mips/mips_malta.c b/hw/mips/mips_malta.c
index f56f34f..0f5de33 100644
--- a/hw/mips/mips_malta.c
+++ b/hw/mips/mips_malta.c
@@ -49,6 +49,7 @@
 #include "hw/sysbus.h"             /* SysBusDevice */
 #include "qemu/host-utils.h"
 #include "sysemu/qtest.h"
+#include "qemu/error-report.h"
 
 //#define DEBUG_BOARD_INIT
 
@@ -1008,9 +1009,9 @@ void mips_malta_init(QEMUMachineInitArgs *args)
             }
             if ((bios_size < 0 || bios_size > BIOS_SIZE) &&
                 !kernel_filename && !qtest_enabled()) {
-                fprintf(stderr,
-                        "qemu: Warning, could not load MIPS bios '%s', and no -kernel argument was specified\n",
-                        bios_name);
+                error_report("Could not load MIPS bios '%s', and no "
+                             "-kernel argument was specified", bios_name);
+                exit(1);
             }
         }
         /* In little endian mode the 32bit words in the bios are swapped,
diff --git a/hw/mips/mips_mipssim.c b/hw/mips/mips_mipssim.c
index fea1a15..297f01e 100644
--- a/hw/mips/mips_mipssim.c
+++ b/hw/mips/mips_mipssim.c
@@ -37,6 +37,7 @@
 #include "elf.h"
 #include "hw/sysbus.h"
 #include "exec/address-spaces.h"
+#include "qemu/error-report.h"
 
 static struct _loaderparams {
     int ram_size;
@@ -191,9 +192,9 @@ mips_mipssim_init(QEMUMachineInitArgs *args)
     }
     if ((bios_size < 0 || bios_size > BIOS_SIZE) && !kernel_filename) {
         /* Bail out if we have neither a kernel image nor boot vector code. */
-        fprintf(stderr,
-                "qemu: Warning, could not load MIPS bios '%s', and no -kernel argument was specified\n",
-                filename);
+        error_report("Could not load MIPS bios '%s', and no "
+                     "-kernel argument was specified", filename);
+        exit(1);
     } else {
         /* We have a boot vector start address. */
         env->active_tc.PC = (target_long)(int32_t)0xbfc00000;
commit 85711e6bafb1910b50ff181e8507cb904ef7e84d
Author: James Hogan <james.hogan at imgtec.com>
Date:   Thu Aug 8 15:40:23 2013 +0100

    tcg/mips: fix invalid op definition errors
    
    tcg/mips/tcg-target.h defines various operations conditionally depending
    upon the isa revision, however these operations are included in
    mips_op_defs[] unconditionally resulting in the following runtime errors
    if CONFIG_DEBUG_TCG is defined:
    
    Invalid op definition for movcond_i32
    Invalid op definition for rotl_i32
    Invalid op definition for rotr_i32
    Invalid op definition for deposit_i32
    Invalid op definition for bswap16_i32
    Invalid op definition for bswap32_i32
    tcg/tcg.c:1196: tcg fatal error
    
    Fix with ifdefs like the i386 backend does for movcond_i32.
    
    Signed-off-by: James Hogan <james.hogan at imgtec.com>
    Cc: Aurelien Jarno <aurelien at aurel32.net>
    Cc: Richard Henderson <rth at twiddle.net>
    Signed-off-by: Aurelien Jarno <aurelien at aurel32.net>

diff --git a/tcg/mips/tcg-target.c b/tcg/mips/tcg-target.c
index 373c364..793532e 100644
--- a/tcg/mips/tcg-target.c
+++ b/tcg/mips/tcg-target.c
@@ -1617,19 +1617,29 @@ static const TCGTargetOpDef mips_op_defs[] = {
     { INDEX_op_shl_i32, { "r", "rZ", "ri" } },
     { INDEX_op_shr_i32, { "r", "rZ", "ri" } },
     { INDEX_op_sar_i32, { "r", "rZ", "ri" } },
+#if TCG_TARGET_HAS_rot_i32
     { INDEX_op_rotr_i32, { "r", "rZ", "ri" } },
     { INDEX_op_rotl_i32, { "r", "rZ", "ri" } },
+#endif
 
+#if TCG_TARGET_HAS_bswap16_i32
     { INDEX_op_bswap16_i32, { "r", "r" } },
+#endif
+#if TCG_TARGET_HAS_bswap32_i32
     { INDEX_op_bswap32_i32, { "r", "r" } },
+#endif
 
     { INDEX_op_ext8s_i32, { "r", "rZ" } },
     { INDEX_op_ext16s_i32, { "r", "rZ" } },
 
+#if TCG_TARGET_HAS_deposit_i32
     { INDEX_op_deposit_i32, { "r", "0", "rZ" } },
+#endif
 
     { INDEX_op_brcond_i32, { "rZ", "rZ" } },
+#if TCG_TARGET_HAS_movcond_i32
     { INDEX_op_movcond_i32, { "r", "rZ", "rZ", "rZ", "0" } },
+#endif
     { INDEX_op_setcond_i32, { "r", "rZ", "rZ" } },
     { INDEX_op_setcond2_i32, { "r", "rZ", "rZ", "rZ", "rZ" } },
 
commit 56c4bfb3f07f3107894c00281276aea4f5e8834d
Author: Laszlo Ersek <lersek at redhat.com>
Date:   Tue Aug 6 12:37:11 2013 +0200

    dump: rebase from host-private RAMBlock offsets to guest-physical addresses
    
    RAMBlock.offset                   --> GuestPhysBlock.target_start
    RAMBlock.offset + RAMBlock.length --> GuestPhysBlock.target_end
    RAMBlock.length                   --> GuestPhysBlock.target_end -
                                          GuestPhysBlock.target_start
    
    "GuestPhysBlock.host_addr" is only used when writing the dump contents.
    
    This patch enables "crash" to work with the vmcore by rebasing the vmcore
    from the left side of the following diagram to the right side:
    
    host-private
    offset
    relative
    to ram_addr   RAMBlock                  guest-visible paddrs
                0 +-------------------+.....+-------------------+ 0
                  |         ^         |     |        ^          |
                  |       640 KB      |     |      640 KB       |
                  |         v         |     |        v          |
      0x0000a0000 +-------------------+.....+-------------------+ 0x0000a0000
                  |         ^         |     |XXXXXXXXXXXXXXXXXXX|
                  |       384 KB      |     |XXXXXXXXXXXXXXXXXXX|
                  |         v         |     |XXXXXXXXXXXXXXXXXXX|
      0x000100000 +-------------------+.....+-------------------+ 0x000100000
                  |         ^         |     |        ^          |
                  |       3583 MB     |     |      3583 MB      |
                  |         v         |     |        v          |
      0x0e0000000 +-------------------+.....+-------------------+ 0x0e0000000
                  |         ^         |.    |XXXXXXXXXXXXXXXXXXX|
                  | above_4g_mem_size | .   |XXXX PCI hole XXXXX|
                  |         v         |  .  |XXXX          XXXXX|
         ram_size +-------------------+   . |XXXX  512 MB  XXXXX|
                                       .   .|XXXXXXXXXXXXXXXXXXX|
                                        .   +-------------------+ 0x100000000
                                         .  |         ^         |
                                          . | above_4g_mem_size |
                                           .|         v         |
                                            +-------------------+ ram_size
                                                                  + 512 MB
    
    Related RHBZ: https://bugzilla.redhat.com/show_bug.cgi?id=981582
    
    Signed-off-by: Laszlo Ersek <lersek at redhat.com>
    Signed-off-by: Luiz Capitulino <lcapitulino at redhat.com>

diff --git a/dump.c b/dump.c
index 3fa33fc..c0dae2c 100644
--- a/dump.c
+++ b/dump.c
@@ -70,7 +70,7 @@ typedef struct DumpState {
     hwaddr memory_offset;
     int fd;
 
-    RAMBlock *block;
+    GuestPhysBlock *next_block;
     ram_addr_t start;
     bool has_filter;
     int64_t begin;
@@ -391,14 +391,14 @@ static int write_data(DumpState *s, void *buf, int length)
 }
 
 /* write the memroy to vmcore. 1 page per I/O. */
-static int write_memory(DumpState *s, RAMBlock *block, ram_addr_t start,
+static int write_memory(DumpState *s, GuestPhysBlock *block, ram_addr_t start,
                         int64_t size)
 {
     int64_t i;
     int ret;
 
     for (i = 0; i < size / TARGET_PAGE_SIZE; i++) {
-        ret = write_data(s, block->host + start + i * TARGET_PAGE_SIZE,
+        ret = write_data(s, block->host_addr + start + i * TARGET_PAGE_SIZE,
                          TARGET_PAGE_SIZE);
         if (ret < 0) {
             return ret;
@@ -406,7 +406,7 @@ static int write_memory(DumpState *s, RAMBlock *block, ram_addr_t start,
     }
 
     if ((size % TARGET_PAGE_SIZE) != 0) {
-        ret = write_data(s, block->host + start + i * TARGET_PAGE_SIZE,
+        ret = write_data(s, block->host_addr + start + i * TARGET_PAGE_SIZE,
                          size % TARGET_PAGE_SIZE);
         if (ret < 0) {
             return ret;
@@ -423,7 +423,7 @@ static void get_offset_range(hwaddr phys_addr,
                              hwaddr *p_offset,
                              hwaddr *p_filesz)
 {
-    RAMBlock *block;
+    GuestPhysBlock *block;
     hwaddr offset = s->memory_offset;
     int64_t size_in_block, start;
 
@@ -437,35 +437,34 @@ static void get_offset_range(hwaddr phys_addr,
         }
     }
 
-    QTAILQ_FOREACH(block, &ram_list.blocks, next) {
+    QTAILQ_FOREACH(block, &s->guest_phys_blocks.head, next) {
         if (s->has_filter) {
-            if (block->offset >= s->begin + s->length ||
-                block->offset + block->length <= s->begin) {
+            if (block->target_start >= s->begin + s->length ||
+                block->target_end <= s->begin) {
                 /* This block is out of the range */
                 continue;
             }
 
-            if (s->begin <= block->offset) {
-                start = block->offset;
+            if (s->begin <= block->target_start) {
+                start = block->target_start;
             } else {
                 start = s->begin;
             }
 
-            size_in_block = block->length - (start - block->offset);
-            if (s->begin + s->length < block->offset + block->length) {
-                size_in_block -= block->offset + block->length -
-                                 (s->begin + s->length);
+            size_in_block = block->target_end - start;
+            if (s->begin + s->length < block->target_end) {
+                size_in_block -= block->target_end - (s->begin + s->length);
             }
         } else {
-            start = block->offset;
-            size_in_block = block->length;
+            start = block->target_start;
+            size_in_block = block->target_end - block->target_start;
         }
 
         if (phys_addr >= start && phys_addr < start + size_in_block) {
             *p_offset = phys_addr - start + offset;
 
             /* The offset range mapped from the vmcore file must not spill over
-             * the RAMBlock, clamp it. The rest of the mapping will be
+             * the GuestPhysBlock, clamp it. The rest of the mapping will be
              * zero-filled in memory at load time; see
              * <http://refspecs.linuxbase.org/elf/gabi4+/ch5.pheader.html>.
              */
@@ -613,7 +612,7 @@ static int dump_completed(DumpState *s)
     return 0;
 }
 
-static int get_next_block(DumpState *s, RAMBlock *block)
+static int get_next_block(DumpState *s, GuestPhysBlock *block)
 {
     while (1) {
         block = QTAILQ_NEXT(block, next);
@@ -623,16 +622,16 @@ static int get_next_block(DumpState *s, RAMBlock *block)
         }
 
         s->start = 0;
-        s->block = block;
+        s->next_block = block;
         if (s->has_filter) {
-            if (block->offset >= s->begin + s->length ||
-                block->offset + block->length <= s->begin) {
+            if (block->target_start >= s->begin + s->length ||
+                block->target_end <= s->begin) {
                 /* This block is out of the range */
                 continue;
             }
 
-            if (s->begin > block->offset) {
-                s->start = s->begin - block->offset;
+            if (s->begin > block->target_start) {
+                s->start = s->begin - block->target_start;
             }
         }
 
@@ -643,18 +642,18 @@ static int get_next_block(DumpState *s, RAMBlock *block)
 /* write all memory to vmcore */
 static int dump_iterate(DumpState *s)
 {
-    RAMBlock *block;
+    GuestPhysBlock *block;
     int64_t size;
     int ret;
 
     while (1) {
-        block = s->block;
+        block = s->next_block;
 
-        size = block->length;
+        size = block->target_end - block->target_start;
         if (s->has_filter) {
             size -= s->start;
-            if (s->begin + s->length < block->offset + block->length) {
-                size -= block->offset + block->length - (s->begin + s->length);
+            if (s->begin + s->length < block->target_end) {
+                size -= block->target_end - (s->begin + s->length);
             }
         }
         ret = write_memory(s, block, s->start, size);
@@ -689,23 +688,23 @@ static int create_vmcore(DumpState *s)
 
 static ram_addr_t get_start_block(DumpState *s)
 {
-    RAMBlock *block;
+    GuestPhysBlock *block;
 
     if (!s->has_filter) {
-        s->block = QTAILQ_FIRST(&ram_list.blocks);
+        s->next_block = QTAILQ_FIRST(&s->guest_phys_blocks.head);
         return 0;
     }
 
-    QTAILQ_FOREACH(block, &ram_list.blocks, next) {
-        if (block->offset >= s->begin + s->length ||
-            block->offset + block->length <= s->begin) {
+    QTAILQ_FOREACH(block, &s->guest_phys_blocks.head, next) {
+        if (block->target_start >= s->begin + s->length ||
+            block->target_end <= s->begin) {
             /* This block is out of the range */
             continue;
         }
 
-        s->block = block;
-        if (s->begin > block->offset) {
-            s->start = s->begin - block->offset;
+        s->next_block = block;
+        if (s->begin > block->target_start) {
+            s->start = s->begin - block->target_start;
         } else {
             s->start = 0;
         }
@@ -758,7 +757,7 @@ 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.
      */
-    ret = cpu_get_dump_info(&s->dump_info);
+    ret = cpu_get_dump_info(&s->dump_info, &s->guest_phys_blocks);
     if (ret < 0) {
         error_set(errp, QERR_UNSUPPORTED);
         goto cleanup;
@@ -774,13 +773,13 @@ 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, &err);
+        qemu_get_guest_memory_mapping(&s->list, &s->guest_phys_blocks, &err);
         if (err != NULL) {
             error_propagate(errp, err);
             goto cleanup;
         }
     } else {
-        qemu_get_guest_simple_memory_mapping(&s->list);
+        qemu_get_guest_simple_memory_mapping(&s->list, &s->guest_phys_blocks);
     }
 
     if (s->has_filter) {
diff --git a/include/sysemu/dump.h b/include/sysemu/dump.h
index b8c770f..19fafb2 100644
--- a/include/sysemu/dump.h
+++ b/include/sysemu/dump.h
@@ -20,7 +20,9 @@ typedef struct ArchDumpInfo {
     int d_class;    /* ELFCLASS32 or ELFCLASS64 */
 } ArchDumpInfo;
 
-int cpu_get_dump_info(ArchDumpInfo *info);
+struct GuestPhysBlockList; /* memory_mapping.h */
+int cpu_get_dump_info(ArchDumpInfo *info,
+                      const struct GuestPhysBlockList *guest_phys_blocks);
 ssize_t cpu_get_note_size(int class, int machine, int nr_cpus);
 
 #endif
diff --git a/include/sysemu/memory_mapping.h b/include/sysemu/memory_mapping.h
index b2d7d85..a75d59a 100644
--- a/include/sysemu/memory_mapping.h
+++ b/include/sysemu/memory_mapping.h
@@ -68,10 +68,13 @@ void guest_phys_blocks_free(GuestPhysBlockList *list);
 void guest_phys_blocks_init(GuestPhysBlockList *list);
 void guest_phys_blocks_append(GuestPhysBlockList *list);
 
-void qemu_get_guest_memory_mapping(MemoryMappingList *list, Error **errp);
+void qemu_get_guest_memory_mapping(MemoryMappingList *list,
+                                   const GuestPhysBlockList *guest_phys_blocks,
+                                   Error **errp);
 
 /* get guest's memory mapping without do paging(virtual address is 0). */
-void qemu_get_guest_simple_memory_mapping(MemoryMappingList *list);
+void qemu_get_guest_simple_memory_mapping(MemoryMappingList *list,
+                                  const GuestPhysBlockList *guest_phys_blocks);
 
 void memory_mapping_filter(MemoryMappingList *list, int64_t begin,
                            int64_t length);
diff --git a/memory_mapping.c b/memory_mapping.c
index 876f5aa..eeeeb44 100644
--- a/memory_mapping.c
+++ b/memory_mapping.c
@@ -279,10 +279,12 @@ static CPUState *find_paging_enabled_cpu(CPUState *start_cpu)
     return NULL;
 }
 
-void qemu_get_guest_memory_mapping(MemoryMappingList *list, Error **errp)
+void qemu_get_guest_memory_mapping(MemoryMappingList *list,
+                                   const GuestPhysBlockList *guest_phys_blocks,
+                                   Error **errp)
 {
     CPUState *cpu, *first_paging_enabled_cpu;
-    RAMBlock *block;
+    GuestPhysBlock *block;
     ram_addr_t offset, length;
 
     first_paging_enabled_cpu = find_paging_enabled_cpu(first_cpu);
@@ -302,19 +304,21 @@ void qemu_get_guest_memory_mapping(MemoryMappingList *list, Error **errp)
      * If the guest doesn't use paging, the virtual address is equal to physical
      * address.
      */
-    QTAILQ_FOREACH(block, &ram_list.blocks, next) {
-        offset = block->offset;
-        length = block->length;
+    QTAILQ_FOREACH(block, &guest_phys_blocks->head, next) {
+        offset = block->target_start;
+        length = block->target_end - block->target_start;
         create_new_memory_mapping(list, offset, offset, length);
     }
 }
 
-void qemu_get_guest_simple_memory_mapping(MemoryMappingList *list)
+void qemu_get_guest_simple_memory_mapping(MemoryMappingList *list,
+                                   const GuestPhysBlockList *guest_phys_blocks)
 {
-    RAMBlock *block;
+    GuestPhysBlock *block;
 
-    QTAILQ_FOREACH(block, &ram_list.blocks, next) {
-        create_new_memory_mapping(list, block->offset, 0, block->length);
+    QTAILQ_FOREACH(block, &guest_phys_blocks->head, next) {
+        create_new_memory_mapping(list, block->target_start, 0,
+                                  block->target_end - block->target_start);
     }
 }
 
diff --git a/stubs/dump.c b/stubs/dump.c
index 43c9a3f..370cd96 100644
--- a/stubs/dump.c
+++ b/stubs/dump.c
@@ -16,7 +16,8 @@
 #include "qapi/qmp/qerror.h"
 #include "qmp-commands.h"
 
-int cpu_get_dump_info(ArchDumpInfo *info)
+int cpu_get_dump_info(ArchDumpInfo *info,
+                      const struct GuestPhysBlockList *guest_phys_blocks)
 {
     return -1;
 }
diff --git a/target-i386/arch_dump.c b/target-i386/arch_dump.c
index 10dc228..0bbed23 100644
--- a/target-i386/arch_dump.c
+++ b/target-i386/arch_dump.c
@@ -15,6 +15,7 @@
 #include "exec/cpu-all.h"
 #include "sysemu/dump.h"
 #include "elf.h"
+#include "sysemu/memory_mapping.h"
 
 #ifdef TARGET_X86_64
 typedef struct {
@@ -389,10 +390,11 @@ int x86_cpu_write_elf32_qemunote(WriteCoreDumpFunction f, CPUState *cs,
     return cpu_write_qemu_note(f, &cpu->env, opaque, 0);
 }
 
-int cpu_get_dump_info(ArchDumpInfo *info)
+int cpu_get_dump_info(ArchDumpInfo *info,
+                      const GuestPhysBlockList *guest_phys_blocks)
 {
     bool lma = false;
-    RAMBlock *block;
+    GuestPhysBlock *block;
 
 #ifdef TARGET_X86_64
     X86CPU *first_x86_cpu = X86_CPU(first_cpu);
@@ -412,8 +414,8 @@ int cpu_get_dump_info(ArchDumpInfo *info)
     } else {
         info->d_class = ELFCLASS32;
 
-        QTAILQ_FOREACH(block, &ram_list.blocks, next) {
-            if (block->offset + block->length > UINT_MAX) {
+        QTAILQ_FOREACH(block, &guest_phys_blocks->head, next) {
+            if (block->target_end > UINT_MAX) {
                 /* The memory size is greater than 4G */
                 info->d_class = ELFCLASS64;
                 break;
diff --git a/target-s390x/arch_dump.c b/target-s390x/arch_dump.c
index f3e5144..9d36116 100644
--- a/target-s390x/arch_dump.c
+++ b/target-s390x/arch_dump.c
@@ -176,7 +176,8 @@ int s390_cpu_write_elf64_note(WriteCoreDumpFunction f, CPUState *cs,
     return s390x_write_all_elf64_notes("CORE", f, cpu, cpuid, opaque);
 }
 
-int cpu_get_dump_info(ArchDumpInfo *info)
+int cpu_get_dump_info(ArchDumpInfo *info,
+                      const struct GuestPhysBlockList *guest_phys_blocks)
 {
     info->d_machine = EM_S390;
     info->d_endian = ELFDATA2MSB;
commit c5d7f60f0614250bd925071e25220ce5958f75d0
Author: Laszlo Ersek <lersek at redhat.com>
Date:   Tue Aug 6 12:37:10 2013 +0200

    dump: populate guest_phys_blocks
    
    While the machine is paused, in guest_phys_blocks_append() we register a
    one-shot MemoryListener, solely for the initial collection of the valid
    guest-physical memory ranges that happens at listener registration time.
    
    For each range that is reported to guest_phys_blocks_region_add(), we
    attempt to merge the range with the preceding one.
    
    Ranges can only be joined if they are contiguous in both guest-physical
    address space, and contiguous in host virtual address space.
    
    The "maximal" ranges that remain in the end constitute the guest-physical
    memory map that the dump will be based on.
    
    Related RHBZ: https://bugzilla.redhat.com/show_bug.cgi?id=981582
    
    Signed-off-by: Laszlo Ersek <lersek at redhat.com>
    Signed-off-by: Luiz Capitulino <lcapitulino at redhat.com>

diff --git a/dump.c b/dump.c
index 716fb1d..3fa33fc 100644
--- a/dump.c
+++ b/dump.c
@@ -746,7 +746,7 @@ static int dump_init(DumpState *s, int fd, bool paging, bool has_filter,
     s->length = length;
 
     guest_phys_blocks_init(&s->guest_phys_blocks);
-    /* FILL LIST */
+    guest_phys_blocks_append(&s->guest_phys_blocks);
 
     s->start = get_start_block(s);
     if (s->start == -1) {
diff --git a/include/sysemu/memory_mapping.h b/include/sysemu/memory_mapping.h
index d2d06cd..b2d7d85 100644
--- a/include/sysemu/memory_mapping.h
+++ b/include/sysemu/memory_mapping.h
@@ -66,6 +66,7 @@ void memory_mapping_list_init(MemoryMappingList *list);
 
 void guest_phys_blocks_free(GuestPhysBlockList *list);
 void guest_phys_blocks_init(GuestPhysBlockList *list);
+void guest_phys_blocks_append(GuestPhysBlockList *list);
 
 void qemu_get_guest_memory_mapping(MemoryMappingList *list, Error **errp);
 
diff --git a/memory_mapping.c b/memory_mapping.c
index c70505b..876f5aa 100644
--- a/memory_mapping.c
+++ b/memory_mapping.c
@@ -11,9 +11,15 @@
  *
  */
 
+#include <glib.h>
+
 #include "cpu.h"
 #include "exec/cpu-all.h"
 #include "sysemu/memory_mapping.h"
+#include "exec/memory.h"
+#include "exec/address-spaces.h"
+
+//#define DEBUG_GUEST_PHYS_REGION_ADD
 
 static void memory_mapping_list_add_mapping_sorted(MemoryMappingList *list,
                                                    MemoryMapping *mapping)
@@ -182,6 +188,84 @@ void guest_phys_blocks_init(GuestPhysBlockList *list)
     QTAILQ_INIT(&list->head);
 }
 
+typedef struct GuestPhysListener {
+    GuestPhysBlockList *list;
+    MemoryListener listener;
+} GuestPhysListener;
+
+static void guest_phys_blocks_region_add(MemoryListener *listener,
+                                         MemoryRegionSection *section)
+{
+    GuestPhysListener *g;
+    uint64_t section_size;
+    hwaddr target_start, target_end;
+    uint8_t *host_addr;
+    GuestPhysBlock *predecessor;
+
+    /* we only care about RAM */
+    if (!memory_region_is_ram(section->mr)) {
+        return;
+    }
+
+    g            = container_of(listener, GuestPhysListener, listener);
+    section_size = int128_get64(section->size);
+    target_start = section->offset_within_address_space;
+    target_end   = target_start + section_size;
+    host_addr    = memory_region_get_ram_ptr(section->mr) +
+                   section->offset_within_region;
+    predecessor  = NULL;
+
+    /* find continuity in guest physical address space */
+    if (!QTAILQ_EMPTY(&g->list->head)) {
+        hwaddr predecessor_size;
+
+        predecessor = QTAILQ_LAST(&g->list->head, GuestPhysBlockHead);
+        predecessor_size = predecessor->target_end - predecessor->target_start;
+
+        /* the memory API guarantees monotonically increasing traversal */
+        g_assert(predecessor->target_end <= target_start);
+
+        /* we want continuity in both guest-physical and host-virtual memory */
+        if (predecessor->target_end < target_start ||
+            predecessor->host_addr + predecessor_size != host_addr) {
+            predecessor = NULL;
+        }
+    }
+
+    if (predecessor == NULL) {
+        /* isolated mapping, allocate it and add it to the list */
+        GuestPhysBlock *block = g_malloc0(sizeof *block);
+
+        block->target_start = target_start;
+        block->target_end   = target_end;
+        block->host_addr    = host_addr;
+
+        QTAILQ_INSERT_TAIL(&g->list->head, block, next);
+        ++g->list->num;
+    } else {
+        /* expand predecessor until @target_end; predecessor's start doesn't
+         * change
+         */
+        predecessor->target_end = target_end;
+    }
+
+#ifdef DEBUG_GUEST_PHYS_REGION_ADD
+    fprintf(stderr, "%s: target_start=" TARGET_FMT_plx " target_end="
+            TARGET_FMT_plx ": %s (count: %u)\n", __FUNCTION__, target_start,
+            target_end, predecessor ? "joined" : "added", g->list->num);
+#endif
+}
+
+void guest_phys_blocks_append(GuestPhysBlockList *list)
+{
+    GuestPhysListener g = { 0 };
+
+    g.list = list;
+    g.listener.region_add = &guest_phys_blocks_region_add;
+    memory_listener_register(&g.listener, &address_space_memory);
+    memory_listener_unregister(&g.listener);
+}
+
 static CPUState *find_paging_enabled_cpu(CPUState *start_cpu)
 {
     CPUState *cpu;
commit 5ee163e8ea2fb6610339f494e039159e08a69066
Author: Laszlo Ersek <lersek at redhat.com>
Date:   Tue Aug 6 12:37:09 2013 +0200

    dump: introduce GuestPhysBlockList
    
    The vmcore must use physical addresses that are visible to the guest, not
    addresses that point into linear RAMBlocks. As first step, introduce the
    list type into which we'll collect the physical mappings in effect at the
    time of the dump.
    
    Related RHBZ: https://bugzilla.redhat.com/show_bug.cgi?id=981582
    
    Signed-off-by: Laszlo Ersek <lersek at redhat.com>
    Signed-off-by: Luiz Capitulino <lcapitulino at redhat.com>

diff --git a/dump.c b/dump.c
index 9a2f939..716fb1d 100644
--- a/dump.c
+++ b/dump.c
@@ -59,6 +59,7 @@ static uint64_t cpu_convert_to_target64(uint64_t val, int endian)
 }
 
 typedef struct DumpState {
+    GuestPhysBlockList guest_phys_blocks;
     ArchDumpInfo dump_info;
     MemoryMappingList list;
     uint16_t phdr_num;
@@ -81,6 +82,7 @@ static int dump_cleanup(DumpState *s)
 {
     int ret = 0;
 
+    guest_phys_blocks_free(&s->guest_phys_blocks);
     memory_mapping_list_free(&s->list);
     if (s->fd != -1) {
         close(s->fd);
@@ -728,31 +730,34 @@ static int dump_init(DumpState *s, int fd, bool paging, bool has_filter,
         s->resume = false;
     }
 
+    /* If we use KVM, we should synchronize the registers before we get dump
+     * info or physmap info.
+     */
+    cpu_synchronize_all_states();
+    nr_cpus = 0;
+    for (cpu = first_cpu; cpu != NULL; cpu = cpu->next_cpu) {
+        nr_cpus++;
+    }
+
     s->errp = errp;
     s->fd = fd;
     s->has_filter = has_filter;
     s->begin = begin;
     s->length = length;
+
+    guest_phys_blocks_init(&s->guest_phys_blocks);
+    /* FILL LIST */
+
     s->start = get_start_block(s);
     if (s->start == -1) {
         error_set(errp, QERR_INVALID_PARAMETER, "begin");
         goto cleanup;
     }
 
-    /*
-     * get dump info: endian, class and architecture.
+    /* get dump info: endian, class and architecture.
      * If the target architecture is not supported, cpu_get_dump_info() will
      * return -1.
-     *
-     * If we use KVM, we should synchronize the registers before we get dump
-     * info.
      */
-    cpu_synchronize_all_states();
-    nr_cpus = 0;
-    for (cpu = first_cpu; cpu != NULL; cpu = cpu->next_cpu) {
-        nr_cpus++;
-    }
-
     ret = cpu_get_dump_info(&s->dump_info);
     if (ret < 0) {
         error_set(errp, QERR_UNSUPPORTED);
@@ -827,6 +832,8 @@ static int dump_init(DumpState *s, int fd, bool paging, bool has_filter,
     return 0;
 
 cleanup:
+    guest_phys_blocks_free(&s->guest_phys_blocks);
+
     if (s->resume) {
         vm_start();
     }
@@ -874,7 +881,7 @@ void qmp_dump_guest_memory(bool paging, const char *file, bool has_begin,
         return;
     }
 
-    s = g_malloc(sizeof(DumpState));
+    s = g_malloc0(sizeof(DumpState));
 
     ret = dump_init(s, fd, paging, has_begin, begin, length, errp);
     if (ret < 0) {
diff --git a/include/sysemu/memory_mapping.h b/include/sysemu/memory_mapping.h
index 6dfb68d..d2d06cd 100644
--- a/include/sysemu/memory_mapping.h
+++ b/include/sysemu/memory_mapping.h
@@ -17,6 +17,25 @@
 #include "qemu/queue.h"
 #include "qemu/typedefs.h"
 
+typedef struct GuestPhysBlock {
+    /* visible to guest, reflects PCI hole, etc */
+    hwaddr target_start;
+
+    /* implies size */
+    hwaddr target_end;
+
+    /* points into host memory */
+    uint8_t *host_addr;
+
+    QTAILQ_ENTRY(GuestPhysBlock) next;
+} GuestPhysBlock;
+
+/* point-in-time snapshot of guest-visible physical mappings */
+typedef struct GuestPhysBlockList {
+    unsigned num;
+    QTAILQ_HEAD(GuestPhysBlockHead, GuestPhysBlock) head;
+} GuestPhysBlockList;
+
 /* The physical and virtual address in the memory mapping are contiguous. */
 typedef struct MemoryMapping {
     hwaddr phys_addr;
@@ -45,6 +64,9 @@ void memory_mapping_list_free(MemoryMappingList *list);
 
 void memory_mapping_list_init(MemoryMappingList *list);
 
+void guest_phys_blocks_free(GuestPhysBlockList *list);
+void guest_phys_blocks_init(GuestPhysBlockList *list);
+
 void qemu_get_guest_memory_mapping(MemoryMappingList *list, Error **errp);
 
 /* get guest's memory mapping without do paging(virtual address is 0). */
diff --git a/memory_mapping.c b/memory_mapping.c
index 515a984..c70505b 100644
--- a/memory_mapping.c
+++ b/memory_mapping.c
@@ -165,6 +165,23 @@ void memory_mapping_list_init(MemoryMappingList *list)
     QTAILQ_INIT(&list->head);
 }
 
+void guest_phys_blocks_free(GuestPhysBlockList *list)
+{
+    GuestPhysBlock *p, *q;
+
+    QTAILQ_FOREACH_SAFE(p, &list->head, next, q) {
+        QTAILQ_REMOVE(&list->head, p, next);
+        g_free(p);
+    }
+    list->num = 0;
+}
+
+void guest_phys_blocks_init(GuestPhysBlockList *list)
+{
+    list->num = 0;
+    QTAILQ_INIT(&list->head);
+}
+
 static CPUState *find_paging_enabled_cpu(CPUState *start_cpu)
 {
     CPUState *cpu;
commit 2cac260768b9d4253737417ea7501cf2950e257f
Author: Laszlo Ersek <lersek at redhat.com>
Date:   Tue Aug 6 12:37:08 2013 +0200

    dump: clamp guest-provided mapping lengths to ramblock sizes
    
    Even a trusted & clean-state guest can map more memory than what it was
    given. Since the vmcore contains RAMBlocks, mapping sizes should be
    clamped to RAMBlock sizes. Otherwise such oversized mappings can exceed
    the entire file size, and ELF parsers might refuse even the valid portion
    of the PT_LOAD entry.
    
    Related RHBZ: https://bugzilla.redhat.com/show_bug.cgi?id=981582
    
    Signed-off-by: Laszlo Ersek <lersek at redhat.com>
    Signed-off-by: Luiz Capitulino <lcapitulino at redhat.com>

diff --git a/dump.c b/dump.c
index 6a3a72a..9a2f939 100644
--- a/dump.c
+++ b/dump.c
@@ -187,7 +187,8 @@ static int write_elf32_header(DumpState *s)
 }
 
 static int write_elf64_load(DumpState *s, MemoryMapping *memory_mapping,
-                            int phdr_index, hwaddr offset)
+                            int phdr_index, hwaddr offset,
+                            hwaddr filesz)
 {
     Elf64_Phdr phdr;
     int ret;
@@ -197,15 +198,12 @@ static int write_elf64_load(DumpState *s, MemoryMapping *memory_mapping,
     phdr.p_type = cpu_convert_to_target32(PT_LOAD, endian);
     phdr.p_offset = cpu_convert_to_target64(offset, endian);
     phdr.p_paddr = cpu_convert_to_target64(memory_mapping->phys_addr, endian);
-    if (offset == -1) {
-        /* When the memory is not stored into vmcore, offset will be -1 */
-        phdr.p_filesz = 0;
-    } else {
-        phdr.p_filesz = cpu_convert_to_target64(memory_mapping->length, endian);
-    }
+    phdr.p_filesz = cpu_convert_to_target64(filesz, endian);
     phdr.p_memsz = cpu_convert_to_target64(memory_mapping->length, endian);
     phdr.p_vaddr = cpu_convert_to_target64(memory_mapping->virt_addr, endian);
 
+    assert(memory_mapping->length >= filesz);
+
     ret = fd_write_vmcore(&phdr, sizeof(Elf64_Phdr), s);
     if (ret < 0) {
         dump_error(s, "dump: failed to write program header table.\n");
@@ -216,7 +214,8 @@ static int write_elf64_load(DumpState *s, MemoryMapping *memory_mapping,
 }
 
 static int write_elf32_load(DumpState *s, MemoryMapping *memory_mapping,
-                            int phdr_index, hwaddr offset)
+                            int phdr_index, hwaddr offset,
+                            hwaddr filesz)
 {
     Elf32_Phdr phdr;
     int ret;
@@ -226,15 +225,12 @@ static int write_elf32_load(DumpState *s, MemoryMapping *memory_mapping,
     phdr.p_type = cpu_convert_to_target32(PT_LOAD, endian);
     phdr.p_offset = cpu_convert_to_target32(offset, endian);
     phdr.p_paddr = cpu_convert_to_target32(memory_mapping->phys_addr, endian);
-    if (offset == -1) {
-        /* When the memory is not stored into vmcore, offset will be -1 */
-        phdr.p_filesz = 0;
-    } else {
-        phdr.p_filesz = cpu_convert_to_target32(memory_mapping->length, endian);
-    }
+    phdr.p_filesz = cpu_convert_to_target32(filesz, endian);
     phdr.p_memsz = cpu_convert_to_target32(memory_mapping->length, endian);
     phdr.p_vaddr = cpu_convert_to_target32(memory_mapping->virt_addr, endian);
 
+    assert(memory_mapping->length >= filesz);
+
     ret = fd_write_vmcore(&phdr, sizeof(Elf32_Phdr), s);
     if (ret < 0) {
         dump_error(s, "dump: failed to write program header table.\n");
@@ -418,17 +414,24 @@ static int write_memory(DumpState *s, RAMBlock *block, ram_addr_t start,
     return 0;
 }
 
-/* get the memory's offset in the vmcore */
-static hwaddr get_offset(hwaddr phys_addr,
-                                     DumpState *s)
+/* get the memory's offset and size in the vmcore */
+static void get_offset_range(hwaddr phys_addr,
+                             ram_addr_t mapping_length,
+                             DumpState *s,
+                             hwaddr *p_offset,
+                             hwaddr *p_filesz)
 {
     RAMBlock *block;
     hwaddr offset = s->memory_offset;
     int64_t size_in_block, start;
 
+    /* When the memory is not stored into vmcore, offset will be -1 */
+    *p_offset = -1;
+    *p_filesz = 0;
+
     if (s->has_filter) {
         if (phys_addr < s->begin || phys_addr >= s->begin + s->length) {
-            return -1;
+            return;
         }
     }
 
@@ -457,18 +460,26 @@ static hwaddr get_offset(hwaddr phys_addr,
         }
 
         if (phys_addr >= start && phys_addr < start + size_in_block) {
-            return phys_addr - start + offset;
+            *p_offset = phys_addr - start + offset;
+
+            /* The offset range mapped from the vmcore file must not spill over
+             * the RAMBlock, clamp it. The rest of the mapping will be
+             * zero-filled in memory at load time; see
+             * <http://refspecs.linuxbase.org/elf/gabi4+/ch5.pheader.html>.
+             */
+            *p_filesz = phys_addr + mapping_length <= start + size_in_block ?
+                        mapping_length :
+                        size_in_block - (phys_addr - start);
+            return;
         }
 
         offset += size_in_block;
     }
-
-    return -1;
 }
 
 static int write_elf_loads(DumpState *s)
 {
-    hwaddr offset;
+    hwaddr offset, filesz;
     MemoryMapping *memory_mapping;
     uint32_t phdr_index = 1;
     int ret;
@@ -481,11 +492,15 @@ static int write_elf_loads(DumpState *s)
     }
 
     QTAILQ_FOREACH(memory_mapping, &s->list.head, next) {
-        offset = get_offset(memory_mapping->phys_addr, s);
+        get_offset_range(memory_mapping->phys_addr,
+                         memory_mapping->length,
+                         s, &offset, &filesz);
         if (s->dump_info.d_class == ELFCLASS64) {
-            ret = write_elf64_load(s, memory_mapping, phdr_index++, offset);
+            ret = write_elf64_load(s, memory_mapping, phdr_index++, offset,
+                                   filesz);
         } else {
-            ret = write_elf32_load(s, memory_mapping, phdr_index++, offset);
+            ret = write_elf32_load(s, memory_mapping, phdr_index++, offset,
+                                   filesz);
         }
 
         if (ret < 0) {
commit dad5b9ea0895c227bc9d48b7f0a6fa51eaaa8661
Author: Gerd Hoffmann <kraxel at redhat.com>
Date:   Thu Aug 1 15:51:08 2013 +0200

    xhci: implement warm port reset
    
    Without this patch windows can't do port resets for usb3 devices.
    
    https://bugzilla.redhat.com/show_bug.cgi?id=949514
    
    Signed-off-by: Gerd Hoffmann <kraxel at redhat.com>

diff --git a/hw/usb/hcd-xhci.c b/hw/usb/hcd-xhci.c
index ff5f681..58c88b8 100644
--- a/hw/usb/hcd-xhci.c
+++ b/hw/usb/hcd-xhci.c
@@ -2672,7 +2672,7 @@ static void xhci_port_update(XHCIPort *port, int is_detach)
     xhci_port_notify(port, PORTSC_CSC);
 }
 
-static void xhci_port_reset(XHCIPort *port)
+static void xhci_port_reset(XHCIPort *port, bool warm_reset)
 {
     trace_usb_xhci_port_reset(port->portnr);
 
@@ -2683,6 +2683,11 @@ static void xhci_port_reset(XHCIPort *port)
     usb_device_reset(port->uport->dev);
 
     switch (port->uport->dev->speed) {
+    case USB_SPEED_SUPER:
+        if (warm_reset) {
+            port->portsc |= PORTSC_WRC;
+        }
+        /* fall through */
     case USB_SPEED_LOW:
     case USB_SPEED_FULL:
     case USB_SPEED_HIGH:
@@ -2845,8 +2850,12 @@ static void xhci_port_write(void *ptr, hwaddr reg,
     switch (reg) {
     case 0x00: /* PORTSC */
         /* write-1-to-start bits */
+        if (val & PORTSC_WPR) {
+            xhci_port_reset(port, true);
+            break;
+        }
         if (val & PORTSC_PR) {
-            xhci_port_reset(port);
+            xhci_port_reset(port, false);
             break;
         }
 
commit 9b9734ef820d9035ac5d254e2b5962cd0b89f4e1
Author: Anthony Liguori <aliguori at us.ibm.com>
Date:   Wed Aug 7 15:38:31 2013 -0500

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

diff --git a/VERSION b/VERSION
index 80b2369..fc7c9a4 100644
--- a/VERSION
+++ b/VERSION
@@ -1 +1 @@
-1.5.91
+1.5.92
commit 6fdf98f281f85ae6e2883bed2f691bcfe33b1f9f
Author: Paolo Bonzini <pbonzini at redhat.com>
Date:   Sun Jul 28 14:35:54 2013 +0200

    fw_cfg: the I/O port variant expects little-endian
    
    The I/O port variant of fw_cfg is used by sparc64, which is a big-endian machine.
    Firmware swaps bytes before sending them to fw_cfg, so we need to unswap them in
    the device.
    
    This is only used on sparc64 and on (little-endian) x86, so it does not affect
    any other target.  32-bit Sparc and PPC all use memory-mapped fw_cfg.
    
    Reported-by: Mark Cave-Ayland <mark.cave-ayland at ilande.co.uk>
    Signed-off-by: Paolo Bonzini <pbonzini at redhat.com>
    Reviewed-by: Laszlo Ersek <lersek at redhat.com>
    Tested-by: Mark Cave-Ayland <mark.cave-ayland at ilande.co.uk>
    Message-id: 1375014954-31916-2-git-send-email-pbonzini at redhat.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 0a35015..d0820e5 100644
--- a/hw/nvram/fw_cfg.c
+++ b/hw/nvram/fw_cfg.c
@@ -324,7 +324,7 @@ static const MemoryRegionOps fw_cfg_data_mem_ops = {
 static const MemoryRegionOps fw_cfg_comb_mem_ops = {
     .read = fw_cfg_comb_read,
     .write = fw_cfg_comb_write,
-    .endianness = DEVICE_NATIVE_ENDIAN,
+    .endianness = DEVICE_LITTLE_ENDIAN,
     .valid.accepts = fw_cfg_comb_valid,
 };
 
commit e9a72359a54978f7364f6486973cea50ceb52173
Author: Stefan Weil <sw at weilnetz.de>
Date:   Mon Aug 5 21:45:22 2013 +0200

    po: Update all *.po files
    
    Running "make install" modified the *.po files because
    they were no longer up to date.
    
    Synchronize them with latest ui/gtk.c and modified build
    rules which use paths relative to the project root.
    
    Signed-off-by: Stefan Weil <sw at weilnetz.de>
    Message-id: 1375731922-24259-1-git-send-email-sw at weilnetz.de
    Signed-off-by: Anthony Liguori <aliguori at us.ibm.com>

diff --git a/po/de_DE.po b/po/de_DE.po
index e35aaf4..fcbde95 100644
--- a/po/de_DE.po
+++ b/po/de_DE.po
@@ -6,7 +6,7 @@ msgid ""
 msgstr ""
 "Project-Id-Version: QEMU 1.4.50\n"
 "Report-Msgid-Bugs-To: qemu-devel at nongnu.org\n"
-"POT-Creation-Date: 2013-03-31 20:42+0200\n"
+"POT-Creation-Date: 2013-07-05 22:36+0200\n"
 "PO-Revision-Date: 2012-02-28 16:00+0100\n"
 "Last-Translator: Kevin Wolf <kwolf at redhat.com>\n"
 "Language-Team: Deutsch <de at li.org>\n"
@@ -16,49 +16,49 @@ msgstr ""
 "Content-Transfer-Encoding: 8bit\n"
 "Plural-Forms: nplurals=2; plural=(n!=1);\n"
 
-#: ../ui/gtk.c:213
+#: ui/gtk.c:214
 msgid " - Press Ctrl+Alt+G to release grab"
 msgstr " - Strg+Alt+G drücken, um Eingabegeräte freizugeben"
 
-#: ../ui/gtk.c:217
+#: ui/gtk.c:218
 msgid " [Paused]"
 msgstr " [Angehalten]"
 
-#: ../ui/gtk.c:1250
-msgid "_Machine"
-msgstr "_Maschine"
-
-#: ../ui/gtk.c:1252
+#: ui/gtk.c:1318
 msgid "_Pause"
 msgstr "_Angehalten"
 
-#: ../ui/gtk.c:1258
+#: ui/gtk.c:1324
 msgid "_Reset"
 msgstr "_Reset"
 
-#: ../ui/gtk.c:1261
+#: ui/gtk.c:1327
 msgid "Power _Down"
 msgstr "_Herunterfahren"
 
-#: ../ui/gtk.c:1276
-msgid "_View"
-msgstr "_Ansicht"
-
-#: ../ui/gtk.c:1306
+#: ui/gtk.c:1381
 msgid "Zoom To _Fit"
 msgstr "Auf _Fenstergröße skalieren"
 
-#: ../ui/gtk.c:1312
+#: ui/gtk.c:1387
 msgid "Grab On _Hover"
 msgstr "Tastatur _automatisch einfangen"
 
-#: ../ui/gtk.c:1315
+#: ui/gtk.c:1390
 msgid "_Grab Input"
 msgstr "_Eingabegeräte einfangen"
 
-#: ../ui/gtk.c:1341
+#: ui/gtk.c:1416
 msgid "Show _Tabs"
 msgstr "_Tableiste anzeigen"
 
+#: ui/gtk.c:1430
+msgid "_Machine"
+msgstr "_Maschine"
+
+#: ui/gtk.c:1435
+msgid "_View"
+msgstr "_Ansicht"
+
 #~ msgid "_File"
 #~ msgstr "_Datei"
diff --git a/po/fr_FR.po b/po/fr_FR.po
index 27d8636..45b2c01 100644
--- a/po/fr_FR.po
+++ b/po/fr_FR.po
@@ -6,7 +6,7 @@ msgid ""
 msgstr ""
 "Project-Id-Version: QEMU 1.4.50\n"
 "Report-Msgid-Bugs-To: qemu-devel at nongnu.org\n"
-"POT-Creation-Date: 2013-03-31 20:42+0200\n"
+"POT-Creation-Date: 2013-07-05 22:36+0200\n"
 "PO-Revision-Date: 2013-03-31 19:39+0200\n"
 "Last-Translator: Aurelien Jarno <aurelien at aurel32.net>\n"
 "Language-Team: French <FR at li.org>\n"
@@ -17,46 +17,46 @@ msgstr ""
 "Plural-Forms: nplurals=2; plural=n != 1;\n"
 "X-Generator: Lokalize 1.4\n"
 
-#: ../ui/gtk.c:213
+#: ui/gtk.c:214
 msgid " - Press Ctrl+Alt+G to release grab"
 msgstr "- Appuyer sur Ctrl+Alt+G pour arrêter la capture"
 
-#: ../ui/gtk.c:217
+#: ui/gtk.c:218
 msgid " [Paused]"
 msgstr " [En pause]"
 
-#: ../ui/gtk.c:1250
-msgid "_Machine"
-msgstr "_Machine"
-
-#: ../ui/gtk.c:1252
+#: ui/gtk.c:1318
 msgid "_Pause"
 msgstr "_Pause"
 
-#: ../ui/gtk.c:1258
+#: ui/gtk.c:1324
 msgid "_Reset"
 msgstr "_Réinitialiser"
 
-#: ../ui/gtk.c:1261
+#: ui/gtk.c:1327
 msgid "Power _Down"
 msgstr "_Éteindre"
 
-#: ../ui/gtk.c:1276
-msgid "_View"
-msgstr "_Vue"
-
-#: ../ui/gtk.c:1306
+#: ui/gtk.c:1381
 msgid "Zoom To _Fit"
 msgstr "Zoomer pour _ajuster"
 
-#: ../ui/gtk.c:1312
+#: ui/gtk.c:1387
 msgid "Grab On _Hover"
 msgstr "Capturer en _survolant"
 
-#: ../ui/gtk.c:1315
+#: ui/gtk.c:1390
 msgid "_Grab Input"
 msgstr "_Capturer les entrées"
 
-#: ../ui/gtk.c:1341
+#: ui/gtk.c:1416
 msgid "Show _Tabs"
 msgstr "Montrer les _onglets"
+
+#: ui/gtk.c:1430
+msgid "_Machine"
+msgstr "_Machine"
+
+#: ui/gtk.c:1435
+msgid "_View"
+msgstr "_Vue"
diff --git a/po/hu.po b/po/hu.po
index debba96..0a44c66 100644
--- a/po/hu.po
+++ b/po/hu.po
@@ -6,7 +6,7 @@ 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"
+"POT-Creation-Date: 2013-07-05 22:36+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"
@@ -15,49 +15,49 @@ msgstr ""
 "Content-Type: text/plain; charset=UTF-8\n"
 "Content-Transfer-Encoding: 8bit\n"
 
-#: ../ui/gtk.c:213
+#: ui/gtk.c:214
 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
+#: ui/gtk.c:218
 msgid " [Paused]"
 msgstr " [Megállítva]"
 
-#: ../ui/gtk.c:1250
-msgid "_Machine"
-msgstr "_Gép"
-
-#: ../ui/gtk.c:1252
+#: ui/gtk.c:1318
 msgid "_Pause"
 msgstr "_Megállítás"
 
-#: ../ui/gtk.c:1258
+#: ui/gtk.c:1324
 msgid "_Reset"
 msgstr "Új_raindítás"
 
-#: ../ui/gtk.c:1261
+#: ui/gtk.c:1327
 msgid "Power _Down"
 msgstr "_Leállítás"
 
-#: ../ui/gtk.c:1276
-msgid "_View"
-msgstr "_Nézet"
-
-#: ../ui/gtk.c:1306
+#: ui/gtk.c:1381
 msgid "Zoom To _Fit"
 msgstr "Ablakmérethez _igazítás"
 
-#: ../ui/gtk.c:1312
+#: ui/gtk.c:1387
 msgid "Grab On _Hover"
 msgstr "Automatikus _elfogás"
 
-#: ../ui/gtk.c:1315
+#: ui/gtk.c:1390
 msgid "_Grab Input"
 msgstr "_Bemeneti eszközök megragadása"
 
-#: ../ui/gtk.c:1341
+#: ui/gtk.c:1416
 msgid "Show _Tabs"
 msgstr "_Fülek megjelenítése"
 
+#: ui/gtk.c:1430
+msgid "_Machine"
+msgstr "_Gép"
+
+#: ui/gtk.c:1435
+msgid "_View"
+msgstr "_Nézet"
+
 #~ msgid "_File"
 #~ msgstr "_File"
diff --git a/po/it.po b/po/it.po
index 2ace3b0..592d3d8 100644
--- a/po/it.po
+++ b/po/it.po
@@ -6,7 +6,7 @@ msgid ""
 msgstr ""
 "Project-Id-Version: QEMU 1.4.50\n"
 "Report-Msgid-Bugs-To: qemu-devel at nongnu.org\n"
-"POT-Creation-Date: 2013-03-31 20:42+0200\n"
+"POT-Creation-Date: 2013-07-05 22:36+0200\n"
 "PO-Revision-Date: 2012-02-27 08:23+0100\n"
 "Last-Translator: Paolo Bonzini <pbonzini at redhat.com>\n"
 "Language-Team: Italian <it at li.org>\n"
@@ -16,49 +16,49 @@ msgstr ""
 "Content-Transfer-Encoding: 8bit\n"
 "Plural-Forms: nplurals=2; plural=n != 1;\n"
 
-#: ../ui/gtk.c:213
+#: ui/gtk.c:214
 msgid " - Press Ctrl+Alt+G to release grab"
 msgstr ""
 
-#: ../ui/gtk.c:217
+#: ui/gtk.c:218
 msgid " [Paused]"
 msgstr ""
 
-#: ../ui/gtk.c:1250
-msgid "_Machine"
-msgstr ""
-
-#: ../ui/gtk.c:1252
+#: ui/gtk.c:1318
 msgid "_Pause"
 msgstr ""
 
-#: ../ui/gtk.c:1258
+#: ui/gtk.c:1324
 msgid "_Reset"
 msgstr ""
 
-#: ../ui/gtk.c:1261
+#: ui/gtk.c:1327
 msgid "Power _Down"
 msgstr ""
 
-#: ../ui/gtk.c:1276
-msgid "_View"
-msgstr "_Visualizza"
-
-#: ../ui/gtk.c:1306
+#: ui/gtk.c:1381
 msgid "Zoom To _Fit"
 msgstr "Adatta alla _finestra"
 
-#: ../ui/gtk.c:1312
+#: ui/gtk.c:1387
 msgid "Grab On _Hover"
 msgstr "Cattura _automatica input"
 
-#: ../ui/gtk.c:1315
+#: ui/gtk.c:1390
 msgid "_Grab Input"
 msgstr "_Cattura input"
 
-#: ../ui/gtk.c:1341
+#: ui/gtk.c:1416
 msgid "Show _Tabs"
 msgstr "Mostra _tab"
 
+#: ui/gtk.c:1430
+msgid "_Machine"
+msgstr ""
+
+#: ui/gtk.c:1435
+msgid "_View"
+msgstr "_Visualizza"
+
 #~ msgid "_File"
 #~ msgstr "_File"
diff --git a/po/messages.po b/po/messages.po
index 42a3eac..26c76bc 100644
--- a/po/messages.po
+++ b/po/messages.po
@@ -5,57 +5,57 @@
 #, fuzzy
 msgid ""
 msgstr ""
-"Project-Id-Version: QEMU 1.4.50\n"
+"Project-Id-Version: QEMU 1.5.50\n"
 "Report-Msgid-Bugs-To: qemu-devel at nongnu.org\n"
-"POT-Creation-Date: 2013-03-31 20:42+0200\n"
+"POT-Creation-Date: 2013-07-05 22:36+0200\n"
 "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
 "Last-Translator: FULL NAME <EMAIL at ADDRESS>\n"
 "Language-Team: LANGUAGE <LL at li.org>\n"
 "Language: \n"
 "MIME-Version: 1.0\n"
-"Content-Type: text/plain; charset=CHARSET\n"
+"Content-Type: text/plain; charset=UTF-8\n"
 "Content-Transfer-Encoding: 8bit\n"
 
-#: ../ui/gtk.c:213
+#: ui/gtk.c:214
 msgid " - Press Ctrl+Alt+G to release grab"
 msgstr ""
 
-#: ../ui/gtk.c:217
+#: ui/gtk.c:218
 msgid " [Paused]"
 msgstr ""
 
-#: ../ui/gtk.c:1250
-msgid "_Machine"
-msgstr ""
-
-#: ../ui/gtk.c:1252
+#: ui/gtk.c:1318
 msgid "_Pause"
 msgstr ""
 
-#: ../ui/gtk.c:1258
+#: ui/gtk.c:1324
 msgid "_Reset"
 msgstr ""
 
-#: ../ui/gtk.c:1261
+#: ui/gtk.c:1327
 msgid "Power _Down"
 msgstr ""
 
-#: ../ui/gtk.c:1276
-msgid "_View"
-msgstr ""
-
-#: ../ui/gtk.c:1306
+#: ui/gtk.c:1381
 msgid "Zoom To _Fit"
 msgstr ""
 
-#: ../ui/gtk.c:1312
+#: ui/gtk.c:1387
 msgid "Grab On _Hover"
 msgstr ""
 
-#: ../ui/gtk.c:1315
+#: ui/gtk.c:1390
 msgid "_Grab Input"
 msgstr ""
 
-#: ../ui/gtk.c:1341
+#: ui/gtk.c:1416
 msgid "Show _Tabs"
 msgstr ""
+
+#: ui/gtk.c:1430
+msgid "_Machine"
+msgstr ""
+
+#: ui/gtk.c:1435
+msgid "_View"
+msgstr ""
diff --git a/po/tr.po b/po/tr.po
index 4faefbd..d57995a 100644
--- a/po/tr.po
+++ b/po/tr.po
@@ -6,7 +6,7 @@ msgid ""
 msgstr ""
 "Project-Id-Version: QEMU 1.4.50\n"
 "Report-Msgid-Bugs-To: qemu-devel at nongnu.org\n"
-"POT-Creation-Date: 2013-04-22 18:33+0300\n"
+"POT-Creation-Date: 2013-07-05 22:36+0200\n"
 "PO-Revision-Date: 2013-04-22 18:35+0300\n"
 "Last-Translator: Ozan Çağlayan <ozancag at gmail.com>\n"
 "Language-Team: Türkçe <>\n"
@@ -17,46 +17,46 @@ msgstr ""
 "Plural-Forms: nplurals=1; plural=0;\n"
 "X-Generator: Gtranslator 2.91.6\n"
 
-#: ../ui/gtk.c:214
+#: ui/gtk.c:214
 msgid " - Press Ctrl+Alt+G to release grab"
 msgstr " - Yakalamayı durdurmak için Ctrl+Alt+G tuşlarına basın"
 
-#: ../ui/gtk.c:218
+#: ui/gtk.c:218
 msgid " [Paused]"
 msgstr " [Duraklatıldı]"
 
-#: ../ui/gtk.c:1282
-msgid "_Machine"
-msgstr "_Makine"
-
-#: ../ui/gtk.c:1284
+#: ui/gtk.c:1318
 msgid "_Pause"
 msgstr "_Duraklat"
 
-#: ../ui/gtk.c:1290
+#: ui/gtk.c:1324
 msgid "_Reset"
 msgstr "_Sıfırla"
 
-#: ../ui/gtk.c:1293
+#: ui/gtk.c:1327
 msgid "Power _Down"
 msgstr "_Kapat"
 
-#: ../ui/gtk.c:1308
-msgid "_View"
-msgstr "_Görüntüle"
-
-#: ../ui/gtk.c:1338
+#: ui/gtk.c:1381
 msgid "Zoom To _Fit"
 msgstr "Yakınlaş ve Sığ_dır"
 
-#: ../ui/gtk.c:1344
+#: ui/gtk.c:1387
 msgid "Grab On _Hover"
 msgstr "Ü_zerindeyken Yakala"
 
-#: ../ui/gtk.c:1347
+#: ui/gtk.c:1390
 msgid "_Grab Input"
 msgstr "Girdiyi _Yakala"
 
-#: ../ui/gtk.c:1373
+#: ui/gtk.c:1416
 msgid "Show _Tabs"
 msgstr "Se_kmeleri Göster"
+
+#: ui/gtk.c:1430
+msgid "_Machine"
+msgstr "_Makine"
+
+#: ui/gtk.c:1435
+msgid "_View"
+msgstr "_Görüntüle"
commit f71d4c4673d0b2b92bccd46eb06f6c1723d6bb0f
Author: Andreas Färber <afaerber at suse.de>
Date:   Thu Aug 1 03:42:03 2013 +0200

    target-ppc: Add POWER5+ v2.1 CPU model
    
    Let's avoid -cpu host barfing at this PVR.
    Linux recognizes it as "POWER5+ (gs) v2.1".
    
    Signed-off-by: Andreas Färber <afaerber at suse.de>
    Signed-off-by: Andreas Färber <afaerber at suse.de>
    Message-id: 1375321323-29954-5-git-send-email-afaerber at suse.de
    Signed-off-by: Anthony Liguori <aliguori at us.ibm.com>

diff --git a/target-ppc/cpu-models.c b/target-ppc/cpu-models.c
index 81f694c..8dea560 100644
--- a/target-ppc/cpu-models.c
+++ b/target-ppc/cpu-models.c
@@ -1123,6 +1123,8 @@
 #endif
     POWERPC_DEF("POWER5+",       CPU_POWERPC_POWER5P,                POWER5P,
                 "POWER5+")
+    POWERPC_DEF("POWER5+_v2.1",  CPU_POWERPC_POWER5P_v21,            POWER5P,
+                "POWER5+ v2.1")
 #if defined(TODO)
     POWERPC_DEF("POWER6",        CPU_POWERPC_POWER6,                 POWER6,
                 "POWER6")
diff --git a/target-ppc/cpu-models.h b/target-ppc/cpu-models.h
index a79cd1b..d9145d1 100644
--- a/target-ppc/cpu-models.h
+++ b/target-ppc/cpu-models.h
@@ -548,6 +548,7 @@ enum {
      /* XXX: missing 0x003A0201 */
     CPU_POWERPC_POWER5             = 0x003A0203,
     CPU_POWERPC_POWER5P            = 0x003B0000,
+    CPU_POWERPC_POWER5P_v21        = 0x003B0201,
     CPU_POWERPC_POWER6             = 0x003E0000,
     CPU_POWERPC_POWER6_5           = 0x0F000001, /* POWER6 in POWER5 mode */
     CPU_POWERPC_POWER6A            = 0x0F000002,
commit 35ebcb2b7a469739e6452d27379181bfbfc0388d
Author: Andreas Färber <afaerber at suse.de>
Date:   Thu Aug 1 03:42:02 2013 +0200

    target-ppc: Prepare POWER5P CPU family
    
    It is ISA 2.03. Modelled as 970FX minus AltiVec flag.
    
    Cc: Benjamin Herrenschmidt <benh at kernel.crashing.org>
    Cc: Alexey Kardashevskiy <aik at ozlabs.ru>
    Signed-off-by: Andreas Färber <afaerber at suse.de>
    Signed-off-by: Andreas Färber <afaerber at suse.de>
    Message-id: 1375321323-29954-4-git-send-email-afaerber at suse.de
    Signed-off-by: Anthony Liguori <aliguori at us.ibm.com>

diff --git a/target-ppc/cpu-models.c b/target-ppc/cpu-models.c
index eb1e982..81f694c 100644
--- a/target-ppc/cpu-models.c
+++ b/target-ppc/cpu-models.c
@@ -1121,10 +1121,8 @@
     POWERPC_DEF("POWER5",        CPU_POWERPC_POWER5,                 POWER5,
                 "POWER5")
 #endif
-#if defined(TODO)
     POWERPC_DEF("POWER5+",       CPU_POWERPC_POWER5P,                POWER5P,
                 "POWER5+")
-#endif
 #if defined(TODO)
     POWERPC_DEF("POWER6",        CPU_POWERPC_POWER6,                 POWER6,
                 "POWER6")
diff --git a/target-ppc/translate_init.c b/target-ppc/translate_init.c
index b14aec8..13b290c 100644
--- a/target-ppc/translate_init.c
+++ b/target-ppc/translate_init.c
@@ -7023,6 +7023,110 @@ POWERPC_FAMILY(970MP)(ObjectClass *oc, void *data)
                  POWERPC_FLAG_BUS_CLK;
 }
 
+static void init_proc_power5plus(CPUPPCState *env)
+{
+    gen_spr_ne_601(env);
+    gen_spr_7xx(env);
+    /* Time base */
+    gen_tbl(env);
+    /* Hardware implementation registers */
+    /* XXX : not implemented */
+    spr_register(env, SPR_HID0, "HID0",
+                 SPR_NOACCESS, SPR_NOACCESS,
+                 &spr_read_generic, &spr_write_clear,
+                 0x60000000);
+    /* XXX : not implemented */
+    spr_register(env, SPR_HID1, "HID1",
+                 SPR_NOACCESS, SPR_NOACCESS,
+                 &spr_read_generic, &spr_write_generic,
+                 0x00000000);
+    /* XXX : not implemented */
+    spr_register(env, SPR_750FX_HID2, "HID2",
+                 SPR_NOACCESS, SPR_NOACCESS,
+                 &spr_read_generic, &spr_write_generic,
+                 0x00000000);
+    /* XXX : not implemented */
+    spr_register(env, SPR_970_HID5, "HID5",
+                 SPR_NOACCESS, SPR_NOACCESS,
+                 &spr_read_generic, &spr_write_generic,
+                 POWERPC970_HID5_INIT);
+    /* XXX : not implemented */
+    spr_register(env, SPR_L2CR, "L2CR",
+                 SPR_NOACCESS, SPR_NOACCESS,
+                 &spr_read_generic, NULL,
+                 0x00000000);
+    /* Memory management */
+    /* XXX: not correct */
+    gen_low_BATs(env);
+    /* XXX : not implemented */
+    spr_register(env, SPR_MMUCFG, "MMUCFG",
+                 SPR_NOACCESS, SPR_NOACCESS,
+                 &spr_read_generic, SPR_NOACCESS,
+                 0x00000000); /* TOFIX */
+    /* XXX : not implemented */
+    spr_register(env, SPR_MMUCSR0, "MMUCSR0",
+                 SPR_NOACCESS, SPR_NOACCESS,
+                 &spr_read_generic, &spr_write_generic,
+                 0x00000000); /* TOFIX */
+    spr_register(env, SPR_HIOR, "SPR_HIOR",
+                 SPR_NOACCESS, SPR_NOACCESS,
+                 &spr_read_hior, &spr_write_hior,
+                 0x00000000);
+    spr_register(env, SPR_CTRL, "SPR_CTRL",
+                 SPR_NOACCESS, SPR_NOACCESS,
+                 &spr_read_generic, &spr_write_generic,
+                 0x00000000);
+    spr_register(env, SPR_UCTRL, "SPR_UCTRL",
+                 SPR_NOACCESS, SPR_NOACCESS,
+                 &spr_read_generic, &spr_write_generic,
+                 0x00000000);
+    spr_register(env, SPR_VRSAVE, "SPR_VRSAVE",
+                 &spr_read_generic, &spr_write_generic,
+                 &spr_read_generic, &spr_write_generic,
+                 0x00000000);
+#if !defined(CONFIG_USER_ONLY)
+    env->slb_nr = 64;
+#endif
+    init_excp_970(env);
+    env->dcache_line_size = 128;
+    env->icache_line_size = 128;
+    /* Allocate hardware IRQ controller */
+    ppc970_irq_init(env);
+    /* Can't find information on what this should be on reset.  This
+     * value is the one used by 74xx processors. */
+    vscr_init(env, 0x00010000);
+}
+
+POWERPC_FAMILY(POWER5P)(ObjectClass *oc, void *data)
+{
+    DeviceClass *dc = DEVICE_CLASS(oc);
+    PowerPCCPUClass *pcc = POWERPC_CPU_CLASS(oc);
+
+    dc->desc = "POWER5+";
+    pcc->init_proc = init_proc_power5plus;
+    pcc->check_pow = check_pow_970FX;
+    pcc->insns_flags = PPC_INSNS_BASE | PPC_STRING | PPC_MFTB |
+                       PPC_FLOAT | PPC_FLOAT_FSEL | PPC_FLOAT_FRES |
+                       PPC_FLOAT_FSQRT | PPC_FLOAT_FRSQRTE |
+                       PPC_FLOAT_STFIWX |
+                       PPC_CACHE | PPC_CACHE_ICBI | PPC_CACHE_DCBZ |
+                       PPC_MEM_SYNC | PPC_MEM_EIEIO |
+                       PPC_MEM_TLBIE | PPC_MEM_TLBSYNC |
+                       PPC_64B |
+                       PPC_SEGMENT_64B | PPC_SLBI;
+    pcc->msr_mask = 0x800000000204FF36ULL;
+    pcc->mmu_model = POWERPC_MMU_64B;
+#if defined(CONFIG_SOFTMMU)
+    pcc->handle_mmu_fault = ppc_hash64_handle_mmu_fault;
+#endif
+    pcc->excp_model = POWERPC_EXCP_970;
+    pcc->bus_model = PPC_FLAGS_INPUT_970;
+    pcc->bfd_mach = bfd_mach_ppc64;
+    pcc->flags = POWERPC_FLAG_VRE | POWERPC_FLAG_SE |
+                 POWERPC_FLAG_BE | POWERPC_FLAG_PMM |
+                 POWERPC_FLAG_BUS_CLK;
+}
+
 static void init_proc_POWER7 (CPUPPCState *env)
 {
     gen_spr_ne_601(env);
commit 469296f1578e1e7b69c267de39d17134b950b93a
Author: Andreas Färber <afaerber at suse.de>
Date:   Thu Aug 1 03:42:01 2013 +0200

    target-ppc: Turn POWER5gr CPU into alias for POWER5
    
    Signed-off-by: Andreas Färber <afaerber at suse.de>
    Signed-off-by: Andreas Färber <afaerber at suse.de>
    Message-id: 1375321323-29954-3-git-send-email-afaerber at suse.de
    Signed-off-by: Anthony Liguori <aliguori at us.ibm.com>

diff --git a/target-ppc/cpu-models.c b/target-ppc/cpu-models.c
index 1f62f7d..eb1e982 100644
--- a/target-ppc/cpu-models.c
+++ b/target-ppc/cpu-models.c
@@ -1120,8 +1120,6 @@
 #if defined(TODO)
     POWERPC_DEF("POWER5",        CPU_POWERPC_POWER5,                 POWER5,
                 "POWER5")
-    POWERPC_DEF("POWER5gr",      CPU_POWERPC_POWER5GR,               POWER5,
-                "POWER5GR")
 #endif
 #if defined(TODO)
     POWERPC_DEF("POWER5+",       CPU_POWERPC_POWER5P,                POWER5P,
@@ -1389,6 +1387,7 @@ PowerPCCPUAlias ppc_cpu_aliases[] = {
     { "Boxer", "POWER3" },
     { "Dino",  "POWER3" },
     { "POWER3+", "631" },
+    { "POWER5gr", "POWER5" },
     { "POWER5gs", "POWER5+" },
     { "POWER7", "POWER7_v2.3" },
     { "POWER7+", "POWER7+_v2.1" },
diff --git a/target-ppc/cpu-models.h b/target-ppc/cpu-models.h
index ca66d55..a79cd1b 100644
--- a/target-ppc/cpu-models.h
+++ b/target-ppc/cpu-models.h
@@ -547,7 +547,6 @@ enum {
     CPU_POWERPC_POWER4P            = 0x00380000,
      /* XXX: missing 0x003A0201 */
     CPU_POWERPC_POWER5             = 0x003A0203,
-#define CPU_POWERPC_POWER5GR         CPU_POWERPC_POWER5
     CPU_POWERPC_POWER5P            = 0x003B0000,
     CPU_POWERPC_POWER6             = 0x003E0000,
     CPU_POWERPC_POWER6_5           = 0x0F000001, /* POWER6 in POWER5 mode */
commit 171777a4b38a0f6331ae60c2546a5baf84c4b359
Author: Andreas Färber <afaerber at suse.de>
Date:   Thu Aug 1 03:42:00 2013 +0200

    target-ppc: Turn POWER5gs CPU into alias for POWER5+
    
    Signed-off-by: Andreas Färber <afaerber at suse.de>
    Signed-off-by: Andreas Färber <afaerber at suse.de>
    Message-id: 1375321323-29954-2-git-send-email-afaerber at suse.de
    Signed-off-by: Anthony Liguori <aliguori at us.ibm.com>

diff --git a/target-ppc/cpu-models.c b/target-ppc/cpu-models.c
index b5b8f42..1f62f7d 100644
--- a/target-ppc/cpu-models.c
+++ b/target-ppc/cpu-models.c
@@ -1126,8 +1126,6 @@
 #if defined(TODO)
     POWERPC_DEF("POWER5+",       CPU_POWERPC_POWER5P,                POWER5P,
                 "POWER5+")
-    POWERPC_DEF("POWER5gs",      CPU_POWERPC_POWER5GS,               POWER5P,
-                "POWER5GS")
 #endif
 #if defined(TODO)
     POWERPC_DEF("POWER6",        CPU_POWERPC_POWER6,                 POWER6,
@@ -1391,6 +1389,7 @@ PowerPCCPUAlias ppc_cpu_aliases[] = {
     { "Boxer", "POWER3" },
     { "Dino",  "POWER3" },
     { "POWER3+", "631" },
+    { "POWER5gs", "POWER5+" },
     { "POWER7", "POWER7_v2.3" },
     { "POWER7+", "POWER7+_v2.1" },
     { "POWER8", "POWER8_v1.0" },
diff --git a/target-ppc/cpu-models.h b/target-ppc/cpu-models.h
index 58c4ea0..ca66d55 100644
--- a/target-ppc/cpu-models.h
+++ b/target-ppc/cpu-models.h
@@ -549,7 +549,6 @@ enum {
     CPU_POWERPC_POWER5             = 0x003A0203,
 #define CPU_POWERPC_POWER5GR         CPU_POWERPC_POWER5
     CPU_POWERPC_POWER5P            = 0x003B0000,
-#define CPU_POWERPC_POWER5GS         CPU_POWERPC_POWER5P
     CPU_POWERPC_POWER6             = 0x003E0000,
     CPU_POWERPC_POWER6_5           = 0x0F000001, /* POWER6 in POWER5 mode */
     CPU_POWERPC_POWER6A            = 0x0F000002,
commit a7d6b9f084765a834110bb9a2a0329b1a96de792
Author: Andreas Färber <afaerber at suse.de>
Date:   Mon Aug 5 22:59:46 2013 +0200

    target-ppc: Fix POWER7+ model
    
    Commit 03a15a5436ed7723f406f15cc3798aa9991e75b5 claimed to add a POWER7+
    model but instead added a "POWER7P" model, with an unhelpful "POWER7P"
    description on top. Fix this to "POWER7+" as we already have "POWER3+",
    "POWER4+" and "POWER5+" and there being no reason to deviate with the
    user-visible command line -cpu POWER7P from the marketing name POWER7+.
    
    Further, don't needlessly deviate from the scheme of naming PVR constant,
    QOM type and device description after the exact revision that is in fact
    encoded in the PVR used.
    That way, we can change the user-friendly alias -cpu POWER7+ to point to a
    different revision if we so desire, while not polluting the type namespace.
    
    This naming scheme is sensible and completely orthogonal to how PVRs may
    or may not get matched to CPU types.
    
    Cc: Alexey Kardashevskiy <aik at ozlabs.ru>
    Signed-off-by: Andreas Färber <afaerber at suse.de>
    Signed-off-by: Andreas Färber <afaerber at suse.de>
    Message-id: 1375736387-8429-1-git-send-email-afaerber at suse.de
    Signed-off-by: Anthony Liguori <aliguori at us.ibm.com>

diff --git a/target-ppc/cpu-models.c b/target-ppc/cpu-models.c
index c97c183..b5b8f42 100644
--- a/target-ppc/cpu-models.c
+++ b/target-ppc/cpu-models.c
@@ -1143,8 +1143,8 @@
                 "POWER7 v2.1")
     POWERPC_DEF("POWER7_v2.3",   CPU_POWERPC_POWER7_v23,             POWER7,
                 "POWER7 v2.3")
-    POWERPC_DEF("POWER7P",       CPU_POWERPC_POWER7P,                POWER7,
-                "POWER7P")
+    POWERPC_DEF("POWER7+_v2.1",  CPU_POWERPC_POWER7P_v21,            POWER7,
+                "POWER7+ v2.1")
     POWERPC_DEF("POWER8_v1.0",   CPU_POWERPC_POWER8_v10,             POWER8,
                 "POWER8 v1.0")
     POWERPC_DEF("970",           CPU_POWERPC_970,                    970,
@@ -1392,6 +1392,7 @@ PowerPCCPUAlias ppc_cpu_aliases[] = {
     { "Dino",  "POWER3" },
     { "POWER3+", "631" },
     { "POWER7", "POWER7_v2.3" },
+    { "POWER7+", "POWER7+_v2.1" },
     { "POWER8", "POWER8_v1.0" },
     { "970fx", "970fx_v3.1" },
     { "970mp", "970mp_v1.1" },
diff --git a/target-ppc/cpu-models.h b/target-ppc/cpu-models.h
index c3c78d1..58c4ea0 100644
--- a/target-ppc/cpu-models.h
+++ b/target-ppc/cpu-models.h
@@ -556,7 +556,7 @@ enum {
     CPU_POWERPC_POWER7_v20         = 0x003F0200,
     CPU_POWERPC_POWER7_v21         = 0x003F0201,
     CPU_POWERPC_POWER7_v23         = 0x003F0203,
-    CPU_POWERPC_POWER7P            = 0x004A0201,
+    CPU_POWERPC_POWER7P_v21        = 0x004A0201,
     CPU_POWERPC_POWER8_v10         = 0x004B0100,
     CPU_POWERPC_970                = 0x00390202,
     CPU_POWERPC_970FX_v10          = 0x00391100,
commit 0dd5ce38fbeb2fb97b01cc8c1c97292211e48ee6
Author: Martijn van den Broek <martijn.vdbrk at gmail.com>
Date:   Tue Aug 6 20:45:39 2013 +0200

    Bugfix for loading multiboot kernels
    
    This patch fixes a bug in rom_copy introduced by
    commit d60fa42e8bae39440f997ebfe8fe328269a57d16.
    
    rom_copy failed to load roms with a "datasize" of 0.
    As a result, multiboot kernels were not loaded correctly
    when they contain a segment with a "file size" of 0.
    
    https://bugs.launchpad.net/qemu/+bug/1208944
    
    Signed-off-by: Martijn van den Broek <martijn.vdbrk at gmail.com>
    Reviewed-by: Paolo Bonzini <pbonzini at redhat.com>
    Message-id: CAG1x_oET1u3TMPu3r_zzd3ZXsTWQLiaM0zAc+RkHFCwvJjGOvg at mail.gmail.com
    Signed-off-by: Anthony Liguori <aliguori at us.ibm.com>

diff --git a/hw/core/loader.c b/hw/core/loader.c
index c3c28cf..6875b7e 100644
--- a/hw/core/loader.c
+++ b/hw/core/loader.c
@@ -814,9 +814,6 @@ int rom_copy(uint8_t *dest, hwaddr addr, size_t size)
         if (rom->addr > end) {
             break;
         }
-        if (!rom->data) {
-            continue;
-        }
 
         d = dest + (rom->addr - addr);
         s = rom->data;
@@ -826,7 +823,9 @@ int rom_copy(uint8_t *dest, hwaddr addr, size_t size)
             l = dest - d;
         }
 
-        memcpy(d, s, l);
+        if (l > 0) {
+            memcpy(d, s, l);
+        }
 
         if (rom->romsize > rom->datasize) {
             /* If datasize is less than romsize, it means that we didn't
commit 6c0f48f5b6c4cf3e1ec8ec6fa7bfe1b97dc92a9c
Merge: cafffa5 cd7b87f
Author: Anthony Liguori <aliguori at us.ibm.com>
Date:   Wed Aug 7 12:43:34 2013 -0500

    Merge remote-tracking branch 'afaerber/tags/qom-cpu-for-anthony' into staging
    
    QOM CPUState refactorings
    
    * Clean up X86CPU error handling
    
    # gpg: Signature made Tue 06 Aug 2013 01:57:34 PM CDT using RSA key ID 3E7E013F
    # gpg: Can't check signature: public key not found
    
    # By Andreas Färber
    # Via Andreas Färber
    * afaerber/tags/qom-cpu-for-anthony:
      target-i386: Fix X86CPU error handling

commit cafffa545420a2c6dc33f9cb58401c606af59572
Merge: a1fc624 ca8804c
Author: Anthony Liguori <aliguori at us.ibm.com>
Date:   Wed Aug 7 12:43:27 2013 -0500

    Merge remote-tracking branch 'kwolf/for-anthony' into staging
    
    # By Fam Zheng (8) and others
    # Via Kevin Wolf
    * kwolf/for-anthony:
      vmdk: rename num_gtes_per_gte to num_gtes_per_gt
      vmdk: use heap allocation for whole_grain
      vmdk: check l1 size before opening image
      vmdk: check l2 table size when opening
      vmdk: check granularity field in opening
      qemu-iotests: add empty test case for vmdk
      qemu-iotests: add poke_file utility function
      vmdk: use unsigned values for on disk header fields
      vmdk: Make VMDK3Header and VmdkGrainMarker QEMU_PACKED
      sheepdog: add missing .bdrv_has_zero_init
      qemu-iotests: filter QEMU version in monitor banner
      iov: handle EOF in iov_send_recv
      ignore SIGPIPE in qemu-img and qemu-io
      qemu-img: Error out for excess arguments
    
    Message-id: 1375799990-995-1-git-send-email-kwolf at redhat.com
    Signed-off-by: Anthony Liguori <aliguori at us.ibm.com>

commit cd7b87ffe9b6b7b0089ec8c71555f3b942bc6daf
Author: Andreas Färber <afaerber at suse.de>
Date:   Fri Aug 2 18:56:05 2013 +0200

    target-i386: Fix X86CPU error handling
    
    Error **errp argument is not for emitting warnings, it means an error
    has occurred and the caller should not make any assumptions about the
    state of other return values (unless otherwise documented).
    
    Therefore cpu_x86_create() must unref the new X86CPU itself, and
    pc_new_cpu() must check for an Error rather than NULL return value.
    
    While at it, clean up a superfluous NULL check.
    
    Reported-by: Jan Kiszka <jan.kiszka at siemens.com>
    Cc: qemu-stable at nongnu.org
    Cc: 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 a2b9d88..6a0b042 100644
--- a/hw/i386/pc.c
+++ b/hw/i386/pc.c
@@ -912,20 +912,19 @@ static X86CPU *pc_new_cpu(const char *cpu_model, int64_t apic_id,
     X86CPU *cpu;
     Error *local_err = NULL;
 
-    cpu = cpu_x86_create(cpu_model, icc_bridge, errp);
-    if (!cpu) {
-        return cpu;
+    cpu = cpu_x86_create(cpu_model, icc_bridge, &local_err);
+    if (local_err != NULL) {
+        error_propagate(errp, local_err);
+        return NULL;
     }
 
     object_property_set_int(OBJECT(cpu), apic_id, "apic-id", &local_err);
     object_property_set_bool(OBJECT(cpu), true, "realized", &local_err);
 
     if (local_err) {
-        if (cpu != NULL) {
-            object_unref(OBJECT(cpu));
-            cpu = NULL;
-        }
         error_propagate(errp, local_err);
+        object_unref(OBJECT(cpu));
+        cpu = NULL;
     }
     return cpu;
 }
diff --git a/target-i386/cpu.c b/target-i386/cpu.c
index 71ab915..2efbeca 100644
--- a/target-i386/cpu.c
+++ b/target-i386/cpu.c
@@ -1824,7 +1824,11 @@ X86CPU *cpu_x86_create(const char *cpu_model, DeviceState *icc_bridge,
     }
 
 out:
-    error_propagate(errp, error);
+    if (error != NULL) {
+        error_propagate(errp, error);
+        object_unref(OBJECT(cpu));
+        cpu = NULL;
+    }
     g_strfreev(model_pieces);
     return cpu;
 }
commit ca8804ced9fdba7a1925ed81084dfb7a5b6ffa9f
Author: Fam Zheng <famz at redhat.com>
Date:   Tue Aug 6 15:44:55 2013 +0800

    vmdk: rename num_gtes_per_gte to num_gtes_per_gt
    
    num_gtes_per_gte is a historical typo, rename it to a more sensible
    name. It means "number of GrainTableEntries per GrainTable".
    
    Signed-off-by: Fam Zheng <famz at redhat.com>
    Signed-off-by: Kevin Wolf <kwolf at redhat.com>

diff --git a/block/vmdk.c b/block/vmdk.c
index ad0a4f3..346bb5c 100644
--- a/block/vmdk.c
+++ b/block/vmdk.c
@@ -71,7 +71,8 @@ typedef struct {
     uint64_t granularity;
     uint64_t desc_offset;
     uint64_t desc_size;
-    uint32_t num_gtes_per_gte;
+    /* Number of GrainTableEntries per GrainTable */
+    uint32_t num_gtes_per_gt;
     uint64_t rgd_offset;
     uint64_t gd_offset;
     uint64_t grain_offset;
@@ -585,12 +586,12 @@ static int vmdk_open_vmdk4(BlockDriverState *bs,
         return -ENOTSUP;
     }
 
-    if (le32_to_cpu(header.num_gtes_per_gte) > 512) {
+    if (le32_to_cpu(header.num_gtes_per_gt) > 512) {
         error_report("L2 table size too big");
         return -EINVAL;
     }
 
-    l1_entry_sectors = le32_to_cpu(header.num_gtes_per_gte)
+    l1_entry_sectors = le32_to_cpu(header.num_gtes_per_gt)
                         * le64_to_cpu(header.granularity);
     if (l1_entry_sectors == 0) {
         return -EINVAL;
@@ -613,7 +614,7 @@ static int vmdk_open_vmdk4(BlockDriverState *bs,
                           le64_to_cpu(header.gd_offset) << 9,
                           l1_backup_offset,
                           l1_size,
-                          le32_to_cpu(header.num_gtes_per_gte),
+                          le32_to_cpu(header.num_gtes_per_gt),
                           le64_to_cpu(header.granularity),
                           &extent);
     if (ret < 0) {
@@ -1411,12 +1412,12 @@ static int vmdk_create_extent(const char *filename, int64_t filesize,
     header.compressAlgorithm = compress ? VMDK4_COMPRESSION_DEFLATE : 0;
     header.capacity = filesize / 512;
     header.granularity = 128;
-    header.num_gtes_per_gte = 512;
+    header.num_gtes_per_gt = 512;
 
     grains = (filesize / 512 + header.granularity - 1) / header.granularity;
-    gt_size = ((header.num_gtes_per_gte * sizeof(uint32_t)) + 511) >> 9;
+    gt_size = ((header.num_gtes_per_gt * sizeof(uint32_t)) + 511) >> 9;
     gt_count =
-        (grains + header.num_gtes_per_gte - 1) / header.num_gtes_per_gte;
+        (grains + header.num_gtes_per_gt - 1) / header.num_gtes_per_gt;
     gd_size = (gt_count * sizeof(uint32_t) + 511) >> 9;
 
     header.desc_offset = 1;
@@ -1432,7 +1433,7 @@ static int vmdk_create_extent(const char *filename, int64_t filesize,
     header.flags = cpu_to_le32(header.flags);
     header.capacity = cpu_to_le64(header.capacity);
     header.granularity = cpu_to_le64(header.granularity);
-    header.num_gtes_per_gte = cpu_to_le32(header.num_gtes_per_gte);
+    header.num_gtes_per_gt = cpu_to_le32(header.num_gtes_per_gt);
     header.desc_offset = cpu_to_le64(header.desc_offset);
     header.desc_size = cpu_to_le64(header.desc_size);
     header.rgd_offset = cpu_to_le64(header.rgd_offset);
commit bf81507de38fdfa4cb6e9b46fb38691a25cb1499
Author: Fam Zheng <famz at redhat.com>
Date:   Tue Aug 6 15:44:54 2013 +0800

    vmdk: use heap allocation for whole_grain
    
    We should never grow the stack beyond 1 MB, otherwise we'll fall off the
    end.  Thread stacks and coroutine stacks (1 MB) do not grow.
    get_cluster_offset() allocates a big stack offset, it will fail for big
    cluster images, change to heap allocated buffer.
    
    Signed-off-by: Fam Zheng <famz at redhat.com>
    Signed-off-by: Kevin Wolf <kwolf at redhat.com>

diff --git a/block/vmdk.c b/block/vmdk.c
index 955125a..ad0a4f3 100644
--- a/block/vmdk.c
+++ b/block/vmdk.c
@@ -842,16 +842,17 @@ static int get_whole_cluster(BlockDriverState *bs,
                 uint64_t offset,
                 bool allocate)
 {
-    /* 128 sectors * 512 bytes each = grain size 64KB */
-    uint8_t  whole_grain[extent->cluster_sectors * 512];
+    int ret = VMDK_OK;
+    uint8_t *whole_grain = NULL;
 
     /* we will be here if it's first write on non-exist grain(cluster).
      * try to read from parent image, if exist */
     if (bs->backing_hd) {
-        int ret;
-
+        whole_grain =
+            qemu_blockalign(bs, extent->cluster_sectors << BDRV_SECTOR_BITS);
         if (!vmdk_is_cid_valid(bs)) {
-            return VMDK_ERROR;
+            ret = VMDK_ERROR;
+            goto exit;
         }
 
         /* floor offset to cluster */
@@ -859,17 +860,21 @@ static int get_whole_cluster(BlockDriverState *bs,
         ret = bdrv_read(bs->backing_hd, offset >> 9, whole_grain,
                 extent->cluster_sectors);
         if (ret < 0) {
-            return VMDK_ERROR;
+            ret = VMDK_ERROR;
+            goto exit;
         }
 
         /* Write grain only into the active image */
         ret = bdrv_write(extent->file, cluster_offset, whole_grain,
                 extent->cluster_sectors);
         if (ret < 0) {
-            return VMDK_ERROR;
+            ret = VMDK_ERROR;
+            goto exit;
         }
     }
-    return VMDK_OK;
+exit:
+    qemu_vfree(whole_grain);
+    return ret;
 }
 
 static int vmdk_L2update(VmdkExtent *extent, VmdkMetaData *m_data)
commit 2c43e43c8cec130fff95ef720a860e91efb36685
Author: Fam Zheng <famz at redhat.com>
Date:   Tue Aug 6 15:44:53 2013 +0800

    vmdk: check l1 size before opening image
    
    L1 table size is calculated from capacity, granularity and l2 table
    size. If capacity is too big or later two are too small, the L1 table
    will be too big to allocate in memory. Limit it to a reasonable range.
    
    Signed-off-by: Fam Zheng <famz at redhat.com>
    Signed-off-by: Kevin Wolf <kwolf at redhat.com>

diff --git a/block/vmdk.c b/block/vmdk.c
index 53020ef..955125a 100644
--- a/block/vmdk.c
+++ b/block/vmdk.c
@@ -597,6 +597,14 @@ static int vmdk_open_vmdk4(BlockDriverState *bs,
     }
     l1_size = (le64_to_cpu(header.capacity) + l1_entry_sectors - 1)
                 / l1_entry_sectors;
+    if (l1_size > 512 * 1024 * 1024) {
+        /* although with big capacity and small l1_entry_sectors, we can get a
+         * big l1_size, we don't want unbounded value to allocate the table.
+         * Limit it to 512M, which is 16PB for default cluster and L2 table
+         * size */
+        error_report("L1 size too big");
+        return -EFBIG;
+    }
     if (le32_to_cpu(header.flags) & VMDK4_FLAG_RGD) {
         l1_backup_offset = le64_to_cpu(header.rgd_offset) << 9;
     }
diff --git a/tests/qemu-iotests/059 b/tests/qemu-iotests/059
index 301eaca..b03429d 100755
--- a/tests/qemu-iotests/059
+++ b/tests/qemu-iotests/059
@@ -43,6 +43,7 @@ _supported_fmt vmdk
 _supported_proto generic
 _supported_os Linux
 
+capacity_offset=16
 granularity_offset=20
 grain_table_size_offset=44
 
@@ -58,6 +59,13 @@ _make_test_img 64M
 poke_file "$TEST_IMG" "$grain_table_size_offset" "\xff\xff\xff\xff"
 { $QEMU_IO -c "read 0 512" $TEST_IMG; } 2>&1 | _filter_qemu_io | _filter_testdir
 
+echo "=== Testing too big L1 table size ==="
+echo
+_make_test_img 64M
+poke_file "$TEST_IMG" "$capacity_offset" "\xff\xff\xff\xff"
+poke_file "$TEST_IMG" "$grain_table_size_offset" "\x01\x00\x00\x00"
+{ $QEMU_IO -c "read 0 512" $TEST_IMG; } 2>&1 | _filter_qemu_io | _filter_testdir
+
 # success, all done
 echo "*** done"
 rm -f $seq.full
diff --git a/tests/qemu-iotests/059.out b/tests/qemu-iotests/059.out
index 583955f..9e715e5 100644
--- a/tests/qemu-iotests/059.out
+++ b/tests/qemu-iotests/059.out
@@ -11,4 +11,10 @@ Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=67108864
 L2 table size too big
 qemu-io: can't open device TEST_DIR/t.vmdk
 no file open, try 'help open'
+=== Testing too big L1 table size ===
+
+Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=67108864
+L1 size too big
+qemu-io: can't open device TEST_DIR/t.vmdk
+no file open, try 'help open'
 *** done
commit f8ce04036e333aae480b1d06d969f6436652633d
Author: Fam Zheng <famz at redhat.com>
Date:   Tue Aug 6 15:44:52 2013 +0800

    vmdk: check l2 table size when opening
    
    header.num_gtes_per_gte determines size for L2 table. Check for too big
    value before using it. Limit to 512M entries (2GB per one L2 table).
    
    Signed-off-by: Fam Zheng <famz at redhat.com>
    Signed-off-by: Kevin Wolf <kwolf at redhat.com>

diff --git a/block/vmdk.c b/block/vmdk.c
index 015cbd4..53020ef 100644
--- a/block/vmdk.c
+++ b/block/vmdk.c
@@ -585,6 +585,11 @@ static int vmdk_open_vmdk4(BlockDriverState *bs,
         return -ENOTSUP;
     }
 
+    if (le32_to_cpu(header.num_gtes_per_gte) > 512) {
+        error_report("L2 table size too big");
+        return -EINVAL;
+    }
+
     l1_entry_sectors = le32_to_cpu(header.num_gtes_per_gte)
                         * le64_to_cpu(header.granularity);
     if (l1_entry_sectors == 0) {
diff --git a/tests/qemu-iotests/059 b/tests/qemu-iotests/059
index 9545e82..301eaca 100755
--- a/tests/qemu-iotests/059
+++ b/tests/qemu-iotests/059
@@ -44,6 +44,7 @@ _supported_proto generic
 _supported_os Linux
 
 granularity_offset=20
+grain_table_size_offset=44
 
 echo "=== Testing invalid granularity ==="
 echo
@@ -51,6 +52,12 @@ _make_test_img 64M
 poke_file "$TEST_IMG" "$granularity_offset" "\xff\xff\xff\xff\xff\xff\xff\xff"
 { $QEMU_IO -c "read 0 512" $TEST_IMG; } 2>&1 | _filter_qemu_io | _filter_testdir
 
+echo "=== Testing too big L2 table size ==="
+echo
+_make_test_img 64M
+poke_file "$TEST_IMG" "$grain_table_size_offset" "\xff\xff\xff\xff"
+{ $QEMU_IO -c "read 0 512" $TEST_IMG; } 2>&1 | _filter_qemu_io | _filter_testdir
+
 # success, all done
 echo "*** done"
 rm -f $seq.full
diff --git a/tests/qemu-iotests/059.out b/tests/qemu-iotests/059.out
index 380ca3d..583955f 100644
--- a/tests/qemu-iotests/059.out
+++ b/tests/qemu-iotests/059.out
@@ -5,4 +5,10 @@ Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=67108864
 invalid granularity, image may be corrupt
 qemu-io: can't open device TEST_DIR/t.vmdk
 no file open, try 'help open'
+=== Testing too big L2 table size ===
+
+Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=67108864
+L2 table size too big
+qemu-io: can't open device TEST_DIR/t.vmdk
+no file open, try 'help open'
 *** done
commit 8aa1331c09a9b899f48d97f097bb49b7d458be1c
Author: Fam Zheng <famz at redhat.com>
Date:   Tue Aug 6 15:44:51 2013 +0800

    vmdk: check granularity field in opening
    
    Granularity is used to calculate the cluster size and allocate r/w
    buffer. Check the value from image before using it, so we don't abort()
    for unbounded memory allocation.
    
    Signed-off-by: Fam Zheng <famz at redhat.com>
    Signed-off-by: Kevin Wolf <kwolf at redhat.com>

diff --git a/block/vmdk.c b/block/vmdk.c
index 2c925da..015cbd4 100644
--- a/block/vmdk.c
+++ b/block/vmdk.c
@@ -385,15 +385,22 @@ static int vmdk_parent_open(BlockDriverState *bs)
 
 /* Create and append extent to the extent array. Return the added VmdkExtent
  * address. return NULL if allocation failed. */
-static VmdkExtent *vmdk_add_extent(BlockDriverState *bs,
+static int vmdk_add_extent(BlockDriverState *bs,
                            BlockDriverState *file, bool flat, int64_t sectors,
                            int64_t l1_offset, int64_t l1_backup_offset,
                            uint32_t l1_size,
-                           int l2_size, unsigned int cluster_sectors)
+                           int l2_size, uint64_t cluster_sectors,
+                           VmdkExtent **new_extent)
 {
     VmdkExtent *extent;
     BDRVVmdkState *s = bs->opaque;
 
+    if (cluster_sectors > 0x200000) {
+        /* 0x200000 * 512Bytes = 1GB for one cluster is unrealistic */
+        error_report("invalid granularity, image may be corrupt");
+        return -EINVAL;
+    }
+
     s->extents = g_realloc(s->extents,
                               (s->num_extents + 1) * sizeof(VmdkExtent));
     extent = &s->extents[s->num_extents];
@@ -416,7 +423,10 @@ static VmdkExtent *vmdk_add_extent(BlockDriverState *bs,
         extent->end_sector = extent->sectors;
     }
     bs->total_sectors = extent->end_sector;
-    return extent;
+    if (new_extent) {
+        *new_extent = extent;
+    }
+    return 0;
 }
 
 static int vmdk_init_tables(BlockDriverState *bs, VmdkExtent *extent)
@@ -475,12 +485,17 @@ static int vmdk_open_vmdk3(BlockDriverState *bs,
     if (ret < 0) {
         return ret;
     }
-    extent = vmdk_add_extent(bs,
+
+    ret = vmdk_add_extent(bs,
                              bs->file, false,
                              le32_to_cpu(header.disk_sectors),
                              le32_to_cpu(header.l1dir_offset) << 9,
                              0, 1 << 6, 1 << 9,
-                             le32_to_cpu(header.granularity));
+                             le32_to_cpu(header.granularity),
+                             &extent);
+    if (ret < 0) {
+        return ret;
+    }
     ret = vmdk_init_tables(bs, extent);
     if (ret) {
         /* free extent allocated by vmdk_add_extent */
@@ -580,13 +595,17 @@ static int vmdk_open_vmdk4(BlockDriverState *bs,
     if (le32_to_cpu(header.flags) & VMDK4_FLAG_RGD) {
         l1_backup_offset = le64_to_cpu(header.rgd_offset) << 9;
     }
-    extent = vmdk_add_extent(bs, file, false,
+    ret = vmdk_add_extent(bs, file, false,
                           le64_to_cpu(header.capacity),
                           le64_to_cpu(header.gd_offset) << 9,
                           l1_backup_offset,
                           l1_size,
                           le32_to_cpu(header.num_gtes_per_gte),
-                          le64_to_cpu(header.granularity));
+                          le64_to_cpu(header.granularity),
+                          &extent);
+    if (ret < 0) {
+        return ret;
+    }
     extent->compressed =
         le16_to_cpu(header.compressAlgorithm) == VMDK4_COMPRESSION_DEFLATE;
     extent->has_marker = le32_to_cpu(header.flags) & VMDK4_FLAG_MARKER;
@@ -702,8 +721,11 @@ static int vmdk_parse_extents(const char *desc, BlockDriverState *bs,
             /* FLAT extent */
             VmdkExtent *extent;
 
-            extent = vmdk_add_extent(bs, extent_file, true, sectors,
-                            0, 0, 0, 0, sectors);
+            ret = vmdk_add_extent(bs, extent_file, true, sectors,
+                            0, 0, 0, 0, sectors, &extent);
+            if (ret < 0) {
+                return ret;
+            }
             extent->flat_start_offset = flat_offset << 9;
         } else if (!strcmp(type, "SPARSE")) {
             /* SPARSE extent */
diff --git a/tests/qemu-iotests/059 b/tests/qemu-iotests/059
index 9dc7f64..9545e82 100755
--- a/tests/qemu-iotests/059
+++ b/tests/qemu-iotests/059
@@ -43,7 +43,13 @@ _supported_fmt vmdk
 _supported_proto generic
 _supported_os Linux
 
-granularity_offset=16
+granularity_offset=20
+
+echo "=== Testing invalid granularity ==="
+echo
+_make_test_img 64M
+poke_file "$TEST_IMG" "$granularity_offset" "\xff\xff\xff\xff\xff\xff\xff\xff"
+{ $QEMU_IO -c "read 0 512" $TEST_IMG; } 2>&1 | _filter_qemu_io | _filter_testdir
 
 # success, all done
 echo "*** done"
diff --git a/tests/qemu-iotests/059.out b/tests/qemu-iotests/059.out
index 4ca7f29..380ca3d 100644
--- a/tests/qemu-iotests/059.out
+++ b/tests/qemu-iotests/059.out
@@ -1,2 +1,8 @@
 QA output created by 059
+=== Testing invalid granularity ===
+
+Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=67108864
+invalid granularity, image may be corrupt
+qemu-io: can't open device TEST_DIR/t.vmdk
+no file open, try 'help open'
 *** done
commit ca6cbb657d66a7beb70f9d91848c80d1a72b1674
Author: Fam Zheng <famz at redhat.com>
Date:   Tue Aug 6 15:44:50 2013 +0800

    qemu-iotests: add empty test case for vmdk
    
    Will add vmdk specific tests later here.
    
    Signed-off-by: Fam Zheng <famz at redhat.com>
    Signed-off-by: Kevin Wolf <kwolf at redhat.com>

diff --git a/tests/qemu-iotests/059 b/tests/qemu-iotests/059
new file mode 100755
index 0000000..9dc7f64
--- /dev/null
+++ b/tests/qemu-iotests/059
@@ -0,0 +1,51 @@
+#!/bin/bash
+#
+# Test case for vmdk
+#
+# 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=famz 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
+
+# This tests vmdk-specific low-level functionality
+_supported_fmt vmdk
+_supported_proto generic
+_supported_os Linux
+
+granularity_offset=16
+
+# success, all done
+echo "*** done"
+rm -f $seq.full
+status=0
diff --git a/tests/qemu-iotests/059.out b/tests/qemu-iotests/059.out
new file mode 100644
index 0000000..4ca7f29
--- /dev/null
+++ b/tests/qemu-iotests/059.out
@@ -0,0 +1,2 @@
+QA output created by 059
+*** done
diff --git a/tests/qemu-iotests/group b/tests/qemu-iotests/group
index 69e208c..43c05d6 100644
--- a/tests/qemu-iotests/group
+++ b/tests/qemu-iotests/group
@@ -63,3 +63,4 @@
 054 rw auto
 055 rw auto
 056 rw auto backing
+059 rw auto
commit 23ea2ecc2a43d850bc9482068201ece5da36a448
Author: Stefan Hajnoczi <stefanha at redhat.com>
Date:   Tue Aug 6 15:44:49 2013 +0800

    qemu-iotests: add poke_file utility function
    
    The new poke_file function sets bytes at an offset in a file given a
    printf-style format string.  It can be used to corrupt an image file for
    test coverage of error paths.
    
    Signed-off-by: Stefan Hajnoczi <stefanha at redhat.com>
    Signed-off-by: Kevin Wolf <kwolf at redhat.com>

diff --git a/tests/qemu-iotests/common.rc b/tests/qemu-iotests/common.rc
index e9ba358..5e077c3 100644
--- a/tests/qemu-iotests/common.rc
+++ b/tests/qemu-iotests/common.rc
@@ -34,6 +34,12 @@ dd()
    fi
 }
 
+# poke_file 'test.img' 512 '\xff\xfe'
+poke_file()
+{
+    printf "$3" | dd "of=$1" bs=1 "seek=$2" conv=notrunc &>/dev/null
+}
+
 # we need common.config
 if [ "$iam" != "check" ]
 then
commit e98768d43799cd3f00b358bfbe455fdae793d3e8
Author: Fam Zheng <famz at redhat.com>
Date:   Tue Aug 6 15:44:48 2013 +0800

    vmdk: use unsigned values for on disk header fields
    
    The size and offset fields are all non-negative values, use uint64_t for
    them to avoid getting negative in memory value by int overflow.
    
    Signed-off-by: Fam Zheng <famz at redhat.com>
    Signed-off-by: Kevin Wolf <kwolf at redhat.com>

diff --git a/block/vmdk.c b/block/vmdk.c
index 5c3c240..2c925da 100644
--- a/block/vmdk.c
+++ b/block/vmdk.c
@@ -67,14 +67,14 @@ typedef struct {
 typedef struct {
     uint32_t version;
     uint32_t flags;
-    int64_t capacity;
-    int64_t granularity;
-    int64_t desc_offset;
-    int64_t desc_size;
-    int32_t num_gtes_per_gte;
-    int64_t rgd_offset;
-    int64_t gd_offset;
-    int64_t grain_offset;
+    uint64_t capacity;
+    uint64_t granularity;
+    uint64_t desc_offset;
+    uint64_t desc_size;
+    uint32_t num_gtes_per_gte;
+    uint64_t rgd_offset;
+    uint64_t gd_offset;
+    uint64_t grain_offset;
     char filler[1];
     char check_bytes[4];
     uint16_t compressAlgorithm;
@@ -109,7 +109,7 @@ typedef struct VmdkExtent {
 
 typedef struct BDRVVmdkState {
     CoMutex lock;
-    int desc_offset;
+    uint64_t desc_offset;
     bool cid_updated;
     uint32_t parent_cid;
     int num_extents;
@@ -490,7 +490,7 @@ static int vmdk_open_vmdk3(BlockDriverState *bs,
 }
 
 static int vmdk_open_desc_file(BlockDriverState *bs, int flags,
-                               int64_t desc_offset);
+                               uint64_t desc_offset);
 
 static int vmdk_open_vmdk4(BlockDriverState *bs,
                            BlockDriverState *file,
@@ -508,7 +508,7 @@ static int vmdk_open_vmdk4(BlockDriverState *bs,
         return ret;
     }
     if (header.capacity == 0) {
-        int64_t desc_offset = le64_to_cpu(header.desc_offset);
+        uint64_t desc_offset = le64_to_cpu(header.desc_offset);
         if (desc_offset) {
             return vmdk_open_desc_file(bs, flags, desc_offset << 9);
         }
@@ -728,7 +728,7 @@ next_line:
 }
 
 static int vmdk_open_desc_file(BlockDriverState *bs, int flags,
-                               int64_t desc_offset)
+                               uint64_t desc_offset)
 {
     int ret;
     char *buf = NULL;
commit 5d8caa543c9714bee36b04899797a3721dff4090
Author: Fam Zheng <famz at redhat.com>
Date:   Tue Aug 6 15:44:47 2013 +0800

    vmdk: Make VMDK3Header and VmdkGrainMarker QEMU_PACKED
    
    It's best to make it consistent that all on disk structures are
    QEMU_PACKED.
    
    Signed-off-by: Fam Zheng <famz at redhat.com>
    Signed-off-by: Kevin Wolf <kwolf at redhat.com>

diff --git a/block/vmdk.c b/block/vmdk.c
index e6c50b1..5c3c240 100644
--- a/block/vmdk.c
+++ b/block/vmdk.c
@@ -62,7 +62,7 @@ typedef struct {
     uint32_t cylinders;
     uint32_t heads;
     uint32_t sectors_per_track;
-} VMDK3Header;
+} QEMU_PACKED VMDK3Header;
 
 typedef struct {
     uint32_t version;
@@ -131,7 +131,7 @@ typedef struct VmdkGrainMarker {
     uint64_t lba;
     uint32_t size;
     uint8_t  data[0];
-} VmdkGrainMarker;
+} QEMU_PACKED VmdkGrainMarker;
 
 enum {
     MARKER_END_OF_STREAM    = 0,
commit a1fc6246b3964e74ddb3a7e0b8bba03af1c6ac38
Author: Leon Alrae <leon.alrae at imgtec.com>
Date:   Tue Aug 6 11:59:25 2013 +0100

    target-mips: fix decoding of microMIPS POOL32Axf instructions
    
    Fix incorrect assumption that DSP and non-DSP versions of the following
    instructions have the same encoding:
    MULT, MULTU, MADD, MADDU, MSUB, MSUBU, MFHI, MFLO, MTHI, MTLO.
    Correct the existing (non-DSP) instructions and add DSP equivalents.
    
    Reference:
    MIPS Architecture for Programmers Volume II-B: The microMIPS32
    Instruction Set
    MIPS Architecture for Programmers Volume IV-e: The MIPS DSP Module for
    the microMIPS32 Architecture
    
    Signed-off-by: Leon Alrae <leon.alrae at imgtec.com>
    Signed-off-by: Aurelien Jarno <aurelien at aurel32.net>

diff --git a/target-mips/translate.c b/target-mips/translate.c
index c1d57a7..e2eb908 100644
--- a/target-mips/translate.c
+++ b/target-mips/translate.c
@@ -11061,6 +11061,36 @@ static void gen_pool32axf (CPUMIPSState *env, DisasContext *ctx, int rt, int rs)
         }
         break;
 #endif
+    case 0x2a:
+        switch (minor & 3) {
+        case MADD_ACC:
+            gen_muldiv(ctx, OPC_MADD, (ctx->opcode >> 14) & 3, rs, rt);
+            break;
+        case MADDU_ACC:
+            gen_muldiv(ctx, OPC_MADDU, (ctx->opcode >> 14) & 3, rs, rt);
+            break;
+        case MSUB_ACC:
+            gen_muldiv(ctx, OPC_MSUB, (ctx->opcode >> 14) & 3, rs, rt);
+            break;
+        case MSUBU_ACC:
+            gen_muldiv(ctx, OPC_MSUBU, (ctx->opcode >> 14) & 3, rs, rt);
+            break;
+        default:
+            goto pool32axf_invalid;
+        }
+        break;
+    case 0x32:
+        switch (minor & 3) {
+        case MULT_ACC:
+            gen_muldiv(ctx, OPC_MULT, (ctx->opcode >> 14) & 3, rs, rt);
+            break;
+        case MULTU_ACC:
+            gen_muldiv(ctx, OPC_MULTU, (ctx->opcode >> 14) & 3, rs, rt);
+            break;
+        default:
+            goto pool32axf_invalid;
+        }
+        break;
     case 0x2c:
         switch (minor) {
         case SEB:
@@ -11113,7 +11143,7 @@ static void gen_pool32axf (CPUMIPSState *env, DisasContext *ctx, int rt, int rs)
             mips32_op = OPC_MSUBU;
         do_mul:
             check_insn(ctx, ISA_MIPS32);
-            gen_muldiv(ctx, mips32_op, (ctx->opcode >> 14) & 3, rs, rt);
+            gen_muldiv(ctx, mips32_op, 0, rs, rt);
             break;
         default:
             goto pool32axf_invalid;
@@ -11247,24 +11277,42 @@ static void gen_pool32axf (CPUMIPSState *env, DisasContext *ctx, int rt, int rs)
             goto pool32axf_invalid;
         }
         break;
-    case 0x35:
+    case 0x01:
         switch (minor & 3) {
-        case MFHI32:
+        case MFHI_ACC:
             gen_HILO(ctx, OPC_MFHI, minor >> 2, rs);
             break;
-        case MFLO32:
+        case MFLO_ACC:
             gen_HILO(ctx, OPC_MFLO, minor >> 2, rs);
             break;
-        case MTHI32:
+        case MTHI_ACC:
             gen_HILO(ctx, OPC_MTHI, minor >> 2, rs);
             break;
-        case MTLO32:
+        case MTLO_ACC:
             gen_HILO(ctx, OPC_MTLO, minor >> 2, rs);
             break;
         default:
             goto pool32axf_invalid;
         }
         break;
+    case 0x35:
+        switch (minor) {
+        case MFHI32:
+            gen_HILO(ctx, OPC_MFHI, 0, rs);
+            break;
+        case MFLO32:
+            gen_HILO(ctx, OPC_MFLO, 0, rs);
+            break;
+        case MTHI32:
+            gen_HILO(ctx, OPC_MTHI, 0, rs);
+            break;
+        case MTLO32:
+            gen_HILO(ctx, OPC_MTLO, 0, rs);
+            break;
+        default:
+            goto pool32axf_invalid;
+        }
+        break;
     default:
     pool32axf_invalid:
         MIPS_INVAL("pool32axf");
commit e4f5c1bf8f6f6fe0bb4c743452bf8288033e80ba
Author: Liu Yuan <namei.unix at gmail.com>
Date:   Tue Aug 6 14:44:37 2013 +0800

    sheepdog: add missing .bdrv_has_zero_init
    
    Commit 3ac21627 changed the behaviour of bdrv_has_zero_init() to default
    to 0. In the review for Sheepdog it turned out that enabling it is safe,
    so that commit updated one BlockDriver definition of sheepdog to use
    bdrv_has_zero_init_1, missed however that there are more BlockDrivers in
    the driver. Fix these now.
    
    Cc: Kevin Wolf <kwolf at redhat.com>
    Cc: Stefan Hajnoczi <stefanha at redhat.com>
    Signed-off-by: Liu Yuan <namei.unix at gmail.com>
    Reviewed-by: MORITA Kazutaka <morita.kazutaka at lab.ntt.co.jp>
    Signed-off-by: Kevin Wolf <kwolf at redhat.com>

diff --git a/block/sheepdog.c b/block/sheepdog.c
index a506137..afe0533 100644
--- a/block/sheepdog.c
+++ b/block/sheepdog.c
@@ -2347,6 +2347,7 @@ static BlockDriver bdrv_sheepdog = {
     .bdrv_file_open = sd_open,
     .bdrv_close     = sd_close,
     .bdrv_create    = sd_create,
+    .bdrv_has_zero_init = bdrv_has_zero_init_1,
     .bdrv_getlength = sd_getlength,
     .bdrv_truncate  = sd_truncate,
 
@@ -2374,6 +2375,7 @@ static BlockDriver bdrv_sheepdog_tcp = {
     .bdrv_file_open = sd_open,
     .bdrv_close     = sd_close,
     .bdrv_create    = sd_create,
+    .bdrv_has_zero_init = bdrv_has_zero_init_1,
     .bdrv_getlength = sd_getlength,
     .bdrv_truncate  = sd_truncate,
 
commit 9580498b9a599b38c3a28599dcd40bd59f12af2c
Author: Stefan Hajnoczi <stefanha at redhat.com>
Date:   Mon Aug 5 14:40:34 2013 +0200

    qemu-iotests: filter QEMU version in monitor banner
    
    Filter out the QEMU monitor version banner so that tests do not break
    when the QEMU version number is changed.
    
    Signed-off-by: Stefan Hajnoczi <stefanha at redhat.com>
    Signed-off-by: Kevin Wolf <kwolf at redhat.com>

diff --git a/tests/qemu-iotests/051.out b/tests/qemu-iotests/051.out
index 9588d0c..5582ed3 100644
--- a/tests/qemu-iotests/051.out
+++ b/tests/qemu-iotests/051.out
@@ -23,11 +23,11 @@ QEMU_PROG: -drive file=TEST_DIR/t.qcow2,format=qcow2,unknown_opt=foo: could not
 === Enable and disable lazy refcounting on the command line, plus some invalid values ===
 
 Testing: -drive file=TEST_DIR/t.qcow2,format=qcow2,lazy-refcounts=on
-QEMU 1.5.50 monitor - type 'help' for more information
+QEMU X.Y.Z monitor - type 'help' for more information
 (qemu) qququiquit
 
 Testing: -drive file=TEST_DIR/t.qcow2,format=qcow2,lazy-refcounts=off
-QEMU 1.5.50 monitor - type 'help' for more information
+QEMU X.Y.Z monitor - type 'help' for more information
 (qemu) qququiquit
 
 Testing: -drive file=TEST_DIR/t.qcow2,format=qcow2,lazy-refcounts=
@@ -51,72 +51,72 @@ QEMU_PROG: -drive file=TEST_DIR/t.qcow2,format=qcow2,lazy-refcounts=on: Lazy ref
 QEMU_PROG: -drive file=TEST_DIR/t.qcow2,format=qcow2,lazy-refcounts=on: could not open disk image TEST_DIR/t.qcow2: Invalid argument
 
 Testing: -drive file=TEST_DIR/t.qcow2,format=qcow2,lazy-refcounts=off
-QEMU 1.5.50 monitor - type 'help' for more information
+QEMU X.Y.Z monitor - type 'help' for more information
 (qemu) qququiquit
 
 
 === No medium ===
 
 Testing: -drive if=floppy
-QEMU 1.5.50 monitor - type 'help' for more information
+QEMU X.Y.Z monitor - type 'help' for more information
 (qemu) qququiquit
 
 Testing: -drive if=ide,media=cdrom
-QEMU 1.5.50 monitor - type 'help' for more information
+QEMU X.Y.Z monitor - type 'help' for more information
 (qemu) qququiquit
 
 Testing: -drive if=scsi,media=cdrom
-QEMU 1.5.50 monitor - type 'help' for more information
+QEMU X.Y.Z monitor - type 'help' for more information
 (qemu) qququiquit
 
 Testing: -drive if=ide
-QEMU 1.5.50 monitor - type 'help' for more information
+QEMU X.Y.Z monitor - type 'help' for more information
 (qemu) QEMU_PROG: Device needs media, but drive is empty
 QEMU_PROG: Device initialization failed.
 QEMU_PROG: Initialization of device ide-hd failed
 
 Testing: -drive if=virtio
-QEMU 1.5.50 monitor - type 'help' for more information
+QEMU X.Y.Z monitor - type 'help' for more information
 (qemu) QEMU_PROG: -drive if=virtio: Device needs media, but drive is empty
 QEMU_PROG: -drive if=virtio: Device initialization failed.
 QEMU_PROG: -drive if=virtio: Device initialization failed.
 QEMU_PROG: -drive if=virtio: Device 'virtio-blk-pci' could not be initialized
 
 Testing: -drive if=scsi
-QEMU 1.5.50 monitor - type 'help' for more information
+QEMU X.Y.Z monitor - type 'help' for more information
 (qemu) QEMU_PROG: -drive if=scsi: Device needs media, but drive is empty
 QEMU_PROG: -drive if=scsi: Device initialization failed.
 QEMU_PROG: Device initialization failed.
 QEMU_PROG: Initialization of device lsi53c895a failed
 
 Testing: -drive if=none,id=disk -device ide-cd,drive=disk
-QEMU 1.5.50 monitor - type 'help' for more information
+QEMU X.Y.Z monitor - type 'help' for more information
 (qemu) qququiquit
 
 Testing: -drive if=none,id=disk -device lsi53c895a -device scsi-cd,drive=disk
-QEMU 1.5.50 monitor - type 'help' for more information
+QEMU X.Y.Z monitor - type 'help' for more information
 (qemu) qququiquit
 
 Testing: -drive if=none,id=disk -device ide-drive,drive=disk
-QEMU 1.5.50 monitor - type 'help' for more information
+QEMU X.Y.Z monitor - type 'help' for more information
 (qemu) QEMU_PROG: -device ide-drive,drive=disk: Device needs media, but drive is empty
 QEMU_PROG: -device ide-drive,drive=disk: Device initialization failed.
 QEMU_PROG: -device ide-drive,drive=disk: Device 'ide-drive' could not be initialized
 
 Testing: -drive if=none,id=disk -device ide-hd,drive=disk
-QEMU 1.5.50 monitor - type 'help' for more information
+QEMU X.Y.Z monitor - type 'help' for more information
 (qemu) QEMU_PROG: -device ide-hd,drive=disk: Device needs media, but drive is empty
 QEMU_PROG: -device ide-hd,drive=disk: Device initialization failed.
 QEMU_PROG: -device ide-hd,drive=disk: Device 'ide-hd' could not be initialized
 
 Testing: -drive if=none,id=disk -device lsi53c895a -device scsi-disk,drive=disk
-QEMU 1.5.50 monitor - type 'help' for more information
+QEMU X.Y.Z monitor - type 'help' for more information
 (qemu) QEMU_PROG: -device scsi-disk,drive=disk: Device needs media, but drive is empty
 QEMU_PROG: -device scsi-disk,drive=disk: Device initialization failed.
 QEMU_PROG: -device scsi-disk,drive=disk: Device 'scsi-disk' could not be initialized
 
 Testing: -drive if=none,id=disk -device lsi53c895a -device scsi-hd,drive=disk
-QEMU 1.5.50 monitor - type 'help' for more information
+QEMU X.Y.Z monitor - type 'help' for more information
 (qemu) QEMU_PROG: -device scsi-hd,drive=disk: Device needs media, but drive is empty
 QEMU_PROG: -device scsi-hd,drive=disk: Device initialization failed.
 QEMU_PROG: -device scsi-hd,drive=disk: Device 'scsi-hd' could not be initialized
@@ -125,77 +125,77 @@ QEMU_PROG: -device scsi-hd,drive=disk: Device 'scsi-hd' could not be initialized
 === Read-only ===
 
 Testing: -drive file=TEST_DIR/t.qcow2,if=floppy,readonly=on
-QEMU 1.5.50 monitor - type 'help' for more information
+QEMU X.Y.Z monitor - type 'help' for more information
 (qemu) qququiquit
 
 Testing: -drive file=TEST_DIR/t.qcow2,if=ide,media=cdrom,readonly=on
-QEMU 1.5.50 monitor - type 'help' for more information
+QEMU X.Y.Z monitor - type 'help' for more information
 (qemu) qququiquit
 
 Testing: -drive file=TEST_DIR/t.qcow2,if=scsi,media=cdrom,readonly=on
-QEMU 1.5.50 monitor - type 'help' for more information
+QEMU X.Y.Z monitor - type 'help' for more information
 (qemu) qququiquit
 
 Testing: -drive file=TEST_DIR/t.qcow2,if=ide,readonly=on
 QEMU_PROG: -drive file=TEST_DIR/t.qcow2,if=ide,readonly=on: read-only not supported by this bus type
 
 Testing: -drive file=TEST_DIR/t.qcow2,if=virtio,readonly=on
-QEMU 1.5.50 monitor - type 'help' for more information
+QEMU X.Y.Z monitor - type 'help' for more information
 (qemu) qququiquit
 
 Testing: -drive file=TEST_DIR/t.qcow2,if=scsi,readonly=on
-QEMU 1.5.50 monitor - type 'help' for more information
+QEMU X.Y.Z monitor - type 'help' for more information
 (qemu) qququiquit
 
 Testing: -drive file=TEST_DIR/t.qcow2,if=none,id=disk,readonly=on -device ide-cd,drive=disk
-QEMU 1.5.50 monitor - type 'help' for more information
+QEMU X.Y.Z monitor - type 'help' for more information
 (qemu) qququiquit
 
 Testing: -drive file=TEST_DIR/t.qcow2,if=none,id=disk,readonly=on -device lsi53c895a -device scsi-cd,drive=disk
-QEMU 1.5.50 monitor - type 'help' for more information
+QEMU X.Y.Z monitor - type 'help' for more information
 (qemu) qququiquit
 
 Testing: -drive file=TEST_DIR/t.qcow2,if=none,id=disk,readonly=on -device ide-drive,drive=disk
-QEMU 1.5.50 monitor - type 'help' for more information
+QEMU X.Y.Z monitor - type 'help' for more information
 (qemu) QEMU_PROG: -device ide-drive,drive=disk: Can't use a read-only drive
 QEMU_PROG: -device ide-drive,drive=disk: Device initialization failed.
 QEMU_PROG: -device ide-drive,drive=disk: Device 'ide-drive' could not be initialized
 
 Testing: -drive file=TEST_DIR/t.qcow2,if=none,id=disk,readonly=on -device ide-hd,drive=disk
-QEMU 1.5.50 monitor - type 'help' for more information
+QEMU X.Y.Z monitor - type 'help' for more information
 (qemu) QEMU_PROG: -device ide-hd,drive=disk: Can't use a read-only drive
 QEMU_PROG: -device ide-hd,drive=disk: Device initialization failed.
 QEMU_PROG: -device ide-hd,drive=disk: Device 'ide-hd' could not be initialized
 
 Testing: -drive file=TEST_DIR/t.qcow2,if=none,id=disk,readonly=on -device lsi53c895a -device scsi-disk,drive=disk
-QEMU 1.5.50 monitor - type 'help' for more information
+QEMU X.Y.Z monitor - type 'help' for more information
 (qemu) qququiquit
 
 Testing: -drive file=TEST_DIR/t.qcow2,if=none,id=disk,readonly=on -device lsi53c895a -device scsi-hd,drive=disk
-QEMU 1.5.50 monitor - type 'help' for more information
+QEMU X.Y.Z monitor - type 'help' for more information
 (qemu) qququiquit
 
 
 === Cache modes ===
 
 Testing: -drive media=cdrom,cache=none
-QEMU 1.5.50 monitor - type 'help' for more information
+QEMU X.Y.Z monitor - type 'help' for more information
 (qemu) qququiquit
 
 Testing: -drive media=cdrom,cache=directsync
-QEMU 1.5.50 monitor - type 'help' for more information
+QEMU X.Y.Z monitor - type 'help' for more information
 (qemu) qququiquit
 
 Testing: -drive media=cdrom,cache=writeback
-QEMU 1.5.50 monitor - type 'help' for more information
+QEMU X.Y.Z monitor - type 'help' for more information
 (qemu) qququiquit
 
 Testing: -drive media=cdrom,cache=writethrough
-QEMU 1.5.50 monitor - type 'help' for more information
+QEMU X.Y.Z monitor - type 'help' for more information
 (qemu) qququiquit
 
 Testing: -drive media=cdrom,cache=unsafe
-QEMU 1.5.50 monitor - type 'help' for more information
+QEMU X.Y.Z monitor - type 'help' for more information
 (qemu) qququiquit
 
 Testing: -drive media=cdrom,cache=invalid_value
@@ -205,7 +205,7 @@ QEMU_PROG: -drive media=cdrom,cache=invalid_value: invalid cache option
 === Specifying the protocol layer ===
 
 Testing: -drive file=TEST_DIR/t.qcow2,file.driver=file
-QEMU 1.5.50 monitor - type 'help' for more information
+QEMU X.Y.Z monitor - type 'help' for more information
 (qemu) qququiquit
 
 Testing: -drive file=TEST_DIR/t.qcow2,file.driver=qcow2
diff --git a/tests/qemu-iotests/common.filter b/tests/qemu-iotests/common.filter
index 9dbcae8..97a31ff 100644
--- a/tests/qemu-iotests/common.filter
+++ b/tests/qemu-iotests/common.filter
@@ -155,7 +155,8 @@ _filter_qemu_io()
 # replace occurrences of QEMU_PROG with "qemu"
 _filter_qemu()
 {
-    sed -e "s#\\(^\\|(qemu) \\)$(basename $QEMU_PROG):#\1QEMU_PROG:#"
+    sed -e "s#\\(^\\|(qemu) \\)$(basename $QEMU_PROG):#\1QEMU_PROG:#" \
+        -e 's#^QEMU [0-9]\+\.[0-9]\+\.[0-9]\+ monitor#QEMU X.Y.Z monitor#'
 }
 
 # make sure this script returns success
commit 840042901710c2dc1a3ac3e5af9bed449c339701
Author: MORITA Kazutaka <morita.kazutaka at lab.ntt.co.jp>
Date:   Tue Jul 23 17:30:12 2013 +0900

    iov: handle EOF in iov_send_recv
    
    Without this patch, iov_send_recv() never returns when do_send_recv()
    returns zero.
    
    Signed-off-by: MORITA Kazutaka <morita.kazutaka at lab.ntt.co.jp>
    Reviewed-by: Paolo Bonzini <pbonzini at redhat.com>
    Signed-off-by: Kevin Wolf <kwolf at redhat.com>

diff --git a/util/iov.c b/util/iov.c
index cc6e837..f705586 100644
--- a/util/iov.c
+++ b/util/iov.c
@@ -202,6 +202,12 @@ ssize_t iov_send_recv(int sockfd, struct iovec *iov, unsigned iov_cnt,
             return -1;
         }
 
+        if (ret == 0 && !do_send) {
+            /* recv returns 0 when the peer has performed an orderly
+             * shutdown. */
+            break;
+        }
+
         /* Prepare for the next iteration */
         offset += ret;
         total += ret;
commit 526eda14a68d5b3596be715505289b541288ef2a
Author: MORITA Kazutaka <morita.kazutaka at lab.ntt.co.jp>
Date:   Tue Jul 23 17:30:11 2013 +0900

    ignore SIGPIPE in qemu-img and qemu-io
    
    This prevents the tools from being stopped when they write data to a
    closed connection in the other side.
    
    Signed-off-by: MORITA Kazutaka <morita.kazutaka at lab.ntt.co.jp>
    Reviewed-by: Paolo Bonzini <pbonzini at redhat.com>
    Signed-off-by: Kevin Wolf <kwolf at redhat.com>

diff --git a/qemu-img.c b/qemu-img.c
index dece1b3..b9a848d 100644
--- a/qemu-img.c
+++ b/qemu-img.c
@@ -2322,6 +2322,10 @@ int main(int argc, char **argv)
     const img_cmd_t *cmd;
     const char *cmdname;
 
+#ifdef CONFIG_POSIX
+    signal(SIGPIPE, SIG_IGN);
+#endif
+
     error_set_progname(argv[0]);
 
     qemu_init_main_loop();
diff --git a/qemu-io.c b/qemu-io.c
index cb9def5..d54dc86 100644
--- a/qemu-io.c
+++ b/qemu-io.c
@@ -335,6 +335,10 @@ int main(int argc, char **argv)
     int opt_index = 0;
     int flags = BDRV_O_UNMAP;
 
+#ifdef CONFIG_POSIX
+    signal(SIGPIPE, SIG_IGN);
+#endif
+
     progname = basename(argv[0]);
 
     while ((c = getopt_long(argc, argv, sopt, lopt, &opt_index)) != -1) {
commit fc11eb26cee7e3621645dd40cd9de944201f590b
Author: Kevin Wolf <kwolf at redhat.com>
Date:   Mon Aug 5 10:53:04 2013 +0200

    qemu-img: Error out for excess arguments
    
    Don't silently ignore excess arguments at the end of the command line,
    but error out instead. This can catch typos like 'resize test.img + 1G',
    which doesn't increase the image size by 1G as intended, but truncates
    the image to 1G. Even for less dangerous commands, the old behaviour is
    confusing.
    
    Signed-off-by: Kevin Wolf <kwolf at redhat.com>
    Reviewed-by: Laszlo Ersek <lersek at redhat.com>
    Reviewed-by: Stefan Hajnoczi <stefanha at redhat.com>

diff --git a/qemu-img.c b/qemu-img.c
index c55ca5c..dece1b3 100644
--- a/qemu-img.c
+++ b/qemu-img.c
@@ -396,6 +396,9 @@ static int img_create(int argc, char **argv)
         }
         img_size = (uint64_t)sval;
     }
+    if (optind != argc) {
+        help();
+    }
 
     if (options && is_help_option(options)) {
         return print_block_option_help(filename, fmt);
@@ -573,7 +576,7 @@ static int img_check(int argc, char **argv)
             break;
         }
     }
-    if (optind >= argc) {
+    if (optind != argc - 1) {
         help();
     }
     filename = argv[optind++];
@@ -684,7 +687,7 @@ static int img_commit(int argc, char **argv)
             break;
         }
     }
-    if (optind >= argc) {
+    if (optind != argc - 1) {
         help();
     }
     filename = argv[optind++];
@@ -930,7 +933,7 @@ static int img_compare(int argc, char **argv)
     }
 
 
-    if (optind > argc - 2) {
+    if (optind != argc - 2) {
         help();
     }
     filename1 = argv[optind++];
@@ -1741,7 +1744,7 @@ static int img_info(int argc, char **argv)
             break;
         }
     }
-    if (optind >= argc) {
+    if (optind != argc - 1) {
         help();
     }
     filename = argv[optind++];
@@ -1842,7 +1845,7 @@ static int img_snapshot(int argc, char **argv)
         }
     }
 
-    if (optind >= argc) {
+    if (optind != argc - 1) {
         help();
     }
     filename = argv[optind++];
@@ -1953,7 +1956,7 @@ static int img_rebase(int argc, char **argv)
         progress = 0;
     }
 
-    if ((optind >= argc) || (!unsafe && !out_baseimg)) {
+    if ((optind != argc - 1) || (!unsafe && !out_baseimg)) {
         help();
     }
     filename = argv[optind++];
@@ -2232,7 +2235,7 @@ static int img_resize(int argc, char **argv)
             break;
         }
     }
-    if (optind >= argc) {
+    if (optind != argc - 1) {
         help();
     }
     filename = argv[optind++];
commit 79761c6681f0d1cc1c027116fcb4382d41ed3ece
Author: Izumi Tsutsui <tsutsui at ceres.dti.ne.jp>
Date:   Wed Jul 3 17:58:14 2013 +0900

    semaphore: fix a hangup problem under load on NetBSD hosts.
    
    Fix following bugs in "fallback implementation of counting semaphores
    with mutex+condvar" added in c166cb72f1676855816340666c3b618beef4b976:
     - waiting threads are not restarted properly if more than one threads
       are waiting unblock signals in qemu_sem_timedwait()
     - possible missing pthread_cond_signal(3) calls when waiting threads
       are returned by ETIMEDOUT
     - fix an uninitialized variable
    The problem is analyzed by and fix is provided by Noriyuki Soda.
    
    Also put additional cleanup suggested by Laszlo Ersek:
     - make QemuSemaphore.count unsigned (it won't be negative)
     - check a return value of in pthread_cond_wait() in qemu_sem_wait()
    
    Signed-off-by: Izumi Tsutsui <tsutsui at ceres.dti.ne.jp>
    Reviewed-by: Laszlo Ersek <lersek at redhat.com>
    Message-id: 1372841894-10634-1-git-send-email-tsutsui at ceres.dti.ne.jp
    Signed-off-by: Anthony Liguori <aliguori at us.ibm.com>

diff --git a/include/qemu/thread-posix.h b/include/qemu/thread-posix.h
index 0f30dcc..361566a 100644
--- a/include/qemu/thread-posix.h
+++ b/include/qemu/thread-posix.h
@@ -15,7 +15,7 @@ struct QemuSemaphore {
 #if defined(__APPLE__) || defined(__NetBSD__)
     pthread_mutex_t lock;
     pthread_cond_t cond;
-    int count;
+    unsigned int count;
 #else
     sem_t sem;
 #endif
diff --git a/util/qemu-thread-posix.c b/util/qemu-thread-posix.c
index 4489abf..4de133e 100644
--- a/util/qemu-thread-posix.c
+++ b/util/qemu-thread-posix.c
@@ -170,12 +170,11 @@ void qemu_sem_post(QemuSemaphore *sem)
 
 #if defined(__APPLE__) || defined(__NetBSD__)
     pthread_mutex_lock(&sem->lock);
-    if (sem->count == INT_MAX) {
+    if (sem->count == UINT_MAX) {
         rc = EINVAL;
-    } else if (sem->count++ < 0) {
-        rc = pthread_cond_signal(&sem->cond);
     } else {
-        rc = 0;
+        sem->count++;
+        rc = pthread_cond_signal(&sem->cond);
     }
     pthread_mutex_unlock(&sem->lock);
     if (rc != 0) {
@@ -207,19 +206,21 @@ int qemu_sem_timedwait(QemuSemaphore *sem, int ms)
     struct timespec ts;
 
 #if defined(__APPLE__) || defined(__NetBSD__)
+    rc = 0;
     compute_abs_deadline(&ts, ms);
     pthread_mutex_lock(&sem->lock);
-    --sem->count;
-    while (sem->count < 0) {
+    while (sem->count == 0) {
         rc = pthread_cond_timedwait(&sem->cond, &sem->lock, &ts);
         if (rc == ETIMEDOUT) {
-            ++sem->count;
             break;
         }
         if (rc != 0) {
             error_exit(rc, __func__);
         }
     }
+    if (rc != ETIMEDOUT) {
+        --sem->count;
+    }
     pthread_mutex_unlock(&sem->lock);
     return (rc == ETIMEDOUT ? -1 : 0);
 #else
@@ -249,16 +250,19 @@ int qemu_sem_timedwait(QemuSemaphore *sem, int ms)
 
 void qemu_sem_wait(QemuSemaphore *sem)
 {
+    int rc;
+
 #if defined(__APPLE__) || defined(__NetBSD__)
     pthread_mutex_lock(&sem->lock);
-    --sem->count;
-    while (sem->count < 0) {
-        pthread_cond_wait(&sem->cond, &sem->lock);
+    while (sem->count == 0) {
+        rc = pthread_cond_wait(&sem->cond, &sem->lock);
+        if (rc != 0) {
+            error_exit(rc, __func__);
+        }
     }
+    --sem->count;
     pthread_mutex_unlock(&sem->lock);
 #else
-    int rc;
-
     do {
         rc = sem_wait(&sem->sem);
     } while (rc == -1 && errno == EINTR);
commit e1d0fb378ae3bb4272124a12e3fe1a02c4745eb1
Author: Isaku Yamahata <yamahata at private.email.ne.jp>
Date:   Sat Aug 3 22:54:54 2013 -0400

    rdma: memory leak RDMAContext::host
    
    It is allocated by g_strdup(), so needs to be freed.
    
    Reviewed-by: Michael R. Hines <mrhines at us.ibm.com>
    Signed-off-by: Isaku Yamahata <yamahata at private.email.ne.jp>
    Signed-off-by: Michael R. Hines <mrhines at us.ibm.com>
    Message-id: 1375584894-9917-8-git-send-email-mrhines at linux.vnet.ibm.com
    Signed-off-by: Anthony Liguori <aliguori at us.ibm.com>

diff --git a/migration-rdma.c b/migration-rdma.c
index 83c9a0b..3a380d4 100644
--- a/migration-rdma.c
+++ b/migration-rdma.c
@@ -2097,6 +2097,8 @@ static void qemu_rdma_cleanup(RDMAContext *rdma)
         rdma_destroy_event_channel(rdma->channel);
         rdma->channel = NULL;
     }
+    g_free(rdma->host);
+    rdma->host = NULL;
 }
 
 
commit 877726397f7e24d0c8a2b303a852769b5edd155c
Author: Isaku Yamahata <yamahata at private.email.ne.jp>
Date:   Sat Aug 3 22:54:53 2013 -0400

    rdma: use RDMA_WRID_READY
    
    Reviewed-by: Michael R. Hines <mrhines at us.ibm.com>
    Signed-off-by: Isaku Yamahata <yamahata at private.email.ne.jp>
    Signed-off-by: Michael R. Hines <mrhines at us.ibm.com>
    Message-id: 1375584894-9917-7-git-send-email-mrhines at linux.vnet.ibm.com
    Signed-off-by: Anthony Liguori <aliguori at us.ibm.com>

diff --git a/migration-rdma.c b/migration-rdma.c
index 5b03e95..83c9a0b 100644
--- a/migration-rdma.c
+++ b/migration-rdma.c
@@ -2223,7 +2223,7 @@ static int qemu_rdma_connect(RDMAContext *rdma, Error **errp)
 
     rdma_ack_cm_event(cm_event);
 
-    ret = qemu_rdma_post_recv_control(rdma, 0);
+    ret = qemu_rdma_post_recv_control(rdma, RDMA_WRID_READY);
     if (ret) {
         ERROR(errp, "posting second control recv!");
         goto err_rdma_source_connect;
@@ -2735,7 +2735,7 @@ static int qemu_rdma_accept(RDMAContext *rdma)
 
     rdma_ack_cm_event(cm_event);
 
-    ret = qemu_rdma_post_recv_control(rdma, 0);
+    ret = qemu_rdma_post_recv_control(rdma, RDMA_WRID_READY);
     if (ret) {
         fprintf(stderr, "rdma migration: error posting second control recv!\n");
         goto err_rdma_dest_wait;
commit 1f22364bb5a756dfcbd15c2ae2bac18bbcef6190
Author: Isaku Yamahata <yamahata at private.email.ne.jp>
Date:   Sat Aug 3 22:54:52 2013 -0400

    rdma: qemu_rdma_post_send_control uses wrongly RDMA_WRID_MAX
    
    RDMA_WRID_CONTROL should be used. And remove related work around.
    
    Reviewed-by: Michael R. Hines <mrhines at us.ibm.com>
    Signed-off-by: Isaku Yamahata <yamahata at private.email.ne.jp>
    Signed-off-by: Michael R. Hines <mrhines at us.ibm.com>
    Message-id: 1375584894-9917-6-git-send-email-mrhines at linux.vnet.ibm.com
    Signed-off-by: Anthony Liguori <aliguori at us.ibm.com>

diff --git a/migration-rdma.c b/migration-rdma.c
index ec0a7ae..5b03e95 100644
--- a/migration-rdma.c
+++ b/migration-rdma.c
@@ -322,7 +322,7 @@ typedef struct RDMAContext {
     char *host;
     int port;
 
-    RDMAWorkRequestData wr_data[RDMA_WRID_MAX + 1];
+    RDMAWorkRequestData wr_data[RDMA_WRID_MAX];
 
     /*
      * This is used by *_exchange_send() to figure out whether or not
@@ -1399,7 +1399,7 @@ static int qemu_rdma_post_send_control(RDMAContext *rdma, uint8_t *buf,
                                        RDMAControlHeader *head)
 {
     int ret = 0;
-    RDMAWorkRequestData *wr = &rdma->wr_data[RDMA_WRID_MAX];
+    RDMAWorkRequestData *wr = &rdma->wr_data[RDMA_WRID_CONTROL];
     struct ibv_send_wr *bad_wr;
     struct ibv_sge sge = {
                            .addr = (uint64_t)(wr->control),
@@ -2054,7 +2054,7 @@ static void qemu_rdma_cleanup(RDMAContext *rdma)
     g_free(rdma->block);
     rdma->block = NULL;
 
-    for (idx = 0; idx <= RDMA_WRID_MAX; idx++) {
+    for (idx = 0; idx < RDMA_WRID_MAX; idx++) {
         if (rdma->wr_data[idx].control_mr) {
             rdma->total_registrations--;
             ibv_dereg_mr(rdma->wr_data[idx].control_mr);
@@ -2136,7 +2136,7 @@ static int qemu_rdma_source_init(RDMAContext *rdma, Error **errp, bool pin_all)
         goto err_rdma_source_init;
     }
 
-    for (idx = 0; idx <= RDMA_WRID_MAX; idx++) {
+    for (idx = 0; idx < RDMA_WRID_MAX; idx++) {
         ret = qemu_rdma_reg_control(rdma, idx);
         if (ret) {
             ERROR(temp, "rdma migration: error registering %d control!",
@@ -2248,7 +2248,7 @@ static int qemu_rdma_dest_init(RDMAContext *rdma, Error **errp)
     struct addrinfo *res;
     char port_str[16];
 
-    for (idx = 0; idx <= RDMA_WRID_MAX; idx++) {
+    for (idx = 0; idx < RDMA_WRID_MAX; idx++) {
         rdma->wr_data[idx].control_len = 0;
         rdma->wr_data[idx].control_curr = NULL;
     }
@@ -2705,7 +2705,7 @@ static int qemu_rdma_accept(RDMAContext *rdma)
         goto err_rdma_dest_wait;
     }
 
-    for (idx = 0; idx <= RDMA_WRID_MAX; idx++) {
+    for (idx = 0; idx < RDMA_WRID_MAX; idx++) {
         ret = qemu_rdma_reg_control(rdma, idx);
         if (ret) {
             fprintf(stderr, "rdma: error registering %d control!\n", idx);
commit 44b5949491a47043c4f7c4ff09f0191f82919a82
Author: Isaku Yamahata <yamahata at private.email.ne.jp>
Date:   Sat Aug 3 22:54:51 2013 -0400

    rdma: don't use negative index to array
    
    Reviewed-by: Michael R. Hines <mrhines at us.ibm.com>
    Signed-off-by: Isaku Yamahata <yamahata at private.email.ne.jp>
    Signed-off-by: Michael R. Hines <mrhines at us.ibm.com>
    Message-id: 1375584894-9917-5-git-send-email-mrhines at linux.vnet.ibm.com
    Signed-off-by: Anthony Liguori <aliguori at us.ibm.com>

diff --git a/migration-rdma.c b/migration-rdma.c
index 48d6c19..ec0a7ae 100644
--- a/migration-rdma.c
+++ b/migration-rdma.c
@@ -1933,10 +1933,21 @@ static int qemu_rdma_write_flush(QEMUFile *f, RDMAContext *rdma)
 static inline int qemu_rdma_buffer_mergable(RDMAContext *rdma,
                     uint64_t offset, uint64_t len)
 {
-    RDMALocalBlock *block =
-        &(rdma->local_ram_blocks.block[rdma->current_index]);
-    uint8_t *host_addr = block->local_host_addr + (offset - block->offset);
-    uint8_t *chunk_end = ram_chunk_end(block, rdma->current_chunk);
+    RDMALocalBlock *block;
+    uint8_t *host_addr;
+    uint8_t *chunk_end;
+
+    if (rdma->current_index < 0) {
+        return 0;
+    }
+
+    if (rdma->current_chunk < 0) {
+        return 0;
+    }
+
+    block = &(rdma->local_ram_blocks.block[rdma->current_index]);
+    host_addr = block->local_host_addr + (offset - block->offset);
+    chunk_end = ram_chunk_end(block, rdma->current_chunk);
 
     if (rdma->current_length == 0) {
         return 0;
@@ -1949,10 +1960,6 @@ static inline int qemu_rdma_buffer_mergable(RDMAContext *rdma,
         return 0;
     }
 
-    if (rdma->current_index < 0) {
-        return 0;
-    }
-
     if (offset < block->offset) {
         return 0;
     }
@@ -1961,10 +1968,6 @@ static inline int qemu_rdma_buffer_mergable(RDMAContext *rdma,
         return 0;
     }
 
-    if (rdma->current_chunk < 0) {
-        return 0;
-    }
-
     if ((host_addr + len) > chunk_end) {
         return 0;
     }
commit 66988941251ef64044aa3b951ebd84162e5a4e3a
Author: Michael R. Hines <mrhines at us.ibm.com>
Date:   Sat Aug 3 22:54:50 2013 -0400

    rdma: correct newlines in error statements
    
    Don't print newlines on the error_setg() function,
    but still allow newlines on fprintf().
    
    Signed-off-by: Michael R. Hines <mrhines at us.ibm.com>
    Message-id: 1375584894-9917-4-git-send-email-mrhines at linux.vnet.ibm.com
    Signed-off-by: Anthony Liguori <aliguori at us.ibm.com>

diff --git a/migration-rdma.c b/migration-rdma.c
index b2e2a76..48d6c19 100644
--- a/migration-rdma.c
+++ b/migration-rdma.c
@@ -60,7 +60,7 @@
  */
 #define ERROR(errp, fmt, ...) \
     do { \
-        fprintf(stderr, "RDMA ERROR: " fmt, ## __VA_ARGS__); \
+        fprintf(stderr, "RDMA ERROR: " fmt "\n", ## __VA_ARGS__); \
         if (errp && (*(errp) == NULL)) { \
             error_setg(errp, "RDMA ERROR: " fmt, ## __VA_ARGS__); \
         } \
@@ -748,21 +748,21 @@ static int qemu_rdma_resolve_host(RDMAContext *rdma, Error **errp)
     int af = rdma->ipv6 ? PF_INET6 : PF_INET;
 
     if (rdma->host == NULL || !strcmp(rdma->host, "")) {
-        ERROR(errp, "RDMA hostname has not been set\n");
+        ERROR(errp, "RDMA hostname has not been set");
         return -1;
     }
 
     /* create CM channel */
     rdma->channel = rdma_create_event_channel();
     if (!rdma->channel) {
-        ERROR(errp, "could not create CM channel\n");
+        ERROR(errp, "could not create CM channel");
         return -1;
     }
 
     /* create CM id */
     ret = rdma_create_id(rdma->channel, &rdma->cm_id, NULL, RDMA_PS_TCP);
     if (ret) {
-        ERROR(errp, "could not create channel id\n");
+        ERROR(errp, "could not create channel id");
         goto err_resolve_create_id;
     }
 
@@ -771,7 +771,7 @@ static int qemu_rdma_resolve_host(RDMAContext *rdma, Error **errp)
 
     ret = getaddrinfo(rdma->host, port_str, NULL, &res);
     if (ret < 0) {
-        ERROR(errp, "could not getaddrinfo address %s\n", rdma->host);
+        ERROR(errp, "could not getaddrinfo address %s", rdma->host);
         goto err_resolve_get_addr;
     }
 
@@ -783,7 +783,7 @@ static int qemu_rdma_resolve_host(RDMAContext *rdma, Error **errp)
     ret = rdma_resolve_addr(rdma->cm_id, NULL, res->ai_addr,
             RDMA_RESOLVE_TIMEOUT_MS);
     if (ret) {
-        ERROR(errp, "could not resolve address %s\n", rdma->host);
+        ERROR(errp, "could not resolve address %s", rdma->host);
         goto err_resolve_get_addr;
     }
 
@@ -791,12 +791,12 @@ static int qemu_rdma_resolve_host(RDMAContext *rdma, Error **errp)
 
     ret = rdma_get_cm_event(rdma->channel, &cm_event);
     if (ret) {
-        ERROR(errp, "could not perform event_addr_resolved\n");
+        ERROR(errp, "could not perform event_addr_resolved");
         goto err_resolve_get_addr;
     }
 
     if (cm_event->event != RDMA_CM_EVENT_ADDR_RESOLVED) {
-        ERROR(errp, "result not equal to event_addr_resolved %s\n",
+        ERROR(errp, "result not equal to event_addr_resolved %s",
                 rdma_event_str(cm_event->event));
         perror("rdma_resolve_addr");
         goto err_resolve_get_addr;
@@ -806,17 +806,17 @@ static int qemu_rdma_resolve_host(RDMAContext *rdma, Error **errp)
     /* resolve route */
     ret = rdma_resolve_route(rdma->cm_id, RDMA_RESOLVE_TIMEOUT_MS);
     if (ret) {
-        ERROR(errp, "could not resolve rdma route\n");
+        ERROR(errp, "could not resolve rdma route");
         goto err_resolve_get_addr;
     }
 
     ret = rdma_get_cm_event(rdma->channel, &cm_event);
     if (ret) {
-        ERROR(errp, "could not perform event_route_resolved\n");
+        ERROR(errp, "could not perform event_route_resolved");
         goto err_resolve_get_addr;
     }
     if (cm_event->event != RDMA_CM_EVENT_ROUTE_RESOLVED) {
-        ERROR(errp, "result not equal to event_route_resolved: %s\n",
+        ERROR(errp, "result not equal to event_route_resolved: %s",
                         rdma_event_str(cm_event->event));
         rdma_ack_cm_event(cm_event);
         goto err_resolve_get_addr;
@@ -2117,26 +2117,26 @@ static int qemu_rdma_source_init(RDMAContext *rdma, Error **errp, bool pin_all)
     if (ret) {
         ERROR(temp, "rdma migration: error allocating pd and cq! Your mlock()"
                     " limits may be too low. Please check $ ulimit -a # and "
-                    "search for 'ulimit -l' in the output\n");
+                    "search for 'ulimit -l' in the output");
         goto err_rdma_source_init;
     }
 
     ret = qemu_rdma_alloc_qp(rdma);
     if (ret) {
-        ERROR(temp, "rdma migration: error allocating qp!\n");
+        ERROR(temp, "rdma migration: error allocating qp!");
         goto err_rdma_source_init;
     }
 
     ret = qemu_rdma_init_ram_blocks(rdma);
     if (ret) {
-        ERROR(temp, "rdma migration: error initializing ram blocks!\n");
+        ERROR(temp, "rdma migration: error initializing ram blocks!");
         goto err_rdma_source_init;
     }
 
     for (idx = 0; idx <= RDMA_WRID_MAX; idx++) {
         ret = qemu_rdma_reg_control(rdma, idx);
         if (ret) {
-            ERROR(temp, "rdma migration: error registering %d control!\n",
+            ERROR(temp, "rdma migration: error registering %d control!",
                                                             idx);
             goto err_rdma_source_init;
         }
@@ -2178,7 +2178,7 @@ static int qemu_rdma_connect(RDMAContext *rdma, Error **errp)
     ret = rdma_connect(rdma->cm_id, &conn_param);
     if (ret) {
         perror("rdma_connect");
-        ERROR(errp, "connecting to destination!\n");
+        ERROR(errp, "connecting to destination!");
         rdma_destroy_id(rdma->cm_id);
         rdma->cm_id = NULL;
         goto err_rdma_source_connect;
@@ -2187,7 +2187,7 @@ static int qemu_rdma_connect(RDMAContext *rdma, Error **errp)
     ret = rdma_get_cm_event(rdma->channel, &cm_event);
     if (ret) {
         perror("rdma_get_cm_event after rdma_connect");
-        ERROR(errp, "connecting to destination!\n");
+        ERROR(errp, "connecting to destination!");
         rdma_ack_cm_event(cm_event);
         rdma_destroy_id(rdma->cm_id);
         rdma->cm_id = NULL;
@@ -2196,7 +2196,7 @@ static int qemu_rdma_connect(RDMAContext *rdma, Error **errp)
 
     if (cm_event->event != RDMA_CM_EVENT_ESTABLISHED) {
         perror("rdma_get_cm_event != EVENT_ESTABLISHED after rdma_connect");
-        ERROR(errp, "connecting to destination!\n");
+        ERROR(errp, "connecting to destination!");
         rdma_ack_cm_event(cm_event);
         rdma_destroy_id(rdma->cm_id);
         rdma->cm_id = NULL;
@@ -2212,7 +2212,7 @@ static int qemu_rdma_connect(RDMAContext *rdma, Error **errp)
      */
     if (rdma->pin_all && !(cap.flags & RDMA_CAPABILITY_PIN_ALL)) {
         ERROR(errp, "Server cannot support pinning all memory. "
-                        "Will register memory dynamically.\n");
+                        "Will register memory dynamically.");
         rdma->pin_all = false;
     }
 
@@ -2222,7 +2222,7 @@ static int qemu_rdma_connect(RDMAContext *rdma, Error **errp)
 
     ret = qemu_rdma_post_recv_control(rdma, 0);
     if (ret) {
-        ERROR(errp, "posting second control recv!\n");
+        ERROR(errp, "posting second control recv!");
         goto err_rdma_source_connect;
     }
 
@@ -2251,14 +2251,14 @@ static int qemu_rdma_dest_init(RDMAContext *rdma, Error **errp)
     }
 
     if (rdma->host == NULL) {
-        ERROR(errp, "RDMA host is not set!\n");
+        ERROR(errp, "RDMA host is not set!");
         rdma->error_state = -EINVAL;
         return -1;
     }
     /* create CM channel */
     rdma->channel = rdma_create_event_channel();
     if (!rdma->channel) {
-        ERROR(errp, "could not create rdma event channel\n");
+        ERROR(errp, "could not create rdma event channel");
         rdma->error_state = -EINVAL;
         return -1;
     }
@@ -2266,7 +2266,7 @@ static int qemu_rdma_dest_init(RDMAContext *rdma, Error **errp)
     /* create CM id */
     ret = rdma_create_id(rdma->channel, &listen_id, NULL, RDMA_PS_TCP);
     if (ret) {
-        ERROR(errp, "could not create cm_id!\n");
+        ERROR(errp, "could not create cm_id!");
         goto err_dest_init_create_listen_id;
     }
 
@@ -2279,7 +2279,7 @@ static int qemu_rdma_dest_init(RDMAContext *rdma, Error **errp)
     if (rdma->host && strcmp("", rdma->host)) {
         ret = getaddrinfo(rdma->host, port_str, NULL, &res);
         if (ret < 0) {
-            ERROR(errp, "could not getaddrinfo address %s\n", rdma->host);
+            ERROR(errp, "could not getaddrinfo address %s", rdma->host);
             goto err_dest_init_bind_addr;
         }
 
@@ -2287,7 +2287,7 @@ static int qemu_rdma_dest_init(RDMAContext *rdma, Error **errp)
         inet_ntop(af, &((struct sockaddr_in *) res->ai_addr)->sin_addr,
                                     ip, sizeof ip);
     } else {
-        ERROR(errp, "migration host and port not specified!\n");
+        ERROR(errp, "migration host and port not specified!");
         ret = -EINVAL;
         goto err_dest_init_bind_addr;
     }
@@ -2296,7 +2296,7 @@ static int qemu_rdma_dest_init(RDMAContext *rdma, Error **errp)
 
     ret = rdma_bind_addr(listen_id, res->ai_addr);
     if (ret) {
-        ERROR(errp, "Error: could not rdma_bind_addr!\n");
+        ERROR(errp, "Error: could not rdma_bind_addr!");
         goto err_dest_init_bind_addr;
     }
 
@@ -3036,7 +3036,7 @@ static int qemu_rdma_registration_stop(QEMUFile *f, void *opaque,
                     &reg_result_idx, rdma->pin_all ?
                     qemu_rdma_reg_whole_ram_blocks : NULL);
         if (ret < 0) {
-            ERROR(errp, "receiving remote info!\n");
+            ERROR(errp, "receiving remote info!");
             return ret;
         }
 
@@ -3061,7 +3061,7 @@ static int qemu_rdma_registration_stop(QEMUFile *f, void *opaque,
         if (local->nb_blocks != nb_remote_blocks) {
             ERROR(errp, "ram blocks mismatch #1! "
                         "Your QEMU command line parameters are probably "
-                        "not identical on both the source and destination.\n");
+                        "not identical on both the source and destination.");
             return -EINVAL;
         }
 
@@ -3077,7 +3077,7 @@ static int qemu_rdma_registration_stop(QEMUFile *f, void *opaque,
                 if (rdma->block[i].length != local->block[j].length) {
                     ERROR(errp, "ram blocks mismatch #2! "
                         "Your QEMU command line parameters are probably "
-                        "not identical on both the source and destination.\n");
+                        "not identical on both the source and destination.");
                     return -EINVAL;
                 }
                 local->block[j].remote_host_addr =
@@ -3089,7 +3089,7 @@ static int qemu_rdma_registration_stop(QEMUFile *f, void *opaque,
             if (j >= local->nb_blocks) {
                 ERROR(errp, "ram blocks mismatch #3! "
                         "Your QEMU command line parameters are probably "
-                        "not identical on both the source and destination.\n");
+                        "not identical on both the source and destination.");
                 return -EINVAL;
             }
         }
@@ -3163,7 +3163,7 @@ static void rdma_accept_incoming_migration(void *opaque)
     ret = qemu_rdma_accept(rdma);
 
     if (ret) {
-        ERROR(errp, "RDMA Migration initialization failed!\n");
+        ERROR(errp, "RDMA Migration initialization failed!");
         return;
     }
 
@@ -3171,7 +3171,7 @@ static void rdma_accept_incoming_migration(void *opaque)
 
     f = qemu_fopen_rdma(rdma, "rb");
     if (f == NULL) {
-        ERROR(errp, "could not qemu_fopen_rdma!\n");
+        ERROR(errp, "could not qemu_fopen_rdma!");
         qemu_rdma_cleanup(rdma);
         return;
     }
@@ -3204,7 +3204,7 @@ void rdma_start_incoming_migration(const char *host_port, Error **errp)
     ret = rdma_listen(rdma->listen_id, 5);
 
     if (ret) {
-        ERROR(errp, "listening on socket!\n");
+        ERROR(errp, "listening on socket!");
         goto err;
     }
 
@@ -3228,7 +3228,7 @@ void rdma_start_outgoing_migration(void *opaque,
     int ret = 0;
 
     if (rdma == NULL) {
-        ERROR(temp, "Failed to initialize RDMA data structures! %d\n", ret);
+        ERROR(temp, "Failed to initialize RDMA data structures! %d", ret);
         goto err;
     }
 
commit 8cd31adc7cc0602ba0a66b7d9b50fd016ab5530a
Author: Michael R. Hines <mrhines at us.ibm.com>
Date:   Sat Aug 3 22:54:49 2013 -0400

    rdma: forgot to turn off the debugging flag
    
    Ooops. We forgot to turn off the flag.
    
    Signed-off-by: Michael R. Hines <mrhines at us.ibm.com>
    Message-id: 1375584894-9917-3-git-send-email-mrhines at linux.vnet.ibm.com
    Signed-off-by: Anthony Liguori <aliguori at us.ibm.com>

diff --git a/migration-rdma.c b/migration-rdma.c
index 6a7bf27..b2e2a76 100644
--- a/migration-rdma.c
+++ b/migration-rdma.c
@@ -27,7 +27,7 @@
 #include <string.h>
 #include <rdma/rdma_cma.h>
 
-#define DEBUG_RDMA
+//#define DEBUG_RDMA
 //#define DEBUG_RDMA_VERBOSE
 //#define DEBUG_RDMA_REALLY_VERBOSE
 
commit b58c8552bd466aaab67c59dedeb846838082cad6
Author: Michael R. Hines <mrhines at us.ibm.com>
Date:   Sat Aug 3 22:54:48 2013 -0400

    rdma: bugfix: make IPv6 support work
    
    RDMA does not use sockets, so we cannot use many of the socket
    helper functions, but we *do* use inet_parse() which gives
    RDMA all the necessary details of the connection parameters.
    
    However, when testing with libvirt, a simple IPv6 migration test failed
    because we were not using getaddrinfo() properly.
    
    This makes IPv6 migration over RDMA work.
    
    Signed-off-by: Michael R. Hines <mrhines at us.ibm.com>
    Message-id: 1375584894-9917-2-git-send-email-mrhines at linux.vnet.ibm.com
    Signed-off-by: Anthony Liguori <aliguori at us.ibm.com>

diff --git a/migration-rdma.c b/migration-rdma.c
index 4828738..6a7bf27 100644
--- a/migration-rdma.c
+++ b/migration-rdma.c
@@ -392,6 +392,7 @@ typedef struct RDMAContext {
     uint64_t unregistrations[RDMA_SIGNALED_SEND_MAX];
 
     GHashTable *blockmap;
+    bool ipv6;
 } RDMAContext;
 
 /*
@@ -744,6 +745,7 @@ static int qemu_rdma_resolve_host(RDMAContext *rdma, Error **errp)
     char port_str[16];
     struct rdma_cm_event *cm_event;
     char ip[40] = "unknown";
+    int af = rdma->ipv6 ? PF_INET6 : PF_INET;
 
     if (rdma->host == NULL || !strcmp(rdma->host, "")) {
         ERROR(errp, "RDMA hostname has not been set\n");
@@ -773,7 +775,7 @@ static int qemu_rdma_resolve_host(RDMAContext *rdma, Error **errp)
         goto err_resolve_get_addr;
     }
 
-    inet_ntop(AF_INET, &((struct sockaddr_in *) res->ai_addr)->sin_addr,
+    inet_ntop(af, &((struct sockaddr_in *) res->ai_addr)->sin_addr,
                                 ip, sizeof ip);
     DPRINTF("%s => %s\n", rdma->host, ip);
 
@@ -2236,9 +2238,12 @@ err_rdma_source_connect:
 static int qemu_rdma_dest_init(RDMAContext *rdma, Error **errp)
 {
     int ret = -EINVAL, idx;
+    int af = rdma->ipv6 ? PF_INET6 : PF_INET;
     struct sockaddr_in sin;
     struct rdma_cm_id *listen_id;
     char ip[40] = "unknown";
+    struct addrinfo *res;
+    char port_str[16];
 
     for (idx = 0; idx <= RDMA_WRID_MAX; idx++) {
         rdma->wr_data[idx].control_len = 0;
@@ -2266,27 +2271,30 @@ static int qemu_rdma_dest_init(RDMAContext *rdma, Error **errp)
     }
 
     memset(&sin, 0, sizeof(sin));
-    sin.sin_family = AF_INET;
+    sin.sin_family = af;
     sin.sin_port = htons(rdma->port);
+    snprintf(port_str, 16, "%d", rdma->port);
+    port_str[15] = '\0';
 
     if (rdma->host && strcmp("", rdma->host)) {
-        struct hostent *dest_addr;
-        dest_addr = gethostbyname(rdma->host);
-        if (!dest_addr) {
-            ERROR(errp, "migration could not gethostbyname!\n");
-            ret = -EINVAL;
+        ret = getaddrinfo(rdma->host, port_str, NULL, &res);
+        if (ret < 0) {
+            ERROR(errp, "could not getaddrinfo address %s\n", rdma->host);
             goto err_dest_init_bind_addr;
         }
-        memcpy(&sin.sin_addr.s_addr, dest_addr->h_addr,
-                dest_addr->h_length);
-        inet_ntop(AF_INET, dest_addr->h_addr, ip, sizeof ip);
+
+
+        inet_ntop(af, &((struct sockaddr_in *) res->ai_addr)->sin_addr,
+                                    ip, sizeof ip);
     } else {
-        sin.sin_addr.s_addr = INADDR_ANY;
+        ERROR(errp, "migration host and port not specified!\n");
+        ret = -EINVAL;
+        goto err_dest_init_bind_addr;
     }
 
     DPRINTF("%s => %s\n", rdma->host, ip);
 
-    ret = rdma_bind_addr(listen_id, (struct sockaddr *)&sin);
+    ret = rdma_bind_addr(listen_id, res->ai_addr);
     if (ret) {
         ERROR(errp, "Error: could not rdma_bind_addr!\n");
         goto err_dest_init_bind_addr;
@@ -2321,6 +2329,7 @@ static void *qemu_rdma_data_init(const char *host_port, Error **errp)
         if (addr != NULL) {
             rdma->port = atoi(addr->port);
             rdma->host = g_strdup(addr->host);
+            rdma->ipv6 = addr->ipv6;
         } else {
             ERROR(errp, "bad RDMA migration address '%s'", host_port);
             g_free(rdma);
commit be2f78b6b062eec5170e2612299fb8953046993f
Author: Andreas Färber <afaerber at suse.de>
Date:   Sun Aug 4 15:05:01 2013 +0200

    pxa2xx: Avoid object_get_link_property() assertion for "parent_bus"
    
    pxa2xx_i2c_init() creates a pxa2xx-i2c-slave device on a second i2c-bus,
    which has a NULL parent device. This causes an assertion in
    object_get_canonical_path() when accessing pxa2xx-i2c-slave's
    "parent_bus" link<bus> property in tosa and likely other PXA2xx machines.
    
    Fix this by using the pxa2xx_i2c device, created just before, as parent.
    
    Signed-off-by: Andreas Färber <afaerber at suse.de>
    Signed-off-by: Andreas Färber <afaerber at suse.de>
    Message-id: 1375621501-5564-1-git-send-email-afaerber at suse.de
    Signed-off-by: Anthony Liguori <aliguori at us.ibm.com>

diff --git a/hw/arm/pxa2xx.c b/hw/arm/pxa2xx.c
index 7de6453..17ddd3f 100644
--- a/hw/arm/pxa2xx.c
+++ b/hw/arm/pxa2xx.c
@@ -1479,6 +1479,7 @@ PXA2xxI2CState *pxa2xx_i2c_init(hwaddr base,
     DeviceState *dev;
     SysBusDevice *i2c_dev;
     PXA2xxI2CState *s;
+    i2c_bus *i2cbus;
 
     dev = qdev_create(NULL, TYPE_PXA2XX_I2C);
     qdev_prop_set_uint32(dev, "size", region_size + 1);
@@ -1491,7 +1492,8 @@ PXA2xxI2CState *pxa2xx_i2c_init(hwaddr base,
 
     s = PXA2XX_I2C(i2c_dev);
     /* FIXME: Should the slave device really be on a separate bus?  */
-    dev = i2c_create_slave(i2c_init_bus(NULL, "dummy"), "pxa2xx-i2c-slave", 0);
+    i2cbus = i2c_init_bus(dev, "dummy");
+    dev = i2c_create_slave(i2cbus, "pxa2xx-i2c-slave", 0);
     s->slave = FROM_I2C_SLAVE(PXA2xxI2CSlaveState, I2C_SLAVE(dev));
     s->slave->host = s;
 
commit 03a15a5436ed7723f406f15cc3798aa9991e75b5
Author: Alexey Kardashevskiy <aik at ozlabs.ru>
Date:   Fri Aug 2 12:59:34 2013 +1000

    target-ppc: Add POWER7+ CPU model
    
    This patch adds CPU PVR definition for POWER7+.
    
    Signed-off-by: Alexey Kardashevskiy <aik at ozlabs.ru>
    Message-id: 1375412374-24701-1-git-send-email-aik at ozlabs.ru
    Signed-off-by: Anthony Liguori <aliguori at us.ibm.com>

diff --git a/target-ppc/cpu-models.c b/target-ppc/cpu-models.c
index 9578ed8..c97c183 100644
--- a/target-ppc/cpu-models.c
+++ b/target-ppc/cpu-models.c
@@ -1143,6 +1143,8 @@
                 "POWER7 v2.1")
     POWERPC_DEF("POWER7_v2.3",   CPU_POWERPC_POWER7_v23,             POWER7,
                 "POWER7 v2.3")
+    POWERPC_DEF("POWER7P",       CPU_POWERPC_POWER7P,                POWER7,
+                "POWER7P")
     POWERPC_DEF("POWER8_v1.0",   CPU_POWERPC_POWER8_v10,             POWER8,
                 "POWER8 v1.0")
     POWERPC_DEF("970",           CPU_POWERPC_970,                    970,
diff --git a/target-ppc/cpu-models.h b/target-ppc/cpu-models.h
index 01e488f..c3c78d1 100644
--- a/target-ppc/cpu-models.h
+++ b/target-ppc/cpu-models.h
@@ -556,6 +556,7 @@ enum {
     CPU_POWERPC_POWER7_v20         = 0x003F0200,
     CPU_POWERPC_POWER7_v21         = 0x003F0201,
     CPU_POWERPC_POWER7_v23         = 0x003F0203,
+    CPU_POWERPC_POWER7P            = 0x004A0201,
     CPU_POWERPC_POWER8_v10         = 0x004B0100,
     CPU_POWERPC_970                = 0x00390202,
     CPU_POWERPC_970FX_v10          = 0x00391100,
commit 64160cd2a3e9a8491ce44aaa9df25cfad48b8666
Merge: 144f28f 908c67f
Author: Anthony Liguori <aliguori at us.ibm.com>
Date:   Mon Aug 5 08:06:25 2013 -0500

    Merge remote-tracking branch 'filippov/tags/20130729-xtensa' into staging
    
    xtensa queue 2013-07-29
    
    * filippov/tags/20130729-xtensa:
      target-xtensa: check register window inline
      target-xtensa: don't generate dead code to access invalid SRs
      tests/tcg/xtensa: Fix out-of-tree build
      target-xtensa: avoid double-stopping at breakpoints
      target-xtensa: add fallthrough markers
      target-xtensa: add extui unit test
    
    Conflicts:
    	configure
    
    Signed-off-by: Anthony Liguori <aliguori at us.ibm.com>

diff --cc configure
index 293f167,c205904..18fa608
--- a/configure
+++ b/configure
@@@ -4507,7 -4502,8 +4507,7 @@@ if [ "$dtc_internal" = "yes" ]; the
  fi
  
  # build tree in object directory in case the source is not in the current directory
- DIRS="tests tests/tcg tests/tcg/cris tests/tcg/lm32 tests/libqos tests/qapi-schema"
 -DIRS="tests tests/tcg tests/tcg/cris tests/tcg/lm32 tests/tcg/xtensa"
 -DIRS="$DIRS tests/libqos"
++DIRS="tests tests/tcg tests/tcg/cris tests/tcg/lm32 tests/libqos tests/qapi-schema tests/tcg/xtensa"
  DIRS="$DIRS pc-bios/optionrom pc-bios/spapr-rtas pc-bios/s390-ccw"
  DIRS="$DIRS roms/seabios roms/vgabios"
  DIRS="$DIRS qapi-generated"
commit 144f28fa58abc56d2244a2e6b97ca78e1540dd05
Merge: 59a8877 9a949b9
Author: Anthony Liguori <aliguori at us.ibm.com>
Date:   Mon Aug 5 08:03:01 2013 -0500

    Merge remote-tracking branch 'mcayland/qemu-openbios' into staging
    
    * mcayland/qemu-openbios:
      Update OpenBIOS images
    
    Signed-off-by: Anthony Liguori <aliguori at us.ibm.com>

commit 59a88774d912bb53795daa2d3620707401aea077
Merge: 56105bd ee76c1f
Author: Anthony Liguori <aliguori at us.ibm.com>
Date:   Mon Aug 5 08:01:48 2013 -0500

    Merge remote-tracking branch 'stefanha/net' into staging
    
    # By Jan Kiszka
    # Via Stefan Hajnoczi
    * stefanha/net:
      pcnet: Flush queued packets on end of STOP state
    
    Message-id: 1375704975-19128-1-git-send-email-stefanha at redhat.com
    Signed-off-by: Anthony Liguori <aliguori at us.ibm.com>

commit 56105bd5c0b6d7ac62b34c8b8f496df8f7bd9d92
Merge: f5e7dad 8afaefb
Author: Anthony Liguori <aliguori at us.ibm.com>
Date:   Mon Aug 5 08:01:39 2013 -0500

    Merge remote-tracking branch 'stefanha/block' into staging
    
    # By Kevin Wolf
    # Via Stefan Hajnoczi
    * stefanha/block:
      block: Disable driver-specific options for 1.6
    
    Message-id: 1375461379-20277-1-git-send-email-stefanha at redhat.com
    Signed-off-by: Anthony Liguori <aliguori at us.ibm.com>

commit f5e7dad8ee5673b4de1eaa9a2fa610f0940f26b0
Merge: d94c426 8e50724
Author: Anthony Liguori <aliguori at us.ibm.com>
Date:   Mon Aug 5 08:01:32 2013 -0500

    Merge remote-tracking branch 'mjt/trivial-patches' into staging
    
    # By Fam Zheng (1) and others
    # Via Michael Tokarev
    * mjt/trivial-patches:
      vmdk: fix comment for vmdk_co_write_zeroes
      memory.c: drop kvm.h dependency
      block/iscsi.c: Fix printf format error.
      qemu-ga: build it even if !system
    
    Message-id: 1375453248-7178-1-git-send-email-mjt at msgid.tls.msk.ru
    Signed-off-by: Anthony Liguori <aliguori at us.ibm.com>

commit d94c426d46e01ad45fc5e3b8e5b485ca1b0158fe
Merge: b9ac5d9 a14ff8a
Author: Anthony Liguori <aliguori at us.ibm.com>
Date:   Mon Aug 5 08:01:25 2013 -0500

    Merge remote-tracking branch 'kraxel/usb.86' into staging
    
    # By Gerd Hoffmann
    # Via Gerd Hoffmann
    * kraxel/usb.86:
      usb-redir: fix use-after-free
      xhci: fix segfault
    
    Message-id: 1375362669-14815-1-git-send-email-kraxel at redhat.com
    Signed-off-by: Anthony Liguori <aliguori at us.ibm.com>

commit ee76c1f821e75550644e084dea85743bbc934f91
Author: Jan Kiszka <jan.kiszka at siemens.com>
Date:   Fri Aug 2 21:48:18 2013 +0200

    pcnet: Flush queued packets on end of STOP state
    
    Analogously to other NICs, we have to inform the network layer when
    the can_receive handler will no longer report 0. Without this, we may
    get stuck waiting on queued incoming packets.
    
    Signed-off-by: Jan Kiszka <jan.kiszka at siemens.com>
    Signed-off-by: Stefan Hajnoczi <stefanha at redhat.com>

diff --git a/hw/net/pcnet.c b/hw/net/pcnet.c
index b606d2b..63aa73a 100644
--- a/hw/net/pcnet.c
+++ b/hw/net/pcnet.c
@@ -861,6 +861,8 @@ static void pcnet_init(PCNetState *s)
 
     s->csr[0] |= 0x0101;
     s->csr[0] &= ~0x0004;       /* clear STOP bit */
+
+    qemu_flush_queued_packets(qemu_get_queue(s->nic));
 }
 
 static void pcnet_start(PCNetState *s)
@@ -878,6 +880,8 @@ static void pcnet_start(PCNetState *s)
     s->csr[0] &= ~0x0004;       /* clear STOP bit */
     s->csr[0] |= 0x0002;
     pcnet_poll_timer(s);
+
+    qemu_flush_queued_packets(qemu_get_queue(s->nic));
 }
 
 static void pcnet_stop(PCNetState *s)
commit b9ac5d923b820a0f0152a2df56067e55ce34f487
Author: Yongbok Kim <yongbok.kim at imgtec.com>
Date:   Fri Aug 2 10:33:43 2013 +0100

    target-mips: fix 34Kf configuration for DSP ASE
    
    34Kf core does support DSP ASE.
    CP0_Config3 configuration for 34Kf and description are wrong.
    
    Please refer to MIPS32(R) 34Kf(TM) Processor Core Datasheet
    
    Signed-off-by: Yongbok Kim <yongbok.kim at imgtec.com>
    Signed-off-by: Aurelien Jarno <aurelien at aurel32.net>

diff --git a/target-mips/translate_init.c b/target-mips/translate_init.c
index 7cf238f..c45b1b2 100644
--- a/target-mips/translate_init.c
+++ b/target-mips/translate_init.c
@@ -274,14 +274,13 @@ static const mips_def_t mips_defs[] =
                        (0 << CP0C1_DS) | (3 << CP0C1_DL) | (1 << CP0C1_DA) |
                        (1 << CP0C1_CA),
         .CP0_Config2 = MIPS_CONFIG2,
-        .CP0_Config3 = MIPS_CONFIG3 | (1 << CP0C3_VInt) | (1 << CP0C3_MT),
+        .CP0_Config3 = MIPS_CONFIG3 | (1 << CP0C3_VInt) | (1 << CP0C3_MT) |
+                       (1 << CP0C3_DSPP),
         .CP0_LLAddr_rw_bitmask = 0,
         .CP0_LLAddr_shift = 0,
         .SYNCI_Step = 32,
         .CCRes = 2,
-        /* No DSP implemented. */
-        .CP0_Status_rw_bitmask = 0x3678FF1F,
-        /* No DSP implemented. */
+        .CP0_Status_rw_bitmask = 0x3778FF1F,
         .CP0_TCStatus_rw_bitmask = (0 << CP0TCSt_TCU3) | (0 << CP0TCSt_TCU2) |
                     (1 << CP0TCSt_TCU1) | (1 << CP0TCSt_TCU0) |
                     (0 << CP0TCSt_TMX) | (1 << CP0TCSt_DT) |
commit 8afaefb8919dc8746a57c450a758717c516c7b0a
Author: Kevin Wolf <kwolf at redhat.com>
Date:   Tue Jul 30 14:58:27 2013 +0200

    block: Disable driver-specific options for 1.6
    
    We don't want to commit to the API yet before everything is worked out.
    Like already for 1.5, disable it again for the 1.6 release. This commit
    is meant to be reverted after the 1.6 release.
    
    The disabling of the driver-specific options is achieved by applying the
    old checks while parsing the command line.
    
    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/blockdev.c b/blockdev.c
index 7879e85..41b0a49 100644
--- a/blockdev.c
+++ b/blockdev.c
@@ -46,6 +46,7 @@
 
 static QTAILQ_HEAD(drivelist, DriveInfo) drives = QTAILQ_HEAD_INITIALIZER(drives);
 extern QemuOptsList qemu_common_drive_opts;
+extern QemuOptsList qemu_old_drive_opts;
 
 static const char *const if_name[IF_COUNT] = {
     [IF_NONE] = "none",
@@ -745,6 +746,26 @@ DriveInfo *drive_init(QemuOpts *all_opts, BlockInterfaceType block_default_type)
 {
     const char *value;
 
+    /*
+     * Check that only old options are used by copying into a QemuOpts with
+     * stricter checks. Going through a QDict seems to be the easiest way to
+     * achieve this...
+     */
+    QemuOpts* check_opts;
+    QDict *qdict;
+    Error *local_err = NULL;
+
+    qdict = qemu_opts_to_qdict(all_opts, NULL);
+    check_opts = qemu_opts_from_qdict(&qemu_old_drive_opts, qdict, &local_err);
+    QDECREF(qdict);
+
+    if (error_is_set(&local_err)) {
+        qerror_report_err(local_err);
+        error_free(local_err);
+        return NULL;
+    }
+    qemu_opts_del(check_opts);
+
     /* Change legacy command line options into QMP ones */
     qemu_opt_rename(all_opts, "iops", "throttling.iops-total");
     qemu_opt_rename(all_opts, "iops_rd", "throttling.iops-read");
@@ -1971,6 +1992,128 @@ QemuOptsList qemu_common_drive_opts = {
     },
 };
 
+QemuOptsList qemu_old_drive_opts = {
+    .name = "drive",
+    .head = QTAILQ_HEAD_INITIALIZER(qemu_old_drive_opts.head),
+    .desc = {
+        {
+            .name = "bus",
+            .type = QEMU_OPT_NUMBER,
+            .help = "bus number",
+        },{
+            .name = "unit",
+            .type = QEMU_OPT_NUMBER,
+            .help = "unit number (i.e. lun for scsi)",
+        },{
+            .name = "if",
+            .type = QEMU_OPT_STRING,
+            .help = "interface (ide, scsi, sd, mtd, floppy, pflash, virtio)",
+        },{
+            .name = "index",
+            .type = QEMU_OPT_NUMBER,
+            .help = "index number",
+        },{
+            .name = "cyls",
+            .type = QEMU_OPT_NUMBER,
+            .help = "number of cylinders (ide disk geometry)",
+        },{
+            .name = "heads",
+            .type = QEMU_OPT_NUMBER,
+            .help = "number of heads (ide disk geometry)",
+        },{
+            .name = "secs",
+            .type = QEMU_OPT_NUMBER,
+            .help = "number of sectors (ide disk geometry)",
+        },{
+            .name = "trans",
+            .type = QEMU_OPT_STRING,
+            .help = "chs translation (auto, lba. none)",
+        },{
+            .name = "media",
+            .type = QEMU_OPT_STRING,
+            .help = "media type (disk, cdrom)",
+        },{
+            .name = "snapshot",
+            .type = QEMU_OPT_BOOL,
+            .help = "enable/disable snapshot mode",
+        },{
+            .name = "file",
+            .type = QEMU_OPT_STRING,
+            .help = "disk image",
+        },{
+            .name = "discard",
+            .type = QEMU_OPT_STRING,
+            .help = "discard operation (ignore/off, unmap/on)",
+        },{
+            .name = "cache",
+            .type = QEMU_OPT_STRING,
+            .help = "host cache usage (none, writeback, writethrough, "
+                    "directsync, unsafe)",
+        },{
+            .name = "aio",
+            .type = QEMU_OPT_STRING,
+            .help = "host AIO implementation (threads, native)",
+        },{
+            .name = "format",
+            .type = QEMU_OPT_STRING,
+            .help = "disk format (raw, qcow2, ...)",
+        },{
+            .name = "serial",
+            .type = QEMU_OPT_STRING,
+            .help = "disk serial number",
+        },{
+            .name = "rerror",
+            .type = QEMU_OPT_STRING,
+            .help = "read error action",
+        },{
+            .name = "werror",
+            .type = QEMU_OPT_STRING,
+            .help = "write error action",
+        },{
+            .name = "addr",
+            .type = QEMU_OPT_STRING,
+            .help = "pci address (virtio only)",
+        },{
+            .name = "readonly",
+            .type = QEMU_OPT_BOOL,
+            .help = "open drive file as read-only",
+        },{
+            .name = "iops",
+            .type = QEMU_OPT_NUMBER,
+            .help = "limit total I/O operations per second",
+        },{
+            .name = "iops_rd",
+            .type = QEMU_OPT_NUMBER,
+            .help = "limit read operations per second",
+        },{
+            .name = "iops_wr",
+            .type = QEMU_OPT_NUMBER,
+            .help = "limit write operations per second",
+        },{
+            .name = "bps",
+            .type = QEMU_OPT_NUMBER,
+            .help = "limit total bytes per second",
+        },{
+            .name = "bps_rd",
+            .type = QEMU_OPT_NUMBER,
+            .help = "limit read bytes per second",
+        },{
+            .name = "bps_wr",
+            .type = QEMU_OPT_NUMBER,
+            .help = "limit write bytes per second",
+        },{
+            .name = "copy-on-read",
+            .type = QEMU_OPT_BOOL,
+            .help = "copy read data from backing file into image file",
+        },{
+            .name = "boot",
+            .type = QEMU_OPT_BOOL,
+            .help = "(deprecated, ignored)",
+        },
+        { /* end of list */ }
+    },
+};
+
 QemuOptsList qemu_drive_opts = {
     .name = "drive",
     .head = QTAILQ_HEAD_INITIALIZER(qemu_drive_opts.head),
diff --git a/tests/qemu-iotests/group b/tests/qemu-iotests/group
index b1d03c7..69e208c 100644
--- a/tests/qemu-iotests/group
+++ b/tests/qemu-iotests/group
@@ -57,7 +57,7 @@
 048 img auto quick
 049 rw auto
 050 rw auto backing quick
-051 rw auto
+#051 rw auto
 052 rw auto backing
 053 rw auto
 054 rw auto
commit 8e50724313895a87057cc243ad805f2eb21feb9f
Author: Fam Zheng <famz at redhat.com>
Date:   Thu Aug 1 18:12:17 2013 +0800

    vmdk: fix comment for vmdk_co_write_zeroes
    
    The comment was truncated. Add the missing parts, especially explain why
    we need zero_dry_run.
    
    Signed-off-by: Fam Zheng <famz at redhat.com>
    Signed-off-by: Michael Tokarev <mjt at tls.msk.ru>

diff --git a/block/vmdk.c b/block/vmdk.c
index 3756333..e6c50b1 100644
--- a/block/vmdk.c
+++ b/block/vmdk.c
@@ -1200,8 +1200,10 @@ static coroutine_fn int vmdk_co_read(BlockDriverState *bs, int64_t sector_num,
 /**
  * vmdk_write:
  * @zeroed:       buf is ignored (data is zero), use zeroed_grain GTE feature
- * if possible, otherwise return -ENOTSUP.
- * @zero_dry_run: used for zeroed == true only, don't update L2 table, just
+ *                if possible, otherwise return -ENOTSUP.
+ * @zero_dry_run: used for zeroed == true only, don't update L2 table, just try
+ *                with each cluster. By dry run we can find if the zero write
+ *                is possible without modifying image data.
  *
  * Returns: error code with 0 for success.
  */
@@ -1328,6 +1330,8 @@ static int coroutine_fn vmdk_co_write_zeroes(BlockDriverState *bs,
     int ret;
     BDRVVmdkState *s = bs->opaque;
     qemu_co_mutex_lock(&s->lock);
+    /* write zeroes could fail if sectors not aligned to cluster, test it with
+     * dry_run == true before really updating image */
     ret = vmdk_write(bs, sector_num, NULL, nb_sectors, true, true);
     if (!ret) {
         ret = vmdk_write(bs, sector_num, NULL, nb_sectors, true, false);
commit 437de2adc633ed28cdd84bcdffc3430b5ce96be6
Author: Michael S. Tsirkin <mst at redhat.com>
Date:   Thu Aug 1 10:55:30 2013 +0300

    memory.c: drop kvm.h dependency
    
    memory.c does not use any kvm specific interfaces,
    don't include kvm.h
    
    Signed-off-by: Michael S. Tsirkin <mst at redhat.com>
    Acked-by: Paolo Bonzini <pbonzini at redhat.com>
    Signed-off-by: Michael Tokarev <mjt at tls.msk.ru>

diff --git a/memory.c b/memory.c
index ac6f3c6..886f838 100644
--- a/memory.c
+++ b/memory.c
@@ -18,7 +18,6 @@
 #include "exec/ioport.h"
 #include "qemu/bitops.h"
 #include "qom/object.h"
-#include "sysemu/kvm.h"
 #include "trace.h"
 #include <assert.h>
 
commit f5075224d6e7fe8cae7e3c1b52a6d0f7bd3533d0
Author: Richard W.M. Jones <rjones at redhat.com>
Date:   Wed Jul 31 22:20:26 2013 +0100

    block/iscsi.c: Fix printf format error.
    
    The error on armv7hl was:
    
    block/iscsi.c: In function ‘is_request_lun_aligned’:
    block/iscsi.c:251:26: error: format ‘%ld’ expects argument of type ‘long int’, but argument 3 has type ‘int64_t’ [-Werror=format=]
                              iscsilun->block_size, sector_num, nb_sectors);
                              ^
    
    This also splits the long line to comply with qemu coding guidelines.
    
    Signed-off-by: Richard W.M. Jones <rjones at redhat.com>
    Reviewed-by: Stefan Weil <sw at weilnetz.de>
    Reviewed-by: Stefan Hajnoczi <stefanha at redhat.com>
    Signed-off-by: Michael Tokarev <mjt at tls.msk.ru>

diff --git a/block/iscsi.c b/block/iscsi.c
index 5f28c6a..e7c1c2b 100644
--- a/block/iscsi.c
+++ b/block/iscsi.c
@@ -247,7 +247,9 @@ static bool is_request_lun_aligned(int64_t sector_num, int nb_sectors,
 {
     if ((sector_num * BDRV_SECTOR_SIZE) % iscsilun->block_size ||
         (nb_sectors * BDRV_SECTOR_SIZE) % iscsilun->block_size) {
-            error_report("iSCSI misaligned request: iscsilun->block_size %u, sector_num %ld, nb_sectors %d",
+            error_report("iSCSI misaligned request: "
+                         "iscsilun->block_size %u, sector_num %" PRIi64
+                         ", nb_sectors %d",
                          iscsilun->block_size, sector_num, nb_sectors);
             return 0;
     }
commit e8ef31a3518c7b1e63a804fe8cecd3e94418db84
Author: Michael Tokarev <mjt at tls.msk.ru>
Date:   Wed Jul 31 14:22:07 2013 +0400

    qemu-ga: build it even if !system
    
    Move qemu-ga build check out of if softmmu.. into its own section.
    We want to build qemu-ga for _guest_ even if system build isn't
    done.  It is controlled separately using --enable-guest-agent.
    Additionally, give error message if guest agent is requested but
    not supported.
    
    Signed-off-by: Michael Tokarev <mjt at tls.msk.ru>

diff --git a/configure b/configure
index f0761ea..293f167 100755
--- a/configure
+++ b/configure
@@ -231,7 +231,7 @@ libusb=""
 usb_redir=""
 glx=""
 zlib="yes"
-guest_agent="yes"
+guest_agent=""
 want_tools="yes"
 libiscsi=""
 coroutine=""
@@ -3444,10 +3444,15 @@ if test "$softmmu" = yes ; then
       virtfs=no
     fi
   fi
+fi
+if [ "$guest_agent" != "no" ]; then
   if [ "$linux" = "yes" -o "$bsd" = "yes" -o "$solaris" = "yes" ] ; then
-    if [ "$guest_agent" = "yes" ]; then
       tools="qemu-ga\$(EXESUF) $tools"
-    fi
+      guest_agent=yes
+  elif [ "$guest_agent" != yes ]; then
+      guest_agent=no
+  else
+      error_exit "Guest agent is not supported on this platform"
   fi
 fi
 
commit 2ddc463725d0fa24e0910fba77fef2777fa94a74
Merge: 00f90df e0d4794
Author: Anthony Liguori <aliguori at us.ibm.com>
Date:   Thu Aug 1 17:09:35 2013 -0500

    Merge remote-tracking branch 'afaerber/tags/qom-cpu-for-anthony' into staging
    
    QOM CPUState refactorings
    
    * Clean up AlphaCPU and OpenRISCCPU migration
    
    # gpg: Signature made Wed 31 Jul 2013 04:57:59 PM CDT using RSA key ID 3E7E013F
    # gpg: Can't check signature: public key not found
    
    # By Andreas Färber
    # Via Andreas Färber
    * afaerber/tags/qom-cpu-for-anthony:
      cpu: Fix VMSTATE_CPU() semantics

commit 00f90df09368035fcfe6a06cd87a6c88f82f2afe
Merge: e501425 5c97367
Author: Anthony Liguori <aliguori at us.ibm.com>
Date:   Thu Aug 1 17:09:28 2013 -0500

    Merge remote-tracking branch 'afaerber/tags/prep-for-upstream' into staging
    
    PReP machine and devices
    
    * Fixes for i82378 PCI-ISA bridge endianness handling
    
    # gpg: Signature made Wed 31 Jul 2013 04:25:51 PM CDT using RSA key ID 3E7E013F
    # gpg: Can't check signature: public key not found
    
    # By Hervé Poussineau
    # Via Andreas Färber
    * afaerber/tags/prep-for-upstream:
      i82378: Cleanup implementation
      pci-host/prep: Set isa_mem_base in the PCI host bridge

commit e501425bbe8d692f022d3db64abf800eaf4f0854
Author: Anthony Liguori <aliguori at us.ibm.com>
Date:   Thu Aug 1 16:59:32 2013 -0500

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

diff --git a/VERSION b/VERSION
index 81fd881..80b2369 100644
--- a/VERSION
+++ b/VERSION
@@ -1 +1 @@
-1.5.90
+1.5.91
commit 203439ce0a832e36b276f10892846bd91ee836eb
Author: Andreas Färber <afaerber at suse.de>
Date:   Thu Aug 1 01:28:46 2013 +0200

    virtio-console: Use exitfn for virtserialport, too
    
    virtconsole and virtserialport are identical in every other aspect
    except for the distinguishing VirtIOSerialPortClass::is_console field.
    
    Cc: qemu-stable at nongnu.org
    Signed-off-by: Andreas Färber <afaerber at suse.de>
    Signed-off-by: Andreas Färber <afaerber at suse.de>
    Message-id: 1375313326-14966-1-git-send-email-afaerber at suse.de
    Signed-off-by: Anthony Liguori <aliguori at us.ibm.com>

diff --git a/hw/char/virtio-console.c b/hw/char/virtio-console.c
index 6759e51..2e00ad2 100644
--- a/hw/char/virtio-console.c
+++ b/hw/char/virtio-console.c
@@ -185,6 +185,7 @@ static void virtserialport_class_init(ObjectClass *klass, void *data)
     VirtIOSerialPortClass *k = VIRTIO_SERIAL_PORT_CLASS(klass);
 
     k->init = virtconsole_initfn;
+    k->exit = virtconsole_exitfn;
     k->have_data = flush_buf;
     k->set_guest_connected = set_guest_connected;
     dc->props = virtserialport_properties;
commit 27915efb974999dd256a6c432a17432d9d84e606
Author: Andreas Färber <afaerber at suse.de>
Date:   Thu Aug 1 01:59:47 2013 +0200

    virtio-9p-device: Avoid freeing uninitialized memory
    
    In virtio_9p_device_init() there are 6x goto out that will lead to
    v9fs_path_free() attempting to free unitialized path.data field.
    Easiest way to trigger is: qemu-system-x86_64 -device virtio-9p-pci
    
    Fix this by moving v9fs_path_init() before any goto out.
    
    Signed-off-by: Andreas Färber <afaerber at suse.de>
    Signed-off-by: Andreas Färber <afaerber at suse.de>
    Message-id: 1375315187-16534-1-git-send-email-afaerber at suse.de
    Signed-off-by: Anthony Liguori <aliguori at us.ibm.com>

diff --git a/hw/9pfs/virtio-9p-device.c b/hw/9pfs/virtio-9p-device.c
index de6f0fe..f0ffbe8 100644
--- a/hw/9pfs/virtio-9p-device.c
+++ b/hw/9pfs/virtio-9p-device.c
@@ -61,6 +61,8 @@ static int virtio_9p_device_init(VirtIODevice *vdev)
 
     s->vq = virtio_add_queue(vdev, MAX_REQ, handle_9p_output);
 
+    v9fs_path_init(&path);
+
     fse = get_fsdev_fsentry(s->fsconf.fsdev_id);
 
     if (!fse) {
@@ -111,7 +113,6 @@ static int virtio_9p_device_init(VirtIODevice *vdev)
      * call back to do that. Since we are in the init path, we don't
      * use co-routines here.
      */
-    v9fs_path_init(&path);
     if (s->ops->name_to_path(&s->ctx, NULL, "/", &path) < 0) {
         fprintf(stderr,
                 "error in converting name to path %s", strerror(errno));
commit d5a2bcf70e81b67cbc4947f5065db8fc9bfc1465
Merge: f44c5c6 8c0426a
Author: Anthony Liguori <aliguori at us.ibm.com>
Date:   Thu Aug 1 11:18:04 2013 -0500

    Merge remote-tracking branch 'luiz/queue/qmp' into staging
    
    # By Pawit Pornkitprasan
    # Via Luiz Capitulino
    * luiz/queue/qmp:
      migration: don't use uninitialized variables
      migration: send total time in QMP at "completed" stage
    
    Message-id: 1375367564-4797-1-git-send-email-lcapitulino at redhat.com
    Signed-off-by: Anthony Liguori <aliguori at us.ibm.com>

commit 8c0426aed1d2279845e6a2c3355da8b5d9926cb6
Author: Pawit Pornkitprasan <p.pawit at gmail.com>
Date:   Tue Jul 30 08:39:52 2013 +0900

    migration: don't use uninitialized variables
    
    The qmp_migrate method uses the 'blk' and 'inc' parameter without
    checking if they're valid or not (they may be uninitialized if
    command is received via QMP)
    
    Signed-off-by: Pawit Pornkitprasan <p.pawit at gmail.com>
    Reviewed-by: Eric Blake <eblake at redhat.com>
    Signed-off-by: Luiz Capitulino <lcapitulino at redhat.com>

diff --git a/migration.c b/migration.c
index 3f682cd..1402fa7 100644
--- a/migration.c
+++ b/migration.c
@@ -400,8 +400,8 @@ void qmp_migrate(const char *uri, bool has_blk, bool blk,
     MigrationParams params;
     const char *p;
 
-    params.blk = blk;
-    params.shared = inc;
+    params.blk = has_blk && blk;
+    params.shared = has_inc && inc;
 
     if (s->state == MIG_STATE_ACTIVE || s->state == MIG_STATE_SETUP) {
         error_set(errp, QERR_MIGRATION_ACTIVE);
commit 00c14997cb95bf3e6c18c2264ef5e10642d89b3a
Author: Pawit Pornkitprasan <p.pawit at gmail.com>
Date:   Fri Jul 19 11:23:45 2013 +0900

    migration: send total time in QMP at "completed" stage
    
    The "completed" stage sets total_time but not has_total_time and
    thus it is not sent via QMP reply (but sent via HMP nevertheless)
    
    Signed-off-by: Pawit Pornkitprasan <p.pawit at gmail.com>
    Reviewed-by: Eric Blake <eblake at redhat.com>
    Reviewed-by: Orit Wasserman <owasserm at redhat.com>
    Signed-off-by: Luiz Capitulino <lcapitulino at redhat.com>

diff --git a/migration.c b/migration.c
index 9fc7294..3f682cd 100644
--- a/migration.c
+++ b/migration.c
@@ -231,6 +231,7 @@ MigrationInfo *qmp_query_migrate(Error **errp)
 
         info->has_status = true;
         info->status = g_strdup("completed");
+        info->has_total_time = true;
         info->total_time = s->total_time;
         info->has_downtime = true;
         info->downtime = s->downtime;
commit a14ff8a650b5943ee6221b952494661f7cb3b5e2
Author: Gerd Hoffmann <kraxel at redhat.com>
Date:   Wed Jul 31 11:17:58 2013 +0200

    usb-redir: fix use-after-free
    
    Reinitialize dev->cs to NULL after deleting it, to make sure it isn't
    used afterwards.
    
    Reported-by: Martin Cerveny <M.Cerveny at computer.org>
    Signed-off-by: Gerd Hoffmann <kraxel at redhat.com>

diff --git a/hw/usb/redirect.c b/hw/usb/redirect.c
index 8b8c010..e3b9f32 100644
--- a/hw/usb/redirect.c
+++ b/hw/usb/redirect.c
@@ -1334,6 +1334,7 @@ static void usbredir_handle_destroy(USBDevice *udev)
     USBRedirDevice *dev = DO_UPCAST(USBRedirDevice, dev, udev);
 
     qemu_chr_delete(dev->cs);
+    dev->cs = NULL;
     /* Note must be done after qemu_chr_close, as that causes a close event */
     qemu_bh_delete(dev->chardev_close_bh);
 
commit 75cc1c1fcba1987bdf3979c4289ab756c2b15742
Author: Gerd Hoffmann <kraxel at redhat.com>
Date:   Wed Jul 31 10:54:11 2013 +0200

    xhci: fix segfault
    
    Guest trying to reset a endpoint of a disconnected device resulted in
    xhci trying to dereference uport while being NULL, thereby crashing
    qemu.  Fix that by adding a check.  Drop unused dev variable while
    touching that code bit.
    
    Cc: qemu-stable at nongnu.org
    Signed-off-by: Gerd Hoffmann <kraxel at redhat.com>

diff --git a/hw/usb/hcd-xhci.c b/hw/usb/hcd-xhci.c
index 7cbf813..ff5f681 100644
--- a/hw/usb/hcd-xhci.c
+++ b/hw/usb/hcd-xhci.c
@@ -1429,7 +1429,6 @@ static TRBCCode xhci_reset_ep(XHCIState *xhci, unsigned int slotid,
 {
     XHCISlot *slot;
     XHCIEPContext *epctx;
-    USBDevice *dev;
 
     trace_usb_xhci_ep_reset(slotid, epid);
     assert(slotid >= 1 && slotid <= xhci->numslots);
@@ -1465,8 +1464,8 @@ static TRBCCode xhci_reset_ep(XHCIState *xhci, unsigned int slotid,
         ep |= 0x80;
     }
 
-    dev = xhci->slots[slotid-1].uport->dev;
-    if (!dev) {
+    if (!xhci->slots[slotid-1].uport ||
+        !xhci->slots[slotid-1].uport->dev) {
         return CC_USB_TRANSACTION_ERROR;
     }
 
commit 5c9736789b79ea49cd236ac326f0a414f63b1015
Author: Hervé Poussineau <hpoussin at reactos.org>
Date:   Tue Jul 23 23:16:46 2013 +0200

    i82378: Cleanup implementation
    
    - i82378 only exists on PCI bus; do not split implementation in 2 structs
    - remove BARs, which are not specified in datasheet
    - replace custom isa_mmio implementation by PCI bus IO region usage
    - use QOM casts when required
    
    Signed-off-by: Hervé Poussineau <hpoussin at reactos.org>
    [AF: Style- and QOM-related changes, dropped no_user, reverted VMSD name]
    Signed-off-by: Andreas Färber <andreas.faerber at web.de>

diff --git a/hw/isa/i82378.c b/hw/isa/i82378.c
index 9b8674a..a7d9aa6 100644
--- a/hw/isa/i82378.c
+++ b/hw/isa/i82378.c
@@ -22,134 +22,28 @@
 #include "hw/timer/i8254.h"
 #include "hw/audio/pcspk.h"
 
-//#define DEBUG_I82378
-
-#ifdef DEBUG_I82378
-#define DPRINTF(fmt, ...) \
-do { fprintf(stderr, "i82378: " fmt , ## __VA_ARGS__); } while (0)
-#else
-#define DPRINTF(fmt, ...) \
-do {} while (0)
-#endif
-
-#define BADF(fmt, ...) \
-do { fprintf(stderr, "i82378 ERROR: " fmt , ## __VA_ARGS__); } while (0)
+#define TYPE_I82378 "i82378"
+#define I82378(obj) \
+    OBJECT_CHECK(I82378State, (obj), TYPE_I82378)
 
 typedef struct I82378State {
+    PCIDevice parent_obj;
+
     qemu_irq out[2];
     qemu_irq *i8259;
     MemoryRegion io;
-    MemoryRegion mem;
 } I82378State;
 
-typedef struct PCIi82378State {
-    PCIDevice pci_dev;
-    uint32_t isa_io_base;
-    I82378State state;
-} PCIi82378State;
-
-static const VMStateDescription vmstate_pci_i82378 = {
+static const VMStateDescription vmstate_i82378 = {
     .name = "pci-i82378",
     .version_id = 0,
     .minimum_version_id = 0,
     .fields = (VMStateField[]) {
-        VMSTATE_PCI_DEVICE(pci_dev, PCIi82378State),
+        VMSTATE_PCI_DEVICE(parent_obj, I82378State),
         VMSTATE_END_OF_LIST()
     },
 };
 
-static void i82378_io_write(void *opaque, hwaddr addr,
-                            uint64_t value, unsigned int size)
-{
-    switch (size) {
-    case 1:
-        DPRINTF("%s: " TARGET_FMT_plx "=%02" PRIx64 "\n", __func__,
-                addr, value);
-        cpu_outb(addr, value);
-        break;
-    case 2:
-        DPRINTF("%s: " TARGET_FMT_plx "=%04" PRIx64 "\n", __func__,
-                addr, value);
-        cpu_outw(addr, value);
-        break;
-    case 4:
-        DPRINTF("%s: " TARGET_FMT_plx "=%08" PRIx64 "\n", __func__,
-                addr, value);
-        cpu_outl(addr, value);
-        break;
-    default:
-        abort();
-    }
-}
-
-static uint64_t i82378_io_read(void *opaque, hwaddr addr,
-                               unsigned int size)
-{
-    DPRINTF("%s: " TARGET_FMT_plx "\n", __func__, addr);
-    switch (size) {
-    case 1:
-        return cpu_inb(addr);
-    case 2:
-        return cpu_inw(addr);
-    case 4:
-        return cpu_inl(addr);
-    default:
-        abort();
-    }
-}
-
-static const MemoryRegionOps i82378_io_ops = {
-    .read = i82378_io_read,
-    .write = i82378_io_write,
-    .endianness = DEVICE_LITTLE_ENDIAN,
-};
-
-static void i82378_mem_write(void *opaque, hwaddr addr,
-                             uint64_t value, unsigned int size)
-{
-    switch (size) {
-    case 1:
-        DPRINTF("%s: " TARGET_FMT_plx "=%02" PRIx64 "\n", __func__,
-                addr, value);
-        cpu_outb(addr, value);
-        break;
-    case 2:
-        DPRINTF("%s: " TARGET_FMT_plx "=%04" PRIx64 "\n", __func__,
-                addr, value);
-        cpu_outw(addr, value);
-        break;
-    case 4:
-        DPRINTF("%s: " TARGET_FMT_plx "=%08" PRIx64 "\n", __func__,
-                addr, value);
-        cpu_outl(addr, value);
-        break;
-    default:
-        abort();
-    }
-}
-
-static uint64_t i82378_mem_read(void *opaque, hwaddr addr,
-                                unsigned int size)
-{
-    DPRINTF("%s: " TARGET_FMT_plx "\n", __func__, addr);
-    switch (size) {
-    case 1:
-        return cpu_inb(addr);
-    case 2:
-        return cpu_inw(addr);
-    case 4:
-        return cpu_inl(addr);
-    default:
-        abort();
-    }
-}
-
-static const MemoryRegionOps i82378_mem_ops = {
-    .read = i82378_mem_read,
-    .write = i82378_mem_write,
-    .endianness = DEVICE_LITTLE_ENDIAN,
-};
-
 static void i82378_request_out0_irq(void *opaque, int irq, int level)
 {
     I82378State *s = opaque;
@@ -159,19 +53,30 @@ static void i82378_request_out0_irq(void *opaque, int irq, int level)
 static void i82378_request_pic_irq(void *opaque, int irq, int level)
 {
     DeviceState *dev = opaque;
-    PCIDevice *pci = DO_UPCAST(PCIDevice, qdev, dev);
-    PCIi82378State *s = DO_UPCAST(PCIi82378State, pci_dev, pci);
+    I82378State *s = I82378(dev);
 
-    qemu_set_irq(s->state.i8259[irq], level);
+    qemu_set_irq(s->i8259[irq], level);
 }
 
-static void i82378_init(DeviceState *dev, I82378State *s)
+static int i82378_initfn(PCIDevice *pci)
 {
-    ISABus *isabus = ISA_BUS(qdev_get_child_bus(dev, "isa.0"));
-    ISADevice *pit;
+    DeviceState *dev = DEVICE(pci);
+    I82378State *s = I82378(dev);
+    uint8_t *pci_conf;
+    ISABus *isabus;
     ISADevice *isa;
     qemu_irq *out0_irq;
 
+    pci_conf = pci->config;
+    pci_set_word(pci_conf + PCI_COMMAND,
+                 PCI_COMMAND_IO | PCI_COMMAND_MEMORY | PCI_COMMAND_MASTER);
+    pci_set_word(pci_conf + PCI_STATUS,
+                 PCI_STATUS_DEVSEL_MEDIUM);
+
+    pci_config_set_interrupt_pin(pci_conf, 1); /* interrupt pin 0 */
+
+    isabus = isa_bus_new(dev, pci_address_space_io(pci));
+
     /* This device has:
        2 82C59 (irq)
        1 82C54 (pit)
@@ -182,9 +87,6 @@ static void i82378_init(DeviceState *dev, I82378State *s)
        All devices accept byte access only, except timer
      */
 
-    qdev_init_gpio_out(dev, s->out, 2);
-    qdev_init_gpio_in(dev, i82378_request_pic_irq, 16);
-
     /* Workaround the fact that i8259 is not qdev'ified... */
     out0_irq = qemu_allocate_irqs(i82378_request_out0_irq, s, 1);
 
@@ -193,10 +95,10 @@ static void i82378_init(DeviceState *dev, I82378State *s)
     isa_bus_irqs(isabus, s->i8259);
 
     /* 1 82C54 (pit) */
-    pit = pit_init(isabus, 0x40, 0, NULL);
+    isa = pit_init(isabus, 0x40, 0, NULL);
 
     /* speaker */
-    pcspk_init(isabus, pit);
+    pcspk_init(isabus, isa);
 
     /* 2 82C37 (dma) */
     isa = isa_create_simple(isabus, "i82374");
@@ -204,74 +106,44 @@ static void i82378_init(DeviceState *dev, I82378State *s)
 
     /* timer */
     isa_create_simple(isabus, "mc146818rtc");
+
+    return 0;
 }
 
-static int pci_i82378_init(PCIDevice *dev)
+static void i82378_init(Object *obj)
 {
-    PCIi82378State *pci = DO_UPCAST(PCIi82378State, pci_dev, dev);
-    I82378State *s = &pci->state;
-    uint8_t *pci_conf;
+    DeviceState *dev = DEVICE(obj);
+    I82378State *s = I82378(obj);
 
-    pci_conf = dev->config;
-    pci_set_word(pci_conf + PCI_COMMAND,
-                 PCI_COMMAND_IO | PCI_COMMAND_MEMORY | PCI_COMMAND_MASTER);
-    pci_set_word(pci_conf + PCI_STATUS,
-                 PCI_STATUS_DEVSEL_MEDIUM);
-
-    pci_conf[PCI_INTERRUPT_PIN] = 1; /* interrupt pin 0 */
-
-    memory_region_init_io(&s->io, OBJECT(pci), &i82378_io_ops, s,
-                          "i82378-io", 0x00010000);
-    pci_register_bar(dev, 0, PCI_BASE_ADDRESS_SPACE_MEMORY, &s->io);
-
-    memory_region_init_io(&s->mem, OBJECT(pci), &i82378_mem_ops, s,
-                          "i82378-mem", 0x01000000);
-    pci_register_bar(dev, 1, PCI_BASE_ADDRESS_SPACE_MEMORY, &s->mem);
-
-    /* Make I/O address read only */
-    pci_set_word(dev->wmask + PCI_COMMAND, PCI_COMMAND_SPECIAL);
-    pci_set_long(dev->wmask + PCI_BASE_ADDRESS_0, 0);
-    pci_set_long(pci_conf + PCI_BASE_ADDRESS_0, pci->isa_io_base);
-
-    isa_bus_new(&dev->qdev, pci_address_space_io(dev));
-
-    i82378_init(&dev->qdev, s);
-
-    return 0;
+    qdev_init_gpio_out(dev, s->out, 2);
+    qdev_init_gpio_in(dev, i82378_request_pic_irq, 16);
 }
 
-static Property i82378_properties[] = {
-    DEFINE_PROP_HEX32("iobase", PCIi82378State, isa_io_base, 0x80000000),
-    DEFINE_PROP_END_OF_LIST()
-};
-
-static void pci_i82378_class_init(ObjectClass *klass, void *data)
+static void i82378_class_init(ObjectClass *klass, void *data)
 {
     PCIDeviceClass *k = PCI_DEVICE_CLASS(klass);
     DeviceClass *dc = DEVICE_CLASS(klass);
 
-    k->init = pci_i82378_init;
+    k->init = i82378_initfn;
     k->vendor_id = PCI_VENDOR_ID_INTEL;
     k->device_id = PCI_DEVICE_ID_INTEL_82378;
     k->revision = 0x03;
     k->class_id = PCI_CLASS_BRIDGE_ISA;
-    k->subsystem_vendor_id = 0x0;
-    k->subsystem_id = 0x0;
-    dc->vmsd = &vmstate_pci_i82378;
+    dc->vmsd = &vmstate_i82378;
     set_bit(DEVICE_CATEGORY_BRIDGE, dc->categories);
-    dc->props = i82378_properties;
 }
 
-static const TypeInfo pci_i82378_info = {
-    .name = "i82378",
+static const TypeInfo i82378_type_info = {
+    .name = TYPE_I82378,
     .parent = TYPE_PCI_DEVICE,
-    .instance_size = sizeof(PCIi82378State),
-    .class_init = pci_i82378_class_init,
+    .instance_size = sizeof(I82378State),
+    .instance_init = i82378_init,
+    .class_init = i82378_class_init,
 };
 
 static void i82378_register_types(void)
 {
-    type_register_static(&pci_i82378_info);
+    type_register_static(&i82378_type_info);
 }
 
 type_init(i82378_register_types)
commit 768d7e2c7f5d20f412506f3a31626185ac54c559
Author: Hervé Poussineau <hpoussin at reactos.org>
Date:   Tue Jul 23 23:16:45 2013 +0200

    pci-host/prep: Set isa_mem_base in the PCI host bridge
    
    Currently, it is done by i82378 PCI-ISA bridge, which shouldn't
    care about it.
    
    Signed-off-by: Hervé Poussineau <hpoussin at reactos.org>
    Signed-off-by: Andreas Färber <andreas.faerber at web.de>

diff --git a/hw/isa/i82378.c b/hw/isa/i82378.c
index a542134..9b8674a 100644
--- a/hw/isa/i82378.c
+++ b/hw/isa/i82378.c
@@ -45,7 +45,6 @@ typedef struct I82378State {
 typedef struct PCIi82378State {
     PCIDevice pci_dev;
     uint32_t isa_io_base;
-    uint32_t isa_mem_base;
     I82378State state;
 } PCIi82378State;
 
@@ -234,7 +233,6 @@ static int pci_i82378_init(PCIDevice *dev)
     pci_set_long(dev->wmask + PCI_BASE_ADDRESS_0, 0);
     pci_set_long(pci_conf + PCI_BASE_ADDRESS_0, pci->isa_io_base);
 
-    isa_mem_base = pci->isa_mem_base;
     isa_bus_new(&dev->qdev, pci_address_space_io(dev));
 
     i82378_init(&dev->qdev, s);
@@ -244,7 +242,6 @@ static int pci_i82378_init(PCIDevice *dev)
 
 static Property i82378_properties[] = {
     DEFINE_PROP_HEX32("iobase", PCIi82378State, isa_io_base, 0x80000000),
-    DEFINE_PROP_HEX32("membase", PCIi82378State, isa_mem_base, 0xc0000000),
     DEFINE_PROP_END_OF_LIST()
 };
 
diff --git a/hw/pci-host/prep.c b/hw/pci-host/prep.c
index 09d3b32..e120058 100644
--- a/hw/pci-host/prep.c
+++ b/hw/pci-host/prep.c
@@ -119,6 +119,8 @@ static void raven_pcihost_realizefn(DeviceState *d, Error **errp)
     MemoryRegion *address_space_mem = get_system_memory();
     int i;
 
+    isa_mem_base = 0xc0000000;
+
     for (i = 0; i < 4; i++) {
         sysbus_init_irq(dev, &s->irq[i]);
     }
commit e0d479445876676f3f92e1bc6d5f92d4bb2500f8
Author: Andreas Färber <afaerber at suse.de>
Date:   Mon Jul 29 04:07:50 2013 +0200

    cpu: Fix VMSTATE_CPU() semantics
    
    Commit 1a1562f5ea3da17d45d3829e35b5f49da9ec2db5 prepared a VMSTATE_CPU()
    macro for device-style VMStateDescription registration, but missed to
    adapt cpu_exec_init(), so that the "cpu_common" VMStateDescription was
    still registered for AlphaCPU (fe31e7374299c0c6172ce618b29bf2fecbd881c7)
    and OpenRISCCPU (da69721460e652072b6a3dd52b7693da21ffe237). Fix this.
    
    Cc: Richard Henderson <rth at twiddle.net>
    Tested-by: Jia Liu <proljc at gmail.com>
    Signed-off-by: Andreas Färber <afaerber at suse.de>

diff --git a/exec.c b/exec.c
index c4f2894..3ca9381 100644
--- a/exec.c
+++ b/exec.c
@@ -402,11 +402,14 @@ void cpu_exec_init(CPUArchState *env)
 #if defined(CONFIG_USER_ONLY)
     cpu_list_unlock();
 #endif
-    vmstate_register(NULL, cpu_index, &vmstate_cpu_common, cpu);
+    if (qdev_get_vmsd(DEVICE(cpu)) == NULL) {
+        vmstate_register(NULL, cpu_index, &vmstate_cpu_common, cpu);
+    }
 #if defined(CPU_SAVE_VERSION) && !defined(CONFIG_USER_ONLY)
     register_savevm(NULL, "cpu", cpu_index, CPU_SAVE_VERSION,
                     cpu_save, cpu_load, env);
     assert(cc->vmsd == NULL);
+    assert(qdev_get_vmsd(DEVICE(cpu)) == NULL);
 #endif
     if (cc->vmsd != NULL) {
         vmstate_register(NULL, cpu_index, cc->vmsd, cpu);
commit f44c5c6794026fc2852c1c0f026b15733560ce7c
Author: Igor Mitsyanko <i.mitsyanko at gmail.com>
Date:   Wed Jul 31 10:27:35 2013 +0400

    MAINTAINERS: change Igor Mitsyanko's email address
    
    My email address in samsung.com domain is no longer accessible, change
    it to my personal gmail address.
    
    Signed-off-by: Igor Mitsyanko <i.mitsyanko at gmail.com>
    Signed-off-by: Anthony Liguori <aliguori at us.ibm.com>

diff --git a/MAINTAINERS b/MAINTAINERS
index 82ca5fb..654e2cb 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -225,7 +225,7 @@ ARM Machines
 Exynos
 M: Evgeny Voevodin <e.voevodin at samsung.com>
 M: Maksim Kozlov <m.kozlov at samsung.com>
-M: Igor Mitsyanko <i.mitsyanko at samsung.com>
+M: Igor Mitsyanko <i.mitsyanko at gmail.com>
 M: Dmitry Solodkiy <d.solodkiy at samsung.com>
 S: Maintained
 F: hw/*/exynos*
commit 1197cbb9eda1dc82e2fa1815ca62bc3de158353e
Author: Richard Henderson <rth at twiddle.net>
Date:   Tue Jul 30 08:20:43 2013 -1000

    qdev: Use clz in print_size
    
    We can compute a floor log2 value with clz rather than a division loop.
    
    Signed-off-by: Richard Henderson <rth at twiddle.net>
    Message-id: 1375208443-17288-3-git-send-email-rth at twiddle.net
    Signed-off-by: Anthony Liguori <aliguori at us.ibm.com>

diff --git a/hw/core/qdev-properties.c b/hw/core/qdev-properties.c
index d6d10c9..dc8ae69 100644
--- a/hw/core/qdev-properties.c
+++ b/hw/core/qdev-properties.c
@@ -1172,15 +1172,21 @@ static int parse_size(DeviceState *dev, Property *prop, const char *str)
 
 static int print_size(DeviceState *dev, Property *prop, char *dest, size_t len)
 {
-    uint64_t *ptr = qdev_get_prop_ptr(dev, prop);
-    char suffixes[] = {'T', 'G', 'M', 'K', 'B'};
-    int i = 0;
-    uint64_t div;
+    static const char suffixes[] = { 'B', 'K', 'M', 'G', 'T' };
+    uint64_t div, val = *(uint64_t *)qdev_get_prop_ptr(dev, prop);
+    int i;
 
-    for (div = 1ULL << 40; !(*ptr / div) ; div >>= 10) {
-        i++;
+    /* Compute floor(log2(val)).  */
+    i = 64 - clz64(val);
+
+    /* Find the power of 1024 that we'll display as the units.  */
+    i /= 10;
+    if (i >= ARRAY_SIZE(suffixes)) {
+        i = ARRAY_SIZE(suffixes) - 1;
     }
-    return snprintf(dest, len, "%0.03f%c", (double)*ptr/div, suffixes[i]);
+    div = 1ULL << (i * 10);
+
+    return snprintf(dest, len, "%0.03f%c", (double)val/div, suffixes[i]);
 }
 
 PropertyInfo qdev_prop_size = {
commit e76c756fd3d3b652c6a65ebe16f2bfb25b8d025e
Author: Richard Henderson <rth at twiddle.net>
Date:   Tue Jul 30 08:20:42 2013 -1000

    qdev: Fix 32-bit compilation in print_size
    
    Signed-off-by: Richard Henderson <rth at twiddle.net>
    Message-id: 1375208443-17288-2-git-send-email-rth at twiddle.net
    Signed-off-by: Anthony Liguori <aliguori at us.ibm.com>

diff --git a/hw/core/qdev-properties.c b/hw/core/qdev-properties.c
index 8d43a8d..d6d10c9 100644
--- a/hw/core/qdev-properties.c
+++ b/hw/core/qdev-properties.c
@@ -1177,7 +1177,7 @@ static int print_size(DeviceState *dev, Property *prop, char *dest, size_t len)
     int i = 0;
     uint64_t div;
 
-    for (div = (long int)1 << 40; !(*ptr / div) ; div >>= 10) {
+    for (div = 1ULL << 40; !(*ptr / div) ; div >>= 10) {
         i++;
     }
     return snprintf(dest, len, "%0.03f%c", (double)*ptr/div, suffixes[i]);
commit 75e2a4baf1536682d111d9bee0261806737a32dc
Merge: c095e10 58ae52a
Author: Anthony Liguori <aliguori at us.ibm.com>
Date:   Tue Jul 30 18:48:58 2013 -0500

    Merge remote-tracking branch 'spice/spice.v72' into staging
    
    # By Gerd Hoffmann
    # Via Gerd Hoffmann
    * spice/spice.v72:
      spice: fix display initialization
    
    Message-id: 1375173625-3784-1-git-send-email-kraxel at redhat.com
    Signed-off-by: Anthony Liguori <aliguori at us.ibm.com>

commit c095e108473f57516e7ad958d905a7017b225f82
Merge: dbef7b1 cf66ee8
Author: Anthony Liguori <aliguori at us.ibm.com>
Date:   Tue Jul 30 18:48:54 2013 -0500

    Merge remote-tracking branch 'kraxel/usb.85' into staging
    
    # By Gerd Hoffmann (2) and Alexey Kardashevskiy (1)
    # Via Gerd Hoffmann
    * kraxel/usb.85:
      hcd-ohci: add dma error handling
      uhci: egsm fix
      xhci: handle USB_RET_IOERROR
    
    Message-id: 1375173371-3378-1-git-send-email-kraxel at redhat.com
    Signed-off-by: Anthony Liguori <aliguori at us.ibm.com>

commit dbef7b17ad1d0be90696dc45b5b8162d8208643f
Merge: c9dd6a9 9b4f38e
Author: Anthony Liguori <aliguori at us.ibm.com>
Date:   Tue Jul 30 18:48:36 2013 -0500

    Merge remote-tracking branch 'borntraeger/s390-for-1.6' into staging
    
    * borntraeger/s390-for-1.6:
      s390: Implement dump-guest-memory support for target s390x
      s390x/kvm: Remove redundant return code
      s390x/kvm: Reworked/fixed handling of cc3 in kvm_handle_css_inst()
      s390x/ioinst: Fixed priority of operand exceptions
      s390x/ioinst: Fixed alignment check in SCHM instruction
      s390x/ioinst: Throw addressing exception when memory_map failed
      s390x/ioinst: Add missing alignment checks for IO instructions
      s390/sclpconsole: handle char layer busy conditions
    
    Signed-off-by: Anthony Liguori <aliguori at us.ibm.com>

commit c9dd6a9fa092827c38d21749a453bc56413411d7
Author: Andreas Färber <afaerber at suse.de>
Date:   Mon Jul 29 16:05:33 2013 +0200

    mips_r4k: Silence BIOS loading warning for qtest
    
    Signed-off-by: Andreas Färber <afaerber at suse.de>
    Reviewed-by: Anthony Liguori <aliguori at us.ibm.com>
    Signed-off-by: Andreas Färber <afaerber at suse.de>
    Message-id: 1375106733-832-6-git-send-email-afaerber at suse.de
    Signed-off-by: Anthony Liguori <aliguori at us.ibm.com>

diff --git a/hw/mips/mips_r4k.c b/hw/mips/mips_r4k.c
index 7af08b8..044f232 100644
--- a/hw/mips/mips_r4k.c
+++ b/hw/mips/mips_r4k.c
@@ -26,6 +26,7 @@
 #include "hw/timer/i8254.h"
 #include "sysemu/blockdev.h"
 #include "exec/address-spaces.h"
+#include "sysemu/qtest.h"
 
 #define MAX_IDE_BUS 2
 
@@ -244,8 +245,7 @@ void mips_r4k_init(QEMUMachineInitArgs *args)
                                    4, 0, 0, 0, 0, be)) {
             fprintf(stderr, "qemu: Error registering flash memory.\n");
 	}
-    }
-    else {
+    } else if (!qtest_enabled()) {
 	/* not fatal */
         fprintf(stderr, "qemu: Warning, could not load MIPS bios '%s'\n",
 		bios_name);
commit 38c8894fe77c14c6af415c75f043370264f89382
Author: Andreas Färber <afaerber at suse.de>
Date:   Mon Jul 29 16:05:32 2013 +0200

    mips_jazz: Silence BIOS loading warning for qtest
    
    Signed-off-by: Andreas Färber <afaerber at suse.de>
    Reviewed-by: Anthony Liguori <aliguori at us.ibm.com>
    Signed-off-by: Andreas Färber <afaerber at suse.de>
    Message-id: 1375106733-832-5-git-send-email-afaerber at suse.de
    Signed-off-by: Anthony Liguori <aliguori at us.ibm.com>

diff --git a/hw/mips/mips_jazz.c b/hw/mips/mips_jazz.c
index d6e0860..36677cc 100644
--- a/hw/mips/mips_jazz.c
+++ b/hw/mips/mips_jazz.c
@@ -42,6 +42,7 @@
 #include "sysemu/blockdev.h"
 #include "hw/sysbus.h"
 #include "exec/address-spaces.h"
+#include "sysemu/qtest.h"
 
 enum jazz_model_e
 {
@@ -176,7 +177,7 @@ static void mips_jazz_init(MemoryRegion *address_space,
     } else {
         bios_size = -1;
     }
-    if (bios_size < 0 || bios_size > MAGNUM_BIOS_SIZE) {
+    if ((bios_size < 0 || bios_size > MAGNUM_BIOS_SIZE) && !qtest_enabled()) {
         fprintf(stderr, "qemu: Warning, could not load MIPS bios '%s'\n",
                 bios_name);
     }
commit 2c57bd9b06e5771c11a1850e709b595a7c283e83
Author: Andreas Färber <afaerber at suse.de>
Date:   Mon Jul 29 16:05:31 2013 +0200

    mips_malta: Silence BIOS loading warning for qtest
    
    Signed-off-by: Andreas Färber <afaerber at suse.de>
    Reviewed-by: Anthony Liguori <aliguori at us.ibm.com>
    Signed-off-by: Andreas Färber <afaerber at suse.de>
    Message-id: 1375106733-832-4-git-send-email-afaerber at suse.de
    Signed-off-by: Anthony Liguori <aliguori at us.ibm.com>

diff --git a/hw/mips/mips_malta.c b/hw/mips/mips_malta.c
index 1589b59..f56f34f 100644
--- a/hw/mips/mips_malta.c
+++ b/hw/mips/mips_malta.c
@@ -48,6 +48,7 @@
 #include "exec/address-spaces.h"
 #include "hw/sysbus.h"             /* SysBusDevice */
 #include "qemu/host-utils.h"
+#include "sysemu/qtest.h"
 
 //#define DEBUG_BOARD_INIT
 
@@ -1005,7 +1006,8 @@ void mips_malta_init(QEMUMachineInitArgs *args)
             } else {
                 bios_size = -1;
             }
-            if ((bios_size < 0 || bios_size > BIOS_SIZE) && !kernel_filename) {
+            if ((bios_size < 0 || bios_size > BIOS_SIZE) &&
+                !kernel_filename && !qtest_enabled()) {
                 fprintf(stderr,
                         "qemu: Warning, could not load MIPS bios '%s', and no -kernel argument was specified\n",
                         bios_name);
commit 4a7ed999a7a5057d860b38c6680a1437945b5139
Author: Andreas Färber <afaerber at suse.de>
Date:   Mon Jul 29 16:05:30 2013 +0200

    mips_fulong2e: Silence BIOS loading warning for qtest
    
    Signed-off-by: Andreas Färber <afaerber at suse.de>
    Reviewed-by: Anthony Liguori <aliguori at us.ibm.com>
    Signed-off-by: Andreas Färber <afaerber at suse.de>
    Message-id: 1375106733-832-3-git-send-email-afaerber at suse.de
    Signed-off-by: Anthony Liguori <aliguori at us.ibm.com>

diff --git a/hw/mips/mips_fulong2e.c b/hw/mips/mips_fulong2e.c
index 9901441..b13750d 100644
--- a/hw/mips/mips_fulong2e.c
+++ b/hw/mips/mips_fulong2e.c
@@ -43,6 +43,7 @@
 #include "hw/timer/i8254.h"
 #include "sysemu/blockdev.h"
 #include "exec/address-spaces.h"
+#include "sysemu/qtest.h"
 
 #define DEBUG_FULONG2E_INIT
 
@@ -332,7 +333,8 @@ static void mips_fulong2e_init(QEMUMachineInitArgs *args)
             bios_size = -1;
         }
 
-        if ((bios_size < 0 || bios_size > BIOS_SIZE) && !kernel_filename) {
+        if ((bios_size < 0 || bios_size > BIOS_SIZE) &&
+            !kernel_filename && !qtest_enabled()) {
             fprintf(stderr, "qemu: Warning, could not load MIPS bios '%s'\n", bios_name);
         }
     }
commit 96b3bfa083987518e8a10364bf994c024c455fff
Author: Andreas Färber <afaerber at suse.de>
Date:   Mon Jul 29 16:05:29 2013 +0200

    target-ppc: Suppress TCG instruction emulation warnings for qtest
    
    Signed-off-by: Andreas Färber <afaerber at suse.de>
    Reviewed-by: Anthony Liguori <aliguori at us.ibm.com>
    Signed-off-by: Andreas Färber <afaerber at suse.de>
    Message-id: 1375106733-832-2-git-send-email-afaerber at suse.de
    Signed-off-by: Anthony Liguori <aliguori at us.ibm.com>

diff --git a/target-ppc/translate_init.c b/target-ppc/translate_init.c
index 0724226..b14aec8 100644
--- a/target-ppc/translate_init.c
+++ b/target-ppc/translate_init.c
@@ -7825,7 +7825,7 @@ static void ppc_cpu_realizefn(DeviceState *dev, Error **errp)
             error_setg(errp, "Unable to virtualize selected CPU with KVM");
             return;
         }
-    } else {
+    } else if (tcg_enabled()) {
         if (ppc_fixup_cpu(cpu) != 0) {
             error_setg(errp, "Unable to emulate selected CPU with TCG");
             return;
commit 7b7ab18d0b9769b5f39e663fa55caed461b1202e
Author: Michael Roth <mdroth at linux.vnet.ibm.com>
Date:   Tue Jul 30 13:04:22 2013 -0500

    chardev: fix CHR_EVENT_OPENED events for mux chardevs
    
    As of bd5c51ee6c4f1c79cae5ad2516d711a27b4ea8ec, chardevs no longer use
    bottom-halves to issue CHR_EVENT_OPENED events. To maintain past
    semantics, we instead defer the CHR_EVENT_OPENED events toward the end
    of chardev initialization.
    
    For muxes, this isn't good enough, since a range of FEs must be able
    to attach to the mux prior to any CHR_EVENT_OPENED being issued, else
    each FE will immediately print it's initial output (prompts, banners,
    etc.) just prior to us switching to the next FE as part of
    initialization.
    
    The is new and confusing behavior for users, as they'll see output for
    things like the HMP monitor, even though their the current mux focus
    may be a guest serial port with potentially no output.
    
    We fix this by further deferring CHR_EVENT_OPENED events for FEs
    associated with muxes until after machine init by flagging mux chardevs
    with 'explicit_be_open', which suppresses emission of CHR_EVENT_OPENED
    events until we explicitly set the mux as opened later.
    
    Currently, we must defer till after machine init since we potentially
    associate FEs with muxes as part of realize (for instance,
    serial_isa_realizefn).
    
    Signed-off-by: Michael Roth <mdroth at linux.vnet.ibm.com>
    Message-id: 1375207462-8141-1-git-send-email-mdroth at linux.vnet.ibm.com
    Cc: qemu-stable at nongnu.org
    Signed-off-by: Anthony Liguori <aliguori at us.ibm.com>

diff --git a/include/sysemu/char.h b/include/sysemu/char.h
index e65e4a4..8053130 100644
--- a/include/sysemu/char.h
+++ b/include/sysemu/char.h
@@ -77,6 +77,7 @@ struct CharDriverState {
     int explicit_fe_open;
     int explicit_be_open;
     int avail_connections;
+    int is_mux;
     QemuOpts *opts;
     QTAILQ_ENTRY(CharDriverState) next;
 };
diff --git a/qemu-char.c b/qemu-char.c
index 3f606c9..16f3ad7 100644
--- a/qemu-char.c
+++ b/qemu-char.c
@@ -476,6 +476,46 @@ static void mux_chr_update_read_handler(CharDriverState *chr)
     mux_chr_send_event(d, d->focus, CHR_EVENT_MUX_IN);
 }
 
+static bool muxes_realized;
+
+/**
+ * Called after processing of default and command-line-specified
+ * chardevs to deliver CHR_EVENT_OPENED events to any FEs attached
+ * to a mux chardev. This is done here to ensure that
+ * output/prompts/banners are only displayed for the FE that has
+ * focus when initial command-line processing/machine init is
+ * completed.
+ *
+ * After this point, any new FE attached to any new or existing
+ * mux will receive CHR_EVENT_OPENED notifications for the BE
+ * immediately.
+ */
+static void muxes_realize_done(Notifier *notifier, void *unused)
+{
+    CharDriverState *chr;
+
+    QTAILQ_FOREACH(chr, &chardevs, next) {
+        if (chr->is_mux) {
+            MuxDriver *d = chr->opaque;
+            int i;
+
+            /* send OPENED to all already-attached FEs */
+            for (i = 0; i < d->mux_cnt; i++) {
+                mux_chr_send_event(d, i, CHR_EVENT_OPENED);
+            }
+            /* mark mux as OPENED so any new FEs will immediately receive
+             * OPENED event
+             */
+            qemu_chr_be_generic_open(chr);
+        }
+    }
+    muxes_realized = true;
+}
+
+static Notifier muxes_realize_notify = {
+    .notify = muxes_realize_done,
+};
+
 static CharDriverState *qemu_chr_open_mux(CharDriverState *drv)
 {
     CharDriverState *chr;
@@ -492,6 +532,11 @@ static CharDriverState *qemu_chr_open_mux(CharDriverState *drv)
     chr->chr_accept_input = mux_chr_accept_input;
     /* Frontend guest-open / -close notification is not support with muxes */
     chr->chr_set_fe_open = NULL;
+    /* only default to opened state if we've realized the initial
+     * set of muxes
+     */
+    chr->explicit_be_open = muxes_realized ? 0 : 1;
+    chr->is_mux = 1;
 
     return chr;
 }
@@ -3798,6 +3843,11 @@ static void register_types(void)
     /* Bug-compatibility: */
     register_char_driver_qapi("memory", CHARDEV_BACKEND_KIND_MEMORY,
                               qemu_chr_parse_ringbuf);
+    /* this must be done after machine init, since we register FEs with muxes
+     * as part of realize functions like serial_isa_realizefn when -nographic
+     * is specified
+     */
+    qemu_add_machine_init_done_notifier(&muxes_realize_notify);
 }
 
 type_init(register_types);
commit 5fe0d351b3a7caf77f899db804d09e4553329c84
Author: Stefan Weil <sw at weilnetz.de>
Date:   Tue Jul 30 22:41:23 2013 +0200

    tci: Fix broken build (compiler warning caused by redefined macro BIT)
    
    The definition of macro BIT in tci/tcg-target.c now conflicts with the
    definition of the same macro in includes qemu/bitops.h.
    
    This conflict was triggered by a recent change in the include chain of
    tcg.c (probably commit 949fc82314cc84162e64a5323764527a542421ce).
    
    Signed-off-by: Stefan Weil <sw at weilnetz.de>
    Message-id: 1375216883-23969-1-git-send-email-sw at weilnetz.de
    Signed-off-by: Anthony Liguori <aliguori at us.ibm.com>

diff --git a/tcg/tci/tcg-target.c b/tcg/tci/tcg-target.c
index d1241b5..e118bc7 100644
--- a/tcg/tci/tcg-target.c
+++ b/tcg/tci/tcg-target.c
@@ -34,9 +34,6 @@
         tcg_abort(); \
     } while (0)
 
-/* Single bit n. */
-#define BIT(n) (1 << (n))
-
 /* Bitfield n...m (in 32 bit value). */
 #define BITS(n, m) (((0xffffffffU << (31 - n)) >> (31 - n + m)) << m)
 
commit 9a949b94f60ee48ca0fbb5dc263c7ee77b75149f
Author: Mark Cave-Ayland <mark.cave-ayland at ilande.co.uk>
Date:   Tue Jul 30 23:11:07 2013 +0100

    Update OpenBIOS images
    
    Update OpenBIOS images to SVN r1198 built from submodule.
    
    Signed-off-by: Mark Cave-Ayland <mark.cave-ayland at ilande.co.uk>

diff --git a/pc-bios/README b/pc-bios/README
index 53b5289..e404a22 100644
--- a/pc-bios/README
+++ b/pc-bios/README
@@ -11,8 +11,8 @@
   firmware implementation. The goal is to implement a 100% IEEE
   1275-1994 (referred to as Open Firmware) compliant firmware.
   The included images for PowerPC (for 32 and 64 bit PPC CPUs),
-  Sparc32 and Sparc64 are built from OpenBIOS 1.1 release (SVN
-  revision 1136).
+  Sparc32 and Sparc64 are built from OpenBIOS SVN revision
+  1198.
 
 - SLOF (Slimline Open Firmware) is a free IEEE 1275 Open Firmware
   implementation for certain IBM POWER hardware.  The sources are at
diff --git a/pc-bios/openbios-ppc b/pc-bios/openbios-ppc
index 77eb55d..c6b3319 100644
Binary files a/pc-bios/openbios-ppc and b/pc-bios/openbios-ppc differ
diff --git a/pc-bios/openbios-sparc32 b/pc-bios/openbios-sparc32
index c5ba6ae..2aa400c 100644
Binary files a/pc-bios/openbios-sparc32 and b/pc-bios/openbios-sparc32 differ
diff --git a/pc-bios/openbios-sparc64 b/pc-bios/openbios-sparc64
index c4aaa05..f6ee286 100644
Binary files a/pc-bios/openbios-sparc64 and b/pc-bios/openbios-sparc64 differ
diff --git a/roms/openbios b/roms/openbios
index 569e40c..0f3d51e 160000
--- a/roms/openbios
+++ b/roms/openbios
@@ -1 +1 @@
-Subproject commit 569e40c517e9623e672be38a21da7bcec046e3be
+Subproject commit 0f3d51ef22ec9166beb3ed434d253029ed7cfe84
commit beb3faaa0027c114e37317fdba38a8a7facf3f9b
Author: Petar Jovanovic <petar.jovanovic at imgtec.com>
Date:   Mon Jul 29 12:49:05 2013 +0200

    target-mips: correct the values in the DSP tests
    
    Five tests files for DSP instructions had wrong expected values in the tests.
    This change fixes this, and this has been cross-checked by running the same
    test binaries on Malta 74K board.
    
    Signed-off-by: Petar Jovanovic <petar.jovanovic at imgtec.com>
    Signed-off-by: Aurelien Jarno <aurelien at aurel32.net>

diff --git a/tests/tcg/mips/mips32-dsp/dpsq_s_w_ph.c b/tests/tcg/mips/mips32-dsp/dpsq_s_w_ph.c
index 22ab4d5..74058fe 100644
--- a/tests/tcg/mips/mips32-dsp/dpsq_s_w_ph.c
+++ b/tests/tcg/mips/mips32-dsp/dpsq_s_w_ph.c
@@ -9,8 +9,8 @@ int main()
 
     rs      = 0xBC0123AD;
     rt      = 0x01643721;
-    resulth = 0x04;
-    resultl = 0xEE9794A3;
+    resulth = 0x00000004;
+    resultl = 0xF15F94A3;
     __asm
         ("mthi  %0, $ac1\n\t"
          "mtlo  %1, $ac1\n\t"
@@ -23,12 +23,12 @@ int main()
     assert(ach == resulth);
     assert(acl == resultl);
 
-    ach = 0x1424Ef1f;
+    ach = 0x1424EF1F;
     acl = 0x1035219A;
     rs      = 0x800083AD;
     rt      = 0x80003721;
-    resulth = 0x1424ef1e;
-    resultl = 0x577ed901;
+    resulth = 0x1424EF1E;
+    resultl = 0xC5C0D901;
     __asm
         ("mthi  %0, $ac1\n\t"
          "mtlo  %1, $ac1\n\t"
diff --git a/tests/tcg/mips/mips32-dsp/maq_s_w_phl.c b/tests/tcg/mips/mips32-dsp/maq_s_w_phl.c
index 292d685..0f7c070 100644
--- a/tests/tcg/mips/mips32-dsp/maq_s_w_phl.c
+++ b/tests/tcg/mips/mips32-dsp/maq_s_w_phl.c
@@ -10,12 +10,12 @@ int main()
     int resulth, resultl;
     int resdsp;
 
-    achi = 0x05;
-    acli = 0xB4CB;
+    achi = 0x00000005;
+    acli = 0x0000B4CB;
     rs  = 0xFF060000;
     rt  = 0xCB000000;
-    resulth = 0x04;
-    resultl = 0x947438CB;
+    resulth = 0x00000005;
+    resultl = 0x006838CB;
 
     __asm
         ("mthi %2, $ac1\n\t"
@@ -29,12 +29,12 @@ int main()
     assert(resulth == acho);
     assert(resultl == aclo);
 
-    achi = 0x06;
-    acli = 0xB4CB;
+    achi = 0x00000006;
+    acli = 0x0000B4CB;
     rs  = 0x80000000;
     rt  = 0x80000000;
-    resulth = 0x6;
-    resultl = 0x8000b4ca;
+    resulth = 0x00000006;
+    resultl = 0x8000B4CA;
     resdsp = 1;
 
     __asm
diff --git a/tests/tcg/mips/mips32-dsp/maq_s_w_phr.c b/tests/tcg/mips/mips32-dsp/maq_s_w_phr.c
index 7b2ef2a..942722a 100644
--- a/tests/tcg/mips/mips32-dsp/maq_s_w_phr.c
+++ b/tests/tcg/mips/mips32-dsp/maq_s_w_phr.c
@@ -10,12 +10,12 @@ int main()
     int resulth, resultl;
     int resdsp;
 
-    achi = 0x05;
-    acli = 0xB4CB;
-    rs  = 0xFF06;
-    rt  = 0xCB00;
-    resulth = 0x04;
-    resultl = 0x947438CB;
+    achi = 0x00000005;
+    acli = 0x0000B4CB;
+    rs  = 0x0000FF06;
+    rt  = 0x0000CB00;
+    resulth = 0x00000005;
+    resultl = 0x006838CB;
 
     __asm
         ("mthi %2, $ac1\n\t"
@@ -29,12 +29,12 @@ int main()
     assert(resulth == acho);
     assert(resultl == aclo);
 
-    achi = 0x06;
-    acli = 0xB4CB;
-    rs  = 0x8000;
-    rt  = 0x8000;
-    resulth = 0x6;
-    resultl = 0x8000b4ca;
+    achi = 0x00000006;
+    acli = 0x0000B4CB;
+    rs  = 0x00008000;
+    rt  = 0x00008000;
+    resulth = 0x00000006;
+    resultl = 0x8000B4CA;
     resdsp = 1;
 
     __asm
diff --git a/tests/tcg/mips/mips32-dspr2/dpaqx_sa_w_ph.c b/tests/tcg/mips/mips32-dspr2/dpaqx_sa_w_ph.c
index 798c4da..d551d64 100644
--- a/tests/tcg/mips/mips32-dspr2/dpaqx_sa_w_ph.c
+++ b/tests/tcg/mips/mips32-dspr2/dpaqx_sa_w_ph.c
@@ -4,14 +4,17 @@
 int main()
 {
     int rs, rt, dsp;
-    int ach = 5, acl = 5;
+    int ach, acl;
     int resulth, resultl, resultdsp;
 
+    ach = 0x00000005;
+    acl = 0x00000005;
     rs     = 0x00FF00FF;
     rt     = 0x00010002;
     resulth = 0x00;
     resultl = 0x7FFFFFFF;
     resultdsp = 0x01;
+    dsp = 0;
     __asm
         ("wrdsp %2\n\t"
          "mthi  %0, $ac1\n\t"
@@ -27,13 +30,14 @@ int main()
     assert(ach == resulth);
     assert(acl == resultl);
 
-    ach = 9;
-    acl = 0xb;
+    ach = 0x00000009;
+    acl = 0x0000000B;
     rs     = 0x800000FF;
     rt     = 0x00018000;
     resulth = 0x00;
-    resultl = 0x7fffffff;
+    resultl = 0x7FFFFFFF;
     resultdsp = 0x01;
+    dsp = 0;
     __asm
         ("wrdsp %2\n\t"
          "mthi  %0, $ac1\n\t"
diff --git a/tests/tcg/mips/mips32-dspr2/dpsqx_s_w_ph.c b/tests/tcg/mips/mips32-dspr2/dpsqx_s_w_ph.c
index 14cdd7c..e40543f 100644
--- a/tests/tcg/mips/mips32-dspr2/dpsqx_s_w_ph.c
+++ b/tests/tcg/mips/mips32-dspr2/dpsqx_s_w_ph.c
@@ -9,8 +9,8 @@ int main()
 
     rs      = 0xBC0123AD;
     rt      = 0x01643721;
-    resulth = 0x04;
-    resultl = 0xAEA3E09B;
+    resulth = 0x00000005;
+    resultl = 0x1CE5E09B;
     resultdsp = 0x00;
     __asm
         ("mthi  %0, $ac1\n\t"
@@ -27,12 +27,12 @@ int main()
     assert(ach == resulth);
     assert(acl == resultl);
 
-    ach = 0x99f13005;
+    ach = 0x99F13005;
     acl = 0x51730062;
     rs      = 0x80008000;
     rt      = 0x80008000;
 
-    resulth = 0x99f13004;
+    resulth = 0x99F13004;
     resultl = 0x51730064;
     resultdsp = 0x01;
     __asm
commit 9b4f38e182d18cac217f04b8b7fddf760a5b9d44
Author: Ekaterina Tumanova <tumanova at linux.vnet.ibm.com>
Date:   Wed Jul 10 15:26:46 2013 +0200

    s390: Implement dump-guest-memory support for target s390x
    
    With this patch dump-guest-memory on s390 produces an ELF formatted,
    crash-readable dump.
    In order to implement this, the arch-specific part of dump-guest-memory
    was added:
    target-s390x/arch_dump.c contains the whole set of function for writing
    Elf note sections of all types for s390x.
    
    Signed-off-by: Ekaterina Tumanova <tumanova at linux.vnet.ibm.com>
    Signed-off-by: Jens Freimann <jfrei at linux.vnet.ibm.com>
    [fixed indentation, use CamelCase, rename note_t to Note, use S390CPU]
    Reviewed-by: Andreas Färber <afaerber at suse.de>
    Signed-off-by: Christian Borntraeger <borntraeger at de.ibm.com>

diff --git a/include/elf.h b/include/elf.h
index cf0d3e2..58bfbf8 100644
--- a/include/elf.h
+++ b/include/elf.h
@@ -1348,11 +1348,17 @@ typedef struct elf64_shdr {
 
 /* Notes used in ET_CORE */
 #define NT_PRSTATUS	1
+#define NT_FPREGSET     2
 #define NT_PRFPREG	2
 #define NT_PRPSINFO	3
 #define NT_TASKSTRUCT	4
 #define NT_AUXV		6
 #define NT_PRXFPREG     0x46e62b7f      /* copied from gdb5.1/include/elf/common.h */
+#define NT_S390_PREFIX  0x305           /* s390 prefix register */
+#define NT_S390_CTRS    0x304           /* s390 control registers */
+#define NT_S390_TODPREG 0x303           /* s390 TOD programmable register */
+#define NT_S390_TODCMP  0x302           /* s390 TOD clock comparator register */
+#define NT_S390_TIMER   0x301           /* s390 timer register */
 
 
 /* Note header in a PT_NOTE section */
diff --git a/target-s390x/Makefile.objs b/target-s390x/Makefile.objs
index ab938e7..f873146 100644
--- a/target-s390x/Makefile.objs
+++ b/target-s390x/Makefile.objs
@@ -1,5 +1,5 @@
 obj-y += translate.o helper.o cpu.o interrupt.o
 obj-y += int_helper.o fpu_helper.o cc_helper.o mem_helper.o misc_helper.o
 obj-y += gdbstub.o
-obj-$(CONFIG_SOFTMMU) += ioinst.o
+obj-$(CONFIG_SOFTMMU) += ioinst.o arch_dump.o
 obj-$(CONFIG_KVM) += kvm.o
diff --git a/target-s390x/arch_dump.c b/target-s390x/arch_dump.c
new file mode 100644
index 0000000..f3e5144
--- /dev/null
+++ b/target-s390x/arch_dump.c
@@ -0,0 +1,212 @@
+/*
+ * writing ELF notes for s390x arch
+ *
+ *
+ * Copyright IBM Corp. 2012, 2013
+ *
+ *     Ekaterina Tumanova <tumanova at linux.vnet.ibm.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 "elf.h"
+#include "exec/cpu-all.h"
+#include "sysemu/dump.h"
+#include "sysemu/kvm.h"
+
+
+struct S390xUserRegsStruct {
+    uint64_t psw[2];
+    uint64_t gprs[16];
+    uint32_t acrs[16];
+} QEMU_PACKED;
+
+typedef struct S390xUserRegsStruct S390xUserRegs;
+
+struct S390xElfPrstatusStruct {
+    uint8_t pad1[32];
+    uint32_t pid;
+    uint8_t pad2[76];
+    S390xUserRegs regs;
+    uint8_t pad3[16];
+} QEMU_PACKED;
+
+typedef struct S390xElfPrstatusStruct S390xElfPrstatus;
+
+struct S390xElfFpregsetStruct {
+    uint32_t fpc;
+    uint32_t pad;
+    uint64_t fprs[16];
+} QEMU_PACKED;
+
+typedef struct S390xElfFpregsetStruct S390xElfFpregset;
+
+typedef struct noteStruct {
+    Elf64_Nhdr hdr;
+    char name[5];
+    char pad3[3];
+    union {
+        S390xElfPrstatus prstatus;
+        S390xElfFpregset fpregset;
+        uint32_t prefix;
+        uint64_t timer;
+        uint64_t todcmp;
+        uint32_t todpreg;
+        uint64_t ctrs[16];
+    } contents;
+} QEMU_PACKED Note;
+
+static void s390x_write_elf64_prstatus(Note *note, S390CPU *cpu)
+{
+    int i;
+    S390xUserRegs *regs;
+
+    note->hdr.n_type = cpu_to_be32(NT_PRSTATUS);
+
+    regs = &(note->contents.prstatus.regs);
+    regs->psw[0] = cpu_to_be64(cpu->env.psw.mask);
+    regs->psw[1] = cpu_to_be64(cpu->env.psw.addr);
+    for (i = 0; i <= 15; i++) {
+        regs->acrs[i] = cpu_to_be32(cpu->env.aregs[i]);
+        regs->gprs[i] = cpu_to_be64(cpu->env.regs[i]);
+    }
+}
+
+static void s390x_write_elf64_fpregset(Note *note, S390CPU *cpu)
+{
+    int i;
+
+    note->hdr.n_type = cpu_to_be32(NT_FPREGSET);
+    note->contents.fpregset.fpc = cpu_to_be32(cpu->env.fpc);
+    for (i = 0; i <= 15; i++) {
+        note->contents.fpregset.fprs[i] = cpu_to_be64(cpu->env.fregs[i].ll);
+    }
+}
+
+
+static void s390x_write_elf64_timer(Note *note, S390CPU *cpu)
+{
+    note->hdr.n_type = cpu_to_be32(NT_S390_TIMER);
+    note->contents.timer = cpu_to_be64((uint64_t)(cpu->env.cputm));
+}
+
+static void s390x_write_elf64_todcmp(Note *note, S390CPU *cpu)
+{
+    note->hdr.n_type = cpu_to_be32(NT_S390_TODCMP);
+    note->contents.todcmp = cpu_to_be64((uint64_t)(cpu->env.ckc));
+}
+
+static void s390x_write_elf64_todpreg(Note *note, S390CPU *cpu)
+{
+    note->hdr.n_type = cpu_to_be32(NT_S390_TODPREG);
+    note->contents.todpreg = cpu_to_be32((uint32_t)(cpu->env.todpr));
+}
+
+static void s390x_write_elf64_ctrs(Note *note, S390CPU *cpu)
+{
+    int i;
+
+    note->hdr.n_type = cpu_to_be32(NT_S390_CTRS);
+
+    for (i = 0; i <= 15; i++) {
+        note->contents.ctrs[i] = cpu_to_be64(cpu->env.cregs[i]);
+    }
+}
+
+static void s390x_write_elf64_prefix(Note *note, S390CPU *cpu)
+{
+    note->hdr.n_type = cpu_to_be32(NT_S390_PREFIX);
+    note->contents.prefix = cpu_to_be32((uint32_t)(cpu->env.psa));
+}
+
+
+struct NoteFuncDescStruct {
+    int contents_size;
+    void (*note_contents_func)(Note *note, S390CPU *cpu);
+} note_func[] = {
+    {sizeof(((Note *)0)->contents.prstatus), s390x_write_elf64_prstatus},
+    {sizeof(((Note *)0)->contents.prefix),   s390x_write_elf64_prefix},
+    {sizeof(((Note *)0)->contents.fpregset), s390x_write_elf64_fpregset},
+    {sizeof(((Note *)0)->contents.ctrs),     s390x_write_elf64_ctrs},
+    {sizeof(((Note *)0)->contents.timer),    s390x_write_elf64_timer},
+    {sizeof(((Note *)0)->contents.todcmp),   s390x_write_elf64_todcmp},
+    {sizeof(((Note *)0)->contents.todpreg),  s390x_write_elf64_todpreg},
+    { 0, NULL}
+};
+
+typedef struct NoteFuncDescStruct NoteFuncDesc;
+
+
+static int s390x_write_all_elf64_notes(const char *note_name,
+                                       WriteCoreDumpFunction f,
+                                       S390CPU *cpu, int id,
+                                       void *opaque)
+{
+    Note note;
+    NoteFuncDesc *nf;
+    int note_size;
+    int ret = -1;
+
+    for (nf = note_func; nf->note_contents_func; nf++) {
+        note.hdr.n_namesz = cpu_to_be32(sizeof(note.name));
+        note.hdr.n_descsz = cpu_to_be32(nf->contents_size);
+        strncpy(note.name, note_name, sizeof(note.name));
+        (*nf->note_contents_func)(&note, cpu);
+
+        note_size = sizeof(note) - sizeof(note.contents) + nf->contents_size;
+        ret = f(&note, note_size, opaque);
+
+        if (ret < 0) {
+            return -1;
+        }
+
+    }
+
+    return 0;
+}
+
+
+int s390_cpu_write_elf64_note(WriteCoreDumpFunction f, CPUState *cs,
+                              int cpuid, void *opaque)
+{
+    S390CPU *cpu = S390_CPU(cs);
+    return s390x_write_all_elf64_notes("CORE", f, cpu, cpuid, opaque);
+}
+
+int cpu_get_dump_info(ArchDumpInfo *info)
+{
+    info->d_machine = EM_S390;
+    info->d_endian = ELFDATA2MSB;
+    info->d_class = ELFCLASS64;
+
+    return 0;
+}
+
+ssize_t cpu_get_note_size(int class, int machine, int nr_cpus)
+{
+    int name_size = 8; /* "CORE" or "QEMU" rounded */
+    size_t elf_note_size = 0;
+    int note_head_size;
+    NoteFuncDesc *nf;
+
+    assert(class == ELFCLASS64);
+    assert(machine == EM_S390);
+
+    note_head_size = sizeof(Elf64_Nhdr);
+
+    for (nf = note_func; nf->note_contents_func; nf++) {
+        elf_note_size = elf_note_size + note_head_size + name_size +
+                        nf->contents_size;
+    }
+
+    return (elf_note_size) * nr_cpus;
+}
+
+int s390_cpu_write_elf64_qemunote(WriteCoreDumpFunction f,
+                                  CPUState *cpu, void *opaque)
+{
+    return 0;
+}
diff --git a/target-s390x/cpu-qom.h b/target-s390x/cpu-qom.h
index 0d63b1c..cbe2341 100644
--- a/target-s390x/cpu-qom.h
+++ b/target-s390x/cpu-qom.h
@@ -74,6 +74,11 @@ static inline S390CPU *s390_env_get_cpu(CPUS390XState *env)
 void s390_cpu_do_interrupt(CPUState *cpu);
 void s390_cpu_dump_state(CPUState *cpu, FILE *f, fprintf_function cpu_fprintf,
                          int flags);
+int s390_cpu_write_elf64_note(WriteCoreDumpFunction f, CPUState *cs,
+                              int cpuid, void *opaque);
+
+int s390_cpu_write_elf64_qemunote(WriteCoreDumpFunction f,
+                                  CPUState *cpu, void *opaque);
 hwaddr s390_cpu_get_phys_page_debug(CPUState *cpu, vaddr addr);
 int s390_cpu_gdb_read_register(CPUState *cpu, uint8_t *buf, int reg);
 int s390_cpu_gdb_write_register(CPUState *cpu, uint8_t *buf, int reg);
diff --git a/target-s390x/cpu.c b/target-s390x/cpu.c
index 9b82495..6be6c08 100644
--- a/target-s390x/cpu.c
+++ b/target-s390x/cpu.c
@@ -178,6 +178,8 @@ static void s390_cpu_class_init(ObjectClass *oc, void *data)
     cc->gdb_write_register = s390_cpu_gdb_write_register;
 #ifndef CONFIG_USER_ONLY
     cc->get_phys_page_debug = s390_cpu_get_phys_page_debug;
+    cc->write_elf64_note = s390_cpu_write_elf64_note;
+    cc->write_elf64_qemunote = s390_cpu_write_elf64_qemunote;
 #endif
     dc->vmsd = &vmstate_s390_cpu;
     cc->gdb_num_core_regs = S390_NUM_REGS;
commit d2ee774616280db778f0b4b97a8ac514602ad52c
Author: Thomas Huth <thuth at linux.vnet.ibm.com>
Date:   Tue Jul 2 14:45:16 2013 +0200

    s390x/kvm: Remove redundant return code
    
    Removed the redundant return code statement from handle_instruction() - it
    always returned 0 and never reports any errors to its caller, since errors
    from the sub-functions are already reported via program exceptions instead.
    
    Signed-off-by: Thomas Huth <thuth at linux.vnet.ibm.com>
    Signed-off-by: Christian Borntraeger <borntraeger at de.ibm.com>

diff --git a/target-s390x/kvm.c b/target-s390x/kvm.c
index eff8d28..26d18e3 100644
--- a/target-s390x/kvm.c
+++ b/target-s390x/kvm.c
@@ -693,7 +693,7 @@ out:
     return 0;
 }
 
-static int handle_instruction(S390CPU *cpu, struct kvm_run *run)
+static void handle_instruction(S390CPU *cpu, struct kvm_run *run)
 {
     unsigned int ipa0 = (run->s390_sieic.ipa & 0xff00);
     uint8_t ipa1 = run->s390_sieic.ipa & 0x00ff;
@@ -719,7 +719,6 @@ static int handle_instruction(S390CPU *cpu, struct kvm_run *run)
     if (r < 0) {
         enter_pgmcheck(cpu, 0x0001);
     }
-    return 0;
 }
 
 static bool is_special_wait_psw(CPUState *cs)
@@ -739,7 +738,7 @@ static int handle_intercept(S390CPU *cpu)
             (long)cs->kvm_run->psw_addr);
     switch (icpt_code) {
         case ICPT_INSTRUCTION:
-            r = handle_instruction(cpu, run);
+            handle_instruction(cpu, run);
             break;
         case ICPT_WAITPSW:
             /* disabled wait, since enabled wait is handled in kernel */
commit c1e8dfb5e860c48adf5026a5a7cf8f35be66c22c
Author: Thomas Huth <thuth at linux.vnet.ibm.com>
Date:   Mon Jun 24 15:17:34 2013 +0200

    s390x/kvm: Reworked/fixed handling of cc3 in kvm_handle_css_inst()
    
    Consolidated the setting of the condition code in kvm_handle_css_inst().
    For the (unhandled) instructions EQBS and SQBS, we have to return
    an operation exception instead of cc3. Also removed the is_ioinst()
    function to avoid decoding the opcode twice.
    
    Signed-off-by: Thomas Huth <thuth at linux.vnet.ibm.com>
    Reviewed-by: Cornelia Huck <cornelia.huck at de.ibm.com>
    Signed-off-by: Christian Borntraeger <borntraeger at de.ibm.com>

diff --git a/target-s390x/kvm.c b/target-s390x/kvm.c
index ab0e2b5..eff8d28 100644
--- a/target-s390x/kvm.c
+++ b/target-s390x/kvm.c
@@ -528,50 +528,19 @@ static int kvm_handle_css_inst(S390CPU *cpu, struct kvm_run *run,
         no_cc = 1;
         r = ioinst_handle_sal(env, env->regs[1]);
         break;
-    default:
-        r = -1;
+    case PRIV_SIGA:
+        /* Not provided, set CC = 3 for subchannel not operational */
+        r = 3;
         break;
+    default:
+        return -1;
     }
 
-    if (r >= 0) {
-        if (!no_cc) {
-            setcc(cpu, r);
-        }
-        r = 0;
-    } else if (r < -1) {
-        r = 0;
-    }
-    return r;
-}
-
-static int is_ioinst(uint8_t ipa0, uint8_t ipa1, uint8_t ipb)
-{
-    int ret = 0;
-    uint16_t ipa = (ipa0 << 8) | ipa1;
-
-    switch (ipa) {
-    case IPA0_B2 | PRIV_CSCH:
-    case IPA0_B2 | PRIV_HSCH:
-    case IPA0_B2 | PRIV_MSCH:
-    case IPA0_B2 | PRIV_SSCH:
-    case IPA0_B2 | PRIV_STSCH:
-    case IPA0_B2 | PRIV_TPI:
-    case IPA0_B2 | PRIV_SAL:
-    case IPA0_B2 | PRIV_RSCH:
-    case IPA0_B2 | PRIV_STCRW:
-    case IPA0_B2 | PRIV_STCPS:
-    case IPA0_B2 | PRIV_RCHP:
-    case IPA0_B2 | PRIV_SCHM:
-    case IPA0_B2 | PRIV_CHSC:
-    case IPA0_B2 | PRIV_SIGA:
-    case IPA0_B2 | PRIV_XSCH:
-    case IPA0_B9 | PRIV_EQBS:
-    case IPA0_EB | PRIV_SQBS:
-        ret = 1;
-        break;
+    if (r >= 0 && !no_cc) {
+        setcc(cpu, r);
     }
 
-    return ret;
+    return 0;
 }
 
 static int handle_priv(S390CPU *cpu, struct kvm_run *run,
@@ -587,15 +556,9 @@ static int handle_priv(S390CPU *cpu, struct kvm_run *run,
             r = kvm_sclp_service_call(cpu, run, ipbh0);
             break;
         default:
-            if (is_ioinst(ipa0, ipa1, ipb)) {
-                r = kvm_handle_css_inst(cpu, run, ipa0, ipa1, ipb);
-                if (r == -1) {
-                    setcc(cpu, 3);
-                    r = 0;
-                }
-            } else {
-                DPRINTF("KVM: unknown PRIV: 0x%x\n", ipa1);
-                r = -1;
+            r = kvm_handle_css_inst(cpu, run, ipa0, ipa1, ipb);
+            if (r == -1) {
+                DPRINTF("KVM: unhandled PRIV: 0x%x\n", ipa1);
             }
             break;
     }
commit 71ed827abd57dc7947ce3316118d0e601e70fac9
Author: Thomas Huth <thuth at linux.vnet.ibm.com>
Date:   Tue Jun 25 14:59:12 2013 +0200

    s390x/ioinst: Fixed priority of operand exceptions
    
    Operand exceptions have a lower priority than specification and address
    exceptions. Thus the checks for operand exceptions must be done later.
    
    Signed-off-by: Thomas Huth <thuth at linux.vnet.ibm.com>
    Acked-by: Cornelia Huck <cornelia.huck at de.ibm.com>
    Signed-off-by: Christian Borntraeger <borntraeger at de.ibm.com>

diff --git a/target-s390x/ioinst.c b/target-s390x/ioinst.c
index 098bd8d..85fd285 100644
--- a/target-s390x/ioinst.c
+++ b/target-s390x/ioinst.c
@@ -151,11 +151,6 @@ int ioinst_handle_msch(CPUS390XState *env, uint64_t reg1, uint32_t ipb)
     int cc;
     hwaddr len = sizeof(*schib);
 
-    if (ioinst_disassemble_sch_ident(reg1, &m, &cssid, &ssid, &schid)) {
-        program_interrupt(env, PGM_OPERAND, 2);
-        return -EIO;
-    }
-    trace_ioinst_sch_id("msch", cssid, ssid, schid);
     addr = decode_basedisp_s(env, ipb);
     if (addr & 3) {
         program_interrupt(env, PGM_SPECIFICATION, 2);
@@ -167,11 +162,13 @@ int ioinst_handle_msch(CPUS390XState *env, uint64_t reg1, uint32_t ipb)
         cc = -EIO;
         goto out;
     }
-    if (!ioinst_schib_valid(schib)) {
+    if (ioinst_disassemble_sch_ident(reg1, &m, &cssid, &ssid, &schid) ||
+        !ioinst_schib_valid(schib)) {
         program_interrupt(env, PGM_OPERAND, 2);
         cc = -EIO;
         goto out;
     }
+    trace_ioinst_sch_id("msch", cssid, ssid, schid);
     sch = css_find_subch(m, cssid, ssid, schid);
     if (sch && css_subch_visible(sch)) {
         ret = css_do_msch(sch, schib);
@@ -226,11 +223,6 @@ int ioinst_handle_ssch(CPUS390XState *env, uint64_t reg1, uint32_t ipb)
     int cc;
     hwaddr len = sizeof(*orig_orb);
 
-    if (ioinst_disassemble_sch_ident(reg1, &m, &cssid, &ssid, &schid)) {
-        program_interrupt(env, PGM_OPERAND, 2);
-        return -EIO;
-    }
-    trace_ioinst_sch_id("ssch", cssid, ssid, schid);
     addr = decode_basedisp_s(env, ipb);
     if (addr & 3) {
         program_interrupt(env, PGM_SPECIFICATION, 2);
@@ -243,11 +235,13 @@ int ioinst_handle_ssch(CPUS390XState *env, uint64_t reg1, uint32_t ipb)
         goto out;
     }
     copy_orb_from_guest(&orb, orig_orb);
-    if (!ioinst_orb_valid(&orb)) {
+    if (ioinst_disassemble_sch_ident(reg1, &m, &cssid, &ssid, &schid) ||
+        !ioinst_orb_valid(&orb)) {
         program_interrupt(env, PGM_OPERAND, 2);
         cc = -EIO;
         goto out;
     }
+    trace_ioinst_sch_id("ssch", cssid, ssid, schid);
     sch = css_find_subch(m, cssid, ssid, schid);
     if (sch && css_subch_visible(sch)) {
         ret = css_do_ssch(sch, &orb);
@@ -306,11 +300,6 @@ int ioinst_handle_stsch(CPUS390XState *env, uint64_t reg1, uint32_t ipb)
     SCHIB *schib;
     hwaddr len = sizeof(*schib);
 
-    if (ioinst_disassemble_sch_ident(reg1, &m, &cssid, &ssid, &schid)) {
-        program_interrupt(env, PGM_OPERAND, 2);
-        return -EIO;
-    }
-    trace_ioinst_sch_id("stsch", cssid, ssid, schid);
     addr = decode_basedisp_s(env, ipb);
     if (addr & 3) {
         program_interrupt(env, PGM_SPECIFICATION, 2);
@@ -322,6 +311,13 @@ int ioinst_handle_stsch(CPUS390XState *env, uint64_t reg1, uint32_t ipb)
         cc = -EIO;
         goto out;
     }
+
+    if (ioinst_disassemble_sch_ident(reg1, &m, &cssid, &ssid, &schid)) {
+        program_interrupt(env, PGM_OPERAND, 2);
+        cc = -EIO;
+        goto out;
+    }
+    trace_ioinst_sch_id("stsch", cssid, ssid, schid);
     sch = css_find_subch(m, cssid, ssid, schid);
     if (sch) {
         if (css_subch_visible(sch)) {
commit 7ae5a7c0f63cc625cf31a9c9f18cc07f4049e48f
Author: Thomas Huth <thuth at linux.vnet.ibm.com>
Date:   Fri Jun 21 15:57:31 2013 +0200

    s390x/ioinst: Fixed alignment check in SCHM instruction
    
    Register 2 only has to be aligned to a 32-byte boundary, not a
    full page boundary.
    
    Signed-off-by: Thomas Huth <thuth at linux.vnet.ibm.com>
    Acked-by: Cornelia Huck <cornelia.huck at de.ibm.com>
    Signed-off-by: Christian Borntraeger <borntraeger at de.ibm.com>

diff --git a/target-s390x/ioinst.c b/target-s390x/ioinst.c
index 0dc258f..098bd8d 100644
--- a/target-s390x/ioinst.c
+++ b/target-s390x/ioinst.c
@@ -688,7 +688,7 @@ int ioinst_handle_schm(CPUS390XState *env, uint64_t reg1, uint64_t reg2,
     update = SCHM_REG1_UPD(reg1);
     dct = SCHM_REG1_DCT(reg1);
 
-    if (update && (reg2 & 0x0000000000000fff)) {
+    if (update && (reg2 & 0x000000000000001f)) {
         program_interrupt(env, PGM_OPERAND, 2);
         return -EIO;
     }
commit 0056fc9e44d5b424a0f2293edacb0381234fc9c5
Author: Thomas Huth <thuth at linux.vnet.ibm.com>
Date:   Fri Jun 21 13:12:45 2013 +0200

    s390x/ioinst: Throw addressing exception when memory_map failed
    
    So far, the IO instructions were throwing specification exceptions when
    there was a problem with accessing the memory. However, the better way
    is to throw an addressing exception instead.
    
    Signed-off-by: Thomas Huth <thuth at linux.vnet.ibm.com>
    Reviewed-by: Cornelia Huck <cornelia.huck at de.ibm.com>
    Signed-off-by: Christian Borntraeger <borntraeger at de.ibm.com>

diff --git a/target-s390x/ioinst.c b/target-s390x/ioinst.c
index 91cc41b..0dc258f 100644
--- a/target-s390x/ioinst.c
+++ b/target-s390x/ioinst.c
@@ -163,7 +163,7 @@ int ioinst_handle_msch(CPUS390XState *env, uint64_t reg1, uint32_t ipb)
     }
     schib = s390_cpu_physical_memory_map(env, addr, &len, 0);
     if (!schib || len != sizeof(*schib)) {
-        program_interrupt(env, PGM_SPECIFICATION, 2);
+        program_interrupt(env, PGM_ADDRESSING, 2);
         cc = -EIO;
         goto out;
     }
@@ -238,7 +238,7 @@ int ioinst_handle_ssch(CPUS390XState *env, uint64_t reg1, uint32_t ipb)
     }
     orig_orb = s390_cpu_physical_memory_map(env, addr, &len, 0);
     if (!orig_orb || len != sizeof(*orig_orb)) {
-        program_interrupt(env, PGM_SPECIFICATION, 2);
+        program_interrupt(env, PGM_ADDRESSING, 2);
         cc = -EIO;
         goto out;
     }
@@ -286,7 +286,7 @@ int ioinst_handle_stcrw(CPUS390XState *env, uint32_t ipb)
     }
     crw = s390_cpu_physical_memory_map(env, addr, &len, 1);
     if (!crw || len != sizeof(*crw)) {
-        program_interrupt(env, PGM_SPECIFICATION, 2);
+        program_interrupt(env, PGM_ADDRESSING, 2);
         cc = -EIO;
         goto out;
     }
@@ -318,7 +318,7 @@ int ioinst_handle_stsch(CPUS390XState *env, uint64_t reg1, uint32_t ipb)
     }
     schib = s390_cpu_physical_memory_map(env, addr, &len, 1);
     if (!schib || len != sizeof(*schib)) {
-        program_interrupt(env, PGM_SPECIFICATION, 2);
+        program_interrupt(env, PGM_ADDRESSING, 2);
         cc = -EIO;
         goto out;
     }
@@ -367,7 +367,7 @@ int ioinst_handle_tsch(CPUS390XState *env, uint64_t reg1, uint32_t ipb)
     }
     irb = s390_cpu_physical_memory_map(env, addr, &len, 1);
     if (!irb || len != sizeof(*irb)) {
-        program_interrupt(env, PGM_SPECIFICATION, 2);
+        program_interrupt(env, PGM_ADDRESSING, 2);
         cc = -EIO;
         goto out;
     }
@@ -600,7 +600,7 @@ int ioinst_handle_chsc(CPUS390XState *env, uint32_t ipb)
     }
     req = s390_cpu_physical_memory_map(env, addr, &map_size, 1);
     if (!req || map_size != TARGET_PAGE_SIZE) {
-        program_interrupt(env, PGM_SPECIFICATION, 2);
+        program_interrupt(env, PGM_ADDRESSING, 2);
         ret = -EIO;
         goto out;
     }
@@ -655,7 +655,7 @@ int ioinst_handle_tpi(CPUS390XState *env, uint32_t ipb)
     orig_len = len;
     int_code = s390_cpu_physical_memory_map(env, addr, &len, 1);
     if (!int_code || (len != orig_len)) {
-        program_interrupt(env, PGM_SPECIFICATION, 2);
+        program_interrupt(env, PGM_ADDRESSING, 2);
         ret = -EIO;
         goto out;
     }
commit 61bf0dcb2efeffa62157de44606f9874a47ed7fe
Author: Thomas Huth <thuth at linux.vnet.ibm.com>
Date:   Fri Jun 21 10:13:42 2013 +0200

    s390x/ioinst: Add missing alignment checks for IO instructions
    
    The IO instructions MSCH, SSCH, STSCH, TSCH, STCRW and TPI require
    that the second operand address must be aligned on a word boundary.
    
    Signed-off-by: Thomas Huth <thuth at linux.vnet.ibm.com>
    Reviewed-by: Cornelia Huck <cornelia.huck at de.ibm.com>
    Signed-off-by: Christian Borntraeger <borntraeger at de.ibm.com>

diff --git a/target-s390x/ioinst.c b/target-s390x/ioinst.c
index 28c508d..91cc41b 100644
--- a/target-s390x/ioinst.c
+++ b/target-s390x/ioinst.c
@@ -157,6 +157,10 @@ int ioinst_handle_msch(CPUS390XState *env, uint64_t reg1, uint32_t ipb)
     }
     trace_ioinst_sch_id("msch", cssid, ssid, schid);
     addr = decode_basedisp_s(env, ipb);
+    if (addr & 3) {
+        program_interrupt(env, PGM_SPECIFICATION, 2);
+        return -EIO;
+    }
     schib = s390_cpu_physical_memory_map(env, addr, &len, 0);
     if (!schib || len != sizeof(*schib)) {
         program_interrupt(env, PGM_SPECIFICATION, 2);
@@ -228,6 +232,10 @@ int ioinst_handle_ssch(CPUS390XState *env, uint64_t reg1, uint32_t ipb)
     }
     trace_ioinst_sch_id("ssch", cssid, ssid, schid);
     addr = decode_basedisp_s(env, ipb);
+    if (addr & 3) {
+        program_interrupt(env, PGM_SPECIFICATION, 2);
+        return -EIO;
+    }
     orig_orb = s390_cpu_physical_memory_map(env, addr, &len, 0);
     if (!orig_orb || len != sizeof(*orig_orb)) {
         program_interrupt(env, PGM_SPECIFICATION, 2);
@@ -272,6 +280,10 @@ int ioinst_handle_stcrw(CPUS390XState *env, uint32_t ipb)
     hwaddr len = sizeof(*crw);
 
     addr = decode_basedisp_s(env, ipb);
+    if (addr & 3) {
+        program_interrupt(env, PGM_SPECIFICATION, 2);
+        return -EIO;
+    }
     crw = s390_cpu_physical_memory_map(env, addr, &len, 1);
     if (!crw || len != sizeof(*crw)) {
         program_interrupt(env, PGM_SPECIFICATION, 2);
@@ -300,6 +312,10 @@ int ioinst_handle_stsch(CPUS390XState *env, uint64_t reg1, uint32_t ipb)
     }
     trace_ioinst_sch_id("stsch", cssid, ssid, schid);
     addr = decode_basedisp_s(env, ipb);
+    if (addr & 3) {
+        program_interrupt(env, PGM_SPECIFICATION, 2);
+        return -EIO;
+    }
     schib = s390_cpu_physical_memory_map(env, addr, &len, 1);
     if (!schib || len != sizeof(*schib)) {
         program_interrupt(env, PGM_SPECIFICATION, 2);
@@ -345,6 +361,10 @@ int ioinst_handle_tsch(CPUS390XState *env, uint64_t reg1, uint32_t ipb)
     }
     trace_ioinst_sch_id("tsch", cssid, ssid, schid);
     addr = decode_basedisp_s(env, ipb);
+    if (addr & 3) {
+        program_interrupt(env, PGM_SPECIFICATION, 2);
+        return -EIO;
+    }
     irb = s390_cpu_physical_memory_map(env, addr, &len, 1);
     if (!irb || len != sizeof(*irb)) {
         program_interrupt(env, PGM_SPECIFICATION, 2);
@@ -625,6 +645,11 @@ int ioinst_handle_tpi(CPUS390XState *env, uint32_t ipb)
 
     trace_ioinst("tpi");
     addr = decode_basedisp_s(env, ipb);
+    if (addr & 3) {
+        program_interrupt(env, PGM_SPECIFICATION, 2);
+        return -EIO;
+    }
+
     lowcore = addr ? 0 : 1;
     len = lowcore ? 8 /* two words */ : 12 /* three words */;
     orig_len = len;
commit 2e14211476d70e3877180c19d72c0d96e23bdac5
Author: Heinz Graalfs <graalfs at linux.vnet.ibm.com>
Date:   Tue May 28 15:03:55 2013 +0200

    s390/sclpconsole: handle char layer busy conditions
    
    Handle busy conditions (errno=EAGAIN) in char layer by using
    the new char layer in the sclp console.
    
    Signed-off-by: Heinz Graalfs <graalfs at linux.vnet.ibm.com>
    Signed-off-by: Christian Borntraeger <borntraeger at de.ibm.com>

diff --git a/hw/char/sclpconsole.c b/hw/char/sclpconsole.c
index bcc7893..eb3988c 100644
--- a/hw/char/sclpconsole.c
+++ b/hw/char/sclpconsole.c
@@ -184,8 +184,6 @@ static int read_event_data(SCLPEvent *event, EventBufferHeader *evt_buf_hdr,
 static ssize_t write_console_data(SCLPEvent *event, const uint8_t *buf,
                                   size_t len)
 {
-    ssize_t ret = 0;
-    const uint8_t *iov_offset;
     SCLPConsole *scon = DO_UPCAST(SCLPConsole, event, event);
 
     if (!scon->chr) {
@@ -193,21 +191,7 @@ static ssize_t write_console_data(SCLPEvent *event, const uint8_t *buf,
         return len;
     }
 
-    iov_offset = buf;
-    while (len > 0) {
-        ret = qemu_chr_fe_write(scon->chr, buf, len);
-        if (ret == 0) {
-            /* a pty doesn't seem to be connected - no error */
-            len = 0;
-        } else if (ret == -EAGAIN || (ret > 0 && ret < len)) {
-            len -= ret;
-            iov_offset += ret;
-        } else {
-            len = 0;
-        }
-    }
-
-    return ret;
+    return qemu_chr_fe_write_all(scon->chr, buf, len);
 }
 
 static int write_event_data(SCLPEvent *event, EventBufferHeader *evt_buf_hdr)
commit cf66ee8e207d5c1831c7d4d8c7f2544314fc676c
Author: Alexey Kardashevskiy <aik at ozlabs.ru>
Date:   Fri Jul 26 20:52:05 2013 +1000

    hcd-ohci: add dma error handling
    
    Current hcd-ohci does not handle DMA errors. However they may happen
    so here we introduce simple error handling.
    
    On such errors, a typical OHCI will stop operating, signal the guest
    about the error by sending "UnrecoverableError Event", set itself into
    error state and set "Detected Parity Error" in its PCI config space
    to signal that it got an error and so does the patch.
    
    This also adds ohci_die() call to ohci_bus_start() to handle possible
    failure of qemu_new_timer_ns().
    
    Signed-off-by: Alexey Kardashevskiy <aik at ozlabs.ru>
    Signed-off-by: Gerd Hoffmann <kraxel at redhat.com>

diff --git a/hw/usb/hcd-ohci.c b/hw/usb/hcd-ohci.c
index d438d64..d7836d6 100644
--- a/hw/usb/hcd-ohci.c
+++ b/hw/usb/hcd-ohci.c
@@ -22,7 +22,6 @@
  *  o Allocate bandwidth in frames properly
  *  o Disable timers when nothing needs to be done, or remove timer usage
  *    all together.
- *  o Handle unrecoverable errors properly
  *  o BIOS work to boot from USB storage
 */
 
@@ -308,6 +307,8 @@ struct ohci_iso_td {
 
 #define OHCI_HRESET_FSBIR       (1 << 0)
 
+static void ohci_die(OHCIState *ohci);
+
 /* Update IRQ levels */
 static inline void ohci_intr_update(OHCIState *ohci)
 {
@@ -508,11 +509,13 @@ static inline int get_dwords(OHCIState *ohci,
     addr += ohci->localmem_base;
 
     for (i = 0; i < num; i++, buf++, addr += sizeof(*buf)) {
-        dma_memory_read(ohci->as, addr, buf, sizeof(*buf));
+        if (dma_memory_read(ohci->as, addr, buf, sizeof(*buf))) {
+            return -1;
+        }
         *buf = le32_to_cpu(*buf);
     }
 
-    return 1;
+    return 0;
 }
 
 /* Put an array of dwords in to main memory */
@@ -525,10 +528,12 @@ static inline int put_dwords(OHCIState *ohci,
 
     for (i = 0; i < num; i++, buf++, addr += sizeof(*buf)) {
         uint32_t tmp = cpu_to_le32(*buf);
-        dma_memory_write(ohci->as, addr, &tmp, sizeof(tmp));
+        if (dma_memory_write(ohci->as, addr, &tmp, sizeof(tmp))) {
+            return -1;
+        }
     }
 
-    return 1;
+    return 0;
 }
 
 /* Get an array of words from main memory */
@@ -540,11 +545,13 @@ static inline int get_words(OHCIState *ohci,
     addr += ohci->localmem_base;
 
     for (i = 0; i < num; i++, buf++, addr += sizeof(*buf)) {
-        dma_memory_read(ohci->as, addr, buf, sizeof(*buf));
+        if (dma_memory_read(ohci->as, addr, buf, sizeof(*buf))) {
+            return -1;
+        }
         *buf = le16_to_cpu(*buf);
     }
 
-    return 1;
+    return 0;
 }
 
 /* Put an array of words in to main memory */
@@ -557,10 +564,12 @@ static inline int put_words(OHCIState *ohci,
 
     for (i = 0; i < num; i++, buf++, addr += sizeof(*buf)) {
         uint16_t tmp = cpu_to_le16(*buf);
-        dma_memory_write(ohci->as, addr, &tmp, sizeof(tmp));
+        if (dma_memory_write(ohci->as, addr, &tmp, sizeof(tmp))) {
+            return -1;
+        }
     }
 
-    return 1;
+    return 0;
 }
 
 static inline int ohci_read_ed(OHCIState *ohci,
@@ -578,15 +587,15 @@ static inline int ohci_read_td(OHCIState *ohci,
 static inline int ohci_read_iso_td(OHCIState *ohci,
                                    dma_addr_t addr, struct ohci_iso_td *td)
 {
-    return (get_dwords(ohci, addr, (uint32_t *)td, 4) &&
-            get_words(ohci, addr + 16, td->offset, 8));
+    return get_dwords(ohci, addr, (uint32_t *)td, 4) ||
+           get_words(ohci, addr + 16, td->offset, 8);
 }
 
 static inline int ohci_read_hcca(OHCIState *ohci,
                                  dma_addr_t addr, struct ohci_hcca *hcca)
 {
-    dma_memory_read(ohci->as, addr + ohci->localmem_base, hcca, sizeof(*hcca));
-    return 1;
+    return dma_memory_read(ohci->as, addr + ohci->localmem_base,
+                           hcca, sizeof(*hcca));
 }
 
 static inline int ohci_put_ed(OHCIState *ohci,
@@ -610,23 +619,22 @@ static inline int ohci_put_td(OHCIState *ohci,
 static inline int ohci_put_iso_td(OHCIState *ohci,
                                   dma_addr_t addr, struct ohci_iso_td *td)
 {
-    return (put_dwords(ohci, addr, (uint32_t *)td, 4) &&
-            put_words(ohci, addr + 16, td->offset, 8));
+    return put_dwords(ohci, addr, (uint32_t *)td, 4 ||
+           put_words(ohci, addr + 16, td->offset, 8));
 }
 
 static inline int ohci_put_hcca(OHCIState *ohci,
                                 dma_addr_t addr, struct ohci_hcca *hcca)
 {
-    dma_memory_write(ohci->as,
-                     addr + ohci->localmem_base + HCCA_WRITEBACK_OFFSET,
-                     (char *)hcca + HCCA_WRITEBACK_OFFSET,
-                     HCCA_WRITEBACK_SIZE);
-    return 1;
+    return dma_memory_write(ohci->as,
+                            addr + ohci->localmem_base + HCCA_WRITEBACK_OFFSET,
+                            (char *)hcca + HCCA_WRITEBACK_OFFSET,
+                            HCCA_WRITEBACK_SIZE);
 }
 
 /* Read/Write the contents of a TD from/to main memory.  */
-static void ohci_copy_td(OHCIState *ohci, struct ohci_td *td,
-                         uint8_t *buf, int len, DMADirection dir)
+static int ohci_copy_td(OHCIState *ohci, struct ohci_td *td,
+                        uint8_t *buf, int len, DMADirection dir)
 {
     dma_addr_t ptr, n;
 
@@ -634,18 +642,26 @@ static void ohci_copy_td(OHCIState *ohci, struct ohci_td *td,
     n = 0x1000 - (ptr & 0xfff);
     if (n > len)
         n = len;
-    dma_memory_rw(ohci->as, ptr + ohci->localmem_base, buf, n, dir);
-    if (n == len)
-        return;
+
+    if (dma_memory_rw(ohci->as, ptr + ohci->localmem_base, buf, n, dir)) {
+        return -1;
+    }
+    if (n == len) {
+        return 0;
+    }
     ptr = td->be & ~0xfffu;
     buf += n;
-    dma_memory_rw(ohci->as, ptr + ohci->localmem_base, buf, len - n, dir);
+    if (dma_memory_rw(ohci->as, ptr + ohci->localmem_base, buf,
+                      len - n, dir)) {
+        return -1;
+    }
+    return 0;
 }
 
 /* Read/Write the contents of an ISO TD from/to main memory.  */
-static void ohci_copy_iso_td(OHCIState *ohci,
-                             uint32_t start_addr, uint32_t end_addr,
-                             uint8_t *buf, int len, DMADirection dir)
+static int ohci_copy_iso_td(OHCIState *ohci,
+                            uint32_t start_addr, uint32_t end_addr,
+                            uint8_t *buf, int len, DMADirection dir)
 {
     dma_addr_t ptr, n;
 
@@ -653,12 +669,20 @@ static void ohci_copy_iso_td(OHCIState *ohci,
     n = 0x1000 - (ptr & 0xfff);
     if (n > len)
         n = len;
-    dma_memory_rw(ohci->as, ptr + ohci->localmem_base, buf, n, dir);
-    if (n == len)
-        return;
+
+    if (dma_memory_rw(ohci->as, ptr + ohci->localmem_base, buf, n, dir)) {
+        return -1;
+    }
+    if (n == len) {
+        return 0;
+    }
     ptr = end_addr & ~0xfffu;
     buf += n;
-    dma_memory_rw(ohci->as, ptr + ohci->localmem_base, buf, len - n, dir);
+    if (dma_memory_rw(ohci->as, ptr + ohci->localmem_base, buf,
+                      len - n, dir)) {
+        return -1;
+    }
+    return 0;
 }
 
 static void ohci_process_lists(OHCIState *ohci, int completion);
@@ -698,8 +722,9 @@ static int ohci_service_iso_td(OHCIState *ohci, struct ohci_ed *ed,
 
     addr = ed->head & OHCI_DPTR_MASK;
 
-    if (!ohci_read_iso_td(ohci, addr, &iso_td)) {
+    if (ohci_read_iso_td(ohci, addr, &iso_td)) {
         printf("usb-ohci: ISO_TD read error at %x\n", addr);
+        ohci_die(ohci);
         return 0;
     }
 
@@ -740,7 +765,10 @@ static int ohci_service_iso_td(OHCIState *ohci, struct ohci_ed *ed,
         i = OHCI_BM(iso_td.flags, TD_DI);
         if (i < ohci->done_count)
             ohci->done_count = i;
-        ohci_put_iso_td(ohci, addr, &iso_td);
+        if (ohci_put_iso_td(ohci, addr, &iso_td)) {
+            ohci_die(ohci);
+            return 1;
+        }
         return 0;
     }
 
@@ -821,8 +849,11 @@ static int ohci_service_iso_td(OHCIState *ohci, struct ohci_ed *ed,
     }
 
     if (len && dir != OHCI_TD_DIR_IN) {
-        ohci_copy_iso_td(ohci, start_addr, end_addr, ohci->usb_buf, len,
-                         DMA_DIRECTION_TO_DEVICE);
+        if (ohci_copy_iso_td(ohci, start_addr, end_addr, ohci->usb_buf, len,
+                             DMA_DIRECTION_TO_DEVICE)) {
+            ohci_die(ohci);
+            return 1;
+        }
     }
 
     if (!completion) {
@@ -852,8 +883,11 @@ static int ohci_service_iso_td(OHCIState *ohci, struct ohci_ed *ed,
     /* Writeback */
     if (dir == OHCI_TD_DIR_IN && ret >= 0 && ret <= len) {
         /* IN transfer succeeded */
-        ohci_copy_iso_td(ohci, start_addr, end_addr, ohci->usb_buf, ret,
-                         DMA_DIRECTION_FROM_DEVICE);
+        if (ohci_copy_iso_td(ohci, start_addr, end_addr, ohci->usb_buf, ret,
+                             DMA_DIRECTION_FROM_DEVICE)) {
+            ohci_die(ohci);
+            return 1;
+        }
         OHCI_SET_BM(iso_td.offset[relative_frame_number], TD_PSW_CC,
                     OHCI_CC_NOERROR);
         OHCI_SET_BM(iso_td.offset[relative_frame_number], TD_PSW_SIZE, ret);
@@ -910,7 +944,9 @@ static int ohci_service_iso_td(OHCIState *ohci, struct ohci_ed *ed,
         if (i < ohci->done_count)
             ohci->done_count = i;
     }
-    ohci_put_iso_td(ohci, addr, &iso_td);
+    if (ohci_put_iso_td(ohci, addr, &iso_td)) {
+        ohci_die(ohci);
+    }
     return 1;
 }
 
@@ -943,8 +979,9 @@ static int ohci_service_td(OHCIState *ohci, struct ohci_ed *ed)
 #endif
         return 1;
     }
-    if (!ohci_read_td(ohci, addr, &td)) {
+    if (ohci_read_td(ohci, addr, &td)) {
         fprintf(stderr, "usb-ohci: TD read error at %x\n", addr);
+        ohci_die(ohci);
         return 0;
     }
 
@@ -997,8 +1034,10 @@ static int ohci_service_td(OHCIState *ohci, struct ohci_ed *ed)
                 pktlen = len;
             }
             if (!completion) {
-                ohci_copy_td(ohci, &td, ohci->usb_buf, pktlen,
-                             DMA_DIRECTION_TO_DEVICE);
+                if (ohci_copy_td(ohci, &td, ohci->usb_buf, pktlen,
+                                 DMA_DIRECTION_TO_DEVICE)) {
+                    ohci_die(ohci);
+                }
             }
         }
     }
@@ -1055,8 +1094,10 @@ static int ohci_service_td(OHCIState *ohci, struct ohci_ed *ed)
 
     if (ret >= 0) {
         if (dir == OHCI_TD_DIR_IN) {
-            ohci_copy_td(ohci, &td, ohci->usb_buf, ret,
-                         DMA_DIRECTION_FROM_DEVICE);
+            if (ohci_copy_td(ohci, &td, ohci->usb_buf, ret,
+                             DMA_DIRECTION_FROM_DEVICE)) {
+                ohci_die(ohci);
+            }
 #ifdef DEBUG_PACKET
             DPRINTF("  data:");
             for (i = 0; i < ret; i++)
@@ -1133,7 +1174,10 @@ static int ohci_service_td(OHCIState *ohci, struct ohci_ed *ed)
     if (i < ohci->done_count)
         ohci->done_count = i;
 exit_no_retire:
-    ohci_put_td(ohci, addr, &td);
+    if (ohci_put_td(ohci, addr, &td)) {
+        ohci_die(ohci);
+        return 1;
+    }
     return OHCI_BM(td.flags, TD_CC) != OHCI_CC_NOERROR;
 }
 
@@ -1151,8 +1195,9 @@ static int ohci_service_ed_list(OHCIState *ohci, uint32_t head, int completion)
         return 0;
 
     for (cur = head; cur; cur = next_ed) {
-        if (!ohci_read_ed(ohci, cur, &ed)) {
+        if (ohci_read_ed(ohci, cur, &ed)) {
             fprintf(stderr, "usb-ohci: ED read error at %x\n", cur);
+            ohci_die(ohci);
             return 0;
         }
 
@@ -1194,7 +1239,10 @@ static int ohci_service_ed_list(OHCIState *ohci, uint32_t head, int completion)
             }
         }
 
-        ohci_put_ed(ohci, cur, &ed);
+        if (ohci_put_ed(ohci, cur, &ed)) {
+            ohci_die(ohci);
+            return 0;
+        }
     }
 
     return active;
@@ -1236,7 +1284,11 @@ static void ohci_frame_boundary(void *opaque)
     OHCIState *ohci = opaque;
     struct ohci_hcca hcca;
 
-    ohci_read_hcca(ohci, ohci->hcca, &hcca);
+    if (ohci_read_hcca(ohci, ohci->hcca, &hcca)) {
+        fprintf(stderr, "usb-ohci: HCCA read error at %x\n", ohci->hcca);
+        ohci_die(ohci);
+        return;
+    }
 
     /* Process all the lists at the end of the frame */
     if (ohci->ctl & OHCI_CTL_PLE) {
@@ -1257,6 +1309,11 @@ static void ohci_frame_boundary(void *opaque)
     ohci->old_ctl = ohci->ctl;
     ohci_process_lists(ohci, 0);
 
+    /* Stop if UnrecoverableError happened or ohci_sof will crash */
+    if (ohci->intr_status & OHCI_INTR_UE) {
+        return;
+    }
+
     /* Frame boundary, so do EOF stuf here */
     ohci->frt = ohci->fit;
 
@@ -1282,7 +1339,9 @@ static void ohci_frame_boundary(void *opaque)
     ohci_sof(ohci);
 
     /* Writeback HCCA */
-    ohci_put_hcca(ohci, ohci->hcca, &hcca);
+    if (ohci_put_hcca(ohci, ohci->hcca, &hcca)) {
+        ohci_die(ohci);
+    }
 }
 
 /* Start sending SOF tokens across the USB bus, lists are processed in
@@ -1296,7 +1355,7 @@ static int ohci_bus_start(OHCIState *ohci)
 
     if (ohci->eof_timer == NULL) {
         fprintf(stderr, "usb-ohci: %s: qemu_new_timer_ns failed\n", ohci->name);
-        /* TODO: Signal unrecoverable error */
+        ohci_die(ohci);
         return 0;
     }
 
@@ -1857,6 +1916,22 @@ typedef struct {
     uint32_t firstport;
 } OHCIPCIState;
 
+/** A typical O/EHCI will stop operating, set itself into error state
+ * (which can be queried by MMIO) and will set PERR in its config
+ * space to signal that it got an error
+ */
+static void ohci_die(OHCIState *ohci)
+{
+    OHCIPCIState *dev = container_of(ohci, OHCIPCIState, state);
+
+    fprintf(stderr, "%s: DMA error\n", __func__);
+
+    ohci_set_interrupt(ohci, OHCI_INTR_UE);
+    ohci_bus_stop(ohci);
+    pci_set_word(dev->parent_obj.config + PCI_STATUS,
+                 PCI_STATUS_DETECTED_PARITY);
+}
+
 static int usb_ohci_initfn_pci(PCIDevice *dev)
 {
     OHCIPCIState *ohci = PCI_OHCI(dev);
commit 9f0f1a0c096f29a856f2e6903beda45b44ce9cdd
Author: Gerd Hoffmann <kraxel at redhat.com>
Date:   Wed Jun 26 17:05:06 2013 +0200

    uhci: egsm fix
    
    When the guest goes suspend the uhci controller while there are
    pending resume requests on the ports go signal global resume
    instantly.
    
    Signed-off-by: Gerd Hoffmann <kraxel at redhat.com>

diff --git a/hw/usb/hcd-uhci.c b/hw/usb/hcd-uhci.c
index cb44abc..ac82833 100644
--- a/hw/usb/hcd-uhci.c
+++ b/hw/usb/hcd-uhci.c
@@ -189,6 +189,7 @@ typedef struct UHCI_QH {
 
 static void uhci_async_cancel(UHCIAsync *async);
 static void uhci_queue_fill(UHCIQueue *q, UHCI_TD *td);
+static void uhci_resume(void *opaque);
 
 static inline int32_t uhci_queue_token(UHCI_TD *td)
 {
@@ -498,6 +499,12 @@ static void uhci_port_write(void *opaque, hwaddr addr,
             return;
         }
         s->cmd = val;
+        if (val & UHCI_CMD_EGSM) {
+            if ((s->ports[0].ctrl & UHCI_PORT_RD) ||
+                (s->ports[1].ctrl & UHCI_PORT_RD)) {
+                uhci_resume(s);
+            }
+        }
         break;
     case 0x02:
         s->status &= ~val;
commit ed60ff024fdb0e7ca9c002af166e10683cf49805
Author: Gerd Hoffmann <kraxel at redhat.com>
Date:   Thu Jul 25 13:12:35 2013 +0200

    xhci: handle USB_RET_IOERROR
    
    https://bugzilla.redhat.com/show_bug.cgi?id=980377
    
    Cc: qemu-stable at nongnu.org
    Signed-off-by: Gerd Hoffmann <kraxel at redhat.com>

diff --git a/hw/usb/hcd-xhci.c b/hw/usb/hcd-xhci.c
index 58f311d..7cbf813 100644
--- a/hw/usb/hcd-xhci.c
+++ b/hw/usb/hcd-xhci.c
@@ -1741,6 +1741,7 @@ static int xhci_complete_packet(XHCITransfer *xfer)
     trace_usb_xhci_xfer_error(xfer, xfer->packet.status);
     switch (xfer->packet.status) {
     case USB_RET_NODEV:
+    case USB_RET_IOERROR:
         xfer->status = CC_USB_TRANSACTION_ERROR;
         xhci_xfer_report(xfer);
         xhci_stall_ep(xfer);
commit 58ae52a8dc7752e3da9a905678580b4cb8181cdc
Author: Gerd Hoffmann <kraxel at redhat.com>
Date:   Mon Jul 22 15:34:12 2013 +0200

    spice: fix display initialization
    
    Spice has two display interface implementations:  One integrated into
    the qxl graphics card, and one generic which can operate with every
    qemu-emulated graphics card.
    
    The generic one is activated in case spice is used without qxl.  The
    logic for that only caught the "-vga qxl" case, "-device qxl-vga" goes
    unnoticed.  Fix that by adding a check in the spice interface
    registration so we'll notice the qxl card no matter how it is created.
    
    https://bugzilla.redhat.com/show_bug.cgi?id=981094
    
    Signed-off-by: Gerd Hoffmann <kraxel at redhat.com>

diff --git a/include/sysemu/sysemu.h b/include/sysemu/sysemu.h
index 3caeb66..d7a77b6 100644
--- a/include/sysemu/sysemu.h
+++ b/include/sysemu/sysemu.h
@@ -103,7 +103,6 @@ typedef enum {
 
 extern int vga_interface_type;
 #define xenfb_enabled (vga_interface_type == VGA_XENFB)
-#define qxl_enabled (vga_interface_type == VGA_QXL)
 
 extern int graphic_width;
 extern int graphic_height;
diff --git a/include/ui/qemu-spice.h b/include/ui/qemu-spice.h
index eba6d77..c6c756b 100644
--- a/include/ui/qemu-spice.h
+++ b/include/ui/qemu-spice.h
@@ -27,6 +27,7 @@
 #include "monitor/monitor.h"
 
 extern int using_spice;
+extern int spice_displays;
 
 void qemu_spice_init(void);
 void qemu_spice_input_init(void);
@@ -57,6 +58,7 @@ static inline CharDriverState *qemu_chr_open_spice_port(const char *name)
 #include "monitor/monitor.h"
 
 #define using_spice 0
+#define spice_displays 0
 static inline int qemu_spice_set_passwd(const char *passwd,
                                         bool fail_if_connected,
                                         bool disconnect_if_connected)
diff --git a/ui/spice-core.c b/ui/spice-core.c
index 033fd89..bd7a248 100644
--- a/ui/spice-core.c
+++ b/ui/spice-core.c
@@ -48,6 +48,7 @@ static char *auth_passwd;
 static time_t auth_expires = TIME_MAX;
 static int spice_migration_completed;
 int using_spice = 0;
+int spice_displays;
 
 static QemuThread me;
 
@@ -836,6 +837,10 @@ int qemu_spice_add_interface(SpiceBaseInstance *sin)
         qemu_add_vm_change_state_handler(vm_change_state_handler, NULL);
     }
 
+    if (strcmp(sin->sif->type, SPICE_INTERFACE_QXL) == 0) {
+        spice_displays++;
+    }
+
     return spice_server_add_interface(spice_server, sin);
 }
 
diff --git a/vl.c b/vl.c
index 25b8f2f..f422a1c 100644
--- a/vl.c
+++ b/vl.c
@@ -4387,7 +4387,7 @@ int main(int argc, char **argv, char **envp)
     }
 #endif
 #ifdef CONFIG_SPICE
-    if (using_spice && !qxl_enabled) {
+    if (using_spice && !spice_displays) {
         qemu_spice_display_init(ds);
     }
 #endif
commit 908c67fca4b2c12a9b2336aa9c188f84468b60b7
Author: Max Filippov <jcmvbkbc at gmail.com>
Date:   Sun Jul 21 12:55:46 2013 +0400

    target-xtensa: check register window inline
    
    This lowers time spent in helper_window_check as reported by perf top
    from ~8% to ~0.15% accelerating register-intensive tests by ~20%.
    
    Signed-off-by: Max Filippov <jcmvbkbc at gmail.com>

diff --git a/target-xtensa/translate.c b/target-xtensa/translate.c
index 15fab1b..504cc53 100644
--- a/target-xtensa/translate.c
+++ b/target-xtensa/translate.c
@@ -305,16 +305,21 @@ static void gen_left_shift_sar(DisasContext *dc, TCGv_i32 sa)
     tcg_temp_free(tmp);
 }
 
-static void gen_advance_ccount(DisasContext *dc)
+static void gen_advance_ccount_cond(DisasContext *dc)
 {
     if (dc->ccount_delta > 0) {
         TCGv_i32 tmp = tcg_const_i32(dc->ccount_delta);
-        dc->ccount_delta = 0;
         gen_helper_advance_ccount(cpu_env, tmp);
         tcg_temp_free(tmp);
     }
 }
 
+static void gen_advance_ccount(DisasContext *dc)
+{
+    gen_advance_ccount_cond(dc);
+    dc->ccount_delta = 0;
+}
+
 static void reset_used_window(DisasContext *dc)
 {
     dc->used_window = 0;
@@ -829,15 +834,27 @@ static void gen_window_check1(DisasContext *dc, unsigned r1)
     }
     if (option_enabled(dc, XTENSA_OPTION_WINDOWED_REGISTER) &&
             r1 / 4 > dc->used_window) {
-        TCGv_i32 pc = tcg_const_i32(dc->pc);
-        TCGv_i32 w = tcg_const_i32(r1 / 4);
+        int label = gen_new_label();
+        TCGv_i32 ws = tcg_temp_new_i32();
 
         dc->used_window = r1 / 4;
-        gen_advance_ccount(dc);
-        gen_helper_window_check(cpu_env, pc, w);
+        tcg_gen_deposit_i32(ws, cpu_SR[WINDOW_START], cpu_SR[WINDOW_START],
+                dc->config->nareg / 4, dc->config->nareg / 4);
+        tcg_gen_shr_i32(ws, ws, cpu_SR[WINDOW_BASE]);
+        tcg_gen_andi_i32(ws, ws, (2 << (r1 / 4)) - 2);
+        tcg_gen_brcondi_i32(TCG_COND_EQ, ws, 0, label);
+        {
+            TCGv_i32 pc = tcg_const_i32(dc->pc);
+            TCGv_i32 w = tcg_const_i32(r1 / 4);
+
+            gen_advance_ccount_cond(dc);
+            gen_helper_window_check(cpu_env, pc, w);
 
-        tcg_temp_free(w);
-        tcg_temp_free(pc);
+            tcg_temp_free(w);
+            tcg_temp_free(pc);
+        }
+        gen_set_label(label);
+        tcg_temp_free(ws);
     }
 }
 
commit 0857a06ef784783887e756d4b7b5f874512c506c
Author: Max Filippov <jcmvbkbc at gmail.com>
Date:   Sun Jul 21 07:54:37 2013 +0400

    target-xtensa: don't generate dead code to access invalid SRs
    
    This fixes the following test failure caused by access to undefined SR:
    
        qemu-system-xtensa -M sim -cpu dc232b -nographic -semihosting  -kernel ./test_sr.tst
        QEMU 1.4.50 monitor - type 'help' for more information
        (qemu) QEMU 1.4.50 monitor - type 'help' for more information
        (qemu) qemu-system-xtensa: tcg/tcg.c:1673: temp_save: Assertion `s->temps[temp].val_type == 2 || s->temps[temp].fixed_reg' failed.
    
    Signed-off-by: Max Filippov <jcmvbkbc at gmail.com>

diff --git a/target-xtensa/translate.c b/target-xtensa/translate.c
index 7ea5e2a..15fab1b 100644
--- a/target-xtensa/translate.c
+++ b/target-xtensa/translate.c
@@ -491,7 +491,7 @@ static void gen_brcondi(DisasContext *dc, TCGCond cond,
     tcg_temp_free(tmp);
 }
 
-static void gen_check_sr(DisasContext *dc, uint32_t sr, unsigned access)
+static bool gen_check_sr(DisasContext *dc, uint32_t sr, unsigned access)
 {
     if (!xtensa_option_bits_enabled(dc->config, sregnames[sr].opt_bits)) {
         if (sregnames[sr].name) {
@@ -500,6 +500,7 @@ static void gen_check_sr(DisasContext *dc, uint32_t sr, unsigned access)
             qemu_log("SR %d is not implemented\n", sr);
         }
         gen_exception_cause(dc, ILLEGAL_INSTRUCTION_CAUSE);
+        return false;
     } else if (!(sregnames[sr].access & access)) {
         static const char * const access_text[] = {
             [SR_R] = "rsr",
@@ -510,7 +511,9 @@ static void gen_check_sr(DisasContext *dc, uint32_t sr, unsigned access)
         qemu_log("SR %s is not available for %s\n", sregnames[sr].name,
                 access_text[access]);
         gen_exception_cause(dc, ILLEGAL_INSTRUCTION_CAUSE);
+        return false;
     }
+    return true;
 }
 
 static void gen_rsr_ccount(DisasContext *dc, TCGv_i32 d, uint32_t sr)
@@ -1482,9 +1485,9 @@ static void disas_xtensa_insn(CPUXtensaState *env, DisasContext *dc)
                 break;
 
             case 6: /*XSR*/
-                {
+                if (gen_check_sr(dc, RSR_SR, SR_X)) {
                     TCGv_i32 tmp = tcg_temp_new_i32();
-                    gen_check_sr(dc, RSR_SR, SR_X);
+
                     if (RSR_SR >= 64) {
                         gen_check_privilege(dc);
                     }
@@ -1707,21 +1710,23 @@ static void disas_xtensa_insn(CPUXtensaState *env, DisasContext *dc)
         case 3: /*RST3*/
             switch (OP2) {
             case 0: /*RSR*/
-                gen_check_sr(dc, RSR_SR, SR_R);
-                if (RSR_SR >= 64) {
-                    gen_check_privilege(dc);
+                if (gen_check_sr(dc, RSR_SR, SR_R)) {
+                    if (RSR_SR >= 64) {
+                        gen_check_privilege(dc);
+                    }
+                    gen_window_check1(dc, RRR_T);
+                    gen_rsr(dc, cpu_R[RRR_T], RSR_SR);
                 }
-                gen_window_check1(dc, RRR_T);
-                gen_rsr(dc, cpu_R[RRR_T], RSR_SR);
                 break;
 
             case 1: /*WSR*/
-                gen_check_sr(dc, RSR_SR, SR_W);
-                if (RSR_SR >= 64) {
-                    gen_check_privilege(dc);
+                if (gen_check_sr(dc, RSR_SR, SR_W)) {
+                    if (RSR_SR >= 64) {
+                        gen_check_privilege(dc);
+                    }
+                    gen_window_check1(dc, RRR_T);
+                    gen_wsr(dc, RSR_SR, cpu_R[RRR_T]);
                 }
-                gen_window_check1(dc, RRR_T);
-                gen_wsr(dc, RSR_SR, cpu_R[RRR_T]);
                 break;
 
             case 2: /*SEXTu*/
commit aaa2ebc567619474d219017785b46ddc9295fffa
Author: Andreas Färber <afaerber at suse.de>
Date:   Sat Jul 6 20:41:37 2013 +0200

    tests/tcg/xtensa: Fix out-of-tree build
    
    Signed-off-by: Andreas Färber <afaerber at suse.de>
    Signed-off-by: Max Filippov <jcmvbkbc at gmail.com>

diff --git a/configure b/configure
index 1c0cc81..c205904 100755
--- a/configure
+++ b/configure
@@ -4502,13 +4502,14 @@ if [ "$dtc_internal" = "yes" ]; then
 fi
 
 # build tree in object directory in case the source is not in the current directory
-DIRS="tests tests/tcg tests/tcg/cris tests/tcg/lm32 tests/libqos"
+DIRS="tests tests/tcg tests/tcg/cris tests/tcg/lm32 tests/tcg/xtensa"
+DIRS="$DIRS tests/libqos"
 DIRS="$DIRS pc-bios/optionrom pc-bios/spapr-rtas pc-bios/s390-ccw"
 DIRS="$DIRS roms/seabios roms/vgabios"
 DIRS="$DIRS qapi-generated"
 FILES="Makefile tests/tcg/Makefile qdict-test-data.txt"
 FILES="$FILES tests/tcg/cris/Makefile tests/tcg/cris/.gdbinit"
-FILES="$FILES tests/tcg/lm32/Makefile po/Makefile"
+FILES="$FILES tests/tcg/lm32/Makefile tests/tcg/xtensa/Makefile po/Makefile"
 FILES="$FILES pc-bios/optionrom/Makefile pc-bios/keymaps"
 FILES="$FILES pc-bios/spapr-rtas/Makefile"
 FILES="$FILES pc-bios/s390-ccw/Makefile"
diff --git a/tests/tcg/xtensa/Makefile b/tests/tcg/xtensa/Makefile
index 9e50d8d..1b519ca 100644
--- a/tests/tcg/xtensa/Makefile
+++ b/tests/tcg/xtensa/Makefile
@@ -1,9 +1,9 @@
--include ../../config-host.mak
+-include ../../../config-host.mak
 
 CROSS=xtensa-dc232b-elf-
 
 ifndef XT
-SIM = qemu-system-xtensa
+SIM = ../../../xtensa-softmmu/qemu-system-xtensa
 SIMFLAGS = -M sim -cpu dc232b -nographic -semihosting $(EXTFLAGS) -kernel
 SIMDEBUG = -s -S
 else
@@ -13,10 +13,12 @@ SIMDEBUG = --gdbserve=0
 endif
 
 CC      = $(CROSS)gcc
-AS      = $(CROSS)gcc -x assembler
+AS      = $(CROSS)gcc -x assembler-with-cpp
 LD      = $(CROSS)ld
 
-LDFLAGS = -Tlinker.ld
+XTENSA_SRC_PATH = $(SRC_PATH)/tests/tcg/xtensa
+
+LDFLAGS = -T$(XTENSA_SRC_PATH)/linker.ld
 
 CRT        = crt.o vectors.o
 
@@ -53,13 +55,13 @@ TESTCASES += test_windowed.tst
 
 all: build
 
-%.o: $(SRC_PATH)/tests/xtensa/%.c
-	$(CC) $(CFLAGS) -c $< -o $@
+%.o: $(XTENSA_SRC_PATH)/%.c
+	$(CC) -I$(XTENSA_SRC_PATH) $(CFLAGS) -c $< -o $@
 
-%.o: $(SRC_PATH)/tests/xtensa/%.S
-	$(AS) $(ASFLAGS) -c $< -o $@
+%.o: $(XTENSA_SRC_PATH)/%.S
+	$(AS) -Wa,-I,$(XTENSA_SRC_PATH) $(ASFLAGS) -c $< -o $@
 
-%.tst: %.o macros.inc $(CRT) Makefile
+%.tst: %.o $(XTENSA_SRC_PATH)/macros.inc $(CRT) Makefile
 	$(LD) $(LDFLAGS) $(NOSTDFLAGS) $(CRT) $< -o $@
 
 build: $(TESTCASES)
commit a00817cc4c18b7872e92765a4736fb2227cc237b
Author: Max Filippov <jcmvbkbc at gmail.com>
Date:   Mon Mar 4 07:02:00 2013 +0400

    target-xtensa: avoid double-stopping at breakpoints
    
    env->exception_taken is set every time an exception is taken. It is used
    to allow single-stepping to stop at the first exception handler
    instruction. This however must exclude debug exceptions, as otherwise
    first step from the instruction where breakpoint was hit stops at that
    same instruction.
    Also don't check env->exception_taken directly from the
    gen_intermediate_code_internal, instead allocate and use TB flag
    XTENSA_TBFLAG_EXCEPTION.
    
    Signed-off-by: Max Filippov <jcmvbkbc at gmail.com>

diff --git a/target-xtensa/cpu.h b/target-xtensa/cpu.h
index a8f02f6..95103e9 100644
--- a/target-xtensa/cpu.h
+++ b/target-xtensa/cpu.h
@@ -484,6 +484,7 @@ static inline int cpu_mmu_index(CPUXtensaState *env)
 #define XTENSA_TBFLAG_ICOUNT 0x20
 #define XTENSA_TBFLAG_CPENABLE_MASK 0x3fc0
 #define XTENSA_TBFLAG_CPENABLE_SHIFT 6
+#define XTENSA_TBFLAG_EXCEPTION 0x4000
 
 static inline void cpu_get_tb_cpu_state(CPUXtensaState *env, target_ulong *pc,
         target_ulong *cs_base, int *flags)
@@ -510,6 +511,9 @@ static inline void cpu_get_tb_cpu_state(CPUXtensaState *env, target_ulong *pc,
     if (xtensa_option_enabled(env->config, XTENSA_OPTION_COPROCESSOR)) {
         *flags |= env->sregs[CPENABLE] << XTENSA_TBFLAG_CPENABLE_SHIFT;
     }
+    if (ENV_GET_CPU(env)->singlestep_enabled && env->exception_taken) {
+        *flags |= XTENSA_TBFLAG_EXCEPTION;
+    }
 }
 
 #include "exec/cpu-all.h"
diff --git a/target-xtensa/op_helper.c b/target-xtensa/op_helper.c
index 834fe90..6ca912c 100644
--- a/target-xtensa/op_helper.c
+++ b/target-xtensa/op_helper.c
@@ -96,6 +96,9 @@ static void tb_invalidate_virtual_addr(CPUXtensaState *env, uint32_t vaddr)
 void HELPER(exception)(CPUXtensaState *env, uint32_t excp)
 {
     env->exception_index = excp;
+    if (excp == EXCP_DEBUG) {
+        env->exception_taken = 0;
+    }
     cpu_loop_exit(env);
 }
 
diff --git a/target-xtensa/translate.c b/target-xtensa/translate.c
index e692329..7ea5e2a 100644
--- a/target-xtensa/translate.c
+++ b/target-xtensa/translate.c
@@ -2918,8 +2918,7 @@ void gen_intermediate_code_internal(XtensaCPU *cpu,
 
     gen_tb_start();
 
-    if (cs->singlestep_enabled && env->exception_taken) {
-        env->exception_taken = 0;
+    if (tb->flags & XTENSA_TBFLAG_EXCEPTION) {
         tcg_gen_movi_i32(cpu_pc, dc.pc);
         gen_exception(&dc, EXCP_DEBUG);
     }
commit 5739006b9ab1ae3680359db5a291eae97eef0f9f
Author: Max Filippov <jcmvbkbc at gmail.com>
Date:   Mon Jan 21 18:40:04 2013 +0400

    target-xtensa: add fallthrough markers
    
    Explicitly mark cases where we are deliberately falling through to the
    following code.
    
    Signed-off-by: Max Filippov <jcmvbkbc at gmail.com>

diff --git a/target-xtensa/op_helper.c b/target-xtensa/op_helper.c
index 4c41de0..834fe90 100644
--- a/target-xtensa/op_helper.c
+++ b/target-xtensa/op_helper.c
@@ -448,8 +448,10 @@ void HELPER(check_atomctl)(CPUXtensaState *env, uint32_t pc, uint32_t vaddr)
     switch (access & PAGE_CACHE_MASK) {
     case PAGE_CACHE_WB:
         atomctl >>= 2;
+        /* fall through */
     case PAGE_CACHE_WT:
         atomctl >>= 2;
+        /* fall through */
     case PAGE_CACHE_BYPASS:
         if ((atomctl & 0x3) == 0) {
             HELPER(exception_cause_vaddr)(env, pc,
commit 7be9d0e6d15c2f4b1a06912128c17b4eb1f32705
Author: Max Filippov <jcmvbkbc at gmail.com>
Date:   Mon Dec 17 00:32:27 2012 +0400

    target-xtensa: add extui unit test
    
    Signed-off-by: Max Filippov <jcmvbkbc at gmail.com>

diff --git a/tests/tcg/xtensa/Makefile b/tests/tcg/xtensa/Makefile
index 002fd87..9e50d8d 100644
--- a/tests/tcg/xtensa/Makefile
+++ b/tests/tcg/xtensa/Makefile
@@ -26,6 +26,7 @@ TESTCASES += test_bi.tst
 TESTCASES += test_break.tst
 TESTCASES += test_bz.tst
 TESTCASES += test_clamps.tst
+TESTCASES += test_extui.tst
 TESTCASES += test_fail.tst
 TESTCASES += test_interrupt.tst
 TESTCASES += test_loop.tst
diff --git a/tests/tcg/xtensa/test_extui.S b/tests/tcg/xtensa/test_extui.S
new file mode 100644
index 0000000..5d55451
--- /dev/null
+++ b/tests/tcg/xtensa/test_extui.S
@@ -0,0 +1,26 @@
+.include "macros.inc"
+
+test_suite extui
+
+.macro test_extui v, shiftimm, maskimm
+    .if     \shiftimm + \maskimm <= 32
+    movi    a2, \v
+    extui   a3, a2, \shiftimm, \maskimm
+    movi    a4, ((\v) >> (\shiftimm)) & ((1 << (\maskimm)) - 1)
+    assert  eq, a3, a4
+    .endif
+.endm
+
+test extui
+    .set    shiftimm, 0
+    .rept   32
+    .set    maskimm, 1
+    .rept   16
+    test_extui 0xc8df1370, shiftimm, maskimm
+    .set    maskimm, maskimm + 1
+    .endr
+    .set    shiftimm, shiftimm + 1
+    .endr
+test_end
+
+test_suite_end
commit 0779caeb1a17f4d3ed14e2925b36ba09b084fb7b
Author: Arthur Chunqi Li <yzt356 at gmail.com>
Date:   Sun Jul 7 23:13:37 2013 +0800

    Initialize IA32_FEATURE_CONTROL MSR in reset and migration
    
    The recent KVM patch adds IA32_FEATURE_CONTROL support. QEMU needs
    to clear this MSR when reset vCPU and keep the value of it when
    migration. This patch add this feature.
    
    Signed-off-by: Arthur Chunqi Li <yzt356 at gmail.com>
    Signed-off-by: Gleb Natapov <gleb at redhat.com>

diff --git a/target-i386/cpu.h b/target-i386/cpu.h
index cedefdc..3a52f94 100644
--- a/target-i386/cpu.h
+++ b/target-i386/cpu.h
@@ -301,6 +301,7 @@
 #define MSR_IA32_APICBASE_BSP           (1<<8)
 #define MSR_IA32_APICBASE_ENABLE        (1<<11)
 #define MSR_IA32_APICBASE_BASE          (0xfffff<<12)
+#define MSR_IA32_FEATURE_CONTROL        0x0000003a
 #define MSR_TSC_ADJUST                  0x0000003b
 #define MSR_IA32_TSCDEADLINE            0x6e0
 
@@ -813,6 +814,7 @@ typedef struct CPUX86State {
 
     uint64_t mcg_status;
     uint64_t msr_ia32_misc_enable;
+    uint64_t msr_ia32_feature_control;
 
     /* exception/interrupt handling */
     int error_code;
diff --git a/target-i386/kvm.c b/target-i386/kvm.c
index 3c9d10a..84ac00a 100644
--- a/target-i386/kvm.c
+++ b/target-i386/kvm.c
@@ -1121,6 +1121,7 @@ static int kvm_put_msrs(X86CPU *cpu, int level)
         if (hyperv_vapic_recommended()) {
             kvm_msr_entry_set(&msrs[n++], HV_X64_MSR_APIC_ASSIST_PAGE, 0);
         }
+        kvm_msr_entry_set(&msrs[n++], MSR_IA32_FEATURE_CONTROL, env->msr_ia32_feature_control);
     }
     if (env->mcg_cap) {
         int i;
@@ -1345,6 +1346,7 @@ static int kvm_get_msrs(X86CPU *cpu)
     if (has_msr_misc_enable) {
         msrs[n++].index = MSR_IA32_MISC_ENABLE;
     }
+    msrs[n++].index = MSR_IA32_FEATURE_CONTROL;
 
     if (!env->tsc_valid) {
         msrs[n++].index = MSR_IA32_TSC;
@@ -1443,6 +1445,8 @@ static int kvm_get_msrs(X86CPU *cpu)
         case MSR_IA32_MISC_ENABLE:
             env->msr_ia32_misc_enable = msrs[i].data;
             break;
+        case MSR_IA32_FEATURE_CONTROL:
+            env->msr_ia32_feature_control = msrs[i].data;
         default:
             if (msrs[i].index >= MSR_MC0_CTL &&
                 msrs[i].index < MSR_MC0_CTL + (env->mcg_cap & 0xff) * 4) {
diff --git a/target-i386/machine.c b/target-i386/machine.c
index f9ec581..0d2088e 100644
--- a/target-i386/machine.c
+++ b/target-i386/machine.c
@@ -435,6 +435,14 @@ static bool misc_enable_needed(void *opaque)
     return env->msr_ia32_misc_enable != MSR_IA32_MISC_ENABLE_DEFAULT;
 }
 
+static bool feature_control_needed(void *opaque)
+{
+    X86CPU *cpu = opaque;
+    CPUX86State *env = &cpu->env;
+
+    return env->msr_ia32_feature_control != 0;
+}
+
 static const VMStateDescription vmstate_msr_ia32_misc_enable = {
     .name = "cpu/msr_ia32_misc_enable",
     .version_id = 1,
@@ -446,6 +454,17 @@ static const VMStateDescription vmstate_msr_ia32_misc_enable = {
     }
 };
 
+static const VMStateDescription vmstate_msr_ia32_feature_control = {
+    .name = "cpu/msr_ia32_feature_control",
+    .version_id = 1,
+    .minimum_version_id = 1,
+    .minimum_version_id_old = 1,
+    .fields      = (VMStateField []) {
+        VMSTATE_UINT64(env.msr_ia32_feature_control, X86CPU),
+        VMSTATE_END_OF_LIST()
+    }
+};
+
 const VMStateDescription vmstate_x86_cpu = {
     .name = "cpu",
     .version_id = 12,
@@ -571,6 +590,9 @@ const VMStateDescription vmstate_x86_cpu = {
         }, {
             .vmsd = &vmstate_msr_ia32_misc_enable,
             .needed = misc_enable_needed,
+        }, {
+            .vmsd = &vmstate_msr_ia32_feature_control,
+            .needed = feature_control_needed,
         } , {
             /* empty */
         }


More information about the Spice-commits mailing list