[Spice-commits] 368 commits - HACKING Makefile Makefile.objs Makefile.target a.out.h acl.c aio.c arch_init.c arm.ld async.c audio/alsaaudio.c audio/audio.c audio/audio_template.h audio/esdaudio.c audio/mixeng.c audio/ossaudio.c audio/paaudio.c audio/wavaudio.c audio/wavcapture.c audio/winwaveaudio.c bitmap.h block-migration.c block.c block.h block/blkdebug.c block/bochs.c block/cloop.c block/curl.c block/dmg.c block/nbd.c block/parallels.c block/qcow.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-check.c block/qed-cluster.c block/qed-gencb.c block/qed-l2-cache.c block/qed.c block/raw-win32.c block/raw.c block/rbd.c block/sheepdog.c block/vdi.c block/vmdk.c block/vpc.c block/vvfat.c block_int.h blockdev.c bsd-user/mmap.c bsd-user/syscall.c bt-host.c bt-vhci.c buffered_file.c check-qdict.c check-qfloat.c check-qint.c check-qlist.c check-qstring.c compiler.h configure console.c coroutine-gthread.c coroutin e-ucontext.c coroutine-win32.c cpu-all.h cpus.c cris-dis.c cursor.c cutils.c device_tree.c disas.c dma-helpers.c docs/memory.txt docs/qapi-code-gen.txt docs/tracing.txt dyngen-exec.h error.c exec.c fpu/softfloat.c fpu/softfloat.h fsdev/file-op-9p.h fsdev/qemu-fsdev.c gdbstub.c hmp-commands.hx hppa.ld hw/9pfs hw/acpi.c hw/adb.c hw/adlib.c hw/apb_pci.c hw/apic.c hw/apic.h hw/applesmc.c hw/arm11mpcore.c hw/arm_gic.c hw/arm_sysctl.c hw/arm_timer.c hw/armv7m.c hw/armv7m_nvic.c hw/axis_dev88.c hw/baum.c hw/bitbang_i2c.c hw/blizzard.c hw/bt-hci-csr.c hw/bt-hci.c hw/bt-hid.c hw/bt-l2cap.c hw/bt-sdp.c hw/bt.c hw/bt.h hw/cbus.c hw/ccid-card-emulated.c hw/ccid-card-passthru.c hw/cirrus_vga.c hw/cris_pic_cpu.c hw/debugcon.c hw/devices.h hw/dp8393x.c hw/ds1225y.c hw/e1000.c hw/e1000_hw.h hw/eepro100.c hw/eeprom93xx.c hw/elf_ops.h hw/escc.c hw/esp.c hw/etraxfs.h hw/etraxfs_dma.c hw/etraxfs_eth.c hw/etraxfs_ser.c hw/fdc.c hw/flash.h hw/fw_cfg.c hw/g364fb.c hw/grlib_apbuart.c hw/grlib_gptim er.c hw/grlib_irqmp.c hw/gt64xxx.c hw/gus.c hw/heathrow_pic.c hw/hid.c hw/hid.h hw/hpet_emul.h hw/hw.h hw/i8259.c hw/ide hw/intel-hda.c hw/ioapic.c hw/irq.c hw/isa-bus.c hw/isa.h hw/isa_mmio.c hw/ivshmem.c hw/jazz_led.c hw/leon3.c hw/lm32_boards.c hw/lm32_hwsetup.h hw/lm32_juart.c hw/lm32_uart.c hw/loader.c hw/lsi53c895a.c hw/m48t59.c hw/mac_dbdma.c hw/mac_nvram.c hw/mcf5206.c hw/mcf5208.c hw/mcf_fec.c hw/mcf_intc.c hw/mcf_uart.c hw/microblaze_pic_cpu.c hw/microblaze_pic_cpu.h hw/milkymist-softusb.c hw/milkymist-tmu2.c hw/milkymist-uart.c hw/milkymist.c hw/mips.h hw/mips_fulong2e.c hw/mips_jazz.c hw/mips_malta.c hw/mips_mipssim.c hw/mips_r4k.c hw/mipsnet.c hw/mpcore.c hw/msix.c hw/msmouse.c hw/multiboot.c hw/nand.c hw/nseries.c hw/omap.h hw/omap1.c hw/omap2.c hw/omap_clk.c hw/omap_dma.c hw/omap_dss.c hw/omap_gpio.c hw/omap_gpmc.c hw/omap_gptimer.c hw/omap_i2c.c hw/omap_intc.c hw/omap_l4.c hw/omap_lcdc.c hw/omap_mmc.c hw/omap_sdrc.c hw/omap_spi.c hw/omap_synctimer.c hw/omap_u art.c hw/onenand.c hw/openpic.c hw/parallel.c hw/pc.c hw/pc.h hw/pc_piix.c hw/pci-stub.c hw/pci.c hw/pci.h hw/pcie.c hw/pcie_aer.c hw/pcie_host.c hw/pcie_host.h hw/pcie_port.c hw/pckbd.c hw/pcnet-pci.c hw/pcnet.h hw/petalogix_ml605_mmu.c hw/petalogix_s3adsp1800_mmu.c hw/pflash_cfi01.c hw/pflash_cfi02.c hw/piix_pci.c hw/pl011.c hw/pl061.c hw/pl110.c hw/pl110_template.h hw/ppc.c hw/ppc405.h hw/ppc405_boards.c hw/ppc405_uc.c hw/ppc440.c hw/ppc440_bamboo.c hw/ppc4xx.h hw/ppc4xx_devs.c hw/ppc4xx_pci.c hw/ppc_newworld.c hw/ppc_oldworld.c hw/ppc_prep.c hw/ppce500_mpc8544ds.c hw/ppce500_pci.c hw/prep_pci.c hw/ps2.c hw/ptimer.c hw/pxa2xx.c hw/pxa2xx_dma.c hw/pxa2xx_keypad.c hw/pxa2xx_lcd.c hw/pxa2xx_mmci.c hw/pxa2xx_pcmcia.c hw/qdev-properties.c hw/qdev.c hw/qxl-render.c hw/qxl.c hw/r2d.c hw/rc4030.c hw/realview.c hw/realview_gic.c hw/rtl8139.c hw/s390-virtio.c hw/scsi-bus.c hw/scsi-defs.h hw/scsi-disk.c hw/scsi-generic.c hw/scsi.h hw/sd.c hw/serial.c hw/sh7750.c hw/sh_intc.c hw/sh_p ci.c hw/sh_serial.c hw/sh_timer.c hw/slavio_intctl.c hw/slavio_misc.c hw/slavio_timer.c hw/sm501.c hw/smbios.c hw/smbios.h hw/smbus_eeprom.c hw/soc_dma.c hw/spapr.c hw/spapr_vio.c hw/spapr_vscsi.c hw/spapr_vty.c hw/srp.h hw/stellaris.c hw/stellaris_enet.c hw/stellaris_input.c hw/strongarm.c hw/sun4m.c hw/sun4m_iommu.c hw/sun4u.c hw/syborg_fb.c hw/syborg_interrupt.c hw/syborg_keyboard.c hw/syborg_pointer.c hw/syborg_serial.c hw/sysbus.c hw/sysbus.h hw/tc58128.c hw/tc6393xb.c hw/tcx.c hw/tsc2005.c hw/tsc210x.c hw/tusb6010.c hw/usb-bus.c hw/usb-ccid.c hw/usb-desc.c hw/usb-ehci.c hw/usb-hid.c hw/usb-msd.c hw/usb-musb.c hw/usb-net.c hw/usb-serial.c hw/usb-uhci.c hw/usb.h hw/versatile_pci.c hw/versatilepb.c hw/vexpress.c hw/vga-isa-mm.c hw/vga-isa.c hw/vga-pci.c hw/vga.c hw/vga_int.h hw/vhost.c hw/vhost.h hw/vhost_net.c hw/virtex_ml507.c hw/virtio-balloon.h hw/virtio-blk.c hw/virtio-blk.h hw/virtio-console.c hw/virtio-net.c hw/virtio-net.h hw/virtio-serial-bus.c hw/virtio-serial.h hw/virtio.c hw/vmware_vga.c hw/wm8750.c hw/xen_backend.c hw/xen_console.c hw/xen_devconfig.c hw/xen_disk.c hw/xen_nic.c hw/xenfb.c hw/xics.c hw/xilinx.h hw/xilinx_axienet.c hw/xilinx_ethlite.c hw/xilinx_intc.c hw/xilinx_timer.c hw/xilinx_uartlite.c hw/zaurus.c i386.ld input.c iohandler.c kvm-all.c libcacard/Makefile libcacard/cac.c libcacard/card_7816.c libcacard/event.c libcacard/vcard.c libcacard/vcard_emul_nss.c libcacard/vreader.c libcacard/vscclient.c linux-aio.c linux-user/elfload.c linux-user/main.c linux-user/signal.c linux-user/syscall.c linux-user/syscall_defs.h m68k-semi.c memory.c memory.h migration-exec.c migration-fd.c migration-tcp.c migration-unix.c migration.c mips.ld module.c monitor.c nbd.h net.c net.h net/queue.c net/slirp.c net/socket.c os-posix.c os-win32.c osdep.h pc-bios/bios.bin pflib.c posix-aio-compat.c ppc.ld ppc64.ld qapi/qapi-dealloc-visitor.c qapi/qmp-input-visitor.c qapi/qmp-output-visitor.c qapi/qmp-registry.c qbool.c qdict.c qemu-char.c qem u-char.h qemu-common.h qemu-config.c qemu-coroutine-lock.c qemu-coroutine.h qemu-ga.c qemu-img-cmds.hx qemu-img.c qemu-img.texi qemu-io.c qemu-malloc.c qemu-nbd.c qemu-option.c qemu-options.hx qemu-sockets.c qemu-thread-win32.c qemu-timer.c qemu-tool.c qerror.c qfloat.c qga/guest-agent-command-state.c qga/guest-agent-commands.c qint.c qlist.c qmp-commands.hx qstring.c readline.c roms/seabios rules.mak savevm.c scripts/checkpatch.pl scripts/qapi-commands.py scripts/simpletrace.py scripts/tracetool simpletrace.c simpletrace.h slirp/ip.h slirp/misc.c slirp/slirp.c slirp/slirp.h slirp/tcp.h slirp/tftp.c sparc.ld spice-qemu-char.c sysemu.h target-alpha/translate.c target-arm/helper.c target-cris/opcode-cris.h target-cris/translate.c target-i386/cpuid.c target-i386/helper.c target-i386/kvm.c target-i386/svm.h target-lm32/helper.c target-m68k/helper.c target-microblaze/cpu.h target-microblaze/translate.c target-mips/cpu.h target-mips/helper.c target-mips/helper.h target-mips/op_hel per.c target-mips/translate.c target-mips/translate_init.c target-ppc/cpu.h target-ppc/helper.c target-ppc/kvm_ppc.c target-ppc/translate.c target-ppc/translate_init.c target-s390x/cpu.h target-s390x/helper.c target-s390x/translate.c target-sh4/translate.c target-sparc/helper.c target-unicore32/helper.c target-unicore32/translate.c 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 test-qmp-commands.c test-visitor.c tests/qruncom.c tests/test-i386.c tests/test_path.c trace-events trace/control.c trace/control.h trace/default.c trace/simple.c trace/simple.h trace/stderr.c trace/stderr.h ui/cocoa.m ui/curses.c ui/keymaps.c ui/sdl.c ui/spice-core.c ui/spice-display.c ui/spice-input.c ui/vnc-auth-sasl.c ui/vnc-enc-hextile.c ui/vnc-enc-tight.c ui/vnc-enc-zlib.c ui/vnc-jobs-async.c ui/vnc-palette.c ui/vnc-tls.c ui/vnc.c usb-bsd.c usb-linux.c usb-redir.c vl.c x86_64.ld xen-all.c xen-mapcache .c

Gerd Hoffmann kraxel at kemper.freedesktop.org
Wed Sep 7 00:24:04 PDT 2011


 HACKING                         |    8 
 Makefile                        |   24 
 Makefile.objs                   |   41 
 Makefile.target                 |   18 
 a.out.h                         |    2 
 acl.c                           |   14 
 aio.c                           |    6 
 arch_init.c                     |    4 
 arm.ld                          |   12 
 async.c                         |    4 
 audio/alsaaudio.c               |   10 
 audio/audio.c                   |   30 
 audio/audio_template.h          |   20 
 audio/esdaudio.c                |    8 
 audio/mixeng.c                  |    2 
 audio/ossaudio.c                |    4 
 audio/paaudio.c                 |    8 
 audio/wavaudio.c                |    4 
 audio/wavcapture.c              |   12 
 audio/winwaveaudio.c            |   16 
 bitmap.h                        |    2 
 block-migration.c               |   40 
 block.c                         |  133 +
 block.h                         |   19 
 block/blkdebug.c                |    4 
 block/bochs.c                   |    4 
 block/cloop.c                   |    6 
 block/curl.c                    |   30 
 block/dmg.c                     |   14 
 block/nbd.c                     |   18 
 block/parallels.c               |    8 
 block/qcow.c                    |  414 +----
 block/qcow2-cache.c             |    8 
 block/qcow2-cluster.c           |   18 
 block/qcow2-refcount.c          |   56 
 block/qcow2-snapshot.c          |   55 
 block/qcow2.c                   |  450 ++---
 block/qcow2.h                   |    2 
 block/qed-check.c               |    4 
 block/qed-cluster.c             |    4 
 block/qed-gencb.c               |    4 
 block/qed-l2-cache.c            |    6 
 block/qed.c                     |    8 
 block/raw-win32.c               |    8 
 block/raw.c                     |    2 
 block/rbd.c                     |   26 
 block/sheepdog.c                |  202 +-
 block/vdi.c                     |   16 
 block/vmdk.c                    |   24 
 block/vpc.c                     |    8 
 block/vvfat.c                   |   46 
 block_int.h                     |    8 
 blockdev.c                      |   29 
 bsd-user/mmap.c                 |   16 
 bsd-user/syscall.c              |    4 
 bt-host.c                       |    2 
 bt-vhci.c                       |    2 
 buffered_file.c                 |    8 
 check-qdict.c                   |    6 
 check-qfloat.c                  |    2 
 check-qint.c                    |    2 
 check-qlist.c                   |    8 
 check-qstring.c                 |    4 
 compiler.h                      |    6 
 configure                       |   85 -
 console.c                       |   46 
 coroutine-gthread.c             |   10 
 coroutine-ucontext.c            |   16 
 coroutine-win32.c               |    4 
 cpu-all.h                       |    2 
 cpus.c                          |  173 --
 cris-dis.c                      |   12 
 cursor.c                        |    4 
 cutils.c                        |    8 
 device_tree.c                   |    4 
 disas.c                         |    2 
 dma-helpers.c                   |    6 
 docs/memory.txt                 |    8 
 docs/qapi-code-gen.txt          |    2 
 docs/tracing.txt                |   73 
 dyngen-exec.h                   |   14 
 error.c                         |   10 
 exec.c                          |   50 
 fpu/softfloat.c                 |   28 
 fpu/softfloat.h                 |    8 
 fsdev/file-op-9p.h              |    2 
 fsdev/qemu-fsdev.c              |    8 
 gdbstub.c                       |   18 
 hmp-commands.hx                 |   11 
 hppa.ld                         |   18 
 hw/9pfs/codir.c                 |  117 +
 hw/9pfs/cofile.c                |  163 ++
 hw/9pfs/cofs.c                  |  191 ++
 hw/9pfs/coxattr.c               |   84 +
 hw/9pfs/virtio-9p-coth.c        |  102 +
 hw/9pfs/virtio-9p-coth.h        |   96 +
 hw/9pfs/virtio-9p-device.c      |   15 
 hw/9pfs/virtio-9p-local.c       |    7 
 hw/9pfs/virtio-9p-xattr.c       |    4 
 hw/9pfs/virtio-9p.c             | 3034 +++++++++++++---------------------------
 hw/9pfs/virtio-9p.h             |  157 --
 hw/acpi.c                       |   12 
 hw/adb.c                        |    4 
 hw/adlib.c                      |    4 
 hw/apb_pci.c                    |   97 -
 hw/apic.c                       |   47 
 hw/apic.h                       |    6 
 hw/applesmc.c                   |    2 
 hw/arm11mpcore.c                |    7 
 hw/arm_gic.c                    |   22 
 hw/arm_sysctl.c                 |   76 -
 hw/arm_timer.c                  |   57 
 hw/armv7m.c                     |   24 
 hw/armv7m_nvic.c                |    3 
 hw/axis_dev88.c                 |    2 
 hw/baum.c                       |   45 
 hw/bitbang_i2c.c                |    2 
 hw/blizzard.c                   |    8 
 hw/bt-hci-csr.c                 |    2 
 hw/bt-hci.c                     |   20 
 hw/bt-hid.c                     |    4 
 hw/bt-l2cap.c                   |   18 
 hw/bt-sdp.c                     |   20 
 hw/bt.c                         |    6 
 hw/bt.h                         |  332 ++--
 hw/cbus.c                       |    6 
 hw/ccid-card-emulated.c         |   16 
 hw/ccid-card-passthru.c         |    6 
 hw/cirrus_vga.c                 |   20 
 hw/cris_pic_cpu.c               |    1 
 hw/debugcon.c                   |    2 
 hw/devices.h                    |    7 
 hw/dp8393x.c                    |    4 
 hw/ds1225y.c                    |    2 
 hw/e1000.c                      |    7 
 hw/e1000_hw.h                   |   17 
 hw/eepro100.c                   |    2 
 hw/eeprom93xx.c                 |    4 
 hw/elf_ops.h                    |   26 
 hw/escc.c                       |   73 
 hw/esp.c                        |   15 
 hw/etraxfs.h                    |   21 
 hw/etraxfs_dma.c                |    4 
 hw/etraxfs_eth.c                |   78 -
 hw/etraxfs_ser.c                |   12 
 hw/fdc.c                        |   18 
 hw/flash.h                      |    7 
 hw/fw_cfg.c                     |   19 
 hw/g364fb.c                     |  365 ++--
 hw/grlib_apbuart.c              |    2 
 hw/grlib_gptimer.c              |    2 
 hw/grlib_irqmp.c                |    2 
 hw/gt64xxx.c                    |   42 
 hw/gus.c                        |    2 
 hw/heathrow_pic.c               |    2 
 hw/hid.c                        |   76 -
 hw/hid.h                        |    1 
 hw/hpet_emul.h                  |    4 
 hw/hw.h                         |   20 
 hw/i8259.c                      |    2 
 hw/ide/ahci.c                   |   13 
 hw/ide/ahci.h                   |    7 
 hw/ide/atapi.c                  |   33 
 hw/ide/core.c                   |   27 
 hw/ide/internal.h               |    1 
 hw/ide/macio.c                  |   42 
 hw/ide/microdrive.c             |    4 
 hw/ide/mmio.c                   |    2 
 hw/ide/qdev.c                   |    4 
 hw/intel-hda.c                  |    4 
 hw/ioapic.c                     |    7 
 hw/irq.c                        |   10 
 hw/isa-bus.c                    |    6 
 hw/isa.h                        |    1 
 hw/isa_mmio.c                   |    2 
 hw/ivshmem.c                    |   14 
 hw/jazz_led.c                   |    2 
 hw/leon3.c                      |    2 
 hw/lm32_boards.c                |    4 
 hw/lm32_hwsetup.h               |    8 
 hw/lm32_juart.c                 |    2 
 hw/lm32_uart.c                  |    2 
 hw/loader.c                     |   48 
 hw/lsi53c895a.c                 |   16 
 hw/m48t59.c                     |   11 
 hw/mac_dbdma.c                  |    2 
 hw/mac_nvram.c                  |    4 
 hw/mcf5206.c                    |    4 
 hw/mcf5208.c                    |    2 
 hw/mcf_fec.c                    |    4 
 hw/mcf_intc.c                   |    2 
 hw/mcf_uart.c                   |    4 
 hw/microblaze_pic_cpu.c         |    2 
 hw/microblaze_pic_cpu.h         |    8 
 hw/milkymist-softusb.c          |  122 -
 hw/milkymist-tmu2.c             |    2 
 hw/milkymist-uart.c             |    2 
 hw/milkymist.c                  |    2 
 hw/mips.h                       |    5 
 hw/mips_fulong2e.c              |    4 
 hw/mips_jazz.c                  |   22 
 hw/mips_malta.c                 |   58 
 hw/mips_mipssim.c               |    4 
 hw/mips_r4k.c                   |    6 
 hw/mipsnet.c                    |    4 
 hw/mpcore.c                     |   37 
 hw/msix.c                       |   12 
 hw/msmouse.c                    |    6 
 hw/multiboot.c                  |   10 
 hw/nand.c                       |    2 
 hw/nseries.c                    |   59 
 hw/omap.h                       |   17 
 hw/omap1.c                      |   20 
 hw/omap2.c                      |   21 
 hw/omap_clk.c                   |    2 
 hw/omap_dma.c                   |    4 
 hw/omap_dss.c                   |    4 
 hw/omap_gpio.c                  |    4 
 hw/omap_gpmc.c                  |  744 +++++++--
 hw/omap_gptimer.c               |    2 
 hw/omap_i2c.c                   |    4 
 hw/omap_intc.c                  |    4 
 hw/omap_l4.c                    |   18 
 hw/omap_lcdc.c                  |    2 
 hw/omap_mmc.c                   |    4 
 hw/omap_sdrc.c                  |    2 
 hw/omap_spi.c                   |    2 
 hw/omap_synctimer.c             |    2 
 hw/omap_uart.c                  |   10 
 hw/onenand.c                    |  249 ++-
 hw/openpic.c                    |    6 
 hw/parallel.c                   |   34 
 hw/pc.c                         |   44 
 hw/pc.h                         |   18 
 hw/pc_piix.c                    |   25 
 hw/pci-stub.c                   |    2 
 hw/pci.c                        |   89 -
 hw/pci.h                        |    1 
 hw/pcie.c                       |   12 
 hw/pcie_aer.c                   |   13 
 hw/pcie_host.c                  |   98 -
 hw/pcie_host.h                  |   12 
 hw/pcie_port.c                  |    2 
 hw/pckbd.c                      |    2 
 hw/pcnet-pci.c                  |    4 
 hw/pcnet.h                      |    4 
 hw/petalogix_ml605_mmu.c        |    5 
 hw/petalogix_s3adsp1800_mmu.c   |    6 
 hw/pflash_cfi01.c               |    4 
 hw/pflash_cfi02.c               |    4 
 hw/piix_pci.c                   |  114 +
 hw/pl011.c                      |    2 
 hw/pl061.c                      |  181 +-
 hw/pl110.c                      |  115 +
 hw/pl110_template.h             |  102 +
 hw/ppc.c                        |    8 
 hw/ppc405.h                     |    9 
 hw/ppc405_boards.c              |   26 
 hw/ppc405_uc.c                  |  156 --
 hw/ppc440.c                     |   11 
 hw/ppc440_bamboo.c              |    4 
 hw/ppc4xx.h                     |    2 
 hw/ppc4xx_devs.c                |   54 
 hw/ppc4xx_pci.c                 |    4 
 hw/ppc_newworld.c               |   13 
 hw/ppc_oldworld.c               |   14 
 hw/ppc_prep.c                   |    6 
 hw/ppce500_mpc8544ds.c          |    8 
 hw/ppce500_pci.c                |   12 
 hw/prep_pci.c                   |    2 
 hw/ps2.c                        |    4 
 hw/ptimer.c                     |    2 
 hw/pxa2xx.c                     |   14 
 hw/pxa2xx_dma.c                 |    2 
 hw/pxa2xx_keypad.c              |    2 
 hw/pxa2xx_lcd.c                 |    4 
 hw/pxa2xx_mmci.c                |    2 
 hw/pxa2xx_pcmcia.c              |    2 
 hw/qdev-properties.c            |    8 
 hw/qdev.c                       |   27 
 hw/qxl-render.c                 |    4 
 hw/qxl.c                        |   23 
 hw/r2d.c                        |    6 
 hw/rc4030.c                     |    8 
 hw/realview.c                   |    2 
 hw/realview_gic.c               |   38 
 hw/rtl8139.c                    |   12 
 hw/s390-virtio.c                |    8 
 hw/scsi-bus.c                   |  571 ++++++-
 hw/scsi-defs.h                  |    4 
 hw/scsi-disk.c                  |  189 --
 hw/scsi-generic.c               |  164 --
 hw/scsi.h                       |   72 
 hw/sd.c                         |    6 
 hw/serial.c                     |   16 
 hw/sh7750.c                     |    2 
 hw/sh_intc.c                    |    2 
 hw/sh_pci.c                     |   63 
 hw/sh_serial.c                  |    4 
 hw/sh_timer.c                   |    4 
 hw/slavio_intctl.c              |    8 
 hw/slavio_misc.c                |    2 
 hw/slavio_timer.c               |    8 
 hw/sm501.c                      |    2 
 hw/smbios.c                     |   14 
 hw/smbios.h                     |   22 
 hw/smbus_eeprom.c               |    2 
 hw/soc_dma.c                    |    8 
 hw/spapr.c                      |   20 
 hw/spapr_vio.c                  |    2 
 hw/spapr_vscsi.c                |   97 -
 hw/spapr_vty.c                  |    4 
 hw/srp.h                        |   10 
 hw/stellaris.c                  |   74 
 hw/stellaris_enet.c             |    2 
 hw/stellaris_input.c            |    4 
 hw/strongarm.c                  |    6 
 hw/sun4m.c                      |   22 
 hw/sun4m_iommu.c                |    2 
 hw/sun4u.c                      |   14 
 hw/syborg_fb.c                  |   15 
 hw/syborg_interrupt.c           |    2 
 hw/syborg_keyboard.c            |    2 
 hw/syborg_pointer.c             |    2 
 hw/syborg_serial.c              |    6 
 hw/sysbus.c                     |   18 
 hw/sysbus.h                     |    6 
 hw/tc58128.c                    |    2 
 hw/tc6393xb.c                   |    2 
 hw/tcx.c                        |    4 
 hw/tsc2005.c                    |    2 
 hw/tsc210x.c                    |    4 
 hw/tusb6010.c                   |  131 +
 hw/usb-bus.c                    |    4 
 hw/usb-ccid.c                   |   18 
 hw/usb-desc.c                   |    6 
 hw/usb-ehci.c                   |    4 
 hw/usb-hid.c                    |   58 
 hw/usb-msd.c                    |    4 
 hw/usb-musb.c                   |    2 
 hw/usb-net.c                    |    6 
 hw/usb-serial.c                 |   18 
 hw/usb-uhci.c                   |    4 
 hw/usb.h                        |    3 
 hw/versatile_pci.c              |   92 -
 hw/versatilepb.c                |   13 
 hw/vexpress.c                   |    2 
 hw/vga-isa-mm.c                 |   21 
 hw/vga-isa.c                    |    5 
 hw/vga-pci.c                    |    4 
 hw/vga.c                        |   75 
 hw/vga_int.h                    |    9 
 hw/vhost.c                      |   90 -
 hw/vhost.h                      |    2 
 hw/vhost_net.c                  |   22 
 hw/virtex_ml507.c               |    6 
 hw/virtio-balloon.h             |    2 
 hw/virtio-blk.c                 |   24 
 hw/virtio-blk.h                 |    2 
 hw/virtio-console.c             |    6 
 hw/virtio-net.c                 |    8 
 hw/virtio-net.h                 |    2 
 hw/virtio-serial-bus.c          |   22 
 hw/virtio-serial.h              |    2 
 hw/virtio.c                     |   12 
 hw/vmware_vga.c                 |  257 ---
 hw/wm8750.c                     |    2 
 hw/xen_backend.c                |   18 
 hw/xen_console.c                |   10 
 hw/xen_devconfig.c              |    4 
 hw/xen_disk.c                   |   29 
 hw/xen_nic.c                    |    6 
 hw/xenfb.c                      |   10 
 hw/xics.c                       |    8 
 hw/xilinx.h                     |    5 
 hw/xilinx_axienet.c             |    6 
 hw/xilinx_ethlite.c             |   27 
 hw/xilinx_intc.c                |   29 
 hw/xilinx_timer.c               |   33 
 hw/xilinx_uartlite.c            |   34 
 hw/zaurus.c                     |    2 
 i386.ld                         |    8 
 input.c                         |   12 
 iohandler.c                     |   65 
 kvm-all.c                       |   22 
 libcacard/Makefile              |   16 
 libcacard/cac.c                 |   16 
 libcacard/card_7816.c           |   28 
 libcacard/event.c               |    4 
 libcacard/vcard.c               |   20 
 libcacard/vcard_emul_nss.c      |   48 
 libcacard/vreader.c             |   14 
 libcacard/vscclient.c           |    4 
 linux-aio.c                     |    4 
 linux-user/elfload.c            |   26 
 linux-user/main.c               |    9 
 linux-user/signal.c             |   29 
 linux-user/syscall.c            |    8 
 linux-user/syscall_defs.h       |   16 
 m68k-semi.c                     |    4 
 memory.c                        |  223 ++
 memory.h                        |   36 
 migration-exec.c                |    4 
 migration-fd.c                  |    4 
 migration-tcp.c                 |    4 
 migration-unix.c                |    4 
 migration.c                     |    2 
 mips.ld                         |   18 
 module.c                        |    2 
 monitor.c                       |  104 -
 nbd.h                           |    4 
 net.c                           |   24 
 net.h                           |    5 
 net/queue.c                     |   14 
 net/slirp.c                     |   26 
 net/socket.c                    |    6 
 os-posix.c                      |    4 
 os-win32.c                      |   10 
 osdep.h                         |    2 
 pc-bios/bios.bin                |binary
 pflib.c                         |   10 
 posix-aio-compat.c              |   46 
 ppc.ld                          |   18 
 ppc64.ld                        |    6 
 qapi/qapi-dealloc-visitor.c     |   14 
 qapi/qmp-input-visitor.c        |   12 
 qapi/qmp-output-visitor.c       |   10 
 qapi/qmp-registry.c             |    2 
 qbool.c                         |    4 
 qdict.c                         |   12 
 qemu-char.c                     |  156 --
 qemu-char.h                     |  151 +
 qemu-common.h                   |    7 
 qemu-config.c                   |   10 
 qemu-coroutine-lock.c           |   44 
 qemu-coroutine.h                |   32 
 qemu-ga.c                       |    6 
 qemu-img-cmds.hx                |    4 
 qemu-img.c                      |  122 +
 qemu-img.texi                   |    7 
 qemu-io.c                       |   12 
 qemu-malloc.c                   |   98 -
 qemu-nbd.c                      |    4 
 qemu-option.c                   |   28 
 qemu-options.hx                 |   41 
 qemu-sockets.c                  |    4 
 qemu-thread-win32.c             |    2 
 qemu-timer.c                    |   63 
 qemu-tool.c                     |    4 
 qerror.c                        |    4 
 qfloat.c                        |    4 
 qga/guest-agent-command-state.c |    4 
 qga/guest-agent-commands.c      |   32 
 qint.c                          |    4 
 qlist.c                         |   10 
 qmp-commands.hx                 |   24 
 qstring.c                       |   10 
 readline.c                      |    8 
 roms/seabios                    |    2 
 rules.mak                       |   10 
 savevm.c                        |   58 
 scripts/checkpatch.pl           |    2 
 scripts/qapi-commands.py        |    2 
 scripts/simpletrace.py          |    4 
 scripts/tracetool               |  116 -
 simpletrace.c                   |  355 ----
 simpletrace.h                   |   48 
 slirp/ip.h                      |   24 
 slirp/misc.c                    |    2 
 slirp/slirp.c                   |   14 
 slirp/slirp.h                   |    2 
 slirp/tcp.h                     |    4 
 slirp/tftp.c                    |    6 
 sparc.ld                        |   12 
 spice-qemu-char.c               |   12 
 sysemu.h                        |    2 
 target-alpha/translate.c        |    2 
 target-arm/helper.c             |    2 
 target-cris/opcode-cris.h       |   12 
 target-cris/translate.c         |    2 
 target-i386/cpuid.c             |    2 
 target-i386/helper.c            |    4 
 target-i386/kvm.c               |   27 
 target-i386/svm.h               |    8 
 target-lm32/helper.c            |    2 
 target-m68k/helper.c            |    4 
 target-microblaze/cpu.h         |    1 
 target-microblaze/translate.c   |   13 
 target-mips/cpu.h               |   55 
 target-mips/helper.c            |    6 
 target-mips/helper.h            |   10 
 target-mips/op_helper.c         |  606 ++++++-
 target-mips/translate.c         |  114 +
 target-mips/translate_init.c    |    8 
 target-ppc/cpu.h                |   17 
 target-ppc/helper.c             |   14 
 target-ppc/kvm_ppc.c            |    2 
 target-ppc/translate.c          |   78 -
 target-ppc/translate_init.c     |    6 
 target-s390x/cpu.h              |    2 
 target-s390x/helper.c           |    2 
 target-s390x/translate.c        |    2 
 target-sh4/translate.c          |    2 
 target-sparc/helper.c           |    4 
 target-unicore32/helper.c       |    2 
 target-unicore32/translate.c    |    2 
 tcg/arm/tcg-target.h            |   30 
 tcg/hppa/tcg-target.c           |    2 
 tcg/hppa/tcg-target.h           |   29 
 tcg/i386/tcg-target.h           |   68 
 tcg/ia64/tcg-target.c           |    4 
 tcg/ia64/tcg-target.h           |   66 
 tcg/mips/tcg-target.h           |   31 
 tcg/optimize.c                  |  273 ---
 tcg/ppc/tcg-target.c            |   32 
 tcg/ppc/tcg-target.h            |   31 
 tcg/ppc64/tcg-target.c          |   13 
 tcg/ppc64/tcg-target.h          |   68 
 tcg/s390/tcg-target.h           |   68 
 tcg/sparc/tcg-target.h          |   68 
 tcg/tcg-op.h                    |  946 +++++-------
 tcg/tcg-opc.h                   |  242 +--
 tcg/tcg.c                       |   29 
 tcg/tcg.h                       |   59 
 test-qmp-commands.c             |    6 
 test-visitor.c                  |   12 
 tests/qruncom.c                 |    8 
 tests/test-i386.c               |   10 
 tests/test_path.c               |    2 
 trace-events                    |  637 ++++----
 trace/control.c                 |   42 
 trace/control.h                 |   41 
 trace/default.c                 |   41 
 trace/simple.c                  |  358 ++++
 trace/simple.h                  |   38 
 trace/stderr.c                  |   37 
 trace/stderr.h                  |   11 
 ui/cocoa.m                      |    6 
 ui/curses.c                     |    2 
 ui/keymaps.c                    |    6 
 ui/sdl.c                        |   24 
 ui/spice-core.c                 |   38 
 ui/spice-display.c              |   12 
 ui/spice-input.c                |    4 
 ui/vnc-auth-sasl.c              |    2 
 ui/vnc-enc-hextile.c            |    4 
 ui/vnc-enc-tight.c              |   12 
 ui/vnc-enc-zlib.c               |    4 
 ui/vnc-jobs-async.c             |   14 
 ui/vnc-palette.c                |    4 
 ui/vnc-tls.c                    |   18 
 ui/vnc.c                        |   54 
 usb-bsd.c                       |    2 
 usb-linux.c                     |   14 
 usb-redir.c                     |   12 
 vl.c                            |  220 ++
 x86_64.ld                       |   14 
 xen-all.c                       |   14 
 xen-mapcache.c                  |   28 
 559 files changed, 11614 insertions(+), 9858 deletions(-)

New commits:
commit 344eecf6995f4a0ad1d887cec922f6806f91a3f8
Author: Edgar E. Iglesias <edgar.iglesias at gmail.com>
Date:   Tue Aug 30 00:44:28 2011 +0200

    mips: Support the MT TCStatus IXMT irq disable flag
    
    Signed-off-by: Edgar E. Iglesias <edgar.iglesias at gmail.com>

diff --git a/target-mips/cpu.h b/target-mips/cpu.h
index f6f16a3..79e2558 100644
--- a/target-mips/cpu.h
+++ b/target-mips/cpu.h
@@ -537,6 +537,10 @@ static inline int cpu_mips_hw_interrupts_pending(CPUState *env)
     if (!(env->CP0_Status & (1 << CP0St_IE)) ||
         (env->CP0_Status & (1 << CP0St_EXL)) ||
         (env->CP0_Status & (1 << CP0St_ERL)) ||
+        /* Note that the TCStatus IXMT field is initialized to zero,
+           and only MT capable cores can set it to one. So we don't
+           need to check for MT capabilities here.  */
+        (env->active_tc.CP0_TCStatus & (1 << CP0TCSt_IXMT)) ||
         (env->hflags & MIPS_HFLAG_DM)) {
         /* Interrupts are disabled */
         return 0;
commit c4cb2578b5d68716b6644edd69d25a1457607053
Author: Edgar E. Iglesias <edgar.iglesias at gmail.com>
Date:   Mon Aug 29 23:07:41 2011 +0200

    mips: Add SMP support to the Malta board
    
    No change to the CPU kinds, so SMP will only work if
    manually changing the cpu to 34Kf:
    
    -cpu 34Kf -smp 2
    
    Signed-off-by: Edgar E. Iglesias <edgar.iglesias at gmail.com>

diff --git a/hw/mips_malta.c b/hw/mips_malta.c
index 86a8ba0..a0adb56 100644
--- a/hw/mips_malta.c
+++ b/hw/mips_malta.c
@@ -732,6 +732,12 @@ static int64_t load_kernel (void)
     return kernel_entry;
 }
 
+static void malta_mips_config(CPUState *env)
+{
+    env->mvp->CP0_MVPConf0 |= ((smp_cpus - 1) << CP0MVPC0_PVPE) |
+                         ((smp_cpus * env->nr_threads - 1) << CP0MVPC0_PTC);
+}
+
 static void main_cpu_reset(void *opaque)
 {
     CPUState *env = opaque;
@@ -743,6 +749,8 @@ static void main_cpu_reset(void *opaque)
     if (loaderparams.kernel_filename) {
         env->CP0_Status &= ~((1 << CP0St_BEV) | (1 << CP0St_ERL));
     }
+
+    malta_mips_config(env);
 }
 
 static void cpu_request_exit(void *opaque, int irq, int level)
@@ -796,12 +804,19 @@ void mips_malta_init (ram_addr_t ram_size,
         cpu_model = "24Kf";
 #endif
     }
-    env = cpu_init(cpu_model);
-    if (!env) {
-        fprintf(stderr, "Unable to find CPU definition\n");
-        exit(1);
+
+    for (i = 0; i < smp_cpus; i++) {
+        env = cpu_init(cpu_model);
+        if (!env) {
+            fprintf(stderr, "Unable to find CPU definition\n");
+            exit(1);
+        }
+        /* Init internal devices */
+        cpu_mips_irq_init_cpu(env);
+        cpu_mips_clock_init(env);
+        qemu_register_reset(main_cpu_reset, env);
     }
-    qemu_register_reset(main_cpu_reset, env);
+    env = first_cpu;
 
     /* allocate RAM */
     if (ram_size > (256 << 20)) {
@@ -955,6 +970,7 @@ static QEMUMachine mips_malta_machine = {
     .name = "malta",
     .desc = "MIPS Malta Core LV",
     .init = mips_malta_init,
+    .max_cpus = 16,
     .is_default = 1,
 };
 
commit f249412c749496714537089959f375a89d3be687
Author: Edgar E. Iglesias <edgar.iglesias at gmail.com>
Date:   Mon Aug 29 23:07:40 2011 +0200

    mips: Add MT halting and waking of VPEs
    
    + some partial support for TC's.
    
    Signed-off-by: Edgar E. Iglesias <edgar.iglesias at gmail.com>

diff --git a/target-mips/cpu.h b/target-mips/cpu.h
index c5f70fa..f6f16a3 100644
--- a/target-mips/cpu.h
+++ b/target-mips/cpu.h
@@ -618,6 +618,14 @@ enum {
 /* Dummy exception for conditional stores.  */
 #define EXCP_SC 0x100
 
+/*
+ * This is an interrnally generated WAKE request line.
+ * It is driven by the CPU itself. Raised when the MT
+ * block wants to wake a VPE from an inactive state and
+ * cleared when VPE goes from active to inactive.
+ */
+#define CPU_INTERRUPT_WAKE CPU_INTERRUPT_TGT_INT_0
+
 int cpu_mips_exec(CPUMIPSState *s);
 CPUMIPSState *cpu_mips_init(const char *cpu_model);
 //~ uint32_t cpu_mips_get_clock (void);
@@ -658,6 +666,37 @@ static inline void cpu_set_tls(CPUState *env, target_ulong newtls)
     env->tls_value = newtls;
 }
 
+static inline int mips_vpe_active(CPUState *env)
+{
+    int active = 1;
+
+    /* Check that the VPE is enabled.  */
+    if (!(env->mvp->CP0_MVPControl & (1 << CP0MVPCo_EVP))) {
+        active = 0;
+    }
+    /* Check that the VPE is actived.  */
+    if (!(env->CP0_VPEConf0 & (1 << CP0VPEC0_VPA))) {
+        active = 0;
+    }
+
+    /* Now verify that there are active thread contexts in the VPE.
+
+       This assumes the CPU model will internally reschedule threads
+       if the active one goes to sleep. If there are no threads available
+       the active one will be in a sleeping state, and we can turn off
+       the entire VPE.  */
+    if (!(env->active_tc.CP0_TCStatus & (1 << CP0TCSt_A))) {
+        /* TC is not activated.  */
+        active = 0;
+    }
+    if (env->active_tc.CP0_TCHalt & 1) {
+        /* TC is in halt state.  */
+        active = 0;
+    }
+
+    return active;
+}
+
 static inline int cpu_has_work(CPUState *env)
 {
     int has_work = 0;
@@ -670,6 +709,18 @@ static inline int cpu_has_work(CPUState *env)
         has_work = 1;
     }
 
+    /* MIPS-MT has the ability to halt the CPU.  */
+    if (env->CP0_Config3 & (1 << CP0C3_MT)) {
+        /* The QEMU model will issue an _WAKE request whenever the CPUs
+           should be woken up.  */
+        if (env->interrupt_request & CPU_INTERRUPT_WAKE) {
+            has_work = 1;
+        }
+
+        if (!mips_vpe_active(env)) {
+            has_work = 0;
+        }
+    }
     return has_work;
 }
 
diff --git a/target-mips/op_helper.c b/target-mips/op_helper.c
index 03a4f18..96e40c6 100644
--- a/target-mips/op_helper.c
+++ b/target-mips/op_helper.c
@@ -749,6 +749,46 @@ void helper_sdm (target_ulong addr, target_ulong reglist, uint32_t mem_idx)
 #endif
 
 #ifndef CONFIG_USER_ONLY
+/* SMP helpers.  */
+static int mips_vpe_is_wfi(CPUState *c)
+{
+    /* If the VPE is halted but otherwise active, it means it's waiting for
+       an interrupt.  */
+    return c->halted && mips_vpe_active(c);
+}
+
+static inline void mips_vpe_wake(CPUState *c)
+{
+    /* Dont set ->halted = 0 directly, let it be done via cpu_has_work
+       because there might be other conditions that state that c should
+       be sleeping.  */
+    cpu_interrupt(c, CPU_INTERRUPT_WAKE);
+}
+
+static inline void mips_vpe_sleep(CPUState *c)
+{
+    /* The VPE was shut off, really go to bed.
+       Reset any old _WAKE requests.  */
+    c->halted = 1;
+    cpu_reset_interrupt(c, CPU_INTERRUPT_WAKE);
+}
+
+static inline void mips_tc_wake(CPUState *c, int tc)
+{
+    /* FIXME: TC reschedule.  */
+    if (mips_vpe_active(c) && !mips_vpe_is_wfi(c)) {
+        mips_vpe_wake(c);
+    }
+}
+
+static inline void mips_tc_sleep(CPUState *c, int tc)
+{
+    /* FIXME: TC reschedule.  */
+    if (!mips_vpe_active(c)) {
+        mips_vpe_sleep(c);
+    }
+}
+
 /* tc should point to an int with the value of the global TC index.
    This function will transform it into a local index within the
    returned CPUState.
@@ -1340,6 +1380,11 @@ void helper_mtc0_tchalt (target_ulong arg1)
     env->active_tc.CP0_TCHalt = arg1 & 0x1;
 
     // TODO: Halt TC / Restart (if allocated+active) TC.
+    if (env->active_tc.CP0_TCHalt & 1) {
+        mips_tc_sleep(env, env->current_tc);
+    } else {
+        mips_tc_wake(env, env->current_tc);
+    }
 }
 
 void helper_mttc0_tchalt (target_ulong arg1)
@@ -1353,6 +1398,12 @@ void helper_mttc0_tchalt (target_ulong arg1)
         other->active_tc.CP0_TCHalt = arg1;
     else
         other->tcs[other_tc].CP0_TCHalt = arg1;
+
+    if (arg1 & 1) {
+        mips_tc_sleep(other, other_tc);
+    } else {
+        mips_tc_wake(other, other_tc);
+    }
 }
 
 void helper_mtc0_tccontext (target_ulong arg1)
@@ -1858,14 +1909,36 @@ target_ulong helper_emt(void)
 
 target_ulong helper_dvpe(void)
 {
-    // TODO
-    return 0;
+    CPUState *other_cpu = first_cpu;
+    target_ulong prev = env->mvp->CP0_MVPControl;
+
+    do {
+        /* Turn off all VPEs except the one executing the dvpe.  */
+        if (other_cpu != env) {
+            other_cpu->mvp->CP0_MVPControl &= ~(1 << CP0MVPCo_EVP);
+            mips_vpe_sleep(other_cpu);
+        }
+        other_cpu = other_cpu->next_cpu;
+    } while (other_cpu);
+    return prev;
 }
 
 target_ulong helper_evpe(void)
 {
-    // TODO
-    return 0;
+    CPUState *other_cpu = first_cpu;
+    target_ulong prev = env->mvp->CP0_MVPControl;
+
+    do {
+        if (other_cpu != env
+           /* If the VPE is WFI, dont distrub it's sleep.  */
+           && !mips_vpe_is_wfi(other_cpu)) {
+            /* Enable the VPE.  */
+            other_cpu->mvp->CP0_MVPControl |= (1 << CP0MVPCo_EVP);
+            mips_vpe_wake(other_cpu); /* And wake it up.  */
+        }
+        other_cpu = other_cpu->next_cpu;
+    } while (other_cpu);
+    return prev;
 }
 #endif /* !CONFIG_USER_ONLY */
 
@@ -2213,6 +2286,7 @@ void helper_pmon (int function)
 void helper_wait (void)
 {
     env->halted = 1;
+    cpu_reset_interrupt(env, CPU_INTERRUPT_WAKE);
     helper_raise_exception(EXCP_HLT);
 }
 
commit 9e56e7562485c3f6f84c40cdee558168ea193a25
Author: Edgar E. Iglesias <edgar.iglesias at gmail.com>
Date:   Mon Aug 29 23:07:39 2011 +0200

    mips: Initialize MT state at reset
    
    Only TC0 on VPE0 is active after reset. All other VPEs and
    TCs start in sleep.
    
    Signed-off-by: Edgar E. Iglesias <edgar.iglesias at gmail.com>

diff --git a/target-mips/translate.c b/target-mips/translate.c
index 1bd1d62..d5b1c76 100644
--- a/target-mips/translate.c
+++ b/target-mips/translate.c
@@ -12813,6 +12813,32 @@ void cpu_reset (CPUMIPSState *env)
     /* Count register increments in debug mode, EJTAG version 1 */
     env->CP0_Debug = (1 << CP0DB_CNT) | (0x1 << CP0DB_VER);
     env->hflags = MIPS_HFLAG_CP0;
+
+    if (env->CP0_Config3 & (1 << CP0C3_MT)) {
+        int i;
+
+        /* Only TC0 on VPE 0 starts as active.  */
+        for (i = 0; i < ARRAY_SIZE(env->tcs); i++) {
+            env->tcs[i].CP0_TCBind = env->cpu_index << CP0TCBd_CurVPE;
+            env->tcs[i].CP0_TCHalt = 1;
+        }
+        env->active_tc.CP0_TCHalt = 1;
+        env->halted = 1;
+
+        if (!env->cpu_index) {
+            /* VPE0 starts up enabled.  */
+            env->mvp->CP0_MVPControl |= (1 << CP0MVPCo_EVP);
+            env->CP0_VPEConf0 |= (1 << CP0VPEC0_MVP) | (1 << CP0VPEC0_VPA);
+
+            /* TC0 starts up unhalted.  */
+            env->halted = 0;
+            env->active_tc.CP0_TCHalt = 0;
+            env->tcs[0].CP0_TCHalt = 0;
+            /* With thread 0 active.  */
+            env->active_tc.CP0_TCStatus = (1 << CP0TCSt_A);
+            env->tcs[0].CP0_TCStatus = (1 << CP0TCSt_A);
+        }
+    }
 #endif
 #if defined(TARGET_MIPS64)
     if (env->cpu_model->insn_flags & ISA_MIPS3) {
commit 1dab005ae2ff3f9b83e02f25aa77c5e262404505
Author: Edgar E. Iglesias <edgar.iglesias at gmail.com>
Date:   Mon Aug 29 23:07:38 2011 +0200

    mips: Default to using one VPE and one TC.
    
    Boards can override the setup if needed.
    
    Signed-off-by: Edgar E. Iglesias <edgar.iglesias at gmail.com>

diff --git a/target-mips/translate_init.c b/target-mips/translate_init.c
index fe6b1fd..c39138f 100644
--- a/target-mips/translate_init.c
+++ b/target-mips/translate_init.c
@@ -580,7 +580,7 @@ static void mvp_init (CPUMIPSState *env, const mips_def_t *def)
 //                             (1 << CP0MVPC0_TCA) | (0x1 << CP0MVPC0_PVPE) |
 //                             (0x04 << CP0MVPC0_PTC);
                              (1 << CP0MVPC0_TCA) | (0x0 << CP0MVPC0_PVPE) |
-                             (0x04 << CP0MVPC0_PTC);
+                             (0x00 << CP0MVPC0_PTC);
 #if !defined(CONFIG_USER_ONLY)
     /* Usermode has no TLB support */
     env->mvp->CP0_MVPConf0 |= (env->tlb->nb_tlb << CP0MVPC0_PTLBE);
commit ded400888106616e1d057d0efc8516148083f6c3
Author: Edgar E. Iglesias <edgar.iglesias at gmail.com>
Date:   Mon Aug 29 23:07:37 2011 +0200

    mips: Enable VInt interrupt mode for the 34Kf
    
    Signed-off-by: Edgar E. Iglesias <edgar.iglesias at gmail.com>

diff --git a/target-mips/translate_init.c b/target-mips/translate_init.c
index 5bb4215..fe6b1fd 100644
--- a/target-mips/translate_init.c
+++ b/target-mips/translate_init.c
@@ -274,7 +274,7 @@ 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 | (0 << CP0C3_VInt) | (1 << CP0C3_MT),
+        .CP0_Config3 = MIPS_CONFIG3 | (1 << CP0C3_VInt) | (1 << CP0C3_MT),
         .CP0_LLAddr_rw_bitmask = 0,
         .CP0_LLAddr_shift = 0,
         .SYNCI_Step = 32,
commit e428097341041ea7a12069a848ef3c92dff13b39
Author: Edgar E. Iglesias <edgar.iglesias at gmail.com>
Date:   Mon Aug 29 23:07:36 2011 +0200

    mips: Correct VInt vector generation
    
    1. The pending need to pass the Status IM gating.
    2. The priority is from seven (highest prio) down to zero.
       QEMU was doing the opposite.
    
    Signed-off-by: Edgar E. Iglesias <edgar.iglesias at gmail.com>

diff --git a/target-mips/helper.c b/target-mips/helper.c
index 024caa2..1c58e0c 100644
--- a/target-mips/helper.c
+++ b/target-mips/helper.c
@@ -482,18 +482,18 @@ void do_interrupt (CPUState *env)
             unsigned int vector;
             unsigned int pending = (env->CP0_Cause & CP0Ca_IP_mask) >> 8;
 
+            pending &= env->CP0_Status >> 8;
             /* Compute the Vector Spacing.  */
             spacing = (env->CP0_IntCtl >> CP0IntCtl_VS) & ((1 << 6) - 1);
             spacing <<= 5;
 
             if (env->CP0_Config3 & (1 << CP0C3_VInt)) {
                 /* For VInt mode, the MIPS computes the vector internally.  */
-                for (vector = 0; vector < 8; vector++) {
-                    if (pending & 1) {
+                for (vector = 7; vector > 0; vector--) {
+                    if (pending & (1 << vector)) {
                         /* Found it.  */
                         break;
                     }
-                    pending >>= 1;
                 }
             } else {
                 /* For VEIC mode, the external interrupt controller feeds the
commit bc45a67a22f18146e638a6e550f282f688abdd7f
Author: Edgar E. Iglesias <edgar.iglesias at gmail.com>
Date:   Mon Aug 29 23:07:35 2011 +0200

    mips: Correct IntCtl write mask for VInt
    
    Signed-off-by: Edgar E. Iglesias <edgar.iglesias at gmail.com>

diff --git a/target-mips/op_helper.c b/target-mips/op_helper.c
index e7868bf..03a4f18 100644
--- a/target-mips/op_helper.c
+++ b/target-mips/op_helper.c
@@ -1542,7 +1542,7 @@ void helper_mttc0_status(target_ulong arg1)
 void helper_mtc0_intctl (target_ulong arg1)
 {
     /* vectored interrupts not implemented, no performance counters. */
-    env->CP0_IntCtl = (env->CP0_IntCtl & ~0x000002e0) | (arg1 & 0x000002e0);
+    env->CP0_IntCtl = (env->CP0_IntCtl & ~0x000003e0) | (arg1 & 0x000003e0);
 }
 
 void helper_mtc0_srsctl (target_ulong arg1)
commit 5a25ce9487430e504430ac77eede44a43a29fc71
Author: Edgar E. Iglesias <edgar.iglesias at gmail.com>
Date:   Mon Aug 29 23:07:34 2011 +0200

    mips: Hook in more reg accesses via mttr/mftr
    
    Signed-off-by: Edgar E. Iglesias <edgar.iglesias at gmail.com>

diff --git a/target-mips/helper.h b/target-mips/helper.h
index 297ab64..442f684 100644
--- a/target-mips/helper.h
+++ b/target-mips/helper.h
@@ -52,6 +52,8 @@ DEF_HELPER_2(msachiu, tl, tl, tl)
 DEF_HELPER_0(mfc0_mvpcontrol, tl)
 DEF_HELPER_0(mfc0_mvpconf0, tl)
 DEF_HELPER_0(mfc0_mvpconf1, tl)
+DEF_HELPER_0(mftc0_vpecontrol, tl)
+DEF_HELPER_0(mftc0_vpeconf0, tl)
 DEF_HELPER_0(mfc0_random, tl)
 DEF_HELPER_0(mfc0_tcstatus, tl)
 DEF_HELPER_0(mftc0_tcstatus, tl)
@@ -70,6 +72,10 @@ DEF_HELPER_0(mftc0_tcschefback, tl)
 DEF_HELPER_0(mfc0_count, tl)
 DEF_HELPER_0(mftc0_entryhi, tl)
 DEF_HELPER_0(mftc0_status, tl)
+DEF_HELPER_0(mftc0_cause, tl)
+DEF_HELPER_0(mftc0_epc, tl)
+DEF_HELPER_0(mftc0_ebase, tl)
+DEF_HELPER_1(mftc0_configx, tl, tl)
 DEF_HELPER_0(mfc0_lladdr, tl)
 DEF_HELPER_1(mfc0_watchlo, tl, i32)
 DEF_HELPER_1(mfc0_watchhi, tl, i32)
@@ -88,7 +94,9 @@ DEF_HELPER_1(dmfc0_watchlo, tl, i32)
 DEF_HELPER_1(mtc0_index, void, tl)
 DEF_HELPER_1(mtc0_mvpcontrol, void, tl)
 DEF_HELPER_1(mtc0_vpecontrol, void, tl)
+DEF_HELPER_1(mttc0_vpecontrol, void, tl)
 DEF_HELPER_1(mtc0_vpeconf0, void, tl)
+DEF_HELPER_1(mttc0_vpeconf0, void, tl)
 DEF_HELPER_1(mtc0_vpeconf1, void, tl)
 DEF_HELPER_1(mtc0_yqmask, void, tl)
 DEF_HELPER_1(mtc0_vpeopt, void, tl)
@@ -127,7 +135,9 @@ DEF_HELPER_1(mttc0_status, void, tl)
 DEF_HELPER_1(mtc0_intctl, void, tl)
 DEF_HELPER_1(mtc0_srsctl, void, tl)
 DEF_HELPER_1(mtc0_cause, void, tl)
+DEF_HELPER_1(mttc0_cause, void, tl)
 DEF_HELPER_1(mtc0_ebase, void, tl)
+DEF_HELPER_1(mttc0_ebase, void, tl)
 DEF_HELPER_1(mtc0_config0, void, tl)
 DEF_HELPER_1(mtc0_config2, void, tl)
 DEF_HELPER_1(mtc0_lladdr, void, tl)
diff --git a/target-mips/op_helper.c b/target-mips/op_helper.c
index 47774fe..e7868bf 100644
--- a/target-mips/op_helper.c
+++ b/target-mips/op_helper.c
@@ -1012,6 +1012,21 @@ target_ulong helper_mftc0_entryhi(void)
     return other->CP0_EntryHi;
 }
 
+target_ulong helper_mftc0_cause(void)
+{
+    int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC);
+    int32_t tccause;
+    CPUState *other = mips_cpu_map_tc(&other_tc);
+
+    if (other_tc == other->current_tc) {
+        tccause = other->CP0_Cause;
+    } else {
+        tccause = other->CP0_Cause;
+    }
+
+    return tccause;
+}
+
 target_ulong helper_mftc0_status(void)
 {
     int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC);
@@ -1143,6 +1158,38 @@ void helper_mtc0_vpecontrol (target_ulong arg1)
     env->CP0_VPEControl = newval;
 }
 
+void helper_mttc0_vpecontrol(target_ulong arg1)
+{
+    int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC);
+    CPUState *other = mips_cpu_map_tc(&other_tc);
+    uint32_t mask;
+    uint32_t newval;
+
+    mask = (1 << CP0VPECo_YSI) | (1 << CP0VPECo_GSI) |
+           (1 << CP0VPECo_TE) | (0xff << CP0VPECo_TargTC);
+    newval = (other->CP0_VPEControl & ~mask) | (arg1 & mask);
+
+    /* TODO: Enable/disable TCs.  */
+
+    other->CP0_VPEControl = newval;
+}
+
+target_ulong helper_mftc0_vpecontrol(void)
+{
+    int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC);
+    CPUState *other = mips_cpu_map_tc(&other_tc);
+    /* FIXME: Mask away return zero on read bits.  */
+    return other->CP0_VPEControl;
+}
+
+target_ulong helper_mftc0_vpeconf0(void)
+{
+    int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC);
+    CPUState *other = mips_cpu_map_tc(&other_tc);
+
+    return other->CP0_VPEConf0;
+}
+
 void helper_mtc0_vpeconf0 (target_ulong arg1)
 {
     uint32_t mask = 0;
@@ -1160,6 +1207,20 @@ void helper_mtc0_vpeconf0 (target_ulong arg1)
     env->CP0_VPEConf0 = newval;
 }
 
+void helper_mttc0_vpeconf0(target_ulong arg1)
+{
+    int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC);
+    CPUState *other = mips_cpu_map_tc(&other_tc);
+    uint32_t mask = 0;
+    uint32_t newval;
+
+    mask |= (1 << CP0VPEC0_MVP) | (1 << CP0VPEC0_VPA);
+    newval = (other->CP0_VPEConf0 & ~mask) | (arg1 & mask);
+
+    /* TODO: TC exclusive handling due to ERL/EXL.  */
+    other->CP0_VPEConf0 = newval;
+}
+
 void helper_mtc0_vpeconf1 (target_ulong arg1)
 {
     uint32_t mask = 0;
@@ -1490,38 +1551,95 @@ void helper_mtc0_srsctl (target_ulong arg1)
     env->CP0_SRSCtl = (env->CP0_SRSCtl & ~mask) | (arg1 & mask);
 }
 
-void helper_mtc0_cause (target_ulong arg1)
+static void mtc0_cause(CPUState *cpu, target_ulong arg1)
 {
     uint32_t mask = 0x00C00300;
-    uint32_t old = env->CP0_Cause;
+    uint32_t old = cpu->CP0_Cause;
     int i;
 
-    if (env->insn_flags & ISA_MIPS32R2)
+    if (cpu->insn_flags & ISA_MIPS32R2) {
         mask |= 1 << CP0Ca_DC;
+    }
 
-    env->CP0_Cause = (env->CP0_Cause & ~mask) | (arg1 & mask);
+    cpu->CP0_Cause = (cpu->CP0_Cause & ~mask) | (arg1 & mask);
 
-    if ((old ^ env->CP0_Cause) & (1 << CP0Ca_DC)) {
-        if (env->CP0_Cause & (1 << CP0Ca_DC))
-            cpu_mips_stop_count(env);
-        else
-            cpu_mips_start_count(env);
+    if ((old ^ cpu->CP0_Cause) & (1 << CP0Ca_DC)) {
+        if (cpu->CP0_Cause & (1 << CP0Ca_DC)) {
+            cpu_mips_stop_count(cpu);
+        } else {
+            cpu_mips_start_count(cpu);
+        }
     }
 
     /* Set/reset software interrupts */
     for (i = 0 ; i < 2 ; i++) {
-        if ((old ^ env->CP0_Cause) & (1 << (CP0Ca_IP + i))) {
-            cpu_mips_soft_irq(env, i, env->CP0_Cause & (1 << (CP0Ca_IP + i)));
+        if ((old ^ cpu->CP0_Cause) & (1 << (CP0Ca_IP + i))) {
+            cpu_mips_soft_irq(cpu, i, cpu->CP0_Cause & (1 << (CP0Ca_IP + i)));
         }
     }
 }
 
+void helper_mtc0_cause(target_ulong arg1)
+{
+    mtc0_cause(env, arg1);
+}
+
+void helper_mttc0_cause(target_ulong arg1)
+{
+    int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC);
+    CPUState *other = mips_cpu_map_tc(&other_tc);
+
+    mtc0_cause(other, arg1);
+}
+
+target_ulong helper_mftc0_epc(void)
+{
+    int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC);
+    CPUState *other = mips_cpu_map_tc(&other_tc);
+
+    return other->CP0_EPC;
+}
+
+target_ulong helper_mftc0_ebase(void)
+{
+    int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC);
+    CPUState *other = mips_cpu_map_tc(&other_tc);
+
+    return other->CP0_EBase;
+}
+
 void helper_mtc0_ebase (target_ulong arg1)
 {
     /* vectored interrupts not implemented */
     env->CP0_EBase = (env->CP0_EBase & ~0x3FFFF000) | (arg1 & 0x3FFFF000);
 }
 
+void helper_mttc0_ebase(target_ulong arg1)
+{
+    int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC);
+    CPUState *other = mips_cpu_map_tc(&other_tc);
+    other->CP0_EBase = (other->CP0_EBase & ~0x3FFFF000) | (arg1 & 0x3FFFF000);
+}
+
+target_ulong helper_mftc0_configx(target_ulong idx)
+{
+    int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC);
+    CPUState *other = mips_cpu_map_tc(&other_tc);
+
+    switch (idx) {
+    case 0: return other->CP0_Config0;
+    case 1: return other->CP0_Config1;
+    case 2: return other->CP0_Config2;
+    case 3: return other->CP0_Config3;
+    /* 4 and 5 are reserved.  */
+    case 6: return other->CP0_Config6;
+    case 7: return other->CP0_Config7;
+    default:
+        break;
+    }
+    return 0;
+}
+
 void helper_mtc0_config0 (target_ulong arg1)
 {
     env->CP0_Config0 = (env->CP0_Config0 & 0x81FFFFF8) | (arg1 & 0x00000007);
diff --git a/target-mips/translate.c b/target-mips/translate.c
index 6c4e0d7..1bd1d62 100644
--- a/target-mips/translate.c
+++ b/target-mips/translate.c
@@ -5537,6 +5537,19 @@ static void gen_mftr(CPUState *env, DisasContext *ctx, int rt, int rd,
         tcg_gen_movi_tl(t0, -1);
     else if (u == 0) {
         switch (rt) {
+        case 1:
+            switch (sel) {
+            case 1:
+                gen_helper_mftc0_vpecontrol(t0);
+                break;
+            case 2:
+                gen_helper_mftc0_vpeconf0(t0);
+                break;
+            default:
+                goto die;
+                break;
+            }
+            break;
         case 2:
             switch (sel) {
             case 1:
@@ -5583,6 +5596,46 @@ static void gen_mftr(CPUState *env, DisasContext *ctx, int rt, int rd,
                 gen_mfc0(env, ctx, t0, rt, sel);
                 break;
             }
+        case 13:
+            switch (sel) {
+            case 0:
+                gen_helper_mftc0_cause(t0);
+                break;
+            default:
+                goto die;
+                break;
+            }
+            break;
+        case 14:
+            switch (sel) {
+            case 0:
+                gen_helper_mftc0_epc(t0);
+                break;
+            default:
+                goto die;
+                break;
+            }
+            break;
+        case 15:
+            switch (sel) {
+            case 1:
+                gen_helper_mftc0_ebase(t0);
+                break;
+            default:
+                goto die;
+                break;
+            }
+            break;
+        case 16:
+            switch (sel) {
+            case 0 ... 7:
+                gen_helper_mftc0_configx(t0, tcg_const_tl(sel));
+                break;
+            default:
+                goto die;
+                break;
+            }
+            break;
         case 23:
             switch (sel) {
             case 0:
@@ -5702,6 +5755,19 @@ static void gen_mttr(CPUState *env, DisasContext *ctx, int rd, int rt,
         /* NOP */ ;
     else if (u == 0) {
         switch (rd) {
+        case 1:
+            switch (sel) {
+            case 1:
+                gen_helper_mttc0_vpecontrol(t0);
+                break;
+            case 2:
+                gen_helper_mttc0_vpeconf0(t0);
+                break;
+            default:
+                goto die;
+                break;
+            }
+            break;
         case 2:
             switch (sel) {
             case 1:
@@ -5748,6 +5814,26 @@ static void gen_mttr(CPUState *env, DisasContext *ctx, int rd, int rt,
                 gen_mtc0(env, ctx, t0, rd, sel);
                 break;
             }
+        case 13:
+            switch (sel) {
+            case 0:
+                gen_helper_mttc0_cause(t0);
+                break;
+            default:
+                goto die;
+                break;
+            }
+            break;
+        case 15:
+            switch (sel) {
+            case 1:
+                gen_helper_mttc0_ebase(t0);
+                break;
+            default:
+                goto die;
+                break;
+            }
+            break;
         case 23:
             switch (sel) {
             case 0:
commit fe8dca8c3c70d079804ce92e1c0a503fb57020d0
Author: Edgar E. Iglesias <edgar.iglesias at gmail.com>
Date:   Mon Aug 29 23:07:33 2011 +0200

    mips: Synchronize CP0 TCSTatus, Status and EntryHi
    
    These registers share some of their fields. Writes to these fields
    should be visible through the corresponding mirror fields.
    
    Signed-off-by: Edgar E. Iglesias <edgar.iglesias at gmail.com>

diff --git a/target-mips/op_helper.c b/target-mips/op_helper.c
index a079fc0..47774fe 100644
--- a/target-mips/op_helper.c
+++ b/target-mips/op_helper.c
@@ -774,6 +774,98 @@ static CPUState *mips_cpu_map_tc(int *tc)
     return other ? other : env;
 }
 
+/* The per VPE CP0_Status register shares some fields with the per TC
+   CP0_TCStatus registers. These fields are wired to the same registers,
+   so changes to either of them should be reflected on both registers.
+
+   Also, EntryHi shares the bottom 8 bit ASID with TCStauts.
+
+   These helper call synchronizes the regs for a given cpu.  */
+
+/* Called for updates to CP0_Status.  */
+static void sync_c0_status(CPUState *cpu, int tc)
+{
+    int32_t tcstatus, *tcst;
+    uint32_t v = cpu->CP0_Status;
+    uint32_t cu, mx, asid, ksu;
+    uint32_t mask = ((1 << CP0TCSt_TCU3)
+                       | (1 << CP0TCSt_TCU2)
+                       | (1 << CP0TCSt_TCU1)
+                       | (1 << CP0TCSt_TCU0)
+                       | (1 << CP0TCSt_TMX)
+                       | (3 << CP0TCSt_TKSU)
+                       | (0xff << CP0TCSt_TASID));
+
+    cu = (v >> CP0St_CU0) & 0xf;
+    mx = (v >> CP0St_MX) & 0x1;
+    ksu = (v >> CP0St_KSU) & 0x3;
+    asid = env->CP0_EntryHi & 0xff;
+
+    tcstatus = cu << CP0TCSt_TCU0;
+    tcstatus |= mx << CP0TCSt_TMX;
+    tcstatus |= ksu << CP0TCSt_TKSU;
+    tcstatus |= asid;
+
+    if (tc == cpu->current_tc) {
+        tcst = &cpu->active_tc.CP0_TCStatus;
+    } else {
+        tcst = &cpu->tcs[tc].CP0_TCStatus;
+    }
+
+    *tcst &= ~mask;
+    *tcst |= tcstatus;
+    compute_hflags(cpu);
+}
+
+/* Called for updates to CP0_TCStatus.  */
+static void sync_c0_tcstatus(CPUState *cpu, int tc, target_ulong v)
+{
+    uint32_t status;
+    uint32_t tcu, tmx, tasid, tksu;
+    uint32_t mask = ((1 << CP0St_CU3)
+                       | (1 << CP0St_CU2)
+                       | (1 << CP0St_CU1)
+                       | (1 << CP0St_CU0)
+                       | (1 << CP0St_MX)
+                       | (3 << CP0St_KSU));
+
+    tcu = (v >> CP0TCSt_TCU0) & 0xf;
+    tmx = (v >> CP0TCSt_TMX) & 0x1;
+    tasid = v & 0xff;
+    tksu = (v >> CP0TCSt_TKSU) & 0x3;
+
+    status = tcu << CP0St_CU0;
+    status |= tmx << CP0St_MX;
+    status |= tksu << CP0St_KSU;
+
+    cpu->CP0_Status &= ~mask;
+    cpu->CP0_Status |= status;
+
+    /* Sync the TASID with EntryHi.  */
+    cpu->CP0_EntryHi &= ~0xff;
+    cpu->CP0_EntryHi = tasid;
+
+    compute_hflags(cpu);
+}
+
+/* Called for updates to CP0_EntryHi.  */
+static void sync_c0_entryhi(CPUState *cpu, int tc)
+{
+    int32_t *tcst;
+    uint32_t asid, v = cpu->CP0_EntryHi;
+
+    asid = v & 0xff;
+
+    if (tc == cpu->current_tc) {
+        tcst = &cpu->active_tc.CP0_TCStatus;
+    } else {
+        tcst = &cpu->tcs[tc].CP0_TCStatus;
+    }
+
+    *tcst &= ~0xff;
+    *tcst |= asid;
+}
+
 /* CP0 helpers */
 target_ulong helper_mfc0_mvpcontrol (void)
 {
@@ -916,34 +1008,16 @@ target_ulong helper_mftc0_entryhi(void)
 {
     int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC);
     CPUState *other = mips_cpu_map_tc(&other_tc);
-    int32_t tcstatus;
 
-    if (other_tc == other->current_tc)
-        tcstatus = other->active_tc.CP0_TCStatus;
-    else
-        tcstatus = other->tcs[other_tc].CP0_TCStatus;
-
-    return (other->CP0_EntryHi & ~0xff) | (tcstatus & 0xff);
+    return other->CP0_EntryHi;
 }
 
 target_ulong helper_mftc0_status(void)
 {
     int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC);
-    target_ulong t0;
-    int32_t tcstatus;
     CPUState *other = mips_cpu_map_tc(&other_tc);
 
-    if (other_tc == other->current_tc)
-        tcstatus = other->active_tc.CP0_TCStatus;
-    else
-        tcstatus = other->tcs[other_tc].CP0_TCStatus;
-
-    t0 = other->CP0_Status & ~0xf1000018;
-    t0 |= tcstatus & (0xf << CP0TCSt_TCU0);
-    t0 |= (tcstatus & (1 << CP0TCSt_TMX)) >> (CP0TCSt_TMX - CP0St_MX);
-    t0 |= (tcstatus & (0x3 << CP0TCSt_TKSU)) >> (CP0TCSt_TKSU - CP0St_KSU);
-
-    return t0;
+    return other->CP0_Status;
 }
 
 target_ulong helper_mfc0_lladdr (void)
@@ -1129,9 +1203,8 @@ void helper_mtc0_tcstatus (target_ulong arg1)
 
     newval = (env->active_tc.CP0_TCStatus & ~mask) | (arg1 & mask);
 
-    // TODO: Sync with CP0_Status.
-
     env->active_tc.CP0_TCStatus = newval;
+    sync_c0_tcstatus(env, env->current_tc, newval);
 }
 
 void helper_mttc0_tcstatus (target_ulong arg1)
@@ -1139,12 +1212,11 @@ void helper_mttc0_tcstatus (target_ulong arg1)
     int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC);
     CPUState *other = mips_cpu_map_tc(&other_tc);
 
-    // TODO: Sync with CP0_Status.
-
     if (other_tc == other->current_tc)
         other->active_tc.CP0_TCStatus = arg1;
     else
         other->tcs[other_tc].CP0_TCStatus = arg1;
+    sync_c0_tcstatus(other, other_tc, arg1);
 }
 
 void helper_mtc0_tcbind (target_ulong arg1)
@@ -1348,8 +1420,7 @@ void helper_mtc0_entryhi (target_ulong arg1)
     old = env->CP0_EntryHi;
     env->CP0_EntryHi = val;
     if (env->CP0_Config3 & (1 << CP0C3_MT)) {
-        uint32_t tcst = env->active_tc.CP0_TCStatus & ~0xff;
-        env->active_tc.CP0_TCStatus = tcst | (val & 0xff);
+        sync_c0_entryhi(env, env->current_tc);
     }
     /* If the ASID changes, flush qemu's TLB.  */
     if ((old & 0xFF) != (val & 0xFF))
@@ -1359,17 +1430,10 @@ void helper_mtc0_entryhi (target_ulong arg1)
 void helper_mttc0_entryhi(target_ulong arg1)
 {
     int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC);
-    int32_t tcstatus;
     CPUState *other = mips_cpu_map_tc(&other_tc);
 
-    other->CP0_EntryHi = (other->CP0_EntryHi & 0xff) | (arg1 & ~0xff);
-    if (other_tc == other->current_tc) {
-        tcstatus = (other->active_tc.CP0_TCStatus & ~0xff) | (arg1 & 0xff);
-        other->active_tc.CP0_TCStatus = tcstatus;
-    } else {
-        tcstatus = (other->tcs[other_tc].CP0_TCStatus & ~0xff) | (arg1 & 0xff);
-        other->tcs[other_tc].CP0_TCStatus = tcstatus;
-    }
+    other->CP0_EntryHi = arg1;
+    sync_c0_entryhi(other, other_tc);
 }
 
 void helper_mtc0_compare (target_ulong arg1)
@@ -1385,7 +1449,12 @@ void helper_mtc0_status (target_ulong arg1)
     val = arg1 & mask;
     old = env->CP0_Status;
     env->CP0_Status = (env->CP0_Status & ~mask) | val;
-    compute_hflags(env);
+    if (env->CP0_Config3 & (1 << CP0C3_MT)) {
+        sync_c0_status(env, env->current_tc);
+    } else {
+        compute_hflags(env);
+    }
+
     if (qemu_loglevel_mask(CPU_LOG_EXEC)) {
         qemu_log("Status %08x (%08x) => %08x (%08x) Cause %08x",
                 old, old & env->CP0_Cause & CP0Ca_IP_mask,
@@ -1403,17 +1472,10 @@ void helper_mtc0_status (target_ulong arg1)
 void helper_mttc0_status(target_ulong arg1)
 {
     int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC);
-    int32_t tcstatus = env->tcs[other_tc].CP0_TCStatus;
     CPUState *other = mips_cpu_map_tc(&other_tc);
 
     other->CP0_Status = arg1 & ~0xf1000018;
-    tcstatus = (tcstatus & ~(0xf << CP0TCSt_TCU0)) | (arg1 & (0xf << CP0St_CU0));
-    tcstatus = (tcstatus & ~(1 << CP0TCSt_TMX)) | ((arg1 & (1 << CP0St_MX)) << (CP0TCSt_TMX - CP0St_MX));
-    tcstatus = (tcstatus & ~(0x3 << CP0TCSt_TKSU)) | ((arg1 & (0x3 << CP0St_KSU)) << (CP0TCSt_TKSU - CP0St_KSU));
-    if (other_tc == other->current_tc)
-        other->active_tc.CP0_TCStatus = tcstatus;
-    else
-        other->tcs[other_tc].CP0_TCStatus = tcstatus;
+    sync_c0_status(other, other_tc);
 }
 
 void helper_mtc0_intctl (target_ulong arg1)
commit b93bbdcd69819cdbcb7e3be54b789be94bda0ff1
Author: Edgar E. Iglesias <edgar.iglesias at gmail.com>
Date:   Mon Aug 29 23:07:32 2011 +0200

    mips: Handle TC indexing of other VPEs
    
    Introduce mips_cpu_map_tc() to map a global TC index into a VPE nr
    and local tc index.
    
    Signed-off-by: Edgar E. Iglesias <edgar.iglesias at gmail.com>

diff --git a/target-mips/op_helper.c b/target-mips/op_helper.c
index 056011f..a079fc0 100644
--- a/target-mips/op_helper.c
+++ b/target-mips/op_helper.c
@@ -749,6 +749,31 @@ void helper_sdm (target_ulong addr, target_ulong reglist, uint32_t mem_idx)
 #endif
 
 #ifndef CONFIG_USER_ONLY
+/* tc should point to an int with the value of the global TC index.
+   This function will transform it into a local index within the
+   returned CPUState.
+
+   FIXME: This code assumes that all VPEs have the same number of TCs,
+          which depends on runtime setup. Can probably be fixed by
+          walking the list of CPUStates.  */
+static CPUState *mips_cpu_map_tc(int *tc)
+{
+    CPUState *other;
+    int vpe_idx, nr_threads = env->nr_threads;
+    int tc_idx = *tc;
+
+    if (!(env->CP0_VPEConf0 & (1 << CP0VPEC0_MVP))) {
+        /* Not allowed to address other CPUs.  */
+        *tc = env->current_tc;
+        return env;
+    }
+
+    vpe_idx = tc_idx / nr_threads;
+    *tc = tc_idx % nr_threads;
+    other = qemu_get_cpu(vpe_idx);
+    return other ? other : env;
+}
+
 /* CP0 helpers */
 target_ulong helper_mfc0_mvpcontrol (void)
 {
@@ -778,11 +803,12 @@ target_ulong helper_mfc0_tcstatus (void)
 target_ulong helper_mftc0_tcstatus(void)
 {
     int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC);
+    CPUState *other = mips_cpu_map_tc(&other_tc);
 
-    if (other_tc == env->current_tc)
-        return env->active_tc.CP0_TCStatus;
+    if (other_tc == other->current_tc)
+        return other->active_tc.CP0_TCStatus;
     else
-        return env->tcs[other_tc].CP0_TCStatus;
+        return other->tcs[other_tc].CP0_TCStatus;
 }
 
 target_ulong helper_mfc0_tcbind (void)
@@ -793,11 +819,12 @@ target_ulong helper_mfc0_tcbind (void)
 target_ulong helper_mftc0_tcbind(void)
 {
     int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC);
+    CPUState *other = mips_cpu_map_tc(&other_tc);
 
-    if (other_tc == env->current_tc)
-        return env->active_tc.CP0_TCBind;
+    if (other_tc == other->current_tc)
+        return other->active_tc.CP0_TCBind;
     else
-        return env->tcs[other_tc].CP0_TCBind;
+        return other->tcs[other_tc].CP0_TCBind;
 }
 
 target_ulong helper_mfc0_tcrestart (void)
@@ -808,11 +835,12 @@ target_ulong helper_mfc0_tcrestart (void)
 target_ulong helper_mftc0_tcrestart(void)
 {
     int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC);
+    CPUState *other = mips_cpu_map_tc(&other_tc);
 
-    if (other_tc == env->current_tc)
-        return env->active_tc.PC;
+    if (other_tc == other->current_tc)
+        return other->active_tc.PC;
     else
-        return env->tcs[other_tc].PC;
+        return other->tcs[other_tc].PC;
 }
 
 target_ulong helper_mfc0_tchalt (void)
@@ -823,11 +851,12 @@ target_ulong helper_mfc0_tchalt (void)
 target_ulong helper_mftc0_tchalt(void)
 {
     int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC);
+    CPUState *other = mips_cpu_map_tc(&other_tc);
 
-    if (other_tc == env->current_tc)
-        return env->active_tc.CP0_TCHalt;
+    if (other_tc == other->current_tc)
+        return other->active_tc.CP0_TCHalt;
     else
-        return env->tcs[other_tc].CP0_TCHalt;
+        return other->tcs[other_tc].CP0_TCHalt;
 }
 
 target_ulong helper_mfc0_tccontext (void)
@@ -838,11 +867,12 @@ target_ulong helper_mfc0_tccontext (void)
 target_ulong helper_mftc0_tccontext(void)
 {
     int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC);
+    CPUState *other = mips_cpu_map_tc(&other_tc);
 
-    if (other_tc == env->current_tc)
-        return env->active_tc.CP0_TCContext;
+    if (other_tc == other->current_tc)
+        return other->active_tc.CP0_TCContext;
     else
-        return env->tcs[other_tc].CP0_TCContext;
+        return other->tcs[other_tc].CP0_TCContext;
 }
 
 target_ulong helper_mfc0_tcschedule (void)
@@ -853,11 +883,12 @@ target_ulong helper_mfc0_tcschedule (void)
 target_ulong helper_mftc0_tcschedule(void)
 {
     int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC);
+    CPUState *other = mips_cpu_map_tc(&other_tc);
 
-    if (other_tc == env->current_tc)
-        return env->active_tc.CP0_TCSchedule;
+    if (other_tc == other->current_tc)
+        return other->active_tc.CP0_TCSchedule;
     else
-        return env->tcs[other_tc].CP0_TCSchedule;
+        return other->tcs[other_tc].CP0_TCSchedule;
 }
 
 target_ulong helper_mfc0_tcschefback (void)
@@ -868,11 +899,12 @@ target_ulong helper_mfc0_tcschefback (void)
 target_ulong helper_mftc0_tcschefback(void)
 {
     int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC);
+    CPUState *other = mips_cpu_map_tc(&other_tc);
 
-    if (other_tc == env->current_tc)
-        return env->active_tc.CP0_TCScheFBack;
+    if (other_tc == other->current_tc)
+        return other->active_tc.CP0_TCScheFBack;
     else
-        return env->tcs[other_tc].CP0_TCScheFBack;
+        return other->tcs[other_tc].CP0_TCScheFBack;
 }
 
 target_ulong helper_mfc0_count (void)
@@ -883,14 +915,15 @@ target_ulong helper_mfc0_count (void)
 target_ulong helper_mftc0_entryhi(void)
 {
     int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC);
+    CPUState *other = mips_cpu_map_tc(&other_tc);
     int32_t tcstatus;
 
-    if (other_tc == env->current_tc)
-        tcstatus = env->active_tc.CP0_TCStatus;
+    if (other_tc == other->current_tc)
+        tcstatus = other->active_tc.CP0_TCStatus;
     else
-        tcstatus = env->tcs[other_tc].CP0_TCStatus;
+        tcstatus = other->tcs[other_tc].CP0_TCStatus;
 
-    return (env->CP0_EntryHi & ~0xff) | (tcstatus & 0xff);
+    return (other->CP0_EntryHi & ~0xff) | (tcstatus & 0xff);
 }
 
 target_ulong helper_mftc0_status(void)
@@ -898,13 +931,14 @@ target_ulong helper_mftc0_status(void)
     int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC);
     target_ulong t0;
     int32_t tcstatus;
+    CPUState *other = mips_cpu_map_tc(&other_tc);
 
-    if (other_tc == env->current_tc)
-        tcstatus = env->active_tc.CP0_TCStatus;
+    if (other_tc == other->current_tc)
+        tcstatus = other->active_tc.CP0_TCStatus;
     else
-        tcstatus = env->tcs[other_tc].CP0_TCStatus;
+        tcstatus = other->tcs[other_tc].CP0_TCStatus;
 
-    t0 = env->CP0_Status & ~0xf1000018;
+    t0 = other->CP0_Status & ~0xf1000018;
     t0 |= tcstatus & (0xf << CP0TCSt_TCU0);
     t0 |= (tcstatus & (1 << CP0TCSt_TMX)) >> (CP0TCSt_TMX - CP0St_MX);
     t0 |= (tcstatus & (0x3 << CP0TCSt_TKSU)) >> (CP0TCSt_TKSU - CP0St_KSU);
@@ -940,14 +974,15 @@ target_ulong helper_mftc0_debug(void)
 {
     int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC);
     int32_t tcstatus;
+    CPUState *other = mips_cpu_map_tc(&other_tc);
 
-    if (other_tc == env->current_tc)
-        tcstatus = env->active_tc.CP0_Debug_tcstatus;
+    if (other_tc == other->current_tc)
+        tcstatus = other->active_tc.CP0_Debug_tcstatus;
     else
-        tcstatus = env->tcs[other_tc].CP0_Debug_tcstatus;
+        tcstatus = other->tcs[other_tc].CP0_Debug_tcstatus;
 
     /* XXX: Might be wrong, check with EJTAG spec. */
-    return (env->CP0_Debug & ~((1 << CP0DB_SSt) | (1 << CP0DB_Halt))) |
+    return (other->CP0_Debug & ~((1 << CP0DB_SSt) | (1 << CP0DB_Halt))) |
             (tcstatus & ((1 << CP0DB_SSt) | (1 << CP0DB_Halt)));
 }
 
@@ -1102,13 +1137,14 @@ void helper_mtc0_tcstatus (target_ulong arg1)
 void helper_mttc0_tcstatus (target_ulong arg1)
 {
     int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC);
+    CPUState *other = mips_cpu_map_tc(&other_tc);
 
     // TODO: Sync with CP0_Status.
 
-    if (other_tc == env->current_tc)
-        env->active_tc.CP0_TCStatus = arg1;
+    if (other_tc == other->current_tc)
+        other->active_tc.CP0_TCStatus = arg1;
     else
-        env->tcs[other_tc].CP0_TCStatus = arg1;
+        other->tcs[other_tc].CP0_TCStatus = arg1;
 }
 
 void helper_mtc0_tcbind (target_ulong arg1)
@@ -1127,15 +1163,16 @@ void helper_mttc0_tcbind (target_ulong arg1)
     int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC);
     uint32_t mask = (1 << CP0TCBd_TBE);
     uint32_t newval;
+    CPUState *other = mips_cpu_map_tc(&other_tc);
 
-    if (env->mvp->CP0_MVPControl & (1 << CP0MVPCo_VPC))
+    if (other->mvp->CP0_MVPControl & (1 << CP0MVPCo_VPC))
         mask |= (1 << CP0TCBd_CurVPE);
-    if (other_tc == env->current_tc) {
-        newval = (env->active_tc.CP0_TCBind & ~mask) | (arg1 & mask);
-        env->active_tc.CP0_TCBind = newval;
+    if (other_tc == other->current_tc) {
+        newval = (other->active_tc.CP0_TCBind & ~mask) | (arg1 & mask);
+        other->active_tc.CP0_TCBind = newval;
     } else {
-        newval = (env->tcs[other_tc].CP0_TCBind & ~mask) | (arg1 & mask);
-        env->tcs[other_tc].CP0_TCBind = newval;
+        newval = (other->tcs[other_tc].CP0_TCBind & ~mask) | (arg1 & mask);
+        other->tcs[other_tc].CP0_TCBind = newval;
     }
 }
 
@@ -1150,16 +1187,17 @@ void helper_mtc0_tcrestart (target_ulong arg1)
 void helper_mttc0_tcrestart (target_ulong arg1)
 {
     int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC);
+    CPUState *other = mips_cpu_map_tc(&other_tc);
 
-    if (other_tc == env->current_tc) {
-        env->active_tc.PC = arg1;
-        env->active_tc.CP0_TCStatus &= ~(1 << CP0TCSt_TDS);
-        env->lladdr = 0ULL;
+    if (other_tc == other->current_tc) {
+        other->active_tc.PC = arg1;
+        other->active_tc.CP0_TCStatus &= ~(1 << CP0TCSt_TDS);
+        other->lladdr = 0ULL;
         /* MIPS16 not implemented. */
     } else {
-        env->tcs[other_tc].PC = arg1;
-        env->tcs[other_tc].CP0_TCStatus &= ~(1 << CP0TCSt_TDS);
-        env->lladdr = 0ULL;
+        other->tcs[other_tc].PC = arg1;
+        other->tcs[other_tc].CP0_TCStatus &= ~(1 << CP0TCSt_TDS);
+        other->lladdr = 0ULL;
         /* MIPS16 not implemented. */
     }
 }
@@ -1174,13 +1212,14 @@ void helper_mtc0_tchalt (target_ulong arg1)
 void helper_mttc0_tchalt (target_ulong arg1)
 {
     int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC);
+    CPUState *other = mips_cpu_map_tc(&other_tc);
 
     // TODO: Halt TC / Restart (if allocated+active) TC.
 
-    if (other_tc == env->current_tc)
-        env->active_tc.CP0_TCHalt = arg1;
+    if (other_tc == other->current_tc)
+        other->active_tc.CP0_TCHalt = arg1;
     else
-        env->tcs[other_tc].CP0_TCHalt = arg1;
+        other->tcs[other_tc].CP0_TCHalt = arg1;
 }
 
 void helper_mtc0_tccontext (target_ulong arg1)
@@ -1191,11 +1230,12 @@ void helper_mtc0_tccontext (target_ulong arg1)
 void helper_mttc0_tccontext (target_ulong arg1)
 {
     int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC);
+    CPUState *other = mips_cpu_map_tc(&other_tc);
 
-    if (other_tc == env->current_tc)
-        env->active_tc.CP0_TCContext = arg1;
+    if (other_tc == other->current_tc)
+        other->active_tc.CP0_TCContext = arg1;
     else
-        env->tcs[other_tc].CP0_TCContext = arg1;
+        other->tcs[other_tc].CP0_TCContext = arg1;
 }
 
 void helper_mtc0_tcschedule (target_ulong arg1)
@@ -1206,11 +1246,12 @@ void helper_mtc0_tcschedule (target_ulong arg1)
 void helper_mttc0_tcschedule (target_ulong arg1)
 {
     int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC);
+    CPUState *other = mips_cpu_map_tc(&other_tc);
 
-    if (other_tc == env->current_tc)
-        env->active_tc.CP0_TCSchedule = arg1;
+    if (other_tc == other->current_tc)
+        other->active_tc.CP0_TCSchedule = arg1;
     else
-        env->tcs[other_tc].CP0_TCSchedule = arg1;
+        other->tcs[other_tc].CP0_TCSchedule = arg1;
 }
 
 void helper_mtc0_tcschefback (target_ulong arg1)
@@ -1221,11 +1262,12 @@ void helper_mtc0_tcschefback (target_ulong arg1)
 void helper_mttc0_tcschefback (target_ulong arg1)
 {
     int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC);
+    CPUState *other = mips_cpu_map_tc(&other_tc);
 
-    if (other_tc == env->current_tc)
-        env->active_tc.CP0_TCScheFBack = arg1;
+    if (other_tc == other->current_tc)
+        other->active_tc.CP0_TCScheFBack = arg1;
     else
-        env->tcs[other_tc].CP0_TCScheFBack = arg1;
+        other->tcs[other_tc].CP0_TCScheFBack = arg1;
 }
 
 void helper_mtc0_entrylo1 (target_ulong arg1)
@@ -1318,14 +1360,15 @@ void helper_mttc0_entryhi(target_ulong arg1)
 {
     int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC);
     int32_t tcstatus;
+    CPUState *other = mips_cpu_map_tc(&other_tc);
 
-    env->CP0_EntryHi = (env->CP0_EntryHi & 0xff) | (arg1 & ~0xff);
-    if (other_tc == env->current_tc) {
-        tcstatus = (env->active_tc.CP0_TCStatus & ~0xff) | (arg1 & 0xff);
-        env->active_tc.CP0_TCStatus = tcstatus;
+    other->CP0_EntryHi = (other->CP0_EntryHi & 0xff) | (arg1 & ~0xff);
+    if (other_tc == other->current_tc) {
+        tcstatus = (other->active_tc.CP0_TCStatus & ~0xff) | (arg1 & 0xff);
+        other->active_tc.CP0_TCStatus = tcstatus;
     } else {
-        tcstatus = (env->tcs[other_tc].CP0_TCStatus & ~0xff) | (arg1 & 0xff);
-        env->tcs[other_tc].CP0_TCStatus = tcstatus;
+        tcstatus = (other->tcs[other_tc].CP0_TCStatus & ~0xff) | (arg1 & 0xff);
+        other->tcs[other_tc].CP0_TCStatus = tcstatus;
     }
 }
 
@@ -1361,15 +1404,16 @@ void helper_mttc0_status(target_ulong arg1)
 {
     int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC);
     int32_t tcstatus = env->tcs[other_tc].CP0_TCStatus;
+    CPUState *other = mips_cpu_map_tc(&other_tc);
 
-    env->CP0_Status = arg1 & ~0xf1000018;
+    other->CP0_Status = arg1 & ~0xf1000018;
     tcstatus = (tcstatus & ~(0xf << CP0TCSt_TCU0)) | (arg1 & (0xf << CP0St_CU0));
     tcstatus = (tcstatus & ~(1 << CP0TCSt_TMX)) | ((arg1 & (1 << CP0St_MX)) << (CP0TCSt_TMX - CP0St_MX));
     tcstatus = (tcstatus & ~(0x3 << CP0TCSt_TKSU)) | ((arg1 & (0x3 << CP0St_KSU)) << (CP0TCSt_TKSU - CP0St_KSU));
-    if (other_tc == env->current_tc)
-        env->active_tc.CP0_TCStatus = tcstatus;
+    if (other_tc == other->current_tc)
+        other->active_tc.CP0_TCStatus = tcstatus;
     else
-        env->tcs[other_tc].CP0_TCStatus = tcstatus;
+        other->tcs[other_tc].CP0_TCStatus = tcstatus;
 }
 
 void helper_mtc0_intctl (target_ulong arg1)
@@ -1471,13 +1515,15 @@ void helper_mttc0_debug(target_ulong arg1)
 {
     int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC);
     uint32_t val = arg1 & ((1 << CP0DB_SSt) | (1 << CP0DB_Halt));
+    CPUState *other = mips_cpu_map_tc(&other_tc);
 
     /* XXX: Might be wrong, check with EJTAG spec. */
-    if (other_tc == env->current_tc)
-        env->active_tc.CP0_Debug_tcstatus = val;
+    if (other_tc == other->current_tc)
+        other->active_tc.CP0_Debug_tcstatus = val;
     else
-        env->tcs[other_tc].CP0_Debug_tcstatus = val;
-    env->CP0_Debug = (env->CP0_Debug & ((1 << CP0DB_SSt) | (1 << CP0DB_Halt))) |
+        other->tcs[other_tc].CP0_Debug_tcstatus = val;
+    other->CP0_Debug = (other->CP0_Debug &
+                     ((1 << CP0DB_SSt) | (1 << CP0DB_Halt))) |
                      (arg1 & ~((1 << CP0DB_SSt) | (1 << CP0DB_Halt)));
 }
 
@@ -1510,101 +1556,111 @@ void helper_mtc0_datahi (target_ulong arg1)
 target_ulong helper_mftgpr(uint32_t sel)
 {
     int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC);
+    CPUState *other = mips_cpu_map_tc(&other_tc);
 
-    if (other_tc == env->current_tc)
-        return env->active_tc.gpr[sel];
+    if (other_tc == other->current_tc)
+        return other->active_tc.gpr[sel];
     else
-        return env->tcs[other_tc].gpr[sel];
+        return other->tcs[other_tc].gpr[sel];
 }
 
 target_ulong helper_mftlo(uint32_t sel)
 {
     int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC);
+    CPUState *other = mips_cpu_map_tc(&other_tc);
 
-    if (other_tc == env->current_tc)
-        return env->active_tc.LO[sel];
+    if (other_tc == other->current_tc)
+        return other->active_tc.LO[sel];
     else
-        return env->tcs[other_tc].LO[sel];
+        return other->tcs[other_tc].LO[sel];
 }
 
 target_ulong helper_mfthi(uint32_t sel)
 {
     int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC);
+    CPUState *other = mips_cpu_map_tc(&other_tc);
 
-    if (other_tc == env->current_tc)
-        return env->active_tc.HI[sel];
+    if (other_tc == other->current_tc)
+        return other->active_tc.HI[sel];
     else
-        return env->tcs[other_tc].HI[sel];
+        return other->tcs[other_tc].HI[sel];
 }
 
 target_ulong helper_mftacx(uint32_t sel)
 {
     int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC);
+    CPUState *other = mips_cpu_map_tc(&other_tc);
 
-    if (other_tc == env->current_tc)
-        return env->active_tc.ACX[sel];
+    if (other_tc == other->current_tc)
+        return other->active_tc.ACX[sel];
     else
-        return env->tcs[other_tc].ACX[sel];
+        return other->tcs[other_tc].ACX[sel];
 }
 
 target_ulong helper_mftdsp(void)
 {
     int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC);
+    CPUState *other = mips_cpu_map_tc(&other_tc);
 
-    if (other_tc == env->current_tc)
-        return env->active_tc.DSPControl;
+    if (other_tc == other->current_tc)
+        return other->active_tc.DSPControl;
     else
-        return env->tcs[other_tc].DSPControl;
+        return other->tcs[other_tc].DSPControl;
 }
 
 void helper_mttgpr(target_ulong arg1, uint32_t sel)
 {
     int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC);
+    CPUState *other = mips_cpu_map_tc(&other_tc);
 
-    if (other_tc == env->current_tc)
-        env->active_tc.gpr[sel] = arg1;
+    if (other_tc == other->current_tc)
+        other->active_tc.gpr[sel] = arg1;
     else
-        env->tcs[other_tc].gpr[sel] = arg1;
+        other->tcs[other_tc].gpr[sel] = arg1;
 }
 
 void helper_mttlo(target_ulong arg1, uint32_t sel)
 {
     int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC);
+    CPUState *other = mips_cpu_map_tc(&other_tc);
 
-    if (other_tc == env->current_tc)
-        env->active_tc.LO[sel] = arg1;
+    if (other_tc == other->current_tc)
+        other->active_tc.LO[sel] = arg1;
     else
-        env->tcs[other_tc].LO[sel] = arg1;
+        other->tcs[other_tc].LO[sel] = arg1;
 }
 
 void helper_mtthi(target_ulong arg1, uint32_t sel)
 {
     int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC);
+    CPUState *other = mips_cpu_map_tc(&other_tc);
 
-    if (other_tc == env->current_tc)
-        env->active_tc.HI[sel] = arg1;
+    if (other_tc == other->current_tc)
+        other->active_tc.HI[sel] = arg1;
     else
-        env->tcs[other_tc].HI[sel] = arg1;
+        other->tcs[other_tc].HI[sel] = arg1;
 }
 
 void helper_mttacx(target_ulong arg1, uint32_t sel)
 {
     int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC);
+    CPUState *other = mips_cpu_map_tc(&other_tc);
 
-    if (other_tc == env->current_tc)
-        env->active_tc.ACX[sel] = arg1;
+    if (other_tc == other->current_tc)
+        other->active_tc.ACX[sel] = arg1;
     else
-        env->tcs[other_tc].ACX[sel] = arg1;
+        other->tcs[other_tc].ACX[sel] = arg1;
 }
 
 void helper_mttdsp(target_ulong arg1)
 {
     int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC);
+    CPUState *other = mips_cpu_map_tc(&other_tc);
 
-    if (other_tc == env->current_tc)
-        env->active_tc.DSPControl = arg1;
+    if (other_tc == other->current_tc)
+        other->active_tc.DSPControl = arg1;
     else
-        env->tcs[other_tc].DSPControl = arg1;
+        other->tcs[other_tc].DSPControl = arg1;
 }
 
 /* MIPS MT functions */
commit f69539b14bdba7a5cd22e1f4bed439b476b17286
Author: Blue Swirl <blauwirbel at gmail.com>
Date:   Sat Sep 3 16:38:02 2011 +0000

    apb_pci: convert PCI space to memory API
    
    Add a new memory space for PCI instead of using system memory.
    
    This also fixes a bug where VGA region vga.chain4 is
    accidentally mapped to 0xa0000 instead of 0x1ff000a0000.
    
    Signed-off-by: Blue Swirl <blauwirbel at gmail.com>

diff --git a/hw/apb_pci.c b/hw/apb_pci.c
index 6ee2068..c232946 100644
--- a/hw/apb_pci.c
+++ b/hw/apb_pci.c
@@ -71,6 +71,7 @@ typedef struct APBState {
     PCIBus      *bus;
     MemoryRegion apb_config;
     MemoryRegion pci_config;
+    MemoryRegion pci_mmio;
     MemoryRegion pci_ioport;
     uint32_t iommu[4];
     uint32_t pci_control[16];
@@ -336,12 +337,14 @@ PCIBus *pci_apb_init(target_phys_addr_t special_base,
     sysbus_mmio_map(s, 2, special_base + 0x2000000ULL);
     d = FROM_SYSBUS(APBState, s);
 
+    memory_region_init(&d->pci_mmio, "pci-mmio", 0x100000000ULL);
+    memory_region_add_subregion(get_system_memory(), mem_base, &d->pci_mmio);
+
     d->bus = pci_register_bus(&d->busdev.qdev, "pci",
-                                         pci_apb_set_irq, pci_pbm_map_irq, d,
-                                         get_system_memory(),
-                                         get_system_io(),
-                                         0, 32);
-    pci_bus_set_mem_base(d->bus, mem_base);
+                              pci_apb_set_irq, pci_pbm_map_irq, d,
+                              &d->pci_mmio,
+                              get_system_io(),
+                              0, 32);
 
     for (i = 0; i < 32; i++) {
         sysbus_connect_irq(s, i, pic[i]);
commit 962d4b2834e6a3b37784391a906b5fe2a7e96b74
Author: Blue Swirl <blauwirbel at gmail.com>
Date:   Fri Aug 26 18:43:18 2011 +0000

    fw_cfg: fix crash if FW_CFG_WRITE_CHANNEL is used incorrectly
    
    Avoid a crash if the guest combines FW_CFG_WRITE_CHANNEL with
    a wrong value.
    
    Signed-off-by: Blue Swirl <blauwirbel at gmail.com>

diff --git a/hw/fw_cfg.c b/hw/fw_cfg.c
index 663ad80..8df265c 100644
--- a/hw/fw_cfg.c
+++ b/hw/fw_cfg.c
@@ -214,7 +214,8 @@ static void fw_cfg_write(FWCfgState *s, uint8_t value)
 
     FW_CFG_DPRINTF("write %d\n", value);
 
-    if (s->cur_entry & FW_CFG_WRITE_CHANNEL && s->cur_offset < e->len) {
+    if (s->cur_entry & FW_CFG_WRITE_CHANNEL && e->callback &&
+        s->cur_offset < e->len) {
         e->data[s->cur_offset++] = value;
         if (s->cur_offset == e->len) {
             e->callback(e->callback_opaque, e->data);
commit 9f8d2a093fa5c8d29934a5f5f2ff611907a83cef
Author: Andreas Färber <andreas.faerber at web.de>
Date:   Sun Aug 28 20:24:34 2011 +0200

    softfloat: Use uint32 consistently
    
    Prepares for uint32 replacement.
    
    Signed-off-by: Andreas Färber <andreas.faerber at web.de>
    Reviewed-by: Peter Maydell <peter.maydell at linaro.org>
    Signed-off-by: Blue Swirl <blauwirbel at gmail.com>

diff --git a/fpu/softfloat.c b/fpu/softfloat.c
index be1206d..2b20085 100644
--- a/fpu/softfloat.c
+++ b/fpu/softfloat.c
@@ -5965,20 +5965,20 @@ int float128_unordered_quiet( float128 a, float128 b STATUS_PARAM )
 }
 
 /* misc functions */
-float32 uint32_to_float32( unsigned int a STATUS_PARAM )
+float32 uint32_to_float32( uint32 a STATUS_PARAM )
 {
     return int64_to_float32(a STATUS_VAR);
 }
 
-float64 uint32_to_float64( unsigned int a STATUS_PARAM )
+float64 uint32_to_float64( uint32 a STATUS_PARAM )
 {
     return int64_to_float64(a STATUS_VAR);
 }
 
-unsigned int float32_to_uint32( float32 a STATUS_PARAM )
+uint32 float32_to_uint32( float32 a STATUS_PARAM )
 {
     int64_t v;
-    unsigned int res;
+    uint32 res;
 
     v = float32_to_int64(a STATUS_VAR);
     if (v < 0) {
@@ -5993,10 +5993,10 @@ unsigned int float32_to_uint32( float32 a STATUS_PARAM )
     return res;
 }
 
-unsigned int float32_to_uint32_round_to_zero( float32 a STATUS_PARAM )
+uint32 float32_to_uint32_round_to_zero( float32 a STATUS_PARAM )
 {
     int64_t v;
-    unsigned int res;
+    uint32 res;
 
     v = float32_to_int64_round_to_zero(a STATUS_VAR);
     if (v < 0) {
@@ -6029,10 +6029,10 @@ uint16 float32_to_uint16_round_to_zero( float32 a STATUS_PARAM )
     return res;
 }
 
-unsigned int float64_to_uint32( float64 a STATUS_PARAM )
+uint32 float64_to_uint32( float64 a STATUS_PARAM )
 {
     int64_t v;
-    unsigned int res;
+    uint32 res;
 
     v = float64_to_int64(a STATUS_VAR);
     if (v < 0) {
@@ -6047,10 +6047,10 @@ unsigned int float64_to_uint32( float64 a STATUS_PARAM )
     return res;
 }
 
-unsigned int float64_to_uint32_round_to_zero( float64 a STATUS_PARAM )
+uint32 float64_to_uint32_round_to_zero( float64 a STATUS_PARAM )
 {
     int64_t v;
-    unsigned int res;
+    uint32 res;
 
     v = float64_to_int64_round_to_zero(a STATUS_VAR);
     if (v < 0) {
diff --git a/fpu/softfloat.h b/fpu/softfloat.h
index e1bbe01..618ddee 100644
--- a/fpu/softfloat.h
+++ b/fpu/softfloat.h
@@ -216,8 +216,8 @@ void float_raise( int8 flags STATUS_PARAM);
 *----------------------------------------------------------------------------*/
 float32 int32_to_float32( int32 STATUS_PARAM );
 float64 int32_to_float64( int32 STATUS_PARAM );
-float32 uint32_to_float32( unsigned int STATUS_PARAM );
-float64 uint32_to_float64( unsigned int STATUS_PARAM );
+float32 uint32_to_float32( uint32 STATUS_PARAM );
+float64 uint32_to_float64( uint32 STATUS_PARAM );
 floatx80 int32_to_floatx80( int32 STATUS_PARAM );
 float128 int32_to_float128( int32 STATUS_PARAM );
 float32 int64_to_float32( int64 STATUS_PARAM );
commit 38641f8f54117fc6a846ca9b62b2611aabf2d6fa
Author: Andreas Färber <andreas.faerber at web.de>
Date:   Sun Aug 28 20:24:33 2011 +0200

    softfloat: Use uint16 consistently
    
    Prepares for uint16 replacement.
    
    Signed-off-by: Andreas Färber <andreas.faerber at web.de>
    Reviewed-by: Peter Maydell <peter.maydell at linaro.org>
    Signed-off-by: Blue Swirl <blauwirbel at gmail.com>

diff --git a/fpu/softfloat.c b/fpu/softfloat.c
index 7951a0e..be1206d 100644
--- a/fpu/softfloat.c
+++ b/fpu/softfloat.c
@@ -6011,10 +6011,10 @@ unsigned int float32_to_uint32_round_to_zero( float32 a STATUS_PARAM )
     return res;
 }
 
-unsigned int float32_to_uint16_round_to_zero( float32 a STATUS_PARAM )
+uint16 float32_to_uint16_round_to_zero( float32 a STATUS_PARAM )
 {
     int64_t v;
-    unsigned int res;
+    uint16 res;
 
     v = float32_to_int64_round_to_zero(a STATUS_VAR);
     if (v < 0) {
@@ -6065,10 +6065,10 @@ unsigned int float64_to_uint32_round_to_zero( float64 a STATUS_PARAM )
     return res;
 }
 
-unsigned int float64_to_uint16_round_to_zero( float64 a STATUS_PARAM )
+uint16 float64_to_uint16_round_to_zero( float64 a STATUS_PARAM )
 {
     int64_t v;
-    unsigned int res;
+    uint16 res;
 
     v = float64_to_int64_round_to_zero(a STATUS_VAR);
     if (v < 0) {
diff --git a/fpu/softfloat.h b/fpu/softfloat.h
index 3bb7d8f..e1bbe01 100644
--- a/fpu/softfloat.h
+++ b/fpu/softfloat.h
@@ -249,7 +249,7 @@ extern const float16 float16_default_nan;
 | Software IEC/IEEE single-precision conversion routines.
 *----------------------------------------------------------------------------*/
 int16 float32_to_int16_round_to_zero( float32 STATUS_PARAM );
-unsigned int float32_to_uint16_round_to_zero( float32 STATUS_PARAM );
+uint16 float32_to_uint16_round_to_zero( float32 STATUS_PARAM );
 int32 float32_to_int32( float32 STATUS_PARAM );
 int32 float32_to_int32_round_to_zero( float32 STATUS_PARAM );
 uint32 float32_to_uint32( float32 STATUS_PARAM );
@@ -352,7 +352,7 @@ extern const float32 float32_default_nan;
 | Software IEC/IEEE double-precision conversion routines.
 *----------------------------------------------------------------------------*/
 int16 float64_to_int16_round_to_zero( float64 STATUS_PARAM );
-unsigned int float64_to_uint16_round_to_zero( float64 STATUS_PARAM );
+uint16 float64_to_uint16_round_to_zero( float64 STATUS_PARAM );
 int32 float64_to_int32( float64 STATUS_PARAM );
 int32 float64_to_int32_round_to_zero( float64 STATUS_PARAM );
 uint32 float64_to_uint32( float64 STATUS_PARAM );
commit e2d8830efcddfde6cb46404ec00785e52b514fa2
Author: Brad <brad at comstyle.com>
Date:   Fri Sep 2 16:53:28 2011 -0400

    Allow overriding the location of Samba's smbd.
    
    Allow overriding the location of Samba's smbd.
    
    Pretty much every OS I look at has some means of
    changing this path (patching) so lets just make
    it easier for OS developers creating packages
    and/or end users to override the location.
    
    Signed-off-by: Brad Smith <brad at comstyle.com>
    Reviewed-by: Stefan Hajnoczi <stefanha at linux.vnet.ibm.com>
    Signed-off-by: Blue Swirl <blauwirbel at gmail.com>

diff --git a/configure b/configure
index a8ea688..c3044c7 100755
--- a/configure
+++ b/configure
@@ -412,6 +412,7 @@ SunOS)
   make="${MAKE-gmake}"
   install="${INSTALL-ginstall}"
   ld="gld"
+  smbd="${SMBD-/usr/sfw/sbin/smbd}"
   needs_libsunmath="no"
   solarisrev=`uname -r | cut -f2 -d.`
   # have to select again, because `uname -m` returns i86pc
@@ -480,6 +481,7 @@ fi
 : ${make=${MAKE-make}}
 : ${install=${INSTALL-install}}
 : ${python=${PYTHON-python}}
+: ${smbd=${SMBD-/usr/sbin/smbd}}
 
 if test "$mingw32" = "yes" ; then
   EXESUF=".exe"
@@ -524,6 +526,8 @@ for opt do
   ;;
   --python=*) python="$optarg"
   ;;
+  --smbd=*) smbd="$optarg"
+  ;;
   --extra-cflags=*)
   ;;
   --extra-ldflags=*)
@@ -938,6 +942,7 @@ echo "  --extra-ldflags=LDFLAGS  append extra linker flags LDFLAGS"
 echo "  --make=MAKE              use specified make [$make]"
 echo "  --install=INSTALL        use specified install [$install]"
 echo "  --python=PYTHON          use specified python [$python]"
+echo "  --smbd=SMBD              use specified smbd [$smbd]"
 echo "  --static                 enable static build [$static]"
 echo "  --mandir=PATH            install man pages in PATH"
 echo "  --datadir=PATH           install firmware in PATH"
@@ -2657,6 +2662,9 @@ echo "LDFLAGS           $LDFLAGS"
 echo "make              $make"
 echo "install           $install"
 echo "python            $python"
+if test "$slirp" = "yes" ; then
+    echo "smbd              $smbd"
+fi
 echo "host CPU          $cpu"
 echo "host big endian   $bigendian"
 echo "target list       $target_list"
@@ -2815,6 +2823,7 @@ if test "$profiler" = "yes" ; then
 fi
 if test "$slirp" = "yes" ; then
   echo "CONFIG_SLIRP=y" >> $config_host_mak
+  echo "CONFIG_SMBD_COMMAND=\"$smbd\"" >> $config_host_mak
   QEMU_INCLUDES="-I\$(SRC_PATH)/slirp $QEMU_INCLUDES"
 fi
 if test "$vde" = "yes" ; then
diff --git a/net.h b/net.h
index 5a7881c..9f633f8 100644
--- a/net.h
+++ b/net.h
@@ -174,11 +174,6 @@ int do_netdev_del(Monitor *mon, const QDict *qdict, QObject **ret_data);
 
 #define DEFAULT_NETWORK_SCRIPT "/etc/qemu-ifup"
 #define DEFAULT_NETWORK_DOWN_SCRIPT "/etc/qemu-ifdown"
-#ifdef __sun__
-#define SMBD_COMMAND "/usr/sfw/sbin/smbd"
-#else
-#define SMBD_COMMAND "/usr/sbin/smbd"
-#endif
 
 void qdev_set_nic_properties(DeviceState *dev, NICInfo *nd);
 
diff --git a/net/slirp.c b/net/slirp.c
index 3b39d21..c6cda5d 100644
--- a/net/slirp.c
+++ b/net/slirp.c
@@ -529,7 +529,7 @@ static int slirp_smb(SlirpState* s, const char *exported_dir,
     fclose(f);
 
     snprintf(smb_cmdline, sizeof(smb_cmdline), "%s -s %s",
-             SMBD_COMMAND, smb_conf);
+             CONFIG_SMBD_COMMAND, smb_conf);
 
     if (slirp_add_exec(s->slirp, 0, smb_cmdline, &vserver_addr, 139) < 0) {
         slirp_smb_cleanup(s);
diff --git a/qemu-options.hx b/qemu-options.hx
index f672365..659ecb2 100644
--- a/qemu-options.hx
+++ b/qemu-options.hx
@@ -1277,9 +1277,9 @@ or @file{C:\WINNT\SYSTEM32\DRIVERS\ETC\LMHOSTS} (Windows NT/2000).
 
 Then @file{@var{dir}} can be accessed in @file{\\smbserver\qemu}.
 
-Note that a SAMBA server must be installed on the host OS in
- at file{/usr/sbin/smbd}. QEMU was tested successfully with smbd versions from
-Red Hat 9, Fedora Core 3 and OpenSUSE 11.x.
+Note that a SAMBA server must be installed on the host OS.
+QEMU was tested successfully with smbd versions from Red Hat 9,
+Fedora Core 3 and OpenSUSE 11.x.
 
 @item hostfwd=[tcp|udp]:[@var{hostaddr}]:@var{hostport}-[@var{guestaddr}]:@var{guestport}
 Redirect incoming TCP or UDP connections to the host port @var{hostport} to
commit 541dc0d47f10973c241e9955afc2aefc96adec51
Author: Stefan Weil <weil at mail.berlios.de>
Date:   Wed Aug 31 12:38:01 2011 +0200

    Use new macro QEMU_PACKED for packed structures
    
    Most changes were made using these commands:
    
    git grep -la '__attribute__((packed))'|xargs perl -pi -e 's/__attribute__\(\(packed\)\)/QEMU_PACKED/'
    git grep -la '__attribute__ ((packed))'|xargs perl -pi -e 's/__attribute__ \(\(packed\)\)/QEMU_PACKED/'
    git grep -la '__attribute__((__packed__))'|xargs perl -pi -e 's/__attribute__\(\(__packed__\)\)/QEMU_PACKED/'
    git grep -la '__attribute__ ((__packed__))'|xargs perl -pi -e 's/__attribute__ \(\(__packed__\)\)/QEMU_PACKED/'
    git grep -la '__attribute((packed))'|xargs perl -pi -e 's/__attribute\(\(packed\)\)/QEMU_PACKED/'
    
    Whitespace in linux-user/syscall_defs.h was fixed manually
    to avoid warnings from scripts/checkpatch.pl.
    
    Manual changes were also applied to hw/pc.c.
    
    I did not fix indentation with tabs in block/vvfat.c.
    The patch will show 4 errors with scripts/checkpatch.pl.
    
    Signed-off-by: Stefan Weil <weil at mail.berlios.de>
    Signed-off-by: Blue Swirl <blauwirbel at gmail.com>

diff --git a/a.out.h b/a.out.h
index dfc104e..33ca7f7 100644
--- a/a.out.h
+++ b/a.out.h
@@ -151,7 +151,7 @@ struct external_lineno {
 #define E_FILNMLEN	14	/* # characters in a file name		*/
 #define E_DIMNUM	4	/* # array dimensions in auxiliary entry */
 
-struct __attribute__((packed)) external_syment
+struct QEMU_PACKED external_syment
 {
   union {
     char e_name[E_SYMNMLEN];
diff --git a/block.c b/block.c
index 03a21d8..43742b7 100644
--- a/block.c
+++ b/block.c
@@ -1327,7 +1327,7 @@ struct partition {
         uint8_t end_cyl;            /* end cylinder */
         uint32_t start_sect;        /* starting sector counting from 0 */
         uint32_t nr_sects;          /* nr of sectors in partition */
-} __attribute__((packed));
+} QEMU_PACKED;
 
 /* try to guess the disk logical geometry from the MSDOS partition table. Return 0 if OK, -1 if could not guess */
 static int guess_disk_lchs(BlockDriverState *bs,
diff --git a/block/parallels.c b/block/parallels.c
index 37d151d..c64103d 100644
--- a/block/parallels.c
+++ b/block/parallels.c
@@ -43,7 +43,7 @@ struct parallels_header {
     uint32_t catalog_entries;
     uint32_t nb_sectors;
     char padding[24];
-} __attribute__((packed));
+} QEMU_PACKED;
 
 typedef struct BDRVParallelsState {
 
diff --git a/block/qcow2-snapshot.c b/block/qcow2-snapshot.c
index 3e6bf8b..bdc33ba 100644
--- a/block/qcow2-snapshot.c
+++ b/block/qcow2-snapshot.c
@@ -26,7 +26,7 @@
 #include "block_int.h"
 #include "block/qcow2.h"
 
-typedef struct __attribute__((packed)) QCowSnapshotHeader {
+typedef struct QEMU_PACKED QCowSnapshotHeader {
     /* header is 8 byte aligned */
     uint64_t l1_table_offset;
 
diff --git a/block/vmdk.c b/block/vmdk.c
index 8da87ac..5f673e9 100644
--- a/block/vmdk.c
+++ b/block/vmdk.c
@@ -56,7 +56,7 @@ typedef struct {
     int64_t grain_offset;
     char filler[1];
     char check_bytes[4];
-} __attribute__((packed)) VMDK4Header;
+} QEMU_PACKED VMDK4Header;
 
 #define L2_CACHE_SIZE 16
 
diff --git a/block/vvfat.c b/block/vvfat.c
index d6a07ef..187ac96 100644
--- a/block/vvfat.c
+++ b/block/vvfat.c
@@ -200,7 +200,7 @@ static int array_index(array_t* array, void* pointer)
 }
 
 /* These structures are used to fake a disk and the VFAT filesystem.
- * For this reason we need to use __attribute__((packed)). */
+ * For this reason we need to use QEMU_PACKED. */
 
 typedef struct bootsector_t {
     uint8_t jump[3];
@@ -224,7 +224,7 @@ typedef struct bootsector_t {
 	    uint8_t signature;
 	    uint32_t id;
 	    uint8_t volume_label[11];
-	} __attribute__((packed)) fat16;
+	} QEMU_PACKED fat16;
 	struct {
 	    uint32_t sectors_per_fat;
 	    uint16_t flags;
@@ -233,12 +233,12 @@ typedef struct bootsector_t {
 	    uint16_t info_sector;
 	    uint16_t backup_boot_sector;
 	    uint16_t ignored;
-	} __attribute__((packed)) fat32;
+	} QEMU_PACKED fat32;
     } u;
     uint8_t fat_type[8];
     uint8_t ignored[0x1c0];
     uint8_t magic[2];
-} __attribute__((packed)) bootsector_t;
+} QEMU_PACKED bootsector_t;
 
 typedef struct {
     uint8_t head;
@@ -253,7 +253,7 @@ typedef struct partition_t {
     mbr_chs_t end_CHS;
     uint32_t start_sector_long;
     uint32_t length_sector_long;
-} __attribute__((packed)) partition_t;
+} QEMU_PACKED partition_t;
 
 typedef struct mbr_t {
     uint8_t ignored[0x1b8];
@@ -261,7 +261,7 @@ typedef struct mbr_t {
     uint8_t ignored2[2];
     partition_t partition[4];
     uint8_t magic[2];
-} __attribute__((packed)) mbr_t;
+} QEMU_PACKED mbr_t;
 
 typedef struct direntry_t {
     uint8_t name[8];
@@ -276,7 +276,7 @@ typedef struct direntry_t {
     uint16_t mdate;
     uint16_t begin;
     uint32_t size;
-} __attribute__((packed)) direntry_t;
+} QEMU_PACKED direntry_t;
 
 /* this structure are used to transparently access the files */
 
diff --git a/hw/9pfs/virtio-9p.h b/hw/9pfs/virtio-9p.h
index 1d8c1b1..d00a502 100644
--- a/hw/9pfs/virtio-9p.h
+++ b/hw/9pfs/virtio-9p.h
@@ -314,7 +314,7 @@ struct virtio_9p_config
     uint16_t tag_len;
     /* Variable size tag name */
     uint8_t tag[0];
-} __attribute__((packed));
+} QEMU_PACKED;
 
 typedef struct V9fsMkState {
     V9fsPDU *pdu;
diff --git a/hw/acpi.c b/hw/acpi.c
index d04b965..1cf35e1 100644
--- a/hw/acpi.c
+++ b/hw/acpi.c
@@ -32,7 +32,7 @@ struct acpi_table_header {
     uint32_t oem_revision;    /* OEM revision number */
     char asl_compiler_id[4];  /* ASL compiler vendor ID */
     uint32_t asl_compiler_revision; /* ASL compiler revision number */
-} __attribute__((packed));
+} QEMU_PACKED;
 
 #define ACPI_TABLE_HDR_SIZE sizeof(struct acpi_table_header)
 #define ACPI_TABLE_PFX_SIZE sizeof(uint16_t)  /* size of the extra prefix */
diff --git a/hw/bt.h b/hw/bt.h
index 3797254..a48b8d4 100644
--- a/hw/bt.h
+++ b/hw/bt.h
@@ -26,7 +26,7 @@
 /* BD Address */
 typedef struct {
     uint8_t b[6];
-} __attribute__((packed)) bdaddr_t;
+} QEMU_PACKED bdaddr_t;
 
 #define BDADDR_ANY	(&(bdaddr_t) {{0, 0, 0, 0, 0, 0}})
 #define BDADDR_ALL	(&(bdaddr_t) {{0xff, 0xff, 0xff, 0xff, 0xff, 0xff}})
@@ -446,13 +446,13 @@ typedef struct {
     uint8_t	lap[3];
     uint8_t	length;		/* 1.28s units */
     uint8_t	num_rsp;
-} __attribute__ ((packed)) inquiry_cp;
+} QEMU_PACKED inquiry_cp;
 #define INQUIRY_CP_SIZE 5
 
 typedef struct {
     uint8_t		status;
     bdaddr_t	bdaddr;
-} __attribute__ ((packed)) status_bdaddr_rp;
+} QEMU_PACKED status_bdaddr_rp;
 #define STATUS_BDADDR_RP_SIZE 7
 
 #define OCF_INQUIRY_CANCEL		0x0002
@@ -464,7 +464,7 @@ typedef struct {
     uint8_t	lap[3];
     uint8_t	length;		/* 1.28s units */
     uint8_t	num_rsp;
-} __attribute__ ((packed)) periodic_inquiry_cp;
+} QEMU_PACKED periodic_inquiry_cp;
 #define PERIODIC_INQUIRY_CP_SIZE 9
 
 #define OCF_EXIT_PERIODIC_INQUIRY	0x0004
@@ -477,55 +477,55 @@ typedef struct {
     uint8_t	pscan_mode;
     uint16_t	clock_offset;
     uint8_t	role_switch;
-} __attribute__ ((packed)) create_conn_cp;
+} QEMU_PACKED create_conn_cp;
 #define CREATE_CONN_CP_SIZE 13
 
 #define OCF_DISCONNECT			0x0006
 typedef struct {
     uint16_t	handle;
     uint8_t	reason;
-} __attribute__ ((packed)) disconnect_cp;
+} QEMU_PACKED disconnect_cp;
 #define DISCONNECT_CP_SIZE 3
 
 #define OCF_ADD_SCO			0x0007
 typedef struct {
     uint16_t	handle;
     uint16_t	pkt_type;
-} __attribute__ ((packed)) add_sco_cp;
+} QEMU_PACKED add_sco_cp;
 #define ADD_SCO_CP_SIZE 4
 
 #define OCF_CREATE_CONN_CANCEL		0x0008
 typedef struct {
     uint8_t	status;
     bdaddr_t	bdaddr;
-} __attribute__ ((packed)) create_conn_cancel_cp;
+} QEMU_PACKED create_conn_cancel_cp;
 #define CREATE_CONN_CANCEL_CP_SIZE 6
 
 typedef struct {
     uint8_t	status;
     bdaddr_t	bdaddr;
-} __attribute__ ((packed)) create_conn_cancel_rp;
+} QEMU_PACKED create_conn_cancel_rp;
 #define CREATE_CONN_CANCEL_RP_SIZE 7
 
 #define OCF_ACCEPT_CONN_REQ		0x0009
 typedef struct {
     bdaddr_t	bdaddr;
     uint8_t	role;
-} __attribute__ ((packed)) accept_conn_req_cp;
+} QEMU_PACKED accept_conn_req_cp;
 #define ACCEPT_CONN_REQ_CP_SIZE	7
 
 #define OCF_REJECT_CONN_REQ		0x000A
 typedef struct {
     bdaddr_t	bdaddr;
     uint8_t	reason;
-} __attribute__ ((packed)) reject_conn_req_cp;
+} QEMU_PACKED reject_conn_req_cp;
 #define REJECT_CONN_REQ_CP_SIZE	7
 
 #define OCF_LINK_KEY_REPLY		0x000B
 typedef struct {
     bdaddr_t	bdaddr;
     uint8_t	link_key[16];
-} __attribute__ ((packed)) link_key_reply_cp;
+} QEMU_PACKED link_key_reply_cp;
 #define LINK_KEY_REPLY_CP_SIZE 22
 
 #define OCF_LINK_KEY_NEG_REPLY		0x000C
@@ -535,7 +535,7 @@ typedef struct {
     bdaddr_t	bdaddr;
     uint8_t	pin_len;
     uint8_t	pin_code[16];
-} __attribute__ ((packed)) pin_code_reply_cp;
+} QEMU_PACKED pin_code_reply_cp;
 #define PIN_CODE_REPLY_CP_SIZE 23
 
 #define OCF_PIN_CODE_NEG_REPLY		0x000E
@@ -544,32 +544,32 @@ typedef struct {
 typedef struct {
     uint16_t	 handle;
     uint16_t	 pkt_type;
-} __attribute__ ((packed)) set_conn_ptype_cp;
+} QEMU_PACKED set_conn_ptype_cp;
 #define SET_CONN_PTYPE_CP_SIZE 4
 
 #define OCF_AUTH_REQUESTED		0x0011
 typedef struct {
     uint16_t	 handle;
-} __attribute__ ((packed)) auth_requested_cp;
+} QEMU_PACKED auth_requested_cp;
 #define AUTH_REQUESTED_CP_SIZE 2
 
 #define OCF_SET_CONN_ENCRYPT		0x0013
 typedef struct {
     uint16_t	handle;
     uint8_t	encrypt;
-} __attribute__ ((packed)) set_conn_encrypt_cp;
+} QEMU_PACKED set_conn_encrypt_cp;
 #define SET_CONN_ENCRYPT_CP_SIZE 3
 
 #define OCF_CHANGE_CONN_LINK_KEY	0x0015
 typedef struct {
     uint16_t	handle;
-} __attribute__ ((packed)) change_conn_link_key_cp;
+} QEMU_PACKED change_conn_link_key_cp;
 #define CHANGE_CONN_LINK_KEY_CP_SIZE 2
 
 #define OCF_MASTER_LINK_KEY		0x0017
 typedef struct {
     uint8_t	key_flag;
-} __attribute__ ((packed)) master_link_key_cp;
+} QEMU_PACKED master_link_key_cp;
 #define MASTER_LINK_KEY_CP_SIZE 1
 
 #define OCF_REMOTE_NAME_REQ		0x0019
@@ -578,50 +578,50 @@ typedef struct {
     uint8_t	pscan_rep_mode;
     uint8_t	pscan_mode;
     uint16_t	clock_offset;
-} __attribute__ ((packed)) remote_name_req_cp;
+} QEMU_PACKED remote_name_req_cp;
 #define REMOTE_NAME_REQ_CP_SIZE 10
 
 #define OCF_REMOTE_NAME_REQ_CANCEL	0x001A
 typedef struct {
     bdaddr_t	bdaddr;
-} __attribute__ ((packed)) remote_name_req_cancel_cp;
+} QEMU_PACKED remote_name_req_cancel_cp;
 #define REMOTE_NAME_REQ_CANCEL_CP_SIZE 6
 
 typedef struct {
     uint8_t		status;
     bdaddr_t	bdaddr;
-} __attribute__ ((packed)) remote_name_req_cancel_rp;
+} QEMU_PACKED remote_name_req_cancel_rp;
 #define REMOTE_NAME_REQ_CANCEL_RP_SIZE 7
 
 #define OCF_READ_REMOTE_FEATURES	0x001B
 typedef struct {
     uint16_t	handle;
-} __attribute__ ((packed)) read_remote_features_cp;
+} QEMU_PACKED read_remote_features_cp;
 #define READ_REMOTE_FEATURES_CP_SIZE 2
 
 #define OCF_READ_REMOTE_EXT_FEATURES	0x001C
 typedef struct {
     uint16_t	handle;
     uint8_t	page_num;
-} __attribute__ ((packed)) read_remote_ext_features_cp;
+} QEMU_PACKED read_remote_ext_features_cp;
 #define READ_REMOTE_EXT_FEATURES_CP_SIZE 3
 
 #define OCF_READ_REMOTE_VERSION		0x001D
 typedef struct {
     uint16_t	handle;
-} __attribute__ ((packed)) read_remote_version_cp;
+} QEMU_PACKED read_remote_version_cp;
 #define READ_REMOTE_VERSION_CP_SIZE 2
 
 #define OCF_READ_CLOCK_OFFSET		0x001F
 typedef struct {
     uint16_t	handle;
-} __attribute__ ((packed)) read_clock_offset_cp;
+} QEMU_PACKED read_clock_offset_cp;
 #define READ_CLOCK_OFFSET_CP_SIZE 2
 
 #define OCF_READ_LMP_HANDLE		0x0020
 typedef struct {
     uint16_t	handle;
-} __attribute__ ((packed)) read_lmp_handle_cp;
+} QEMU_PACKED read_lmp_handle_cp;
 #define READ_LMP_HANDLE_CP_SIZE 2
 
 typedef struct {
@@ -629,7 +629,7 @@ typedef struct {
     uint16_t	handle;
     uint8_t	lmp_handle;
     uint32_t	reserved;
-} __attribute__ ((packed)) read_lmp_handle_rp;
+} QEMU_PACKED read_lmp_handle_rp;
 #define READ_LMP_HANDLE_RP_SIZE 8
 
 #define OCF_SETUP_SYNC_CONN		0x0028
@@ -641,7 +641,7 @@ typedef struct {
     uint16_t	voice_setting;
     uint8_t	retrans_effort;
     uint16_t	pkt_type;
-} __attribute__ ((packed)) setup_sync_conn_cp;
+} QEMU_PACKED setup_sync_conn_cp;
 #define SETUP_SYNC_CONN_CP_SIZE 17
 
 #define OCF_ACCEPT_SYNC_CONN_REQ	0x0029
@@ -653,14 +653,14 @@ typedef struct {
     uint16_t	voice_setting;
     uint8_t	retrans_effort;
     uint16_t	pkt_type;
-} __attribute__ ((packed)) accept_sync_conn_req_cp;
+} QEMU_PACKED accept_sync_conn_req_cp;
 #define ACCEPT_SYNC_CONN_REQ_CP_SIZE 21
 
 #define OCF_REJECT_SYNC_CONN_REQ	0x002A
 typedef struct {
     bdaddr_t	bdaddr;
     uint8_t	reason;
-} __attribute__ ((packed)) reject_sync_conn_req_cp;
+} QEMU_PACKED reject_sync_conn_req_cp;
 #define REJECT_SYNC_CONN_REQ_CP_SIZE 7
 
 /* Link Policy */
@@ -671,7 +671,7 @@ typedef struct {
     uint16_t	handle;
     uint16_t	max_interval;
     uint16_t	min_interval;
-} __attribute__ ((packed)) hold_mode_cp;
+} QEMU_PACKED hold_mode_cp;
 #define HOLD_MODE_CP_SIZE 6
 
 #define OCF_SNIFF_MODE			0x0003
@@ -681,13 +681,13 @@ typedef struct {
     uint16_t	min_interval;
     uint16_t	attempt;
     uint16_t	timeout;
-} __attribute__ ((packed)) sniff_mode_cp;
+} QEMU_PACKED sniff_mode_cp;
 #define SNIFF_MODE_CP_SIZE 10
 
 #define OCF_EXIT_SNIFF_MODE		0x0004
 typedef struct {
     uint16_t	handle;
-} __attribute__ ((packed)) exit_sniff_mode_cp;
+} QEMU_PACKED exit_sniff_mode_cp;
 #define EXIT_SNIFF_MODE_CP_SIZE 2
 
 #define OCF_PARK_MODE			0x0005
@@ -695,13 +695,13 @@ typedef struct {
     uint16_t	handle;
     uint16_t	max_interval;
     uint16_t	min_interval;
-} __attribute__ ((packed)) park_mode_cp;
+} QEMU_PACKED park_mode_cp;
 #define PARK_MODE_CP_SIZE 6
 
 #define OCF_EXIT_PARK_MODE		0x0006
 typedef struct {
     uint16_t	handle;
-} __attribute__ ((packed)) exit_park_mode_cp;
+} QEMU_PACKED exit_park_mode_cp;
 #define EXIT_PARK_MODE_CP_SIZE 2
 
 #define OCF_QOS_SETUP			0x0007
@@ -711,56 +711,56 @@ typedef struct {
     uint32_t	peak_bandwidth;		/* Byte per seconds */
     uint32_t	latency;		/* Microseconds */
     uint32_t	delay_variation;	/* Microseconds */
-} __attribute__ ((packed)) hci_qos;
+} QEMU_PACKED hci_qos;
 #define HCI_QOS_CP_SIZE 17
 typedef struct {
     uint16_t 	handle;
     uint8_t 	flags;			/* Reserved */
     hci_qos 	qos;
-} __attribute__ ((packed)) qos_setup_cp;
+} QEMU_PACKED qos_setup_cp;
 #define QOS_SETUP_CP_SIZE (3 + HCI_QOS_CP_SIZE)
 
 #define OCF_ROLE_DISCOVERY		0x0009
 typedef struct {
     uint16_t	handle;
-} __attribute__ ((packed)) role_discovery_cp;
+} QEMU_PACKED role_discovery_cp;
 #define ROLE_DISCOVERY_CP_SIZE 2
 typedef struct {
     uint8_t	status;
     uint16_t	handle;
     uint8_t	role;
-} __attribute__ ((packed)) role_discovery_rp;
+} QEMU_PACKED role_discovery_rp;
 #define ROLE_DISCOVERY_RP_SIZE 4
 
 #define OCF_SWITCH_ROLE			0x000B
 typedef struct {
     bdaddr_t	bdaddr;
     uint8_t	role;
-} __attribute__ ((packed)) switch_role_cp;
+} QEMU_PACKED switch_role_cp;
 #define SWITCH_ROLE_CP_SIZE 7
 
 #define OCF_READ_LINK_POLICY		0x000C
 typedef struct {
     uint16_t	handle;
-} __attribute__ ((packed)) read_link_policy_cp;
+} QEMU_PACKED read_link_policy_cp;
 #define READ_LINK_POLICY_CP_SIZE 2
 typedef struct {
     uint8_t 	status;
     uint16_t	handle;
     uint16_t	policy;
-} __attribute__ ((packed)) read_link_policy_rp;
+} QEMU_PACKED read_link_policy_rp;
 #define READ_LINK_POLICY_RP_SIZE 5
 
 #define OCF_WRITE_LINK_POLICY		0x000D
 typedef struct {
     uint16_t	handle;
     uint16_t	policy;
-} __attribute__ ((packed)) write_link_policy_cp;
+} QEMU_PACKED write_link_policy_cp;
 #define WRITE_LINK_POLICY_CP_SIZE 4
 typedef struct {
     uint8_t 	status;
     uint16_t	handle;
-} __attribute__ ((packed)) write_link_policy_rp;
+} QEMU_PACKED write_link_policy_rp;
 #define WRITE_LINK_POLICY_RP_SIZE 3
 
 #define OCF_READ_DEFAULT_LINK_POLICY	0x000E
@@ -776,7 +776,7 @@ typedef struct {
     uint16_t	max_local_latency;
     uint16_t	min_remote_timeout;
     uint16_t	min_local_timeout;
-} __attribute__ ((packed)) sniff_subrate_cp;
+} QEMU_PACKED sniff_subrate_cp;
 #define SNIFF_SUBRATE_CP_SIZE 10
 
 /* Host Controller and Baseband */
@@ -785,7 +785,7 @@ typedef struct {
 #define OCF_SET_EVENT_MASK		0x0001
 typedef struct {
     uint8_t	mask[8];
-} __attribute__ ((packed)) set_event_mask_cp;
+} QEMU_PACKED set_event_mask_cp;
 #define SET_EVENT_MASK_CP_SIZE 8
 
 #define OCF_RESET			0x0003
@@ -795,7 +795,7 @@ typedef struct {
     uint8_t	flt_type;
     uint8_t	cond_type;
     uint8_t	condition[0];
-} __attribute__ ((packed)) set_event_flt_cp;
+} QEMU_PACKED set_event_flt_cp;
 #define SET_EVENT_FLT_CP_SIZE 2
 
 enum bt_filter_type {
@@ -821,26 +821,26 @@ enum conn_setup_cond {
 #define OCF_FLUSH			0x0008
 typedef struct {
     uint16_t	handle;
-} __attribute__ ((packed)) flush_cp;
+} QEMU_PACKED flush_cp;
 #define FLUSH_CP_SIZE 2
 
 typedef struct {
     uint8_t	status;
     uint16_t	handle;
-} __attribute__ ((packed)) flush_rp;
+} QEMU_PACKED flush_rp;
 #define FLUSH_RP_SIZE 3
 
 #define OCF_READ_PIN_TYPE		0x0009
 typedef struct {
     uint8_t	status;
     uint8_t	pin_type;
-} __attribute__ ((packed)) read_pin_type_rp;
+} QEMU_PACKED read_pin_type_rp;
 #define READ_PIN_TYPE_RP_SIZE 2
 
 #define OCF_WRITE_PIN_TYPE		0x000A
 typedef struct {
     uint8_t	pin_type;
-} __attribute__ ((packed)) write_pin_type_cp;
+} QEMU_PACKED write_pin_type_cp;
 #define WRITE_PIN_TYPE_CP_SIZE 1
 
 #define OCF_CREATE_NEW_UNIT_KEY		0x000B
@@ -849,89 +849,89 @@ typedef struct {
 typedef struct {
     bdaddr_t	bdaddr;
     uint8_t	read_all;
-} __attribute__ ((packed)) read_stored_link_key_cp;
+} QEMU_PACKED read_stored_link_key_cp;
 #define READ_STORED_LINK_KEY_CP_SIZE 7
 typedef struct {
     uint8_t	status;
     uint16_t	max_keys;
     uint16_t	num_keys;
-} __attribute__ ((packed)) read_stored_link_key_rp;
+} QEMU_PACKED read_stored_link_key_rp;
 #define READ_STORED_LINK_KEY_RP_SIZE 5
 
 #define OCF_WRITE_STORED_LINK_KEY	0x0011
 typedef struct {
     uint8_t	num_keys;
     /* variable length part */
-} __attribute__ ((packed)) write_stored_link_key_cp;
+} QEMU_PACKED write_stored_link_key_cp;
 #define WRITE_STORED_LINK_KEY_CP_SIZE 1
 typedef struct {
     uint8_t	status;
     uint8_t	num_keys;
-} __attribute__ ((packed)) write_stored_link_key_rp;
+} QEMU_PACKED write_stored_link_key_rp;
 #define READ_WRITE_LINK_KEY_RP_SIZE 2
 
 #define OCF_DELETE_STORED_LINK_KEY	0x0012
 typedef struct {
     bdaddr_t	bdaddr;
     uint8_t	delete_all;
-} __attribute__ ((packed)) delete_stored_link_key_cp;
+} QEMU_PACKED delete_stored_link_key_cp;
 #define DELETE_STORED_LINK_KEY_CP_SIZE 7
 typedef struct {
     uint8_t	status;
     uint16_t	num_keys;
-} __attribute__ ((packed)) delete_stored_link_key_rp;
+} QEMU_PACKED delete_stored_link_key_rp;
 #define DELETE_STORED_LINK_KEY_RP_SIZE 3
 
 #define OCF_CHANGE_LOCAL_NAME		0x0013
 typedef struct {
     char	name[248];
-} __attribute__ ((packed)) change_local_name_cp;
+} QEMU_PACKED change_local_name_cp;
 #define CHANGE_LOCAL_NAME_CP_SIZE 248 
 
 #define OCF_READ_LOCAL_NAME		0x0014
 typedef struct {
     uint8_t	status;
     char	name[248];
-} __attribute__ ((packed)) read_local_name_rp;
+} QEMU_PACKED read_local_name_rp;
 #define READ_LOCAL_NAME_RP_SIZE 249 
 
 #define OCF_READ_CONN_ACCEPT_TIMEOUT	0x0015
 typedef struct {
     uint8_t	status;
     uint16_t	timeout;
-} __attribute__ ((packed)) read_conn_accept_timeout_rp;
+} QEMU_PACKED read_conn_accept_timeout_rp;
 #define READ_CONN_ACCEPT_TIMEOUT_RP_SIZE 3
 
 #define OCF_WRITE_CONN_ACCEPT_TIMEOUT	0x0016
 typedef struct {
     uint16_t	timeout;
-} __attribute__ ((packed)) write_conn_accept_timeout_cp;
+} QEMU_PACKED write_conn_accept_timeout_cp;
 #define WRITE_CONN_ACCEPT_TIMEOUT_CP_SIZE 2
 
 #define OCF_READ_PAGE_TIMEOUT		0x0017
 typedef struct {
     uint8_t	status;
     uint16_t	timeout;
-} __attribute__ ((packed)) read_page_timeout_rp;
+} QEMU_PACKED read_page_timeout_rp;
 #define READ_PAGE_TIMEOUT_RP_SIZE 3
 
 #define OCF_WRITE_PAGE_TIMEOUT		0x0018
 typedef struct {
     uint16_t	timeout;
-} __attribute__ ((packed)) write_page_timeout_cp;
+} QEMU_PACKED write_page_timeout_cp;
 #define WRITE_PAGE_TIMEOUT_CP_SIZE 2
 
 #define OCF_READ_SCAN_ENABLE		0x0019
 typedef struct {
     uint8_t	status;
     uint8_t	enable;
-} __attribute__ ((packed)) read_scan_enable_rp;
+} QEMU_PACKED read_scan_enable_rp;
 #define READ_SCAN_ENABLE_RP_SIZE 2
 
 #define OCF_WRITE_SCAN_ENABLE		0x001A
 typedef struct {
     uint8_t	scan_enable;
-} __attribute__ ((packed)) write_scan_enable_cp;
+} QEMU_PACKED write_scan_enable_cp;
 #define WRITE_SCAN_ENABLE_CP_SIZE 1
 
 enum scan_enable_bits {
@@ -945,14 +945,14 @@ typedef struct {
     uint8_t	status;
     uint16_t	interval;
     uint16_t	window;
-} __attribute__ ((packed)) read_page_activity_rp;
+} QEMU_PACKED read_page_activity_rp;
 #define READ_PAGE_ACTIVITY_RP_SIZE 5
 
 #define OCF_WRITE_PAGE_ACTIVITY		0x001C
 typedef struct {
     uint16_t	interval;
     uint16_t	window;
-} __attribute__ ((packed)) write_page_activity_cp;
+} QEMU_PACKED write_page_activity_cp;
 #define WRITE_PAGE_ACTIVITY_CP_SIZE 4
 
 #define OCF_READ_INQ_ACTIVITY		0x001D
@@ -960,14 +960,14 @@ typedef struct {
     uint8_t	status;
     uint16_t	interval;
     uint16_t	window;
-} __attribute__ ((packed)) read_inq_activity_rp;
+} QEMU_PACKED read_inq_activity_rp;
 #define READ_INQ_ACTIVITY_RP_SIZE 5
 
 #define OCF_WRITE_INQ_ACTIVITY		0x001E
 typedef struct {
     uint16_t	interval;
     uint16_t	window;
-} __attribute__ ((packed)) write_inq_activity_cp;
+} QEMU_PACKED write_inq_activity_cp;
 #define WRITE_INQ_ACTIVITY_CP_SIZE 4
 
 #define OCF_READ_AUTH_ENABLE		0x001F
@@ -989,26 +989,26 @@ typedef struct {
 typedef struct {
     uint8_t	status;
     uint8_t	dev_class[3];
-} __attribute__ ((packed)) read_class_of_dev_rp;
+} QEMU_PACKED read_class_of_dev_rp;
 #define READ_CLASS_OF_DEV_RP_SIZE 4 
 
 #define OCF_WRITE_CLASS_OF_DEV		0x0024
 typedef struct {
     uint8_t	dev_class[3];
-} __attribute__ ((packed)) write_class_of_dev_cp;
+} QEMU_PACKED write_class_of_dev_cp;
 #define WRITE_CLASS_OF_DEV_CP_SIZE 3
 
 #define OCF_READ_VOICE_SETTING		0x0025
 typedef struct {
     uint8_t	status;
     uint16_t	voice_setting;
-} __attribute__ ((packed)) read_voice_setting_rp;
+} QEMU_PACKED read_voice_setting_rp;
 #define READ_VOICE_SETTING_RP_SIZE 3
 
 #define OCF_WRITE_VOICE_SETTING		0x0026
 typedef struct {
     uint16_t	voice_setting;
-} __attribute__ ((packed)) write_voice_setting_cp;
+} QEMU_PACKED write_voice_setting_cp;
 #define WRITE_VOICE_SETTING_CP_SIZE 2
 
 #define OCF_READ_AUTOMATIC_FLUSH_TIMEOUT	0x0027
@@ -1027,13 +1027,13 @@ typedef struct {
 typedef struct {
     uint16_t	handle;
     uint8_t	type;
-} __attribute__ ((packed)) read_transmit_power_level_cp;
+} QEMU_PACKED read_transmit_power_level_cp;
 #define READ_TRANSMIT_POWER_LEVEL_CP_SIZE 3
 typedef struct {
     uint8_t	status;
     uint16_t	handle;
     int8_t	level;
-} __attribute__ ((packed)) read_transmit_power_level_rp;
+} QEMU_PACKED read_transmit_power_level_rp;
 #define READ_TRANSMIT_POWER_LEVEL_RP_SIZE 4
 
 #define OCF_HOST_BUFFER_SIZE		0x0033
@@ -1042,7 +1042,7 @@ typedef struct {
     uint8_t	sco_mtu;
     uint16_t	acl_max_pkt;
     uint16_t	sco_max_pkt;
-} __attribute__ ((packed)) host_buffer_size_cp;
+} QEMU_PACKED host_buffer_size_cp;
 #define HOST_BUFFER_SIZE_CP_SIZE 7
 
 #define OCF_HOST_NUMBER_OF_COMPLETED_PACKETS	0x0035
@@ -1052,19 +1052,19 @@ typedef struct {
     uint8_t	status;
     uint16_t	handle;
     uint16_t	link_sup_to;
-} __attribute__ ((packed)) read_link_supervision_timeout_rp;
+} QEMU_PACKED read_link_supervision_timeout_rp;
 #define READ_LINK_SUPERVISION_TIMEOUT_RP_SIZE 5
 
 #define OCF_WRITE_LINK_SUPERVISION_TIMEOUT	0x0037
 typedef struct {
     uint16_t	handle;
     uint16_t	link_sup_to;
-} __attribute__ ((packed)) write_link_supervision_timeout_cp;
+} QEMU_PACKED write_link_supervision_timeout_cp;
 #define WRITE_LINK_SUPERVISION_TIMEOUT_CP_SIZE 4
 typedef struct {
     uint8_t	status;
     uint16_t	handle;
-} __attribute__ ((packed)) write_link_supervision_timeout_rp;
+} QEMU_PACKED write_link_supervision_timeout_rp;
 #define WRITE_LINK_SUPERVISION_TIMEOUT_RP_SIZE 3
 
 #define OCF_READ_NUM_SUPPORTED_IAC	0x0038
@@ -1075,14 +1075,14 @@ typedef struct {
     uint8_t	status;
     uint8_t	num_current_iac;
     uint8_t	lap[MAX_IAC_LAP][3];
-} __attribute__ ((packed)) read_current_iac_lap_rp;
+} QEMU_PACKED read_current_iac_lap_rp;
 #define READ_CURRENT_IAC_LAP_RP_SIZE 2+3*MAX_IAC_LAP
 
 #define OCF_WRITE_CURRENT_IAC_LAP	0x003A
 typedef struct {
     uint8_t	num_current_iac;
     uint8_t	lap[MAX_IAC_LAP][3];
-} __attribute__ ((packed)) write_current_iac_lap_cp;
+} QEMU_PACKED write_current_iac_lap_cp;
 #define WRITE_CURRENT_IAC_LAP_CP_SIZE 1+3*MAX_IAC_LAP
 
 #define OCF_READ_PAGE_SCAN_PERIOD_MODE	0x003B
@@ -1096,45 +1096,45 @@ typedef struct {
 #define OCF_SET_AFH_CLASSIFICATION	0x003F
 typedef struct {
     uint8_t	map[10];
-} __attribute__ ((packed)) set_afh_classification_cp;
+} QEMU_PACKED set_afh_classification_cp;
 #define SET_AFH_CLASSIFICATION_CP_SIZE 10
 typedef struct {
     uint8_t	status;
-} __attribute__ ((packed)) set_afh_classification_rp;
+} QEMU_PACKED set_afh_classification_rp;
 #define SET_AFH_CLASSIFICATION_RP_SIZE 1
 
 #define OCF_READ_INQUIRY_SCAN_TYPE	0x0042
 typedef struct {
     uint8_t	status;
     uint8_t	type;
-} __attribute__ ((packed)) read_inquiry_scan_type_rp;
+} QEMU_PACKED read_inquiry_scan_type_rp;
 #define READ_INQUIRY_SCAN_TYPE_RP_SIZE 2
 
 #define OCF_WRITE_INQUIRY_SCAN_TYPE	0x0043
 typedef struct {
     uint8_t	type;
-} __attribute__ ((packed)) write_inquiry_scan_type_cp;
+} QEMU_PACKED write_inquiry_scan_type_cp;
 #define WRITE_INQUIRY_SCAN_TYPE_CP_SIZE 1
 typedef struct {
     uint8_t	status;
-} __attribute__ ((packed)) write_inquiry_scan_type_rp;
+} QEMU_PACKED write_inquiry_scan_type_rp;
 #define WRITE_INQUIRY_SCAN_TYPE_RP_SIZE 1
 
 #define OCF_READ_INQUIRY_MODE		0x0044
 typedef struct {
     uint8_t	status;
     uint8_t	mode;
-} __attribute__ ((packed)) read_inquiry_mode_rp;
+} QEMU_PACKED read_inquiry_mode_rp;
 #define READ_INQUIRY_MODE_RP_SIZE 2
 
 #define OCF_WRITE_INQUIRY_MODE		0x0045
 typedef struct {
     uint8_t	mode;
-} __attribute__ ((packed)) write_inquiry_mode_cp;
+} QEMU_PACKED write_inquiry_mode_cp;
 #define WRITE_INQUIRY_MODE_CP_SIZE 1
 typedef struct {
     uint8_t	status;
-} __attribute__ ((packed)) write_inquiry_mode_rp;
+} QEMU_PACKED write_inquiry_mode_rp;
 #define WRITE_INQUIRY_MODE_RP_SIZE 1
 
 #define OCF_READ_PAGE_SCAN_TYPE		0x0046
@@ -1145,17 +1145,17 @@ typedef struct {
 typedef struct {
     uint8_t	status;
     uint8_t	mode;
-} __attribute__ ((packed)) read_afh_mode_rp;
+} QEMU_PACKED read_afh_mode_rp;
 #define READ_AFH_MODE_RP_SIZE 2
 
 #define OCF_WRITE_AFH_MODE		0x0049
 typedef struct {
     uint8_t	mode;
-} __attribute__ ((packed)) write_afh_mode_cp;
+} QEMU_PACKED write_afh_mode_cp;
 #define WRITE_AFH_MODE_CP_SIZE 1
 typedef struct {
     uint8_t	status;
-} __attribute__ ((packed)) write_afh_mode_rp;
+} QEMU_PACKED write_afh_mode_rp;
 #define WRITE_AFH_MODE_RP_SIZE 1
 
 #define OCF_READ_EXT_INQUIRY_RESPONSE	0x0051
@@ -1163,18 +1163,18 @@ typedef struct {
     uint8_t	status;
     uint8_t	fec;
     uint8_t	data[240];
-} __attribute__ ((packed)) read_ext_inquiry_response_rp;
+} QEMU_PACKED read_ext_inquiry_response_rp;
 #define READ_EXT_INQUIRY_RESPONSE_RP_SIZE 242
 
 #define OCF_WRITE_EXT_INQUIRY_RESPONSE	0x0052
 typedef struct {
     uint8_t	fec;
     uint8_t	data[240];
-} __attribute__ ((packed)) write_ext_inquiry_response_cp;
+} QEMU_PACKED write_ext_inquiry_response_cp;
 #define WRITE_EXT_INQUIRY_RESPONSE_CP_SIZE 241
 typedef struct {
     uint8_t	status;
-} __attribute__ ((packed)) write_ext_inquiry_response_rp;
+} QEMU_PACKED write_ext_inquiry_response_rp;
 #define WRITE_EXT_INQUIRY_RESPONSE_RP_SIZE 1
 
 /* Informational Parameters */
@@ -1188,34 +1188,34 @@ typedef struct {
     uint8_t	lmp_ver;
     uint16_t	manufacturer;
     uint16_t	lmp_subver;
-} __attribute__ ((packed)) read_local_version_rp;
+} QEMU_PACKED read_local_version_rp;
 #define READ_LOCAL_VERSION_RP_SIZE 9
 
 #define OCF_READ_LOCAL_COMMANDS		0x0002
 typedef struct {
     uint8_t	status;
     uint8_t	commands[64];
-} __attribute__ ((packed)) read_local_commands_rp;
+} QEMU_PACKED read_local_commands_rp;
 #define READ_LOCAL_COMMANDS_RP_SIZE 65
 
 #define OCF_READ_LOCAL_FEATURES		0x0003
 typedef struct {
     uint8_t	status;
     uint8_t	features[8];
-} __attribute__ ((packed)) read_local_features_rp;
+} QEMU_PACKED read_local_features_rp;
 #define READ_LOCAL_FEATURES_RP_SIZE 9
 
 #define OCF_READ_LOCAL_EXT_FEATURES	0x0004
 typedef struct {
     uint8_t	page_num;
-} __attribute__ ((packed)) read_local_ext_features_cp;
+} QEMU_PACKED read_local_ext_features_cp;
 #define READ_LOCAL_EXT_FEATURES_CP_SIZE 1
 typedef struct {
     uint8_t	status;
     uint8_t	page_num;
     uint8_t	max_page_num;
     uint8_t	features[8];
-} __attribute__ ((packed)) read_local_ext_features_rp;
+} QEMU_PACKED read_local_ext_features_rp;
 #define READ_LOCAL_EXT_FEATURES_RP_SIZE 11
 
 #define OCF_READ_BUFFER_SIZE		0x0005
@@ -1225,21 +1225,21 @@ typedef struct {
     uint8_t	sco_mtu;
     uint16_t	acl_max_pkt;
     uint16_t	sco_max_pkt;
-} __attribute__ ((packed)) read_buffer_size_rp;
+} QEMU_PACKED read_buffer_size_rp;
 #define READ_BUFFER_SIZE_RP_SIZE 8
 
 #define OCF_READ_COUNTRY_CODE		0x0007
 typedef struct {
     uint8_t	status;
     uint8_t	country_code;
-} __attribute__ ((packed)) read_country_code_rp;
+} QEMU_PACKED read_country_code_rp;
 #define READ_COUNTRY_CODE_RP_SIZE 2
 
 #define OCF_READ_BD_ADDR		0x0009
 typedef struct {
     uint8_t	status;
     bdaddr_t	bdaddr;
-} __attribute__ ((packed)) read_bd_addr_rp;
+} QEMU_PACKED read_bd_addr_rp;
 #define READ_BD_ADDR_RP_SIZE 7
 
 /* Status params */
@@ -1250,27 +1250,27 @@ typedef struct {
     uint8_t	status;
     uint16_t	handle;
     uint8_t	counter;
-} __attribute__ ((packed)) read_failed_contact_counter_rp;
+} QEMU_PACKED read_failed_contact_counter_rp;
 #define READ_FAILED_CONTACT_COUNTER_RP_SIZE 4
 
 #define OCF_RESET_FAILED_CONTACT_COUNTER	0x0002
 typedef struct {
     uint8_t	status;
     uint16_t	handle;
-} __attribute__ ((packed)) reset_failed_contact_counter_rp;
+} QEMU_PACKED reset_failed_contact_counter_rp;
 #define RESET_FAILED_CONTACT_COUNTER_RP_SIZE 4
 
 #define OCF_READ_LINK_QUALITY		0x0003
 typedef struct {
     uint16_t	handle;
-} __attribute__ ((packed)) read_link_quality_cp;
+} QEMU_PACKED read_link_quality_cp;
 #define READ_LINK_QUALITY_CP_SIZE 4
 
 typedef struct {
     uint8_t	status;
     uint16_t	handle;
     uint8_t	link_quality;
-} __attribute__ ((packed)) read_link_quality_rp;
+} QEMU_PACKED read_link_quality_rp;
 #define READ_LINK_QUALITY_RP_SIZE 4
 
 #define OCF_READ_RSSI			0x0005
@@ -1278,7 +1278,7 @@ typedef struct {
     uint8_t	status;
     uint16_t	handle;
     int8_t	rssi;
-} __attribute__ ((packed)) read_rssi_rp;
+} QEMU_PACKED read_rssi_rp;
 #define READ_RSSI_RP_SIZE 4
 
 #define OCF_READ_AFH_MAP		0x0006
@@ -1287,21 +1287,21 @@ typedef struct {
     uint16_t	handle;
     uint8_t	mode;
     uint8_t	map[10];
-} __attribute__ ((packed)) read_afh_map_rp;
+} QEMU_PACKED read_afh_map_rp;
 #define READ_AFH_MAP_RP_SIZE 14
 
 #define OCF_READ_CLOCK			0x0007
 typedef struct {
     uint16_t	handle;
     uint8_t	which_clock;
-} __attribute__ ((packed)) read_clock_cp;
+} QEMU_PACKED read_clock_cp;
 #define READ_CLOCK_CP_SIZE 3
 typedef struct {
     uint8_t	status;
     uint16_t	handle;
     uint32_t	clock;
     uint16_t	accuracy;
-} __attribute__ ((packed)) read_clock_rp;
+} QEMU_PACKED read_clock_rp;
 #define READ_CLOCK_RP_SIZE 9
 
 /* Testing commands */
@@ -1323,7 +1323,7 @@ typedef struct {
     uint8_t	pscan_mode;
     uint8_t	dev_class[3];
     uint16_t	clock_offset;
-} __attribute__ ((packed)) inquiry_info;
+} QEMU_PACKED inquiry_info;
 #define INQUIRY_INFO_SIZE 14
 
 #define EVT_CONN_COMPLETE		0x03
@@ -1333,7 +1333,7 @@ typedef struct {
     bdaddr_t	bdaddr;
     uint8_t	link_type;
     uint8_t	encr_mode;
-} __attribute__ ((packed)) evt_conn_complete;
+} QEMU_PACKED evt_conn_complete;
 #define EVT_CONN_COMPLETE_SIZE 11
 
 #define EVT_CONN_REQUEST		0x04
@@ -1341,7 +1341,7 @@ typedef struct {
     bdaddr_t	bdaddr;
     uint8_t	dev_class[3];
     uint8_t	link_type;
-} __attribute__ ((packed)) evt_conn_request;
+} QEMU_PACKED evt_conn_request;
 #define EVT_CONN_REQUEST_SIZE 10
 
 #define EVT_DISCONN_COMPLETE		0x05
@@ -1349,14 +1349,14 @@ typedef struct {
     uint8_t	status;
     uint16_t	handle;
     uint8_t	reason;
-} __attribute__ ((packed)) evt_disconn_complete;
+} QEMU_PACKED evt_disconn_complete;
 #define EVT_DISCONN_COMPLETE_SIZE 4
 
 #define EVT_AUTH_COMPLETE		0x06
 typedef struct {
     uint8_t	status;
     uint16_t	handle;
-} __attribute__ ((packed)) evt_auth_complete;
+} QEMU_PACKED evt_auth_complete;
 #define EVT_AUTH_COMPLETE_SIZE 3
 
 #define EVT_REMOTE_NAME_REQ_COMPLETE	0x07
@@ -1364,7 +1364,7 @@ typedef struct {
     uint8_t	status;
     bdaddr_t	bdaddr;
     char	name[248];
-} __attribute__ ((packed)) evt_remote_name_req_complete;
+} QEMU_PACKED evt_remote_name_req_complete;
 #define EVT_REMOTE_NAME_REQ_COMPLETE_SIZE 255
 
 #define EVT_ENCRYPT_CHANGE		0x08
@@ -1372,14 +1372,14 @@ typedef struct {
     uint8_t	status;
     uint16_t	handle;
     uint8_t	encrypt;
-} __attribute__ ((packed)) evt_encrypt_change;
+} QEMU_PACKED evt_encrypt_change;
 #define EVT_ENCRYPT_CHANGE_SIZE 5
 
 #define EVT_CHANGE_CONN_LINK_KEY_COMPLETE	0x09
 typedef struct {
     uint8_t	status;
     uint16_t	handle;
-}  __attribute__ ((packed)) evt_change_conn_link_key_complete;
+}  QEMU_PACKED evt_change_conn_link_key_complete;
 #define EVT_CHANGE_CONN_LINK_KEY_COMPLETE_SIZE 3
 
 #define EVT_MASTER_LINK_KEY_COMPLETE		0x0A
@@ -1387,7 +1387,7 @@ typedef struct {
     uint8_t	status;
     uint16_t	handle;
     uint8_t	key_flag;
-} __attribute__ ((packed)) evt_master_link_key_complete;
+} QEMU_PACKED evt_master_link_key_complete;
 #define EVT_MASTER_LINK_KEY_COMPLETE_SIZE 4
 
 #define EVT_READ_REMOTE_FEATURES_COMPLETE	0x0B
@@ -1395,7 +1395,7 @@ typedef struct {
     uint8_t	status;
     uint16_t	handle;
     uint8_t	features[8];
-} __attribute__ ((packed)) evt_read_remote_features_complete;
+} QEMU_PACKED evt_read_remote_features_complete;
 #define EVT_READ_REMOTE_FEATURES_COMPLETE_SIZE 11
 
 #define EVT_READ_REMOTE_VERSION_COMPLETE	0x0C
@@ -1405,7 +1405,7 @@ typedef struct {
     uint8_t	lmp_ver;
     uint16_t	manufacturer;
     uint16_t	lmp_subver;
-} __attribute__ ((packed)) evt_read_remote_version_complete;
+} QEMU_PACKED evt_read_remote_version_complete;
 #define EVT_READ_REMOTE_VERSION_COMPLETE_SIZE 8
 
 #define EVT_QOS_SETUP_COMPLETE		0x0D
@@ -1414,14 +1414,14 @@ typedef struct {
     uint16_t	handle;
     uint8_t	flags;			/* Reserved */
     hci_qos	qos;
-} __attribute__ ((packed)) evt_qos_setup_complete;
+} QEMU_PACKED evt_qos_setup_complete;
 #define EVT_QOS_SETUP_COMPLETE_SIZE (4 + HCI_QOS_CP_SIZE)
 
 #define EVT_CMD_COMPLETE 		0x0E
 typedef struct {
     uint8_t	ncmd;
     uint16_t	opcode;
-} __attribute__ ((packed)) evt_cmd_complete;
+} QEMU_PACKED evt_cmd_complete;
 #define EVT_CMD_COMPLETE_SIZE 3
 
 #define EVT_CMD_STATUS 			0x0F
@@ -1429,19 +1429,19 @@ typedef struct {
     uint8_t	status;
     uint8_t	ncmd;
     uint16_t	opcode;
-} __attribute__ ((packed)) evt_cmd_status;
+} QEMU_PACKED evt_cmd_status;
 #define EVT_CMD_STATUS_SIZE 4
 
 #define EVT_HARDWARE_ERROR		0x10
 typedef struct {
     uint8_t	code;
-} __attribute__ ((packed)) evt_hardware_error;
+} QEMU_PACKED evt_hardware_error;
 #define EVT_HARDWARE_ERROR_SIZE 1
 
 #define EVT_FLUSH_OCCURRED		0x11
 typedef struct {
     uint16_t	handle;
-} __attribute__ ((packed)) evt_flush_occurred;
+} QEMU_PACKED evt_flush_occurred;
 #define EVT_FLUSH_OCCURRED_SIZE 2
 
 #define EVT_ROLE_CHANGE			0x12
@@ -1449,7 +1449,7 @@ typedef struct {
     uint8_t	status;
     bdaddr_t	bdaddr;
     uint8_t	role;
-} __attribute__ ((packed)) evt_role_change;
+} QEMU_PACKED evt_role_change;
 #define EVT_ROLE_CHANGE_SIZE 8
 
 #define EVT_NUM_COMP_PKTS		0x13
@@ -1459,7 +1459,7 @@ typedef struct {
         uint16_t handle;
         uint16_t num_packets;
     } connection[0];
-} __attribute__ ((packed)) evt_num_comp_pkts;
+} QEMU_PACKED evt_num_comp_pkts;
 #define EVT_NUM_COMP_PKTS_SIZE(num_hndl) (1 + 4 * (num_hndl))
 
 #define EVT_MODE_CHANGE			0x14
@@ -1468,26 +1468,26 @@ typedef struct {
     uint16_t	handle;
     uint8_t	mode;
     uint16_t	interval;
-} __attribute__ ((packed)) evt_mode_change;
+} QEMU_PACKED evt_mode_change;
 #define EVT_MODE_CHANGE_SIZE 6
 
 #define EVT_RETURN_LINK_KEYS		0x15
 typedef struct {
     uint8_t	num_keys;
     /* variable length part */
-} __attribute__ ((packed)) evt_return_link_keys;
+} QEMU_PACKED evt_return_link_keys;
 #define EVT_RETURN_LINK_KEYS_SIZE 1
 
 #define EVT_PIN_CODE_REQ		0x16
 typedef struct {
     bdaddr_t	bdaddr;
-} __attribute__ ((packed)) evt_pin_code_req;
+} QEMU_PACKED evt_pin_code_req;
 #define EVT_PIN_CODE_REQ_SIZE 6
 
 #define EVT_LINK_KEY_REQ		0x17
 typedef struct {
     bdaddr_t	bdaddr;
-} __attribute__ ((packed)) evt_link_key_req;
+} QEMU_PACKED evt_link_key_req;
 #define EVT_LINK_KEY_REQ_SIZE 6
 
 #define EVT_LINK_KEY_NOTIFY		0x18
@@ -1495,7 +1495,7 @@ typedef struct {
     bdaddr_t	bdaddr;
     uint8_t	link_key[16];
     uint8_t	key_type;
-} __attribute__ ((packed)) evt_link_key_notify;
+} QEMU_PACKED evt_link_key_notify;
 #define EVT_LINK_KEY_NOTIFY_SIZE 23
 
 #define EVT_LOOPBACK_COMMAND		0x19
@@ -1503,14 +1503,14 @@ typedef struct {
 #define EVT_DATA_BUFFER_OVERFLOW	0x1A
 typedef struct {
     uint8_t	link_type;
-} __attribute__ ((packed)) evt_data_buffer_overflow;
+} QEMU_PACKED evt_data_buffer_overflow;
 #define EVT_DATA_BUFFER_OVERFLOW_SIZE 1
 
 #define EVT_MAX_SLOTS_CHANGE		0x1B
 typedef struct {
     uint16_t	handle;
     uint8_t	max_slots;
-} __attribute__ ((packed)) evt_max_slots_change;
+} QEMU_PACKED evt_max_slots_change;
 #define EVT_MAX_SLOTS_CHANGE_SIZE 3
 
 #define EVT_READ_CLOCK_OFFSET_COMPLETE	0x1C
@@ -1518,7 +1518,7 @@ typedef struct {
     uint8_t	status;
     uint16_t	handle;
     uint16_t	clock_offset;
-} __attribute__ ((packed)) evt_read_clock_offset_complete;
+} QEMU_PACKED evt_read_clock_offset_complete;
 #define EVT_READ_CLOCK_OFFSET_COMPLETE_SIZE 5
 
 #define EVT_CONN_PTYPE_CHANGED		0x1D
@@ -1526,20 +1526,20 @@ typedef struct {
     uint8_t	status;
     uint16_t	handle;
     uint16_t	ptype;
-} __attribute__ ((packed)) evt_conn_ptype_changed;
+} QEMU_PACKED evt_conn_ptype_changed;
 #define EVT_CONN_PTYPE_CHANGED_SIZE 5
 
 #define EVT_QOS_VIOLATION		0x1E
 typedef struct {
     uint16_t	handle;
-} __attribute__ ((packed)) evt_qos_violation;
+} QEMU_PACKED evt_qos_violation;
 #define EVT_QOS_VIOLATION_SIZE 2
 
 #define EVT_PSCAN_REP_MODE_CHANGE	0x20
 typedef struct {
     bdaddr_t	bdaddr;
     uint8_t	pscan_rep_mode;
-} __attribute__ ((packed)) evt_pscan_rep_mode_change;
+} QEMU_PACKED evt_pscan_rep_mode_change;
 #define EVT_PSCAN_REP_MODE_CHANGE_SIZE 7
 
 #define EVT_FLOW_SPEC_COMPLETE		0x21
@@ -1549,7 +1549,7 @@ typedef struct {
     uint8_t	flags;
     uint8_t	direction;
     hci_qos	qos;
-} __attribute__ ((packed)) evt_flow_spec_complete;
+} QEMU_PACKED evt_flow_spec_complete;
 #define EVT_FLOW_SPEC_COMPLETE_SIZE (5 + HCI_QOS_CP_SIZE)
 
 #define EVT_INQUIRY_RESULT_WITH_RSSI	0x22
@@ -1561,7 +1561,7 @@ typedef struct {
     uint8_t	dev_class[3];
     uint16_t	clock_offset;
     int8_t	rssi;
-} __attribute__ ((packed)) inquiry_info_with_rssi;
+} QEMU_PACKED inquiry_info_with_rssi;
 #define INQUIRY_INFO_WITH_RSSI_SIZE 15
 typedef struct {
     uint8_t	num_responses;
@@ -1572,7 +1572,7 @@ typedef struct {
     uint8_t	dev_class[3];
     uint16_t	clock_offset;
     int8_t	rssi;
-} __attribute__ ((packed)) inquiry_info_with_rssi_and_pscan_mode;
+} QEMU_PACKED inquiry_info_with_rssi_and_pscan_mode;
 #define INQUIRY_INFO_WITH_RSSI_AND_PSCAN_MODE_SIZE 16
 
 #define EVT_READ_REMOTE_EXT_FEATURES_COMPLETE	0x23
@@ -1582,7 +1582,7 @@ typedef struct {
     uint8_t	page_num;
     uint8_t	max_page_num;
     uint8_t	features[8];
-} __attribute__ ((packed)) evt_read_remote_ext_features_complete;
+} QEMU_PACKED evt_read_remote_ext_features_complete;
 #define EVT_READ_REMOTE_EXT_FEATURES_COMPLETE_SIZE 13
 
 #define EVT_SYNC_CONN_COMPLETE		0x2C
@@ -1596,7 +1596,7 @@ typedef struct {
     uint16_t	rx_pkt_len;
     uint16_t	tx_pkt_len;
     uint8_t	air_mode;
-} __attribute__ ((packed)) evt_sync_conn_complete;
+} QEMU_PACKED evt_sync_conn_complete;
 #define EVT_SYNC_CONN_COMPLETE_SIZE 17
 
 #define EVT_SYNC_CONN_CHANGED		0x2D
@@ -1607,7 +1607,7 @@ typedef struct {
     uint8_t	retrans_window;
     uint16_t	rx_pkt_len;
     uint16_t	tx_pkt_len;
-} __attribute__ ((packed)) evt_sync_conn_changed;
+} QEMU_PACKED evt_sync_conn_changed;
 #define EVT_SYNC_CONN_CHANGED_SIZE 9
 
 #define EVT_SNIFF_SUBRATE		0x2E
@@ -1618,7 +1618,7 @@ typedef struct {
     uint16_t	max_local_latency;
     uint16_t	min_remote_timeout;
     uint16_t	min_local_timeout;
-} __attribute__ ((packed)) evt_sniff_subrate;
+} QEMU_PACKED evt_sniff_subrate;
 #define EVT_SNIFF_SUBRATE_SIZE 11
 
 #define EVT_EXTENDED_INQUIRY_RESULT	0x2F
@@ -1630,7 +1630,7 @@ typedef struct {
     uint16_t	clock_offset;
     int8_t	rssi;
     uint8_t	data[240];
-} __attribute__ ((packed)) extended_inquiry_info;
+} QEMU_PACKED extended_inquiry_info;
 #define EXTENDED_INQUIRY_INFO_SIZE 254
 
 #define EVT_TESTING			0xFE
@@ -1656,22 +1656,22 @@ typedef struct {
 struct hci_command_hdr {
     uint16_t 	opcode;		/* OCF & OGF */
     uint8_t	plen;
-} __attribute__ ((packed));
+} QEMU_PACKED;
 
 struct hci_event_hdr {
     uint8_t	evt;
     uint8_t	plen;
-} __attribute__ ((packed));
+} QEMU_PACKED;
 
 struct hci_acl_hdr {
     uint16_t	handle;		/* Handle & Flags(PB, BC) */
     uint16_t	dlen;
-} __attribute__ ((packed));
+} QEMU_PACKED;
 
 struct hci_sco_hdr {
     uint16_t	handle;
     uint8_t	dlen;
-} __attribute__ ((packed));
+} QEMU_PACKED;
 
 /* L2CAP layer defines */
 
@@ -1718,25 +1718,25 @@ typedef struct {
     uint16_t	len;
     uint16_t	cid;
     uint8_t	data[0];
-} __attribute__ ((packed)) l2cap_hdr;
+} QEMU_PACKED l2cap_hdr;
 #define L2CAP_HDR_SIZE 4
 
 typedef struct {
     uint8_t	code;
     uint8_t	ident;
     uint16_t	len;
-} __attribute__ ((packed)) l2cap_cmd_hdr;
+} QEMU_PACKED l2cap_cmd_hdr;
 #define L2CAP_CMD_HDR_SIZE 4
 
 typedef struct {
     uint16_t	reason;
-} __attribute__ ((packed)) l2cap_cmd_rej;
+} QEMU_PACKED l2cap_cmd_rej;
 #define L2CAP_CMD_REJ_SIZE 2
 
 typedef struct {
     uint16_t	dcid;
     uint16_t	scid;
-} __attribute__ ((packed)) l2cap_cmd_rej_cid;
+} QEMU_PACKED l2cap_cmd_rej_cid;
 #define L2CAP_CMD_REJ_CID_SIZE 4
 
 /* reject reason */
@@ -1749,7 +1749,7 @@ enum bt_l2cap_rej_reason {
 typedef struct {
     uint16_t	psm;
     uint16_t	scid;
-} __attribute__ ((packed)) l2cap_conn_req;
+} QEMU_PACKED l2cap_conn_req;
 #define L2CAP_CONN_REQ_SIZE 4
 
 typedef struct {
@@ -1757,7 +1757,7 @@ typedef struct {
     uint16_t	scid;
     uint16_t	result;
     uint16_t	status;
-} __attribute__ ((packed)) l2cap_conn_rsp;
+} QEMU_PACKED l2cap_conn_rsp;
 #define L2CAP_CONN_RSP_SIZE 8
 
 /* connect result */
@@ -1780,7 +1780,7 @@ typedef struct {
     uint16_t	dcid;
     uint16_t	flags;
     uint8_t	data[0];
-} __attribute__ ((packed)) l2cap_conf_req;
+} QEMU_PACKED l2cap_conf_req;
 #define L2CAP_CONF_REQ_SIZE(datalen) (4 + (datalen))
 
 typedef struct {
@@ -1788,7 +1788,7 @@ typedef struct {
     uint16_t	flags;
     uint16_t	result;
     uint8_t	data[0];
-} __attribute__ ((packed)) l2cap_conf_rsp;
+} QEMU_PACKED l2cap_conf_rsp;
 #define L2CAP_CONF_RSP_SIZE(datalen) (6 + datalen)
 
 enum bt_l2cap_conf_res {
@@ -1802,7 +1802,7 @@ typedef struct {
     uint8_t	type;
     uint8_t	len;
     uint8_t	val[0];
-} __attribute__ ((packed)) l2cap_conf_opt;
+} QEMU_PACKED l2cap_conf_opt;
 #define L2CAP_CONF_OPT_SIZE 2
 
 enum bt_l2cap_conf_val {
@@ -1821,7 +1821,7 @@ typedef struct {
     uint32_t	peak_bandwidth;
     uint32_t	latency;
     uint32_t	delay_variation;
-} __attribute__ ((packed)) l2cap_conf_opt_qos;
+} QEMU_PACKED l2cap_conf_opt_qos;
 #define L2CAP_CONF_OPT_QOS_SIZE 22
 
 enum bt_l2cap_conf_opt_qos_st {
@@ -1841,25 +1841,25 @@ enum bt_l2cap_mode {
 typedef struct {
     uint16_t	dcid;
     uint16_t	scid;
-} __attribute__ ((packed)) l2cap_disconn_req;
+} QEMU_PACKED l2cap_disconn_req;
 #define L2CAP_DISCONN_REQ_SIZE 4
 
 typedef struct {
     uint16_t	dcid;
     uint16_t	scid;
-} __attribute__ ((packed)) l2cap_disconn_rsp;
+} QEMU_PACKED l2cap_disconn_rsp;
 #define L2CAP_DISCONN_RSP_SIZE 4
 
 typedef struct {
     uint16_t	type;
-} __attribute__ ((packed)) l2cap_info_req;
+} QEMU_PACKED l2cap_info_req;
 #define L2CAP_INFO_REQ_SIZE 2
 
 typedef struct {
     uint16_t	type;
     uint16_t	result;
     uint8_t	data[0];
-} __attribute__ ((packed)) l2cap_info_rsp;
+} QEMU_PACKED l2cap_info_rsp;
 #define L2CAP_INFO_RSP_SIZE 4
 
 /* info type */
diff --git a/hw/hpet_emul.h b/hw/hpet_emul.h
index 8bf312a..6128702 100644
--- a/hw/hpet_emul.h
+++ b/hw/hpet_emul.h
@@ -59,13 +59,13 @@ struct hpet_fw_entry
     uint64_t address;
     uint16_t min_tick;
     uint8_t page_prot;
-} __attribute__ ((packed));
+} QEMU_PACKED;
 
 struct hpet_fw_config
 {
     uint8_t count;
     struct hpet_fw_entry hpet[8];
-} __attribute__ ((packed));
+} QEMU_PACKED;
 
 extern struct hpet_fw_config hpet_cfg;
 #endif
diff --git a/hw/ide/ahci.h b/hw/ide/ahci.h
index 832539c..3c29d93 100644
--- a/hw/ide/ahci.h
+++ b/hw/ide/ahci.h
@@ -244,13 +244,13 @@ typedef struct AHCICmdHdr {
     uint32_t    status;
     uint64_t    tbl_addr;
     uint32_t    reserved[4];
-} __attribute__ ((packed)) AHCICmdHdr;
+} QEMU_PACKED AHCICmdHdr;
 
 typedef struct AHCI_SG {
     uint64_t    addr;
     uint32_t    reserved;
     uint32_t    flags_size;
-} __attribute__ ((packed)) AHCI_SG;
+} QEMU_PACKED AHCI_SG;
 
 typedef struct AHCIDevice AHCIDevice;
 
@@ -321,7 +321,7 @@ typedef struct NCQFrame {
     uint8_t reserved8;
     uint8_t reserved9;
     uint8_t reserved10;
-} __attribute__ ((packed)) NCQFrame;
+} QEMU_PACKED NCQFrame;
 
 void ahci_init(AHCIState *s, DeviceState *qdev, int ports);
 void ahci_uninit(AHCIState *s);
diff --git a/hw/ide/atapi.c b/hw/ide/atapi.c
index c552320..f38d289 100644
--- a/hw/ide/atapi.c
+++ b/hw/ide/atapi.c
@@ -557,13 +557,13 @@ static void cmd_get_event_status_notification(IDEState *s,
         uint8_t reserved3[2];
         uint16_t len;
         uint8_t control;
-    } __attribute__((packed)) *gesn_cdb;
+    } QEMU_PACKED *gesn_cdb;
 
     struct {
         uint16_t len;
         uint8_t notification_class;
         uint8_t supported_events;
-    } __attribute((packed)) *gesn_event_header;
+    } QEMU_PACKED *gesn_event_header;
 
     enum notification_class_request_type {
         NCR_RESERVED1 = 1 << 0,
diff --git a/hw/milkymist-tmu2.c b/hw/milkymist-tmu2.c
index 790cdcb..953d42f 100644
--- a/hw/milkymist-tmu2.c
+++ b/hw/milkymist-tmu2.c
@@ -73,7 +73,7 @@ enum {
 struct vertex {
     int x;
     int y;
-} __attribute__((packed));
+} QEMU_PACKED;
 
 struct MilkymistTMU2State {
     SysBusDevice busdev;
diff --git a/hw/pc.c b/hw/pc.c
index 263fb1a..5bc845a 100644
--- a/hw/pc.c
+++ b/hw/pc.c
@@ -78,12 +78,12 @@ struct e820_entry {
     uint64_t address;
     uint64_t length;
     uint32_t type;
-} __attribute((__packed__, __aligned__(4)));
+} QEMU_PACKED __attribute((__aligned__(4)));
 
 struct e820_table {
     uint32_t count;
     struct e820_entry entry[E820_NR_ENTRIES];
-} __attribute((__packed__, __aligned__(4)));
+} QEMU_PACKED __attribute((__aligned__(4)));
 
 static struct e820_table e820_table;
 struct hpet_fw_config hpet_cfg = {.count = UINT8_MAX};
diff --git a/hw/pxa2xx_lcd.c b/hw/pxa2xx_lcd.c
index 97f9015..b73290c 100644
--- a/hw/pxa2xx_lcd.c
+++ b/hw/pxa2xx_lcd.c
@@ -70,7 +70,7 @@ struct PXA2xxLCDState {
     int orientation;
 };
 
-typedef struct __attribute__ ((__packed__)) {
+typedef struct QEMU_PACKED {
     uint32_t fdaddr;
     uint32_t fsaddr;
     uint32_t fidr;
diff --git a/hw/r2d.c b/hw/r2d.c
index 96a7ff8..771f3d0 100644
--- a/hw/r2d.c
+++ b/hw/r2d.c
@@ -209,7 +209,7 @@ static void main_cpu_reset(void *opaque)
     env->pc = s->vector;
 }
 
-static struct __attribute__((__packed__))
+static struct QEMU_PACKED
 {
     int mount_root_rdonly;
     int ramdisk_flags;
diff --git a/hw/rc4030.c b/hw/rc4030.c
index a2a2099..33e1070 100644
--- a/hw/rc4030.c
+++ b/hw/rc4030.c
@@ -50,7 +50,7 @@ do { fprintf(stderr, "rc4030 ERROR: %s: " fmt, __func__ , ## __VA_ARGS__); } whi
 typedef struct dma_pagetable_entry {
     int32_t frame;
     int32_t owner;
-} __attribute__((packed)) dma_pagetable_entry;
+} QEMU_PACKED dma_pagetable_entry;
 
 #define DMA_PAGESIZE    4096
 #define DMA_REG_ENABLE  1
diff --git a/hw/smbios.c b/hw/smbios.c
index 8f2e965..c9ba43e 100644
--- a/hw/smbios.c
+++ b/hw/smbios.c
@@ -21,19 +21,19 @@
 struct smbios_header {
     uint16_t length;
     uint8_t type;
-} __attribute__((__packed__));
+} QEMU_PACKED;
 
 struct smbios_field {
     struct smbios_header header;
     uint8_t type;
     uint16_t offset;
     uint8_t data[];
-} __attribute__((__packed__));
+} QEMU_PACKED;
 
 struct smbios_table {
     struct smbios_header header;
     uint8_t data[];
-} __attribute__((__packed__));
+} QEMU_PACKED;
 
 #define SMBIOS_FIELD_ENTRY 0
 #define SMBIOS_TABLE_ENTRY 1
diff --git a/hw/smbios.h b/hw/smbios.h
index 3a5169d..94e3641 100644
--- a/hw/smbios.h
+++ b/hw/smbios.h
@@ -26,7 +26,7 @@ struct smbios_structure_header {
     uint8_t type;
     uint8_t length;
     uint16_t handle;
-} __attribute__((__packed__));
+} QEMU_PACKED;
 
 /* SMBIOS type 0 - BIOS Information */
 struct smbios_type_0 {
@@ -42,7 +42,7 @@ struct smbios_type_0 {
     uint8_t system_bios_minor_release;
     uint8_t embedded_controller_major_release;
     uint8_t embedded_controller_minor_release;
-} __attribute__((__packed__));
+} QEMU_PACKED;
 
 /* SMBIOS type 1 - System Information */
 struct smbios_type_1 {
@@ -55,7 +55,7 @@ struct smbios_type_1 {
     uint8_t wake_up_type;
     uint8_t sku_number_str;
     uint8_t family_str;
-} __attribute__((__packed__));
+} QEMU_PACKED;
 
 /* SMBIOS type 3 - System Enclosure (v2.3) */
 struct smbios_type_3 {
@@ -74,7 +74,7 @@ struct smbios_type_3 {
     uint8_t number_of_power_cords;
     uint8_t contained_element_count;
     // contained elements follow
-} __attribute__((__packed__));
+} QEMU_PACKED;
 
 /* SMBIOS type 4 - Processor Information (v2.0) */
 struct smbios_type_4 {
@@ -94,7 +94,7 @@ struct smbios_type_4 {
     uint16_t l1_cache_handle;
     uint16_t l2_cache_handle;
     uint16_t l3_cache_handle;
-} __attribute__((__packed__));
+} QEMU_PACKED;
 
 /* SMBIOS type 16 - Physical Memory Array
  *   Associated with one type 17 (Memory Device).
@@ -107,7 +107,7 @@ struct smbios_type_16 {
     uint32_t maximum_capacity;
     uint16_t memory_error_information_handle;
     uint16_t number_of_memory_devices;
-} __attribute__((__packed__));
+} QEMU_PACKED;
 /* SMBIOS type 17 - Memory Device
  *   Associated with one type 19
  */
@@ -124,7 +124,7 @@ struct smbios_type_17 {
     uint8_t bank_locator_str;
     uint8_t memory_type;
     uint16_t type_detail;
-} __attribute__((__packed__));
+} QEMU_PACKED;
 
 /* SMBIOS type 19 - Memory Array Mapped Address */
 struct smbios_type_19 {
@@ -133,7 +133,7 @@ struct smbios_type_19 {
     uint32_t ending_address;
     uint16_t memory_array_handle;
     uint8_t partition_width;
-} __attribute__((__packed__));
+} QEMU_PACKED;
 
 /* SMBIOS type 20 - Memory Device Mapped Address */
 struct smbios_type_20 {
@@ -145,18 +145,18 @@ struct smbios_type_20 {
     uint8_t partition_row_position;
     uint8_t interleave_position;
     uint8_t interleaved_data_depth;
-} __attribute__((__packed__));
+} QEMU_PACKED;
 
 /* SMBIOS type 32 - System Boot Information */
 struct smbios_type_32 {
     struct smbios_structure_header header;
     uint8_t reserved[6];
     uint8_t boot_status;
-} __attribute__((__packed__));
+} QEMU_PACKED;
 
 /* SMBIOS type 127 -- End-of-table */
 struct smbios_type_127 {
     struct smbios_structure_header header;
-} __attribute__((__packed__));
+} QEMU_PACKED;
 
 #endif /*QEMU_SMBIOS_H */
diff --git a/hw/srp.h b/hw/srp.h
index afcd135..3009bd5 100644
--- a/hw/srp.h
+++ b/hw/srp.h
@@ -106,7 +106,7 @@ struct srp_indirect_buf {
     struct srp_direct_buf    table_desc;
     uint32_t                 len;
     struct srp_direct_buf    desc_list[0];
-} __attribute__((packed));
+} QEMU_PACKED;
 
 enum {
     SRP_MULTICHAN_SINGLE = 0,
@@ -141,7 +141,7 @@ struct srp_login_rsp {
     uint16_t   buf_fmt;
     uint8_t    rsp_flags;
     uint8_t    reserved2[25];
-} __attribute__((packed));
+} QEMU_PACKED;
 
 struct srp_login_rej {
     uint8_t    opcode;
@@ -177,7 +177,7 @@ struct srp_tsk_mgmt {
     uint8_t    reserved1[6];
     uint64_t   tag;
     uint8_t    reserved2[4];
-    uint64_t   lun __attribute__((packed));
+    uint64_t   lun QEMU_PACKED;
     uint8_t    reserved3[2];
     uint8_t    tsk_mgmt_func;
     uint8_t    reserved4;
@@ -198,7 +198,7 @@ struct srp_cmd {
     uint8_t    data_in_desc_cnt;
     uint64_t   tag;
     uint8_t    reserved2[4];
-    uint64_t   lun __attribute__((packed));
+    uint64_t   lun QEMU_PACKED;
     uint8_t    reserved3;
     uint8_t    task_attr;
     uint8_t    reserved4;
@@ -235,6 +235,6 @@ struct srp_rsp {
     uint32_t   sense_data_len;
     uint32_t   resp_data_len;
     uint8_t    data[0];
-} __attribute__((packed));
+} QEMU_PACKED;
 
 #endif /* SCSI_SRP_H */
diff --git a/hw/usb-ccid.c b/hw/usb-ccid.c
index 66aeb21..c2f9241 100644
--- a/hw/usb-ccid.c
+++ b/hw/usb-ccid.c
@@ -176,56 +176,56 @@ enum {
      */
 };
 
-typedef struct __attribute__ ((__packed__)) CCID_Header {
+typedef struct QEMU_PACKED CCID_Header {
     uint8_t     bMessageType;
     uint32_t    dwLength;
     uint8_t     bSlot;
     uint8_t     bSeq;
 } CCID_Header;
 
-typedef struct __attribute__ ((__packed__)) CCID_BULK_IN {
+typedef struct QEMU_PACKED CCID_BULK_IN {
     CCID_Header hdr;
     uint8_t     bStatus;        /* Only used in BULK_IN */
     uint8_t     bError;         /* Only used in BULK_IN */
 } CCID_BULK_IN;
 
-typedef struct __attribute__ ((__packed__)) CCID_SlotStatus {
+typedef struct QEMU_PACKED CCID_SlotStatus {
     CCID_BULK_IN b;
     uint8_t     bClockStatus;
 } CCID_SlotStatus;
 
-typedef struct __attribute__ ((__packed__)) CCID_Parameter {
+typedef struct QEMU_PACKED CCID_Parameter {
     CCID_BULK_IN b;
     uint8_t     bProtocolNum;
     uint8_t     abProtocolDataStructure[0];
 } CCID_Parameter;
 
-typedef struct __attribute__ ((__packed__)) CCID_DataBlock {
+typedef struct QEMU_PACKED CCID_DataBlock {
     CCID_BULK_IN b;
     uint8_t      bChainParameter;
     uint8_t      abData[0];
 } CCID_DataBlock;
 
 /* 6.1.4 PC_to_RDR_XfrBlock */
-typedef struct __attribute__ ((__packed__)) CCID_XferBlock {
+typedef struct QEMU_PACKED CCID_XferBlock {
     CCID_Header  hdr;
     uint8_t      bBWI; /* Block Waiting Timeout */
     uint16_t     wLevelParameter; /* XXX currently unused */
     uint8_t      abData[0];
 } CCID_XferBlock;
 
-typedef struct __attribute__ ((__packed__)) CCID_IccPowerOn {
+typedef struct QEMU_PACKED CCID_IccPowerOn {
     CCID_Header hdr;
     uint8_t     bPowerSelect;
     uint16_t    abRFU;
 } CCID_IccPowerOn;
 
-typedef struct __attribute__ ((__packed__)) CCID_IccPowerOff {
+typedef struct QEMU_PACKED CCID_IccPowerOff {
     CCID_Header hdr;
     uint16_t    abRFU;
 } CCID_IccPowerOff;
 
-typedef struct __attribute__ ((__packed__)) CCID_SetParameters {
+typedef struct QEMU_PACKED CCID_SetParameters {
     CCID_Header hdr;
     uint8_t     bProtocolNum;
     uint16_t   abRFU;
diff --git a/hw/virtio-balloon.h b/hw/virtio-balloon.h
index e20cf6b..73300dd 100644
--- a/hw/virtio-balloon.h
+++ b/hw/virtio-balloon.h
@@ -50,6 +50,6 @@ struct virtio_balloon_config
 typedef struct VirtIOBalloonStat {
     uint16_t tag;
     uint64_t val;
-} __attribute__((packed)) VirtIOBalloonStat;
+} QEMU_PACKED VirtIOBalloonStat;
 
 #endif
diff --git a/hw/virtio-blk.h b/hw/virtio-blk.h
index 5645d2b..244dce4 100644
--- a/hw/virtio-blk.h
+++ b/hw/virtio-blk.h
@@ -49,7 +49,7 @@ struct virtio_blk_config
     uint8_t alignment_offset;
     uint16_t min_io_size;
     uint32_t opt_io_size;
-} __attribute__((packed));
+} QEMU_PACKED;
 
 /* These two define direction. */
 #define VIRTIO_BLK_T_IN         0
diff --git a/hw/virtio-net.h b/hw/virtio-net.h
index 8af9a1c..4468741 100644
--- a/hw/virtio-net.h
+++ b/hw/virtio-net.h
@@ -72,7 +72,7 @@ struct virtio_net_config
     uint8_t mac[ETH_ALEN];
     /* See VIRTIO_NET_F_STATUS and VIRTIO_NET_S_* above */
     uint16_t status;
-} __attribute__((packed));
+} QEMU_PACKED;
 
 /* This is the first element of the scatter-gather list.  If you don't
  * specify GSO or CSUM features, you can simply ignore the header. */
diff --git a/hw/virtio-serial.h b/hw/virtio-serial.h
index 36e9d22..ab13803 100644
--- a/hw/virtio-serial.h
+++ b/hw/virtio-serial.h
@@ -37,7 +37,7 @@ struct virtio_console_config {
     uint16_t rows;
 
     uint32_t max_nr_ports;
-} __attribute__((packed));
+} QEMU_PACKED;
 
 struct virtio_console_control {
     uint32_t id;		/* Port number */
diff --git a/hw/vmware_vga.c b/hw/vmware_vga.c
index 52d2d26..aa68237 100644
--- a/hw/vmware_vga.c
+++ b/hw/vmware_vga.c
@@ -70,7 +70,7 @@ struct vmsvga_state_s {
 
     union {
         uint32_t *fifo;
-        struct __attribute__((__packed__)) {
+        struct QEMU_PACKED {
             uint32_t min;
             uint32_t max;
             uint32_t next_cmd;
diff --git a/hw/zaurus.c b/hw/zaurus.c
index c24aeb5..0eeacf7 100644
--- a/hw/zaurus.c
+++ b/hw/zaurus.c
@@ -246,7 +246,7 @@ device_init(scoop_register);
 
 #define MAGIC_CHG(a, b, c, d)	((d << 24) | (c << 16) | (b << 8) | a)
 
-static struct __attribute__ ((__packed__)) sl_param_info {
+static struct QEMU_PACKED sl_param_info {
     uint32_t comadj_keyword;
     int32_t comadj;
 
diff --git a/linux-user/syscall_defs.h b/linux-user/syscall_defs.h
index a117407..15c44d4 100644
--- a/linux-user/syscall_defs.h
+++ b/linux-user/syscall_defs.h
@@ -1120,7 +1120,7 @@ struct target_stat64 {
 	abi_ulong	__pad7;		/* will be high 32 bits of ctime someday */
 
 	unsigned long long	st_ino;
-} __attribute__((packed));
+} QEMU_PACKED;
 
 #ifdef TARGET_ARM
 struct target_eabi_stat64 {
@@ -1151,7 +1151,7 @@ struct target_eabi_stat64 {
         abi_ulong    target_st_ctime_nsec;
 
         unsigned long long st_ino;
-} __attribute__ ((packed));
+} QEMU_PACKED;
 #endif
 
 #elif defined(TARGET_SPARC64) && !defined(TARGET_ABI32)
@@ -1294,7 +1294,7 @@ struct target_stat {
 #endif
 };
 
-struct __attribute__((__packed__)) target_stat64 {
+struct QEMU_PACKED target_stat64 {
 	unsigned long long st_dev;
         unsigned long long st_ino;
 	unsigned int st_mode;
@@ -1341,7 +1341,7 @@ struct target_stat {
 };
 
 /* FIXME: Microblaze no-mmu user-space has a difference stat64 layout...  */
-struct __attribute__((__packed__)) target_stat64 {
+struct QEMU_PACKED target_stat64 {
 	uint64_t st_dev;
 #define TARGET_STAT64_HAS_BROKEN_ST_INO 1
 	uint32_t pad0;
@@ -1428,7 +1428,7 @@ struct target_stat64 {
 	abi_ulong	target_st_ctime_nsec;
 
 	unsigned long long	st_ino;
-} __attribute__((packed));
+} QEMU_PACKED;
 
 #elif defined(TARGET_ABI_MIPSN64)
 
@@ -1680,7 +1680,7 @@ struct target_stat {
 /* This matches struct stat64 in glibc2.1, hence the absolutely
  * insane amounts of padding around dev_t's.
  */
-struct __attribute__((__packed__)) target_stat64 {
+struct QEMU_PACKED target_stat64 {
 	unsigned long long	st_dev;
 	unsigned char	__pad0[4];
 
@@ -2095,7 +2095,7 @@ struct target_flock64 {
 	unsigned long long l_start;
 	unsigned long long l_len;
 	int  l_pid;
-}__attribute__((packed));
+} QEMU_PACKED;
 
 #ifdef TARGET_ARM
 struct target_eabi_flock64 {
@@ -2105,7 +2105,7 @@ struct target_eabi_flock64 {
 	unsigned long long l_start;
 	unsigned long long l_len;
 	int  l_pid;
-}__attribute__((packed));
+} QEMU_PACKED;
 #endif
 
 /* soundcard defines */
diff --git a/m68k-semi.c b/m68k-semi.c
index 7fde10e..bab01ee 100644
--- a/m68k-semi.c
+++ b/m68k-semi.c
@@ -70,12 +70,12 @@ struct m68k_gdb_stat {
   gdb_time_t  gdb_st_atime;   /* time of last access */
   gdb_time_t  gdb_st_mtime;   /* time of last modification */
   gdb_time_t  gdb_st_ctime;   /* time of last change */
-} __attribute__((packed));
+} QEMU_PACKED;
 
 struct gdb_timeval {
   gdb_time_t tv_sec;  /* second */
   uint64_t tv_usec;   /* microsecond */
-} __attribute__((packed));
+} QEMU_PACKED;
 
 #define GDB_O_RDONLY   0x0
 #define GDB_O_WRONLY   0x1
diff --git a/nbd.h b/nbd.h
index b38d0d0..96f77fe 100644
--- a/nbd.h
+++ b/nbd.h
@@ -31,13 +31,13 @@ struct nbd_request {
     uint64_t handle;
     uint64_t from;
     uint32_t len;
-} __attribute__ ((__packed__));
+} QEMU_PACKED;
 
 struct nbd_reply {
     uint32_t magic;
     uint32_t error;
     uint64_t handle;
-} __attribute__ ((__packed__));
+} QEMU_PACKED;
 
 enum {
     NBD_CMD_READ = 0,
diff --git a/slirp/ip.h b/slirp/ip.h
index 72dbe9a..88c903f 100644
--- a/slirp/ip.h
+++ b/slirp/ip.h
@@ -91,7 +91,7 @@ struct ip {
 	uint8_t ip_p;			/* protocol */
 	uint16_t	ip_sum;			/* checksum */
 	struct	in_addr ip_src,ip_dst;	/* source and dest address */
-} __attribute__((packed));
+} QEMU_PACKED;
 
 #define	IP_MAXPACKET	65535		/* maximum packet size */
 
@@ -153,7 +153,7 @@ struct	ip_timestamp {
 			n_long ipt_time;
 		} ipt_ta[1];
 	} ipt_timestamp;
-} __attribute__((packed));
+} QEMU_PACKED;
 
 /* flag bits for ipt_flg */
 #define	IPOPT_TS_TSONLY		0		/* timestamps only */
@@ -183,11 +183,11 @@ struct	ip_timestamp {
 struct mbuf_ptr {
 	struct mbuf *mptr;
 	uint32_t dummy;
-} __attribute__((packed));
+} QEMU_PACKED;
 #else
 struct mbuf_ptr {
 	struct mbuf *mptr;
-} __attribute__((packed));
+} QEMU_PACKED;
 #endif
 struct qlink {
 	void *next, *prev;
@@ -203,7 +203,7 @@ struct ipovly {
 	uint16_t	ih_len;			/* protocol length */
 	struct	in_addr ih_src;		/* source internet address */
 	struct	in_addr ih_dst;		/* destination internet address */
-} __attribute__((packed));
+} QEMU_PACKED;
 
 /*
  * Ip reassembly queue structure.  Each fragment
@@ -219,7 +219,7 @@ struct ipq {
 	uint8_t	ipq_p;			/* protocol of this fragment */
 	uint16_t	ipq_id;			/* sequence id for reassembly */
 	struct	in_addr ipq_src,ipq_dst;
-} __attribute__((packed));
+} QEMU_PACKED;
 
 /*
  * Ip header, when holding a fragment.
@@ -229,7 +229,7 @@ struct ipq {
 struct	ipasfrag {
 	struct qlink ipf_link;
 	struct ip ipf_ip;
-} __attribute__((packed));
+} QEMU_PACKED;
 
 #define ipf_off      ipf_ip.ip_off
 #define ipf_tos      ipf_ip.ip_tos
@@ -248,6 +248,6 @@ struct	ipasfrag {
 struct ipoption {
 	struct	in_addr ipopt_dst;	/* first-hop dst if source routed */
 	int8_t	ipopt_list[MAX_IPOPTLEN];	/* options proper */
-} __attribute__((packed));
+} QEMU_PACKED;
 
 #endif
diff --git a/slirp/slirp.h b/slirp/slirp.h
index dcf99d5..28a5c03 100644
--- a/slirp/slirp.h
+++ b/slirp/slirp.h
@@ -199,7 +199,7 @@ struct arphdr {
     uint32_t      ar_sip;           /* sender IP address       */
     unsigned char ar_tha[ETH_ALEN]; /* target hardware address */
     uint32_t      ar_tip;           /* target IP address       */
-} __attribute__((packed));
+} QEMU_PACKED;
 
 #define ARP_TABLE_SIZE 16
 
diff --git a/target-i386/kvm.c b/target-i386/kvm.c
index 1d9b20c..70ef74b 100644
--- a/target-i386/kvm.c
+++ b/target-i386/kvm.c
@@ -348,7 +348,7 @@ int kvm_arch_init_vcpu(CPUState *env)
     struct {
         struct kvm_cpuid2 cpuid;
         struct kvm_cpuid_entry2 entries[100];
-    } __attribute__((packed)) cpuid_data;
+    } QEMU_PACKED cpuid_data;
     KVMState *s = env->kvm_state;
     uint32_t limit, i, j, cpuid_i;
     uint32_t unused;
diff --git a/target-i386/svm.h b/target-i386/svm.h
index a224aea..04193ed 100644
--- a/target-i386/svm.h
+++ b/target-i386/svm.h
@@ -130,7 +130,7 @@
 
 #define SVM_CR0_SELECTIVE_MASK (1 << 3 | 1) /* TS and MP */
 
-struct __attribute__ ((__packed__)) vmcb_control_area {
+struct QEMU_PACKED vmcb_control_area {
 	uint16_t intercept_cr_read;
 	uint16_t intercept_cr_write;
 	uint16_t intercept_dr_read;
@@ -162,14 +162,14 @@ struct __attribute__ ((__packed__)) vmcb_control_area {
 	uint8_t reserved_5[832];
 };
 
-struct __attribute__ ((__packed__)) vmcb_seg {
+struct QEMU_PACKED vmcb_seg {
 	uint16_t selector;
 	uint16_t attrib;
 	uint32_t limit;
 	uint64_t base;
 };
 
-struct __attribute__ ((__packed__)) vmcb_save_area {
+struct QEMU_PACKED vmcb_save_area {
 	struct vmcb_seg es;
 	struct vmcb_seg cs;
 	struct vmcb_seg ss;
@@ -214,7 +214,7 @@ struct __attribute__ ((__packed__)) vmcb_save_area {
 	uint64_t last_excp_to;
 };
 
-struct __attribute__ ((__packed__)) vmcb {
+struct QEMU_PACKED vmcb {
 	struct vmcb_control_area control;
 	struct vmcb_save_area save;
 };
diff --git a/target-s390x/cpu.h b/target-s390x/cpu.h
index f8f0c82..e192b50 100644
--- a/target-s390x/cpu.h
+++ b/target-s390x/cpu.h
@@ -698,7 +698,7 @@ typedef struct LowCore
     /* align to the top of the prefix area */
 
     uint8_t         pad18[0x2000-0x1400];      /* 0x1400 */
-} __attribute__((packed)) LowCore;
+} QEMU_PACKED LowCore;
 
 /* STSI */
 #define STSI_LEVEL_MASK         0x00000000f0000000ULL
diff --git a/tests/test-i386.c b/tests/test-i386.c
index 56ff110..9cb5b51 100644
--- a/tests/test-i386.c
+++ b/tests/test-i386.c
@@ -773,7 +773,7 @@ void test_fops(double a, double b)
 
 void fpu_clear_exceptions(void)
 {
-    struct __attribute__((packed)) {
+    struct QEMU_PACKED {
         uint16_t fpuc;
         uint16_t dummy1;
         uint16_t fpus;
@@ -924,7 +924,7 @@ void test_fbcd(double a)
 
 void test_fenv(void)
 {
-    struct __attribute__((packed)) {
+    struct QEMU_PACKED {
         uint16_t fpuc;
         uint16_t dummy1;
         uint16_t fpus;
@@ -934,7 +934,7 @@ void test_fenv(void)
         uint32_t ignored[4];
         long double fpregs[8];
     } float_env32;
-    struct __attribute__((packed)) {
+    struct QEMU_PACKED {
         uint16_t fpuc;
         uint16_t fpus;
         uint16_t fptag;
@@ -1279,7 +1279,7 @@ void test_segs(void)
     struct {
         uint32_t offset;
         uint16_t seg;
-    } __attribute__((packed)) segoff;
+    } QEMU_PACKED segoff;
 
     ldt.entry_number = 1;
     ldt.base_addr = (unsigned long)&seg_data1;
@@ -1441,7 +1441,7 @@ void test_misc(void)
         /* XXX: see if Intel Core2 and AMD64 behavior really
            differ. Here we implemented the Intel way which is not
            compatible yet with QEMU. */
-        static struct __attribute__((packed)) {
+        static struct QEMU_PACKED {
             uint64_t offset;
             uint16_t seg;
         } desc;
commit 0f7fdd347514ea97b24f5f658f3ae31f9b078397
Author: Stefan Weil <weil at mail.berlios.de>
Date:   Wed Aug 31 12:38:00 2011 +0200

    Add new macro QEMU_PACKED for packed C structures
    
    A packed struct needs different gcc attributes for compilations
    with MinGW compilers because glib-2.0 adds compiler flag
    -mms-bitfields which modifies the packing algorithm.
    
    Attribute gcc_struct reverses the negative effects of -mms-bitfields.
    QEMU_PACKED sets this attribute and must be used for any packed
    struct which is affected by -mms-bitfields.
    
    Signed-off-by: Stefan Weil <weil at mail.berlios.de>
    Signed-off-by: Blue Swirl <blauwirbel at gmail.com>

diff --git a/compiler.h b/compiler.h
index 9af5dc6..a2d5959 100644
--- a/compiler.h
+++ b/compiler.h
@@ -12,6 +12,12 @@
 #define QEMU_WARN_UNUSED_RESULT
 #endif
 
+#if defined(_WIN32)
+# define QEMU_PACKED __attribute__((gcc_struct, packed))
+#else
+# define QEMU_PACKED __attribute__((packed))
+#endif
+
 #define QEMU_BUILD_BUG_ON(x) \
     typedef char qemu_build_bug_on__##__LINE__[(x)?-1:1];
 
commit a74cd8cc37896402a1793217d5059a0b0489155a
Author: Frediano Ziglio <freddy77 at gmail.com>
Date:   Wed Aug 31 09:25:35 2011 +0200

    rename qemu_malloc and related to glib names for coherence
    
    Reviewed-by: Stefan Hajnoczi <stefanha at linux.vnet.ibm.com>
    Signed-off-by: Frediano Ziglio <freddy77 at gmail.com>
    Signed-off-by: Anthony Liguori <aliguori at us.ibm.com>

diff --git a/trace-events b/trace-events
index 98f3ec2..08ffedf 100644
--- a/trace-events
+++ b/trace-events
@@ -14,7 +14,7 @@
 #
 # [disable] <name>(<type1> <arg1>[, <type2> <arg2>] ...) "<format-string>"
 #
-# Example: qemu_malloc(size_t size) "size %zu"
+# Example: g_malloc(size_t size) "size %zu"
 #
 # The "disable" keyword will build without the trace event.
 #
@@ -26,9 +26,9 @@
 # The <format-string> should be a sprintf()-compatible format string.
 
 # qemu-malloc.c
-qemu_malloc(size_t size, void *ptr) "size %zu ptr %p"
-qemu_realloc(void *ptr, size_t size, void *newptr) "ptr %p size %zu newptr %p"
-qemu_free(void *ptr) "ptr %p"
+g_malloc(size_t size, void *ptr) "size %zu ptr %p"
+g_realloc(void *ptr, size_t size, void *newptr) "ptr %p size %zu newptr %p"
+g_free(void *ptr) "ptr %p"
 
 # osdep.c
 qemu_memalign(size_t alignment, size_t size, void *ptr) "alignment %zu size %zu ptr %p"
diff --git a/vl.c b/vl.c
index 7a6fbac..5ba9b35 100644
--- a/vl.c
+++ b/vl.c
@@ -2144,20 +2144,20 @@ static const QEMUOption *lookup_opt(int argc, char **argv,
 static gpointer malloc_and_trace(gsize n_bytes)
 {
     void *ptr = malloc(n_bytes);
-    trace_qemu_malloc(n_bytes, ptr);
+    trace_g_malloc(n_bytes, ptr);
     return ptr;
 }
 
 static gpointer realloc_and_trace(gpointer mem, gsize n_bytes)
 {
     void *ptr = realloc(mem, n_bytes);
-    trace_qemu_realloc(mem, n_bytes, ptr);
+    trace_g_realloc(mem, n_bytes, ptr);
     return ptr;
 }
 
 static void free_and_trace(gpointer mem)
 {
-    trace_qemu_free(mem);
+    trace_g_free(mem);
     free(mem);
 }
 
commit 1901cb14edb6b6d4c20986a77b2fcff67bd19755
Author: Brad <brad at comstyle.com>
Date:   Sun Aug 28 04:01:33 2011 -0400

    Fix install(1) usage to be compatible with OpenBSD's install(1).
    
    Fix install(1) usage to be compatible with OpenBSD's install(1).
    
    When creating a directory via the -d flag the -p flag cannot be
    used at the same time. Also in the context of installing QEMU it
    doesn't make sense to use the -p flag anyway so use the [default]
    -c flag instead.
    
    Signed-off-by: Brad Smith <brad at comstyle.com>
    Signed-off-by: Anthony Liguori <aliguori at us.ibm.com>

diff --git a/configure b/configure
index eba6fc6..a8ea688 100755
--- a/configure
+++ b/configure
@@ -3085,9 +3085,9 @@ echo "TOOLS=$tools" >> $config_host_mak
 echo "ROMS=$roms" >> $config_host_mak
 echo "MAKE=$make" >> $config_host_mak
 echo "INSTALL=$install" >> $config_host_mak
-echo "INSTALL_DIR=$install -d -m0755 -p" >> $config_host_mak
-echo "INSTALL_DATA=$install -m0644 -p" >> $config_host_mak
-echo "INSTALL_PROG=$install -m0755 -p" >> $config_host_mak
+echo "INSTALL_DIR=$install -d -m 0755" >> $config_host_mak
+echo "INSTALL_DATA=$install -c -m 0644" >> $config_host_mak
+echo "INSTALL_PROG=$install -c -m 0755" >> $config_host_mak
 echo "PYTHON=$python" >> $config_host_mak
 echo "CC=$cc" >> $config_host_mak
 echo "CC_I386=$cc_i386" >> $config_host_mak
commit 9aed1e036dc0de49d08d713f9e5c4655e94acb56
Author: Anthony Liguori <aliguori at us.ibm.com>
Date:   Mon Aug 29 09:55:36 2011 -0500

    Rename qemu -> qemu-system-i386
    
    This has been discussed before in the past.  The special casing really makes no
    sense anymore.  This seems like a good change to make for 1.0.
    
    Signed-off-by: Anthony Liguori <aliguori at us.ibm.com>

diff --git a/Makefile b/Makefile
index 13be25a..e0cf51a 100644
--- a/Makefile
+++ b/Makefile
@@ -366,9 +366,8 @@ tar:
 	rm -rf /tmp/$(FILE)
 
 SYSTEM_TARGETS=$(filter %-softmmu,$(TARGET_DIRS))
-SYSTEM_PROGS=$(patsubst qemu-system-i386,qemu, \
-             $(patsubst %-softmmu,qemu-system-%, \
-             $(SYSTEM_TARGETS)))
+SYSTEM_PROGS=$(patsubst %-softmmu,qemu-system-%, \
+             $(SYSTEM_TARGETS))
 
 USER_TARGETS=$(filter %-user,$(TARGET_DIRS))
 USER_PROGS=$(patsubst %-bsd-user,qemu-%, \
diff --git a/Makefile.target b/Makefile.target
index 25c16d7..0787758 100644
--- a/Makefile.target
+++ b/Makefile.target
@@ -27,12 +27,8 @@ ifdef CONFIG_USER_ONLY
 QEMU_PROG=qemu-$(TARGET_ARCH2)
 else
 # system emulator name
-ifeq ($(TARGET_ARCH), i386)
-QEMU_PROG=qemu$(EXESUF)
-else
 QEMU_PROG=qemu-system-$(TARGET_ARCH2)$(EXESUF)
 endif
-endif
 
 PROGS=$(QEMU_PROG)
 STPFILES=
commit 12d4536f7d911b6d87a766ad7300482ea663cea2
Author: Anthony Liguori <aliguori at us.ibm.com>
Date:   Mon Aug 22 08:24:58 2011 -0500

    main: force enabling of I/O thread
    
    Enabling the I/O thread by default seems like an important part of declaring
    1.0.  Besides allowing true SMP support with KVM, the I/O thread means that the
    TCG VCPU doesn't have to multiplex itself with the I/O dispatch routines which
    currently requires a (racey) signal based alarm system.
    
    I know there have been concerns about performance.  I think so far the ones that
    have come up (virtio-net) are most likely due to secondary reasons like
    decreased batching.
    
    I think we ought to force enabling I/O thread early in 1.0 development and
    commit to resolving any lingering issues.
    
    Signed-off-by: Anthony Liguori <aliguori at us.ibm.com>

diff --git a/configure b/configure
index 1fb31c7..eba6fc6 100755
--- a/configure
+++ b/configure
@@ -165,7 +165,6 @@ darwin_user="no"
 bsd_user="no"
 guest_base=""
 uname_release=""
-io_thread="no"
 mixemu="no"
 aix="no"
 blobs="yes"
@@ -723,8 +722,6 @@ for opt do
   ;;
   --enable-attr) attr="yes"
   ;;
-  --enable-io-thread) io_thread="yes"
-  ;;
   --disable-blobs) blobs="no"
   ;;
   --with-pkgversion=*) pkgversion=" ($optarg)"
@@ -2158,12 +2155,6 @@ EOF
 
 if compile_prog "" "" ; then
   signalfd=yes
-elif test "$kvm" = "yes" -a "$io_thread" != "yes"; then
-  echo
-  echo "ERROR: Host kernel lacks signalfd() support,"
-  echo "but KVM depends on it when the IO thread is disabled."
-  echo
-  exit 1
 fi
 
 # check if eventfd is supported
@@ -2710,7 +2701,6 @@ echo "NPTL support      $nptl"
 echo "GUEST_BASE        $guest_base"
 echo "PIE user targets  $user_pie"
 echo "vde support       $vde"
-echo "IO thread         $io_thread"
 echo "Linux AIO support $linux_aio"
 echo "ATTR/XATTR support $attr"
 echo "Install blobs     $blobs"
@@ -2968,9 +2958,6 @@ if test "$xen" = "yes" ; then
   echo "CONFIG_XEN_BACKEND=y" >> $config_host_mak
   echo "CONFIG_XEN_CTRL_INTERFACE_VERSION=$xen_ctrl_version" >> $config_host_mak
 fi
-if test "$io_thread" = "yes" ; then
-  echo "CONFIG_IOTHREAD=y" >> $config_host_mak
-fi
 if test "$linux_aio" = "yes" ; then
   echo "CONFIG_LINUX_AIO=y" >> $config_host_mak
 fi
diff --git a/cpus.c b/cpus.c
index b163efe..54c188c 100644
--- a/cpus.c
+++ b/cpus.c
@@ -173,12 +173,9 @@ static void cpu_handle_guest_debug(CPUState *env)
 {
     gdb_set_stop_cpu(env);
     qemu_system_debug_request();
-#ifdef CONFIG_IOTHREAD
     env->stopped = 1;
-#endif
 }
 
-#ifdef CONFIG_IOTHREAD
 static void cpu_signal(int sig)
 {
     if (cpu_single_env) {
@@ -186,7 +183,6 @@ static void cpu_signal(int sig)
     }
     exit_request = 1;
 }
-#endif
 
 #ifdef CONFIG_LINUX
 static void sigbus_reraise(void)
@@ -262,12 +258,6 @@ static void qemu_kvm_eat_signals(CPUState *env)
             exit(1);
         }
     } while (sigismember(&chkset, SIG_IPI) || sigismember(&chkset, SIGBUS));
-
-#ifndef CONFIG_IOTHREAD
-    if (sigismember(&chkset, SIGIO) || sigismember(&chkset, SIGALRM)) {
-        qemu_notify_event();
-    }
-#endif
 }
 
 #else /* !CONFIG_LINUX */
@@ -390,7 +380,6 @@ static int qemu_signal_init(void)
     int sigfd;
     sigset_t set;
 
-#ifdef CONFIG_IOTHREAD
     /* SIGUSR2 used by posix-aio-compat.c */
     sigemptyset(&set);
     sigaddset(&set, SIGUSR2);
@@ -409,18 +398,6 @@ static int qemu_signal_init(void)
     sigaddset(&set, SIGIO);
     sigaddset(&set, SIGALRM);
     sigaddset(&set, SIGBUS);
-#else
-    sigemptyset(&set);
-    sigaddset(&set, SIGBUS);
-    if (kvm_enabled()) {
-        /*
-         * We need to process timer signals synchronously to avoid a race
-         * between exit_request check and KVM vcpu entry.
-         */
-        sigaddset(&set, SIGIO);
-        sigaddset(&set, SIGALRM);
-    }
-#endif
     pthread_sigmask(SIG_BLOCK, &set, NULL);
 
     sigfd = qemu_signalfd(&set);
@@ -447,7 +424,6 @@ static void qemu_kvm_init_cpu_signals(CPUState *env)
     sigact.sa_handler = dummy_signal;
     sigaction(SIG_IPI, &sigact, NULL);
 
-#ifdef CONFIG_IOTHREAD
     pthread_sigmask(SIG_BLOCK, NULL, &set);
     sigdelset(&set, SIG_IPI);
     sigdelset(&set, SIGBUS);
@@ -456,17 +432,7 @@ static void qemu_kvm_init_cpu_signals(CPUState *env)
         fprintf(stderr, "kvm_set_signal_mask: %s\n", strerror(-r));
         exit(1);
     }
-#else
-    sigemptyset(&set);
-    sigaddset(&set, SIG_IPI);
-    sigaddset(&set, SIGIO);
-    sigaddset(&set, SIGALRM);
-    pthread_sigmask(SIG_BLOCK, &set, NULL);
 
-    pthread_sigmask(SIG_BLOCK, NULL, &set);
-    sigdelset(&set, SIGIO);
-    sigdelset(&set, SIGALRM);
-#endif
     sigdelset(&set, SIG_IPI);
     sigdelset(&set, SIGBUS);
     r = kvm_set_signal_mask(env, &set);
@@ -478,7 +444,6 @@ static void qemu_kvm_init_cpu_signals(CPUState *env)
 
 static void qemu_tcg_init_cpu_signals(void)
 {
-#ifdef CONFIG_IOTHREAD
     sigset_t set;
     struct sigaction sigact;
 
@@ -489,7 +454,6 @@ static void qemu_tcg_init_cpu_signals(void)
     sigemptyset(&set);
     sigaddset(&set, SIG_IPI);
     pthread_sigmask(SIG_UNBLOCK, &set, NULL);
-#endif
 }
 
 #else /* _WIN32 */
@@ -535,106 +499,6 @@ static void qemu_tcg_init_cpu_signals(void)
 }
 #endif /* _WIN32 */
 
-#ifndef CONFIG_IOTHREAD
-int qemu_init_main_loop(void)
-{
-    int ret;
-
-    ret = qemu_signal_init();
-    if (ret) {
-        return ret;
-    }
-
-    qemu_init_sigbus();
-
-    return qemu_event_init();
-}
-
-void qemu_main_loop_start(void)
-{
-}
-
-void qemu_init_vcpu(void *_env)
-{
-    CPUState *env = _env;
-    int r;
-
-    env->nr_cores = smp_cores;
-    env->nr_threads = smp_threads;
-
-    if (kvm_enabled()) {
-        r = kvm_init_vcpu(env);
-        if (r < 0) {
-            fprintf(stderr, "kvm_init_vcpu failed: %s\n", strerror(-r));
-            exit(1);
-        }
-        qemu_kvm_init_cpu_signals(env);
-    } else {
-        qemu_tcg_init_cpu_signals();
-    }
-}
-
-int qemu_cpu_is_self(void *env)
-{
-    return 1;
-}
-
-void run_on_cpu(CPUState *env, void (*func)(void *data), void *data)
-{
-    func(data);
-}
-
-void resume_all_vcpus(void)
-{
-}
-
-void pause_all_vcpus(void)
-{
-}
-
-void qemu_cpu_kick(void *env)
-{
-}
-
-void qemu_cpu_kick_self(void)
-{
-#ifndef _WIN32
-    assert(cpu_single_env);
-
-    raise(SIG_IPI);
-#else
-    abort();
-#endif
-}
-
-void qemu_notify_event(void)
-{
-    CPUState *env = cpu_single_env;
-
-    qemu_event_increment ();
-    if (env) {
-        cpu_exit(env);
-    }
-    if (next_cpu && env != next_cpu) {
-        cpu_exit(next_cpu);
-    }
-    exit_request = 1;
-}
-
-void qemu_mutex_lock_iothread(void) {}
-void qemu_mutex_unlock_iothread(void) {}
-
-void cpu_stop_current(void)
-{
-}
-
-void vm_stop(int reason)
-{
-    do_vm_stop(reason);
-}
-
-#else /* CONFIG_IOTHREAD */
-
 QemuMutex qemu_global_mutex;
 static QemuCond qemu_io_proceeded_cond;
 static bool iothread_requesting_mutex;
@@ -1028,8 +892,6 @@ void vm_stop(int reason)
     do_vm_stop(reason);
 }
 
-#endif
-
 static int tcg_cpu_exec(CPUState *env)
 {
     int ret;
@@ -1084,11 +946,6 @@ bool cpu_exec_all(void)
         qemu_clock_enable(vm_clock,
                           (env->singlestep_enabled & SSTEP_NOTIMER) == 0);
 
-#ifndef CONFIG_IOTHREAD
-        if (qemu_alarm_pending()) {
-            break;
-        }
-#endif
         if (cpu_can_run(env)) {
             if (kvm_enabled()) {
                 r = kvm_cpu_exec(env);
diff --git a/hw/qxl.c b/hw/qxl.c
index 1d9077d..45e2401 100644
--- a/hw/qxl.c
+++ b/hw/qxl.c
@@ -1388,11 +1388,7 @@ static void init_pipe_signaling(PCIQXLDevice *d)
        dprint(d, 1, "%s: pipe creation failed\n", __FUNCTION__);
        return;
    }
-#ifdef CONFIG_IOTHREAD
    fcntl(d->pipe[0], F_SETFL, O_NONBLOCK);
-#else
-   fcntl(d->pipe[0], F_SETFL, O_NONBLOCK /* | O_ASYNC */);
-#endif
    fcntl(d->pipe[1], F_SETFL, O_NONBLOCK);
    fcntl(d->pipe[0], F_SETOWN, getpid());
 
diff --git a/kvm-all.c b/kvm-all.c
index 0ae2e26..fbb9ff3 100644
--- a/kvm-all.c
+++ b/kvm-all.c
@@ -479,7 +479,7 @@ static int kvm_check_many_ioeventfds(void)
      * Older kernels have a 6 device limit on the KVM io bus.  Find out so we
      * can avoid creating too many ioeventfds.
      */
-#if defined(CONFIG_EVENTFD) && defined(CONFIG_IOTHREAD)
+#if defined(CONFIG_EVENTFD)
     int ioeventfds[7];
     int i, ret = 0;
     for (i = 0; i < ARRAY_SIZE(ioeventfds); i++) {
diff --git a/qemu-timer.c b/qemu-timer.c
index 19313d3..46dd483 100644
--- a/qemu-timer.c
+++ b/qemu-timer.c
@@ -101,22 +101,6 @@ static int64_t cpu_get_clock(void)
     }
 }
 
-#ifndef CONFIG_IOTHREAD
-static int64_t qemu_icount_delta(void)
-{
-    if (!use_icount) {
-        return 5000 * (int64_t) 1000000;
-    } else if (use_icount == 1) {
-        /* When not using an adaptive execution frequency
-           we tend to get badly out of sync with real time,
-           so just delay for a reasonable amount of time.  */
-        return 0;
-    } else {
-        return cpu_get_icount() - cpu_get_clock();
-    }
-}
-#endif
-
 /* enable cpu_get_ticks() */
 void cpu_enable_ticks(void)
 {
@@ -688,9 +672,7 @@ void configure_icount(const char *option)
     if (!option)
         return;
 
-#ifdef CONFIG_IOTHREAD
     vm_clock->warp_timer = qemu_new_timer_ns(rt_clock, icount_warp_rt, NULL);
-#endif
 
     if (strcmp(option, "auto") != 0) {
         icount_time_shift = strtol(option, NULL, 0);
@@ -1178,41 +1160,6 @@ void quit_timers(void)
 
 int qemu_calculate_timeout(void)
 {
-#ifndef CONFIG_IOTHREAD
-    int timeout;
-
-    if (!vm_running)
-        timeout = 5000;
-    else {
-     /* XXX: use timeout computed from timers */
-        int64_t add;
-        int64_t delta;
-        /* Advance virtual time to the next event.  */
-	delta = qemu_icount_delta();
-        if (delta > 0) {
-            /* If virtual time is ahead of real time then just
-               wait for IO.  */
-            timeout = (delta + 999999) / 1000000;
-        } else {
-            /* Wait for either IO to occur or the next
-               timer event.  */
-            add = qemu_next_icount_deadline();
-            /* We advance the timer before checking for IO.
-               Limit the amount we advance so that early IO
-               activity won't get the guest too far ahead.  */
-            if (add > 10000000)
-                add = 10000000;
-            delta += add;
-            qemu_icount += qemu_icount_round (add);
-            timeout = delta / 1000000;
-            if (timeout < 0)
-                timeout = 0;
-        }
-    }
-
-    return timeout;
-#else /* CONFIG_IOTHREAD */
     return 1000;
-#endif
 }
 
diff --git a/vl.c b/vl.c
index 60bce0c..7a6fbac 100644
--- a/vl.c
+++ b/vl.c
@@ -1445,17 +1445,6 @@ int main_loop_wait(int nonblocking)
     return ret;
 }
 
-#ifndef CONFIG_IOTHREAD
-static int vm_request_pending(void)
-{
-    return powerdown_requested ||
-           reset_requested ||
-           shutdown_requested ||
-           debug_requested ||
-           vmstop_requested;
-}
-#endif
-
 qemu_irq qemu_system_powerdown;
 
 static void main_loop(void)
@@ -1470,14 +1459,7 @@ static void main_loop(void)
     qemu_main_loop_start();
 
     for (;;) {
-#ifdef CONFIG_IOTHREAD
         nonblocking = !kvm_enabled() && last_io > 0;
-#else
-        nonblocking = cpu_exec_all();
-        if (vm_request_pending()) {
-            nonblocking = true;
-        }
-#endif
 #ifdef CONFIG_PROFILER
         ti = profile_getclock();
 #endif
commit d9cd446b4f6ff464f9520898116534de988d9bc1
Author: Anthony Liguori <aliguori at us.ibm.com>
Date:   Fri Sep 2 10:28:35 2011 -0500

    trace: fix out-of-tree builds
    
    Reported-by: Lluis Vilanova <vilanova at ac.upc.edu>
    Signed-off-by: Anthony Liguori <aliguori at us.ibm.com>

diff --git a/configure b/configure
index 300d34b..1fb31c7 100755
--- a/configure
+++ b/configure
@@ -3617,7 +3617,7 @@ DIRS="$DIRS pc-bios/spapr-rtas"
 DIRS="$DIRS roms/seabios roms/vgabios"
 DIRS="$DIRS fsdev ui"
 DIRS="$DIRS qapi"
-DIRS="$DIRS qga"
+DIRS="$DIRS qga trace"
 FILES="Makefile tests/Makefile"
 FILES="$FILES tests/cris/Makefile tests/cris/.gdbinit"
 FILES="$FILES pc-bios/optionrom/Makefile pc-bios/keymaps"
commit 88adbdfdf4b33210ba7acb0a30c292d301ca1554
Merge: 625f9e1... d8e8ef4...
Author: Anthony Liguori <aliguori at us.ibm.com>
Date:   Fri Sep 2 10:08:48 2011 -0500

    Merge remote-tracking branch 'stefanha/tracing' into staging

commit 625f9e1f54cd78ee98ac22030da527c9a1cc9d2b
Merge: a952c57... 2542bfd...
Author: Anthony Liguori <aliguori at us.ibm.com>
Date:   Thu Sep 1 13:57:19 2011 -0500

    Merge remote-tracking branch 'stefanha/trivial-patches' into staging

commit a952c570c865d5eae6c148716f2cb585a0d3a2ee
Merge: e2a99ad... 021d26d...
Author: Anthony Liguori <aliguori at us.ibm.com>
Date:   Thu Sep 1 13:55:58 2011 -0500

    Merge remote-tracking branch 'qemu-kvm-tmp/memory/core' into staging

commit e2a99ad3e174ab4c9d2320dcecd779230409829f
Author: Stefan Hajnoczi <stefanha at linux.vnet.ibm.com>
Date:   Thu Aug 25 09:18:52 2011 +0100

    build: sort objects to remove duplicates for link
    
    Avoid duplicate object files during the link.  There are legitimate
    cases where a link command-line would include duplicate object files
    because two independent subsystems both depend on common infrastructure.
    
    Use GNU make's $(sort) function to remove duplicate object files from
    the link command-line.
    
    Signed-off-by: Stefan Hajnoczi <stefanha at linux.vnet.ibm.com>
    Signed-off-by: Anthony Liguori <aliguori at us.ibm.com>

diff --git a/rules.mak b/rules.mak
index 884d421..04a9198 100644
--- a/rules.mak
+++ b/rules.mak
@@ -31,7 +31,7 @@ endif
 %.o: %.m
 	$(call quiet-command,$(CC) $(QEMU_INCLUDES) $(QEMU_CFLAGS) $(QEMU_DGFLAGS) $(CFLAGS) -c -o $@ $<,"  OBJC  $(TARGET_DIR)$@")
 
-LINK = $(call quiet-command,$(CC) $(QEMU_CFLAGS) $(CFLAGS) $(LDFLAGS) -o $@ $(1) $(LIBS),"  LINK  $(TARGET_DIR)$@")
+LINK = $(call quiet-command,$(CC) $(QEMU_CFLAGS) $(CFLAGS) $(LDFLAGS) -o $@ $(sort $(1)) $(LIBS),"  LINK  $(TARGET_DIR)$@")
 
 %$(EXESUF): %.o
 	$(call LINK,$^)
commit 4d88a2ac8643265108ef1fb47ceee5d7b28e19f2
Author: Anthony Liguori <aliguori at us.ibm.com>
Date:   Mon Aug 22 08:12:53 2011 -0500

    main: switch qemu_set_fd_handler to g_io_add_watch
    
    This patch changes qemu_set_fd_handler to be implemented in terms of
    g_io_add_watch().  The semantics are a bit different so some glue is required.
    
    qemu_set_fd_handler2 is much harder to convert because of its use of polling.
    
    The glib main loop has the major of advantage of having a proven thread safe
    architecture.  By using the glib main loop instead of our own, it will allow us
    to eventually introduce multiple I/O threads.
    
    I'm pretty sure that this will work on Win32, but I would appreciate some help
    testing.  I think the semantics of g_io_channel_unix_new() are really just tied
    to the notion of a "unix fd" and not necessarily unix itself.
    
    Signed-off-by: Anthony Liguori <aliguori at us.ibm.com>

diff --git a/iohandler.c b/iohandler.c
index 4deae1e..5ef66fb 100644
--- a/iohandler.c
+++ b/iohandler.c
@@ -80,12 +80,67 @@ int qemu_set_fd_handler2(int fd,
     return 0;
 }
 
+typedef struct IOTrampoline
+{
+    GIOChannel *chan;
+    IOHandler *fd_read;
+    IOHandler *fd_write;
+    void *opaque;
+    guint tag;
+} IOTrampoline;
+
+static gboolean fd_trampoline(GIOChannel *chan, GIOCondition cond, gpointer opaque)
+{
+    IOTrampoline *tramp = opaque;
+
+    if (tramp->opaque == NULL) {
+        return FALSE;
+    }
+
+    if ((cond & G_IO_IN) && tramp->fd_read) {
+        tramp->fd_read(tramp->opaque);
+    }
+
+    if ((cond & G_IO_OUT) && tramp->fd_write) {
+        tramp->fd_write(tramp->opaque);
+    }
+
+    return TRUE;
+}
+
 int qemu_set_fd_handler(int fd,
                         IOHandler *fd_read,
                         IOHandler *fd_write,
                         void *opaque)
 {
-    return qemu_set_fd_handler2(fd, NULL, fd_read, fd_write, opaque);
+    static IOTrampoline fd_trampolines[FD_SETSIZE];
+    IOTrampoline *tramp = &fd_trampolines[fd];
+
+    if (tramp->tag != 0) {
+        g_io_channel_unref(tramp->chan);
+        g_source_remove(tramp->tag);
+    }
+
+    if (opaque) {
+        GIOCondition cond = 0;
+
+        tramp->fd_read = fd_read;
+        tramp->fd_write = fd_write;
+        tramp->opaque = opaque;
+
+        if (fd_read) {
+            cond |= G_IO_IN | G_IO_ERR;
+        }
+
+        if (fd_write) {
+            cond |= G_IO_OUT | G_IO_ERR;
+        }
+
+        tramp->chan = g_io_channel_unix_new(fd);
+        tramp->tag = g_io_add_watch(tramp->chan, cond, fd_trampoline, tramp);
+    }
+
+    return 0;
 }
 
 void qemu_iohandler_fill(int *pnfds, fd_set *readfds, fd_set *writefds, fd_set *xfds)
commit 69e5bb68a5e95286edd59c3ce34c6f7bae5b5548
Author: Anthony Liguori <aliguori at us.ibm.com>
Date:   Mon Aug 22 08:12:52 2011 -0500

    Add glib support to main loop
    
    This allows GSources to be used to register callback events in QEMU.  This is
    useful as it allows us to take greater advantage of glib and also because it
    allows us to write code that is more easily testable outside of QEMU since we
    can make use of glib's main loop in unit tests.
    
    All new code should use glib's callback mechanisms for registering fd events
    which are very well documented at:
    
    http://developer.gnome.org/glib/stable/glib-The-Main-Event-Loop.html
    
    And:
    
    http://developer.gnome.org/gio/stable/
    
    Signed-off-by: Anthony Liguori <aliguori at us.ibm.com>
    Signed-off-by: Anthony Liguori <aliguori at us.ibm.com>

diff --git a/vl.c b/vl.c
index 9cd67a3..a6f4c71 100644
--- a/vl.c
+++ b/vl.c
@@ -111,6 +111,8 @@ int main(int argc, char **argv)
 #define main qemu_main
 #endif /* CONFIG_COCOA */
 
+#include <glib.h>
+
 #include "hw/hw.h"
 #include "hw/boards.h"
 #include "hw/usb.h"
@@ -1321,6 +1323,75 @@ void qemu_system_vmstop_request(int reason)
     qemu_notify_event();
 }
 
+static GPollFD poll_fds[1024 * 2]; /* this is probably overkill */
+static int n_poll_fds;
+static int max_priority;
+
+static void glib_select_fill(int *max_fd, fd_set *rfds, fd_set *wfds,
+                             fd_set *xfds, struct timeval *tv)
+{
+    GMainContext *context = g_main_context_default();
+    int i;
+    int timeout = 0, cur_timeout;
+
+    g_main_context_prepare(context, &max_priority);
+
+    n_poll_fds = g_main_context_query(context, max_priority, &timeout,
+                                      poll_fds, ARRAY_SIZE(poll_fds));
+    g_assert(n_poll_fds <= ARRAY_SIZE(poll_fds));
+
+    for (i = 0; i < n_poll_fds; i++) {
+        GPollFD *p = &poll_fds[i];
+
+        if ((p->events & G_IO_IN)) {
+            FD_SET(p->fd, rfds);
+            *max_fd = MAX(*max_fd, p->fd);
+        }
+        if ((p->events & G_IO_OUT)) {
+            FD_SET(p->fd, wfds);
+            *max_fd = MAX(*max_fd, p->fd);
+        }
+        if ((p->events & G_IO_ERR)) {
+            FD_SET(p->fd, xfds);
+            *max_fd = MAX(*max_fd, p->fd);
+        }
+    }
+
+    cur_timeout = (tv->tv_sec * 1000) + ((tv->tv_usec + 500) / 1000);
+    if (timeout >= 0 && timeout < cur_timeout) {
+        tv->tv_sec = timeout / 1000;
+        tv->tv_usec = (timeout % 1000) * 1000;
+    }
+}
+
+static void glib_select_poll(fd_set *rfds, fd_set *wfds, fd_set *xfds,
+                             bool err)
+{
+    GMainContext *context = g_main_context_default();
+
+    if (!err) {
+        int i;
+
+        for (i = 0; i < n_poll_fds; i++) {
+            GPollFD *p = &poll_fds[i];
+
+            if ((p->events & G_IO_IN) && FD_ISSET(p->fd, rfds)) {
+                p->revents |= G_IO_IN;
+            }
+            if ((p->events & G_IO_OUT) && FD_ISSET(p->fd, wfds)) {
+                p->revents |= G_IO_OUT;
+            }
+            if ((p->events & G_IO_ERR) && FD_ISSET(p->fd, xfds)) {
+                p->revents |= G_IO_ERR;
+            }
+        }
+    }
+
+    if (g_main_context_check(context, max_priority, poll_fds, n_poll_fds)) {
+        g_main_context_dispatch(context);
+    }
+}
+
 int main_loop_wait(int nonblocking)
 {
     fd_set rfds, wfds, xfds;
@@ -1346,8 +1417,10 @@ int main_loop_wait(int nonblocking)
     FD_ZERO(&rfds);
     FD_ZERO(&wfds);
     FD_ZERO(&xfds);
+
     qemu_iohandler_fill(&nfds, &rfds, &wfds, &xfds);
     slirp_select_fill(&nfds, &rfds, &wfds, &xfds);
+    glib_select_fill(&nfds, &rfds, &wfds, &xfds, &tv);
 
     if (timeout > 0) {
         qemu_mutex_unlock_iothread();
@@ -1361,6 +1434,7 @@ int main_loop_wait(int nonblocking)
 
     qemu_iohandler_poll(&rfds, &wfds, &xfds, ret);
     slirp_select_poll(&rfds, &wfds, &xfds, (ret < 0));
+    glib_select_poll(&rfds, &wfds, &xfds, (ret < 0));
 
     qemu_run_all_timers();
 
commit 70d705fd46ccd7afe1d0ad07a6f1ee2101a979db
Author: Peter Maydell <peter.maydell at linaro.org>
Date:   Thu Sep 1 16:45:01 2011 +0100

    tcg/ppc/tcg-target.c: Avoid 'set but not used' gcc warnings
    
    Move the declaration and initialisation of some variables in
    tcg_out_qemu_ld and tcg_out_qemu_st inside CONFIG_SOFTMMU, to
    avoid the "variable set but not used" warning of gcc 4.6.
    
    Signed-off-by: Peter Maydell <peter.maydell at linaro.org>
    Signed-off-by: malc <av1474 at comtv.ru>

diff --git a/tcg/ppc/tcg-target.c b/tcg/ppc/tcg-target.c
index 4462647..87cc117 100644
--- a/tcg/ppc/tcg-target.c
+++ b/tcg/ppc/tcg-target.c
@@ -525,14 +525,14 @@ static void *qemu_st_helpers[4] = {
 
 static void tcg_out_qemu_ld (TCGContext *s, const TCGArg *args, int opc)
 {
-    int addr_reg, data_reg, data_reg2, r0, r1, rbase, mem_index, s_bits, bswap;
+    int addr_reg, data_reg, data_reg2, r0, r1, rbase, bswap;
 #ifdef CONFIG_SOFTMMU
-    int r2;
+    int mem_index, s_bits, r2;
     void *label1_ptr, *label2_ptr;
-#endif
 #if TARGET_LONG_BITS == 64
     int addr_reg2;
 #endif
+#endif
 
     data_reg = *args++;
     if (opc == 3)
@@ -540,13 +540,13 @@ static void tcg_out_qemu_ld (TCGContext *s, const TCGArg *args, int opc)
     else
         data_reg2 = 0;
     addr_reg = *args++;
+
+#ifdef CONFIG_SOFTMMU
 #if TARGET_LONG_BITS == 64
     addr_reg2 = *args++;
 #endif
     mem_index = *args;
     s_bits = opc & 3;
-
-#ifdef CONFIG_SOFTMMU
     r0 = 3;
     r1 = 4;
     r2 = 0;
@@ -722,14 +722,14 @@ static void tcg_out_qemu_ld (TCGContext *s, const TCGArg *args, int opc)
 
 static void tcg_out_qemu_st (TCGContext *s, const TCGArg *args, int opc)
 {
-    int addr_reg, r0, r1, data_reg, data_reg2, mem_index, bswap, rbase;
+    int addr_reg, r0, r1, data_reg, data_reg2, bswap, rbase;
 #ifdef CONFIG_SOFTMMU
-    int r2, ir;
+    int mem_index, r2, ir;
     void *label1_ptr, *label2_ptr;
-#endif
 #if TARGET_LONG_BITS == 64
     int addr_reg2;
 #endif
+#endif
 
     data_reg = *args++;
     if (opc == 3)
@@ -737,12 +737,12 @@ static void tcg_out_qemu_st (TCGContext *s, const TCGArg *args, int opc)
     else
         data_reg2 = 0;
     addr_reg = *args++;
+
+#ifdef CONFIG_SOFTMMU
 #if TARGET_LONG_BITS == 64
     addr_reg2 = *args++;
 #endif
     mem_index = *args;
-
-#ifdef CONFIG_SOFTMMU
     r0 = 3;
     r1 = 4;
     r2 = 0;
commit d8e8ef4ee05bfee0df84e2665d9196c4a954c095
Author: Stefan Hajnoczi <stefanha at linux.vnet.ibm.com>
Date:   Thu Aug 25 18:03:49 2011 +0100

    simpletrace: fix process() argument count
    
    The simpletrace.process() function invokes analyzer methods with the
    wrong number of arguments if a timestamp should be included.  This patch
    fixes the issue so that trace analysis scripts can make use of
    timestamps.
    
    Signed-off-by: Stefan Hajnoczi <stefanha at linux.vnet.ibm.com>

diff --git a/scripts/simpletrace.py b/scripts/simpletrace.py
index 2ad5699..f55e5e6 100755
--- a/scripts/simpletrace.py
+++ b/scripts/simpletrace.py
@@ -102,10 +102,10 @@ def process(events, log, analyzer):
         fn_argcount = len(inspect.getargspec(fn)[0]) - 1
         if fn_argcount == event_argcount + 1:
             # Include timestamp as first argument
-            return lambda _, rec: fn(*rec[1:2 + fn_argcount])
+            return lambda _, rec: fn(*rec[1:2 + event_argcount])
         else:
             # Just arguments, no timestamp
-            return lambda _, rec: fn(*rec[2:2 + fn_argcount])
+            return lambda _, rec: fn(*rec[2:2 + event_argcount])
 
     analyzer.begin()
     fn_cache = {}
commit 47f08d7a9ddced79d08aa9ad69fe2ddfadd4f791
Author: Lluís <xscript at gmx.net>
Date:   Wed Aug 31 20:31:58 2011 +0200

    trace: enable all events
    
    Given that all events with programmatically-controlled state are disabled by
    default, we can delete the "disable" property from all events.
    
    Signed-off-by: Lluís Vilanova <vilanova at ac.upc.edu>

diff --git a/trace-events b/trace-events
index eb612e8..98f3ec2 100644
--- a/trace-events
+++ b/trace-events
@@ -26,439 +26,439 @@
 # The <format-string> should be a sprintf()-compatible format string.
 
 # qemu-malloc.c
-disable qemu_malloc(size_t size, void *ptr) "size %zu ptr %p"
-disable qemu_realloc(void *ptr, size_t size, void *newptr) "ptr %p size %zu newptr %p"
-disable qemu_free(void *ptr) "ptr %p"
+qemu_malloc(size_t size, void *ptr) "size %zu ptr %p"
+qemu_realloc(void *ptr, size_t size, void *newptr) "ptr %p size %zu newptr %p"
+qemu_free(void *ptr) "ptr %p"
 
 # osdep.c
-disable qemu_memalign(size_t alignment, size_t size, void *ptr) "alignment %zu size %zu ptr %p"
-disable qemu_vmalloc(size_t size, void *ptr) "size %zu ptr %p"
-disable qemu_vfree(void *ptr) "ptr %p"
+qemu_memalign(size_t alignment, size_t size, void *ptr) "alignment %zu size %zu ptr %p"
+qemu_vmalloc(size_t size, void *ptr) "size %zu ptr %p"
+qemu_vfree(void *ptr) "ptr %p"
 
 # hw/virtio.c
-disable virtqueue_fill(void *vq, const void *elem, unsigned int len, unsigned int idx) "vq %p elem %p len %u idx %u"
-disable virtqueue_flush(void *vq, unsigned int count) "vq %p count %u"
-disable virtqueue_pop(void *vq, void *elem, unsigned int in_num, unsigned int out_num) "vq %p elem %p in_num %u out_num %u"
-disable virtio_queue_notify(void *vdev, int n, void *vq) "vdev %p n %d vq %p"
-disable virtio_irq(void *vq) "vq %p"
-disable virtio_notify(void *vdev, void *vq) "vdev %p vq %p"
+virtqueue_fill(void *vq, const void *elem, unsigned int len, unsigned int idx) "vq %p elem %p len %u idx %u"
+virtqueue_flush(void *vq, unsigned int count) "vq %p count %u"
+virtqueue_pop(void *vq, void *elem, unsigned int in_num, unsigned int out_num) "vq %p elem %p in_num %u out_num %u"
+virtio_queue_notify(void *vdev, int n, void *vq) "vdev %p n %d vq %p"
+virtio_irq(void *vq) "vq %p"
+virtio_notify(void *vdev, void *vq) "vdev %p vq %p"
 
 # hw/virtio-serial-bus.c
-disable virtio_serial_send_control_event(unsigned int port, uint16_t event, uint16_t value) "port %u, event %u, value %u"
-disable virtio_serial_throttle_port(unsigned int port, bool throttle) "port %u, throttle %d"
-disable virtio_serial_handle_control_message(uint16_t event, uint16_t value) "event %u, value %u"
-disable virtio_serial_handle_control_message_port(unsigned int port) "port %u"
+virtio_serial_send_control_event(unsigned int port, uint16_t event, uint16_t value) "port %u, event %u, value %u"
+virtio_serial_throttle_port(unsigned int port, bool throttle) "port %u, throttle %d"
+virtio_serial_handle_control_message(uint16_t event, uint16_t value) "event %u, value %u"
+virtio_serial_handle_control_message_port(unsigned int port) "port %u"
 
 # hw/virtio-console.c
-disable virtio_console_flush_buf(unsigned int port, size_t len, ssize_t ret) "port %u, in_len %zu, out_len %zd"
-disable virtio_console_chr_read(unsigned int port, int size) "port %u, size %d"
-disable virtio_console_chr_event(unsigned int port, int event) "port %u, event %d"
+virtio_console_flush_buf(unsigned int port, size_t len, ssize_t ret) "port %u, in_len %zu, out_len %zd"
+virtio_console_chr_read(unsigned int port, int size) "port %u, size %d"
+virtio_console_chr_event(unsigned int port, int event) "port %u, event %d"
 
 # block.c
-disable multiwrite_cb(void *mcb, int ret) "mcb %p ret %d"
-disable bdrv_aio_multiwrite(void *mcb, int num_callbacks, int num_reqs) "mcb %p num_callbacks %d num_reqs %d"
-disable bdrv_aio_multiwrite_earlyfail(void *mcb) "mcb %p"
-disable bdrv_aio_multiwrite_latefail(void *mcb, int i) "mcb %p i %d"
-disable bdrv_aio_flush(void *bs, void *opaque) "bs %p opaque %p"
-disable bdrv_aio_readv(void *bs, int64_t sector_num, int nb_sectors, void *opaque) "bs %p sector_num %"PRId64" nb_sectors %d opaque %p"
-disable bdrv_aio_writev(void *bs, int64_t sector_num, int nb_sectors, void *opaque) "bs %p sector_num %"PRId64" nb_sectors %d opaque %p"
-disable bdrv_set_locked(void *bs, int locked) "bs %p locked %d"
-disable bdrv_co_readv(void *bs, int64_t sector_num, int nb_sector) "bs %p sector_num %"PRId64" nb_sectors %d"
-disable bdrv_co_writev(void *bs, int64_t sector_num, int nb_sector) "bs %p sector_num %"PRId64" nb_sectors %d"
-disable bdrv_co_io(int is_write, void *acb) "is_write %d acb %p"
+multiwrite_cb(void *mcb, int ret) "mcb %p ret %d"
+bdrv_aio_multiwrite(void *mcb, int num_callbacks, int num_reqs) "mcb %p num_callbacks %d num_reqs %d"
+bdrv_aio_multiwrite_earlyfail(void *mcb) "mcb %p"
+bdrv_aio_multiwrite_latefail(void *mcb, int i) "mcb %p i %d"
+bdrv_aio_flush(void *bs, void *opaque) "bs %p opaque %p"
+bdrv_aio_readv(void *bs, int64_t sector_num, int nb_sectors, void *opaque) "bs %p sector_num %"PRId64" nb_sectors %d opaque %p"
+bdrv_aio_writev(void *bs, int64_t sector_num, int nb_sectors, void *opaque) "bs %p sector_num %"PRId64" nb_sectors %d opaque %p"
+bdrv_set_locked(void *bs, int locked) "bs %p locked %d"
+bdrv_co_readv(void *bs, int64_t sector_num, int nb_sector) "bs %p sector_num %"PRId64" nb_sectors %d"
+bdrv_co_writev(void *bs, int64_t sector_num, int nb_sector) "bs %p sector_num %"PRId64" nb_sectors %d"
+bdrv_co_io(int is_write, void *acb) "is_write %d acb %p"
 
 # hw/virtio-blk.c
-disable virtio_blk_req_complete(void *req, int status) "req %p status %d"
-disable virtio_blk_rw_complete(void *req, int ret) "req %p ret %d"
-disable virtio_blk_handle_write(void *req, uint64_t sector, size_t nsectors) "req %p sector %"PRIu64" nsectors %zu"
+virtio_blk_req_complete(void *req, int status) "req %p status %d"
+virtio_blk_rw_complete(void *req, int ret) "req %p ret %d"
+virtio_blk_handle_write(void *req, uint64_t sector, size_t nsectors) "req %p sector %"PRIu64" nsectors %zu"
 
 # posix-aio-compat.c
-disable paio_submit(void *acb, void *opaque, int64_t sector_num, int nb_sectors, int type) "acb %p opaque %p sector_num %"PRId64" nb_sectors %d type %d"
-disable paio_complete(void *acb, void *opaque, int ret) "acb %p opaque %p ret %d"
-disable paio_cancel(void *acb, void *opaque) "acb %p opaque %p"
+paio_submit(void *acb, void *opaque, int64_t sector_num, int nb_sectors, int type) "acb %p opaque %p sector_num %"PRId64" nb_sectors %d type %d"
+paio_complete(void *acb, void *opaque, int ret) "acb %p opaque %p ret %d"
+paio_cancel(void *acb, void *opaque) "acb %p opaque %p"
 
 # ioport.c
-disable cpu_in(unsigned int addr, unsigned int val) "addr %#x value %u"
-disable cpu_out(unsigned int addr, unsigned int val) "addr %#x value %u"
+cpu_in(unsigned int addr, unsigned int val) "addr %#x value %u"
+cpu_out(unsigned int addr, unsigned int val) "addr %#x value %u"
 
 # balloon.c
 # Since requests are raised via monitor, not many tracepoints are needed.
-disable balloon_event(void *opaque, unsigned long addr) "opaque %p addr %lu"
+balloon_event(void *opaque, unsigned long addr) "opaque %p addr %lu"
 
 # hw/apic.c
-disable apic_local_deliver(int vector, uint32_t lvt) "vector %d delivery mode %d"
-disable apic_deliver_irq(uint8_t dest, uint8_t dest_mode, uint8_t delivery_mode, uint8_t vector_num, uint8_t trigger_mode) "dest %d dest_mode %d delivery_mode %d vector %d trigger_mode %d"
-disable cpu_set_apic_base(uint64_t val) "%016"PRIx64""
-disable cpu_get_apic_base(uint64_t val) "%016"PRIx64""
-disable apic_mem_readl(uint64_t addr, uint32_t val)  "%"PRIx64" = %08x"
-disable apic_mem_writel(uint64_t addr, uint32_t val) "%"PRIx64" = %08x"
+apic_local_deliver(int vector, uint32_t lvt) "vector %d delivery mode %d"
+apic_deliver_irq(uint8_t dest, uint8_t dest_mode, uint8_t delivery_mode, uint8_t vector_num, uint8_t trigger_mode) "dest %d dest_mode %d delivery_mode %d vector %d trigger_mode %d"
+cpu_set_apic_base(uint64_t val) "%016"PRIx64""
+cpu_get_apic_base(uint64_t val) "%016"PRIx64""
+apic_mem_readl(uint64_t addr, uint32_t val)  "%"PRIx64" = %08x"
+apic_mem_writel(uint64_t addr, uint32_t val) "%"PRIx64" = %08x"
 # coalescing
-disable apic_reset_irq_delivered(int apic_irq_delivered) "old coalescing %d"
-disable apic_get_irq_delivered(int apic_irq_delivered) "returning coalescing %d"
-disable apic_set_irq(int apic_irq_delivered) "coalescing %d"
+apic_reset_irq_delivered(int apic_irq_delivered) "old coalescing %d"
+apic_get_irq_delivered(int apic_irq_delivered) "returning coalescing %d"
+apic_set_irq(int apic_irq_delivered) "coalescing %d"
 
 # hw/cs4231.c
-disable cs4231_mem_readl_dreg(uint32_t reg, uint32_t ret) "read dreg %d: 0x%02x"
-disable cs4231_mem_readl_reg(uint32_t reg, uint32_t ret) "read reg %d: 0x%08x"
-disable cs4231_mem_writel_reg(uint32_t reg, uint32_t old, uint32_t val) "write reg %d: 0x%08x -> 0x%08x"
-disable cs4231_mem_writel_dreg(uint32_t reg, uint32_t old, uint32_t val) "write dreg %d: 0x%02x -> 0x%02x"
+cs4231_mem_readl_dreg(uint32_t reg, uint32_t ret) "read dreg %d: 0x%02x"
+cs4231_mem_readl_reg(uint32_t reg, uint32_t ret) "read reg %d: 0x%08x"
+cs4231_mem_writel_reg(uint32_t reg, uint32_t old, uint32_t val) "write reg %d: 0x%08x -> 0x%08x"
+cs4231_mem_writel_dreg(uint32_t reg, uint32_t old, uint32_t val) "write dreg %d: 0x%02x -> 0x%02x"
 
 # hw/ds1225y.c
-disable nvram_read(uint32_t addr, uint32_t ret) "read addr %d: 0x%02x"
-disable nvram_write(uint32_t addr, uint32_t old, uint32_t val) "write addr %d: 0x%02x -> 0x%02x"
+nvram_read(uint32_t addr, uint32_t ret) "read addr %d: 0x%02x"
+nvram_write(uint32_t addr, uint32_t old, uint32_t val) "write addr %d: 0x%02x -> 0x%02x"
 
 # hw/eccmemctl.c
-disable ecc_mem_writel_mer(uint32_t val) "Write memory enable %08x"
-disable ecc_mem_writel_mdr(uint32_t val) "Write memory delay %08x"
-disable ecc_mem_writel_mfsr(uint32_t val) "Write memory fault status %08x"
-disable ecc_mem_writel_vcr(uint32_t val) "Write slot configuration %08x"
-disable ecc_mem_writel_dr(uint32_t val) "Write diagnostic %08x"
-disable ecc_mem_writel_ecr0(uint32_t val) "Write event count 1 %08x"
-disable ecc_mem_writel_ecr1(uint32_t val) "Write event count 2 %08x"
-disable ecc_mem_readl_mer(uint32_t ret) "Read memory enable %08x"
-disable ecc_mem_readl_mdr(uint32_t ret) "Read memory delay %08x"
-disable ecc_mem_readl_mfsr(uint32_t ret) "Read memory fault status %08x"
-disable ecc_mem_readl_vcr(uint32_t ret) "Read slot configuration %08x"
-disable ecc_mem_readl_mfar0(uint32_t ret) "Read memory fault address 0 %08x"
-disable ecc_mem_readl_mfar1(uint32_t ret) "Read memory fault address 1 %08x"
-disable ecc_mem_readl_dr(uint32_t ret) "Read diagnostic %08x"
-disable ecc_mem_readl_ecr0(uint32_t ret) "Read event count 1 %08x"
-disable ecc_mem_readl_ecr1(uint32_t ret) "Read event count 2 %08x"
-disable ecc_diag_mem_writeb(uint64_t addr, uint32_t val) "Write diagnostic %"PRId64" = %02x"
-disable ecc_diag_mem_readb(uint64_t addr, uint32_t ret) "Read diagnostic %"PRId64"= %02x"
+ecc_mem_writel_mer(uint32_t val) "Write memory enable %08x"
+ecc_mem_writel_mdr(uint32_t val) "Write memory delay %08x"
+ecc_mem_writel_mfsr(uint32_t val) "Write memory fault status %08x"
+ecc_mem_writel_vcr(uint32_t val) "Write slot configuration %08x"
+ecc_mem_writel_dr(uint32_t val) "Write diagnostic %08x"
+ecc_mem_writel_ecr0(uint32_t val) "Write event count 1 %08x"
+ecc_mem_writel_ecr1(uint32_t val) "Write event count 2 %08x"
+ecc_mem_readl_mer(uint32_t ret) "Read memory enable %08x"
+ecc_mem_readl_mdr(uint32_t ret) "Read memory delay %08x"
+ecc_mem_readl_mfsr(uint32_t ret) "Read memory fault status %08x"
+ecc_mem_readl_vcr(uint32_t ret) "Read slot configuration %08x"
+ecc_mem_readl_mfar0(uint32_t ret) "Read memory fault address 0 %08x"
+ecc_mem_readl_mfar1(uint32_t ret) "Read memory fault address 1 %08x"
+ecc_mem_readl_dr(uint32_t ret) "Read diagnostic %08x"
+ecc_mem_readl_ecr0(uint32_t ret) "Read event count 1 %08x"
+ecc_mem_readl_ecr1(uint32_t ret) "Read event count 2 %08x"
+ecc_diag_mem_writeb(uint64_t addr, uint32_t val) "Write diagnostic %"PRId64" = %02x"
+ecc_diag_mem_readb(uint64_t addr, uint32_t ret) "Read diagnostic %"PRId64"= %02x"
 
 # hw/lance.c
-disable lance_mem_readw(uint64_t addr, uint32_t ret) "addr=%"PRIx64"val=0x%04x"
-disable lance_mem_writew(uint64_t addr, uint32_t val) "addr=%"PRIx64"val=0x%04x"
+lance_mem_readw(uint64_t addr, uint32_t ret) "addr=%"PRIx64"val=0x%04x"
+lance_mem_writew(uint64_t addr, uint32_t val) "addr=%"PRIx64"val=0x%04x"
 
 # hw/slavio_intctl.c
-disable slavio_intctl_mem_readl(uint32_t cpu, uint64_t addr, uint32_t ret) "read cpu %d reg 0x%"PRIx64" = %x"
-disable slavio_intctl_mem_writel(uint32_t cpu, uint64_t addr, uint32_t val) "write cpu %d reg 0x%"PRIx64" = %x"
-disable slavio_intctl_mem_writel_clear(uint32_t cpu, uint32_t val, uint32_t intreg_pending) "Cleared cpu %d irq mask %x, curmask %x"
-disable slavio_intctl_mem_writel_set(uint32_t cpu, uint32_t val, uint32_t intreg_pending) "Set cpu %d irq mask %x, curmask %x"
-disable slavio_intctlm_mem_readl(uint64_t addr, uint32_t ret) "read system reg 0x%"PRIx64" = %x"
-disable slavio_intctlm_mem_writel(uint64_t addr, uint32_t val) "write system reg 0x%"PRIx64" = %x"
-disable slavio_intctlm_mem_writel_enable(uint32_t val, uint32_t intregm_disabled) "Enabled master irq mask %x, curmask %x"
-disable slavio_intctlm_mem_writel_disable(uint32_t val, uint32_t intregm_disabled) "Disabled master irq mask %x, curmask %x"
-disable slavio_intctlm_mem_writel_target(uint32_t cpu) "Set master irq cpu %d"
-disable slavio_check_interrupts(uint32_t pending, uint32_t intregm_disabled) "pending %x disabled %x"
-disable slavio_set_irq(uint32_t target_cpu, int irq, uint32_t pil, int level) "Set cpu %d irq %d -> pil %d level %d"
-disable slavio_set_timer_irq_cpu(int cpu, int level) "Set cpu %d local timer level %d"
+slavio_intctl_mem_readl(uint32_t cpu, uint64_t addr, uint32_t ret) "read cpu %d reg 0x%"PRIx64" = %x"
+slavio_intctl_mem_writel(uint32_t cpu, uint64_t addr, uint32_t val) "write cpu %d reg 0x%"PRIx64" = %x"
+slavio_intctl_mem_writel_clear(uint32_t cpu, uint32_t val, uint32_t intreg_pending) "Cleared cpu %d irq mask %x, curmask %x"
+slavio_intctl_mem_writel_set(uint32_t cpu, uint32_t val, uint32_t intreg_pending) "Set cpu %d irq mask %x, curmask %x"
+slavio_intctlm_mem_readl(uint64_t addr, uint32_t ret) "read system reg 0x%"PRIx64" = %x"
+slavio_intctlm_mem_writel(uint64_t addr, uint32_t val) "write system reg 0x%"PRIx64" = %x"
+slavio_intctlm_mem_writel_enable(uint32_t val, uint32_t intregm_disabled) "Enabled master irq mask %x, curmask %x"
+slavio_intctlm_mem_writel_disable(uint32_t val, uint32_t intregm_disabled) "Disabled master irq mask %x, curmask %x"
+slavio_intctlm_mem_writel_target(uint32_t cpu) "Set master irq cpu %d"
+slavio_check_interrupts(uint32_t pending, uint32_t intregm_disabled) "pending %x disabled %x"
+slavio_set_irq(uint32_t target_cpu, int irq, uint32_t pil, int level) "Set cpu %d irq %d -> pil %d level %d"
+slavio_set_timer_irq_cpu(int cpu, int level) "Set cpu %d local timer level %d"
 
 # hw/slavio_misc.c
-disable slavio_misc_update_irq_raise(void) "Raise IRQ"
-disable slavio_misc_update_irq_lower(void) "Lower IRQ"
-disable slavio_set_power_fail(int power_failing, uint8_t config) "Power fail: %d, config: %d"
-disable slavio_cfg_mem_writeb(uint32_t val) "Write config %02x"
-disable slavio_cfg_mem_readb(uint32_t ret) "Read config %02x"
-disable slavio_diag_mem_writeb(uint32_t val) "Write diag %02x"
-disable slavio_diag_mem_readb(uint32_t ret) "Read diag %02x"
-disable slavio_mdm_mem_writeb(uint32_t val) "Write modem control %02x"
-disable slavio_mdm_mem_readb(uint32_t ret) "Read modem control %02x"
-disable slavio_aux1_mem_writeb(uint32_t val) "Write aux1 %02x"
-disable slavio_aux1_mem_readb(uint32_t ret) "Read aux1 %02x"
-disable slavio_aux2_mem_writeb(uint32_t val) "Write aux2 %02x"
-disable slavio_aux2_mem_readb(uint32_t ret) "Read aux2 %02x"
-disable apc_mem_writeb(uint32_t val) "Write power management %02x"
-disable apc_mem_readb(uint32_t ret) "Read power management %02x"
-disable slavio_sysctrl_mem_writel(uint32_t val) "Write system control %08x"
-disable slavio_sysctrl_mem_readl(uint32_t ret) "Read system control %08x"
-disable slavio_led_mem_writew(uint32_t val) "Write diagnostic LED %04x"
-disable slavio_led_mem_readw(uint32_t ret) "Read diagnostic LED %04x"
+slavio_misc_update_irq_raise(void) "Raise IRQ"
+slavio_misc_update_irq_lower(void) "Lower IRQ"
+slavio_set_power_fail(int power_failing, uint8_t config) "Power fail: %d, config: %d"
+slavio_cfg_mem_writeb(uint32_t val) "Write config %02x"
+slavio_cfg_mem_readb(uint32_t ret) "Read config %02x"
+slavio_diag_mem_writeb(uint32_t val) "Write diag %02x"
+slavio_diag_mem_readb(uint32_t ret) "Read diag %02x"
+slavio_mdm_mem_writeb(uint32_t val) "Write modem control %02x"
+slavio_mdm_mem_readb(uint32_t ret) "Read modem control %02x"
+slavio_aux1_mem_writeb(uint32_t val) "Write aux1 %02x"
+slavio_aux1_mem_readb(uint32_t ret) "Read aux1 %02x"
+slavio_aux2_mem_writeb(uint32_t val) "Write aux2 %02x"
+slavio_aux2_mem_readb(uint32_t ret) "Read aux2 %02x"
+apc_mem_writeb(uint32_t val) "Write power management %02x"
+apc_mem_readb(uint32_t ret) "Read power management %02x"
+slavio_sysctrl_mem_writel(uint32_t val) "Write system control %08x"
+slavio_sysctrl_mem_readl(uint32_t ret) "Read system control %08x"
+slavio_led_mem_writew(uint32_t val) "Write diagnostic LED %04x"
+slavio_led_mem_readw(uint32_t ret) "Read diagnostic LED %04x"
 
 # hw/slavio_timer.c
-disable slavio_timer_get_out(uint64_t limit, uint32_t counthigh, uint32_t count) "limit %"PRIx64" count %x%08x"
-disable slavio_timer_irq(uint32_t counthigh, uint32_t count) "callback: count %x%08x"
-disable slavio_timer_mem_readl_invalid(uint64_t addr) "invalid read address %"PRIx64""
-disable slavio_timer_mem_readl(uint64_t addr, uint32_t ret) "read %"PRIx64" = %08x"
-disable slavio_timer_mem_writel(uint64_t addr, uint32_t val) "write %"PRIx64" = %08x"
-disable slavio_timer_mem_writel_limit(unsigned int timer_index, uint64_t count) "processor %d user timer set to %016"PRIx64""
-disable slavio_timer_mem_writel_counter_invalid(void) "not user timer"
-disable slavio_timer_mem_writel_status_start(unsigned int timer_index) "processor %d user timer started"
-disable slavio_timer_mem_writel_status_stop(unsigned int timer_index) "processor %d user timer stopped"
-disable slavio_timer_mem_writel_mode_user(unsigned int timer_index) "processor %d changed from counter to user timer"
-disable slavio_timer_mem_writel_mode_counter(unsigned int timer_index) "processor %d changed from user timer to counter"
-disable slavio_timer_mem_writel_mode_invalid(void) "not system timer"
-disable slavio_timer_mem_writel_invalid(uint64_t addr) "invalid write address %"PRIx64""
+slavio_timer_get_out(uint64_t limit, uint32_t counthigh, uint32_t count) "limit %"PRIx64" count %x%08x"
+slavio_timer_irq(uint32_t counthigh, uint32_t count) "callback: count %x%08x"
+slavio_timer_mem_readl_invalid(uint64_t addr) "invalid read address %"PRIx64""
+slavio_timer_mem_readl(uint64_t addr, uint32_t ret) "read %"PRIx64" = %08x"
+slavio_timer_mem_writel(uint64_t addr, uint32_t val) "write %"PRIx64" = %08x"
+slavio_timer_mem_writel_limit(unsigned int timer_index, uint64_t count) "processor %d user timer set to %016"PRIx64""
+slavio_timer_mem_writel_counter_invalid(void) "not user timer"
+slavio_timer_mem_writel_status_start(unsigned int timer_index) "processor %d user timer started"
+slavio_timer_mem_writel_status_stop(unsigned int timer_index) "processor %d user timer stopped"
+slavio_timer_mem_writel_mode_user(unsigned int timer_index) "processor %d changed from counter to user timer"
+slavio_timer_mem_writel_mode_counter(unsigned int timer_index) "processor %d changed from user timer to counter"
+slavio_timer_mem_writel_mode_invalid(void) "not system timer"
+slavio_timer_mem_writel_invalid(uint64_t addr) "invalid write address %"PRIx64""
 
 # hw/sparc32_dma.c
-disable ledma_memory_read(uint64_t addr) "DMA read addr 0x%"PRIx64""
-disable ledma_memory_write(uint64_t addr) "DMA write addr 0x%"PRIx64""
-disable sparc32_dma_set_irq_raise(void) "Raise IRQ"
-disable sparc32_dma_set_irq_lower(void) "Lower IRQ"
-disable espdma_memory_read(uint32_t addr) "DMA read addr 0x%08x"
-disable espdma_memory_write(uint32_t addr) "DMA write addr 0x%08x"
-disable sparc32_dma_mem_readl(uint64_t addr, uint32_t ret) "read dmareg %"PRIx64": 0x%08x"
-disable sparc32_dma_mem_writel(uint64_t addr, uint32_t old, uint32_t val) "write dmareg %"PRIx64": 0x%08x -> 0x%08x"
-disable sparc32_dma_enable_raise(void) "Raise DMA enable"
-disable sparc32_dma_enable_lower(void) "Lower DMA enable"
+ledma_memory_read(uint64_t addr) "DMA read addr 0x%"PRIx64""
+ledma_memory_write(uint64_t addr) "DMA write addr 0x%"PRIx64""
+sparc32_dma_set_irq_raise(void) "Raise IRQ"
+sparc32_dma_set_irq_lower(void) "Lower IRQ"
+espdma_memory_read(uint32_t addr) "DMA read addr 0x%08x"
+espdma_memory_write(uint32_t addr) "DMA write addr 0x%08x"
+sparc32_dma_mem_readl(uint64_t addr, uint32_t ret) "read dmareg %"PRIx64": 0x%08x"
+sparc32_dma_mem_writel(uint64_t addr, uint32_t old, uint32_t val) "write dmareg %"PRIx64": 0x%08x -> 0x%08x"
+sparc32_dma_enable_raise(void) "Raise DMA enable"
+sparc32_dma_enable_lower(void) "Lower DMA enable"
 
 # hw/sun4m.c
-disable sun4m_cpu_interrupt(unsigned int level) "Set CPU IRQ %d"
-disable sun4m_cpu_reset_interrupt(unsigned int level) "Reset CPU IRQ %d"
-disable sun4m_cpu_set_irq_raise(int level) "Raise CPU IRQ %d"
-disable sun4m_cpu_set_irq_lower(int level) "Lower CPU IRQ %d"
+sun4m_cpu_interrupt(unsigned int level) "Set CPU IRQ %d"
+sun4m_cpu_reset_interrupt(unsigned int level) "Reset CPU IRQ %d"
+sun4m_cpu_set_irq_raise(int level) "Raise CPU IRQ %d"
+sun4m_cpu_set_irq_lower(int level) "Lower CPU IRQ %d"
 
 # hw/sun4m_iommu.c
-disable sun4m_iommu_mem_readl(uint64_t addr, uint32_t ret) "read reg[%"PRIx64"] = %x"
-disable sun4m_iommu_mem_writel(uint64_t addr, uint32_t val) "write reg[%"PRIx64"] = %x"
-disable sun4m_iommu_mem_writel_ctrl(uint64_t iostart) "iostart = %"PRIx64""
-disable sun4m_iommu_mem_writel_tlbflush(uint32_t val) "tlb flush %x"
-disable sun4m_iommu_mem_writel_pgflush(uint32_t val) "page flush %x"
-disable sun4m_iommu_page_get_flags(uint64_t pa, uint64_t iopte, uint32_t ret) "get flags addr %"PRIx64" => pte %"PRIx64", *pte = %x"
-disable sun4m_iommu_translate_pa(uint64_t addr, uint64_t pa, uint32_t iopte) "xlate dva %"PRIx64" => pa %"PRIx64" iopte = %x"
-disable sun4m_iommu_bad_addr(uint64_t addr) "bad addr %"PRIx64""
+sun4m_iommu_mem_readl(uint64_t addr, uint32_t ret) "read reg[%"PRIx64"] = %x"
+sun4m_iommu_mem_writel(uint64_t addr, uint32_t val) "write reg[%"PRIx64"] = %x"
+sun4m_iommu_mem_writel_ctrl(uint64_t iostart) "iostart = %"PRIx64""
+sun4m_iommu_mem_writel_tlbflush(uint32_t val) "tlb flush %x"
+sun4m_iommu_mem_writel_pgflush(uint32_t val) "page flush %x"
+sun4m_iommu_page_get_flags(uint64_t pa, uint64_t iopte, uint32_t ret) "get flags addr %"PRIx64" => pte %"PRIx64", *pte = %x"
+sun4m_iommu_translate_pa(uint64_t addr, uint64_t pa, uint32_t iopte) "xlate dva %"PRIx64" => pa %"PRIx64" iopte = %x"
+sun4m_iommu_bad_addr(uint64_t addr) "bad addr %"PRIx64""
 
 # hw/usb-ehci.c
-disable usb_ehci_reset(void) "=== RESET ==="
-disable usb_ehci_mmio_readl(uint32_t addr, const char *str, uint32_t val) "rd mmio %04x [%s] = %x"
-disable usb_ehci_mmio_writel(uint32_t addr, const char *str, uint32_t val) "wr mmio %04x [%s] = %x"
-disable usb_ehci_mmio_change(uint32_t addr, const char *str, uint32_t new, uint32_t old) "ch mmio %04x [%s] = %x (old: %x)"
-disable usb_ehci_usbsts(const char *sts, int state) "usbsts %s %d"
-disable usb_ehci_state(const char *schedule, const char *state) "%s schedule %s"
-disable usb_ehci_qh_ptrs(void *q, uint32_t addr, uint32_t nxt, uint32_t c_qtd, uint32_t n_qtd, uint32_t a_qtd) "q %p - QH @ %08x: next %08x qtds %08x,%08x,%08x"
-disable usb_ehci_qh_fields(uint32_t addr, int rl, int mplen, int eps, int ep, int devaddr) "QH @ %08x - rl %d, mplen %d, eps %d, ep %d, dev %d"
-disable usb_ehci_qh_bits(uint32_t addr, int c, int h, int dtc, int i) "QH @ %08x - c %d, h %d, dtc %d, i %d"
-disable usb_ehci_qtd_ptrs(void *q, uint32_t addr, uint32_t nxt, uint32_t altnext) "q %p - QTD @ %08x: next %08x altnext %08x"
-disable usb_ehci_qtd_fields(uint32_t addr, int tbytes, int cpage, int cerr, int pid) "QTD @ %08x - tbytes %d, cpage %d, cerr %d, pid %d"
-disable usb_ehci_qtd_bits(uint32_t addr, int ioc, int active, int halt, int babble, int xacterr) "QTD @ %08x - ioc %d, active %d, halt %d, babble %d, xacterr %d"
-disable usb_ehci_itd(uint32_t addr, uint32_t nxt, uint32_t mplen, uint32_t mult, uint32_t ep, uint32_t devaddr) "ITD @ %08x: next %08x - mplen %d, mult %d, ep %d, dev %d"
-disable usb_ehci_port_attach(uint32_t port, const char *device) "attach port #%d - %s"
-disable usb_ehci_port_detach(uint32_t port) "detach port #%d"
-disable usb_ehci_port_reset(uint32_t port, int enable) "reset port #%d - %d"
-disable usb_ehci_data(int rw, uint32_t cpage, uint32_t offset, uint32_t addr, uint32_t len, uint32_t bufpos) "write %d, cpage %d, offset 0x%03x, addr 0x%08x, len %d, bufpos %d"
-disable usb_ehci_queue_action(void *q, const char *action) "q %p: %s"
+usb_ehci_reset(void) "=== RESET ==="
+usb_ehci_mmio_readl(uint32_t addr, const char *str, uint32_t val) "rd mmio %04x [%s] = %x"
+usb_ehci_mmio_writel(uint32_t addr, const char *str, uint32_t val) "wr mmio %04x [%s] = %x"
+usb_ehci_mmio_change(uint32_t addr, const char *str, uint32_t new, uint32_t old) "ch mmio %04x [%s] = %x (old: %x)"
+usb_ehci_usbsts(const char *sts, int state) "usbsts %s %d"
+usb_ehci_state(const char *schedule, const char *state) "%s schedule %s"
+usb_ehci_qh_ptrs(void *q, uint32_t addr, uint32_t nxt, uint32_t c_qtd, uint32_t n_qtd, uint32_t a_qtd) "q %p - QH @ %08x: next %08x qtds %08x,%08x,%08x"
+usb_ehci_qh_fields(uint32_t addr, int rl, int mplen, int eps, int ep, int devaddr) "QH @ %08x - rl %d, mplen %d, eps %d, ep %d, dev %d"
+usb_ehci_qh_bits(uint32_t addr, int c, int h, int dtc, int i) "QH @ %08x - c %d, h %d, dtc %d, i %d"
+usb_ehci_qtd_ptrs(void *q, uint32_t addr, uint32_t nxt, uint32_t altnext) "q %p - QTD @ %08x: next %08x altnext %08x"
+usb_ehci_qtd_fields(uint32_t addr, int tbytes, int cpage, int cerr, int pid) "QTD @ %08x - tbytes %d, cpage %d, cerr %d, pid %d"
+usb_ehci_qtd_bits(uint32_t addr, int ioc, int active, int halt, int babble, int xacterr) "QTD @ %08x - ioc %d, active %d, halt %d, babble %d, xacterr %d"
+usb_ehci_itd(uint32_t addr, uint32_t nxt, uint32_t mplen, uint32_t mult, uint32_t ep, uint32_t devaddr) "ITD @ %08x: next %08x - mplen %d, mult %d, ep %d, dev %d"
+usb_ehci_port_attach(uint32_t port, const char *device) "attach port #%d - %s"
+usb_ehci_port_detach(uint32_t port) "detach port #%d"
+usb_ehci_port_reset(uint32_t port, int enable) "reset port #%d - %d"
+usb_ehci_data(int rw, uint32_t cpage, uint32_t offset, uint32_t addr, uint32_t len, uint32_t bufpos) "write %d, cpage %d, offset 0x%03x, addr 0x%08x, len %d, bufpos %d"
+usb_ehci_queue_action(void *q, const char *action) "q %p: %s"
 
 # hw/usb-desc.c
-disable usb_desc_device(int addr, int len, int ret) "dev %d query device, len %d, ret %d"
-disable usb_desc_device_qualifier(int addr, int len, int ret) "dev %d query device qualifier, len %d, ret %d"
-disable usb_desc_config(int addr, int index, int len, int ret) "dev %d query config %d, len %d, ret %d"
-disable usb_desc_other_speed_config(int addr, int index, int len, int ret) "dev %d query config %d, len %d, ret %d"
-disable usb_desc_string(int addr, int index, int len, int ret) "dev %d query string %d, len %d, ret %d"
-disable usb_set_addr(int addr) "dev %d"
-disable usb_set_config(int addr, int config, int ret) "dev %d, config %d, ret %d"
-disable usb_clear_device_feature(int addr, int feature, int ret) "dev %d, feature %d, ret %d"
-disable usb_set_device_feature(int addr, int feature, int ret) "dev %d, feature %d, ret %d"
+usb_desc_device(int addr, int len, int ret) "dev %d query device, len %d, ret %d"
+usb_desc_device_qualifier(int addr, int len, int ret) "dev %d query device qualifier, len %d, ret %d"
+usb_desc_config(int addr, int index, int len, int ret) "dev %d query config %d, len %d, ret %d"
+usb_desc_other_speed_config(int addr, int index, int len, int ret) "dev %d query config %d, len %d, ret %d"
+usb_desc_string(int addr, int index, int len, int ret) "dev %d query string %d, len %d, ret %d"
+usb_set_addr(int addr) "dev %d"
+usb_set_config(int addr, int config, int ret) "dev %d, config %d, ret %d"
+usb_clear_device_feature(int addr, int feature, int ret) "dev %d, feature %d, ret %d"
+usb_set_device_feature(int addr, int feature, int ret) "dev %d, feature %d, ret %d"
 
 # hw/scsi-bus.c
-disable scsi_req_alloc(int target, int lun, int tag) "target %d lun %d tag %d"
-disable scsi_req_data(int target, int lun, int tag, int len) "target %d lun %d tag %d len %d"
-disable scsi_req_dequeue(int target, int lun, int tag) "target %d lun %d tag %d"
-disable scsi_req_continue(int target, int lun, int tag) "target %d lun %d tag %d"
-disable scsi_req_parsed(int target, int lun, int tag, int cmd, int mode, int xfer) "target %d lun %d tag %d command %d dir %d length %d"
-disable scsi_req_parsed_lba(int target, int lun, int tag, int cmd, uint64_t lba) "target %d lun %d tag %d command %d lba %"PRIu64""
-disable scsi_req_parse_bad(int target, int lun, int tag, int cmd) "target %d lun %d tag %d command %d"
-disable scsi_req_build_sense(int target, int lun, int tag, int key, int asc, int ascq) "target %d lun %d tag %d key %#02x asc %#02x ascq %#02x"
-disable scsi_report_luns(int target, int lun, int tag) "target %d lun %d tag %d"
-disable scsi_inquiry(int target, int lun, int tag, int cdb1, int cdb2) "target %d lun %d tag %d page %#02x/%#02x"
-disable scsi_test_unit_ready(int target, int lun, int tag) "target %d lun %d tag %d"
-disable scsi_request_sense(int target, int lun, int tag) "target %d lun %d tag %d"
+scsi_req_alloc(int target, int lun, int tag) "target %d lun %d tag %d"
+scsi_req_data(int target, int lun, int tag, int len) "target %d lun %d tag %d len %d"
+scsi_req_dequeue(int target, int lun, int tag) "target %d lun %d tag %d"
+scsi_req_continue(int target, int lun, int tag) "target %d lun %d tag %d"
+scsi_req_parsed(int target, int lun, int tag, int cmd, int mode, int xfer) "target %d lun %d tag %d command %d dir %d length %d"
+scsi_req_parsed_lba(int target, int lun, int tag, int cmd, uint64_t lba) "target %d lun %d tag %d command %d lba %"PRIu64""
+scsi_req_parse_bad(int target, int lun, int tag, int cmd) "target %d lun %d tag %d command %d"
+scsi_req_build_sense(int target, int lun, int tag, int key, int asc, int ascq) "target %d lun %d tag %d key %#02x asc %#02x ascq %#02x"
+scsi_report_luns(int target, int lun, int tag) "target %d lun %d tag %d"
+scsi_inquiry(int target, int lun, int tag, int cdb1, int cdb2) "target %d lun %d tag %d page %#02x/%#02x"
+scsi_test_unit_ready(int target, int lun, int tag) "target %d lun %d tag %d"
+scsi_request_sense(int target, int lun, int tag) "target %d lun %d tag %d"
 
 # vl.c
-disable vm_state_notify(int running, int reason) "running %d reason %d"
+vm_state_notify(int running, int reason) "running %d reason %d"
 
 # block/qed-l2-cache.c
-disable qed_alloc_l2_cache_entry(void *l2_cache, void *entry) "l2_cache %p entry %p"
-disable qed_unref_l2_cache_entry(void *entry, int ref) "entry %p ref %d"
-disable qed_find_l2_cache_entry(void *l2_cache, void *entry, uint64_t offset, int ref) "l2_cache %p entry %p offset %"PRIu64" ref %d"
+qed_alloc_l2_cache_entry(void *l2_cache, void *entry) "l2_cache %p entry %p"
+qed_unref_l2_cache_entry(void *entry, int ref) "entry %p ref %d"
+qed_find_l2_cache_entry(void *l2_cache, void *entry, uint64_t offset, int ref) "l2_cache %p entry %p offset %"PRIu64" ref %d"
 
 # block/qed-table.c
-disable qed_read_table(void *s, uint64_t offset, void *table) "s %p offset %"PRIu64" table %p"
-disable qed_read_table_cb(void *s, void *table, int ret) "s %p table %p ret %d"
-disable qed_write_table(void *s, uint64_t offset, void *table, unsigned int index, unsigned int n) "s %p offset %"PRIu64" table %p index %u n %u"
-disable qed_write_table_cb(void *s, void *table, int flush, int ret) "s %p table %p flush %d ret %d"
+qed_read_table(void *s, uint64_t offset, void *table) "s %p offset %"PRIu64" table %p"
+qed_read_table_cb(void *s, void *table, int ret) "s %p table %p ret %d"
+qed_write_table(void *s, uint64_t offset, void *table, unsigned int index, unsigned int n) "s %p offset %"PRIu64" table %p index %u n %u"
+qed_write_table_cb(void *s, void *table, int flush, int ret) "s %p table %p flush %d ret %d"
 
 # block/qed.c
-disable qed_need_check_timer_cb(void *s) "s %p"
-disable qed_start_need_check_timer(void *s) "s %p"
-disable qed_cancel_need_check_timer(void *s) "s %p"
-disable qed_aio_complete(void *s, void *acb, int ret) "s %p acb %p ret %d"
-disable qed_aio_setup(void *s, void *acb, int64_t sector_num, int nb_sectors, void *opaque, int is_write) "s %p acb %p sector_num %"PRId64" nb_sectors %d opaque %p is_write %d"
-disable qed_aio_next_io(void *s, void *acb, int ret, uint64_t cur_pos) "s %p acb %p ret %d cur_pos %"PRIu64""
-disable qed_aio_read_data(void *s, void *acb, int ret, uint64_t offset, size_t len) "s %p acb %p ret %d offset %"PRIu64" len %zu"
-disable qed_aio_write_data(void *s, void *acb, int ret, uint64_t offset, size_t len) "s %p acb %p ret %d offset %"PRIu64" len %zu"
-disable qed_aio_write_prefill(void *s, void *acb, uint64_t start, size_t len, uint64_t offset) "s %p acb %p start %"PRIu64" len %zu offset %"PRIu64""
-disable qed_aio_write_postfill(void *s, void *acb, uint64_t start, size_t len, uint64_t offset) "s %p acb %p start %"PRIu64" len %zu offset %"PRIu64""
-disable qed_aio_write_main(void *s, void *acb, int ret, uint64_t offset, size_t len) "s %p acb %p ret %d offset %"PRIu64" len %zu"
+qed_need_check_timer_cb(void *s) "s %p"
+qed_start_need_check_timer(void *s) "s %p"
+qed_cancel_need_check_timer(void *s) "s %p"
+qed_aio_complete(void *s, void *acb, int ret) "s %p acb %p ret %d"
+qed_aio_setup(void *s, void *acb, int64_t sector_num, int nb_sectors, void *opaque, int is_write) "s %p acb %p sector_num %"PRId64" nb_sectors %d opaque %p is_write %d"
+qed_aio_next_io(void *s, void *acb, int ret, uint64_t cur_pos) "s %p acb %p ret %d cur_pos %"PRIu64""
+qed_aio_read_data(void *s, void *acb, int ret, uint64_t offset, size_t len) "s %p acb %p ret %d offset %"PRIu64" len %zu"
+qed_aio_write_data(void *s, void *acb, int ret, uint64_t offset, size_t len) "s %p acb %p ret %d offset %"PRIu64" len %zu"
+qed_aio_write_prefill(void *s, void *acb, uint64_t start, size_t len, uint64_t offset) "s %p acb %p start %"PRIu64" len %zu offset %"PRIu64""
+qed_aio_write_postfill(void *s, void *acb, uint64_t start, size_t len, uint64_t offset) "s %p acb %p start %"PRIu64" len %zu offset %"PRIu64""
+qed_aio_write_main(void *s, void *acb, int ret, uint64_t offset, size_t len) "s %p acb %p ret %d offset %"PRIu64" len %zu"
 
 # hw/g364fb.c
-disable g364fb_read(uint64_t addr, uint32_t val) "read addr=0x%"PRIx64": 0x%x"
-disable g364fb_write(uint64_t addr, uint32_t new) "write addr=0x%"PRIx64": 0x%x"
+g364fb_read(uint64_t addr, uint32_t val) "read addr=0x%"PRIx64": 0x%x"
+g364fb_write(uint64_t addr, uint32_t new) "write addr=0x%"PRIx64": 0x%x"
 
 # hw/grlib_gptimer.c
-disable grlib_gptimer_enable(int id, uint32_t count) "timer:%d set count 0x%x and run"
-disable grlib_gptimer_disabled(int id, uint32_t config) "timer:%d Timer disable config 0x%x"
-disable grlib_gptimer_restart(int id, uint32_t reload) "timer:%d reload val: 0x%x"
-disable grlib_gptimer_set_scaler(uint32_t scaler, uint32_t freq) "scaler:0x%x freq: 0x%x"
-disable grlib_gptimer_hit(int id) "timer:%d HIT"
-disable grlib_gptimer_readl(int id, uint64_t addr, uint32_t val) "timer:%d addr 0x%"PRIx64" 0x%x"
-disable grlib_gptimer_writel(int id, uint64_t addr, uint32_t val) "timer:%d addr 0x%"PRIx64" 0x%x"
+grlib_gptimer_enable(int id, uint32_t count) "timer:%d set count 0x%x and run"
+grlib_gptimer_disabled(int id, uint32_t config) "timer:%d Timer disable config 0x%x"
+grlib_gptimer_restart(int id, uint32_t reload) "timer:%d reload val: 0x%x"
+grlib_gptimer_set_scaler(uint32_t scaler, uint32_t freq) "scaler:0x%x freq: 0x%x"
+grlib_gptimer_hit(int id) "timer:%d HIT"
+grlib_gptimer_readl(int id, uint64_t addr, uint32_t val) "timer:%d addr 0x%"PRIx64" 0x%x"
+grlib_gptimer_writel(int id, uint64_t addr, uint32_t val) "timer:%d addr 0x%"PRIx64" 0x%x"
 
 # hw/grlib_irqmp.c
-disable grlib_irqmp_check_irqs(uint32_t pend, uint32_t force, uint32_t mask, uint32_t lvl1, uint32_t lvl2) "pend:0x%04x force:0x%04x mask:0x%04x lvl1:0x%04x lvl0:0x%04x\n"
-disable grlib_irqmp_ack(int intno) "interrupt:%d"
-disable grlib_irqmp_set_irq(int irq) "Raise CPU IRQ %d"
-disable grlib_irqmp_readl_unknown(uint64_t addr) "addr 0x%"PRIx64""
-disable grlib_irqmp_writel_unknown(uint64_t addr, uint32_t value) "addr 0x%"PRIx64" value 0x%x"
+grlib_irqmp_check_irqs(uint32_t pend, uint32_t force, uint32_t mask, uint32_t lvl1, uint32_t lvl2) "pend:0x%04x force:0x%04x mask:0x%04x lvl1:0x%04x lvl0:0x%04x\n"
+grlib_irqmp_ack(int intno) "interrupt:%d"
+grlib_irqmp_set_irq(int irq) "Raise CPU IRQ %d"
+grlib_irqmp_readl_unknown(uint64_t addr) "addr 0x%"PRIx64""
+grlib_irqmp_writel_unknown(uint64_t addr, uint32_t value) "addr 0x%"PRIx64" value 0x%x"
 
 # hw/grlib_apbuart.c
-disable grlib_apbuart_event(int event) "event:%d"
-disable grlib_apbuart_writel_unknown(uint64_t addr, uint32_t value) "addr 0x%"PRIx64" value 0x%x"
+grlib_apbuart_event(int event) "event:%d"
+grlib_apbuart_writel_unknown(uint64_t addr, uint32_t value) "addr 0x%"PRIx64" value 0x%x"
 
 # hw/leon3.c
-disable leon3_set_irq(int intno) "Set CPU IRQ %d"
-disable leon3_reset_irq(int intno) "Reset CPU IRQ %d"
+leon3_set_irq(int intno) "Set CPU IRQ %d"
+leon3_reset_irq(int intno) "Reset CPU IRQ %d"
 
 # spice-qemu-char.c
-disable spice_vmc_write(ssize_t out, int len) "spice wrottn %zd of requested %d"
-disable spice_vmc_read(int bytes, int len) "spice read %d of requested %d"
-disable spice_vmc_register_interface(void *scd) "spice vmc registered interface %p"
-disable spice_vmc_unregister_interface(void *scd) "spice vmc unregistered interface %p"
+spice_vmc_write(ssize_t out, int len) "spice wrottn %zd of requested %d"
+spice_vmc_read(int bytes, int len) "spice read %d of requested %d"
+spice_vmc_register_interface(void *scd) "spice vmc registered interface %p"
+spice_vmc_unregister_interface(void *scd) "spice vmc unregistered interface %p"
 
 # hw/lm32_pic.c
-disable lm32_pic_raise_irq(void) "Raise CPU interrupt"
-disable lm32_pic_lower_irq(void) "Lower CPU interrupt"
-disable lm32_pic_interrupt(int irq, int level) "Set IRQ%d %d"
-disable lm32_pic_set_im(uint32_t im) "im 0x%08x"
-disable lm32_pic_set_ip(uint32_t ip) "ip 0x%08x"
-disable lm32_pic_get_im(uint32_t im) "im 0x%08x"
-disable lm32_pic_get_ip(uint32_t ip) "ip 0x%08x"
+lm32_pic_raise_irq(void) "Raise CPU interrupt"
+lm32_pic_lower_irq(void) "Lower CPU interrupt"
+lm32_pic_interrupt(int irq, int level) "Set IRQ%d %d"
+lm32_pic_set_im(uint32_t im) "im 0x%08x"
+lm32_pic_set_ip(uint32_t ip) "ip 0x%08x"
+lm32_pic_get_im(uint32_t im) "im 0x%08x"
+lm32_pic_get_ip(uint32_t ip) "ip 0x%08x"
 
 # hw/lm32_juart.c
-disable lm32_juart_get_jtx(uint32_t value) "jtx 0x%08x"
-disable lm32_juart_set_jtx(uint32_t value) "jtx 0x%08x"
-disable lm32_juart_get_jrx(uint32_t value) "jrx 0x%08x"
-disable lm32_juart_set_jrx(uint32_t value) "jrx 0x%08x"
+lm32_juart_get_jtx(uint32_t value) "jtx 0x%08x"
+lm32_juart_set_jtx(uint32_t value) "jtx 0x%08x"
+lm32_juart_get_jrx(uint32_t value) "jrx 0x%08x"
+lm32_juart_set_jrx(uint32_t value) "jrx 0x%08x"
 
 # hw/lm32_timer.c
-disable lm32_timer_memory_write(uint32_t addr, uint32_t value) "addr 0x%08x value 0x%08x"
-disable lm32_timer_memory_read(uint32_t addr, uint32_t value) "addr 0x%08x value 0x%08x"
-disable lm32_timer_hit(void) "timer hit"
-disable lm32_timer_irq_state(int level) "irq state %d"
+lm32_timer_memory_write(uint32_t addr, uint32_t value) "addr 0x%08x value 0x%08x"
+lm32_timer_memory_read(uint32_t addr, uint32_t value) "addr 0x%08x value 0x%08x"
+lm32_timer_hit(void) "timer hit"
+lm32_timer_irq_state(int level) "irq state %d"
 
 # hw/lm32_uart.c
-disable lm32_uart_memory_write(uint32_t addr, uint32_t value) "addr 0x%08x value 0x%08x"
-disable lm32_uart_memory_read(uint32_t addr, uint32_t value) "addr 0x%08x value 0x%08x"
-disable lm32_uart_irq_state(int level) "irq state %d"
+lm32_uart_memory_write(uint32_t addr, uint32_t value) "addr 0x%08x value 0x%08x"
+lm32_uart_memory_read(uint32_t addr, uint32_t value) "addr 0x%08x value 0x%08x"
+lm32_uart_irq_state(int level) "irq state %d"
 
 # hw/lm32_sys.c
-disable lm32_sys_memory_write(uint32_t addr, uint32_t value) "addr 0x%08x value 0x%08x"
+lm32_sys_memory_write(uint32_t addr, uint32_t value) "addr 0x%08x value 0x%08x"
 
 # hw/milkymist-ac97.c
-disable milkymist_ac97_memory_read(uint32_t addr, uint32_t value) "addr %08x value %08x"
-disable milkymist_ac97_memory_write(uint32_t addr, uint32_t value) "addr %08x value %08x"
-disable milkymist_ac97_pulse_irq_crrequest(void) "Pulse IRQ CR request"
-disable milkymist_ac97_pulse_irq_crreply(void) "Pulse IRQ CR reply"
-disable milkymist_ac97_pulse_irq_dmaw(void) "Pulse IRQ DMA write"
-disable milkymist_ac97_pulse_irq_dmar(void) "Pulse IRQ DMA read"
-disable milkymist_ac97_in_cb(int avail, uint32_t remaining) "avail %d remaining %u"
-disable milkymist_ac97_in_cb_transferred(int transferred) "transferred %d"
-disable milkymist_ac97_out_cb(int free, uint32_t remaining) "free %d remaining %u"
-disable milkymist_ac97_out_cb_transferred(int transferred) "transferred %d"
+milkymist_ac97_memory_read(uint32_t addr, uint32_t value) "addr %08x value %08x"
+milkymist_ac97_memory_write(uint32_t addr, uint32_t value) "addr %08x value %08x"
+milkymist_ac97_pulse_irq_crrequest(void) "Pulse IRQ CR request"
+milkymist_ac97_pulse_irq_crreply(void) "Pulse IRQ CR reply"
+milkymist_ac97_pulse_irq_dmaw(void) "Pulse IRQ DMA write"
+milkymist_ac97_pulse_irq_dmar(void) "Pulse IRQ DMA read"
+milkymist_ac97_in_cb(int avail, uint32_t remaining) "avail %d remaining %u"
+milkymist_ac97_in_cb_transferred(int transferred) "transferred %d"
+milkymist_ac97_out_cb(int free, uint32_t remaining) "free %d remaining %u"
+milkymist_ac97_out_cb_transferred(int transferred) "transferred %d"
 
 # hw/milkymist-hpdmc.c
-disable milkymist_hpdmc_memory_read(uint32_t addr, uint32_t value) "addr=%08x value=%08x"
-disable milkymist_hpdmc_memory_write(uint32_t addr, uint32_t value) "addr=%08x value=%08x"
+milkymist_hpdmc_memory_read(uint32_t addr, uint32_t value) "addr=%08x value=%08x"
+milkymist_hpdmc_memory_write(uint32_t addr, uint32_t value) "addr=%08x value=%08x"
 
 # hw/milkymist-memcard.c
-disable milkymist_memcard_memory_read(uint32_t addr, uint32_t value) "addr %08x value %08x"
-disable milkymist_memcard_memory_write(uint32_t addr, uint32_t value) "addr %08x value %08x"
+milkymist_memcard_memory_read(uint32_t addr, uint32_t value) "addr %08x value %08x"
+milkymist_memcard_memory_write(uint32_t addr, uint32_t value) "addr %08x value %08x"
 
 # hw/milkymist-minimac2.c
-disable milkymist_minimac2_memory_read(uint32_t addr, uint32_t value) "addr %08x value %08x"
-disable milkymist_minimac2_memory_write(uint32_t addr, uint32_t value) "addr %08x value %08x"
-disable milkymist_minimac2_mdio_write(uint8_t phy_addr, uint8_t addr, uint16_t value) "phy_addr %02x addr %02x value %04x"
-disable milkymist_minimac2_mdio_read(uint8_t phy_addr, uint8_t addr, uint16_t value) "phy_addr %02x addr %02x value %04x"
-disable milkymist_minimac2_tx_frame(uint32_t length) "length %u"
-disable milkymist_minimac2_rx_frame(const void *buf, uint32_t length) "buf %p length %u"
-disable milkymist_minimac2_drop_rx_frame(const void *buf) "buf %p"
-disable milkymist_minimac2_rx_transfer(const void *buf, uint32_t length) "buf %p length %d"
-disable milkymist_minimac2_raise_irq_rx(void) "Raise IRQ RX"
-disable milkymist_minimac2_lower_irq_rx(void) "Lower IRQ RX"
-disable milkymist_minimac2_pulse_irq_tx(void) "Pulse IRQ TX"
+milkymist_minimac2_memory_read(uint32_t addr, uint32_t value) "addr %08x value %08x"
+milkymist_minimac2_memory_write(uint32_t addr, uint32_t value) "addr %08x value %08x"
+milkymist_minimac2_mdio_write(uint8_t phy_addr, uint8_t addr, uint16_t value) "phy_addr %02x addr %02x value %04x"
+milkymist_minimac2_mdio_read(uint8_t phy_addr, uint8_t addr, uint16_t value) "phy_addr %02x addr %02x value %04x"
+milkymist_minimac2_tx_frame(uint32_t length) "length %u"
+milkymist_minimac2_rx_frame(const void *buf, uint32_t length) "buf %p length %u"
+milkymist_minimac2_drop_rx_frame(const void *buf) "buf %p"
+milkymist_minimac2_rx_transfer(const void *buf, uint32_t length) "buf %p length %d"
+milkymist_minimac2_raise_irq_rx(void) "Raise IRQ RX"
+milkymist_minimac2_lower_irq_rx(void) "Lower IRQ RX"
+milkymist_minimac2_pulse_irq_tx(void) "Pulse IRQ TX"
 
 # hw/milkymist-pfpu.c
-disable milkymist_pfpu_memory_read(uint32_t addr, uint32_t value) "addr %08x value %08x"
-disable milkymist_pfpu_memory_write(uint32_t addr, uint32_t value) "addr %08x value %08x"
-disable milkymist_pfpu_vectout(uint32_t a, uint32_t b, uint32_t dma_ptr) "a %08x b %08x dma_ptr %08x"
-disable milkymist_pfpu_pulse_irq(void) "Pulse IRQ"
+milkymist_pfpu_memory_read(uint32_t addr, uint32_t value) "addr %08x value %08x"
+milkymist_pfpu_memory_write(uint32_t addr, uint32_t value) "addr %08x value %08x"
+milkymist_pfpu_vectout(uint32_t a, uint32_t b, uint32_t dma_ptr) "a %08x b %08x dma_ptr %08x"
+milkymist_pfpu_pulse_irq(void) "Pulse IRQ"
 
 # hw/milkymist-softusb.c
-disable milkymist_softusb_memory_read(uint32_t addr, uint32_t value) "addr %08x value %08x"
-disable milkymist_softusb_memory_write(uint32_t addr, uint32_t value) "addr %08x value %08x"
-disable milkymist_softusb_mevt(uint8_t m) "m %d"
-disable milkymist_softusb_kevt(uint8_t m) "m %d"
-disable milkymist_softusb_mouse_event(int dx, int dy, int dz, int bs) "dx %d dy %d dz %d bs %02x"
-disable milkymist_softusb_pulse_irq(void) "Pulse IRQ"
+milkymist_softusb_memory_read(uint32_t addr, uint32_t value) "addr %08x value %08x"
+milkymist_softusb_memory_write(uint32_t addr, uint32_t value) "addr %08x value %08x"
+milkymist_softusb_mevt(uint8_t m) "m %d"
+milkymist_softusb_kevt(uint8_t m) "m %d"
+milkymist_softusb_mouse_event(int dx, int dy, int dz, int bs) "dx %d dy %d dz %d bs %02x"
+milkymist_softusb_pulse_irq(void) "Pulse IRQ"
 
 # hw/milkymist-sysctl.c
-disable milkymist_sysctl_memory_read(uint32_t addr, uint32_t value) "addr %08x value %08x"
-disable milkymist_sysctl_memory_write(uint32_t addr, uint32_t value) "addr %08x value %08x"
-disable milkymist_sysctl_icap_write(uint32_t value) "value %08x"
-disable milkymist_sysctl_start_timer0(void) "Start timer0"
-disable milkymist_sysctl_stop_timer0(void) "Stop timer0"
-disable milkymist_sysctl_start_timer1(void) "Start timer1"
-disable milkymist_sysctl_stop_timer1(void) "Stop timer1"
-disable milkymist_sysctl_pulse_irq_timer0(void) "Pulse IRQ Timer0"
-disable milkymist_sysctl_pulse_irq_timer1(void) "Pulse IRQ Timer1"
+milkymist_sysctl_memory_read(uint32_t addr, uint32_t value) "addr %08x value %08x"
+milkymist_sysctl_memory_write(uint32_t addr, uint32_t value) "addr %08x value %08x"
+milkymist_sysctl_icap_write(uint32_t value) "value %08x"
+milkymist_sysctl_start_timer0(void) "Start timer0"
+milkymist_sysctl_stop_timer0(void) "Stop timer0"
+milkymist_sysctl_start_timer1(void) "Start timer1"
+milkymist_sysctl_stop_timer1(void) "Stop timer1"
+milkymist_sysctl_pulse_irq_timer0(void) "Pulse IRQ Timer0"
+milkymist_sysctl_pulse_irq_timer1(void) "Pulse IRQ Timer1"
 
 # hw/milkymist-tmu2.c
-disable milkymist_tmu2_memory_read(uint32_t addr, uint32_t value) "addr %08x value %08x"
-disable milkymist_tmu2_memory_write(uint32_t addr, uint32_t value) "addr %08x value %08x"
-disable milkymist_tmu2_start(void) "Start TMU"
-disable milkymist_tmu2_pulse_irq(void) "Pulse IRQ"
+milkymist_tmu2_memory_read(uint32_t addr, uint32_t value) "addr %08x value %08x"
+milkymist_tmu2_memory_write(uint32_t addr, uint32_t value) "addr %08x value %08x"
+milkymist_tmu2_start(void) "Start TMU"
+milkymist_tmu2_pulse_irq(void) "Pulse IRQ"
 
 # hw/milkymist-uart.c
-disable milkymist_uart_memory_read(uint32_t addr, uint32_t value) "addr %08x value %08x"
-disable milkymist_uart_memory_write(uint32_t addr, uint32_t value) "addr %08x value %08x"
-disable milkymist_uart_pulse_irq_rx(void) "Pulse IRQ RX"
-disable milkymist_uart_pulse_irq_tx(void) "Pulse IRQ TX"
+milkymist_uart_memory_read(uint32_t addr, uint32_t value) "addr %08x value %08x"
+milkymist_uart_memory_write(uint32_t addr, uint32_t value) "addr %08x value %08x"
+milkymist_uart_pulse_irq_rx(void) "Pulse IRQ RX"
+milkymist_uart_pulse_irq_tx(void) "Pulse IRQ TX"
 
 # hw/milkymist-vgafb.c
-disable milkymist_vgafb_memory_read(uint32_t addr, uint32_t value) "addr %08x value %08x"
-disable milkymist_vgafb_memory_write(uint32_t addr, uint32_t value) "addr %08x value %08x"
+milkymist_vgafb_memory_read(uint32_t addr, uint32_t value) "addr %08x value %08x"
+milkymist_vgafb_memory_write(uint32_t addr, uint32_t value) "addr %08x value %08x"
 
 # xen-all.c
-disable xen_ram_alloc(unsigned long ram_addr, unsigned long size) "requested: %#lx, size %#lx"
-disable xen_client_set_memory(uint64_t start_addr, unsigned long size, unsigned long phys_offset, bool log_dirty) "%#"PRIx64" size %#lx, offset %#lx, log_dirty %i"
+xen_ram_alloc(unsigned long ram_addr, unsigned long size) "requested: %#lx, size %#lx"
+xen_client_set_memory(uint64_t start_addr, unsigned long size, unsigned long phys_offset, bool log_dirty) "%#"PRIx64" size %#lx, offset %#lx, log_dirty %i"
 
 # xen-mapcache.c
-disable xen_map_cache(uint64_t phys_addr) "want %#"PRIx64""
-disable xen_remap_bucket(uint64_t index) "index %#"PRIx64""
-disable xen_map_cache_return(void* ptr) "%p"
-disable xen_map_block(uint64_t phys_addr, uint64_t size) "%#"PRIx64", size %#"PRIx64""
-disable xen_unmap_block(void* addr, unsigned long size) "%p, size %#lx"
+xen_map_cache(uint64_t phys_addr) "want %#"PRIx64""
+xen_remap_bucket(uint64_t index) "index %#"PRIx64""
+xen_map_cache_return(void* ptr) "%p"
+xen_map_block(uint64_t phys_addr, uint64_t size) "%#"PRIx64", size %#"PRIx64""
+xen_unmap_block(void* addr, unsigned long size) "%p, size %#lx"
 
 # exec.c
-disable qemu_put_ram_ptr(void* addr) "%p"
+qemu_put_ram_ptr(void* addr) "%p"
 
 # hw/xen_platform.c
-disable xen_platform_log(char *s) "xen platform: %s"
+xen_platform_log(char *s) "xen platform: %s"
 
 # qemu-coroutine.c
-disable qemu_coroutine_enter(void *from, void *to, void *opaque) "from %p to %p opaque %p"
-disable qemu_coroutine_yield(void *from, void *to) "from %p to %p"
-disable qemu_coroutine_terminate(void *co) "self %p"
+qemu_coroutine_enter(void *from, void *to, void *opaque) "from %p to %p opaque %p"
+qemu_coroutine_yield(void *from, void *to) "from %p to %p"
+qemu_coroutine_terminate(void *co) "self %p"
 
 # qemu-coroutine-lock.c
-disable qemu_co_queue_next_bh(void) ""
-disable qemu_co_queue_next(void *next) "next %p"
-disable qemu_co_mutex_lock_entry(void *mutex, void *self) "mutex %p self %p"
-disable qemu_co_mutex_lock_return(void *mutex, void *self) "mutex %p self %p"
-disable qemu_co_mutex_unlock_entry(void *mutex, void *self) "mutex %p self %p"
-disable qemu_co_mutex_unlock_return(void *mutex, void *self) "mutex %p self %p"
+qemu_co_queue_next_bh(void) ""
+qemu_co_queue_next(void *next) "next %p"
+qemu_co_mutex_lock_entry(void *mutex, void *self) "mutex %p self %p"
+qemu_co_mutex_lock_return(void *mutex, void *self) "mutex %p self %p"
+qemu_co_mutex_unlock_entry(void *mutex, void *self) "mutex %p self %p"
+qemu_co_mutex_unlock_return(void *mutex, void *self) "mutex %p self %p"
 
 # hw/escc.c
-disable escc_put_queue(char channel, int b) "channel %c put: 0x%02x"
-disable escc_get_queue(char channel, int val) "channel %c get 0x%02x"
-disable escc_update_irq(int irq) "IRQ = %d"
-disable escc_update_parameters(char channel, int speed, int parity, int data_bits, int stop_bits) "channel %c: speed=%d parity=%c data=%d stop=%d"
-disable escc_mem_writeb_ctrl(char channel, uint32_t reg, uint32_t val) "Write channel %c, reg[%d] = %2.2x"
-disable escc_mem_writeb_data(char channel, uint32_t val) "Write channel %c, ch %d"
-disable escc_mem_readb_ctrl(char channel, uint32_t reg, uint8_t val) "Read channel %c, reg[%d] = %2.2x"
-disable escc_mem_readb_data(char channel, uint32_t ret) "Read channel %c, ch %d"
-disable escc_serial_receive_byte(char channel, int ch) "channel %c put ch %d"
-disable escc_sunkbd_event_in(int ch) "Untranslated keycode %2.2x"
-disable escc_sunkbd_event_out(int ch) "Translated keycode %2.2x"
-disable escc_kbd_command(int val) "Command %d"
-disable escc_sunmouse_event(int dx, int dy, int buttons_state) "dx=%d dy=%d buttons=%01x"
+escc_put_queue(char channel, int b) "channel %c put: 0x%02x"
+escc_get_queue(char channel, int val) "channel %c get 0x%02x"
+escc_update_irq(int irq) "IRQ = %d"
+escc_update_parameters(char channel, int speed, int parity, int data_bits, int stop_bits) "channel %c: speed=%d parity=%c data=%d stop=%d"
+escc_mem_writeb_ctrl(char channel, uint32_t reg, uint32_t val) "Write channel %c, reg[%d] = %2.2x"
+escc_mem_writeb_data(char channel, uint32_t val) "Write channel %c, ch %d"
+escc_mem_readb_ctrl(char channel, uint32_t reg, uint8_t val) "Read channel %c, reg[%d] = %2.2x"
+escc_mem_readb_data(char channel, uint32_t ret) "Read channel %c, ch %d"
+escc_serial_receive_byte(char channel, int ch) "channel %c put ch %d"
+escc_sunkbd_event_in(int ch) "Untranslated keycode %2.2x"
+escc_sunkbd_event_out(int ch) "Translated keycode %2.2x"
+escc_kbd_command(int val) "Command %d"
+escc_sunmouse_event(int dx, int dy, int buttons_state) "dx=%d dy=%d buttons=%01x"
commit 9a82b6a590bd7c845ab9754b34b33ffee982ccb2
Author: Lluís <xscript at gmx.net>
Date:   Wed Aug 31 20:31:51 2011 +0200

    trace: [stderr] add support for dynamically enabling/disabling events
    
    Uses the generic interface provided in "trace/control.h" in order to provide
    a programmatic interface as well as command line and monitor controls.
    
    Signed-off-by: Fabien Chouteau <chouteau at adacore.com>
    Signed-off-by: Lluís Vilanova <vilanova at ac.upc.edu>

diff --git a/Makefile.objs b/Makefile.objs
index 036a4eb..26b885b 100644
--- a/Makefile.objs
+++ b/Makefile.objs
@@ -384,6 +384,8 @@ trace-nested-$(CONFIG_TRACE_DEFAULT) += default.o
 trace-nested-$(CONFIG_TRACE_SIMPLE) += simple.o
 trace-obj-$(CONFIG_TRACE_SIMPLE) += qemu-timer-common.o
 
+trace-nested-$(CONFIG_TRACE_STDERR) += stderr.o
+
 trace-nested-y += control.o
 
 trace-obj-y += $(addprefix trace/, $(trace-nested-y))
diff --git a/configure b/configure
index 4f9b27c..300d34b 100755
--- a/configure
+++ b/configure
@@ -3078,6 +3078,7 @@ if test "$trace_backend" = "simple"; then
 fi
 if test "$trace_backend" = "stderr"; then
   echo "CONFIG_TRACE_STDERR=y" >> $config_host_mak
+  trace_default=no
 fi
 if test "$trace_backend" = "ust"; then
   echo "CONFIG_TRACE_UST=y" >> $config_host_mak
diff --git a/docs/tracing.txt b/docs/tracing.txt
index d1d4e8c..4b27ab0 100644
--- a/docs/tracing.txt
+++ b/docs/tracing.txt
@@ -178,11 +178,6 @@ effectively turns trace events into debug printfs.
 This is the simplest backend and can be used together with existing code that
 uses DPRINTF().
 
-Note that with this backend trace events cannot be programmatically
-enabled/disabled. Thus, in order to trim down the amount of output and the
-performance impact of tracing, you might want to add the "disable" property in
-the "trace-events" file for those events you are not interested in.
-
 === Simpletrace ===
 
 The "simple" backend supports common use cases and comes as part of the QEMU
diff --git a/qemu-options.hx b/qemu-options.hx
index edd181b..f672365 100644
--- a/qemu-options.hx
+++ b/qemu-options.hx
@@ -2454,7 +2454,8 @@ Immediately enable events listed in @var{file}.
 The file must contain one event name (as listed in the @var{trace-events} file)
 per line.
 
-This option is only available when using the @var{simple} tracing backend.
+This option is only available when using the @var{simple} and @var{stderr}
+tracing backends.
 @item file=@var{file}
 Log output traces to @var{file}.
 
diff --git a/scripts/tracetool b/scripts/tracetool
index c740080..743d246 100755
--- a/scripts/tracetool
+++ b/scripts/tracetool
@@ -241,7 +241,12 @@ linetoh_begin_stderr()
 {
     cat <<EOF
 #include <stdio.h>
+#include "trace/stderr.h"
+
+extern TraceEvent trace_list[];
 EOF
+
+    stderr_event_num=0
 }
 
 linetoh_stderr()
@@ -260,29 +265,47 @@ linetoh_stderr()
     cat <<EOF
 static inline void trace_$name($args)
 {
-    fprintf(stderr, "$name $fmt\n" $argnames);
+    if (trace_list[$stderr_event_num].state != 0) {
+        fprintf(stderr, "$name $fmt\n" $argnames);
+    }
 }
 EOF
+    stderr_event_num=$((stderr_event_num + 1))
+
 }
 
 linetoh_end_stderr()
 {
-return
+    cat <<EOF
+#define NR_TRACE_EVENTS $stderr_event_num
+EOF
 }
 
 linetoc_begin_stderr()
 {
-return
+    cat <<EOF
+#include "trace.h"
+
+TraceEvent trace_list[] = {
+EOF
+    stderr_event_num=0
 }
 
 linetoc_stderr()
 {
-return
+    local name
+    name=$(get_name "$1")
+    cat <<EOF
+{.tp_name = "$name", .state=0},
+EOF
+    stderr_event_num=$(($stderr_event_num + 1))
 }
 
 linetoc_end_stderr()
 {
-return
+    cat <<EOF
+};
+EOF
 }
 #END OF STDERR
 
diff --git a/trace/stderr.c b/trace/stderr.c
new file mode 100644
index 0000000..7107c4a
--- /dev/null
+++ b/trace/stderr.c
@@ -0,0 +1,37 @@
+#include "trace.h"
+#include "trace/control.h"
+
+
+void trace_print_events(FILE *stream, fprintf_function stream_printf)
+{
+    unsigned int i;
+
+    for (i = 0; i < NR_TRACE_EVENTS; i++) {
+        stream_printf(stream, "%s [Event ID %u] : state %u\n",
+                      trace_list[i].tp_name, i, trace_list[i].state);
+    }
+}
+
+bool trace_event_set_state(const char *name, bool state)
+{
+    unsigned int i;
+
+    for (i = 0; i < NR_TRACE_EVENTS; i++) {
+        if (!strcmp(trace_list[i].tp_name, name)) {
+            trace_list[i].state = state;
+            return true;
+        }
+    }
+    return false;
+}
+
+bool trace_backend_init(const char *events, const char *file)
+{
+    if (file) {
+        fprintf(stderr, "error: -trace file=...: "
+                "option not supported by the selected tracing backend\n");
+        return false;
+    }
+    trace_backend_init_events(events);
+    return true;
+}
diff --git a/trace/stderr.h b/trace/stderr.h
new file mode 100644
index 0000000..d575b61
--- /dev/null
+++ b/trace/stderr.h
@@ -0,0 +1,11 @@
+#ifndef TRACE_STDERR_H
+#define TRACE_STDERR_H
+
+typedef uint64_t TraceEventID;
+
+typedef struct {
+    const char *tp_name;
+    bool state;
+} TraceEvent;
+
+#endif /* ! TRACE_STDERR_H */
commit 03727e6a06087dc8f46d5674b4b29262bf7377a4
Author: Lluís <xscript at gmx.net>
Date:   Wed Aug 31 20:31:45 2011 +0200

    trace: [simple] disable all trace points by default
    
    Note that this refers to the backend-specific state (whether the output must be
    generated), not the event "disabled" property (which always uses the "nop"
    backend).
    
    Signed-off-by: Lluís Vilanova <vilanova at ac.upc.edu>

diff --git a/docs/tracing.txt b/docs/tracing.txt
index 85793cf..d1d4e8c 100644
--- a/docs/tracing.txt
+++ b/docs/tracing.txt
@@ -12,11 +12,16 @@ for debugging, profiling, and observing execution.
     ./configure --trace-backend=simple
     make
 
-2. Run the virtual machine to produce a trace file:
+2. Create a file with the events you want to trace:
 
-    qemu ... # your normal QEMU invocation
+   echo bdrv_aio_readv   > /tmp/events
+   echo bdrv_aio_writev >> /tmp/events
 
-3. Pretty-print the binary trace file:
+3. Run the virtual machine to produce a trace file:
+
+    qemu -trace events=/tmp/events ... # your normal QEMU invocation
+
+4. Pretty-print the binary trace file:
 
     ./simpletrace.py trace-events trace-*
 
diff --git a/scripts/tracetool b/scripts/tracetool
index e2cf117..c740080 100755
--- a/scripts/tracetool
+++ b/scripts/tracetool
@@ -221,15 +221,10 @@ EOF
 
 linetoc_simple()
 {
-    local name state
+    local name
     name=$(get_name "$1")
-    if has_property "$1" "disable"; then
-        state="0"
-    else
-        state="1"
-    fi
     cat <<EOF
-{.tp_name = "$name", .state=$state},
+{.tp_name = "$name", .state=0},
 EOF
     simple_event_num=$((simple_event_num + 1))
 }
diff --git a/trace-events b/trace-events
index f08d6d0..eb612e8 100644
--- a/trace-events
+++ b/trace-events
@@ -17,9 +17,6 @@
 # Example: qemu_malloc(size_t size) "size %zu"
 #
 # The "disable" keyword will build without the trace event.
-# In case of 'simple' trace backend, it will allow the trace event to be
-# compiled, but this would be turned off by default. It can be toggled on via
-# the monitor.
 #
 # The <name> must be a valid as a C function name.
 #
commit dd215f646c72b4cf680097b13aeb8b0c589dceb2
Author: Lluís <xscript at gmx.net>
Date:   Wed Aug 31 20:31:38 2011 +0200

    trace: always use the "nop" backend on events with the "disable" keyword
    
    Any event with the keyword/property "disable" generates an empty trace event
    using the "nop" backend, regardless of the current backend.
    
    Signed-off-by: Lluís Vilanova <vilanova at ac.upc.edu>

diff --git a/docs/tracing.txt b/docs/tracing.txt
index 455da37..85793cf 100644
--- a/docs/tracing.txt
+++ b/docs/tracing.txt
@@ -12,15 +12,11 @@ for debugging, profiling, and observing execution.
     ./configure --trace-backend=simple
     make
 
-2. Enable trace events you are interested in:
-
-    $EDITOR trace-events  # remove "disable" from events you want
-
-3. Run the virtual machine to produce a trace file:
+2. Run the virtual machine to produce a trace file:
 
     qemu ... # your normal QEMU invocation
 
-4. Pretty-print the binary trace file:
+3. Pretty-print the binary trace file:
 
     ./simpletrace.py trace-events trace-*
 
@@ -103,10 +99,11 @@ portability macros, ensure they are preceded and followed by double quotes:
 4. Name trace events after their function.  If there are multiple trace events
    in one function, append a unique distinguisher at the end of the name.
 
-5. Declare trace events with the "disable" property.  Some trace events can
-   produce a lot of output and users are typically only interested in a subset
-   of trace events.  Marking trace events disabled by default saves the user
-   from having to manually disable noisy trace events.
+5. If specific trace events are going to be called a huge number of times, this
+   might have a noticeable performance impact even when the trace events are
+   programmatically disabled. In this case you should declare the trace event
+   with the "disable" property, which will effectively disable it at compile
+   time (using the "nop" backend).
 
 == Generic interface and monitor commands ==
 
@@ -165,6 +162,9 @@ The "nop" backend generates empty trace event functions so that the compiler
 can optimize out trace events completely.  This is the default and imposes no
 performance penalty.
 
+Note that regardless of the selected trace backend, events with the "disable"
+property will be generated with the "nop" backend.
+
 === Stderr ===
 
 The "stderr" backend sends trace events directly to standard error.  This
@@ -173,6 +173,11 @@ effectively turns trace events into debug printfs.
 This is the simplest backend and can be used together with existing code that
 uses DPRINTF().
 
+Note that with this backend trace events cannot be programmatically
+enabled/disabled. Thus, in order to trim down the amount of output and the
+performance impact of tracing, you might want to add the "disable" property in
+the "trace-events" file for those events you are not interested in.
+
 === Simpletrace ===
 
 The "simple" backend supports common use cases and comes as part of the QEMU
diff --git a/scripts/tracetool b/scripts/tracetool
index e649a5b..e2cf117 100755
--- a/scripts/tracetool
+++ b/scripts/tracetool
@@ -506,21 +506,10 @@ convert()
         # Skip comments and empty lines
         test -z "${str%%#*}" && continue
 
+        echo
         # Process the line.  The nop backend handles disabled lines.
-        disable="0"
         if has_property "$str" "disable"; then
-            disable="1"
-        fi
-        echo
-        if [ "$disable" = "1" ]; then
-            # Pass the disabled state as an arg for the simple
-            # or DTrace backends which handle it dynamically.
-            # For all other backends, call lineto$1_nop()
-            if [ $backend = "simple" -o "$backend" = "dtrace" ]; then
-                "$process_line" "$str"
-            else
-                "lineto$1_nop" "${str##disable }"
-            fi
+            "lineto$1_nop" "$str"
         else
             "$process_line" "$str"
         fi
commit 23d15e860b33819ad76092fbb32577542fe0c44d
Author: Lluís <xscript at gmx.net>
Date:   Wed Aug 31 20:31:31 2011 +0200

    trace: add "-trace events" argument to control initial state
    
    The "-trace events" argument can be used to provide a file with a list of trace
    event names that will be enabled prior to starting execution, thus providing
    early tracing.
    
    This saves the user from manually toggling event states through the monitor
    interface or whichever backend-specific interface.
    
    Signed-off-by: Lluís Vilanova <vilanova at ac.upc.edu>

diff --git a/Makefile.objs b/Makefile.objs
index 57a80e6..036a4eb 100644
--- a/Makefile.objs
+++ b/Makefile.objs
@@ -384,6 +384,8 @@ trace-nested-$(CONFIG_TRACE_DEFAULT) += default.o
 trace-nested-$(CONFIG_TRACE_SIMPLE) += simple.o
 trace-obj-$(CONFIG_TRACE_SIMPLE) += qemu-timer-common.o
 
+trace-nested-y += control.o
+
 trace-obj-y += $(addprefix trace/, $(trace-nested-y))
 
 ######################################################################
diff --git a/docs/tracing.txt b/docs/tracing.txt
index 41eb8e6..455da37 100644
--- a/docs/tracing.txt
+++ b/docs/tracing.txt
@@ -138,6 +138,10 @@ This functionality is also provided through monitor commands:
 * trace-event NAME on|off
   Enable/disable a given trace event.
 
+The "-trace events=<file>" command line argument can be used to enable the
+events listed in <file> from the very beginning of the program. This file must
+contain one event name per line.
+
 == Trace backends ==
 
 The "tracetool" script automates tedious trace event code generation and also
diff --git a/qemu-config.c b/qemu-config.c
index 4f3465d..7a7854f 100644
--- a/qemu-config.c
+++ b/qemu-config.c
@@ -309,6 +309,9 @@ static QemuOptsList qemu_trace_opts = {
     .head = QTAILQ_HEAD_INITIALIZER(qemu_trace_opts.head),
     .desc = {
         {
+            .name = "events",
+            .type = QEMU_OPT_STRING,
+        },{
             .name = "file",
             .type = QEMU_OPT_STRING,
         },
diff --git a/qemu-options.hx b/qemu-options.hx
index 2d29933..edd181b 100644
--- a/qemu-options.hx
+++ b/qemu-options.hx
@@ -2437,17 +2437,29 @@ Normally QEMU loads a configuration file from @var{sysconfdir}/qemu.conf and
 option will prevent QEMU from loading these configuration files at startup.
 ETEXI
 DEF("trace", HAS_ARG, QEMU_OPTION_trace,
-    "-trace\n"
-    "                Specify a trace file to log traces to\n",
+    "-trace [events=<file>][,file=<file>]\n"
+    "                specify tracing options\n",
     QEMU_ARCH_ALL)
 STEXI
-HXCOMM This line is not accurate, as the option is backend-specific but HX does
-HXCOMM not support conditional compilation of text.
- at item -trace
+HXCOMM This line is not accurate, as some sub-options are backend-specific but
+HXCOMM HX does not support conditional compilation of text.
+ at item -trace [events=@var{file}][,file=@var{file}]
 @findex -trace
-Specify a trace file to log output traces to.
 
-This option is available only when using the @var{simple} tracing backend.
+Specify tracing options.
+
+ at table @option
+ at item events=@var{file}
+Immediately enable events listed in @var{file}.
+The file must contain one event name (as listed in the @var{trace-events} file)
+per line.
+
+This option is only available when using the @var{simple} tracing backend.
+ at item file=@var{file}
+Log output traces to @var{file}.
+
+This option is only available when using the @var{simple} tracing backend.
+ at end table
 ETEXI
 
 HXCOMM This is the last statement. Insert new options before this line!
diff --git a/trace/control.c b/trace/control.c
new file mode 100644
index 0000000..4c5527d
--- /dev/null
+++ b/trace/control.c
@@ -0,0 +1,42 @@
+/*
+ * Interface for configuring and controlling the state of tracing events.
+ *
+ * Copyright (C) 2011 Lluís Vilanova <vilanova at ac.upc.edu>
+ *
+ * This work is licensed under the terms of the GNU GPL, version 2.  See
+ * the COPYING file in the top-level directory.
+ */
+
+#include "trace/control.h"
+
+
+void trace_backend_init_events(const char *fname)
+{
+    if (fname == NULL) {
+        return;
+    }
+
+    FILE *fp = fopen(fname, "r");
+    if (!fp) {
+        fprintf(stderr, "error: could not open trace events file '%s': %s\n",
+                fname, strerror(errno));
+        exit(1);
+    }
+    char line_buf[1024];
+    while (fgets(line_buf, sizeof(line_buf), fp)) {
+        size_t len = strlen(line_buf);
+        if (len > 1) {              /* skip empty lines */
+            line_buf[len - 1] = '\0';
+            if (!trace_event_set_state(line_buf, true)) {
+                fprintf(stderr,
+                        "error: trace event '%s' does not exist\n", line_buf);
+                exit(1);
+            }
+        }
+    }
+    if (fclose(fp) != 0) {
+        fprintf(stderr, "error: closing file '%s': %s\n",
+                fname, strerror(errno));
+        exit(1);
+    }
+}
diff --git a/trace/control.h b/trace/control.h
index c99b4d5..2acaa42 100644
--- a/trace/control.h
+++ b/trace/control.h
@@ -24,10 +24,18 @@ bool trace_event_set_state(const char *name, bool state);
 
 /** Initialize the tracing backend.
  *
- * @file Name of trace output file; may be NULL.
- *       Corresponds to commandline option "-trace file=...".
+ * @events Name of file with events to be enabled at startup; may be NULL.
+ *         Corresponds to commandline option "-trace events=...".
+ * @file   Name of trace output file; may be NULL.
+ *         Corresponds to commandline option "-trace file=...".
  * @return Whether the backend could be successfully initialized.
  */
-bool trace_backend_init(const char *file);
+bool trace_backend_init(const char *events, const char *file);
+
+/** Generic function to initialize the state of events.
+ *
+ * @fname Name of file with events to enable; may be NULL.
+ */
+void trace_backend_init_events(const char *fname);
 
 #endif  /* TRACE_CONTROL_H */
diff --git a/trace/default.c b/trace/default.c
index 3573d5b..c9b27a2 100644
--- a/trace/default.c
+++ b/trace/default.c
@@ -25,8 +25,13 @@ bool trace_event_set_state(const char *name, bool state)
     return false;
 }
 
-bool trace_backend_init(const char *file)
+bool trace_backend_init(const char *events, const char *file)
 {
+    if (events) {
+        fprintf(stderr, "error: -trace events=...: "
+                "option not supported by the selected tracing backend\n");
+        return false;
+    }
     if (file) {
         fprintf(stderr, "error: -trace file=...: "
                 "option not supported by the selected tracing backend\n");
diff --git a/trace/simple.c b/trace/simple.c
index 70689e9..a609368 100644
--- a/trace/simple.c
+++ b/trace/simple.c
@@ -331,7 +331,7 @@ bool trace_event_set_state(const char *name, bool state)
     return false;
 }
 
-bool trace_backend_init(const char *file)
+bool trace_backend_init(const char *events, const char *file)
 {
     pthread_t thread;
     pthread_attr_t attr;
@@ -350,6 +350,7 @@ bool trace_backend_init(const char *file)
         fprintf(stderr, "warning: unable to initialize simple trace backend\n");
     } else {
         atexit(st_flush_trace_buffer);
+        trace_backend_init_events(events);
         st_set_trace_file(file);
     }
 
diff --git a/vl.c b/vl.c
index 60322b6..c6dc689 100644
--- a/vl.c
+++ b/vl.c
@@ -2137,6 +2137,7 @@ int main(int argc, char **argv, char **envp)
         .realloc = realloc_and_trace,
         .free = free_and_trace,
     };
+    const char *trace_events = NULL;
     const char *trace_file = NULL;
 
     atexit(qemu_run_exit_notifiers);
@@ -2934,6 +2935,7 @@ int main(int argc, char **argv, char **envp)
                 if (!opts) {
                     exit(1);
                 }
+                trace_events = qemu_opt_get(opts, "events");
                 trace_file = qemu_opt_get(opts, "file");
                 break;
             }
@@ -2994,7 +2996,7 @@ int main(int argc, char **argv, char **envp)
         set_cpu_log(log_mask);
     }
 
-    if (!trace_backend_init(trace_file)) {
+    if (!trace_backend_init(trace_events, trace_file)) {
         exit(1);
     }
 
commit 31965ae27bc11e90674be12584bb201b83df5aef
Author: Lluís <xscript at gmx.net>
Date:   Wed Aug 31 20:31:24 2011 +0200

    trace: always compile support for controlling and querying trace event states
    
    The current interface is generic for this small set of operations, and thus
    other backends can easily modify the "trace/control.c" file to add their own
    implementation.
    
    Signed-off-by: Lluís Vilanova <vilanova at ac.upc.edu>

diff --git a/docs/tracing.txt b/docs/tracing.txt
index 1ad106a..41eb8e6 100644
--- a/docs/tracing.txt
+++ b/docs/tracing.txt
@@ -108,6 +108,36 @@ portability macros, ensure they are preceded and followed by double quotes:
    of trace events.  Marking trace events disabled by default saves the user
    from having to manually disable noisy trace events.
 
+== Generic interface and monitor commands ==
+
+You can programmatically query and control the dynamic state of trace events
+through a backend-agnostic interface:
+
+* trace_print_events
+
+* trace_event_set_state
+  Enables or disables trace events at runtime inside QEMU.
+  The function returns "true" if the state of the event has been successfully
+  changed, or "false" otherwise:
+
+    #include "trace/control.h"
+    
+    trace_event_set_state("virtio_irq", true); /* enable */
+    [...]
+    trace_event_set_state("virtio_irq", false); /* disable */
+
+Note that some of the backends do not provide an implementation for this
+interface, in which case QEMU will just print a warning.
+
+This functionality is also provided through monitor commands:
+
+* info trace-events
+  View available trace events and their state.  State 1 means enabled, state 0
+  means disabled.
+
+* trace-event NAME on|off
+  Enable/disable a given trace event.
+
 == Trace backends ==
 
 The "tracetool" script automates tedious trace event code generation and also
@@ -157,27 +187,9 @@ unless you have specific needs for more advanced backends.
   flushed and emptied.  This means the 'info trace' will display few or no
   entries if the buffer has just been flushed.
 
-* info trace-events
-  View available trace events and their state.  State 1 means enabled, state 0
-  means disabled.
-
-* trace-event NAME on|off
-  Enable/disable a given trace event.
-
 * trace-file on|off|flush|set <path>
   Enable/disable/flush the trace file or set the trace file name.
 
-==== Enabling/disabling trace events programmatically ====
-
-The st_change_trace_event_state() function can be used to enable or disable trace
-events at runtime inside QEMU:
-
-    #include "trace.h"
-    
-    st_change_trace_event_state("virtio_irq", true); /* enable */
-    [...]
-    st_change_trace_event_state("virtio_irq", false); /* disable */
-
 ==== Analyzing trace files ====
 
 The "simple" backend produces binary trace files that can be formatted with the
diff --git a/hmp-commands.hx b/hmp-commands.hx
index d77e75f..9e1cca8 100644
--- a/hmp-commands.hx
+++ b/hmp-commands.hx
@@ -180,7 +180,6 @@ STEXI
 Output logs to @var{filename}.
 ETEXI
 
-#ifdef CONFIG_TRACE_SIMPLE
     {
         .name       = "trace-event",
         .args_type  = "name:s,option:b",
@@ -195,6 +194,7 @@ STEXI
 changes status of a trace event
 ETEXI
 
+#if defined(CONFIG_SIMPLE_TRACE)
     {
         .name       = "trace-file",
         .args_type  = "op:s?,arg:F?",
@@ -1358,10 +1358,13 @@ ETEXI
 STEXI
 @item info trace
 show contents of trace buffer
+ETEXI
+#endif
+
+STEXI
 @item info trace-events
 show available trace events and their state
 ETEXI
-#endif
 
 STEXI
 @end table
diff --git a/monitor.c b/monitor.c
index 2cff62d..df0f622 100644
--- a/monitor.c
+++ b/monitor.c
@@ -57,8 +57,9 @@
 #include "json-parser.h"
 #include "osdep.h"
 #include "cpu.h"
+#include "trace/control.h"
 #ifdef CONFIG_TRACE_SIMPLE
-#include "trace.h"
+#include "trace/simple.h"
 #endif
 #include "trace/control.h"
 #include "ui/qemu-spice.h"
@@ -593,7 +594,6 @@ static void do_help_cmd(Monitor *mon, const QDict *qdict)
     help_cmd(mon, qdict_get_try_str(qdict, "name"));
 }
 
-#ifdef CONFIG_TRACE_SIMPLE
 static void do_trace_event_set_state(Monitor *mon, const QDict *qdict)
 {
     const char *tp_name = qdict_get_str(qdict, "name");
@@ -605,6 +605,7 @@ static void do_trace_event_set_state(Monitor *mon, const QDict *qdict)
     }
 }
 
+#ifdef CONFIG_SIMPLE_TRACE
 static void do_trace_file(Monitor *mon, const QDict *qdict)
 {
     const char *op = qdict_get_try_str(qdict, "op");
@@ -1002,12 +1003,12 @@ static void do_info_trace(Monitor *mon)
 {
     st_print_trace((FILE *)mon, &monitor_fprintf);
 }
+#endif
 
 static void do_trace_print_events(Monitor *mon)
 {
     trace_print_events((FILE *)mon, &monitor_fprintf);
 }
-#endif
 
 /**
  * do_quit(): Quit QEMU execution
@@ -3144,6 +3145,7 @@ static const mon_cmd_t info_cmds[] = {
         .help       = "show current contents of trace buffer",
         .mhandler.info = do_info_trace,
     },
+#endif
     {
         .name       = "trace-events",
         .args_type  = "",
@@ -3151,7 +3153,6 @@ static const mon_cmd_t info_cmds[] = {
         .help       = "show available trace-events & their state",
         .mhandler.info = do_trace_print_events,
     },
-#endif
     {
         .name       = NULL,
     },
commit fc764105397fa55e7c03f42a6d019063ec0cad00
Author: Lluís <xscript at gmx.net>
Date:   Wed Aug 31 20:31:18 2011 +0200

    trace: separate trace event control and query routines from the simple backend
    
    Generalize the 'st_print_trace_events' and 'st_change_trace_event_state' into
    backend-specific 'trace_print_events' and 'trace_event_set_state' (respectively)
    in the "trace/control.h" file.
    
    Signed-off-by: Lluís Vilanova <vilanova at ac.upc.edu>

diff --git a/hmp-commands.hx b/hmp-commands.hx
index ad4174f..d77e75f 100644
--- a/hmp-commands.hx
+++ b/hmp-commands.hx
@@ -186,7 +186,7 @@ ETEXI
         .args_type  = "name:s,option:b",
         .params     = "name on|off",
         .help       = "changes status of a specific trace event",
-        .mhandler.cmd = do_change_trace_event_state,
+        .mhandler.cmd = do_trace_event_set_state,
     },
 
 STEXI
diff --git a/monitor.c b/monitor.c
index 935aa33..2cff62d 100644
--- a/monitor.c
+++ b/monitor.c
@@ -60,6 +60,7 @@
 #ifdef CONFIG_TRACE_SIMPLE
 #include "trace.h"
 #endif
+#include "trace/control.h"
 #include "ui/qemu-spice.h"
 
 //#define DEBUG
@@ -593,11 +594,11 @@ static void do_help_cmd(Monitor *mon, const QDict *qdict)
 }
 
 #ifdef CONFIG_TRACE_SIMPLE
-static void do_change_trace_event_state(Monitor *mon, const QDict *qdict)
+static void do_trace_event_set_state(Monitor *mon, const QDict *qdict)
 {
     const char *tp_name = qdict_get_str(qdict, "name");
     bool new_state = qdict_get_bool(qdict, "option");
-    int ret = st_change_trace_event_state(tp_name, new_state);
+    int ret = trace_event_set_state(tp_name, new_state);
 
     if (!ret) {
         monitor_printf(mon, "unknown event name \"%s\"\n", tp_name);
@@ -1002,9 +1003,9 @@ static void do_info_trace(Monitor *mon)
     st_print_trace((FILE *)mon, &monitor_fprintf);
 }
 
-static void do_info_trace_events(Monitor *mon)
+static void do_trace_print_events(Monitor *mon)
 {
-    st_print_trace_events((FILE *)mon, &monitor_fprintf);
+    trace_print_events((FILE *)mon, &monitor_fprintf);
 }
 #endif
 
@@ -3148,7 +3149,7 @@ static const mon_cmd_t info_cmds[] = {
         .args_type  = "",
         .params     = "",
         .help       = "show available trace-events & their state",
-        .mhandler.info = do_info_trace_events,
+        .mhandler.info = do_trace_print_events,
     },
 #endif
     {
diff --git a/trace/control.h b/trace/control.h
index bb54339..c99b4d5 100644
--- a/trace/control.h
+++ b/trace/control.h
@@ -10,7 +10,16 @@
 #ifndef TRACE_CONTROL_H
 #define TRACE_CONTROL_H
 
-#include <stdbool.h>
+#include "qemu-common.h"
+
+
+/** Print the state of all events. */
+void trace_print_events(FILE *stream, fprintf_function stream_printf);
+/** Set the state of an event.
+ *
+ * @return Whether the state changed.
+ */
+bool trace_event_set_state(const char *name, bool state);
 
 
 /** Initialize the tracing backend.
diff --git a/trace/default.c b/trace/default.c
index 42fdb6b..3573d5b 100644
--- a/trace/default.c
+++ b/trace/default.c
@@ -10,6 +10,21 @@
 #include "trace/control.h"
 
 
+void trace_print_events(FILE *stream, fprintf_function stream_printf)
+{
+    fprintf(stderr, "warning: "
+            "cannot print the trace events with the current backend\n");
+    stream_printf(stream, "error: "
+                  "operation not supported with the current backend\n");
+}
+
+bool trace_event_set_state(const char *name, bool state)
+{
+    fprintf(stderr, "warning: "
+            "cannot set the state of a trace event with the current backend\n");
+    return false;
+}
+
 bool trace_backend_init(const char *file)
 {
     if (file) {
diff --git a/trace/simple.c b/trace/simple.c
index 369e860..70689e9 100644
--- a/trace/simple.c
+++ b/trace/simple.c
@@ -303,7 +303,12 @@ void st_print_trace(FILE *stream, int (*stream_printf)(FILE *stream, const char
     }
 }
 
-void st_print_trace_events(FILE *stream, int (*stream_printf)(FILE *stream, const char *fmt, ...))
+void st_flush_trace_buffer(void)
+{
+    flush_trace_file(true);
+}
+
+void trace_print_events(FILE *stream, fprintf_function stream_printf)
 {
     unsigned int i;
 
@@ -313,24 +318,19 @@ void st_print_trace_events(FILE *stream, int (*stream_printf)(FILE *stream, cons
     }
 }
 
-bool st_change_trace_event_state(const char *name, bool enabled)
+bool trace_event_set_state(const char *name, bool state)
 {
     unsigned int i;
 
     for (i = 0; i < NR_TRACE_EVENTS; i++) {
         if (!strcmp(trace_list[i].tp_name, name)) {
-            trace_list[i].state = enabled;
+            trace_list[i].state = state;
             return true;
         }
     }
     return false;
 }
 
-void st_flush_trace_buffer(void)
-{
-    flush_trace_file(true);
-}
-
 bool trace_backend_init(const char *file)
 {
     pthread_t thread;
diff --git a/trace/simple.h b/trace/simple.h
index 08b9a52..466e75b 100644
--- a/trace/simple.h
+++ b/trace/simple.h
@@ -30,8 +30,6 @@ void trace4(TraceEventID event, uint64_t x1, uint64_t x2, uint64_t x3, uint64_t
 void trace5(TraceEventID event, uint64_t x1, uint64_t x2, uint64_t x3, uint64_t x4, uint64_t x5);
 void trace6(TraceEventID event, uint64_t x1, uint64_t x2, uint64_t x3, uint64_t x4, uint64_t x5, uint64_t x6);
 void st_print_trace(FILE *stream, fprintf_function stream_printf);
-void st_print_trace_events(FILE *stream, fprintf_function stream_printf);
-bool st_change_trace_event_state(const char *tname, bool tstate);
 void st_print_trace_file_status(FILE *stream, fprintf_function stream_printf);
 void st_set_trace_file_enabled(bool enable);
 bool st_set_trace_file(const char *file);
commit 49926043c1319ce99481d45c87c602c20b9dbb79
Author: Lluís <xscript at gmx.net>
Date:   Wed Aug 31 20:31:10 2011 +0200

    trace: generalize the "property" concept in the trace-events file
    
    This adds/modifies the following functions:
    
    * get_name: Get _only_ the event name
    * has_property: Return whether an event has a property (keyword before the event
      name)
    
    Signed-off-by: Lluís Vilanova <vilanova at ac.upc.edu>

diff --git a/docs/tracing.txt b/docs/tracing.txt
index c99a0f2..1ad106a 100644
--- a/docs/tracing.txt
+++ b/docs/tracing.txt
@@ -38,7 +38,7 @@ generate code for the trace events.  Trace events are invoked directly from
 source code like this:
 
     #include "trace.h"  /* needed for trace event prototype */
-
+    
     void *qemu_malloc(size_t size)
     {
         void *ptr;
@@ -103,7 +103,7 @@ portability macros, ensure they are preceded and followed by double quotes:
 4. Name trace events after their function.  If there are multiple trace events
    in one function, append a unique distinguisher at the end of the name.
 
-5. Declare trace events with the "disable" keyword.  Some trace events can
+5. Declare trace events with the "disable" property.  Some trace events can
    produce a lot of output and users are typically only interested in a subset
    of trace events.  Marking trace events disabled by default saves the user
    from having to manually disable noisy trace events.
diff --git a/scripts/tracetool b/scripts/tracetool
index 9ed4fae..e649a5b 100755
--- a/scripts/tracetool
+++ b/scripts/tracetool
@@ -43,7 +43,26 @@ EOF
 # Get the name of a trace event
 get_name()
 {
-    echo ${1%%\(*}
+    local name
+    name=${1%%\(*}
+    echo "${name##* }"
+}
+
+# Get the given property of a trace event
+# 1: trace-events line
+# 2: property name
+# -> return 0 if property is present, or 1 otherwise
+has_property()
+{
+    local props prop
+    props=${1%%\(*}
+    props=${props% *}
+    for prop in $props; do
+        if [ "$prop" = "$2" ]; then
+            return 0
+        fi
+    done
+    return 1
 }
 
 # Get the argument list of a trace event, including types and names
@@ -101,20 +120,6 @@ get_fmt()
     echo "$fmt"
 }
 
-# Get the state of a trace event
-get_state()
-{
-    local str disable state
-    str=$(get_name "$1")
-    disable=${str##disable }
-    if [ "$disable" = "$str" ] ; then
-        state=1
-    else
-        state=0
-    fi
-    echo "$state"
-}
-
 linetoh_begin_nop()
 {
     return
@@ -174,14 +179,10 @@ cast_args_to_uint64_t()
 
 linetoh_simple()
 {
-    local name args argc trace_args state
+    local name args argc trace_args
     name=$(get_name "$1")
     args=$(get_args "$1")
     argc=$(get_argc "$1")
-    state=$(get_state "$1")
-    if [ "$state" = "0" ]; then
-        name=${name##disable }
-    fi
 
     trace_args="$simple_event_num"
     if [ "$argc" -gt 0 ]
@@ -222,9 +223,10 @@ linetoc_simple()
 {
     local name state
     name=$(get_name "$1")
-    state=$(get_state "$1")
-    if [ "$state" = "0" ] ; then
-        name=${name##disable }
+    if has_property "$1" "disable"; then
+        state="0"
+    else
+        state="1"
     fi
     cat <<EOF
 {.tp_name = "$name", .state=$state},
@@ -379,14 +381,10 @@ EOF
 
 linetoh_dtrace()
 {
-    local name args argnames state nameupper
+    local name args argnames nameupper
     name=$(get_name "$1")
     args=$(get_args "$1")
     argnames=$(get_argnames "$1", ",")
-    state=$(get_state "$1")
-    if [ "$state" = "0" ] ; then
-        name=${name##disable }
-    fi
 
     nameupper=`echo $name | tr '[:lower:]' '[:upper:]'`
 
@@ -430,13 +428,9 @@ EOF
 
 linetod_dtrace()
 {
-    local name args state
+    local name args
     name=$(get_name "$1")
     args=$(get_args "$1")
-    state=$(get_state "$1")
-    if [ "$state" = "0" ] ; then
-        name=${name##disable }
-    fi
 
     # DTrace provider syntax expects foo() for empty
     # params, not foo(void)
@@ -464,14 +458,10 @@ linetostap_begin_dtrace()
 
 linetostap_dtrace()
 {
-    local i arg name args arglist state
+    local i arg name args arglist
     name=$(get_name "$1")
     args=$(get_args "$1")
     arglist=$(get_argnames "$1", "")
-    state=$(get_state "$1")
-    if [ "$state" = "0" ] ; then
-        name=${name##disable }
-    fi
 
     # Define prototype for probe arguments
     cat <<EOF
@@ -517,9 +507,12 @@ convert()
         test -z "${str%%#*}" && continue
 
         # Process the line.  The nop backend handles disabled lines.
-        disable=${str%%disable *}
+        disable="0"
+        if has_property "$str" "disable"; then
+            disable="1"
+        fi
         echo
-        if test -z "$disable"; then
+        if [ "$disable" = "1" ]; then
             # Pass the disabled state as an arg for the simple
             # or DTrace backends which handle it dynamically.
             # For all other backends, call lineto$1_nop()
commit e4858974ec36afd8a6b3a9e2b0ad8f357f28efc7
Author: Lluís <xscript at gmx.net>
Date:   Wed Aug 31 20:31:03 2011 +0200

    trace: avoid conditional code compilation during option parsing
    
    A default implementation for backend-specific routines is provided in
    "trace/default.c", which backends can override by setting "trace_default=no" in
    "configure".
    
    Signed-off-by: Lluís Vilanova <vilanova at ac.upc.edu>

diff --git a/Makefile.objs b/Makefile.objs
index 4f8b0ed..57a80e6 100644
--- a/Makefile.objs
+++ b/Makefile.objs
@@ -379,6 +379,8 @@ ifneq ($(TRACE_BACKEND),dtrace)
 trace-obj-y = trace.o
 endif
 
+trace-nested-$(CONFIG_TRACE_DEFAULT) += default.o
+
 trace-nested-$(CONFIG_TRACE_SIMPLE) += simple.o
 trace-obj-$(CONFIG_TRACE_SIMPLE) += qemu-timer-common.o
 
diff --git a/configure b/configure
index ebf14ee..4f9b27c 100755
--- a/configure
+++ b/configure
@@ -3064,12 +3064,15 @@ bsd)
 ;;
 esac
 
+# use default implementation for tracing backend-specific routines
+trace_default=yes
 echo "TRACE_BACKEND=$trace_backend" >> $config_host_mak
 if test "$trace_backend" = "nop"; then
   echo "CONFIG_TRACE_NOP=y" >> $config_host_mak
 fi
 if test "$trace_backend" = "simple"; then
   echo "CONFIG_TRACE_SIMPLE=y" >> $config_host_mak
+  trace_default=no
   # Set the appropriate trace file.
   trace_file="\"$trace_file-\" FMT_pid"
 fi
@@ -3086,6 +3089,9 @@ if test "$trace_backend" = "dtrace"; then
   fi
 fi
 echo "CONFIG_TRACE_FILE=$trace_file" >> $config_host_mak
+if test "$trace_default" = "yes"; then
+  echo "CONFIG_TRACE_DEFAULT=y" >> $config_host_mak
+fi
 
 echo "TOOLS=$tools" >> $config_host_mak
 echo "ROMS=$roms" >> $config_host_mak
diff --git a/qemu-config.c b/qemu-config.c
index b64edc9..4f3465d 100644
--- a/qemu-config.c
+++ b/qemu-config.c
@@ -303,7 +303,6 @@ static QemuOptsList qemu_mon_opts = {
     },
 };
 
-#ifdef CONFIG_TRACE_SIMPLE
 static QemuOptsList qemu_trace_opts = {
     .name = "trace",
     .implied_opt_name = "trace",
@@ -316,7 +315,6 @@ static QemuOptsList qemu_trace_opts = {
         { /* end of list */ }
     },
 };
-#endif
 
 static QemuOptsList qemu_cpudef_opts = {
     .name = "cpudef",
@@ -517,9 +515,7 @@ static QemuOptsList *vm_config_groups[32] = {
     &qemu_global_opts,
     &qemu_mon_opts,
     &qemu_cpudef_opts,
-#ifdef CONFIG_TRACE_SIMPLE
     &qemu_trace_opts,
-#endif
     &qemu_option_rom_opts,
     &qemu_machine_opts,
     &qemu_boot_opts,
diff --git a/qemu-options.hx b/qemu-options.hx
index dcb00b7..2d29933 100644
--- a/qemu-options.hx
+++ b/qemu-options.hx
@@ -2436,17 +2436,19 @@ Normally QEMU loads a configuration file from @var{sysconfdir}/qemu.conf and
 @var{sysconfdir}/target- at var{ARCH}.conf on startup.  The @code{-nodefconfig}
 option will prevent QEMU from loading these configuration files at startup.
 ETEXI
-#ifdef CONFIG_TRACE_SIMPLE
 DEF("trace", HAS_ARG, QEMU_OPTION_trace,
     "-trace\n"
     "                Specify a trace file to log traces to\n",
     QEMU_ARCH_ALL)
 STEXI
+HXCOMM This line is not accurate, as the option is backend-specific but HX does
+HXCOMM not support conditional compilation of text.
 @item -trace
 @findex -trace
 Specify a trace file to log output traces to.
+
+This option is available only when using the @var{simple} tracing backend.
 ETEXI
-#endif
 
 HXCOMM This is the last statement. Insert new options before this line!
 STEXI
diff --git a/trace/control.h b/trace/control.h
new file mode 100644
index 0000000..bb54339
--- /dev/null
+++ b/trace/control.h
@@ -0,0 +1,24 @@
+/*
+ * Interface for configuring and controlling the state of tracing events.
+ *
+ * Copyright (C) 2011 Lluís Vilanova <vilanova at ac.upc.edu>
+ *
+ * This work is licensed under the terms of the GNU GPL, version 2.  See
+ * the COPYING file in the top-level directory.
+ */
+
+#ifndef TRACE_CONTROL_H
+#define TRACE_CONTROL_H
+
+#include <stdbool.h>
+
+
+/** Initialize the tracing backend.
+ *
+ * @file Name of trace output file; may be NULL.
+ *       Corresponds to commandline option "-trace file=...".
+ * @return Whether the backend could be successfully initialized.
+ */
+bool trace_backend_init(const char *file);
+
+#endif  /* TRACE_CONTROL_H */
diff --git a/trace/default.c b/trace/default.c
new file mode 100644
index 0000000..42fdb6b
--- /dev/null
+++ b/trace/default.c
@@ -0,0 +1,21 @@
+/*
+ * Default implementation for backend initialization from commandline.
+ *
+ * Copyright (C) 2011 Lluís Vilanova <vilanova at ac.upc.edu>
+ *
+ * This work is licensed under the terms of the GNU GPL, version 2.  See
+ * the COPYING file in the top-level directory.
+ */
+
+#include "trace/control.h"
+
+
+bool trace_backend_init(const char *file)
+{
+    if (file) {
+        fprintf(stderr, "error: -trace file=...: "
+                "option not supported by the selected tracing backend\n");
+        return false;
+    }
+    return true;
+}
diff --git a/trace/simple.c b/trace/simple.c
index de355e9..369e860 100644
--- a/trace/simple.c
+++ b/trace/simple.c
@@ -16,6 +16,7 @@
 #include <pthread.h>
 #include "qemu-timer.h"
 #include "trace.h"
+#include "trace/control.h"
 
 /** Trace file header event ID */
 #define HEADER_EVENT_ID (~(uint64_t)0) /* avoids conflicting with TraceEventIDs */
@@ -330,7 +331,7 @@ void st_flush_trace_buffer(void)
     flush_trace_file(true);
 }
 
-bool st_init(const char *file)
+bool trace_backend_init(const char *file)
 {
     pthread_t thread;
     pthread_attr_t attr;
@@ -346,10 +347,11 @@ bool st_init(const char *file)
     pthread_sigmask(SIG_SETMASK, &oldset, NULL);
 
     if (ret != 0) {
-        return false;
+        fprintf(stderr, "warning: unable to initialize simple trace backend\n");
+    } else {
+        atexit(st_flush_trace_buffer);
+        st_set_trace_file(file);
     }
 
-    atexit(st_flush_trace_buffer);
-    st_set_trace_file(file);
     return true;
 }
diff --git a/trace/simple.h b/trace/simple.h
index 77633ab..08b9a52 100644
--- a/trace/simple.h
+++ b/trace/simple.h
@@ -15,7 +15,6 @@
 #include <stdbool.h>
 #include <stdio.h>
 
-#ifdef CONFIG_TRACE_SIMPLE
 typedef uint64_t TraceEventID;
 
 typedef struct {
@@ -37,12 +36,5 @@ void st_print_trace_file_status(FILE *stream, fprintf_function stream_printf);
 void st_set_trace_file_enabled(bool enable);
 bool st_set_trace_file(const char *file);
 void st_flush_trace_buffer(void);
-bool st_init(const char *file);
-#else
-static inline bool st_init(const char *file)
-{
-    return true;
-}
-#endif /* !CONFIG_TRACE_SIMPLE */
 
 #endif /* TRACE_SIMPLE_H */
diff --git a/vl.c b/vl.c
index 145d738..60322b6 100644
--- a/vl.c
+++ b/vl.c
@@ -156,7 +156,7 @@ int main(int argc, char **argv)
 #include "slirp/libslirp.h"
 
 #include "trace.h"
-#include "trace/simple.h"
+#include "trace/control.h"
 #include "qemu-queue.h"
 #include "cpus.h"
 #include "arch_init.h"
@@ -2130,7 +2130,6 @@ int main(int argc, char **argv, char **envp)
     int show_vnc_port = 0;
 #endif
     int defconfig = 1;
-    const char *trace_file = NULL;
     const char *log_mask = NULL;
     const char *log_file = NULL;
     GMemVTable mem_trace = {
@@ -2138,6 +2137,7 @@ int main(int argc, char **argv, char **envp)
         .realloc = realloc_and_trace,
         .free = free_and_trace,
     };
+    const char *trace_file = NULL;
 
     atexit(qemu_run_exit_notifiers);
     error_set_progname(argv[0]);
@@ -2928,14 +2928,15 @@ int main(int argc, char **argv, char **envp)
                 }
                 xen_mode = XEN_ATTACH;
                 break;
-#ifdef CONFIG_TRACE_SIMPLE
             case QEMU_OPTION_trace:
+            {
                 opts = qemu_opts_parse(qemu_find_opts("trace"), optarg, 0);
-                if (opts) {
-                    trace_file = qemu_opt_get(opts, "file");
+                if (!opts) {
+                    exit(1);
                 }
+                trace_file = qemu_opt_get(opts, "file");
                 break;
-#endif
+            }
             case QEMU_OPTION_readconfig:
                 {
                     int ret = qemu_read_config_file(optarg);
@@ -2993,8 +2994,8 @@ int main(int argc, char **argv, char **envp)
         set_cpu_log(log_mask);
     }
 
-    if (!st_init(trace_file)) {
-        fprintf(stderr, "warning: unable to initialize simple trace backend\n");
+    if (!trace_backend_init(trace_file)) {
+        exit(1);
     }
 
     /* If no data_dir is specified then try to find it relative to the
commit edb47ec498a5c00607e8d428668d5141822a9eac
Author: Lluís <xscript at gmx.net>
Date:   Wed Aug 31 20:30:57 2011 +0200

    trace: move backend-specific code into the trace/ directory
    
    Signed-off-by: Lluís Vilanova <vilanova at ac.upc.edu>

diff --git a/Makefile b/Makefile
index 8606849..13be25a 100644
--- a/Makefile
+++ b/Makefile
@@ -209,6 +209,7 @@ clean:
 	rm -Rf .libs
 	rm -f slirp/*.o slirp/*.d audio/*.o audio/*.d block/*.o block/*.d net/*.o net/*.d fsdev/*.o fsdev/*.d ui/*.o ui/*.d qapi/*.o qapi/*.d qga/*.o qga/*.d
 	rm -f qemu-img-cmds.h
+	rm -f trace/*.o trace/*.d
 	rm -f trace.c trace.h trace.c-timestamp trace.h-timestamp
 	rm -f trace-dtrace.dtrace trace-dtrace.dtrace-timestamp
 	rm -f trace-dtrace.h trace-dtrace.h-timestamp
diff --git a/Makefile.objs b/Makefile.objs
index 833158b..4f8b0ed 100644
--- a/Makefile.objs
+++ b/Makefile.objs
@@ -372,16 +372,18 @@ trace-dtrace.lo: trace-dtrace.dtrace
 	$(call quiet-command,$(LIBTOOL) --mode=compile --tag=CC dtrace -o $@ -G -s $<, "  lt GEN trace-dtrace.o")
 endif
 
-simpletrace.o: simpletrace.c $(GENERATED_HEADERS)
+trace/simple.o: trace/simple.c $(GENERATED_HEADERS)
 
 trace-obj-$(CONFIG_TRACE_DTRACE) += trace-dtrace.o
 ifneq ($(TRACE_BACKEND),dtrace)
 trace-obj-y = trace.o
 endif
 
-trace-obj-$(CONFIG_TRACE_SIMPLE) += simpletrace.o
+trace-nested-$(CONFIG_TRACE_SIMPLE) += simple.o
 trace-obj-$(CONFIG_TRACE_SIMPLE) += qemu-timer-common.o
 
+trace-obj-y += $(addprefix trace/, $(trace-nested-y))
+
 ######################################################################
 # smartcard
 
diff --git a/scripts/tracetool b/scripts/tracetool
index 2155a57..9ed4fae 100755
--- a/scripts/tracetool
+++ b/scripts/tracetool
@@ -158,7 +158,7 @@ linetoc_end_nop()
 linetoh_begin_simple()
 {
     cat <<EOF
-#include "simpletrace.h"
+#include "trace/simple.h"
 EOF
 
     simple_event_num=0
diff --git a/simpletrace.c b/simpletrace.c
deleted file mode 100644
index de355e9..0000000
--- a/simpletrace.c
+++ /dev/null
@@ -1,355 +0,0 @@
-/*
- * Simple trace backend
- *
- * Copyright IBM, Corp. 2010
- *
- * This work is licensed under the terms of the GNU GPL, version 2.  See
- * the COPYING file in the top-level directory.
- *
- */
-
-#include <stdlib.h>
-#include <stdint.h>
-#include <stdio.h>
-#include <time.h>
-#include <signal.h>
-#include <pthread.h>
-#include "qemu-timer.h"
-#include "trace.h"
-
-/** Trace file header event ID */
-#define HEADER_EVENT_ID (~(uint64_t)0) /* avoids conflicting with TraceEventIDs */
-
-/** Trace file magic number */
-#define HEADER_MAGIC 0xf2b177cb0aa429b4ULL
-
-/** Trace file version number, bump if format changes */
-#define HEADER_VERSION 0
-
-/** Records were dropped event ID */
-#define DROPPED_EVENT_ID (~(uint64_t)0 - 1)
-
-/** Trace record is valid */
-#define TRACE_RECORD_VALID ((uint64_t)1 << 63)
-
-/** Trace buffer entry */
-typedef struct {
-    uint64_t event;
-    uint64_t timestamp_ns;
-    uint64_t x1;
-    uint64_t x2;
-    uint64_t x3;
-    uint64_t x4;
-    uint64_t x5;
-    uint64_t x6;
-} TraceRecord;
-
-enum {
-    TRACE_BUF_LEN = 4096,
-    TRACE_BUF_FLUSH_THRESHOLD = TRACE_BUF_LEN / 4,
-};
-
-/*
- * Trace records are written out by a dedicated thread.  The thread waits for
- * records to become available, writes them out, and then waits again.
- */
-static pthread_mutex_t trace_lock = PTHREAD_MUTEX_INITIALIZER;
-static pthread_cond_t trace_available_cond = PTHREAD_COND_INITIALIZER;
-static pthread_cond_t trace_empty_cond = PTHREAD_COND_INITIALIZER;
-static bool trace_available;
-static bool trace_writeout_enabled;
-
-static TraceRecord trace_buf[TRACE_BUF_LEN];
-static unsigned int trace_idx;
-static FILE *trace_fp;
-static char *trace_file_name = NULL;
-
-/**
- * Read a trace record from the trace buffer
- *
- * @idx         Trace buffer index
- * @record      Trace record to fill
- *
- * Returns false if the record is not valid.
- */
-static bool get_trace_record(unsigned int idx, TraceRecord *record)
-{
-    if (!(trace_buf[idx].event & TRACE_RECORD_VALID)) {
-        return false;
-    }
-
-    __sync_synchronize(); /* read memory barrier before accessing record */
-
-    *record = trace_buf[idx];
-    record->event &= ~TRACE_RECORD_VALID;
-    return true;
-}
-
-/**
- * Kick writeout thread
- *
- * @wait        Whether to wait for writeout thread to complete
- */
-static void flush_trace_file(bool wait)
-{
-    pthread_mutex_lock(&trace_lock);
-    trace_available = true;
-    pthread_cond_signal(&trace_available_cond);
-
-    if (wait) {
-        pthread_cond_wait(&trace_empty_cond, &trace_lock);
-    }
-
-    pthread_mutex_unlock(&trace_lock);
-}
-
-static void wait_for_trace_records_available(void)
-{
-    pthread_mutex_lock(&trace_lock);
-    while (!(trace_available && trace_writeout_enabled)) {
-        pthread_cond_signal(&trace_empty_cond);
-        pthread_cond_wait(&trace_available_cond, &trace_lock);
-    }
-    trace_available = false;
-    pthread_mutex_unlock(&trace_lock);
-}
-
-static void *writeout_thread(void *opaque)
-{
-    TraceRecord record;
-    unsigned int writeout_idx = 0;
-    unsigned int num_available, idx;
-    size_t unused __attribute__ ((unused));
-
-    for (;;) {
-        wait_for_trace_records_available();
-
-        num_available = trace_idx - writeout_idx;
-        if (num_available > TRACE_BUF_LEN) {
-            record = (TraceRecord){
-                .event = DROPPED_EVENT_ID,
-                .x1 = num_available,
-            };
-            unused = fwrite(&record, sizeof(record), 1, trace_fp);
-            writeout_idx += num_available;
-        }
-
-        idx = writeout_idx % TRACE_BUF_LEN;
-        while (get_trace_record(idx, &record)) {
-            trace_buf[idx].event = 0; /* clear valid bit */
-            unused = fwrite(&record, sizeof(record), 1, trace_fp);
-            idx = ++writeout_idx % TRACE_BUF_LEN;
-        }
-
-        fflush(trace_fp);
-    }
-    return NULL;
-}
-
-static void trace(TraceEventID event, uint64_t x1, uint64_t x2, uint64_t x3,
-                  uint64_t x4, uint64_t x5, uint64_t x6)
-{
-    unsigned int idx;
-    uint64_t timestamp;
-
-    if (!trace_list[event].state) {
-        return;
-    }
-
-    timestamp = get_clock();
-
-    idx = __sync_fetch_and_add(&trace_idx, 1) % TRACE_BUF_LEN;
-    trace_buf[idx] = (TraceRecord){
-        .event = event,
-        .timestamp_ns = timestamp,
-        .x1 = x1,
-        .x2 = x2,
-        .x3 = x3,
-        .x4 = x4,
-        .x5 = x5,
-        .x6 = x6,
-    };
-    __sync_synchronize(); /* write barrier before marking as valid */
-    trace_buf[idx].event |= TRACE_RECORD_VALID;
-
-    if ((idx + 1) % TRACE_BUF_FLUSH_THRESHOLD == 0) {
-        flush_trace_file(false);
-    }
-}
-
-void trace0(TraceEventID event)
-{
-    trace(event, 0, 0, 0, 0, 0, 0);
-}
-
-void trace1(TraceEventID event, uint64_t x1)
-{
-    trace(event, x1, 0, 0, 0, 0, 0);
-}
-
-void trace2(TraceEventID event, uint64_t x1, uint64_t x2)
-{
-    trace(event, x1, x2, 0, 0, 0, 0);
-}
-
-void trace3(TraceEventID event, uint64_t x1, uint64_t x2, uint64_t x3)
-{
-    trace(event, x1, x2, x3, 0, 0, 0);
-}
-
-void trace4(TraceEventID event, uint64_t x1, uint64_t x2, uint64_t x3, uint64_t x4)
-{
-    trace(event, x1, x2, x3, x4, 0, 0);
-}
-
-void trace5(TraceEventID event, uint64_t x1, uint64_t x2, uint64_t x3, uint64_t x4, uint64_t x5)
-{
-    trace(event, x1, x2, x3, x4, x5, 0);
-}
-
-void trace6(TraceEventID event, uint64_t x1, uint64_t x2, uint64_t x3, uint64_t x4, uint64_t x5, uint64_t x6)
-{
-    trace(event, x1, x2, x3, x4, x5, x6);
-}
-
-void st_set_trace_file_enabled(bool enable)
-{
-    if (enable == !!trace_fp) {
-        return; /* no change */
-    }
-
-    /* Halt trace writeout */
-    flush_trace_file(true);
-    trace_writeout_enabled = false;
-    flush_trace_file(true);
-
-    if (enable) {
-        static const TraceRecord header = {
-            .event = HEADER_EVENT_ID,
-            .timestamp_ns = HEADER_MAGIC,
-            .x1 = HEADER_VERSION,
-        };
-
-        trace_fp = fopen(trace_file_name, "w");
-        if (!trace_fp) {
-            return;
-        }
-
-        if (fwrite(&header, sizeof header, 1, trace_fp) != 1) {
-            fclose(trace_fp);
-            trace_fp = NULL;
-            return;
-        }
-
-        /* Resume trace writeout */
-        trace_writeout_enabled = true;
-        flush_trace_file(false);
-    } else {
-        fclose(trace_fp);
-        trace_fp = NULL;
-    }
-}
-
-/**
- * Set the name of a trace file
- *
- * @file        The trace file name or NULL for the default name-<pid> set at
- *              config time
- */
-bool st_set_trace_file(const char *file)
-{
-    st_set_trace_file_enabled(false);
-
-    free(trace_file_name);
-
-    if (!file) {
-        if (asprintf(&trace_file_name, CONFIG_TRACE_FILE, getpid()) < 0) {
-            trace_file_name = NULL;
-            return false;
-        }
-    } else {
-        if (asprintf(&trace_file_name, "%s", file) < 0) {
-            trace_file_name = NULL;
-            return false;
-        }
-    }
-
-    st_set_trace_file_enabled(true);
-    return true;
-}
-
-void st_print_trace_file_status(FILE *stream, int (*stream_printf)(FILE *stream, const char *fmt, ...))
-{
-    stream_printf(stream, "Trace file \"%s\" %s.\n",
-                  trace_file_name, trace_fp ? "on" : "off");
-}
-
-void st_print_trace(FILE *stream, int (*stream_printf)(FILE *stream, const char *fmt, ...))
-{
-    unsigned int i;
-
-    for (i = 0; i < TRACE_BUF_LEN; i++) {
-        TraceRecord record;
-
-        if (!get_trace_record(i, &record)) {
-            continue;
-        }
-        stream_printf(stream, "Event %" PRIu64 " : %" PRIx64 " %" PRIx64
-                      " %" PRIx64 " %" PRIx64 " %" PRIx64 " %" PRIx64 "\n",
-                      record.event, record.x1, record.x2,
-                      record.x3, record.x4, record.x5,
-                      record.x6);
-    }
-}
-
-void st_print_trace_events(FILE *stream, int (*stream_printf)(FILE *stream, const char *fmt, ...))
-{
-    unsigned int i;
-
-    for (i = 0; i < NR_TRACE_EVENTS; i++) {
-        stream_printf(stream, "%s [Event ID %u] : state %u\n",
-                      trace_list[i].tp_name, i, trace_list[i].state);
-    }
-}
-
-bool st_change_trace_event_state(const char *name, bool enabled)
-{
-    unsigned int i;
-
-    for (i = 0; i < NR_TRACE_EVENTS; i++) {
-        if (!strcmp(trace_list[i].tp_name, name)) {
-            trace_list[i].state = enabled;
-            return true;
-        }
-    }
-    return false;
-}
-
-void st_flush_trace_buffer(void)
-{
-    flush_trace_file(true);
-}
-
-bool st_init(const char *file)
-{
-    pthread_t thread;
-    pthread_attr_t attr;
-    sigset_t set, oldset;
-    int ret;
-
-    pthread_attr_init(&attr);
-    pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
-
-    sigfillset(&set);
-    pthread_sigmask(SIG_SETMASK, &set, &oldset);
-    ret = pthread_create(&thread, &attr, writeout_thread, NULL);
-    pthread_sigmask(SIG_SETMASK, &oldset, NULL);
-
-    if (ret != 0) {
-        return false;
-    }
-
-    atexit(st_flush_trace_buffer);
-    st_set_trace_file(file);
-    return true;
-}
diff --git a/simpletrace.h b/simpletrace.h
deleted file mode 100644
index 507dd87..0000000
--- a/simpletrace.h
+++ /dev/null
@@ -1,48 +0,0 @@
-/*
- * Simple trace backend
- *
- * Copyright IBM, Corp. 2010
- *
- * This work is licensed under the terms of the GNU GPL, version 2.  See
- * the COPYING file in the top-level directory.
- *
- */
-
-#ifndef SIMPLETRACE_H
-#define SIMPLETRACE_H
-
-#include <stdint.h>
-#include <stdbool.h>
-#include <stdio.h>
-
-#ifdef CONFIG_TRACE_SIMPLE
-typedef uint64_t TraceEventID;
-
-typedef struct {
-    const char *tp_name;
-    bool state;
-} TraceEvent;
-
-void trace0(TraceEventID event);
-void trace1(TraceEventID event, uint64_t x1);
-void trace2(TraceEventID event, uint64_t x1, uint64_t x2);
-void trace3(TraceEventID event, uint64_t x1, uint64_t x2, uint64_t x3);
-void trace4(TraceEventID event, uint64_t x1, uint64_t x2, uint64_t x3, uint64_t x4);
-void trace5(TraceEventID event, uint64_t x1, uint64_t x2, uint64_t x3, uint64_t x4, uint64_t x5);
-void trace6(TraceEventID event, uint64_t x1, uint64_t x2, uint64_t x3, uint64_t x4, uint64_t x5, uint64_t x6);
-void st_print_trace(FILE *stream, fprintf_function stream_printf);
-void st_print_trace_events(FILE *stream, fprintf_function stream_printf);
-bool st_change_trace_event_state(const char *tname, bool tstate);
-void st_print_trace_file_status(FILE *stream, fprintf_function stream_printf);
-void st_set_trace_file_enabled(bool enable);
-bool st_set_trace_file(const char *file);
-void st_flush_trace_buffer(void);
-bool st_init(const char *file);
-#else
-static inline bool st_init(const char *file)
-{
-    return true;
-}
-#endif /* !CONFIG_TRACE_SIMPLE */
-
-#endif /* SIMPLETRACE_H */
diff --git a/trace/simple.c b/trace/simple.c
new file mode 100644
index 0000000..de355e9
--- /dev/null
+++ b/trace/simple.c
@@ -0,0 +1,355 @@
+/*
+ * Simple trace backend
+ *
+ * Copyright IBM, Corp. 2010
+ *
+ * This work is licensed under the terms of the GNU GPL, version 2.  See
+ * the COPYING file in the top-level directory.
+ *
+ */
+
+#include <stdlib.h>
+#include <stdint.h>
+#include <stdio.h>
+#include <time.h>
+#include <signal.h>
+#include <pthread.h>
+#include "qemu-timer.h"
+#include "trace.h"
+
+/** Trace file header event ID */
+#define HEADER_EVENT_ID (~(uint64_t)0) /* avoids conflicting with TraceEventIDs */
+
+/** Trace file magic number */
+#define HEADER_MAGIC 0xf2b177cb0aa429b4ULL
+
+/** Trace file version number, bump if format changes */
+#define HEADER_VERSION 0
+
+/** Records were dropped event ID */
+#define DROPPED_EVENT_ID (~(uint64_t)0 - 1)
+
+/** Trace record is valid */
+#define TRACE_RECORD_VALID ((uint64_t)1 << 63)
+
+/** Trace buffer entry */
+typedef struct {
+    uint64_t event;
+    uint64_t timestamp_ns;
+    uint64_t x1;
+    uint64_t x2;
+    uint64_t x3;
+    uint64_t x4;
+    uint64_t x5;
+    uint64_t x6;
+} TraceRecord;
+
+enum {
+    TRACE_BUF_LEN = 4096,
+    TRACE_BUF_FLUSH_THRESHOLD = TRACE_BUF_LEN / 4,
+};
+
+/*
+ * Trace records are written out by a dedicated thread.  The thread waits for
+ * records to become available, writes them out, and then waits again.
+ */
+static pthread_mutex_t trace_lock = PTHREAD_MUTEX_INITIALIZER;
+static pthread_cond_t trace_available_cond = PTHREAD_COND_INITIALIZER;
+static pthread_cond_t trace_empty_cond = PTHREAD_COND_INITIALIZER;
+static bool trace_available;
+static bool trace_writeout_enabled;
+
+static TraceRecord trace_buf[TRACE_BUF_LEN];
+static unsigned int trace_idx;
+static FILE *trace_fp;
+static char *trace_file_name = NULL;
+
+/**
+ * Read a trace record from the trace buffer
+ *
+ * @idx         Trace buffer index
+ * @record      Trace record to fill
+ *
+ * Returns false if the record is not valid.
+ */
+static bool get_trace_record(unsigned int idx, TraceRecord *record)
+{
+    if (!(trace_buf[idx].event & TRACE_RECORD_VALID)) {
+        return false;
+    }
+
+    __sync_synchronize(); /* read memory barrier before accessing record */
+
+    *record = trace_buf[idx];
+    record->event &= ~TRACE_RECORD_VALID;
+    return true;
+}
+
+/**
+ * Kick writeout thread
+ *
+ * @wait        Whether to wait for writeout thread to complete
+ */
+static void flush_trace_file(bool wait)
+{
+    pthread_mutex_lock(&trace_lock);
+    trace_available = true;
+    pthread_cond_signal(&trace_available_cond);
+
+    if (wait) {
+        pthread_cond_wait(&trace_empty_cond, &trace_lock);
+    }
+
+    pthread_mutex_unlock(&trace_lock);
+}
+
+static void wait_for_trace_records_available(void)
+{
+    pthread_mutex_lock(&trace_lock);
+    while (!(trace_available && trace_writeout_enabled)) {
+        pthread_cond_signal(&trace_empty_cond);
+        pthread_cond_wait(&trace_available_cond, &trace_lock);
+    }
+    trace_available = false;
+    pthread_mutex_unlock(&trace_lock);
+}
+
+static void *writeout_thread(void *opaque)
+{
+    TraceRecord record;
+    unsigned int writeout_idx = 0;
+    unsigned int num_available, idx;
+    size_t unused __attribute__ ((unused));
+
+    for (;;) {
+        wait_for_trace_records_available();
+
+        num_available = trace_idx - writeout_idx;
+        if (num_available > TRACE_BUF_LEN) {
+            record = (TraceRecord){
+                .event = DROPPED_EVENT_ID,
+                .x1 = num_available,
+            };
+            unused = fwrite(&record, sizeof(record), 1, trace_fp);
+            writeout_idx += num_available;
+        }
+
+        idx = writeout_idx % TRACE_BUF_LEN;
+        while (get_trace_record(idx, &record)) {
+            trace_buf[idx].event = 0; /* clear valid bit */
+            unused = fwrite(&record, sizeof(record), 1, trace_fp);
+            idx = ++writeout_idx % TRACE_BUF_LEN;
+        }
+
+        fflush(trace_fp);
+    }
+    return NULL;
+}
+
+static void trace(TraceEventID event, uint64_t x1, uint64_t x2, uint64_t x3,
+                  uint64_t x4, uint64_t x5, uint64_t x6)
+{
+    unsigned int idx;
+    uint64_t timestamp;
+
+    if (!trace_list[event].state) {
+        return;
+    }
+
+    timestamp = get_clock();
+
+    idx = __sync_fetch_and_add(&trace_idx, 1) % TRACE_BUF_LEN;
+    trace_buf[idx] = (TraceRecord){
+        .event = event,
+        .timestamp_ns = timestamp,
+        .x1 = x1,
+        .x2 = x2,
+        .x3 = x3,
+        .x4 = x4,
+        .x5 = x5,
+        .x6 = x6,
+    };
+    __sync_synchronize(); /* write barrier before marking as valid */
+    trace_buf[idx].event |= TRACE_RECORD_VALID;
+
+    if ((idx + 1) % TRACE_BUF_FLUSH_THRESHOLD == 0) {
+        flush_trace_file(false);
+    }
+}
+
+void trace0(TraceEventID event)
+{
+    trace(event, 0, 0, 0, 0, 0, 0);
+}
+
+void trace1(TraceEventID event, uint64_t x1)
+{
+    trace(event, x1, 0, 0, 0, 0, 0);
+}
+
+void trace2(TraceEventID event, uint64_t x1, uint64_t x2)
+{
+    trace(event, x1, x2, 0, 0, 0, 0);
+}
+
+void trace3(TraceEventID event, uint64_t x1, uint64_t x2, uint64_t x3)
+{
+    trace(event, x1, x2, x3, 0, 0, 0);
+}
+
+void trace4(TraceEventID event, uint64_t x1, uint64_t x2, uint64_t x3, uint64_t x4)
+{
+    trace(event, x1, x2, x3, x4, 0, 0);
+}
+
+void trace5(TraceEventID event, uint64_t x1, uint64_t x2, uint64_t x3, uint64_t x4, uint64_t x5)
+{
+    trace(event, x1, x2, x3, x4, x5, 0);
+}
+
+void trace6(TraceEventID event, uint64_t x1, uint64_t x2, uint64_t x3, uint64_t x4, uint64_t x5, uint64_t x6)
+{
+    trace(event, x1, x2, x3, x4, x5, x6);
+}
+
+void st_set_trace_file_enabled(bool enable)
+{
+    if (enable == !!trace_fp) {
+        return; /* no change */
+    }
+
+    /* Halt trace writeout */
+    flush_trace_file(true);
+    trace_writeout_enabled = false;
+    flush_trace_file(true);
+
+    if (enable) {
+        static const TraceRecord header = {
+            .event = HEADER_EVENT_ID,
+            .timestamp_ns = HEADER_MAGIC,
+            .x1 = HEADER_VERSION,
+        };
+
+        trace_fp = fopen(trace_file_name, "w");
+        if (!trace_fp) {
+            return;
+        }
+
+        if (fwrite(&header, sizeof header, 1, trace_fp) != 1) {
+            fclose(trace_fp);
+            trace_fp = NULL;
+            return;
+        }
+
+        /* Resume trace writeout */
+        trace_writeout_enabled = true;
+        flush_trace_file(false);
+    } else {
+        fclose(trace_fp);
+        trace_fp = NULL;
+    }
+}
+
+/**
+ * Set the name of a trace file
+ *
+ * @file        The trace file name or NULL for the default name-<pid> set at
+ *              config time
+ */
+bool st_set_trace_file(const char *file)
+{
+    st_set_trace_file_enabled(false);
+
+    free(trace_file_name);
+
+    if (!file) {
+        if (asprintf(&trace_file_name, CONFIG_TRACE_FILE, getpid()) < 0) {
+            trace_file_name = NULL;
+            return false;
+        }
+    } else {
+        if (asprintf(&trace_file_name, "%s", file) < 0) {
+            trace_file_name = NULL;
+            return false;
+        }
+    }
+
+    st_set_trace_file_enabled(true);
+    return true;
+}
+
+void st_print_trace_file_status(FILE *stream, int (*stream_printf)(FILE *stream, const char *fmt, ...))
+{
+    stream_printf(stream, "Trace file \"%s\" %s.\n",
+                  trace_file_name, trace_fp ? "on" : "off");
+}
+
+void st_print_trace(FILE *stream, int (*stream_printf)(FILE *stream, const char *fmt, ...))
+{
+    unsigned int i;
+
+    for (i = 0; i < TRACE_BUF_LEN; i++) {
+        TraceRecord record;
+
+        if (!get_trace_record(i, &record)) {
+            continue;
+        }
+        stream_printf(stream, "Event %" PRIu64 " : %" PRIx64 " %" PRIx64
+                      " %" PRIx64 " %" PRIx64 " %" PRIx64 " %" PRIx64 "\n",
+                      record.event, record.x1, record.x2,
+                      record.x3, record.x4, record.x5,
+                      record.x6);
+    }
+}
+
+void st_print_trace_events(FILE *stream, int (*stream_printf)(FILE *stream, const char *fmt, ...))
+{
+    unsigned int i;
+
+    for (i = 0; i < NR_TRACE_EVENTS; i++) {
+        stream_printf(stream, "%s [Event ID %u] : state %u\n",
+                      trace_list[i].tp_name, i, trace_list[i].state);
+    }
+}
+
+bool st_change_trace_event_state(const char *name, bool enabled)
+{
+    unsigned int i;
+
+    for (i = 0; i < NR_TRACE_EVENTS; i++) {
+        if (!strcmp(trace_list[i].tp_name, name)) {
+            trace_list[i].state = enabled;
+            return true;
+        }
+    }
+    return false;
+}
+
+void st_flush_trace_buffer(void)
+{
+    flush_trace_file(true);
+}
+
+bool st_init(const char *file)
+{
+    pthread_t thread;
+    pthread_attr_t attr;
+    sigset_t set, oldset;
+    int ret;
+
+    pthread_attr_init(&attr);
+    pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
+
+    sigfillset(&set);
+    pthread_sigmask(SIG_SETMASK, &set, &oldset);
+    ret = pthread_create(&thread, &attr, writeout_thread, NULL);
+    pthread_sigmask(SIG_SETMASK, &oldset, NULL);
+
+    if (ret != 0) {
+        return false;
+    }
+
+    atexit(st_flush_trace_buffer);
+    st_set_trace_file(file);
+    return true;
+}
diff --git a/trace/simple.h b/trace/simple.h
new file mode 100644
index 0000000..77633ab
--- /dev/null
+++ b/trace/simple.h
@@ -0,0 +1,48 @@
+/*
+ * Simple trace backend
+ *
+ * Copyright IBM, Corp. 2010
+ *
+ * This work is licensed under the terms of the GNU GPL, version 2.  See
+ * the COPYING file in the top-level directory.
+ *
+ */
+
+#ifndef TRACE_SIMPLE_H
+#define TRACE_SIMPLE_H
+
+#include <stdint.h>
+#include <stdbool.h>
+#include <stdio.h>
+
+#ifdef CONFIG_TRACE_SIMPLE
+typedef uint64_t TraceEventID;
+
+typedef struct {
+    const char *tp_name;
+    bool state;
+} TraceEvent;
+
+void trace0(TraceEventID event);
+void trace1(TraceEventID event, uint64_t x1);
+void trace2(TraceEventID event, uint64_t x1, uint64_t x2);
+void trace3(TraceEventID event, uint64_t x1, uint64_t x2, uint64_t x3);
+void trace4(TraceEventID event, uint64_t x1, uint64_t x2, uint64_t x3, uint64_t x4);
+void trace5(TraceEventID event, uint64_t x1, uint64_t x2, uint64_t x3, uint64_t x4, uint64_t x5);
+void trace6(TraceEventID event, uint64_t x1, uint64_t x2, uint64_t x3, uint64_t x4, uint64_t x5, uint64_t x6);
+void st_print_trace(FILE *stream, fprintf_function stream_printf);
+void st_print_trace_events(FILE *stream, fprintf_function stream_printf);
+bool st_change_trace_event_state(const char *tname, bool tstate);
+void st_print_trace_file_status(FILE *stream, fprintf_function stream_printf);
+void st_set_trace_file_enabled(bool enable);
+bool st_set_trace_file(const char *file);
+void st_flush_trace_buffer(void);
+bool st_init(const char *file);
+#else
+static inline bool st_init(const char *file)
+{
+    return true;
+}
+#endif /* !CONFIG_TRACE_SIMPLE */
+
+#endif /* TRACE_SIMPLE_H */
diff --git a/vl.c b/vl.c
index 8c7aaaa..145d738 100644
--- a/vl.c
+++ b/vl.c
@@ -156,7 +156,7 @@ int main(int argc, char **argv)
 #include "slirp/libslirp.h"
 
 #include "trace.h"
-#include "simpletrace.h"
+#include "trace/simple.h"
 #include "qemu-queue.h"
 #include "cpus.h"
 #include "arch_init.h"
commit 09001ee7b27b9b5f049362efc427d03e2186a431
Author: Lluís <xscript at gmx.net>
Date:   Wed Aug 31 20:30:50 2011 +0200

    trace: [make] replace 'ifeq' with values in CONFIG_TRACE_*
    
    Signed-off-by: Lluís Vilanova <vilanova at ac.upc.edu>

diff --git a/Makefile.objs b/Makefile.objs
index 44d7238..833158b 100644
--- a/Makefile.objs
+++ b/Makefile.objs
@@ -374,16 +374,14 @@ endif
 
 simpletrace.o: simpletrace.c $(GENERATED_HEADERS)
 
-ifeq ($(TRACE_BACKEND),dtrace)
-trace-obj-y = trace-dtrace.o
-else
+trace-obj-$(CONFIG_TRACE_DTRACE) += trace-dtrace.o
+ifneq ($(TRACE_BACKEND),dtrace)
 trace-obj-y = trace.o
-ifeq ($(TRACE_BACKEND),simple)
-trace-obj-y += simpletrace.o
-trace-obj-y += qemu-timer-common.o
-endif
 endif
 
+trace-obj-$(CONFIG_TRACE_SIMPLE) += simpletrace.o
+trace-obj-$(CONFIG_TRACE_SIMPLE) += qemu-timer-common.o
+
 ######################################################################
 # smartcard
 
commit 6d8a764e0fcdde8e3a62fb3fc5911b338c8893ca
Author: Lluís <xscript at gmx.net>
Date:   Wed Aug 31 20:30:43 2011 +0200

    trace: [configure] rename CONFIG_*_TRACE into CONFIG_TRACE_*
    
    Provides a more hierarchical view of the variable domain.
    
    Also adds the CONFIG_TRACE_* variables for all backends.
    
    [Stefan added missing 'test' in stap if statement]
    
    Signed-off-by: Lluís Vilanova <vilanova at ac.upc.edu>
    Signed-off-by: Stefan Hajnoczi <stefanha at linux.vnet.ibm.com>

diff --git a/Makefile.target b/Makefile.target
index 62ddfc9..25c16d7 100644
--- a/Makefile.target
+++ b/Makefile.target
@@ -44,7 +44,7 @@ endif
 config-target.h: config-target.h-timestamp
 config-target.h-timestamp: config-target.mak
 
-ifdef CONFIG_SYSTEMTAP_TRACE
+ifdef CONFIG_TRACE_SYSTEMTAP
 stap: $(QEMU_PROG).stp
 
 ifdef CONFIG_USER_ONLY
@@ -414,7 +414,7 @@ clean:
 	rm -f *.o *.a *~ $(PROGS) nwfpe/*.o fpu/*.o
 	rm -f *.d */*.d tcg/*.o ide/*.o 9pfs/*.o
 	rm -f hmp-commands.h qmp-commands.h gdbstub-xml.c
-ifdef CONFIG_SYSTEMTAP_TRACE
+ifdef CONFIG_TRACE_SYSTEMTAP
 	rm -f *.stp
 endif
 
@@ -425,7 +425,7 @@ ifneq ($(STRIP),)
 	$(STRIP) $(patsubst %,"$(DESTDIR)$(bindir)/%",$(PROGS))
 endif
 endif
-ifdef CONFIG_SYSTEMTAP_TRACE
+ifdef CONFIG_TRACE_SYSTEMTAP
 	$(INSTALL_DIR) "$(DESTDIR)$(datadir)/../systemtap/tapset"
 	$(INSTALL_DATA) $(QEMU_PROG).stp "$(DESTDIR)$(datadir)/../systemtap/tapset"
 endif
diff --git a/configure b/configure
index 1340c33..ebf14ee 100755
--- a/configure
+++ b/configure
@@ -3065,15 +3065,25 @@ bsd)
 esac
 
 echo "TRACE_BACKEND=$trace_backend" >> $config_host_mak
-if test "$trace_backend" = "simple"; then
-  echo "CONFIG_SIMPLE_TRACE=y" >> $config_host_mak
+if test "$trace_backend" = "nop"; then
+  echo "CONFIG_TRACE_NOP=y" >> $config_host_mak
 fi
-# Set the appropriate trace file.
 if test "$trace_backend" = "simple"; then
+  echo "CONFIG_TRACE_SIMPLE=y" >> $config_host_mak
+  # Set the appropriate trace file.
   trace_file="\"$trace_file-\" FMT_pid"
 fi
-if test "$trace_backend" = "dtrace" -a "$trace_backend_stap" = "yes" ; then
-  echo "CONFIG_SYSTEMTAP_TRACE=y" >> $config_host_mak
+if test "$trace_backend" = "stderr"; then
+  echo "CONFIG_TRACE_STDERR=y" >> $config_host_mak
+fi
+if test "$trace_backend" = "ust"; then
+  echo "CONFIG_TRACE_UST=y" >> $config_host_mak
+fi
+if test "$trace_backend" = "dtrace"; then
+  echo "CONFIG_TRACE_DTRACE=y" >> $config_host_mak
+  if test "$trace_backend_stap" = "yes" ; then
+    echo "CONFIG_TRACE_SYSTEMTAP=y" >> $config_host_mak
+  fi
 fi
 echo "CONFIG_TRACE_FILE=$trace_file" >> $config_host_mak
 
diff --git a/hmp-commands.hx b/hmp-commands.hx
index 0ccfb28..ad4174f 100644
--- a/hmp-commands.hx
+++ b/hmp-commands.hx
@@ -180,7 +180,7 @@ STEXI
 Output logs to @var{filename}.
 ETEXI
 
-#ifdef CONFIG_SIMPLE_TRACE
+#ifdef CONFIG_TRACE_SIMPLE
     {
         .name       = "trace-event",
         .args_type  = "name:s,option:b",
@@ -1354,7 +1354,7 @@ show roms
 @end table
 ETEXI
 
-#ifdef CONFIG_SIMPLE_TRACE
+#ifdef CONFIG_TRACE_SIMPLE
 STEXI
 @item info trace
 show contents of trace buffer
diff --git a/monitor.c b/monitor.c
index 04f465a..935aa33 100644
--- a/monitor.c
+++ b/monitor.c
@@ -57,7 +57,7 @@
 #include "json-parser.h"
 #include "osdep.h"
 #include "cpu.h"
-#ifdef CONFIG_SIMPLE_TRACE
+#ifdef CONFIG_TRACE_SIMPLE
 #include "trace.h"
 #endif
 #include "ui/qemu-spice.h"
@@ -592,7 +592,7 @@ static void do_help_cmd(Monitor *mon, const QDict *qdict)
     help_cmd(mon, qdict_get_try_str(qdict, "name"));
 }
 
-#ifdef CONFIG_SIMPLE_TRACE
+#ifdef CONFIG_TRACE_SIMPLE
 static void do_change_trace_event_state(Monitor *mon, const QDict *qdict)
 {
     const char *tp_name = qdict_get_str(qdict, "name");
@@ -996,7 +996,7 @@ static void do_info_cpu_stats(Monitor *mon)
 }
 #endif
 
-#if defined(CONFIG_SIMPLE_TRACE)
+#if defined(CONFIG_TRACE_SIMPLE)
 static void do_info_trace(Monitor *mon)
 {
     st_print_trace((FILE *)mon, &monitor_fprintf);
@@ -3135,7 +3135,7 @@ static const mon_cmd_t info_cmds[] = {
         .help       = "show roms",
         .mhandler.info = do_info_roms,
     },
-#if defined(CONFIG_SIMPLE_TRACE)
+#if defined(CONFIG_TRACE_SIMPLE)
     {
         .name       = "trace",
         .args_type  = "",
diff --git a/qemu-config.c b/qemu-config.c
index 139e077..b64edc9 100644
--- a/qemu-config.c
+++ b/qemu-config.c
@@ -303,7 +303,7 @@ static QemuOptsList qemu_mon_opts = {
     },
 };
 
-#ifdef CONFIG_SIMPLE_TRACE
+#ifdef CONFIG_TRACE_SIMPLE
 static QemuOptsList qemu_trace_opts = {
     .name = "trace",
     .implied_opt_name = "trace",
@@ -517,7 +517,7 @@ static QemuOptsList *vm_config_groups[32] = {
     &qemu_global_opts,
     &qemu_mon_opts,
     &qemu_cpudef_opts,
-#ifdef CONFIG_SIMPLE_TRACE
+#ifdef CONFIG_TRACE_SIMPLE
     &qemu_trace_opts,
 #endif
     &qemu_option_rom_opts,
diff --git a/qemu-options.hx b/qemu-options.hx
index 35d95d1..dcb00b7 100644
--- a/qemu-options.hx
+++ b/qemu-options.hx
@@ -2436,7 +2436,7 @@ Normally QEMU loads a configuration file from @var{sysconfdir}/qemu.conf and
 @var{sysconfdir}/target- at var{ARCH}.conf on startup.  The @code{-nodefconfig}
 option will prevent QEMU from loading these configuration files at startup.
 ETEXI
-#ifdef CONFIG_SIMPLE_TRACE
+#ifdef CONFIG_TRACE_SIMPLE
 DEF("trace", HAS_ARG, QEMU_OPTION_trace,
     "-trace\n"
     "                Specify a trace file to log traces to\n",
diff --git a/simpletrace.h b/simpletrace.h
index 8d893bd..507dd87 100644
--- a/simpletrace.h
+++ b/simpletrace.h
@@ -15,7 +15,7 @@
 #include <stdbool.h>
 #include <stdio.h>
 
-#ifdef CONFIG_SIMPLE_TRACE
+#ifdef CONFIG_TRACE_SIMPLE
 typedef uint64_t TraceEventID;
 
 typedef struct {
@@ -43,6 +43,6 @@ static inline bool st_init(const char *file)
 {
     return true;
 }
-#endif /* !CONFIG_SIMPLE_TRACE */
+#endif /* !CONFIG_TRACE_SIMPLE */
 
 #endif /* SIMPLETRACE_H */
diff --git a/tests/test_path.c b/tests/test_path.c
index 234ed97..7265a94 100644
--- a/tests/test_path.c
+++ b/tests/test_path.c
@@ -4,7 +4,7 @@
 #include "../cutils.c"
 #include "../path.c"
 #include "../trace.c"
-#ifdef CONFIG_SIMPLE_TRACE
+#ifdef CONFIG_TRACE_SIMPLE
 #include "../simpletrace.c"
 #endif
 
diff --git a/vl.c b/vl.c
index 9cd67a3..8c7aaaa 100644
--- a/vl.c
+++ b/vl.c
@@ -2928,7 +2928,7 @@ int main(int argc, char **argv, char **envp)
                 }
                 xen_mode = XEN_ATTACH;
                 break;
-#ifdef CONFIG_SIMPLE_TRACE
+#ifdef CONFIG_TRACE_SIMPLE
             case QEMU_OPTION_trace:
                 opts = qemu_opts_parse(qemu_find_opts("trace"), optarg, 0);
                 if (opts) {
commit 51010317dd74a7d6ad30dcc73478924aa4f590c5
Author: Lluís <xscript at gmx.net>
Date:   Wed Aug 31 20:30:37 2011 +0200

    build: [simple] Include qemu-timer-common.o in trace-obj-y
    
    Helper programs like qemu-ga use tracing primitives, but qemu-timer-common.o
    (also used by simpletrace.o) is not necessarily included in the linkage line.
    
    Signed-off-by: Lluís Vilanova <vilanova at ac.upc.edu>

diff --git a/Makefile.objs b/Makefile.objs
index d1f3e5d..44d7238 100644
--- a/Makefile.objs
+++ b/Makefile.objs
@@ -380,7 +380,7 @@ else
 trace-obj-y = trace.o
 ifeq ($(TRACE_BACKEND),simple)
 trace-obj-y += simpletrace.o
-user-obj-y += qemu-timer-common.o
+trace-obj-y += qemu-timer-common.o
 endif
 endif
 
commit e03b41d47708744669aaa51e781021c3dc380198
Author: Lluís <xscript at gmx.net>
Date:   Wed Aug 31 20:30:30 2011 +0200

    build: Fix linkage of QEMU_PROG
    
    Using '$^' to establish the files to link with will remove any repeated entries
    in the list of dependencies.
    
    Signed-off-by: Lluís Vilanova <vilanova at ac.upc.edu>

diff --git a/Makefile.target b/Makefile.target
index 07af4d4..62ddfc9 100644
--- a/Makefile.target
+++ b/Makefile.target
@@ -398,7 +398,7 @@ obj-y += $(addprefix ../, $(trace-obj-y))
 obj-$(CONFIG_GDBSTUB_XML) += gdbstub-xml.o
 
 $(QEMU_PROG): $(obj-y) $(obj-$(TARGET_BASE_ARCH)-y)
-	$(call LINK,$(obj-y) $(obj-$(TARGET_BASE_ARCH)-y))
+	$(call LINK,$^)
 
 
 gdbstub-xml.c: $(TARGET_XML_FILES) $(SRC_PATH)/scripts/feature_to_c.sh
commit bdc76462aca464f11286ddcf6d5b748b4547267e
Author: Peter Maydell <peter.maydell at linaro.org>
Date:   Tue Aug 30 18:36:56 2011 +0100

    tusb6010: Convert to qdev
    
    Convert the tusb6010 to qdev.
    
    Signed-off-by: Juha Riihimäki <juha.riihimaki at nokia.com>
    [Riku Voipio: Fixes and restructuring patchset]
    Signed-off-by: Riku Voipio <riku.voipio at iki.fi>
    [Peter Maydell: More fixes and cleanups for upstream submission]
    Signed-off-by:  Peter Maydell <peter.maydell at linaro.org>
    Signed-off-by: Edgar E. Iglesias <edgar.iglesias at gmail.com>

diff --git a/hw/nseries.c b/hw/nseries.c
index f7ace99..af287dd 100644
--- a/hw/nseries.c
+++ b/hw/nseries.c
@@ -32,7 +32,6 @@
 #include "bt.h"
 #include "loader.h"
 #include "blockdev.h"
-#include "tusb6010.h"
 #include "sysbus.h"
 
 /* Nokia N8x0 support */
@@ -50,7 +49,7 @@ struct n800_s {
     int keymap[0x80];
     DeviceState *kbd;
 
-    TUSBState *usb;
+    DeviceState *usb;
     void *retu;
     void *tahvo;
     DeviceState *nand;
@@ -765,25 +764,21 @@ static void n8x0_uart_setup(struct n800_s *s)
     omap_uart_attach(s->cpu->uart[BT_UART], radio);
 }
 
-static void n8x0_usb_power_cb(void *opaque, int line, int level)
-{
-    struct n800_s *s = opaque;
-
-    tusb6010_power(s->usb, level);
-}
-
 static void n8x0_usb_setup(struct n800_s *s)
 {
-    qemu_irq tusb_irq = qdev_get_gpio_in(s->cpu->gpio, N8X0_TUSB_INT_GPIO);
-    qemu_irq tusb_pwr = qemu_allocate_irqs(n8x0_usb_power_cb, s, 1)[0];
-    TUSBState *tusb = tusb6010_init(tusb_irq);
-
+    SysBusDevice *dev;
+    s->usb = qdev_create(NULL, "tusb6010");
+    dev = sysbus_from_qdev(s->usb);
+    qdev_init_nofail(s->usb);
+    sysbus_connect_irq(dev, 0,
+                       qdev_get_gpio_in(s->cpu->gpio, N8X0_TUSB_INT_GPIO));
     /* Using the NOR interface */
-    omap_gpmc_attach(s->cpu->gpmc, N8X0_USB_ASYNC_CS, tusb6010_async_io(tusb));
-    omap_gpmc_attach(s->cpu->gpmc, N8X0_USB_SYNC_CS, tusb6010_sync_io(tusb));
-
-    s->usb = tusb;
-    qdev_connect_gpio_out(s->cpu->gpio, N8X0_TUSB_ENABLE_GPIO, tusb_pwr);
+    omap_gpmc_attach(s->cpu->gpmc, N8X0_USB_ASYNC_CS,
+                     sysbus_mmio_get_region(dev, 0));
+    omap_gpmc_attach(s->cpu->gpmc, N8X0_USB_SYNC_CS,
+                     sysbus_mmio_get_region(dev, 1));
+    qdev_connect_gpio_out(s->cpu->gpio, N8X0_TUSB_ENABLE_GPIO,
+                          qdev_get_gpio_in(s->usb, 0)); /* tusb_pwr */
 }
 
 /* Setup done before the main bootloader starts by some early setup code
diff --git a/hw/tusb6010.c b/hw/tusb6010.c
index b2bf359..de6ffc6 100644
--- a/hw/tusb6010.c
+++ b/hw/tusb6010.c
@@ -23,9 +23,11 @@
 #include "usb.h"
 #include "omap.h"
 #include "irq.h"
-#include "tusb6010.h"
+#include "devices.h"
+#include "sysbus.h"
 
-struct TUSBState {
+typedef struct TUSBState {
+    SysBusDevice busdev;
     MemoryRegion iomem[2];
     qemu_irq irq;
     MUSBState *musb;
@@ -59,7 +61,7 @@ struct TUSBState {
     uint32_t pullup[2];
     uint32_t control_config;
     uint32_t otg_timer_val;
-};
+} TUSBState;
 
 #define TUSB_DEVCLOCK			60000000	/* 60 MHz */
 
@@ -234,16 +236,6 @@ struct TUSBState {
 #define TUSB_EP_CONFIG_XFR_SIZE(v)	((v) & 0x7fffffff)
 #define TUSB_PROD_TEST_RESET_VAL	0xa596
 
-MemoryRegion *tusb6010_sync_io(TUSBState *s)
-{
-    return &s->iomem[0];
-}
-
-MemoryRegion *tusb6010_async_io(TUSBState *s)
-{
-    return &s->iomem[1];
-}
-
 static void tusb_intr_update(TUSBState *s)
 {
     if (s->control_config & TUSB_INT_CTRL_CONF_INT_POLARITY)
@@ -723,9 +715,33 @@ static void tusb_musb_core_intr(void *opaque, int source, int level)
     }
 }
 
-TUSBState *tusb6010_init(qemu_irq intr)
+static void tusb6010_power(TUSBState *s, int on)
 {
-    TUSBState *s = g_malloc0(sizeof(*s));
+    if (!on) {
+        s->power = 0;
+    } else if (!s->power && on) {
+        s->power = 1;
+        /* 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);
+    }
+}
+
+static void tusb6010_irq(void *opaque, int source, int level)
+{
+    if (source) {
+        tusb_musb_core_intr(opaque, source - 1, level);
+    } else {
+        tusb6010_power(opaque, level);
+    }
+}
+
+static void tusb6010_reset(DeviceState *dev)
+{
+    TUSBState *s = FROM_SYSBUS(TUSBState, sysbus_from_qdev(dev));
+    int i;
 
     s->test_reset = TUSB_PROD_TEST_RESET_VAL;
     s->host_mode = 0;
@@ -735,28 +751,59 @@ TUSBState *tusb6010_init(qemu_irq intr)
     s->mask = 0xffffffff;
     s->intr = 0x00000000;
     s->otg_timer_val = 0;
-    memory_region_init_io(&s->iomem[1], &tusb_async_ops, s, "tusb-async",
-                          UINT32_MAX);
-    s->irq = intr;
+    s->scratch = 0;
+    s->prcm_config = 0;
+    s->prcm_mngmt = 0;
+    s->intr_ok = 0;
+    s->usbip_intr = 0;
+    s->usbip_mask = 0;
+    s->gpio_intr = 0;
+    s->gpio_mask = 0;
+    s->gpio_config = 0;
+    s->dma_intr = 0;
+    s->dma_mask = 0;
+    s->dma_map = 0;
+    s->dma_config = 0;
+    s->ep0_config = 0;
+    s->wkup_mask = 0;
+    s->pullup[0] = s->pullup[1] = 0;
+    s->control_config = 0;
+    for (i = 0; i < 15; i++) {
+        s->rx_config[i] = s->tx_config[i] = 0;
+    }
+}
+
+static int tusb6010_init(SysBusDevice *dev)
+{
+    TUSBState *s = FROM_SYSBUS(TUSBState, dev);
+    qemu_irq *musb_irqs;
+    int i;
     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->musb = musb_init(qemu_allocate_irqs(tusb_musb_core_intr, s,
-                            __musb_irq_max));
-
-    return s;
+    memory_region_init_io(&s->iomem[1], &tusb_async_ops, s, "tusb-async",
+                          UINT32_MAX);
+    sysbus_init_mmio_region(dev, &s->iomem[0]);
+    sysbus_init_mmio_region(dev, &s->iomem[1]);
+    sysbus_init_irq(dev, &s->irq);
+    qdev_init_gpio_in(&dev->qdev, tusb6010_irq, __musb_irq_max + 1);
+    musb_irqs = g_new0(qemu_irq, __musb_irq_max);
+    for (i = 0; i < __musb_irq_max; i++) {
+        musb_irqs[i] = qdev_get_gpio_in(&dev->qdev, i + 1);
+    }
+    s->musb = musb_init(musb_irqs);
+    return 0;
 }
 
-void tusb6010_power(TUSBState *s, int on)
-{
-    if (!on)
-        s->power = 0;
-    else if (!s->power && on) {
-        s->power = 1;
+static SysBusDeviceInfo tusb6010_info = {
+    .init = tusb6010_init,
+    .qdev.name = "tusb6010",
+    .qdev.size = sizeof(TUSBState),
+    .qdev.reset = tusb6010_reset,
+};
 
-        /* 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);
-    }
+static void tusb6010_register_device(void)
+{
+    sysbus_register_withprop(&tusb6010_info);
 }
+
+device_init(tusb6010_register_device)
diff --git a/hw/tusb6010.h b/hw/tusb6010.h
deleted file mode 100644
index b85ee86..0000000
--- a/hw/tusb6010.h
+++ /dev/null
@@ -1,28 +0,0 @@
-/*
- * tusb6010 interfaces
- *
- * Copyright 2011 Red Hat, Inc. and/or its affiliates
- *
- * Authors:
- *  Avi Kivity <avi at redhat.com>
- *
- * Derived from hw/devices.h.
- *
- * This work is licensed under the terms of the GNU GPL, version 2.  See
- * the COPYING file in the top-level directory.
- *
- */
-
-#ifndef TUSB6010_H
-#define TUSB6010_H
-
-#include "targphys.h"
-#include "memory.h"
-
-typedef struct TUSBState TUSBState;
-TUSBState *tusb6010_init(qemu_irq intr);
-MemoryRegion *tusb6010_sync_io(TUSBState *s);
-MemoryRegion *tusb6010_async_io(TUSBState *s);
-void tusb6010_power(TUSBState *s, int on);
-
-#endif
commit 021d26d161bac89235eb79126996825221cf9f10
Author: Jan Kiszka <jan.kiszka at siemens.com>
Date:   Tue Aug 30 00:38:24 2011 +0200

    memory: Fix memory_region_get_ram_ptr for ROM devices
    
    Mask out the sub-page bits that are used by ROM device for storing the
    io-index and the IO_MEM_ROMD flag.
    
    Signed-off-by: Jan Kiszka <jan.kiszka at siemens.com>
    Signed-off-by: Avi Kivity <avi at redhat.com>

diff --git a/memory.c b/memory.c
index eb31fa8..57f0fa4 100644
--- a/memory.c
+++ b/memory.c
@@ -1063,7 +1063,7 @@ void *memory_region_get_ram_ptr(MemoryRegion *mr)
 
     assert(mr->terminates);
 
-    return qemu_get_ram_ptr(mr->ram_addr);
+    return qemu_get_ram_ptr(mr->ram_addr & TARGET_PAGE_MASK);
 }
 
 static void memory_region_update_coalesced_range(MemoryRegion *mr)
commit f0fb8b7180fdcf536ea635a0720e1496110ecb3b
Merge: 9f4bd6b... d5c8cf9...
Author: Edgar E. Iglesias <edgar.iglesias at gmail.com>
Date:   Mon Aug 29 23:59:06 2011 +0200

    Merge branch 'omap-for-upstream' of git://git.linaro.org/people/pmaydell/qemu-arm into pm

commit 9f4bd6baf64b8139cf2d7f8f53a98b27531da13c
Merge: 950c671... a22f123...
Author: Anthony Liguori <aliguori at us.ibm.com>
Date:   Mon Aug 29 09:57:06 2011 -0500

    Merge remote-tracking branch 'kwolf/for-anthony' into staging

commit 950c671df1078f4505d1b8461620f48aa91a9fda
Merge: 751d63c... b5fe14c...
Author: Anthony Liguori <aliguori at us.ibm.com>
Date:   Mon Aug 29 08:48:43 2011 -0500

    Merge remote-tracking branch 'qemu-kvm/memory/core' into staging

commit 751d63c371045dafc76f0e87fcdc41967c59e04d
Merge: c783924... 73c92f9...
Author: Anthony Liguori <aliguori at us.ibm.com>
Date:   Mon Aug 29 08:48:28 2011 -0500

    Merge remote-tracking branch 'qemu-kvm/memory/urgent' into staging

commit c783924136e166d6034859d87118195f4c08d68f
Merge: 8d76d4b... b0b3db7...
Author: Anthony Liguori <aliguori at us.ibm.com>
Date:   Mon Aug 29 08:48:15 2011 -0500

    Merge remote-tracking branch 'mst/for_anthony' into staging

commit 8d76d4befbdde3a5a50f68512671494b76d74ad2
Merge: 9f94778... 860341f...
Author: Anthony Liguori <aliguori at us.ibm.com>
Date:   Mon Aug 29 08:48:07 2011 -0500

    Merge remote-tracking branch 'qmp/queue/monitor' into staging

commit a22f123ca3d3c09a77af4341ed1fbcc175b54f1d
Author: Kevin Wolf <kwolf at redhat.com>
Date:   Fri Aug 26 15:27:13 2011 +0200

    qemu-img: Require larger zero areas for sparse handling
    
    By default, require 4k of consecutive zero bytes for qemu-img to make the
    output file sparse by not issuing a write request for the zeroed parts. Add an
    -S option to allow users to tune this setting.
    
    This helps to avoid situations where a lot of zero sectors and data sectors are
    mixed and qemu-img tended to issue many tiny 512 byte writes.
    
    Signed-off-by: Kevin Wolf <kwolf at redhat.com>

diff --git a/qemu-img-cmds.hx b/qemu-img-cmds.hx
index 1299e83..4be00a5 100644
--- a/qemu-img-cmds.hx
+++ b/qemu-img-cmds.hx
@@ -28,9 +28,9 @@ STEXI
 ETEXI
 
 DEF("convert", img_convert,
-    "convert [-c] [-p] [-f fmt] [-t cache] [-O output_fmt] [-o options] [-s snapshot_name] filename [filename2 [...]] output_filename")
+    "convert [-c] [-p] [-f fmt] [-t cache] [-O output_fmt] [-o options] [-s snapshot_name] [-S sparse_size] filename [filename2 [...]] output_filename")
 STEXI
- at item convert [-c] [-p] [-f @var{fmt}] [-O @var{output_fmt}] [-o @var{options}] [-s @var{snapshot_name}] @var{filename} [@var{filename2} [...]] @var{output_filename}
+ at item convert [-c] [-p] [-f @var{fmt}] [-O @var{output_fmt}] [-o @var{options}] [-s @var{snapshot_name}] [-S @var{sparse_size}] @var{filename} [@var{filename2} [...]] @var{output_filename}
 ETEXI
 
 DEF("info", img_info,
diff --git a/qemu-img.c b/qemu-img.c
index 0561d77..6a39731 100644
--- a/qemu-img.c
+++ b/qemu-img.c
@@ -82,6 +82,8 @@ static void help(void)
            "       rebasing in this case (useful for renaming the backing file)\n"
            "  '-h' with or without a command shows this help and lists the supported formats\n"
            "  '-p' show progress of command (only certain commands)\n"
+           "  '-S' indicates the consecutive number of bytes that must contain only zeros\n"
+           "       for qemu-img to create a sparse image during conversion\n"
            "\n"
            "Parameters to snapshot subcommand:\n"
            "  'snapshot' is the name of the snapshot to create, apply or delete\n"
@@ -571,6 +573,48 @@ static int is_allocated_sectors(const uint8_t *buf, int n, int *pnum)
 }
 
 /*
+ * Like is_allocated_sectors, but if the buffer starts with a used sector,
+ * up to 'min' consecutive sectors containing zeros are ignored. This avoids
+ * breaking up write requests for only small sparse areas.
+ */
+static int is_allocated_sectors_min(const uint8_t *buf, int n, int *pnum,
+    int min)
+{
+    int ret;
+    int num_checked, num_used;
+
+    if (n < min) {
+        min = n;
+    }
+
+    ret = is_allocated_sectors(buf, n, pnum);
+    if (!ret) {
+        return ret;
+    }
+
+    num_used = *pnum;
+    buf += BDRV_SECTOR_SIZE * *pnum;
+    n -= *pnum;
+    num_checked = num_used;
+
+    while (n > 0) {
+        ret = is_allocated_sectors(buf, n, pnum);
+
+        buf += BDRV_SECTOR_SIZE * *pnum;
+        n -= *pnum;
+        num_checked += *pnum;
+        if (ret) {
+            num_used = num_checked;
+        } else if (*pnum >= min) {
+            break;
+        }
+    }
+
+    *pnum = num_used;
+    return 1;
+}
+
+/*
  * Compares two buffers sector by sector. Returns 0 if the first sector of both
  * buffers matches, non-zero otherwise.
  *
@@ -620,6 +664,7 @@ static int img_convert(int argc, char **argv)
     char *options = NULL;
     const char *snapshot_name = NULL;
     float local_progress;
+    int min_sparse = 8; /* Need at least 4k of zeros for sparse detection */
 
     fmt = NULL;
     out_fmt = "raw";
@@ -627,7 +672,7 @@ static int img_convert(int argc, char **argv)
     out_baseimg = NULL;
     compress = 0;
     for(;;) {
-        c = getopt(argc, argv, "f:O:B:s:hce6o:pt:");
+        c = getopt(argc, argv, "f:O:B:s:hce6o:pS:t:");
         if (c == -1) {
             break;
         }
@@ -662,6 +707,18 @@ static int img_convert(int argc, char **argv)
         case 's':
             snapshot_name = optarg;
             break;
+        case 'S':
+        {
+            int64_t sval;
+            sval = strtosz_suffix(optarg, NULL, STRTOSZ_DEFSUFFIX_B);
+            if (sval < 0) {
+                error_report("Invalid minimum zero buffer size for sparse output specified");
+                return 1;
+            }
+
+            min_sparse = sval / BDRV_SECTOR_SIZE;
+            break;
+        }
         case 'p':
             progress = 1;
             break;
@@ -970,7 +1027,7 @@ static int img_convert(int argc, char **argv)
                    sectors that are entirely 0, since whatever data was
                    already there is garbage, not 0s. */
                 if (!has_zero_init || out_baseimg ||
-                    is_allocated_sectors(buf1, n, &n1)) {
+                    is_allocated_sectors_min(buf1, n, &n1, min_sparse)) {
                     ret = bdrv_write(out_bs, sector_num, buf1, n1);
                     if (ret < 0) {
                         error_report("error while writing sector %" PRId64
diff --git a/qemu-img.texi b/qemu-img.texi
index 495a1b6..70fa321 100644
--- a/qemu-img.texi
+++ b/qemu-img.texi
@@ -40,6 +40,11 @@ indicates that target image must be compressed (qcow format only)
 with or without a command shows help and lists the supported formats
 @item -p
 display progress bar (convert and rebase commands only)
+ at item -S @var{size}
+indicates the consecutive number of bytes that must contain only zeros
+for qemu-img to create a sparse image during conversion. This value is rounded
+down to the nearest 512 bytes. You may use the common size suffixes like
+ at code{k} for kilobytes.
 @end table
 
 Parameters to snapshot subcommand:
@@ -86,7 +91,7 @@ it doesn't need to be specified separately in this case.
 
 Commit the changes recorded in @var{filename} in its base image.
 
- at item convert [-c] [-p] [-f @var{fmt}] [-O @var{output_fmt}] [-o @var{options}] [-s @var{snapshot_name}] @var{filename} [@var{filename2} [...]] @var{output_filename}
+ at item convert [-c] [-p] [-f @var{fmt}] [-O @var{output_fmt}] [-o @var{options}] [-s @var{snapshot_name}] [-S @var{sparse_size}] @var{filename} [@var{filename2} [...]] @var{output_filename}
 
 Convert the disk image @var{filename} or a snapshot @var{snapshot_name} to disk image @var{output_filename}
 using format @var{output_fmt}. It can be optionally compressed (@code{-c}
commit 2542bfd51c42eead37e0025a9055f74b8c3a1aed
Author: Stefan Weil <weil at mail.berlios.de>
Date:   Sun Aug 28 21:45:40 2011 +0200

    Fix spelling in comments and debug messages (recieve -> receive)
    
    Signed-off-by: Stefan Weil <weil at mail.berlios.de>
    Reviewed-by: Andreas Färber <andreas.faerber at web.de>
    Signed-off-by: Stefan Hajnoczi <stefanha at linux.vnet.ibm.com>

diff --git a/docs/qapi-code-gen.txt b/docs/qapi-code-gen.txt
index b7befb5..f345866 100644
--- a/docs/qapi-code-gen.txt
+++ b/docs/qapi-code-gen.txt
@@ -229,7 +229,7 @@ in the schema. The following files are generated:
 $(prefix)qmp-marshal.c: command marshal/dispatch functions for each
                         QMP command defined in the schema. Functions
                         generated by qapi-visit.py are used to
-                        convert QObjects recieved from the wire into
+                        convert QObjects received from the wire into
                         function parameters, and uses the same
                         visitor functions to convert native C return
                         values to QObjects from transmission back
diff --git a/libcacard/vscclient.c b/libcacard/vscclient.c
index a7b3834..2191f60 100644
--- a/libcacard/vscclient.c
+++ b/libcacard/vscclient.c
@@ -585,7 +585,7 @@ main(
                 printf(" recv APDU: ");
                 print_byte_array(pbSendBuffer, mhHeader.length);
             }
-            /* Transmit recieved APDU */
+            /* Transmit received APDU */
             dwSendLength = mhHeader.length;
             dwRecvLength = sizeof(pbRecvBuffer);
             reader = vreader_get_reader_by_id(mhHeader.reader_id);
diff --git a/qemu-ga.c b/qemu-ga.c
index 858d75a..4932013 100644
--- a/qemu-ga.c
+++ b/qemu-ga.c
@@ -51,7 +51,7 @@ static struct GAState *ga_state;
 
 static void quit_handler(int sig)
 {
-    g_debug("recieved signal num %d, quitting", sig);
+    g_debug("received signal num %d, quitting", sig);
 
     if (g_main_loop_is_running(ga_state->main_loop)) {
         g_main_loop_quit(ga_state->main_loop);
commit 11d6dded8eb09aca1d648166f5f80e846e9c8fc8
Author: Alon Levy <alevy at redhat.com>
Date:   Fri Aug 26 22:06:01 2011 +0300

    hw/pci-stub: fix comment typo
    
    [Stefan fixed "doesn't" -> "don't"]
    
    Signed-off-by: Alon Levy <alevy at redhat.com>
    Signed-off-by: Stefan Hajnoczi <stefanha at linux.vnet.ibm.com>

diff --git a/hw/pci-stub.c b/hw/pci-stub.c
index c5a0aa8..1fb105d 100644
--- a/hw/pci-stub.c
+++ b/hw/pci-stub.c
@@ -1,5 +1,5 @@
 /*
- * PCI stubs for plathome that doesn't support pci bus.
+ * PCI stubs for platforms that don't support pci bus.
  *
  * Copyright (c) 2010 Isaku Yamahata <yamahata at valinux co jp>
  *                    VA Linux Systems Japan K.K.
commit b5fe14cc7efa4e3ef58f591728e69203287a9de4
Author: Avi Kivity <avi at redhat.com>
Date:   Mon Aug 29 09:12:49 2011 +0300

    memory: fix rom_device I/O mode
    
    When adding a rom_device in I/O mode, we incorrectly masked off the low
    bits, resulting in a pure RAM map.  Fix my masking off the high bits and
    IO_MEM_ROMD, yielding a pure I/O map.
    
    Signed-off-by: Avi Kivity <avi at redhat.com>

diff --git a/memory.c b/memory.c
index 1491a39..eb31fa8 100644
--- a/memory.c
+++ b/memory.c
@@ -304,7 +304,7 @@ static void as_memory_range_add(AddressSpace *as, FlatRange *fr)
     }
 
     if (!fr->readable) {
-        phys_offset &= TARGET_PAGE_MASK;
+        phys_offset &= ~TARGET_PAGE_MASK & ~IO_MEM_ROMD;
     }
 
     cpu_register_physical_memory_log(fr->addr.start,
commit d5c8cf993a5018aa61a935e1160cb95ef1afd1f5
Author: Peter Maydell <peter.maydell at linaro.org>
Date:   Sun Aug 28 16:22:20 2011 +0000

    omap_gpmc: Implement prefetch engine
    
    This commit implements the prefetch engine feature of the GPMC
    which can be used for NAND devices. This includes both interrupt
    driven and DMA-filling modes.
    
    Signed-off-by: Peter Maydell <peter.maydell at linaro.org>

diff --git a/hw/omap_gpmc.c b/hw/omap_gpmc.c
index be309fe..02f0c52 100644
--- a/hw/omap_gpmc.c
+++ b/hw/omap_gpmc.c
@@ -35,6 +35,7 @@ struct omap_gpmc_s {
     uint8_t sysconfig;
     uint16_t irqst;
     uint16_t irqen;
+    uint16_t lastirq;
     uint16_t timeout;
     uint16_t config;
     struct omap_gpmc_cs_file_s {
@@ -54,6 +55,8 @@ struct omap_gpmc_s {
         int startengine; /* GPMC_PREFETCH_CONTROL:STARTENGINE */
         int fifopointer; /* GPMC_PREFETCH_STATUS:FIFOPOINTER */
         int count; /* GPMC_PREFETCH_STATUS:COUNTVALUE */
+        MemoryRegion iomem;
+        uint8_t fifo[64];
     } prefetch;
 };
 
@@ -76,9 +79,42 @@ static int omap_gpmc_devsize(struct omap_gpmc_cs_file_s *f)
     return (f->config[0] >> 12) & 1;
 }
 
+/* Extract the chip-select value from the prefetch config1 register */
+static int prefetch_cs(uint32_t config1)
+{
+    return (config1 >> 24) & 7;
+}
+
+static int prefetch_threshold(uint32_t config1)
+{
+    return (config1 >> 8) & 0x7f;
+}
+
 static void omap_gpmc_int_update(struct omap_gpmc_s *s)
 {
-    qemu_set_irq(s->irq, s->irqen & s->irqst);
+    /* The TRM is a bit unclear, but it seems to say that
+     * the TERMINALCOUNTSTATUS bit is set only on the
+     * transition when the prefetch engine goes from
+     * active to inactive, whereas the FIFOEVENTSTATUS
+     * bit is held high as long as the fifo has at
+     * least THRESHOLD bytes available.
+     * So we do the latter here, but TERMINALCOUNTSTATUS
+     * is set elsewhere.
+     */
+    if (s->prefetch.fifopointer >= prefetch_threshold(s->prefetch.config1)) {
+        s->irqst |= 1;
+    }
+    if ((s->irqen & s->irqst) != s->lastirq) {
+        s->lastirq = s->irqen & s->irqst;
+        qemu_set_irq(s->irq, s->lastirq);
+    }
+}
+
+static void omap_gpmc_dma_update(struct omap_gpmc_s *s, int value)
+{
+    if (s->prefetch.config1 & 4) {
+        qemu_set_irq(s->drq, value);
+    }
 }
 
 /* Access functions for when a NAND-like device is mapped into memory:
@@ -176,6 +212,161 @@ static const MemoryRegionOps omap_nand_ops = {
     .endianness = DEVICE_NATIVE_ENDIAN,
 };
 
+static void fill_prefetch_fifo(struct omap_gpmc_s *s)
+{
+    /* Fill the prefetch FIFO by reading data from NAND.
+     * We do this synchronously, unlike the hardware which
+     * will do this asynchronously. We refill when the
+     * FIFO has THRESHOLD bytes free, and we always refill
+     * as much data as possible starting at the top end
+     * of the FIFO.
+     * (We have to refill at THRESHOLD rather than waiting
+     * for the FIFO to empty to allow for the case where
+     * the FIFO size isn't an exact multiple of THRESHOLD
+     * and we're doing DMA transfers.)
+     * This means we never need to handle wrap-around in
+     * the fifo-reading code, and the next byte of data
+     * to read is always fifo[63 - fifopointer].
+     */
+    int fptr;
+    int cs = prefetch_cs(s->prefetch.config1);
+    int is16bit = (((s->cs_file[cs].config[0] >> 12) & 3) != 0);
+    int bytes;
+    /* Don't believe the bit of the OMAP TRM that says that COUNTVALUE
+     * and TRANSFERCOUNT are in units of 16 bit words for 16 bit NAND.
+     * Instead believe the bit that says it is always a byte count.
+     */
+    bytes = 64 - s->prefetch.fifopointer;
+    if (bytes > s->prefetch.count) {
+        bytes = s->prefetch.count;
+    }
+    s->prefetch.count -= bytes;
+    s->prefetch.fifopointer += bytes;
+    fptr = 64 - s->prefetch.fifopointer;
+    /* Move the existing data in the FIFO so it sits just
+     * before what we're about to read in
+     */
+    while (fptr < (64 - bytes)) {
+        s->prefetch.fifo[fptr] = s->prefetch.fifo[fptr + bytes];
+        fptr++;
+    }
+    while (fptr < 64) {
+        if (is16bit) {
+            uint32_t v = omap_nand_read(&s->cs_file[cs], 0, 2);
+            s->prefetch.fifo[fptr++] = v & 0xff;
+            s->prefetch.fifo[fptr++] = (v >> 8) & 0xff;
+        } else {
+            s->prefetch.fifo[fptr++] = omap_nand_read(&s->cs_file[cs], 0, 1);
+        }
+    }
+    if (s->prefetch.startengine && (s->prefetch.count == 0)) {
+        /* This was the final transfer: raise TERMINALCOUNTSTATUS */
+        s->irqst |= 2;
+        s->prefetch.startengine = 0;
+    }
+    /* If there are any bytes in the FIFO at this point then
+     * we must raise a DMA request (either this is a final part
+     * transfer, or we filled the FIFO in which case we certainly
+     * have THRESHOLD bytes available)
+     */
+    if (s->prefetch.fifopointer != 0) {
+        omap_gpmc_dma_update(s, 1);
+    }
+    omap_gpmc_int_update(s);
+}
+
+/* Access functions for a NAND-like device when the prefetch/postwrite
+ * engine is enabled -- all addresses in the region behave alike:
+ * data is read or written to the FIFO.
+ */
+static uint64_t omap_gpmc_prefetch_read(void *opaque, target_phys_addr_t addr,
+                                        unsigned size)
+{
+    struct omap_gpmc_s *s = (struct omap_gpmc_s *) opaque;
+    uint32_t data;
+    if (s->prefetch.config1 & 1) {
+        /* The TRM doesn't define the behaviour if you read from the
+         * FIFO when the prefetch engine is in write mode. We choose
+         * to always return zero.
+         */
+        return 0;
+    }
+    /* Note that trying to read an empty fifo repeats the last byte */
+    if (s->prefetch.fifopointer) {
+        s->prefetch.fifopointer--;
+    }
+    data = s->prefetch.fifo[63 - s->prefetch.fifopointer];
+    if (s->prefetch.fifopointer ==
+        (64 - prefetch_threshold(s->prefetch.config1))) {
+        /* We've drained THRESHOLD bytes now. So deassert the
+         * DMA request, then refill the FIFO (which will probably
+         * assert it again.)
+         */
+        omap_gpmc_dma_update(s, 0);
+        fill_prefetch_fifo(s);
+    }
+    omap_gpmc_int_update(s);
+    return data;
+}
+
+static void omap_gpmc_prefetch_write(void *opaque, target_phys_addr_t addr,
+                                     uint64_t value, unsigned size)
+{
+    struct omap_gpmc_s *s = (struct omap_gpmc_s *) opaque;
+    int cs = prefetch_cs(s->prefetch.config1);
+    if ((s->prefetch.config1 & 1) == 0) {
+        /* The TRM doesn't define the behaviour of writing to the
+         * FIFO when the prefetch engine is in read mode. We
+         * choose to ignore the write.
+         */
+        return;
+    }
+    if (s->prefetch.count == 0) {
+        /* The TRM doesn't define the behaviour of writing to the
+         * FIFO if the transfer is complete. We choose to ignore.
+         */
+        return;
+    }
+    /* The only reason we do any data buffering in postwrite
+     * mode is if we are talking to a 16 bit NAND device, in
+     * which case we need to buffer the first byte of the
+     * 16 bit word until the other byte arrives.
+     */
+    int is16bit = (((s->cs_file[cs].config[0] >> 12) & 3) != 0);
+    if (is16bit) {
+        /* fifopointer alternates between 64 (waiting for first
+         * byte of word) and 63 (waiting for second byte)
+         */
+        if (s->prefetch.fifopointer == 64) {
+            s->prefetch.fifo[0] = value;
+            s->prefetch.fifopointer--;
+        } else {
+            value = (value << 8) | s->prefetch.fifo[0];
+            omap_nand_write(&s->cs_file[cs], 0, value, 2);
+            s->prefetch.count--;
+            s->prefetch.fifopointer = 64;
+        }
+    } else {
+        /* Just write the byte : fifopointer remains 64 at all times */
+        omap_nand_write(&s->cs_file[cs], 0, value, 1);
+        s->prefetch.count--;
+    }
+    if (s->prefetch.count == 0) {
+        /* Final transfer: raise TERMINALCOUNTSTATUS */
+        s->irqst |= 2;
+        s->prefetch.startengine = 0;
+    }
+    omap_gpmc_int_update(s);
+}
+
+static const MemoryRegionOps omap_prefetch_ops = {
+    .read = omap_gpmc_prefetch_read,
+    .write = omap_gpmc_prefetch_write,
+    .endianness = DEVICE_NATIVE_ENDIAN,
+    .impl.min_access_size = 1,
+    .impl.max_access_size = 1,
+};
+
 static MemoryRegion *omap_gpmc_cs_memregion(struct omap_gpmc_s *s, int cs)
 {
     /* Return the MemoryRegion* to map/unmap for this chipselect */
@@ -183,6 +374,11 @@ static MemoryRegion *omap_gpmc_cs_memregion(struct omap_gpmc_s *s, int cs)
     if (omap_gpmc_devtype(f) == OMAP_GPMC_NOR) {
         return f->iomem;
     }
+    if ((s->prefetch.config1 & 0x80) &&
+        (prefetch_cs(s->prefetch.config1) == cs)) {
+        /* The prefetch engine is enabled for this CS: map the FIFO */
+        return &s->prefetch.iomem;
+    }
     return &f->nandiomem;
 }
 
@@ -510,24 +706,61 @@ static void omap_gpmc_write(void *opaque, target_phys_addr_t addr,
         break;
 
     case 0x1e0:	/* GPMC_PREFETCH_CONFIG1 */
-        s->prefetch.config1 = value & 0x7f8f7fbf;
-        /* TODO: update interrupts, fifos, dmas */
+        if (!s->prefetch.startengine) {
+            uint32_t oldconfig1 = s->prefetch.config1;
+            uint32_t changed;
+            s->prefetch.config1 = value & 0x7f8f7fbf;
+            changed = oldconfig1 ^ s->prefetch.config1;
+            if (changed & (0x80 | 0x7000000)) {
+                /* Turning the engine on or off, or mapping it somewhere else.
+                 * cs_map() and cs_unmap() check the prefetch config and
+                 * overall CSVALID bits, so it is sufficient to unmap-and-map
+                 * both the old cs and the new one.
+                 */
+                int oldcs = prefetch_cs(oldconfig1);
+                int newcs = prefetch_cs(s->prefetch.config1);
+                omap_gpmc_cs_unmap(s, oldcs);
+                omap_gpmc_cs_map(s, oldcs);
+                if (newcs != oldcs) {
+                    omap_gpmc_cs_unmap(s, newcs);
+                    omap_gpmc_cs_map(s, newcs);
+                }
+            }
+        }
         break;
 
     case 0x1e4:	/* GPMC_PREFETCH_CONFIG2 */
-        s->prefetch.transfercount = value & 0x3fff;
+        if (!s->prefetch.startengine) {
+            s->prefetch.transfercount = value & 0x3fff;
+        }
         break;
 
     case 0x1ec:	/* GPMC_PREFETCH_CONTROL */
-        s->prefetch.startengine = value & 1;
-        if (s->prefetch.startengine) {
-            if (s->prefetch.config1 & 1) {
-                s->prefetch.fifopointer = 0x40;
+        if (s->prefetch.startengine != (value & 1)) {
+            s->prefetch.startengine = value & 1;
+            if (s->prefetch.startengine) {
+                /* Prefetch engine start */
+                s->prefetch.count = s->prefetch.transfercount;
+                if (s->prefetch.config1 & 1) {
+                    /* Write */
+                    s->prefetch.fifopointer = 64;
+                } else {
+                    /* Read */
+                    s->prefetch.fifopointer = 0;
+                    fill_prefetch_fifo(s);
+                }
             } else {
-                s->prefetch.fifopointer = 0x00;
+                /* Prefetch engine forcibly stopped. The TRM
+                 * doesn't define the behaviour if you do this.
+                 * We clear the prefetch count, which means that
+                 * we permit no more writes, and don't read any
+                 * more data from NAND. The CPU can still drain
+                 * the FIFO of unread data.
+                 */
+                s->prefetch.count = 0;
             }
+            omap_gpmc_int_update(s);
         }
-        /* TODO: start */
         break;
 
     case 0x1f4:	/* GPMC_ECC_CONFIG */
@@ -579,6 +812,7 @@ struct omap_gpmc_s *omap_gpmc_init(struct omap_mpu_state_s *mpu,
     s->drq = drq;
     s->accept_256 = cpu_is_omap3630(mpu);
     s->revision = cpu_class_omap3(mpu) ? 0x50 : 0x20;
+    s->lastirq = 0;
     omap_gpmc_reset(s);
 
     /* We have to register a different IO memory handler for each
@@ -594,6 +828,9 @@ struct omap_gpmc_s *omap_gpmc_init(struct omap_mpu_state_s *mpu,
                               "omap-nand",
                               256 * 1024 * 1024);
     }
+
+    memory_region_init_io(&s->prefetch.iomem, &omap_prefetch_ops, s,
+                          "omap-gpmc-prefetch", 256 * 1024 * 1024);
     return s;
 }
 
commit eee0a1c67e46a22e7205c2240c4eaab12a9c6f72
Author: Peter Maydell <peter.maydell at linaro.org>
Date:   Sun Aug 28 16:22:20 2011 +0000

    omap: Wire up the DMA request line to the GPMC
    
    Signed-off-by: Peter Maydell <peter.maydell at linaro.org>

diff --git a/hw/omap.h b/hw/omap.h
index 81f5544..d9ab006 100644
--- a/hw/omap.h
+++ b/hw/omap.h
@@ -119,7 +119,8 @@ void omap_sdrc_reset(struct omap_sdrc_s *s);
 /* OMAP2 general purpose memory controller */
 struct omap_gpmc_s;
 struct omap_gpmc_s *omap_gpmc_init(struct omap_mpu_state_s *mpu,
-                                   target_phys_addr_t base, qemu_irq irq);
+                                   target_phys_addr_t base,
+                                   qemu_irq irq, qemu_irq drq);
 void omap_gpmc_reset(struct omap_gpmc_s *s);
 void omap_gpmc_attach(struct omap_gpmc_s *s, int cs, MemoryRegion *iomem);
 void omap_gpmc_attach_nand(struct omap_gpmc_s *s, int cs, DeviceState *nand);
diff --git a/hw/omap2.c b/hw/omap2.c
index 0feb7a5..ca088d9 100644
--- a/hw/omap2.c
+++ b/hw/omap2.c
@@ -2402,7 +2402,8 @@ struct omap_mpu_state_s *omap2420_mpu_init(unsigned long sdram_size,
     sysbus_mmio_map(busdev, 4, omap_l4_region_base(ta, 5));
 
     s->sdrc = omap_sdrc_init(0x68009000);
-    s->gpmc = omap_gpmc_init(s, 0x6800a000, s->irq[0][OMAP_INT_24XX_GPMC_IRQ]);
+    s->gpmc = omap_gpmc_init(s, 0x6800a000, s->irq[0][OMAP_INT_24XX_GPMC_IRQ],
+                             s->drq[OMAP24XX_DMA_GPMC]);
 
     dinfo = drive_get(IF_SD, 0, 0);
     if (!dinfo) {
diff --git a/hw/omap_gpmc.c b/hw/omap_gpmc.c
index 158c097..be309fe 100644
--- a/hw/omap_gpmc.c
+++ b/hw/omap_gpmc.c
@@ -27,6 +27,7 @@
 /* General-Purpose Memory Controller */
 struct omap_gpmc_s {
     qemu_irq irq;
+    qemu_irq drq;
     MemoryRegion iomem;
     int accept_256;
 
@@ -564,7 +565,8 @@ static const MemoryRegionOps omap_gpmc_ops = {
 };
 
 struct omap_gpmc_s *omap_gpmc_init(struct omap_mpu_state_s *mpu,
-                                   target_phys_addr_t base, qemu_irq irq)
+                                   target_phys_addr_t base,
+                                   qemu_irq irq, qemu_irq drq)
 {
     int cs;
     struct omap_gpmc_s *s = (struct omap_gpmc_s *)
@@ -574,6 +576,7 @@ struct omap_gpmc_s *omap_gpmc_init(struct omap_mpu_state_s *mpu,
     memory_region_add_subregion(get_system_memory(), base, &s->iomem);
 
     s->irq = irq;
+    s->drq = drq;
     s->accept_256 = cpu_is_omap3630(mpu);
     s->revision = cpu_class_omap3(mpu) ? 0x50 : 0x20;
     omap_gpmc_reset(s);
commit ef20677ca654f0d6e848edf93a9975b350fec2b7
Author: Peter Maydell <peter.maydell at linaro.org>
Date:   Sun Aug 28 16:22:20 2011 +0000

    omap_gpmc: Pull prefetch engine data into sub-struct
    
    Refactor the gpmc state structure so items relating to
    the prefetch engine are in their own sub-struct and have
    more useful names.
    
    Signed-off-by: Peter Maydell <peter.maydell at linaro.org>

diff --git a/hw/omap_gpmc.c b/hw/omap_gpmc.c
index 0326d49..158c097 100644
--- a/hw/omap_gpmc.c
+++ b/hw/omap_gpmc.c
@@ -36,10 +36,6 @@ struct omap_gpmc_s {
     uint16_t irqen;
     uint16_t timeout;
     uint16_t config;
-    uint32_t prefconfig[2];
-    int prefcontrol;
-    int preffifo;
-    int prefcount;
     struct omap_gpmc_cs_file_s {
         uint32_t config[7];
         MemoryRegion *iomem;
@@ -51,6 +47,13 @@ struct omap_gpmc_s {
     int ecc_ptr;
     uint32_t ecc_cfg;
     ECCState ecc[9];
+    struct prefetch {
+        uint32_t config1; /* GPMC_PREFETCH_CONFIG1 */
+        uint32_t transfercount; /* GPMC_PREFETCH_CONFIG2:TRANSFERCOUNT */
+        int startengine; /* GPMC_PREFETCH_CONTROL:STARTENGINE */
+        int fifopointer; /* GPMC_PREFETCH_STATUS:FIFOPOINTER */
+        int count; /* GPMC_PREFETCH_STATUS:COUNTVALUE */
+    } prefetch;
 };
 
 #define OMAP_GPMC_8BIT 0
@@ -243,11 +246,11 @@ void omap_gpmc_reset(struct omap_gpmc_s *s)
     omap_gpmc_int_update(s);
     s->timeout = 0;
     s->config = 0xa00;
-    s->prefconfig[0] = 0x00004000;
-    s->prefconfig[1] = 0x00000000;
-    s->prefcontrol = 0;
-    s->preffifo = 0;
-    s->prefcount = 0;
+    s->prefetch.config1 = 0x00004000;
+    s->prefetch.transfercount = 0x00000000;
+    s->prefetch.startengine = 0;
+    s->prefetch.fifopointer = 0;
+    s->prefetch.count = 0;
     for (i = 0; i < 8; i ++) {
         omap_gpmc_cs_unmap(s, i);
         s->cs_file[i].config[1] = 0x101001;
@@ -363,16 +366,16 @@ static uint64_t omap_gpmc_read(void *opaque, target_phys_addr_t addr,
         break;
 
     case 0x1e0:	/* GPMC_PREFETCH_CONFIG1 */
-        return s->prefconfig[0];
+        return s->prefetch.config1;
     case 0x1e4:	/* GPMC_PREFETCH_CONFIG2 */
-        return s->prefconfig[1];
+        return s->prefetch.transfercount;
     case 0x1ec:	/* GPMC_PREFETCH_CONTROL */
-        return s->prefcontrol;
+        return s->prefetch.startengine;
     case 0x1f0:	/* GPMC_PREFETCH_STATUS */
-        return (s->preffifo << 24) |
-                ((s->preffifo >=
-                  ((s->prefconfig[0] >> 8) & 0x7f) ? 1 : 0) << 16) |
-                s->prefcount;
+        return (s->prefetch.fifopointer << 24) |
+                ((s->prefetch.fifopointer >=
+                  ((s->prefetch.config1 >> 8) & 0x7f) ? 1 : 0) << 16) |
+                s->prefetch.count;
 
     case 0x1f4:	/* GPMC_ECC_CONFIG */
         return s->ecc_cs;
@@ -506,21 +509,22 @@ static void omap_gpmc_write(void *opaque, target_phys_addr_t addr,
         break;
 
     case 0x1e0:	/* GPMC_PREFETCH_CONFIG1 */
-        s->prefconfig[0] = value & 0x7f8f7fbf;
+        s->prefetch.config1 = value & 0x7f8f7fbf;
         /* TODO: update interrupts, fifos, dmas */
         break;
 
     case 0x1e4:	/* GPMC_PREFETCH_CONFIG2 */
-        s->prefconfig[1] = value & 0x3fff;
+        s->prefetch.transfercount = value & 0x3fff;
         break;
 
     case 0x1ec:	/* GPMC_PREFETCH_CONTROL */
-        s->prefcontrol = value & 1;
-        if (s->prefcontrol) {
-            if (s->prefconfig[0] & 1)
-                s->preffifo = 0x40;
-            else
-                s->preffifo = 0x00;
+        s->prefetch.startengine = value & 1;
+        if (s->prefetch.startengine) {
+            if (s->prefetch.config1 & 1) {
+                s->prefetch.fifopointer = 0x40;
+            } else {
+                s->prefetch.fifopointer = 0x00;
+            }
         }
         /* TODO: start */
         break;
commit 856f2df7717bc4270bac39469443dec401b02fec
Author: Juha Riihimäki <juha.riihimaki at nokia.com>
Date:   Sun Aug 28 16:22:20 2011 +0000

    omap_gpmc: Accept a zero mask field on omap3630
    
    OMAP3630 adds an extra bit of address masking, so a mask of
    0xb1111 is valid. Unfortunately the GPMC_REVISION is the same as
    on the OMAP3430 which only has three bits of address masking, so
    we have to derive this feature directly from the OMAP revision
    rather than from the GPMC revision.
    
    Signed-off-by: Juha Riihimäki <juha.riihimaki at nokia.com>
    [Riku Voipio: Fixes and restructuring patchset]
    Signed-off-by: Riku Voipio <riku.voipio at iki.fi>
    [Peter Maydell: More fixes and cleanups for upstream submission]
    Signed-off-by:  Peter Maydell <peter.maydell at linaro.org>

diff --git a/hw/omap_gpmc.c b/hw/omap_gpmc.c
index d2de72f..0326d49 100644
--- a/hw/omap_gpmc.c
+++ b/hw/omap_gpmc.c
@@ -28,6 +28,7 @@
 struct omap_gpmc_s {
     qemu_irq irq;
     MemoryRegion iomem;
+    int accept_256;
 
     uint8_t revision;
     uint8_t sysconfig;
@@ -198,11 +199,10 @@ static void omap_gpmc_cs_map(struct omap_gpmc_s *s, int cs)
     }
 
     /* TODO: check for overlapping regions and report access errors */
-    if ((mask != 0x8 && mask != 0xc && mask != 0xe && mask != 0xf) ||
-        (base & 0x0f & ~mask)) {
-        fprintf(stderr, "%s: wrong cs address mapping/decoding!\n",
-                        __FUNCTION__);
-        return;
+    if (mask != 0x8 && mask != 0xc && mask != 0xe && mask != 0xf
+         && !(s->accept_256 && !mask)) {
+        fprintf(stderr, "%s: invalid chip-select mask address (0x%x)\n",
+                 __func__, mask);
     }
 
     base <<= 24;
@@ -570,6 +570,7 @@ struct omap_gpmc_s *omap_gpmc_init(struct omap_mpu_state_s *mpu,
     memory_region_add_subregion(get_system_memory(), base, &s->iomem);
 
     s->irq = irq;
+    s->accept_256 = cpu_is_omap3630(mpu);
     s->revision = cpu_class_omap3(mpu) ? 0x50 : 0x20;
     omap_gpmc_reset(s);
 
commit f13e656e7eb555523df4b1ca73d0d9b65bf1d015
Author: Peter Maydell <peter.maydell at linaro.org>
Date:   Sun Aug 28 16:22:20 2011 +0000

    hw/omap.h: Add OMAP 3630 to omap_mpu_model enumeration
    
    Add the OMAP 3630 to the omap_mpu_model enumeration, and add the
    corresponding cpu_is_omap3630() function.
    
    (OMAP3 isn't supported yet but this is useful in upgrading common
    components to be "OMAP3 ready". We already have this for OMAP3430.)
    
    Signed-off-by: Peter Maydell <peter.maydell at linaro.org>

diff --git a/hw/omap.h b/hw/omap.h
index 2018636..81f5544 100644
--- a/hw/omap.h
+++ b/hw/omap.h
@@ -788,6 +788,7 @@ i2c_bus *omap_i2c_bus(struct omap_i2c_s *s);
 # define cpu_is_omap2420(cpu)		(cpu->mpu_model == omap2420)
 # define cpu_is_omap2430(cpu)		(cpu->mpu_model == omap2430)
 # define cpu_is_omap3430(cpu)		(cpu->mpu_model == omap3430)
+# define cpu_is_omap3630(cpu)           (cpu->mpu_model == omap3630)
 
 # define cpu_is_omap15xx(cpu)		\
         (cpu_is_omap310(cpu) || cpu_is_omap1510(cpu))
@@ -799,7 +800,8 @@ i2c_bus *omap_i2c_bus(struct omap_i2c_s *s);
 # define cpu_class_omap1(cpu)		\
         (cpu_is_omap15xx(cpu) || cpu_is_omap16xx(cpu))
 # define cpu_class_omap2(cpu)		cpu_is_omap24xx(cpu)
-# define cpu_class_omap3(cpu)		cpu_is_omap3430(cpu)
+# define cpu_class_omap3(cpu) \
+        (cpu_is_omap3430(cpu) || cpu_is_omap3630(cpu))
 
 struct omap_mpu_state_s {
     enum omap_mpu_model {
@@ -813,6 +815,7 @@ struct omap_mpu_state_s {
         omap2423,
         omap2430,
         omap3430,
+        omap3630,
     } mpu_model;
 
     CPUState *env;
commit 2a952feb8393209634d31d546e202d916e09da06
Author: Peter Maydell <peter.maydell at linaro.org>
Date:   Sun Aug 28 16:22:19 2011 +0000

    omap_gpmc: Support NAND devices
    
    Support accesses to NAND devices, both by mapping them into
    the GPMC address space, and via the NAND_COMMAND, NAND_ADDRESS
    and NAND_DATA GPMC registers.
    
    Signed-off-by: Peter Maydell <peter.maydell at linaro.org>

diff --git a/hw/omap.h b/hw/omap.h
index 8509c82..2018636 100644
--- a/hw/omap.h
+++ b/hw/omap.h
@@ -122,6 +122,7 @@ struct omap_gpmc_s *omap_gpmc_init(struct omap_mpu_state_s *mpu,
                                    target_phys_addr_t base, qemu_irq irq);
 void omap_gpmc_reset(struct omap_gpmc_s *s);
 void omap_gpmc_attach(struct omap_gpmc_s *s, int cs, MemoryRegion *iomem);
+void omap_gpmc_attach_nand(struct omap_gpmc_s *s, int cs, DeviceState *nand);
 
 /*
  * Common IRQ numbers for level 1 interrupt handler
diff --git a/hw/omap_gpmc.c b/hw/omap_gpmc.c
index c569aa1..d2de72f 100644
--- a/hw/omap_gpmc.c
+++ b/hw/omap_gpmc.c
@@ -43,6 +43,8 @@ struct omap_gpmc_s {
         uint32_t config[7];
         MemoryRegion *iomem;
         MemoryRegion container;
+        MemoryRegion nandiomem;
+        DeviceState *dev;
     } cs_file[8];
     int ecc_cs;
     int ecc_ptr;
@@ -50,11 +52,135 @@ struct omap_gpmc_s {
     ECCState ecc[9];
 };
 
+#define OMAP_GPMC_8BIT 0
+#define OMAP_GPMC_16BIT 1
+#define OMAP_GPMC_NOR 0
+#define OMAP_GPMC_NAND 2
+
+static int omap_gpmc_devtype(struct omap_gpmc_cs_file_s *f)
+{
+    return (f->config[0] >> 10) & 3;
+}
+
+static int omap_gpmc_devsize(struct omap_gpmc_cs_file_s *f)
+{
+    /* devsize field is really 2 bits but we ignore the high
+     * bit to ensure consistent behaviour if the guest sets
+     * it (values 2 and 3 are reserved in the TRM)
+     */
+    return (f->config[0] >> 12) & 1;
+}
+
 static void omap_gpmc_int_update(struct omap_gpmc_s *s)
 {
     qemu_set_irq(s->irq, s->irqen & s->irqst);
 }
 
+/* Access functions for when a NAND-like device is mapped into memory:
+ * all addresses in the region behave like accesses to the relevant
+ * GPMC_NAND_DATA_i register (which is actually implemented to call these)
+ */
+static uint64_t omap_nand_read(void *opaque, target_phys_addr_t addr,
+                               unsigned size)
+{
+    struct omap_gpmc_cs_file_s *f = (struct omap_gpmc_cs_file_s *)opaque;
+    uint64_t v;
+    nand_setpins(f->dev, 0, 0, 0, 1, 0);
+    switch (omap_gpmc_devsize(f)) {
+    case OMAP_GPMC_8BIT:
+        v = nand_getio(f->dev);
+        if (size == 1) {
+            return v;
+        }
+        v |= (nand_getio(f->dev) << 8);
+        if (size == 2) {
+            return v;
+        }
+        v |= (nand_getio(f->dev) << 16);
+        v |= (nand_getio(f->dev) << 24);
+        return v;
+    case OMAP_GPMC_16BIT:
+        v = nand_getio(f->dev);
+        if (size == 1) {
+            /* 8 bit read from 16 bit device : probably a guest bug */
+            return v & 0xff;
+        }
+        if (size == 2) {
+            return v;
+        }
+        v |= (nand_getio(f->dev) << 16);
+        return v;
+    default:
+        abort();
+    }
+}
+
+static void omap_nand_setio(DeviceState *dev, uint64_t value,
+                            int nandsize, int size)
+{
+    /* Write the specified value to the NAND device, respecting
+     * both size of the NAND device and size of the write access.
+     */
+    switch (nandsize) {
+    case OMAP_GPMC_8BIT:
+        switch (size) {
+        case 1:
+            nand_setio(dev, value & 0xff);
+            break;
+        case 2:
+            nand_setio(dev, value & 0xff);
+            nand_setio(dev, (value >> 8) & 0xff);
+            break;
+        case 4:
+        default:
+            nand_setio(dev, value & 0xff);
+            nand_setio(dev, (value >> 8) & 0xff);
+            nand_setio(dev, (value >> 16) & 0xff);
+            nand_setio(dev, (value >> 24) & 0xff);
+            break;
+        }
+    case OMAP_GPMC_16BIT:
+        switch (size) {
+        case 1:
+            /* writing to a 16bit device with 8bit access is probably a guest
+             * bug; pass the value through anyway.
+             */
+        case 2:
+            nand_setio(dev, value & 0xffff);
+            break;
+        case 4:
+        default:
+            nand_setio(dev, value & 0xffff);
+            nand_setio(dev, (value >> 16) & 0xffff);
+            break;
+        }
+    }
+}
+
+static void omap_nand_write(void *opaque, target_phys_addr_t addr,
+                            uint64_t value, unsigned size)
+{
+    struct omap_gpmc_cs_file_s *f = (struct omap_gpmc_cs_file_s *)opaque;
+    nand_setpins(f->dev, 0, 0, 0, 1, 0);
+    omap_nand_setio(f->dev, value, omap_gpmc_devsize(f), size);
+}
+
+static const MemoryRegionOps omap_nand_ops = {
+    .read = omap_nand_read,
+    .write = omap_nand_write,
+    .endianness = DEVICE_NATIVE_ENDIAN,
+};
+
+static MemoryRegion *omap_gpmc_cs_memregion(struct omap_gpmc_s *s, int cs)
+{
+    /* Return the MemoryRegion* to map/unmap for this chipselect */
+    struct omap_gpmc_cs_file_s *f = &s->cs_file[cs];
+    if (omap_gpmc_devtype(f) == OMAP_GPMC_NOR) {
+        return f->iomem;
+    }
+    return &f->nandiomem;
+}
+
 static void omap_gpmc_cs_map(struct omap_gpmc_s *s, int cs)
 {
     struct omap_gpmc_cs_file_s *f = &s->cs_file[cs];
@@ -62,7 +188,7 @@ static void omap_gpmc_cs_map(struct omap_gpmc_s *s, int cs)
     uint32_t base = f->config[6] & 0x3f;
     uint32_t size;
 
-    if (!f->iomem) {
+    if (!f->iomem && !f->dev) {
         return;
     }
 
@@ -86,7 +212,8 @@ static void omap_gpmc_cs_map(struct omap_gpmc_s *s, int cs)
      * that the same memory becomes accessible at every <i>size</i> bytes
      * starting from <i>base</i>.  */
     memory_region_init(&f->container, "omap-gpmc-file", size);
-    memory_region_add_subregion(&f->container, 0, f->iomem);
+    memory_region_add_subregion(&f->container, 0,
+                                omap_gpmc_cs_memregion(s, cs));
     memory_region_add_subregion(get_system_memory(), base,
                                 &f->container);
 }
@@ -98,12 +225,11 @@ static void omap_gpmc_cs_unmap(struct omap_gpmc_s *s, int cs)
         /* Do nothing unless CSVALID */
         return;
     }
-    if (!f->iomem) {
+    if (!f->iomem && !f->dev) {
         return;
     }
-
     memory_region_del_subregion(get_system_memory(), &f->container);
-    memory_region_del_subregion(&f->container, f->iomem);
+    memory_region_del_subregion(&f->container, omap_gpmc_cs_memregion(s, cs));
     memory_region_destroy(&f->container);
 }
 
@@ -151,6 +277,24 @@ void omap_gpmc_reset(struct omap_gpmc_s *s)
         ecc_reset(&s->ecc[i]);
 }
 
+static int gpmc_wordaccess_only(target_phys_addr_t addr)
+{
+    /* Return true if the register offset is to a register that
+     * only permits word width accesses.
+     * Non-word accesses are only OK for GPMC_NAND_DATA/ADDRESS/COMMAND
+     * for any chipselect.
+     */
+    if (addr >= 0x60 && addr <= 0x1d4) {
+        int cs = (addr - 0x60) / 0x30;
+        addr -= cs * 0x30;
+        if (addr >= 0x7c && addr < 0x88) {
+            /* GPMC_NAND_COMMAND, GPMC_NAND_ADDRESS, GPMC_NAND_DATA */
+            return 0;
+        }
+    }
+    return 1;
+}
+
 static uint64_t omap_gpmc_read(void *opaque, target_phys_addr_t addr,
                                unsigned size)
 {
@@ -158,7 +302,7 @@ static uint64_t omap_gpmc_read(void *opaque, target_phys_addr_t addr,
     int cs;
     struct omap_gpmc_cs_file_s *f;
 
-    if (size != 4) {
+    if (size != 4 && gpmc_wordaccess_only(addr)) {
         return omap_badwidth_read32(opaque, addr);
     }
 
@@ -210,7 +354,10 @@ static uint64_t omap_gpmc_read(void *opaque, target_phys_addr_t addr,
             return f->config[5];
         case 0x78:      /* GPMC_CONFIG7 */
             return f->config[6];
-        case 0x84:      /* GPMC_NAND_DATA */
+        case 0x84 ... 0x87: /* GPMC_NAND_DATA */
+            if (omap_gpmc_devtype(f) == OMAP_GPMC_NAND) {
+                return omap_nand_read(f, 0, size);
+            }
             return 0;
         }
         break;
@@ -260,7 +407,7 @@ static void omap_gpmc_write(void *opaque, target_phys_addr_t addr,
     int cs;
     struct omap_gpmc_cs_file_s *f;
 
-    if (size != 4) {
+    if (size != 4 && gpmc_wordaccess_only(addr)) {
         return omap_badwidth_write32(opaque, addr, value);
     }
 
@@ -336,11 +483,23 @@ static void omap_gpmc_write(void *opaque, target_phys_addr_t addr,
                 omap_gpmc_cs_map(s, cs);
             }
             break;
-        case 0x7c:      /* GPMC_NAND_COMMAND */
-        case 0x80:      /* GPMC_NAND_ADDRESS */
-        case 0x84:      /* GPMC_NAND_DATA */
+        case 0x7c ... 0x7f: /* GPMC_NAND_COMMAND */
+            if (omap_gpmc_devtype(f) == OMAP_GPMC_NAND) {
+                nand_setpins(f->dev, 1, 0, 0, 1, 0); /* CLE */
+                omap_nand_setio(f->dev, value, omap_gpmc_devsize(f), size);
+            }
+            break;
+        case 0x80 ... 0x83: /* GPMC_NAND_ADDRESS */
+            if (omap_gpmc_devtype(f) == OMAP_GPMC_NAND) {
+                nand_setpins(f->dev, 0, 1, 0, 1, 0); /* ALE */
+                omap_nand_setio(f->dev, value, omap_gpmc_devsize(f), size);
+            }
+            break;
+        case 0x84 ... 0x87: /* GPMC_NAND_DATA */
+            if (omap_gpmc_devtype(f) == OMAP_GPMC_NAND) {
+                omap_nand_write(f, 0, value, size);
+            }
             break;
-
         default:
             goto bad_reg;
         }
@@ -403,6 +562,7 @@ static const MemoryRegionOps omap_gpmc_ops = {
 struct omap_gpmc_s *omap_gpmc_init(struct omap_mpu_state_s *mpu,
                                    target_phys_addr_t base, qemu_irq irq)
 {
+    int cs;
     struct omap_gpmc_s *s = (struct omap_gpmc_s *)
             g_malloc0(sizeof(struct omap_gpmc_s));
 
@@ -413,6 +573,19 @@ struct omap_gpmc_s *omap_gpmc_init(struct omap_mpu_state_s *mpu,
     s->revision = cpu_class_omap3(mpu) ? 0x50 : 0x20;
     omap_gpmc_reset(s);
 
+    /* We have to register a different IO memory handler for each
+     * chip select region in case a NAND device is mapped there. We
+     * make the region the worst-case size of 256MB and rely on the
+     * container memory region in cs_map to chop it down to the actual
+     * guest-requested size.
+     */
+    for (cs = 0; cs < 8; cs++) {
+        memory_region_init_io(&s->cs_file[cs].nandiomem,
+                              &omap_nand_ops,
+                              &s->cs_file[cs],
+                              "omap-nand",
+                              256 * 1024 * 1024);
+    }
     return s;
 }
 
@@ -428,6 +601,28 @@ void omap_gpmc_attach(struct omap_gpmc_s *s, int cs, MemoryRegion *iomem)
     f = &s->cs_file[cs];
 
     omap_gpmc_cs_unmap(s, cs);
+    f->config[0] &= ~(0xf << 10);
     f->iomem = iomem;
     omap_gpmc_cs_map(s, cs);
 }
+
+void omap_gpmc_attach_nand(struct omap_gpmc_s *s, int cs, DeviceState *nand)
+{
+    struct omap_gpmc_cs_file_s *f;
+    assert(nand);
+
+    if (cs < 0 || cs >= 8) {
+        fprintf(stderr, "%s: bad chip-select %i\n", __func__, cs);
+        exit(-1);
+    }
+    f = &s->cs_file[cs];
+
+    omap_gpmc_cs_unmap(s, cs);
+    f->config[0] &= ~(0xf << 10);
+    f->config[0] |= (OMAP_GPMC_NAND << 10);
+    f->dev = nand;
+    if (nand_getbuswidth(f->dev) == 16) {
+        f->config[0] |= OMAP_GPMC_16BIT << 12;
+    }
+    omap_gpmc_cs_map(s, cs);
+}
commit 9ed3e1b183d720333012f9c93595fc61c7bbf069
Author: Peter Maydell <peter.maydell at linaro.org>
Date:   Sun Aug 28 16:22:19 2011 +0000

    omap_gpmc: Reindent misindented switch statements
    
    Whitespace-only change fixing indentation.
    
    Signed-off-by: Peter Maydell <peter.maydell at linaro.org>

diff --git a/hw/omap_gpmc.c b/hw/omap_gpmc.c
index 5c1365c..c569aa1 100644
--- a/hw/omap_gpmc.c
+++ b/hw/omap_gpmc.c
@@ -196,22 +196,22 @@ static uint64_t omap_gpmc_read(void *opaque, target_phys_addr_t addr,
         addr -= cs * 0x30;
         f = s->cs_file + cs;
         switch (addr) {
-            case 0x60:	/* GPMC_CONFIG1 */
-                return f->config[0];
-            case 0x64:	/* GPMC_CONFIG2 */
-                return f->config[1];
-            case 0x68:	/* GPMC_CONFIG3 */
-                return f->config[2];
-            case 0x6c:	/* GPMC_CONFIG4 */
-                return f->config[3];
-            case 0x70:	/* GPMC_CONFIG5 */
-                return f->config[4];
-            case 0x74:	/* GPMC_CONFIG6 */
-                return f->config[5];
-            case 0x78:	/* GPMC_CONFIG7 */
-                return f->config[6];
-            case 0x84:	/* GPMC_NAND_DATA */
-                return 0;
+        case 0x60:      /* GPMC_CONFIG1 */
+            return f->config[0];
+        case 0x64:      /* GPMC_CONFIG2 */
+            return f->config[1];
+        case 0x68:      /* GPMC_CONFIG3 */
+            return f->config[2];
+        case 0x6c:      /* GPMC_CONFIG4 */
+            return f->config[3];
+        case 0x70:      /* GPMC_CONFIG5 */
+            return f->config[4];
+        case 0x74:      /* GPMC_CONFIG6 */
+            return f->config[5];
+        case 0x78:      /* GPMC_CONFIG7 */
+            return f->config[6];
+        case 0x84:      /* GPMC_NAND_DATA */
+            return 0;
         }
         break;
 
@@ -311,38 +311,38 @@ static void omap_gpmc_write(void *opaque, target_phys_addr_t addr,
         addr -= cs * 0x30;
         f = s->cs_file + cs;
         switch (addr) {
-            case 0x60:	/* GPMC_CONFIG1 */
-                f->config[0] = value & 0xffef3e13;
-                break;
-            case 0x64:	/* GPMC_CONFIG2 */
-                f->config[1] = value & 0x001f1f8f;
-                break;
-            case 0x68:	/* GPMC_CONFIG3 */
-                f->config[2] = value & 0x001f1f8f;
-                break;
-            case 0x6c:	/* GPMC_CONFIG4 */
-                f->config[3] = value & 0x1f8f1f8f;
-                break;
-            case 0x70:	/* GPMC_CONFIG5 */
-                f->config[4] = value & 0x0f1f1f1f;
-                break;
-            case 0x74:	/* GPMC_CONFIG6 */
-                f->config[5] = value & 0x00000fcf;
-                break;
-            case 0x78:	/* GPMC_CONFIG7 */
-                if ((f->config[6] ^ value) & 0xf7f) {
-                    omap_gpmc_cs_unmap(s, cs);
-                    f->config[6] = value & 0x00000f7f;
-                    omap_gpmc_cs_map(s, cs);
-                }
-                break;
-            case 0x7c:	/* GPMC_NAND_COMMAND */
-            case 0x80:	/* GPMC_NAND_ADDRESS */
-            case 0x84:	/* GPMC_NAND_DATA */
-                break;
-
-            default:
-                goto bad_reg;
+        case 0x60:      /* GPMC_CONFIG1 */
+            f->config[0] = value & 0xffef3e13;
+            break;
+        case 0x64:      /* GPMC_CONFIG2 */
+            f->config[1] = value & 0x001f1f8f;
+            break;
+        case 0x68:      /* GPMC_CONFIG3 */
+            f->config[2] = value & 0x001f1f8f;
+            break;
+        case 0x6c:      /* GPMC_CONFIG4 */
+            f->config[3] = value & 0x1f8f1f8f;
+            break;
+        case 0x70:      /* GPMC_CONFIG5 */
+            f->config[4] = value & 0x0f1f1f1f;
+            break;
+        case 0x74:      /* GPMC_CONFIG6 */
+            f->config[5] = value & 0x00000fcf;
+            break;
+        case 0x78:      /* GPMC_CONFIG7 */
+            if ((f->config[6] ^ value) & 0xf7f) {
+                omap_gpmc_cs_unmap(s, cs);
+                f->config[6] = value & 0x00000f7f;
+                omap_gpmc_cs_map(s, cs);
+            }
+            break;
+        case 0x7c:      /* GPMC_NAND_COMMAND */
+        case 0x80:      /* GPMC_NAND_ADDRESS */
+        case 0x84:      /* GPMC_NAND_DATA */
+            break;
+
+        default:
+            goto bad_reg;
         }
         break;
 
commit 7c470ff1eb01605337d2cdba70fde9e8c1012e1a
Author: Juha Riihimäki <juha.riihimaki at nokia.com>
Date:   Sun Aug 28 16:22:19 2011 +0000

    omap_gpmc: Calculate revision from OMAP model
    
    Signed-off-by: Juha Riihimäki <juha.riihimaki at nokia.com>
    [Riku Voipio: Fixes and restructuring patchset]
    Signed-off-by: Riku Voipio <riku.voipio at iki.fi>
    [Peter Maydell: More fixes and cleanups for upstream submission]
    Signed-off-by:  Peter Maydell <peter.maydell at linaro.org>

diff --git a/hw/omap_gpmc.c b/hw/omap_gpmc.c
index c86e7ed..5c1365c 100644
--- a/hw/omap_gpmc.c
+++ b/hw/omap_gpmc.c
@@ -29,6 +29,7 @@ struct omap_gpmc_s {
     qemu_irq irq;
     MemoryRegion iomem;
 
+    uint8_t revision;
     uint8_t sysconfig;
     uint16_t irqst;
     uint16_t irqen;
@@ -163,7 +164,7 @@ static uint64_t omap_gpmc_read(void *opaque, target_phys_addr_t addr,
 
     switch (addr) {
     case 0x000:	/* GPMC_REVISION */
-        return 0x20;
+        return s->revision;
 
     case 0x010:	/* GPMC_SYSCONFIG */
         return s->sysconfig;
@@ -409,6 +410,7 @@ struct omap_gpmc_s *omap_gpmc_init(struct omap_mpu_state_s *mpu,
     memory_region_add_subregion(get_system_memory(), base, &s->iomem);
 
     s->irq = irq;
+    s->revision = cpu_class_omap3(mpu) ? 0x50 : 0x20;
     omap_gpmc_reset(s);
 
     return s;
commit b5325c2739d9795f9462ef87e4080b792835d70a
Author: Juha Riihimäki <juha.riihimaki at nokia.com>
Date:   Sun Aug 28 16:22:19 2011 +0000

    omap_gpmc: Take omap_mpu_state* in omap_gpmc_init
    
    Take a pointer to the omap mpu state struct in omap_gpmc_init.
    Some details of GPMC behaviour depend on the OMAP version we
    are a part of.
    
    Signed-off-by: Juha Riihimäki <juha.riihimaki at nokia.com>
    [Riku Voipio: Fixes and restructuring patchset]
    Signed-off-by: Riku Voipio <riku.voipio at iki.fi>
    [Peter Maydell: More fixes and cleanups for upstream submission]
    Signed-off-by:  Peter Maydell <peter.maydell at linaro.org>

diff --git a/hw/omap.h b/hw/omap.h
index 47c8629..8509c82 100644
--- a/hw/omap.h
+++ b/hw/omap.h
@@ -118,7 +118,8 @@ void omap_sdrc_reset(struct omap_sdrc_s *s);
 
 /* OMAP2 general purpose memory controller */
 struct omap_gpmc_s;
-struct omap_gpmc_s *omap_gpmc_init(target_phys_addr_t base, qemu_irq irq);
+struct omap_gpmc_s *omap_gpmc_init(struct omap_mpu_state_s *mpu,
+                                   target_phys_addr_t base, qemu_irq irq);
 void omap_gpmc_reset(struct omap_gpmc_s *s);
 void omap_gpmc_attach(struct omap_gpmc_s *s, int cs, MemoryRegion *iomem);
 
diff --git a/hw/omap2.c b/hw/omap2.c
index 7e5820a..0feb7a5 100644
--- a/hw/omap2.c
+++ b/hw/omap2.c
@@ -2402,7 +2402,7 @@ struct omap_mpu_state_s *omap2420_mpu_init(unsigned long sdram_size,
     sysbus_mmio_map(busdev, 4, omap_l4_region_base(ta, 5));
 
     s->sdrc = omap_sdrc_init(0x68009000);
-    s->gpmc = omap_gpmc_init(0x6800a000, s->irq[0][OMAP_INT_24XX_GPMC_IRQ]);
+    s->gpmc = omap_gpmc_init(s, 0x6800a000, s->irq[0][OMAP_INT_24XX_GPMC_IRQ]);
 
     dinfo = drive_get(IF_SD, 0, 0);
     if (!dinfo) {
diff --git a/hw/omap_gpmc.c b/hw/omap_gpmc.c
index 9da8491..c86e7ed 100644
--- a/hw/omap_gpmc.c
+++ b/hw/omap_gpmc.c
@@ -399,7 +399,8 @@ static const MemoryRegionOps omap_gpmc_ops = {
     .endianness = DEVICE_NATIVE_ENDIAN,
 };
 
-struct omap_gpmc_s *omap_gpmc_init(target_phys_addr_t base, qemu_irq irq)
+struct omap_gpmc_s *omap_gpmc_init(struct omap_mpu_state_s *mpu,
+                                   target_phys_addr_t base, qemu_irq irq)
 {
     struct omap_gpmc_s *s = (struct omap_gpmc_s *)
             g_malloc0(sizeof(struct omap_gpmc_s));
commit de8af7fe0158493baa1c9a5418ac598a18e86027
Author: Peter Maydell <peter.maydell at linaro.org>
Date:   Sun Aug 28 16:22:19 2011 +0000

    omap_gpmc: Fix handling of FIFOTHRESHOLDSTATUS bit
    
    The OMAP3 TRM is inconsistent about whether the GPMC FIFOTHRESHOLDSTATUS
    bit should be set when FIFOPOINTER > FIFOTHRESHOLD or when it is >=
    FIFOTHRESHOLD. Apparently the underlying functional spec from which
    the TRM was created states that the behaviour is ">=", and this also
    makes more conceptual sense.
    
    Signed-off-by: Peter Maydell <peter.maydell at linaro.org>

diff --git a/hw/omap_gpmc.c b/hw/omap_gpmc.c
index b728397..9da8491 100644
--- a/hw/omap_gpmc.c
+++ b/hw/omap_gpmc.c
@@ -222,7 +222,7 @@ static uint64_t omap_gpmc_read(void *opaque, target_phys_addr_t addr,
         return s->prefcontrol;
     case 0x1f0:	/* GPMC_PREFETCH_STATUS */
         return (s->preffifo << 24) |
-                ((s->preffifo >
+                ((s->preffifo >=
                   ((s->prefconfig[0] >> 8) & 0x7f) ? 1 : 0) << 16) |
                 s->prefcount;
 
commit 77c6c7369035c25d9d4babd920dbe691e3453cfc
Author: Peter Maydell <peter.maydell at linaro.org>
Date:   Sun Aug 28 16:22:18 2011 +0000

    omap_gpmc: Wire up the GPMC IRQ correctly
    
    The omap_gpmc wasn't actually wiring up its IRQ, so
    anything that provoked an interrupt would be using
    uninitialised data for its IRQ number.
    
    Signed-off-by: Peter Maydell <peter.maydell at linaro.org>

diff --git a/hw/omap_gpmc.c b/hw/omap_gpmc.c
index ff4d485..b728397 100644
--- a/hw/omap_gpmc.c
+++ b/hw/omap_gpmc.c
@@ -407,6 +407,7 @@ struct omap_gpmc_s *omap_gpmc_init(target_phys_addr_t base, qemu_irq irq)
     memory_region_init_io(&s->iomem, &omap_gpmc_ops, s, "omap-gpmc", 0x1000);
     memory_region_add_subregion(get_system_memory(), base, &s->iomem);
 
+    s->irq = irq;
     omap_gpmc_reset(s);
 
     return s;
commit 9c8255e12422771cdecbb3bf538f0732be629e2a
Author: Peter Maydell <peter.maydell at linaro.org>
Date:   Sun Aug 28 16:22:18 2011 +0000

    omap_gpmc: GPMC_IRQSTATUS is write-one-to-clear
    
    Fix a bug in the handling of writes to GPMC_IRQSTATUS:
    it behaves as "write one to clear, writing zero is ignored".
    
    Signed-off-by: Peter Maydell <peter.maydell at linaro.org>

diff --git a/hw/omap_gpmc.c b/hw/omap_gpmc.c
index d16b28b..ff4d485 100644
--- a/hw/omap_gpmc.c
+++ b/hw/omap_gpmc.c
@@ -284,7 +284,7 @@ static void omap_gpmc_write(void *opaque, target_phys_addr_t addr,
         break;
 
     case 0x018:	/* GPMC_IRQSTATUS */
-        s->irqen = ~value;
+        s->irqen &= ~value;
         omap_gpmc_int_update(s);
         break;
 
commit 3387bf5581df66c2cfb0d399d73c80f3cc3be198
Author: Peter Maydell <peter.maydell at linaro.org>
Date:   Sun Aug 28 16:22:18 2011 +0000

    omap_gpmc: Refactor omap_gpmc_cs_map and omap_gpmc_cs_unmap
    
    Refactor the omap_gpmc_cs_map/unmap functions:
     * take the omap_gpmc_s* and a chipselect id rather than the
       omap_gpmc_cs_file_s*, so they have access to the general gpmc
       member fields
     * extract the base and mask from the config registers in the functions
       rather than at every callsite
     * check for CSVALID in the functions rather than at every callsite
    
    Signed-off-by: Peter Maydell <peter.maydell at linaro.org>

diff --git a/hw/omap_gpmc.c b/hw/omap_gpmc.c
index 19f246c..d16b28b 100644
--- a/hw/omap_gpmc.c
+++ b/hw/omap_gpmc.c
@@ -54,18 +54,25 @@ static void omap_gpmc_int_update(struct omap_gpmc_s *s)
     qemu_set_irq(s->irq, s->irqen & s->irqst);
 }
 
-static void omap_gpmc_cs_map(struct omap_gpmc_cs_file_s *f, int base, int mask)
+static void omap_gpmc_cs_map(struct omap_gpmc_s *s, int cs)
 {
+    struct omap_gpmc_cs_file_s *f = &s->cs_file[cs];
+    uint32_t mask = (f->config[6] >> 8) & 0xf;
+    uint32_t base = f->config[6] & 0x3f;
     uint32_t size;
 
     if (!f->iomem) {
         return;
     }
 
+    if (!(f->config[6] & (1 << 6))) {
+        /* Do nothing unless CSVALID */
+        return;
+    }
+
     /* TODO: check for overlapping regions and report access errors */
     if ((mask != 0x8 && mask != 0xc && mask != 0xe && mask != 0xf) ||
-                    (base < 0 || base >= 0x40) ||
-                    (base & 0x0f & ~mask)) {
+        (base & 0x0f & ~mask)) {
         fprintf(stderr, "%s: wrong cs address mapping/decoding!\n",
                         __FUNCTION__);
         return;
@@ -83,8 +90,13 @@ static void omap_gpmc_cs_map(struct omap_gpmc_cs_file_s *f, int base, int mask)
                                 &f->container);
 }
 
-static void omap_gpmc_cs_unmap(struct omap_gpmc_cs_file_s *f)
+static void omap_gpmc_cs_unmap(struct omap_gpmc_s *s, int cs)
 {
+    struct omap_gpmc_cs_file_s *f = &s->cs_file[cs];
+    if (!(f->config[6] & (1 << 6))) {
+        /* Do nothing unless CSVALID */
+        return;
+    }
     if (!f->iomem) {
         return;
     }
@@ -110,19 +122,26 @@ void omap_gpmc_reset(struct omap_gpmc_s *s)
     s->preffifo = 0;
     s->prefcount = 0;
     for (i = 0; i < 8; i ++) {
-        if (s->cs_file[i].config[6] & (1 << 6))			/* CSVALID */
-            omap_gpmc_cs_unmap(s->cs_file + i);
-        s->cs_file[i].config[0] = i ? 1 << 12 : 0;
+        omap_gpmc_cs_unmap(s, i);
         s->cs_file[i].config[1] = 0x101001;
         s->cs_file[i].config[2] = 0x020201;
         s->cs_file[i].config[3] = 0x10031003;
         s->cs_file[i].config[4] = 0x10f1111;
         s->cs_file[i].config[5] = 0;
         s->cs_file[i].config[6] = 0xf00 | (i ? 0 : 1 << 6);
-        if (s->cs_file[i].config[6] & (1 << 6))			/* CSVALID */
-            omap_gpmc_cs_map(&s->cs_file[i],
-                            s->cs_file[i].config[6] & 0x1f,	/* MASKADDR */
-                        (s->cs_file[i].config[6] >> 8 & 0xf));	/* BASEADDR */
+
+        s->cs_file[i].config[6] = 0xf00;
+        /* In theory we could probe attached devices for some CFG1
+         * bits here, but we just retain them across resets as they
+         * were set initially by omap_gpmc_attach().
+         */
+        if (i == 0) {
+            s->cs_file[i].config[0] &= 0x00433e00;
+            s->cs_file[i].config[6] |= 1 << 6; /* CSVALID */
+            omap_gpmc_cs_map(s, i);
+        } else {
+            s->cs_file[i].config[0] &= 0x00403c00;
+        }
     }
     s->ecc_cs = 0;
     s->ecc_ptr = 0;
@@ -311,13 +330,10 @@ static void omap_gpmc_write(void *opaque, target_phys_addr_t addr,
                 break;
             case 0x78:	/* GPMC_CONFIG7 */
                 if ((f->config[6] ^ value) & 0xf7f) {
-                    if (f->config[6] & (1 << 6))		/* CSVALID */
-                        omap_gpmc_cs_unmap(f);
-                    if (value & (1 << 6))			/* CSVALID */
-                        omap_gpmc_cs_map(f, value & 0x1f,	/* MASKADDR */
-                                        (value >> 8 & 0xf));	/* BASEADDR */
+                    omap_gpmc_cs_unmap(s, cs);
+                    f->config[6] = value & 0x00000f7f;
+                    omap_gpmc_cs_map(s, cs);
                 }
-                f->config[6] = value & 0x00000f7f;
                 break;
             case 0x7c:	/* GPMC_NAND_COMMAND */
             case 0x80:	/* GPMC_NAND_ADDRESS */
@@ -407,9 +423,7 @@ void omap_gpmc_attach(struct omap_gpmc_s *s, int cs, MemoryRegion *iomem)
     }
     f = &s->cs_file[cs];
 
+    omap_gpmc_cs_unmap(s, cs);
     f->iomem = iomem;
-
-    if (f->config[6] & (1 << 6))				/* CSVALID */
-        omap_gpmc_cs_map(f, f->config[6] & 0x1f,		/* MASKADDR */
-                        (f->config[6] >> 8 & 0xf));		/* BASEADDR */
+    omap_gpmc_cs_map(s, cs);
 }
commit 07bc2f807768d85e98f50de2e5f8115743277381
Author: Peter Maydell <peter.maydell at linaro.org>
Date:   Sun Aug 28 16:22:18 2011 +0000

    omap_gpmc: Clean up omap_gpmc_attach MemoryRegion conversion
    
    Now that all callers of omap_gpmc_attach pass in a MemoryRegion*,
    we can remove the base_update and unmap function pointer arguments,
    and the opaque pointer that was passed into these callbacks.
    
    We can also remove the base and size fields from omap_gpmc_cs_file_s
    as these are no longer necessary (you don't need the base/size
    to unmap a MemoryRegion the way you did to undo a mapping made
    with cpu_register_physical_memory()).
    
    Signed-off-by: Peter Maydell <peter.maydell at linaro.org>

diff --git a/hw/nseries.c b/hw/nseries.c
index 7e1ad34..f7ace99 100644
--- a/hw/nseries.c
+++ b/hw/nseries.c
@@ -182,9 +182,7 @@ static void n8x0_nand_setup(struct n800_s *s)
     sysbus_connect_irq(sysbus_from_qdev(s->nand), 0,
                        qdev_get_gpio_in(s->cpu->gpio, N8X0_ONENAND_GPIO));
     omap_gpmc_attach(s->cpu->gpmc, N8X0_ONENAND_CS,
-                     sysbus_mmio_get_region(sysbus_from_qdev(s->nand), 0),
-                     NULL, NULL,
-                     s->nand);
+                     sysbus_mmio_get_region(sysbus_from_qdev(s->nand), 0));
     otp_region = onenand_raw_otp(s->nand);
 
     memcpy(otp_region + 0x000, n8x0_cal_wlan_mac, sizeof(n8x0_cal_wlan_mac));
@@ -781,10 +779,8 @@ static void n8x0_usb_setup(struct n800_s *s)
     TUSBState *tusb = tusb6010_init(tusb_irq);
 
     /* Using the NOR interface */
-    omap_gpmc_attach(s->cpu->gpmc, N8X0_USB_ASYNC_CS,
-                    tusb6010_async_io(tusb), NULL, NULL, tusb);
-    omap_gpmc_attach(s->cpu->gpmc, N8X0_USB_SYNC_CS,
-                    tusb6010_sync_io(tusb), NULL, NULL, tusb);
+    omap_gpmc_attach(s->cpu->gpmc, N8X0_USB_ASYNC_CS, tusb6010_async_io(tusb));
+    omap_gpmc_attach(s->cpu->gpmc, N8X0_USB_SYNC_CS, tusb6010_sync_io(tusb));
 
     s->usb = tusb;
     qdev_connect_gpio_out(s->cpu->gpio, N8X0_TUSB_ENABLE_GPIO, tusb_pwr);
diff --git a/hw/omap.h b/hw/omap.h
index db101c6..47c8629 100644
--- a/hw/omap.h
+++ b/hw/omap.h
@@ -120,9 +120,7 @@ void omap_sdrc_reset(struct omap_sdrc_s *s);
 struct omap_gpmc_s;
 struct omap_gpmc_s *omap_gpmc_init(target_phys_addr_t base, qemu_irq irq);
 void omap_gpmc_reset(struct omap_gpmc_s *s);
-void omap_gpmc_attach(struct omap_gpmc_s *s, int cs, MemoryRegion *iomem,
-                void (*base_upd)(void *opaque, target_phys_addr_t new),
-                void (*unmap)(void *opaque), void *opaque);
+void omap_gpmc_attach(struct omap_gpmc_s *s, int cs, MemoryRegion *iomem);
 
 /*
  * Common IRQ numbers for level 1 interrupt handler
diff --git a/hw/omap_gpmc.c b/hw/omap_gpmc.c
index 673dddd..19f246c 100644
--- a/hw/omap_gpmc.c
+++ b/hw/omap_gpmc.c
@@ -40,13 +40,8 @@ struct omap_gpmc_s {
     int prefcount;
     struct omap_gpmc_cs_file_s {
         uint32_t config[7];
-        target_phys_addr_t base;
-        size_t size;
         MemoryRegion *iomem;
         MemoryRegion container;
-        void (*base_update)(void *opaque, target_phys_addr_t new);
-        void (*unmap)(void *opaque);
-        void *opaque;
     } cs_file[8];
     int ecc_cs;
     int ecc_ptr;
@@ -61,6 +56,12 @@ static void omap_gpmc_int_update(struct omap_gpmc_s *s)
 
 static void omap_gpmc_cs_map(struct omap_gpmc_cs_file_s *f, int base, int mask)
 {
+    uint32_t size;
+
+    if (!f->iomem) {
+        return;
+    }
+
     /* TODO: check for overlapping regions and report access errors */
     if ((mask != 0x8 && mask != 0xc && mask != 0xe && mask != 0xf) ||
                     (base < 0 || base >= 0x40) ||
@@ -70,39 +71,27 @@ static void omap_gpmc_cs_map(struct omap_gpmc_cs_file_s *f, int base, int mask)
         return;
     }
 
-    if (!f->opaque)
-        return;
-
-    f->base = base << 24;
-    f->size = (0x0fffffff & ~(mask << 24)) + 1;
+    base <<= 24;
+    size = (0x0fffffff & ~(mask << 24)) + 1;
     /* TODO: rather than setting the size of the mapping (which should be
      * constant), the mask should cause wrapping of the address space, so
      * that the same memory becomes accessible at every <i>size</i> bytes
      * starting from <i>base</i>.  */
-    if (f->iomem) {
-        memory_region_init(&f->container, "omap-gpmc-file", f->size);
-        memory_region_add_subregion(&f->container, 0, f->iomem);
-        memory_region_add_subregion(get_system_memory(), f->base,
-                                    &f->container);
-    }
-
-    if (f->base_update)
-        f->base_update(f->opaque, f->base);
+    memory_region_init(&f->container, "omap-gpmc-file", size);
+    memory_region_add_subregion(&f->container, 0, f->iomem);
+    memory_region_add_subregion(get_system_memory(), base,
+                                &f->container);
 }
 
 static void omap_gpmc_cs_unmap(struct omap_gpmc_cs_file_s *f)
 {
-    if (f->size) {
-        if (f->unmap)
-            f->unmap(f->opaque);
-        if (f->iomem) {
-            memory_region_del_subregion(get_system_memory(), &f->container);
-            memory_region_del_subregion(&f->container, f->iomem);
-            memory_region_destroy(&f->container);
-        }
-        f->base = 0;
-        f->size = 0;
+    if (!f->iomem) {
+        return;
     }
+
+    memory_region_del_subregion(get_system_memory(), &f->container);
+    memory_region_del_subregion(&f->container, f->iomem);
+    memory_region_destroy(&f->container);
 }
 
 void omap_gpmc_reset(struct omap_gpmc_s *s)
@@ -399,19 +388,18 @@ struct omap_gpmc_s *omap_gpmc_init(target_phys_addr_t base, qemu_irq irq)
     struct omap_gpmc_s *s = (struct omap_gpmc_s *)
             g_malloc0(sizeof(struct omap_gpmc_s));
 
-    omap_gpmc_reset(s);
-
     memory_region_init_io(&s->iomem, &omap_gpmc_ops, s, "omap-gpmc", 0x1000);
     memory_region_add_subregion(get_system_memory(), base, &s->iomem);
 
+    omap_gpmc_reset(s);
+
     return s;
 }
 
-void omap_gpmc_attach(struct omap_gpmc_s *s, int cs, MemoryRegion *iomem,
-                void (*base_upd)(void *opaque, target_phys_addr_t new),
-                void (*unmap)(void *opaque), void *opaque)
+void omap_gpmc_attach(struct omap_gpmc_s *s, int cs, MemoryRegion *iomem)
 {
     struct omap_gpmc_cs_file_s *f;
+    assert(iomem);
 
     if (cs < 0 || cs >= 8) {
         fprintf(stderr, "%s: bad chip-select %i\n", __FUNCTION__, cs);
@@ -420,9 +408,6 @@ void omap_gpmc_attach(struct omap_gpmc_s *s, int cs, MemoryRegion *iomem,
     f = &s->cs_file[cs];
 
     f->iomem = iomem;
-    f->base_update = base_upd;
-    f->unmap = unmap;
-    f->opaque = opaque;
 
     if (f->config[6] & (1 << 6))				/* CSVALID */
         omap_gpmc_cs_map(f, f->config[6] & 0x1f,		/* MASKADDR */
commit 7c00b9de8b1cdb18d3ba0d6759abea3776d7e05b
Author: Juha Riihimäki <juha.riihimaki at nokia.com>
Date:   Sun Aug 28 16:22:17 2011 +0000

    hw/onenand: Minor spacing fixes
    
    Minor whitespace-only cleanup (separated out from the qdevifying
    patch for clarity).
    
    Signed-off-by: Juha Riihimäki <juha.riihimaki at nokia.com>
    [Riku Voipio: Fixes and restructuring patchset]
    Signed-off-by: Riku Voipio <riku.voipio at iki.fi>
    [Peter Maydell: More fixes and cleanups for upstream submission]
    Signed-off-by:  Peter Maydell <peter.maydell at linaro.org>

diff --git a/hw/onenand.c b/hw/onenand.c
index 720c4cf..6f68f70 100644
--- a/hw/onenand.c
+++ b/hw/onenand.c
@@ -245,8 +245,8 @@ static inline int onenand_prog_main(OneNANDState *s, int sec, int secn,
     int result = 0;
 
     if (secn > 0) {
-        uint32_t size = (uint32_t) secn * 512;
-        const uint8_t *sp = (const uint8_t *) src;
+        uint32_t size = (uint32_t)secn * 512;
+        const uint8_t *sp = (const uint8_t *)src;
         uint8_t *dp = 0;
         if (s->bdrv_cur) {
             dp = g_malloc(size);
@@ -257,7 +257,7 @@ static inline int onenand_prog_main(OneNANDState *s, int sec, int secn,
             if (sec + secn > s->secs_cur) {
                 result = 1;
             } else {
-                dp = (uint8_t *) s->current + (sec << 9);
+                dp = (uint8_t *)s->current + (sec << 9);
             }
         }
         if (!result) {
@@ -299,13 +299,13 @@ static inline int onenand_prog_spare(OneNANDState *s, int sec, int secn,
 {
     int result = 0;
     if (secn > 0) {
-        const uint8_t *sp = (const uint8_t *) src;
+        const uint8_t *sp = (const uint8_t *)src;
         uint8_t *dp = 0, *dpp = 0;
         if (s->bdrv_cur) {
             dp = g_malloc(512);
             if (!dp || bdrv_read(s->bdrv_cur,
-                                s->secs_cur + (sec >> 5),
-                                dp, 1) < 0) {
+                                 s->secs_cur + (sec >> 5),
+                                 dp, 1) < 0) {
                 result = 1;
             } else {
                 dpp = dp + ((sec & 31) << 4);
@@ -324,7 +324,7 @@ static inline int onenand_prog_spare(OneNANDState *s, int sec, int secn,
             }
             if (s->bdrv_cur) {
                 result = bdrv_write(s->bdrv_cur, s->secs_cur + (sec >> 5),
-                                dp, 1) < 0;
+                                    dp, 1) < 0;
             }
         }
         if (dp) {
commit 500954e35cac9dd4544a023d482804186b7f7383
Author: Juha Riihimäki <juha.riihimaki at nokia.com>
Date:   Sun Aug 28 16:22:17 2011 +0000

    hw/onenand: Qdevify
    
    Qdevify the ONENAND device.
    
    Signed-off-by: Juha Riihimäki <juha.riihimaki at nokia.com>
    [Riku Voipio: Fixes and restructuring patchset]
    Signed-off-by: Riku Voipio <riku.voipio at iki.fi>
    [Peter Maydell: More fixes and cleanups for upstream submission]
    Signed-off-by:  Peter Maydell <peter.maydell at linaro.org>

diff --git a/hw/flash.h b/hw/flash.h
index 140ae39..270be5e 100644
--- a/hw/flash.h
+++ b/hw/flash.h
@@ -36,12 +36,7 @@ uint32_t nand_getbuswidth(DeviceState *dev);
 #define NAND_MFR_MICRON		0x2c
 
 /* onenand.c */
-void onenand_base_update(void *opaque, target_phys_addr_t new);
-void onenand_base_unmap(void *opaque);
-void *onenand_init(BlockDriverState *bdrv,
-                uint16_t man_id, uint16_t dev_id, uint16_t ver_id,
-                int regshift, qemu_irq irq);
-void *onenand_raw_otp(void *opaque);
+void *onenand_raw_otp(DeviceState *onenand_device);
 
 /* ecc.c */
 typedef struct {
diff --git a/hw/nseries.c b/hw/nseries.c
index f7aae7a..7e1ad34 100644
--- a/hw/nseries.c
+++ b/hw/nseries.c
@@ -33,6 +33,7 @@
 #include "loader.h"
 #include "blockdev.h"
 #include "tusb6010.h"
+#include "sysbus.h"
 
 /* Nokia N8x0 support */
 struct n800_s {
@@ -52,7 +53,7 @@ struct n800_s {
     TUSBState *usb;
     void *retu;
     void *tahvo;
-    void *nand;
+    DeviceState *nand;
 };
 
 /* GPIO pins */
@@ -167,13 +168,23 @@ static void n8x0_nand_setup(struct n800_s *s)
     char *otp_region;
     DriveInfo *dinfo;
 
-    dinfo = drive_get(IF_MTD, 0, 0);
+    s->nand = qdev_create(NULL, "onenand");
+    qdev_prop_set_uint16(s->nand, "manufacturer_id", NAND_MFR_SAMSUNG);
     /* Either 0x40 or 0x48 are OK for the device ID */
-    s->nand = onenand_init(dinfo ? dinfo->bdrv : 0,
-                    NAND_MFR_SAMSUNG, 0x48, 0, 1,
-                    qdev_get_gpio_in(s->cpu->gpio, N8X0_ONENAND_GPIO));
-    omap_gpmc_attach(s->cpu->gpmc, N8X0_ONENAND_CS, 0, onenand_base_update,
-                    onenand_base_unmap, s->nand);
+    qdev_prop_set_uint16(s->nand, "device_id", 0x48);
+    qdev_prop_set_uint16(s->nand, "version_id", 0);
+    qdev_prop_set_int32(s->nand, "shift", 1);
+    dinfo = drive_get(IF_MTD, 0, 0);
+    if (dinfo && dinfo->bdrv) {
+        qdev_prop_set_drive_nofail(s->nand, "drive", dinfo->bdrv);
+    }
+    qdev_init_nofail(s->nand);
+    sysbus_connect_irq(sysbus_from_qdev(s->nand), 0,
+                       qdev_get_gpio_in(s->cpu->gpio, N8X0_ONENAND_GPIO));
+    omap_gpmc_attach(s->cpu->gpmc, N8X0_ONENAND_CS,
+                     sysbus_mmio_get_region(sysbus_from_qdev(s->nand), 0),
+                     NULL, NULL,
+                     s->nand);
     otp_region = onenand_raw_otp(s->nand);
 
     memcpy(otp_region + 0x000, n8x0_cal_wlan_mac, sizeof(n8x0_cal_wlan_mac));
diff --git a/hw/onenand.c b/hw/onenand.c
index 1706842..720c4cf 100644
--- a/hw/onenand.c
+++ b/hw/onenand.c
@@ -25,6 +25,7 @@
 #include "blockdev.h"
 #include "memory.h"
 #include "exec-memory.h"
+#include "sysbus.h"
 
 /* 11 for 2kB-page OneNAND ("2nd generation") and 10 for 1kB-page chips */
 #define PAGE_SHIFT	11
@@ -33,6 +34,7 @@
 #define BLOCK_SHIFT	(PAGE_SHIFT + 6)
 
 typedef struct {
+    SysBusDevice busdev;
     struct {
         uint16_t man;
         uint16_t dev;
@@ -49,6 +51,7 @@ typedef struct {
     uint8_t *current;
     MemoryRegion ram;
     MemoryRegion mapped_ram;
+    uint8_t current_direction;
     uint8_t *boot[2];
     uint8_t *data[2][2];
     MemoryRegion iomem;
@@ -120,27 +123,72 @@ static void onenand_mem_setup(OneNANDState *s)
                                         1);
 }
 
-void onenand_base_update(void *opaque, target_phys_addr_t new)
+static void onenand_intr_update(OneNANDState *s)
 {
-    OneNANDState *s = (OneNANDState *) opaque;
-
-    s->base = new;
-
-    memory_region_add_subregion(get_system_memory(), s->base, &s->container);
+    qemu_set_irq(s->intr, ((s->intstatus >> 15) ^ (~s->config[0] >> 6)) & 1);
 }
 
-void onenand_base_unmap(void *opaque)
+static void onenand_pre_save(void *opaque)
 {
-    OneNANDState *s = (OneNANDState *) opaque;
-
-    memory_region_del_subregion(get_system_memory(), &s->container);
+    OneNANDState *s = opaque;
+    if (s->current == s->otp) {
+        s->current_direction = 1;
+    } else if (s->current == s->image) {
+        s->current_direction = 2;
+    } else {
+        s->current_direction = 0;
+    }
 }
 
-static void onenand_intr_update(OneNANDState *s)
+static int onenand_post_load(void *opaque, int version_id)
 {
-    qemu_set_irq(s->intr, ((s->intstatus >> 15) ^ (~s->config[0] >> 6)) & 1);
+    OneNANDState *s = opaque;
+    switch (s->current_direction) {
+    case 0:
+        break;
+    case 1:
+        s->current = s->otp;
+        break;
+    case 2:
+        s->current = s->image;
+        break;
+    default:
+        return -1;
+    }
+    onenand_intr_update(s);
+    return 0;
 }
 
+static const VMStateDescription vmstate_onenand = {
+    .name = "onenand",
+    .version_id = 1,
+    .minimum_version_id = 1,
+    .minimum_version_id_old = 1,
+    .pre_save = onenand_pre_save,
+    .post_load = onenand_post_load,
+    .fields = (VMStateField[]) {
+        VMSTATE_UINT8(current_direction, OneNANDState),
+        VMSTATE_INT32(cycle, OneNANDState),
+        VMSTATE_INT32(otpmode, OneNANDState),
+        VMSTATE_UINT16_ARRAY(addr, OneNANDState, 8),
+        VMSTATE_UINT16_ARRAY(unladdr, OneNANDState, 8),
+        VMSTATE_INT32(bufaddr, OneNANDState),
+        VMSTATE_INT32(count, OneNANDState),
+        VMSTATE_UINT16(command, OneNANDState),
+        VMSTATE_UINT16_ARRAY(config, OneNANDState, 2),
+        VMSTATE_UINT16(status, OneNANDState),
+        VMSTATE_UINT16(intstatus, OneNANDState),
+        VMSTATE_UINT16(wpstatus, OneNANDState),
+        VMSTATE_INT32(secs_cur, OneNANDState),
+        VMSTATE_PARTIAL_VBUFFER(blockwp, OneNANDState, blocks),
+        VMSTATE_UINT8(ecc.cp, OneNANDState),
+        VMSTATE_UINT16_ARRAY(ecc.lp, OneNANDState, 2),
+        VMSTATE_UINT16(ecc.count, OneNANDState),
+        VMSTATE_BUFFER_UNSAFE(otp, OneNANDState, 0, ((64 + 2) << PAGE_SHIFT)),
+        VMSTATE_END_OF_LIST()
+    }
+};
+
 /* Hot reset (Reset OneNAND command) or warm reset (RP pin low) */
 static void onenand_reset(OneNANDState *s, int cold)
 {
@@ -167,11 +215,17 @@ static void onenand_reset(OneNANDState *s, int cold)
         /* Lock the whole flash */
         memset(s->blockwp, ONEN_LOCK_LOCKED, s->blocks);
 
-        if (s->bdrv && bdrv_read(s->bdrv, 0, s->boot[0], 8) < 0)
-            hw_error("%s: Loading the BootRAM failed.\n", __FUNCTION__);
+        if (s->bdrv_cur && bdrv_read(s->bdrv_cur, 0, s->boot[0], 8) < 0) {
+            hw_error("%s: Loading the BootRAM failed.\n", __func__);
+        }
     }
 }
 
+static void onenand_system_reset(DeviceState *dev)
+{
+    onenand_reset(FROM_SYSBUS(OneNANDState, sysbus_from_qdev(dev)), 1);
+}
+
 static inline int onenand_load_main(OneNANDState *s, int sec, int secn,
                 void *dest)
 {
@@ -700,30 +754,25 @@ static const MemoryRegionOps onenand_ops = {
     .endianness = DEVICE_NATIVE_ENDIAN,
 };
 
-void *onenand_init(BlockDriverState *bdrv,
-                uint16_t man_id, uint16_t dev_id, uint16_t ver_id,
-                int regshift, qemu_irq irq)
+static int onenand_initfn(SysBusDevice *dev)
 {
-    OneNANDState *s = (OneNANDState *) g_malloc0(sizeof(*s));
-    uint32_t size = 1 << (24 + ((dev_id >> 4) & 7));
+    OneNANDState *s = (OneNANDState *)dev;
+    uint32_t size = 1 << (24 + ((s->id.dev >> 4) & 7));
     void *ram;
-
-    s->shift = regshift;
-    s->intr = irq;
+    s->base = (target_phys_addr_t)-1;
     s->rdy = NULL;
-    s->id.man = man_id;
-    s->id.dev = dev_id;
-    s->id.ver = ver_id;
     s->blocks = size >> BLOCK_SHIFT;
     s->secs = size >> 9;
     s->blockwp = g_malloc(s->blocks);
-    s->density_mask = (dev_id & 0x08) ? (1 << (6 + ((dev_id >> 4) & 7))) : 0;
+    s->density_mask = (s->id.dev & 0x08)
+        ? (1 << (6 + ((s->id.dev >> 4) & 7))) : 0;
     memory_region_init_io(&s->iomem, &onenand_ops, s, "onenand",
                           0x10000 << s->shift);
-    s->bdrv = bdrv;
     if (!s->bdrv) {
         s->image = memset(g_malloc(size + (size >> 5)),
-                        0xff, size + (size >> 5));
+                          0xff, size + (size >> 5));
+    } else {
+        s->bdrv_cur = s->bdrv;
     }
     s->otp = memset(g_malloc((64 + 2) << PAGE_SHIFT),
                     0xff, (64 + 2) << PAGE_SHIFT);
@@ -736,15 +785,40 @@ void *onenand_init(BlockDriverState *bdrv,
     s->data[1][0] = ram + ((0x0200 + (1 << (PAGE_SHIFT - 1))) << s->shift);
     s->data[1][1] = ram + ((0x8010 + (1 << (PAGE_SHIFT - 6))) << s->shift);
     onenand_mem_setup(s);
+    sysbus_init_irq(dev, &s->intr);
+    sysbus_init_mmio_region(dev, &s->container);
+    vmstate_register(&dev->qdev,
+                     ((s->shift & 0x7f) << 24)
+                     | ((s->id.man & 0xff) << 16)
+                     | ((s->id.dev & 0xff) << 8)
+                     | (s->id.ver & 0xff),
+                     &vmstate_onenand, s);
+    return 0;
+}
 
-    onenand_reset(s, 1);
+static SysBusDeviceInfo onenand_info = {
+    .init = onenand_initfn,
+    .qdev.name = "onenand",
+    .qdev.size = sizeof(OneNANDState),
+    .qdev.reset = onenand_system_reset,
+    .qdev.props = (Property[]) {
+        DEFINE_PROP_UINT16("manufacturer_id", OneNANDState, id.man, 0),
+        DEFINE_PROP_UINT16("device_id", OneNANDState, id.dev, 0),
+        DEFINE_PROP_UINT16("version_id", OneNANDState, id.ver, 0),
+        DEFINE_PROP_INT32("shift", OneNANDState, shift, 0),
+        DEFINE_PROP_DRIVE("drive", OneNANDState, bdrv),
+        DEFINE_PROP_END_OF_LIST()
+    }
+};
 
-    return s;
+static void onenand_register_device(void)
+{
+    sysbus_register_withprop(&onenand_info);
 }
 
-void *onenand_raw_otp(void *opaque)
+void *onenand_raw_otp(DeviceState *onenand_device)
 {
-    OneNANDState *s = (OneNANDState *) opaque;
-
-    return s->otp;
+    return FROM_SYSBUS(OneNANDState, sysbus_from_qdev(onenand_device))->otp;
 }
+
+device_init(onenand_register_device)
commit 82866965e98030b780d6097af27afe347583f45e
Author: Juha Riihimäki <juha.riihimaki at nokia.com>
Date:   Sun Aug 28 16:33:02 2011 +0000

    hw/onenand: Remove unnecessary argument from onenand_command()
    
    Refactor onenand_command() -- since it is essentially a method of
    the device object, it doesn't make sense to pass in something as
    an argument which is one of the object's own member fields.
    
    Signed-off-by: Juha Riihimäki <juha.riihimaki at nokia.com>
    [Riku Voipio: Fixes and restructuring patchset]
    Signed-off-by: Riku Voipio <riku.voipio at iki.fi>
    [Peter Maydell: More fixes and cleanups for upstream submission]
    Signed-off-by:  Peter Maydell <peter.maydell at linaro.org>

diff --git a/hw/onenand.c b/hw/onenand.c
index 00276a0..1706842 100644
--- a/hw/onenand.c
+++ b/hw/onenand.c
@@ -326,7 +326,7 @@ fail:
     return 1;
 }
 
-static void onenand_command(OneNANDState *s, int cmd)
+static void onenand_command(OneNANDState *s)
 {
     int b;
     int sec;
@@ -346,7 +346,7 @@ static void onenand_command(OneNANDState *s, int cmd)
             s->data[(s->bufaddr >> 2) & 1][1] : s->boot[1];	\
     buf += (s->bufaddr & 3) << 4;
 
-    switch (cmd) {
+    switch (s->command) {
     case 0x00:	/* Load single/multiple sector data unit into buffer */
         SETADDR(ONEN_BUF_BLOCK, ONEN_BUF_PAGE)
 
@@ -527,7 +527,7 @@ static void onenand_command(OneNANDState *s, int cmd)
         s->status |= ONEN_ERR_CMD;
         s->intstatus |= ONEN_INT;
         fprintf(stderr, "%s: unknown OneNAND command %x\n",
-                        __FUNCTION__, cmd);
+                        __func__, s->command);
     }
 
     onenand_intr_update(s);
@@ -659,7 +659,7 @@ static void onenand_write(void *opaque, target_phys_addr_t addr,
         if (s->intstatus & (1 << 15))
             break;
         s->command = value;
-        onenand_command(s, s->command);
+        onenand_command(s);
         break;
     case 0xf221:	/* System Configuration 1 */
         s->config[0] = value;
commit 46c305ef6b0d1ed6c85e863568fccc03caf7f75e
Author: Peter Maydell <peter.maydell at linaro.org>
Date:   Sun Aug 28 16:22:17 2011 +0000

    hw/sysbus: Add sysbus_mmio_get_region()
    
    Add a sysbus_mmio_get_region() which allows users of sysbus
    devices to turn a (SysBusDevice*, mmioidx) tuple into a
    MemoryRegion*. This enables some useful simplifications of
    devices which pass through another device's mmio region
    (either directly or by implementing some kind of memory
    controller device).
    
    Signed-off-by: Peter Maydell <peter.maydell at linaro.org>

diff --git a/hw/sysbus.c b/hw/sysbus.c
index f39768b..c365d39 100644
--- a/hw/sysbus.c
+++ b/hw/sysbus.c
@@ -131,6 +131,11 @@ void sysbus_init_mmio_region(SysBusDevice *dev, MemoryRegion *memory)
     dev->mmio[n].memory = memory;
 }
 
+MemoryRegion *sysbus_mmio_get_region(SysBusDevice *dev, int n)
+{
+    return dev->mmio[n].memory;
+}
+
 void sysbus_init_ioports(SysBusDevice *dev, pio_addr_t ioport, pio_addr_t size)
 {
     pio_addr_t i;
diff --git a/hw/sysbus.h b/hw/sysbus.h
index b87c6c5..aa3d383 100644
--- a/hw/sysbus.h
+++ b/hw/sysbus.h
@@ -50,6 +50,7 @@ void sysbus_init_mmio(SysBusDevice *dev, target_phys_addr_t size,
 void sysbus_init_mmio_cb2(SysBusDevice *dev,
                           mmio_mapfunc cb, mmio_mapfunc unmap);
 void sysbus_init_mmio_region(SysBusDevice *dev, MemoryRegion *memory);
+MemoryRegion *sysbus_mmio_get_region(SysBusDevice *dev, int n);
 void sysbus_init_irq(SysBusDevice *dev, qemu_irq *p);
 void sysbus_pass_irq(SysBusDevice *dev, SysBusDevice *target);
 void sysbus_init_ioports(SysBusDevice *dev, pio_addr_t ioport, pio_addr_t size);
commit 73c92f9aecc099aa81ee05a2bdb30bb43184cc28
Author: Avi Kivity <avi at redhat.com>
Date:   Sun Aug 28 18:17:04 2011 +0300

    sh_pci: Fix sh_pci memory alias confusion
    
    The a7 area was set up as an alias of itself, rather than the p4 area.  This
    sent the memory core into infinite recursion.
    
    Fix by aliasing the a7 area to the p4 area.
    
    Signed-off-by: Avi Kivity <avi at redhat.com>

diff --git a/hw/sh_pci.c b/hw/sh_pci.c
index 76061bb..36f3930 100644
--- a/hw/sh_pci.c
+++ b/hw/sh_pci.c
@@ -150,7 +150,7 @@ static int sh_pci_init_device(SysBusDevice *dev)
                               PCI_DEVFN(0, 0), 4);
     memory_region_init_io(&s->memconfig_p4, &sh_pci_reg_ops, s,
                           "sh_pci", 0x224);
-    memory_region_init_alias(&s->memconfig_a7, "sh_pci.2", &s->memconfig_a7,
+    memory_region_init_alias(&s->memconfig_a7, "sh_pci.2", &s->memconfig_p4,
                              0, 0x224);
     isa_mmio_setup(&s->isa, 0x40000);
     sysbus_init_mmio_cb2(dev, sh_pci_map, sh_pci_unmap);
commit 9f94778c1603420e48d779a495e84eb82945cc75
Author: Artyom Tarasenko <atar4qemu at gmail.com>
Date:   Mon Jul 25 19:22:38 2011 +0200

    Fix disabling interrupts in sun4u
    
    clear interrupt request if the interrupt priority < CPU pil
    clear hardware interrupt request if interrupts are disabled
    
    Signed-off-by: Artyom Tarasenko <atar4qemu at gmail.com>
    [blauwirbel at gmail.com: added a comment about magic 2]
    Signed-off-by: Blue Swirl <blauwirbel at gmail.com>

diff --git a/hw/sun4u.c b/hw/sun4u.c
index 1b60e4e..32e6ab9 100644
--- a/hw/sun4u.c
+++ b/hw/sun4u.c
@@ -261,7 +261,9 @@ void cpu_check_irqs(CPUState *env)
         pil |= 1 << 14;
     }
 
-    if (!pil) {
+    /* The bit corresponding to psrpil is (1<< psrpil), the next bit
+       is (2 << psrpil). */
+    if (pil < (2 << env->psrpil)){
         if (env->interrupt_request & CPU_INTERRUPT_HARD) {
             CPUIRQ_DPRINTF("Reset CPU IRQ (current interrupt %x)\n",
                            env->interrupt_index);
@@ -293,10 +295,12 @@ void cpu_check_irqs(CPUState *env)
                 break;
             }
         }
-    } else {
+    } else if (env->interrupt_request & CPU_INTERRUPT_HARD) {
         CPUIRQ_DPRINTF("Interrupts disabled, pil=%08x pil_in=%08x softint=%08x "
                        "current interrupt %x\n",
                        pil, env->pil_in, env->softint, env->interrupt_index);
+        env->interrupt_index = 0;
+        cpu_reset_interrupt(env, CPU_INTERRUPT_HARD);
     }
 }
 
commit 010f3f5fbd5f8edc1a584b5388f8ea2ad518a439
Author: Edgar E. Iglesias <edgar.iglesias at gmail.com>
Date:   Fri Aug 26 00:13:47 2011 +0200

    xilinx: Convert most xilinx devices to MemoryRegion
    
    This converts ethlite, intc, timer and uartlite to use
    MemoryRegions.
    
    Signed-off-by: Edgar E. Iglesias <edgar.iglesias at gmail.com>

diff --git a/hw/xilinx_ethlite.c b/hw/xilinx_ethlite.c
index f35ba84..6f44c84 100644
--- a/hw/xilinx_ethlite.c
+++ b/hw/xilinx_ethlite.c
@@ -50,6 +50,7 @@
 struct xlx_ethlite
 {
     SysBusDevice busdev;
+    MemoryRegion mmio;
     qemu_irq irq;
     NICState *nic;
     NICConf conf;
@@ -70,7 +71,8 @@ static inline void eth_pulse_irq(struct xlx_ethlite *s)
     }
 }
 
-static uint32_t eth_readl (void *opaque, target_phys_addr_t addr)
+static uint64_t
+eth_read(void *opaque, target_phys_addr_t addr, unsigned int size)
 {
     struct xlx_ethlite *s = opaque;
     uint32_t r = 0;
@@ -98,10 +100,12 @@ static uint32_t eth_readl (void *opaque, target_phys_addr_t addr)
 }
 
 static void
-eth_writel (void *opaque, target_phys_addr_t addr, uint32_t value)
+eth_write(void *opaque, target_phys_addr_t addr,
+          uint64_t val64, unsigned int size)
 {
     struct xlx_ethlite *s = opaque;
     unsigned int base = 0;
+    uint32_t value = val64;
 
     addr >>= 2;
     switch (addr) 
@@ -146,12 +150,14 @@ eth_writel (void *opaque, target_phys_addr_t addr, uint32_t value)
     }
 }
 
-static CPUReadMemoryFunc * const eth_read[] = {
-    NULL, NULL, &eth_readl,
-};
-
-static CPUWriteMemoryFunc * const eth_write[] = {
-    NULL, NULL, &eth_writel,
+static const MemoryRegionOps eth_ops = {
+    .read = eth_read,
+    .write = eth_write,
+    .endianness = DEVICE_NATIVE_ENDIAN,
+    .valid = {
+        .min_access_size = 4,
+        .max_access_size = 4
+    }
 };
 
 static int eth_can_rx(VLANClientState *nc)
@@ -206,13 +212,12 @@ static NetClientInfo net_xilinx_ethlite_info = {
 static int xilinx_ethlite_init(SysBusDevice *dev)
 {
     struct xlx_ethlite *s = FROM_SYSBUS(typeof (*s), dev);
-    int regs;
 
     sysbus_init_irq(dev, &s->irq);
     s->rxbuf = 0;
 
-    regs = cpu_register_io_memory(eth_read, eth_write, s, DEVICE_NATIVE_ENDIAN);
-    sysbus_init_mmio(dev, R_MAX * 4, regs);
+    memory_region_init_io(&s->mmio, &eth_ops, s, "xilinx-ethlite", R_MAX * 4);
+    sysbus_init_mmio_region(dev, &s->mmio);
 
     qemu_macaddr_default_if_unset(&s->conf.macaddr);
     s->nic = qemu_new_nic(&net_xilinx_ethlite_info, &s->conf,
diff --git a/hw/xilinx_intc.c b/hw/xilinx_intc.c
index cb72d5a..58b73d9 100644
--- a/hw/xilinx_intc.c
+++ b/hw/xilinx_intc.c
@@ -40,6 +40,7 @@
 struct xlx_pic
 {
     SysBusDevice busdev;
+    MemoryRegion mmio;
     qemu_irq parent_irq;
 
     /* Configuration reg chosen at synthesis-time. QEMU populates
@@ -72,7 +73,8 @@ static void update_irq(struct xlx_pic *p)
     }
 }
 
-static uint32_t pic_readl (void *opaque, target_phys_addr_t addr)
+static uint64_t
+pic_read(void *opaque, target_phys_addr_t addr, unsigned int size)
 {
     struct xlx_pic *p = opaque;
     uint32_t r = 0;
@@ -91,9 +93,11 @@ static uint32_t pic_readl (void *opaque, target_phys_addr_t addr)
 }
 
 static void
-pic_writel (void *opaque, target_phys_addr_t addr, uint32_t value)
+pic_write(void *opaque, target_phys_addr_t addr,
+          uint64_t val64, unsigned int size)
 {
     struct xlx_pic *p = opaque;
+    uint32_t value = val64;
 
     addr >>= 2;
     D(qemu_log("%s addr=%x val=%x\n", __func__, addr * 4, value));
@@ -116,14 +120,14 @@ pic_writel (void *opaque, target_phys_addr_t addr, uint32_t value)
     update_irq(p);
 }
 
-static CPUReadMemoryFunc * const pic_read[] = {
-    NULL, NULL,
-    &pic_readl,
-};
-
-static CPUWriteMemoryFunc * const pic_write[] = {
-    NULL, NULL,
-    &pic_writel,
+static const MemoryRegionOps pic_ops = {
+    .read = pic_read,
+    .write = pic_write,
+    .endianness = DEVICE_NATIVE_ENDIAN,
+    .valid = {
+        .min_access_size = 4,
+        .max_access_size = 4
+    }
 };
 
 static void irq_handler(void *opaque, int irq, int level)
@@ -148,13 +152,12 @@ static void irq_handler(void *opaque, int irq, int level)
 static int xilinx_intc_init(SysBusDevice *dev)
 {
     struct xlx_pic *p = FROM_SYSBUS(typeof (*p), dev);
-    int pic_regs;
 
     qdev_init_gpio_in(&dev->qdev, irq_handler, 32);
     sysbus_init_irq(dev, &p->parent_irq);
 
-    pic_regs = cpu_register_io_memory(pic_read, pic_write, p, DEVICE_NATIVE_ENDIAN);
-    sysbus_init_mmio(dev, R_MAX * 4, pic_regs);
+    memory_region_init_io(&p->mmio, &pic_ops, p, "xilinx-pic", R_MAX * 4);
+    sysbus_init_mmio_region(dev, &p->mmio);
     return 0;
 }
 
diff --git a/hw/xilinx_timer.c b/hw/xilinx_timer.c
index f1c7abc..8779c56 100644
--- a/hw/xilinx_timer.c
+++ b/hw/xilinx_timer.c
@@ -59,6 +59,7 @@ struct xlx_timer
 struct timerblock
 {
     SysBusDevice busdev;
+    MemoryRegion mmio;
     qemu_irq irq;
     uint32_t nr_timers;
     uint32_t freq_hz;
@@ -85,7 +86,8 @@ static void timer_update_irq(struct timerblock *t)
     qemu_set_irq(t->irq, !!irq);
 }
 
-static uint32_t timer_readl (void *opaque, target_phys_addr_t addr)
+static uint64_t
+timer_read(void *opaque, target_phys_addr_t addr, unsigned int size)
 {
     struct timerblock *t = opaque;
     struct xlx_timer *xt;
@@ -134,11 +136,13 @@ static void timer_enable(struct xlx_timer *xt)
 }
 
 static void
-timer_writel (void *opaque, target_phys_addr_t addr, uint32_t value)
+timer_write(void *opaque, target_phys_addr_t addr,
+            uint64_t val64, unsigned int size)
 {
     struct timerblock *t = opaque;
     struct xlx_timer *xt;
     unsigned int timer;
+    uint32_t value = val64;
 
     addr >>= 2;
     timer = timer_from_addr(addr);
@@ -166,14 +170,14 @@ timer_writel (void *opaque, target_phys_addr_t addr, uint32_t value)
     timer_update_irq(t);
 }
 
-static CPUReadMemoryFunc * const timer_read[] = {
-    NULL, NULL,
-    &timer_readl,
-};
-
-static CPUWriteMemoryFunc * const timer_write[] = {
-    NULL, NULL,
-    &timer_writel,
+static const MemoryRegionOps timer_ops = {
+    .read = timer_read,
+    .write = timer_write,
+    .endianness = DEVICE_NATIVE_ENDIAN,
+    .valid = {
+        .min_access_size = 4,
+        .max_access_size = 4
+    }
 };
 
 static void timer_hit(void *opaque)
@@ -192,7 +196,6 @@ static int xilinx_timer_init(SysBusDevice *dev)
 {
     struct timerblock *t = FROM_SYSBUS(typeof (*t), dev);
     unsigned int i;
-    int timer_regs;
 
     /* All timers share a single irq line.  */
     sysbus_init_irq(dev, &t->irq);
@@ -209,9 +212,9 @@ static int xilinx_timer_init(SysBusDevice *dev)
         ptimer_set_freq(xt->ptimer, t->freq_hz);
     }
 
-    timer_regs = cpu_register_io_memory(timer_read, timer_write, t,
-                                        DEVICE_NATIVE_ENDIAN);
-    sysbus_init_mmio(dev, R_MAX * 4 * t->nr_timers, timer_regs);
+    memory_region_init_io(&t->mmio, &timer_ops, t, "xilinx-timer",
+                          R_MAX * 4 * t->nr_timers);
+    sysbus_init_mmio_region(dev, &t->mmio);
     return 0;
 }
 
diff --git a/hw/xilinx_uartlite.c b/hw/xilinx_uartlite.c
index 467a26c..ceb7b4d 100644
--- a/hw/xilinx_uartlite.c
+++ b/hw/xilinx_uartlite.c
@@ -49,6 +49,7 @@
 struct xlx_uartlite
 {
     SysBusDevice busdev;
+    MemoryRegion mmio;
     CharDriverState *chr;
     qemu_irq irq;
 
@@ -82,7 +83,8 @@ static void uart_update_status(struct xlx_uartlite *s)
     s->regs[R_STATUS] = r;
 }
 
-static uint32_t uart_readl (void *opaque, target_phys_addr_t addr)
+static uint64_t
+uart_read(void *opaque, target_phys_addr_t addr, unsigned int size)
 {
     struct xlx_uartlite *s = opaque;
     uint32_t r = 0;
@@ -107,9 +109,11 @@ static uint32_t uart_readl (void *opaque, target_phys_addr_t addr)
 }
 
 static void
-uart_writel (void *opaque, target_phys_addr_t addr, uint32_t value)
+uart_write(void *opaque, target_phys_addr_t addr,
+           uint64_t val64, unsigned int size)
 {
     struct xlx_uartlite *s = opaque;
+    uint32_t value = val64;
     unsigned char ch = value;
 
     addr >>= 2;
@@ -147,16 +151,14 @@ uart_writel (void *opaque, target_phys_addr_t addr, uint32_t value)
     uart_update_irq(s);
 }
 
-static CPUReadMemoryFunc * const uart_read[] = {
-    &uart_readl,
-    &uart_readl,
-    &uart_readl,
-};
-
-static CPUWriteMemoryFunc * const uart_write[] = {
-    &uart_writel,
-    &uart_writel,
-    &uart_writel,
+static const MemoryRegionOps uart_ops = {
+    .read = uart_read,
+    .write = uart_write,
+    .endianness = DEVICE_NATIVE_ENDIAN,
+    .valid = {
+        .min_access_size = 1,
+        .max_access_size = 4
+    }
 };
 
 static void uart_rx(void *opaque, const uint8_t *buf, int size)
@@ -196,14 +198,12 @@ static void uart_event(void *opaque, int event)
 static int xilinx_uartlite_init(SysBusDevice *dev)
 {
     struct xlx_uartlite *s = FROM_SYSBUS(typeof (*s), dev);
-    int uart_regs;
 
     sysbus_init_irq(dev, &s->irq);
 
     uart_update_status(s);
-    uart_regs = cpu_register_io_memory(uart_read, uart_write, s,
-                                       DEVICE_NATIVE_ENDIAN);
-    sysbus_init_mmio(dev, R_MAX * 4, uart_regs);
+    memory_region_init_io(&s->mmio, &uart_ops, s, "xilinx-uartlite", R_MAX * 4);
+    sysbus_init_mmio_region(dev, &s->mmio);
 
     s->chr = qdev_init_chardev(&dev->qdev);
     if (s->chr)
commit fe0de7aa5ecb8917acb181eea6e5c29657c8c36c
Author: Blue Swirl <blauwirbel at gmail.com>
Date:   Sat Jul 30 19:18:32 2011 +0000

    TCG: improve optimizer debugging
    
    Use enum TCGOpcode instead of plain old int so that the name of
    current op can be seen in GDB. Add a default case to switch
    so that GCC does not complain about unhandled enum cases.
    
    Signed-off-by: Blue Swirl <blauwirbel at gmail.com>

diff --git a/tcg/optimize.c b/tcg/optimize.c
index 7e7f2b2..9c65474 100644
--- a/tcg/optimize.c
+++ b/tcg/optimize.c
@@ -87,13 +87,13 @@ static void reset_temp(TCGArg temp, int nb_temps, int nb_globals)
     }
 }
 
-static int op_bits(enum TCGOpcode op)
+static int op_bits(TCGOpcode op)
 {
     const TCGOpDef *def = &tcg_op_defs[op];
     return def->flags & TCG_OPF_64BIT ? 64 : 32;
 }
 
-static int op_to_movi(int op)
+static TCGOpcode op_to_movi(TCGOpcode op)
 {
     switch (op_bits(op)) {
     case 32:
@@ -143,7 +143,7 @@ static void tcg_opt_gen_movi(TCGArg *gen_args, TCGArg dst, TCGArg val,
         gen_args[1] = val;
 }
 
-static int op_to_mov(int op)
+static TCGOpcode op_to_mov(TCGOpcode op)
 {
     switch (op_bits(op)) {
     case 32:
@@ -157,7 +157,7 @@ static int op_to_mov(int op)
     }
 }
 
-static TCGArg do_constant_folding_2(int op, TCGArg x, TCGArg y)
+static TCGArg do_constant_folding_2(TCGOpcode op, TCGArg x, TCGArg y)
 {
     switch (op) {
     CASE_OP_32_64(add):
@@ -258,7 +258,7 @@ static TCGArg do_constant_folding_2(int op, TCGArg x, TCGArg y)
     }
 }
 
-static TCGArg do_constant_folding(int op, TCGArg x, TCGArg y)
+static TCGArg do_constant_folding(TCGOpcode op, TCGArg x, TCGArg y)
 {
     TCGArg res = do_constant_folding_2(op, x, y);
     if (op_bits(op) == 32) {
@@ -271,7 +271,8 @@ static TCGArg do_constant_folding(int op, TCGArg x, TCGArg y)
 static TCGArg *tcg_constant_folding(TCGContext *s, uint16_t *tcg_opc_ptr,
                                     TCGArg *args, TCGOpDef *tcg_op_defs)
 {
-    int i, nb_ops, op_index, op, nb_temps, nb_globals, nb_call_args;
+    int i, nb_ops, op_index, nb_temps, nb_globals, nb_call_args;
+    TCGOpcode op;
     const TCGOpDef *def;
     TCGArg *gen_args;
     TCGArg tmp;
@@ -377,6 +378,8 @@ static TCGArg *tcg_constant_folding(TCGContext *s, uint16_t *tcg_opc_ptr,
                 continue;
             }
             break;
+        default:
+            break;
         }
 
         /* Propagate constants through copy operations and do constant
commit e5b34f37793dc239c2f65442046e12a5dd7b61ec
Author: Blue Swirl <blauwirbel at gmail.com>
Date:   Sat Jul 30 15:50:22 2011 +0000

    dyngen-exec.h: cleanup
    
    Remove unused or otherwise available stuff.
    
    Signed-off-by: Blue Swirl <blauwirbel at gmail.com>

diff --git a/dyngen-exec.h b/dyngen-exec.h
index cc1e4fb..8beb7f3 100644
--- a/dyngen-exec.h
+++ b/dyngen-exec.h
@@ -19,15 +19,6 @@
 #if !defined(__DYNGEN_EXEC_H__)
 #define __DYNGEN_EXEC_H__
 
-#include "qemu-common.h"
-
-#ifdef __OpenBSD__
-#include <sys/types.h>
-#endif
-
-/* XXX: This may be wrong for 64-bit ILP32 hosts.  */
-typedef void * host_reg_t;
-
 #if defined(__i386__)
 #define AREG0 "ebp"
 #elif defined(__x86_64__)
@@ -66,11 +57,6 @@ typedef void * host_reg_t;
 
 register CPUState *env asm(AREG0);
 
-#define xglue(x, y) x ## y
-#define glue(x, y) xglue(x, y)
-#define stringify(s)	tostring(s)
-#define tostring(s)	#s
-
 /* The return address may point to the start of the next instruction.
    Subtracting one gets us the call instruction itself.  */
 #if defined(__s390__) && !defined(__s390x__)
commit 97a3f6ffbba66250d9a6f1ba7f8444f6bb8c6676
Author: Hervé Poussineau <hpoussin at reactos.org>
Date:   Fri Aug 26 21:20:12 2011 +0200

    g364fb: convert to qdev
    
    Extract G364 ROM contents from device emulation to machine emulation,
    so device emulation can be reused in other machines (Commodore Amiga)
    
    Signed-off-by: Hervé Poussineau <hpoussin at reactos.org>
    Signed-off-by: Blue Swirl <blauwirbel at gmail.com>

diff --git a/hw/g364fb.c b/hw/g364fb.c
index fa074f4..5e7bcfa 100644
--- a/hw/g364fb.c
+++ b/hw/g364fb.c
@@ -1,7 +1,7 @@
 /*
  * QEMU G364 framebuffer Emulator.
  *
- * Copyright (c) 2007-2009 Herve Poussineau
+ * Copyright (c) 2007-2011 Herve Poussineau
  *
  * This program is free software; you can redistribute it and/or
  * modify it under the terms of the GNU General Public License as
@@ -18,17 +18,18 @@
  */
 
 #include "hw.h"
-#include "mips.h"
 #include "console.h"
 #include "pixel_ops.h"
 #include "trace.h"
+#include "sysbus.h"
 
 typedef struct G364State {
     /* hardware */
     uint8_t *vram;
-    ram_addr_t vram_offset;
-    int vram_size;
+    uint32_t vram_size;
     qemu_irq irq;
+    MemoryRegion mem_vram;
+    MemoryRegion mem_ctrl;
     /* registers */
     uint8_t color_palette[256][3];
     uint8_t cursor_palette[3][3];
@@ -43,31 +44,32 @@ typedef struct G364State {
     int blanked;
 } G364State;
 
-#define REG_ID       0x000000
-#define REG_BOOT     0x080000
-#define REG_DISPLAY  0x080118
-#define REG_VDISPLAY 0x080150
-#define REG_CTLA     0x080300
-#define REG_TOP      0x080400
-#define REG_CURS_PAL 0x080508
-#define REG_CURS_POS 0x080638
-#define REG_CLR_PAL  0x080800
-#define REG_CURS_PAT 0x081000
-#define REG_RESET    0x180000
+#define REG_BOOT     0x000000
+#define REG_DISPLAY  0x000118
+#define REG_VDISPLAY 0x000150
+#define REG_CTLA     0x000300
+#define REG_TOP      0x000400
+#define REG_CURS_PAL 0x000508
+#define REG_CURS_POS 0x000638
+#define REG_CLR_PAL  0x000800
+#define REG_CURS_PAT 0x001000
+#define REG_RESET    0x100000
 
 #define CTLA_FORCE_BLANK 0x00000400
 #define CTLA_NO_CURSOR   0x00800000
 
-static inline int check_dirty(ram_addr_t page)
+static inline int check_dirty(G364State *s, ram_addr_t page)
 {
-    return cpu_physical_memory_get_dirty(page, VGA_DIRTY_FLAG);
+    return memory_region_get_dirty(&s->mem_vram, page, DIRTY_MEMORY_VGA);
 }
 
 static inline void reset_dirty(G364State *s,
                                ram_addr_t page_min, ram_addr_t page_max)
 {
-    cpu_physical_memory_reset_dirty(page_min, page_max + TARGET_PAGE_SIZE - 1,
-                                    VGA_DIRTY_FLAG);
+    memory_region_reset_dirty(&s->mem_vram,
+                              page_min,
+                              page_max + TARGET_PAGE_SIZE - page_min - 1,
+                              DIRTY_MEMORY_VGA);
 }
 
 static void g364fb_draw_graphic8(G364State *s)
@@ -105,7 +107,7 @@ static void g364fb_draw_graphic8(G364State *s)
             return;
     }
 
-    page = s->vram_offset;
+    page = 0;
     page_min = (ram_addr_t)-1;
     page_max = 0;
 
@@ -126,7 +128,7 @@ static void g364fb_draw_graphic8(G364State *s)
     /* XXX: out of range in vram? */
     data_display = dd = ds_get_data(s->ds);
     while (y < s->height) {
-        if (check_dirty(page)) {
+        if (check_dirty(s, page)) {
             if (y < ymin)
                 ymin = ymax = y;
             if (page_min == (ram_addr_t)-1)
@@ -266,13 +268,12 @@ static inline void g364fb_invalidate_display(void *opaque)
 
     s->blanked = 0;
     for (i = 0; i < s->vram_size; i += TARGET_PAGE_SIZE) {
-        cpu_physical_memory_set_dirty(s->vram_offset + i);
+        memory_region_set_dirty(&s->mem_vram, i);
     }
 }
 
-static void g364fb_reset(void *opaque)
+static void g364fb_reset(G364State *s)
 {
-    G364State *s = opaque;
     qemu_irq_lower(s->irq);
 
     memset(s->color_palette, 0, sizeof(s->color_palette));
@@ -283,7 +284,7 @@ static void g364fb_reset(void *opaque)
     s->top_of_screen = 0;
     s->width = s->height = 0;
     memset(s->vram, 0, s->vram_size);
-    g364fb_invalidate_display(opaque);
+    g364fb_invalidate_display(s);
 }
 
 static void g364fb_screen_dump(void *opaque, const char *filename)
@@ -327,7 +328,9 @@ static void g364fb_screen_dump(void *opaque, const char *filename)
 }
 
 /* called for accesses to io ports */
-static uint32_t g364fb_ctrl_readl(void *opaque, target_phys_addr_t addr)
+static uint64_t g364fb_ctrl_read(void *opaque,
+                                 target_phys_addr_t addr,
+                                 unsigned int size)
 {
     G364State *s = opaque;
     uint32_t val;
@@ -344,9 +347,6 @@ static uint32_t g364fb_ctrl_readl(void *opaque, target_phys_addr_t addr)
         val |= ((uint32_t)s->cursor_palette[idx][2] << 0);
     } else {
         switch (addr) {
-            case REG_ID:
-                val = 0x10; /* Mips G364 */
-                break;
             case REG_DISPLAY:
                 val = s->width / 4;
                 break;
@@ -371,21 +371,6 @@ static uint32_t g364fb_ctrl_readl(void *opaque, target_phys_addr_t addr)
     return val;
 }
 
-static uint32_t g364fb_ctrl_readw(void *opaque, target_phys_addr_t addr)
-{
-    uint32_t v = g364fb_ctrl_readl(opaque, addr & ~0x3);
-    if (addr & 0x2)
-        return v >> 16;
-    else
-        return v & 0xffff;
-}
-
-static uint32_t g364fb_ctrl_readb(void *opaque, target_phys_addr_t addr)
-{
-    uint32_t v = g364fb_ctrl_readl(opaque, addr & ~0x3);
-    return (v >> (8 * (addr & 0x3))) & 0xff;
-}
-
 static void g364fb_update_depth(G364State *s)
 {
     static const int depths[8] = { 1, 2, 4, 8, 15, 16, 0 };
@@ -403,11 +388,14 @@ static void g364_invalidate_cursor_position(G364State *s)
     end = (ymax + 1) * ds_get_linesize(s->ds);
 
     for (i = start; i < end; i += TARGET_PAGE_SIZE) {
-        cpu_physical_memory_set_dirty(s->vram_offset + i);
+        memory_region_set_dirty(&s->mem_vram, i);
     }
 }
 
-static void g364fb_ctrl_writel(void *opaque, target_phys_addr_t addr, uint32_t val)
+static void g364fb_ctrl_write(void *opaque,
+                              target_phys_addr_t addr,
+                              uint64_t val,
+                              unsigned int size)
 {
     G364State *s = opaque;
 
@@ -434,121 +422,65 @@ static void g364fb_ctrl_writel(void *opaque, target_phys_addr_t addr, uint32_t v
         g364fb_invalidate_display(s);
     } else {
         switch (addr) {
-            case REG_ID: /* Card identifier; read-only */
-            case REG_BOOT: /* Boot timing */
-            case 0x80108: /* Line timing: half sync */
-            case 0x80110: /* Line timing: back porch */
-            case 0x80120: /* Line timing: short display */
-            case 0x80128: /* Frame timing: broad pulse */
-            case 0x80130: /* Frame timing: v sync */
-            case 0x80138: /* Frame timing: v preequalise */
-            case 0x80140: /* Frame timing: v postequalise */
-            case 0x80148: /* Frame timing: v blank */
-            case 0x80158: /* Line timing: line time */
-            case 0x80160: /* Frame store: line start */
-            case 0x80168: /* vram cycle: mem init */
-            case 0x80170: /* vram cycle: transfer delay */
-            case 0x80200: /* vram cycle: mask register */
-                /* ignore */
-                break;
-            case REG_TOP:
-                s->top_of_screen = val;
-                g364fb_invalidate_display(s);
-                break;
-            case REG_DISPLAY:
-                s->width = val * 4;
-                break;
-            case REG_VDISPLAY:
-                s->height = val / 2;
-                break;
-            case REG_CTLA:
-                s->ctla = val;
-                g364fb_update_depth(s);
-                g364fb_invalidate_display(s);
-                break;
-            case REG_CURS_POS:
-                g364_invalidate_cursor_position(s);
-                s->cursor_position = val;
-                g364_invalidate_cursor_position(s);
-                break;
-            case REG_RESET:
-                g364fb_reset(s);
-                break;
-            default:
-                error_report("g364: invalid write of 0x%" PRIx64
-                             " at [" TARGET_FMT_plx "]", val, addr);
-                break;
+        case REG_BOOT: /* Boot timing */
+        case 0x00108: /* Line timing: half sync */
+        case 0x00110: /* Line timing: back porch */
+        case 0x00120: /* Line timing: short display */
+        case 0x00128: /* Frame timing: broad pulse */
+        case 0x00130: /* Frame timing: v sync */
+        case 0x00138: /* Frame timing: v preequalise */
+        case 0x00140: /* Frame timing: v postequalise */
+        case 0x00148: /* Frame timing: v blank */
+        case 0x00158: /* Line timing: line time */
+        case 0x00160: /* Frame store: line start */
+        case 0x00168: /* vram cycle: mem init */
+        case 0x00170: /* vram cycle: transfer delay */
+        case 0x00200: /* vram cycle: mask register */
+            /* ignore */
+            break;
+        case REG_TOP:
+            s->top_of_screen = val;
+            g364fb_invalidate_display(s);
+            break;
+        case REG_DISPLAY:
+            s->width = val * 4;
+            break;
+        case REG_VDISPLAY:
+            s->height = val / 2;
+            break;
+        case REG_CTLA:
+            s->ctla = val;
+            g364fb_update_depth(s);
+            g364fb_invalidate_display(s);
+            break;
+        case REG_CURS_POS:
+            g364_invalidate_cursor_position(s);
+            s->cursor_position = val;
+            g364_invalidate_cursor_position(s);
+            break;
+        case REG_RESET:
+            g364fb_reset(s);
+            break;
+        default:
+            error_report("g364: invalid write of 0x%" PRIx64
+                         " at [" TARGET_FMT_plx "]", val, addr);
+            break;
         }
     }
     qemu_irq_lower(s->irq);
 }
 
-static void g364fb_ctrl_writew(void *opaque, target_phys_addr_t addr, uint32_t val)
-{
-    uint32_t old_val = g364fb_ctrl_readl(opaque, addr & ~0x3);
-
-    if (addr & 0x2)
-        val = (val << 16) | (old_val & 0x0000ffff);
-    else
-        val = val | (old_val & 0xffff0000);
-    g364fb_ctrl_writel(opaque, addr & ~0x3, val);
-}
-
-static void g364fb_ctrl_writeb(void *opaque, target_phys_addr_t addr, uint32_t val)
-{
-    uint32_t old_val = g364fb_ctrl_readl(opaque, addr & ~0x3);
-
-    switch (addr & 3) {
-    case 0:
-        val = val | (old_val & 0xffffff00);
-        break;
-    case 1:
-        val = (val << 8) | (old_val & 0xffff00ff);
-        break;
-    case 2:
-        val = (val << 16) | (old_val & 0xff00ffff);
-        break;
-    case 3:
-        val = (val << 24) | (old_val & 0x00ffffff);
-        break;
-    }
-    g364fb_ctrl_writel(opaque, addr & ~0x3, val);
-}
-
-static CPUReadMemoryFunc * const g364fb_ctrl_read[3] = {
-    g364fb_ctrl_readb,
-    g364fb_ctrl_readw,
-    g364fb_ctrl_readl,
-};
-
-static CPUWriteMemoryFunc * const g364fb_ctrl_write[3] = {
-    g364fb_ctrl_writeb,
-    g364fb_ctrl_writew,
-    g364fb_ctrl_writel,
+static const MemoryRegionOps g364fb_ctrl_ops = {
+    .read = g364fb_ctrl_read,
+    .write = g364fb_ctrl_write,
+    .endianness = DEVICE_LITTLE_ENDIAN,
+    .impl.min_access_size = 4,
+    .impl.max_access_size = 4,
 };
 
-static int g364fb_load(QEMUFile *f, void *opaque, int version_id)
+static int g364fb_post_load(void *opaque, int version_id)
 {
     G364State *s = opaque;
-    unsigned int i, vram_size;
-
-    if (version_id != 1)
-        return -EINVAL;
-
-    vram_size = qemu_get_be32(f);
-    if (vram_size < s->vram_size)
-        return -EINVAL;
-    qemu_get_buffer(f, s->vram, s->vram_size);
-    for (i = 0; i < 256; i++)
-        qemu_get_buffer(f, s->color_palette[i], 3);
-    for (i = 0; i < 3; i++)
-        qemu_get_buffer(f, s->cursor_palette[i], 3);
-    qemu_get_buffer(f, (uint8_t *)s->cursor, sizeof(s->cursor));
-    s->cursor_position = qemu_get_be32(f);
-    s->ctla = qemu_get_be32(f);
-    s->top_of_screen = qemu_get_be32(f);
-    s->width = qemu_get_be32(f);
-    s->height = qemu_get_be32(f);
 
     /* force refresh */
     g364fb_update_depth(s);
@@ -557,52 +489,80 @@ static int g364fb_load(QEMUFile *f, void *opaque, int version_id)
     return 0;
 }
 
-static void g364fb_save(QEMUFile *f, void *opaque)
-{
-    G364State *s = opaque;
-    int i;
-
-    qemu_put_be32(f, s->vram_size);
-    qemu_put_buffer(f, s->vram, s->vram_size);
-    for (i = 0; i < 256; i++)
-        qemu_put_buffer(f, s->color_palette[i], 3);
-    for (i = 0; i < 3; i++)
-        qemu_put_buffer(f, s->cursor_palette[i], 3);
-    qemu_put_buffer(f, (uint8_t *)s->cursor, sizeof(s->cursor));
-    qemu_put_be32(f, s->cursor_position);
-    qemu_put_be32(f, s->ctla);
-    qemu_put_be32(f, s->top_of_screen);
-    qemu_put_be32(f, s->width);
-    qemu_put_be32(f, s->height);
-}
+static const VMStateDescription vmstate_g364fb = {
+    .name = "g364fb",
+    .version_id = 1,
+    .minimum_version_id = 1,
+    .minimum_version_id_old = 1,
+    .post_load = g364fb_post_load,
+    .fields = (VMStateField[]) {
+        VMSTATE_VBUFFER_UINT32(vram, G364State, 1, NULL, 0, vram_size),
+        VMSTATE_BUFFER_UNSAFE(color_palette, G364State, 0, 256 * 3),
+        VMSTATE_BUFFER_UNSAFE(cursor_palette, G364State, 0, 9),
+        VMSTATE_UINT16_ARRAY(cursor, G364State, 512),
+        VMSTATE_UINT32(cursor_position, G364State),
+        VMSTATE_UINT32(ctla, G364State),
+        VMSTATE_UINT32(top_of_screen, G364State),
+        VMSTATE_UINT32(width, G364State),
+        VMSTATE_UINT32(height, G364State),
+        VMSTATE_END_OF_LIST()
+    }
+};
 
-int g364fb_mm_init(target_phys_addr_t vram_base,
-                   target_phys_addr_t ctrl_base, int it_shift,
-                   qemu_irq irq)
+static void g364fb_init(DeviceState *dev, G364State *s)
 {
-    G364State *s;
-    int io_ctrl;
-
-    s = g_malloc0(sizeof(G364State));
-
-    s->vram_size = 8 * 1024 * 1024;
-    s->vram_offset = qemu_ram_alloc(NULL, "g364fb.vram", s->vram_size);
-    s->vram = qemu_get_ram_ptr(s->vram_offset);
-    s->irq = irq;
-
-    qemu_register_reset(g364fb_reset, s);
-    register_savevm(NULL, "g364fb", 0, 1, g364fb_save, g364fb_load, s);
-    g364fb_reset(s);
+    s->vram = g_malloc0(s->vram_size);
 
     s->ds = graphic_console_init(g364fb_update_display,
                                  g364fb_invalidate_display,
                                  g364fb_screen_dump, NULL, s);
 
-    cpu_register_physical_memory(vram_base, s->vram_size, s->vram_offset);
+    memory_region_init_io(&s->mem_ctrl, &g364fb_ctrl_ops, s, "ctrl", 0x180000);
+    memory_region_init_ram_ptr(&s->mem_vram, dev, "vram",
+                               s->vram_size, s->vram);
+    memory_region_set_coalescing(&s->mem_vram);
+}
+
+typedef struct {
+    SysBusDevice busdev;
+    G364State g364;
+} G364SysBusState;
 
-    io_ctrl = cpu_register_io_memory(g364fb_ctrl_read, g364fb_ctrl_write, s,
-                                     DEVICE_NATIVE_ENDIAN);
-    cpu_register_physical_memory(ctrl_base, 0x200000, io_ctrl);
+static int g364fb_sysbus_init(SysBusDevice *dev)
+{
+    G364State *s = &FROM_SYSBUS(G364SysBusState, dev)->g364;
+
+    g364fb_init(&dev->qdev, s);
+    sysbus_init_irq(dev, &s->irq);
+    sysbus_init_mmio_region(dev, &s->mem_ctrl);
+    sysbus_init_mmio_region(dev, &s->mem_vram);
 
     return 0;
 }
+
+static void g364fb_sysbus_reset(DeviceState *d)
+{
+    G364SysBusState *s = DO_UPCAST(G364SysBusState, busdev.qdev, d);
+    g364fb_reset(&s->g364);
+}
+
+static SysBusDeviceInfo g364fb_sysbus_info = {
+    .init = g364fb_sysbus_init,
+    .qdev.name = "sysbus-g364",
+    .qdev.desc = "G364 framebuffer",
+    .qdev.size = sizeof(G364SysBusState),
+    .qdev.vmsd = &vmstate_g364fb,
+    .qdev.reset = g364fb_sysbus_reset,
+    .qdev.props = (Property[]) {
+        DEFINE_PROP_HEX32("vram_size", G364SysBusState, g364.vram_size,
+                          8 * 1024 * 1024),
+        DEFINE_PROP_END_OF_LIST(),
+    }
+};
+
+static void g364fb_register(void)
+{
+    sysbus_register_withprop(&g364fb_sysbus_info);
+}
+
+device_init(g364fb_register);
diff --git a/hw/mips.h b/hw/mips.h
index cae5f4c..8ce41fc 100644
--- a/hw/mips.h
+++ b/hw/mips.h
@@ -8,11 +8,6 @@ PCIBus *gt64120_register(qemu_irq *pic);
 /* bonito.c */
 PCIBus *bonito_init(qemu_irq *pic);
 
-/* g364fb.c */
-int g364fb_mm_init(target_phys_addr_t vram_base,
-                   target_phys_addr_t ctrl_base, int it_shift,
-                   qemu_irq irq);
-
 /* mipsnet.c */
 void mipsnet_init(int base, qemu_irq irq, NICInfo *nd);
 
diff --git a/hw/mips_jazz.c b/hw/mips_jazz.c
index 84ce061..f3c9f93 100644
--- a/hw/mips_jazz.c
+++ b/hw/mips_jazz.c
@@ -195,7 +195,20 @@ void mips_jazz_init (ram_addr_t ram_size,
     /* Video card */
     switch (jazz_model) {
     case JAZZ_MAGNUM:
-        g364fb_mm_init(0x40000000, 0x60000000, 0, rc4030[3]);
+        dev = qdev_create(NULL, "sysbus-g364");
+        qdev_init_nofail(dev);
+        sysbus = sysbus_from_qdev(dev);
+        sysbus_mmio_map(sysbus, 0, 0x60080000);
+        sysbus_mmio_map(sysbus, 1, 0x40000000);
+        sysbus_connect_irq(sysbus, 0, rc4030[3]);
+        {
+            /* Simple ROM, so user doesn't have to provide one */
+            ram_addr_t rom_offset = qemu_ram_alloc(NULL, "g364fb.rom", 0x80000);
+            uint8_t *rom = qemu_get_ram_ptr(rom_offset);
+            cpu_register_physical_memory(0x60000000, 0x80000,
+                                         rom_offset | IO_MEM_ROM);
+            rom[0] = 0x10; /* Mips G364 */
+        }
         break;
     case JAZZ_PICA61:
         isa_vga_mm_init(0x40000000, 0x60000000, 0, get_system_memory());
commit b213b37072e2eb3e3d13f2a3064e8876f00ce1a0
Author: Hervé Poussineau <hpoussin at reactos.org>
Date:   Fri Aug 26 21:20:11 2011 +0200

    g364fb: use trace framework
    
    Signed-off-by: Hervé Poussineau <hpoussin at reactos.org>
    Signed-off-by: Blue Swirl <blauwirbel at gmail.com>

diff --git a/hw/g364fb.c b/hw/g364fb.c
index b3020c5..fa074f4 100644
--- a/hw/g364fb.c
+++ b/hw/g364fb.c
@@ -21,17 +21,7 @@
 #include "mips.h"
 #include "console.h"
 #include "pixel_ops.h"
-
-//#define DEBUG_G364
-
-#ifdef DEBUG_G364
-#define DPRINTF(fmt, ...) \
-do { printf("g364: " fmt , ## __VA_ARGS__); } while (0)
-#else
-#define DPRINTF(fmt, ...) do {} while (0)
-#endif
-#define BADF(fmt, ...) \
-do { fprintf(stderr, "g364 ERROR: " fmt , ## __VA_ARGS__);} while (0)
+#include "trace.h"
 
 typedef struct G364State {
     /* hardware */
@@ -110,7 +100,8 @@ static void g364fb_draw_graphic8(G364State *s)
             w = 4;
             break;
         default:
-            BADF("unknown host depth %d\n", ds_get_bits_per_pixel(s->ds));
+            hw_error("g364: unknown host depth %d",
+                     ds_get_bits_per_pixel(s->ds));
             return;
     }
 
@@ -262,7 +253,7 @@ static void g364fb_update_display(void *opaque)
     } else if (s->depth == 8) {
         g364fb_draw_graphic8(s);
     } else {
-        BADF("unknown guest depth %d\n", s->depth);
+        error_report("g364: unknown guest depth %d", s->depth);
     }
 
     qemu_irq_raise(s->irq);
@@ -304,7 +295,7 @@ static void g364fb_screen_dump(void *opaque, const char *filename)
     FILE *f;
 
     if (s->depth != 8) {
-        BADF("unknown guest depth %d\n", s->depth);
+        error_report("g364: unknown guest depth %d", s->depth);
         return;
     }
 
@@ -367,14 +358,15 @@ static uint32_t g364fb_ctrl_readl(void *opaque, target_phys_addr_t addr)
                 break;
             default:
             {
-                BADF("invalid read at [" TARGET_FMT_plx "]\n", addr);
+                error_report("g364: invalid read at [" TARGET_FMT_plx "]",
+                             addr);
                 val = 0;
                 break;
             }
         }
     }
 
-    DPRINTF("read 0x%08x at [" TARGET_FMT_plx "]\n", val, addr);
+    trace_g364fb_read(addr, val);
 
     return val;
 }
@@ -419,7 +411,7 @@ static void g364fb_ctrl_writel(void *opaque, target_phys_addr_t addr, uint32_t v
 {
     G364State *s = opaque;
 
-    DPRINTF("write 0x%08x at [" TARGET_FMT_plx "]\n", val, addr);
+    trace_g364fb_write(addr, val);
 
     if (addr >= REG_CLR_PAL && addr < REG_CLR_PAL + 0x800) {
         /* color palette */
@@ -483,7 +475,8 @@ static void g364fb_ctrl_writel(void *opaque, target_phys_addr_t addr, uint32_t v
                 g364fb_reset(s);
                 break;
             default:
-                BADF("invalid write of 0x%08x at [" TARGET_FMT_plx "]\n", val, addr);
+                error_report("g364: invalid write of 0x%" PRIx64
+                             " at [" TARGET_FMT_plx "]", val, addr);
                 break;
         }
     }
diff --git a/trace-events b/trace-events
index dc300a2..f08d6d0 100644
--- a/trace-events
+++ b/trace-events
@@ -284,6 +284,10 @@ disable qed_aio_write_prefill(void *s, void *acb, uint64_t start, size_t len, ui
 disable qed_aio_write_postfill(void *s, void *acb, uint64_t start, size_t len, uint64_t offset) "s %p acb %p start %"PRIu64" len %zu offset %"PRIu64""
 disable qed_aio_write_main(void *s, void *acb, int ret, uint64_t offset, size_t len) "s %p acb %p ret %d offset %"PRIu64" len %zu"
 
+# hw/g364fb.c
+disable g364fb_read(uint64_t addr, uint32_t val) "read addr=0x%"PRIx64": 0x%x"
+disable g364fb_write(uint64_t addr, uint32_t new) "write addr=0x%"PRIx64": 0x%x"
+
 # hw/grlib_gptimer.c
 disable grlib_gptimer_enable(int id, uint32_t count) "timer:%d set count 0x%x and run"
 disable grlib_gptimer_disabled(int id, uint32_t config) "timer:%d Timer disable config 0x%x"
commit 01c4330b58909612ac202573da6e1a872b8bb0ad
Author: Pavel Borzenkov <pavel.borzenkov at gmail.com>
Date:   Fri Aug 26 17:34:37 2011 +0400

    checkpatch: fix braces {} handling
    
    checkpatch.pl doesn't report warning for if/else statements with missing
    'else' braces:
    
    if (something) {
        foo;
    } else
        bar;
    
    The patch has been tested using the last 100 commits.
    
    Signed-off-by: Pavel Borzenkov <pavel.borzenkov at gmail.com>
    Signed-off-by: Blue Swirl <blauwirbel at gmail.com>

diff --git a/scripts/checkpatch.pl b/scripts/checkpatch.pl
index 3498425..0eba357 100755
--- a/scripts/checkpatch.pl
+++ b/scripts/checkpatch.pl
@@ -2532,7 +2532,7 @@ sub process {
 						$allowed = 1;
 					}
 				}
-				if (!$seen) {
+				if ($seen != ($#chunks + 1)) {
 					WARN("braces {} are necessary for all arms of this statement\n" . $herectx);
 				}
 			}
commit 8733f6093c2b77502e7228503fc22024e51599b8
Author: Gerd Hoffmann <kraxel at redhat.com>
Date:   Fri Aug 26 11:16:10 2011 +0200

    Fix linker scripts
    
    Remove PROVIDE_HIDDEN and ONLY_IF_{RO,RW} from linker scripts to make
    them work with older binutils versions.  Fixes *-bsd-user build on
    OpenBSD 4.9 which ships binutils 2.15.
    
    Signed-off-by: Gerd Hoffmann <kraxel at redhat.com>
    Signed-off-by: Blue Swirl <blauwirbel at gmail.com>

diff --git a/arm.ld b/arm.ld
index 12b3edb..7f13da9 100644
--- a/arm.ld
+++ b/arm.ld
@@ -71,23 +71,23 @@ SECTIONS
   .data1   : { *(.data1) }
   .preinit_array     :
   {
-    PROVIDE_HIDDEN (__preinit_array_start = .);
+    PROVIDE (__preinit_array_start = .);
     KEEP (*(.preinit_array))
-    PROVIDE_HIDDEN (__preinit_array_end = .);
+    PROVIDE (__preinit_array_end = .);
   }
   .init_array     :
   {
-     PROVIDE_HIDDEN (__init_array_start = .);
+     PROVIDE (__init_array_start = .);
      KEEP (*(SORT(.init_array.*)))
      KEEP (*(.init_array))
-     PROVIDE_HIDDEN (__init_array_end = .);
+     PROVIDE (__init_array_end = .);
   }
   .fini_array     :
   {
-    PROVIDE_HIDDEN (__fini_array_start = .);
+    PROVIDE (__fini_array_start = .);
     KEEP (*(.fini_array))
     KEEP (*(SORT(.fini_array.*)))
-    PROVIDE_HIDDEN (__fini_array_end = .);
+    PROVIDE (__fini_array_end = .);
   }
   .ctors         :
   {
diff --git a/hppa.ld b/hppa.ld
index 9a4b22c..3555b3e 100644
--- a/hppa.ld
+++ b/hppa.ld
@@ -75,36 +75,34 @@ SECTIONS
   .sbss2          : { *(.sbss2 .sbss2.* .gnu.linkonce.sb2.*) }
   .PARISC.unwind   : { *(.PARISC.unwind) }
   .eh_frame_hdr : { *(.eh_frame_hdr) }
-  .eh_frame       : ONLY_IF_RO { KEEP (*(.eh_frame)) }
-  .gcc_except_table   : ONLY_IF_RO { *(.gcc_except_table .gcc_except_table.*) }
   /* Adjust the address for the data segment.  We want to adjust up to
      the same address within the page on the next page up.  */
   . = ALIGN(0x10000) + (. & (0x10000 - 1));
   /* Exception handling  */
-  .eh_frame       : ONLY_IF_RW { KEEP (*(.eh_frame)) }
-  .gcc_except_table   : ONLY_IF_RW { *(.gcc_except_table .gcc_except_table.*) }
+  .eh_frame       : { KEEP (*(.eh_frame)) }
+  .gcc_except_table   : { *(.gcc_except_table .gcc_except_table.*) }
   /* Thread Local Storage sections  */
   .tdata	  : { *(.tdata .tdata.* .gnu.linkonce.td.*) }
   .tbss		  : { *(.tbss .tbss.* .gnu.linkonce.tb.*) *(.tcommon) }
   .preinit_array     :
   {
-    PROVIDE_HIDDEN (__preinit_array_start = .);
+    PROVIDE (__preinit_array_start = .);
     KEEP (*(.preinit_array))
-    PROVIDE_HIDDEN (__preinit_array_end = .);
+    PROVIDE (__preinit_array_end = .);
   }
   .init_array     :
   {
-     PROVIDE_HIDDEN (__init_array_start = .);
+     PROVIDE (__init_array_start = .);
      KEEP (*(SORT(.init_array.*)))
      KEEP (*(.init_array))
-     PROVIDE_HIDDEN (__init_array_end = .);
+     PROVIDE (__init_array_end = .);
   }
   .fini_array     :
   {
-    PROVIDE_HIDDEN (__fini_array_start = .);
+    PROVIDE (__fini_array_start = .);
     KEEP (*(.fini_array))
     KEEP (*(SORT(.fini_array.*)))
-    PROVIDE_HIDDEN (__fini_array_end = .);
+    PROVIDE (__fini_array_end = .);
   }
   .ctors          :
   {
diff --git a/i386.ld b/i386.ld
index f8df7bf..cc3f160 100644
--- a/i386.ld
+++ b/i386.ld
@@ -42,16 +42,16 @@ SECTIONS
   .rel.plt      :
   {
     *(.rel.plt)
-    PROVIDE_HIDDEN (__rel_iplt_start = .);
+    PROVIDE (__rel_iplt_start = .);
     *(.rel.iplt)
-    PROVIDE_HIDDEN (__rel_iplt_end = .);
+    PROVIDE (__rel_iplt_end = .);
   }
   .rela.plt       :
   {
     *(.rela.plt)
-    PROVIDE_HIDDEN (__rela_iplt_start = .);
+    PROVIDE (__rela_iplt_start = .);
     *(.rela.iplt)
-    PROVIDE_HIDDEN (__rela_iplt_end = .);
+    PROVIDE (__rela_iplt_end = .);
   }
   .init          : { *(.init)	} =0x47ff041f
   .text      :
diff --git a/mips.ld b/mips.ld
index 4294761..7b610ce 100644
--- a/mips.ld
+++ b/mips.ld
@@ -79,36 +79,34 @@ SECTIONS
   }
   .sbss2          : { *(.sbss2 .sbss2.* .gnu.linkonce.sb2.*) }
   .eh_frame_hdr : { *(.eh_frame_hdr) }
-  .eh_frame       : ONLY_IF_RO { KEEP (*(.eh_frame)) }
-  .gcc_except_table   : ONLY_IF_RO { *(.gcc_except_table .gcc_except_table.*) }
   /* Adjust the address for the data segment.  We want to adjust up to
      the same address within the page on the next page up.  */
   . = ALIGN (0x40000) - ((0x40000 - .) & (0x40000 - 1)); . = DATA_SEGMENT_ALIGN (0x40000, 0x1000);
   /* Exception handling  */
-  .eh_frame       : ONLY_IF_RW { KEEP (*(.eh_frame)) }
-  .gcc_except_table   : ONLY_IF_RW { *(.gcc_except_table .gcc_except_table.*) }
+  .eh_frame       : { KEEP (*(.eh_frame)) }
+  .gcc_except_table   : { *(.gcc_except_table .gcc_except_table.*) }
   /* Thread Local Storage sections  */
   .tdata         : { *(.tdata .tdata.* .gnu.linkonce.td.*) }
   .tbss                  : { *(.tbss .tbss.* .gnu.linkonce.tb.*) *(.tcommon) }
   .preinit_array     :
   {
-    PROVIDE_HIDDEN (__preinit_array_start = .);
+    PROVIDE (__preinit_array_start = .);
     KEEP (*(.preinit_array))
-    PROVIDE_HIDDEN (__preinit_array_end = .);
+    PROVIDE (__preinit_array_end = .);
   }
   .init_array     :
   {
-     PROVIDE_HIDDEN (__init_array_start = .);
+     PROVIDE (__init_array_start = .);
      KEEP (*(SORT(.init_array.*)))
      KEEP (*(.init_array))
-     PROVIDE_HIDDEN (__init_array_end = .);
+     PROVIDE (__init_array_end = .);
   }
   .fini_array     :
   {
-    PROVIDE_HIDDEN (__fini_array_start = .);
+    PROVIDE (__fini_array_start = .);
     KEEP (*(.fini_array))
     KEEP (*(SORT(.fini_array.*)))
-    PROVIDE_HIDDEN (__fini_array_end = .);
+    PROVIDE (__fini_array_end = .);
   }
   .ctors          :
   {
diff --git a/ppc.ld b/ppc.ld
index 5248ef1..69aa3f2 100644
--- a/ppc.ld
+++ b/ppc.ld
@@ -79,36 +79,34 @@ SECTIONS
   }
   .sbss2          : { *(.sbss2 .sbss2.* .gnu.linkonce.sb2.*) }
   .eh_frame_hdr : { *(.eh_frame_hdr) }
-  .eh_frame       : ONLY_IF_RO { KEEP (*(.eh_frame)) }
-  .gcc_except_table   : ONLY_IF_RO { *(.gcc_except_table .gcc_except_table.*) }
   /* Adjust the address for the data segment.  We want to adjust up to
      the same address within the page on the next page up.  */
   . = ALIGN (0x10000) - ((0x10000 - .) & (0x10000 - 1)); . = DATA_SEGMENT_ALIGN (0x10000, 0x1000);
   /* Exception handling  */
-  .eh_frame       : ONLY_IF_RW { KEEP (*(.eh_frame)) }
-  .gcc_except_table   : ONLY_IF_RW { *(.gcc_except_table .gcc_except_table.*) }
+  .eh_frame       : { KEEP (*(.eh_frame)) }
+  .gcc_except_table   : { *(.gcc_except_table .gcc_except_table.*) }
   /* Thread Local Storage sections  */
   .tdata	  : { *(.tdata .tdata.* .gnu.linkonce.td.*) }
   .tbss		  : { *(.tbss .tbss.* .gnu.linkonce.tb.*) *(.tcommon) }
   .preinit_array     :
   {
-    PROVIDE_HIDDEN (__preinit_array_start = .);
+    PROVIDE (__preinit_array_start = .);
     KEEP (*(.preinit_array))
-    PROVIDE_HIDDEN (__preinit_array_end = .);
+    PROVIDE (__preinit_array_end = .);
   }
   .init_array     :
   {
-     PROVIDE_HIDDEN (__init_array_start = .);
+     PROVIDE (__init_array_start = .);
      KEEP (*(SORT(.init_array.*)))
      KEEP (*(.init_array))
-     PROVIDE_HIDDEN (__init_array_end = .);
+     PROVIDE (__init_array_end = .);
   }
   .fini_array     :
   {
-    PROVIDE_HIDDEN (__fini_array_start = .);
+    PROVIDE (__fini_array_start = .);
     KEEP (*(.fini_array))
     KEEP (*(SORT(.fini_array.*)))
-    PROVIDE_HIDDEN (__fini_array_end = .);
+    PROVIDE (__fini_array_end = .);
   }
   .ctors          :
   {
diff --git a/ppc64.ld b/ppc64.ld
index dea0dbd..0059ee5 100644
--- a/ppc64.ld
+++ b/ppc64.ld
@@ -81,14 +81,12 @@ SECTIONS
   .sdata2         : { *(.sdata2 .sdata2.* .gnu.linkonce.s2.*) }
   .sbss2          : { *(.sbss2 .sbss2.* .gnu.linkonce.sb2.*) }
   .eh_frame_hdr : { *(.eh_frame_hdr) }
-  .eh_frame       : ONLY_IF_RO { KEEP (*(.eh_frame)) }
-  .gcc_except_table   : ONLY_IF_RO { KEEP (*(.gcc_except_table))
 *(.gcc_except_table.*) } /* Adjust the address for the data segment.  We want to
 adjust up to +     the same address within the page on the next page up.  */
   . = ALIGN (0x10000) - ((0x10000 - .) & (0x10000 - 1)); . = DATA_SEGMENT_ALIGN
 (0x10000, 0x1000);   /* Exception handling  */
-  .eh_frame       : ONLY_IF_RW { KEEP (*(.eh_frame)) }
-  .gcc_except_table   : ONLY_IF_RW { KEEP (*(.gcc_except_table))
+  .eh_frame       : { KEEP (*(.eh_frame)) }
+  .gcc_except_table   : { KEEP (*(.gcc_except_table))
 *(.gcc_except_table.*) }   /* Thread Local Storage sections  */
   .tdata	  : { *(.tdata .tdata.* .gnu.linkonce.td.*) }
   .tbss		  : { *(.tbss .tbss.* .gnu.linkonce.tb.*) *(.tcommon) }
diff --git a/sparc.ld b/sparc.ld
index 31321be..56efe34 100644
--- a/sparc.ld
+++ b/sparc.ld
@@ -67,23 +67,23 @@ SECTIONS
   .tbss    : { *(.tbss) }
   .preinit_array     :
   {
-    PROVIDE_HIDDEN (__preinit_array_start = .);
+    PROVIDE (__preinit_array_start = .);
     KEEP (*(.preinit_array))
-    PROVIDE_HIDDEN (__preinit_array_end = .);
+    PROVIDE (__preinit_array_end = .);
   }
   .init_array     :
   {
-     PROVIDE_HIDDEN (__init_array_start = .);
+     PROVIDE (__init_array_start = .);
      KEEP (*(SORT(.init_array.*)))
      KEEP (*(.init_array))
-     PROVIDE_HIDDEN (__init_array_end = .);
+     PROVIDE (__init_array_end = .);
   }
   .fini_array     :
   {
-    PROVIDE_HIDDEN (__fini_array_start = .);
+    PROVIDE (__fini_array_start = .);
     KEEP (*(.fini_array))
     KEEP (*(SORT(.fini_array.*)))
-    PROVIDE_HIDDEN (__fini_array_end = .);
+    PROVIDE (__fini_array_end = .);
   }
   .ctors         :
   {
diff --git a/x86_64.ld b/x86_64.ld
index 46d8d4d..b7a9f4e 100644
--- a/x86_64.ld
+++ b/x86_64.ld
@@ -38,16 +38,16 @@ SECTIONS
   .rel.plt      :
   {
     *(.rel.plt)
-    PROVIDE_HIDDEN (__rel_iplt_start = .);
+    PROVIDE (__rel_iplt_start = .);
     *(.rel.iplt)
-    PROVIDE_HIDDEN (__rel_iplt_end = .);
+    PROVIDE (__rel_iplt_end = .);
   }
   .rela.plt       :
   {
     *(.rela.plt)
-    PROVIDE_HIDDEN (__rela_iplt_start = .);
+    PROVIDE (__rela_iplt_start = .);
     *(.rela.iplt)
-    PROVIDE_HIDDEN (__rela_iplt_end = .);
+    PROVIDE (__rela_iplt_end = .);
   }
   .init           :
   {
@@ -70,8 +70,6 @@ SECTIONS
   .rodata         : { *(.rodata .rodata.* .gnu.linkonce.r.*) }
   .rodata1        : { *(.rodata1) }
   .eh_frame_hdr : { *(.eh_frame_hdr) }
-  .eh_frame       : ONLY_IF_RO { KEEP (*(.eh_frame)) }
-  .gcc_except_table   : ONLY_IF_RO { *(.gcc_except_table) }
   /* Adjust the address for the data segment.  We want to adjust up to
      the same address within the page on the next page up.  */
   . = ALIGN (0x100000) - ((0x100000 - .) & (0x100000 - 1)); . = DATA_SEGMENT_ALIGN (0x100000, 0x1000);
@@ -97,8 +95,8 @@ SECTIONS
   .data1          : { *(.data1) }
   .tdata	  : { *(.tdata .tdata.* .gnu.linkonce.td.*) }
   .tbss		  : { *(.tbss .tbss.* .gnu.linkonce.tb.*) *(.tcommon) }
-  .eh_frame       : ONLY_IF_RW { KEEP (*(.eh_frame)) }
-  .gcc_except_table   : ONLY_IF_RW { *(.gcc_except_table) }
+  .eh_frame       : { KEEP (*(.eh_frame)) }
+  .gcc_except_table   : { *(.gcc_except_table) }
   .dynamic        : { *(.dynamic) }
   .ctors          :
   {
commit 0fc6b5828ff23d81aff6f48cb168bfe82548e1d7
Author: Brad <brad at comstyle.com>
Date:   Mon Aug 22 16:39:59 2011 -0400

    Fix build on OpenBSD with BSD userland emu and smartcard NSS enabled
    
    The first issue is the hard coded POSIX Real Time extensions library in the
    libcacard/Makefile. From looking at the code it doesn't seem this is necessary
    anyway. Robert Relyea seems to think it most likely isn't necessary.
    
    The second issue was the missing exclusion of the BSD userland binary
    builds from the addition of this Makefile target for the smartcard NSS
    code which breaks the builds if smartcard NSS support is enabled.
    
    pastebin clip of the build failure..
    
    http://pastebin.com/raw.php?i=BLCKd3s6
    
    Signed-off-by: Brad Smith <brad at comstyle.com>
    Signed-off-by: Blue Swirl <blauwirbel at gmail.com>

diff --git a/Makefile.target b/Makefile.target
index e280bf6..07af4d4 100644
--- a/Makefile.target
+++ b/Makefile.target
@@ -387,9 +387,11 @@ obj-y += $(addprefix $(HWDIR)/, $(hw-obj-y))
 endif # CONFIG_SOFTMMU
 
 ifndef CONFIG_LINUX_USER
+ifndef CONFIG_BSD_USER
 # libcacard needs qemu-thread support, and besides is only needed by devices
-# so not requires with linux-user targets
+# so not requires with linux-user / bsd-user targets
 obj-$(CONFIG_SMARTCARD_NSS) += $(addprefix ../libcacard/, $(libcacard-y))
+endif # CONFIG_BSD_USER
 endif # CONFIG_LINUX_USER
 
 obj-y += $(addprefix ../, $(trace-obj-y))
diff --git a/libcacard/Makefile b/libcacard/Makefile
index b3f5e6c..bf052bc 100644
--- a/libcacard/Makefile
+++ b/libcacard/Makefile
@@ -20,7 +20,7 @@ QEMU_CFLAGS+=$(GLIB_CFLAGS)
 libcacard.lib-y=$(addsuffix .lo,$(basename $(libcacard-y)))
 
 vscclient: $(libcacard-y) $(QEMU_OBJS) vscclient.o
-	$(call quiet-command,$(CC) -o $@ $^ $(libcacard_libs) $(LIBS) -lrt,"  LINK  $@")
+	$(call quiet-command,$(CC) -o $@ $^ $(libcacard_libs) $(LIBS),"  LINK  $@")
 
 clean:
 	rm -f *.o */*.o *.d */*.d *.a */*.a *~ */*~ vscclient *.lo .libs/* *.la *.pc
@@ -39,7 +39,7 @@ install-libcacard:
 	@echo "libtool is missing, please install and rerun configure"; exit 1
 else
 libcacard.la: $(libcacard.lib-y) $(QEMU_OBJS_LIB)
-	$(call quiet-command,$(LIBTOOL) --mode=link --quiet --tag=CC $(CC) -rpath $(libdir) -o $@ $^ $(libcacard_libs) -lrt,"  lt LINK $@")
+	$(call quiet-command,$(LIBTOOL) --mode=link --quiet --tag=CC $(CC) -rpath $(libdir) -o $@ $^ $(libcacard_libs),"  lt LINK $@")
 
 libcacard.pc: $(libcacard_srcpath)/libcacard.pc.in
 	sed -e 's|@LIBDIR@|$(libdir)|' \
commit c488c7f649106d09df76f697adccbe6e72520b26
Author: Christoph Hellwig <hch at lst.de>
Date:   Thu Aug 25 08:26:10 2011 +0200

    block: latency accounting
    
    Account the total latency for read/write/flush requests.  This allows
    management tools to average it based on a snapshot of the nr ops
    counters and allow checking for SLAs or provide statistics.
    
    Signed-off-by: Christoph Hellwig <hch at lst.de>
    Signed-off-by: Kevin Wolf <kwolf at redhat.com>

diff --git a/block.c b/block.c
index 24fba37..03a21d8 100644
--- a/block.c
+++ b/block.c
@@ -1916,12 +1916,18 @@ static void bdrv_stats_iter(QObject *data, void *opaque)
                         " rd_operations=%" PRId64
                         " wr_operations=%" PRId64
                         " flush_operations=%" PRId64
+                        " wr_total_time_ns=%" PRId64
+                        " rd_total_time_ns=%" PRId64
+                        " flush_total_time_ns=%" PRId64
                         "\n",
                         qdict_get_int(qdict, "rd_bytes"),
                         qdict_get_int(qdict, "wr_bytes"),
                         qdict_get_int(qdict, "rd_operations"),
                         qdict_get_int(qdict, "wr_operations"),
-                        qdict_get_int(qdict, "flush_operations"));
+                        qdict_get_int(qdict, "flush_operations"),
+                        qdict_get_int(qdict, "wr_total_time_ns"),
+                        qdict_get_int(qdict, "rd_total_time_ns"),
+                        qdict_get_int(qdict, "flush_total_time_ns"));
 }
 
 void bdrv_stats_print(Monitor *mon, const QObject *data)
@@ -1940,7 +1946,10 @@ static QObject* bdrv_info_stats_bs(BlockDriverState *bs)
                              "'rd_operations': %" PRId64 ","
                              "'wr_operations': %" PRId64 ","
                              "'wr_highest_offset': %" PRId64 ","
-                             "'flush_operations': %" PRId64
+                             "'flush_operations': %" PRId64 ","
+                             "'wr_total_time_ns': %" PRId64 ","
+                             "'rd_total_time_ns': %" PRId64 ","
+                             "'flush_total_time_ns': %" PRId64
                              "} }",
                              bs->nr_bytes[BDRV_ACCT_READ],
                              bs->nr_bytes[BDRV_ACCT_WRITE],
@@ -1948,7 +1957,10 @@ static QObject* bdrv_info_stats_bs(BlockDriverState *bs)
                              bs->nr_ops[BDRV_ACCT_WRITE],
                              bs->wr_highest_sector *
                              (uint64_t)BDRV_SECTOR_SIZE,
-                             bs->nr_ops[BDRV_ACCT_FLUSH]);
+                             bs->nr_ops[BDRV_ACCT_FLUSH],
+                             bs->total_time_ns[BDRV_ACCT_WRITE],
+                             bs->total_time_ns[BDRV_ACCT_READ],
+                             bs->total_time_ns[BDRV_ACCT_FLUSH]);
     dict  = qobject_to_qdict(res);
 
     if (*bs->device_name) {
@@ -3160,6 +3172,7 @@ bdrv_acct_start(BlockDriverState *bs, BlockAcctCookie *cookie, int64_t bytes,
     assert(type < BDRV_MAX_IOTYPE);
 
     cookie->bytes = bytes;
+    cookie->start_time_ns = get_clock();
     cookie->type = type;
 }
 
@@ -3170,6 +3183,7 @@ bdrv_acct_done(BlockDriverState *bs, BlockAcctCookie *cookie)
 
     bs->nr_bytes[cookie->type] += cookie->bytes;
     bs->nr_ops[cookie->type]++;
+    bs->total_time_ns[cookie->type] += get_clock() - cookie->start_time_ns;
 }
 
 int bdrv_img_create(const char *filename, const char *fmt,
diff --git a/block.h b/block.h
index df06af5..3ac0b94 100644
--- a/block.h
+++ b/block.h
@@ -264,6 +264,7 @@ enum BlockAcctType {
 
 typedef struct BlockAcctCookie {
     int64_t bytes;
+    int64_t start_time_ns;
     enum BlockAcctType type;
 } BlockAcctCookie;
 
diff --git a/block_int.h b/block_int.h
index 5f8050d..8a72b80 100644
--- a/block_int.h
+++ b/block_int.h
@@ -28,6 +28,7 @@
 #include "qemu-option.h"
 #include "qemu-queue.h"
 #include "qemu-coroutine.h"
+#include "qemu-timer.h"
 
 #define BLOCK_FLAG_ENCRYPT	1
 #define BLOCK_FLAG_COMPAT6	4
@@ -186,6 +187,7 @@ struct BlockDriverState {
     /* I/O stats (display with "info blockstats"). */
     uint64_t nr_bytes[BDRV_MAX_IOTYPE];
     uint64_t nr_ops[BDRV_MAX_IOTYPE];
+    uint64_t total_time_ns[BDRV_MAX_IOTYPE];
     uint64_t wr_highest_sector;
 
     /* Whether the disk can expand beyond total_sectors */
diff --git a/qmp-commands.hx b/qmp-commands.hx
index 8570b33..27cc66e 100644
--- a/qmp-commands.hx
+++ b/qmp-commands.hx
@@ -1202,6 +1202,9 @@ Each json-object contain the following:
     - "rd_operations": read operations (json-int)
     - "wr_operations": write operations (json-int)
     - "flush_operations": cache flush operations (json-int)
+    - "wr_total_time_ns": total time spend on writes in nano-seconds (json-int)
+    - "rd_total_time_ns": total time spend on reads in nano-seconds (json-int)
+    - "flush_total_time_ns": total time spend on cache flushes in nano-seconds (json-int)
     - "wr_highest_offset": Highest offset of a sector written since the
                            BlockDriverState has been opened (json-int)
 - "parent": Contains recursively the statistics of the underlying
@@ -1223,6 +1226,9 @@ Example:
                   "wr_operations":751,
                   "rd_bytes":122567168,
                   "rd_operations":36772
+                  "wr_total_times_ns":313253456
+                  "rd_total_times_ns":3465673657
+                  "flush_total_times_ns":49653
                   "flush_operations":61,
                }
             },
@@ -1233,6 +1239,9 @@ Example:
                "rd_bytes":122739200,
                "rd_operations":36604
                "flush_operations":51,
+               "wr_total_times_ns":313253456
+               "rd_total_times_ns":3465673657
+               "flush_total_times_ns":49653
             }
          },
          {
@@ -1244,6 +1253,9 @@ Example:
                "rd_bytes":0,
                "rd_operations":0
                "flush_operations":0,
+               "wr_total_times_ns":0
+               "rd_total_times_ns":0
+               "flush_total_times_ns":0
             }
          },
          {
@@ -1255,6 +1267,9 @@ Example:
                "rd_bytes":0,
                "rd_operations":0
                "flush_operations":0,
+               "wr_total_times_ns":0
+               "rd_total_times_ns":0
+               "flush_total_times_ns":0
             }
          },
          {
@@ -1266,6 +1281,9 @@ Example:
                "rd_bytes":0,
                "rd_operations":0
                "flush_operations":0,
+               "wr_total_times_ns":0
+               "rd_total_times_ns":0
+               "flush_total_times_ns":0
             }
          }
       ]
commit b0b3db79559e57db340b292621c397e7a6cdbdc5
Author: Michael S. Tsirkin <mst at redhat.com>
Date:   Thu Aug 11 10:21:18 2011 +0300

    vhost-net: cleanup host notifiers at last step
    
    When the vhost notifier is disabled, the userspace handler runs
    immediately: virtio_pci_set_host_notifier_internal might
    call virtio_queue_notify_vq.
    Since the VQ state and the tap backend state aren't
    recovered yet, this causes
    "Guest moved used index from XXX to YYY" assertions.
    
    The solution is to split out host notifier handling
    from vhost VQ setup and disable notifiers as our last step
    when we stop vhost-net. For symmetry enable them first thing
    on start.
    
    Signed-off-by: Michael S. Tsirkin <mst at redhat.com>

diff --git a/hw/vhost.c b/hw/vhost.c
index 1886067..0870cb7 100644
--- a/hw/vhost.c
+++ b/hw/vhost.c
@@ -515,11 +515,6 @@ static int vhost_virtqueue_init(struct vhost_dev *dev,
     };
     struct VirtQueue *vvq = virtio_get_queue(vdev, idx);
 
-    if (!vdev->binding->set_host_notifier) {
-        fprintf(stderr, "binding does not support host notifiers\n");
-        return -ENOSYS;
-    }
-
     vq->num = state.num = virtio_queue_get_num(vdev, idx);
     r = ioctl(dev->control, VHOST_SET_VRING_NUM, &state);
     if (r) {
@@ -567,12 +562,6 @@ static int vhost_virtqueue_init(struct vhost_dev *dev,
         r = -errno;
         goto fail_alloc;
     }
-    r = vdev->binding->set_host_notifier(vdev->binding_opaque, idx, true);
-    if (r < 0) {
-        fprintf(stderr, "Error binding host notifier: %d\n", -r);
-        goto fail_host_notifier;
-    }
-
     file.fd = event_notifier_get_fd(virtio_queue_get_host_notifier(vvq));
     r = ioctl(dev->control, VHOST_SET_VRING_KICK, &file);
     if (r) {
@@ -591,8 +580,6 @@ static int vhost_virtqueue_init(struct vhost_dev *dev,
 
 fail_call:
 fail_kick:
-    vdev->binding->set_host_notifier(vdev->binding_opaque, idx, false);
-fail_host_notifier:
 fail_alloc:
     cpu_physical_memory_unmap(vq->ring, virtio_queue_get_ring_size(vdev, idx),
                               0, 0);
@@ -618,12 +605,6 @@ static void vhost_virtqueue_cleanup(struct vhost_dev *dev,
         .index = idx,
     };
     int r;
-    r = vdev->binding->set_host_notifier(vdev->binding_opaque, idx, false);
-    if (r < 0) {
-        fprintf(stderr, "vhost VQ %d host cleanup failed: %d\n", idx, r);
-        fflush(stderr);
-    }
-    assert (r >= 0);
     r = ioctl(dev->control, VHOST_GET_VRING_BASE, &state);
     if (r < 0) {
         fprintf(stderr, "vhost VQ %d ring restore failed: %d\n", idx, r);
@@ -697,6 +678,60 @@ bool vhost_dev_query(struct vhost_dev *hdev, VirtIODevice *vdev)
         hdev->force;
 }
 
+/* Stop processing guest IO notifications in qemu.
+ * Start processing them in vhost in kernel.
+ */
+int vhost_dev_enable_notifiers(struct vhost_dev *hdev, VirtIODevice *vdev)
+{
+    int i, r;
+    if (!vdev->binding->set_host_notifier) {
+        fprintf(stderr, "binding does not support host notifiers\n");
+        r = -ENOSYS;
+        goto fail;
+    }
+
+    for (i = 0; i < hdev->nvqs; ++i) {
+        r = vdev->binding->set_host_notifier(vdev->binding_opaque, i, true);
+        if (r < 0) {
+            fprintf(stderr, "vhost VQ %d notifier binding failed: %d\n", i, -r);
+            goto fail_vq;
+        }
+    }
+
+    return 0;
+fail_vq:
+    while (--i >= 0) {
+        r = vdev->binding->set_host_notifier(vdev->binding_opaque, i, false);
+        if (r < 0) {
+            fprintf(stderr, "vhost VQ %d notifier cleanup error: %d\n", i, -r);
+            fflush(stderr);
+        }
+        assert (r >= 0);
+    }
+fail:
+    return r;
+}
+
+/* Stop processing guest IO notifications in vhost.
+ * Start processing them in qemu.
+ * This might actually run the qemu handlers right away,
+ * so virtio in qemu must be completely setup when this is called.
+ */
+void vhost_dev_disable_notifiers(struct vhost_dev *hdev, VirtIODevice *vdev)
+{
+    int i, r;
+
+    for (i = 0; i < hdev->nvqs; ++i) {
+        r = vdev->binding->set_host_notifier(vdev->binding_opaque, i, false);
+        if (r < 0) {
+            fprintf(stderr, "vhost VQ %d notifier cleanup failed: %d\n", i, -r);
+            fflush(stderr);
+        }
+        assert (r >= 0);
+    }
+}
+
+/* Host notifiers must be enabled at this point. */
 int vhost_dev_start(struct vhost_dev *hdev, VirtIODevice *vdev)
 {
     int i, r;
@@ -762,6 +797,7 @@ fail:
     return r;
 }
 
+/* Host notifiers must be enabled at this point. */
 void vhost_dev_stop(struct vhost_dev *hdev, VirtIODevice *vdev)
 {
     int i, r;
diff --git a/hw/vhost.h b/hw/vhost.h
index c8c595a..c9452f0 100644
--- a/hw/vhost.h
+++ b/hw/vhost.h
@@ -46,5 +46,7 @@ void vhost_dev_cleanup(struct vhost_dev *hdev);
 bool vhost_dev_query(struct vhost_dev *hdev, VirtIODevice *vdev);
 int vhost_dev_start(struct vhost_dev *hdev, VirtIODevice *vdev);
 void vhost_dev_stop(struct vhost_dev *hdev, VirtIODevice *vdev);
+int vhost_dev_enable_notifiers(struct vhost_dev *hdev, VirtIODevice *vdev);
+void vhost_dev_disable_notifiers(struct vhost_dev *hdev, VirtIODevice *vdev);
 
 #endif
diff --git a/hw/vhost_net.c b/hw/vhost_net.c
index a559812..950a6b8 100644
--- a/hw/vhost_net.c
+++ b/hw/vhost_net.c
@@ -139,16 +139,22 @@ int vhost_net_start(struct vhost_net *net,
 {
     struct vhost_vring_file file = { };
     int r;
+
+    net->dev.nvqs = 2;
+    net->dev.vqs = net->vqs;
+
+    r = vhost_dev_enable_notifiers(&net->dev, dev);
+    if (r < 0) {
+        goto fail_notifiers;
+    }
     if (net->dev.acked_features & (1 << VIRTIO_NET_F_MRG_RXBUF)) {
         tap_set_vnet_hdr_len(net->vc,
                              sizeof(struct virtio_net_hdr_mrg_rxbuf));
     }
 
-    net->dev.nvqs = 2;
-    net->dev.vqs = net->vqs;
     r = vhost_dev_start(&net->dev, dev);
     if (r < 0) {
-        return r;
+        goto fail_start;
     }
 
     net->vc->info->poll(net->vc, false);
@@ -173,6 +179,9 @@ fail:
     if (net->dev.acked_features & (1 << VIRTIO_NET_F_MRG_RXBUF)) {
         tap_set_vnet_hdr_len(net->vc, sizeof(struct virtio_net_hdr));
     }
+fail_start:
+    vhost_dev_disable_notifiers(&net->dev, dev);
+fail_notifiers:
     return r;
 }
 
@@ -190,6 +199,7 @@ void vhost_net_stop(struct vhost_net *net,
     if (net->dev.acked_features & (1 << VIRTIO_NET_F_MRG_RXBUF)) {
         tap_set_vnet_hdr_len(net->vc, sizeof(struct virtio_net_hdr));
     }
+    vhost_dev_disable_notifiers(&net->dev, dev);
 }
 
 void vhost_net_cleanup(struct vhost_net *net)
commit cb9c626888c5aa46d440db473e18806c72feb69e
Author: Edgar E. Iglesias <edgar.iglesias at gmail.com>
Date:   Mon Aug 22 18:44:58 2011 +0200

    linux-user: Correct a few missuses of host addresses
    
    Fix a few cases where we were passing host pointers to the
    guest.
    
    Signed-off-by: Edgar E. Iglesias <edgar.iglesias at gmail.com>

diff --git a/linux-user/signal.c b/linux-user/signal.c
index 07ad07a..89276eb 100644
--- a/linux-user/signal.c
+++ b/linux-user/signal.c
@@ -3064,10 +3064,10 @@ static void setup_frame(int sig, struct target_sigaction *ka,
         goto give_sigsegv;
 
     /* Set up registers for signal handler */
-    regs->gregs[15] = (unsigned long) frame;
+    regs->gregs[15] = frame_addr;
     regs->gregs[4] = signal; /* Arg for signal handler */
     regs->gregs[5] = 0;
-    regs->gregs[6] = (unsigned long) &frame->sc;
+    regs->gregs[6] = frame_addr += offsetof(typeof(*frame), sc);
     regs->pc = (unsigned long) ka->_sa_handler;
 
     unlock_user_struct(frame, frame_addr, 1);
@@ -3127,10 +3127,10 @@ static void setup_rt_frame(int sig, struct target_sigaction *ka,
         goto give_sigsegv;
 
     /* Set up registers for signal handler */
-    regs->gregs[15] = (unsigned long) frame;
+    regs->gregs[15] = frame_addr;
     regs->gregs[4] = signal; /* Arg for signal handler */
-    regs->gregs[5] = (unsigned long) &frame->info;
-    regs->gregs[6] = (unsigned long) &frame->uc;
+    regs->gregs[5] = frame_addr + offsetof(typeof(*frame), info);
+    regs->gregs[6] = frame_addr + offsetof(typeof(*frame), uc);
     regs->pc = (unsigned long) ka->_sa_handler;
 
     unlock_user_struct(frame, frame_addr, 1);
@@ -3381,11 +3381,12 @@ static void setup_frame(int sig, struct target_sigaction *ka,
         goto badframe;
 
     /* Set up registers for signal handler */
-    env->regs[1] = (unsigned long) frame;
+    env->regs[1] = frame_addr;
     /* Signal handler args: */
     env->regs[5] = sig; /* Arg 0: signum */
     env->regs[6] = 0;
-    env->regs[7] = (unsigned long) &frame->uc; /* arg 1: sigcontext */
+    /* arg 1: sigcontext */
+    env->regs[7] = frame_addr += offsetof(typeof(*frame), uc);
 
     /* Offset of 4 to handle microblaze rtid r14, 0 */
     env->sregs[SR_PC] = (unsigned long)ka->_sa_handler;
@@ -3559,11 +3560,11 @@ static void setup_frame(int sig, struct target_sigaction *ka,
 	setup_sigcontext(&frame->sc, env);
 
 	/* Move the stack and setup the arguments for the handler.  */
-	env->regs[R_SP] = (uint32_t) (unsigned long) frame;
+	env->regs[R_SP] = frame_addr;
 	env->regs[10] = sig;
 	env->pc = (unsigned long) ka->_sa_handler;
 	/* Link SRP so the guest returns through the trampoline.  */
-	env->pregs[PR_SRP] = (uint32_t) (unsigned long) &frame->retcode[0];
+	env->pregs[PR_SRP] = frame_addr + offsetof(typeof(*frame), retcode);
 
 	unlock_user_struct(frame, frame_addr, 1);
 	return;
@@ -3769,11 +3770,11 @@ static void setup_frame(int sig, struct target_sigaction *ka,
     }
 
     /* Set up registers for signal handler */
-    env->regs[15] = (target_ulong)(unsigned long) frame;
+    env->regs[15] = frame_addr;
     env->psw.addr = (target_ulong) ka->_sa_handler | PSW_ADDR_AMODE;
 
     env->regs[2] = sig; //map_signal(sig);
-    env->regs[3] = (target_ulong)(unsigned long) &frame->sc;
+    env->regs[3] = frame_addr += offsetof(typeof(*frame), sc);
 
     /* We forgot to include these in the sigcontext.
        To avoid breaking binary compatibility, they are passed as args. */
@@ -3844,12 +3845,12 @@ static void setup_rt_frame(int sig, struct target_sigaction *ka,
     }
 
     /* Set up registers for signal handler */
-    env->regs[15] = (target_ulong)(unsigned long) frame;
+    env->regs[15] = frame_addr;
     env->psw.addr = (target_ulong) ka->_sa_handler | PSW_ADDR_AMODE;
 
     env->regs[2] = sig; //map_signal(sig);
-    env->regs[3] = (target_ulong)(unsigned long) &frame->info;
-    env->regs[4] = (target_ulong)(unsigned long) &frame->uc;
+    env->regs[3] = frame_addr + offsetof(typeof(*frame), info);
+    env->regs[4] = frame_addr + offsetof(typeof(*frame), uc);
     return;
 
 give_sigsegv:
commit 75f5941cb583712b37a557ce61b95eeba91f520e
Author: Avi Kivity <avi at redhat.com>
Date:   Fri Aug 26 00:35:15 2011 +0300

    memory: add opaque parameter to memory_region_init_rom_device()
    
    The MemoryRegionOps callbacks expect it.
    
    Signed-off-by: Avi Kivity <avi at redhat.com>

diff --git a/memory.c b/memory.c
index b91c5da..1491a39 100644
--- a/memory.c
+++ b/memory.c
@@ -962,12 +962,14 @@ void memory_region_init_alias(MemoryRegion *mr,
 
 void memory_region_init_rom_device(MemoryRegion *mr,
                                    const MemoryRegionOps *ops,
+                                   void *opaque,
                                    DeviceState *dev,
                                    const char *name,
                                    uint64_t size)
 {
     memory_region_init(mr, name, size);
     mr->ops = ops;
+    mr->opaque = opaque;
     mr->terminates = true;
     mr->destructor = memory_region_destructor_rom_device;
     mr->ram_addr = qemu_ram_alloc(dev, name, size);
diff --git a/memory.h b/memory.h
index 0553cc7..06b83ae 100644
--- a/memory.h
+++ b/memory.h
@@ -235,6 +235,7 @@ void memory_region_init_alias(MemoryRegion *mr,
  */
 void memory_region_init_rom_device(MemoryRegion *mr,
                                    const MemoryRegionOps *ops,
+                                   void *opaque,
                                    DeviceState *dev, /* FIXME: layering violation */
                                    const char *name,
                                    uint64_t size);
commit 8a84fc6bf7cd9de567a13ced6cd4f481274f006d
Author: Edgar E. Iglesias <edgar.iglesias at petalogix.com>
Date:   Thu Aug 25 16:41:19 2011 +1000

    microblaze: Add an MSR_PVR constant and use it.
    
    Signed-off-by: Edgar E. Iglesias <edgar.iglesias at petalogix.com>

diff --git a/target-microblaze/cpu.h b/target-microblaze/cpu.h
index a81da62..3530286 100644
--- a/target-microblaze/cpu.h
+++ b/target-microblaze/cpu.h
@@ -65,6 +65,7 @@ struct CPUMBState;
 #define MSR_DCE (1<<7) /* 0x080 */
 #define MSR_EE  (1<<8) /* 0x100 */
 #define MSR_EIP (1<<9) /* 0x200 */
+#define MSR_PVR (1<<10) /* 0x400 */
 #define MSR_CC  (1<<31)
 
 /* Machine State Register (MSR) Fields */
diff --git a/target-microblaze/translate.c b/target-microblaze/translate.c
index 15f1fe5..366fd3e 100644
--- a/target-microblaze/translate.c
+++ b/target-microblaze/translate.c
@@ -429,8 +429,8 @@ static inline void msr_write(DisasContext *dc, TCGv v)
     t = tcg_temp_new();
     dc->cpustate_changed = 1;
     /* PVR bit is not writable.  */
-    tcg_gen_andi_tl(t, v, ~(1 << 10));
-    tcg_gen_andi_tl(cpu_SR[SR_MSR], cpu_SR[SR_MSR], (1 << 10));
+    tcg_gen_andi_tl(t, v, ~MSR_PVR);
+    tcg_gen_andi_tl(cpu_SR[SR_MSR], cpu_SR[SR_MSR], MSR_PVR);
     tcg_gen_or_tl(cpu_SR[SR_MSR], cpu_SR[SR_MSR], v);
     tcg_temp_free(t);
 }
commit 97b833c5df820acc5c7b3e63c84059857c115c45
Author: Edgar E. Iglesias <edgar.iglesias at petalogix.com>
Date:   Thu Aug 25 16:41:18 2011 +1000

    microblaze: Make the MSR PVR bit non writable
    
    Instead of hardcoding it to 1.
    
    Signed-off-by: Edgar E. Iglesias <edgar.iglesias at petalogix.com>

diff --git a/target-microblaze/translate.c b/target-microblaze/translate.c
index 1a862d3..15f1fe5 100644
--- a/target-microblaze/translate.c
+++ b/target-microblaze/translate.c
@@ -424,10 +424,15 @@ static inline void msr_read(DisasContext *dc, TCGv d)
 
 static inline void msr_write(DisasContext *dc, TCGv v)
 {
+    TCGv t;
+
+    t = tcg_temp_new();
     dc->cpustate_changed = 1;
-    tcg_gen_mov_tl(cpu_SR[SR_MSR], v);
-    /* PVR, we have a processor version register.  */
-    tcg_gen_ori_tl(cpu_SR[SR_MSR], cpu_SR[SR_MSR], (1 << 10));
+    /* PVR bit is not writable.  */
+    tcg_gen_andi_tl(t, v, ~(1 << 10));
+    tcg_gen_andi_tl(cpu_SR[SR_MSR], cpu_SR[SR_MSR], (1 << 10));
+    tcg_gen_or_tl(cpu_SR[SR_MSR], cpu_SR[SR_MSR], v);
+    tcg_temp_free(t);
 }
 
 static void dec_msr(DisasContext *dc)
commit 01e0451a08e0afb9af04783c320d70084cf4e574
Author: Anthony Liguori <aliguori at us.ibm.com>
Date:   Thu Aug 25 14:39:18 2011 -0500

    Revert "Merge remote-tracking branch 'qemu-kvm/memory/batch' into staging"
    
    This reverts commit 8ef9ea85a2cc1007eaefa53e6871f1f83bcef22d, reversing
    changes made to 444dc48298c480e42e15a8fe676be737d8a6b2a1.
    
    From Avi:
    
      Please revert the entire pull (git revert 8ef9ea85a2cc1) while I work this
      out - it isn't trivial.
    
    Signed-off-by: Anthony Liguori <aliguori at us.ibm.com>

diff --git a/Makefile.hw b/Makefile.hw
index 63eb7e4..659e441 100644
--- a/Makefile.hw
+++ b/Makefile.hw
@@ -10,7 +10,6 @@ include $(SRC_PATH)/rules.mak
 $(call set-vpath, $(SRC_PATH):$(SRC_PATH)/hw)
 
 QEMU_CFLAGS+=-I..
-QEMU_CFLAGS += $(GLIB_CFLAGS)
 
 include $(SRC_PATH)/Makefile.objs
 
diff --git a/Makefile.target b/Makefile.target
index c9957ae..e280bf6 100644
--- a/Makefile.target
+++ b/Makefile.target
@@ -195,6 +195,7 @@ obj-$(CONFIG_VIRTIO) += virtio.o virtio-blk.o virtio-balloon.o virtio-net.o virt
 obj-y += vhost_net.o
 obj-$(CONFIG_VHOST_NET) += vhost.o
 obj-$(CONFIG_REALLY_VIRTFS) += 9pfs/virtio-9p-device.o
+obj-y += rwhandler.o
 obj-$(CONFIG_KVM) += kvm.o kvm-all.o
 obj-$(CONFIG_NO_KVM) += kvm-stub.o
 obj-y += memory.o
diff --git a/hw/an5206.c b/hw/an5206.c
index 481ae60..04ca420 100644
--- a/hw/an5206.c
+++ b/hw/an5206.c
@@ -12,7 +12,6 @@
 #include "boards.h"
 #include "loader.h"
 #include "elf.h"
-#include "exec-memory.h"
 
 #define KERNEL_LOAD_ADDR 0x10000
 #define AN5206_MBAR_ADDR 0x10000000
@@ -38,9 +37,6 @@ static void an5206_init(ram_addr_t ram_size,
     int kernel_size;
     uint64_t elf_entry;
     target_phys_addr_t entry;
-    MemoryRegion *address_space_mem = get_system_memory();
-    MemoryRegion *ram = g_new(MemoryRegion, 1);
-    MemoryRegion *sram = g_new(MemoryRegion, 1);
 
     if (!cpu_model)
         cpu_model = "m5206";
@@ -56,12 +52,12 @@ static void an5206_init(ram_addr_t ram_size,
     env->rambar0 = AN5206_RAMBAR_ADDR | 1;
 
     /* DRAM at address zero */
-    memory_region_init_ram(ram, NULL, "an5206.ram", ram_size);
-    memory_region_add_subregion(address_space_mem, 0, ram);
+    cpu_register_physical_memory(0, ram_size,
+        qemu_ram_alloc(NULL, "an5206.ram", ram_size) | IO_MEM_RAM);
 
     /* Internal SRAM.  */
-    memory_region_init_ram(sram, NULL, "an5206.sram", 512);
-    memory_region_add_subregion(address_space_mem, AN5206_RAMBAR_ADDR, sram);
+    cpu_register_physical_memory(AN5206_RAMBAR_ADDR, 512,
+        qemu_ram_alloc(NULL, "an5206.sram", 512) | IO_MEM_RAM);
 
     mcf5206_init(AN5206_MBAR_ADDR, env);
 
diff --git a/hw/arm-misc.h b/hw/arm-misc.h
index af403a1..f8a7472 100644
--- a/hw/arm-misc.h
+++ b/hw/arm-misc.h
@@ -11,16 +11,13 @@
 #ifndef ARM_MISC_H
 #define ARM_MISC_H 1
 
-#include "memory.h"
-
 /* The CPU is also modeled as an interrupt controller.  */
 #define ARM_PIC_CPU_IRQ 0
 #define ARM_PIC_CPU_FIQ 1
 qemu_irq *arm_pic_init_cpu(CPUState *env);
 
 /* armv7m.c */
-qemu_irq *armv7m_init(MemoryRegion *address_space_mem,
-                      int flash_size, int sram_size,
+qemu_irq *armv7m_init(int flash_size, int sram_size,
                       const char *kernel_filename, const char *cpu_model);
 
 /* arm_boot.c */
diff --git a/hw/armv7m.c b/hw/armv7m.c
index 28d41b8..a932f16 100644
--- a/hw/armv7m.c
+++ b/hw/armv7m.c
@@ -156,8 +156,7 @@ static void armv7m_reset(void *opaque)
    flash_size and sram_size are in kb.
    Returns the NVIC array.  */
 
-qemu_irq *armv7m_init(MemoryRegion *address_space_mem,
-                      int flash_size, int sram_size,
+qemu_irq *armv7m_init(int flash_size, int sram_size,
                       const char *kernel_filename, const char *cpu_model)
 {
     CPUState *env;
@@ -170,9 +169,6 @@ qemu_irq *armv7m_init(MemoryRegion *address_space_mem,
     uint64_t lowaddr;
     int i;
     int big_endian;
-    MemoryRegion *sram = g_new(MemoryRegion, 1);
-    MemoryRegion *flash = g_new(MemoryRegion, 1);
-    MemoryRegion *hack = g_new(MemoryRegion, 1);
 
     flash_size *= 1024;
     sram_size *= 1024;
@@ -198,11 +194,12 @@ qemu_irq *armv7m_init(MemoryRegion *address_space_mem,
 #endif
 
     /* Flash programming is done via the SCU, so pretend it is ROM.  */
-    memory_region_init_ram(flash, NULL, "armv7m.flash", flash_size);
-    memory_region_set_readonly(flash, true);
-    memory_region_add_subregion(address_space_mem, 0, flash);
-    memory_region_init_ram(sram, NULL, "armv7m.sram", sram_size);
-    memory_region_add_subregion(address_space_mem, 0x20000000, sram);
+    cpu_register_physical_memory(0, flash_size,
+                                 qemu_ram_alloc(NULL, "armv7m.flash",
+                                                flash_size) | IO_MEM_ROM);
+    cpu_register_physical_memory(0x20000000, sram_size,
+                                 qemu_ram_alloc(NULL, "armv7m.sram",
+                                                sram_size) | IO_MEM_RAM);
     armv7m_bitband_init();
 
     nvic = qdev_create(NULL, "armv7m_nvic");
@@ -235,8 +232,9 @@ qemu_irq *armv7m_init(MemoryRegion *address_space_mem,
     /* Hack to map an additional page of ram at the top of the address
        space.  This stops qemu complaining about executing code outside RAM
        when returning from an exception.  */
-    memory_region_init_ram(hack, NULL, "armv7m.hack", 0x1000);
-    memory_region_add_subregion(address_space_mem, 0xfffff000, hack);
+    cpu_register_physical_memory(0xfffff000, 0x1000,
+                                 qemu_ram_alloc(NULL, "armv7m.hack", 
+                                                0x1000) | IO_MEM_RAM);
 
     qemu_register_reset(armv7m_reset, env);
     return pic;
diff --git a/hw/axis_dev88.c b/hw/axis_dev88.c
index 73eb39d..06200e2 100644
--- a/hw/axis_dev88.c
+++ b/hw/axis_dev88.c
@@ -31,7 +31,6 @@
 #include "elf.h"
 #include "cris-boot.h"
 #include "blockdev.h"
-#include "exec-memory.h"
 
 #define D(x)
 #define DNAND(x)
@@ -260,9 +259,8 @@ void axisdev88_init (ram_addr_t ram_size,
     int i;
     int nand_regs;
     int gpio_regs;
-    MemoryRegion *address_space_mem = get_system_memory();
-    MemoryRegion *phys_ram = g_new(MemoryRegion, 1);
-    MemoryRegion *phys_intmem = g_new(MemoryRegion, 1);
+    ram_addr_t phys_ram;
+    ram_addr_t phys_intmem;
 
     /* init CPUs */
     if (cpu_model == NULL) {
@@ -271,13 +269,15 @@ void axisdev88_init (ram_addr_t ram_size,
     env = cpu_init(cpu_model);
 
     /* allocate RAM */
-    memory_region_init_ram(phys_ram, NULL, "axisdev88.ram", ram_size);
-    memory_region_add_subregion(address_space_mem, 0x40000000, phys_ram);
+    phys_ram = qemu_ram_alloc(NULL, "axisdev88.ram", ram_size);
+    cpu_register_physical_memory(0x40000000, ram_size, phys_ram | IO_MEM_RAM);
 
     /* The ETRAX-FS has 128Kb on chip ram, the docs refer to it as the 
        internal memory.  */
-    memory_region_init_ram(phys_intmem, NULL, "axisdev88.chipram", INTMEM_SIZE);
-    memory_region_add_subregion(address_space_mem, 0x38000000, phys_intmem);
+    phys_intmem = qemu_ram_alloc(NULL, "axisdev88.chipram", INTMEM_SIZE);
+    cpu_register_physical_memory(0x38000000, INTMEM_SIZE,
+                                 phys_intmem | IO_MEM_RAM);
+
 
       /* Attach a NAND flash to CS1.  */
     nand = drive_get(IF_MTD, 0, 0);
diff --git a/hw/cirrus_vga.c b/hw/cirrus_vga.c
index ec7ea82..4d0ef0d 100644
--- a/hw/cirrus_vga.c
+++ b/hw/cirrus_vga.c
@@ -2424,7 +2424,6 @@ static void cirrus_update_memory_access(CirrusVGAState *s)
 {
     unsigned mode;
 
-    memory_region_transaction_begin();
     if ((s->vga.sr[0x17] & 0x44) == 0x44) {
         goto generic_io;
     } else if (s->cirrus_srcptr != s->cirrus_srcptr_end) {
@@ -2444,7 +2443,6 @@ static void cirrus_update_memory_access(CirrusVGAState *s)
             unmap_linear_vram(s);
         }
     }
-    memory_region_transaction_commit();
 }
 
 
diff --git a/hw/collie.c b/hw/collie.c
index 0b955e0..156404d 100644
--- a/hw/collie.c
+++ b/hw/collie.c
@@ -26,7 +26,7 @@ static void collie_init(ram_addr_t ram_size,
 {
     StrongARMState *s;
     DriveInfo *dinfo;
-    MemoryRegion *phys_flash = g_new(MemoryRegion, 2);
+    ram_addr_t phys_flash;
 
     if (!cpu_model) {
         cpu_model = "sa1110";
@@ -34,19 +34,17 @@ static void collie_init(ram_addr_t ram_size,
 
     s = sa1110_init(collie_binfo.ram_size, cpu_model);
 
-    memory_region_init_rom_device(&phys_flash[0], &pflash_cfi01_ops_le,
-                                  NULL, "collie.fl1", 0x02000000);
+    phys_flash = qemu_ram_alloc(NULL, "collie.fl1", 0x02000000);
     dinfo = drive_get(IF_PFLASH, 0, 0);
-    pflash_cfi01_register(SA_CS0, &phys_flash[0],
+    pflash_cfi01_register(SA_CS0, phys_flash,
                     dinfo ? dinfo->bdrv : NULL, (64 * 1024),
-                    512, 4, 0x00, 0x00, 0x00, 0x00);
+                    512, 4, 0x00, 0x00, 0x00, 0x00, 0);
 
-    memory_region_init_rom_device(&phys_flash[1], &pflash_cfi01_ops_le,
-                                  NULL, "collie.fl2", 0x02000000);
+    phys_flash = qemu_ram_alloc(NULL, "collie.fl2", 0x02000000);
     dinfo = drive_get(IF_PFLASH, 0, 1);
-    pflash_cfi01_register(SA_CS1, &phys_flash[1],
+    pflash_cfi01_register(SA_CS1, phys_flash,
                     dinfo ? dinfo->bdrv : NULL, (64 * 1024),
-                    512, 4, 0x00, 0x00, 0x00, 0x00);
+                    512, 4, 0x00, 0x00, 0x00, 0x00, 0);
 
     sysbus_create_simple("scoop", 0x40800000, NULL);
 
diff --git a/hw/dec_pci.c b/hw/dec_pci.c
index 1aec066..a35f382 100644
--- a/hw/dec_pci.c
+++ b/hw/dec_pci.c
@@ -80,15 +80,16 @@ PCIBus *pci_dec_21154_init(PCIBus *parent_bus, int devfn)
 static int pci_dec_21154_init_device(SysBusDevice *dev)
 {
     DECState *s;
+    int pci_mem_config, pci_mem_data;
 
     s = FROM_SYSBUS(DECState, dev);
 
-    memory_region_init_io(&s->host_state.conf_mem, &pci_host_conf_le_ops,
-                          &s->host_state, "pci-conf-idx", 0x1000);
-    memory_region_init_io(&s->host_state.data_mem, &pci_host_data_le_ops,
-                          &s->host_state, "pci-data-idx", 0x1000);
-    sysbus_init_mmio_region(dev, &s->host_state.conf_mem);
-    sysbus_init_mmio_region(dev, &s->host_state.data_mem);
+    pci_mem_config = pci_host_conf_register_mmio(&s->host_state,
+                                                 DEVICE_LITTLE_ENDIAN);
+    pci_mem_data = pci_host_data_register_mmio(&s->host_state,
+                                               DEVICE_LITTLE_ENDIAN);
+    sysbus_init_mmio(dev, 0x1000, pci_mem_config);
+    sysbus_init_mmio(dev, 0x1000, pci_mem_data);
     return 0;
 }
 
diff --git a/hw/dummy_m68k.c b/hw/dummy_m68k.c
index 30146b9..eed9e38 100644
--- a/hw/dummy_m68k.c
+++ b/hw/dummy_m68k.c
@@ -10,7 +10,6 @@
 #include "boards.h"
 #include "loader.h"
 #include "elf.h"
-#include "exec-memory.h"
 
 #define KERNEL_LOAD_ADDR 0x10000
 
@@ -22,8 +21,6 @@ static void dummy_m68k_init(ram_addr_t ram_size,
                      const char *initrd_filename, const char *cpu_model)
 {
     CPUState *env;
-    MemoryRegion *address_space_mem =  get_system_memory();
-    MemoryRegion *ram = g_new(MemoryRegion, 1);
     int kernel_size;
     uint64_t elf_entry;
     target_phys_addr_t entry;
@@ -40,8 +37,8 @@ static void dummy_m68k_init(ram_addr_t ram_size,
     env->vbr = 0;
 
     /* RAM at address zero */
-    memory_region_init_ram(ram, NULL, "dummy_m68k.ram", ram_size);
-    memory_region_add_subregion(address_space_mem, 0, ram);
+    cpu_register_physical_memory(0, ram_size,
+        qemu_ram_alloc(NULL, "dummy_m68k.ram", ram_size) | IO_MEM_RAM);
 
     /* Load kernel.  */
     if (kernel_filename) {
diff --git a/hw/flash.h b/hw/flash.h
index 7fb012b..140ae39 100644
--- a/hw/flash.h
+++ b/hw/flash.h
@@ -1,27 +1,21 @@
-#include "memory.h"
-
 /* NOR flash devices */
 typedef struct pflash_t pflash_t;
 
 /* pflash_cfi01.c */
-extern const MemoryRegionOps pflash_cfi01_ops_be;
-extern const MemoryRegionOps pflash_cfi01_ops_le;
-extern const MemoryRegionOps pflash_cfi02_ops_be;
-extern const MemoryRegionOps pflash_cfi02_ops_le;
-
-pflash_t *pflash_cfi01_register(target_phys_addr_t base, MemoryRegion *mem,
+pflash_t *pflash_cfi01_register(target_phys_addr_t base, ram_addr_t off,
                                 BlockDriverState *bs,
                                 uint32_t sector_len, int nb_blocs, int width,
                                 uint16_t id0, uint16_t id1,
-                                uint16_t id2, uint16_t id3);
+                                uint16_t id2, uint16_t id3, int be);
 
 /* pflash_cfi02.c */
-pflash_t *pflash_cfi02_register(target_phys_addr_t base, MemoryRegion *mem,
+pflash_t *pflash_cfi02_register(target_phys_addr_t base, ram_addr_t off,
                                 BlockDriverState *bs, uint32_t sector_len,
                                 int nb_blocs, int nb_mappings, int width,
                                 uint16_t id0, uint16_t id1,
                                 uint16_t id2, uint16_t id3,
-                                uint16_t unlock_addr0, uint16_t unlock_addr1);
+                                uint16_t unlock_addr0, uint16_t unlock_addr1,
+                                int be);
 
 /* nand.c */
 DeviceState *nand_init(BlockDriverState *bdrv, int manf_id, int chip_id);
diff --git a/hw/g364fb.c b/hw/g364fb.c
index a7731ec..b3020c5 100644
--- a/hw/g364fb.c
+++ b/hw/g364fb.c
@@ -36,7 +36,7 @@ do { fprintf(stderr, "g364 ERROR: " fmt , ## __VA_ARGS__);} while (0)
 typedef struct G364State {
     /* hardware */
     uint8_t *vram;
-    MemoryRegion vram_region;
+    ram_addr_t vram_offset;
     int vram_size;
     qemu_irq irq;
     /* registers */
@@ -68,17 +68,16 @@ typedef struct G364State {
 #define CTLA_FORCE_BLANK 0x00000400
 #define CTLA_NO_CURSOR   0x00800000
 
-static inline int check_dirty(G364State *s, ram_addr_t page)
+static inline int check_dirty(ram_addr_t page)
 {
-    return memory_region_get_dirty(&s->vram_region, page, DIRTY_MEMORY_VGA);
+    return cpu_physical_memory_get_dirty(page, VGA_DIRTY_FLAG);
 }
 
 static inline void reset_dirty(G364State *s,
                                ram_addr_t page_min, ram_addr_t page_max)
 {
-    memory_region_reset_dirty(&s->vram_region, page_min,
-                              page_max + TARGET_PAGE_SIZE - 1,
-                              DIRTY_MEMORY_VGA);
+    cpu_physical_memory_reset_dirty(page_min, page_max + TARGET_PAGE_SIZE - 1,
+                                    VGA_DIRTY_FLAG);
 }
 
 static void g364fb_draw_graphic8(G364State *s)
@@ -115,7 +114,7 @@ static void g364fb_draw_graphic8(G364State *s)
             return;
     }
 
-    page = 0;
+    page = s->vram_offset;
     page_min = (ram_addr_t)-1;
     page_max = 0;
 
@@ -136,7 +135,7 @@ static void g364fb_draw_graphic8(G364State *s)
     /* XXX: out of range in vram? */
     data_display = dd = ds_get_data(s->ds);
     while (y < s->height) {
-        if (check_dirty(s, page)) {
+        if (check_dirty(page)) {
             if (y < ymin)
                 ymin = ymax = y;
             if (page_min == (ram_addr_t)-1)
@@ -276,7 +275,7 @@ static inline void g364fb_invalidate_display(void *opaque)
 
     s->blanked = 0;
     for (i = 0; i < s->vram_size; i += TARGET_PAGE_SIZE) {
-        memory_region_set_dirty(&s->vram_region, i);
+        cpu_physical_memory_set_dirty(s->vram_offset + i);
     }
 }
 
@@ -412,7 +411,7 @@ static void g364_invalidate_cursor_position(G364State *s)
     end = (ymax + 1) * ds_get_linesize(s->ds);
 
     for (i = start; i < end; i += TARGET_PAGE_SIZE) {
-        memory_region_set_dirty(&s->vram_region, i);
+        cpu_physical_memory_set_dirty(s->vram_offset + i);
     }
 }
 
@@ -523,20 +522,16 @@ static void g364fb_ctrl_writeb(void *opaque, target_phys_addr_t addr, uint32_t v
     g364fb_ctrl_writel(opaque, addr & ~0x3, val);
 }
 
-static const MemoryRegionOps g364fb_ctrl_ops = {
-    .old_mmio = {
-        .read = {
-            g364fb_ctrl_readb,
-            g364fb_ctrl_readw,
-            g364fb_ctrl_readl,
-        },
-        .write = {
-            g364fb_ctrl_writeb,
-            g364fb_ctrl_writew,
-            g364fb_ctrl_writel,
-        },
-    },
-    .endianness = DEVICE_NATIVE_ENDIAN,
+static CPUReadMemoryFunc * const g364fb_ctrl_read[3] = {
+    g364fb_ctrl_readb,
+    g364fb_ctrl_readw,
+    g364fb_ctrl_readl,
+};
+
+static CPUWriteMemoryFunc * const g364fb_ctrl_write[3] = {
+    g364fb_ctrl_writeb,
+    g364fb_ctrl_writew,
+    g364fb_ctrl_writel,
 };
 
 static int g364fb_load(QEMUFile *f, void *opaque, int version_id)
@@ -588,19 +583,18 @@ static void g364fb_save(QEMUFile *f, void *opaque)
     qemu_put_be32(f, s->height);
 }
 
-int g364fb_mm_init(MemoryRegion *system_memory,
-                   target_phys_addr_t vram_base,
+int g364fb_mm_init(target_phys_addr_t vram_base,
                    target_phys_addr_t ctrl_base, int it_shift,
                    qemu_irq irq)
 {
     G364State *s;
-    MemoryRegion *io_ctrl = g_new(MemoryRegion, 1);
+    int io_ctrl;
 
     s = g_malloc0(sizeof(G364State));
 
     s->vram_size = 8 * 1024 * 1024;
-    memory_region_init_ram(&s->vram_region, NULL, "g364fb.vram", s->vram_size);
-    s->vram = memory_region_get_ram_ptr(&s->vram_region);
+    s->vram_offset = qemu_ram_alloc(NULL, "g364fb.vram", s->vram_size);
+    s->vram = qemu_get_ram_ptr(s->vram_offset);
     s->irq = irq;
 
     qemu_register_reset(g364fb_reset, s);
@@ -611,11 +605,11 @@ int g364fb_mm_init(MemoryRegion *system_memory,
                                  g364fb_invalidate_display,
                                  g364fb_screen_dump, NULL, s);
 
-    memory_region_add_subregion(system_memory, vram_base, &s->vram_region);
+    cpu_register_physical_memory(vram_base, s->vram_size, s->vram_offset);
 
-    memory_region_init_io(io_ctrl, &g364fb_ctrl_ops, s,
-                          "g364fb-ctrl", 0x200000);
-    memory_region_add_subregion(system_memory, ctrl_base, io_ctrl);
+    io_ctrl = cpu_register_io_memory(g364fb_ctrl_read, g364fb_ctrl_write, s,
+                                     DEVICE_NATIVE_ENDIAN);
+    cpu_register_physical_memory(ctrl_base, 0x200000, io_ctrl);
 
     return 0;
 }
diff --git a/hw/grackle_pci.c b/hw/grackle_pci.c
index 9d3ff7d..9a823e1 100644
--- a/hw/grackle_pci.c
+++ b/hw/grackle_pci.c
@@ -92,15 +92,16 @@ PCIBus *pci_grackle_init(uint32_t base, qemu_irq *pic,
 static int pci_grackle_init_device(SysBusDevice *dev)
 {
     GrackleState *s;
+    int pci_mem_config, pci_mem_data;
 
     s = FROM_SYSBUS(GrackleState, dev);
 
-    memory_region_init_io(&s->host_state.conf_mem, &pci_host_conf_le_ops,
-                          &s->host_state, "pci-conf-idx", 0x1000);
-    memory_region_init_io(&s->host_state.data_mem, &pci_host_data_le_ops,
-                          &s->host_state, "pci-data-idx", 0x1000);
-    sysbus_init_mmio_region(dev, &s->host_state.conf_mem);
-    sysbus_init_mmio_region(dev, &s->host_state.data_mem);
+    pci_mem_config = pci_host_conf_register_mmio(&s->host_state,
+                                                 DEVICE_LITTLE_ENDIAN);
+    pci_mem_data = pci_host_data_register_mmio(&s->host_state,
+                                               DEVICE_LITTLE_ENDIAN);
+    sysbus_init_mmio(dev, 0x1000, pci_mem_config);
+    sysbus_init_mmio(dev, 0x1000, pci_mem_data);
 
     qemu_register_reset(pci_grackle_reset, &s->host_state);
     return 0;
diff --git a/hw/gumstix.c b/hw/gumstix.c
index d3a4bb4..853f7e1 100644
--- a/hw/gumstix.c
+++ b/hw/gumstix.c
@@ -48,8 +48,7 @@ static void connex_init(ram_addr_t ram_size,
 {
     PXA2xxState *cpu;
     DriveInfo *dinfo;
-    const MemoryRegionOps *flash_ops;
-    MemoryRegion *flash = g_new(MemoryRegion, 1);
+    int be;
 
     uint32_t connex_rom = 0x01000000;
     uint32_t connex_ram = 0x04000000;
@@ -64,15 +63,14 @@ static void connex_init(ram_addr_t ram_size,
     }
 
 #ifdef TARGET_WORDS_BIGENDIAN
-    flash_ops = &pflash_cfi01_ops_be;
+    be = 1;
 #else
-    flash_ops = &pflash_cfi01_ops_le;
+    be = 0;
 #endif
-    memory_region_init_rom_device(flash, flash_ops,
-                                  NULL, "connext.rom", connex_rom);
-    if (!pflash_cfi01_register(0x00000000, flash,
+    if (!pflash_cfi01_register(0x00000000, qemu_ram_alloc(NULL, "connext.rom",
+                                                          connex_rom),
                                dinfo->bdrv, sector_len, connex_rom / sector_len,
-                               2, 0, 0, 0, 0)) {
+                               2, 0, 0, 0, 0, be)) {
         fprintf(stderr, "qemu: Error registering flash memory.\n");
         exit(1);
     }
@@ -89,8 +87,7 @@ static void verdex_init(ram_addr_t ram_size,
 {
     PXA2xxState *cpu;
     DriveInfo *dinfo;
-    MemoryRegion *flash = g_new(MemoryRegion, 1);
-    const MemoryRegionOps *flash_ops;
+    int be;
 
     uint32_t verdex_rom = 0x02000000;
     uint32_t verdex_ram = 0x10000000;
@@ -105,15 +102,14 @@ static void verdex_init(ram_addr_t ram_size,
     }
 
 #ifdef TARGET_WORDS_BIGENDIAN
-    flash_ops = &pflash_cfi01_ops_be;
+    be = 1;
 #else
-    flash_ops = &pflash_cfi01_ops_le;
+    be = 0;
 #endif
-    memory_region_init_rom_device(flash, flash_ops,
-                                  NULL, "verdex.rom", verdex_rom);
-    if (!pflash_cfi01_register(0x00000000, flash,
+    if (!pflash_cfi01_register(0x00000000, qemu_ram_alloc(NULL, "verdex.rom",
+                                                          verdex_rom),
                                dinfo->bdrv, sector_len, verdex_rom / sector_len,
-                               2, 0, 0, 0, 0)) {
+                               2, 0, 0, 0, 0, be)) {
         fprintf(stderr, "qemu: Error registering flash memory.\n");
         exit(1);
     }
diff --git a/hw/integratorcp.c b/hw/integratorcp.c
index 3c8982e..2814108 100644
--- a/hw/integratorcp.c
+++ b/hw/integratorcp.c
@@ -13,13 +13,11 @@
 #include "boards.h"
 #include "arm-misc.h"
 #include "net.h"
-#include "exec-memory.h"
 
 typedef struct {
     SysBusDevice busdev;
     uint32_t memsz;
-    MemoryRegion flash;
-    bool flash_mapped;
+    uint32_t flash_offset;
     uint32_t cm_osc;
     uint32_t cm_ctrl;
     uint32_t cm_lock;
@@ -110,15 +108,9 @@ static uint32_t integratorcm_read(void *opaque, target_phys_addr_t offset)
 static void integratorcm_do_remap(integratorcm_state *s, int flash)
 {
     if (flash) {
-        if (s->flash_mapped) {
-            sysbus_del_memory(&s->busdev, &s->flash);
-            s->flash_mapped = false;
-        }
+        cpu_register_physical_memory(0, 0x100000, IO_MEM_RAM);
     } else {
-        if (!s->flash_mapped) {
-            sysbus_add_memory_overlap(&s->busdev, 0, &s->flash, 1);
-            s->flash_mapped = true;
-        }
+        cpu_register_physical_memory(0, 0x100000, s->flash_offset | IO_MEM_RAM);
     }
     //??? tlb_flush (cpu_single_env, 1);
 }
@@ -260,8 +252,7 @@ static int integratorcm_init(SysBusDevice *dev)
     }
     memcpy(integrator_spd + 73, "QEMU-MEMORY", 11);
     s->cm_init = 0x00000112;
-    memory_region_init_ram(&s->flash, NULL, "integrator.flash", 0x100000);
-    s->flash_mapped = false;
+    s->flash_offset = qemu_ram_alloc(NULL, "integrator.flash", 0x100000);
 
     iomemtype = cpu_register_io_memory(integratorcm_readfn,
                                        integratorcm_writefn, s,
@@ -465,9 +456,7 @@ static void integratorcp_init(ram_addr_t ram_size,
                      const char *initrd_filename, const char *cpu_model)
 {
     CPUState *env;
-    MemoryRegion *address_space_mem = get_system_memory();
-    MemoryRegion *ram = g_new(MemoryRegion, 1);
-    MemoryRegion *ram_alias = g_new(MemoryRegion, 1);
+    ram_addr_t ram_offset;
     qemu_irq pic[32];
     qemu_irq *cpu_pic;
     DeviceState *dev;
@@ -480,14 +469,13 @@ static void integratorcp_init(ram_addr_t ram_size,
         fprintf(stderr, "Unable to find CPU definition\n");
         exit(1);
     }
-    memory_region_init_ram(ram, NULL, "integrator.ram", ram_size);
+    ram_offset = qemu_ram_alloc(NULL, "integrator.ram", ram_size);
     /* ??? On a real system the first 1Mb is mapped as SSRAM or boot flash.  */
     /* ??? RAM should repeat to fill physical memory space.  */
     /* SDRAM at address zero*/
-    memory_region_add_subregion(address_space_mem, 0, ram);
+    cpu_register_physical_memory(0, ram_size, ram_offset | IO_MEM_RAM);
     /* And again at address 0x80000000 */
-    memory_region_init_alias(ram_alias, "ram.alias", ram, 0, ram_size);
-    memory_region_add_subregion(address_space_mem, 0x80000000, ram_alias);
+    cpu_register_physical_memory(0x80000000, ram_size, ram_offset | IO_MEM_RAM);
 
     dev = qdev_create(NULL, "integrator_core");
     qdev_prop_set_uint32(dev, "memsz", ram_size >> 20);
diff --git a/hw/leon3.c b/hw/leon3.c
index 607ec85..a62a941 100644
--- a/hw/leon3.c
+++ b/hw/leon3.c
@@ -29,7 +29,6 @@
 #include "loader.h"
 #include "elf.h"
 #include "trace.h"
-#include "exec-memory.h"
 
 #include "grlib.h"
 
@@ -101,9 +100,7 @@ static void leon3_generic_hw_init(ram_addr_t  ram_size,
                                   const char *cpu_model)
 {
     CPUState   *env;
-    MemoryRegion *address_space_mem = get_system_memory();
-    MemoryRegion *ram = g_new(MemoryRegion, 1);
-    MemoryRegion *prom = g_new(MemoryRegion, 1);
+    ram_addr_t  ram_offset, prom_offset;
     int         ret;
     char       *filename;
     qemu_irq   *cpu_irqs = NULL;
@@ -142,14 +139,14 @@ static void leon3_generic_hw_init(ram_addr_t  ram_size,
         exit(1);
     }
 
-    memory_region_init_ram(ram, NULL, "leon3.ram", ram_size);
-    memory_region_add_subregion(address_space_mem, 0x40000000, ram);
+    ram_offset = qemu_ram_alloc(NULL, "leon3.ram", ram_size);
+    cpu_register_physical_memory(0x40000000, ram_size, ram_offset | IO_MEM_RAM);
 
     /* Allocate BIOS */
     prom_size = 8 * 1024 * 1024; /* 8Mb */
-    memory_region_init_ram(prom, NULL, "Leon3.bios", prom_size);
-    memory_region_set_readonly(prom, true);
-    memory_region_add_subregion(address_space_mem, 0x00000000, prom);
+    prom_offset = qemu_ram_alloc(NULL, "Leon3.bios", prom_size);
+    cpu_register_physical_memory(0x00000000, prom_size,
+                                 prom_offset | IO_MEM_ROM);
 
     /* Load boot prom */
     if (bios_name == NULL) {
diff --git a/hw/lm32_boards.c b/hw/lm32_boards.c
index a84007b..d18aad7 100644
--- a/hw/lm32_boards.c
+++ b/hw/lm32_boards.c
@@ -28,7 +28,6 @@
 #include "elf.h"
 #include "lm32_hwsetup.h"
 #include "lm32.h"
-#include "exec-memory.h"
 
 typedef struct {
     CPUState *env;
@@ -77,9 +76,8 @@ static void lm32_evr_init(ram_addr_t ram_size_not_used,
 {
     CPUState *env;
     DriveInfo *dinfo;
-    MemoryRegion *address_space_mem =  get_system_memory();
-    MemoryRegion *phys_ram = g_new(MemoryRegion, 1);
-    MemoryRegion *phys_flash = g_new(MemoryRegion, 1);
+    ram_addr_t phys_ram;
+    ram_addr_t phys_flash;
     qemu_irq *cpu_irq, irq[32];
     ResetInfo *reset_info;
     int i;
@@ -107,17 +105,16 @@ static void lm32_evr_init(ram_addr_t ram_size_not_used,
 
     reset_info->flash_base = flash_base;
 
-    memory_region_init_ram(phys_ram, NULL, "lm32_evr.sdram", ram_size);
-    memory_region_add_subregion(address_space_mem, ram_base, phys_ram);
+    phys_ram = qemu_ram_alloc(NULL, "lm32_evr.sdram", ram_size);
+    cpu_register_physical_memory(ram_base, ram_size, phys_ram | IO_MEM_RAM);
 
-    memory_region_init_rom_device(phys_flash, &pflash_cfi02_ops_be,
-                                  NULL, "lm32_evr.flash", flash_size);
+    phys_flash = qemu_ram_alloc(NULL, "lm32_evr.flash", flash_size);
     dinfo = drive_get(IF_PFLASH, 0, 0);
     /* Spansion S29NS128P */
     pflash_cfi02_register(flash_base, phys_flash,
                           dinfo ? dinfo->bdrv : NULL, flash_sector_size,
                           flash_size / flash_sector_size, 1, 2,
-                          0x01, 0x7e, 0x43, 0x00, 0x555, 0x2aa);
+                          0x01, 0x7e, 0x43, 0x00, 0x555, 0x2aa, 1);
 
     /* create irq lines */
     cpu_irq = qemu_allocate_irqs(cpu_irq_handler, env, 1);
@@ -167,9 +164,8 @@ static void lm32_uclinux_init(ram_addr_t ram_size_not_used,
 {
     CPUState *env;
     DriveInfo *dinfo;
-    MemoryRegion *address_space_mem =  get_system_memory();
-    MemoryRegion *phys_ram = g_new(MemoryRegion, 1);
-    MemoryRegion *phys_flash = g_new(MemoryRegion, 1);
+    ram_addr_t phys_ram;
+    ram_addr_t phys_flash;
     qemu_irq *cpu_irq, irq[32];
     HWSetup *hw;
     ResetInfo *reset_info;
@@ -204,17 +200,16 @@ static void lm32_uclinux_init(ram_addr_t ram_size_not_used,
 
     reset_info->flash_base = flash_base;
 
-    memory_region_init_ram(phys_ram, NULL, "lm32_uclinux.sdram", ram_size);
-    memory_region_add_subregion(address_space_mem, ram_base, phys_ram);
+    phys_ram = qemu_ram_alloc(NULL, "lm32_uclinux.sdram", ram_size);
+    cpu_register_physical_memory(ram_base, ram_size, phys_ram | IO_MEM_RAM);
 
-    memory_region_init_rom_device(phys_flash, &pflash_cfi01_ops_be,
-                                  NULL, "lm32_uclinux.flash", flash_size);
+    phys_flash = qemu_ram_alloc(NULL, "lm32_uclinux.flash", flash_size);
     dinfo = drive_get(IF_PFLASH, 0, 0);
     /* Spansion S29NS128P */
     pflash_cfi02_register(flash_base, phys_flash,
                           dinfo ? dinfo->bdrv : NULL, flash_sector_size,
                           flash_size / flash_sector_size, 1, 2,
-                          0x01, 0x7e, 0x43, 0x00, 0x555, 0x2aa);
+                          0x01, 0x7e, 0x43, 0x00, 0x555, 0x2aa, 1);
 
     /* create irq lines */
     cpu_irq = qemu_allocate_irqs(cpu_irq_handler, env, 1);
diff --git a/hw/mainstone.c b/hw/mainstone.c
index 82e9571..4792f0e 100644
--- a/hw/mainstone.c
+++ b/hw/mainstone.c
@@ -17,7 +17,6 @@
 #include "flash.h"
 #include "blockdev.h"
 #include "sysbus.h"
-#include "exec-memory.h"
 
 /* Device addresses */
 #define MST_FPGA_PHYS	0x08000000
@@ -91,8 +90,7 @@ static struct arm_boot_info mainstone_binfo = {
     .ram_size = 0x04000000,
 };
 
-static void mainstone_common_init(MemoryRegion *address_space_mem,
-                ram_addr_t ram_size,
+static void mainstone_common_init(ram_addr_t ram_size,
                 const char *kernel_filename,
                 const char *kernel_cmdline, const char *initrd_filename,
                 const char *cpu_model, enum mainstone_model_e model, int arm_id)
@@ -103,23 +101,21 @@ static void mainstone_common_init(MemoryRegion *address_space_mem,
     DeviceState *mst_irq;
     DriveInfo *dinfo;
     int i;
-    MemoryRegion *rom = g_new(MemoryRegion, 1);
-    MemoryRegion *flashes = g_new(MemoryRegion, 2);
-    const MemoryRegionOps *flash_ops;
+    int be;
 
     if (!cpu_model)
         cpu_model = "pxa270-c5";
 
     /* Setup CPU & memory */
     cpu = pxa270_init(mainstone_binfo.ram_size, cpu_model);
-    memory_region_init_ram(rom, NULL, "mainstone.rom", MAINSTONE_ROM);
-    memory_region_set_readonly(rom, true);
-    memory_region_add_subregion(address_space_mem, 0, rom);
+    cpu_register_physical_memory(0, MAINSTONE_ROM,
+                    qemu_ram_alloc(NULL, "mainstone.rom",
+                                   MAINSTONE_ROM) | IO_MEM_ROM);
 
 #ifdef TARGET_WORDS_BIGENDIAN
-    flash_ops = &pflash_cfi01_ops_be;
+    be = 1;
 #else
-    flash_ops = &pflash_cfi01_ops_le;
+    be = 0;
 #endif
     /* There are two 32MiB flash devices on the board */
     for (i = 0; i < 2; i ++) {
@@ -130,14 +126,13 @@ static void mainstone_common_init(MemoryRegion *address_space_mem,
             exit(1);
         }
 
-        memory_region_init_rom_device(&flashes[i], flash_ops,
-                                      NULL, (i ? "mainstone.flash1"
-                                               : "mainstone.flash0"),
-                                      MAINSTONE_FLASH);
         if (!pflash_cfi01_register(mainstone_flash_base[i],
-                                   &flashes[i], dinfo->bdrv, sector_len,
-                                   MAINSTONE_FLASH / sector_len, 4, 0, 0, 0,
-                                   0)) {
+                                   qemu_ram_alloc(NULL, i ? "mainstone.flash1" :
+                                                  "mainstone.flash0",
+                                                  MAINSTONE_FLASH),
+                                   dinfo->bdrv, sector_len,
+                                   MAINSTONE_FLASH / sector_len, 4, 0, 0, 0, 0,
+                                   be)) {
             fprintf(stderr, "qemu: Error registering flash memory.\n");
             exit(1);
         }
@@ -175,7 +170,7 @@ static void mainstone_init(ram_addr_t ram_size,
                 const char *kernel_filename, const char *kernel_cmdline,
                 const char *initrd_filename, const char *cpu_model)
 {
-    mainstone_common_init(get_system_memory(), ram_size, kernel_filename,
+    mainstone_common_init(ram_size, kernel_filename,
                 kernel_cmdline, initrd_filename, cpu_model, mainstone, 0x196);
 }
 
diff --git a/hw/mcf5208.c b/hw/mcf5208.c
index 1c2c0c4..8fe507f 100644
--- a/hw/mcf5208.c
+++ b/hw/mcf5208.c
@@ -13,7 +13,6 @@
 #include "boards.h"
 #include "loader.h"
 #include "elf.h"
-#include "exec-memory.h"
 
 #define SYS_FREQ 66000000
 
@@ -28,7 +27,6 @@
 #define PCSR_PRE_MASK   0x0f00
 
 typedef struct {
-    MemoryRegion iomem;
     qemu_irq irq;
     ptimer_state *timer;
     uint16_t pcsr;
@@ -45,7 +43,7 @@ static void m5208_timer_update(m5208_timer_state *s)
 }
 
 static void m5208_timer_write(void *opaque, target_phys_addr_t offset,
-                              uint64_t value, unsigned size)
+                              uint32_t value)
 {
     m5208_timer_state *s = (m5208_timer_state *)opaque;
     int prescale;
@@ -106,8 +104,7 @@ static void m5208_timer_trigger(void *opaque)
     m5208_timer_update(s);
 }
 
-static uint64_t m5208_timer_read(void *opaque, target_phys_addr_t addr,
-                                 unsigned size)
+static uint32_t m5208_timer_read(void *opaque, target_phys_addr_t addr)
 {
     m5208_timer_state *s = (m5208_timer_state *)opaque;
     switch (addr) {
@@ -123,14 +120,19 @@ static uint64_t m5208_timer_read(void *opaque, target_phys_addr_t addr,
     }
 }
 
-static const MemoryRegionOps m5208_timer_ops = {
-    .read = m5208_timer_read,
-    .write = m5208_timer_write,
-    .endianness = DEVICE_NATIVE_ENDIAN,
+static CPUReadMemoryFunc * const m5208_timer_readfn[] = {
+   m5208_timer_read,
+   m5208_timer_read,
+   m5208_timer_read
 };
 
-static uint64_t m5208_sys_read(void *opaque, target_phys_addr_t addr,
-                               unsigned size)
+static CPUWriteMemoryFunc * const m5208_timer_writefn[] = {
+   m5208_timer_write,
+   m5208_timer_write,
+   m5208_timer_write
+};
+
+static uint32_t m5208_sys_read(void *opaque, target_phys_addr_t addr)
 {
     switch (addr) {
     case 0x110: /* SDCS0 */
@@ -152,36 +154,45 @@ static uint64_t m5208_sys_read(void *opaque, target_phys_addr_t addr,
 }
 
 static void m5208_sys_write(void *opaque, target_phys_addr_t addr,
-                            uint64_t value, unsigned size)
+                            uint32_t value)
 {
     hw_error("m5208_sys_write: Bad offset 0x%x\n", (int)addr);
 }
 
-static const MemoryRegionOps m5208_sys_ops = {
-    .read = m5208_sys_read,
-    .write = m5208_sys_write,
-    .endianness = DEVICE_NATIVE_ENDIAN,
+static CPUReadMemoryFunc * const m5208_sys_readfn[] = {
+   m5208_sys_read,
+   m5208_sys_read,
+   m5208_sys_read
+};
+
+static CPUWriteMemoryFunc * const m5208_sys_writefn[] = {
+   m5208_sys_write,
+   m5208_sys_write,
+   m5208_sys_write
 };
 
-static void mcf5208_sys_init(MemoryRegion *address_space, qemu_irq *pic)
+static void mcf5208_sys_init(qemu_irq *pic)
 {
-    MemoryRegion *iomem = g_new(MemoryRegion, 1);
+    int iomemtype;
     m5208_timer_state *s;
     QEMUBH *bh;
     int i;
 
+    iomemtype = cpu_register_io_memory(m5208_sys_readfn,
+                                       m5208_sys_writefn, NULL,
+                                       DEVICE_NATIVE_ENDIAN);
     /* SDRAMC.  */
-    memory_region_init_io(iomem, &m5208_sys_ops, NULL, "m5208-sys", 0x00004000);
-    memory_region_add_subregion(address_space, 0xfc0a8000, iomem);
+    cpu_register_physical_memory(0xfc0a8000, 0x00004000, iomemtype);
     /* Timers.  */
     for (i = 0; i < 2; i++) {
         s = (m5208_timer_state *)g_malloc0(sizeof(m5208_timer_state));
         bh = qemu_bh_new(m5208_timer_trigger, s);
         s->timer = ptimer_init(bh);
-        memory_region_init_io(&s->iomem, &m5208_timer_ops, s,
-                              "m5208-timer", 0x00004000);
-        memory_region_add_subregion(address_space, 0xfc080000 + 0x4000 * i,
-                                    &s->iomem);
+        iomemtype = cpu_register_io_memory(m5208_timer_readfn,
+                                           m5208_timer_writefn, s,
+                                           DEVICE_NATIVE_ENDIAN);
+        cpu_register_physical_memory(0xfc080000 + 0x4000 * i, 0x00004000,
+                                     iomemtype);
         s->irq = pic[4 + i];
     }
 }
@@ -196,9 +207,6 @@ static void mcf5208evb_init(ram_addr_t ram_size,
     uint64_t elf_entry;
     target_phys_addr_t entry;
     qemu_irq *pic;
-    MemoryRegion *address_space_mem = get_system_memory();
-    MemoryRegion *ram = g_new(MemoryRegion, 1);
-    MemoryRegion *sram = g_new(MemoryRegion, 1);
 
     if (!cpu_model)
         cpu_model = "m5208";
@@ -213,12 +221,12 @@ static void mcf5208evb_init(ram_addr_t ram_size,
     /* TODO: Configure BARs.  */
 
     /* DRAM at 0x40000000 */
-    memory_region_init_ram(ram, NULL, "mcf5208.ram", ram_size);
-    memory_region_add_subregion(address_space_mem, 0x40000000, ram);
+    cpu_register_physical_memory(0x40000000, ram_size,
+        qemu_ram_alloc(NULL, "mcf5208.ram", ram_size) | IO_MEM_RAM);
 
     /* Internal SRAM.  */
-    memory_region_init_ram(sram, NULL, "mcf5208.sram", 16384);
-    memory_region_add_subregion(address_space_mem, 0x80000000, sram);
+    cpu_register_physical_memory(0x80000000, 16384,
+        qemu_ram_alloc(NULL, "mcf5208.sram", 16384) | IO_MEM_RAM);
 
     /* Internal peripherals.  */
     pic = mcf_intc_init(0xfc048000, env);
@@ -227,7 +235,7 @@ static void mcf5208evb_init(ram_addr_t ram_size,
     mcf_uart_mm_init(0xfc064000, pic[27], serial_hds[1]);
     mcf_uart_mm_init(0xfc068000, pic[28], serial_hds[2]);
 
-    mcf5208_sys_init(address_space_mem, pic);
+    mcf5208_sys_init(pic);
 
     if (nb_nics > 1) {
         fprintf(stderr, "Too many NICs\n");
diff --git a/hw/milkymist-minimac2.c b/hw/milkymist-minimac2.c
index fb48e37..cd36026 100644
--- a/hw/milkymist-minimac2.c
+++ b/hw/milkymist-minimac2.c
@@ -97,8 +97,6 @@ struct MilkymistMinimac2State {
     NICConf conf;
     char *phy_model;
     target_phys_addr_t buffers_base;
-    MemoryRegion buffers;
-    MemoryRegion regs_region;
 
     qemu_irq rx_irq;
     qemu_irq tx_irq;
@@ -322,8 +320,8 @@ static ssize_t minimac2_rx(VLANClientState *nc, const uint8_t *buf, size_t size)
     return size;
 }
 
-static uint64_t
-minimac2_read(void *opaque, target_phys_addr_t addr, unsigned size)
+static uint32_t
+minimac2_read(void *opaque, target_phys_addr_t addr)
 {
     MilkymistMinimac2State *s = opaque;
     uint32_t r = 0;
@@ -352,8 +350,7 @@ minimac2_read(void *opaque, target_phys_addr_t addr, unsigned size)
 }
 
 static void
-minimac2_write(void *opaque, target_phys_addr_t addr, uint64_t value,
-               unsigned size)
+minimac2_write(void *opaque, target_phys_addr_t addr, uint32_t value)
 {
     MilkymistMinimac2State *s = opaque;
 
@@ -398,14 +395,16 @@ minimac2_write(void *opaque, target_phys_addr_t addr, uint64_t value,
     }
 }
 
-static const MemoryRegionOps minimac2_ops = {
-    .read = minimac2_read,
-    .write = minimac2_write,
-    .valid = {
-        .min_access_size = 4,
-        .max_access_size = 4,
-    },
-    .endianness = DEVICE_NATIVE_ENDIAN,
+static CPUReadMemoryFunc * const minimac2_read_fn[] = {
+    NULL,
+    NULL,
+    &minimac2_read,
+};
+
+static CPUWriteMemoryFunc * const minimac2_write_fn[] = {
+    NULL,
+    NULL,
+    &minimac2_write,
 };
 
 static int minimac2_can_rx(VLANClientState *nc)
@@ -458,23 +457,25 @@ static NetClientInfo net_milkymist_minimac2_info = {
 static int milkymist_minimac2_init(SysBusDevice *dev)
 {
     MilkymistMinimac2State *s = FROM_SYSBUS(typeof(*s), dev);
+    int regs;
+    ram_addr_t buffers;
     size_t buffers_size = TARGET_PAGE_ALIGN(3 * MINIMAC2_BUFFER_SIZE);
 
     sysbus_init_irq(dev, &s->rx_irq);
     sysbus_init_irq(dev, &s->tx_irq);
 
-    memory_region_init_io(&s->regs_region, &minimac2_ops, s,
-                          "minimac2-mmio", R_MAX * 4);
-    sysbus_init_mmio_region(dev, &s->regs_region);
+    regs = cpu_register_io_memory(minimac2_read_fn, minimac2_write_fn, s,
+            DEVICE_NATIVE_ENDIAN);
+    sysbus_init_mmio(dev, R_MAX * 4, regs);
 
     /* register buffers memory */
-    memory_region_init_ram(&s->buffers, NULL, "milkymist_minimac2.buffers",
-                           buffers_size);
-    s->rx0_buf = memory_region_get_ram_ptr(&s->buffers);
+    buffers = qemu_ram_alloc(NULL, "milkymist_minimac2.buffers", buffers_size);
+    s->rx0_buf = qemu_get_ram_ptr(buffers);
     s->rx1_buf = s->rx0_buf + MINIMAC2_BUFFER_SIZE;
     s->tx_buf = s->rx1_buf + MINIMAC2_BUFFER_SIZE;
 
-    sysbus_add_memory(dev, s->buffers_base, &s->buffers);
+    cpu_register_physical_memory(s->buffers_base, buffers_size,
+            buffers | IO_MEM_RAM);
 
     qemu_macaddr_default_if_unset(&s->conf.macaddr);
     s->nic = qemu_new_nic(&net_milkymist_minimac2_info, &s->conf,
diff --git a/hw/milkymist-softusb.c b/hw/milkymist-softusb.c
index ef4d9ee..fe4eedb 100644
--- a/hw/milkymist-softusb.c
+++ b/hw/milkymist-softusb.c
@@ -49,9 +49,6 @@ struct MilkymistSoftUsbState {
     HIDState hid_kbd;
     HIDState hid_mouse;
 
-    MemoryRegion regs_region;
-    MemoryRegion pmem;
-    MemoryRegion dmem;
     qemu_irq irq;
 
     /* device properties */
@@ -71,8 +68,7 @@ struct MilkymistSoftUsbState {
 };
 typedef struct MilkymistSoftUsbState MilkymistSoftUsbState;
 
-static uint64_t softusb_read(void *opaque, target_phys_addr_t addr,
-                             unsigned size)
+static uint32_t softusb_read(void *opaque, target_phys_addr_t addr)
 {
     MilkymistSoftUsbState *s = opaque;
     uint32_t r = 0;
@@ -95,8 +91,7 @@ static uint64_t softusb_read(void *opaque, target_phys_addr_t addr,
 }
 
 static void
-softusb_write(void *opaque, target_phys_addr_t addr, uint64_t value,
-              unsigned size)
+softusb_write(void *opaque, target_phys_addr_t addr, uint32_t value)
 {
     MilkymistSoftUsbState *s = opaque;
 
@@ -115,14 +110,16 @@ softusb_write(void *opaque, target_phys_addr_t addr, uint64_t value,
     }
 }
 
-static const MemoryRegionOps softusb_mmio_ops = {
-    .read = softusb_read,
-    .write = softusb_write,
-    .endianness = DEVICE_NATIVE_ENDIAN,
-    .valid = {
-        .min_access_size = 4,
-        .max_access_size = 4,
-    },
+static CPUReadMemoryFunc * const softusb_read_fn[] = {
+    NULL,
+    NULL,
+    &softusb_read,
+};
+
+static CPUWriteMemoryFunc * const softusb_write_fn[] = {
+    NULL,
+    NULL,
+    &softusb_write,
 };
 
 static inline void softusb_read_dmem(MilkymistSoftUsbState *s,
@@ -259,20 +256,23 @@ static void milkymist_softusb_reset(DeviceState *d)
 static int milkymist_softusb_init(SysBusDevice *dev)
 {
     MilkymistSoftUsbState *s = FROM_SYSBUS(typeof(*s), dev);
+    int softusb_regs;
+    ram_addr_t pmem_ram;
+    ram_addr_t dmem_ram;
 
     sysbus_init_irq(dev, &s->irq);
 
-    memory_region_init_io(&s->regs_region, &softusb_mmio_ops, s,
-                          "milkymist-softusb", R_MAX * 4);
-    sysbus_init_mmio_region(dev, &s->regs_region);
+    softusb_regs = cpu_register_io_memory(softusb_read_fn, softusb_write_fn, s,
+            DEVICE_NATIVE_ENDIAN);
+    sysbus_init_mmio(dev, R_MAX * 4, softusb_regs);
 
     /* register pmem and dmem */
-    memory_region_init_ram(&s->pmem, NULL, "milkymist_softusb.pmem",
-                           s->pmem_size);
-    sysbus_add_memory(dev, s->pmem_base, &s->pmem);
-    memory_region_init_ram(&s->dmem, NULL, "milkymist_softusb.dmem",
-                           s->dmem_size);
-    sysbus_add_memory(dev, s->dmem_base, &s->dmem);
+    pmem_ram = qemu_ram_alloc(NULL, "milkymist_softusb.pmem", s->pmem_size);
+    cpu_register_physical_memory(s->pmem_base, s->pmem_size,
+            pmem_ram | IO_MEM_RAM);
+    dmem_ram = qemu_ram_alloc(NULL, "milkymist_softusb.dmem", s->dmem_size);
+    cpu_register_physical_memory(s->dmem_base, s->dmem_size,
+            dmem_ram | IO_MEM_RAM);
 
     hid_init(&s->hid_kbd, HID_KEYBOARD, softusb_kbd_hid_datain);
     hid_init(&s->hid_mouse, HID_MOUSE, softusb_mouse_hid_datain);
diff --git a/hw/milkymist.c b/hw/milkymist.c
index ef21cca..93288c8 100644
--- a/hw/milkymist.c
+++ b/hw/milkymist.c
@@ -29,7 +29,6 @@
 #include "blockdev.h"
 #include "milkymist-hw.h"
 #include "lm32.h"
-#include "exec-memory.h"
 
 #define BIOS_FILENAME    "mmone-bios.bin"
 #define BIOS_OFFSET      0x00860000
@@ -82,9 +81,8 @@ milkymist_init(ram_addr_t ram_size_not_used,
     CPUState *env;
     int kernel_size;
     DriveInfo *dinfo;
-    MemoryRegion *address_space_mem = get_system_memory();
-    MemoryRegion *phys_sdram = g_new(MemoryRegion, 1);
-    MemoryRegion *phys_flash = g_new(MemoryRegion, 1);
+    ram_addr_t phys_sdram;
+    ram_addr_t phys_flash;
     qemu_irq irq[32], *cpu_irq;
     int i;
     char *bios_filename;
@@ -111,17 +109,17 @@ milkymist_init(ram_addr_t ram_size_not_used,
 
     cpu_lm32_set_phys_msb_ignore(env, 1);
 
-    memory_region_init_ram(phys_sdram, NULL, "milkymist.sdram", sdram_size);
-    memory_region_add_subregion(address_space_mem, sdram_base, phys_sdram);
+    phys_sdram = qemu_ram_alloc(NULL, "milkymist.sdram", sdram_size);
+    cpu_register_physical_memory(sdram_base, sdram_size,
+            phys_sdram | IO_MEM_RAM);
 
-    memory_region_init_rom_device(phys_flash, &pflash_cfi01_ops_be,
-                                  NULL, "milkymist.flash", flash_size);
+    phys_flash = qemu_ram_alloc(NULL, "milkymist.flash", flash_size);
     dinfo = drive_get(IF_PFLASH, 0, 0);
     /* Numonyx JS28F256J3F105 */
     pflash_cfi01_register(flash_base, phys_flash,
                           dinfo ? dinfo->bdrv : NULL, flash_sector_size,
                           flash_size / flash_sector_size, 2,
-                          0x00, 0x89, 0x00, 0x1d);
+                          0x00, 0x89, 0x00, 0x1d, 1);
 
     /* create irq lines */
     cpu_irq = qemu_allocate_irqs(cpu_irq_handler, env, 1);
diff --git a/hw/mips.h b/hw/mips.h
index 97d7b9e..cae5f4c 100644
--- a/hw/mips.h
+++ b/hw/mips.h
@@ -2,8 +2,6 @@
 #define HW_MIPS_H
 /* Definitions for mips board emulation.  */
 
-#include "memory.h"
-
 /* gt64xxx.c */
 PCIBus *gt64120_register(qemu_irq *pic);
 
@@ -11,7 +9,7 @@ PCIBus *gt64120_register(qemu_irq *pic);
 PCIBus *bonito_init(qemu_irq *pic);
 
 /* g364fb.c */
-int g364fb_mm_init(MemoryRegion *system_memory, target_phys_addr_t vram_base,
+int g364fb_mm_init(target_phys_addr_t vram_base,
                    target_phys_addr_t ctrl_base, int it_shift,
                    qemu_irq irq);
 
diff --git a/hw/mips_jazz.c b/hw/mips_jazz.c
index a741086..84ce061 100644
--- a/hw/mips_jazz.c
+++ b/hw/mips_jazz.c
@@ -195,8 +195,7 @@ void mips_jazz_init (ram_addr_t ram_size,
     /* Video card */
     switch (jazz_model) {
     case JAZZ_MAGNUM:
-        g364fb_mm_init(get_system_memory(), 0x40000000, 0x60000000, 0,
-                       rc4030[3]);
+        g364fb_mm_init(0x40000000, 0x60000000, 0, rc4030[3]);
         break;
     case JAZZ_PICA61:
         isa_vga_mm_init(0x40000000, 0x60000000, 0, get_system_memory());
diff --git a/hw/mips_malta.c b/hw/mips_malta.c
index b5c9bcf..86a8ba0 100644
--- a/hw/mips_malta.c
+++ b/hw/mips_malta.c
@@ -46,7 +46,6 @@
 #include "elf.h"
 #include "mc146818rtc.h"
 #include "blockdev.h"
-#include "exec-memory.h"
 
 //#define DEBUG_BOARD_INIT
 
@@ -763,10 +762,7 @@ void mips_malta_init (ram_addr_t ram_size,
 {
     char *filename;
     ram_addr_t ram_offset;
-    MemoryRegion *address_space_mem = get_system_memory();
-    MemoryRegion *bios = g_new(MemoryRegion, 1);
-    MemoryRegion *bios_1e0 = g_new(MemoryRegion, 1);
-    MemoryRegion *bios_1fc = g_new(MemoryRegion, 1);
+    ram_addr_t bios_offset;
     target_long bios_size;
     int64_t kernel_entry;
     PCIBus *pci_bus;
@@ -781,7 +777,7 @@ void mips_malta_init (ram_addr_t ram_size,
     DriveInfo *fd[MAX_FD];
     int fl_idx = 0;
     int fl_sectors = 0;
-    const MemoryRegionOps *bios_ops;
+    int be;
 
     /* Make sure the first 3 serial ports are associated with a device. */
     for(i = 0; i < 3; i++) {
@@ -814,24 +810,23 @@ void mips_malta_init (ram_addr_t ram_size,
                 ((unsigned int)ram_size / (1 << 20)));
         exit(1);
     }
-#ifdef TARGET_WORDS_BIGENDIAN
-    bios_ops = &pflash_cfi01_ops_be;
-#else
-    bios_ops = &pflash_cfi01_ops_le;
-#endif
-
     ram_offset = qemu_ram_alloc(NULL, "mips_malta.ram", ram_size);
-    memory_region_init_rom_device(bios, bios_ops, NULL,
-                                  "mips_malta.bios", BIOS_SIZE);
+    bios_offset = qemu_ram_alloc(NULL, "mips_malta.bios", BIOS_SIZE);
+
 
     cpu_register_physical_memory(0, ram_size, ram_offset | IO_MEM_RAM);
 
     /* Map the bios at two physical locations, as on the real board. */
-    memory_region_init_alias(bios_1e0, "bios-1e0", bios, 0, BIOS_SIZE);
-    memory_region_add_subregion(address_space_mem, 0x1e000000LL, bios_1e0);
-    memory_region_init_alias(bios_1fc, "bios-1fc", bios, 0, BIOS_SIZE);
-    memory_region_add_subregion(address_space_mem, 0x1fc00000LL, bios_1fc);
+    cpu_register_physical_memory(0x1e000000LL,
+                                 BIOS_SIZE, bios_offset | IO_MEM_ROM);
+    cpu_register_physical_memory(0x1fc00000LL,
+                                 BIOS_SIZE, bios_offset | IO_MEM_ROM);
 
+#ifdef TARGET_WORDS_BIGENDIAN
+    be = 1;
+#else
+    be = 0;
+#endif
     /* FPGA */
     malta_fpga_init(0x1f000000LL, env->irq[2], serial_hds[2]);
 
@@ -843,7 +838,7 @@ void mips_malta_init (ram_addr_t ram_size,
         loaderparams.kernel_cmdline = kernel_cmdline;
         loaderparams.initrd_filename = initrd_filename;
         kernel_entry = load_kernel();
-        write_bootloader(env, memory_region_get_ram_ptr(bios), kernel_entry);
+        write_bootloader(env, qemu_get_ram_ptr(bios_offset), kernel_entry);
     } else {
         dinfo = drive_get(IF_PFLASH, 0, fl_idx);
         if (dinfo) {
@@ -852,13 +847,13 @@ void mips_malta_init (ram_addr_t ram_size,
             fl_sectors = bios_size >> 16;
 #ifdef DEBUG_BOARD_INIT
             printf("Register parallel flash %d size " TARGET_FMT_lx " at "
-                   "addr %08llx '%s' %x\n",
-                   fl_idx, bios_size, 0x1e000000LL,
+                   "offset %08lx addr %08llx '%s' %x\n",
+                   fl_idx, bios_size, bios_offset, 0x1e000000LL,
                    bdrv_get_device_name(dinfo->bdrv), fl_sectors);
 #endif
-            pflash_cfi01_register(0x1e000000LL, bios,
+            pflash_cfi01_register(0x1e000000LL, bios_offset,
                                   dinfo->bdrv, 65536, fl_sectors,
-                                  4, 0x0000, 0x0000, 0x0000, 0x0000);
+                                  4, 0x0000, 0x0000, 0x0000, 0x0000, be);
             fl_idx++;
         } else {
             /* Load a BIOS image. */
@@ -883,7 +878,7 @@ void mips_malta_init (ram_addr_t ram_size,
            a neat trick which allows bi-endian firmware. */
 #ifndef TARGET_WORDS_BIGENDIAN
         {
-            uint32_t *addr = memory_region_get_ram_ptr(bios);
+            uint32_t *addr = qemu_get_ram_ptr(bios_offset);;
             uint32_t *end = addr + bios_size;
             while (addr < end) {
                 bswap32s(addr);
@@ -895,7 +890,7 @@ void mips_malta_init (ram_addr_t ram_size,
     /* Board ID = 0x420 (Malta Board with CoreLV)
        XXX: theoretically 0x1e000010 should map to flash and 0x1fc00010 should
        map to the board ID. */
-    stl_p(memory_region_get_ram_ptr(bios) + 0x10, 0x00000420);
+    stl_p(qemu_get_ram_ptr(bios_offset) + 0x10, 0x00000420);
 
     /* Init internal devices */
     cpu_mips_irq_init_cpu(env);
diff --git a/hw/mips_r4k.c b/hw/mips_r4k.c
index 51dc868..9d90568 100644
--- a/hw/mips_r4k.c
+++ b/hw/mips_r4k.c
@@ -23,7 +23,6 @@
 #include "elf.h"
 #include "mc146818rtc.h"
 #include "blockdev.h"
-#include "exec-memory.h"
 
 #define MAX_IDE_BUS 2
 
@@ -164,8 +163,7 @@ void mips_r4k_init (ram_addr_t ram_size,
 {
     char *filename;
     ram_addr_t ram_offset;
-    MemoryRegion *address_space_mem = get_system_memory();
-    MemoryRegion *bios = g_new(MemoryRegion, 1);
+    ram_addr_t bios_offset;
     int bios_size;
     CPUState *env;
     ResetData *reset_info;
@@ -229,20 +227,18 @@ void mips_r4k_init (ram_addr_t ram_size,
     be = 0;
 #endif
     if ((bios_size > 0) && (bios_size <= BIOS_SIZE)) {
-        memory_region_init_ram(bios, NULL, "mips_r4k.bios", BIOS_SIZE);
-        memory_region_set_readonly(bios, true);
-        memory_region_add_subregion(address_space_mem, 0x1fc00000, bios);
+        bios_offset = qemu_ram_alloc(NULL, "mips_r4k.bios", BIOS_SIZE);
+	cpu_register_physical_memory(0x1fc00000, BIOS_SIZE,
+                                     bios_offset | IO_MEM_ROM);
+
         load_image_targphys(filename, 0x1fc00000, BIOS_SIZE);
     } else if ((dinfo = drive_get(IF_PFLASH, 0, 0)) != NULL) {
         uint32_t mips_rom = 0x00400000;
-        memory_region_init_rom_device(bios,
-                                      (be ? &pflash_cfi01_ops_be
-                                          : &pflash_cfi01_ops_le),
-                                      NULL, "mips_r4k.bios", mips_rom);
-        if (!pflash_cfi01_register(0x1fc00000, bios,
+        bios_offset = qemu_ram_alloc(NULL, "mips_r4k.bios", mips_rom);
+        if (!pflash_cfi01_register(0x1fc00000, bios_offset,
                                    dinfo->bdrv, sector_len,
                                    mips_rom / sector_len,
-                                   4, 0, 0, 0, 0)) {
+                                   4, 0, 0, 0, 0, be)) {
             fprintf(stderr, "qemu: Error registering flash memory.\n");
 	}
     }
diff --git a/hw/musicpal.c b/hw/musicpal.c
index 5e74ee7..63dd391 100644
--- a/hw/musicpal.c
+++ b/hw/musicpal.c
@@ -1502,7 +1502,6 @@ static void musicpal_init(ram_addr_t ram_size,
     unsigned long flash_size;
     DriveInfo *dinfo;
     ram_addr_t sram_off;
-    MemoryRegion *flash = g_new(MemoryRegion, 1);
 
     if (!cpu_model) {
         cpu_model = "arm926";
@@ -1566,23 +1565,21 @@ static void musicpal_init(ram_addr_t ram_size,
          * image is smaller than 32 MB.
          */
 #ifdef TARGET_WORDS_BIGENDIAN
-        memory_region_init_rom_device(flash, &pflash_cfi02_ops_be,
-                                      NULL, "musicpal.flash", flash_size);
-        pflash_cfi02_register(0-MP_FLASH_SIZE_MAX, flash,
+        pflash_cfi02_register(0-MP_FLASH_SIZE_MAX, qemu_ram_alloc(NULL,
+                              "musicpal.flash", flash_size),
                               dinfo->bdrv, 0x10000,
                               (flash_size + 0xffff) >> 16,
                               MP_FLASH_SIZE_MAX / flash_size,
                               2, 0x00BF, 0x236D, 0x0000, 0x0000,
-                              0x5555, 0x2AAA);
+                              0x5555, 0x2AAA, 1);
 #else
-        memory_region_init_rom_device(flash, &pflash_cfi02_ops_le,
-                                      NULL, "musicpal.flash", flash_size);
-        pflash_cfi02_register(0-MP_FLASH_SIZE_MAX, flash,
+        pflash_cfi02_register(0-MP_FLASH_SIZE_MAX, qemu_ram_alloc(NULL,
+                              "musicpal.flash", flash_size),
                               dinfo->bdrv, 0x10000,
                               (flash_size + 0xffff) >> 16,
                               MP_FLASH_SIZE_MAX / flash_size,
                               2, 0x00BF, 0x236D, 0x0000, 0x0000,
-                              0x5555, 0x2AAA);
+                              0x5555, 0x2AAA, 0);
 #endif
 
     }
diff --git a/hw/omap_sx1.c b/hw/omap_sx1.c
index 70364f4..a7b687b 100644
--- a/hw/omap_sx1.c
+++ b/hw/omap_sx1.c
@@ -129,8 +129,7 @@ static void sx1_init(ram_addr_t ram_size,
     DriveInfo *dinfo;
     int fl_idx;
     uint32_t flash_size = flash0_size;
-    const MemoryRegionOps *flash_ops;
-    MemoryRegion *flash = g_new(MemoryRegion, 2);
+    int be;
 
     if (version == 2) {
         flash_size = flash2_size;
@@ -156,18 +155,17 @@ static void sx1_init(ram_addr_t ram_size,
 
     fl_idx = 0;
 #ifdef TARGET_WORDS_BIGENDIAN
-    flash_ops = &pflash_cfi01_ops_be;
+    be = 1;
 #else
-    flash_ops = &pflash_cfi01_ops_le;
+    be = 0;
 #endif
 
     if ((dinfo = drive_get(IF_PFLASH, 0, fl_idx)) != NULL) {
-        memory_region_init_rom_device(&flash[0], flash_ops,
-                                      NULL, "omap_sx1.flash0-1", flash_size);
-        if (!pflash_cfi01_register(OMAP_CS0_BASE, &flash[0],
+        if (!pflash_cfi01_register(OMAP_CS0_BASE, qemu_ram_alloc(NULL,
+                                   "omap_sx1.flash0-1", flash_size),
                                    dinfo->bdrv, sector_size,
                                    flash_size / sector_size,
-                                   4, 0, 0, 0, 0)) {
+                                   4, 0, 0, 0, 0, be)) {
             fprintf(stderr, "qemu: Error registering flash memory %d.\n",
                            fl_idx);
         }
@@ -184,12 +182,11 @@ static void sx1_init(ram_addr_t ram_size,
         cpu_register_physical_memory(OMAP_CS1_BASE + flash1_size,
                         OMAP_CS1_SIZE - flash1_size, io);
 
-        memory_region_init_rom_device(&flash[1], flash_ops,
-                                      NULL, "omap_sx1.flash1-1", flash1_size);
-        if (!pflash_cfi01_register(OMAP_CS1_BASE, &flash[1],
+        if (!pflash_cfi01_register(OMAP_CS1_BASE, qemu_ram_alloc(NULL,
+                                   "omap_sx1.flash1-1", flash1_size),
                                    dinfo->bdrv, sector_size,
                                    flash1_size / sector_size,
-                                   4, 0, 0, 0, 0)) {
+                                   4, 0, 0, 0, 0, be)) {
             fprintf(stderr, "qemu: Error registering flash memory %d.\n",
                            fl_idx);
         }
diff --git a/hw/pci_host.c b/hw/pci_host.c
index 44c6c20..2e8a29f 100644
--- a/hw/pci_host.c
+++ b/hw/pci_host.c
@@ -94,72 +94,82 @@ uint32_t pci_data_read(PCIBus *s, uint32_t addr, int len)
     return val;
 }
 
-static void pci_host_config_write(void *opaque, target_phys_addr_t addr,
-                                  uint64_t val, unsigned len)
+static void pci_host_config_write(ReadWriteHandler *handler,
+                                  pcibus_t addr, uint32_t val, int len)
 {
-    PCIHostState *s = opaque;
+    PCIHostState *s = container_of(handler, PCIHostState, conf_handler);
 
-    PCI_DPRINTF("%s addr " TARGET_FMT_plx " len %d val %"PRIx64"\n",
+    PCI_DPRINTF("%s addr %" FMT_PCIBUS " %d val %"PRIx32"\n",
                 __func__, addr, len, val);
     s->config_reg = val;
 }
 
-static uint64_t pci_host_config_read(void *opaque, target_phys_addr_t addr,
-                                     unsigned len)
+static uint32_t pci_host_config_read(ReadWriteHandler *handler,
+                                     pcibus_t addr, int len)
 {
-    PCIHostState *s = opaque;
+    PCIHostState *s = container_of(handler, PCIHostState, conf_handler);
     uint32_t val = s->config_reg;
 
-    PCI_DPRINTF("%s addr " TARGET_FMT_plx " len %d val %"PRIx32"\n",
+    PCI_DPRINTF("%s addr %" FMT_PCIBUS " len %d val %"PRIx32"\n",
                 __func__, addr, len, val);
     return val;
 }
 
-static void pci_host_data_write(void *opaque, target_phys_addr_t addr,
-                                uint64_t val, unsigned len)
+static void pci_host_data_write(ReadWriteHandler *handler,
+                                pcibus_t addr, uint32_t val, int len)
 {
-    PCIHostState *s = opaque;
-    PCI_DPRINTF("write addr " TARGET_FMT_plx " len %d val %x\n",
-                addr, len, (unsigned)val);
+    PCIHostState *s = container_of(handler, PCIHostState, data_handler);
+    PCI_DPRINTF("write addr %" FMT_PCIBUS " len %d val %x\n",
+                addr, len, val);
     if (s->config_reg & (1u << 31))
         pci_data_write(s->bus, s->config_reg | (addr & 3), val, len);
 }
 
-static uint64_t pci_host_data_read(void *opaque,
-                                   target_phys_addr_t addr, unsigned len)
+static uint32_t pci_host_data_read(ReadWriteHandler *handler,
+                                   pcibus_t addr, int len)
 {
-    PCIHostState *s = opaque;
+    PCIHostState *s = container_of(handler, PCIHostState, data_handler);
     uint32_t val;
     if (!(s->config_reg & (1 << 31)))
         return 0xffffffff;
     val = pci_data_read(s->bus, s->config_reg | (addr & 3), len);
-    PCI_DPRINTF("read addr " TARGET_FMT_plx " len %d val %x\n",
+    PCI_DPRINTF("read addr %" FMT_PCIBUS " len %d val %x\n",
                 addr, len, val);
     return val;
 }
 
-const MemoryRegionOps pci_host_conf_le_ops = {
-    .read = pci_host_config_read,
-    .write = pci_host_config_write,
-    .endianness = DEVICE_LITTLE_ENDIAN,
-};
-
-const MemoryRegionOps pci_host_conf_be_ops = {
-    .read = pci_host_config_read,
-    .write = pci_host_config_write,
-    .endianness = DEVICE_BIG_ENDIAN,
-};
+static void pci_host_init(PCIHostState *s)
+{
+    s->conf_handler.write = pci_host_config_write;
+    s->conf_handler.read = pci_host_config_read;
+    s->data_handler.write = pci_host_data_write;
+    s->data_handler.read = pci_host_data_read;
+}
 
-const MemoryRegionOps pci_host_data_le_ops = {
-    .read = pci_host_data_read,
-    .write = pci_host_data_write,
-    .endianness = DEVICE_LITTLE_ENDIAN,
-};
+int pci_host_conf_register_mmio(PCIHostState *s, int endian)
+{
+    pci_host_init(s);
+    return cpu_register_io_memory_simple(&s->conf_handler, endian);
+}
 
-const MemoryRegionOps pci_host_data_be_ops = {
-    .read = pci_host_data_read,
-    .write = pci_host_data_write,
-    .endianness = DEVICE_BIG_ENDIAN,
-};
+void pci_host_conf_register_ioport(pio_addr_t ioport, PCIHostState *s)
+{
+    pci_host_init(s);
+    register_ioport_simple(&s->conf_handler, ioport, 4, 4);
+    sysbus_init_ioports(&s->busdev, ioport, 4);
+}
 
+int pci_host_data_register_mmio(PCIHostState *s, int endian)
+{
+    pci_host_init(s);
+    return cpu_register_io_memory_simple(&s->data_handler, endian);
+}
 
+void pci_host_data_register_ioport(pio_addr_t ioport, PCIHostState *s)
+{
+    pci_host_init(s);
+    register_ioport_simple(&s->data_handler, ioport, 4, 1);
+    register_ioport_simple(&s->data_handler, ioport, 4, 2);
+    register_ioport_simple(&s->data_handler, ioport, 4, 4);
+    sysbus_init_ioports(&s->busdev, ioport, 4);
+}
diff --git a/hw/pci_host.h b/hw/pci_host.h
index 0211086..7f55114 100644
--- a/hw/pci_host.h
+++ b/hw/pci_host.h
@@ -29,11 +29,12 @@
 #define PCI_HOST_H
 
 #include "sysbus.h"
+#include "rwhandler.h"
 
 struct PCIHostState {
     SysBusDevice busdev;
-    MemoryRegion conf_mem;
-    MemoryRegion data_mem;
+    ReadWriteHandler conf_handler;
+    ReadWriteHandler data_handler;
     MemoryRegion *address_space;
     uint32_t config_reg;
     PCIBus *bus;
@@ -48,9 +49,12 @@ uint32_t pci_host_config_read_common(PCIDevice *pci_dev, uint32_t addr,
 void pci_data_write(PCIBus *s, uint32_t addr, uint32_t val, int len);
 uint32_t pci_data_read(PCIBus *s, uint32_t addr, int len);
 
-extern const MemoryRegionOps pci_host_conf_le_ops;
-extern const MemoryRegionOps pci_host_conf_be_ops;
-extern const MemoryRegionOps pci_host_data_le_ops;
-extern const MemoryRegionOps pci_host_data_be_ops;
+/* for mmio */
+int pci_host_conf_register_mmio(PCIHostState *s, int endian);
+int pci_host_data_register_mmio(PCIHostState *s, int endian);
+
+/* for ioio */
+void pci_host_conf_register_ioport(pio_addr_t ioport, PCIHostState *s);
+void pci_host_data_register_ioport(pio_addr_t ioport, PCIHostState *s);
 
 #endif /* PCI_HOST_H */
diff --git a/hw/petalogix_ml605_mmu.c b/hw/petalogix_ml605_mmu.c
index 257fcca..e3ca310 100644
--- a/hw/petalogix_ml605_mmu.c
+++ b/hw/petalogix_ml605_mmu.c
@@ -149,7 +149,7 @@ petalogix_ml605_init(ram_addr_t ram_size,
     target_phys_addr_t ddr_base = MEMORY_BASEADDR;
     ram_addr_t phys_lmb_bram;
     ram_addr_t phys_ram;
-    MemoryRegion *phys_flash = g_new(MemoryRegion, 1);
+    ram_addr_t phys_flash;
     qemu_irq irq[32], *cpu_irq;
 
     /* init CPUs */
@@ -169,15 +169,14 @@ petalogix_ml605_init(ram_addr_t ram_size,
     phys_ram = qemu_ram_alloc(NULL, "petalogix_ml605.ram", ram_size);
     cpu_register_physical_memory(ddr_base, ram_size, phys_ram | IO_MEM_RAM);
 
-    memory_region_init_rom_device(phys_flash, &pflash_cfi01_ops_le,
-                                  NULL, "petalogix_ml605.flash", FLASH_SIZE);
+    phys_flash = qemu_ram_alloc(NULL, "petalogix_ml605.flash", FLASH_SIZE);
     dinfo = drive_get(IF_PFLASH, 0, 0);
     /* 5th parameter 2 means bank-width
      * 10th paremeter 0 means little-endian */
     pflash_cfi01_register(FLASH_BASEADDR, phys_flash,
                           dinfo ? dinfo->bdrv : NULL, (64 * 1024),
                           FLASH_SIZE >> 16,
-                          2, 0x89, 0x18, 0x0000, 0x0);
+                          2, 0x89, 0x18, 0x0000, 0x0, 0);
 
 
     cpu_irq = microblaze_pic_init_cpu(env);
diff --git a/hw/petalogix_s3adsp1800_mmu.c b/hw/petalogix_s3adsp1800_mmu.c
index 1481745..a43fb4c 100644
--- a/hw/petalogix_s3adsp1800_mmu.c
+++ b/hw/petalogix_s3adsp1800_mmu.c
@@ -127,7 +127,7 @@ petalogix_s3adsp1800_init(ram_addr_t ram_size,
     target_phys_addr_t ddr_base = 0x90000000;
     ram_addr_t phys_lmb_bram;
     ram_addr_t phys_ram;
-    MemoryRegion *phys_flash = g_new(MemoryRegion, 1);
+    ram_addr_t phys_flash;
     qemu_irq irq[32], *cpu_irq;
 
     /* init CPUs */
@@ -148,14 +148,12 @@ petalogix_s3adsp1800_init(ram_addr_t ram_size,
     phys_ram = qemu_ram_alloc(NULL, "petalogix_s3adsp1800.ram", ram_size);
     cpu_register_physical_memory(ddr_base, ram_size, phys_ram | IO_MEM_RAM);
 
-    memory_region_init_rom_device(phys_flash, &pflash_cfi01_ops_be,
-                                  NULL, "petalogix_s3adsp1800.flash",
-                                  FLASH_SIZE);
+    phys_flash = qemu_ram_alloc(NULL, "petalogix_s3adsp1800.flash", FLASH_SIZE);
     dinfo = drive_get(IF_PFLASH, 0, 0);
     pflash_cfi01_register(0xa0000000, phys_flash,
                           dinfo ? dinfo->bdrv : NULL, (64 * 1024),
                           FLASH_SIZE >> 16,
-                          1, 0x89, 0x18, 0x0000, 0x0);
+                          1, 0x89, 0x18, 0x0000, 0x0, 1);
 
     cpu_irq = microblaze_pic_init_cpu(env);
     dev = xilinx_intc_create(0x81800000, cpu_irq[0], 2);
diff --git a/hw/pflash_cfi01.c b/hw/pflash_cfi01.c
index 2144c6a..90e1301 100644
--- a/hw/pflash_cfi01.c
+++ b/hw/pflash_cfi01.c
@@ -40,7 +40,6 @@
 #include "flash.h"
 #include "block.h"
 #include "qemu-timer.h"
-#include "exec-memory.h"
 
 #define PFLASH_BUG(fmt, ...) \
 do { \
@@ -75,7 +74,8 @@ struct pflash_t {
     target_phys_addr_t counter;
     unsigned int writeblock_size;
     QEMUTimer *timer;
-    MemoryRegion *mem;
+    ram_addr_t off;
+    int fl_mem;
     void *storage;
 };
 
@@ -89,7 +89,8 @@ static void pflash_timer (void *opaque)
     if (pfl->bypass) {
         pfl->wcycle = 2;
     } else {
-        memory_region_rom_device_set_readable(pfl->mem, true);
+        cpu_register_physical_memory(pfl->base, pfl->total_len,
+                        pfl->off | IO_MEM_ROMD | pfl->fl_mem);
         pfl->wcycle = 0;
     }
     pfl->cmd = 0;
@@ -262,7 +263,7 @@ static void pflash_write(pflash_t *pfl, target_phys_addr_t offset,
 
     if (!pfl->wcycle) {
         /* Set the device in I/O access mode */
-        memory_region_rom_device_set_readable(pfl->mem, false);
+        cpu_register_physical_memory(pfl->base, pfl->total_len, pfl->fl_mem);
     }
 
     switch (pfl->wcycle) {
@@ -421,7 +422,8 @@ static void pflash_write(pflash_t *pfl, target_phys_addr_t offset,
            __func__, offset, pfl->wcycle, pfl->cmd, value);
 
  reset_flash:
-    memory_region_rom_device_set_readable(pfl->mem, true);
+    cpu_register_physical_memory(pfl->base, pfl->total_len,
+                    pfl->off | IO_MEM_ROMD | pfl->fl_mem);
 
     pfl->bypass = 0;
     pfl->wcycle = 0;
@@ -512,20 +514,28 @@ static void pflash_writel_le(void *opaque, target_phys_addr_t addr,
     pflash_write(pfl, addr, value, 4, 0);
 }
 
-const MemoryRegionOps pflash_cfi01_ops_be = {
-    .old_mmio = {
-        .read = { pflash_readb_be, pflash_readw_be, pflash_readl_be, },
-        .write = { pflash_writeb_be, pflash_writew_be, pflash_writel_be, },
-    },
-    .endianness = DEVICE_NATIVE_ENDIAN,
+static CPUWriteMemoryFunc * const pflash_write_ops_be[] = {
+    &pflash_writeb_be,
+    &pflash_writew_be,
+    &pflash_writel_be,
 };
 
-const MemoryRegionOps pflash_cfi01_ops_le = {
-    .old_mmio = {
-        .read = { pflash_readb_le, pflash_readw_le, pflash_readl_le, },
-        .write = { pflash_writeb_le, pflash_writew_le, pflash_writel_le, },
-    },
-    .endianness = DEVICE_NATIVE_ENDIAN,
+static CPUReadMemoryFunc * const pflash_read_ops_be[] = {
+    &pflash_readb_be,
+    &pflash_readw_be,
+    &pflash_readl_be,
+};
+
+static CPUWriteMemoryFunc * const pflash_write_ops_le[] = {
+    &pflash_writeb_le,
+    &pflash_writew_le,
+    &pflash_writel_le,
+};
+
+static CPUReadMemoryFunc * const pflash_read_ops_le[] = {
+    &pflash_readb_le,
+    &pflash_readw_le,
+    &pflash_readl_le,
 };
 
 /* Count trailing zeroes of a 32 bits quantity */
@@ -564,11 +574,12 @@ static int ctz32 (uint32_t n)
     return ret;
 }
 
-pflash_t *pflash_cfi01_register(target_phys_addr_t base, MemoryRegion *mem,
+pflash_t *pflash_cfi01_register(target_phys_addr_t base, ram_addr_t off,
                                 BlockDriverState *bs, uint32_t sector_len,
                                 int nb_blocs, int width,
                                 uint16_t id0, uint16_t id1,
-                                uint16_t id2, uint16_t id3)
+                                uint16_t id2, uint16_t id3,
+                                int be)
 {
     pflash_t *pfl;
     target_phys_addr_t total_len;
@@ -586,16 +597,26 @@ pflash_t *pflash_cfi01_register(target_phys_addr_t base, MemoryRegion *mem,
     pfl = g_malloc0(sizeof(pflash_t));
 
     /* FIXME: Allocate ram ourselves.  */
-    pfl->storage = memory_region_get_ram_ptr(mem);
-    pfl->mem = mem;
-    memory_region_add_subregion(get_system_memory(), base, mem);
+    pfl->storage = qemu_get_ram_ptr(off);
+    if (be) {
+        pfl->fl_mem = cpu_register_io_memory(pflash_read_ops_be,
+                                             pflash_write_ops_be, pfl,
+                                             DEVICE_NATIVE_ENDIAN);
+    } else {
+        pfl->fl_mem = cpu_register_io_memory(pflash_read_ops_le,
+                                             pflash_write_ops_le, pfl,
+                                             DEVICE_NATIVE_ENDIAN);
+    }
+    pfl->off = off;
+    cpu_register_physical_memory(base, total_len,
+                    off | pfl->fl_mem | IO_MEM_ROMD);
 
     pfl->bs = bs;
     if (pfl->bs) {
         /* read the initial flash content */
         ret = bdrv_read(pfl->bs, 0, pfl->storage, total_len >> 9);
         if (ret < 0) {
-            memory_region_del_subregion(get_system_memory(), mem);
+            cpu_unregister_io_memory(pfl->fl_mem);
             g_free(pfl);
             return NULL;
         }
diff --git a/hw/pflash_cfi02.c b/hw/pflash_cfi02.c
index e7e0408..ac5115e 100644
--- a/hw/pflash_cfi02.c
+++ b/hw/pflash_cfi02.c
@@ -39,7 +39,6 @@
 #include "flash.h"
 #include "qemu-timer.h"
 #include "block.h"
-#include "exec-memory.h"
 
 //#define PFLASH_DEBUG
 #ifdef PFLASH_DEBUG
@@ -70,39 +69,25 @@ struct pflash_t {
     uint8_t cfi_len;
     uint8_t cfi_table[0x52];
     QEMUTimer *timer;
-    /* The device replicates the flash memory across its memory space.  Emulate
-     * that by having a container (.mem) filled with an array of aliases
-     * (.mem_mappings) pointing to the flash memory (.orig_mem).
-     */
-    MemoryRegion mem;
-    MemoryRegion *mem_mappings;    /* array; one per mapping */
-    MemoryRegion *orig_mem;
+    ram_addr_t off;
+    int fl_mem;
     int rom_mode;
     int read_counter; /* used for lazy switch-back to rom mode */
     void *storage;
 };
 
-/*
- * Set up replicated mappings of the same region.
- */
-static void pflash_setup_mappings(pflash_t *pfl, MemoryRegion *mem)
-{
-    unsigned i;
-    target_phys_addr_t size = memory_region_size(mem);
-
-    pfl->orig_mem = mem;
-    memory_region_init(&pfl->mem, "pflash", pfl->mappings * size);
-    pfl->mem_mappings = g_new(MemoryRegion, pfl->mappings);
-    for (i = 0; i < pfl->mappings; ++i) {
-        memory_region_init_alias(&pfl->mem_mappings[i], "pflash-alias", mem,
-                                 0, size);
-        memory_region_add_subregion(&pfl->mem, i * size, &pfl->mem_mappings[i]);
-    }
-}
-
 static void pflash_register_memory(pflash_t *pfl, int rom_mode)
 {
-    memory_region_rom_device_set_readable(pfl->orig_mem, rom_mode);
+    unsigned long phys_offset = pfl->fl_mem;
+    int i;
+
+    if (rom_mode)
+        phys_offset |= pfl->off | IO_MEM_ROMD;
+    pfl->rom_mode = rom_mode;
+
+    for (i = 0; i < pfl->mappings; i++)
+        cpu_register_physical_memory(pfl->base + i * pfl->chip_len,
+                                     pfl->chip_len, phys_offset);
 }
 
 static void pflash_timer (void *opaque)
@@ -553,20 +538,28 @@ static void pflash_writel_le(void *opaque, target_phys_addr_t addr,
     pflash_write(pfl, addr, value, 4, 0);
 }
 
-const MemoryRegionOps pflash_cfi02_ops_be = {
-    .old_mmio = {
-        .read = { pflash_readb_be, pflash_readw_be, pflash_readl_be, },
-        .write = { pflash_writeb_be, pflash_writew_be, pflash_writel_be, },
-    },
-    .endianness = DEVICE_NATIVE_ENDIAN,
+static CPUWriteMemoryFunc * const pflash_write_ops_be[] = {
+    &pflash_writeb_be,
+    &pflash_writew_be,
+    &pflash_writel_be,
+};
+
+static CPUReadMemoryFunc * const pflash_read_ops_be[] = {
+    &pflash_readb_be,
+    &pflash_readw_be,
+    &pflash_readl_be,
 };
 
-const MemoryRegionOps pflash_cfi02_ops_le = {
-    .old_mmio = {
-        .read = { pflash_readb_le, pflash_readw_le, pflash_readl_le, },
-        .write = { pflash_writeb_le, pflash_writew_le, pflash_writel_le, },
-    },
-    .endianness = DEVICE_NATIVE_ENDIAN,
+static CPUWriteMemoryFunc * const pflash_write_ops_le[] = {
+    &pflash_writeb_le,
+    &pflash_writew_le,
+    &pflash_writel_le,
+};
+
+static CPUReadMemoryFunc * const pflash_read_ops_le[] = {
+    &pflash_readb_le,
+    &pflash_readw_le,
+    &pflash_readl_le,
 };
 
 /* Count trailing zeroes of a 32 bits quantity */
@@ -605,12 +598,13 @@ static int ctz32 (uint32_t n)
     return ret;
 }
 
-pflash_t *pflash_cfi02_register(target_phys_addr_t base, MemoryRegion *mem,
+pflash_t *pflash_cfi02_register(target_phys_addr_t base, ram_addr_t off,
                                 BlockDriverState *bs, uint32_t sector_len,
                                 int nb_blocs, int nb_mappings, int width,
                                 uint16_t id0, uint16_t id1,
                                 uint16_t id2, uint16_t id3,
-                                uint16_t unlock_addr0, uint16_t unlock_addr1)
+                                uint16_t unlock_addr0, uint16_t unlock_addr1,
+                                int be)
 {
     pflash_t *pfl;
     int32_t chip_len;
@@ -625,22 +619,31 @@ pflash_t *pflash_cfi02_register(target_phys_addr_t base, MemoryRegion *mem,
 #endif
     pfl = g_malloc0(sizeof(pflash_t));
     /* FIXME: Allocate ram ourselves.  */
-    pfl->storage = memory_region_get_ram_ptr(mem);
+    pfl->storage = qemu_get_ram_ptr(off);
+    if (be) {
+        pfl->fl_mem = cpu_register_io_memory(pflash_read_ops_be,
+                                             pflash_write_ops_be,
+                                             pfl, DEVICE_NATIVE_ENDIAN);
+    } else {
+        pfl->fl_mem = cpu_register_io_memory(pflash_read_ops_le,
+                                             pflash_write_ops_le,
+                                             pfl, DEVICE_NATIVE_ENDIAN);
+    }
+    pfl->off = off;
     pfl->base = base;
     pfl->chip_len = chip_len;
     pfl->mappings = nb_mappings;
+    pflash_register_memory(pfl, 1);
     pfl->bs = bs;
     if (pfl->bs) {
         /* read the initial flash content */
         ret = bdrv_read(pfl->bs, 0, pfl->storage, chip_len >> 9);
         if (ret < 0) {
+            cpu_unregister_io_memory(pfl->fl_mem);
             g_free(pfl);
             return NULL;
         }
     }
-    pflash_setup_mappings(pfl, mem);
-    pfl->rom_mode = 1;
-    memory_region_add_subregion(get_system_memory(), pfl->base, &pfl->mem);
 #if 0 /* XXX: there should be a bit to set up read-only,
        *      the same way the hardware does (with WP pin).
        */
diff --git a/hw/piix_pci.c b/hw/piix_pci.c
index 8f6ea42..c563c6e 100644
--- a/hw/piix_pci.c
+++ b/hw/piix_pci.c
@@ -142,7 +142,6 @@ static void i440fx_update_memory_mappings(PCII440FXState *d)
     int i, r;
     uint32_t smram;
 
-    memory_region_transaction_begin();
     update_pam(d, 0xf0000, 0x100000, (d->dev.config[I440FX_PAM] >> 4) & 3,
                &d->pam_regions[0]);
     for(i = 0; i < 12; i++) {
@@ -163,7 +162,6 @@ static void i440fx_update_memory_mappings(PCII440FXState *d)
             d->smram_enabled = false;
         }
     }
-    memory_region_transaction_commit();
 }
 
 static void i440fx_set_smm(int val, void *arg)
@@ -237,16 +235,9 @@ static int i440fx_pcihost_initfn(SysBusDevice *dev)
 {
     I440FXState *s = FROM_SYSBUS(I440FXState, dev);
 
-    memory_region_init_io(&s->conf_mem, &pci_host_conf_le_ops, s,
-                          "pci-conf-idx", 4);
-    sysbus_add_io(dev, 0xcf8, &s->conf_mem);
-    sysbus_init_ioports(&s->busdev, 0xcf8, 4);
-
-    memory_region_init_io(&s->data_mem, &pci_host_data_le_ops, s,
-                          "pci-conf-data", 4);
-    sysbus_add_io(dev, 0xcfc, &s->data_mem);
-    sysbus_init_ioports(&s->busdev, 0xcfc, 4);
+    pci_host_conf_register_ioport(0xcf8, s);
 
+    pci_host_data_register_ioport(0xcfc, s);
     return 0;
 }
 
diff --git a/hw/ppc405_boards.c b/hw/ppc405_boards.c
index 1eb807c..dec165e 100644
--- a/hw/ppc405_boards.c
+++ b/hw/ppc405_boards.c
@@ -32,7 +32,6 @@
 #include "qemu-log.h"
 #include "loader.h"
 #include "blockdev.h"
-#include "exec-memory.h"
 
 #define BIOS_FILENAME "ppc405_rom.bin"
 #define BIOS_SIZE (2048 * 1024)
@@ -182,9 +181,7 @@ static void ref405ep_init (ram_addr_t ram_size,
     ppc4xx_bd_info_t bd;
     CPUPPCState *env;
     qemu_irq *pic;
-    ram_addr_t sram_offset, bdloc;
-    MemoryRegion *address_space_mem = get_system_memory();
-    MemoryRegion *bios = g_new(MemoryRegion, 1);
+    ram_addr_t sram_offset, bios_offset, bdloc;
     MemoryRegion *ram_memories = g_malloc(2 * sizeof(*ram_memories));
     target_phys_addr_t ram_bases[2], ram_sizes[2];
     target_ulong sram_size;
@@ -227,18 +224,18 @@ static void ref405ep_init (ram_addr_t ram_size,
     dinfo = drive_get(IF_PFLASH, 0, fl_idx);
     if (dinfo) {
         bios_size = bdrv_getlength(dinfo->bdrv);
-        memory_region_init_rom_device(bios, &pflash_cfi02_ops_be,
-                                      NULL, "ef405ep.bios", bios_size);
+        bios_offset = qemu_ram_alloc(NULL, "ef405ep.bios", bios_size);
         fl_sectors = (bios_size + 65535) >> 16;
 #ifdef DEBUG_BOARD_INIT
         printf("Register parallel flash %d size %lx"
-               " at addr %lx '%s' %d\n",
-               fl_idx, bios_size, -bios_size,
+               " at offset %08lx addr %lx '%s' %d\n",
+               fl_idx, bios_size, bios_offset, -bios_size,
                bdrv_get_device_name(dinfo->bdrv), fl_sectors);
 #endif
-        pflash_cfi02_register((uint32_t)(-bios_size), bios,
+        pflash_cfi02_register((uint32_t)(-bios_size), bios_offset,
                               dinfo->bdrv, 65536, fl_sectors, 1,
-                              2, 0x0001, 0x22DA, 0x0000, 0x0000, 0x555, 0x2AA);
+                              2, 0x0001, 0x22DA, 0x0000, 0x0000, 0x555, 0x2AA,
+                              1);
         fl_idx++;
     } else
 #endif
@@ -246,12 +243,12 @@ static void ref405ep_init (ram_addr_t ram_size,
 #ifdef DEBUG_BOARD_INIT
         printf("Load BIOS from file\n");
 #endif
-        memory_region_init_ram(bios, NULL, "ef405ep.bios", BIOS_SIZE);
+        bios_offset = qemu_ram_alloc(NULL, "ef405ep.bios", BIOS_SIZE);
         if (bios_name == NULL)
             bios_name = BIOS_FILENAME;
         filename = qemu_find_file(QEMU_FILE_TYPE_BIOS, bios_name);
         if (filename) {
-            bios_size = load_image(filename, memory_region_get_ram_ptr(bios));
+            bios_size = load_image(filename, qemu_get_ram_ptr(bios_offset));
             g_free(filename);
         } else {
             bios_size = -1;
@@ -262,9 +259,8 @@ static void ref405ep_init (ram_addr_t ram_size,
             exit(1);
         }
         bios_size = (bios_size + 0xfff) & ~0xfff;
-        memory_region_set_readonly(bios, true);
-        memory_region_add_subregion(address_space_mem, (uint32_t)(-bios_size),
-                                    bios);
+        cpu_register_physical_memory((uint32_t)(-bios_size),
+                                     bios_size, bios_offset | IO_MEM_ROM);
     }
     /* Register FPGA */
 #ifdef DEBUG_BOARD_INIT
@@ -511,9 +507,7 @@ static void taihu_405ep_init(ram_addr_t ram_size,
 {
     char *filename;
     qemu_irq *pic;
-    MemoryRegion *address_space_mem = get_system_memory();
-    MemoryRegion *bios = g_new(MemoryRegion, 1);
-    MemoryRegion *flash = g_new(MemoryRegion, 1);
+    ram_addr_t bios_offset;
     MemoryRegion *ram_memories = g_malloc(2 * sizeof(*ram_memories));
     target_phys_addr_t ram_bases[2], ram_sizes[2];
     long bios_size;
@@ -550,17 +544,17 @@ static void taihu_405ep_init(ram_addr_t ram_size,
         /* XXX: should check that size is 2MB */
         //        bios_size = 2 * 1024 * 1024;
         fl_sectors = (bios_size + 65535) >> 16;
-        memory_region_init_rom_device(bios, &pflash_cfi02_ops_be,
-                                      NULL, "taihu_405ep.bios", bios_size);
+        bios_offset = qemu_ram_alloc(NULL, "taihu_405ep.bios", bios_size);
 #ifdef DEBUG_BOARD_INIT
         printf("Register parallel flash %d size %lx"
-               " at addr %lx '%s' %d\n",
-               fl_idx, bios_size, -bios_size,
+               " at offset %08lx addr %lx '%s' %d\n",
+               fl_idx, bios_size, bios_offset, -bios_size,
                bdrv_get_device_name(dinfo->bdrv), fl_sectors);
 #endif
-        pflash_cfi02_register((uint32_t)(-bios_size), bios,
+        pflash_cfi02_register((uint32_t)(-bios_size), bios_offset,
                               dinfo->bdrv, 65536, fl_sectors, 1,
-                              4, 0x0001, 0x22DA, 0x0000, 0x0000, 0x555, 0x2AA);
+                              4, 0x0001, 0x22DA, 0x0000, 0x0000, 0x555, 0x2AA,
+                              1);
         fl_idx++;
     } else
 #endif
@@ -570,10 +564,10 @@ static void taihu_405ep_init(ram_addr_t ram_size,
 #endif
         if (bios_name == NULL)
             bios_name = BIOS_FILENAME;
-        memory_region_init_ram(bios, NULL, "taihu_405ep.bios", BIOS_SIZE);
+        bios_offset = qemu_ram_alloc(NULL, "taihu_405ep.bios", BIOS_SIZE);
         filename = qemu_find_file(QEMU_FILE_TYPE_BIOS, bios_name);
         if (filename) {
-            bios_size = load_image(filename, memory_region_get_ram_ptr(bios));
+            bios_size = load_image(filename, qemu_get_ram_ptr(bios_offset));
             g_free(filename);
         } else {
             bios_size = -1;
@@ -584,9 +578,8 @@ static void taihu_405ep_init(ram_addr_t ram_size,
             exit(1);
         }
         bios_size = (bios_size + 0xfff) & ~0xfff;
-        memory_region_set_readonly(bios, true);
-        memory_region_add_subregion(address_space_mem,
-                                    (uint32_t)(-bios_size), bios);
+        cpu_register_physical_memory((uint32_t)(-bios_size),
+                                     bios_size, bios_offset | IO_MEM_ROM);
     }
     /* Register Linux flash */
     dinfo = drive_get(IF_PFLASH, 0, fl_idx);
@@ -597,15 +590,15 @@ static void taihu_405ep_init(ram_addr_t ram_size,
         fl_sectors = (bios_size + 65535) >> 16;
 #ifdef DEBUG_BOARD_INIT
         printf("Register parallel flash %d size %lx"
-               " at addr " TARGET_FMT_lx " '%s'\n",
-               fl_idx, bios_size, (target_ulong)0xfc000000,
+               " at offset %08lx  addr " TARGET_FMT_lx " '%s'\n",
+               fl_idx, bios_size, bios_offset, (target_ulong)0xfc000000,
                bdrv_get_device_name(dinfo->bdrv));
 #endif
-        memory_region_init_rom_device(flash, &pflash_cfi02_ops_be,
-                                      NULL, "taihu_405ep.flash", bios_size);
-        pflash_cfi02_register(0xfc000000, flash,
+        bios_offset = qemu_ram_alloc(NULL, "taihu_405ep.flash", bios_size);
+        pflash_cfi02_register(0xfc000000, bios_offset,
                               dinfo->bdrv, 65536, fl_sectors, 1,
-                              4, 0x0001, 0x22DA, 0x0000, 0x0000, 0x555, 0x2AA);
+                              4, 0x0001, 0x22DA, 0x0000, 0x0000, 0x555, 0x2AA,
+                              1);
         fl_idx++;
     }
     /* Register CLPD & LCD display */
diff --git a/hw/ppc4xx_pci.c b/hw/ppc4xx_pci.c
index 339b38e..52e2663 100644
--- a/hw/ppc4xx_pci.c
+++ b/hw/ppc4xx_pci.c
@@ -368,12 +368,10 @@ PCIBus *ppc4xx_pci_init(CPUState *env, qemu_irq pci_irqs[4],
     cpu_register_physical_memory(config_space + PCIC0_CFGADDR, 4, index);
 
     /* CFGDATA */
-    memory_region_init_io(&controller->pci_state.data_mem,
-                          &pci_host_data_be_ops,
-                          &controller->pci_state, "pci-conf-data", 4);
-    memory_region_add_subregion(get_system_memory(),
-                                config_space + PCIC0_CFGDATA,
-                                &controller->pci_state.data_mem);
+    index = pci_host_data_register_mmio(&controller->pci_state, 1);
+    if (index < 0)
+        goto free;
+    cpu_register_physical_memory(config_space + PCIC0_CFGDATA, 4, index);
 
     /* Internal registers */
     index = cpu_register_io_memory(pci_reg_read, pci_reg_write, controller,
diff --git a/hw/ppce500_pci.c b/hw/ppce500_pci.c
index 2db365d..4390aeb 100644
--- a/hw/ppce500_pci.c
+++ b/hw/ppce500_pci.c
@@ -79,6 +79,8 @@ struct PPCE500PCIState {
     uint32_t gasket_time;
     qemu_irq irq[4];
     /* mmio maps */
+    int cfgaddr;
+    int cfgdata;
     int reg;
 };
 
@@ -266,18 +268,18 @@ static void e500_pci_map(SysBusDevice *dev, target_phys_addr_t base)
     PCIHostState *h = FROM_SYSBUS(PCIHostState, sysbus_from_qdev(dev));
     PPCE500PCIState *s = DO_UPCAST(PPCE500PCIState, pci_state, h);
 
-    sysbus_add_memory(dev, base + PCIE500_CFGADDR, &h->conf_mem);
-    sysbus_add_memory(dev, base + PCIE500_CFGDATA, &h->data_mem);
+    cpu_register_physical_memory(base + PCIE500_CFGADDR, 4, s->cfgaddr);
+    cpu_register_physical_memory(base + PCIE500_CFGDATA, 4, s->cfgdata);
     cpu_register_physical_memory(base + PCIE500_REG_BASE, PCIE500_REG_SIZE,
                                  s->reg);
 }
 
 static void e500_pci_unmap(SysBusDevice *dev, target_phys_addr_t base)
 {
-    PCIHostState *h = FROM_SYSBUS(PCIHostState, sysbus_from_qdev(dev));
-
-    sysbus_del_memory(dev, &h->conf_mem);
-    sysbus_del_memory(dev, &h->data_mem);
+    cpu_register_physical_memory(base + PCIE500_CFGADDR, 4,
+                                 IO_MEM_UNASSIGNED);
+    cpu_register_physical_memory(base + PCIE500_CFGDATA, 4,
+                                 IO_MEM_UNASSIGNED);
     cpu_register_physical_memory(base + PCIE500_REG_BASE, PCIE500_REG_SIZE,
                                  IO_MEM_UNASSIGNED);
 }
@@ -307,10 +309,9 @@ static int e500_pcihost_initfn(SysBusDevice *dev)
 
     pci_create_simple(b, 0, "e500-host-bridge");
 
-    memory_region_init_io(&h->conf_mem, &pci_host_conf_be_ops, h,
-                          "pci-conf-idx", 4);
-    memory_region_init_io(&h->data_mem, &pci_host_data_le_ops, h,
-                          "pci-conf-data", 4);
+    s->cfgaddr = pci_host_conf_register_mmio(&s->pci_state, DEVICE_BIG_ENDIAN);
+    s->cfgdata = pci_host_data_register_mmio(&s->pci_state,
+                                             DEVICE_LITTLE_ENDIAN);
     s->reg = cpu_register_io_memory(e500_pci_reg_read, e500_pci_reg_write, s,
                                     DEVICE_BIG_ENDIAN);
     sysbus_init_mmio_cb2(dev, e500_pci_map, e500_pci_unmap);
diff --git a/hw/prep_pci.c b/hw/prep_pci.c
index 55e4e25..c36232a 100644
--- a/hw/prep_pci.c
+++ b/hw/prep_pci.c
@@ -125,15 +125,9 @@ PCIBus *pci_prep_init(qemu_irq *pic,
                               address_space_io,
                               0, 4);
 
-    memory_region_init_io(&s->conf_mem, &pci_host_conf_be_ops, s,
-                          "pci-conf-idx", 1);
-    memory_region_add_subregion(address_space_io, 0xcf8, &s->conf_mem);
-    sysbus_init_ioports(&s->busdev, 0xcf8, 1);
-
-    memory_region_init_io(&s->conf_mem, &pci_host_data_be_ops, s,
-                          "pci-conf-data", 1);
-    memory_region_add_subregion(address_space_io, 0xcfc, &s->data_mem);
-    sysbus_init_ioports(&s->busdev, 0xcfc, 1);
+    pci_host_conf_register_ioport(0xcf8, s);
+
+    pci_host_data_register_ioport(0xcfc, s);
 
     PPC_io_memory = cpu_register_io_memory(PPC_PCIIO_read,
                                            PPC_PCIIO_write, s,
diff --git a/hw/r2d.c b/hw/r2d.c
index 41aa2c2..96a7ff8 100644
--- a/hw/r2d.c
+++ b/hw/r2d.c
@@ -235,7 +235,6 @@ static void r2d_init(ram_addr_t ram_size,
     qemu_irq *irq;
     DriveInfo *dinfo;
     int i;
-    MemoryRegion *flash = g_new(MemoryRegion, 1);
 
     if (!cpu_model)
         cpu_model = "SH7751R";
@@ -268,13 +267,11 @@ static void r2d_init(ram_addr_t ram_size,
 
     /* onboard flash memory */
     dinfo = drive_get(IF_PFLASH, 0, 0);
-    memory_region_init_rom_device(flash, &pflash_cfi02_ops_le,
-                                  NULL, "r2d.flash", FLASH_SIZE);
-    pflash_cfi02_register(0x0, flash,
+    pflash_cfi02_register(0x0, qemu_ram_alloc(NULL, "r2d.flash", FLASH_SIZE),
                           dinfo ? dinfo->bdrv : NULL, (16 * 1024),
                           FLASH_SIZE >> 16,
                           1, 4, 0x0000, 0x0000, 0x0000, 0x0000,
-                          0x555, 0x2aa);
+                          0x555, 0x2aa, 0);
 
     /* NIC: rtl8139 on-board, and 2 slots. */
     for (i = 0; i < nb_nics; i++)
diff --git a/hw/stellaris.c b/hw/stellaris.c
index 2bf1c23..9b0db7f 100644
--- a/hw/stellaris.c
+++ b/hw/stellaris.c
@@ -15,7 +15,6 @@
 #include "i2c.h"
 #include "net.h"
 #include "boards.h"
-#include "exec-memory.h"
 
 #define GPIO_A 0
 #define GPIO_B 1
@@ -1261,7 +1260,6 @@ static void stellaris_init(const char *kernel_filename, const char *cpu_model,
         0x40024000, 0x40025000, 0x40026000};
     static const int gpio_irq[7] = {0, 1, 2, 3, 4, 30, 31};
 
-    MemoryRegion *address_space_mem = get_system_memory();
     qemu_irq *pic;
     DeviceState *gpio_dev[7];
     qemu_irq gpio_in[7][8];
@@ -1276,8 +1274,7 @@ static void stellaris_init(const char *kernel_filename, const char *cpu_model,
 
     flash_size = ((board->dc0 & 0xffff) + 1) << 1;
     sram_size = (board->dc0 >> 18) + 1;
-    pic = armv7m_init(address_space_mem,
-                      flash_size, sram_size, kernel_filename, cpu_model);
+    pic = armv7m_init(flash_size, sram_size, kernel_filename, cpu_model);
 
     if (board->dc1 & (1 << 16)) {
         dev = sysbus_create_varargs("stellaris-adc", 0x40038000,
diff --git a/hw/stellaris_enet.c b/hw/stellaris_enet.c
index d5613ff..f9bd3da 100644
--- a/hw/stellaris_enet.c
+++ b/hw/stellaris_enet.c
@@ -69,7 +69,7 @@ typedef struct {
     NICState *nic;
     NICConf conf;
     qemu_irq irq;
-    MemoryRegion mmio;
+    int mmio_index;
 } stellaris_enet_state;
 
 static void stellaris_enet_update(stellaris_enet_state *s)
@@ -130,8 +130,7 @@ static int stellaris_enet_can_receive(VLANClientState *nc)
     return (s->np < 31);
 }
 
-static uint64_t stellaris_enet_read(void *opaque, target_phys_addr_t offset,
-                                    unsigned size)
+static uint32_t stellaris_enet_read(void *opaque, target_phys_addr_t offset)
 {
     stellaris_enet_state *s = (stellaris_enet_state *)opaque;
     uint32_t val;
@@ -199,7 +198,7 @@ static uint64_t stellaris_enet_read(void *opaque, target_phys_addr_t offset,
 }
 
 static void stellaris_enet_write(void *opaque, target_phys_addr_t offset,
-                                 uint64_t value, unsigned size)
+                        uint32_t value)
 {
     stellaris_enet_state *s = (stellaris_enet_state *)opaque;
 
@@ -304,12 +303,17 @@ static void stellaris_enet_write(void *opaque, target_phys_addr_t offset,
     }
 }
 
-static const MemoryRegionOps stellaris_enet_ops = {
-    .read = stellaris_enet_read,
-    .write = stellaris_enet_write,
-    .endianness = DEVICE_NATIVE_ENDIAN,
+static CPUReadMemoryFunc * const stellaris_enet_readfn[] = {
+   stellaris_enet_read,
+   stellaris_enet_read,
+   stellaris_enet_read
 };
 
+static CPUWriteMemoryFunc * const stellaris_enet_writefn[] = {
+   stellaris_enet_write,
+   stellaris_enet_write,
+   stellaris_enet_write
+};
 static void stellaris_enet_reset(stellaris_enet_state *s)
 {
     s->mdv = 0x80;
@@ -387,7 +391,7 @@ static void stellaris_enet_cleanup(VLANClientState *nc)
 
     unregister_savevm(&s->busdev.qdev, "stellaris_enet", s);
 
-    memory_region_destroy(&s->mmio);
+    cpu_unregister_io_memory(s->mmio_index);
 
     g_free(s);
 }
@@ -404,9 +408,10 @@ static int stellaris_enet_init(SysBusDevice *dev)
 {
     stellaris_enet_state *s = FROM_SYSBUS(stellaris_enet_state, dev);
 
-    memory_region_init_io(&s->mmio, &stellaris_enet_ops, s, "stellaris_enet",
-                          0x1000);
-    sysbus_init_mmio_region(dev, &s->mmio);
+    s->mmio_index = cpu_register_io_memory(stellaris_enet_readfn,
+                                           stellaris_enet_writefn, s,
+                                           DEVICE_NATIVE_ENDIAN);
+    sysbus_init_mmio(dev, 0x1000, s->mmio_index);
     sysbus_init_irq(dev, &s->irq);
     qemu_macaddr_default_if_unset(&s->conf.macaddr);
 
diff --git a/hw/sysbus.c b/hw/sysbus.c
index 6e89f06..f39768b 100644
--- a/hw/sysbus.c
+++ b/hw/sysbus.c
@@ -256,32 +256,3 @@ static char *sysbus_get_fw_dev_path(DeviceState *dev)
 
     return strdup(path);
 }
-
-void sysbus_add_memory(SysBusDevice *dev, target_phys_addr_t addr,
-                       MemoryRegion *mem)
-{
-    memory_region_add_subregion(get_system_memory(), addr, mem);
-}
-
-void sysbus_add_memory_overlap(SysBusDevice *dev, target_phys_addr_t addr,
-                               MemoryRegion *mem, unsigned priority)
-{
-    memory_region_add_subregion_overlap(get_system_memory(), addr, mem,
-                                        priority);
-}
-
-void sysbus_del_memory(SysBusDevice *dev, MemoryRegion *mem)
-{
-    memory_region_del_subregion(get_system_memory(), mem);
-}
-
-void sysbus_add_io(SysBusDevice *dev, target_phys_addr_t addr,
-                       MemoryRegion *mem)
-{
-    memory_region_add_subregion(get_system_io(), addr, mem);
-}
-
-void sysbus_del_io(SysBusDevice *dev, MemoryRegion *mem)
-{
-    memory_region_del_subregion(get_system_io(), mem);
-}
diff --git a/hw/sysbus.h b/hw/sysbus.h
index b3e1f99..b87c6c5 100644
--- a/hw/sysbus.h
+++ b/hw/sysbus.h
@@ -57,14 +57,6 @@ void sysbus_init_ioports(SysBusDevice *dev, pio_addr_t ioport, pio_addr_t size);
 
 void sysbus_connect_irq(SysBusDevice *dev, int n, qemu_irq irq);
 void sysbus_mmio_map(SysBusDevice *dev, int n, target_phys_addr_t addr);
-void sysbus_add_memory(SysBusDevice *dev, target_phys_addr_t addr,
-                       MemoryRegion *mem);
-void sysbus_add_memory_overlap(SysBusDevice *dev, target_phys_addr_t addr,
-                               MemoryRegion *mem, unsigned priority);
-void sysbus_del_memory(SysBusDevice *dev, MemoryRegion *mem);
-void sysbus_add_io(SysBusDevice *dev, target_phys_addr_t addr,
-                   MemoryRegion *mem);
-void sysbus_del_io(SysBusDevice *dev, MemoryRegion *mem);
 
 /* Legacy helper function for creating devices.  */
 DeviceState *sysbus_create_varargs(const char *name,
diff --git a/hw/unin_pci.c b/hw/unin_pci.c
index 600cd1e..f896f8c 100644
--- a/hw/unin_pci.c
+++ b/hw/unin_pci.c
@@ -41,6 +41,7 @@ static const int unin_irq_line[] = { 0x1b, 0x1c, 0x1d, 0x1e };
 typedef struct UNINState {
     SysBusDevice busdev;
     PCIHostState host_state;
+    ReadWriteHandler data_handler;
 } UNINState;
 
 static int pci_unin_map_irq(PCIDevice *pci_dev, int irq_num)
@@ -99,70 +100,67 @@ static uint32_t unin_get_config_reg(uint32_t reg, uint32_t addr)
     return retval;
 }
 
-static void unin_data_write(void *opaque, target_phys_addr_t addr,
-                            uint64_t val, unsigned len)
+static void unin_data_write(ReadWriteHandler *handler,
+                            pcibus_t addr, uint32_t val, int len)
 {
-    UNINState *s = opaque;
-    UNIN_DPRINTF("write addr %" TARGET_FMT_plx " len %d val %"PRIx64"\n",
-                 addr, len, val);
+    UNINState *s = container_of(handler, UNINState, data_handler);
+    UNIN_DPRINTF("write addr %" FMT_PCIBUS " len %d val %x\n", addr, len, val);
     pci_data_write(s->host_state.bus,
                    unin_get_config_reg(s->host_state.config_reg, addr),
                    val, len);
 }
 
-static uint64_t unin_data_read(void *opaque, target_phys_addr_t addr,
-                               unsigned len)
+static uint32_t unin_data_read(ReadWriteHandler *handler,
+                               pcibus_t addr, int len)
 {
-    UNINState *s = opaque;
+    UNINState *s = container_of(handler, UNINState, data_handler);
     uint32_t val;
 
     val = pci_data_read(s->host_state.bus,
                         unin_get_config_reg(s->host_state.config_reg, addr),
                         len);
-    UNIN_DPRINTF("read addr %" TARGET_FMT_plx " len %d val %x\n",
-                 addr, len, val);
+    UNIN_DPRINTF("read addr %" FMT_PCIBUS " len %d val %x\n", addr, len, val);
     return val;
 }
 
-static const MemoryRegionOps unin_data_ops = {
-    .read = unin_data_read,
-    .write = unin_data_write,
-    .endianness = DEVICE_LITTLE_ENDIAN,
-};
-
 static int pci_unin_main_init_device(SysBusDevice *dev)
 {
     UNINState *s;
+    int pci_mem_config, pci_mem_data;
 
     /* Use values found on a real PowerMac */
     /* Uninorth main bus */
     s = FROM_SYSBUS(UNINState, dev);
 
-    memory_region_init_io(&s->host_state.conf_mem, &pci_host_conf_le_ops,
-                          &s->host_state, "pci-conf-idx", 0x1000);
-    memory_region_init_io(&s->host_state.data_mem, &unin_data_ops, s,
-                          "pci-conf-data", 0x1000);
-    sysbus_init_mmio_region(dev, &s->host_state.conf_mem);
-    sysbus_init_mmio_region(dev, &s->host_state.data_mem);
+    pci_mem_config = pci_host_conf_register_mmio(&s->host_state,
+                                                 DEVICE_LITTLE_ENDIAN);
+    s->data_handler.read = unin_data_read;
+    s->data_handler.write = unin_data_write;
+    pci_mem_data = cpu_register_io_memory_simple(&s->data_handler,
+                                                 DEVICE_LITTLE_ENDIAN);
+    sysbus_init_mmio(dev, 0x1000, pci_mem_config);
+    sysbus_init_mmio(dev, 0x1000, pci_mem_data);
 
     qemu_register_reset(pci_unin_reset, &s->host_state);
     return 0;
 }
 
-
 static int pci_u3_agp_init_device(SysBusDevice *dev)
 {
     UNINState *s;
+    int pci_mem_config, pci_mem_data;
 
     /* Uninorth U3 AGP bus */
     s = FROM_SYSBUS(UNINState, dev);
 
-    memory_region_init_io(&s->host_state.conf_mem, &pci_host_conf_le_ops,
-                          &s->host_state, "pci-conf-idx", 0x1000);
-    memory_region_init_io(&s->host_state.data_mem, &unin_data_ops, s,
-                          "pci-conf-data", 0x1000);
-    sysbus_init_mmio_region(dev, &s->host_state.conf_mem);
-    sysbus_init_mmio_region(dev, &s->host_state.data_mem);
+    pci_mem_config = pci_host_conf_register_mmio(&s->host_state,
+                                                 DEVICE_LITTLE_ENDIAN);
+    s->data_handler.read = unin_data_read;
+    s->data_handler.write = unin_data_write;
+    pci_mem_data = cpu_register_io_memory_simple(&s->data_handler,
+                                                 DEVICE_LITTLE_ENDIAN);
+    sysbus_init_mmio(dev, 0x1000, pci_mem_config);
+    sysbus_init_mmio(dev, 0x1000, pci_mem_data);
 
     qemu_register_reset(pci_unin_reset, &s->host_state);
 
@@ -172,32 +170,34 @@ static int pci_u3_agp_init_device(SysBusDevice *dev)
 static int pci_unin_agp_init_device(SysBusDevice *dev)
 {
     UNINState *s;
+    int pci_mem_config, pci_mem_data;
 
     /* Uninorth AGP bus */
     s = FROM_SYSBUS(UNINState, dev);
 
-    memory_region_init_io(&s->host_state.conf_mem, &pci_host_conf_le_ops,
-                          &s->host_state, "pci-conf-idx", 0x1000);
-    memory_region_init_io(&s->host_state.data_mem, &pci_host_data_le_ops,
-                          &s->host_state, "pci-conf-data", 0x1000);
-    sysbus_init_mmio_region(dev, &s->host_state.conf_mem);
-    sysbus_init_mmio_region(dev, &s->host_state.data_mem);
+    pci_mem_config = pci_host_conf_register_mmio(&s->host_state,
+                                                 DEVICE_LITTLE_ENDIAN);
+    pci_mem_data = pci_host_data_register_mmio(&s->host_state,
+                                               DEVICE_LITTLE_ENDIAN);
+    sysbus_init_mmio(dev, 0x1000, pci_mem_config);
+    sysbus_init_mmio(dev, 0x1000, pci_mem_data);
     return 0;
 }
 
 static int pci_unin_internal_init_device(SysBusDevice *dev)
 {
     UNINState *s;
+    int pci_mem_config, pci_mem_data;
 
     /* Uninorth internal bus */
     s = FROM_SYSBUS(UNINState, dev);
 
-    memory_region_init_io(&s->host_state.conf_mem, &pci_host_conf_le_ops,
-                          &s->host_state, "pci-conf-idx", 0x1000);
-    memory_region_init_io(&s->host_state.data_mem, &pci_host_data_le_ops,
-                          &s->host_state, "pci-conf-data", 0x1000);
-    sysbus_init_mmio_region(dev, &s->host_state.conf_mem);
-    sysbus_init_mmio_region(dev, &s->host_state.data_mem);
+    pci_mem_config = pci_host_conf_register_mmio(&s->host_state,
+                                                 DEVICE_LITTLE_ENDIAN);
+    pci_mem_data = pci_host_data_register_mmio(&s->host_state,
+                                               DEVICE_LITTLE_ENDIAN);
+    sysbus_init_mmio(dev, 0x1000, pci_mem_config);
+    sysbus_init_mmio(dev, 0x1000, pci_mem_data);
     return 0;
 }
 
diff --git a/hw/virtex_ml507.c b/hw/virtex_ml507.c
index aa9e512..333050c 100644
--- a/hw/virtex_ml507.c
+++ b/hw/virtex_ml507.c
@@ -196,7 +196,7 @@ static void virtex_init(ram_addr_t ram_size,
     target_phys_addr_t ram_base = 0;
     DriveInfo *dinfo;
     ram_addr_t phys_ram;
-    MemoryRegion *phys_flash = g_new(MemoryRegion, 1);
+    ram_addr_t phys_flash;
     qemu_irq irq[32], *cpu_irq;
     clk_setup_t clk_setup[7];
     int kernel_size;
@@ -215,13 +215,12 @@ static void virtex_init(ram_addr_t ram_size,
     phys_ram = qemu_ram_alloc(NULL, "ram", ram_size);
     cpu_register_physical_memory(ram_base, ram_size, phys_ram | IO_MEM_RAM);
 
-    memory_region_init_rom_device(phys_flash, &pflash_cfi01_ops_be,
-                                  NULL, "virtex.flash", FLASH_SIZE);
+    phys_flash = qemu_ram_alloc(NULL, "virtex.flash", FLASH_SIZE);
     dinfo = drive_get(IF_PFLASH, 0, 0);
     pflash_cfi01_register(0xfc000000, phys_flash,
                           dinfo ? dinfo->bdrv : NULL, (64 * 1024),
                           FLASH_SIZE >> 16,
-                          1, 0x89, 0x18, 0x0000, 0x0);
+                          1, 0x89, 0x18, 0x0000, 0x0, 1);
 
     cpu_irq = (qemu_irq *) &env->irq_inputs[PPC40x_INPUT_INT];
     dev = xilinx_intc_create(0x81800000, cpu_irq[0], 0);
diff --git a/hw/z2.c b/hw/z2.c
index d7b8d53..f93a1bf 100644
--- a/hw/z2.c
+++ b/hw/z2.c
@@ -280,11 +280,10 @@ static void z2_init(ram_addr_t ram_size,
     uint32_t sector_len = 0x10000;
     PXA2xxState *cpu;
     DriveInfo *dinfo;
-    const MemoryRegionOps *flash_ops;
+    int be;
     void *z2_lcd;
     i2c_bus *bus;
     DeviceState *wm;
-    MemoryRegion *flash = g_new(MemoryRegion, 1);
 
     if (!cpu_model) {
         cpu_model = "pxa270-c5";
@@ -294,9 +293,9 @@ static void z2_init(ram_addr_t ram_size,
     cpu = pxa270_init(z2_binfo.ram_size, cpu_model);
 
 #ifdef TARGET_WORDS_BIGENDIAN
-    flash_ops = &pflash_cfi01_ops_be;
+    be = 1;
 #else
-    flash_ops = &pflash_cfi01_ops_le;
+    be = 0;
 #endif
     dinfo = drive_get(IF_PFLASH, 0, 0);
     if (!dinfo) {
@@ -305,11 +304,11 @@ static void z2_init(ram_addr_t ram_size,
         exit(1);
     }
 
-    memory_region_init_rom_device(flash, flash_ops,
-                                  NULL, "z2.flash0", Z2_FLASH_SIZE);
-    if (!pflash_cfi01_register(Z2_FLASH_BASE, flash,
+    if (!pflash_cfi01_register(Z2_FLASH_BASE,
+                               qemu_ram_alloc(NULL, "z2.flash0", Z2_FLASH_SIZE),
                                dinfo->bdrv, sector_len,
-                               Z2_FLASH_SIZE / sector_len, 4, 0, 0, 0, 0)) {
+                               Z2_FLASH_SIZE / sector_len, 4, 0, 0, 0, 0,
+                               be)) {
         fprintf(stderr, "qemu: Error registering flash memory.\n");
         exit(1);
     }
diff --git a/rwhandler.c b/rwhandler.c
new file mode 100644
index 0000000..bb2238f
--- /dev/null
+++ b/rwhandler.c
@@ -0,0 +1,87 @@
+#include "rwhandler.h"
+#include "ioport.h"
+#include "cpu-all.h"
+
+#define RWHANDLER_WRITE(name, len, type) \
+static void name(void *opaque, type addr, uint32_t value) \
+{\
+    struct ReadWriteHandler *handler = opaque;\
+    handler->write(handler, addr, value, len);\
+}
+
+#define RWHANDLER_READ(name, len, type) \
+static uint32_t name(void *opaque, type addr) \
+{ \
+    struct ReadWriteHandler *handler = opaque; \
+    return handler->read(handler, addr, len); \
+}
+
+RWHANDLER_WRITE(cpu_io_memory_simple_writeb, 1, target_phys_addr_t);
+RWHANDLER_READ(cpu_io_memory_simple_readb, 1, target_phys_addr_t);
+RWHANDLER_WRITE(cpu_io_memory_simple_writew, 2, target_phys_addr_t);
+RWHANDLER_READ(cpu_io_memory_simple_readw, 2, target_phys_addr_t);
+RWHANDLER_WRITE(cpu_io_memory_simple_writel, 4, target_phys_addr_t);
+RWHANDLER_READ(cpu_io_memory_simple_readl, 4, target_phys_addr_t);
+
+static CPUWriteMemoryFunc * const cpu_io_memory_simple_write[] = {
+    &cpu_io_memory_simple_writeb,
+    &cpu_io_memory_simple_writew,
+    &cpu_io_memory_simple_writel,
+};
+
+static CPUReadMemoryFunc * const cpu_io_memory_simple_read[] = {
+    &cpu_io_memory_simple_readb,
+    &cpu_io_memory_simple_readw,
+    &cpu_io_memory_simple_readl,
+};
+
+int cpu_register_io_memory_simple(struct ReadWriteHandler *handler, int endian)
+{
+    if (!handler->read || !handler->write) {
+        return -1;
+    }
+    return cpu_register_io_memory(cpu_io_memory_simple_read,
+                                  cpu_io_memory_simple_write,
+                                  handler, endian);
+}
+
+RWHANDLER_WRITE(ioport_simple_writeb, 1, uint32_t);
+RWHANDLER_READ(ioport_simple_readb, 1, uint32_t);
+RWHANDLER_WRITE(ioport_simple_writew, 2, uint32_t);
+RWHANDLER_READ(ioport_simple_readw, 2, uint32_t);
+RWHANDLER_WRITE(ioport_simple_writel, 4, uint32_t);
+RWHANDLER_READ(ioport_simple_readl, 4, uint32_t);
+
+int register_ioport_simple(ReadWriteHandler* handler,
+                           pio_addr_t start, int length, int size)
+{
+    IOPortWriteFunc *write;
+    IOPortReadFunc *read;
+    int r;
+    switch (size) {
+    case 1:
+        write = ioport_simple_writeb;
+        read = ioport_simple_readb;
+        break;
+    case 2:
+        write = ioport_simple_writew;
+        read = ioport_simple_readw;
+        break;
+    default:
+        write = ioport_simple_writel;
+        read = ioport_simple_readl;
+    }
+    if (handler->write) {
+        r = register_ioport_write(start, length, size, write, handler);
+        if (r < 0) {
+            return r;
+        }
+    }
+    if (handler->read) {
+        r = register_ioport_read(start, length, size, read, handler);
+        if (r < 0) {
+            return r;
+        }
+    }
+    return 0;
+}
diff --git a/rwhandler.h b/rwhandler.h
new file mode 100644
index 0000000..b2a5790
--- /dev/null
+++ b/rwhandler.h
@@ -0,0 +1,27 @@
+#ifndef READ_WRITE_HANDLER_H
+#define READ_WRITE_HANDLER_H
+
+#include "qemu-common.h"
+#include "ioport.h"
+
+typedef struct ReadWriteHandler ReadWriteHandler;
+
+/* len is guaranteed to be one of 1, 2 or 4, addr is guaranteed to fit in an
+ * appropriate type (io/memory/etc). They do not need to be range checked. */
+typedef void WriteHandlerFunc(ReadWriteHandler *, pcibus_t addr,
+                              uint32_t value, int len);
+typedef uint32_t ReadHandlerFunc(ReadWriteHandler *, pcibus_t addr, int len);
+
+struct ReadWriteHandler {
+    WriteHandlerFunc *write;
+    ReadHandlerFunc *read;
+};
+
+/* Helpers for when we want to use a single routine with length. */
+/* CPU memory handler: both read and write must be present. */
+int cpu_register_io_memory_simple(ReadWriteHandler *, int endian);
+/* io port handler: can supply only read or write handlers. */
+int register_ioport_simple(ReadWriteHandler *,
+                           pio_addr_t start, int length, int size);
+
+#endif
commit f065aa0a005ac539bf8ca556775e5cc4c3d2d3b7
Author: Jan Kiszka <jan.kiszka at siemens.com>
Date:   Thu Aug 25 11:10:13 2011 +0200

    vga: Silence bogus gcc warning about uninitialized variables
    
    Some gcc versions do not properly detect that all possible cases are
    covered and base and size are always initialized. Please gcc by defining
    a pseudo default case.
    
    Signed-off-by: Jan Kiszka <jan.kiszka at siemens.com>
    Signed-off-by: Anthony Liguori <aliguori at us.ibm.com>

diff --git a/hw/vga.c b/hw/vga.c
index 851fd68..125fb29 100644
--- a/hw/vga.c
+++ b/hw/vga.c
@@ -176,6 +176,7 @@ static void vga_update_memory_access(VGACommonState *s)
             size = 0x8000;
             break;
         case 3:
+        default:
             base = 0xb8000;
             size = 0x8000;
             break;
commit a597e79ce14ea62266924acc7b8a7030a42ed29b
Author: Christoph Hellwig <hch at lst.de>
Date:   Thu Aug 25 08:26:01 2011 +0200

    block: explicit I/O accounting
    
    Decouple the I/O accounting from bdrv_aio_readv/writev/flush and
    make the hardware models call directly into the accounting helpers.
    
    This means:
     - we do not count internal requests from image formats in addition
       to guest originating I/O
     - we do not double count I/O ops if the device model handles it
       chunk wise
     - we only account I/O once it actuall is done
     - can extent I/O accounting to synchronous or coroutine I/O easily
     - implement I/O latency tracking easily (see the next patch)
    
    I've conveted the existing device model callers to the new model,
    device models that are using synchronous I/O and weren't accounted
    before haven't been updated yet.  Also scsi hasn't been converted
    to the end-to-end accounting as I want to defer that after the pending
    scsi layer overhaul.
    
    Signed-off-by: Christoph Hellwig <hch at lst.de>
    Signed-off-by: Kevin Wolf <kwolf at redhat.com>

diff --git a/block.c b/block.c
index 0f256f5..24fba37 100644
--- a/block.c
+++ b/block.c
@@ -1942,13 +1942,13 @@ static QObject* bdrv_info_stats_bs(BlockDriverState *bs)
                              "'wr_highest_offset': %" PRId64 ","
                              "'flush_operations': %" PRId64
                              "} }",
-                             bs->rd_bytes,
-                             bs->wr_bytes,
-                             bs->rd_ops,
-                             bs->wr_ops,
+                             bs->nr_bytes[BDRV_ACCT_READ],
+                             bs->nr_bytes[BDRV_ACCT_WRITE],
+                             bs->nr_ops[BDRV_ACCT_READ],
+                             bs->nr_ops[BDRV_ACCT_WRITE],
                              bs->wr_highest_sector *
                              (uint64_t)BDRV_SECTOR_SIZE,
-                             bs->flush_ops);
+                             bs->nr_ops[BDRV_ACCT_FLUSH]);
     dict  = qobject_to_qdict(res);
 
     if (*bs->device_name) {
@@ -2262,7 +2262,6 @@ char *bdrv_snapshot_dump(char *buf, int buf_size, QEMUSnapshotInfo *sn)
     return buf;
 }
 
-
 /**************************************************************/
 /* async I/Os */
 
@@ -2271,7 +2270,6 @@ BlockDriverAIOCB *bdrv_aio_readv(BlockDriverState *bs, int64_t sector_num,
                                  BlockDriverCompletionFunc *cb, void *opaque)
 {
     BlockDriver *drv = bs->drv;
-    BlockDriverAIOCB *ret;
 
     trace_bdrv_aio_readv(bs, sector_num, nb_sectors, opaque);
 
@@ -2280,16 +2278,8 @@ BlockDriverAIOCB *bdrv_aio_readv(BlockDriverState *bs, int64_t sector_num,
     if (bdrv_check_request(bs, sector_num, nb_sectors))
         return NULL;
 
-    ret = drv->bdrv_aio_readv(bs, sector_num, qiov, nb_sectors,
-                              cb, opaque);
-
-    if (ret) {
-        /* Update stats even though technically transfer has not happened. */
-        bs->rd_bytes += (unsigned) nb_sectors * BDRV_SECTOR_SIZE;
-        bs->rd_ops++;
-    }
-
-    return ret;
+    return drv->bdrv_aio_readv(bs, sector_num, qiov, nb_sectors,
+                               cb, opaque);
 }
 
 typedef struct BlockCompleteData {
@@ -2356,9 +2346,6 @@ BlockDriverAIOCB *bdrv_aio_writev(BlockDriverState *bs, int64_t sector_num,
                                cb, opaque);
 
     if (ret) {
-        /* Update stats even though technically transfer has not happened. */
-        bs->wr_bytes += (unsigned) nb_sectors * BDRV_SECTOR_SIZE;
-        bs->wr_ops ++;
         if (bs->wr_highest_sector < sector_num + nb_sectors - 1) {
             bs->wr_highest_sector = sector_num + nb_sectors - 1;
         }
@@ -2612,8 +2599,6 @@ BlockDriverAIOCB *bdrv_aio_flush(BlockDriverState *bs,
 
     trace_bdrv_aio_flush(bs, opaque);
 
-    bs->flush_ops++;
-
     if (bs->open_flags & BDRV_O_NO_FLUSH) {
         return bdrv_aio_noop_em(bs, cb, opaque);
     }
@@ -3168,6 +3153,25 @@ int bdrv_in_use(BlockDriverState *bs)
     return bs->in_use;
 }
 
+void
+bdrv_acct_start(BlockDriverState *bs, BlockAcctCookie *cookie, int64_t bytes,
+        enum BlockAcctType type)
+{
+    assert(type < BDRV_MAX_IOTYPE);
+
+    cookie->bytes = bytes;
+    cookie->type = type;
+}
+
+void
+bdrv_acct_done(BlockDriverState *bs, BlockAcctCookie *cookie)
+{
+    assert(cookie->type < BDRV_MAX_IOTYPE);
+
+    bs->nr_bytes[cookie->type] += cookie->bytes;
+    bs->nr_ops[cookie->type]++;
+}
+
 int bdrv_img_create(const char *filename, const char *fmt,
                     const char *base_filename, const char *base_fmt,
                     char *options, uint64_t img_size, int flags)
diff --git a/block.h b/block.h
index c7b5128..df06af5 100644
--- a/block.h
+++ b/block.h
@@ -255,6 +255,22 @@ int64_t bdrv_get_dirty_count(BlockDriverState *bs);
 void bdrv_set_in_use(BlockDriverState *bs, int in_use);
 int bdrv_in_use(BlockDriverState *bs);
 
+enum BlockAcctType {
+    BDRV_ACCT_READ,
+    BDRV_ACCT_WRITE,
+    BDRV_ACCT_FLUSH,
+    BDRV_MAX_IOTYPE,
+};
+
+typedef struct BlockAcctCookie {
+    int64_t bytes;
+    enum BlockAcctType type;
+} BlockAcctCookie;
+
+void bdrv_acct_start(BlockDriverState *bs, BlockAcctCookie *cookie,
+        int64_t bytes, enum BlockAcctType type);
+void bdrv_acct_done(BlockDriverState *bs, BlockAcctCookie *cookie);
+
 typedef enum {
     BLKDBG_L1_UPDATE,
 
@@ -307,3 +323,4 @@ typedef enum {
 void bdrv_debug_event(BlockDriverState *bs, BlkDebugEvent event);
 
 #endif
+
diff --git a/block_int.h b/block_int.h
index f1480d6..5f8050d 100644
--- a/block_int.h
+++ b/block_int.h
@@ -184,11 +184,8 @@ struct BlockDriverState {
     void *sync_aiocb;
 
     /* I/O stats (display with "info blockstats"). */
-    uint64_t rd_bytes;
-    uint64_t wr_bytes;
-    uint64_t rd_ops;
-    uint64_t wr_ops;
-    uint64_t flush_ops;
+    uint64_t nr_bytes[BDRV_MAX_IOTYPE];
+    uint64_t nr_ops[BDRV_MAX_IOTYPE];
     uint64_t wr_highest_sector;
 
     /* Whether the disk can expand beyond total_sectors */
diff --git a/hw/ide/ahci.c b/hw/ide/ahci.c
index 29521ba..f4fa154 100644
--- a/hw/ide/ahci.c
+++ b/hw/ide/ahci.c
@@ -710,6 +710,7 @@ static void ncq_cb(void *opaque, int ret)
     DPRINTF(ncq_tfs->drive->port_no, "NCQ transfer tag %d finished\n",
             ncq_tfs->tag);
 
+    bdrv_acct_done(ncq_tfs->drive->port.ifs[0].bs, &ncq_tfs->acct);
     qemu_sglist_destroy(&ncq_tfs->sglist);
     ncq_tfs->used = 0;
 }
@@ -756,6 +757,10 @@ static void process_ncq_command(AHCIState *s, int port, uint8_t *cmd_fis,
             ncq_tfs->is_read = 1;
 
             DPRINTF(port, "tag %d aio read %ld\n", ncq_tfs->tag, ncq_tfs->lba);
+
+            bdrv_acct_start(ncq_tfs->drive->port.ifs[0].bs, &ncq_tfs->acct,
+                            (ncq_tfs->sector_count-1) * BDRV_SECTOR_SIZE,
+                            BDRV_ACCT_READ);
             ncq_tfs->aiocb = dma_bdrv_read(ncq_tfs->drive->port.ifs[0].bs,
                                            &ncq_tfs->sglist, ncq_tfs->lba,
                                            ncq_cb, ncq_tfs);
@@ -766,6 +771,10 @@ static void process_ncq_command(AHCIState *s, int port, uint8_t *cmd_fis,
             ncq_tfs->is_read = 0;
 
             DPRINTF(port, "tag %d aio write %ld\n", ncq_tfs->tag, ncq_tfs->lba);
+
+            bdrv_acct_start(ncq_tfs->drive->port.ifs[0].bs, &ncq_tfs->acct,
+                            (ncq_tfs->sector_count-1) * BDRV_SECTOR_SIZE,
+                            BDRV_ACCT_WRITE);
             ncq_tfs->aiocb = dma_bdrv_write(ncq_tfs->drive->port.ifs[0].bs,
                                             &ncq_tfs->sglist, ncq_tfs->lba,
                                             ncq_cb, ncq_tfs);
diff --git a/hw/ide/ahci.h b/hw/ide/ahci.h
index e456193..832539c 100644
--- a/hw/ide/ahci.h
+++ b/hw/ide/ahci.h
@@ -258,6 +258,7 @@ typedef struct NCQTransferState {
     AHCIDevice *drive;
     BlockDriverAIOCB *aiocb;
     QEMUSGList sglist;
+    BlockAcctCookie acct;
     int is_read;
     uint16_t sector_count;
     uint64_t lba;
diff --git a/hw/ide/atapi.c b/hw/ide/atapi.c
index fe2fb0b..c552320 100644
--- a/hw/ide/atapi.c
+++ b/hw/ide/atapi.c
@@ -104,17 +104,20 @@ static void cd_data_to_raw(uint8_t *buf, int lba)
     memset(buf, 0, 288);
 }
 
-static int cd_read_sector(BlockDriverState *bs, int lba, uint8_t *buf,
-                           int sector_size)
+static int cd_read_sector(IDEState *s, int lba, uint8_t *buf, int sector_size)
 {
     int ret;
 
     switch(sector_size) {
     case 2048:
-        ret = bdrv_read(bs, (int64_t)lba << 2, buf, 4);
+        bdrv_acct_start(s->bs, &s->acct, 4 * BDRV_SECTOR_SIZE, BDRV_ACCT_READ);
+        ret = bdrv_read(s->bs, (int64_t)lba << 2, buf, 4);
+        bdrv_acct_done(s->bs, &s->acct);
         break;
     case 2352:
-        ret = bdrv_read(bs, (int64_t)lba << 2, buf + 16, 4);
+        bdrv_acct_start(s->bs, &s->acct, 4 * BDRV_SECTOR_SIZE, BDRV_ACCT_READ);
+        ret = bdrv_read(s->bs, (int64_t)lba << 2, buf + 16, 4);
+        bdrv_acct_done(s->bs, &s->acct);
         if (ret < 0)
             return ret;
         cd_data_to_raw(buf, lba);
@@ -181,7 +184,7 @@ void ide_atapi_cmd_reply_end(IDEState *s)
     } else {
         /* see if a new sector must be read */
         if (s->lba != -1 && s->io_buffer_index >= s->cd_sector_size) {
-            ret = cd_read_sector(s->bs, s->lba, s->io_buffer, s->cd_sector_size);
+            ret = cd_read_sector(s, s->lba, s->io_buffer, s->cd_sector_size);
             if (ret < 0) {
                 ide_transfer_stop(s);
                 ide_atapi_io_error(s, ret);
@@ -250,6 +253,7 @@ static void ide_atapi_cmd_reply(IDEState *s, int size, int max_size)
     s->io_buffer_index = 0;
 
     if (s->atapi_dma) {
+        bdrv_acct_start(s->bs, &s->acct, size, BDRV_ACCT_READ);
         s->status = READY_STAT | SEEK_STAT | DRQ_STAT;
         s->bus->dma->ops->start_dma(s->bus->dma, s,
                                    ide_atapi_cmd_read_dma_cb);
@@ -322,10 +326,7 @@ static void ide_atapi_cmd_read_dma_cb(void *opaque, int ret)
         s->status = READY_STAT | SEEK_STAT;
         s->nsector = (s->nsector & ~7) | ATAPI_INT_REASON_IO | ATAPI_INT_REASON_CD;
         ide_set_irq(s->bus);
-    eot:
-        s->bus->dma->ops->add_status(s->bus->dma, BM_STATUS_INT);
-        ide_set_inactive(s);
-        return;
+        goto eot;
     }
 
     s->io_buffer_index = 0;
@@ -343,9 +344,11 @@ static void ide_atapi_cmd_read_dma_cb(void *opaque, int ret)
 #ifdef DEBUG_AIO
     printf("aio_read_cd: lba=%u n=%d\n", s->lba, n);
 #endif
+
     s->bus->dma->iov.iov_base = (void *)(s->io_buffer + data_offset);
     s->bus->dma->iov.iov_len = n * 4 * 512;
     qemu_iovec_init_external(&s->bus->dma->qiov, &s->bus->dma->iov, 1);
+
     s->bus->dma->aiocb = bdrv_aio_readv(s->bs, (int64_t)s->lba << 2,
                                        &s->bus->dma->qiov, n * 4,
                                        ide_atapi_cmd_read_dma_cb, s);
@@ -355,6 +358,12 @@ static void ide_atapi_cmd_read_dma_cb(void *opaque, int ret)
                             ASC_MEDIUM_NOT_PRESENT);
         goto eot;
     }
+
+    return;
+eot:
+    bdrv_acct_done(s->bs, &s->acct);
+    s->bus->dma->ops->add_status(s->bus->dma, BM_STATUS_INT);
+    ide_set_inactive(s);
 }
 
 /* start a CD-CDROM read command with DMA */
@@ -368,6 +377,8 @@ static void ide_atapi_cmd_read_dma(IDEState *s, int lba, int nb_sectors,
     s->io_buffer_size = 0;
     s->cd_sector_size = sector_size;
 
+    bdrv_acct_start(s->bs, &s->acct, s->packet_transfer_size, BDRV_ACCT_READ);
+
     /* XXX: check if BUSY_STAT should be set */
     s->status = READY_STAT | SEEK_STAT | DRQ_STAT | BUSY_STAT;
     s->bus->dma->ops->start_dma(s->bus->dma, s,
diff --git a/hw/ide/core.c b/hw/ide/core.c
index d145b19..40abc1e 100644
--- a/hw/ide/core.c
+++ b/hw/ide/core.c
@@ -473,7 +473,10 @@ void ide_sector_read(IDEState *s)
 #endif
         if (n > s->req_nb_sectors)
             n = s->req_nb_sectors;
+
+        bdrv_acct_start(s->bs, &s->acct, n * BDRV_SECTOR_SIZE, BDRV_ACCT_READ);
         ret = bdrv_read(s->bs, sector_num, s->io_buffer, n);
+        bdrv_acct_done(s->bs, &s->acct);
         if (ret != 0) {
             if (ide_handle_rw_error(s, -ret,
                 BM_STATUS_PIO_RETRY | BM_STATUS_RETRY_READ))
@@ -610,7 +613,10 @@ handle_rw_error:
     return;
 
 eot:
-   ide_set_inactive(s);
+    if (s->dma_cmd == IDE_DMA_READ || s->dma_cmd == IDE_DMA_WRITE) {
+        bdrv_acct_done(s->bs, &s->acct);
+    }
+    ide_set_inactive(s);
 }
 
 static void ide_sector_start_dma(IDEState *s, enum ide_dma_cmd dma_cmd)
@@ -619,6 +625,20 @@ static void ide_sector_start_dma(IDEState *s, enum ide_dma_cmd dma_cmd)
     s->io_buffer_index = 0;
     s->io_buffer_size = 0;
     s->dma_cmd = dma_cmd;
+
+    switch (dma_cmd) {
+    case IDE_DMA_READ:
+        bdrv_acct_start(s->bs, &s->acct, s->nsector * BDRV_SECTOR_SIZE,
+                        BDRV_ACCT_READ);
+        break;
+    case IDE_DMA_WRITE:
+        bdrv_acct_start(s->bs, &s->acct, s->nsector * BDRV_SECTOR_SIZE,
+                        BDRV_ACCT_WRITE);
+        break;
+    default:
+        break;
+    }
+
     s->bus->dma->ops->start_dma(s->bus->dma, s, ide_dma_cb);
 }
 
@@ -641,7 +661,10 @@ void ide_sector_write(IDEState *s)
     n = s->nsector;
     if (n > s->req_nb_sectors)
         n = s->req_nb_sectors;
+
+    bdrv_acct_start(s->bs, &s->acct, n * BDRV_SECTOR_SIZE, BDRV_ACCT_READ);
     ret = bdrv_write(s->bs, sector_num, s->io_buffer, n);
+    bdrv_acct_done(s->bs, &s->acct);
 
     if (ret != 0) {
         if (ide_handle_rw_error(s, -ret, BM_STATUS_PIO_RETRY))
@@ -685,6 +708,7 @@ static void ide_flush_cb(void *opaque, int ret)
         }
     }
 
+    bdrv_acct_done(s->bs, &s->acct);
     s->status = READY_STAT | SEEK_STAT;
     ide_set_irq(s->bus);
 }
@@ -698,6 +722,7 @@ void ide_flush_cache(IDEState *s)
         return;
     }
 
+    bdrv_acct_start(s->bs, &s->acct, 0, BDRV_ACCT_FLUSH);
     acb = bdrv_aio_flush(s->bs, ide_flush_cb, s);
     if (acb == NULL) {
         ide_flush_cb(s, -EIO);
diff --git a/hw/ide/internal.h b/hw/ide/internal.h
index 02e805f..7f5ef8d 100644
--- a/hw/ide/internal.h
+++ b/hw/ide/internal.h
@@ -440,6 +440,7 @@ struct IDEState {
     int lba;
     int cd_sector_size;
     int atapi_dma; /* true if dma is requested for the packet cmd */
+    BlockAcctCookie acct;
     /* ATA DMA state */
     int io_buffer_size;
     QEMUSGList sg;
diff --git a/hw/ide/macio.c b/hw/ide/macio.c
index 44fb3fe..fdf5d75 100644
--- a/hw/ide/macio.c
+++ b/hw/ide/macio.c
@@ -52,8 +52,7 @@ static void pmac_ide_atapi_transfer_cb(void *opaque, int ret)
         m->aiocb = NULL;
         qemu_sglist_destroy(&s->sg);
         ide_atapi_io_error(s, ret);
-        io->dma_end(opaque);
-        return;
+        goto done;
     }
 
     if (s->io_buffer_size > 0) {
@@ -71,8 +70,7 @@ static void pmac_ide_atapi_transfer_cb(void *opaque, int ret)
         ide_atapi_cmd_ok(s);
 
     if (io->len == 0) {
-        io->dma_end(opaque);
-        return;
+        goto done;
     }
 
     /* launch next transfer */
@@ -92,9 +90,14 @@ static void pmac_ide_atapi_transfer_cb(void *opaque, int ret)
         /* Note: media not present is the most likely case */
         ide_atapi_cmd_error(s, SENSE_NOT_READY,
                             ASC_MEDIUM_NOT_PRESENT);
-        io->dma_end(opaque);
-        return;
+        goto done;
     }
+    return;
+
+done:
+    bdrv_acct_done(s->bs, &s->acct);
+    io->dma_end(opaque);
+    return;
 }
 
 static void pmac_ide_transfer_cb(void *opaque, int ret)
@@ -109,8 +112,7 @@ static void pmac_ide_transfer_cb(void *opaque, int ret)
         m->aiocb = NULL;
         qemu_sglist_destroy(&s->sg);
 	ide_dma_error(s);
-        io->dma_end(io);
-        return;
+        goto done;
     }
 
     sector_num = ide_get_sector(s);
@@ -130,10 +132,8 @@ static void pmac_ide_transfer_cb(void *opaque, int ret)
     }
 
     /* end of DMA ? */
-
     if (io->len == 0) {
-        io->dma_end(io);
-	return;
+        goto done;
     }
 
     /* launch next transfer */
@@ -163,6 +163,12 @@ static void pmac_ide_transfer_cb(void *opaque, int ret)
 
     if (!m->aiocb)
         pmac_ide_transfer_cb(io, -1);
+    return;
+done:
+    if (s->dma_cmd == IDE_DMA_READ || s->dma_cmd == IDE_DMA_WRITE) {
+        bdrv_acct_done(s->bs, &s->acct);
+    }
+    io->dma_end(io);
 }
 
 static void pmac_ide_transfer(DBDMA_io *io)
@@ -172,10 +178,22 @@ static void pmac_ide_transfer(DBDMA_io *io)
 
     s->io_buffer_size = 0;
     if (s->drive_kind == IDE_CD) {
+        bdrv_acct_start(s->bs, &s->acct, io->len, BDRV_ACCT_READ);
         pmac_ide_atapi_transfer_cb(io, 0);
         return;
     }
 
+    switch (s->dma_cmd) {
+    case IDE_DMA_READ:
+        bdrv_acct_start(s->bs, &s->acct, io->len, BDRV_ACCT_READ);
+        break;
+    case IDE_DMA_WRITE:
+        bdrv_acct_start(s->bs, &s->acct, io->len, BDRV_ACCT_WRITE);
+        break;
+    default:
+        break;
+    }
+
     pmac_ide_transfer_cb(io, 0);
 }
 
diff --git a/hw/scsi-disk.c b/hw/scsi-disk.c
index d94b1eb..3cc830f 100644
--- a/hw/scsi-disk.c
+++ b/hw/scsi-disk.c
@@ -57,6 +57,7 @@ typedef struct SCSIDiskReq {
     struct iovec iov;
     QEMUIOVector qiov;
     uint32_t status;
+    BlockAcctCookie acct;
 } SCSIDiskReq;
 
 struct SCSIDiskState
@@ -107,10 +108,13 @@ static void scsi_cancel_io(SCSIRequest *req)
 static void scsi_read_complete(void * opaque, int ret)
 {
     SCSIDiskReq *r = (SCSIDiskReq *)opaque;
+    SCSIDiskState *s = DO_UPCAST(SCSIDiskState, qdev, r->req.dev);
     int n;
 
     r->req.aiocb = NULL;
 
+    bdrv_acct_done(s->bs, &r->acct);
+
     if (ret) {
         if (scsi_handle_rw_error(r, -ret, SCSI_REQ_STATUS_RETRY_READ)) {
             return;
@@ -161,6 +165,8 @@ static void scsi_read_data(SCSIRequest *req)
 
     r->iov.iov_len = n * 512;
     qemu_iovec_init_external(&r->qiov, &r->iov, 1);
+
+    bdrv_acct_start(s->bs, &r->acct, n * BDRV_SECTOR_SIZE, BDRV_ACCT_READ);
     r->req.aiocb = bdrv_aio_readv(s->bs, r->sector, &r->qiov, n,
                               scsi_read_complete, r);
     if (r->req.aiocb == NULL) {
@@ -207,11 +213,14 @@ static int scsi_handle_rw_error(SCSIDiskReq *r, int error, int type)
 static void scsi_write_complete(void * opaque, int ret)
 {
     SCSIDiskReq *r = (SCSIDiskReq *)opaque;
+    SCSIDiskState *s = DO_UPCAST(SCSIDiskState, qdev, r->req.dev);
     uint32_t len;
     uint32_t n;
 
     r->req.aiocb = NULL;
 
+    bdrv_acct_done(s->bs, &r->acct);
+
     if (ret) {
         if (scsi_handle_rw_error(r, -ret, SCSI_REQ_STATUS_RETRY_WRITE)) {
             return;
@@ -252,6 +261,8 @@ static void scsi_write_data(SCSIRequest *req)
     n = r->iov.iov_len / 512;
     if (n) {
         qemu_iovec_init_external(&r->qiov, &r->iov, 1);
+
+        bdrv_acct_start(s->bs, &r->acct, n * BDRV_SECTOR_SIZE, BDRV_ACCT_WRITE);
         r->req.aiocb = bdrv_aio_writev(s->bs, r->sector, &r->qiov, n,
                                    scsi_write_complete, r);
         if (r->req.aiocb == NULL) {
@@ -854,13 +865,19 @@ static int scsi_disk_emulate_command(SCSIDiskReq *r, uint8_t *outbuf)
         buflen = 8;
         break;
     case SYNCHRONIZE_CACHE:
+    {
+        BlockAcctCookie acct;
+
+        bdrv_acct_start(s->bs, &acct, 0, BDRV_ACCT_FLUSH);
         ret = bdrv_flush(s->bs);
+        bdrv_acct_done(s->bs, &acct);
         if (ret < 0) {
             if (scsi_handle_rw_error(r, -ret, SCSI_REQ_STATUS_RETRY_FLUSH)) {
                 return -1;
             }
         }
         break;
+    }
     case GET_CONFIGURATION:
         memset(outbuf, 0, 8);
         /* ??? This should probably return much more information.  For now
diff --git a/hw/virtio-blk.c b/hw/virtio-blk.c
index dad8c0a..2a8ccd0 100644
--- a/hw/virtio-blk.c
+++ b/hw/virtio-blk.c
@@ -47,6 +47,7 @@ typedef struct VirtIOBlockReq
     struct virtio_scsi_inhdr *scsi;
     QEMUIOVector qiov;
     struct VirtIOBlockReq *next;
+    BlockAcctCookie acct;
 } VirtIOBlockReq;
 
 static void virtio_blk_req_complete(VirtIOBlockReq *req, int status)
@@ -58,8 +59,6 @@ static void virtio_blk_req_complete(VirtIOBlockReq *req, int status)
     stb_p(&req->in->status, status);
     virtqueue_push(s->vq, &req->elem, req->qiov.size + sizeof(*req->in));
     virtio_notify(&s->vdev, s->vq);
-
-    g_free(req);
 }
 
 static int virtio_blk_handle_rw_error(VirtIOBlockReq *req, int error,
@@ -81,6 +80,8 @@ static int virtio_blk_handle_rw_error(VirtIOBlockReq *req, int error,
         vm_stop(VMSTOP_DISKFULL);
     } else {
         virtio_blk_req_complete(req, VIRTIO_BLK_S_IOERR);
+        bdrv_acct_done(s->bs, &req->acct);
+        g_free(req);
         bdrv_mon_event(s->bs, BDRV_ACTION_REPORT, is_read);
     }
 
@@ -100,6 +101,8 @@ static void virtio_blk_rw_complete(void *opaque, int ret)
     }
 
     virtio_blk_req_complete(req, VIRTIO_BLK_S_OK);
+    bdrv_acct_done(req->dev->bs, &req->acct);
+    g_free(req);
 }
 
 static void virtio_blk_flush_complete(void *opaque, int ret)
@@ -113,6 +116,8 @@ static void virtio_blk_flush_complete(void *opaque, int ret)
     }
 
     virtio_blk_req_complete(req, VIRTIO_BLK_S_OK);
+    bdrv_acct_done(req->dev->bs, &req->acct);
+    g_free(req);
 }
 
 static VirtIOBlockReq *virtio_blk_alloc_request(VirtIOBlock *s)
@@ -155,6 +160,7 @@ static void virtio_blk_handle_scsi(VirtIOBlockReq *req)
      */
     if (req->elem.out_num < 2 || req->elem.in_num < 3) {
         virtio_blk_req_complete(req, VIRTIO_BLK_S_IOERR);
+        g_free(req);
         return;
     }
 
@@ -163,6 +169,7 @@ static void virtio_blk_handle_scsi(VirtIOBlockReq *req)
      */
     if (req->elem.out_num > 2 && req->elem.in_num > 3) {
         virtio_blk_req_complete(req, VIRTIO_BLK_S_UNSUPP);
+        g_free(req);
         return;
     }
 
@@ -229,11 +236,13 @@ static void virtio_blk_handle_scsi(VirtIOBlockReq *req)
     stl_p(&req->scsi->data_len, hdr.dxfer_len);
 
     virtio_blk_req_complete(req, status);
+    g_free(req);
 }
 #else
 static void virtio_blk_handle_scsi(VirtIOBlockReq *req)
 {
     virtio_blk_req_complete(req, VIRTIO_BLK_S_UNSUPP);
+    g_free(req);
 }
 #endif /* __linux__ */
 
@@ -266,6 +275,8 @@ static void virtio_blk_handle_flush(VirtIOBlockReq *req, MultiReqBuffer *mrb)
 {
     BlockDriverAIOCB *acb;
 
+    bdrv_acct_start(req->dev->bs, &req->acct, 0, BDRV_ACCT_FLUSH);
+
     /*
      * Make sure all outstanding writes are posted to the backing device.
      */
@@ -284,6 +295,8 @@ static void virtio_blk_handle_write(VirtIOBlockReq *req, MultiReqBuffer *mrb)
 
     sector = ldq_p(&req->out->sector);
 
+    bdrv_acct_start(req->dev->bs, &req->acct, req->qiov.size, BDRV_ACCT_WRITE);
+
     trace_virtio_blk_handle_write(req, sector, req->qiov.size / 512);
 
     if (sector & req->dev->sector_mask) {
@@ -317,6 +330,8 @@ static void virtio_blk_handle_read(VirtIOBlockReq *req)
 
     sector = ldq_p(&req->out->sector);
 
+    bdrv_acct_start(req->dev->bs, &req->acct, req->qiov.size, BDRV_ACCT_READ);
+
     if (sector & req->dev->sector_mask) {
         virtio_blk_rw_complete(req, -EIO);
         return;
@@ -370,6 +385,7 @@ static void virtio_blk_handle_request(VirtIOBlockReq *req,
                 s->serial ? s->serial : "",
                 MIN(req->elem.in_sg[0].iov_len, VIRTIO_BLK_ID_BYTES));
         virtio_blk_req_complete(req, VIRTIO_BLK_S_OK);
+        g_free(req);
     } else if (type & VIRTIO_BLK_T_OUT) {
         qemu_iovec_init_external(&req->qiov, &req->elem.out_sg[1],
                                  req->elem.out_num - 1);
diff --git a/hw/xen_disk.c b/hw/xen_disk.c
index 31f9151..bd5c669 100644
--- a/hw/xen_disk.c
+++ b/hw/xen_disk.c
@@ -79,6 +79,7 @@ struct ioreq {
 
     struct XenBlkDev    *blkdev;
     QLIST_ENTRY(ioreq)   list;
+    BlockAcctCookie     acct;
 };
 
 struct XenBlkDev {
@@ -401,6 +402,7 @@ static void qemu_aio_complete(void *opaque, int ret)
     ioreq->status = ioreq->aio_errors ? BLKIF_RSP_ERROR : BLKIF_RSP_OKAY;
     ioreq_unmap(ioreq);
     ioreq_finish(ioreq);
+    bdrv_acct_done(ioreq->blkdev->bs, &ioreq->acct);
     qemu_bh_schedule(ioreq->blkdev->bh);
 }
 
@@ -419,6 +421,7 @@ static int ioreq_runio_qemu_aio(struct ioreq *ioreq)
 
     switch (ioreq->req.operation) {
     case BLKIF_OP_READ:
+        bdrv_acct_start(blkdev->bs, &ioreq->acct, ioreq->v.size, BDRV_ACCT_READ);
         ioreq->aio_inflight++;
         bdrv_aio_readv(blkdev->bs, ioreq->start / BLOCK_SIZE,
                        &ioreq->v, ioreq->v.size / BLOCK_SIZE,
@@ -429,6 +432,8 @@ static int ioreq_runio_qemu_aio(struct ioreq *ioreq)
         if (!ioreq->req.nr_segments) {
             break;
         }
+
+        bdrv_acct_start(blkdev->bs, &ioreq->acct, ioreq->v.size, BDRV_ACCT_WRITE);
         ioreq->aio_inflight++;
         bdrv_aio_writev(blkdev->bs, ioreq->start / BLOCK_SIZE,
                         &ioreq->v, ioreq->v.size / BLOCK_SIZE,
commit 860341f60582959698d2e1d839a5b7a004a2d76f
Author: Jamie Iles <jamie at jamieiles.com>
Date:   Wed Aug 10 15:18:42 2011 +0100

    monitor: fix build breakage for !CONFIG_VNC
    
    Commit c62f6d1 (monitor: fix build breakage with --disable-vnc)
    conditionalised some VNC setup code but left an unused variable.  Move
    the variable into the conditional code to fix the build breakage.
    
    Cc: Luiz Capitulino <lcapitulino at redhat.com>
    Cc: Markus Armbruster <armbru at redhat.com>
    Signed-off-by: Jamie Iles <jamie at jamieiles.com>
    Signed-off-by: Luiz Capitulino <lcapitulino at redhat.com>

diff --git a/monitor.c b/monitor.c
index ada51d0..04f465a 100644
--- a/monitor.c
+++ b/monitor.c
@@ -1189,7 +1189,6 @@ static int add_graphics_client(Monitor *mon, const QDict *qdict, QObject **ret_d
 {
     const char *protocol  = qdict_get_str(qdict, "protocol");
     const char *fdname = qdict_get_str(qdict, "fdname");
-    int skipauth = qdict_get_try_bool(qdict, "skipauth", 0);
     CharDriverState *s;
 
     if (strcmp(protocol, "spice") == 0) {
@@ -1203,6 +1202,7 @@ static int add_graphics_client(Monitor *mon, const QDict *qdict, QObject **ret_d
 #ifdef CONFIG_VNC
     } else if (strcmp(protocol, "vnc") == 0) {
 	int fd = monitor_get_fd(mon, fdname);
+        int skipauth = qdict_get_try_bool(qdict, "skipauth", 0);
 	vnc_display_add_client(NULL, fd, skipauth);
 	return 0;
 #endif
commit 2f4b7593674e986e60b0b0f1a46707e0e149eb6d
Author: Frediano Ziglio <freddy77 at gmail.com>
Date:   Thu Aug 25 09:29:32 2011 +0200

    qcow2: remove unused qcow2_create_refcount_update function
    
    Signed-off-by: Frediano Ziglio <freddy77 at gmail.com>
    Signed-off-by: Kevin Wolf <kwolf at redhat.com>

diff --git a/block/qcow2-refcount.c b/block/qcow2-refcount.c
index fbf28da..9605367 100644
--- a/block/qcow2-refcount.c
+++ b/block/qcow2-refcount.c
@@ -680,24 +680,6 @@ void qcow2_free_any_clusters(BlockDriverState *bs,
 
 
 
-void qcow2_create_refcount_update(QCowCreateState *s, int64_t offset,
-    int64_t size)
-{
-    int refcount;
-    int64_t start, last, cluster_offset;
-    uint16_t *p;
-
-    start = offset & ~(s->cluster_size - 1);
-    last = (offset + size - 1)  & ~(s->cluster_size - 1);
-    for(cluster_offset = start; cluster_offset <= last;
-        cluster_offset += s->cluster_size) {
-        p = &s->refcount_block[cluster_offset >> s->cluster_bits];
-        refcount = be16_to_cpu(*p);
-        refcount++;
-        *p = cpu_to_be16(refcount);
-    }
-}
-
 /* update the refcounts of snapshots and the copied flag */
 int qcow2_update_snapshot_refcount(BlockDriverState *bs,
     int64_t l1_table_offset, int l1_size, int addend)
diff --git a/block/qcow2.h b/block/qcow2.h
index de23abe..c8ca3bc 100644
--- a/block/qcow2.h
+++ b/block/qcow2.h
@@ -189,8 +189,6 @@ void qcow2_free_clusters(BlockDriverState *bs,
 void qcow2_free_any_clusters(BlockDriverState *bs,
     uint64_t cluster_offset, int nb_clusters);
 
-void qcow2_create_refcount_update(QCowCreateState *s, int64_t offset,
-    int64_t size);
 int qcow2_update_snapshot_refcount(BlockDriverState *bs,
     int64_t l1_table_offset, int l1_size, int addend);
 
commit 35ee5e39c50fda3e6bd5ded74d57beb6c0276cff
Author: Frediano Ziglio <freddy77 at gmail.com>
Date:   Thu Aug 25 09:23:55 2011 +0200

    qcow2: use always stderr for debugging
    
    let all DEBUG_ALLOC2 printf goes to stderr
    
    Signed-off-by: Frediano Ziglio <freddy77 at gmail.com>
    Signed-off-by: Kevin Wolf <kwolf at redhat.com>

diff --git a/block/qcow2-cluster.c b/block/qcow2-cluster.c
index fde397e..e06be64 100644
--- a/block/qcow2-cluster.c
+++ b/block/qcow2-cluster.c
@@ -53,7 +53,7 @@ int qcow2_grow_l1_table(BlockDriverState *bs, int min_size, bool exact_size)
     }
 
 #ifdef DEBUG_ALLOC2
-    printf("grow l1_table from %d to %d\n", s->l1_size, new_l1_size);
+    fprintf(stderr, "grow l1_table from %d to %d\n", s->l1_size, new_l1_size);
 #endif
 
     new_l1_size2 = sizeof(uint64_t) * new_l1_size;
diff --git a/block/qcow2-refcount.c b/block/qcow2-refcount.c
index 2a915be..fbf28da 100644
--- a/block/qcow2-refcount.c
+++ b/block/qcow2-refcount.c
@@ -422,7 +422,7 @@ static int QEMU_WARN_UNUSED_RESULT update_refcount(BlockDriverState *bs,
     int ret;
 
 #ifdef DEBUG_ALLOC2
-    printf("update_refcount: offset=%" PRId64 " size=%" PRId64 " addend=%d\n",
+    fprintf(stderr, "update_refcount: offset=%" PRId64 " size=%" PRId64 " addend=%d\n",
            offset, length, addend);
 #endif
     if (length < 0) {
@@ -556,7 +556,7 @@ retry:
         }
     }
 #ifdef DEBUG_ALLOC2
-    printf("alloc_clusters: size=%" PRId64 " -> %" PRId64 "\n",
+    fprintf(stderr, "alloc_clusters: size=%" PRId64 " -> %" PRId64 "\n",
             size,
             (s->free_cluster_index - nb_clusters) << s->cluster_bits);
 #endif
commit 56a7a874e962e28522857fbf72eaefb1a07e2001
Merge: 8ef9ea8... e99722f...
Author: Anthony Liguori <aliguori at us.ibm.com>
Date:   Thu Aug 25 07:50:07 2011 -0500

    Merge remote-tracking branch 'stefanha/trivial-patches' into staging

commit 8ef9ea85a2cc1007eaefa53e6871f1f83bcef22d
Merge: 444dc48... 2b90ca0...
Author: Anthony Liguori <aliguori at us.ibm.com>
Date:   Thu Aug 25 07:48:24 2011 -0500

    Merge remote-tracking branch 'qemu-kvm/memory/batch' into staging

commit 444dc48298c480e42e15a8fe676be737d8a6b2a1
Merge: 5b15f27... 5f524c1...
Author: Anthony Liguori <aliguori at us.ibm.com>
Date:   Thu Aug 25 07:48:15 2011 -0500

    Merge remote-tracking branch 'aneesh/for-upstream-2' into staging

commit 7bc2b9cd4da5020b9adff3b3c8fdc04d6bcde79a
Author: Avi Kivity <avi at redhat.com>
Date:   Thu Aug 25 14:56:14 2011 +0300

    memory: fix memory_region_init_rom_device() not initializing ->ops
    
    Signed-off-by: Avi Kivity <avi at redhat.com>

diff --git a/memory.c b/memory.c
index 8e9ac46..b91c5da 100644
--- a/memory.c
+++ b/memory.c
@@ -967,6 +967,7 @@ void memory_region_init_rom_device(MemoryRegion *mr,
                                    uint64_t size)
 {
     memory_region_init(mr, name, size);
+    mr->ops = ops;
     mr->terminates = true;
     mr->destructor = memory_region_destructor_rom_device;
     mr->ram_addr = qemu_ram_alloc(dev, name, size);
commit e99722f66ae9b25b407c3c5afe4bdd9c9395ebd9
Author: Frediano Ziglio <freddy77 at gmail.com>
Date:   Thu Aug 25 09:14:38 2011 +0200

    disasm: update comment
    
    Signed-off-by: Frediano Ziglio <freddy77 at gmail.com>
    Signed-off-by: Stefan Hajnoczi <stefanha at linux.vnet.ibm.com>

diff --git a/disas.c b/disas.c
index 1334b8e..611b30b 100644
--- a/disas.c
+++ b/disas.c
@@ -137,7 +137,7 @@ print_insn_thumb1(bfd_vma pc, disassemble_info *info)
 
 /* Disassemble this for me please... (debugging). 'flags' has the following
    values:
-    i386 - nonzero means 16 bit code
+    i386 - 1 means 16 bit code, 2 means 64 bit code
     arm  - nonzero means thumb code
     ppc  - nonzero means little endian
     other targets - unused
commit fdc9c41a5a3f3dc6b849d381802ae1f22c5b23a9
Author: Jan Kiszka <jan.kiszka at web.de>
Date:   Mon Aug 15 16:24:48 2011 -0700

    Fix up some style nits of last uq/master merge
    
    Signed-off-by: Jan Kiszka <jan.kiszka at siemens.com>
    Signed-off-by: Stefan Hajnoczi <stefanha at linux.vnet.ibm.com>

diff --git a/cutils.c b/cutils.c
index f2bcf20..c91f887 100644
--- a/cutils.c
+++ b/cutils.c
@@ -408,7 +408,7 @@ fail:
 
 int64_t strtosz_suffix(const char *nptr, char **end, const char default_suffix)
 {
-        return strtosz_suffix_unit(nptr, end, default_suffix, 1024);
+    return strtosz_suffix_unit(nptr, end, default_suffix, 1024);
 }
 
 int64_t strtosz(const char *nptr, char **end)
diff --git a/target-i386/kvm.c b/target-i386/kvm.c
index bd850ed..1d9b20c 100644
--- a/target-i386/kvm.c
+++ b/target-i386/kvm.c
@@ -501,8 +501,9 @@ int kvm_arch_init_vcpu(CPUState *env)
     qemu_add_vm_change_state_handler(cpu_update_state, env);
 
     r = kvm_vcpu_ioctl(env, KVM_SET_CPUID2, &cpuid_data);
-    if (r)
-	    return r;
+    if (r) {
+        return r;
+    }
 
     r = kvm_check_extension(env->kvm_state, KVM_CAP_TSC_CONTROL);
     if (r && env->tsc_khz) {
commit 2b90ca040c59d73943061e49f39455964e8af158
Author: Avi Kivity <avi at redhat.com>
Date:   Mon Aug 8 21:42:57 2011 +0300

    milkymist: convert to memory API
    
    Reviewed-by: Richard Henderson  <rth at twiddle.net>
    Signed-off-by: Avi Kivity <avi at redhat.com>

diff --git a/hw/milkymist.c b/hw/milkymist.c
index 092d8b0..ef21cca 100644
--- a/hw/milkymist.c
+++ b/hw/milkymist.c
@@ -29,6 +29,7 @@
 #include "blockdev.h"
 #include "milkymist-hw.h"
 #include "lm32.h"
+#include "exec-memory.h"
 
 #define BIOS_FILENAME    "mmone-bios.bin"
 #define BIOS_OFFSET      0x00860000
@@ -81,7 +82,8 @@ milkymist_init(ram_addr_t ram_size_not_used,
     CPUState *env;
     int kernel_size;
     DriveInfo *dinfo;
-    ram_addr_t phys_sdram;
+    MemoryRegion *address_space_mem = get_system_memory();
+    MemoryRegion *phys_sdram = g_new(MemoryRegion, 1);
     MemoryRegion *phys_flash = g_new(MemoryRegion, 1);
     qemu_irq irq[32], *cpu_irq;
     int i;
@@ -109,9 +111,8 @@ milkymist_init(ram_addr_t ram_size_not_used,
 
     cpu_lm32_set_phys_msb_ignore(env, 1);
 
-    phys_sdram = qemu_ram_alloc(NULL, "milkymist.sdram", sdram_size);
-    cpu_register_physical_memory(sdram_base, sdram_size,
-            phys_sdram | IO_MEM_RAM);
+    memory_region_init_ram(phys_sdram, NULL, "milkymist.sdram", sdram_size);
+    memory_region_add_subregion(address_space_mem, sdram_base, phys_sdram);
 
     memory_region_init_rom_device(phys_flash, &pflash_cfi01_ops_be,
                                   NULL, "milkymist.flash", flash_size);
commit fcb9fc24c48b5af86cf0c7f1ff3d44a1fad6c655
Author: Avi Kivity <avi at redhat.com>
Date:   Mon Aug 8 21:40:35 2011 +0300

    milkymist-softusb: convert to memory API
    
    Reviewed-by: Richard Henderson  <rth at twiddle.net>
    Signed-off-by: Avi Kivity <avi at redhat.com>

diff --git a/hw/milkymist-softusb.c b/hw/milkymist-softusb.c
index fe4eedb..ef4d9ee 100644
--- a/hw/milkymist-softusb.c
+++ b/hw/milkymist-softusb.c
@@ -49,6 +49,9 @@ struct MilkymistSoftUsbState {
     HIDState hid_kbd;
     HIDState hid_mouse;
 
+    MemoryRegion regs_region;
+    MemoryRegion pmem;
+    MemoryRegion dmem;
     qemu_irq irq;
 
     /* device properties */
@@ -68,7 +71,8 @@ struct MilkymistSoftUsbState {
 };
 typedef struct MilkymistSoftUsbState MilkymistSoftUsbState;
 
-static uint32_t softusb_read(void *opaque, target_phys_addr_t addr)
+static uint64_t softusb_read(void *opaque, target_phys_addr_t addr,
+                             unsigned size)
 {
     MilkymistSoftUsbState *s = opaque;
     uint32_t r = 0;
@@ -91,7 +95,8 @@ static uint32_t softusb_read(void *opaque, target_phys_addr_t addr)
 }
 
 static void
-softusb_write(void *opaque, target_phys_addr_t addr, uint32_t value)
+softusb_write(void *opaque, target_phys_addr_t addr, uint64_t value,
+              unsigned size)
 {
     MilkymistSoftUsbState *s = opaque;
 
@@ -110,16 +115,14 @@ softusb_write(void *opaque, target_phys_addr_t addr, uint32_t value)
     }
 }
 
-static CPUReadMemoryFunc * const softusb_read_fn[] = {
-    NULL,
-    NULL,
-    &softusb_read,
-};
-
-static CPUWriteMemoryFunc * const softusb_write_fn[] = {
-    NULL,
-    NULL,
-    &softusb_write,
+static const MemoryRegionOps softusb_mmio_ops = {
+    .read = softusb_read,
+    .write = softusb_write,
+    .endianness = DEVICE_NATIVE_ENDIAN,
+    .valid = {
+        .min_access_size = 4,
+        .max_access_size = 4,
+    },
 };
 
 static inline void softusb_read_dmem(MilkymistSoftUsbState *s,
@@ -256,23 +259,20 @@ static void milkymist_softusb_reset(DeviceState *d)
 static int milkymist_softusb_init(SysBusDevice *dev)
 {
     MilkymistSoftUsbState *s = FROM_SYSBUS(typeof(*s), dev);
-    int softusb_regs;
-    ram_addr_t pmem_ram;
-    ram_addr_t dmem_ram;
 
     sysbus_init_irq(dev, &s->irq);
 
-    softusb_regs = cpu_register_io_memory(softusb_read_fn, softusb_write_fn, s,
-            DEVICE_NATIVE_ENDIAN);
-    sysbus_init_mmio(dev, R_MAX * 4, softusb_regs);
+    memory_region_init_io(&s->regs_region, &softusb_mmio_ops, s,
+                          "milkymist-softusb", R_MAX * 4);
+    sysbus_init_mmio_region(dev, &s->regs_region);
 
     /* register pmem and dmem */
-    pmem_ram = qemu_ram_alloc(NULL, "milkymist_softusb.pmem", s->pmem_size);
-    cpu_register_physical_memory(s->pmem_base, s->pmem_size,
-            pmem_ram | IO_MEM_RAM);
-    dmem_ram = qemu_ram_alloc(NULL, "milkymist_softusb.dmem", s->dmem_size);
-    cpu_register_physical_memory(s->dmem_base, s->dmem_size,
-            dmem_ram | IO_MEM_RAM);
+    memory_region_init_ram(&s->pmem, NULL, "milkymist_softusb.pmem",
+                           s->pmem_size);
+    sysbus_add_memory(dev, s->pmem_base, &s->pmem);
+    memory_region_init_ram(&s->dmem, NULL, "milkymist_softusb.dmem",
+                           s->dmem_size);
+    sysbus_add_memory(dev, s->dmem_base, &s->dmem);
 
     hid_init(&s->hid_kbd, HID_KEYBOARD, softusb_kbd_hid_datain);
     hid_init(&s->hid_mouse, HID_MOUSE, softusb_mouse_hid_datain);
commit 906d23eb0d0a2a2202523806804c65efe8e031c2
Author: Avi Kivity <avi at redhat.com>
Date:   Mon Aug 8 21:32:25 2011 +0300

    milkymist-minimac2: convert to memory API
    
    Reviewed-by: Richard Henderson  <rth at twiddle.net>
    Signed-off-by: Avi Kivity <avi at redhat.com>

diff --git a/hw/milkymist-minimac2.c b/hw/milkymist-minimac2.c
index cd36026..fb48e37 100644
--- a/hw/milkymist-minimac2.c
+++ b/hw/milkymist-minimac2.c
@@ -97,6 +97,8 @@ struct MilkymistMinimac2State {
     NICConf conf;
     char *phy_model;
     target_phys_addr_t buffers_base;
+    MemoryRegion buffers;
+    MemoryRegion regs_region;
 
     qemu_irq rx_irq;
     qemu_irq tx_irq;
@@ -320,8 +322,8 @@ static ssize_t minimac2_rx(VLANClientState *nc, const uint8_t *buf, size_t size)
     return size;
 }
 
-static uint32_t
-minimac2_read(void *opaque, target_phys_addr_t addr)
+static uint64_t
+minimac2_read(void *opaque, target_phys_addr_t addr, unsigned size)
 {
     MilkymistMinimac2State *s = opaque;
     uint32_t r = 0;
@@ -350,7 +352,8 @@ minimac2_read(void *opaque, target_phys_addr_t addr)
 }
 
 static void
-minimac2_write(void *opaque, target_phys_addr_t addr, uint32_t value)
+minimac2_write(void *opaque, target_phys_addr_t addr, uint64_t value,
+               unsigned size)
 {
     MilkymistMinimac2State *s = opaque;
 
@@ -395,16 +398,14 @@ minimac2_write(void *opaque, target_phys_addr_t addr, uint32_t value)
     }
 }
 
-static CPUReadMemoryFunc * const minimac2_read_fn[] = {
-    NULL,
-    NULL,
-    &minimac2_read,
-};
-
-static CPUWriteMemoryFunc * const minimac2_write_fn[] = {
-    NULL,
-    NULL,
-    &minimac2_write,
+static const MemoryRegionOps minimac2_ops = {
+    .read = minimac2_read,
+    .write = minimac2_write,
+    .valid = {
+        .min_access_size = 4,
+        .max_access_size = 4,
+    },
+    .endianness = DEVICE_NATIVE_ENDIAN,
 };
 
 static int minimac2_can_rx(VLANClientState *nc)
@@ -457,25 +458,23 @@ static NetClientInfo net_milkymist_minimac2_info = {
 static int milkymist_minimac2_init(SysBusDevice *dev)
 {
     MilkymistMinimac2State *s = FROM_SYSBUS(typeof(*s), dev);
-    int regs;
-    ram_addr_t buffers;
     size_t buffers_size = TARGET_PAGE_ALIGN(3 * MINIMAC2_BUFFER_SIZE);
 
     sysbus_init_irq(dev, &s->rx_irq);
     sysbus_init_irq(dev, &s->tx_irq);
 
-    regs = cpu_register_io_memory(minimac2_read_fn, minimac2_write_fn, s,
-            DEVICE_NATIVE_ENDIAN);
-    sysbus_init_mmio(dev, R_MAX * 4, regs);
+    memory_region_init_io(&s->regs_region, &minimac2_ops, s,
+                          "minimac2-mmio", R_MAX * 4);
+    sysbus_init_mmio_region(dev, &s->regs_region);
 
     /* register buffers memory */
-    buffers = qemu_ram_alloc(NULL, "milkymist_minimac2.buffers", buffers_size);
-    s->rx0_buf = qemu_get_ram_ptr(buffers);
+    memory_region_init_ram(&s->buffers, NULL, "milkymist_minimac2.buffers",
+                           buffers_size);
+    s->rx0_buf = memory_region_get_ram_ptr(&s->buffers);
     s->rx1_buf = s->rx0_buf + MINIMAC2_BUFFER_SIZE;
     s->tx_buf = s->rx1_buf + MINIMAC2_BUFFER_SIZE;
 
-    cpu_register_physical_memory(s->buffers_base, buffers_size,
-            buffers | IO_MEM_RAM);
+    sysbus_add_memory(dev, s->buffers_base, &s->buffers);
 
     qemu_macaddr_default_if_unset(&s->conf.macaddr);
     s->nic = qemu_new_nic(&net_milkymist_minimac2_info, &s->conf,
commit e33df454e5b0f4ad353a4c4a935c0dc236bae9cb
Author: Avi Kivity <avi at redhat.com>
Date:   Mon Aug 8 21:21:47 2011 +0300

    mcf5208: convert to memory API
    
    Reviewed-by: Richard Henderson  <rth at twiddle.net>
    Signed-off-by: Avi Kivity <avi at redhat.com>

diff --git a/hw/mcf5208.c b/hw/mcf5208.c
index 8fe507f..1c2c0c4 100644
--- a/hw/mcf5208.c
+++ b/hw/mcf5208.c
@@ -13,6 +13,7 @@
 #include "boards.h"
 #include "loader.h"
 #include "elf.h"
+#include "exec-memory.h"
 
 #define SYS_FREQ 66000000
 
@@ -27,6 +28,7 @@
 #define PCSR_PRE_MASK   0x0f00
 
 typedef struct {
+    MemoryRegion iomem;
     qemu_irq irq;
     ptimer_state *timer;
     uint16_t pcsr;
@@ -43,7 +45,7 @@ static void m5208_timer_update(m5208_timer_state *s)
 }
 
 static void m5208_timer_write(void *opaque, target_phys_addr_t offset,
-                              uint32_t value)
+                              uint64_t value, unsigned size)
 {
     m5208_timer_state *s = (m5208_timer_state *)opaque;
     int prescale;
@@ -104,7 +106,8 @@ static void m5208_timer_trigger(void *opaque)
     m5208_timer_update(s);
 }
 
-static uint32_t m5208_timer_read(void *opaque, target_phys_addr_t addr)
+static uint64_t m5208_timer_read(void *opaque, target_phys_addr_t addr,
+                                 unsigned size)
 {
     m5208_timer_state *s = (m5208_timer_state *)opaque;
     switch (addr) {
@@ -120,19 +123,14 @@ static uint32_t m5208_timer_read(void *opaque, target_phys_addr_t addr)
     }
 }
 
-static CPUReadMemoryFunc * const m5208_timer_readfn[] = {
-   m5208_timer_read,
-   m5208_timer_read,
-   m5208_timer_read
+static const MemoryRegionOps m5208_timer_ops = {
+    .read = m5208_timer_read,
+    .write = m5208_timer_write,
+    .endianness = DEVICE_NATIVE_ENDIAN,
 };
 
-static CPUWriteMemoryFunc * const m5208_timer_writefn[] = {
-   m5208_timer_write,
-   m5208_timer_write,
-   m5208_timer_write
-};
-
-static uint32_t m5208_sys_read(void *opaque, target_phys_addr_t addr)
+static uint64_t m5208_sys_read(void *opaque, target_phys_addr_t addr,
+                               unsigned size)
 {
     switch (addr) {
     case 0x110: /* SDCS0 */
@@ -154,45 +152,36 @@ static uint32_t m5208_sys_read(void *opaque, target_phys_addr_t addr)
 }
 
 static void m5208_sys_write(void *opaque, target_phys_addr_t addr,
-                            uint32_t value)
+                            uint64_t value, unsigned size)
 {
     hw_error("m5208_sys_write: Bad offset 0x%x\n", (int)addr);
 }
 
-static CPUReadMemoryFunc * const m5208_sys_readfn[] = {
-   m5208_sys_read,
-   m5208_sys_read,
-   m5208_sys_read
-};
-
-static CPUWriteMemoryFunc * const m5208_sys_writefn[] = {
-   m5208_sys_write,
-   m5208_sys_write,
-   m5208_sys_write
+static const MemoryRegionOps m5208_sys_ops = {
+    .read = m5208_sys_read,
+    .write = m5208_sys_write,
+    .endianness = DEVICE_NATIVE_ENDIAN,
 };
 
-static void mcf5208_sys_init(qemu_irq *pic)
+static void mcf5208_sys_init(MemoryRegion *address_space, qemu_irq *pic)
 {
-    int iomemtype;
+    MemoryRegion *iomem = g_new(MemoryRegion, 1);
     m5208_timer_state *s;
     QEMUBH *bh;
     int i;
 
-    iomemtype = cpu_register_io_memory(m5208_sys_readfn,
-                                       m5208_sys_writefn, NULL,
-                                       DEVICE_NATIVE_ENDIAN);
     /* SDRAMC.  */
-    cpu_register_physical_memory(0xfc0a8000, 0x00004000, iomemtype);
+    memory_region_init_io(iomem, &m5208_sys_ops, NULL, "m5208-sys", 0x00004000);
+    memory_region_add_subregion(address_space, 0xfc0a8000, iomem);
     /* Timers.  */
     for (i = 0; i < 2; i++) {
         s = (m5208_timer_state *)g_malloc0(sizeof(m5208_timer_state));
         bh = qemu_bh_new(m5208_timer_trigger, s);
         s->timer = ptimer_init(bh);
-        iomemtype = cpu_register_io_memory(m5208_timer_readfn,
-                                           m5208_timer_writefn, s,
-                                           DEVICE_NATIVE_ENDIAN);
-        cpu_register_physical_memory(0xfc080000 + 0x4000 * i, 0x00004000,
-                                     iomemtype);
+        memory_region_init_io(&s->iomem, &m5208_timer_ops, s,
+                              "m5208-timer", 0x00004000);
+        memory_region_add_subregion(address_space, 0xfc080000 + 0x4000 * i,
+                                    &s->iomem);
         s->irq = pic[4 + i];
     }
 }
@@ -207,6 +196,9 @@ static void mcf5208evb_init(ram_addr_t ram_size,
     uint64_t elf_entry;
     target_phys_addr_t entry;
     qemu_irq *pic;
+    MemoryRegion *address_space_mem = get_system_memory();
+    MemoryRegion *ram = g_new(MemoryRegion, 1);
+    MemoryRegion *sram = g_new(MemoryRegion, 1);
 
     if (!cpu_model)
         cpu_model = "m5208";
@@ -221,12 +213,12 @@ static void mcf5208evb_init(ram_addr_t ram_size,
     /* TODO: Configure BARs.  */
 
     /* DRAM at 0x40000000 */
-    cpu_register_physical_memory(0x40000000, ram_size,
-        qemu_ram_alloc(NULL, "mcf5208.ram", ram_size) | IO_MEM_RAM);
+    memory_region_init_ram(ram, NULL, "mcf5208.ram", ram_size);
+    memory_region_add_subregion(address_space_mem, 0x40000000, ram);
 
     /* Internal SRAM.  */
-    cpu_register_physical_memory(0x80000000, 16384,
-        qemu_ram_alloc(NULL, "mcf5208.sram", 16384) | IO_MEM_RAM);
+    memory_region_init_ram(sram, NULL, "mcf5208.sram", 16384);
+    memory_region_add_subregion(address_space_mem, 0x80000000, sram);
 
     /* Internal peripherals.  */
     pic = mcf_intc_init(0xfc048000, env);
@@ -235,7 +227,7 @@ static void mcf5208evb_init(ram_addr_t ram_size,
     mcf_uart_mm_init(0xfc064000, pic[27], serial_hds[1]);
     mcf_uart_mm_init(0xfc068000, pic[28], serial_hds[2]);
 
-    mcf5208_sys_init(pic);
+    mcf5208_sys_init(address_space_mem, pic);
 
     if (nb_nics > 1) {
         fprintf(stderr, "Too many NICs\n");
commit 09730e296bcb0fe1471200c5c04681b644f439bd
Author: Avi Kivity <avi at redhat.com>
Date:   Mon Aug 8 21:08:45 2011 +0300

    mainstone: convert to memory API
    
    Reviewed-by: Richard Henderson  <rth at twiddle.net>
    Signed-off-by: Avi Kivity <avi at redhat.com>

diff --git a/hw/mainstone.c b/hw/mainstone.c
index 78af41b..82e9571 100644
--- a/hw/mainstone.c
+++ b/hw/mainstone.c
@@ -17,6 +17,7 @@
 #include "flash.h"
 #include "blockdev.h"
 #include "sysbus.h"
+#include "exec-memory.h"
 
 /* Device addresses */
 #define MST_FPGA_PHYS	0x08000000
@@ -90,7 +91,8 @@ static struct arm_boot_info mainstone_binfo = {
     .ram_size = 0x04000000,
 };
 
-static void mainstone_common_init(ram_addr_t ram_size,
+static void mainstone_common_init(MemoryRegion *address_space_mem,
+                ram_addr_t ram_size,
                 const char *kernel_filename,
                 const char *kernel_cmdline, const char *initrd_filename,
                 const char *cpu_model, enum mainstone_model_e model, int arm_id)
@@ -101,6 +103,7 @@ static void mainstone_common_init(ram_addr_t ram_size,
     DeviceState *mst_irq;
     DriveInfo *dinfo;
     int i;
+    MemoryRegion *rom = g_new(MemoryRegion, 1);
     MemoryRegion *flashes = g_new(MemoryRegion, 2);
     const MemoryRegionOps *flash_ops;
 
@@ -109,9 +112,9 @@ static void mainstone_common_init(ram_addr_t ram_size,
 
     /* Setup CPU & memory */
     cpu = pxa270_init(mainstone_binfo.ram_size, cpu_model);
-    cpu_register_physical_memory(0, MAINSTONE_ROM,
-                    qemu_ram_alloc(NULL, "mainstone.rom",
-                                   MAINSTONE_ROM) | IO_MEM_ROM);
+    memory_region_init_ram(rom, NULL, "mainstone.rom", MAINSTONE_ROM);
+    memory_region_set_readonly(rom, true);
+    memory_region_add_subregion(address_space_mem, 0, rom);
 
 #ifdef TARGET_WORDS_BIGENDIAN
     flash_ops = &pflash_cfi01_ops_be;
@@ -172,7 +175,7 @@ static void mainstone_init(ram_addr_t ram_size,
                 const char *kernel_filename, const char *kernel_cmdline,
                 const char *initrd_filename, const char *cpu_model)
 {
-    mainstone_common_init(ram_size, kernel_filename,
+    mainstone_common_init(get_system_memory(), ram_size, kernel_filename,
                 kernel_cmdline, initrd_filename, cpu_model, mainstone, 0x196);
 }
 
commit 4c9e975d646f1633093e10a27da6cf655a6d9dcf
Author: Avi Kivity <avi at redhat.com>
Date:   Mon Aug 8 21:05:07 2011 +0300

    lm32_boards: convert to memory API
    
    Reviewed-by: Richard Henderson  <rth at twiddle.net>
    Signed-off-by: Avi Kivity <avi at redhat.com>

diff --git a/hw/lm32_boards.c b/hw/lm32_boards.c
index f032bc0..a84007b 100644
--- a/hw/lm32_boards.c
+++ b/hw/lm32_boards.c
@@ -28,6 +28,7 @@
 #include "elf.h"
 #include "lm32_hwsetup.h"
 #include "lm32.h"
+#include "exec-memory.h"
 
 typedef struct {
     CPUState *env;
@@ -76,7 +77,8 @@ static void lm32_evr_init(ram_addr_t ram_size_not_used,
 {
     CPUState *env;
     DriveInfo *dinfo;
-    ram_addr_t phys_ram;
+    MemoryRegion *address_space_mem =  get_system_memory();
+    MemoryRegion *phys_ram = g_new(MemoryRegion, 1);
     MemoryRegion *phys_flash = g_new(MemoryRegion, 1);
     qemu_irq *cpu_irq, irq[32];
     ResetInfo *reset_info;
@@ -105,8 +107,8 @@ static void lm32_evr_init(ram_addr_t ram_size_not_used,
 
     reset_info->flash_base = flash_base;
 
-    phys_ram = qemu_ram_alloc(NULL, "lm32_evr.sdram", ram_size);
-    cpu_register_physical_memory(ram_base, ram_size, phys_ram | IO_MEM_RAM);
+    memory_region_init_ram(phys_ram, NULL, "lm32_evr.sdram", ram_size);
+    memory_region_add_subregion(address_space_mem, ram_base, phys_ram);
 
     memory_region_init_rom_device(phys_flash, &pflash_cfi02_ops_be,
                                   NULL, "lm32_evr.flash", flash_size);
@@ -165,7 +167,8 @@ static void lm32_uclinux_init(ram_addr_t ram_size_not_used,
 {
     CPUState *env;
     DriveInfo *dinfo;
-    ram_addr_t phys_ram;
+    MemoryRegion *address_space_mem =  get_system_memory();
+    MemoryRegion *phys_ram = g_new(MemoryRegion, 1);
     MemoryRegion *phys_flash = g_new(MemoryRegion, 1);
     qemu_irq *cpu_irq, irq[32];
     HWSetup *hw;
@@ -201,8 +204,8 @@ static void lm32_uclinux_init(ram_addr_t ram_size_not_used,
 
     reset_info->flash_base = flash_base;
 
-    phys_ram = qemu_ram_alloc(NULL, "lm32_uclinux.sdram", ram_size);
-    cpu_register_physical_memory(ram_base, ram_size, phys_ram | IO_MEM_RAM);
+    memory_region_init_ram(phys_ram, NULL, "lm32_uclinux.sdram", ram_size);
+    memory_region_add_subregion(address_space_mem, ram_base, phys_ram);
 
     memory_region_init_rom_device(phys_flash, &pflash_cfi01_ops_be,
                                   NULL, "lm32_uclinux.flash", flash_size);
commit 82afb3a70796f3e600ac84bbaff21e4af0759291
Author: Avi Kivity <avi at redhat.com>
Date:   Mon Aug 8 21:01:16 2011 +0300

    g364fb: convert to memory API
    
    Reviewed-by: Richard Henderson  <rth at twiddle.net>
    Signed-off-by: Avi Kivity <avi at redhat.com>

diff --git a/hw/g364fb.c b/hw/g364fb.c
index b3020c5..a7731ec 100644
--- a/hw/g364fb.c
+++ b/hw/g364fb.c
@@ -36,7 +36,7 @@ do { fprintf(stderr, "g364 ERROR: " fmt , ## __VA_ARGS__);} while (0)
 typedef struct G364State {
     /* hardware */
     uint8_t *vram;
-    ram_addr_t vram_offset;
+    MemoryRegion vram_region;
     int vram_size;
     qemu_irq irq;
     /* registers */
@@ -68,16 +68,17 @@ typedef struct G364State {
 #define CTLA_FORCE_BLANK 0x00000400
 #define CTLA_NO_CURSOR   0x00800000
 
-static inline int check_dirty(ram_addr_t page)
+static inline int check_dirty(G364State *s, ram_addr_t page)
 {
-    return cpu_physical_memory_get_dirty(page, VGA_DIRTY_FLAG);
+    return memory_region_get_dirty(&s->vram_region, page, DIRTY_MEMORY_VGA);
 }
 
 static inline void reset_dirty(G364State *s,
                                ram_addr_t page_min, ram_addr_t page_max)
 {
-    cpu_physical_memory_reset_dirty(page_min, page_max + TARGET_PAGE_SIZE - 1,
-                                    VGA_DIRTY_FLAG);
+    memory_region_reset_dirty(&s->vram_region, page_min,
+                              page_max + TARGET_PAGE_SIZE - 1,
+                              DIRTY_MEMORY_VGA);
 }
 
 static void g364fb_draw_graphic8(G364State *s)
@@ -114,7 +115,7 @@ static void g364fb_draw_graphic8(G364State *s)
             return;
     }
 
-    page = s->vram_offset;
+    page = 0;
     page_min = (ram_addr_t)-1;
     page_max = 0;
 
@@ -135,7 +136,7 @@ static void g364fb_draw_graphic8(G364State *s)
     /* XXX: out of range in vram? */
     data_display = dd = ds_get_data(s->ds);
     while (y < s->height) {
-        if (check_dirty(page)) {
+        if (check_dirty(s, page)) {
             if (y < ymin)
                 ymin = ymax = y;
             if (page_min == (ram_addr_t)-1)
@@ -275,7 +276,7 @@ static inline void g364fb_invalidate_display(void *opaque)
 
     s->blanked = 0;
     for (i = 0; i < s->vram_size; i += TARGET_PAGE_SIZE) {
-        cpu_physical_memory_set_dirty(s->vram_offset + i);
+        memory_region_set_dirty(&s->vram_region, i);
     }
 }
 
@@ -411,7 +412,7 @@ static void g364_invalidate_cursor_position(G364State *s)
     end = (ymax + 1) * ds_get_linesize(s->ds);
 
     for (i = start; i < end; i += TARGET_PAGE_SIZE) {
-        cpu_physical_memory_set_dirty(s->vram_offset + i);
+        memory_region_set_dirty(&s->vram_region, i);
     }
 }
 
@@ -522,16 +523,20 @@ static void g364fb_ctrl_writeb(void *opaque, target_phys_addr_t addr, uint32_t v
     g364fb_ctrl_writel(opaque, addr & ~0x3, val);
 }
 
-static CPUReadMemoryFunc * const g364fb_ctrl_read[3] = {
-    g364fb_ctrl_readb,
-    g364fb_ctrl_readw,
-    g364fb_ctrl_readl,
-};
-
-static CPUWriteMemoryFunc * const g364fb_ctrl_write[3] = {
-    g364fb_ctrl_writeb,
-    g364fb_ctrl_writew,
-    g364fb_ctrl_writel,
+static const MemoryRegionOps g364fb_ctrl_ops = {
+    .old_mmio = {
+        .read = {
+            g364fb_ctrl_readb,
+            g364fb_ctrl_readw,
+            g364fb_ctrl_readl,
+        },
+        .write = {
+            g364fb_ctrl_writeb,
+            g364fb_ctrl_writew,
+            g364fb_ctrl_writel,
+        },
+    },
+    .endianness = DEVICE_NATIVE_ENDIAN,
 };
 
 static int g364fb_load(QEMUFile *f, void *opaque, int version_id)
@@ -583,18 +588,19 @@ static void g364fb_save(QEMUFile *f, void *opaque)
     qemu_put_be32(f, s->height);
 }
 
-int g364fb_mm_init(target_phys_addr_t vram_base,
+int g364fb_mm_init(MemoryRegion *system_memory,
+                   target_phys_addr_t vram_base,
                    target_phys_addr_t ctrl_base, int it_shift,
                    qemu_irq irq)
 {
     G364State *s;
-    int io_ctrl;
+    MemoryRegion *io_ctrl = g_new(MemoryRegion, 1);
 
     s = g_malloc0(sizeof(G364State));
 
     s->vram_size = 8 * 1024 * 1024;
-    s->vram_offset = qemu_ram_alloc(NULL, "g364fb.vram", s->vram_size);
-    s->vram = qemu_get_ram_ptr(s->vram_offset);
+    memory_region_init_ram(&s->vram_region, NULL, "g364fb.vram", s->vram_size);
+    s->vram = memory_region_get_ram_ptr(&s->vram_region);
     s->irq = irq;
 
     qemu_register_reset(g364fb_reset, s);
@@ -605,11 +611,11 @@ int g364fb_mm_init(target_phys_addr_t vram_base,
                                  g364fb_invalidate_display,
                                  g364fb_screen_dump, NULL, s);
 
-    cpu_register_physical_memory(vram_base, s->vram_size, s->vram_offset);
+    memory_region_add_subregion(system_memory, vram_base, &s->vram_region);
 
-    io_ctrl = cpu_register_io_memory(g364fb_ctrl_read, g364fb_ctrl_write, s,
-                                     DEVICE_NATIVE_ENDIAN);
-    cpu_register_physical_memory(ctrl_base, 0x200000, io_ctrl);
+    memory_region_init_io(io_ctrl, &g364fb_ctrl_ops, s,
+                          "g364fb-ctrl", 0x200000);
+    memory_region_add_subregion(system_memory, ctrl_base, io_ctrl);
 
     return 0;
 }
diff --git a/hw/mips.h b/hw/mips.h
index cae5f4c..97d7b9e 100644
--- a/hw/mips.h
+++ b/hw/mips.h
@@ -2,6 +2,8 @@
 #define HW_MIPS_H
 /* Definitions for mips board emulation.  */
 
+#include "memory.h"
+
 /* gt64xxx.c */
 PCIBus *gt64120_register(qemu_irq *pic);
 
@@ -9,7 +11,7 @@ PCIBus *gt64120_register(qemu_irq *pic);
 PCIBus *bonito_init(qemu_irq *pic);
 
 /* g364fb.c */
-int g364fb_mm_init(target_phys_addr_t vram_base,
+int g364fb_mm_init(MemoryRegion *system_memory, target_phys_addr_t vram_base,
                    target_phys_addr_t ctrl_base, int it_shift,
                    qemu_irq irq);
 
diff --git a/hw/mips_jazz.c b/hw/mips_jazz.c
index 84ce061..a741086 100644
--- a/hw/mips_jazz.c
+++ b/hw/mips_jazz.c
@@ -195,7 +195,8 @@ void mips_jazz_init (ram_addr_t ram_size,
     /* Video card */
     switch (jazz_model) {
     case JAZZ_MAGNUM:
-        g364fb_mm_init(0x40000000, 0x60000000, 0, rc4030[3]);
+        g364fb_mm_init(get_system_memory(), 0x40000000, 0x60000000, 0,
+                       rc4030[3]);
         break;
     case JAZZ_PICA61:
         isa_vga_mm_init(0x40000000, 0x60000000, 0, get_system_memory());
commit 9eadff4a94a55a481ee24b45ba3a83615499d339
Author: Avi Kivity <avi at redhat.com>
Date:   Mon Aug 8 20:44:23 2011 +0300

    dummy_m68k: convert to memory API
    
    Reviewed-by: Richard Henderson  <rth at twiddle.net>
    Signed-off-by: Avi Kivity <avi at redhat.com>

diff --git a/hw/dummy_m68k.c b/hw/dummy_m68k.c
index eed9e38..30146b9 100644
--- a/hw/dummy_m68k.c
+++ b/hw/dummy_m68k.c
@@ -10,6 +10,7 @@
 #include "boards.h"
 #include "loader.h"
 #include "elf.h"
+#include "exec-memory.h"
 
 #define KERNEL_LOAD_ADDR 0x10000
 
@@ -21,6 +22,8 @@ static void dummy_m68k_init(ram_addr_t ram_size,
                      const char *initrd_filename, const char *cpu_model)
 {
     CPUState *env;
+    MemoryRegion *address_space_mem =  get_system_memory();
+    MemoryRegion *ram = g_new(MemoryRegion, 1);
     int kernel_size;
     uint64_t elf_entry;
     target_phys_addr_t entry;
@@ -37,8 +40,8 @@ static void dummy_m68k_init(ram_addr_t ram_size,
     env->vbr = 0;
 
     /* RAM at address zero */
-    cpu_register_physical_memory(0, ram_size,
-        qemu_ram_alloc(NULL, "dummy_m68k.ram", ram_size) | IO_MEM_RAM);
+    memory_region_init_ram(ram, NULL, "dummy_m68k.ram", ram_size);
+    memory_region_add_subregion(address_space_mem, 0, ram);
 
     /* Load kernel.  */
     if (kernel_filename) {
commit c8a50e596c8eeb41bf5718df5bad6be4080f40c7
Author: Avi Kivity <avi at redhat.com>
Date:   Thu Aug 4 15:55:30 2011 +0300

    pflash_cfi01/pflash_cfi02: convert to memory API
    
    cfi02 is annoying in that is ignores some address bits; we probably
    want explicit support in the memory API for that.
    
    Reviewed-by: Richard Henderson  <rth at twiddle.net>
    Signed-off-by: Avi Kivity <avi at redhat.com>

diff --git a/hw/collie.c b/hw/collie.c
index 156404d..0b955e0 100644
--- a/hw/collie.c
+++ b/hw/collie.c
@@ -26,7 +26,7 @@ static void collie_init(ram_addr_t ram_size,
 {
     StrongARMState *s;
     DriveInfo *dinfo;
-    ram_addr_t phys_flash;
+    MemoryRegion *phys_flash = g_new(MemoryRegion, 2);
 
     if (!cpu_model) {
         cpu_model = "sa1110";
@@ -34,17 +34,19 @@ static void collie_init(ram_addr_t ram_size,
 
     s = sa1110_init(collie_binfo.ram_size, cpu_model);
 
-    phys_flash = qemu_ram_alloc(NULL, "collie.fl1", 0x02000000);
+    memory_region_init_rom_device(&phys_flash[0], &pflash_cfi01_ops_le,
+                                  NULL, "collie.fl1", 0x02000000);
     dinfo = drive_get(IF_PFLASH, 0, 0);
-    pflash_cfi01_register(SA_CS0, phys_flash,
+    pflash_cfi01_register(SA_CS0, &phys_flash[0],
                     dinfo ? dinfo->bdrv : NULL, (64 * 1024),
-                    512, 4, 0x00, 0x00, 0x00, 0x00, 0);
+                    512, 4, 0x00, 0x00, 0x00, 0x00);
 
-    phys_flash = qemu_ram_alloc(NULL, "collie.fl2", 0x02000000);
+    memory_region_init_rom_device(&phys_flash[1], &pflash_cfi01_ops_le,
+                                  NULL, "collie.fl2", 0x02000000);
     dinfo = drive_get(IF_PFLASH, 0, 1);
-    pflash_cfi01_register(SA_CS1, phys_flash,
+    pflash_cfi01_register(SA_CS1, &phys_flash[1],
                     dinfo ? dinfo->bdrv : NULL, (64 * 1024),
-                    512, 4, 0x00, 0x00, 0x00, 0x00, 0);
+                    512, 4, 0x00, 0x00, 0x00, 0x00);
 
     sysbus_create_simple("scoop", 0x40800000, NULL);
 
diff --git a/hw/flash.h b/hw/flash.h
index 140ae39..7fb012b 100644
--- a/hw/flash.h
+++ b/hw/flash.h
@@ -1,21 +1,27 @@
+#include "memory.h"
+
 /* NOR flash devices */
 typedef struct pflash_t pflash_t;
 
 /* pflash_cfi01.c */
-pflash_t *pflash_cfi01_register(target_phys_addr_t base, ram_addr_t off,
+extern const MemoryRegionOps pflash_cfi01_ops_be;
+extern const MemoryRegionOps pflash_cfi01_ops_le;
+extern const MemoryRegionOps pflash_cfi02_ops_be;
+extern const MemoryRegionOps pflash_cfi02_ops_le;
+
+pflash_t *pflash_cfi01_register(target_phys_addr_t base, MemoryRegion *mem,
                                 BlockDriverState *bs,
                                 uint32_t sector_len, int nb_blocs, int width,
                                 uint16_t id0, uint16_t id1,
-                                uint16_t id2, uint16_t id3, int be);
+                                uint16_t id2, uint16_t id3);
 
 /* pflash_cfi02.c */
-pflash_t *pflash_cfi02_register(target_phys_addr_t base, ram_addr_t off,
+pflash_t *pflash_cfi02_register(target_phys_addr_t base, MemoryRegion *mem,
                                 BlockDriverState *bs, uint32_t sector_len,
                                 int nb_blocs, int nb_mappings, int width,
                                 uint16_t id0, uint16_t id1,
                                 uint16_t id2, uint16_t id3,
-                                uint16_t unlock_addr0, uint16_t unlock_addr1,
-                                int be);
+                                uint16_t unlock_addr0, uint16_t unlock_addr1);
 
 /* nand.c */
 DeviceState *nand_init(BlockDriverState *bdrv, int manf_id, int chip_id);
diff --git a/hw/gumstix.c b/hw/gumstix.c
index 853f7e1..d3a4bb4 100644
--- a/hw/gumstix.c
+++ b/hw/gumstix.c
@@ -48,7 +48,8 @@ static void connex_init(ram_addr_t ram_size,
 {
     PXA2xxState *cpu;
     DriveInfo *dinfo;
-    int be;
+    const MemoryRegionOps *flash_ops;
+    MemoryRegion *flash = g_new(MemoryRegion, 1);
 
     uint32_t connex_rom = 0x01000000;
     uint32_t connex_ram = 0x04000000;
@@ -63,14 +64,15 @@ static void connex_init(ram_addr_t ram_size,
     }
 
 #ifdef TARGET_WORDS_BIGENDIAN
-    be = 1;
+    flash_ops = &pflash_cfi01_ops_be;
 #else
-    be = 0;
+    flash_ops = &pflash_cfi01_ops_le;
 #endif
-    if (!pflash_cfi01_register(0x00000000, qemu_ram_alloc(NULL, "connext.rom",
-                                                          connex_rom),
+    memory_region_init_rom_device(flash, flash_ops,
+                                  NULL, "connext.rom", connex_rom);
+    if (!pflash_cfi01_register(0x00000000, flash,
                                dinfo->bdrv, sector_len, connex_rom / sector_len,
-                               2, 0, 0, 0, 0, be)) {
+                               2, 0, 0, 0, 0)) {
         fprintf(stderr, "qemu: Error registering flash memory.\n");
         exit(1);
     }
@@ -87,7 +89,8 @@ static void verdex_init(ram_addr_t ram_size,
 {
     PXA2xxState *cpu;
     DriveInfo *dinfo;
-    int be;
+    MemoryRegion *flash = g_new(MemoryRegion, 1);
+    const MemoryRegionOps *flash_ops;
 
     uint32_t verdex_rom = 0x02000000;
     uint32_t verdex_ram = 0x10000000;
@@ -102,14 +105,15 @@ static void verdex_init(ram_addr_t ram_size,
     }
 
 #ifdef TARGET_WORDS_BIGENDIAN
-    be = 1;
+    flash_ops = &pflash_cfi01_ops_be;
 #else
-    be = 0;
+    flash_ops = &pflash_cfi01_ops_le;
 #endif
-    if (!pflash_cfi01_register(0x00000000, qemu_ram_alloc(NULL, "verdex.rom",
-                                                          verdex_rom),
+    memory_region_init_rom_device(flash, flash_ops,
+                                  NULL, "verdex.rom", verdex_rom);
+    if (!pflash_cfi01_register(0x00000000, flash,
                                dinfo->bdrv, sector_len, verdex_rom / sector_len,
-                               2, 0, 0, 0, 0, be)) {
+                               2, 0, 0, 0, 0)) {
         fprintf(stderr, "qemu: Error registering flash memory.\n");
         exit(1);
     }
diff --git a/hw/lm32_boards.c b/hw/lm32_boards.c
index d18aad7..f032bc0 100644
--- a/hw/lm32_boards.c
+++ b/hw/lm32_boards.c
@@ -77,7 +77,7 @@ static void lm32_evr_init(ram_addr_t ram_size_not_used,
     CPUState *env;
     DriveInfo *dinfo;
     ram_addr_t phys_ram;
-    ram_addr_t phys_flash;
+    MemoryRegion *phys_flash = g_new(MemoryRegion, 1);
     qemu_irq *cpu_irq, irq[32];
     ResetInfo *reset_info;
     int i;
@@ -108,13 +108,14 @@ static void lm32_evr_init(ram_addr_t ram_size_not_used,
     phys_ram = qemu_ram_alloc(NULL, "lm32_evr.sdram", ram_size);
     cpu_register_physical_memory(ram_base, ram_size, phys_ram | IO_MEM_RAM);
 
-    phys_flash = qemu_ram_alloc(NULL, "lm32_evr.flash", flash_size);
+    memory_region_init_rom_device(phys_flash, &pflash_cfi02_ops_be,
+                                  NULL, "lm32_evr.flash", flash_size);
     dinfo = drive_get(IF_PFLASH, 0, 0);
     /* Spansion S29NS128P */
     pflash_cfi02_register(flash_base, phys_flash,
                           dinfo ? dinfo->bdrv : NULL, flash_sector_size,
                           flash_size / flash_sector_size, 1, 2,
-                          0x01, 0x7e, 0x43, 0x00, 0x555, 0x2aa, 1);
+                          0x01, 0x7e, 0x43, 0x00, 0x555, 0x2aa);
 
     /* create irq lines */
     cpu_irq = qemu_allocate_irqs(cpu_irq_handler, env, 1);
@@ -165,7 +166,7 @@ static void lm32_uclinux_init(ram_addr_t ram_size_not_used,
     CPUState *env;
     DriveInfo *dinfo;
     ram_addr_t phys_ram;
-    ram_addr_t phys_flash;
+    MemoryRegion *phys_flash = g_new(MemoryRegion, 1);
     qemu_irq *cpu_irq, irq[32];
     HWSetup *hw;
     ResetInfo *reset_info;
@@ -203,13 +204,14 @@ static void lm32_uclinux_init(ram_addr_t ram_size_not_used,
     phys_ram = qemu_ram_alloc(NULL, "lm32_uclinux.sdram", ram_size);
     cpu_register_physical_memory(ram_base, ram_size, phys_ram | IO_MEM_RAM);
 
-    phys_flash = qemu_ram_alloc(NULL, "lm32_uclinux.flash", flash_size);
+    memory_region_init_rom_device(phys_flash, &pflash_cfi01_ops_be,
+                                  NULL, "lm32_uclinux.flash", flash_size);
     dinfo = drive_get(IF_PFLASH, 0, 0);
     /* Spansion S29NS128P */
     pflash_cfi02_register(flash_base, phys_flash,
                           dinfo ? dinfo->bdrv : NULL, flash_sector_size,
                           flash_size / flash_sector_size, 1, 2,
-                          0x01, 0x7e, 0x43, 0x00, 0x555, 0x2aa, 1);
+                          0x01, 0x7e, 0x43, 0x00, 0x555, 0x2aa);
 
     /* create irq lines */
     cpu_irq = qemu_allocate_irqs(cpu_irq_handler, env, 1);
diff --git a/hw/mainstone.c b/hw/mainstone.c
index 4792f0e..78af41b 100644
--- a/hw/mainstone.c
+++ b/hw/mainstone.c
@@ -101,7 +101,8 @@ static void mainstone_common_init(ram_addr_t ram_size,
     DeviceState *mst_irq;
     DriveInfo *dinfo;
     int i;
-    int be;
+    MemoryRegion *flashes = g_new(MemoryRegion, 2);
+    const MemoryRegionOps *flash_ops;
 
     if (!cpu_model)
         cpu_model = "pxa270-c5";
@@ -113,9 +114,9 @@ static void mainstone_common_init(ram_addr_t ram_size,
                                    MAINSTONE_ROM) | IO_MEM_ROM);
 
 #ifdef TARGET_WORDS_BIGENDIAN
-    be = 1;
+    flash_ops = &pflash_cfi01_ops_be;
 #else
-    be = 0;
+    flash_ops = &pflash_cfi01_ops_le;
 #endif
     /* There are two 32MiB flash devices on the board */
     for (i = 0; i < 2; i ++) {
@@ -126,13 +127,14 @@ static void mainstone_common_init(ram_addr_t ram_size,
             exit(1);
         }
 
+        memory_region_init_rom_device(&flashes[i], flash_ops,
+                                      NULL, (i ? "mainstone.flash1"
+                                               : "mainstone.flash0"),
+                                      MAINSTONE_FLASH);
         if (!pflash_cfi01_register(mainstone_flash_base[i],
-                                   qemu_ram_alloc(NULL, i ? "mainstone.flash1" :
-                                                  "mainstone.flash0",
-                                                  MAINSTONE_FLASH),
-                                   dinfo->bdrv, sector_len,
-                                   MAINSTONE_FLASH / sector_len, 4, 0, 0, 0, 0,
-                                   be)) {
+                                   &flashes[i], dinfo->bdrv, sector_len,
+                                   MAINSTONE_FLASH / sector_len, 4, 0, 0, 0,
+                                   0)) {
             fprintf(stderr, "qemu: Error registering flash memory.\n");
             exit(1);
         }
diff --git a/hw/milkymist.c b/hw/milkymist.c
index 93288c8..092d8b0 100644
--- a/hw/milkymist.c
+++ b/hw/milkymist.c
@@ -82,7 +82,7 @@ milkymist_init(ram_addr_t ram_size_not_used,
     int kernel_size;
     DriveInfo *dinfo;
     ram_addr_t phys_sdram;
-    ram_addr_t phys_flash;
+    MemoryRegion *phys_flash = g_new(MemoryRegion, 1);
     qemu_irq irq[32], *cpu_irq;
     int i;
     char *bios_filename;
@@ -113,13 +113,14 @@ milkymist_init(ram_addr_t ram_size_not_used,
     cpu_register_physical_memory(sdram_base, sdram_size,
             phys_sdram | IO_MEM_RAM);
 
-    phys_flash = qemu_ram_alloc(NULL, "milkymist.flash", flash_size);
+    memory_region_init_rom_device(phys_flash, &pflash_cfi01_ops_be,
+                                  NULL, "milkymist.flash", flash_size);
     dinfo = drive_get(IF_PFLASH, 0, 0);
     /* Numonyx JS28F256J3F105 */
     pflash_cfi01_register(flash_base, phys_flash,
                           dinfo ? dinfo->bdrv : NULL, flash_sector_size,
                           flash_size / flash_sector_size, 2,
-                          0x00, 0x89, 0x00, 0x1d, 1);
+                          0x00, 0x89, 0x00, 0x1d);
 
     /* create irq lines */
     cpu_irq = qemu_allocate_irqs(cpu_irq_handler, env, 1);
diff --git a/hw/mips_malta.c b/hw/mips_malta.c
index 86a8ba0..b5c9bcf 100644
--- a/hw/mips_malta.c
+++ b/hw/mips_malta.c
@@ -46,6 +46,7 @@
 #include "elf.h"
 #include "mc146818rtc.h"
 #include "blockdev.h"
+#include "exec-memory.h"
 
 //#define DEBUG_BOARD_INIT
 
@@ -762,7 +763,10 @@ void mips_malta_init (ram_addr_t ram_size,
 {
     char *filename;
     ram_addr_t ram_offset;
-    ram_addr_t bios_offset;
+    MemoryRegion *address_space_mem = get_system_memory();
+    MemoryRegion *bios = g_new(MemoryRegion, 1);
+    MemoryRegion *bios_1e0 = g_new(MemoryRegion, 1);
+    MemoryRegion *bios_1fc = g_new(MemoryRegion, 1);
     target_long bios_size;
     int64_t kernel_entry;
     PCIBus *pci_bus;
@@ -777,7 +781,7 @@ void mips_malta_init (ram_addr_t ram_size,
     DriveInfo *fd[MAX_FD];
     int fl_idx = 0;
     int fl_sectors = 0;
-    int be;
+    const MemoryRegionOps *bios_ops;
 
     /* Make sure the first 3 serial ports are associated with a device. */
     for(i = 0; i < 3; i++) {
@@ -810,23 +814,24 @@ void mips_malta_init (ram_addr_t ram_size,
                 ((unsigned int)ram_size / (1 << 20)));
         exit(1);
     }
-    ram_offset = qemu_ram_alloc(NULL, "mips_malta.ram", ram_size);
-    bios_offset = qemu_ram_alloc(NULL, "mips_malta.bios", BIOS_SIZE);
+#ifdef TARGET_WORDS_BIGENDIAN
+    bios_ops = &pflash_cfi01_ops_be;
+#else
+    bios_ops = &pflash_cfi01_ops_le;
+#endif
 
+    ram_offset = qemu_ram_alloc(NULL, "mips_malta.ram", ram_size);
+    memory_region_init_rom_device(bios, bios_ops, NULL,
+                                  "mips_malta.bios", BIOS_SIZE);
 
     cpu_register_physical_memory(0, ram_size, ram_offset | IO_MEM_RAM);
 
     /* Map the bios at two physical locations, as on the real board. */
-    cpu_register_physical_memory(0x1e000000LL,
-                                 BIOS_SIZE, bios_offset | IO_MEM_ROM);
-    cpu_register_physical_memory(0x1fc00000LL,
-                                 BIOS_SIZE, bios_offset | IO_MEM_ROM);
+    memory_region_init_alias(bios_1e0, "bios-1e0", bios, 0, BIOS_SIZE);
+    memory_region_add_subregion(address_space_mem, 0x1e000000LL, bios_1e0);
+    memory_region_init_alias(bios_1fc, "bios-1fc", bios, 0, BIOS_SIZE);
+    memory_region_add_subregion(address_space_mem, 0x1fc00000LL, bios_1fc);
 
-#ifdef TARGET_WORDS_BIGENDIAN
-    be = 1;
-#else
-    be = 0;
-#endif
     /* FPGA */
     malta_fpga_init(0x1f000000LL, env->irq[2], serial_hds[2]);
 
@@ -838,7 +843,7 @@ void mips_malta_init (ram_addr_t ram_size,
         loaderparams.kernel_cmdline = kernel_cmdline;
         loaderparams.initrd_filename = initrd_filename;
         kernel_entry = load_kernel();
-        write_bootloader(env, qemu_get_ram_ptr(bios_offset), kernel_entry);
+        write_bootloader(env, memory_region_get_ram_ptr(bios), kernel_entry);
     } else {
         dinfo = drive_get(IF_PFLASH, 0, fl_idx);
         if (dinfo) {
@@ -847,13 +852,13 @@ void mips_malta_init (ram_addr_t ram_size,
             fl_sectors = bios_size >> 16;
 #ifdef DEBUG_BOARD_INIT
             printf("Register parallel flash %d size " TARGET_FMT_lx " at "
-                   "offset %08lx addr %08llx '%s' %x\n",
-                   fl_idx, bios_size, bios_offset, 0x1e000000LL,
+                   "addr %08llx '%s' %x\n",
+                   fl_idx, bios_size, 0x1e000000LL,
                    bdrv_get_device_name(dinfo->bdrv), fl_sectors);
 #endif
-            pflash_cfi01_register(0x1e000000LL, bios_offset,
+            pflash_cfi01_register(0x1e000000LL, bios,
                                   dinfo->bdrv, 65536, fl_sectors,
-                                  4, 0x0000, 0x0000, 0x0000, 0x0000, be);
+                                  4, 0x0000, 0x0000, 0x0000, 0x0000);
             fl_idx++;
         } else {
             /* Load a BIOS image. */
@@ -878,7 +883,7 @@ void mips_malta_init (ram_addr_t ram_size,
            a neat trick which allows bi-endian firmware. */
 #ifndef TARGET_WORDS_BIGENDIAN
         {
-            uint32_t *addr = qemu_get_ram_ptr(bios_offset);;
+            uint32_t *addr = memory_region_get_ram_ptr(bios);
             uint32_t *end = addr + bios_size;
             while (addr < end) {
                 bswap32s(addr);
@@ -890,7 +895,7 @@ void mips_malta_init (ram_addr_t ram_size,
     /* Board ID = 0x420 (Malta Board with CoreLV)
        XXX: theoretically 0x1e000010 should map to flash and 0x1fc00010 should
        map to the board ID. */
-    stl_p(qemu_get_ram_ptr(bios_offset) + 0x10, 0x00000420);
+    stl_p(memory_region_get_ram_ptr(bios) + 0x10, 0x00000420);
 
     /* Init internal devices */
     cpu_mips_irq_init_cpu(env);
diff --git a/hw/mips_r4k.c b/hw/mips_r4k.c
index 9d90568..51dc868 100644
--- a/hw/mips_r4k.c
+++ b/hw/mips_r4k.c
@@ -23,6 +23,7 @@
 #include "elf.h"
 #include "mc146818rtc.h"
 #include "blockdev.h"
+#include "exec-memory.h"
 
 #define MAX_IDE_BUS 2
 
@@ -163,7 +164,8 @@ void mips_r4k_init (ram_addr_t ram_size,
 {
     char *filename;
     ram_addr_t ram_offset;
-    ram_addr_t bios_offset;
+    MemoryRegion *address_space_mem = get_system_memory();
+    MemoryRegion *bios = g_new(MemoryRegion, 1);
     int bios_size;
     CPUState *env;
     ResetData *reset_info;
@@ -227,18 +229,20 @@ void mips_r4k_init (ram_addr_t ram_size,
     be = 0;
 #endif
     if ((bios_size > 0) && (bios_size <= BIOS_SIZE)) {
-        bios_offset = qemu_ram_alloc(NULL, "mips_r4k.bios", BIOS_SIZE);
-	cpu_register_physical_memory(0x1fc00000, BIOS_SIZE,
-                                     bios_offset | IO_MEM_ROM);
-
+        memory_region_init_ram(bios, NULL, "mips_r4k.bios", BIOS_SIZE);
+        memory_region_set_readonly(bios, true);
+        memory_region_add_subregion(address_space_mem, 0x1fc00000, bios);
         load_image_targphys(filename, 0x1fc00000, BIOS_SIZE);
     } else if ((dinfo = drive_get(IF_PFLASH, 0, 0)) != NULL) {
         uint32_t mips_rom = 0x00400000;
-        bios_offset = qemu_ram_alloc(NULL, "mips_r4k.bios", mips_rom);
-        if (!pflash_cfi01_register(0x1fc00000, bios_offset,
+        memory_region_init_rom_device(bios,
+                                      (be ? &pflash_cfi01_ops_be
+                                          : &pflash_cfi01_ops_le),
+                                      NULL, "mips_r4k.bios", mips_rom);
+        if (!pflash_cfi01_register(0x1fc00000, bios,
                                    dinfo->bdrv, sector_len,
                                    mips_rom / sector_len,
-                                   4, 0, 0, 0, 0, be)) {
+                                   4, 0, 0, 0, 0)) {
             fprintf(stderr, "qemu: Error registering flash memory.\n");
 	}
     }
diff --git a/hw/musicpal.c b/hw/musicpal.c
index 63dd391..5e74ee7 100644
--- a/hw/musicpal.c
+++ b/hw/musicpal.c
@@ -1502,6 +1502,7 @@ static void musicpal_init(ram_addr_t ram_size,
     unsigned long flash_size;
     DriveInfo *dinfo;
     ram_addr_t sram_off;
+    MemoryRegion *flash = g_new(MemoryRegion, 1);
 
     if (!cpu_model) {
         cpu_model = "arm926";
@@ -1565,21 +1566,23 @@ static void musicpal_init(ram_addr_t ram_size,
          * image is smaller than 32 MB.
          */
 #ifdef TARGET_WORDS_BIGENDIAN
-        pflash_cfi02_register(0-MP_FLASH_SIZE_MAX, qemu_ram_alloc(NULL,
-                              "musicpal.flash", flash_size),
+        memory_region_init_rom_device(flash, &pflash_cfi02_ops_be,
+                                      NULL, "musicpal.flash", flash_size);
+        pflash_cfi02_register(0-MP_FLASH_SIZE_MAX, flash,
                               dinfo->bdrv, 0x10000,
                               (flash_size + 0xffff) >> 16,
                               MP_FLASH_SIZE_MAX / flash_size,
                               2, 0x00BF, 0x236D, 0x0000, 0x0000,
-                              0x5555, 0x2AAA, 1);
+                              0x5555, 0x2AAA);
 #else
-        pflash_cfi02_register(0-MP_FLASH_SIZE_MAX, qemu_ram_alloc(NULL,
-                              "musicpal.flash", flash_size),
+        memory_region_init_rom_device(flash, &pflash_cfi02_ops_le,
+                                      NULL, "musicpal.flash", flash_size);
+        pflash_cfi02_register(0-MP_FLASH_SIZE_MAX, flash,
                               dinfo->bdrv, 0x10000,
                               (flash_size + 0xffff) >> 16,
                               MP_FLASH_SIZE_MAX / flash_size,
                               2, 0x00BF, 0x236D, 0x0000, 0x0000,
-                              0x5555, 0x2AAA, 0);
+                              0x5555, 0x2AAA);
 #endif
 
     }
diff --git a/hw/omap_sx1.c b/hw/omap_sx1.c
index a7b687b..70364f4 100644
--- a/hw/omap_sx1.c
+++ b/hw/omap_sx1.c
@@ -129,7 +129,8 @@ static void sx1_init(ram_addr_t ram_size,
     DriveInfo *dinfo;
     int fl_idx;
     uint32_t flash_size = flash0_size;
-    int be;
+    const MemoryRegionOps *flash_ops;
+    MemoryRegion *flash = g_new(MemoryRegion, 2);
 
     if (version == 2) {
         flash_size = flash2_size;
@@ -155,17 +156,18 @@ static void sx1_init(ram_addr_t ram_size,
 
     fl_idx = 0;
 #ifdef TARGET_WORDS_BIGENDIAN
-    be = 1;
+    flash_ops = &pflash_cfi01_ops_be;
 #else
-    be = 0;
+    flash_ops = &pflash_cfi01_ops_le;
 #endif
 
     if ((dinfo = drive_get(IF_PFLASH, 0, fl_idx)) != NULL) {
-        if (!pflash_cfi01_register(OMAP_CS0_BASE, qemu_ram_alloc(NULL,
-                                   "omap_sx1.flash0-1", flash_size),
+        memory_region_init_rom_device(&flash[0], flash_ops,
+                                      NULL, "omap_sx1.flash0-1", flash_size);
+        if (!pflash_cfi01_register(OMAP_CS0_BASE, &flash[0],
                                    dinfo->bdrv, sector_size,
                                    flash_size / sector_size,
-                                   4, 0, 0, 0, 0, be)) {
+                                   4, 0, 0, 0, 0)) {
             fprintf(stderr, "qemu: Error registering flash memory %d.\n",
                            fl_idx);
         }
@@ -182,11 +184,12 @@ static void sx1_init(ram_addr_t ram_size,
         cpu_register_physical_memory(OMAP_CS1_BASE + flash1_size,
                         OMAP_CS1_SIZE - flash1_size, io);
 
-        if (!pflash_cfi01_register(OMAP_CS1_BASE, qemu_ram_alloc(NULL,
-                                   "omap_sx1.flash1-1", flash1_size),
+        memory_region_init_rom_device(&flash[1], flash_ops,
+                                      NULL, "omap_sx1.flash1-1", flash1_size);
+        if (!pflash_cfi01_register(OMAP_CS1_BASE, &flash[1],
                                    dinfo->bdrv, sector_size,
                                    flash1_size / sector_size,
-                                   4, 0, 0, 0, 0, be)) {
+                                   4, 0, 0, 0, 0)) {
             fprintf(stderr, "qemu: Error registering flash memory %d.\n",
                            fl_idx);
         }
diff --git a/hw/petalogix_ml605_mmu.c b/hw/petalogix_ml605_mmu.c
index e3ca310..257fcca 100644
--- a/hw/petalogix_ml605_mmu.c
+++ b/hw/petalogix_ml605_mmu.c
@@ -149,7 +149,7 @@ petalogix_ml605_init(ram_addr_t ram_size,
     target_phys_addr_t ddr_base = MEMORY_BASEADDR;
     ram_addr_t phys_lmb_bram;
     ram_addr_t phys_ram;
-    ram_addr_t phys_flash;
+    MemoryRegion *phys_flash = g_new(MemoryRegion, 1);
     qemu_irq irq[32], *cpu_irq;
 
     /* init CPUs */
@@ -169,14 +169,15 @@ petalogix_ml605_init(ram_addr_t ram_size,
     phys_ram = qemu_ram_alloc(NULL, "petalogix_ml605.ram", ram_size);
     cpu_register_physical_memory(ddr_base, ram_size, phys_ram | IO_MEM_RAM);
 
-    phys_flash = qemu_ram_alloc(NULL, "petalogix_ml605.flash", FLASH_SIZE);
+    memory_region_init_rom_device(phys_flash, &pflash_cfi01_ops_le,
+                                  NULL, "petalogix_ml605.flash", FLASH_SIZE);
     dinfo = drive_get(IF_PFLASH, 0, 0);
     /* 5th parameter 2 means bank-width
      * 10th paremeter 0 means little-endian */
     pflash_cfi01_register(FLASH_BASEADDR, phys_flash,
                           dinfo ? dinfo->bdrv : NULL, (64 * 1024),
                           FLASH_SIZE >> 16,
-                          2, 0x89, 0x18, 0x0000, 0x0, 0);
+                          2, 0x89, 0x18, 0x0000, 0x0);
 
 
     cpu_irq = microblaze_pic_init_cpu(env);
diff --git a/hw/petalogix_s3adsp1800_mmu.c b/hw/petalogix_s3adsp1800_mmu.c
index a43fb4c..1481745 100644
--- a/hw/petalogix_s3adsp1800_mmu.c
+++ b/hw/petalogix_s3adsp1800_mmu.c
@@ -127,7 +127,7 @@ petalogix_s3adsp1800_init(ram_addr_t ram_size,
     target_phys_addr_t ddr_base = 0x90000000;
     ram_addr_t phys_lmb_bram;
     ram_addr_t phys_ram;
-    ram_addr_t phys_flash;
+    MemoryRegion *phys_flash = g_new(MemoryRegion, 1);
     qemu_irq irq[32], *cpu_irq;
 
     /* init CPUs */
@@ -148,12 +148,14 @@ petalogix_s3adsp1800_init(ram_addr_t ram_size,
     phys_ram = qemu_ram_alloc(NULL, "petalogix_s3adsp1800.ram", ram_size);
     cpu_register_physical_memory(ddr_base, ram_size, phys_ram | IO_MEM_RAM);
 
-    phys_flash = qemu_ram_alloc(NULL, "petalogix_s3adsp1800.flash", FLASH_SIZE);
+    memory_region_init_rom_device(phys_flash, &pflash_cfi01_ops_be,
+                                  NULL, "petalogix_s3adsp1800.flash",
+                                  FLASH_SIZE);
     dinfo = drive_get(IF_PFLASH, 0, 0);
     pflash_cfi01_register(0xa0000000, phys_flash,
                           dinfo ? dinfo->bdrv : NULL, (64 * 1024),
                           FLASH_SIZE >> 16,
-                          1, 0x89, 0x18, 0x0000, 0x0, 1);
+                          1, 0x89, 0x18, 0x0000, 0x0);
 
     cpu_irq = microblaze_pic_init_cpu(env);
     dev = xilinx_intc_create(0x81800000, cpu_irq[0], 2);
diff --git a/hw/pflash_cfi01.c b/hw/pflash_cfi01.c
index 90e1301..2144c6a 100644
--- a/hw/pflash_cfi01.c
+++ b/hw/pflash_cfi01.c
@@ -40,6 +40,7 @@
 #include "flash.h"
 #include "block.h"
 #include "qemu-timer.h"
+#include "exec-memory.h"
 
 #define PFLASH_BUG(fmt, ...) \
 do { \
@@ -74,8 +75,7 @@ struct pflash_t {
     target_phys_addr_t counter;
     unsigned int writeblock_size;
     QEMUTimer *timer;
-    ram_addr_t off;
-    int fl_mem;
+    MemoryRegion *mem;
     void *storage;
 };
 
@@ -89,8 +89,7 @@ static void pflash_timer (void *opaque)
     if (pfl->bypass) {
         pfl->wcycle = 2;
     } else {
-        cpu_register_physical_memory(pfl->base, pfl->total_len,
-                        pfl->off | IO_MEM_ROMD | pfl->fl_mem);
+        memory_region_rom_device_set_readable(pfl->mem, true);
         pfl->wcycle = 0;
     }
     pfl->cmd = 0;
@@ -263,7 +262,7 @@ static void pflash_write(pflash_t *pfl, target_phys_addr_t offset,
 
     if (!pfl->wcycle) {
         /* Set the device in I/O access mode */
-        cpu_register_physical_memory(pfl->base, pfl->total_len, pfl->fl_mem);
+        memory_region_rom_device_set_readable(pfl->mem, false);
     }
 
     switch (pfl->wcycle) {
@@ -422,8 +421,7 @@ static void pflash_write(pflash_t *pfl, target_phys_addr_t offset,
            __func__, offset, pfl->wcycle, pfl->cmd, value);
 
  reset_flash:
-    cpu_register_physical_memory(pfl->base, pfl->total_len,
-                    pfl->off | IO_MEM_ROMD | pfl->fl_mem);
+    memory_region_rom_device_set_readable(pfl->mem, true);
 
     pfl->bypass = 0;
     pfl->wcycle = 0;
@@ -514,28 +512,20 @@ static void pflash_writel_le(void *opaque, target_phys_addr_t addr,
     pflash_write(pfl, addr, value, 4, 0);
 }
 
-static CPUWriteMemoryFunc * const pflash_write_ops_be[] = {
-    &pflash_writeb_be,
-    &pflash_writew_be,
-    &pflash_writel_be,
+const MemoryRegionOps pflash_cfi01_ops_be = {
+    .old_mmio = {
+        .read = { pflash_readb_be, pflash_readw_be, pflash_readl_be, },
+        .write = { pflash_writeb_be, pflash_writew_be, pflash_writel_be, },
+    },
+    .endianness = DEVICE_NATIVE_ENDIAN,
 };
 
-static CPUReadMemoryFunc * const pflash_read_ops_be[] = {
-    &pflash_readb_be,
-    &pflash_readw_be,
-    &pflash_readl_be,
-};
-
-static CPUWriteMemoryFunc * const pflash_write_ops_le[] = {
-    &pflash_writeb_le,
-    &pflash_writew_le,
-    &pflash_writel_le,
-};
-
-static CPUReadMemoryFunc * const pflash_read_ops_le[] = {
-    &pflash_readb_le,
-    &pflash_readw_le,
-    &pflash_readl_le,
+const MemoryRegionOps pflash_cfi01_ops_le = {
+    .old_mmio = {
+        .read = { pflash_readb_le, pflash_readw_le, pflash_readl_le, },
+        .write = { pflash_writeb_le, pflash_writew_le, pflash_writel_le, },
+    },
+    .endianness = DEVICE_NATIVE_ENDIAN,
 };
 
 /* Count trailing zeroes of a 32 bits quantity */
@@ -574,12 +564,11 @@ static int ctz32 (uint32_t n)
     return ret;
 }
 
-pflash_t *pflash_cfi01_register(target_phys_addr_t base, ram_addr_t off,
+pflash_t *pflash_cfi01_register(target_phys_addr_t base, MemoryRegion *mem,
                                 BlockDriverState *bs, uint32_t sector_len,
                                 int nb_blocs, int width,
                                 uint16_t id0, uint16_t id1,
-                                uint16_t id2, uint16_t id3,
-                                int be)
+                                uint16_t id2, uint16_t id3)
 {
     pflash_t *pfl;
     target_phys_addr_t total_len;
@@ -597,26 +586,16 @@ pflash_t *pflash_cfi01_register(target_phys_addr_t base, ram_addr_t off,
     pfl = g_malloc0(sizeof(pflash_t));
 
     /* FIXME: Allocate ram ourselves.  */
-    pfl->storage = qemu_get_ram_ptr(off);
-    if (be) {
-        pfl->fl_mem = cpu_register_io_memory(pflash_read_ops_be,
-                                             pflash_write_ops_be, pfl,
-                                             DEVICE_NATIVE_ENDIAN);
-    } else {
-        pfl->fl_mem = cpu_register_io_memory(pflash_read_ops_le,
-                                             pflash_write_ops_le, pfl,
-                                             DEVICE_NATIVE_ENDIAN);
-    }
-    pfl->off = off;
-    cpu_register_physical_memory(base, total_len,
-                    off | pfl->fl_mem | IO_MEM_ROMD);
+    pfl->storage = memory_region_get_ram_ptr(mem);
+    pfl->mem = mem;
+    memory_region_add_subregion(get_system_memory(), base, mem);
 
     pfl->bs = bs;
     if (pfl->bs) {
         /* read the initial flash content */
         ret = bdrv_read(pfl->bs, 0, pfl->storage, total_len >> 9);
         if (ret < 0) {
-            cpu_unregister_io_memory(pfl->fl_mem);
+            memory_region_del_subregion(get_system_memory(), mem);
             g_free(pfl);
             return NULL;
         }
diff --git a/hw/pflash_cfi02.c b/hw/pflash_cfi02.c
index ac5115e..e7e0408 100644
--- a/hw/pflash_cfi02.c
+++ b/hw/pflash_cfi02.c
@@ -39,6 +39,7 @@
 #include "flash.h"
 #include "qemu-timer.h"
 #include "block.h"
+#include "exec-memory.h"
 
 //#define PFLASH_DEBUG
 #ifdef PFLASH_DEBUG
@@ -69,25 +70,39 @@ struct pflash_t {
     uint8_t cfi_len;
     uint8_t cfi_table[0x52];
     QEMUTimer *timer;
-    ram_addr_t off;
-    int fl_mem;
+    /* The device replicates the flash memory across its memory space.  Emulate
+     * that by having a container (.mem) filled with an array of aliases
+     * (.mem_mappings) pointing to the flash memory (.orig_mem).
+     */
+    MemoryRegion mem;
+    MemoryRegion *mem_mappings;    /* array; one per mapping */
+    MemoryRegion *orig_mem;
     int rom_mode;
     int read_counter; /* used for lazy switch-back to rom mode */
     void *storage;
 };
 
-static void pflash_register_memory(pflash_t *pfl, int rom_mode)
+/*
+ * Set up replicated mappings of the same region.
+ */
+static void pflash_setup_mappings(pflash_t *pfl, MemoryRegion *mem)
 {
-    unsigned long phys_offset = pfl->fl_mem;
-    int i;
-
-    if (rom_mode)
-        phys_offset |= pfl->off | IO_MEM_ROMD;
-    pfl->rom_mode = rom_mode;
+    unsigned i;
+    target_phys_addr_t size = memory_region_size(mem);
+
+    pfl->orig_mem = mem;
+    memory_region_init(&pfl->mem, "pflash", pfl->mappings * size);
+    pfl->mem_mappings = g_new(MemoryRegion, pfl->mappings);
+    for (i = 0; i < pfl->mappings; ++i) {
+        memory_region_init_alias(&pfl->mem_mappings[i], "pflash-alias", mem,
+                                 0, size);
+        memory_region_add_subregion(&pfl->mem, i * size, &pfl->mem_mappings[i]);
+    }
+}
 
-    for (i = 0; i < pfl->mappings; i++)
-        cpu_register_physical_memory(pfl->base + i * pfl->chip_len,
-                                     pfl->chip_len, phys_offset);
+static void pflash_register_memory(pflash_t *pfl, int rom_mode)
+{
+    memory_region_rom_device_set_readable(pfl->orig_mem, rom_mode);
 }
 
 static void pflash_timer (void *opaque)
@@ -538,28 +553,20 @@ static void pflash_writel_le(void *opaque, target_phys_addr_t addr,
     pflash_write(pfl, addr, value, 4, 0);
 }
 
-static CPUWriteMemoryFunc * const pflash_write_ops_be[] = {
-    &pflash_writeb_be,
-    &pflash_writew_be,
-    &pflash_writel_be,
-};
-
-static CPUReadMemoryFunc * const pflash_read_ops_be[] = {
-    &pflash_readb_be,
-    &pflash_readw_be,
-    &pflash_readl_be,
+const MemoryRegionOps pflash_cfi02_ops_be = {
+    .old_mmio = {
+        .read = { pflash_readb_be, pflash_readw_be, pflash_readl_be, },
+        .write = { pflash_writeb_be, pflash_writew_be, pflash_writel_be, },
+    },
+    .endianness = DEVICE_NATIVE_ENDIAN,
 };
 
-static CPUWriteMemoryFunc * const pflash_write_ops_le[] = {
-    &pflash_writeb_le,
-    &pflash_writew_le,
-    &pflash_writel_le,
-};
-
-static CPUReadMemoryFunc * const pflash_read_ops_le[] = {
-    &pflash_readb_le,
-    &pflash_readw_le,
-    &pflash_readl_le,
+const MemoryRegionOps pflash_cfi02_ops_le = {
+    .old_mmio = {
+        .read = { pflash_readb_le, pflash_readw_le, pflash_readl_le, },
+        .write = { pflash_writeb_le, pflash_writew_le, pflash_writel_le, },
+    },
+    .endianness = DEVICE_NATIVE_ENDIAN,
 };
 
 /* Count trailing zeroes of a 32 bits quantity */
@@ -598,13 +605,12 @@ static int ctz32 (uint32_t n)
     return ret;
 }
 
-pflash_t *pflash_cfi02_register(target_phys_addr_t base, ram_addr_t off,
+pflash_t *pflash_cfi02_register(target_phys_addr_t base, MemoryRegion *mem,
                                 BlockDriverState *bs, uint32_t sector_len,
                                 int nb_blocs, int nb_mappings, int width,
                                 uint16_t id0, uint16_t id1,
                                 uint16_t id2, uint16_t id3,
-                                uint16_t unlock_addr0, uint16_t unlock_addr1,
-                                int be)
+                                uint16_t unlock_addr0, uint16_t unlock_addr1)
 {
     pflash_t *pfl;
     int32_t chip_len;
@@ -619,31 +625,22 @@ pflash_t *pflash_cfi02_register(target_phys_addr_t base, ram_addr_t off,
 #endif
     pfl = g_malloc0(sizeof(pflash_t));
     /* FIXME: Allocate ram ourselves.  */
-    pfl->storage = qemu_get_ram_ptr(off);
-    if (be) {
-        pfl->fl_mem = cpu_register_io_memory(pflash_read_ops_be,
-                                             pflash_write_ops_be,
-                                             pfl, DEVICE_NATIVE_ENDIAN);
-    } else {
-        pfl->fl_mem = cpu_register_io_memory(pflash_read_ops_le,
-                                             pflash_write_ops_le,
-                                             pfl, DEVICE_NATIVE_ENDIAN);
-    }
-    pfl->off = off;
+    pfl->storage = memory_region_get_ram_ptr(mem);
     pfl->base = base;
     pfl->chip_len = chip_len;
     pfl->mappings = nb_mappings;
-    pflash_register_memory(pfl, 1);
     pfl->bs = bs;
     if (pfl->bs) {
         /* read the initial flash content */
         ret = bdrv_read(pfl->bs, 0, pfl->storage, chip_len >> 9);
         if (ret < 0) {
-            cpu_unregister_io_memory(pfl->fl_mem);
             g_free(pfl);
             return NULL;
         }
     }
+    pflash_setup_mappings(pfl, mem);
+    pfl->rom_mode = 1;
+    memory_region_add_subregion(get_system_memory(), pfl->base, &pfl->mem);
 #if 0 /* XXX: there should be a bit to set up read-only,
        *      the same way the hardware does (with WP pin).
        */
diff --git a/hw/ppc405_boards.c b/hw/ppc405_boards.c
index dec165e..1eb807c 100644
--- a/hw/ppc405_boards.c
+++ b/hw/ppc405_boards.c
@@ -32,6 +32,7 @@
 #include "qemu-log.h"
 #include "loader.h"
 #include "blockdev.h"
+#include "exec-memory.h"
 
 #define BIOS_FILENAME "ppc405_rom.bin"
 #define BIOS_SIZE (2048 * 1024)
@@ -181,7 +182,9 @@ static void ref405ep_init (ram_addr_t ram_size,
     ppc4xx_bd_info_t bd;
     CPUPPCState *env;
     qemu_irq *pic;
-    ram_addr_t sram_offset, bios_offset, bdloc;
+    ram_addr_t sram_offset, bdloc;
+    MemoryRegion *address_space_mem = get_system_memory();
+    MemoryRegion *bios = g_new(MemoryRegion, 1);
     MemoryRegion *ram_memories = g_malloc(2 * sizeof(*ram_memories));
     target_phys_addr_t ram_bases[2], ram_sizes[2];
     target_ulong sram_size;
@@ -224,18 +227,18 @@ static void ref405ep_init (ram_addr_t ram_size,
     dinfo = drive_get(IF_PFLASH, 0, fl_idx);
     if (dinfo) {
         bios_size = bdrv_getlength(dinfo->bdrv);
-        bios_offset = qemu_ram_alloc(NULL, "ef405ep.bios", bios_size);
+        memory_region_init_rom_device(bios, &pflash_cfi02_ops_be,
+                                      NULL, "ef405ep.bios", bios_size);
         fl_sectors = (bios_size + 65535) >> 16;
 #ifdef DEBUG_BOARD_INIT
         printf("Register parallel flash %d size %lx"
-               " at offset %08lx addr %lx '%s' %d\n",
-               fl_idx, bios_size, bios_offset, -bios_size,
+               " at addr %lx '%s' %d\n",
+               fl_idx, bios_size, -bios_size,
                bdrv_get_device_name(dinfo->bdrv), fl_sectors);
 #endif
-        pflash_cfi02_register((uint32_t)(-bios_size), bios_offset,
+        pflash_cfi02_register((uint32_t)(-bios_size), bios,
                               dinfo->bdrv, 65536, fl_sectors, 1,
-                              2, 0x0001, 0x22DA, 0x0000, 0x0000, 0x555, 0x2AA,
-                              1);
+                              2, 0x0001, 0x22DA, 0x0000, 0x0000, 0x555, 0x2AA);
         fl_idx++;
     } else
 #endif
@@ -243,12 +246,12 @@ static void ref405ep_init (ram_addr_t ram_size,
 #ifdef DEBUG_BOARD_INIT
         printf("Load BIOS from file\n");
 #endif
-        bios_offset = qemu_ram_alloc(NULL, "ef405ep.bios", BIOS_SIZE);
+        memory_region_init_ram(bios, NULL, "ef405ep.bios", BIOS_SIZE);
         if (bios_name == NULL)
             bios_name = BIOS_FILENAME;
         filename = qemu_find_file(QEMU_FILE_TYPE_BIOS, bios_name);
         if (filename) {
-            bios_size = load_image(filename, qemu_get_ram_ptr(bios_offset));
+            bios_size = load_image(filename, memory_region_get_ram_ptr(bios));
             g_free(filename);
         } else {
             bios_size = -1;
@@ -259,8 +262,9 @@ static void ref405ep_init (ram_addr_t ram_size,
             exit(1);
         }
         bios_size = (bios_size + 0xfff) & ~0xfff;
-        cpu_register_physical_memory((uint32_t)(-bios_size),
-                                     bios_size, bios_offset | IO_MEM_ROM);
+        memory_region_set_readonly(bios, true);
+        memory_region_add_subregion(address_space_mem, (uint32_t)(-bios_size),
+                                    bios);
     }
     /* Register FPGA */
 #ifdef DEBUG_BOARD_INIT
@@ -507,7 +511,9 @@ static void taihu_405ep_init(ram_addr_t ram_size,
 {
     char *filename;
     qemu_irq *pic;
-    ram_addr_t bios_offset;
+    MemoryRegion *address_space_mem = get_system_memory();
+    MemoryRegion *bios = g_new(MemoryRegion, 1);
+    MemoryRegion *flash = g_new(MemoryRegion, 1);
     MemoryRegion *ram_memories = g_malloc(2 * sizeof(*ram_memories));
     target_phys_addr_t ram_bases[2], ram_sizes[2];
     long bios_size;
@@ -544,17 +550,17 @@ static void taihu_405ep_init(ram_addr_t ram_size,
         /* XXX: should check that size is 2MB */
         //        bios_size = 2 * 1024 * 1024;
         fl_sectors = (bios_size + 65535) >> 16;
-        bios_offset = qemu_ram_alloc(NULL, "taihu_405ep.bios", bios_size);
+        memory_region_init_rom_device(bios, &pflash_cfi02_ops_be,
+                                      NULL, "taihu_405ep.bios", bios_size);
 #ifdef DEBUG_BOARD_INIT
         printf("Register parallel flash %d size %lx"
-               " at offset %08lx addr %lx '%s' %d\n",
-               fl_idx, bios_size, bios_offset, -bios_size,
+               " at addr %lx '%s' %d\n",
+               fl_idx, bios_size, -bios_size,
                bdrv_get_device_name(dinfo->bdrv), fl_sectors);
 #endif
-        pflash_cfi02_register((uint32_t)(-bios_size), bios_offset,
+        pflash_cfi02_register((uint32_t)(-bios_size), bios,
                               dinfo->bdrv, 65536, fl_sectors, 1,
-                              4, 0x0001, 0x22DA, 0x0000, 0x0000, 0x555, 0x2AA,
-                              1);
+                              4, 0x0001, 0x22DA, 0x0000, 0x0000, 0x555, 0x2AA);
         fl_idx++;
     } else
 #endif
@@ -564,10 +570,10 @@ static void taihu_405ep_init(ram_addr_t ram_size,
 #endif
         if (bios_name == NULL)
             bios_name = BIOS_FILENAME;
-        bios_offset = qemu_ram_alloc(NULL, "taihu_405ep.bios", BIOS_SIZE);
+        memory_region_init_ram(bios, NULL, "taihu_405ep.bios", BIOS_SIZE);
         filename = qemu_find_file(QEMU_FILE_TYPE_BIOS, bios_name);
         if (filename) {
-            bios_size = load_image(filename, qemu_get_ram_ptr(bios_offset));
+            bios_size = load_image(filename, memory_region_get_ram_ptr(bios));
             g_free(filename);
         } else {
             bios_size = -1;
@@ -578,8 +584,9 @@ static void taihu_405ep_init(ram_addr_t ram_size,
             exit(1);
         }
         bios_size = (bios_size + 0xfff) & ~0xfff;
-        cpu_register_physical_memory((uint32_t)(-bios_size),
-                                     bios_size, bios_offset | IO_MEM_ROM);
+        memory_region_set_readonly(bios, true);
+        memory_region_add_subregion(address_space_mem,
+                                    (uint32_t)(-bios_size), bios);
     }
     /* Register Linux flash */
     dinfo = drive_get(IF_PFLASH, 0, fl_idx);
@@ -590,15 +597,15 @@ static void taihu_405ep_init(ram_addr_t ram_size,
         fl_sectors = (bios_size + 65535) >> 16;
 #ifdef DEBUG_BOARD_INIT
         printf("Register parallel flash %d size %lx"
-               " at offset %08lx  addr " TARGET_FMT_lx " '%s'\n",
-               fl_idx, bios_size, bios_offset, (target_ulong)0xfc000000,
+               " at addr " TARGET_FMT_lx " '%s'\n",
+               fl_idx, bios_size, (target_ulong)0xfc000000,
                bdrv_get_device_name(dinfo->bdrv));
 #endif
-        bios_offset = qemu_ram_alloc(NULL, "taihu_405ep.flash", bios_size);
-        pflash_cfi02_register(0xfc000000, bios_offset,
+        memory_region_init_rom_device(flash, &pflash_cfi02_ops_be,
+                                      NULL, "taihu_405ep.flash", bios_size);
+        pflash_cfi02_register(0xfc000000, flash,
                               dinfo->bdrv, 65536, fl_sectors, 1,
-                              4, 0x0001, 0x22DA, 0x0000, 0x0000, 0x555, 0x2AA,
-                              1);
+                              4, 0x0001, 0x22DA, 0x0000, 0x0000, 0x555, 0x2AA);
         fl_idx++;
     }
     /* Register CLPD & LCD display */
diff --git a/hw/r2d.c b/hw/r2d.c
index 96a7ff8..41aa2c2 100644
--- a/hw/r2d.c
+++ b/hw/r2d.c
@@ -235,6 +235,7 @@ static void r2d_init(ram_addr_t ram_size,
     qemu_irq *irq;
     DriveInfo *dinfo;
     int i;
+    MemoryRegion *flash = g_new(MemoryRegion, 1);
 
     if (!cpu_model)
         cpu_model = "SH7751R";
@@ -267,11 +268,13 @@ static void r2d_init(ram_addr_t ram_size,
 
     /* onboard flash memory */
     dinfo = drive_get(IF_PFLASH, 0, 0);
-    pflash_cfi02_register(0x0, qemu_ram_alloc(NULL, "r2d.flash", FLASH_SIZE),
+    memory_region_init_rom_device(flash, &pflash_cfi02_ops_le,
+                                  NULL, "r2d.flash", FLASH_SIZE);
+    pflash_cfi02_register(0x0, flash,
                           dinfo ? dinfo->bdrv : NULL, (16 * 1024),
                           FLASH_SIZE >> 16,
                           1, 4, 0x0000, 0x0000, 0x0000, 0x0000,
-                          0x555, 0x2aa, 0);
+                          0x555, 0x2aa);
 
     /* NIC: rtl8139 on-board, and 2 slots. */
     for (i = 0; i < nb_nics; i++)
diff --git a/hw/virtex_ml507.c b/hw/virtex_ml507.c
index 333050c..aa9e512 100644
--- a/hw/virtex_ml507.c
+++ b/hw/virtex_ml507.c
@@ -196,7 +196,7 @@ static void virtex_init(ram_addr_t ram_size,
     target_phys_addr_t ram_base = 0;
     DriveInfo *dinfo;
     ram_addr_t phys_ram;
-    ram_addr_t phys_flash;
+    MemoryRegion *phys_flash = g_new(MemoryRegion, 1);
     qemu_irq irq[32], *cpu_irq;
     clk_setup_t clk_setup[7];
     int kernel_size;
@@ -215,12 +215,13 @@ static void virtex_init(ram_addr_t ram_size,
     phys_ram = qemu_ram_alloc(NULL, "ram", ram_size);
     cpu_register_physical_memory(ram_base, ram_size, phys_ram | IO_MEM_RAM);
 
-    phys_flash = qemu_ram_alloc(NULL, "virtex.flash", FLASH_SIZE);
+    memory_region_init_rom_device(phys_flash, &pflash_cfi01_ops_be,
+                                  NULL, "virtex.flash", FLASH_SIZE);
     dinfo = drive_get(IF_PFLASH, 0, 0);
     pflash_cfi01_register(0xfc000000, phys_flash,
                           dinfo ? dinfo->bdrv : NULL, (64 * 1024),
                           FLASH_SIZE >> 16,
-                          1, 0x89, 0x18, 0x0000, 0x0, 1);
+                          1, 0x89, 0x18, 0x0000, 0x0);
 
     cpu_irq = (qemu_irq *) &env->irq_inputs[PPC40x_INPUT_INT];
     dev = xilinx_intc_create(0x81800000, cpu_irq[0], 0);
diff --git a/hw/z2.c b/hw/z2.c
index f93a1bf..d7b8d53 100644
--- a/hw/z2.c
+++ b/hw/z2.c
@@ -280,10 +280,11 @@ static void z2_init(ram_addr_t ram_size,
     uint32_t sector_len = 0x10000;
     PXA2xxState *cpu;
     DriveInfo *dinfo;
-    int be;
+    const MemoryRegionOps *flash_ops;
     void *z2_lcd;
     i2c_bus *bus;
     DeviceState *wm;
+    MemoryRegion *flash = g_new(MemoryRegion, 1);
 
     if (!cpu_model) {
         cpu_model = "pxa270-c5";
@@ -293,9 +294,9 @@ static void z2_init(ram_addr_t ram_size,
     cpu = pxa270_init(z2_binfo.ram_size, cpu_model);
 
 #ifdef TARGET_WORDS_BIGENDIAN
-    be = 1;
+    flash_ops = &pflash_cfi01_ops_be;
 #else
-    be = 0;
+    flash_ops = &pflash_cfi01_ops_le;
 #endif
     dinfo = drive_get(IF_PFLASH, 0, 0);
     if (!dinfo) {
@@ -304,11 +305,11 @@ static void z2_init(ram_addr_t ram_size,
         exit(1);
     }
 
-    if (!pflash_cfi01_register(Z2_FLASH_BASE,
-                               qemu_ram_alloc(NULL, "z2.flash0", Z2_FLASH_SIZE),
+    memory_region_init_rom_device(flash, flash_ops,
+                                  NULL, "z2.flash0", Z2_FLASH_SIZE);
+    if (!pflash_cfi01_register(Z2_FLASH_BASE, flash,
                                dinfo->bdrv, sector_len,
-                               Z2_FLASH_SIZE / sector_len, 4, 0, 0, 0, 0,
-                               be)) {
+                               Z2_FLASH_SIZE / sector_len, 4, 0, 0, 0, 0)) {
         fprintf(stderr, "qemu: Error registering flash memory.\n");
         exit(1);
     }
commit a1807ef2954d3ddbf9a9bca3949bd0c69fd45a0e
Author: Avi Kivity <avi at redhat.com>
Date:   Wed Aug 3 18:55:00 2011 +0300

    Makefile.hw: allow hw/ files to include glib headers
    
    Reviewed-by: Richard Henderson  <rth at twiddle.net>
    Signed-off-by: Avi Kivity <avi at redhat.com>

diff --git a/Makefile.hw b/Makefile.hw
index 659e441..63eb7e4 100644
--- a/Makefile.hw
+++ b/Makefile.hw
@@ -10,6 +10,7 @@ include $(SRC_PATH)/rules.mak
 $(call set-vpath, $(SRC_PATH):$(SRC_PATH)/hw)
 
 QEMU_CFLAGS+=-I..
+QEMU_CFLAGS += $(GLIB_CFLAGS)
 
 include $(SRC_PATH)/Makefile.objs
 
commit c2c1b0f84b3dd56f5a8e192b97881e62e82e3b14
Author: Avi Kivity <avi at redhat.com>
Date:   Mon Aug 1 11:04:39 2011 +0300

    piix_pci: wrap memory update in a transaction
    
    The code will remap all PAMs, even if just one is updated, resulting
    in reduced performance.  Wrap in a transaction to detect that those
    other PAMs have not changed.
    
    Reviewed-by: Richard Henderson  <rth at twiddle.net>
    Signed-off-by: Avi Kivity <avi at redhat.com>

diff --git a/hw/piix_pci.c b/hw/piix_pci.c
index f892994..8f6ea42 100644
--- a/hw/piix_pci.c
+++ b/hw/piix_pci.c
@@ -142,6 +142,7 @@ static void i440fx_update_memory_mappings(PCII440FXState *d)
     int i, r;
     uint32_t smram;
 
+    memory_region_transaction_begin();
     update_pam(d, 0xf0000, 0x100000, (d->dev.config[I440FX_PAM] >> 4) & 3,
                &d->pam_regions[0]);
     for(i = 0; i < 12; i++) {
@@ -162,6 +163,7 @@ static void i440fx_update_memory_mappings(PCII440FXState *d)
             d->smram_enabled = false;
         }
     }
+    memory_region_transaction_commit();
 }
 
 static void i440fx_set_smm(int val, void *arg)
commit cf9182e2290732be9f8d4f73ba3d6f3484380450
Author: Avi Kivity <avi at redhat.com>
Date:   Mon Aug 1 11:03:42 2011 +0300

    cirrus: wrap memory update in a transaction
    
    This prevents spurious unmapping and remapping of the vga windows,
    which reduces performance.
    
    Reviewed-by: Richard Henderson  <rth at twiddle.net>
    Signed-off-by: Avi Kivity <avi at redhat.com>

diff --git a/hw/cirrus_vga.c b/hw/cirrus_vga.c
index 4d0ef0d..ec7ea82 100644
--- a/hw/cirrus_vga.c
+++ b/hw/cirrus_vga.c
@@ -2424,6 +2424,7 @@ static void cirrus_update_memory_access(CirrusVGAState *s)
 {
     unsigned mode;
 
+    memory_region_transaction_begin();
     if ((s->vga.sr[0x17] & 0x44) == 0x44) {
         goto generic_io;
     } else if (s->cirrus_srcptr != s->cirrus_srcptr_end) {
@@ -2443,6 +2444,7 @@ static void cirrus_update_memory_access(CirrusVGAState *s)
             unmap_linear_vram(s);
         }
     }
+    memory_region_transaction_commit();
 }
 
 
commit 20e5758b086a2fc6658afc58836e9cdb76b09977
Author: Avi Kivity <avi at redhat.com>
Date:   Mon Jul 25 15:07:22 2011 +0300

    leon3: convert to memory API
    
    Reviewed-by: Richard Henderson  <rth at twiddle.net>
    Signed-off-by: Avi Kivity <avi at redhat.com>

diff --git a/hw/leon3.c b/hw/leon3.c
index a62a941..607ec85 100644
--- a/hw/leon3.c
+++ b/hw/leon3.c
@@ -29,6 +29,7 @@
 #include "loader.h"
 #include "elf.h"
 #include "trace.h"
+#include "exec-memory.h"
 
 #include "grlib.h"
 
@@ -100,7 +101,9 @@ static void leon3_generic_hw_init(ram_addr_t  ram_size,
                                   const char *cpu_model)
 {
     CPUState   *env;
-    ram_addr_t  ram_offset, prom_offset;
+    MemoryRegion *address_space_mem = get_system_memory();
+    MemoryRegion *ram = g_new(MemoryRegion, 1);
+    MemoryRegion *prom = g_new(MemoryRegion, 1);
     int         ret;
     char       *filename;
     qemu_irq   *cpu_irqs = NULL;
@@ -139,14 +142,14 @@ static void leon3_generic_hw_init(ram_addr_t  ram_size,
         exit(1);
     }
 
-    ram_offset = qemu_ram_alloc(NULL, "leon3.ram", ram_size);
-    cpu_register_physical_memory(0x40000000, ram_size, ram_offset | IO_MEM_RAM);
+    memory_region_init_ram(ram, NULL, "leon3.ram", ram_size);
+    memory_region_add_subregion(address_space_mem, 0x40000000, ram);
 
     /* Allocate BIOS */
     prom_size = 8 * 1024 * 1024; /* 8Mb */
-    prom_offset = qemu_ram_alloc(NULL, "Leon3.bios", prom_size);
-    cpu_register_physical_memory(0x00000000, prom_size,
-                                 prom_offset | IO_MEM_ROM);
+    memory_region_init_ram(prom, NULL, "Leon3.bios", prom_size);
+    memory_region_set_readonly(prom, true);
+    memory_region_add_subregion(address_space_mem, 0x00000000, prom);
 
     /* Load boot prom */
     if (bios_name == NULL) {
commit b3cc4962558b50821fb3a1f35c3fb24e25c384bf
Author: Avi Kivity <avi at redhat.com>
Date:   Mon Jul 25 15:03:19 2011 +0300

    integratorcp: convert to memory API (RAM/flash only)
    
    Reviewed-by: Richard Henderson  <rth at twiddle.net>
    Signed-off-by: Avi Kivity <avi at redhat.com>

diff --git a/hw/integratorcp.c b/hw/integratorcp.c
index 2814108..3c8982e 100644
--- a/hw/integratorcp.c
+++ b/hw/integratorcp.c
@@ -13,11 +13,13 @@
 #include "boards.h"
 #include "arm-misc.h"
 #include "net.h"
+#include "exec-memory.h"
 
 typedef struct {
     SysBusDevice busdev;
     uint32_t memsz;
-    uint32_t flash_offset;
+    MemoryRegion flash;
+    bool flash_mapped;
     uint32_t cm_osc;
     uint32_t cm_ctrl;
     uint32_t cm_lock;
@@ -108,9 +110,15 @@ static uint32_t integratorcm_read(void *opaque, target_phys_addr_t offset)
 static void integratorcm_do_remap(integratorcm_state *s, int flash)
 {
     if (flash) {
-        cpu_register_physical_memory(0, 0x100000, IO_MEM_RAM);
+        if (s->flash_mapped) {
+            sysbus_del_memory(&s->busdev, &s->flash);
+            s->flash_mapped = false;
+        }
     } else {
-        cpu_register_physical_memory(0, 0x100000, s->flash_offset | IO_MEM_RAM);
+        if (!s->flash_mapped) {
+            sysbus_add_memory_overlap(&s->busdev, 0, &s->flash, 1);
+            s->flash_mapped = true;
+        }
     }
     //??? tlb_flush (cpu_single_env, 1);
 }
@@ -252,7 +260,8 @@ static int integratorcm_init(SysBusDevice *dev)
     }
     memcpy(integrator_spd + 73, "QEMU-MEMORY", 11);
     s->cm_init = 0x00000112;
-    s->flash_offset = qemu_ram_alloc(NULL, "integrator.flash", 0x100000);
+    memory_region_init_ram(&s->flash, NULL, "integrator.flash", 0x100000);
+    s->flash_mapped = false;
 
     iomemtype = cpu_register_io_memory(integratorcm_readfn,
                                        integratorcm_writefn, s,
@@ -456,7 +465,9 @@ static void integratorcp_init(ram_addr_t ram_size,
                      const char *initrd_filename, const char *cpu_model)
 {
     CPUState *env;
-    ram_addr_t ram_offset;
+    MemoryRegion *address_space_mem = get_system_memory();
+    MemoryRegion *ram = g_new(MemoryRegion, 1);
+    MemoryRegion *ram_alias = g_new(MemoryRegion, 1);
     qemu_irq pic[32];
     qemu_irq *cpu_pic;
     DeviceState *dev;
@@ -469,13 +480,14 @@ static void integratorcp_init(ram_addr_t ram_size,
         fprintf(stderr, "Unable to find CPU definition\n");
         exit(1);
     }
-    ram_offset = qemu_ram_alloc(NULL, "integrator.ram", ram_size);
+    memory_region_init_ram(ram, NULL, "integrator.ram", ram_size);
     /* ??? On a real system the first 1Mb is mapped as SSRAM or boot flash.  */
     /* ??? RAM should repeat to fill physical memory space.  */
     /* SDRAM at address zero*/
-    cpu_register_physical_memory(0, ram_size, ram_offset | IO_MEM_RAM);
+    memory_region_add_subregion(address_space_mem, 0, ram);
     /* And again at address 0x80000000 */
-    cpu_register_physical_memory(0x80000000, ram_size, ram_offset | IO_MEM_RAM);
+    memory_region_init_alias(ram_alias, "ram.alias", ram, 0, ram_size);
+    memory_region_add_subregion(address_space_mem, 0x80000000, ram_alias);
 
     dev = qdev_create(NULL, "integrator_core");
     qdev_prop_set_uint32(dev, "memsz", ram_size >> 20);
commit 28e7796459fbc3609557b34f9a9ad01c82bcff21
Author: Avi Kivity <avi at redhat.com>
Date:   Mon Jul 25 15:02:17 2011 +0300

    sysbus: add sysbus_add_memory_overlap()
    
    Signed-off-by: Avi Kivity <avi at redhat.com>

diff --git a/hw/sysbus.c b/hw/sysbus.c
index f5f0ed2..6e89f06 100644
--- a/hw/sysbus.c
+++ b/hw/sysbus.c
@@ -263,6 +263,13 @@ void sysbus_add_memory(SysBusDevice *dev, target_phys_addr_t addr,
     memory_region_add_subregion(get_system_memory(), addr, mem);
 }
 
+void sysbus_add_memory_overlap(SysBusDevice *dev, target_phys_addr_t addr,
+                               MemoryRegion *mem, unsigned priority)
+{
+    memory_region_add_subregion_overlap(get_system_memory(), addr, mem,
+                                        priority);
+}
+
 void sysbus_del_memory(SysBusDevice *dev, MemoryRegion *mem)
 {
     memory_region_del_subregion(get_system_memory(), mem);
diff --git a/hw/sysbus.h b/hw/sysbus.h
index e4d56cf..b3e1f99 100644
--- a/hw/sysbus.h
+++ b/hw/sysbus.h
@@ -59,6 +59,8 @@ void sysbus_connect_irq(SysBusDevice *dev, int n, qemu_irq irq);
 void sysbus_mmio_map(SysBusDevice *dev, int n, target_phys_addr_t addr);
 void sysbus_add_memory(SysBusDevice *dev, target_phys_addr_t addr,
                        MemoryRegion *mem);
+void sysbus_add_memory_overlap(SysBusDevice *dev, target_phys_addr_t addr,
+                               MemoryRegion *mem, unsigned priority);
 void sysbus_del_memory(SysBusDevice *dev, MemoryRegion *mem);
 void sysbus_add_io(SysBusDevice *dev, target_phys_addr_t addr,
                    MemoryRegion *mem);
commit 5461eb211197ec5957cd9c6c7fe39f038535dcf3
Author: Avi Kivity <avi at redhat.com>
Date:   Mon Jul 25 14:32:34 2011 +0300

    axis_dev88: convert to memory API (RAM only)
    
    Reviewed-by: Richard Henderson  <rth at twiddle.net>
    Acked-by: Edgar E. Iglesias <edgar.iglesias at gmail.com>
    Signed-off-by: Avi Kivity <avi at redhat.com>

diff --git a/hw/axis_dev88.c b/hw/axis_dev88.c
index 06200e2..73eb39d 100644
--- a/hw/axis_dev88.c
+++ b/hw/axis_dev88.c
@@ -31,6 +31,7 @@
 #include "elf.h"
 #include "cris-boot.h"
 #include "blockdev.h"
+#include "exec-memory.h"
 
 #define D(x)
 #define DNAND(x)
@@ -259,8 +260,9 @@ void axisdev88_init (ram_addr_t ram_size,
     int i;
     int nand_regs;
     int gpio_regs;
-    ram_addr_t phys_ram;
-    ram_addr_t phys_intmem;
+    MemoryRegion *address_space_mem = get_system_memory();
+    MemoryRegion *phys_ram = g_new(MemoryRegion, 1);
+    MemoryRegion *phys_intmem = g_new(MemoryRegion, 1);
 
     /* init CPUs */
     if (cpu_model == NULL) {
@@ -269,15 +271,13 @@ void axisdev88_init (ram_addr_t ram_size,
     env = cpu_init(cpu_model);
 
     /* allocate RAM */
-    phys_ram = qemu_ram_alloc(NULL, "axisdev88.ram", ram_size);
-    cpu_register_physical_memory(0x40000000, ram_size, phys_ram | IO_MEM_RAM);
+    memory_region_init_ram(phys_ram, NULL, "axisdev88.ram", ram_size);
+    memory_region_add_subregion(address_space_mem, 0x40000000, phys_ram);
 
     /* The ETRAX-FS has 128Kb on chip ram, the docs refer to it as the 
        internal memory.  */
-    phys_intmem = qemu_ram_alloc(NULL, "axisdev88.chipram", INTMEM_SIZE);
-    cpu_register_physical_memory(0x38000000, INTMEM_SIZE,
-                                 phys_intmem | IO_MEM_RAM);
-
+    memory_region_init_ram(phys_intmem, NULL, "axisdev88.chipram", INTMEM_SIZE);
+    memory_region_add_subregion(address_space_mem, 0x38000000, phys_intmem);
 
       /* Attach a NAND flash to CS1.  */
     nand = drive_get(IF_MTD, 0, 0);
commit 5b15f27516ce3249c80bd2e0458d8d61f20da415
Author: Avi Kivity <avi at redhat.com>
Date:   Wed Aug 24 21:37:05 2011 +0300

    ppc_oldworld, ppc_newworld: fix escc BAR related crash
    
    ppc maps the escc mmio region both at a fixed offset (as a sysbus area) and as part of a PCI BAR.
    This crashes, since a MemoryRegion may have only one parent.  Use an alias so we have a separate
    MemoryRegion for the BAR.
    
    Signed-off-by: Avi Kivity <avi at redhat.com>

diff --git a/hw/ppc_newworld.c b/hw/ppc_newworld.c
index 4727e07..fbd443d 100644
--- a/hw/ppc_newworld.c
+++ b/hw/ppc_newworld.c
@@ -146,6 +146,7 @@ static void ppc_core99_init (ram_addr_t ram_size,
     MacIONVRAMState *nvr;
     int bios_size;
     MemoryRegion *pic_mem, *dbdma_mem, *cuda_mem, *escc_mem;
+    MemoryRegion *escc_bar = g_new(MemoryRegion, 1);
     MemoryRegion *ide_mem[3];
     int ppc_boot_device;
     DriveInfo *hd[MAX_IDE_BUS * MAX_IDE_DEVS];
@@ -328,6 +329,8 @@ static void ppc_core99_init (ram_addr_t ram_size,
 
     escc_mem = escc_init(0x80013000, pic[0x25], pic[0x24],
                          serial_hds[0], serial_hds[1], ESCC_CLOCK, 4);
+    memory_region_init_alias(escc_bar, "escc-bar",
+                             escc_mem, 0, memory_region_size(escc_mem));
 
     for(i = 0; i < nb_nics; i++)
         pci_nic_init_nofail(&nd_table[i], "ne2k_pci", NULL);
@@ -350,7 +353,7 @@ static void ppc_core99_init (ram_addr_t ram_size,
     adb_mouse_init(&adb_bus);
 
     macio_init(pci_bus, PCI_DEVICE_ID_APPLE_UNI_N_KEYL, 0, pic_mem,
-               dbdma_mem, cuda_mem, NULL, 3, ide_mem, escc_mem);
+               dbdma_mem, cuda_mem, NULL, 3, ide_mem, escc_bar);
 
     if (usb_enabled) {
         usb_ohci_init_pci(pci_bus, -1);
diff --git a/hw/ppc_oldworld.c b/hw/ppc_oldworld.c
index 0071fc9..235d2ef 100644
--- a/hw/ppc_oldworld.c
+++ b/hw/ppc_oldworld.c
@@ -83,7 +83,7 @@ static void ppc_heathrow_init (ram_addr_t ram_size,
     MacIONVRAMState *nvr;
     int bios_size;
     MemoryRegion *pic_mem, *dbdma_mem, *cuda_mem;
-    MemoryRegion *escc_mem, *ide_mem[2];
+    MemoryRegion *escc_mem, *escc_bar = g_new(MemoryRegion, 1), *ide_mem[2];
     uint16_t ppc_boot_device;
     DriveInfo *hd[MAX_IDE_BUS * MAX_IDE_DEVS];
     void *fw_cfg;
@@ -241,6 +241,8 @@ static void ppc_heathrow_init (ram_addr_t ram_size,
 
     escc_mem = escc_init(0x80013000, pic[0x0f], pic[0x10], serial_hds[0],
                                serial_hds[1], ESCC_CLOCK, 4);
+    memory_region_init_alias(escc_bar, "escc-bar",
+                             escc_mem, 0, memory_region_size(escc_mem));
 
     for(i = 0; i < nb_nics; i++)
         pci_nic_init_nofail(&nd_table[i], "ne2k_pci", NULL);
@@ -269,7 +271,7 @@ static void ppc_heathrow_init (ram_addr_t ram_size,
     pmac_format_nvram_partition(nvr, 0x2000);
 
     macio_init(pci_bus, PCI_DEVICE_ID_APPLE_343S1201, 1, pic_mem,
-               dbdma_mem, cuda_mem, nvr, 2, ide_mem, escc_mem);
+               dbdma_mem, cuda_mem, nvr, 2, ide_mem, escc_bar);
 
     if (usb_enabled) {
         usb_ohci_init_pci(pci_bus, -1);
commit 89da90b1b4acf24a9a3f2fd197b1bdf69ab24e72
Author: Avi Kivity <avi at redhat.com>
Date:   Wed Aug 24 22:09:41 2011 +0300

    gt64xxx: fix crash in gt64120_pci_mapping()
    
    The map/unmap code was assymetric - unmap used the local MemoryRegion while
    map used isa_mmio_init(), which cannot handle dynamic mappings.
    
    Fix by using isa_mmio_setup() and the local MemoryRegion.
    
    Signed-off-by: Avi Kivity <avi at redhat.com>
    Signed-off-by: Edgar E. Iglesias <edgar.iglesias at gmail.com>

diff --git a/hw/gt64xxx.c b/hw/gt64xxx.c
index 6af9782..1c34253 100644
--- a/hw/gt64xxx.c
+++ b/hw/gt64xxx.c
@@ -297,7 +297,11 @@ static void gt64120_pci_mapping(GT64120State *s)
       s->PCI0IO_start = s->regs[GT_PCI0IOLD] << 21;
       s->PCI0IO_length = ((s->regs[GT_PCI0IOHD] + 1) - (s->regs[GT_PCI0IOLD] & 0x7f)) << 21;
       isa_mem_base = s->PCI0IO_start;
-      isa_mmio_init(s->PCI0IO_start, s->PCI0IO_length);
+      if (s->PCI0IO_length) {
+          isa_mmio_setup(&s->PCI0IO_mem, s->PCI0IO_length);
+          memory_region_add_subregion(get_system_memory(), s->PCI0IO_start,
+                                      &s->PCI0IO_mem);
+      }
     }
 }
 
commit fbe15adf8ed7c3ec41ff44fadabafb3175eb88cc
Author: Avi Kivity <avi at redhat.com>
Date:   Mon Jul 25 14:27:01 2011 +0300

    armv7m: convert to memory API
    
    Reviewed-by: Richard Henderson  <rth at twiddle.net>
    Signed-off-by: Avi Kivity <avi at redhat.com>

diff --git a/hw/arm-misc.h b/hw/arm-misc.h
index f8a7472..af403a1 100644
--- a/hw/arm-misc.h
+++ b/hw/arm-misc.h
@@ -11,13 +11,16 @@
 #ifndef ARM_MISC_H
 #define ARM_MISC_H 1
 
+#include "memory.h"
+
 /* The CPU is also modeled as an interrupt controller.  */
 #define ARM_PIC_CPU_IRQ 0
 #define ARM_PIC_CPU_FIQ 1
 qemu_irq *arm_pic_init_cpu(CPUState *env);
 
 /* armv7m.c */
-qemu_irq *armv7m_init(int flash_size, int sram_size,
+qemu_irq *armv7m_init(MemoryRegion *address_space_mem,
+                      int flash_size, int sram_size,
                       const char *kernel_filename, const char *cpu_model);
 
 /* arm_boot.c */
diff --git a/hw/armv7m.c b/hw/armv7m.c
index a932f16..28d41b8 100644
--- a/hw/armv7m.c
+++ b/hw/armv7m.c
@@ -156,7 +156,8 @@ static void armv7m_reset(void *opaque)
    flash_size and sram_size are in kb.
    Returns the NVIC array.  */
 
-qemu_irq *armv7m_init(int flash_size, int sram_size,
+qemu_irq *armv7m_init(MemoryRegion *address_space_mem,
+                      int flash_size, int sram_size,
                       const char *kernel_filename, const char *cpu_model)
 {
     CPUState *env;
@@ -169,6 +170,9 @@ qemu_irq *armv7m_init(int flash_size, int sram_size,
     uint64_t lowaddr;
     int i;
     int big_endian;
+    MemoryRegion *sram = g_new(MemoryRegion, 1);
+    MemoryRegion *flash = g_new(MemoryRegion, 1);
+    MemoryRegion *hack = g_new(MemoryRegion, 1);
 
     flash_size *= 1024;
     sram_size *= 1024;
@@ -194,12 +198,11 @@ qemu_irq *armv7m_init(int flash_size, int sram_size,
 #endif
 
     /* Flash programming is done via the SCU, so pretend it is ROM.  */
-    cpu_register_physical_memory(0, flash_size,
-                                 qemu_ram_alloc(NULL, "armv7m.flash",
-                                                flash_size) | IO_MEM_ROM);
-    cpu_register_physical_memory(0x20000000, sram_size,
-                                 qemu_ram_alloc(NULL, "armv7m.sram",
-                                                sram_size) | IO_MEM_RAM);
+    memory_region_init_ram(flash, NULL, "armv7m.flash", flash_size);
+    memory_region_set_readonly(flash, true);
+    memory_region_add_subregion(address_space_mem, 0, flash);
+    memory_region_init_ram(sram, NULL, "armv7m.sram", sram_size);
+    memory_region_add_subregion(address_space_mem, 0x20000000, sram);
     armv7m_bitband_init();
 
     nvic = qdev_create(NULL, "armv7m_nvic");
@@ -232,9 +235,8 @@ qemu_irq *armv7m_init(int flash_size, int sram_size,
     /* Hack to map an additional page of ram at the top of the address
        space.  This stops qemu complaining about executing code outside RAM
        when returning from an exception.  */
-    cpu_register_physical_memory(0xfffff000, 0x1000,
-                                 qemu_ram_alloc(NULL, "armv7m.hack", 
-                                                0x1000) | IO_MEM_RAM);
+    memory_region_init_ram(hack, NULL, "armv7m.hack", 0x1000);
+    memory_region_add_subregion(address_space_mem, 0xfffff000, hack);
 
     qemu_register_reset(armv7m_reset, env);
     return pic;
diff --git a/hw/stellaris.c b/hw/stellaris.c
index 9b0db7f..2bf1c23 100644
--- a/hw/stellaris.c
+++ b/hw/stellaris.c
@@ -15,6 +15,7 @@
 #include "i2c.h"
 #include "net.h"
 #include "boards.h"
+#include "exec-memory.h"
 
 #define GPIO_A 0
 #define GPIO_B 1
@@ -1260,6 +1261,7 @@ static void stellaris_init(const char *kernel_filename, const char *cpu_model,
         0x40024000, 0x40025000, 0x40026000};
     static const int gpio_irq[7] = {0, 1, 2, 3, 4, 30, 31};
 
+    MemoryRegion *address_space_mem = get_system_memory();
     qemu_irq *pic;
     DeviceState *gpio_dev[7];
     qemu_irq gpio_in[7][8];
@@ -1274,7 +1276,8 @@ static void stellaris_init(const char *kernel_filename, const char *cpu_model,
 
     flash_size = ((board->dc0 & 0xffff) + 1) << 1;
     sram_size = (board->dc0 >> 18) + 1;
-    pic = armv7m_init(flash_size, sram_size, kernel_filename, cpu_model);
+    pic = armv7m_init(address_space_mem,
+                      flash_size, sram_size, kernel_filename, cpu_model);
 
     if (board->dc1 & (1 << 16)) {
         dev = sysbus_create_varargs("stellaris-adc", 0x40038000,
commit 4c390a1d32b59c49fbb89e73b1d21fde78e0168d
Author: Avi Kivity <avi at redhat.com>
Date:   Mon Jul 25 14:14:31 2011 +0300

    an5206: convert to memory API
    
    Reviewed-by: Richard Henderson  <rth at twiddle.net>
    Signed-off-by: Avi Kivity <avi at redhat.com>

diff --git a/hw/an5206.c b/hw/an5206.c
index 04ca420..481ae60 100644
--- a/hw/an5206.c
+++ b/hw/an5206.c
@@ -12,6 +12,7 @@
 #include "boards.h"
 #include "loader.h"
 #include "elf.h"
+#include "exec-memory.h"
 
 #define KERNEL_LOAD_ADDR 0x10000
 #define AN5206_MBAR_ADDR 0x10000000
@@ -37,6 +38,9 @@ static void an5206_init(ram_addr_t ram_size,
     int kernel_size;
     uint64_t elf_entry;
     target_phys_addr_t entry;
+    MemoryRegion *address_space_mem = get_system_memory();
+    MemoryRegion *ram = g_new(MemoryRegion, 1);
+    MemoryRegion *sram = g_new(MemoryRegion, 1);
 
     if (!cpu_model)
         cpu_model = "m5206";
@@ -52,12 +56,12 @@ static void an5206_init(ram_addr_t ram_size,
     env->rambar0 = AN5206_RAMBAR_ADDR | 1;
 
     /* DRAM at address zero */
-    cpu_register_physical_memory(0, ram_size,
-        qemu_ram_alloc(NULL, "an5206.ram", ram_size) | IO_MEM_RAM);
+    memory_region_init_ram(ram, NULL, "an5206.ram", ram_size);
+    memory_region_add_subregion(address_space_mem, 0, ram);
 
     /* Internal SRAM.  */
-    cpu_register_physical_memory(AN5206_RAMBAR_ADDR, 512,
-        qemu_ram_alloc(NULL, "an5206.sram", 512) | IO_MEM_RAM);
+    memory_region_init_ram(sram, NULL, "an5206.sram", 512);
+    memory_region_add_subregion(address_space_mem, AN5206_RAMBAR_ADDR, sram);
 
     mcf5206_init(AN5206_MBAR_ADDR, env);
 
commit fb48f855ee7b91d7a81c7f094399cfe4d0718be1
Author: Avi Kivity <avi at redhat.com>
Date:   Sun Jul 24 19:27:24 2011 +0300

    ReadWriteHandler: remove
    
    No longer used.
    
    Reviewed-by: Richard Henderson  <rth at twiddle.net>
    Signed-off-by: Avi Kivity <avi at redhat.com>

diff --git a/Makefile.target b/Makefile.target
index e280bf6..c9957ae 100644
--- a/Makefile.target
+++ b/Makefile.target
@@ -195,7 +195,6 @@ obj-$(CONFIG_VIRTIO) += virtio.o virtio-blk.o virtio-balloon.o virtio-net.o virt
 obj-y += vhost_net.o
 obj-$(CONFIG_VHOST_NET) += vhost.o
 obj-$(CONFIG_REALLY_VIRTFS) += 9pfs/virtio-9p-device.o
-obj-y += rwhandler.o
 obj-$(CONFIG_KVM) += kvm.o kvm-all.o
 obj-$(CONFIG_NO_KVM) += kvm-stub.o
 obj-y += memory.o
diff --git a/rwhandler.c b/rwhandler.c
deleted file mode 100644
index bb2238f..0000000
--- a/rwhandler.c
+++ /dev/null
@@ -1,87 +0,0 @@
-#include "rwhandler.h"
-#include "ioport.h"
-#include "cpu-all.h"
-
-#define RWHANDLER_WRITE(name, len, type) \
-static void name(void *opaque, type addr, uint32_t value) \
-{\
-    struct ReadWriteHandler *handler = opaque;\
-    handler->write(handler, addr, value, len);\
-}
-
-#define RWHANDLER_READ(name, len, type) \
-static uint32_t name(void *opaque, type addr) \
-{ \
-    struct ReadWriteHandler *handler = opaque; \
-    return handler->read(handler, addr, len); \
-}
-
-RWHANDLER_WRITE(cpu_io_memory_simple_writeb, 1, target_phys_addr_t);
-RWHANDLER_READ(cpu_io_memory_simple_readb, 1, target_phys_addr_t);
-RWHANDLER_WRITE(cpu_io_memory_simple_writew, 2, target_phys_addr_t);
-RWHANDLER_READ(cpu_io_memory_simple_readw, 2, target_phys_addr_t);
-RWHANDLER_WRITE(cpu_io_memory_simple_writel, 4, target_phys_addr_t);
-RWHANDLER_READ(cpu_io_memory_simple_readl, 4, target_phys_addr_t);
-
-static CPUWriteMemoryFunc * const cpu_io_memory_simple_write[] = {
-    &cpu_io_memory_simple_writeb,
-    &cpu_io_memory_simple_writew,
-    &cpu_io_memory_simple_writel,
-};
-
-static CPUReadMemoryFunc * const cpu_io_memory_simple_read[] = {
-    &cpu_io_memory_simple_readb,
-    &cpu_io_memory_simple_readw,
-    &cpu_io_memory_simple_readl,
-};
-
-int cpu_register_io_memory_simple(struct ReadWriteHandler *handler, int endian)
-{
-    if (!handler->read || !handler->write) {
-        return -1;
-    }
-    return cpu_register_io_memory(cpu_io_memory_simple_read,
-                                  cpu_io_memory_simple_write,
-                                  handler, endian);
-}
-
-RWHANDLER_WRITE(ioport_simple_writeb, 1, uint32_t);
-RWHANDLER_READ(ioport_simple_readb, 1, uint32_t);
-RWHANDLER_WRITE(ioport_simple_writew, 2, uint32_t);
-RWHANDLER_READ(ioport_simple_readw, 2, uint32_t);
-RWHANDLER_WRITE(ioport_simple_writel, 4, uint32_t);
-RWHANDLER_READ(ioport_simple_readl, 4, uint32_t);
-
-int register_ioport_simple(ReadWriteHandler* handler,
-                           pio_addr_t start, int length, int size)
-{
-    IOPortWriteFunc *write;
-    IOPortReadFunc *read;
-    int r;
-    switch (size) {
-    case 1:
-        write = ioport_simple_writeb;
-        read = ioport_simple_readb;
-        break;
-    case 2:
-        write = ioport_simple_writew;
-        read = ioport_simple_readw;
-        break;
-    default:
-        write = ioport_simple_writel;
-        read = ioport_simple_readl;
-    }
-    if (handler->write) {
-        r = register_ioport_write(start, length, size, write, handler);
-        if (r < 0) {
-            return r;
-        }
-    }
-    if (handler->read) {
-        r = register_ioport_read(start, length, size, read, handler);
-        if (r < 0) {
-            return r;
-        }
-    }
-    return 0;
-}
diff --git a/rwhandler.h b/rwhandler.h
deleted file mode 100644
index b2a5790..0000000
--- a/rwhandler.h
+++ /dev/null
@@ -1,27 +0,0 @@
-#ifndef READ_WRITE_HANDLER_H
-#define READ_WRITE_HANDLER_H
-
-#include "qemu-common.h"
-#include "ioport.h"
-
-typedef struct ReadWriteHandler ReadWriteHandler;
-
-/* len is guaranteed to be one of 1, 2 or 4, addr is guaranteed to fit in an
- * appropriate type (io/memory/etc). They do not need to be range checked. */
-typedef void WriteHandlerFunc(ReadWriteHandler *, pcibus_t addr,
-                              uint32_t value, int len);
-typedef uint32_t ReadHandlerFunc(ReadWriteHandler *, pcibus_t addr, int len);
-
-struct ReadWriteHandler {
-    WriteHandlerFunc *write;
-    ReadHandlerFunc *read;
-};
-
-/* Helpers for when we want to use a single routine with length. */
-/* CPU memory handler: both read and write must be present. */
-int cpu_register_io_memory_simple(ReadWriteHandler *, int endian);
-/* io port handler: can supply only read or write handlers. */
-int register_ioport_simple(ReadWriteHandler *,
-                           pio_addr_t start, int length, int size);
-
-#endif
commit d2c33733c85c4df7cd0f5e0426a22e737d542516
Author: Avi Kivity <avi at redhat.com>
Date:   Sun Jul 24 17:47:18 2011 +0300

    pci_host: convert conf index and data ports to memory API
    
    Reviewed-by: Richard Henderson  <rth at twiddle.net>
    Signed-off-by: Avi Kivity <avi at redhat.com>

diff --git a/hw/dec_pci.c b/hw/dec_pci.c
index a35f382..1aec066 100644
--- a/hw/dec_pci.c
+++ b/hw/dec_pci.c
@@ -80,16 +80,15 @@ PCIBus *pci_dec_21154_init(PCIBus *parent_bus, int devfn)
 static int pci_dec_21154_init_device(SysBusDevice *dev)
 {
     DECState *s;
-    int pci_mem_config, pci_mem_data;
 
     s = FROM_SYSBUS(DECState, dev);
 
-    pci_mem_config = pci_host_conf_register_mmio(&s->host_state,
-                                                 DEVICE_LITTLE_ENDIAN);
-    pci_mem_data = pci_host_data_register_mmio(&s->host_state,
-                                               DEVICE_LITTLE_ENDIAN);
-    sysbus_init_mmio(dev, 0x1000, pci_mem_config);
-    sysbus_init_mmio(dev, 0x1000, pci_mem_data);
+    memory_region_init_io(&s->host_state.conf_mem, &pci_host_conf_le_ops,
+                          &s->host_state, "pci-conf-idx", 0x1000);
+    memory_region_init_io(&s->host_state.data_mem, &pci_host_data_le_ops,
+                          &s->host_state, "pci-data-idx", 0x1000);
+    sysbus_init_mmio_region(dev, &s->host_state.conf_mem);
+    sysbus_init_mmio_region(dev, &s->host_state.data_mem);
     return 0;
 }
 
diff --git a/hw/grackle_pci.c b/hw/grackle_pci.c
index 9a823e1..9d3ff7d 100644
--- a/hw/grackle_pci.c
+++ b/hw/grackle_pci.c
@@ -92,16 +92,15 @@ PCIBus *pci_grackle_init(uint32_t base, qemu_irq *pic,
 static int pci_grackle_init_device(SysBusDevice *dev)
 {
     GrackleState *s;
-    int pci_mem_config, pci_mem_data;
 
     s = FROM_SYSBUS(GrackleState, dev);
 
-    pci_mem_config = pci_host_conf_register_mmio(&s->host_state,
-                                                 DEVICE_LITTLE_ENDIAN);
-    pci_mem_data = pci_host_data_register_mmio(&s->host_state,
-                                               DEVICE_LITTLE_ENDIAN);
-    sysbus_init_mmio(dev, 0x1000, pci_mem_config);
-    sysbus_init_mmio(dev, 0x1000, pci_mem_data);
+    memory_region_init_io(&s->host_state.conf_mem, &pci_host_conf_le_ops,
+                          &s->host_state, "pci-conf-idx", 0x1000);
+    memory_region_init_io(&s->host_state.data_mem, &pci_host_data_le_ops,
+                          &s->host_state, "pci-data-idx", 0x1000);
+    sysbus_init_mmio_region(dev, &s->host_state.conf_mem);
+    sysbus_init_mmio_region(dev, &s->host_state.data_mem);
 
     qemu_register_reset(pci_grackle_reset, &s->host_state);
     return 0;
diff --git a/hw/pci_host.c b/hw/pci_host.c
index 2e8a29f..44c6c20 100644
--- a/hw/pci_host.c
+++ b/hw/pci_host.c
@@ -94,82 +94,72 @@ uint32_t pci_data_read(PCIBus *s, uint32_t addr, int len)
     return val;
 }
 
-static void pci_host_config_write(ReadWriteHandler *handler,
-                                  pcibus_t addr, uint32_t val, int len)
+static void pci_host_config_write(void *opaque, target_phys_addr_t addr,
+                                  uint64_t val, unsigned len)
 {
-    PCIHostState *s = container_of(handler, PCIHostState, conf_handler);
+    PCIHostState *s = opaque;
 
-    PCI_DPRINTF("%s addr %" FMT_PCIBUS " %d val %"PRIx32"\n",
+    PCI_DPRINTF("%s addr " TARGET_FMT_plx " len %d val %"PRIx64"\n",
                 __func__, addr, len, val);
     s->config_reg = val;
 }
 
-static uint32_t pci_host_config_read(ReadWriteHandler *handler,
-                                     pcibus_t addr, int len)
+static uint64_t pci_host_config_read(void *opaque, target_phys_addr_t addr,
+                                     unsigned len)
 {
-    PCIHostState *s = container_of(handler, PCIHostState, conf_handler);
+    PCIHostState *s = opaque;
     uint32_t val = s->config_reg;
 
-    PCI_DPRINTF("%s addr %" FMT_PCIBUS " len %d val %"PRIx32"\n",
+    PCI_DPRINTF("%s addr " TARGET_FMT_plx " len %d val %"PRIx32"\n",
                 __func__, addr, len, val);
     return val;
 }
 
-static void pci_host_data_write(ReadWriteHandler *handler,
-                                pcibus_t addr, uint32_t val, int len)
+static void pci_host_data_write(void *opaque, target_phys_addr_t addr,
+                                uint64_t val, unsigned len)
 {
-    PCIHostState *s = container_of(handler, PCIHostState, data_handler);
-    PCI_DPRINTF("write addr %" FMT_PCIBUS " len %d val %x\n",
-                addr, len, val);
+    PCIHostState *s = opaque;
+    PCI_DPRINTF("write addr " TARGET_FMT_plx " len %d val %x\n",
+                addr, len, (unsigned)val);
     if (s->config_reg & (1u << 31))
         pci_data_write(s->bus, s->config_reg | (addr & 3), val, len);
 }
 
-static uint32_t pci_host_data_read(ReadWriteHandler *handler,
-                                   pcibus_t addr, int len)
+static uint64_t pci_host_data_read(void *opaque,
+                                   target_phys_addr_t addr, unsigned len)
 {
-    PCIHostState *s = container_of(handler, PCIHostState, data_handler);
+    PCIHostState *s = opaque;
     uint32_t val;
     if (!(s->config_reg & (1 << 31)))
         return 0xffffffff;
     val = pci_data_read(s->bus, s->config_reg | (addr & 3), len);
-    PCI_DPRINTF("read addr %" FMT_PCIBUS " len %d val %x\n",
+    PCI_DPRINTF("read addr " TARGET_FMT_plx " len %d val %x\n",
                 addr, len, val);
     return val;
 }
 
-static void pci_host_init(PCIHostState *s)
-{
-    s->conf_handler.write = pci_host_config_write;
-    s->conf_handler.read = pci_host_config_read;
-    s->data_handler.write = pci_host_data_write;
-    s->data_handler.read = pci_host_data_read;
-}
+const MemoryRegionOps pci_host_conf_le_ops = {
+    .read = pci_host_config_read,
+    .write = pci_host_config_write,
+    .endianness = DEVICE_LITTLE_ENDIAN,
+};
 
-int pci_host_conf_register_mmio(PCIHostState *s, int endian)
-{
-    pci_host_init(s);
-    return cpu_register_io_memory_simple(&s->conf_handler, endian);
-}
+const MemoryRegionOps pci_host_conf_be_ops = {
+    .read = pci_host_config_read,
+    .write = pci_host_config_write,
+    .endianness = DEVICE_BIG_ENDIAN,
+};
 
-void pci_host_conf_register_ioport(pio_addr_t ioport, PCIHostState *s)
-{
-    pci_host_init(s);
-    register_ioport_simple(&s->conf_handler, ioport, 4, 4);
-    sysbus_init_ioports(&s->busdev, ioport, 4);
-}
+const MemoryRegionOps pci_host_data_le_ops = {
+    .read = pci_host_data_read,
+    .write = pci_host_data_write,
+    .endianness = DEVICE_LITTLE_ENDIAN,
+};
+
+const MemoryRegionOps pci_host_data_be_ops = {
+    .read = pci_host_data_read,
+    .write = pci_host_data_write,
+    .endianness = DEVICE_BIG_ENDIAN,
+};
 
-int pci_host_data_register_mmio(PCIHostState *s, int endian)
-{
-    pci_host_init(s);
-    return cpu_register_io_memory_simple(&s->data_handler, endian);
-}
 
-void pci_host_data_register_ioport(pio_addr_t ioport, PCIHostState *s)
-{
-    pci_host_init(s);
-    register_ioport_simple(&s->data_handler, ioport, 4, 1);
-    register_ioport_simple(&s->data_handler, ioport, 4, 2);
-    register_ioport_simple(&s->data_handler, ioport, 4, 4);
-    sysbus_init_ioports(&s->busdev, ioport, 4);
-}
diff --git a/hw/pci_host.h b/hw/pci_host.h
index 7f55114..0211086 100644
--- a/hw/pci_host.h
+++ b/hw/pci_host.h
@@ -29,12 +29,11 @@
 #define PCI_HOST_H
 
 #include "sysbus.h"
-#include "rwhandler.h"
 
 struct PCIHostState {
     SysBusDevice busdev;
-    ReadWriteHandler conf_handler;
-    ReadWriteHandler data_handler;
+    MemoryRegion conf_mem;
+    MemoryRegion data_mem;
     MemoryRegion *address_space;
     uint32_t config_reg;
     PCIBus *bus;
@@ -49,12 +48,9 @@ uint32_t pci_host_config_read_common(PCIDevice *pci_dev, uint32_t addr,
 void pci_data_write(PCIBus *s, uint32_t addr, uint32_t val, int len);
 uint32_t pci_data_read(PCIBus *s, uint32_t addr, int len);
 
-/* for mmio */
-int pci_host_conf_register_mmio(PCIHostState *s, int endian);
-int pci_host_data_register_mmio(PCIHostState *s, int endian);
-
-/* for ioio */
-void pci_host_conf_register_ioport(pio_addr_t ioport, PCIHostState *s);
-void pci_host_data_register_ioport(pio_addr_t ioport, PCIHostState *s);
+extern const MemoryRegionOps pci_host_conf_le_ops;
+extern const MemoryRegionOps pci_host_conf_be_ops;
+extern const MemoryRegionOps pci_host_data_le_ops;
+extern const MemoryRegionOps pci_host_data_be_ops;
 
 #endif /* PCI_HOST_H */
diff --git a/hw/piix_pci.c b/hw/piix_pci.c
index c563c6e..f892994 100644
--- a/hw/piix_pci.c
+++ b/hw/piix_pci.c
@@ -235,9 +235,16 @@ static int i440fx_pcihost_initfn(SysBusDevice *dev)
 {
     I440FXState *s = FROM_SYSBUS(I440FXState, dev);
 
-    pci_host_conf_register_ioport(0xcf8, s);
+    memory_region_init_io(&s->conf_mem, &pci_host_conf_le_ops, s,
+                          "pci-conf-idx", 4);
+    sysbus_add_io(dev, 0xcf8, &s->conf_mem);
+    sysbus_init_ioports(&s->busdev, 0xcf8, 4);
+
+    memory_region_init_io(&s->data_mem, &pci_host_data_le_ops, s,
+                          "pci-conf-data", 4);
+    sysbus_add_io(dev, 0xcfc, &s->data_mem);
+    sysbus_init_ioports(&s->busdev, 0xcfc, 4);
 
-    pci_host_data_register_ioport(0xcfc, s);
     return 0;
 }
 
diff --git a/hw/ppc4xx_pci.c b/hw/ppc4xx_pci.c
index 52e2663..339b38e 100644
--- a/hw/ppc4xx_pci.c
+++ b/hw/ppc4xx_pci.c
@@ -368,10 +368,12 @@ PCIBus *ppc4xx_pci_init(CPUState *env, qemu_irq pci_irqs[4],
     cpu_register_physical_memory(config_space + PCIC0_CFGADDR, 4, index);
 
     /* CFGDATA */
-    index = pci_host_data_register_mmio(&controller->pci_state, 1);
-    if (index < 0)
-        goto free;
-    cpu_register_physical_memory(config_space + PCIC0_CFGDATA, 4, index);
+    memory_region_init_io(&controller->pci_state.data_mem,
+                          &pci_host_data_be_ops,
+                          &controller->pci_state, "pci-conf-data", 4);
+    memory_region_add_subregion(get_system_memory(),
+                                config_space + PCIC0_CFGDATA,
+                                &controller->pci_state.data_mem);
 
     /* Internal registers */
     index = cpu_register_io_memory(pci_reg_read, pci_reg_write, controller,
diff --git a/hw/ppce500_pci.c b/hw/ppce500_pci.c
index 4390aeb..2db365d 100644
--- a/hw/ppce500_pci.c
+++ b/hw/ppce500_pci.c
@@ -79,8 +79,6 @@ struct PPCE500PCIState {
     uint32_t gasket_time;
     qemu_irq irq[4];
     /* mmio maps */
-    int cfgaddr;
-    int cfgdata;
     int reg;
 };
 
@@ -268,18 +266,18 @@ static void e500_pci_map(SysBusDevice *dev, target_phys_addr_t base)
     PCIHostState *h = FROM_SYSBUS(PCIHostState, sysbus_from_qdev(dev));
     PPCE500PCIState *s = DO_UPCAST(PPCE500PCIState, pci_state, h);
 
-    cpu_register_physical_memory(base + PCIE500_CFGADDR, 4, s->cfgaddr);
-    cpu_register_physical_memory(base + PCIE500_CFGDATA, 4, s->cfgdata);
+    sysbus_add_memory(dev, base + PCIE500_CFGADDR, &h->conf_mem);
+    sysbus_add_memory(dev, base + PCIE500_CFGDATA, &h->data_mem);
     cpu_register_physical_memory(base + PCIE500_REG_BASE, PCIE500_REG_SIZE,
                                  s->reg);
 }
 
 static void e500_pci_unmap(SysBusDevice *dev, target_phys_addr_t base)
 {
-    cpu_register_physical_memory(base + PCIE500_CFGADDR, 4,
-                                 IO_MEM_UNASSIGNED);
-    cpu_register_physical_memory(base + PCIE500_CFGDATA, 4,
-                                 IO_MEM_UNASSIGNED);
+    PCIHostState *h = FROM_SYSBUS(PCIHostState, sysbus_from_qdev(dev));
+
+    sysbus_del_memory(dev, &h->conf_mem);
+    sysbus_del_memory(dev, &h->data_mem);
     cpu_register_physical_memory(base + PCIE500_REG_BASE, PCIE500_REG_SIZE,
                                  IO_MEM_UNASSIGNED);
 }
@@ -309,9 +307,10 @@ static int e500_pcihost_initfn(SysBusDevice *dev)
 
     pci_create_simple(b, 0, "e500-host-bridge");
 
-    s->cfgaddr = pci_host_conf_register_mmio(&s->pci_state, DEVICE_BIG_ENDIAN);
-    s->cfgdata = pci_host_data_register_mmio(&s->pci_state,
-                                             DEVICE_LITTLE_ENDIAN);
+    memory_region_init_io(&h->conf_mem, &pci_host_conf_be_ops, h,
+                          "pci-conf-idx", 4);
+    memory_region_init_io(&h->data_mem, &pci_host_data_le_ops, h,
+                          "pci-conf-data", 4);
     s->reg = cpu_register_io_memory(e500_pci_reg_read, e500_pci_reg_write, s,
                                     DEVICE_BIG_ENDIAN);
     sysbus_init_mmio_cb2(dev, e500_pci_map, e500_pci_unmap);
diff --git a/hw/prep_pci.c b/hw/prep_pci.c
index c36232a..55e4e25 100644
--- a/hw/prep_pci.c
+++ b/hw/prep_pci.c
@@ -125,9 +125,15 @@ PCIBus *pci_prep_init(qemu_irq *pic,
                               address_space_io,
                               0, 4);
 
-    pci_host_conf_register_ioport(0xcf8, s);
-
-    pci_host_data_register_ioport(0xcfc, s);
+    memory_region_init_io(&s->conf_mem, &pci_host_conf_be_ops, s,
+                          "pci-conf-idx", 1);
+    memory_region_add_subregion(address_space_io, 0xcf8, &s->conf_mem);
+    sysbus_init_ioports(&s->busdev, 0xcf8, 1);
+
+    memory_region_init_io(&s->conf_mem, &pci_host_data_be_ops, s,
+                          "pci-conf-data", 1);
+    memory_region_add_subregion(address_space_io, 0xcfc, &s->data_mem);
+    sysbus_init_ioports(&s->busdev, 0xcfc, 1);
 
     PPC_io_memory = cpu_register_io_memory(PPC_PCIIO_read,
                                            PPC_PCIIO_write, s,
diff --git a/hw/unin_pci.c b/hw/unin_pci.c
index f896f8c..600cd1e 100644
--- a/hw/unin_pci.c
+++ b/hw/unin_pci.c
@@ -41,7 +41,6 @@ static const int unin_irq_line[] = { 0x1b, 0x1c, 0x1d, 0x1e };
 typedef struct UNINState {
     SysBusDevice busdev;
     PCIHostState host_state;
-    ReadWriteHandler data_handler;
 } UNINState;
 
 static int pci_unin_map_irq(PCIDevice *pci_dev, int irq_num)
@@ -100,67 +99,70 @@ static uint32_t unin_get_config_reg(uint32_t reg, uint32_t addr)
     return retval;
 }
 
-static void unin_data_write(ReadWriteHandler *handler,
-                            pcibus_t addr, uint32_t val, int len)
+static void unin_data_write(void *opaque, target_phys_addr_t addr,
+                            uint64_t val, unsigned len)
 {
-    UNINState *s = container_of(handler, UNINState, data_handler);
-    UNIN_DPRINTF("write addr %" FMT_PCIBUS " len %d val %x\n", addr, len, val);
+    UNINState *s = opaque;
+    UNIN_DPRINTF("write addr %" TARGET_FMT_plx " len %d val %"PRIx64"\n",
+                 addr, len, val);
     pci_data_write(s->host_state.bus,
                    unin_get_config_reg(s->host_state.config_reg, addr),
                    val, len);
 }
 
-static uint32_t unin_data_read(ReadWriteHandler *handler,
-                               pcibus_t addr, int len)
+static uint64_t unin_data_read(void *opaque, target_phys_addr_t addr,
+                               unsigned len)
 {
-    UNINState *s = container_of(handler, UNINState, data_handler);
+    UNINState *s = opaque;
     uint32_t val;
 
     val = pci_data_read(s->host_state.bus,
                         unin_get_config_reg(s->host_state.config_reg, addr),
                         len);
-    UNIN_DPRINTF("read addr %" FMT_PCIBUS " len %d val %x\n", addr, len, val);
+    UNIN_DPRINTF("read addr %" TARGET_FMT_plx " len %d val %x\n",
+                 addr, len, val);
     return val;
 }
 
+static const MemoryRegionOps unin_data_ops = {
+    .read = unin_data_read,
+    .write = unin_data_write,
+    .endianness = DEVICE_LITTLE_ENDIAN,
+};
+
 static int pci_unin_main_init_device(SysBusDevice *dev)
 {
     UNINState *s;
-    int pci_mem_config, pci_mem_data;
 
     /* Use values found on a real PowerMac */
     /* Uninorth main bus */
     s = FROM_SYSBUS(UNINState, dev);
 
-    pci_mem_config = pci_host_conf_register_mmio(&s->host_state,
-                                                 DEVICE_LITTLE_ENDIAN);
-    s->data_handler.read = unin_data_read;
-    s->data_handler.write = unin_data_write;
-    pci_mem_data = cpu_register_io_memory_simple(&s->data_handler,
-                                                 DEVICE_LITTLE_ENDIAN);
-    sysbus_init_mmio(dev, 0x1000, pci_mem_config);
-    sysbus_init_mmio(dev, 0x1000, pci_mem_data);
+    memory_region_init_io(&s->host_state.conf_mem, &pci_host_conf_le_ops,
+                          &s->host_state, "pci-conf-idx", 0x1000);
+    memory_region_init_io(&s->host_state.data_mem, &unin_data_ops, s,
+                          "pci-conf-data", 0x1000);
+    sysbus_init_mmio_region(dev, &s->host_state.conf_mem);
+    sysbus_init_mmio_region(dev, &s->host_state.data_mem);
 
     qemu_register_reset(pci_unin_reset, &s->host_state);
     return 0;
 }
 
+
 static int pci_u3_agp_init_device(SysBusDevice *dev)
 {
     UNINState *s;
-    int pci_mem_config, pci_mem_data;
 
     /* Uninorth U3 AGP bus */
     s = FROM_SYSBUS(UNINState, dev);
 
-    pci_mem_config = pci_host_conf_register_mmio(&s->host_state,
-                                                 DEVICE_LITTLE_ENDIAN);
-    s->data_handler.read = unin_data_read;
-    s->data_handler.write = unin_data_write;
-    pci_mem_data = cpu_register_io_memory_simple(&s->data_handler,
-                                                 DEVICE_LITTLE_ENDIAN);
-    sysbus_init_mmio(dev, 0x1000, pci_mem_config);
-    sysbus_init_mmio(dev, 0x1000, pci_mem_data);
+    memory_region_init_io(&s->host_state.conf_mem, &pci_host_conf_le_ops,
+                          &s->host_state, "pci-conf-idx", 0x1000);
+    memory_region_init_io(&s->host_state.data_mem, &unin_data_ops, s,
+                          "pci-conf-data", 0x1000);
+    sysbus_init_mmio_region(dev, &s->host_state.conf_mem);
+    sysbus_init_mmio_region(dev, &s->host_state.data_mem);
 
     qemu_register_reset(pci_unin_reset, &s->host_state);
 
@@ -170,34 +172,32 @@ static int pci_u3_agp_init_device(SysBusDevice *dev)
 static int pci_unin_agp_init_device(SysBusDevice *dev)
 {
     UNINState *s;
-    int pci_mem_config, pci_mem_data;
 
     /* Uninorth AGP bus */
     s = FROM_SYSBUS(UNINState, dev);
 
-    pci_mem_config = pci_host_conf_register_mmio(&s->host_state,
-                                                 DEVICE_LITTLE_ENDIAN);
-    pci_mem_data = pci_host_data_register_mmio(&s->host_state,
-                                               DEVICE_LITTLE_ENDIAN);
-    sysbus_init_mmio(dev, 0x1000, pci_mem_config);
-    sysbus_init_mmio(dev, 0x1000, pci_mem_data);
+    memory_region_init_io(&s->host_state.conf_mem, &pci_host_conf_le_ops,
+                          &s->host_state, "pci-conf-idx", 0x1000);
+    memory_region_init_io(&s->host_state.data_mem, &pci_host_data_le_ops,
+                          &s->host_state, "pci-conf-data", 0x1000);
+    sysbus_init_mmio_region(dev, &s->host_state.conf_mem);
+    sysbus_init_mmio_region(dev, &s->host_state.data_mem);
     return 0;
 }
 
 static int pci_unin_internal_init_device(SysBusDevice *dev)
 {
     UNINState *s;
-    int pci_mem_config, pci_mem_data;
 
     /* Uninorth internal bus */
     s = FROM_SYSBUS(UNINState, dev);
 
-    pci_mem_config = pci_host_conf_register_mmio(&s->host_state,
-                                                 DEVICE_LITTLE_ENDIAN);
-    pci_mem_data = pci_host_data_register_mmio(&s->host_state,
-                                               DEVICE_LITTLE_ENDIAN);
-    sysbus_init_mmio(dev, 0x1000, pci_mem_config);
-    sysbus_init_mmio(dev, 0x1000, pci_mem_data);
+    memory_region_init_io(&s->host_state.conf_mem, &pci_host_conf_le_ops,
+                          &s->host_state, "pci-conf-idx", 0x1000);
+    memory_region_init_io(&s->host_state.data_mem, &pci_host_data_le_ops,
+                          &s->host_state, "pci-conf-data", 0x1000);
+    sysbus_init_mmio_region(dev, &s->host_state.conf_mem);
+    sysbus_init_mmio_region(dev, &s->host_state.data_mem);
     return 0;
 }
 
commit be35694da941168603b09a7420bcc476d745fc41
Author: Avi Kivity <avi at redhat.com>
Date:   Sun Jul 24 17:12:11 2011 +0300

    sysbus: add helpers to add and delete memory regions to the system bus
    
    Reviewed-by: Richard Henderson  <rth at twiddle.net>
    Signed-off-by: Avi Kivity <avi at redhat.com>

diff --git a/hw/sysbus.c b/hw/sysbus.c
index f39768b..f5f0ed2 100644
--- a/hw/sysbus.c
+++ b/hw/sysbus.c
@@ -256,3 +256,25 @@ static char *sysbus_get_fw_dev_path(DeviceState *dev)
 
     return strdup(path);
 }
+
+void sysbus_add_memory(SysBusDevice *dev, target_phys_addr_t addr,
+                       MemoryRegion *mem)
+{
+    memory_region_add_subregion(get_system_memory(), addr, mem);
+}
+
+void sysbus_del_memory(SysBusDevice *dev, MemoryRegion *mem)
+{
+    memory_region_del_subregion(get_system_memory(), mem);
+}
+
+void sysbus_add_io(SysBusDevice *dev, target_phys_addr_t addr,
+                       MemoryRegion *mem)
+{
+    memory_region_add_subregion(get_system_io(), addr, mem);
+}
+
+void sysbus_del_io(SysBusDevice *dev, MemoryRegion *mem)
+{
+    memory_region_del_subregion(get_system_io(), mem);
+}
diff --git a/hw/sysbus.h b/hw/sysbus.h
index b87c6c5..e4d56cf 100644
--- a/hw/sysbus.h
+++ b/hw/sysbus.h
@@ -57,6 +57,12 @@ void sysbus_init_ioports(SysBusDevice *dev, pio_addr_t ioport, pio_addr_t size);
 
 void sysbus_connect_irq(SysBusDevice *dev, int n, qemu_irq irq);
 void sysbus_mmio_map(SysBusDevice *dev, int n, target_phys_addr_t addr);
+void sysbus_add_memory(SysBusDevice *dev, target_phys_addr_t addr,
+                       MemoryRegion *mem);
+void sysbus_del_memory(SysBusDevice *dev, MemoryRegion *mem);
+void sysbus_add_io(SysBusDevice *dev, target_phys_addr_t addr,
+                   MemoryRegion *mem);
+void sysbus_del_io(SysBusDevice *dev, MemoryRegion *mem);
 
 /* Legacy helper function for creating devices.  */
 DeviceState *sysbus_create_varargs(const char *name,
commit 58160bafa2a0e0b915309c58e7d51f0e67831bf0
Author: Avi Kivity <avi at redhat.com>
Date:   Mon Jul 18 11:58:50 2011 +0300

    stellaris_enet: convert to memory API
    
    Reviewed-by: Richard Henderson  <rth at twiddle.net>
    Signed-off-by: Avi Kivity <avi at redhat.com>

diff --git a/hw/stellaris_enet.c b/hw/stellaris_enet.c
index f9bd3da..d5613ff 100644
--- a/hw/stellaris_enet.c
+++ b/hw/stellaris_enet.c
@@ -69,7 +69,7 @@ typedef struct {
     NICState *nic;
     NICConf conf;
     qemu_irq irq;
-    int mmio_index;
+    MemoryRegion mmio;
 } stellaris_enet_state;
 
 static void stellaris_enet_update(stellaris_enet_state *s)
@@ -130,7 +130,8 @@ static int stellaris_enet_can_receive(VLANClientState *nc)
     return (s->np < 31);
 }
 
-static uint32_t stellaris_enet_read(void *opaque, target_phys_addr_t offset)
+static uint64_t stellaris_enet_read(void *opaque, target_phys_addr_t offset,
+                                    unsigned size)
 {
     stellaris_enet_state *s = (stellaris_enet_state *)opaque;
     uint32_t val;
@@ -198,7 +199,7 @@ static uint32_t stellaris_enet_read(void *opaque, target_phys_addr_t offset)
 }
 
 static void stellaris_enet_write(void *opaque, target_phys_addr_t offset,
-                        uint32_t value)
+                                 uint64_t value, unsigned size)
 {
     stellaris_enet_state *s = (stellaris_enet_state *)opaque;
 
@@ -303,17 +304,12 @@ static void stellaris_enet_write(void *opaque, target_phys_addr_t offset,
     }
 }
 
-static CPUReadMemoryFunc * const stellaris_enet_readfn[] = {
-   stellaris_enet_read,
-   stellaris_enet_read,
-   stellaris_enet_read
+static const MemoryRegionOps stellaris_enet_ops = {
+    .read = stellaris_enet_read,
+    .write = stellaris_enet_write,
+    .endianness = DEVICE_NATIVE_ENDIAN,
 };
 
-static CPUWriteMemoryFunc * const stellaris_enet_writefn[] = {
-   stellaris_enet_write,
-   stellaris_enet_write,
-   stellaris_enet_write
-};
 static void stellaris_enet_reset(stellaris_enet_state *s)
 {
     s->mdv = 0x80;
@@ -391,7 +387,7 @@ static void stellaris_enet_cleanup(VLANClientState *nc)
 
     unregister_savevm(&s->busdev.qdev, "stellaris_enet", s);
 
-    cpu_unregister_io_memory(s->mmio_index);
+    memory_region_destroy(&s->mmio);
 
     g_free(s);
 }
@@ -408,10 +404,9 @@ static int stellaris_enet_init(SysBusDevice *dev)
 {
     stellaris_enet_state *s = FROM_SYSBUS(stellaris_enet_state, dev);
 
-    s->mmio_index = cpu_register_io_memory(stellaris_enet_readfn,
-                                           stellaris_enet_writefn, s,
-                                           DEVICE_NATIVE_ENDIAN);
-    sysbus_init_mmio(dev, 0x1000, s->mmio_index);
+    memory_region_init_io(&s->mmio, &stellaris_enet_ops, s, "stellaris_enet",
+                          0x1000);
+    sysbus_init_mmio_region(dev, &s->mmio);
     sysbus_init_irq(dev, &s->irq);
     qemu_macaddr_default_if_unset(&s->conf.macaddr);
 
commit 2df4624662103eb007428e6ded3b3496a952b154
Author: MORITA Kazutaka <morita.kazutaka at lab.ntt.co.jp>
Date:   Fri Aug 12 21:33:15 2011 +0900

    sheepdog: use coroutines
    
    This makes the sheepdog block driver support bdrv_co_readv/writev
    instead of bdrv_aio_readv/writev.
    
    With this patch, Sheepdog network I/O becomes fully asynchronous.  The
    block driver yields back when send/recv returns EAGAIN, and is resumed
    when the sheepdog network connection is ready for the operation.
    
    Signed-off-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 57b6e1a..c1f6e07 100644
--- a/block/sheepdog.c
+++ b/block/sheepdog.c
@@ -274,7 +274,7 @@ struct SheepdogAIOCB {
     int ret;
     enum AIOCBState aiocb_type;
 
-    QEMUBH *bh;
+    Coroutine *coroutine;
     void (*aio_done_func)(SheepdogAIOCB *);
 
     int canceled;
@@ -295,6 +295,10 @@ typedef struct BDRVSheepdogState {
     char *port;
     int fd;
 
+    CoMutex lock;
+    Coroutine *co_send;
+    Coroutine *co_recv;
+
     uint32_t aioreq_seq_num;
     QLIST_HEAD(outstanding_aio_head, AIOReq) outstanding_aio_head;
 } BDRVSheepdogState;
@@ -346,19 +350,16 @@ static const char * sd_strerror(int err)
 /*
  * Sheepdog I/O handling:
  *
- * 1. In the sd_aio_readv/writev, read/write requests are added to the
- *    QEMU Bottom Halves.
- *
- * 2. In sd_readv_writev_bh_cb, the callbacks of BHs, we send the I/O
- *    requests to the server and link the requests to the
- *    outstanding_list in the BDRVSheepdogState.  we exits the
- *    function without waiting for receiving the response.
+ * 1. In sd_co_rw_vector, we send the I/O requests to the server and
+ *    link the requests to the outstanding_list in the
+ *    BDRVSheepdogState.  The function exits without waiting for
+ *    receiving the response.
  *
- * 3. We receive the response in aio_read_response, the fd handler to
+ * 2. We receive the response in aio_read_response, the fd handler to
  *    the sheepdog connection.  If metadata update is needed, we send
  *    the write request to the vdi object in sd_write_done, the write
- *    completion function.  The AIOCB callback is not called until all
- *    the requests belonging to the AIOCB are finished.
+ *    completion function.  We switch back to sd_co_readv/writev after
+ *    all the requests belonging to the AIOCB are finished.
  */
 
 static inline AIOReq *alloc_aio_req(BDRVSheepdogState *s, SheepdogAIOCB *acb,
@@ -398,7 +399,7 @@ static inline int free_aio_req(BDRVSheepdogState *s, AIOReq *aio_req)
 static void sd_finish_aiocb(SheepdogAIOCB *acb)
 {
     if (!acb->canceled) {
-        acb->common.cb(acb->common.opaque, acb->ret);
+        qemu_coroutine_enter(acb->coroutine, NULL);
     }
     qemu_aio_release(acb);
 }
@@ -411,7 +412,8 @@ static void sd_aio_cancel(BlockDriverAIOCB *blockacb)
      * Sheepdog cannot cancel the requests which are already sent to
      * the servers, so we just complete the request with -EIO here.
      */
-    acb->common.cb(acb->common.opaque, -EIO);
+    acb->ret = -EIO;
+    qemu_coroutine_enter(acb->coroutine, NULL);
     acb->canceled = 1;
 }
 
@@ -435,24 +437,12 @@ static SheepdogAIOCB *sd_aio_setup(BlockDriverState *bs, QEMUIOVector *qiov,
 
     acb->aio_done_func = NULL;
     acb->canceled = 0;
-    acb->bh = NULL;
+    acb->coroutine = qemu_coroutine_self();
     acb->ret = 0;
     QLIST_INIT(&acb->aioreq_head);
     return acb;
 }
 
-static int sd_schedule_bh(QEMUBHFunc *cb, SheepdogAIOCB *acb)
-{
-    if (acb->bh) {
-        error_report("bug: %d %d", acb->aiocb_type, acb->aiocb_type);
-        return -EIO;
-    }
-
-    acb->bh = qemu_bh_new(cb, acb);
-    qemu_bh_schedule(acb->bh);
-    return 0;
-}
-
 #ifdef _WIN32
 
 struct msghdr {
@@ -635,7 +625,13 @@ static int do_readv_writev(int sockfd, struct iovec *iov, int len,
 again:
     ret = do_send_recv(sockfd, iov, len, iov_offset, write);
     if (ret < 0) {
-        if (errno == EINTR || errno == EAGAIN) {
+        if (errno == EINTR) {
+            goto again;
+        }
+        if (errno == EAGAIN) {
+            if (qemu_in_coroutine()) {
+                qemu_coroutine_yield();
+            }
             goto again;
         }
         error_report("failed to recv a rsp, %s", strerror(errno));
@@ -793,14 +789,14 @@ static void aio_read_response(void *opaque)
     unsigned long idx;
 
     if (QLIST_EMPTY(&s->outstanding_aio_head)) {
-        return;
+        goto out;
     }
 
     /* read a header */
     ret = do_read(fd, &rsp, sizeof(rsp));
     if (ret) {
         error_report("failed to get the header, %s", strerror(errno));
-        return;
+        goto out;
     }
 
     /* find the right aio_req from the outstanding_aio list */
@@ -811,7 +807,7 @@ static void aio_read_response(void *opaque)
     }
     if (!aio_req) {
         error_report("cannot find aio_req %x", rsp.id);
-        return;
+        goto out;
     }
 
     acb = aio_req->aiocb;
@@ -847,7 +843,7 @@ static void aio_read_response(void *opaque)
                        aio_req->iov_offset);
         if (ret) {
             error_report("failed to get the data, %s", strerror(errno));
-            return;
+            goto out;
         }
         break;
     }
@@ -861,10 +857,30 @@ static void aio_read_response(void *opaque)
     if (!rest) {
         /*
          * We've finished all requests which belong to the AIOCB, so
-         * we can call the callback now.
+         * we can switch back to sd_co_readv/writev now.
          */
         acb->aio_done_func(acb);
     }
+out:
+    s->co_recv = NULL;
+}
+
+static void co_read_response(void *opaque)
+{
+    BDRVSheepdogState *s = opaque;
+
+    if (!s->co_recv) {
+        s->co_recv = qemu_coroutine_create(aio_read_response);
+    }
+
+    qemu_coroutine_enter(s->co_recv, opaque);
+}
+
+static void co_write_request(void *opaque)
+{
+    BDRVSheepdogState *s = opaque;
+
+    qemu_coroutine_enter(s->co_send, NULL);
 }
 
 static int aio_flush_request(void *opaque)
@@ -924,7 +940,7 @@ static int get_sheep_fd(BDRVSheepdogState *s)
         return -1;
     }
 
-    qemu_aio_set_fd_handler(fd, aio_read_response, NULL, aio_flush_request,
+    qemu_aio_set_fd_handler(fd, co_read_response, NULL, aio_flush_request,
                             NULL, s);
     return fd;
 }
@@ -1091,6 +1107,10 @@ static int add_aio_request(BDRVSheepdogState *s, AIOReq *aio_req,
 
     hdr.id = aio_req->id;
 
+    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, NULL, s);
     set_cork(s->fd, 1);
 
     /* send a header */
@@ -1109,6 +1129,9 @@ static int add_aio_request(BDRVSheepdogState *s, AIOReq *aio_req,
     }
 
     set_cork(s->fd, 0);
+    qemu_aio_set_fd_handler(s->fd, co_read_response, NULL,
+                            aio_flush_request, NULL, s);
+    qemu_co_mutex_unlock(&s->lock);
 
     return 0;
 }
@@ -1225,6 +1248,7 @@ static int sd_open(BlockDriverState *bs, const char *filename, int flags)
 
     bs->total_sectors = s->inode.vdi_size / SECTOR_SIZE;
     strncpy(s->name, vdi, sizeof(s->name));
+    qemu_co_mutex_init(&s->lock);
     g_free(buf);
     return 0;
 out:
@@ -1491,7 +1515,7 @@ static int sd_truncate(BlockDriverState *bs, int64_t offset)
 /*
  * This function is called after writing data objects.  If we need to
  * update metadata, this sends a write request to the vdi object.
- * Otherwise, this calls the AIOCB callback.
+ * Otherwise, this switches back to sd_co_readv/writev.
  */
 static void sd_write_done(SheepdogAIOCB *acb)
 {
@@ -1587,8 +1611,11 @@ out:
  * waiting the response.  The responses are received in the
  * `aio_read_response' function which is called from the main loop as
  * a fd handler.
+ *
+ * Returns 1 when we need to wait a response, 0 when there is no sent
+ * request and -errno in error cases.
  */
-static void sd_readv_writev_bh_cb(void *p)
+static int sd_co_rw_vector(void *p)
 {
     SheepdogAIOCB *acb = p;
     int ret = 0;
@@ -1600,9 +1627,6 @@ static void sd_readv_writev_bh_cb(void *p)
     SheepdogInode *inode = &s->inode;
     AIOReq *aio_req;
 
-    qemu_bh_delete(acb->bh);
-    acb->bh = NULL;
-
     if (acb->aiocb_type == AIOCB_WRITE_UDATA && s->is_snapshot) {
         /*
          * In the case we open the snapshot VDI, Sheepdog creates the
@@ -1684,42 +1708,47 @@ static void sd_readv_writev_bh_cb(void *p)
     }
 out:
     if (QLIST_EMPTY(&acb->aioreq_head)) {
-        sd_finish_aiocb(acb);
+        return acb->ret;
     }
+    return 1;
 }
 
-static BlockDriverAIOCB *sd_aio_writev(BlockDriverState *bs, int64_t sector_num,
-                                       QEMUIOVector *qiov, int nb_sectors,
-                                       BlockDriverCompletionFunc *cb,
-                                       void *opaque)
+static int sd_co_writev(BlockDriverState *bs, int64_t sector_num,
+                        int nb_sectors, QEMUIOVector *qiov)
 {
     SheepdogAIOCB *acb;
+    int ret;
 
     if (bs->growable && sector_num + nb_sectors > bs->total_sectors) {
         /* TODO: shouldn't block here */
         if (sd_truncate(bs, (sector_num + nb_sectors) * SECTOR_SIZE) < 0) {
-            return NULL;
+            return -EIO;
         }
         bs->total_sectors = sector_num + nb_sectors;
     }
 
-    acb = sd_aio_setup(bs, qiov, sector_num, nb_sectors, cb, opaque);
+    acb = sd_aio_setup(bs, qiov, sector_num, nb_sectors, NULL, NULL);
     acb->aio_done_func = sd_write_done;
     acb->aiocb_type = AIOCB_WRITE_UDATA;
 
-    sd_schedule_bh(sd_readv_writev_bh_cb, acb);
-    return &acb->common;
+    ret = sd_co_rw_vector(acb);
+    if (ret <= 0) {
+        qemu_aio_release(acb);
+        return ret;
+    }
+
+    qemu_coroutine_yield();
+
+    return acb->ret;
 }
 
-static BlockDriverAIOCB *sd_aio_readv(BlockDriverState *bs, int64_t sector_num,
-                                      QEMUIOVector *qiov, int nb_sectors,
-                                      BlockDriverCompletionFunc *cb,
-                                      void *opaque)
+static int sd_co_readv(BlockDriverState *bs, int64_t sector_num,
+                       int nb_sectors, QEMUIOVector *qiov)
 {
     SheepdogAIOCB *acb;
-    int i;
+    int i, ret;
 
-    acb = sd_aio_setup(bs, qiov, sector_num, nb_sectors, cb, opaque);
+    acb = sd_aio_setup(bs, qiov, sector_num, nb_sectors, NULL, NULL);
     acb->aiocb_type = AIOCB_READ_UDATA;
     acb->aio_done_func = sd_finish_aiocb;
 
@@ -1731,8 +1760,15 @@ static BlockDriverAIOCB *sd_aio_readv(BlockDriverState *bs, int64_t sector_num,
         memset(qiov->iov[i].iov_base, 0, qiov->iov[i].iov_len);
     }
 
-    sd_schedule_bh(sd_readv_writev_bh_cb, acb);
-    return &acb->common;
+    ret = sd_co_rw_vector(acb);
+    if (ret <= 0) {
+        qemu_aio_release(acb);
+        return ret;
+    }
+
+    qemu_coroutine_yield();
+
+    return acb->ret;
 }
 
 static int sd_snapshot_create(BlockDriverState *bs, QEMUSnapshotInfo *sn_info)
@@ -2062,8 +2098,8 @@ BlockDriver bdrv_sheepdog = {
     .bdrv_getlength = sd_getlength,
     .bdrv_truncate  = sd_truncate,
 
-    .bdrv_aio_readv     = sd_aio_readv,
-    .bdrv_aio_writev    = sd_aio_writev,
+    .bdrv_co_readv  = sd_co_readv,
+    .bdrv_co_writev = sd_co_writev,
 
     .bdrv_snapshot_create   = sd_snapshot_create,
     .bdrv_snapshot_goto     = sd_snapshot_goto,
commit c9abe111209abca1b910e35c6ca9888aced5f183
Author: Jan Kiszka <jan.kiszka at siemens.com>
Date:   Wed Aug 24 14:29:30 2011 +0200

    pci: Error on PCI capability collisions
    
    Nothing good can happen when we overlap capabilities. This may happen
    when plugging in assigned devices or when devices models contain bugs.
    Detect the overlap and report it.
    
    Based on qemu-kvm commit by Alex Williamson.
    
    Signed-off-by: Jan Kiszka <jan.kiszka at siemens.com>
    Acked-by: Don Dutile <ddutile at redhat.com>
    Signed-off-by: Michael S. Tsirkin <mst at redhat.com>

diff --git a/hw/pci.c b/hw/pci.c
index 6124790..57ff7b1 100644
--- a/hw/pci.c
+++ b/hw/pci.c
@@ -1811,6 +1811,25 @@ static uint8_t pci_find_capability_list(PCIDevice *pdev, uint8_t cap_id,
     return next;
 }
 
+static uint8_t pci_find_capability_at_offset(PCIDevice *pdev, uint8_t offset)
+{
+    uint8_t next, prev, found = 0;
+
+    if (!(pdev->used[offset])) {
+        return 0;
+    }
+
+    assert(pdev->config[PCI_STATUS] & PCI_STATUS_CAP_LIST);
+
+    for (prev = PCI_CAPABILITY_LIST; (next = pdev->config[prev]);
+         prev = next + PCI_CAP_LIST_NEXT) {
+        if (next <= offset && next > found) {
+            found = next;
+        }
+    }
+    return found;
+}
+
 /* Patch the PCI vendor and device ids in a PCI rom image if necessary.
    This is needed for an option rom which is used for more than one device. */
 static void pci_patch_ids(PCIDevice *pdev, uint8_t *ptr, int size)
@@ -1952,11 +1971,30 @@ int pci_add_capability(PCIDevice *pdev, uint8_t cap_id,
                        uint8_t offset, uint8_t size)
 {
     uint8_t *config;
+    int i, overlapping_cap;
+
     if (!offset) {
         offset = pci_find_space(pdev, size);
         if (!offset) {
             return -ENOSPC;
         }
+    } else {
+        /* Verify that capabilities don't overlap.  Note: device assignment
+         * depends on this check to verify that the device is not broken.
+         * Should never trigger for emulated devices, but it's helpful
+         * for debugging these. */
+        for (i = offset; i < offset + size; i++) {
+            overlapping_cap = pci_find_capability_at_offset(pdev, i);
+            if (overlapping_cap) {
+                fprintf(stderr, "ERROR: %04x:%02x:%02x.%x "
+                        "Attempt to add PCI capability %x at offset "
+                        "%x overlaps existing capability %x at offset %x\n",
+                        pci_find_domain(pdev->bus), pci_bus_num(pdev->bus),
+                        PCI_SLOT(pdev->devfn), PCI_FUNC(pdev->devfn),
+                        cap_id, offset, overlapping_cap, i);
+                return -EINVAL;
+            }
+        }
     }
 
     config = pdev->config + offset;
commit 74d63b65479f4d8a72c1bba54256eee029cd5d5f
Author: Isaku Yamahata <yamahata at valinux.co.jp>
Date:   Fri Aug 5 18:22:06 2011 +0900

    pcie/aer: fix inject aer error command
    
    various fixes to make aer inject error command work.
    - wrong assert
    - command line parser
    - err.status needs initialization
    
    Signed-off-by: Isaku Yamahata <yamahata at valinux.co.jp>
    Signed-off-by: Michael S. Tsirkin <mst at redhat.com>

diff --git a/hw/pcie_aer.c b/hw/pcie_aer.c
index 2ae65ec..62c06ea 100644
--- a/hw/pcie_aer.c
+++ b/hw/pcie_aer.c
@@ -415,7 +415,7 @@ static void pcie_aer_update_log(PCIDevice *dev, const PCIEAERErr *err)
     int i;
 
     assert(err->status);
-    assert(err->status & (err->status - 1));
+    assert(!(err->status & (err->status - 1)));
 
     errcap &= ~(PCI_ERR_CAP_FEP_MASK | PCI_ERR_CAP_TLP);
     errcap |= PCI_ERR_CAP_FEP(first_bit);
@@ -495,7 +495,7 @@ static int pcie_aer_record_error(PCIDevice *dev,
     int fep = PCI_ERR_CAP_FEP(errcap);
 
     assert(err->status);
-    assert(err->status & (err->status - 1));
+    assert(!(err->status & (err->status - 1)));
 
     if (errcap & PCI_ERR_CAP_MHRE &&
         (pci_get_long(aer_cap + PCI_ERR_UNCOR_STATUS) & (1U << fep))) {
@@ -979,20 +979,21 @@ int do_pcie_aer_inejct_error(Monitor *mon,
     if (pcie_aer_parse_error_string(error_name, &error_status, &correctable)) {
         char *e = NULL;
         error_status = strtoul(error_name, &e, 0);
-        correctable = !!qdict_get_int(qdict, "correctable");
+        correctable = qdict_get_try_bool(qdict, "correctable", 0);
         if (!e || *e != '\0') {
             monitor_printf(mon, "invalid error status value. \"%s\"",
                            error_name);
             return -EINVAL;
         }
     }
+    err.status = error_status;
     err.source_id = (pci_bus_num(dev->bus) << 8) | dev->devfn;
 
     err.flags = 0;
     if (correctable) {
         err.flags |= PCIE_AER_ERR_IS_CORRECTABLE;
     }
-    if (qdict_get_int(qdict, "advisory_non_fatal")) {
+    if (qdict_get_try_bool(qdict, "advisory_non_fatal", 0)) {
         err.flags |= PCIE_AER_ERR_MAYBE_ADVISORY;
     }
     if (qdict_haskey(qdict, "header0")) {
commit 1553d4f1fc6b7455234de93d105e7b46bc7a0844
Author: Isaku Yamahata <yamahata at valinux.co.jp>
Date:   Fri Aug 5 18:22:03 2011 +0900

    pcie/slot: fix hotplug event
    
    When slot status register is cleared, PCIDevice::exp.hpev_notify
    needs to be cleared.
    Otherwise, PCIDevice::exp.hpev_notify is never set to false resulting
    in no more hot plug event once it's raised.
    
    Signed-off-by: Isaku Yamahata <yamahata at valinux.co.jp>
    Signed-off-by: Michael S. Tsirkin <mst at redhat.com>

diff --git a/hw/pcie.c b/hw/pcie.c
index 39607bf..5c9eb2f 100644
--- a/hw/pcie.c
+++ b/hw/pcie.c
@@ -175,6 +175,14 @@ static void hotplug_event_notify(PCIDevice *dev)
     }
 }
 
+static void hotplug_event_clear(PCIDevice *dev)
+{
+    hotplug_event_update_event_status(dev);
+    if (!msix_enabled(dev) && !msi_enabled(dev) && !dev->exp.hpev_notified) {
+        qemu_set_irq(dev->irq[dev->exp.hpev_intx], 0);
+    }
+}
+
 /*
  * A PCI Express Hot-Plug Event has occurred, so update slot status register
  * and notify OS of the event if necessary.
@@ -320,6 +328,10 @@ void pcie_cap_slot_write_config(PCIDevice *dev,
     uint8_t *exp_cap = dev->config + pos;
     uint16_t sltsta = pci_get_word(exp_cap + PCI_EXP_SLTSTA);
 
+    if (ranges_overlap(addr, len, pos + PCI_EXP_SLTSTA, 2)) {
+        hotplug_event_clear(dev);
+    }
+
     if (!ranges_overlap(addr, len, pos + PCI_EXP_SLTCTL, 2)) {
         return;
     }
commit e8906f3529a452276375ab8e7b8598751bc33b01
Author: Alexander Graf <agraf at suse.de>
Date:   Tue Aug 23 06:55:44 2011 +0200

    PPC: E500: Set ESR values
    
    When an exception occurs on BookE, we need to set ESR bits to expose
    to the guest information on what exactly happened. Add the obvious ones.
    
    Reported-by: Jason Wessel <jason.wessel at windriver.com>
    Signed-off-by: Alexander Graf <agraf at suse.de>
    Signed-off-by: Edgar E. Iglesias <edgar.iglesias at gmail.com>

diff --git a/target-ppc/helper.c b/target-ppc/helper.c
index c23d4a4..5ec83f2 100644
--- a/target-ppc/helper.c
+++ b/target-ppc/helper.c
@@ -2484,16 +2484,19 @@ static inline void powerpc_excp(CPUState *env, int excp_model, int excp)
             if (lpes1 == 0)
                 new_msr |= (target_ulong)MSR_HVB;
             msr |= 0x00080000;
+            env->spr[SPR_BOOKE_ESR] = ESR_PIL;
             break;
         case POWERPC_EXCP_PRIV:
             if (lpes1 == 0)
                 new_msr |= (target_ulong)MSR_HVB;
             msr |= 0x00040000;
+            env->spr[SPR_BOOKE_ESR] = ESR_PPR;
             break;
         case POWERPC_EXCP_TRAP:
             if (lpes1 == 0)
                 new_msr |= (target_ulong)MSR_HVB;
             msr |= 0x00020000;
+            env->spr[SPR_BOOKE_ESR] = ESR_PTR;
             break;
         default:
             /* Should never occur */
@@ -2556,16 +2559,19 @@ static inline void powerpc_excp(CPUState *env, int excp_model, int excp)
         cpu_abort(env, "Debug exception is not implemented yet !\n");
         goto store_next;
     case POWERPC_EXCP_SPEU:      /* SPE/embedded floating-point unavailable  */
+        env->spr[SPR_BOOKE_ESR] = ESR_SPV;
         goto store_current;
     case POWERPC_EXCP_EFPDI:     /* Embedded floating-point data interrupt   */
         /* XXX: TODO */
         cpu_abort(env, "Embedded floating point data exception "
                   "is not implemented yet !\n");
+        env->spr[SPR_BOOKE_ESR] = ESR_SPV;
         goto store_next;
     case POWERPC_EXCP_EFPRI:     /* Embedded floating-point round interrupt  */
         /* XXX: TODO */
         cpu_abort(env, "Embedded floating point round exception "
                   "is not implemented yet !\n");
+        env->spr[SPR_BOOKE_ESR] = ESR_SPV;
         goto store_next;
     case POWERPC_EXCP_EPERFM:    /* Embedded performance monitor interrupt   */
         /* XXX: TODO */
commit 27a69bb088bee6d4efea254659422fb9c751b3c7
Author: Alexander Graf <agraf at suse.de>
Date:   Tue Aug 23 06:55:43 2011 +0200

    PPC: E500: Inject SPE exception on invalid SPE access
    
    When accessing an SPE instruction despite it being not available,
    throw an SPE exception instead of an APU exception. That way the
    guest knows what's going on and actually uses SPE.
    
    Reported-by: Jason Wessel <jason.wessel at windriver.com>
    Signed-off-by: Alexander Graf <agraf at suse.de>
    Signed-off-by: Edgar E. Iglesias <edgar.iglesias at gmail.com>

diff --git a/target-ppc/translate.c b/target-ppc/translate.c
index fd7c208..4277460 100644
--- a/target-ppc/translate.c
+++ b/target-ppc/translate.c
@@ -6622,7 +6622,7 @@ static inline void gen_evmra(DisasContext *ctx)
 {
 
     if (unlikely(!ctx->spe_enabled)) {
-        gen_exception(ctx, POWERPC_EXCP_APU);
+        gen_exception(ctx, POWERPC_EXCP_SPEU);
         return;
     }
 
@@ -6693,7 +6693,7 @@ static inline void gen_speundef(DisasContext *ctx)
 static inline void gen_##name(DisasContext *ctx)                              \
 {                                                                             \
     if (unlikely(!ctx->spe_enabled)) {                                        \
-        gen_exception(ctx, POWERPC_EXCP_APU);                                 \
+        gen_exception(ctx, POWERPC_EXCP_SPEU);                                \
         return;                                                               \
     }                                                                         \
     tcg_op(cpu_gpr[rD(ctx->opcode)], cpu_gpr[rA(ctx->opcode)],                \
@@ -6704,7 +6704,7 @@ static inline void gen_##name(DisasContext *ctx)                              \
 static inline void gen_##name(DisasContext *ctx)                              \
 {                                                                             \
     if (unlikely(!ctx->spe_enabled)) {                                        \
-        gen_exception(ctx, POWERPC_EXCP_APU);                                 \
+        gen_exception(ctx, POWERPC_EXCP_SPEU);                                \
         return;                                                               \
     }                                                                         \
     tcg_op(cpu_gpr[rD(ctx->opcode)], cpu_gpr[rA(ctx->opcode)],                \
@@ -6729,7 +6729,7 @@ GEN_SPEOP_LOGIC2(evnand, tcg_gen_nand_tl);
 static inline void gen_##name(DisasContext *ctx)                              \
 {                                                                             \
     if (unlikely(!ctx->spe_enabled)) {                                        \
-        gen_exception(ctx, POWERPC_EXCP_APU);                                 \
+        gen_exception(ctx, POWERPC_EXCP_SPEU);                                \
         return;                                                               \
     }                                                                         \
     TCGv_i32 t0 = tcg_temp_local_new_i32();                                   \
@@ -6750,7 +6750,7 @@ static inline void gen_##name(DisasContext *ctx)                              \
 static inline void gen_##name(DisasContext *ctx)                              \
 {                                                                             \
     if (unlikely(!ctx->spe_enabled)) {                                        \
-        gen_exception(ctx, POWERPC_EXCP_APU);                                 \
+        gen_exception(ctx, POWERPC_EXCP_SPEU);                                \
         return;                                                               \
     }                                                                         \
     tcg_opi(cpu_gpr[rD(ctx->opcode)], cpu_gpr[rA(ctx->opcode)],               \
@@ -6770,7 +6770,7 @@ GEN_SPEOP_TCG_LOGIC_IMM2(evrlwi, tcg_gen_rotli_i32);
 static inline void gen_##name(DisasContext *ctx)                              \
 {                                                                             \
     if (unlikely(!ctx->spe_enabled)) {                                        \
-        gen_exception(ctx, POWERPC_EXCP_APU);                                 \
+        gen_exception(ctx, POWERPC_EXCP_SPEU);                                \
         return;                                                               \
     }                                                                         \
     TCGv_i32 t0 = tcg_temp_local_new_i32();                                   \
@@ -6791,7 +6791,7 @@ static inline void gen_##name(DisasContext *ctx)                              \
 static inline void gen_##name(DisasContext *ctx)                              \
 {                                                                             \
     if (unlikely(!ctx->spe_enabled)) {                                        \
-        gen_exception(ctx, POWERPC_EXCP_APU);                                 \
+        gen_exception(ctx, POWERPC_EXCP_SPEU);                                \
         return;                                                               \
     }                                                                         \
     tcg_op(cpu_gpr[rD(ctx->opcode)], cpu_gpr[rA(ctx->opcode)]);               \
@@ -6829,7 +6829,7 @@ GEN_SPEOP_ARITH1(evcntlzw, gen_helper_cntlzw32);
 static inline void gen_##name(DisasContext *ctx)                              \
 {                                                                             \
     if (unlikely(!ctx->spe_enabled)) {                                        \
-        gen_exception(ctx, POWERPC_EXCP_APU);                                 \
+        gen_exception(ctx, POWERPC_EXCP_SPEU);                                \
         return;                                                               \
     }                                                                         \
     TCGv_i32 t0 = tcg_temp_local_new_i32();                                   \
@@ -6855,7 +6855,7 @@ static inline void gen_##name(DisasContext *ctx)                              \
 static inline void gen_##name(DisasContext *ctx)                              \
 {                                                                             \
     if (unlikely(!ctx->spe_enabled)) {                                        \
-        gen_exception(ctx, POWERPC_EXCP_APU);                                 \
+        gen_exception(ctx, POWERPC_EXCP_SPEU);                                \
         return;                                                               \
     }                                                                         \
     tcg_op(cpu_gpr[rD(ctx->opcode)], cpu_gpr[rA(ctx->opcode)],                \
@@ -6933,7 +6933,7 @@ GEN_SPEOP_ARITH2(evrlw, gen_op_evrlw);
 static inline void gen_evmergehi(DisasContext *ctx)
 {
     if (unlikely(!ctx->spe_enabled)) {
-        gen_exception(ctx, POWERPC_EXCP_APU);
+        gen_exception(ctx, POWERPC_EXCP_SPEU);
         return;
     }
 #if defined(TARGET_PPC64)
@@ -6962,7 +6962,7 @@ GEN_SPEOP_ARITH2(evsubfw, gen_op_evsubf);
 static inline void gen_##name(DisasContext *ctx)                              \
 {                                                                             \
     if (unlikely(!ctx->spe_enabled)) {                                        \
-        gen_exception(ctx, POWERPC_EXCP_APU);                                 \
+        gen_exception(ctx, POWERPC_EXCP_SPEU);                                \
         return;                                                               \
     }                                                                         \
     TCGv_i32 t0 = tcg_temp_local_new_i32();                                   \
@@ -6983,7 +6983,7 @@ static inline void gen_##name(DisasContext *ctx)                              \
 static inline void gen_##name(DisasContext *ctx)                              \
 {                                                                             \
     if (unlikely(!ctx->spe_enabled)) {                                        \
-        gen_exception(ctx, POWERPC_EXCP_APU);                                 \
+        gen_exception(ctx, POWERPC_EXCP_SPEU);                                \
         return;                                                               \
     }                                                                         \
     tcg_op(cpu_gpr[rD(ctx->opcode)], cpu_gpr[rB(ctx->opcode)],                \
@@ -7001,7 +7001,7 @@ GEN_SPEOP_ARITH_IMM2(evsubifw, tcg_gen_subi_i32);
 static inline void gen_##name(DisasContext *ctx)                              \
 {                                                                             \
     if (unlikely(!ctx->spe_enabled)) {                                        \
-        gen_exception(ctx, POWERPC_EXCP_APU);                                 \
+        gen_exception(ctx, POWERPC_EXCP_SPEU);                                \
         return;                                                               \
     }                                                                         \
     int l1 = gen_new_label();                                                 \
@@ -7041,7 +7041,7 @@ static inline void gen_##name(DisasContext *ctx)                              \
 static inline void gen_##name(DisasContext *ctx)                              \
 {                                                                             \
     if (unlikely(!ctx->spe_enabled)) {                                        \
-        gen_exception(ctx, POWERPC_EXCP_APU);                                 \
+        gen_exception(ctx, POWERPC_EXCP_SPEU);                                \
         return;                                                               \
     }                                                                         \
     int l1 = gen_new_label();                                                 \
@@ -7084,7 +7084,7 @@ static inline void gen_brinc(DisasContext *ctx)
 static inline void gen_evmergelo(DisasContext *ctx)
 {
     if (unlikely(!ctx->spe_enabled)) {
-        gen_exception(ctx, POWERPC_EXCP_APU);
+        gen_exception(ctx, POWERPC_EXCP_SPEU);
         return;
     }
 #if defined(TARGET_PPC64)
@@ -7103,7 +7103,7 @@ static inline void gen_evmergelo(DisasContext *ctx)
 static inline void gen_evmergehilo(DisasContext *ctx)
 {
     if (unlikely(!ctx->spe_enabled)) {
-        gen_exception(ctx, POWERPC_EXCP_APU);
+        gen_exception(ctx, POWERPC_EXCP_SPEU);
         return;
     }
 #if defined(TARGET_PPC64)
@@ -7122,7 +7122,7 @@ static inline void gen_evmergehilo(DisasContext *ctx)
 static inline void gen_evmergelohi(DisasContext *ctx)
 {
     if (unlikely(!ctx->spe_enabled)) {
-        gen_exception(ctx, POWERPC_EXCP_APU);
+        gen_exception(ctx, POWERPC_EXCP_SPEU);
         return;
     }
 #if defined(TARGET_PPC64)
@@ -7245,7 +7245,7 @@ static inline void gen_evmwumi(DisasContext *ctx)
     TCGv_i64 t0, t1;
 
     if (unlikely(!ctx->spe_enabled)) {
-        gen_exception(ctx, POWERPC_EXCP_APU);
+        gen_exception(ctx, POWERPC_EXCP_SPEU);
         return;
     }
 
@@ -7274,7 +7274,7 @@ static inline void gen_evmwumia(DisasContext *ctx)
     TCGv_i64 tmp;
 
     if (unlikely(!ctx->spe_enabled)) {
-        gen_exception(ctx, POWERPC_EXCP_APU);
+        gen_exception(ctx, POWERPC_EXCP_SPEU);
         return;
     }
 
@@ -7294,7 +7294,7 @@ static inline void gen_evmwumiaa(DisasContext *ctx)
     TCGv_i64 tmp;
 
     if (unlikely(!ctx->spe_enabled)) {
-        gen_exception(ctx, POWERPC_EXCP_APU);
+        gen_exception(ctx, POWERPC_EXCP_SPEU);
         return;
     }
 
@@ -7327,7 +7327,7 @@ static inline void gen_evmwsmi(DisasContext *ctx)
     TCGv_i64 t0, t1;
 
     if (unlikely(!ctx->spe_enabled)) {
-        gen_exception(ctx, POWERPC_EXCP_APU);
+        gen_exception(ctx, POWERPC_EXCP_SPEU);
         return;
     }
 
@@ -7746,7 +7746,7 @@ static void glue(gen_, name)(DisasContext *ctx)
 {                                                                             \
     TCGv t0;                                                                  \
     if (unlikely(!ctx->spe_enabled)) {                                        \
-        gen_exception(ctx, POWERPC_EXCP_APU);                                 \
+        gen_exception(ctx, POWERPC_EXCP_SPEU);                                \
         return;                                                               \
     }                                                                         \
     gen_set_access_type(ctx, ACCESS_INT);                                     \
@@ -7904,7 +7904,7 @@ static inline void gen_##name(DisasContext *ctx)                              \
     TCGv_i32 t0, t1;                                                          \
     TCGv_i64 t2;                                                              \
     if (unlikely(!ctx->spe_enabled)) {                                        \
-        gen_exception(ctx, POWERPC_EXCP_APU);                                 \
+        gen_exception(ctx, POWERPC_EXCP_SPEU);                                \
         return;                                                               \
     }                                                                         \
     t0 = tcg_temp_new_i32();                                                  \
@@ -7925,7 +7925,7 @@ static inline void gen_##name(DisasContext *ctx)                              \
 static inline void gen_##name(DisasContext *ctx)                              \
 {                                                                             \
     if (unlikely(!ctx->spe_enabled)) {                                        \
-        gen_exception(ctx, POWERPC_EXCP_APU);                                 \
+        gen_exception(ctx, POWERPC_EXCP_SPEU);                                \
         return;                                                               \
     }                                                                         \
     gen_helper_##name(cpu_gpr[rD(ctx->opcode)], cpu_gpr[rA(ctx->opcode)],     \
@@ -7936,7 +7936,7 @@ static inline void gen_##name(DisasContext *ctx)                              \
 {                                                                             \
     TCGv_i32 t0, t1;                                                          \
     if (unlikely(!ctx->spe_enabled)) {                                        \
-        gen_exception(ctx, POWERPC_EXCP_APU);                                 \
+        gen_exception(ctx, POWERPC_EXCP_SPEU);                                \
         return;                                                               \
     }                                                                         \
     t0 = tcg_temp_new_i32();                                                  \
@@ -7951,7 +7951,7 @@ static inline void gen_##name(DisasContext *ctx)                              \
 static inline void gen_##name(DisasContext *ctx)                              \
 {                                                                             \
     if (unlikely(!ctx->spe_enabled)) {                                        \
-        gen_exception(ctx, POWERPC_EXCP_APU);                                 \
+        gen_exception(ctx, POWERPC_EXCP_SPEU);                                \
         return;                                                               \
     }                                                                         \
     gen_helper_##name(cpu_crf[crfD(ctx->opcode)],                             \
@@ -7992,7 +7992,7 @@ static inline void gen_##name(DisasContext *ctx)                              \
 static inline void gen_##name(DisasContext *ctx)                              \
 {                                                                             \
     if (unlikely(!ctx->spe_enabled)) {                                        \
-        gen_exception(ctx, POWERPC_EXCP_APU);                                 \
+        gen_exception(ctx, POWERPC_EXCP_SPEU);                                \
         return;                                                               \
     }                                                                         \
     gen_helper_##name(cpu_gpr[rD(ctx->opcode)],                               \
@@ -8003,7 +8003,7 @@ static inline void gen_##name(DisasContext *ctx)                              \
 {                                                                             \
     TCGv_i64 t0, t1;                                                          \
     if (unlikely(!ctx->spe_enabled)) {                                        \
-        gen_exception(ctx, POWERPC_EXCP_APU);                                 \
+        gen_exception(ctx, POWERPC_EXCP_SPEU);                                \
         return;                                                               \
     }                                                                         \
     t0 = tcg_temp_new_i64();                                                  \
@@ -8019,7 +8019,7 @@ static inline void gen_##name(DisasContext *ctx)                              \
 static inline void gen_##name(DisasContext *ctx)                              \
 {                                                                             \
     if (unlikely(!ctx->spe_enabled)) {                                        \
-        gen_exception(ctx, POWERPC_EXCP_APU);                                 \
+        gen_exception(ctx, POWERPC_EXCP_SPEU);                                \
         return;                                                               \
     }                                                                         \
     gen_helper_##name(cpu_crf[crfD(ctx->opcode)],                             \
@@ -8030,7 +8030,7 @@ static inline void gen_##name(DisasContext *ctx)                              \
 {                                                                             \
     TCGv_i64 t0, t1;                                                          \
     if (unlikely(!ctx->spe_enabled)) {                                        \
-        gen_exception(ctx, POWERPC_EXCP_APU);                                 \
+        gen_exception(ctx, POWERPC_EXCP_SPEU);                                \
         return;                                                               \
     }                                                                         \
     t0 = tcg_temp_new_i64();                                                  \
@@ -8052,7 +8052,7 @@ GEN_SPEFPUOP_ARITH2_64_64(evfsdiv);
 static inline void gen_evfsabs(DisasContext *ctx)
 {
     if (unlikely(!ctx->spe_enabled)) {
-        gen_exception(ctx, POWERPC_EXCP_APU);
+        gen_exception(ctx, POWERPC_EXCP_SPEU);
         return;
     }
 #if defined(TARGET_PPC64)
@@ -8065,7 +8065,7 @@ static inline void gen_evfsabs(DisasContext *ctx)
 static inline void gen_evfsnabs(DisasContext *ctx)
 {
     if (unlikely(!ctx->spe_enabled)) {
-        gen_exception(ctx, POWERPC_EXCP_APU);
+        gen_exception(ctx, POWERPC_EXCP_SPEU);
         return;
     }
 #if defined(TARGET_PPC64)
@@ -8078,7 +8078,7 @@ static inline void gen_evfsnabs(DisasContext *ctx)
 static inline void gen_evfsneg(DisasContext *ctx)
 {
     if (unlikely(!ctx->spe_enabled)) {
-        gen_exception(ctx, POWERPC_EXCP_APU);
+        gen_exception(ctx, POWERPC_EXCP_SPEU);
         return;
     }
 #if defined(TARGET_PPC64)
@@ -8134,7 +8134,7 @@ GEN_SPEFPUOP_ARITH2_32_32(efsdiv);
 static inline void gen_efsabs(DisasContext *ctx)
 {
     if (unlikely(!ctx->spe_enabled)) {
-        gen_exception(ctx, POWERPC_EXCP_APU);
+        gen_exception(ctx, POWERPC_EXCP_SPEU);
         return;
     }
     tcg_gen_andi_tl(cpu_gpr[rD(ctx->opcode)], cpu_gpr[rA(ctx->opcode)], (target_long)~0x80000000LL);
@@ -8142,7 +8142,7 @@ static inline void gen_efsabs(DisasContext *ctx)
 static inline void gen_efsnabs(DisasContext *ctx)
 {
     if (unlikely(!ctx->spe_enabled)) {
-        gen_exception(ctx, POWERPC_EXCP_APU);
+        gen_exception(ctx, POWERPC_EXCP_SPEU);
         return;
     }
     tcg_gen_ori_tl(cpu_gpr[rD(ctx->opcode)], cpu_gpr[rA(ctx->opcode)], 0x80000000);
@@ -8150,7 +8150,7 @@ static inline void gen_efsnabs(DisasContext *ctx)
 static inline void gen_efsneg(DisasContext *ctx)
 {
     if (unlikely(!ctx->spe_enabled)) {
-        gen_exception(ctx, POWERPC_EXCP_APU);
+        gen_exception(ctx, POWERPC_EXCP_SPEU);
         return;
     }
     tcg_gen_xori_tl(cpu_gpr[rD(ctx->opcode)], cpu_gpr[rA(ctx->opcode)], 0x80000000);
@@ -8202,7 +8202,7 @@ GEN_SPEFPUOP_ARITH2_64_64(efddiv);
 static inline void gen_efdabs(DisasContext *ctx)
 {
     if (unlikely(!ctx->spe_enabled)) {
-        gen_exception(ctx, POWERPC_EXCP_APU);
+        gen_exception(ctx, POWERPC_EXCP_SPEU);
         return;
     }
 #if defined(TARGET_PPC64)
@@ -8215,7 +8215,7 @@ static inline void gen_efdabs(DisasContext *ctx)
 static inline void gen_efdnabs(DisasContext *ctx)
 {
     if (unlikely(!ctx->spe_enabled)) {
-        gen_exception(ctx, POWERPC_EXCP_APU);
+        gen_exception(ctx, POWERPC_EXCP_SPEU);
         return;
     }
 #if defined(TARGET_PPC64)
@@ -8228,7 +8228,7 @@ static inline void gen_efdnabs(DisasContext *ctx)
 static inline void gen_efdneg(DisasContext *ctx)
 {
     if (unlikely(!ctx->spe_enabled)) {
-        gen_exception(ctx, POWERPC_EXCP_APU);
+        gen_exception(ctx, POWERPC_EXCP_SPEU);
         return;
     }
 #if defined(TARGET_PPC64)
commit 542df9bfb707866f1ddf937898341f749975dd17
Author: Alexander Graf <agraf at suse.de>
Date:   Tue Aug 23 06:55:42 2011 +0200

    PPC: E500: Add ESR bit definitions
    
    The BookE spec specifies a number of ESR bits. Add defines for them
    so we can use them later on.
    
    Reported-by: Jason Wessel <jason.wessel at windriver.com>
    Signed-off-by: Alexander Graf <agraf at suse.de>
    Signed-off-by: Edgar E. Iglesias <edgar.iglesias at gmail.com>

diff --git a/target-ppc/cpu.h b/target-ppc/cpu.h
index 024eb6f..b8d42e0 100644
--- a/target-ppc/cpu.h
+++ b/target-ppc/cpu.h
@@ -516,7 +516,22 @@ struct ppc_slb_t {
 #endif
 
 /* Exception state register bits definition                                  */
-#define ESR_ST    23    /* Exception was caused by a store type access.      */
+#define ESR_PIL   (1 << (63 - 36)) /* Illegal Instruction                    */
+#define ESR_PPR   (1 << (63 - 37)) /* Privileged Instruction                 */
+#define ESR_PTR   (1 << (63 - 38)) /* Trap                                   */
+#define ESR_FP    (1 << (63 - 39)) /* Floating-Point Operation               */
+#define ESR_ST    (1 << (63 - 40)) /* Store Operation                        */
+#define ESR_AP    (1 << (63 - 44)) /* Auxiliary Processor Operation          */
+#define ESR_PUO   (1 << (63 - 45)) /* Unimplemented Operation                */
+#define ESR_BO    (1 << (63 - 46)) /* Byte Ordering                          */
+#define ESR_PIE   (1 << (63 - 47)) /* Imprecise exception                    */
+#define ESR_DATA  (1 << (63 - 53)) /* Data Access (Embedded page table)      */
+#define ESR_TLBI  (1 << (63 - 54)) /* TLB Ineligible (Embedded page table)   */
+#define ESR_PT    (1 << (63 - 55)) /* Page Table (Embedded page table)       */
+#define ESR_SPV   (1 << (63 - 56)) /* SPE/VMX operation                      */
+#define ESR_EPID  (1 << (63 - 57)) /* External Process ID operation          */
+#define ESR_VLEMI (1 << (63 - 58)) /* VLE operation                          */
+#define ESR_MIF   (1 << (63 - 62)) /* Misaligned instruction (VLE)           */
 
 enum {
     POWERPC_FLAG_NONE     = 0x00000000,
diff --git a/target-ppc/helper.c b/target-ppc/helper.c
index 3abab1a..c23d4a4 100644
--- a/target-ppc/helper.c
+++ b/target-ppc/helper.c
@@ -1837,7 +1837,7 @@ int cpu_ppc_handle_mmu_fault (CPUState *env, target_ulong address, int rw,
                     env->exception_index = POWERPC_EXCP_DTLB;
                     env->error_code = 0;
                     env->spr[SPR_BOOKE_DEAR] = address;
-                    env->spr[SPR_BOOKE_ESR] = rw ? 1 << ESR_ST : 0;
+                    env->spr[SPR_BOOKE_ESR] = rw ? ESR_ST : 0;
                     return -1;
                 case POWERPC_MMU_REAL:
                     cpu_abort(env, "PowerPC in real mode should never raise "
@@ -1861,7 +1861,7 @@ int cpu_ppc_handle_mmu_fault (CPUState *env, target_ulong address, int rw,
                 } else if ((env->mmu_model == POWERPC_MMU_BOOKE) ||
                            (env->mmu_model == POWERPC_MMU_BOOKE206)) {
                     env->spr[SPR_BOOKE_DEAR] = address;
-                    env->spr[SPR_BOOKE_ESR] = rw ? 1 << ESR_ST : 0;
+                    env->spr[SPR_BOOKE_ESR] = rw ? ESR_ST : 0;
                 } else {
                     env->spr[SPR_DAR] = address;
                     if (rw == 1) {
commit 710ffe604810676f9385263ba10f71f41b330cce
Author: Peter Maydell <peter.maydell at linaro.org>
Date:   Tue Aug 23 19:24:32 2011 +0100

    hw/omap_gpmc: Don't try to map CS0 twice on reset
    
    Remove a spurious second map of the OMAP GPMC CS0 region on reset.
    This fixes an assertion failure when we try to add the region to
    its container when it was already added. (The old code did not
    complain about mismatched map/unmap calls, but the new MemoryRegion
    implementation does.)
    
    Signed-off-by: Peter Maydell <peter.maydell at linaro.org>
    Signed-off-by: Edgar E. Iglesias <edgar.iglesias at gmail.com>

diff --git a/hw/omap_gpmc.c b/hw/omap_gpmc.c
index 922d622..673dddd 100644
--- a/hw/omap_gpmc.c
+++ b/hw/omap_gpmc.c
@@ -135,7 +135,6 @@ void omap_gpmc_reset(struct omap_gpmc_s *s)
                             s->cs_file[i].config[6] & 0x1f,	/* MASKADDR */
                         (s->cs_file[i].config[6] >> 8 & 0xf));	/* BASEADDR */
     }
-    omap_gpmc_cs_map(s->cs_file, 0, 0xf);
     s->ecc_cs = 0;
     s->ecc_ptr = 0;
     s->ecc_cfg = 0x3fcff000;
commit f412c762e2c2798088c0188e7fdb714def549e05
Author: Richard Henderson <rth at twiddle.net>
Date:   Tue Aug 23 10:43:32 2011 -0700

    tcg: Update --enable-debug for TCG_OPF_NOT_PRESENT.
    
    Signed-off-by: Richard Henderson <rth at twiddle.net>
    Reviewed-by: Peter Maydell <peter.maydell at linaro.org>
    Signed-off-by: Edgar E. Iglesias <edgar.iglesias at gmail.com>

diff --git a/tcg/tcg.c b/tcg/tcg.c
index 06ce214..411f971 100644
--- a/tcg/tcg.c
+++ b/tcg/tcg.c
@@ -1128,18 +1128,19 @@ void tcg_add_target_add_op_defs(const TCGTargetOpDef *tdefs)
 #if defined(CONFIG_DEBUG_TCG)
     i = 0;
     for (op = 0; op < ARRAY_SIZE(tcg_op_defs); op++) {
-        if (op < INDEX_op_call || op == INDEX_op_debug_insn_start) {
+        const TCGOpDef *def = &tcg_op_defs[op];
+        if (op < INDEX_op_call
+            || op == INDEX_op_debug_insn_start
+            || (def->flags & TCG_OPF_NOT_PRESENT)) {
             /* Wrong entry in op definitions? */
-            if (tcg_op_defs[op].used) {
-                fprintf(stderr, "Invalid op definition for %s\n",
-                        tcg_op_defs[op].name);
+            if (def->used) {
+                fprintf(stderr, "Invalid op definition for %s\n", def->name);
                 i = 1;
             }
         } else {
             /* Missing entry in op definitions? */
-            if (!tcg_op_defs[op].used) {
-                fprintf(stderr, "Missing op definition for %s\n",
-                        tcg_op_defs[op].name);
+            if (!def->used) {
+                fprintf(stderr, "Missing op definition for %s\n", def->name);
                 i = 1;
             }
         }
commit ab0997e0afdcb272fd04784a280b2df46b0c759f
Author: Frediano Ziglio <freddy77 at gmail.com>
Date:   Tue Aug 23 15:21:20 2011 +0200

    qcow2: remove memory leak
    
    Signed-off-by: Frediano Ziglio <freddy77 at gmail.com>
    Signed-off-by: Kevin Wolf <kwolf at redhat.com>

diff --git a/block/qcow2.c b/block/qcow2.c
index 37dab65..b725d68 100644
--- a/block/qcow2.c
+++ b/block/qcow2.c
@@ -496,6 +496,7 @@ fail:
     qemu_co_mutex_unlock(&s->lock);
 
     qemu_iovec_destroy(&hd_qiov);
+    g_free(cluster_data);
 
     return ret;
 }
@@ -608,6 +609,7 @@ fail:
     qemu_co_mutex_unlock(&s->lock);
 
     qemu_iovec_destroy(&hd_qiov);
+    g_free(cluster_data);
 
     return ret;
 }
commit 3fc48d0983a989d2227668bbcaae1681ea37fddd
Author: Frediano Ziglio <freddy77 at gmail.com>
Date:   Tue Aug 23 15:21:19 2011 +0200

    qcow2: Removed QCowAIOCB entirely
    
    Signed-off-by: Frediano Ziglio <freddy77 at gmail.com>
    Signed-off-by: Kevin Wolf <kwolf at redhat.com>

diff --git a/block/qcow2.c b/block/qcow2.c
index 52a7769..37dab65 100644
--- a/block/qcow2.c
+++ b/block/qcow2.c
@@ -376,83 +376,77 @@ int qcow2_backing_read1(BlockDriverState *bs, QEMUIOVector *qiov,
     return n1;
 }
 
-typedef struct QCowAIOCB {
-    BlockDriverState *bs;
-    int64_t sector_num;
-    QEMUIOVector *qiov;
-    int remaining_sectors;
-    uint64_t bytes_done;
-    uint8_t *cluster_data;
-    QEMUIOVector hd_qiov;
-} QCowAIOCB;
-
-/*
- * Returns 0 when the request is completed successfully, 1 when there is still
- * a part left to do and -errno in error cases.
- */
-static int qcow2_aio_read_cb(QCowAIOCB *acb)
+static int qcow2_co_readv(BlockDriverState *bs, int64_t sector_num,
+                          int remaining_sectors, QEMUIOVector *qiov)
 {
-    BlockDriverState *bs = acb->bs;
     BDRVQcowState *s = bs->opaque;
     int index_in_cluster, n1;
     int ret;
     int cur_nr_sectors; /* number of sectors in current iteration */
     uint64_t cluster_offset = 0;
+    uint64_t bytes_done = 0;
+    QEMUIOVector hd_qiov;
+    uint8_t *cluster_data = NULL;
 
-    while (acb->remaining_sectors != 0) {
+    qemu_iovec_init(&hd_qiov, qiov->niov);
+
+    qemu_co_mutex_lock(&s->lock);
+
+    while (remaining_sectors != 0) {
 
         /* prepare next request */
-        cur_nr_sectors = acb->remaining_sectors;
+        cur_nr_sectors = remaining_sectors;
         if (s->crypt_method) {
             cur_nr_sectors = MIN(cur_nr_sectors,
                 QCOW_MAX_CRYPT_CLUSTERS * s->cluster_sectors);
         }
 
-        ret = qcow2_get_cluster_offset(bs, acb->sector_num << 9,
+        ret = qcow2_get_cluster_offset(bs, sector_num << 9,
             &cur_nr_sectors, &cluster_offset);
         if (ret < 0) {
-            return ret;
+            goto fail;
         }
 
-        index_in_cluster = acb->sector_num & (s->cluster_sectors - 1);
+        index_in_cluster = sector_num & (s->cluster_sectors - 1);
 
-        qemu_iovec_reset(&acb->hd_qiov);
-        qemu_iovec_copy(&acb->hd_qiov, acb->qiov, acb->bytes_done,
+        qemu_iovec_reset(&hd_qiov);
+        qemu_iovec_copy(&hd_qiov, qiov, bytes_done,
             cur_nr_sectors * 512);
 
         if (!cluster_offset) {
 
             if (bs->backing_hd) {
                 /* read from the base image */
-                n1 = qcow2_backing_read1(bs->backing_hd, &acb->hd_qiov,
-                    acb->sector_num, cur_nr_sectors);
+                n1 = qcow2_backing_read1(bs->backing_hd, &hd_qiov,
+                    sector_num, cur_nr_sectors);
                 if (n1 > 0) {
                     BLKDBG_EVENT(bs->file, BLKDBG_READ_BACKING_AIO);
                     qemu_co_mutex_unlock(&s->lock);
-                    ret = bdrv_co_readv(bs->backing_hd, acb->sector_num,
-                                        n1, &acb->hd_qiov);
+                    ret = bdrv_co_readv(bs->backing_hd, sector_num,
+                                        n1, &hd_qiov);
                     qemu_co_mutex_lock(&s->lock);
                     if (ret < 0) {
-                        return ret;
+                        goto fail;
                     }
                 }
             } else {
                 /* Note: in this case, no need to wait */
-                qemu_iovec_memset(&acb->hd_qiov, 0, 512 * cur_nr_sectors);
+                qemu_iovec_memset(&hd_qiov, 0, 512 * cur_nr_sectors);
             }
         } else if (cluster_offset & QCOW_OFLAG_COMPRESSED) {
             /* add AIO support for compressed blocks ? */
             ret = qcow2_decompress_cluster(bs, cluster_offset);
             if (ret < 0) {
-                return ret;
+                goto fail;
             }
 
-            qemu_iovec_from_buffer(&acb->hd_qiov,
+            qemu_iovec_from_buffer(&hd_qiov,
                 s->cluster_cache + index_in_cluster * 512,
                 512 * cur_nr_sectors);
         } else {
             if ((cluster_offset & 511) != 0) {
-                return -EIO;
+                ret = -EIO;
+                goto fail;
             }
 
             if (s->crypt_method) {
@@ -460,15 +454,15 @@ static int qcow2_aio_read_cb(QCowAIOCB *acb)
                  * For encrypted images, read everything into a temporary
                  * contiguous buffer on which the AES functions can work.
                  */
-                if (!acb->cluster_data) {
-                    acb->cluster_data =
+                if (!cluster_data) {
+                    cluster_data =
                         g_malloc0(QCOW_MAX_CRYPT_CLUSTERS * s->cluster_size);
                 }
 
                 assert(cur_nr_sectors <=
                     QCOW_MAX_CRYPT_CLUSTERS * s->cluster_sectors);
-                qemu_iovec_reset(&acb->hd_qiov);
-                qemu_iovec_add(&acb->hd_qiov, acb->cluster_data,
+                qemu_iovec_reset(&hd_qiov);
+                qemu_iovec_add(&hd_qiov, cluster_data,
                     512 * cur_nr_sectors);
             }
 
@@ -476,63 +470,32 @@ static int qcow2_aio_read_cb(QCowAIOCB *acb)
             qemu_co_mutex_unlock(&s->lock);
             ret = bdrv_co_readv(bs->file,
                                 (cluster_offset >> 9) + index_in_cluster,
-                                cur_nr_sectors, &acb->hd_qiov);
+                                cur_nr_sectors, &hd_qiov);
             qemu_co_mutex_lock(&s->lock);
             if (ret < 0) {
-                return ret;
+                goto fail;
             }
             if (s->crypt_method) {
-                qcow2_encrypt_sectors(s, acb->sector_num,  acb->cluster_data,
-                    acb->cluster_data, cur_nr_sectors, 0, &s->aes_decrypt_key);
-                qemu_iovec_reset(&acb->hd_qiov);
-                qemu_iovec_copy(&acb->hd_qiov, acb->qiov, acb->bytes_done,
+                qcow2_encrypt_sectors(s, sector_num,  cluster_data,
+                    cluster_data, cur_nr_sectors, 0, &s->aes_decrypt_key);
+                qemu_iovec_reset(&hd_qiov);
+                qemu_iovec_copy(&hd_qiov, qiov, bytes_done,
                     cur_nr_sectors * 512);
-                qemu_iovec_from_buffer(&acb->hd_qiov, acb->cluster_data,
+                qemu_iovec_from_buffer(&hd_qiov, cluster_data,
                     512 * cur_nr_sectors);
             }
         }
 
-        acb->remaining_sectors -= cur_nr_sectors;
-        acb->sector_num += cur_nr_sectors;
-        acb->bytes_done += cur_nr_sectors * 512;
+        remaining_sectors -= cur_nr_sectors;
+        sector_num += cur_nr_sectors;
+        bytes_done += cur_nr_sectors * 512;
     }
+    ret = 0;
 
-    return 0;
-}
-
-static QCowAIOCB *qcow2_aio_setup(BlockDriverState *bs, int64_t sector_num,
-                                  QEMUIOVector *qiov, int nb_sectors,
-                                  BlockDriverCompletionFunc *cb,
-                                  void *opaque, QCowAIOCB *acb)
-{
-    memset(acb, 0, sizeof(*acb));
-    acb->bs = bs;
-    acb->sector_num = sector_num;
-    acb->qiov = qiov;
-
-    qemu_iovec_init(&acb->hd_qiov, qiov->niov);
-
-    acb->bytes_done = 0;
-    acb->remaining_sectors = nb_sectors;
-    return acb;
-}
-
-static int qcow2_co_readv(BlockDriverState *bs, int64_t sector_num,
-                          int nb_sectors, QEMUIOVector *qiov)
-{
-    BDRVQcowState *s = bs->opaque;
-    QCowAIOCB acb;
-    int ret;
-
-    qcow2_aio_setup(bs, sector_num, qiov, nb_sectors, NULL, NULL, &acb);
-
-    qemu_co_mutex_lock(&s->lock);
-    do {
-        ret = qcow2_aio_read_cb(&acb);
-    } while (ret > 0);
+fail:
     qemu_co_mutex_unlock(&s->lock);
 
-    qemu_iovec_destroy(&acb.hd_qiov);
+    qemu_iovec_destroy(&hd_qiov);
 
     return ret;
 }
@@ -552,13 +515,11 @@ static void run_dependent_requests(BDRVQcowState *s, QCowL2Meta *m)
     }
 }
 
-/*
- * Returns 0 when the request is completed successfully, 1 when there is still
- * a part left to do and -errno in error cases.
- */
-static int qcow2_aio_write_cb(QCowAIOCB *acb)
+static int qcow2_co_writev(BlockDriverState *bs,
+                           int64_t sector_num,
+                           int remaining_sectors,
+                           QEMUIOVector *qiov)
 {
-    BlockDriverState *bs = acb->bs;
     BDRVQcowState *s = bs->opaque;
     int index_in_cluster;
     int n_end;
@@ -566,47 +527,56 @@ static int qcow2_aio_write_cb(QCowAIOCB *acb)
     int cur_nr_sectors; /* number of sectors in current iteration */
     QCowL2Meta l2meta;
     uint64_t cluster_offset;
+    QEMUIOVector hd_qiov;
+    uint64_t bytes_done = 0;
+    uint8_t *cluster_data = NULL;
 
     l2meta.nb_clusters = 0;
     qemu_co_queue_init(&l2meta.dependent_requests);
 
-    while (acb->remaining_sectors != 0) {
+    qemu_iovec_init(&hd_qiov, qiov->niov);
+
+    s->cluster_cache_offset = -1; /* disable compressed cache */
+
+    qemu_co_mutex_lock(&s->lock);
 
-        index_in_cluster = acb->sector_num & (s->cluster_sectors - 1);
-        n_end = index_in_cluster + acb->remaining_sectors;
+    while (remaining_sectors != 0) {
+
+        index_in_cluster = sector_num & (s->cluster_sectors - 1);
+        n_end = index_in_cluster + remaining_sectors;
         if (s->crypt_method &&
             n_end > QCOW_MAX_CRYPT_CLUSTERS * s->cluster_sectors) {
             n_end = QCOW_MAX_CRYPT_CLUSTERS * s->cluster_sectors;
         }
 
-        ret = qcow2_alloc_cluster_offset(bs, acb->sector_num << 9,
+        ret = qcow2_alloc_cluster_offset(bs, sector_num << 9,
             index_in_cluster, n_end, &cur_nr_sectors, &l2meta);
         if (ret < 0) {
-            return ret;
+            goto fail;
         }
 
         cluster_offset = l2meta.cluster_offset;
         assert((cluster_offset & 511) == 0);
 
-        qemu_iovec_reset(&acb->hd_qiov);
-        qemu_iovec_copy(&acb->hd_qiov, acb->qiov, acb->bytes_done,
+        qemu_iovec_reset(&hd_qiov);
+        qemu_iovec_copy(&hd_qiov, qiov, bytes_done,
             cur_nr_sectors * 512);
 
         if (s->crypt_method) {
-            if (!acb->cluster_data) {
-                acb->cluster_data = g_malloc0(QCOW_MAX_CRYPT_CLUSTERS *
+            if (!cluster_data) {
+                cluster_data = g_malloc0(QCOW_MAX_CRYPT_CLUSTERS *
                                                  s->cluster_size);
             }
 
-            assert(acb->hd_qiov.size <=
+            assert(hd_qiov.size <=
                    QCOW_MAX_CRYPT_CLUSTERS * s->cluster_size);
-            qemu_iovec_to_buffer(&acb->hd_qiov, acb->cluster_data);
+            qemu_iovec_to_buffer(&hd_qiov, cluster_data);
 
-            qcow2_encrypt_sectors(s, acb->sector_num, acb->cluster_data,
-                acb->cluster_data, cur_nr_sectors, 1, &s->aes_encrypt_key);
+            qcow2_encrypt_sectors(s, sector_num, cluster_data,
+                cluster_data, cur_nr_sectors, 1, &s->aes_encrypt_key);
 
-            qemu_iovec_reset(&acb->hd_qiov);
-            qemu_iovec_add(&acb->hd_qiov, acb->cluster_data,
+            qemu_iovec_reset(&hd_qiov);
+            qemu_iovec_add(&hd_qiov, cluster_data,
                 cur_nr_sectors * 512);
         }
 
@@ -614,10 +584,10 @@ static int qcow2_aio_write_cb(QCowAIOCB *acb)
         qemu_co_mutex_unlock(&s->lock);
         ret = bdrv_co_writev(bs->file,
                              (cluster_offset >> 9) + index_in_cluster,
-                             cur_nr_sectors, &acb->hd_qiov);
+                             cur_nr_sectors, &hd_qiov);
         qemu_co_mutex_lock(&s->lock);
         if (ret < 0) {
-            return ret;
+            goto fail;
         }
 
         ret = qcow2_alloc_cluster_link_l2(bs, &l2meta);
@@ -625,36 +595,19 @@ static int qcow2_aio_write_cb(QCowAIOCB *acb)
         run_dependent_requests(s, &l2meta);
 
         if (ret < 0) {
-            return ret;
+            goto fail;
         }
 
-        acb->remaining_sectors -= cur_nr_sectors;
-        acb->sector_num += cur_nr_sectors;
-        acb->bytes_done += cur_nr_sectors * 512;
+        remaining_sectors -= cur_nr_sectors;
+        sector_num += cur_nr_sectors;
+        bytes_done += cur_nr_sectors * 512;
     }
+    ret = 0;
 
-    return 0;
-}
-
-static int qcow2_co_writev(BlockDriverState *bs,
-                           int64_t sector_num,
-                           int nb_sectors,
-                           QEMUIOVector *qiov)
-{
-    BDRVQcowState *s = bs->opaque;
-    QCowAIOCB acb;
-    int ret;
-
-    qcow2_aio_setup(bs, sector_num, qiov, nb_sectors, NULL, NULL, &acb);
-    s->cluster_cache_offset = -1; /* disable compressed cache */
-
-    qemu_co_mutex_lock(&s->lock);
-    do {
-        ret = qcow2_aio_write_cb(&acb);
-    } while (ret > 0);
+fail:
     qemu_co_mutex_unlock(&s->lock);
 
-    qemu_iovec_destroy(&acb.hd_qiov);
+    qemu_iovec_destroy(&hd_qiov);
 
     return ret;
 }
commit 5ebaa27e9ad01fa01df7bcb269f3b67e2726ecfa
Author: Frediano Ziglio <freddy77 at gmail.com>
Date:   Tue Aug 23 15:21:18 2011 +0200

    qcow2: reindent and use while before the big jump
    
    prepare to remove read/write callbacks
    
    Signed-off-by: Frediano Ziglio <freddy77 at gmail.com>
    Signed-off-by: Kevin Wolf <kwolf at redhat.com>

diff --git a/block/qcow2.c b/block/qcow2.c
index fdb4140..52a7769 100644
--- a/block/qcow2.c
+++ b/block/qcow2.c
@@ -399,107 +399,105 @@ static int qcow2_aio_read_cb(QCowAIOCB *acb)
     int cur_nr_sectors; /* number of sectors in current iteration */
     uint64_t cluster_offset = 0;
 
-    if (acb->remaining_sectors == 0) {
-        /* request completed */
-        return 0;
-    }
-
-    /* prepare next request */
-    cur_nr_sectors = acb->remaining_sectors;
-    if (s->crypt_method) {
-        cur_nr_sectors = MIN(cur_nr_sectors,
-            QCOW_MAX_CRYPT_CLUSTERS * s->cluster_sectors);
-    }
+    while (acb->remaining_sectors != 0) {
 
-    ret = qcow2_get_cluster_offset(bs, acb->sector_num << 9,
-        &cur_nr_sectors, &cluster_offset);
-    if (ret < 0) {
-        return ret;
-    }
-
-    index_in_cluster = acb->sector_num & (s->cluster_sectors - 1);
-
-    qemu_iovec_reset(&acb->hd_qiov);
-    qemu_iovec_copy(&acb->hd_qiov, acb->qiov, acb->bytes_done,
-        cur_nr_sectors * 512);
-
-    if (!cluster_offset) {
-
-        if (bs->backing_hd) {
-            /* read from the base image */
-            n1 = qcow2_backing_read1(bs->backing_hd, &acb->hd_qiov,
-                acb->sector_num, cur_nr_sectors);
-            if (n1 > 0) {
-                BLKDBG_EVENT(bs->file, BLKDBG_READ_BACKING_AIO);
-                qemu_co_mutex_unlock(&s->lock);
-                ret = bdrv_co_readv(bs->backing_hd, acb->sector_num,
-                                    n1, &acb->hd_qiov);
-                qemu_co_mutex_lock(&s->lock);
-                if (ret < 0) {
-                    return ret;
-                }
-            }
-        } else {
-            /* Note: in this case, no need to wait */
-            qemu_iovec_memset(&acb->hd_qiov, 0, 512 * cur_nr_sectors);
+        /* prepare next request */
+        cur_nr_sectors = acb->remaining_sectors;
+        if (s->crypt_method) {
+            cur_nr_sectors = MIN(cur_nr_sectors,
+                QCOW_MAX_CRYPT_CLUSTERS * s->cluster_sectors);
         }
-    } else if (cluster_offset & QCOW_OFLAG_COMPRESSED) {
-        /* add AIO support for compressed blocks ? */
-        ret = qcow2_decompress_cluster(bs, cluster_offset);
+
+        ret = qcow2_get_cluster_offset(bs, acb->sector_num << 9,
+            &cur_nr_sectors, &cluster_offset);
         if (ret < 0) {
             return ret;
         }
 
-        qemu_iovec_from_buffer(&acb->hd_qiov,
-            s->cluster_cache + index_in_cluster * 512,
-            512 * cur_nr_sectors);
-    } else {
-        if ((cluster_offset & 511) != 0) {
-            return -EIO;
-        }
+        index_in_cluster = acb->sector_num & (s->cluster_sectors - 1);
 
-        if (s->crypt_method) {
-            /*
-             * For encrypted images, read everything into a temporary
-             * contiguous buffer on which the AES functions can work.
-             */
-            if (!acb->cluster_data) {
-                acb->cluster_data =
-                    g_malloc0(QCOW_MAX_CRYPT_CLUSTERS * s->cluster_size);
+        qemu_iovec_reset(&acb->hd_qiov);
+        qemu_iovec_copy(&acb->hd_qiov, acb->qiov, acb->bytes_done,
+            cur_nr_sectors * 512);
+
+        if (!cluster_offset) {
+
+            if (bs->backing_hd) {
+                /* read from the base image */
+                n1 = qcow2_backing_read1(bs->backing_hd, &acb->hd_qiov,
+                    acb->sector_num, cur_nr_sectors);
+                if (n1 > 0) {
+                    BLKDBG_EVENT(bs->file, BLKDBG_READ_BACKING_AIO);
+                    qemu_co_mutex_unlock(&s->lock);
+                    ret = bdrv_co_readv(bs->backing_hd, acb->sector_num,
+                                        n1, &acb->hd_qiov);
+                    qemu_co_mutex_lock(&s->lock);
+                    if (ret < 0) {
+                        return ret;
+                    }
+                }
+            } else {
+                /* Note: in this case, no need to wait */
+                qemu_iovec_memset(&acb->hd_qiov, 0, 512 * cur_nr_sectors);
+            }
+        } else if (cluster_offset & QCOW_OFLAG_COMPRESSED) {
+            /* add AIO support for compressed blocks ? */
+            ret = qcow2_decompress_cluster(bs, cluster_offset);
+            if (ret < 0) {
+                return ret;
             }
 
-            assert(cur_nr_sectors <=
-                QCOW_MAX_CRYPT_CLUSTERS * s->cluster_sectors);
-            qemu_iovec_reset(&acb->hd_qiov);
-            qemu_iovec_add(&acb->hd_qiov, acb->cluster_data,
+            qemu_iovec_from_buffer(&acb->hd_qiov,
+                s->cluster_cache + index_in_cluster * 512,
                 512 * cur_nr_sectors);
-        }
+        } else {
+            if ((cluster_offset & 511) != 0) {
+                return -EIO;
+            }
 
-        BLKDBG_EVENT(bs->file, BLKDBG_READ_AIO);
-        qemu_co_mutex_unlock(&s->lock);
-        ret = bdrv_co_readv(bs->file,
-                            (cluster_offset >> 9) + index_in_cluster,
-                            cur_nr_sectors, &acb->hd_qiov);
-        qemu_co_mutex_lock(&s->lock);
-        if (ret < 0) {
-            return ret;
-        }
-        if (s->crypt_method) {
-            qcow2_encrypt_sectors(s, acb->sector_num,  acb->cluster_data,
-                acb->cluster_data, cur_nr_sectors, 0, &s->aes_decrypt_key);
-            qemu_iovec_reset(&acb->hd_qiov);
-            qemu_iovec_copy(&acb->hd_qiov, acb->qiov, acb->bytes_done,
-                cur_nr_sectors * 512);
-            qemu_iovec_from_buffer(&acb->hd_qiov, acb->cluster_data,
-                512 * cur_nr_sectors);
+            if (s->crypt_method) {
+                /*
+                 * For encrypted images, read everything into a temporary
+                 * contiguous buffer on which the AES functions can work.
+                 */
+                if (!acb->cluster_data) {
+                    acb->cluster_data =
+                        g_malloc0(QCOW_MAX_CRYPT_CLUSTERS * s->cluster_size);
+                }
+
+                assert(cur_nr_sectors <=
+                    QCOW_MAX_CRYPT_CLUSTERS * s->cluster_sectors);
+                qemu_iovec_reset(&acb->hd_qiov);
+                qemu_iovec_add(&acb->hd_qiov, acb->cluster_data,
+                    512 * cur_nr_sectors);
+            }
+
+            BLKDBG_EVENT(bs->file, BLKDBG_READ_AIO);
+            qemu_co_mutex_unlock(&s->lock);
+            ret = bdrv_co_readv(bs->file,
+                                (cluster_offset >> 9) + index_in_cluster,
+                                cur_nr_sectors, &acb->hd_qiov);
+            qemu_co_mutex_lock(&s->lock);
+            if (ret < 0) {
+                return ret;
+            }
+            if (s->crypt_method) {
+                qcow2_encrypt_sectors(s, acb->sector_num,  acb->cluster_data,
+                    acb->cluster_data, cur_nr_sectors, 0, &s->aes_decrypt_key);
+                qemu_iovec_reset(&acb->hd_qiov);
+                qemu_iovec_copy(&acb->hd_qiov, acb->qiov, acb->bytes_done,
+                    cur_nr_sectors * 512);
+                qemu_iovec_from_buffer(&acb->hd_qiov, acb->cluster_data,
+                    512 * cur_nr_sectors);
+            }
         }
-    }
 
-    acb->remaining_sectors -= cur_nr_sectors;
-    acb->sector_num += cur_nr_sectors;
-    acb->bytes_done += cur_nr_sectors * 512;
+        acb->remaining_sectors -= cur_nr_sectors;
+        acb->sector_num += cur_nr_sectors;
+        acb->bytes_done += cur_nr_sectors * 512;
+    }
 
-    return 1;
+    return 0;
 }
 
 static QCowAIOCB *qcow2_aio_setup(BlockDriverState *bs, int64_t sector_num,
@@ -572,70 +570,70 @@ static int qcow2_aio_write_cb(QCowAIOCB *acb)
     l2meta.nb_clusters = 0;
     qemu_co_queue_init(&l2meta.dependent_requests);
 
-    if (acb->remaining_sectors == 0) {
-        /* request completed */
-        return 0;
-    }
+    while (acb->remaining_sectors != 0) {
 
-    index_in_cluster = acb->sector_num & (s->cluster_sectors - 1);
-    n_end = index_in_cluster + acb->remaining_sectors;
-    if (s->crypt_method &&
-        n_end > QCOW_MAX_CRYPT_CLUSTERS * s->cluster_sectors)
-        n_end = QCOW_MAX_CRYPT_CLUSTERS * s->cluster_sectors;
+        index_in_cluster = acb->sector_num & (s->cluster_sectors - 1);
+        n_end = index_in_cluster + acb->remaining_sectors;
+        if (s->crypt_method &&
+            n_end > QCOW_MAX_CRYPT_CLUSTERS * s->cluster_sectors) {
+            n_end = QCOW_MAX_CRYPT_CLUSTERS * s->cluster_sectors;
+        }
 
-    ret = qcow2_alloc_cluster_offset(bs, acb->sector_num << 9,
-        index_in_cluster, n_end, &cur_nr_sectors, &l2meta);
-    if (ret < 0) {
-        return ret;
-    }
+        ret = qcow2_alloc_cluster_offset(bs, acb->sector_num << 9,
+            index_in_cluster, n_end, &cur_nr_sectors, &l2meta);
+        if (ret < 0) {
+            return ret;
+        }
 
-    cluster_offset = l2meta.cluster_offset;
-    assert((cluster_offset & 511) == 0);
+        cluster_offset = l2meta.cluster_offset;
+        assert((cluster_offset & 511) == 0);
 
-    qemu_iovec_reset(&acb->hd_qiov);
-    qemu_iovec_copy(&acb->hd_qiov, acb->qiov, acb->bytes_done,
-        cur_nr_sectors * 512);
+        qemu_iovec_reset(&acb->hd_qiov);
+        qemu_iovec_copy(&acb->hd_qiov, acb->qiov, acb->bytes_done,
+            cur_nr_sectors * 512);
 
-    if (s->crypt_method) {
-        if (!acb->cluster_data) {
-            acb->cluster_data = g_malloc0(QCOW_MAX_CRYPT_CLUSTERS *
-                                             s->cluster_size);
-        }
+        if (s->crypt_method) {
+            if (!acb->cluster_data) {
+                acb->cluster_data = g_malloc0(QCOW_MAX_CRYPT_CLUSTERS *
+                                                 s->cluster_size);
+            }
 
-        assert(acb->hd_qiov.size <= QCOW_MAX_CRYPT_CLUSTERS * s->cluster_size);
-        qemu_iovec_to_buffer(&acb->hd_qiov, acb->cluster_data);
+            assert(acb->hd_qiov.size <=
+                   QCOW_MAX_CRYPT_CLUSTERS * s->cluster_size);
+            qemu_iovec_to_buffer(&acb->hd_qiov, acb->cluster_data);
 
-        qcow2_encrypt_sectors(s, acb->sector_num, acb->cluster_data,
-            acb->cluster_data, cur_nr_sectors, 1, &s->aes_encrypt_key);
+            qcow2_encrypt_sectors(s, acb->sector_num, acb->cluster_data,
+                acb->cluster_data, cur_nr_sectors, 1, &s->aes_encrypt_key);
 
-        qemu_iovec_reset(&acb->hd_qiov);
-        qemu_iovec_add(&acb->hd_qiov, acb->cluster_data,
-            cur_nr_sectors * 512);
-    }
+            qemu_iovec_reset(&acb->hd_qiov);
+            qemu_iovec_add(&acb->hd_qiov, acb->cluster_data,
+                cur_nr_sectors * 512);
+        }
 
-    BLKDBG_EVENT(bs->file, BLKDBG_WRITE_AIO);
-    qemu_co_mutex_unlock(&s->lock);
-    ret = bdrv_co_writev(bs->file,
-                         (cluster_offset >> 9) + index_in_cluster,
-                         cur_nr_sectors, &acb->hd_qiov);
-    qemu_co_mutex_lock(&s->lock);
-    if (ret < 0) {
-        return ret;
-    }
+        BLKDBG_EVENT(bs->file, BLKDBG_WRITE_AIO);
+        qemu_co_mutex_unlock(&s->lock);
+        ret = bdrv_co_writev(bs->file,
+                             (cluster_offset >> 9) + index_in_cluster,
+                             cur_nr_sectors, &acb->hd_qiov);
+        qemu_co_mutex_lock(&s->lock);
+        if (ret < 0) {
+            return ret;
+        }
 
-    ret = qcow2_alloc_cluster_link_l2(bs, &l2meta);
+        ret = qcow2_alloc_cluster_link_l2(bs, &l2meta);
 
-    run_dependent_requests(s, &l2meta);
+        run_dependent_requests(s, &l2meta);
 
-    if (ret < 0) {
-        return ret;
-    }
+        if (ret < 0) {
+            return ret;
+        }
 
-    acb->remaining_sectors -= cur_nr_sectors;
-    acb->sector_num += cur_nr_sectors;
-    acb->bytes_done += cur_nr_sectors * 512;
+        acb->remaining_sectors -= cur_nr_sectors;
+        acb->sector_num += cur_nr_sectors;
+        acb->bytes_done += cur_nr_sectors * 512;
+    }
 
-    return 1;
+    return 0;
 }
 
 static int qcow2_co_writev(BlockDriverState *bs,
commit e78c69b89c3c40f938e41b2917e86eeaebc4adc2
Author: Frediano Ziglio <freddy77 at gmail.com>
Date:   Tue Aug 23 15:21:17 2011 +0200

    qcow2: remove common from QCowAIOCB
    
    Signed-off-by: Frediano Ziglio <freddy77 at gmail.com>
    Signed-off-by: Kevin Wolf <kwolf at redhat.com>

diff --git a/block/qcow2.c b/block/qcow2.c
index 22da050..fdb4140 100644
--- a/block/qcow2.c
+++ b/block/qcow2.c
@@ -377,7 +377,7 @@ int qcow2_backing_read1(BlockDriverState *bs, QEMUIOVector *qiov,
 }
 
 typedef struct QCowAIOCB {
-    BlockDriverAIOCB common;
+    BlockDriverState *bs;
     int64_t sector_num;
     QEMUIOVector *qiov;
     int remaining_sectors;
@@ -392,7 +392,7 @@ typedef struct QCowAIOCB {
  */
 static int qcow2_aio_read_cb(QCowAIOCB *acb)
 {
-    BlockDriverState *bs = acb->common.bs;
+    BlockDriverState *bs = acb->bs;
     BDRVQcowState *s = bs->opaque;
     int index_in_cluster, n1;
     int ret;
@@ -508,7 +508,7 @@ static QCowAIOCB *qcow2_aio_setup(BlockDriverState *bs, int64_t sector_num,
                                   void *opaque, QCowAIOCB *acb)
 {
     memset(acb, 0, sizeof(*acb));
-    acb->common.bs = bs;
+    acb->bs = bs;
     acb->sector_num = sector_num;
     acb->qiov = qiov;
 
@@ -560,7 +560,7 @@ static void run_dependent_requests(BDRVQcowState *s, QCowL2Meta *m)
  */
 static int qcow2_aio_write_cb(QCowAIOCB *acb)
 {
-    BlockDriverState *bs = acb->common.bs;
+    BlockDriverState *bs = acb->bs;
     BDRVQcowState *s = bs->opaque;
     int index_in_cluster;
     int n_end;
commit c2bdd9904b4c77389a7bffa5e6517cf1c1e2b420
Author: Frediano Ziglio <freddy77 at gmail.com>
Date:   Tue Aug 23 15:21:16 2011 +0200

    qcow2: remove cluster_offset from QCowAIOCB
    
    Signed-off-by: Frediano Ziglio <freddy77 at gmail.com>
    Signed-off-by: Kevin Wolf <kwolf at redhat.com>

diff --git a/block/qcow2.c b/block/qcow2.c
index 3068a58..22da050 100644
--- a/block/qcow2.c
+++ b/block/qcow2.c
@@ -382,7 +382,6 @@ typedef struct QCowAIOCB {
     QEMUIOVector *qiov;
     int remaining_sectors;
     uint64_t bytes_done;
-    uint64_t cluster_offset;
     uint8_t *cluster_data;
     QEMUIOVector hd_qiov;
 } QCowAIOCB;
@@ -398,6 +397,7 @@ static int qcow2_aio_read_cb(QCowAIOCB *acb)
     int index_in_cluster, n1;
     int ret;
     int cur_nr_sectors; /* number of sectors in current iteration */
+    uint64_t cluster_offset = 0;
 
     if (acb->remaining_sectors == 0) {
         /* request completed */
@@ -412,7 +412,7 @@ static int qcow2_aio_read_cb(QCowAIOCB *acb)
     }
 
     ret = qcow2_get_cluster_offset(bs, acb->sector_num << 9,
-        &cur_nr_sectors, &acb->cluster_offset);
+        &cur_nr_sectors, &cluster_offset);
     if (ret < 0) {
         return ret;
     }
@@ -423,7 +423,7 @@ static int qcow2_aio_read_cb(QCowAIOCB *acb)
     qemu_iovec_copy(&acb->hd_qiov, acb->qiov, acb->bytes_done,
         cur_nr_sectors * 512);
 
-    if (!acb->cluster_offset) {
+    if (!cluster_offset) {
 
         if (bs->backing_hd) {
             /* read from the base image */
@@ -443,9 +443,9 @@ static int qcow2_aio_read_cb(QCowAIOCB *acb)
             /* Note: in this case, no need to wait */
             qemu_iovec_memset(&acb->hd_qiov, 0, 512 * cur_nr_sectors);
         }
-    } else if (acb->cluster_offset & QCOW_OFLAG_COMPRESSED) {
+    } else if (cluster_offset & QCOW_OFLAG_COMPRESSED) {
         /* add AIO support for compressed blocks ? */
-        ret = qcow2_decompress_cluster(bs, acb->cluster_offset);
+        ret = qcow2_decompress_cluster(bs, cluster_offset);
         if (ret < 0) {
             return ret;
         }
@@ -454,7 +454,7 @@ static int qcow2_aio_read_cb(QCowAIOCB *acb)
             s->cluster_cache + index_in_cluster * 512,
             512 * cur_nr_sectors);
     } else {
-        if ((acb->cluster_offset & 511) != 0) {
+        if ((cluster_offset & 511) != 0) {
             return -EIO;
         }
 
@@ -478,7 +478,7 @@ static int qcow2_aio_read_cb(QCowAIOCB *acb)
         BLKDBG_EVENT(bs->file, BLKDBG_READ_AIO);
         qemu_co_mutex_unlock(&s->lock);
         ret = bdrv_co_readv(bs->file,
-                            (acb->cluster_offset >> 9) + index_in_cluster,
+                            (cluster_offset >> 9) + index_in_cluster,
                             cur_nr_sectors, &acb->hd_qiov);
         qemu_co_mutex_lock(&s->lock);
         if (ret < 0) {
@@ -516,7 +516,6 @@ static QCowAIOCB *qcow2_aio_setup(BlockDriverState *bs, int64_t sector_num,
 
     acb->bytes_done = 0;
     acb->remaining_sectors = nb_sectors;
-    acb->cluster_offset = 0;
     return acb;
 }
 
@@ -568,6 +567,7 @@ static int qcow2_aio_write_cb(QCowAIOCB *acb)
     int ret;
     int cur_nr_sectors; /* number of sectors in current iteration */
     QCowL2Meta l2meta;
+    uint64_t cluster_offset;
 
     l2meta.nb_clusters = 0;
     qemu_co_queue_init(&l2meta.dependent_requests);
@@ -589,8 +589,8 @@ static int qcow2_aio_write_cb(QCowAIOCB *acb)
         return ret;
     }
 
-    acb->cluster_offset = l2meta.cluster_offset;
-    assert((acb->cluster_offset & 511) == 0);
+    cluster_offset = l2meta.cluster_offset;
+    assert((cluster_offset & 511) == 0);
 
     qemu_iovec_reset(&acb->hd_qiov);
     qemu_iovec_copy(&acb->hd_qiov, acb->qiov, acb->bytes_done,
@@ -616,7 +616,7 @@ static int qcow2_aio_write_cb(QCowAIOCB *acb)
     BLKDBG_EVENT(bs->file, BLKDBG_WRITE_AIO);
     qemu_co_mutex_unlock(&s->lock);
     ret = bdrv_co_writev(bs->file,
-                         (acb->cluster_offset >> 9) + index_in_cluster,
+                         (cluster_offset >> 9) + index_in_cluster,
                          cur_nr_sectors, &acb->hd_qiov);
     qemu_co_mutex_lock(&s->lock);
     if (ret < 0) {
commit c227140397c7167479862632498b78a3d680ec57
Author: Frediano Ziglio <freddy77 at gmail.com>
Date:   Tue Aug 23 15:21:15 2011 +0200

    qcow2: remove l2meta from QCowAIOCB
    
    Signed-off-by: Frediano Ziglio <freddy77 at gmail.com>
    Signed-off-by: Kevin Wolf <kwolf at redhat.com>

diff --git a/block/qcow2.c b/block/qcow2.c
index cc5f409..3068a58 100644
--- a/block/qcow2.c
+++ b/block/qcow2.c
@@ -385,7 +385,6 @@ typedef struct QCowAIOCB {
     uint64_t cluster_offset;
     uint8_t *cluster_data;
     QEMUIOVector hd_qiov;
-    QCowL2Meta l2meta;
 } QCowAIOCB;
 
 /*
@@ -518,8 +517,6 @@ static QCowAIOCB *qcow2_aio_setup(BlockDriverState *bs, int64_t sector_num,
     acb->bytes_done = 0;
     acb->remaining_sectors = nb_sectors;
     acb->cluster_offset = 0;
-    acb->l2meta.nb_clusters = 0;
-    qemu_co_queue_init(&acb->l2meta.dependent_requests);
     return acb;
 }
 
@@ -570,6 +567,10 @@ static int qcow2_aio_write_cb(QCowAIOCB *acb)
     int n_end;
     int ret;
     int cur_nr_sectors; /* number of sectors in current iteration */
+    QCowL2Meta l2meta;
+
+    l2meta.nb_clusters = 0;
+    qemu_co_queue_init(&l2meta.dependent_requests);
 
     if (acb->remaining_sectors == 0) {
         /* request completed */
@@ -583,12 +584,12 @@ static int qcow2_aio_write_cb(QCowAIOCB *acb)
         n_end = QCOW_MAX_CRYPT_CLUSTERS * s->cluster_sectors;
 
     ret = qcow2_alloc_cluster_offset(bs, acb->sector_num << 9,
-        index_in_cluster, n_end, &cur_nr_sectors, &acb->l2meta);
+        index_in_cluster, n_end, &cur_nr_sectors, &l2meta);
     if (ret < 0) {
         return ret;
     }
 
-    acb->cluster_offset = acb->l2meta.cluster_offset;
+    acb->cluster_offset = l2meta.cluster_offset;
     assert((acb->cluster_offset & 511) == 0);
 
     qemu_iovec_reset(&acb->hd_qiov);
@@ -622,9 +623,9 @@ static int qcow2_aio_write_cb(QCowAIOCB *acb)
         return ret;
     }
 
-    ret = qcow2_alloc_cluster_link_l2(bs, &acb->l2meta);
+    ret = qcow2_alloc_cluster_link_l2(bs, &l2meta);
 
-    run_dependent_requests(s, &acb->l2meta);
+    run_dependent_requests(s, &l2meta);
 
     if (ret < 0) {
         return ret;
commit faf575c136cfeed785016179aa7560ad41202e51
Author: Frediano Ziglio <freddy77 at gmail.com>
Date:   Tue Aug 23 15:21:14 2011 +0200

    qcow2: removed cur_nr_sectors field in QCowAIOCB
    
    Signed-off-by: Frediano Ziglio <freddy77 at gmail.com>
    Signed-off-by: Kevin Wolf <kwolf at redhat.com>

diff --git a/block/qcow2.c b/block/qcow2.c
index 9f7566f..cc5f409 100644
--- a/block/qcow2.c
+++ b/block/qcow2.c
@@ -381,7 +381,6 @@ typedef struct QCowAIOCB {
     int64_t sector_num;
     QEMUIOVector *qiov;
     int remaining_sectors;
-    int cur_nr_sectors;	/* number of sectors in current iteration */
     uint64_t bytes_done;
     uint64_t cluster_offset;
     uint8_t *cluster_data;
@@ -399,42 +398,22 @@ static int qcow2_aio_read_cb(QCowAIOCB *acb)
     BDRVQcowState *s = bs->opaque;
     int index_in_cluster, n1;
     int ret;
-
-    /* post process the read buffer */
-    if (!acb->cluster_offset) {
-        /* nothing to do */
-    } else if (acb->cluster_offset & QCOW_OFLAG_COMPRESSED) {
-        /* nothing to do */
-    } else {
-        if (s->crypt_method) {
-            qcow2_encrypt_sectors(s, acb->sector_num,  acb->cluster_data,
-                acb->cluster_data, acb->cur_nr_sectors, 0, &s->aes_decrypt_key);
-            qemu_iovec_reset(&acb->hd_qiov);
-            qemu_iovec_copy(&acb->hd_qiov, acb->qiov, acb->bytes_done,
-                acb->cur_nr_sectors * 512);
-            qemu_iovec_from_buffer(&acb->hd_qiov, acb->cluster_data,
-                512 * acb->cur_nr_sectors);
-        }
-    }
-
-    acb->remaining_sectors -= acb->cur_nr_sectors;
-    acb->sector_num += acb->cur_nr_sectors;
-    acb->bytes_done += acb->cur_nr_sectors * 512;
+    int cur_nr_sectors; /* number of sectors in current iteration */
 
     if (acb->remaining_sectors == 0) {
         /* request completed */
         return 0;
     }
 
-    /* prepare next AIO request */
-    acb->cur_nr_sectors = acb->remaining_sectors;
+    /* prepare next request */
+    cur_nr_sectors = acb->remaining_sectors;
     if (s->crypt_method) {
-        acb->cur_nr_sectors = MIN(acb->cur_nr_sectors,
+        cur_nr_sectors = MIN(cur_nr_sectors,
             QCOW_MAX_CRYPT_CLUSTERS * s->cluster_sectors);
     }
 
     ret = qcow2_get_cluster_offset(bs, acb->sector_num << 9,
-        &acb->cur_nr_sectors, &acb->cluster_offset);
+        &cur_nr_sectors, &acb->cluster_offset);
     if (ret < 0) {
         return ret;
     }
@@ -443,14 +422,14 @@ static int qcow2_aio_read_cb(QCowAIOCB *acb)
 
     qemu_iovec_reset(&acb->hd_qiov);
     qemu_iovec_copy(&acb->hd_qiov, acb->qiov, acb->bytes_done,
-        acb->cur_nr_sectors * 512);
+        cur_nr_sectors * 512);
 
     if (!acb->cluster_offset) {
 
         if (bs->backing_hd) {
             /* read from the base image */
             n1 = qcow2_backing_read1(bs->backing_hd, &acb->hd_qiov,
-                acb->sector_num, acb->cur_nr_sectors);
+                acb->sector_num, cur_nr_sectors);
             if (n1 > 0) {
                 BLKDBG_EVENT(bs->file, BLKDBG_READ_BACKING_AIO);
                 qemu_co_mutex_unlock(&s->lock);
@@ -461,11 +440,9 @@ static int qcow2_aio_read_cb(QCowAIOCB *acb)
                     return ret;
                 }
             }
-            return 1;
         } else {
             /* Note: in this case, no need to wait */
-            qemu_iovec_memset(&acb->hd_qiov, 0, 512 * acb->cur_nr_sectors);
-            return 1;
+            qemu_iovec_memset(&acb->hd_qiov, 0, 512 * cur_nr_sectors);
         }
     } else if (acb->cluster_offset & QCOW_OFLAG_COMPRESSED) {
         /* add AIO support for compressed blocks ? */
@@ -476,9 +453,7 @@ static int qcow2_aio_read_cb(QCowAIOCB *acb)
 
         qemu_iovec_from_buffer(&acb->hd_qiov,
             s->cluster_cache + index_in_cluster * 512,
-            512 * acb->cur_nr_sectors);
-
-        return 1;
+            512 * cur_nr_sectors);
     } else {
         if ((acb->cluster_offset & 511) != 0) {
             return -EIO;
@@ -494,24 +469,37 @@ static int qcow2_aio_read_cb(QCowAIOCB *acb)
                     g_malloc0(QCOW_MAX_CRYPT_CLUSTERS * s->cluster_size);
             }
 
-            assert(acb->cur_nr_sectors <=
+            assert(cur_nr_sectors <=
                 QCOW_MAX_CRYPT_CLUSTERS * s->cluster_sectors);
             qemu_iovec_reset(&acb->hd_qiov);
             qemu_iovec_add(&acb->hd_qiov, acb->cluster_data,
-                512 * acb->cur_nr_sectors);
+                512 * cur_nr_sectors);
         }
 
         BLKDBG_EVENT(bs->file, BLKDBG_READ_AIO);
         qemu_co_mutex_unlock(&s->lock);
         ret = bdrv_co_readv(bs->file,
                             (acb->cluster_offset >> 9) + index_in_cluster,
-                            acb->cur_nr_sectors, &acb->hd_qiov);
+                            cur_nr_sectors, &acb->hd_qiov);
         qemu_co_mutex_lock(&s->lock);
         if (ret < 0) {
             return ret;
         }
+        if (s->crypt_method) {
+            qcow2_encrypt_sectors(s, acb->sector_num,  acb->cluster_data,
+                acb->cluster_data, cur_nr_sectors, 0, &s->aes_decrypt_key);
+            qemu_iovec_reset(&acb->hd_qiov);
+            qemu_iovec_copy(&acb->hd_qiov, acb->qiov, acb->bytes_done,
+                cur_nr_sectors * 512);
+            qemu_iovec_from_buffer(&acb->hd_qiov, acb->cluster_data,
+                512 * cur_nr_sectors);
+        }
     }
 
+    acb->remaining_sectors -= cur_nr_sectors;
+    acb->sector_num += cur_nr_sectors;
+    acb->bytes_done += cur_nr_sectors * 512;
+
     return 1;
 }
 
@@ -529,7 +517,6 @@ static QCowAIOCB *qcow2_aio_setup(BlockDriverState *bs, int64_t sector_num,
 
     acb->bytes_done = 0;
     acb->remaining_sectors = nb_sectors;
-    acb->cur_nr_sectors = 0;
     acb->cluster_offset = 0;
     acb->l2meta.nb_clusters = 0;
     qemu_co_queue_init(&acb->l2meta.dependent_requests);
@@ -582,18 +569,7 @@ static int qcow2_aio_write_cb(QCowAIOCB *acb)
     int index_in_cluster;
     int n_end;
     int ret;
-
-    ret = qcow2_alloc_cluster_link_l2(bs, &acb->l2meta);
-
-    run_dependent_requests(s, &acb->l2meta);
-
-    if (ret < 0) {
-        return ret;
-    }
-
-    acb->remaining_sectors -= acb->cur_nr_sectors;
-    acb->sector_num += acb->cur_nr_sectors;
-    acb->bytes_done += acb->cur_nr_sectors * 512;
+    int cur_nr_sectors; /* number of sectors in current iteration */
 
     if (acb->remaining_sectors == 0) {
         /* request completed */
@@ -607,7 +583,7 @@ static int qcow2_aio_write_cb(QCowAIOCB *acb)
         n_end = QCOW_MAX_CRYPT_CLUSTERS * s->cluster_sectors;
 
     ret = qcow2_alloc_cluster_offset(bs, acb->sector_num << 9,
-        index_in_cluster, n_end, &acb->cur_nr_sectors, &acb->l2meta);
+        index_in_cluster, n_end, &cur_nr_sectors, &acb->l2meta);
     if (ret < 0) {
         return ret;
     }
@@ -617,7 +593,7 @@ static int qcow2_aio_write_cb(QCowAIOCB *acb)
 
     qemu_iovec_reset(&acb->hd_qiov);
     qemu_iovec_copy(&acb->hd_qiov, acb->qiov, acb->bytes_done,
-        acb->cur_nr_sectors * 512);
+        cur_nr_sectors * 512);
 
     if (s->crypt_method) {
         if (!acb->cluster_data) {
@@ -629,23 +605,35 @@ static int qcow2_aio_write_cb(QCowAIOCB *acb)
         qemu_iovec_to_buffer(&acb->hd_qiov, acb->cluster_data);
 
         qcow2_encrypt_sectors(s, acb->sector_num, acb->cluster_data,
-            acb->cluster_data, acb->cur_nr_sectors, 1, &s->aes_encrypt_key);
+            acb->cluster_data, cur_nr_sectors, 1, &s->aes_encrypt_key);
 
         qemu_iovec_reset(&acb->hd_qiov);
         qemu_iovec_add(&acb->hd_qiov, acb->cluster_data,
-            acb->cur_nr_sectors * 512);
+            cur_nr_sectors * 512);
     }
 
     BLKDBG_EVENT(bs->file, BLKDBG_WRITE_AIO);
     qemu_co_mutex_unlock(&s->lock);
     ret = bdrv_co_writev(bs->file,
                          (acb->cluster_offset >> 9) + index_in_cluster,
-                         acb->cur_nr_sectors, &acb->hd_qiov);
+                         cur_nr_sectors, &acb->hd_qiov);
     qemu_co_mutex_lock(&s->lock);
     if (ret < 0) {
         return ret;
     }
 
+    ret = qcow2_alloc_cluster_link_l2(bs, &acb->l2meta);
+
+    run_dependent_requests(s, &acb->l2meta);
+
+    if (ret < 0) {
+        return ret;
+    }
+
+    acb->remaining_sectors -= cur_nr_sectors;
+    acb->sector_num += cur_nr_sectors;
+    acb->bytes_done += cur_nr_sectors * 512;
+
     return 1;
 }
 
commit 4617310c33990609f05a6ce7eebc2f4d51b7ddfc
Author: Frediano Ziglio <freddy77 at gmail.com>
Date:   Tue Aug 23 15:21:13 2011 +0200

    qcow2: Removed unused AIOCB fields
    
    Signed-off-by: Frediano Ziglio <freddy77 at gmail.com>
    Signed-off-by: Kevin Wolf <kwolf at redhat.com>

diff --git a/block/qcow2.c b/block/qcow2.c
index f4e3c06..9f7566f 100644
--- a/block/qcow2.c
+++ b/block/qcow2.c
@@ -385,11 +385,8 @@ typedef struct QCowAIOCB {
     uint64_t bytes_done;
     uint64_t cluster_offset;
     uint8_t *cluster_data;
-    bool is_write;
     QEMUIOVector hd_qiov;
-    QEMUBH *bh;
     QCowL2Meta l2meta;
-    QLIST_ENTRY(QCowAIOCB) next_depend;
 } QCowAIOCB;
 
 /*
@@ -521,13 +518,12 @@ static int qcow2_aio_read_cb(QCowAIOCB *acb)
 static QCowAIOCB *qcow2_aio_setup(BlockDriverState *bs, int64_t sector_num,
                                   QEMUIOVector *qiov, int nb_sectors,
                                   BlockDriverCompletionFunc *cb,
-                                  void *opaque, int is_write, QCowAIOCB *acb)
+                                  void *opaque, QCowAIOCB *acb)
 {
     memset(acb, 0, sizeof(*acb));
     acb->common.bs = bs;
     acb->sector_num = sector_num;
     acb->qiov = qiov;
-    acb->is_write = is_write;
 
     qemu_iovec_init(&acb->hd_qiov, qiov->niov);
 
@@ -547,7 +543,7 @@ static int qcow2_co_readv(BlockDriverState *bs, int64_t sector_num,
     QCowAIOCB acb;
     int ret;
 
-    qcow2_aio_setup(bs, sector_num, qiov, nb_sectors, NULL, NULL, 0, &acb);
+    qcow2_aio_setup(bs, sector_num, qiov, nb_sectors, NULL, NULL, &acb);
 
     qemu_co_mutex_lock(&s->lock);
     do {
@@ -662,7 +658,7 @@ static int qcow2_co_writev(BlockDriverState *bs,
     QCowAIOCB acb;
     int ret;
 
-    qcow2_aio_setup(bs, sector_num, qiov, nb_sectors, NULL, NULL, 1, &acb);
+    qcow2_aio_setup(bs, sector_num, qiov, nb_sectors, NULL, NULL, &acb);
     s->cluster_cache_offset = -1; /* disable compressed cache */
 
     qemu_co_mutex_lock(&s->lock);
commit 122bbd1dd955b29099297da3633ea7a49ae00a44
Author: Frediano Ziglio <freddy77 at gmail.com>
Date:   Tue Aug 23 15:21:12 2011 +0200

    qcow: remove old #undefined code
    
    Signed-off-by: Frediano Ziglio <freddy77 at gmail.com>
    Signed-off-by: Kevin Wolf <kwolf at redhat.com>

diff --git a/block/qcow.c b/block/qcow.c
index 4495afe..c8bfecc 100644
--- a/block/qcow.c
+++ b/block/qcow.c
@@ -192,24 +192,6 @@ static int qcow_set_key(BlockDriverState *bs, const char *key)
         return -1;
     if (AES_set_decrypt_key(keybuf, 128, &s->aes_decrypt_key) != 0)
         return -1;
-#if 0
-    /* test */
-    {
-        uint8_t in[16];
-        uint8_t out[16];
-        uint8_t tmp[16];
-        for(i=0;i<16;i++)
-            in[i] = i;
-        AES_encrypt(in, tmp, &s->aes_encrypt_key);
-        AES_decrypt(tmp, out, &s->aes_decrypt_key);
-        for(i = 0; i < 16; i++)
-            printf(" %02x", tmp[i]);
-        printf("\n");
-        for(i = 0; i < 16; i++)
-            printf(" %02x", out[i]);
-        printf("\n");
-    }
-#endif
     return 0;
 }
 
@@ -443,51 +425,6 @@ static int decompress_cluster(BlockDriverState *bs, uint64_t cluster_offset)
     return 0;
 }
 
-#if 0
-
-static int qcow_read(BlockDriverState *bs, int64_t sector_num,
-                     uint8_t *buf, int nb_sectors)
-{
-    BDRVQcowState *s = bs->opaque;
-    int ret, index_in_cluster, n;
-    uint64_t cluster_offset;
-
-    while (nb_sectors > 0) {
-        cluster_offset = get_cluster_offset(bs, sector_num << 9, 0, 0, 0, 0);
-        index_in_cluster = sector_num & (s->cluster_sectors - 1);
-        n = s->cluster_sectors - index_in_cluster;
-        if (n > nb_sectors)
-            n = nb_sectors;
-        if (!cluster_offset) {
-            if (bs->backing_hd) {
-                /* read from the base image */
-                ret = bdrv_read(bs->backing_hd, sector_num, buf, n);
-                if (ret < 0)
-                    return -1;
-            } else {
-                memset(buf, 0, 512 * n);
-            }
-        } else if (cluster_offset & QCOW_OFLAG_COMPRESSED) {
-            if (decompress_cluster(bs, cluster_offset) < 0)
-                return -1;
-            memcpy(buf, s->cluster_cache + index_in_cluster * 512, 512 * n);
-        } else {
-            ret = bdrv_pread(bs->file, cluster_offset + index_in_cluster * 512, buf, n * 512);
-            if (ret != n * 512)
-                return -1;
-            if (s->crypt_method) {
-                encrypt_sectors(s, sector_num, buf, buf, n, 0,
-                                &s->aes_decrypt_key);
-            }
-        }
-        nb_sectors -= n;
-        sector_num += n;
-        buf += n * 512;
-    }
-    return 0;
-}
-#endif
-
 static int qcow_co_readv(BlockDriverState *bs, int64_t sector_num,
                          int nb_sectors, QEMUIOVector *qiov)
 {
commit 27deebe83657599ae834bb455709b2a6e7c57f82
Author: Frediano Ziglio <freddy77 at gmail.com>
Date:   Tue Aug 23 15:21:11 2011 +0200

    qcow: Remove QCowAIOCB
    
    Embed qcow_aio_read_cb into qcow_co_readv and qcow_aio_write_cb into qcow_co_writev
    
    Signed-off-by: Frediano Ziglio <freddy77 at gmail.com>
    Signed-off-by: Kevin Wolf <kwolf at redhat.com>

diff --git a/block/qcow.c b/block/qcow.c
index 8c559e2..4495afe 100644
--- a/block/qcow.c
+++ b/block/qcow.c
@@ -488,223 +488,178 @@ static int qcow_read(BlockDriverState *bs, int64_t sector_num,
 }
 #endif
 
-typedef struct QCowAIOCB {
-    BlockDriverState *bs;
-    int64_t sector_num;
-    QEMUIOVector *qiov;
-    uint8_t *buf;
-    void *orig_buf;
-    int nb_sectors;
-} QCowAIOCB;
-
-static QCowAIOCB *qcow_aio_setup(BlockDriverState *bs,
-        int64_t sector_num, QEMUIOVector *qiov, int nb_sectors,
-        int is_write, QCowAIOCB *acb)
-{
-    acb->bs = bs;
-    acb->sector_num = sector_num;
-    acb->qiov = qiov;
-
-    if (qiov->niov > 1) {
-        acb->buf = acb->orig_buf = qemu_blockalign(bs, qiov->size);
-        if (is_write)
-            qemu_iovec_to_buffer(qiov, acb->buf);
-    } else {
-        acb->orig_buf = NULL;
-        acb->buf = (uint8_t *)qiov->iov->iov_base;
-    }
-    acb->nb_sectors = nb_sectors;
-    return acb;
-}
-
-static int qcow_aio_read_cb(QCowAIOCB *acb)
+static int qcow_co_readv(BlockDriverState *bs, int64_t sector_num,
+                         int nb_sectors, QEMUIOVector *qiov)
 {
-    BlockDriverState *bs = acb->bs;
     BDRVQcowState *s = bs->opaque;
     int index_in_cluster;
-    int ret, n;
+    int ret = 0, n;
     uint64_t cluster_offset;
     struct iovec hd_iov;
     QEMUIOVector hd_qiov;
+    uint8_t *buf;
+    void *orig_buf;
 
- redo:
-    if (acb->nb_sectors == 0) {
-        /* request completed */
-        return 0;
+    if (qiov->niov > 1) {
+        buf = orig_buf = qemu_blockalign(bs, qiov->size);
+    } else {
+        orig_buf = NULL;
+        buf = (uint8_t *)qiov->iov->iov_base;
     }
 
-    /* prepare next request */
-    cluster_offset = get_cluster_offset(bs, acb->sector_num << 9,
-                                             0, 0, 0, 0);
-    index_in_cluster = acb->sector_num & (s->cluster_sectors - 1);
-    n = s->cluster_sectors - index_in_cluster;
-    if (n > acb->nb_sectors) {
-        n = acb->nb_sectors;
-    }
+    qemu_co_mutex_lock(&s->lock);
+
+    while (nb_sectors != 0) {
+        /* prepare next request */
+        cluster_offset = get_cluster_offset(bs, sector_num << 9,
+                                                 0, 0, 0, 0);
+        index_in_cluster = sector_num & (s->cluster_sectors - 1);
+        n = s->cluster_sectors - index_in_cluster;
+        if (n > nb_sectors) {
+            n = nb_sectors;
+        }
 
-    if (!cluster_offset) {
-        if (bs->backing_hd) {
-            /* read from the base image */
-            hd_iov.iov_base = (void *)acb->buf;
+        if (!cluster_offset) {
+            if (bs->backing_hd) {
+                /* read from the base image */
+                hd_iov.iov_base = (void *)buf;
+                hd_iov.iov_len = n * 512;
+                qemu_iovec_init_external(&hd_qiov, &hd_iov, 1);
+                qemu_co_mutex_unlock(&s->lock);
+                ret = bdrv_co_readv(bs->backing_hd, sector_num,
+                                    n, &hd_qiov);
+                qemu_co_mutex_lock(&s->lock);
+                if (ret < 0) {
+                    goto fail;
+                }
+            } else {
+                /* Note: in this case, no need to wait */
+                memset(buf, 0, 512 * n);
+            }
+        } else if (cluster_offset & QCOW_OFLAG_COMPRESSED) {
+            /* add AIO support for compressed blocks ? */
+            if (decompress_cluster(bs, cluster_offset) < 0) {
+                goto fail;
+            }
+            memcpy(buf,
+                   s->cluster_cache + index_in_cluster * 512, 512 * n);
+        } else {
+            if ((cluster_offset & 511) != 0) {
+                goto fail;
+            }
+            hd_iov.iov_base = (void *)buf;
             hd_iov.iov_len = n * 512;
             qemu_iovec_init_external(&hd_qiov, &hd_iov, 1);
             qemu_co_mutex_unlock(&s->lock);
-            ret = bdrv_co_readv(bs->backing_hd, acb->sector_num,
+            ret = bdrv_co_readv(bs->file,
+                                (cluster_offset >> 9) + index_in_cluster,
                                 n, &hd_qiov);
             qemu_co_mutex_lock(&s->lock);
             if (ret < 0) {
-                return -EIO;
+                break;
+            }
+            if (s->crypt_method) {
+                encrypt_sectors(s, sector_num, buf, buf,
+                                n, 0,
+                                &s->aes_decrypt_key);
             }
-        } else {
-            /* Note: in this case, no need to wait */
-            memset(acb->buf, 0, 512 * n);
-        }
-    } else if (cluster_offset & QCOW_OFLAG_COMPRESSED) {
-        /* add AIO support for compressed blocks ? */
-        if (decompress_cluster(bs, cluster_offset) < 0) {
-            return -EIO;
-        }
-        memcpy(acb->buf,
-               s->cluster_cache + index_in_cluster * 512, 512 * n);
-    } else {
-        if ((cluster_offset & 511) != 0) {
-            return -EIO;
-        }
-        hd_iov.iov_base = (void *)acb->buf;
-        hd_iov.iov_len = n * 512;
-        qemu_iovec_init_external(&hd_qiov, &hd_iov, 1);
-        qemu_co_mutex_unlock(&s->lock);
-        ret = bdrv_co_readv(bs->file,
-                            (cluster_offset >> 9) + index_in_cluster,
-                            n, &hd_qiov);
-        qemu_co_mutex_lock(&s->lock);
-        if (ret < 0) {
-            return ret;
         }
-    }
+        ret = 0;
 
-    /* post process the read buffer */
-    if (!cluster_offset) {
-        /* nothing to do */
-    } else if (cluster_offset & QCOW_OFLAG_COMPRESSED) {
-        /* nothing to do */
-    } else {
-        if (s->crypt_method) {
-            encrypt_sectors(s, acb->sector_num, acb->buf, acb->buf,
-                            n, 0,
-                            &s->aes_decrypt_key);
-        }
+        nb_sectors -= n;
+        sector_num += n;
+        buf += n * 512;
     }
 
-    acb->nb_sectors -= n;
-    acb->sector_num += n;
-    acb->buf += n * 512;
-
-    goto redo;
-}
-
-static int qcow_co_readv(BlockDriverState *bs, int64_t sector_num,
-                         int nb_sectors, QEMUIOVector *qiov)
-{
-    BDRVQcowState *s = bs->opaque;
-    QCowAIOCB acb;
-    int ret;
-
-    qcow_aio_setup(bs, sector_num, qiov, nb_sectors, 0, &acb);
-
-    qemu_co_mutex_lock(&s->lock);
-    ret = qcow_aio_read_cb(&acb);
+done:
     qemu_co_mutex_unlock(&s->lock);
 
-    if (acb.qiov->niov > 1) {
-        qemu_iovec_from_buffer(acb.qiov, acb.orig_buf, acb.qiov->size);
-        qemu_vfree(acb.orig_buf);
+    if (qiov->niov > 1) {
+        qemu_iovec_from_buffer(qiov, orig_buf, qiov->size);
+        qemu_vfree(orig_buf);
     }
 
     return ret;
+
+fail:
+    ret = -EIO;
+    goto done;
 }
 
-static int qcow_aio_write_cb(QCowAIOCB *acb)
+static int qcow_co_writev(BlockDriverState *bs, int64_t sector_num,
+                          int nb_sectors, QEMUIOVector *qiov)
 {
-    BlockDriverState *bs = acb->bs;
     BDRVQcowState *s = bs->opaque;
     int index_in_cluster;
     uint64_t cluster_offset;
     const uint8_t *src_buf;
-    int ret, n;
+    int ret = 0, n;
     uint8_t *cluster_data = NULL;
     struct iovec hd_iov;
     QEMUIOVector hd_qiov;
+    uint8_t *buf;
+    void *orig_buf;
 
-redo:
-    if (acb->nb_sectors == 0) {
-        /* request completed */
-        return 0;
-    }
+    s->cluster_cache_offset = -1; /* disable compressed cache */
 
-    index_in_cluster = acb->sector_num & (s->cluster_sectors - 1);
-    n = s->cluster_sectors - index_in_cluster;
-    if (n > acb->nb_sectors) {
-        n = acb->nb_sectors;
-    }
-    cluster_offset = get_cluster_offset(bs, acb->sector_num << 9, 1, 0,
-                                        index_in_cluster,
-                                        index_in_cluster + n);
-    if (!cluster_offset || (cluster_offset & 511) != 0) {
-        return -EIO;
-    }
-    if (s->crypt_method) {
-        if (!cluster_data) {
-            cluster_data = g_malloc0(s->cluster_size);
-        }
-        encrypt_sectors(s, acb->sector_num, cluster_data, acb->buf,
-                        n, 1, &s->aes_encrypt_key);
-        src_buf = cluster_data;
+    if (qiov->niov > 1) {
+        buf = orig_buf = qemu_blockalign(bs, qiov->size);
+        qemu_iovec_to_buffer(qiov, buf);
     } else {
-        src_buf = acb->buf;
+        orig_buf = NULL;
+        buf = (uint8_t *)qiov->iov->iov_base;
     }
 
-    hd_iov.iov_base = (void *)src_buf;
-    hd_iov.iov_len = n * 512;
-    qemu_iovec_init_external(&hd_qiov, &hd_iov, 1);
-    qemu_co_mutex_unlock(&s->lock);
-    ret = bdrv_co_writev(bs->file,
-                         (cluster_offset >> 9) + index_in_cluster,
-                         n, &hd_qiov);
-    if (cluster_data) {
-        free(cluster_data);
-        cluster_data = NULL;
-    }
     qemu_co_mutex_lock(&s->lock);
-    if (ret < 0) {
-        return ret;
-    }
-
-    acb->nb_sectors -= n;
-    acb->sector_num += n;
-    acb->buf += n * 512;
 
-    goto redo;
-}
+    while (nb_sectors != 0) {
 
-static int qcow_co_writev(BlockDriverState *bs, int64_t sector_num,
-                          int nb_sectors, QEMUIOVector *qiov)
-{
-    BDRVQcowState *s = bs->opaque;
-    QCowAIOCB acb;
-    int ret;
-
-    s->cluster_cache_offset = -1; /* disable compressed cache */
+        index_in_cluster = sector_num & (s->cluster_sectors - 1);
+        n = s->cluster_sectors - index_in_cluster;
+        if (n > nb_sectors) {
+            n = nb_sectors;
+        }
+        cluster_offset = get_cluster_offset(bs, sector_num << 9, 1, 0,
+                                            index_in_cluster,
+                                            index_in_cluster + n);
+        if (!cluster_offset || (cluster_offset & 511) != 0) {
+            ret = -EIO;
+            break;
+        }
+        if (s->crypt_method) {
+            if (!cluster_data) {
+                cluster_data = g_malloc0(s->cluster_size);
+            }
+            encrypt_sectors(s, sector_num, cluster_data, buf,
+                            n, 1, &s->aes_encrypt_key);
+            src_buf = cluster_data;
+        } else {
+            src_buf = buf;
+        }
 
-    qcow_aio_setup(bs, sector_num, qiov, nb_sectors, 1, &acb);
+        hd_iov.iov_base = (void *)src_buf;
+        hd_iov.iov_len = n * 512;
+        qemu_iovec_init_external(&hd_qiov, &hd_iov, 1);
+        qemu_co_mutex_unlock(&s->lock);
+        ret = bdrv_co_writev(bs->file,
+                             (cluster_offset >> 9) + index_in_cluster,
+                             n, &hd_qiov);
+        qemu_co_mutex_lock(&s->lock);
+        if (ret < 0) {
+            break;
+        }
+        ret = 0;
 
-    qemu_co_mutex_lock(&s->lock);
-    ret = qcow_aio_write_cb(&acb);
+        nb_sectors -= n;
+        sector_num += n;
+        buf += n * 512;
+    }
     qemu_co_mutex_unlock(&s->lock);
 
-    if (acb.qiov->niov > 1) {
-        qemu_vfree(acb.orig_buf);
+    if (qiov->niov > 1) {
+        qemu_vfree(orig_buf);
     }
+    free(cluster_data);
 
     return ret;
 }
commit 43ca85b559795fd0f246ffb1db8e09c0da920dd0
Author: Frediano Ziglio <freddy77 at gmail.com>
Date:   Tue Aug 23 15:21:10 2011 +0200

    qcow: move some blocks of code to avoid useless variable initialization
    
    Signed-off-by: Frediano Ziglio <freddy77 at gmail.com>
    Signed-off-by: Kevin Wolf <kwolf at redhat.com>

diff --git a/block/qcow.c b/block/qcow.c
index 7727604..8c559e2 100644
--- a/block/qcow.c
+++ b/block/qcow.c
@@ -522,35 +522,18 @@ static int qcow_aio_read_cb(QCowAIOCB *acb)
     BlockDriverState *bs = acb->bs;
     BDRVQcowState *s = bs->opaque;
     int index_in_cluster;
-    int ret, n = 0;
-    uint64_t cluster_offset = 0;
+    int ret, n;
+    uint64_t cluster_offset;
     struct iovec hd_iov;
     QEMUIOVector hd_qiov;
 
  redo:
-    /* post process the read buffer */
-    if (!cluster_offset) {
-        /* nothing to do */
-    } else if (cluster_offset & QCOW_OFLAG_COMPRESSED) {
-        /* nothing to do */
-    } else {
-        if (s->crypt_method) {
-            encrypt_sectors(s, acb->sector_num, acb->buf, acb->buf,
-                            n, 0,
-                            &s->aes_decrypt_key);
-        }
-    }
-
-    acb->nb_sectors -= n;
-    acb->sector_num += n;
-    acb->buf += n * 512;
-
     if (acb->nb_sectors == 0) {
         /* request completed */
         return 0;
     }
 
-    /* prepare next AIO request */
+    /* prepare next request */
     cluster_offset = get_cluster_offset(bs, acb->sector_num << 9,
                                              0, 0, 0, 0);
     index_in_cluster = acb->sector_num & (s->cluster_sectors - 1);
@@ -575,7 +558,6 @@ static int qcow_aio_read_cb(QCowAIOCB *acb)
         } else {
             /* Note: in this case, no need to wait */
             memset(acb->buf, 0, 512 * n);
-            goto redo;
         }
     } else if (cluster_offset & QCOW_OFLAG_COMPRESSED) {
         /* add AIO support for compressed blocks ? */
@@ -584,7 +566,6 @@ static int qcow_aio_read_cb(QCowAIOCB *acb)
         }
         memcpy(acb->buf,
                s->cluster_cache + index_in_cluster * 512, 512 * n);
-        goto redo;
     } else {
         if ((cluster_offset & 511) != 0) {
             return -EIO;
@@ -602,6 +583,23 @@ static int qcow_aio_read_cb(QCowAIOCB *acb)
         }
     }
 
+    /* post process the read buffer */
+    if (!cluster_offset) {
+        /* nothing to do */
+    } else if (cluster_offset & QCOW_OFLAG_COMPRESSED) {
+        /* nothing to do */
+    } else {
+        if (s->crypt_method) {
+            encrypt_sectors(s, acb->sector_num, acb->buf, acb->buf,
+                            n, 0,
+                            &s->aes_decrypt_key);
+        }
+    }
+
+    acb->nb_sectors -= n;
+    acb->sector_num += n;
+    acb->buf += n * 512;
+
     goto redo;
 }
 
@@ -633,16 +631,12 @@ static int qcow_aio_write_cb(QCowAIOCB *acb)
     int index_in_cluster;
     uint64_t cluster_offset;
     const uint8_t *src_buf;
-    int ret, n = 0;
+    int ret, n;
     uint8_t *cluster_data = NULL;
     struct iovec hd_iov;
     QEMUIOVector hd_qiov;
 
 redo:
-    acb->nb_sectors -= n;
-    acb->sector_num += n;
-    acb->buf += n * 512;
-
     if (acb->nb_sectors == 0) {
         /* request completed */
         return 0;
@@ -685,6 +679,11 @@ redo:
     if (ret < 0) {
         return ret;
     }
+
+    acb->nb_sectors -= n;
+    acb->sector_num += n;
+    acb->buf += n * 512;
+
     goto redo;
 }
 
commit 430bbaaa95a07169a1de8e99e543db5413a56ef6
Author: Frediano Ziglio <freddy77 at gmail.com>
Date:   Tue Aug 23 15:21:09 2011 +0200

    qcow: QCowAIOCB field cleanup
    
    remove unused field from this structure and put some of them in qcow_aio_read_cb and qcow_aio_write_cb
    
    Signed-off-by: Frediano Ziglio <freddy77 at gmail.com>
    Signed-off-by: Kevin Wolf <kwolf at redhat.com>

diff --git a/block/qcow.c b/block/qcow.c
index 1e06dc9..7727604 100644
--- a/block/qcow.c
+++ b/block/qcow.c
@@ -489,72 +489,61 @@ static int qcow_read(BlockDriverState *bs, int64_t sector_num,
 #endif
 
 typedef struct QCowAIOCB {
-    BlockDriverAIOCB common;
+    BlockDriverState *bs;
     int64_t sector_num;
     QEMUIOVector *qiov;
     uint8_t *buf;
     void *orig_buf;
     int nb_sectors;
-    int n;
-    uint64_t cluster_offset;
-    uint8_t *cluster_data;
-    struct iovec hd_iov;
-    bool is_write;
-    QEMUBH *bh;
-    QEMUIOVector hd_qiov;
-    BlockDriverAIOCB *hd_aiocb;
 } QCowAIOCB;
 
 static QCowAIOCB *qcow_aio_setup(BlockDriverState *bs,
         int64_t sector_num, QEMUIOVector *qiov, int nb_sectors,
         int is_write, QCowAIOCB *acb)
 {
-    memset(acb, 0, sizeof(*acb));
-    acb->common.bs = bs;
-    acb->hd_aiocb = NULL;
+    acb->bs = bs;
     acb->sector_num = sector_num;
     acb->qiov = qiov;
-    acb->is_write = is_write;
 
     if (qiov->niov > 1) {
         acb->buf = acb->orig_buf = qemu_blockalign(bs, qiov->size);
         if (is_write)
             qemu_iovec_to_buffer(qiov, acb->buf);
     } else {
+        acb->orig_buf = NULL;
         acb->buf = (uint8_t *)qiov->iov->iov_base;
     }
     acb->nb_sectors = nb_sectors;
-    acb->n = 0;
-    acb->cluster_offset = 0;
     return acb;
 }
 
 static int qcow_aio_read_cb(QCowAIOCB *acb)
 {
-    BlockDriverState *bs = acb->common.bs;
+    BlockDriverState *bs = acb->bs;
     BDRVQcowState *s = bs->opaque;
     int index_in_cluster;
-    int ret;
-
-    acb->hd_aiocb = NULL;
+    int ret, n = 0;
+    uint64_t cluster_offset = 0;
+    struct iovec hd_iov;
+    QEMUIOVector hd_qiov;
 
  redo:
     /* post process the read buffer */
-    if (!acb->cluster_offset) {
+    if (!cluster_offset) {
         /* nothing to do */
-    } else if (acb->cluster_offset & QCOW_OFLAG_COMPRESSED) {
+    } else if (cluster_offset & QCOW_OFLAG_COMPRESSED) {
         /* nothing to do */
     } else {
         if (s->crypt_method) {
             encrypt_sectors(s, acb->sector_num, acb->buf, acb->buf,
-                            acb->n, 0,
+                            n, 0,
                             &s->aes_decrypt_key);
         }
     }
 
-    acb->nb_sectors -= acb->n;
-    acb->sector_num += acb->n;
-    acb->buf += acb->n * 512;
+    acb->nb_sectors -= n;
+    acb->sector_num += n;
+    acb->buf += n * 512;
 
     if (acb->nb_sectors == 0) {
         /* request completed */
@@ -562,57 +551,58 @@ static int qcow_aio_read_cb(QCowAIOCB *acb)
     }
 
     /* prepare next AIO request */
-    acb->cluster_offset = get_cluster_offset(bs, acb->sector_num << 9,
+    cluster_offset = get_cluster_offset(bs, acb->sector_num << 9,
                                              0, 0, 0, 0);
     index_in_cluster = acb->sector_num & (s->cluster_sectors - 1);
-    acb->n = s->cluster_sectors - index_in_cluster;
-    if (acb->n > acb->nb_sectors)
-        acb->n = acb->nb_sectors;
+    n = s->cluster_sectors - index_in_cluster;
+    if (n > acb->nb_sectors) {
+        n = acb->nb_sectors;
+    }
 
-    if (!acb->cluster_offset) {
+    if (!cluster_offset) {
         if (bs->backing_hd) {
             /* read from the base image */
-            acb->hd_iov.iov_base = (void *)acb->buf;
-            acb->hd_iov.iov_len = acb->n * 512;
-            qemu_iovec_init_external(&acb->hd_qiov, &acb->hd_iov, 1);
+            hd_iov.iov_base = (void *)acb->buf;
+            hd_iov.iov_len = n * 512;
+            qemu_iovec_init_external(&hd_qiov, &hd_iov, 1);
             qemu_co_mutex_unlock(&s->lock);
             ret = bdrv_co_readv(bs->backing_hd, acb->sector_num,
-                                acb->n, &acb->hd_qiov);
+                                n, &hd_qiov);
             qemu_co_mutex_lock(&s->lock);
             if (ret < 0) {
                 return -EIO;
             }
         } else {
             /* Note: in this case, no need to wait */
-            memset(acb->buf, 0, 512 * acb->n);
+            memset(acb->buf, 0, 512 * n);
             goto redo;
         }
-    } else if (acb->cluster_offset & QCOW_OFLAG_COMPRESSED) {
+    } else if (cluster_offset & QCOW_OFLAG_COMPRESSED) {
         /* add AIO support for compressed blocks ? */
-        if (decompress_cluster(bs, acb->cluster_offset) < 0) {
+        if (decompress_cluster(bs, cluster_offset) < 0) {
             return -EIO;
         }
         memcpy(acb->buf,
-               s->cluster_cache + index_in_cluster * 512, 512 * acb->n);
+               s->cluster_cache + index_in_cluster * 512, 512 * n);
         goto redo;
     } else {
-        if ((acb->cluster_offset & 511) != 0) {
+        if ((cluster_offset & 511) != 0) {
             return -EIO;
         }
-        acb->hd_iov.iov_base = (void *)acb->buf;
-        acb->hd_iov.iov_len = acb->n * 512;
-        qemu_iovec_init_external(&acb->hd_qiov, &acb->hd_iov, 1);
+        hd_iov.iov_base = (void *)acb->buf;
+        hd_iov.iov_len = n * 512;
+        qemu_iovec_init_external(&hd_qiov, &hd_iov, 1);
         qemu_co_mutex_unlock(&s->lock);
         ret = bdrv_co_readv(bs->file,
-                            (acb->cluster_offset >> 9) + index_in_cluster,
-                            acb->n, &acb->hd_qiov);
+                            (cluster_offset >> 9) + index_in_cluster,
+                            n, &hd_qiov);
         qemu_co_mutex_lock(&s->lock);
         if (ret < 0) {
             return ret;
         }
     }
 
-    return 1;
+    goto redo;
 }
 
 static int qcow_co_readv(BlockDriverState *bs, int64_t sector_num,
@@ -625,9 +615,7 @@ static int qcow_co_readv(BlockDriverState *bs, int64_t sector_num,
     qcow_aio_setup(bs, sector_num, qiov, nb_sectors, 0, &acb);
 
     qemu_co_mutex_lock(&s->lock);
-    do {
-        ret = qcow_aio_read_cb(&acb);
-    } while (ret > 0);
+    ret = qcow_aio_read_cb(&acb);
     qemu_co_mutex_unlock(&s->lock);
 
     if (acb.qiov->niov > 1) {
@@ -640,18 +628,20 @@ static int qcow_co_readv(BlockDriverState *bs, int64_t sector_num,
 
 static int qcow_aio_write_cb(QCowAIOCB *acb)
 {
-    BlockDriverState *bs = acb->common.bs;
+    BlockDriverState *bs = acb->bs;
     BDRVQcowState *s = bs->opaque;
     int index_in_cluster;
     uint64_t cluster_offset;
     const uint8_t *src_buf;
-    int ret;
-
-    acb->hd_aiocb = NULL;
+    int ret, n = 0;
+    uint8_t *cluster_data = NULL;
+    struct iovec hd_iov;
+    QEMUIOVector hd_qiov;
 
-    acb->nb_sectors -= acb->n;
-    acb->sector_num += acb->n;
-    acb->buf += acb->n * 512;
+redo:
+    acb->nb_sectors -= n;
+    acb->sector_num += n;
+    acb->buf += n * 512;
 
     if (acb->nb_sectors == 0) {
         /* request completed */
@@ -659,38 +649,43 @@ static int qcow_aio_write_cb(QCowAIOCB *acb)
     }
 
     index_in_cluster = acb->sector_num & (s->cluster_sectors - 1);
-    acb->n = s->cluster_sectors - index_in_cluster;
-    if (acb->n > acb->nb_sectors)
-        acb->n = acb->nb_sectors;
+    n = s->cluster_sectors - index_in_cluster;
+    if (n > acb->nb_sectors) {
+        n = acb->nb_sectors;
+    }
     cluster_offset = get_cluster_offset(bs, acb->sector_num << 9, 1, 0,
                                         index_in_cluster,
-                                        index_in_cluster + acb->n);
+                                        index_in_cluster + n);
     if (!cluster_offset || (cluster_offset & 511) != 0) {
         return -EIO;
     }
     if (s->crypt_method) {
-        if (!acb->cluster_data) {
-            acb->cluster_data = g_malloc0(s->cluster_size);
+        if (!cluster_data) {
+            cluster_data = g_malloc0(s->cluster_size);
         }
-        encrypt_sectors(s, acb->sector_num, acb->cluster_data, acb->buf,
-                        acb->n, 1, &s->aes_encrypt_key);
-        src_buf = acb->cluster_data;
+        encrypt_sectors(s, acb->sector_num, cluster_data, acb->buf,
+                        n, 1, &s->aes_encrypt_key);
+        src_buf = cluster_data;
     } else {
         src_buf = acb->buf;
     }
 
-    acb->hd_iov.iov_base = (void *)src_buf;
-    acb->hd_iov.iov_len = acb->n * 512;
-    qemu_iovec_init_external(&acb->hd_qiov, &acb->hd_iov, 1);
+    hd_iov.iov_base = (void *)src_buf;
+    hd_iov.iov_len = n * 512;
+    qemu_iovec_init_external(&hd_qiov, &hd_iov, 1);
     qemu_co_mutex_unlock(&s->lock);
     ret = bdrv_co_writev(bs->file,
                          (cluster_offset >> 9) + index_in_cluster,
-                         acb->n, &acb->hd_qiov);
+                         n, &hd_qiov);
+    if (cluster_data) {
+        free(cluster_data);
+        cluster_data = NULL;
+    }
     qemu_co_mutex_lock(&s->lock);
     if (ret < 0) {
         return ret;
     }
-    return 1;
+    goto redo;
 }
 
 static int qcow_co_writev(BlockDriverState *bs, int64_t sector_num,
@@ -705,9 +700,7 @@ static int qcow_co_writev(BlockDriverState *bs, int64_t sector_num,
     qcow_aio_setup(bs, sector_num, qiov, nb_sectors, 1, &acb);
 
     qemu_co_mutex_lock(&s->lock);
-    do {
-        ret = qcow_aio_write_cb(&acb);
-    } while (ret > 0);
+    ret = qcow_aio_write_cb(&acb);
     qemu_co_mutex_unlock(&s->lock);
 
     if (acb.qiov->niov > 1) {
commit f5cd8173e77c334c278b4684e3806ad01bba1047
Author: Frediano Ziglio <freddy77 at gmail.com>
Date:   Tue Aug 23 15:21:08 2011 +0200

    qcow/qcow2: Allocate QCowAIOCB structure using stack
    
    instead of calling qemi_aio_get use stack
    
    Signed-off-by: Frediano Ziglio <freddy77 at gmail.com>
    Signed-off-by: Kevin Wolf <kwolf at redhat.com>

diff --git a/block/qcow.c b/block/qcow.c
index 8f2bdfd..1e06dc9 100644
--- a/block/qcow.c
+++ b/block/qcow.c
@@ -505,28 +505,12 @@ typedef struct QCowAIOCB {
     BlockDriverAIOCB *hd_aiocb;
 } QCowAIOCB;
 
-static void qcow_aio_cancel(BlockDriverAIOCB *blockacb)
-{
-    QCowAIOCB *acb = container_of(blockacb, QCowAIOCB, common);
-    if (acb->hd_aiocb)
-        bdrv_aio_cancel(acb->hd_aiocb);
-    qemu_aio_release(acb);
-}
-
-static AIOPool qcow_aio_pool = {
-    .aiocb_size         = sizeof(QCowAIOCB),
-    .cancel             = qcow_aio_cancel,
-};
-
 static QCowAIOCB *qcow_aio_setup(BlockDriverState *bs,
         int64_t sector_num, QEMUIOVector *qiov, int nb_sectors,
-        int is_write)
+        int is_write, QCowAIOCB *acb)
 {
-    QCowAIOCB *acb;
-
-    acb = qemu_aio_get(&qcow_aio_pool, bs, NULL, NULL);
-    if (!acb)
-        return NULL;
+    memset(acb, 0, sizeof(*acb));
+    acb->common.bs = bs;
     acb->hd_aiocb = NULL;
     acb->sector_num = sector_num;
     acb->qiov = qiov;
@@ -545,9 +529,8 @@ static QCowAIOCB *qcow_aio_setup(BlockDriverState *bs,
     return acb;
 }
 
-static int qcow_aio_read_cb(void *opaque)
+static int qcow_aio_read_cb(QCowAIOCB *acb)
 {
-    QCowAIOCB *acb = opaque;
     BlockDriverState *bs = acb->common.bs;
     BDRVQcowState *s = bs->opaque;
     int index_in_cluster;
@@ -636,29 +619,27 @@ static int qcow_co_readv(BlockDriverState *bs, int64_t sector_num,
                          int nb_sectors, QEMUIOVector *qiov)
 {
     BDRVQcowState *s = bs->opaque;
-    QCowAIOCB *acb;
+    QCowAIOCB acb;
     int ret;
 
-    acb = qcow_aio_setup(bs, sector_num, qiov, nb_sectors, 0);
+    qcow_aio_setup(bs, sector_num, qiov, nb_sectors, 0, &acb);
 
     qemu_co_mutex_lock(&s->lock);
     do {
-        ret = qcow_aio_read_cb(acb);
+        ret = qcow_aio_read_cb(&acb);
     } while (ret > 0);
     qemu_co_mutex_unlock(&s->lock);
 
-    if (acb->qiov->niov > 1) {
-        qemu_iovec_from_buffer(acb->qiov, acb->orig_buf, acb->qiov->size);
-        qemu_vfree(acb->orig_buf);
+    if (acb.qiov->niov > 1) {
+        qemu_iovec_from_buffer(acb.qiov, acb.orig_buf, acb.qiov->size);
+        qemu_vfree(acb.orig_buf);
     }
-    qemu_aio_release(acb);
 
     return ret;
 }
 
-static int qcow_aio_write_cb(void *opaque)
+static int qcow_aio_write_cb(QCowAIOCB *acb)
 {
-    QCowAIOCB *acb = opaque;
     BlockDriverState *bs = acb->common.bs;
     BDRVQcowState *s = bs->opaque;
     int index_in_cluster;
@@ -716,23 +697,22 @@ static int qcow_co_writev(BlockDriverState *bs, int64_t sector_num,
                           int nb_sectors, QEMUIOVector *qiov)
 {
     BDRVQcowState *s = bs->opaque;
-    QCowAIOCB *acb;
+    QCowAIOCB acb;
     int ret;
 
     s->cluster_cache_offset = -1; /* disable compressed cache */
 
-    acb = qcow_aio_setup(bs, sector_num, qiov, nb_sectors, 1);
+    qcow_aio_setup(bs, sector_num, qiov, nb_sectors, 1, &acb);
 
     qemu_co_mutex_lock(&s->lock);
     do {
-        ret = qcow_aio_write_cb(acb);
+        ret = qcow_aio_write_cb(&acb);
     } while (ret > 0);
     qemu_co_mutex_unlock(&s->lock);
 
-    if (acb->qiov->niov > 1) {
-        qemu_vfree(acb->orig_buf);
+    if (acb.qiov->niov > 1) {
+        qemu_vfree(acb.orig_buf);
     }
-    qemu_aio_release(acb);
 
     return ret;
 }
diff --git a/block/qcow2.c b/block/qcow2.c
index 01ea265..f4e3c06 100644
--- a/block/qcow2.c
+++ b/block/qcow2.c
@@ -392,17 +392,6 @@ typedef struct QCowAIOCB {
     QLIST_ENTRY(QCowAIOCB) next_depend;
 } QCowAIOCB;
 
-static void qcow2_aio_cancel(BlockDriverAIOCB *blockacb)
-{
-    QCowAIOCB *acb = container_of(blockacb, QCowAIOCB, common);
-    qemu_aio_release(acb);
-}
-
-static AIOPool qcow2_aio_pool = {
-    .aiocb_size         = sizeof(QCowAIOCB),
-    .cancel             = qcow2_aio_cancel,
-};
-
 /*
  * Returns 0 when the request is completed successfully, 1 when there is still
  * a part left to do and -errno in error cases.
@@ -532,13 +521,10 @@ static int qcow2_aio_read_cb(QCowAIOCB *acb)
 static QCowAIOCB *qcow2_aio_setup(BlockDriverState *bs, int64_t sector_num,
                                   QEMUIOVector *qiov, int nb_sectors,
                                   BlockDriverCompletionFunc *cb,
-                                  void *opaque, int is_write)
+                                  void *opaque, int is_write, QCowAIOCB *acb)
 {
-    QCowAIOCB *acb;
-
-    acb = qemu_aio_get(&qcow2_aio_pool, bs, cb, opaque);
-    if (!acb)
-        return NULL;
+    memset(acb, 0, sizeof(*acb));
+    acb->common.bs = bs;
     acb->sector_num = sector_num;
     acb->qiov = qiov;
     acb->is_write = is_write;
@@ -558,19 +544,18 @@ static int qcow2_co_readv(BlockDriverState *bs, int64_t sector_num,
                           int nb_sectors, QEMUIOVector *qiov)
 {
     BDRVQcowState *s = bs->opaque;
-    QCowAIOCB *acb;
+    QCowAIOCB acb;
     int ret;
 
-    acb = qcow2_aio_setup(bs, sector_num, qiov, nb_sectors, NULL, NULL, 0);
+    qcow2_aio_setup(bs, sector_num, qiov, nb_sectors, NULL, NULL, 0, &acb);
 
     qemu_co_mutex_lock(&s->lock);
     do {
-        ret = qcow2_aio_read_cb(acb);
+        ret = qcow2_aio_read_cb(&acb);
     } while (ret > 0);
     qemu_co_mutex_unlock(&s->lock);
 
-    qemu_iovec_destroy(&acb->hd_qiov);
-    qemu_aio_release(acb);
+    qemu_iovec_destroy(&acb.hd_qiov);
 
     return ret;
 }
@@ -674,20 +659,19 @@ static int qcow2_co_writev(BlockDriverState *bs,
                            QEMUIOVector *qiov)
 {
     BDRVQcowState *s = bs->opaque;
-    QCowAIOCB *acb;
+    QCowAIOCB acb;
     int ret;
 
-    acb = qcow2_aio_setup(bs, sector_num, qiov, nb_sectors, NULL, NULL, 1);
+    qcow2_aio_setup(bs, sector_num, qiov, nb_sectors, NULL, NULL, 1, &acb);
     s->cluster_cache_offset = -1; /* disable compressed cache */
 
     qemu_co_mutex_lock(&s->lock);
     do {
-        ret = qcow2_aio_write_cb(acb);
+        ret = qcow2_aio_write_cb(&acb);
     } while (ret > 0);
     qemu_co_mutex_unlock(&s->lock);
 
-    qemu_iovec_destroy(&acb->hd_qiov);
-    qemu_aio_release(acb);
+    qemu_iovec_destroy(&acb.hd_qiov);
 
     return ret;
 }
commit e4ea78ee76ab3d725dc63bc7025568e8ddbd7dbf
Author: Avi Kivity <avi at redhat.com>
Date:   Sun Aug 14 07:04:49 2011 +0300

    posix-aio-compat: fix latency issues
    
    In certain circumstances, posix-aio-compat can incur a lot of latency:
     - threads are created by vcpu threads, so if vcpu affinity is set,
       aio threads inherit vcpu affinity.  This can cause many aio threads
       to compete for one cpu.
     - we can create up to max_threads (64) aio threads in one go; since a
       pthread_create can take around 30μs, we have up to 2ms of cpu time
       under a global lock.
    
    Fix by:
     - moving thread creation to the main thread, so we inherit the main
       thread's affinity instead of the vcpu thread's affinity.
     - if a thread is currently being created, and we need to create yet
       another thread, let thread being born create the new thread, reducing
       the amount of time we spend under the main thread.
     - drop the local lock while creating a thread (we may still hold the
       global mutex, though)
    
    Note this doesn't eliminate latency completely; scheduler artifacts or
    lack of host cpu resources can still cause it.  We may want pre-allocated
    threads when this cannot be tolerated.
    
    Thanks to Uli Obergfell of Red Hat for his excellent analysis and suggestions.
    
    Signed-off-by: Avi Kivity <avi at redhat.com>
    Signed-off-by: Kevin Wolf <kwolf at redhat.com>

diff --git a/posix-aio-compat.c b/posix-aio-compat.c
index babb094..3193dbf 100644
--- a/posix-aio-compat.c
+++ b/posix-aio-compat.c
@@ -30,6 +30,7 @@
 
 #include "block/raw-posix-aio.h"
 
+static void do_spawn_thread(void);
 
 struct qemu_paiocb {
     BlockDriverAIOCB common;
@@ -64,6 +65,9 @@ static pthread_attr_t attr;
 static int max_threads = 64;
 static int cur_threads = 0;
 static int idle_threads = 0;
+static int new_threads = 0;     /* backlog of threads we need to create */
+static int pending_threads = 0; /* threads created but not running yet */
+static QEMUBH *new_thread_bh;
 static QTAILQ_HEAD(, qemu_paiocb) request_list;
 
 #ifdef CONFIG_PREADV
@@ -311,6 +315,11 @@ static void *aio_thread(void *unused)
 
     pid = getpid();
 
+    mutex_lock(&lock);
+    pending_threads--;
+    mutex_unlock(&lock);
+    do_spawn_thread();
+
     while (1) {
         struct qemu_paiocb *aiocb;
         ssize_t ret = 0;
@@ -381,11 +390,20 @@ static void *aio_thread(void *unused)
     return NULL;
 }
 
-static void spawn_thread(void)
+static void do_spawn_thread(void)
 {
     sigset_t set, oldset;
 
-    cur_threads++;
+    mutex_lock(&lock);
+    if (!new_threads) {
+        mutex_unlock(&lock);
+        return;
+    }
+
+    new_threads--;
+    pending_threads++;
+
+    mutex_unlock(&lock);
 
     /* block all signals */
     if (sigfillset(&set)) die("sigfillset");
@@ -396,6 +414,27 @@ static void spawn_thread(void)
     if (sigprocmask(SIG_SETMASK, &oldset, NULL)) die("sigprocmask restore");
 }
 
+static void spawn_thread_bh_fn(void *opaque)
+{
+    do_spawn_thread();
+}
+
+static void spawn_thread(void)
+{
+    cur_threads++;
+    new_threads++;
+    /* If there are threads being created, they will spawn new workers, so
+     * we don't spend time creating many threads in a loop holding a mutex or
+     * starving the current vcpu.
+     *
+     * If there are no idle threads, ask the main thread to create one, so we
+     * inherit the correct affinity instead of the vcpu affinity.
+     */
+    if (!pending_threads) {
+        qemu_bh_schedule(new_thread_bh);
+    }
+}
+
 static void qemu_paio_submit(struct qemu_paiocb *aiocb)
 {
     aiocb->ret = -EINPROGRESS;
@@ -665,6 +704,7 @@ int paio_init(void)
         die2(ret, "pthread_attr_setdetachstate");
 
     QTAILQ_INIT(&request_list);
+    new_thread_bh = qemu_bh_new(spawn_thread_bh_fn, NULL);
 
     posix_aio_state = s;
     return 0;
commit e8045d6726b45e27812cc7504781859e8c3afffb
Author: Christoph Hellwig <hch at lst.de>
Date:   Mon Aug 22 00:25:58 2011 +0200

    block: include flush requests in info blockstats
    
    Signed-off-by: Christoph Hellwig <hch at lst.de>
    Signed-off-by: Kevin Wolf <kwolf at redhat.com>

diff --git a/block.c b/block.c
index 4186a2f..0f256f5 100644
--- a/block.c
+++ b/block.c
@@ -1915,11 +1915,13 @@ static void bdrv_stats_iter(QObject *data, void *opaque)
                         " wr_bytes=%" PRId64
                         " rd_operations=%" PRId64
                         " wr_operations=%" PRId64
+                        " flush_operations=%" PRId64
                         "\n",
                         qdict_get_int(qdict, "rd_bytes"),
                         qdict_get_int(qdict, "wr_bytes"),
                         qdict_get_int(qdict, "rd_operations"),
-                        qdict_get_int(qdict, "wr_operations"));
+                        qdict_get_int(qdict, "wr_operations"),
+                        qdict_get_int(qdict, "flush_operations"));
 }
 
 void bdrv_stats_print(Monitor *mon, const QObject *data)
@@ -1937,12 +1939,16 @@ static QObject* bdrv_info_stats_bs(BlockDriverState *bs)
                              "'wr_bytes': %" PRId64 ","
                              "'rd_operations': %" PRId64 ","
                              "'wr_operations': %" PRId64 ","
-                             "'wr_highest_offset': %" PRId64
+                             "'wr_highest_offset': %" PRId64 ","
+                             "'flush_operations': %" PRId64
                              "} }",
-                             bs->rd_bytes, bs->wr_bytes,
-                             bs->rd_ops, bs->wr_ops,
+                             bs->rd_bytes,
+                             bs->wr_bytes,
+                             bs->rd_ops,
+                             bs->wr_ops,
                              bs->wr_highest_sector *
-                             (uint64_t)BDRV_SECTOR_SIZE);
+                             (uint64_t)BDRV_SECTOR_SIZE,
+                             bs->flush_ops);
     dict  = qobject_to_qdict(res);
 
     if (*bs->device_name) {
@@ -2606,6 +2612,8 @@ BlockDriverAIOCB *bdrv_aio_flush(BlockDriverState *bs,
 
     trace_bdrv_aio_flush(bs, opaque);
 
+    bs->flush_ops++;
+
     if (bs->open_flags & BDRV_O_NO_FLUSH) {
         return bdrv_aio_noop_em(bs, cb, opaque);
     }
diff --git a/block_int.h b/block_int.h
index f6d02b3..f1480d6 100644
--- a/block_int.h
+++ b/block_int.h
@@ -188,6 +188,7 @@ struct BlockDriverState {
     uint64_t wr_bytes;
     uint64_t rd_ops;
     uint64_t wr_ops;
+    uint64_t flush_ops;
     uint64_t wr_highest_sector;
 
     /* Whether the disk can expand beyond total_sectors */
diff --git a/qmp-commands.hx b/qmp-commands.hx
index 03f67da..8570b33 100644
--- a/qmp-commands.hx
+++ b/qmp-commands.hx
@@ -1201,6 +1201,7 @@ Each json-object contain the following:
     - "wr_bytes": bytes written (json-int)
     - "rd_operations": read operations (json-int)
     - "wr_operations": write operations (json-int)
+    - "flush_operations": cache flush operations (json-int)
     - "wr_highest_offset": Highest offset of a sector written since the
                            BlockDriverState has been opened (json-int)
 - "parent": Contains recursively the statistics of the underlying
@@ -1222,6 +1223,7 @@ Example:
                   "wr_operations":751,
                   "rd_bytes":122567168,
                   "rd_operations":36772
+                  "flush_operations":61,
                }
             },
             "stats":{
@@ -1230,6 +1232,7 @@ Example:
                "wr_operations":692,
                "rd_bytes":122739200,
                "rd_operations":36604
+               "flush_operations":51,
             }
          },
          {
@@ -1240,6 +1243,7 @@ Example:
                "wr_operations":0,
                "rd_bytes":0,
                "rd_operations":0
+               "flush_operations":0,
             }
          },
          {
@@ -1250,6 +1254,7 @@ Example:
                "wr_operations":0,
                "rd_bytes":0,
                "rd_operations":0
+               "flush_operations":0,
             }
          },
          {
@@ -1260,6 +1265,7 @@ Example:
                "wr_operations":0,
                "rd_bytes":0,
                "rd_operations":0
+               "flush_operations":0,
             }
          }
       ]
commit f785a5ae36c92fbeb8e0e8c9d71f5789cbce8b29
Author: Nicholas Thomas <nick at bytemark.co.uk>
Date:   Mon Aug 15 10:00:34 2011 +0100

    block/curl: Handle failed reads gracefully.
    
    Current behaviour if a read fails is for the acb to not get finished.
    This causes an infinite loop in bdrv_read_em (block.c). The read failure
    never gets reported to the  guest and if the error condition clears, the
    process never recovers.
    
    With this patch, when curl reports a failure we finish the acb as a
    failure. This results in the guest receiving an I/O error (rather than
    the read hanging indefinitely) and if the error condition subsequently
    clears, retries work as expected.
    
    The simplest test is to put an ISO on a web server you have control over
    and open it with qemu-io. Then move the ISO out of the way and attempt
    to read some data - you should see behaviour matching the above.
    
    Signed-off-by: Nick Thomas <nick at bytemark.co.uk>
    Signed-off-by: Kevin Wolf <kwolf at redhat.com>

diff --git a/block/curl.c b/block/curl.c
index 5c157bc..f3f61cc 100644
--- a/block/curl.c
+++ b/block/curl.c
@@ -229,6 +229,23 @@ static void curl_multi_do(void *arg)
             {
                 CURLState *state = NULL;
                 curl_easy_getinfo(msg->easy_handle, CURLINFO_PRIVATE, (char**)&state);
+
+                /* ACBs for successful messages get completed in curl_read_cb */
+                if (msg->data.result != CURLE_OK) {
+                    int i;
+                    for (i = 0; i < CURL_NUM_ACB; i++) {
+                        CURLAIOCB *acb = state->acb[i];
+
+                        if (acb == NULL) {
+                            continue;
+                        }
+
+                        acb->common.cb(acb->common.opaque, -EIO);
+                        qemu_aio_release(acb);
+                        state->acb[i] = NULL;
+                    }
+                }
+
                 curl_clean_state(state);
                 break;
             }
@@ -277,7 +294,8 @@ static CURLState *curl_init_state(BDRVCURLState *s)
     curl_easy_setopt(state->curl, CURLOPT_FOLLOWLOCATION, 1);
     curl_easy_setopt(state->curl, CURLOPT_NOSIGNAL, 1);
     curl_easy_setopt(state->curl, CURLOPT_ERRORBUFFER, state->errmsg);
-    
+    curl_easy_setopt(state->curl, CURLOPT_FAILONERROR, 1);
+
 #ifdef DEBUG_VERBOSE
     curl_easy_setopt(state->curl, CURLOPT_VERBOSE, 1);
 #endif
commit 3fba9d8198a50f69e80aba8458d26cf1654e6e26
Author: Stefan Hajnoczi <stefanha at linux.vnet.ibm.com>
Date:   Wed Aug 17 17:41:09 2011 +0100

    qemu-img: print error codes when convert fails
    
    Signed-off-by: Stefan Hajnoczi <stefanha at linux.vnet.ibm.com>
    Signed-off-by: Kevin Wolf <kwolf at redhat.com>

diff --git a/qemu-img.c b/qemu-img.c
index 2fee782..0561d77 100644
--- a/qemu-img.c
+++ b/qemu-img.c
@@ -870,7 +870,8 @@ static int img_convert(int argc, char **argv)
 
                 ret = bdrv_read(bs[bs_i], bs_num, buf2, nlow);
                 if (ret < 0) {
-                    error_report("error while reading");
+                    error_report("error while reading sector %" PRId64 ": %s",
+                                 bs_num, strerror(-ret));
                     goto out;
                 }
 
@@ -888,8 +889,8 @@ static int img_convert(int argc, char **argv)
                 ret = bdrv_write_compressed(out_bs, sector_num, buf,
                                             cluster_sectors);
                 if (ret != 0) {
-                    error_report("error while compressing sector %" PRId64,
-                          sector_num);
+                    error_report("error while compressing sector %" PRId64
+                                 ": %s", sector_num, strerror(-ret));
                     goto out;
                 }
             }
@@ -952,7 +953,8 @@ static int img_convert(int argc, char **argv)
 
             ret = bdrv_read(bs[bs_i], sector_num - bs_offset, buf, n);
             if (ret < 0) {
-                error_report("error while reading");
+                error_report("error while reading sector %" PRId64 ": %s",
+                             sector_num - bs_offset, strerror(-ret));
                 goto out;
             }
             /* NOTE: at the same time we convert, we do not write zero
@@ -971,7 +973,8 @@ static int img_convert(int argc, char **argv)
                     is_allocated_sectors(buf1, n, &n1)) {
                     ret = bdrv_write(out_bs, sector_num, buf1, n1);
                     if (ret < 0) {
-                        error_report("error while writing");
+                        error_report("error while writing sector %" PRId64
+                                     ": %s", sector_num, strerror(-ret));
                         goto out;
                     }
                 }
commit de33b1f3ddef8d6b4d53dbd4ae049262de2d3f02
Author: Scott Wood <scottwood at freescale.com>
Date:   Thu Aug 11 16:27:15 2011 -0500

    qcow: initialize coroutine mutex
    
    commit 52b8eb60132b27ad53476490e9d7579003390cfa added a mutex,
    but never initialized it.  This caused a segfault.
    
    Reported-by: Alexander Graf <agraf at suse.de>
    Signed-off-by: Scott Wood <scottwood at freescale.com>
    Signed-off-by: Kevin Wolf <kwolf at redhat.com>

diff --git a/block/qcow.c b/block/qcow.c
index e155d3c..8f2bdfd 100644
--- a/block/qcow.c
+++ b/block/qcow.c
@@ -159,6 +159,8 @@ static int qcow_open(BlockDriverState *bs, int flags)
             goto fail;
         bs->backing_file[len] = '\0';
     }
+
+    qemu_co_mutex_init(&s->lock);
     return 0;
 
  fail:
commit d57237f29127c8c488453e327221c7b3dcdbfd01
Author: Devin Nakamura <devin122 at gmail.com>
Date:   Sun Aug 7 19:47:36 2011 -0400

    qcow2: fix typo in documentation for qcow2_get_cluster_offset()
    
    Documentation states the num is measured in clusters, but its
    actually measured in sectors
    
    Signed-off-by: Devin Nakamura <devin122 at gmail.com>
    Signed-off-by: Kevin Wolf <kwolf at redhat.com>

diff --git a/block/qcow2-cluster.c b/block/qcow2-cluster.c
index 9269dda..fde397e 100644
--- a/block/qcow2-cluster.c
+++ b/block/qcow2-cluster.c
@@ -381,10 +381,10 @@ static int copy_sectors(BlockDriverState *bs, uint64_t start_sect,
  * For a given offset of the disk image, find the cluster offset in
  * qcow2 file. The offset is stored in *cluster_offset.
  *
- * on entry, *num is the number of contiguous clusters we'd like to
+ * on entry, *num is the number of contiguous sectors we'd like to
  * access following offset.
  *
- * on exit, *num is the number of contiguous clusters we can read.
+ * on exit, *num is the number of contiguous sectors we can read.
  *
  * Return 0, if the offset is found
  * Return -errno, otherwise.
commit bb1c05973cf2206b628b0dc064f7e022b63f2702
Author: Kevin Wolf <kwolf at redhat.com>
Date:   Mon Aug 8 14:09:12 2011 +0200

    qemu-img: Use qemu_blockalign
    
    Now that you can use cache=none for the output file in qemu-img, we should
    properly align our buffers so that raw-posix doesn't have to use its (smaller)
    bounce buffer.
    
    Signed-off-by: Kevin Wolf <kwolf at redhat.com>
    Reviewed-by: Stefan Hajnoczi <stefanha at linux.vnet.ibm.com>

diff --git a/qemu-img.c b/qemu-img.c
index 10a3a8b..2fee782 100644
--- a/qemu-img.c
+++ b/qemu-img.c
@@ -814,7 +814,7 @@ static int img_convert(int argc, char **argv)
     bs_i = 0;
     bs_offset = 0;
     bdrv_get_geometry(bs[0], &bs_sectors);
-    buf = g_malloc(IO_BUF_SIZE);
+    buf = qemu_blockalign(out_bs, IO_BUF_SIZE);
 
     if (compress) {
         ret = bdrv_get_info(out_bs, &bdi);
@@ -986,7 +986,7 @@ out:
     qemu_progress_end();
     free_option_parameters(create_options);
     free_option_parameters(param);
-    g_free(buf);
+    qemu_vfree(buf);
     if (out_bs) {
         bdrv_delete(out_bs);
     }
@@ -1353,8 +1353,8 @@ static int img_rebase(int argc, char **argv)
         uint8_t * buf_new;
         float local_progress;
 
-        buf_old = g_malloc(IO_BUF_SIZE);
-        buf_new = g_malloc(IO_BUF_SIZE);
+        buf_old = qemu_blockalign(bs, IO_BUF_SIZE);
+        buf_new = qemu_blockalign(bs, IO_BUF_SIZE);
 
         bdrv_get_geometry(bs, &num_sectors);
 
@@ -1410,8 +1410,8 @@ static int img_rebase(int argc, char **argv)
             qemu_progress_print(local_progress, 100);
         }
 
-        g_free(buf_old);
-        g_free(buf_new);
+        qemu_vfree(buf_old);
+        qemu_vfree(buf_new);
     }
 
     /*
commit 6cbc3031c8408e4cb3e55a01f25536e81d3ae90d
Author: Philipp Hahn <hahn at univention.de>
Date:   Thu Aug 4 19:22:10 2011 +0200

    qcow2: Fix DEBUG_* compilation
    
    By introducing BlockDriverState compiling qcow2 with DEBUG_ALLOC and DEBUG_EXT
    defined got broken.
    Define a BdrvCheckResult structure locally which is now needed as the second
    argument.
    
    Also fix qcow2_read_extensions() needing BDRVQcowState.
    
    Signed-off-by: Philipp Hahn <hahn at univention.de>
    Signed-off-by: Kevin Wolf <kwolf at redhat.com>

diff --git a/block/qcow2-snapshot.c b/block/qcow2-snapshot.c
index 3bd2a30..3e6bf8b 100644
--- a/block/qcow2-snapshot.c
+++ b/block/qcow2-snapshot.c
@@ -303,7 +303,10 @@ int qcow2_snapshot_create(BlockDriverState *bs, QEMUSnapshotInfo *sn_info)
     if (qcow2_write_snapshots(bs) < 0)
         goto fail;
 #ifdef DEBUG_ALLOC
-    qcow2_check_refcounts(bs);
+    {
+      BdrvCheckResult result = {0};
+      qcow2_check_refcounts(bs, &result);
+    }
 #endif
     return 0;
  fail:
@@ -353,7 +356,10 @@ int qcow2_snapshot_goto(BlockDriverState *bs, const char *snapshot_id)
         goto fail;
 
 #ifdef DEBUG_ALLOC
-    qcow2_check_refcounts(bs);
+    {
+        BdrvCheckResult result = {0};
+        qcow2_check_refcounts(bs, &result);
+    }
 #endif
     return 0;
  fail:
@@ -390,7 +396,10 @@ int qcow2_snapshot_delete(BlockDriverState *bs, const char *snapshot_id)
         return ret;
     }
 #ifdef DEBUG_ALLOC
-    qcow2_check_refcounts(bs);
+    {
+        BdrvCheckResult result = {0};
+        qcow2_check_refcounts(bs, &result);
+    }
 #endif
     return 0;
 }
diff --git a/block/qcow2.c b/block/qcow2.c
index bfff6cd..01ea265 100644
--- a/block/qcow2.c
+++ b/block/qcow2.c
@@ -87,6 +87,7 @@ static int qcow2_read_extensions(BlockDriverState *bs, uint64_t start_offset,
     while (offset < end_offset) {
 
 #ifdef DEBUG_EXT
+        BDRVQcowState *s = bs->opaque;
         /* Sanity check */
         if (offset > s->cluster_size)
             printf("qcow2_read_extension: suspicious offset %lu\n", offset);
@@ -280,7 +281,10 @@ static int qcow2_open(BlockDriverState *bs, int flags)
     qemu_co_mutex_init(&s->lock);
 
 #ifdef DEBUG_ALLOC
-    qcow2_check_refcounts(bs);
+    {
+        BdrvCheckResult result = {0};
+        qcow2_check_refcounts(bs, &result);
+    }
 #endif
     return ret;
 
commit 92196b2f5664d5defa778b1b24df56e2239b5e93
Author: Stefan Hajnoczi <stefanha at linux.vnet.ibm.com>
Date:   Thu Aug 4 12:26:52 2011 +0100

    block: add cache=directsync parameter to -drive
    
    This patch adds -drive cache=directsync for O_DIRECT | O_SYNC host file
    I/O with no disk write cache presented to the guest.
    
    This mode is useful when guests may not be sending flushes when
    appropriate and therefore leave data at risk in case of power failure.
    When cache=directsync is used, write operations are only completed to
    the guest when data is safely on disk.
    
    This new mode is like cache=writethrough but it bypasses the host page
    cache.
    
    Signed-off-by: Stefan Hajnoczi <stefanha at linux.vnet.ibm.com>
    Signed-off-by: Kevin Wolf <kwolf at redhat.com>

diff --git a/block.c b/block.c
index dbef3ae..4186a2f 100644
--- a/block.c
+++ b/block.c
@@ -448,6 +448,8 @@ int bdrv_parse_cache_flags(const char *mode, int *flags)
 
     if (!strcmp(mode, "off") || !strcmp(mode, "none")) {
         *flags |= BDRV_O_NOCACHE | BDRV_O_CACHE_WB;
+    } else if (!strcmp(mode, "directsync")) {
+        *flags |= BDRV_O_NOCACHE;
     } else if (!strcmp(mode, "writeback")) {
         *flags |= BDRV_O_CACHE_WB;
     } else if (!strcmp(mode, "unsafe")) {
@@ -1188,8 +1190,8 @@ int bdrv_pwrite_sync(BlockDriverState *bs, int64_t offset,
         return ret;
     }
 
-    /* No flush needed for cache=writethrough, it uses O_DSYNC */
-    if ((bs->open_flags & BDRV_O_CACHE_MASK) != 0) {
+    /* No flush needed for cache modes that use O_DSYNC */
+    if ((bs->open_flags & BDRV_O_CACHE_WB) != 0) {
         bdrv_flush(bs);
     }
 
diff --git a/qemu-config.c b/qemu-config.c
index 1eb6b9a..139e077 100644
--- a/qemu-config.c
+++ b/qemu-config.c
@@ -55,7 +55,8 @@ static QemuOptsList qemu_drive_opts = {
         },{
             .name = "cache",
             .type = QEMU_OPT_STRING,
-            .help = "host cache usage (none, writeback, writethrough, unsafe)",
+            .help = "host cache usage (none, writeback, writethrough, "
+                    "directsync, unsafe)",
         },{
             .name = "aio",
             .type = QEMU_OPT_STRING,
diff --git a/qemu-img.c b/qemu-img.c
index 5e203c2..10a3a8b 100644
--- a/qemu-img.c
+++ b/qemu-img.c
@@ -66,7 +66,8 @@ static void help(void)
            "  'filename' is a disk image filename\n"
            "  'fmt' is the disk image format. It is guessed automatically in most cases\n"
            "  'cache' is the cache mode used to write the output disk image, the valid\n"
-           "    options are: 'none', 'writeback' (default), 'writethrough' and 'unsafe'\n"
+           "    options are: 'none', 'writeback' (default), 'writethrough', 'directsync'\n"
+           "    and 'unsafe'\n"
            "  'size' is the disk image size in bytes. Optional suffixes\n"
            "    'k' or 'K' (kilobyte, 1024), 'M' (megabyte, 1024k), 'G' (gigabyte, 1024M)\n"
            "    and T (terabyte, 1024G) are supported. 'b' is ignored.\n"
diff --git a/qemu-options.hx b/qemu-options.hx
index d86815d..35d95d1 100644
--- a/qemu-options.hx
+++ b/qemu-options.hx
@@ -133,7 +133,7 @@ ETEXI
 DEF("drive", HAS_ARG, QEMU_OPTION_drive,
     "-drive [file=file][,if=type][,bus=n][,unit=m][,media=d][,index=i]\n"
     "       [,cyls=c,heads=h,secs=s[,trans=t]][,snapshot=on|off]\n"
-    "       [,cache=writethrough|writeback|none|unsafe][,format=f]\n"
+    "       [,cache=writethrough|writeback|none|directsync|unsafe][,format=f]\n"
     "       [,serial=s][,addr=A][,id=name][,aio=threads|native]\n"
     "       [,readonly=on|off]\n"
     "                use 'file' as a drive image\n", QEMU_ARCH_ALL)
@@ -164,7 +164,7 @@ These options have the same definition as they have in @option{-hdachs}.
 @item snapshot=@var{snapshot}
 @var{snapshot} is "on" or "off" and allows to enable snapshot for given drive (see @option{-snapshot}).
 @item cache=@var{cache}
- at var{cache} is "none", "writeback", "unsafe", or "writethrough" and controls how the host cache is used to access block data.
+ at var{cache} is "none", "writeback", "unsafe", "directsync" or "writethrough" and controls how the host cache is used to access block data.
 @item aio=@var{aio}
 @var{aio} is "threads", or "native" and selects between pthread based disk I/O and native Linux AIO.
 @item format=@var{format}
@@ -199,6 +199,10 @@ The host page cache can be avoided entirely with @option{cache=none}.  This will
 attempt to do disk IO directly to the guests memory.  QEMU may still perform
 an internal copy of the data.
 
+The host page cache can be avoided while only sending write notifications to
+the guest when the data has been reported as written by the storage subsystem
+using @option{cache=directsync}.
+
 Some block drivers perform badly with @option{cache=writethrough}, most notably,
 qcow2.  If performance is more important than correctness,
 @option{cache=writeback} should be used with qcow2.
commit c3993cdca39c252d65bbbcc234d8d242dc9bd693
Author: Stefan Hajnoczi <stefanha at linux.vnet.ibm.com>
Date:   Thu Aug 4 12:26:51 2011 +0100

    block: parse cache mode flags in a single place
    
    This patch introduces bdrv_parse_cache_flags() which sets open flags
    given a cache mode.  Previously this was duplicated in blockdev.c and
    qemu-img.c.
    
    Signed-off-by: Stefan Hajnoczi <stefanha at linux.vnet.ibm.com>
    Signed-off-by: Kevin Wolf <kwolf at redhat.com>

diff --git a/block.c b/block.c
index a8a013a..dbef3ae 100644
--- a/block.c
+++ b/block.c
@@ -437,6 +437,31 @@ static int refresh_total_sectors(BlockDriverState *bs, int64_t hint)
     return 0;
 }
 
+/**
+ * Set open flags for a given cache mode
+ *
+ * Return 0 on success, -1 if the cache mode was invalid.
+ */
+int bdrv_parse_cache_flags(const char *mode, int *flags)
+{
+    *flags &= ~BDRV_O_CACHE_MASK;
+
+    if (!strcmp(mode, "off") || !strcmp(mode, "none")) {
+        *flags |= BDRV_O_NOCACHE | BDRV_O_CACHE_WB;
+    } else if (!strcmp(mode, "writeback")) {
+        *flags |= BDRV_O_CACHE_WB;
+    } else if (!strcmp(mode, "unsafe")) {
+        *flags |= BDRV_O_CACHE_WB;
+        *flags |= BDRV_O_NO_FLUSH;
+    } else if (!strcmp(mode, "writethrough")) {
+        /* this is the default */
+    } else {
+        return -1;
+    }
+
+    return 0;
+}
+
 /*
  * Common part for opening disk images and files
  */
diff --git a/block.h b/block.h
index a3bfaaf..c7b5128 100644
--- a/block.h
+++ b/block.h
@@ -69,6 +69,7 @@ int bdrv_create_file(const char* filename, QEMUOptionParameter *options);
 BlockDriverState *bdrv_new(const char *device_name);
 void bdrv_make_anon(BlockDriverState *bs);
 void bdrv_delete(BlockDriverState *bs);
+int bdrv_parse_cache_flags(const char *mode, int *flags);
 int bdrv_file_open(BlockDriverState **pbs, const char *filename, int flags);
 int bdrv_open(BlockDriverState *bs, const char *filename, int flags,
               BlockDriver *drv);
diff --git a/blockdev.c b/blockdev.c
index d272659..2602591 100644
--- a/blockdev.c
+++ b/blockdev.c
@@ -321,18 +321,9 @@ DriveInfo *drive_init(QemuOpts *opts, int default_to_scsi)
     }
 
     if ((buf = qemu_opt_get(opts, "cache")) != NULL) {
-        if (!strcmp(buf, "off") || !strcmp(buf, "none")) {
-            bdrv_flags |= BDRV_O_NOCACHE | BDRV_O_CACHE_WB;
-        } else if (!strcmp(buf, "writeback")) {
-            bdrv_flags |= BDRV_O_CACHE_WB;
-        } else if (!strcmp(buf, "unsafe")) {
-            bdrv_flags |= BDRV_O_CACHE_WB;
-            bdrv_flags |= BDRV_O_NO_FLUSH;
-        } else if (!strcmp(buf, "writethrough")) {
-            /* this is the default */
-        } else {
-           error_report("invalid cache option");
-           return NULL;
+        if (bdrv_parse_cache_flags(buf, &bdrv_flags) != 0) {
+            error_report("invalid cache option");
+            return NULL;
         }
     }
 
diff --git a/qemu-img.c b/qemu-img.c
index 95f3219..5e203c2 100644
--- a/qemu-img.c
+++ b/qemu-img.c
@@ -183,27 +183,6 @@ static int read_password(char *buf, int buf_size)
 }
 #endif
 
-static int set_cache_flag(const char *mode, int *flags)
-{
-    *flags &= ~BDRV_O_CACHE_MASK;
-
-    if (!strcmp(mode, "none") || !strcmp(mode, "off")) {
-        *flags |= BDRV_O_CACHE_WB;
-        *flags |= BDRV_O_NOCACHE;
-    } else if (!strcmp(mode, "writeback")) {
-        *flags |= BDRV_O_CACHE_WB;
-    } else if (!strcmp(mode, "unsafe")) {
-        *flags |= BDRV_O_CACHE_WB;
-        *flags |= BDRV_O_NO_FLUSH;
-    } else if (!strcmp(mode, "writethrough")) {
-        /* this is the default */
-    } else {
-        return -1;
-    }
-
-    return 0;
-}
-
 static int print_block_option_help(const char *filename, const char *fmt)
 {
     BlockDriver *drv, *proto_drv;
@@ -495,7 +474,7 @@ static int img_commit(int argc, char **argv)
     filename = argv[optind++];
 
     flags = BDRV_O_RDWR;
-    ret = set_cache_flag(cache, &flags);
+    ret = bdrv_parse_cache_flags(cache, &flags);
     if (ret < 0) {
         error_report("Invalid cache option: %s", cache);
         return -1;
@@ -819,7 +798,7 @@ static int img_convert(int argc, char **argv)
     }
 
     flags = BDRV_O_RDWR;
-    ret = set_cache_flag(cache, &flags);
+    ret = bdrv_parse_cache_flags(cache, &flags);
     if (ret < 0) {
         error_report("Invalid cache option: %s", cache);
         return -1;
@@ -1291,7 +1270,7 @@ static int img_rebase(int argc, char **argv)
     qemu_progress_print(0, 100);
 
     flags = BDRV_O_RDWR | (unsafe ? BDRV_O_NO_BACKING : 0);
-    ret = set_cache_flag(cache, &flags);
+    ret = bdrv_parse_cache_flags(cache, &flags);
     if (ret < 0) {
         error_report("Invalid cache option: %s", cache);
         return -1;
commit 12888904fe7f0231e853072805fb2317ec60c510
Author: Aneesh Kumar K.V <aneesh.kumar at linux.vnet.ibm.com>
Date:   Tue Aug 2 12:02:51 2011 +0530

    coroutine: Add CoRwlock support
    
    Signed-off-by: Aneesh Kumar K.V <aneesh.kumar at linux.vnet.ibm.com>
    Signed-off-by: Kevin Wolf <kwolf at redhat.com>

diff --git a/qemu-coroutine-lock.c b/qemu-coroutine-lock.c
index a80f437..2a385a3 100644
--- a/qemu-coroutine-lock.c
+++ b/qemu-coroutine-lock.c
@@ -115,3 +115,47 @@ void coroutine_fn qemu_co_mutex_unlock(CoMutex *mutex)
 
     trace_qemu_co_mutex_unlock_return(mutex, self);
 }
+
+void qemu_co_rwlock_init(CoRwlock *lock)
+{
+    memset(lock, 0, sizeof(*lock));
+    qemu_co_queue_init(&lock->queue);
+}
+
+void qemu_co_rwlock_rdlock(CoRwlock *lock)
+{
+    while (lock->writer) {
+        qemu_co_queue_wait(&lock->queue);
+    }
+    lock->reader++;
+}
+
+void qemu_co_rwlock_unlock(CoRwlock *lock)
+{
+    assert(qemu_in_coroutine());
+    if (lock->writer) {
+        lock->writer = false;
+        while (!qemu_co_queue_empty(&lock->queue)) {
+            /*
+             * Wakeup every body. This will include some
+             * writers too.
+             */
+            qemu_co_queue_next(&lock->queue);
+        }
+    } else {
+        lock->reader--;
+        assert(lock->reader >= 0);
+        /* Wakeup only one waiting writer */
+        if (!lock->reader) {
+            qemu_co_queue_next(&lock->queue);
+        }
+    }
+}
+
+void qemu_co_rwlock_wrlock(CoRwlock *lock)
+{
+    while (lock->writer || lock->reader) {
+        qemu_co_queue_wait(&lock->queue);
+    }
+    lock->writer = true;
+}
diff --git a/qemu-coroutine.h b/qemu-coroutine.h
index 2f2fd95..b8fc4f4 100644
--- a/qemu-coroutine.h
+++ b/qemu-coroutine.h
@@ -156,4 +156,36 @@ void coroutine_fn qemu_co_mutex_lock(CoMutex *mutex);
  */
 void coroutine_fn qemu_co_mutex_unlock(CoMutex *mutex);
 
+typedef struct CoRwlock {
+    bool writer;
+    int reader;
+    CoQueue queue;
+} CoRwlock;
+
+/**
+ * Initialises a CoRwlock. This must be called before any other operation
+ * is used on the CoRwlock
+ */
+void qemu_co_rwlock_init(CoRwlock *lock);
+
+/**
+ * Read locks the CoRwlock. If the lock cannot be taken immediately because
+ * of a parallel writer, control is transferred to the caller of the current
+ * coroutine.
+ */
+void qemu_co_rwlock_rdlock(CoRwlock *lock);
+
+/**
+ * Write Locks the mutex. If the lock cannot be taken immediately because
+ * of a parallel reader, control is transferred to the caller of the current
+ * coroutine.
+ */
+void qemu_co_rwlock_wrlock(CoRwlock *lock);
+
+/**
+ * Unlocks the read/write lock and schedules the next coroutine that was
+ * waiting for this lock to be run.
+ */
+void qemu_co_rwlock_unlock(CoRwlock *lock);
+
 #endif /* QEMU_COROUTINE_H */
commit b861b7419c49ad53e786062b4fbf6da53468f130
Author: Peter A. G. Crosthwaite <peter.crosthwaite at petalogix.com>
Date:   Mon Aug 22 18:15:25 2011 +1000

    xilinx: removed microbalze_pic_init from xilinx.h
    
    This is a microblaze target specific function that belongs outside
    of xilinx.h (which is a collection of target independent device model
    instantiator functions)
    
    Signed-off-by: Peter A. G. Crosthwaite <peter.crosthwaite at petalogix.com>
    Signed-off-by: Edgar E. Iglesias <edgar.iglesias at gmail.com>

diff --git a/hw/microblaze_pic_cpu.c b/hw/microblaze_pic_cpu.c
index 7c59382..9ad48b4 100644
--- a/hw/microblaze_pic_cpu.c
+++ b/hw/microblaze_pic_cpu.c
@@ -24,6 +24,7 @@
 
 #include "hw.h"
 #include "pc.h"
+#include "microblaze_pic_cpu.h"
 
 #define D(x)
 
@@ -43,7 +44,6 @@ static void microblaze_pic_cpu_handler(void *opaque, int irq, int level)
         cpu_reset_interrupt(env, type);
 }
 
-qemu_irq *microblaze_pic_init_cpu(CPUState *env);
 qemu_irq *microblaze_pic_init_cpu(CPUState *env)
 {
     return qemu_allocate_irqs(microblaze_pic_cpu_handler, env, 2);
diff --git a/hw/microblaze_pic_cpu.h b/hw/microblaze_pic_cpu.h
new file mode 100644
index 0000000..4c76275
--- /dev/null
+++ b/hw/microblaze_pic_cpu.h
@@ -0,0 +1,8 @@
+#ifndef MICROBLAZE_PIC_CPU_H
+#define MICROBLAZE_PIC_CPU_H
+
+#include "qemu-common.h"
+
+qemu_irq *microblaze_pic_init_cpu(CPUState *env);
+
+#endif /*  MICROBLAZE_PIC_CPU_H */
diff --git a/hw/petalogix_ml605_mmu.c b/hw/petalogix_ml605_mmu.c
index e3a66e5..e3ca310 100644
--- a/hw/petalogix_ml605_mmu.c
+++ b/hw/petalogix_ml605_mmu.c
@@ -39,6 +39,7 @@
 #include "blockdev.h"
 #include "pc.h"
 
+#include "microblaze_pic_cpu.h"
 #include "xilinx_axidma.h"
 
 #define LMB_BRAM_SIZE  (128 * 1024)
diff --git a/hw/petalogix_s3adsp1800_mmu.c b/hw/petalogix_s3adsp1800_mmu.c
index 589e8ca..a43fb4c 100644
--- a/hw/petalogix_s3adsp1800_mmu.c
+++ b/hw/petalogix_s3adsp1800_mmu.c
@@ -36,6 +36,8 @@
 #include "elf.h"
 #include "blockdev.h"
 
+#include "microblaze_pic_cpu.h"
+
 #define LMB_BRAM_SIZE  (128 * 1024)
 #define FLASH_SIZE     (16 * 1024 * 1024)
 
diff --git a/hw/xilinx.h b/hw/xilinx.h
index 3a1f4c6..35f35bd 100644
--- a/hw/xilinx.h
+++ b/hw/xilinx.h
@@ -1,9 +1,6 @@
 #include "qemu-common.h"
 #include "net.h"
 
-/* OPB Interrupt Controller.  */
-qemu_irq *microblaze_pic_init_cpu(CPUState *env);
-
 static inline DeviceState *
 xilinx_intc_create(target_phys_addr_t base, qemu_irq irq, int kind_of_intr)
 {
commit 0d877c66b6df4a0d90eec9fd225a5592bc96ab51
Author: Peter A. G. Crosthwaite <peter.crosthwaite at petalogix.com>
Date:   Mon Aug 22 18:15:24 2011 +1000

    xilinx.h: Added missing includes
    
    Added some missing #includes for this file. Previously this file
    relied on its clients to pre-include its dependencies.
    
    Signed-off-by: Peter A. G. Crosthwaite <peter.crosthwaite at petalogix.com>
    Signed-off-by: Edgar E. Iglesias <edgar.iglesias at gmail.com>

diff --git a/hw/xilinx.h b/hw/xilinx.h
index 090e6f7..3a1f4c6 100644
--- a/hw/xilinx.h
+++ b/hw/xilinx.h
@@ -1,3 +1,5 @@
+#include "qemu-common.h"
+#include "net.h"
 
 /* OPB Interrupt Controller.  */
 qemu_irq *microblaze_pic_init_cpu(CPUState *env);
commit f8b8d633f68ac97b7d3e5d6cecbbac96769f0cfb
Author: Jan Kiszka <jan.kiszka at siemens.com>
Date:   Mon Aug 22 18:42:42 2011 +0200

    sdl: Don't release input on mouse mode change in full-screen mode
    
    While in full-screen mode, the input focus naturally belongs to the SDL
    window. Avoid dropping it when switching from absolute to relative
    mouse mode.
    
    Signed-off-by: Jan Kiszka <jan.kiszka at siemens.com>
    Signed-off-by: Anthony Liguori <aliguori at us.ibm.com>

diff --git a/ui/sdl.c b/ui/sdl.c
index 385cc91..c7aaedf 100644
--- a/ui/sdl.c
+++ b/ui/sdl.c
@@ -491,7 +491,9 @@ static void sdl_mouse_mode_change(Notifier *notify, void *data)
             absolute_enabled = 1;
         }
     } else if (absolute_enabled) {
-        sdl_grab_end();
+        if (!gui_fullscreen) {
+            sdl_grab_end();
+        }
         absolute_enabled = 0;
     }
 }
commit fa7d1867578b6a1afc39d4ece8629a1e92baddd7
Author: Jan Kiszka <jan.kiszka at siemens.com>
Date:   Mon Aug 22 18:35:25 2011 +0200

    Replace qemu_system_cond with VCPU stop mechanism
    
    We can express the VCPU thread wakeup with the stop mechanism, saving
    both qemu_system_ready and the qemu_system_cond. For KVM threads, we can
    just enter the main loop as long as the thread is stopped. The central
    TCG thread is better held back before the loop as there can be side
    effects of the services called even when all CPUs are stopped.
    
    Creating VCPUs in stopped state will also be required for proper CPU
    hotplugging support.
    
    Signed-off-by: Jan Kiszka <jan.kiszka at siemens.com>
    Signed-off-by: Anthony Liguori <aliguori at us.ibm.com>

diff --git a/cpus.c b/cpus.c
index b60410c..b163efe 100644
--- a/cpus.c
+++ b/cpus.c
@@ -644,11 +644,9 @@ static QemuThread io_thread;
 static QemuThread *tcg_cpu_thread;
 static QemuCond *tcg_halt_cond;
 
-static int qemu_system_ready;
 /* cpu creation */
 static QemuCond qemu_cpu_cond;
 /* system init */
-static QemuCond qemu_system_cond;
 static QemuCond qemu_pause_cond;
 static QemuCond qemu_work_cond;
 
@@ -670,7 +668,6 @@ int qemu_init_main_loop(void)
     }
 
     qemu_cond_init(&qemu_cpu_cond);
-    qemu_cond_init(&qemu_system_cond);
     qemu_cond_init(&qemu_pause_cond);
     qemu_cond_init(&qemu_work_cond);
     qemu_cond_init(&qemu_io_proceeded_cond);
@@ -684,8 +681,7 @@ int qemu_init_main_loop(void)
 
 void qemu_main_loop_start(void)
 {
-    qemu_system_ready = 1;
-    qemu_cond_broadcast(&qemu_system_cond);
+    resume_all_vcpus();
 }
 
 void run_on_cpu(CPUState *env, void (*func)(void *data), void *data)
@@ -796,11 +792,6 @@ static void *qemu_kvm_cpu_thread_fn(void *arg)
     env->created = 1;
     qemu_cond_signal(&qemu_cpu_cond);
 
-    /* and wait for machine initialization */
-    while (!qemu_system_ready) {
-        qemu_cond_wait(&qemu_system_cond, &qemu_global_mutex);
-    }
-
     while (1) {
         if (cpu_can_run(env)) {
             r = kvm_cpu_exec(env);
@@ -829,9 +820,9 @@ static void *qemu_tcg_cpu_thread_fn(void *arg)
     }
     qemu_cond_signal(&qemu_cpu_cond);
 
-    /* and wait for machine initialization */
-    while (!qemu_system_ready) {
-        qemu_cond_wait(&qemu_system_cond, &qemu_global_mutex);
+    /* wait for initial kick-off after machine start */
+    while (first_cpu->stopped) {
+        qemu_cond_wait(tcg_halt_cond, &qemu_global_mutex);
     }
 
     while (1) {
@@ -971,12 +962,12 @@ static void qemu_tcg_init_vcpu(void *_env)
         env->thread = g_malloc0(sizeof(QemuThread));
         env->halt_cond = g_malloc0(sizeof(QemuCond));
         qemu_cond_init(env->halt_cond);
+        tcg_halt_cond = env->halt_cond;
         qemu_thread_create(env->thread, qemu_tcg_cpu_thread_fn, env);
         while (env->created == 0) {
             qemu_cond_wait(&qemu_cpu_cond, &qemu_global_mutex);
         }
         tcg_cpu_thread = env->thread;
-        tcg_halt_cond = env->halt_cond;
     } else {
         env->thread = tcg_cpu_thread;
         env->halt_cond = tcg_halt_cond;
@@ -1000,6 +991,7 @@ void qemu_init_vcpu(void *_env)
 
     env->nr_cores = smp_cores;
     env->nr_threads = smp_threads;
+    env->stopped = 1;
     if (kvm_enabled()) {
         qemu_kvm_start_vcpu(env);
     } else {
commit 78dd9ff6328eca1aa17fb1bc4d63f30b44ff0b6f
Author: Jan Kiszka <jan.kiszka at siemens.com>
Date:   Mon Aug 22 19:12:13 2011 +0200

    vga: Drop some unused fields
    
    Memory region refactorings obsoleted them.
    
    CC: Avi Kivity <avi at redhat.com>
    Signed-off-by: Jan Kiszka <jan.kiszka at siemens.com>
    Signed-off-by: Anthony Liguori <aliguori at us.ibm.com>

diff --git a/hw/vga_int.h b/hw/vga_int.h
index 28b9287..99287dd 100644
--- a/hw/vga_int.h
+++ b/hw/vga_int.h
@@ -110,7 +110,6 @@ typedef struct VGACommonState {
     MemoryRegion vram;
     uint32_t vram_size;
     uint32_t latch;
-    uint32_t lfb_vram_mapped; /* whether 0xa0000 is mapped as ram */
     MemoryRegion *chain4_alias;
     uint8_t sr_index;
     uint8_t sr[256];
@@ -133,7 +132,6 @@ typedef struct VGACommonState {
     int dac_8bit;
     uint8_t palette[768];
     int32_t bank_offset;
-    MemoryRegion *vga_io_memory;
     int (*get_bpp)(struct VGACommonState *s);
     void (*get_offsets)(struct VGACommonState *s,
                         uint32_t *pline_offset,
commit 80763888bfcb89dddb2f4eeece8ffc2ed91bde40
Author: Jan Kiszka <jan.kiszka at siemens.com>
Date:   Mon Aug 22 19:12:12 2011 +0200

    vga: Use linear mapping + dirty logging in chain 4 memory access mode
    
    Most VGA memory access modes require MMIO handling as they demand weird
    logic to get a byte from or into the video RAM. However, there is one
    exception: chain 4 mode with all memory planes enabled for writing. This
    mode actually allows lineary mapping, which can then be combined with
    dirty logging to accelerate KVM.
    
    This patch accelerates specifically VBE accesses like they are used by
    grub in graphical mode. Not only the standard VGA adapter benefits from
    this, also vmware and spice in VGA mode.
    
    CC: Gerd Hoffmann <kraxel at redhat.com>
    CC: Avi Kivity <avi at redhat.com>
    Signed-off-by: Jan Kiszka <jan.kiszka at siemens.com>
    Signed-off-by: Anthony Liguori <aliguori at us.ibm.com>

diff --git a/hw/vga.c b/hw/vga.c
index 432d2cb..851fd68 100644
--- a/hw/vga.c
+++ b/hw/vga.c
@@ -152,6 +152,48 @@ static void vga_screen_dump(void *opaque, const char *filename);
 static char *screen_dump_filename;
 static DisplayChangeListener *screen_dump_dcl;
 
+static void vga_update_memory_access(VGACommonState *s)
+{
+    MemoryRegion *region, *old_region = s->chain4_alias;
+    target_phys_addr_t base, offset, size;
+
+    s->chain4_alias = NULL;
+
+    if ((s->sr[0x02] & 0xf) == 0xf && s->sr[0x04] & 0x08) {
+        offset = 0;
+        switch ((s->gr[6] >> 2) & 3) {
+        case 0:
+            base = 0xa0000;
+            size = 0x20000;
+            break;
+        case 1:
+            base = 0xa0000;
+            size = 0x10000;
+            offset = s->bank_offset;
+            break;
+        case 2:
+            base = 0xb0000;
+            size = 0x8000;
+            break;
+        case 3:
+            base = 0xb8000;
+            size = 0x8000;
+            break;
+        }
+        region = g_malloc(sizeof(*region));
+        memory_region_init_alias(region, "vga.chain4", &s->vram, offset, size);
+        memory_region_add_subregion_overlap(s->legacy_address_space, base,
+                                            region, 2);
+        s->chain4_alias = region;
+    }
+    if (old_region) {
+        memory_region_del_subregion(s->legacy_address_space, old_region);
+        memory_region_destroy(old_region);
+        g_free(old_region);
+        s->plane_updated = 0xf;
+    }
+}
+
 static void vga_dumb_update_retrace_info(VGACommonState *s)
 {
     (void) s;
@@ -445,6 +487,7 @@ void vga_ioport_write(void *opaque, uint32_t addr, uint32_t val)
 #endif
         s->sr[s->sr_index] = val & sr_mask[s->sr_index];
         if (s->sr_index == 1) s->update_retrace_info(s);
+        vga_update_memory_access(s);
         break;
     case 0x3c7:
         s->dac_read_index = val;
@@ -472,6 +515,7 @@ void vga_ioport_write(void *opaque, uint32_t addr, uint32_t val)
         printf("vga: write GR%x = 0x%02x\n", s->gr_index, val);
 #endif
         s->gr[s->gr_index] = val & gr_mask[s->gr_index];
+        vga_update_memory_access(s);
         break;
     case 0x3b4:
     case 0x3d4:
@@ -605,6 +649,7 @@ static void vbe_ioport_write_data(void *opaque, uint32_t addr, uint32_t val)
             }
             s->vbe_regs[s->vbe_index] = val;
             s->bank_offset = (val << 16);
+            vga_update_memory_access(s);
             break;
         case VBE_DISPI_INDEX_ENABLE:
             if ((val & VBE_DISPI_ENABLED) &&
@@ -664,6 +709,7 @@ static void vbe_ioport_write_data(void *opaque, uint32_t addr, uint32_t val)
             }
             s->dac_8bit = (val & VBE_DISPI_8BIT_DAC) > 0;
             s->vbe_regs[s->vbe_index] = val;
+            vga_update_memory_access(s);
             break;
         case VBE_DISPI_INDEX_VIRT_WIDTH:
             {
@@ -1238,7 +1284,7 @@ static void vga_draw_text(VGACommonState *s, int full_update)
         s->font_offsets[1] = offset;
         full_update = 1;
     }
-    if (s->plane_updated & (1 << 2)) {
+    if (s->plane_updated & (1 << 2) || s->chain4_alias) {
         /* if the plane 2 was modified since the last display, it
            indicates the font may have been modified */
         s->plane_updated = 0;
@@ -1885,6 +1931,7 @@ void vga_common_reset(VGACommonState *s)
         memset(&s->retrace_info, 0, sizeof (s->retrace_info));
         break;
     }
+    vga_update_memory_access(s);
 }
 
 static void vga_reset(void *opaque)
@@ -2242,6 +2289,8 @@ void vga_init(VGACommonState *s, MemoryRegion *address_space)
 
     s->bank_offset = 0;
 
+    s->legacy_address_space = address_space;
+
     vga_io_memory = vga_init_io(s);
     memory_region_add_subregion_overlap(address_space,
                                         isa_mem_base + 0x000a0000,
diff --git a/hw/vga_int.h b/hw/vga_int.h
index d2dd7dd..28b9287 100644
--- a/hw/vga_int.h
+++ b/hw/vga_int.h
@@ -105,11 +105,13 @@ typedef uint8_t (* vga_retrace_fn)(struct VGACommonState *s);
 typedef void (* vga_update_retrace_info_fn)(struct VGACommonState *s);
 
 typedef struct VGACommonState {
+    MemoryRegion *legacy_address_space;
     uint8_t *vram_ptr;
     MemoryRegion vram;
     uint32_t vram_size;
     uint32_t latch;
     uint32_t lfb_vram_mapped; /* whether 0xa0000 is mapped as ram */
+    MemoryRegion *chain4_alias;
     uint8_t sr_index;
     uint8_t sr[256];
     uint8_t gr_index;
commit fe55ff6e6114c7382a68a2cf7230f125d4f3a248
Author: Jan Kiszka <jan.kiszka at siemens.com>
Date:   Mon Aug 22 19:12:11 2011 +0200

    vmware-vga: Eliminate vga_dirty_log_restart
    
    After the conversion to the new Memory API, vga_dirty_log_restart became
    seriously pointless. Remove it from vmware-vga and and then finally drop
    the service.
    
    CC: Andrzej Zaborowski <balrogg at gmail.com>
    CC: Avi Kivity <avi at redhat.com>
    Signed-off-by: Jan Kiszka <jan.kiszka at siemens.com>
    Signed-off-by: Anthony Liguori <aliguori at us.ibm.com>

diff --git a/hw/vga.c b/hw/vga.c
index b0371d5..432d2cb 100644
--- a/hw/vga.c
+++ b/hw/vga.c
@@ -1532,12 +1532,6 @@ void vga_dirty_log_stop(VGACommonState *s)
     memory_region_set_log(&s->vram, false, DIRTY_MEMORY_VGA);
 }
 
-void vga_dirty_log_restart(VGACommonState *s)
-{
-    vga_dirty_log_stop(s);
-    vga_dirty_log_start(s);
-}
-
 /*
  * graphic modes
  */
diff --git a/hw/vga_int.h b/hw/vga_int.h
index 7e4ed71..d2dd7dd 100644
--- a/hw/vga_int.h
+++ b/hw/vga_int.h
@@ -193,7 +193,6 @@ void vga_common_reset(VGACommonState *s);
 
 void vga_dirty_log_start(VGACommonState *s);
 void vga_dirty_log_stop(VGACommonState *s);
-void vga_dirty_log_restart(VGACommonState *s);
 
 extern const VMStateDescription vmstate_vga_common;
 uint32_t vga_ioport_read(void *opaque, uint32_t addr);
diff --git a/hw/vmware_vga.c b/hw/vmware_vga.c
index 95c9897..52d2d26 100644
--- a/hw/vmware_vga.c
+++ b/hw/vmware_vga.c
@@ -1175,8 +1175,6 @@ static int pci_vmsvga_initfn(PCIDevice *dev)
 
     iomem = &s->chip.vga.vram;
 
-    vga_dirty_log_restart(&s->chip.vga);
-
     s->card.config[PCI_CACHE_LINE_SIZE]	= 0x08;		/* Cache line size */
     s->card.config[PCI_LATENCY_TIMER] = 0x40;		/* Latency timer */
     s->card.config[PCI_INTERRUPT_LINE] = 0xff;		/* End */
commit 8d121d49604a42ea5c5b1268c6e45d1699e9e6f6
Author: Jan Kiszka <jan.kiszka at siemens.com>
Date:   Mon Aug 22 19:12:10 2011 +0200

    vmware-vga: Remove dead DIRECT_VRAM mode
    
    The code was disabled since day 1 of vmware-vga, and now it does not
    even build anymore. Time for a cleanup.
    
    CC: Andrzej Zaborowski <balrogg at gmail.com>
    Signed-off-by: Jan Kiszka <jan.kiszka at siemens.com>
    Signed-off-by: Anthony Liguori <aliguori at us.ibm.com>

diff --git a/hw/vmware_vga.c b/hw/vmware_vga.c
index 8c63e48..95c9897 100644
--- a/hw/vmware_vga.c
+++ b/hw/vmware_vga.c
@@ -28,7 +28,6 @@
 #include "vmware_vga.h"
 
 #undef VERBOSE
-#undef DIRECT_VRAM
 #define HW_RECT_ACCEL
 #define HW_FILL_ACCEL
 #define HW_MOUSE_ACCEL
@@ -292,7 +291,6 @@ enum {
 static inline void vmsvga_update_rect(struct vmsvga_state_s *s,
                 int x, int y, int w, int h)
 {
-#ifndef DIRECT_VRAM
     int line;
     int bypl;
     int width;
@@ -323,23 +321,17 @@ static inline void vmsvga_update_rect(struct vmsvga_state_s *s,
 
     for (; line > 0; line --, src += bypl, dst += bypl)
         memcpy(dst, src, width);
-#endif
 
     dpy_update(s->vga.ds, x, y, w, h);
 }
 
 static inline void vmsvga_update_screen(struct vmsvga_state_s *s)
 {
-#ifndef DIRECT_VRAM
-    memcpy(ds_get_data(s->vga.ds), s->vga.vram_ptr, s->bypp * s->width * s->height);
-#endif
-
+    memcpy(ds_get_data(s->vga.ds), s->vga.vram_ptr,
+           s->bypp * s->width * s->height);
     dpy_update(s->vga.ds, 0, 0, s->width, s->height);
 }
 
-#ifdef DIRECT_VRAM
-# define vmsvga_update_rect_delayed	vmsvga_update_rect
-#else
 static inline void vmsvga_update_rect_delayed(struct vmsvga_state_s *s,
                 int x, int y, int w, int h)
 {
@@ -350,7 +342,6 @@ static inline void vmsvga_update_rect_delayed(struct vmsvga_state_s *s,
     rect->w = w;
     rect->h = h;
 }
-#endif
 
 static inline void vmsvga_update_rect_flush(struct vmsvga_state_s *s)
 {
@@ -372,32 +363,23 @@ static inline void vmsvga_update_rect_flush(struct vmsvga_state_s *s)
 static inline void vmsvga_copy_rect(struct vmsvga_state_s *s,
                 int x0, int y0, int x1, int y1, int w, int h)
 {
-# ifdef DIRECT_VRAM
-    uint8_t *vram = ds_get_data(s->ds);
-# else
     uint8_t *vram = s->vga.vram_ptr;
-# endif
     int bypl = s->bypp * s->width;
     int width = s->bypp * w;
     int line = h;
     uint8_t *ptr[2];
 
-# ifdef DIRECT_VRAM
-    if (s->ds->dpy_copy)
-        qemu_console_copy(s->ds, x0, y0, x1, y1, w, h);
-    else
-# endif
-    {
-        if (y1 > y0) {
-            ptr[0] = vram + s->bypp * x0 + bypl * (y0 + h - 1);
-            ptr[1] = vram + s->bypp * x1 + bypl * (y1 + h - 1);
-            for (; line > 0; line --, ptr[0] -= bypl, ptr[1] -= bypl)
-                memmove(ptr[1], ptr[0], width);
-        } else {
-            ptr[0] = vram + s->bypp * x0 + bypl * y0;
-            ptr[1] = vram + s->bypp * x1 + bypl * y1;
-            for (; line > 0; line --, ptr[0] += bypl, ptr[1] += bypl)
-                memmove(ptr[1], ptr[0], width);
+    if (y1 > y0) {
+        ptr[0] = vram + s->bypp * x0 + bypl * (y0 + h - 1);
+        ptr[1] = vram + s->bypp * x1 + bypl * (y1 + h - 1);
+        for (; line > 0; line --, ptr[0] -= bypl, ptr[1] -= bypl) {
+            memmove(ptr[1], ptr[0], width);
+        }
+    } else {
+        ptr[0] = vram + s->bypp * x0 + bypl * y0;
+        ptr[1] = vram + s->bypp * x1 + bypl * y1;
+        for (; line > 0; line --, ptr[0] += bypl, ptr[1] += bypl) {
+            memmove(ptr[1], ptr[0], width);
         }
     }
 
@@ -409,11 +391,7 @@ static inline void vmsvga_copy_rect(struct vmsvga_state_s *s,
 static inline void vmsvga_fill_rect(struct vmsvga_state_s *s,
                 uint32_t c, int x, int y, int w, int h)
 {
-# ifdef DIRECT_VRAM
-    uint8_t *vram = ds_get_data(s->ds);
-# else
     uint8_t *vram = s->vga.vram_ptr;
-# endif
     int bypp = s->bypp;
     int bypl = bypp * s->width;
     int width = bypp * w;
@@ -424,31 +402,25 @@ static inline void vmsvga_fill_rect(struct vmsvga_state_s *s,
     uint8_t *src;
     uint8_t col[4];
 
-# ifdef DIRECT_VRAM
-    if (s->ds->dpy_fill)
-        s->ds->dpy_fill(s->ds, x, y, w, h, c);
-    else
-# endif
-    {
-        col[0] = c;
-        col[1] = c >> 8;
-        col[2] = c >> 16;
-        col[3] = c >> 24;
-
-        if (line --) {
-            dst = fst;
-            src = col;
-            for (column = width; column > 0; column --) {
-                *(dst ++) = *(src ++);
-                if (src - col == bypp)
-                    src = col;
-            }
-            dst = fst;
-            for (; line > 0; line --) {
-                dst += bypl;
-                memcpy(dst, fst, width);
+    col[0] = c;
+    col[1] = c >> 8;
+    col[2] = c >> 16;
+    col[3] = c >> 24;
+
+    if (line--) {
+        dst = fst;
+        src = col;
+        for (column = width; column > 0; column--) {
+            *(dst++) = *(src++);
+            if (src - col == bypp) {
+                src = col;
             }
         }
+        dst = fst;
+        for (; line > 0; line--) {
+            dst += bypl;
+            memcpy(dst, fst, width);
+        }
     }
 
     vmsvga_update_rect_delayed(s, x, y, w, h);
@@ -1055,82 +1027,6 @@ static void vmsvga_text_update(void *opaque, console_ch_t *chardata)
         s->vga.text_update(&s->vga, chardata);
 }
 
-#ifdef DIRECT_VRAM
-static uint32_t vmsvga_vram_readb(void *opaque, target_phys_addr_t addr)
-{
-    struct vmsvga_state_s *s = opaque;
-    if (addr < s->fb_size)
-        return *(uint8_t *) (ds_get_data(s->ds) + addr);
-    else
-        return *(uint8_t *) (s->vram_ptr + addr);
-}
-
-static uint32_t vmsvga_vram_readw(void *opaque, target_phys_addr_t addr)
-{
-    struct vmsvga_state_s *s = opaque;
-    if (addr < s->fb_size)
-        return *(uint16_t *) (ds_get_data(s->ds) + addr);
-    else
-        return *(uint16_t *) (s->vram_ptr + addr);
-}
-
-static uint32_t vmsvga_vram_readl(void *opaque, target_phys_addr_t addr)
-{
-    struct vmsvga_state_s *s = opaque;
-    if (addr < s->fb_size)
-        return *(uint32_t *) (ds_get_data(s->ds) + addr);
-    else
-        return *(uint32_t *) (s->vram_ptr + addr);
-}
-
-static void vmsvga_vram_writeb(void *opaque, target_phys_addr_t addr,
-                uint32_t value)
-{
-    struct vmsvga_state_s *s = opaque;
-    if (addr < s->fb_size)
-        *(uint8_t *) (ds_get_data(s->ds) + addr) = value;
-    else
-        *(uint8_t *) (s->vram_ptr + addr) = value;
-}
-
-static void vmsvga_vram_writew(void *opaque, target_phys_addr_t addr,
-                uint32_t value)
-{
-    struct vmsvga_state_s *s = opaque;
-    if (addr < s->fb_size)
-        *(uint16_t *) (ds_get_data(s->ds) + addr) = value;
-    else
-        *(uint16_t *) (s->vram_ptr + addr) = value;
-}
-
-static void vmsvga_vram_writel(void *opaque, target_phys_addr_t addr,
-                uint32_t value)
-{
-    struct vmsvga_state_s *s = opaque;
-    if (addr < s->fb_size)
-        *(uint32_t *) (ds_get_data(s->ds) + addr) = value;
-    else
-        *(uint32_t *) (s->vram_ptr + addr) = value;
-}
-
-static const MemoryRegionOps vmsvga_vram_io_ops = {
-    .old_mmio = {
-        .read = {
-            vmsvga_vram_readb,
-            vmsvga_vram_readw,
-            vmsvga_vram_readl,
-        },
-        .write = {
-            vmsvga_vram_writeb,
-            vmsvga_vram_writew,
-            vmsvga_vram_writel,
-        },
-    },
-    .endianness = DEVICE_NATIVE_ENDIAN,
-}
-
-#endif
-
 static int vmsvga_post_load(void *opaque, int version_id)
 {
     struct vmsvga_state_s *s = opaque;
@@ -1277,15 +1173,7 @@ static int pci_vmsvga_initfn(PCIDevice *dev)
         DO_UPCAST(struct pci_vmsvga_state_s, card, dev);
     MemoryRegion *iomem;
 
-#ifdef DIRECT_VRAM
-    DirectMem *directmem = g_malloc(sizeof(*directmem));
-
-    iomem = &directmem->mr;
-    memory_region_init_io(iomem, &vmsvga_vram_io_ops, &s->chip, "vmsvga",
-                          memory_region_size(&s->chip.vga.vram));
-#else
     iomem = &s->chip.vga.vram;
-#endif
 
     vga_dirty_log_restart(&s->chip.vga);
 
commit ca0508df2e3efec0c2aa8c23972f778329a993a1
Author: Jan Kiszka <jan.kiszka at siemens.com>
Date:   Mon Aug 22 19:12:09 2011 +0200

    vmware-vga: Disable verbose mode
    
    Elimiates 'vmsvga_value_write: guest runs Linux.' messages from the
    console.
    
    CC: Andrzej Zaborowski <balrogg at gmail.com>
    Signed-off-by: Jan Kiszka <jan.kiszka at siemens.com>
    Signed-off-by: Anthony Liguori <aliguori at us.ibm.com>

diff --git a/hw/vmware_vga.c b/hw/vmware_vga.c
index 4fac38b..8c63e48 100644
--- a/hw/vmware_vga.c
+++ b/hw/vmware_vga.c
@@ -27,7 +27,7 @@
 #include "pci.h"
 #include "vmware_vga.h"
 
-#define VERBOSE
+#undef VERBOSE
 #undef DIRECT_VRAM
 #define HW_RECT_ACCEL
 #define HW_FILL_ACCEL
commit 8a9501bae2aa87d422b13a8087416d8e24ca94aa
Author: Jan Kiszka <jan.kiszka at siemens.com>
Date:   Mon Aug 22 19:12:08 2011 +0200

    vmware-vga: Register reset service
    
    Fixes cold reset in vmware graphic modes. We need to split up the reset
    function for this purpose, breaking out init-once bits.
    
    Cc: Andrzej Zaborowski <balrogg at gmail.com>
    Signed-off-by: Jan Kiszka <jan.kiszka at siemens.com>
    Signed-off-by: Anthony Liguori <aliguori at us.ibm.com>

diff --git a/hw/vmware_vga.c b/hw/vmware_vga.c
index 5396a6c..4fac38b 100644
--- a/hw/vmware_vga.c
+++ b/hw/vmware_vga.c
@@ -998,46 +998,21 @@ static void vmsvga_update_display(void *opaque)
     }
 }
 
-static void vmsvga_reset(struct vmsvga_state_s *s)
+static void vmsvga_reset(DeviceState *dev)
 {
+    struct pci_vmsvga_state_s *pci =
+        DO_UPCAST(struct pci_vmsvga_state_s, card.qdev, dev);
+    struct vmsvga_state_s *s = &pci->chip;
+
     s->index = 0;
     s->enable = 0;
     s->config = 0;
     s->width = -1;
     s->height = -1;
     s->svgaid = SVGA_ID;
-    s->depth = ds_get_bits_per_pixel(s->vga.ds);
-    s->bypp = ds_get_bytes_per_pixel(s->vga.ds);
     s->cursor.on = 0;
     s->redraw_fifo_first = 0;
     s->redraw_fifo_last = 0;
-    switch (s->depth) {
-    case 8:
-        s->wred   = 0x00000007;
-        s->wgreen = 0x00000038;
-        s->wblue  = 0x000000c0;
-        break;
-    case 15:
-        s->wred   = 0x0000001f;
-        s->wgreen = 0x000003e0;
-        s->wblue  = 0x00007c00;
-        break;
-    case 16:
-        s->wred   = 0x0000001f;
-        s->wgreen = 0x000007e0;
-        s->wblue  = 0x0000f800;
-        break;
-    case 24:
-        s->wred   = 0x00ff0000;
-        s->wgreen = 0x0000ff00;
-        s->wblue  = 0x000000ff;
-        break;
-    case 32:
-        s->wred   = 0x00ff0000;
-        s->wgreen = 0x0000ff00;
-        s->wblue  = 0x000000ff;
-        break;
-    }
     s->syncing = 0;
 
     vga_dirty_log_start(&s->vga);
@@ -1227,7 +1202,35 @@ static void vmsvga_init(struct vmsvga_state_s *s, int vga_ram_size,
     vga_init(&s->vga, address_space);
     vmstate_register(NULL, 0, &vmstate_vga_common, &s->vga);
 
-    vmsvga_reset(s);
+    s->depth = ds_get_bits_per_pixel(s->vga.ds);
+    s->bypp = ds_get_bytes_per_pixel(s->vga.ds);
+    switch (s->depth) {
+    case 8:
+        s->wred   = 0x00000007;
+        s->wgreen = 0x00000038;
+        s->wblue  = 0x000000c0;
+        break;
+    case 15:
+        s->wred   = 0x0000001f;
+        s->wgreen = 0x000003e0;
+        s->wblue  = 0x00007c00;
+        break;
+    case 16:
+        s->wred   = 0x0000001f;
+        s->wgreen = 0x000007e0;
+        s->wblue  = 0x0000f800;
+        break;
+    case 24:
+        s->wred   = 0x00ff0000;
+        s->wgreen = 0x0000ff00;
+        s->wblue  = 0x000000ff;
+        break;
+    case 32:
+        s->wred   = 0x00ff0000;
+        s->wgreen = 0x0000ff00;
+        s->wblue  = 0x000000ff;
+        break;
+    }
 }
 
 static uint64_t vmsvga_io_read(void *opaque, target_phys_addr_t addr,
@@ -1312,6 +1315,7 @@ static PCIDeviceInfo vmsvga_info = {
     .qdev.name    = "vmware-svga",
     .qdev.size    = sizeof(struct pci_vmsvga_state_s),
     .qdev.vmsd    = &vmstate_vmware_vga,
+    .qdev.reset   = vmsvga_reset,
     .no_hotplug   = 1,
     .init         = pci_vmsvga_initfn,
     .romfile      = "vgabios-vmware.bin",
commit 0035e5094c9e01c8227db2ddc0c607e3f6bc33b7
Author: Jan Kiszka <jan.kiszka at siemens.com>
Date:   Mon Aug 22 17:46:42 2011 +0200

    ioapic: Implement polarity
    
    If the polarity bit is set in the redirection table, the input level
    simply has to inverted as it is low active in this case.
    
    Signed-off-by: Jan Kiszka <jan.kiszka at siemens.com>
    Signed-off-by: Anthony Liguori <aliguori at us.ibm.com>

diff --git a/hw/ioapic.c b/hw/ioapic.c
index 5916387..61991d7 100644
--- a/hw/ioapic.c
+++ b/hw/ioapic.c
@@ -148,6 +148,9 @@ static void ioapic_set_irq(void *opaque, int vector, int level)
         uint32_t mask = 1 << vector;
         uint64_t entry = s->ioredtbl[vector];
 
+        if (entry & (1 << IOAPIC_LVT_POLARITY_SHIFT)) {
+            level = !level;
+        }
         if (((entry >> IOAPIC_LVT_TRIGGER_MODE_SHIFT) & 1) ==
             IOAPIC_TRIGGER_LEVEL) {
             /* level triggered */
commit 1f6f408c8c38b83b9e3e4577b680dfd686ffe37a
Author: Jan Kiszka <jan.kiszka at siemens.com>
Date:   Mon Aug 22 17:46:31 2011 +0200

    target-i386: Remove unused polarity arguments from APIC API
    
    Polarity of external interrupts needs to be handled in the IOAPIC.
    Passing it to the APIC is pointless. So remove all these arguments.
    
    Signed-off-by: Jan Kiszka <jan.kiszka at siemens.com>
    Signed-off-by: Anthony Liguori <aliguori at us.ibm.com>

diff --git a/hw/apic.c b/hw/apic.c
index 7d0b0f6..d8f56c8 100644
--- a/hw/apic.c
+++ b/hw/apic.c
@@ -223,8 +223,7 @@ void apic_deliver_pic_intr(DeviceState *d, int level)
 }
 
 static void apic_bus_deliver(const uint32_t *deliver_bitmask,
-                             uint8_t delivery_mode,
-                             uint8_t vector_num, uint8_t polarity,
+                             uint8_t delivery_mode, uint8_t vector_num,
                              uint8_t trigger_mode)
 {
     APICState *apic_iter;
@@ -281,18 +280,16 @@ static void apic_bus_deliver(const uint32_t *deliver_bitmask,
                  apic_set_irq(apic_iter, vector_num, trigger_mode) );
 }
 
-void apic_deliver_irq(uint8_t dest, uint8_t dest_mode,
-                      uint8_t delivery_mode, uint8_t vector_num,
-                      uint8_t polarity, uint8_t trigger_mode)
+void apic_deliver_irq(uint8_t dest, uint8_t dest_mode, uint8_t delivery_mode,
+                      uint8_t vector_num, uint8_t trigger_mode)
 {
     uint32_t deliver_bitmask[MAX_APIC_WORDS];
 
     trace_apic_deliver_irq(dest, dest_mode, delivery_mode, vector_num,
-                           polarity, trigger_mode);
+                           trigger_mode);
 
     apic_get_delivery_bitmask(deliver_bitmask, dest, dest_mode);
-    apic_bus_deliver(deliver_bitmask, delivery_mode, vector_num, polarity,
-                     trigger_mode);
+    apic_bus_deliver(deliver_bitmask, delivery_mode, vector_num, trigger_mode);
 }
 
 void cpu_set_apic_base(DeviceState *d, uint64_t val)
@@ -549,7 +546,7 @@ void apic_sipi(DeviceState *d)
 
 static void apic_deliver(DeviceState *d, uint8_t dest, uint8_t dest_mode,
                          uint8_t delivery_mode, uint8_t vector_num,
-                         uint8_t polarity, uint8_t trigger_mode)
+                         uint8_t trigger_mode)
 {
     APICState *s = DO_UPCAST(APICState, busdev.qdev, d);
     uint32_t deliver_bitmask[MAX_APIC_WORDS];
@@ -592,8 +589,7 @@ static void apic_deliver(DeviceState *d, uint8_t dest, uint8_t dest_mode,
             return;
     }
 
-    apic_bus_deliver(deliver_bitmask, delivery_mode, vector_num, polarity,
-                     trigger_mode);
+    apic_bus_deliver(deliver_bitmask, delivery_mode, vector_num, trigger_mode);
 }
 
 int apic_get_interrupt(DeviceState *d)
@@ -795,7 +791,7 @@ static void apic_send_msi(target_phys_addr_t addr, uint32_t data)
     uint8_t trigger_mode = (data >> MSI_DATA_TRIGGER_SHIFT) & 0x1;
     uint8_t delivery = (data >> MSI_DATA_DELIVERY_MODE_SHIFT) & 0x7;
     /* XXX: Ignore redirection hint. */
-    apic_deliver_irq(dest, dest_mode, delivery, vector, 0, trigger_mode);
+    apic_deliver_irq(dest, dest_mode, delivery, vector, trigger_mode);
 }
 
 static void apic_mem_writel(void *opaque, target_phys_addr_t addr, uint32_t val)
@@ -856,7 +852,7 @@ static void apic_mem_writel(void *opaque, target_phys_addr_t addr, uint32_t val)
         s->icr[0] = val;
         apic_deliver(d, (s->icr[1] >> 24) & 0xff, (s->icr[0] >> 11) & 1,
                      (s->icr[0] >> 8) & 7, (s->icr[0] & 0xff),
-                     (s->icr[0] >> 14) & 1, (s->icr[0] >> 15) & 1);
+                     (s->icr[0] >> 15) & 1);
         break;
     case 0x31:
         s->icr[1] = val;
diff --git a/hw/apic.h b/hw/apic.h
index 8a0c9d0..a5c910f 100644
--- a/hw/apic.h
+++ b/hw/apic.h
@@ -4,10 +4,8 @@
 #include "qemu-common.h"
 
 /* apic.c */
-void apic_deliver_irq(uint8_t dest, uint8_t dest_mode,
-                             uint8_t delivery_mode,
-                             uint8_t vector_num, uint8_t polarity,
-                             uint8_t trigger_mode);
+void apic_deliver_irq(uint8_t dest, uint8_t dest_mode, uint8_t delivery_mode,
+                      uint8_t vector_num, uint8_t trigger_mode);
 int apic_accept_pic_intr(DeviceState *s);
 void apic_deliver_pic_intr(DeviceState *s, int level);
 int apic_get_interrupt(DeviceState *s);
diff --git a/hw/ioapic.c b/hw/ioapic.c
index 6c26e82..5916387 100644
--- a/hw/ioapic.c
+++ b/hw/ioapic.c
@@ -104,7 +104,6 @@ static void ioapic_service(IOAPICState *s)
     uint64_t entry;
     uint8_t dest;
     uint8_t dest_mode;
-    uint8_t polarity;
 
     for (i = 0; i < IOAPIC_NUM_PINS; i++) {
         mask = 1 << i;
@@ -116,7 +115,6 @@ static void ioapic_service(IOAPICState *s)
                 dest_mode = (entry >> IOAPIC_LVT_DEST_MODE_SHIFT) & 1;
                 delivery_mode =
                     (entry >> IOAPIC_LVT_DELIV_MODE_SHIFT) & IOAPIC_DM_MASK;
-                polarity = (entry >> IOAPIC_LVT_POLARITY_SHIFT) & 1;
                 if (trig_mode == IOAPIC_TRIGGER_EDGE) {
                     s->irr &= ~mask;
                 } else {
@@ -128,7 +126,7 @@ static void ioapic_service(IOAPICState *s)
                     vector = entry & IOAPIC_VECTOR_MASK;
                 }
                 apic_deliver_irq(dest, dest_mode, delivery_mode,
-                                 vector, polarity, trig_mode);
+                                 vector, trig_mode);
             }
         }
     }
diff --git a/trace-events b/trace-events
index 14e6f8b..dc300a2 100644
--- a/trace-events
+++ b/trace-events
@@ -90,7 +90,7 @@ disable balloon_event(void *opaque, unsigned long addr) "opaque %p addr %lu"
 
 # hw/apic.c
 disable apic_local_deliver(int vector, uint32_t lvt) "vector %d delivery mode %d"
-disable apic_deliver_irq(uint8_t dest, uint8_t dest_mode, uint8_t delivery_mode, uint8_t vector_num, uint8_t polarity, uint8_t trigger_mode) "dest %d dest_mode %d delivery_mode %d vector %d polarity %d trigger_mode %d"
+disable apic_deliver_irq(uint8_t dest, uint8_t dest_mode, uint8_t delivery_mode, uint8_t vector_num, uint8_t trigger_mode) "dest %d dest_mode %d delivery_mode %d vector %d trigger_mode %d"
 disable cpu_set_apic_base(uint64_t val) "%016"PRIx64""
 disable cpu_get_apic_base(uint64_t val) "%016"PRIx64""
 disable apic_mem_readl(uint64_t addr, uint32_t val)  "%"PRIx64" = %08x"
commit eae74cf906942999bf70e94f034f95c7f831ec63
Author: Jan Kiszka <jan.kiszka at siemens.com>
Date:   Mon Aug 22 17:46:03 2011 +0200

    Do not kick vcpus in TCG mode
    
    In TCG mode, iothread and vcpus run in lock-step. So it's pointless to
    send a signal from qemu_cpu_kick to the vcpu thread - if we got here,
    the receiver already left the vcpu loop.
    
    Signed-off-by: Jan Kiszka <jan.kiszka at siemens.com>
    Signed-off-by: Anthony Liguori <aliguori at us.ibm.com>

diff --git a/cpus.c b/cpus.c
index c996ac5..b60410c 100644
--- a/cpus.c
+++ b/cpus.c
@@ -869,7 +869,7 @@ void qemu_cpu_kick(void *_env)
     CPUState *env = _env;
 
     qemu_cond_broadcast(env->halt_cond);
-    if (!env->thread_kicked) {
+    if (kvm_enabled() && !env->thread_kicked) {
         qemu_cpu_kick_thread(env);
         env->thread_kicked = true;
     }
commit c9f711a5d31e22dac932c1c01e9c0f97caff0988
Author: Jan Kiszka <jan.kiszka at siemens.com>
Date:   Mon Aug 22 17:46:02 2011 +0200

    Poll main loop after I/O events were received
    
    Polling until select returns empty fdsets helps to reduce the switches
    between iothread and vcpus. The benefit of this patch is best visible
    when running an SMP guest on an SMP host in emulation mode.
    
    Signed-off-by: Jan Kiszka <jan.kiszka at siemens.com>
    Signed-off-by: Anthony Liguori <aliguori at us.ibm.com>

diff --git a/sysemu.h b/sysemu.h
index bd830e5..9090457 100644
--- a/sysemu.h
+++ b/sysemu.h
@@ -67,7 +67,7 @@ void do_info_snapshots(Monitor *mon);
 
 void qemu_announce_self(void);
 
-void main_loop_wait(int nonblocking);
+int main_loop_wait(int nonblocking);
 
 bool qemu_savevm_state_blocked(Monitor *mon);
 int qemu_savevm_state_begin(Monitor *mon, QEMUFile *f, int blk_enable,
diff --git a/vl.c b/vl.c
index c52937a..9cd67a3 100644
--- a/vl.c
+++ b/vl.c
@@ -1321,7 +1321,7 @@ void qemu_system_vmstop_request(int reason)
     qemu_notify_event();
 }
 
-void main_loop_wait(int nonblocking)
+int main_loop_wait(int nonblocking)
 {
     fd_set rfds, wfds, xfds;
     int ret, nfds;
@@ -1368,6 +1368,7 @@ void main_loop_wait(int nonblocking)
        them.  */
     qemu_bh_poll();
 
+    return ret;
 }
 
 #ifndef CONFIG_IOTHREAD
@@ -1385,7 +1386,8 @@ qemu_irq qemu_system_powerdown;
 
 static void main_loop(void)
 {
-    bool nonblocking = false;
+    bool nonblocking;
+    int last_io __attribute__ ((unused)) = 0;
 #ifdef CONFIG_PROFILER
     int64_t ti;
 #endif
@@ -1394,7 +1396,9 @@ static void main_loop(void)
     qemu_main_loop_start();
 
     for (;;) {
-#ifndef CONFIG_IOTHREAD
+#ifdef CONFIG_IOTHREAD
+        nonblocking = !kvm_enabled() && last_io > 0;
+#else
         nonblocking = cpu_exec_all();
         if (vm_request_pending()) {
             nonblocking = true;
@@ -1403,7 +1407,7 @@ static void main_loop(void)
 #ifdef CONFIG_PROFILER
         ti = profile_getclock();
 #endif
-        main_loop_wait(nonblocking);
+        last_io = main_loop_wait(nonblocking);
 #ifdef CONFIG_PROFILER
         dev_time += profile_getclock() - ti;
 #endif
commit 200668ba0839e664f0e4d0bcdc55ab5a163a418a
Author: Jan Kiszka <jan.kiszka at siemens.com>
Date:   Mon Aug 22 17:46:01 2011 +0200

    Do not drop global mutex for polled main loop runs
    
    If we call select without a timeout, it's more efficient to keep the
    global mutex locked as we may otherwise just play ping pong with a
    vcpu thread contending for it. This is particularly important for TCG
    mode where we run in lock-step with the vcpu thread.
    
    Signed-off-by: Jan Kiszka <jan.kiszka at siemens.com>
    Signed-off-by: Anthony Liguori <aliguori at us.ibm.com>

diff --git a/vl.c b/vl.c
index 5f1a177..c52937a 100644
--- a/vl.c
+++ b/vl.c
@@ -1349,9 +1349,15 @@ void main_loop_wait(int nonblocking)
     qemu_iohandler_fill(&nfds, &rfds, &wfds, &xfds);
     slirp_select_fill(&nfds, &rfds, &wfds, &xfds);
 
-    qemu_mutex_unlock_iothread();
+    if (timeout > 0) {
+        qemu_mutex_unlock_iothread();
+    }
+
     ret = select(nfds + 1, &rfds, &wfds, &xfds, &tv);
-    qemu_mutex_lock_iothread();
+
+    if (timeout > 0) {
+        qemu_mutex_lock_iothread();
+    }
 
     qemu_iohandler_poll(&rfds, &wfds, &xfds, ret);
     slirp_select_poll(&rfds, &wfds, &xfds, (ret < 0));
commit 6e23063c469c0d90d14b376a696d87149e2a1aa4
Merge: 22a78d6... 563ea48...
Author: Anthony Liguori <aliguori at us.ibm.com>
Date:   Mon Aug 22 12:26:30 2011 -0500

    Merge remote-tracking branch 'qemu-kvm/memory/core' into staging

commit 22a78d64cca77916e0b56f63b493ff5e445c41b9
Author: Edgar E. Iglesias <edgar.iglesias at gmail.com>
Date:   Mon Aug 22 18:42:54 2011 +0200

    microblaze-user: Deliver SIGFPE on div by zero
    
    Signed-off-by: Edgar E. Iglesias <edgar.iglesias at gmail.com>

diff --git a/linux-user/main.c b/linux-user/main.c
index 95e3fe6..89a51d7 100644
--- a/linux-user/main.c
+++ b/linux-user/main.c
@@ -2339,6 +2339,13 @@ void cpu_loop (CPUState *env)
             env->iflags &= ~(IMM_FLAG | D_FLAG);
 
             switch (env->sregs[SR_ESR] & 31) {
+                case ESR_EC_DIVZERO:
+                    info.si_signo = SIGFPE;
+                    info.si_errno = 0;
+                    info.si_code = TARGET_FPE_FLTDIV;
+                    info._sifields._sigfault._addr = 0;
+                    queue_signal(env, info.si_signo, &info);
+                    break;
                 case ESR_EC_FPU:
                     info.si_signo = SIGFPE;
                     info.si_errno = 0;
commit 563ea489031375c53d3b94d74c56c42238e94914
Author: Richard Henderson <rth at twiddle.net>
Date:   Wed Aug 10 15:28:19 2011 -0700

    memory: Fix old_portio vs non-zero offset
    
    The legacy functions that we're wrapping expect that offset
    to be included in the register.  Indeed, they generally
    expect the absolute address and then mask off the "high" bits.
    
    The FDC is the first converted device with a non-zero offset.
    
    Signed-off-by: Richard Henderson <rth at twiddle.net>
    Signed-off-by: Avi Kivity <avi at redhat.com>

diff --git a/memory.c b/memory.c
index 531b575..8e9ac46 100644
--- a/memory.c
+++ b/memory.c
@@ -396,7 +396,7 @@ static void memory_region_iorange_read(IORange *iorange,
 
         *data = ((uint64_t)1 << (width * 8)) - 1;
         if (mrp) {
-            *data = mrp->read(mr->opaque, offset - mrp->offset);
+            *data = mrp->read(mr->opaque, offset);
         }
         return;
     }
@@ -418,7 +418,7 @@ static void memory_region_iorange_write(IORange *iorange,
         const MemoryRegionPortio *mrp = find_portio(mr, offset, width, true);
 
         if (mrp) {
-            mrp->write(mr->opaque, offset - mrp->offset, data);
+            mrp->write(mr->opaque, offset, data);
         }
         return;
     }
commit a5e1cbc80e88ed7d73b3fcb46053a3ba167293fc
Author: Anthony Liguori <aliguori at us.ibm.com>
Date:   Mon Aug 22 11:14:56 2011 -0500

    memory: temporarily suppress the subregion collision warning
    
    After 312b4234, the APIC and PCI devices are colliding with each other.  This
    is harmless in practice because the APIC accesses are special cased and never
    make there way onto the bus.
    
    Avi is working on a proper fix, but until that's ready, avoid printing the
    warning.
    
    Signed-off-by: Anthony Liguori <aliguori at us.ibm.com>

diff --git a/memory.c b/memory.c
index 30ba4a4..531b575 100644
--- a/memory.c
+++ b/memory.c
@@ -1191,11 +1191,13 @@ static void memory_region_add_subregion_common(MemoryRegion *mr,
             || offset + subregion->size <= other->offset) {
             continue;
         }
+#if 0
         printf("warning: subregion collision %llx/%llx vs %llx/%llx\n",
                (unsigned long long)offset,
                (unsigned long long)subregion->size,
                (unsigned long long)other->offset,
                (unsigned long long)other->size);
+#endif
     }
     QTAILQ_FOREACH(other, &mr->subregions, subregions_link) {
         if (subregion->priority >= other->priority) {
commit ae0a54664c76f1d2a2a7a268266d47b4e8c12a4c
Author: Avi Kivity <avi at redhat.com>
Date:   Mon Aug 15 17:17:38 2011 +0300

    440fx: fix PAM, PCI holes
    
    The current implementation of PAM and the PCI holes is broken in several
    ways:
    
      - PCI BARs are not restricted to the PCI hole (a BAR may hide memory)
      - PCI devices do not respect PAM (if a PCI device maps a region while
        PAM maps the region to RAM, the request will be honored)
    
    This patch fixes things by introducing a pci address space, and using
    memory region aliases to represent PAM regions, SMRAM, and PCI holes.
    
    The memory hierarchy looks something like
    
    system_memory
     |
     +--- low memory alias (0-0xe0000000)
     |      |
     |      +-- ram at 0
     |
     +--- high memory alias (0x100000000-EOM)
     |      |
     |      +-- ram at 0xe0000000
     |
     +--- pci hole alias (end of low memory-0x100000000)
     |      |
     |      +-- pci at end-of-low-memory
     |
     |
     +--- pam[n] (0xc0000-0xc3fff etc) (when set to pci, priority 1)
     |      |
     |      +-- pci at 0xc4000 etc
     |
     +--- smram (0xa0000-0xbffff) (when set to pci/vga, priority 1)
            |
            +-- pci at 0xa0000 etc
    
    ram (simple ram region)
    
    pci
     |
     +--- BARn
     |
     +--- VGA 0xa0000-0xbffff
     |
     +--- ROMs
    
    Signed-off-by: Avi Kivity <avi at redhat.com>
    Signed-off-by: Anthony Liguori <aliguori at us.ibm.com>

diff --git a/hw/pc.c b/hw/pc.c
index a29a29f..263fb1a 100644
--- a/hw/pc.c
+++ b/hw/pc.c
@@ -964,7 +964,9 @@ void pc_memory_init(MemoryRegion *system_memory,
                     const char *kernel_cmdline,
                     const char *initrd_filename,
                     ram_addr_t below_4g_mem_size,
-                    ram_addr_t above_4g_mem_size)
+                    ram_addr_t above_4g_mem_size,
+                    MemoryRegion *pci_memory,
+                    MemoryRegion **ram_memory)
 {
     char *filename;
     int ret, linux_boot, i;
@@ -982,6 +984,7 @@ void pc_memory_init(MemoryRegion *system_memory,
     ram = g_malloc(sizeof(*ram));
     memory_region_init_ram(ram, NULL, "pc.ram",
                            below_4g_mem_size + above_4g_mem_size);
+    *ram_memory = ram;
     ram_below_4g = g_malloc(sizeof(*ram_below_4g));
     memory_region_init_alias(ram_below_4g, "ram-below-4g", ram,
                              0, below_4g_mem_size);
@@ -1026,7 +1029,7 @@ void pc_memory_init(MemoryRegion *system_memory,
     isa_bios = g_malloc(sizeof(*isa_bios));
     memory_region_init_alias(isa_bios, "isa-bios", bios,
                              bios_size - isa_bios_size, isa_bios_size);
-    memory_region_add_subregion_overlap(system_memory,
+    memory_region_add_subregion_overlap(pci_memory,
                                         0x100000 - isa_bios_size,
                                         isa_bios,
                                         1);
@@ -1034,13 +1037,13 @@ void pc_memory_init(MemoryRegion *system_memory,
 
     option_rom_mr = g_malloc(sizeof(*option_rom_mr));
     memory_region_init_ram(option_rom_mr, NULL, "pc.rom", PC_ROM_SIZE);
-    memory_region_add_subregion_overlap(system_memory,
+    memory_region_add_subregion_overlap(pci_memory,
                                         PC_ROM_MIN_VGA,
                                         option_rom_mr,
                                         1);
 
     /* map all the bios at the top of memory */
-    memory_region_add_subregion(system_memory,
+    memory_region_add_subregion(pci_memory,
                                 (uint32_t)(-bios_size),
                                 bios);
 
diff --git a/hw/pc.h b/hw/pc.h
index d871fd8..dae736e 100644
--- a/hw/pc.h
+++ b/hw/pc.h
@@ -136,7 +136,9 @@ void pc_memory_init(MemoryRegion *system_memory,
                     const char *kernel_cmdline,
                     const char *initrd_filename,
                     ram_addr_t below_4g_mem_size,
-                    ram_addr_t above_4g_mem_size);
+                    ram_addr_t above_4g_mem_size,
+                    MemoryRegion *pci_memory,
+                    MemoryRegion **ram_memory);
 qemu_irq *pc_allocate_cpu_irq(void);
 void pc_vga_init(PCIBus *pci_bus);
 void pc_basic_device_init(qemu_irq *isa_irq,
@@ -182,8 +184,13 @@ PCIBus *i440fx_init(PCII440FXState **pi440fx_state, int *piix_devfn,
                     qemu_irq *pic,
                     MemoryRegion *address_space_mem,
                     MemoryRegion *address_space_io,
-                    ram_addr_t ram_size);
-void i440fx_init_memory_mappings(PCII440FXState *d);
+                    ram_addr_t ram_size,
+                    target_phys_addr_t pci_hole_start,
+                    target_phys_addr_t pci_hole_size,
+                    target_phys_addr_t pci_hole64_start,
+                    target_phys_addr_t pci_hole64_size,
+                    MemoryRegion *pci_memory,
+                    MemoryRegion *ram_memory);
 
 /* piix4.c */
 extern PCIDevice *piix4_dev;
diff --git a/hw/pc_piix.c b/hw/pc_piix.c
index a9fe596..75d96d9 100644
--- a/hw/pc_piix.c
+++ b/hw/pc_piix.c
@@ -22,6 +22,8 @@
  * THE SOFTWARE.
  */
 
+#include <glib.h>
+
 #include "hw.h"
 #include "pc.h"
 #include "apic.h"
@@ -93,6 +95,8 @@ static void pc_init1(MemoryRegion *system_memory,
     DriveInfo *hd[MAX_IDE_BUS * MAX_IDE_DEVS];
     BusState *idebus[MAX_IDE_BUS];
     ISADevice *rtc_state;
+    MemoryRegion *ram_memory;
+    MemoryRegion *pci_memory;
 
     pc_cpus_init(cpu_model);
 
@@ -108,11 +112,15 @@ static void pc_init1(MemoryRegion *system_memory,
         below_4g_mem_size = ram_size;
     }
 
+    pci_memory = g_new(MemoryRegion, 1);
+    memory_region_init(pci_memory, "pci", INT64_MAX);
+
     /* allocate ram and load rom/bios */
     if (!xen_enabled()) {
         pc_memory_init(system_memory,
                        kernel_filename, kernel_cmdline, initrd_filename,
-                       below_4g_mem_size, above_4g_mem_size);
+                       below_4g_mem_size, above_4g_mem_size,
+                       pci_memory, &ram_memory);
     }
 
     if (!xen_enabled()) {
@@ -130,7 +138,14 @@ static void pc_init1(MemoryRegion *system_memory,
 
     if (pci_enabled) {
         pci_bus = i440fx_init(&i440fx_state, &piix3_devfn, isa_irq,
-                              system_memory, system_io, ram_size);
+                              system_memory, system_io, ram_size,
+                              below_4g_mem_size,
+                              0x100000000ULL - below_4g_mem_size,
+                              0x100000000ULL + above_4g_mem_size,
+                              (sizeof(target_phys_addr_t) == 4
+                               ? 0
+                               : ((uint64_t)1 << 62)),
+                              pci_memory, ram_memory);
     } else {
         pci_bus = NULL;
         i440fx_state = NULL;
@@ -202,10 +217,6 @@ static void pc_init1(MemoryRegion *system_memory,
         smbus_eeprom_init(smbus, 8, NULL, 0);
     }
 
-    if (i440fx_state) {
-        i440fx_init_memory_mappings(i440fx_state);
-    }
-
     if (pci_enabled) {
         pc_pci_device_init(pci_bus);
     }
diff --git a/hw/piix_pci.c b/hw/piix_pci.c
index 28a3ee2..c563c6e 100644
--- a/hw/piix_pci.c
+++ b/hw/piix_pci.c
@@ -66,10 +66,22 @@ typedef struct PIIX3State {
     int32_t pci_irq_levels_vmstate[PIIX_NUM_PIRQS];
 } PIIX3State;
 
+typedef struct PAMMemoryRegion {
+    MemoryRegion mem;
+    bool initialized;
+} PAMMemoryRegion;
+
 struct PCII440FXState {
     PCIDevice dev;
-    target_phys_addr_t isa_page_descs[384 / 4];
+    MemoryRegion *system_memory;
+    MemoryRegion *pci_address_space;
+    MemoryRegion *ram_memory;
+    MemoryRegion pci_hole;
+    MemoryRegion pci_hole_64bit;
+    PAMMemoryRegion pam_regions[13];
+    MemoryRegion smram_region;
     uint8_t smm_enabled;
+    bool smram_enabled;
     PIIX3State *piix3;
 };
 
@@ -92,50 +104,62 @@ static int pci_slot_get_pirq(PCIDevice *pci_dev, int pci_intx)
     return (pci_intx + slot_addend) & 3;
 }
 
-static void update_pam(PCII440FXState *d, uint32_t start, uint32_t end, int r)
+static void update_pam(PCII440FXState *d, uint32_t start, uint32_t end, int r,
+                       PAMMemoryRegion *mem)
 {
-    uint32_t addr;
+    if (mem->initialized) {
+        memory_region_del_subregion(d->system_memory, &mem->mem);
+        memory_region_destroy(&mem->mem);
+    }
 
     //    printf("ISA mapping %08x-0x%08x: %d\n", start, end, r);
     switch(r) {
     case 3:
         /* RAM */
-        cpu_register_physical_memory(start, end - start,
-                                     start);
+        memory_region_init_alias(&mem->mem, "pam-ram", d->ram_memory,
+                                 start, end - start);
         break;
     case 1:
         /* ROM (XXX: not quite correct) */
-        cpu_register_physical_memory(start, end - start,
-                                     start | IO_MEM_ROM);
+        memory_region_init_alias(&mem->mem, "pam-rom", d->ram_memory,
+                                 start, end - start);
+        memory_region_set_readonly(&mem->mem, true);
         break;
     case 2:
     case 0:
         /* XXX: should distinguish read/write cases */
-        for(addr = start; addr < end; addr += 4096) {
-            cpu_register_physical_memory(addr, 4096,
-                                         d->isa_page_descs[(addr - 0xa0000) >> 12]);
-        }
+        memory_region_init_alias(&mem->mem, "pam-pci", d->pci_address_space,
+                                 start, end - start);
         break;
     }
+    memory_region_add_subregion_overlap(d->system_memory,
+                                        start, &mem->mem, 1);
+    mem->initialized = true;
 }
 
 static void i440fx_update_memory_mappings(PCII440FXState *d)
 {
     int i, r;
-    uint32_t smram, addr;
+    uint32_t smram;
 
-    update_pam(d, 0xf0000, 0x100000, (d->dev.config[I440FX_PAM] >> 4) & 3);
+    update_pam(d, 0xf0000, 0x100000, (d->dev.config[I440FX_PAM] >> 4) & 3,
+               &d->pam_regions[0]);
     for(i = 0; i < 12; i++) {
         r = (d->dev.config[(i >> 1) + (I440FX_PAM + 1)] >> ((i & 1) * 4)) & 3;
-        update_pam(d, 0xc0000 + 0x4000 * i, 0xc0000 + 0x4000 * (i + 1), r);
+        update_pam(d, 0xc0000 + 0x4000 * i, 0xc0000 + 0x4000 * (i + 1), r,
+                   &d->pam_regions[i+1]);
     }
     smram = d->dev.config[I440FX_SMRAM];
     if ((d->smm_enabled && (smram & 0x08)) || (smram & 0x40)) {
-        cpu_register_physical_memory(0xa0000, 0x20000, 0xa0000);
+        if (!d->smram_enabled) {
+            memory_region_del_subregion(d->system_memory, &d->smram_region);
+            d->smram_enabled = true;
+        }
     } else {
-        for(addr = 0xa0000; addr < 0xc0000; addr += 4096) {
-            cpu_register_physical_memory(addr, 4096,
-                                         d->isa_page_descs[(addr - 0xa0000) >> 12]);
+        if (d->smram_enabled) {
+            memory_region_add_subregion_overlap(d->system_memory, 0xa0000,
+                                                &d->smram_region, 1);
+            d->smram_enabled = false;
         }
     }
 }
@@ -152,17 +176,6 @@ static void i440fx_set_smm(int val, void *arg)
 }
 
 
-/* XXX: suppress when better memory API. We make the assumption that
-   no device (in particular the VGA) changes the memory mappings in
-   the 0xa0000-0x100000 range */
-void i440fx_init_memory_mappings(PCII440FXState *d)
-{
-    int i;
-    for(i = 0; i < 96; i++) {
-        d->isa_page_descs[i] = cpu_get_physical_page_desc(0xa0000 + i * 0x1000);
-    }
-}
-
 static void i440fx_write_config(PCIDevice *dev,
                                 uint32_t address, uint32_t val, int len)
 {
@@ -244,24 +257,48 @@ static PCIBus *i440fx_common_init(const char *device_name,
                                   qemu_irq *pic,
                                   MemoryRegion *address_space_mem,
                                   MemoryRegion *address_space_io,
-                                  ram_addr_t ram_size)
+                                  ram_addr_t ram_size,
+                                  target_phys_addr_t pci_hole_start,
+                                  target_phys_addr_t pci_hole_size,
+                                  target_phys_addr_t pci_hole64_start,
+                                  target_phys_addr_t pci_hole64_size,
+                                  MemoryRegion *pci_address_space,
+                                  MemoryRegion *ram_memory)
 {
     DeviceState *dev;
     PCIBus *b;
     PCIDevice *d;
     I440FXState *s;
     PIIX3State *piix3;
+    PCII440FXState *f;
 
     dev = qdev_create(NULL, "i440FX-pcihost");
     s = FROM_SYSBUS(I440FXState, sysbus_from_qdev(dev));
     s->address_space = address_space_mem;
-    b = pci_bus_new(&s->busdev.qdev, NULL, s->address_space,
+    b = pci_bus_new(&s->busdev.qdev, NULL, pci_address_space,
                     address_space_io, 0);
     s->bus = b;
     qdev_init_nofail(dev);
 
     d = pci_create_simple(b, 0, device_name);
     *pi440fx_state = DO_UPCAST(PCII440FXState, dev, d);
+    f = *pi440fx_state;
+    f->system_memory = address_space_mem;
+    f->pci_address_space = pci_address_space;
+    f->ram_memory = ram_memory;
+    memory_region_init_alias(&f->pci_hole, "pci-hole", f->pci_address_space,
+                             pci_hole_start, pci_hole_size);
+    memory_region_add_subregion(f->system_memory, pci_hole_start, &f->pci_hole);
+    memory_region_init_alias(&f->pci_hole_64bit, "pci-hole64",
+                             f->pci_address_space,
+                             pci_hole64_start, pci_hole64_size);
+    if (pci_hole64_size) {
+        memory_region_add_subregion(f->system_memory, pci_hole64_start,
+                                    &f->pci_hole_64bit);
+    }
+    memory_region_init_alias(&f->smram_region, "smram-region",
+                             f->pci_address_space, 0xa0000, 0x20000);
+    f->smram_enabled = true;
 
     /* Xen supports additional interrupt routes from the PCI devices to
      * the IOAPIC: the four pins of each PCI device on the bus are also
@@ -289,6 +326,8 @@ static PCIBus *i440fx_common_init(const char *device_name,
         ram_size = 255;
     (*pi440fx_state)->dev.config[0x57]=ram_size;
 
+    i440fx_update_memory_mappings(f);
+
     return b;
 }
 
@@ -296,12 +335,21 @@ PCIBus *i440fx_init(PCII440FXState **pi440fx_state, int *piix3_devfn,
                     qemu_irq *pic,
                     MemoryRegion *address_space_mem,
                     MemoryRegion *address_space_io,
-                    ram_addr_t ram_size)
+                    ram_addr_t ram_size,
+                    target_phys_addr_t pci_hole_start,
+                    target_phys_addr_t pci_hole_size,
+                    target_phys_addr_t pci_hole64_start,
+                    target_phys_addr_t pci_hole64_size,
+                    MemoryRegion *pci_memory, MemoryRegion *ram_memory)
+
 {
     PCIBus *b;
 
     b = i440fx_common_init("i440FX", pi440fx_state, piix3_devfn, pic,
-                           address_space_mem, address_space_io, ram_size);
+                           address_space_mem, address_space_io, ram_size,
+                           pci_hole_start, pci_hole_size,
+                           pci_hole64_size, pci_hole64_size,
+                           pci_memory, ram_memory);
     return b;
 }
 
commit be20f9e902ca47ea84e1b1c1e89b0a55d59b4c11
Author: Avi Kivity <avi at redhat.com>
Date:   Mon Aug 15 17:17:37 2011 +0300

    vga: drop get_system_memory() from vga devices and derivatives
    
    Instead, use the bus accessors, or get the address space directly
    from the board constructor.
    
    Signed-off-by: Avi Kivity <avi at redhat.com>
    Signed-off-by: Anthony Liguori <aliguori at us.ibm.com>

diff --git a/hw/cirrus_vga.c b/hw/cirrus_vga.c
index 0f91112..4d0ef0d 100644
--- a/hw/cirrus_vga.c
+++ b/hw/cirrus_vga.c
@@ -32,7 +32,6 @@
 #include "console.h"
 #include "vga_int.h"
 #include "loader.h"
-#include "exec-memory.h"
 
 /*
  * TODO:
@@ -2801,7 +2800,8 @@ static const MemoryRegionOps cirrus_linear_io_ops = {
     },
 };
 
-static void cirrus_init_common(CirrusVGAState * s, int device_id, int is_pci)
+static void cirrus_init_common(CirrusVGAState * s, int device_id, int is_pci,
+                               MemoryRegion *system_memory)
 {
     int i;
     static int inited;
@@ -2854,7 +2854,7 @@ static void cirrus_init_common(CirrusVGAState * s, int device_id, int is_pci)
     memory_region_init_io(&s->low_mem, &cirrus_vga_mem_ops, s,
                           "cirrus-low-memory", 0x20000);
     memory_region_add_subregion(&s->low_mem_container, 0, &s->low_mem);
-    memory_region_add_subregion_overlap(get_system_memory(),
+    memory_region_add_subregion_overlap(system_memory,
                                         isa_mem_base + 0x000a0000,
                                         &s->low_mem_container,
                                         1);
@@ -2897,14 +2897,14 @@ static void cirrus_init_common(CirrusVGAState * s, int device_id, int is_pci)
  *
  ***************************************/
 
-void isa_cirrus_vga_init(void)
+void isa_cirrus_vga_init(MemoryRegion *system_memory)
 {
     CirrusVGAState *s;
 
     s = g_malloc0(sizeof(CirrusVGAState));
 
     vga_common_init(&s->vga, VGA_RAM_SIZE);
-    cirrus_init_common(s, CIRRUS_ID_CLGD5430, 0);
+    cirrus_init_common(s, CIRRUS_ID_CLGD5430, 0, system_memory);
     s->vga.ds = graphic_console_init(s->vga.update, s->vga.invalidate,
                                      s->vga.screen_dump, s->vga.text_update,
                                      &s->vga);
@@ -2928,7 +2928,7 @@ static int pci_cirrus_vga_initfn(PCIDevice *dev)
 
      /* setup VGA */
      vga_common_init(&s->vga, VGA_RAM_SIZE);
-     cirrus_init_common(s, device_id, 1);
+     cirrus_init_common(s, device_id, 1, pci_address_space(dev));
      s->vga.ds = graphic_console_init(s->vga.update, s->vga.invalidate,
                                       s->vga.screen_dump, s->vga.text_update,
                                       &s->vga);
diff --git a/hw/mips_jazz.c b/hw/mips_jazz.c
index ea20510..84ce061 100644
--- a/hw/mips_jazz.c
+++ b/hw/mips_jazz.c
@@ -38,6 +38,7 @@
 #include "mc146818rtc.h"
 #include "blockdev.h"
 #include "sysbus.h"
+#include "exec-memory.h"
 
 enum jazz_model_e
 {
@@ -197,7 +198,7 @@ void mips_jazz_init (ram_addr_t ram_size,
         g364fb_mm_init(0x40000000, 0x60000000, 0, rc4030[3]);
         break;
     case JAZZ_PICA61:
-        isa_vga_mm_init(0x40000000, 0x60000000, 0);
+        isa_vga_mm_init(0x40000000, 0x60000000, 0, get_system_memory());
         break;
     default:
         break;
diff --git a/hw/pc.c b/hw/pc.c
index 7be60a4..a29a29f 100644
--- a/hw/pc.c
+++ b/hw/pc.c
@@ -42,6 +42,7 @@
 #include "blockdev.h"
 #include "ui/qemu-spice.h"
 #include "memory.h"
+#include "exec-memory.h"
 
 /* output Bochs bios info messages */
 //#define DEBUG_BIOS
@@ -1066,7 +1067,7 @@ void pc_vga_init(PCIBus *pci_bus)
         if (pci_bus) {
             pci_cirrus_vga_init(pci_bus);
         } else {
-            isa_cirrus_vga_init();
+            isa_cirrus_vga_init(get_system_memory());
         }
     } else if (vmsvga_enabled) {
         if (pci_bus) {
diff --git a/hw/pc.h b/hw/pc.h
index ec34db7..d871fd8 100644
--- a/hw/pc.h
+++ b/hw/pc.h
@@ -212,11 +212,12 @@ static inline int isa_vga_init(void)
 
 int pci_vga_init(PCIBus *bus);
 int isa_vga_mm_init(target_phys_addr_t vram_base,
-                    target_phys_addr_t ctrl_base, int it_shift);
+                    target_phys_addr_t ctrl_base, int it_shift,
+                    MemoryRegion *address_space);
 
 /* cirrus_vga.c */
 void pci_cirrus_vga_init(PCIBus *bus);
-void isa_cirrus_vga_init(void);
+void isa_cirrus_vga_init(MemoryRegion *address_space);
 
 /* ne2000.c */
 static inline bool isa_ne2000_init(int base, int irq, NICInfo *nd)
diff --git a/hw/qxl.c b/hw/qxl.c
index bab60a5..1d9077d 100644
--- a/hw/qxl.c
+++ b/hw/qxl.c
@@ -1598,7 +1598,7 @@ static int qxl_init_primary(PCIDevice *dev)
         ram_size = 32 * 1024 * 1024;
     }
     vga_common_init(vga, ram_size);
-    vga_init(vga);
+    vga_init(vga, pci_address_space(dev));
     register_ioport_write(0x3c0, 16, 1, qxl_vga_ioport_write, vga);
     register_ioport_write(0x3b4,  2, 1, qxl_vga_ioport_write, vga);
     register_ioport_write(0x3d4,  2, 1, qxl_vga_ioport_write, vga);
diff --git a/hw/vga-isa-mm.c b/hw/vga-isa-mm.c
index b934978..f8984c6 100644
--- a/hw/vga-isa-mm.c
+++ b/hw/vga-isa-mm.c
@@ -27,7 +27,6 @@
 #include "vga_int.h"
 #include "pixel_ops.h"
 #include "qemu-timer.h"
-#include "exec-memory.h"
 
 typedef struct ISAVGAMMState {
     VGACommonState vga;
@@ -97,7 +96,8 @@ static const MemoryRegionOps vga_mm_ctrl_ops = {
 };
 
 static void vga_mm_init(ISAVGAMMState *s, target_phys_addr_t vram_base,
-                        target_phys_addr_t ctrl_base, int it_shift)
+                        target_phys_addr_t ctrl_base, int it_shift,
+                        MemoryRegion *address_space)
 {
     MemoryRegion *s_ioport_ctrl, *vga_io_memory;
 
@@ -113,26 +113,27 @@ static void vga_mm_init(ISAVGAMMState *s, target_phys_addr_t vram_base,
 
     vmstate_register(NULL, 0, &vmstate_vga_common, s);
 
-    memory_region_add_subregion(get_system_memory(), ctrl_base, s_ioport_ctrl);
+    memory_region_add_subregion(address_space, ctrl_base, s_ioport_ctrl);
     s->vga.bank_offset = 0;
-    memory_region_add_subregion(get_system_memory(),
+    memory_region_add_subregion(address_space,
                                 vram_base + 0x000a0000, vga_io_memory);
     memory_region_set_coalescing(vga_io_memory);
 }
 
 int isa_vga_mm_init(target_phys_addr_t vram_base,
-                    target_phys_addr_t ctrl_base, int it_shift)
+                    target_phys_addr_t ctrl_base, int it_shift,
+                    MemoryRegion *address_space)
 {
     ISAVGAMMState *s;
 
     s = g_malloc0(sizeof(*s));
 
     vga_common_init(&s->vga, VGA_RAM_SIZE);
-    vga_mm_init(s, vram_base, ctrl_base, it_shift);
+    vga_mm_init(s, vram_base, ctrl_base, it_shift, address_space);
 
     s->vga.ds = graphic_console_init(s->vga.update, s->vga.invalidate,
                                      s->vga.screen_dump, s->vga.text_update, s);
 
-    vga_init_vbe(&s->vga);
+    vga_init_vbe(&s->vga, address_space);
     return 0;
 }
diff --git a/hw/vga-isa.c b/hw/vga-isa.c
index fef7f58..0d19901 100644
--- a/hw/vga-isa.c
+++ b/hw/vga-isa.c
@@ -28,7 +28,6 @@
 #include "pixel_ops.h"
 #include "qemu-timer.h"
 #include "loader.h"
-#include "exec-memory.h"
 
 typedef struct ISAVGAState {
     ISADevice dev;
@@ -51,7 +50,7 @@ static int vga_initfn(ISADevice *dev)
 
     vga_common_init(s, VGA_RAM_SIZE);
     vga_io_memory = vga_init_io(s);
-    memory_region_add_subregion_overlap(get_system_memory(),
+    memory_region_add_subregion_overlap(isa_address_space(dev),
                                         isa_mem_base + 0x000a0000,
                                         vga_io_memory, 1);
     memory_region_set_coalescing(vga_io_memory);
@@ -68,7 +67,7 @@ static int vga_initfn(ISADevice *dev)
     s->ds = graphic_console_init(s->update, s->invalidate,
                                  s->screen_dump, s->text_update, s);
 
-    vga_init_vbe(s);
+    vga_init_vbe(s, isa_address_space(dev));
     /* ROM BIOS */
     rom_add_vga(VGABIOS_FILENAME);
     return 0;
diff --git a/hw/vga-pci.c b/hw/vga-pci.c
index c67be0a..3c8bcb0 100644
--- a/hw/vga-pci.c
+++ b/hw/vga-pci.c
@@ -54,7 +54,7 @@ static int pci_vga_initfn(PCIDevice *dev)
 
      // vga + console init
      vga_common_init(s, VGA_RAM_SIZE);
-     vga_init(s);
+     vga_init(s, pci_address_space(dev));
 
      s->ds = graphic_console_init(s->update, s->invalidate,
                                   s->screen_dump, s->text_update, s);
@@ -64,7 +64,7 @@ static int pci_vga_initfn(PCIDevice *dev)
 
      if (!dev->rom_bar) {
          /* compatibility with pc-0.13 and older */
-         vga_init_vbe(s);
+         vga_init_vbe(s, pci_address_space(dev));
      }
 
      return 0;
diff --git a/hw/vga.c b/hw/vga.c
index a190105..b0371d5 100644
--- a/hw/vga.c
+++ b/hw/vga.c
@@ -28,7 +28,6 @@
 #include "vga_int.h"
 #include "pixel_ops.h"
 #include "qemu-timer.h"
-#include "exec-memory.h"
 
 //#define DEBUG_VGA
 //#define DEBUG_VGA_MEM
@@ -2241,7 +2240,7 @@ MemoryRegion *vga_init_io(VGACommonState *s)
     return vga_mem;
 }
 
-void vga_init(VGACommonState *s)
+void vga_init(VGACommonState *s, MemoryRegion *address_space)
 {
     MemoryRegion *vga_io_memory;
 
@@ -2250,18 +2249,18 @@ void vga_init(VGACommonState *s)
     s->bank_offset = 0;
 
     vga_io_memory = vga_init_io(s);
-    memory_region_add_subregion_overlap(get_system_memory(),
+    memory_region_add_subregion_overlap(address_space,
                                         isa_mem_base + 0x000a0000,
                                         vga_io_memory,
                                         1);
     memory_region_set_coalescing(vga_io_memory);
 }
 
-void vga_init_vbe(VGACommonState *s)
+void vga_init_vbe(VGACommonState *s, MemoryRegion *system_memory)
 {
 #ifdef CONFIG_BOCHS_VBE
     /* XXX: use optimized standard vga accesses */
-    memory_region_add_subregion(get_system_memory(),
+    memory_region_add_subregion(system_memory,
                                 VBE_DISPI_LFB_PHYSICAL_ADDRESS,
                                 &s->vram);
     s->vbe_mapped = 1;
diff --git a/hw/vga_int.h b/hw/vga_int.h
index 100d98c..7e4ed71 100644
--- a/hw/vga_int.h
+++ b/hw/vga_int.h
@@ -187,7 +187,7 @@ static inline int c6_to_8(int v)
 }
 
 void vga_common_init(VGACommonState *s, int vga_ram_size);
-void vga_init(VGACommonState *s);
+void vga_init(VGACommonState *s, MemoryRegion *address_space);
 MemoryRegion *vga_init_io(VGACommonState *s);
 void vga_common_reset(VGACommonState *s);
 
@@ -217,7 +217,7 @@ void vga_draw_cursor_line_32(uint8_t *d1, const uint8_t *src1,
                              unsigned int color_xor);
 
 int vga_ioport_invalid(VGACommonState *s, uint32_t addr);
-void vga_init_vbe(VGACommonState *s);
+void vga_init_vbe(VGACommonState *s, MemoryRegion *address_space);
 
 extern const uint8_t sr_mask[8];
 extern const uint8_t gr_mask[16];
diff --git a/hw/vmware_vga.c b/hw/vmware_vga.c
index a840cbd..5396a6c 100644
--- a/hw/vmware_vga.c
+++ b/hw/vmware_vga.c
@@ -1207,7 +1207,8 @@ static const VMStateDescription vmstate_vmware_vga = {
     }
 };
 
-static void vmsvga_init(struct vmsvga_state_s *s, int vga_ram_size)
+static void vmsvga_init(struct vmsvga_state_s *s, int vga_ram_size,
+                        MemoryRegion *address_space)
 {
     s->scratch_size = SVGA_SCRATCH_SIZE;
     s->scratch = g_malloc(s->scratch_size * 4);
@@ -1223,7 +1224,7 @@ static void vmsvga_init(struct vmsvga_state_s *s, int vga_ram_size)
     s->fifo_ptr = memory_region_get_ram_ptr(&s->fifo_ram);
 
     vga_common_init(&s->vga, vga_ram_size);
-    vga_init(&s->vga);
+    vga_init(&s->vga, address_space);
     vmstate_register(NULL, 0, &vmstate_vga_common, &s->vga);
 
     vmsvga_reset(s);
@@ -1293,7 +1294,7 @@ static int pci_vmsvga_initfn(PCIDevice *dev)
                           "vmsvga-io", 0x10);
     pci_register_bar(&s->card, 0, PCI_BASE_ADDRESS_SPACE_IO, &s->io_bar);
 
-    vmsvga_init(&s->chip, VGA_RAM_SIZE);
+    vmsvga_init(&s->chip, VGA_RAM_SIZE, pci_address_space(dev));
 
     pci_register_bar(&s->card, 1, PCI_BASE_ADDRESS_MEM_PREFETCH, iomem);
     pci_register_bar(&s->card, 2, PCI_BASE_ADDRESS_MEM_PREFETCH,
@@ -1301,7 +1302,7 @@ static int pci_vmsvga_initfn(PCIDevice *dev)
 
     if (!dev->rom_bar) {
         /* compatibility with pc-0.13 and older */
-        vga_init_vbe(&s->chip.vga);
+        vga_init_vbe(&s->chip.vga, pci_address_space(dev));
     }
 
     return 0;
commit f5e6fed879ae10b9f6494a6eed21c1979391d7cb
Author: Avi Kivity <avi at redhat.com>
Date:   Mon Aug 15 17:17:36 2011 +0300

    pci: add pci_address_space()
    
    Returns the PCI address space.  Useful for bridges that can obscure
    part of the PCI address space.
    
    Signed-off-by: Avi Kivity <avi at redhat.com>
    Signed-off-by: Anthony Liguori <aliguori at us.ibm.com>

diff --git a/hw/pci.c b/hw/pci.c
index 4dc13d2..6124790 100644
--- a/hw/pci.c
+++ b/hw/pci.c
@@ -2165,3 +2165,8 @@ int pci_qdev_find_device(const char *id, PCIDevice **pdev)
 
     return rc;
 }
+
+MemoryRegion *pci_address_space(PCIDevice *dev)
+{
+    return dev->bus->address_space_mem;
+}
diff --git a/hw/pci.h b/hw/pci.h
index d7ad7fb..391217e 100644
--- a/hw/pci.h
+++ b/hw/pci.h
@@ -220,6 +220,7 @@ void pci_default_write_config(PCIDevice *d,
                               uint32_t address, uint32_t val, int len);
 void pci_device_save(PCIDevice *s, QEMUFile *f);
 int pci_device_load(PCIDevice *s, QEMUFile *f);
+MemoryRegion *pci_address_space(PCIDevice *dev);
 
 typedef void (*pci_set_irq_fn)(void *opaque, int irq_num, int level);
 typedef int (*pci_map_irq_fn)(PCIDevice *pci_dev, int irq_num);
commit c839adec884ed601204d527f021bf638e879a61f
Author: Avi Kivity <avi at redhat.com>
Date:   Mon Aug 15 17:17:35 2011 +0300

    isa: add isa_address_space()
    
    A helper that returns the address space used by ISA devices.  Useful
    for getting rid of isa_mem_base, multiple ISA buses, or ISA buses behind
    bridges.
    
    Signed-off-by: Avi Kivity <avi at redhat.com>
    Signed-off-by: Anthony Liguori <aliguori at us.ibm.com>

diff --git a/hw/isa-bus.c b/hw/isa-bus.c
index 2765543..1cb497f 100644
--- a/hw/isa-bus.c
+++ b/hw/isa-bus.c
@@ -20,6 +20,7 @@
 #include "monitor.h"
 #include "sysbus.h"
 #include "isa.h"
+#include "exec-memory.h"
 
 struct ISABus {
     BusState qbus;
@@ -202,4 +203,9 @@ static char *isabus_get_fw_dev_path(DeviceState *dev)
     return strdup(path);
 }
 
+MemoryRegion *isa_address_space(ISADevice *dev)
+{
+    return get_system_memory();
+}
+
 device_init(isabus_register_devices)
diff --git a/hw/isa.h b/hw/isa.h
index f1f2181..f344699 100644
--- a/hw/isa.h
+++ b/hw/isa.h
@@ -32,6 +32,7 @@ void isa_init_irq(ISADevice *dev, qemu_irq *p, int isairq);
 void isa_init_ioport(ISADevice *dev, uint16_t ioport);
 void isa_init_ioport_range(ISADevice *dev, uint16_t start, uint16_t length);
 void isa_qdev_register(ISADeviceInfo *info);
+MemoryRegion *isa_address_space(ISADevice *dev);
 ISADevice *isa_create(const char *name);
 ISADevice *isa_try_create(const char *name);
 ISADevice *isa_create_simple(const char *name);
commit c5b3572fc64360152fe1ccb9e4b72d17770c55e7
Author: Avi Kivity <avi at redhat.com>
Date:   Mon Aug 15 17:17:34 2011 +0300

    sysbus: remove sysbus_init_mmio_cb()
    
    This problem with this function is that it is not reversible - it is
    impossible to know where things are registered and unregister them
    exactly.  As there are no more users, we can remove it.
    
    Signed-off-by: Avi Kivity <avi at redhat.com>
    Signed-off-by: Anthony Liguori <aliguori at us.ibm.com>

diff --git a/hw/sysbus.c b/hw/sysbus.c
index 1e57f09..f39768b 100644
--- a/hw/sysbus.c
+++ b/hw/sysbus.c
@@ -107,18 +107,6 @@ void sysbus_init_mmio(SysBusDevice *dev, target_phys_addr_t size,
     dev->mmio[n].iofunc = iofunc;
 }
 
-void sysbus_init_mmio_cb(SysBusDevice *dev, target_phys_addr_t size,
-                         mmio_mapfunc cb)
-{
-    int n;
-
-    assert(dev->num_mmio < QDEV_MAX_MMIO);
-    n = dev->num_mmio++;
-    dev->mmio[n].addr = -1;
-    dev->mmio[n].size = size;
-    dev->mmio[n].cb = cb;
-}
-
 void sysbus_init_mmio_cb2(SysBusDevice *dev,
                           mmio_mapfunc cb, mmio_mapfunc unmap)
 {
diff --git a/hw/sysbus.h b/hw/sysbus.h
index 16fd969..b87c6c5 100644
--- a/hw/sysbus.h
+++ b/hw/sysbus.h
@@ -47,8 +47,6 @@ void sysbus_register_withprop(SysBusDeviceInfo *info);
 void *sysbus_new(void);
 void sysbus_init_mmio(SysBusDevice *dev, target_phys_addr_t size,
                       ram_addr_t iofunc);
-void sysbus_init_mmio_cb(SysBusDevice *dev, target_phys_addr_t size,
-                            mmio_mapfunc cb);
 void sysbus_init_mmio_cb2(SysBusDevice *dev,
                           mmio_mapfunc cb, mmio_mapfunc unmap);
 void sysbus_init_mmio_region(SysBusDevice *dev, MemoryRegion *memory);
commit cd0fa1e6d30b122dc239735e85853e7696e8e07a
Author: Avi Kivity <avi at redhat.com>
Date:   Mon Aug 15 17:17:33 2011 +0300

    ppce500_pci: convert to sysbus_init_mmio_cb2()
    
    Not a huge step forward, but at least we now have a 1:1 relationship
    between registration and unregistration.
    
    Signed-off-by: Avi Kivity <avi at redhat.com>
    Signed-off-by: Anthony Liguori <aliguori at us.ibm.com>

diff --git a/hw/ppce500_pci.c b/hw/ppce500_pci.c
index 6a9f979..4390aeb 100644
--- a/hw/ppce500_pci.c
+++ b/hw/ppce500_pci.c
@@ -274,6 +274,16 @@ static void e500_pci_map(SysBusDevice *dev, target_phys_addr_t base)
                                  s->reg);
 }
 
+static void e500_pci_unmap(SysBusDevice *dev, target_phys_addr_t base)
+{
+    cpu_register_physical_memory(base + PCIE500_CFGADDR, 4,
+                                 IO_MEM_UNASSIGNED);
+    cpu_register_physical_memory(base + PCIE500_CFGDATA, 4,
+                                 IO_MEM_UNASSIGNED);
+    cpu_register_physical_memory(base + PCIE500_REG_BASE, PCIE500_REG_SIZE,
+                                 IO_MEM_UNASSIGNED);
+}
+
 #include "exec-memory.h"
 
 static int e500_pcihost_initfn(SysBusDevice *dev)
@@ -304,7 +314,7 @@ static int e500_pcihost_initfn(SysBusDevice *dev)
                                              DEVICE_LITTLE_ENDIAN);
     s->reg = cpu_register_io_memory(e500_pci_reg_read, e500_pci_reg_write, s,
                                     DEVICE_BIG_ENDIAN);
-    sysbus_init_mmio_cb(dev, PCIE500_ALL_SIZE, e500_pci_map);
+    sysbus_init_mmio_cb2(dev, e500_pci_map, e500_pci_unmap);
 
     return 0;
 }
commit 45de094eb8fdaf81e9bdd83183e414cf95fd4460
Author: Avi Kivity <avi at redhat.com>
Date:   Mon Aug 15 17:17:32 2011 +0300

    versatile_pci: convert to memory API
    
    Signed-off-by: Avi Kivity <avi at redhat.com>
    Signed-off-by: Anthony Liguori <aliguori at us.ibm.com>

diff --git a/hw/versatile_pci.c b/hw/versatile_pci.c
index e1d5c0b..98e56f1 100644
--- a/hw/versatile_pci.c
+++ b/hw/versatile_pci.c
@@ -16,7 +16,9 @@ typedef struct {
     SysBusDevice busdev;
     qemu_irq irq[4];
     int realview;
-    int mem_config;
+    MemoryRegion mem_config;
+    MemoryRegion mem_config2;
+    MemoryRegion isa;
 } PCIVPBState;
 
 static inline uint32_t vpb_pci_config_addr(target_phys_addr_t addr)
@@ -24,55 +26,24 @@ static inline uint32_t vpb_pci_config_addr(target_phys_addr_t addr)
     return addr & 0xffffff;
 }
 
-static void pci_vpb_config_writeb (void *opaque, target_phys_addr_t addr,
-                                   uint32_t val)
+static void pci_vpb_config_write(void *opaque, target_phys_addr_t addr,
+                                 uint64_t val, unsigned size)
 {
-    pci_data_write(opaque, vpb_pci_config_addr (addr), val, 1);
+    pci_data_write(opaque, vpb_pci_config_addr(addr), val, size);
 }
 
-static void pci_vpb_config_writew (void *opaque, target_phys_addr_t addr,
-                                   uint32_t val)
-{
-    pci_data_write(opaque, vpb_pci_config_addr (addr), val, 2);
-}
-
-static void pci_vpb_config_writel (void *opaque, target_phys_addr_t addr,
-                                   uint32_t val)
-{
-    pci_data_write(opaque, vpb_pci_config_addr (addr), val, 4);
-}
-
-static uint32_t pci_vpb_config_readb (void *opaque, target_phys_addr_t addr)
-{
-    uint32_t val;
-    val = pci_data_read(opaque, vpb_pci_config_addr (addr), 1);
-    return val;
-}
-
-static uint32_t pci_vpb_config_readw (void *opaque, target_phys_addr_t addr)
-{
-    uint32_t val;
-    val = pci_data_read(opaque, vpb_pci_config_addr (addr), 2);
-    return val;
-}
-
-static uint32_t pci_vpb_config_readl (void *opaque, target_phys_addr_t addr)
+static uint64_t pci_vpb_config_read(void *opaque, target_phys_addr_t addr,
+                                    unsigned size)
 {
     uint32_t val;
-    val = pci_data_read(opaque, vpb_pci_config_addr (addr), 4);
+    val = pci_data_read(opaque, vpb_pci_config_addr(addr), size);
     return val;
 }
 
-static CPUWriteMemoryFunc * const pci_vpb_config_write[] = {
-    &pci_vpb_config_writeb,
-    &pci_vpb_config_writew,
-    &pci_vpb_config_writel,
-};
-
-static CPUReadMemoryFunc * const pci_vpb_config_read[] = {
-    &pci_vpb_config_readb,
-    &pci_vpb_config_readw,
-    &pci_vpb_config_readl,
+static const MemoryRegionOps pci_vpb_config_ops = {
+    .read = pci_vpb_config_read,
+    .write = pci_vpb_config_write,
+    .endianness = DEVICE_NATIVE_ENDIAN,
 };
 
 static int pci_vpb_map_irq(PCIDevice *d, int irq_num)
@@ -87,17 +58,35 @@ static void pci_vpb_set_irq(void *opaque, int irq_num, int level)
     qemu_set_irq(pic[irq_num], level);
 }
 
+
 static void pci_vpb_map(SysBusDevice *dev, target_phys_addr_t base)
 {
     PCIVPBState *s = (PCIVPBState *)dev;
     /* Selfconfig area.  */
-    cpu_register_physical_memory(base + 0x01000000, 0x1000000, s->mem_config);
+    memory_region_add_subregion(get_system_memory(), base + 0x01000000,
+                                &s->mem_config);
+    /* Normal config area.  */
+    memory_region_add_subregion(get_system_memory(), base + 0x02000000,
+                                &s->mem_config2);
+
+    if (s->realview) {
+        /* IO memory area.  */
+        memory_region_add_subregion(get_system_memory(), base + 0x03000000,
+                                    &s->isa);
+    }
+}
+
+static void pci_vpb_unmap(SysBusDevice *dev, target_phys_addr_t base)
+{
+    PCIVPBState *s = (PCIVPBState *)dev;
+    /* Selfconfig area.  */
+    memory_region_del_subregion(get_system_memory(), &s->mem_config);
     /* Normal config area.  */
-    cpu_register_physical_memory(base + 0x02000000, 0x1000000, s->mem_config);
+    memory_region_del_subregion(get_system_memory(), &s->mem_config2);
 
     if (s->realview) {
         /* IO memory area.  */
-        isa_mmio_init(base + 0x03000000, 0x00100000);
+        memory_region_del_subregion(get_system_memory(), &s->isa);
     }
 }
 
@@ -117,10 +106,15 @@ static int pci_vpb_init(SysBusDevice *dev)
 
     /* ??? Register memory space.  */
 
-    s->mem_config = cpu_register_io_memory(pci_vpb_config_read,
-                                           pci_vpb_config_write, bus,
-                                           DEVICE_LITTLE_ENDIAN);
-    sysbus_init_mmio_cb(dev, 0x04000000, pci_vpb_map);
+    memory_region_init_io(&s->mem_config, &pci_vpb_config_ops, bus,
+                          "pci-vpb-selfconfig", 0x1000000);
+    memory_region_init_io(&s->mem_config2, &pci_vpb_config_ops, bus,
+                          "pci-vpb-config", 0x1000000);
+    if (s->realview) {
+        isa_mmio_setup(&s->isa, 0x0100000);
+    }
+
+    sysbus_init_mmio_cb2(dev, pci_vpb_map, pci_vpb_unmap);
 
     pci_create_simple(bus, -1, "versatile_pci_host");
     return 0;
commit 1635bdfa787e2e4b267be5b3b936f0f8acf7a4df
Author: Avi Kivity <avi at redhat.com>
Date:   Mon Aug 15 17:17:31 2011 +0300

    arm11mpcore: use sysbus_init_mmio_cb2
    
    This tells the sysbus code it need not use IO_MEM_UNASSIGNED.
    
    Signed-off-by: Avi Kivity <avi at redhat.com>
    Signed-off-by: Anthony Liguori <aliguori at us.ibm.com>

diff --git a/hw/arm11mpcore.c b/hw/arm11mpcore.c
index b47707f..7d60ef6 100644
--- a/hw/arm11mpcore.c
+++ b/hw/arm11mpcore.c
@@ -54,6 +54,11 @@ static void mpcore_rirq_map(SysBusDevice *dev, target_phys_addr_t base)
     sysbus_mmio_map(s->priv, 0, base);
 }
 
+static void mpcore_rirq_unmap(SysBusDevice *dev, target_phys_addr_t base)
+{
+    /* nothing to do */
+}
+
 static int realview_mpcore_init(SysBusDevice *dev)
 {
     mpcore_rirq_state *s = FROM_SYSBUS(mpcore_rirq_state, dev);
@@ -79,7 +84,7 @@ static int realview_mpcore_init(SysBusDevice *dev)
         }
     }
     qdev_init_gpio_in(&dev->qdev, mpcore_rirq_set_irq, 64);
-    sysbus_init_mmio_cb(dev, 0x2000, mpcore_rirq_map);
+    sysbus_init_mmio_cb2(dev, mpcore_rirq_map, mpcore_rirq_unmap);
     return 0;
 }
 
commit fb57117a19061229d255bfc603c1841d3947c03c
Author: Avi Kivity <avi at redhat.com>
Date:   Mon Aug 15 17:17:30 2011 +0300

    sh_pci: convert to memory API
    
    Signed-off-by: Avi Kivity <avi at redhat.com>
    Signed-off-by: Anthony Liguori <aliguori at us.ibm.com>

diff --git a/hw/sh_pci.c b/hw/sh_pci.c
index cd86501..76061bb 100644
--- a/hw/sh_pci.c
+++ b/hw/sh_pci.c
@@ -33,13 +33,16 @@ typedef struct SHPCIState {
     PCIBus *bus;
     PCIDevice *dev;
     qemu_irq irq[4];
-    int memconfig;
+    MemoryRegion memconfig_p4;
+    MemoryRegion memconfig_a7;
+    MemoryRegion isa;
     uint32_t par;
     uint32_t mbr;
     uint32_t iobr;
 } SHPCIState;
 
-static void sh_pci_reg_write (void *p, target_phys_addr_t addr, uint32_t val)
+static void sh_pci_reg_write (void *p, target_phys_addr_t addr, uint64_t val,
+                              unsigned size)
 {
     SHPCIState *pcic = p;
     switch(addr) {
@@ -54,10 +57,10 @@ static void sh_pci_reg_write (void *p, target_phys_addr_t addr, uint32_t val)
         break;
     case 0x1c8:
         if ((val & 0xfffc0000) != (pcic->iobr & 0xfffc0000)) {
-            cpu_register_physical_memory(pcic->iobr & 0xfffc0000, 0x40000,
-                                         IO_MEM_UNASSIGNED);
+            memory_region_del_subregion(get_system_memory(), &pcic->isa);
             pcic->iobr = val & 0xfffc0001;
-            isa_mmio_init(pcic->iobr & 0xfffc0000, 0x40000);
+            memory_region_add_subregion(get_system_memory(),
+                                        pcic->iobr & 0xfffc0000, &pcic->isa);
         }
         break;
     case 0x220:
@@ -66,7 +69,8 @@ static void sh_pci_reg_write (void *p, target_phys_addr_t addr, uint32_t val)
     }
 }
 
-static uint32_t sh_pci_reg_read (void *p, target_phys_addr_t addr)
+static uint64_t sh_pci_reg_read (void *p, target_phys_addr_t addr,
+                                 unsigned size)
 {
     SHPCIState *pcic = p;
     switch(addr) {
@@ -84,14 +88,14 @@ static uint32_t sh_pci_reg_read (void *p, target_phys_addr_t addr)
     return 0;
 }
 
-typedef struct {
-    CPUReadMemoryFunc * const r[3];
-    CPUWriteMemoryFunc * const w[3];
-} MemOp;
-
-static MemOp sh_pci_reg = {
-    { NULL, NULL, sh_pci_reg_read },
-    { NULL, NULL, sh_pci_reg_write },
+static const MemoryRegionOps sh_pci_reg_ops = {
+    .read = sh_pci_reg_read,
+    .write = sh_pci_reg_write,
+    .endianness = DEVICE_NATIVE_ENDIAN,
+    .valid = {
+        .min_access_size = 4,
+        .max_access_size = 4,
+    },
 };
 
 static int sh_pci_map_irq(PCIDevice *d, int irq_num)
@@ -110,11 +114,23 @@ static void sh_pci_map(SysBusDevice *dev, target_phys_addr_t base)
 {
     SHPCIState *s = FROM_SYSBUS(SHPCIState, dev);
 
-    cpu_register_physical_memory(P4ADDR(base), 0x224, s->memconfig);
-    cpu_register_physical_memory(A7ADDR(base), 0x224, s->memconfig);
-
+    memory_region_add_subregion(get_system_memory(),
+                                P4ADDR(base),
+                                &s->memconfig_p4);
+    memory_region_add_subregion(get_system_memory(),
+                                A7ADDR(base),
+                                &s->memconfig_a7);
     s->iobr = 0xfe240000;
-    isa_mmio_init(s->iobr, 0x40000);
+    memory_region_add_subregion(get_system_memory(), s->iobr, &s->isa);
+}
+
+static void sh_pci_unmap(SysBusDevice *dev, target_phys_addr_t base)
+{
+    SHPCIState *s = FROM_SYSBUS(SHPCIState, dev);
+
+    memory_region_del_subregion(get_system_memory(), &s->memconfig_p4);
+    memory_region_del_subregion(get_system_memory(), &s->memconfig_a7);
+    memory_region_del_subregion(get_system_memory(), &s->isa);
 }
 
 static int sh_pci_init_device(SysBusDevice *dev)
@@ -132,9 +148,14 @@ static int sh_pci_init_device(SysBusDevice *dev)
                               get_system_memory(),
                               get_system_io(),
                               PCI_DEVFN(0, 0), 4);
-    s->memconfig = cpu_register_io_memory(sh_pci_reg.r, sh_pci_reg.w,
-                                          s, DEVICE_NATIVE_ENDIAN);
-    sysbus_init_mmio_cb(dev, 0x224, sh_pci_map);
+    memory_region_init_io(&s->memconfig_p4, &sh_pci_reg_ops, s,
+                          "sh_pci", 0x224);
+    memory_region_init_alias(&s->memconfig_a7, "sh_pci.2", &s->memconfig_a7,
+                             0, 0x224);
+    isa_mmio_setup(&s->isa, 0x40000);
+    sysbus_init_mmio_cb2(dev, sh_pci_map, sh_pci_unmap);
+    sysbus_init_mmio_region(dev, &s->memconfig_a7);
+    sysbus_init_mmio_region(dev, &s->isa);
     s->dev = pci_create_simple(s->bus, PCI_DEVFN(0, 0), "sh_pci_host");
     return 0;
 }
commit d76120135b9ed5ea34c2038629dc9bc563f46108
Author: Avi Kivity <avi at redhat.com>
Date:   Mon Aug 15 17:17:29 2011 +0300

    sysbus: add a variant of sysbus_init_mmio_cb with an unmap callback
    
    sysbus_init_mmio_cb() uses the destructive IO_MEM_UNASSIGNED to remove a
    region.  Provide an alternative that calls an unmap callback, so the removal
    may be done non-destructively.
    
    Signed-off-by: Avi Kivity <avi at redhat.com>
    Signed-off-by: Anthony Liguori <aliguori at us.ibm.com>

diff --git a/hw/sysbus.c b/hw/sysbus.c
index f8f1746..1e57f09 100644
--- a/hw/sysbus.c
+++ b/hw/sysbus.c
@@ -53,6 +53,8 @@ void sysbus_mmio_map(SysBusDevice *dev, int n, target_phys_addr_t addr)
         if (dev->mmio[n].memory) {
             memory_region_del_subregion(get_system_memory(),
                                         dev->mmio[n].memory);
+        } else if (dev->mmio[n].unmap) {
+            dev->mmio[n].unmap(dev, dev->mmio[n].addr);
         } else {
             cpu_register_physical_memory(dev->mmio[n].addr, dev->mmio[n].size,
                                          IO_MEM_UNASSIGNED);
@@ -117,6 +119,19 @@ void sysbus_init_mmio_cb(SysBusDevice *dev, target_phys_addr_t size,
     dev->mmio[n].cb = cb;
 }
 
+void sysbus_init_mmio_cb2(SysBusDevice *dev,
+                          mmio_mapfunc cb, mmio_mapfunc unmap)
+{
+    int n;
+
+    assert(dev->num_mmio < QDEV_MAX_MMIO);
+    n = dev->num_mmio++;
+    dev->mmio[n].addr = -1;
+    dev->mmio[n].size = 0;
+    dev->mmio[n].cb = cb;
+    dev->mmio[n].unmap = unmap;
+}
+
 void sysbus_init_mmio_region(SysBusDevice *dev, MemoryRegion *memory)
 {
     int n;
diff --git a/hw/sysbus.h b/hw/sysbus.h
index 5f62e2d..16fd969 100644
--- a/hw/sysbus.h
+++ b/hw/sysbus.h
@@ -23,6 +23,7 @@ struct SysBusDevice {
         target_phys_addr_t addr;
         target_phys_addr_t size;
         mmio_mapfunc cb;
+        mmio_mapfunc unmap;
         ram_addr_t iofunc;
         MemoryRegion *memory;
     } mmio[QDEV_MAX_MMIO];
@@ -48,6 +49,8 @@ void sysbus_init_mmio(SysBusDevice *dev, target_phys_addr_t size,
                       ram_addr_t iofunc);
 void sysbus_init_mmio_cb(SysBusDevice *dev, target_phys_addr_t size,
                             mmio_mapfunc cb);
+void sysbus_init_mmio_cb2(SysBusDevice *dev,
+                          mmio_mapfunc cb, mmio_mapfunc unmap);
 void sysbus_init_mmio_region(SysBusDevice *dev, MemoryRegion *memory);
 void sysbus_init_irq(SysBusDevice *dev, qemu_irq *p);
 void sysbus_pass_irq(SysBusDevice *dev, SysBusDevice *target);
commit b6dcbe086c77ec683f5ff0b693593cda1d61f3a1
Author: Avi Kivity <avi at redhat.com>
Date:   Mon Aug 15 17:17:27 2011 +0300

    ppc4xx_sdram: convert to memory API
    
    Clumsy due to the lack of clipping support, needed for
    changing exposed ram size.
    
    Signed-off-by: Avi Kivity <avi at redhat.com>
    Signed-off-by: Anthony Liguori <aliguori at us.ibm.com>

diff --git a/hw/ppc405.h b/hw/ppc405.h
index e042a05..f0e81a6 100644
--- a/hw/ppc405.h
+++ b/hw/ppc405.h
@@ -59,16 +59,19 @@ struct ppc4xx_bd_info_t {
 ram_addr_t ppc405_set_bootinfo (CPUState *env, ppc4xx_bd_info_t *bd,
                                 uint32_t flags);
 
-CPUState *ppc405cr_init (target_phys_addr_t ram_bases[4],
+CPUState *ppc405cr_init (MemoryRegion ram_memories[4],
+                         target_phys_addr_t ram_bases[4],
                          target_phys_addr_t ram_sizes[4],
                          uint32_t sysclk, qemu_irq **picp,
                          int do_init);
-CPUState *ppc405ep_init (target_phys_addr_t ram_bases[2],
+CPUState *ppc405ep_init (MemoryRegion ram_memories[2],
+                         target_phys_addr_t ram_bases[2],
                          target_phys_addr_t ram_sizes[2],
                          uint32_t sysclk, qemu_irq **picp,
                          int do_init);
 /* IBM STBxxx microcontrollers */
-CPUState *ppc_stb025_init (target_phys_addr_t ram_bases[2],
+CPUState *ppc_stb025_init (MemoryRegion ram_memories[2],
+                           target_phys_addr_t ram_bases[2],
                            target_phys_addr_t ram_sizes[2],
                            uint32_t sysclk, qemu_irq **picp,
                            ram_addr_t *offsetp);
diff --git a/hw/ppc405_boards.c b/hw/ppc405_boards.c
index 34f9350..dec165e 100644
--- a/hw/ppc405_boards.c
+++ b/hw/ppc405_boards.c
@@ -182,6 +182,7 @@ static void ref405ep_init (ram_addr_t ram_size,
     CPUPPCState *env;
     qemu_irq *pic;
     ram_addr_t sram_offset, bios_offset, bdloc;
+    MemoryRegion *ram_memories = g_malloc(2 * sizeof(*ram_memories));
     target_phys_addr_t ram_bases[2], ram_sizes[2];
     target_ulong sram_size;
     long bios_size;
@@ -194,15 +195,17 @@ static void ref405ep_init (ram_addr_t ram_size,
     DriveInfo *dinfo;
 
     /* XXX: fix this */
-    ram_bases[0] = qemu_ram_alloc(NULL, "ef405ep.ram", 0x08000000);
+    memory_region_init_ram(&ram_memories[0], NULL, "ef405ep.ram", 0x08000000);
+    ram_bases[0] = 0;
     ram_sizes[0] = 0x08000000;
+    memory_region_init(&ram_memories[1], "ef405ep.ram1", 0);
     ram_bases[1] = 0x00000000;
     ram_sizes[1] = 0x00000000;
     ram_size = 128 * 1024 * 1024;
 #ifdef DEBUG_BOARD_INIT
     printf("%s: register cpu\n", __func__);
 #endif
-    env = ppc405ep_init(ram_bases, ram_sizes, 33333333, &pic,
+    env = ppc405ep_init(ram_memories, ram_bases, ram_sizes, 33333333, &pic,
                         kernel_filename == NULL ? 0 : 1);
     /* allocate SRAM */
     sram_size = 512 * 1024;
@@ -505,6 +508,7 @@ static void taihu_405ep_init(ram_addr_t ram_size,
     char *filename;
     qemu_irq *pic;
     ram_addr_t bios_offset;
+    MemoryRegion *ram_memories = g_malloc(2 * sizeof(*ram_memories));
     target_phys_addr_t ram_bases[2], ram_sizes[2];
     long bios_size;
     target_ulong kernel_base, initrd_base;
@@ -514,15 +518,19 @@ static void taihu_405ep_init(ram_addr_t ram_size,
     DriveInfo *dinfo;
 
     /* RAM is soldered to the board so the size cannot be changed */
-    ram_bases[0] = qemu_ram_alloc(NULL, "taihu_405ep.ram-0", 0x04000000);
+    memory_region_init_ram(&ram_memories[0], NULL,
+                           "taihu_405ep.ram-0", 0x04000000);
+    ram_bases[0] = 0;
     ram_sizes[0] = 0x04000000;
-    ram_bases[1] = qemu_ram_alloc(NULL, "taihu_405ep.ram-1", 0x04000000);
+    memory_region_init_ram(&ram_memories[1], NULL,
+                           "taihu_405ep.ram-1", 0x04000000);
+    ram_bases[1] = 0x04000000;
     ram_sizes[1] = 0x04000000;
     ram_size = 0x08000000;
 #ifdef DEBUG_BOARD_INIT
     printf("%s: register cpu\n", __func__);
 #endif
-    ppc405ep_init(ram_bases, ram_sizes, 33333333, &pic,
+    ppc405ep_init(ram_memories, ram_bases, ram_sizes, 33333333, &pic,
                   kernel_filename == NULL ? 0 : 1);
     /* allocate and load BIOS */
 #ifdef DEBUG_BOARD_INIT
diff --git a/hw/ppc405_uc.c b/hw/ppc405_uc.c
index 03b2592..9d5d2af 100644
--- a/hw/ppc405_uc.c
+++ b/hw/ppc405_uc.c
@@ -2107,7 +2107,8 @@ static void ppc405cr_cpc_init (CPUState *env, clk_setup_t clk_setup[7],
     qemu_register_reset(ppc405cr_cpc_reset, cpc);
 }
 
-CPUState *ppc405cr_init (target_phys_addr_t ram_bases[4],
+CPUState *ppc405cr_init (MemoryRegion ram_memories[4],
+                         target_phys_addr_t ram_bases[4],
                          target_phys_addr_t ram_sizes[4],
                          uint32_t sysclk, qemu_irq **picp,
                          int do_init)
@@ -2136,7 +2137,8 @@ CPUState *ppc405cr_init (target_phys_addr_t ram_bases[4],
     pic = ppcuic_init(env, irqs, 0x0C0, 0, 1);
     *picp = pic;
     /* SDRAM controller */
-    ppc4xx_sdram_init(env, pic[14], 1, ram_bases, ram_sizes, do_init);
+    ppc4xx_sdram_init(env, pic[14], 1, ram_memories,
+                      ram_bases, ram_sizes, do_init);
     /* External bus controller */
     ppc405_ebc_init(env);
     /* DMA controller */
@@ -2451,7 +2453,8 @@ static void ppc405ep_cpc_init (CPUState *env, clk_setup_t clk_setup[8],
 #endif
 }
 
-CPUState *ppc405ep_init (target_phys_addr_t ram_bases[2],
+CPUState *ppc405ep_init (MemoryRegion ram_memories[2],
+                         target_phys_addr_t ram_bases[2],
                          target_phys_addr_t ram_sizes[2],
                          uint32_t sysclk, qemu_irq **picp,
                          int do_init)
@@ -2485,7 +2488,8 @@ CPUState *ppc405ep_init (target_phys_addr_t ram_bases[2],
     *picp = pic;
     /* SDRAM controller */
 	/* XXX 405EP has no ECC interrupt */
-    ppc4xx_sdram_init(env, pic[17], 2, ram_bases, ram_sizes, do_init);
+    ppc4xx_sdram_init(env, pic[17], 2, ram_memories,
+                      ram_bases, ram_sizes, do_init);
     /* External bus controller */
     ppc405_ebc_init(env);
     /* DMA controller */
diff --git a/hw/ppc440.c b/hw/ppc440.c
index baf991f..5885ff0 100644
--- a/hw/ppc440.c
+++ b/hw/ppc440.c
@@ -38,6 +38,8 @@ CPUState *ppc440ep_init(ram_addr_t *ram_size, PCIBus **pcip,
                         const unsigned int pci_irq_nrs[4], int do_init,
                         const char *cpu_model)
 {
+    MemoryRegion *ram_memories
+        = g_malloc(PPC440EP_SDRAM_NR_BANKS * sizeof(*ram_memories));
     target_phys_addr_t ram_bases[PPC440EP_SDRAM_NR_BANKS];
     target_phys_addr_t ram_sizes[PPC440EP_SDRAM_NR_BANKS];
     CPUState *env;
@@ -66,11 +68,12 @@ CPUState *ppc440ep_init(ram_addr_t *ram_size, PCIBus **pcip,
     memset(ram_bases, 0, sizeof(ram_bases));
     memset(ram_sizes, 0, sizeof(ram_sizes));
     *ram_size = ppc4xx_sdram_adjust(*ram_size, PPC440EP_SDRAM_NR_BANKS,
+                                    ram_memories,
                                     ram_bases, ram_sizes,
                                     ppc440ep_sdram_bank_sizes);
     /* XXX 440EP's ECC interrupts are on UIC1, but we've only created UIC0. */
-    ppc4xx_sdram_init(env, pic[14], PPC440EP_SDRAM_NR_BANKS, ram_bases,
-                      ram_sizes, do_init);
+    ppc4xx_sdram_init(env, pic[14], PPC440EP_SDRAM_NR_BANKS, ram_memories,
+                      ram_bases, ram_sizes, do_init);
 
     /* PCI */
     pci_irqs = g_malloc(sizeof(qemu_irq) * 4);
diff --git a/hw/ppc4xx.h b/hw/ppc4xx.h
index bc4ee01..f969e44 100644
--- a/hw/ppc4xx.h
+++ b/hw/ppc4xx.h
@@ -42,11 +42,13 @@ qemu_irq *ppcuic_init (CPUState *env, qemu_irq *irqs,
                        uint32_t dcr_base, int has_ssr, int has_vr);
 
 ram_addr_t ppc4xx_sdram_adjust(ram_addr_t ram_size, int nr_banks,
+                               MemoryRegion ram_memories[],
                                target_phys_addr_t ram_bases[],
                                target_phys_addr_t ram_sizes[],
                                const unsigned int sdram_bank_sizes[]);
 
 void ppc4xx_sdram_init (CPUState *env, qemu_irq irq, int nbanks,
+                        MemoryRegion ram_memories[],
                         target_phys_addr_t *ram_bases,
                         target_phys_addr_t *ram_sizes,
                         int do_init);
diff --git a/hw/ppc4xx_devs.c b/hw/ppc4xx_devs.c
index 1af5f2e..349f046 100644
--- a/hw/ppc4xx_devs.c
+++ b/hw/ppc4xx_devs.c
@@ -25,6 +25,7 @@
 #include "ppc.h"
 #include "ppc4xx.h"
 #include "qemu-log.h"
+#include "exec-memory.h"
 
 //#define DEBUG_MMIO
 //#define DEBUG_UNASSIGNED
@@ -313,6 +314,8 @@ typedef struct ppc4xx_sdram_t ppc4xx_sdram_t;
 struct ppc4xx_sdram_t {
     uint32_t addr;
     int nbanks;
+    MemoryRegion containers[4]; /* used for clipping */
+    MemoryRegion *ram_memories;
     target_phys_addr_t ram_bases[4];
     target_phys_addr_t ram_sizes[4];
     uint32_t besr0;
@@ -395,16 +398,22 @@ static target_ulong sdram_size (uint32_t bcr)
     return size;
 }
 
-static void sdram_set_bcr (uint32_t *bcrp, uint32_t bcr, int enabled)
+static void sdram_set_bcr(ppc4xx_sdram_t *sdram,
+                          uint32_t *bcrp, uint32_t bcr, int enabled)
 {
+    unsigned n = bcrp - sdram->bcr;
+
     if (*bcrp & 0x00000001) {
         /* Unmap RAM */
 #ifdef DEBUG_SDRAM
         printf("%s: unmap RAM area " TARGET_FMT_plx " " TARGET_FMT_lx "\n",
                __func__, sdram_base(*bcrp), sdram_size(*bcrp));
 #endif
-        cpu_register_physical_memory(sdram_base(*bcrp), sdram_size(*bcrp),
-                                     IO_MEM_UNASSIGNED);
+        memory_region_del_subregion(get_system_memory(),
+                                    &sdram->containers[n]);
+        memory_region_del_subregion(&sdram->containers[n],
+                                    &sdram->ram_memories[n]);
+        memory_region_destroy(&sdram->containers[n]);
     }
     *bcrp = bcr & 0xFFDEE001;
     if (enabled && (bcr & 0x00000001)) {
@@ -412,8 +421,13 @@ static void sdram_set_bcr (uint32_t *bcrp, uint32_t bcr, int enabled)
         printf("%s: Map RAM area " TARGET_FMT_plx " " TARGET_FMT_lx "\n",
                __func__, sdram_base(bcr), sdram_size(bcr));
 #endif
-        cpu_register_physical_memory(sdram_base(bcr), sdram_size(bcr),
-                                     sdram_base(bcr) | IO_MEM_RAM);
+        memory_region_init(&sdram->containers[n], "sdram-containers",
+                           sdram_size(bcr));
+        memory_region_add_subregion(&sdram->containers[n], 0,
+                                    &sdram->ram_memories[n]);
+        memory_region_add_subregion(get_system_memory(),
+                                    sdram_base(bcr),
+                                    &sdram->containers[n]);
     }
 }
 
@@ -423,11 +437,12 @@ static void sdram_map_bcr (ppc4xx_sdram_t *sdram)
 
     for (i = 0; i < sdram->nbanks; i++) {
         if (sdram->ram_sizes[i] != 0) {
-            sdram_set_bcr(&sdram->bcr[i],
+            sdram_set_bcr(sdram,
+                          &sdram->bcr[i],
                           sdram_bcr(sdram->ram_bases[i], sdram->ram_sizes[i]),
                           1);
         } else {
-            sdram_set_bcr(&sdram->bcr[i], 0x00000000, 0);
+            sdram_set_bcr(sdram, &sdram->bcr[i], 0x00000000, 0);
         }
     }
 }
@@ -441,9 +456,8 @@ static void sdram_unmap_bcr (ppc4xx_sdram_t *sdram)
         printf("%s: Unmap RAM area " TARGET_FMT_plx " " TARGET_FMT_lx "\n",
                __func__, sdram_base(sdram->bcr[i]), sdram_size(sdram->bcr[i]));
 #endif
-        cpu_register_physical_memory(sdram_base(sdram->bcr[i]),
-                                     sdram_size(sdram->bcr[i]),
-                                     IO_MEM_UNASSIGNED);
+        memory_region_del_subregion(get_system_memory(),
+                                    &sdram->ram_memories[i]);
     }
 }
 
@@ -568,16 +582,16 @@ static void dcr_write_sdram (void *opaque, int dcrn, uint32_t val)
             sdram->pmit = (val & 0xF8000000) | 0x07C00000;
             break;
         case 0x40: /* SDRAM_B0CR */
-            sdram_set_bcr(&sdram->bcr[0], val, sdram->cfg & 0x80000000);
+            sdram_set_bcr(sdram, &sdram->bcr[0], val, sdram->cfg & 0x80000000);
             break;
         case 0x44: /* SDRAM_B1CR */
-            sdram_set_bcr(&sdram->bcr[1], val, sdram->cfg & 0x80000000);
+            sdram_set_bcr(sdram, &sdram->bcr[1], val, sdram->cfg & 0x80000000);
             break;
         case 0x48: /* SDRAM_B2CR */
-            sdram_set_bcr(&sdram->bcr[2], val, sdram->cfg & 0x80000000);
+            sdram_set_bcr(sdram, &sdram->bcr[2], val, sdram->cfg & 0x80000000);
             break;
         case 0x4C: /* SDRAM_B3CR */
-            sdram_set_bcr(&sdram->bcr[3], val, sdram->cfg & 0x80000000);
+            sdram_set_bcr(sdram, &sdram->bcr[3], val, sdram->cfg & 0x80000000);
             break;
         case 0x80: /* SDRAM_TR */
             sdram->tr = val & 0x018FC01F;
@@ -621,6 +635,7 @@ static void sdram_reset (void *opaque)
 }
 
 void ppc4xx_sdram_init (CPUState *env, qemu_irq irq, int nbanks,
+                        MemoryRegion *ram_memories,
                         target_phys_addr_t *ram_bases,
                         target_phys_addr_t *ram_sizes,
                         int do_init)
@@ -630,6 +645,7 @@ void ppc4xx_sdram_init (CPUState *env, qemu_irq irq, int nbanks,
     sdram = g_malloc0(sizeof(ppc4xx_sdram_t));
     sdram->irq = irq;
     sdram->nbanks = nbanks;
+    sdram->ram_memories = ram_memories;
     memset(sdram->ram_bases, 0, 4 * sizeof(target_phys_addr_t));
     memcpy(sdram->ram_bases, ram_bases,
            nbanks * sizeof(target_phys_addr_t));
@@ -653,11 +669,13 @@ void ppc4xx_sdram_init (CPUState *env, qemu_irq irq, int nbanks,
  * must be one of a small set of sizes. The number of banks and the supported
  * sizes varies by SoC. */
 ram_addr_t ppc4xx_sdram_adjust(ram_addr_t ram_size, int nr_banks,
+                               MemoryRegion ram_memories[],
                                target_phys_addr_t ram_bases[],
                                target_phys_addr_t ram_sizes[],
                                const unsigned int sdram_bank_sizes[])
 {
     ram_addr_t size_left = ram_size;
+    ram_addr_t base = 0;
     int i;
     int j;
 
@@ -668,8 +686,10 @@ ram_addr_t ppc4xx_sdram_adjust(ram_addr_t ram_size, int nr_banks,
             if (bank_size <= size_left) {
                 char name[32];
                 snprintf(name, sizeof(name), "ppc4xx.sdram%d", i);
-                ram_bases[i] = qemu_ram_alloc(NULL, name, bank_size);
+                memory_region_init_ram(&ram_memories[i], NULL, name, bank_size);
+                ram_bases[i] = base;
                 ram_sizes[i] = bank_size;
+                base += ram_size;
                 size_left -= bank_size;
                 break;
             }
commit 9074e0e3e8b087fcc14b0ae76fb240ae9872e70c
Author: Avi Kivity <avi at redhat.com>
Date:   Mon Aug 15 17:17:26 2011 +0300

    ppc405_uc: convert to memory API
    
    Signed-off-by: Avi Kivity <avi at redhat.com>
    Signed-off-by: Anthony Liguori <aliguori at us.ibm.com>

diff --git a/hw/ppc405_uc.c b/hw/ppc405_uc.c
index 68c7cbd..03b2592 100644
--- a/hw/ppc405_uc.c
+++ b/hw/ppc405_uc.c
@@ -28,6 +28,7 @@
 #include "qemu-timer.h"
 #include "sysemu.h"
 #include "qemu-log.h"
+#include "exec-memory.h"
 
 #define DEBUG_OPBA
 #define DEBUG_SDRAM
@@ -259,6 +260,7 @@ static void ppc4xx_pob_init(CPUState *env)
 /* OPB arbitrer */
 typedef struct ppc4xx_opba_t ppc4xx_opba_t;
 struct ppc4xx_opba_t {
+    MemoryRegion io;
     uint8_t cr;
     uint8_t pr;
 };
@@ -357,16 +359,12 @@ static void opba_writel (void *opaque,
     opba_writeb(opaque, addr + 1, value >> 16);
 }
 
-static CPUReadMemoryFunc * const opba_read[] = {
-    &opba_readb,
-    &opba_readw,
-    &opba_readl,
-};
-
-static CPUWriteMemoryFunc * const opba_write[] = {
-    &opba_writeb,
-    &opba_writew,
-    &opba_writel,
+static const MemoryRegionOps opba_ops = {
+    .old_mmio = {
+        .read = { opba_readb, opba_readw, opba_readl, },
+        .write = { opba_writeb, opba_writew, opba_writel, },
+    },
+    .endianness = DEVICE_NATIVE_ENDIAN,
 };
 
 static void ppc4xx_opba_reset (void *opaque)
@@ -381,15 +379,13 @@ static void ppc4xx_opba_reset (void *opaque)
 static void ppc4xx_opba_init(target_phys_addr_t base)
 {
     ppc4xx_opba_t *opba;
-    int io;
 
     opba = g_malloc0(sizeof(ppc4xx_opba_t));
 #ifdef DEBUG_OPBA
     printf("%s: offset " TARGET_FMT_plx "\n", __func__, base);
 #endif
-    io = cpu_register_io_memory(opba_read, opba_write, opba,
-                                DEVICE_NATIVE_ENDIAN);
-    cpu_register_physical_memory(base, 0x002, io);
+    memory_region_init_io(&opba->io, &opba_ops, opba, "opba", 0x002);
+    memory_region_add_subregion(get_system_memory(), base, &opba->io);
     qemu_register_reset(ppc4xx_opba_reset, opba);
 }
 
@@ -722,6 +718,7 @@ static void ppc405_dma_init(CPUState *env, qemu_irq irqs[4])
 /* GPIO */
 typedef struct ppc405_gpio_t ppc405_gpio_t;
 struct ppc405_gpio_t {
+    MemoryRegion io;
     uint32_t or;
     uint32_t tcr;
     uint32_t osrh;
@@ -789,16 +786,12 @@ static void ppc405_gpio_writel (void *opaque,
 #endif
 }
 
-static CPUReadMemoryFunc * const ppc405_gpio_read[] = {
-    &ppc405_gpio_readb,
-    &ppc405_gpio_readw,
-    &ppc405_gpio_readl,
-};
-
-static CPUWriteMemoryFunc * const ppc405_gpio_write[] = {
-    &ppc405_gpio_writeb,
-    &ppc405_gpio_writew,
-    &ppc405_gpio_writel,
+static const MemoryRegionOps ppc405_gpio_ops = {
+    .old_mmio = {
+        .read = { ppc405_gpio_readb, ppc405_gpio_readw, ppc405_gpio_readl, },
+        .write = { ppc405_gpio_writeb, ppc405_gpio_writew, ppc405_gpio_writel, },
+    },
+    .endianness = DEVICE_NATIVE_ENDIAN,
 };
 
 static void ppc405_gpio_reset (void *opaque)
@@ -808,15 +801,13 @@ static void ppc405_gpio_reset (void *opaque)
 static void ppc405_gpio_init(target_phys_addr_t base)
 {
     ppc405_gpio_t *gpio;
-    int io;
 
     gpio = g_malloc0(sizeof(ppc405_gpio_t));
 #ifdef DEBUG_GPIO
     printf("%s: offset " TARGET_FMT_plx "\n", __func__, base);
 #endif
-    io = cpu_register_io_memory(ppc405_gpio_read, ppc405_gpio_write, gpio,
-                                DEVICE_NATIVE_ENDIAN);
-    cpu_register_physical_memory(base, 0x038, io);
+    memory_region_init_io(&gpio->io, &ppc405_gpio_ops, gpio, "pgio", 0x038);
+    memory_region_add_subregion(get_system_memory(), base, &gpio->io);
     qemu_register_reset(&ppc405_gpio_reset, gpio);
 }
 
@@ -831,7 +822,9 @@ enum {
 
 typedef struct ppc405_ocm_t ppc405_ocm_t;
 struct ppc405_ocm_t {
-    target_ulong offset;
+    MemoryRegion ram;
+    MemoryRegion isarc_ram;
+    MemoryRegion dsarc_ram;
     uint32_t isarc;
     uint32_t isacntl;
     uint32_t dsarc;
@@ -854,16 +847,15 @@ static void ocm_update_mappings (ppc405_ocm_t *ocm,
         if (ocm->isacntl & 0x80000000) {
             /* Unmap previously assigned memory region */
             printf("OCM unmap ISA %08" PRIx32 "\n", ocm->isarc);
-            cpu_register_physical_memory(ocm->isarc, 0x04000000,
-                                         IO_MEM_UNASSIGNED);
+            memory_region_del_subregion(get_system_memory(), &ocm->isarc_ram);
         }
         if (isacntl & 0x80000000) {
             /* Map new instruction memory region */
 #ifdef DEBUG_OCM
             printf("OCM map ISA %08" PRIx32 "\n", isarc);
 #endif
-            cpu_register_physical_memory(isarc, 0x04000000,
-                                         ocm->offset | IO_MEM_RAM);
+            memory_region_add_subregion(get_system_memory(), isarc,
+                                        &ocm->isarc_ram);
         }
     }
     if (ocm->dsarc != dsarc ||
@@ -875,8 +867,8 @@ static void ocm_update_mappings (ppc405_ocm_t *ocm,
 #ifdef DEBUG_OCM
                 printf("OCM unmap DSA %08" PRIx32 "\n", ocm->dsarc);
 #endif
-                cpu_register_physical_memory(ocm->dsarc, 0x04000000,
-                                             IO_MEM_UNASSIGNED);
+                memory_region_del_subregion(get_system_memory(),
+                                            &ocm->dsarc_ram);
             }
         }
         if (dsacntl & 0x80000000) {
@@ -886,8 +878,8 @@ static void ocm_update_mappings (ppc405_ocm_t *ocm,
 #ifdef DEBUG_OCM
                 printf("OCM map DSA %08" PRIx32 "\n", dsarc);
 #endif
-                cpu_register_physical_memory(dsarc, 0x04000000,
-                                             ocm->offset | IO_MEM_RAM);
+                memory_region_add_subregion(get_system_memory(), dsarc,
+                                            &ocm->dsarc_ram);
             }
         }
     }
@@ -973,7 +965,10 @@ static void ppc405_ocm_init(CPUState *env)
     ppc405_ocm_t *ocm;
 
     ocm = g_malloc0(sizeof(ppc405_ocm_t));
-    ocm->offset = qemu_ram_alloc(NULL, "ppc405.ocm", 4096);
+    /* XXX: Size is 4096 or 0x04000000 */
+    memory_region_init_ram(&ocm->isarc_ram, NULL, "ppc405.ocm", 4096);
+    memory_region_init_alias(&ocm->dsarc_ram, "ppc405.dsarc", &ocm->isarc_ram,
+                             0, 4096);
     qemu_register_reset(&ocm_reset, ocm);
     ppc_dcr_register(env, OCM0_ISARC,
                      ocm, &dcr_read_ocm, &dcr_write_ocm);
@@ -990,6 +985,7 @@ static void ppc405_ocm_init(CPUState *env)
 typedef struct ppc4xx_i2c_t ppc4xx_i2c_t;
 struct ppc4xx_i2c_t {
     qemu_irq irq;
+    MemoryRegion iomem;
     uint8_t mdata;
     uint8_t lmadr;
     uint8_t hmadr;
@@ -1186,16 +1182,12 @@ static void ppc4xx_i2c_writel (void *opaque,
     ppc4xx_i2c_writeb(opaque, addr + 3, value);
 }
 
-static CPUReadMemoryFunc * const i2c_read[] = {
-    &ppc4xx_i2c_readb,
-    &ppc4xx_i2c_readw,
-    &ppc4xx_i2c_readl,
-};
-
-static CPUWriteMemoryFunc * const i2c_write[] = {
-    &ppc4xx_i2c_writeb,
-    &ppc4xx_i2c_writew,
-    &ppc4xx_i2c_writel,
+static const MemoryRegionOps i2c_ops = {
+    .old_mmio = {
+        .read = { ppc4xx_i2c_readb, ppc4xx_i2c_readw, ppc4xx_i2c_readl, },
+        .write = { ppc4xx_i2c_writeb, ppc4xx_i2c_writew, ppc4xx_i2c_writel, },
+    },
+    .endianness = DEVICE_NATIVE_ENDIAN,
 };
 
 static void ppc4xx_i2c_reset (void *opaque)
@@ -1217,16 +1209,14 @@ static void ppc4xx_i2c_reset (void *opaque)
 static void ppc405_i2c_init(target_phys_addr_t base, qemu_irq irq)
 {
     ppc4xx_i2c_t *i2c;
-    int io;
 
     i2c = g_malloc0(sizeof(ppc4xx_i2c_t));
     i2c->irq = irq;
 #ifdef DEBUG_I2C
     printf("%s: offset " TARGET_FMT_plx "\n", __func__, base);
 #endif
-    io = cpu_register_io_memory(i2c_read, i2c_write, i2c,
-                                DEVICE_NATIVE_ENDIAN);
-    cpu_register_physical_memory(base, 0x011, io);
+    memory_region_init_io(&i2c->iomem, &i2c_ops, i2c, "i2c", 0x011);
+    memory_region_add_subregion(get_system_memory(), base, &i2c->iomem);
     qemu_register_reset(ppc4xx_i2c_reset, i2c);
 }
 
@@ -1234,6 +1224,7 @@ static void ppc405_i2c_init(target_phys_addr_t base, qemu_irq irq)
 /* General purpose timers */
 typedef struct ppc4xx_gpt_t ppc4xx_gpt_t;
 struct ppc4xx_gpt_t {
+    MemoryRegion iomem;
     int64_t tb_offset;
     uint32_t tb_freq;
     struct QEMUTimer *timer;
@@ -1454,16 +1445,12 @@ static void ppc4xx_gpt_writel (void *opaque,
     }
 }
 
-static CPUReadMemoryFunc * const gpt_read[] = {
-    &ppc4xx_gpt_readb,
-    &ppc4xx_gpt_readw,
-    &ppc4xx_gpt_readl,
-};
-
-static CPUWriteMemoryFunc * const gpt_write[] = {
-    &ppc4xx_gpt_writeb,
-    &ppc4xx_gpt_writew,
-    &ppc4xx_gpt_writel,
+static const MemoryRegionOps gpt_ops = {
+    .old_mmio = {
+        .read = { ppc4xx_gpt_readb, ppc4xx_gpt_readw, ppc4xx_gpt_readl, },
+        .write = { ppc4xx_gpt_writeb, ppc4xx_gpt_writew, ppc4xx_gpt_writel, },
+    },
+    .endianness = DEVICE_NATIVE_ENDIAN,
 };
 
 static void ppc4xx_gpt_cb (void *opaque)
@@ -1498,7 +1485,6 @@ static void ppc4xx_gpt_init(target_phys_addr_t base, qemu_irq irqs[5])
 {
     ppc4xx_gpt_t *gpt;
     int i;
-    int io;
 
     gpt = g_malloc0(sizeof(ppc4xx_gpt_t));
     for (i = 0; i < 5; i++) {
@@ -1508,8 +1494,8 @@ static void ppc4xx_gpt_init(target_phys_addr_t base, qemu_irq irqs[5])
 #ifdef DEBUG_GPT
     printf("%s: offset " TARGET_FMT_plx "\n", __func__, base);
 #endif
-    io = cpu_register_io_memory(gpt_read, gpt_write, gpt, DEVICE_NATIVE_ENDIAN);
-    cpu_register_physical_memory(base, 0x0d4, io);
+    memory_region_init_io(&gpt->iomem, &gpt_ops, gpt, "gpt", 0x0d4);
+    memory_region_add_subregion(get_system_memory(), base, &gpt->iomem);
     qemu_register_reset(ppc4xx_gpt_reset, gpt);
 }
 
commit c76f990e8dd90b61dbc83ee0def95c41375b8921
Author: Avi Kivity <avi at redhat.com>
Date:   Mon Aug 15 17:17:25 2011 +0300

    pcie_host: convert to memory API
    
    Assuming that mmcfg size cannot change at runtime.
    
    Signed-off-by: Avi Kivity <avi at redhat.com>
    Signed-off-by: Anthony Liguori <aliguori at us.ibm.com>

diff --git a/hw/pcie_host.c b/hw/pcie_host.c
index f9fea3d..28bbe72 100644
--- a/hw/pcie_host.c
+++ b/hw/pcie_host.c
@@ -22,6 +22,7 @@
 #include "hw.h"
 #include "pci.h"
 #include "pcie_host.h"
+#include "exec-memory.h"
 
 /*
  * PCI express mmcfig address
@@ -52,9 +53,11 @@ static inline PCIDevice *pcie_dev_find_by_mmcfg_addr(PCIBus *s,
                            PCIE_MMCFG_DEVFN(mmcfg_addr));
 }
 
-static void pcie_mmcfg_data_write(PCIBus *s,
-                                  uint32_t mmcfg_addr, uint32_t val, int len)
+static void pcie_mmcfg_data_write(void *opaque, target_phys_addr_t mmcfg_addr,
+                                  uint64_t val, unsigned len)
 {
+    PCIExpressHost *e = opaque;
+    PCIBus *s = e->pci.bus;
     PCIDevice *pci_dev = pcie_dev_find_by_mmcfg_addr(s, mmcfg_addr);
     uint32_t addr;
     uint32_t limit;
@@ -72,8 +75,12 @@ static void pcie_mmcfg_data_write(PCIBus *s,
     pci_host_config_write_common(pci_dev, addr, limit, val, len);
 }
 
-static uint32_t pcie_mmcfg_data_read(PCIBus *s, uint32_t mmcfg_addr, int len)
+static uint64_t pcie_mmcfg_data_read(void *opaque,
+                                     target_phys_addr_t mmcfg_addr,
+                                     unsigned len)
 {
+    PCIExpressHost *e = opaque;
+    PCIBus *s = e->pci.bus;
     PCIDevice *pci_dev = pcie_dev_find_by_mmcfg_addr(s, mmcfg_addr);
     uint32_t addr;
     uint32_t limit;
@@ -91,72 +98,23 @@ static uint32_t pcie_mmcfg_data_read(PCIBus *s, uint32_t mmcfg_addr, int len)
     return pci_host_config_read_common(pci_dev, addr, limit, len);
 }
 
-static void pcie_mmcfg_data_writeb(void *opaque,
-                                   target_phys_addr_t addr, uint32_t value)
-{
-    PCIExpressHost *e = opaque;
-    pcie_mmcfg_data_write(e->pci.bus, addr - e->base_addr, value, 1);
-}
-
-static void pcie_mmcfg_data_writew(void *opaque,
-                                   target_phys_addr_t addr, uint32_t value)
-{
-    PCIExpressHost *e = opaque;
-    pcie_mmcfg_data_write(e->pci.bus, addr - e->base_addr, value, 2);
-}
-
-static void pcie_mmcfg_data_writel(void *opaque,
-                                   target_phys_addr_t addr, uint32_t value)
-{
-    PCIExpressHost *e = opaque;
-    pcie_mmcfg_data_write(e->pci.bus, addr - e->base_addr, value, 4);
-}
-
-static uint32_t pcie_mmcfg_data_readb(void *opaque, target_phys_addr_t addr)
-{
-    PCIExpressHost *e = opaque;
-    return pcie_mmcfg_data_read(e->pci.bus, addr - e->base_addr, 1);
-}
-
-static uint32_t pcie_mmcfg_data_readw(void *opaque, target_phys_addr_t addr)
-{
-    PCIExpressHost *e = opaque;
-    return pcie_mmcfg_data_read(e->pci.bus, addr - e->base_addr, 2);
-}
-
-static uint32_t pcie_mmcfg_data_readl(void *opaque, target_phys_addr_t addr)
-{
-    PCIExpressHost *e = opaque;
-    return pcie_mmcfg_data_read(e->pci.bus, addr - e->base_addr, 4);
-}
-
-
-static CPUWriteMemoryFunc * const pcie_mmcfg_write[] =
-{
-    pcie_mmcfg_data_writeb,
-    pcie_mmcfg_data_writew,
-    pcie_mmcfg_data_writel,
-};
-
-static CPUReadMemoryFunc * const pcie_mmcfg_read[] =
-{
-    pcie_mmcfg_data_readb,
-    pcie_mmcfg_data_readw,
-    pcie_mmcfg_data_readl,
+static const MemoryRegionOps pcie_mmcfg_ops = {
+    .read = pcie_mmcfg_data_read,
+    .write = pcie_mmcfg_data_write,
+    .endianness = DEVICE_NATIVE_ENDIAN,
 };
 
 /* pcie_host::base_addr == PCIE_BASE_ADDR_UNMAPPED when it isn't mapped. */
 #define PCIE_BASE_ADDR_UNMAPPED  ((target_phys_addr_t)-1ULL)
 
-int pcie_host_init(PCIExpressHost *e)
+int pcie_host_init(PCIExpressHost *e, uint32_t size)
 {
+    assert(!(size & (size - 1)));       /* power of 2 */
+    assert(size >= PCIE_MMCFG_SIZE_MIN);
+    assert(size <= PCIE_MMCFG_SIZE_MAX);
     e->base_addr = PCIE_BASE_ADDR_UNMAPPED;
-    e->mmio_index =
-        cpu_register_io_memory(pcie_mmcfg_read, pcie_mmcfg_write, e,
-                               DEVICE_NATIVE_ENDIAN);
-    if (e->mmio_index < 0) {
-        return -1;
-    }
+    e->size = size;
+    memory_region_init_io(&e->mmio, &pcie_mmcfg_ops, e, "pcie-mmcfg", e->size);
 
     return 0;
 }
@@ -164,29 +122,23 @@ int pcie_host_init(PCIExpressHost *e)
 void pcie_host_mmcfg_unmap(PCIExpressHost *e)
 {
     if (e->base_addr != PCIE_BASE_ADDR_UNMAPPED) {
-        cpu_register_physical_memory(e->base_addr, e->size, IO_MEM_UNASSIGNED);
+        memory_region_del_subregion(get_system_memory(), &e->mmio);
         e->base_addr = PCIE_BASE_ADDR_UNMAPPED;
     }
 }
 
-void pcie_host_mmcfg_map(PCIExpressHost *e,
-                         target_phys_addr_t addr, uint32_t size)
+void pcie_host_mmcfg_map(PCIExpressHost *e, target_phys_addr_t addr)
 {
-    assert(!(size & (size - 1)));       /* power of 2 */
-    assert(size >= PCIE_MMCFG_SIZE_MIN);
-    assert(size <= PCIE_MMCFG_SIZE_MAX);
-
     e->base_addr = addr;
-    e->size = size;
-    cpu_register_physical_memory(e->base_addr, e->size, e->mmio_index);
+    memory_region_add_subregion(get_system_memory(), e->base_addr, &e->mmio);
 }
 
 void pcie_host_mmcfg_update(PCIExpressHost *e,
                             int enable,
-                            target_phys_addr_t addr, uint32_t size)
+                            target_phys_addr_t addr)
 {
     pcie_host_mmcfg_unmap(e);
     if (enable) {
-        pcie_host_mmcfg_map(e, addr, size);
+        pcie_host_mmcfg_map(e, addr);
     }
 }
diff --git a/hw/pcie_host.h b/hw/pcie_host.h
index a202661..0074508 100644
--- a/hw/pcie_host.h
+++ b/hw/pcie_host.h
@@ -22,6 +22,7 @@
 #define PCIE_HOST_H
 
 #include "pci_host.h"
+#include "memory.h"
 
 struct PCIExpressHost {
     PCIHostState pci;
@@ -34,16 +35,15 @@ struct PCIExpressHost {
     /* the size of MMCONFIG area. It's host bridge dependent */
     target_phys_addr_t  size;
 
-    /* result of cpu_register_io_memory() to map MMCONFIG area */
-    int mmio_index;
+    /* MMCONFIG mmio area */
+    MemoryRegion mmio;
 };
 
-int pcie_host_init(PCIExpressHost *e);
+int pcie_host_init(PCIExpressHost *e, uint32_t size);
 void pcie_host_mmcfg_unmap(PCIExpressHost *e);
-void pcie_host_mmcfg_map(PCIExpressHost *e,
-                         target_phys_addr_t addr, uint32_t size);
+void pcie_host_mmcfg_map(PCIExpressHost *e, target_phys_addr_t addr);
 void pcie_host_mmcfg_update(PCIExpressHost *e,
                             int enable,
-                            target_phys_addr_t addr, uint32_t size);
+                            target_phys_addr_t addr);
 
 #endif /* PCIE_HOST_H */
commit 689a1921aef42ef2a3da1ca4a406c473a0531aed
Author: Avi Kivity <avi at redhat.com>
Date:   Mon Aug 15 17:17:24 2011 +0300

    onenand: convert to memory API
    
    Signed-off-by: Avi Kivity <avi at redhat.com>
    Signed-off-by: Anthony Liguori <aliguori at us.ibm.com>

diff --git a/hw/onenand.c b/hw/onenand.c
index c37cf59..00276a0 100644
--- a/hw/onenand.c
+++ b/hw/onenand.c
@@ -23,6 +23,8 @@
 #include "flash.h"
 #include "irq.h"
 #include "blockdev.h"
+#include "memory.h"
+#include "exec-memory.h"
 
 /* 11 for 2kB-page OneNAND ("2nd generation") and 10 for 1kB-page chips */
 #define PAGE_SHIFT	11
@@ -45,10 +47,12 @@ typedef struct {
     uint8_t *image;
     uint8_t *otp;
     uint8_t *current;
-    ram_addr_t ram;
+    MemoryRegion ram;
+    MemoryRegion mapped_ram;
     uint8_t *boot[2];
     uint8_t *data[2][2];
-    int iomemtype;
+    MemoryRegion iomem;
+    MemoryRegion container;
     int cycle;
     int otpmode;
 
@@ -100,31 +104,36 @@ enum {
     ONEN_LOCK_UNLOCKED = 1 << 2,
 };
 
+static void onenand_mem_setup(OneNANDState *s)
+{
+    /* XXX: We should use IO_MEM_ROMD but we broke it earlier...
+     * Both 0x0000 ... 0x01ff and 0x8000 ... 0x800f can be used to
+     * write boot commands.  Also take note of the BWPS bit.  */
+    memory_region_init(&s->container, "onenand", 0x10000 << s->shift);
+    memory_region_add_subregion(&s->container, 0, &s->iomem);
+    memory_region_init_alias(&s->mapped_ram, "onenand-mapped-ram",
+                             &s->ram, 0x0200 << s->shift,
+                             0xbe00 << s->shift);
+    memory_region_add_subregion_overlap(&s->container,
+                                        0x0200 << s->shift,
+                                        &s->mapped_ram,
+                                        1);
+}
+
 void onenand_base_update(void *opaque, target_phys_addr_t new)
 {
     OneNANDState *s = (OneNANDState *) opaque;
 
     s->base = new;
 
-    /* XXX: We should use IO_MEM_ROMD but we broke it earlier...
-     * Both 0x0000 ... 0x01ff and 0x8000 ... 0x800f can be used to
-     * write boot commands.  Also take note of the BWPS bit.  */
-    cpu_register_physical_memory(s->base + (0x0000 << s->shift),
-                    0x0200 << s->shift, s->iomemtype);
-    cpu_register_physical_memory(s->base + (0x0200 << s->shift),
-                    0xbe00 << s->shift,
-                    (s->ram +(0x0200 << s->shift)) | IO_MEM_RAM);
-    if (s->iomemtype)
-        cpu_register_physical_memory_offset(s->base + (0xc000 << s->shift),
-                    0x4000 << s->shift, s->iomemtype, (0xc000 << s->shift));
+    memory_region_add_subregion(get_system_memory(), s->base, &s->container);
 }
 
 void onenand_base_unmap(void *opaque)
 {
     OneNANDState *s = (OneNANDState *) opaque;
 
-    cpu_register_physical_memory(s->base,
-                    0x10000 << s->shift, IO_MEM_UNASSIGNED);
+    memory_region_del_subregion(get_system_memory(), &s->container);
 }
 
 static void onenand_intr_update(OneNANDState *s)
@@ -524,7 +533,8 @@ static void onenand_command(OneNANDState *s, int cmd)
     onenand_intr_update(s);
 }
 
-static uint32_t onenand_read(void *opaque, target_phys_addr_t addr)
+static uint64_t onenand_read(void *opaque, target_phys_addr_t addr,
+                             unsigned size)
 {
     OneNANDState *s = (OneNANDState *) opaque;
     int offset = addr >> s->shift;
@@ -589,7 +599,7 @@ static uint32_t onenand_read(void *opaque, target_phys_addr_t addr)
 }
 
 static void onenand_write(void *opaque, target_phys_addr_t addr,
-                uint32_t value)
+                          uint64_t value, unsigned size)
 {
     OneNANDState *s = (OneNANDState *) opaque;
     int offset = addr >> s->shift;
@@ -628,7 +638,7 @@ static void onenand_write(void *opaque, target_phys_addr_t addr,
             break;
 
         default:
-            fprintf(stderr, "%s: unknown OneNAND boot command %x\n",
+            fprintf(stderr, "%s: unknown OneNAND boot command %"PRIx64"\n",
                             __FUNCTION__, value);
         }
         break;
@@ -684,16 +694,10 @@ static void onenand_write(void *opaque, target_phys_addr_t addr,
     }
 }
 
-static CPUReadMemoryFunc * const onenand_readfn[] = {
-    onenand_read,	/* TODO */
-    onenand_read,
-    onenand_read,
-};
-
-static CPUWriteMemoryFunc * const onenand_writefn[] = {
-    onenand_write,	/* TODO */
-    onenand_write,
-    onenand_write,
+static const MemoryRegionOps onenand_ops = {
+    .read = onenand_read,
+    .write = onenand_write,
+    .endianness = DEVICE_NATIVE_ENDIAN,
 };
 
 void *onenand_init(BlockDriverState *bdrv,
@@ -714,8 +718,8 @@ void *onenand_init(BlockDriverState *bdrv,
     s->secs = size >> 9;
     s->blockwp = g_malloc(s->blocks);
     s->density_mask = (dev_id & 0x08) ? (1 << (6 + ((dev_id >> 4) & 7))) : 0;
-    s->iomemtype = cpu_register_io_memory(onenand_readfn,
-                    onenand_writefn, s, DEVICE_NATIVE_ENDIAN);
+    memory_region_init_io(&s->iomem, &onenand_ops, s, "onenand",
+                          0x10000 << s->shift);
     s->bdrv = bdrv;
     if (!s->bdrv) {
         s->image = memset(g_malloc(size + (size >> 5)),
@@ -723,14 +727,15 @@ void *onenand_init(BlockDriverState *bdrv,
     }
     s->otp = memset(g_malloc((64 + 2) << PAGE_SHIFT),
                     0xff, (64 + 2) << PAGE_SHIFT);
-    s->ram = qemu_ram_alloc(NULL, "onenand.ram", 0xc000 << s->shift);
-    ram = qemu_get_ram_ptr(s->ram);
+    memory_region_init_ram(&s->ram, NULL, "onenand.ram", 0xc000 << s->shift);
+    ram = memory_region_get_ram_ptr(&s->ram);
     s->boot[0] = ram + (0x0000 << s->shift);
     s->boot[1] = ram + (0x8000 << s->shift);
     s->data[0][0] = ram + ((0x0200 + (0 << (PAGE_SHIFT - 1))) << s->shift);
     s->data[0][1] = ram + ((0x8010 + (0 << (PAGE_SHIFT - 6))) << s->shift);
     s->data[1][0] = ram + ((0x0200 + (1 << (PAGE_SHIFT - 1))) << s->shift);
     s->data[1][1] = ram + ((0x8010 + (1 << (PAGE_SHIFT - 6))) << s->shift);
+    onenand_mem_setup(s);
 
     onenand_reset(s, 1);
 
commit 64066a8fb6ed08c542d919552a02fd0fdf22cc2c
Author: Avi Kivity <avi at redhat.com>
Date:   Mon Aug 15 17:17:23 2011 +0300

    omap_gpmc/nseries/tusb6010: convert to memory API
    
    Somewhat clumsy since it needs a variable sized region.
    
    Signed-off-by: Avi Kivity <avi at redhat.com>
    Signed-off-by: Anthony Liguori <aliguori at us.ibm.com>

diff --git a/hw/omap.h b/hw/omap.h
index 2a6d589..db101c6 100644
--- a/hw/omap.h
+++ b/hw/omap.h
@@ -17,6 +17,7 @@
  * with this program; if not, see <http://www.gnu.org/licenses/>.
  */
 #ifndef hw_omap_h
+#include "memory.h"
 # define hw_omap_h		"omap.h"
 
 # define OMAP_EMIFS_BASE	0x00000000
@@ -119,7 +120,7 @@ void omap_sdrc_reset(struct omap_sdrc_s *s);
 struct omap_gpmc_s;
 struct omap_gpmc_s *omap_gpmc_init(target_phys_addr_t base, qemu_irq irq);
 void omap_gpmc_reset(struct omap_gpmc_s *s);
-void omap_gpmc_attach(struct omap_gpmc_s *s, int cs, int iomemtype,
+void omap_gpmc_attach(struct omap_gpmc_s *s, int cs, MemoryRegion *iomem,
                 void (*base_upd)(void *opaque, target_phys_addr_t new),
                 void (*unmap)(void *opaque), void *opaque);
 
diff --git a/hw/omap_gpmc.c b/hw/omap_gpmc.c
index 13e3e00..922d622 100644
--- a/hw/omap_gpmc.c
+++ b/hw/omap_gpmc.c
@@ -21,10 +21,13 @@
 #include "hw.h"
 #include "flash.h"
 #include "omap.h"
+#include "memory.h"
+#include "exec-memory.h"
 
 /* General-Purpose Memory Controller */
 struct omap_gpmc_s {
     qemu_irq irq;
+    MemoryRegion iomem;
 
     uint8_t sysconfig;
     uint16_t irqst;
@@ -39,7 +42,8 @@ struct omap_gpmc_s {
         uint32_t config[7];
         target_phys_addr_t base;
         size_t size;
-        int iomemtype;
+        MemoryRegion *iomem;
+        MemoryRegion container;
         void (*base_update)(void *opaque, target_phys_addr_t new);
         void (*unmap)(void *opaque);
         void *opaque;
@@ -75,8 +79,12 @@ static void omap_gpmc_cs_map(struct omap_gpmc_cs_file_s *f, int base, int mask)
      * constant), the mask should cause wrapping of the address space, so
      * that the same memory becomes accessible at every <i>size</i> bytes
      * starting from <i>base</i>.  */
-    if (f->iomemtype)
-        cpu_register_physical_memory(f->base, f->size, f->iomemtype);
+    if (f->iomem) {
+        memory_region_init(&f->container, "omap-gpmc-file", f->size);
+        memory_region_add_subregion(&f->container, 0, f->iomem);
+        memory_region_add_subregion(get_system_memory(), f->base,
+                                    &f->container);
+    }
 
     if (f->base_update)
         f->base_update(f->opaque, f->base);
@@ -87,8 +95,11 @@ static void omap_gpmc_cs_unmap(struct omap_gpmc_cs_file_s *f)
     if (f->size) {
         if (f->unmap)
             f->unmap(f->opaque);
-        if (f->iomemtype)
-            cpu_register_physical_memory(f->base, f->size, IO_MEM_UNASSIGNED);
+        if (f->iomem) {
+            memory_region_del_subregion(get_system_memory(), &f->container);
+            memory_region_del_subregion(&f->container, f->iomem);
+            memory_region_destroy(&f->container);
+        }
         f->base = 0;
         f->size = 0;
     }
@@ -132,12 +143,17 @@ void omap_gpmc_reset(struct omap_gpmc_s *s)
         ecc_reset(&s->ecc[i]);
 }
 
-static uint32_t omap_gpmc_read(void *opaque, target_phys_addr_t addr)
+static uint64_t omap_gpmc_read(void *opaque, target_phys_addr_t addr,
+                               unsigned size)
 {
     struct omap_gpmc_s *s = (struct omap_gpmc_s *) opaque;
     int cs;
     struct omap_gpmc_cs_file_s *f;
 
+    if (size != 4) {
+        return omap_badwidth_read32(opaque, addr);
+    }
+
     switch (addr) {
     case 0x000:	/* GPMC_REVISION */
         return 0x20;
@@ -230,12 +246,16 @@ static uint32_t omap_gpmc_read(void *opaque, target_phys_addr_t addr)
 }
 
 static void omap_gpmc_write(void *opaque, target_phys_addr_t addr,
-                uint32_t value)
+                            uint64_t value, unsigned size)
 {
     struct omap_gpmc_s *s = (struct omap_gpmc_s *) opaque;
     int cs;
     struct omap_gpmc_cs_file_s *f;
 
+    if (size != 4) {
+        return omap_badwidth_write32(opaque, addr, value);
+    }
+
     switch (addr) {
     case 0x000:	/* GPMC_REVISION */
     case 0x014:	/* GPMC_SYSSTATUS */
@@ -249,7 +269,7 @@ static void omap_gpmc_write(void *opaque, target_phys_addr_t addr,
 
     case 0x010:	/* GPMC_SYSCONFIG */
         if ((value >> 3) == 0x3)
-            fprintf(stderr, "%s: bad SDRAM idle mode %i\n",
+            fprintf(stderr, "%s: bad SDRAM idle mode %"PRIi64"\n",
                             __FUNCTION__, value >> 3);
         if (value & 2)
             omap_gpmc_reset(s);
@@ -369,34 +389,26 @@ static void omap_gpmc_write(void *opaque, target_phys_addr_t addr,
     }
 }
 
-static CPUReadMemoryFunc * const omap_gpmc_readfn[] = {
-    omap_badwidth_read32,	/* TODO */
-    omap_badwidth_read32,	/* TODO */
-    omap_gpmc_read,
-};
-
-static CPUWriteMemoryFunc * const omap_gpmc_writefn[] = {
-    omap_badwidth_write32,	/* TODO */
-    omap_badwidth_write32,	/* TODO */
-    omap_gpmc_write,
+static const MemoryRegionOps omap_gpmc_ops = {
+    .read = omap_gpmc_read,
+    .write = omap_gpmc_write,
+    .endianness = DEVICE_NATIVE_ENDIAN,
 };
 
 struct omap_gpmc_s *omap_gpmc_init(target_phys_addr_t base, qemu_irq irq)
 {
-    int iomemtype;
     struct omap_gpmc_s *s = (struct omap_gpmc_s *)
             g_malloc0(sizeof(struct omap_gpmc_s));
 
     omap_gpmc_reset(s);
 
-    iomemtype = cpu_register_io_memory(omap_gpmc_readfn,
-                    omap_gpmc_writefn, s, DEVICE_NATIVE_ENDIAN);
-    cpu_register_physical_memory(base, 0x1000, iomemtype);
+    memory_region_init_io(&s->iomem, &omap_gpmc_ops, s, "omap-gpmc", 0x1000);
+    memory_region_add_subregion(get_system_memory(), base, &s->iomem);
 
     return s;
 }
 
-void omap_gpmc_attach(struct omap_gpmc_s *s, int cs, int iomemtype,
+void omap_gpmc_attach(struct omap_gpmc_s *s, int cs, MemoryRegion *iomem,
                 void (*base_upd)(void *opaque, target_phys_addr_t new),
                 void (*unmap)(void *opaque), void *opaque)
 {
@@ -408,7 +420,7 @@ void omap_gpmc_attach(struct omap_gpmc_s *s, int cs, int iomemtype,
     }
     f = &s->cs_file[cs];
 
-    f->iomemtype = iomemtype;
+    f->iomem = iomem;
     f->base_update = base_upd;
     f->unmap = unmap;
     f->opaque = opaque;
diff --git a/hw/tusb6010.c b/hw/tusb6010.c
index 925136b..b2bf359 100644
--- a/hw/tusb6010.c
+++ b/hw/tusb6010.c
@@ -26,7 +26,7 @@
 #include "tusb6010.h"
 
 struct TUSBState {
-    int iomemtype[2];
+    MemoryRegion iomem[2];
     qemu_irq irq;
     MUSBState *musb;
     QEMUTimer *otg_timer;
@@ -234,14 +234,14 @@ struct TUSBState {
 #define TUSB_EP_CONFIG_XFR_SIZE(v)	((v) & 0x7fffffff)
 #define TUSB_PROD_TEST_RESET_VAL	0xa596
 
-int tusb6010_sync_io(TUSBState *s)
+MemoryRegion *tusb6010_sync_io(TUSBState *s)
 {
-    return s->iomemtype[0];
+    return &s->iomem[0];
 }
 
-int tusb6010_async_io(TUSBState *s)
+MemoryRegion *tusb6010_async_io(TUSBState *s)
 {
-    return s->iomemtype[1];
+    return &s->iomem[1];
 }
 
 static void tusb_intr_update(TUSBState *s)
@@ -647,16 +647,12 @@ static void tusb_async_writew(void *opaque, target_phys_addr_t addr,
     }
 }
 
-static CPUReadMemoryFunc * const tusb_async_readfn[] = {
-    tusb_async_readb,
-    tusb_async_readh,
-    tusb_async_readw,
-};
-
-static CPUWriteMemoryFunc * const tusb_async_writefn[] = {
-    tusb_async_writeb,
-    tusb_async_writeh,
-    tusb_async_writew,
+static const MemoryRegionOps tusb_async_ops = {
+    .old_mmio = {
+        .read = { tusb_async_readb, tusb_async_readh, tusb_async_readw, },
+        .write =  { tusb_async_writeb, tusb_async_writeh, tusb_async_writew, },
+    },
+    .endianness = DEVICE_NATIVE_ENDIAN,
 };
 
 static void tusb_otg_tick(void *opaque)
@@ -739,8 +735,8 @@ TUSBState *tusb6010_init(qemu_irq intr)
     s->mask = 0xffffffff;
     s->intr = 0x00000000;
     s->otg_timer_val = 0;
-    s->iomemtype[1] = cpu_register_io_memory(tusb_async_readfn,
-                    tusb_async_writefn, s, DEVICE_NATIVE_ENDIAN);
+    memory_region_init_io(&s->iomem[1], &tusb_async_ops, s, "tusb-async",
+                          UINT32_MAX);
     s->irq = intr;
     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);
diff --git a/hw/tusb6010.h b/hw/tusb6010.h
index ebb3584..b85ee86 100644
--- a/hw/tusb6010.h
+++ b/hw/tusb6010.h
@@ -16,10 +16,13 @@
 #ifndef TUSB6010_H
 #define TUSB6010_H
 
+#include "targphys.h"
+#include "memory.h"
+
 typedef struct TUSBState TUSBState;
 TUSBState *tusb6010_init(qemu_irq intr);
-int tusb6010_sync_io(TUSBState *s);
-int tusb6010_async_io(TUSBState *s);
+MemoryRegion *tusb6010_sync_io(TUSBState *s);
+MemoryRegion *tusb6010_async_io(TUSBState *s);
 void tusb6010_power(TUSBState *s, int on);
 
 #endif
commit d09871f69c1863e6683d7c62a72b2d1a98e6d639
Author: Avi Kivity <avi at redhat.com>
Date:   Mon Aug 15 17:17:22 2011 +0300

    tusb6010: move declarations to new file tusb6010.h
    
    Avoid #include hell.
    
    Signed-off-by: Avi Kivity <avi at redhat.com>
    Signed-off-by: Anthony Liguori <aliguori at us.ibm.com>

diff --git a/hw/devices.h b/hw/devices.h
index c788373..07fda83 100644
--- a/hw/devices.h
+++ b/hw/devices.h
@@ -47,13 +47,6 @@ void *tahvo_init(qemu_irq irq, int betty);
 
 void retu_key_event(void *retu, int state);
 
-/* tusb6010.c */
-typedef struct TUSBState TUSBState;
-TUSBState *tusb6010_init(qemu_irq intr);
-int tusb6010_sync_io(TUSBState *s);
-int tusb6010_async_io(TUSBState *s);
-void tusb6010_power(TUSBState *s, int on);
-
 /* tc6393xb.c */
 typedef struct TC6393xbState TC6393xbState;
 #define TC6393XB_RAM	0x110000 /* amount of ram for Video and USB */
diff --git a/hw/nseries.c b/hw/nseries.c
index 144fd5a..f7aae7a 100644
--- a/hw/nseries.c
+++ b/hw/nseries.c
@@ -32,6 +32,7 @@
 #include "bt.h"
 #include "loader.h"
 #include "blockdev.h"
+#include "tusb6010.h"
 
 /* Nokia N8x0 support */
 struct n800_s {
diff --git a/hw/tusb6010.c b/hw/tusb6010.c
index d7ae527..925136b 100644
--- a/hw/tusb6010.c
+++ b/hw/tusb6010.c
@@ -23,7 +23,7 @@
 #include "usb.h"
 #include "omap.h"
 #include "irq.h"
-#include "devices.h"
+#include "tusb6010.h"
 
 struct TUSBState {
     int iomemtype[2];
diff --git a/hw/tusb6010.h b/hw/tusb6010.h
new file mode 100644
index 0000000..ebb3584
--- /dev/null
+++ b/hw/tusb6010.h
@@ -0,0 +1,25 @@
+/*
+ * tusb6010 interfaces
+ *
+ * Copyright 2011 Red Hat, Inc. and/or its affiliates
+ *
+ * Authors:
+ *  Avi Kivity <avi at redhat.com>
+ *
+ * Derived from hw/devices.h.
+ *
+ * This work is licensed under the terms of the GNU GPL, version 2.  See
+ * the COPYING file in the top-level directory.
+ *
+ */
+
+#ifndef TUSB6010_H
+#define TUSB6010_H
+
+typedef struct TUSBState TUSBState;
+TUSBState *tusb6010_init(qemu_irq intr);
+int tusb6010_sync_io(TUSBState *s);
+int tusb6010_async_io(TUSBState *s);
+void tusb6010_power(TUSBState *s, int on);
+
+#endif
commit fc2bf44972349b078d8310466c3866615500e67f
Author: Avi Kivity <avi at redhat.com>
Date:   Mon Aug 15 17:17:21 2011 +0300

    gt64xxx.c: convert to memory API
    
    Signed-off-by: Avi Kivity <avi at redhat.com>
    Signed-off-by: Anthony Liguori <aliguori at us.ibm.com>

diff --git a/hw/gt64xxx.c b/hw/gt64xxx.c
index d541558..6af9782 100644
--- a/hw/gt64xxx.c
+++ b/hw/gt64xxx.c
@@ -227,7 +227,7 @@
 #define PCI_MAPPING_ENTRY(regname)            \
     target_phys_addr_t regname ##_start;      \
     target_phys_addr_t regname ##_length;     \
-    int regname ##_handle
+    MemoryRegion regname ##_mem
 
 typedef struct GT64120State {
     SysBusDevice busdev;
@@ -269,9 +269,9 @@ static void gt64120_isd_mapping(GT64120State *s)
     target_phys_addr_t start = s->regs[GT_ISD] << 21;
     target_phys_addr_t length = 0x1000;
 
-    if (s->ISD_length)
-        cpu_register_physical_memory(s->ISD_start, s->ISD_length,
-                                     IO_MEM_UNASSIGNED);
+    if (s->ISD_length) {
+        memory_region_del_subregion(get_system_memory(), &s->ISD_mem);
+    }
     check_reserved_space(&start, &length);
     length = 0x1000;
     /* Map new address */
@@ -279,7 +279,7 @@ static void gt64120_isd_mapping(GT64120State *s)
             length, start, s->ISD_handle);
     s->ISD_start = start;
     s->ISD_length = length;
-    cpu_register_physical_memory(s->ISD_start, s->ISD_length, s->ISD_handle);
+    memory_region_add_subregion(get_system_memory(), s->ISD_start, &s->ISD_mem);
 }
 
 static void gt64120_pci_mapping(GT64120State *s)
@@ -290,7 +290,8 @@ static void gt64120_pci_mapping(GT64120State *s)
       /* Unmap old IO address */
       if (s->PCI0IO_length)
       {
-        cpu_register_physical_memory(s->PCI0IO_start, s->PCI0IO_length, IO_MEM_UNASSIGNED);
+          memory_region_del_subregion(get_system_memory(), &s->PCI0IO_mem);
+          memory_region_destroy(&s->PCI0IO_mem);
       }
       /* Map new IO address */
       s->PCI0IO_start = s->regs[GT_PCI0IOLD] << 21;
@@ -301,7 +302,7 @@ static void gt64120_pci_mapping(GT64120State *s)
 }
 
 static void gt64120_writel (void *opaque, target_phys_addr_t addr,
-                            uint32_t val)
+                            uint64_t val, unsigned size)
 {
     GT64120State *s = opaque;
     uint32_t saddr;
@@ -579,8 +580,8 @@ static void gt64120_writel (void *opaque, target_phys_addr_t addr,
     }
 }
 
-static uint32_t gt64120_readl (void *opaque,
-                               target_phys_addr_t addr)
+static uint64_t gt64120_readl (void *opaque,
+                               target_phys_addr_t addr, unsigned size)
 {
     GT64120State *s = opaque;
     uint32_t val;
@@ -851,16 +852,10 @@ static uint32_t gt64120_readl (void *opaque,
     return val;
 }
 
-static CPUWriteMemoryFunc * const gt64120_write[] = {
-    &gt64120_writel,
-    &gt64120_writel,
-    &gt64120_writel,
-};
-
-static CPUReadMemoryFunc * const gt64120_read[] = {
-    &gt64120_readl,
-    &gt64120_readl,
-    &gt64120_readl,
+static const MemoryRegionOps isd_mem_ops = {
+    .read = gt64120_readl,
+    .write = gt64120_writel,
+    .endianness = DEVICE_NATIVE_ENDIAN,
 };
 
 static int gt64120_pci_map_irq(PCIDevice *pci_dev, int irq_num)
@@ -1097,8 +1092,7 @@ PCIBus *gt64120_register(qemu_irq *pic)
                                   get_system_memory(),
                                   get_system_io(),
                                   PCI_DEVFN(18, 0), 4);
-    d->ISD_handle = cpu_register_io_memory(gt64120_read, gt64120_write, d,
-                                           DEVICE_NATIVE_ENDIAN);
+    memory_region_init_io(&d->ISD_mem, &isd_mem_ops, d, "isd-mem", 0x1000);
 
     pci_create_simple(d->pci.bus, PCI_DEVFN(0, 0), "gt64120_pci");
     return d->pci.bus;
commit f69bf9d41c2432f4021afb25830f19b0b813dc42
Author: Avi Kivity <avi at redhat.com>
Date:   Mon Aug 15 17:17:20 2011 +0300

    armv7m: convert to memory API
    
    Signed-off-by: Avi Kivity <avi at redhat.com>
    Signed-off-by: Anthony Liguori <aliguori at us.ibm.com>

diff --git a/hw/armv7m.c b/hw/armv7m.c
index 83f3393..a932f16 100644
--- a/hw/armv7m.c
+++ b/hw/armv7m.c
@@ -106,31 +106,27 @@ static void bitband_writel(void *opaque, target_phys_addr_t offset,
     cpu_physical_memory_write(addr, (uint8_t *)&v, 4);
 }
 
-static CPUReadMemoryFunc * const bitband_readfn[] = {
-   bitband_readb,
-   bitband_readw,
-   bitband_readl
-};
-
-static CPUWriteMemoryFunc * const bitband_writefn[] = {
-   bitband_writeb,
-   bitband_writew,
-   bitband_writel
+static const MemoryRegionOps bitband_ops = {
+    .old_mmio = {
+        .read = { bitband_readb, bitband_readw, bitband_readl, },
+        .write = { bitband_writeb, bitband_writew, bitband_writel, },
+    },
+    .endianness = DEVICE_NATIVE_ENDIAN,
 };
 
 typedef struct {
     SysBusDevice busdev;
+    MemoryRegion iomem;
     uint32_t base;
 } BitBandState;
 
 static int bitband_init(SysBusDevice *dev)
 {
     BitBandState *s = FROM_SYSBUS(BitBandState, dev);
-    int iomemtype;
 
-    iomemtype = cpu_register_io_memory(bitband_readfn, bitband_writefn,
-                                       &s->base, DEVICE_NATIVE_ENDIAN);
-    sysbus_init_mmio(dev, 0x02000000, iomemtype);
+    memory_region_init_io(&s->iomem, &bitband_ops, &s->base, "bitband",
+                          0x02000000);
+    sysbus_init_mmio_region(dev, &s->iomem);
     return 0;
 }
 
commit e219dea2f37448adb38875ae41391f8ba8601467
Author: Avi Kivity <avi at redhat.com>
Date:   Mon Aug 15 17:17:19 2011 +0300

    arm_timer: convert to memory API
    
    Signed-off-by: Avi Kivity <avi at redhat.com>
    Signed-off-by: Anthony Liguori <aliguori at us.ibm.com>

diff --git a/hw/arm_timer.c b/hw/arm_timer.c
index f2832f9..09a4b24 100644
--- a/hw/arm_timer.c
+++ b/hw/arm_timer.c
@@ -176,6 +176,7 @@ static arm_timer_state *arm_timer_init(uint32_t freq)
 
 typedef struct {
     SysBusDevice busdev;
+    MemoryRegion iomem;
     arm_timer_state *timer[2];
     int level[2];
     qemu_irq irq;
@@ -190,7 +191,8 @@ static void sp804_set_irq(void *opaque, int irq, int level)
     qemu_set_irq(s->irq, s->level[0] || s->level[1]);
 }
 
-static uint32_t sp804_read(void *opaque, target_phys_addr_t offset)
+static uint64_t sp804_read(void *opaque, target_phys_addr_t offset,
+                           unsigned size)
 {
     sp804_state *s = (sp804_state *)opaque;
 
@@ -203,7 +205,7 @@ static uint32_t sp804_read(void *opaque, target_phys_addr_t offset)
 }
 
 static void sp804_write(void *opaque, target_phys_addr_t offset,
-                        uint32_t value)
+                        uint64_t value, unsigned size)
 {
     sp804_state *s = (sp804_state *)opaque;
 
@@ -214,19 +216,12 @@ static void sp804_write(void *opaque, target_phys_addr_t offset,
     }
 }
 
-static CPUReadMemoryFunc * const sp804_readfn[] = {
-   sp804_read,
-   sp804_read,
-   sp804_read
+static const MemoryRegionOps sp804_ops = {
+    .read = sp804_read,
+    .write = sp804_write,
+    .endianness = DEVICE_NATIVE_ENDIAN,
 };
 
-static CPUWriteMemoryFunc * const sp804_writefn[] = {
-   sp804_write,
-   sp804_write,
-   sp804_write
-};
-
-
 static const VMStateDescription vmstate_sp804 = {
     .name = "sp804",
     .version_id = 1,
@@ -240,7 +235,6 @@ static const VMStateDescription vmstate_sp804 = {
 
 static int sp804_init(SysBusDevice *dev)
 {
-    int iomemtype;
     sp804_state *s = FROM_SYSBUS(sp804_state, dev);
     qemu_irq *qi;
 
@@ -252,9 +246,8 @@ static int sp804_init(SysBusDevice *dev)
     s->timer[1] = arm_timer_init(1000000);
     s->timer[0]->irq = qi[0];
     s->timer[1]->irq = qi[1];
-    iomemtype = cpu_register_io_memory(sp804_readfn,
-                                       sp804_writefn, s, DEVICE_NATIVE_ENDIAN);
-    sysbus_init_mmio(dev, 0x1000, iomemtype);
+    memory_region_init_io(&s->iomem, &sp804_ops, s, "sp804", 0x1000);
+    sysbus_init_mmio_region(dev, &s->iomem);
     vmstate_register(&dev->qdev, -1, &vmstate_sp804, s);
     return 0;
 }
@@ -264,10 +257,12 @@ static int sp804_init(SysBusDevice *dev)
 
 typedef struct {
     SysBusDevice busdev;
+    MemoryRegion iomem;
     arm_timer_state *timer[3];
 } icp_pit_state;
 
-static uint32_t icp_pit_read(void *opaque, target_phys_addr_t offset)
+static uint64_t icp_pit_read(void *opaque, target_phys_addr_t offset,
+                             unsigned size)
 {
     icp_pit_state *s = (icp_pit_state *)opaque;
     int n;
@@ -282,7 +277,7 @@ static uint32_t icp_pit_read(void *opaque, target_phys_addr_t offset)
 }
 
 static void icp_pit_write(void *opaque, target_phys_addr_t offset,
-                          uint32_t value)
+                          uint64_t value, unsigned size)
 {
     icp_pit_state *s = (icp_pit_state *)opaque;
     int n;
@@ -295,22 +290,14 @@ static void icp_pit_write(void *opaque, target_phys_addr_t offset,
     arm_timer_write(s->timer[n], offset & 0xff, value);
 }
 
-
-static CPUReadMemoryFunc * const icp_pit_readfn[] = {
-   icp_pit_read,
-   icp_pit_read,
-   icp_pit_read
-};
-
-static CPUWriteMemoryFunc * const icp_pit_writefn[] = {
-   icp_pit_write,
-   icp_pit_write,
-   icp_pit_write
+static const MemoryRegionOps icp_pit_ops = {
+    .read = icp_pit_read,
+    .write = icp_pit_write,
+    .endianness = DEVICE_NATIVE_ENDIAN,
 };
 
 static int icp_pit_init(SysBusDevice *dev)
 {
-    int iomemtype;
     icp_pit_state *s = FROM_SYSBUS(icp_pit_state, dev);
 
     /* Timer 0 runs at the system clock speed (40MHz).  */
@@ -323,10 +310,8 @@ static int icp_pit_init(SysBusDevice *dev)
     sysbus_init_irq(dev, &s->timer[1]->irq);
     sysbus_init_irq(dev, &s->timer[2]->irq);
 
-    iomemtype = cpu_register_io_memory(icp_pit_readfn,
-                                       icp_pit_writefn, s,
-                                       DEVICE_NATIVE_ENDIAN);
-    sysbus_init_mmio(dev, 0x1000, iomemtype);
+    memory_region_init_io(&s->iomem, &icp_pit_ops, s, "icp_pit", 0x1000);
+    sysbus_init_mmio_region(dev, &s->iomem);
     /* This device has no state to save/restore.  The component timers will
        save themselves.  */
     return 0;
commit 460d7c53cdb0901457c0e1c5194fcdca40bf50ad
Author: Avi Kivity <avi at redhat.com>
Date:   Mon Aug 15 17:17:18 2011 +0300

    arm_sysctl: convert to memory API
    
    Signed-off-by: Avi Kivity <avi at redhat.com>
    Signed-off-by: Anthony Liguori <aliguori at us.ibm.com>

diff --git a/hw/arm_sysctl.c b/hw/arm_sysctl.c
index 22c62df..17cf6f7 100644
--- a/hw/arm_sysctl.c
+++ b/hw/arm_sysctl.c
@@ -17,6 +17,7 @@
 
 typedef struct {
     SysBusDevice busdev;
+    MemoryRegion iomem;
     qemu_irq pl110_mux_ctrl;
 
     uint32_t sys_id;
@@ -91,7 +92,8 @@ static void arm_sysctl_reset(DeviceState *d)
     }
 }
 
-static uint32_t arm_sysctl_read(void *opaque, target_phys_addr_t offset)
+static uint64_t arm_sysctl_read(void *opaque, target_phys_addr_t offset,
+                                unsigned size)
 {
     arm_sysctl_state *s = (arm_sysctl_state *)opaque;
 
@@ -188,7 +190,7 @@ static uint32_t arm_sysctl_read(void *opaque, target_phys_addr_t offset)
 }
 
 static void arm_sysctl_write(void *opaque, target_phys_addr_t offset,
-                          uint32_t val)
+                             uint64_t val, unsigned size)
 {
     arm_sysctl_state *s = (arm_sysctl_state *)opaque;
 
@@ -327,16 +329,10 @@ static void arm_sysctl_write(void *opaque, target_phys_addr_t offset,
     }
 }
 
-static CPUReadMemoryFunc * const arm_sysctl_readfn[] = {
-   arm_sysctl_read,
-   arm_sysctl_read,
-   arm_sysctl_read
-};
-
-static CPUWriteMemoryFunc * const arm_sysctl_writefn[] = {
-   arm_sysctl_write,
-   arm_sysctl_write,
-   arm_sysctl_write
+static const MemoryRegionOps arm_sysctl_ops = {
+    .read = arm_sysctl_read,
+    .write = arm_sysctl_write,
+    .endianness = DEVICE_NATIVE_ENDIAN,
 };
 
 static void arm_sysctl_gpio_set(void *opaque, int line, int level)
@@ -370,12 +366,9 @@ static void arm_sysctl_gpio_set(void *opaque, int line, int level)
 static int arm_sysctl_init1(SysBusDevice *dev)
 {
     arm_sysctl_state *s = FROM_SYSBUS(arm_sysctl_state, dev);
-    int iomemtype;
 
-    iomemtype = cpu_register_io_memory(arm_sysctl_readfn,
-                                       arm_sysctl_writefn, s,
-                                       DEVICE_NATIVE_ENDIAN);
-    sysbus_init_mmio(dev, 0x1000, iomemtype);
+    memory_region_init_io(&s->iomem, &arm_sysctl_ops, s, "arm-sysctl", 0x1000);
+    sysbus_init_mmio_region(dev, &s->iomem);
     qdev_init_gpio_in(&s->busdev.qdev, arm_sysctl_gpio_set, 2);
     qdev_init_gpio_out(&s->busdev.qdev, &s->pl110_mux_ctrl, 1);
     return 0;
commit 755c08022507c451d33135eca2a0d2c8a8b78286
Author: Avi Kivity <avi at redhat.com>
Date:   Mon Aug 15 17:17:17 2011 +0300

    arm_gic: convert to memory API
    
    Signed-off-by: Avi Kivity <avi at redhat.com>
    Signed-off-by: Anthony Liguori <aliguori at us.ibm.com>

diff --git a/hw/arm_gic.c b/hw/arm_gic.c
index fb07314..83213dd 100644
--- a/hw/arm_gic.c
+++ b/hw/arm_gic.c
@@ -104,7 +104,7 @@ typedef struct gic_state
     int num_cpu;
 #endif
 
-    int iomemtype;
+    MemoryRegion iomem;
 } gic_state;
 
 /* TODO: Many places that call this routine could be optimized.  */
@@ -567,16 +567,12 @@ static void gic_dist_writel(void *opaque, target_phys_addr_t offset,
     gic_dist_writew(opaque, offset + 2, value >> 16);
 }
 
-static CPUReadMemoryFunc * const gic_dist_readfn[] = {
-   gic_dist_readb,
-   gic_dist_readw,
-   gic_dist_readl
-};
-
-static CPUWriteMemoryFunc * const gic_dist_writefn[] = {
-   gic_dist_writeb,
-   gic_dist_writew,
-   gic_dist_writel
+static const MemoryRegionOps gic_dist_ops = {
+    .old_mmio = {
+        .read = { gic_dist_readb, gic_dist_readw, gic_dist_readl, },
+        .write = { gic_dist_writeb, gic_dist_writew, gic_dist_writel, },
+    },
+    .endianness = DEVICE_NATIVE_ENDIAN,
 };
 
 #ifndef NVIC
@@ -741,9 +737,7 @@ static void gic_init(gic_state *s)
     for (i = 0; i < NUM_CPU(s); i++) {
         sysbus_init_irq(&s->busdev, &s->parent_irq[i]);
     }
-    s->iomemtype = cpu_register_io_memory(gic_dist_readfn,
-                                          gic_dist_writefn, s,
-                                          DEVICE_NATIVE_ENDIAN);
+    memory_region_init_io(&s->iomem, &gic_dist_ops, s, "gic_dist", 0x1000);
     gic_reset(s);
     register_savevm(NULL, "arm_gic", -1, 1, gic_save, gic_load, s);
 }
diff --git a/hw/armv7m_nvic.c b/hw/armv7m_nvic.c
index 1df8d4d..bf8c3c5 100644
--- a/hw/armv7m_nvic.c
+++ b/hw/armv7m_nvic.c
@@ -13,6 +13,7 @@
 #include "sysbus.h"
 #include "qemu-timer.h"
 #include "arm-misc.h"
+#include "exec-memory.h"
 
 /* 32 internal lines (16 used for system exceptions) plus 64 external
    interrupt lines.  */
@@ -384,7 +385,7 @@ static int armv7m_nvic_init(SysBusDevice *dev)
     nvic_state *s= FROM_SYSBUSGIC(nvic_state, dev);
 
     gic_init(&s->gic);
-    cpu_register_physical_memory(0xe000e000, 0x1000, s->gic.iomemtype);
+    memory_region_add_subregion(get_system_memory(), 0xe000e000, &s->gic.iomem);
     s->systick.timer = qemu_new_timer_ns(vm_clock, systick_timer_tick, s);
     vmstate_register(&dev->qdev, -1, &vmstate_nvic, s);
     return 0;
diff --git a/hw/mpcore.c b/hw/mpcore.c
index d778507..d6175cf 100644
--- a/hw/mpcore.c
+++ b/hw/mpcore.c
@@ -40,6 +40,8 @@ typedef struct mpcore_priv_state {
     int iomemtype;
     mpcore_timer_state timer[8];
     uint32_t num_cpu;
+    MemoryRegion iomem;
+    MemoryRegion container;
 } mpcore_priv_state;
 
 /* Per-CPU Timers.  */
@@ -151,7 +153,8 @@ static void mpcore_timer_init(mpcore_priv_state *mpcore,
 
 /* Per-CPU private memory mapped IO.  */
 
-static uint32_t mpcore_priv_read(void *opaque, target_phys_addr_t offset)
+static uint64_t mpcore_priv_read(void *opaque, target_phys_addr_t offset,
+                                 unsigned size)
 {
     mpcore_priv_state *s = (mpcore_priv_state *)opaque;
     int id;
@@ -203,7 +206,7 @@ bad_reg:
 }
 
 static void mpcore_priv_write(void *opaque, target_phys_addr_t offset,
-                          uint32_t value)
+                              uint64_t value, unsigned size)
 {
     mpcore_priv_state *s = (mpcore_priv_state *)opaque;
     int id;
@@ -250,23 +253,19 @@ bad_reg:
     hw_error("mpcore_priv_read: Bad offset %x\n", (int)offset);
 }
 
-static CPUReadMemoryFunc * const mpcore_priv_readfn[] = {
-   mpcore_priv_read,
-   mpcore_priv_read,
-   mpcore_priv_read
+static const MemoryRegionOps mpcore_priv_ops = {
+    .read = mpcore_priv_read,
+    .write = mpcore_priv_write,
+    .endianness = DEVICE_NATIVE_ENDIAN,
 };
 
-static CPUWriteMemoryFunc * const mpcore_priv_writefn[] = {
-   mpcore_priv_write,
-   mpcore_priv_write,
-   mpcore_priv_write
-};
-
-static void mpcore_priv_map(SysBusDevice *dev, target_phys_addr_t base)
+static void mpcore_priv_map_setup(mpcore_priv_state *s)
 {
-    mpcore_priv_state *s = FROM_SYSBUSGIC(mpcore_priv_state, dev);
-    cpu_register_physical_memory(base, 0x1000, s->iomemtype);
-    cpu_register_physical_memory(base + 0x1000, 0x1000, s->gic.iomemtype);
+    memory_region_init(&s->container, "mpcode-priv-container", 0x2000);
+    memory_region_init_io(&s->iomem, &mpcore_priv_ops, s, "mpcode-priv",
+                          0x1000);
+    memory_region_add_subregion(&s->container, 0, &s->iomem);
+    memory_region_add_subregion(&s->container, 0x1000, &s->gic.iomem);
 }
 
 static int mpcore_priv_init(SysBusDevice *dev)
@@ -275,10 +274,8 @@ static int mpcore_priv_init(SysBusDevice *dev)
     int i;
 
     gic_init(&s->gic, s->num_cpu);
-    s->iomemtype = cpu_register_io_memory(mpcore_priv_readfn,
-                                          mpcore_priv_writefn, s,
-                                          DEVICE_NATIVE_ENDIAN);
-    sysbus_init_mmio_cb(dev, 0x2000, mpcore_priv_map);
+    mpcore_priv_map_setup(s);
+    sysbus_init_mmio_region(dev, &s->container);
     for (i = 0; i < s->num_cpu * 2; i++) {
         mpcore_timer_init(s, &s->timer[i], i);
     }
diff --git a/hw/realview_gic.c b/hw/realview_gic.c
index 43a2a0d..cd6a44d 100644
--- a/hw/realview_gic.c
+++ b/hw/realview_gic.c
@@ -23,39 +23,37 @@ gic_get_current_cpu(void)
 
 typedef struct {
     gic_state gic;
-    int iomemtype;
+    MemoryRegion iomem;
+    MemoryRegion container;
 } RealViewGICState;
 
-static uint32_t realview_gic_cpu_read(void *opaque, target_phys_addr_t offset)
+static uint64_t realview_gic_cpu_read(void *opaque, target_phys_addr_t offset,
+                                      unsigned size)
 {
     gic_state *s = (gic_state *)opaque;
     return gic_cpu_read(s, gic_get_current_cpu(), offset);
 }
 
 static void realview_gic_cpu_write(void *opaque, target_phys_addr_t offset,
-                          uint32_t value)
+                                   uint64_t value, unsigned size)
 {
     gic_state *s = (gic_state *)opaque;
     gic_cpu_write(s, gic_get_current_cpu(), offset, value);
 }
 
-static CPUReadMemoryFunc * const realview_gic_cpu_readfn[] = {
-   realview_gic_cpu_read,
-   realview_gic_cpu_read,
-   realview_gic_cpu_read
+static const MemoryRegionOps realview_gic_cpu_ops = {
+    .read = realview_gic_cpu_read,
+    .write = realview_gic_cpu_write,
+    .endianness = DEVICE_NATIVE_ENDIAN,
 };
 
-static CPUWriteMemoryFunc * const realview_gic_cpu_writefn[] = {
-   realview_gic_cpu_write,
-   realview_gic_cpu_write,
-   realview_gic_cpu_write
-};
-
-static void realview_gic_map(SysBusDevice *dev, target_phys_addr_t base)
+static void realview_gic_map_setup(RealViewGICState *s)
 {
-    RealViewGICState *s = FROM_SYSBUSGIC(RealViewGICState, dev);
-    cpu_register_physical_memory(base, 0x1000, s->iomemtype);
-    cpu_register_physical_memory(base + 0x1000, 0x1000, s->gic.iomemtype);
+    memory_region_init(&s->container, "realview-gic-container", 0x2000);
+    memory_region_init_io(&s->iomem, &realview_gic_cpu_ops, &s->gic,
+                          "realview-gic", 0x1000);
+    memory_region_add_subregion(&s->container, 0, &s->iomem);
+    memory_region_add_subregion(&s->container, 0x1000, &s->gic.iomem);
 }
 
 static int realview_gic_init(SysBusDevice *dev)
@@ -63,10 +61,8 @@ static int realview_gic_init(SysBusDevice *dev)
     RealViewGICState *s = FROM_SYSBUSGIC(RealViewGICState, dev);
 
     gic_init(&s->gic);
-    s->iomemtype = cpu_register_io_memory(realview_gic_cpu_readfn,
-                                          realview_gic_cpu_writefn, s,
-                                          DEVICE_NATIVE_ENDIAN);
-    sysbus_init_mmio_cb(dev, 0x2000, realview_gic_map);
+    realview_gic_map_setup(s);
+    sysbus_init_mmio_region(dev, &s->container);
     return 0;
 }
 
commit 312b4234c66e7c0de95e7a8df70dff21e58c15a7
Author: Avi Kivity <avi at redhat.com>
Date:   Mon Aug 15 17:17:16 2011 +0300

    apic: convert to memory API
    
    Signed-off-by: Avi Kivity <avi at redhat.com>
    Signed-off-by: Anthony Liguori <aliguori at us.ibm.com>

diff --git a/hw/apic.c b/hw/apic.c
index 9febf40..7d0b0f6 100644
--- a/hw/apic.c
+++ b/hw/apic.c
@@ -80,6 +80,7 @@ typedef struct APICState APICState;
 
 struct APICState {
     SysBusDevice busdev;
+    MemoryRegion io_memory;
     void *cpu_env;
     uint32_t apicbase;
     uint8_t id;
@@ -979,31 +980,25 @@ static void apic_reset(DeviceState *d)
     }
 }
 
-static CPUReadMemoryFunc * const apic_mem_read[3] = {
-    apic_mem_readb,
-    apic_mem_readw,
-    apic_mem_readl,
-};
-
-static CPUWriteMemoryFunc * const apic_mem_write[3] = {
-    apic_mem_writeb,
-    apic_mem_writew,
-    apic_mem_writel,
+static const MemoryRegionOps apic_io_ops = {
+    .old_mmio = {
+        .read = { apic_mem_readb, apic_mem_readw, apic_mem_readl, },
+        .write = { apic_mem_writeb, apic_mem_writew, apic_mem_writel, },
+    },
+    .endianness = DEVICE_NATIVE_ENDIAN,
 };
 
 static int apic_init1(SysBusDevice *dev)
 {
     APICState *s = FROM_SYSBUS(APICState, dev);
-    int apic_io_memory;
     static int last_apic_idx;
 
     if (last_apic_idx >= MAX_APICS) {
         return -1;
     }
-    apic_io_memory = cpu_register_io_memory(apic_mem_read,
-                                            apic_mem_write, NULL,
-                                            DEVICE_NATIVE_ENDIAN);
-    sysbus_init_mmio(dev, MSI_ADDR_SIZE, apic_io_memory);
+    memory_region_init_io(&s->io_memory, &apic_io_ops, s, "apic",
+                          MSI_ADDR_SIZE);
+    sysbus_init_mmio_region(dev, &s->io_memory);
 
     s->timer = qemu_new_timer_ns(vm_clock, apic_timer, s);
     s->idx = last_apic_idx++;
commit 3812ed0baa41a5858af193bfa870c6fe3a80a567
Author: Avi Kivity <avi at redhat.com>
Date:   Mon Aug 15 17:17:15 2011 +0300

    apb_pci: convert to memory API
    
    Signed-off-by: Avi Kivity <avi at redhat.com>
    Signed-off-by: Anthony Liguori <aliguori at us.ibm.com>

diff --git a/hw/apb_pci.c b/hw/apb_pci.c
index 1638226..6ee2068 100644
--- a/hw/apb_pci.c
+++ b/hw/apb_pci.c
@@ -31,7 +31,6 @@
 #include "pci_host.h"
 #include "pci_bridge.h"
 #include "pci_internals.h"
-#include "rwhandler.h"
 #include "apb_pci.h"
 #include "sysemu.h"
 #include "exec-memory.h"
@@ -70,7 +69,9 @@ do { printf("APB: " fmt , ## __VA_ARGS__); } while (0)
 typedef struct APBState {
     SysBusDevice busdev;
     PCIBus      *bus;
-    ReadWriteHandler pci_config_handler;
+    MemoryRegion apb_config;
+    MemoryRegion pci_config;
+    MemoryRegion pci_ioport;
     uint32_t iommu[4];
     uint32_t pci_control[16];
     uint32_t pci_irq_map[8];
@@ -81,7 +82,7 @@ typedef struct APBState {
 } APBState;
 
 static void apb_config_writel (void *opaque, target_phys_addr_t addr,
-                               uint32_t val)
+                               uint64_t val, unsigned size)
 {
     APBState *s = opaque;
 
@@ -128,8 +129,8 @@ static void apb_config_writel (void *opaque, target_phys_addr_t addr,
     }
 }
 
-static uint32_t apb_config_readl (void *opaque,
-                                  target_phys_addr_t addr)
+static uint64_t apb_config_readl (void *opaque,
+                                  target_phys_addr_t addr, unsigned size)
 {
     APBState *s = opaque;
     uint32_t val;
@@ -176,33 +177,27 @@ static uint32_t apb_config_readl (void *opaque,
     return val;
 }
 
-static CPUWriteMemoryFunc * const apb_config_write[] = {
-    &apb_config_writel,
-    &apb_config_writel,
-    &apb_config_writel,
+static const MemoryRegionOps apb_config_ops = {
+    .read = apb_config_readl,
+    .write = apb_config_writel,
+    .endianness = DEVICE_NATIVE_ENDIAN,
 };
 
-static CPUReadMemoryFunc * const apb_config_read[] = {
-    &apb_config_readl,
-    &apb_config_readl,
-    &apb_config_readl,
-};
-
-static void apb_pci_config_write(ReadWriteHandler *h, pcibus_t addr,
-                                 uint32_t val, int size)
+static void apb_pci_config_write(void *opaque, target_phys_addr_t addr,
+                                 uint64_t val, unsigned size)
 {
-    APBState *s = container_of(h, APBState, pci_config_handler);
+    APBState *s = opaque;
 
     val = qemu_bswap_len(val, size);
     APB_DPRINTF("%s: addr " TARGET_FMT_lx " val %x\n", __func__, addr, val);
     pci_data_write(s->bus, addr, val, size);
 }
 
-static uint32_t apb_pci_config_read(ReadWriteHandler *h, pcibus_t addr,
-                                    int size)
+static uint64_t apb_pci_config_read(void *opaque, target_phys_addr_t addr,
+                                    unsigned size)
 {
     uint32_t ret;
-    APBState *s = container_of(h, APBState, pci_config_handler);
+    APBState *s = opaque;
 
     ret = pci_data_read(s->bus, addr, size);
     ret = qemu_bswap_len(ret, size);
@@ -252,16 +247,12 @@ static uint32_t pci_apb_ioreadl (void *opaque, target_phys_addr_t addr)
     return val;
 }
 
-static CPUWriteMemoryFunc * const pci_apb_iowrite[] = {
-    &pci_apb_iowriteb,
-    &pci_apb_iowritew,
-    &pci_apb_iowritel,
-};
-
-static CPUReadMemoryFunc * const pci_apb_ioread[] = {
-    &pci_apb_ioreadb,
-    &pci_apb_ioreadw,
-    &pci_apb_ioreadl,
+static const MemoryRegionOps pci_ioport_ops = {
+    .old_mmio = {
+        .read = { pci_apb_ioreadb, pci_apb_ioreadw, pci_apb_ioreadl },
+        .write = { pci_apb_iowriteb, pci_apb_iowritew, pci_apb_iowritel, },
+    },
+    .endianness = DEVICE_NATIVE_ENDIAN,
 };
 
 /* The APB host has an IRQ line for each IRQ line of each slot.  */
@@ -393,10 +384,15 @@ static void pci_pbm_reset(DeviceState *d)
     }
 }
 
+static const MemoryRegionOps pci_config_ops = {
+    .read = apb_pci_config_read,
+    .write = apb_pci_config_write,
+    .endianness = DEVICE_NATIVE_ENDIAN,
+};
+
 static int pci_pbm_init_device(SysBusDevice *dev)
 {
     APBState *s;
-    int pci_config, apb_config, pci_ioport;
     unsigned int i;
 
     s = FROM_SYSBUS(APBState, dev);
@@ -408,27 +404,21 @@ static int pci_pbm_init_device(SysBusDevice *dev)
     }
 
     /* apb_config */
-    apb_config = cpu_register_io_memory(apb_config_read,
-                                        apb_config_write, s,
-                                        DEVICE_NATIVE_ENDIAN);
+    memory_region_init_io(&s->apb_config, &apb_config_ops, s, "apb-config",
+                          0x10000);
     /* at region 0 */
-    sysbus_init_mmio(dev, 0x10000ULL, apb_config);
+    sysbus_init_mmio_region(dev, &s->apb_config);
 
-    /* PCI configuration space */
-    s->pci_config_handler.read = apb_pci_config_read;
-    s->pci_config_handler.write = apb_pci_config_write;
-    pci_config = cpu_register_io_memory_simple(&s->pci_config_handler,
-                                               DEVICE_NATIVE_ENDIAN);
-    assert(pci_config >= 0);
+    memory_region_init_io(&s->pci_config, &pci_config_ops, s, "apb-pci-config",
+                          0x1000000);
     /* at region 1 */
-    sysbus_init_mmio(dev, 0x1000000ULL, pci_config);
+    sysbus_init_mmio_region(dev, &s->pci_config);
 
     /* pci_ioport */
-    pci_ioport = cpu_register_io_memory(pci_apb_ioread,
-                                        pci_apb_iowrite, s,
-                                        DEVICE_NATIVE_ENDIAN);
+    memory_region_init_io(&s->pci_ioport, &pci_ioport_ops, s,
+                          "apb-pci-ioport", 0x10000);
     /* at region 2 */
-    sysbus_init_mmio(dev, 0x10000ULL, pci_ioport);
+    sysbus_init_mmio_region(dev, &s->pci_ioport);
 
     return 0;
 }
commit 145aebeca442f608353cc1dd8d48f5a11faca71e
Author: Hervé Poussineau <hpoussin at reactos.org>
Date:   Sat Aug 20 16:29:50 2011 +0200

    pcnet: fix wrong opaque (broken by bd8d6f7cadb6ace98c779135217a4ed7b5fccc23)
    
    Reviewed-by: Stefan Hajnoczi <stefanha at linux.vnet.ibm.com>
    Signed-off-by: Hervé Poussineau <hpoussin at reactos.org>
    Signed-off-by: Anthony Liguori <aliguori at us.ibm.com>

diff --git a/hw/pcnet-pci.c b/hw/pcnet-pci.c
index 13d9380..51e1320 100644
--- a/hw/pcnet-pci.c
+++ b/hw/pcnet-pci.c
@@ -290,10 +290,10 @@ static int pci_pcnet_init(PCIDevice *pci_dev)
     pci_conf[PCI_MAX_LAT] = 0xff;
 
     /* Handler for memory-mapped I/O */
-    memory_region_init_io(&d->state.mmio, &pcnet_mmio_ops, d, "pcnet-mmio",
+    memory_region_init_io(&d->state.mmio, &pcnet_mmio_ops, s, "pcnet-mmio",
                           PCNET_PNPMMIO_SIZE);
 
-    memory_region_init_io(&d->io_bar, &pcnet_io_ops, d, "pcnet-io",
+    memory_region_init_io(&d->io_bar, &pcnet_io_ops, s, "pcnet-io",
                           PCNET_IOPORT_SIZE);
     pci_register_bar(pci_dev, 0, PCI_BASE_ADDRESS_SPACE_IO, &d->io_bar);
 
commit 3f53458137b6154acfa5bfe05efe8bd67f6d1778
Author: Brad <brad at comstyle.com>
Date:   Sat Aug 13 20:30:14 2011 -0400

    Improvements to libtool support.
    
    Improvements to the libtool support in QEMU. Replace hard coded
    libtool in the infrastructure with $(LIBTOOL) and allow
    overriding the libtool binary used via the configure
    script.
    
    Reviewed-by: Andreas F=E4rber <andreas.faerber at web.de>
    Signed-off-by: Brad Smith <brad at comstyle.com>
    Signed-off-by: Anthony Liguori <aliguori at us.ibm.com>

diff --git a/Makefile.objs b/Makefile.objs
index abd867a..d1f3e5d 100644
--- a/Makefile.objs
+++ b/Makefile.objs
@@ -369,7 +369,7 @@ trace-dtrace.lo: trace-dtrace.dtrace
 	@echo "missing libtool. please install and rerun configure."; exit 1
 else
 trace-dtrace.lo: trace-dtrace.dtrace
-	$(call quiet-command,libtool --mode=compile --tag=CC dtrace -o $@ -G -s $<, "  lt GEN trace-dtrace.o")
+	$(call quiet-command,$(LIBTOOL) --mode=compile --tag=CC dtrace -o $@ -G -s $<, "  lt GEN trace-dtrace.o")
 endif
 
 simpletrace.o: simpletrace.c $(GENERATED_HEADERS)
diff --git a/configure b/configure
index 234a4c5..1340c33 100755
--- a/configure
+++ b/configure
@@ -225,6 +225,7 @@ cc="${CC-${cross_prefix}gcc}"
 ar="${AR-${cross_prefix}ar}"
 objcopy="${OBJCOPY-${cross_prefix}objcopy}"
 ld="${LD-${cross_prefix}ld}"
+libtool="${LIBTOOL-${cross_prefix}libtool}"
 strip="${STRIP-${cross_prefix}strip}"
 windres="${WINDRES-${cross_prefix}windres}"
 pkg_config="${PKG_CONFIG-${cross_prefix}pkg-config}"
@@ -1342,10 +1343,8 @@ fi
 ##########################################
 # libtool probe
 
-if ! has libtool; then
+if ! has $libtool; then
     libtool=
-else
-    libtool=libtool
 fi
 
 ##########################################
diff --git a/libcacard/Makefile b/libcacard/Makefile
index 1701388..b3f5e6c 100644
--- a/libcacard/Makefile
+++ b/libcacard/Makefile
@@ -39,7 +39,7 @@ install-libcacard:
 	@echo "libtool is missing, please install and rerun configure"; exit 1
 else
 libcacard.la: $(libcacard.lib-y) $(QEMU_OBJS_LIB)
-	$(call quiet-command,libtool --mode=link --quiet --tag=CC $(CC) -rpath $(libdir) -o $@ $^ $(libcacard_libs) -lrt,"  lt LINK $@")
+	$(call quiet-command,$(LIBTOOL) --mode=link --quiet --tag=CC $(CC) -rpath $(libdir) -o $@ $^ $(libcacard_libs) -lrt,"  lt LINK $@")
 
 libcacard.pc: $(libcacard_srcpath)/libcacard.pc.in
 	sed -e 's|@LIBDIR@|$(libdir)|' \
@@ -55,10 +55,10 @@ install-libcacard: libcacard.pc libcacard.la vscclient
 	$(INSTALL_DIR) "$(DESTDIR)$(libdir)/pkgconfig"
 	$(INSTALL_DIR) "$(DESTDIR)$(libcacard_includedir)"
 	$(INSTALL_DIR) "$(DESTDIR)$(bindir)"
-	libtool --mode=install $(INSTALL_PROG) vscclient "$(DESTDIR)$(bindir)"
-	libtool --mode=install $(INSTALL_PROG) libcacard.la "$(DESTDIR)$(libdir)"
-	libtool --mode=install $(INSTALL_DATA) libcacard.pc "$(DESTDIR)$(libdir)/pkgconfig"
+	$(LIBTOOL) --mode=install $(INSTALL_PROG) vscclient "$(DESTDIR)$(bindir)"
+	$(LIBTOOL) --mode=install $(INSTALL_PROG) libcacard.la "$(DESTDIR)$(libdir)"
+	$(LIBTOOL) --mode=install $(INSTALL_DATA) libcacard.pc "$(DESTDIR)$(libdir)/pkgconfig"
 	for inc in *.h; do \
-		libtool --mode=install $(INSTALL_DATA) $(libcacard_srcpath)/$$inc "$(DESTDIR)$(libcacard_includedir)"; \
+		$(LIBTOOL) --mode=install $(INSTALL_DATA) $(libcacard_srcpath)/$$inc "$(DESTDIR)$(libcacard_includedir)"; \
 	done
 endif
diff --git a/rules.mak b/rules.mak
index 1a2622c..884d421 100644
--- a/rules.mak
+++ b/rules.mak
@@ -22,7 +22,7 @@ ifeq ($(LIBTOOL),)
 	@echo "missing libtool. please install and rerun configure"; exit 1
 else
 %.lo: %.c
-	$(call quiet-command,libtool --mode=compile --quiet --tag=CC $(CC) $(QEMU_INCLUDES) $(QEMU_CFLAGS) $(QEMU_DGFLAGS) $(CFLAGS) -c -o $@ $<,"  lt CC $@")
+	$(call quiet-command,$(LIBTOOL) --mode=compile --quiet --tag=CC $(CC) $(QEMU_INCLUDES) $(QEMU_CFLAGS) $(QEMU_DGFLAGS) $(CFLAGS) -c -o $@ $<,"  lt CC $@")
 endif
 
 %.o: %.S
commit 2c993ec294893af31deed27e5d79610ce71642e1
Author: Stefan Weil <weil at mail.berlios.de>
Date:   Sat Aug 20 12:10:05 2011 +0200

    w32: Fix qemu_ftruncate64
    
    SetFilePointer returns INVALID_SET_FILE_POINTER when it fails.
    In addition, GetLastError must be checked.
    
    The first call of SetFilePointer did not use INVALID_SET_FILE_POINTER,
    the second call used wrong error handling.
    
    Signed-off-by: Stefan Weil <weil at mail.berlios.de>
    Signed-off-by: Anthony Liguori <aliguori at us.ibm.com>

diff --git a/block/raw-win32.c b/block/raw-win32.c
index e47cfe0..b7dd357 100644
--- a/block/raw-win32.c
+++ b/block/raw-win32.c
@@ -41,6 +41,7 @@ typedef struct BDRVRawState {
 int qemu_ftruncate64(int fd, int64_t length)
 {
     LARGE_INTEGER li;
+    DWORD dw;
     LONG high;
     HANDLE h;
     BOOL res;
@@ -53,12 +54,15 @@ int qemu_ftruncate64(int fd, int64_t length)
     /* get current position, ftruncate do not change position */
     li.HighPart = 0;
     li.LowPart = SetFilePointer (h, 0, &li.HighPart, FILE_CURRENT);
-    if (li.LowPart == 0xffffffffUL && GetLastError() != NO_ERROR)
+    if (li.LowPart == INVALID_SET_FILE_POINTER && GetLastError() != NO_ERROR) {
 	return -1;
+    }
 
     high = length >> 32;
-    if (!SetFilePointer(h, (DWORD) length, &high, FILE_BEGIN))
+    dw = SetFilePointer(h, (DWORD) length, &high, FILE_BEGIN);
+    if (dw == INVALID_SET_FILE_POINTER && GetLastError() != NO_ERROR) {
 	return -1;
+    }
     res = SetEndOfFile(h);
 
     /* back to old position */
commit 1f22a6bc62bc7b1c21a4dc5c9cf16e156ad8321e
Author: Diego Elio Pettenò <flameeyes at flameeyes.eu>
Date:   Sun Aug 14 15:31:24 2011 +0200

    build: list libraries after objects, for proper linkage
    
    Without this change, when using -Wl,--as-needed with GNU linker, the
    libraries would be discarded.
    
    Signed-off-by: Diego Elio Pettenò <flameeyes at flameeyes.eu>
    Signed-off-by: Anthony Liguori <aliguori at us.ibm.com>

diff --git a/libcacard/Makefile b/libcacard/Makefile
index 9ad8f1e..1701388 100644
--- a/libcacard/Makefile
+++ b/libcacard/Makefile
@@ -20,7 +20,7 @@ QEMU_CFLAGS+=$(GLIB_CFLAGS)
 libcacard.lib-y=$(addsuffix .lo,$(basename $(libcacard-y)))
 
 vscclient: $(libcacard-y) $(QEMU_OBJS) vscclient.o
-	$(call quiet-command,$(CC) $(libcacard_libs) $(LIBS) -lrt -o $@ $^,"  LINK  $@")
+	$(call quiet-command,$(CC) -o $@ $^ $(libcacard_libs) $(LIBS) -lrt,"  LINK  $@")
 
 clean:
 	rm -f *.o */*.o *.d */*.d *.a */*.a *~ */*~ vscclient *.lo .libs/* *.la *.pc
@@ -39,7 +39,7 @@ install-libcacard:
 	@echo "libtool is missing, please install and rerun configure"; exit 1
 else
 libcacard.la: $(libcacard.lib-y) $(QEMU_OBJS_LIB)
-	$(call quiet-command,libtool --mode=link --quiet --tag=CC $(CC) $(libcacard_libs) -lrt -rpath $(libdir) -o $@ $^,"  lt LINK $@")
+	$(call quiet-command,libtool --mode=link --quiet --tag=CC $(CC) -rpath $(libdir) -o $@ $^ $(libcacard_libs) -lrt,"  lt LINK $@")
 
 libcacard.pc: $(libcacard_srcpath)/libcacard.pc.in
 	sed -e 's|@LIBDIR@|$(libdir)|' \
commit d62b5dea30284eacd88055bb08db7c295655945f
Author: Robert Wang <wdongxu at linux.vnet.ibm.com>
Date:   Fri Aug 19 17:17:12 2011 +0800

    fix code format
    
    Fix code format to make checkpatch.pl happy.
    
    Signed-off-by: Robert Wang <wdongxu at linux.vnet.ibm.com>
    Signed-off-by: Anthony Liguori <aliguori at us.ibm.com>

diff --git a/block.c b/block.c
index 785c88e..a8a013a 100644
--- a/block.c
+++ b/block.c
@@ -2251,9 +2251,9 @@ BlockDriverAIOCB *bdrv_aio_readv(BlockDriverState *bs, int64_t sector_num,
                               cb, opaque);
 
     if (ret) {
-	/* Update stats even though technically transfer has not happened. */
-	bs->rd_bytes += (unsigned) nb_sectors * BDRV_SECTOR_SIZE;
-	bs->rd_ops ++;
+        /* Update stats even though technically transfer has not happened. */
+        bs->rd_bytes += (unsigned) nb_sectors * BDRV_SECTOR_SIZE;
+        bs->rd_ops++;
     }
 
     return ret;
commit d4044c2a6b9ba4a00dd653f515a4b0ebfcb7e125
Author: Bjørn Mork <bjorn at mork.no>
Date:   Wed Aug 17 11:03:14 2011 +0200

    e1000: use MII status register for link up/down
    
    Some guests will use the standard MII status register
    to verify link state.  They will not notice link changes
    unless this register is updated.
    
    Verified with Linux 3.0 and Windows XP guests.
    
    Without this patch, ethtool will report speed and duplex as
    unknown when the link is down, but still report the link as
    up.  This is because the Linux e1000 driver checks the
    mac_reg[STATUS] register link state before it checks speed
    and duplex, but uses the phy_reg[PHY_STATUS] register for
    the actual link state check.  Fix by updating both registers
    on link state changes.
    
    Linux guest before:
    
     (qemu) set_link e1000.0 off
    
     kvm-sid:~# ethtool eth0
     Settings for eth0:
            Supported ports: [ TP ]
            Supported link modes:   10baseT/Half 10baseT/Full
                                    100baseT/Half 100baseT/Full
                                    1000baseT/Full
            Supports auto-negotiation: Yes
            Advertised link modes:  10baseT/Half 10baseT/Full
                                    100baseT/Half 100baseT/Full
                                    1000baseT/Full
            Advertised pause frame use: No
            Advertised auto-negotiation: Yes
            Speed: Unknown!
            Duplex: Unknown! (255)
            Port: Twisted Pair
            PHYAD: 0
            Transceiver: internal
            Auto-negotiation: on
            MDI-X: Unknown
            Supports Wake-on: umbg
            Wake-on: d
            Current message level: 0x00000007 (7)
                                   drv probe link
            Link detected: yes
    
     (qemu) set_link e1000.0 on
    
    Linux guest after:
    
     (qemu) set_link e1000.0 off
     [   63.384221] e1000: eth0 NIC Link is Down
    
     kvm-sid:~# ethtool eth0
     Settings for eth0:
            Supported ports: [ TP ]
            Supported link modes:   10baseT/Half 10baseT/Full
                                    100baseT/Half 100baseT/Full
                                    1000baseT/Full
            Supports auto-negotiation: Yes
            Advertised link modes:  10baseT/Half 10baseT/Full
                                    100baseT/Half 100baseT/Full
                                    1000baseT/Full
            Advertised pause frame use: No
            Advertised auto-negotiation: Yes
            Speed: Unknown!
            Duplex: Unknown! (255)
            Port: Twisted Pair
            PHYAD: 0
            Transceiver: internal
            Auto-negotiation: on
            MDI-X: Unknown
            Supports Wake-on: umbg
            Wake-on: d
            Current message level: 0x00000007 (7)
                                   drv probe link
            Link detected: no
    
     (qemu) set_link e1000.0 on
     [   84.304582] e1000: eth0 NIC Link is Up 1000 Mbps Full Duplex, Flow Control: RX
    
    Signed-off-by: Bjørn Mork <bjorn at mork.no>
    Signed-off-by: Anthony Liguori <aliguori at us.ibm.com>

diff --git a/hw/e1000.c b/hw/e1000.c
index 29b453f..a6d12c5 100644
--- a/hw/e1000.c
+++ b/hw/e1000.c
@@ -617,10 +617,13 @@ e1000_set_link_status(VLANClientState *nc)
     E1000State *s = DO_UPCAST(NICState, nc, nc)->opaque;
     uint32_t old_status = s->mac_reg[STATUS];
 
-    if (nc->link_down)
+    if (nc->link_down) {
         s->mac_reg[STATUS] &= ~E1000_STATUS_LU;
-    else
+        s->phy_reg[PHY_STATUS] &= ~MII_SR_LINK_STATUS;
+    } else {
         s->mac_reg[STATUS] |= E1000_STATUS_LU;
+        s->phy_reg[PHY_STATUS] |= MII_SR_LINK_STATUS;
+    }
 
     if (s->mac_reg[STATUS] != old_status)
         set_ics(s, 0, E1000_ICR_LSC);
diff --git a/hw/e1000_hw.h b/hw/e1000_hw.h
index 9bd8a4b..2e341ac 100644
--- a/hw/e1000_hw.h
+++ b/hw/e1000_hw.h
@@ -349,6 +349,23 @@
 #define M88E1000_PHY_VCO_REG_BIT8  0x100 /* Bits 8 & 11 are adjusted for */
 #define M88E1000_PHY_VCO_REG_BIT11 0x800    /* improved BER performance */
 
+/* PHY Status Register */
+#define MII_SR_EXTENDED_CAPS     0x0001	/* Extended register capabilities */
+#define MII_SR_JABBER_DETECT     0x0002	/* Jabber Detected */
+#define MII_SR_LINK_STATUS       0x0004	/* Link Status 1 = link */
+#define MII_SR_AUTONEG_CAPS      0x0008	/* Auto Neg Capable */
+#define MII_SR_REMOTE_FAULT      0x0010	/* Remote Fault Detect */
+#define MII_SR_AUTONEG_COMPLETE  0x0020	/* Auto Neg Complete */
+#define MII_SR_PREAMBLE_SUPPRESS 0x0040	/* Preamble may be suppressed */
+#define MII_SR_EXTENDED_STATUS   0x0100	/* Ext. status info in Reg 0x0F */
+#define MII_SR_100T2_HD_CAPS     0x0200	/* 100T2 Half Duplex Capable */
+#define MII_SR_100T2_FD_CAPS     0x0400	/* 100T2 Full Duplex Capable */
+#define MII_SR_10T_HD_CAPS       0x0800	/* 10T   Half Duplex Capable */
+#define MII_SR_10T_FD_CAPS       0x1000	/* 10T   Full Duplex Capable */
+#define MII_SR_100X_HD_CAPS      0x2000	/* 100X  Half Duplex Capable */
+#define MII_SR_100X_FD_CAPS      0x4000	/* 100X  Full Duplex Capable */
+#define MII_SR_100T4_CAPS        0x8000	/* 100T4 Capable */
+
 /* Interrupt Cause Read */
 #define E1000_ICR_TXDW          0x00000001 /* Transmit desc written back */
 #define E1000_ICR_TXQE          0x00000002 /* Transmit Queue empty */
commit 2011fe5657f421e919eb6fed826ad2413e375673
Author: Anthony Liguori <aliguori at us.ibm.com>
Date:   Mon Aug 15 11:17:41 2011 -0500

    char: document the functions that will be the public interface
    
    Signed-off-by: Anthony Liguori <aliguori at us.ibm.com>

diff --git a/qemu-char.h b/qemu-char.h
index fba0290..eebbdd8 100644
--- a/qemu-char.h
+++ b/qemu-char.h
@@ -76,33 +76,156 @@ struct CharDriverState {
     QTAILQ_ENTRY(CharDriverState) next;
 };
 
-QemuOpts *qemu_chr_parse_compat(const char *label, const char *filename);
+/**
+ * @qemu_chr_new_from_opts:
+ *
+ * Create a new character backend from a QemuOpts list.
+ *
+ * @opts see qemu-config.c for a list of valid options
+ * @init not sure..
+ *
+ * Returns: a new character backend
+ */
 CharDriverState *qemu_chr_new_from_opts(QemuOpts *opts,
                                     void (*init)(struct CharDriverState *s));
-CharDriverState *qemu_chr_new(const char *label, const char *filename, void (*init)(struct CharDriverState *s));
+
+/**
+ * @qemu_chr_new:
+ *
+ * Create a new character backend from a URI.
+ *
+ * @label the name of the backend
+ * @filename the URI
+ * @init not sure..
+ *
+ * Returns: a new character backend
+ */
+CharDriverState *qemu_chr_new(const char *label, const char *filename,
+                              void (*init)(struct CharDriverState *s));
+
+/**
+ * @qemu_chr_delete:
+ *
+ * Destroy a character backend.
+ */
+void qemu_chr_delete(CharDriverState *chr);
+
+/**
+ * @qemu_chr_fe_set_echo:
+ *
+ * Ask the backend to override its normal echo setting.  This only really
+ * applies to the stdio backend and is used by the QMP server such that you
+ * can see what you type if you try to type QMP commands.
+ *
+ * @echo true to enable echo, false to disable echo
+ */
 void qemu_chr_fe_set_echo(struct CharDriverState *chr, bool echo);
+
+/**
+ * @qemu_chr_fe_open:
+ *
+ * Open a character backend.  This function call is an indication that the
+ * front end is ready to begin doing I/O.
+ */
 void qemu_chr_fe_open(struct CharDriverState *chr);
+
+/**
+ * @qemu_chr_fe_close:
+ *
+ * Close a character backend.  This function call indicates that the front end
+ * no longer is able to process I/O.  To process I/O again, the front end will
+ * call @qemu_chr_fe_open.
+ */
 void qemu_chr_fe_close(struct CharDriverState *chr);
-void qemu_chr_delete(CharDriverState *chr);
+
+/**
+ * @qemu_chr_fe_printf:
+ *
+ * Write to a character backend using a printf style interface.
+ *
+ * @fmt see #printf
+ */
 void qemu_chr_fe_printf(CharDriverState *s, const char *fmt, ...)
     GCC_FMT_ATTR(2, 3);
+
+/**
+ * @qemu_chr_fe_write:
+ *
+ * Write data to a character backend from the front end.  This function will
+ * send data from the front end to the back end.
+ *
+ * @buf the data
+ * @len the number of bytes to send
+ *
+ * Returns: the number of bytes consumed
+ */
 int qemu_chr_fe_write(CharDriverState *s, const uint8_t *buf, int len);
+
+/**
+ * @qemu_chr_fe_ioctl:
+ *
+ * Issue a device specific ioctl to a backend.
+ *
+ * @cmd see CHR_IOCTL_*
+ * @arg the data associated with @cmd
+ *
+ * Returns: if @cmd is not supported by the backend, -ENOTSUP, otherwise the
+ *          return value depends on the semantics of @cmd
+ */
+int qemu_chr_fe_ioctl(CharDriverState *s, int cmd, void *arg);
+
+/**
+ * @qemu_chr_fe_get_msgfd:
+ *
+ * For backends capable of fd passing, return the latest file descriptor passed
+ * by a client.
+ *
+ * Returns: -1 if fd passing isn't supported or there is no pending file
+ *          descriptor.  If a file descriptor is returned, subsequent calls to
+ *          this function will return -1 until a client sends a new file
+ *          descriptor.
+ */
+int qemu_chr_fe_get_msgfd(CharDriverState *s);
+
+/**
+ * @qemu_chr_be_can_write:
+ *
+ * Determine how much data the front end can currently accept.  This function
+ * returns the number of bytes the front end can accept.  If it returns 0, the
+ * front end cannot receive data at the moment.  The function must be polled
+ * to determine when data can be received.
+ *
+ * Returns: the number of bytes the front end can receive via @qemu_chr_be_write
+ */
+int qemu_chr_be_can_write(CharDriverState *s);
+
+/**
+ * @qemu_chr_be_write:
+ *
+ * Write data from the back end to the front end.  Before issuing this call,
+ * the caller should call @qemu_chr_be_can_write to determine how much data
+ * the front end can currently accept.
+ *
+ * @buf a buffer to receive data from the front end
+ * @len the number of bytes to receive from the front end
+ */
+void qemu_chr_be_write(CharDriverState *s, uint8_t *buf, int len);
+
 void qemu_chr_add_handlers(CharDriverState *s,
                            IOCanReadHandler *fd_can_read,
                            IOReadHandler *fd_read,
                            IOEventHandler *fd_event,
                            void *opaque);
-int qemu_chr_fe_ioctl(CharDriverState *s, int cmd, void *arg);
+
 void qemu_chr_generic_open(CharDriverState *s);
-int qemu_chr_be_can_write(CharDriverState *s);
-void qemu_chr_be_write(CharDriverState *s, uint8_t *buf, int len);
-int qemu_chr_fe_get_msgfd(CharDriverState *s);
 void qemu_chr_accept_input(CharDriverState *s);
 int qemu_chr_add_client(CharDriverState *s, int fd);
 void qemu_chr_info_print(Monitor *mon, const QObject *ret_data);
 void qemu_chr_info(Monitor *mon, QObject **ret_data);
 CharDriverState *qemu_chr_find(const char *name);
 
+QemuOpts *qemu_chr_parse_compat(const char *label, const char *filename);
+
 /* add an eventfd to the qemu devices that are polled */
 CharDriverState *qemu_chr_open_eventfd(int eventfd);
 
commit 903396ad3ea8f84b38362134ef7157c82b32071e
Author: Anthony Liguori <aliguori at us.ibm.com>
Date:   Mon Aug 15 11:17:40 2011 -0500

    char: remove qemu_chr_send_event()
    
    It's dead code.
    
    Signed-off-by: Anthony Liguori <aliguori at us.ibm.com>

diff --git a/console.c b/console.c
index 553358b..500b3fb 100644
--- a/console.c
+++ b/console.c
@@ -1102,21 +1102,6 @@ static int console_puts(CharDriverState *chr, const uint8_t *buf, int len)
     return len;
 }
 
-static void console_send_event(CharDriverState *chr, int event)
-{
-    TextConsole *s = chr->opaque;
-    int i;
-
-    if (event == CHR_EVENT_FOCUS) {
-        for(i = 0; i < nb_consoles; i++) {
-            if (consoles[i] == s) {
-                console_select(i);
-                break;
-            }
-        }
-    }
-}
-
 static void kbd_send_chars(void *opaque)
 {
     TextConsole *s = opaque;
@@ -1462,7 +1447,6 @@ static void text_console_do_init(CharDriverState *chr, DisplayState *ds)
     s = chr->opaque;
 
     chr->chr_write = console_puts;
-    chr->chr_send_event = console_send_event;
 
     s->out_fifo.buf = s->out_fifo_buf;
     s->out_fifo.buf_size = sizeof(s->out_fifo_buf);
diff --git a/hw/baum.c b/hw/baum.c
index 1c6d3e2..86d780a 100644
--- a/hw/baum.c
+++ b/hw/baum.c
@@ -468,20 +468,6 @@ static int baum_write(CharDriverState *chr, const uint8_t *buf, int len)
     return orig_len;
 }
 
-/* The other end sent us some event */
-static void baum_send_event(CharDriverState *chr, int event)
-{
-    BaumDriverState *baum = chr->opaque;
-    switch (event) {
-    case CHR_EVENT_BREAK:
-        break;
-    case CHR_EVENT_OPENED:
-        /* Reset state */
-        baum->in_buf_used = 0;
-        break;
-    }
-}
-
 /* Send the key code to the other end */
 static void baum_send_key(BaumDriverState *baum, uint8_t type, uint8_t value) {
     uint8_t packet[] = { type, value };
@@ -591,7 +577,6 @@ int chr_baum_init(QemuOpts *opts, CharDriverState **_chr)
 
     chr->opaque = baum;
     chr->chr_write = baum_write;
-    chr->chr_send_event = baum_send_event;
     chr->chr_accept_input = baum_accept_input;
     chr->chr_close = baum_close;
 
diff --git a/qemu-char.c b/qemu-char.c
index 2075118..c9e5c41 100644
--- a/qemu-char.c
+++ b/qemu-char.c
@@ -189,12 +189,6 @@ void qemu_chr_fe_printf(CharDriverState *s, const char *fmt, ...)
     va_end(ap);
 }
 
-void qemu_chr_send_event(CharDriverState *s, int event)
-{
-    if (s->chr_send_event)
-        s->chr_send_event(s, event);
-}
-
 void qemu_chr_add_handlers(CharDriverState *s,
                            IOCanReadHandler *fd_can_read,
                            IOReadHandler *fd_read,
diff --git a/qemu-char.h b/qemu-char.h
index abd9cbd..fba0290 100644
--- a/qemu-char.h
+++ b/qemu-char.h
@@ -62,7 +62,6 @@ struct CharDriverState {
     IOCanReadHandler *chr_can_read;
     IOReadHandler *chr_read;
     void *handler_opaque;
-    void (*chr_send_event)(struct CharDriverState *chr, int event);
     void (*chr_close)(struct CharDriverState *chr);
     void (*chr_accept_input)(struct CharDriverState *chr);
     void (*chr_set_echo)(struct CharDriverState *chr, bool echo);
@@ -88,7 +87,6 @@ void qemu_chr_delete(CharDriverState *chr);
 void qemu_chr_fe_printf(CharDriverState *s, const char *fmt, ...)
     GCC_FMT_ATTR(2, 3);
 int qemu_chr_fe_write(CharDriverState *s, const uint8_t *buf, int len);
-void qemu_chr_send_event(CharDriverState *s, int event);
 void qemu_chr_add_handlers(CharDriverState *s,
                            IOCanReadHandler *fd_can_read,
                            IOReadHandler *fd_read,
commit 74c0d6f02048767f05ba671f1b5ca85aad720446
Author: Anthony Liguori <aliguori at us.ibm.com>
Date:   Mon Aug 15 11:17:39 2011 -0500

    char: rename qemu_chr_get_msgfd() -> qemu_chr_fe_get_msgfd()
    
    Signed-off-by: Anthony Liguori <aliguori at us.ibm.com>

diff --git a/hw/ivshmem.c b/hw/ivshmem.c
index f4ae0d2..242fbea 100644
--- a/hw/ivshmem.c
+++ b/hw/ivshmem.c
@@ -401,7 +401,7 @@ static void ivshmem_read(void *opaque, const uint8_t * buf, int flags)
 
     memcpy(&incoming_posn, buf, sizeof(long));
     /* pick off s->server_chr->msgfd and store it, posn should accompany msg */
-    tmp_fd = qemu_chr_get_msgfd(s->server_chr);
+    tmp_fd = qemu_chr_fe_get_msgfd(s->server_chr);
     IVSHMEM_DPRINTF("posn is %ld, fd is %d\n", incoming_posn, tmp_fd);
 
     /* make sure we have enough space for this guest */
diff --git a/monitor.c b/monitor.c
index cc1b7be..ada51d0 100644
--- a/monitor.c
+++ b/monitor.c
@@ -2770,7 +2770,7 @@ static int do_getfd(Monitor *mon, const QDict *qdict, QObject **ret_data)
     mon_fd_t *monfd;
     int fd;
 
-    fd = qemu_chr_get_msgfd(mon->chr);
+    fd = qemu_chr_fe_get_msgfd(mon->chr);
     if (fd == -1) {
         qerror_report(QERR_FD_NOT_SUPPLIED);
         return -1;
diff --git a/qemu-char.c b/qemu-char.c
index c0af8f3..2075118 100644
--- a/qemu-char.c
+++ b/qemu-char.c
@@ -163,7 +163,7 @@ void qemu_chr_be_write(CharDriverState *s, uint8_t *buf, int len)
     s->chr_read(s->handler_opaque, buf, len);
 }
 
-int qemu_chr_get_msgfd(CharDriverState *s)
+int qemu_chr_fe_get_msgfd(CharDriverState *s)
 {
     return s->get_msgfd ? s->get_msgfd(s) : -1;
 }
diff --git a/qemu-char.h b/qemu-char.h
index 555b5f1..abd9cbd 100644
--- a/qemu-char.h
+++ b/qemu-char.h
@@ -98,7 +98,7 @@ int qemu_chr_fe_ioctl(CharDriverState *s, int cmd, void *arg);
 void qemu_chr_generic_open(CharDriverState *s);
 int qemu_chr_be_can_write(CharDriverState *s);
 void qemu_chr_be_write(CharDriverState *s, uint8_t *buf, int len);
-int qemu_chr_get_msgfd(CharDriverState *s);
+int qemu_chr_fe_get_msgfd(CharDriverState *s);
 void qemu_chr_accept_input(CharDriverState *s);
 int qemu_chr_add_client(CharDriverState *s, int fd);
 void qemu_chr_info_print(Monitor *mon, const QObject *ret_data);
commit 70f24fb6c647c65760c8e1caa29f72531d5be8cd
Author: Anthony Liguori <aliguori at us.ibm.com>
Date:   Mon Aug 15 11:17:38 2011 -0500

    char: rename qemu_chr_close() -> qemu_chr_delete()
    
    Signed-off-by: Anthony Liguori <aliguori at us.ibm.com>

diff --git a/gdbstub.c b/gdbstub.c
index 4663682..3b87c27 100644
--- a/gdbstub.c
+++ b/gdbstub.c
@@ -2499,7 +2499,7 @@ void gdb_exit(CPUState *env, int code)
 
 #ifndef CONFIG_USER_ONLY
   if (s->chr) {
-      qemu_chr_close(s->chr);
+      qemu_chr_delete(s->chr);
   }
 #endif
 }
@@ -2785,7 +2785,7 @@ int gdbserver_start(const char *device)
         monitor_init(mon_chr, 0);
     } else {
         if (s->chr)
-            qemu_chr_close(s->chr);
+            qemu_chr_delete(s->chr);
         mon_chr = s->mon_chr;
         memset(s, 0, sizeof(GDBState));
     }
diff --git a/hw/ccid-card-passthru.c b/hw/ccid-card-passthru.c
index 082fd82..2cbc81b 100644
--- a/hw/ccid-card-passthru.c
+++ b/hw/ccid-card-passthru.c
@@ -198,7 +198,7 @@ static void ccid_card_vscard_handle_message(PassthruState *card,
 
 static void ccid_card_vscard_drop_connection(PassthruState *card)
 {
-    qemu_chr_close(card->cs);
+    qemu_chr_delete(card->cs);
     card->vscard_in_pos = card->vscard_in_hdr = 0;
 }
 
diff --git a/hw/usb-serial.c b/hw/usb-serial.c
index 0637ee9..7dbf6df 100644
--- a/hw/usb-serial.c
+++ b/hw/usb-serial.c
@@ -428,7 +428,7 @@ static void usb_serial_handle_destroy(USBDevice *dev)
 {
     USBSerialState *s = (USBSerialState *)dev;
 
-    qemu_chr_close(s->cs);
+    qemu_chr_delete(s->cs);
 }
 
 static int usb_serial_can_read(void *opaque)
diff --git a/qemu-char.c b/qemu-char.c
index 1395235..c0af8f3 100644
--- a/qemu-char.c
+++ b/qemu-char.c
@@ -2370,7 +2370,7 @@ QString *qemu_chr_mem_to_qs(CharDriverState *chr)
     return qstring_from_substr((char *) d->outbuf, 0, d->outbuf_size - 1);
 }
 
-/* NOTE: this driver can not be closed with qemu_chr_close()! */
+/* NOTE: this driver can not be closed with qemu_chr_delete()! */
 void qemu_chr_close_mem(CharDriverState *chr)
 {
     MemoryDriver *d = chr->opaque;
@@ -2646,7 +2646,7 @@ void qemu_chr_fe_close(struct CharDriverState *chr)
     }
 }
 
-void qemu_chr_close(CharDriverState *chr)
+void qemu_chr_delete(CharDriverState *chr)
 {
     QTAILQ_REMOVE(&chardevs, chr, next);
     if (chr->chr_close)
diff --git a/qemu-char.h b/qemu-char.h
index f90b85c..555b5f1 100644
--- a/qemu-char.h
+++ b/qemu-char.h
@@ -84,7 +84,7 @@ CharDriverState *qemu_chr_new(const char *label, const char *filename, void (*in
 void qemu_chr_fe_set_echo(struct CharDriverState *chr, bool echo);
 void qemu_chr_fe_open(struct CharDriverState *chr);
 void qemu_chr_fe_close(struct CharDriverState *chr);
-void qemu_chr_close(CharDriverState *chr);
+void qemu_chr_delete(CharDriverState *chr);
 void qemu_chr_fe_printf(CharDriverState *s, const char *fmt, ...)
     GCC_FMT_ATTR(2, 3);
 int qemu_chr_fe_write(CharDriverState *s, const uint8_t *buf, int len);
diff --git a/usb-redir.c b/usb-redir.c
index 84fa020..c74b156 100644
--- a/usb-redir.c
+++ b/usb-redir.c
@@ -837,7 +837,7 @@ static void usbredir_handle_destroy(USBDevice *udev)
 {
     USBRedirDevice *dev = DO_UPCAST(USBRedirDevice, dev, udev);
 
-    qemu_chr_close(dev->cs);
+    qemu_chr_delete(dev->cs);
     /* Note must be done after qemu_chr_close, as that causes a close event */
     qemu_bh_delete(dev->open_close_bh);
 
commit f69554b9e859f5672afda827a9f8772ff41d0f59
Author: Anthony Liguori <aliguori at us.ibm.com>
Date:   Mon Aug 15 11:17:37 2011 -0500

    char: qemu_chr_open_opts() -> qemu_chr_new_from_opts()
    
    Signed-off-by: Anthony Liguori <aliguori at us.ibm.com>

diff --git a/qemu-char.c b/qemu-char.c
index 4eec8d1..1395235 100644
--- a/qemu-char.c
+++ b/qemu-char.c
@@ -2548,7 +2548,7 @@ static const struct {
 #endif
 };
 
-CharDriverState *qemu_chr_open_opts(QemuOpts *opts,
+CharDriverState *qemu_chr_new_from_opts(QemuOpts *opts,
                                     void (*init)(struct CharDriverState *s))
 {
     CharDriverState *chr;
@@ -2617,7 +2617,7 @@ CharDriverState *qemu_chr_new(const char *label, const char *filename, void (*in
     if (!opts)
         return NULL;
 
-    chr = qemu_chr_open_opts(opts, init);
+    chr = qemu_chr_new_from_opts(opts, init);
     if (chr && qemu_opt_get_bool(opts, "mux", 0)) {
         monitor_init(chr, MONITOR_USE_READLINE);
     }
diff --git a/qemu-char.h b/qemu-char.h
index 097f0e6..f90b85c 100644
--- a/qemu-char.h
+++ b/qemu-char.h
@@ -78,7 +78,7 @@ struct CharDriverState {
 };
 
 QemuOpts *qemu_chr_parse_compat(const char *label, const char *filename);
-CharDriverState *qemu_chr_open_opts(QemuOpts *opts,
+CharDriverState *qemu_chr_new_from_opts(QemuOpts *opts,
                                     void (*init)(struct CharDriverState *s));
 CharDriverState *qemu_chr_new(const char *label, const char *filename, void (*init)(struct CharDriverState *s));
 void qemu_chr_fe_set_echo(struct CharDriverState *chr, bool echo);
diff --git a/vl.c b/vl.c
index 321bc15..5f1a177 100644
--- a/vl.c
+++ b/vl.c
@@ -1689,7 +1689,7 @@ static int chardev_init_func(QemuOpts *opts, void *opaque)
 {
     CharDriverState *chr;
 
-    chr = qemu_chr_open_opts(opts, NULL);
+    chr = qemu_chr_new_from_opts(opts, NULL);
     if (!chr)
         return -1;
     return 0;
commit 27143a445b99a283b3c6529738ba17aa0271746e
Author: Anthony Liguori <aliguori at us.ibm.com>
Date:   Mon Aug 15 11:17:36 2011 -0500

    char: rename qemu_chr_open() -> qemu_chr_new()
    
    Signed-off-by: Anthony Liguori <aliguori at us.ibm.com>

diff --git a/gdbstub.c b/gdbstub.c
index 35bf009..4663682 100644
--- a/gdbstub.c
+++ b/gdbstub.c
@@ -2764,7 +2764,7 @@ int gdbserver_start(const char *device)
             sigaction(SIGINT, &act, NULL);
         }
 #endif
-        chr = qemu_chr_open("gdb", device, NULL);
+        chr = qemu_chr_new("gdb", device, NULL);
         if (!chr)
             return -1;
 
diff --git a/hw/mips_malta.c b/hw/mips_malta.c
index eedbada..86a8ba0 100644
--- a/hw/mips_malta.c
+++ b/hw/mips_malta.c
@@ -443,7 +443,7 @@ static MaltaFPGAState *malta_fpga_init(target_phys_addr_t base, qemu_irq uart_ir
     /* 0xa00 is less than a page, so will still get the right offsets.  */
     cpu_register_physical_memory(base + 0xa00, 0x100000 - 0xa00, malta);
 
-    s->display = qemu_chr_open("fpga", "vc:320x200", malta_fpga_led_init);
+    s->display = qemu_chr_new("fpga", "vc:320x200", malta_fpga_led_init);
 
 #ifdef TARGET_WORDS_BIGENDIAN
     s->uart = serial_mm_init(base + 0x900, 3, uart_irq, 230400, uart_chr, 1, 1);
@@ -784,7 +784,7 @@ void mips_malta_init (ram_addr_t ram_size,
         if (!serial_hds[i]) {
             char label[32];
             snprintf(label, sizeof(label), "serial%d", i);
-            serial_hds[i] = qemu_chr_open(label, "null", NULL);
+            serial_hds[i] = qemu_chr_new(label, "null", NULL);
         }
     }
 
diff --git a/hw/omap2.c b/hw/omap2.c
index e32cd94..7e5820a 100644
--- a/hw/omap2.c
+++ b/hw/omap2.c
@@ -782,7 +782,7 @@ static struct omap_sti_s *omap_sti_init(struct omap_target_agent_s *ta,
     s->irq = irq;
     omap_sti_reset(s);
 
-    s->chr = chr ?: qemu_chr_open("null", "null", NULL);
+    s->chr = chr ?: qemu_chr_new("null", "null", NULL);
 
     iomemtype = l4_register_io_memory(omap_sti_readfn,
                     omap_sti_writefn, s);
diff --git a/hw/omap_uart.c b/hw/omap_uart.c
index 09ae9f8..191a0c2 100644
--- a/hw/omap_uart.c
+++ b/hw/omap_uart.c
@@ -62,11 +62,11 @@ struct omap_uart_s *omap_uart_init(target_phys_addr_t base,
     s->irq = irq;
 #ifdef TARGET_WORDS_BIGENDIAN
     s->serial = serial_mm_init(base, 2, irq, omap_clk_getrate(fclk)/16,
-                               chr ?: qemu_chr_open(label, "null", NULL), 1,
+                               chr ?: qemu_chr_new(label, "null", NULL), 1,
                                1);
 #else
     s->serial = serial_mm_init(base, 2, irq, omap_clk_getrate(fclk)/16,
-                               chr ?: qemu_chr_open(label, "null", NULL), 1,
+                               chr ?: qemu_chr_new(label, "null", NULL), 1,
                                0);
 #endif
     return s;
@@ -185,12 +185,12 @@ void omap_uart_attach(struct omap_uart_s *s, CharDriverState *chr)
 #ifdef TARGET_WORDS_BIGENDIAN
     s->serial = serial_mm_init(s->base, 2, s->irq,
                                omap_clk_getrate(s->fclk) / 16,
-                               chr ?: qemu_chr_open("null", "null", NULL), 1,
+                               chr ?: qemu_chr_new("null", "null", NULL), 1,
                                1);
 #else
     s->serial = serial_mm_init(s->base, 2, s->irq,
                                omap_clk_getrate(s->fclk) / 16,
-                               chr ?: qemu_chr_open("null", "null", NULL), 1,
+                               chr ?: qemu_chr_new("null", "null", NULL), 1,
                                0);
 #endif
 }
diff --git a/hw/usb-serial.c b/hw/usb-serial.c
index a0fbfca..0637ee9 100644
--- a/hw/usb-serial.c
+++ b/hw/usb-serial.c
@@ -538,7 +538,7 @@ static USBDevice *usb_serial_init(const char *filename)
     filename++;
 
     snprintf(label, sizeof(label), "usbserial%d", index++);
-    cdrv = qemu_chr_open(label, filename, NULL);
+    cdrv = qemu_chr_new(label, filename, NULL);
     if (!cdrv)
         return NULL;
 
@@ -561,7 +561,7 @@ static USBDevice *usb_braille_init(const char *unused)
     USBDevice *dev;
     CharDriverState *cdrv;
 
-    cdrv = qemu_chr_open("braille", "braille", NULL);
+    cdrv = qemu_chr_new("braille", "braille", NULL);
     if (!cdrv)
         return NULL;
 
diff --git a/hw/xen_console.c b/hw/xen_console.c
index 8468891..5789bd0 100644
--- a/hw/xen_console.c
+++ b/hw/xen_console.c
@@ -202,7 +202,7 @@ static int con_init(struct XenDevice *xendev)
         con->chr = serial_hds[con->xendev.dev];
     } else {
         snprintf(label, sizeof(label), "xencons%d", con->xendev.dev);
-        con->chr = qemu_chr_open(label, output, NULL);
+        con->chr = qemu_chr_new(label, output, NULL);
     }
 
     xenstore_store_pv_console_info(con->xendev.dev, con->chr);
diff --git a/net/slirp.c b/net/slirp.c
index ec7433f..3b39d21 100644
--- a/net/slirp.c
+++ b/net/slirp.c
@@ -616,7 +616,7 @@ static int slirp_guestfwd(SlirpState *s, const char *config_str,
 
     fwd = g_malloc(sizeof(struct GuestFwd));
     snprintf(buf, sizeof(buf), "guestfwd.tcp.%d", port);
-    fwd->hd = qemu_chr_open(buf, p, NULL);
+    fwd->hd = qemu_chr_new(buf, p, NULL);
     if (!fwd->hd) {
         error_report("could not open guest forwarding device '%s'", buf);
         g_free(fwd);
diff --git a/qemu-char.c b/qemu-char.c
index 9fd8028..4eec8d1 100644
--- a/qemu-char.c
+++ b/qemu-char.c
@@ -2603,7 +2603,7 @@ CharDriverState *qemu_chr_open_opts(QemuOpts *opts,
     return chr;
 }
 
-CharDriverState *qemu_chr_open(const char *label, const char *filename, void (*init)(struct CharDriverState *s))
+CharDriverState *qemu_chr_new(const char *label, const char *filename, void (*init)(struct CharDriverState *s))
 {
     const char *p;
     CharDriverState *chr;
diff --git a/qemu-char.h b/qemu-char.h
index a487454..097f0e6 100644
--- a/qemu-char.h
+++ b/qemu-char.h
@@ -80,7 +80,7 @@ struct CharDriverState {
 QemuOpts *qemu_chr_parse_compat(const char *label, const char *filename);
 CharDriverState *qemu_chr_open_opts(QemuOpts *opts,
                                     void (*init)(struct CharDriverState *s));
-CharDriverState *qemu_chr_open(const char *label, const char *filename, void (*init)(struct CharDriverState *s));
+CharDriverState *qemu_chr_new(const char *label, const char *filename, void (*init)(struct CharDriverState *s));
 void qemu_chr_fe_set_echo(struct CharDriverState *chr, bool echo);
 void qemu_chr_fe_open(struct CharDriverState *chr);
 void qemu_chr_fe_close(struct CharDriverState *chr);
diff --git a/vl.c b/vl.c
index 06a6f80..321bc15 100644
--- a/vl.c
+++ b/vl.c
@@ -1828,7 +1828,7 @@ static int serial_parse(const char *devname)
         exit(1);
     }
     snprintf(label, sizeof(label), "serial%d", index);
-    serial_hds[index] = qemu_chr_open(label, devname, NULL);
+    serial_hds[index] = qemu_chr_new(label, devname, NULL);
     if (!serial_hds[index]) {
         fprintf(stderr, "qemu: could not open serial device '%s': %s\n",
                 devname, strerror(errno));
@@ -1850,7 +1850,7 @@ static int parallel_parse(const char *devname)
         exit(1);
     }
     snprintf(label, sizeof(label), "parallel%d", index);
-    parallel_hds[index] = qemu_chr_open(label, devname, NULL);
+    parallel_hds[index] = qemu_chr_new(label, devname, NULL);
     if (!parallel_hds[index]) {
         fprintf(stderr, "qemu: could not open parallel device '%s': %s\n",
                 devname, strerror(errno));
@@ -1881,7 +1881,7 @@ static int virtcon_parse(const char *devname)
     qemu_opt_set(dev_opts, "driver", "virtconsole");
 
     snprintf(label, sizeof(label), "virtcon%d", index);
-    virtcon_hds[index] = qemu_chr_open(label, devname, NULL);
+    virtcon_hds[index] = qemu_chr_new(label, devname, NULL);
     if (!virtcon_hds[index]) {
         fprintf(stderr, "qemu: could not open virtio console '%s': %s\n",
                 devname, strerror(errno));
@@ -1897,7 +1897,7 @@ static int debugcon_parse(const char *devname)
 {   
     QemuOpts *opts;
 
-    if (!qemu_chr_open("debugcon", devname, NULL)) {
+    if (!qemu_chr_new("debugcon", devname, NULL)) {
         exit(1);
     }
     opts = qemu_opts_create(qemu_find_opts("device"), "debugcon", 1);
commit 15f31519b423747285bdc924ec4138c554076a73
Author: Anthony Liguori <aliguori at us.ibm.com>
Date:   Mon Aug 15 11:17:35 2011 -0500

    char: rename qemu_chr_set_echo() -> qemu_chr_fe_set_echo()
    
    Signed-off-by: Anthony Liguori <aliguori at us.ibm.com>

diff --git a/monitor.c b/monitor.c
index f95d959..cc1b7be 100644
--- a/monitor.c
+++ b/monitor.c
@@ -5287,7 +5287,7 @@ void monitor_init(CharDriverState *chr, int flags)
         /* Control mode requires special handlers */
         qemu_chr_add_handlers(chr, monitor_can_read, monitor_control_read,
                               monitor_control_event, mon);
-        qemu_chr_set_echo(chr, true);
+        qemu_chr_fe_set_echo(chr, true);
     } else {
         qemu_chr_add_handlers(chr, monitor_can_read, monitor_read,
                               monitor_event, mon);
diff --git a/qemu-char.c b/qemu-char.c
index 4789db3..9fd8028 100644
--- a/qemu-char.c
+++ b/qemu-char.c
@@ -795,7 +795,7 @@ static int qemu_chr_open_stdio(QemuOpts *opts, CharDriverState **_chr)
     stdio_nb_clients++;
     stdio_allow_signal = qemu_opt_get_bool(opts, "signal",
                                            display_type != DT_NOGRAPHIC);
-    qemu_chr_set_echo(chr, false);
+    qemu_chr_fe_set_echo(chr, false);
 
     *_chr = chr;
     return 0;
@@ -2625,7 +2625,7 @@ CharDriverState *qemu_chr_open(const char *label, const char *filename, void (*i
     return chr;
 }
 
-void qemu_chr_set_echo(struct CharDriverState *chr, bool echo)
+void qemu_chr_fe_set_echo(struct CharDriverState *chr, bool echo)
 {
     if (chr->chr_set_echo) {
         chr->chr_set_echo(chr, echo);
diff --git a/qemu-char.h b/qemu-char.h
index 513daa9..a487454 100644
--- a/qemu-char.h
+++ b/qemu-char.h
@@ -81,7 +81,7 @@ QemuOpts *qemu_chr_parse_compat(const char *label, const char *filename);
 CharDriverState *qemu_chr_open_opts(QemuOpts *opts,
                                     void (*init)(struct CharDriverState *s));
 CharDriverState *qemu_chr_open(const char *label, const char *filename, void (*init)(struct CharDriverState *s));
-void qemu_chr_set_echo(struct CharDriverState *chr, bool echo);
+void qemu_chr_fe_set_echo(struct CharDriverState *chr, bool echo);
 void qemu_chr_fe_open(struct CharDriverState *chr);
 void qemu_chr_fe_close(struct CharDriverState *chr);
 void qemu_chr_close(CharDriverState *chr);
commit 41084f1badadcb054823dfe57c58eafefe50d8a8
Author: Anthony Liguori <aliguori at us.ibm.com>
Date:   Mon Aug 15 11:17:34 2011 -0500

    char: qemu_chr_ioctl() -> qemu_chr_fe_ioctl()
    
    Signed-off-by: Anthony Liguori <aliguori at us.ibm.com>

diff --git a/hw/escc.c b/hw/escc.c
index b2391b2..13c7e66 100644
--- a/hw/escc.c
+++ b/hw/escc.c
@@ -460,7 +460,7 @@ static void escc_update_parameters(ChannelState *s)
     ssp.data_bits = data_bits;
     ssp.stop_bits = stop_bits;
     trace_escc_update_parameters(CHN_C(s), speed, parity, data_bits, stop_bits);
-    qemu_chr_ioctl(s->chr, CHR_IOCTL_SERIAL_SET_PARAMS, &ssp);
+    qemu_chr_fe_ioctl(s->chr, CHR_IOCTL_SERIAL_SET_PARAMS, &ssp);
 }
 
 static void escc_mem_write(void *opaque, target_phys_addr_t addr,
diff --git a/hw/parallel.c b/hw/parallel.c
index 84feab8..ecbc8c3 100644
--- a/hw/parallel.c
+++ b/hw/parallel.c
@@ -150,7 +150,7 @@ static void parallel_ioport_write_hw(void *opaque, uint32_t addr, uint32_t val)
         if (s->dataw == val)
             return;
         pdebug("wd%02x\n", val);
-        qemu_chr_ioctl(s->chr, CHR_IOCTL_PP_WRITE_DATA, &parm);
+        qemu_chr_fe_ioctl(s->chr, CHR_IOCTL_PP_WRITE_DATA, &parm);
         s->dataw = val;
         break;
     case PARA_REG_STS:
@@ -170,11 +170,11 @@ static void parallel_ioport_write_hw(void *opaque, uint32_t addr, uint32_t val)
             } else {
                 dir = 0;
             }
-            qemu_chr_ioctl(s->chr, CHR_IOCTL_PP_DATA_DIR, &dir);
+            qemu_chr_fe_ioctl(s->chr, CHR_IOCTL_PP_DATA_DIR, &dir);
             parm &= ~PARA_CTR_DIR;
         }
 
-        qemu_chr_ioctl(s->chr, CHR_IOCTL_PP_WRITE_CONTROL, &parm);
+        qemu_chr_fe_ioctl(s->chr, CHR_IOCTL_PP_WRITE_CONTROL, &parm);
         s->control = val;
         break;
     case PARA_REG_EPP_ADDR:
@@ -183,7 +183,7 @@ static void parallel_ioport_write_hw(void *opaque, uint32_t addr, uint32_t val)
             pdebug("wa%02x s\n", val);
         else {
             struct ParallelIOArg ioarg = { .buffer = &parm, .count = 1 };
-            if (qemu_chr_ioctl(s->chr, CHR_IOCTL_PP_EPP_WRITE_ADDR, &ioarg)) {
+            if (qemu_chr_fe_ioctl(s->chr, CHR_IOCTL_PP_EPP_WRITE_ADDR, &ioarg)) {
                 s->epp_timeout = 1;
                 pdebug("wa%02x t\n", val);
             }
@@ -197,7 +197,7 @@ static void parallel_ioport_write_hw(void *opaque, uint32_t addr, uint32_t val)
             pdebug("we%02x s\n", val);
         else {
             struct ParallelIOArg ioarg = { .buffer = &parm, .count = 1 };
-            if (qemu_chr_ioctl(s->chr, CHR_IOCTL_PP_EPP_WRITE, &ioarg)) {
+            if (qemu_chr_fe_ioctl(s->chr, CHR_IOCTL_PP_EPP_WRITE, &ioarg)) {
                 s->epp_timeout = 1;
                 pdebug("we%02x t\n", val);
             }
@@ -222,7 +222,7 @@ parallel_ioport_eppdata_write_hw2(void *opaque, uint32_t addr, uint32_t val)
         pdebug("we%04x s\n", val);
         return;
     }
-    err = qemu_chr_ioctl(s->chr, CHR_IOCTL_PP_EPP_WRITE, &ioarg);
+    err = qemu_chr_fe_ioctl(s->chr, CHR_IOCTL_PP_EPP_WRITE, &ioarg);
     if (err) {
         s->epp_timeout = 1;
         pdebug("we%04x t\n", val);
@@ -245,7 +245,7 @@ parallel_ioport_eppdata_write_hw4(void *opaque, uint32_t addr, uint32_t val)
         pdebug("we%08x s\n", val);
         return;
     }
-    err = qemu_chr_ioctl(s->chr, CHR_IOCTL_PP_EPP_WRITE, &ioarg);
+    err = qemu_chr_fe_ioctl(s->chr, CHR_IOCTL_PP_EPP_WRITE, &ioarg);
     if (err) {
         s->epp_timeout = 1;
         pdebug("we%08x t\n", val);
@@ -297,13 +297,13 @@ static uint32_t parallel_ioport_read_hw(void *opaque, uint32_t addr)
     addr &= 7;
     switch(addr) {
     case PARA_REG_DATA:
-        qemu_chr_ioctl(s->chr, CHR_IOCTL_PP_READ_DATA, &ret);
+        qemu_chr_fe_ioctl(s->chr, CHR_IOCTL_PP_READ_DATA, &ret);
         if (s->last_read_offset != addr || s->datar != ret)
             pdebug("rd%02x\n", ret);
         s->datar = ret;
         break;
     case PARA_REG_STS:
-        qemu_chr_ioctl(s->chr, CHR_IOCTL_PP_READ_STATUS, &ret);
+        qemu_chr_fe_ioctl(s->chr, CHR_IOCTL_PP_READ_STATUS, &ret);
         ret &= ~PARA_STS_TMOUT;
         if (s->epp_timeout)
             ret |= PARA_STS_TMOUT;
@@ -315,7 +315,7 @@ static uint32_t parallel_ioport_read_hw(void *opaque, uint32_t addr)
         /* s->control has some bits fixed to 1. It is zero only when
            it has not been yet written to.  */
         if (s->control == 0) {
-            qemu_chr_ioctl(s->chr, CHR_IOCTL_PP_READ_CONTROL, &ret);
+            qemu_chr_fe_ioctl(s->chr, CHR_IOCTL_PP_READ_CONTROL, &ret);
             if (s->last_read_offset != addr)
                 pdebug("rc%02x\n", ret);
             s->control = ret;
@@ -332,7 +332,7 @@ static uint32_t parallel_ioport_read_hw(void *opaque, uint32_t addr)
             pdebug("ra%02x s\n", ret);
         else {
             struct ParallelIOArg ioarg = { .buffer = &ret, .count = 1 };
-            if (qemu_chr_ioctl(s->chr, CHR_IOCTL_PP_EPP_READ_ADDR, &ioarg)) {
+            if (qemu_chr_fe_ioctl(s->chr, CHR_IOCTL_PP_EPP_READ_ADDR, &ioarg)) {
                 s->epp_timeout = 1;
                 pdebug("ra%02x t\n", ret);
             }
@@ -346,7 +346,7 @@ static uint32_t parallel_ioport_read_hw(void *opaque, uint32_t addr)
             pdebug("re%02x s\n", ret);
         else {
             struct ParallelIOArg ioarg = { .buffer = &ret, .count = 1 };
-            if (qemu_chr_ioctl(s->chr, CHR_IOCTL_PP_EPP_READ, &ioarg)) {
+            if (qemu_chr_fe_ioctl(s->chr, CHR_IOCTL_PP_EPP_READ, &ioarg)) {
                 s->epp_timeout = 1;
                 pdebug("re%02x t\n", ret);
             }
@@ -374,7 +374,7 @@ parallel_ioport_eppdata_read_hw2(void *opaque, uint32_t addr)
         pdebug("re%04x s\n", eppdata);
         return eppdata;
     }
-    err = qemu_chr_ioctl(s->chr, CHR_IOCTL_PP_EPP_READ, &ioarg);
+    err = qemu_chr_fe_ioctl(s->chr, CHR_IOCTL_PP_EPP_READ, &ioarg);
     ret = le16_to_cpu(eppdata);
 
     if (err) {
@@ -401,7 +401,7 @@ parallel_ioport_eppdata_read_hw4(void *opaque, uint32_t addr)
         pdebug("re%08x s\n", eppdata);
         return eppdata;
     }
-    err = qemu_chr_ioctl(s->chr, CHR_IOCTL_PP_EPP_READ, &ioarg);
+    err = qemu_chr_fe_ioctl(s->chr, CHR_IOCTL_PP_EPP_READ, &ioarg);
     ret = le32_to_cpu(eppdata);
 
     if (err) {
@@ -473,7 +473,7 @@ static int parallel_isa_initfn(ISADevice *dev)
     isa_init_irq(dev, &s->irq, isa->isairq);
     qemu_register_reset(parallel_reset, s);
 
-    if (qemu_chr_ioctl(s->chr, CHR_IOCTL_PP_READ_STATUS, &dummy) == 0) {
+    if (qemu_chr_fe_ioctl(s->chr, CHR_IOCTL_PP_READ_STATUS, &dummy) == 0) {
         s->hw_driver = 1;
         s->status = dummy;
     }
diff --git a/hw/serial.c b/hw/serial.c
index 427eb4b..ed7fd0a 100644
--- a/hw/serial.c
+++ b/hw/serial.c
@@ -274,7 +274,7 @@ static void serial_update_parameters(SerialState *s)
     ssp.data_bits = data_bits;
     ssp.stop_bits = stop_bits;
     s->char_transmit_time =  (get_ticks_per_sec() / speed) * frame_size;
-    qemu_chr_ioctl(s->chr, CHR_IOCTL_SERIAL_SET_PARAMS, &ssp);
+    qemu_chr_fe_ioctl(s->chr, CHR_IOCTL_SERIAL_SET_PARAMS, &ssp);
 
     DPRINTF("speed=%d parity=%c data=%d stop=%d\n",
            speed, parity, data_bits, stop_bits);
@@ -287,7 +287,7 @@ static void serial_update_msl(SerialState *s)
 
     qemu_del_timer(s->modem_status_poll);
 
-    if (qemu_chr_ioctl(s->chr,CHR_IOCTL_SERIAL_GET_TIOCM, &flags) == -ENOTSUP) {
+    if (qemu_chr_fe_ioctl(s->chr,CHR_IOCTL_SERIAL_GET_TIOCM, &flags) == -ENOTSUP) {
         s->poll_msl = -1;
         return;
     }
@@ -467,7 +467,7 @@ static void serial_ioport_write(void *opaque, uint32_t addr, uint32_t val)
             break_enable = (val >> 6) & 1;
             if (break_enable != s->last_break_enable) {
                 s->last_break_enable = break_enable;
-                qemu_chr_ioctl(s->chr, CHR_IOCTL_SERIAL_SET_BREAK,
+                qemu_chr_fe_ioctl(s->chr, CHR_IOCTL_SERIAL_SET_BREAK,
                                &break_enable);
             }
         }
@@ -482,7 +482,7 @@ static void serial_ioport_write(void *opaque, uint32_t addr, uint32_t val)
 
             if (s->poll_msl >= 0 && old_mcr != s->mcr) {
 
-                qemu_chr_ioctl(s->chr,CHR_IOCTL_SERIAL_GET_TIOCM, &flags);
+                qemu_chr_fe_ioctl(s->chr,CHR_IOCTL_SERIAL_GET_TIOCM, &flags);
 
                 flags &= ~(CHR_TIOCM_RTS | CHR_TIOCM_DTR);
 
@@ -491,7 +491,7 @@ static void serial_ioport_write(void *opaque, uint32_t addr, uint32_t val)
                 if (val & UART_MCR_DTR)
                     flags |= CHR_TIOCM_DTR;
 
-                qemu_chr_ioctl(s->chr,CHR_IOCTL_SERIAL_SET_TIOCM, &flags);
+                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);
diff --git a/hw/strongarm.c b/hw/strongarm.c
index 84855cb..6097ea2 100644
--- a/hw/strongarm.c
+++ b/hw/strongarm.c
@@ -980,7 +980,7 @@ static void strongarm_uart_update_parameters(StrongARMUARTState *s)
     ssp.stop_bits = stop_bits;
     s->char_transmit_time =  (get_ticks_per_sec() / speed) * frame_size;
     if (s->chr) {
-        qemu_chr_ioctl(s->chr, CHR_IOCTL_SERIAL_SET_PARAMS, &ssp);
+        qemu_chr_fe_ioctl(s->chr, CHR_IOCTL_SERIAL_SET_PARAMS, &ssp);
     }
 
     DPRINTF(stderr, "%s speed=%d parity=%c data=%d stop=%d\n", s->chr->label,
diff --git a/hw/usb-serial.c b/hw/usb-serial.c
index 8ed0fa6..a0fbfca 100644
--- a/hw/usb-serial.c
+++ b/hw/usb-serial.c
@@ -203,7 +203,7 @@ static uint8_t usb_get_modem_lines(USBSerialState *s)
     int flags;
     uint8_t ret;
 
-    if (qemu_chr_ioctl(s->cs, CHR_IOCTL_SERIAL_GET_TIOCM, &flags) == -ENOTSUP)
+    if (qemu_chr_fe_ioctl(s->cs, CHR_IOCTL_SERIAL_GET_TIOCM, &flags) == -ENOTSUP)
         return FTDI_CTS|FTDI_DSR|FTDI_RLSD;
 
     ret = 0;
@@ -263,7 +263,7 @@ static int usb_serial_handle_control(USBDevice *dev, USBPacket *p,
     case DeviceOutVendor | FTDI_SET_MDM_CTRL:
     {
         static int flags;
-        qemu_chr_ioctl(s->cs,CHR_IOCTL_SERIAL_GET_TIOCM, &flags);
+        qemu_chr_fe_ioctl(s->cs,CHR_IOCTL_SERIAL_GET_TIOCM, &flags);
         if (value & FTDI_SET_RTS) {
             if (value & FTDI_RTS)
                 flags |= CHR_TIOCM_RTS;
@@ -276,7 +276,7 @@ static int usb_serial_handle_control(USBDevice *dev, USBPacket *p,
             else
                 flags &= ~CHR_TIOCM_DTR;
         }
-        qemu_chr_ioctl(s->cs,CHR_IOCTL_SERIAL_SET_TIOCM, &flags);
+        qemu_chr_fe_ioctl(s->cs,CHR_IOCTL_SERIAL_SET_TIOCM, &flags);
         break;
     }
     case DeviceOutVendor | FTDI_SET_FLOW_CTRL:
@@ -295,7 +295,7 @@ static int usb_serial_handle_control(USBDevice *dev, USBPacket *p,
             divisor = 1;
 
         s->params.speed = (48000000 / 2) / (8 * divisor + subdivisor8);
-        qemu_chr_ioctl(s->cs, CHR_IOCTL_SERIAL_SET_PARAMS, &s->params);
+        qemu_chr_fe_ioctl(s->cs, CHR_IOCTL_SERIAL_SET_PARAMS, &s->params);
         break;
     }
     case DeviceOutVendor | FTDI_SET_DATA:
@@ -324,7 +324,7 @@ static int usb_serial_handle_control(USBDevice *dev, USBPacket *p,
                 DPRINTF("unsupported stop bits %d\n", value & FTDI_STOP);
                 goto fail;
         }
-        qemu_chr_ioctl(s->cs, CHR_IOCTL_SERIAL_SET_PARAMS, &s->params);
+        qemu_chr_fe_ioctl(s->cs, CHR_IOCTL_SERIAL_SET_PARAMS, &s->params);
         /* TODO: TX ON/OFF */
         break;
     case DeviceInVendor | FTDI_GET_MDM_ST:
diff --git a/qemu-char.c b/qemu-char.c
index d0a0fb1..4789db3 100644
--- a/qemu-char.c
+++ b/qemu-char.c
@@ -144,7 +144,7 @@ int qemu_chr_fe_write(CharDriverState *s, const uint8_t *buf, int len)
     return s->chr_write(s, buf, len);
 }
 
-int qemu_chr_ioctl(CharDriverState *s, int cmd, void *arg)
+int qemu_chr_fe_ioctl(CharDriverState *s, int cmd, void *arg)
 {
     if (!s->chr_ioctl)
         return -ENOTSUP;
diff --git a/qemu-char.h b/qemu-char.h
index c95b554..513daa9 100644
--- a/qemu-char.h
+++ b/qemu-char.h
@@ -94,7 +94,7 @@ void qemu_chr_add_handlers(CharDriverState *s,
                            IOReadHandler *fd_read,
                            IOEventHandler *fd_event,
                            void *opaque);
-int qemu_chr_ioctl(CharDriverState *s, int cmd, void *arg);
+int qemu_chr_fe_ioctl(CharDriverState *s, int cmd, void *arg);
 void qemu_chr_generic_open(CharDriverState *s);
 int qemu_chr_be_can_write(CharDriverState *s);
 void qemu_chr_be_write(CharDriverState *s, uint8_t *buf, int len);
commit 2817822dced78521ab7c532ea50959aa248ea8c0
Author: Anthony Liguori <aliguori at us.ibm.com>
Date:   Mon Aug 15 11:17:33 2011 -0500

    char: rename qemu_chr_guest_close() -> qemu_chr_fe_close()
    
    Signed-off-by: Anthony Liguori <aliguori at us.ibm.com>

diff --git a/hw/virtio-console.c b/hw/virtio-console.c
index 21f752b..d3351c8 100644
--- a/hw/virtio-console.c
+++ b/hw/virtio-console.c
@@ -60,7 +60,7 @@ static void guest_close(VirtIOSerialPort *port)
 {
     VirtConsole *vcon = DO_UPCAST(VirtConsole, port, port);
 
-    qemu_chr_guest_close(vcon->chr);
+    qemu_chr_fe_close(vcon->chr);
 }
 
 /* Readiness of the guest to accept data on a port */
diff --git a/qemu-char.c b/qemu-char.c
index eb0cc74..d0a0fb1 100644
--- a/qemu-char.c
+++ b/qemu-char.c
@@ -2639,7 +2639,7 @@ void qemu_chr_fe_open(struct CharDriverState *chr)
     }
 }
 
-void qemu_chr_guest_close(struct CharDriverState *chr)
+void qemu_chr_fe_close(struct CharDriverState *chr)
 {
     if (chr->chr_guest_close) {
         chr->chr_guest_close(chr);
diff --git a/qemu-char.h b/qemu-char.h
index ad770cd..c95b554 100644
--- a/qemu-char.h
+++ b/qemu-char.h
@@ -83,7 +83,7 @@ CharDriverState *qemu_chr_open_opts(QemuOpts *opts,
 CharDriverState *qemu_chr_open(const char *label, const char *filename, void (*init)(struct CharDriverState *s));
 void qemu_chr_set_echo(struct CharDriverState *chr, bool echo);
 void qemu_chr_fe_open(struct CharDriverState *chr);
-void qemu_chr_guest_close(struct CharDriverState *chr);
+void qemu_chr_fe_close(struct CharDriverState *chr);
 void qemu_chr_close(CharDriverState *chr);
 void qemu_chr_fe_printf(CharDriverState *s, const char *fmt, ...)
     GCC_FMT_ATTR(2, 3);
commit c9d830eddc58db80a954a4eef1dc1e6ef8ca55b3
Author: Anthony Liguori <aliguori at us.ibm.com>
Date:   Mon Aug 15 11:17:32 2011 -0500

    char: rename qemu_chr_guest_open() -> qemu_chr_fe_open()
    
    Signed-off-by: Anthony Liguori <aliguori at us.ibm.com>

diff --git a/hw/virtio-console.c b/hw/virtio-console.c
index 6c386fa..21f752b 100644
--- a/hw/virtio-console.c
+++ b/hw/virtio-console.c
@@ -52,7 +52,7 @@ static void guest_open(VirtIOSerialPort *port)
 {
     VirtConsole *vcon = DO_UPCAST(VirtConsole, port, port);
 
-    qemu_chr_guest_open(vcon->chr);
+    qemu_chr_fe_open(vcon->chr);
 }
 
 /* Callback function that's called when the guest closes the port */
diff --git a/qemu-char.c b/qemu-char.c
index d3bfcaf..eb0cc74 100644
--- a/qemu-char.c
+++ b/qemu-char.c
@@ -2632,7 +2632,7 @@ void qemu_chr_set_echo(struct CharDriverState *chr, bool echo)
     }
 }
 
-void qemu_chr_guest_open(struct CharDriverState *chr)
+void qemu_chr_fe_open(struct CharDriverState *chr)
 {
     if (chr->chr_guest_open) {
         chr->chr_guest_open(chr);
diff --git a/qemu-char.h b/qemu-char.h
index 3500a57..ad770cd 100644
--- a/qemu-char.h
+++ b/qemu-char.h
@@ -82,7 +82,7 @@ CharDriverState *qemu_chr_open_opts(QemuOpts *opts,
                                     void (*init)(struct CharDriverState *s));
 CharDriverState *qemu_chr_open(const char *label, const char *filename, void (*init)(struct CharDriverState *s));
 void qemu_chr_set_echo(struct CharDriverState *chr, bool echo);
-void qemu_chr_guest_open(struct CharDriverState *chr);
+void qemu_chr_fe_open(struct CharDriverState *chr);
 void qemu_chr_guest_close(struct CharDriverState *chr);
 void qemu_chr_close(CharDriverState *chr);
 void qemu_chr_fe_printf(CharDriverState *s, const char *fmt, ...)
commit 909cda12b57d8742d67470c5350ecc4012267cb2
Author: Anthony Liguori <aliguori at us.ibm.com>
Date:   Mon Aug 15 11:17:31 2011 -0500

    char: rename qemu_chr_can_read() -> qemu_chr_be_can_read()
    
    Signed-off-by: Anthony Liguori <aliguori at us.ibm.com>

diff --git a/console.c b/console.c
index 64246b7..553358b 100644
--- a/console.c
+++ b/console.c
@@ -1123,7 +1123,7 @@ static void kbd_send_chars(void *opaque)
     int len;
     uint8_t buf[16];
 
-    len = qemu_chr_can_read(s->chr);
+    len = qemu_chr_be_can_write(s->chr);
     if (len > s->out_fifo.count)
         len = s->out_fifo.count;
     if (len > 0) {
diff --git a/hw/baum.c b/hw/baum.c
index 51e0c8f..1c6d3e2 100644
--- a/hw/baum.c
+++ b/hw/baum.c
@@ -223,7 +223,7 @@ static void baum_accept_input(struct CharDriverState *chr)
 
     if (!baum->out_buf_used)
         return;
-    room = qemu_chr_can_read(chr);
+    room = qemu_chr_be_can_write(chr);
     if (!room)
         return;
     if (room > baum->out_buf_used)
@@ -250,7 +250,7 @@ static void baum_write_packet(BaumDriverState *baum, const uint8_t *buf, int len
     while (len--)
         if ((*cur++ = *buf++) == ESC)
             *cur++ = ESC;
-    room = qemu_chr_can_read(baum->chr);
+    room = qemu_chr_be_can_write(baum->chr);
     len = cur - io_buf;
     if (len <= room) {
         /* Fits */
diff --git a/qemu-char.c b/qemu-char.c
index 0786ab4..d3bfcaf 100644
--- a/qemu-char.c
+++ b/qemu-char.c
@@ -151,7 +151,7 @@ int qemu_chr_ioctl(CharDriverState *s, int cmd, void *arg)
     return s->chr_ioctl(s, cmd, arg);
 }
 
-int qemu_chr_can_read(CharDriverState *s)
+int qemu_chr_be_can_write(CharDriverState *s)
 {
     if (!s->chr_can_read)
         return 0;
@@ -565,7 +565,7 @@ static int fd_chr_read_poll(void *opaque)
     CharDriverState *chr = opaque;
     FDCharDriver *s = chr->opaque;
 
-    s->max_size = qemu_chr_can_read(chr);
+    s->max_size = qemu_chr_be_can_write(chr);
     return s->max_size;
 }
 
@@ -699,7 +699,7 @@ static int stdio_read_poll(void *opaque)
     CharDriverState *chr = opaque;
 
     /* try to flush the queue if needed */
-    if (term_fifo_size != 0 && qemu_chr_can_read(chr) > 0) {
+    if (term_fifo_size != 0 && qemu_chr_be_can_write(chr) > 0) {
         qemu_chr_be_write(chr, term_fifo, 1);
         term_fifo_size = 0;
     }
@@ -724,7 +724,7 @@ static void stdio_read(void *opaque)
         return;
     }
     if (size > 0) {
-        if (qemu_chr_can_read(chr) > 0) {
+        if (qemu_chr_be_can_write(chr) > 0) {
             qemu_chr_be_write(chr, buf, 1);
         } else if (term_fifo_size == 0) {
             term_fifo[term_fifo_size++] = buf[0];
@@ -890,7 +890,7 @@ static int pty_chr_read_poll(void *opaque)
     CharDriverState *chr = opaque;
     PtyCharDriver *s = chr->opaque;
 
-    s->read_bytes = qemu_chr_can_read(chr);
+    s->read_bytes = qemu_chr_be_can_write(chr);
     return s->read_bytes;
 }
 
@@ -1602,7 +1602,7 @@ static int win_chr_read_poll(CharDriverState *chr)
 {
     WinCharState *s = chr->opaque;
 
-    s->max_size = qemu_chr_can_read(chr);
+    s->max_size = qemu_chr_be_can_write(chr);
     return s->max_size;
 }
 
@@ -1840,7 +1840,7 @@ static int udp_chr_read_poll(void *opaque)
     CharDriverState *chr = opaque;
     NetCharDriver *s = chr->opaque;
 
-    s->max_size = qemu_chr_can_read(chr);
+    s->max_size = qemu_chr_be_can_write(chr);
 
     /* If there were any stray characters in the queue process them
      * first
@@ -1848,7 +1848,7 @@ static int udp_chr_read_poll(void *opaque)
     while (s->max_size > 0 && s->bufptr < s->bufcnt) {
         qemu_chr_be_write(chr, &s->buf[s->bufptr], 1);
         s->bufptr++;
-        s->max_size = qemu_chr_can_read(chr);
+        s->max_size = qemu_chr_be_can_write(chr);
     }
     return s->max_size;
 }
@@ -1869,7 +1869,7 @@ static void udp_chr_read(void *opaque)
     while (s->max_size > 0 && s->bufptr < s->bufcnt) {
         qemu_chr_be_write(chr, &s->buf[s->bufptr], 1);
         s->bufptr++;
-        s->max_size = qemu_chr_can_read(chr);
+        s->max_size = qemu_chr_be_can_write(chr);
     }
 }
 
@@ -1963,7 +1963,7 @@ static int tcp_chr_read_poll(void *opaque)
     TCPCharDriver *s = chr->opaque;
     if (!s->connected)
         return 0;
-    s->max_size = qemu_chr_can_read(chr);
+    s->max_size = qemu_chr_be_can_write(chr);
     return s->max_size;
 }
 
diff --git a/qemu-char.h b/qemu-char.h
index b16e566..3500a57 100644
--- a/qemu-char.h
+++ b/qemu-char.h
@@ -96,7 +96,7 @@ void qemu_chr_add_handlers(CharDriverState *s,
                            void *opaque);
 int qemu_chr_ioctl(CharDriverState *s, int cmd, void *arg);
 void qemu_chr_generic_open(CharDriverState *s);
-int qemu_chr_can_read(CharDriverState *s);
+int qemu_chr_be_can_write(CharDriverState *s);
 void qemu_chr_be_write(CharDriverState *s, uint8_t *buf, int len);
 int qemu_chr_get_msgfd(CharDriverState *s);
 void qemu_chr_accept_input(CharDriverState *s);
diff --git a/spice-qemu-char.c b/spice-qemu-char.c
index f3e7702..a9323f3 100644
--- a/spice-qemu-char.c
+++ b/spice-qemu-char.c
@@ -36,7 +36,7 @@ static int vmc_write(SpiceCharDeviceInstance *sin, const uint8_t *buf, int len)
 
     while (len > 0) {
         last_out = MIN(len, VMC_MAX_HOST_WRITE);
-        if (qemu_chr_can_read(scd->chr) < last_out) {
+        if (qemu_chr_be_can_write(scd->chr) < last_out) {
             break;
         }
         qemu_chr_be_write(scd->chr, p, last_out);
commit fa5efccb2a063f1dee46ed3ebd9192b318009f65
Author: Anthony Liguori <aliguori at us.ibm.com>
Date:   Mon Aug 15 11:17:30 2011 -0500

    char: rename qemu_chr_read() -> qemu_chr_be_write()
    
    Signed-off-by: Anthony Liguori <aliguori at us.ibm.com>

diff --git a/console.c b/console.c
index ec529ae..64246b7 100644
--- a/console.c
+++ b/console.c
@@ -1130,7 +1130,7 @@ static void kbd_send_chars(void *opaque)
         if (len > sizeof(buf))
             len = sizeof(buf);
         qemu_fifo_read(&s->out_fifo, buf, len);
-        qemu_chr_read(s->chr, buf, len);
+        qemu_chr_be_write(s->chr, buf, len);
     }
     /* characters are pending: we send them a bit later (XXX:
        horrible, should change char device API) */
diff --git a/gdbstub.c b/gdbstub.c
index b0f57c1..35bf009 100644
--- a/gdbstub.c
+++ b/gdbstub.c
@@ -2194,7 +2194,7 @@ static int gdb_handle_packet(GDBState *s, const char *line_buf)
             hextomem(mem_buf, p + 5, len);
             len = len / 2;
             mem_buf[len++] = 0;
-            qemu_chr_read(s->mon_chr, mem_buf, len);
+            qemu_chr_be_write(s->mon_chr, mem_buf, len);
             put_packet(s, "OK");
             break;
         }
diff --git a/hw/baum.c b/hw/baum.c
index 26beeaf..51e0c8f 100644
--- a/hw/baum.c
+++ b/hw/baum.c
@@ -231,12 +231,12 @@ static void baum_accept_input(struct CharDriverState *chr)
 
     first = BUF_SIZE - baum->out_buf_ptr;
     if (room > first) {
-        qemu_chr_read(chr, baum->out_buf + baum->out_buf_ptr, first);
+        qemu_chr_be_write(chr, baum->out_buf + baum->out_buf_ptr, first);
         baum->out_buf_ptr = 0;
         baum->out_buf_used -= first;
         room -= first;
     }
-    qemu_chr_read(chr, baum->out_buf + baum->out_buf_ptr, room);
+    qemu_chr_be_write(chr, baum->out_buf + baum->out_buf_ptr, room);
     baum->out_buf_ptr += room;
     baum->out_buf_used -= room;
 }
@@ -254,12 +254,12 @@ static void baum_write_packet(BaumDriverState *baum, const uint8_t *buf, int len
     len = cur - io_buf;
     if (len <= room) {
         /* Fits */
-        qemu_chr_read(baum->chr, io_buf, len);
+        qemu_chr_be_write(baum->chr, io_buf, len);
     } else {
         int first;
         uint8_t out;
         /* Can't fit all, send what can be, and store the rest. */
-        qemu_chr_read(baum->chr, io_buf, room);
+        qemu_chr_be_write(baum->chr, io_buf, room);
         len -= room;
         cur = io_buf + room;
         if (len > BUF_SIZE - baum->out_buf_used) {
diff --git a/hw/msmouse.c b/hw/msmouse.c
index b611c2f..c3b57ea 100644
--- a/hw/msmouse.c
+++ b/hw/msmouse.c
@@ -50,7 +50,7 @@ static void msmouse_event(void *opaque,
     /* We always send the packet of, so that we do not have to keep track
        of previous state of the middle button. This can potentially confuse
        some very old drivers for two button mice though. */
-    qemu_chr_read(chr, bytes, 4);
+    qemu_chr_be_write(chr, bytes, 4);
 }
 
 static int msmouse_chr_write (struct CharDriverState *s, const uint8_t *buf, int len)
diff --git a/qemu-char.c b/qemu-char.c
index 5a539b0..0786ab4 100644
--- a/qemu-char.c
+++ b/qemu-char.c
@@ -158,7 +158,7 @@ int qemu_chr_can_read(CharDriverState *s)
     return s->chr_can_read(s->handler_opaque);
 }
 
-void qemu_chr_read(CharDriverState *s, uint8_t *buf, int len)
+void qemu_chr_be_write(CharDriverState *s, uint8_t *buf, int len)
 {
     s->chr_read(s->handler_opaque, buf, len);
 }
@@ -589,7 +589,7 @@ static void fd_chr_read(void *opaque)
         return;
     }
     if (size > 0) {
-        qemu_chr_read(chr, buf, size);
+        qemu_chr_be_write(chr, buf, size);
     }
 }
 
@@ -700,7 +700,7 @@ static int stdio_read_poll(void *opaque)
 
     /* try to flush the queue if needed */
     if (term_fifo_size != 0 && qemu_chr_can_read(chr) > 0) {
-        qemu_chr_read(chr, term_fifo, 1);
+        qemu_chr_be_write(chr, term_fifo, 1);
         term_fifo_size = 0;
     }
     /* see if we can absorb more chars */
@@ -725,7 +725,7 @@ static void stdio_read(void *opaque)
     }
     if (size > 0) {
         if (qemu_chr_can_read(chr) > 0) {
-            qemu_chr_read(chr, buf, 1);
+            qemu_chr_be_write(chr, buf, 1);
         } else if (term_fifo_size == 0) {
             term_fifo[term_fifo_size++] = buf[0];
         }
@@ -914,7 +914,7 @@ static void pty_chr_read(void *opaque)
     }
     if (size > 0) {
         pty_chr_state(chr, 1);
-        qemu_chr_read(chr, buf, size);
+        qemu_chr_be_write(chr, buf, size);
     }
 }
 
@@ -1624,7 +1624,7 @@ static void win_chr_readfile(CharDriverState *chr)
     }
 
     if (size > 0) {
-        qemu_chr_read(chr, buf, size);
+        qemu_chr_be_write(chr, buf, size);
     }
 }
 
@@ -1846,7 +1846,7 @@ static int udp_chr_read_poll(void *opaque)
      * first
      */
     while (s->max_size > 0 && s->bufptr < s->bufcnt) {
-        qemu_chr_read(chr, &s->buf[s->bufptr], 1);
+        qemu_chr_be_write(chr, &s->buf[s->bufptr], 1);
         s->bufptr++;
         s->max_size = qemu_chr_can_read(chr);
     }
@@ -1867,7 +1867,7 @@ static void udp_chr_read(void *opaque)
 
     s->bufptr = 0;
     while (s->max_size > 0 && s->bufptr < s->bufcnt) {
-        qemu_chr_read(chr, &s->buf[s->bufptr], 1);
+        qemu_chr_be_write(chr, &s->buf[s->bufptr], 1);
         s->bufptr++;
         s->max_size = qemu_chr_can_read(chr);
     }
@@ -2109,7 +2109,7 @@ static void tcp_chr_read(void *opaque)
         if (s->do_telnetopt)
             tcp_chr_process_IAC_bytes(chr, s, buf, &size);
         if (size > 0)
-            qemu_chr_read(chr, buf, size);
+            qemu_chr_be_write(chr, buf, size);
     }
 }
 
diff --git a/qemu-char.h b/qemu-char.h
index 72c457b..b16e566 100644
--- a/qemu-char.h
+++ b/qemu-char.h
@@ -97,7 +97,7 @@ void qemu_chr_add_handlers(CharDriverState *s,
 int qemu_chr_ioctl(CharDriverState *s, int cmd, void *arg);
 void qemu_chr_generic_open(CharDriverState *s);
 int qemu_chr_can_read(CharDriverState *s);
-void qemu_chr_read(CharDriverState *s, uint8_t *buf, int len);
+void qemu_chr_be_write(CharDriverState *s, uint8_t *buf, int len);
 int qemu_chr_get_msgfd(CharDriverState *s);
 void qemu_chr_accept_input(CharDriverState *s);
 int qemu_chr_add_client(CharDriverState *s, int fd);
diff --git a/spice-qemu-char.c b/spice-qemu-char.c
index 684024b..f3e7702 100644
--- a/spice-qemu-char.c
+++ b/spice-qemu-char.c
@@ -39,7 +39,7 @@ static int vmc_write(SpiceCharDeviceInstance *sin, const uint8_t *buf, int len)
         if (qemu_chr_can_read(scd->chr) < last_out) {
             break;
         }
-        qemu_chr_read(scd->chr, p, last_out);
+        qemu_chr_be_write(scd->chr, p, last_out);
         out += last_out;
         len -= last_out;
         p += last_out;
commit e7e71b0ec62d2954635ba8a2462a20a60fa2c147
Author: Anthony Liguori <aliguori at us.ibm.com>
Date:   Mon Aug 15 11:17:29 2011 -0500

    char: rename qemu_chr_printf() -> qemu_chr_fe_printf()
    
    Signed-off-by: Anthony Liguori <aliguori at us.ibm.com>

diff --git a/hw/mips_malta.c b/hw/mips_malta.c
index 5bdb45b..eedbada 100644
--- a/hw/mips_malta.c
+++ b/hw/mips_malta.c
@@ -92,8 +92,8 @@ static void malta_fpga_update_display(void *opaque)
     }
     leds_text[8] = '\0';
 
-    qemu_chr_printf(s->display, "\e[H\n\n|\e[32m%-8.8s\e[00m|\r\n", leds_text);
-    qemu_chr_printf(s->display, "\n\n\n\n|\e[31m%-8.8s\e[00m|", s->display_text);
+    qemu_chr_fe_printf(s->display, "\e[H\n\n|\e[32m%-8.8s\e[00m|\r\n", leds_text);
+    qemu_chr_fe_printf(s->display, "\n\n\n\n|\e[31m%-8.8s\e[00m|", s->display_text);
 }
 
 /*
@@ -417,15 +417,15 @@ static void malta_fpga_reset(void *opaque)
 
 static void malta_fpga_led_init(CharDriverState *chr)
 {
-    qemu_chr_printf(chr, "\e[HMalta LEDBAR\r\n");
-    qemu_chr_printf(chr, "+--------+\r\n");
-    qemu_chr_printf(chr, "+        +\r\n");
-    qemu_chr_printf(chr, "+--------+\r\n");
-    qemu_chr_printf(chr, "\n");
-    qemu_chr_printf(chr, "Malta ASCII\r\n");
-    qemu_chr_printf(chr, "+--------+\r\n");
-    qemu_chr_printf(chr, "+        +\r\n");
-    qemu_chr_printf(chr, "+--------+\r\n");
+    qemu_chr_fe_printf(chr, "\e[HMalta LEDBAR\r\n");
+    qemu_chr_fe_printf(chr, "+--------+\r\n");
+    qemu_chr_fe_printf(chr, "+        +\r\n");
+    qemu_chr_fe_printf(chr, "+--------+\r\n");
+    qemu_chr_fe_printf(chr, "\n");
+    qemu_chr_fe_printf(chr, "Malta ASCII\r\n");
+    qemu_chr_fe_printf(chr, "+--------+\r\n");
+    qemu_chr_fe_printf(chr, "+        +\r\n");
+    qemu_chr_fe_printf(chr, "+--------+\r\n");
 }
 
 static MaltaFPGAState *malta_fpga_init(target_phys_addr_t base, qemu_irq uart_irq, CharDriverState *uart_chr)
diff --git a/qemu-char.c b/qemu-char.c
index bab43d8..5a539b0 100644
--- a/qemu-char.c
+++ b/qemu-char.c
@@ -179,7 +179,7 @@ void qemu_chr_accept_input(CharDriverState *s)
         s->chr_accept_input(s);
 }
 
-void qemu_chr_printf(CharDriverState *s, const char *fmt, ...)
+void qemu_chr_fe_printf(CharDriverState *s, const char *fmt, ...)
 {
     char buf[READ_BUF_LEN];
     va_list ap;
diff --git a/qemu-char.h b/qemu-char.h
index a4865fc..72c457b 100644
--- a/qemu-char.h
+++ b/qemu-char.h
@@ -85,7 +85,7 @@ void qemu_chr_set_echo(struct CharDriverState *chr, bool echo);
 void qemu_chr_guest_open(struct CharDriverState *chr);
 void qemu_chr_guest_close(struct CharDriverState *chr);
 void qemu_chr_close(CharDriverState *chr);
-void qemu_chr_printf(CharDriverState *s, const char *fmt, ...)
+void qemu_chr_fe_printf(CharDriverState *s, const char *fmt, ...)
     GCC_FMT_ATTR(2, 3);
 int qemu_chr_fe_write(CharDriverState *s, const uint8_t *buf, int len);
 void qemu_chr_send_event(CharDriverState *s, int event);
commit 2cc6e0a14210d2e80173ec6b4611e7e3c50c2cce
Author: Anthony Liguori <aliguori at us.ibm.com>
Date:   Mon Aug 15 11:17:28 2011 -0500

    char: rename qemu_chr_write() -> qemu_chr_fe_write()
    
    Signed-off-by: Anthony Liguori <aliguori at us.ibm.com>

diff --git a/gdbstub.c b/gdbstub.c
index 2f0206d..b0f57c1 100644
--- a/gdbstub.c
+++ b/gdbstub.c
@@ -382,7 +382,7 @@ static void put_buffer(GDBState *s, const uint8_t *buf, int len)
         }
     }
 #else
-    qemu_chr_write(s->chr, buf, len);
+    qemu_chr_fe_write(s->chr, buf, len);
 #endif
 }
 
diff --git a/hw/ccid-card-passthru.c b/hw/ccid-card-passthru.c
index 28eb9d1..082fd82 100644
--- a/hw/ccid-card-passthru.c
+++ b/hw/ccid-card-passthru.c
@@ -72,8 +72,8 @@ static void ccid_card_vscard_send_msg(PassthruState *s,
     scr_msg_header.type = htonl(type);
     scr_msg_header.reader_id = htonl(reader_id);
     scr_msg_header.length = htonl(length);
-    qemu_chr_write(s->cs, (uint8_t *)&scr_msg_header, sizeof(VSCMsgHeader));
-    qemu_chr_write(s->cs, payload, length);
+    qemu_chr_fe_write(s->cs, (uint8_t *)&scr_msg_header, sizeof(VSCMsgHeader));
+    qemu_chr_fe_write(s->cs, payload, length);
 }
 
 static void ccid_card_vscard_send_apdu(PassthruState *s,
diff --git a/hw/debugcon.c b/hw/debugcon.c
index 5ee6821..c9ee6d9 100644
--- a/hw/debugcon.c
+++ b/hw/debugcon.c
@@ -51,7 +51,7 @@ static void debugcon_ioport_write(void *opaque, uint32_t addr, uint32_t val)
     printf("debugcon: write addr=0x%04x val=0x%02x\n", addr, val);
 #endif
 
-    qemu_chr_write(s->chr, &ch, 1);
+    qemu_chr_fe_write(s->chr, &ch, 1);
 }
 
 
diff --git a/hw/escc.c b/hw/escc.c
index 76d94f3..b2391b2 100644
--- a/hw/escc.c
+++ b/hw/escc.c
@@ -551,7 +551,7 @@ static void escc_mem_write(void *opaque, target_phys_addr_t addr,
         s->tx = val;
         if (s->wregs[W_TXCTRL2] & TXCTRL2_TXEN) { // tx enabled
             if (s->chr)
-                qemu_chr_write(s->chr, &s->tx, 1);
+                qemu_chr_fe_write(s->chr, &s->tx, 1);
             else if (s->type == kbd && !s->disabled) {
                 handle_kbd_command(s, val);
             }
diff --git a/hw/etraxfs_ser.c b/hw/etraxfs_ser.c
index 28b86ea..0036037 100644
--- a/hw/etraxfs_ser.c
+++ b/hw/etraxfs_ser.c
@@ -119,7 +119,7 @@ ser_writel (void *opaque, target_phys_addr_t addr, uint32_t value)
     switch (addr)
     {
         case RW_DOUT:
-            qemu_chr_write(s->chr, &ch, 1);
+            qemu_chr_fe_write(s->chr, &ch, 1);
             s->regs[R_INTR] |= 3;
             s->pending_tx = 1;
             s->regs[addr] = value;
diff --git a/hw/grlib_apbuart.c b/hw/grlib_apbuart.c
index 169a56e..c90b810 100644
--- a/hw/grlib_apbuart.c
+++ b/hw/grlib_apbuart.c
@@ -114,7 +114,7 @@ grlib_apbuart_writel(void *opaque, target_phys_addr_t addr, uint32_t value)
     switch (addr) {
     case DATA_OFFSET:
         c = value & 0xFF;
-        qemu_chr_write(uart->chr, &c, 1);
+        qemu_chr_fe_write(uart->chr, &c, 1);
         return;
 
     case STATUS_OFFSET:
diff --git a/hw/lm32_juart.c b/hw/lm32_juart.c
index fddcf7e..5454aa4 100644
--- a/hw/lm32_juart.c
+++ b/hw/lm32_juart.c
@@ -72,7 +72,7 @@ void lm32_juart_set_jtx(DeviceState *d, uint32_t jtx)
 
     s->jtx = jtx;
     if (s->chr) {
-        qemu_chr_write(s->chr, &ch, 1);
+        qemu_chr_fe_write(s->chr, &ch, 1);
     }
 }
 
diff --git a/hw/lm32_uart.c b/hw/lm32_uart.c
index 09090e9..3678545 100644
--- a/hw/lm32_uart.c
+++ b/hw/lm32_uart.c
@@ -169,7 +169,7 @@ static void uart_write(void *opaque, target_phys_addr_t addr, uint32_t value)
     switch (addr) {
     case R_RXTX:
         if (s->chr) {
-            qemu_chr_write(s->chr, &ch, 1);
+            qemu_chr_fe_write(s->chr, &ch, 1);
         }
         break;
     case R_IER:
diff --git a/hw/mcf_uart.c b/hw/mcf_uart.c
index 6118ccb..e6b2ab0 100644
--- a/hw/mcf_uart.c
+++ b/hw/mcf_uart.c
@@ -110,7 +110,7 @@ static void mcf_uart_do_tx(mcf_uart_state *s)
 {
     if (s->tx_enabled && (s->sr & MCF_UART_TxEMP) == 0) {
         if (s->chr)
-            qemu_chr_write(s->chr, (unsigned char *)&s->tb, 1);
+            qemu_chr_fe_write(s->chr, (unsigned char *)&s->tb, 1);
         s->sr |= MCF_UART_TxEMP;
     }
     if (s->tx_enabled) {
diff --git a/hw/milkymist-uart.c b/hw/milkymist-uart.c
index 56c90da..e8e309d 100644
--- a/hw/milkymist-uart.c
+++ b/hw/milkymist-uart.c
@@ -77,7 +77,7 @@ static void uart_write(void *opaque, target_phys_addr_t addr, uint32_t value)
     switch (addr) {
     case R_RXTX:
         if (s->chr) {
-            qemu_chr_write(s->chr, &ch, 1);
+            qemu_chr_fe_write(s->chr, &ch, 1);
         }
         trace_milkymist_uart_pulse_irq_tx();
         qemu_irq_pulse(s->tx_irq);
diff --git a/hw/omap2.c b/hw/omap2.c
index 3b51ac5..e32cd94 100644
--- a/hw/omap2.c
+++ b/hw/omap2.c
@@ -748,14 +748,14 @@ static void omap_sti_fifo_write(void *opaque, target_phys_addr_t addr,
 
     if (ch == STI_TRACE_CONTROL_CHANNEL) {
         /* Flush channel <i>value</i>.  */
-        qemu_chr_write(s->chr, (const uint8_t *) "\r", 1);
+        qemu_chr_fe_write(s->chr, (const uint8_t *) "\r", 1);
     } else if (ch == STI_TRACE_CONSOLE_CHANNEL || 1) {
         if (value == 0xc0 || value == 0xc3) {
             /* Open channel <i>ch</i>.  */
         } else if (value == 0x00)
-            qemu_chr_write(s->chr, (const uint8_t *) "\n", 1);
+            qemu_chr_fe_write(s->chr, (const uint8_t *) "\n", 1);
         else
-            qemu_chr_write(s->chr, &byte, 1);
+            qemu_chr_fe_write(s->chr, &byte, 1);
     }
 }
 
diff --git a/hw/parallel.c b/hw/parallel.c
index 71f30ea..84feab8 100644
--- a/hw/parallel.c
+++ b/hw/parallel.c
@@ -120,7 +120,7 @@ parallel_ioport_write_sw(void *opaque, uint32_t addr, uint32_t val)
             if (val & PARA_CTR_STROBE) {
                 s->status &= ~PARA_STS_BUSY;
                 if ((s->control & PARA_CTR_STROBE) == 0)
-                    qemu_chr_write(s->chr, &s->dataw, 1);
+                    qemu_chr_fe_write(s->chr, &s->dataw, 1);
             } else {
                 if (s->control & PARA_CTR_INTEN) {
                     s->irq_pending = 1;
diff --git a/hw/pl011.c b/hw/pl011.c
index 997ce84..707a161 100644
--- a/hw/pl011.c
+++ b/hw/pl011.c
@@ -133,7 +133,7 @@ static void pl011_write(void *opaque, target_phys_addr_t offset,
         /* ??? Check if transmitter is enabled.  */
         ch = value;
         if (s->chr)
-            qemu_chr_write(s->chr, &ch, 1);
+            qemu_chr_fe_write(s->chr, &ch, 1);
         s->int_level |= PL011_INT_TX;
         pl011_update(s);
         break;
diff --git a/hw/pxa2xx.c b/hw/pxa2xx.c
index d00edc6..2aa8760 100644
--- a/hw/pxa2xx.c
+++ b/hw/pxa2xx.c
@@ -1923,7 +1923,7 @@ static void pxa2xx_fir_write(void *opaque, target_phys_addr_t addr,
         else
             ch = ~value;
         if (s->chr && s->enable && (s->control[0] & (1 << 3)))	/* TXE */
-            qemu_chr_write(s->chr, &ch, 1);
+            qemu_chr_fe_write(s->chr, &ch, 1);
         break;
     case ICSR0:
         s->status[0] &= ~(value & 0x66);
diff --git a/hw/serial.c b/hw/serial.c
index 222e356..427eb4b 100644
--- a/hw/serial.c
+++ b/hw/serial.c
@@ -334,7 +334,7 @@ static void serial_xmit(void *opaque)
     if (s->mcr & UART_MCR_LOOP) {
         /* in loopback mode, say that we just received a char */
         serial_receive1(s, &s->tsr, 1);
-    } else if (qemu_chr_write(s->chr, &s->tsr, 1) != 1) {
+    } else if (qemu_chr_fe_write(s->chr, &s->tsr, 1) != 1) {
         if ((s->tsr_retry > 0) && (s->tsr_retry <= MAX_XMIT_RETRY)) {
             s->tsr_retry++;
             qemu_mod_timer(s->transmit_timer,  new_xmit_ts + s->char_transmit_time);
diff --git a/hw/sh_serial.c b/hw/sh_serial.c
index 1767c97..a20c59e 100644
--- a/hw/sh_serial.c
+++ b/hw/sh_serial.c
@@ -105,7 +105,7 @@ static void sh_serial_write(void *opaque, uint32_t offs, uint32_t val)
     case 0x0c: /* FTDR / TDR */
         if (s->chr) {
             ch = val;
-            qemu_chr_write(s->chr, &ch, 1);
+            qemu_chr_fe_write(s->chr, &ch, 1);
 	}
 	s->dr = val;
 	s->flags &= ~SH_SERIAL_FLAG_TDE;
diff --git a/hw/spapr_vty.c b/hw/spapr_vty.c
index 6fc0105..f5046d9 100644
--- a/hw/spapr_vty.c
+++ b/hw/spapr_vty.c
@@ -50,8 +50,8 @@ void vty_putchars(VIOsPAPRDevice *sdev, uint8_t *buf, int len)
 {
     VIOsPAPRVTYDevice *dev = (VIOsPAPRVTYDevice *)sdev;
 
-    /* FIXME: should check the qemu_chr_write() return value */
-    qemu_chr_write(dev->chardev, buf, len);
+    /* FIXME: should check the qemu_chr_fe_write() return value */
+    qemu_chr_fe_write(dev->chardev, buf, len);
 }
 
 static int spapr_vty_init(VIOsPAPRDevice *sdev)
diff --git a/hw/strongarm.c b/hw/strongarm.c
index 3a7fd6d..84855cb 100644
--- a/hw/strongarm.c
+++ b/hw/strongarm.c
@@ -1067,7 +1067,7 @@ static void strongarm_uart_tx(void *opaque)
     if (s->utcr3 & UTCR3_LBM) /* loopback */ {
         strongarm_uart_receive(s, &s->tx_fifo[s->tx_start], 1);
     } else if (s->chr) {
-        qemu_chr_write(s->chr, &s->tx_fifo[s->tx_start], 1);
+        qemu_chr_fe_write(s->chr, &s->tx_fifo[s->tx_start], 1);
     }
 
     s->tx_start = (s->tx_start + 1) % 8;
diff --git a/hw/syborg_serial.c b/hw/syborg_serial.c
index 4d0ec04..c83f82c 100644
--- a/hw/syborg_serial.c
+++ b/hw/syborg_serial.c
@@ -119,7 +119,7 @@ static void do_dma_tx(SyborgSerialState *s, uint32_t count)
         /* optimize later. Now, 1 byte per iteration */
         while (count--) {
             cpu_physical_memory_read(s->dma_tx_ptr, &ch, 1);
-            qemu_chr_write(s->chr, &ch, 1);
+            qemu_chr_fe_write(s->chr, &ch, 1);
             s->dma_tx_ptr++;
         }
     } else {
@@ -203,7 +203,7 @@ static void syborg_serial_write(void *opaque, target_phys_addr_t offset,
     case SERIAL_DATA:
         ch = value;
         if (s->chr)
-            qemu_chr_write(s->chr, &ch, 1);
+            qemu_chr_fe_write(s->chr, &ch, 1);
         break;
     case SERIAL_INT_ENABLE:
         s->int_enable = value;
diff --git a/hw/usb-serial.c b/hw/usb-serial.c
index bf2b775..8ed0fa6 100644
--- a/hw/usb-serial.c
+++ b/hw/usb-serial.c
@@ -371,7 +371,7 @@ static int usb_serial_handle_data(USBDevice *dev, USBPacket *p)
             goto fail;
         for (i = 0; i < p->iov.niov; i++) {
             iov = p->iov.iov + i;
-            qemu_chr_write(s->cs, iov->iov_base, iov->iov_len);
+            qemu_chr_fe_write(s->cs, iov->iov_base, iov->iov_len);
         }
         break;
 
diff --git a/hw/virtio-console.c b/hw/virtio-console.c
index fe5e188..6c386fa 100644
--- a/hw/virtio-console.c
+++ b/hw/virtio-console.c
@@ -27,7 +27,7 @@ static ssize_t flush_buf(VirtIOSerialPort *port, const uint8_t *buf, size_t len)
     VirtConsole *vcon = DO_UPCAST(VirtConsole, port, port);
     ssize_t ret;
 
-    ret = qemu_chr_write(vcon->chr, buf, len);
+    ret = qemu_chr_fe_write(vcon->chr, buf, len);
     trace_virtio_console_flush_buf(port->id, len, ret);
 
     if (ret < 0) {
diff --git a/hw/xen_console.c b/hw/xen_console.c
index 99ff442..8468891 100644
--- a/hw/xen_console.c
+++ b/hw/xen_console.c
@@ -156,7 +156,7 @@ static void xencons_send(struct XenConsole *con)
 
     size = con->buffer.size - con->buffer.consumed;
     if (con->chr)
-        len = qemu_chr_write(con->chr, con->buffer.data + con->buffer.consumed,
+        len = qemu_chr_fe_write(con->chr, con->buffer.data + con->buffer.consumed,
                              size);
     else
         len = size;
diff --git a/hw/xilinx_uartlite.c b/hw/xilinx_uartlite.c
index 9b94e98..467a26c 100644
--- a/hw/xilinx_uartlite.c
+++ b/hw/xilinx_uartlite.c
@@ -129,7 +129,7 @@ uart_writel (void *opaque, target_phys_addr_t addr, uint32_t value)
 
         case R_TX:
             if (s->chr)
-                qemu_chr_write(s->chr, &ch, 1);
+                qemu_chr_fe_write(s->chr, &ch, 1);
 
             s->regs[addr] = value;
 
diff --git a/monitor.c b/monitor.c
index 39791dc..f95d959 100644
--- a/monitor.c
+++ b/monitor.c
@@ -247,7 +247,7 @@ static int monitor_read_password(Monitor *mon, ReadLineFunc *readline_func,
 void monitor_flush(Monitor *mon)
 {
     if (mon && mon->outbuf_index != 0 && !mon->mux_out) {
-        qemu_chr_write(mon->chr, mon->outbuf, mon->outbuf_index);
+        qemu_chr_fe_write(mon->chr, mon->outbuf, mon->outbuf_index);
         mon->outbuf_index = 0;
     }
 }
diff --git a/qemu-char.c b/qemu-char.c
index 2358117..bab43d8 100644
--- a/qemu-char.c
+++ b/qemu-char.c
@@ -139,7 +139,7 @@ void qemu_chr_generic_open(CharDriverState *s)
     }
 }
 
-int qemu_chr_write(CharDriverState *s, const uint8_t *buf, int len)
+int qemu_chr_fe_write(CharDriverState *s, const uint8_t *buf, int len)
 {
     return s->chr_write(s, buf, len);
 }
@@ -185,7 +185,7 @@ void qemu_chr_printf(CharDriverState *s, const char *fmt, ...)
     va_list ap;
     va_start(ap, fmt);
     vsnprintf(buf, sizeof(buf), fmt, ap);
-    qemu_chr_write(s, (uint8_t *)buf, strlen(buf));
+    qemu_chr_fe_write(s, (uint8_t *)buf, strlen(buf));
     va_end(ap);
 }
 
diff --git a/qemu-char.h b/qemu-char.h
index f361c6d..a4865fc 100644
--- a/qemu-char.h
+++ b/qemu-char.h
@@ -87,7 +87,7 @@ void qemu_chr_guest_close(struct CharDriverState *chr);
 void qemu_chr_close(CharDriverState *chr);
 void qemu_chr_printf(CharDriverState *s, const char *fmt, ...)
     GCC_FMT_ATTR(2, 3);
-int qemu_chr_write(CharDriverState *s, const uint8_t *buf, int len);
+int qemu_chr_fe_write(CharDriverState *s, const uint8_t *buf, int len);
 void qemu_chr_send_event(CharDriverState *s, int event);
 void qemu_chr_add_handlers(CharDriverState *s,
                            IOCanReadHandler *fd_can_read,
diff --git a/slirp/slirp.c b/slirp/slirp.c
index 655b3f4..19d69eb 100644
--- a/slirp/slirp.c
+++ b/slirp/slirp.c
@@ -818,7 +818,7 @@ int slirp_add_exec(Slirp *slirp, int do_pty, const void *args,
 ssize_t slirp_send(struct socket *so, const void *buf, size_t len, int flags)
 {
 	if (so->s == -1 && so->extra) {
-		qemu_chr_write(so->extra, buf, len);
+		qemu_chr_fe_write(so->extra, buf, len);
 		return len;
 	}
 
diff --git a/usb-redir.c b/usb-redir.c
index 3fbbcff..84fa020 100644
--- a/usb-redir.c
+++ b/usb-redir.c
@@ -225,7 +225,7 @@ static int usbredir_write(void *priv, uint8_t *data, int count)
 {
     USBRedirDevice *dev = priv;
 
-    return qemu_chr_write(dev->cs, data, count);
+    return qemu_chr_fe_write(dev->cs, data, count);
 }
 
 /*
commit 0bf1dbdcc935dfc220a93cd990e947e90706aec6
Author: malc <av1474 at comtv.ru>
Date:   Mon Aug 22 18:26:15 2011 +0400

    tcg/ppc64: fix 16/32 mixup
    
    Signed-off-by: malc <av1474 at comtv.ru>

diff --git a/tcg/ppc64/tcg-target.h b/tcg/ppc64/tcg-target.h
index 5a4609a..5395131 100644
--- a/tcg/ppc64/tcg-target.h
+++ b/tcg/ppc64/tcg-target.h
@@ -91,8 +91,8 @@ enum {
 #define TCG_TARGET_HAS_ext16s_i64       1
 #define TCG_TARGET_HAS_ext32s_i64       1
 #define TCG_TARGET_HAS_ext8u_i64        0
-#define TCG_TARGET_HAS_ext16u_i64       1
-#define TCG_TARGET_HAS_ext32u_i64       0
+#define TCG_TARGET_HAS_ext16u_i64       0
+#define TCG_TARGET_HAS_ext32u_i64       1
 #define TCG_TARGET_HAS_bswap16_i64      0
 #define TCG_TARGET_HAS_bswap32_i64      0
 #define TCG_TARGET_HAS_bswap64_i64      0
commit 1afa194a0a3384c5a8fd150e4335d332c22883cf
Merge: 157f266... f1a7104...
Author: malc <av1474 at comtv.ru>
Date:   Mon Aug 22 14:41:12 2011 +0400

    Merge branch 'master' of git://git.qemu.org/qemu

commit 157f2662fb4dd8f02885027e47f79fbee83c7b94
Author: malc <av1474 at comtv.ru>
Date:   Mon Aug 22 14:40:00 2011 +0400

    tcg/ppc64: implement not_i32/64 and ext32u_i64
    
    Signed-off-by: malc <av1474 at comtv.ru>

diff --git a/tcg/ppc64/tcg-target.c b/tcg/ppc64/tcg-target.c
index 02a6cb2..d831684 100644
--- a/tcg/ppc64/tcg-target.c
+++ b/tcg/ppc64/tcg-target.c
@@ -355,6 +355,7 @@ static int tcg_target_const_match (tcg_target_long val,
 #define SRAWI  XO31(824)
 #define NEG    XO31(104)
 #define MFCR   XO31( 19)
+#define NOR    XO31(124)
 #define CNTLZW XO31( 26)
 #define CNTLZD XO31( 58)
 
@@ -1449,6 +1450,11 @@ static void tcg_out_op (TCGContext *s, TCGOpcode opc, const TCGArg *args,
         tcg_out32 (s, NEG | RT (args[0]) | RA (args[1]));
         break;
 
+    case INDEX_op_not_i32:
+    case INDEX_op_not_i64:
+        tcg_out32 (s, NOR | SAB (args[1], args[0], args[1]));
+        break;
+
     case INDEX_op_add_i64:
         if (const_args[2])
             ppc_addi64 (s, args[0], args[1], args[2]);
@@ -1553,6 +1559,10 @@ static void tcg_out_op (TCGContext *s, TCGOpcode opc, const TCGArg *args,
         tcg_out32 (s, c | RS (args[1]) | RA (args[0]));
         break;
 
+    case INDEX_op_ext32u_i64:
+        tcg_out_rld (s, RLDICR, args[0], args[1], 0, 32);
+        break;
+
     case INDEX_op_setcond_i32:
         tcg_out_setcond (s, TCG_TYPE_I32, args[3], args[0], args[1], args[2],
                          const_args[2]);
@@ -1621,6 +1631,7 @@ static const TCGTargetOpDef ppc_op_defs[] = {
     { INDEX_op_brcond_i64, { "r", "ri" } },
 
     { INDEX_op_neg_i32, { "r", "r" } },
+    { INDEX_op_not_i32, { "r", "r" } },
 
     { INDEX_op_add_i64, { "r", "r", "ri" } },
     { INDEX_op_sub_i64, { "r", "r", "ri" } },
@@ -1639,6 +1650,7 @@ static const TCGTargetOpDef ppc_op_defs[] = {
     { INDEX_op_remu_i64, { "r", "r", "r" } },
 
     { INDEX_op_neg_i64, { "r", "r" } },
+    { INDEX_op_not_i64, { "r", "r" } },
 
     { INDEX_op_qemu_ld8u, { "r", "L" } },
     { INDEX_op_qemu_ld8s, { "r", "L" } },
@@ -1659,6 +1671,7 @@ static const TCGTargetOpDef ppc_op_defs[] = {
     { INDEX_op_ext8s_i64, { "r", "r" } },
     { INDEX_op_ext16s_i64, { "r", "r" } },
     { INDEX_op_ext32s_i64, { "r", "r" } },
+    { INDEX_op_ext32u_i64, { "r", "r" } },
 
     { INDEX_op_setcond_i32, { "r", "r", "ri" } },
     { INDEX_op_setcond_i64, { "r", "r", "ri" } },
diff --git a/tcg/ppc64/tcg-target.h b/tcg/ppc64/tcg-target.h
index 041fe9d..5a4609a 100644
--- a/tcg/ppc64/tcg-target.h
+++ b/tcg/ppc64/tcg-target.h
@@ -76,7 +76,7 @@ enum {
 #define TCG_TARGET_HAS_ext16u_i32       0
 #define TCG_TARGET_HAS_bswap16_i32      0
 #define TCG_TARGET_HAS_bswap32_i32      0
-#define TCG_TARGET_HAS_not_i32          0
+#define TCG_TARGET_HAS_not_i32          1
 #define TCG_TARGET_HAS_neg_i32          1
 #define TCG_TARGET_HAS_andc_i32         0
 #define TCG_TARGET_HAS_orc_i32          0
@@ -91,12 +91,12 @@ enum {
 #define TCG_TARGET_HAS_ext16s_i64       1
 #define TCG_TARGET_HAS_ext32s_i64       1
 #define TCG_TARGET_HAS_ext8u_i64        0
-#define TCG_TARGET_HAS_ext16u_i64       0
+#define TCG_TARGET_HAS_ext16u_i64       1
 #define TCG_TARGET_HAS_ext32u_i64       0
 #define TCG_TARGET_HAS_bswap16_i64      0
 #define TCG_TARGET_HAS_bswap32_i64      0
 #define TCG_TARGET_HAS_bswap64_i64      0
-#define TCG_TARGET_HAS_not_i64          0
+#define TCG_TARGET_HAS_not_i64          1
 #define TCG_TARGET_HAS_neg_i64          1
 #define TCG_TARGET_HAS_andc_i64         0
 #define TCG_TARGET_HAS_orc_i64          0
commit 350dba6ce65fbb81cff0603273289d50131a992b
Author: malc <av1474 at comtv.ru>
Date:   Mon Aug 22 14:39:00 2011 +0400

    tcg/ppc32: implement deposit_i32
    
    Signed-off-by: malc <av1474 at comtv.ru>

diff --git a/tcg/ppc/tcg-target.c b/tcg/ppc/tcg-target.c
index 58c8621..4462647 100644
--- a/tcg/ppc/tcg-target.c
+++ b/tcg/ppc/tcg-target.c
@@ -1790,6 +1790,16 @@ static void tcg_out_op(TCGContext *s, TCGOpcode opc, const TCGArg *args,
         }
         break;
 
+    case INDEX_op_deposit_i32:
+        tcg_out32 (s, RLWIMI
+                   | RA (args[0])
+                   | RS (args[2])
+                   | SH (args[3])
+                   | MB (32 - args[3] - args[4])
+                   | ME (31 - args[3])
+            );
+        break;
+
     default:
         tcg_dump_ops (s, stderr);
         tcg_abort ();
@@ -1885,6 +1895,8 @@ static const TCGTargetOpDef ppc_op_defs[] = {
     { INDEX_op_ext16s_i32, { "r", "r" } },
     { INDEX_op_ext16u_i32, { "r", "r" } },
 
+    { INDEX_op_deposit_i32, { "r", "0", "r" } },
+
     { -1 },
 };
 
diff --git a/tcg/ppc/tcg-target.h b/tcg/ppc/tcg-target.h
index 8c35c4e..f9a88c4 100644
--- a/tcg/ppc/tcg-target.h
+++ b/tcg/ppc/tcg-target.h
@@ -92,7 +92,7 @@ enum {
 #define TCG_TARGET_HAS_eqv_i32          1
 #define TCG_TARGET_HAS_nand_i32         1
 #define TCG_TARGET_HAS_nor_i32          1
-#define TCG_TARGET_HAS_deposit_i32      0
+#define TCG_TARGET_HAS_deposit_i32      1
 
 #define TCG_AREG0 TCG_REG_R27
 
commit 5f524c1ebcc5e0dec0de8940d34f9adb3c7887a1
Author: Harsh Prateek Bora <harsh at linux.vnet.ibm.com>
Date:   Wed May 18 17:23:00 2011 +0530

    use readdir_r instead of readdir for reentrancy
    
    Signed-off-by: Harsh Prateek Bora <harsh at linux.vnet.ibm.com>
    Signed-off-by: Aneesh Kumar K.V <aneesh.kumar at linux.vnet.ibm.com>

diff --git a/fsdev/file-op-9p.h b/fsdev/file-op-9p.h
index af9daf7..1eda342 100644
--- a/fsdev/file-op-9p.h
+++ b/fsdev/file-op-9p.h
@@ -78,7 +78,7 @@ typedef struct FileOperations
     int (*open2)(FsContext *, const char *, int, FsCred *);
     void (*rewinddir)(FsContext *, DIR *);
     off_t (*telldir)(FsContext *, DIR *);
-    struct dirent *(*readdir)(FsContext *, DIR *);
+    int (*readdir_r)(FsContext *, DIR *, struct dirent *, struct dirent **);
     void (*seekdir)(FsContext *, DIR *, off_t);
     ssize_t (*preadv)(FsContext *, int, const struct iovec *, int, off_t);
     ssize_t (*pwritev)(FsContext *, int, const struct iovec *, int, off_t);
diff --git a/hw/9pfs/codir.c b/hw/9pfs/codir.c
index 0c31db3..3a257b9 100644
--- a/hw/9pfs/codir.c
+++ b/hw/9pfs/codir.c
@@ -17,16 +17,16 @@
 #include "qemu-coroutine.h"
 #include "virtio-9p-coth.h"
 
-int v9fs_co_readdir(V9fsState *s, V9fsFidState *fidp, struct dirent **dent)
+int v9fs_co_readdir_r(V9fsState *s, V9fsFidState *fidp, struct dirent *dent,
+                      struct dirent **result)
 {
     int err;
 
     v9fs_co_run_in_worker(
         {
             errno = 0;
-            /*FIXME!! need to switch to readdir_r */
-            *dent = s->ops->readdir(&s->ctx, fidp->fs.dir);
-            if (!*dent && errno) {
+            err = s->ops->readdir_r(&s->ctx, fidp->fs.dir, dent, result);
+            if (!*result && errno) {
                 err = -errno;
             } else {
                 err = 0;
diff --git a/hw/9pfs/virtio-9p-coth.h b/hw/9pfs/virtio-9p-coth.h
index 5fa2972..48defb7 100644
--- a/hw/9pfs/virtio-9p-coth.h
+++ b/hw/9pfs/virtio-9p-coth.h
@@ -57,8 +57,8 @@ typedef struct V9fsThPool {
 extern void co_run_in_worker_bh(void *);
 extern int v9fs_init_worker_threads(void);
 extern int v9fs_co_readlink(V9fsState *, V9fsString *, V9fsString *);
-extern int v9fs_co_readdir(V9fsState *, V9fsFidState *,
-                           struct dirent **);
+extern int v9fs_co_readdir_r(V9fsState *, V9fsFidState *,
+                           struct dirent *, struct dirent **result);
 extern off_t v9fs_co_telldir(V9fsState *, V9fsFidState *);
 extern void v9fs_co_seekdir(V9fsState *, V9fsFidState *, off_t);
 extern void v9fs_co_rewinddir(V9fsState *, V9fsFidState *);
diff --git a/hw/9pfs/virtio-9p-local.c b/hw/9pfs/virtio-9p-local.c
index 77904c3..61cbf8d 100644
--- a/hw/9pfs/virtio-9p-local.c
+++ b/hw/9pfs/virtio-9p-local.c
@@ -165,9 +165,10 @@ static off_t local_telldir(FsContext *ctx, DIR *dir)
     return telldir(dir);
 }
 
-static struct dirent *local_readdir(FsContext *ctx, DIR *dir)
+static int local_readdir_r(FsContext *ctx, DIR *dir, struct dirent *entry,
+                         struct dirent **result)
 {
-    return readdir(dir);
+    return readdir_r(dir, entry, result);
 }
 
 static void local_seekdir(FsContext *ctx, DIR *dir, off_t off)
@@ -532,7 +533,7 @@ FileOperations local_ops = {
     .opendir = local_opendir,
     .rewinddir = local_rewinddir,
     .telldir = local_telldir,
-    .readdir = local_readdir,
+    .readdir_r = local_readdir_r,
     .seekdir = local_seekdir,
     .preadv = local_preadv,
     .pwritev = local_pwritev,
diff --git a/hw/9pfs/virtio-9p.c b/hw/9pfs/virtio-9p.c
index 4abf2f9..ad70768 100644
--- a/hw/9pfs/virtio-9p.c
+++ b/hw/9pfs/virtio-9p.c
@@ -1495,17 +1495,20 @@ static int v9fs_do_readdir_with_stat(V9fsState *s, V9fsPDU *pdu,
     int32_t count = 0;
     struct stat stbuf;
     off_t saved_dir_pos;
-    struct dirent *dent;
+    struct dirent *dent, *result;
 
     /* save the directory position */
     saved_dir_pos = v9fs_co_telldir(s, fidp);
     if (saved_dir_pos < 0) {
         return saved_dir_pos;
     }
+
+    dent = g_malloc(sizeof(struct dirent));
+
     while (1) {
         v9fs_string_init(&name);
-        err = v9fs_co_readdir(s, fidp, &dent);
-        if (err || !dent) {
+        err = v9fs_co_readdir_r(s, fidp, dent, &result);
+        if (err || !result) {
             break;
         }
         v9fs_string_sprintf(&name, "%s/%s", fidp->path.data, dent->d_name);
@@ -1524,6 +1527,7 @@ static int v9fs_do_readdir_with_stat(V9fsState *s, V9fsPDU *pdu,
             v9fs_co_seekdir(s, fidp, saved_dir_pos);
             v9fs_stat_free(&v9stat);
             v9fs_string_free(&name);
+            g_free(dent);
             return count;
         }
         count += len;
@@ -1532,6 +1536,7 @@ static int v9fs_do_readdir_with_stat(V9fsState *s, V9fsPDU *pdu,
         saved_dir_pos = dent->d_off;
     }
 out:
+    g_free(dent);
     v9fs_string_free(&name);
     if (err < 0) {
         return err;
@@ -1628,16 +1633,19 @@ static int v9fs_do_readdir(V9fsState *s, V9fsPDU *pdu,
     int len, err = 0;
     int32_t count = 0;
     off_t saved_dir_pos;
-    struct dirent *dent;
+    struct dirent *dent, *result;
 
     /* save the directory position */
     saved_dir_pos = v9fs_co_telldir(s, fidp);
     if (saved_dir_pos < 0) {
         return saved_dir_pos;
     }
+
+    dent = g_malloc(sizeof(struct dirent));
+
     while (1) {
-        err = v9fs_co_readdir(s, fidp, &dent);
-        if (err || !dent) {
+        err = v9fs_co_readdir_r(s, fidp, dent, &result);
+        if (err || !result) {
             break;
         }
         v9fs_string_init(&name);
@@ -1646,6 +1654,7 @@ static int v9fs_do_readdir(V9fsState *s, V9fsPDU *pdu,
             /* Ran out of buffer. Set dir back to old position and return */
             v9fs_co_seekdir(s, fidp, saved_dir_pos);
             v9fs_string_free(&name);
+            g_free(dent);
             return count;
         }
         /*
@@ -1667,6 +1676,7 @@ static int v9fs_do_readdir(V9fsState *s, V9fsPDU *pdu,
         v9fs_string_free(&name);
         saved_dir_pos = dent->d_off;
     }
+    g_free(dent);
     if (err < 0) {
         return err;
     }
commit d208a0e00598d19abab7cb6dc97cf21d7bf0eede
Author: Aneesh Kumar K.V <aneesh.kumar at linux.vnet.ibm.com>
Date:   Fri May 20 13:46:31 2011 -0700

    hw/9pfs: Update v9fs_read to use coroutines
    
    Signed-off-by: Aneesh Kumar K.V <aneesh.kumar at linux.vnet.ibm.com>

diff --git a/hw/9pfs/virtio-9p.c b/hw/9pfs/virtio-9p.c
index add889e..4abf2f9 100644
--- a/hw/9pfs/virtio-9p.c
+++ b/hw/9pfs/virtio-9p.c
@@ -77,32 +77,6 @@ void cred_init(FsCred *credp)
     credp->fc_rdev = -1;
 }
 
-static int v9fs_do_lstat(V9fsState *s, V9fsString *path, struct stat *stbuf)
-{
-    return s->ops->lstat(&s->ctx, path->data, stbuf);
-}
-
-static void v9fs_do_rewinddir(V9fsState *s, DIR *dir)
-{
-    return s->ops->rewinddir(&s->ctx, dir);
-}
-
-static off_t v9fs_do_telldir(V9fsState *s, DIR *dir)
-{
-    return s->ops->telldir(&s->ctx, dir);
-}
-
-static void v9fs_do_seekdir(V9fsState *s, DIR *dir, off_t off)
-{
-    return s->ops->seekdir(&s->ctx, dir, off);
-}
-
-static int v9fs_do_preadv(V9fsState *s, int fd, const struct iovec *iov,
-                            int iovcnt, int64_t offset)
-{
-    return s->ops->preadv(&s->ctx, fd, iov, iovcnt, offset);
-}
-
 static void v9fs_string_init(V9fsString *str)
 {
     str->data = NULL;
@@ -1488,207 +1462,152 @@ out:
     complete_pdu(s, pdu, err);
 }
 
-static void v9fs_read_post_readdir(V9fsState *, V9fsReadState *, ssize_t);
-
-static void v9fs_read_post_seekdir(V9fsState *s, V9fsReadState *vs, ssize_t err)
+static int v9fs_xattr_read(V9fsState *s, V9fsPDU *pdu,
+                           V9fsFidState *fidp, int64_t off, int32_t max_count)
 {
-    if (err) {
-        goto out;
-    }
-    vs->offset += pdu_marshal(vs->pdu, vs->offset, "d", vs->count);
-    vs->offset += vs->count;
-    err = vs->offset;
-out:
-    complete_pdu(s, vs->pdu, err);
-    v9fs_stat_free(&vs->v9stat);
-    v9fs_string_free(&vs->name);
-    g_free(vs);
-    return;
-}
-
-static void v9fs_read_post_dir_lstat(V9fsState *s, V9fsReadState *vs,
-                                    ssize_t err)
-{
-    if (err) {
-        err = -errno;
-        goto out;
-    }
-    err = stat_to_v9stat(s, &vs->name, &vs->stbuf, &vs->v9stat);
-    if (err) {
-        goto out;
-    }
-
-    vs->len = pdu_marshal(vs->pdu, vs->offset + 4 + vs->count, "S",
-                            &vs->v9stat);
-    if ((vs->len != (vs->v9stat.size + 2)) ||
-            ((vs->count + vs->len) > vs->max_count)) {
-        v9fs_do_seekdir(s, vs->fidp->fs.dir, vs->dir_pos);
-        v9fs_read_post_seekdir(s, vs, err);
-        return;
-    }
-    vs->count += vs->len;
-    v9fs_stat_free(&vs->v9stat);
-    v9fs_string_free(&vs->name);
-    vs->dir_pos = vs->dent->d_off;
-    v9fs_co_readdir(s, vs->fidp, &vs->dent);
-    v9fs_read_post_readdir(s, vs, err);
-    return;
-out:
-    v9fs_do_seekdir(s, vs->fidp->fs.dir, vs->dir_pos);
-    v9fs_read_post_seekdir(s, vs, err);
-    return;
-
-}
+    size_t offset = 7;
+    int read_count;
+    int64_t xattr_len;
 
-static void v9fs_read_post_readdir(V9fsState *s, V9fsReadState *vs, ssize_t err)
-{
-    if (vs->dent) {
-        memset(&vs->v9stat, 0, sizeof(vs->v9stat));
-        v9fs_string_init(&vs->name);
-        v9fs_string_sprintf(&vs->name, "%s/%s", vs->fidp->path.data,
-                            vs->dent->d_name);
-        err = v9fs_do_lstat(s, &vs->name, &vs->stbuf);
-        v9fs_read_post_dir_lstat(s, vs, err);
-        return;
+    xattr_len = fidp->fs.xattr.len;
+    read_count = xattr_len - off;
+    if (read_count > max_count) {
+        read_count = max_count;
+    } else if (read_count < 0) {
+        /*
+         * read beyond XATTR value
+         */
+        read_count = 0;
     }
-
-    vs->offset += pdu_marshal(vs->pdu, vs->offset, "d", vs->count);
-    vs->offset += vs->count;
-    err = vs->offset;
-    complete_pdu(s, vs->pdu, err);
-    g_free(vs);
-    return;
-}
-
-static void v9fs_read_post_telldir(V9fsState *s, V9fsReadState *vs, ssize_t err)
-{
-    v9fs_co_readdir(s, vs->fidp, &vs->dent);
-    v9fs_read_post_readdir(s, vs, err);
-    return;
+    offset += pdu_marshal(pdu, offset, "d", read_count);
+    offset += pdu_pack(pdu, offset,
+                       ((char *)fidp->fs.xattr.value) + off,
+                       read_count);
+    return offset;
 }
 
-static void v9fs_read_post_rewinddir(V9fsState *s, V9fsReadState *vs,
-                                       ssize_t err)
+static int v9fs_do_readdir_with_stat(V9fsState *s, V9fsPDU *pdu,
+                                     V9fsFidState *fidp, int32_t max_count)
 {
-    vs->dir_pos = v9fs_do_telldir(s, vs->fidp->fs.dir);
-    v9fs_read_post_telldir(s, vs, err);
-    return;
-}
+    V9fsString name;
+    V9fsStat v9stat;
+    int len, err = 0;
+    int32_t count = 0;
+    struct stat stbuf;
+    off_t saved_dir_pos;
+    struct dirent *dent;
 
-static void v9fs_read_post_preadv(V9fsState *s, V9fsReadState *vs, ssize_t err)
-{
-    if (err  < 0) {
-        /* IO error return the error */
-        err = -errno;
-        goto out;
+    /* save the directory position */
+    saved_dir_pos = v9fs_co_telldir(s, fidp);
+    if (saved_dir_pos < 0) {
+        return saved_dir_pos;
     }
-    vs->total += vs->len;
-    vs->sg = adjust_sg(vs->sg, vs->len, &vs->cnt);
-    if (vs->total < vs->count && vs->len > 0) {
-        do {
-            if (0) {
-                print_sg(vs->sg, vs->cnt);
-            }
-            vs->len = v9fs_do_preadv(s, vs->fidp->fs.fd, vs->sg, vs->cnt,
-                      vs->off);
-            if (vs->len > 0) {
-                vs->off += vs->len;
-            }
-        } while (vs->len == -1 && errno == EINTR);
-        if (vs->len == -1) {
-            err  = -errno;
+    while (1) {
+        v9fs_string_init(&name);
+        err = v9fs_co_readdir(s, fidp, &dent);
+        if (err || !dent) {
+            break;
+        }
+        v9fs_string_sprintf(&name, "%s/%s", fidp->path.data, dent->d_name);
+        err = v9fs_co_lstat(s, &name, &stbuf);
+        if (err < 0) {
+            goto out;
+        }
+        err = stat_to_v9stat(s, &name, &stbuf, &v9stat);
+        if (err < 0) {
+            goto out;
+        }
+        /* 11 = 7 + 4 (7 = start offset, 4 = space for storing count) */
+        len = pdu_marshal(pdu, 11 + count, "S", &v9stat);
+        if ((len != (v9stat.size + 2)) || ((count + len) > max_count)) {
+            /* Ran out of buffer. Set dir back to old position and return */
+            v9fs_co_seekdir(s, fidp, saved_dir_pos);
+            v9fs_stat_free(&v9stat);
+            v9fs_string_free(&name);
+            return count;
         }
-        v9fs_read_post_preadv(s, vs, err);
-        return;
+        count += len;
+        v9fs_stat_free(&v9stat);
+        v9fs_string_free(&name);
+        saved_dir_pos = dent->d_off;
     }
-    vs->offset += pdu_marshal(vs->pdu, vs->offset, "d", vs->total);
-    vs->offset += vs->count;
-    err = vs->offset;
-
 out:
-    complete_pdu(s, vs->pdu, err);
-    g_free(vs);
-}
-
-static void v9fs_xattr_read(V9fsState *s, V9fsReadState *vs)
-{
-    ssize_t err = 0;
-    int read_count;
-    int64_t xattr_len;
-
-    xattr_len = vs->fidp->fs.xattr.len;
-    read_count = xattr_len - vs->off;
-    if (read_count > vs->count) {
-        read_count = vs->count;
-    } else if (read_count < 0) {
-        /*
-         * read beyond XATTR value
-         */
-        read_count = 0;
+    v9fs_string_free(&name);
+    if (err < 0) {
+        return err;
     }
-    vs->offset += pdu_marshal(vs->pdu, vs->offset, "d", read_count);
-    vs->offset += pdu_pack(vs->pdu, vs->offset,
-                           ((char *)vs->fidp->fs.xattr.value) + vs->off,
-                           read_count);
-    err = vs->offset;
-    complete_pdu(s, vs->pdu, err);
-    g_free(vs);
+    return count;
 }
 
 static void v9fs_read(void *opaque)
 {
-    V9fsPDU *pdu = opaque;
-    V9fsState *s = pdu->s;
     int32_t fid;
-    V9fsReadState *vs;
+    int64_t off;
     ssize_t err = 0;
+    int32_t count = 0;
+    size_t offset = 7;
+    int32_t max_count;
+    V9fsFidState *fidp;
+    V9fsPDU *pdu = opaque;
+    V9fsState *s = pdu->s;
 
-    vs = g_malloc(sizeof(*vs));
-    vs->pdu = pdu;
-    vs->offset = 7;
-    vs->total = 0;
-    vs->len = 0;
-    vs->count = 0;
-
-    pdu_unmarshal(vs->pdu, vs->offset, "dqd", &fid, &vs->off, &vs->count);
-
-    vs->fidp = lookup_fid(s, fid);
-    if (vs->fidp == NULL) {
+    pdu_unmarshal(pdu, offset, "dqd", &fid, &off, &max_count);
+    fidp = lookup_fid(s, fid);
+    if (fidp == NULL) {
         err = -EINVAL;
         goto out;
     }
+    if (fidp->fid_type == P9_FID_DIR) {
 
-    if (vs->fidp->fid_type == P9_FID_DIR) {
-        vs->max_count = vs->count;
-        vs->count = 0;
-        if (vs->off == 0) {
-            v9fs_do_rewinddir(s, vs->fidp->fs.dir);
-        }
-        v9fs_read_post_rewinddir(s, vs, err);
-        return;
-    } else if (vs->fidp->fid_type == P9_FID_FILE) {
-        vs->sg = vs->iov;
-        pdu_marshal(vs->pdu, vs->offset + 4, "v", vs->sg, &vs->cnt);
-        vs->sg = cap_sg(vs->sg, vs->count, &vs->cnt);
-        if (vs->total <= vs->count) {
-            vs->len = v9fs_do_preadv(s, vs->fidp->fs.fd, vs->sg, vs->cnt,
-                                    vs->off);
-            if (vs->len > 0) {
-                vs->off += vs->len;
-            }
-            err = vs->len;
-            v9fs_read_post_preadv(s, vs, err);
+        if (off == 0) {
+            v9fs_co_rewinddir(s, fidp);
+        }
+        count = v9fs_do_readdir_with_stat(s, pdu, fidp, max_count);
+        if (count < 0) {
+            err = count;
+            goto out;
         }
-        return;
-    } else if (vs->fidp->fid_type == P9_FID_XATTR) {
-        v9fs_xattr_read(s, vs);
-        return;
+        err = offset;
+        err += pdu_marshal(pdu, offset, "d", count);
+        err += count;
+    } else if (fidp->fid_type == P9_FID_FILE) {
+        int32_t cnt;
+        int32_t len;
+        struct iovec *sg;
+        struct iovec iov[128]; /* FIXME: bad, bad, bad */
+
+        sg = iov;
+        pdu_marshal(pdu, offset + 4, "v", sg, &cnt);
+        sg = cap_sg(sg, max_count, &cnt);
+        do {
+            if (0) {
+                print_sg(sg, cnt);
+            }
+            /* Loop in case of EINTR */
+            do {
+                len = v9fs_co_preadv(s, fidp, sg, cnt, off);
+                if (len >= 0) {
+                    off   += len;
+                    count += len;
+                }
+            } while (len == -EINTR);
+            if (len < 0) {
+                /* IO error return the error */
+                err = len;
+                goto out;
+            }
+            sg = adjust_sg(sg, len, &cnt);
+        } while (count < max_count && len > 0);
+        err = offset;
+        err += pdu_marshal(pdu, offset, "d", count);
+        err += count;
+    } else if (fidp->fid_type == P9_FID_XATTR) {
+        err = v9fs_xattr_read(s, pdu, fidp, off, max_count);
     } else {
         err = -EINVAL;
     }
 out:
     complete_pdu(s, pdu, err);
-    g_free(vs);
 }
 
 static size_t v9fs_readdir_data_size(V9fsString *name)
commit 7eafdcc96c13535bad6137ea33a1bcacb5e48cd8
Author: Aneesh Kumar K.V <aneesh.kumar at linux.vnet.ibm.com>
Date:   Sun May 8 15:16:22 2011 +0530

    hw/9pfs: Add yield support for preadv coroutine
    
    Signed-off-by: Aneesh Kumar K.V <aneesh.kumar at linux.vnet.ibm.com>

diff --git a/hw/9pfs/cofile.c b/hw/9pfs/cofile.c
index e0d032d..e388146 100644
--- a/hw/9pfs/cofile.c
+++ b/hw/9pfs/cofile.c
@@ -144,3 +144,20 @@ int v9fs_co_pwritev(V9fsState *s, V9fsFidState *fidp,
         });
     return err;
 }
+
+int v9fs_co_preadv(V9fsState *s, V9fsFidState *fidp,
+                   struct iovec *iov, int iovcnt, int64_t offset)
+{
+    int fd;
+    int err;
+
+    fd = fidp->fs.fd;
+    v9fs_co_run_in_worker(
+        {
+            err = s->ops->preadv(&s->ctx, fd, iov, iovcnt, offset);
+            if (err < 0) {
+                err = -errno;
+            }
+        });
+    return err;
+}
diff --git a/hw/9pfs/virtio-9p-coth.h b/hw/9pfs/virtio-9p-coth.h
index fa408f8..5fa2972 100644
--- a/hw/9pfs/virtio-9p-coth.h
+++ b/hw/9pfs/virtio-9p-coth.h
@@ -91,4 +91,6 @@ extern int v9fs_co_symlink(V9fsState *, V9fsFidState *, const char *,
 extern int v9fs_co_link(V9fsState *, V9fsString *, V9fsString *);
 extern int v9fs_co_pwritev(V9fsState *, V9fsFidState *,
                            struct iovec *, int, int64_t);
+extern int v9fs_co_preadv(V9fsState *, V9fsFidState *,
+                          struct iovec *, int, int64_t);
 #endif
commit 8c158561a0a0aff9c245260a7284e8498093ab20
Author: Aneesh Kumar K.V <aneesh.kumar at linux.vnet.ibm.com>
Date:   Sun May 8 13:15:29 2011 +0530

    hw/9pfs: Update v9fs_attach to use coroutines
    
    Signed-off-by: Aneesh Kumar K.V <aneesh.kumar at linux.vnet.ibm.com>

diff --git a/hw/9pfs/virtio-9p.c b/hw/9pfs/virtio-9p.c
index 9329f70..add889e 100644
--- a/hw/9pfs/virtio-9p.c
+++ b/hw/9pfs/virtio-9p.c
@@ -402,11 +402,10 @@ static int fid_to_qid(V9fsState *s, V9fsFidState *fidp, V9fsQID *qidp)
     struct stat stbuf;
     int err;
 
-    err = v9fs_do_lstat(s, &fidp->path, &stbuf);
-    if (err) {
+    err = v9fs_co_lstat(s, &fidp->path, &stbuf);
+    if (err < 0) {
         return err;
     }
-
     stat_to_qid(&stbuf, qidp);
     return 0;
 }
@@ -1032,8 +1031,8 @@ static void v9fs_attach(void *opaque)
     int32_t fid, afid, n_uname;
     V9fsString uname, aname;
     V9fsFidState *fidp;
-    V9fsQID qid;
     size_t offset = 7;
+    V9fsQID qid;
     ssize_t err;
 
     pdu_unmarshal(pdu, offset, "ddssd", &fid, &afid, &uname, &aname, &n_uname);
@@ -1043,19 +1042,15 @@ static void v9fs_attach(void *opaque)
         err = -EINVAL;
         goto out;
     }
-
     fidp->uid = n_uname;
-
     v9fs_string_sprintf(&fidp->path, "%s", "/");
     err = fid_to_qid(s, fidp, &qid);
-    if (err) {
+    if (err < 0) {
         err = -EINVAL;
         free_fid(s, fid);
         goto out;
     }
-
     offset += pdu_marshal(pdu, offset, "Q", &qid);
-
     err = offset;
 out:
     complete_pdu(s, pdu, err);
commit b81d685e2111c52cc78e242f97194c950ee22558
Author: Aneesh Kumar K.V <aneesh.kumar at linux.vnet.ibm.com>
Date:   Sun May 8 13:06:04 2011 +0530

    hw/9pfs: Update v9fs_wstat to use coroutines
    
    Signed-off-by: Aneesh Kumar K.V <aneesh.kumar at linux.vnet.ibm.com>

diff --git a/hw/9pfs/virtio-9p.c b/hw/9pfs/virtio-9p.c
index 4b5c584..9329f70 100644
--- a/hw/9pfs/virtio-9p.c
+++ b/hw/9pfs/virtio-9p.c
@@ -103,40 +103,6 @@ static int v9fs_do_preadv(V9fsState *s, int fd, const struct iovec *iov,
     return s->ops->preadv(&s->ctx, fd, iov, iovcnt, offset);
 }
 
-static int v9fs_do_chmod(V9fsState *s, V9fsString *path, mode_t mode)
-{
-    FsCred cred;
-    cred_init(&cred);
-    cred.fc_mode = mode;
-    return s->ops->chmod(&s->ctx, path->data, &cred);
-}
-
-static int v9fs_do_truncate(V9fsState *s, V9fsString *path, off_t size)
-{
-    return s->ops->truncate(&s->ctx, path->data, size);
-}
-
-static int v9fs_do_chown(V9fsState *s, V9fsString *path, uid_t uid, gid_t gid)
-{
-    FsCred cred;
-    cred_init(&cred);
-    cred.fc_uid = uid;
-    cred.fc_gid = gid;
-
-    return s->ops->chown(&s->ctx, path->data, &cred);
-}
-
-static int v9fs_do_utimensat(V9fsState *s, V9fsString *path,
-                                           const struct timespec times[2])
-{
-    return s->ops->utimensat(&s->ctx, path->data, times);
-}
-
-static int v9fs_do_fsync(V9fsState *s, int fd, int datasync)
-{
-    return s->ops->fsync(&s->ctx, fd, datasync);
-}
-
 static void v9fs_string_init(V9fsString *str)
 {
     str->data = NULL;
@@ -2181,39 +2147,6 @@ out:
     complete_pdu(pdu->s, pdu, err);
 }
 
-static void v9fs_wstat_post_truncate(V9fsState *s, V9fsWstatState *vs, int err)
-{
-    if (err < 0) {
-        goto out;
-    }
-
-    err = vs->offset;
-
-out:
-    v9fs_stat_free(&vs->v9stat);
-    complete_pdu(s, vs->pdu, err);
-    g_free(vs);
-}
-
-static void v9fs_wstat_post_rename(V9fsState *s, V9fsWstatState *vs, int err)
-{
-    if (err < 0) {
-        goto out;
-    }
-    if (vs->v9stat.length != -1) {
-        if (v9fs_do_truncate(s, &vs->fidp->path, vs->v9stat.length) < 0) {
-            err = -errno;
-        }
-    }
-    v9fs_wstat_post_truncate(s, vs, err);
-    return;
-
-out:
-    v9fs_stat_free(&vs->v9stat);
-    complete_pdu(s, vs->pdu, err);
-    g_free(vs);
-}
-
 static int v9fs_complete_rename(V9fsState *s, V9fsFidState *fidp,
                                 int32_t newdirfid, V9fsString *name)
 {
@@ -2282,24 +2215,6 @@ out:
     return err;
 }
 
-static void v9fs_wstat_post_chown(V9fsState *s, V9fsWstatState *vs, int err)
-{
-    if (err < 0) {
-        goto out;
-    }
-
-    if (vs->v9stat.name.size != 0) {
-        err = v9fs_complete_rename(s, vs->fidp, -1, &vs->v9stat.name);
-    }
-    v9fs_wstat_post_rename(s, vs, err);
-    return;
-
-out:
-    v9fs_stat_free(&vs->v9stat);
-    complete_pdu(s, vs->pdu, err);
-    g_free(vs);
-}
-
 static void v9fs_rename(void *opaque)
 {
     int32_t fid;
@@ -2329,143 +2244,90 @@ out:
     v9fs_string_free(&name);
 }
 
-static void v9fs_wstat_post_utime(V9fsState *s, V9fsWstatState *vs, int err)
+static void v9fs_wstat(void *opaque)
 {
-    if (err < 0) {
-        goto out;
-    }
+    int32_t fid;
+    int err = 0;
+    int16_t unused;
+    V9fsStat v9stat;
+    size_t offset = 7;
+    struct stat stbuf;
+    V9fsFidState *fidp;
+    V9fsPDU *pdu = opaque;
+    V9fsState *s = pdu->s;
 
-    if (vs->v9stat.n_gid != -1 || vs->v9stat.n_uid != -1) {
-        if (v9fs_do_chown(s, &vs->fidp->path, vs->v9stat.n_uid,
-                    vs->v9stat.n_gid)) {
-            err = -errno;
-        }
+    pdu_unmarshal(pdu, offset, "dwS", &fid, &unused, &v9stat);
+    fidp = lookup_fid(s, fid);
+    if (fidp == NULL) {
+        err = -EINVAL;
+        goto out;
     }
-    v9fs_wstat_post_chown(s, vs, err);
-    return;
-
-out:
-    v9fs_stat_free(&vs->v9stat);
-    complete_pdu(s, vs->pdu, err);
-    g_free(vs);
-}
-
-static void v9fs_wstat_post_chmod(V9fsState *s, V9fsWstatState *vs, int err)
-{
-    if (err < 0) {
+    /* do we need to sync the file? */
+    if (donttouch_stat(&v9stat)) {
+        err = v9fs_co_fsync(s, fidp, 0);
         goto out;
     }
-
-    if (vs->v9stat.mtime != -1 || vs->v9stat.atime != -1) {
+    if (v9stat.mode != -1) {
+        uint32_t v9_mode;
+        err = v9fs_co_lstat(s, &fidp->path, &stbuf);
+        if (err < 0) {
+            goto out;
+        }
+        v9_mode = stat_to_v9mode(&stbuf);
+        if ((v9stat.mode & P9_STAT_MODE_TYPE_BITS) !=
+            (v9_mode & P9_STAT_MODE_TYPE_BITS)) {
+            /* Attempting to change the type */
+            err = -EIO;
+            goto out;
+        }
+        err = v9fs_co_chmod(s, &fidp->path,
+                            v9mode_to_mode(v9stat.mode,
+                                           &v9stat.extension));
+        if (err < 0) {
+            goto out;
+        }
+    }
+    if (v9stat.mtime != -1 || v9stat.atime != -1) {
         struct timespec times[2];
-        if (vs->v9stat.atime != -1) {
-            times[0].tv_sec = vs->v9stat.atime;
+        if (v9stat.atime != -1) {
+            times[0].tv_sec = v9stat.atime;
             times[0].tv_nsec = 0;
         } else {
             times[0].tv_nsec = UTIME_OMIT;
         }
-        if (vs->v9stat.mtime != -1) {
-            times[1].tv_sec = vs->v9stat.mtime;
+        if (v9stat.mtime != -1) {
+            times[1].tv_sec = v9stat.mtime;
             times[1].tv_nsec = 0;
         } else {
             times[1].tv_nsec = UTIME_OMIT;
         }
-
-        if (v9fs_do_utimensat(s, &vs->fidp->path, times)) {
-            err = -errno;
+        err = v9fs_co_utimensat(s, &fidp->path, times);
+        if (err < 0) {
+            goto out;
         }
     }
-
-    v9fs_wstat_post_utime(s, vs, err);
-    return;
-
-out:
-    v9fs_stat_free(&vs->v9stat);
-    complete_pdu(s, vs->pdu, err);
-    g_free(vs);
-}
-
-static void v9fs_wstat_post_fsync(V9fsState *s, V9fsWstatState *vs, int err)
-{
-    if (err == -1) {
-        err = -errno;
-    }
-    v9fs_stat_free(&vs->v9stat);
-    complete_pdu(s, vs->pdu, err);
-    g_free(vs);
-}
-
-static void v9fs_wstat_post_lstat(V9fsState *s, V9fsWstatState *vs, int err)
-{
-    uint32_t v9_mode;
-
-    if (err == -1) {
-        err = -errno;
-        goto out;
-    }
-
-    v9_mode = stat_to_v9mode(&vs->stbuf);
-
-    if ((vs->v9stat.mode & P9_STAT_MODE_TYPE_BITS) !=
-        (v9_mode & P9_STAT_MODE_TYPE_BITS)) {
-            /* Attempting to change the type */
-            err = -EIO;
+    if (v9stat.n_gid != -1 || v9stat.n_uid != -1) {
+        err = v9fs_co_chown(s, &fidp->path, v9stat.n_uid, v9stat.n_gid);
+        if (err < 0) {
             goto out;
+        }
     }
-
-    if (v9fs_do_chmod(s, &vs->fidp->path, v9mode_to_mode(vs->v9stat.mode,
-                    &vs->v9stat.extension))) {
-            err = -errno;
-     }
-    v9fs_wstat_post_chmod(s, vs, err);
-    return;
-
-out:
-    v9fs_stat_free(&vs->v9stat);
-    complete_pdu(s, vs->pdu, err);
-    g_free(vs);
-}
-
-static void v9fs_wstat(void *opaque)
-{
-    V9fsPDU *pdu = opaque;
-    V9fsState *s = pdu->s;
-    int32_t fid;
-    V9fsWstatState *vs;
-    int err = 0;
-
-    vs = g_malloc(sizeof(*vs));
-    vs->pdu = pdu;
-    vs->offset = 7;
-
-    pdu_unmarshal(pdu, vs->offset, "dwS", &fid, &vs->unused, &vs->v9stat);
-
-    vs->fidp = lookup_fid(s, fid);
-    if (vs->fidp == NULL) {
-        err = -EINVAL;
-        goto out;
-    }
-
-    /* do we need to sync the file? */
-    if (donttouch_stat(&vs->v9stat)) {
-        err = v9fs_do_fsync(s, vs->fidp->fs.fd, 0);
-        v9fs_wstat_post_fsync(s, vs, err);
-        return;
+    if (v9stat.name.size != 0) {
+        err = v9fs_complete_rename(s, fidp, -1, &v9stat.name);
+        if (err < 0) {
+            goto out;
+        }
     }
-
-    if (vs->v9stat.mode != -1) {
-        err = v9fs_do_lstat(s, &vs->fidp->path, &vs->stbuf);
-        v9fs_wstat_post_lstat(s, vs, err);
-        return;
+    if (v9stat.length != -1) {
+        err = v9fs_co_truncate(s, &fidp->path, v9stat.length);
+        if (err < 0) {
+            goto out;
+        }
     }
-
-    v9fs_wstat_post_chmod(s, vs, err);
-    return;
-
+    err = offset;
 out:
-    v9fs_stat_free(&vs->v9stat);
-    complete_pdu(s, vs->pdu, err);
-    g_free(vs);
+    v9fs_stat_free(&v9stat);
+    complete_pdu(s, pdu, err);
 }
 
 static int v9fs_fill_statfs(V9fsState *s, V9fsPDU *pdu, struct statfs *stbuf)
diff --git a/hw/9pfs/virtio-9p.h b/hw/9pfs/virtio-9p.h
index 29f3184..1d8c1b1 100644
--- a/hw/9pfs/virtio-9p.h
+++ b/hw/9pfs/virtio-9p.h
@@ -295,16 +295,6 @@ typedef struct V9fsWriteState {
     int cnt;
 } V9fsWriteState;
 
-typedef struct V9fsWstatState
-{
-    V9fsPDU *pdu;
-    size_t offset;
-    int16_t unused;
-    V9fsStat v9stat;
-    V9fsFidState *fidp;
-    struct stat stbuf;
-} V9fsWstatState;
-
 typedef struct V9fsIattr
 {
     int32_t valid;
commit d7a90491195a4b830296ffd8a91e2c882c2833ed
Author: Aneesh Kumar K.V <aneesh.kumar at linux.vnet.ibm.com>
Date:   Sun May 8 12:29:31 2011 +0530

    hw/9pfs: Update v9fs_write to use coroutines
    
    Signed-off-by: Aneesh Kumar K.V <aneesh.kumar at linux.vnet.ibm.com>

diff --git a/hw/9pfs/virtio-9p.c b/hw/9pfs/virtio-9p.c
index fdfe582..4b5c584 100644
--- a/hw/9pfs/virtio-9p.c
+++ b/hw/9pfs/virtio-9p.c
@@ -103,12 +103,6 @@ static int v9fs_do_preadv(V9fsState *s, int fd, const struct iovec *iov,
     return s->ops->preadv(&s->ctx, fd, iov, iovcnt, offset);
 }
 
-static int v9fs_do_pwritev(V9fsState *s, int fd, const struct iovec *iov,
-                       int iovcnt, int64_t offset)
-{
-    return s->ops->pwritev(&s->ctx, fd, iov, iovcnt, offset);
-}
-
 static int v9fs_do_chmod(V9fsState *s, V9fsString *path, mode_t mode)
 {
     FsCred cred;
@@ -1834,51 +1828,21 @@ out:
     complete_pdu(s, pdu, retval);
 }
 
-static void v9fs_write_post_pwritev(V9fsState *s, V9fsWriteState *vs,
-                                   ssize_t err)
-{
-    if (err  < 0) {
-        /* IO error return the error */
-        err = -errno;
-        goto out;
-    }
-    vs->total += vs->len;
-    vs->sg = adjust_sg(vs->sg, vs->len, &vs->cnt);
-    if (vs->total < vs->count && vs->len > 0) {
-        do {
-            if (0) {
-                print_sg(vs->sg, vs->cnt);
-            }
-            vs->len = v9fs_do_pwritev(s, vs->fidp->fs.fd, vs->sg, vs->cnt,
-                      vs->off);
-            if (vs->len > 0) {
-                vs->off += vs->len;
-            }
-        } while (vs->len == -1 && errno == EINTR);
-        if (vs->len == -1) {
-            err  = -errno;
-        }
-        v9fs_write_post_pwritev(s, vs, err);
-        return;
-    }
-    vs->offset += pdu_marshal(vs->pdu, vs->offset, "d", vs->total);
-    err = vs->offset;
-out:
-    complete_pdu(s, vs->pdu, err);
-    g_free(vs);
-}
-
-static void v9fs_xattr_write(V9fsState *s, V9fsWriteState *vs)
+static int v9fs_xattr_write(V9fsState *s, V9fsPDU *pdu, V9fsFidState *fidp,
+                            int64_t off, int32_t count,
+                            struct iovec *sg, int cnt)
 {
     int i, to_copy;
     ssize_t err = 0;
     int write_count;
     int64_t xattr_len;
+    size_t offset = 7;
 
-    xattr_len = vs->fidp->fs.xattr.len;
-    write_count = xattr_len - vs->off;
-    if (write_count > vs->count) {
-        write_count = vs->count;
+
+    xattr_len = fidp->fs.xattr.len;
+    write_count = xattr_len - off;
+    if (write_count > count) {
+        write_count = count;
     } else if (write_count < 0) {
         /*
          * write beyond XATTR value len specified in
@@ -1887,82 +1851,88 @@ static void v9fs_xattr_write(V9fsState *s, V9fsWriteState *vs)
         err = -ENOSPC;
         goto out;
     }
-    vs->offset += pdu_marshal(vs->pdu, vs->offset, "d", write_count);
-    err = vs->offset;
-    vs->fidp->fs.xattr.copied_len += write_count;
+    offset += pdu_marshal(pdu, offset, "d", write_count);
+    err = offset;
+    fidp->fs.xattr.copied_len += write_count;
     /*
      * Now copy the content from sg list
      */
-    for (i = 0; i < vs->cnt; i++) {
-        if (write_count > vs->sg[i].iov_len) {
-            to_copy = vs->sg[i].iov_len;
+    for (i = 0; i < cnt; i++) {
+        if (write_count > sg[i].iov_len) {
+            to_copy = sg[i].iov_len;
         } else {
             to_copy = write_count;
         }
-        memcpy((char *)vs->fidp->fs.xattr.value + vs->off,
-               vs->sg[i].iov_base, to_copy);
+        memcpy((char *)fidp->fs.xattr.value + off, sg[i].iov_base, to_copy);
         /* updating vs->off since we are not using below */
-        vs->off += to_copy;
+        off += to_copy;
         write_count -= to_copy;
     }
 out:
-    complete_pdu(s, vs->pdu, err);
-    g_free(vs);
+    return err;
 }
 
 static void v9fs_write(void *opaque)
 {
+    int cnt;
+    ssize_t err;
+    int32_t fid;
+    int64_t off;
+    int32_t count;
+    int32_t len = 0;
+    int32_t total = 0;
+    size_t offset = 7;
+    V9fsFidState *fidp;
+    struct iovec iov[128]; /* FIXME: bad, bad, bad */
+    struct iovec *sg = iov;
     V9fsPDU *pdu = opaque;
     V9fsState *s = pdu->s;
-    int32_t fid;
-    V9fsWriteState *vs;
-    ssize_t err;
 
-    vs = g_malloc(sizeof(*vs));
-
-    vs->pdu = pdu;
-    vs->offset = 7;
-    vs->sg = vs->iov;
-    vs->total = 0;
-    vs->len = 0;
-
-    pdu_unmarshal(vs->pdu, vs->offset, "dqdv", &fid, &vs->off, &vs->count,
-                  vs->sg, &vs->cnt);
-
-    vs->fidp = lookup_fid(s, fid);
-    if (vs->fidp == NULL) {
+    pdu_unmarshal(pdu, offset, "dqdv", &fid, &off, &count, sg, &cnt);
+    fidp = lookup_fid(s, fid);
+    if (fidp == NULL) {
         err = -EINVAL;
         goto out;
     }
-
-    if (vs->fidp->fid_type == P9_FID_FILE) {
-        if (vs->fidp->fs.fd == -1) {
+    if (fidp->fid_type == P9_FID_FILE) {
+        if (fidp->fs.fd == -1) {
             err = -EINVAL;
             goto out;
         }
-    } else if (vs->fidp->fid_type == P9_FID_XATTR) {
+    } else if (fidp->fid_type == P9_FID_XATTR) {
         /*
          * setxattr operation
          */
-        v9fs_xattr_write(s, vs);
-        return;
+        err = v9fs_xattr_write(s, pdu, fidp, off, count, sg, cnt);
+        goto out;
     } else {
         err = -EINVAL;
         goto out;
     }
-    vs->sg = cap_sg(vs->sg, vs->count, &vs->cnt);
-    if (vs->total <= vs->count) {
-        vs->len = v9fs_do_pwritev(s, vs->fidp->fs.fd, vs->sg, vs->cnt, vs->off);
-        if (vs->len > 0) {
-            vs->off += vs->len;
+    sg = cap_sg(sg, count, &cnt);
+    do {
+        if (0) {
+            print_sg(sg, cnt);
         }
-        err = vs->len;
-        v9fs_write_post_pwritev(s, vs, err);
-    }
-    return;
+        /* Loop in case of EINTR */
+        do {
+            len = v9fs_co_pwritev(s, fidp, sg, cnt, off);
+            if (len >= 0) {
+                off   += len;
+                total += len;
+            }
+        } while (len == -EINTR);
+        if (len < 0) {
+            /* IO error return the error */
+            err = len;
+            goto out;
+        }
+        sg = adjust_sg(sg, len, &cnt);
+    } while (total < count && len > 0);
+    offset += pdu_marshal(pdu, offset, "d", total);
+    err = offset;
 out:
-    complete_pdu(s, vs->pdu, err);
-    g_free(vs);
+    complete_pdu(s, pdu, err);
 }
 
 static void v9fs_create(void *opaque)
commit f6b3c976c699451a52bdef7f93a3ef128ee648e3
Author: Aneesh Kumar K.V <aneesh.kumar at linux.vnet.ibm.com>
Date:   Sun May 8 12:36:59 2011 +0530

    hw/9pfs: Add yield support for pwritev coroutine
    
    Signed-off-by: Aneesh Kumar K.V <aneesh.kumar at linux.vnet.ibm.com>

diff --git a/hw/9pfs/cofile.c b/hw/9pfs/cofile.c
index 52eec2a..e0d032d 100644
--- a/hw/9pfs/cofile.c
+++ b/hw/9pfs/cofile.c
@@ -127,3 +127,20 @@ int v9fs_co_link(V9fsState *s, V9fsString *oldpath, V9fsString *newpath)
         });
     return err;
 }
+
+int v9fs_co_pwritev(V9fsState *s, V9fsFidState *fidp,
+                    struct iovec *iov, int iovcnt, int64_t offset)
+{
+    int fd;
+    int err;
+
+    fd = fidp->fs.fd;
+    v9fs_co_run_in_worker(
+        {
+            err = s->ops->pwritev(&s->ctx, fd, iov, iovcnt, offset);
+            if (err < 0) {
+                err = -errno;
+            }
+        });
+    return err;
+}
diff --git a/hw/9pfs/virtio-9p-coth.h b/hw/9pfs/virtio-9p-coth.h
index 17ffd76..fa408f8 100644
--- a/hw/9pfs/virtio-9p-coth.h
+++ b/hw/9pfs/virtio-9p-coth.h
@@ -89,4 +89,6 @@ extern int v9fs_co_fsync(V9fsState *, V9fsFidState *, int);
 extern int v9fs_co_symlink(V9fsState *, V9fsFidState *, const char *,
                            const char *, gid_t);
 extern int v9fs_co_link(V9fsState *, V9fsString *, V9fsString *);
+extern int v9fs_co_pwritev(V9fsState *, V9fsFidState *,
+                           struct iovec *, int, int64_t);
 #endif
commit ffd668764cb2db02606d74f68c7b59d0585e9d3c
Author: Venkateswararao Jujjuri (JV) <jvrao at linux.vnet.ibm.com>
Date:   Mon May 9 11:47:28 2011 -0700

    hw/9pfs: Update v9fs_link to use coroutines
    
    Signed-off-by: Venkateswararao Jujjuri <jvrao at linux.vnet.ibm.com>
    Signed-off-by: Aneesh Kumar K.V <aneesh.kumar at linux.vnet.ibm.com>

diff --git a/hw/9pfs/virtio-9p.c b/hw/9pfs/virtio-9p.c
index 203c031..fdfe582 100644
--- a/hw/9pfs/virtio-9p.c
+++ b/hw/9pfs/virtio-9p.c
@@ -117,11 +117,6 @@ static int v9fs_do_chmod(V9fsState *s, V9fsString *path, mode_t mode)
     return s->ops->chmod(&s->ctx, path->data, &cred);
 }
 
-static int v9fs_do_link(V9fsState *s, V9fsString *oldpath, V9fsString *newpath)
-{
-    return s->ops->link(&s->ctx, oldpath->data, newpath->data);
-}
-
 static int v9fs_do_truncate(V9fsState *s, V9fsString *path, off_t size)
 {
     return s->ops->truncate(&s->ctx, path->data, size);
@@ -2029,9 +2024,8 @@ static void v9fs_create(void *opaque)
             err = -EINVAL;
             goto out;
         }
-        err = v9fs_do_link(pdu->s, &nfidp->path, &fullname);
+        err = v9fs_co_link(pdu->s, &nfidp->path, &fullname);
         if (err < 0) {
-            err = -errno;
             goto out;
         }
     } else if (perm & P9_STAT_MODE_DEVICE) {
@@ -2169,21 +2163,20 @@ static void v9fs_link(void *opaque)
 
     dfidp = lookup_fid(s, dfid);
     if (dfidp == NULL) {
-        err = -errno;
+        err = -ENOENT;
         goto out;
     }
 
     oldfidp = lookup_fid(s, oldfid);
     if (oldfidp == NULL) {
-        err = -errno;
+        err = -ENOENT;
         goto out;
     }
 
     v9fs_string_sprintf(&fullname, "%s/%s", dfidp->path.data, name.data);
-    err = offset;
-    err = v9fs_do_link(s, &oldfidp->path, &fullname);
-    if (err) {
-        err = -errno;
+    err = v9fs_co_link(s, &oldfidp->path, &fullname);
+    if (!err) {
+        err = offset;
     }
     v9fs_string_free(&fullname);
 
commit c6c069b0c5fdfc748008d8a4879f3d41c1d32702
Author: Venkateswararao Jujjuri <jvrao at linux.vnet.ibm.com>
Date:   Tue Aug 9 00:01:22 2011 +0530

    hw/9pfs: Add yield support for link coroutine
    
    Signed-off-by: Venkateswararao Jujjuri <jvrao at linux.vnet.ibm.com>
    Signed-off-by: Aneesh Kumar K.V <aneesh.kumar at linux.vnet.ibm.com>

diff --git a/hw/9pfs/cofile.c b/hw/9pfs/cofile.c
index 26dd636..52eec2a 100644
--- a/hw/9pfs/cofile.c
+++ b/hw/9pfs/cofile.c
@@ -113,3 +113,17 @@ int v9fs_co_fsync(V9fsState *s, V9fsFidState *fidp, int datasync)
         });
     return err;
 }
+
+int v9fs_co_link(V9fsState *s, V9fsString *oldpath, V9fsString *newpath)
+{
+    int err;
+
+    v9fs_co_run_in_worker(
+        {
+            err = s->ops->link(&s->ctx, oldpath->data, newpath->data);
+            if (err < 0) {
+                err = -errno;
+            }
+        });
+    return err;
+}
diff --git a/hw/9pfs/virtio-9p-coth.h b/hw/9pfs/virtio-9p-coth.h
index e394933..17ffd76 100644
--- a/hw/9pfs/virtio-9p-coth.h
+++ b/hw/9pfs/virtio-9p-coth.h
@@ -88,4 +88,5 @@ extern int v9fs_co_close(V9fsState *, V9fsFidState *);
 extern int v9fs_co_fsync(V9fsState *, V9fsFidState *, int);
 extern int v9fs_co_symlink(V9fsState *, V9fsFidState *, const char *,
                            const char *, gid_t);
+extern int v9fs_co_link(V9fsState *, V9fsString *, V9fsString *);
 #endif
commit 3fa2a8d1cd5794dd20c5bdb71e5a6db4b6f8eb4f
Author: Venkateswararao Jujjuri <jvrao at linux.vnet.ibm.com>
Date:   Tue Aug 9 00:00:01 2011 +0530

    hw/9pfs: Update v9fs_symlink to use coroutines
    
    Signed-off-by: Venkateswararao Jujjuri <jvrao at linux.vnet.ibm.com>
    Signed-off-by: Aneesh Kumar K.V <aneesh.kumar at linux.vnet.ibm.com>

diff --git a/hw/9pfs/virtio-9p.c b/hw/9pfs/virtio-9p.c
index 1659e8c..203c031 100644
--- a/hw/9pfs/virtio-9p.c
+++ b/hw/9pfs/virtio-9p.c
@@ -117,18 +117,6 @@ static int v9fs_do_chmod(V9fsState *s, V9fsString *path, mode_t mode)
     return s->ops->chmod(&s->ctx, path->data, &cred);
 }
 
-static int v9fs_do_symlink(V9fsState *s, V9fsFidState *fidp,
-        const char *oldpath, const char *newpath, gid_t gid)
-{
-    FsCred cred;
-    cred_init(&cred);
-    cred.fc_uid = fidp->uid;
-    cred.fc_gid = gid;
-    cred.fc_mode = 0777;
-
-    return s->ops->symlink(&s->ctx, oldpath, newpath, &cred);
-}
-
 static int v9fs_do_link(V9fsState *s, V9fsString *oldpath, V9fsString *newpath)
 {
     return s->ops->link(&s->ctx, oldpath->data, newpath->data);
@@ -2029,10 +2017,9 @@ static void v9fs_create(void *opaque)
         }
         fidp->fid_type = P9_FID_DIR;
     } else if (perm & P9_STAT_MODE_SYMLINK) {
-        err = v9fs_do_symlink(pdu->s, fidp, extension.data,
+        err = v9fs_co_symlink(pdu->s, fidp, extension.data,
                               fullname.data, -1);
         if (err < 0) {
-            err = -errno;
             goto out;
         }
     } else if (perm & P9_STAT_MODE_LINK) {
@@ -2115,69 +2102,46 @@ out:
    v9fs_string_free(&fullname);
 }
 
-static void v9fs_post_symlink(V9fsState *s, V9fsSymlinkState *vs, int err)
-{
-    if (err == 0) {
-        stat_to_qid(&vs->stbuf, &vs->qid);
-        vs->offset += pdu_marshal(vs->pdu, vs->offset, "Q", &vs->qid);
-        err = vs->offset;
-    } else {
-        err = -errno;
-    }
-    complete_pdu(s, vs->pdu, err);
-    v9fs_string_free(&vs->name);
-    v9fs_string_free(&vs->symname);
-    v9fs_string_free(&vs->fullname);
-    g_free(vs);
-}
-
-static void v9fs_symlink_post_do_symlink(V9fsState *s, V9fsSymlinkState *vs,
-        int err)
-{
-    if (err) {
-        goto out;
-    }
-    err = v9fs_do_lstat(s, &vs->fullname, &vs->stbuf);
-out:
-    v9fs_post_symlink(s, vs, err);
-}
-
 static void v9fs_symlink(void *opaque)
 {
     V9fsPDU *pdu = opaque;
-    V9fsState *s = pdu->s;
+    V9fsString name;
+    V9fsString symname;
+    V9fsString fullname;
+    V9fsFidState *dfidp;
+    V9fsQID qid;
+    struct stat stbuf;
     int32_t dfid;
-    V9fsSymlinkState *vs;
     int err = 0;
     gid_t gid;
+    size_t offset = 7;
 
-    vs = g_malloc(sizeof(*vs));
-    vs->pdu = pdu;
-    vs->offset = 7;
-
-    v9fs_string_init(&vs->fullname);
-
-    pdu_unmarshal(vs->pdu, vs->offset, "dssd", &dfid, &vs->name,
-            &vs->symname, &gid);
+    v9fs_string_init(&fullname);
+    pdu_unmarshal(pdu, offset, "dssd", &dfid, &name, &symname, &gid);
 
-    vs->dfidp = lookup_fid(s, dfid);
-    if (vs->dfidp == NULL) {
+    dfidp = lookup_fid(pdu->s, dfid);
+    if (dfidp == NULL) {
         err = -EINVAL;
         goto out;
     }
 
-    v9fs_string_sprintf(&vs->fullname, "%s/%s", vs->dfidp->path.data,
-            vs->name.data);
-    err = v9fs_do_symlink(s, vs->dfidp, vs->symname.data,
-            vs->fullname.data, gid);
-    v9fs_symlink_post_do_symlink(s, vs, err);
-    return;
-
+    v9fs_string_sprintf(&fullname, "%s/%s", dfidp->path.data, name.data);
+    err = v9fs_co_symlink(pdu->s, dfidp, symname.data, fullname.data, gid);
+    if (err < 0) {
+        goto out;
+    }
+    err = v9fs_co_lstat(pdu->s, &fullname, &stbuf);
+    if (err < 0) {
+        goto out;
+    }
+    stat_to_qid(&stbuf, &qid);
+    offset += pdu_marshal(pdu, offset, "Q", &qid);
+    err = offset;
 out:
-    complete_pdu(s, vs->pdu, err);
-    v9fs_string_free(&vs->name);
-    v9fs_string_free(&vs->symname);
-    g_free(vs);
+    complete_pdu(pdu->s, pdu, err);
+    v9fs_string_free(&name);
+    v9fs_string_free(&symname);
+    v9fs_string_free(&fullname);
 }
 
 static void v9fs_flush(void *opaque)
diff --git a/hw/9pfs/virtio-9p.h b/hw/9pfs/virtio-9p.h
index e7d87d9..29f3184 100644
--- a/hw/9pfs/virtio-9p.h
+++ b/hw/9pfs/virtio-9p.h
@@ -305,18 +305,6 @@ typedef struct V9fsWstatState
     struct stat stbuf;
 } V9fsWstatState;
 
-typedef struct V9fsSymlinkState
-{
-    V9fsPDU *pdu;
-    size_t offset;
-    V9fsString name;
-    V9fsString symname;
-    V9fsString fullname;
-    V9fsFidState *dfidp;
-    V9fsQID qid;
-    struct stat stbuf;
-} V9fsSymlinkState;
-
 typedef struct V9fsIattr
 {
     int32_t valid;
commit 02ac7a34ff124b8d41dc1afadf622b07fa292b48
Author: Venkateswararao Jujjuri <jvrao at linux.vnet.ibm.com>
Date:   Mon Aug 8 23:58:39 2011 +0530

    hw/9pfs: Add yield support for symlin coroutine
    
    Signed-off-by: Venkateswararao Jujjuri <jvrao at linux.vnet.ibm.com>
    Signed-off-by: Aneesh Kumar K.V <aneesh.kumar at linux.vnet.ibm.com>

diff --git a/hw/9pfs/cofs.c b/hw/9pfs/cofs.c
index 1f10632..a78fccb 100644
--- a/hw/9pfs/cofs.c
+++ b/hw/9pfs/cofs.c
@@ -169,3 +169,23 @@ int v9fs_co_rename(V9fsState *s, V9fsString *oldpath, V9fsString *newpath)
         });
     return err;
 }
+
+int v9fs_co_symlink(V9fsState *s, V9fsFidState *fidp,
+                    const char *oldpath, const char *newpath, gid_t gid)
+{
+    int err;
+    FsCred cred;
+
+    cred_init(&cred);
+    cred.fc_uid = fidp->uid;
+    cred.fc_gid = gid;
+    cred.fc_mode = 0777;
+    v9fs_co_run_in_worker(
+        {
+            err = s->ops->symlink(&s->ctx, oldpath, newpath, &cred);
+            if (err < 0) {
+                err = -errno;
+            }
+        });
+    return err;
+}
diff --git a/hw/9pfs/virtio-9p-coth.h b/hw/9pfs/virtio-9p-coth.h
index a3881f3..e394933 100644
--- a/hw/9pfs/virtio-9p-coth.h
+++ b/hw/9pfs/virtio-9p-coth.h
@@ -86,4 +86,6 @@ extern int v9fs_co_lremovexattr(V9fsState *, V9fsString *, V9fsString *);
 extern int v9fs_co_closedir(V9fsState *, V9fsFidState *);
 extern int v9fs_co_close(V9fsState *, V9fsFidState *);
 extern int v9fs_co_fsync(V9fsState *, V9fsFidState *, int);
+extern int v9fs_co_symlink(V9fsState *, V9fsFidState *, const char *,
+                           const char *, gid_t);
 #endif
commit baaa86d9f5d516d423d34af92e0c15b56e06ac4b
Author: Venkateswararao Jujjuri <jvrao at linux.vnet.ibm.com>
Date:   Mon Aug 8 23:56:50 2011 +0530

    hw/9pfs: Update v9fs_create to use coroutines
    
    Signed-off-by: Venkateswararao Jujjuri <jvrao at linux.vnet.ibm.com>
    Signed-off-by: Aneesh Kumar K.V <aneesh.kumar at linux.vnet.ibm.com>

diff --git a/hw/9pfs/virtio-9p.c b/hw/9pfs/virtio-9p.c
index fc1f513..1659e8c 100644
--- a/hw/9pfs/virtio-9p.c
+++ b/hw/9pfs/virtio-9p.c
@@ -82,11 +82,6 @@ static int v9fs_do_lstat(V9fsState *s, V9fsString *path, struct stat *stbuf)
     return s->ops->lstat(&s->ctx, path->data, stbuf);
 }
 
-static DIR *v9fs_do_opendir(V9fsState *s, V9fsString *path)
-{
-    return s->ops->opendir(&s->ctx, path->data);
-}
-
 static void v9fs_do_rewinddir(V9fsState *s, DIR *dir)
 {
     return s->ops->rewinddir(&s->ctx, dir);
@@ -122,23 +117,6 @@ static int v9fs_do_chmod(V9fsState *s, V9fsString *path, mode_t mode)
     return s->ops->chmod(&s->ctx, path->data, &cred);
 }
 
-static int v9fs_do_mknod(V9fsState *s, char *name,
-        mode_t mode, dev_t dev, uid_t uid, gid_t gid)
-{
-    FsCred cred;
-    cred_init(&cred);
-    cred.fc_uid = uid;
-    cred.fc_gid = gid;
-    cred.fc_mode = mode;
-    cred.fc_rdev = dev;
-    return s->ops->mknod(&s->ctx, name, &cred);
-}
-
-static int v9fs_do_fstat(V9fsState *s, int fd, struct stat *stbuf)
-{
-    return s->ops->fstat(&s->ctx, fd, stbuf);
-}
-
 static int v9fs_do_symlink(V9fsState *s, V9fsFidState *fidp,
         const char *oldpath, const char *newpath, gid_t gid)
 {
@@ -2004,146 +1982,79 @@ out:
     g_free(vs);
 }
 
-static void v9fs_create_post_getiounit(V9fsState *s, V9fsCreateState *vs)
-{
-    int err;
-    v9fs_string_copy(&vs->fidp->path, &vs->fullname);
-    stat_to_qid(&vs->stbuf, &vs->qid);
-
-    vs->offset += pdu_marshal(vs->pdu, vs->offset, "Qd", &vs->qid, vs->iounit);
-    err = vs->offset;
-
-    complete_pdu(s, vs->pdu, err);
-    v9fs_string_free(&vs->name);
-    v9fs_string_free(&vs->extension);
-    v9fs_string_free(&vs->fullname);
-    g_free(vs);
-}
-
-static void v9fs_post_create(V9fsState *s, V9fsCreateState *vs, int err)
-{
-    if (err == 0) {
-        vs->iounit = get_iounit(s, &vs->fidp->path);
-        v9fs_create_post_getiounit(s, vs);
-        return;
-    }
-
-    complete_pdu(s, vs->pdu, err);
-    v9fs_string_free(&vs->name);
-    v9fs_string_free(&vs->extension);
-    v9fs_string_free(&vs->fullname);
-    g_free(vs);
-}
-
-static void v9fs_create_post_perms(V9fsState *s, V9fsCreateState *vs, int err)
-{
-    if (err) {
-        err = -errno;
-    }
-    v9fs_post_create(s, vs, err);
-}
-
-static void v9fs_create_post_opendir(V9fsState *s, V9fsCreateState *vs,
-                                                                    int err)
-{
-    if (!vs->fidp->fs.dir) {
-        err = -errno;
-    }
-    vs->fidp->fid_type = P9_FID_DIR;
-    v9fs_post_create(s, vs, err);
-}
-
-static void v9fs_create_post_dir_lstat(V9fsState *s, V9fsCreateState *vs,
-                                                                    int err)
+static void v9fs_create(void *opaque)
 {
-    if (err) {
-        err = -errno;
-        goto out;
-    }
+    int32_t fid;
+    int err = 0;
+    size_t offset = 7;
+    V9fsFidState *fidp;
+    V9fsQID qid;
+    int32_t perm;
+    int8_t mode;
+    struct stat stbuf;
+    V9fsString name;
+    V9fsString extension;
+    V9fsString fullname;
+    int iounit;
+    V9fsPDU *pdu = opaque;
 
-    vs->fidp->fs.dir = v9fs_do_opendir(s, &vs->fullname);
-    v9fs_create_post_opendir(s, vs, err);
-    return;
+    v9fs_string_init(&fullname);
 
-out:
-    v9fs_post_create(s, vs, err);
-}
+    pdu_unmarshal(pdu, offset, "dsdbs", &fid, &name,
+                  &perm, &mode, &extension);
 
-static void v9fs_create_post_mkdir(V9fsState *s, V9fsCreateState *vs, int err)
-{
-    if (err < 0) {
+    fidp = lookup_fid(pdu->s, fid);
+    if (fidp == NULL) {
+        err = -EINVAL;
         goto out;
     }
 
-    err = v9fs_do_lstat(s, &vs->fullname, &vs->stbuf);
-    v9fs_create_post_dir_lstat(s, vs, err);
-    return;
-
-out:
-    v9fs_post_create(s, vs, err);
-}
-
-static void v9fs_create_post_fstat(V9fsState *s, V9fsCreateState *vs, int err)
-{
-    if (err) {
-        vs->fidp->fid_type = P9_FID_NONE;
-        close(vs->fidp->fs.fd);
-        err = -errno;
-    }
-    v9fs_post_create(s, vs, err);
-    return;
-}
-
-static void v9fs_create_post_open2(V9fsState *s, V9fsCreateState *vs, int err)
-{
-    if (err < 0) {
+    v9fs_string_sprintf(&fullname, "%s/%s", fidp->path.data, name.data);
+    err = v9fs_co_lstat(pdu->s, &fullname, &stbuf);
+    if (!err) {
+        err = -EEXIST;
         goto out;
-    }
-    vs->fidp->fid_type = P9_FID_FILE;
-    err = v9fs_do_fstat(s, vs->fidp->fs.fd, &vs->stbuf);
-    v9fs_create_post_fstat(s, vs, err);
-
-    return;
-
-out:
-    v9fs_post_create(s, vs, err);
-
-}
-
-static void v9fs_create_post_lstat(V9fsState *s, V9fsCreateState *vs, int err)
-{
-
-    if (err == 0 || errno != ENOENT) {
-        err = -errno;
+    } else if (err != -ENOENT) {
         goto out;
     }
-
-    if (vs->perm & P9_STAT_MODE_DIR) {
-        err = v9fs_co_mkdir(s, vs->fullname.data, vs->perm & 0777,
-                vs->fidp->uid, -1);
-        v9fs_create_post_mkdir(s, vs, err);
-    } else if (vs->perm & P9_STAT_MODE_SYMLINK) {
-        err = v9fs_do_symlink(s, vs->fidp, vs->extension.data,
-                vs->fullname.data, -1);
-        v9fs_create_post_perms(s, vs, err);
-    } else if (vs->perm & P9_STAT_MODE_LINK) {
-        int32_t nfid = atoi(vs->extension.data);
-        V9fsFidState *nfidp = lookup_fid(s, nfid);
+    if (perm & P9_STAT_MODE_DIR) {
+        err = v9fs_co_mkdir(pdu->s, fullname.data, perm & 0777,
+                            fidp->uid, -1);
+        if (err < 0) {
+            goto out;
+        }
+        err = v9fs_co_opendir(pdu->s, fidp);
+        if (err < 0) {
+            goto out;
+        }
+        fidp->fid_type = P9_FID_DIR;
+    } else if (perm & P9_STAT_MODE_SYMLINK) {
+        err = v9fs_do_symlink(pdu->s, fidp, extension.data,
+                              fullname.data, -1);
+        if (err < 0) {
+            err = -errno;
+            goto out;
+        }
+    } else if (perm & P9_STAT_MODE_LINK) {
+        int32_t nfid = atoi(extension.data);
+        V9fsFidState *nfidp = lookup_fid(pdu->s, nfid);
         if (nfidp == NULL) {
+            err = -EINVAL;
+            goto out;
+        }
+        err = v9fs_do_link(pdu->s, &nfidp->path, &fullname);
+        if (err < 0) {
             err = -errno;
-            v9fs_post_create(s, vs, err);
+            goto out;
         }
-        err = v9fs_do_link(s, &nfidp->path, &vs->fullname);
-        v9fs_create_post_perms(s, vs, err);
-    } else if (vs->perm & P9_STAT_MODE_DEVICE) {
+    } else if (perm & P9_STAT_MODE_DEVICE) {
         char ctype;
         uint32_t major, minor;
         mode_t nmode = 0;
 
-        if (sscanf(vs->extension.data, "%c %u %u", &ctype, &major,
-                                        &minor) != 3) {
+        if (sscanf(extension.data, "%c %u %u", &ctype, &major, &minor) != 3) {
             err = -errno;
-            v9fs_post_create(s, vs, err);
+            goto out;
         }
 
         switch (ctype) {
@@ -2155,69 +2066,53 @@ static void v9fs_create_post_lstat(V9fsState *s, V9fsCreateState *vs, int err)
             break;
         default:
             err = -EIO;
-            v9fs_post_create(s, vs, err);
-        }
-
-        nmode |= vs->perm & 0777;
-        err = v9fs_do_mknod(s, vs->fullname.data, nmode,
-                makedev(major, minor), vs->fidp->uid, -1);
-        v9fs_create_post_perms(s, vs, err);
-    } else if (vs->perm & P9_STAT_MODE_NAMED_PIPE) {
-        err = v9fs_do_mknod(s, vs->fullname.data, S_IFIFO | (vs->perm & 0777),
-                0, vs->fidp->uid, -1);
-        v9fs_post_create(s, vs, err);
-    } else if (vs->perm & P9_STAT_MODE_SOCKET) {
-        err = v9fs_do_mknod(s, vs->fullname.data, S_IFSOCK | (vs->perm & 0777),
-                0, vs->fidp->uid, -1);
-        v9fs_post_create(s, vs, err);
-    } else {
-        err = v9fs_co_open2(s, vs->fidp, vs->fullname.data, -1,
-                omode_to_uflags(vs->mode)|O_CREAT, vs->perm);
+            goto out;
+        }
 
-        v9fs_create_post_open2(s, vs, err);
+        nmode |= perm & 0777;
+        err = v9fs_co_mknod(pdu->s, &fullname, fidp->uid, -1,
+                            makedev(major, minor), nmode);
+        if (err < 0) {
+            goto out;
+        }
+    } else if (perm & P9_STAT_MODE_NAMED_PIPE) {
+        err = v9fs_co_mknod(pdu->s, &fullname, fidp->uid, -1,
+                            0, S_IFIFO | (perm & 0777));
+        if (err < 0) {
+            goto out;
+        }
+    } else if (perm & P9_STAT_MODE_SOCKET) {
+        err = v9fs_co_mknod(pdu->s, &fullname, fidp->uid, -1,
+                            0, S_IFSOCK | (perm & 0777));
+        if (err < 0) {
+            goto out;
+        }
+    } else {
+        err = v9fs_co_open2(pdu->s, fidp, fullname.data, -1,
+                            omode_to_uflags(mode)|O_CREAT, perm);
+        if (err < 0) {
+            goto out;
+        }
+        fidp->fid_type = P9_FID_FILE;
     }
-
-    return;
-
-out:
-    v9fs_post_create(s, vs, err);
-}
-
-static void v9fs_create(void *opaque)
-{
-    V9fsPDU *pdu = opaque;
-    V9fsState *s = pdu->s;
-    int32_t fid;
-    V9fsCreateState *vs;
-    int err = 0;
-
-    vs = g_malloc(sizeof(*vs));
-    vs->pdu = pdu;
-    vs->offset = 7;
-
-    v9fs_string_init(&vs->fullname);
-
-    pdu_unmarshal(vs->pdu, vs->offset, "dsdbs", &fid, &vs->name,
-                                &vs->perm, &vs->mode, &vs->extension);
-
-    vs->fidp = lookup_fid(s, fid);
-    if (vs->fidp == NULL) {
-        err = -EINVAL;
+    err = v9fs_co_lstat(pdu->s, &fullname, &stbuf);
+    if (err < 0) {
+        fidp->fid_type = P9_FID_NONE;
+        if (fidp->fs.fd) {
+            close(fidp->fs.fd);
+        }
         goto out;
     }
-
-    v9fs_string_sprintf(&vs->fullname, "%s/%s", vs->fidp->path.data,
-                                                        vs->name.data);
-
-    err = v9fs_do_lstat(s, &vs->fullname, &vs->stbuf);
-    v9fs_create_post_lstat(s, vs, err);
-    return;
-
+    iounit = get_iounit(pdu->s, &fidp->path);
+    v9fs_string_copy(&fidp->path, &fullname);
+    stat_to_qid(&stbuf, &qid);
+    offset += pdu_marshal(pdu, offset, "Qd", &qid, iounit);
+    err = offset;
 out:
-    complete_pdu(s, vs->pdu, err);
-    v9fs_string_free(&vs->name);
-    v9fs_string_free(&vs->extension);
-    g_free(vs);
+   complete_pdu(pdu->s, pdu, err);
+   v9fs_string_free(&name);
+   v9fs_string_free(&extension);
+   v9fs_string_free(&fullname);
 }
 
 static void v9fs_post_symlink(V9fsState *s, V9fsSymlinkState *vs, int err)
diff --git a/hw/9pfs/virtio-9p.h b/hw/9pfs/virtio-9p.h
index 3b585f0..e7d87d9 100644
--- a/hw/9pfs/virtio-9p.h
+++ b/hw/9pfs/virtio-9p.h
@@ -222,20 +222,6 @@ typedef struct V9fsState
     int32_t msize;
 } V9fsState;
 
-typedef struct V9fsCreateState {
-    V9fsPDU *pdu;
-    size_t offset;
-    V9fsFidState *fidp;
-    V9fsQID qid;
-    int32_t perm;
-    int8_t mode;
-    struct stat stbuf;
-    V9fsString name;
-    V9fsString extension;
-    V9fsString fullname;
-    int iounit;
-} V9fsCreateState;
-
 typedef struct V9fsStatState {
     V9fsPDU *pdu;
     size_t offset;
commit 4e9ad444982576f8434929b8e23c9fefb625c9e4
Author: Aneesh Kumar K.V <aneesh.kumar at linux.vnet.ibm.com>
Date:   Sat May 7 21:25:51 2011 +0530

    hw/9pfs: Update v9fs_fsync to use coroutines
    
    Signed-off-by: Aneesh Kumar K.V <aneesh.kumar at linux.vnet.ibm.com>

diff --git a/hw/9pfs/virtio-9p.c b/hw/9pfs/virtio-9p.c
index c113294..fc1f513 100644
--- a/hw/9pfs/virtio-9p.c
+++ b/hw/9pfs/virtio-9p.c
@@ -1530,33 +1530,28 @@ out:
     v9fs_string_free(&fullname);
 }
 
-static void v9fs_post_do_fsync(V9fsState *s, V9fsPDU *pdu, int err)
-{
-    if (err == -1) {
-        err = -errno;
-    }
-    complete_pdu(s, pdu, err);
-}
-
 static void v9fs_fsync(void *opaque)
 {
-    V9fsPDU *pdu = opaque;
-    V9fsState *s = pdu->s;
+    int err;
     int32_t fid;
+    int datasync;
     size_t offset = 7;
     V9fsFidState *fidp;
-    int datasync;
-    int err;
+    V9fsPDU *pdu = opaque;
+    V9fsState *s = pdu->s;
 
     pdu_unmarshal(pdu, offset, "dd", &fid, &datasync);
     fidp = lookup_fid(s, fid);
     if (fidp == NULL) {
         err = -ENOENT;
-        v9fs_post_do_fsync(s, pdu, err);
-        return;
+        goto out;
     }
-    err = v9fs_do_fsync(s, fidp->fs.fd, datasync);
-    v9fs_post_do_fsync(s, pdu, err);
+    err = v9fs_co_fsync(s, fidp, datasync);
+    if (!err) {
+        err = offset;
+    }
+out:
+    complete_pdu(s, pdu, err);
 }
 
 static void v9fs_clunk(void *opaque)
commit 4743d1f5d31c76ff60223dcf05f5358dc4605015
Author: Aneesh Kumar K.V <aneesh.kumar at linux.vnet.ibm.com>
Date:   Sat May 7 21:29:32 2011 +0530

    hw/9pfs: Add yield support for fsync coroutine
    
    Signed-off-by: Aneesh Kumar K.V <aneesh.kumar at linux.vnet.ibm.com>

diff --git a/hw/9pfs/cofile.c b/hw/9pfs/cofile.c
index e552999..26dd636 100644
--- a/hw/9pfs/cofile.c
+++ b/hw/9pfs/cofile.c
@@ -97,3 +97,19 @@ int v9fs_co_close(V9fsState *s, V9fsFidState *fidp)
         });
     return err;
 }
+
+int v9fs_co_fsync(V9fsState *s, V9fsFidState *fidp, int datasync)
+{
+    int fd;
+    int err;
+
+    fd = fidp->fs.fd;
+    v9fs_co_run_in_worker(
+        {
+            err = s->ops->fsync(&s->ctx, fd, datasync);
+            if (err < 0) {
+                err = -errno;
+            }
+        });
+    return err;
+}
diff --git a/hw/9pfs/virtio-9p-coth.h b/hw/9pfs/virtio-9p-coth.h
index 5d7dfd7..a3881f3 100644
--- a/hw/9pfs/virtio-9p-coth.h
+++ b/hw/9pfs/virtio-9p-coth.h
@@ -85,4 +85,5 @@ extern int v9fs_co_lsetxattr(V9fsState *, V9fsString *, V9fsString *,
 extern int v9fs_co_lremovexattr(V9fsState *, V9fsString *, V9fsString *);
 extern int v9fs_co_closedir(V9fsState *, V9fsFidState *);
 extern int v9fs_co_close(V9fsState *, V9fsFidState *);
+extern int v9fs_co_fsync(V9fsState *, V9fsFidState *, int);
 #endif
commit c540ee51870e283e4ddc0ebf694419bfdeaef66f
Author: Aneesh Kumar K.V <aneesh.kumar at linux.vnet.ibm.com>
Date:   Sat May 7 20:36:38 2011 +0530

    hw/9pfs: Update v9fs_clunk to use coroutines
    
    Signed-off-by: Aneesh Kumar K.V <aneesh.kumar at linux.vnet.ibm.com>

diff --git a/hw/9pfs/virtio-9p.c b/hw/9pfs/virtio-9p.c
index 766821b..c113294 100644
--- a/hw/9pfs/virtio-9p.c
+++ b/hw/9pfs/virtio-9p.c
@@ -82,16 +82,6 @@ static int v9fs_do_lstat(V9fsState *s, V9fsString *path, struct stat *stbuf)
     return s->ops->lstat(&s->ctx, path->data, stbuf);
 }
 
-static int v9fs_do_close(V9fsState *s, int fd)
-{
-    return s->ops->close(&s->ctx, fd);
-}
-
-static int v9fs_do_closedir(V9fsState *s, DIR *dir)
-{
-    return s->ops->closedir(&s->ctx, dir);
-}
-
 static DIR *v9fs_do_opendir(V9fsState *s, V9fsString *path)
 {
     return s->ops->opendir(&s->ctx, path->data);
@@ -192,22 +182,6 @@ static int v9fs_do_fsync(V9fsState *s, int fd, int datasync)
     return s->ops->fsync(&s->ctx, fd, datasync);
 }
 
-static int v9fs_do_lsetxattr(V9fsState *s, V9fsString *path,
-                             V9fsString *xattr_name,
-                             void *value, size_t size, int flags)
-{
-    return s->ops->lsetxattr(&s->ctx, path->data,
-                             xattr_name->data, value, size, flags);
-}
-
-static int v9fs_do_lremovexattr(V9fsState *s, V9fsString *path,
-                                V9fsString *xattr_name)
-{
-    return s->ops->lremovexattr(&s->ctx, path->data,
-                                xattr_name->data);
-}
-
-
 static void v9fs_string_init(V9fsString *str)
 {
     str->data = NULL;
@@ -414,12 +388,12 @@ static int v9fs_xattr_fid_clunk(V9fsState *s, V9fsFidState *fidp)
         goto free_out;
     }
     if (fidp->fs.xattr.len) {
-        retval = v9fs_do_lsetxattr(s, &fidp->path, &fidp->fs.xattr.name,
+        retval = v9fs_co_lsetxattr(s, &fidp->path, &fidp->fs.xattr.name,
                                    fidp->fs.xattr.value,
                                    fidp->fs.xattr.len,
                                    fidp->fs.xattr.flags);
     } else {
-        retval = v9fs_do_lremovexattr(s, &fidp->path, &fidp->fs.xattr.name);
+        retval = v9fs_co_lremovexattr(s, &fidp->path, &fidp->fs.xattr.name);
     }
 free_out:
     v9fs_string_free(&fidp->fs.xattr.name);
@@ -449,15 +423,14 @@ static int free_fid(V9fsState *s, int32_t fid)
     *fidpp = fidp->next;
 
     if (fidp->fid_type == P9_FID_FILE) {
-        v9fs_do_close(s, fidp->fs.fd);
+        retval = v9fs_co_close(s, fidp);
     } else if (fidp->fid_type == P9_FID_DIR) {
-        v9fs_do_closedir(s, fidp->fs.dir);
+        retval = v9fs_co_closedir(s, fidp);
     } else if (fidp->fid_type == P9_FID_XATTR) {
         retval = v9fs_xattr_fid_clunk(s, fidp);
     }
     v9fs_string_free(&fidp->path);
     g_free(fidp);
-
     return retval;
 }
 
@@ -1588,20 +1561,17 @@ static void v9fs_fsync(void *opaque)
 
 static void v9fs_clunk(void *opaque)
 {
-    V9fsPDU *pdu = opaque;
-    V9fsState *s = pdu->s;
+    int err;
     int32_t fid;
     size_t offset = 7;
-    int err;
+    V9fsPDU *pdu = opaque;
+    V9fsState *s = pdu->s;
 
     pdu_unmarshal(pdu, offset, "d", &fid);
-
     err = free_fid(s, fid);
     if (err < 0) {
         goto out;
     }
-
-    offset = 7;
     err = offset;
 out:
     complete_pdu(s, pdu, err);
commit bed4352c4f041af65c522cb453aff468f49aebea
Author: Aneesh Kumar K.V <aneesh.kumar at linux.vnet.ibm.com>
Date:   Sat May 7 21:09:24 2011 +0530

    hw/9pfs: Add yeild support for clunk related coroutine
    
    This include lsetxattr, lremovexattr, closedir and close.
    
    Signed-off-by: Aneesh Kumar K.V <aneesh.kumar at linux.vnet.ibm.com>

diff --git a/hw/9pfs/codir.c b/hw/9pfs/codir.c
index bc6a105..0c31db3 100644
--- a/hw/9pfs/codir.c
+++ b/hw/9pfs/codir.c
@@ -99,3 +99,19 @@ int v9fs_co_opendir(V9fsState *s, V9fsFidState *fidp)
         });
     return err;
 }
+
+int v9fs_co_closedir(V9fsState *s, V9fsFidState *fidp)
+{
+    int err;
+    DIR *dir;
+
+    dir = fidp->fs.dir;
+    v9fs_co_run_in_worker(
+        {
+            err = s->ops->closedir(&s->ctx, dir);
+            if (err < 0) {
+                err = -errno;
+            }
+        });
+    return err;
+}
diff --git a/hw/9pfs/cofile.c b/hw/9pfs/cofile.c
index 4b0d96c..e552999 100644
--- a/hw/9pfs/cofile.c
+++ b/hw/9pfs/cofile.c
@@ -81,3 +81,19 @@ int v9fs_co_open2(V9fsState *s, V9fsFidState *fidp, char *fullname, gid_t gid,
         });
     return err;
 }
+
+int v9fs_co_close(V9fsState *s, V9fsFidState *fidp)
+{
+    int fd;
+    int err;
+
+    fd = fidp->fs.fd;
+    v9fs_co_run_in_worker(
+        {
+            err = s->ops->close(&s->ctx, fd);
+            if (err < 0) {
+                err = -errno;
+            }
+        });
+    return err;
+}
diff --git a/hw/9pfs/coxattr.c b/hw/9pfs/coxattr.c
index 2fba2c9..a289389 100644
--- a/hw/9pfs/coxattr.c
+++ b/hw/9pfs/coxattr.c
@@ -48,3 +48,37 @@ int v9fs_co_lgetxattr(V9fsState *s, V9fsString *path,
         });
     return err;
 }
+
+int v9fs_co_lsetxattr(V9fsState *s, V9fsString *path,
+                      V9fsString *xattr_name, void *value,
+                      size_t size, int flags)
+{
+    int err;
+
+    v9fs_co_run_in_worker(
+        {
+            err = s->ops->lsetxattr(&s->ctx, path->data,
+                                    xattr_name->data, value,
+                                    size, flags);
+            if (err < 0) {
+                err = -errno;
+            }
+        });
+    return err;
+}
+
+int v9fs_co_lremovexattr(V9fsState *s, V9fsString *path,
+                         V9fsString *xattr_name)
+{
+    int err;
+
+    v9fs_co_run_in_worker(
+        {
+            err = s->ops->lremovexattr(&s->ctx, path->data,
+                                       xattr_name->data);
+            if (err < 0) {
+                err = -errno;
+            }
+        });
+    return err;
+}
diff --git a/hw/9pfs/virtio-9p-coth.h b/hw/9pfs/virtio-9p-coth.h
index f9610b9..5d7dfd7 100644
--- a/hw/9pfs/virtio-9p-coth.h
+++ b/hw/9pfs/virtio-9p-coth.h
@@ -80,4 +80,9 @@ extern int v9fs_co_fstat(V9fsState *, int, struct stat *);
 extern int v9fs_co_opendir(V9fsState *, V9fsFidState *);
 extern int v9fs_co_open(V9fsState *, V9fsFidState *, int);
 extern int v9fs_co_open2(V9fsState *, V9fsFidState *, char *, gid_t, int, int);
+extern int v9fs_co_lsetxattr(V9fsState *, V9fsString *, V9fsString *,
+                             void *, size_t, int);
+extern int v9fs_co_lremovexattr(V9fsState *, V9fsString *, V9fsString *);
+extern int v9fs_co_closedir(V9fsState *, V9fsFidState *);
+extern int v9fs_co_close(V9fsState *, V9fsFidState *);
 #endif
commit 3cc19c0c607ca780c79dbf42b4781d110a64e342
Author: Aneesh Kumar K.V <aneesh.kumar at linux.vnet.ibm.com>
Date:   Sat May 7 19:41:55 2011 +0530

    hw/9pfs: Update v9fs_walk to use coroutines
    
    Signed-off-by: Aneesh Kumar K.V <aneesh.kumar at linux.vnet.ibm.com>

diff --git a/hw/9pfs/virtio-9p.c b/hw/9pfs/virtio-9p.c
index 911d019..766821b 100644
--- a/hw/9pfs/virtio-9p.c
+++ b/hw/9pfs/virtio-9p.c
@@ -1327,171 +1327,101 @@ out:
     complete_pdu(s, pdu, err);
 }
 
-static void v9fs_walk_complete(V9fsState *s, V9fsWalkState *vs, int err)
-{
-    complete_pdu(s, vs->pdu, err);
-
-    if (vs->nwnames && vs->nwnames <= P9_MAXWELEM) {
-        for (vs->name_idx = 0; vs->name_idx < vs->nwnames; vs->name_idx++) {
-            v9fs_string_free(&vs->wnames[vs->name_idx]);
-        }
-
-        g_free(vs->wnames);
-        g_free(vs->qids);
-    }
-}
-
-static void v9fs_walk_marshal(V9fsWalkState *vs)
+static int v9fs_walk_marshal(V9fsPDU *pdu, uint16_t nwnames, V9fsQID *qids)
 {
     int i;
-    vs->offset = 7;
-    vs->offset += pdu_marshal(vs->pdu, vs->offset, "w", vs->nwnames);
-
-    for (i = 0; i < vs->nwnames; i++) {
-        vs->offset += pdu_marshal(vs->pdu, vs->offset, "Q", &vs->qids[i]);
-    }
-}
-
-static void v9fs_walk_post_newfid_lstat(V9fsState *s, V9fsWalkState *vs,
-                                                                int err)
-{
-    if (err == -1) {
-        free_fid(s, vs->newfidp->fid);
-        v9fs_string_free(&vs->path);
-        err = -ENOENT;
-        goto out;
-    }
-
-    stat_to_qid(&vs->stbuf, &vs->qids[vs->name_idx]);
-
-    vs->name_idx++;
-    if (vs->name_idx < vs->nwnames) {
-        v9fs_string_sprintf(&vs->path, "%s/%s", vs->newfidp->path.data,
-                                            vs->wnames[vs->name_idx].data);
-        v9fs_string_copy(&vs->newfidp->path, &vs->path);
-
-        err = v9fs_do_lstat(s, &vs->newfidp->path, &vs->stbuf);
-        v9fs_walk_post_newfid_lstat(s, vs, err);
-        return;
-    }
-
-    v9fs_string_free(&vs->path);
-    v9fs_walk_marshal(vs);
-    err = vs->offset;
-out:
-    v9fs_walk_complete(s, vs, err);
-}
-
-static void v9fs_walk_post_oldfid_lstat(V9fsState *s, V9fsWalkState *vs,
-        int err)
-{
-    if (err == -1) {
-        v9fs_string_free(&vs->path);
-        err = -ENOENT;
-        goto out;
-    }
-
-    stat_to_qid(&vs->stbuf, &vs->qids[vs->name_idx]);
-    vs->name_idx++;
-    if (vs->name_idx < vs->nwnames) {
-
-        v9fs_string_sprintf(&vs->path, "%s/%s",
-                vs->fidp->path.data, vs->wnames[vs->name_idx].data);
-        v9fs_string_copy(&vs->fidp->path, &vs->path);
-
-        err = v9fs_do_lstat(s, &vs->fidp->path, &vs->stbuf);
-        v9fs_walk_post_oldfid_lstat(s, vs, err);
-        return;
+    size_t offset = 7;
+    offset += pdu_marshal(pdu, offset, "w", nwnames);
+    for (i = 0; i < nwnames; i++) {
+        offset += pdu_marshal(pdu, offset, "Q", &qids[i]);
     }
-
-    v9fs_string_free(&vs->path);
-    v9fs_walk_marshal(vs);
-    err = vs->offset;
-out:
-    v9fs_walk_complete(s, vs, err);
+    return offset;
 }
 
 static void v9fs_walk(void *opaque)
 {
+    int name_idx;
+    V9fsQID *qids = NULL;
+    int i, err = 0;
+    V9fsString path;
+    uint16_t nwnames;
+    struct stat stbuf;
+    size_t offset = 7;
+    int32_t fid, newfid;
+    V9fsString *wnames = NULL;
+    V9fsFidState *fidp;
+    V9fsFidState *newfidp;
     V9fsPDU *pdu = opaque;
     V9fsState *s = pdu->s;
-    int32_t fid, newfid;
-    V9fsWalkState *vs;
-    int err = 0;
-    int i;
 
-    vs = g_malloc(sizeof(*vs));
-    vs->pdu = pdu;
-    vs->wnames = NULL;
-    vs->qids = NULL;
-    vs->offset = 7;
-
-    vs->offset += pdu_unmarshal(vs->pdu, vs->offset, "ddw", &fid,
-                                            &newfid, &vs->nwnames);
-
-    if (vs->nwnames && vs->nwnames <= P9_MAXWELEM) {
-        vs->wnames = g_malloc0(sizeof(vs->wnames[0]) * vs->nwnames);
+    offset += pdu_unmarshal(pdu, offset, "ddw", &fid,
+                            &newfid, &nwnames);
 
-        vs->qids = g_malloc0(sizeof(vs->qids[0]) * vs->nwnames);
-
-        for (i = 0; i < vs->nwnames; i++) {
-            vs->offset += pdu_unmarshal(vs->pdu, vs->offset, "s",
-                                            &vs->wnames[i]);
+    if (nwnames && nwnames <= P9_MAXWELEM) {
+        wnames = g_malloc0(sizeof(wnames[0]) * nwnames);
+        qids   = g_malloc0(sizeof(qids[0]) * nwnames);
+        for (i = 0; i < nwnames; i++) {
+            offset += pdu_unmarshal(pdu, offset, "s", &wnames[i]);
         }
-    } else if (vs->nwnames > P9_MAXWELEM) {
+
+    } else if (nwnames > P9_MAXWELEM) {
         err = -EINVAL;
         goto out;
     }
-
-    vs->fidp = lookup_fid(s, fid);
-    if (vs->fidp == NULL) {
+    fidp = lookup_fid(s, fid);
+    if (fidp == NULL) {
         err = -ENOENT;
         goto out;
     }
-
-    /* FIXME: is this really valid? */
     if (fid == newfid) {
-
-        BUG_ON(vs->fidp->fid_type != P9_FID_NONE);
-        v9fs_string_init(&vs->path);
-        vs->name_idx = 0;
-
-        if (vs->name_idx < vs->nwnames) {
-            v9fs_string_sprintf(&vs->path, "%s/%s",
-                vs->fidp->path.data, vs->wnames[vs->name_idx].data);
-            v9fs_string_copy(&vs->fidp->path, &vs->path);
-
-            err = v9fs_do_lstat(s, &vs->fidp->path, &vs->stbuf);
-            v9fs_walk_post_oldfid_lstat(s, vs, err);
-            return;
+        BUG_ON(fidp->fid_type != P9_FID_NONE);
+        v9fs_string_init(&path);
+        for (name_idx = 0; name_idx < nwnames; name_idx++) {
+            v9fs_string_sprintf(&path, "%s/%s",
+                                fidp->path.data, wnames[name_idx].data);
+            v9fs_string_copy(&fidp->path, &path);
+
+            err = v9fs_co_lstat(s, &fidp->path, &stbuf);
+            if (err < 0) {
+                v9fs_string_free(&path);
+                goto out;
+            }
+            stat_to_qid(&stbuf, &qids[name_idx]);
         }
+        v9fs_string_free(&path);
     } else {
-        vs->newfidp = alloc_fid(s, newfid);
-        if (vs->newfidp == NULL) {
+        newfidp = alloc_fid(s, newfid);
+        if (newfidp == NULL) {
             err = -EINVAL;
             goto out;
         }
-
-        vs->newfidp->uid = vs->fidp->uid;
-        v9fs_string_init(&vs->path);
-        vs->name_idx = 0;
-        v9fs_string_copy(&vs->newfidp->path, &vs->fidp->path);
-
-        if (vs->name_idx < vs->nwnames) {
-            v9fs_string_sprintf(&vs->path, "%s/%s", vs->newfidp->path.data,
-                                vs->wnames[vs->name_idx].data);
-            v9fs_string_copy(&vs->newfidp->path, &vs->path);
-
-            err = v9fs_do_lstat(s, &vs->newfidp->path, &vs->stbuf);
-            v9fs_walk_post_newfid_lstat(s, vs, err);
-            return;
+        newfidp->uid = fidp->uid;
+        v9fs_string_init(&path);
+        v9fs_string_copy(&newfidp->path, &fidp->path);
+        for (name_idx = 0; name_idx < nwnames; name_idx++) {
+            v9fs_string_sprintf(&path, "%s/%s", newfidp->path.data,
+                                wnames[name_idx].data);
+            v9fs_string_copy(&newfidp->path, &path);
+            err = v9fs_co_lstat(s, &newfidp->path, &stbuf);
+            if (err < 0) {
+                free_fid(s, newfidp->fid);
+                v9fs_string_free(&path);
+                goto out;
+            }
+            stat_to_qid(&stbuf, &qids[name_idx]);
         }
+        v9fs_string_free(&path);
     }
-
-    v9fs_walk_marshal(vs);
-    err = vs->offset;
+    err = v9fs_walk_marshal(pdu, nwnames, qids);
 out:
-    v9fs_walk_complete(s, vs, err);
+    complete_pdu(s, pdu, err);
+    if (nwnames && nwnames <= P9_MAXWELEM) {
+        for (name_idx = 0; name_idx < nwnames; name_idx++) {
+            v9fs_string_free(&wnames[name_idx]);
+        }
+        g_free(wnames);
+        g_free(qids);
+    }
 }
 
 static int32_t get_iounit(V9fsState *s, V9fsString *name)
diff --git a/hw/9pfs/virtio-9p.h b/hw/9pfs/virtio-9p.h
index 97ceb72..3b585f0 100644
--- a/hw/9pfs/virtio-9p.h
+++ b/hw/9pfs/virtio-9p.h
@@ -267,19 +267,6 @@ typedef struct V9fsStatDotl {
     uint64_t st_data_version;
 } V9fsStatDotl;
 
-typedef struct V9fsWalkState {
-    V9fsPDU *pdu;
-    size_t offset;
-    uint16_t nwnames;
-    int name_idx;
-    V9fsQID *qids;
-    V9fsFidState *fidp;
-    V9fsFidState *newfidp;
-    V9fsString path;
-    V9fsString *wnames;
-    struct stat stbuf;
-} V9fsWalkState;
-
 typedef struct V9fsOpenState {
     V9fsPDU *pdu;
     size_t offset;
commit d8e0c29e407284f90c6cfb25fb03733347618eec
Author: Aneesh Kumar K.V <aneesh.kumar at linux.vnet.ibm.com>
Date:   Sat May 7 18:29:24 2011 +0530

    hw/9pfs: Update v9fs_stat to use coroutines
    
    Signed-off-by: Aneesh Kumar K.V <aneesh.kumar at linux.vnet.ibm.com>

diff --git a/hw/9pfs/virtio-9p.c b/hw/9pfs/virtio-9p.c
index d382493..911d019 100644
--- a/hw/9pfs/virtio-9p.c
+++ b/hw/9pfs/virtio-9p.c
@@ -1169,56 +1169,36 @@ out:
     v9fs_string_free(&aname);
 }
 
-static void v9fs_stat_post_lstat(V9fsState *s, V9fsStatState *vs, int err)
-{
-    if (err == -1) {
-        err = -errno;
-        goto out;
-    }
-
-    err = stat_to_v9stat(s, &vs->fidp->path, &vs->stbuf, &vs->v9stat);
-    if (err) {
-        goto out;
-    }
-    vs->offset += pdu_marshal(vs->pdu, vs->offset, "wS", 0, &vs->v9stat);
-    err = vs->offset;
-
-out:
-    complete_pdu(s, vs->pdu, err);
-    v9fs_stat_free(&vs->v9stat);
-    g_free(vs);
-}
-
 static void v9fs_stat(void *opaque)
 {
-    V9fsPDU *pdu = opaque;
-    V9fsState *s = pdu->s;
     int32_t fid;
-    V9fsStatState *vs;
+    V9fsStat v9stat;
     ssize_t err = 0;
+    size_t offset = 7;
+    struct stat stbuf;
+    V9fsFidState *fidp;
+    V9fsPDU *pdu = opaque;
+    V9fsState *s = pdu->s;
 
-    vs = g_malloc(sizeof(*vs));
-    vs->pdu = pdu;
-    vs->offset = 7;
-
-    memset(&vs->v9stat, 0, sizeof(vs->v9stat));
-
-    pdu_unmarshal(vs->pdu, vs->offset, "d", &fid);
-
-    vs->fidp = lookup_fid(s, fid);
-    if (vs->fidp == NULL) {
+    pdu_unmarshal(pdu, offset, "d", &fid);
+    fidp = lookup_fid(s, fid);
+    if (fidp == NULL) {
         err = -ENOENT;
         goto out;
     }
-
-    err = v9fs_do_lstat(s, &vs->fidp->path, &vs->stbuf);
-    v9fs_stat_post_lstat(s, vs, err);
-    return;
-
+    err = v9fs_co_lstat(s, &fidp->path, &stbuf);
+    if (err < 0) {
+        goto out;
+    }
+    err = stat_to_v9stat(s, &fidp->path, &stbuf, &v9stat);
+    if (err < 0) {
+        goto out;
+    }
+    offset += pdu_marshal(pdu, offset, "wS", 0, &v9stat);
+    err = offset;
+    v9fs_stat_free(&v9stat);
 out:
-    complete_pdu(s, vs->pdu, err);
-    v9fs_stat_free(&vs->v9stat);
-    g_free(vs);
+    complete_pdu(s, pdu, err);
 }
 
 static void v9fs_getattr(void *opaque)
commit 36f8981f0104520d0b5d964ca55d4bb56c33919a
Author: Venkateswararao Jujjuri <jvrao at linux.vnet.ibm.com>
Date:   Mon Aug 8 23:54:08 2011 +0530

    hw/9pfs: Update v9fs_lcreate to use coroutines
    
    Signed-off-by: Venkateswararao Jujjuri <jvrao at linux.vnet.ibm.com>
    Signed-off-by: Aneesh Kumar K.V <aneesh.kumar at linux.vnet.ibm.com>

diff --git a/hw/9pfs/virtio-9p.c b/hw/9pfs/virtio-9p.c
index c0fa0f4..d382493 100644
--- a/hw/9pfs/virtio-9p.c
+++ b/hw/9pfs/virtio-9p.c
@@ -149,19 +149,6 @@ static int v9fs_do_fstat(V9fsState *s, int fd, struct stat *stbuf)
     return s->ops->fstat(&s->ctx, fd, stbuf);
 }
 
-static int v9fs_do_open2(V9fsState *s, char *fullname, uid_t uid, gid_t gid,
-        int flags, int mode)
-{
-    FsCred cred;
-
-    cred_init(&cred);
-    cred.fc_uid = uid;
-    cred.fc_gid = gid;
-    cred.fc_mode = mode & 07777;
-
-    return s->ops->open2(&s->ctx, fullname, flags, &cred);
-}
-
 static int v9fs_do_symlink(V9fsState *s, V9fsFidState *fidp,
         const char *oldpath, const char *newpath, gid_t gid)
 {
@@ -1607,96 +1594,57 @@ out:
     complete_pdu(s, pdu, err);
 }
 
-static void v9fs_post_lcreate(V9fsState *s, V9fsLcreateState *vs, int err)
-{
-    if (err == 0) {
-        v9fs_string_copy(&vs->fidp->path, &vs->fullname);
-        stat_to_qid(&vs->stbuf, &vs->qid);
-        vs->offset += pdu_marshal(vs->pdu, vs->offset, "Qd", &vs->qid,
-                vs->iounit);
-        err = vs->offset;
-    } else {
-        vs->fidp->fid_type = P9_FID_NONE;
-        err = -errno;
-        if (vs->fidp->fs.fd > 0) {
-            close(vs->fidp->fs.fd);
-        }
-    }
-
-    complete_pdu(s, vs->pdu, err);
-    v9fs_string_free(&vs->name);
-    v9fs_string_free(&vs->fullname);
-    g_free(vs);
-}
-
-static void v9fs_lcreate_post_get_iounit(V9fsState *s, V9fsLcreateState *vs,
-        int err)
-{
-    if (err) {
-        err = -errno;
-        goto out;
-    }
-    err = v9fs_do_lstat(s, &vs->fullname, &vs->stbuf);
-
-out:
-    v9fs_post_lcreate(s, vs, err);
-}
-
-static void v9fs_lcreate_post_do_open2(V9fsState *s, V9fsLcreateState *vs,
-        int err)
-{
-    if (vs->fidp->fs.fd == -1) {
-        err = -errno;
-        goto out;
-    }
-    vs->fidp->fid_type = P9_FID_FILE;
-    vs->iounit =  get_iounit(s, &vs->fullname);
-    v9fs_lcreate_post_get_iounit(s, vs, err);
-    return;
-
-out:
-    v9fs_post_lcreate(s, vs, err);
-}
-
 static void v9fs_lcreate(void *opaque)
 {
-    V9fsPDU *pdu = opaque;
-    V9fsState *s = pdu->s;
     int32_t dfid, flags, mode;
     gid_t gid;
-    V9fsLcreateState *vs;
     ssize_t err = 0;
+    ssize_t offset = 7;
+    V9fsString fullname;
+    V9fsString name;
+    V9fsFidState *fidp;
+    struct stat stbuf;
+    V9fsQID qid;
+    int32_t iounit;
+    V9fsPDU *pdu = opaque;
 
-    vs = g_malloc(sizeof(*vs));
-    vs->pdu = pdu;
-    vs->offset = 7;
-
-    v9fs_string_init(&vs->fullname);
-
-    pdu_unmarshal(vs->pdu, vs->offset, "dsddd", &dfid, &vs->name, &flags,
-            &mode, &gid);
+    v9fs_string_init(&fullname);
+    pdu_unmarshal(pdu, offset, "dsddd", &dfid, &name, &flags,
+                  &mode, &gid);
 
-    vs->fidp = lookup_fid(s, dfid);
-    if (vs->fidp == NULL) {
+    fidp = lookup_fid(pdu->s, dfid);
+    if (fidp == NULL) {
         err = -ENOENT;
         goto out;
     }
-
-    v9fs_string_sprintf(&vs->fullname, "%s/%s", vs->fidp->path.data,
-             vs->name.data);
+    v9fs_string_sprintf(&fullname, "%s/%s", fidp->path.data, name.data);
 
     /* Ignore direct disk access hint until the server supports it. */
     flags &= ~O_DIRECT;
 
-    vs->fidp->fs.fd = v9fs_do_open2(s, vs->fullname.data, vs->fidp->uid,
-            gid, flags, mode);
-    v9fs_lcreate_post_do_open2(s, vs, err);
-    return;
+    err = v9fs_co_open2(pdu->s, fidp, fullname.data, gid, flags, mode);
+    if (err < 0) {
+        goto out;
+    }
+    fidp->fid_type = P9_FID_FILE;
+    iounit =  get_iounit(pdu->s, &fullname);
 
+    err = v9fs_co_lstat(pdu->s, &fullname, &stbuf);
+    if (err < 0) {
+        fidp->fid_type = P9_FID_NONE;
+        if (fidp->fs.fd > 0) {
+            close(fidp->fs.fd);
+        }
+        goto out;
+    }
+    v9fs_string_copy(&fidp->path, &fullname);
+    stat_to_qid(&stbuf, &qid);
+    offset += pdu_marshal(pdu, offset, "Qd", &qid, iounit);
+    err = offset;
 out:
-    complete_pdu(s, vs->pdu, err);
-    v9fs_string_free(&vs->name);
-    g_free(vs);
+    complete_pdu(pdu->s, pdu, err);
+    v9fs_string_free(&name);
+    v9fs_string_free(&fullname);
 }
 
 static void v9fs_post_do_fsync(V9fsState *s, V9fsPDU *pdu, int err)
@@ -2273,8 +2221,7 @@ static void v9fs_create_post_fstat(V9fsState *s, V9fsCreateState *vs, int err)
 
 static void v9fs_create_post_open2(V9fsState *s, V9fsCreateState *vs, int err)
 {
-    if (vs->fidp->fs.fd == -1) {
-        err = -errno;
+    if (err < 0) {
         goto out;
     }
     vs->fidp->fid_type = P9_FID_FILE;
@@ -2349,8 +2296,8 @@ static void v9fs_create_post_lstat(V9fsState *s, V9fsCreateState *vs, int err)
                 0, vs->fidp->uid, -1);
         v9fs_post_create(s, vs, err);
     } else {
-        vs->fidp->fs.fd = v9fs_do_open2(s, vs->fullname.data, vs->fidp->uid,
-                -1, omode_to_uflags(vs->mode)|O_CREAT, vs->perm);
+        err = v9fs_co_open2(s, vs->fidp, vs->fullname.data, -1,
+                omode_to_uflags(vs->mode)|O_CREAT, vs->perm);
 
         v9fs_create_post_open2(s, vs, err);
     }
diff --git a/hw/9pfs/virtio-9p.h b/hw/9pfs/virtio-9p.h
index edf3413..97ceb72 100644
--- a/hw/9pfs/virtio-9p.h
+++ b/hw/9pfs/virtio-9p.h
@@ -236,17 +236,6 @@ typedef struct V9fsCreateState {
     int iounit;
 } V9fsCreateState;
 
-typedef struct V9fsLcreateState {
-    V9fsPDU *pdu;
-    size_t offset;
-    V9fsFidState *fidp;
-    V9fsQID qid;
-    int32_t iounit;
-    struct stat stbuf;
-    V9fsString name;
-    V9fsString fullname;
-} V9fsLcreateState;
-
 typedef struct V9fsStatState {
     V9fsPDU *pdu;
     size_t offset;
commit e4de423214d7c778effc2889ef5cad98b83a4986
Author: Venkateswararao Jujjuri <jvrao at linux.vnet.ibm.com>
Date:   Mon Aug 8 23:52:33 2011 +0530

    hw/9pfs: Add yield support for open2 coroutine
    
    Signed-off-by: Venkateswararao Jujjuri <jvrao at linux.vnet.ibm.com>
    Signed-off-by: Aneesh Kumar K.V <aneesh.kumar at linux.vnet.ibm.com>

diff --git a/hw/9pfs/cofile.c b/hw/9pfs/cofile.c
index 4a3ca21..4b0d96c 100644
--- a/hw/9pfs/cofile.c
+++ b/hw/9pfs/cofile.c
@@ -60,3 +60,24 @@ int v9fs_co_open(V9fsState *s, V9fsFidState *fidp, int flags)
         });
     return err;
 }
+
+int v9fs_co_open2(V9fsState *s, V9fsFidState *fidp, char *fullname, gid_t gid,
+                  int flags, int mode)
+{
+    int err;
+    FsCred cred;
+
+    cred_init(&cred);
+    cred.fc_mode = mode & 07777;
+    cred.fc_uid = fidp->uid;
+    cred.fc_gid = gid;
+    v9fs_co_run_in_worker(
+        {
+            fidp->fs.fd = s->ops->open2(&s->ctx, fullname, flags, &cred);
+            err = 0;
+            if (fidp->fs.fd == -1) {
+                err = -errno;
+            }
+        });
+    return err;
+}
diff --git a/hw/9pfs/virtio-9p-coth.h b/hw/9pfs/virtio-9p-coth.h
index 1df7063..f9610b9 100644
--- a/hw/9pfs/virtio-9p-coth.h
+++ b/hw/9pfs/virtio-9p-coth.h
@@ -79,4 +79,5 @@ extern int v9fs_co_rename(V9fsState *, V9fsString *, V9fsString *);
 extern int v9fs_co_fstat(V9fsState *, int, struct stat *);
 extern int v9fs_co_opendir(V9fsState *, V9fsFidState *);
 extern int v9fs_co_open(V9fsState *, V9fsFidState *, int);
+extern int v9fs_co_open2(V9fsState *, V9fsFidState *, char *, gid_t, int, int);
 #endif
commit 857bc158d4d2d271db5b0df8e9f6d90395a42cb4
Author: Aneesh Kumar K.V <aneesh.kumar at linux.vnet.ibm.com>
Date:   Sat May 7 17:36:36 2011 +0530

    hw/9pfs: Update v9fs_open to use coroutines
    
    Signed-off-by: Aneesh Kumar K.V <aneesh.kumar at linux.vnet.ibm.com>

diff --git a/hw/9pfs/virtio-9p.c b/hw/9pfs/virtio-9p.c
index 10312c9..c0fa0f4 100644
--- a/hw/9pfs/virtio-9p.c
+++ b/hw/9pfs/virtio-9p.c
@@ -92,11 +92,6 @@ static int v9fs_do_closedir(V9fsState *s, DIR *dir)
     return s->ops->closedir(&s->ctx, dir);
 }
 
-static int v9fs_do_open(V9fsState *s, V9fsString *path, int flags)
-{
-    return s->ops->open(&s->ctx, path->data, flags);
-}
-
 static DIR *v9fs_do_opendir(V9fsState *s, V9fsString *path)
 {
     return s->ops->opendir(&s->ctx, path->data);
@@ -210,11 +205,6 @@ static int v9fs_do_fsync(V9fsState *s, int fd, int datasync)
     return s->ops->fsync(&s->ctx, fd, datasync);
 }
 
-static int v9fs_do_statfs(V9fsState *s, V9fsString *path, struct statfs *stbuf)
-{
-    return s->ops->statfs(&s->ctx, path->data, stbuf);
-}
-
 static int v9fs_do_lsetxattr(V9fsState *s, V9fsString *path,
                              V9fsString *xattr_name,
                              void *value, size_t size, int flags)
@@ -1546,122 +1536,75 @@ static int32_t get_iounit(V9fsState *s, V9fsString *name)
      * iounit should be multiples of f_bsize (host filesystem block size
      * and as well as less than (client msize - P9_IOHDRSZ))
      */
-    if (!v9fs_do_statfs(s, name, &stbuf)) {
+    if (!v9fs_co_statfs(s, name, &stbuf)) {
         iounit = stbuf.f_bsize;
         iounit *= (s->msize - P9_IOHDRSZ)/stbuf.f_bsize;
     }
-
     if (!iounit) {
         iounit = s->msize - P9_IOHDRSZ;
     }
     return iounit;
 }
 
-static void v9fs_open_post_opendir(V9fsState *s, V9fsOpenState *vs, int err)
-{
-    if (vs->fidp->fs.dir == NULL) {
-        err = -errno;
-        goto out;
-    }
-    vs->fidp->fid_type = P9_FID_DIR;
-    vs->offset += pdu_marshal(vs->pdu, vs->offset, "Qd", &vs->qid, 0);
-    err = vs->offset;
-out:
-    complete_pdu(s, vs->pdu, err);
-    g_free(vs);
-
-}
-
-static void v9fs_open_post_getiounit(V9fsState *s, V9fsOpenState *vs)
+static void v9fs_open(void *opaque)
 {
-    int err;
-    vs->offset += pdu_marshal(vs->pdu, vs->offset, "Qd", &vs->qid, vs->iounit);
-    err = vs->offset;
-    complete_pdu(s, vs->pdu, err);
-    g_free(vs);
-}
+    int flags;
+    int iounit;
+    int32_t fid;
+    int32_t mode;
+    V9fsQID qid;
+    ssize_t err = 0;
+    size_t offset = 7;
+    struct stat stbuf;
+    V9fsFidState *fidp;
+    V9fsPDU *pdu = opaque;
+    V9fsState *s = pdu->s;
 
-static void v9fs_open_post_open(V9fsState *s, V9fsOpenState *vs, int err)
-{
-    if (vs->fidp->fs.fd == -1) {
-        err = -errno;
+    if (s->proto_version == V9FS_PROTO_2000L) {
+        pdu_unmarshal(pdu, offset, "dd", &fid, &mode);
+    } else {
+        pdu_unmarshal(pdu, offset, "db", &fid, &mode);
+    }
+    fidp = lookup_fid(s, fid);
+    if (fidp == NULL) {
+        err = -ENOENT;
         goto out;
     }
-    vs->fidp->fid_type = P9_FID_FILE;
-    vs->iounit = get_iounit(s, &vs->fidp->path);
-    v9fs_open_post_getiounit(s, vs);
-    return;
-out:
-    complete_pdu(s, vs->pdu, err);
-    g_free(vs);
-}
-
-static void v9fs_open_post_lstat(V9fsState *s, V9fsOpenState *vs, int err)
-{
-    int flags;
+    BUG_ON(fidp->fid_type != P9_FID_NONE);
 
-    if (err) {
-        err = -errno;
+    err = v9fs_co_lstat(s, &fidp->path, &stbuf);
+    if (err < 0) {
         goto out;
     }
-
-    stat_to_qid(&vs->stbuf, &vs->qid);
-
-    if (S_ISDIR(vs->stbuf.st_mode)) {
-        vs->fidp->fs.dir = v9fs_do_opendir(s, &vs->fidp->path);
-        v9fs_open_post_opendir(s, vs, err);
+    stat_to_qid(&stbuf, &qid);
+    if (S_ISDIR(stbuf.st_mode)) {
+        err = v9fs_co_opendir(s, fidp);
+        if (err < 0) {
+            goto out;
+        }
+        fidp->fid_type = P9_FID_DIR;
+        offset += pdu_marshal(pdu, offset, "Qd", &qid, 0);
+        err = offset;
     } else {
         if (s->proto_version == V9FS_PROTO_2000L) {
-            flags = vs->mode;
+            flags = mode;
             flags &= ~(O_NOCTTY | O_ASYNC | O_CREAT);
             /* Ignore direct disk access hint until the server supports it. */
             flags &= ~O_DIRECT;
         } else {
-            flags = omode_to_uflags(vs->mode);
+            flags = omode_to_uflags(mode);
         }
-        vs->fidp->fs.fd = v9fs_do_open(s, &vs->fidp->path, flags);
-        v9fs_open_post_open(s, vs, err);
-    }
-    return;
-out:
-    complete_pdu(s, vs->pdu, err);
-    g_free(vs);
-}
-
-static void v9fs_open(void *opaque)
-{
-    V9fsPDU *pdu = opaque;
-    V9fsState *s = pdu->s;
-    int32_t fid;
-    V9fsOpenState *vs;
-    ssize_t err = 0;
-
-    vs = g_malloc(sizeof(*vs));
-    vs->pdu = pdu;
-    vs->offset = 7;
-    vs->mode = 0;
-
-    if (s->proto_version == V9FS_PROTO_2000L) {
-        pdu_unmarshal(vs->pdu, vs->offset, "dd", &fid, &vs->mode);
-    } else {
-        pdu_unmarshal(vs->pdu, vs->offset, "db", &fid, &vs->mode);
-    }
-
-    vs->fidp = lookup_fid(s, fid);
-    if (vs->fidp == NULL) {
-        err = -ENOENT;
-        goto out;
+        err = v9fs_co_open(s, fidp, flags);
+        if (err < 0) {
+            goto out;
+        }
+        fidp->fid_type = P9_FID_FILE;
+        iounit = get_iounit(s, &fidp->path);
+        offset += pdu_marshal(pdu, offset, "Qd", &qid, iounit);
+        err = offset;
     }
-
-    BUG_ON(vs->fidp->fid_type != P9_FID_NONE);
-
-    err = v9fs_do_lstat(s, &vs->fidp->path, &vs->stbuf);
-
-    v9fs_open_post_lstat(s, vs, err);
-    return;
 out:
     complete_pdu(s, pdu, err);
-    g_free(vs);
 }
 
 static void v9fs_post_lcreate(V9fsState *s, V9fsLcreateState *vs, int err)
commit f6b7f0ab5c891203b7f706ad21dcec6023bb188c
Author: Aneesh Kumar K.V <aneesh.kumar at linux.vnet.ibm.com>
Date:   Sat May 7 18:12:42 2011 +0530

    hw/9pfs: Add yield support for open and opendir coroutine
    
    Signed-off-by: Aneesh Kumar K.V <aneesh.kumar at linux.vnet.ibm.com>

diff --git a/hw/9pfs/codir.c b/hw/9pfs/codir.c
index 28f2ad7..bc6a105 100644
--- a/hw/9pfs/codir.c
+++ b/hw/9pfs/codir.c
@@ -83,3 +83,19 @@ int v9fs_co_mkdir(V9fsState *s, char *name, mode_t mode, uid_t uid, gid_t gid)
         });
     return err;
 }
+
+int v9fs_co_opendir(V9fsState *s, V9fsFidState *fidp)
+{
+    int err;
+
+    v9fs_co_run_in_worker(
+        {
+            fidp->fs.dir = s->ops->opendir(&s->ctx, fidp->path.data);
+            if (!fidp->fs.dir) {
+                err = -errno;
+            } else {
+                err = 0;
+            }
+        });
+    return err;
+}
diff --git a/hw/9pfs/cofile.c b/hw/9pfs/cofile.c
index e400b86..4a3ca21 100644
--- a/hw/9pfs/cofile.c
+++ b/hw/9pfs/cofile.c
@@ -44,3 +44,19 @@ int v9fs_co_fstat(V9fsState *s, int fd, struct stat *stbuf)
         });
     return err;
 }
+
+int v9fs_co_open(V9fsState *s, V9fsFidState *fidp, int flags)
+{
+    int err;
+
+    v9fs_co_run_in_worker(
+        {
+            fidp->fs.fd = s->ops->open(&s->ctx, fidp->path.data, flags);
+            if (fidp->fs.fd == -1) {
+                err = -errno;
+            } else {
+                err = 0;
+            }
+        });
+    return err;
+}
diff --git a/hw/9pfs/virtio-9p-coth.h b/hw/9pfs/virtio-9p-coth.h
index 88070d3..1df7063 100644
--- a/hw/9pfs/virtio-9p-coth.h
+++ b/hw/9pfs/virtio-9p-coth.h
@@ -77,4 +77,6 @@ extern int v9fs_co_mkdir(V9fsState *, char *, mode_t, uid_t, gid_t);
 extern int v9fs_co_remove(V9fsState *, V9fsString *);
 extern int v9fs_co_rename(V9fsState *, V9fsString *, V9fsString *);
 extern int v9fs_co_fstat(V9fsState *, int, struct stat *);
+extern int v9fs_co_opendir(V9fsState *, V9fsFidState *);
+extern int v9fs_co_open(V9fsState *, V9fsFidState *, int);
 #endif
commit e4e414a427e0d7ff799e1b3ae9413c82f99b923f
Author: Aneesh Kumar K.V <aneesh.kumar at linux.vnet.ibm.com>
Date:   Sat May 7 17:21:38 2011 +0530

    hw/9pfs: Update v9fs_getlock to use coroutines
    
    Signed-off-by: Aneesh Kumar K.V <aneesh.kumar at linux.vnet.ibm.com>

diff --git a/hw/9pfs/virtio-9p.c b/hw/9pfs/virtio-9p.c
index 13e7c30..10312c9 100644
--- a/hw/9pfs/virtio-9p.c
+++ b/hw/9pfs/virtio-9p.c
@@ -3049,42 +3049,38 @@ out:
  * When a TGETLOCK request comes, always return success because all lock
  * handling is done by client's VFS layer.
  */
-
 static void v9fs_getlock(void *opaque)
 {
+    size_t offset = 7;
+    struct stat stbuf;
+    V9fsFidState *fidp;
+    V9fsGetlock *glock;
+    int32_t fid, err = 0;
     V9fsPDU *pdu = opaque;
     V9fsState *s = pdu->s;
-    int32_t fid, err = 0;
-    V9fsGetlockState *vs;
 
-    vs = g_malloc0(sizeof(*vs));
-    vs->pdu = pdu;
-    vs->offset = 7;
-
-    vs->glock = g_malloc(sizeof(*vs->glock));
-    pdu_unmarshal(vs->pdu, vs->offset, "dbqqds", &fid, &vs->glock->type,
-                &vs->glock->start, &vs->glock->length, &vs->glock->proc_id,
-		&vs->glock->client_id);
+    glock = g_malloc(sizeof(*glock));
+    pdu_unmarshal(pdu, offset, "dbqqds", &fid, &glock->type,
+                  &glock->start, &glock->length, &glock->proc_id,
+                  &glock->client_id);
 
-    vs->fidp = lookup_fid(s, fid);
-    if (vs->fidp == NULL) {
+    fidp = lookup_fid(s, fid);
+    if (fidp == NULL) {
         err = -ENOENT;
         goto out;
     }
-
-    err = v9fs_do_fstat(s, vs->fidp->fs.fd, &vs->stbuf);
+    err = v9fs_co_fstat(s, fidp->fs.fd, &stbuf);
     if (err < 0) {
-        err = -errno;
         goto out;
     }
-    vs->glock->type = F_UNLCK;
-    vs->offset += pdu_marshal(vs->pdu, vs->offset, "bqqds", vs->glock->type,
-                vs->glock->start, vs->glock->length, vs->glock->proc_id,
-		&vs->glock->client_id);
+    glock->type = F_UNLCK;
+    offset += pdu_marshal(pdu, offset, "bqqds", glock->type,
+                          glock->start, glock->length, glock->proc_id,
+                          &glock->client_id);
+    err = offset;
 out:
-    complete_pdu(s, vs->pdu, err);
-    g_free(vs->glock);
-    g_free(vs);
+    complete_pdu(s, pdu, err);
+    g_free(glock);
 }
 
 static void v9fs_mkdir(void *opaque)
diff --git a/hw/9pfs/virtio-9p.h b/hw/9pfs/virtio-9p.h
index 0c1e3ee..edf3413 100644
--- a/hw/9pfs/virtio-9p.h
+++ b/hw/9pfs/virtio-9p.h
@@ -412,15 +412,6 @@ typedef struct V9fsGetlock
     V9fsString client_id;
 } V9fsGetlock;
 
-typedef struct V9fsGetlockState
-{
-    V9fsPDU *pdu;
-    size_t offset;
-    struct stat stbuf;
-    V9fsFidState *fidp;
-    V9fsGetlock *glock;
-} V9fsGetlockState;
-
 size_t pdu_packunpack(void *addr, struct iovec *sg, int sg_count,
                       size_t offset, size_t size, int pack);
 
commit 0c27bf2a45d8b25119f65890d78a71415fbb0911
Author: Aneesh Kumar K.V <aneesh.kumar at linux.vnet.ibm.com>
Date:   Mon Aug 22 09:14:04 2011 +0530

    hw/9pfs: Update v9fs_lock to use coroutines
    
    Signed-off-by: Aneesh Kumar K.V <aneesh.kumar at linux.vnet.ibm.com>

diff --git a/hw/9pfs/virtio-9p.c b/hw/9pfs/virtio-9p.c
index eb33636..13e7c30 100644
--- a/hw/9pfs/virtio-9p.c
+++ b/hw/9pfs/virtio-9p.c
@@ -3006,47 +3006,43 @@ out:
  * do any thing in * qemu 9p server side lock code path.
  * So when a TLOCK request comes, always return success
  */
-
 static void v9fs_lock(void *opaque)
 {
+    int8_t status;
+    V9fsFlock *flock;
+    size_t offset = 7;
+    struct stat stbuf;
+    V9fsFidState *fidp;
+    int32_t fid, err = 0;
     V9fsPDU *pdu = opaque;
     V9fsState *s = pdu->s;
-    int32_t fid, err = 0;
-    V9fsLockState *vs;
-
-    vs = g_malloc0(sizeof(*vs));
-    vs->pdu = pdu;
-    vs->offset = 7;
-
-    vs->flock = g_malloc(sizeof(*vs->flock));
-    pdu_unmarshal(vs->pdu, vs->offset, "dbdqqds", &fid, &vs->flock->type,
-                &vs->flock->flags, &vs->flock->start, &vs->flock->length,
-                            &vs->flock->proc_id, &vs->flock->client_id);
 
-    vs->status = P9_LOCK_ERROR;
+    flock = g_malloc(sizeof(*flock));
+    pdu_unmarshal(pdu, offset, "dbdqqds", &fid, &flock->type,
+                  &flock->flags, &flock->start, &flock->length,
+                  &flock->proc_id, &flock->client_id);
+    status = P9_LOCK_ERROR;
 
     /* We support only block flag now (that too ignored currently) */
-    if (vs->flock->flags & ~P9_LOCK_FLAGS_BLOCK) {
+    if (flock->flags & ~P9_LOCK_FLAGS_BLOCK) {
         err = -EINVAL;
         goto out;
     }
-    vs->fidp = lookup_fid(s, fid);
-    if (vs->fidp == NULL) {
+    fidp = lookup_fid(s, fid);
+    if (fidp == NULL) {
         err = -ENOENT;
         goto out;
     }
-
-    err = v9fs_do_fstat(s, vs->fidp->fs.fd, &vs->stbuf);
+    err = v9fs_co_fstat(s, fidp->fs.fd, &stbuf);
     if (err < 0) {
-        err = -errno;
         goto out;
     }
-    vs->status = P9_LOCK_SUCCESS;
+    status = P9_LOCK_SUCCESS;
 out:
-    vs->offset += pdu_marshal(vs->pdu, vs->offset, "b", vs->status);
-    complete_pdu(s, vs->pdu, err);
-    g_free(vs->flock);
-    g_free(vs);
+    err = offset;
+    err += pdu_marshal(pdu, offset, "b", status);
+    complete_pdu(s, pdu, err);
+    g_free(flock);
 }
 
 /*
diff --git a/hw/9pfs/virtio-9p.h b/hw/9pfs/virtio-9p.h
index 46d79da..0c1e3ee 100644
--- a/hw/9pfs/virtio-9p.h
+++ b/hw/9pfs/virtio-9p.h
@@ -403,16 +403,6 @@ typedef struct V9fsFlock
     V9fsString client_id;
 } V9fsFlock;
 
-typedef struct V9fsLockState
-{
-    V9fsPDU *pdu;
-    size_t offset;
-    int8_t status;
-    struct stat stbuf;
-    V9fsFidState *fidp;
-    V9fsFlock *flock;
-} V9fsLockState;
-
 typedef struct V9fsGetlock
 {
     uint8_t type;
commit 03feb1e1724949d94d4e442f865392320139162c
Author: Aneesh Kumar K.V <aneesh.kumar at linux.vnet.ibm.com>
Date:   Mon Aug 22 09:14:04 2011 +0530

    hw/9pfs: Add yeild support for fstat coroutine
    
    Signed-off-by: Aneesh Kumar K.V <aneesh.kumar at linux.vnet.ibm.com>

diff --git a/hw/9pfs/cofile.c b/hw/9pfs/cofile.c
index a4c0ae7..e400b86 100644
--- a/hw/9pfs/cofile.c
+++ b/hw/9pfs/cofile.c
@@ -30,3 +30,17 @@ int v9fs_co_lstat(V9fsState *s, V9fsString *path, struct stat *stbuf)
         });
     return err;
 }
+
+int v9fs_co_fstat(V9fsState *s, int fd, struct stat *stbuf)
+{
+    int err;
+
+    v9fs_co_run_in_worker(
+        {
+            err = s->ops->fstat(&s->ctx, fd, stbuf);
+            if (err < 0) {
+                err = -errno;
+            }
+        });
+    return err;
+}
diff --git a/hw/9pfs/virtio-9p-coth.h b/hw/9pfs/virtio-9p-coth.h
index 11272d3..88070d3 100644
--- a/hw/9pfs/virtio-9p-coth.h
+++ b/hw/9pfs/virtio-9p-coth.h
@@ -76,4 +76,5 @@ extern int v9fs_co_mknod(V9fsState *, V9fsString *, uid_t,
 extern int v9fs_co_mkdir(V9fsState *, char *, mode_t, uid_t, gid_t);
 extern int v9fs_co_remove(V9fsState *, V9fsString *);
 extern int v9fs_co_rename(V9fsState *, V9fsString *, V9fsString *);
+extern int v9fs_co_fstat(V9fsState *, int, struct stat *);
 #endif
commit f1a7104a5f435a1bf2a1158e6f737dbd89e8c153
Merge: 957f1f9... dc804ab...
Author: Anthony Liguori <aliguori at us.ibm.com>
Date:   Sun Aug 21 18:34:33 2011 -0500

    Merge remote-tracking branch 'pmaydell/armhw-for-upstream' into staging

commit 957f1f99f263d57612807a9535f75ca4473f05f0
Author: Michael Roth <mdroth at linux.vnet.ibm.com>
Date:   Thu Aug 11 15:38:12 2011 -0500

    guest agent: remove uneeded dependencies
    
    This patch tries to cull any uneeded library dependencies from the guest
    agent to improve portability across various distros. We do so by being
    as explicit as possible about in-tree dependencies rather than relying
    on existing *-obj-y targets, and by manually setting LIBS for the
    qemu-ga target to avoid pulling in LIBS_TOOLS libraries discovered by
    configure.
    
    Signed-off-by: Michael Roth <mdroth at linux.vnet.ibm.com>
    Signed-off-by: Anthony Liguori <aliguori at us.ibm.com>

diff --git a/Makefile b/Makefile
index eb3e338..8606849 100644
--- a/Makefile
+++ b/Makefile
@@ -166,6 +166,7 @@ test-coroutine: test-coroutine.o qemu-timer-common.o async.o $(coroutine-obj-y)
 $(qapi-obj-y): $(GENERATED_HEADERS)
 qapi-dir := qapi-generated
 test-visitor.o test-qmp-commands.o qemu-ga$(EXESUF): QEMU_CFLAGS += -I $(qapi-dir)
+qemu-ga$(EXESUF): LIBS = $(LIBS_QGA)
 
 $(qapi-dir)/test-qapi-types.c: $(qapi-dir)/test-qapi-types.h
 $(qapi-dir)/test-qapi-types.h: $(SRC_PATH)/qapi-schema-test.json $(SRC_PATH)/scripts/qapi-types.py
@@ -192,12 +193,11 @@ test-visitor: test-visitor.o qfloat.o qint.o qdict.o qstring.o qlist.o qbool.o $
 test-qmp-commands.o: $(addprefix $(qapi-dir)/, test-qapi-types.c test-qapi-types.h test-qapi-visit.c test-qapi-visit.h test-qmp-marshal.c test-qmp-commands.h) $(qapi-obj-y)
 test-qmp-commands: test-qmp-commands.o qfloat.o qint.o qdict.o qstring.o qlist.o qbool.o $(qapi-obj-y) error.o osdep.o $(oslib-obj-y) qjson.o json-streamer.o json-lexer.o json-parser.o qerror.o qemu-error.o qemu-tool.o $(qapi-dir)/test-qapi-visit.o $(qapi-dir)/test-qapi-types.o $(qapi-dir)/test-qmp-marshal.o module.o
 
-QGALIB=qga/guest-agent-command-state.o qga/guest-agent-commands.o
 QGALIB_GEN=$(addprefix $(qapi-dir)/, qga-qapi-types.c qga-qapi-types.h qga-qapi-visit.c qga-qmp-marshal.c)
-
 $(QGALIB_GEN): $(GENERATED_HEADERS)
-$(QGALIB) qemu-ga.o: $(QGALIB_GEN) $(qapi-obj-y)
-qemu-ga$(EXESUF): qemu-ga.o $(QGALIB) qemu-tool.o qemu-error.o error.o $(oslib-obj-y) $(trace-obj-y) $(block-obj-y) $(qobject-obj-y) $(version-obj-y) $(qapi-obj-y) qemu-timer-common.o qemu-sockets.o module.o qapi/qmp-dispatch.o qapi/qmp-registry.o $(qapi-dir)/qga-qapi-visit.o $(qapi-dir)/qga-qapi-types.o $(qapi-dir)/qga-qmp-marshal.o
+$(qga-obj-y) qemu-ga.o: $(QGALIB_GEN)
+
+qemu-ga$(EXESUF): qemu-ga.o $(qga-obj-y) $(qapi-obj-y) $(trace-obj-y) $(qobject-obj-y) $(version-obj-y) $(addprefix $(qapi-dir)/, qga-qapi-visit.o qga-qapi-types.o qga-qmp-marshal.o)
 
 QEMULIBS=libhw32 libhw64 libuser libdis libdis-user
 
diff --git a/Makefile.objs b/Makefile.objs
index 91b71b6..abd867a 100644
--- a/Makefile.objs
+++ b/Makefile.objs
@@ -396,6 +396,15 @@ qapi-nested-y = qapi-visit-core.o qmp-input-visitor.o qmp-output-visitor.o qapi-
 qapi-nested-y += qmp-registry.o qmp-dispatch.o
 qapi-obj-y = $(addprefix qapi/, $(qapi-nested-y))
 
+######################################################################
+# guest agent
+
+qga-nested-y = guest-agent-commands.o guest-agent-command-state.o
+qga-obj-y = $(addprefix qga/, $(qga-nested-y))
+qga-obj-y += qemu-ga.o qemu-tool.o qemu-error.o qemu-sockets.o module.o qemu-option.o cutils.o osdep.o
+qga-obj-$(CONFIG_WIN32) += oslib-win32.o
+qga-obj-$(CONFIG_POSIX) += oslib-posix.o
+
 vl.o: QEMU_CFLAGS+=$(GPROF_CFLAGS)
 
 vl.o: QEMU_CFLAGS+=$(SDL_CFLAGS)
diff --git a/configure b/configure
index 8513875..234a4c5 100755
--- a/configure
+++ b/configure
@@ -92,6 +92,7 @@ libs_tools=""
 audio_pt_int=""
 audio_win_int=""
 cc_i386=i386-pc-linux-gnu-gcc
+libs_qga=""
 
 target_list=""
 
@@ -1849,6 +1850,7 @@ if $pkg_config --modversion 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`
     LIBS="$glib_libs $LIBS"
+    libs_qga="$glib_libs $libs_qga"
 else
     echo "glib-2.0 required to compile QEMU"
     exit 1
@@ -3107,6 +3109,7 @@ echo "ARLIBS_END=$arlibs_end" >> $config_host_mak
 echo "LIBS+=$LIBS" >> $config_host_mak
 echo "LIBS_TOOLS+=$libs_tools" >> $config_host_mak
 echo "EXESUF=$EXESUF" >> $config_host_mak
+echo "LIBS_QGA+=$libs_qga" >> $config_host_mak
 
 # generate list of library paths for linker script
 
commit 8f4774789947bc4bc4c8d026a289fe980d3d2ee1
Author: Michael Roth <mdroth at linux.vnet.ibm.com>
Date:   Thu Aug 11 15:38:11 2011 -0500

    guest agent: remove g_strcmp0 usage
    
    g_strcmp0 isn't in all version of glib 2.0, so don't use it to avoid
    build breakage on older distros.
    
    Signed-off-by: Michael Roth <mdroth at linux.vnet.ibm.com>
    Signed-off-by: Michael Roth <mdroth at linux.vnet.ibm.com>
    Signed-off-by: Anthony Liguori <aliguori at us.ibm.com>

diff --git a/qemu-ga.c b/qemu-ga.c
index eb632b7..858d75a 100644
--- a/qemu-ga.c
+++ b/qemu-ga.c
@@ -146,7 +146,7 @@ static void ga_log(const gchar *domain, GLogLevelFlags level,
     }
 
     level &= G_LOG_LEVEL_MASK;
-    if (g_strcmp0(domain, "syslog") == 0) {
+    if (domain && strcmp(domain, "syslog") == 0) {
         syslog(LOG_INFO, "%s: %s", level_str, msg);
     } else if (level & s->log_level) {
         g_get_current_time(&time);
commit 3a130f4ef07f4532500473aeab43c86a3c2991c8
Author: Avi Kivity <avi at redhat.com>
Date:   Thu Aug 11 10:40:26 2011 +0300

    memory: crack wide ioport accesses into smaller ones when needed
    
    The memory API supports cracking wide accesses into narrower ones
    when needed; but this was no implemented for the pio address space,
    causing lsi53c895a's IO BAR to malfunction.
    
    Fix by correctly cracking wide accesses when needed.
    
    Signed-off-by: Avi Kivity <avi at redhat.com>
    Signed-off-by: Anthony Liguori <aliguori at us.ibm.com>

diff --git a/memory.c b/memory.c
index 8e6dd35..30ba4a4 100644
--- a/memory.c
+++ b/memory.c
@@ -400,7 +400,11 @@ static void memory_region_iorange_read(IORange *iorange,
         }
         return;
     }
-    *data = mr->ops->read(mr->opaque, offset, width);
+    *data = 0;
+    access_with_adjusted_size(offset, data, width,
+                              mr->ops->impl.min_access_size,
+                              mr->ops->impl.max_access_size,
+                              memory_region_read_accessor, mr);
 }
 
 static void memory_region_iorange_write(IORange *iorange,
@@ -418,7 +422,10 @@ static void memory_region_iorange_write(IORange *iorange,
         }
         return;
     }
-    mr->ops->write(mr->opaque, offset, data, width);
+    access_with_adjusted_size(offset, &data, width,
+                              mr->ops->impl.min_access_size,
+                              mr->ops->impl.max_access_size,
+                              memory_region_write_accessor, mr);
 }
 
 static const IORangeOps memory_region_iorange_ops = {
commit 164a4dcd8d90a0db5ffa2174f693195744374418
Author: Avi Kivity <avi at redhat.com>
Date:   Thu Aug 11 10:40:25 2011 +0300

    memory: abstract cracking of write access ops into a function
    
    The memory API automatically cracks large reads and writes into smaller
    ones when needed.  Factor out this mechanism, which is now duplicated between
    memory reads and memory writes, into a function.
    
    Signed-off-by: Avi Kivity <avi at redhat.com>
    Signed-off-by: Anthony Liguori <aliguori at us.ibm.com>

diff --git a/memory.c b/memory.c
index 24439f3..8e6dd35 100644
--- a/memory.c
+++ b/memory.c
@@ -226,6 +226,65 @@ static void flatview_simplify(FlatView *view)
     }
 }
 
+static void memory_region_read_accessor(void *opaque,
+                                        target_phys_addr_t addr,
+                                        uint64_t *value,
+                                        unsigned size,
+                                        unsigned shift,
+                                        uint64_t mask)
+{
+    MemoryRegion *mr = opaque;
+    uint64_t tmp;
+
+    tmp = mr->ops->read(mr->opaque, addr, size);
+    *value |= (tmp & mask) << shift;
+}
+
+static void memory_region_write_accessor(void *opaque,
+                                         target_phys_addr_t addr,
+                                         uint64_t *value,
+                                         unsigned size,
+                                         unsigned shift,
+                                         uint64_t mask)
+{
+    MemoryRegion *mr = opaque;
+    uint64_t tmp;
+
+    tmp = (*value >> shift) & mask;
+    mr->ops->write(mr->opaque, addr, tmp, size);
+}
+
+static void access_with_adjusted_size(target_phys_addr_t addr,
+                                      uint64_t *value,
+                                      unsigned size,
+                                      unsigned access_size_min,
+                                      unsigned access_size_max,
+                                      void (*access)(void *opaque,
+                                                     target_phys_addr_t addr,
+                                                     uint64_t *value,
+                                                     unsigned size,
+                                                     unsigned shift,
+                                                     uint64_t mask),
+                                      void *opaque)
+{
+    uint64_t access_mask;
+    unsigned access_size;
+    unsigned i;
+
+    if (!access_size_min) {
+        access_size_min = 1;
+    }
+    if (!access_size_max) {
+        access_size_max = 4;
+    }
+    access_size = MAX(MIN(size, access_size_max), access_size_min);
+    access_mask = -1ULL >> (64 - access_size * 8);
+    for (i = 0; i < size; i += access_size) {
+        /* FIXME: big-endian support */
+        access(opaque, addr + i, value, access_size, i * 8, access_mask);
+    }
+}
+
 static void memory_region_prepare_ram_addr(MemoryRegion *mr);
 
 static void as_memory_range_add(AddressSpace *as, FlatRange *fr)
@@ -744,10 +803,7 @@ static uint32_t memory_region_read_thunk_n(void *_mr,
                                            unsigned size)
 {
     MemoryRegion *mr = _mr;
-    unsigned access_size, access_size_min, access_size_max;
-    uint64_t access_mask;
-    uint32_t data = 0, tmp;
-    unsigned i;
+    uint64_t data = 0;
 
     if (!memory_region_access_valid(mr, addr, size)) {
         return -1U; /* FIXME: better signalling */
@@ -758,23 +814,10 @@ static uint32_t memory_region_read_thunk_n(void *_mr,
     }
 
     /* FIXME: support unaligned access */
-
-    access_size_min = mr->ops->impl.min_access_size;
-    if (!access_size_min) {
-        access_size_min = 1;
-    }
-    access_size_max = mr->ops->impl.max_access_size;
-    if (!access_size_max) {
-        access_size_max = 4;
-    }
-    access_size = MAX(MIN(size, access_size_max), access_size_min);
-    access_mask = -1ULL >> (64 - access_size * 8);
-    addr += mr->offset;
-    for (i = 0; i < size; i += access_size) {
-        /* FIXME: big-endian support */
-        tmp = mr->ops->read(mr->opaque, addr + i, access_size);
-        data |= (tmp & access_mask) << (i * 8);
-    }
+    access_with_adjusted_size(addr + mr->offset, &data, size,
+                              mr->ops->impl.min_access_size,
+                              mr->ops->impl.max_access_size,
+                              memory_region_read_accessor, mr);
 
     return data;
 }
@@ -785,9 +828,6 @@ static void memory_region_write_thunk_n(void *_mr,
                                         uint64_t data)
 {
     MemoryRegion *mr = _mr;
-    unsigned access_size, access_size_min, access_size_max;
-    uint64_t access_mask;
-    unsigned i;
 
     if (!memory_region_access_valid(mr, addr, size)) {
         return; /* FIXME: better signalling */
@@ -799,23 +839,10 @@ static void memory_region_write_thunk_n(void *_mr,
     }
 
     /* FIXME: support unaligned access */
-
-    access_size_min = mr->ops->impl.min_access_size;
-    if (!access_size_min) {
-        access_size_min = 1;
-    }
-    access_size_max = mr->ops->impl.max_access_size;
-    if (!access_size_max) {
-        access_size_max = 4;
-    }
-    access_size = MAX(MIN(size, access_size_max), access_size_min);
-    access_mask = -1ULL >> (64 - access_size * 8);
-    addr += mr->offset;
-    for (i = 0; i < size; i += access_size) {
-        /* FIXME: big-endian support */
-        mr->ops->write(mr->opaque, addr + i, (data >> (i * 8)) & access_mask,
-                       access_size);
-    }
+    access_with_adjusted_size(addr + mr->offset, &data, size,
+                              mr->ops->impl.min_access_size,
+                              mr->ops->impl.max_access_size,
+                              memory_region_write_accessor, mr);
 }
 
 static uint32_t memory_region_read_thunk_b(void *mr, target_phys_addr_t addr)
commit 30c2f2388ab083074b3ab0de8e7f87aed9c62c7a
Author: Blue Swirl <blauwirbel at gmail.com>
Date:   Sun Aug 7 11:01:05 2011 +0000

    escc: replace DPRINTFs with tracepoints
    
    Signed-off-by: Blue Swirl <blauwirbel at gmail.com>

diff --git a/hw/escc.c b/hw/escc.c
index ffcd746..76d94f3 100644
--- a/hw/escc.c
+++ b/hw/escc.c
@@ -27,15 +27,7 @@
 #include "escc.h"
 #include "qemu-char.h"
 #include "console.h"
-
-/* debug serial */
-//#define DEBUG_SERIAL
-
-/* debug keyboard */
-//#define DEBUG_KBD
-
-/* debug mouse */
-//#define DEBUG_MOUSE
+#include "trace.h"
 
 /*
  * Chipset docs:
@@ -69,25 +61,6 @@
  *  2010-May-23  Artyom Tarasenko:  Reworked IUS logic
  */
 
-#ifdef DEBUG_SERIAL
-#define SER_DPRINTF(fmt, ...)                                   \
-    do { printf("SER: " fmt , ## __VA_ARGS__); } while (0)
-#else
-#define SER_DPRINTF(fmt, ...)
-#endif
-#ifdef DEBUG_KBD
-#define KBD_DPRINTF(fmt, ...)                                   \
-    do { printf("KBD: " fmt , ## __VA_ARGS__); } while (0)
-#else
-#define KBD_DPRINTF(fmt, ...)
-#endif
-#ifdef DEBUG_MOUSE
-#define MS_DPRINTF(fmt, ...)                                    \
-    do { printf("MSC: " fmt , ## __VA_ARGS__); } while (0)
-#else
-#define MS_DPRINTF(fmt, ...)
-#endif
-
 typedef enum {
     chn_a, chn_b,
 } ChnID;
@@ -250,7 +223,7 @@ static void put_queue(void *opaque, int b)
     ChannelState *s = opaque;
     SERIOQueue *q = &s->queue;
 
-    SER_DPRINTF("channel %c put: 0x%02x\n", CHN_C(s), b);
+    trace_escc_put_queue(CHN_C(s), b);
     if (q->count >= SERIO_QUEUE_SIZE)
         return;
     q->data[q->wptr] = b;
@@ -274,7 +247,7 @@ static uint32_t get_queue(void *opaque)
             q->rptr = 0;
         q->count--;
     }
-    SER_DPRINTF("channel %c get 0x%02x\n", CHN_C(s), val);
+    trace_escc_get_queue(CHN_C(s), val);
     if (q->count > 0)
         serial_receive_byte(s, 0);
     return val;
@@ -301,7 +274,7 @@ static void escc_update_irq(ChannelState *s)
     irq = escc_update_irq_chn(s);
     irq |= escc_update_irq_chn(s->otherchn);
 
-    SER_DPRINTF("IRQ = %d\n", irq);
+    trace_escc_update_irq(irq);
     qemu_set_irq(s->irq, irq);
 }
 
@@ -486,8 +459,7 @@ static void escc_update_parameters(ChannelState *s)
     ssp.parity = parity;
     ssp.data_bits = data_bits;
     ssp.stop_bits = stop_bits;
-    SER_DPRINTF("channel %c: speed=%d parity=%c data=%d stop=%d\n", CHN_C(s),
-                speed, parity, data_bits, stop_bits);
+    trace_escc_update_parameters(CHN_C(s), speed, parity, data_bits, stop_bits);
     qemu_chr_ioctl(s->chr, CHR_IOCTL_SERIAL_SET_PARAMS, &ssp);
 }
 
@@ -505,8 +477,7 @@ static void escc_mem_write(void *opaque, target_phys_addr_t addr,
     s = &serial->chn[channel];
     switch (saddr) {
     case SERIAL_CTRL:
-        SER_DPRINTF("Write channel %c, reg[%d] = %2.2x\n", CHN_C(s), s->reg,
-                    val & 0xff);
+        trace_escc_mem_writeb_ctrl(CHN_C(s), s->reg, val & 0xff);
         newreg = 0;
         switch (s->reg) {
         case W_CMD:
@@ -576,7 +547,7 @@ static void escc_mem_write(void *opaque, target_phys_addr_t addr,
             s->reg = 0;
         break;
     case SERIAL_DATA:
-        SER_DPRINTF("Write channel %c, ch %d\n", CHN_C(s), val);
+        trace_escc_mem_writeb_data(CHN_C(s), val);
         s->tx = val;
         if (s->wregs[W_TXCTRL2] & TXCTRL2_TXEN) { // tx enabled
             if (s->chr)
@@ -608,8 +579,7 @@ static uint64_t escc_mem_read(void *opaque, target_phys_addr_t addr,
     s = &serial->chn[channel];
     switch (saddr) {
     case SERIAL_CTRL:
-        SER_DPRINTF("Read channel %c, reg[%d] = %2.2x\n", CHN_C(s), s->reg,
-                    s->rregs[s->reg]);
+        trace_escc_mem_readb_ctrl(CHN_C(s), s->reg, s->rregs[s->reg]);
         ret = s->rregs[s->reg];
         s->reg = 0;
         return ret;
@@ -620,7 +590,7 @@ static uint64_t escc_mem_read(void *opaque, target_phys_addr_t addr,
             ret = get_queue(s);
         else
             ret = s->rx;
-        SER_DPRINTF("Read channel %c, ch %d\n", CHN_C(s), ret);
+        trace_escc_mem_readb_data(CHN_C(s), ret);
         if (s->chr)
             qemu_chr_accept_input(s->chr);
         return ret;
@@ -656,7 +626,7 @@ static int serial_can_receive(void *opaque)
 
 static void serial_receive_byte(ChannelState *s, int ch)
 {
-    SER_DPRINTF("channel %c put ch %d\n", CHN_C(s), ch);
+    trace_escc_serial_receive_byte(CHN_C(s), ch);
     s->rregs[R_STATUS] |= STATUS_RXAV;
     s->rx = ch;
     set_rxint(s);
@@ -768,8 +738,7 @@ static void sunkbd_event(void *opaque, int ch)
     ChannelState *s = opaque;
     int release = ch & 0x80;
 
-    KBD_DPRINTF("Untranslated keycode %2.2x (%s)\n", ch, release? "release" :
-                "press");
+    trace_escc_sunkbd_event_in(ch);
     switch (ch) {
     case 58: // Caps lock press
         s->caps_lock_mode ^= 1;
@@ -803,13 +772,13 @@ static void sunkbd_event(void *opaque, int ch)
     } else {
         ch = keycodes[ch & 0x7f];
     }
-    KBD_DPRINTF("Translated keycode %2.2x\n", ch);
+    trace_escc_sunkbd_event_out(ch);
     put_queue(s, ch | release);
 }
 
 static void handle_kbd_command(ChannelState *s, int val)
 {
-    KBD_DPRINTF("Command %d\n", val);
+    trace_escc_kbd_command(val);
     if (s->led_mode) { // Ignore led byte
         s->led_mode = 0;
         return;
@@ -841,8 +810,7 @@ static void sunmouse_event(void *opaque,
     ChannelState *s = opaque;
     int ch;
 
-    MS_DPRINTF("dx=%d dy=%d buttons=%01x\n", dx, dy, buttons_state);
-
+    trace_escc_sunmouse_event(dx, dy, buttons_state);
     ch = 0x80 | 0x7; /* protocol start byte, no buttons pressed */
 
     if (buttons_state & MOUSE_EVENT_LBUTTON)
diff --git a/trace-events b/trace-events
index 246704c..14e6f8b 100644
--- a/trace-events
+++ b/trace-events
@@ -446,3 +446,18 @@ disable qemu_co_mutex_lock_entry(void *mutex, void *self) "mutex %p self %p"
 disable qemu_co_mutex_lock_return(void *mutex, void *self) "mutex %p self %p"
 disable qemu_co_mutex_unlock_entry(void *mutex, void *self) "mutex %p self %p"
 disable qemu_co_mutex_unlock_return(void *mutex, void *self) "mutex %p self %p"
+
+# hw/escc.c
+disable escc_put_queue(char channel, int b) "channel %c put: 0x%02x"
+disable escc_get_queue(char channel, int val) "channel %c get 0x%02x"
+disable escc_update_irq(int irq) "IRQ = %d"
+disable escc_update_parameters(char channel, int speed, int parity, int data_bits, int stop_bits) "channel %c: speed=%d parity=%c data=%d stop=%d"
+disable escc_mem_writeb_ctrl(char channel, uint32_t reg, uint32_t val) "Write channel %c, reg[%d] = %2.2x"
+disable escc_mem_writeb_data(char channel, uint32_t val) "Write channel %c, ch %d"
+disable escc_mem_readb_ctrl(char channel, uint32_t reg, uint8_t val) "Read channel %c, reg[%d] = %2.2x"
+disable escc_mem_readb_data(char channel, uint32_t ret) "Read channel %c, ch %d"
+disable escc_serial_receive_byte(char channel, int ch) "channel %c put ch %d"
+disable escc_sunkbd_event_in(int ch) "Untranslated keycode %2.2x"
+disable escc_sunkbd_event_out(int ch) "Translated keycode %2.2x"
+disable escc_kbd_command(int val) "Command %d"
+disable escc_sunmouse_event(int dx, int dy, int buttons_state) "dx=%d dy=%d buttons=%01x"
commit 42c812b98bbdb1d9e12b111f779a4cc6d987727d
Author: Blue Swirl <blauwirbel at gmail.com>
Date:   Sun Aug 7 20:02:02 2011 +0000

    m48t59: avoid structure holes spotted by pahole
    
    Report from pahole on amd64 host:
    struct M48t59State {
    	uint32_t                   type;                 /*     0     4 */
    
    	/* XXX 4 bytes hole, try to pack */
    
    	qemu_irq                   IRQ;                  /*     8     8 */
    	uint32_t                   io_base;              /*    16     4 */
    	uint32_t                   size;                 /*    20     4 */
    	time_t                     time_offset;          /*    24     8 */
    	time_t                     stop_time;            /*    32     8 */
    	struct tm                  alarm;                /*    40    56 */
    	/* --- cacheline 1 boundary (64 bytes) was 32 bytes ago --- */
    	struct QEMUTimer *         alrm_timer;           /*    96     8 */
    	struct QEMUTimer *         wd_timer;             /*   104     8 */
    	uint8_t                    lock;                 /*   112     1 */
    
    	/* XXX 1 byte hole, try to pack */
    
    	uint16_t                   addr;                 /*   114     2 */
    
    	/* XXX 4 bytes hole, try to pack */
    
    	uint8_t *                  buffer;               /*   120     8 */
    	/* --- cacheline 2 boundary (128 bytes) --- */
    
    	/* size: 128, cachelines: 2 */
    	/* sum members: 119, holes: 3, sum holes: 9 */
    };	/* definitions: 1 */
    
    Fix by rearranging the structure to avoid padding.
    
    Signed-off-by: Blue Swirl <blauwirbel at gmail.com>

diff --git a/hw/m48t59.c b/hw/m48t59.c
index 401b969..0cc361e 100644
--- a/hw/m48t59.c
+++ b/hw/m48t59.c
@@ -50,8 +50,6 @@
  */
 
 struct M48t59State {
-    /* Model parameters */
-    uint32_t type; // 2 = m48t02, 8 = m48t08, 59 = m48t59
     /* Hardware parameters */
     qemu_irq IRQ;
     uint32_t io_base;
@@ -64,9 +62,12 @@ struct M48t59State {
     struct QEMUTimer *alrm_timer;
     struct QEMUTimer *wd_timer;
     /* NVRAM storage */
-    uint8_t  lock;
-    uint16_t addr;
     uint8_t *buffer;
+    /* Model parameters */
+    uint32_t type; /* 2 = m48t02, 8 = m48t08, 59 = m48t59 */
+    /* NVRAM storage */
+    uint16_t addr;
+    uint8_t  lock;
 };
 
 typedef struct M48t59ISAState {
commit d7b9553489f896bbcdb47403edb92f0bfb02eeaa
Author: Blue Swirl <blauwirbel at gmail.com>
Date:   Sun Aug 7 19:55:23 2011 +0000

    escc: avoid structure holes spotted by pahole
    
    Edited report from pahole on amd64 host:
    struct ChannelState {
    ...
    	ChnType                    type;                 /*    32     4 */
    
    	/* XXX 4 bytes hole, try to pack */
    ...
    	uint8_t                    rregs[16];            /*    66    16 */
    
    	/* XXX 2 bytes hole, try to pack */
    ...
    	/* size: 392, cachelines: 7 */
    	/* sum members: 382, holes: 2, sum holes: 6 */
    	/* padding: 4 */
    	/* last cacheline: 8 bytes */
    };	/* definitions: 1 */
    
    Fix by rearranging the structure to avoid padding.
    
    Signed-off-by: Blue Swirl <blauwirbel at gmail.com>

diff --git a/hw/escc.c b/hw/escc.c
index bea5873..ffcd746 100644
--- a/hw/escc.c
+++ b/hw/escc.c
@@ -108,18 +108,19 @@ typedef struct {
 #define SERIAL_REGS 16
 typedef struct ChannelState {
     qemu_irq irq;
-    uint32_t reg;
     uint32_t rxint, txint, rxint_under_svc, txint_under_svc;
-    ChnID chn; // this channel, A (base+4) or B (base+0)
-    ChnType type;
     struct ChannelState *otherchn;
-    uint8_t rx, tx, wregs[SERIAL_REGS], rregs[SERIAL_REGS];
+    uint32_t reg;
+    uint8_t wregs[SERIAL_REGS], rregs[SERIAL_REGS];
     SERIOQueue queue;
     CharDriverState *chr;
     int e0_mode, led_mode, caps_lock_mode, num_lock_mode;
     int disabled;
     int clock;
     uint32_t vmstate_dummy;
+    ChnID chn; // this channel, A (base+4) or B (base+0)
+    ChnType type;
+    uint8_t rx, tx;
 } ChannelState;
 
 struct SerialState {
commit 242cca4fdfadafca39fa918e78fea6ef89d6decc
Author: Blue Swirl <blauwirbel at gmail.com>
Date:   Sun Aug 7 19:43:38 2011 +0000

    fdc: avoid structure holes spotted by pahole
    
    Edited report from pahole on amd64 host:
    struct FDCtrl {
    	uint8_t                    version;              /*     0     1 */
    
    	/* XXX 7 bytes hole, try to pack */
    
    	qemu_irq                   irq;                  /*     8     8 */
    	int                        dma_chann;            /*    16     4 */
    
    	/* XXX 4 bytes hole, try to pack */
    ...
    	uint8_t                    status2;              /*    42     1 */
    
    	/* XXX 5 bytes hole, try to pack */
    
    	uint8_t *                  fifo;                 /*    48     8 */
    ...
    	uint8_t                    pwrd;                 /*    76     1 */
    
    	/* XXX 3 bytes hole, try to pack */
    
    	int                        sun4m;                /*    80     4 */
    	uint8_t                    num_floppies;         /*    84     1 */
    
    	/* XXX 3 bytes hole, try to pack */
    
    	FDrive                     drives[2];            /*    88    64 */
    	/* --- cacheline 2 boundary (128 bytes) was 24 bytes ago --- */
    	int                        reset_sensei;         /*   152     4 */
    
    	/* size: 160, cachelines: 3 */
    	/* sum members: 134, holes: 5, sum holes: 22 */
    	/* padding: 4 */
    	/* last cacheline: 32 bytes */
    };	/* definitions: 1 */
    
    Fix by rearranging the structure to avoid padding.
    
    Signed-off-by: Blue Swirl <blauwirbel at gmail.com>

diff --git a/hw/fdc.c b/hw/fdc.c
index edf0360..580b657 100644
--- a/hw/fdc.c
+++ b/hw/fdc.c
@@ -374,13 +374,13 @@ enum {
 #define FD_FORMAT_CMD(state) ((state) & FD_STATE_FORMAT)
 
 struct FDCtrl {
-    /* Controller's identification */
-    uint8_t version;
-    /* HW */
     qemu_irq irq;
-    int dma_chann;
     /* Controller state */
     QEMUTimer *result_timer;
+    int dma_chann;
+    /* Controller's identification */
+    uint8_t version;
+    /* HW */
     uint8_t sra;
     uint8_t srb;
     uint8_t dor;
@@ -401,21 +401,21 @@ struct FDCtrl {
     uint8_t data_dir;
     uint8_t eot; /* last wanted sector */
     /* States kept only to be returned back */
-    /* Timers state */
-    uint8_t timer0;
-    uint8_t timer1;
     /* precompensation */
     uint8_t precomp_trk;
     uint8_t config;
     uint8_t lock;
     /* Power down config (also with status regB access mode */
     uint8_t pwrd;
-    /* Sun4m quirks? */
-    int sun4m;
     /* Floppy drives */
     uint8_t num_floppies;
+    /* Sun4m quirks? */
+    int sun4m;
     FDrive drives[MAX_FD];
     int reset_sensei;
+    /* Timers state */
+    uint8_t timer0;
+    uint8_t timer1;
 };
 
 typedef struct FDCtrlSysBus {
commit fe87aa83c6d0c78bc29230ace4598363cdf4c835
Author: Blue Swirl <blauwirbel at gmail.com>
Date:   Sun Aug 7 19:38:49 2011 +0000

    pcnet: avoid structure holes spotted by pahole
    
    Edited report from pahole on amd64 host:
    struct PCNetState_st {
    ...
    	uint16_t                   bcr[32];              /*   340    64 */
    
    	/* XXX 4 bytes hole, try to pack */
    ...
    	int                        tx_busy;              /*  4520     4 */
    
    	/* XXX 4 bytes hole, try to pack */
    
    	qemu_irq                   irq;                  /*  4528     8 */
    	void                       (*phys_mem_read)(void *, target_phys_addr_t, uint8_t *, int, int); /*  4536     8 */
    	/* --- cacheline 71 boundary (4544 bytes) --- */
    	void                       (*phys_mem_write)(void *, target_phys_addr_t, uint8_t *, int, int); /*  4544     8 */
    	void *                     dma_opaque;           /*  4552     8 */
    	int                        looptest;             /*  4560     4 */
    
    	/* size: 4568, cachelines: 72 */
    	/* sum members: 4556, holes: 2, sum holes: 8 */
    	/* padding: 4 */
    	/* last cacheline: 24 bytes */
    };	/* definitions: 2 */
    
    Fix by rearranging the structure to avoid padding.
    
    Signed-off-by: Blue Swirl <blauwirbel at gmail.com>

diff --git a/hw/pcnet.h b/hw/pcnet.h
index 7e1c685..cd86bde 100644
--- a/hw/pcnet.h
+++ b/hw/pcnet.h
@@ -17,17 +17,17 @@ struct PCNetState_st {
     uint8_t prom[16];
     uint16_t csr[128];
     uint16_t bcr[32];
+    int xmit_pos;
     uint64_t timer;
     MemoryRegion mmio;
-    int xmit_pos;
     uint8_t buffer[4096];
-    int tx_busy;
     qemu_irq irq;
     void (*phys_mem_read)(void *dma_opaque, target_phys_addr_t addr,
                          uint8_t *buf, int len, int do_bswap);
     void (*phys_mem_write)(void *dma_opaque, target_phys_addr_t addr,
                           uint8_t *buf, int len, int do_bswap);
     void *dma_opaque;
+    int tx_busy;
     int looptest;
 };
 
commit 9a975d63563c2d09279b0e9a7fb7c2abcbd512b9
Author: Blue Swirl <blauwirbel at gmail.com>
Date:   Sun Aug 7 19:33:30 2011 +0000

    esp: avoid structure holes spotted by pahole
    
    Report from pahole on amd64 host:
    struct ESPState {
    	SysBusDevice               busdev;               /*     0  5648 */
    	/* --- cacheline 88 boundary (5632 bytes) was 16 bytes ago --- */
    	uint32_t                   it_shift;             /*  5648     4 */
    
    	/* XXX 4 bytes hole, try to pack */
    
    	qemu_irq                   irq;                  /*  5656     8 */
    	uint8_t                    rregs[16];            /*  5664    16 */
    	uint8_t                    wregs[16];            /*  5680    16 */
    	/* --- cacheline 89 boundary (5696 bytes) --- */
    	int32_t                    ti_size;              /*  5696     4 */
    	uint32_t                   ti_rptr;              /*  5700     4 */
    	uint32_t                   ti_wptr;              /*  5704     4 */
    	uint8_t                    ti_buf[16];           /*  5708    16 */
    	uint32_t                   status;               /*  5724     4 */
    	uint32_t                   dma;                  /*  5728     4 */
    
    	/* XXX 4 bytes hole, try to pack */
    
    	SCSIBus                    bus;                  /*  5736  2120 */
    	/* --- cacheline 122 boundary (7808 bytes) was 48 bytes ago --- */
    	SCSIDevice *               current_dev;          /*  7856     8 */
    	SCSIRequest *              current_req;          /*  7864     8 */
    	/* --- cacheline 123 boundary (7872 bytes) --- */
    	uint8_t                    cmdbuf[16];           /*  7872    16 */
    	uint32_t                   cmdlen;               /*  7888     4 */
    	uint32_t                   do_cmd;               /*  7892     4 */
    	uint32_t                   dma_left;             /*  7896     4 */
    	uint32_t                   dma_counter;          /*  7900     4 */
    	uint8_t *                  async_buf;            /*  7904     8 */
    	uint32_t                   async_len;            /*  7912     4 */
    
    	/* XXX 4 bytes hole, try to pack */
    
    	ESPDMAMemoryReadWriteFunc  dma_memory_read;      /*  7920     8 */
    	ESPDMAMemoryReadWriteFunc  dma_memory_write;     /*  7928     8 */
    	/* --- cacheline 124 boundary (7936 bytes) --- */
    	void *                     dma_opaque;           /*  7936     8 */
    	int                        dma_enabled;          /*  7944     4 */
    
    	/* XXX 4 bytes hole, try to pack */
    
    	void                       (*dma_cb)(ESPState *); /*  7952     8 */
    
    	/* size: 7960, cachelines: 125 */
    	/* sum members: 7944, holes: 4, sum holes: 16 */
    	/* last cacheline: 24 bytes */
    };	/* definitions: 1 */
    
    Fix by rearranging the structure to avoid padding.
    
    Signed-off-by: Blue Swirl <blauwirbel at gmail.com>

diff --git a/hw/esp.c b/hw/esp.c
index be3a35d..ca41f80 100644
--- a/hw/esp.c
+++ b/hw/esp.c
@@ -54,15 +54,15 @@ typedef struct ESPState ESPState;
 
 struct ESPState {
     SysBusDevice busdev;
-    uint32_t it_shift;
-    qemu_irq irq;
     uint8_t rregs[ESP_REGS];
     uint8_t wregs[ESP_REGS];
+    qemu_irq irq;
+    uint32_t it_shift;
     int32_t ti_size;
     uint32_t ti_rptr, ti_wptr;
-    uint8_t ti_buf[TI_BUFSZ];
     uint32_t status;
     uint32_t dma;
+    uint8_t ti_buf[TI_BUFSZ];
     SCSIBus bus;
     SCSIDevice *current_dev;
     SCSIRequest *current_req;
@@ -75,13 +75,14 @@ struct ESPState {
     /* The size of the current DMA transfer.  Zero if no transfer is in
        progress.  */
     uint32_t dma_counter;
-    uint8_t *async_buf;
+    int dma_enabled;
+
     uint32_t async_len;
+    uint8_t *async_buf;
 
     ESPDMAMemoryReadWriteFunc dma_memory_read;
     ESPDMAMemoryReadWriteFunc dma_memory_write;
     void *dma_opaque;
-    int dma_enabled;
     void (*dma_cb)(ESPState *s);
 };
 
commit 61999750d3df96ee3f2b111420c7d0a117e57df7
Author: Blue Swirl <blauwirbel at gmail.com>
Date:   Sun Aug 7 19:22:46 2011 +0000

    sun4m: avoid structure holes spotted by pahole
    
    Edited report from pahole on amd64 host:
    struct sun4c_hwdef {
    ...
    	uint8_t                    nvram_machine_id;     /*   112     1 */
    
    	/* XXX 1 byte hole, try to pack */
    ...
    	/* size: 136, cachelines: 3 */
    	/* sum members: 135, holes: 1, sum holes: 1 */
    	/* last cacheline: 8 bytes */
    };	/* definitions: 1 */
    
    struct sun4d_hwdef {
    ...
    	uint8_t                    nvram_machine_id;     /*   128     1 */
    
    	/* XXX 1 byte hole, try to pack */
    ...
    	/* size: 152, cachelines: 3 */
    	/* sum members: 151, holes: 1, sum holes: 1 */
    	/* last cacheline: 24 bytes */
    };	/* definitions: 1 */
    
    struct sun4m_hwdef {
    ...
    	uint8_t                    nvram_machine_id;     /*   260     1 */
    
    	/* XXX 1 byte hole, try to pack */
    
    	uint16_t                   machine_id;           /*   262     2 */
    	uint32_t                   iommu_version;        /*   264     4 */
    
    	/* XXX 4 bytes hole, try to pack */
    ...
    	/* size: 288, cachelines: 5 */
    	/* sum members: 283, holes: 2, sum holes: 5 */
    	/* last cacheline: 32 bytes */
    };	/* definitions: 1 */
    
    Fix by rearranging the structures to avoid padding.
    
    Signed-off-by: Blue Swirl <blauwirbel at gmail.com>

diff --git a/hw/sun4m.c b/hw/sun4m.c
index 7516703..dcaed38 100644
--- a/hw/sun4m.c
+++ b/hw/sun4m.c
@@ -97,12 +97,12 @@ struct sun4m_hwdef {
         target_phys_addr_t reg_base, vram_base;
     } vsimm[MAX_VSIMMS];
     target_phys_addr_t ecc_base;
-    uint32_t ecc_version;
-    uint8_t nvram_machine_id;
-    uint16_t machine_id;
-    uint32_t iommu_version;
     uint64_t max_mem;
     const char * const default_cpu_model;
+    uint32_t ecc_version;
+    uint32_t iommu_version;
+    uint16_t machine_id;
+    uint8_t nvram_machine_id;
 };
 
 #define MAX_IOUNITS 5
@@ -115,11 +115,11 @@ struct sun4d_hwdef {
     target_phys_addr_t ledma_base, le_base;
     target_phys_addr_t tcx_base;
     target_phys_addr_t sbi_base;
-    uint8_t nvram_machine_id;
-    uint16_t machine_id;
-    uint32_t iounit_version;
     uint64_t max_mem;
     const char * const default_cpu_model;
+    uint32_t iounit_version;
+    uint16_t machine_id;
+    uint8_t nvram_machine_id;
 };
 
 struct sun4c_hwdef {
@@ -128,11 +128,11 @@ struct sun4c_hwdef {
     target_phys_addr_t serial_base, fd_base;
     target_phys_addr_t idreg_base, dma_base, esp_base, le_base;
     target_phys_addr_t tcx_base, aux1_base;
-    uint8_t nvram_machine_id;
-    uint16_t machine_id;
-    uint32_t iommu_version;
     uint64_t max_mem;
     const char * const default_cpu_model;
+    uint32_t iommu_version;
+    uint16_t machine_id;
+    uint8_t nvram_machine_id;
 };
 
 int DMA_get_channel_mode (int nchan)
commit 427a66c3a5674cf69efcd2d82f32ffdf91f2044a
Author: Blue Swirl <blauwirbel at gmail.com>
Date:   Sun Aug 7 19:13:24 2011 +0000

    tcx: avoid structure holes spotted by pahole
    
    Report from pahole on amd64 host:
    struct TCXState {
    	SysBusDevice               busdev;               /*     0  5648 */
    	/* --- cacheline 88 boundary (5632 bytes) was 16 bytes ago --- */
    	target_phys_addr_t         addr;                 /*  5648     8 */
    	DisplayState *             ds;                   /*  5656     8 */
    	uint8_t *                  vram;                 /*  5664     8 */
    	uint32_t *                 vram24;               /*  5672     8 */
    	uint32_t *                 cplane;               /*  5680     8 */
    	ram_addr_t                 vram_offset;          /*  5688     8 */
    	/* --- cacheline 89 boundary (5696 bytes) --- */
    	ram_addr_t                 vram24_offset;        /*  5696     8 */
    	ram_addr_t                 cplane_offset;        /*  5704     8 */
    	uint32_t                   vram_size;            /*  5712     4 */
    	uint16_t                   width;                /*  5716     2 */
    	uint16_t                   height;               /*  5718     2 */
    	uint16_t                   depth;                /*  5720     2 */
    	uint8_t                    r[256];               /*  5722   256 */
    	/* --- cacheline 93 boundary (5952 bytes) was 26 bytes ago --- */
    	uint8_t                    g[256];               /*  5978   256 */
    	/* --- cacheline 97 boundary (6208 bytes) was 26 bytes ago --- */
    	uint8_t                    b[256];               /*  6234   256 */
    
    	/* XXX 2 bytes hole, try to pack */
    
    	/* --- cacheline 101 boundary (6464 bytes) was 28 bytes ago --- */
    	uint32_t                   palette[256];         /*  6492  1024 */
    	/* --- cacheline 117 boundary (7488 bytes) was 28 bytes ago --- */
    	uint8_t                    dac_index;            /*  7516     1 */
    	uint8_t                    dac_state;            /*  7517     1 */
    
    	/* size: 7520, cachelines: 118 */
    	/* sum members: 7516, holes: 1, sum holes: 2 */
    	/* padding: 2 */
    	/* last cacheline: 32 bytes */
    };	/* definitions: 1 */
    
    Fix by rearranging the structure to avoid padding.
    
    Signed-off-by: Blue Swirl <blauwirbel at gmail.com>

diff --git a/hw/tcx.c b/hw/tcx.c
index 0e32830..309600d 100644
--- a/hw/tcx.c
+++ b/hw/tcx.c
@@ -42,9 +42,9 @@ typedef struct TCXState {
     uint32_t *vram24, *cplane;
     ram_addr_t vram_offset, vram24_offset, cplane_offset;
     uint32_t vram_size;
-    uint16_t width, height, depth;
-    uint8_t r[256], g[256], b[256];
     uint32_t palette[256];
+    uint8_t r[256], g[256], b[256];
+    uint16_t width, height, depth;
     uint8_t dac_index, dac_state;
 } TCXState;
 
commit 149e1ea154efebf0b3a7aae20538ce7673d78b77
Author: Blue Swirl <blauwirbel at gmail.com>
Date:   Sun Aug 7 19:09:50 2011 +0000

    sun4m_iommu: avoid structure holes spotted by pahole
    
    Report from pahole on amd64 host:
    struct IOMMUState {
    	SysBusDevice               busdev;               /*     0  5648 */
    	/* --- cacheline 88 boundary (5632 bytes) was 16 bytes ago --- */
    	uint32_t                   regs[4096];           /*  5648 16384 */
    	/* --- cacheline 344 boundary (22016 bytes) was 16 bytes ago --- */
    	target_phys_addr_t         iostart;              /* 22032     8 */
    	uint32_t                   version;              /* 22040     4 */
    
    	/* XXX 4 bytes hole, try to pack */
    
    	qemu_irq                   irq;                  /* 22048     8 */
    
    	/* size: 22056, cachelines: 345 */
    	/* sum members: 22052, holes: 1, sum holes: 4 */
    	/* last cacheline: 40 bytes */
    };	/* definitions: 1 */
    
    Fix by rearranging the structure to avoid padding.
    
    Signed-off-by: Blue Swirl <blauwirbel at gmail.com>

diff --git a/hw/sun4m_iommu.c b/hw/sun4m_iommu.c
index 7f5dad5..6eeadfa 100644
--- a/hw/sun4m_iommu.c
+++ b/hw/sun4m_iommu.c
@@ -130,8 +130,8 @@ typedef struct IOMMUState {
     SysBusDevice busdev;
     uint32_t regs[IOMMU_NREGS];
     target_phys_addr_t iostart;
-    uint32_t version;
     qemu_irq irq;
+    uint32_t version;
 } IOMMUState;
 
 static uint32_t iommu_mem_readl(void *opaque, target_phys_addr_t addr)
commit 07dd0035d83727ed2b1922a85cd5aea5b010025b
Author: Blue Swirl <blauwirbel at gmail.com>
Date:   Sun Aug 7 19:06:26 2011 +0000

    slavio_intctl: avoid structure holes spotted by pahole
    
    Report from pahole on amd64 host:
    struct SLAVIO_INTCTLState {
    	SysBusDevice               busdev;               /*     0  5648 */
    	/* --- cacheline 88 boundary (5632 bytes) was 16 bytes ago --- */
    	uint32_t                   intregm_pending;      /*  5648     4 */
    	uint32_t                   intregm_disabled;     /*  5652     4 */
    	uint32_t                   target_cpu;           /*  5656     4 */
    
    	/* XXX 4 bytes hole, try to pack */
    
    	qemu_irq                   cpu_irqs[16][16];     /*  5664  2048 */
    	/* --- cacheline 120 boundary (7680 bytes) was 32 bytes ago --- */
    	SLAVIO_CPUINTCTLState      slaves[16];           /*  7712   384 */
    	/* --- cacheline 126 boundary (8064 bytes) was 32 bytes ago --- */
    
    	/* size: 8096, cachelines: 127 */
    	/* sum members: 8092, holes: 1, sum holes: 4 */
    	/* last cacheline: 32 bytes */
    };	/* definitions: 1 */
    
    struct SLAVIO_CPUINTCTLState {
    	uint32_t                   intreg_pending;       /*     0     4 */
    
    	/* XXX 4 bytes hole, try to pack */
    
    	struct SLAVIO_INTCTLState * master;              /*     8     8 */
    	uint32_t                   cpu;                  /*    16     4 */
    	uint32_t                   irl_out;              /*    20     4 */
    
    	/* size: 24, cachelines: 1 */
    	/* sum members: 20, holes: 1, sum holes: 4 */
    	/* last cacheline: 24 bytes */
    };	/* definitions: 1 */
    
    Fix by rearranging the structures to avoid padding.
    
    Signed-off-by: Blue Swirl <blauwirbel at gmail.com>

diff --git a/hw/slavio_intctl.c b/hw/slavio_intctl.c
index a83e5b8..329c251 100644
--- a/hw/slavio_intctl.c
+++ b/hw/slavio_intctl.c
@@ -46,22 +46,22 @@
 struct SLAVIO_INTCTLState;
 
 typedef struct SLAVIO_CPUINTCTLState {
-    uint32_t intreg_pending;
     struct SLAVIO_INTCTLState *master;
+    uint32_t intreg_pending;
     uint32_t cpu;
     uint32_t irl_out;
 } SLAVIO_CPUINTCTLState;
 
 typedef struct SLAVIO_INTCTLState {
     SysBusDevice busdev;
-    uint32_t intregm_pending;
-    uint32_t intregm_disabled;
-    uint32_t target_cpu;
 #ifdef DEBUG_IRQ_COUNT
     uint64_t irq_count[32];
 #endif
     qemu_irq cpu_irqs[MAX_CPUS][MAX_PILS];
     SLAVIO_CPUINTCTLState slaves[MAX_CPUS];
+    uint32_t intregm_pending;
+    uint32_t intregm_disabled;
+    uint32_t target_cpu;
 } SLAVIO_INTCTLState;
 
 #define INTCTL_MAXADDR 0xf
commit 97bbb109b1349051390f6b2ad77b1bfb44e3d760
Author: Blue Swirl <blauwirbel at gmail.com>
Date:   Sun Aug 7 19:03:18 2011 +0000

    slavio_misc: avoid structure holes spotted by pahole
    
    Report from pahole on amd64 host:
    struct MiscState {
    	SysBusDevice               busdev;               /*     0  5648 */
    	/* --- cacheline 88 boundary (5632 bytes) was 16 bytes ago --- */
    	qemu_irq                   irq;                  /*  5648     8 */
    	uint32_t                   dummy;                /*  5656     4 */
    	uint8_t                    config;               /*  5660     1 */
    	uint8_t                    aux1;                 /*  5661     1 */
    	uint8_t                    aux2;                 /*  5662     1 */
    	uint8_t                    diag;                 /*  5663     1 */
    	uint8_t                    mctrl;                /*  5664     1 */
    	uint8_t                    sysctrl;              /*  5665     1 */
    	uint16_t                   leds;                 /*  5666     2 */
    
    	/* XXX 4 bytes hole, try to pack */
    
    	qemu_irq                   fdc_tc;               /*  5672     8 */
    
    	/* size: 5680, cachelines: 89 */
    	/* sum members: 5676, holes: 1, sum holes: 4 */
    	/* last cacheline: 48 bytes */
    };	/* definitions: 1 */
    
    Fix by rearranging the structure to avoid padding.
    
    Signed-off-by: Blue Swirl <blauwirbel at gmail.com>

diff --git a/hw/slavio_misc.c b/hw/slavio_misc.c
index 198360d..1f5a2d7 100644
--- a/hw/slavio_misc.c
+++ b/hw/slavio_misc.c
@@ -37,13 +37,13 @@
 typedef struct MiscState {
     SysBusDevice busdev;
     qemu_irq irq;
+    qemu_irq fdc_tc;
     uint32_t dummy;
     uint8_t config;
     uint8_t aux1, aux2;
     uint8_t diag, mctrl;
     uint8_t sysctrl;
     uint16_t leds;
-    qemu_irq fdc_tc;
 } MiscState;
 
 typedef struct APCState {
commit f90074f49309de9dd65b978a95d10f089017960a
Author: Blue Swirl <blauwirbel at gmail.com>
Date:   Sun Aug 7 19:00:23 2011 +0000

    slavio_timer: avoid structure holes spotted by pahole
    
    Report from pahole on amd64 host:
    struct SLAVIO_TIMERState {
    	SysBusDevice               busdev;               /*     0  5648 */
    	/* --- cacheline 88 boundary (5632 bytes) was 16 bytes ago --- */
    	uint32_t                   num_cpus;             /*  5648     4 */
    
    	/* XXX 4 bytes hole, try to pack */
    
    	CPUTimerState              cputimer[17];         /*  5656   816 */
    	/* --- cacheline 101 boundary (6464 bytes) was 8 bytes ago --- */
    	uint32_t                   cputimer_mode;        /*  6472     4 */
    
    	/* size: 6480, cachelines: 102 */
    	/* sum members: 6472, holes: 1, sum holes: 4 */
    	/* padding: 4 */
    	/* last cacheline: 16 bytes */
    };	/* definitions: 1 */
    
    struct CPUTimerState {
    	qemu_irq                   irq;                  /*     0     8 */
    	ptimer_state *             timer;                /*     8     8 */
    	uint32_t                   count;                /*    16     4 */
    	uint32_t                   counthigh;            /*    20     4 */
    	uint32_t                   reached;              /*    24     4 */
    
    	/* XXX 4 bytes hole, try to pack */
    
    	uint64_t                   limit;                /*    32     8 */
    	uint32_t                   running;              /*    40     4 */
    
    	/* size: 48, cachelines: 1 */
    	/* sum members: 40, holes: 1, sum holes: 4 */
    	/* padding: 4 */
    	/* last cacheline: 48 bytes */
    };	/* definitions: 1 */
    
    Fix by rearranging the structures to avoid padding.
    
    Signed-off-by: Blue Swirl <blauwirbel at gmail.com>

diff --git a/hw/slavio_timer.c b/hw/slavio_timer.c
index f89b4fb..84449ba 100644
--- a/hw/slavio_timer.c
+++ b/hw/slavio_timer.c
@@ -48,16 +48,16 @@ typedef struct CPUTimerState {
     qemu_irq irq;
     ptimer_state *timer;
     uint32_t count, counthigh, reached;
-    uint64_t limit;
-    // processor only
+    /* processor only */
     uint32_t running;
+    uint64_t limit;
 } CPUTimerState;
 
 typedef struct SLAVIO_TIMERState {
     SysBusDevice busdev;
     uint32_t num_cpus;
-    CPUTimerState cputimer[MAX_CPUS + 1];
     uint32_t cputimer_mode;
+    CPUTimerState cputimer[MAX_CPUS + 1];
 } SLAVIO_TIMERState;
 
 typedef struct TimerContext {
commit 94ac5cd20c6e441e0ed3aec5c98d6cbefb7f503f
Author: Austin Clements <amdragon at MIT.EDU>
Date:   Sun Aug 21 14:49:45 2011 -0400

    monitor: Prevent sign-extension of 32-bit addresses printed by info tlb
    
    This is the same fix that was recently applied to info mem.  Before
    this change, info tlb output looked like:
    
    ffffffffffffc000: 000000000fffc000 --------W
    ffffffffffffd000: 000000000fffd000 --------W
    ffffffffffffe000: 000000000fffe000 --------W
    fffffffffffff000: 000000000ffff000 --------W
    
    With this change, it looks like
    
    00000000ffffc000: 000000000fffc000 --------W
    00000000ffffd000: 000000000fffd000 --------W
    00000000ffffe000: 000000000fffe000 --------W
    00000000fffff000: 000000000ffff000 --------W
    
    Signed-off-by: Austin Clements <amdragon at mit.edu>
    Signed-off-by: Blue Swirl <blauwirbel at gmail.com>

diff --git a/monitor.c b/monitor.c
index 0e101f5..39791dc 100644
--- a/monitor.c
+++ b/monitor.c
@@ -2054,7 +2054,7 @@ static void print_pte(Monitor *mon, target_phys_addr_t addr,
 
 static void tlb_info_32(Monitor *mon, CPUState *env)
 {
-    int l1, l2;
+    unsigned int l1, l2;
     uint32_t pgd, pde, pte;
 
     pgd = env->cr[3] & ~0xfff;
@@ -2082,7 +2082,7 @@ static void tlb_info_32(Monitor *mon, CPUState *env)
 
 static void tlb_info_pae32(Monitor *mon, CPUState *env)
 {
-    int l1, l2, l3;
+    unsigned int l1, l2, l3;
     uint64_t pdpe, pde, pte;
     uint64_t pdp_addr, pd_addr, pt_addr;
 
commit aec7c6dc683314d1e5bed09a9cc98dab086ead82
Merge: 64ba39a... 1b930bf...
Author: Blue Swirl <blauwirbel at gmail.com>
Date:   Sun Aug 21 19:19:29 2011 +0000

    Merge branch 'queues/slirp' of git://git.kiszka.org/qemu
    
    * 'queues/slirp' of git://git.kiszka.org/qemu:
      slirp: Fix bit field types in IP header structs

commit 64ba39af27c0ddaa48fd5625f3109ae81e970e4e
Author: Richard Henderson <rth at twiddle.net>
Date:   Wed Aug 17 14:11:49 2011 -0700

    tcg-ia64: Fix typos in AREG0 setup in prologue.
    
    Signed-off-by: Richard Henderson <rth at twiddle.net>
    Signed-off-by: Blue Swirl <blauwirbel at gmail.com>

diff --git a/tcg/ia64/tcg-target.c b/tcg/ia64/tcg-target.c
index 6386a5b..9db205d 100644
--- a/tcg/ia64/tcg-target.c
+++ b/tcg/ia64/tcg-target.c
@@ -2308,8 +2308,8 @@ static void tcg_target_qemu_prologue(TCGContext *s)
     }
 
     tcg_out_bundle(s, miB,
-                   tcg_opc_m48(TCG_REG_P0, OPC_MOV_I21,
-                               TCG_REG_AREG0, TCG_REG_R32, 0),
+                   tcg_opc_a4 (TCG_REG_P0, OPC_ADDS_A4,
+                               TCG_AREG0, 0, TCG_REG_R32),
                    tcg_opc_a4 (TCG_REG_P0, OPC_ADDS_A4,
                                TCG_REG_R12, -frame_size, TCG_REG_R12),
                    tcg_opc_b4 (TCG_REG_P0, OPC_BR_SPTK_MANY_B4, TCG_REG_B6));
commit 6e6a99249cb54188ab3a1cc1152fa69420a174ce
Author: Richard Henderson <rth at twiddle.net>
Date:   Wed Aug 17 14:11:48 2011 -0700

    tcg-hppa: Fix CPU_TEMP_BUF_NLONGS oversight.
    
    Signed-off-by: Richard Henderson <rth at twiddle.net>
    Signed-off-by: Blue Swirl <blauwirbel at gmail.com>

diff --git a/tcg/hppa/tcg-target.c b/tcg/hppa/tcg-target.c
index 222f33e..71d9677 100644
--- a/tcg/hppa/tcg-target.c
+++ b/tcg/hppa/tcg-target.c
@@ -1650,7 +1650,7 @@ static void tcg_target_qemu_prologue(TCGContext *s)
 
     /* Record the location of the TCG temps.  */
     tcg_set_frame(s, TCG_REG_CALL_STACK, -frame_size + i * 4,
-                  TCG_TEMP_BUF_NLONGS * sizeof(long));
+                  CPU_TEMP_BUF_NLONGS * sizeof(long));
 
 #ifdef CONFIG_USE_GUEST_BASE
     if (GUEST_BASE != 0) {
commit cb25c80a9b8324c59aa157c4e9cfe296489d0b9c
Author: Richard Henderson <rth at twiddle.net>
Date:   Wed Aug 17 14:11:47 2011 -0700

    tcg: Constant fold neg, andc, orc, eqv, nand, nor.
    
    Signed-off-by: Richard Henderson <rth at twiddle.net>
    Signed-off-by: Blue Swirl <blauwirbel at gmail.com>

diff --git a/tcg/optimize.c b/tcg/optimize.c
index 32f928f..7e7f2b2 100644
--- a/tcg/optimize.c
+++ b/tcg/optimize.c
@@ -215,6 +215,24 @@ static TCGArg do_constant_folding_2(int op, TCGArg x, TCGArg y)
     CASE_OP_32_64(not):
         return ~x;
 
+    CASE_OP_32_64(neg):
+        return -x;
+
+    CASE_OP_32_64(andc):
+        return x & ~y;
+
+    CASE_OP_32_64(orc):
+        return x | ~y;
+
+    CASE_OP_32_64(eqv):
+        return ~(x ^ y);
+
+    CASE_OP_32_64(nand):
+        return ~(x & y);
+
+    CASE_OP_32_64(nor):
+        return ~(x | y);
+
     CASE_OP_32_64(ext8s):
         return (int8_t)x;
 
@@ -290,6 +308,9 @@ static TCGArg *tcg_constant_folding(TCGContext *s, uint16_t *tcg_opc_ptr,
         CASE_OP_32_64(and):
         CASE_OP_32_64(or):
         CASE_OP_32_64(xor):
+        CASE_OP_32_64(eqv):
+        CASE_OP_32_64(nand):
+        CASE_OP_32_64(nor):
             if (temps[args[1]].state == TCG_TEMP_CONST) {
                 tmp = args[1];
                 args[1] = args[2];
@@ -389,6 +410,7 @@ static TCGArg *tcg_constant_folding(TCGContext *s, uint16_t *tcg_opc_ptr,
             args += 2;
             break;
         CASE_OP_32_64(not):
+        CASE_OP_32_64(neg):
         CASE_OP_32_64(ext8s):
         CASE_OP_32_64(ext8u):
         CASE_OP_32_64(ext16s):
@@ -421,6 +443,11 @@ static TCGArg *tcg_constant_folding(TCGContext *s, uint16_t *tcg_opc_ptr,
         CASE_OP_32_64(sar):
         CASE_OP_32_64(rotl):
         CASE_OP_32_64(rotr):
+        CASE_OP_32_64(andc):
+        CASE_OP_32_64(orc):
+        CASE_OP_32_64(eqv):
+        CASE_OP_32_64(nand):
+        CASE_OP_32_64(nor):
             if (temps[args[1]].state == TCG_TEMP_CONST
                 && temps[args[2]].state == TCG_TEMP_CONST) {
                 gen_opc_buf[op_index] = op_to_movi(op);
commit 25c4d9cc845fb58f624dae8c0f690e20c70e7a1d
Author: Richard Henderson <rth at twiddle.net>
Date:   Wed Aug 17 14:11:46 2011 -0700

    tcg: Always define all of the TCGOpcode enum members.
    
    By always defining these symbols, we can eliminate a lot of ifdefs.
    
    To allow this to be checked reliably, the semantics of the
    TCG_TARGET_HAS_* macros must be changed from def/undef to true/false.
    This allows even more ifdefs to be removed, converting them into
    C if statements.
    
    Signed-off-by: Richard Henderson <rth at twiddle.net>
    Signed-off-by: Blue Swirl <blauwirbel at gmail.com>

diff --git a/tcg/arm/tcg-target.h b/tcg/arm/tcg-target.h
index d8d7d94..0e0f69a 100644
--- a/tcg/arm/tcg-target.h
+++ b/tcg/arm/tcg-target.h
@@ -58,20 +58,22 @@ enum {
 #define TCG_TARGET_CALL_STACK_OFFSET	0
 
 /* optional instructions */
-#define TCG_TARGET_HAS_ext8s_i32
-#define TCG_TARGET_HAS_ext16s_i32
-#undef TCG_TARGET_HAS_ext8u_i32       /* and r0, r1, #0xff */
-#define TCG_TARGET_HAS_ext16u_i32
-#define TCG_TARGET_HAS_bswap16_i32
-#define TCG_TARGET_HAS_bswap32_i32
-#define TCG_TARGET_HAS_not_i32
-#define TCG_TARGET_HAS_neg_i32
-#define TCG_TARGET_HAS_rot_i32
-#define TCG_TARGET_HAS_andc_i32
-// #define TCG_TARGET_HAS_orc_i32
-// #define TCG_TARGET_HAS_eqv_i32
-// #define TCG_TARGET_HAS_nand_i32
-// #define TCG_TARGET_HAS_nor_i32
+#define TCG_TARGET_HAS_div_i32          0
+#define TCG_TARGET_HAS_ext8s_i32        1
+#define TCG_TARGET_HAS_ext16s_i32       1
+#define TCG_TARGET_HAS_ext8u_i32        0 /* and r0, r1, #0xff */
+#define TCG_TARGET_HAS_ext16u_i32       1
+#define TCG_TARGET_HAS_bswap16_i32      1
+#define TCG_TARGET_HAS_bswap32_i32      1
+#define TCG_TARGET_HAS_not_i32          1
+#define TCG_TARGET_HAS_neg_i32          1
+#define TCG_TARGET_HAS_rot_i32          1
+#define TCG_TARGET_HAS_andc_i32         1
+#define TCG_TARGET_HAS_orc_i32          0
+#define TCG_TARGET_HAS_eqv_i32          0
+#define TCG_TARGET_HAS_nand_i32         0
+#define TCG_TARGET_HAS_nor_i32          0
+#define TCG_TARGET_HAS_deposit_i32      0
 
 #define TCG_TARGET_HAS_GUEST_BASE
 
diff --git a/tcg/hppa/tcg-target.h b/tcg/hppa/tcg-target.h
index f7919ce..ed90efc 100644
--- a/tcg/hppa/tcg-target.h
+++ b/tcg/hppa/tcg-target.h
@@ -85,21 +85,24 @@ enum {
 #define TCG_TARGET_STACK_GROWSUP
 
 /* optional instructions */
-// #define TCG_TARGET_HAS_div_i32
-#define TCG_TARGET_HAS_rot_i32
-#define TCG_TARGET_HAS_ext8s_i32
-#define TCG_TARGET_HAS_ext16s_i32
-#define TCG_TARGET_HAS_bswap16_i32
-#define TCG_TARGET_HAS_bswap32_i32
-#define TCG_TARGET_HAS_not_i32
-#define TCG_TARGET_HAS_andc_i32
-// #define TCG_TARGET_HAS_orc_i32
-#define TCG_TARGET_HAS_deposit_i32
+#define TCG_TARGET_HAS_div_i32          0
+#define TCG_TARGET_HAS_rot_i32          1
+#define TCG_TARGET_HAS_ext8s_i32        1
+#define TCG_TARGET_HAS_ext16s_i32       1
+#define TCG_TARGET_HAS_bswap16_i32      1
+#define TCG_TARGET_HAS_bswap32_i32      1
+#define TCG_TARGET_HAS_not_i32          1
+#define TCG_TARGET_HAS_andc_i32         1
+#define TCG_TARGET_HAS_orc_i32          0
+#define TCG_TARGET_HAS_eqv_i32          0
+#define TCG_TARGET_HAS_nand_i32         0
+#define TCG_TARGET_HAS_nor_i32          0
+#define TCG_TARGET_HAS_deposit_i32      1
 
 /* optional instructions automatically implemented */
-#undef TCG_TARGET_HAS_neg_i32           /* sub rd, 0, rs */
-#undef TCG_TARGET_HAS_ext8u_i32         /* and rd, rs, 0xff */
-#undef TCG_TARGET_HAS_ext16u_i32        /* and rd, rs, 0xffff */
+#define TCG_TARGET_HAS_neg_i32          0 /* sub rd, 0, rs */
+#define TCG_TARGET_HAS_ext8u_i32        0 /* and rd, rs, 0xff */
+#define TCG_TARGET_HAS_ext16u_i32       0 /* and rd, rs, 0xffff */
 
 #define TCG_TARGET_HAS_GUEST_BASE
 
diff --git a/tcg/i386/tcg-target.h b/tcg/i386/tcg-target.h
index bfafbfc..5088e47 100644
--- a/tcg/i386/tcg-target.h
+++ b/tcg/i386/tcg-target.h
@@ -75,41 +75,43 @@ enum {
 #define TCG_TARGET_CALL_STACK_OFFSET 0
 
 /* optional instructions */
-#define TCG_TARGET_HAS_div2_i32
-#define TCG_TARGET_HAS_rot_i32
-#define TCG_TARGET_HAS_ext8s_i32
-#define TCG_TARGET_HAS_ext16s_i32
-#define TCG_TARGET_HAS_ext8u_i32
-#define TCG_TARGET_HAS_ext16u_i32
-#define TCG_TARGET_HAS_bswap16_i32
-#define TCG_TARGET_HAS_bswap32_i32
-#define TCG_TARGET_HAS_neg_i32
-#define TCG_TARGET_HAS_not_i32
-// #define TCG_TARGET_HAS_andc_i32
-// #define TCG_TARGET_HAS_orc_i32
-// #define TCG_TARGET_HAS_eqv_i32
-// #define TCG_TARGET_HAS_nand_i32
-// #define TCG_TARGET_HAS_nor_i32
+#define TCG_TARGET_HAS_div2_i32         1
+#define TCG_TARGET_HAS_rot_i32          1
+#define TCG_TARGET_HAS_ext8s_i32        1
+#define TCG_TARGET_HAS_ext16s_i32       1
+#define TCG_TARGET_HAS_ext8u_i32        1
+#define TCG_TARGET_HAS_ext16u_i32       1
+#define TCG_TARGET_HAS_bswap16_i32      1
+#define TCG_TARGET_HAS_bswap32_i32      1
+#define TCG_TARGET_HAS_neg_i32          1
+#define TCG_TARGET_HAS_not_i32          1
+#define TCG_TARGET_HAS_andc_i32         0
+#define TCG_TARGET_HAS_orc_i32          0
+#define TCG_TARGET_HAS_eqv_i32          0
+#define TCG_TARGET_HAS_nand_i32         0
+#define TCG_TARGET_HAS_nor_i32          0
+#define TCG_TARGET_HAS_deposit_i32      0
 
 #if TCG_TARGET_REG_BITS == 64
-#define TCG_TARGET_HAS_div2_i64
-#define TCG_TARGET_HAS_rot_i64
-#define TCG_TARGET_HAS_ext8s_i64
-#define TCG_TARGET_HAS_ext16s_i64
-#define TCG_TARGET_HAS_ext32s_i64
-#define TCG_TARGET_HAS_ext8u_i64
-#define TCG_TARGET_HAS_ext16u_i64
-#define TCG_TARGET_HAS_ext32u_i64
-#define TCG_TARGET_HAS_bswap16_i64
-#define TCG_TARGET_HAS_bswap32_i64
-#define TCG_TARGET_HAS_bswap64_i64
-#define TCG_TARGET_HAS_neg_i64
-#define TCG_TARGET_HAS_not_i64
-// #define TCG_TARGET_HAS_andc_i64
-// #define TCG_TARGET_HAS_orc_i64
-// #define TCG_TARGET_HAS_eqv_i64
-// #define TCG_TARGET_HAS_nand_i64
-// #define TCG_TARGET_HAS_nor_i64
+#define TCG_TARGET_HAS_div2_i64         1
+#define TCG_TARGET_HAS_rot_i64          1
+#define TCG_TARGET_HAS_ext8s_i64        1
+#define TCG_TARGET_HAS_ext16s_i64       1
+#define TCG_TARGET_HAS_ext32s_i64       1
+#define TCG_TARGET_HAS_ext8u_i64        1
+#define TCG_TARGET_HAS_ext16u_i64       1
+#define TCG_TARGET_HAS_ext32u_i64       1
+#define TCG_TARGET_HAS_bswap16_i64      1
+#define TCG_TARGET_HAS_bswap32_i64      1
+#define TCG_TARGET_HAS_bswap64_i64      1
+#define TCG_TARGET_HAS_neg_i64          1
+#define TCG_TARGET_HAS_not_i64          1
+#define TCG_TARGET_HAS_andc_i64         0
+#define TCG_TARGET_HAS_orc_i64          0
+#define TCG_TARGET_HAS_eqv_i64          0
+#define TCG_TARGET_HAS_nand_i64         0
+#define TCG_TARGET_HAS_nor_i64          0
+#define TCG_TARGET_HAS_deposit_i64      0
 #endif
 
 #define TCG_TARGET_HAS_GUEST_BASE
diff --git a/tcg/ia64/tcg-target.h b/tcg/ia64/tcg-target.h
index e56e88f..ddc93c1 100644
--- a/tcg/ia64/tcg-target.h
+++ b/tcg/ia64/tcg-target.h
@@ -104,39 +104,43 @@ enum {
 #define TCG_TARGET_CALL_STACK_OFFSET 16
 
 /* optional instructions */
-#define TCG_TARGET_HAS_andc_i32
-#define TCG_TARGET_HAS_andc_i64
-#define TCG_TARGET_HAS_bswap16_i32
-#define TCG_TARGET_HAS_bswap16_i64
-#define TCG_TARGET_HAS_bswap32_i32
-#define TCG_TARGET_HAS_bswap32_i64
-#define TCG_TARGET_HAS_bswap64_i64
-#define TCG_TARGET_HAS_eqv_i32
-#define TCG_TARGET_HAS_eqv_i64
-#define TCG_TARGET_HAS_ext8s_i32
-#define TCG_TARGET_HAS_ext16s_i32
-#define TCG_TARGET_HAS_ext8s_i64
-#define TCG_TARGET_HAS_ext16s_i64
-#define TCG_TARGET_HAS_ext32s_i64
-#define TCG_TARGET_HAS_ext8u_i32
-#define TCG_TARGET_HAS_ext16u_i32
-#define TCG_TARGET_HAS_ext8u_i64
-#define TCG_TARGET_HAS_ext16u_i64
-#define TCG_TARGET_HAS_ext32u_i64
-#define TCG_TARGET_HAS_nand_i32
-#define TCG_TARGET_HAS_nand_i64
-#define TCG_TARGET_HAS_nor_i32
-#define TCG_TARGET_HAS_nor_i64
-#define TCG_TARGET_HAS_orc_i32
-#define TCG_TARGET_HAS_orc_i64
-#define TCG_TARGET_HAS_rot_i32
-#define TCG_TARGET_HAS_rot_i64
+#define TCG_TARGET_HAS_div_i32          0
+#define TCG_TARGET_HAS_div_i64          0
+#define TCG_TARGET_HAS_andc_i32         1
+#define TCG_TARGET_HAS_andc_i64         1
+#define TCG_TARGET_HAS_bswap16_i32      1
+#define TCG_TARGET_HAS_bswap16_i64      1
+#define TCG_TARGET_HAS_bswap32_i32      1
+#define TCG_TARGET_HAS_bswap32_i64      1
+#define TCG_TARGET_HAS_bswap64_i64      1
+#define TCG_TARGET_HAS_eqv_i32          1
+#define TCG_TARGET_HAS_eqv_i64          1
+#define TCG_TARGET_HAS_ext8s_i32        1
+#define TCG_TARGET_HAS_ext16s_i32       1
+#define TCG_TARGET_HAS_ext8s_i64        1
+#define TCG_TARGET_HAS_ext16s_i64       1
+#define TCG_TARGET_HAS_ext32s_i64       1
+#define TCG_TARGET_HAS_ext8u_i32        1
+#define TCG_TARGET_HAS_ext16u_i32       1
+#define TCG_TARGET_HAS_ext8u_i64        1
+#define TCG_TARGET_HAS_ext16u_i64       1
+#define TCG_TARGET_HAS_ext32u_i64       1
+#define TCG_TARGET_HAS_nand_i32         1
+#define TCG_TARGET_HAS_nand_i64         1
+#define TCG_TARGET_HAS_nor_i32          1
+#define TCG_TARGET_HAS_nor_i64          1
+#define TCG_TARGET_HAS_orc_i32          1
+#define TCG_TARGET_HAS_orc_i64          1
+#define TCG_TARGET_HAS_rot_i32          1
+#define TCG_TARGET_HAS_rot_i64          1
+#define TCG_TARGET_HAS_deposit_i32      0
+#define TCG_TARGET_HAS_deposit_i64      0
 
 /* optional instructions automatically implemented */
-#undef TCG_TARGET_HAS_neg_i32   /* sub r1, r0, r3 */
-#undef TCG_TARGET_HAS_neg_i64   /* sub r1, r0, r3 */
-#undef TCG_TARGET_HAS_not_i32   /* xor r1, -1, r3 */
-#undef TCG_TARGET_HAS_not_i64   /* xor r1, -1, r3 */
+#define TCG_TARGET_HAS_neg_i32          0 /* sub r1, r0, r3 */
+#define TCG_TARGET_HAS_neg_i64          0 /* sub r1, r0, r3 */
+#define TCG_TARGET_HAS_not_i32          0 /* xor r1, -1, r3 */
+#define TCG_TARGET_HAS_not_i64          0 /* xor r1, -1, r3 */
 
 /* Note: must be synced with dyngen-exec.h */
 #define TCG_AREG0 TCG_REG_R7
diff --git a/tcg/mips/tcg-target.h b/tcg/mips/tcg-target.h
index 8cb7d88..43c5501 100644
--- a/tcg/mips/tcg-target.h
+++ b/tcg/mips/tcg-target.h
@@ -78,23 +78,24 @@ enum {
 #define TCG_TARGET_CALL_ALIGN_ARGS 1
 
 /* optional instructions */
-#define TCG_TARGET_HAS_div_i32
-#define TCG_TARGET_HAS_not_i32
-#define TCG_TARGET_HAS_nor_i32
-#undef TCG_TARGET_HAS_rot_i32
-#define TCG_TARGET_HAS_ext8s_i32
-#define TCG_TARGET_HAS_ext16s_i32
-#undef TCG_TARGET_HAS_bswap32_i32
-#undef TCG_TARGET_HAS_bswap16_i32
-#undef TCG_TARGET_HAS_andc_i32
-#undef TCG_TARGET_HAS_orc_i32
-#undef TCG_TARGET_HAS_eqv_i32
-#undef TCG_TARGET_HAS_nand_i32
+#define TCG_TARGET_HAS_div_i32          1
+#define TCG_TARGET_HAS_not_i32          1
+#define TCG_TARGET_HAS_nor_i32          1
+#define TCG_TARGET_HAS_rot_i32          0
+#define TCG_TARGET_HAS_ext8s_i32        1
+#define TCG_TARGET_HAS_ext16s_i32       1
+#define TCG_TARGET_HAS_bswap32_i32      0
+#define TCG_TARGET_HAS_bswap16_i32      0
+#define TCG_TARGET_HAS_andc_i32         0
+#define TCG_TARGET_HAS_orc_i32          0
+#define TCG_TARGET_HAS_eqv_i32          0
+#define TCG_TARGET_HAS_nand_i32         0
+#define TCG_TARGET_HAS_deposit_i32      0
 
 /* optional instructions automatically implemented */
-#undef TCG_TARGET_HAS_neg_i32      /* sub  rd, zero, rt   */
-#undef TCG_TARGET_HAS_ext8u_i32    /* andi rt, rs, 0xff   */
-#undef TCG_TARGET_HAS_ext16u_i32   /* andi rt, rs, 0xffff */
+#define TCG_TARGET_HAS_neg_i32          0 /* sub  rd, zero, rt   */
+#define TCG_TARGET_HAS_ext8u_i32        0 /* andi rt, rs, 0xff   */
+#define TCG_TARGET_HAS_ext16u_i32       0 /* andi rt, rs, 0xffff */
 
 /* Note: must be synced with dyngen-exec.h */
 #define TCG_AREG0 TCG_REG_S0
diff --git a/tcg/optimize.c b/tcg/optimize.c
index 98c7e3f..32f928f 100644
--- a/tcg/optimize.c
+++ b/tcg/optimize.c
@@ -31,14 +31,9 @@
 #include "qemu-common.h"
 #include "tcg-op.h"
 
-#if TCG_TARGET_REG_BITS == 64
 #define CASE_OP_32_64(x)                        \
         glue(glue(case INDEX_op_, x), _i32):    \
         glue(glue(case INDEX_op_, x), _i64)
-#else
-#define CASE_OP_32_64(x)                        \
-        glue(glue(case INDEX_op_, x), _i32)
-#endif
 
 typedef enum {
     TCG_TEMP_UNDEF = 0,
@@ -103,10 +98,8 @@ static int op_to_movi(int op)
     switch (op_bits(op)) {
     case 32:
         return INDEX_op_movi_i32;
-#if TCG_TARGET_REG_BITS == 64
     case 64:
         return INDEX_op_movi_i64;
-#endif
     default:
         fprintf(stderr, "op_to_movi: unexpected return value of "
                 "function op_bits.\n");
@@ -155,10 +148,8 @@ static int op_to_mov(int op)
     switch (op_bits(op)) {
     case 32:
         return INDEX_op_mov_i32;
-#if TCG_TARGET_REG_BITS == 64
     case 64:
         return INDEX_op_mov_i64;
-#endif
     default:
         fprintf(stderr, "op_to_mov: unexpected return value of "
                 "function op_bits.\n");
@@ -190,124 +181,57 @@ static TCGArg do_constant_folding_2(int op, TCGArg x, TCGArg y)
     case INDEX_op_shl_i32:
         return (uint32_t)x << (uint32_t)y;
 
-#if TCG_TARGET_REG_BITS == 64
     case INDEX_op_shl_i64:
         return (uint64_t)x << (uint64_t)y;
-#endif
 
     case INDEX_op_shr_i32:
         return (uint32_t)x >> (uint32_t)y;
 
-#if TCG_TARGET_REG_BITS == 64
     case INDEX_op_shr_i64:
         return (uint64_t)x >> (uint64_t)y;
-#endif
 
     case INDEX_op_sar_i32:
         return (int32_t)x >> (int32_t)y;
 
-#if TCG_TARGET_REG_BITS == 64
     case INDEX_op_sar_i64:
         return (int64_t)x >> (int64_t)y;
-#endif
 
-#ifdef TCG_TARGET_HAS_rot_i32
     case INDEX_op_rotr_i32:
-#if TCG_TARGET_REG_BITS == 64
-        x &= 0xffffffff;
-        y &= 0xffffffff;
-#endif
-        x = (x << (32 - y)) | (x >> y);
+        x = ((uint32_t)x << (32 - y)) | ((uint32_t)x >> y);
         return x;
-#endif
 
-#ifdef TCG_TARGET_HAS_rot_i64
-#if TCG_TARGET_REG_BITS == 64
     case INDEX_op_rotr_i64:
-        x = (x << (64 - y)) | (x >> y);
+        x = ((uint64_t)x << (64 - y)) | ((uint64_t)x >> y);
         return x;
-#endif
-#endif
 
-#ifdef TCG_TARGET_HAS_rot_i32
     case INDEX_op_rotl_i32:
-#if TCG_TARGET_REG_BITS == 64
-        x &= 0xffffffff;
-        y &= 0xffffffff;
-#endif
-        x = (x << y) | (x >> (32 - y));
+        x = ((uint32_t)x << y) | ((uint32_t)x >> (32 - y));
         return x;
-#endif
 
-#ifdef TCG_TARGET_HAS_rot_i64
-#if TCG_TARGET_REG_BITS == 64
     case INDEX_op_rotl_i64:
-        x = (x << y) | (x >> (64 - y));
+        x = ((uint64_t)x << y) | ((uint64_t)x >> (64 - y));
         return x;
-#endif
-#endif
-
-#if defined(TCG_TARGET_HAS_not_i32) || defined(TCG_TARGET_HAS_not_i64)
-#ifdef TCG_TARGET_HAS_not_i32
-    case INDEX_op_not_i32:
-#endif
-#ifdef TCG_TARGET_HAS_not_i64
-    case INDEX_op_not_i64:
-#endif
+
+    CASE_OP_32_64(not):
         return ~x;
-#endif
-
-#if defined(TCG_TARGET_HAS_ext8s_i32) || defined(TCG_TARGET_HAS_ext8s_i64)
-#ifdef TCG_TARGET_HAS_ext8s_i32
-    case INDEX_op_ext8s_i32:
-#endif
-#ifdef TCG_TARGET_HAS_ext8s_i64
-    case INDEX_op_ext8s_i64:
-#endif
+
+    CASE_OP_32_64(ext8s):
         return (int8_t)x;
-#endif
-
-#if defined(TCG_TARGET_HAS_ext16s_i32) || defined(TCG_TARGET_HAS_ext16s_i64)
-#ifdef TCG_TARGET_HAS_ext16s_i32
-    case INDEX_op_ext16s_i32:
-#endif
-#ifdef TCG_TARGET_HAS_ext16s_i64
-    case INDEX_op_ext16s_i64:
-#endif
+
+    CASE_OP_32_64(ext16s):
         return (int16_t)x;
-#endif
-
-#if defined(TCG_TARGET_HAS_ext8u_i32) || defined(TCG_TARGET_HAS_ext8u_i64)
-#ifdef TCG_TARGET_HAS_ext8u_i32
-    case INDEX_op_ext8u_i32:
-#endif
-#ifdef TCG_TARGET_HAS_ext8u_i64
-    case INDEX_op_ext8u_i64:
-#endif
+
+    CASE_OP_32_64(ext8u):
         return (uint8_t)x;
-#endif
-
-#if defined(TCG_TARGET_HAS_ext16u_i32) || defined(TCG_TARGET_HAS_ext16u_i64)
-#ifdef TCG_TARGET_HAS_ext16u_i32
-    case INDEX_op_ext16u_i32:
-#endif
-#ifdef TCG_TARGET_HAS_ext16u_i64
-    case INDEX_op_ext16u_i64:
-#endif
+
+    CASE_OP_32_64(ext16u):
         return (uint16_t)x;
-#endif
 
-#if TCG_TARGET_REG_BITS == 64
-#ifdef TCG_TARGET_HAS_ext32s_i64
     case INDEX_op_ext32s_i64:
         return (int32_t)x;
-#endif
 
-#ifdef TCG_TARGET_HAS_ext32u_i64
     case INDEX_op_ext32u_i64:
         return (uint32_t)x;
-#endif
-#endif
 
     default:
         fprintf(stderr,
@@ -319,11 +243,9 @@ static TCGArg do_constant_folding_2(int op, TCGArg x, TCGArg y)
 static TCGArg do_constant_folding(int op, TCGArg x, TCGArg y)
 {
     TCGArg res = do_constant_folding_2(op, x, y);
-#if TCG_TARGET_REG_BITS == 64
     if (op_bits(op) == 32) {
         res &= 0xffffffff;
     }
-#endif
     return res;
 }
 
@@ -385,14 +307,8 @@ static TCGArg *tcg_constant_folding(TCGContext *s, uint16_t *tcg_opc_ptr,
         CASE_OP_32_64(shl):
         CASE_OP_32_64(shr):
         CASE_OP_32_64(sar):
-#ifdef TCG_TARGET_HAS_rot_i32
-        case INDEX_op_rotl_i32:
-        case INDEX_op_rotr_i32:
-#endif
-#ifdef TCG_TARGET_HAS_rot_i64
-        case INDEX_op_rotl_i64:
-        case INDEX_op_rotr_i64:
-#endif
+        CASE_OP_32_64(rotl):
+        CASE_OP_32_64(rotr):
             if (temps[args[1]].state == TCG_TEMP_CONST) {
                 /* Proceed with possible constant folding. */
                 break;
@@ -473,34 +389,12 @@ static TCGArg *tcg_constant_folding(TCGContext *s, uint16_t *tcg_opc_ptr,
             args += 2;
             break;
         CASE_OP_32_64(not):
-#ifdef TCG_TARGET_HAS_ext8s_i32
-        case INDEX_op_ext8s_i32:
-#endif
-#ifdef TCG_TARGET_HAS_ext8s_i64
-        case INDEX_op_ext8s_i64:
-#endif
-#ifdef TCG_TARGET_HAS_ext16s_i32
-        case INDEX_op_ext16s_i32:
-#endif
-#ifdef TCG_TARGET_HAS_ext16s_i64
-        case INDEX_op_ext16s_i64:
-#endif
-#ifdef TCG_TARGET_HAS_ext8u_i32
-        case INDEX_op_ext8u_i32:
-#endif
-#ifdef TCG_TARGET_HAS_ext8u_i64
-        case INDEX_op_ext8u_i64:
-#endif
-#ifdef TCG_TARGET_HAS_ext16u_i32
-        case INDEX_op_ext16u_i32:
-#endif
-#ifdef TCG_TARGET_HAS_ext16u_i64
-        case INDEX_op_ext16u_i64:
-#endif
-#if TCG_TARGET_REG_BITS == 64
+        CASE_OP_32_64(ext8s):
+        CASE_OP_32_64(ext8u):
+        CASE_OP_32_64(ext16s):
+        CASE_OP_32_64(ext16u):
         case INDEX_op_ext32s_i64:
         case INDEX_op_ext32u_i64:
-#endif
             if (temps[args[1]].state == TCG_TEMP_CONST) {
                 gen_opc_buf[op_index] = op_to_movi(op);
                 tmp = do_constant_folding(op, temps[args[1]].val, 0);
@@ -525,14 +419,8 @@ static TCGArg *tcg_constant_folding(TCGContext *s, uint16_t *tcg_opc_ptr,
         CASE_OP_32_64(shl):
         CASE_OP_32_64(shr):
         CASE_OP_32_64(sar):
-#ifdef TCG_TARGET_HAS_rot_i32
-        case INDEX_op_rotl_i32:
-        case INDEX_op_rotr_i32:
-#endif
-#ifdef TCG_TARGET_HAS_rot_i64
-        case INDEX_op_rotl_i64:
-        case INDEX_op_rotr_i64:
-#endif
+        CASE_OP_32_64(rotl):
+        CASE_OP_32_64(rotr):
             if (temps[args[1]].state == TCG_TEMP_CONST
                 && temps[args[2]].state == TCG_TEMP_CONST) {
                 gen_opc_buf[op_index] = op_to_movi(op);
diff --git a/tcg/ppc/tcg-target.h b/tcg/ppc/tcg-target.h
index a1f8599..8c35c4e 100644
--- a/tcg/ppc/tcg-target.h
+++ b/tcg/ppc/tcg-target.h
@@ -77,21 +77,22 @@ enum {
 #endif
 
 /* optional instructions */
-#define TCG_TARGET_HAS_div_i32
-#define TCG_TARGET_HAS_rot_i32
-#define TCG_TARGET_HAS_ext8s_i32
-#define TCG_TARGET_HAS_ext16s_i32
-#define TCG_TARGET_HAS_ext8u_i32
-#define TCG_TARGET_HAS_ext16u_i32
-#define TCG_TARGET_HAS_bswap16_i32
-#define TCG_TARGET_HAS_bswap32_i32
-#define TCG_TARGET_HAS_not_i32
-#define TCG_TARGET_HAS_neg_i32
-#define TCG_TARGET_HAS_andc_i32
-#define TCG_TARGET_HAS_orc_i32
-#define TCG_TARGET_HAS_eqv_i32
-#define TCG_TARGET_HAS_nand_i32
-#define TCG_TARGET_HAS_nor_i32
+#define TCG_TARGET_HAS_div_i32          1
+#define TCG_TARGET_HAS_rot_i32          1
+#define TCG_TARGET_HAS_ext8s_i32        1
+#define TCG_TARGET_HAS_ext16s_i32       1
+#define TCG_TARGET_HAS_ext8u_i32        1
+#define TCG_TARGET_HAS_ext16u_i32       1
+#define TCG_TARGET_HAS_bswap16_i32      1
+#define TCG_TARGET_HAS_bswap32_i32      1
+#define TCG_TARGET_HAS_not_i32          1
+#define TCG_TARGET_HAS_neg_i32          1
+#define TCG_TARGET_HAS_andc_i32         1
+#define TCG_TARGET_HAS_orc_i32          1
+#define TCG_TARGET_HAS_eqv_i32          1
+#define TCG_TARGET_HAS_nand_i32         1
+#define TCG_TARGET_HAS_nor_i32          1
+#define TCG_TARGET_HAS_deposit_i32      0
 
 #define TCG_AREG0 TCG_REG_R27
 
diff --git a/tcg/ppc64/tcg-target.h b/tcg/ppc64/tcg-target.h
index 8a6db11..041fe9d 100644
--- a/tcg/ppc64/tcg-target.h
+++ b/tcg/ppc64/tcg-target.h
@@ -68,40 +68,42 @@ enum {
 #define TCG_TARGET_CALL_STACK_OFFSET 48
 
 /* optional instructions */
-#define TCG_TARGET_HAS_div_i32
-/* #define TCG_TARGET_HAS_rot_i32 */
-#define TCG_TARGET_HAS_ext8s_i32
-#define TCG_TARGET_HAS_ext16s_i32
-/* #define TCG_TARGET_HAS_ext8u_i32 */
-/* #define TCG_TARGET_HAS_ext16u_i32 */
-/* #define TCG_TARGET_HAS_bswap16_i32 */
-/* #define TCG_TARGET_HAS_bswap32_i32 */
-/* #define TCG_TARGET_HAS_not_i32 */
-#define TCG_TARGET_HAS_neg_i32
-/* #define TCG_TARGET_HAS_andc_i32 */
-/* #define TCG_TARGET_HAS_orc_i32 */
-/* #define TCG_TARGET_HAS_eqv_i32 */
-/* #define TCG_TARGET_HAS_nand_i32 */
-/* #define TCG_TARGET_HAS_nor_i32 */
+#define TCG_TARGET_HAS_div_i32          1
+#define TCG_TARGET_HAS_rot_i32          0
+#define TCG_TARGET_HAS_ext8s_i32        1
+#define TCG_TARGET_HAS_ext16s_i32       1
+#define TCG_TARGET_HAS_ext8u_i32        0
+#define TCG_TARGET_HAS_ext16u_i32       0
+#define TCG_TARGET_HAS_bswap16_i32      0
+#define TCG_TARGET_HAS_bswap32_i32      0
+#define TCG_TARGET_HAS_not_i32          0
+#define TCG_TARGET_HAS_neg_i32          1
+#define TCG_TARGET_HAS_andc_i32         0
+#define TCG_TARGET_HAS_orc_i32          0
+#define TCG_TARGET_HAS_eqv_i32          0
+#define TCG_TARGET_HAS_nand_i32         0
+#define TCG_TARGET_HAS_nor_i32          0
+#define TCG_TARGET_HAS_deposit_i32      0
 
-#define TCG_TARGET_HAS_div_i64
-/* #define TCG_TARGET_HAS_rot_i64 */
-#define TCG_TARGET_HAS_ext8s_i64
-#define TCG_TARGET_HAS_ext16s_i64
-#define TCG_TARGET_HAS_ext32s_i64
-/* #define TCG_TARGET_HAS_ext8u_i64 */
-/* #define TCG_TARGET_HAS_ext16u_i64 */
-/* #define TCG_TARGET_HAS_ext32u_i64 */
-/* #define TCG_TARGET_HAS_bswap16_i64 */
-/* #define TCG_TARGET_HAS_bswap32_i64 */
-/* #define TCG_TARGET_HAS_bswap64_i64 */
-/* #define TCG_TARGET_HAS_not_i64 */
-#define TCG_TARGET_HAS_neg_i64
-/* #define TCG_TARGET_HAS_andc_i64 */
-/* #define TCG_TARGET_HAS_orc_i64 */
-/* #define TCG_TARGET_HAS_eqv_i64 */
-/* #define TCG_TARGET_HAS_nand_i64 */
-/* #define TCG_TARGET_HAS_nor_i64 */
+#define TCG_TARGET_HAS_div_i64          1
+#define TCG_TARGET_HAS_rot_i64          0
+#define TCG_TARGET_HAS_ext8s_i64        1
+#define TCG_TARGET_HAS_ext16s_i64       1
+#define TCG_TARGET_HAS_ext32s_i64       1
+#define TCG_TARGET_HAS_ext8u_i64        0
+#define TCG_TARGET_HAS_ext16u_i64       0
+#define TCG_TARGET_HAS_ext32u_i64       0
+#define TCG_TARGET_HAS_bswap16_i64      0
+#define TCG_TARGET_HAS_bswap32_i64      0
+#define TCG_TARGET_HAS_bswap64_i64      0
+#define TCG_TARGET_HAS_not_i64          0
+#define TCG_TARGET_HAS_neg_i64          1
+#define TCG_TARGET_HAS_andc_i64         0
+#define TCG_TARGET_HAS_orc_i64          0
+#define TCG_TARGET_HAS_eqv_i64          0
+#define TCG_TARGET_HAS_nand_i64         0
+#define TCG_TARGET_HAS_nor_i64          0
+#define TCG_TARGET_HAS_deposit_i64      0
 
 #define TCG_AREG0 TCG_REG_R27
 
diff --git a/tcg/s390/tcg-target.h b/tcg/s390/tcg-target.h
index 4e45cf3..35ebac3 100644
--- a/tcg/s390/tcg-target.h
+++ b/tcg/s390/tcg-target.h
@@ -53,41 +53,43 @@ typedef enum TCGReg {
 #define TCG_TARGET_NB_REGS 16
 
 /* optional instructions */
-#define TCG_TARGET_HAS_div2_i32
-#define TCG_TARGET_HAS_rot_i32
-#define TCG_TARGET_HAS_ext8s_i32
-#define TCG_TARGET_HAS_ext16s_i32
-#define TCG_TARGET_HAS_ext8u_i32
-#define TCG_TARGET_HAS_ext16u_i32
-#define TCG_TARGET_HAS_bswap16_i32
-#define TCG_TARGET_HAS_bswap32_i32
-// #define TCG_TARGET_HAS_not_i32
-#define TCG_TARGET_HAS_neg_i32
-// #define TCG_TARGET_HAS_andc_i32
-// #define TCG_TARGET_HAS_orc_i32
-// #define TCG_TARGET_HAS_eqv_i32
-// #define TCG_TARGET_HAS_nand_i32
-// #define TCG_TARGET_HAS_nor_i32
+#define TCG_TARGET_HAS_div2_i32         1
+#define TCG_TARGET_HAS_rot_i32          1
+#define TCG_TARGET_HAS_ext8s_i32        1
+#define TCG_TARGET_HAS_ext16s_i32       1
+#define TCG_TARGET_HAS_ext8u_i32        1
+#define TCG_TARGET_HAS_ext16u_i32       1
+#define TCG_TARGET_HAS_bswap16_i32      1
+#define TCG_TARGET_HAS_bswap32_i32      1
+#define TCG_TARGET_HAS_not_i32          0
+#define TCG_TARGET_HAS_neg_i32          1
+#define TCG_TARGET_HAS_andc_i32         0
+#define TCG_TARGET_HAS_orc_i32          0
+#define TCG_TARGET_HAS_eqv_i32          0
+#define TCG_TARGET_HAS_nand_i32         0
+#define TCG_TARGET_HAS_nor_i32          0
+#define TCG_TARGET_HAS_deposit_i32      0
 
 #if TCG_TARGET_REG_BITS == 64
-#define TCG_TARGET_HAS_div2_i64
-#define TCG_TARGET_HAS_rot_i64
-#define TCG_TARGET_HAS_ext8s_i64
-#define TCG_TARGET_HAS_ext16s_i64
-#define TCG_TARGET_HAS_ext32s_i64
-#define TCG_TARGET_HAS_ext8u_i64
-#define TCG_TARGET_HAS_ext16u_i64
-#define TCG_TARGET_HAS_ext32u_i64
-#define TCG_TARGET_HAS_bswap16_i64
-#define TCG_TARGET_HAS_bswap32_i64
-#define TCG_TARGET_HAS_bswap64_i64
-// #define TCG_TARGET_HAS_not_i64
-#define TCG_TARGET_HAS_neg_i64
-// #define TCG_TARGET_HAS_andc_i64
-// #define TCG_TARGET_HAS_orc_i64
-// #define TCG_TARGET_HAS_eqv_i64
-// #define TCG_TARGET_HAS_nand_i64
-// #define TCG_TARGET_HAS_nor_i64
+#define TCG_TARGET_HAS_div2_i64         1
+#define TCG_TARGET_HAS_rot_i64          1
+#define TCG_TARGET_HAS_ext8s_i64        1
+#define TCG_TARGET_HAS_ext16s_i64       1
+#define TCG_TARGET_HAS_ext32s_i64       1
+#define TCG_TARGET_HAS_ext8u_i64        1
+#define TCG_TARGET_HAS_ext16u_i64       1
+#define TCG_TARGET_HAS_ext32u_i64       1
+#define TCG_TARGET_HAS_bswap16_i64      1
+#define TCG_TARGET_HAS_bswap32_i64      1
+#define TCG_TARGET_HAS_bswap64_i64      1
+#define TCG_TARGET_HAS_not_i64          0
+#define TCG_TARGET_HAS_neg_i64          1
+#define TCG_TARGET_HAS_andc_i64         0
+#define TCG_TARGET_HAS_orc_i64          0
+#define TCG_TARGET_HAS_eqv_i64          0
+#define TCG_TARGET_HAS_nand_i64         0
+#define TCG_TARGET_HAS_nor_i64          0
+#define TCG_TARGET_HAS_deposit_i64      0
 #endif
 
 #define TCG_TARGET_HAS_GUEST_BASE
diff --git a/tcg/sparc/tcg-target.h b/tcg/sparc/tcg-target.h
index df0785e..7b4e7f9 100644
--- a/tcg/sparc/tcg-target.h
+++ b/tcg/sparc/tcg-target.h
@@ -92,41 +92,43 @@ enum {
 #endif
 
 /* optional instructions */
-#define TCG_TARGET_HAS_div_i32
-// #define TCG_TARGET_HAS_rot_i32
-// #define TCG_TARGET_HAS_ext8s_i32
-// #define TCG_TARGET_HAS_ext16s_i32
-// #define TCG_TARGET_HAS_ext8u_i32
-// #define TCG_TARGET_HAS_ext16u_i32
-// #define TCG_TARGET_HAS_bswap16_i32
-// #define TCG_TARGET_HAS_bswap32_i32
-#define TCG_TARGET_HAS_neg_i32
-#define TCG_TARGET_HAS_not_i32
-#define TCG_TARGET_HAS_andc_i32
-#define TCG_TARGET_HAS_orc_i32
-// #define TCG_TARGET_HAS_eqv_i32
-// #define TCG_TARGET_HAS_nand_i32
-// #define TCG_TARGET_HAS_nor_i32
+#define TCG_TARGET_HAS_div_i32		1
+#define TCG_TARGET_HAS_rot_i32          0
+#define TCG_TARGET_HAS_ext8s_i32        0
+#define TCG_TARGET_HAS_ext16s_i32       0
+#define TCG_TARGET_HAS_ext8u_i32        0
+#define TCG_TARGET_HAS_ext16u_i32       0
+#define TCG_TARGET_HAS_bswap16_i32      0
+#define TCG_TARGET_HAS_bswap32_i32      0
+#define TCG_TARGET_HAS_neg_i32          1
+#define TCG_TARGET_HAS_not_i32          1
+#define TCG_TARGET_HAS_andc_i32         1
+#define TCG_TARGET_HAS_orc_i32          1
+#define TCG_TARGET_HAS_eqv_i32          0
+#define TCG_TARGET_HAS_nand_i32         0
+#define TCG_TARGET_HAS_nor_i32          0
+#define TCG_TARGET_HAS_deposit_i32      0
 
 #if TCG_TARGET_REG_BITS == 64
-#define TCG_TARGET_HAS_div_i64
-// #define TCG_TARGET_HAS_rot_i64
-// #define TCG_TARGET_HAS_ext8s_i64
-// #define TCG_TARGET_HAS_ext16s_i64
-#define TCG_TARGET_HAS_ext32s_i64
-// #define TCG_TARGET_HAS_ext8u_i64
-// #define TCG_TARGET_HAS_ext16u_i64
-#define TCG_TARGET_HAS_ext32u_i64
-// #define TCG_TARGET_HAS_bswap16_i64
-// #define TCG_TARGET_HAS_bswap32_i64
-// #define TCG_TARGET_HAS_bswap64_i64
-#define TCG_TARGET_HAS_neg_i64
-#define TCG_TARGET_HAS_not_i64
-#define TCG_TARGET_HAS_andc_i64
-#define TCG_TARGET_HAS_orc_i64
-// #define TCG_TARGET_HAS_eqv_i64
-// #define TCG_TARGET_HAS_nand_i64
-// #define TCG_TARGET_HAS_nor_i64
+#define TCG_TARGET_HAS_div_i64          1
+#define TCG_TARGET_HAS_rot_i64          0
+#define TCG_TARGET_HAS_ext8s_i64        0
+#define TCG_TARGET_HAS_ext16s_i64       0
+#define TCG_TARGET_HAS_ext32s_i64       1
+#define TCG_TARGET_HAS_ext8u_i64        0
+#define TCG_TARGET_HAS_ext16u_i64       0
+#define TCG_TARGET_HAS_ext32u_i64       1
+#define TCG_TARGET_HAS_bswap16_i64      0
+#define TCG_TARGET_HAS_bswap32_i64      0
+#define TCG_TARGET_HAS_bswap64_i64      0
+#define TCG_TARGET_HAS_neg_i64          1
+#define TCG_TARGET_HAS_not_i64          1
+#define TCG_TARGET_HAS_andc_i64         1
+#define TCG_TARGET_HAS_orc_i64          1
+#define TCG_TARGET_HAS_eqv_i64          0
+#define TCG_TARGET_HAS_nand_i64         0
+#define TCG_TARGET_HAS_nor_i64          0
+#define TCG_TARGET_HAS_deposit_i64      0
 #endif
 
 /* Note: must be synced with dyngen-exec.h */
diff --git a/tcg/tcg-op.h b/tcg/tcg-op.h
index ebf5e13..404b637 100644
--- a/tcg/tcg-op.h
+++ b/tcg/tcg-op.h
@@ -664,107 +664,81 @@ static inline void tcg_gen_muli_i32(TCGv_i32 ret, TCGv_i32 arg1, int32_t arg2)
     tcg_temp_free_i32(t0);
 }
 
-#ifdef TCG_TARGET_HAS_div_i32
 static inline void tcg_gen_div_i32(TCGv_i32 ret, TCGv_i32 arg1, TCGv_i32 arg2)
 {
-    tcg_gen_op3_i32(INDEX_op_div_i32, ret, arg1, arg2);
-}
-
-static inline void tcg_gen_rem_i32(TCGv_i32 ret, TCGv_i32 arg1, TCGv_i32 arg2)
-{
-    tcg_gen_op3_i32(INDEX_op_rem_i32, ret, arg1, arg2);
-}
-
-static inline void tcg_gen_divu_i32(TCGv_i32 ret, TCGv_i32 arg1, TCGv_i32 arg2)
-{
-    tcg_gen_op3_i32(INDEX_op_divu_i32, ret, arg1, arg2);
-}
-
-static inline void tcg_gen_remu_i32(TCGv_i32 ret, TCGv_i32 arg1, TCGv_i32 arg2)
-{
-    tcg_gen_op3_i32(INDEX_op_remu_i32, ret, arg1, arg2);
-}
-#elif defined(TCG_TARGET_HAS_div2_i32)
-static inline void tcg_gen_div_i32(TCGv_i32 ret, TCGv_i32 arg1, TCGv_i32 arg2)
-{
-    TCGv_i32 t0;
-    t0 = tcg_temp_new_i32();
-    tcg_gen_sari_i32(t0, arg1, 31);
-    tcg_gen_op5_i32(INDEX_op_div2_i32, ret, t0, arg1, t0, arg2);
-    tcg_temp_free_i32(t0);
-}
-
-static inline void tcg_gen_rem_i32(TCGv_i32 ret, TCGv_i32 arg1, TCGv_i32 arg2)
-{
-    TCGv_i32 t0;
-    t0 = tcg_temp_new_i32();
-    tcg_gen_sari_i32(t0, arg1, 31);
-    tcg_gen_op5_i32(INDEX_op_div2_i32, t0, ret, arg1, t0, arg2);
-    tcg_temp_free_i32(t0);
-}
-
-static inline void tcg_gen_divu_i32(TCGv_i32 ret, TCGv_i32 arg1, TCGv_i32 arg2)
-{
-    TCGv_i32 t0;
-    t0 = tcg_temp_new_i32();
-    tcg_gen_movi_i32(t0, 0);
-    tcg_gen_op5_i32(INDEX_op_divu2_i32, ret, t0, arg1, t0, arg2);
-    tcg_temp_free_i32(t0);
-}
-
-static inline void tcg_gen_remu_i32(TCGv_i32 ret, TCGv_i32 arg1, TCGv_i32 arg2)
-{
-    TCGv_i32 t0;
-    t0 = tcg_temp_new_i32();
-    tcg_gen_movi_i32(t0, 0);
-    tcg_gen_op5_i32(INDEX_op_divu2_i32, t0, ret, arg1, t0, arg2);
-    tcg_temp_free_i32(t0);
-}
-#else
-static inline void tcg_gen_div_i32(TCGv_i32 ret, TCGv_i32 arg1, TCGv_i32 arg2)
-{
-    int sizemask = 0;
-    /* Return value and both arguments are 32-bit and signed.  */
-    sizemask |= tcg_gen_sizemask(0, 0, 1);
-    sizemask |= tcg_gen_sizemask(1, 0, 1);
-    sizemask |= tcg_gen_sizemask(2, 0, 1);
-
-    tcg_gen_helper32(tcg_helper_div_i32, sizemask, ret, arg1, arg2);
+    if (TCG_TARGET_HAS_div_i32) {
+        tcg_gen_op3_i32(INDEX_op_div_i32, ret, arg1, arg2);
+    } else if (TCG_TARGET_HAS_div2_i32) {
+        TCGv_i32 t0 = tcg_temp_new_i32();
+        tcg_gen_sari_i32(t0, arg1, 31);
+        tcg_gen_op5_i32(INDEX_op_div2_i32, ret, t0, arg1, t0, arg2);
+        tcg_temp_free_i32(t0);
+    } else {
+        int sizemask = 0;
+        /* Return value and both arguments are 32-bit and signed.  */
+        sizemask |= tcg_gen_sizemask(0, 0, 1);
+        sizemask |= tcg_gen_sizemask(1, 0, 1);
+        sizemask |= tcg_gen_sizemask(2, 0, 1);
+        tcg_gen_helper32(tcg_helper_div_i32, sizemask, ret, arg1, arg2);
+    }
 }
 
 static inline void tcg_gen_rem_i32(TCGv_i32 ret, TCGv_i32 arg1, TCGv_i32 arg2)
 {
-    int sizemask = 0;
-    /* Return value and both arguments are 32-bit and signed.  */
-    sizemask |= tcg_gen_sizemask(0, 0, 1);
-    sizemask |= tcg_gen_sizemask(1, 0, 1);
-    sizemask |= tcg_gen_sizemask(2, 0, 1);
-
-    tcg_gen_helper32(tcg_helper_rem_i32, sizemask, ret, arg1, arg2);
+    if (TCG_TARGET_HAS_div_i32) {
+        tcg_gen_op3_i32(INDEX_op_rem_i32, ret, arg1, arg2);
+    } else if (TCG_TARGET_HAS_div2_i32) {
+        TCGv_i32 t0 = tcg_temp_new_i32();
+        tcg_gen_sari_i32(t0, arg1, 31);
+        tcg_gen_op5_i32(INDEX_op_div2_i32, t0, ret, arg1, t0, arg2);
+        tcg_temp_free_i32(t0);
+    } else {
+        int sizemask = 0;
+        /* Return value and both arguments are 32-bit and signed.  */
+        sizemask |= tcg_gen_sizemask(0, 0, 1);
+        sizemask |= tcg_gen_sizemask(1, 0, 1);
+        sizemask |= tcg_gen_sizemask(2, 0, 1);
+        tcg_gen_helper32(tcg_helper_rem_i32, sizemask, ret, arg1, arg2);
+    }
 }
 
 static inline void tcg_gen_divu_i32(TCGv_i32 ret, TCGv_i32 arg1, TCGv_i32 arg2)
 {
-    int sizemask = 0;
-    /* Return value and both arguments are 32-bit and unsigned.  */
-    sizemask |= tcg_gen_sizemask(0, 0, 0);
-    sizemask |= tcg_gen_sizemask(1, 0, 0);
-    sizemask |= tcg_gen_sizemask(2, 0, 0);
-
-    tcg_gen_helper32(tcg_helper_divu_i32, sizemask, ret, arg1, arg2);
+    if (TCG_TARGET_HAS_div_i32) {
+        tcg_gen_op3_i32(INDEX_op_divu_i32, ret, arg1, arg2);
+    } else if (TCG_TARGET_HAS_div2_i32) {
+        TCGv_i32 t0 = tcg_temp_new_i32();
+        tcg_gen_movi_i32(t0, 0);
+        tcg_gen_op5_i32(INDEX_op_divu2_i32, ret, t0, arg1, t0, arg2);
+        tcg_temp_free_i32(t0);
+    } else {
+        int sizemask = 0;
+        /* Return value and both arguments are 32-bit and unsigned.  */
+        sizemask |= tcg_gen_sizemask(0, 0, 0);
+        sizemask |= tcg_gen_sizemask(1, 0, 0);
+        sizemask |= tcg_gen_sizemask(2, 0, 0);
+        tcg_gen_helper32(tcg_helper_divu_i32, sizemask, ret, arg1, arg2);
+    }
 }
 
 static inline void tcg_gen_remu_i32(TCGv_i32 ret, TCGv_i32 arg1, TCGv_i32 arg2)
 {
-    int sizemask = 0;
-    /* Return value and both arguments are 32-bit and unsigned.  */
-    sizemask |= tcg_gen_sizemask(0, 0, 0);
-    sizemask |= tcg_gen_sizemask(1, 0, 0);
-    sizemask |= tcg_gen_sizemask(2, 0, 0);
-
-    tcg_gen_helper32(tcg_helper_remu_i32, sizemask, ret, arg1, arg2);
+    if (TCG_TARGET_HAS_div_i32) {
+        tcg_gen_op3_i32(INDEX_op_remu_i32, ret, arg1, arg2);
+    } else if (TCG_TARGET_HAS_div2_i32) {
+        TCGv_i32 t0 = tcg_temp_new_i32();
+        tcg_gen_movi_i32(t0, 0);
+        tcg_gen_op5_i32(INDEX_op_divu2_i32, t0, ret, arg1, t0, arg2);
+        tcg_temp_free_i32(t0);
+    } else {
+        int sizemask = 0;
+        /* Return value and both arguments are 32-bit and unsigned.  */
+        sizemask |= tcg_gen_sizemask(0, 0, 0);
+        sizemask |= tcg_gen_sizemask(1, 0, 0);
+        sizemask |= tcg_gen_sizemask(2, 0, 0);
+        tcg_gen_helper32(tcg_helper_remu_i32, sizemask, ret, arg1, arg2);
+    }
 }
-#endif
 
 #if TCG_TARGET_REG_BITS == 32
 
@@ -1250,109 +1224,82 @@ static inline void tcg_gen_mul_i64(TCGv_i64 ret, TCGv_i64 arg1, TCGv_i64 arg2)
     tcg_gen_op3_i64(INDEX_op_mul_i64, ret, arg1, arg2);
 }
 
-#ifdef TCG_TARGET_HAS_div_i64
-static inline void tcg_gen_div_i64(TCGv_i64 ret, TCGv_i64 arg1, TCGv_i64 arg2)
-{
-    tcg_gen_op3_i64(INDEX_op_div_i64, ret, arg1, arg2);
-}
-
-static inline void tcg_gen_rem_i64(TCGv_i64 ret, TCGv_i64 arg1, TCGv_i64 arg2)
-{
-    tcg_gen_op3_i64(INDEX_op_rem_i64, ret, arg1, arg2);
-}
-
-static inline void tcg_gen_divu_i64(TCGv_i64 ret, TCGv_i64 arg1, TCGv_i64 arg2)
-{
-    tcg_gen_op3_i64(INDEX_op_divu_i64, ret, arg1, arg2);
-}
-
-static inline void tcg_gen_remu_i64(TCGv_i64 ret, TCGv_i64 arg1, TCGv_i64 arg2)
-{
-    tcg_gen_op3_i64(INDEX_op_remu_i64, ret, arg1, arg2);
-}
-#elif defined(TCG_TARGET_HAS_div2_i64)
-static inline void tcg_gen_div_i64(TCGv_i64 ret, TCGv_i64 arg1, TCGv_i64 arg2)
-{
-    TCGv_i64 t0;
-    t0 = tcg_temp_new_i64();
-    tcg_gen_sari_i64(t0, arg1, 63);
-    tcg_gen_op5_i64(INDEX_op_div2_i64, ret, t0, arg1, t0, arg2);
-    tcg_temp_free_i64(t0);
-}
-
-static inline void tcg_gen_rem_i64(TCGv_i64 ret, TCGv_i64 arg1, TCGv_i64 arg2)
-{
-    TCGv_i64 t0;
-    t0 = tcg_temp_new_i64();
-    tcg_gen_sari_i64(t0, arg1, 63);
-    tcg_gen_op5_i64(INDEX_op_div2_i64, t0, ret, arg1, t0, arg2);
-    tcg_temp_free_i64(t0);
-}
-
-static inline void tcg_gen_divu_i64(TCGv_i64 ret, TCGv_i64 arg1, TCGv_i64 arg2)
-{
-    TCGv_i64 t0;
-    t0 = tcg_temp_new_i64();
-    tcg_gen_movi_i64(t0, 0);
-    tcg_gen_op5_i64(INDEX_op_divu2_i64, ret, t0, arg1, t0, arg2);
-    tcg_temp_free_i64(t0);
-}
-
-static inline void tcg_gen_remu_i64(TCGv_i64 ret, TCGv_i64 arg1, TCGv_i64 arg2)
-{
-    TCGv_i64 t0;
-    t0 = tcg_temp_new_i64();
-    tcg_gen_movi_i64(t0, 0);
-    tcg_gen_op5_i64(INDEX_op_divu2_i64, t0, ret, arg1, t0, arg2);
-    tcg_temp_free_i64(t0);
-}
-#else
 static inline void tcg_gen_div_i64(TCGv_i64 ret, TCGv_i64 arg1, TCGv_i64 arg2)
 {
-    int sizemask = 0;
-    /* Return value and both arguments are 64-bit and signed.  */
-    sizemask |= tcg_gen_sizemask(0, 1, 1);
-    sizemask |= tcg_gen_sizemask(1, 1, 1);
-    sizemask |= tcg_gen_sizemask(2, 1, 1);
-
-    tcg_gen_helper64(tcg_helper_div_i64, sizemask, ret, arg1, arg2);
+    if (TCG_TARGET_HAS_div_i64) {
+        tcg_gen_op3_i64(INDEX_op_div_i64, ret, arg1, arg2);
+    } else if (TCG_TARGET_HAS_div2_i64) {
+        TCGv_i64 t0 = tcg_temp_new_i64();
+        tcg_gen_sari_i64(t0, arg1, 63);
+        tcg_gen_op5_i64(INDEX_op_div2_i64, ret, t0, arg1, t0, arg2);
+        tcg_temp_free_i64(t0);
+    } else {
+        int sizemask = 0;
+        /* Return value and both arguments are 64-bit and signed.  */
+        sizemask |= tcg_gen_sizemask(0, 1, 1);
+        sizemask |= tcg_gen_sizemask(1, 1, 1);
+        sizemask |= tcg_gen_sizemask(2, 1, 1);
+        tcg_gen_helper64(tcg_helper_div_i64, sizemask, ret, arg1, arg2);
+    }
 }
 
 static inline void tcg_gen_rem_i64(TCGv_i64 ret, TCGv_i64 arg1, TCGv_i64 arg2)
 {
-    int sizemask = 0;
-    /* Return value and both arguments are 64-bit and signed.  */
-    sizemask |= tcg_gen_sizemask(0, 1, 1);
-    sizemask |= tcg_gen_sizemask(1, 1, 1);
-    sizemask |= tcg_gen_sizemask(2, 1, 1);
-
-    tcg_gen_helper64(tcg_helper_rem_i64, sizemask, ret, arg1, arg2);
+    if (TCG_TARGET_HAS_div_i64) {
+        tcg_gen_op3_i64(INDEX_op_rem_i64, ret, arg1, arg2);
+    } else if (TCG_TARGET_HAS_div2_i64) {
+        TCGv_i64 t0 = tcg_temp_new_i64();
+        tcg_gen_sari_i64(t0, arg1, 63);
+        tcg_gen_op5_i64(INDEX_op_div2_i64, t0, ret, arg1, t0, arg2);
+        tcg_temp_free_i64(t0);
+    } else {
+        int sizemask = 0;
+        /* Return value and both arguments are 64-bit and signed.  */
+        sizemask |= tcg_gen_sizemask(0, 1, 1);
+        sizemask |= tcg_gen_sizemask(1, 1, 1);
+        sizemask |= tcg_gen_sizemask(2, 1, 1);
+        tcg_gen_helper64(tcg_helper_rem_i64, sizemask, ret, arg1, arg2);
+    }
 }
 
 static inline void tcg_gen_divu_i64(TCGv_i64 ret, TCGv_i64 arg1, TCGv_i64 arg2)
 {
-    int sizemask = 0;
-    /* Return value and both arguments are 64-bit and unsigned.  */
-    sizemask |= tcg_gen_sizemask(0, 1, 0);
-    sizemask |= tcg_gen_sizemask(1, 1, 0);
-    sizemask |= tcg_gen_sizemask(2, 1, 0);
-
-    tcg_gen_helper64(tcg_helper_divu_i64, sizemask, ret, arg1, arg2);
+    if (TCG_TARGET_HAS_div_i64) {
+        tcg_gen_op3_i64(INDEX_op_divu_i64, ret, arg1, arg2);
+    } else if (TCG_TARGET_HAS_div2_i64) {
+        TCGv_i64 t0 = tcg_temp_new_i64();
+        tcg_gen_movi_i64(t0, 0);
+        tcg_gen_op5_i64(INDEX_op_divu2_i64, ret, t0, arg1, t0, arg2);
+        tcg_temp_free_i64(t0);
+    } else {
+        int sizemask = 0;
+        /* Return value and both arguments are 64-bit and unsigned.  */
+        sizemask |= tcg_gen_sizemask(0, 1, 0);
+        sizemask |= tcg_gen_sizemask(1, 1, 0);
+        sizemask |= tcg_gen_sizemask(2, 1, 0);
+        tcg_gen_helper64(tcg_helper_divu_i64, sizemask, ret, arg1, arg2);
+    }
 }
 
 static inline void tcg_gen_remu_i64(TCGv_i64 ret, TCGv_i64 arg1, TCGv_i64 arg2)
 {
-    int sizemask = 0;
-    /* Return value and both arguments are 64-bit and unsigned.  */
-    sizemask |= tcg_gen_sizemask(0, 1, 0);
-    sizemask |= tcg_gen_sizemask(1, 1, 0);
-    sizemask |= tcg_gen_sizemask(2, 1, 0);
-
-    tcg_gen_helper64(tcg_helper_remu_i64, sizemask, ret, arg1, arg2);
+    if (TCG_TARGET_HAS_div_i64) {
+        tcg_gen_op3_i64(INDEX_op_remu_i64, ret, arg1, arg2);
+    } else if (TCG_TARGET_HAS_div2_i64) {
+        TCGv_i64 t0 = tcg_temp_new_i64();
+        tcg_gen_movi_i64(t0, 0);
+        tcg_gen_op5_i64(INDEX_op_divu2_i64, t0, ret, arg1, t0, arg2);
+        tcg_temp_free_i64(t0);
+    } else {
+        int sizemask = 0;
+        /* Return value and both arguments are 64-bit and unsigned.  */
+        sizemask |= tcg_gen_sizemask(0, 1, 0);
+        sizemask |= tcg_gen_sizemask(1, 1, 0);
+        sizemask |= tcg_gen_sizemask(2, 1, 0);
+        tcg_gen_helper64(tcg_helper_remu_i64, sizemask, ret, arg1, arg2);
+    }
 }
-#endif
-
-#endif
+#endif /* TCG_TARGET_REG_BITS == 32 */
 
 static inline void tcg_gen_addi_i64(TCGv_i64 ret, TCGv_i64 arg1, int64_t arg2)
 {
@@ -1413,82 +1360,82 @@ static inline void tcg_gen_muli_i64(TCGv_i64 ret, TCGv_i64 arg1, int64_t arg2)
 
 static inline void tcg_gen_ext8s_i32(TCGv_i32 ret, TCGv_i32 arg)
 {
-#ifdef TCG_TARGET_HAS_ext8s_i32
-    tcg_gen_op2_i32(INDEX_op_ext8s_i32, ret, arg);
-#else
-    tcg_gen_shli_i32(ret, arg, 24);
-    tcg_gen_sari_i32(ret, ret, 24);
-#endif
+    if (TCG_TARGET_HAS_ext8s_i32) {
+        tcg_gen_op2_i32(INDEX_op_ext8s_i32, ret, arg);
+    } else {
+        tcg_gen_shli_i32(ret, arg, 24);
+        tcg_gen_sari_i32(ret, ret, 24);
+    }
 }
 
 static inline void tcg_gen_ext16s_i32(TCGv_i32 ret, TCGv_i32 arg)
 {
-#ifdef TCG_TARGET_HAS_ext16s_i32
-    tcg_gen_op2_i32(INDEX_op_ext16s_i32, ret, arg);
-#else
-    tcg_gen_shli_i32(ret, arg, 16);
-    tcg_gen_sari_i32(ret, ret, 16);
-#endif
+    if (TCG_TARGET_HAS_ext16s_i32) {
+        tcg_gen_op2_i32(INDEX_op_ext16s_i32, ret, arg);
+    } else {
+        tcg_gen_shli_i32(ret, arg, 16);
+        tcg_gen_sari_i32(ret, ret, 16);
+    }
 }
 
 static inline void tcg_gen_ext8u_i32(TCGv_i32 ret, TCGv_i32 arg)
 {
-#ifdef TCG_TARGET_HAS_ext8u_i32
-    tcg_gen_op2_i32(INDEX_op_ext8u_i32, ret, arg);
-#else
-    tcg_gen_andi_i32(ret, arg, 0xffu);
-#endif
+    if (TCG_TARGET_HAS_ext8u_i32) {
+        tcg_gen_op2_i32(INDEX_op_ext8u_i32, ret, arg);
+    } else {
+        tcg_gen_andi_i32(ret, arg, 0xffu);
+    }
 }
 
 static inline void tcg_gen_ext16u_i32(TCGv_i32 ret, TCGv_i32 arg)
 {
-#ifdef TCG_TARGET_HAS_ext16u_i32
-    tcg_gen_op2_i32(INDEX_op_ext16u_i32, ret, arg);
-#else
-    tcg_gen_andi_i32(ret, arg, 0xffffu);
-#endif
+    if (TCG_TARGET_HAS_ext16u_i32) {
+        tcg_gen_op2_i32(INDEX_op_ext16u_i32, ret, arg);
+    } else {
+        tcg_gen_andi_i32(ret, arg, 0xffffu);
+    }
 }
 
 /* Note: we assume the two high bytes are set to zero */
 static inline void tcg_gen_bswap16_i32(TCGv_i32 ret, TCGv_i32 arg)
 {
-#ifdef TCG_TARGET_HAS_bswap16_i32
-    tcg_gen_op2_i32(INDEX_op_bswap16_i32, ret, arg);
-#else
-    TCGv_i32 t0 = tcg_temp_new_i32();
+    if (TCG_TARGET_HAS_bswap16_i32) {
+        tcg_gen_op2_i32(INDEX_op_bswap16_i32, ret, arg);
+    } else {
+        TCGv_i32 t0 = tcg_temp_new_i32();
     
-    tcg_gen_ext8u_i32(t0, arg);
-    tcg_gen_shli_i32(t0, t0, 8);
-    tcg_gen_shri_i32(ret, arg, 8);
-    tcg_gen_or_i32(ret, ret, t0);
-    tcg_temp_free_i32(t0);
-#endif
+        tcg_gen_ext8u_i32(t0, arg);
+        tcg_gen_shli_i32(t0, t0, 8);
+        tcg_gen_shri_i32(ret, arg, 8);
+        tcg_gen_or_i32(ret, ret, t0);
+        tcg_temp_free_i32(t0);
+    }
 }
 
 static inline void tcg_gen_bswap32_i32(TCGv_i32 ret, TCGv_i32 arg)
 {
-#ifdef TCG_TARGET_HAS_bswap32_i32
-    tcg_gen_op2_i32(INDEX_op_bswap32_i32, ret, arg);
-#else
-    TCGv_i32 t0, t1;
-    t0 = tcg_temp_new_i32();
-    t1 = tcg_temp_new_i32();
+    if (TCG_TARGET_HAS_bswap32_i32) {
+        tcg_gen_op2_i32(INDEX_op_bswap32_i32, ret, arg);
+    } else {
+        TCGv_i32 t0, t1;
+        t0 = tcg_temp_new_i32();
+        t1 = tcg_temp_new_i32();
     
-    tcg_gen_shli_i32(t0, arg, 24);
+        tcg_gen_shli_i32(t0, arg, 24);
     
-    tcg_gen_andi_i32(t1, arg, 0x0000ff00);
-    tcg_gen_shli_i32(t1, t1, 8);
-    tcg_gen_or_i32(t0, t0, t1);
+        tcg_gen_andi_i32(t1, arg, 0x0000ff00);
+        tcg_gen_shli_i32(t1, t1, 8);
+        tcg_gen_or_i32(t0, t0, t1);
     
-    tcg_gen_shri_i32(t1, arg, 8);
-    tcg_gen_andi_i32(t1, t1, 0x0000ff00);
-    tcg_gen_or_i32(t0, t0, t1);
+        tcg_gen_shri_i32(t1, arg, 8);
+        tcg_gen_andi_i32(t1, t1, 0x0000ff00);
+        tcg_gen_or_i32(t0, t0, t1);
     
-    tcg_gen_shri_i32(t1, arg, 24);
-    tcg_gen_or_i32(ret, t0, t1);
-    tcg_temp_free_i32(t0);
-    tcg_temp_free_i32(t1);
-#endif
+        tcg_gen_shri_i32(t1, arg, 24);
+        tcg_gen_or_i32(ret, t0, t1);
+        tcg_temp_free_i32(t0);
+        tcg_temp_free_i32(t1);
+    }
 }
 
 #if TCG_TARGET_REG_BITS == 32
@@ -1576,59 +1523,59 @@ static inline void tcg_gen_bswap64_i64(TCGv_i64 ret, TCGv_i64 arg)
 
 static inline void tcg_gen_ext8s_i64(TCGv_i64 ret, TCGv_i64 arg)
 {
-#ifdef TCG_TARGET_HAS_ext8s_i64
-    tcg_gen_op2_i64(INDEX_op_ext8s_i64, ret, arg);
-#else
-    tcg_gen_shli_i64(ret, arg, 56);
-    tcg_gen_sari_i64(ret, ret, 56);
-#endif
+    if (TCG_TARGET_HAS_ext8s_i64) {
+        tcg_gen_op2_i64(INDEX_op_ext8s_i64, ret, arg);
+    } else {
+        tcg_gen_shli_i64(ret, arg, 56);
+        tcg_gen_sari_i64(ret, ret, 56);
+    }
 }
 
 static inline void tcg_gen_ext16s_i64(TCGv_i64 ret, TCGv_i64 arg)
 {
-#ifdef TCG_TARGET_HAS_ext16s_i64
-    tcg_gen_op2_i64(INDEX_op_ext16s_i64, ret, arg);
-#else
-    tcg_gen_shli_i64(ret, arg, 48);
-    tcg_gen_sari_i64(ret, ret, 48);
-#endif
+    if (TCG_TARGET_HAS_ext16s_i64) {
+        tcg_gen_op2_i64(INDEX_op_ext16s_i64, ret, arg);
+    } else {
+        tcg_gen_shli_i64(ret, arg, 48);
+        tcg_gen_sari_i64(ret, ret, 48);
+    }
 }
 
 static inline void tcg_gen_ext32s_i64(TCGv_i64 ret, TCGv_i64 arg)
 {
-#ifdef TCG_TARGET_HAS_ext32s_i64
-    tcg_gen_op2_i64(INDEX_op_ext32s_i64, ret, arg);
-#else
-    tcg_gen_shli_i64(ret, arg, 32);
-    tcg_gen_sari_i64(ret, ret, 32);
-#endif
+    if (TCG_TARGET_HAS_ext32s_i64) {
+        tcg_gen_op2_i64(INDEX_op_ext32s_i64, ret, arg);
+    } else {
+        tcg_gen_shli_i64(ret, arg, 32);
+        tcg_gen_sari_i64(ret, ret, 32);
+    }
 }
 
 static inline void tcg_gen_ext8u_i64(TCGv_i64 ret, TCGv_i64 arg)
 {
-#ifdef TCG_TARGET_HAS_ext8u_i64
-    tcg_gen_op2_i64(INDEX_op_ext8u_i64, ret, arg);
-#else
-    tcg_gen_andi_i64(ret, arg, 0xffu);
-#endif
+    if (TCG_TARGET_HAS_ext8u_i64) {
+        tcg_gen_op2_i64(INDEX_op_ext8u_i64, ret, arg);
+    } else {
+        tcg_gen_andi_i64(ret, arg, 0xffu);
+    }
 }
 
 static inline void tcg_gen_ext16u_i64(TCGv_i64 ret, TCGv_i64 arg)
 {
-#ifdef TCG_TARGET_HAS_ext16u_i64
-    tcg_gen_op2_i64(INDEX_op_ext16u_i64, ret, arg);
-#else
-    tcg_gen_andi_i64(ret, arg, 0xffffu);
-#endif
+    if (TCG_TARGET_HAS_ext16u_i64) {
+        tcg_gen_op2_i64(INDEX_op_ext16u_i64, ret, arg);
+    } else {
+        tcg_gen_andi_i64(ret, arg, 0xffffu);
+    }
 }
 
 static inline void tcg_gen_ext32u_i64(TCGv_i64 ret, TCGv_i64 arg)
 {
-#ifdef TCG_TARGET_HAS_ext32u_i64
-    tcg_gen_op2_i64(INDEX_op_ext32u_i64, ret, arg);
-#else
-    tcg_gen_andi_i64(ret, arg, 0xffffffffu);
-#endif
+    if (TCG_TARGET_HAS_ext32u_i64) {
+        tcg_gen_op2_i64(INDEX_op_ext32u_i64, ret, arg);
+    } else {
+        tcg_gen_andi_i64(ret, arg, 0xffffffffu);
+    }
 }
 
 /* Note: we assume the target supports move between 32 and 64 bit
@@ -1655,130 +1602,132 @@ static inline void tcg_gen_ext_i32_i64(TCGv_i64 ret, TCGv_i32 arg)
 /* Note: we assume the six high bytes are set to zero */
 static inline void tcg_gen_bswap16_i64(TCGv_i64 ret, TCGv_i64 arg)
 {
-#ifdef TCG_TARGET_HAS_bswap16_i64
-    tcg_gen_op2_i64(INDEX_op_bswap16_i64, ret, arg);
-#else
-    TCGv_i64 t0 = tcg_temp_new_i64();
+    if (TCG_TARGET_HAS_bswap16_i64) {
+        tcg_gen_op2_i64(INDEX_op_bswap16_i64, ret, arg);
+    } else {
+        TCGv_i64 t0 = tcg_temp_new_i64();
 
-    tcg_gen_ext8u_i64(t0, arg);
-    tcg_gen_shli_i64(t0, t0, 8);
-    tcg_gen_shri_i64(ret, arg, 8);
-    tcg_gen_or_i64(ret, ret, t0);
-    tcg_temp_free_i64(t0);
-#endif
+        tcg_gen_ext8u_i64(t0, arg);
+        tcg_gen_shli_i64(t0, t0, 8);
+        tcg_gen_shri_i64(ret, arg, 8);
+        tcg_gen_or_i64(ret, ret, t0);
+        tcg_temp_free_i64(t0);
+    }
 }
 
 /* Note: we assume the four high bytes are set to zero */
 static inline void tcg_gen_bswap32_i64(TCGv_i64 ret, TCGv_i64 arg)
 {
-#ifdef TCG_TARGET_HAS_bswap32_i64
-    tcg_gen_op2_i64(INDEX_op_bswap32_i64, ret, arg);
-#else
-    TCGv_i64 t0, t1;
-    t0 = tcg_temp_new_i64();
-    t1 = tcg_temp_new_i64();
+    if (TCG_TARGET_HAS_bswap32_i64) {
+        tcg_gen_op2_i64(INDEX_op_bswap32_i64, ret, arg);
+    } else {
+        TCGv_i64 t0, t1;
+        t0 = tcg_temp_new_i64();
+        t1 = tcg_temp_new_i64();
 
-    tcg_gen_shli_i64(t0, arg, 24);
-    tcg_gen_ext32u_i64(t0, t0);
+        tcg_gen_shli_i64(t0, arg, 24);
+        tcg_gen_ext32u_i64(t0, t0);
 
-    tcg_gen_andi_i64(t1, arg, 0x0000ff00);
-    tcg_gen_shli_i64(t1, t1, 8);
-    tcg_gen_or_i64(t0, t0, t1);
+        tcg_gen_andi_i64(t1, arg, 0x0000ff00);
+        tcg_gen_shli_i64(t1, t1, 8);
+        tcg_gen_or_i64(t0, t0, t1);
 
-    tcg_gen_shri_i64(t1, arg, 8);
-    tcg_gen_andi_i64(t1, t1, 0x0000ff00);
-    tcg_gen_or_i64(t0, t0, t1);
+        tcg_gen_shri_i64(t1, arg, 8);
+        tcg_gen_andi_i64(t1, t1, 0x0000ff00);
+        tcg_gen_or_i64(t0, t0, t1);
 
-    tcg_gen_shri_i64(t1, arg, 24);
-    tcg_gen_or_i64(ret, t0, t1);
-    tcg_temp_free_i64(t0);
-    tcg_temp_free_i64(t1);
-#endif
+        tcg_gen_shri_i64(t1, arg, 24);
+        tcg_gen_or_i64(ret, t0, t1);
+        tcg_temp_free_i64(t0);
+        tcg_temp_free_i64(t1);
+    }
 }
 
 static inline void tcg_gen_bswap64_i64(TCGv_i64 ret, TCGv_i64 arg)
 {
-#ifdef TCG_TARGET_HAS_bswap64_i64
-    tcg_gen_op2_i64(INDEX_op_bswap64_i64, ret, arg);
-#else
-    TCGv_i64 t0 = tcg_temp_new_i64();
-    TCGv_i64 t1 = tcg_temp_new_i64();
+    if (TCG_TARGET_HAS_bswap64_i64) {
+        tcg_gen_op2_i64(INDEX_op_bswap64_i64, ret, arg);
+    } else {
+        TCGv_i64 t0 = tcg_temp_new_i64();
+        TCGv_i64 t1 = tcg_temp_new_i64();
     
-    tcg_gen_shli_i64(t0, arg, 56);
+        tcg_gen_shli_i64(t0, arg, 56);
     
-    tcg_gen_andi_i64(t1, arg, 0x0000ff00);
-    tcg_gen_shli_i64(t1, t1, 40);
-    tcg_gen_or_i64(t0, t0, t1);
+        tcg_gen_andi_i64(t1, arg, 0x0000ff00);
+        tcg_gen_shli_i64(t1, t1, 40);
+        tcg_gen_or_i64(t0, t0, t1);
     
-    tcg_gen_andi_i64(t1, arg, 0x00ff0000);
-    tcg_gen_shli_i64(t1, t1, 24);
-    tcg_gen_or_i64(t0, t0, t1);
+        tcg_gen_andi_i64(t1, arg, 0x00ff0000);
+        tcg_gen_shli_i64(t1, t1, 24);
+        tcg_gen_or_i64(t0, t0, t1);
 
-    tcg_gen_andi_i64(t1, arg, 0xff000000);
-    tcg_gen_shli_i64(t1, t1, 8);
-    tcg_gen_or_i64(t0, t0, t1);
+        tcg_gen_andi_i64(t1, arg, 0xff000000);
+        tcg_gen_shli_i64(t1, t1, 8);
+        tcg_gen_or_i64(t0, t0, t1);
 
-    tcg_gen_shri_i64(t1, arg, 8);
-    tcg_gen_andi_i64(t1, t1, 0xff000000);
-    tcg_gen_or_i64(t0, t0, t1);
+        tcg_gen_shri_i64(t1, arg, 8);
+        tcg_gen_andi_i64(t1, t1, 0xff000000);
+        tcg_gen_or_i64(t0, t0, t1);
     
-    tcg_gen_shri_i64(t1, arg, 24);
-    tcg_gen_andi_i64(t1, t1, 0x00ff0000);
-    tcg_gen_or_i64(t0, t0, t1);
+        tcg_gen_shri_i64(t1, arg, 24);
+        tcg_gen_andi_i64(t1, t1, 0x00ff0000);
+        tcg_gen_or_i64(t0, t0, t1);
 
-    tcg_gen_shri_i64(t1, arg, 40);
-    tcg_gen_andi_i64(t1, t1, 0x0000ff00);
-    tcg_gen_or_i64(t0, t0, t1);
+        tcg_gen_shri_i64(t1, arg, 40);
+        tcg_gen_andi_i64(t1, t1, 0x0000ff00);
+        tcg_gen_or_i64(t0, t0, t1);
 
-    tcg_gen_shri_i64(t1, arg, 56);
-    tcg_gen_or_i64(ret, t0, t1);
-    tcg_temp_free_i64(t0);
-    tcg_temp_free_i64(t1);
-#endif
+        tcg_gen_shri_i64(t1, arg, 56);
+        tcg_gen_or_i64(ret, t0, t1);
+        tcg_temp_free_i64(t0);
+        tcg_temp_free_i64(t1);
+    }
 }
 
 #endif
 
 static inline void tcg_gen_neg_i32(TCGv_i32 ret, TCGv_i32 arg)
 {
-#ifdef TCG_TARGET_HAS_neg_i32
-    tcg_gen_op2_i32(INDEX_op_neg_i32, ret, arg);
-#else
-    TCGv_i32 t0 = tcg_const_i32(0);
-    tcg_gen_sub_i32(ret, t0, arg);
-    tcg_temp_free_i32(t0);
-#endif
+    if (TCG_TARGET_HAS_neg_i32) {
+        tcg_gen_op2_i32(INDEX_op_neg_i32, ret, arg);
+    } else {
+        TCGv_i32 t0 = tcg_const_i32(0);
+        tcg_gen_sub_i32(ret, t0, arg);
+        tcg_temp_free_i32(t0);
+    }
 }
 
 static inline void tcg_gen_neg_i64(TCGv_i64 ret, TCGv_i64 arg)
 {
-#ifdef TCG_TARGET_HAS_neg_i64
-    tcg_gen_op2_i64(INDEX_op_neg_i64, ret, arg);
-#else
-    TCGv_i64 t0 = tcg_const_i64(0);
-    tcg_gen_sub_i64(ret, t0, arg);
-    tcg_temp_free_i64(t0);
-#endif
+    if (TCG_TARGET_HAS_neg_i64) {
+        tcg_gen_op2_i64(INDEX_op_neg_i64, ret, arg);
+    } else {
+        TCGv_i64 t0 = tcg_const_i64(0);
+        tcg_gen_sub_i64(ret, t0, arg);
+        tcg_temp_free_i64(t0);
+    }
 }
 
 static inline void tcg_gen_not_i32(TCGv_i32 ret, TCGv_i32 arg)
 {
-#ifdef TCG_TARGET_HAS_not_i32
-    tcg_gen_op2_i32(INDEX_op_not_i32, ret, arg);
-#else
-    tcg_gen_xori_i32(ret, arg, -1);
-#endif
+    if (TCG_TARGET_HAS_not_i32) {
+        tcg_gen_op2_i32(INDEX_op_not_i32, ret, arg);
+    } else {
+        tcg_gen_xori_i32(ret, arg, -1);
+    }
 }
 
 static inline void tcg_gen_not_i64(TCGv_i64 ret, TCGv_i64 arg)
 {
-#ifdef TCG_TARGET_HAS_not_i64
-    tcg_gen_op2_i64(INDEX_op_not_i64, ret, arg);
-#elif defined(TCG_TARGET_HAS_not_i32) && TCG_TARGET_REG_BITS == 32
+#if TCG_TARGET_REG_BITS == 64
+    if (TCG_TARGET_HAS_not_i64) {
+        tcg_gen_op2_i64(INDEX_op_not_i64, ret, arg);
+    } else {
+        tcg_gen_xori_i64(ret, arg, -1);
+    }
+#else
     tcg_gen_not_i32(TCGV_LOW(ret), TCGV_LOW(arg));
     tcg_gen_not_i32(TCGV_HIGH(ret), TCGV_HIGH(arg));
-#else
-    tcg_gen_xori_i64(ret, arg, -1);
 #endif
 }
 
@@ -1787,18 +1736,15 @@ static inline void tcg_gen_discard_i32(TCGv_i32 arg)
     tcg_gen_op1_i32(INDEX_op_discard, arg);
 }
 
-#if TCG_TARGET_REG_BITS == 32
 static inline void tcg_gen_discard_i64(TCGv_i64 arg)
 {
+#if TCG_TARGET_REG_BITS == 32
     tcg_gen_discard_i32(TCGV_LOW(arg));
     tcg_gen_discard_i32(TCGV_HIGH(arg));
-}
 #else
-static inline void tcg_gen_discard_i64(TCGv_i64 arg)
-{
     tcg_gen_op1_i64(INDEX_op_discard, arg);
-}
 #endif
+}
 
 static inline void tcg_gen_concat_i32_i64(TCGv_i64 dest, TCGv_i32 low, TCGv_i32 high)
 {
@@ -1832,165 +1778,170 @@ static inline void tcg_gen_concat32_i64(TCGv_i64 dest, TCGv_i64 low, TCGv_i64 hi
 
 static inline void tcg_gen_andc_i32(TCGv_i32 ret, TCGv_i32 arg1, TCGv_i32 arg2)
 {
-#ifdef TCG_TARGET_HAS_andc_i32
-    tcg_gen_op3_i32(INDEX_op_andc_i32, ret, arg1, arg2);
-#else
-    TCGv_i32 t0;
-    t0 = tcg_temp_new_i32();
-    tcg_gen_not_i32(t0, arg2);
-    tcg_gen_and_i32(ret, arg1, t0);
-    tcg_temp_free_i32(t0);
-#endif
+    if (TCG_TARGET_HAS_andc_i32) {
+        tcg_gen_op3_i32(INDEX_op_andc_i32, ret, arg1, arg2);
+    } else {
+        TCGv_i32 t0 = tcg_temp_new_i32();
+        tcg_gen_not_i32(t0, arg2);
+        tcg_gen_and_i32(ret, arg1, t0);
+        tcg_temp_free_i32(t0);
+    }
 }
 
 static inline void tcg_gen_andc_i64(TCGv_i64 ret, TCGv_i64 arg1, TCGv_i64 arg2)
 {
-#ifdef TCG_TARGET_HAS_andc_i64
-    tcg_gen_op3_i64(INDEX_op_andc_i64, ret, arg1, arg2);
-#elif defined(TCG_TARGET_HAS_andc_i32) && TCG_TARGET_REG_BITS == 32
+#if TCG_TARGET_REG_BITS == 64
+    if (TCG_TARGET_HAS_andc_i64) {
+        tcg_gen_op3_i64(INDEX_op_andc_i64, ret, arg1, arg2);
+    } else {
+        TCGv_i64 t0 = tcg_temp_new_i64();
+        tcg_gen_not_i64(t0, arg2);
+        tcg_gen_and_i64(ret, arg1, t0);
+        tcg_temp_free_i64(t0);
+    }
+#else
     tcg_gen_andc_i32(TCGV_LOW(ret), TCGV_LOW(arg1), TCGV_LOW(arg2));
     tcg_gen_andc_i32(TCGV_HIGH(ret), TCGV_HIGH(arg1), TCGV_HIGH(arg2));
-#else
-    TCGv_i64 t0;
-    t0 = tcg_temp_new_i64();
-    tcg_gen_not_i64(t0, arg2);
-    tcg_gen_and_i64(ret, arg1, t0);
-    tcg_temp_free_i64(t0);
 #endif
 }
 
 static inline void tcg_gen_eqv_i32(TCGv_i32 ret, TCGv_i32 arg1, TCGv_i32 arg2)
 {
-#ifdef TCG_TARGET_HAS_eqv_i32
-    tcg_gen_op3_i32(INDEX_op_eqv_i32, ret, arg1, arg2);
-#else
-    tcg_gen_xor_i32(ret, arg1, arg2);
-    tcg_gen_not_i32(ret, ret);
-#endif
+    if (TCG_TARGET_HAS_eqv_i32) {
+        tcg_gen_op3_i32(INDEX_op_eqv_i32, ret, arg1, arg2);
+    } else {
+        tcg_gen_xor_i32(ret, arg1, arg2);
+        tcg_gen_not_i32(ret, ret);
+    }
 }
 
 static inline void tcg_gen_eqv_i64(TCGv_i64 ret, TCGv_i64 arg1, TCGv_i64 arg2)
 {
-#ifdef TCG_TARGET_HAS_eqv_i64
-    tcg_gen_op3_i64(INDEX_op_eqv_i64, ret, arg1, arg2);
-#elif defined(TCG_TARGET_HAS_eqv_i32) && TCG_TARGET_REG_BITS == 32
+#if TCG_TARGET_REG_BITS == 64
+    if (TCG_TARGET_HAS_eqv_i64) {
+        tcg_gen_op3_i64(INDEX_op_eqv_i64, ret, arg1, arg2);
+    } else {
+        tcg_gen_xor_i64(ret, arg1, arg2);
+        tcg_gen_not_i64(ret, ret);
+    }
+#else
     tcg_gen_eqv_i32(TCGV_LOW(ret), TCGV_LOW(arg1), TCGV_LOW(arg2));
     tcg_gen_eqv_i32(TCGV_HIGH(ret), TCGV_HIGH(arg1), TCGV_HIGH(arg2));
-#else
-    tcg_gen_xor_i64(ret, arg1, arg2);
-    tcg_gen_not_i64(ret, ret);
 #endif
 }
 
 static inline void tcg_gen_nand_i32(TCGv_i32 ret, TCGv_i32 arg1, TCGv_i32 arg2)
 {
-#ifdef TCG_TARGET_HAS_nand_i32
-    tcg_gen_op3_i32(INDEX_op_nand_i32, ret, arg1, arg2);
-#else
-    tcg_gen_and_i32(ret, arg1, arg2);
-    tcg_gen_not_i32(ret, ret);
-#endif
+    if (TCG_TARGET_HAS_nand_i32) {
+        tcg_gen_op3_i32(INDEX_op_nand_i32, ret, arg1, arg2);
+    } else {
+        tcg_gen_and_i32(ret, arg1, arg2);
+        tcg_gen_not_i32(ret, ret);
+    }
 }
 
 static inline void tcg_gen_nand_i64(TCGv_i64 ret, TCGv_i64 arg1, TCGv_i64 arg2)
 {
-#ifdef TCG_TARGET_HAS_nand_i64
-    tcg_gen_op3_i64(INDEX_op_nand_i64, ret, arg1, arg2);
-#elif defined(TCG_TARGET_HAS_nand_i32) && TCG_TARGET_REG_BITS == 32
+#if TCG_TARGET_REG_BITS == 64
+    if (TCG_TARGET_HAS_nand_i64) {
+        tcg_gen_op3_i64(INDEX_op_nand_i64, ret, arg1, arg2);
+    } else {
+        tcg_gen_and_i64(ret, arg1, arg2);
+        tcg_gen_not_i64(ret, ret);
+    }
+#else
     tcg_gen_nand_i32(TCGV_LOW(ret), TCGV_LOW(arg1), TCGV_LOW(arg2));
     tcg_gen_nand_i32(TCGV_HIGH(ret), TCGV_HIGH(arg1), TCGV_HIGH(arg2));
-#else
-    tcg_gen_and_i64(ret, arg1, arg2);
-    tcg_gen_not_i64(ret, ret);
 #endif
 }
 
 static inline void tcg_gen_nor_i32(TCGv_i32 ret, TCGv_i32 arg1, TCGv_i32 arg2)
 {
-#ifdef TCG_TARGET_HAS_nor_i32
-    tcg_gen_op3_i32(INDEX_op_nor_i32, ret, arg1, arg2);
-#else
-    tcg_gen_or_i32(ret, arg1, arg2);
-    tcg_gen_not_i32(ret, ret);
-#endif
+    if (TCG_TARGET_HAS_nor_i32) {
+        tcg_gen_op3_i32(INDEX_op_nor_i32, ret, arg1, arg2);
+    } else {
+        tcg_gen_or_i32(ret, arg1, arg2);
+        tcg_gen_not_i32(ret, ret);
+    }
 }
 
 static inline void tcg_gen_nor_i64(TCGv_i64 ret, TCGv_i64 arg1, TCGv_i64 arg2)
 {
-#ifdef TCG_TARGET_HAS_nor_i64
-    tcg_gen_op3_i64(INDEX_op_nor_i64, ret, arg1, arg2);
-#elif defined(TCG_TARGET_HAS_nor_i32) && TCG_TARGET_REG_BITS == 32
+#if TCG_TARGET_REG_BITS == 64
+    if (TCG_TARGET_HAS_nor_i64) {
+        tcg_gen_op3_i64(INDEX_op_nor_i64, ret, arg1, arg2);
+    } else {
+        tcg_gen_or_i64(ret, arg1, arg2);
+        tcg_gen_not_i64(ret, ret);
+    }
+#else
     tcg_gen_nor_i32(TCGV_LOW(ret), TCGV_LOW(arg1), TCGV_LOW(arg2));
     tcg_gen_nor_i32(TCGV_HIGH(ret), TCGV_HIGH(arg1), TCGV_HIGH(arg2));
-#else
-    tcg_gen_or_i64(ret, arg1, arg2);
-    tcg_gen_not_i64(ret, ret);
 #endif
 }
 
 static inline void tcg_gen_orc_i32(TCGv_i32 ret, TCGv_i32 arg1, TCGv_i32 arg2)
 {
-#ifdef TCG_TARGET_HAS_orc_i32
-    tcg_gen_op3_i32(INDEX_op_orc_i32, ret, arg1, arg2);
-#else
-    TCGv_i32 t0;
-    t0 = tcg_temp_new_i32();
-    tcg_gen_not_i32(t0, arg2);
-    tcg_gen_or_i32(ret, arg1, t0);
-    tcg_temp_free_i32(t0);
-#endif
+    if (TCG_TARGET_HAS_orc_i32) {
+        tcg_gen_op3_i32(INDEX_op_orc_i32, ret, arg1, arg2);
+    } else {
+        TCGv_i32 t0 = tcg_temp_new_i32();
+        tcg_gen_not_i32(t0, arg2);
+        tcg_gen_or_i32(ret, arg1, t0);
+        tcg_temp_free_i32(t0);
+    }
 }
 
 static inline void tcg_gen_orc_i64(TCGv_i64 ret, TCGv_i64 arg1, TCGv_i64 arg2)
 {
-#ifdef TCG_TARGET_HAS_orc_i64
-    tcg_gen_op3_i64(INDEX_op_orc_i64, ret, arg1, arg2);
-#elif defined(TCG_TARGET_HAS_orc_i32) && TCG_TARGET_REG_BITS == 32
+#if TCG_TARGET_REG_BITS == 64
+    if (TCG_TARGET_HAS_orc_i64) {
+        tcg_gen_op3_i64(INDEX_op_orc_i64, ret, arg1, arg2);
+    } else {
+        TCGv_i64 t0 = tcg_temp_new_i64();
+        tcg_gen_not_i64(t0, arg2);
+        tcg_gen_or_i64(ret, arg1, t0);
+        tcg_temp_free_i64(t0);
+    }
+#else
     tcg_gen_orc_i32(TCGV_LOW(ret), TCGV_LOW(arg1), TCGV_LOW(arg2));
     tcg_gen_orc_i32(TCGV_HIGH(ret), TCGV_HIGH(arg1), TCGV_HIGH(arg2));
-#else
-    TCGv_i64 t0;
-    t0 = tcg_temp_new_i64();
-    tcg_gen_not_i64(t0, arg2);
-    tcg_gen_or_i64(ret, arg1, t0);
-    tcg_temp_free_i64(t0);
 #endif
 }
 
 static inline void tcg_gen_rotl_i32(TCGv_i32 ret, TCGv_i32 arg1, TCGv_i32 arg2)
 {
-#ifdef TCG_TARGET_HAS_rot_i32
-    tcg_gen_op3_i32(INDEX_op_rotl_i32, ret, arg1, arg2);
-#else
-    TCGv_i32 t0, t1;
+    if (TCG_TARGET_HAS_rot_i32) {
+        tcg_gen_op3_i32(INDEX_op_rotl_i32, ret, arg1, arg2);
+    } else {
+        TCGv_i32 t0, t1;
 
-    t0 = tcg_temp_new_i32();
-    t1 = tcg_temp_new_i32();
-    tcg_gen_shl_i32(t0, arg1, arg2);
-    tcg_gen_subfi_i32(t1, 32, arg2);
-    tcg_gen_shr_i32(t1, arg1, t1);
-    tcg_gen_or_i32(ret, t0, t1);
-    tcg_temp_free_i32(t0);
-    tcg_temp_free_i32(t1);
-#endif
+        t0 = tcg_temp_new_i32();
+        t1 = tcg_temp_new_i32();
+        tcg_gen_shl_i32(t0, arg1, arg2);
+        tcg_gen_subfi_i32(t1, 32, arg2);
+        tcg_gen_shr_i32(t1, arg1, t1);
+        tcg_gen_or_i32(ret, t0, t1);
+        tcg_temp_free_i32(t0);
+        tcg_temp_free_i32(t1);
+    }
 }
 
 static inline void tcg_gen_rotl_i64(TCGv_i64 ret, TCGv_i64 arg1, TCGv_i64 arg2)
 {
-#ifdef TCG_TARGET_HAS_rot_i64
-    tcg_gen_op3_i64(INDEX_op_rotl_i64, ret, arg1, arg2);
-#else
-    TCGv_i64 t0, t1;
-
-    t0 = tcg_temp_new_i64();
-    t1 = tcg_temp_new_i64();
-    tcg_gen_shl_i64(t0, arg1, arg2);
-    tcg_gen_subfi_i64(t1, 64, arg2);
-    tcg_gen_shr_i64(t1, arg1, t1);
-    tcg_gen_or_i64(ret, t0, t1);
-    tcg_temp_free_i64(t0);
-    tcg_temp_free_i64(t1);
-#endif
+    if (TCG_TARGET_HAS_rot_i64) {
+        tcg_gen_op3_i64(INDEX_op_rotl_i64, ret, arg1, arg2);
+    } else {
+        TCGv_i64 t0, t1;
+        t0 = tcg_temp_new_i64();
+        t1 = tcg_temp_new_i64();
+        tcg_gen_shl_i64(t0, arg1, arg2);
+        tcg_gen_subfi_i64(t1, 64, arg2);
+        tcg_gen_shr_i64(t1, arg1, t1);
+        tcg_gen_or_i64(ret, t0, t1);
+        tcg_temp_free_i64(t0);
+        tcg_temp_free_i64(t1);
+    }
 }
 
 static inline void tcg_gen_rotli_i32(TCGv_i32 ret, TCGv_i32 arg1, int32_t arg2)
@@ -1998,12 +1949,11 @@ static inline void tcg_gen_rotli_i32(TCGv_i32 ret, TCGv_i32 arg1, int32_t arg2)
     /* some cases can be optimized here */
     if (arg2 == 0) {
         tcg_gen_mov_i32(ret, arg1);
-    } else {
-#ifdef TCG_TARGET_HAS_rot_i32
+    } else if (TCG_TARGET_HAS_rot_i32) {
         TCGv_i32 t0 = tcg_const_i32(arg2);
         tcg_gen_rotl_i32(ret, arg1, t0);
         tcg_temp_free_i32(t0);
-#else
+    } else {
         TCGv_i32 t0, t1;
         t0 = tcg_temp_new_i32();
         t1 = tcg_temp_new_i32();
@@ -2012,7 +1962,6 @@ static inline void tcg_gen_rotli_i32(TCGv_i32 ret, TCGv_i32 arg1, int32_t arg2)
         tcg_gen_or_i32(ret, t0, t1);
         tcg_temp_free_i32(t0);
         tcg_temp_free_i32(t1);
-#endif
     }
 }
 
@@ -2021,12 +1970,11 @@ static inline void tcg_gen_rotli_i64(TCGv_i64 ret, TCGv_i64 arg1, int64_t arg2)
     /* some cases can be optimized here */
     if (arg2 == 0) {
         tcg_gen_mov_i64(ret, arg1);
-    } else {
-#ifdef TCG_TARGET_HAS_rot_i64
+    } else if (TCG_TARGET_HAS_rot_i64) {
         TCGv_i64 t0 = tcg_const_i64(arg2);
         tcg_gen_rotl_i64(ret, arg1, t0);
         tcg_temp_free_i64(t0);
-#else
+    } else {
         TCGv_i64 t0, t1;
         t0 = tcg_temp_new_i64();
         t1 = tcg_temp_new_i64();
@@ -2035,44 +1983,42 @@ static inline void tcg_gen_rotli_i64(TCGv_i64 ret, TCGv_i64 arg1, int64_t arg2)
         tcg_gen_or_i64(ret, t0, t1);
         tcg_temp_free_i64(t0);
         tcg_temp_free_i64(t1);
-#endif
     }
 }
 
 static inline void tcg_gen_rotr_i32(TCGv_i32 ret, TCGv_i32 arg1, TCGv_i32 arg2)
 {
-#ifdef TCG_TARGET_HAS_rot_i32
-    tcg_gen_op3_i32(INDEX_op_rotr_i32, ret, arg1, arg2);
-#else
-    TCGv_i32 t0, t1;
+    if (TCG_TARGET_HAS_rot_i32) {
+        tcg_gen_op3_i32(INDEX_op_rotr_i32, ret, arg1, arg2);
+    } else {
+        TCGv_i32 t0, t1;
 
-    t0 = tcg_temp_new_i32();
-    t1 = tcg_temp_new_i32();
-    tcg_gen_shr_i32(t0, arg1, arg2);
-    tcg_gen_subfi_i32(t1, 32, arg2);
-    tcg_gen_shl_i32(t1, arg1, t1);
-    tcg_gen_or_i32(ret, t0, t1);
-    tcg_temp_free_i32(t0);
-    tcg_temp_free_i32(t1);
-#endif
+        t0 = tcg_temp_new_i32();
+        t1 = tcg_temp_new_i32();
+        tcg_gen_shr_i32(t0, arg1, arg2);
+        tcg_gen_subfi_i32(t1, 32, arg2);
+        tcg_gen_shl_i32(t1, arg1, t1);
+        tcg_gen_or_i32(ret, t0, t1);
+        tcg_temp_free_i32(t0);
+        tcg_temp_free_i32(t1);
+    }
 }
 
 static inline void tcg_gen_rotr_i64(TCGv_i64 ret, TCGv_i64 arg1, TCGv_i64 arg2)
 {
-#ifdef TCG_TARGET_HAS_rot_i64
-    tcg_gen_op3_i64(INDEX_op_rotr_i64, ret, arg1, arg2);
-#else
-    TCGv_i64 t0, t1;
-
-    t0 = tcg_temp_new_i64();
-    t1 = tcg_temp_new_i64();
-    tcg_gen_shr_i64(t0, arg1, arg2);
-    tcg_gen_subfi_i64(t1, 64, arg2);
-    tcg_gen_shl_i64(t1, arg1, t1);
-    tcg_gen_or_i64(ret, t0, t1);
-    tcg_temp_free_i64(t0);
-    tcg_temp_free_i64(t1);
-#endif
+    if (TCG_TARGET_HAS_rot_i64) {
+        tcg_gen_op3_i64(INDEX_op_rotr_i64, ret, arg1, arg2);
+    } else {
+        TCGv_i64 t0, t1;
+        t0 = tcg_temp_new_i64();
+        t1 = tcg_temp_new_i64();
+        tcg_gen_shr_i64(t0, arg1, arg2);
+        tcg_gen_subfi_i64(t1, 64, arg2);
+        tcg_gen_shl_i64(t1, arg1, t1);
+        tcg_gen_or_i64(ret, t0, t1);
+        tcg_temp_free_i64(t0);
+        tcg_temp_free_i64(t1);
+    }
 }
 
 static inline void tcg_gen_rotri_i32(TCGv_i32 ret, TCGv_i32 arg1, int32_t arg2)
@@ -2099,38 +2045,38 @@ static inline void tcg_gen_deposit_i32(TCGv_i32 ret, TCGv_i32 arg1,
 				       TCGv_i32 arg2, unsigned int ofs,
 				       unsigned int len)
 {
-#ifdef TCG_TARGET_HAS_deposit_i32
-  tcg_gen_op5ii_i32(INDEX_op_deposit_i32, ret, arg1, arg2, ofs, len);
-#else
-  uint32_t mask = (1u << len) - 1;
-  TCGv_i32 t1 = tcg_temp_new_i32 ();
+    if (TCG_TARGET_HAS_deposit_i32) {
+        tcg_gen_op5ii_i32(INDEX_op_deposit_i32, ret, arg1, arg2, ofs, len);
+    } else {
+        uint32_t mask = (1u << len) - 1;
+        TCGv_i32 t1 = tcg_temp_new_i32 ();
 
-  tcg_gen_andi_i32(t1, arg2, mask);
-  tcg_gen_shli_i32(t1, t1, ofs);
-  tcg_gen_andi_i32(ret, arg1, ~(mask << ofs));
-  tcg_gen_or_i32(ret, ret, t1);
+        tcg_gen_andi_i32(t1, arg2, mask);
+        tcg_gen_shli_i32(t1, t1, ofs);
+        tcg_gen_andi_i32(ret, arg1, ~(mask << ofs));
+        tcg_gen_or_i32(ret, ret, t1);
 
-  tcg_temp_free_i32(t1);
-#endif
+        tcg_temp_free_i32(t1);
+    }
 }
 
 static inline void tcg_gen_deposit_i64(TCGv_i64 ret, TCGv_i64 arg1,
 				       TCGv_i64 arg2, unsigned int ofs,
 				       unsigned int len)
 {
-#ifdef TCG_TARGET_HAS_deposit_i64
-  tcg_gen_op5ii_i64(INDEX_op_deposit_i64, ret, arg1, arg2, ofs, len);
-#else
-  uint64_t mask = (1ull << len) - 1;
-  TCGv_i64 t1 = tcg_temp_new_i64 ();
+    if (TCG_TARGET_HAS_deposit_i64) {
+        tcg_gen_op5ii_i64(INDEX_op_deposit_i64, ret, arg1, arg2, ofs, len);
+    } else {
+        uint64_t mask = (1ull << len) - 1;
+        TCGv_i64 t1 = tcg_temp_new_i64 ();
 
-  tcg_gen_andi_i64(t1, arg2, mask);
-  tcg_gen_shli_i64(t1, t1, ofs);
-  tcg_gen_andi_i64(ret, arg1, ~(mask << ofs));
-  tcg_gen_or_i64(ret, ret, t1);
+        tcg_gen_andi_i64(t1, arg2, mask);
+        tcg_gen_shli_i64(t1, t1, ofs);
+        tcg_gen_andi_i64(ret, arg1, ~(mask << ofs));
+        tcg_gen_or_i64(ret, ret, t1);
 
-  tcg_temp_free_i64(t1);
-#endif
+        tcg_temp_free_i64(t1);
+    }
 }
 
 /***************************************/
diff --git a/tcg/tcg-opc.h b/tcg/tcg-opc.h
index b48669b..8e06d03 100644
--- a/tcg/tcg-opc.h
+++ b/tcg/tcg-opc.h
@@ -41,6 +41,13 @@ DEF(call, 0, 1, 2, TCG_OPF_SIDE_EFFECTS) /* variable number of parameters */
 DEF(jmp, 0, 1, 0, TCG_OPF_BB_END | TCG_OPF_SIDE_EFFECTS)
 DEF(br, 0, 0, 1, TCG_OPF_BB_END | TCG_OPF_SIDE_EFFECTS)
 
+#define IMPL(X) (X ? 0 : TCG_OPF_NOT_PRESENT)
+#if TCG_TARGET_REG_BITS == 32
+# define IMPL64  TCG_OPF_64BIT | TCG_OPF_NOT_PRESENT
+#else
+# define IMPL64  TCG_OPF_64BIT
+#endif
+
 DEF(mov_i32, 1, 1, 0, 0)
 DEF(movi_i32, 1, 0, 1, 0)
 DEF(setcond_i32, 1, 2, 1, 0)
@@ -57,16 +64,12 @@ DEF(st_i32, 0, 2, 1, TCG_OPF_SIDE_EFFECTS)
 DEF(add_i32, 1, 2, 0, 0)
 DEF(sub_i32, 1, 2, 0, 0)
 DEF(mul_i32, 1, 2, 0, 0)
-#ifdef TCG_TARGET_HAS_div_i32
-DEF(div_i32, 1, 2, 0, 0)
-DEF(divu_i32, 1, 2, 0, 0)
-DEF(rem_i32, 1, 2, 0, 0)
-DEF(remu_i32, 1, 2, 0, 0)
-#endif
-#ifdef TCG_TARGET_HAS_div2_i32
-DEF(div2_i32, 2, 3, 0, 0)
-DEF(divu2_i32, 2, 3, 0, 0)
-#endif
+DEF(div_i32, 1, 2, 0, IMPL(TCG_TARGET_HAS_div_i32))
+DEF(divu_i32, 1, 2, 0, IMPL(TCG_TARGET_HAS_div_i32))
+DEF(rem_i32, 1, 2, 0, IMPL(TCG_TARGET_HAS_div_i32))
+DEF(remu_i32, 1, 2, 0, IMPL(TCG_TARGET_HAS_div_i32))
+DEF(div2_i32, 2, 3, 0, IMPL(TCG_TARGET_HAS_div2_i32))
+DEF(divu2_i32, 2, 3, 0, IMPL(TCG_TARGET_HAS_div2_i32))
 DEF(and_i32, 1, 2, 0, 0)
 DEF(or_i32, 1, 2, 0, 0)
 DEF(xor_i32, 1, 2, 0, 0)
@@ -74,157 +77,86 @@ DEF(xor_i32, 1, 2, 0, 0)
 DEF(shl_i32, 1, 2, 0, 0)
 DEF(shr_i32, 1, 2, 0, 0)
 DEF(sar_i32, 1, 2, 0, 0)
-#ifdef TCG_TARGET_HAS_rot_i32
-DEF(rotl_i32, 1, 2, 0, 0)
-DEF(rotr_i32, 1, 2, 0, 0)
-#endif
-#ifdef TCG_TARGET_HAS_deposit_i32
-DEF(deposit_i32, 1, 2, 2, 0)
-#endif
+DEF(rotl_i32, 1, 2, 0, IMPL(TCG_TARGET_HAS_rot_i32))
+DEF(rotr_i32, 1, 2, 0, IMPL(TCG_TARGET_HAS_rot_i32))
+DEF(deposit_i32, 1, 2, 2, IMPL(TCG_TARGET_HAS_deposit_i32))
 
 DEF(brcond_i32, 0, 2, 2, TCG_OPF_BB_END | TCG_OPF_SIDE_EFFECTS)
-#if TCG_TARGET_REG_BITS == 32
-DEF(add2_i32, 2, 4, 0, 0)
-DEF(sub2_i32, 2, 4, 0, 0)
-DEF(brcond2_i32, 0, 4, 2, TCG_OPF_BB_END | TCG_OPF_SIDE_EFFECTS)
-DEF(mulu2_i32, 2, 2, 0, 0)
-DEF(setcond2_i32, 1, 4, 1, 0)
-#endif
-#ifdef TCG_TARGET_HAS_ext8s_i32
-DEF(ext8s_i32, 1, 1, 0, 0)
-#endif
-#ifdef TCG_TARGET_HAS_ext16s_i32
-DEF(ext16s_i32, 1, 1, 0, 0)
-#endif
-#ifdef TCG_TARGET_HAS_ext8u_i32
-DEF(ext8u_i32, 1, 1, 0, 0)
-#endif
-#ifdef TCG_TARGET_HAS_ext16u_i32
-DEF(ext16u_i32, 1, 1, 0, 0)
-#endif
-#ifdef TCG_TARGET_HAS_bswap16_i32
-DEF(bswap16_i32, 1, 1, 0, 0)
-#endif
-#ifdef TCG_TARGET_HAS_bswap32_i32
-DEF(bswap32_i32, 1, 1, 0, 0)
-#endif
-#ifdef TCG_TARGET_HAS_not_i32
-DEF(not_i32, 1, 1, 0, 0)
-#endif
-#ifdef TCG_TARGET_HAS_neg_i32
-DEF(neg_i32, 1, 1, 0, 0)
-#endif
-#ifdef TCG_TARGET_HAS_andc_i32
-DEF(andc_i32, 1, 2, 0, 0)
-#endif
-#ifdef TCG_TARGET_HAS_orc_i32
-DEF(orc_i32, 1, 2, 0, 0)
-#endif
-#ifdef TCG_TARGET_HAS_eqv_i32
-DEF(eqv_i32, 1, 2, 0, 0)
-#endif
-#ifdef TCG_TARGET_HAS_nand_i32
-DEF(nand_i32, 1, 2, 0, 0)
-#endif
-#ifdef TCG_TARGET_HAS_nor_i32
-DEF(nor_i32, 1, 2, 0, 0)
-#endif
 
-#if TCG_TARGET_REG_BITS == 64
-DEF(mov_i64, 1, 1, 0, TCG_OPF_64BIT)
-DEF(movi_i64, 1, 0, 1, TCG_OPF_64BIT)
-DEF(setcond_i64, 1, 2, 1, TCG_OPF_64BIT)
+DEF(add2_i32, 2, 4, 0, IMPL(TCG_TARGET_REG_BITS == 32))
+DEF(sub2_i32, 2, 4, 0, IMPL(TCG_TARGET_REG_BITS == 32))
+DEF(brcond2_i32, 0, 4, 2,
+    TCG_OPF_BB_END | TCG_OPF_SIDE_EFFECTS | IMPL(TCG_TARGET_REG_BITS == 32))
+DEF(mulu2_i32, 2, 2, 0, IMPL(TCG_TARGET_REG_BITS == 32))
+DEF(setcond2_i32, 1, 4, 1, IMPL(TCG_TARGET_REG_BITS == 32))
+
+DEF(ext8s_i32, 1, 1, 0, IMPL(TCG_TARGET_HAS_ext8s_i32))
+DEF(ext16s_i32, 1, 1, 0, IMPL(TCG_TARGET_HAS_ext16s_i32))
+DEF(ext8u_i32, 1, 1, 0, IMPL(TCG_TARGET_HAS_ext8u_i32))
+DEF(ext16u_i32, 1, 1, 0, IMPL(TCG_TARGET_HAS_ext16u_i32))
+DEF(bswap16_i32, 1, 1, 0, IMPL(TCG_TARGET_HAS_bswap16_i32))
+DEF(bswap32_i32, 1, 1, 0, IMPL(TCG_TARGET_HAS_bswap32_i32))
+DEF(not_i32, 1, 1, 0, IMPL(TCG_TARGET_HAS_not_i32))
+DEF(neg_i32, 1, 1, 0, IMPL(TCG_TARGET_HAS_neg_i32))
+DEF(andc_i32, 1, 2, 0, IMPL(TCG_TARGET_HAS_andc_i32))
+DEF(orc_i32, 1, 2, 0, IMPL(TCG_TARGET_HAS_orc_i32))
+DEF(eqv_i32, 1, 2, 0, IMPL(TCG_TARGET_HAS_eqv_i32))
+DEF(nand_i32, 1, 2, 0, IMPL(TCG_TARGET_HAS_nand_i32))
+DEF(nor_i32, 1, 2, 0, IMPL(TCG_TARGET_HAS_nor_i32))
+
+DEF(mov_i64, 1, 1, 0, IMPL64)
+DEF(movi_i64, 1, 0, 1, IMPL64)
+DEF(setcond_i64, 1, 2, 1, IMPL64)
 /* load/store */
-DEF(ld8u_i64, 1, 1, 1, TCG_OPF_64BIT)
-DEF(ld8s_i64, 1, 1, 1, TCG_OPF_64BIT)
-DEF(ld16u_i64, 1, 1, 1, TCG_OPF_64BIT)
-DEF(ld16s_i64, 1, 1, 1, TCG_OPF_64BIT)
-DEF(ld32u_i64, 1, 1, 1, TCG_OPF_64BIT)
-DEF(ld32s_i64, 1, 1, 1, TCG_OPF_64BIT)
-DEF(ld_i64, 1, 1, 1, TCG_OPF_64BIT)
-DEF(st8_i64, 0, 2, 1, TCG_OPF_SIDE_EFFECTS | TCG_OPF_64BIT)
-DEF(st16_i64, 0, 2, 1, TCG_OPF_SIDE_EFFECTS | TCG_OPF_64BIT)
-DEF(st32_i64, 0, 2, 1, TCG_OPF_SIDE_EFFECTS | TCG_OPF_64BIT)
-DEF(st_i64, 0, 2, 1, TCG_OPF_SIDE_EFFECTS | TCG_OPF_64BIT)
+DEF(ld8u_i64, 1, 1, 1, IMPL64)
+DEF(ld8s_i64, 1, 1, 1, IMPL64)
+DEF(ld16u_i64, 1, 1, 1, IMPL64)
+DEF(ld16s_i64, 1, 1, 1, IMPL64)
+DEF(ld32u_i64, 1, 1, 1, IMPL64)
+DEF(ld32s_i64, 1, 1, 1, IMPL64)
+DEF(ld_i64, 1, 1, 1, IMPL64)
+DEF(st8_i64, 0, 2, 1, TCG_OPF_SIDE_EFFECTS | IMPL64)
+DEF(st16_i64, 0, 2, 1, TCG_OPF_SIDE_EFFECTS | IMPL64)
+DEF(st32_i64, 0, 2, 1, TCG_OPF_SIDE_EFFECTS | IMPL64)
+DEF(st_i64, 0, 2, 1, TCG_OPF_SIDE_EFFECTS | IMPL64)
 /* arith */
-DEF(add_i64, 1, 2, 0, TCG_OPF_64BIT)
-DEF(sub_i64, 1, 2, 0, TCG_OPF_64BIT)
-DEF(mul_i64, 1, 2, 0, TCG_OPF_64BIT)
-#ifdef TCG_TARGET_HAS_div_i64
-DEF(div_i64, 1, 2, 0, TCG_OPF_64BIT)
-DEF(divu_i64, 1, 2, 0, TCG_OPF_64BIT)
-DEF(rem_i64, 1, 2, 0, TCG_OPF_64BIT)
-DEF(remu_i64, 1, 2, 0, TCG_OPF_64BIT)
-#endif
-#ifdef TCG_TARGET_HAS_div2_i64
-DEF(div2_i64, 2, 3, 0, TCG_OPF_64BIT)
-DEF(divu2_i64, 2, 3, 0, TCG_OPF_64BIT)
-#endif
-DEF(and_i64, 1, 2, 0, TCG_OPF_64BIT)
-DEF(or_i64, 1, 2, 0, TCG_OPF_64BIT)
-DEF(xor_i64, 1, 2, 0, TCG_OPF_64BIT)
+DEF(add_i64, 1, 2, 0, IMPL64)
+DEF(sub_i64, 1, 2, 0, IMPL64)
+DEF(mul_i64, 1, 2, 0, IMPL64)
+DEF(div_i64, 1, 2, 0, IMPL64 | IMPL(TCG_TARGET_HAS_div_i64))
+DEF(divu_i64, 1, 2, 0, IMPL64 | IMPL(TCG_TARGET_HAS_div_i64))
+DEF(rem_i64, 1, 2, 0, IMPL64 | IMPL(TCG_TARGET_HAS_div_i64))
+DEF(remu_i64, 1, 2, 0, IMPL64 | IMPL(TCG_TARGET_HAS_div_i64))
+DEF(div2_i64, 2, 3, 0, IMPL64 | IMPL(TCG_TARGET_HAS_div2_i64))
+DEF(divu2_i64, 2, 3, 0, IMPL64 | IMPL(TCG_TARGET_HAS_div2_i64))
+DEF(and_i64, 1, 2, 0, IMPL64)
+DEF(or_i64, 1, 2, 0, IMPL64)
+DEF(xor_i64, 1, 2, 0, IMPL64)
 /* shifts/rotates */
-DEF(shl_i64, 1, 2, 0, TCG_OPF_64BIT)
-DEF(shr_i64, 1, 2, 0, TCG_OPF_64BIT)
-DEF(sar_i64, 1, 2, 0, TCG_OPF_64BIT)
-#ifdef TCG_TARGET_HAS_rot_i64
-DEF(rotl_i64, 1, 2, 0, TCG_OPF_64BIT)
-DEF(rotr_i64, 1, 2, 0, TCG_OPF_64BIT)
-#endif
-#ifdef TCG_TARGET_HAS_deposit_i64
-DEF(deposit_i64, 1, 2, 2, TCG_OPF_64BIT)
-#endif
+DEF(shl_i64, 1, 2, 0, IMPL64)
+DEF(shr_i64, 1, 2, 0, IMPL64)
+DEF(sar_i64, 1, 2, 0, IMPL64)
+DEF(rotl_i64, 1, 2, 0, IMPL64 | IMPL(TCG_TARGET_HAS_rot_i64))
+DEF(rotr_i64, 1, 2, 0, IMPL64 | IMPL(TCG_TARGET_HAS_rot_i64))
+DEF(deposit_i64, 1, 2, 2, IMPL64 | IMPL(TCG_TARGET_HAS_deposit_i64))
 
-DEF(brcond_i64, 0, 2, 2, TCG_OPF_BB_END | TCG_OPF_SIDE_EFFECTS | TCG_OPF_64BIT)
-#ifdef TCG_TARGET_HAS_ext8s_i64
-DEF(ext8s_i64, 1, 1, 0, TCG_OPF_64BIT)
-#endif
-#ifdef TCG_TARGET_HAS_ext16s_i64
-DEF(ext16s_i64, 1, 1, 0, TCG_OPF_64BIT)
-#endif
-#ifdef TCG_TARGET_HAS_ext32s_i64
-DEF(ext32s_i64, 1, 1, 0, TCG_OPF_64BIT)
-#endif
-#ifdef TCG_TARGET_HAS_ext8u_i64
-DEF(ext8u_i64, 1, 1, 0, TCG_OPF_64BIT)
-#endif
-#ifdef TCG_TARGET_HAS_ext16u_i64
-DEF(ext16u_i64, 1, 1, 0, TCG_OPF_64BIT)
-#endif
-#ifdef TCG_TARGET_HAS_ext32u_i64
-DEF(ext32u_i64, 1, 1, 0, TCG_OPF_64BIT)
-#endif
-#ifdef TCG_TARGET_HAS_bswap16_i64
-DEF(bswap16_i64, 1, 1, 0, TCG_OPF_64BIT)
-#endif
-#ifdef TCG_TARGET_HAS_bswap32_i64
-DEF(bswap32_i64, 1, 1, 0, TCG_OPF_64BIT)
-#endif
-#ifdef TCG_TARGET_HAS_bswap64_i64
-DEF(bswap64_i64, 1, 1, 0, TCG_OPF_64BIT)
-#endif
-#ifdef TCG_TARGET_HAS_not_i64
-DEF(not_i64, 1, 1, 0, TCG_OPF_64BIT)
-#endif
-#ifdef TCG_TARGET_HAS_neg_i64
-DEF(neg_i64, 1, 1, 0, TCG_OPF_64BIT)
-#endif
-#ifdef TCG_TARGET_HAS_andc_i64
-DEF(andc_i64, 1, 2, 0, TCG_OPF_64BIT)
-#endif
-#ifdef TCG_TARGET_HAS_orc_i64
-DEF(orc_i64, 1, 2, 0, TCG_OPF_64BIT)
-#endif
-#ifdef TCG_TARGET_HAS_eqv_i64
-DEF(eqv_i64, 1, 2, 0, TCG_OPF_64BIT)
-#endif
-#ifdef TCG_TARGET_HAS_nand_i64
-DEF(nand_i64, 1, 2, 0, TCG_OPF_64BIT)
-#endif
-#ifdef TCG_TARGET_HAS_nor_i64
-DEF(nor_i64, 1, 2, 0, TCG_OPF_64BIT)
-#endif
-#endif
+DEF(brcond_i64, 0, 2, 2, TCG_OPF_BB_END | TCG_OPF_SIDE_EFFECTS | IMPL64)
+DEF(ext8s_i64, 1, 1, 0, IMPL64 | IMPL(TCG_TARGET_HAS_ext8s_i64))
+DEF(ext16s_i64, 1, 1, 0, IMPL64 | IMPL(TCG_TARGET_HAS_ext16s_i64))
+DEF(ext32s_i64, 1, 1, 0, IMPL64 | IMPL(TCG_TARGET_HAS_ext32s_i64))
+DEF(ext8u_i64, 1, 1, 0, IMPL64 | IMPL(TCG_TARGET_HAS_ext8u_i64))
+DEF(ext16u_i64, 1, 1, 0, IMPL64 | IMPL(TCG_TARGET_HAS_ext16u_i64))
+DEF(ext32u_i64, 1, 1, 0, IMPL64 | IMPL(TCG_TARGET_HAS_ext32u_i64))
+DEF(bswap16_i64, 1, 1, 0, IMPL64 | IMPL(TCG_TARGET_HAS_bswap16_i64))
+DEF(bswap32_i64, 1, 1, 0, IMPL64 | IMPL(TCG_TARGET_HAS_bswap32_i64))
+DEF(bswap64_i64, 1, 1, 0, IMPL64 | IMPL(TCG_TARGET_HAS_bswap64_i64))
+DEF(not_i64, 1, 1, 0, IMPL64 | IMPL(TCG_TARGET_HAS_not_i64))
+DEF(neg_i64, 1, 1, 0, IMPL64 | IMPL(TCG_TARGET_HAS_neg_i64))
+DEF(andc_i64, 1, 2, 0, IMPL64 | IMPL(TCG_TARGET_HAS_andc_i64))
+DEF(orc_i64, 1, 2, 0, IMPL64 | IMPL(TCG_TARGET_HAS_orc_i64))
+DEF(eqv_i64, 1, 2, 0, IMPL64 | IMPL(TCG_TARGET_HAS_eqv_i64))
+DEF(nand_i64, 1, 2, 0, IMPL64 | IMPL(TCG_TARGET_HAS_nand_i64))
+DEF(nor_i64, 1, 2, 0, IMPL64 | IMPL(TCG_TARGET_HAS_nor_i64))
 
 /* QEMU specific */
 #if TARGET_LONG_BITS > TCG_TARGET_REG_BITS
@@ -307,4 +239,6 @@ DEF(qemu_st64, 0, 2, 1, TCG_OPF_CALL_CLOBBER | TCG_OPF_SIDE_EFFECTS)
 
 #endif /* TCG_TARGET_REG_BITS != 32 */
 
+#undef IMPL
+#undef IMPL64
 #undef DEF
diff --git a/tcg/tcg.c b/tcg/tcg.c
index 70f19e4..06ce214 100644
--- a/tcg/tcg.c
+++ b/tcg/tcg.c
@@ -2124,6 +2124,10 @@ static inline int tcg_gen_code_common(TCGContext *s, uint8_t *gen_code_buf,
         case INDEX_op_end:
             goto the_end;
         default:
+            /* Sanity check that we've not introduced any unhandled opcodes. */
+            if (def->flags & TCG_OPF_NOT_PRESENT) {
+                tcg_abort();
+            }
             /* Note: in order to speed up the code, it would be much
                faster to have specialized register allocator functions for
                some common argument patterns */
diff --git a/tcg/tcg.h b/tcg/tcg.h
index 6a4f6e4..dc5e9c9 100644
--- a/tcg/tcg.h
+++ b/tcg/tcg.h
@@ -47,6 +47,42 @@ typedef uint64_t TCGRegSet;
 #error unsupported
 #endif
 
+/* Turn some undef macros into false macros.  */
+#if TCG_TARGET_REG_BITS == 32
+#define TCG_TARGET_HAS_div_i64          0
+#define TCG_TARGET_HAS_div2_i64         0
+#define TCG_TARGET_HAS_rot_i64          0
+#define TCG_TARGET_HAS_ext8s_i64        0
+#define TCG_TARGET_HAS_ext16s_i64       0
+#define TCG_TARGET_HAS_ext32s_i64       0
+#define TCG_TARGET_HAS_ext8u_i64        0
+#define TCG_TARGET_HAS_ext16u_i64       0
+#define TCG_TARGET_HAS_ext32u_i64       0
+#define TCG_TARGET_HAS_bswap16_i64      0
+#define TCG_TARGET_HAS_bswap32_i64      0
+#define TCG_TARGET_HAS_bswap64_i64      0
+#define TCG_TARGET_HAS_neg_i64          0
+#define TCG_TARGET_HAS_not_i64          0
+#define TCG_TARGET_HAS_andc_i64         0
+#define TCG_TARGET_HAS_orc_i64          0
+#define TCG_TARGET_HAS_eqv_i64          0
+#define TCG_TARGET_HAS_nand_i64         0
+#define TCG_TARGET_HAS_nor_i64          0
+#define TCG_TARGET_HAS_deposit_i64      0
+#endif
+
+/* Only one of DIV or DIV2 should be defined.  */
+#if defined(TCG_TARGET_HAS_div_i32)
+#define TCG_TARGET_HAS_div2_i32         0
+#elif defined(TCG_TARGET_HAS_div2_i32)
+#define TCG_TARGET_HAS_div_i32          0
+#endif
+#if defined(TCG_TARGET_HAS_div_i64)
+#define TCG_TARGET_HAS_div2_i64         0
+#elif defined(TCG_TARGET_HAS_div2_i64)
+#define TCG_TARGET_HAS_div_i64          0
+#endif
+
 typedef enum TCGOpcode {
 #define DEF(name, oargs, iargs, cargs, flags) INDEX_op_ ## name,
 #include "tcg-opc.h"
@@ -456,6 +492,8 @@ enum {
     TCG_OPF_SIDE_EFFECTS = 0x04,
     /* Instruction operands are 64-bits (otherwise 32-bits).  */
     TCG_OPF_64BIT        = 0x08,
+    /* Instruction is optional and not implemented by the host.  */
+    TCG_OPF_NOT_PRESENT  = 0x10,
 };
 
 typedef struct TCGOpDef {
commit 8399ad59e73a0f48af3edef62f021e2cb6220e12
Author: Richard Henderson <rth at twiddle.net>
Date:   Wed Aug 17 14:11:45 2011 -0700

    tcg: Add and use TCG_OPF_64BIT.
    
    This allows the simplification of the op_bits function from
    tcg/optimize.c.
    
    Signed-off-by: Richard Henderson <rth at twiddle.net>
    Signed-off-by: Blue Swirl <blauwirbel at gmail.com>

diff --git a/tcg/optimize.c b/tcg/optimize.c
index 7eb5eb1..98c7e3f 100644
--- a/tcg/optimize.c
+++ b/tcg/optimize.c
@@ -92,81 +92,10 @@ static void reset_temp(TCGArg temp, int nb_temps, int nb_globals)
     }
 }
 
-static int op_bits(int op)
+static int op_bits(enum TCGOpcode op)
 {
-    switch (op) {
-    case INDEX_op_mov_i32:
-    case INDEX_op_add_i32:
-    case INDEX_op_sub_i32:
-    case INDEX_op_mul_i32:
-    case INDEX_op_and_i32:
-    case INDEX_op_or_i32:
-    case INDEX_op_xor_i32:
-    case INDEX_op_shl_i32:
-    case INDEX_op_shr_i32:
-    case INDEX_op_sar_i32:
-#ifdef TCG_TARGET_HAS_rot_i32
-    case INDEX_op_rotl_i32:
-    case INDEX_op_rotr_i32:
-#endif
-#ifdef TCG_TARGET_HAS_not_i32
-    case INDEX_op_not_i32:
-#endif
-#ifdef TCG_TARGET_HAS_ext8s_i32
-    case INDEX_op_ext8s_i32:
-#endif
-#ifdef TCG_TARGET_HAS_ext16s_i32
-    case INDEX_op_ext16s_i32:
-#endif
-#ifdef TCG_TARGET_HAS_ext8u_i32
-    case INDEX_op_ext8u_i32:
-#endif
-#ifdef TCG_TARGET_HAS_ext16u_i32
-    case INDEX_op_ext16u_i32:
-#endif
-        return 32;
-#if TCG_TARGET_REG_BITS == 64
-    case INDEX_op_mov_i64:
-    case INDEX_op_add_i64:
-    case INDEX_op_sub_i64:
-    case INDEX_op_mul_i64:
-    case INDEX_op_and_i64:
-    case INDEX_op_or_i64:
-    case INDEX_op_xor_i64:
-    case INDEX_op_shl_i64:
-    case INDEX_op_shr_i64:
-    case INDEX_op_sar_i64:
-#ifdef TCG_TARGET_HAS_rot_i64
-    case INDEX_op_rotl_i64:
-    case INDEX_op_rotr_i64:
-#endif
-#ifdef TCG_TARGET_HAS_not_i64
-    case INDEX_op_not_i64:
-#endif
-#ifdef TCG_TARGET_HAS_ext8s_i64
-    case INDEX_op_ext8s_i64:
-#endif
-#ifdef TCG_TARGET_HAS_ext16s_i64
-    case INDEX_op_ext16s_i64:
-#endif
-#ifdef TCG_TARGET_HAS_ext32s_i64
-    case INDEX_op_ext32s_i64:
-#endif
-#ifdef TCG_TARGET_HAS_ext8u_i64
-    case INDEX_op_ext8u_i64:
-#endif
-#ifdef TCG_TARGET_HAS_ext16u_i64
-    case INDEX_op_ext16u_i64:
-#endif
-#ifdef TCG_TARGET_HAS_ext32u_i64
-    case INDEX_op_ext32u_i64:
-#endif
-        return 64;
-#endif
-    default:
-        fprintf(stderr, "Unrecognized operation %d in op_bits.\n", op);
-        tcg_abort();
-    }
+    const TCGOpDef *def = &tcg_op_defs[op];
+    return def->flags & TCG_OPF_64BIT ? 64 : 32;
 }
 
 static int op_to_movi(int op)
diff --git a/tcg/tcg-opc.h b/tcg/tcg-opc.h
index 2c7ca1a..b48669b 100644
--- a/tcg/tcg-opc.h
+++ b/tcg/tcg-opc.h
@@ -131,98 +131,98 @@ DEF(nor_i32, 1, 2, 0, 0)
 #endif
 
 #if TCG_TARGET_REG_BITS == 64
-DEF(mov_i64, 1, 1, 0, 0)
-DEF(movi_i64, 1, 0, 1, 0)
-DEF(setcond_i64, 1, 2, 1, 0)
+DEF(mov_i64, 1, 1, 0, TCG_OPF_64BIT)
+DEF(movi_i64, 1, 0, 1, TCG_OPF_64BIT)
+DEF(setcond_i64, 1, 2, 1, TCG_OPF_64BIT)
 /* load/store */
-DEF(ld8u_i64, 1, 1, 1, 0)
-DEF(ld8s_i64, 1, 1, 1, 0)
-DEF(ld16u_i64, 1, 1, 1, 0)
-DEF(ld16s_i64, 1, 1, 1, 0)
-DEF(ld32u_i64, 1, 1, 1, 0)
-DEF(ld32s_i64, 1, 1, 1, 0)
-DEF(ld_i64, 1, 1, 1, 0)
-DEF(st8_i64, 0, 2, 1, TCG_OPF_SIDE_EFFECTS)
-DEF(st16_i64, 0, 2, 1, TCG_OPF_SIDE_EFFECTS)
-DEF(st32_i64, 0, 2, 1, TCG_OPF_SIDE_EFFECTS)
-DEF(st_i64, 0, 2, 1, TCG_OPF_SIDE_EFFECTS)
+DEF(ld8u_i64, 1, 1, 1, TCG_OPF_64BIT)
+DEF(ld8s_i64, 1, 1, 1, TCG_OPF_64BIT)
+DEF(ld16u_i64, 1, 1, 1, TCG_OPF_64BIT)
+DEF(ld16s_i64, 1, 1, 1, TCG_OPF_64BIT)
+DEF(ld32u_i64, 1, 1, 1, TCG_OPF_64BIT)
+DEF(ld32s_i64, 1, 1, 1, TCG_OPF_64BIT)
+DEF(ld_i64, 1, 1, 1, TCG_OPF_64BIT)
+DEF(st8_i64, 0, 2, 1, TCG_OPF_SIDE_EFFECTS | TCG_OPF_64BIT)
+DEF(st16_i64, 0, 2, 1, TCG_OPF_SIDE_EFFECTS | TCG_OPF_64BIT)
+DEF(st32_i64, 0, 2, 1, TCG_OPF_SIDE_EFFECTS | TCG_OPF_64BIT)
+DEF(st_i64, 0, 2, 1, TCG_OPF_SIDE_EFFECTS | TCG_OPF_64BIT)
 /* arith */
-DEF(add_i64, 1, 2, 0, 0)
-DEF(sub_i64, 1, 2, 0, 0)
-DEF(mul_i64, 1, 2, 0, 0)
+DEF(add_i64, 1, 2, 0, TCG_OPF_64BIT)
+DEF(sub_i64, 1, 2, 0, TCG_OPF_64BIT)
+DEF(mul_i64, 1, 2, 0, TCG_OPF_64BIT)
 #ifdef TCG_TARGET_HAS_div_i64
-DEF(div_i64, 1, 2, 0, 0)
-DEF(divu_i64, 1, 2, 0, 0)
-DEF(rem_i64, 1, 2, 0, 0)
-DEF(remu_i64, 1, 2, 0, 0)
+DEF(div_i64, 1, 2, 0, TCG_OPF_64BIT)
+DEF(divu_i64, 1, 2, 0, TCG_OPF_64BIT)
+DEF(rem_i64, 1, 2, 0, TCG_OPF_64BIT)
+DEF(remu_i64, 1, 2, 0, TCG_OPF_64BIT)
 #endif
 #ifdef TCG_TARGET_HAS_div2_i64
-DEF(div2_i64, 2, 3, 0, 0)
-DEF(divu2_i64, 2, 3, 0, 0)
+DEF(div2_i64, 2, 3, 0, TCG_OPF_64BIT)
+DEF(divu2_i64, 2, 3, 0, TCG_OPF_64BIT)
 #endif
-DEF(and_i64, 1, 2, 0, 0)
-DEF(or_i64, 1, 2, 0, 0)
-DEF(xor_i64, 1, 2, 0, 0)
+DEF(and_i64, 1, 2, 0, TCG_OPF_64BIT)
+DEF(or_i64, 1, 2, 0, TCG_OPF_64BIT)
+DEF(xor_i64, 1, 2, 0, TCG_OPF_64BIT)
 /* shifts/rotates */
-DEF(shl_i64, 1, 2, 0, 0)
-DEF(shr_i64, 1, 2, 0, 0)
-DEF(sar_i64, 1, 2, 0, 0)
+DEF(shl_i64, 1, 2, 0, TCG_OPF_64BIT)
+DEF(shr_i64, 1, 2, 0, TCG_OPF_64BIT)
+DEF(sar_i64, 1, 2, 0, TCG_OPF_64BIT)
 #ifdef TCG_TARGET_HAS_rot_i64
-DEF(rotl_i64, 1, 2, 0, 0)
-DEF(rotr_i64, 1, 2, 0, 0)
+DEF(rotl_i64, 1, 2, 0, TCG_OPF_64BIT)
+DEF(rotr_i64, 1, 2, 0, TCG_OPF_64BIT)
 #endif
 #ifdef TCG_TARGET_HAS_deposit_i64
-DEF(deposit_i64, 1, 2, 2, 0)
+DEF(deposit_i64, 1, 2, 2, TCG_OPF_64BIT)
 #endif
 
-DEF(brcond_i64, 0, 2, 2, TCG_OPF_BB_END | TCG_OPF_SIDE_EFFECTS)
+DEF(brcond_i64, 0, 2, 2, TCG_OPF_BB_END | TCG_OPF_SIDE_EFFECTS | TCG_OPF_64BIT)
 #ifdef TCG_TARGET_HAS_ext8s_i64
-DEF(ext8s_i64, 1, 1, 0, 0)
+DEF(ext8s_i64, 1, 1, 0, TCG_OPF_64BIT)
 #endif
 #ifdef TCG_TARGET_HAS_ext16s_i64
-DEF(ext16s_i64, 1, 1, 0, 0)
+DEF(ext16s_i64, 1, 1, 0, TCG_OPF_64BIT)
 #endif
 #ifdef TCG_TARGET_HAS_ext32s_i64
-DEF(ext32s_i64, 1, 1, 0, 0)
+DEF(ext32s_i64, 1, 1, 0, TCG_OPF_64BIT)
 #endif
 #ifdef TCG_TARGET_HAS_ext8u_i64
-DEF(ext8u_i64, 1, 1, 0, 0)
+DEF(ext8u_i64, 1, 1, 0, TCG_OPF_64BIT)
 #endif
 #ifdef TCG_TARGET_HAS_ext16u_i64
-DEF(ext16u_i64, 1, 1, 0, 0)
+DEF(ext16u_i64, 1, 1, 0, TCG_OPF_64BIT)
 #endif
 #ifdef TCG_TARGET_HAS_ext32u_i64
-DEF(ext32u_i64, 1, 1, 0, 0)
+DEF(ext32u_i64, 1, 1, 0, TCG_OPF_64BIT)
 #endif
 #ifdef TCG_TARGET_HAS_bswap16_i64
-DEF(bswap16_i64, 1, 1, 0, 0)
+DEF(bswap16_i64, 1, 1, 0, TCG_OPF_64BIT)
 #endif
 #ifdef TCG_TARGET_HAS_bswap32_i64
-DEF(bswap32_i64, 1, 1, 0, 0)
+DEF(bswap32_i64, 1, 1, 0, TCG_OPF_64BIT)
 #endif
 #ifdef TCG_TARGET_HAS_bswap64_i64
-DEF(bswap64_i64, 1, 1, 0, 0)
+DEF(bswap64_i64, 1, 1, 0, TCG_OPF_64BIT)
 #endif
 #ifdef TCG_TARGET_HAS_not_i64
-DEF(not_i64, 1, 1, 0, 0)
+DEF(not_i64, 1, 1, 0, TCG_OPF_64BIT)
 #endif
 #ifdef TCG_TARGET_HAS_neg_i64
-DEF(neg_i64, 1, 1, 0, 0)
+DEF(neg_i64, 1, 1, 0, TCG_OPF_64BIT)
 #endif
 #ifdef TCG_TARGET_HAS_andc_i64
-DEF(andc_i64, 1, 2, 0, 0)
+DEF(andc_i64, 1, 2, 0, TCG_OPF_64BIT)
 #endif
 #ifdef TCG_TARGET_HAS_orc_i64
-DEF(orc_i64, 1, 2, 0, 0)
+DEF(orc_i64, 1, 2, 0, TCG_OPF_64BIT)
 #endif
 #ifdef TCG_TARGET_HAS_eqv_i64
-DEF(eqv_i64, 1, 2, 0, 0)
+DEF(eqv_i64, 1, 2, 0, TCG_OPF_64BIT)
 #endif
 #ifdef TCG_TARGET_HAS_nand_i64
-DEF(nand_i64, 1, 2, 0, 0)
+DEF(nand_i64, 1, 2, 0, TCG_OPF_64BIT)
 #endif
 #ifdef TCG_TARGET_HAS_nor_i64
-DEF(nor_i64, 1, 2, 0, 0)
+DEF(nor_i64, 1, 2, 0, TCG_OPF_64BIT)
 #endif
 #endif
 
diff --git a/tcg/tcg.c b/tcg/tcg.c
index c735348..70f19e4 100644
--- a/tcg/tcg.c
+++ b/tcg/tcg.c
@@ -68,7 +68,7 @@ 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);
 
-static TCGOpDef tcg_op_defs[] = {
+TCGOpDef tcg_op_defs[] = {
 #define DEF(s, oargs, iargs, cargs, flags) { #s, oargs, iargs, cargs, iargs + oargs + cargs, flags },
 #include "tcg-opc.h"
 #undef DEF
diff --git a/tcg/tcg.h b/tcg/tcg.h
index e2a7095..6a4f6e4 100644
--- a/tcg/tcg.h
+++ b/tcg/tcg.h
@@ -445,13 +445,18 @@ typedef struct TCGArgConstraint {
 
 #define TCG_MAX_OP_ARGS 16
 
-#define TCG_OPF_BB_END     0x01 /* instruction defines the end of a basic
-                                   block */
-#define TCG_OPF_CALL_CLOBBER 0x02 /* instruction clobbers call registers 
-                                   and potentially update globals. */
-#define TCG_OPF_SIDE_EFFECTS 0x04 /* instruction has side effects : it
-                                     cannot be removed if its output
-                                     are not used */
+/* Bits for TCGOpDef->flags, 8 bits available.  */
+enum {
+    /* Instruction defines the end of a basic block.  */
+    TCG_OPF_BB_END       = 0x01,
+    /* Instruction clobbers call registers and potentially update globals.  */
+    TCG_OPF_CALL_CLOBBER = 0x02,
+    /* Instruction has side effects: it cannot be removed
+       if its outputs are not used.  */
+    TCG_OPF_SIDE_EFFECTS = 0x04,
+    /* Instruction operands are 64-bits (otherwise 32-bits).  */
+    TCG_OPF_64BIT        = 0x08,
+};
 
 typedef struct TCGOpDef {
     const char *name;
@@ -463,6 +468,8 @@ typedef struct TCGOpDef {
     int used;
 #endif
 } TCGOpDef;
+
+extern TCGOpDef tcg_op_defs[];
         
 typedef struct TCGTargetOpDef {
     TCGOpcode op;
commit 4b29ec41c82a6e6c6a50263818e81944ef522fb2
Author: Brad <brad at comstyle.com>
Date:   Sun Aug 7 20:02:11 2011 -0400

    Check for presence of compiler -pthread flag.
    
    OpenBSD / FreeBSD and some other OS's require the use of
    cc -pthread to link threaded programs so have QEMU's
    configure script check for the presence of the flag
    and use it if so.
    
    Signed-off-by: Brad Smith <brad at comstyle.com>
    Signed-off-by: Blue Swirl <blauwirbel at gmail.com>

diff --git a/configure b/configure
index 79ddcad..8513875 100755
--- a/configure
+++ b/configure
@@ -1856,7 +1856,7 @@ fi
 
 ##########################################
 # pthread probe
-PTHREADLIBS_LIST="-lpthread -lpthreadGC2"
+PTHREADLIBS_LIST="-pthread -lpthread -lpthreadGC2"
 
 pthread=no
 cat > $TMPC << EOF
commit 58a06675d39955e80154c36cff5113bb30e078a7
Author: Blue Swirl <blauwirbel at gmail.com>
Date:   Sun Aug 21 18:42:08 2011 +0000

    Convert last qemu_free and qemu_malloc uses
    
    7267c0947d7e8ae5dff7bafd932c3bc285f43e5c missed
    a few cases, fix them.
    
    Signed-off-by: Blue Swirl <blauwirbel at gmail.com>

diff --git a/HACKING b/HACKING
index 5b4ae10..733eab2 100644
--- a/HACKING
+++ b/HACKING
@@ -80,7 +80,7 @@ APIs is not allowed in the QEMU codebase. Instead of these routines,
 use the replacement g_malloc/g_malloc0/g_realloc/g_free or
 qemu_vmalloc/qemu_memalign/qemu_vfree APIs.
 
-Please note that NULL check for the qemu_malloc result is redundant and
+Please note that NULL check for the g_malloc result is redundant and
 that g_malloc() call with zero size is not allowed.
 
 Memory allocated by qemu_vmalloc or qemu_memalign must be freed with
diff --git a/coroutine-gthread.c b/coroutine-gthread.c
index b00e548..fdea27a 100644
--- a/coroutine-gthread.c
+++ b/coroutine-gthread.c
@@ -117,7 +117,7 @@ Coroutine *qemu_coroutine_self(void)
     if (!co) {
         co = g_malloc0(sizeof(*co));
         co->runnable = true;
-        g_static_private_set(&coroutine_key, co, (GDestroyNotify)qemu_free);
+        g_static_private_set(&coroutine_key, co, (GDestroyNotify)g_free);
     }
 
     return &co->base;
diff --git a/ui/cocoa.m b/ui/cocoa.m
index 515e684..d9e4e3d 100644
--- a/ui/cocoa.m
+++ b/ui/cocoa.m
@@ -1004,15 +1004,15 @@ static void cocoa_refresh(DisplayState *ds)
 static void cocoa_cleanup(void)
 {
     COCOA_DEBUG("qemu_cocoa: cocoa_cleanup\n");
-	qemu_free(dcl);
+    g_free(dcl);
 }
 
 void cocoa_display_init(DisplayState *ds, int full_screen)
 {
     COCOA_DEBUG("qemu_cocoa: cocoa_display_init\n");
 
-	dcl = qemu_mallocz(sizeof(DisplayChangeListener));
-	
+    dcl = g_malloc0(sizeof(DisplayChangeListener));
+
     // register vga output callbacks
     dcl->dpy_update = cocoa_update;
     dcl->dpy_resize = cocoa_resize;
commit c76c8416be5631dfdbd13799d3c67ad670637155
Author: Austin Clements <amdragon at MIT.EDU>
Date:   Sun Aug 14 23:22:28 2011 -0400

    monitor: Show combined protection bits in "info mem"
    
    Previously, "info mem" considered and displayed only the last-level
    protection bits for a memory range, which doesn't accurrately
    represent the protection of that range.  Now it shows the combined
    protection.
    
    Signed-off-by: Austin Clements <amdragon at mit.edu>
    Signed-off-by: Blue Swirl <blauwirbel at gmail.com>

diff --git a/monitor.c b/monitor.c
index d1f03e4..0e101f5 100644
--- a/monitor.c
+++ b/monitor.c
@@ -2248,7 +2248,8 @@ static void mem_info_32(Monitor *mon, CPUState *env)
                     pte = le32_to_cpu(pte);
                     end = (l1 << 22) + (l2 << 12);
                     if (pte & PG_PRESENT_MASK) {
-                        prot = pte & (PG_USER_MASK | PG_RW_MASK | PG_PRESENT_MASK);
+                        prot = pte & pde &
+                            (PG_USER_MASK | PG_RW_MASK | PG_PRESENT_MASK);
                     } else {
                         prot = 0;
                     }
@@ -2297,8 +2298,8 @@ static void mem_info_pae32(Monitor *mon, CPUState *env)
                             pte = le64_to_cpu(pte);
                             end = (l1 << 30) + (l2 << 21) + (l3 << 12);
                             if (pte & PG_PRESENT_MASK) {
-                                prot = pte & (PG_USER_MASK | PG_RW_MASK |
-                                              PG_PRESENT_MASK);
+                                prot = pte & pde & (PG_USER_MASK | PG_RW_MASK |
+                                                    PG_PRESENT_MASK);
                             } else {
                                 prot = 0;
                             }
@@ -2345,6 +2346,7 @@ static void mem_info_64(Monitor *mon, CPUState *env)
                     if (pdpe & PG_PSE_MASK) {
                         prot = pdpe & (PG_USER_MASK | PG_RW_MASK |
                                        PG_PRESENT_MASK);
+                        prot &= pml4e;
                         mem_print(mon, &start, &last_prot, end, prot);
                     } else {
                         pd_addr = pdpe & 0x3fffffffff000ULL;
@@ -2356,6 +2358,7 @@ static void mem_info_64(Monitor *mon, CPUState *env)
                                 if (pde & PG_PSE_MASK) {
                                     prot = pde & (PG_USER_MASK | PG_RW_MASK |
                                                   PG_PRESENT_MASK);
+                                    prot &= pml4e & pdpe;
                                     mem_print(mon, &start, &last_prot, end, prot);
                                 } else {
                                     pt_addr = pde & 0x3fffffffff000ULL;
@@ -2369,6 +2372,7 @@ static void mem_info_64(Monitor *mon, CPUState *env)
                                         if (pte & PG_PRESENT_MASK) {
                                             prot = pte & (PG_USER_MASK | PG_RW_MASK |
                                                           PG_PRESENT_MASK);
+                                            prot &= pml4e & pdpe & pde;
                                         } else {
                                             prot = 0;
                                         }
commit 8a94b8ca530a983dacc78bd165fa2afb95205cb0
Author: Austin Clements <amdragon at MIT.EDU>
Date:   Sun Aug 14 23:22:04 2011 -0400

    monitor: Fix "info mem" to print the last memory range
    
    "info mem" groups its output into contiguous ranges with identical
    protection bits, but previously forgot to print the last range.
    
    Signed-off-by: Austin Clements <amdragon at mit.edu>
    Signed-off-by: Blue Swirl <blauwirbel at gmail.com>

diff --git a/monitor.c b/monitor.c
index d049923..d1f03e4 100644
--- a/monitor.c
+++ b/monitor.c
@@ -2260,6 +2260,8 @@ static void mem_info_32(Monitor *mon, CPUState *env)
             mem_print(mon, &start, &last_prot, end, prot);
         }
     }
+    /* Flush last range */
+    mem_print(mon, &start, &last_prot, (target_phys_addr_t)1 << 32, 0);
 }
 
 static void mem_info_pae32(Monitor *mon, CPUState *env)
@@ -2313,6 +2315,8 @@ static void mem_info_pae32(Monitor *mon, CPUState *env)
             mem_print(mon, &start, &last_prot, end, prot);
         }
     }
+    /* Flush last range */
+    mem_print(mon, &start, &last_prot, (target_phys_addr_t)1 << 32, 0);
 }
 
 
@@ -2387,6 +2391,8 @@ static void mem_info_64(Monitor *mon, CPUState *env)
             mem_print(mon, &start, &last_prot, end, prot);
         }
     }
+    /* Flush last range */
+    mem_print(mon, &start, &last_prot, (target_phys_addr_t)1 << 48, 0);
 }
 #endif
 
commit b49ca72dd7c6157324656694a924ad1d781e2916
Author: Austin Clements <amdragon at MIT.EDU>
Date:   Sun Aug 14 23:19:21 2011 -0400

    monitor: Prevent sign-extension of 32-bit addresses printed by info mem
    
    Previously, on 32-bit i386, info mem used signed 32-bit int's to store
    the page table indexes.  As a result, address calculation was done in
    32 bits and then incorrectly sign-extended to 64 bits, yielding output
    like
    
    ffffffffef000000-ffffffffef031000 0000000000031000 ur-
    ffffffffef7bc000-ffffffffef7bd000 0000000000001000 urw
    ffffffffef7bd000-ffffffffef7be000 0000000000001000 ur-
    
    This makes these indexes unsigned, which yields correct output
    
    00000000ef000000-00000000ef031000 0000000000031000 ur-
    00000000ef7bc000-00000000ef7bd000 0000000000001000 urw
    00000000ef7bd000-00000000ef7be000 0000000000001000 ur-
    
    Signed-off-by: Austin Clements <amdragon at mit.edu>
    Signed-off-by: Blue Swirl <blauwirbel at gmail.com>

diff --git a/monitor.c b/monitor.c
index 68553f1..d049923 100644
--- a/monitor.c
+++ b/monitor.c
@@ -2226,7 +2226,8 @@ static void mem_print(Monitor *mon, target_phys_addr_t *pstart,
 
 static void mem_info_32(Monitor *mon, CPUState *env)
 {
-    int l1, l2, prot, last_prot;
+    unsigned int l1, l2;
+    int prot, last_prot;
     uint32_t pgd, pde, pte;
     target_phys_addr_t start, end;
 
@@ -2263,7 +2264,8 @@ static void mem_info_32(Monitor *mon, CPUState *env)
 
 static void mem_info_pae32(Monitor *mon, CPUState *env)
 {
-    int l1, l2, l3, prot, last_prot;
+    unsigned int l1, l2, l3;
+    int prot, last_prot;
     uint64_t pdpe, pde, pte;
     uint64_t pdp_addr, pd_addr, pt_addr;
     target_phys_addr_t start, end;
commit 59ad3403c29e6b2b4f7a2f3c20d1c3fd093565ec
Author: Stefan Weil <weil at mail.berlios.de>
Date:   Fri Jul 15 21:38:14 2011 +0200

    w32: Fix format string regression
    
    Commit 953ffe0f935f40c0d6061d69e76e0339393b54f8
    introduced FMT_pid which is wrong for w32 and w64 getpid():
    those getpid() implementations always return an int value.
    
    Signed-off-by: Stefan Weil <weil at mail.berlios.de>
    Signed-off-by: Blue Swirl <blauwirbel at gmail.com>

diff --git a/os-win32.c b/os-win32.c
index d3cea42..f09f01f 100644
--- a/os-win32.c
+++ b/os-win32.c
@@ -258,7 +258,7 @@ int qemu_create_pidfile(const char *filename)
     if (file == INVALID_HANDLE_VALUE) {
         return -1;
     }
-    len = snprintf(buffer, sizeof(buffer), FMT_pid "\n", getpid());
+    len = snprintf(buffer, sizeof(buffer), "%d\n", getpid());
     ret = WriteFileEx(file, (LPCVOID)buffer, (DWORD)len,
 		      &overlap, NULL);
     if (ret == 0) {
commit 0e0167bacc405f9ba5b056d7d41264ccd0b000ca
Author: Stefan Weil <weil at mail.berlios.de>
Date:   Fri Jul 15 21:38:13 2011 +0200

    w64: Add definition of FMT_pid
    
    For mingw-w64, pid_t is _pid_t which is __int64,
    so this platform needs its own definition of FMT_pid.
    
    Reviewed-by: Andreas Färber <andreas.faerber at web.de>
    Signed-off-by: Stefan Weil <weil at mail.berlios.de>
    Signed-off-by: Blue Swirl <blauwirbel at gmail.com>

diff --git a/osdep.h b/osdep.h
index a817017..252d050 100644
--- a/osdep.h
+++ b/osdep.h
@@ -130,6 +130,8 @@ int qemu_madvise(void *addr, size_t len, int advice);
 
 #if defined(__HAIKU__) && defined(__i386__)
 #define FMT_pid "%ld"
+#elif defined(WIN64)
+#define FMT_pid "%" PRId64
 #else
 #define FMT_pid "%d"
 #endif
commit 3feaca9e88ddc72b3a9d7388fd542d1c0a5c24fb
Author: Stefan Weil <weil at mail.berlios.de>
Date:   Fri Jul 15 21:38:12 2011 +0200

    Fix conversions from pointer to tcg_target_long
    
    tcg_gen_exit_tb takes a parameter of type tcg_target_long,
    so the type casts of pointer to long should be replaced by
    type casts of pointer to tcg_target_long.
    
    These changes are needed for build environments where
    sizeof(long) != sizeof(void *), especially for w64.
    
    See 4b4a72e55660abf7efe85aca78762dcfea5519ad which fixed the
    same issue for the other targets.
    
    Cc: Alexander Graf <agraf at suse.de>
    Cc: Guan Xuetao <gxt at mprc.pku.edu.cn>
    Acked-by: Guan Xuetao<gxt at mprc.pku.edu.cn>
    Acked-by: Alexander Graf <agraf at suse.de>
    Signed-off-by: Stefan Weil <weil at mail.berlios.de>
    Signed-off-by: Blue Swirl <blauwirbel at gmail.com>

diff --git a/target-s390x/translate.c b/target-s390x/translate.c
index 77fb448..6a22fde 100644
--- a/target-s390x/translate.c
+++ b/target-s390x/translate.c
@@ -830,7 +830,7 @@ static inline void gen_goto_tb(DisasContext *s, int tb_num, target_ulong pc)
         /* jump to same page: we can use a direct jump */
         tcg_gen_goto_tb(tb_num);
         tcg_gen_movi_i64(psw_addr, pc);
-        tcg_gen_exit_tb((long)tb + tb_num);
+        tcg_gen_exit_tb((tcg_target_long)tb + tb_num);
     } else {
         /* jump to another page: currently not optimized */
         tcg_gen_movi_i64(psw_addr, pc);
diff --git a/target-unicore32/translate.c b/target-unicore32/translate.c
index a15e42d..4ecb0f1 100644
--- a/target-unicore32/translate.c
+++ b/target-unicore32/translate.c
@@ -1056,7 +1056,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((long)tb + n);
+        tcg_gen_exit_tb((tcg_target_long)tb + n);
     } else {
         gen_set_pc_im(dest);
         tcg_gen_exit_tb(0);
commit 92f562ec5655a7bd783d26b0da995c58436f9125
Author: Anthony Liguori <aliguori at us.ibm.com>
Date:   Sun Aug 21 08:36:21 2011 -0500

    Remove remenants of qemu_malloc
    
    This covers the various check commands
    
    Signed-off-by: Anthony Liguori <aliguori at us.ibm.com>

diff --git a/Makefile b/Makefile
index 516a254..eb3e338 100644
--- a/Makefile
+++ b/Makefile
@@ -131,7 +131,7 @@ libcacard.la:
 install-libcacard:
 	@echo "libtool is missing, please install and rerun configure"; exit 1
 else
-libcacard.la: $(GENERATED_HEADERS) $(oslib-obj-y) qemu-malloc.o qemu-timer-common.o $(addsuffix .lo, $(basename $(trace-obj-y)))
+libcacard.la: $(GENERATED_HEADERS) $(oslib-obj-y) qemu-timer-common.o $(addsuffix .lo, $(basename $(trace-obj-y)))
 	$(call quiet-command,$(MAKE) $(SUBDIR_MAKEFLAGS) -C libcacard V="$(V)" TARGET_DIR="$*/" libcacard.la,)
 
 install-libcacard: libcacard.la
@@ -153,7 +153,7 @@ qemu-img-cmds.h: $(SRC_PATH)/qemu-img-cmds.hx
 
 check-qint.o check-qstring.o check-qdict.o check-qlist.o check-qfloat.o check-qjson.o test-coroutine.o: $(GENERATED_HEADERS)
 
-CHECK_PROG_DEPS = qemu-malloc.o $(oslib-obj-y) $(trace-obj-y) qemu-tool.o
+CHECK_PROG_DEPS = $(oslib-obj-y) $(trace-obj-y) qemu-tool.o
 
 check-qint: check-qint.o qint.o $(CHECK_PROG_DEPS)
 check-qstring: check-qstring.o qstring.o $(CHECK_PROG_DEPS)
@@ -187,10 +187,10 @@ $(qapi-dir)/qga-qmp-marshal.c: $(SRC_PATH)/qapi-schema-guest.json $(SRC_PATH)/sc
 	$(call quiet-command,$(PYTHON) $(SRC_PATH)/scripts/qapi-commands.py -o "$(qapi-dir)" -p "qga-" < $<, "  GEN   $@")
 
 test-visitor.o: $(addprefix $(qapi-dir)/, test-qapi-types.c test-qapi-types.h test-qapi-visit.c test-qapi-visit.h) $(qapi-obj-y)
-test-visitor: test-visitor.o qfloat.o qint.o qdict.o qstring.o qlist.o qbool.o $(qapi-obj-y) error.o osdep.o qemu-malloc.o $(oslib-obj-y) qjson.o json-streamer.o json-lexer.o json-parser.o qerror.o qemu-error.o qemu-tool.o $(qapi-dir)/test-qapi-visit.o $(qapi-dir)/test-qapi-types.o
+test-visitor: test-visitor.o qfloat.o qint.o qdict.o qstring.o qlist.o qbool.o $(qapi-obj-y) error.o osdep.o $(oslib-obj-y) qjson.o json-streamer.o json-lexer.o json-parser.o qerror.o qemu-error.o qemu-tool.o $(qapi-dir)/test-qapi-visit.o $(qapi-dir)/test-qapi-types.o
 
 test-qmp-commands.o: $(addprefix $(qapi-dir)/, test-qapi-types.c test-qapi-types.h test-qapi-visit.c test-qapi-visit.h test-qmp-marshal.c test-qmp-commands.h) $(qapi-obj-y)
-test-qmp-commands: test-qmp-commands.o qfloat.o qint.o qdict.o qstring.o qlist.o qbool.o $(qapi-obj-y) error.o osdep.o qemu-malloc.o $(oslib-obj-y) qjson.o json-streamer.o json-lexer.o json-parser.o qerror.o qemu-error.o qemu-tool.o $(qapi-dir)/test-qapi-visit.o $(qapi-dir)/test-qapi-types.o $(qapi-dir)/test-qmp-marshal.o module.o
+test-qmp-commands: test-qmp-commands.o qfloat.o qint.o qdict.o qstring.o qlist.o qbool.o $(qapi-obj-y) error.o osdep.o $(oslib-obj-y) qjson.o json-streamer.o json-lexer.o json-parser.o qerror.o qemu-error.o qemu-tool.o $(qapi-dir)/test-qapi-visit.o $(qapi-dir)/test-qapi-types.o $(qapi-dir)/test-qmp-marshal.o module.o
 
 QGALIB=qga/guest-agent-command-state.o qga/guest-agent-commands.o
 QGALIB_GEN=$(addprefix $(qapi-dir)/, qga-qapi-types.c qga-qapi-types.h qga-qapi-visit.c qga-qmp-marshal.c)
diff --git a/libcacard/Makefile b/libcacard/Makefile
index f72781e..9ad8f1e 100644
--- a/libcacard/Makefile
+++ b/libcacard/Makefile
@@ -8,7 +8,7 @@ libcacard_includedir=$(includedir)/cacard
 $(call set-vpath, $(SRC_PATH):$(libcacard_srcpath))
 
 # objects linked against normal qemu binaries, not compiled with libtool
-QEMU_OBJS=$(addprefix ../,$(oslib-obj-y) qemu-malloc.o qemu-timer-common.o $(trace-obj-y))
+QEMU_OBJS=$(addprefix ../,$(oslib-obj-y) qemu-timer-common.o $(trace-obj-y))
 
 # objects linked into a shared library, built with libtool with -fPIC if required
 QEMU_OBJS_LIB=$(addsuffix .lo,$(basename $(QEMU_OBJS)))
commit 145e21dbd06dbb4af319a019ee1281631215a94f
Author: Anthony Liguori <aliguori at us.ibm.com>
Date:   Sun Aug 21 08:16:56 2011 -0500

    Update HACKING to refer to g_malloc instead of qemu_malloc
    
    Signed-off-by: Anthony Liguori <aliguori at us.ibm.com>

diff --git a/HACKING b/HACKING
index 3af53fd..5b4ae10 100644
--- a/HACKING
+++ b/HACKING
@@ -77,11 +77,11 @@ avoided.
 
 Use of the malloc/free/realloc/calloc/valloc/memalign/posix_memalign
 APIs is not allowed in the QEMU codebase. Instead of these routines,
-use the replacement qemu_malloc/qemu_mallocz/qemu_realloc/qemu_free or
+use the replacement g_malloc/g_malloc0/g_realloc/g_free or
 qemu_vmalloc/qemu_memalign/qemu_vfree APIs.
 
 Please note that NULL check for the qemu_malloc result is redundant and
-that qemu_malloc() call with zero size is not allowed.
+that g_malloc() call with zero size is not allowed.
 
 Memory allocated by qemu_vmalloc or qemu_memalign must be freed with
 qemu_vfree, since breaking this will cause problems on Win32 and user
@@ -108,7 +108,7 @@ int qemu_strnlen(const char *s, int max_len)
 There are also replacement character processing macros for isxyz and toxyz,
 so instead of e.g. isalnum you should use qemu_isalnum.
 
-Because of the memory management rules, you must use qemu_strdup/qemu_strndup
+Because of the memory management rules, you must use g_strdup/g_strndup
 instead of plain strdup/strndup.
 
 5. Printf-style functions
commit 0750112af49b6f1a91a26d76e99badbca1e27b41
Author: Anthony Liguori <aliguori at us.ibm.com>
Date:   Sat Aug 20 22:38:31 2011 -0500

    Add trace points for g_malloc/g_free functions
    
    Derived from a patch submitted by Avi Kivity.
    
    Signed-off-by: Anthony Liguori <aliguori at us.ibm.com>

diff --git a/vl.c b/vl.c
index 8405429..06a6f80 100644
--- a/vl.c
+++ b/vl.c
@@ -2075,6 +2075,26 @@ static const QEMUOption *lookup_opt(int argc, char **argv,
     return popt;
 }
 
+static gpointer malloc_and_trace(gsize n_bytes)
+{
+    void *ptr = malloc(n_bytes);
+    trace_qemu_malloc(n_bytes, ptr);
+    return ptr;
+}
+
+static gpointer realloc_and_trace(gpointer mem, gsize n_bytes)
+{
+    void *ptr = realloc(mem, n_bytes);
+    trace_qemu_realloc(mem, n_bytes, ptr);
+    return ptr;
+}
+
+static void free_and_trace(gpointer mem)
+{
+    trace_qemu_free(mem);
+    free(mem);
+}
+
 int main(int argc, char **argv, char **envp)
 {
     const char *gdbstub_dev = NULL;
@@ -2103,10 +2123,17 @@ int main(int argc, char **argv, char **envp)
     const char *trace_file = NULL;
     const char *log_mask = NULL;
     const char *log_file = NULL;
+    GMemVTable mem_trace = {
+        .malloc = malloc_and_trace,
+        .realloc = realloc_and_trace,
+        .free = free_and_trace,
+    };
 
     atexit(qemu_run_exit_notifiers);
     error_set_progname(argv[0]);
 
+    g_mem_set_vtable(&mem_trace);
+
     init_clocks();
 
     qemu_cache_utils_init(envp);
commit 41a748265f4879b52b0e87ff9c93bed975163886
Author: Anthony Liguori <aliguori at us.ibm.com>
Date:   Sat Aug 20 22:23:03 2011 -0500

    Remove qemu_malloc/qemu_free
    
    Signed-off-by: Anthony Liguori <aliguori at us.ibm.com>

diff --git a/Makefile b/Makefile
index 9e5871b..516a254 100644
--- a/Makefile
+++ b/Makefile
@@ -88,7 +88,7 @@ include $(SRC_PATH)/Makefile.objs
 endif
 
 $(common-obj-y): $(GENERATED_HEADERS)
-subdir-libcacard: $(oslib-obj-y) $(trace-obj-y) qemu-malloc.o qemu-timer-common.o
+subdir-libcacard: $(oslib-obj-y) $(trace-obj-y) qemu-timer-common.o
 
 $(filter %-softmmu,$(SUBDIR_RULES)): $(trace-obj-y) $(common-obj-y) subdir-libdis
 
diff --git a/Makefile.objs b/Makefile.objs
index 77950d5..91b71b6 100644
--- a/Makefile.objs
+++ b/Makefile.objs
@@ -23,7 +23,7 @@ coroutine-obj-$(CONFIG_WIN32) += coroutine-win32.o
 #######################################################################
 # block-obj-y is code used by both qemu system emulation and qemu-img
 
-block-obj-y = cutils.o cache-utils.o qemu-malloc.o qemu-option.o module.o async.o
+block-obj-y = cutils.o cache-utils.o qemu-option.o module.o async.o
 block-obj-y += nbd.o block.o aio.o aes.o qemu-config.o qemu-progress.o qemu-sockets.o
 block-obj-y += $(coroutine-obj-y)
 block-obj-$(CONFIG_POSIX) += posix-aio-compat.o
diff --git a/Makefile.target b/Makefile.target
index 096214a..e280bf6 100644
--- a/Makefile.target
+++ b/Makefile.target
@@ -111,7 +111,7 @@ $(call set-vpath, $(SRC_PATH)/linux-user:$(SRC_PATH)/linux-user/$(TARGET_ABI_DIR
 QEMU_CFLAGS+=-I$(SRC_PATH)/linux-user/$(TARGET_ABI_DIR) -I$(SRC_PATH)/linux-user
 obj-y = main.o syscall.o strace.o mmap.o signal.o thunk.o \
       elfload.o linuxload.o uaccess.o gdbstub.o cpu-uname.o \
-      qemu-malloc.o user-exec.o $(oslib-obj-y)
+      user-exec.o $(oslib-obj-y)
 
 obj-$(TARGET_HAS_BFLT) += flatload.o
 
diff --git a/qemu-common.h b/qemu-common.h
index c1d4126..404c421 100644
--- a/qemu-common.h
+++ b/qemu-common.h
@@ -182,12 +182,6 @@ const char *path(const char *pathname);
 #define qemu_toascii(c)		toascii((unsigned char)(c))
 
 void *qemu_oom_check(void *ptr);
-void *qemu_malloc(size_t size);
-void *qemu_realloc(void *ptr, size_t size);
-void *qemu_mallocz(size_t size);
-void qemu_free(void *ptr);
-char *qemu_strdup(const char *str);
-char *qemu_strndup(const char *str, size_t size);
 
 void qemu_mutex_lock_iothread(void);
 void qemu_mutex_unlock_iothread(void);
diff --git a/qemu-malloc.c b/qemu-malloc.c
deleted file mode 100644
index b9b3851..0000000
--- a/qemu-malloc.c
+++ /dev/null
@@ -1,98 +0,0 @@
-/*
- * malloc-like functions for system emulation.
- *
- * 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 "trace.h"
-#include <stdlib.h>
-
-void qemu_free(void *ptr)
-{
-    trace_qemu_free(ptr);
-    free(ptr);
-}
-
-static int allow_zero_malloc(void)
-{
-#if defined(CONFIG_ZERO_MALLOC)
-    return 1;
-#else
-    return 0;
-#endif
-}
-
-void *qemu_malloc(size_t size)
-{
-    void *ptr;
-    if (!size && !allow_zero_malloc()) {
-        abort();
-    }
-    ptr = qemu_oom_check(malloc(size ? size : 1));
-    trace_qemu_malloc(size, ptr);
-    return ptr;
-}
-
-void *qemu_realloc(void *ptr, size_t size)
-{
-    void *newptr;
-    if (!size && !allow_zero_malloc()) {
-        abort();
-    }
-    newptr = qemu_oom_check(realloc(ptr, size ? size : 1));
-    trace_qemu_realloc(ptr, size, newptr);
-    return newptr;
-}
-
-void *qemu_mallocz(size_t size)
-{
-    void *ptr;
-    if (!size && !allow_zero_malloc()) {
-        abort();
-    }
-    ptr = qemu_oom_check(calloc(1, size ? size : 1));
-    trace_qemu_malloc(size, ptr);
-    return ptr;
-}
-
-char *qemu_strdup(const char *str)
-{
-    char *ptr;
-    size_t len = strlen(str);
-    ptr = qemu_malloc(len + 1);
-    memcpy(ptr, str, len + 1);
-    return ptr;
-}
-
-char *qemu_strndup(const char *str, size_t size)
-{
-    const char *end = memchr(str, 0, size);
-    char *new;
-
-    if (end) {
-        size = end - str;
-    }
-
-    new = qemu_malloc(size + 1);
-    new[size] = 0;
-
-    return memcpy(new, str, size);
-}
commit 7267c0947d7e8ae5dff7bafd932c3bc285f43e5c
Author: Anthony Liguori <aliguori at us.ibm.com>
Date:   Sat Aug 20 22:09:37 2011 -0500

    Use glib memory allocation and free functions
    
    qemu_malloc/qemu_free no longer exist after this commit.
    
    Signed-off-by: Anthony Liguori <aliguori at us.ibm.com>

diff --git a/acl.c b/acl.c
index 82c2704..0654f38 100644
--- a/acl.c
+++ b/acl.c
@@ -55,8 +55,8 @@ qemu_acl *qemu_acl_init(const char *aclname)
     if (acl)
         return acl;
 
-    acl = qemu_malloc(sizeof(*acl));
-    acl->aclname = qemu_strdup(aclname);
+    acl = g_malloc(sizeof(*acl));
+    acl->aclname = g_strdup(aclname);
     /* Deny by default, so there is no window of "open
      * access" between QEMU starting, and the user setting
      * up ACLs in the monitor */
@@ -65,7 +65,7 @@ qemu_acl *qemu_acl_init(const char *aclname)
     acl->nentries = 0;
     QTAILQ_INIT(&acl->entries);
 
-    acls = qemu_realloc(acls, sizeof(*acls) * (nacls +1));
+    acls = g_realloc(acls, sizeof(*acls) * (nacls +1));
     acls[nacls] = acl;
     nacls++;
 
@@ -116,8 +116,8 @@ int qemu_acl_append(qemu_acl *acl,
 {
     qemu_acl_entry *entry;
 
-    entry = qemu_malloc(sizeof(*entry));
-    entry->match = qemu_strdup(match);
+    entry = g_malloc(sizeof(*entry));
+    entry->match = g_strdup(match);
     entry->deny = deny;
 
     QTAILQ_INSERT_TAIL(&acl->entries, entry, next);
@@ -142,8 +142,8 @@ int qemu_acl_insert(qemu_acl *acl,
         return qemu_acl_append(acl, deny, match);
 
 
-    entry = qemu_malloc(sizeof(*entry));
-    entry->match = qemu_strdup(match);
+    entry = g_malloc(sizeof(*entry));
+    entry->match = g_strdup(match);
     entry->deny = deny;
 
     QTAILQ_FOREACH(tmp, &acl->entries, next) {
diff --git a/aio.c b/aio.c
index 2f08655..1239ca7 100644
--- a/aio.c
+++ b/aio.c
@@ -75,13 +75,13 @@ int qemu_aio_set_fd_handler(int fd,
                  * releasing the walking_handlers lock.
                  */
                 QLIST_REMOVE(node, node);
-                qemu_free(node);
+                g_free(node);
             }
         }
     } else {
         if (node == NULL) {
             /* Alloc and insert if it's not already there */
-            node = qemu_mallocz(sizeof(AioHandler));
+            node = g_malloc0(sizeof(AioHandler));
             node->fd = fd;
             QLIST_INSERT_HEAD(&aio_handlers, node, node);
         }
@@ -220,7 +220,7 @@ void qemu_aio_wait(void)
 
                 if (tmp->deleted) {
                     QLIST_REMOVE(tmp, node);
-                    qemu_free(tmp);
+                    g_free(tmp);
                 }
             }
 
diff --git a/arch_init.c b/arch_init.c
index 484b39d..567ab32 100644
--- a/arch_init.c
+++ b/arch_init.c
@@ -235,7 +235,7 @@ static void sort_ram_list(void)
     QLIST_FOREACH(block, &ram_list.blocks, next) {
         ++n;
     }
-    blocks = qemu_malloc(n * sizeof *blocks);
+    blocks = g_malloc(n * sizeof *blocks);
     n = 0;
     QLIST_FOREACH_SAFE(block, &ram_list.blocks, next, nblock) {
         blocks[n++] = block;
@@ -245,7 +245,7 @@ static void sort_ram_list(void)
     while (--n >= 0) {
         QLIST_INSERT_HEAD(&ram_list.blocks, blocks[n], next);
     }
-    qemu_free(blocks);
+    g_free(blocks);
 }
 
 int ram_save_live(Monitor *mon, QEMUFile *f, int stage, void *opaque)
diff --git a/async.c b/async.c
index 3fe70b9..9d4e960 100644
--- a/async.c
+++ b/async.c
@@ -43,7 +43,7 @@ struct QEMUBH {
 QEMUBH *qemu_bh_new(QEMUBHFunc *cb, void *opaque)
 {
     QEMUBH *bh;
-    bh = qemu_mallocz(sizeof(QEMUBH));
+    bh = g_malloc0(sizeof(QEMUBH));
     bh->cb = cb;
     bh->opaque = opaque;
     bh->next = first_bh;
@@ -74,7 +74,7 @@ int qemu_bh_poll(void)
         bh = *bhp;
         if (bh->deleted) {
             *bhp = bh->next;
-            qemu_free(bh);
+            g_free(bh);
         } else
             bhp = &bh->next;
     }
diff --git a/audio/alsaaudio.c b/audio/alsaaudio.c
index 4d72014..cb45b49 100644
--- a/audio/alsaaudio.c
+++ b/audio/alsaaudio.c
@@ -136,7 +136,7 @@ static void alsa_fini_poll (struct pollhlp *hlp)
         for (i = 0; i < hlp->count; ++i) {
             qemu_set_fd_handler (pfds[i].fd, NULL, NULL, NULL);
         }
-        qemu_free (pfds);
+        g_free (pfds);
     }
     hlp->pfds = NULL;
     hlp->count = 0;
@@ -260,7 +260,7 @@ static int alsa_poll_helper (snd_pcm_t *handle, struct pollhlp *hlp, int mask)
     if (err < 0) {
         alsa_logerr (err, "Could not initialize poll mode\n"
                      "Could not obtain poll descriptors\n");
-        qemu_free (pfds);
+        g_free (pfds);
         return -1;
     }
 
@@ -288,7 +288,7 @@ static int alsa_poll_helper (snd_pcm_t *handle, struct pollhlp *hlp, int mask)
             while (i--) {
                 qemu_set_fd_handler (pfds[i].fd, NULL, NULL, NULL);
             }
-            qemu_free (pfds);
+            g_free (pfds);
             return -1;
         }
     }
@@ -816,7 +816,7 @@ static void alsa_fini_out (HWVoiceOut *hw)
     alsa_anal_close (&alsa->handle, &alsa->pollhlp);
 
     if (alsa->pcm_buf) {
-        qemu_free (alsa->pcm_buf);
+        g_free (alsa->pcm_buf);
         alsa->pcm_buf = NULL;
     }
 }
@@ -979,7 +979,7 @@ static void alsa_fini_in (HWVoiceIn *hw)
     alsa_anal_close (&alsa->handle, &alsa->pollhlp);
 
     if (alsa->pcm_buf) {
-        qemu_free (alsa->pcm_buf);
+        g_free (alsa->pcm_buf);
         alsa->pcm_buf = NULL;
     }
 }
diff --git a/audio/audio.c b/audio/audio.c
index 50d2b64..5649075 100644
--- a/audio/audio.c
+++ b/audio/audio.c
@@ -196,7 +196,7 @@ void *audio_calloc (const char *funcname, int nmemb, size_t size)
         return NULL;
     }
 
-    return qemu_mallocz (len);
+    return g_malloc0 (len);
 }
 
 static char *audio_alloc_prefix (const char *s)
@@ -210,7 +210,7 @@ static char *audio_alloc_prefix (const char *s)
     }
 
     len = strlen (s);
-    r = qemu_malloc (len + sizeof (qemu_prefix));
+    r = g_malloc (len + sizeof (qemu_prefix));
 
     u = r + sizeof (qemu_prefix) - 1;
 
@@ -425,7 +425,7 @@ static void audio_print_options (const char *prefix,
         printf ("    %s\n", opt->descr);
     }
 
-    qemu_free (uprefix);
+    g_free (uprefix);
 }
 
 static void audio_process_options (const char *prefix,
@@ -462,7 +462,7 @@ static void audio_process_options (const char *prefix,
          * (includes trailing zero) + zero + underscore (on behalf of
          * sizeof) */
         optlen = len + preflen + sizeof (qemu_prefix) + 1;
-        optname = qemu_malloc (optlen);
+        optname = g_malloc (optlen);
 
         pstrcpy (optname, optlen, qemu_prefix);
 
@@ -507,7 +507,7 @@ static void audio_process_options (const char *prefix,
             opt->overriddenp = &opt->overridden;
         }
         *opt->overriddenp = !def;
-        qemu_free (optname);
+        g_free (optname);
     }
 }
 
@@ -778,7 +778,7 @@ static void audio_detach_capture (HWVoiceOut *hw)
 
         QLIST_REMOVE (sw, entries);
         QLIST_REMOVE (sc, entries);
-        qemu_free (sc);
+        g_free (sc);
         if (was_active) {
             /* We have removed soft voice from the capture:
                this might have changed the overall status of the capture
@@ -818,7 +818,7 @@ static int audio_attach_capture (HWVoiceOut *hw)
         sw->rate = st_rate_start (sw->info.freq, hw_cap->info.freq);
         if (!sw->rate) {
             dolog ("Could not start rate conversion for `%s'\n", SW_NAME (sw));
-            qemu_free (sw);
+            g_free (sw);
             return -1;
         }
         QLIST_INSERT_HEAD (&hw_cap->sw_head, sw, entries);
@@ -1907,7 +1907,7 @@ static void audio_init (void)
 void AUD_register_card (const char *name, QEMUSoundCard *card)
 {
     audio_init ();
-    card->name = qemu_strdup (name);
+    card->name = g_strdup (name);
     memset (&card->entries, 0, sizeof (card->entries));
     QLIST_INSERT_HEAD (&glob_audio_state.card_head, card, entries);
 }
@@ -1915,7 +1915,7 @@ void AUD_register_card (const char *name, QEMUSoundCard *card)
 void AUD_remove_card (QEMUSoundCard *card)
 {
     QLIST_REMOVE (card, entries);
-    qemu_free (card->name);
+    g_free (card->name);
 }
 
 
@@ -2000,11 +2000,11 @@ CaptureVoiceOut *AUD_add_capture (
         return cap;
 
     err3:
-        qemu_free (cap->hw.mix_buf);
+        g_free (cap->hw.mix_buf);
     err2:
-        qemu_free (cap);
+        g_free (cap);
     err1:
-        qemu_free (cb);
+        g_free (cb);
     err0:
         return NULL;
     }
@@ -2018,7 +2018,7 @@ void AUD_del_capture (CaptureVoiceOut *cap, void *cb_opaque)
         if (cb->opaque == cb_opaque) {
             cb->ops.destroy (cb_opaque);
             QLIST_REMOVE (cb, entries);
-            qemu_free (cb);
+            g_free (cb);
 
             if (!cap->cb_head.lh_first) {
                 SWVoiceOut *sw = cap->hw.sw_head.lh_first, *sw1;
@@ -2036,11 +2036,11 @@ void AUD_del_capture (CaptureVoiceOut *cap, void *cb_opaque)
                     }
                     QLIST_REMOVE (sw, entries);
                     QLIST_REMOVE (sc, entries);
-                    qemu_free (sc);
+                    g_free (sc);
                     sw = sw1;
                 }
                 QLIST_REMOVE (cap, entries);
-                qemu_free (cap);
+                g_free (cap);
             }
             return;
         }
diff --git a/audio/audio_template.h b/audio/audio_template.h
index fd4469e..e62a713 100644
--- a/audio/audio_template.h
+++ b/audio/audio_template.h
@@ -72,7 +72,7 @@ static void glue (audio_init_nb_voices_, TYPE) (struct audio_driver *drv)
 static void glue (audio_pcm_hw_free_resources_, TYPE) (HW *hw)
 {
     if (HWBUF) {
-        qemu_free (HWBUF);
+        g_free (HWBUF);
     }
 
     HWBUF = NULL;
@@ -93,7 +93,7 @@ static int glue (audio_pcm_hw_alloc_resources_, TYPE) (HW *hw)
 static void glue (audio_pcm_sw_free_resources_, TYPE) (SW *sw)
 {
     if (sw->buf) {
-        qemu_free (sw->buf);
+        g_free (sw->buf);
     }
 
     if (sw->rate) {
@@ -123,7 +123,7 @@ static int glue (audio_pcm_sw_alloc_resources_, TYPE) (SW *sw)
     sw->rate = st_rate_start (sw->hw->info.freq, sw->info.freq);
 #endif
     if (!sw->rate) {
-        qemu_free (sw->buf);
+        g_free (sw->buf);
         sw->buf = NULL;
         return -1;
     }
@@ -160,10 +160,10 @@ static int glue (audio_pcm_sw_init_, TYPE) (
         [sw->info.swap_endianness]
         [audio_bits_to_index (sw->info.bits)];
 
-    sw->name = qemu_strdup (name);
+    sw->name = g_strdup (name);
     err = glue (audio_pcm_sw_alloc_resources_, TYPE) (sw);
     if (err) {
-        qemu_free (sw->name);
+        g_free (sw->name);
         sw->name = NULL;
     }
     return err;
@@ -173,7 +173,7 @@ static void glue (audio_pcm_sw_fini_, TYPE) (SW *sw)
 {
     glue (audio_pcm_sw_free_resources_, TYPE) (sw);
     if (sw->name) {
-        qemu_free (sw->name);
+        g_free (sw->name);
         sw->name = NULL;
     }
 }
@@ -201,7 +201,7 @@ static void glue (audio_pcm_hw_gc_, TYPE) (HW **hwp)
         glue (s->nb_hw_voices_, TYPE) += 1;
         glue (audio_pcm_hw_free_resources_ ,TYPE) (hw);
         glue (hw->pcm_ops->fini_, TYPE) (hw);
-        qemu_free (hw);
+        g_free (hw);
         *hwp = NULL;
     }
 }
@@ -300,7 +300,7 @@ static HW *glue (audio_pcm_hw_add_new_, TYPE) (struct audsettings *as)
  err1:
     glue (hw->pcm_ops->fini_, TYPE) (hw);
  err0:
-    qemu_free (hw);
+    g_free (hw);
     return NULL;
 }
 
@@ -368,7 +368,7 @@ err3:
     glue (audio_pcm_hw_del_sw_, TYPE) (sw);
     glue (audio_pcm_hw_gc_, TYPE) (&hw);
 err2:
-    qemu_free (sw);
+    g_free (sw);
 err1:
     return NULL;
 }
@@ -378,7 +378,7 @@ static void glue (audio_close_, TYPE) (SW *sw)
     glue (audio_pcm_sw_fini_, TYPE) (sw);
     glue (audio_pcm_hw_del_sw_, TYPE) (sw);
     glue (audio_pcm_hw_gc_, TYPE) (&sw->hw);
-    qemu_free (sw);
+    g_free (sw);
 }
 
 void glue (AUD_close_, TYPE) (QEMUSoundCard *card, SW *sw)
diff --git a/audio/esdaudio.c b/audio/esdaudio.c
index ff97b39..bd6e1cc 100644
--- a/audio/esdaudio.c
+++ b/audio/esdaudio.c
@@ -246,7 +246,7 @@ static int qesd_init_out (HWVoiceOut *hw, struct audsettings *as)
     esd->fd = -1;
 
  fail1:
-    qemu_free (esd->pcm_buf);
+    g_free (esd->pcm_buf);
     esd->pcm_buf = NULL;
     return -1;
 }
@@ -270,7 +270,7 @@ static void qesd_fini_out (HWVoiceOut *hw)
 
     audio_pt_fini (&esd->pt, AUDIO_FUNC);
 
-    qemu_free (esd->pcm_buf);
+    g_free (esd->pcm_buf);
     esd->pcm_buf = NULL;
 }
 
@@ -453,7 +453,7 @@ static int qesd_init_in (HWVoiceIn *hw, struct audsettings *as)
     esd->fd = -1;
 
  fail1:
-    qemu_free (esd->pcm_buf);
+    g_free (esd->pcm_buf);
     esd->pcm_buf = NULL;
     return -1;
 }
@@ -477,7 +477,7 @@ static void qesd_fini_in (HWVoiceIn *hw)
 
     audio_pt_fini (&esd->pt, AUDIO_FUNC);
 
-    qemu_free (esd->pcm_buf);
+    g_free (esd->pcm_buf);
     esd->pcm_buf = NULL;
 }
 
diff --git a/audio/mixeng.c b/audio/mixeng.c
index 4a9e8eb..5446be6 100644
--- a/audio/mixeng.c
+++ b/audio/mixeng.c
@@ -326,7 +326,7 @@ void *st_rate_start (int inrate, int outrate)
 
 void st_rate_stop (void *opaque)
 {
-    qemu_free (opaque);
+    g_free (opaque);
 }
 
 void mixeng_clear (struct st_sample *buf, int len)
diff --git a/audio/ossaudio.c b/audio/ossaudio.c
index b49e102..df51b7c 100644
--- a/audio/ossaudio.c
+++ b/audio/ossaudio.c
@@ -508,7 +508,7 @@ static void oss_fini_out (HWVoiceOut *hw)
             }
         }
         else {
-            qemu_free (oss->pcm_buf);
+            g_free (oss->pcm_buf);
         }
         oss->pcm_buf = NULL;
     }
@@ -741,7 +741,7 @@ static void oss_fini_in (HWVoiceIn *hw)
     oss_anal_close (&oss->fd);
 
     if (oss->pcm_buf) {
-        qemu_free (oss->pcm_buf);
+        g_free (oss->pcm_buf);
         oss->pcm_buf = NULL;
     }
 }
diff --git a/audio/paaudio.c b/audio/paaudio.c
index fb4510e..d1f3912 100644
--- a/audio/paaudio.c
+++ b/audio/paaudio.c
@@ -339,7 +339,7 @@ static int qpa_init_out (HWVoiceOut *hw, struct audsettings *as)
     return 0;
 
  fail3:
-    qemu_free (pa->pcm_buf);
+    g_free (pa->pcm_buf);
     pa->pcm_buf = NULL;
  fail2:
     pa_simple_free (pa->s);
@@ -394,7 +394,7 @@ static int qpa_init_in (HWVoiceIn *hw, struct audsettings *as)
     return 0;
 
  fail3:
-    qemu_free (pa->pcm_buf);
+    g_free (pa->pcm_buf);
     pa->pcm_buf = NULL;
  fail2:
     pa_simple_free (pa->s);
@@ -419,7 +419,7 @@ static void qpa_fini_out (HWVoiceOut *hw)
     }
 
     audio_pt_fini (&pa->pt, AUDIO_FUNC);
-    qemu_free (pa->pcm_buf);
+    g_free (pa->pcm_buf);
     pa->pcm_buf = NULL;
 }
 
@@ -439,7 +439,7 @@ static void qpa_fini_in (HWVoiceIn *hw)
     }
 
     audio_pt_fini (&pa->pt, AUDIO_FUNC);
-    qemu_free (pa->pcm_buf);
+    g_free (pa->pcm_buf);
     pa->pcm_buf = NULL;
 }
 
diff --git a/audio/wavaudio.c b/audio/wavaudio.c
index 294f357..aed1817 100644
--- a/audio/wavaudio.c
+++ b/audio/wavaudio.c
@@ -156,7 +156,7 @@ static int wav_init_out (HWVoiceOut *hw, struct audsettings *as)
     if (!wav->f) {
         dolog ("Failed to open wave file `%s'\nReason: %s\n",
                conf.wav_path, strerror (errno));
-        qemu_free (wav->pcm_buf);
+        g_free (wav->pcm_buf);
         wav->pcm_buf = NULL;
         return -1;
     }
@@ -189,7 +189,7 @@ static void wav_fini_out (HWVoiceOut *hw)
     qemu_fclose (wav->f);
     wav->f = NULL;
 
-    qemu_free (wav->pcm_buf);
+    g_free (wav->pcm_buf);
     wav->pcm_buf = NULL;
 }
 
diff --git a/audio/wavcapture.c b/audio/wavcapture.c
index 1f49cd1..c64f0ef 100644
--- a/audio/wavcapture.c
+++ b/audio/wavcapture.c
@@ -48,7 +48,7 @@ static void wav_destroy (void *opaque)
         qemu_fclose (wav->f);
     }
 
-    qemu_free (wav->path);
+    g_free (wav->path);
 }
 
 static void wav_capture (void *opaque, void *buf, int size)
@@ -120,7 +120,7 @@ int wav_start_capture (CaptureState *s, const char *path, int freq,
     ops.capture = wav_capture;
     ops.destroy = wav_destroy;
 
-    wav = qemu_mallocz (sizeof (*wav));
+    wav = g_malloc0 (sizeof (*wav));
 
     shift = bits16 + stereo;
     hdr[34] = bits16 ? 0x10 : 0x08;
@@ -134,11 +134,11 @@ int wav_start_capture (CaptureState *s, const char *path, int freq,
     if (!wav->f) {
         monitor_printf(mon, "Failed to open wave file `%s'\nReason: %s\n",
                        path, strerror (errno));
-        qemu_free (wav);
+        g_free (wav);
         return -1;
     }
 
-    wav->path = qemu_strdup (path);
+    wav->path = g_strdup (path);
     wav->bits = bits;
     wav->nchannels = nchannels;
     wav->freq = freq;
@@ -148,9 +148,9 @@ int wav_start_capture (CaptureState *s, const char *path, int freq,
     cap = AUD_add_capture (&as, &ops, wav);
     if (!cap) {
         monitor_printf(mon, "Failed to add audio capture\n");
-        qemu_free (wav->path);
+        g_free (wav->path);
         qemu_fclose (wav->f);
-        qemu_free (wav);
+        g_free (wav);
         return -1;
     }
 
diff --git a/audio/winwaveaudio.c b/audio/winwaveaudio.c
index e5ad3c6..87e7493 100644
--- a/audio/winwaveaudio.c
+++ b/audio/winwaveaudio.c
@@ -222,9 +222,9 @@ static int winwave_init_out (HWVoiceOut *hw, struct audsettings *as)
     return 0;
 
  err4:
-    qemu_free (wave->pcm_buf);
+    g_free (wave->pcm_buf);
  err3:
-    qemu_free (wave->hdrs);
+    g_free (wave->hdrs);
  err2:
     winwave_anal_close_out (wave);
  err1:
@@ -310,10 +310,10 @@ static void winwave_fini_out (HWVoiceOut *hw)
         wave->event = NULL;
     }
 
-    qemu_free (wave->pcm_buf);
+    g_free (wave->pcm_buf);
     wave->pcm_buf = NULL;
 
-    qemu_free (wave->hdrs);
+    g_free (wave->hdrs);
     wave->hdrs = NULL;
 }
 
@@ -511,9 +511,9 @@ static int winwave_init_in (HWVoiceIn *hw, struct audsettings *as)
     return 0;
 
  err4:
-    qemu_free (wave->pcm_buf);
+    g_free (wave->pcm_buf);
  err3:
-    qemu_free (wave->hdrs);
+    g_free (wave->hdrs);
  err2:
     winwave_anal_close_in (wave);
  err1:
@@ -550,10 +550,10 @@ static void winwave_fini_in (HWVoiceIn *hw)
         wave->event = NULL;
     }
 
-    qemu_free (wave->pcm_buf);
+    g_free (wave->pcm_buf);
     wave->pcm_buf = NULL;
 
-    qemu_free (wave->hdrs);
+    g_free (wave->hdrs);
     wave->hdrs = NULL;
 }
 
diff --git a/bitmap.h b/bitmap.h
index efd5d3a..08755eb 100644
--- a/bitmap.h
+++ b/bitmap.h
@@ -91,7 +91,7 @@ int slow_bitmap_intersects(const unsigned long *bitmap1,
 static inline unsigned long *bitmap_new(int nbits)
 {
     int len = BITS_TO_LONGS(nbits) * sizeof(unsigned long);
-    return qemu_mallocz(len);
+    return g_malloc0(len);
 }
 
 static inline void bitmap_zero(unsigned long *dst, int nbits)
diff --git a/block-migration.c b/block-migration.c
index 0936c7d..e2775ee 100644
--- a/block-migration.c
+++ b/block-migration.c
@@ -180,7 +180,7 @@ static void alloc_aio_bitmap(BlkMigDevState *bmds)
             BDRV_SECTORS_PER_DIRTY_CHUNK * 8 - 1;
     bitmap_size /= BDRV_SECTORS_PER_DIRTY_CHUNK * 8;
 
-    bmds->aio_bitmap = qemu_mallocz(bitmap_size);
+    bmds->aio_bitmap = g_malloc0(bitmap_size);
 }
 
 static void blk_mig_read_cb(void *opaque, int ret)
@@ -235,8 +235,8 @@ static int mig_save_device_bulk(Monitor *mon, QEMUFile *f,
         nr_sectors = total_sectors - cur_sector;
     }
 
-    blk = qemu_malloc(sizeof(BlkMigBlock));
-    blk->buf = qemu_malloc(BLOCK_SIZE);
+    blk = g_malloc(sizeof(BlkMigBlock));
+    blk->buf = g_malloc(BLOCK_SIZE);
     blk->bmds = bmds;
     blk->sector = cur_sector;
     blk->nr_sectors = nr_sectors;
@@ -264,8 +264,8 @@ static int mig_save_device_bulk(Monitor *mon, QEMUFile *f,
 error:
     monitor_printf(mon, "Error reading sector %" PRId64 "\n", cur_sector);
     qemu_file_set_error(f);
-    qemu_free(blk->buf);
-    qemu_free(blk);
+    g_free(blk->buf);
+    g_free(blk);
     return 0;
 }
 
@@ -290,7 +290,7 @@ static void init_blk_migration_it(void *opaque, BlockDriverState *bs)
             return;
         }
 
-        bmds = qemu_mallocz(sizeof(BlkMigDevState));
+        bmds = g_malloc0(sizeof(BlkMigDevState));
         bmds->bs = bs;
         bmds->bulk_completed = 0;
         bmds->total_sectors = sectors;
@@ -395,8 +395,8 @@ static int mig_save_device_dirty(Monitor *mon, QEMUFile *f,
             } else {
                 nr_sectors = BDRV_SECTORS_PER_DIRTY_CHUNK;
             }
-            blk = qemu_malloc(sizeof(BlkMigBlock));
-            blk->buf = qemu_malloc(BLOCK_SIZE);
+            blk = g_malloc(sizeof(BlkMigBlock));
+            blk->buf = g_malloc(BLOCK_SIZE);
             blk->bmds = bmds;
             blk->sector = sector;
             blk->nr_sectors = nr_sectors;
@@ -424,8 +424,8 @@ static int mig_save_device_dirty(Monitor *mon, QEMUFile *f,
                 }
                 blk_send(f, blk);
 
-                qemu_free(blk->buf);
-                qemu_free(blk);
+                g_free(blk->buf);
+                g_free(blk);
             }
 
             bdrv_reset_dirty(bmds->bs, sector, nr_sectors);
@@ -440,8 +440,8 @@ static int mig_save_device_dirty(Monitor *mon, QEMUFile *f,
 error:
     monitor_printf(mon, "Error reading sector %" PRId64 "\n", sector);
     qemu_file_set_error(f);
-    qemu_free(blk->buf);
-    qemu_free(blk);
+    g_free(blk->buf);
+    g_free(blk);
     return 0;
 }
 
@@ -479,8 +479,8 @@ static void flush_blks(QEMUFile* f)
         blk_send(f, blk);
 
         QSIMPLEQ_REMOVE_HEAD(&block_mig_state.blk_list, entry);
-        qemu_free(blk->buf);
-        qemu_free(blk);
+        g_free(blk->buf);
+        g_free(blk);
 
         block_mig_state.read_done--;
         block_mig_state.transferred++;
@@ -541,14 +541,14 @@ static void blk_mig_cleanup(Monitor *mon)
         QSIMPLEQ_REMOVE_HEAD(&block_mig_state.bmds_list, entry);
         bdrv_set_in_use(bmds->bs, 0);
         drive_put_ref(drive_get_by_blockdev(bmds->bs));
-        qemu_free(bmds->aio_bitmap);
-        qemu_free(bmds);
+        g_free(bmds->aio_bitmap);
+        g_free(bmds);
     }
 
     while ((blk = QSIMPLEQ_FIRST(&block_mig_state.blk_list)) != NULL) {
         QSIMPLEQ_REMOVE_HEAD(&block_mig_state.blk_list, entry);
-        qemu_free(blk->buf);
-        qemu_free(blk);
+        g_free(blk->buf);
+        g_free(blk);
     }
 
     monitor_printf(mon, "\n");
@@ -683,12 +683,12 @@ static int block_load(QEMUFile *f, void *opaque, int version_id)
                 nr_sectors = BDRV_SECTORS_PER_DIRTY_CHUNK;
             }
 
-            buf = qemu_malloc(BLOCK_SIZE);
+            buf = g_malloc(BLOCK_SIZE);
 
             qemu_get_buffer(f, buf, BLOCK_SIZE);
             ret = bdrv_write(bs, addr, buf, nr_sectors);
 
-            qemu_free(buf);
+            g_free(buf);
             if (ret < 0) {
                 return ret;
             }
diff --git a/block.c b/block.c
index 26910ca..785c88e 100644
--- a/block.c
+++ b/block.c
@@ -215,7 +215,7 @@ BlockDriverState *bdrv_new(const char *device_name)
 {
     BlockDriverState *bs;
 
-    bs = qemu_mallocz(sizeof(BlockDriverState));
+    bs = g_malloc0(sizeof(BlockDriverState));
     pstrcpy(bs->device_name, sizeof(bs->device_name), device_name);
     if (device_name[0] != '\0') {
         QTAILQ_INSERT_TAIL(&bdrv_states, bs, list);
@@ -462,7 +462,7 @@ static int bdrv_open_common(BlockDriverState *bs, const char *filename,
     }
 
     bs->drv = drv;
-    bs->opaque = qemu_mallocz(drv->instance_size);
+    bs->opaque = g_malloc0(drv->instance_size);
 
     if (flags & BDRV_O_CACHE_WB)
         bs->enable_write_cache = 1;
@@ -513,7 +513,7 @@ free_and_fail:
         bdrv_delete(bs->file);
         bs->file = NULL;
     }
-    qemu_free(bs->opaque);
+    g_free(bs->opaque);
     bs->opaque = NULL;
     bs->drv = NULL;
     return ret;
@@ -687,7 +687,7 @@ void bdrv_close(BlockDriverState *bs)
             bs->backing_hd = NULL;
         }
         bs->drv->bdrv_close(bs);
-        qemu_free(bs->opaque);
+        g_free(bs->opaque);
 #ifdef _WIN32
         if (bs->is_temporary) {
             unlink(bs->filename);
@@ -739,7 +739,7 @@ void bdrv_delete(BlockDriverState *bs)
     }
 
     assert(bs != bs_snapshots);
-    qemu_free(bs);
+    g_free(bs);
 }
 
 int bdrv_attach(BlockDriverState *bs, DeviceState *qdev)
@@ -837,7 +837,7 @@ int bdrv_commit(BlockDriverState *bs)
     }
 
     total_sectors = bdrv_getlength(bs) >> BDRV_SECTOR_BITS;
-    buf = qemu_malloc(COMMIT_BUF_SECTORS * BDRV_SECTOR_SIZE);
+    buf = g_malloc(COMMIT_BUF_SECTORS * BDRV_SECTOR_SIZE);
 
     for (sector = 0; sector < total_sectors; sector += n) {
         if (drv->bdrv_is_allocated(bs, sector, COMMIT_BUF_SECTORS, &n)) {
@@ -867,7 +867,7 @@ int bdrv_commit(BlockDriverState *bs)
         bdrv_flush(bs->backing_hd);
 
 ro_cleanup:
-    qemu_free(buf);
+    g_free(buf);
 
     if (ro) {
         /* re-open as RO */
@@ -2275,7 +2275,7 @@ static void block_complete_cb(void *opaque, int ret)
         set_dirty_bitmap(b->bs, b->sector_num, b->nb_sectors, 1);
     }
     b->cb(b->opaque, ret);
-    qemu_free(b);
+    g_free(b);
 }
 
 static BlockCompleteData *blk_dirty_cb_alloc(BlockDriverState *bs,
@@ -2284,7 +2284,7 @@ static BlockCompleteData *blk_dirty_cb_alloc(BlockDriverState *bs,
                                              BlockDriverCompletionFunc *cb,
                                              void *opaque)
 {
-    BlockCompleteData *blkdata = qemu_mallocz(sizeof(BlockCompleteData));
+    BlockCompleteData *blkdata = g_malloc0(sizeof(BlockCompleteData));
 
     blkdata->bs = bs;
     blkdata->cb = cb;
@@ -2356,7 +2356,7 @@ static void multiwrite_user_cb(MultiwriteCB *mcb)
         if (mcb->callbacks[i].free_qiov) {
             qemu_iovec_destroy(mcb->callbacks[i].free_qiov);
         }
-        qemu_free(mcb->callbacks[i].free_qiov);
+        g_free(mcb->callbacks[i].free_qiov);
         qemu_vfree(mcb->callbacks[i].free_buf);
     }
 }
@@ -2374,7 +2374,7 @@ static void multiwrite_cb(void *opaque, int ret)
     mcb->num_requests--;
     if (mcb->num_requests == 0) {
         multiwrite_user_cb(mcb);
-        qemu_free(mcb);
+        g_free(mcb);
     }
 }
 
@@ -2434,7 +2434,7 @@ static int multiwrite_merge(BlockDriverState *bs, BlockRequest *reqs,
 
         if (merge) {
             size_t size;
-            QEMUIOVector *qiov = qemu_mallocz(sizeof(*qiov));
+            QEMUIOVector *qiov = g_malloc0(sizeof(*qiov));
             qemu_iovec_init(qiov,
                 reqs[outidx].qiov->niov + reqs[i].qiov->niov + 1);
 
@@ -2503,7 +2503,7 @@ int bdrv_aio_multiwrite(BlockDriverState *bs, BlockRequest *reqs, int num_reqs)
     }
 
     // Create MultiwriteCB structure
-    mcb = qemu_mallocz(sizeof(*mcb) + num_reqs * sizeof(*mcb->callbacks));
+    mcb = g_malloc0(sizeof(*mcb) + num_reqs * sizeof(*mcb->callbacks));
     mcb->num_requests = 0;
     mcb->num_callbacks = num_reqs;
 
@@ -2568,7 +2568,7 @@ fail:
     for (i = 0; i < mcb->num_callbacks; i++) {
         reqs[i].error = -EIO;
     }
-    qemu_free(mcb);
+    g_free(mcb);
     return -1;
 }
 
@@ -2884,7 +2884,7 @@ void *qemu_aio_get(AIOPool *pool, BlockDriverState *bs,
         acb = pool->free_aiocb;
         pool->free_aiocb = acb->next;
     } else {
-        acb = qemu_mallocz(pool->aiocb_size);
+        acb = g_malloc0(pool->aiocb_size);
         acb->pool = pool;
     }
     acb->bs = bs;
@@ -3088,11 +3088,11 @@ void bdrv_set_dirty_tracking(BlockDriverState *bs, int enable)
                     BDRV_SECTORS_PER_DIRTY_CHUNK * 8 - 1;
             bitmap_size /= BDRV_SECTORS_PER_DIRTY_CHUNK * 8;
 
-            bs->dirty_bitmap = qemu_mallocz(bitmap_size);
+            bs->dirty_bitmap = g_malloc0(bitmap_size);
         }
     } else {
         if (bs->dirty_bitmap) {
-            qemu_free(bs->dirty_bitmap);
+            g_free(bs->dirty_bitmap);
             bs->dirty_bitmap = NULL;
         }
     }
diff --git a/block/blkdebug.c b/block/blkdebug.c
index cd9eb80..b3c5d42 100644
--- a/block/blkdebug.c
+++ b/block/blkdebug.c
@@ -214,7 +214,7 @@ static int add_rule(QemuOpts *opts, void *opaque)
     }
 
     /* Set attributes common for all actions */
-    rule = qemu_mallocz(sizeof(*rule));
+    rule = g_malloc0(sizeof(*rule));
     *rule = (struct BlkdebugRule) {
         .event  = event,
         .action = d->action,
@@ -392,7 +392,7 @@ static void blkdebug_close(BlockDriverState *bs)
     for (i = 0; i < BLKDBG_EVENT_MAX; i++) {
         QLIST_FOREACH_SAFE(rule, &s->rules[i], next, next) {
             QLIST_REMOVE(rule, next);
-            qemu_free(rule);
+            g_free(rule);
         }
     }
 }
diff --git a/block/bochs.c b/block/bochs.c
index 5fe2fa3..3c2f8d1 100644
--- a/block/bochs.c
+++ b/block/bochs.c
@@ -136,7 +136,7 @@ static int bochs_open(BlockDriverState *bs, int flags)
     }
 
     s->catalog_size = le32_to_cpu(bochs.extra.redolog.catalog);
-    s->catalog_bitmap = qemu_malloc(s->catalog_size * 4);
+    s->catalog_bitmap = g_malloc(s->catalog_size * 4);
     if (bdrv_pread(bs->file, le32_to_cpu(bochs.header), s->catalog_bitmap,
                    s->catalog_size * 4) != s->catalog_size * 4)
 	goto fail;
@@ -210,7 +210,7 @@ static int bochs_read(BlockDriverState *bs, int64_t sector_num,
 static void bochs_close(BlockDriverState *bs)
 {
     BDRVBochsState *s = bs->opaque;
-    qemu_free(s->catalog_bitmap);
+    g_free(s->catalog_bitmap);
 }
 
 static BlockDriver bdrv_bochs = {
diff --git a/block/cloop.c b/block/cloop.c
index fe015c4..8cff9f2 100644
--- a/block/cloop.c
+++ b/block/cloop.c
@@ -70,7 +70,7 @@ static int cloop_open(BlockDriverState *bs, int flags)
 
     /* read offsets */
     offsets_size = s->n_blocks * sizeof(uint64_t);
-    s->offsets = qemu_malloc(offsets_size);
+    s->offsets = g_malloc(offsets_size);
     if (bdrv_pread(bs->file, 128 + 4 + 4, s->offsets, offsets_size) <
             offsets_size) {
 	goto cloop_close;
@@ -85,8 +85,8 @@ static int cloop_open(BlockDriverState *bs, int flags)
     }
 
     /* initialize zlib engine */
-    s->compressed_block = qemu_malloc(max_compressed_block_size+1);
-    s->uncompressed_block = qemu_malloc(s->block_size);
+    s->compressed_block = g_malloc(max_compressed_block_size+1);
+    s->uncompressed_block = g_malloc(s->block_size);
     if(inflateInit(&s->zstream) != Z_OK)
 	goto cloop_close;
     s->current_block=s->n_blocks;
diff --git a/block/curl.c b/block/curl.c
index 407f095..5c157bc 100644
--- a/block/curl.c
+++ b/block/curl.c
@@ -310,7 +310,7 @@ static int curl_open(BlockDriverState *bs, const char *filename, int flags)
 
     static int inited = 0;
 
-    file = qemu_strdup(filename);
+    file = g_strdup(filename);
     s->readahead_size = READ_AHEAD_SIZE;
 
     /* Parse a trailing ":readahead=#:" param, if present. */
@@ -390,7 +390,7 @@ out:
     curl_easy_cleanup(state->curl);
     state->curl = NULL;
 out_noclean:
-    qemu_free(file);
+    g_free(file);
     return -EINVAL;
 }
 
@@ -444,11 +444,11 @@ static BlockDriverAIOCB *curl_aio_readv(BlockDriverState *bs,
 
     state->buf_off = 0;
     if (state->orig_buf)
-        qemu_free(state->orig_buf);
+        g_free(state->orig_buf);
     state->buf_start = start;
     state->buf_len = acb->end + s->readahead_size;
     end = MIN(start + state->buf_len, s->len) - 1;
-    state->orig_buf = qemu_malloc(state->buf_len);
+    state->orig_buf = g_malloc(state->buf_len);
     state->acb[0] = acb;
 
     snprintf(state->range, 127, "%zd-%zd", start, end);
@@ -476,7 +476,7 @@ static void curl_close(BlockDriverState *bs)
             s->states[i].curl = NULL;
         }
         if (s->states[i].orig_buf) {
-            qemu_free(s->states[i].orig_buf);
+            g_free(s->states[i].orig_buf);
             s->states[i].orig_buf = NULL;
         }
     }
diff --git a/block/dmg.c b/block/dmg.c
index a3c815b..64c3cce 100644
--- a/block/dmg.c
+++ b/block/dmg.c
@@ -127,11 +127,11 @@ static int dmg_open(BlockDriverState *bs, int flags)
 
 	    chunk_count = (count-204)/40;
 	    new_size = sizeof(uint64_t) * (s->n_chunks + chunk_count);
-	    s->types = qemu_realloc(s->types, new_size/2);
-	    s->offsets = qemu_realloc(s->offsets, new_size);
-	    s->lengths = qemu_realloc(s->lengths, new_size);
-	    s->sectors = qemu_realloc(s->sectors, new_size);
-	    s->sectorcounts = qemu_realloc(s->sectorcounts, new_size);
+	    s->types = g_realloc(s->types, new_size/2);
+	    s->offsets = g_realloc(s->offsets, new_size);
+	    s->lengths = g_realloc(s->lengths, new_size);
+	    s->sectors = g_realloc(s->sectors, new_size);
+	    s->sectorcounts = g_realloc(s->sectorcounts, new_size);
 
 	    for(i=s->n_chunks;i<s->n_chunks+chunk_count;i++) {
 		s->types[i] = read_uint32(bs, offset);
@@ -170,8 +170,8 @@ static int dmg_open(BlockDriverState *bs, int flags)
     }
 
     /* initialize zlib engine */
-    s->compressed_chunk = qemu_malloc(max_compressed_size+1);
-    s->uncompressed_chunk = qemu_malloc(512*max_sectors_per_chunk);
+    s->compressed_chunk = g_malloc(max_compressed_size+1);
+    s->uncompressed_chunk = g_malloc(512*max_sectors_per_chunk);
     if(inflateInit(&s->zstream) != Z_OK)
 	goto fail;
 
diff --git a/block/nbd.c b/block/nbd.c
index 7a52f62..55cb2fd 100644
--- a/block/nbd.c
+++ b/block/nbd.c
@@ -65,7 +65,7 @@ static int nbd_config(BDRVNBDState *s, const char *filename, int flags)
     const char *unixpath;
     int err = -EINVAL;
 
-    file = qemu_strdup(filename);
+    file = g_strdup(filename);
 
     export_name = strstr(file, EN_OPTSTR);
     if (export_name) {
@@ -74,7 +74,7 @@ static int nbd_config(BDRVNBDState *s, const char *filename, int flags)
         }
         export_name[0] = 0; /* truncate 'file' */
         export_name += strlen(EN_OPTSTR);
-        s->export_name = qemu_strdup(export_name);
+        s->export_name = g_strdup(export_name);
     }
 
     /* extract the host_spec - fail if it's not nbd:... */
@@ -87,18 +87,18 @@ static int nbd_config(BDRVNBDState *s, const char *filename, int flags)
         if (unixpath[0] != '/') { /* We demand  an absolute path*/
             goto out;
         }
-        s->host_spec = qemu_strdup(unixpath);
+        s->host_spec = g_strdup(unixpath);
     } else {
-        s->host_spec = qemu_strdup(host_spec);
+        s->host_spec = g_strdup(host_spec);
     }
 
     err = 0;
 
 out:
-    qemu_free(file);
+    g_free(file);
     if (err != 0) {
-        qemu_free(s->export_name);
-        qemu_free(s->host_spec);
+        g_free(s->export_name);
+        g_free(s->host_spec);
     }
     return err;
 }
@@ -240,8 +240,8 @@ static int nbd_write(BlockDriverState *bs, int64_t sector_num,
 static void nbd_close(BlockDriverState *bs)
 {
     BDRVNBDState *s = bs->opaque;
-    qemu_free(s->export_name);
-    qemu_free(s->host_spec);
+    g_free(s->export_name);
+    g_free(s->host_spec);
 
     nbd_teardown_connection(bs);
 }
diff --git a/block/parallels.c b/block/parallels.c
index 35a14aa..37d151d 100644
--- a/block/parallels.c
+++ b/block/parallels.c
@@ -88,7 +88,7 @@ static int parallels_open(BlockDriverState *bs, int flags)
     s->tracks = le32_to_cpu(ph.tracks);
 
     s->catalog_size = le32_to_cpu(ph.catalog_entries);
-    s->catalog_bitmap = qemu_malloc(s->catalog_size * 4);
+    s->catalog_bitmap = g_malloc(s->catalog_size * 4);
     if (bdrv_pread(bs->file, 64, s->catalog_bitmap, s->catalog_size * 4) !=
 	s->catalog_size * 4)
 	goto fail;
@@ -98,7 +98,7 @@ static int parallels_open(BlockDriverState *bs, int flags)
     return 0;
 fail:
     if (s->catalog_bitmap)
-	qemu_free(s->catalog_bitmap);
+	g_free(s->catalog_bitmap);
     return -1;
 }
 
@@ -137,7 +137,7 @@ static int parallels_read(BlockDriverState *bs, int64_t sector_num,
 static void parallels_close(BlockDriverState *bs)
 {
     BDRVParallelsState *s = bs->opaque;
-    qemu_free(s->catalog_bitmap);
+    g_free(s->catalog_bitmap);
 }
 
 static BlockDriver bdrv_parallels = {
diff --git a/block/qcow.c b/block/qcow.c
index 6447c2a..e155d3c 100644
--- a/block/qcow.c
+++ b/block/qcow.c
@@ -129,7 +129,7 @@ static int qcow_open(BlockDriverState *bs, int flags)
     s->l1_size = (header.size + (1LL << shift) - 1) >> shift;
 
     s->l1_table_offset = header.l1_table_offset;
-    s->l1_table = qemu_malloc(s->l1_size * sizeof(uint64_t));
+    s->l1_table = g_malloc(s->l1_size * sizeof(uint64_t));
     if (!s->l1_table)
         goto fail;
     if (bdrv_pread(bs->file, s->l1_table_offset, s->l1_table, s->l1_size * sizeof(uint64_t)) !=
@@ -139,13 +139,13 @@ static int qcow_open(BlockDriverState *bs, int flags)
         be64_to_cpus(&s->l1_table[i]);
     }
     /* alloc L2 cache */
-    s->l2_cache = qemu_malloc(s->l2_size * L2_CACHE_SIZE * sizeof(uint64_t));
+    s->l2_cache = g_malloc(s->l2_size * L2_CACHE_SIZE * sizeof(uint64_t));
     if (!s->l2_cache)
         goto fail;
-    s->cluster_cache = qemu_malloc(s->cluster_size);
+    s->cluster_cache = g_malloc(s->cluster_size);
     if (!s->cluster_cache)
         goto fail;
-    s->cluster_data = qemu_malloc(s->cluster_size);
+    s->cluster_data = g_malloc(s->cluster_size);
     if (!s->cluster_data)
         goto fail;
     s->cluster_cache_offset = -1;
@@ -162,10 +162,10 @@ static int qcow_open(BlockDriverState *bs, int flags)
     return 0;
 
  fail:
-    qemu_free(s->l1_table);
-    qemu_free(s->l2_cache);
-    qemu_free(s->cluster_cache);
-    qemu_free(s->cluster_data);
+    g_free(s->l1_table);
+    g_free(s->l2_cache);
+    g_free(s->cluster_cache);
+    g_free(s->cluster_data);
     return -1;
 }
 
@@ -687,7 +687,7 @@ static int qcow_aio_write_cb(void *opaque)
     }
     if (s->crypt_method) {
         if (!acb->cluster_data) {
-            acb->cluster_data = qemu_mallocz(s->cluster_size);
+            acb->cluster_data = g_malloc0(s->cluster_size);
         }
         encrypt_sectors(s, acb->sector_num, acb->cluster_data, acb->buf,
                         acb->n, 1, &s->aes_encrypt_key);
@@ -738,10 +738,10 @@ static int qcow_co_writev(BlockDriverState *bs, int64_t sector_num,
 static void qcow_close(BlockDriverState *bs)
 {
     BDRVQcowState *s = bs->opaque;
-    qemu_free(s->l1_table);
-    qemu_free(s->l2_cache);
-    qemu_free(s->cluster_cache);
-    qemu_free(s->cluster_data);
+    g_free(s->l1_table);
+    g_free(s->l2_cache);
+    g_free(s->cluster_cache);
+    g_free(s->cluster_data);
 }
 
 static int qcow_create(const char *filename, QEMUOptionParameter *options)
@@ -869,7 +869,7 @@ static int qcow_write_compressed(BlockDriverState *bs, int64_t sector_num,
     if (nb_sectors != s->cluster_sectors)
         return -EINVAL;
 
-    out_buf = qemu_malloc(s->cluster_size + (s->cluster_size / 1000) + 128);
+    out_buf = g_malloc(s->cluster_size + (s->cluster_size / 1000) + 128);
     if (!out_buf)
         return -1;
 
@@ -879,7 +879,7 @@ static int qcow_write_compressed(BlockDriverState *bs, int64_t sector_num,
                        Z_DEFLATED, -12,
                        9, Z_DEFAULT_STRATEGY);
     if (ret != 0) {
-        qemu_free(out_buf);
+        g_free(out_buf);
         return -1;
     }
 
@@ -890,7 +890,7 @@ static int qcow_write_compressed(BlockDriverState *bs, int64_t sector_num,
 
     ret = deflate(&strm, Z_FINISH);
     if (ret != Z_STREAM_END && ret != Z_OK) {
-        qemu_free(out_buf);
+        g_free(out_buf);
         deflateEnd(&strm);
         return -1;
     }
@@ -906,12 +906,12 @@ static int qcow_write_compressed(BlockDriverState *bs, int64_t sector_num,
                                             out_len, 0, 0);
         cluster_offset &= s->cluster_offset_mask;
         if (bdrv_pwrite(bs->file, cluster_offset, out_buf, out_len) != out_len) {
-            qemu_free(out_buf);
+            g_free(out_buf);
             return -1;
         }
     }
 
-    qemu_free(out_buf);
+    g_free(out_buf);
     return 0;
 }
 
diff --git a/block/qcow2-cache.c b/block/qcow2-cache.c
index 8408847..340a6f2 100644
--- a/block/qcow2-cache.c
+++ b/block/qcow2-cache.c
@@ -49,9 +49,9 @@ Qcow2Cache *qcow2_cache_create(BlockDriverState *bs, int num_tables,
     Qcow2Cache *c;
     int i;
 
-    c = qemu_mallocz(sizeof(*c));
+    c = g_malloc0(sizeof(*c));
     c->size = num_tables;
-    c->entries = qemu_mallocz(sizeof(*c->entries) * num_tables);
+    c->entries = g_malloc0(sizeof(*c->entries) * num_tables);
     c->writethrough = writethrough;
 
     for (i = 0; i < c->size; i++) {
@@ -70,8 +70,8 @@ int qcow2_cache_destroy(BlockDriverState* bs, Qcow2Cache *c)
         qemu_vfree(c->entries[i].table);
     }
 
-    qemu_free(c->entries);
-    qemu_free(c);
+    g_free(c->entries);
+    g_free(c);
 
     return 0;
 }
diff --git a/block/qcow2-cluster.c b/block/qcow2-cluster.c
index 81cf77d..9269dda 100644
--- a/block/qcow2-cluster.c
+++ b/block/qcow2-cluster.c
@@ -57,14 +57,14 @@ int qcow2_grow_l1_table(BlockDriverState *bs, int min_size, bool exact_size)
 #endif
 
     new_l1_size2 = sizeof(uint64_t) * new_l1_size;
-    new_l1_table = qemu_mallocz(align_offset(new_l1_size2, 512));
+    new_l1_table = g_malloc0(align_offset(new_l1_size2, 512));
     memcpy(new_l1_table, s->l1_table, s->l1_size * sizeof(uint64_t));
 
     /* write new table (align to cluster) */
     BLKDBG_EVENT(bs->file, BLKDBG_L1_GROW_ALLOC_TABLE);
     new_l1_table_offset = qcow2_alloc_clusters(bs, new_l1_size2);
     if (new_l1_table_offset < 0) {
-        qemu_free(new_l1_table);
+        g_free(new_l1_table);
         return new_l1_table_offset;
     }
 
@@ -90,14 +90,14 @@ int qcow2_grow_l1_table(BlockDriverState *bs, int min_size, bool exact_size)
     if (ret < 0) {
         goto fail;
     }
-    qemu_free(s->l1_table);
+    g_free(s->l1_table);
     qcow2_free_clusters(bs, s->l1_table_offset, s->l1_size * sizeof(uint64_t));
     s->l1_table_offset = new_l1_table_offset;
     s->l1_table = new_l1_table;
     s->l1_size = new_l1_size;
     return 0;
  fail:
-    qemu_free(new_l1_table);
+    g_free(new_l1_table);
     qcow2_free_clusters(bs, new_l1_table_offset, new_l1_size2);
     return ret;
 }
@@ -612,7 +612,7 @@ int qcow2_alloc_cluster_link_l2(BlockDriverState *bs, QCowL2Meta *m)
     if (m->nb_clusters == 0)
         return 0;
 
-    old_cluster = qemu_malloc(m->nb_clusters * sizeof(uint64_t));
+    old_cluster = g_malloc(m->nb_clusters * sizeof(uint64_t));
 
     /* copy content of unmodified sectors */
     start_sect = (m->offset & ~(s->cluster_size - 1)) >> 9;
@@ -683,7 +683,7 @@ int qcow2_alloc_cluster_link_l2(BlockDriverState *bs, QCowL2Meta *m)
 
     ret = 0;
 err:
-    qemu_free(old_cluster);
+    g_free(old_cluster);
     return ret;
  }
 
diff --git a/block/qcow2-refcount.c b/block/qcow2-refcount.c
index 14b2f67..2a915be 100644
--- a/block/qcow2-refcount.c
+++ b/block/qcow2-refcount.c
@@ -41,7 +41,7 @@ int qcow2_refcount_init(BlockDriverState *bs)
     int ret, refcount_table_size2, i;
 
     refcount_table_size2 = s->refcount_table_size * sizeof(uint64_t);
-    s->refcount_table = qemu_malloc(refcount_table_size2);
+    s->refcount_table = g_malloc(refcount_table_size2);
     if (s->refcount_table_size > 0) {
         BLKDBG_EVENT(bs->file, BLKDBG_REFTABLE_LOAD);
         ret = bdrv_pread(bs->file, s->refcount_table_offset,
@@ -59,7 +59,7 @@ int qcow2_refcount_init(BlockDriverState *bs)
 void qcow2_refcount_close(BlockDriverState *bs)
 {
     BDRVQcowState *s = bs->opaque;
-    qemu_free(s->refcount_table);
+    g_free(s->refcount_table);
 }
 
 
@@ -323,8 +323,8 @@ static int alloc_refcount_block(BlockDriverState *bs,
     uint64_t meta_offset = (blocks_used * refcount_block_clusters) *
         s->cluster_size;
     uint64_t table_offset = meta_offset + blocks_clusters * s->cluster_size;
-    uint16_t *new_blocks = qemu_mallocz(blocks_clusters * s->cluster_size);
-    uint64_t *new_table = qemu_mallocz(table_size * sizeof(uint64_t));
+    uint16_t *new_blocks = g_malloc0(blocks_clusters * s->cluster_size);
+    uint64_t *new_table = g_malloc0(table_size * sizeof(uint64_t));
 
     assert(meta_offset >= (s->free_cluster_index * s->cluster_size));
 
@@ -349,7 +349,7 @@ static int alloc_refcount_block(BlockDriverState *bs,
     BLKDBG_EVENT(bs->file, BLKDBG_REFBLOCK_ALLOC_WRITE_BLOCKS);
     ret = bdrv_pwrite_sync(bs->file, meta_offset, new_blocks,
         blocks_clusters * s->cluster_size);
-    qemu_free(new_blocks);
+    g_free(new_blocks);
     if (ret < 0) {
         goto fail_table;
     }
@@ -385,7 +385,7 @@ static int alloc_refcount_block(BlockDriverState *bs,
     uint64_t old_table_offset = s->refcount_table_offset;
     uint64_t old_table_size = s->refcount_table_size;
 
-    qemu_free(s->refcount_table);
+    g_free(s->refcount_table);
     s->refcount_table = new_table;
     s->refcount_table_size = table_size;
     s->refcount_table_offset = table_offset;
@@ -403,7 +403,7 @@ static int alloc_refcount_block(BlockDriverState *bs,
     return new_block;
 
 fail_table:
-    qemu_free(new_table);
+    g_free(new_table);
 fail_block:
     if (*refcount_block != NULL) {
         qcow2_cache_put(bs, s->refcount_block_cache, (void**) refcount_block);
@@ -720,7 +720,7 @@ int qcow2_update_snapshot_refcount(BlockDriverState *bs,
     l1_size2 = l1_size * sizeof(uint64_t);
     if (l1_table_offset != s->l1_table_offset) {
         if (l1_size2 != 0) {
-            l1_table = qemu_mallocz(align_offset(l1_size2, 512));
+            l1_table = g_malloc0(align_offset(l1_size2, 512));
         } else {
             l1_table = NULL;
         }
@@ -847,7 +847,7 @@ fail:
             be64_to_cpus(&l1_table[i]);
     }
     if (l1_allocated)
-        qemu_free(l1_table);
+        g_free(l1_table);
     return ret;
 }
 
@@ -921,7 +921,7 @@ static int check_refcounts_l2(BlockDriverState *bs, BdrvCheckResult *res,
 
     /* Read L2 table from disk */
     l2_size = s->l2_size * sizeof(uint64_t);
-    l2_table = qemu_malloc(l2_size);
+    l2_table = g_malloc(l2_size);
 
     if (bdrv_pread(bs->file, l2_offset, l2_table, l2_size) != l2_size)
         goto fail;
@@ -979,12 +979,12 @@ static int check_refcounts_l2(BlockDriverState *bs, BdrvCheckResult *res,
         }
     }
 
-    qemu_free(l2_table);
+    g_free(l2_table);
     return 0;
 
 fail:
     fprintf(stderr, "ERROR: I/O error in check_refcounts_l2\n");
-    qemu_free(l2_table);
+    g_free(l2_table);
     return -EIO;
 }
 
@@ -1017,7 +1017,7 @@ static int check_refcounts_l1(BlockDriverState *bs,
     if (l1_size2 == 0) {
         l1_table = NULL;
     } else {
-        l1_table = qemu_malloc(l1_size2);
+        l1_table = g_malloc(l1_size2);
         if (bdrv_pread(bs->file, l1_table_offset,
                        l1_table, l1_size2) != l1_size2)
             goto fail;
@@ -1065,13 +1065,13 @@ static int check_refcounts_l1(BlockDriverState *bs,
             }
         }
     }
-    qemu_free(l1_table);
+    g_free(l1_table);
     return 0;
 
 fail:
     fprintf(stderr, "ERROR: I/O error in check_refcounts_l1\n");
     res->check_errors++;
-    qemu_free(l1_table);
+    g_free(l1_table);
     return -EIO;
 }
 
@@ -1092,7 +1092,7 @@ int qcow2_check_refcounts(BlockDriverState *bs, BdrvCheckResult *res)
 
     size = bdrv_getlength(bs->file);
     nb_clusters = size_to_clusters(s, size);
-    refcount_table = qemu_mallocz(nb_clusters * sizeof(uint16_t));
+    refcount_table = g_malloc0(nb_clusters * sizeof(uint16_t));
 
     /* header */
     inc_refcounts(bs, res, refcount_table, nb_clusters,
@@ -1178,7 +1178,7 @@ int qcow2_check_refcounts(BlockDriverState *bs, BdrvCheckResult *res)
     ret = 0;
 
 fail:
-    qemu_free(refcount_table);
+    g_free(refcount_table);
 
     return ret;
 }
diff --git a/block/qcow2-snapshot.c b/block/qcow2-snapshot.c
index e32bcf0..3bd2a30 100644
--- a/block/qcow2-snapshot.c
+++ b/block/qcow2-snapshot.c
@@ -52,10 +52,10 @@ void qcow2_free_snapshots(BlockDriverState *bs)
     int i;
 
     for(i = 0; i < s->nb_snapshots; i++) {
-        qemu_free(s->snapshots[i].name);
-        qemu_free(s->snapshots[i].id_str);
+        g_free(s->snapshots[i].name);
+        g_free(s->snapshots[i].id_str);
     }
-    qemu_free(s->snapshots);
+    g_free(s->snapshots);
     s->snapshots = NULL;
     s->nb_snapshots = 0;
 }
@@ -76,7 +76,7 @@ int qcow2_read_snapshots(BlockDriverState *bs)
     }
 
     offset = s->snapshots_offset;
-    s->snapshots = qemu_mallocz(s->nb_snapshots * sizeof(QCowSnapshot));
+    s->snapshots = g_malloc0(s->nb_snapshots * sizeof(QCowSnapshot));
     for(i = 0; i < s->nb_snapshots; i++) {
         offset = align_offset(offset, 8);
         if (bdrv_pread(bs->file, offset, &h, sizeof(h)) != sizeof(h))
@@ -96,13 +96,13 @@ int qcow2_read_snapshots(BlockDriverState *bs)
 
         offset += extra_data_size;
 
-        sn->id_str = qemu_malloc(id_str_size + 1);
+        sn->id_str = g_malloc(id_str_size + 1);
         if (bdrv_pread(bs->file, offset, sn->id_str, id_str_size) != id_str_size)
             goto fail;
         offset += id_str_size;
         sn->id_str[id_str_size] = '\0';
 
-        sn->name = qemu_malloc(name_size + 1);
+        sn->name = g_malloc(name_size + 1);
         if (bdrv_pread(bs->file, offset, sn->name, name_size) != name_size)
             goto fail;
         offset += name_size;
@@ -252,10 +252,10 @@ int qcow2_snapshot_create(BlockDriverState *bs, QEMUSnapshotInfo *sn_info)
     if (find_snapshot_by_id(bs, sn_info->id_str) >= 0)
         return -ENOENT;
 
-    sn->id_str = qemu_strdup(sn_info->id_str);
+    sn->id_str = g_strdup(sn_info->id_str);
     if (!sn->id_str)
         goto fail;
-    sn->name = qemu_strdup(sn_info->name);
+    sn->name = g_strdup(sn_info->name);
     if (!sn->name)
         goto fail;
     sn->vm_state_size = sn_info->vm_state_size;
@@ -278,7 +278,7 @@ int qcow2_snapshot_create(BlockDriverState *bs, QEMUSnapshotInfo *sn_info)
     sn->l1_size = s->l1_size;
 
     if (s->l1_size != 0) {
-        l1_table = qemu_malloc(s->l1_size * sizeof(uint64_t));
+        l1_table = g_malloc(s->l1_size * sizeof(uint64_t));
     } else {
         l1_table = NULL;
     }
@@ -289,13 +289,13 @@ int qcow2_snapshot_create(BlockDriverState *bs, QEMUSnapshotInfo *sn_info)
     if (bdrv_pwrite_sync(bs->file, sn->l1_table_offset,
                     l1_table, s->l1_size * sizeof(uint64_t)) < 0)
         goto fail;
-    qemu_free(l1_table);
+    g_free(l1_table);
     l1_table = NULL;
 
-    snapshots1 = qemu_malloc((s->nb_snapshots + 1) * sizeof(QCowSnapshot));
+    snapshots1 = g_malloc((s->nb_snapshots + 1) * sizeof(QCowSnapshot));
     if (s->snapshots) {
         memcpy(snapshots1, s->snapshots, s->nb_snapshots * sizeof(QCowSnapshot));
-        qemu_free(s->snapshots);
+        g_free(s->snapshots);
     }
     s->snapshots = snapshots1;
     s->snapshots[s->nb_snapshots++] = *sn;
@@ -307,8 +307,8 @@ int qcow2_snapshot_create(BlockDriverState *bs, QEMUSnapshotInfo *sn_info)
 #endif
     return 0;
  fail:
-    qemu_free(sn->name);
-    qemu_free(l1_table);
+    g_free(sn->name);
+    g_free(l1_table);
     return -1;
 }
 
@@ -380,8 +380,8 @@ int qcow2_snapshot_delete(BlockDriverState *bs, const char *snapshot_id)
         return ret;
     qcow2_free_clusters(bs, sn->l1_table_offset, sn->l1_size * sizeof(uint64_t));
 
-    qemu_free(sn->id_str);
-    qemu_free(sn->name);
+    g_free(sn->id_str);
+    g_free(sn->name);
     memmove(sn, sn + 1, (s->nb_snapshots - snapshot_index - 1) * sizeof(*sn));
     s->nb_snapshots--;
     ret = qcow2_write_snapshots(bs);
@@ -407,7 +407,7 @@ int qcow2_snapshot_list(BlockDriverState *bs, QEMUSnapshotInfo **psn_tab)
         return s->nb_snapshots;
     }
 
-    sn_tab = qemu_mallocz(s->nb_snapshots * sizeof(QEMUSnapshotInfo));
+    sn_tab = g_malloc0(s->nb_snapshots * sizeof(QEMUSnapshotInfo));
     for(i = 0; i < s->nb_snapshots; i++) {
         sn_info = sn_tab + i;
         sn = s->snapshots + i;
@@ -439,11 +439,11 @@ int qcow2_snapshot_load_tmp(BlockDriverState *bs, const char *snapshot_name)
     s->l1_size = sn->l1_size;
     l1_size2 = s->l1_size * sizeof(uint64_t);
     if (s->l1_table != NULL) {
-        qemu_free(s->l1_table);
+        g_free(s->l1_table);
     }
 
     s->l1_table_offset = sn->l1_table_offset;
-    s->l1_table = qemu_mallocz(align_offset(l1_size2, 512));
+    s->l1_table = g_malloc0(align_offset(l1_size2, 512));
 
     if (bdrv_pread(bs->file, sn->l1_table_offset,
                    s->l1_table, l1_size2) != l1_size2) {
diff --git a/block/qcow2.c b/block/qcow2.c
index f07d550..bfff6cd 100644
--- a/block/qcow2.c
+++ b/block/qcow2.c
@@ -216,7 +216,7 @@ static int qcow2_open(BlockDriverState *bs, int flags)
     }
     s->l1_table_offset = header.l1_table_offset;
     if (s->l1_size > 0) {
-        s->l1_table = qemu_mallocz(
+        s->l1_table = g_malloc0(
             align_offset(s->l1_size * sizeof(uint64_t), 512));
         ret = bdrv_pread(bs->file, s->l1_table_offset, s->l1_table,
                          s->l1_size * sizeof(uint64_t));
@@ -234,9 +234,9 @@ static int qcow2_open(BlockDriverState *bs, int flags)
     s->refcount_block_cache = qcow2_cache_create(bs, REFCOUNT_CACHE_SIZE,
         writethrough);
 
-    s->cluster_cache = qemu_malloc(s->cluster_size);
+    s->cluster_cache = g_malloc(s->cluster_size);
     /* one more sector for decompressed data alignment */
-    s->cluster_data = qemu_malloc(QCOW_MAX_CRYPT_CLUSTERS * s->cluster_size
+    s->cluster_data = g_malloc(QCOW_MAX_CRYPT_CLUSTERS * s->cluster_size
                                   + 512);
     s->cluster_cache_offset = -1;
 
@@ -287,12 +287,12 @@ static int qcow2_open(BlockDriverState *bs, int flags)
  fail:
     qcow2_free_snapshots(bs);
     qcow2_refcount_close(bs);
-    qemu_free(s->l1_table);
+    g_free(s->l1_table);
     if (s->l2_table_cache) {
         qcow2_cache_destroy(bs, s->l2_table_cache);
     }
-    qemu_free(s->cluster_cache);
-    qemu_free(s->cluster_data);
+    g_free(s->cluster_cache);
+    g_free(s->cluster_data);
     return ret;
 }
 
@@ -501,7 +501,7 @@ static int qcow2_aio_read_cb(QCowAIOCB *acb)
              */
             if (!acb->cluster_data) {
                 acb->cluster_data =
-                    qemu_mallocz(QCOW_MAX_CRYPT_CLUSTERS * s->cluster_size);
+                    g_malloc0(QCOW_MAX_CRYPT_CLUSTERS * s->cluster_size);
             }
 
             assert(acb->cur_nr_sectors <=
@@ -636,7 +636,7 @@ static int qcow2_aio_write_cb(QCowAIOCB *acb)
 
     if (s->crypt_method) {
         if (!acb->cluster_data) {
-            acb->cluster_data = qemu_mallocz(QCOW_MAX_CRYPT_CLUSTERS *
+            acb->cluster_data = g_malloc0(QCOW_MAX_CRYPT_CLUSTERS *
                                              s->cluster_size);
         }
 
@@ -691,7 +691,7 @@ static int qcow2_co_writev(BlockDriverState *bs,
 static void qcow2_close(BlockDriverState *bs)
 {
     BDRVQcowState *s = bs->opaque;
-    qemu_free(s->l1_table);
+    g_free(s->l1_table);
 
     qcow2_cache_flush(bs, s->l2_table_cache);
     qcow2_cache_flush(bs, s->refcount_block_cache);
@@ -699,8 +699,8 @@ static void qcow2_close(BlockDriverState *bs)
     qcow2_cache_destroy(bs, s->l2_table_cache);
     qcow2_cache_destroy(bs, s->refcount_block_cache);
 
-    qemu_free(s->cluster_cache);
-    qemu_free(s->cluster_data);
+    g_free(s->cluster_cache);
+    g_free(s->cluster_data);
     qcow2_refcount_close(bs);
 }
 
@@ -923,9 +923,9 @@ static int qcow2_create2(const char *filename, int64_t total_size,
     }
 
     /* Write an empty refcount table */
-    refcount_table = qemu_mallocz(cluster_size);
+    refcount_table = g_malloc0(cluster_size);
     ret = bdrv_pwrite(bs, cluster_size, refcount_table, cluster_size);
-    qemu_free(refcount_table);
+    g_free(refcount_table);
 
     if (ret < 0) {
         goto out;
@@ -1117,7 +1117,7 @@ static int qcow2_write_compressed(BlockDriverState *bs, int64_t sector_num,
     if (nb_sectors != s->cluster_sectors)
         return -EINVAL;
 
-    out_buf = qemu_malloc(s->cluster_size + (s->cluster_size / 1000) + 128);
+    out_buf = g_malloc(s->cluster_size + (s->cluster_size / 1000) + 128);
 
     /* best compression, small window, no zlib header */
     memset(&strm, 0, sizeof(strm));
@@ -1125,7 +1125,7 @@ static int qcow2_write_compressed(BlockDriverState *bs, int64_t sector_num,
                        Z_DEFLATED, -12,
                        9, Z_DEFAULT_STRATEGY);
     if (ret != 0) {
-        qemu_free(out_buf);
+        g_free(out_buf);
         return -1;
     }
 
@@ -1136,7 +1136,7 @@ static int qcow2_write_compressed(BlockDriverState *bs, int64_t sector_num,
 
     ret = deflate(&strm, Z_FINISH);
     if (ret != Z_STREAM_END && ret != Z_OK) {
-        qemu_free(out_buf);
+        g_free(out_buf);
         deflateEnd(&strm);
         return -1;
     }
@@ -1155,12 +1155,12 @@ static int qcow2_write_compressed(BlockDriverState *bs, int64_t sector_num,
         cluster_offset &= s->cluster_offset_mask;
         BLKDBG_EVENT(bs->file, BLKDBG_WRITE_COMPRESSED);
         if (bdrv_pwrite(bs->file, cluster_offset, out_buf, out_len) != out_len) {
-            qemu_free(out_buf);
+            g_free(out_buf);
             return -1;
         }
     }
 
-    qemu_free(out_buf);
+    g_free(out_buf);
     return 0;
 }
 
diff --git a/block/qed-check.c b/block/qed-check.c
index 22cd07f..e4a49ce 100644
--- a/block/qed-check.c
+++ b/block/qed-check.c
@@ -197,7 +197,7 @@ int qed_check(BDRVQEDState *s, BdrvCheckResult *result, bool fix)
     };
     int ret;
 
-    check.used_clusters = qemu_mallocz(((check.nclusters + 31) / 32) *
+    check.used_clusters = g_malloc0(((check.nclusters + 31) / 32) *
                                        sizeof(check.used_clusters[0]));
 
     ret = qed_check_l1_table(&check, s->l1_table);
@@ -206,6 +206,6 @@ int qed_check(BDRVQEDState *s, BdrvCheckResult *result, bool fix)
         qed_check_for_leaks(&check);
     }
 
-    qemu_free(check.used_clusters);
+    g_free(check.used_clusters);
     return ret;
 }
diff --git a/block/qed-cluster.c b/block/qed-cluster.c
index 3e19ad1..f64b2af 100644
--- a/block/qed-cluster.c
+++ b/block/qed-cluster.c
@@ -108,7 +108,7 @@ static void qed_find_cluster_cb(void *opaque, int ret)
 
 out:
     find_cluster_cb->cb(find_cluster_cb->opaque, ret, offset, len);
-    qemu_free(find_cluster_cb);
+    g_free(find_cluster_cb);
 }
 
 /**
@@ -152,7 +152,7 @@ void qed_find_cluster(BDRVQEDState *s, QEDRequest *request, uint64_t pos,
         return;
     }
 
-    find_cluster_cb = qemu_malloc(sizeof(*find_cluster_cb));
+    find_cluster_cb = g_malloc(sizeof(*find_cluster_cb));
     find_cluster_cb->s = s;
     find_cluster_cb->pos = pos;
     find_cluster_cb->len = len;
diff --git a/block/qed-gencb.c b/block/qed-gencb.c
index 1513dc6..7d7ac1f 100644
--- a/block/qed-gencb.c
+++ b/block/qed-gencb.c
@@ -15,7 +15,7 @@
 
 void *gencb_alloc(size_t len, BlockDriverCompletionFunc *cb, void *opaque)
 {
-    GenericCB *gencb = qemu_malloc(len);
+    GenericCB *gencb = g_malloc(len);
     gencb->cb = cb;
     gencb->opaque = opaque;
     return gencb;
@@ -27,6 +27,6 @@ void gencb_complete(void *opaque, int ret)
     BlockDriverCompletionFunc *cb = gencb->cb;
     void *user_opaque = gencb->opaque;
 
-    qemu_free(gencb);
+    g_free(gencb);
     cb(user_opaque, ret);
 }
diff --git a/block/qed-l2-cache.c b/block/qed-l2-cache.c
index 57518a4..02b81a2 100644
--- a/block/qed-l2-cache.c
+++ b/block/qed-l2-cache.c
@@ -74,7 +74,7 @@ void qed_free_l2_cache(L2TableCache *l2_cache)
 
     QTAILQ_FOREACH_SAFE(entry, &l2_cache->entries, node, next_entry) {
         qemu_vfree(entry->table);
-        qemu_free(entry);
+        g_free(entry);
     }
 }
 
@@ -89,7 +89,7 @@ CachedL2Table *qed_alloc_l2_cache_entry(L2TableCache *l2_cache)
 {
     CachedL2Table *entry;
 
-    entry = qemu_mallocz(sizeof(*entry));
+    entry = g_malloc0(sizeof(*entry));
     entry->ref++;
 
     trace_qed_alloc_l2_cache_entry(l2_cache, entry);
@@ -111,7 +111,7 @@ void qed_unref_l2_cache_entry(CachedL2Table *entry)
     trace_qed_unref_l2_cache_entry(entry, entry->ref);
     if (entry->ref == 0) {
         qemu_vfree(entry->table);
-        qemu_free(entry);
+        g_free(entry);
     }
 }
 
diff --git a/block/qed.c b/block/qed.c
index 333f067..624e261 100644
--- a/block/qed.c
+++ b/block/qed.c
@@ -595,7 +595,7 @@ static int qed_create(const char *filename, uint32_t cluster_size,
         goto out;
     }
 
-    l1_table = qemu_mallocz(l1_size);
+    l1_table = g_malloc0(l1_size);
     ret = bdrv_pwrite(bs, header.l1_table_offset, l1_table, l1_size);
     if (ret < 0) {
         goto out;
@@ -603,7 +603,7 @@ static int qed_create(const char *filename, uint32_t cluster_size,
 
     ret = 0; /* success */
 out:
-    qemu_free(l1_table);
+    g_free(l1_table);
     bdrv_delete(bs);
     return ret;
 }
@@ -1419,7 +1419,7 @@ static int bdrv_qed_change_backing_file(BlockDriverState *bs,
     }
 
     /* Prepare new header */
-    buffer = qemu_malloc(buffer_len);
+    buffer = g_malloc(buffer_len);
 
     qed_header_cpu_to_le(&new_header, &le_header);
     memcpy(buffer, &le_header, sizeof(le_header));
@@ -1430,7 +1430,7 @@ static int bdrv_qed_change_backing_file(BlockDriverState *bs,
 
     /* Write new header */
     ret = bdrv_pwrite_sync(bs->file, 0, buffer, buffer_len);
-    qemu_free(buffer);
+    g_free(buffer);
     if (ret == 0) {
         memcpy(&s->header, &new_header, sizeof(new_header));
     }
diff --git a/block/raw.c b/block/raw.c
index cb6203e..555db4f 100644
--- a/block/raw.c
+++ b/block/raw.c
@@ -119,7 +119,7 @@ static int raw_has_zero_init(BlockDriverState *bs)
 static BlockDriver bdrv_raw = {
     .format_name        = "raw",
 
-    /* It's really 0, but we need to make qemu_malloc() happy */
+    /* It's really 0, but we need to make g_malloc() happy */
     .instance_size      = 1,
 
     .bdrv_open          = raw_open,
diff --git a/block/rbd.c b/block/rbd.c
index d5659cd..ce0f6ef 100644
--- a/block/rbd.c
+++ b/block/rbd.c
@@ -138,7 +138,7 @@ static int qemu_rbd_parsename(const char *filename,
         return -EINVAL;
     }
 
-    buf = qemu_strdup(start);
+    buf = g_strdup(start);
     p = buf;
     *snap = '\0';
     *conf = '\0';
@@ -165,7 +165,7 @@ static int qemu_rbd_parsename(const char *filename,
     ret = qemu_rbd_next_tok(conf, conf_len, p, '\0', "configuration", &p);
 
 done:
-    qemu_free(buf);
+    g_free(buf);
     return ret;
 }
 
@@ -176,7 +176,7 @@ static int qemu_rbd_set_conf(rados_t cluster, const char *conf)
     char value[RBD_MAX_CONF_VAL_SIZE];
     int ret = 0;
 
-    buf = qemu_strdup(conf);
+    buf = g_strdup(conf);
     p = buf;
 
     while (p) {
@@ -214,7 +214,7 @@ static int qemu_rbd_set_conf(rados_t cluster, const char *conf)
         }
     }
 
-    qemu_free(buf);
+    g_free(buf);
     return ret;
 }
 
@@ -341,7 +341,7 @@ static void qemu_rbd_complete_aio(RADOSCB *rcb)
     acb->bh = qemu_bh_new(rbd_aio_bh_cb, acb);
     qemu_bh_schedule(acb->bh);
 done:
-    qemu_free(rcb);
+    g_free(rcb);
 }
 
 /*
@@ -395,7 +395,7 @@ static int qemu_rbd_open(BlockDriverState *bs, const char *filename, int flags)
     }
     s->snap = NULL;
     if (snap_buf[0] != '\0') {
-        s->snap = qemu_strdup(snap_buf);
+        s->snap = g_strdup(snap_buf);
     }
 
     r = rados_create(&s->cluster, NULL);
@@ -478,7 +478,7 @@ static void qemu_rbd_close(BlockDriverState *bs)
 
     rbd_close(s->image);
     rados_ioctx_destroy(s->io_ctx);
-    qemu_free(s->snap);
+    g_free(s->snap);
     rados_shutdown(s->cluster);
 }
 
@@ -544,7 +544,7 @@ static void rbd_finish_aiocb(rbd_completion_t c, RADOSCB *rcb)
     ret = qemu_rbd_send_pipe(rcb->s, rcb);
     if (ret < 0) {
         error_report("failed writing to acb->s->fds");
-        qemu_free(rcb);
+        g_free(rcb);
     }
 }
 
@@ -605,7 +605,7 @@ static BlockDriverAIOCB *rbd_aio_rw_vector(BlockDriverState *bs,
 
     s->qemu_aio_count++; /* All the RADOSCB */
 
-    rcb = qemu_malloc(sizeof(RADOSCB));
+    rcb = g_malloc(sizeof(RADOSCB));
     rcb->done = 0;
     rcb->acb = acb;
     rcb->buf = buf;
@@ -629,7 +629,7 @@ static BlockDriverAIOCB *rbd_aio_rw_vector(BlockDriverState *bs,
     return &acb->common;
 
 failed:
-    qemu_free(rcb);
+    g_free(rcb);
     s->qemu_aio_count--;
     qemu_aio_release(acb);
     return NULL;
@@ -739,10 +739,10 @@ static int qemu_rbd_snap_list(BlockDriverState *bs,
     int max_snaps = RBD_MAX_SNAPS;
 
     do {
-        snaps = qemu_malloc(sizeof(*snaps) * max_snaps);
+        snaps = g_malloc(sizeof(*snaps) * max_snaps);
         snap_count = rbd_snap_list(s->image, snaps, &max_snaps);
         if (snap_count < 0) {
-            qemu_free(snaps);
+            g_free(snaps);
         }
     } while (snap_count == -ERANGE);
 
@@ -750,7 +750,7 @@ static int qemu_rbd_snap_list(BlockDriverState *bs,
         return snap_count;
     }
 
-    sn_tab = qemu_mallocz(snap_count * sizeof(QEMUSnapshotInfo));
+    sn_tab = g_malloc0(snap_count * sizeof(QEMUSnapshotInfo));
 
     for (i = 0; i < snap_count; i++) {
         const char *snap_name = snaps[i].name;
diff --git a/block/sheepdog.c b/block/sheepdog.c
index e150ac0..57b6e1a 100644
--- a/block/sheepdog.c
+++ b/block/sheepdog.c
@@ -368,7 +368,7 @@ static inline AIOReq *alloc_aio_req(BDRVSheepdogState *s, SheepdogAIOCB *acb,
 {
     AIOReq *aio_req;
 
-    aio_req = qemu_malloc(sizeof(*aio_req));
+    aio_req = g_malloc(sizeof(*aio_req));
     aio_req->aiocb = acb;
     aio_req->iov_offset = iov_offset;
     aio_req->oid = oid;
@@ -390,7 +390,7 @@ static inline int free_aio_req(BDRVSheepdogState *s, AIOReq *aio_req)
     SheepdogAIOCB *acb = aio_req->aiocb;
     QLIST_REMOVE(aio_req, outstanding_aio_siblings);
     QLIST_REMOVE(aio_req, aioreq_siblings);
-    qemu_free(aio_req);
+    g_free(aio_req);
 
     return !QLIST_EMPTY(&acb->aioreq_head);
 }
@@ -470,7 +470,7 @@ static ssize_t sendmsg(int s, const struct msghdr *msg, int flags)
     for (i = 0; i < msg->msg_iovlen; i++) {
         size += msg->msg_iov[i].iov_len;
     }
-    buf = qemu_malloc(size);
+    buf = g_malloc(size);
 
     p = buf;
     for (i = 0; i < msg->msg_iovlen; i++) {
@@ -480,7 +480,7 @@ static ssize_t sendmsg(int s, const struct msghdr *msg, int flags)
 
     ret = send(s, buf, size, flags);
 
-    qemu_free(buf);
+    g_free(buf);
     return ret;
 }
 
@@ -494,7 +494,7 @@ static ssize_t recvmsg(int s, struct msghdr *msg, int flags)
     for (i = 0; i < msg->msg_iovlen; i++) {
         size += msg->msg_iov[i].iov_len;
     }
-    buf = qemu_malloc(size);
+    buf = g_malloc(size);
 
     ret = qemu_recv(s, buf, size, flags);
     if (ret < 0) {
@@ -507,7 +507,7 @@ static ssize_t recvmsg(int s, struct msghdr *msg, int flags)
         p += msg->msg_iov[i].iov_len;
     }
 out:
-    qemu_free(buf);
+    g_free(buf);
     return ret;
 }
 
@@ -952,7 +952,7 @@ static int parse_vdiname(BDRVSheepdogState *s, const char *filename,
     char *p, *q;
     int nr_sep;
 
-    p = q = qemu_strdup(filename);
+    p = q = g_strdup(filename);
 
     /* count the number of separators */
     nr_sep = 0;
@@ -992,7 +992,7 @@ static int parse_vdiname(BDRVSheepdogState *s, const char *filename,
     }
 
     if (s->addr == NULL) {
-        qemu_free(q);
+        g_free(q);
     }
 
     return 0;
@@ -1210,7 +1210,7 @@ static int sd_open(BlockDriverState *bs, const char *filename, int flags)
         goto out;
     }
 
-    buf = qemu_malloc(SD_INODE_SIZE);
+    buf = g_malloc(SD_INODE_SIZE);
     ret = read_object(fd, buf, vid_to_vdi_oid(vid), 0, SD_INODE_SIZE, 0);
 
     closesocket(fd);
@@ -1225,14 +1225,14 @@ static int sd_open(BlockDriverState *bs, const char *filename, int flags)
 
     bs->total_sectors = s->inode.vdi_size / SECTOR_SIZE;
     strncpy(s->name, vdi, sizeof(s->name));
-    qemu_free(buf);
+    g_free(buf);
     return 0;
 out:
     qemu_aio_set_fd_handler(s->fd, NULL, NULL, NULL, NULL, NULL);
     if (s->fd >= 0) {
         closesocket(s->fd);
     }
-    qemu_free(buf);
+    g_free(buf);
     return -1;
 }
 
@@ -1291,7 +1291,7 @@ static int sd_prealloc(const char *filename)
     BlockDriverState *bs = NULL;
     uint32_t idx, max_idx;
     int64_t vdi_size;
-    void *buf = qemu_mallocz(SD_DATA_OBJ_SIZE);
+    void *buf = g_malloc0(SD_DATA_OBJ_SIZE);
     int ret;
 
     ret = bdrv_file_open(&bs, filename, BDRV_O_RDWR);
@@ -1324,7 +1324,7 @@ out:
     if (bs) {
         bdrv_delete(bs);
     }
-    qemu_free(buf);
+    g_free(buf);
 
     return ret;
 }
@@ -1444,7 +1444,7 @@ static void sd_close(BlockDriverState *bs)
 
     qemu_aio_set_fd_handler(s->fd, NULL, NULL, NULL, NULL, NULL);
     closesocket(s->fd);
-    qemu_free(s->addr);
+    g_free(s->addr);
 }
 
 static int64_t sd_getlength(BlockDriverState *bs)
@@ -1542,7 +1542,7 @@ static int sd_create_branch(BDRVSheepdogState *s)
 
     dprintf("%" PRIx32 " is snapshot.\n", s->inode.vdi_id);
 
-    buf = qemu_malloc(SD_INODE_SIZE);
+    buf = g_malloc(SD_INODE_SIZE);
 
     ret = do_sd_create(s->name, s->inode.vdi_size, s->inode.vdi_id, &vid, 1,
                        s->addr, s->port);
@@ -1574,7 +1574,7 @@ static int sd_create_branch(BDRVSheepdogState *s)
     dprintf("%" PRIx32 " was newly created.\n", s->inode.vdi_id);
 
 out:
-    qemu_free(buf);
+    g_free(buf);
 
     return ret;
 }
@@ -1786,7 +1786,7 @@ static int sd_snapshot_create(BlockDriverState *bs, QEMUSnapshotInfo *sn_info)
         goto cleanup;
     }
 
-    inode = (SheepdogInode *)qemu_malloc(datalen);
+    inode = (SheepdogInode *)g_malloc(datalen);
 
     ret = read_object(fd, (char *)inode, vid_to_vdi_oid(new_vid),
                       s->inode.nr_copies, datalen, 0);
@@ -1816,7 +1816,7 @@ static int sd_snapshot_goto(BlockDriverState *bs, const char *snapshot_id)
     uint32_t snapid = 0;
     int ret = -ENOENT, fd;
 
-    old_s = qemu_malloc(sizeof(BDRVSheepdogState));
+    old_s = g_malloc(sizeof(BDRVSheepdogState));
 
     memcpy(old_s, s, sizeof(BDRVSheepdogState));
 
@@ -1842,7 +1842,7 @@ static int sd_snapshot_goto(BlockDriverState *bs, const char *snapshot_id)
         goto out;
     }
 
-    buf = qemu_malloc(SD_INODE_SIZE);
+    buf = g_malloc(SD_INODE_SIZE);
     ret = read_object(fd, buf, vid_to_vdi_oid(vid), s->inode.nr_copies,
                       SD_INODE_SIZE, 0);
 
@@ -1863,15 +1863,15 @@ static int sd_snapshot_goto(BlockDriverState *bs, const char *snapshot_id)
 
     s->is_snapshot = 1;
 
-    qemu_free(buf);
-    qemu_free(old_s);
+    g_free(buf);
+    g_free(old_s);
 
     return 0;
 out:
     /* recover bdrv_sd_state */
     memcpy(s, old_s, sizeof(BDRVSheepdogState));
-    qemu_free(buf);
-    qemu_free(old_s);
+    g_free(buf);
+    g_free(old_s);
 
     error_report("failed to open. recover old bdrv_sd_state.");
 
@@ -1898,7 +1898,7 @@ static int sd_snapshot_list(BlockDriverState *bs, QEMUSnapshotInfo **psn_tab)
     uint64_t hval;
     uint32_t vid;
 
-    vdi_inuse = qemu_malloc(max);
+    vdi_inuse = g_malloc(max);
 
     fd = connect_to_sdog(s->addr, s->port);
     if (fd < 0) {
@@ -1920,7 +1920,7 @@ static int sd_snapshot_list(BlockDriverState *bs, QEMUSnapshotInfo **psn_tab)
         goto out;
     }
 
-    sn_tab = qemu_mallocz(nr * sizeof(*sn_tab));
+    sn_tab = g_malloc0(nr * sizeof(*sn_tab));
 
     /* calculate a vdi id with hash function */
     hval = fnv_64a_buf(s->name, strlen(s->name), FNV1A_64_INIT);
@@ -1963,7 +1963,7 @@ static int sd_snapshot_list(BlockDriverState *bs, QEMUSnapshotInfo **psn_tab)
 out:
     *psn_tab = sn_tab;
 
-    qemu_free(vdi_inuse);
+    g_free(vdi_inuse);
 
     return found;
 }
diff --git a/block/vdi.c b/block/vdi.c
index 261cf9b..1d5ad2b 100644
--- a/block/vdi.c
+++ b/block/vdi.c
@@ -301,7 +301,7 @@ static int vdi_check(BlockDriverState *bs, BdrvCheckResult *res)
     uint32_t *bmap;
     logout("\n");
 
-    bmap = qemu_malloc(s->header.blocks_in_image * sizeof(uint32_t));
+    bmap = g_malloc(s->header.blocks_in_image * sizeof(uint32_t));
     memset(bmap, 0xff, s->header.blocks_in_image * sizeof(uint32_t));
 
     /* Check block map and value of blocks_allocated. */
@@ -331,7 +331,7 @@ static int vdi_check(BlockDriverState *bs, BdrvCheckResult *res)
         res->corruptions++;
     }
 
-    qemu_free(bmap);
+    g_free(bmap);
 
     return 0;
 }
@@ -443,7 +443,7 @@ static int vdi_open(BlockDriverState *bs, int flags)
     bmap_size = header.blocks_in_image * sizeof(uint32_t);
     bmap_size = (bmap_size + SECTOR_SIZE - 1) / SECTOR_SIZE;
     if (bmap_size > 0) {
-        s->bmap = qemu_malloc(bmap_size * SECTOR_SIZE);
+        s->bmap = g_malloc(bmap_size * SECTOR_SIZE);
     }
     if (bdrv_read(bs->file, s->bmap_sector, (uint8_t *)s->bmap, bmap_size) < 0) {
         goto fail_free_bmap;
@@ -452,7 +452,7 @@ static int vdi_open(BlockDriverState *bs, int flags)
     return 0;
 
  fail_free_bmap:
-    qemu_free(s->bmap);
+    g_free(s->bmap);
 
  fail:
     return -1;
@@ -704,7 +704,7 @@ static void vdi_aio_write_cb(void *opaque, int ret)
             uint64_t offset;
             uint32_t bmap_first;
             uint32_t bmap_last;
-            qemu_free(acb->block_buffer);
+            g_free(acb->block_buffer);
             acb->block_buffer = NULL;
             bmap_first = acb->bmap_first;
             bmap_last = acb->bmap_last;
@@ -760,7 +760,7 @@ static void vdi_aio_write_cb(void *opaque, int ret)
                  (uint64_t)bmap_entry * s->block_sectors;
         block = acb->block_buffer;
         if (block == NULL) {
-            block = qemu_mallocz(s->block_size);
+            block = g_malloc0(s->block_size);
             acb->block_buffer = block;
             acb->bmap_first = block_index;
             assert(!acb->header_modified);
@@ -906,7 +906,7 @@ static int vdi_create(const char *filename, QEMUOptionParameter *options)
 
     bmap = NULL;
     if (bmap_size > 0) {
-        bmap = (uint32_t *)qemu_mallocz(bmap_size);
+        bmap = (uint32_t *)g_malloc0(bmap_size);
     }
     for (i = 0; i < blocks; i++) {
         if (image_type == VDI_TYPE_STATIC) {
@@ -918,7 +918,7 @@ static int vdi_create(const char *filename, QEMUOptionParameter *options)
     if (write(fd, bmap, bmap_size) < 0) {
         result = -errno;
     }
-    qemu_free(bmap);
+    g_free(bmap);
     if (image_type == VDI_TYPE_STATIC) {
         if (ftruncate(fd, sizeof(header) + bmap_size + blocks * block_size)) {
             result = -errno;
diff --git a/block/vmdk.c b/block/vmdk.c
index 37478d2..8da87ac 100644
--- a/block/vmdk.c
+++ b/block/vmdk.c
@@ -167,11 +167,11 @@ static void vmdk_free_extents(BlockDriverState *bs)
     BDRVVmdkState *s = bs->opaque;
 
     for (i = 0; i < s->num_extents; i++) {
-        qemu_free(s->extents[i].l1_table);
-        qemu_free(s->extents[i].l2_cache);
-        qemu_free(s->extents[i].l1_backup_table);
+        g_free(s->extents[i].l1_table);
+        g_free(s->extents[i].l2_cache);
+        g_free(s->extents[i].l1_backup_table);
     }
-    qemu_free(s->extents);
+    g_free(s->extents);
 }
 
 static uint32_t vmdk_read_cid(BlockDriverState *bs, int parent)
@@ -289,7 +289,7 @@ static VmdkExtent *vmdk_add_extent(BlockDriverState *bs,
     VmdkExtent *extent;
     BDRVVmdkState *s = bs->opaque;
 
-    s->extents = qemu_realloc(s->extents,
+    s->extents = g_realloc(s->extents,
                               (s->num_extents + 1) * sizeof(VmdkExtent));
     extent = &s->extents[s->num_extents];
     s->num_extents++;
@@ -321,7 +321,7 @@ static int vmdk_init_tables(BlockDriverState *bs, VmdkExtent *extent)
 
     /* read the L1 table */
     l1_size = extent->l1_size * sizeof(uint32_t);
-    extent->l1_table = qemu_malloc(l1_size);
+    extent->l1_table = g_malloc(l1_size);
     ret = bdrv_pread(extent->file,
                     extent->l1_table_offset,
                     extent->l1_table,
@@ -334,7 +334,7 @@ static int vmdk_init_tables(BlockDriverState *bs, VmdkExtent *extent)
     }
 
     if (extent->l1_backup_table_offset) {
-        extent->l1_backup_table = qemu_malloc(l1_size);
+        extent->l1_backup_table = g_malloc(l1_size);
         ret = bdrv_pread(extent->file,
                         extent->l1_backup_table_offset,
                         extent->l1_backup_table,
@@ -348,12 +348,12 @@ static int vmdk_init_tables(BlockDriverState *bs, VmdkExtent *extent)
     }
 
     extent->l2_cache =
-        qemu_malloc(extent->l2_size * L2_CACHE_SIZE * sizeof(uint32_t));
+        g_malloc(extent->l2_size * L2_CACHE_SIZE * sizeof(uint32_t));
     return 0;
  fail_l1b:
-    qemu_free(extent->l1_backup_table);
+    g_free(extent->l1_backup_table);
  fail_l1:
-    qemu_free(extent->l1_table);
+    g_free(extent->l1_table);
     return ret;
 }
 
@@ -564,7 +564,7 @@ static int vmdk_open_desc_file(BlockDriverState *bs, int flags)
 
     /* try to open parent images, if exist */
     if (vmdk_parent_open(bs)) {
-        qemu_free(s->extents);
+        g_free(s->extents);
         return -EINVAL;
     }
     s->parent_cid = vmdk_read_cid(bs, 1);
diff --git a/block/vpc.c b/block/vpc.c
index fdd5236..cb6c570 100644
--- a/block/vpc.c
+++ b/block/vpc.c
@@ -196,7 +196,7 @@ static int vpc_open(BlockDriverState *bs, int flags)
     s->bitmap_size = ((s->block_size / (8 * 512)) + 511) & ~511;
 
     s->max_table_entries = be32_to_cpu(dyndisk_header->max_table_entries);
-    s->pagetable = qemu_malloc(s->max_table_entries * 4);
+    s->pagetable = g_malloc(s->max_table_entries * 4);
 
     s->bat_offset = be64_to_cpu(dyndisk_header->table_offset);
     if (bdrv_pread(bs->file, s->bat_offset, s->pagetable,
@@ -220,7 +220,7 @@ static int vpc_open(BlockDriverState *bs, int flags)
     s->last_bitmap_offset = (int64_t) -1;
 
 #ifdef CACHE
-    s->pageentry_u8 = qemu_malloc(512);
+    s->pageentry_u8 = g_malloc(512);
     s->pageentry_u32 = s->pageentry_u8;
     s->pageentry_u16 = s->pageentry_u8;
     s->last_pagetable = -1;
@@ -619,9 +619,9 @@ static int vpc_create(const char *filename, QEMUOptionParameter *options)
 static void vpc_close(BlockDriverState *bs)
 {
     BDRVVPCState *s = bs->opaque;
-    qemu_free(s->pagetable);
+    g_free(s->pagetable);
 #ifdef CACHE
-    qemu_free(s->pageentry_u8);
+    g_free(s->pageentry_u8);
 #endif
 }
 
diff --git a/block/vvfat.c b/block/vvfat.c
index fe568fe..d6a07ef 100644
--- a/block/vvfat.c
+++ b/block/vvfat.c
@@ -101,7 +101,7 @@ static inline int array_ensure_allocated(array_t* array, int index)
 {
     if((index + 1) * array->item_size > array->size) {
 	int new_size = (index + 32) * array->item_size;
-	array->pointer = qemu_realloc(array->pointer, new_size);
+	array->pointer = g_realloc(array->pointer, new_size);
 	if (!array->pointer)
 	    return -1;
 	array->size = new_size;
@@ -127,7 +127,7 @@ static inline void* array_get_next(array_t* array) {
 static inline void* array_insert(array_t* array,unsigned int index,unsigned int count) {
     if((array->next+count)*array->item_size>array->size) {
 	int increment=count*array->item_size;
-	array->pointer=qemu_realloc(array->pointer,array->size+increment);
+	array->pointer=g_realloc(array->pointer,array->size+increment);
 	if(!array->pointer)
             return NULL;
 	array->size+=increment;
@@ -159,7 +159,7 @@ static inline int array_roll(array_t* array,int index_to,int index_from,int coun
     is=array->item_size;
     from=array->pointer+index_from*is;
     to=array->pointer+index_to*is;
-    buf=qemu_malloc(is*count);
+    buf=g_malloc(is*count);
     memcpy(buf,from,is*count);
 
     if(index_to<index_from)
@@ -728,7 +728,7 @@ static int read_directory(BDRVVVFATState* s, int mapping_index)
 	if(first_cluster == 0 && (is_dotdot || is_dot))
 	    continue;
 
-	buffer=(char*)qemu_malloc(length);
+	buffer=(char*)g_malloc(length);
 	snprintf(buffer,length,"%s/%s",dirname,entry->d_name);
 
 	if(stat(buffer,&st)<0) {
@@ -850,7 +850,7 @@ static int init_directories(BDRVVVFATState* s,
     memset(&(s->first_sectors[0]),0,0x40*0x200);
 
     s->cluster_size=s->sectors_per_cluster*0x200;
-    s->cluster_buffer=qemu_malloc(s->cluster_size);
+    s->cluster_buffer=g_malloc(s->cluster_size);
 
     /*
      * The formula: sc = spf+1+spf*spc*(512*8/fat_type),
@@ -884,7 +884,7 @@ static int init_directories(BDRVVVFATState* s,
     mapping->dir_index = 0;
     mapping->info.dir.parent_mapping_index = -1;
     mapping->first_mapping_index = -1;
-    mapping->path = qemu_strdup(dirname);
+    mapping->path = g_strdup(dirname);
     i = strlen(mapping->path);
     if (i > 0 && mapping->path[i - 1] == '/')
 	mapping->path[i - 1] = '\0';
@@ -1638,10 +1638,10 @@ static uint32_t get_cluster_count_for_direntry(BDRVVVFATState* s,
 
 	    /* rename */
 	    if (strcmp(basename, basename2))
-		schedule_rename(s, cluster_num, qemu_strdup(path));
+		schedule_rename(s, cluster_num, g_strdup(path));
 	} else if (is_file(direntry))
 	    /* new file */
-	    schedule_new_file(s, qemu_strdup(path), cluster_num);
+	    schedule_new_file(s, g_strdup(path), cluster_num);
 	else {
             abort();
 	    return 0;
@@ -1735,7 +1735,7 @@ static int check_directory_consistency(BDRVVVFATState *s,
 	int cluster_num, const char* path)
 {
     int ret = 0;
-    unsigned char* cluster = qemu_malloc(s->cluster_size);
+    unsigned char* cluster = g_malloc(s->cluster_size);
     direntry_t* direntries = (direntry_t*)cluster;
     mapping_t* mapping = find_mapping_for_cluster(s, cluster_num);
 
@@ -1758,10 +1758,10 @@ static int check_directory_consistency(BDRVVVFATState *s,
 	mapping->mode &= ~MODE_DELETED;
 
 	if (strcmp(basename, basename2))
-	    schedule_rename(s, cluster_num, qemu_strdup(path));
+	    schedule_rename(s, cluster_num, g_strdup(path));
     } else
 	/* new directory */
-	schedule_mkdir(s, cluster_num, qemu_strdup(path));
+	schedule_mkdir(s, cluster_num, g_strdup(path));
 
     lfn_init(&lfn);
     do {
@@ -1876,7 +1876,7 @@ DLOG(checkpoint());
      */
     if (s->fat2 == NULL) {
 	int size = 0x200 * s->sectors_per_fat;
-	s->fat2 = qemu_malloc(size);
+	s->fat2 = g_malloc(size);
 	memcpy(s->fat2, s->fat.pointer, size);
     }
     check = vvfat_read(s->bs,
@@ -2218,7 +2218,7 @@ static int commit_one_file(BDRVVVFATState* s,
     uint32_t first_cluster = c;
     mapping_t* mapping = find_mapping_for_cluster(s, c);
     uint32_t size = filesize_of_direntry(direntry);
-    char* cluster = qemu_malloc(s->cluster_size);
+    char* cluster = g_malloc(s->cluster_size);
     uint32_t i;
     int fd = 0;
 
@@ -2383,7 +2383,7 @@ static int handle_renames_and_mkdirs(BDRVVVFATState* s)
 			    mapping_t* m = find_mapping_for_cluster(s,
 				    begin_of_direntry(d));
 			    int l = strlen(m->path);
-			    char* new_path = qemu_malloc(l + diff + 1);
+			    char* new_path = g_malloc(l + diff + 1);
 
 			    assert(!strncmp(m->path, mapping->path, l2));
 
@@ -2794,7 +2794,7 @@ static int enable_write_target(BDRVVVFATState *s)
 
     array_init(&(s->commits), sizeof(commit_t));
 
-    s->qcow_filename = qemu_malloc(1024);
+    s->qcow_filename = g_malloc(1024);
     get_tmp_filename(s->qcow_filename, 1024);
 
     bdrv_qcow = bdrv_find_format("qcow");
@@ -2822,7 +2822,7 @@ static int enable_write_target(BDRVVVFATState *s)
 
     s->bs->backing_hd = calloc(sizeof(BlockDriverState), 1);
     s->bs->backing_hd->drv = &vvfat_write_target;
-    s->bs->backing_hd->opaque = qemu_malloc(sizeof(void*));
+    s->bs->backing_hd->opaque = g_malloc(sizeof(void*));
     *(void**)s->bs->backing_hd->opaque = s;
 
     return 0;
diff --git a/blockdev.c b/blockdev.c
index a25367a..d272659 100644
--- a/blockdev.c
+++ b/blockdev.c
@@ -182,9 +182,9 @@ static void drive_uninit(DriveInfo *dinfo)
 {
     qemu_opts_del(dinfo->opts);
     bdrv_delete(dinfo->bdrv);
-    qemu_free(dinfo->id);
+    g_free(dinfo->id);
     QTAILQ_REMOVE(&drives, dinfo, next);
-    qemu_free(dinfo);
+    g_free(dinfo);
 }
 
 void drive_put_ref(DriveInfo *dinfo)
@@ -442,12 +442,12 @@ DriveInfo *drive_init(QemuOpts *opts, int default_to_scsi)
 
     /* init */
 
-    dinfo = qemu_mallocz(sizeof(*dinfo));
+    dinfo = g_malloc0(sizeof(*dinfo));
     if ((buf = qemu_opts_id(opts)) != NULL) {
-        dinfo->id = qemu_strdup(buf);
+        dinfo->id = g_strdup(buf);
     } else {
         /* no id supplied -> create one */
-        dinfo->id = qemu_mallocz(32);
+        dinfo->id = g_malloc0(32);
         if (type == IF_IDE || type == IF_SCSI)
             mediastr = (media == MEDIA_CDROM) ? "-cd" : "-hd";
         if (max_devs)
@@ -542,9 +542,9 @@ DriveInfo *drive_init(QemuOpts *opts, int default_to_scsi)
 
 err:
     bdrv_delete(dinfo->bdrv);
-    qemu_free(dinfo->id);
+    g_free(dinfo->id);
     QTAILQ_REMOVE(&drives, dinfo, next);
-    qemu_free(dinfo);
+    g_free(dinfo);
     return NULL;
 }
 
diff --git a/bsd-user/mmap.c b/bsd-user/mmap.c
index 207c774..5d6cffc 100644
--- a/bsd-user/mmap.c
+++ b/bsd-user/mmap.c
@@ -94,7 +94,7 @@ void *qemu_vmalloc(size_t size)
     return p;
 }
 
-void *qemu_malloc(size_t size)
+void *g_malloc(size_t size)
 {
     char * p;
     size += 16;
@@ -104,12 +104,12 @@ void *qemu_malloc(size_t size)
 }
 
 /* We use map, which is always zero initialized.  */
-void * qemu_mallocz(size_t size)
+void * g_malloc0(size_t size)
 {
-    return qemu_malloc(size);
+    return g_malloc(size);
 }
 
-void qemu_free(void *ptr)
+void g_free(void *ptr)
 {
     /* FIXME: We should unmark the reserved pages here.  However this gets
        complicated when one target page spans multiple host pages, so we
@@ -119,18 +119,18 @@ void qemu_free(void *ptr)
     munmap(p, *p);
 }
 
-void *qemu_realloc(void *ptr, size_t size)
+void *g_realloc(void *ptr, size_t size)
 {
     size_t old_size, copy;
     void *new_ptr;
 
     if (!ptr)
-        return qemu_malloc(size);
+        return g_malloc(size);
     old_size = *(size_t *)((char *)ptr - 16);
     copy = old_size < size ? old_size : size;
-    new_ptr = qemu_malloc(size);
+    new_ptr = g_malloc(size);
     memcpy(new_ptr, ptr, copy);
-    qemu_free(ptr);
+    g_free(ptr);
     return new_ptr;
 }
 
diff --git a/bsd-user/syscall.c b/bsd-user/syscall.c
index d4d039a..18b43f1 100644
--- a/bsd-user/syscall.c
+++ b/bsd-user/syscall.c
@@ -231,7 +231,7 @@ static abi_long do_freebsd_sysctl(abi_ulong namep, int32_t namelen, abi_ulong ol
     void *hnamep, *holdp, *hnewp = NULL;
     size_t holdlen;
     abi_ulong oldlen = 0;
-    int32_t *snamep = qemu_malloc(sizeof(int32_t) * namelen), *p, *q, i;
+    int32_t *snamep = g_malloc(sizeof(int32_t) * namelen), *p, *q, i;
     uint32_t kind = 0;
 
     if (oldlenp)
@@ -255,7 +255,7 @@ static abi_long do_freebsd_sysctl(abi_ulong namep, int32_t namelen, abi_ulong ol
     unlock_user(holdp, oldp, holdlen);
     if (hnewp)
         unlock_user(hnewp, newp, 0);
-    qemu_free(snamep);
+    g_free(snamep);
     return ret;
 }
 #endif
diff --git a/bt-host.c b/bt-host.c
index 095254d..df5b7cd 100644
--- a/bt-host.c
+++ b/bt-host.c
@@ -177,7 +177,7 @@ struct HCIInfo *bt_host_hci(const char *id)
     }
 # endif
 
-    s = qemu_mallocz(sizeof(struct bt_host_hci_s));
+    s = g_malloc0(sizeof(struct bt_host_hci_s));
     s->fd = fd;
     s->hci.cmd_send = bt_host_cmd;
     s->hci.sco_send = bt_host_sco;
diff --git a/bt-vhci.c b/bt-vhci.c
index 3c57720..bbc1029 100644
--- a/bt-vhci.c
+++ b/bt-vhci.c
@@ -156,7 +156,7 @@ void bt_vhci_init(struct HCIInfo *info)
         exit(-1);
     }
 
-    s = qemu_mallocz(sizeof(struct bt_vhci_s));
+    s = g_malloc0(sizeof(struct bt_vhci_s));
     s->fd = fd;
     s->info = info ?: qemu_next_hci();
     s->info->opaque = s;
diff --git a/buffered_file.c b/buffered_file.c
index 41b42c3..486af57 100644
--- a/buffered_file.c
+++ b/buffered_file.c
@@ -56,7 +56,7 @@ static void buffered_append(QEMUFileBuffered *s,
 
         s->buffer_capacity += size + 1024;
 
-        tmp = qemu_realloc(s->buffer, s->buffer_capacity);
+        tmp = g_realloc(s->buffer, s->buffer_capacity);
         if (tmp == NULL) {
             fprintf(stderr, "qemu file buffer expansion failed\n");
             exit(1);
@@ -183,8 +183,8 @@ static int buffered_close(void *opaque)
 
     qemu_del_timer(s->timer);
     qemu_free_timer(s->timer);
-    qemu_free(s->buffer);
-    qemu_free(s);
+    g_free(s->buffer);
+    g_free(s);
 
     return ret;
 }
@@ -259,7 +259,7 @@ QEMUFile *qemu_fopen_ops_buffered(void *opaque,
 {
     QEMUFileBuffered *s;
 
-    s = qemu_mallocz(sizeof(*s));
+    s = g_malloc0(sizeof(*s));
 
     s->opaque = opaque;
     s->xfer_limit = bytes_per_sec / 10;
diff --git a/check-qdict.c b/check-qdict.c
index ecc7fd7..5515773 100644
--- a/check-qdict.c
+++ b/check-qdict.c
@@ -56,9 +56,9 @@ START_TEST(qdict_put_obj_test)
 
     // destroy doesn't exit yet
     QDECREF(qi);
-    qemu_free(ent->key);
-    qemu_free(ent);
-    qemu_free(qdict);
+    g_free(ent->key);
+    g_free(ent);
+    g_free(qdict);
 }
 END_TEST
 
diff --git a/check-qfloat.c b/check-qfloat.c
index b71d983..3344057 100644
--- a/check-qfloat.c
+++ b/check-qfloat.c
@@ -33,7 +33,7 @@ START_TEST(qfloat_from_double_test)
     fail_unless(qobject_type(QOBJECT(qf)) == QTYPE_QFLOAT);
 
     // destroy doesn't exit yet
-    qemu_free(qf);
+    g_free(qf);
 }
 END_TEST
 
diff --git a/check-qint.c b/check-qint.c
index f3b0316..3af51f2 100644
--- a/check-qint.c
+++ b/check-qint.c
@@ -32,7 +32,7 @@ START_TEST(qint_from_int_test)
     fail_unless(qobject_type(QOBJECT(qi)) == QTYPE_QINT);
 
     // destroy doesn't exit yet
-    qemu_free(qi);
+    g_free(qi);
 }
 END_TEST
 
diff --git a/check-qlist.c b/check-qlist.c
index 58984cb..ee2454a 100644
--- a/check-qlist.c
+++ b/check-qlist.c
@@ -30,7 +30,7 @@ START_TEST(qlist_new_test)
     fail_unless(qobject_type(QOBJECT(qlist)) == QTYPE_QLIST);
 
     // destroy doesn't exist yet
-    qemu_free(qlist);
+    g_free(qlist);
 }
 END_TEST
 
@@ -51,8 +51,8 @@ START_TEST(qlist_append_test)
 
     // destroy doesn't exist yet
     QDECREF(qi);
-    qemu_free(entry);
-    qemu_free(qlist);
+    g_free(entry);
+    g_free(qlist);
 }
 END_TEST
 
@@ -65,7 +65,7 @@ START_TEST(qobject_to_qlist_test)
     fail_unless(qobject_to_qlist(QOBJECT(qlist)) == qlist);
 
     // destroy doesn't exist yet
-    qemu_free(qlist);
+    g_free(qlist);
 }
 END_TEST
 
diff --git a/check-qstring.c b/check-qstring.c
index c9bafc2..93bd475 100644
--- a/check-qstring.c
+++ b/check-qstring.c
@@ -32,8 +32,8 @@ START_TEST(qstring_from_str_test)
     fail_unless(qobject_type(QOBJECT(qstring)) == QTYPE_QSTRING);
 
     // destroy doesn't exit yet
-    qemu_free(qstring->string);
-    qemu_free(qstring);
+    g_free(qstring->string);
+    g_free(qstring);
 }
 END_TEST
 
diff --git a/console.c b/console.c
index 242086c..ec529ae 100644
--- a/console.c
+++ b/console.c
@@ -516,7 +516,7 @@ static void text_console_resize(TextConsole *s)
     if (s->width < w1)
         w1 = s->width;
 
-    cells = qemu_malloc(s->width * s->total_height * sizeof(TextCell));
+    cells = g_malloc(s->width * s->total_height * sizeof(TextCell));
     for(y = 0; y < s->total_height; y++) {
         c = &cells[y * s->width];
         if (w1 > 0) {
@@ -531,7 +531,7 @@ static void text_console_resize(TextConsole *s)
             c++;
         }
     }
-    qemu_free(s->cells);
+    g_free(s->cells);
     s->cells = cells;
 }
 
@@ -1252,7 +1252,7 @@ static TextConsole *new_console(DisplayState *ds, console_type_t console_type)
 
     if (nb_consoles >= MAX_CONSOLES)
         return NULL;
-    s = qemu_mallocz(sizeof(TextConsole));
+    s = g_malloc0(sizeof(TextConsole));
     if (!active_console || ((active_console->console_type != GRAPHIC_CONSOLE) &&
         (console_type == GRAPHIC_CONSOLE))) {
         active_console = s;
@@ -1276,7 +1276,7 @@ static TextConsole *new_console(DisplayState *ds, console_type_t console_type)
 
 static DisplaySurface* defaultallocator_create_displaysurface(int width, int height)
 {
-    DisplaySurface *surface = (DisplaySurface*) qemu_mallocz(sizeof(DisplaySurface));
+    DisplaySurface *surface = (DisplaySurface*) g_malloc0(sizeof(DisplaySurface));
 
     int linesize = width * 4;
     qemu_alloc_display(surface, width, height, linesize,
@@ -1302,10 +1302,10 @@ void qemu_alloc_display(DisplaySurface *surface, int width, int height,
     surface->linesize = linesize;
     surface->pf = pf;
     if (surface->flags & QEMU_ALLOCATED_FLAG) {
-        data = qemu_realloc(surface->data,
+        data = g_realloc(surface->data,
                             surface->linesize * surface->height);
     } else {
-        data = qemu_malloc(surface->linesize * surface->height);
+        data = g_malloc(surface->linesize * surface->height);
     }
     surface->data = (uint8_t *)data;
     surface->flags = newflags | QEMU_ALLOCATED_FLAG;
@@ -1317,7 +1317,7 @@ void qemu_alloc_display(DisplaySurface *surface, int width, int height,
 DisplaySurface* qemu_create_displaysurface_from(int width, int height, int bpp,
                                               int linesize, uint8_t *data)
 {
-    DisplaySurface *surface = (DisplaySurface*) qemu_mallocz(sizeof(DisplaySurface));
+    DisplaySurface *surface = (DisplaySurface*) g_malloc0(sizeof(DisplaySurface));
 
     surface->width = width;
     surface->height = height;
@@ -1336,8 +1336,8 @@ static void defaultallocator_free_displaysurface(DisplaySurface *surface)
     if (surface == NULL)
         return;
     if (surface->flags & QEMU_ALLOCATED_FLAG)
-        qemu_free(surface->data);
-    qemu_free(surface);
+        g_free(surface->data);
+    g_free(surface);
 }
 
 static struct DisplayAllocator default_allocator = {
@@ -1348,7 +1348,7 @@ static struct DisplayAllocator default_allocator = {
 
 static void dumb_display_init(void)
 {
-    DisplayState *ds = qemu_mallocz(sizeof(DisplayState));
+    DisplayState *ds = g_malloc0(sizeof(DisplayState));
     int width = 640;
     int height = 480;
 
@@ -1403,14 +1403,14 @@ DisplayState *graphic_console_init(vga_hw_update_ptr update,
     TextConsole *s;
     DisplayState *ds;
 
-    ds = (DisplayState *) qemu_mallocz(sizeof(DisplayState));
+    ds = (DisplayState *) g_malloc0(sizeof(DisplayState));
     ds->allocator = &default_allocator; 
     ds->surface = qemu_create_displaysurface(ds, 640, 480);
 
     s = new_console(ds, GRAPHIC_CONSOLE);
     if (s == NULL) {
         qemu_free_displaysurface(ds);
-        qemu_free(ds);
+        g_free(ds);
         return NULL;
     }
     s->hw_update = update;
@@ -1521,7 +1521,7 @@ int text_console_init(QemuOpts *opts, CharDriverState **_chr)
     unsigned width;
     unsigned height;
 
-    chr = qemu_mallocz(sizeof(CharDriverState));
+    chr = g_malloc0(sizeof(CharDriverState));
 
     if (n_text_consoles == 128) {
         fprintf(stderr, "Too many text consoles\n");
diff --git a/coroutine-gthread.c b/coroutine-gthread.c
index f09877e..b00e548 100644
--- a/coroutine-gthread.c
+++ b/coroutine-gthread.c
@@ -71,11 +71,11 @@ Coroutine *qemu_coroutine_new(void)
 {
     CoroutineGThread *co;
 
-    co = qemu_mallocz(sizeof(*co));
+    co = g_malloc0(sizeof(*co));
     co->thread = g_thread_create_full(coroutine_thread, co, 0, TRUE, TRUE,
                                       G_THREAD_PRIORITY_NORMAL, NULL);
     if (!co->thread) {
-        qemu_free(co);
+        g_free(co);
         return NULL;
     }
     return &co->base;
@@ -86,7 +86,7 @@ void qemu_coroutine_delete(Coroutine *co_)
     CoroutineGThread *co = DO_UPCAST(CoroutineGThread, base, co_);
 
     g_thread_join(co->thread);
-    qemu_free(co);
+    g_free(co);
 }
 
 CoroutineAction qemu_coroutine_switch(Coroutine *from_,
@@ -115,7 +115,7 @@ Coroutine *qemu_coroutine_self(void)
     CoroutineGThread *co = g_static_private_get(&coroutine_key);
 
     if (!co) {
-        co = qemu_mallocz(sizeof(*co));
+        co = g_malloc0(sizeof(*co));
         co->runnable = true;
         g_static_private_set(&coroutine_key, co, (GDestroyNotify)qemu_free);
     }
diff --git a/coroutine-ucontext.c b/coroutine-ucontext.c
index 42dc3e2..2b8d3e9 100644
--- a/coroutine-ucontext.c
+++ b/coroutine-ucontext.c
@@ -73,7 +73,7 @@ static CoroutineThreadState *coroutine_get_thread_state(void)
     CoroutineThreadState *s = pthread_getspecific(thread_state_key);
 
     if (!s) {
-        s = qemu_mallocz(sizeof(*s));
+        s = g_malloc0(sizeof(*s));
         s->current = &s->leader.base;
         QLIST_INIT(&s->pool);
         pthread_setspecific(thread_state_key, s);
@@ -88,10 +88,10 @@ static void qemu_coroutine_thread_cleanup(void *opaque)
     Coroutine *tmp;
 
     QLIST_FOREACH_SAFE(co, &s->pool, pool_next, tmp) {
-        qemu_free(DO_UPCAST(CoroutineUContext, base, co)->stack);
-        qemu_free(co);
+        g_free(DO_UPCAST(CoroutineUContext, base, co)->stack);
+        g_free(co);
     }
-    qemu_free(s);
+    g_free(s);
 }
 
 static void __attribute__((constructor)) coroutine_init(void)
@@ -146,8 +146,8 @@ static Coroutine *coroutine_new(void)
         abort();
     }
 
-    co = qemu_mallocz(sizeof(*co));
-    co->stack = qemu_malloc(stack_size);
+    co = g_malloc0(sizeof(*co));
+    co->stack = g_malloc(stack_size);
     co->base.entry_arg = &old_env; /* stash away our jmp_buf */
 
     uc.uc_link = &old_uc;
@@ -194,8 +194,8 @@ void qemu_coroutine_delete(Coroutine *co_)
         return;
     }
 
-    qemu_free(co->stack);
-    qemu_free(co);
+    g_free(co->stack);
+    g_free(co);
 }
 
 CoroutineAction qemu_coroutine_switch(Coroutine *from_, Coroutine *to_,
diff --git a/coroutine-win32.c b/coroutine-win32.c
index 0e29448..4179609 100644
--- a/coroutine-win32.c
+++ b/coroutine-win32.c
@@ -64,7 +64,7 @@ Coroutine *qemu_coroutine_new(void)
     const size_t stack_size = 1 << 20;
     CoroutineWin32 *co;
 
-    co = qemu_mallocz(sizeof(*co));
+    co = g_malloc0(sizeof(*co));
     co->fiber = CreateFiber(stack_size, coroutine_trampoline, &co->base);
     return &co->base;
 }
@@ -74,7 +74,7 @@ void qemu_coroutine_delete(Coroutine *co_)
     CoroutineWin32 *co = DO_UPCAST(CoroutineWin32, base, co_);
 
     DeleteFiber(co->fiber);
-    qemu_free(co);
+    g_free(co);
 }
 
 Coroutine *qemu_coroutine_self(void)
diff --git a/cpus.c b/cpus.c
index 6bf4e3f..c996ac5 100644
--- a/cpus.c
+++ b/cpus.c
@@ -968,8 +968,8 @@ static void qemu_tcg_init_vcpu(void *_env)
 
     /* share a single thread for all cpus with TCG */
     if (!tcg_cpu_thread) {
-        env->thread = qemu_mallocz(sizeof(QemuThread));
-        env->halt_cond = qemu_mallocz(sizeof(QemuCond));
+        env->thread = g_malloc0(sizeof(QemuThread));
+        env->halt_cond = g_malloc0(sizeof(QemuCond));
         qemu_cond_init(env->halt_cond);
         qemu_thread_create(env->thread, qemu_tcg_cpu_thread_fn, env);
         while (env->created == 0) {
@@ -985,8 +985,8 @@ static void qemu_tcg_init_vcpu(void *_env)
 
 static void qemu_kvm_start_vcpu(CPUState *env)
 {
-    env->thread = qemu_mallocz(sizeof(QemuThread));
-    env->halt_cond = qemu_mallocz(sizeof(QemuCond));
+    env->thread = g_malloc0(sizeof(QemuThread));
+    env->halt_cond = g_malloc0(sizeof(QemuCond));
     qemu_cond_init(env->halt_cond);
     qemu_thread_create(env->thread, qemu_kvm_cpu_thread_fn, env);
     while (env->created == 0) {
diff --git a/cris-dis.c b/cris-dis.c
index 5fa67d9..5b8e90b 100644
--- a/cris-dis.c
+++ b/cris-dis.c
@@ -1396,32 +1396,32 @@ get_opcode_entry (unsigned int insn,
   /* Allocate and clear the opcode-table.  */
   if (opc_table == NULL)
     {
-      opc_table = qemu_malloc (65536 * sizeof (opc_table[0]));
+      opc_table = g_malloc (65536 * sizeof (opc_table[0]));
 
       memset (opc_table, 0, 65536 * sizeof (const struct cris_opcode *));
 
       dip_prefixes
-	= qemu_malloc (65536 * sizeof (const struct cris_opcode **));
+	= g_malloc (65536 * sizeof (const struct cris_opcode **));
 
       memset (dip_prefixes, 0, 65536 * sizeof (dip_prefixes[0]));
 
       bdapq_m1_prefixes
-	= qemu_malloc (65536 * sizeof (const struct cris_opcode **));
+	= g_malloc (65536 * sizeof (const struct cris_opcode **));
 
       memset (bdapq_m1_prefixes, 0, 65536 * sizeof (bdapq_m1_prefixes[0]));
 
       bdapq_m2_prefixes
-	= qemu_malloc (65536 * sizeof (const struct cris_opcode **));
+	= g_malloc (65536 * sizeof (const struct cris_opcode **));
 
       memset (bdapq_m2_prefixes, 0, 65536 * sizeof (bdapq_m2_prefixes[0]));
 
       bdapq_m4_prefixes
-	= qemu_malloc (65536 * sizeof (const struct cris_opcode **));
+	= g_malloc (65536 * sizeof (const struct cris_opcode **));
 
       memset (bdapq_m4_prefixes, 0, 65536 * sizeof (bdapq_m4_prefixes[0]));
 
       rest_prefixes
-	= qemu_malloc (65536 * sizeof (const struct cris_opcode **));
+	= g_malloc (65536 * sizeof (const struct cris_opcode **));
 
       memset (rest_prefixes, 0, 65536 * sizeof (rest_prefixes[0]));
     }
diff --git a/cursor.c b/cursor.c
index dfb9eef..efc5917 100644
--- a/cursor.c
+++ b/cursor.c
@@ -98,7 +98,7 @@ QEMUCursor *cursor_alloc(int width, int height)
     QEMUCursor *c;
     int datasize = width * height * sizeof(uint32_t);
 
-    c = qemu_mallocz(sizeof(QEMUCursor) + datasize);
+    c = g_malloc0(sizeof(QEMUCursor) + datasize);
     c->width  = width;
     c->height = height;
     c->refcount = 1;
@@ -117,7 +117,7 @@ void cursor_put(QEMUCursor *c)
     c->refcount--;
     if (c->refcount)
         return;
-    qemu_free(c);
+    g_free(c);
 }
 
 int cursor_get_mono_bpl(QEMUCursor *c)
diff --git a/cutils.c b/cutils.c
index 28049e0..f2bcf20 100644
--- a/cutils.c
+++ b/cutils.c
@@ -136,7 +136,7 @@ int qemu_fdatasync(int fd)
 
 void qemu_iovec_init(QEMUIOVector *qiov, int alloc_hint)
 {
-    qiov->iov = qemu_malloc(alloc_hint * sizeof(struct iovec));
+    qiov->iov = g_malloc(alloc_hint * sizeof(struct iovec));
     qiov->niov = 0;
     qiov->nalloc = alloc_hint;
     qiov->size = 0;
@@ -160,7 +160,7 @@ void qemu_iovec_add(QEMUIOVector *qiov, void *base, size_t len)
 
     if (qiov->niov == qiov->nalloc) {
         qiov->nalloc = 2 * qiov->nalloc + 1;
-        qiov->iov = qemu_realloc(qiov->iov, qiov->nalloc * sizeof(struct iovec));
+        qiov->iov = g_realloc(qiov->iov, qiov->nalloc * sizeof(struct iovec));
     }
     qiov->iov[qiov->niov].iov_base = base;
     qiov->iov[qiov->niov].iov_len = len;
@@ -217,7 +217,7 @@ void qemu_iovec_destroy(QEMUIOVector *qiov)
 {
     assert(qiov->nalloc != -1);
 
-    qemu_free(qiov->iov);
+    g_free(qiov->iov);
 }
 
 void qemu_iovec_reset(QEMUIOVector *qiov)
diff --git a/device_tree.c b/device_tree.c
index f5d5eb1..3a224d1 100644
--- a/device_tree.c
+++ b/device_tree.c
@@ -43,7 +43,7 @@ void *load_device_tree(const char *filename_path, int *sizep)
     /* Expand to 2x size to give enough room for manipulation.  */
     dt_size *= 2;
     /* First allocate space in qemu for device tree */
-    fdt = qemu_mallocz(dt_size);
+    fdt = g_malloc0(dt_size);
 
     dt_file_load_size = load_image(filename_path, fdt);
     if (dt_file_load_size < 0) {
@@ -68,7 +68,7 @@ void *load_device_tree(const char *filename_path, int *sizep)
     return fdt;
 
 fail:
-    qemu_free(fdt);
+    g_free(fdt);
     return NULL;
 }
 
diff --git a/dma-helpers.c b/dma-helpers.c
index ba7f897..4610ea0 100644
--- a/dma-helpers.c
+++ b/dma-helpers.c
@@ -12,7 +12,7 @@
 
 void qemu_sglist_init(QEMUSGList *qsg, int alloc_hint)
 {
-    qsg->sg = qemu_malloc(alloc_hint * sizeof(ScatterGatherEntry));
+    qsg->sg = g_malloc(alloc_hint * sizeof(ScatterGatherEntry));
     qsg->nsg = 0;
     qsg->nalloc = alloc_hint;
     qsg->size = 0;
@@ -23,7 +23,7 @@ void qemu_sglist_add(QEMUSGList *qsg, target_phys_addr_t base,
 {
     if (qsg->nsg == qsg->nalloc) {
         qsg->nalloc = 2 * qsg->nalloc + 1;
-        qsg->sg = qemu_realloc(qsg->sg, qsg->nalloc * sizeof(ScatterGatherEntry));
+        qsg->sg = g_realloc(qsg->sg, qsg->nalloc * sizeof(ScatterGatherEntry));
     }
     qsg->sg[qsg->nsg].base = base;
     qsg->sg[qsg->nsg].len = len;
@@ -33,7 +33,7 @@ void qemu_sglist_add(QEMUSGList *qsg, target_phys_addr_t base,
 
 void qemu_sglist_destroy(QEMUSGList *qsg)
 {
-    qemu_free(qsg->sg);
+    g_free(qsg->sg);
 }
 
 typedef struct {
diff --git a/error.c b/error.c
index 74d7398..b802752 100644
--- a/error.c
+++ b/error.c
@@ -32,7 +32,7 @@ void error_set(Error **errp, const char *fmt, ...)
         return;
     }
 
-    err = qemu_mallocz(sizeof(*err));
+    err = g_malloc0(sizeof(*err));
 
     va_start(ap, fmt);
     err->obj = qobject_to_qdict(qobject_from_jsonv(fmt, &ap));
@@ -52,7 +52,7 @@ const char *error_get_pretty(Error *err)
     if (err->msg == NULL) {
         QString *str;
         str = qerror_format(err->fmt, err->obj);
-        err->msg = qemu_strdup(qstring_get_str(str));
+        err->msg = g_strdup(qstring_get_str(str));
         QDECREF(str);
     }
 
@@ -86,8 +86,8 @@ void error_free(Error *err)
 {
     if (err) {
         QDECREF(err->obj);
-        qemu_free(err->msg);
-        qemu_free(err);
+        g_free(err->msg);
+        g_free(err);
     }
 }
 
@@ -133,7 +133,7 @@ void error_set_qobject(Error **errp, QObject *obj)
     if (errp == NULL) {
         return;
     }
-    err = qemu_mallocz(sizeof(*err));
+    err = g_malloc0(sizeof(*err));
     err->obj = qobject_to_qdict(obj);
     qobject_incref(obj);
 
diff --git a/exec.c b/exec.c
index 63adb18..c1e045d 100644
--- a/exec.c
+++ b/exec.c
@@ -352,7 +352,7 @@ static PageDesc *page_find_alloc(tb_page_addr_t index, int alloc)
     int i;
 
 #if defined(CONFIG_USER_ONLY)
-    /* We can't use qemu_malloc because it may recurse into a locked mutex. */
+    /* We can't use g_malloc because it may recurse into a locked mutex. */
 # define ALLOC(P, SIZE)                                 \
     do {                                                \
         P = mmap(NULL, SIZE, PROT_READ | PROT_WRITE,    \
@@ -360,7 +360,7 @@ static PageDesc *page_find_alloc(tb_page_addr_t index, int alloc)
     } while (0)
 #else
 # define ALLOC(P, SIZE) \
-    do { P = qemu_mallocz(SIZE); } while (0)
+    do { P = g_malloc0(SIZE); } while (0)
 #endif
 
     /* Level 1.  Always allocated.  */
@@ -417,7 +417,7 @@ static PhysPageDesc *phys_page_find_alloc(target_phys_addr_t index, int alloc)
             if (!alloc) {
                 return NULL;
             }
-            *lp = p = qemu_mallocz(sizeof(void *) * L2_SIZE);
+            *lp = p = g_malloc0(sizeof(void *) * L2_SIZE);
         }
         lp = p + ((index >> (i * L2_BITS)) & (L2_SIZE - 1));
     }
@@ -430,7 +430,7 @@ static PhysPageDesc *phys_page_find_alloc(target_phys_addr_t index, int alloc)
             return NULL;
         }
 
-        *lp = pd = qemu_malloc(sizeof(PhysPageDesc) * L2_SIZE);
+        *lp = pd = g_malloc(sizeof(PhysPageDesc) * L2_SIZE);
 
         for (i = 0; i < L2_SIZE; i++) {
             pd[i].phys_offset = IO_MEM_UNASSIGNED;
@@ -558,7 +558,7 @@ static void code_gen_alloc(unsigned long tb_size)
         }
     }
 #else
-    code_gen_buffer = qemu_malloc(code_gen_buffer_size);
+    code_gen_buffer = g_malloc(code_gen_buffer_size);
     map_exec(code_gen_buffer, code_gen_buffer_size);
 #endif
 #endif /* !USE_STATIC_CODE_GEN_BUFFER */
@@ -566,7 +566,7 @@ static void code_gen_alloc(unsigned long tb_size)
     code_gen_buffer_max_size = code_gen_buffer_size -
         (TCG_MAX_OP_SIZE * OPC_BUF_SIZE);
     code_gen_max_blocks = code_gen_buffer_size / CODE_GEN_AVG_BLOCK_SIZE;
-    tbs = qemu_malloc(code_gen_max_blocks * sizeof(TranslationBlock));
+    tbs = g_malloc(code_gen_max_blocks * sizeof(TranslationBlock));
 }
 
 /* Must be called before using the QEMU cpus. 'tb_size' is the size
@@ -701,7 +701,7 @@ void tb_free(TranslationBlock *tb)
 static inline void invalidate_page_bitmap(PageDesc *p)
 {
     if (p->code_bitmap) {
-        qemu_free(p->code_bitmap);
+        g_free(p->code_bitmap);
         p->code_bitmap = NULL;
     }
     p->code_write_count = 0;
@@ -961,7 +961,7 @@ static void build_page_bitmap(PageDesc *p)
     int n, tb_start, tb_end;
     TranslationBlock *tb;
 
-    p->code_bitmap = qemu_mallocz(TARGET_PAGE_SIZE / 8);
+    p->code_bitmap = g_malloc0(TARGET_PAGE_SIZE / 8);
 
     tb = p->first_tb;
     while (tb != NULL) {
@@ -1448,7 +1448,7 @@ int cpu_watchpoint_insert(CPUState *env, target_ulong addr, target_ulong len,
                 TARGET_FMT_lx ", len=" TARGET_FMT_lu "\n", addr, len);
         return -EINVAL;
     }
-    wp = qemu_malloc(sizeof(*wp));
+    wp = g_malloc(sizeof(*wp));
 
     wp->vaddr = addr;
     wp->len_mask = len_mask;
@@ -1491,7 +1491,7 @@ void cpu_watchpoint_remove_by_ref(CPUState *env, CPUWatchpoint *watchpoint)
 
     tlb_flush_page(env, watchpoint->vaddr);
 
-    qemu_free(watchpoint);
+    g_free(watchpoint);
 }
 
 /* Remove all matching watchpoints.  */
@@ -1513,7 +1513,7 @@ int cpu_breakpoint_insert(CPUState *env, target_ulong pc, int flags,
 #if defined(TARGET_HAS_ICE)
     CPUBreakpoint *bp;
 
-    bp = qemu_malloc(sizeof(*bp));
+    bp = g_malloc(sizeof(*bp));
 
     bp->pc = pc;
     bp->flags = flags;
@@ -1560,7 +1560,7 @@ void cpu_breakpoint_remove_by_ref(CPUState *env, CPUBreakpoint *breakpoint)
 
     breakpoint_invalidate(env, breakpoint->pc);
 
-    qemu_free(breakpoint);
+    g_free(breakpoint);
 #endif
 }
 
@@ -2921,13 +2921,13 @@ ram_addr_t qemu_ram_alloc_from_ptr(DeviceState *dev, const char *name,
     RAMBlock *new_block, *block;
 
     size = TARGET_PAGE_ALIGN(size);
-    new_block = qemu_mallocz(sizeof(*new_block));
+    new_block = g_malloc0(sizeof(*new_block));
 
     if (dev && dev->parent_bus && dev->parent_bus->info->get_dev_path) {
         char *id = dev->parent_bus->info->get_dev_path(dev);
         if (id) {
             snprintf(new_block->idstr, sizeof(new_block->idstr), "%s/", id);
-            qemu_free(id);
+            g_free(id);
         }
     }
     pstrcat(new_block->idstr, sizeof(new_block->idstr), name);
@@ -2984,7 +2984,7 @@ ram_addr_t qemu_ram_alloc_from_ptr(DeviceState *dev, const char *name,
 
     QLIST_INSERT_HEAD(&ram_list.blocks, new_block, next);
 
-    ram_list.phys_dirty = qemu_realloc(ram_list.phys_dirty,
+    ram_list.phys_dirty = g_realloc(ram_list.phys_dirty,
                                        last_ram_offset() >> TARGET_PAGE_BITS);
     memset(ram_list.phys_dirty + (new_block->offset >> TARGET_PAGE_BITS),
            0xff, size >> TARGET_PAGE_BITS);
@@ -3007,7 +3007,7 @@ void qemu_ram_free_from_ptr(ram_addr_t addr)
     QLIST_FOREACH(block, &ram_list.blocks, next) {
         if (addr == block->offset) {
             QLIST_REMOVE(block, next);
-            qemu_free(block);
+            g_free(block);
             return;
         }
     }
@@ -3044,7 +3044,7 @@ void qemu_ram_free(ram_addr_t addr)
                 }
 #endif
             }
-            qemu_free(block);
+            g_free(block);
             return;
         }
     }
@@ -3602,7 +3602,7 @@ static subpage_t *subpage_init (target_phys_addr_t base, ram_addr_t *phys,
     subpage_t *mmio;
     int subpage_memory;
 
-    mmio = qemu_mallocz(sizeof(subpage_t));
+    mmio = g_malloc0(sizeof(subpage_t));
 
     mmio->base = base;
     subpage_memory = cpu_register_io_memory(subpage_read, subpage_write, mmio,
@@ -3708,7 +3708,7 @@ static CPUWriteMemoryFunc * const swapendian_writefn[3]={
 
 static void swapendian_init(int io_index)
 {
-    SwapEndianContainer *c = qemu_malloc(sizeof(SwapEndianContainer));
+    SwapEndianContainer *c = g_malloc(sizeof(SwapEndianContainer));
     int i;
 
     /* Swap mmio for big endian targets */
@@ -3726,7 +3726,7 @@ static void swapendian_init(int io_index)
 static void swapendian_del(int io_index)
 {
     if (io_mem_read[io_index][0] == swapendian_readfn[0]) {
-        qemu_free(io_mem_opaque[io_index]);
+        g_free(io_mem_opaque[io_index]);
     }
 }
 
@@ -3828,11 +3828,11 @@ static void io_mem_init(void)
 
 static void memory_map_init(void)
 {
-    system_memory = qemu_malloc(sizeof(*system_memory));
+    system_memory = g_malloc(sizeof(*system_memory));
     memory_region_init(system_memory, "system", INT64_MAX);
     set_system_memory_map(system_memory);
 
-    system_io = qemu_malloc(sizeof(*system_io));
+    system_io = g_malloc(sizeof(*system_io));
     memory_region_init(system_io, "io", 65536);
     set_system_io_map(system_io);
 }
@@ -4048,7 +4048,7 @@ static QLIST_HEAD(map_client_list, MapClient) map_client_list
 
 void *cpu_register_map_client(void *opaque, void (*callback)(void *opaque))
 {
-    MapClient *client = qemu_malloc(sizeof(*client));
+    MapClient *client = g_malloc(sizeof(*client));
 
     client->opaque = opaque;
     client->callback = callback;
@@ -4061,7 +4061,7 @@ void cpu_unregister_map_client(void *_client)
     MapClient *client = (MapClient *)_client;
 
     QLIST_REMOVE(client, link);
-    qemu_free(client);
+    g_free(client);
 }
 
 static void cpu_notify_map_clients(void)
diff --git a/fsdev/qemu-fsdev.c b/fsdev/qemu-fsdev.c
index 0b33290..336d7e4 100644
--- a/fsdev/qemu-fsdev.c
+++ b/fsdev/qemu-fsdev.c
@@ -65,11 +65,11 @@ int qemu_fsdev_add(QemuOpts *opts)
         return -1;
     }
 
-    fsle = qemu_malloc(sizeof(*fsle));
+    fsle = g_malloc(sizeof(*fsle));
 
-    fsle->fse.fsdev_id = qemu_strdup(fsdev_id);
-    fsle->fse.path = qemu_strdup(path);
-    fsle->fse.security_model = qemu_strdup(sec_model);
+    fsle->fse.fsdev_id = g_strdup(fsdev_id);
+    fsle->fse.path = g_strdup(path);
+    fsle->fse.security_model = g_strdup(sec_model);
     fsle->fse.ops = FsTypes[i].ops;
 
     QTAILQ_INSERT_TAIL(&fstype_entries, fsle, next);
diff --git a/gdbstub.c b/gdbstub.c
index 27b0cfa..2f0206d 100644
--- a/gdbstub.c
+++ b/gdbstub.c
@@ -1668,7 +1668,7 @@ void gdb_register_coprocessor(CPUState * env,
     GDBRegisterState **p;
     static int last_reg = NUM_CORE_REGS;
 
-    s = (GDBRegisterState *)qemu_mallocz(sizeof(GDBRegisterState));
+    s = (GDBRegisterState *)g_malloc0(sizeof(GDBRegisterState));
     s->base_reg = last_reg;
     s->num_regs = num_regs;
     s->get_reg = get_reg;
@@ -2606,7 +2606,7 @@ static void gdb_accept(void)
     val = 1;
     setsockopt(fd, IPPROTO_TCP, TCP_NODELAY, (char *)&val, sizeof(val));
 
-    s = qemu_mallocz(sizeof(GDBState));
+    s = g_malloc0(sizeof(GDBState));
     s->c_cpu = first_cpu;
     s->g_cpu = first_cpu;
     s->fd = fd;
@@ -2774,13 +2774,13 @@ int gdbserver_start(const char *device)
 
     s = gdbserver_state;
     if (!s) {
-        s = qemu_mallocz(sizeof(GDBState));
+        s = g_malloc0(sizeof(GDBState));
         gdbserver_state = s;
 
         qemu_add_vm_change_state_handler(gdb_vm_state_change, NULL);
 
         /* Initialize a monitor terminal for gdb */
-        mon_chr = qemu_mallocz(sizeof(*mon_chr));
+        mon_chr = g_malloc0(sizeof(*mon_chr));
         mon_chr->chr_write = gdb_monitor_write;
         monitor_init(mon_chr, 0);
     } else {
diff --git a/hw/9pfs/cofs.c b/hw/9pfs/cofs.c
index 473ce53..1f10632 100644
--- a/hw/9pfs/cofs.c
+++ b/hw/9pfs/cofs.c
@@ -22,7 +22,7 @@ int v9fs_co_readlink(V9fsState *s, V9fsString *path, V9fsString *buf)
     int err;
     ssize_t len;
 
-    buf->data = qemu_malloc(PATH_MAX);
+    buf->data = g_malloc(PATH_MAX);
     v9fs_co_run_in_worker(
         {
             len = s->ops->readlink(&s->ctx, path->data,
@@ -36,7 +36,7 @@ int v9fs_co_readlink(V9fsState *s, V9fsString *path, V9fsString *buf)
             }
         });
     if (err) {
-        qemu_free(buf->data);
+        g_free(buf->data);
         buf->data = NULL;
         buf->size = 0;
     }
diff --git a/hw/9pfs/virtio-9p-device.c b/hw/9pfs/virtio-9p-device.c
index f4bf471..9466002 100644
--- a/hw/9pfs/virtio-9p-device.c
+++ b/hw/9pfs/virtio-9p-device.c
@@ -36,12 +36,12 @@ static void virtio_9p_get_config(VirtIODevice *vdev, uint8_t *config)
     struct virtio_9p_config *cfg;
     V9fsState *s = to_virtio_9p(vdev);
 
-    cfg = qemu_mallocz(sizeof(struct virtio_9p_config) +
+    cfg = g_malloc0(sizeof(struct virtio_9p_config) +
                         s->tag_len);
     stw_raw(&cfg->tag_len, s->tag_len);
     memcpy(cfg->tag, s->tag, s->tag_len);
     memcpy(config, cfg, s->config_size);
-    qemu_free(cfg);
+    g_free(cfg);
 }
 
 VirtIODevice *virtio_9p_init(DeviceState *dev, V9fsConf *conf)
@@ -114,13 +114,13 @@ VirtIODevice *virtio_9p_init(DeviceState *dev, V9fsConf *conf)
         exit(1);
     }
 
-    s->ctx.fs_root = qemu_strdup(fse->path);
+    s->ctx.fs_root = g_strdup(fse->path);
     len = strlen(conf->tag);
     if (len > MAX_TAG_LEN) {
         len = MAX_TAG_LEN;
     }
     /* s->tag is non-NULL terminated string */
-    s->tag = qemu_malloc(len);
+    s->tag = g_malloc(len);
     memcpy(s->tag, conf->tag, len);
     s->tag_len = len;
     s->ctx.uid = -1;
diff --git a/hw/9pfs/virtio-9p-xattr.c b/hw/9pfs/virtio-9p-xattr.c
index bde0b7f..7f08f6e 100644
--- a/hw/9pfs/virtio-9p-xattr.c
+++ b/hw/9pfs/virtio-9p-xattr.c
@@ -79,7 +79,7 @@ ssize_t v9fs_list_xattr(FsContext *ctx, const char *path,
     }
 
     /* Now fetch the xattr and find the actual size */
-    orig_value = qemu_malloc(xattr_len);
+    orig_value = g_malloc(xattr_len);
     xattr_len = llistxattr(rpath(ctx, path, buffer), orig_value, xattr_len);
 
     /* store the orig pointer */
@@ -111,7 +111,7 @@ next_entry:
     }
 
 err_out:
-    qemu_free(orig_value_start);
+    g_free(orig_value_start);
     return size;
 }
 
diff --git a/hw/9pfs/virtio-9p.c b/hw/9pfs/virtio-9p.c
index f2193d6..eb33636 100644
--- a/hw/9pfs/virtio-9p.c
+++ b/hw/9pfs/virtio-9p.c
@@ -239,7 +239,7 @@ static void v9fs_string_init(V9fsString *str)
 
 static void v9fs_string_free(V9fsString *str)
 {
-    qemu_free(str->data);
+    g_free(str->data);
     str->data = NULL;
     str->size = 0;
 }
@@ -338,7 +338,7 @@ v9fs_string_alloc_printf(char **strp, const char *fmt, va_list ap)
     }
 
 alloc_print:
-    *strp = qemu_malloc((len + 1) * sizeof(**strp));
+    *strp = g_malloc((len + 1) * sizeof(**strp));
 
     return vsprintf(*strp, fmt, ap);
 }
@@ -408,7 +408,7 @@ static V9fsFidState *alloc_fid(V9fsState *s, int32_t fid)
         return NULL;
     }
 
-    f = qemu_mallocz(sizeof(V9fsFidState));
+    f = g_malloc0(sizeof(V9fsFidState));
 
     f->fid = fid;
     f->fid_type = P9_FID_NONE;
@@ -448,7 +448,7 @@ free_out:
     v9fs_string_free(&fidp->fs.xattr.name);
 free_value:
     if (fidp->fs.xattr.value) {
-        qemu_free(fidp->fs.xattr.value);
+        g_free(fidp->fs.xattr.value);
     }
     return retval;
 }
@@ -479,7 +479,7 @@ static int free_fid(V9fsState *s, int32_t fid)
         retval = v9fs_xattr_fid_clunk(s, fidp);
     }
     v9fs_string_free(&fidp->path);
-    qemu_free(fidp);
+    g_free(fidp);
 
     return retval;
 }
@@ -685,7 +685,7 @@ static size_t pdu_unmarshal(V9fsPDU *pdu, size_t offset, const char *fmt, ...)
             V9fsString *str = va_arg(ap, V9fsString *);
             offset += pdu_unmarshal(pdu, offset, "w", &str->size);
             /* FIXME: sanity check str->size */
-            str->data = qemu_malloc(str->size + 1);
+            str->data = g_malloc(str->size + 1);
             offset += pdu_unpack(str->data, pdu, offset, str->size);
             str->data[str->size] = 0;
             break;
@@ -1209,7 +1209,7 @@ static void v9fs_stat_post_lstat(V9fsState *s, V9fsStatState *vs, int err)
 out:
     complete_pdu(s, vs->pdu, err);
     v9fs_stat_free(&vs->v9stat);
-    qemu_free(vs);
+    g_free(vs);
 }
 
 static void v9fs_stat(void *opaque)
@@ -1220,7 +1220,7 @@ static void v9fs_stat(void *opaque)
     V9fsStatState *vs;
     ssize_t err = 0;
 
-    vs = qemu_malloc(sizeof(*vs));
+    vs = g_malloc(sizeof(*vs));
     vs->pdu = pdu;
     vs->offset = 7;
 
@@ -1241,7 +1241,7 @@ static void v9fs_stat(void *opaque)
 out:
     complete_pdu(s, vs->pdu, err);
     v9fs_stat_free(&vs->v9stat);
-    qemu_free(vs);
+    g_free(vs);
 }
 
 static void v9fs_getattr(void *opaque)
@@ -1379,8 +1379,8 @@ static void v9fs_walk_complete(V9fsState *s, V9fsWalkState *vs, int err)
             v9fs_string_free(&vs->wnames[vs->name_idx]);
         }
 
-        qemu_free(vs->wnames);
-        qemu_free(vs->qids);
+        g_free(vs->wnames);
+        g_free(vs->qids);
     }
 }
 
@@ -1463,7 +1463,7 @@ static void v9fs_walk(void *opaque)
     int err = 0;
     int i;
 
-    vs = qemu_malloc(sizeof(*vs));
+    vs = g_malloc(sizeof(*vs));
     vs->pdu = pdu;
     vs->wnames = NULL;
     vs->qids = NULL;
@@ -1473,9 +1473,9 @@ static void v9fs_walk(void *opaque)
                                             &newfid, &vs->nwnames);
 
     if (vs->nwnames && vs->nwnames <= P9_MAXWELEM) {
-        vs->wnames = qemu_mallocz(sizeof(vs->wnames[0]) * vs->nwnames);
+        vs->wnames = g_malloc0(sizeof(vs->wnames[0]) * vs->nwnames);
 
-        vs->qids = qemu_mallocz(sizeof(vs->qids[0]) * vs->nwnames);
+        vs->qids = g_malloc0(sizeof(vs->qids[0]) * vs->nwnames);
 
         for (i = 0; i < vs->nwnames; i++) {
             vs->offset += pdu_unmarshal(vs->pdu, vs->offset, "s",
@@ -1568,7 +1568,7 @@ static void v9fs_open_post_opendir(V9fsState *s, V9fsOpenState *vs, int err)
     err = vs->offset;
 out:
     complete_pdu(s, vs->pdu, err);
-    qemu_free(vs);
+    g_free(vs);
 
 }
 
@@ -1578,7 +1578,7 @@ static void v9fs_open_post_getiounit(V9fsState *s, V9fsOpenState *vs)
     vs->offset += pdu_marshal(vs->pdu, vs->offset, "Qd", &vs->qid, vs->iounit);
     err = vs->offset;
     complete_pdu(s, vs->pdu, err);
-    qemu_free(vs);
+    g_free(vs);
 }
 
 static void v9fs_open_post_open(V9fsState *s, V9fsOpenState *vs, int err)
@@ -1593,7 +1593,7 @@ static void v9fs_open_post_open(V9fsState *s, V9fsOpenState *vs, int err)
     return;
 out:
     complete_pdu(s, vs->pdu, err);
-    qemu_free(vs);
+    g_free(vs);
 }
 
 static void v9fs_open_post_lstat(V9fsState *s, V9fsOpenState *vs, int err)
@@ -1625,7 +1625,7 @@ static void v9fs_open_post_lstat(V9fsState *s, V9fsOpenState *vs, int err)
     return;
 out:
     complete_pdu(s, vs->pdu, err);
-    qemu_free(vs);
+    g_free(vs);
 }
 
 static void v9fs_open(void *opaque)
@@ -1636,7 +1636,7 @@ static void v9fs_open(void *opaque)
     V9fsOpenState *vs;
     ssize_t err = 0;
 
-    vs = qemu_malloc(sizeof(*vs));
+    vs = g_malloc(sizeof(*vs));
     vs->pdu = pdu;
     vs->offset = 7;
     vs->mode = 0;
@@ -1661,7 +1661,7 @@ static void v9fs_open(void *opaque)
     return;
 out:
     complete_pdu(s, pdu, err);
-    qemu_free(vs);
+    g_free(vs);
 }
 
 static void v9fs_post_lcreate(V9fsState *s, V9fsLcreateState *vs, int err)
@@ -1683,7 +1683,7 @@ static void v9fs_post_lcreate(V9fsState *s, V9fsLcreateState *vs, int err)
     complete_pdu(s, vs->pdu, err);
     v9fs_string_free(&vs->name);
     v9fs_string_free(&vs->fullname);
-    qemu_free(vs);
+    g_free(vs);
 }
 
 static void v9fs_lcreate_post_get_iounit(V9fsState *s, V9fsLcreateState *vs,
@@ -1724,7 +1724,7 @@ static void v9fs_lcreate(void *opaque)
     V9fsLcreateState *vs;
     ssize_t err = 0;
 
-    vs = qemu_malloc(sizeof(*vs));
+    vs = g_malloc(sizeof(*vs));
     vs->pdu = pdu;
     vs->offset = 7;
 
@@ -1753,7 +1753,7 @@ static void v9fs_lcreate(void *opaque)
 out:
     complete_pdu(s, vs->pdu, err);
     v9fs_string_free(&vs->name);
-    qemu_free(vs);
+    g_free(vs);
 }
 
 static void v9fs_post_do_fsync(V9fsState *s, V9fsPDU *pdu, int err)
@@ -1820,7 +1820,7 @@ out:
     complete_pdu(s, vs->pdu, err);
     v9fs_stat_free(&vs->v9stat);
     v9fs_string_free(&vs->name);
-    qemu_free(vs);
+    g_free(vs);
     return;
 }
 
@@ -1874,7 +1874,7 @@ static void v9fs_read_post_readdir(V9fsState *s, V9fsReadState *vs, ssize_t err)
     vs->offset += vs->count;
     err = vs->offset;
     complete_pdu(s, vs->pdu, err);
-    qemu_free(vs);
+    g_free(vs);
     return;
 }
 
@@ -1925,7 +1925,7 @@ static void v9fs_read_post_preadv(V9fsState *s, V9fsReadState *vs, ssize_t err)
 
 out:
     complete_pdu(s, vs->pdu, err);
-    qemu_free(vs);
+    g_free(vs);
 }
 
 static void v9fs_xattr_read(V9fsState *s, V9fsReadState *vs)
@@ -1950,7 +1950,7 @@ static void v9fs_xattr_read(V9fsState *s, V9fsReadState *vs)
                            read_count);
     err = vs->offset;
     complete_pdu(s, vs->pdu, err);
-    qemu_free(vs);
+    g_free(vs);
 }
 
 static void v9fs_read(void *opaque)
@@ -1961,7 +1961,7 @@ static void v9fs_read(void *opaque)
     V9fsReadState *vs;
     ssize_t err = 0;
 
-    vs = qemu_malloc(sizeof(*vs));
+    vs = g_malloc(sizeof(*vs));
     vs->pdu = pdu;
     vs->offset = 7;
     vs->total = 0;
@@ -2006,7 +2006,7 @@ static void v9fs_read(void *opaque)
     }
 out:
     complete_pdu(s, pdu, err);
-    qemu_free(vs);
+    g_free(vs);
 }
 
 static size_t v9fs_readdir_data_size(V9fsString *name)
@@ -2138,7 +2138,7 @@ static void v9fs_write_post_pwritev(V9fsState *s, V9fsWriteState *vs,
     err = vs->offset;
 out:
     complete_pdu(s, vs->pdu, err);
-    qemu_free(vs);
+    g_free(vs);
 }
 
 static void v9fs_xattr_write(V9fsState *s, V9fsWriteState *vs)
@@ -2180,7 +2180,7 @@ static void v9fs_xattr_write(V9fsState *s, V9fsWriteState *vs)
     }
 out:
     complete_pdu(s, vs->pdu, err);
-    qemu_free(vs);
+    g_free(vs);
 }
 
 static void v9fs_write(void *opaque)
@@ -2191,7 +2191,7 @@ static void v9fs_write(void *opaque)
     V9fsWriteState *vs;
     ssize_t err;
 
-    vs = qemu_malloc(sizeof(*vs));
+    vs = g_malloc(sizeof(*vs));
 
     vs->pdu = pdu;
     vs->offset = 7;
@@ -2235,7 +2235,7 @@ static void v9fs_write(void *opaque)
     return;
 out:
     complete_pdu(s, vs->pdu, err);
-    qemu_free(vs);
+    g_free(vs);
 }
 
 static void v9fs_create_post_getiounit(V9fsState *s, V9fsCreateState *vs)
@@ -2251,7 +2251,7 @@ static void v9fs_create_post_getiounit(V9fsState *s, V9fsCreateState *vs)
     v9fs_string_free(&vs->name);
     v9fs_string_free(&vs->extension);
     v9fs_string_free(&vs->fullname);
-    qemu_free(vs);
+    g_free(vs);
 }
 
 static void v9fs_post_create(V9fsState *s, V9fsCreateState *vs, int err)
@@ -2266,7 +2266,7 @@ static void v9fs_post_create(V9fsState *s, V9fsCreateState *vs, int err)
     v9fs_string_free(&vs->name);
     v9fs_string_free(&vs->extension);
     v9fs_string_free(&vs->fullname);
-    qemu_free(vs);
+    g_free(vs);
 }
 
 static void v9fs_create_post_perms(V9fsState *s, V9fsCreateState *vs, int err)
@@ -2426,7 +2426,7 @@ static void v9fs_create(void *opaque)
     V9fsCreateState *vs;
     int err = 0;
 
-    vs = qemu_malloc(sizeof(*vs));
+    vs = g_malloc(sizeof(*vs));
     vs->pdu = pdu;
     vs->offset = 7;
 
@@ -2452,7 +2452,7 @@ out:
     complete_pdu(s, vs->pdu, err);
     v9fs_string_free(&vs->name);
     v9fs_string_free(&vs->extension);
-    qemu_free(vs);
+    g_free(vs);
 }
 
 static void v9fs_post_symlink(V9fsState *s, V9fsSymlinkState *vs, int err)
@@ -2468,7 +2468,7 @@ static void v9fs_post_symlink(V9fsState *s, V9fsSymlinkState *vs, int err)
     v9fs_string_free(&vs->name);
     v9fs_string_free(&vs->symname);
     v9fs_string_free(&vs->fullname);
-    qemu_free(vs);
+    g_free(vs);
 }
 
 static void v9fs_symlink_post_do_symlink(V9fsState *s, V9fsSymlinkState *vs,
@@ -2491,7 +2491,7 @@ static void v9fs_symlink(void *opaque)
     int err = 0;
     gid_t gid;
 
-    vs = qemu_malloc(sizeof(*vs));
+    vs = g_malloc(sizeof(*vs));
     vs->pdu = pdu;
     vs->offset = 7;
 
@@ -2517,7 +2517,7 @@ out:
     complete_pdu(s, vs->pdu, err);
     v9fs_string_free(&vs->name);
     v9fs_string_free(&vs->symname);
-    qemu_free(vs);
+    g_free(vs);
 }
 
 static void v9fs_flush(void *opaque)
@@ -2605,7 +2605,7 @@ static void v9fs_wstat_post_truncate(V9fsState *s, V9fsWstatState *vs, int err)
 out:
     v9fs_stat_free(&vs->v9stat);
     complete_pdu(s, vs->pdu, err);
-    qemu_free(vs);
+    g_free(vs);
 }
 
 static void v9fs_wstat_post_rename(V9fsState *s, V9fsWstatState *vs, int err)
@@ -2624,7 +2624,7 @@ static void v9fs_wstat_post_rename(V9fsState *s, V9fsWstatState *vs, int err)
 out:
     v9fs_stat_free(&vs->v9stat);
     complete_pdu(s, vs->pdu, err);
-    qemu_free(vs);
+    g_free(vs);
 }
 
 static int v9fs_complete_rename(V9fsState *s, V9fsFidState *fidp,
@@ -2643,7 +2643,7 @@ static int v9fs_complete_rename(V9fsState *s, V9fsFidState *fidp,
         }
         BUG_ON(dirfidp->fid_type != P9_FID_NONE);
 
-        new_name = qemu_mallocz(dirfidp->path.size + name->size + 2);
+        new_name = g_malloc0(dirfidp->path.size + name->size + 2);
 
         strcpy(new_name, dirfidp->path.data);
         strcat(new_name, "/");
@@ -2656,7 +2656,7 @@ static int v9fs_complete_rename(V9fsState *s, V9fsFidState *fidp,
         } else {
             end = old_name;
         }
-        new_name = qemu_mallocz(end - old_name + name->size + 1);
+        new_name = g_malloc0(end - old_name + name->size + 1);
 
         strncat(new_name, old_name, end - old_name);
         strncat(new_name + (end - old_name), name->data, name->size);
@@ -2710,7 +2710,7 @@ static void v9fs_wstat_post_chown(V9fsState *s, V9fsWstatState *vs, int err)
 out:
     v9fs_stat_free(&vs->v9stat);
     complete_pdu(s, vs->pdu, err);
-    qemu_free(vs);
+    g_free(vs);
 }
 
 static void v9fs_rename(void *opaque)
@@ -2760,7 +2760,7 @@ static void v9fs_wstat_post_utime(V9fsState *s, V9fsWstatState *vs, int err)
 out:
     v9fs_stat_free(&vs->v9stat);
     complete_pdu(s, vs->pdu, err);
-    qemu_free(vs);
+    g_free(vs);
 }
 
 static void v9fs_wstat_post_chmod(V9fsState *s, V9fsWstatState *vs, int err)
@@ -2795,7 +2795,7 @@ static void v9fs_wstat_post_chmod(V9fsState *s, V9fsWstatState *vs, int err)
 out:
     v9fs_stat_free(&vs->v9stat);
     complete_pdu(s, vs->pdu, err);
-    qemu_free(vs);
+    g_free(vs);
 }
 
 static void v9fs_wstat_post_fsync(V9fsState *s, V9fsWstatState *vs, int err)
@@ -2805,7 +2805,7 @@ static void v9fs_wstat_post_fsync(V9fsState *s, V9fsWstatState *vs, int err)
     }
     v9fs_stat_free(&vs->v9stat);
     complete_pdu(s, vs->pdu, err);
-    qemu_free(vs);
+    g_free(vs);
 }
 
 static void v9fs_wstat_post_lstat(V9fsState *s, V9fsWstatState *vs, int err)
@@ -2836,7 +2836,7 @@ static void v9fs_wstat_post_lstat(V9fsState *s, V9fsWstatState *vs, int err)
 out:
     v9fs_stat_free(&vs->v9stat);
     complete_pdu(s, vs->pdu, err);
-    qemu_free(vs);
+    g_free(vs);
 }
 
 static void v9fs_wstat(void *opaque)
@@ -2847,7 +2847,7 @@ static void v9fs_wstat(void *opaque)
     V9fsWstatState *vs;
     int err = 0;
 
-    vs = qemu_malloc(sizeof(*vs));
+    vs = g_malloc(sizeof(*vs));
     vs->pdu = pdu;
     vs->offset = 7;
 
@@ -2878,7 +2878,7 @@ static void v9fs_wstat(void *opaque)
 out:
     v9fs_stat_free(&vs->v9stat);
     complete_pdu(s, vs->pdu, err);
-    qemu_free(vs);
+    g_free(vs);
 }
 
 static int v9fs_fill_statfs(V9fsState *s, V9fsPDU *pdu, struct statfs *stbuf)
@@ -3014,11 +3014,11 @@ static void v9fs_lock(void *opaque)
     int32_t fid, err = 0;
     V9fsLockState *vs;
 
-    vs = qemu_mallocz(sizeof(*vs));
+    vs = g_malloc0(sizeof(*vs));
     vs->pdu = pdu;
     vs->offset = 7;
 
-    vs->flock = qemu_malloc(sizeof(*vs->flock));
+    vs->flock = g_malloc(sizeof(*vs->flock));
     pdu_unmarshal(vs->pdu, vs->offset, "dbdqqds", &fid, &vs->flock->type,
                 &vs->flock->flags, &vs->flock->start, &vs->flock->length,
                             &vs->flock->proc_id, &vs->flock->client_id);
@@ -3045,8 +3045,8 @@ static void v9fs_lock(void *opaque)
 out:
     vs->offset += pdu_marshal(vs->pdu, vs->offset, "b", vs->status);
     complete_pdu(s, vs->pdu, err);
-    qemu_free(vs->flock);
-    qemu_free(vs);
+    g_free(vs->flock);
+    g_free(vs);
 }
 
 /*
@@ -3061,11 +3061,11 @@ static void v9fs_getlock(void *opaque)
     int32_t fid, err = 0;
     V9fsGetlockState *vs;
 
-    vs = qemu_mallocz(sizeof(*vs));
+    vs = g_malloc0(sizeof(*vs));
     vs->pdu = pdu;
     vs->offset = 7;
 
-    vs->glock = qemu_malloc(sizeof(*vs->glock));
+    vs->glock = g_malloc(sizeof(*vs->glock));
     pdu_unmarshal(vs->pdu, vs->offset, "dbqqds", &fid, &vs->glock->type,
                 &vs->glock->start, &vs->glock->length, &vs->glock->proc_id,
 		&vs->glock->client_id);
@@ -3087,8 +3087,8 @@ static void v9fs_getlock(void *opaque)
 		&vs->glock->client_id);
 out:
     complete_pdu(s, vs->pdu, err);
-    qemu_free(vs->glock);
-    qemu_free(vs);
+    g_free(vs->glock);
+    g_free(vs);
 }
 
 static void v9fs_mkdir(void *opaque)
@@ -3171,7 +3171,7 @@ static void v9fs_xattrwalk(void *opaque)
         xattr_fidp->fid_type = P9_FID_XATTR;
         xattr_fidp->fs.xattr.copied_len = -1;
         if (size) {
-            xattr_fidp->fs.xattr.value = qemu_malloc(size);
+            xattr_fidp->fs.xattr.value = g_malloc(size);
             err = v9fs_co_llistxattr(s, &xattr_fidp->path,
                                      xattr_fidp->fs.xattr.value,
                                      xattr_fidp->fs.xattr.len);
@@ -3201,7 +3201,7 @@ static void v9fs_xattrwalk(void *opaque)
         xattr_fidp->fid_type = P9_FID_XATTR;
         xattr_fidp->fs.xattr.copied_len = -1;
         if (size) {
-            xattr_fidp->fs.xattr.value = qemu_malloc(size);
+            xattr_fidp->fs.xattr.value = g_malloc(size);
             err = v9fs_co_lgetxattr(s, &xattr_fidp->path,
                                     &name, xattr_fidp->fs.xattr.value,
                                     xattr_fidp->fs.xattr.len);
@@ -3248,7 +3248,7 @@ static void v9fs_xattrcreate(void *opaque)
     v9fs_string_init(&xattr_fidp->fs.xattr.name);
     v9fs_string_copy(&xattr_fidp->fs.xattr.name, &name);
     if (size) {
-        xattr_fidp->fs.xattr.value = qemu_malloc(size);
+        xattr_fidp->fs.xattr.value = g_malloc(size);
     } else {
         xattr_fidp->fs.xattr.value = NULL;
     }
diff --git a/hw/acpi.c b/hw/acpi.c
index 79ec66c..d04b965 100644
--- a/hw/acpi.c
+++ b/hw/acpi.c
@@ -100,13 +100,13 @@ int acpi_table_add(const char *t)
 
     if (!acpi_tables) {
         allen = sizeof(uint16_t);
-        acpi_tables = qemu_mallocz(allen);
+        acpi_tables = g_malloc0(allen);
     } else {
         allen = acpi_tables_len;
     }
 
     start = allen;
-    acpi_tables = qemu_realloc(acpi_tables, start + ACPI_TABLE_HDR_SIZE);
+    acpi_tables = g_realloc(acpi_tables, start + ACPI_TABLE_HDR_SIZE);
     allen += has_header ? ACPI_TABLE_PFX_SIZE : ACPI_TABLE_HDR_SIZE;
 
     /* now read in the data files, reallocating buffer as needed */
@@ -125,7 +125,7 @@ int acpi_table_add(const char *t)
             if (r == 0) {
                 break;
             } else if (r > 0) {
-                acpi_tables = qemu_realloc(acpi_tables, allen + r);
+                acpi_tables = g_realloc(acpi_tables, allen + r);
                 memcpy(acpi_tables + allen, data, r);
                 allen += r;
             } else if (errno != EINTR) {
@@ -379,8 +379,8 @@ void acpi_pm1_cnt_reset(ACPIPM1CNT *pm1_cnt)
 void acpi_gpe_init(ACPIGPE *gpe, uint8_t len)
 {
     gpe->len = len;
-    gpe->sts = qemu_mallocz(len / 2);
-    gpe->en = qemu_mallocz(len / 2);
+    gpe->sts = g_malloc0(len / 2);
+    gpe->en = g_malloc0(len / 2);
 }
 
 void acpi_gpe_blk(ACPIGPE *gpe, uint32_t blk)
diff --git a/hw/adb.c b/hw/adb.c
index 7499cdc..8dedbf8 100644
--- a/hw/adb.c
+++ b/hw/adb.c
@@ -290,7 +290,7 @@ void adb_kbd_init(ADBBusState *bus)
 {
     ADBDevice *d;
     KBDState *s;
-    s = qemu_mallocz(sizeof(KBDState));
+    s = g_malloc0(sizeof(KBDState));
     d = adb_register_device(bus, ADB_KEYBOARD, adb_kbd_request,
                             adb_kbd_reset, s);
     qemu_add_kbd_event_handler(adb_kbd_put_keycode, d);
@@ -447,7 +447,7 @@ void adb_mouse_init(ADBBusState *bus)
     ADBDevice *d;
     MouseState *s;
 
-    s = qemu_mallocz(sizeof(MouseState));
+    s = g_malloc0(sizeof(MouseState));
     d = adb_register_device(bus, ADB_MOUSE, adb_mouse_request,
                             adb_mouse_reset, s);
     qemu_add_mouse_event_handler(adb_mouse_event, d, 0, "QEMU ADB Mouse");
diff --git a/hw/adlib.c b/hw/adlib.c
index 4d76d57..c1c46e3 100644
--- a/hw/adlib.c
+++ b/hw/adlib.c
@@ -268,7 +268,7 @@ static void Adlib_fini (AdlibState *s)
 #endif
 
     if (s->mixbuf) {
-        qemu_free (s->mixbuf);
+        g_free (s->mixbuf);
     }
 
     s->active = 0;
@@ -323,7 +323,7 @@ int Adlib_init (qemu_irq *pic)
     }
 
     s->samples = AUD_get_buffer_size_out (s->voice) >> SHIFT;
-    s->mixbuf = qemu_mallocz (s->samples << SHIFT);
+    s->mixbuf = g_malloc0 (s->samples << SHIFT);
 
     register_ioport_read (0x388, 4, 1, adlib_read, s);
     register_ioport_write (0x388, 4, 1, adlib_write, s);
diff --git a/hw/applesmc.c b/hw/applesmc.c
index 23ed328..c47b592 100644
--- a/hw/applesmc.c
+++ b/hw/applesmc.c
@@ -170,7 +170,7 @@ static void applesmc_add_key(struct AppleSMCStatus *s, const char *key,
 {
     struct AppleSMCData *def;
 
-    def = qemu_mallocz(sizeof(struct AppleSMCData));
+    def = g_malloc0(sizeof(struct AppleSMCData));
     def->key = key;
     def->len = len;
     def->data = data;
diff --git a/hw/arm_timer.c b/hw/arm_timer.c
index fd9448f..f2832f9 100644
--- a/hw/arm_timer.c
+++ b/hw/arm_timer.c
@@ -159,7 +159,7 @@ static arm_timer_state *arm_timer_init(uint32_t freq)
     arm_timer_state *s;
     QEMUBH *bh;
 
-    s = (arm_timer_state *)qemu_mallocz(sizeof(arm_timer_state));
+    s = (arm_timer_state *)g_malloc0(sizeof(arm_timer_state));
     s->freq = freq;
     s->control = TIMER_CTRL_IE;
 
diff --git a/hw/axis_dev88.c b/hw/axis_dev88.c
index d9002a5..06200e2 100644
--- a/hw/axis_dev88.c
+++ b/hw/axis_dev88.c
@@ -315,7 +315,7 @@ void axisdev88_init (ram_addr_t ram_size,
     }
 
     /* Add the two ethernet blocks.  */
-    dma_eth = qemu_mallocz(sizeof dma_eth[0] * 4); /* Allocate 4 channels.  */
+    dma_eth = g_malloc0(sizeof dma_eth[0] * 4); /* Allocate 4 channels.  */
     etraxfs_eth_init(&nd_table[0], 0x30034000, 1, &dma_eth[0], &dma_eth[1]);
     if (nb_nics > 1) {
         etraxfs_eth_init(&nd_table[1], 0x30036000, 2, &dma_eth[2], &dma_eth[3]);
diff --git a/hw/baum.c b/hw/baum.c
index 33a22a7..26beeaf 100644
--- a/hw/baum.c
+++ b/hw/baum.c
@@ -559,7 +559,7 @@ static void baum_chr_read(void *opaque)
     if (ret == -1 && (brlapi_errno != BRLAPI_ERROR_LIBCERR || errno != EINTR)) {
         brlapi_perror("baum: brlapi_readKey");
         brlapi__closeConnection(baum->brlapi);
-        qemu_free(baum->brlapi);
+        g_free(baum->brlapi);
         baum->brlapi = NULL;
     }
 }
@@ -571,9 +571,9 @@ static void baum_close(struct CharDriverState *chr)
     qemu_free_timer(baum->cellCount_timer);
     if (baum->brlapi) {
         brlapi__closeConnection(baum->brlapi);
-        qemu_free(baum->brlapi);
+        g_free(baum->brlapi);
     }
-    qemu_free(baum);
+    g_free(baum);
 }
 
 int chr_baum_init(QemuOpts *opts, CharDriverState **_chr)
@@ -586,8 +586,8 @@ int chr_baum_init(QemuOpts *opts, CharDriverState **_chr)
 #endif
     int tty;
 
-    baum = qemu_mallocz(sizeof(BaumDriverState));
-    baum->chr = chr = qemu_mallocz(sizeof(CharDriverState));
+    baum = g_malloc0(sizeof(BaumDriverState));
+    baum->chr = chr = g_malloc0(sizeof(CharDriverState));
 
     chr->opaque = baum;
     chr->chr_write = baum_write;
@@ -595,7 +595,7 @@ int chr_baum_init(QemuOpts *opts, CharDriverState **_chr)
     chr->chr_accept_input = baum_accept_input;
     chr->chr_close = baum_close;
 
-    handle = qemu_mallocz(brlapi_getHandleSize());
+    handle = g_malloc0(brlapi_getHandleSize());
     baum->brlapi = handle;
 
     baum->brlapi_fd = brlapi__openConnection(handle, NULL, NULL);
@@ -636,8 +636,8 @@ fail:
     qemu_free_timer(baum->cellCount_timer);
     brlapi__closeConnection(handle);
 fail_handle:
-    qemu_free(handle);
-    qemu_free(chr);
-    qemu_free(baum);
+    g_free(handle);
+    g_free(chr);
+    g_free(baum);
     return -EIO;
 }
diff --git a/hw/bitbang_i2c.c b/hw/bitbang_i2c.c
index 53e9c5c..431359d 100644
--- a/hw/bitbang_i2c.c
+++ b/hw/bitbang_i2c.c
@@ -171,7 +171,7 @@ bitbang_i2c_interface *bitbang_i2c_init(i2c_bus *bus)
 {
     bitbang_i2c_interface *s;
 
-    s = qemu_mallocz(sizeof(bitbang_i2c_interface));
+    s = g_malloc0(sizeof(bitbang_i2c_interface));
 
     s->bus = bus;
     s->last_data = 1;
diff --git a/hw/blizzard.c b/hw/blizzard.c
index c524550..b2c1b22 100644
--- a/hw/blizzard.c
+++ b/hw/blizzard.c
@@ -188,7 +188,7 @@ static int blizzard_transfer_setup(BlizzardState *s)
     s->data.len = s->bpp * s->data.dx * s->data.dy;
     s->data.pitch = s->data.dx;
     if (s->data.len > s->data.buflen) {
-        s->data.buf = qemu_realloc(s->data.buf, s->data.len);
+        s->data.buf = g_realloc(s->data.buf, s->data.len);
         s->data.buflen = s->data.len;
     }
     s->data.ptr = s->data.buf;
@@ -953,9 +953,9 @@ static void blizzard_screen_dump(void *opaque, const char *filename) {
 
 void *s1d13745_init(qemu_irq gpio_int)
 {
-    BlizzardState *s = (BlizzardState *) qemu_mallocz(sizeof(*s));
+    BlizzardState *s = (BlizzardState *) g_malloc0(sizeof(*s));
 
-    s->fb = qemu_malloc(0x180000);
+    s->fb = g_malloc(0x180000);
 
     s->state = graphic_console_init(blizzard_update_display,
                                  blizzard_invalidate_display,
@@ -964,7 +964,7 @@ void *s1d13745_init(qemu_irq gpio_int)
     switch (ds_get_bits_per_pixel(s->state)) {
     case 0:
         s->line_fn_tab[0] = s->line_fn_tab[1] =
-                qemu_mallocz(sizeof(blizzard_fn_t) * 0x10);
+                g_malloc0(sizeof(blizzard_fn_t) * 0x10);
         break;
     case 8:
         s->line_fn_tab[0] = blizzard_draw_fn_8;
diff --git a/hw/bt-hci-csr.c b/hw/bt-hci-csr.c
index d135ef4..0dcf897 100644
--- a/hw/bt-hci-csr.c
+++ b/hw/bt-hci-csr.c
@@ -434,7 +434,7 @@ qemu_irq *csrhci_pins_get(CharDriverState *chr)
 CharDriverState *uart_hci_init(qemu_irq wakeup)
 {
     struct csrhci_s *s = (struct csrhci_s *)
-            qemu_mallocz(sizeof(struct csrhci_s));
+            g_malloc0(sizeof(struct csrhci_s));
 
     s->chr.opaque = s;
     s->chr.chr_write = csrhci_write;
diff --git a/hw/bt-hci.c b/hw/bt-hci.c
index 41df24c..a3a7fb4 100644
--- a/hw/bt-hci.c
+++ b/hw/bt-hci.c
@@ -721,7 +721,7 @@ static void bt_hci_connection_reject_event(struct bt_hci_s *hci,
 static void bt_hci_connection_accept(struct bt_hci_s *hci,
                 struct bt_device_s *host)
 {
-    struct bt_hci_link_s *link = qemu_mallocz(sizeof(struct bt_hci_link_s));
+    struct bt_hci_link_s *link = g_malloc0(sizeof(struct bt_hci_link_s));
     evt_conn_complete params;
     uint16_t handle;
     uint8_t status = HCI_SUCCESS;
@@ -736,7 +736,7 @@ static void bt_hci_connection_accept(struct bt_hci_s *hci,
             tries);
 
     if (!tries) {
-        qemu_free(link);
+        g_free(link);
         bt_hci_connection_reject(hci, host, HCI_REJECTED_LIMITED_RESOURCES);
         status = HCI_NO_CONNECTION;
         goto complete;
@@ -893,7 +893,7 @@ static void bt_hci_disconnect(struct bt_hci_s *hci,
 
     /* We are the slave, we get to clean this burden */
     link = (struct bt_hci_link_s *) btlink;
-    qemu_free(link);
+    g_free(link);
 
 complete:
     bt_hci_lmp_link_teardown(hci, handle);
@@ -928,7 +928,7 @@ static void bt_hci_lmp_disconnect_slave(struct bt_link_s *btlink)
     uint16_t handle = link->handle;
     evt_disconn_complete params;
 
-    qemu_free(link);
+    g_free(link);
 
     bt_hci_lmp_link_teardown(hci, handle);
 
@@ -1138,7 +1138,7 @@ static void bt_hci_reset(struct bt_hci_s *hci)
     hci->device.inquiry_scan = 0;
     hci->device.page_scan = 0;
     if (hci->device.lmp_name)
-        qemu_free((void *) hci->device.lmp_name);
+        g_free((void *) hci->device.lmp_name);
     hci->device.lmp_name = NULL;
     hci->device.class[0] = 0x00;
     hci->device.class[1] = 0x00;
@@ -1816,8 +1816,8 @@ static void bt_submit_hci(struct HCIInfo *info,
         LENGTH_CHECK(change_local_name);
 
         if (hci->device.lmp_name)
-            qemu_free((void *) hci->device.lmp_name);
-        hci->device.lmp_name = qemu_strndup(PARAM(change_local_name, name),
+            g_free((void *) hci->device.lmp_name);
+        hci->device.lmp_name = g_strndup(PARAM(change_local_name, name),
                         sizeof(PARAM(change_local_name, name)));
         bt_hci_event_complete_status(hci, HCI_SUCCESS);
         break;
@@ -2143,7 +2143,7 @@ static void bt_hci_destroy(struct bt_device_s *dev)
 
 struct HCIInfo *bt_new_hci(struct bt_scatternet_s *net)
 {
-    struct bt_hci_s *s = qemu_mallocz(sizeof(struct bt_hci_s));
+    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);
@@ -2188,7 +2188,7 @@ static void bt_hci_done(struct HCIInfo *info)
     bt_device_done(&hci->device);
 
     if (hci->device.lmp_name)
-        qemu_free((void *) hci->device.lmp_name);
+        g_free((void *) hci->device.lmp_name);
 
     /* Be gentle and send DISCONNECT to all connected peers and those
      * currently waiting for us to accept or reject a connection request.
@@ -2217,5 +2217,5 @@ static void bt_hci_done(struct HCIInfo *info)
     qemu_free_timer(hci->lm.inquiry_next);
     qemu_free_timer(hci->conn_accept_timer);
 
-    qemu_free(hci);
+    g_free(hci);
 }
diff --git a/hw/bt-hid.c b/hw/bt-hid.c
index 5f1afe3..8d7a3da 100644
--- a/hw/bt-hid.c
+++ b/hw/bt-hid.c
@@ -504,7 +504,7 @@ static void bt_hid_destroy(struct bt_device_s *dev)
 
     hid_free(&hid->hid);
 
-    qemu_free(hid);
+    g_free(hid);
 }
 
 enum peripheral_minor_class {
@@ -517,7 +517,7 @@ enum peripheral_minor_class {
 static struct bt_device_s *bt_hid_init(struct bt_scatternet_s *net,
                                        enum peripheral_minor_class minor)
 {
-    struct bt_hid_device_s *s = qemu_mallocz(sizeof(*s));
+    struct bt_hid_device_s *s = g_malloc0(sizeof(*s));
     uint32_t class =
             /* Format type */
             (0 << 0) |
diff --git a/hw/bt-l2cap.c b/hw/bt-l2cap.c
index 7e2f668..2ccba60 100644
--- a/hw/bt-l2cap.c
+++ b/hw/bt-l2cap.c
@@ -410,7 +410,7 @@ static struct l2cap_chan_s *l2cap_channel_open(struct l2cap_instance_s *l2cap,
 
         if (psm_info) {
             /* Device supports this use-case.  */
-            ch = qemu_mallocz(sizeof(*ch));
+            ch = g_malloc0(sizeof(*ch));
             ch->params.sdu_out = l2cap_bframe_out;
             ch->params.sdu_submit = l2cap_bframe_submit;
             ch->frame_in = l2cap_bframe_in;
@@ -428,7 +428,7 @@ static struct l2cap_chan_s *l2cap_channel_open(struct l2cap_instance_s *l2cap,
                 result = L2CAP_CR_SUCCESS;
                 status = L2CAP_CS_NO_INFO;
             } else {
-                qemu_free(ch);
+                g_free(ch);
 
                 result = L2CAP_CR_NO_MEM;
                 status = L2CAP_CS_NO_INFO;
@@ -473,7 +473,7 @@ static void l2cap_channel_close(struct l2cap_instance_s *l2cap,
         l2cap->cid[cid] = NULL;
 
         ch->params.close(ch->params.opaque);
-        qemu_free(ch);
+        g_free(ch);
     }
 
     l2cap_disconnection_response(l2cap, cid, source_cid);
@@ -1218,13 +1218,13 @@ static void l2cap_teardown(struct l2cap_instance_s *l2cap, int send_disconnect)
     for (cid = L2CAP_CID_ALLOC; cid < L2CAP_CID_MAX; cid ++)
         if (l2cap->cid[cid]) {
             l2cap->cid[cid]->params.close(l2cap->cid[cid]->params.opaque);
-            qemu_free(l2cap->cid[cid]);
+            g_free(l2cap->cid[cid]);
         }
 
     if (l2cap->role)
-        qemu_free(l2cap);
+        g_free(l2cap);
     else
-        qemu_free(l2cap->link);
+        g_free(l2cap->link);
 }
 
 /* L2CAP glue to lower layers in bluetooth stack (LMP) */
@@ -1236,7 +1236,7 @@ static void l2cap_lmp_connection_request(struct bt_link_s *link)
 
     /* Always accept - we only get called if (dev->device->page_scan).  */
 
-    l2cap = qemu_mallocz(sizeof(struct slave_l2cap_instance_s));
+    l2cap = g_malloc0(sizeof(struct slave_l2cap_instance_s));
     l2cap->link.slave = &dev->device;
     l2cap->link.host = link->host;
     l2cap_init(&l2cap->l2cap, &l2cap->link, 0);
@@ -1257,7 +1257,7 @@ static void l2cap_lmp_connection_complete(struct bt_link_s *link)
         return;
     }
 
-    l2cap = qemu_mallocz(sizeof(struct l2cap_instance_s));
+    l2cap = g_malloc0(sizeof(struct l2cap_instance_s));
     l2cap_init(l2cap, link, 1);
 
     link->acl_mode = acl_active;
@@ -1353,7 +1353,7 @@ void bt_l2cap_psm_register(struct bt_l2cap_device_s *dev, int psm, int min_mtu,
         exit(-1);
     }
 
-    new_psm = qemu_mallocz(sizeof(*new_psm));
+    new_psm = g_malloc0(sizeof(*new_psm));
     new_psm->psm = psm;
     new_psm->min_mtu = min_mtu;
     new_psm->new_channel = new_channel;
diff --git a/hw/bt-sdp.c b/hw/bt-sdp.c
index cdf2d95..3e390ab 100644
--- a/hw/bt-sdp.c
+++ b/hw/bt-sdp.c
@@ -567,12 +567,12 @@ static void bt_l2cap_sdp_close_ch(void *opaque)
     int i;
 
     for (i = 0; i < sdp->services; i ++) {
-        qemu_free(sdp->service_list[i].attribute_list->pair);
-        qemu_free(sdp->service_list[i].attribute_list);
-        qemu_free(sdp->service_list[i].uuid);
+        g_free(sdp->service_list[i].attribute_list->pair);
+        g_free(sdp->service_list[i].attribute_list);
+        g_free(sdp->service_list[i].uuid);
     }
-    qemu_free(sdp->service_list);
-    qemu_free(sdp);
+    g_free(sdp->service_list);
+    g_free(sdp);
 }
 
 struct sdp_def_service_s {
@@ -709,10 +709,10 @@ static void sdp_service_record_build(struct sdp_service_record_s *record,
     }
     record->uuids = 1 << ffs(record->uuids - 1);
     record->attribute_list =
-            qemu_mallocz(record->attributes * sizeof(*record->attribute_list));
+            g_malloc0(record->attributes * sizeof(*record->attribute_list));
     record->uuid =
-            qemu_mallocz(record->uuids * sizeof(*record->uuid));
-    data = qemu_malloc(len);
+            g_malloc0(record->uuids * sizeof(*record->uuid));
+    data = g_malloc(len);
 
     record->attributes = 0;
     uuid = record->uuid;
@@ -753,7 +753,7 @@ static void sdp_service_db_build(struct bt_l2cap_sdp_state_s *sdp,
     while (service[sdp->services])
         sdp->services ++;
     sdp->service_list =
-            qemu_mallocz(sdp->services * sizeof(*sdp->service_list));
+            g_malloc0(sdp->services * sizeof(*sdp->service_list));
 
     sdp->services = 0;
     while (*service) {
@@ -942,7 +942,7 @@ SERVICE(pnp,
 static int bt_l2cap_sdp_new_ch(struct bt_l2cap_device_s *dev,
                 struct bt_l2cap_conn_params_s *params)
 {
-    struct bt_l2cap_sdp_state_s *sdp = qemu_mallocz(sizeof(*sdp));
+    struct bt_l2cap_sdp_state_s *sdp = g_malloc0(sizeof(*sdp));
     struct sdp_def_service_s *services[] = {
         &sdp_service_sdp_s,
         &sdp_service_hid_s,
diff --git a/hw/bt.c b/hw/bt.c
index 34bf004..dc99fc2 100644
--- a/hw/bt.c
+++ b/hw/bt.c
@@ -54,7 +54,7 @@ static void bt_dummy_lmp_acl_resp(struct bt_link_s *link,
 /* Slaves that don't hold any additional per link state can use these */
 static void bt_dummy_lmp_connection_request(struct bt_link_s *req)
 {
-    struct bt_link_s *link = qemu_mallocz(sizeof(struct bt_link_s));
+    struct bt_link_s *link = g_malloc0(sizeof(struct bt_link_s));
 
     link->slave = req->slave;
     link->host = req->host;
@@ -65,13 +65,13 @@ static void bt_dummy_lmp_connection_request(struct bt_link_s *req)
 
 static void bt_dummy_lmp_disconnect_slave(struct bt_link_s *link)
 {
-    qemu_free(link);
+    g_free(link);
 }
 
 static void bt_dummy_destroy(struct bt_device_s *device)
 {
     bt_device_done(device);
-    qemu_free(device);
+    g_free(device);
 }
 
 static int bt_dev_idx = 0;
diff --git a/hw/cbus.c b/hw/cbus.c
index 8ae24e0..7216899 100644
--- a/hw/cbus.c
+++ b/hw/cbus.c
@@ -132,7 +132,7 @@ static void cbus_sel(void *opaque, int line, int level)
 
 CBus *cbus_init(qemu_irq dat)
 {
-    CBusPriv *s = (CBusPriv *) qemu_mallocz(sizeof(*s));
+    CBusPriv *s = (CBusPriv *) g_malloc0(sizeof(*s));
 
     s->dat_out = dat;
     s->cbus.clk = qemu_allocate_irqs(cbus_clk, s, 1)[0];
@@ -387,7 +387,7 @@ static void retu_io(void *opaque, int rw, int reg, uint16_t *val)
 
 void *retu_init(qemu_irq irq, int vilma)
 {
-    CBusRetu *s = (CBusRetu *) qemu_mallocz(sizeof(*s));
+    CBusRetu *s = (CBusRetu *) g_malloc0(sizeof(*s));
 
     s->irq = irq;
     s->irqen = 0xffff;
@@ -603,7 +603,7 @@ static void tahvo_io(void *opaque, int rw, int reg, uint16_t *val)
 
 void *tahvo_init(qemu_irq irq, int betty)
 {
-    CBusTahvo *s = (CBusTahvo *) qemu_mallocz(sizeof(*s));
+    CBusTahvo *s = (CBusTahvo *) g_malloc0(sizeof(*s));
 
     s->irq = irq;
     s->irqen = 0xffff;
diff --git a/hw/ccid-card-emulated.c b/hw/ccid-card-emulated.c
index 4762e85..092301b 100644
--- a/hw/ccid-card-emulated.c
+++ b/hw/ccid-card-emulated.c
@@ -135,7 +135,7 @@ static void emulated_apdu_from_guest(CCIDCardState *base,
     const uint8_t *apdu, uint32_t len)
 {
     EmulatedState *card = DO_UPCAST(EmulatedState, base, base);
-    EmulEvent *event = (EmulEvent *)qemu_malloc(sizeof(EmulEvent) + len);
+    EmulEvent *event = (EmulEvent *)g_malloc(sizeof(EmulEvent) + len);
 
     assert(event);
     event->p.data.type = EMUL_GUEST_APDU;
@@ -169,7 +169,7 @@ static void emulated_push_event(EmulatedState *card, EmulEvent *event)
 
 static void emulated_push_type(EmulatedState *card, uint32_t type)
 {
-    EmulEvent *event = (EmulEvent *)qemu_malloc(sizeof(EmulEvent));
+    EmulEvent *event = (EmulEvent *)g_malloc(sizeof(EmulEvent));
 
     assert(event);
     event->p.gen.type = type;
@@ -178,7 +178,7 @@ static void emulated_push_type(EmulatedState *card, uint32_t type)
 
 static void emulated_push_error(EmulatedState *card, uint64_t code)
 {
-    EmulEvent *event = (EmulEvent *)qemu_malloc(sizeof(EmulEvent));
+    EmulEvent *event = (EmulEvent *)g_malloc(sizeof(EmulEvent));
 
     assert(event);
     event->p.error.type = EMUL_ERROR;
@@ -189,7 +189,7 @@ static void emulated_push_error(EmulatedState *card, uint64_t code)
 static void emulated_push_data_type(EmulatedState *card, uint32_t type,
     const uint8_t *data, uint32_t len)
 {
-    EmulEvent *event = (EmulEvent *)qemu_malloc(sizeof(EmulEvent) + len);
+    EmulEvent *event = (EmulEvent *)g_malloc(sizeof(EmulEvent) + len);
 
     assert(event);
     event->p.data.type = type;
@@ -249,12 +249,12 @@ static void *handle_apdu_thread(void* arg)
             QSIMPLEQ_REMOVE_HEAD(&card->guest_apdu_list, entry);
             if (event->p.data.type != EMUL_GUEST_APDU) {
                 DPRINTF(card, 1, "unexpected message in handle_apdu_thread\n");
-                qemu_free(event);
+                g_free(event);
                 continue;
             }
             if (card->reader == NULL) {
                 DPRINTF(card, 1, "reader is NULL\n");
-                qemu_free(event);
+                g_free(event);
                 continue;
             }
             recv_len = sizeof(recv_data);
@@ -267,7 +267,7 @@ static void *handle_apdu_thread(void* arg)
             } else {
                 emulated_push_error(card, reader_status);
             }
-            qemu_free(event);
+            g_free(event);
         }
         qemu_mutex_unlock(&card->vreader_mutex);
     }
@@ -401,7 +401,7 @@ static void pipe_read(void *opaque)
             DPRINTF(card, 2, "unexpected event\n");
             break;
         }
-        qemu_free(event);
+        g_free(event);
     }
     QSIMPLEQ_INIT(&card->event_list);
     qemu_mutex_unlock(&card->event_list_mutex);
diff --git a/hw/cirrus_vga.c b/hw/cirrus_vga.c
index b489309..0f91112 100644
--- a/hw/cirrus_vga.c
+++ b/hw/cirrus_vga.c
@@ -174,8 +174,6 @@
 
 #define CIRRUS_PNPMMIO_SIZE         0x1000
 
-#define ABS(a) ((signed)(a) > 0 ? a : -a)
-
 #define BLTUNSAFE(s) \
     ( \
         ( /* check dst is within bounds */ \
@@ -2372,7 +2370,7 @@ static void unmap_bank(CirrusVGAState *s, unsigned bank)
         memory_region_del_subregion(&s->low_mem_container,
                                     s->cirrus_bank[bank]);
         memory_region_destroy(s->cirrus_bank[bank]);
-        qemu_free(s->cirrus_bank[bank]);
+        g_free(s->cirrus_bank[bank]);
         s->cirrus_bank[bank] = NULL;
     }
 }
@@ -2387,7 +2385,7 @@ static void map_linear_vram_bank(CirrusVGAState *s, unsigned bank)
         && !((s->vga.gr[0x0B] & 0x14) == 0x14)
         && !(s->vga.gr[0x0B] & 0x02)) {
 
-        mr = qemu_malloc(sizeof(*mr));
+        mr = g_malloc(sizeof(*mr));
         memory_region_init_alias(mr, names[bank], &s->vga.vram,
                                  s->cirrus_bank_base[bank], 0x8000);
         memory_region_add_subregion_overlap(
@@ -2903,7 +2901,7 @@ void isa_cirrus_vga_init(void)
 {
     CirrusVGAState *s;
 
-    s = qemu_mallocz(sizeof(CirrusVGAState));
+    s = g_malloc0(sizeof(CirrusVGAState));
 
     vga_common_init(&s->vga, VGA_RAM_SIZE);
     cirrus_init_common(s, CIRRUS_ID_CLGD5430, 0);
diff --git a/hw/dp8393x.c b/hw/dp8393x.c
index 1bcd8ee..f66844b 100644
--- a/hw/dp8393x.c
+++ b/hw/dp8393x.c
@@ -870,7 +870,7 @@ static void nic_cleanup(VLANClientState *nc)
     qemu_del_timer(s->watchdog);
     qemu_free_timer(s->watchdog);
 
-    qemu_free(s);
+    g_free(s);
 }
 
 static NetClientInfo net_dp83932_info = {
@@ -889,7 +889,7 @@ void dp83932_init(NICInfo *nd, target_phys_addr_t base, int it_shift,
 
     qemu_check_nic_model(nd, "dp83932");
 
-    s = qemu_mallocz(sizeof(dp8393xState));
+    s = g_malloc0(sizeof(dp8393xState));
 
     s->mem_opaque = mem_opaque;
     s->memory_rw = memory_rw;
diff --git a/hw/ds1225y.c b/hw/ds1225y.c
index 662d7b5..9875c44 100644
--- a/hw/ds1225y.c
+++ b/hw/ds1225y.c
@@ -146,7 +146,7 @@ static int nvram_sysbus_initfn(SysBusDevice *dev)
     QEMUFile *file;
     int s_io;
 
-    s->contents = qemu_mallocz(s->chip_size);
+    s->contents = g_malloc0(s->chip_size);
 
     s_io = cpu_register_io_memory(nvram_read, nvram_write, s,
                                   DEVICE_NATIVE_ENDIAN);
diff --git a/hw/eepro100.c b/hw/eepro100.c
index a636d30..4e3c52f 100644
--- a/hw/eepro100.c
+++ b/hw/eepro100.c
@@ -1901,7 +1901,7 @@ static int e100_nic_init(PCIDevice *pci_dev)
 
     qemu_register_reset(nic_reset, s);
 
-    s->vmstate = qemu_malloc(sizeof(vmstate_eepro100));
+    s->vmstate = g_malloc(sizeof(vmstate_eepro100));
     memcpy(s->vmstate, &vmstate_eepro100, sizeof(vmstate_eepro100));
     s->vmstate->name = s->nic->nc.model;
     vmstate_register(&pci_dev->qdev, -1, s->vmstate, s);
diff --git a/hw/eeprom93xx.c b/hw/eeprom93xx.c
index 7b21f98..4c7158d 100644
--- a/hw/eeprom93xx.c
+++ b/hw/eeprom93xx.c
@@ -310,7 +310,7 @@ eeprom_t *eeprom93xx_new(DeviceState *dev, uint16_t nwords)
             addrbits = 6;
     }
 
-    eeprom = (eeprom_t *)qemu_mallocz(sizeof(*eeprom) + nwords * 2);
+    eeprom = (eeprom_t *)g_malloc0(sizeof(*eeprom) + nwords * 2);
     eeprom->size = nwords;
     eeprom->addrbits = addrbits;
     /* Output DO is tristate, read results in 1. */
@@ -325,7 +325,7 @@ void eeprom93xx_free(DeviceState *dev, eeprom_t *eeprom)
     /* Destroy EEPROM. */
     logout("eeprom = 0x%p\n", eeprom);
     vmstate_unregister(dev, &vmstate_eeprom, eeprom);
-    qemu_free(eeprom);
+    g_free(eeprom);
 }
 
 uint16_t *eeprom93xx_data(eeprom_t *eeprom)
diff --git a/hw/elf_ops.h b/hw/elf_ops.h
index 0bd7235..6af357f 100644
--- a/hw/elf_ops.h
+++ b/hw/elf_ops.h
@@ -150,7 +150,7 @@ static int glue(load_symbols, SZ)(struct elfhdr *ehdr, int fd, int must_swab,
         i++;
     }
     if (nsyms) {
-        syms = qemu_realloc(syms, nsyms * sizeof(*syms));
+        syms = g_realloc(syms, nsyms * sizeof(*syms));
 
         qsort(syms, nsyms, sizeof(*syms), glue(symcmp, SZ));
         for (i = 0; i < nsyms - 1; i++) {
@@ -159,7 +159,7 @@ static int glue(load_symbols, SZ)(struct elfhdr *ehdr, int fd, int must_swab,
             }
         }
     } else {
-        qemu_free(syms);
+        g_free(syms);
         syms = NULL;
     }
 
@@ -173,19 +173,19 @@ static int glue(load_symbols, SZ)(struct elfhdr *ehdr, int fd, int must_swab,
         goto fail;
 
     /* Commit */
-    s = qemu_mallocz(sizeof(*s));
+    s = g_malloc0(sizeof(*s));
     s->lookup_symbol = glue(lookup_symbol, SZ);
     glue(s->disas_symtab.elf, SZ) = syms;
     s->disas_num_syms = nsyms;
     s->disas_strtab = str;
     s->next = syminfos;
     syminfos = s;
-    qemu_free(shdr_table);
+    g_free(shdr_table);
     return 0;
  fail:
-    qemu_free(syms);
-    qemu_free(str);
-    qemu_free(shdr_table);
+    g_free(syms);
+    g_free(str);
+    g_free(shdr_table);
     return -1;
 }
 
@@ -238,7 +238,7 @@ static int glue(load_elf, SZ)(const char *name, int fd,
 
     size = ehdr.e_phnum * sizeof(phdr[0]);
     lseek(fd, ehdr.e_phoff, SEEK_SET);
-    phdr = qemu_mallocz(size);
+    phdr = g_malloc0(size);
     if (!phdr)
         goto fail;
     if (read(fd, phdr, size) != size)
@@ -256,7 +256,7 @@ static int glue(load_elf, SZ)(const char *name, int fd,
         if (ph->p_type == PT_LOAD) {
             mem_size = ph->p_memsz;
             /* XXX: avoid allocating */
-            data = qemu_mallocz(mem_size);
+            data = g_malloc0(mem_size);
             if (ph->p_filesz > 0) {
                 if (lseek(fd, ph->p_offset, SEEK_SET) < 0)
                     goto fail;
@@ -280,18 +280,18 @@ static int glue(load_elf, SZ)(const char *name, int fd,
             if ((addr + mem_size) > high)
                 high = addr + mem_size;
 
-            qemu_free(data);
+            g_free(data);
             data = NULL;
         }
     }
-    qemu_free(phdr);
+    g_free(phdr);
     if (lowaddr)
         *lowaddr = (uint64_t)(elf_sword)low;
     if (highaddr)
         *highaddr = (uint64_t)(elf_sword)high;
     return total_size;
  fail:
-    qemu_free(data);
-    qemu_free(phdr);
+    g_free(data);
+    g_free(phdr);
     return -1;
 }
diff --git a/hw/etraxfs_dma.c b/hw/etraxfs_dma.c
index c205ec1..e8ad9e6 100644
--- a/hw/etraxfs_dma.c
+++ b/hw/etraxfs_dma.c
@@ -743,12 +743,12 @@ void *etraxfs_dmac_init(target_phys_addr_t base, int nr_channels)
 {
 	struct fs_dma_ctrl *ctrl = NULL;
 
-	ctrl = qemu_mallocz(sizeof *ctrl);
+	ctrl = g_malloc0(sizeof *ctrl);
 
         ctrl->bh = qemu_bh_new(DMA_run, ctrl);
 
 	ctrl->nr_channels = nr_channels;
-	ctrl->channels = qemu_mallocz(sizeof ctrl->channels[0] * nr_channels);
+	ctrl->channels = g_malloc0(sizeof ctrl->channels[0] * nr_channels);
 
 	ctrl->map = cpu_register_io_memory(dma_read, dma_write, ctrl, DEVICE_NATIVE_ENDIAN);
 	cpu_register_physical_memory(base, nr_channels * 0x2000, ctrl->map);
diff --git a/hw/etraxfs_eth.c b/hw/etraxfs_eth.c
index 92d4eca..48de6dc 100644
--- a/hw/etraxfs_eth.c
+++ b/hw/etraxfs_eth.c
@@ -574,7 +574,7 @@ static void eth_cleanup(VLANClientState *nc)
 	eth->dma_out->client.opaque = NULL;
 	eth->dma_in->client.opaque = NULL;
 	eth->dma_in->client.pull = NULL;
-        qemu_free(eth);
+        g_free(eth);
 }
 
 static NetClientInfo net_etraxfs_info = {
diff --git a/hw/fw_cfg.c b/hw/fw_cfg.c
index e4847b7..663ad80 100644
--- a/hw/fw_cfg.c
+++ b/hw/fw_cfg.c
@@ -177,14 +177,14 @@ static void fw_cfg_bootsplash(FWCfgState *s)
         /* probing the file */
         fp = probe_splashfile(filename, &file_size, &file_type);
         if (fp == NULL) {
-            qemu_free(filename);
+            g_free(filename);
             return;
         }
         /* loading file data */
         if (boot_splash_filedata != NULL) {
-            qemu_free(boot_splash_filedata);
+            g_free(boot_splash_filedata);
         }
-        boot_splash_filedata = qemu_malloc(file_size);
+        boot_splash_filedata = g_malloc(file_size);
         boot_splash_filedata_size = file_size;
         fseek(fp, 0L, SEEK_SET);
         fop_ret = fread(boot_splash_filedata, 1, file_size, fp);
@@ -203,7 +203,7 @@ static void fw_cfg_bootsplash(FWCfgState *s)
             fw_cfg_add_file(s, "bootsplash.bmp",
                     boot_splash_filedata, boot_splash_filedata_size);
         }
-        qemu_free(filename);
+        g_free(filename);
     }
 }
 
@@ -385,7 +385,7 @@ int fw_cfg_add_i16(FWCfgState *s, uint16_t key, uint16_t value)
 {
     uint16_t *copy;
 
-    copy = qemu_malloc(sizeof(value));
+    copy = g_malloc(sizeof(value));
     *copy = cpu_to_le16(value);
     return fw_cfg_add_bytes(s, key, (uint8_t *)copy, sizeof(value));
 }
@@ -394,7 +394,7 @@ int fw_cfg_add_i32(FWCfgState *s, uint16_t key, uint32_t value)
 {
     uint32_t *copy;
 
-    copy = qemu_malloc(sizeof(value));
+    copy = g_malloc(sizeof(value));
     *copy = cpu_to_le32(value);
     return fw_cfg_add_bytes(s, key, (uint8_t *)copy, sizeof(value));
 }
@@ -403,7 +403,7 @@ int fw_cfg_add_i64(FWCfgState *s, uint16_t key, uint64_t value)
 {
     uint64_t *copy;
 
-    copy = qemu_malloc(sizeof(value));
+    copy = g_malloc(sizeof(value));
     *copy = cpu_to_le64(value);
     return fw_cfg_add_bytes(s, key, (uint8_t *)copy, sizeof(value));
 }
@@ -436,7 +436,7 @@ int fw_cfg_add_file(FWCfgState *s,  const char *filename, uint8_t *data,
 
     if (!s->files) {
         int dsize = sizeof(uint32_t) + sizeof(FWCfgFile) * FW_CFG_FILE_SLOTS;
-        s->files = qemu_mallocz(dsize);
+        s->files = g_malloc0(dsize);
         fw_cfg_add_bytes(s, FW_CFG_FILE_DIR, (uint8_t*)s->files, dsize);
     }
 
diff --git a/hw/g364fb.c b/hw/g364fb.c
index a41e988..b3020c5 100644
--- a/hw/g364fb.c
+++ b/hw/g364fb.c
@@ -590,7 +590,7 @@ int g364fb_mm_init(target_phys_addr_t vram_base,
     G364State *s;
     int io_ctrl;
 
-    s = qemu_mallocz(sizeof(G364State));
+    s = g_malloc0(sizeof(G364State));
 
     s->vram_size = 8 * 1024 * 1024;
     s->vram_offset = qemu_ram_alloc(NULL, "g364fb.vram", s->vram_size);
diff --git a/hw/grlib_gptimer.c b/hw/grlib_gptimer.c
index 99e9033..85869b9 100644
--- a/hw/grlib_gptimer.c
+++ b/hw/grlib_gptimer.c
@@ -345,7 +345,7 @@ static int grlib_gptimer_init(SysBusDevice *dev)
     assert(unit->nr_timers > 0);
     assert(unit->nr_timers <= GPTIMER_MAX_TIMERS);
 
-    unit->timers = qemu_mallocz(sizeof unit->timers[0] * unit->nr_timers);
+    unit->timers = g_malloc0(sizeof unit->timers[0] * unit->nr_timers);
 
     for (i = 0; i < unit->nr_timers; i++) {
         GPTimer *timer = &unit->timers[i];
diff --git a/hw/grlib_irqmp.c b/hw/grlib_irqmp.c
index b8738fc..9490a78 100644
--- a/hw/grlib_irqmp.c
+++ b/hw/grlib_irqmp.c
@@ -345,7 +345,7 @@ static int grlib_irqmp_init(SysBusDevice *dev)
                                         grlib_irqmp_write,
                                         irqmp, DEVICE_NATIVE_ENDIAN);
 
-    irqmp->state = qemu_mallocz(sizeof *irqmp->state);
+    irqmp->state = g_malloc0(sizeof *irqmp->state);
 
     if (irqmp_regs < 0) {
         return -1;
diff --git a/hw/gus.c b/hw/gus.c
index ff9e7c7..37e543a 100644
--- a/hw/gus.c
+++ b/hw/gus.c
@@ -260,7 +260,7 @@ static int gus_initfn (ISADevice *dev)
 
     s->shift = 2;
     s->samples = AUD_get_buffer_size_out (s->voice) >> s->shift;
-    s->mixbuf = qemu_mallocz (s->samples << s->shift);
+    s->mixbuf = g_malloc0 (s->samples << s->shift);
 
     register_ioport_write (s->port, 1, 1, gus_writeb, s);
     register_ioport_write (s->port, 1, 2, gus_writew, s);
diff --git a/hw/heathrow_pic.c b/hw/heathrow_pic.c
index 3ba0b0e..51996ab 100644
--- a/hw/heathrow_pic.c
+++ b/hw/heathrow_pic.c
@@ -202,7 +202,7 @@ qemu_irq *heathrow_pic_init(MemoryRegion **pmem,
 {
     HeathrowPICS *s;
 
-    s = qemu_mallocz(sizeof(HeathrowPICS));
+    s = g_malloc0(sizeof(HeathrowPICS));
     /* only 1 CPU */
     s->irqs = irqs[0];
     memory_region_init_io(&s->mem, &heathrow_pic_ops, s,
diff --git a/hw/i8259.c b/hw/i8259.c
index 84d330d..c0b96ab 100644
--- a/hw/i8259.c
+++ b/hw/i8259.c
@@ -526,7 +526,7 @@ qemu_irq *i8259_init(qemu_irq parent_irq)
 {
     PicState2 *s;
 
-    s = qemu_mallocz(sizeof(PicState2));
+    s = g_malloc0(sizeof(PicState2));
     pic_init1(0x20, 0x4d0, &s->pics[0]);
     pic_init1(0xa0, 0x4d1, &s->pics[1]);
     s->pics[0].elcr_mask = 0xf8;
diff --git a/hw/ide/ahci.c b/hw/ide/ahci.c
index e207ca0..29521ba 100644
--- a/hw/ide/ahci.c
+++ b/hw/ide/ahci.c
@@ -1123,7 +1123,7 @@ void ahci_init(AHCIState *s, DeviceState *qdev, int ports)
     int i;
 
     s->ports = ports;
-    s->dev = qemu_mallocz(sizeof(AHCIDevice) * ports);
+    s->dev = g_malloc0(sizeof(AHCIDevice) * ports);
     ahci_reg_init(s);
     /* XXX BAR size should be 1k, but that breaks, so bump it to 4k for now */
     memory_region_init_io(&s->mem, &ahci_mem_ops, s, "ahci", 0x1000);
@@ -1146,7 +1146,7 @@ void ahci_init(AHCIState *s, DeviceState *qdev, int ports)
 void ahci_uninit(AHCIState *s)
 {
     memory_region_destroy(&s->mem);
-    qemu_free(s->dev);
+    g_free(s->dev);
 }
 
 void ahci_reset(void *opaque)
diff --git a/hw/ide/macio.c b/hw/ide/macio.c
index 7ee35e9..44fb3fe 100644
--- a/hw/ide/macio.c
+++ b/hw/ide/macio.c
@@ -325,7 +325,7 @@ MemoryRegion *pmac_ide_init (DriveInfo **hd_table, qemu_irq irq,
 {
     MACIOIDEState *d;
 
-    d = qemu_mallocz(sizeof(MACIOIDEState));
+    d = g_malloc0(sizeof(MACIOIDEState));
     ide_init2_with_non_qdev_drives(&d->bus, hd_table[0], hd_table[1], irq);
 
     if (dbdma)
diff --git a/hw/ide/microdrive.c b/hw/ide/microdrive.c
index 9fbbf0e..91c0e3c 100644
--- a/hw/ide/microdrive.c
+++ b/hw/ide/microdrive.c
@@ -531,7 +531,7 @@ static int dscm1xxxx_detach(void *opaque)
 
 PCMCIACardState *dscm1xxxx_init(DriveInfo *bdrv)
 {
-    MicroDriveState *md = (MicroDriveState *) qemu_mallocz(sizeof(MicroDriveState));
+    MicroDriveState *md = (MicroDriveState *) g_malloc0(sizeof(MicroDriveState));
     md->card.state = md;
     md->card.attach = dscm1xxxx_attach;
     md->card.detach = dscm1xxxx_detach;
@@ -542,7 +542,7 @@ PCMCIACardState *dscm1xxxx_init(DriveInfo *bdrv)
                                    qemu_allocate_irqs(md_set_irq, md, 1)[0]);
     md->bus.ifs[0].drive_kind = IDE_CFATA;
     md->bus.ifs[0].mdata_size = METADATA_SIZE;
-    md->bus.ifs[0].mdata_storage = (uint8_t *) qemu_mallocz(METADATA_SIZE);
+    md->bus.ifs[0].mdata_storage = (uint8_t *) g_malloc0(METADATA_SIZE);
 
     vmstate_register(NULL, -1, &vmstate_microdrive, md);
 
diff --git a/hw/ide/mmio.c b/hw/ide/mmio.c
index 10f6f40..132b751 100644
--- a/hw/ide/mmio.c
+++ b/hw/ide/mmio.c
@@ -121,7 +121,7 @@ void mmio_ide_init (target_phys_addr_t membase, target_phys_addr_t membase2,
                     qemu_irq irq, int shift,
                     DriveInfo *hd0, DriveInfo *hd1)
 {
-    MMIOState *s = qemu_mallocz(sizeof(MMIOState));
+    MMIOState *s = g_malloc0(sizeof(MMIOState));
     int mem1, mem2;
 
     ide_init2_with_non_qdev_drives(&s->bus, hd0, hd1, irq);
diff --git a/hw/ide/qdev.c b/hw/ide/qdev.c
index 6bd8d20..4207127 100644
--- a/hw/ide/qdev.c
+++ b/hw/ide/qdev.c
@@ -148,10 +148,10 @@ static int ide_dev_initfn(IDEDevice *dev, IDEDriveKind kind)
     }
 
     if (!dev->version) {
-        dev->version = qemu_strdup(s->version);
+        dev->version = g_strdup(s->version);
     }
     if (!dev->serial) {
-        dev->serial = qemu_strdup(s->drive_serial_str);
+        dev->serial = g_strdup(s->drive_serial_str);
     }
 
     add_boot_device_path(dev->conf.bootindex, &dev->qdev,
diff --git a/hw/intel-hda.c b/hw/intel-hda.c
index fa56a92..4272204 100644
--- a/hw/intel-hda.c
+++ b/hw/intel-hda.c
@@ -467,8 +467,8 @@ static void intel_hda_parse_bdl(IntelHDAState *d, IntelHDAStream *st)
 
     addr = intel_hda_addr(st->bdlp_lbase, st->bdlp_ubase);
     st->bentries = st->lvi +1;
-    qemu_free(st->bpl);
-    st->bpl = qemu_malloc(sizeof(bpl) * st->bentries);
+    g_free(st->bpl);
+    st->bpl = g_malloc(sizeof(bpl) * st->bentries);
     for (i = 0; i < st->bentries; i++, addr += 16) {
         cpu_physical_memory_read(addr, buf, 16);
         st->bpl[i].addr  = le64_to_cpu(*(uint64_t *)buf);
diff --git a/hw/irq.c b/hw/irq.c
index 4035a8c..60eabe8 100644
--- a/hw/irq.c
+++ b/hw/irq.c
@@ -44,8 +44,8 @@ qemu_irq *qemu_allocate_irqs(qemu_irq_handler handler, void *opaque, int n)
     struct IRQState *p;
     int i;
 
-    s = (qemu_irq *)qemu_mallocz(sizeof(qemu_irq) * n);
-    p = (struct IRQState *)qemu_mallocz(sizeof(struct IRQState) * n);
+    s = (qemu_irq *)g_malloc0(sizeof(qemu_irq) * n);
+    p = (struct IRQState *)g_malloc0(sizeof(struct IRQState) * n);
     for (i = 0; i < n; i++) {
         p->handler = handler;
         p->opaque = opaque;
@@ -58,8 +58,8 @@ qemu_irq *qemu_allocate_irqs(qemu_irq_handler handler, void *opaque, int n)
 
 void qemu_free_irqs(qemu_irq *s)
 {
-    qemu_free(s[0]);
-    qemu_free(s);
+    g_free(s[0]);
+    g_free(s);
 }
 
 static void qemu_notirq(void *opaque, int line, int level)
@@ -85,7 +85,7 @@ static void qemu_splitirq(void *opaque, int line, int level)
 
 qemu_irq qemu_irq_split(qemu_irq irq1, qemu_irq irq2)
 {
-    qemu_irq *s = qemu_mallocz(2 * sizeof(qemu_irq));
+    qemu_irq *s = g_malloc0(2 * sizeof(qemu_irq));
     s[0] = irq1;
     s[1] = irq2;
     return qemu_allocate_irqs(qemu_splitirq, s, 1)[0];
diff --git a/hw/isa_mmio.c b/hw/isa_mmio.c
index 3d2af1a..fd755ab 100644
--- a/hw/isa_mmio.c
+++ b/hw/isa_mmio.c
@@ -74,7 +74,7 @@ void isa_mmio_setup(MemoryRegion *mr, target_phys_addr_t size)
 
 void isa_mmio_init(target_phys_addr_t base, target_phys_addr_t size)
 {
-    MemoryRegion *mr = qemu_malloc(sizeof(*mr));
+    MemoryRegion *mr = g_malloc(sizeof(*mr));
 
     isa_mmio_setup(mr, size);
     memory_region_add_subregion(get_system_memory(), base, mr);
diff --git a/hw/ivshmem.c b/hw/ivshmem.c
index 42a5877..f4ae0d2 100644
--- a/hw/ivshmem.c
+++ b/hw/ivshmem.c
@@ -351,7 +351,7 @@ static void close_guest_eventfds(IVShmemState *s, int posn)
         close(s->peers[posn].eventfds[i]);
     }
 
-    qemu_free(s->peers[posn].eventfds);
+    g_free(s->peers[posn].eventfds);
     s->peers[posn].nb_eventfds = 0;
 }
 
@@ -383,7 +383,7 @@ static void increase_dynamic_storage(IVShmemState *s, int new_min_size) {
         s->nb_peers = s->nb_peers * 2;
 
     IVSHMEM_DPRINTF("bumping storage to %d guests\n", s->nb_peers);
-    s->peers = qemu_realloc(s->peers, s->nb_peers * sizeof(Peer));
+    s->peers = g_realloc(s->peers, s->nb_peers * sizeof(Peer));
 
     /* zero out new pointers */
     for (j = old_nb_alloc; j < s->nb_peers; j++) {
@@ -467,7 +467,7 @@ static void ivshmem_read(void *opaque, const uint8_t * buf, int flags)
 
     if (guest_max_eventfd == 0) {
         /* one eventfd per MSI vector */
-        s->peers[incoming_posn].eventfds = (int *) qemu_malloc(s->vectors *
+        s->peers[incoming_posn].eventfds = (int *) g_malloc(s->vectors *
                                                                 sizeof(int));
     }
 
@@ -557,7 +557,7 @@ static void ivshmem_setup_msi(IVShmemState * s) {
     }
 
     /* allocate Qemu char devices for receiving interrupts */
-    s->eventfd_table = qemu_mallocz(s->vectors * sizeof(EventfdEntry));
+    s->eventfd_table = g_malloc0(s->vectors * sizeof(EventfdEntry));
 }
 
 static void ivshmem_save(QEMUFile* f, void *opaque)
@@ -691,12 +691,12 @@ static int pci_ivshmem_init(PCIDevice *dev)
         s->vm_id = -1;
 
         /* allocate/initialize space for interrupt handling */
-        s->peers = qemu_mallocz(s->nb_peers * sizeof(Peer));
+        s->peers = g_malloc0(s->nb_peers * sizeof(Peer));
 
         pci_register_bar(&s->dev, 2,
                          PCI_BASE_ADDRESS_SPACE_MEMORY, &s->ivshmem);
 
-        s->eventfd_chr = qemu_mallocz(s->vectors * sizeof(CharDriverState *));
+        s->eventfd_chr = g_malloc0(s->vectors * sizeof(CharDriverState *));
 
         qemu_chr_add_handlers(s->server_chr, ivshmem_can_receive, ivshmem_read,
                      ivshmem_event, s);
diff --git a/hw/jazz_led.c b/hw/jazz_led.c
index 1dc22cf..eb472a0 100644
--- a/hw/jazz_led.c
+++ b/hw/jazz_led.c
@@ -312,7 +312,7 @@ void jazz_led_init(target_phys_addr_t base)
     LedState *s;
     int io;
 
-    s = qemu_mallocz(sizeof(LedState));
+    s = g_malloc0(sizeof(LedState));
 
     s->state = REDRAW_SEGMENTS | REDRAW_BACKGROUND;
 
diff --git a/hw/leon3.c b/hw/leon3.c
index 919f49f..a62a941 100644
--- a/hw/leon3.c
+++ b/hw/leon3.c
@@ -122,7 +122,7 @@ static void leon3_generic_hw_init(ram_addr_t  ram_size,
     cpu_sparc_set_id(env, 0);
 
     /* Reset data */
-    reset_info        = qemu_mallocz(sizeof(ResetData));
+    reset_info        = g_malloc0(sizeof(ResetData));
     reset_info->env   = env;
     qemu_register_reset(main_cpu_reset, reset_info);
 
diff --git a/hw/lm32_boards.c b/hw/lm32_boards.c
index 6462923..d18aad7 100644
--- a/hw/lm32_boards.c
+++ b/hw/lm32_boards.c
@@ -95,7 +95,7 @@ static void lm32_evr_init(ram_addr_t ram_size_not_used,
     int timer0_irq                 = 1;
     int timer1_irq                 = 3;
 
-    reset_info = qemu_mallocz(sizeof(ResetInfo));
+    reset_info = g_malloc0(sizeof(ResetInfo));
 
     if (cpu_model == NULL) {
         cpu_model = "lm32-full";
@@ -190,7 +190,7 @@ static void lm32_uclinux_init(ram_addr_t ram_size_not_used,
     target_phys_addr_t initrd_base  = 0x08400000;
     size_t initrd_max               = 0x01000000;
 
-    reset_info = qemu_mallocz(sizeof(ResetInfo));
+    reset_info = g_malloc0(sizeof(ResetInfo));
 
     if (cpu_model == NULL) {
         cpu_model = "lm32-full";
diff --git a/hw/lm32_hwsetup.h b/hw/lm32_hwsetup.h
index 9f47821..8fc285e 100644
--- a/hw/lm32_hwsetup.h
+++ b/hw/lm32_hwsetup.h
@@ -57,8 +57,8 @@ static inline HWSetup *hwsetup_init(void)
 {
     HWSetup *hw;
 
-    hw = qemu_malloc(sizeof(HWSetup));
-    hw->data = qemu_mallocz(TARGET_PAGE_SIZE);
+    hw = g_malloc(sizeof(HWSetup));
+    hw->data = g_malloc0(TARGET_PAGE_SIZE);
     hw->ptr = hw->data;
 
     return hw;
@@ -66,8 +66,8 @@ static inline HWSetup *hwsetup_init(void)
 
 static inline void hwsetup_free(HWSetup *hw)
 {
-    qemu_free(hw->data);
-    qemu_free(hw);
+    g_free(hw->data);
+    g_free(hw);
 }
 
 static inline void hwsetup_create_rom(HWSetup *hw,
diff --git a/hw/loader.c b/hw/loader.c
index 35d792e..8efb146 100644
--- a/hw/loader.c
+++ b/hw/loader.c
@@ -91,11 +91,11 @@ int read_targphys(const char *name,
     uint8_t *buf;
     size_t did;
 
-    buf = qemu_malloc(nbytes);
+    buf = g_malloc(nbytes);
     did = read(fd, buf, nbytes);
     if (did > 0)
         rom_add_blob_fixed("read", buf, did, dst_addr);
-    qemu_free(buf);
+    g_free(buf);
     return did;
 }
 
@@ -234,9 +234,9 @@ static void *load_at(int fd, int offset, int size)
     void *ptr;
     if (lseek(fd, offset, SEEK_SET) < 0)
         return NULL;
-    ptr = qemu_malloc(size);
+    ptr = g_malloc(size);
     if (read(fd, ptr, size) != size) {
-        qemu_free(ptr);
+        g_free(ptr);
         return NULL;
     }
     return ptr;
@@ -351,14 +351,14 @@ static void *zalloc(void *x, unsigned items, unsigned size)
     size *= items;
     size = (size + ZALLOC_ALIGNMENT - 1) & ~(ZALLOC_ALIGNMENT - 1);
 
-    p = qemu_malloc(size);
+    p = g_malloc(size);
 
     return (p);
 }
 
 static void zfree(void *x, void *addr)
 {
-    qemu_free(addr);
+    g_free(addr);
 }
 
 
@@ -476,7 +476,7 @@ int load_uimage(const char *filename, target_phys_addr_t *ep,
     }
 
     *ep = hdr->ih_ep;
-    data = qemu_malloc(hdr->ih_size);
+    data = g_malloc(hdr->ih_size);
 
     if (read(fd, data, hdr->ih_size) != hdr->ih_size) {
         fprintf(stderr, "Error reading file\n");
@@ -490,10 +490,10 @@ int load_uimage(const char *filename, target_phys_addr_t *ep,
 
         compressed_data = data;
         max_bytes = UBOOT_MAX_GUNZIP_BYTES;
-        data = qemu_malloc(max_bytes);
+        data = g_malloc(max_bytes);
 
         bytes = gunzip(data, max_bytes, compressed_data, hdr->ih_size);
-        qemu_free(compressed_data);
+        g_free(compressed_data);
         if (bytes < 0) {
             fprintf(stderr, "Unable to decompress gzipped image!\n");
             goto out;
@@ -510,7 +510,7 @@ int load_uimage(const char *filename, target_phys_addr_t *ep,
 
 out:
     if (data)
-        qemu_free(data);
+        g_free(data);
     close(fd);
     return ret;
 }
@@ -564,11 +564,11 @@ int rom_add_file(const char *file, const char *fw_dir,
     int rc, fd = -1;
     char devpath[100];
 
-    rom = qemu_mallocz(sizeof(*rom));
-    rom->name = qemu_strdup(file);
+    rom = g_malloc0(sizeof(*rom));
+    rom->name = g_strdup(file);
     rom->path = qemu_find_file(QEMU_FILE_TYPE_BIOS, rom->name);
     if (rom->path == NULL) {
-        rom->path = qemu_strdup(file);
+        rom->path = g_strdup(file);
     }
 
     fd = open(rom->path, O_RDONLY | O_BINARY);
@@ -579,12 +579,12 @@ int rom_add_file(const char *file, const char *fw_dir,
     }
 
     if (fw_dir) {
-        rom->fw_dir  = qemu_strdup(fw_dir);
-        rom->fw_file = qemu_strdup(file);
+        rom->fw_dir  = g_strdup(fw_dir);
+        rom->fw_file = g_strdup(file);
     }
     rom->addr    = addr;
     rom->romsize = lseek(fd, 0, SEEK_END);
-    rom->data    = qemu_mallocz(rom->romsize);
+    rom->data    = g_malloc0(rom->romsize);
     lseek(fd, 0, SEEK_SET);
     rc = read(fd, rom->data, rom->romsize);
     if (rc != rom->romsize) {
@@ -618,10 +618,10 @@ int rom_add_file(const char *file, const char *fw_dir,
 err:
     if (fd != -1)
         close(fd);
-    qemu_free(rom->data);
-    qemu_free(rom->path);
-    qemu_free(rom->name);
-    qemu_free(rom);
+    g_free(rom->data);
+    g_free(rom->path);
+    g_free(rom->name);
+    g_free(rom);
     return -1;
 }
 
@@ -630,11 +630,11 @@ int rom_add_blob(const char *name, const void *blob, size_t len,
 {
     Rom *rom;
 
-    rom = qemu_mallocz(sizeof(*rom));
-    rom->name    = qemu_strdup(name);
+    rom = g_malloc0(sizeof(*rom));
+    rom->name    = g_strdup(name);
     rom->addr    = addr;
     rom->romsize = len;
-    rom->data    = qemu_mallocz(rom->romsize);
+    rom->data    = g_malloc0(rom->romsize);
     memcpy(rom->data, blob, len);
     rom_insert(rom);
     return 0;
@@ -664,7 +664,7 @@ static void rom_reset(void *unused)
         cpu_physical_memory_write_rom(rom->addr, rom->data, rom->romsize);
         if (rom->isrom) {
             /* rom needs to be written only once */
-            qemu_free(rom->data);
+            g_free(rom->data);
             rom->data = NULL;
         }
     }
diff --git a/hw/lsi53c895a.c b/hw/lsi53c895a.c
index 41c2fb0..1643a63 100644
--- a/hw/lsi53c895a.c
+++ b/hw/lsi53c895a.c
@@ -353,10 +353,10 @@ static void lsi_soft_reset(LSIState *s)
     while (!QTAILQ_EMPTY(&s->queue)) {
         p = QTAILQ_FIRST(&s->queue);
         QTAILQ_REMOVE(&s->queue, p, next);
-        qemu_free(p);
+        g_free(p);
     }
     if (s->current) {
-        qemu_free(s->current);
+        g_free(s->current);
         s->current = NULL;
     }
 }
@@ -664,7 +664,7 @@ static void lsi_request_cancelled(SCSIRequest *req)
 
     if (s->current && req == s->current->req) {
         scsi_req_unref(req);
-        qemu_free(s->current);
+        g_free(s->current);
         s->current = NULL;
         return;
     }
@@ -672,7 +672,7 @@ static void lsi_request_cancelled(SCSIRequest *req)
     if (p) {
         QTAILQ_REMOVE(&s->queue, p, next);
         scsi_req_unref(req);
-        qemu_free(p);
+        g_free(p);
     }
 }
 
@@ -723,7 +723,7 @@ static void lsi_command_complete(SCSIRequest *req, uint32_t status)
 
     if (s->current && req == s->current->req) {
         scsi_req_unref(s->current->req);
-        qemu_free(s->current);
+        g_free(s->current);
         s->current = NULL;
     }
     lsi_resume_script(s);
@@ -779,7 +779,7 @@ static void lsi_do_command(LSIState *s)
     }
 
     assert(s->current == NULL);
-    s->current = qemu_mallocz(sizeof(lsi_request));
+    s->current = g_malloc0(sizeof(lsi_request));
     s->current->tag = s->select_tag;
     s->current->req = scsi_req_new(dev, s->current->tag, s->current_lun, buf,
                                    s->current);
diff --git a/hw/m48t59.c b/hw/m48t59.c
index 537c0f7..401b969 100644
--- a/hw/m48t59.c
+++ b/hw/m48t59.c
@@ -679,7 +679,7 @@ M48t59State *m48t59_init_isa(uint32_t io_base, uint16_t size, int type)
 
 static void m48t59_init_common(M48t59State *s)
 {
-    s->buffer = qemu_mallocz(s->size);
+    s->buffer = g_malloc0(s->size);
     if (s->type == 59) {
         s->alrm_timer = qemu_new_timer_ns(vm_clock, &alarm_cb, s);
         s->wd_timer = qemu_new_timer_ns(vm_clock, &watchdog_cb, s);
diff --git a/hw/mac_dbdma.c b/hw/mac_dbdma.c
index 350d901..5affdd1 100644
--- a/hw/mac_dbdma.c
+++ b/hw/mac_dbdma.c
@@ -846,7 +846,7 @@ void* DBDMA_init (MemoryRegion **dbdma_mem)
 {
     DBDMAState *s;
 
-    s = qemu_mallocz(sizeof(DBDMAState));
+    s = g_malloc0(sizeof(DBDMAState));
 
     memory_region_init_io(&s->mem, &dbdma_ops, s, "dbdma", 0x1000);
     *dbdma_mem = &s->mem;
diff --git a/hw/mac_nvram.c b/hw/mac_nvram.c
index ced1e58..ed0a2b7 100644
--- a/hw/mac_nvram.c
+++ b/hw/mac_nvram.c
@@ -121,8 +121,8 @@ MacIONVRAMState *macio_nvram_init (target_phys_addr_t size,
 {
     MacIONVRAMState *s;
 
-    s = qemu_mallocz(sizeof(MacIONVRAMState));
-    s->data = qemu_mallocz(size);
+    s = g_malloc0(sizeof(MacIONVRAMState));
+    s->data = g_malloc0(size);
     s->size = size;
     s->it_shift = it_shift;
 
diff --git a/hw/mcf5206.c b/hw/mcf5206.c
index fce282d..15d6f22 100644
--- a/hw/mcf5206.c
+++ b/hw/mcf5206.c
@@ -132,7 +132,7 @@ static m5206_timer_state *m5206_timer_init(qemu_irq irq)
     m5206_timer_state *s;
     QEMUBH *bh;
 
-    s = (m5206_timer_state *)qemu_mallocz(sizeof(m5206_timer_state));
+    s = (m5206_timer_state *)g_malloc0(sizeof(m5206_timer_state));
     bh = qemu_bh_new(m5206_timer_trigger, s);
     s->timer = ptimer_init(bh);
     s->irq = irq;
@@ -523,7 +523,7 @@ qemu_irq *mcf5206_init(uint32_t base, CPUState *env)
     qemu_irq *pic;
     int iomemtype;
 
-    s = (m5206_mbar_state *)qemu_mallocz(sizeof(m5206_mbar_state));
+    s = (m5206_mbar_state *)g_malloc0(sizeof(m5206_mbar_state));
     iomemtype = cpu_register_io_memory(m5206_mbar_readfn,
                                        m5206_mbar_writefn, s,
                                        DEVICE_NATIVE_ENDIAN);
diff --git a/hw/mcf5208.c b/hw/mcf5208.c
index 78fbc5f..8fe507f 100644
--- a/hw/mcf5208.c
+++ b/hw/mcf5208.c
@@ -185,7 +185,7 @@ static void mcf5208_sys_init(qemu_irq *pic)
     cpu_register_physical_memory(0xfc0a8000, 0x00004000, iomemtype);
     /* Timers.  */
     for (i = 0; i < 2; i++) {
-        s = (m5208_timer_state *)qemu_mallocz(sizeof(m5208_timer_state));
+        s = (m5208_timer_state *)g_malloc0(sizeof(m5208_timer_state));
         bh = qemu_bh_new(m5208_timer_trigger, s);
         s->timer = ptimer_init(bh);
         iomemtype = cpu_register_io_memory(m5208_timer_readfn,
diff --git a/hw/mcf_fec.c b/hw/mcf_fec.c
index 748eb59..42a5d77 100644
--- a/hw/mcf_fec.c
+++ b/hw/mcf_fec.c
@@ -447,7 +447,7 @@ static void mcf_fec_cleanup(VLANClientState *nc)
 
     cpu_unregister_io_memory(s->mmio_index);
 
-    qemu_free(s);
+    g_free(s);
 }
 
 static NetClientInfo net_mcf_fec_info = {
@@ -464,7 +464,7 @@ void mcf_fec_init(NICInfo *nd, target_phys_addr_t base, qemu_irq *irq)
 
     qemu_check_nic_model(nd, "mcf_fec");
 
-    s = (mcf_fec_state *)qemu_mallocz(sizeof(mcf_fec_state));
+    s = (mcf_fec_state *)g_malloc0(sizeof(mcf_fec_state));
     s->irq = irq;
     s->mmio_index = cpu_register_io_memory(mcf_fec_readfn,
                                            mcf_fec_writefn, s,
diff --git a/hw/mcf_intc.c b/hw/mcf_intc.c
index 6cb0a09..99092e7 100644
--- a/hw/mcf_intc.c
+++ b/hw/mcf_intc.c
@@ -144,7 +144,7 @@ qemu_irq *mcf_intc_init(target_phys_addr_t base, CPUState *env)
     mcf_intc_state *s;
     int iomemtype;
 
-    s = qemu_mallocz(sizeof(mcf_intc_state));
+    s = g_malloc0(sizeof(mcf_intc_state));
     s->env = env;
     mcf_intc_reset(s);
 
diff --git a/hw/mcf_uart.c b/hw/mcf_uart.c
index 905e116..6118ccb 100644
--- a/hw/mcf_uart.c
+++ b/hw/mcf_uart.c
@@ -272,7 +272,7 @@ void *mcf_uart_init(qemu_irq irq, CharDriverState *chr)
 {
     mcf_uart_state *s;
 
-    s = qemu_mallocz(sizeof(mcf_uart_state));
+    s = g_malloc0(sizeof(mcf_uart_state));
     s->chr = chr;
     s->irq = irq;
     if (chr) {
diff --git a/hw/milkymist.c b/hw/milkymist.c
index 7879840..93288c8 100644
--- a/hw/milkymist.c
+++ b/hw/milkymist.c
@@ -99,7 +99,7 @@ milkymist_init(ram_addr_t ram_size_not_used,
     target_phys_addr_t cmdline_base = sdram_base + 0x1000000;
     size_t initrd_max = sdram_size - 0x1002000;
 
-    reset_info = qemu_mallocz(sizeof(ResetInfo));
+    reset_info = g_malloc0(sizeof(ResetInfo));
 
     if (cpu_model == NULL) {
         cpu_model = "lm32-full";
diff --git a/hw/mips_fulong2e.c b/hw/mips_fulong2e.c
index 420fada..ec8c88e 100644
--- a/hw/mips_fulong2e.c
+++ b/hw/mips_fulong2e.c
@@ -140,7 +140,7 @@ static int64_t load_kernel (CPUState *env)
 
     /* Setup prom parameters. */
     prom_size = ENVP_NB_ENTRIES * (sizeof(int32_t) + ENVP_ENTRY_SIZE);
-    prom_buf = qemu_malloc(prom_size);
+    prom_buf = g_malloc(prom_size);
 
     prom_set(prom_buf, index++, "%s", loaderparams.kernel_filename);
     if (initrd_size > 0) {
@@ -313,7 +313,7 @@ static void mips_fulong2e_init(ram_addr_t ram_size, const char *boot_device,
         if (filename) {
             bios_size = load_image_targphys(filename, 0x1fc00000LL,
                                             BIOS_SIZE);
-            qemu_free(filename);
+            g_free(filename);
         } else {
             bios_size = -1;
         }
diff --git a/hw/mips_jazz.c b/hw/mips_jazz.c
index f6ab6dc..ea20510 100644
--- a/hw/mips_jazz.c
+++ b/hw/mips_jazz.c
@@ -158,7 +158,7 @@ void mips_jazz_init (ram_addr_t ram_size,
     if (filename) {
         bios_size = load_image_targphys(filename, 0xfff00000LL,
                                         MAGNUM_BIOS_SIZE);
-        qemu_free(filename);
+        g_free(filename);
     } else {
         bios_size = -1;
     }
@@ -207,7 +207,7 @@ void mips_jazz_init (ram_addr_t ram_size,
     for (n = 0; n < nb_nics; n++) {
         nd = &nd_table[n];
         if (!nd->model)
-            nd->model = qemu_strdup("dp83932");
+            nd->model = g_strdup("dp83932");
         if (strcmp(nd->model, "dp83932") == 0) {
             dp83932_init(nd, 0x80001000, 2, rc4030[4],
                          rc4030_opaque, rc4030_dma_memory_rw);
diff --git a/hw/mips_malta.c b/hw/mips_malta.c
index ed2a483..5bdb45b 100644
--- a/hw/mips_malta.c
+++ b/hw/mips_malta.c
@@ -433,7 +433,7 @@ static MaltaFPGAState *malta_fpga_init(target_phys_addr_t base, qemu_irq uart_ir
     MaltaFPGAState *s;
     int malta;
 
-    s = (MaltaFPGAState *)qemu_mallocz(sizeof(MaltaFPGAState));
+    s = (MaltaFPGAState *)g_malloc0(sizeof(MaltaFPGAState));
 
     malta = cpu_register_io_memory(malta_fpga_read,
                                    malta_fpga_write, s,
@@ -709,7 +709,7 @@ static int64_t load_kernel (void)
 
     /* Setup prom parameters. */
     prom_size = ENVP_NB_ENTRIES * (sizeof(int32_t) + ENVP_ENTRY_SIZE);
-    prom_buf = qemu_malloc(prom_size);
+    prom_buf = g_malloc(prom_size);
 
     prom_set(prom_buf, prom_index++, "%s", loaderparams.kernel_filename);
     if (initrd_size > 0) {
@@ -863,7 +863,7 @@ void mips_malta_init (ram_addr_t ram_size,
             if (filename) {
                 bios_size = load_image_targphys(filename, 0x1fc00000LL,
                                                 BIOS_SIZE);
-                qemu_free(filename);
+                g_free(filename);
             } else {
                 bios_size = -1;
             }
diff --git a/hw/mips_mipssim.c b/hw/mips_mipssim.c
index 380a7eb..0d46cc4 100644
--- a/hw/mips_mipssim.c
+++ b/hw/mips_mipssim.c
@@ -138,7 +138,7 @@ mips_mipssim_init (ram_addr_t ram_size,
         fprintf(stderr, "Unable to find CPU definition\n");
         exit(1);
     }
-    reset_info = qemu_mallocz(sizeof(ResetData));
+    reset_info = g_malloc0(sizeof(ResetData));
     reset_info->env = env;
     reset_info->vector = env->active_tc.PC;
     qemu_register_reset(main_cpu_reset, reset_info);
@@ -158,7 +158,7 @@ mips_mipssim_init (ram_addr_t ram_size,
     filename = qemu_find_file(QEMU_FILE_TYPE_BIOS, bios_name);
     if (filename) {
         bios_size = load_image_targphys(filename, 0x1fc00000LL, BIOS_SIZE);
-        qemu_free(filename);
+        g_free(filename);
     } else {
         bios_size = -1;
     }
diff --git a/hw/mips_r4k.c b/hw/mips_r4k.c
index 2834a46..9d90568 100644
--- a/hw/mips_r4k.c
+++ b/hw/mips_r4k.c
@@ -126,7 +126,7 @@ static int64_t load_kernel(void)
 
     /* Store command line.  */
     params_size = 264;
-    params_buf = qemu_malloc(params_size);
+    params_buf = g_malloc(params_size);
 
     params_buf[0] = tswap32(ram_size);
     params_buf[1] = tswap32(0x12345678);
@@ -186,7 +186,7 @@ void mips_r4k_init (ram_addr_t ram_size,
         fprintf(stderr, "Unable to find CPU definition\n");
         exit(1);
     }
-    reset_info = qemu_mallocz(sizeof(ResetData));
+    reset_info = g_malloc0(sizeof(ResetData));
     reset_info->env = env;
     reset_info->vector = env->active_tc.PC;
     qemu_register_reset(main_cpu_reset, reset_info);
@@ -248,7 +248,7 @@ void mips_r4k_init (ram_addr_t ram_size,
 		bios_name);
     }
     if (filename) {
-        qemu_free(filename);
+        g_free(filename);
     }
 
     if (kernel_filename) {
diff --git a/hw/mipsnet.c b/hw/mipsnet.c
index 0db3ba7..b889ee0 100644
--- a/hw/mipsnet.c
+++ b/hw/mipsnet.c
@@ -228,7 +228,7 @@ static void mipsnet_cleanup(VLANClientState *nc)
 
     isa_unassign_ioport(s->io_base, 36);
 
-    qemu_free(s);
+    g_free(s);
 }
 
 static NetClientInfo net_mipsnet_info = {
@@ -245,7 +245,7 @@ void mipsnet_init (int base, qemu_irq irq, NICInfo *nd)
 
     qemu_check_nic_model(nd, "mipsnet");
 
-    s = qemu_mallocz(sizeof(MIPSnetState));
+    s = g_malloc0(sizeof(MIPSnetState));
 
     register_ioport_write(base, 36, 1, mipsnet_ioport_write, s);
     register_ioport_read(base, 36, 1, mipsnet_ioport_read, s);
diff --git a/hw/msix.c b/hw/msix.c
index 8536c3f..b15bafc 100644
--- a/hw/msix.c
+++ b/hw/msix.c
@@ -219,10 +219,10 @@ int msix_init(struct PCIDevice *dev, unsigned short nentries,
     if (nentries > MSIX_MAX_ENTRIES)
         return -EINVAL;
 
-    dev->msix_entry_used = qemu_mallocz(MSIX_MAX_ENTRIES *
+    dev->msix_entry_used = g_malloc0(MSIX_MAX_ENTRIES *
                                         sizeof *dev->msix_entry_used);
 
-    dev->msix_table_page = qemu_mallocz(MSIX_PAGE_SIZE);
+    dev->msix_table_page = g_malloc0(MSIX_PAGE_SIZE);
     msix_mask_all(dev, nentries);
 
     memory_region_init_io(&dev->msix_mmio, &msix_mmio_ops, dev,
@@ -240,9 +240,9 @@ int msix_init(struct PCIDevice *dev, unsigned short nentries,
 err_config:
     dev->msix_entries_nr = 0;
     memory_region_destroy(&dev->msix_mmio);
-    qemu_free(dev->msix_table_page);
+    g_free(dev->msix_table_page);
     dev->msix_table_page = NULL;
-    qemu_free(dev->msix_entry_used);
+    g_free(dev->msix_entry_used);
     dev->msix_entry_used = NULL;
     return ret;
 }
@@ -268,9 +268,9 @@ int msix_uninit(PCIDevice *dev, MemoryRegion *bar)
     dev->msix_entries_nr = 0;
     memory_region_del_subregion(bar, &dev->msix_mmio);
     memory_region_destroy(&dev->msix_mmio);
-    qemu_free(dev->msix_table_page);
+    g_free(dev->msix_table_page);
     dev->msix_table_page = NULL;
-    qemu_free(dev->msix_entry_used);
+    g_free(dev->msix_entry_used);
     dev->msix_entry_used = NULL;
     dev->cap_present &= ~QEMU_PCI_CAP_MSIX;
     return 0;
diff --git a/hw/msmouse.c b/hw/msmouse.c
index 67c6cd4..b611c2f 100644
--- a/hw/msmouse.c
+++ b/hw/msmouse.c
@@ -61,14 +61,14 @@ static int msmouse_chr_write (struct CharDriverState *s, const uint8_t *buf, int
 
 static void msmouse_chr_close (struct CharDriverState *chr)
 {
-    qemu_free (chr);
+    g_free (chr);
 }
 
 int qemu_chr_open_msmouse(QemuOpts *opts, CharDriverState **_chr)
 {
     CharDriverState *chr;
 
-    chr = qemu_mallocz(sizeof(CharDriverState));
+    chr = g_malloc0(sizeof(CharDriverState));
     chr->chr_write = msmouse_chr_write;
     chr->chr_close = msmouse_chr_close;
 
diff --git a/hw/multiboot.c b/hw/multiboot.c
index a1d3f41..b4484a3 100644
--- a/hw/multiboot.c
+++ b/hw/multiboot.c
@@ -187,7 +187,7 @@ int load_multiboot(void *fw_cfg,
         mb_kernel_size = elf_high - elf_low;
         mh_entry_addr = elf_entry;
 
-        mbs.mb_buf = qemu_malloc(mb_kernel_size);
+        mbs.mb_buf = g_malloc(mb_kernel_size);
         if (rom_copy(mbs.mb_buf, mh_load_addr, mb_kernel_size) != mb_kernel_size) {
             fprintf(stderr, "Error while fetching elf kernel from rom\n");
             exit(1);
@@ -220,7 +220,7 @@ int load_multiboot(void *fw_cfg,
         mb_debug("qemu: loading multiboot kernel (%#x bytes) at %#x\n",
                  mb_load_size, mh_load_addr);
 
-        mbs.mb_buf = qemu_malloc(mb_kernel_size);
+        mbs.mb_buf = g_malloc(mb_kernel_size);
         fseek(f, mb_kernel_text_offset, SEEK_SET);
         if (fread(mbs.mb_buf, 1, mb_load_size, f) != mb_load_size) {
             fprintf(stderr, "fread() failed\n");
@@ -252,7 +252,7 @@ int load_multiboot(void *fw_cfg,
     mbs.mb_buf_size = TARGET_PAGE_ALIGN(mbs.mb_buf_size);
 
     /* enlarge mb_buf to hold cmdlines and mb-info structs */
-    mbs.mb_buf          = qemu_realloc(mbs.mb_buf, mbs.mb_buf_size);
+    mbs.mb_buf          = g_realloc(mbs.mb_buf, mbs.mb_buf_size);
     mbs.offset_cmdlines = mbs.offset_mbinfo + mbs.mb_mods_avail * MB_MOD_SIZE;
 
     if (initrd_filename) {
@@ -281,7 +281,7 @@ int load_multiboot(void *fw_cfg,
             }
 
             mbs.mb_buf_size = TARGET_PAGE_ALIGN(mb_mod_length + mbs.mb_buf_size);
-            mbs.mb_buf = qemu_realloc(mbs.mb_buf, mbs.mb_buf_size);
+            mbs.mb_buf = g_realloc(mbs.mb_buf, mbs.mb_buf_size);
 
             load_image(initrd_filename, (unsigned char *)mbs.mb_buf + offs);
             mb_add_mod(&mbs, mbs.mb_buf_phys + offs,
@@ -320,7 +320,7 @@ int load_multiboot(void *fw_cfg,
     mb_debug("           mb_mods_count = %d\n", mbs.mb_mods_count);
 
     /* save bootinfo off the stack */
-    mb_bootinfo_data = qemu_malloc(sizeof(bootinfo));
+    mb_bootinfo_data = g_malloc(sizeof(bootinfo));
     memcpy(mb_bootinfo_data, bootinfo, sizeof(bootinfo));
 
     /* Pass variables to option rom */
diff --git a/hw/nand.c b/hw/nand.c
index 28d9f0b..c27783e 100644
--- a/hw/nand.c
+++ b/hw/nand.c
@@ -399,7 +399,7 @@ static int nand_device_init(SysBusDevice *dev)
         pagesize += 1 << s->page_shift;
     }
     if (pagesize) {
-        s->storage = (uint8_t *) memset(qemu_malloc(s->pages * pagesize),
+        s->storage = (uint8_t *) memset(g_malloc(s->pages * pagesize),
                         0xff, s->pages * pagesize);
     }
     /* Give s->ioaddr a sane value in case we save state before it is used. */
diff --git a/hw/nseries.c b/hw/nseries.c
index 6a5575e..144fd5a 100644
--- a/hw/nseries.c
+++ b/hw/nseries.c
@@ -654,7 +654,7 @@ static uint32_t mipid_txrx(void *opaque, uint32_t cmd, int len)
 
 static void *mipid_init(void)
 {
-    struct mipid_s *s = (struct mipid_s *) qemu_mallocz(sizeof(*s));
+    struct mipid_s *s = (struct mipid_s *) g_malloc0(sizeof(*s));
 
     s->id = 0x838f03;
     mipid_reset(s);
@@ -710,10 +710,10 @@ static void n800_dss_init(struct rfbi_chip_s *chip)
     chip->write(chip->opaque, 1, 0x01);		/* Input Data Format */
     chip->write(chip->opaque, 1, 0x01);		/* Data Source Select */
 
-    fb_blank = memset(qemu_malloc(800 * 480 * 2), 0xff, 800 * 480 * 2);
+    fb_blank = memset(g_malloc(800 * 480 * 2), 0xff, 800 * 480 * 2);
     /* Display Memory Data Port */
     chip->block(chip->opaque, 1, fb_blank, 800 * 480 * 2, 800);
-    qemu_free(fb_blank);
+    g_free(fb_blank);
 }
 
 static void n8x0_dss_setup(struct n800_s *s)
@@ -1270,7 +1270,7 @@ static void n8x0_init(ram_addr_t ram_size, const char *boot_device,
                 const char *kernel_cmdline, const char *initrd_filename,
                 const char *cpu_model, struct arm_boot_info *binfo, int model)
 {
-    struct n800_s *s = (struct n800_s *) qemu_mallocz(sizeof(*s));
+    struct n800_s *s = (struct n800_s *) g_malloc0(sizeof(*s));
     int sdram_size = binfo->ram_size;
     DisplayState *ds;
 
diff --git a/hw/omap.h b/hw/omap.h
index a064353..2a6d589 100644
--- a/hw/omap.h
+++ b/hw/omap.h
@@ -1107,7 +1107,7 @@ inline static int debug_register_io_memory(CPUReadMemoryFunc * const *mem_read,
                                            CPUWriteMemoryFunc * const *mem_write,
                                            void *opaque)
 {
-    struct io_fn *s = qemu_malloc(sizeof(struct io_fn));
+    struct io_fn *s = g_malloc(sizeof(struct io_fn));
 
     s->mem_read = mem_read;
     s->mem_write = mem_write;
diff --git a/hw/omap1.c b/hw/omap1.c
index 400de47..614fd31 100644
--- a/hw/omap1.c
+++ b/hw/omap1.c
@@ -255,7 +255,7 @@ static struct omap_mpu_timer_s *omap_mpu_timer_init(target_phys_addr_t base,
 {
     int iomemtype;
     struct omap_mpu_timer_s *s = (struct omap_mpu_timer_s *)
-            qemu_mallocz(sizeof(struct omap_mpu_timer_s));
+            g_malloc0(sizeof(struct omap_mpu_timer_s));
 
     s->irq = irq;
     s->clk = clk;
@@ -379,7 +379,7 @@ static struct omap_watchdog_timer_s *omap_wd_timer_init(target_phys_addr_t base,
 {
     int iomemtype;
     struct omap_watchdog_timer_s *s = (struct omap_watchdog_timer_s *)
-            qemu_mallocz(sizeof(struct omap_watchdog_timer_s));
+            g_malloc0(sizeof(struct omap_watchdog_timer_s));
 
     s->timer.irq = irq;
     s->timer.clk = clk;
@@ -481,7 +481,7 @@ static struct omap_32khz_timer_s *omap_os_timer_init(target_phys_addr_t base,
 {
     int iomemtype;
     struct omap_32khz_timer_s *s = (struct omap_32khz_timer_s *)
-            qemu_mallocz(sizeof(struct omap_32khz_timer_s));
+            g_malloc0(sizeof(struct omap_32khz_timer_s));
 
     s->timer.irq = irq;
     s->timer.clk = clk;
@@ -1188,7 +1188,7 @@ static struct omap_tipb_bridge_s *omap_tipb_bridge_init(target_phys_addr_t base,
 {
     int iomemtype;
     struct omap_tipb_bridge_s *s = (struct omap_tipb_bridge_s *)
-            qemu_mallocz(sizeof(struct omap_tipb_bridge_s));
+            g_malloc0(sizeof(struct omap_tipb_bridge_s));
 
     s->abort = abort_irq;
     omap_tipb_bridge_reset(s);
@@ -2025,7 +2025,7 @@ struct omap_mpuio_s *omap_mpuio_init(target_phys_addr_t base,
 {
     int iomemtype;
     struct omap_mpuio_s *s = (struct omap_mpuio_s *)
-            qemu_mallocz(sizeof(struct omap_mpuio_s));
+            g_malloc0(sizeof(struct omap_mpuio_s));
 
     s->irq = gpio_int;
     s->kbd_irq = kbd_int;
@@ -2211,7 +2211,7 @@ struct omap_uwire_s *omap_uwire_init(target_phys_addr_t base,
 {
     int iomemtype;
     struct omap_uwire_s *s = (struct omap_uwire_s *)
-            qemu_mallocz(sizeof(struct omap_uwire_s));
+            g_malloc0(sizeof(struct omap_uwire_s));
 
     s->txirq = irq[0];
     s->rxirq = irq[1];
@@ -2819,7 +2819,7 @@ static struct omap_rtc_s *omap_rtc_init(target_phys_addr_t base,
 {
     int iomemtype;
     struct omap_rtc_s *s = (struct omap_rtc_s *)
-            qemu_mallocz(sizeof(struct omap_rtc_s));
+            g_malloc0(sizeof(struct omap_rtc_s));
 
     s->irq = irq[0];
     s->alarm = irq[1];
@@ -3339,7 +3339,7 @@ struct omap_mcbsp_s *omap_mcbsp_init(target_phys_addr_t base,
 {
     int iomemtype;
     struct omap_mcbsp_s *s = (struct omap_mcbsp_s *)
-            qemu_mallocz(sizeof(struct omap_mcbsp_s));
+            g_malloc0(sizeof(struct omap_mcbsp_s));
 
     s->txirq = irq[0];
     s->rxirq = irq[1];
@@ -3515,7 +3515,7 @@ static struct omap_lpg_s *omap_lpg_init(target_phys_addr_t base, omap_clk clk)
 {
     int iomemtype;
     struct omap_lpg_s *s = (struct omap_lpg_s *)
-            qemu_mallocz(sizeof(struct omap_lpg_s));
+            g_malloc0(sizeof(struct omap_lpg_s));
 
     s->tm = qemu_new_timer_ms(rt_clock, omap_lpg_tick, s);
 
@@ -3711,7 +3711,7 @@ struct omap_mpu_state_s *omap310_mpu_init(unsigned long sdram_size,
 {
     int i;
     struct omap_mpu_state_s *s = (struct omap_mpu_state_s *)
-            qemu_mallocz(sizeof(struct omap_mpu_state_s));
+            g_malloc0(sizeof(struct omap_mpu_state_s));
     ram_addr_t imif_base, emiff_base;
     qemu_irq *cpu_irq;
     qemu_irq dma_irqs[6];
diff --git a/hw/omap2.c b/hw/omap2.c
index c9b3540..3b51ac5 100644
--- a/hw/omap2.c
+++ b/hw/omap2.c
@@ -591,7 +591,7 @@ static struct omap_eac_s *omap_eac_init(struct omap_target_agent_s *ta,
 {
     int iomemtype;
     struct omap_eac_s *s = (struct omap_eac_s *)
-            qemu_mallocz(sizeof(struct omap_eac_s));
+            g_malloc0(sizeof(struct omap_eac_s));
 
     s->irq = irq;
     s->codec.rxdrq = *drq ++;
@@ -777,7 +777,7 @@ static struct omap_sti_s *omap_sti_init(struct omap_target_agent_s *ta,
 {
     int iomemtype;
     struct omap_sti_s *s = (struct omap_sti_s *)
-            qemu_mallocz(sizeof(struct omap_sti_s));
+            g_malloc0(sizeof(struct omap_sti_s));
 
     s->irq = irq;
     omap_sti_reset(s);
@@ -1790,7 +1790,7 @@ static struct omap_prcm_s *omap_prcm_init(struct omap_target_agent_s *ta,
 {
     int iomemtype;
     struct omap_prcm_s *s = (struct omap_prcm_s *)
-            qemu_mallocz(sizeof(struct omap_prcm_s));
+            g_malloc0(sizeof(struct omap_prcm_s));
 
     s->irq[0] = mpu_int;
     s->irq[1] = dsp_int;
@@ -2163,7 +2163,7 @@ static struct omap_sysctl_s *omap_sysctl_init(struct omap_target_agent_s *ta,
 {
     int iomemtype;
     struct omap_sysctl_s *s = (struct omap_sysctl_s *)
-            qemu_mallocz(sizeof(struct omap_sysctl_s));
+            g_malloc0(sizeof(struct omap_sysctl_s));
 
     s->mpu = mpu;
     omap_sysctl_reset(s);
@@ -2228,7 +2228,7 @@ struct omap_mpu_state_s *omap2420_mpu_init(unsigned long sdram_size,
                 const char *core)
 {
     struct omap_mpu_state_s *s = (struct omap_mpu_state_s *)
-            qemu_mallocz(sizeof(struct omap_mpu_state_s));
+            g_malloc0(sizeof(struct omap_mpu_state_s));
     ram_addr_t sram_base, q2_base;
     qemu_irq *cpu_irq;
     qemu_irq dma_irqs[4];
diff --git a/hw/omap_clk.c b/hw/omap_clk.c
index 577b326..8448006 100644
--- a/hw/omap_clk.c
+++ b/hw/omap_clk.c
@@ -1239,7 +1239,7 @@ void omap_clk_init(struct omap_mpu_state_s *mpu)
     for (i = onchip_clks, count = 0; *i; i ++)
         if ((*i)->flags & flag)
             count ++;
-    mpu->clks = (struct clk *) qemu_mallocz(sizeof(struct clk) * (count + 1));
+    mpu->clks = (struct clk *) g_malloc0(sizeof(struct clk) * (count + 1));
     for (i = onchip_clks, j = mpu->clks; *i; i ++)
         if ((*i)->flags & flag) {
             memcpy(j, *i, sizeof(struct clk));
diff --git a/hw/omap_dma.c b/hw/omap_dma.c
index 8e2dcc9..f943d4e 100644
--- a/hw/omap_dma.c
+++ b/hw/omap_dma.c
@@ -1620,7 +1620,7 @@ struct soc_dma_s *omap_dma_init(target_phys_addr_t base, qemu_irq *irqs,
 {
     int iomemtype, num_irqs, memsize, i;
     struct omap_dma_s *s = (struct omap_dma_s *)
-            qemu_mallocz(sizeof(struct omap_dma_s));
+            g_malloc0(sizeof(struct omap_dma_s));
 
     if (model <= omap_dma_3_1) {
         num_irqs = 6;
@@ -2039,7 +2039,7 @@ struct soc_dma_s *omap_dma4_init(target_phys_addr_t base, qemu_irq *irqs,
 {
     int iomemtype, i;
     struct omap_dma_s *s = (struct omap_dma_s *)
-            qemu_mallocz(sizeof(struct omap_dma_s));
+            g_malloc0(sizeof(struct omap_dma_s));
 
     s->model = omap_dma_4;
     s->chans = chans;
diff --git a/hw/omap_dss.c b/hw/omap_dss.c
index afe287a..c8387a8 100644
--- a/hw/omap_dss.c
+++ b/hw/omap_dss.c
@@ -627,7 +627,7 @@ static void omap_rfbi_transfer_start(struct omap_dss_s *s)
     }
     if (!data) {
         if (len > bounce_len) {
-            bounce_buffer = qemu_realloc(bounce_buffer, len);
+            bounce_buffer = g_realloc(bounce_buffer, len);
         }
         data = bounce_buffer;
         cpu_physical_memory_read(data_addr, data, len);
@@ -1030,7 +1030,7 @@ struct omap_dss_s *omap_dss_init(struct omap_target_agent_s *ta,
 {
     int iomemtype[5];
     struct omap_dss_s *s = (struct omap_dss_s *)
-            qemu_mallocz(sizeof(struct omap_dss_s));
+            g_malloc0(sizeof(struct omap_dss_s));
 
     s->irq = irq;
     s->drq = drq;
diff --git a/hw/omap_gpio.c b/hw/omap_gpio.c
index c23964c..42e59c3 100644
--- a/hw/omap_gpio.c
+++ b/hw/omap_gpio.c
@@ -696,8 +696,8 @@ static int omap2_gpio_init(SysBusDevice *dev)
     } else {
         s->modulecount = 6;
     }
-    s->modules = qemu_mallocz(s->modulecount * sizeof(struct omap2_gpio_s));
-    s->handler = qemu_mallocz(s->modulecount * 32 * sizeof(qemu_irq));
+    s->modules = g_malloc0(s->modulecount * sizeof(struct omap2_gpio_s));
+    s->handler = g_malloc0(s->modulecount * 32 * sizeof(qemu_irq));
     qdev_init_gpio_in(&dev->qdev, omap2_gpio_set, s->modulecount * 32);
     qdev_init_gpio_out(&dev->qdev, s->handler, s->modulecount * 32);
     for (i = 0; i < s->modulecount; i++) {
diff --git a/hw/omap_gpmc.c b/hw/omap_gpmc.c
index 8bf3343..13e3e00 100644
--- a/hw/omap_gpmc.c
+++ b/hw/omap_gpmc.c
@@ -385,7 +385,7 @@ struct omap_gpmc_s *omap_gpmc_init(target_phys_addr_t base, qemu_irq irq)
 {
     int iomemtype;
     struct omap_gpmc_s *s = (struct omap_gpmc_s *)
-            qemu_mallocz(sizeof(struct omap_gpmc_s));
+            g_malloc0(sizeof(struct omap_gpmc_s));
 
     omap_gpmc_reset(s);
 
diff --git a/hw/omap_gptimer.c b/hw/omap_gptimer.c
index f2a424f..704b000 100644
--- a/hw/omap_gptimer.c
+++ b/hw/omap_gptimer.c
@@ -465,7 +465,7 @@ struct omap_gp_timer_s *omap_gp_timer_init(struct omap_target_agent_s *ta,
 {
     int iomemtype;
     struct omap_gp_timer_s *s = (struct omap_gp_timer_s *)
-            qemu_mallocz(sizeof(struct omap_gp_timer_s));
+            g_malloc0(sizeof(struct omap_gp_timer_s));
 
     s->ta = ta;
     s->irq = irq;
diff --git a/hw/omap_i2c.c b/hw/omap_i2c.c
index 5cabb5a..11577b1 100644
--- a/hw/omap_i2c.c
+++ b/hw/omap_i2c.c
@@ -426,7 +426,7 @@ struct omap_i2c_s *omap_i2c_init(target_phys_addr_t base,
 {
     int iomemtype;
     struct omap_i2c_s *s = (struct omap_i2c_s *)
-            qemu_mallocz(sizeof(struct omap_i2c_s));
+            g_malloc0(sizeof(struct omap_i2c_s));
 
     /* TODO: set a value greater or equal to real hardware */
     s->revision = 0x11;
@@ -448,7 +448,7 @@ struct omap_i2c_s *omap2_i2c_init(struct omap_target_agent_s *ta,
 {
     int iomemtype;
     struct omap_i2c_s *s = (struct omap_i2c_s *)
-            qemu_mallocz(sizeof(struct omap_i2c_s));
+            g_malloc0(sizeof(struct omap_i2c_s));
 
     s->revision = 0x34;
     s->irq = irq;
diff --git a/hw/omap_intc.c b/hw/omap_intc.c
index 001e20b..f1f570e 100644
--- a/hw/omap_intc.c
+++ b/hw/omap_intc.c
@@ -358,7 +358,7 @@ struct omap_intr_handler_s *omap_inth_init(target_phys_addr_t base,
 {
     int iomemtype;
     struct omap_intr_handler_s *s = (struct omap_intr_handler_s *)
-            qemu_mallocz(sizeof(struct omap_intr_handler_s) +
+            g_malloc0(sizeof(struct omap_intr_handler_s) +
                             sizeof(struct omap_intr_handler_bank_s) * nbanks);
 
     s->parent_intr[0] = parent_irq;
@@ -577,7 +577,7 @@ struct omap_intr_handler_s *omap2_inth_init(target_phys_addr_t base,
 {
     int iomemtype;
     struct omap_intr_handler_s *s = (struct omap_intr_handler_s *)
-            qemu_mallocz(sizeof(struct omap_intr_handler_s) +
+            g_malloc0(sizeof(struct omap_intr_handler_s) +
                             sizeof(struct omap_intr_handler_bank_s) * nbanks);
 
     s->parent_intr[0] = parent_irq;
diff --git a/hw/omap_l4.c b/hw/omap_l4.c
index 59c84b1..a4a8883 100644
--- a/hw/omap_l4.c
+++ b/hw/omap_l4.c
@@ -120,7 +120,7 @@ struct omap_l4_s {
 
 struct omap_l4_s *omap_l4_init(target_phys_addr_t base, int ta_num)
 {
-    struct omap_l4_s *bus = qemu_mallocz(
+    struct omap_l4_s *bus = g_malloc0(
                     sizeof(*bus) + ta_num * sizeof(*bus->ta));
 
     bus->ta_num = ta_num;
@@ -128,19 +128,19 @@ struct omap_l4_s *omap_l4_init(target_phys_addr_t base, int ta_num)
 
 #ifdef L4_MUX_HACK
     omap_l4_io_entries = 1;
-    omap_l4_io_entry = qemu_mallocz(125 * sizeof(*omap_l4_io_entry));
+    omap_l4_io_entry = g_malloc0(125 * sizeof(*omap_l4_io_entry));
 
     omap_cpu_io_entry =
             cpu_register_io_memory(omap_l4_io_readfn,
                             omap_l4_io_writefn, bus, DEVICE_NATIVE_ENDIAN);
 # define L4_PAGES	(0xb4000 / TARGET_PAGE_SIZE)
-    omap_l4_io_readb_fn = qemu_mallocz(sizeof(void *) * L4_PAGES);
-    omap_l4_io_readh_fn = qemu_mallocz(sizeof(void *) * L4_PAGES);
-    omap_l4_io_readw_fn = qemu_mallocz(sizeof(void *) * L4_PAGES);
-    omap_l4_io_writeb_fn = qemu_mallocz(sizeof(void *) * L4_PAGES);
-    omap_l4_io_writeh_fn = qemu_mallocz(sizeof(void *) * L4_PAGES);
-    omap_l4_io_writew_fn = qemu_mallocz(sizeof(void *) * L4_PAGES);
-    omap_l4_io_opaque = qemu_mallocz(sizeof(void *) * L4_PAGES);
+    omap_l4_io_readb_fn = g_malloc0(sizeof(void *) * L4_PAGES);
+    omap_l4_io_readh_fn = g_malloc0(sizeof(void *) * L4_PAGES);
+    omap_l4_io_readw_fn = g_malloc0(sizeof(void *) * L4_PAGES);
+    omap_l4_io_writeb_fn = g_malloc0(sizeof(void *) * L4_PAGES);
+    omap_l4_io_writeh_fn = g_malloc0(sizeof(void *) * L4_PAGES);
+    omap_l4_io_writew_fn = g_malloc0(sizeof(void *) * L4_PAGES);
+    omap_l4_io_opaque = g_malloc0(sizeof(void *) * L4_PAGES);
 #endif
 
     return bus;
diff --git a/hw/omap_lcdc.c b/hw/omap_lcdc.c
index 0c2c550..a905422 100644
--- a/hw/omap_lcdc.c
+++ b/hw/omap_lcdc.c
@@ -441,7 +441,7 @@ struct omap_lcd_panel_s *omap_lcdc_init(target_phys_addr_t base, qemu_irq irq,
 {
     int iomemtype;
     struct omap_lcd_panel_s *s = (struct omap_lcd_panel_s *)
-            qemu_mallocz(sizeof(struct omap_lcd_panel_s));
+            g_malloc0(sizeof(struct omap_lcd_panel_s));
 
     s->irq = irq;
     s->dma = dma;
diff --git a/hw/omap_mmc.c b/hw/omap_mmc.c
index e9ec2f3..a1afeb5 100644
--- a/hw/omap_mmc.c
+++ b/hw/omap_mmc.c
@@ -576,7 +576,7 @@ struct omap_mmc_s *omap_mmc_init(target_phys_addr_t base,
 {
     int iomemtype;
     struct omap_mmc_s *s = (struct omap_mmc_s *)
-            qemu_mallocz(sizeof(struct omap_mmc_s));
+            g_malloc0(sizeof(struct omap_mmc_s));
 
     s->irq = irq;
     s->dma = dma;
@@ -602,7 +602,7 @@ struct omap_mmc_s *omap2_mmc_init(struct omap_target_agent_s *ta,
 {
     int iomemtype;
     struct omap_mmc_s *s = (struct omap_mmc_s *)
-            qemu_mallocz(sizeof(struct omap_mmc_s));
+            g_malloc0(sizeof(struct omap_mmc_s));
 
     s->irq = irq;
     s->dma = dma;
diff --git a/hw/omap_sdrc.c b/hw/omap_sdrc.c
index e183762..1df2fd8 100644
--- a/hw/omap_sdrc.c
+++ b/hw/omap_sdrc.c
@@ -153,7 +153,7 @@ struct omap_sdrc_s *omap_sdrc_init(target_phys_addr_t base)
 {
     int iomemtype;
     struct omap_sdrc_s *s = (struct omap_sdrc_s *)
-            qemu_mallocz(sizeof(struct omap_sdrc_s));
+            g_malloc0(sizeof(struct omap_sdrc_s));
 
     omap_sdrc_reset(s);
 
diff --git a/hw/omap_spi.c b/hw/omap_spi.c
index a6b0349..6030ad9 100644
--- a/hw/omap_spi.c
+++ b/hw/omap_spi.c
@@ -315,7 +315,7 @@ struct omap_mcspi_s *omap_mcspi_init(struct omap_target_agent_s *ta, int chnum,
 {
     int iomemtype;
     struct omap_mcspi_s *s = (struct omap_mcspi_s *)
-            qemu_mallocz(sizeof(struct omap_mcspi_s));
+            g_malloc0(sizeof(struct omap_mcspi_s));
     struct omap_mcspi_ch_s *ch = s->ch;
 
     s->irq = irq;
diff --git a/hw/omap_synctimer.c b/hw/omap_synctimer.c
index 67f65e6..b47ca88 100644
--- a/hw/omap_synctimer.c
+++ b/hw/omap_synctimer.c
@@ -86,7 +86,7 @@ static CPUWriteMemoryFunc * const omap_synctimer_writefn[] = {
 struct omap_synctimer_s *omap_synctimer_init(struct omap_target_agent_s *ta,
                 struct omap_mpu_state_s *mpu, omap_clk fclk, omap_clk iclk)
 {
-    struct omap_synctimer_s *s = qemu_mallocz(sizeof(*s));
+    struct omap_synctimer_s *s = g_malloc0(sizeof(*s));
 
     omap_synctimer_reset(s);
     omap_l4_attach(ta, 0, l4_register_io_memory(
diff --git a/hw/omap_uart.c b/hw/omap_uart.c
index 9cee81d..09ae9f8 100644
--- a/hw/omap_uart.c
+++ b/hw/omap_uart.c
@@ -55,7 +55,7 @@ struct omap_uart_s *omap_uart_init(target_phys_addr_t base,
                 const char *label, CharDriverState *chr)
 {
     struct omap_uart_s *s = (struct omap_uart_s *)
-            qemu_mallocz(sizeof(struct omap_uart_s));
+            g_malloc0(sizeof(struct omap_uart_s));
 
     s->base = base;
     s->fclk = fclk;
diff --git a/hw/onenand.c b/hw/onenand.c
index b0cbebc..c37cf59 100644
--- a/hw/onenand.c
+++ b/hw/onenand.c
@@ -186,7 +186,7 @@ static inline int onenand_prog_main(OneNANDState *s, int sec, int secn,
         const uint8_t *sp = (const uint8_t *) src;
         uint8_t *dp = 0;
         if (s->bdrv_cur) {
-            dp = qemu_malloc(size);
+            dp = g_malloc(size);
             if (!dp || bdrv_read(s->bdrv_cur, sec, dp, secn) < 0) {
                 result = 1;
             }
@@ -207,7 +207,7 @@ static inline int onenand_prog_main(OneNANDState *s, int sec, int secn,
             }
         }
         if (dp && s->bdrv_cur) {
-            qemu_free(dp);
+            g_free(dp);
         }
     }
 
@@ -239,7 +239,7 @@ static inline int onenand_prog_spare(OneNANDState *s, int sec, int secn,
         const uint8_t *sp = (const uint8_t *) src;
         uint8_t *dp = 0, *dpp = 0;
         if (s->bdrv_cur) {
-            dp = qemu_malloc(512);
+            dp = g_malloc(512);
             if (!dp || bdrv_read(s->bdrv_cur,
                                 s->secs_cur + (sec >> 5),
                                 dp, 1) < 0) {
@@ -265,7 +265,7 @@ static inline int onenand_prog_spare(OneNANDState *s, int sec, int secn,
             }
         }
         if (dp) {
-            qemu_free(dp);
+            g_free(dp);
         }
     }
     return result;
@@ -274,13 +274,13 @@ static inline int onenand_prog_spare(OneNANDState *s, int sec, int secn,
 static inline int onenand_erase(OneNANDState *s, int sec, int num)
 {
     uint8_t *blankbuf, *tmpbuf;
-    blankbuf = qemu_malloc(512);
+    blankbuf = g_malloc(512);
     if (!blankbuf) {
         return 1;
     }
-    tmpbuf = qemu_malloc(512);
+    tmpbuf = g_malloc(512);
     if (!tmpbuf) {
-        qemu_free(blankbuf);
+        g_free(blankbuf);
         return 1;
     }
     memset(blankbuf, 0xff, 512);
@@ -307,13 +307,13 @@ static inline int onenand_erase(OneNANDState *s, int sec, int num)
         }
     }
 
-    qemu_free(tmpbuf);
-    qemu_free(blankbuf);
+    g_free(tmpbuf);
+    g_free(blankbuf);
     return 0;
 
 fail:
-    qemu_free(tmpbuf);
-    qemu_free(blankbuf);
+    g_free(tmpbuf);
+    g_free(blankbuf);
     return 1;
 }
 
@@ -700,7 +700,7 @@ void *onenand_init(BlockDriverState *bdrv,
                 uint16_t man_id, uint16_t dev_id, uint16_t ver_id,
                 int regshift, qemu_irq irq)
 {
-    OneNANDState *s = (OneNANDState *) qemu_mallocz(sizeof(*s));
+    OneNANDState *s = (OneNANDState *) g_malloc0(sizeof(*s));
     uint32_t size = 1 << (24 + ((dev_id >> 4) & 7));
     void *ram;
 
@@ -712,16 +712,16 @@ void *onenand_init(BlockDriverState *bdrv,
     s->id.ver = ver_id;
     s->blocks = size >> BLOCK_SHIFT;
     s->secs = size >> 9;
-    s->blockwp = qemu_malloc(s->blocks);
+    s->blockwp = g_malloc(s->blocks);
     s->density_mask = (dev_id & 0x08) ? (1 << (6 + ((dev_id >> 4) & 7))) : 0;
     s->iomemtype = cpu_register_io_memory(onenand_readfn,
                     onenand_writefn, s, DEVICE_NATIVE_ENDIAN);
     s->bdrv = bdrv;
     if (!s->bdrv) {
-        s->image = memset(qemu_malloc(size + (size >> 5)),
+        s->image = memset(g_malloc(size + (size >> 5)),
                         0xff, size + (size >> 5));
     }
-    s->otp = memset(qemu_malloc((64 + 2) << PAGE_SHIFT),
+    s->otp = memset(g_malloc((64 + 2) << PAGE_SHIFT),
                     0xff, (64 + 2) << PAGE_SHIFT);
     s->ram = qemu_ram_alloc(NULL, "onenand.ram", 0xc000 << s->shift);
     ram = qemu_get_ram_ptr(s->ram);
diff --git a/hw/openpic.c b/hw/openpic.c
index ccd4a14..26c96e2 100644
--- a/hw/openpic.c
+++ b/hw/openpic.c
@@ -1180,7 +1180,7 @@ qemu_irq *openpic_init (PCIBus *bus, MemoryRegion **pmem, int nb_cpus,
         pci_register_bar(&opp->pci_dev, 0,
                          PCI_BASE_ADDRESS_SPACE_MEMORY, &opp->mem);
     } else {
-        opp = qemu_mallocz(sizeof(openpic_t));
+        opp = g_malloc0(sizeof(openpic_t));
         memory_region_init_io(&opp->mem, &openpic_ops, opp, "openpic", 0x40000);
     }
 
@@ -1644,7 +1644,7 @@ qemu_irq *mpic_init (target_phys_addr_t base, int nb_cpus,
     if (nb_cpus != 1)
         return NULL;
 
-    mpp = qemu_mallocz(sizeof(openpic_t));
+    mpp = g_malloc0(sizeof(openpic_t));
 
     for (i = 0; i < sizeof(list)/sizeof(list[0]); i++) {
         int mem_index;
@@ -1676,6 +1676,6 @@ qemu_irq *mpic_init (target_phys_addr_t base, int nb_cpus,
     return qemu_allocate_irqs(openpic_set_irq, mpp, mpp->max_irq);
 
 free:
-    qemu_free(mpp);
+    g_free(mpp);
     return NULL;
 }
diff --git a/hw/parallel.c b/hw/parallel.c
index cc853a5..71f30ea 100644
--- a/hw/parallel.c
+++ b/hw/parallel.c
@@ -565,7 +565,7 @@ bool parallel_mm_init(target_phys_addr_t base, int it_shift, qemu_irq irq,
     ParallelState *s;
     int io_sw;
 
-    s = qemu_mallocz(sizeof(ParallelState));
+    s = g_malloc0(sizeof(ParallelState));
     s->irq = irq;
     s->chr = chr;
     s->it_shift = it_shift;
diff --git a/hw/pc.c b/hw/pc.c
index 4b07b35..7be60a4 100644
--- a/hw/pc.c
+++ b/hw/pc.c
@@ -617,7 +617,7 @@ static void *bochs_bios_init(void)
      * of nodes, one word for each VCPU->node and one word for each node to
      * hold the amount of memory.
      */
-    numa_fw_cfg = qemu_mallocz((1 + smp_cpus + nb_numa_nodes) * 8);
+    numa_fw_cfg = g_malloc0((1 + smp_cpus + nb_numa_nodes) * 8);
     numa_fw_cfg[0] = cpu_to_le64(nb_numa_nodes);
     for (i = 0; i < smp_cpus; i++) {
         for (j = 0; j < nb_numa_nodes; j++) {
@@ -788,7 +788,7 @@ static void load_linux(void *fw_cfg,
 
         initrd_addr = (initrd_max-initrd_size) & ~4095;
 
-        initrd_data = qemu_malloc(initrd_size);
+        initrd_data = g_malloc(initrd_size);
         load_image(initrd_filename, initrd_data);
 
         fw_cfg_add_i32(fw_cfg, FW_CFG_INITRD_ADDR, initrd_addr);
@@ -806,8 +806,8 @@ static void load_linux(void *fw_cfg,
     setup_size = (setup_size+1)*512;
     kernel_size -= setup_size;
 
-    setup  = qemu_malloc(setup_size);
-    kernel = qemu_malloc(kernel_size);
+    setup  = g_malloc(setup_size);
+    kernel = g_malloc(kernel_size);
     fseek(f, 0, SEEK_SET);
     if (fread(setup, 1, setup_size, f) != setup_size) {
         fprintf(stderr, "fread() failed\n");
@@ -978,15 +978,15 @@ void pc_memory_init(MemoryRegion *system_memory,
      * aliases to address portions of it, mostly for backwards compatiblity
      * with older qemus that used qemu_ram_alloc().
      */
-    ram = qemu_malloc(sizeof(*ram));
+    ram = g_malloc(sizeof(*ram));
     memory_region_init_ram(ram, NULL, "pc.ram",
                            below_4g_mem_size + above_4g_mem_size);
-    ram_below_4g = qemu_malloc(sizeof(*ram_below_4g));
+    ram_below_4g = g_malloc(sizeof(*ram_below_4g));
     memory_region_init_alias(ram_below_4g, "ram-below-4g", ram,
                              0, below_4g_mem_size);
     memory_region_add_subregion(system_memory, 0, ram_below_4g);
     if (above_4g_mem_size > 0) {
-        ram_above_4g = qemu_malloc(sizeof(*ram_above_4g));
+        ram_above_4g = g_malloc(sizeof(*ram_above_4g));
         memory_region_init_alias(ram_above_4g, "ram-above-4g", ram,
                                  below_4g_mem_size, above_4g_mem_size);
         memory_region_add_subregion(system_memory, 0x100000000ULL,
@@ -1006,7 +1006,7 @@ void pc_memory_init(MemoryRegion *system_memory,
         (bios_size % 65536) != 0) {
         goto bios_error;
     }
-    bios = qemu_malloc(sizeof(*bios));
+    bios = g_malloc(sizeof(*bios));
     memory_region_init_ram(bios, NULL, "pc.bios", bios_size);
     memory_region_set_readonly(bios, true);
     ret = rom_add_file_fixed(bios_name, (uint32_t)(-bios_size), -1);
@@ -1016,13 +1016,13 @@ void pc_memory_init(MemoryRegion *system_memory,
         exit(1);
     }
     if (filename) {
-        qemu_free(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 = qemu_malloc(sizeof(*isa_bios));
+    isa_bios = g_malloc(sizeof(*isa_bios));
     memory_region_init_alias(isa_bios, "isa-bios", bios,
                              bios_size - isa_bios_size, isa_bios_size);
     memory_region_add_subregion_overlap(system_memory,
@@ -1031,7 +1031,7 @@ void pc_memory_init(MemoryRegion *system_memory,
                                         1);
     memory_region_set_readonly(isa_bios, true);
 
-    option_rom_mr = qemu_malloc(sizeof(*option_rom_mr));
+    option_rom_mr = g_malloc(sizeof(*option_rom_mr));
     memory_region_init_ram(option_rom_mr, NULL, "pc.rom", PC_ROM_SIZE);
     memory_region_add_subregion_overlap(system_memory,
                                         PC_ROM_MIN_VGA,
diff --git a/hw/pc_piix.c b/hw/pc_piix.c
index 7dd5008..a9fe596 100644
--- a/hw/pc_piix.c
+++ b/hw/pc_piix.c
@@ -121,7 +121,7 @@ static void pc_init1(MemoryRegion *system_memory,
     } else {
         i8259 = xen_interrupt_controller_init();
     }
-    isa_irq_state = qemu_mallocz(sizeof(*isa_irq_state));
+    isa_irq_state = g_malloc0(sizeof(*isa_irq_state));
     isa_irq_state->i8259 = i8259;
     if (pci_enabled) {
         ioapic_init(isa_irq_state);
diff --git a/hw/pci.c b/hw/pci.c
index dc7271a..4dc13d2 100644
--- a/hw/pci.c
+++ b/hw/pci.c
@@ -223,7 +223,7 @@ static int pcibus_reset(BusState *qbus)
 static void pci_host_bus_register(int domain, PCIBus *bus)
 {
     struct PCIHostBus *host;
-    host = qemu_mallocz(sizeof(*host));
+    host = g_malloc0(sizeof(*host));
     host->domain = domain;
     host->bus = bus;
     QLIST_INSERT_HEAD(&host_buses, host, next);
@@ -288,7 +288,7 @@ PCIBus *pci_bus_new(DeviceState *parent, const char *name,
 {
     PCIBus *bus;
 
-    bus = qemu_mallocz(sizeof(*bus));
+    bus = g_malloc0(sizeof(*bus));
     bus->qbus.qdev_allocated = 1;
     pci_bus_new_inplace(bus, parent, name, address_space_mem,
                         address_space_io, devfn_min);
@@ -302,7 +302,7 @@ void pci_bus_irqs(PCIBus *bus, pci_set_irq_fn set_irq, pci_map_irq_fn map_irq,
     bus->map_irq = map_irq;
     bus->irq_opaque = irq_opaque;
     bus->nirq = nirq;
-    bus->irq_count = qemu_mallocz(nirq * sizeof(bus->irq_count[0]));
+    bus->irq_count = g_malloc0(nirq * sizeof(bus->irq_count[0]));
 }
 
 void pci_bus_hotplug(PCIBus *bus, pci_hotplug_fn hotplug, DeviceState *qdev)
@@ -346,13 +346,13 @@ static int get_pci_config_device(QEMUFile *f, void *pv, size_t size)
     int i;
 
     assert(size == pci_config_size(s));
-    config = qemu_malloc(size);
+    config = g_malloc(size);
 
     qemu_get_buffer(f, config, size);
     for (i = 0; i < size; ++i) {
         if ((config[i] ^ s->config[i]) &
             s->cmask[i] & ~s->wmask[i] & ~s->w1cmask[i]) {
-            qemu_free(config);
+            g_free(config);
             return -EINVAL;
         }
     }
@@ -360,7 +360,7 @@ static int get_pci_config_device(QEMUFile *f, void *pv, size_t size)
 
     pci_update_mappings(s);
 
-    qemu_free(config);
+    g_free(config);
     return 0;
 }
 
@@ -720,20 +720,20 @@ static void pci_config_alloc(PCIDevice *pci_dev)
 {
     int config_size = pci_config_size(pci_dev);
 
-    pci_dev->config = qemu_mallocz(config_size);
-    pci_dev->cmask = qemu_mallocz(config_size);
-    pci_dev->wmask = qemu_mallocz(config_size);
-    pci_dev->w1cmask = qemu_mallocz(config_size);
-    pci_dev->used = qemu_mallocz(config_size);
+    pci_dev->config = g_malloc0(config_size);
+    pci_dev->cmask = g_malloc0(config_size);
+    pci_dev->wmask = g_malloc0(config_size);
+    pci_dev->w1cmask = g_malloc0(config_size);
+    pci_dev->used = g_malloc0(config_size);
 }
 
 static void pci_config_free(PCIDevice *pci_dev)
 {
-    qemu_free(pci_dev->config);
-    qemu_free(pci_dev->cmask);
-    qemu_free(pci_dev->wmask);
-    qemu_free(pci_dev->w1cmask);
-    qemu_free(pci_dev->used);
+    g_free(pci_dev->config);
+    g_free(pci_dev->cmask);
+    g_free(pci_dev->wmask);
+    g_free(pci_dev->w1cmask);
+    g_free(pci_dev->used);
 }
 
 /* -1 for devfn means auto assign */
@@ -825,7 +825,7 @@ PCIDevice *pci_register_device(PCIBus *bus, const char *name,
         .config_write = config_write,
     };
 
-    pci_dev = qemu_mallocz(instance_size);
+    pci_dev = g_malloc0(instance_size);
     pci_dev = do_pci_register_device(pci_dev, bus, name, devfn, &info);
     if (pci_dev == NULL) {
         hw_error("PCI: can't register device\n");
@@ -865,7 +865,7 @@ static int pci_unregister_device(DeviceState *dev)
 
     pci_unregister_io_regions(pci_dev);
     pci_del_option_rom(pci_dev);
-    qemu_free(pci_dev->romfile);
+    g_free(pci_dev->romfile);
     do_pci_unregister_device(pci_dev);
     return 0;
 }
@@ -1680,7 +1680,7 @@ static int pci_qdev_init(DeviceState *qdev, DeviceInfo *base)
     /* rom loading */
     is_default_rom = false;
     if (pci_dev->romfile == NULL && info->romfile != NULL) {
-        pci_dev->romfile = qemu_strdup(info->romfile);
+        pci_dev->romfile = g_strdup(info->romfile);
         is_default_rom = true;
     }
     pci_add_option_rom(pci_dev, is_default_rom);
@@ -1896,14 +1896,14 @@ static int pci_add_option_rom(PCIDevice *pdev, bool is_default_rom)
 
     path = qemu_find_file(QEMU_FILE_TYPE_BIOS, pdev->romfile);
     if (path == NULL) {
-        path = qemu_strdup(pdev->romfile);
+        path = g_strdup(pdev->romfile);
     }
 
     size = get_image_size(path);
     if (size < 0) {
         error_report("%s: failed to find romfile \"%s\"",
                      __FUNCTION__, pdev->romfile);
-        qemu_free(path);
+        g_free(path);
         return -1;
     }
     if (size & (size - 1)) {
@@ -1918,7 +1918,7 @@ static int pci_add_option_rom(PCIDevice *pdev, bool is_default_rom)
     memory_region_init_ram(&pdev->rom, &pdev->qdev, name, size);
     ptr = memory_region_get_ram_ptr(&pdev->rom);
     load_image(path, ptr);
-    qemu_free(path);
+    g_free(path);
 
     if (is_default_rom) {
         /* Only the default rom images will be patched (if needed). */
@@ -2108,7 +2108,7 @@ static char *pcibus_get_dev_path(DeviceState *dev)
     path_len = domain_len + slot_len * slot_depth;
 
     /* Allocate memory, fill in the terminating null byte. */
-    path = qemu_malloc(path_len + 1 /* For '\0' */);
+    path = g_malloc(path_len + 1 /* For '\0' */);
     path[path_len] = '\0';
 
     /* First field is the domain. */
diff --git a/hw/pcie_aer.c b/hw/pcie_aer.c
index be019c7..2ae65ec 100644
--- a/hw/pcie_aer.c
+++ b/hw/pcie_aer.c
@@ -111,7 +111,7 @@ int pcie_aer_init(PCIDevice *dev, uint16_t offset)
     if (dev->exp.aer_log.log_max > PCIE_AER_LOG_MAX_LIMIT) {
         return -EINVAL;
     }
-    dev->exp.aer_log.log = qemu_mallocz(sizeof dev->exp.aer_log.log[0] *
+    dev->exp.aer_log.log = g_malloc0(sizeof dev->exp.aer_log.log[0] *
                                         dev->exp.aer_log.log_max);
 
     pci_set_long(dev->w1cmask + offset + PCI_ERR_UNCOR_STATUS,
@@ -165,7 +165,7 @@ int pcie_aer_init(PCIDevice *dev, uint16_t offset)
 
 void pcie_aer_exit(PCIDevice *dev)
 {
-    qemu_free(dev->exp.aer_log.log);
+    g_free(dev->exp.aer_log.log);
 }
 
 static void pcie_aer_update_uncor_status(PCIDevice *dev)
diff --git a/hw/pcie_port.c b/hw/pcie_port.c
index 340dcdb..8a36f5c 100644
--- a/hw/pcie_port.c
+++ b/hw/pcie_port.c
@@ -76,7 +76,7 @@ void pcie_chassis_create(uint8_t chassis_number)
     if (c) {
         return;
     }
-    c = qemu_mallocz(sizeof(*c));
+    c = g_malloc0(sizeof(*c));
     c->number = chassis_number;
     QLIST_INIT(&c->slots);
     QLIST_INSERT_HEAD(&chassis, c, next);
diff --git a/hw/pckbd.c b/hw/pckbd.c
index ae65c04..a272ccd 100644
--- a/hw/pckbd.c
+++ b/hw/pckbd.c
@@ -416,7 +416,7 @@ void i8042_mm_init(qemu_irq kbd_irq, qemu_irq mouse_irq,
                    target_phys_addr_t base, ram_addr_t size,
                    target_phys_addr_t mask)
 {
-    KBDState *s = qemu_mallocz(sizeof(KBDState));
+    KBDState *s = g_malloc0(sizeof(KBDState));
     int s_io_memory;
 
     s->irq_kbd = kbd_irq;
diff --git a/hw/petalogix_ml605_mmu.c b/hw/petalogix_ml605_mmu.c
index 8213902..e3a66e5 100644
--- a/hw/petalogix_ml605_mmu.c
+++ b/hw/petalogix_ml605_mmu.c
@@ -88,7 +88,7 @@ static int petalogix_load_device_tree(target_phys_addr_t addr,
         path = qemu_find_file(QEMU_FILE_TYPE_BIOS, BINARY_DEVICE_TREE_FILE);
         if (path) {
             fdt = load_device_tree(path, &fdt_size);
-            qemu_free(path);
+            g_free(path);
         }
         if (!fdt) {
             return 0;
@@ -108,7 +108,7 @@ static int petalogix_load_device_tree(target_phys_addr_t addr,
         path = qemu_find_file(QEMU_FILE_TYPE_BIOS, BINARY_DEVICE_TREE_FILE);
         if (path) {
             fdt_size = load_image_targphys(path, addr, 0x10000);
-            qemu_free(path);
+            g_free(path);
         }
     }
 
diff --git a/hw/petalogix_s3adsp1800_mmu.c b/hw/petalogix_s3adsp1800_mmu.c
index 4dcdfbd..589e8ca 100644
--- a/hw/petalogix_s3adsp1800_mmu.c
+++ b/hw/petalogix_s3adsp1800_mmu.c
@@ -75,7 +75,7 @@ static int petalogix_load_device_tree(target_phys_addr_t addr,
         path = qemu_find_file(QEMU_FILE_TYPE_BIOS, BINARY_DEVICE_TREE_FILE);
         if (path) {
             fdt = load_device_tree(path, &fdt_size);
-            qemu_free(path);
+            g_free(path);
         }
         if (!fdt)
             return 0;
@@ -93,7 +93,7 @@ static int petalogix_load_device_tree(target_phys_addr_t addr,
         path = qemu_find_file(QEMU_FILE_TYPE_BIOS, BINARY_DEVICE_TREE_FILE);
         if (path) {
             fdt_size = load_image_targphys(path, addr, 0x10000);
-	    qemu_free(path);
+	    g_free(path);
         }
     }
 
diff --git a/hw/pflash_cfi01.c b/hw/pflash_cfi01.c
index 90fdc84..90e1301 100644
--- a/hw/pflash_cfi01.c
+++ b/hw/pflash_cfi01.c
@@ -594,7 +594,7 @@ pflash_t *pflash_cfi01_register(target_phys_addr_t base, ram_addr_t off,
         return NULL;
 #endif
 
-    pfl = qemu_mallocz(sizeof(pflash_t));
+    pfl = g_malloc0(sizeof(pflash_t));
 
     /* FIXME: Allocate ram ourselves.  */
     pfl->storage = qemu_get_ram_ptr(off);
@@ -617,7 +617,7 @@ pflash_t *pflash_cfi01_register(target_phys_addr_t base, ram_addr_t off,
         ret = bdrv_read(pfl->bs, 0, pfl->storage, total_len >> 9);
         if (ret < 0) {
             cpu_unregister_io_memory(pfl->fl_mem);
-            qemu_free(pfl);
+            g_free(pfl);
             return NULL;
         }
     }
diff --git a/hw/pflash_cfi02.c b/hw/pflash_cfi02.c
index 725cd1e..ac5115e 100644
--- a/hw/pflash_cfi02.c
+++ b/hw/pflash_cfi02.c
@@ -617,7 +617,7 @@ pflash_t *pflash_cfi02_register(target_phys_addr_t base, ram_addr_t off,
         total_len != (32 * 1024 * 1024) && total_len != (64 * 1024 * 1024))
         return NULL;
 #endif
-    pfl = qemu_mallocz(sizeof(pflash_t));
+    pfl = g_malloc0(sizeof(pflash_t));
     /* FIXME: Allocate ram ourselves.  */
     pfl->storage = qemu_get_ram_ptr(off);
     if (be) {
@@ -640,7 +640,7 @@ pflash_t *pflash_cfi02_register(target_phys_addr_t base, ram_addr_t off,
         ret = bdrv_read(pfl->bs, 0, pfl->storage, chip_len >> 9);
         if (ret < 0) {
             cpu_unregister_io_memory(pfl->fl_mem);
-            qemu_free(pfl);
+            g_free(pfl);
             return NULL;
         }
     }
diff --git a/hw/ppc.c b/hw/ppc.c
index 9157719..8870748 100644
--- a/hw/ppc.c
+++ b/hw/ppc.c
@@ -761,7 +761,7 @@ clk_setup_cb cpu_ppc_tb_init (CPUState *env, uint32_t freq)
 {
     ppc_tb_t *tb_env;
 
-    tb_env = qemu_mallocz(sizeof(ppc_tb_t));
+    tb_env = g_malloc0(sizeof(ppc_tb_t));
     env->tb_env = tb_env;
     /* Create new timer */
     tb_env->decr_timer = qemu_new_timer_ns(vm_clock, &cpu_ppc_decr_cb, env);
@@ -1038,9 +1038,9 @@ clk_setup_cb ppc_emb_timers_init (CPUState *env, uint32_t freq,
     ppc_tb_t *tb_env;
     ppcemb_timer_t *ppcemb_timer;
 
-    tb_env = qemu_mallocz(sizeof(ppc_tb_t));
+    tb_env = g_malloc0(sizeof(ppc_tb_t));
     env->tb_env = tb_env;
-    ppcemb_timer = qemu_mallocz(sizeof(ppcemb_timer_t));
+    ppcemb_timer = g_malloc0(sizeof(ppcemb_timer_t));
     tb_env->tb_freq = freq;
     tb_env->decr_freq = freq;
     tb_env->opaque = ppcemb_timer;
@@ -1145,7 +1145,7 @@ int ppc_dcr_init (CPUState *env, int (*read_error)(int dcrn),
 {
     ppc_dcr_t *dcr_env;
 
-    dcr_env = qemu_mallocz(sizeof(ppc_dcr_t));
+    dcr_env = g_malloc0(sizeof(ppc_dcr_t));
     dcr_env->read_error = read_error;
     dcr_env->write_error = write_error;
     env->dcr_env = dcr_env;
diff --git a/hw/ppc405_boards.c b/hw/ppc405_boards.c
index ad27181..34f9350 100644
--- a/hw/ppc405_boards.c
+++ b/hw/ppc405_boards.c
@@ -162,7 +162,7 @@ static void ref405ep_fpga_init (uint32_t base)
     ref405ep_fpga_t *fpga;
     int fpga_memory;
 
-    fpga = qemu_mallocz(sizeof(ref405ep_fpga_t));
+    fpga = g_malloc0(sizeof(ref405ep_fpga_t));
     fpga_memory = cpu_register_io_memory(ref405ep_fpga_read,
                                          ref405ep_fpga_write, fpga,
                                          DEVICE_NATIVE_ENDIAN);
@@ -246,7 +246,7 @@ static void ref405ep_init (ram_addr_t ram_size,
         filename = qemu_find_file(QEMU_FILE_TYPE_BIOS, bios_name);
         if (filename) {
             bios_size = load_image(filename, qemu_get_ram_ptr(bios_offset));
-            qemu_free(filename);
+            g_free(filename);
         } else {
             bios_size = -1;
         }
@@ -487,7 +487,7 @@ static void taihu_cpld_init (uint32_t base)
     taihu_cpld_t *cpld;
     int cpld_memory;
 
-    cpld = qemu_mallocz(sizeof(taihu_cpld_t));
+    cpld = g_malloc0(sizeof(taihu_cpld_t));
     cpld_memory = cpu_register_io_memory(taihu_cpld_read,
                                          taihu_cpld_write, cpld,
                                          DEVICE_NATIVE_ENDIAN);
@@ -560,7 +560,7 @@ static void taihu_405ep_init(ram_addr_t ram_size,
         filename = qemu_find_file(QEMU_FILE_TYPE_BIOS, bios_name);
         if (filename) {
             bios_size = load_image(filename, qemu_get_ram_ptr(bios_offset));
-            qemu_free(filename);
+            g_free(filename);
         } else {
             bios_size = -1;
         }
diff --git a/hw/ppc405_uc.c b/hw/ppc405_uc.c
index 06a053b..68c7cbd 100644
--- a/hw/ppc405_uc.c
+++ b/hw/ppc405_uc.c
@@ -172,7 +172,7 @@ static void ppc4xx_plb_init(CPUState *env)
 {
     ppc4xx_plb_t *plb;
 
-    plb = qemu_mallocz(sizeof(ppc4xx_plb_t));
+    plb = g_malloc0(sizeof(ppc4xx_plb_t));
     ppc_dcr_register(env, PLB0_ACR, plb, &dcr_read_plb, &dcr_write_plb);
     ppc_dcr_register(env, PLB0_BEAR, plb, &dcr_read_plb, &dcr_write_plb);
     ppc_dcr_register(env, PLB0_BESR, plb, &dcr_read_plb, &dcr_write_plb);
@@ -248,7 +248,7 @@ static void ppc4xx_pob_init(CPUState *env)
 {
     ppc4xx_pob_t *pob;
 
-    pob = qemu_mallocz(sizeof(ppc4xx_pob_t));
+    pob = g_malloc0(sizeof(ppc4xx_pob_t));
     ppc_dcr_register(env, POB0_BEAR, pob, &dcr_read_pob, &dcr_write_pob);
     ppc_dcr_register(env, POB0_BESR0, pob, &dcr_read_pob, &dcr_write_pob);
     ppc_dcr_register(env, POB0_BESR1, pob, &dcr_read_pob, &dcr_write_pob);
@@ -383,7 +383,7 @@ static void ppc4xx_opba_init(target_phys_addr_t base)
     ppc4xx_opba_t *opba;
     int io;
 
-    opba = qemu_mallocz(sizeof(ppc4xx_opba_t));
+    opba = g_malloc0(sizeof(ppc4xx_opba_t));
 #ifdef DEBUG_OPBA
     printf("%s: offset " TARGET_FMT_plx "\n", __func__, base);
 #endif
@@ -582,7 +582,7 @@ static void ppc405_ebc_init(CPUState *env)
 {
     ppc4xx_ebc_t *ebc;
 
-    ebc = qemu_mallocz(sizeof(ppc4xx_ebc_t));
+    ebc = g_malloc0(sizeof(ppc4xx_ebc_t));
     qemu_register_reset(&ebc_reset, ebc);
     ppc_dcr_register(env, EBC0_CFGADDR,
                      ebc, &dcr_read_ebc, &dcr_write_ebc);
@@ -665,7 +665,7 @@ static void ppc405_dma_init(CPUState *env, qemu_irq irqs[4])
 {
     ppc405_dma_t *dma;
 
-    dma = qemu_mallocz(sizeof(ppc405_dma_t));
+    dma = g_malloc0(sizeof(ppc405_dma_t));
     memcpy(dma->irqs, irqs, 4 * sizeof(qemu_irq));
     qemu_register_reset(&ppc405_dma_reset, dma);
     ppc_dcr_register(env, DMA0_CR0,
@@ -810,7 +810,7 @@ static void ppc405_gpio_init(target_phys_addr_t base)
     ppc405_gpio_t *gpio;
     int io;
 
-    gpio = qemu_mallocz(sizeof(ppc405_gpio_t));
+    gpio = g_malloc0(sizeof(ppc405_gpio_t));
 #ifdef DEBUG_GPIO
     printf("%s: offset " TARGET_FMT_plx "\n", __func__, base);
 #endif
@@ -972,7 +972,7 @@ static void ppc405_ocm_init(CPUState *env)
 {
     ppc405_ocm_t *ocm;
 
-    ocm = qemu_mallocz(sizeof(ppc405_ocm_t));
+    ocm = g_malloc0(sizeof(ppc405_ocm_t));
     ocm->offset = qemu_ram_alloc(NULL, "ppc405.ocm", 4096);
     qemu_register_reset(&ocm_reset, ocm);
     ppc_dcr_register(env, OCM0_ISARC,
@@ -1219,7 +1219,7 @@ static void ppc405_i2c_init(target_phys_addr_t base, qemu_irq irq)
     ppc4xx_i2c_t *i2c;
     int io;
 
-    i2c = qemu_mallocz(sizeof(ppc4xx_i2c_t));
+    i2c = g_malloc0(sizeof(ppc4xx_i2c_t));
     i2c->irq = irq;
 #ifdef DEBUG_I2C
     printf("%s: offset " TARGET_FMT_plx "\n", __func__, base);
@@ -1500,7 +1500,7 @@ static void ppc4xx_gpt_init(target_phys_addr_t base, qemu_irq irqs[5])
     int i;
     int io;
 
-    gpt = qemu_mallocz(sizeof(ppc4xx_gpt_t));
+    gpt = g_malloc0(sizeof(ppc4xx_gpt_t));
     for (i = 0; i < 5; i++) {
         gpt->irqs[i] = irqs[i];
     }
@@ -1731,7 +1731,7 @@ static void ppc405_mal_init(CPUState *env, qemu_irq irqs[4])
     ppc40x_mal_t *mal;
     int i;
 
-    mal = qemu_mallocz(sizeof(ppc40x_mal_t));
+    mal = g_malloc0(sizeof(ppc40x_mal_t));
     for (i = 0; i < 4; i++)
         mal->irqs[i] = irqs[i];
     qemu_register_reset(&ppc40x_mal_reset, mal);
@@ -2096,7 +2096,7 @@ static void ppc405cr_cpc_init (CPUState *env, clk_setup_t clk_setup[7],
 {
     ppc405cr_cpc_t *cpc;
 
-    cpc = qemu_mallocz(sizeof(ppc405cr_cpc_t));
+    cpc = g_malloc0(sizeof(ppc405cr_cpc_t));
     memcpy(cpc->clk_setup, clk_setup,
            PPC405CR_CLK_NB * sizeof(clk_setup_t));
     cpc->sysclk = sysclk;
@@ -2142,7 +2142,7 @@ CPUState *ppc405cr_init (target_phys_addr_t ram_bases[4],
     /* OBP arbitrer */
     ppc4xx_opba_init(0xef600600);
     /* Universal interrupt controller */
-    irqs = qemu_mallocz(sizeof(qemu_irq) * PPCUIC_OUTPUT_NB);
+    irqs = g_malloc0(sizeof(qemu_irq) * PPCUIC_OUTPUT_NB);
     irqs[PPCUIC_OUTPUT_INT] =
         ((qemu_irq *)env->irq_inputs)[PPC40x_INPUT_INT];
     irqs[PPCUIC_OUTPUT_CINT] =
@@ -2433,7 +2433,7 @@ static void ppc405ep_cpc_init (CPUState *env, clk_setup_t clk_setup[8],
 {
     ppc405ep_cpc_t *cpc;
 
-    cpc = qemu_mallocz(sizeof(ppc405ep_cpc_t));
+    cpc = g_malloc0(sizeof(ppc405ep_cpc_t));
     memcpy(cpc->clk_setup, clk_setup,
            PPC405EP_CLK_NB * sizeof(clk_setup_t));
     cpc->jtagid = 0x20267049;
@@ -2490,7 +2490,7 @@ CPUState *ppc405ep_init (target_phys_addr_t ram_bases[2],
     /* OBP arbitrer */
     ppc4xx_opba_init(0xef600600);
     /* Universal interrupt controller */
-    irqs = qemu_mallocz(sizeof(qemu_irq) * PPCUIC_OUTPUT_NB);
+    irqs = g_malloc0(sizeof(qemu_irq) * PPCUIC_OUTPUT_NB);
     irqs[PPCUIC_OUTPUT_INT] =
         ((qemu_irq *)env->irq_inputs)[PPC40x_INPUT_INT];
     irqs[PPCUIC_OUTPUT_CINT] =
diff --git a/hw/ppc440.c b/hw/ppc440.c
index 90abc91..baf991f 100644
--- a/hw/ppc440.c
+++ b/hw/ppc440.c
@@ -57,7 +57,7 @@ CPUState *ppc440ep_init(ram_addr_t *ram_size, PCIBus **pcip,
     ppc_dcr_init(env, NULL, NULL);
 
     /* interrupt controller */
-    irqs = qemu_mallocz(sizeof(qemu_irq) * PPCUIC_OUTPUT_NB);
+    irqs = g_malloc0(sizeof(qemu_irq) * PPCUIC_OUTPUT_NB);
     irqs[PPCUIC_OUTPUT_INT] = ((qemu_irq *)env->irq_inputs)[PPC40x_INPUT_INT];
     irqs[PPCUIC_OUTPUT_CINT] = ((qemu_irq *)env->irq_inputs)[PPC40x_INPUT_CINT];
     pic = ppcuic_init(env, irqs, 0x0C0, 0, 1);
@@ -73,7 +73,7 @@ CPUState *ppc440ep_init(ram_addr_t *ram_size, PCIBus **pcip,
                       ram_sizes, do_init);
 
     /* PCI */
-    pci_irqs = qemu_malloc(sizeof(qemu_irq) * 4);
+    pci_irqs = g_malloc(sizeof(qemu_irq) * 4);
     pci_irqs[0] = pic[pci_irq_nrs[0]];
     pci_irqs[1] = pic[pci_irq_nrs[1]];
     pci_irqs[2] = pic[pci_irq_nrs[2]];
diff --git a/hw/ppc440_bamboo.c b/hw/ppc440_bamboo.c
index 20b8629..1addb68 100644
--- a/hw/ppc440_bamboo.c
+++ b/hw/ppc440_bamboo.c
@@ -49,7 +49,7 @@ static int bamboo_load_device_tree(target_phys_addr_t addr,
         goto out;
     }
     fdt = load_device_tree(filename, &fdt_size);
-    qemu_free(filename);
+    g_free(filename);
     if (fdt == NULL) {
         goto out;
     }
@@ -80,7 +80,7 @@ static int bamboo_load_device_tree(target_phys_addr_t addr,
         kvmppc_fdt_update(fdt);
 
     ret = rom_add_blob_fixed(BINARY_DEVICE_TREE_FILE, fdt, fdt_size, addr);
-    qemu_free(fdt);
+    g_free(fdt);
 
 out:
 #endif
diff --git a/hw/ppc4xx_devs.c b/hw/ppc4xx_devs.c
index 68bdfaa..1af5f2e 100644
--- a/hw/ppc4xx_devs.c
+++ b/hw/ppc4xx_devs.c
@@ -293,7 +293,7 @@ qemu_irq *ppcuic_init (CPUState *env, qemu_irq *irqs,
     ppcuic_t *uic;
     int i;
 
-    uic = qemu_mallocz(sizeof(ppcuic_t));
+    uic = g_malloc0(sizeof(ppcuic_t));
     uic->dcr_base = dcr_base;
     uic->irqs = irqs;
     if (has_vr)
@@ -627,7 +627,7 @@ void ppc4xx_sdram_init (CPUState *env, qemu_irq irq, int nbanks,
 {
     ppc4xx_sdram_t *sdram;
 
-    sdram = qemu_mallocz(sizeof(ppc4xx_sdram_t));
+    sdram = g_malloc0(sizeof(ppc4xx_sdram_t));
     sdram->irq = irq;
     sdram->nbanks = nbanks;
     memset(sdram->ram_bases, 0, 4 * sizeof(target_phys_addr_t));
diff --git a/hw/ppc4xx_pci.c b/hw/ppc4xx_pci.c
index c7696b0..52e2663 100644
--- a/hw/ppc4xx_pci.c
+++ b/hw/ppc4xx_pci.c
@@ -341,7 +341,7 @@ PCIBus *ppc4xx_pci_init(CPUState *env, qemu_irq pci_irqs[4],
     static int ppc4xx_pci_id;
     uint8_t *pci_conf;
 
-    controller = qemu_mallocz(sizeof(PPC4xxPCIState));
+    controller = g_malloc0(sizeof(PPC4xxPCIState));
 
     controller->pci_state.bus = pci_register_bus(NULL, "pci",
                                                  ppc4xx_pci_set_irq,
@@ -390,6 +390,6 @@ PCIBus *ppc4xx_pci_init(CPUState *env, qemu_irq pci_irqs[4],
 
 free:
     printf("%s error\n", __func__);
-    qemu_free(controller);
+    g_free(controller);
     return NULL;
 }
diff --git a/hw/ppc_newworld.c b/hw/ppc_newworld.c
index 3039022..4727e07 100644
--- a/hw/ppc_newworld.c
+++ b/hw/ppc_newworld.c
@@ -189,7 +189,7 @@ static void ppc_core99_init (ram_addr_t ram_size,
         bios_size = load_elf(filename, NULL, NULL, NULL,
                              NULL, NULL, 1, ELF_MACHINE, 0);
 
-        qemu_free(filename);
+        g_free(filename);
     } else {
         bios_size = -1;
     }
@@ -271,9 +271,9 @@ static void ppc_core99_init (ram_addr_t ram_size,
                                          DEVICE_NATIVE_ENDIAN);
     cpu_register_physical_memory(0xf8000000, 0x00001000, unin_memory);
 
-    openpic_irqs = qemu_mallocz(smp_cpus * sizeof(qemu_irq *));
+    openpic_irqs = g_malloc0(smp_cpus * sizeof(qemu_irq *));
     openpic_irqs[0] =
-        qemu_mallocz(smp_cpus * sizeof(qemu_irq) * OPENPIC_OUTPUT_NB);
+        g_malloc0(smp_cpus * sizeof(qemu_irq) * OPENPIC_OUTPUT_NB);
     for (i = 0; i < smp_cpus; i++) {
         /* Mac99 IRQ connection between OpenPIC outputs pins
          * and PowerPC input pins
@@ -398,7 +398,7 @@ static void ppc_core99_init (ram_addr_t ram_size,
         uint8_t *hypercall;
 
         fw_cfg_add_i32(fw_cfg, FW_CFG_PPC_TBFREQ, kvmppc_get_tbfreq());
-        hypercall = qemu_malloc(16);
+        hypercall = g_malloc(16);
         kvmppc_get_hypercall(env, hypercall, 16);
         fw_cfg_add_bytes(fw_cfg, FW_CFG_PPC_KVM_HC, hypercall, 16);
         fw_cfg_add_i32(fw_cfg, FW_CFG_PPC_KVM_PID, getpid());
diff --git a/hw/ppc_oldworld.c b/hw/ppc_oldworld.c
index 41703a7..0071fc9 100644
--- a/hw/ppc_oldworld.c
+++ b/hw/ppc_oldworld.c
@@ -127,7 +127,7 @@ static void ppc_heathrow_init (ram_addr_t ram_size,
     if (filename) {
         bios_size = load_elf(filename, 0, NULL, NULL, NULL, NULL,
                              1, ELF_MACHINE, 0);
-        qemu_free(filename);
+        g_free(filename);
     } else {
         bios_size = -1;
     }
@@ -213,9 +213,9 @@ static void ppc_heathrow_init (ram_addr_t ram_size,
     isa_mmio_init(0xfe000000, 0x00200000);
 
     /* XXX: we register only 1 output pin for heathrow PIC */
-    heathrow_irqs = qemu_mallocz(smp_cpus * sizeof(qemu_irq *));
+    heathrow_irqs = g_malloc0(smp_cpus * sizeof(qemu_irq *));
     heathrow_irqs[0] =
-        qemu_mallocz(smp_cpus * sizeof(qemu_irq) * 1);
+        g_malloc0(smp_cpus * sizeof(qemu_irq) * 1);
     /* Connect the heathrow PIC outputs to the 6xx bus */
     for (i = 0; i < smp_cpus; i++) {
         switch (PPC_INPUT(env)) {
@@ -306,7 +306,7 @@ static void ppc_heathrow_init (ram_addr_t ram_size,
         uint8_t *hypercall;
 
         fw_cfg_add_i32(fw_cfg, FW_CFG_PPC_TBFREQ, kvmppc_get_tbfreq());
-        hypercall = qemu_malloc(16);
+        hypercall = g_malloc(16);
         kvmppc_get_hypercall(env, hypercall, 16);
         fw_cfg_add_bytes(fw_cfg, FW_CFG_PPC_KVM_HC, hypercall, 16);
         fw_cfg_add_i32(fw_cfg, FW_CFG_PPC_KVM_PID, getpid());
diff --git a/hw/ppc_prep.c b/hw/ppc_prep.c
index 38d8573..515de42 100644
--- a/hw/ppc_prep.c
+++ b/hw/ppc_prep.c
@@ -550,7 +550,7 @@ static void ppc_prep_init (ram_addr_t ram_size,
     DriveInfo *hd[MAX_IDE_BUS * MAX_IDE_DEVS];
     DriveInfo *fd[MAX_FD];
 
-    sysctrl = qemu_mallocz(sizeof(sysctrl_t));
+    sysctrl = g_malloc0(sizeof(sysctrl_t));
 
     linux_boot = (kernel_filename != NULL);
 
@@ -599,7 +599,7 @@ static void ppc_prep_init (ram_addr_t ram_size,
         hw_error("qemu: could not load PPC PREP bios '%s'\n", bios_name);
     }
     if (filename) {
-        qemu_free(filename);
+        g_free(filename);
     }
 
     if (linux_boot) {
@@ -673,7 +673,7 @@ static void ppc_prep_init (ram_addr_t ram_size,
         nb_nics1 = NE2000_NB_MAX;
     for(i = 0; i < nb_nics1; i++) {
         if (nd_table[i].model == NULL) {
-	    nd_table[i].model = qemu_strdup("ne2k_isa");
+	    nd_table[i].model = g_strdup("ne2k_isa");
         }
         if (strcmp(nd_table[i].model, "ne2k_isa") == 0) {
             isa_ne2000_init(ne2000_io[i], ne2000_irq[i], &nd_table[i]);
diff --git a/hw/ppce500_mpc8544ds.c b/hw/ppce500_mpc8544ds.c
index b739ce2..1274a3e 100644
--- a/hw/ppce500_mpc8544ds.c
+++ b/hw/ppce500_mpc8544ds.c
@@ -102,7 +102,7 @@ static int mpc8544_load_device_tree(CPUState *env,
         goto out;
     }
     fdt = load_device_tree(filename, &fdt_size);
-    qemu_free(filename);
+    g_free(filename);
     if (fdt == NULL) {
         goto out;
     }
@@ -176,7 +176,7 @@ static int mpc8544_load_device_tree(CPUState *env,
     }
 
     ret = rom_add_blob_fixed(BINARY_DEVICE_TREE_FILE, fdt, fdt_size, addr);
-    qemu_free(fdt);
+    g_free(fdt);
 
 out:
 #endif
@@ -267,7 +267,7 @@ static void mpc8544ds_init(ram_addr_t ram_size,
                                  "mpc8544ds.ram", ram_size));
 
     /* MPIC */
-    irqs = qemu_mallocz(sizeof(qemu_irq) * OPENPIC_OUTPUT_NB);
+    irqs = g_malloc0(sizeof(qemu_irq) * OPENPIC_OUTPUT_NB);
     irqs[OPENPIC_OUTPUT_INT] = ((qemu_irq *)env->irq_inputs)[PPCE500_INPUT_INT];
     irqs[OPENPIC_OUTPUT_CINT] = ((qemu_irq *)env->irq_inputs)[PPCE500_INPUT_CINT];
     mpic = mpic_init(MPC8544_MPIC_REGS_BASE, 1, &irqs, NULL);
@@ -336,7 +336,7 @@ static void mpc8544ds_init(ram_addr_t ram_size,
         }
     }
 
-    boot_info = qemu_mallocz(sizeof(struct boot_info));
+    boot_info = g_malloc0(sizeof(struct boot_info));
 
     /* If we're loading a kernel directly, we must load the device tree too. */
     if (kernel_filename) {
diff --git a/hw/prep_pci.c b/hw/prep_pci.c
index 58619dd..c36232a 100644
--- a/hw/prep_pci.c
+++ b/hw/prep_pci.c
@@ -118,7 +118,7 @@ PCIBus *pci_prep_init(qemu_irq *pic,
     PCIDevice *d;
     int PPC_io_memory;
 
-    s = qemu_mallocz(sizeof(PREPPCIState));
+    s = g_malloc0(sizeof(PREPPCIState));
     s->bus = pci_register_bus(NULL, "pci",
                               prep_set_irq, prep_map_irq, pic,
                               address_space_mem,
diff --git a/hw/ps2.c b/hw/ps2.c
index 91b73e0..24228c1 100644
--- a/hw/ps2.c
+++ b/hw/ps2.c
@@ -604,7 +604,7 @@ static const VMStateDescription vmstate_ps2_mouse = {
 
 void *ps2_kbd_init(void (*update_irq)(void *, int), void *update_arg)
 {
-    PS2KbdState *s = (PS2KbdState *)qemu_mallocz(sizeof(PS2KbdState));
+    PS2KbdState *s = (PS2KbdState *)g_malloc0(sizeof(PS2KbdState));
 
     s->common.update_irq = update_irq;
     s->common.update_arg = update_arg;
@@ -617,7 +617,7 @@ void *ps2_kbd_init(void (*update_irq)(void *, int), void *update_arg)
 
 void *ps2_mouse_init(void (*update_irq)(void *, int), void *update_arg)
 {
-    PS2MouseState *s = (PS2MouseState *)qemu_mallocz(sizeof(PS2MouseState));
+    PS2MouseState *s = (PS2MouseState *)g_malloc0(sizeof(PS2MouseState));
 
     s->common.update_irq = update_irq;
     s->common.update_arg = update_arg;
diff --git a/hw/ptimer.c b/hw/ptimer.c
index 6f13ce9..b6cabd5 100644
--- a/hw/ptimer.c
+++ b/hw/ptimer.c
@@ -210,7 +210,7 @@ ptimer_state *ptimer_init(QEMUBH *bh)
 {
     ptimer_state *s;
 
-    s = (ptimer_state *)qemu_mallocz(sizeof(ptimer_state));
+    s = (ptimer_state *)g_malloc0(sizeof(ptimer_state));
     s->bh = bh;
     s->timer = qemu_new_timer_ns(vm_clock, ptimer_tick, s);
     return s;
diff --git a/hw/pxa2xx.c b/hw/pxa2xx.c
index cf93110..d00edc6 100644
--- a/hw/pxa2xx.c
+++ b/hw/pxa2xx.c
@@ -1764,7 +1764,7 @@ static PXA2xxI2SState *pxa2xx_i2s_init(target_phys_addr_t base,
 {
     int iomemtype;
     PXA2xxI2SState *s = (PXA2xxI2SState *)
-            qemu_mallocz(sizeof(PXA2xxI2SState));
+            g_malloc0(sizeof(PXA2xxI2SState));
 
     s->irq = irq;
     s->rx_dma = rx_dma;
@@ -2025,7 +2025,7 @@ static PXA2xxFIrState *pxa2xx_fir_init(target_phys_addr_t base,
 {
     int iomemtype;
     PXA2xxFIrState *s = (PXA2xxFIrState *)
-            qemu_mallocz(sizeof(PXA2xxFIrState));
+            g_malloc0(sizeof(PXA2xxFIrState));
 
     s->irq = irq;
     s->rx_dma = rx_dma;
@@ -2064,7 +2064,7 @@ PXA2xxState *pxa270_init(unsigned int sdram_size, const char *revision)
     PXA2xxState *s;
     int iomemtype, i;
     DriveInfo *dinfo;
-    s = (PXA2xxState *) qemu_mallocz(sizeof(PXA2xxState));
+    s = (PXA2xxState *) g_malloc0(sizeof(PXA2xxState));
 
     if (revision && strncmp(revision, "pxa27", 5)) {
         fprintf(stderr, "Machine requires a PXA27x processor.\n");
@@ -2162,7 +2162,7 @@ PXA2xxState *pxa270_init(unsigned int sdram_size, const char *revision)
     vmstate_register(NULL, 0, &vmstate_pxa2xx_pm, s);
 
     for (i = 0; pxa27x_ssp[i].io_base; i ++);
-    s->ssp = (SSIBus **)qemu_mallocz(sizeof(SSIBus *) * i);
+    s->ssp = (SSIBus **)g_malloc0(sizeof(SSIBus *) * i);
     for (i = 0; pxa27x_ssp[i].io_base; i ++) {
         DeviceState *dev;
         dev = sysbus_create_simple("pxa2xx-ssp", pxa27x_ssp[i].io_base,
@@ -2207,7 +2207,7 @@ PXA2xxState *pxa255_init(unsigned int sdram_size)
     int iomemtype, i;
     DriveInfo *dinfo;
 
-    s = (PXA2xxState *) qemu_mallocz(sizeof(PXA2xxState));
+    s = (PXA2xxState *) g_malloc0(sizeof(PXA2xxState));
 
     s->env = cpu_init("pxa255");
     if (!s->env) {
@@ -2298,7 +2298,7 @@ PXA2xxState *pxa255_init(unsigned int sdram_size)
     vmstate_register(NULL, 0, &vmstate_pxa2xx_pm, s);
 
     for (i = 0; pxa255_ssp[i].io_base; i ++);
-    s->ssp = (SSIBus **)qemu_mallocz(sizeof(SSIBus *) * i);
+    s->ssp = (SSIBus **)g_malloc0(sizeof(SSIBus *) * i);
     for (i = 0; pxa255_ssp[i].io_base; i ++) {
         DeviceState *dev;
         dev = sysbus_create_simple("pxa2xx-ssp", pxa255_ssp[i].io_base,
diff --git a/hw/pxa2xx_dma.c b/hw/pxa2xx_dma.c
index 599581e..07ec2db 100644
--- a/hw/pxa2xx_dma.c
+++ b/hw/pxa2xx_dma.c
@@ -461,7 +461,7 @@ static int pxa2xx_dma_init(SysBusDevice *dev)
         return -1;
     }
 
-    s->chan = qemu_mallocz(sizeof(PXA2xxDMAChannel) * s->channels);
+    s->chan = g_malloc0(sizeof(PXA2xxDMAChannel) * s->channels);
 
     memset(s->chan, 0, sizeof(PXA2xxDMAChannel) * s->channels);
     for (i = 0; i < s->channels; i ++)
diff --git a/hw/pxa2xx_keypad.c b/hw/pxa2xx_keypad.c
index 10ef154..e33959d 100644
--- a/hw/pxa2xx_keypad.c
+++ b/hw/pxa2xx_keypad.c
@@ -312,7 +312,7 @@ PXA2xxKeyPadState *pxa27x_keypad_init(target_phys_addr_t base,
     int iomemtype;
     PXA2xxKeyPadState *s;
 
-    s = (PXA2xxKeyPadState *) qemu_mallocz(sizeof(PXA2xxKeyPadState));
+    s = (PXA2xxKeyPadState *) g_malloc0(sizeof(PXA2xxKeyPadState));
     s->irq = irq;
 
     iomemtype = cpu_register_io_memory(pxa2xx_keypad_readfn,
diff --git a/hw/pxa2xx_lcd.c b/hw/pxa2xx_lcd.c
index a5f8c51..97f9015 100644
--- a/hw/pxa2xx_lcd.c
+++ b/hw/pxa2xx_lcd.c
@@ -986,7 +986,7 @@ PXA2xxLCDState *pxa2xx_lcdc_init(target_phys_addr_t base, qemu_irq irq)
     int iomemtype;
     PXA2xxLCDState *s;
 
-    s = (PXA2xxLCDState *) qemu_mallocz(sizeof(PXA2xxLCDState));
+    s = (PXA2xxLCDState *) g_malloc0(sizeof(PXA2xxLCDState));
     s->invalidated = 1;
     s->irq = irq;
 
diff --git a/hw/pxa2xx_mmci.c b/hw/pxa2xx_mmci.c
index d86f735..1de4979 100644
--- a/hw/pxa2xx_mmci.c
+++ b/hw/pxa2xx_mmci.c
@@ -524,7 +524,7 @@ PXA2xxMMCIState *pxa2xx_mmci_init(target_phys_addr_t base,
     int iomemtype;
     PXA2xxMMCIState *s;
 
-    s = (PXA2xxMMCIState *) qemu_mallocz(sizeof(PXA2xxMMCIState));
+    s = (PXA2xxMMCIState *) g_malloc0(sizeof(PXA2xxMMCIState));
     s->irq = irq;
     s->rx_dma = rx_dma;
     s->tx_dma = tx_dma;
diff --git a/hw/pxa2xx_pcmcia.c b/hw/pxa2xx_pcmcia.c
index 50d4649..74c6817 100644
--- a/hw/pxa2xx_pcmcia.c
+++ b/hw/pxa2xx_pcmcia.c
@@ -136,7 +136,7 @@ PXA2xxPCMCIAState *pxa2xx_pcmcia_init(target_phys_addr_t base)
     PXA2xxPCMCIAState *s;
 
     s = (PXA2xxPCMCIAState *)
-            qemu_mallocz(sizeof(PXA2xxPCMCIAState));
+            g_malloc0(sizeof(PXA2xxPCMCIAState));
 
     /* Socket I/O Memory Space */
     iomemtype = cpu_register_io_memory(pxa2xx_pcmcia_io_readfn,
diff --git a/hw/qdev-properties.c b/hw/qdev-properties.c
index eff2d24..0c0c292 100644
--- a/hw/qdev-properties.c
+++ b/hw/qdev-properties.c
@@ -275,14 +275,14 @@ static int parse_string(DeviceState *dev, Property *prop, const char *str)
     char **ptr = qdev_get_prop_ptr(dev, prop);
 
     if (*ptr)
-        qemu_free(*ptr);
-    *ptr = qemu_strdup(str);
+        g_free(*ptr);
+    *ptr = g_strdup(str);
     return 0;
 }
 
 static void free_string(DeviceState *dev, Property *prop)
 {
-    qemu_free(*(char **)qdev_get_prop_ptr(dev, prop));
+    g_free(*(char **)qdev_get_prop_ptr(dev, prop));
 }
 
 static int print_string(DeviceState *dev, Property *prop, char *dest, size_t len)
@@ -768,7 +768,7 @@ static int qdev_add_one_global(QemuOpts *opts, void *opaque)
 {
     GlobalProperty *g;
 
-    g = qemu_mallocz(sizeof(*g));
+    g = g_malloc0(sizeof(*g));
     g->driver   = qemu_opt_get(opts, "driver");
     g->property = qemu_opt_get(opts, "property");
     g->value    = qemu_opt_get(opts, "value");
diff --git a/hw/qdev.c b/hw/qdev.c
index d8114c6..c463c52 100644
--- a/hw/qdev.c
+++ b/hw/qdev.c
@@ -85,7 +85,7 @@ static DeviceState *qdev_create_from_info(BusState *bus, DeviceInfo *info)
     DeviceState *dev;
 
     assert(bus->info == info->bus_info);
-    dev = qemu_mallocz(info->size);
+    dev = g_malloc0(info->size);
     dev->info = info;
     dev->parent_bus = bus;
     qdev_prop_set_defaults(dev, dev->info->props);
@@ -408,7 +408,7 @@ void qdev_free(DeviceState *dev)
             prop->info->free(dev, prop);
         }
     }
-    qemu_free(dev);
+    g_free(dev);
 }
 
 void qdev_machine_creation_done(void)
@@ -750,17 +750,17 @@ void qbus_create_inplace(BusState *bus, BusInfo *info,
 
     if (name) {
         /* use supplied name */
-        bus->name = qemu_strdup(name);
+        bus->name = g_strdup(name);
     } else if (parent && parent->id) {
         /* parent device has id -> use it for bus name */
         len = strlen(parent->id) + 16;
-        buf = qemu_malloc(len);
+        buf = g_malloc(len);
         snprintf(buf, len, "%s.%d", parent->id, parent->num_child_bus);
         bus->name = buf;
     } else {
         /* no id -> use lowercase bus type for bus name */
         len = strlen(info->name) + 16;
-        buf = qemu_malloc(len);
+        buf = g_malloc(len);
         len = snprintf(buf, len, "%s.%d", info->name,
                        parent ? parent->num_child_bus : 0);
         for (i = 0; i < len; i++)
@@ -783,7 +783,7 @@ BusState *qbus_create(BusInfo *info, DeviceState *parent, const char *name)
 {
     BusState *bus;
 
-    bus = qemu_mallocz(info->size);
+    bus = g_malloc0(info->size);
     bus->qdev_allocated = 1;
     qbus_create_inplace(bus, info, parent, name);
     return bus;
@@ -793,7 +793,7 @@ static void main_system_bus_create(void)
 {
     /* assign main_system_bus before qbus_create_inplace()
      * in order to make "if (bus != main_system_bus)" work */
-    main_system_bus = qemu_mallocz(system_bus_info.size);
+    main_system_bus = g_malloc0(system_bus_info.size);
     main_system_bus->qdev_allocated = 1;
     qbus_create_inplace(main_system_bus, &system_bus_info, NULL,
                         "main-system-bus");
@@ -813,9 +813,9 @@ void qbus_free(BusState *bus)
         assert(bus != main_system_bus); /* main_system_bus is never freed */
         qemu_unregister_reset(qbus_reset_all_fn, bus);
     }
-    qemu_free((void*)bus->name);
+    g_free((void*)bus->name);
     if (bus->qdev_allocated) {
-        qemu_free(bus);
+        g_free(bus);
     }
 }
 
@@ -935,7 +935,7 @@ static int qdev_get_fw_dev_path_helper(DeviceState *dev, char *p, int size)
         if (dev->parent_bus->info->get_fw_dev_path) {
             d = dev->parent_bus->info->get_fw_dev_path(dev);
             l += snprintf(p + l, size - l, "%s", d);
-            qemu_free(d);
+            g_free(d);
         } else {
             l += snprintf(p + l, size - l, "%s", dev->info->name);
         }
diff --git a/hw/qxl-render.c b/hw/qxl-render.c
index 1b77577..c290739 100644
--- a/hw/qxl-render.c
+++ b/hw/qxl-render.c
@@ -81,7 +81,7 @@ void qxl_render_update(PCIQXLDevice *qxl)
         qxl->guest_primary.resized = 0;
 
         if (qxl->guest_primary.flipped) {
-            qemu_free(qxl->guest_primary.flipped);
+            g_free(qxl->guest_primary.flipped);
             qxl->guest_primary.flipped = NULL;
         }
         qemu_free_displaysurface(vga->ds);
@@ -90,7 +90,7 @@ void qxl_render_update(PCIQXLDevice *qxl)
         if (qxl->guest_primary.stride < 0) {
             /* spice surface is upside down -> need extra buffer to flip */
             qxl->guest_primary.stride = -qxl->guest_primary.stride;
-            qxl->guest_primary.flipped = qemu_malloc(qxl->guest_primary.surface.width *
+            qxl->guest_primary.flipped = g_malloc(qxl->guest_primary.surface.width *
                                                      qxl->guest_primary.stride);
             ptr = qxl->guest_primary.flipped;
         } else {
diff --git a/hw/qxl.c b/hw/qxl.c
index b34bccf..bab60a5 100644
--- a/hw/qxl.c
+++ b/hw/qxl.c
@@ -1697,7 +1697,7 @@ static int qxl_post_load(void *opaque, int version)
         qxl_create_guest_primary(d, 1, QXL_SYNC);
 
         /* replay surface-create and cursor-set commands */
-        cmds = qemu_mallocz(sizeof(QXLCommandExt) * (NUM_SURFACES + 1));
+        cmds = g_malloc0(sizeof(QXLCommandExt) * (NUM_SURFACES + 1));
         for (in = 0, out = 0; in < NUM_SURFACES; in++) {
             if (d->guest_surfaces.cmds[in] == 0) {
                 continue;
@@ -1712,7 +1712,7 @@ static int qxl_post_load(void *opaque, int version)
         cmds[out].group_id = MEMSLOT_GROUP_GUEST;
         out++;
         qxl_spice_loadvm_commands(d, cmds, out);
-        qemu_free(cmds);
+        g_free(cmds);
 
         break;
     case QXL_MODE_COMPAT:
diff --git a/hw/r2d.c b/hw/r2d.c
index a0f8c1f..96a7ff8 100644
--- a/hw/r2d.c
+++ b/hw/r2d.c
@@ -184,7 +184,7 @@ static qemu_irq *r2d_fpga_init(target_phys_addr_t base, qemu_irq irl)
     int iomemtype;
     r2d_fpga_t *s;
 
-    s = qemu_mallocz(sizeof(r2d_fpga_t));
+    s = g_malloc0(sizeof(r2d_fpga_t));
 
     s->irl = irl;
 
@@ -244,7 +244,7 @@ static void r2d_init(ram_addr_t ram_size,
         fprintf(stderr, "Unable to find CPU definition\n");
         exit(1);
     }
-    reset_info = qemu_mallocz(sizeof(ResetData));
+    reset_info = g_malloc0(sizeof(ResetData));
     reset_info->env = env;
     reset_info->vector = env->pc;
     qemu_register_reset(main_cpu_reset, reset_info);
diff --git a/hw/rc4030.c b/hw/rc4030.c
index 6563336..a2a2099 100644
--- a/hw/rc4030.c
+++ b/hw/rc4030.c
@@ -789,8 +789,8 @@ static rc4030_dma *rc4030_allocate_dmas(void *opaque, int n)
     struct rc4030DMAState *p;
     int i;
 
-    s = (rc4030_dma *)qemu_mallocz(sizeof(rc4030_dma) * n);
-    p = (struct rc4030DMAState *)qemu_mallocz(sizeof(struct rc4030DMAState) * n);
+    s = (rc4030_dma *)g_malloc0(sizeof(rc4030_dma) * n);
+    p = (struct rc4030DMAState *)g_malloc0(sizeof(struct rc4030DMAState) * n);
     for (i = 0; i < n; i++) {
         p->opaque = opaque;
         p->n = i;
@@ -806,7 +806,7 @@ void *rc4030_init(qemu_irq timer, qemu_irq jazz_bus,
     rc4030State *s;
     int s_chipset, s_jazzio;
 
-    s = qemu_mallocz(sizeof(rc4030State));
+    s = g_malloc0(sizeof(rc4030State));
 
     *irqs = qemu_allocate_irqs(rc4030_irq_jazz_request, s, 16);
     *dmas = rc4030_allocate_dmas(s, 4);
diff --git a/hw/rtl8139.c b/hw/rtl8139.c
index c6cafc2..c5de5b4 100644
--- a/hw/rtl8139.c
+++ b/hw/rtl8139.c
@@ -1796,7 +1796,7 @@ static void rtl8139_transfer_frame(RTL8139State *s, uint8_t *buf, int size,
 
         if (iov) {
             buf2_size = iov_size(iov, 3);
-            buf2 = qemu_malloc(buf2_size);
+            buf2 = g_malloc(buf2_size);
             iov_to_buf(iov, 3, buf2, 0, buf2_size);
             buf = buf2;
         }
@@ -1805,7 +1805,7 @@ static void rtl8139_transfer_frame(RTL8139State *s, uint8_t *buf, int size,
         rtl8139_do_receive(&s->nic->nc, buf, size, do_interrupt);
 
         if (iov) {
-            qemu_free(buf2);
+            g_free(buf2);
         }
     }
     else
@@ -2053,7 +2053,7 @@ static int rtl8139_cplus_transmit_one(RTL8139State *s)
     if (!s->cplus_txbuffer)
     {
         s->cplus_txbuffer_len = CP_TX_BUFFER_SIZE;
-        s->cplus_txbuffer = qemu_malloc(s->cplus_txbuffer_len);
+        s->cplus_txbuffer = g_malloc(s->cplus_txbuffer_len);
         s->cplus_txbuffer_offset = 0;
 
         DPRINTF("+++ C+ mode transmission buffer allocated space %d\n",
@@ -2063,7 +2063,7 @@ static int rtl8139_cplus_transmit_one(RTL8139State *s)
     while (s->cplus_txbuffer && s->cplus_txbuffer_offset + txsize >= s->cplus_txbuffer_len)
     {
         s->cplus_txbuffer_len += CP_TX_BUFFER_SIZE;
-        s->cplus_txbuffer = qemu_realloc(s->cplus_txbuffer, s->cplus_txbuffer_len);
+        s->cplus_txbuffer = g_realloc(s->cplus_txbuffer, s->cplus_txbuffer_len);
 
         DPRINTF("+++ C+ mode transmission buffer space changed to %d\n",
             s->cplus_txbuffer_len);
@@ -2401,7 +2401,7 @@ static int rtl8139_cplus_transmit_one(RTL8139State *s)
         }
         else
         {
-            qemu_free(saved_buffer);
+            g_free(saved_buffer);
         }
     }
     else
@@ -3441,7 +3441,7 @@ static int pci_rtl8139_uninit(PCIDevice *dev)
     memory_region_destroy(&s->bar_io);
     memory_region_destroy(&s->bar_mem);
     if (s->cplus_txbuffer) {
-        qemu_free(s->cplus_txbuffer);
+        g_free(s->cplus_txbuffer);
         s->cplus_txbuffer = NULL;
     }
     qemu_del_timer(s->timer);
diff --git a/hw/s390-virtio.c b/hw/s390-virtio.c
index abe954d..acbf026 100644
--- a/hw/s390-virtio.c
+++ b/hw/s390-virtio.c
@@ -165,14 +165,14 @@ static void s390_init(ram_addr_t my_ram_size,
     cpu_register_physical_memory(0, my_ram_size, ram_addr);
 
     /* allocate storage keys */
-    storage_keys = qemu_mallocz(my_ram_size / TARGET_PAGE_SIZE);
+    storage_keys = g_malloc0(my_ram_size / TARGET_PAGE_SIZE);
 
     /* init CPUs */
     if (cpu_model == NULL) {
         cpu_model = "host";
     }
 
-    ipi_states = qemu_malloc(sizeof(CPUState *) * smp_cpus);
+    ipi_states = g_malloc(sizeof(CPUState *) * smp_cpus);
 
     for (i = 0; i < smp_cpus; i++) {
         CPUState *tmp_env;
@@ -211,7 +211,7 @@ static void s390_init(ram_addr_t my_ram_size,
 
         bios_filename = qemu_find_file(QEMU_FILE_TYPE_BIOS, bios_name);
         bios_size = load_image(bios_filename, qemu_get_ram_ptr(ZIPL_LOAD_ADDR));
-        qemu_free(bios_filename);
+        g_free(bios_filename);
 
         if ((long)bios_size < 0) {
             hw_error("could not load bootloader '%s'\n", bios_name);
@@ -247,7 +247,7 @@ static void s390_init(ram_addr_t my_ram_size,
         DeviceState *dev;
 
         if (!nd->model) {
-            nd->model = qemu_strdup("virtio");
+            nd->model = g_strdup("virtio");
         }
 
         if (strcmp(nd->model, "virtio")) {
diff --git a/hw/scsi-bus.c b/hw/scsi-bus.c
index c3ce7df..6f0d039 100644
--- a/hw/scsi-bus.c
+++ b/hw/scsi-bus.c
@@ -346,7 +346,7 @@ SCSIRequest *scsi_req_alloc(SCSIReqOps *reqops, SCSIDevice *d, uint32_t tag,
 {
     SCSIRequest *req;
 
-    req = qemu_mallocz(reqops->size);
+    req = g_malloc0(reqops->size);
     req->refcount = 1;
     req->bus = scsi_bus_from_device(d);
     req->dev = d;
@@ -1015,7 +1015,7 @@ void scsi_req_unref(SCSIRequest *req)
         if (req->ops->free_req) {
             req->ops->free_req(req);
         }
-        qemu_free(req);
+        g_free(req);
     }
 }
 
diff --git a/hw/scsi-disk.c b/hw/scsi-disk.c
index f1ffe95..d94b1eb 100644
--- a/hw/scsi-disk.c
+++ b/hw/scsi-disk.c
@@ -1125,12 +1125,12 @@ static int scsi_initfn(SCSIDevice *dev, uint8_t scsi_type)
         /* try to fall back to value set with legacy -drive serial=... */
         dinfo = drive_get_by_blockdev(s->bs);
         if (*dinfo->serial) {
-            s->serial = qemu_strdup(dinfo->serial);
+            s->serial = g_strdup(dinfo->serial);
         }
     }
 
     if (!s->version) {
-        s->version = qemu_strdup(QEMU_VERSION);
+        s->version = g_strdup(QEMU_VERSION);
     }
 
     if (bdrv_is_sg(s->bs)) {
diff --git a/hw/scsi-generic.c b/hw/scsi-generic.c
index b63371e..cb5d4f1 100644
--- a/hw/scsi-generic.c
+++ b/hw/scsi-generic.c
@@ -66,7 +66,7 @@ static void scsi_free_request(SCSIRequest *req)
 {
     SCSIGenericReq *r = DO_UPCAST(SCSIGenericReq, req, req);
 
-    qemu_free(r->buf);
+    g_free(r->buf);
 }
 
 /* Helper function for command completion.  */
@@ -288,7 +288,7 @@ static int32_t scsi_send_command(SCSIRequest *req, uint8_t *cmd)
 
     if (r->req.cmd.xfer == 0) {
         if (r->buf != NULL)
-            qemu_free(r->buf);
+            g_free(r->buf);
         r->buflen = 0;
         r->buf = NULL;
         ret = execute_command(s->bs, r, SG_DXFER_NONE, scsi_command_complete);
@@ -301,8 +301,8 @@ static int32_t scsi_send_command(SCSIRequest *req, uint8_t *cmd)
 
     if (r->buflen != r->req.cmd.xfer) {
         if (r->buf != NULL)
-            qemu_free(r->buf);
-        r->buf = qemu_malloc(r->req.cmd.xfer);
+            g_free(r->buf);
+        r->buf = g_malloc(r->req.cmd.xfer);
         r->buflen = r->req.cmd.xfer;
     }
 
diff --git a/hw/sd.c b/hw/sd.c
index c2c80ab..bb8c2ff 100644
--- a/hw/sd.c
+++ b/hw/sd.c
@@ -409,9 +409,9 @@ static void sd_reset(SDState *sd, BlockDriverState *bdrv)
     sd->bdrv = bdrv;
 
     if (sd->wp_groups)
-        qemu_free(sd->wp_groups);
+        g_free(sd->wp_groups);
     sd->wp_switch = bdrv ? bdrv_is_read_only(bdrv) : 0;
-    sd->wp_groups = (int *) qemu_mallocz(sizeof(int) * sect);
+    sd->wp_groups = (int *) g_malloc0(sizeof(int) * sect);
     memset(sd->function_group, 0, sizeof(int) * 6);
     sd->erase_start = 0;
     sd->erase_end = 0;
@@ -443,7 +443,7 @@ SDState *sd_init(BlockDriverState *bs, int is_spi)
 {
     SDState *sd;
 
-    sd = (SDState *) qemu_mallocz(sizeof(SDState));
+    sd = (SDState *) g_malloc0(sizeof(SDState));
     sd->buf = qemu_blockalign(bs, 512);
     sd->spi = is_spi;
     sd->enable = 1;
diff --git a/hw/serial.c b/hw/serial.c
index 0ee61dd..222e356 100644
--- a/hw/serial.c
+++ b/hw/serial.c
@@ -797,7 +797,7 @@ SerialState *serial_init(int base, qemu_irq irq, int baudbase,
 {
     SerialState *s;
 
-    s = qemu_mallocz(sizeof(SerialState));
+    s = g_malloc0(sizeof(SerialState));
 
     s->irq = irq;
     s->baudbase = baudbase;
@@ -931,7 +931,7 @@ SerialState *serial_mm_init (target_phys_addr_t base, int it_shift,
     SerialState *s;
     int s_io_memory;
 
-    s = qemu_mallocz(sizeof(SerialState));
+    s = g_malloc0(sizeof(SerialState));
 
     s->it_shift = it_shift;
     s->irq = irq;
diff --git a/hw/sh7750.c b/hw/sh7750.c
index 4f279e7..9f3ea92 100644
--- a/hw/sh7750.c
+++ b/hw/sh7750.c
@@ -712,7 +712,7 @@ SH7750State *sh7750_init(CPUSH4State * cpu)
     int sh7750_io_memory;
     int sh7750_mm_cache_and_tlb; /* memory mapped cache and tlb */
 
-    s = qemu_mallocz(sizeof(SH7750State));
+    s = g_malloc0(sizeof(SH7750State));
     s->cpu = cpu;
     s->periph_freq = 60000000;	/* 60MHz */
     sh7750_io_memory = cpu_register_io_memory(sh7750_mem_read,
diff --git a/hw/sh_intc.c b/hw/sh_intc.c
index c43b99f..ecb46e5 100644
--- a/hw/sh_intc.c
+++ b/hw/sh_intc.c
@@ -431,7 +431,7 @@ int sh_intc_init(struct intc_desc *desc,
     desc->nr_prio_regs = nr_prio_regs;
 
     i = sizeof(struct intc_source) * nr_sources;
-    desc->sources = qemu_mallocz(i);
+    desc->sources = g_malloc0(i);
 
     for (i = 0; i < desc->nr_sources; i++) {
         struct intc_source *source = desc->sources + i;
diff --git a/hw/sh_serial.c b/hw/sh_serial.c
index 191f4a6..1767c97 100644
--- a/hw/sh_serial.c
+++ b/hw/sh_serial.c
@@ -361,7 +361,7 @@ void sh_serial_init (target_phys_addr_t base, int feat,
     sh_serial_state *s;
     int s_io_memory;
 
-    s = qemu_mallocz(sizeof(sh_serial_state));
+    s = g_malloc0(sizeof(sh_serial_state));
 
     s->feat = feat;
     s->flags = SH_SERIAL_FLAG_TEND | SH_SERIAL_FLAG_TDE;
diff --git a/hw/sh_timer.c b/hw/sh_timer.c
index 5df7fb6..dca3c94 100644
--- a/hw/sh_timer.c
+++ b/hw/sh_timer.c
@@ -188,7 +188,7 @@ static void *sh_timer_init(uint32_t freq, int feat, qemu_irq irq)
     sh_timer_state *s;
     QEMUBH *bh;
 
-    s = (sh_timer_state *)qemu_mallocz(sizeof(sh_timer_state));
+    s = (sh_timer_state *)g_malloc0(sizeof(sh_timer_state));
     s->freq = freq;
     s->feat = feat;
     s->tcor = 0xffffffff;
@@ -311,7 +311,7 @@ void tmu012_init(target_phys_addr_t base, int feat, uint32_t freq,
     tmu012_state *s;
     int timer_feat = (feat & TMU012_FEAT_EXTCLK) ? TIMER_FEAT_EXTCLK : 0;
 
-    s = (tmu012_state *)qemu_mallocz(sizeof(tmu012_state));
+    s = (tmu012_state *)g_malloc0(sizeof(tmu012_state));
     s->feat = feat;
     s->timer[0] = sh_timer_init(freq, timer_feat, ch0_irq);
     s->timer[1] = sh_timer_init(freq, timer_feat, ch1_irq);
diff --git a/hw/slavio_timer.c b/hw/slavio_timer.c
index 5511313..f89b4fb 100644
--- a/hw/slavio_timer.c
+++ b/hw/slavio_timer.c
@@ -381,7 +381,7 @@ static int slavio_timer_init1(SysBusDevice *dev)
     TimerContext *tc;
 
     for (i = 0; i <= MAX_CPUS; i++) {
-        tc = qemu_mallocz(sizeof(TimerContext));
+        tc = g_malloc0(sizeof(TimerContext));
         tc->s = s;
         tc->timer_index = i;
 
diff --git a/hw/sm501.c b/hw/sm501.c
index 0f0bf96..1ed0a7e 100644
--- a/hw/sm501.c
+++ b/hw/sm501.c
@@ -1395,7 +1395,7 @@ void sm501_init(uint32_t base, uint32_t local_mem_bytes, qemu_irq irq,
     int sm501_2d_engine_index;
 
     /* allocate management data region */
-    s = (SM501State *)qemu_mallocz(sizeof(SM501State));
+    s = (SM501State *)g_malloc0(sizeof(SM501State));
     s->base = base;
     s->local_mem_size_index
 	= get_local_mem_size_index(local_mem_bytes);
diff --git a/hw/smbios.c b/hw/smbios.c
index a3ae1de..8f2e965 100644
--- a/hw/smbios.c
+++ b/hw/smbios.c
@@ -105,9 +105,9 @@ void smbios_add_field(int type, int offset, int len, void *data)
 
     if (!smbios_entries) {
         smbios_entries_len = sizeof(uint16_t);
-        smbios_entries = qemu_mallocz(smbios_entries_len);
+        smbios_entries = g_malloc0(smbios_entries_len);
     }
-    smbios_entries = qemu_realloc(smbios_entries, smbios_entries_len +
+    smbios_entries = g_realloc(smbios_entries, smbios_entries_len +
                                                   sizeof(*field) + len);
     field = (struct smbios_field *)(smbios_entries + smbios_entries_len);
     field->header.type = SMBIOS_FIELD_ENTRY;
@@ -192,10 +192,10 @@ int smbios_entry_add(const char *t)
 
         if (!smbios_entries) {
             smbios_entries_len = sizeof(uint16_t);
-            smbios_entries = qemu_mallocz(smbios_entries_len);
+            smbios_entries = g_malloc0(smbios_entries_len);
         }
 
-        smbios_entries = qemu_realloc(smbios_entries, smbios_entries_len +
+        smbios_entries = g_realloc(smbios_entries, smbios_entries_len +
                                                       sizeof(*table) + size);
         table = (struct smbios_table *)(smbios_entries + smbios_entries_len);
         table->header.type = SMBIOS_TABLE_ENTRY;
diff --git a/hw/smbus_eeprom.c b/hw/smbus_eeprom.c
index 3634754..5d080ab 100644
--- a/hw/smbus_eeprom.c
+++ b/hw/smbus_eeprom.c
@@ -130,7 +130,7 @@ void smbus_eeprom_init(i2c_bus *smbus, int nb_eeprom,
                        const uint8_t *eeprom_spd, int eeprom_spd_size)
 {
     int i;
-    uint8_t *eeprom_buf = qemu_mallocz(8 * 256); /* XXX: make this persistent */
+    uint8_t *eeprom_buf = g_malloc0(8 * 256); /* XXX: make this persistent */
     if (eeprom_spd_size > 0) {
         memcpy(eeprom_buf, eeprom_spd, eeprom_spd_size);
     }
diff --git a/hw/soc_dma.c b/hw/soc_dma.c
index 3f0f414..03bc846 100644
--- a/hw/soc_dma.c
+++ b/hw/soc_dma.c
@@ -48,7 +48,7 @@ static int fifo_size;
 static void transfer_fifo2fifo(struct soc_dma_ch_s *ch)
 {
     if (ch->bytes > fifo_size)
-        fifo_buf = qemu_realloc(fifo_buf, fifo_size = ch->bytes);
+        fifo_buf = g_realloc(fifo_buf, fifo_size = ch->bytes);
 
     /* Implement as transfer_fifo2linear + transfer_linear2fifo.  */
     ch->io_fn[0](ch->io_opaque[0], fifo_buf, ch->bytes);
@@ -239,7 +239,7 @@ void soc_dma_reset(struct soc_dma_s *soc)
 struct soc_dma_s *soc_dma_init(int n)
 {
     int i;
-    struct dma_s *s = qemu_mallocz(sizeof(*s) + n * sizeof(*s->ch));
+    struct dma_s *s = g_malloc0(sizeof(*s) + n * sizeof(*s->ch));
 
     s->chnum = n;
     s->soc.ch = s->ch;
@@ -261,7 +261,7 @@ void soc_dma_port_add_fifo(struct soc_dma_s *soc, target_phys_addr_t virt_base,
     struct memmap_entry_s *entry;
     struct dma_s *dma = (struct dma_s *) soc;
 
-    dma->memmap = qemu_realloc(dma->memmap, sizeof(*entry) *
+    dma->memmap = g_realloc(dma->memmap, sizeof(*entry) *
                     (dma->memmap_size + 1));
     entry = soc_dma_lookup(dma, virt_base);
 
@@ -313,7 +313,7 @@ void soc_dma_port_add_mem(struct soc_dma_s *soc, uint8_t *phys_base,
     struct memmap_entry_s *entry;
     struct dma_s *dma = (struct dma_s *) soc;
 
-    dma->memmap = qemu_realloc(dma->memmap, sizeof(*entry) *
+    dma->memmap = g_realloc(dma->memmap, sizeof(*entry) *
                     (dma->memmap_size + 1));
     entry = soc_dma_lookup(dma, virt_base);
 
diff --git a/hw/spapr.c b/hw/spapr.c
index 109b774..1265cee 100644
--- a/hw/spapr.c
+++ b/hw/spapr.c
@@ -85,7 +85,7 @@ static void *spapr_create_fdt_skel(const char *cpu_model,
         }                                                          \
     } while (0)
 
-    fdt = qemu_mallocz(FDT_MAX_SIZE);
+    fdt = g_malloc0(FDT_MAX_SIZE);
     _FDT((fdt_create(fdt, FDT_MAX_SIZE)));
 
     _FDT((fdt_finish_reservemap(fdt)));
@@ -125,7 +125,7 @@ static void *spapr_create_fdt_skel(const char *cpu_model,
     _FDT((fdt_property_cell(fdt, "#address-cells", 0x1)));
     _FDT((fdt_property_cell(fdt, "#size-cells", 0x0)));
 
-    modelname = qemu_strdup(cpu_model);
+    modelname = g_strdup(cpu_model);
 
     for (i = 0; i < strlen(modelname); i++) {
         modelname[i] = toupper(modelname[i]);
@@ -176,7 +176,7 @@ static void *spapr_create_fdt_skel(const char *cpu_model,
         _FDT((fdt_end_node(fdt)));
     }
 
-    qemu_free(modelname);
+    g_free(modelname);
 
     _FDT((fdt_end_node(fdt)));
 
@@ -228,7 +228,7 @@ static void spapr_finalize_fdt(sPAPREnvironment *spapr,
     int ret;
     void *fdt;
 
-    fdt = qemu_malloc(FDT_MAX_SIZE);
+    fdt = g_malloc(FDT_MAX_SIZE);
 
     /* open out the base tree into a temp buffer for the final tweaks */
     _FDT((fdt_open_into(spapr->fdt_skel, fdt, FDT_MAX_SIZE)));
@@ -249,7 +249,7 @@ static void spapr_finalize_fdt(sPAPREnvironment *spapr,
 
     cpu_physical_memory_write(fdt_addr, fdt, fdt_totalsize(fdt));
 
-    qemu_free(fdt);
+    g_free(fdt);
 }
 
 static uint64_t translate_kernel_address(void *opaque, uint64_t addr)
@@ -300,7 +300,7 @@ static void ppc_spapr_init(ram_addr_t ram_size,
     char *filename;
     int irq = 16;
 
-    spapr = qemu_malloc(sizeof(*spapr));
+    spapr = g_malloc(sizeof(*spapr));
     cpu_ppc_hypercall = emulate_spapr_hypercall;
 
     /* We place the device tree just below either the top of RAM, or
@@ -337,7 +337,7 @@ static void ppc_spapr_init(ram_addr_t ram_size,
      * later we should probably make it scale to the size of guest
      * RAM */
     spapr->htab_size = 1ULL << (pteg_shift + 7);
-    spapr->htab = qemu_malloc(spapr->htab_size);
+    spapr->htab = g_malloc(spapr->htab_size);
 
     for (env = first_cpu; env != NULL; env = env->next_cpu) {
         env->external_htab = spapr->htab;
@@ -352,7 +352,7 @@ static void ppc_spapr_init(ram_addr_t ram_size,
         hw_error("qemu: could not load LPAR rtas '%s'\n", filename);
         exit(1);
     }
-    qemu_free(filename);
+    g_free(filename);
 
     /* Set up Interrupt Controller */
     spapr->icp = xics_system_init(XICS_IRQS);
@@ -372,7 +372,7 @@ static void ppc_spapr_init(ram_addr_t ram_size,
         NICInfo *nd = &nd_table[i];
 
         if (!nd->model) {
-            nd->model = qemu_strdup("ibmveth");
+            nd->model = g_strdup("ibmveth");
         }
 
         if (strcmp(nd->model, "ibmveth") == 0) {
@@ -436,7 +436,7 @@ static void ppc_spapr_init(ram_addr_t ram_size,
             hw_error("qemu: could not load LPAR rtas '%s'\n", filename);
             exit(1);
         }
-        qemu_free(filename);
+        g_free(filename);
         spapr->entry_point = 0x100;
         initrd_base = 0;
         initrd_size = 0;
diff --git a/hw/spapr_vio.c b/hw/spapr_vio.c
index 481a804..ce6558b 100644
--- a/hw/spapr_vio.c
+++ b/hw/spapr_vio.c
@@ -160,7 +160,7 @@ static void rtce_init(VIOsPAPRDevice *dev)
         * sizeof(VIOsPAPR_RTCE);
 
     if (size) {
-        dev->rtce_table = qemu_mallocz(size);
+        dev->rtce_table = g_malloc0(size);
     }
 }
 
diff --git a/hw/spapr_vscsi.c b/hw/spapr_vscsi.c
index d98d1fd..fc9ac6a 100644
--- a/hw/spapr_vscsi.c
+++ b/hw/spapr_vscsi.c
@@ -788,7 +788,7 @@ static void vscsi_got_payload(VSCSIState *s, vscsi_crq *crq)
     if (spapr_tce_dma_read(&s->vdev, crq->s.IU_data_ptr, &req->iu,
                            crq->s.IU_length)) {
         fprintf(stderr, "vscsi_got_payload: DMA read failure !\n");
-        qemu_free(req);
+        g_free(req);
     }
     memcpy(&req->crq, crq, sizeof(vscsi_crq));
 
diff --git a/hw/stellaris.c b/hw/stellaris.c
index a280930..646eec7 100644
--- a/hw/stellaris.c
+++ b/hw/stellaris.c
@@ -605,7 +605,7 @@ static int stellaris_sys_init(uint32_t base, qemu_irq irq,
     int iomemtype;
     ssys_state *s;
 
-    s = (ssys_state *)qemu_mallocz(sizeof(ssys_state));
+    s = (ssys_state *)g_malloc0(sizeof(ssys_state));
     s->irq = irq;
     s->board = board;
     /* Most devices come preprogrammed with a MAC address in the user data. */
diff --git a/hw/stellaris_enet.c b/hw/stellaris_enet.c
index 1291931..f9bd3da 100644
--- a/hw/stellaris_enet.c
+++ b/hw/stellaris_enet.c
@@ -393,7 +393,7 @@ static void stellaris_enet_cleanup(VLANClientState *nc)
 
     cpu_unregister_io_memory(s->mmio_index);
 
-    qemu_free(s);
+    g_free(s);
 }
 
 static NetClientInfo net_stellaris_enet_info = {
diff --git a/hw/stellaris_input.c b/hw/stellaris_input.c
index 95604ec..68c600c 100644
--- a/hw/stellaris_input.c
+++ b/hw/stellaris_input.c
@@ -77,8 +77,8 @@ void stellaris_gamepad_init(int n, qemu_irq *irq, const int *keycode)
     gamepad_state *s;
     int i;
 
-    s = (gamepad_state *)qemu_mallocz(sizeof (gamepad_state));
-    s->buttons = (gamepad_button *)qemu_mallocz(n * sizeof (gamepad_button));
+    s = (gamepad_state *)g_malloc0(sizeof (gamepad_state));
+    s->buttons = (gamepad_button *)g_malloc0(n * sizeof (gamepad_button));
     for (i = 0; i < n; i++) {
         s->buttons[i].irq = irq[i];
         s->buttons[i].keycode = keycode[i];
diff --git a/hw/strongarm.c b/hw/strongarm.c
index 0e03d61..3a7fd6d 100644
--- a/hw/strongarm.c
+++ b/hw/strongarm.c
@@ -1529,7 +1529,7 @@ StrongARMState *sa1110_init(unsigned int sdram_size, const char *rev)
     qemu_irq *pic;
     int i;
 
-    s = qemu_mallocz(sizeof(StrongARMState));
+    s = g_malloc0(sizeof(StrongARMState));
 
     if (!rev) {
         rev = "sa1110-b5";
diff --git a/hw/sun4m.c b/hw/sun4m.c
index df3aa32..7516703 100644
--- a/hw/sun4m.c
+++ b/hw/sun4m.c
@@ -681,7 +681,7 @@ static void prom_init(target_phys_addr_t addr, const char *bios_name)
         if (ret < 0 || ret > PROM_SIZE_MAX) {
             ret = load_image_targphys(filename, addr, PROM_SIZE_MAX);
         }
-        qemu_free(filename);
+        g_free(filename);
     } else {
         ret = -1;
     }
diff --git a/hw/sun4u.c b/hw/sun4u.c
index 7b2d0b1..1b60e4e 100644
--- a/hw/sun4u.c
+++ b/hw/sun4u.c
@@ -351,7 +351,7 @@ static CPUTimer* cpu_timer_create(const char* name, CPUState *env,
                                   QEMUBHFunc *cb, uint32_t frequency,
                                   uint64_t disabled_mask)
 {
-    CPUTimer *timer = qemu_mallocz(sizeof (CPUTimer));
+    CPUTimer *timer = g_malloc0(sizeof (CPUTimer));
 
     timer->name = name;
     timer->frequency = frequency;
@@ -608,7 +608,7 @@ static void prom_init(target_phys_addr_t addr, const char *bios_name)
         if (ret < 0 || ret > PROM_SIZE_MAX) {
             ret = load_image_targphys(filename, addr, PROM_SIZE_MAX);
         }
-        qemu_free(filename);
+        g_free(filename);
     } else {
         ret = -1;
     }
@@ -723,7 +723,7 @@ static CPUState *cpu_devinit(const char *cpu_model, const struct hwdef *hwdef)
     env->hstick = cpu_timer_create("hstick", env, hstick_irq,
                                     hstick_frequency, TICK_INT_DIS);
 
-    reset_info = qemu_mallocz(sizeof(ResetData));
+    reset_info = g_malloc0(sizeof(ResetData));
     reset_info->env = env;
     reset_info->prom_addr = hwdef->prom_addr;
     qemu_register_reset(main_cpu_reset, reset_info);
diff --git a/hw/syborg_interrupt.c b/hw/syborg_interrupt.c
index 5217983..1b0f3bb 100644
--- a/hw/syborg_interrupt.c
+++ b/hw/syborg_interrupt.c
@@ -213,7 +213,7 @@ static int syborg_int_init(SysBusDevice *dev)
                                        syborg_int_writefn, s,
                                        DEVICE_NATIVE_ENDIAN);
     sysbus_init_mmio(dev, 0x1000, iomemtype);
-    s->flags = qemu_mallocz(s->num_irqs * sizeof(syborg_int_flags));
+    s->flags = g_malloc0(s->num_irqs * sizeof(syborg_int_flags));
 
     register_savevm(&dev->qdev, "syborg_int", -1, 1, syborg_int_save,
                     syborg_int_load, s);
diff --git a/hw/syborg_keyboard.c b/hw/syborg_keyboard.c
index 706a039..82b9dc0 100644
--- a/hw/syborg_keyboard.c
+++ b/hw/syborg_keyboard.c
@@ -195,7 +195,7 @@ static int syborg_keyboard_init(SysBusDevice *dev)
         fprintf(stderr, "syborg_keyboard: fifo too small\n");
         s->fifo_size = 16;
     }
-    s->key_fifo = qemu_mallocz(s->fifo_size * sizeof(s->key_fifo[0]));
+    s->key_fifo = g_malloc0(s->fifo_size * sizeof(s->key_fifo[0]));
 
     qemu_add_kbd_event_handler(syborg_keyboard_event, s);
 
diff --git a/hw/syborg_pointer.c b/hw/syborg_pointer.c
index 2f99707..b91214d 100644
--- a/hw/syborg_pointer.c
+++ b/hw/syborg_pointer.c
@@ -198,7 +198,7 @@ static int syborg_pointer_init(SysBusDevice *dev)
         fprintf(stderr, "syborg_pointer: fifo too small\n");
         s->fifo_size = 16;
     }
-    s->event_fifo = qemu_mallocz(s->fifo_size * sizeof(s->event_fifo[0]));
+    s->event_fifo = g_malloc0(s->fifo_size * sizeof(s->event_fifo[0]));
 
     qemu_add_mouse_event_handler(syborg_pointer_event, s, s->absolute,
                                  "Syborg Pointer");
diff --git a/hw/syborg_serial.c b/hw/syborg_serial.c
index 2ef7175..4d0ec04 100644
--- a/hw/syborg_serial.c
+++ b/hw/syborg_serial.c
@@ -311,7 +311,7 @@ static int syborg_serial_init(SysBusDevice *dev)
         fprintf(stderr, "syborg_serial: fifo too small\n");
         s->fifo_size = 16;
     }
-    s->read_fifo = qemu_mallocz(s->fifo_size * sizeof(s->read_fifo[0]));
+    s->read_fifo = g_malloc0(s->fifo_size * sizeof(s->read_fifo[0]));
 
     return 0;
 }
diff --git a/hw/sysbus.c b/hw/sysbus.c
index ea442ac..f8f1746 100644
--- a/hw/sysbus.c
+++ b/hw/sysbus.c
@@ -158,8 +158,8 @@ void sysbus_register_dev(const char *name, size_t size, sysbus_initfn init)
 {
     SysBusDeviceInfo *info;
 
-    info = qemu_mallocz(sizeof(*info));
-    info->qdev.name = qemu_strdup(name);
+    info = g_malloc0(sizeof(*info));
+    info->qdev.name = g_strdup(name);
     info->qdev.size = size;
     info->init = init;
     sysbus_register_withprop(info);
diff --git a/hw/tc58128.c b/hw/tc58128.c
index 61b99dd..ee3ecad 100644
--- a/hw/tc58128.c
+++ b/hw/tc58128.c
@@ -30,7 +30,7 @@ static void init_dev(tc58128_dev * dev, const char *filename)
     int ret, blocks;
 
     dev->state = WAIT;
-    dev->flash_contents = qemu_mallocz(FLASH_SIZE);
+    dev->flash_contents = g_malloc0(FLASH_SIZE);
     memset(dev->flash_contents, 0xff, FLASH_SIZE);
     if (!dev->flash_contents) {
 	fprintf(stderr, "could not alloc memory for flash\n");
diff --git a/hw/tc6393xb.c b/hw/tc6393xb.c
index a1c48bf..c28005a 100644
--- a/hw/tc6393xb.c
+++ b/hw/tc6393xb.c
@@ -579,7 +579,7 @@ TC6393xbState *tc6393xb_init(uint32_t base, qemu_irq irq)
         tc6393xb_writel,
     };
 
-    s = (TC6393xbState *) qemu_mallocz(sizeof(TC6393xbState));
+    s = (TC6393xbState *) g_malloc0(sizeof(TC6393xbState));
     s->irq = irq;
     s->gpio_in = qemu_allocate_irqs(tc6393xb_gpio_set, s, TC6393XB_GPIOS);
 
diff --git a/hw/tsc2005.c b/hw/tsc2005.c
index c95dcf0..9a500eb 100644
--- a/hw/tsc2005.c
+++ b/hw/tsc2005.c
@@ -524,7 +524,7 @@ void *tsc2005_init(qemu_irq pintdav)
     TSC2005State *s;
 
     s = (TSC2005State *)
-            qemu_mallocz(sizeof(TSC2005State));
+            g_malloc0(sizeof(TSC2005State));
     s->x = 400;
     s->y = 240;
     s->pressure = 0;
diff --git a/hw/tsc210x.c b/hw/tsc210x.c
index 96446dd..3c448a6 100644
--- a/hw/tsc210x.c
+++ b/hw/tsc210x.c
@@ -1105,7 +1105,7 @@ uWireSlave *tsc2102_init(qemu_irq pint)
     TSC210xState *s;
 
     s = (TSC210xState *)
-            qemu_mallocz(sizeof(TSC210xState));
+            g_malloc0(sizeof(TSC210xState));
     memset(s, 0, sizeof(TSC210xState));
     s->x = 160;
     s->y = 160;
@@ -1154,7 +1154,7 @@ uWireSlave *tsc2301_init(qemu_irq penirq, qemu_irq kbirq, qemu_irq dav)
     TSC210xState *s;
 
     s = (TSC210xState *)
-            qemu_mallocz(sizeof(TSC210xState));
+            g_malloc0(sizeof(TSC210xState));
     memset(s, 0, sizeof(TSC210xState));
     s->x = 400;
     s->y = 240;
diff --git a/hw/tusb6010.c b/hw/tusb6010.c
index ccd01ad..d7ae527 100644
--- a/hw/tusb6010.c
+++ b/hw/tusb6010.c
@@ -729,7 +729,7 @@ static void tusb_musb_core_intr(void *opaque, int source, int level)
 
 TUSBState *tusb6010_init(qemu_irq intr)
 {
-    TUSBState *s = qemu_mallocz(sizeof(*s));
+    TUSBState *s = g_malloc0(sizeof(*s));
 
     s->test_reset = TUSB_PROD_TEST_RESET_VAL;
     s->host_mode = 0;
diff --git a/hw/usb-bus.c b/hw/usb-bus.c
index f1dd55e..c0bbc7c 100644
--- a/hw/usb-bus.c
+++ b/hw/usb-bus.c
@@ -342,7 +342,7 @@ static void usb_bus_dev_print(Monitor *mon, DeviceState *qdev, int indent)
 static char *usb_get_dev_path(DeviceState *qdev)
 {
     USBDevice *dev = DO_UPCAST(USBDevice, qdev, qdev);
-    return qemu_strdup(dev->port->path);
+    return g_strdup(dev->port->path);
 }
 
 static char *usb_get_fw_dev_path(DeviceState *qdev)
@@ -353,7 +353,7 @@ static char *usb_get_fw_dev_path(DeviceState *qdev)
     long nr;
 
     fw_len = 32 + strlen(dev->port->path) * 6;
-    fw_path = qemu_malloc(fw_len);
+    fw_path = g_malloc(fw_len);
     in = dev->port->path;
     while (fw_len - pos > 0) {
         nr = strtol(in, &in, 10);
diff --git a/hw/usb-desc.c b/hw/usb-desc.c
index bc6858f..ae2d384 100644
--- a/hw/usb-desc.c
+++ b/hw/usb-desc.c
@@ -283,12 +283,12 @@ void usb_desc_set_string(USBDevice *dev, uint8_t index, const char *str)
         }
     }
     if (s == NULL) {
-        s = qemu_mallocz(sizeof(*s));
+        s = g_malloc0(sizeof(*s));
         s->index = index;
         QLIST_INSERT_HEAD(&dev->strings, s, next);
     }
-    qemu_free(s->str);
-    s->str = qemu_strdup(str);
+    g_free(s->str);
+    s->str = g_strdup(str);
 }
 
 const char *usb_desc_get_string(USBDevice *dev, uint8_t index)
diff --git a/hw/usb-ehci.c b/hw/usb-ehci.c
index c9d0a69..47a7fb9 100644
--- a/hw/usb-ehci.c
+++ b/hw/usb-ehci.c
@@ -652,7 +652,7 @@ static EHCIQueue *ehci_alloc_queue(EHCIState *ehci, int async)
 {
     EHCIQueue *q;
 
-    q = qemu_mallocz(sizeof(*q));
+    q = g_malloc0(sizeof(*q));
     q->ehci = ehci;
     q->async_schedule = async;
     QTAILQ_INSERT_HEAD(&ehci->queues, q, next);
@@ -667,7 +667,7 @@ static void ehci_free_queue(EHCIQueue *q)
         usb_cancel_packet(&q->packet);
     }
     QTAILQ_REMOVE(&q->ehci->queues, q, next);
-    qemu_free(q);
+    g_free(q);
 }
 
 static EHCIQueue *ehci_find_queue_by_qh(EHCIState *ehci, uint32_t addr)
diff --git a/hw/usb-musb.c b/hw/usb-musb.c
index d3ccde9..799fa6e 100644
--- a/hw/usb-musb.c
+++ b/hw/usb-musb.c
@@ -342,7 +342,7 @@ struct MUSBState {
 
 struct MUSBState *musb_init(qemu_irq *irqs)
 {
-    MUSBState *s = qemu_mallocz(sizeof(*s));
+    MUSBState *s = g_malloc0(sizeof(*s));
     int i;
 
     s->irqs = irqs;
diff --git a/hw/usb-net.c b/hw/usb-net.c
index 0cb47d6..a8b7c8d 100644
--- a/hw/usb-net.c
+++ b/hw/usb-net.c
@@ -844,7 +844,7 @@ static int rndis_get_response(USBNetState *s, uint8_t *buf)
     QTAILQ_REMOVE(&s->rndis_resp, r, entries);
     ret = r->length;
     memcpy(buf, r->buf, r->length);
-    qemu_free(r);
+    g_free(r);
 
     return ret;
 }
@@ -852,7 +852,7 @@ static int rndis_get_response(USBNetState *s, uint8_t *buf)
 static void *rndis_queue_response(USBNetState *s, unsigned int length)
 {
     struct rndis_response *r =
-            qemu_mallocz(sizeof(struct rndis_response) + length);
+            g_malloc0(sizeof(struct rndis_response) + length);
 
     QTAILQ_INSERT_TAIL(&s->rndis_resp, r, entries);
     r->length = length;
@@ -866,7 +866,7 @@ static void rndis_clear_responsequeue(USBNetState *s)
 
     while ((r = s->rndis_resp.tqh_first)) {
         QTAILQ_REMOVE(&s->rndis_resp, r, entries);
-        qemu_free(r);
+        g_free(r);
     }
 }
 
diff --git a/hw/usb-uhci.c b/hw/usb-uhci.c
index 16088d7..6ca7ca8 100644
--- a/hw/usb-uhci.c
+++ b/hw/usb-uhci.c
@@ -168,7 +168,7 @@ typedef struct UHCI_QH {
 
 static UHCIAsync *uhci_async_alloc(UHCIState *s)
 {
-    UHCIAsync *async = qemu_malloc(sizeof(UHCIAsync));
+    UHCIAsync *async = g_malloc(sizeof(UHCIAsync));
 
     memset(&async->packet, 0, sizeof(async->packet));
     async->uhci  = s;
@@ -187,7 +187,7 @@ static void uhci_async_free(UHCIState *s, UHCIAsync *async)
 {
     usb_packet_cleanup(&async->packet);
     qemu_sglist_destroy(&async->sgl);
-    qemu_free(async);
+    g_free(async);
 }
 
 static void uhci_async_link(UHCIState *s, UHCIAsync *async)
diff --git a/hw/vga-isa-mm.c b/hw/vga-isa-mm.c
index 96e6e7d..b934978 100644
--- a/hw/vga-isa-mm.c
+++ b/hw/vga-isa-mm.c
@@ -102,11 +102,11 @@ static void vga_mm_init(ISAVGAMMState *s, target_phys_addr_t vram_base,
     MemoryRegion *s_ioport_ctrl, *vga_io_memory;
 
     s->it_shift = it_shift;
-    s_ioport_ctrl = qemu_malloc(sizeof(*s_ioport_ctrl));
+    s_ioport_ctrl = g_malloc(sizeof(*s_ioport_ctrl));
     memory_region_init_io(s_ioport_ctrl, &vga_mm_ctrl_ops, s,
                           "vga-mm-ctrl", 0x100000);
 
-    vga_io_memory = qemu_malloc(sizeof(*vga_io_memory));
+    vga_io_memory = g_malloc(sizeof(*vga_io_memory));
     /* XXX: endianness? */
     memory_region_init_io(vga_io_memory, &vga_mem_ops, &s->vga,
                           "vga-mem", 0x20000);
@@ -125,7 +125,7 @@ int isa_vga_mm_init(target_phys_addr_t vram_base,
 {
     ISAVGAMMState *s;
 
-    s = qemu_mallocz(sizeof(*s));
+    s = g_malloc0(sizeof(*s));
 
     vga_common_init(&s->vga, VGA_RAM_SIZE);
     vga_mm_init(s, vram_base, ctrl_base, it_shift);
diff --git a/hw/vga.c b/hw/vga.c
index 33dc478..a190105 100644
--- a/hw/vga.c
+++ b/hw/vga.c
@@ -2234,7 +2234,7 @@ MemoryRegion *vga_init_io(VGACommonState *s)
 #endif
 #endif /* CONFIG_BOCHS_VBE */
 
-    vga_mem = qemu_malloc(sizeof(*vga_mem));
+    vga_mem = g_malloc(sizeof(*vga_mem));
     memory_region_init_io(vga_mem, &vga_mem_ops, s,
                           "vga-lowmem", 0x20000);
 
@@ -2302,7 +2302,7 @@ int ppm_save(const char *filename, struct DisplaySurface *ds)
         return -1;
     fprintf(f, "P6\n%d %d\n%d\n",
             ds->width, ds->height, 255);
-    linebuf = qemu_malloc(ds->width * 3);
+    linebuf = g_malloc(ds->width * 3);
     d1 = ds->data;
     for(y = 0; y < ds->height; y++) {
         d = d1;
@@ -2327,7 +2327,7 @@ int ppm_save(const char *filename, struct DisplaySurface *ds)
         ret = fwrite(linebuf, 1, pbuf - linebuf, f);
         (void)ret;
     }
-    qemu_free(linebuf);
+    g_free(linebuf);
     fclose(f);
     return 0;
 }
@@ -2336,7 +2336,7 @@ static DisplayChangeListener* vga_screen_dump_init(DisplayState *ds)
 {
     DisplayChangeListener *dcl;
 
-    dcl = qemu_mallocz(sizeof(DisplayChangeListener));
+    dcl = g_malloc0(sizeof(DisplayChangeListener));
     dcl->dpy_update = vga_save_dpy_update;
     dcl->dpy_resize = vga_save_dpy_resize;
     dcl->dpy_refresh = vga_save_dpy_refresh;
diff --git a/hw/vhost.c b/hw/vhost.c
index 19e7255..1886067 100644
--- a/hw/vhost.c
+++ b/hw/vhost.c
@@ -252,7 +252,7 @@ static inline void vhost_dev_log_resize(struct vhost_dev* dev, uint64_t size)
     uint64_t log_base;
     int r;
     if (size) {
-        log = qemu_mallocz(size * sizeof *log);
+        log = g_malloc0(size * sizeof *log);
     } else {
         log = NULL;
     }
@@ -262,7 +262,7 @@ static inline void vhost_dev_log_resize(struct vhost_dev* dev, uint64_t size)
     vhost_client_sync_dirty_bitmap(&dev->client, 0,
                                    (target_phys_addr_t)~0x0ull);
     if (dev->log) {
-        qemu_free(dev->log);
+        g_free(dev->log);
     }
     dev->log = log;
     dev->log_size = size;
@@ -348,7 +348,7 @@ static void vhost_client_set_memory(CPUPhysMemoryClient *client,
     uint64_t log_size;
     int r;
 
-    dev->mem = qemu_realloc(dev->mem, s);
+    dev->mem = g_realloc(dev->mem, s);
 
     if (log_dirty) {
         flags = IO_MEM_UNASSIGNED;
@@ -485,7 +485,7 @@ static int vhost_client_migration_log(CPUPhysMemoryClient *client,
             return r;
         }
         if (dev->log) {
-            qemu_free(dev->log);
+            g_free(dev->log);
         }
         dev->log = NULL;
         dev->log_size = 0;
@@ -669,7 +669,7 @@ int vhost_dev_init(struct vhost_dev *hdev, int devfd, bool force)
     hdev->client.migration_log = vhost_client_migration_log;
     hdev->client.log_start = NULL;
     hdev->client.log_stop = NULL;
-    hdev->mem = qemu_mallocz(offsetof(struct vhost_memory, regions));
+    hdev->mem = g_malloc0(offsetof(struct vhost_memory, regions));
     hdev->log = NULL;
     hdev->log_size = 0;
     hdev->log_enabled = false;
@@ -686,7 +686,7 @@ fail:
 void vhost_dev_cleanup(struct vhost_dev *hdev)
 {
     cpu_unregister_phys_memory_client(&hdev->client);
-    qemu_free(hdev->mem);
+    g_free(hdev->mem);
     close(hdev->control);
 }
 
@@ -734,7 +734,7 @@ int vhost_dev_start(struct vhost_dev *hdev, VirtIODevice *vdev)
     if (hdev->log_enabled) {
         hdev->log_size = vhost_get_log_size(hdev);
         hdev->log = hdev->log_size ?
-            qemu_mallocz(hdev->log_size * sizeof *hdev->log) : NULL;
+            g_malloc0(hdev->log_size * sizeof *hdev->log) : NULL;
         r = ioctl(hdev->control, VHOST_SET_LOG_BASE,
                   (uint64_t)(unsigned long)hdev->log);
         if (r < 0) {
@@ -782,7 +782,7 @@ void vhost_dev_stop(struct vhost_dev *hdev, VirtIODevice *vdev)
     assert (r >= 0);
 
     hdev->started = false;
-    qemu_free(hdev->log);
+    g_free(hdev->log);
     hdev->log = NULL;
     hdev->log_size = 0;
 }
diff --git a/hw/vhost_net.c b/hw/vhost_net.c
index b6dc592..a559812 100644
--- a/hw/vhost_net.c
+++ b/hw/vhost_net.c
@@ -92,7 +92,7 @@ struct vhost_net *vhost_net_init(VLANClientState *backend, int devfd,
                                  bool force)
 {
     int r;
-    struct vhost_net *net = qemu_malloc(sizeof *net);
+    struct vhost_net *net = g_malloc(sizeof *net);
     if (!backend) {
         fprintf(stderr, "vhost-net requires backend to be setup\n");
         goto fail;
@@ -125,7 +125,7 @@ struct vhost_net *vhost_net_init(VLANClientState *backend, int devfd,
     vhost_net_ack_features(net, 0);
     return net;
 fail:
-    qemu_free(net);
+    g_free(net);
     return NULL;
 }
 
@@ -198,7 +198,7 @@ void vhost_net_cleanup(struct vhost_net *net)
     if (net->dev.acked_features & (1 << VIRTIO_NET_F_MRG_RXBUF)) {
         tap_set_vnet_hdr_len(net->vc, sizeof(struct virtio_net_hdr));
     }
-    qemu_free(net);
+    g_free(net);
 }
 #else
 struct vhost_net *vhost_net_init(VLANClientState *backend, int devfd,
diff --git a/hw/virtex_ml507.c b/hw/virtex_ml507.c
index 7bde8c7..333050c 100644
--- a/hw/virtex_ml507.c
+++ b/hw/virtex_ml507.c
@@ -102,7 +102,7 @@ static CPUState *ppc440_init_xilinx(ram_addr_t *ram_size,
     ppc_dcr_init(env, NULL, NULL);
 
     /* interrupt controller */
-    irqs = qemu_mallocz(sizeof(qemu_irq) * PPCUIC_OUTPUT_NB);
+    irqs = g_malloc0(sizeof(qemu_irq) * PPCUIC_OUTPUT_NB);
     irqs[PPCUIC_OUTPUT_INT] = ((qemu_irq *)env->irq_inputs)[PPC40x_INPUT_INT];
     irqs[PPCUIC_OUTPUT_CINT] = ((qemu_irq *)env->irq_inputs)[PPC40x_INPUT_CINT];
     ppcuic_init(env, irqs, 0x0C0, 0, 1);
@@ -154,7 +154,7 @@ static int xilinx_load_device_tree(target_phys_addr_t addr,
         path = qemu_find_file(QEMU_FILE_TYPE_BIOS, BINARY_DEVICE_TREE_FILE);
         if (path) {
             fdt = load_device_tree(path, &fdt_size);
-            qemu_free(path);
+            g_free(path);
         }
         if (!fdt) {
             return 0;
@@ -173,7 +173,7 @@ static int xilinx_load_device_tree(target_phys_addr_t addr,
         path = qemu_find_file(QEMU_FILE_TYPE_BIOS, BINARY_DEVICE_TREE_FILE);
         if (path) {
             fdt_size = load_image_targphys(path, addr, 0x10000);
-            qemu_free(path);
+            g_free(path);
         }
     }
 
diff --git a/hw/virtio-blk.c b/hw/virtio-blk.c
index 836dbc3..dad8c0a 100644
--- a/hw/virtio-blk.c
+++ b/hw/virtio-blk.c
@@ -59,7 +59,7 @@ static void virtio_blk_req_complete(VirtIOBlockReq *req, int status)
     virtqueue_push(s->vq, &req->elem, req->qiov.size + sizeof(*req->in));
     virtio_notify(&s->vdev, s->vq);
 
-    qemu_free(req);
+    g_free(req);
 }
 
 static int virtio_blk_handle_rw_error(VirtIOBlockReq *req, int error,
@@ -117,7 +117,7 @@ static void virtio_blk_flush_complete(void *opaque, int ret)
 
 static VirtIOBlockReq *virtio_blk_alloc_request(VirtIOBlock *s)
 {
-    VirtIOBlockReq *req = qemu_malloc(sizeof(*req));
+    VirtIOBlockReq *req = g_malloc(sizeof(*req));
     req->dev = s;
     req->qiov.size = 0;
     req->next = NULL;
@@ -130,7 +130,7 @@ static VirtIOBlockReq *virtio_blk_get_request(VirtIOBlock *s)
 
     if (req != NULL) {
         if (!virtqueue_pop(s->vq, &req->elem)) {
-            qemu_free(req);
+            g_free(req);
             return NULL;
         }
     }
diff --git a/hw/virtio-net.c b/hw/virtio-net.c
index 3f10391..8c2f460 100644
--- a/hw/virtio-net.c
+++ b/hw/virtio-net.c
@@ -1039,9 +1039,9 @@ VirtIODevice *virtio_net_init(DeviceState *dev, NICConf *conf,
     n->mergeable_rx_bufs = 0;
     n->promisc = 1; /* for compatibility */
 
-    n->mac_table.macs = qemu_mallocz(MAC_TABLE_ENTRIES * ETH_ALEN);
+    n->mac_table.macs = g_malloc0(MAC_TABLE_ENTRIES * ETH_ALEN);
 
-    n->vlans = qemu_mallocz(MAX_VLAN >> 3);
+    n->vlans = g_malloc0(MAX_VLAN >> 3);
 
     n->qdev = dev;
     register_savevm(dev, "virtio-net", -1, VIRTIO_NET_VM_VERSION,
@@ -1063,8 +1063,8 @@ void virtio_net_exit(VirtIODevice *vdev)
 
     unregister_savevm(n->qdev, "virtio-net", n);
 
-    qemu_free(n->mac_table.macs);
-    qemu_free(n->vlans);
+    g_free(n->mac_table.macs);
+    g_free(n->vlans);
 
     if (n->tx_timer) {
         qemu_del_timer(n->tx_timer);
diff --git a/hw/virtio-serial-bus.c b/hw/virtio-serial-bus.c
index c5eb931..a4825b9 100644
--- a/hw/virtio-serial-bus.c
+++ b/hw/virtio-serial-bus.c
@@ -383,14 +383,14 @@ static void handle_control_message(VirtIOSerial *vser, void *buf, size_t len)
             stw_p(&cpkt.value, 1);
 
             buffer_len = sizeof(cpkt) + strlen(port->name) + 1;
-            buffer = qemu_malloc(buffer_len);
+            buffer = g_malloc(buffer_len);
 
             memcpy(buffer, &cpkt, sizeof(cpkt));
             memcpy(buffer + sizeof(cpkt), port->name, strlen(port->name));
             buffer[buffer_len - 1] = 0;
 
             send_control_msg(port, buffer, buffer_len);
-            qemu_free(buffer);
+            g_free(buffer);
         }
 
         if (port->host_connected) {
@@ -447,9 +447,9 @@ static void control_out(VirtIODevice *vdev, VirtQueue *vq)
          * if the size of the buf differs
          */
         if (cur_len > len) {
-            qemu_free(buf);
+            g_free(buf);
 
-            buf = qemu_malloc(cur_len);
+            buf = g_malloc(cur_len);
             len = cur_len;
         }
         copied = iov_to_buf(elem.out_sg, elem.out_num, buf, 0, len);
@@ -457,7 +457,7 @@ static void control_out(VirtIODevice *vdev, VirtQueue *vq)
         handle_control_message(vser, buf, copied);
         virtqueue_push(vq, &elem, 0);
     }
-    qemu_free(buf);
+    g_free(buf);
     virtio_notify(vdev, vq);
 }
 
@@ -862,8 +862,8 @@ VirtIODevice *virtio_serial_init(DeviceState *dev, virtio_serial_conf *conf)
     QTAILQ_INIT(&vser->ports);
 
     vser->bus.max_nr_ports = conf->max_virtserial_ports;
-    vser->ivqs = qemu_malloc(conf->max_virtserial_ports * sizeof(VirtQueue *));
-    vser->ovqs = qemu_malloc(conf->max_virtserial_ports * sizeof(VirtQueue *));
+    vser->ivqs = g_malloc(conf->max_virtserial_ports * sizeof(VirtQueue *));
+    vser->ovqs = g_malloc(conf->max_virtserial_ports * sizeof(VirtQueue *));
 
     /* Add a queue for host to guest transfers for port 0 (backward compat) */
     vser->ivqs[0] = virtio_add_queue(vdev, 128, handle_input);
@@ -889,7 +889,7 @@ VirtIODevice *virtio_serial_init(DeviceState *dev, virtio_serial_conf *conf)
     }
 
     vser->config.max_nr_ports = tswap32(conf->max_virtserial_ports);
-    vser->ports_map = qemu_mallocz(((conf->max_virtserial_ports + 31) / 32)
+    vser->ports_map = g_malloc0(((conf->max_virtserial_ports + 31) / 32)
         * sizeof(vser->ports_map[0]));
     /*
      * Reserve location 0 for a console port for backward compat
@@ -919,9 +919,9 @@ void virtio_serial_exit(VirtIODevice *vdev)
 
     unregister_savevm(vser->qdev, "virtio-console", vser);
 
-    qemu_free(vser->ivqs);
-    qemu_free(vser->ovqs);
-    qemu_free(vser->ports_map);
+    g_free(vser->ivqs);
+    g_free(vser->ovqs);
+    g_free(vser->ports_map);
 
     virtio_cleanup(vdev);
 }
diff --git a/hw/virtio.c b/hw/virtio.c
index 93dfb1e..13aa0fa 100644
--- a/hw/virtio.c
+++ b/hw/virtio.c
@@ -832,9 +832,9 @@ void virtio_cleanup(VirtIODevice *vdev)
 {
     qemu_del_vm_change_state_handler(vdev->vmstate);
     if (vdev->config)
-        qemu_free(vdev->config);
-    qemu_free(vdev->vq);
-    qemu_free(vdev);
+        g_free(vdev->config);
+    g_free(vdev->vq);
+    g_free(vdev);
 }
 
 static void virtio_vmstate_change(void *opaque, int running, int reason)
@@ -862,14 +862,14 @@ VirtIODevice *virtio_common_init(const char *name, uint16_t device_id,
     VirtIODevice *vdev;
     int i;
 
-    vdev = qemu_mallocz(struct_size);
+    vdev = g_malloc0(struct_size);
 
     vdev->device_id = device_id;
     vdev->status = 0;
     vdev->isr = 0;
     vdev->queue_sel = 0;
     vdev->config_vector = VIRTIO_NO_VECTOR;
-    vdev->vq = qemu_mallocz(sizeof(VirtQueue) * VIRTIO_PCI_QUEUE_MAX);
+    vdev->vq = g_malloc0(sizeof(VirtQueue) * VIRTIO_PCI_QUEUE_MAX);
     vdev->vm_running = vm_running;
     for(i = 0; i < VIRTIO_PCI_QUEUE_MAX; i++) {
         vdev->vq[i].vector = VIRTIO_NO_VECTOR;
@@ -879,7 +879,7 @@ VirtIODevice *virtio_common_init(const char *name, uint16_t device_id,
     vdev->name = name;
     vdev->config_len = config_size;
     if (vdev->config_len)
-        vdev->config = qemu_mallocz(config_size);
+        vdev->config = g_malloc0(config_size);
     else
         vdev->config = NULL;
 
diff --git a/hw/vmware_vga.c b/hw/vmware_vga.c
index d5cfa70..a840cbd 100644
--- a/hw/vmware_vga.c
+++ b/hw/vmware_vga.c
@@ -1068,7 +1068,7 @@ static void vmsvga_screen_dump(void *opaque, const char *filename)
         DisplaySurface *ds = qemu_create_displaysurface_from(s->width,
                 s->height, 32, ds_get_linesize(s->vga.ds), s->vga.vram_ptr);
         ppm_save(filename, ds);
-        qemu_free(ds);
+        g_free(ds);
     }
 }
 
@@ -1210,7 +1210,7 @@ static const VMStateDescription vmstate_vmware_vga = {
 static void vmsvga_init(struct vmsvga_state_s *s, int vga_ram_size)
 {
     s->scratch_size = SVGA_SCRATCH_SIZE;
-    s->scratch = qemu_malloc(s->scratch_size * 4);
+    s->scratch = g_malloc(s->scratch_size * 4);
 
     s->vga.ds = graphic_console_init(vmsvga_update_display,
                                      vmsvga_invalidate_display,
@@ -1274,7 +1274,7 @@ static int pci_vmsvga_initfn(PCIDevice *dev)
     MemoryRegion *iomem;
 
 #ifdef DIRECT_VRAM
-    DirectMem *directmem = qemu_malloc(sizeof(*directmem));
+    DirectMem *directmem = g_malloc(sizeof(*directmem));
 
     iomem = &directmem->mr;
     memory_region_init_io(iomem, &vmsvga_vram_io_ops, &s->chip, "vmsvga",
diff --git a/hw/wm8750.c b/hw/wm8750.c
index c9c6744..39383f4 100644
--- a/hw/wm8750.c
+++ b/hw/wm8750.c
@@ -625,7 +625,7 @@ static void wm8750_fini(i2c_slave *i2c)
     WM8750State *s = (WM8750State *) i2c;
     wm8750_reset(&s->i2c);
     AUD_remove_card(&s->card);
-    qemu_free(s);
+    g_free(s);
 }
 #endif
 
diff --git a/hw/xen_backend.c b/hw/xen_backend.c
index d881fa2..aa64267 100644
--- a/hw/xen_backend.c
+++ b/hw/xen_backend.c
@@ -75,8 +75,8 @@ char *xenstore_read_str(const char *base, const char *node)
     str = xs_read(xenstore, 0, abspath, &len);
     if (str != NULL) {
         /* move to qemu-allocated memory to make sure
-         * callers can savely qemu_free() stuff. */
-        ret = qemu_strdup(str);
+         * callers can savely g_free() stuff. */
+        ret = g_strdup(str);
         free(str);
     }
     return ret;
@@ -99,7 +99,7 @@ int xenstore_read_int(const char *base, const char *node, int *ival)
     if (val && 1 == sscanf(val, "%d", ival)) {
         rc = 0;
     }
-    qemu_free(val);
+    g_free(val);
     return rc;
 }
 
@@ -199,7 +199,7 @@ static struct XenDevice *xen_be_get_xendev(const char *type, int dom, int dev,
     }
 
     /* init new xendev */
-    xendev = qemu_mallocz(ops->size);
+    xendev = g_malloc0(ops->size);
     xendev->type  = type;
     xendev->dom   = dom;
     xendev->dev   = dev;
@@ -218,7 +218,7 @@ static struct XenDevice *xen_be_get_xendev(const char *type, int dom, int dev,
     xendev->evtchndev = xen_xc_evtchn_open(NULL, 0);
     if (xendev->evtchndev == XC_HANDLER_INITIAL_VALUE) {
         xen_be_printf(NULL, 0, "can't open evtchn device\n");
-        qemu_free(xendev);
+        g_free(xendev);
         return NULL;
     }
     fcntl(xc_evtchn_fd(xendev->evtchndev), F_SETFD, FD_CLOEXEC);
@@ -228,7 +228,7 @@ static struct XenDevice *xen_be_get_xendev(const char *type, int dom, int dev,
         if (xendev->gnttabdev == XC_HANDLER_INITIAL_VALUE) {
             xen_be_printf(NULL, 0, "can't open gnttab device\n");
             xc_evtchn_close(xendev->evtchndev);
-            qemu_free(xendev);
+            g_free(xendev);
             return NULL;
         }
     } else {
@@ -275,7 +275,7 @@ static struct XenDevice *xen_be_del_xendev(int dom, int dev)
             char token[XEN_BUFSIZE];
             snprintf(token, sizeof(token), "fe:%p", xendev);
             xs_unwatch(xenstore, xendev->fe, token);
-            qemu_free(xendev->fe);
+            g_free(xendev->fe);
         }
 
         if (xendev->evtchndev != XC_HANDLER_INITIAL_VALUE) {
@@ -286,7 +286,7 @@ static struct XenDevice *xen_be_del_xendev(int dom, int dev)
         }
 
         QTAILQ_REMOVE(&xendevs, xendev, next);
-        qemu_free(xendev);
+        g_free(xendev);
     }
     return NULL;
 }
@@ -328,7 +328,7 @@ static void xen_be_frontend_changed(struct XenDevice *xendev, const char *node)
         xendev->fe_state = fe_state;
     }
     if (node == NULL  ||  strcmp(node, "protocol") == 0) {
-        qemu_free(xendev->protocol);
+        g_free(xendev->protocol);
         xendev->protocol = xenstore_read_fe_str(xendev, "protocol");
         if (xendev->protocol) {
             xen_be_printf(xendev, 1, "frontend protocol: %s\n", xendev->protocol);
diff --git a/hw/xen_console.c b/hw/xen_console.c
index 8ef104c..99ff442 100644
--- a/hw/xen_console.c
+++ b/hw/xen_console.c
@@ -70,7 +70,7 @@ static void buffer_append(struct XenConsole *con)
 
     if ((buffer->capacity - buffer->size) < size) {
 	buffer->capacity += (size + 1024);
-	buffer->data = qemu_realloc(buffer->data, buffer->capacity);
+	buffer->data = g_realloc(buffer->data, buffer->capacity);
     }
 
     while (cons != prod)
@@ -89,7 +89,7 @@ static void buffer_append(struct XenConsole *con)
 	uint8_t *maxpos = buffer->data + buffer->max_capacity;
 
 	memmove(maxpos - over, maxpos, over);
-	buffer->data = qemu_realloc(buffer->data, buffer->max_capacity);
+	buffer->data = g_realloc(buffer->data, buffer->max_capacity);
 	buffer->size = buffer->capacity = buffer->max_capacity;
 
 	if (buffer->consumed > buffer->max_capacity - over)
@@ -208,7 +208,7 @@ static int con_init(struct XenDevice *xendev)
     xenstore_store_pv_console_info(con->xendev.dev, con->chr);
 
 out:
-    qemu_free(type);
+    g_free(type);
     return ret;
 }
 
diff --git a/hw/xen_devconfig.c b/hw/xen_devconfig.c
index 6926c54..41accbb 100644
--- a/hw/xen_devconfig.c
+++ b/hw/xen_devconfig.c
@@ -14,7 +14,7 @@ static void xen_config_cleanup_dir(char *dir)
 {
     struct xs_dirs *d;
 
-    d = qemu_malloc(sizeof(*d));
+    d = g_malloc(sizeof(*d));
     d->xs_dir = dir;
     QTAILQ_INSERT_TAIL(&xs_cleanup, d, list);
 }
@@ -43,7 +43,7 @@ static int xen_config_dev_mkdir(char *dev, int p)
 	xen_be_printf(NULL, 0, "xs_mkdir %s: failed\n", dev);
 	return -1;
     }
-    xen_config_cleanup_dir(qemu_strdup(dev));
+    xen_config_cleanup_dir(g_strdup(dev));
 
     if (!xs_set_permissions(xenstore, 0, dev, perms, 2)) {
 	xen_be_printf(NULL, 0, "xs_set_permissions %s: failed\n", dev);
diff --git a/hw/xen_disk.c b/hw/xen_disk.c
index add815f..31f9151 100644
--- a/hw/xen_disk.c
+++ b/hw/xen_disk.c
@@ -124,7 +124,7 @@ static struct ioreq *ioreq_start(struct XenBlkDev *blkdev)
             goto out;
         }
         /* allocate new struct */
-        ioreq = qemu_mallocz(sizeof(*ioreq));
+        ioreq = g_malloc0(sizeof(*ioreq));
         ioreq->blkdev = blkdev;
         blkdev->requests_total++;
         qemu_iovec_init(&ioreq->v, BLKIF_MAX_SEGMENTS_PER_REQUEST);
@@ -716,15 +716,15 @@ static int blk_init(struct XenDevice *xendev)
     return 0;
 
 out_error:
-    qemu_free(blkdev->params);
+    g_free(blkdev->params);
     blkdev->params = NULL;
-    qemu_free(blkdev->mode);
+    g_free(blkdev->mode);
     blkdev->mode = NULL;
-    qemu_free(blkdev->type);
+    g_free(blkdev->type);
     blkdev->type = NULL;
-    qemu_free(blkdev->dev);
+    g_free(blkdev->dev);
     blkdev->dev = NULL;
-    qemu_free(blkdev->devtype);
+    g_free(blkdev->devtype);
     blkdev->devtype = NULL;
     return -1;
 }
@@ -822,14 +822,14 @@ static int blk_free(struct XenDevice *xendev)
         ioreq = QLIST_FIRST(&blkdev->freelist);
         QLIST_REMOVE(ioreq, list);
         qemu_iovec_destroy(&ioreq->v);
-        qemu_free(ioreq);
+        g_free(ioreq);
     }
 
-    qemu_free(blkdev->params);
-    qemu_free(blkdev->mode);
-    qemu_free(blkdev->type);
-    qemu_free(blkdev->dev);
-    qemu_free(blkdev->devtype);
+    g_free(blkdev->params);
+    g_free(blkdev->mode);
+    g_free(blkdev->type);
+    g_free(blkdev->dev);
+    g_free(blkdev->devtype);
     qemu_bh_delete(blkdev->bh);
     return 0;
 }
diff --git a/hw/xen_nic.c b/hw/xen_nic.c
index ff86491..b28b156 100644
--- a/hw/xen_nic.c
+++ b/hw/xen_nic.c
@@ -183,7 +183,7 @@ static void net_tx_packets(struct XenNetDev *netdev)
             if (txreq.flags & NETTXF_csum_blank) {
                 /* have read-only mapping -> can't fill checksum in-place */
                 if (!tmpbuf) {
-                    tmpbuf = qemu_malloc(XC_PAGE_SIZE);
+                    tmpbuf = g_malloc(XC_PAGE_SIZE);
                 }
                 memcpy(tmpbuf, page + txreq.offset, txreq.size);
                 net_checksum_calculate(tmpbuf, txreq.size);
@@ -199,7 +199,7 @@ static void net_tx_packets(struct XenNetDev *netdev)
         }
         netdev->tx_work = 0;
     }
-    qemu_free(tmpbuf);
+    g_free(tmpbuf);
 }
 
 /* ------------------------------------------------------------- */
@@ -423,7 +423,7 @@ static int net_free(struct XenDevice *xendev)
 {
     struct XenNetDev *netdev = container_of(xendev, struct XenNetDev, xendev);
 
-    qemu_free(netdev->mac);
+    g_free(netdev->mac);
     return 0;
 }
 
diff --git a/hw/xenfb.c b/hw/xenfb.c
index 0a01ae3..d532d3e 100644
--- a/hw/xenfb.c
+++ b/hw/xenfb.c
@@ -366,7 +366,7 @@ static int input_connect(struct XenDevice *xendev)
             /* there is no vfb, run vkbd on its own */
             in->c.ds = get_displaystate();
         } else {
-            qemu_free(vfb);
+            g_free(vfb);
             xen_be_printf(xendev, 1, "ds not set (yet)\n");
             return -1;
         }
@@ -483,8 +483,8 @@ static int xenfb_map_fb(struct XenFB *xenfb)
     n_fbdirs = xenfb->fbpages * mode / 8;
     n_fbdirs = (n_fbdirs + (XC_PAGE_SIZE - 1)) / XC_PAGE_SIZE;
 
-    pgmfns = qemu_mallocz(sizeof(unsigned long) * n_fbdirs);
-    fbmfns = qemu_mallocz(sizeof(unsigned long) * xenfb->fbpages);
+    pgmfns = g_malloc0(sizeof(unsigned long) * n_fbdirs);
+    fbmfns = g_malloc0(sizeof(unsigned long) * xenfb->fbpages);
 
     xenfb_copy_mfns(mode, n_fbdirs, pgmfns, pd);
     map = xc_map_foreign_pages(xen_xc, xenfb->c.xendev.dom,
@@ -502,8 +502,8 @@ static int xenfb_map_fb(struct XenFB *xenfb)
     ret = 0; /* all is fine */
 
 out:
-    qemu_free(pgmfns);
-    qemu_free(fbmfns);
+    g_free(pgmfns);
+    g_free(fbmfns);
     return ret;
 }
 
diff --git a/hw/xics.c b/hw/xics.c
index 13a1d25..9bf82aa 100644
--- a/hw/xics.c
+++ b/hw/xics.c
@@ -440,9 +440,9 @@ struct icp_state *xics_system_init(int nr_irqs)
         }
     }
 
-    icp = qemu_mallocz(sizeof(*icp));
+    icp = g_malloc0(sizeof(*icp));
     icp->nr_servers = max_server_num + 1;
-    icp->ss = qemu_mallocz(icp->nr_servers*sizeof(struct icp_server_state));
+    icp->ss = g_malloc0(icp->nr_servers*sizeof(struct icp_server_state));
 
     for (i = 0; i < icp->nr_servers; i++) {
         icp->ss[i].mfrr = 0xff;
@@ -467,10 +467,10 @@ struct icp_state *xics_system_init(int nr_irqs)
         }
     }
 
-    ics = qemu_mallocz(sizeof(*ics));
+    ics = g_malloc0(sizeof(*ics));
     ics->nr_irqs = nr_irqs;
     ics->offset = 16;
-    ics->irqs = qemu_mallocz(nr_irqs * sizeof(struct ics_irq_state));
+    ics->irqs = g_malloc0(nr_irqs * sizeof(struct ics_irq_state));
 
     icp->ics = ics;
     ics->icp = icp;
diff --git a/hw/xilinx_axienet.c b/hw/xilinx_axienet.c
index 464d275..b875aad 100644
--- a/hw/xilinx_axienet.c
+++ b/hw/xilinx_axienet.c
@@ -789,8 +789,8 @@ static void eth_cleanup(VLANClientState *nc)
 {
     /* FIXME.  */
     struct XilinxAXIEnet *s = DO_UPCAST(NICState, nc, nc)->opaque;
-    qemu_free(s->rxmem);
-    qemu_free(s);
+    g_free(s->rxmem);
+    g_free(s);
 }
 
 static void
@@ -871,7 +871,7 @@ static int xilinx_enet_init(SysBusDevice *dev)
 
     s->TEMAC.parent = s;
 
-    s->rxmem = qemu_malloc(s->c_rxmem);
+    s->rxmem = g_malloc(s->c_rxmem);
     axienet_reset(s);
 
     return 0;
diff --git a/hw/xilinx_timer.c b/hw/xilinx_timer.c
index d398c18..f1c7abc 100644
--- a/hw/xilinx_timer.c
+++ b/hw/xilinx_timer.c
@@ -198,7 +198,7 @@ static int xilinx_timer_init(SysBusDevice *dev)
     sysbus_init_irq(dev, &t->irq);
 
     /* Init all the ptimers.  */
-    t->timers = qemu_mallocz(sizeof t->timers[0] * t->nr_timers);
+    t->timers = g_malloc0(sizeof t->timers[0] * t->nr_timers);
     for (i = 0; i < t->nr_timers; i++) {
         struct xlx_timer *xt = &t->timers[i];
 
diff --git a/input.c b/input.c
index 310bad5..e2f7c92 100644
--- a/input.c
+++ b/input.c
@@ -73,12 +73,12 @@ QEMUPutMouseEntry *qemu_add_mouse_event_handler(QEMUPutMouseEvent *func,
     QEMUPutMouseEntry *s;
     static int mouse_index = 0;
 
-    s = qemu_mallocz(sizeof(QEMUPutMouseEntry));
+    s = g_malloc0(sizeof(QEMUPutMouseEntry));
 
     s->qemu_put_mouse_event = func;
     s->qemu_put_mouse_event_opaque = opaque;
     s->qemu_put_mouse_event_absolute = absolute;
-    s->qemu_put_mouse_event_name = qemu_strdup(name);
+    s->qemu_put_mouse_event_name = g_strdup(name);
     s->index = mouse_index++;
 
     QTAILQ_INSERT_TAIL(&mouse_handlers, s, node);
@@ -100,8 +100,8 @@ void qemu_remove_mouse_event_handler(QEMUPutMouseEntry *entry)
 {
     QTAILQ_REMOVE(&mouse_handlers, entry, node);
 
-    qemu_free(entry->qemu_put_mouse_event_name);
-    qemu_free(entry);
+    g_free(entry->qemu_put_mouse_event_name);
+    g_free(entry);
 
     check_mode_change();
 }
@@ -111,7 +111,7 @@ QEMUPutLEDEntry *qemu_add_led_event_handler(QEMUPutLEDEvent *func,
 {
     QEMUPutLEDEntry *s;
 
-    s = qemu_mallocz(sizeof(QEMUPutLEDEntry));
+    s = g_malloc0(sizeof(QEMUPutLEDEntry));
 
     s->put_led = func;
     s->opaque = opaque;
@@ -124,7 +124,7 @@ void qemu_remove_led_event_handler(QEMUPutLEDEntry *entry)
     if (entry == NULL)
         return;
     QTAILQ_REMOVE(&led_handlers, entry, next);
-    qemu_free(entry);
+    g_free(entry);
 }
 
 void kbd_put_keycode(int keycode)
diff --git a/iohandler.c b/iohandler.c
index 2b82421..4deae1e 100644
--- a/iohandler.c
+++ b/iohandler.c
@@ -67,7 +67,7 @@ int qemu_set_fd_handler2(int fd,
             if (ioh->fd == fd)
                 goto found;
         }
-        ioh = qemu_mallocz(sizeof(IOHandlerRecord));
+        ioh = g_malloc0(sizeof(IOHandlerRecord));
         QLIST_INSERT_HEAD(&io_handlers, ioh, next);
     found:
         ioh->fd = fd;
@@ -126,7 +126,7 @@ void qemu_iohandler_poll(fd_set *readfds, fd_set *writefds, fd_set *xfds, int re
             /* Do this last in case read/write handlers marked it for deletion */
             if (ioh->deleted) {
                 QLIST_REMOVE(ioh, next);
-                qemu_free(ioh);
+                g_free(ioh);
             }
         }
     }
@@ -157,7 +157,7 @@ static void sigchld_bh_handler(void *opaque)
     QLIST_FOREACH_SAFE(rec, &child_watches, next, next) {
         if (waitpid(rec->pid, NULL, WNOHANG) == rec->pid) {
             QLIST_REMOVE(rec, next);
-            qemu_free(rec);
+            g_free(rec);
         }
     }
 }
@@ -185,7 +185,7 @@ int qemu_add_child_watch(pid_t pid)
             return 1;
         }
     }
-    rec = qemu_mallocz(sizeof(ChildProcessRecord));
+    rec = g_malloc0(sizeof(ChildProcessRecord));
     rec->pid = pid;
     QLIST_INSERT_HEAD(&child_watches, rec, next);
     return 0;
diff --git a/kvm-all.c b/kvm-all.c
index b9c172b..0ae2e26 100644
--- a/kvm-all.c
+++ b/kvm-all.c
@@ -400,9 +400,9 @@ static int kvm_physical_sync_dirty_bitmap(target_phys_addr_t start_addr,
         size = ALIGN(((mem->memory_size) >> TARGET_PAGE_BITS),
                      /*HOST_LONG_BITS*/ 64) / 8;
         if (!d.dirty_bitmap) {
-            d.dirty_bitmap = qemu_malloc(size);
+            d.dirty_bitmap = g_malloc(size);
         } else if (size > allocated_size) {
-            d.dirty_bitmap = qemu_realloc(d.dirty_bitmap, size);
+            d.dirty_bitmap = g_realloc(d.dirty_bitmap, size);
         }
         allocated_size = size;
         memset(d.dirty_bitmap, 0, allocated_size);
@@ -419,7 +419,7 @@ static int kvm_physical_sync_dirty_bitmap(target_phys_addr_t start_addr,
                                       mem->start_addr, mem->memory_size);
         start_addr = mem->start_addr + mem->memory_size;
     }
-    qemu_free(d.dirty_bitmap);
+    g_free(d.dirty_bitmap);
 
     return ret;
 }
@@ -702,7 +702,7 @@ int kvm_init(void)
     int ret;
     int i;
 
-    s = qemu_mallocz(sizeof(KVMState));
+    s = g_malloc0(sizeof(KVMState));
 
 #ifdef KVM_CAP_SET_GUEST_DEBUG
     QTAILQ_INIT(&s->kvm_sw_breakpoints);
@@ -804,7 +804,7 @@ err:
             close(s->fd);
         }
     }
-    qemu_free(s);
+    g_free(s);
 
     return ret;
 }
@@ -1188,7 +1188,7 @@ int kvm_insert_breakpoint(CPUState *current_env, target_ulong addr,
             return 0;
         }
 
-        bp = qemu_malloc(sizeof(struct kvm_sw_breakpoint));
+        bp = g_malloc(sizeof(struct kvm_sw_breakpoint));
         if (!bp) {
             return -ENOMEM;
         }
@@ -1197,7 +1197,7 @@ int kvm_insert_breakpoint(CPUState *current_env, target_ulong addr,
         bp->use_count = 1;
         err = kvm_arch_insert_sw_breakpoint(current_env, bp);
         if (err) {
-            qemu_free(bp);
+            g_free(bp);
             return err;
         }
 
@@ -1243,7 +1243,7 @@ int kvm_remove_breakpoint(CPUState *current_env, target_ulong addr,
         }
 
         QTAILQ_REMOVE(&current_env->kvm_state->kvm_sw_breakpoints, bp, entry);
-        qemu_free(bp);
+        g_free(bp);
     } else {
         err = kvm_arch_remove_hw_breakpoint(addr, len, type);
         if (err) {
@@ -1316,12 +1316,12 @@ int kvm_set_signal_mask(CPUState *env, const sigset_t *sigset)
         return kvm_vcpu_ioctl(env, KVM_SET_SIGNAL_MASK, NULL);
     }
 
-    sigmask = qemu_malloc(sizeof(*sigmask) + sizeof(*sigset));
+    sigmask = g_malloc(sizeof(*sigmask) + sizeof(*sigset));
 
     sigmask->len = 8;
     memcpy(sigmask->sigset, sigset, sizeof(*sigset));
     r = kvm_vcpu_ioctl(env, KVM_SET_SIGNAL_MASK, sigmask);
-    qemu_free(sigmask);
+    g_free(sigmask);
 
     return r;
 }
diff --git a/libcacard/cac.c b/libcacard/cac.c
index f34f63a..f4b0b1b 100644
--- a/libcacard/cac.c
+++ b/libcacard/cac.c
@@ -98,7 +98,7 @@ cac_applet_pki_reset(VCard *card, int channel)
 
     pki_applet->cert_buffer = NULL;
     if (pki_applet->sign_buffer) {
-        qemu_free(pki_applet->sign_buffer);
+        g_free(pki_applet->sign_buffer);
         pki_applet->sign_buffer = NULL;
     }
     pki_applet->cert_buffer_len = 0;
@@ -166,7 +166,7 @@ cac_applet_pki_process_apdu(VCard *card, VCardAPDU *apdu,
         sign_buffer = realloc(pki_applet->sign_buffer,
                       pki_applet->sign_buffer_len+size);
         if (sign_buffer == NULL) {
-            qemu_free(pki_applet->sign_buffer);
+            g_free(pki_applet->sign_buffer);
             pki_applet->sign_buffer = NULL;
             pki_applet->sign_buffer_len = 0;
             *response = vcard_make_response(
@@ -204,7 +204,7 @@ cac_applet_pki_process_apdu(VCard *card, VCardAPDU *apdu,
                                 VCARD7816_STATUS_ERROR_P1_P2_INCORRECT);
             break;
         }
-        qemu_free(sign_buffer);
+        g_free(sign_buffer);
         pki_applet->sign_buffer = NULL;
         pki_applet->sign_buffer_len = 0;
         return VCARD_DONE;
@@ -271,15 +271,15 @@ cac_delete_pki_applet_private(VCardAppletPrivate *applet_private)
     }
     pki_applet_data = &(applet_private->u.pki_data);
     if (pki_applet_data->cert != NULL) {
-        qemu_free(pki_applet_data->cert);
+        g_free(pki_applet_data->cert);
     }
     if (pki_applet_data->sign_buffer != NULL) {
-        qemu_free(pki_applet_data->sign_buffer);
+        g_free(pki_applet_data->sign_buffer);
     }
     if (pki_applet_data->key != NULL) {
         vcard_emul_delete_key(pki_applet_data->key);
     }
-    qemu_free(applet_private);
+    g_free(applet_private);
 }
 
 static VCardAppletPrivate *
@@ -288,7 +288,7 @@ cac_new_pki_applet_private(const unsigned char *cert,
 {
     CACPKIAppletData *pki_applet_data = NULL;
     VCardAppletPrivate *applet_private = NULL;
-    applet_private = (VCardAppletPrivate *)qemu_malloc(sizeof(VCardAppletPrivate));
+    applet_private = (VCardAppletPrivate *)g_malloc(sizeof(VCardAppletPrivate));
 
     pki_applet_data = &(applet_private->u.pki_data);
     pki_applet_data->cert_buffer = NULL;
@@ -296,7 +296,7 @@ cac_new_pki_applet_private(const unsigned char *cert,
     pki_applet_data->sign_buffer = NULL;
     pki_applet_data->sign_buffer_len = 0;
     pki_applet_data->key = NULL;
-    pki_applet_data->cert = (unsigned char *)qemu_malloc(cert_len+1);
+    pki_applet_data->cert = (unsigned char *)g_malloc(cert_len+1);
     /*
      * if we want to support compression, then we simply change the 0 to a 1
      * and compress the cert data with libz
diff --git a/libcacard/card_7816.c b/libcacard/card_7816.c
index eeea849..9fd59d4 100644
--- a/libcacard/card_7816.c
+++ b/libcacard/card_7816.c
@@ -51,8 +51,8 @@ vcard_response_new_data(unsigned char *buf, int len)
 {
     VCardResponse *new_response;
 
-    new_response = (VCardResponse *)qemu_malloc(sizeof(VCardResponse));
-    new_response->b_data = qemu_malloc(len + 2);
+    new_response = (VCardResponse *)g_malloc(sizeof(VCardResponse));
+    new_response->b_data = g_malloc(len + 2);
     memcpy(new_response->b_data, buf, len);
     new_response->b_total_len = len+2;
     new_response->b_len = len;
@@ -132,7 +132,7 @@ vcard_response_new_status(vcard_7816_status_t status)
 {
     VCardResponse *new_response;
 
-    new_response = (VCardResponse *)qemu_malloc(sizeof(VCardResponse));
+    new_response = (VCardResponse *)g_malloc(sizeof(VCardResponse));
     new_response->b_data = &new_response->b_sw1;
     new_response->b_len = 0;
     new_response->b_total_len = 2;
@@ -149,7 +149,7 @@ vcard_response_new_status_bytes(unsigned char sw1, unsigned char sw2)
 {
     VCardResponse *new_response;
 
-    new_response = (VCardResponse *)qemu_malloc(sizeof(VCardResponse));
+    new_response = (VCardResponse *)g_malloc(sizeof(VCardResponse));
     new_response->b_data = &new_response->b_sw1;
     new_response->b_len = 0;
     new_response->b_total_len = 2;
@@ -173,19 +173,19 @@ vcard_response_delete(VCardResponse *response)
     case VCARD_MALLOC:
         /* everything was malloc'ed */
         if (response->b_data) {
-            qemu_free(response->b_data);
+            g_free(response->b_data);
         }
-        qemu_free(response);
+        g_free(response);
         break;
     case VCARD_MALLOC_DATA:
         /* only the data buffer was malloc'ed */
         if (response->b_data) {
-            qemu_free(response->b_data);
+            g_free(response->b_data);
         }
         break;
     case VCARD_MALLOC_STRUCT:
         /* only the structure was malloc'ed */
-        qemu_free(response);
+        g_free(response);
         break;
     case VCARD_STATIC:
         break;
@@ -336,18 +336,18 @@ vcard_apdu_new(unsigned char *raw_apdu, int len, vcard_7816_status_t *status)
         return NULL;
     }
 
-    new_apdu = (VCardAPDU *)qemu_malloc(sizeof(VCardAPDU));
-    new_apdu->a_data = qemu_malloc(len);
+    new_apdu = (VCardAPDU *)g_malloc(sizeof(VCardAPDU));
+    new_apdu->a_data = g_malloc(len);
     memcpy(new_apdu->a_data, raw_apdu, len);
     new_apdu->a_len = len;
     *status = vcard_apdu_set_class(new_apdu);
     if (*status != VCARD7816_STATUS_SUCCESS) {
-        qemu_free(new_apdu);
+        g_free(new_apdu);
         return NULL;
     }
     *status = vcard_apdu_set_length(new_apdu);
     if (*status != VCARD7816_STATUS_SUCCESS) {
-        qemu_free(new_apdu);
+        g_free(new_apdu);
         new_apdu = NULL;
     }
     return new_apdu;
@@ -360,9 +360,9 @@ vcard_apdu_delete(VCardAPDU *apdu)
         return;
     }
     if (apdu->a_data) {
-        qemu_free(apdu->a_data);
+        g_free(apdu->a_data);
     }
-    qemu_free(apdu);
+    g_free(apdu);
 }
 
 
diff --git a/libcacard/event.c b/libcacard/event.c
index bb2f921..6192376 100644
--- a/libcacard/event.c
+++ b/libcacard/event.c
@@ -17,7 +17,7 @@ vevent_new(VEventType type, VReader *reader, VCard *card)
 {
     VEvent *new_vevent;
 
-    new_vevent = (VEvent *)qemu_malloc(sizeof(VEvent));
+    new_vevent = (VEvent *)g_malloc(sizeof(VEvent));
     new_vevent->next = NULL;
     new_vevent->type = type;
     new_vevent->reader = vreader_reference(reader);
@@ -34,7 +34,7 @@ vevent_delete(VEvent *vevent)
     }
     vreader_free(vevent->reader);
     vcard_free(vevent->card);
-    qemu_free(vevent);
+    g_free(vevent);
 }
 
 /*
diff --git a/libcacard/vcard.c b/libcacard/vcard.c
index 29b4cce..b02556e 100644
--- a/libcacard/vcard.c
+++ b/libcacard/vcard.c
@@ -37,8 +37,8 @@ vcard_buffer_response_new(unsigned char *buffer, int size)
 {
     VCardBufferResponse *new_buffer;
 
-    new_buffer = (VCardBufferResponse *)qemu_malloc(sizeof(VCardBufferResponse));
-    new_buffer->buffer = (unsigned char *)qemu_malloc(size);
+    new_buffer = (VCardBufferResponse *)g_malloc(sizeof(VCardBufferResponse));
+    new_buffer->buffer = (unsigned char *)g_malloc(size);
     memcpy(new_buffer->buffer, buffer, size);
     new_buffer->buffer_len = size;
     new_buffer->current = new_buffer->buffer;
@@ -53,9 +53,9 @@ vcard_buffer_response_delete(VCardBufferResponse *buffer_response)
         return;
     }
     if (buffer_response->buffer) {
-        qemu_free(buffer_response->buffer);
+        g_free(buffer_response->buffer);
     }
-    qemu_free(buffer_response);
+    g_free(buffer_response);
 }
 
 
@@ -102,14 +102,14 @@ vcard_new_applet(VCardProcessAPDU applet_process_function,
 {
     VCardApplet *applet;
 
-    applet = (VCardApplet *)qemu_malloc(sizeof(VCardApplet));
+    applet = (VCardApplet *)g_malloc(sizeof(VCardApplet));
     applet->next = NULL;
     applet->applet_private = NULL;
     applet->applet_private_free = NULL;
     applet->process_apdu = applet_process_function;
     applet->reset_applet = applet_reset_function;
 
-    applet->aid = qemu_malloc(aid_len);
+    applet->aid = g_malloc(aid_len);
     memcpy(applet->aid, aid, aid_len);
     applet->aid_len = aid_len;
     return applet;
@@ -127,10 +127,10 @@ vcard_delete_applet(VCardApplet *applet)
         applet->applet_private = NULL;
     }
     if (applet->aid) {
-        qemu_free(applet->aid);
+        g_free(applet->aid);
         applet->aid = NULL;
     }
-    qemu_free(applet);
+    g_free(applet);
 }
 
 /* accessor */
@@ -151,7 +151,7 @@ vcard_new(VCardEmul *private, VCardEmulFree private_free)
     VCard *new_card;
     int i;
 
-    new_card = (VCard *)qemu_malloc(sizeof(VCard));
+    new_card = (VCard *)g_malloc(sizeof(VCard));
     new_card->applet_list = NULL;
     for (i = 0; i < MAX_CHANNEL; i++) {
         new_card->current_applet[i] = NULL;
@@ -199,7 +199,7 @@ vcard_free(VCard *vcard)
         vcard_delete_applet(current_applet);
     }
     vcard_buffer_response_delete(vcard->vcard_buffer_response);
-    qemu_free(vcard);
+    g_free(vcard);
     return;
 }
 
diff --git a/libcacard/vcard_emul_nss.c b/libcacard/vcard_emul_nss.c
index 84fc490..397485c 100644
--- a/libcacard/vcard_emul_nss.c
+++ b/libcacard/vcard_emul_nss.c
@@ -94,9 +94,9 @@ vcard_emul_alloc_arrays(unsigned char ***certsp, int **cert_lenp,
     *certsp = NULL;
     *cert_lenp = NULL;
     *keysp = NULL;
-    *certsp = (unsigned char **)qemu_malloc(sizeof(unsigned char *)*cert_count);
-    *cert_lenp = (int *)qemu_malloc(sizeof(int)*cert_count);
-    *keysp = (VCardKey **)qemu_malloc(sizeof(VCardKey *)*cert_count);
+    *certsp = (unsigned char **)g_malloc(sizeof(unsigned char *)*cert_count);
+    *cert_lenp = (int *)g_malloc(sizeof(int)*cert_count);
+    *keysp = (VCardKey **)g_malloc(sizeof(VCardKey *)*cert_count);
     return PR_TRUE;
 }
 
@@ -140,7 +140,7 @@ vcard_emul_make_key(PK11SlotInfo *slot, CERTCertificate *cert)
 {
     VCardKey *key;
 
-    key = (VCardKey *)qemu_malloc(sizeof(VCardKey));
+    key = (VCardKey *)g_malloc(sizeof(VCardKey));
     key->slot = PK11_ReferenceSlot(slot);
     key->cert = CERT_DupCertificate(cert);
     /* NOTE: if we aren't logged into the token, this could return NULL */
@@ -244,7 +244,7 @@ vcard_emul_rsa_op(VCard *card, VCardKey *key,
     /* be able to handle larger keys if necessariy */
     bp = &buf[0];
     if (sizeof(buf) < signature_len) {
-        bp = qemu_malloc(signature_len);
+        bp = g_malloc(signature_len);
     }
 
     /*
@@ -348,7 +348,7 @@ vcard_emul_rsa_op(VCard *card, VCardKey *key,
     key->failedX509 = VCardEmulTrue;
 cleanup:
     if (bp != buf) {
-        qemu_free(bp);
+        g_free(bp);
     }
     return ret;
 }
@@ -382,7 +382,7 @@ vcard_emul_login(VCard *card, unsigned char *pin, int pin_len)
       * to handle multiple guests from one process, then we would need to keep
       * a lot of extra state in our card structure
       * */
-    pin_string = qemu_malloc(pin_len+1);
+    pin_string = g_malloc(pin_len+1);
     memcpy(pin_string, pin, pin_len);
     pin_string[pin_len] = 0;
 
@@ -394,7 +394,7 @@ vcard_emul_login(VCard *card, unsigned char *pin, int pin_len)
     rv = PK11_Authenticate(slot, PR_FALSE, pin_string);
     memset(pin_string, 0, pin_len);  /* don't let the pin hang around in memory
                                         to be snooped */
-    qemu_free(pin_string);
+    g_free(pin_string);
     if (rv == SECSuccess) {
         return VCARD7816_STATUS_SUCCESS;
     }
@@ -452,7 +452,7 @@ vreader_emul_new(PK11SlotInfo *slot, VCardEmulType type, const char *params)
 {
     VReaderEmul *new_reader_emul;
 
-    new_reader_emul = (VReaderEmul *)qemu_malloc(sizeof(VReaderEmul));
+    new_reader_emul = (VReaderEmul *)g_malloc(sizeof(VReaderEmul));
 
     new_reader_emul->slot = PK11_ReferenceSlot(slot);
     new_reader_emul->default_type = type;
@@ -473,9 +473,9 @@ vreader_emul_delete(VReaderEmul *vreader_emul)
         PK11_FreeSlot(vreader_emul->slot);
     }
     if (vreader_emul->type_params) {
-        qemu_free(vreader_emul->type_params);
+        g_free(vreader_emul->type_params);
     }
-    qemu_free(vreader_emul);
+    g_free(vreader_emul);
 }
 
 /*
@@ -658,9 +658,9 @@ vcard_emul_mirror_card(VReader *vreader)
 
     /* now create the card */
     card = vcard_emul_make_card(vreader, certs, cert_len, keys, cert_count);
-    qemu_free(certs);
-    qemu_free(cert_len);
-    qemu_free(keys);
+    g_free(certs);
+    g_free(cert_len);
+    g_free(keys);
 
     return card;
 }
@@ -947,9 +947,9 @@ vcard_emul_init(const VCardEmulOptions *options)
             vreader_free(vreader);
             has_readers = PR_TRUE;
         }
-        qemu_free(certs);
-        qemu_free(cert_len);
-        qemu_free(keys);
+        g_free(certs);
+        g_free(cert_len);
+        g_free(keys);
     }
 
     /* if we aren't suppose to use hw, skip looking up hardware tokens */
@@ -1173,18 +1173,18 @@ vcard_emul_options(const char *args)
             }
             opts->vreader = vreaderOpt;
             vreaderOpt = &vreaderOpt[opts->vreader_count];
-            vreaderOpt->name = qemu_strndup(name, name_length);
-            vreaderOpt->vname = qemu_strndup(vname, vname_length);
+            vreaderOpt->name = g_strndup(name, name_length);
+            vreaderOpt->vname = g_strndup(vname, vname_length);
             vreaderOpt->card_type = type;
             vreaderOpt->type_params =
-                qemu_strndup(type_params, type_params_length);
+                g_strndup(type_params, type_params_length);
             count = count_tokens(args, ',', ')') + 1;
             vreaderOpt->cert_count = count;
-            vreaderOpt->cert_name = (char **)qemu_malloc(count*sizeof(char *));
+            vreaderOpt->cert_name = (char **)g_malloc(count*sizeof(char *));
             for (i = 0; i < count; i++) {
                 const char *cert = args;
                 args = strpbrk(args, ",)");
-                vreaderOpt->cert_name[i] = qemu_strndup(cert, args - cert);
+                vreaderOpt->cert_name[i] = g_strndup(cert, args - cert);
                 args = strip(args+1);
             }
             if (*args == ')') {
@@ -1211,7 +1211,7 @@ vcard_emul_options(const char *args)
             args = strip(args+10);
             params = args;
             args = find_blank(args);
-            opts->hw_type_params = qemu_strndup(params, args-params);
+            opts->hw_type_params = g_strndup(params, args-params);
         /* db="/data/base/path" */
         } else if (strncmp(args, "db=", 3) == 0) {
             const char *db;
@@ -1222,7 +1222,7 @@ vcard_emul_options(const char *args)
             args++;
             db = args;
             args = strpbrk(args, "\"\n");
-            opts->nss_db = qemu_strndup(db, args-db);
+            opts->nss_db = g_strndup(db, args-db);
             if (*args != 0) {
                 args++;
             }
diff --git a/libcacard/vreader.c b/libcacard/vreader.c
index 4a0125b..ec126df 100644
--- a/libcacard/vreader.c
+++ b/libcacard/vreader.c
@@ -46,7 +46,7 @@ vreader_new(const char *name, VReaderEmul *private,
 {
     VReader *reader;
 
-    reader = (VReader *)qemu_malloc(sizeof(VReader));
+    reader = (VReader *)g_malloc(sizeof(VReader));
     qemu_mutex_init(&reader->lock);
     reader->reference_count = 1;
     reader->name = name ? strdup(name) : NULL;
@@ -87,12 +87,12 @@ vreader_free(VReader *reader)
         vcard_free(reader->card);
     }
     if (reader->name) {
-        qemu_free(reader->name);
+        g_free(reader->name);
     }
     if (reader->reader_private_free) {
         reader->reader_private_free(reader->reader_private);
     }
-    qemu_free(reader);
+    g_free(reader);
     return;
 }
 
@@ -237,7 +237,7 @@ vreader_list_entry_new(VReader *reader)
     VReaderListEntry *new_reader_list_entry;
 
     new_reader_list_entry = (VReaderListEntry *)
-                               qemu_malloc(sizeof(VReaderListEntry));
+                               g_malloc(sizeof(VReaderListEntry));
     new_reader_list_entry->next = NULL;
     new_reader_list_entry->prev = NULL;
     new_reader_list_entry->reader = vreader_reference(reader);
@@ -251,7 +251,7 @@ vreader_list_entry_delete(VReaderListEntry *entry)
         return;
     }
     vreader_free(entry->reader);
-    qemu_free(entry);
+    g_free(entry);
 }
 
 
@@ -260,7 +260,7 @@ vreader_list_new(void)
 {
     VReaderList *new_reader_list;
 
-    new_reader_list = (VReaderList *)qemu_malloc(sizeof(VReaderList));
+    new_reader_list = (VReaderList *)g_malloc(sizeof(VReaderList));
     new_reader_list->head = NULL;
     new_reader_list->tail = NULL;
     return new_reader_list;
@@ -278,7 +278,7 @@ vreader_list_delete(VReaderList *list)
     }
     list->head = NULL;
     list->tail = NULL;
-    qemu_free(list);
+    g_free(list);
 }
 
 
diff --git a/libcacard/vscclient.c b/libcacard/vscclient.c
index ce33f5a..a7b3834 100644
--- a/libcacard/vscclient.c
+++ b/libcacard/vscclient.c
@@ -488,7 +488,7 @@ main(
         for (i = 0; i < cert_count; i++) {
             len += strlen(cert_names[i])+1; /* 1 == comma */
         }
-        new_args = qemu_malloc(len);
+        new_args = g_malloc(len);
         strcpy(new_args, emul_args);
         strcat(new_args, SOFT_STRING);
         for (i = 0; i < cert_count; i++) {
diff --git a/linux-aio.c b/linux-aio.c
index dc3faf2..5fd3932 100644
--- a/linux-aio.c
+++ b/linux-aio.c
@@ -204,7 +204,7 @@ void *laio_init(void)
 {
     struct qemu_laio_state *s;
 
-    s = qemu_mallocz(sizeof(*s));
+    s = g_malloc0(sizeof(*s));
     s->efd = eventfd(0, 0);
     if (s->efd == -1)
         goto out_free_state;
@@ -221,6 +221,6 @@ void *laio_init(void)
 out_close_efd:
     close(s->efd);
 out_free_state:
-    qemu_free(s);
+    g_free(s);
     return NULL;
 }
diff --git a/linux-user/elfload.c b/linux-user/elfload.c
index 443d246..04e8e6e 100644
--- a/linux-user/elfload.c
+++ b/linux-user/elfload.c
@@ -1473,7 +1473,7 @@ static void load_elf_image(const char *image_name, int image_fd,
 #ifdef CONFIG_USE_FDPIC
     {
         struct elf32_fdpic_loadseg *loadsegs = info->loadsegs =
-            qemu_malloc(sizeof(*loadsegs) * info->nsegs);
+            g_malloc(sizeof(*loadsegs) * info->nsegs);
 
         for (i = 0; i < ehdr->e_phnum; ++i) {
             switch (phdr[i].p_type) {
@@ -2063,7 +2063,7 @@ static struct mm_struct *vma_init(void)
 {
     struct mm_struct *mm;
 
-    if ((mm = qemu_malloc(sizeof (*mm))) == NULL)
+    if ((mm = g_malloc(sizeof (*mm))) == NULL)
         return (NULL);
 
     mm->mm_count = 0;
@@ -2078,9 +2078,9 @@ static void vma_delete(struct mm_struct *mm)
 
     while ((vma = vma_first(mm)) != NULL) {
         QTAILQ_REMOVE(&mm->mm_mmap, vma, vma_link);
-        qemu_free(vma);
+        g_free(vma);
     }
-    qemu_free(mm);
+    g_free(mm);
 }
 
 static int vma_add_mapping(struct mm_struct *mm, abi_ulong start,
@@ -2088,7 +2088,7 @@ static int vma_add_mapping(struct mm_struct *mm, abi_ulong start,
 {
     struct vm_area_struct *vma;
 
-    if ((vma = qemu_mallocz(sizeof (*vma))) == NULL)
+    if ((vma = g_malloc0(sizeof (*vma))) == NULL)
         return (-1);
 
     vma->vma_start = start;
@@ -2412,7 +2412,7 @@ static void fill_thread_info(struct elf_note_info *info, const CPUState *env)
     TaskState *ts = (TaskState *)env->opaque;
     struct elf_thread_status *ets;
 
-    ets = qemu_mallocz(sizeof (*ets));
+    ets = g_malloc0(sizeof (*ets));
     ets->num_notes = 1; /* only prstatus is dumped */
     fill_prstatus(&ets->prstatus, ts, 0);
     elf_core_copy_regs(&ets->prstatus.pr_reg, env);
@@ -2436,13 +2436,13 @@ static int fill_note_info(struct elf_note_info *info,
 
     QTAILQ_INIT(&info->thread_list);
 
-    info->notes = qemu_mallocz(NUMNOTES * sizeof (struct memelfnote));
+    info->notes = g_malloc0(NUMNOTES * sizeof (struct memelfnote));
     if (info->notes == NULL)
         return (-ENOMEM);
-    info->prstatus = qemu_mallocz(sizeof (*info->prstatus));
+    info->prstatus = g_malloc0(sizeof (*info->prstatus));
     if (info->prstatus == NULL)
         return (-ENOMEM);
-    info->psinfo = qemu_mallocz(sizeof (*info->psinfo));
+    info->psinfo = g_malloc0(sizeof (*info->psinfo));
     if (info->prstatus == NULL)
         return (-ENOMEM);
 
@@ -2483,12 +2483,12 @@ static void free_note_info(struct elf_note_info *info)
     while (!QTAILQ_EMPTY(&info->thread_list)) {
         ets = QTAILQ_FIRST(&info->thread_list);
         QTAILQ_REMOVE(&info->thread_list, ets, ets_link);
-        qemu_free(ets);
+        g_free(ets);
     }
 
-    qemu_free(info->prstatus);
-    qemu_free(info->psinfo);
-    qemu_free(info->notes);
+    g_free(info->prstatus);
+    g_free(info->psinfo);
+    g_free(info->notes);
 }
 
 static int write_note_info(struct elf_note_info *info, int fd)
diff --git a/linux-user/main.c b/linux-user/main.c
index 8e15474..95e3fe6 100644
--- a/linux-user/main.c
+++ b/linux-user/main.c
@@ -3216,7 +3216,7 @@ int main(int argc, char **argv, char **envp)
     }
     target_argv[target_argc] = NULL;
 
-    ts = qemu_mallocz (sizeof(TaskState));
+    ts = g_malloc0 (sizeof(TaskState));
     init_task_state(ts);
     /* build Task State */
     ts->info = info;
diff --git a/linux-user/syscall.c b/linux-user/syscall.c
index 73f9baa..6bdf4e6 100644
--- a/linux-user/syscall.c
+++ b/linux-user/syscall.c
@@ -3991,7 +3991,7 @@ static int do_fork(CPUState *env, unsigned int flags, abi_ulong newsp,
         new_thread_info info;
         pthread_attr_t attr;
 #endif
-        ts = qemu_mallocz(sizeof(TaskState));
+        ts = g_malloc0(sizeof(TaskState));
         init_task_state(ts);
         /* we create a new CPU instance. */
         new_env = cpu_copy(env);
@@ -4057,7 +4057,7 @@ static int do_fork(CPUState *env, unsigned int flags, abi_ulong newsp,
         if (flags & CLONE_NPTL_FLAGS2)
             return -EINVAL;
         /* This is probably going to die very quickly, but do it anyway.  */
-        new_stack = qemu_mallocz (NEW_STACK_SIZE);
+        new_stack = g_malloc0 (NEW_STACK_SIZE);
 #ifdef __ia64__
         ret = __clone2(clone_func, new_stack, NEW_STACK_SIZE, flags, new_env);
 #else
@@ -4651,8 +4651,8 @@ abi_long do_syscall(void *cpu_env, int num, abi_long arg1,
                         NULL, NULL, 0);
           }
           thread_env = NULL;
-          qemu_free(cpu_env);
-          qemu_free(ts);
+          g_free(cpu_env);
+          g_free(ts);
           pthread_exit(NULL);
       }
 #endif
diff --git a/memory.c b/memory.c
index beff98c..24439f3 100644
--- a/memory.c
+++ b/memory.c
@@ -183,7 +183,7 @@ static void flatview_insert(FlatView *view, unsigned pos, FlatRange *range)
 {
     if (view->nr == view->nr_allocated) {
         view->nr_allocated = MAX(2 * view->nr, 10);
-        view->ranges = qemu_realloc(view->ranges,
+        view->ranges = g_realloc(view->ranges,
                                     view->nr_allocated * sizeof(*view->ranges));
     }
     memmove(view->ranges + pos + 1, view->ranges + pos,
@@ -194,7 +194,7 @@ static void flatview_insert(FlatView *view, unsigned pos, FlatRange *range)
 
 static void flatview_destroy(FlatView *view)
 {
-    qemu_free(view->ranges);
+    g_free(view->ranges);
 }
 
 static bool can_merge(FlatRange *r1, FlatRange *r2)
@@ -553,7 +553,7 @@ static void address_space_update_ioeventfds(AddressSpace *as)
                                   fr->addr.start - fr->offset_in_region);
             if (addrrange_intersects(fr->addr, tmp)) {
                 ++ioeventfd_nb;
-                ioeventfds = qemu_realloc(ioeventfds,
+                ioeventfds = g_realloc(ioeventfds,
                                           ioeventfd_nb * sizeof(*ioeventfds));
                 ioeventfds[ioeventfd_nb-1] = fr->mr->ioeventfds[i];
                 ioeventfds[ioeventfd_nb-1].addr = tmp;
@@ -564,7 +564,7 @@ static void address_space_update_ioeventfds(AddressSpace *as)
     address_space_add_del_ioeventfds(as, ioeventfds, ioeventfd_nb,
                                      as->ioeventfds, as->ioeventfd_nb);
 
-    qemu_free(as->ioeventfds);
+    g_free(as->ioeventfds);
     as->ioeventfds = ioeventfds;
     as->ioeventfd_nb = ioeventfd_nb;
 }
@@ -713,7 +713,7 @@ void memory_region_init(MemoryRegion *mr,
     QTAILQ_INIT(&mr->subregions);
     memset(&mr->subregions_link, 0, sizeof mr->subregions_link);
     QTAILQ_INIT(&mr->coalesced);
-    mr->name = qemu_strdup(name);
+    mr->name = g_strdup(name);
     mr->dirty_log_mask = 0;
     mr->ioeventfd_nb = 0;
     mr->ioeventfds = NULL;
@@ -949,8 +949,8 @@ void memory_region_destroy(MemoryRegion *mr)
     assert(QTAILQ_EMPTY(&mr->subregions));
     mr->destructor(mr);
     memory_region_clear_coalescing(mr);
-    qemu_free((char *)mr->name);
-    qemu_free(mr->ioeventfds);
+    g_free((char *)mr->name);
+    g_free(mr->ioeventfds);
 }
 
 uint64_t memory_region_size(MemoryRegion *mr)
@@ -1061,7 +1061,7 @@ void memory_region_add_coalescing(MemoryRegion *mr,
                                   target_phys_addr_t offset,
                                   uint64_t size)
 {
-    CoalescedMemoryRange *cmr = qemu_malloc(sizeof(*cmr));
+    CoalescedMemoryRange *cmr = g_malloc(sizeof(*cmr));
 
     cmr->addr = addrrange_make(offset, size);
     QTAILQ_INSERT_TAIL(&mr->coalesced, cmr, link);
@@ -1075,7 +1075,7 @@ void memory_region_clear_coalescing(MemoryRegion *mr)
     while (!QTAILQ_EMPTY(&mr->coalesced)) {
         cmr = QTAILQ_FIRST(&mr->coalesced);
         QTAILQ_REMOVE(&mr->coalesced, cmr, link);
-        qemu_free(cmr);
+        g_free(cmr);
     }
     memory_region_update_coalesced_range(mr);
 }
@@ -1102,7 +1102,7 @@ void memory_region_add_eventfd(MemoryRegion *mr,
         }
     }
     ++mr->ioeventfd_nb;
-    mr->ioeventfds = qemu_realloc(mr->ioeventfds,
+    mr->ioeventfds = g_realloc(mr->ioeventfds,
                                   sizeof(*mr->ioeventfds) * mr->ioeventfd_nb);
     memmove(&mr->ioeventfds[i+1], &mr->ioeventfds[i],
             sizeof(*mr->ioeventfds) * (mr->ioeventfd_nb-1 - i));
@@ -1135,7 +1135,7 @@ void memory_region_del_eventfd(MemoryRegion *mr,
     memmove(&mr->ioeventfds[i], &mr->ioeventfds[i+1],
             sizeof(*mr->ioeventfds) * (mr->ioeventfd_nb - (i+1)));
     --mr->ioeventfd_nb;
-    mr->ioeventfds = qemu_realloc(mr->ioeventfds,
+    mr->ioeventfds = g_realloc(mr->ioeventfds,
                                   sizeof(*mr->ioeventfds)*mr->ioeventfd_nb + 1);
     memory_region_update_topology();
 }
diff --git a/migration-exec.c b/migration-exec.c
index 4b7aad8..2cfb6f2 100644
--- a/migration-exec.c
+++ b/migration-exec.c
@@ -71,7 +71,7 @@ MigrationState *exec_start_outgoing_migration(Monitor *mon,
     FdMigrationState *s;
     FILE *f;
 
-    s = qemu_mallocz(sizeof(*s));
+    s = g_malloc0(sizeof(*s));
 
     f = popen(command, "w");
     if (f == NULL) {
@@ -113,7 +113,7 @@ MigrationState *exec_start_outgoing_migration(Monitor *mon,
 err_after_open:
     pclose(f);
 err_after_alloc:
-    qemu_free(s);
+    g_free(s);
     return NULL;
 }
 
diff --git a/migration-fd.c b/migration-fd.c
index 66d51c1..aee690a 100644
--- a/migration-fd.c
+++ b/migration-fd.c
@@ -59,7 +59,7 @@ MigrationState *fd_start_outgoing_migration(Monitor *mon,
 {
     FdMigrationState *s;
 
-    s = qemu_mallocz(sizeof(*s));
+    s = g_malloc0(sizeof(*s));
 
     s->fd = monitor_get_fd(mon, fdname);
     if (s->fd == -1) {
@@ -96,7 +96,7 @@ MigrationState *fd_start_outgoing_migration(Monitor *mon,
 err_after_open:
     close(s->fd);
 err_after_alloc:
-    qemu_free(s);
+    g_free(s);
     return NULL;
 }
 
diff --git a/migration-tcp.c b/migration-tcp.c
index d3d80c9..c431e03 100644
--- a/migration-tcp.c
+++ b/migration-tcp.c
@@ -89,7 +89,7 @@ MigrationState *tcp_start_outgoing_migration(Monitor *mon,
     if (parse_host_port(&addr, host_port) < 0)
         return NULL;
 
-    s = qemu_mallocz(sizeof(*s));
+    s = g_malloc0(sizeof(*s));
 
     s->get_error = socket_errno;
     s->write = socket_write;
@@ -106,7 +106,7 @@ MigrationState *tcp_start_outgoing_migration(Monitor *mon,
     s->bandwidth_limit = bandwidth_limit;
     s->fd = qemu_socket(PF_INET, SOCK_STREAM, 0);
     if (s->fd == -1) {
-        qemu_free(s);
+        g_free(s);
         return NULL;
     }
 
diff --git a/migration-unix.c b/migration-unix.c
index c8625c7..6dc985d 100644
--- a/migration-unix.c
+++ b/migration-unix.c
@@ -88,7 +88,7 @@ MigrationState *unix_start_outgoing_migration(Monitor *mon,
     addr.sun_family = AF_UNIX;
     snprintf(addr.sun_path, sizeof(addr.sun_path), "%s", path);
 
-    s = qemu_mallocz(sizeof(*s));
+    s = g_malloc0(sizeof(*s));
 
     s->get_error = unix_errno;
     s->write = unix_write;
@@ -138,7 +138,7 @@ err_after_open:
     close(s->fd);
 
 err_after_alloc:
-    qemu_free(s);
+    g_free(s);
     return NULL;
 }
 
diff --git a/migration.c b/migration.c
index 756fa62..f5959b4 100644
--- a/migration.c
+++ b/migration.c
@@ -428,7 +428,7 @@ void migrate_fd_release(MigrationState *mig_state)
         notifier_list_notify(&migration_state_notifiers, NULL);
         migrate_fd_cleanup(s);
     }
-    qemu_free(s);
+    g_free(s);
 }
 
 void migrate_fd_wait_for_unfreeze(void *opaque)
diff --git a/module.c b/module.c
index e77d569..91f0e61 100644
--- a/module.c
+++ b/module.c
@@ -59,7 +59,7 @@ void register_module_init(void (*fn)(void), module_init_type type)
     ModuleEntry *e;
     ModuleTypeList *l;
 
-    e = qemu_mallocz(sizeof(*e));
+    e = g_malloc0(sizeof(*e));
     e->init = fn;
 
     l = find_type(type);
diff --git a/monitor.c b/monitor.c
index 1b8ba2c..68553f1 100644
--- a/monitor.c
+++ b/monitor.c
@@ -636,7 +636,7 @@ static void user_monitor_complete(void *opaque, QObject *ret_data)
         data->user_print(data->mon, ret_data);
     }
     monitor_resume(data->mon);
-    qemu_free(data);
+    g_free(data);
 }
 
 static void qmp_monitor_complete(void *opaque, QObject *ret_data)
@@ -660,7 +660,7 @@ static void user_async_cmd_handler(Monitor *mon, const mon_cmd_t *cmd,
 {
     int ret;
 
-    MonitorCompletionData *cb_data = qemu_malloc(sizeof(*cb_data));
+    MonitorCompletionData *cb_data = g_malloc(sizeof(*cb_data));
     cb_data->mon = mon;
     cb_data->user_print = cmd->user_print;
     monitor_suspend(mon);
@@ -668,7 +668,7 @@ static void user_async_cmd_handler(Monitor *mon, const mon_cmd_t *cmd,
                                   user_monitor_complete, cb_data);
     if (ret < 0) {
         monitor_resume(mon);
-        qemu_free(cb_data);
+        g_free(cb_data);
     }
 }
 
@@ -676,14 +676,14 @@ static void user_async_info_handler(Monitor *mon, const mon_cmd_t *cmd)
 {
     int ret;
 
-    MonitorCompletionData *cb_data = qemu_malloc(sizeof(*cb_data));
+    MonitorCompletionData *cb_data = g_malloc(sizeof(*cb_data));
     cb_data->mon = mon;
     cb_data->user_print = cmd->user_print;
     monitor_suspend(mon);
     ret = cmd->mhandler.info_async(mon, user_monitor_complete, cb_data);
     if (ret < 0) {
         monitor_resume(mon);
-        qemu_free(cb_data);
+        g_free(cb_data);
     }
 }
 
@@ -2545,7 +2545,7 @@ static void do_stop_capture(Monitor *mon, const QDict *qdict)
         if (i == n) {
             s->ops.destroy (s->opaque);
             QLIST_REMOVE (s, entries);
-            qemu_free (s);
+            g_free (s);
             return;
         }
     }
@@ -2562,7 +2562,7 @@ static void do_wav_capture(Monitor *mon, const QDict *qdict)
     int nchannels = qdict_get_try_int(qdict, "nchannels", -1);
     CaptureState *s;
 
-    s = qemu_mallocz (sizeof (*s));
+    s = g_malloc0 (sizeof (*s));
 
     freq = has_freq ? freq : 44100;
     bits = has_bits ? bits : 16;
@@ -2570,7 +2570,7 @@ static void do_wav_capture(Monitor *mon, const QDict *qdict)
 
     if (wav_start_capture (s, path, freq, bits, nchannels)) {
         monitor_printf(mon, "Failed to add wave capture\n");
-        qemu_free (s);
+        g_free (s);
         return;
     }
     QLIST_INSERT_HEAD (&capture_head, s, entries);
@@ -2780,8 +2780,8 @@ static int do_getfd(Monitor *mon, const QDict *qdict, QObject **ret_data)
         return 0;
     }
 
-    monfd = qemu_mallocz(sizeof(mon_fd_t));
-    monfd->name = qemu_strdup(fdname);
+    monfd = g_malloc0(sizeof(mon_fd_t));
+    monfd->name = g_strdup(fdname);
     monfd->fd = fd;
 
     QLIST_INSERT_HEAD(&mon->fds, monfd, next);
@@ -2800,8 +2800,8 @@ static int do_closefd(Monitor *mon, const QDict *qdict, QObject **ret_data)
 
         QLIST_REMOVE(monfd, next);
         close(monfd->fd);
-        qemu_free(monfd->name);
-        qemu_free(monfd);
+        g_free(monfd->name);
+        g_free(monfd);
         return 0;
     }
 
@@ -2836,8 +2836,8 @@ int monitor_get_fd(Monitor *mon, const char *fdname)
 
         /* caller takes ownership of fd */
         QLIST_REMOVE(monfd, next);
-        qemu_free(monfd->name);
-        qemu_free(monfd);
+        g_free(monfd->name);
+        g_free(monfd);
 
         return fd;
     }
@@ -4034,7 +4034,7 @@ static char *key_get_info(const char *type, char **key)
     }
     len = p - type;
 
-    str = qemu_malloc(len + 1);
+    str = g_malloc(len + 1);
     memcpy(str, type, len);
     str[len] = '\0';
 
@@ -4417,7 +4417,7 @@ static const mon_cmd_t *monitor_parse_command(Monitor *mon,
             monitor_printf(mon, "%s: unknown type '%c'\n", cmdname, c);
             goto fail;
         }
-        qemu_free(key);
+        g_free(key);
         key = NULL;
     }
     /* check that all arguments were parsed */
@@ -4432,7 +4432,7 @@ static const mon_cmd_t *monitor_parse_command(Monitor *mon,
     return cmd;
 
 fail:
-    qemu_free(key);
+    g_free(key);
     return NULL;
 }
 
@@ -4631,7 +4631,7 @@ static void parse_cmdline(const char *cmdline,
         if (nb_args >= MAX_ARGS)
             break;
         ret = get_str(buf, sizeof(buf), &p);
-        args[nb_args] = qemu_strdup(buf);
+        args[nb_args] = g_strdup(buf);
         nb_args++;
         if (ret < 0)
             break;
@@ -4668,7 +4668,7 @@ static void monitor_find_completion(const char *cmdline)
         if (nb_args >= MAX_ARGS) {
             goto cleanup;
         }
-        args[nb_args++] = qemu_strdup("");
+        args[nb_args++] = g_strdup("");
     }
     if (nb_args <= 1) {
         /* command completion */
@@ -4743,7 +4743,7 @@ static void monitor_find_completion(const char *cmdline)
 
 cleanup:
     for (i = 0; i < nb_args; i++) {
-        qemu_free(args[i]);
+        g_free(args[i]);
     }
 }
 
@@ -5261,7 +5261,7 @@ void monitor_init(CharDriverState *chr, int flags)
         is_first_init = 0;
     }
 
-    mon = qemu_mallocz(sizeof(*mon));
+    mon = g_malloc0(sizeof(*mon));
 
     mon->chr = chr;
     mon->flags = flags;
@@ -5271,7 +5271,7 @@ void monitor_init(CharDriverState *chr, int flags)
     }
 
     if (monitor_ctrl_mode(mon)) {
-        mon->mc = qemu_mallocz(sizeof(MonitorControl));
+        mon->mc = g_malloc0(sizeof(MonitorControl));
         /* Control mode requires special handlers */
         qemu_chr_add_handlers(chr, monitor_can_read, monitor_control_read,
                               monitor_control_event, mon);
diff --git a/net.c b/net.c
index cb6a2b0..d05930c 100644
--- a/net.c
+++ b/net.c
@@ -170,7 +170,7 @@ static char *assign_name(VLANClientState *vc1, const char *model)
 
     snprintf(buf, sizeof(buf), "%s.%d", model, id);
 
-    return qemu_strdup(buf);
+    return g_strdup(buf);
 }
 
 static ssize_t qemu_deliver_packet(VLANClientState *sender,
@@ -194,12 +194,12 @@ VLANClientState *qemu_new_net_client(NetClientInfo *info,
 
     assert(info->size >= sizeof(VLANClientState));
 
-    vc = qemu_mallocz(info->size);
+    vc = g_malloc0(info->size);
 
     vc->info = info;
-    vc->model = qemu_strdup(model);
+    vc->model = g_strdup(model);
     if (name) {
-        vc->name = qemu_strdup(name);
+        vc->name = g_strdup(name);
     } else {
         vc->name = assign_name(vc, model);
     }
@@ -268,9 +268,9 @@ static void qemu_free_vlan_client(VLANClientState *vc)
             vc->peer->peer = NULL;
         }
     }
-    qemu_free(vc->name);
-    qemu_free(vc->model);
-    qemu_free(vc);
+    g_free(vc->name);
+    g_free(vc->model);
+    g_free(vc);
 }
 
 void qemu_del_vlan_client(VLANClientState *vc)
@@ -640,7 +640,7 @@ VLANState *qemu_find_vlan(int id, int allocate)
         return NULL;
     }
 
-    vlan = qemu_mallocz(sizeof(VLANState));
+    vlan = g_malloc0(sizeof(VLANState));
     vlan->id = id;
     QTAILQ_INIT(&vlan->clients);
 
@@ -710,7 +710,7 @@ int qemu_find_nic_model(NICInfo *nd, const char * const *models,
     int i;
 
     if (!nd->model)
-        nd->model = qemu_strdup(default_model);
+        nd->model = g_strdup(default_model);
 
     for (i = 0 ; models[i]; i++) {
         if (strcmp(nd->model, models[i]) == 0)
@@ -774,13 +774,13 @@ static int net_init_nic(QemuOpts *opts,
         nd->vlan = vlan;
     }
     if (name) {
-        nd->name = qemu_strdup(name);
+        nd->name = g_strdup(name);
     }
     if (qemu_opt_get(opts, "model")) {
-        nd->model = qemu_strdup(qemu_opt_get(opts, "model"));
+        nd->model = g_strdup(qemu_opt_get(opts, "model"));
     }
     if (qemu_opt_get(opts, "addr")) {
-        nd->devaddr = qemu_strdup(qemu_opt_get(opts, "addr"));
+        nd->devaddr = g_strdup(qemu_opt_get(opts, "addr"));
     }
 
     if (qemu_opt_get(opts, "macaddr") &&
diff --git a/net/queue.c b/net/queue.c
index 2ea6cd0..1ab5247 100644
--- a/net/queue.c
+++ b/net/queue.c
@@ -63,7 +63,7 @@ NetQueue *qemu_new_net_queue(NetPacketDeliver *deliver,
 {
     NetQueue *queue;
 
-    queue = qemu_mallocz(sizeof(NetQueue));
+    queue = g_malloc0(sizeof(NetQueue));
 
     queue->deliver = deliver;
     queue->deliver_iov = deliver_iov;
@@ -82,10 +82,10 @@ void qemu_del_net_queue(NetQueue *queue)
 
     QTAILQ_FOREACH_SAFE(packet, &queue->packets, entry, next) {
         QTAILQ_REMOVE(&queue->packets, packet, entry);
-        qemu_free(packet);
+        g_free(packet);
     }
 
-    qemu_free(queue);
+    g_free(queue);
 }
 
 static ssize_t qemu_net_queue_append(NetQueue *queue,
@@ -97,7 +97,7 @@ static ssize_t qemu_net_queue_append(NetQueue *queue,
 {
     NetPacket *packet;
 
-    packet = qemu_malloc(sizeof(NetPacket) + size);
+    packet = g_malloc(sizeof(NetPacket) + size);
     packet->sender = sender;
     packet->flags = flags;
     packet->size = size;
@@ -124,7 +124,7 @@ static ssize_t qemu_net_queue_append_iov(NetQueue *queue,
         max_len += iov[i].iov_len;
     }
 
-    packet = qemu_malloc(sizeof(NetPacket) + max_len);
+    packet = g_malloc(sizeof(NetPacket) + max_len);
     packet->sender = sender;
     packet->sent_cb = sent_cb;
     packet->flags = flags;
@@ -227,7 +227,7 @@ void qemu_net_queue_purge(NetQueue *queue, VLANClientState *from)
     QTAILQ_FOREACH_SAFE(packet, &queue->packets, entry, next) {
         if (packet->sender == from) {
             QTAILQ_REMOVE(&queue->packets, packet, entry);
-            qemu_free(packet);
+            g_free(packet);
         }
     }
 }
@@ -255,6 +255,6 @@ void qemu_net_queue_flush(NetQueue *queue)
             packet->sent_cb(packet->sender, ret);
         }
 
-        qemu_free(packet);
+        g_free(packet);
     }
 }
diff --git a/net/slirp.c b/net/slirp.c
index 157b80a..ec7433f 100644
--- a/net/slirp.c
+++ b/net/slirp.c
@@ -450,7 +450,7 @@ int net_slirp_redir(const char *redir_str)
     struct slirp_config_str *config;
 
     if (QTAILQ_EMPTY(&slirp_stacks)) {
-        config = qemu_malloc(sizeof(*config));
+        config = g_malloc(sizeof(*config));
         pstrcpy(config->str, sizeof(config->str), redir_str);
         config->flags = SLIRP_CFG_HOSTFWD | SLIRP_CFG_LEGACY;
         config->next = slirp_configs;
@@ -614,19 +614,19 @@ static int slirp_guestfwd(SlirpState *s, const char *config_str,
         goto fail_syntax;
     }
 
-    fwd = qemu_malloc(sizeof(struct GuestFwd));
+    fwd = g_malloc(sizeof(struct GuestFwd));
     snprintf(buf, sizeof(buf), "guestfwd.tcp.%d", port);
     fwd->hd = qemu_chr_open(buf, p, NULL);
     if (!fwd->hd) {
         error_report("could not open guest forwarding device '%s'", buf);
-        qemu_free(fwd);
+        g_free(fwd);
         return -1;
     }
 
     if (slirp_add_exec(s->slirp, 3, fwd->hd, &server, port) < 0) {
         error_report("conflicting/invalid host:port in guest forwarding "
                      "rule '%s'", config_str);
-        qemu_free(fwd);
+        g_free(fwd);
         return -1;
     }
     fwd->server = server;
@@ -662,7 +662,7 @@ static int net_init_slirp_configs(const char *name, const char *value, void *opa
         return 0;
     }
 
-    config = qemu_mallocz(sizeof(*config));
+    config = g_malloc0(sizeof(*config));
 
     pstrcpy(config->str, sizeof(config->str), value);
 
@@ -720,7 +720,7 @@ int net_init_slirp(QemuOpts *opts,
         const char *ip = qemu_opt_get(opts, "ip");
         int l = strlen(ip) + strlen("/24") + 1;
 
-        vnet = qemu_malloc(l);
+        vnet = g_malloc(l);
 
         /* emulate legacy ip= parameter */
         pstrcpy(vnet, l, ip);
@@ -729,9 +729,9 @@ int net_init_slirp(QemuOpts *opts,
 
     if (qemu_opt_get(opts, "net")) {
         if (vnet) {
-            qemu_free(vnet);
+            g_free(vnet);
         }
-        vnet = qemu_strdup(qemu_opt_get(opts, "net"));
+        vnet = g_strdup(qemu_opt_get(opts, "net"));
     }
 
     qemu_opt_foreach(opts, net_init_slirp_configs, NULL, 0);
@@ -743,10 +743,10 @@ int net_init_slirp(QemuOpts *opts,
     while (slirp_configs) {
         config = slirp_configs;
         slirp_configs = config->next;
-        qemu_free(config);
+        g_free(config);
     }
 
-    qemu_free(vnet);
+    g_free(vnet);
 
     return ret;
 }
@@ -764,7 +764,7 @@ int net_slirp_parse_legacy(QemuOptsList *opts_list, const char *optarg, int *ret
     if (QTAILQ_EMPTY(&slirp_stacks)) {
         struct slirp_config_str *config;
 
-        config = qemu_malloc(sizeof(*config));
+        config = g_malloc(sizeof(*config));
         pstrcpy(config->str, sizeof(config->str), optarg);
         config->flags = SLIRP_CFG_LEGACY;
         config->next = slirp_configs;
diff --git a/net/socket.c b/net/socket.c
index 5cd0b9a..e9ef128 100644
--- a/net/socket.c
+++ b/net/socket.c
@@ -404,7 +404,7 @@ static int net_socket_listen_init(VLANState *vlan,
     if (parse_host_port(&saddr, host_str) < 0)
         return -1;
 
-    s = qemu_mallocz(sizeof(NetSocketListenState));
+    s = g_malloc0(sizeof(NetSocketListenState));
 
     fd = qemu_socket(PF_INET, SOCK_STREAM, 0);
     if (fd < 0) {
@@ -428,8 +428,8 @@ static int net_socket_listen_init(VLANState *vlan,
         return -1;
     }
     s->vlan = vlan;
-    s->model = qemu_strdup(model);
-    s->name = name ? qemu_strdup(name) : NULL;
+    s->model = g_strdup(model);
+    s->name = name ? g_strdup(name) : NULL;
     s->fd = fd;
     qemu_set_fd_handler(fd, net_socket_accept, NULL, s);
     return 0;
diff --git a/os-posix.c b/os-posix.c
index 6f8d488..dbf3b24 100644
--- a/os-posix.c
+++ b/os-posix.c
@@ -128,12 +128,12 @@ char *os_find_datadir(const char *argv0)
 
     max_len = strlen(dir) +
         MAX(strlen(SHARE_SUFFIX), strlen(BUILD_SUFFIX)) + 1;
-    res = qemu_mallocz(max_len);
+    res = g_malloc0(max_len);
     snprintf(res, max_len, "%s%s", dir, SHARE_SUFFIX);
     if (access(res, R_OK)) {
         snprintf(res, max_len, "%s%s", dir, BUILD_SUFFIX);
         if (access(res, R_OK)) {
-            qemu_free(res);
+            g_free(res);
             res = NULL;
         }
     }
diff --git a/os-win32.c b/os-win32.c
index b6652af..d3cea42 100644
--- a/os-win32.c
+++ b/os-win32.c
@@ -41,7 +41,7 @@ int setenv(const char *name, const char *value, int overwrite)
     int result = 0;
     if (overwrite || !getenv(name)) {
         size_t length = strlen(name) + strlen(value) + 2;
-        char *string = qemu_malloc(length);
+        char *string = g_malloc(length);
         snprintf(string, length, "%s=%s", name, value);
         result = putenv(string);
     }
@@ -62,7 +62,7 @@ static PollingEntry *first_polling_entry;
 int qemu_add_polling_cb(PollingFunc *func, void *opaque)
 {
     PollingEntry **ppe, *pe;
-    pe = qemu_mallocz(sizeof(PollingEntry));
+    pe = g_malloc0(sizeof(PollingEntry));
     pe->func = func;
     pe->opaque = opaque;
     for(ppe = &first_polling_entry; *ppe != NULL; ppe = &(*ppe)->next);
@@ -77,7 +77,7 @@ void qemu_del_polling_cb(PollingFunc *func, void *opaque)
         pe = *ppe;
         if (pe->func == func && pe->opaque == opaque) {
             *ppe = pe->next;
-            qemu_free(pe);
+            g_free(pe);
             break;
         }
     }
@@ -218,7 +218,7 @@ char *os_find_datadir(const char *argv0)
         p--;
     *p = 0;
     if (access(buf, R_OK) == 0) {
-        return qemu_strdup(buf);
+        return g_strdup(buf);
     }
     return NULL;
 }
diff --git a/pflib.c b/pflib.c
index 1154d0c..64cb2b3 100644
--- a/pflib.c
+++ b/pflib.c
@@ -145,7 +145,7 @@ static void convert_generic(QemuPfConv *conv, void *dst, void *src, uint32_t cnt
 {
     if (conv->conv_cnt < cnt) {
         conv->conv_cnt = cnt;
-        conv->conv_buf = qemu_realloc(conv->conv_buf, sizeof(QemuPixel) * conv->conv_cnt);
+        conv->conv_buf = g_realloc(conv->conv_buf, sizeof(QemuPixel) * conv->conv_cnt);
     }
     conv->conv_from(&conv->src, conv->conv_buf, src, cnt);
     conv->conv_to(&conv->dst, dst, conv->conv_buf, cnt);
@@ -156,7 +156,7 @@ static void convert_generic(QemuPfConv *conv, void *dst, void *src, uint32_t cnt
 
 QemuPfConv *qemu_pf_conv_get(PixelFormat *dst, PixelFormat *src)
 {
-    QemuPfConv *conv = qemu_mallocz(sizeof(QemuPfConv));
+    QemuPfConv *conv = g_malloc0(sizeof(QemuPfConv));
 
     conv->src = *src;
     conv->dst = *dst;
@@ -195,7 +195,7 @@ QemuPfConv *qemu_pf_conv_get(PixelFormat *dst, PixelFormat *src)
     return conv;
 
 err:
-    qemu_free(conv);
+    g_free(conv);
     return NULL;
 }
 
@@ -207,7 +207,7 @@ void qemu_pf_conv_run(QemuPfConv *conv, void *dst, void *src, uint32_t cnt)
 void qemu_pf_conv_put(QemuPfConv *conv)
 {
     if (conv) {
-        qemu_free(conv->conv_buf);
-        qemu_free(conv);
+        g_free(conv->conv_buf);
+        g_free(conv);
     }
 }
diff --git a/posix-aio-compat.c b/posix-aio-compat.c
index 8dc00cb..babb094 100644
--- a/posix-aio-compat.c
+++ b/posix-aio-compat.c
@@ -634,7 +634,7 @@ int paio_init(void)
     if (posix_aio_state)
         return 0;
 
-    s = qemu_malloc(sizeof(PosixAioState));
+    s = g_malloc(sizeof(PosixAioState));
 
     sigfillset(&act.sa_mask);
     act.sa_flags = 0; /* do not restart syscalls to interrupt select() */
diff --git a/qapi/qapi-dealloc-visitor.c b/qapi/qapi-dealloc-visitor.c
index 8cde4dd..f629061 100644
--- a/qapi/qapi-dealloc-visitor.c
+++ b/qapi/qapi-dealloc-visitor.c
@@ -35,7 +35,7 @@ static QapiDeallocVisitor *to_qov(Visitor *v)
 
 static void qapi_dealloc_push(QapiDeallocVisitor *qov, void *value)
 {
-    StackEntry *e = qemu_mallocz(sizeof(*e));
+    StackEntry *e = g_malloc0(sizeof(*e));
 
     e->value = value;
     QTAILQ_INSERT_HEAD(&qov->stack, e, node);
@@ -47,7 +47,7 @@ static void *qapi_dealloc_pop(QapiDeallocVisitor *qov)
     QObject *value;
     QTAILQ_REMOVE(&qov->stack, e, node);
     value = e->value;
-    qemu_free(e);
+    g_free(e);
     return value;
 }
 
@@ -64,7 +64,7 @@ static void qapi_dealloc_end_struct(Visitor *v, Error **errp)
     QapiDeallocVisitor *qov = to_qov(v);
     void **obj = qapi_dealloc_pop(qov);
     if (obj) {
-        qemu_free(*obj);
+        g_free(*obj);
     }
 }
 
@@ -76,7 +76,7 @@ static GenericList *qapi_dealloc_next_list(Visitor *v, GenericList **list,
                                            Error **errp)
 {
     GenericList *retval = *list;
-    qemu_free(retval->value);
+    g_free(retval->value);
     *list = retval->next;
     return retval;
 }
@@ -89,7 +89,7 @@ static void qapi_dealloc_type_str(Visitor *v, char **obj, const char *name,
                                   Error **errp)
 {
     if (obj) {
-        qemu_free(*obj);
+        g_free(*obj);
     }
 }
 
@@ -121,14 +121,14 @@ Visitor *qapi_dealloc_get_visitor(QapiDeallocVisitor *v)
 
 void qapi_dealloc_visitor_cleanup(QapiDeallocVisitor *v)
 {
-    qemu_free(v);
+    g_free(v);
 }
 
 QapiDeallocVisitor *qapi_dealloc_visitor_new(void)
 {
     QapiDeallocVisitor *v;
 
-    v = qemu_mallocz(sizeof(*v));
+    v = g_malloc0(sizeof(*v));
 
     v->visitor.start_struct = qapi_dealloc_start_struct;
     v->visitor.end_struct = qapi_dealloc_end_struct;
diff --git a/qapi/qmp-input-visitor.c b/qapi/qmp-input-visitor.c
index 6a1adc9..fcf8bf9 100644
--- a/qapi/qmp-input-visitor.c
+++ b/qapi/qmp-input-visitor.c
@@ -99,7 +99,7 @@ static void qmp_input_start_struct(Visitor *v, void **obj, const char *kind,
     }
 
     if (obj) {
-        *obj = qemu_mallocz(size);
+        *obj = g_malloc0(size);
     }
 }
 
@@ -135,11 +135,11 @@ static GenericList *qmp_input_next_list(Visitor *v, GenericList **list,
         return NULL;
     }
 
-    entry = qemu_mallocz(sizeof(*entry));
+    entry = g_malloc0(sizeof(*entry));
     if (*list) {
         so->entry = qlist_next(so->entry);
         if (so->entry == NULL) {
-            qemu_free(entry);
+            g_free(entry);
             return NULL;
         }
         (*list)->next = entry;
@@ -199,7 +199,7 @@ static void qmp_input_type_str(Visitor *v, char **obj, const char *name,
         return;
     }
 
-    *obj = qemu_strdup(qstring_get_str(qobject_to_qstring(qobj)));
+    *obj = g_strdup(qstring_get_str(qobject_to_qstring(qobj)));
 }
 
 static void qmp_input_type_number(Visitor *v, double *obj, const char *name,
@@ -272,14 +272,14 @@ Visitor *qmp_input_get_visitor(QmpInputVisitor *v)
 void qmp_input_visitor_cleanup(QmpInputVisitor *v)
 {
     qobject_decref(v->obj);
-    qemu_free(v);
+    g_free(v);
 }
 
 QmpInputVisitor *qmp_input_visitor_new(QObject *obj)
 {
     QmpInputVisitor *v;
 
-    v = qemu_mallocz(sizeof(*v));
+    v = g_malloc0(sizeof(*v));
 
     v->visitor.start_struct = qmp_input_start_struct;
     v->visitor.end_struct = qmp_input_end_struct;
diff --git a/qapi/qmp-output-visitor.c b/qapi/qmp-output-visitor.c
index c398cac..4419a31 100644
--- a/qapi/qmp-output-visitor.c
+++ b/qapi/qmp-output-visitor.c
@@ -42,7 +42,7 @@ static QmpOutputVisitor *to_qov(Visitor *v)
 
 static void qmp_output_push_obj(QmpOutputVisitor *qov, QObject *value)
 {
-    QStackEntry *e = qemu_mallocz(sizeof(*e));
+    QStackEntry *e = g_malloc0(sizeof(*e));
 
     e->value = value;
     QTAILQ_INSERT_HEAD(&qov->stack, e, node);
@@ -54,7 +54,7 @@ static QObject *qmp_output_pop(QmpOutputVisitor *qov)
     QObject *value;
     QTAILQ_REMOVE(&qov->stack, e, node);
     value = e->value;
-    qemu_free(e);
+    g_free(e);
     return value;
 }
 
@@ -210,17 +210,17 @@ void qmp_output_visitor_cleanup(QmpOutputVisitor *v)
         if (e->value) {
             qobject_decref(e->value);
         }
-        qemu_free(e);
+        g_free(e);
     }
 
-    qemu_free(v);
+    g_free(v);
 }
 
 QmpOutputVisitor *qmp_output_visitor_new(void)
 {
     QmpOutputVisitor *v;
 
-    v = qemu_mallocz(sizeof(*v));
+    v = g_malloc0(sizeof(*v));
 
     v->visitor.start_struct = qmp_output_start_struct;
     v->visitor.end_struct = qmp_output_end_struct;
diff --git a/qapi/qmp-registry.c b/qapi/qmp-registry.c
index 3fe8866..5ff99cf 100644
--- a/qapi/qmp-registry.c
+++ b/qapi/qmp-registry.c
@@ -19,7 +19,7 @@ static QTAILQ_HEAD(, QmpCommand) qmp_commands =
 
 void qmp_register_command(const char *name, QmpCommandFunc *fn)
 {
-    QmpCommand *cmd = qemu_mallocz(sizeof(*cmd));
+    QmpCommand *cmd = g_malloc0(sizeof(*cmd));
 
     cmd->name = name;
     cmd->type = QCT_NORMAL;
diff --git a/qbool.c b/qbool.c
index ad4873f..590cd71 100644
--- a/qbool.c
+++ b/qbool.c
@@ -31,7 +31,7 @@ QBool *qbool_from_int(int value)
 {
     QBool *qb;
 
-    qb = qemu_malloc(sizeof(*qb));
+    qb = g_malloc(sizeof(*qb));
     qb->value = value;
     QOBJECT_INIT(qb, &qbool_type);
 
@@ -64,5 +64,5 @@ QBool *qobject_to_qbool(const QObject *obj)
 static void qbool_destroy_obj(QObject *obj)
 {
     assert(obj != NULL);
-    qemu_free(qobject_to_qbool(obj));
+    g_free(qobject_to_qbool(obj));
 }
diff --git a/qdict.c b/qdict.c
index dee0fb4..4bf308b 100644
--- a/qdict.c
+++ b/qdict.c
@@ -35,7 +35,7 @@ QDict *qdict_new(void)
 {
     QDict *qdict;
 
-    qdict = qemu_mallocz(sizeof(*qdict));
+    qdict = g_malloc0(sizeof(*qdict));
     QOBJECT_INIT(qdict, &qdict_type);
 
     return qdict;
@@ -75,8 +75,8 @@ static QDictEntry *alloc_entry(const char *key, QObject *value)
 {
     QDictEntry *entry;
 
-    entry = qemu_mallocz(sizeof(*entry));
-    entry->key = qemu_strdup(key);
+    entry = g_malloc0(sizeof(*entry));
+    entry->key = g_strdup(key);
     entry->value = value;
 
     return entry;
@@ -410,8 +410,8 @@ static void qentry_destroy(QDictEntry *e)
     assert(e->value != NULL);
 
     qobject_decref(e->value);
-    qemu_free(e->key);
-    qemu_free(e);
+    g_free(e->key);
+    g_free(e);
 }
 
 /**
@@ -452,5 +452,5 @@ static void qdict_destroy_obj(QObject *obj)
         }
     }
 
-    qemu_free(qdict);
+    g_free(qdict);
 }
diff --git a/qemu-char.c b/qemu-char.c
index 8e8cf31..2358117 100644
--- a/qemu-char.c
+++ b/qemu-char.c
@@ -228,7 +228,7 @@ static int qemu_chr_open_null(QemuOpts *opts, CharDriverState **_chr)
 {
     CharDriverState *chr;
 
-    chr = qemu_mallocz(sizeof(CharDriverState));
+    chr = g_malloc0(sizeof(CharDriverState));
     chr->chr_write = null_chr_write;
 
     *_chr= chr;
@@ -477,8 +477,8 @@ static CharDriverState *qemu_chr_open_mux(CharDriverState *drv)
     CharDriverState *chr;
     MuxDriver *d;
 
-    chr = qemu_mallocz(sizeof(CharDriverState));
-    d = qemu_mallocz(sizeof(MuxDriver));
+    chr = g_malloc0(sizeof(CharDriverState));
+    d = g_malloc0(sizeof(MuxDriver));
 
     chr->opaque = d;
     d->drv = drv;
@@ -617,7 +617,7 @@ static void fd_chr_close(struct CharDriverState *chr)
         }
     }
 
-    qemu_free(s);
+    g_free(s);
     qemu_chr_event(chr, CHR_EVENT_CLOSED);
 }
 
@@ -627,8 +627,8 @@ static CharDriverState *qemu_chr_open_fd(int fd_in, int fd_out)
     CharDriverState *chr;
     FDCharDriver *s;
 
-    chr = qemu_mallocz(sizeof(CharDriverState));
-    s = qemu_mallocz(sizeof(FDCharDriver));
+    chr = g_malloc0(sizeof(CharDriverState));
+    s = g_malloc0(sizeof(FDCharDriver));
     s->fd_in = fd_in;
     s->fd_out = fd_out;
     chr->opaque = s;
@@ -981,7 +981,7 @@ static void pty_chr_close(struct CharDriverState *chr)
     close(s->fd);
     qemu_del_timer(s->timer);
     qemu_free_timer(s->timer);
-    qemu_free(s);
+    g_free(s);
     qemu_chr_event(chr, CHR_EVENT_CLOSED);
 }
 
@@ -999,8 +999,8 @@ static int qemu_chr_open_pty(QemuOpts *opts, CharDriverState **_chr)
 #define q_ptsname(x) ptsname(x)
 #endif
 
-    chr = qemu_mallocz(sizeof(CharDriverState));
-    s = qemu_mallocz(sizeof(PtyCharDriver));
+    chr = g_malloc0(sizeof(CharDriverState));
+    s = g_malloc0(sizeof(PtyCharDriver));
 
     if (openpty(&s->fd, &slave_fd, pty_name, NULL, NULL) < 0) {
         return -errno;
@@ -1013,7 +1013,7 @@ static int qemu_chr_open_pty(QemuOpts *opts, CharDriverState **_chr)
     close(slave_fd);
 
     len = strlen(q_ptsname(s->fd)) + 5;
-    chr->filename = qemu_malloc(len);
+    chr->filename = g_malloc(len);
     snprintf(chr->filename, len, "pty:%s", q_ptsname(s->fd));
     qemu_opt_set(opts, "path", q_ptsname(s->fd));
     fprintf(stderr, "char device redirected to %s\n", q_ptsname(s->fd));
@@ -1358,7 +1358,7 @@ static void pp_close(CharDriverState *chr)
     pp_hw_mode(drv, IEEE1284_MODE_COMPAT);
     ioctl(fd, PPRELEASE);
     close(fd);
-    qemu_free(drv);
+    g_free(drv);
     qemu_chr_event(chr, CHR_EVENT_CLOSED);
 }
 
@@ -1379,11 +1379,11 @@ static int qemu_chr_open_pp(QemuOpts *opts, CharDriverState **_chr)
         return -errno;
     }
 
-    drv = qemu_mallocz(sizeof(ParallelCharDriver));
+    drv = g_malloc0(sizeof(ParallelCharDriver));
     drv->fd = fd;
     drv->mode = IEEE1284_MODE_COMPAT;
 
-    chr = qemu_mallocz(sizeof(CharDriverState));
+    chr = g_malloc0(sizeof(CharDriverState));
     chr->chr_write = null_chr_write;
     chr->chr_ioctl = pp_ioctl;
     chr->chr_close = pp_close;
@@ -1445,7 +1445,7 @@ static int qemu_chr_open_pp(QemuOpts *opts, CharDriverState **_chr)
         return -errno;
     }
 
-    chr = qemu_mallocz(sizeof(CharDriverState));
+    chr = g_malloc0(sizeof(CharDriverState));
     chr->opaque = (void *)(intptr_t)fd;
     chr->chr_write = null_chr_write;
     chr->chr_ioctl = pp_ioctl;
@@ -1663,8 +1663,8 @@ static int qemu_chr_open_win(QemuOpts *opts, CharDriverState **_chr)
     CharDriverState *chr;
     WinCharState *s;
 
-    chr = qemu_mallocz(sizeof(CharDriverState));
-    s = qemu_mallocz(sizeof(WinCharState));
+    chr = g_malloc0(sizeof(CharDriverState));
+    s = g_malloc0(sizeof(WinCharState));
     chr->opaque = s;
     chr->chr_write = win_chr_write;
     chr->chr_close = win_chr_close;
@@ -1765,8 +1765,8 @@ static int qemu_chr_open_win_pipe(QemuOpts *opts, CharDriverState **_chr)
     CharDriverState *chr;
     WinCharState *s;
 
-    chr = qemu_mallocz(sizeof(CharDriverState));
-    s = qemu_mallocz(sizeof(WinCharState));
+    chr = g_malloc0(sizeof(CharDriverState));
+    s = g_malloc0(sizeof(WinCharState));
     chr->opaque = s;
     chr->chr_write = win_chr_write;
     chr->chr_close = win_chr_close;
@@ -1787,8 +1787,8 @@ static int qemu_chr_open_win_file(HANDLE fd_out, CharDriverState **pchr)
     CharDriverState *chr;
     WinCharState *s;
 
-    chr = qemu_mallocz(sizeof(CharDriverState));
-    s = qemu_mallocz(sizeof(WinCharState));
+    chr = g_malloc0(sizeof(CharDriverState));
+    s = g_malloc0(sizeof(WinCharState));
     s->hcom = fd_out;
     chr->opaque = s;
     chr->chr_write = win_chr_write;
@@ -1890,7 +1890,7 @@ static void udp_chr_close(CharDriverState *chr)
         qemu_set_fd_handler(s->fd, NULL, NULL, NULL);
         closesocket(s->fd);
     }
-    qemu_free(s);
+    g_free(s);
     qemu_chr_event(chr, CHR_EVENT_CLOSED);
 }
 
@@ -1901,8 +1901,8 @@ static int qemu_chr_open_udp(QemuOpts *opts, CharDriverState **_chr)
     int fd = -1;
     int ret;
 
-    chr = qemu_mallocz(sizeof(CharDriverState));
-    s = qemu_mallocz(sizeof(NetCharDriver));
+    chr = g_malloc0(sizeof(CharDriverState));
+    s = g_malloc0(sizeof(NetCharDriver));
 
     fd = inet_dgram_opts(opts);
     if (fd < 0) {
@@ -1923,8 +1923,8 @@ static int qemu_chr_open_udp(QemuOpts *opts, CharDriverState **_chr)
     return 0;
 
 return_err:
-    qemu_free(chr);
-    qemu_free(s);
+    g_free(chr);
+    g_free(s);
     if (fd >= 0) {
         closesocket(fd);
     }
@@ -2215,7 +2215,7 @@ static void tcp_chr_close(CharDriverState *chr)
         qemu_set_fd_handler(s->listen_fd, NULL, NULL, NULL);
         closesocket(s->listen_fd);
     }
-    qemu_free(s);
+    g_free(s);
     qemu_chr_event(chr, CHR_EVENT_CLOSED);
 }
 
@@ -2239,8 +2239,8 @@ static int qemu_chr_open_socket(QemuOpts *opts, CharDriverState **_chr)
     if (!is_listen)
         is_waitconnect = 0;
 
-    chr = qemu_mallocz(sizeof(CharDriverState));
-    s = qemu_mallocz(sizeof(TCPCharDriver));
+    chr = g_malloc0(sizeof(CharDriverState));
+    s = g_malloc0(sizeof(TCPCharDriver));
 
     if (is_unix) {
         if (is_listen) {
@@ -2290,7 +2290,7 @@ static int qemu_chr_open_socket(QemuOpts *opts, CharDriverState **_chr)
     }
 
     /* for "info chardev" monitor command */
-    chr->filename = qemu_malloc(256);
+    chr->filename = g_malloc(256);
     if (is_unix) {
         snprintf(chr->filename, 256, "unix:%s%s",
                  qemu_opt_get(opts, "path"),
@@ -2318,8 +2318,8 @@ static int qemu_chr_open_socket(QemuOpts *opts, CharDriverState **_chr)
  fail:
     if (fd >= 0)
         closesocket(fd);
-    qemu_free(s);
-    qemu_free(chr);
+    g_free(s);
+    g_free(chr);
     return ret;
 }
 
@@ -2341,7 +2341,7 @@ static int mem_chr_write(CharDriverState *chr, const uint8_t *buf, int len)
         /* grow outbuf */
         d->outbuf_capacity += len;
         d->outbuf_capacity *= 2;
-        d->outbuf = qemu_realloc(d->outbuf, d->outbuf_capacity);
+        d->outbuf = g_realloc(d->outbuf, d->outbuf_capacity);
     }
 
     memcpy(d->outbuf + d->outbuf_size, buf, len);
@@ -2354,10 +2354,10 @@ void qemu_chr_init_mem(CharDriverState *chr)
 {
     MemoryDriver *d;
 
-    d = qemu_malloc(sizeof(*d));
+    d = g_malloc(sizeof(*d));
     d->outbuf_size = 0;
     d->outbuf_capacity = 4096;
-    d->outbuf = qemu_mallocz(d->outbuf_capacity);
+    d->outbuf = g_malloc0(d->outbuf_capacity);
 
     memset(chr, 0, sizeof(*chr));
     chr->opaque = d;
@@ -2375,8 +2375,8 @@ void qemu_chr_close_mem(CharDriverState *chr)
 {
     MemoryDriver *d = chr->opaque;
 
-    qemu_free(d->outbuf);
-    qemu_free(chr->opaque);
+    g_free(d->outbuf);
+    g_free(chr->opaque);
     chr->opaque = NULL;
     chr->chr_write = NULL;
 }
@@ -2583,14 +2583,14 @@ CharDriverState *qemu_chr_open_opts(QemuOpts *opts,
     }
 
     if (!chr->filename)
-        chr->filename = qemu_strdup(qemu_opt_get(opts, "backend"));
+        chr->filename = g_strdup(qemu_opt_get(opts, "backend"));
     chr->init = init;
     QTAILQ_INSERT_TAIL(&chardevs, chr, next);
 
     if (qemu_opt_get_bool(opts, "mux", 0)) {
         CharDriverState *base = chr;
         int len = strlen(qemu_opts_id(opts)) + 6;
-        base->label = qemu_malloc(len);
+        base->label = g_malloc(len);
         snprintf(base->label, len, "%s-base", qemu_opts_id(opts));
         chr = qemu_chr_open_mux(base);
         chr->filename = base->filename;
@@ -2599,7 +2599,7 @@ CharDriverState *qemu_chr_open_opts(QemuOpts *opts,
     } else {
         chr->avail_connections = 1;
     }
-    chr->label = qemu_strdup(qemu_opts_id(opts));
+    chr->label = g_strdup(qemu_opts_id(opts));
     return chr;
 }
 
@@ -2651,9 +2651,9 @@ void qemu_chr_close(CharDriverState *chr)
     QTAILQ_REMOVE(&chardevs, chr, next);
     if (chr->chr_close)
         chr->chr_close(chr);
-    qemu_free(chr->filename);
-    qemu_free(chr->label);
-    qemu_free(chr);
+    g_free(chr->filename);
+    g_free(chr->label);
+    g_free(chr);
 }
 
 static void qemu_chr_qlist_iter(QObject *obj, void *opaque)
diff --git a/qemu-ga.c b/qemu-ga.c
index 869ee37..eb632b7 100644
--- a/qemu-ga.c
+++ b/qemu-ga.c
@@ -610,7 +610,7 @@ int main(int argc, char **argv)
         become_daemon(pidfile);
     }
 
-    s = qemu_mallocz(sizeof(GAState));
+    s = g_malloc0(sizeof(GAState));
     s->conn_channel = NULL;
     s->path = path;
     s->method = method;
diff --git a/qemu-img.c b/qemu-img.c
index b205e98..95f3219 100644
--- a/qemu-img.c
+++ b/qemu-img.c
@@ -713,7 +713,7 @@ static int img_convert(int argc, char **argv)
     qemu_progress_init(progress, 2.0);
     qemu_progress_print(0, 100);
 
-    bs = qemu_mallocz(bs_n * sizeof(BlockDriverState *));
+    bs = g_malloc0(bs_n * sizeof(BlockDriverState *));
 
     total_sectors = 0;
     for (bs_i = 0; bs_i < bs_n; bs_i++) {
@@ -834,7 +834,7 @@ static int img_convert(int argc, char **argv)
     bs_i = 0;
     bs_offset = 0;
     bdrv_get_geometry(bs[0], &bs_sectors);
-    buf = qemu_malloc(IO_BUF_SIZE);
+    buf = g_malloc(IO_BUF_SIZE);
 
     if (compress) {
         ret = bdrv_get_info(out_bs, &bdi);
@@ -1006,7 +1006,7 @@ out:
     qemu_progress_end();
     free_option_parameters(create_options);
     free_option_parameters(param);
-    qemu_free(buf);
+    g_free(buf);
     if (out_bs) {
         bdrv_delete(out_bs);
     }
@@ -1016,7 +1016,7 @@ out:
                 bdrv_delete(bs[bs_i]);
             }
         }
-        qemu_free(bs);
+        g_free(bs);
     }
     if (ret) {
         return 1;
@@ -1040,7 +1040,7 @@ static void dump_snapshots(BlockDriverState *bs)
         sn = &sn_tab[i];
         printf("%s\n", bdrv_snapshot_dump(buf, sizeof(buf), sn));
     }
-    qemu_free(sn_tab);
+    g_free(sn_tab);
 }
 
 static int img_info(int argc, char **argv)
@@ -1373,8 +1373,8 @@ static int img_rebase(int argc, char **argv)
         uint8_t * buf_new;
         float local_progress;
 
-        buf_old = qemu_malloc(IO_BUF_SIZE);
-        buf_new = qemu_malloc(IO_BUF_SIZE);
+        buf_old = g_malloc(IO_BUF_SIZE);
+        buf_new = g_malloc(IO_BUF_SIZE);
 
         bdrv_get_geometry(bs, &num_sectors);
 
@@ -1430,8 +1430,8 @@ static int img_rebase(int argc, char **argv)
             qemu_progress_print(local_progress, 100);
         }
 
-        qemu_free(buf_old);
-        qemu_free(buf_new);
+        g_free(buf_old);
+        g_free(buf_new);
     }
 
     /*
diff --git a/qemu-io.c b/qemu-io.c
index a553d0c..7e40c48 100644
--- a/qemu-io.c
+++ b/qemu-io.c
@@ -950,9 +950,9 @@ static int multiwrite_f(int argc, char **argv)
         }
     }
 
-    reqs = qemu_malloc(nr_reqs * sizeof(*reqs));
-    buf = qemu_malloc(nr_reqs * sizeof(*buf));
-    qiovs = qemu_malloc(nr_reqs * sizeof(*qiovs));
+    reqs = g_malloc(nr_reqs * sizeof(*reqs));
+    buf = g_malloc(nr_reqs * sizeof(*buf));
+    qiovs = g_malloc(nr_reqs * sizeof(*qiovs));
 
     for (i = 0; i < nr_reqs; i++) {
         int j;
@@ -1017,9 +1017,9 @@ out:
         qemu_io_free(buf[i]);
         qemu_iovec_destroy(&qiovs[i]);
     }
-    qemu_free(buf);
-    qemu_free(reqs);
-    qemu_free(qiovs);
+    g_free(buf);
+    g_free(reqs);
+    g_free(qiovs);
     return 0;
 }
 
diff --git a/qemu-nbd.c b/qemu-nbd.c
index d91c02c..0b25a4d 100644
--- a/qemu-nbd.c
+++ b/qemu-nbd.c
@@ -431,7 +431,7 @@ int main(int argc, char **argv)
         /* children */
     }
 
-    sharing_fds = qemu_malloc((shared + 1) * sizeof(int));
+    sharing_fds = g_malloc((shared + 1) * sizeof(int));
 
     if (socket) {
         sharing_fds[0] = unix_socket_incoming(socket);
@@ -491,7 +491,7 @@ int main(int argc, char **argv)
 
     close(sharing_fds[0]);
     bdrv_close(bs);
-    qemu_free(sharing_fds);
+    g_free(sharing_fds);
     if (socket)
         unlink(socket);
 
diff --git a/qemu-option.c b/qemu-option.c
index 65db542..105d760 100644
--- a/qemu-option.c
+++ b/qemu-option.c
@@ -277,7 +277,7 @@ int set_option_parameter(QEMUOptionParameter *list, const char *name,
 
     case OPT_STRING:
         if (value != NULL) {
-            list->value.s = qemu_strdup(value);
+            list->value.s = g_strdup(value);
         } else {
             fprintf(stderr, "Option '%s' needs a parameter\n", name);
             return -1;
@@ -337,12 +337,12 @@ void free_option_parameters(QEMUOptionParameter *list)
 
     while (cur && cur->name) {
         if (cur->type == OPT_STRING) {
-            qemu_free(cur->value.s);
+            g_free(cur->value.s);
         }
         cur++;
     }
 
-    qemu_free(list);
+    g_free(list);
 }
 
 /*
@@ -377,7 +377,7 @@ QEMUOptionParameter *append_option_parameters(QEMUOptionParameter *dest,
 
     num_options += count_option_parameters(list);
 
-    dest = qemu_realloc(dest, (num_options + 1) * sizeof(QEMUOptionParameter));
+    dest = g_realloc(dest, (num_options + 1) * sizeof(QEMUOptionParameter));
     dest[num_dest_options].name = NULL;
 
     while (list && list->name) {
@@ -594,9 +594,9 @@ static int qemu_opt_parse(QemuOpt *opt)
 static void qemu_opt_del(QemuOpt *opt)
 {
     QTAILQ_REMOVE(&opt->opts->head, opt, next);
-    qemu_free((/* !const */ char*)opt->name);
-    qemu_free((/* !const */ char*)opt->str);
-    qemu_free(opt);
+    g_free((/* !const */ char*)opt->name);
+    g_free((/* !const */ char*)opt->str);
+    g_free(opt);
 }
 
 int qemu_opt_set(QemuOpts *opts, const char *name, const char *value)
@@ -619,15 +619,15 @@ int qemu_opt_set(QemuOpts *opts, const char *name, const char *value)
         }
     }
 
-    opt = qemu_mallocz(sizeof(*opt));
-    opt->name = qemu_strdup(name);
+    opt = g_malloc0(sizeof(*opt));
+    opt->name = g_strdup(name);
     opt->opts = opts;
     QTAILQ_INSERT_TAIL(&opts->head, opt, next);
     if (desc[i].name != NULL) {
         opt->desc = desc+i;
     }
     if (value) {
-        opt->str = qemu_strdup(value);
+        opt->str = g_strdup(value);
     }
     if (qemu_opt_parse(opt) < 0) {
         qemu_opt_del(opt);
@@ -701,9 +701,9 @@ QemuOpts *qemu_opts_create(QemuOptsList *list, const char *id, int fail_if_exist
             }
         }
     }
-    opts = qemu_mallocz(sizeof(*opts));
+    opts = g_malloc0(sizeof(*opts));
     if (id) {
-        opts->id = qemu_strdup(id);
+        opts->id = g_strdup(id);
     }
     opts->list = list;
     loc_save(&opts->loc);
@@ -754,8 +754,8 @@ void qemu_opts_del(QemuOpts *opts)
         qemu_opt_del(opt);
     }
     QTAILQ_REMOVE(&opts->list->head, opts, next);
-    qemu_free(opts->id);
-    qemu_free(opts);
+    g_free(opts->id);
+    g_free(opts);
 }
 
 int qemu_opts_print(QemuOpts *opts, void *dummy)
diff --git a/qemu-sockets.c b/qemu-sockets.c
index eda1850..183a9cb 100644
--- a/qemu-sockets.c
+++ b/qemu-sockets.c
@@ -593,10 +593,10 @@ int unix_listen(const char *str, char *ostr, int olen)
     if (optstr) {
         len = optstr - str;
         if (len) {
-            path = qemu_malloc(len+1);
+            path = g_malloc(len+1);
             snprintf(path, len+1, "%.*s", len, str);
             qemu_opt_set(opts, "path", path);
-            qemu_free(path);
+            g_free(path);
         }
     } else {
         qemu_opt_set(opts, "path", str);
diff --git a/qemu-thread-win32.c b/qemu-thread-win32.c
index 2d2d5ab..a27332e 100644
--- a/qemu-thread-win32.c
+++ b/qemu-thread-win32.c
@@ -249,7 +249,7 @@ void qemu_thread_create(QemuThread *thread,
 
     struct QemuThreadData *data;
     qemu_thread_init();
-    data = qemu_malloc(sizeof *data);
+    data = g_malloc(sizeof *data);
     data->thread = thread;
     data->start_routine = start_routine;
     data->arg = arg;
diff --git a/qemu-timer.c b/qemu-timer.c
index 30e8f12..19313d3 100644
--- a/qemu-timer.c
+++ b/qemu-timer.c
@@ -327,7 +327,7 @@ void configure_alarms(char const *opt)
         exit(0);
     }
 
-    arg = qemu_strdup(opt);
+    arg = g_strdup(opt);
 
     /* Reorder the array */
     name = strtok(arg, ",");
@@ -356,7 +356,7 @@ next:
         name = strtok(NULL, ",");
     }
 
-    qemu_free(arg);
+    g_free(arg);
 
     if (cur) {
         /* Disable remaining timers */
@@ -380,7 +380,7 @@ static QEMUClock *qemu_new_clock(int type)
 {
     QEMUClock *clock;
 
-    clock = qemu_mallocz(sizeof(QEMUClock));
+    clock = g_malloc0(sizeof(QEMUClock));
     clock->type = type;
     clock->enabled = 1;
     notifier_list_init(&clock->reset_notifiers);
@@ -485,7 +485,7 @@ QEMUTimer *qemu_new_timer(QEMUClock *clock, int scale,
 {
     QEMUTimer *ts;
 
-    ts = qemu_mallocz(sizeof(QEMUTimer));
+    ts = g_malloc0(sizeof(QEMUTimer));
     ts->clock = clock;
     ts->cb = cb;
     ts->opaque = opaque;
@@ -495,7 +495,7 @@ QEMUTimer *qemu_new_timer(QEMUClock *clock, int scale,
 
 void qemu_free_timer(QEMUTimer *ts)
 {
-    qemu_free(ts);
+    g_free(ts);
 }
 
 /* stop a timer, but do not dealloc it */
diff --git a/qemu-tool.c b/qemu-tool.c
index 41e5c41..eb89fe0 100644
--- a/qemu-tool.c
+++ b/qemu-tool.c
@@ -76,12 +76,12 @@ void qemu_notify_event(void)
 QEMUTimer *qemu_new_timer(QEMUClock *clock, int scale,
                           QEMUTimerCB *cb, void *opaque)
 {
-    return qemu_malloc(1);
+    return g_malloc(1);
 }
 
 void qemu_free_timer(QEMUTimer *ts)
 {
-    qemu_free(ts);
+    g_free(ts);
 }
 
 void qemu_del_timer(QEMUTimer *ts)
diff --git a/qerror.c b/qerror.c
index 69c1bc9..3d64b80 100644
--- a/qerror.c
+++ b/qerror.c
@@ -242,7 +242,7 @@ QError *qerror_new(void)
 {
     QError *qerr;
 
-    qerr = qemu_mallocz(sizeof(*qerr));
+    qerr = g_malloc0(sizeof(*qerr));
     QOBJECT_INIT(qerr, &qerror_type);
 
     return qerr;
@@ -501,5 +501,5 @@ static void qerror_destroy_obj(QObject *obj)
     qerr = qobject_to_qerror(obj);
 
     QDECREF(qerr->error);
-    qemu_free(qerr);
+    g_free(qerr);
 }
diff --git a/qfloat.c b/qfloat.c
index f8c8a2e..98338f3 100644
--- a/qfloat.c
+++ b/qfloat.c
@@ -31,7 +31,7 @@ QFloat *qfloat_from_double(double value)
 {
     QFloat *qf;
 
-    qf = qemu_malloc(sizeof(*qf));
+    qf = g_malloc(sizeof(*qf));
     qf->value = value;
     QOBJECT_INIT(qf, &qfloat_type);
 
@@ -64,5 +64,5 @@ QFloat *qobject_to_qfloat(const QObject *obj)
 static void qfloat_destroy_obj(QObject *obj)
 {
     assert(obj != NULL);
-    qemu_free(qobject_to_qfloat(obj));
+    g_free(qobject_to_qfloat(obj));
 }
diff --git a/qga/guest-agent-command-state.c b/qga/guest-agent-command-state.c
index bc6e0bd..969da23 100644
--- a/qga/guest-agent-command-state.c
+++ b/qga/guest-agent-command-state.c
@@ -27,7 +27,7 @@ void ga_command_state_add(GACommandState *cs,
                           void (*init)(void),
                           void (*cleanup)(void))
 {
-    GACommandGroup *cg = qemu_mallocz(sizeof(GACommandGroup));
+    GACommandGroup *cg = g_malloc0(sizeof(GACommandGroup));
     cg->init = init;
     cg->cleanup = cleanup;
     cs->groups = g_slist_append(cs->groups, cg);
@@ -67,7 +67,7 @@ void ga_command_state_cleanup_all(GACommandState *cs)
 
 GACommandState *ga_command_state_new(void)
 {
-    GACommandState *cs = qemu_mallocz(sizeof(GACommandState));
+    GACommandState *cs = g_malloc0(sizeof(GACommandState));
     cs->groups = NULL;
     return cs;
 }
diff --git a/qga/guest-agent-commands.c b/qga/guest-agent-commands.c
index 30c4068..6da9904 100644
--- a/qga/guest-agent-commands.c
+++ b/qga/guest-agent-commands.c
@@ -56,7 +56,7 @@ void qmp_guest_ping(Error **err)
 
 struct GuestAgentInfo *qmp_guest_info(Error **err)
 {
-    GuestAgentInfo *info = qemu_mallocz(sizeof(GuestAgentInfo));
+    GuestAgentInfo *info = g_malloc0(sizeof(GuestAgentInfo));
 
     info->version = g_strdup(QGA_VERSION);
 
@@ -114,7 +114,7 @@ static void guest_file_handle_add(FILE *fh)
 {
     GuestFileHandle *gfh;
 
-    gfh = qemu_mallocz(sizeof(GuestFileHandle));
+    gfh = g_malloc0(sizeof(GuestFileHandle));
     gfh->id = fileno(fh);
     gfh->fh = fh;
     QTAILQ_INSERT_TAIL(&guest_file_state.filehandles, gfh, next);
@@ -185,7 +185,7 @@ void qmp_guest_file_close(int64_t handle, Error **err)
     }
 
     QTAILQ_REMOVE(&guest_file_state.filehandles, gfh, next);
-    qemu_free(gfh);
+    g_free(gfh);
 }
 
 struct GuestFileRead *qmp_guest_file_read(int64_t handle, bool has_count,
@@ -210,21 +210,21 @@ struct GuestFileRead *qmp_guest_file_read(int64_t handle, bool has_count,
     }
 
     fh = gfh->fh;
-    buf = qemu_mallocz(count+1);
+    buf = g_malloc0(count+1);
     read_count = fread(buf, 1, count, fh);
     if (ferror(fh)) {
         slog("guest-file-read failed, handle: %ld", handle);
         error_set(err, QERR_QGA_COMMAND_FAILED, "fread() failed");
     } else {
         buf[read_count] = 0;
-        read_data = qemu_mallocz(sizeof(GuestFileRead));
+        read_data = g_malloc0(sizeof(GuestFileRead));
         read_data->count = read_count;
         read_data->eof = feof(fh);
         if (read_count) {
             read_data->buf_b64 = g_base64_encode(buf, read_count);
         }
     }
-    qemu_free(buf);
+    g_free(buf);
     clearerr(fh);
 
     return read_data;
@@ -251,7 +251,7 @@ GuestFileWrite *qmp_guest_file_write(int64_t handle, const char *buf_b64,
     if (!has_count) {
         count = buf_len;
     } else if (count < 0 || count > buf_len) {
-        qemu_free(buf);
+        g_free(buf);
         error_set(err, QERR_INVALID_PARAMETER, "count");
         return NULL;
     }
@@ -261,11 +261,11 @@ GuestFileWrite *qmp_guest_file_write(int64_t handle, const char *buf_b64,
         slog("guest-file-write failed, handle: %ld", handle);
         error_set(err, QERR_QGA_COMMAND_FAILED, "fwrite() error");
     } else {
-        write_data = qemu_mallocz(sizeof(GuestFileWrite));
+        write_data = g_malloc0(sizeof(GuestFileWrite));
         write_data->count = write_count;
         write_data->eof = feof(fh);
     }
-    qemu_free(buf);
+    g_free(buf);
     clearerr(fh);
 
     return write_data;
@@ -289,7 +289,7 @@ struct GuestFileSeek *qmp_guest_file_seek(int64_t handle, int64_t offset,
     if (ret == -1) {
         error_set(err, QERR_QGA_COMMAND_FAILED, strerror(errno));
     } else {
-        seek_data = qemu_mallocz(sizeof(GuestFileRead));
+        seek_data = g_malloc0(sizeof(GuestFileRead));
         seek_data->position = ftell(fh);
         seek_data->eof = feof(fh);
     }
@@ -355,9 +355,9 @@ static int guest_fsfreeze_build_mount_list(void)
 
     QTAILQ_FOREACH_SAFE(mount, &guest_fsfreeze_state.mount_list, next, temp) {
         QTAILQ_REMOVE(&guest_fsfreeze_state.mount_list, mount, next);
-        qemu_free(mount->dirname);
-        qemu_free(mount->devtype);
-        qemu_free(mount);
+        g_free(mount->dirname);
+        g_free(mount->devtype);
+        g_free(mount);
     }
 
     fp = setmntent(mtab, "r");
@@ -379,9 +379,9 @@ static int guest_fsfreeze_build_mount_list(void)
             continue;
         }
 
-        mount = qemu_mallocz(sizeof(GuestFsfreezeMount));
-        mount->dirname = qemu_strdup(ment->mnt_dir);
-        mount->devtype = qemu_strdup(ment->mnt_type);
+        mount = g_malloc0(sizeof(GuestFsfreezeMount));
+        mount->dirname = g_strdup(ment->mnt_dir);
+        mount->devtype = g_strdup(ment->mnt_type);
 
         QTAILQ_INSERT_TAIL(&guest_fsfreeze_state.mount_list, mount, next);
     }
diff --git a/qint.c b/qint.c
index fb3823a..ee51804 100644
--- a/qint.c
+++ b/qint.c
@@ -30,7 +30,7 @@ QInt *qint_from_int(int64_t value)
 {
     QInt *qi;
 
-    qi = qemu_malloc(sizeof(*qi));
+    qi = g_malloc(sizeof(*qi));
     qi->value = value;
     QOBJECT_INIT(qi, &qint_type);
 
@@ -63,5 +63,5 @@ QInt *qobject_to_qint(const QObject *obj)
 static void qint_destroy_obj(QObject *obj)
 {
     assert(obj != NULL);
-    qemu_free(qobject_to_qint(obj));
+    g_free(qobject_to_qint(obj));
 }
diff --git a/qlist.c b/qlist.c
index 5730fb8..88498b1 100644
--- a/qlist.c
+++ b/qlist.c
@@ -31,7 +31,7 @@ QList *qlist_new(void)
 {
     QList *qlist;
 
-    qlist = qemu_malloc(sizeof(*qlist));
+    qlist = g_malloc(sizeof(*qlist));
     QTAILQ_INIT(&qlist->head);
     QOBJECT_INIT(qlist, &qlist_type);
 
@@ -64,7 +64,7 @@ void qlist_append_obj(QList *qlist, QObject *value)
 {
     QListEntry *entry;
 
-    entry = qemu_malloc(sizeof(*entry));
+    entry = g_malloc(sizeof(*entry));
     entry->value = value;
 
     QTAILQ_INSERT_TAIL(&qlist->head, entry, next);
@@ -98,7 +98,7 @@ QObject *qlist_pop(QList *qlist)
     QTAILQ_REMOVE(&qlist->head, entry, next);
 
     ret = entry->value;
-    qemu_free(entry);
+    g_free(entry);
 
     return ret;
 }
@@ -150,8 +150,8 @@ static void qlist_destroy_obj(QObject *obj)
     QTAILQ_FOREACH_SAFE(entry, &qlist->head, next, next_entry) {
         QTAILQ_REMOVE(&qlist->head, entry, next);
         qobject_decref(entry->value);
-        qemu_free(entry);
+        g_free(entry);
     }
 
-    qemu_free(qlist);
+    g_free(qlist);
 }
diff --git a/qstring.c b/qstring.c
index 4e2ba08..b7e12e4 100644
--- a/qstring.c
+++ b/qstring.c
@@ -40,12 +40,12 @@ QString *qstring_from_substr(const char *str, int start, int end)
 {
     QString *qstring;
 
-    qstring = qemu_malloc(sizeof(*qstring));
+    qstring = g_malloc(sizeof(*qstring));
 
     qstring->length = end - start + 1;
     qstring->capacity = qstring->length;
 
-    qstring->string = qemu_malloc(qstring->capacity + 1);
+    qstring->string = g_malloc(qstring->capacity + 1);
     memcpy(qstring->string, str + start, qstring->length);
     qstring->string[qstring->length] = 0;
 
@@ -70,7 +70,7 @@ static void capacity_increase(QString *qstring, size_t len)
         qstring->capacity += len;
         qstring->capacity *= 2; /* use exponential growth */
 
-        qstring->string = qemu_realloc(qstring->string, qstring->capacity + 1);
+        qstring->string = g_realloc(qstring->string, qstring->capacity + 1);
     }
 }
 
@@ -136,6 +136,6 @@ static void qstring_destroy_obj(QObject *obj)
 
     assert(obj != NULL);
     qs = qobject_to_qstring(obj);
-    qemu_free(qs->string);
-    qemu_free(qs);
+    g_free(qs->string);
+    g_free(qs);
 }
diff --git a/readline.c b/readline.c
index 92f9cd1..6a3160a 100644
--- a/readline.c
+++ b/readline.c
@@ -264,7 +264,7 @@ static void readline_hist_add(ReadLineState *rs, const char *cmdline)
 void readline_add_completion(ReadLineState *rs, const char *str)
 {
     if (rs->nb_completions < READLINE_MAX_COMPLETIONS) {
-        rs->completions[rs->nb_completions++] = qemu_strdup(str);
+        rs->completions[rs->nb_completions++] = g_strdup(str);
     }
 }
 
@@ -281,11 +281,11 @@ static void readline_completion(ReadLineState *rs)
 
     rs->nb_completions = 0;
 
-    cmdline = qemu_malloc(rs->cmd_buf_index + 1);
+    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);
-    qemu_free(cmdline);
+    g_free(cmdline);
 
     /* no completion found */
     if (rs->nb_completions <= 0)
@@ -466,7 +466,7 @@ const char *readline_get_history(ReadLineState *rs, unsigned int index)
 ReadLineState *readline_init(Monitor *mon,
                              ReadLineCompletionFunc *completion_finder)
 {
-    ReadLineState *rs = qemu_mallocz(sizeof(*rs));
+    ReadLineState *rs = g_malloc0(sizeof(*rs));
 
     rs->hist_entry = -1;
     rs->mon = mon;
diff --git a/savevm.c b/savevm.c
index 7801aa7..b06308b 100644
--- a/savevm.c
+++ b/savevm.c
@@ -206,7 +206,7 @@ static int socket_get_buffer(void *opaque, uint8_t *buf, int64_t pos, int size)
 static int socket_close(void *opaque)
 {
     QEMUFileSocket *s = opaque;
-    qemu_free(s);
+    g_free(s);
     return 0;
 }
 
@@ -234,7 +234,7 @@ static int stdio_pclose(void *opaque)
     QEMUFileStdio *s = opaque;
     int ret;
     ret = pclose(s->stdio_file);
-    qemu_free(s);
+    g_free(s);
     return ret;
 }
 
@@ -242,7 +242,7 @@ static int stdio_fclose(void *opaque)
 {
     QEMUFileStdio *s = opaque;
     fclose(s->stdio_file);
-    qemu_free(s);
+    g_free(s);
     return 0;
 }
 
@@ -255,7 +255,7 @@ QEMUFile *qemu_popen(FILE *stdio_file, const char *mode)
         return NULL;
     }
 
-    s = qemu_mallocz(sizeof(QEMUFileStdio));
+    s = g_malloc0(sizeof(QEMUFileStdio));
 
     s->stdio_file = stdio_file;
 
@@ -303,7 +303,7 @@ QEMUFile *qemu_fdopen(int fd, const char *mode)
         return NULL;
     }
 
-    s = qemu_mallocz(sizeof(QEMUFileStdio));
+    s = g_malloc0(sizeof(QEMUFileStdio));
     s->stdio_file = fdopen(fd, mode);
     if (!s->stdio_file)
         goto fail;
@@ -318,13 +318,13 @@ QEMUFile *qemu_fdopen(int fd, const char *mode)
     return s->file;
 
 fail:
-    qemu_free(s);
+    g_free(s);
     return NULL;
 }
 
 QEMUFile *qemu_fopen_socket(int fd)
 {
-    QEMUFileSocket *s = qemu_mallocz(sizeof(QEMUFileSocket));
+    QEMUFileSocket *s = g_malloc0(sizeof(QEMUFileSocket));
 
     s->fd = fd;
     s->file = qemu_fopen_ops(s, NULL, socket_get_buffer, socket_close, 
@@ -358,7 +358,7 @@ QEMUFile *qemu_fopen(const char *filename, const char *mode)
         return NULL;
     }
 
-    s = qemu_mallocz(sizeof(QEMUFileStdio));
+    s = g_malloc0(sizeof(QEMUFileStdio));
 
     s->stdio_file = fopen(filename, mode);
     if (!s->stdio_file)
@@ -373,7 +373,7 @@ QEMUFile *qemu_fopen(const char *filename, const char *mode)
     }
     return s->file;
 fail:
-    qemu_free(s);
+    g_free(s);
     return NULL;
 }
 
@@ -411,7 +411,7 @@ QEMUFile *qemu_fopen_ops(void *opaque, QEMUFilePutBufferFunc *put_buffer,
 {
     QEMUFile *f;
 
-    f = qemu_mallocz(sizeof(QEMUFile));
+    f = g_malloc0(sizeof(QEMUFile));
 
     f->opaque = opaque;
     f->put_buffer = put_buffer;
@@ -477,7 +477,7 @@ int qemu_fclose(QEMUFile *f)
     qemu_fflush(f);
     if (f->close)
         ret = f->close(f->opaque);
-    qemu_free(f);
+    g_free(f);
     return ret;
 }
 
@@ -1114,7 +1114,7 @@ int register_savevm_live(DeviceState *dev,
 {
     SaveStateEntry *se;
 
-    se = qemu_mallocz(sizeof(SaveStateEntry));
+    se = g_malloc0(sizeof(SaveStateEntry));
     se->version_id = version_id;
     se->section_id = global_section_id++;
     se->set_params = set_params;
@@ -1130,9 +1130,9 @@ int register_savevm_live(DeviceState *dev,
         if (id) {
             pstrcpy(se->idstr, sizeof(se->idstr), id);
             pstrcat(se->idstr, sizeof(se->idstr), "/");
-            qemu_free(id);
+            g_free(id);
 
-            se->compat = qemu_mallocz(sizeof(CompatEntry));
+            se->compat = g_malloc0(sizeof(CompatEntry));
             pstrcpy(se->compat->idstr, sizeof(se->compat->idstr), idstr);
             se->compat->instance_id = instance_id == -1 ?
                          calculate_compat_instance_id(idstr) : instance_id;
@@ -1174,7 +1174,7 @@ void unregister_savevm(DeviceState *dev, const char *idstr, void *opaque)
         if (path) {
             pstrcpy(id, sizeof(id), path);
             pstrcat(id, sizeof(id), "/");
-            qemu_free(path);
+            g_free(path);
         }
     }
     pstrcat(id, sizeof(id), idstr);
@@ -1183,9 +1183,9 @@ void unregister_savevm(DeviceState *dev, const char *idstr, void *opaque)
         if (strcmp(se->idstr, id) == 0 && se->opaque == opaque) {
             QTAILQ_REMOVE(&savevm_handlers, se, entry);
             if (se->compat) {
-                qemu_free(se->compat);
+                g_free(se->compat);
             }
-            qemu_free(se);
+            g_free(se);
         }
     }
 }
@@ -1203,7 +1203,7 @@ void register_device_unmigratable(DeviceState *dev, const char *idstr,
         if (path) {
             pstrcpy(id, sizeof(id), path);
             pstrcat(id, sizeof(id), "/");
-            qemu_free(path);
+            g_free(path);
         }
     }
     pstrcat(id, sizeof(id), idstr);
@@ -1225,7 +1225,7 @@ int vmstate_register_with_alias_id(DeviceState *dev, int instance_id,
     /* If this triggers, alias support can be dropped for the vmsd. */
     assert(alias_id == -1 || required_for_version >= vmsd->minimum_version_id);
 
-    se = qemu_mallocz(sizeof(SaveStateEntry));
+    se = g_malloc0(sizeof(SaveStateEntry));
     se->version_id = vmsd->version_id;
     se->section_id = global_section_id++;
     se->save_live_state = NULL;
@@ -1241,9 +1241,9 @@ int vmstate_register_with_alias_id(DeviceState *dev, int instance_id,
         if (id) {
             pstrcpy(se->idstr, sizeof(se->idstr), id);
             pstrcat(se->idstr, sizeof(se->idstr), "/");
-            qemu_free(id);
+            g_free(id);
 
-            se->compat = qemu_mallocz(sizeof(CompatEntry));
+            se->compat = g_malloc0(sizeof(CompatEntry));
             pstrcpy(se->compat->idstr, sizeof(se->compat->idstr), vmsd->name);
             se->compat->instance_id = instance_id == -1 ?
                          calculate_compat_instance_id(vmsd->name) : instance_id;
@@ -1279,9 +1279,9 @@ void vmstate_unregister(DeviceState *dev, const VMStateDescription *vmsd,
         if (se->vmsd == vmsd && se->opaque == opaque) {
             QTAILQ_REMOVE(&savevm_handlers, se, entry);
             if (se->compat) {
-                qemu_free(se->compat);
+                g_free(se->compat);
             }
-            qemu_free(se);
+            g_free(se);
         }
     }
 }
@@ -1785,7 +1785,7 @@ int qemu_loadvm_state(QEMUFile *f)
             }
 
             /* Add entry */
-            le = qemu_mallocz(sizeof(*le));
+            le = g_malloc0(sizeof(*le));
 
             le->se = se;
             le->section_id = section_id;
@@ -1835,7 +1835,7 @@ int qemu_loadvm_state(QEMUFile *f)
 out:
     QLIST_FOREACH_SAFE(le, &loadvm_handlers, entry, new_le) {
         QLIST_REMOVE(le, entry);
-        qemu_free(le);
+        g_free(le);
     }
 
     if (qemu_file_has_error(f))
@@ -1862,7 +1862,7 @@ static int bdrv_snapshot_find(BlockDriverState *bs, QEMUSnapshotInfo *sn_info,
             break;
         }
     }
-    qemu_free(sn_tab);
+    g_free(sn_tab);
     return ret;
 }
 
@@ -2141,7 +2141,7 @@ void do_info_snapshots(Monitor *mon)
         return;
     }
 
-    available_snapshots = qemu_mallocz(sizeof(int) * nb_sns);
+    available_snapshots = g_malloc0(sizeof(int) * nb_sns);
     total = 0;
     for (i = 0; i < nb_sns; i++) {
         sn = &sn_tab[i];
@@ -2174,7 +2174,7 @@ void do_info_snapshots(Monitor *mon)
         monitor_printf(mon, "There is no suitable snapshot available\n");
     }
 
-    qemu_free(sn_tab);
-    qemu_free(available_snapshots);
+    g_free(sn_tab);
+    g_free(available_snapshots);
 
 }
diff --git a/slirp/misc.c b/slirp/misc.c
index 6002550..6c80e69 100644
--- a/slirp/misc.c
+++ b/slirp/misc.c
@@ -182,7 +182,7 @@ fork_exec(struct socket *so, const char *ex, int do_pty)
 		   close(s);
 
 		i = 0;
-		bptr = qemu_strdup(ex); /* No need to free() this */
+		bptr = g_strdup(ex); /* No need to free() this */
 		if (do_pty == 1) {
 			/* Setup "slirp.telnetd -x" */
 			argv[i++] = "slirp.telnetd";
diff --git a/slirp/slirp.c b/slirp/slirp.c
index 2c242ef..655b3f4 100644
--- a/slirp/slirp.c
+++ b/slirp/slirp.c
@@ -202,7 +202,7 @@ Slirp *slirp_init(int restricted, struct in_addr vnetwork,
                   const char *bootfile, struct in_addr vdhcp_start,
                   struct in_addr vnameserver, void *opaque)
 {
-    Slirp *slirp = qemu_mallocz(sizeof(Slirp));
+    Slirp *slirp = g_malloc0(sizeof(Slirp));
 
     slirp_init_once();
 
@@ -222,10 +222,10 @@ Slirp *slirp_init(int restricted, struct in_addr vnetwork,
                 vhostname);
     }
     if (tftp_path) {
-        slirp->tftp_prefix = qemu_strdup(tftp_path);
+        slirp->tftp_prefix = g_strdup(tftp_path);
     }
     if (bootfile) {
-        slirp->bootp_filename = qemu_strdup(bootfile);
+        slirp->bootp_filename = g_strdup(bootfile);
     }
     slirp->vdhcp_startaddr = vdhcp_start;
     slirp->vnameserver_addr = vnameserver;
@@ -246,9 +246,9 @@ void slirp_cleanup(Slirp *slirp)
 
     unregister_savevm(NULL, "slirp", slirp);
 
-    qemu_free(slirp->tftp_prefix);
-    qemu_free(slirp->bootp_filename);
-    qemu_free(slirp);
+    g_free(slirp->tftp_prefix);
+    g_free(slirp->bootp_filename);
+    g_free(slirp);
 }
 
 #define CONN_CANFSEND(so) (((so)->so_state & (SS_FCANTSENDMORE|SS_ISFCONNECTED)) == SS_ISFCONNECTED)
diff --git a/slirp/tftp.c b/slirp/tftp.c
index 8055ccc..b78765f 100644
--- a/slirp/tftp.c
+++ b/slirp/tftp.c
@@ -37,7 +37,7 @@ static inline void tftp_session_update(struct tftp_session *spt)
 
 static void tftp_session_terminate(struct tftp_session *spt)
 {
-    qemu_free(spt->filename);
+    g_free(spt->filename);
     spt->slirp = NULL;
 }
 
@@ -54,7 +54,7 @@ static int tftp_session_allocate(Slirp *slirp, struct tftp_t *tp)
 
     /* sessions time out after 5 inactive seconds */
     if ((int)(curtime - spt->timestamp) > 5000) {
-        qemu_free(spt->filename);
+        g_free(spt->filename);
         goto found;
     }
   }
@@ -287,7 +287,7 @@ static void tftp_handle_rrq(Slirp *slirp, struct tftp_t *tp, int pktlen)
 
   /* prepend tftp_prefix */
   prefix_len = strlen(slirp->tftp_prefix);
-  spt->filename = qemu_malloc(prefix_len + TFTP_FILENAME_MAX + 2);
+  spt->filename = g_malloc(prefix_len + TFTP_FILENAME_MAX + 2);
   memcpy(spt->filename, slirp->tftp_prefix, prefix_len);
   spt->filename[prefix_len] = '/';
 
diff --git a/spice-qemu-char.c b/spice-qemu-char.c
index 95bf6b6..684024b 100644
--- a/spice-qemu-char.c
+++ b/spice-qemu-char.c
@@ -112,7 +112,7 @@ static int spice_chr_write(CharDriverState *chr, const uint8_t *buf, int len)
     assert(s->datalen == 0);
     if (s->bufsize < len) {
         s->bufsize = len;
-        s->buffer = qemu_realloc(s->buffer, s->bufsize);
+        s->buffer = g_realloc(s->buffer, s->bufsize);
     }
     memcpy(s->buffer, buf, len);
     s->datapos = s->buffer;
@@ -127,7 +127,7 @@ static void spice_chr_close(struct CharDriverState *chr)
 
     printf("%s\n", __func__);
     vmc_unregister_interface(s);
-    qemu_free(s);
+    g_free(s);
 }
 
 static void spice_chr_guest_open(struct CharDriverState *chr)
@@ -185,8 +185,8 @@ int qemu_chr_open_spice(QemuOpts *opts, CharDriverState **_chr)
         return -EINVAL;
     }
 
-    chr = qemu_mallocz(sizeof(CharDriverState));
-    s = qemu_mallocz(sizeof(SpiceCharDriver));
+    chr = g_malloc0(sizeof(CharDriverState));
+    s = g_malloc0(sizeof(SpiceCharDriver));
     s->chr = chr;
     s->debug = debug;
     s->active = false;
diff --git a/target-alpha/translate.c b/target-alpha/translate.c
index c61906a..1e224a2 100644
--- a/target-alpha/translate.c
+++ b/target-alpha/translate.c
@@ -3449,7 +3449,7 @@ CPUAlphaState * cpu_alpha_init (const char *cpu_model)
     CPUAlphaState *env;
     int implver, amask, i, max;
 
-    env = qemu_mallocz(sizeof(CPUAlphaState));
+    env = g_malloc0(sizeof(CPUAlphaState));
     cpu_exec_init(env);
     alpha_translate_init();
     tlb_flush(env, 1);
diff --git a/target-arm/helper.c b/target-arm/helper.c
index 8cae972..d3a3ba2 100644
--- a/target-arm/helper.c
+++ b/target-arm/helper.c
@@ -384,7 +384,7 @@ CPUARMState *cpu_arm_init(const char *cpu_model)
     id = cpu_arm_find_by_name(cpu_model);
     if (id == 0)
         return NULL;
-    env = qemu_mallocz(sizeof(CPUARMState));
+    env = g_malloc0(sizeof(CPUARMState));
     cpu_exec_init(env);
     if (!inited) {
         inited = 1;
diff --git a/target-cris/translate.c b/target-cris/translate.c
index dd85859..70abf8a 100644
--- a/target-cris/translate.c
+++ b/target-cris/translate.c
@@ -3516,7 +3516,7 @@ CPUCRISState *cpu_cris_init (const char *cpu_model)
 	static int tcg_initialized = 0;
 	int i;
 
-	env = qemu_mallocz(sizeof(CPUCRISState));
+	env = g_malloc0(sizeof(CPUCRISState));
 
 	env->pregs[PR_VR] = vr_by_name(cpu_model);
 	cpu_exec_init(env);
diff --git a/target-i386/cpuid.c b/target-i386/cpuid.c
index 89e9623..1e8bcff 100644
--- a/target-i386/cpuid.c
+++ b/target-i386/cpuid.c
@@ -1009,7 +1009,7 @@ static int cpudef_setfield(const char *name, const char *str, void *opaque)
  */
 static int cpudef_register(QemuOpts *opts, void *opaque)
 {
-    x86_def_t *def = qemu_mallocz(sizeof (x86_def_t));
+    x86_def_t *def = g_malloc0(sizeof (x86_def_t));
 
     qemu_opt_foreach(opts, cpudef_setfield, def, 1);
     def->next = x86_defs;
diff --git a/target-i386/helper.c b/target-i386/helper.c
index f8c8633..5df40d4 100644
--- a/target-i386/helper.c
+++ b/target-i386/helper.c
@@ -108,7 +108,7 @@ void cpu_reset(CPUX86State *env)
 
 void cpu_x86_close(CPUX86State *env)
 {
-    qemu_free(env);
+    g_free(env);
 }
 
 static void cpu_x86_version(CPUState *env, int *family, int *model)
@@ -1239,7 +1239,7 @@ CPUX86State *cpu_x86_init(const char *cpu_model)
     CPUX86State *env;
     static int inited;
 
-    env = qemu_mallocz(sizeof(CPUX86State));
+    env = g_malloc0(sizeof(CPUX86State));
     cpu_exec_init(env);
     env->cpu_model_str = cpu_model;
 
diff --git a/target-i386/kvm.c b/target-i386/kvm.c
index 31b88b7..bd850ed 100644
--- a/target-i386/kvm.c
+++ b/target-i386/kvm.c
@@ -68,7 +68,7 @@ static struct kvm_cpuid2 *try_get_cpuid(KVMState *s, int max)
     int r, size;
 
     size = sizeof(*cpuid) + max * sizeof(*cpuid->entries);
-    cpuid = (struct kvm_cpuid2 *)qemu_mallocz(size);
+    cpuid = (struct kvm_cpuid2 *)g_malloc0(size);
     cpuid->nent = max;
     r = kvm_ioctl(s, KVM_GET_SUPPORTED_CPUID, cpuid);
     if (r == 0 && cpuid->nent >= max) {
@@ -76,7 +76,7 @@ static struct kvm_cpuid2 *try_get_cpuid(KVMState *s, int max)
     }
     if (r < 0) {
         if (r == -E2BIG) {
-            qemu_free(cpuid);
+            g_free(cpuid);
             return NULL;
         } else {
             fprintf(stderr, "KVM_GET_SUPPORTED_CPUID failed: %s\n",
@@ -162,7 +162,7 @@ uint32_t kvm_arch_get_supported_cpuid(KVMState *s, uint32_t function,
         }
     }
 
-    qemu_free(cpuid);
+    g_free(cpuid);
 
     /* fallback for older kernels */
     if (!has_kvm_features && (function == KVM_CPUID_FEATURES)) {
@@ -187,7 +187,7 @@ static void kvm_unpoison_all(void *param)
     QLIST_FOREACH_SAFE(page, &hwpoison_page_list, list, next_page) {
         QLIST_REMOVE(page, list);
         qemu_ram_remap(page->ram_addr, TARGET_PAGE_SIZE);
-        qemu_free(page);
+        g_free(page);
     }
 }
 
@@ -200,7 +200,7 @@ static void kvm_hwpoison_page_add(ram_addr_t ram_addr)
             return;
         }
     }
-    page = qemu_malloc(sizeof(HWPoisonPage));
+    page = g_malloc(sizeof(HWPoisonPage));
     page->ram_addr = ram_addr;
     QLIST_INSERT_HEAD(&hwpoison_page_list, page, list);
 }
@@ -549,7 +549,7 @@ static int kvm_get_supported_msrs(KVMState *s)
         }
         /* Old kernel modules had a bug and could write beyond the provided
            memory. Allocate at least a safe amount of 1K. */
-        kvm_msr_list = qemu_mallocz(MAX(1024, sizeof(msr_list) +
+        kvm_msr_list = g_malloc0(MAX(1024, sizeof(msr_list) +
                                               msr_list.nmsrs *
                                               sizeof(msr_list.indices[0])));
 
@@ -570,7 +570,7 @@ static int kvm_get_supported_msrs(KVMState *s)
             }
         }
 
-        qemu_free(kvm_msr_list);
+        g_free(kvm_msr_list);
     }
 
     return ret;
@@ -788,7 +788,7 @@ static int kvm_put_xsave(CPUState *env)
     memcpy(&xsave->region[XSAVE_YMMH_SPACE], env->ymmh_regs,
             sizeof env->ymmh_regs);
     r = kvm_vcpu_ioctl(env, KVM_SET_XSAVE, xsave);
-    qemu_free(xsave);
+    g_free(xsave);
     return r;
 }
 
@@ -969,7 +969,7 @@ static int kvm_get_xsave(CPUState *env)
     xsave = qemu_memalign(4096, sizeof(struct kvm_xsave));
     ret = kvm_vcpu_ioctl(env, KVM_GET_XSAVE, xsave);
     if (ret < 0) {
-        qemu_free(xsave);
+        g_free(xsave);
         return ret;
     }
 
@@ -993,7 +993,7 @@ static int kvm_get_xsave(CPUState *env)
     env->xstate_bv = *(uint64_t *)&xsave->region[XSAVE_XSTATE_BV];
     memcpy(env->ymmh_regs, &xsave->region[XSAVE_YMMH_SPACE],
             sizeof env->ymmh_regs);
-    qemu_free(xsave);
+    g_free(xsave);
     return 0;
 }
 
diff --git a/target-lm32/helper.c b/target-lm32/helper.c
index 48c402e..014fd8d 100644
--- a/target-lm32/helper.c
+++ b/target-lm32/helper.c
@@ -208,7 +208,7 @@ CPUState *cpu_lm32_init(const char *cpu_model)
         return NULL;
     }
 
-    env = qemu_mallocz(sizeof(CPUState));
+    env = g_malloc0(sizeof(CPUState));
 
     env->features = def->features;
     env->num_bps = def->num_breakpoints;
diff --git a/target-m68k/helper.c b/target-m68k/helper.c
index 7ca75fb..674c8e6 100644
--- a/target-m68k/helper.c
+++ b/target-m68k/helper.c
@@ -172,7 +172,7 @@ CPUM68KState *cpu_m68k_init(const char *cpu_model)
     CPUM68KState *env;
     static int inited;
 
-    env = qemu_mallocz(sizeof(CPUM68KState));
+    env = g_malloc0(sizeof(CPUM68KState));
     cpu_exec_init(env);
     if (!inited) {
         inited = 1;
@@ -193,7 +193,7 @@ CPUM68KState *cpu_m68k_init(const char *cpu_model)
 
 void cpu_m68k_close(CPUM68KState *env)
 {
-    qemu_free(env);
+    g_free(env);
 }
 
 void cpu_m68k_flush_flags(CPUM68KState *env, int cc_op)
diff --git a/target-microblaze/translate.c b/target-microblaze/translate.c
index 41beb0a..1a862d3 100644
--- a/target-microblaze/translate.c
+++ b/target-microblaze/translate.c
@@ -1846,7 +1846,7 @@ CPUState *cpu_mb_init (const char *cpu_model)
     static int tcg_initialized = 0;
     int i;
 
-    env = qemu_mallocz(sizeof(CPUState));
+    env = g_malloc0(sizeof(CPUState));
 
     cpu_exec_init(env);
     cpu_reset(env);
diff --git a/target-mips/translate.c b/target-mips/translate.c
index 2848c6a..6c4e0d7 100644
--- a/target-mips/translate.c
+++ b/target-mips/translate.c
@@ -12618,7 +12618,7 @@ CPUMIPSState *cpu_mips_init (const char *cpu_model)
     def = cpu_mips_find_by_name(cpu_model);
     if (!def)
         return NULL;
-    env = qemu_mallocz(sizeof(CPUMIPSState));
+    env = g_malloc0(sizeof(CPUMIPSState));
     env->cpu_model = def;
     env->cpu_model_str = cpu_model;
 
diff --git a/target-mips/translate_init.c b/target-mips/translate_init.c
index d55c522..5bb4215 100644
--- a/target-mips/translate_init.c
+++ b/target-mips/translate_init.c
@@ -535,7 +535,7 @@ static void r4k_mmu_init (CPUMIPSState *env, const mips_def_t *def)
 
 static void mmu_init (CPUMIPSState *env, const mips_def_t *def)
 {
-    env->tlb = qemu_mallocz(sizeof(CPUMIPSTLBContext));
+    env->tlb = g_malloc0(sizeof(CPUMIPSTLBContext));
 
     switch (def->mmu_type) {
         case MMU_TYPE_NONE:
@@ -568,7 +568,7 @@ static void fpu_init (CPUMIPSState *env, const mips_def_t *def)
 
 static void mvp_init (CPUMIPSState *env, const mips_def_t *def)
 {
-    env->mvp = qemu_mallocz(sizeof(CPUMIPSMVPContext));
+    env->mvp = g_malloc0(sizeof(CPUMIPSMVPContext));
 
     /* MVPConf1 implemented, TLB sharable, no gating storage support,
        programmable cache partitioning implemented, number of allocatable
diff --git a/target-ppc/helper.c b/target-ppc/helper.c
index 789e6aa..3abab1a 100644
--- a/target-ppc/helper.c
+++ b/target-ppc/helper.c
@@ -3089,7 +3089,7 @@ CPUPPCState *cpu_ppc_init (const char *cpu_model)
     if (!def)
         return NULL;
 
-    env = qemu_mallocz(sizeof(CPUPPCState));
+    env = g_malloc0(sizeof(CPUPPCState));
     cpu_exec_init(env);
     if (tcg_enabled()) {
         ppc_translate_init();
@@ -3105,5 +3105,5 @@ CPUPPCState *cpu_ppc_init (const char *cpu_model)
 void cpu_ppc_close (CPUPPCState *env)
 {
     /* Should also remove all opcode tables... */
-    qemu_free(env);
+    g_free(env);
 }
diff --git a/target-ppc/kvm_ppc.c b/target-ppc/kvm_ppc.c
index 536fcab..867dc1d 100644
--- a/target-ppc/kvm_ppc.c
+++ b/target-ppc/kvm_ppc.c
@@ -32,7 +32,7 @@ int kvmppc_read_host_property(const char *node_path, const char *prop,
 
     pathlen = snprintf(NULL, 0, "%s/%s/%s", PROC_DEVTREE_PATH, node_path, prop)
               + 1;
-    path = qemu_malloc(pathlen);
+    path = g_malloc(pathlen);
 
     snprintf(path, pathlen, "%s/%s/%s", PROC_DEVTREE_PATH, node_path, prop);
 
diff --git a/target-ppc/translate_init.c b/target-ppc/translate_init.c
index f542b8e..9ea193d 100644
--- a/target-ppc/translate_init.c
+++ b/target-ppc/translate_init.c
@@ -9327,13 +9327,13 @@ static void init_ppc_proc (CPUPPCState *env, const ppc_def_t *def)
             nb_tlb *= 2;
         switch (env->tlb_type) {
         case TLB_6XX:
-            env->tlb.tlb6 = qemu_mallocz(nb_tlb * sizeof(ppc6xx_tlb_t));
+            env->tlb.tlb6 = g_malloc0(nb_tlb * sizeof(ppc6xx_tlb_t));
             break;
         case TLB_EMB:
-            env->tlb.tlbe = qemu_mallocz(nb_tlb * sizeof(ppcemb_tlb_t));
+            env->tlb.tlbe = g_malloc0(nb_tlb * sizeof(ppcemb_tlb_t));
             break;
         case TLB_MAS:
-            env->tlb.tlbm = qemu_mallocz(nb_tlb * sizeof(ppcmas_tlb_t));
+            env->tlb.tlbm = g_malloc0(nb_tlb * sizeof(ppcmas_tlb_t));
             break;
         }
         /* Pre-compute some useful values */
diff --git a/target-s390x/helper.c b/target-s390x/helper.c
index db88603..96dd867 100644
--- a/target-s390x/helper.c
+++ b/target-s390x/helper.c
@@ -79,7 +79,7 @@ CPUS390XState *cpu_s390x_init(const char *cpu_model)
     static int inited = 0;
     static int cpu_num = 0;
 
-    env = qemu_mallocz(sizeof(CPUS390XState));
+    env = g_malloc0(sizeof(CPUS390XState));
     cpu_exec_init(env);
     if (tcg_enabled() && !inited) {
         inited = 1;
diff --git a/target-sh4/translate.c b/target-sh4/translate.c
index 569bc73..bad3577 100644
--- a/target-sh4/translate.c
+++ b/target-sh4/translate.c
@@ -279,7 +279,7 @@ CPUSH4State *cpu_sh4_init(const char *cpu_model)
     def = cpu_sh4_find_by_name(cpu_model);
     if (!def)
 	return NULL;
-    env = qemu_mallocz(sizeof(CPUSH4State));
+    env = g_malloc0(sizeof(CPUSH4State));
     env->features = def->features;
     cpu_exec_init(env);
     env->movcal_backup_tail = &(env->movcal_backup);
diff --git a/target-sparc/helper.c b/target-sparc/helper.c
index 47110a5..1fe1f07 100644
--- a/target-sparc/helper.c
+++ b/target-sparc/helper.c
@@ -1091,7 +1091,7 @@ static int cpu_sparc_register(CPUSPARCState *env, const char *cpu_model)
     if (cpu_sparc_find_by_name(def, cpu_model) < 0)
         return -1;
 
-    env->def = qemu_mallocz(sizeof(*def));
+    env->def = g_malloc0(sizeof(*def));
     memcpy(env->def, def, sizeof(*def));
 #if defined(CONFIG_USER_ONLY)
     if ((env->def->features & CPU_FEATURE_FLOAT))
@@ -1124,7 +1124,7 @@ CPUSPARCState *cpu_sparc_init(const char *cpu_model)
 {
     CPUSPARCState *env;
 
-    env = qemu_mallocz(sizeof(CPUSPARCState));
+    env = g_malloc0(sizeof(CPUSPARCState));
     cpu_exec_init(env);
 
     gen_intermediate_code_init(env);
diff --git a/target-unicore32/helper.c b/target-unicore32/helper.c
index 8edfcb7..b5b1cb7 100644
--- a/target-unicore32/helper.c
+++ b/target-unicore32/helper.c
@@ -53,7 +53,7 @@ CPUState *uc32_cpu_init(const char *cpu_model)
     uint32_t id;
     static int inited = 1;
 
-    env = qemu_mallocz(sizeof(CPUState));
+    env = g_malloc0(sizeof(CPUState));
     cpu_exec_init(env);
 
     id = uc32_cpu_find_by_name(cpu_model);
diff --git a/tcg/tcg.c b/tcg/tcg.c
index 92f1989..c735348 100644
--- a/tcg/tcg.c
+++ b/tcg/tcg.c
@@ -166,7 +166,7 @@ void *tcg_malloc_internal(TCGContext *s, int size)
     
     if (size > TCG_POOL_CHUNK_SIZE) {
         /* big malloc: insert a new pool (XXX: could optimize) */
-        p = qemu_malloc(sizeof(TCGPool) + size);
+        p = g_malloc(sizeof(TCGPool) + size);
         p->size = size;
         if (s->pool_current)
             s->pool_current->next = p;
@@ -183,7 +183,7 @@ void *tcg_malloc_internal(TCGContext *s, int size)
             if (!p->next) {
             new_pool:
                 pool_size = TCG_POOL_CHUNK_SIZE;
-                p = qemu_malloc(sizeof(TCGPool) + pool_size);
+                p = g_malloc(sizeof(TCGPool) + pool_size);
                 p->size = pool_size;
                 p->next = NULL;
                 if (s->pool_current) 
@@ -227,8 +227,8 @@ void tcg_context_init(TCGContext *s)
         total_args += n;
     }
 
-    args_ct = qemu_malloc(sizeof(TCGArgConstraint) * total_args);
-    sorted_args = qemu_malloc(sizeof(int) * total_args);
+    args_ct = g_malloc(sizeof(TCGArgConstraint) * total_args);
+    sorted_args = g_malloc(sizeof(int) * total_args);
 
     for(op = 0; op < NB_OPS; op++) {
         def = &tcg_op_defs[op];
diff --git a/test-qmp-commands.c b/test-qmp-commands.c
index 7752904..f142cc6 100644
--- a/test-qmp-commands.c
+++ b/test-qmp-commands.c
@@ -15,15 +15,15 @@ void qmp_user_def_cmd1(UserDefOne * ud1, Error **errp)
 UserDefTwo * qmp_user_def_cmd2(UserDefOne * ud1a, UserDefOne * ud1b, Error **errp)
 {
     UserDefTwo *ret;
-    UserDefOne *ud1c = qemu_mallocz(sizeof(UserDefOne));
-    UserDefOne *ud1d = qemu_mallocz(sizeof(UserDefOne));
+    UserDefOne *ud1c = g_malloc0(sizeof(UserDefOne));
+    UserDefOne *ud1d = g_malloc0(sizeof(UserDefOne));
 
     ud1c->string = strdup(ud1a->string);
     ud1c->integer = ud1a->integer;
     ud1d->string = strdup(ud1b->string);
     ud1d->integer = ud1b->integer;
 
-    ret = qemu_mallocz(sizeof(UserDefTwo));
+    ret = g_malloc0(sizeof(UserDefTwo));
     ret->string = strdup("blah1");
     ret->dict.string = strdup("blah2");
     ret->dict.dict.userdef = ud1c;
diff --git a/test-visitor.c b/test-visitor.c
index 5133ad6..b7717de 100644
--- a/test-visitor.c
+++ b/test-visitor.c
@@ -191,11 +191,11 @@ static void test_nested_structs(void)
     g_assert(!g_strcmp0(ud1c_p->string, ud1_p->string));
 
     g_assert(!g_strcmp0(ud2c_p->dict.dict2.string, ud2.dict.dict2.string));
-    qemu_free(ud1.string);
-    qemu_free(ud2.string);
-    qemu_free(ud2.dict.string);
-    qemu_free(ud2.dict.dict.string);
-    qemu_free(ud2.dict.dict2.string);
+    g_free(ud1.string);
+    g_free(ud2.string);
+    g_free(ud2.dict.string);
+    g_free(ud2.dict.dict.string);
+    g_free(ud2.dict.dict2.string);
 
     qapi_free_UserDefTwo(ud2c_p);
 
@@ -251,7 +251,7 @@ static void test_nested_enums(void)
     QObject *obj;
     QString *str;
 
-    nested_enums = qemu_mallocz(sizeof(NestedEnumsOne));
+    nested_enums = g_malloc0(sizeof(NestedEnumsOne));
     nested_enums->enum1 = ENUM_ONE_VALUE1;
     nested_enums->enum2 = ENUM_ONE_VALUE2;
     nested_enums->enum3 = ENUM_ONE_VALUE3;
diff --git a/tests/qruncom.c b/tests/qruncom.c
index 079f7a2..2e93aaf 100644
--- a/tests/qruncom.c
+++ b/tests/qruncom.c
@@ -44,20 +44,20 @@ static void set_idt(int n, unsigned int dpl)
     set_gate(idt_table + n, 0, dpl, 0, 0);
 }
 
-void qemu_free(void *ptr)
+void g_free(void *ptr)
 {
     free(ptr);
 }
 
-void *qemu_malloc(size_t size)
+void *g_malloc(size_t size)
 {
     return malloc(size);
 }
 
-void *qemu_mallocz(size_t size)
+void *g_malloc0(size_t size)
 {
     void *ptr;
-    ptr = qemu_malloc(size);
+    ptr = g_malloc(size);
     if (!ptr)
         return NULL;
     memset(ptr, 0, size);
diff --git a/ui/curses.c b/ui/curses.c
index d29b6cf..c2be2c6 100644
--- a/ui/curses.c
+++ b/ui/curses.c
@@ -354,7 +354,7 @@ void curses_display_init(DisplayState *ds, int full_screen)
 #endif
 #endif
 
-    dcl = (DisplayChangeListener *) qemu_mallocz(sizeof(DisplayChangeListener));
+    dcl = (DisplayChangeListener *) g_malloc0(sizeof(DisplayChangeListener));
     dcl->dpy_update = curses_update;
     dcl->dpy_resize = curses_resize;
     dcl->dpy_refresh = curses_refresh;
diff --git a/ui/keymaps.c b/ui/keymaps.c
index 78c7ea3..81003bb 100644
--- a/ui/keymaps.c
+++ b/ui/keymaps.c
@@ -52,7 +52,7 @@ static void add_to_key_range(struct key_range **krp, int code) {
 	}
     }
     if (kr == NULL) {
-	kr = qemu_mallocz(sizeof(*kr));
+	kr = g_malloc0(sizeof(*kr));
         kr->start = kr->end = code;
         kr->next = *krp;
         *krp = kr;
@@ -94,13 +94,13 @@ static kbd_layout_t *parse_keyboard_layout(const name2keysym_t *table,
     filename = qemu_find_file(QEMU_FILE_TYPE_KEYMAP, language);
 
     if (!k)
-	k = qemu_mallocz(sizeof(kbd_layout_t));
+	k = g_malloc0(sizeof(kbd_layout_t));
     if (!(filename && (f = fopen(filename, "r")))) {
 	fprintf(stderr,
 		"Could not read keymap file: '%s'\n", language);
 	return NULL;
     }
-    qemu_free(filename);
+    g_free(filename);
     for(;;) {
 	if (fgets(line, 1024, f) == NULL)
             break;
diff --git a/ui/sdl.c b/ui/sdl.c
index 30cde86..385cc91 100644
--- a/ui/sdl.c
+++ b/ui/sdl.c
@@ -166,7 +166,7 @@ static PixelFormat sdl_to_qemu_pixelformat(SDL_PixelFormat *sdl_pf)
 
 static DisplaySurface* sdl_create_displaysurface(int width, int height)
 {
-    DisplaySurface *surface = (DisplaySurface*) qemu_mallocz(sizeof(DisplaySurface));
+    DisplaySurface *surface = (DisplaySurface*) g_malloc0(sizeof(DisplaySurface));
     if (surface == NULL) {
         fprintf(stderr, "sdl_create_displaysurface: malloc failed\n");
         exit(1);
@@ -215,8 +215,8 @@ static void sdl_free_displaysurface(DisplaySurface *surface)
         return;
 
     if (surface->flags & QEMU_ALLOCATED_FLAG)
-        qemu_free(surface->data);
-    qemu_free(surface);
+        g_free(surface->data);
+    g_free(surface);
 }
 
 static DisplaySurface* sdl_resize_displaysurface(DisplaySurface *surface, int width, int height)
@@ -928,14 +928,14 @@ static void sdl_mouse_define(QEMUCursor *c)
         SDL_FreeCursor(guest_sprite);
 
     bpl = cursor_get_mono_bpl(c);
-    image = qemu_mallocz(bpl * c->height);
-    mask  = qemu_mallocz(bpl * c->height);
+    image = g_malloc0(bpl * c->height);
+    mask  = g_malloc0(bpl * c->height);
     cursor_get_mono_image(c, 0x000000, image);
     cursor_get_mono_mask(c, 0, mask);
     guest_sprite = SDL_CreateCursor(image, mask, c->width, c->height,
                                     c->hot_x, c->hot_y);
-    qemu_free(image);
-    qemu_free(mask);
+    g_free(image);
+    g_free(mask);
 
     if (guest_cursor &&
             (gui_grab || kbd_mouse_is_absolute() || absolute_enabled))
@@ -1009,7 +1009,7 @@ void sdl_display_init(DisplayState *ds, int full_screen, int no_frame)
             SDL_SetColorKey(image, SDL_SRCCOLORKEY, colorkey);
             SDL_WM_SetIcon(image, NULL);
         }
-        qemu_free(filename);
+        g_free(filename);
     }
 
     if (full_screen) {
@@ -1017,7 +1017,7 @@ void sdl_display_init(DisplayState *ds, int full_screen, int no_frame)
         sdl_grab_start();
     }
 
-    dcl = qemu_mallocz(sizeof(DisplayChangeListener));
+    dcl = g_malloc0(sizeof(DisplayChangeListener));
     dcl->dpy_update = sdl_update;
     dcl->dpy_resize = sdl_resize;
     dcl->dpy_refresh = sdl_refresh;
@@ -1027,7 +1027,7 @@ void sdl_display_init(DisplayState *ds, int full_screen, int no_frame)
     ds->cursor_define = sdl_mouse_define;
     register_displaychangelistener(ds, dcl);
 
-    da = qemu_mallocz(sizeof(DisplayAllocator));
+    da = g_malloc0(sizeof(DisplayAllocator));
     da->create_displaysurface = sdl_create_displaysurface;
     da->resize_displaysurface = sdl_resize_displaysurface;
     da->free_displaysurface = sdl_free_displaysurface;
diff --git a/ui/spice-core.c b/ui/spice-core.c
index 8bb62ea..dba11f0 100644
--- a/ui/spice-core.c
+++ b/ui/spice-core.c
@@ -54,7 +54,7 @@ static SpiceTimer *timer_add(SpiceTimerFunc func, void *opaque)
 {
     SpiceTimer *timer;
 
-    timer = qemu_mallocz(sizeof(*timer));
+    timer = g_malloc0(sizeof(*timer));
     timer->timer = qemu_new_timer_ms(rt_clock, func, opaque);
     QTAILQ_INSERT_TAIL(&timers, timer, next);
     return timer;
@@ -75,7 +75,7 @@ static void timer_remove(SpiceTimer *timer)
     qemu_del_timer(timer->timer);
     qemu_free_timer(timer->timer);
     QTAILQ_REMOVE(&timers, timer, next);
-    qemu_free(timer);
+    g_free(timer);
 }
 
 struct SpiceWatch {
@@ -118,7 +118,7 @@ static SpiceWatch *watch_add(int fd, int event_mask, SpiceWatchFunc func, void *
 {
     SpiceWatch *watch;
 
-    watch = qemu_mallocz(sizeof(*watch));
+    watch = g_malloc0(sizeof(*watch));
     watch->fd     = fd;
     watch->func   = func;
     watch->opaque = opaque;
@@ -132,7 +132,7 @@ static void watch_remove(SpiceWatch *watch)
 {
     watch_update_mask(watch, 0);
     QTAILQ_REMOVE(&watches, watch, next);
-    qemu_free(watch);
+    g_free(watch);
 }
 
 #if SPICE_INTERFACE_CORE_MINOR >= 3
@@ -148,7 +148,7 @@ static void channel_list_add(SpiceChannelEventInfo *info)
 {
     ChannelList *item;
 
-    item = qemu_mallocz(sizeof(*item));
+    item = g_malloc0(sizeof(*item));
     item->info = info;
     QTAILQ_INSERT_TAIL(&channel_list, item, link);
 }
@@ -162,7 +162,7 @@ static void channel_list_del(SpiceChannelEventInfo *info)
             continue;
         }
         QTAILQ_REMOVE(&channel_list, item, link);
-        qemu_free(item);
+        g_free(item);
         return;
     }
 }
@@ -510,25 +510,25 @@ void qemu_spice_init(void)
 
         str = qemu_opt_get(opts, "x509-key-file");
         if (str) {
-            x509_key_file = qemu_strdup(str);
+            x509_key_file = g_strdup(str);
         } else {
-            x509_key_file = qemu_malloc(len);
+            x509_key_file = g_malloc(len);
             snprintf(x509_key_file, len, "%s/%s", x509_dir, X509_SERVER_KEY_FILE);
         }
 
         str = qemu_opt_get(opts, "x509-cert-file");
         if (str) {
-            x509_cert_file = qemu_strdup(str);
+            x509_cert_file = g_strdup(str);
         } else {
-            x509_cert_file = qemu_malloc(len);
+            x509_cert_file = g_malloc(len);
             snprintf(x509_cert_file, len, "%s/%s", x509_dir, X509_SERVER_CERT_FILE);
         }
 
         str = qemu_opt_get(opts, "x509-cacert-file");
         if (str) {
-            x509_cacert_file = qemu_strdup(str);
+            x509_cacert_file = g_strdup(str);
         } else {
-            x509_cacert_file = qemu_malloc(len);
+            x509_cacert_file = g_malloc(len);
             snprintf(x509_cacert_file, len, "%s/%s", x509_dir, X509_CA_CERT_FILE);
         }
 
@@ -631,9 +631,9 @@ void qemu_spice_init(void)
     qemu_spice_input_init();
     qemu_spice_audio_init();
 
-    qemu_free(x509_key_file);
-    qemu_free(x509_cert_file);
-    qemu_free(x509_cacert_file);
+    g_free(x509_key_file);
+    g_free(x509_cert_file);
+    g_free(x509_cacert_file);
 }
 
 int qemu_spice_add_interface(SpiceBaseInstance *sin)
diff --git a/ui/spice-display.c b/ui/spice-display.c
index 683d454..4983963 100644
--- a/ui/spice-display.c
+++ b/ui/spice-display.c
@@ -144,14 +144,14 @@ static SimpleSpiceUpdate *qemu_spice_create_update(SimpleSpiceDisplay *ssd)
            ssd->dirty.left, ssd->dirty.right,
            ssd->dirty.top, ssd->dirty.bottom);
 
-    update   = qemu_mallocz(sizeof(*update));
+    update   = g_malloc0(sizeof(*update));
     drawable = &update->drawable;
     image    = &update->image;
     cmd      = &update->ext.cmd;
 
     bw       = ssd->dirty.right - ssd->dirty.left;
     bh       = ssd->dirty.bottom - ssd->dirty.top;
-    update->bitmap = qemu_malloc(bw * bh * 4);
+    update->bitmap = g_malloc(bw * bh * 4);
 
     drawable->bbox            = ssd->dirty;
     drawable->clip.type       = SPICE_CLIP_TYPE_NONE;
@@ -208,12 +208,12 @@ static SimpleSpiceUpdate *qemu_spice_create_update(SimpleSpiceDisplay *ssd)
  * Called from spice server thread context (via interface_release_ressource)
  * We do *not* hold the global qemu mutex here, so extra care is needed
  * when calling qemu functions.  Qemu interfaces used:
- *    - qemu_free (underlying glibc free is re-entrant).
+ *    - g_free (underlying glibc free is re-entrant).
  */
 void qemu_spice_destroy_update(SimpleSpiceDisplay *sdpy, SimpleSpiceUpdate *update)
 {
-    qemu_free(update->bitmap);
-    qemu_free(update);
+    g_free(update->bitmap);
+    g_free(update);
 }
 
 void qemu_spice_create_host_memslot(SimpleSpiceDisplay *ssd)
@@ -274,7 +274,7 @@ void qemu_spice_display_init_common(SimpleSpiceDisplay *ssd, DisplayState *ds)
     ssd->mouse_x = -1;
     ssd->mouse_y = -1;
     ssd->bufsize = (16 * 1024 * 1024);
-    ssd->buf = qemu_malloc(ssd->bufsize);
+    ssd->buf = g_malloc(ssd->bufsize);
 }
 
 /* display listener callbacks */
diff --git a/ui/spice-input.c b/ui/spice-input.c
index 75abf5f..af4223d 100644
--- a/ui/spice-input.c
+++ b/ui/spice-input.c
@@ -200,12 +200,12 @@ void qemu_spice_input_init(void)
     QemuSpiceKbd *kbd;
     QemuSpicePointer *pointer;
 
-    kbd = qemu_mallocz(sizeof(*kbd));
+    kbd = g_malloc0(sizeof(*kbd));
     kbd->sin.base.sif = &kbd_interface.base;
     qemu_spice_add_interface(&kbd->sin.base);
     qemu_add_led_event_handler(kbd_leds, kbd);
 
-    pointer = qemu_mallocz(sizeof(*pointer));
+    pointer = g_malloc0(sizeof(*pointer));
     pointer->mouse.base.sif  = &mouse_interface.base;
     pointer->tablet.base.sif = &tablet_interface.base;
     qemu_spice_add_interface(&pointer->mouse.base);
diff --git a/ui/vnc-auth-sasl.c b/ui/vnc-auth-sasl.c
index 15af49b..e96095a 100644
--- a/ui/vnc-auth-sasl.c
+++ b/ui/vnc-auth-sasl.c
@@ -135,7 +135,7 @@ static int vnc_auth_sasl_check_access(VncState *vs)
     }
     VNC_DEBUG("SASL client username %s\n", (const char *)val);
 
-    vs->sasl.username = qemu_strdup((const char*)val);
+    vs->sasl.username = g_strdup((const char*)val);
 
     if (vs->vd->sasl.acl == NULL) {
         VNC_DEBUG("no ACL activated, allowing access\n");
diff --git a/ui/vnc-enc-hextile.c b/ui/vnc-enc-hextile.c
index 364a491..d2905c8 100644
--- a/ui/vnc-enc-hextile.c
+++ b/ui/vnc-enc-hextile.c
@@ -70,8 +70,8 @@ int vnc_hextile_send_framebuffer_update(VncState *vs, int x,
     uint8_t *last_fg, *last_bg;
     VncDisplay *vd = vs->vd;
 
-    last_fg = (uint8_t *) qemu_malloc(vd->server->pf.bytes_per_pixel);
-    last_bg = (uint8_t *) qemu_malloc(vd->server->pf.bytes_per_pixel);
+    last_fg = (uint8_t *) g_malloc(vd->server->pf.bytes_per_pixel);
+    last_bg = (uint8_t *) g_malloc(vd->server->pf.bytes_per_pixel);
     has_fg = has_bg = 0;
     for (j = y; j < (y + h); j += 16) {
         for (i = x; i < (x + w); i += 16) {
diff --git a/ui/vnc-enc-tight.c b/ui/vnc-enc-tight.c
index 5c02803..5d492ab 100644
--- a/ui/vnc-enc-tight.c
+++ b/ui/vnc-enc-tight.c
@@ -1293,13 +1293,13 @@ static int send_jpeg_rect(VncState *vs, int x, int y, int w, int h, int quality)
 
     jpeg_start_compress(&cinfo, true);
 
-    buf = qemu_malloc(w * 3);
+    buf = g_malloc(w * 3);
     row[0] = buf;
     for (dy = 0; dy < h; dy++) {
         rgb_prepare_row(vs, buf, x, y + dy, w);
         jpeg_write_scanlines(&cinfo, row, 1);
     }
-    qemu_free(buf);
+    g_free(buf);
 
     jpeg_finish_compress(&cinfo);
     jpeg_destroy_compress(&cinfo);
@@ -1363,12 +1363,12 @@ static void png_flush_data(png_structp png_ptr)
 
 static void *vnc_png_malloc(png_structp png_ptr, png_size_t size)
 {
-    return qemu_malloc(size);
+    return g_malloc(size);
 }
 
 static void vnc_png_free(png_structp png_ptr, png_voidp ptr)
 {
-    qemu_free(ptr);
+    g_free(ptr);
 }
 
 static int send_png_rect(VncState *vs, int x, int y, int w, int h,
@@ -1432,7 +1432,7 @@ static int send_png_rect(VncState *vs, int x, int y, int w, int h,
     png_write_info(png_ptr, info_ptr);
 
     buffer_reserve(&vs->tight.png, 2048);
-    buf = qemu_malloc(w * 3);
+    buf = g_malloc(w * 3);
     for (dy = 0; dy < h; dy++)
     {
         if (color_type == PNG_COLOR_TYPE_PALETTE) {
@@ -1442,7 +1442,7 @@ static int send_png_rect(VncState *vs, int x, int y, int w, int h,
         }
         png_write_row(png_ptr, buf);
     }
-    qemu_free(buf);
+    g_free(buf);
 
     png_write_end(png_ptr, NULL);
 
diff --git a/ui/vnc-enc-zlib.c b/ui/vnc-enc-zlib.c
index e32e4cd..d1b97f2 100644
--- a/ui/vnc-enc-zlib.c
+++ b/ui/vnc-enc-zlib.c
@@ -35,14 +35,14 @@ void *vnc_zlib_zalloc(void *x, unsigned items, unsigned size)
     size *= items;
     size = (size + ZALLOC_ALIGNMENT - 1) & ~(ZALLOC_ALIGNMENT - 1);
 
-    p = qemu_mallocz(size);
+    p = g_malloc0(size);
 
     return (p);
 }
 
 void vnc_zlib_zfree(void *x, void *addr)
 {
-    qemu_free(addr);
+    g_free(addr);
 }
 
 static void vnc_zlib_start(VncState *vs)
diff --git a/ui/vnc-jobs-async.c b/ui/vnc-jobs-async.c
index 1dfa6c3..de5ea6b 100644
--- a/ui/vnc-jobs-async.c
+++ b/ui/vnc-jobs-async.c
@@ -77,7 +77,7 @@ static void vnc_unlock_queue(VncJobQueue *queue)
 
 VncJob *vnc_job_new(VncState *vs)
 {
-    VncJob *job = qemu_mallocz(sizeof(VncJob));
+    VncJob *job = g_malloc0(sizeof(VncJob));
 
     job->vs = vs;
     vnc_lock_queue(queue);
@@ -88,7 +88,7 @@ VncJob *vnc_job_new(VncState *vs)
 
 int vnc_job_add_rect(VncJob *job, int x, int y, int w, int h)
 {
-    VncRectEntry *entry = qemu_mallocz(sizeof(VncRectEntry));
+    VncRectEntry *entry = g_malloc0(sizeof(VncRectEntry));
 
     entry->rect.x = x;
     entry->rect.y = y;
@@ -105,7 +105,7 @@ void vnc_job_push(VncJob *job)
 {
     vnc_lock_queue(queue);
     if (queue->exit || QLIST_EMPTY(&job->rectangles)) {
-        qemu_free(job);
+        g_free(job);
     } else {
         QTAILQ_INSERT_TAIL(&queue->jobs, job, next);
         qemu_cond_broadcast(&queue->cond);
@@ -246,7 +246,7 @@ static int vnc_worker_thread_loop(VncJobQueue *queue)
         if (n >= 0) {
             n_rectangles += n;
         }
-        qemu_free(entry);
+        g_free(entry);
     }
     vnc_unlock_display(job->vs->vd);
 
@@ -276,13 +276,13 @@ disconnected:
     QTAILQ_REMOVE(&queue->jobs, job, next);
     vnc_unlock_queue(queue);
     qemu_cond_broadcast(&queue->cond);
-    qemu_free(job);
+    g_free(job);
     return 0;
 }
 
 static VncJobQueue *vnc_queue_init(void)
 {
-    VncJobQueue *queue = qemu_mallocz(sizeof(VncJobQueue));
+    VncJobQueue *queue = g_malloc0(sizeof(VncJobQueue));
 
     qemu_cond_init(&queue->cond);
     qemu_mutex_init(&queue->mutex);
@@ -295,7 +295,7 @@ static void vnc_queue_clear(VncJobQueue *q)
     qemu_cond_destroy(&queue->cond);
     qemu_mutex_destroy(&queue->mutex);
     buffer_free(&queue->buffer);
-    qemu_free(q);
+    g_free(q);
     queue = NULL; /* Unset global queue */
 }
 
diff --git a/ui/vnc-palette.c b/ui/vnc-palette.c
index 13ece42..63d5f64 100644
--- a/ui/vnc-palette.c
+++ b/ui/vnc-palette.c
@@ -55,7 +55,7 @@ VncPalette *palette_new(size_t max, int bpp)
 {
     VncPalette *palette;
 
-    palette = qemu_mallocz(sizeof(*palette));
+    palette = g_malloc0(sizeof(*palette));
     palette_init(palette, max, bpp);
     return palette;
 }
@@ -69,7 +69,7 @@ void palette_init(VncPalette *palette, size_t max, int bpp)
 
 void palette_destroy(VncPalette *palette)
 {
-    qemu_free(palette);
+    g_free(palette);
 }
 
 int palette_put(VncPalette *palette, uint32_t color)
diff --git a/ui/vnc-tls.c b/ui/vnc-tls.c
index 31f1467..2e2456e 100644
--- a/ui/vnc-tls.c
+++ b/ui/vnc-tls.c
@@ -244,11 +244,11 @@ int vnc_tls_validate_certificate(struct VncState *vs)
 
         if (i == 0) {
             size_t dnameSize = 1024;
-            vs->tls.dname = qemu_malloc(dnameSize);
+            vs->tls.dname = g_malloc(dnameSize);
         requery:
             if ((ret = gnutls_x509_crt_get_dn (cert, vs->tls.dname, &dnameSize)) != 0) {
                 if (ret == GNUTLS_E_SHORT_MEMORY_BUFFER) {
-                    vs->tls.dname = qemu_realloc(vs->tls.dname, dnameSize);
+                    vs->tls.dname = g_realloc(vs->tls.dname, dnameSize);
                     goto requery;
                 }
                 gnutls_x509_crt_deinit (cert);
@@ -397,11 +397,11 @@ static int vnc_set_x509_credential(VncDisplay *vd,
     struct stat sb;
 
     if (*cred) {
-        qemu_free(*cred);
+        g_free(*cred);
         *cred = NULL;
     }
 
-    *cred = qemu_malloc(strlen(certdir) + strlen(filename) + 2);
+    *cred = g_malloc(strlen(certdir) + strlen(filename) + 2);
 
     strcpy(*cred, certdir);
     strcat(*cred, "/");
@@ -409,7 +409,7 @@ static int vnc_set_x509_credential(VncDisplay *vd,
 
     VNC_DEBUG("Check %s\n", *cred);
     if (stat(*cred, &sb) < 0) {
-        qemu_free(*cred);
+        g_free(*cred);
         *cred = NULL;
         if (ignoreMissing && errno == ENOENT)
             return 0;
@@ -435,10 +435,10 @@ int vnc_tls_set_x509_creds_dir(VncDisplay *vd,
     return 0;
 
  cleanup:
-    qemu_free(vd->tls.x509cacert);
-    qemu_free(vd->tls.x509cacrl);
-    qemu_free(vd->tls.x509cert);
-    qemu_free(vd->tls.x509key);
+    g_free(vd->tls.x509cacert);
+    g_free(vd->tls.x509cacrl);
+    g_free(vd->tls.x509cert);
+    g_free(vd->tls.x509key);
     vd->tls.x509cacert = vd->tls.x509cacrl = vd->tls.x509cert = vd->tls.x509key = NULL;
     return -1;
 }
diff --git a/ui/vnc.c b/ui/vnc.c
index f1e27d9..fc3a612 100644
--- a/ui/vnc.c
+++ b/ui/vnc.c
@@ -67,7 +67,7 @@ static char *addr_to_string(const char *format,
     /* Enough for the existing format + the 2 vars we're
      * substituting in. */
     addrlen = strlen(format) + strlen(host) + strlen(serv);
-    addr = qemu_malloc(addrlen + 1);
+    addr = g_malloc(addrlen + 1);
     snprintf(addr, addrlen, format, host, serv);
     addr[addrlen] = '\0';
 
@@ -411,7 +411,7 @@ void buffer_reserve(Buffer *buffer, size_t len)
 {
     if ((buffer->capacity - buffer->offset) < len) {
         buffer->capacity += (len + 1024);
-        buffer->buffer = qemu_realloc(buffer->buffer, buffer->capacity);
+        buffer->buffer = g_realloc(buffer->buffer, buffer->capacity);
         if (buffer->buffer == NULL) {
             fprintf(stderr, "vnc: out of memory\n");
             exit(1);
@@ -436,7 +436,7 @@ void buffer_reset(Buffer *buffer)
 
 void buffer_free(Buffer *buffer)
 {
-    qemu_free(buffer->buffer);
+    g_free(buffer->buffer);
     buffer->offset = 0;
     buffer->capacity = 0;
     buffer->buffer = NULL;
@@ -505,16 +505,16 @@ static void vnc_dpy_resize(DisplayState *ds)
 
     /* server surface */
     if (!vd->server)
-        vd->server = qemu_mallocz(sizeof(*vd->server));
+        vd->server = g_malloc0(sizeof(*vd->server));
     if (vd->server->data)
-        qemu_free(vd->server->data);
+        g_free(vd->server->data);
     *(vd->server) = *(ds->surface);
-    vd->server->data = qemu_mallocz(vd->server->linesize *
+    vd->server->data = g_malloc0(vd->server->linesize *
                                     vd->server->height);
 
     /* guest surface */
     if (!vd->guest.ds)
-        vd->guest.ds = qemu_mallocz(sizeof(*vd->guest.ds));
+        vd->guest.ds = g_malloc0(sizeof(*vd->guest.ds));
     if (ds_get_bytes_per_pixel(ds) != vd->guest.ds->pf.bytes_per_pixel)
         console_color_init(ds);
     *(vd->guest.ds) = *(ds->surface);
@@ -781,12 +781,12 @@ static void vnc_dpy_cursor_define(QEMUCursor *c)
     VncState *vs;
 
     cursor_put(vd->cursor);
-    qemu_free(vd->cursor_mask);
+    g_free(vd->cursor_mask);
 
     vd->cursor = c;
     cursor_get(vd->cursor);
     vd->cursor_msize = cursor_get_mono_bpl(c) * c->height;
-    vd->cursor_mask = qemu_mallocz(vd->cursor_msize);
+    vd->cursor_mask = g_malloc0(vd->cursor_msize);
     cursor_get_mono_mask(c, 0, vd->cursor_mask);
 
     QTAILQ_FOREACH(vs, &vd->clients, next) {
@@ -1013,10 +1013,10 @@ static void vnc_disconnect_finish(VncState *vs)
     qemu_mutex_destroy(&vs->output_mutex);
 #endif
     for (i = 0; i < VNC_STAT_ROWS; ++i) {
-        qemu_free(vs->lossy_rect[i]);
+        g_free(vs->lossy_rect[i]);
     }
-    qemu_free(vs->lossy_rect);
-    qemu_free(vs);
+    g_free(vs->lossy_rect);
+    g_free(vs);
 }
 
 int vnc_client_io_error(VncState *vs, int ret, int last_errno)
@@ -2496,7 +2496,7 @@ static void vnc_remove_timer(VncDisplay *vd)
 
 static void vnc_connect(VncDisplay *vd, int csock, int skipauth)
 {
-    VncState *vs = qemu_mallocz(sizeof(VncState));
+    VncState *vs = g_malloc0(sizeof(VncState));
     int i;
 
     vs->csock = csock;
@@ -2513,9 +2513,9 @@ static void vnc_connect(VncDisplay *vd, int csock, int skipauth)
 #endif
     }
 
-    vs->lossy_rect = qemu_mallocz(VNC_STAT_ROWS * sizeof (*vs->lossy_rect));
+    vs->lossy_rect = g_malloc0(VNC_STAT_ROWS * sizeof (*vs->lossy_rect));
     for (i = 0; i < VNC_STAT_ROWS; ++i) {
-        vs->lossy_rect[i] = qemu_mallocz(VNC_STAT_COLS * sizeof (uint8_t));
+        vs->lossy_rect[i] = g_malloc0(VNC_STAT_COLS * sizeof (uint8_t));
     }
 
     VNC_DEBUG("New client on socket %d\n", csock);
@@ -2576,9 +2576,9 @@ static void vnc_listen_read(void *opaque)
 
 void vnc_display_init(DisplayState *ds)
 {
-    VncDisplay *vs = qemu_mallocz(sizeof(*vs));
+    VncDisplay *vs = g_malloc0(sizeof(*vs));
 
-    dcl = qemu_mallocz(sizeof(DisplayChangeListener));
+    dcl = g_malloc0(sizeof(DisplayChangeListener));
 
     ds->opaque = vs;
     dcl->idle = 1;
@@ -2620,7 +2620,7 @@ void vnc_display_close(DisplayState *ds)
     if (!vs)
         return;
     if (vs->display) {
-        qemu_free(vs->display);
+        g_free(vs->display);
         vs->display = NULL;
     }
     if (vs->lsock != -1) {
@@ -2644,7 +2644,7 @@ int vnc_display_disable_login(DisplayState *ds)
     }
 
     if (vs->password) {
-        qemu_free(vs->password);
+        g_free(vs->password);
     }
 
     vs->password = NULL;
@@ -2671,10 +2671,10 @@ int vnc_display_password(DisplayState *ds, const char *password)
     }
 
     if (vs->password) {
-        qemu_free(vs->password);
+        g_free(vs->password);
         vs->password = NULL;
     }
-    vs->password = qemu_strdup(password);
+    vs->password = g_strdup(password);
     vs->auth = VNC_AUTH_VNC;
 out:
     if (ret != 0) {
@@ -2753,20 +2753,20 @@ int vnc_display_open(DisplayState *ds, const char *display)
             end = strchr(options, ',');
             if (start && (!end || (start < end))) {
                 int len = end ? end-(start+1) : strlen(start+1);
-                char *path = qemu_strndup(start + 1, len);
+                char *path = g_strndup(start + 1, len);
 
                 VNC_DEBUG("Trying certificate path '%s'\n", path);
                 if (vnc_tls_set_x509_creds_dir(vs, path) < 0) {
                     fprintf(stderr, "Failed to find x509 certificates/keys in %s\n", path);
-                    qemu_free(path);
-                    qemu_free(vs->display);
+                    g_free(path);
+                    g_free(vs->display);
                     vs->display = NULL;
                     return -1;
                 }
-                qemu_free(path);
+                g_free(path);
             } else {
                 fprintf(stderr, "No certificate path provided\n");
-                qemu_free(vs->display);
+                g_free(vs->display);
                 vs->display = NULL;
                 return -1;
             }
@@ -2907,7 +2907,7 @@ int vnc_display_open(DisplayState *ds, const char *display)
     } else {
         /* listen for connects */
         char *dpy;
-        dpy = qemu_malloc(256);
+        dpy = g_malloc(256);
         if (strncmp(display, "unix:", 5) == 0) {
             pstrcpy(dpy, 256, "unix:");
             vs->lsock = unix_listen(display+5, dpy+5, 256-5);
diff --git a/usb-bsd.c b/usb-bsd.c
index ab84d93..1187552 100644
--- a/usb-bsd.c
+++ b/usb-bsd.c
@@ -290,7 +290,7 @@ static void usb_host_handle_destroy(USBDevice *opaque)
 
     close(s->devfd);
 
-    qemu_free(s);
+    g_free(s);
 }
 
 static int usb_host_initfn(USBDevice *dev)
diff --git a/usb-linux.c b/usb-linux.c
index 5562187..2e20f8e 100644
--- a/usb-linux.c
+++ b/usb-linux.c
@@ -271,7 +271,7 @@ struct AsyncURB
 
 static AsyncURB *async_alloc(USBHostDevice *s)
 {
-    AsyncURB *aurb = qemu_mallocz(sizeof(AsyncURB));
+    AsyncURB *aurb = g_malloc0(sizeof(AsyncURB));
     aurb->hdev = s;
     QLIST_INSERT_HEAD(&s->aurbs, aurb, next);
     return aurb;
@@ -280,7 +280,7 @@ static AsyncURB *async_alloc(USBHostDevice *s)
 static void async_free(AsyncURB *aurb)
 {
     QLIST_REMOVE(aurb, next);
-    qemu_free(aurb);
+    g_free(aurb);
 }
 
 static void do_disconnect(USBHostDevice *s)
@@ -528,11 +528,11 @@ static AsyncURB *usb_host_alloc_iso(USBHostDevice *s, uint8_t ep, int in)
     AsyncURB *aurb;
     int i, j, len = get_max_packet_size(s, ep);
 
-    aurb = qemu_mallocz(s->iso_urb_count * sizeof(*aurb));
+    aurb = g_malloc0(s->iso_urb_count * sizeof(*aurb));
     for (i = 0; i < s->iso_urb_count; i++) {
         aurb[i].urb.endpoint      = ep;
         aurb[i].urb.buffer_length = ISO_FRAME_DESC_PER_URB * len;
-        aurb[i].urb.buffer        = qemu_malloc(aurb[i].urb.buffer_length);
+        aurb[i].urb.buffer        = g_malloc(aurb[i].urb.buffer_length);
         aurb[i].urb.type          = USBDEVFS_URB_TYPE_ISO;
         aurb[i].urb.flags         = USBDEVFS_URB_ISO_ASAP;
         aurb[i].urb.number_of_packets = ISO_FRAME_DESC_PER_URB;
@@ -578,11 +578,11 @@ static void usb_host_stop_n_free_iso(USBHostDevice *s, uint8_t ep)
     }
 
     for (i = 0; i < s->iso_urb_count; i++) {
-        qemu_free(aurb[i].urb.buffer);
+        g_free(aurb[i].urb.buffer);
     }
 
     if (free)
-        qemu_free(aurb);
+        g_free(aurb);
     else
         printf("husb: leaking iso urbs because of discard failure\n");
     set_iso_urb(s, ep, NULL);
@@ -1688,7 +1688,7 @@ static int usb_host_scan(void *opaque, USBScanFunc *func)
         }
 
         /* the module setting (used later for opening devices) */
-        usb_host_device_path = qemu_mallocz(strlen(devpath)+1);
+        usb_host_device_path = g_malloc0(strlen(devpath)+1);
         strcpy(usb_host_device_path, devpath);
         if (mon) {
             monitor_printf(mon, "husb: using %s file-system with %s\n",
diff --git a/usb-redir.c b/usb-redir.c
index 9e5fce2..3fbbcff 100644
--- a/usb-redir.c
+++ b/usb-redir.c
@@ -234,7 +234,7 @@ static int usbredir_write(void *priv, uint8_t *data, int count)
 
 static AsyncURB *async_alloc(USBRedirDevice *dev, USBPacket *p)
 {
-    AsyncURB *aurb = (AsyncURB *) qemu_mallocz(sizeof(AsyncURB));
+    AsyncURB *aurb = (AsyncURB *) g_malloc0(sizeof(AsyncURB));
     aurb->dev = dev;
     aurb->packet = p;
     aurb->packet_id = dev->packet_id;
@@ -247,7 +247,7 @@ static AsyncURB *async_alloc(USBRedirDevice *dev, USBPacket *p)
 static void async_free(USBRedirDevice *dev, AsyncURB *aurb)
 {
     QTAILQ_REMOVE(&dev->asyncq, aurb, next);
-    qemu_free(aurb);
+    g_free(aurb);
 }
 
 static AsyncURB *async_find(USBRedirDevice *dev, uint32_t packet_id)
@@ -286,7 +286,7 @@ static void usbredir_cancel_packet(USBDevice *udev, USBPacket *p)
 static struct buf_packet *bufp_alloc(USBRedirDevice *dev,
     uint8_t *data, int len, int status, uint8_t ep)
 {
-    struct buf_packet *bufp = qemu_malloc(sizeof(struct buf_packet));
+    struct buf_packet *bufp = g_malloc(sizeof(struct buf_packet));
     bufp->data   = data;
     bufp->len    = len;
     bufp->status = status;
@@ -299,7 +299,7 @@ static void bufp_free(USBRedirDevice *dev, struct buf_packet *bufp,
 {
     QTAILQ_REMOVE(&dev->endpoint[EP2I(ep)].bufpq, bufp, next);
     free(bufp->data);
-    qemu_free(bufp);
+    g_free(bufp);
 }
 
 static void usbredir_free_bufpq(USBRedirDevice *dev, uint8_t ep)
diff --git a/vl.c b/vl.c
index d1971df..8405429 100644
--- a/vl.c
+++ b/vl.c
@@ -300,7 +300,7 @@ static struct {
 static void res_free(void)
 {
     if (boot_splash_filedata != NULL) {
-        qemu_free(boot_splash_filedata);
+        g_free(boot_splash_filedata);
         boot_splash_filedata = NULL;
     }
 }
@@ -466,7 +466,7 @@ static struct bt_scatternet_s *qemu_find_bt_vlan(int id)
         if (vlan->id == id)
             return &vlan->net;
     }
-    vlan = qemu_mallocz(sizeof(struct bt_vlan_s));
+    vlan = g_malloc0(sizeof(struct bt_vlan_s));
     vlan->id = id;
     pvlan = &first_bt_vlan;
     while (*pvlan != NULL)
@@ -741,7 +741,7 @@ static void restore_boot_devices(void *opaque)
     qemu_boot_set(standard_boot_devices);
 
     qemu_unregister_reset(restore_boot_devices, standard_boot_devices);
-    qemu_free(standard_boot_devices);
+    g_free(standard_boot_devices);
 }
 
 void add_boot_device_path(int32_t bootindex, DeviceState *dev,
@@ -755,9 +755,9 @@ void add_boot_device_path(int32_t bootindex, DeviceState *dev,
 
     assert(dev != NULL || suffix != NULL);
 
-    node = qemu_mallocz(sizeof(FWBootEntry));
+    node = g_malloc0(sizeof(FWBootEntry));
     node->bootindex = bootindex;
-    node->suffix = suffix ? qemu_strdup(suffix) : NULL;
+    node->suffix = suffix ? g_strdup(suffix) : NULL;
     node->dev = dev;
 
     QTAILQ_FOREACH(i, &fw_boot_order, link) {
@@ -798,13 +798,13 @@ char *get_boot_devices_list(uint32_t *size)
         if (i->suffix && devpath) {
             size_t bootpathlen = strlen(devpath) + strlen(i->suffix) + 1;
 
-            bootpath = qemu_malloc(bootpathlen);
+            bootpath = g_malloc(bootpathlen);
             snprintf(bootpath, bootpathlen, "%s%s", devpath, i->suffix);
-            qemu_free(devpath);
+            g_free(devpath);
         } else if (devpath) {
             bootpath = devpath;
         } else {
-            bootpath = qemu_strdup(i->suffix);
+            bootpath = g_strdup(i->suffix);
             assert(bootpath);
         }
 
@@ -812,10 +812,10 @@ char *get_boot_devices_list(uint32_t *size)
             list[total-1] = '\n';
         }
         len = strlen(bootpath) + 1;
-        list = qemu_realloc(list, total + len);
+        list = g_realloc(list, total + len);
         memcpy(&list[total], bootpath, len);
         total += len;
-        qemu_free(bootpath);
+        g_free(bootpath);
     }
 
     *size = total;
@@ -1014,7 +1014,7 @@ void pcmcia_socket_register(PCMCIASocket *socket)
 {
     struct pcmcia_socket_entry_s *entry;
 
-    entry = qemu_malloc(sizeof(struct pcmcia_socket_entry_s));
+    entry = g_malloc(sizeof(struct pcmcia_socket_entry_s));
     entry->socket = socket;
     entry->next = pcmcia_sockets;
     pcmcia_sockets = entry;
@@ -1028,7 +1028,7 @@ void pcmcia_socket_unregister(PCMCIASocket *socket)
     for (entry = *ptr; entry; ptr = &entry->next, entry = *ptr)
         if (entry->socket == socket) {
             *ptr = entry->next;
-            qemu_free(entry);
+            g_free(entry);
         }
 }
 
@@ -1129,7 +1129,7 @@ VMChangeStateEntry *qemu_add_vm_change_state_handler(VMChangeStateHandler *cb,
 {
     VMChangeStateEntry *e;
 
-    e = qemu_mallocz(sizeof (*e));
+    e = g_malloc0(sizeof (*e));
 
     e->cb = cb;
     e->opaque = opaque;
@@ -1140,7 +1140,7 @@ VMChangeStateEntry *qemu_add_vm_change_state_handler(VMChangeStateHandler *cb,
 void qemu_del_vm_change_state_handler(VMChangeStateEntry *e)
 {
     QLIST_REMOVE (e, entries);
-    qemu_free (e);
+    g_free (e);
 }
 
 void vm_state_notify(int running, int reason)
@@ -1245,7 +1245,7 @@ static int qemu_vmstop_requested(void)
 
 void qemu_register_reset(QEMUResetHandler *func, void *opaque)
 {
-    QEMUResetEntry *re = qemu_mallocz(sizeof(QEMUResetEntry));
+    QEMUResetEntry *re = g_malloc0(sizeof(QEMUResetEntry));
 
     re->func = func;
     re->opaque = opaque;
@@ -1259,7 +1259,7 @@ void qemu_unregister_reset(QEMUResetHandler *func, void *opaque)
     QTAILQ_FOREACH(re, &reset_handlers, entry) {
         if (re->func == func && re->opaque == opaque) {
             QTAILQ_REMOVE(&reset_handlers, re, entry);
-            qemu_free(re);
+            g_free(re);
             return;
         }
     }
@@ -1648,7 +1648,7 @@ char *qemu_find_file(int type, const char *name)
     /* If name contains path separators then try it as a straight path.  */
     if ((strchr(name, '/') || strchr(name, '\\'))
         && access(name, R_OK) == 0) {
-        return qemu_strdup(name);
+        return g_strdup(name);
     }
     switch (type) {
     case QEMU_FILE_TYPE_BIOS:
@@ -1661,10 +1661,10 @@ char *qemu_find_file(int type, const char *name)
         abort();
     }
     len = strlen(data_dir) + strlen(name) + strlen(subdir) + 2;
-    buf = qemu_mallocz(len);
+    buf = g_malloc0(len);
     snprintf(buf, len, "%s/%s%s", data_dir, subdir, name);
     if (access(buf, R_OK)) {
-        qemu_free(buf);
+        g_free(buf);
         return NULL;
     }
     return buf;
@@ -1795,7 +1795,7 @@ static void add_device_config(int type, const char *cmdline)
 {
     struct device_config *conf;
 
-    conf = qemu_mallocz(sizeof(*conf));
+    conf = g_malloc0(sizeof(*conf));
     conf->type = type;
     conf->cmdline = cmdline;
     QTAILQ_INSERT_TAIL(&device_configs, conf, next);
@@ -2367,7 +2367,7 @@ int main(int argc, char **argv, char **envp)
                         if (get_param_value(buf, sizeof(buf),
                                             "once", optarg)) {
                             validate_bootdevices(buf);
-                            standard_boot_devices = qemu_strdup(boot_devices);
+                            standard_boot_devices = g_strdup(boot_devices);
                             pstrcpy(boot_devices, sizeof(boot_devices), buf);
                             qemu_register_reset(restore_boot_devices,
                                                 standard_boot_devices);
@@ -2808,7 +2808,7 @@ int main(int argc, char **argv, char **envp)
                 semihosting_enabled = 1;
                 break;
             case QEMU_OPTION_name:
-                qemu_name = qemu_strdup(optarg);
+                qemu_name = g_strdup(optarg);
 		 {
 		     char *p = strchr(qemu_name, ',');
 		     if (p != NULL) {
diff --git a/xen-all.c b/xen-all.c
index 9eaeac1..84420d8 100644
--- a/xen-all.c
+++ b/xen-all.c
@@ -140,7 +140,7 @@ static void xen_ram_init(ram_addr_t ram_size)
     RAMBlock *new_block;
     ram_addr_t below_4g_mem_size, above_4g_mem_size = 0;
 
-    new_block = qemu_mallocz(sizeof (*new_block));
+    new_block = g_malloc0(sizeof (*new_block));
     pstrcpy(new_block->idstr, sizeof (new_block->idstr), "xen.ram");
     new_block->host = NULL;
     new_block->offset = 0;
@@ -154,7 +154,7 @@ static void xen_ram_init(ram_addr_t ram_size)
 
     QLIST_INSERT_HEAD(&ram_list.blocks, new_block, next);
 
-    ram_list.phys_dirty = qemu_realloc(ram_list.phys_dirty,
+    ram_list.phys_dirty = g_realloc(ram_list.phys_dirty,
                                        new_block->length >> TARGET_PAGE_BITS);
     memset(ram_list.phys_dirty + (new_block->offset >> TARGET_PAGE_BITS),
            0xff, new_block->length >> TARGET_PAGE_BITS);
@@ -190,7 +190,7 @@ void xen_ram_alloc(ram_addr_t ram_addr, ram_addr_t size)
     trace_xen_ram_alloc(ram_addr, size);
 
     nr_pfn = size >> TARGET_PAGE_BITS;
-    pfn_list = qemu_malloc(sizeof (*pfn_list) * nr_pfn);
+    pfn_list = g_malloc(sizeof (*pfn_list) * nr_pfn);
 
     for (i = 0; i < nr_pfn; i++) {
         pfn_list[i] = (ram_addr >> TARGET_PAGE_BITS) + i;
@@ -200,7 +200,7 @@ void xen_ram_alloc(ram_addr_t ram_addr, ram_addr_t size)
         hw_error("xen: failed to populate ram at " RAM_ADDR_FMT, ram_addr);
     }
 
-    qemu_free(pfn_list);
+    g_free(pfn_list);
 }
 
 static XenPhysmap *get_physmapping(XenIOState *state,
@@ -267,7 +267,7 @@ go_physmap:
         }
     }
 
-    physmap = qemu_malloc(sizeof (XenPhysmap));
+    physmap = g_malloc(sizeof (XenPhysmap));
 
     physmap->start_addr = start_addr;
     physmap->size = size;
@@ -888,7 +888,7 @@ int xen_hvm_init(void)
     unsigned long ioreq_pfn;
     XenIOState *state;
 
-    state = qemu_mallocz(sizeof (XenIOState));
+    state = g_malloc0(sizeof (XenIOState));
 
     state->xce_handle = xen_xc_evtchn_open(NULL, 0);
     if (state->xce_handle == XC_HANDLER_INITIAL_VALUE) {
@@ -922,7 +922,7 @@ int xen_hvm_init(void)
         hw_error("map buffered IO page returned error %d", errno);
     }
 
-    state->ioreq_local_port = qemu_mallocz(smp_cpus * sizeof (evtchn_port_t));
+    state->ioreq_local_port = g_malloc0(smp_cpus * sizeof (evtchn_port_t));
 
     /* FIXME: how about if we overflow the page here? */
     for (i = 0; i < smp_cpus; i++) {
diff --git a/xen-mapcache.c b/xen-mapcache.c
index 15d1241..5b247ee 100644
--- a/xen-mapcache.c
+++ b/xen-mapcache.c
@@ -87,7 +87,7 @@ void xen_map_cache_init(void)
     unsigned long size;
     struct rlimit rlimit_as;
 
-    mapcache = qemu_mallocz(sizeof (MapCache));
+    mapcache = g_malloc0(sizeof (MapCache));
 
     QTAILQ_INIT(&mapcache->locked_entries);
     mapcache->last_address_index = -1;
@@ -111,7 +111,7 @@ void xen_map_cache_init(void)
     size = (size + XC_PAGE_SIZE - 1) & ~(XC_PAGE_SIZE - 1);
     DPRINTF("%s, nr_buckets = %lx size %lu\n", __func__,
             mapcache->nr_buckets, size);
-    mapcache->entry = qemu_mallocz(size);
+    mapcache->entry = g_malloc0(size);
 }
 
 static void xen_remap_bucket(MapCacheEntry *entry,
@@ -126,8 +126,8 @@ static void xen_remap_bucket(MapCacheEntry *entry,
 
     trace_xen_remap_bucket(address_index);
 
-    pfns = qemu_mallocz(nb_pfn * sizeof (xen_pfn_t));
-    err = qemu_mallocz(nb_pfn * sizeof (int));
+    pfns = g_malloc0(nb_pfn * sizeof (xen_pfn_t));
+    err = g_malloc0(nb_pfn * sizeof (int));
 
     if (entry->vaddr_base != NULL) {
         if (munmap(entry->vaddr_base, entry->size) != 0) {
@@ -136,7 +136,7 @@ static void xen_remap_bucket(MapCacheEntry *entry,
         }
     }
     if (entry->valid_mapping != NULL) {
-        qemu_free(entry->valid_mapping);
+        g_free(entry->valid_mapping);
         entry->valid_mapping = NULL;
     }
 
@@ -154,7 +154,7 @@ static void xen_remap_bucket(MapCacheEntry *entry,
     entry->vaddr_base = vaddr_base;
     entry->paddr_index = address_index;
     entry->size = size;
-    entry->valid_mapping = (unsigned long *) qemu_mallocz(sizeof(unsigned long) *
+    entry->valid_mapping = (unsigned long *) g_malloc0(sizeof(unsigned long) *
             BITS_TO_LONGS(size >> XC_PAGE_SHIFT));
 
     bitmap_zero(entry->valid_mapping, nb_pfn);
@@ -164,8 +164,8 @@ static void xen_remap_bucket(MapCacheEntry *entry,
         }
     }
 
-    qemu_free(pfns);
-    qemu_free(err);
+    g_free(pfns);
+    g_free(err);
 }
 
 uint8_t *xen_map_cache(target_phys_addr_t phys_addr, target_phys_addr_t size,
@@ -201,7 +201,7 @@ uint8_t *xen_map_cache(target_phys_addr_t phys_addr, target_phys_addr_t size,
         entry = entry->next;
     }
     if (!entry) {
-        entry = qemu_mallocz(sizeof (MapCacheEntry));
+        entry = g_malloc0(sizeof (MapCacheEntry));
         pentry->next = entry;
         xen_remap_bucket(entry, __size, address_index);
     } else if (!entry->lock) {
@@ -223,7 +223,7 @@ uint8_t *xen_map_cache(target_phys_addr_t phys_addr, target_phys_addr_t size,
     mapcache->last_address_index = address_index;
     mapcache->last_address_vaddr = entry->vaddr_base;
     if (lock) {
-        MapCacheRev *reventry = qemu_mallocz(sizeof(MapCacheRev));
+        MapCacheRev *reventry = g_malloc0(sizeof(MapCacheRev));
         entry->lock++;
         reventry->vaddr_req = mapcache->last_address_vaddr + address_offset;
         reventry->paddr_index = mapcache->last_address_index;
@@ -301,7 +301,7 @@ void xen_invalidate_map_cache_entry(uint8_t *buffer)
         return;
     }
     QTAILQ_REMOVE(&mapcache->locked_entries, reventry, next);
-    qemu_free(reventry);
+    g_free(reventry);
 
     entry = &mapcache->entry[paddr_index % mapcache->nr_buckets];
     while (entry && (entry->paddr_index != paddr_index || entry->size != size)) {
@@ -322,8 +322,8 @@ void xen_invalidate_map_cache_entry(uint8_t *buffer)
         perror("unmap fails");
         exit(-1);
     }
-    qemu_free(entry->valid_mapping);
-    qemu_free(entry);
+    g_free(entry->valid_mapping);
+    g_free(entry);
 }
 
 void xen_invalidate_map_cache(void)
@@ -357,7 +357,7 @@ void xen_invalidate_map_cache(void)
         entry->paddr_index = 0;
         entry->vaddr_base = NULL;
         entry->size = 0;
-        qemu_free(entry->valid_mapping);
+        g_free(entry->valid_mapping);
         entry->valid_mapping = NULL;
     }
 
commit 14015304b662e8f8ccce46c5a6927af6a14c510b
Author: Anthony Liguori <aliguori at us.ibm.com>
Date:   Sat Aug 20 22:18:37 2011 -0500

    Make glib mandatory and fixup utils appropriately
    
    Signed-off-by: Anthony Liguori <aliguori at us.ibm.com>

diff --git a/Makefile.objs b/Makefile.objs
index 16eef38..77950d5 100644
--- a/Makefile.objs
+++ b/Makefile.objs
@@ -400,4 +400,5 @@ vl.o: QEMU_CFLAGS+=$(GPROF_CFLAGS)
 
 vl.o: QEMU_CFLAGS+=$(SDL_CFLAGS)
 
-vl.o: QEMU_CFLAGS+=$(GLIB_CFLAGS)
+QEMU_CFLAGS+=$(GLIB_CFLAGS)
+
diff --git a/configure b/configure
index 6873e13..79ddcad 100755
--- a/configure
+++ b/configure
@@ -1848,8 +1848,7 @@ fi
 if $pkg_config --modversion 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`
-    libs_softmmu="$glib_libs $libs_softmmu"
-    libs_tools="$glib_libs $libs_tools"
+    LIBS="$glib_libs $LIBS"
 else
     echo "glib-2.0 required to compile QEMU"
     exit 1
diff --git a/libcacard/Makefile b/libcacard/Makefile
index 5cd7594..f72781e 100644
--- a/libcacard/Makefile
+++ b/libcacard/Makefile
@@ -15,10 +15,12 @@ QEMU_OBJS_LIB=$(addsuffix .lo,$(basename $(QEMU_OBJS)))
 
 QEMU_CFLAGS+=-I../
 
+QEMU_CFLAGS+=$(GLIB_CFLAGS)
+
 libcacard.lib-y=$(addsuffix .lo,$(basename $(libcacard-y)))
 
 vscclient: $(libcacard-y) $(QEMU_OBJS) vscclient.o
-	$(call quiet-command,$(CC) $(libcacard_libs) -lrt -o $@ $^,"  LINK  $@")
+	$(call quiet-command,$(CC) $(libcacard_libs) $(LIBS) -lrt -o $@ $^,"  LINK  $@")
 
 clean:
 	rm -f *.o */*.o *.d */*.d *.a */*.a *~ */*~ vscclient *.lo .libs/* *.la *.pc
diff --git a/qemu-common.h b/qemu-common.h
index 74d5c4b..c1d4126 100644
--- a/qemu-common.h
+++ b/qemu-common.h
@@ -37,6 +37,7 @@ typedef struct Monitor Monitor;
 #include <sys/time.h>
 #include <assert.h>
 #include <signal.h>
+#include <glib.h>
 
 #ifdef _WIN32
 #include "qemu-os-win32.h"
commit 0ac543de94f4f5e7e79d59a56df60937cdd3cd24
Author: Jan Kiszka <jan.kiszka at web.de>
Date:   Mon Aug 15 16:18:57 2011 -0700

    Reorder default ram_size initialization
    
    code_gen_alloc depends on it, and that is now called earlier via
    configure_accelerator.
    
    Signed-off-by: Jan Kiszka <jan.kiszka at siemens.com>
    Signed-off-by: Edgar E. Iglesias <edgar.iglesias at gmail.com>

diff --git a/vl.c b/vl.c
index c714127..d1971df 100644
--- a/vl.c
+++ b/vl.c
@@ -3077,6 +3077,11 @@ int main(int argc, char **argv, char **envp)
         exit(1);
     }
 
+    /* init the memory */
+    if (ram_size == 0) {
+        ram_size = DEFAULT_RAM_SIZE * 1024 * 1024;
+    }
+
     configure_accelerator();
 
     if (qemu_init_main_loop()) {
@@ -3111,11 +3116,6 @@ int main(int argc, char **argv, char **envp)
     if (foreach_device_config(DEV_BT, bt_parse))
         exit(1);
 
-    /* init the memory */
-    if (ram_size == 0) {
-        ram_size = DEFAULT_RAM_SIZE * 1024 * 1024;
-    }
-
     if (!xen_enabled()) {
         /* On 32-bit hosts, QEMU is limited by virtual address space */
         if (ram_size > (2047 << 20) && HOST_LONG_BITS == 32) {
commit 02fa69b6e8de1742c60ce3a050ed397102122e6b
Author: Blue Swirl <blauwirbel at gmail.com>
Date:   Sat Aug 20 09:21:42 2011 +0000

    scsi-disk: fix DPRINTF
    
    The variable 'status' does not exist anymore, adjust DPRINTF
    accordingly.
    
    Signed-off-by: Blue Swirl <blauwirbel at gmail.com>

diff --git a/hw/scsi-disk.c b/hw/scsi-disk.c
index f848318..f1ffe95 100644
--- a/hw/scsi-disk.c
+++ b/hw/scsi-disk.c
@@ -86,8 +86,8 @@ static void scsi_free_request(SCSIRequest *req)
 /* Helper function for command completion with sense.  */
 static void scsi_check_condition(SCSIDiskReq *r, SCSISense sense)
 {
-    DPRINTF("Command complete tag=0x%x status=%d sense=%d/%d/%d\n",
-            r->req.tag, status, sense.key, sense.asc, sense.ascq);
+    DPRINTF("Command complete tag=0x%x sense=%d/%d/%d\n",
+            r->req.tag, sense.key, sense.asc, sense.ascq);
     scsi_req_build_sense(&r->req, sense);
     scsi_req_complete(&r->req, CHECK_CONDITION);
 }
commit 871708bf39fd19e56680af61d5db665986bae036
Author: Peter Maydell <peter.maydell at linaro.org>
Date:   Sat Aug 20 00:27:04 2011 +0100

    target-cris/opcode-cris.h: rename REG_PC/SP to CRIS_REG_PC/SP
    
    The REG_PC constant used in opcode-cris.h can clash with a
    similar define in system include files. In particular the
    Ubuntu Lucid SPARC signal.h will define REG_PC, and since
    qemu-common.h now includes signal.h this was causing compile
    failures. Rename the constants to avoid this issue.
    (NB that REG_SP is not actually used within QEMU.)
    
    Signed-off-by: Peter Maydell <peter.maydell at linaro.org>
    Signed-off-by: Edgar E. Iglesias <edgar.iglesias at gmail.com>

diff --git a/target-cris/opcode-cris.h b/target-cris/opcode-cris.h
index 8d4749d..779d4aa 100644
--- a/target-cris/opcode-cris.h
+++ b/target-cris/opcode-cris.h
@@ -29,8 +29,8 @@ along with this program; if not, see <http://www.gnu.org/licenses/>.  */
 
 /* Registers.  */
 #define MAX_REG (15)
-#define REG_SP (14)
-#define REG_PC (15)
+#define CRIS_REG_SP (14)
+#define CRIS_REG_PC (15)
 
 /* CPU version control of disassembly and assembly of instructions.
    May affect how the instruction is assembled, at least the size of
@@ -138,7 +138,7 @@ extern const struct cris_cond15 cris_conds15[];
 
 #define BDAP_INDIR_OPCODE (BDAP_INDIR_HIGH * 0x0100 + BDAP_INDIR_LOW)
 #define BDAP_INDIR_Z_BITS (BDAP_INDIR_HIGH_Z * 0x100 + BDAP_INDIR_LOW_Z)
-#define BDAP_PC_LOW	  (BDAP_INDIR_LOW + REG_PC)
+#define BDAP_PC_LOW	  (BDAP_INDIR_LOW + CRIS_REG_PC)
 #define BDAP_INCR_HIGH	  (BDAP_INDIR_HIGH + AUTOINCR_BIT)
 
 /* No prefix must have this code for its "match" bits in the
@@ -192,16 +192,16 @@ extern const char *const cris_cc_strings[];
 #define JUMP_INDIR_OPCODE (0x0930)
 #define JUMP_INDIR_Z_BITS (0xf2c0)
 #define JUMP_PC_INCR_OPCODE \
- (JUMP_INDIR_OPCODE + AUTOINCR_BIT * 0x0100 + REG_PC)
+ (JUMP_INDIR_OPCODE + AUTOINCR_BIT * 0x0100 + CRIS_REG_PC)
 
 #define MOVE_M_TO_PREG_OPCODE 0x0a30
 #define MOVE_M_TO_PREG_ZBITS 0x01c0
 
 /* BDAP.D N,PC.  */
 #define MOVE_PC_INCR_OPCODE_PREFIX \
- (((BDAP_INCR_HIGH | (REG_PC << 4)) << 8) | BDAP_PC_LOW | (2 << 4))
+ (((BDAP_INCR_HIGH | (CRIS_REG_PC << 4)) << 8) | BDAP_PC_LOW | (2 << 4))
 #define MOVE_PC_INCR_OPCODE_SUFFIX \
- (MOVE_M_TO_PREG_OPCODE | REG_PC | (AUTOINCR_BIT << 8))
+ (MOVE_M_TO_PREG_OPCODE | CRIS_REG_PC | (AUTOINCR_BIT << 8))
 
 #define JUMP_PC_INCR_OPCODE_V32 (0x0DBF)
 
commit dc804ab77630f5f3d28a9fb7487966d29f505829
Author: Engin AYDOGAN <engin at bzzzt.biz>
Date:   Wed Aug 3 22:15:23 2011 +0100

    hw/stellaris: Add support for RCC2 register
    
    Add support for the RCC2 register on Fury class devices.
    Based on a patch by Vijay Kumar.
    
    Signed-off-by: Engin AYDOGAN <engin at bzzzt.biz>
    [Peter Maydell: fixed comment typos, minor cleanup of unreachable code]
    Signed-off-by: Peter Maydell <peter.maydell at linaro.org>

diff --git a/hw/stellaris.c b/hw/stellaris.c
index a280930..70db99f 100644
--- a/hw/stellaris.c
+++ b/hw/stellaris.c
@@ -332,6 +332,7 @@ typedef struct {
     uint32_t int_mask;
     uint32_t resc;
     uint32_t rcc;
+    uint32_t rcc2;
     uint32_t rcgc[3];
     uint32_t scgc[3];
     uint32_t dcgc[3];
@@ -386,6 +387,32 @@ static uint32_t pllcfg_fury[16] = {
     0xb11c /* 8.192 Mhz */
 };
 
+#define DID0_VER_MASK        0x70000000
+#define DID0_VER_0           0x00000000
+#define DID0_VER_1           0x10000000
+
+#define DID0_CLASS_MASK      0x00FF0000
+#define DID0_CLASS_SANDSTORM 0x00000000
+#define DID0_CLASS_FURY      0x00010000
+
+static int ssys_board_class(const ssys_state *s)
+{
+    uint32_t did0 = s->board->did0;
+    switch (did0 & DID0_VER_MASK) {
+    case DID0_VER_0:
+        return DID0_CLASS_SANDSTORM;
+    case DID0_VER_1:
+        switch (did0 & DID0_CLASS_MASK) {
+        case DID0_CLASS_SANDSTORM:
+        case DID0_CLASS_FURY:
+            return did0 & DID0_CLASS_MASK;
+        }
+        /* for unknown classes, fall through */
+    default:
+        hw_error("ssys_board_class: Unknown class 0x%08x\n", did0);
+    }
+}
+
 static uint32_t ssys_read(void *opaque, target_phys_addr_t offset)
 {
     ssys_state *s = (ssys_state *)opaque;
@@ -429,12 +456,18 @@ static uint32_t ssys_read(void *opaque, target_phys_addr_t offset)
         {
             int xtal;
             xtal = (s->rcc >> 6) & 0xf;
-            if (s->board->did0 & (1 << 16)) {
+            switch (ssys_board_class(s)) {
+            case DID0_CLASS_FURY:
                 return pllcfg_fury[xtal];
-            } else {
+            case DID0_CLASS_SANDSTORM:
                 return pllcfg_sandstorm[xtal];
+            default:
+                hw_error("ssys_read: Unhandled class for PLLCFG read.\n");
+                return 0;
             }
         }
+    case 0x070: /* RCC2 */
+        return s->rcc2;
     case 0x100: /* RCGC0 */
         return s->rcgc[0];
     case 0x104: /* RCGC1 */
@@ -467,9 +500,21 @@ static uint32_t ssys_read(void *opaque, target_phys_addr_t offset)
     }
 }
 
+static bool ssys_use_rcc2(ssys_state *s)
+{
+    return (s->rcc2 >> 31) & 0x1;
+}
+
+/*
+ * Caculate the sys. clock period in ms.
+ */
 static void ssys_calculate_system_clock(ssys_state *s)
 {
-    system_clock_scale = 5 * (((s->rcc >> 23) & 0xf) + 1);
+    if (ssys_use_rcc2(s)) {
+        system_clock_scale = 5 * (((s->rcc2 >> 23) & 0x3f) + 1);
+    } else {
+        system_clock_scale = 5 * (((s->rcc >> 23) & 0xf) + 1);
+    }
 }
 
 static void ssys_write(void *opaque, target_phys_addr_t offset, uint32_t value)
@@ -505,6 +550,18 @@ static void ssys_write(void *opaque, target_phys_addr_t offset, uint32_t value)
         s->rcc = value;
         ssys_calculate_system_clock(s);
         break;
+    case 0x070: /* RCC2 */
+        if (ssys_board_class(s) == DID0_CLASS_SANDSTORM) {
+            break;
+        }
+
+        if ((s->rcc2 & (1 << 13)) != 0 && (value & (1 << 13)) == 0) {
+            /* PLL enable.  */
+            s->int_status |= (1 << 6);
+        }
+        s->rcc2 = value;
+        ssys_calculate_system_clock(s);
+        break;
     case 0x100: /* RCGC0 */
         s->rcgc[0] = value;
         break;
@@ -562,6 +619,12 @@ static void ssys_reset(void *opaque)
 
     s->pborctl = 0x7ffd;
     s->rcc = 0x078e3ac0;
+
+    if (ssys_board_class(s) == DID0_CLASS_SANDSTORM) {
+        s->rcc2 = 0;
+    } else {
+        s->rcc2 = 0x07802810;
+    }
     s->rcgc[0] = 1;
     s->scgc[0] = 1;
     s->dcgc[0] = 1;
@@ -578,7 +641,7 @@ static int stellaris_sys_post_load(void *opaque, int version_id)
 
 static const VMStateDescription vmstate_stellaris_sys = {
     .name = "stellaris_sys",
-    .version_id = 1,
+    .version_id = 2,
     .minimum_version_id = 1,
     .minimum_version_id_old = 1,
     .post_load = stellaris_sys_post_load,
@@ -589,6 +652,7 @@ static const VMStateDescription vmstate_stellaris_sys = {
         VMSTATE_UINT32(int_status, ssys_state),
         VMSTATE_UINT32(resc, ssys_state),
         VMSTATE_UINT32(rcc, ssys_state),
+        VMSTATE_UINT32_V(rcc2, ssys_state, 2),
         VMSTATE_UINT32_ARRAY(rcgc, ssys_state, 3),
         VMSTATE_UINT32_ARRAY(scgc, ssys_state, 3),
         VMSTATE_UINT32_ARRAY(dcgc, ssys_state, 3),
commit b3aaff11ec0a4c9c9c7f089b74406d926accfd17
Author: Peter Maydell <peter.maydell at linaro.org>
Date:   Wed Aug 3 23:04:49 2011 +0100

    hw/pl061.c: Support GPIOAMSEL register
    
    Support the GPIOAMSEL register found on some Stellaris boards.
    
    Signed-off-by: Peter Maydell <peter.maydell at linaro.org>

diff --git a/hw/pl061.c b/hw/pl061.c
index 27de824..d13746c 100644
--- a/hw/pl061.c
+++ b/hw/pl061.c
@@ -50,6 +50,7 @@ typedef struct {
     uint32_t den;
     uint32_t cr;
     uint32_t float_high;
+    uint32_t amsel;
     qemu_irq irq;
     qemu_irq out[8];
     const unsigned char *id;
@@ -57,7 +58,7 @@ typedef struct {
 
 static const VMStateDescription vmstate_pl061 = {
     .name = "pl061",
-    .version_id = 1,
+    .version_id = 2,
     .minimum_version_id = 1,
     .fields = (VMStateField[]) {
         VMSTATE_UINT32(locked, pl061_state),
@@ -80,6 +81,7 @@ static const VMStateDescription vmstate_pl061 = {
         VMSTATE_UINT32(den, pl061_state),
         VMSTATE_UINT32(cr, pl061_state),
         VMSTATE_UINT32(float_high, pl061_state),
+        VMSTATE_UINT32_V(amsel, pl061_state, 2),
         VMSTATE_END_OF_LIST()
     }
 };
@@ -157,6 +159,8 @@ static uint32_t pl061_read(void *opaque, target_phys_addr_t offset)
         return s->locked;
     case 0x524: /* Commit */
         return s->cr;
+    case 0x528: /* Analog mode select */
+        return s->amsel;
     default:
         hw_error("pl061_read: Bad offset %x\n", (int)offset);
         return 0;
@@ -229,6 +233,9 @@ static void pl061_write(void *opaque, target_phys_addr_t offset,
         if (!s->locked)
             s->cr = value & 0xff;
         break;
+    case 0x528:
+        s->amsel = value & 0xff;
+        break;
     default:
         hw_error("pl061_write: Bad offset %x\n", (int)offset);
     }
commit a35faa94c8e8d851a1d07e17c98f4ab2202b8a38
Author: Peter Maydell <peter.maydell at linaro.org>
Date:   Wed Aug 3 23:13:45 2011 +0100

    hw/pl061: Convert to VMState
    
    Convert the PL061 to VMState. We choose to widen the struct members
    to uint32_t rather than the other two options of breaking migration
    compatibility or using vmstate hacks to read/write a 32 bit value
    into an 8 bit struct field.
    
    Signed-off-by: Peter Maydell <peter.maydell at linaro.org>

diff --git a/hw/pl061.c b/hw/pl061.c
index 79e5c53..27de824 100644
--- a/hw/pl061.c
+++ b/hw/pl061.c
@@ -30,31 +30,60 @@ static const uint8_t pl061_id_luminary[12] =
 
 typedef struct {
     SysBusDevice busdev;
-    int locked;
-    uint8_t data;
-    uint8_t old_data;
-    uint8_t dir;
-    uint8_t isense;
-    uint8_t ibe;
-    uint8_t iev;
-    uint8_t im;
-    uint8_t istate;
-    uint8_t afsel;
-    uint8_t dr2r;
-    uint8_t dr4r;
-    uint8_t dr8r;
-    uint8_t odr;
-    uint8_t pur;
-    uint8_t pdr;
-    uint8_t slr;
-    uint8_t den;
-    uint8_t cr;
-    uint8_t float_high;
+    uint32_t locked;
+    uint32_t data;
+    uint32_t old_data;
+    uint32_t dir;
+    uint32_t isense;
+    uint32_t ibe;
+    uint32_t iev;
+    uint32_t im;
+    uint32_t istate;
+    uint32_t afsel;
+    uint32_t dr2r;
+    uint32_t dr4r;
+    uint32_t dr8r;
+    uint32_t odr;
+    uint32_t pur;
+    uint32_t pdr;
+    uint32_t slr;
+    uint32_t den;
+    uint32_t cr;
+    uint32_t float_high;
     qemu_irq irq;
     qemu_irq out[8];
     const unsigned char *id;
 } pl061_state;
 
+static const VMStateDescription vmstate_pl061 = {
+    .name = "pl061",
+    .version_id = 1,
+    .minimum_version_id = 1,
+    .fields = (VMStateField[]) {
+        VMSTATE_UINT32(locked, pl061_state),
+        VMSTATE_UINT32(data, pl061_state),
+        VMSTATE_UINT32(old_data, pl061_state),
+        VMSTATE_UINT32(dir, pl061_state),
+        VMSTATE_UINT32(isense, pl061_state),
+        VMSTATE_UINT32(ibe, pl061_state),
+        VMSTATE_UINT32(iev, pl061_state),
+        VMSTATE_UINT32(im, pl061_state),
+        VMSTATE_UINT32(istate, pl061_state),
+        VMSTATE_UINT32(afsel, pl061_state),
+        VMSTATE_UINT32(dr2r, pl061_state),
+        VMSTATE_UINT32(dr4r, pl061_state),
+        VMSTATE_UINT32(dr8r, pl061_state),
+        VMSTATE_UINT32(odr, pl061_state),
+        VMSTATE_UINT32(pur, pl061_state),
+        VMSTATE_UINT32(pdr, pl061_state),
+        VMSTATE_UINT32(slr, pl061_state),
+        VMSTATE_UINT32(den, pl061_state),
+        VMSTATE_UINT32(cr, pl061_state),
+        VMSTATE_UINT32(float_high, pl061_state),
+        VMSTATE_END_OF_LIST()
+    }
+};
+
 static void pl061_update(pl061_state *s)
 {
     uint8_t changed;
@@ -148,19 +177,19 @@ static void pl061_write(void *opaque, target_phys_addr_t offset,
     }
     switch (offset) {
     case 0x400: /* Direction */
-        s->dir = value;
+        s->dir = value & 0xff;
         break;
     case 0x404: /* Interrupt sense */
-        s->isense = value;
+        s->isense = value & 0xff;
         break;
     case 0x408: /* Interrupt both edges */
-        s->ibe = value;
+        s->ibe = value & 0xff;
         break;
     case 0x40c: /* Interrupt event */
-        s->iev = value;
+        s->iev = value & 0xff;
         break;
     case 0x410: /* Interrupt mask */
-        s->im = value;
+        s->im = value & 0xff;
         break;
     case 0x41c: /* Interrupt clear */
         s->istate &= ~value;
@@ -170,35 +199,35 @@ static void pl061_write(void *opaque, target_phys_addr_t offset,
         s->afsel = (s->afsel & ~mask) | (value & mask);
         break;
     case 0x500: /* 2mA drive */
-        s->dr2r = value;
+        s->dr2r = value & 0xff;
         break;
     case 0x504: /* 4mA drive */
-        s->dr4r = value;
+        s->dr4r = value & 0xff;
         break;
     case 0x508: /* 8mA drive */
-        s->dr8r = value;
+        s->dr8r = value & 0xff;
         break;
     case 0x50c: /* Open drain */
-        s->odr = value;
+        s->odr = value & 0xff;
         break;
     case 0x510: /* Pull-up */
-        s->pur = value;
+        s->pur = value & 0xff;
         break;
     case 0x514: /* Pull-down */
-        s->pdr = value;
+        s->pdr = value & 0xff;
         break;
     case 0x518: /* Slew rate control */
-        s->slr = value;
+        s->slr = value & 0xff;
         break;
     case 0x51c: /* Digital enable */
-        s->den = value;
+        s->den = value & 0xff;
         break;
     case 0x520: /* Lock */
         s->locked = (value != 0xacce551);
         break;
     case 0x524: /* Commit */
         if (!s->locked)
-            s->cr = value;
+            s->cr = value & 0xff;
         break;
     default:
         hw_error("pl061_write: Bad offset %x\n", (int)offset);
@@ -238,62 +267,6 @@ static CPUWriteMemoryFunc * const pl061_writefn[] = {
    pl061_write
 };
 
-static void pl061_save(QEMUFile *f, void *opaque)
-{
-    pl061_state *s = (pl061_state *)opaque;
-
-    qemu_put_be32(f, s->locked);
-    qemu_put_be32(f, s->data);
-    qemu_put_be32(f, s->old_data);
-    qemu_put_be32(f, s->dir);
-    qemu_put_be32(f, s->isense);
-    qemu_put_be32(f, s->ibe);
-    qemu_put_be32(f, s->iev);
-    qemu_put_be32(f, s->im);
-    qemu_put_be32(f, s->istate);
-    qemu_put_be32(f, s->afsel);
-    qemu_put_be32(f, s->dr2r);
-    qemu_put_be32(f, s->dr4r);
-    qemu_put_be32(f, s->dr8r);
-    qemu_put_be32(f, s->odr);
-    qemu_put_be32(f, s->pur);
-    qemu_put_be32(f, s->pdr);
-    qemu_put_be32(f, s->slr);
-    qemu_put_be32(f, s->den);
-    qemu_put_be32(f, s->cr);
-    qemu_put_be32(f, s->float_high);
-}
-
-static int pl061_load(QEMUFile *f, void *opaque, int version_id)
-{
-    pl061_state *s = (pl061_state *)opaque;
-    if (version_id != 1)
-        return -EINVAL;
-
-    s->locked = qemu_get_be32(f);
-    s->data = qemu_get_be32(f);
-    s->old_data = qemu_get_be32(f);
-    s->dir = qemu_get_be32(f);
-    s->isense = qemu_get_be32(f);
-    s->ibe = qemu_get_be32(f);
-    s->iev = qemu_get_be32(f);
-    s->im = qemu_get_be32(f);
-    s->istate = qemu_get_be32(f);
-    s->afsel = qemu_get_be32(f);
-    s->dr2r = qemu_get_be32(f);
-    s->dr4r = qemu_get_be32(f);
-    s->dr8r = qemu_get_be32(f);
-    s->odr = qemu_get_be32(f);
-    s->pur = qemu_get_be32(f);
-    s->pdr = qemu_get_be32(f);
-    s->slr = qemu_get_be32(f);
-    s->den = qemu_get_be32(f);
-    s->cr = qemu_get_be32(f);
-    s->float_high = qemu_get_be32(f);
-
-    return 0;
-}
-
 static int pl061_init(SysBusDevice *dev, const unsigned char *id)
 {
     int iomemtype;
@@ -307,7 +280,6 @@ static int pl061_init(SysBusDevice *dev, const unsigned char *id)
     qdev_init_gpio_in(&dev->qdev, pl061_set_irq, 8);
     qdev_init_gpio_out(&dev->qdev, s->out, 8);
     pl061_reset(s);
-    register_savevm(&dev->qdev, "pl061_gpio", -1, 1, pl061_save, pl061_load, s);
     return 0;
 }
 
@@ -321,12 +293,24 @@ static int pl061_init_arm(SysBusDevice *dev)
     return pl061_init(dev, pl061_id);
 }
 
+static SysBusDeviceInfo pl061_info = {
+    .init = pl061_init_arm,
+    .qdev.name = "pl061",
+    .qdev.size = sizeof(pl061_state),
+    .qdev.vmsd = &vmstate_pl061,
+};
+
+static SysBusDeviceInfo pl061_luminary_info = {
+    .init = pl061_init_luminary,
+    .qdev.name = "pl061_luminary",
+    .qdev.size = sizeof(pl061_state),
+    .qdev.vmsd = &vmstate_pl061,
+};
+
 static void pl061_register_devices(void)
 {
-    sysbus_register_dev("pl061", sizeof(pl061_state),
-                        pl061_init_arm);
-    sysbus_register_dev("pl061_luminary", sizeof(pl061_state),
-                        pl061_init_luminary);
+    sysbus_register_withprop(&pl061_info);
+    sysbus_register_withprop(&pl061_luminary_info);
 }
 
 device_init(pl061_register_devices)
commit acb9b72240543307e061db5986532db402807e3c
Author: Peter Maydell <peter.maydell at linaro.org>
Date:   Fri Jul 22 15:36:54 2011 +0000

    vexpress, realview: Use pl111, not pl110
    
    The Versatile Express, Realview EB, PBX A9 and PB A8 boards all
    use a PL111 for their graphics, not a PL110. Now we model the
    PL111, use it on these board models.
    
    Signed-off-by: Peter Maydell <peter.maydell at linaro.org>

diff --git a/hw/realview.c b/hw/realview.c
index 94ab900..549bb15 100644
--- a/hw/realview.c
+++ b/hw/realview.c
@@ -251,7 +251,7 @@ static void realview_init(ram_addr_t ram_size,
     sysbus_create_simple("pl061", 0x10014000, pic[7]);
     gpio2 = sysbus_create_simple("pl061", 0x10015000, pic[8]);
 
-    sysbus_create_simple("pl110_versatile", 0x10020000, pic[23]);
+    sysbus_create_simple("pl111", 0x10020000, pic[23]);
 
     dev = sysbus_create_varargs("pl181", 0x10005000, pic[17], pic[18], NULL);
     /* Wire up MMC card detect and read-only signals. These have
diff --git a/hw/vexpress.c b/hw/vexpress.c
index 9ffd332..c9766dd 100644
--- a/hw/vexpress.c
+++ b/hw/vexpress.c
@@ -150,7 +150,7 @@ static void vexpress_a9_init(ram_addr_t ram_size,
     /* Daughterboard peripherals : 0x10020000 .. 0x20000000 */
 
     /* 0x10020000 PL111 CLCD (daughterboard) */
-    sysbus_create_simple("pl110", 0x10020000, pic[44]);
+    sysbus_create_simple("pl111", 0x10020000, pic[44]);
 
     /* 0x10060000 AXI RAM */
     /* 0x100e0000 PL341 Dynamic Memory Controller */
commit 242ea2c6bc96473d37894b258a28a2162208228c
Author: Peter Maydell <peter.maydell at linaro.org>
Date:   Fri Jul 22 13:42:39 2011 +0000

    versatilepb: Implement SYS_CLCD mux control register bits
    
    On the Versatile PB, PL110 graphics adaptor only natively supports
    5551 pixel format; an external mux swaps bits around to allow
    RGB565 and BGR565, under the control of bits [1:0] in the SYS_CLCD
    system register.
    
    Implement these SYS_CLCD register bits, and use a gpio line to
    feed them out of the system register model, across the versatilepb
    board and into the pl110 so we can select the right format.
    
    This is necessary as recent Linux versatile kernels default to
    programming the CLCD and mux for 16 bit BGR rather than 16 bit RGB.
    
    Signed-off-by: Peter Maydell <peter.maydell at linaro.org>

diff --git a/hw/arm_sysctl.c b/hw/arm_sysctl.c
index fd0c8bc..22c62df 100644
--- a/hw/arm_sysctl.c
+++ b/hw/arm_sysctl.c
@@ -17,6 +17,8 @@
 
 typedef struct {
     SysBusDevice busdev;
+    qemu_irq pl110_mux_ctrl;
+
     uint32_t sys_id;
     uint32_t leds;
     uint16_t lockval;
@@ -30,11 +32,12 @@ typedef struct {
     uint32_t sys_cfgdata;
     uint32_t sys_cfgctrl;
     uint32_t sys_cfgstat;
+    uint32_t sys_clcd;
 } arm_sysctl_state;
 
 static const VMStateDescription vmstate_arm_sysctl = {
     .name = "realview_sysctl",
-    .version_id = 2,
+    .version_id = 3,
     .minimum_version_id = 1,
     .fields = (VMStateField[]) {
         VMSTATE_UINT32(leds, arm_sysctl_state),
@@ -48,6 +51,7 @@ static const VMStateDescription vmstate_arm_sysctl = {
         VMSTATE_UINT32_V(sys_cfgdata, arm_sysctl_state, 2),
         VMSTATE_UINT32_V(sys_cfgctrl, arm_sysctl_state, 2),
         VMSTATE_UINT32_V(sys_cfgstat, arm_sysctl_state, 2),
+        VMSTATE_UINT32_V(sys_clcd, arm_sysctl_state, 3),
         VMSTATE_END_OF_LIST()
     }
 };
@@ -78,6 +82,13 @@ static void arm_sysctl_reset(DeviceState *d)
     s->cfgdata2 = 0;
     s->flags = 0;
     s->resetlevel = 0;
+    if (board_id(s) == BOARD_ID_VEXPRESS) {
+        /* On VExpress this register will RAZ/WI */
+        s->sys_clcd = 0;
+    } else {
+        /* All others: CLCDID 0x1f, indicating VGA */
+        s->sys_clcd = 0x1f00;
+    }
 }
 
 static uint32_t arm_sysctl_read(void *opaque, target_phys_addr_t offset)
@@ -124,7 +135,7 @@ static uint32_t arm_sysctl_read(void *opaque, target_phys_addr_t offset)
     case 0x4c: /* FLASH */
         return 0;
     case 0x50: /* CLCD */
-        return 0x1000;
+        return s->sys_clcd;
     case 0x54: /* CLCDSER */
         return 0;
     case 0x58: /* BOOTCS */
@@ -232,7 +243,39 @@ static void arm_sysctl_write(void *opaque, target_phys_addr_t offset,
         /* nothing to do.  */
         break;
     case 0x4c: /* FLASH */
+        break;
     case 0x50: /* CLCD */
+        switch (board_id(s)) {
+        case BOARD_ID_PB926:
+            /* On 926 bits 13:8 are R/O, bits 1:0 control
+             * the mux that defines how to interpret the PL110
+             * graphics format, and other bits are r/w but we
+             * don't implement them to do anything.
+             */
+            s->sys_clcd &= 0x3f00;
+            s->sys_clcd |= val & ~0x3f00;
+            qemu_set_irq(s->pl110_mux_ctrl, val & 3);
+            break;
+        case BOARD_ID_EB:
+            /* The EB is the same except that there is no mux since
+             * the EB has a PL111.
+             */
+            s->sys_clcd &= 0x3f00;
+            s->sys_clcd |= val & ~0x3f00;
+            break;
+        case BOARD_ID_PBA8:
+        case BOARD_ID_PBX:
+            /* On PBA8 and PBX bit 7 is r/w and all other bits
+             * are either r/o or RAZ/WI.
+             */
+            s->sys_clcd &= (1 << 7);
+            s->sys_clcd |= val & ~(1 << 7);
+            break;
+        case BOARD_ID_VEXPRESS:
+        default:
+            /* On VExpress this register is unimplemented and will RAZ/WI */
+            break;
+        }
     case 0x54: /* CLCDSER */
     case 0x64: /* DMAPSR0 */
     case 0x68: /* DMAPSR1 */
@@ -334,7 +377,7 @@ static int arm_sysctl_init1(SysBusDevice *dev)
                                        DEVICE_NATIVE_ENDIAN);
     sysbus_init_mmio(dev, 0x1000, iomemtype);
     qdev_init_gpio_in(&s->busdev.qdev, arm_sysctl_gpio_set, 2);
-    /* ??? Save/restore.  */
+    qdev_init_gpio_out(&s->busdev.qdev, &s->pl110_mux_ctrl, 1);
     return 0;
 }
 
diff --git a/hw/pl110.c b/hw/pl110.c
index 384eba2..4ac710a 100644
--- a/hw/pl110.c
+++ b/hw/pl110.c
@@ -53,6 +53,7 @@ typedef struct {
     int rows;
     enum pl110_bppmode bpp;
     int invalidate;
+    uint32_t mux_ctrl;
     uint32_t pallette[256];
     uint32_t raw_pallette[128];
     qemu_irq irq;
@@ -60,7 +61,7 @@ typedef struct {
 
 static const VMStateDescription vmstate_pl110 = {
     .name = "pl110",
-    .version_id = 1,
+    .version_id = 2,
     .minimum_version_id = 1,
     .fields = (VMStateField[]) {
         VMSTATE_INT32(version, pl110_state),
@@ -76,6 +77,7 @@ static const VMStateDescription vmstate_pl110 = {
         VMSTATE_INT32(invalidate, pl110_state),
         VMSTATE_UINT32_ARRAY(pallette, pl110_state, 256),
         VMSTATE_UINT32_ARRAY(raw_pallette, pl110_state, 128),
+        VMSTATE_UINT32_V(mux_ctrl, pl110_state, 2),
         VMSTATE_END_OF_LIST()
     }
 };
@@ -173,16 +175,26 @@ static void pl110_update_display(void *opaque)
          * mux which allows bits to be reshuffled to give
          * 565 format. The mux is typically controlled by
          * an external system register.
-         * This should be controlled by a GPIO input pin
+         * This is controlled by a GPIO input pin
          * so boards can wire it up to their register.
-         * For now, force 16 bit to be 565, to match
-         * previous QEMU PL110 model behaviour.
          *
          * The PL111 straightforwardly implements both
          * 5551 and 565 under control of the bpp field
          * in the LCDControl register.
          */
-        bpp_offset += (BPP_16_565 - BPP_16);
+        switch (s->mux_ctrl) {
+        case 3: /* 565 BGR */
+            bpp_offset = (BPP_16_565 - BPP_16);
+            break;
+        case 1: /* 5551 */
+            break;
+        case 0: /* 888; also if we have loaded vmstate from an old version */
+        case 2: /* 565 RGB */
+        default:
+            /* treat as 565 but honour BGR bit */
+            bpp_offset += (BPP_16_565 - BPP_16);
+            break;
+        }
     }
 
     if (s->cr & PL110_CR_BEBO)
@@ -416,6 +428,12 @@ static CPUWriteMemoryFunc * const pl110_writefn[] = {
    pl110_write
 };
 
+static void pl110_mux_ctrl_set(void *opaque, int line, int level)
+{
+    pl110_state *s = (pl110_state *)opaque;
+    s->mux_ctrl = level;
+}
+
 static int pl110_init(SysBusDevice *dev)
 {
     pl110_state *s = FROM_SYSBUS(pl110_state, dev);
@@ -426,6 +444,7 @@ static int pl110_init(SysBusDevice *dev)
                                        DEVICE_NATIVE_ENDIAN);
     sysbus_init_mmio(dev, 0x1000, iomemtype);
     sysbus_init_irq(dev, &s->irq);
+    qdev_init_gpio_in(&s->busdev.qdev, pl110_mux_ctrl_set, 1);
     s->ds = graphic_console_init(pl110_update_display,
                                  pl110_invalidate_display,
                                  NULL, NULL, s);
diff --git a/hw/versatilepb.c b/hw/versatilepb.c
index 147fe29..49f8f5f 100644
--- a/hw/versatilepb.c
+++ b/hw/versatilepb.c
@@ -180,7 +180,7 @@ static void versatile_init(ram_addr_t ram_size,
     qemu_irq *cpu_pic;
     qemu_irq pic[32];
     qemu_irq sic[32];
-    DeviceState *dev;
+    DeviceState *dev, *sysctl;
     PCIBus *pci_bus;
     NICInfo *nd;
     int n;
@@ -198,7 +198,12 @@ static void versatile_init(ram_addr_t ram_size,
     /* SDRAM at address zero.  */
     cpu_register_physical_memory(0, ram_size, ram_offset | IO_MEM_RAM);
 
-    arm_sysctl_init(0x10000000, 0x41007004, 0x02000000);
+    sysctl = qdev_create(NULL, "realview_sysctl");
+    qdev_prop_set_uint32(sysctl, "sys_id", 0x41007004);
+    qdev_init_nofail(sysctl);
+    qdev_prop_set_uint32(sysctl, "proc_id", 0x02000000);
+    sysbus_mmio_map(sysbus_from_qdev(sysctl), 0, 0x10000000);
+
     cpu_pic = arm_pic_init_cpu(env);
     dev = sysbus_create_varargs("pl190", 0x10140000,
                                 cpu_pic[0], cpu_pic[1], NULL);
@@ -250,7 +255,9 @@ static void versatile_init(ram_addr_t ram_size,
 
     /* The versatile/PB actually has a modified Color LCD controller
        that includes hardware cursor support from the PL111.  */
-    sysbus_create_simple("pl110_versatile", 0x10120000, pic[16]);
+    dev = sysbus_create_simple("pl110_versatile", 0x10120000, pic[16]);
+    /* Wire up the mux control signals from the SYS_CLCD register */
+    qdev_connect_gpio_out(sysctl, 0, qdev_get_gpio_in(dev, 0));
 
     sysbus_create_varargs("pl181", 0x10005000, sic[22], sic[1], NULL);
     sysbus_create_varargs("pl181", 0x1000b000, sic[23], sic[2], NULL);
commit 4fbf55568bb53a27a8c6270f1d3e2f6daf05c705
Author: Peter Maydell <peter.maydell at linaro.org>
Date:   Fri Jul 22 13:19:33 2011 +0000

    hw/pl110: Model the PL111 CLCD controller
    
    Model the PL111 CLCD controller. This is a minor variation
    on the PL110; the major programmer visible differences are
    support for hardware cursor (unimplemented) and two new
    pixel formats.
    
    Since syborg_fb.c borrows the pl11x pixel drawing routines,
    we also update it to cope with the new slightly larger array
    of function pointers.
    
    Signed-off-by: Peter Maydell <peter.maydell at linaro.org>

diff --git a/hw/pl110.c b/hw/pl110.c
index 62aba17..384eba2 100644
--- a/hw/pl110.c
+++ b/hw/pl110.c
@@ -24,15 +24,25 @@ enum pl110_bppmode
     BPP_4,
     BPP_8,
     BPP_16,
-    BPP_32
+    BPP_32,
+    BPP_16_565, /* PL111 only */
+    BPP_12      /* PL111 only */
+};
+
+
+/* The Versatile/PB uses a slightly modified PL110 controller.  */
+enum pl110_version
+{
+    PL110,
+    PL110_VERSATILE,
+    PL111
 };
 
 typedef struct {
     SysBusDevice busdev;
     DisplayState *ds;
 
-    /* The Versatile/PB uses a slightly modified PL110 controller.  */
-    int versatile;
+    int version;
     uint32_t timing[4];
     uint32_t cr;
     uint32_t upbase;
@@ -53,7 +63,7 @@ static const VMStateDescription vmstate_pl110 = {
     .version_id = 1,
     .minimum_version_id = 1,
     .fields = (VMStateField[]) {
-        VMSTATE_INT32(versatile, pl110_state),
+        VMSTATE_INT32(version, pl110_state),
         VMSTATE_UINT32_ARRAY(timing, pl110_state, 4),
         VMSTATE_UINT32(cr, pl110_state),
         VMSTATE_UINT32(upbase, pl110_state),
@@ -82,6 +92,17 @@ static const unsigned char pl110_versatile_id[] =
 #define pl110_versatile_id pl110_id
 #endif
 
+static const unsigned char pl111_id[] = {
+    0x11, 0x11, 0x24, 0x00, 0x0d, 0xf0, 0x05, 0xb1
+};
+
+/* Indexed by pl110_version */
+static const unsigned char *idregs[] = {
+    pl110_id,
+    pl110_versatile_id,
+    pl111_id
+};
+
 #include "pixel_ops.h"
 
 #define BITS 8
@@ -144,12 +165,30 @@ static void pl110_update_display(void *opaque)
     if (s->cr & PL110_CR_BGR)
         bpp_offset = 0;
     else
-        bpp_offset = 18;
+        bpp_offset = 24;
+
+    if ((s->version != PL111) && (s->bpp == BPP_16)) {
+        /* The PL110's native 16 bit mode is 5551; however
+         * most boards with a PL110 implement an external
+         * mux which allows bits to be reshuffled to give
+         * 565 format. The mux is typically controlled by
+         * an external system register.
+         * This should be controlled by a GPIO input pin
+         * so boards can wire it up to their register.
+         * For now, force 16 bit to be 565, to match
+         * previous QEMU PL110 model behaviour.
+         *
+         * The PL111 straightforwardly implements both
+         * 5551 and 565 under control of the bpp field
+         * in the LCDControl register.
+         */
+        bpp_offset += (BPP_16_565 - BPP_16);
+    }
 
     if (s->cr & PL110_CR_BEBO)
-        fn = fntable[s->bpp + 6 + bpp_offset];
+        fn = fntable[s->bpp + 8 + bpp_offset];
     else if (s->cr & PL110_CR_BEPO)
-        fn = fntable[s->bpp + 12 + bpp_offset];
+        fn = fntable[s->bpp + 16 + bpp_offset];
     else
         fn = fntable[s->bpp + bpp_offset];
 
@@ -167,6 +206,8 @@ static void pl110_update_display(void *opaque)
     case BPP_8:
         break;
     case BPP_16:
+    case BPP_16_565:
+    case BPP_12:
         src_width <<= 1;
         break;
     case BPP_32:
@@ -253,10 +294,7 @@ static uint32_t pl110_read(void *opaque, target_phys_addr_t offset)
     pl110_state *s = (pl110_state *)opaque;
 
     if (offset >= 0xfe0 && offset < 0x1000) {
-        if (s->versatile)
-            return pl110_versatile_id[(offset - 0xfe0) >> 2];
-        else
-            return pl110_id[(offset - 0xfe0) >> 2];
+        return idregs[s->version][(offset - 0xfe0) >> 2];
     }
     if (offset >= 0x200 && offset < 0x400) {
         return s->raw_pallette[(offset - 0x200) >> 2];
@@ -275,12 +313,14 @@ static uint32_t pl110_read(void *opaque, target_phys_addr_t offset)
     case 5: /* LCDLPBASE */
         return s->lpbase;
     case 6: /* LCDIMSC */
-	if (s->versatile)
-	  return s->cr;
+        if (s->version != PL110) {
+            return s->cr;
+        }
         return s->int_mask;
     case 7: /* LCDControl */
-	if (s->versatile)
-	  return s->int_mask;
+        if (s->version != PL110) {
+            return s->int_mask;
+        }
         return s->cr;
     case 8: /* LCDRIS */
         return s->int_status;
@@ -337,15 +377,17 @@ static void pl110_write(void *opaque, target_phys_addr_t offset,
         s->lpbase = val;
         break;
     case 6: /* LCDIMSC */
-        if (s->versatile)
+        if (s->version != PL110) {
             goto control;
+        }
     imsc:
         s->int_mask = val;
         pl110_update(s);
         break;
     case 7: /* LCDControl */
-        if (s->versatile)
+        if (s->version != PL110) {
             goto imsc;
+        }
     control:
         s->cr = val;
         s->bpp = (val >> 1) & 7;
@@ -393,7 +435,14 @@ static int pl110_init(SysBusDevice *dev)
 static int pl110_versatile_init(SysBusDevice *dev)
 {
     pl110_state *s = FROM_SYSBUS(pl110_state, dev);
-    s->versatile = 1;
+    s->version = PL110_VERSATILE;
+    return pl110_init(dev);
+}
+
+static int pl111_init(SysBusDevice *dev)
+{
+    pl110_state *s = FROM_SYSBUS(pl110_state, dev);
+    s->version = PL111;
     return pl110_init(dev);
 }
 
@@ -413,10 +462,19 @@ static SysBusDeviceInfo pl110_versatile_info = {
     .qdev.no_user = 1,
 };
 
+static SysBusDeviceInfo pl111_info = {
+    .init = pl111_init,
+    .qdev.name = "pl111",
+    .qdev.size = sizeof(pl110_state),
+    .qdev.vmsd = &vmstate_pl110,
+    .qdev.no_user = 1,
+};
+
 static void pl110_register_devices(void)
 {
     sysbus_register_withprop(&pl110_info);
     sysbus_register_withprop(&pl110_versatile_info);
+    sysbus_register_withprop(&pl111_info);
 }
 
 device_init(pl110_register_devices)
diff --git a/hw/pl110_template.h b/hw/pl110_template.h
index d303336..1dce32a 100644
--- a/hw/pl110_template.h
+++ b/hw/pl110_template.h
@@ -43,49 +43,61 @@
 #include "pl110_template.h"
 #undef BORDER
 
-static drawfn glue(pl110_draw_fn_,BITS)[36] =
+static drawfn glue(pl110_draw_fn_,BITS)[48] =
 {
     glue(pl110_draw_line1_lblp_bgr,BITS),
     glue(pl110_draw_line2_lblp_bgr,BITS),
     glue(pl110_draw_line4_lblp_bgr,BITS),
     glue(pl110_draw_line8_lblp_bgr,BITS),
-    glue(pl110_draw_line16_lblp_bgr,BITS),
+    glue(pl110_draw_line16_555_lblp_bgr,BITS),
     glue(pl110_draw_line32_lblp_bgr,BITS),
+    glue(pl110_draw_line16_lblp_bgr,BITS),
+    glue(pl110_draw_line12_lblp_bgr,BITS),
 
     glue(pl110_draw_line1_bbbp_bgr,BITS),
     glue(pl110_draw_line2_bbbp_bgr,BITS),
     glue(pl110_draw_line4_bbbp_bgr,BITS),
     glue(pl110_draw_line8_bbbp_bgr,BITS),
-    glue(pl110_draw_line16_bbbp_bgr,BITS),
+    glue(pl110_draw_line16_555_bbbp_bgr,BITS),
     glue(pl110_draw_line32_bbbp_bgr,BITS),
+    glue(pl110_draw_line16_bbbp_bgr,BITS),
+    glue(pl110_draw_line12_bbbp_bgr,BITS),
 
     glue(pl110_draw_line1_lbbp_bgr,BITS),
     glue(pl110_draw_line2_lbbp_bgr,BITS),
     glue(pl110_draw_line4_lbbp_bgr,BITS),
     glue(pl110_draw_line8_lbbp_bgr,BITS),
-    glue(pl110_draw_line16_lbbp_bgr,BITS),
+    glue(pl110_draw_line16_555_lbbp_bgr,BITS),
     glue(pl110_draw_line32_lbbp_bgr,BITS),
+    glue(pl110_draw_line16_lbbp_bgr,BITS),
+    glue(pl110_draw_line12_lbbp_bgr,BITS),
 
     glue(pl110_draw_line1_lblp_rgb,BITS),
     glue(pl110_draw_line2_lblp_rgb,BITS),
     glue(pl110_draw_line4_lblp_rgb,BITS),
     glue(pl110_draw_line8_lblp_rgb,BITS),
-    glue(pl110_draw_line16_lblp_rgb,BITS),
+    glue(pl110_draw_line16_555_lblp_rgb,BITS),
     glue(pl110_draw_line32_lblp_rgb,BITS),
+    glue(pl110_draw_line16_lblp_rgb,BITS),
+    glue(pl110_draw_line12_lblp_rgb,BITS),
 
     glue(pl110_draw_line1_bbbp_rgb,BITS),
     glue(pl110_draw_line2_bbbp_rgb,BITS),
     glue(pl110_draw_line4_bbbp_rgb,BITS),
     glue(pl110_draw_line8_bbbp_rgb,BITS),
-    glue(pl110_draw_line16_bbbp_rgb,BITS),
+    glue(pl110_draw_line16_555_bbbp_rgb,BITS),
     glue(pl110_draw_line32_bbbp_rgb,BITS),
+    glue(pl110_draw_line16_bbbp_rgb,BITS),
+    glue(pl110_draw_line12_bbbp_rgb,BITS),
 
     glue(pl110_draw_line1_lbbp_rgb,BITS),
     glue(pl110_draw_line2_lbbp_rgb,BITS),
     glue(pl110_draw_line4_lbbp_rgb,BITS),
     glue(pl110_draw_line8_lbbp_rgb,BITS),
-    glue(pl110_draw_line16_lbbp_rgb,BITS),
+    glue(pl110_draw_line16_555_lbbp_rgb,BITS),
     glue(pl110_draw_line32_lbbp_rgb,BITS),
+    glue(pl110_draw_line16_lbbp_rgb,BITS),
+    glue(pl110_draw_line12_lbbp_rgb,BITS),
 };
 
 #undef BITS
@@ -299,6 +311,82 @@ static void glue(pl110_draw_line32_,NAME)(void *opaque, uint8_t *d, const uint8_
     }
 }
 
+static void glue(pl110_draw_line16_555_,NAME)(void *opaque, uint8_t *d, const uint8_t *src, int width, int deststep)
+{
+    /* RGB 555 plus an intensity bit (which we ignore) */
+    uint32_t data;
+    unsigned int r, g, b;
+    while (width > 0) {
+        data = *(uint32_t *)src;
+#ifdef SWAP_WORDS
+        data = bswap32(data);
+#endif
+#ifdef RGB
+#define LSB r
+#define MSB b
+#else
+#define LSB b
+#define MSB r
+#endif
+        LSB = (data & 0x1f) << 3;
+        data >>= 5;
+        g = (data & 0x1f) << 3;
+        data >>= 5;
+        MSB = (data & 0x1f) << 3;
+        data >>= 5;
+        COPY_PIXEL(d, glue(rgb_to_pixel,BITS)(r, g, b));
+        LSB = (data & 0x1f) << 3;
+        data >>= 5;
+        g = (data & 0x1f) << 3;
+        data >>= 5;
+        MSB = (data & 0x1f) << 3;
+        data >>= 6;
+        COPY_PIXEL(d, glue(rgb_to_pixel,BITS)(r, g, b));
+#undef MSB
+#undef LSB
+        width -= 2;
+        src += 4;
+    }
+}
+
+static void glue(pl110_draw_line12_,NAME)(void *opaque, uint8_t *d, const uint8_t *src, int width, int deststep)
+{
+    /* RGB 444 with 4 bits of zeroes at the top of each halfword */
+    uint32_t data;
+    unsigned int r, g, b;
+    while (width > 0) {
+        data = *(uint32_t *)src;
+#ifdef SWAP_WORDS
+        data = bswap32(data);
+#endif
+#ifdef RGB
+#define LSB r
+#define MSB b
+#else
+#define LSB b
+#define MSB r
+#endif
+        LSB = (data & 0xf) << 4;
+        data >>= 4;
+        g = (data & 0xf) << 4;
+        data >>= 4;
+        MSB = (data & 0xf) << 4;
+        data >>= 8;
+        COPY_PIXEL(d, glue(rgb_to_pixel,BITS)(r, g, b));
+        LSB = (data & 0xf) << 4;
+        data >>= 4;
+        g = (data & 0xf) << 4;
+        data >>= 4;
+        MSB = (data & 0xf) << 4;
+        data >>= 8;
+        COPY_PIXEL(d, glue(rgb_to_pixel,BITS)(r, g, b));
+#undef MSB
+#undef LSB
+        width -= 2;
+        src += 4;
+    }
+}
+
 #undef SWAP_PIXELS
 #undef NAME
 #undef SWAP_WORDS
diff --git a/hw/syborg_fb.c b/hw/syborg_fb.c
index 7e37364..ae3e0eb 100644
--- a/hw/syborg_fb.c
+++ b/hw/syborg_fb.c
@@ -217,15 +217,24 @@ static void syborg_fb_update_display(void *opaque)
     }
 
     if (s->rgb) {
-        bpp_offset = 18;
+        bpp_offset = 24;
     } else {
         bpp_offset = 0;
     }
     if (s->endian) {
+        bpp_offset += 8;
+    }
+    /* Our bpp constants mostly match the PL110/PL111 but
+     * not for the 16 bit case
+     */
+    switch (s->bpp) {
+    case BPP_SRC_16:
         bpp_offset += 6;
+        break;
+    default:
+        bpp_offset += s->bpp;
     }
-
-    fn = fntable[s->bpp + bpp_offset];
+    fn = fntable[bpp_offset];
 
     if (s->pitch) {
         src_width = s->pitch;
commit 8b2a04eeb95212305d3a39170e1c4bc3dbe45e8a
Author: Paolo Bonzini <pbonzini at redhat.com>
Date:   Sun Aug 14 14:05:49 2011 -0700

    scsi: do not overwrite memory on REQUEST SENSE commands with a large buffer
    
    Other scsi_target_reqops commands were careful about not using r->cmd.xfer
    directly, and instead always cap it to a fixed length.  This was not done
    for REQUEST SENSE, and this patch fixes it.
    
    Reported-by: Blue Swirl <blauwirbel at gmail.com>
    Signed-off-by: Paolo Bonzini <pbonzini at redhat.com>
    Signed-off-by: Blue Swirl <blauwirbel at gmail.com>

diff --git a/hw/scsi-bus.c b/hw/scsi-bus.c
index 559d5a4..c3ce7df 100644
--- a/hw/scsi-bus.c
+++ b/hw/scsi-bus.c
@@ -292,7 +292,8 @@ static int32_t scsi_target_send_command(SCSIRequest *req, uint8_t *buf)
         if (req->cmd.xfer < 4) {
             goto illegal_request;
         }
-        r->len = scsi_device_get_sense(r->req.dev, r->buf, req->cmd.xfer,
+        r->len = scsi_device_get_sense(r->req.dev, r->buf,
+                                       MIN(req->cmd.xfer, sizeof r->buf),
                                        (req->cmd.buf[1] & 1) == 0);
         break;
     default:
commit 1b930bfa098ebad8abfc5ceff5d943133e7513f4
Author: Jan Kiszka <jan.kiszka at siemens.com>
Date:   Sat Aug 6 14:23:29 2011 +0200

    slirp: Fix bit field types in IP header structs
    
    -mms-bitfields prevents that the bitfields in current IP header structs
    are packed into a single byte as it is required. Fix this by using
    uint8_t as backing type.
    
    Signed-off-by: Jan Kiszka <jan.kiszka at siemens.com>

diff --git a/slirp/ip.h b/slirp/ip.h
index 48ea38e..72dbe9a 100644
--- a/slirp/ip.h
+++ b/slirp/ip.h
@@ -74,10 +74,10 @@ typedef uint32_t n_long;                 /* long as received from the net */
  */
 struct ip {
 #ifdef HOST_WORDS_BIGENDIAN
-	u_int ip_v:4,			/* version */
+	uint8_t ip_v:4,			/* version */
 		ip_hl:4;		/* header length */
 #else
-	u_int ip_hl:4,		/* header length */
+	uint8_t ip_hl:4,		/* header length */
 		ip_v:4;			/* version */
 #endif
 	uint8_t		ip_tos;			/* type of service */
@@ -140,10 +140,10 @@ struct	ip_timestamp {
 	uint8_t	ipt_len;		/* size of structure (variable) */
 	uint8_t	ipt_ptr;		/* index of current entry */
 #ifdef HOST_WORDS_BIGENDIAN
-	u_int	ipt_oflw:4,		/* overflow counter */
+	uint8_t	ipt_oflw:4,		/* overflow counter */
 		ipt_flg:4;		/* flags, see below */
 #else
-	u_int	ipt_flg:4,		/* flags, see below */
+	uint8_t	ipt_flg:4,		/* flags, see below */
 		ipt_oflw:4;		/* overflow counter */
 #endif
 	union ipt_timestamp {
diff --git a/slirp/tcp.h b/slirp/tcp.h
index 9d06836..b3817cb 100644
--- a/slirp/tcp.h
+++ b/slirp/tcp.h
@@ -51,10 +51,10 @@ struct tcphdr {
 	tcp_seq	th_seq;			/* sequence number */
 	tcp_seq	th_ack;			/* acknowledgement number */
 #ifdef HOST_WORDS_BIGENDIAN
-	u_int	th_off:4,		/* data offset */
+	uint8_t	th_off:4,		/* data offset */
 		th_x2:4;		/* (unused) */
 #else
-	u_int	th_x2:4,		/* (unused) */
+	uint8_t	th_x2:4,		/* (unused) */
 		th_off:4;		/* data offset */
 #endif
 	uint8_t th_flags;
commit 3b6ffe50300f13240e1b46420ad05da1116df410
Author: Peter Maydell <peter.maydell at linaro.org>
Date:   Fri Aug 12 17:49:36 2011 +0100

    hw/scsi-bus.c: Fix use of uninitialised variable
    
    Don't use req before it has been initialised in scsi_req_new().
    This fixes a compile failure due to gcc complaining about this.
    
    Signed-off-by: Peter Maydell <peter.maydell at linaro.org>
    Acked-by: Paolo Bonzini <pbonzini at redhat.com>
    Signed-off-by: Blue Swirl <blauwirbel at gmail.com>

diff --git a/hw/scsi-bus.c b/hw/scsi-bus.c
index f2af6cd..559d5a4 100644
--- a/hw/scsi-bus.c
+++ b/hw/scsi-bus.c
@@ -372,7 +372,7 @@ SCSIRequest *scsi_req_new(SCSIDevice *d, uint32_t tag, uint32_t lun,
     } else {
         trace_scsi_req_parsed(d->id, lun, tag, buf[0],
                               cmd.mode, cmd.xfer);
-        if (req->cmd.lba != -1) {
+        if (cmd.lba != -1) {
             trace_scsi_req_parsed_lba(d->id, lun, tag, buf[0],
                                       cmd.lba);
         }
commit 7534ba0130a29a3373ed10557e2c64452b75ba8a
Author: Michael Roth <mdroth at linux.vnet.ibm.com>
Date:   Wed Aug 10 13:10:51 2011 -0500

    qapi: fix build issue due to missing newline in generated header
    
    Fixes a build issue on RHEL5, and potentially other distros, where gcc
    will generate an error due to us not writing a trailing "\n" when
    generating *qmp-commands.h
    
    Signed-off-by: Michael Roth <mdroth at linux.vnet.ibm.com>
    Signed-off-by: Anthony Liguori <aliguori at us.ibm.com>

diff --git a/scripts/qapi-commands.py b/scripts/qapi-commands.py
index 9ad4c54..bf61740 100644
--- a/scripts/qapi-commands.py
+++ b/scripts/qapi-commands.py
@@ -375,7 +375,7 @@ if dispatch_type == "sync":
         ret = gen_marshal_input(cmd['command'], arglist, ret_type) + "\n"
         fdef.write(ret)
 
-    fdecl.write("\n#endif");
+    fdecl.write("\n#endif\n");
     ret = gen_registry(commands)
     fdef.write(ret)
 
commit 7075ba3097091507de89650f6e4e247f7411ebad
Author: Avi Kivity <avi at redhat.com>
Date:   Mon Aug 8 19:58:50 2011 +0300

    memory: correct documentation typos
    
    Noted by Drew Jones.
    
    Signed-off-by: Avi Kivity <avi at redhat.com>
    Signed-off-by: Anthony Liguori <aliguori at us.ibm.com>

diff --git a/docs/memory.txt b/docs/memory.txt
index 4460c06..3fc1683 100644
--- a/docs/memory.txt
+++ b/docs/memory.txt
@@ -15,7 +15,7 @@ The memory model provides support for
  - setting up coalesced memory for kvm
  - setting up ioeventfd regions for kvm
 
-Memory is modelled as an tree (really acyclic graph) of MemoryRegion objects.
+Memory is modelled as a tree (really acyclic graph) of MemoryRegion objects.
 The root of the tree is memory as seen from the CPU's viewpoint (the system
 bus).  Nodes in the tree represent other buses, memory controllers, and
 memory regions that have been rerouted.  Leaves are RAM and MMIO regions.
@@ -87,7 +87,7 @@ guest accesses an address:
   descending priority order
   - if the address lies outside the region offset/size, the subregion is
     discarded
-  - if the subregion is a leaf (RAM or MMIO), the seach terminates
+  - if the subregion is a leaf (RAM or MMIO), the search terminates
   - if the subregion is a container, the same algorithm is used within the
     subregion (after the address is adjusted by the subregion offset)
   - if the subregion is an alias, the search is continues at the alias target
@@ -128,7 +128,7 @@ so-called PCI hole, that allows a 32-bit PCI bus to exist in a system with
 4GB of memory.
 
 The memory controller diverts addresses in the range 640K-768K to the PCI
-address space.  This is modeled using the "vga-window" alias, mapped at a
+address space.  This is modelled using the "vga-window" alias, mapped at a
 higher priority so it obscures the RAM at the same addresses.  The vga window
 can be removed by programming the memory controller; this is modelled by
 removing the alias and exposing the RAM underneath.
@@ -164,7 +164,7 @@ various constraints can be supplied to control how these callbacks are called:
  - .impl.min_access_size, .impl.max_access_size define the access sizes
    (in bytes) supported by the *implementation*; other access sizes will be
    emulated using the ones available.  For example a 4-byte write will be
-   emulated using four 1-byte write, is .impl.max_access_size = 1.
+   emulated using four 1-byte write, if .impl.max_access_size = 1.
  - .impl.valid specifies that the *implementation* only supports unaligned
    accesses; unaligned accesses will be emulated by two aligned accesses.
  - .old_portio and .old_mmio can be used to ease porting from code using
commit d0a9b5bc0a6abdab182ad55dcc1c71508c163c5c
Author: Avi Kivity <avi at redhat.com>
Date:   Mon Aug 8 19:58:49 2011 +0300

    memory: add API for creating ROM/device regions
    
    ROM/device regions act as mapped RAM for reads, can I/O memory for
    writes.  This allow emulation of flash devices.
    
    Signed-off-by: Avi Kivity <avi at redhat.com>
    Signed-off-by: Anthony Liguori <aliguori at us.ibm.com>

diff --git a/memory.c b/memory.c
index 5e3d966..beff98c 100644
--- a/memory.c
+++ b/memory.c
@@ -125,6 +125,7 @@ struct FlatRange {
     target_phys_addr_t offset_in_region;
     AddrRange addr;
     uint8_t dirty_log_mask;
+    bool readable;
 };
 
 /* Flattened global view of current active memory hierarchy.  Kept in sorted
@@ -164,7 +165,8 @@ static bool flatrange_equal(FlatRange *a, FlatRange *b)
 {
     return a->mr == b->mr
         && addrrange_equal(a->addr, b->addr)
-        && a->offset_in_region == b->offset_in_region;
+        && a->offset_in_region == b->offset_in_region
+        && a->readable == b->readable;
 }
 
 static void flatview_init(FlatView *view)
@@ -200,7 +202,8 @@ static bool can_merge(FlatRange *r1, FlatRange *r2)
     return addrrange_end(r1->addr) == r2->addr.start
         && r1->mr == r2->mr
         && r1->offset_in_region + r1->addr.size == r2->offset_in_region
-        && r1->dirty_log_mask == r2->dirty_log_mask;
+        && r1->dirty_log_mask == r2->dirty_log_mask
+        && r1->readable == r2->readable;
 }
 
 /* Attempt to simplify a view by merging ajacent ranges */
@@ -241,6 +244,10 @@ static void as_memory_range_add(AddressSpace *as, FlatRange *fr)
         region_offset = 0;
     }
 
+    if (!fr->readable) {
+        phys_offset &= TARGET_PAGE_MASK;
+    }
+
     cpu_register_physical_memory_log(fr->addr.start,
                                      fr->addr.size,
                                      phys_offset,
@@ -462,6 +469,7 @@ static void render_memory_region(FlatView *view,
             fr.offset_in_region = offset_in_region;
             fr.addr = addrrange_make(base, now);
             fr.dirty_log_mask = mr->dirty_log_mask;
+            fr.readable = mr->readable;
             flatview_insert(view, i, &fr);
             ++i;
             base += now;
@@ -480,6 +488,7 @@ static void render_memory_region(FlatView *view,
         fr.offset_in_region = offset_in_region;
         fr.addr = addrrange_make(base, remain);
         fr.dirty_log_mask = mr->dirty_log_mask;
+        fr.readable = mr->readable;
         flatview_insert(view, i, &fr);
     }
 }
@@ -680,6 +689,12 @@ static void memory_region_destructor_iomem(MemoryRegion *mr)
     cpu_unregister_io_memory(mr->ram_addr);
 }
 
+static void memory_region_destructor_rom_device(MemoryRegion *mr)
+{
+    qemu_ram_free(mr->ram_addr & TARGET_PAGE_MASK);
+    cpu_unregister_io_memory(mr->ram_addr & ~(TARGET_PAGE_MASK | IO_MEM_ROMD));
+}
+
 void memory_region_init(MemoryRegion *mr,
                         const char *name,
                         uint64_t size)
@@ -690,6 +705,7 @@ void memory_region_init(MemoryRegion *mr,
     mr->addr = 0;
     mr->offset = 0;
     mr->terminates = false;
+    mr->readable = true;
     mr->destructor = memory_region_destructor_none;
     mr->priority = 0;
     mr->may_overlap = false;
@@ -910,6 +926,24 @@ void memory_region_init_alias(MemoryRegion *mr,
     mr->alias_offset = offset;
 }
 
+void memory_region_init_rom_device(MemoryRegion *mr,
+                                   const MemoryRegionOps *ops,
+                                   DeviceState *dev,
+                                   const char *name,
+                                   uint64_t size)
+{
+    memory_region_init(mr, name, size);
+    mr->terminates = true;
+    mr->destructor = memory_region_destructor_rom_device;
+    mr->ram_addr = qemu_ram_alloc(dev, name, size);
+    mr->ram_addr |= cpu_register_io_memory(memory_region_read_thunk,
+                                           memory_region_write_thunk,
+                                           mr,
+                                           mr->ops->endianness);
+    mr->ram_addr |= IO_MEM_ROMD;
+    mr->backend_registered = true;
+}
+
 void memory_region_destroy(MemoryRegion *mr)
 {
     assert(QTAILQ_EMPTY(&mr->subregions));
@@ -967,6 +1001,14 @@ void memory_region_set_readonly(MemoryRegion *mr, bool readonly)
     /* FIXME */
 }
 
+void memory_region_rom_device_set_readable(MemoryRegion *mr, bool readable)
+{
+    if (mr->readable != readable) {
+        mr->readable = readable;
+        memory_region_update_topology();
+    }
+}
+
 void memory_region_reset_dirty(MemoryRegion *mr, target_phys_addr_t addr,
                                target_phys_addr_t size, unsigned client)
 {
diff --git a/memory.h b/memory.h
index c9252a2..0553cc7 100644
--- a/memory.h
+++ b/memory.h
@@ -113,6 +113,7 @@ struct MemoryRegion {
     ram_addr_t ram_addr;
     IORange iorange;
     bool terminates;
+    bool readable;
     MemoryRegion *alias;
     target_phys_addr_t alias_offset;
     unsigned priority;
@@ -219,6 +220,25 @@ void memory_region_init_alias(MemoryRegion *mr,
                               MemoryRegion *orig,
                               target_phys_addr_t offset,
                               uint64_t size);
+
+/**
+ * memory_region_init_rom_device:  Initialize a ROM memory region.  Writes are
+ *                                 handled via callbacks.
+ *
+ * @mr: the #MemoryRegion to be initialized.
+ * @ops: callbacks for write access handling.
+ * @dev: a device associated with the region; may be %NULL.
+ * @name: the name of the region; the pair (@dev, @name) must be globally
+ *        unique.  The name is part of the save/restore ABI and so cannot be
+ *        changed.
+ * @size: size of the region.
+ */
+void memory_region_init_rom_device(MemoryRegion *mr,
+                                   const MemoryRegionOps *ops,
+                                   DeviceState *dev, /* FIXME: layering violation */
+                                   const char *name,
+                                   uint64_t size);
+
 /**
  * memory_region_destroy: Destroy a memory region and relaim all resources.
  *
@@ -331,6 +351,20 @@ void memory_region_reset_dirty(MemoryRegion *mr, target_phys_addr_t addr,
 void memory_region_set_readonly(MemoryRegion *mr, bool readonly);
 
 /**
+ * memory_region_rom_device_set_readable: enable/disable ROM readability
+ *
+ * Allows a ROM device (initialized with memory_region_init_rom_device() to
+ * to be marked as readable (default) or not readable.  When it is readable,
+ * the device is mapped to guest memory.  When not readable, reads are
+ * forwarded to the #MemoryRegion.read function.
+ *
+ * @mr: the memory region to be updated
+ * @readable: whether reads are satisified directly (%true) or via callbacks
+ *            (%false)
+ */
+void memory_region_rom_device_set_readable(MemoryRegion *mr, bool readable);
+
+/**
  * memory_region_set_coalescing: Enable memory coalescing for the region.
  *
  * Enabled writes to a region to be queued for later processing. MMIO ->write
commit 545e92e06aa4f5eda46f4be2018a595d1adf66f8
Author: Avi Kivity <avi at redhat.com>
Date:   Mon Aug 8 19:58:48 2011 +0300

    memory: reclaim resources when a memory region is destroyed for good
    
    Signed-off-by: Avi Kivity <avi at redhat.com>
    Signed-off-by: Anthony Liguori <aliguori at us.ibm.com>

diff --git a/memory.c b/memory.c
index be891c6..5e3d966 100644
--- a/memory.c
+++ b/memory.c
@@ -661,6 +661,25 @@ void memory_region_transaction_commit(void)
     memory_region_update_topology();
 }
 
+static void memory_region_destructor_none(MemoryRegion *mr)
+{
+}
+
+static void memory_region_destructor_ram(MemoryRegion *mr)
+{
+    qemu_ram_free(mr->ram_addr);
+}
+
+static void memory_region_destructor_ram_from_ptr(MemoryRegion *mr)
+{
+    qemu_ram_free_from_ptr(mr->ram_addr);
+}
+
+static void memory_region_destructor_iomem(MemoryRegion *mr)
+{
+    cpu_unregister_io_memory(mr->ram_addr);
+}
+
 void memory_region_init(MemoryRegion *mr,
                         const char *name,
                         uint64_t size)
@@ -671,6 +690,7 @@ void memory_region_init(MemoryRegion *mr,
     mr->addr = 0;
     mr->offset = 0;
     mr->terminates = false;
+    mr->destructor = memory_region_destructor_none;
     mr->priority = 0;
     mr->may_overlap = false;
     mr->alias = NULL;
@@ -833,6 +853,7 @@ static void memory_region_prepare_ram_addr(MemoryRegion *mr)
         return;
     }
 
+    mr->destructor = memory_region_destructor_iomem;
     mr->ram_addr = cpu_register_io_memory(memory_region_read_thunk,
                                           memory_region_write_thunk,
                                           mr,
@@ -860,6 +881,7 @@ void memory_region_init_ram(MemoryRegion *mr,
 {
     memory_region_init(mr, name, size);
     mr->terminates = true;
+    mr->destructor = memory_region_destructor_ram;
     mr->ram_addr = qemu_ram_alloc(dev, name, size);
     mr->backend_registered = true;
 }
@@ -872,6 +894,7 @@ void memory_region_init_ram_ptr(MemoryRegion *mr,
 {
     memory_region_init(mr, name, size);
     mr->terminates = true;
+    mr->destructor = memory_region_destructor_ram_from_ptr;
     mr->ram_addr = qemu_ram_alloc_from_ptr(dev, name, size, ptr);
     mr->backend_registered = true;
 }
@@ -890,6 +913,7 @@ void memory_region_init_alias(MemoryRegion *mr,
 void memory_region_destroy(MemoryRegion *mr)
 {
     assert(QTAILQ_EMPTY(&mr->subregions));
+    mr->destructor(mr);
     memory_region_clear_coalescing(mr);
     qemu_free((char *)mr->name);
     qemu_free(mr->ioeventfds);
diff --git a/memory.h b/memory.h
index da00a3b..c9252a2 100644
--- a/memory.h
+++ b/memory.h
@@ -109,6 +109,7 @@ struct MemoryRegion {
     target_phys_addr_t addr;
     target_phys_addr_t offset;
     bool backend_registered;
+    void (*destructor)(MemoryRegion *mr);
     ram_addr_t ram_addr;
     IORange iorange;
     bool terminates;
commit 76dc3cf82c1fa4afc4b67f60318d90355ded8fb3
Author: Jiri Denemark <jdenemar at redhat.com>
Date:   Wed Aug 10 12:04:34 2011 +0200

    build: Move QEMU_INCLUDES before QEMU_CFLAGS
    
    This patch fixes build when any of the include paths from QEMU_CFLAGS
    contains a header file with similar name to a header file in qemu
    sources. I hit it with error.h included by qapi/qapi-types-core.h. GCC
    decided to use /usr/include/alsa/error.h instead of qemu's error.h.
    
    Tested-by: Michael Roth <mdroth at linux.vnet.ibm.com>
    Signed-off-by: Jiri Denemark <jdenemar at redhat.com>
    Signed-off-by: Anthony Liguori <aliguori at us.ibm.com>

diff --git a/rules.mak b/rules.mak
index 612ae37..1a2622c 100644
--- a/rules.mak
+++ b/rules.mak
@@ -15,21 +15,21 @@ MAKEFLAGS += -rR
 QEMU_DGFLAGS += -MMD -MP -MT $@ -MF $(*D)/$(*F).d
 
 %.o: %.c
-	$(call quiet-command,$(CC) $(QEMU_CFLAGS) $(QEMU_INCLUDES) $(QEMU_DGFLAGS) $(CFLAGS) -c -o $@ $<,"  CC    $(TARGET_DIR)$@")
+	$(call quiet-command,$(CC) $(QEMU_INCLUDES) $(QEMU_CFLAGS) $(QEMU_DGFLAGS) $(CFLAGS) -c -o $@ $<,"  CC    $(TARGET_DIR)$@")
 
 ifeq ($(LIBTOOL),)
 %.lo: %.c
 	@echo "missing libtool. please install and rerun configure"; exit 1
 else
 %.lo: %.c
-	$(call quiet-command,libtool --mode=compile --quiet --tag=CC $(CC) $(QEMU_CFLAGS) $(QEMU_INCLUDES) $(QEMU_DGFLAGS) $(CFLAGS) -c -o $@ $<,"  lt CC $@")
+	$(call quiet-command,libtool --mode=compile --quiet --tag=CC $(CC) $(QEMU_INCLUDES) $(QEMU_CFLAGS) $(QEMU_DGFLAGS) $(CFLAGS) -c -o $@ $<,"  lt CC $@")
 endif
 
 %.o: %.S
-	$(call quiet-command,$(CC) $(QEMU_CFLAGS) $(QEMU_INCLUDES) $(QEMU_DGFLAGS) $(CFLAGS) -c -o $@ $<,"  AS    $(TARGET_DIR)$@")
+	$(call quiet-command,$(CC) $(QEMU_INCLUDES) $(QEMU_CFLAGS) $(QEMU_DGFLAGS) $(CFLAGS) -c -o $@ $<,"  AS    $(TARGET_DIR)$@")
 
 %.o: %.m
-	$(call quiet-command,$(CC) $(QEMU_CFLAGS) $(QEMU_INCLUDES) $(QEMU_DGFLAGS) $(CFLAGS) -c -o $@ $<,"  OBJC  $(TARGET_DIR)$@")
+	$(call quiet-command,$(CC) $(QEMU_INCLUDES) $(QEMU_CFLAGS) $(QEMU_DGFLAGS) $(CFLAGS) -c -o $@ $<,"  OBJC  $(TARGET_DIR)$@")
 
 LINK = $(call quiet-command,$(CC) $(QEMU_CFLAGS) $(CFLAGS) $(LDFLAGS) -o $@ $(1) $(LIBS),"  LINK  $(TARGET_DIR)$@")
 
commit 83b2f0a0d810922d3d167153ac612dc187ff9d8f
Author: Stefan Weil <weil at mail.berlios.de>
Date:   Sat Aug 6 22:47:22 2011 +0200

    configure: Disable guest_agent for mingw32
    
    guest_agent is not supported for mingw32, so the default value
    should be 'no', not 'yes'.
    
    This removes the dependencies to glib-2.0 and python which
    makes native and cross builds for w32 much easier (no need
    to get and install these extra packages).
    
    It also avoids the problems caused by different bitfield alignment
    which is required by glib-2.0.
    
    It is still possible to set guest_agent=yes via configure option.
    
    Signed-off-by: Stefan Weil <weil at mail.berlios.de>
    Signed-off-by: Anthony Liguori <aliguori at us.ibm.com>

diff --git a/configure b/configure
index a6687f7..6873e13 100755
--- a/configure
+++ b/configure
@@ -493,6 +493,7 @@ if test "$mingw32" = "yes" ; then
   bindir="\${prefix}"
   sysconfdir="\${prefix}"
   confsuffix=""
+  guest_agent="no"
 fi
 
 werror=""
commit 98254542f9aca81f136a96c82a9ae08e781a9baf
Author: Paolo Bonzini <pbonzini at redhat.com>
Date:   Wed Aug 3 10:49:19 2011 +0200

    scsi: add special traces for common commands
    
    Can be useful when debugging the device scan phase.
    
    Signed-off-by: Paolo Bonzini <pbonzini at redhat.com>
    Signed-off-by: Anthony Liguori <aliguori at us.ibm.com>

diff --git a/hw/scsi-bus.c b/hw/scsi-bus.c
index 9b2d12d..f2af6cd 100644
--- a/hw/scsi-bus.c
+++ b/hw/scsi-bus.c
@@ -396,6 +396,23 @@ SCSIRequest *scsi_req_new(SCSIDevice *d, uint32_t tag, uint32_t lun,
     }
 
     req->cmd = cmd;
+    switch (buf[0]) {
+    case INQUIRY:
+        trace_scsi_inquiry(d->id, lun, tag, cmd.buf[1], cmd.buf[2]);
+        break;
+    case TEST_UNIT_READY:
+        trace_scsi_test_unit_ready(d->id, lun, tag);
+        break;
+    case REPORT_LUNS:
+        trace_scsi_report_luns(d->id, lun, tag);
+        break;
+    case REQUEST_SENSE:
+        trace_scsi_request_sense(d->id, lun, tag);
+        break;
+    default:
+        break;
+    }
+
     return req;
 }
 
diff --git a/trace-events b/trace-events
index 0daf2cc..246704c 100644
--- a/trace-events
+++ b/trace-events
@@ -252,6 +252,10 @@ disable scsi_req_parsed(int target, int lun, int tag, int cmd, int mode, int xfe
 disable scsi_req_parsed_lba(int target, int lun, int tag, int cmd, uint64_t lba) "target %d lun %d tag %d command %d lba %"PRIu64""
 disable scsi_req_parse_bad(int target, int lun, int tag, int cmd) "target %d lun %d tag %d command %d"
 disable scsi_req_build_sense(int target, int lun, int tag, int key, int asc, int ascq) "target %d lun %d tag %d key %#02x asc %#02x ascq %#02x"
+disable scsi_report_luns(int target, int lun, int tag) "target %d lun %d tag %d"
+disable scsi_inquiry(int target, int lun, int tag, int cdb1, int cdb2) "target %d lun %d tag %d page %#02x/%#02x"
+disable scsi_test_unit_ready(int target, int lun, int tag) "target %d lun %d tag %d"
+disable scsi_request_sense(int target, int lun, int tag) "target %d lun %d tag %d"
 
 # vl.c
 disable vm_state_notify(int running, int reason) "running %d reason %d"
commit c7b488721d6aafe32994ac63f8d690ae6d4729fa
Author: Paolo Bonzini <pbonzini at redhat.com>
Date:   Wed Aug 3 10:49:18 2011 +0200

    scsi: report unit attention on reset
    
    Signed-off-by: Paolo Bonzini <pbonzini at redhat.com>
    Signed-off-by: Anthony Liguori <aliguori at us.ibm.com>

diff --git a/hw/scsi-bus.c b/hw/scsi-bus.c
index 564b840..9b2d12d 100644
--- a/hw/scsi-bus.c
+++ b/hw/scsi-bus.c
@@ -1099,7 +1099,7 @@ void scsi_req_abort(SCSIRequest *req, int status)
     scsi_req_complete(req, status);
 }
 
-void scsi_device_purge_requests(SCSIDevice *sdev)
+void scsi_device_purge_requests(SCSIDevice *sdev, SCSISense sense)
 {
     SCSIRequest *req;
 
@@ -1107,6 +1107,7 @@ void scsi_device_purge_requests(SCSIDevice *sdev)
         req = QTAILQ_FIRST(&sdev->requests);
         scsi_req_cancel(req);
     }
+    sdev->unit_attention = sense;
 }
 
 static char *scsibus_get_fw_dev_path(DeviceState *dev)
diff --git a/hw/scsi-disk.c b/hw/scsi-disk.c
index a33da55..f848318 100644
--- a/hw/scsi-disk.c
+++ b/hw/scsi-disk.c
@@ -1087,7 +1087,7 @@ static void scsi_disk_reset(DeviceState *dev)
     SCSIDiskState *s = DO_UPCAST(SCSIDiskState, qdev.qdev, dev);
     uint64_t nb_sectors;
 
-    scsi_device_purge_requests(&s->qdev);
+    scsi_device_purge_requests(&s->qdev, SENSE_CODE(RESET));
 
     bdrv_get_geometry(s->bs, &nb_sectors);
     nb_sectors /= s->cluster_size;
@@ -1101,7 +1101,7 @@ static void scsi_destroy(SCSIDevice *dev)
 {
     SCSIDiskState *s = DO_UPCAST(SCSIDiskState, qdev, dev);
 
-    scsi_device_purge_requests(&s->qdev);
+    scsi_device_purge_requests(&s->qdev, SENSE_CODE(NO_SENSE));
     blockdev_mark_auto_del(s->qdev.conf.bs);
 }
 
diff --git a/hw/scsi-generic.c b/hw/scsi-generic.c
index 83723ac..b63371e 100644
--- a/hw/scsi-generic.c
+++ b/hw/scsi-generic.c
@@ -381,14 +381,14 @@ static void scsi_generic_reset(DeviceState *dev)
 {
     SCSIGenericState *s = DO_UPCAST(SCSIGenericState, qdev.qdev, dev);
 
-    scsi_device_purge_requests(&s->qdev);
+    scsi_device_purge_requests(&s->qdev, SENSE_CODE(RESET));
 }
 
 static void scsi_destroy(SCSIDevice *d)
 {
     SCSIGenericState *s = DO_UPCAST(SCSIGenericState, qdev, d);
 
-    scsi_device_purge_requests(&s->qdev);
+    scsi_device_purge_requests(&s->qdev, SENSE_CODE(NO_SENSE));
     blockdev_mark_auto_del(s->qdev.conf.bs);
 }
 
diff --git a/hw/scsi.h b/hw/scsi.h
index 09c3606..98fd689 100644
--- a/hw/scsi.h
+++ b/hw/scsi.h
@@ -187,7 +187,7 @@ uint8_t *scsi_req_get_buf(SCSIRequest *req);
 int scsi_req_get_sense(SCSIRequest *req, uint8_t *buf, int len);
 void scsi_req_abort(SCSIRequest *req, int status);
 void scsi_req_cancel(SCSIRequest *req);
-void scsi_device_purge_requests(SCSIDevice *sdev);
+void scsi_device_purge_requests(SCSIDevice *sdev, SCSISense sense);
 int scsi_device_get_sense(SCSIDevice *dev, uint8_t *buf, int len, bool fixed);
 
 #endif
commit 6dc06f08b3d6c0347df00ac68d9f30e2b233a749
Author: Paolo Bonzini <pbonzini at redhat.com>
Date:   Wed Aug 3 10:49:17 2011 +0200

    scsi: add support for unit attention conditions
    
    Unit attention conditions override any sense data the device already
    has.  Their signaling and clearing is handled entirely by the SCSIBus
    code, and they are completely transparent to the SCSIDevices.
    
    Signed-off-by: Paolo Bonzini <pbonzini at redhat.com>
    Signed-off-by: Anthony Liguori <aliguori at us.ibm.com>

diff --git a/hw/scsi-bus.c b/hw/scsi-bus.c
index bec8d82..564b840 100644
--- a/hw/scsi-bus.c
+++ b/hw/scsi-bus.c
@@ -149,6 +149,24 @@ struct SCSIReqOps reqops_invalid_opcode = {
     .send_command = scsi_invalid_command
 };
 
+/* SCSIReqOps implementation for unit attention conditions.  */
+
+static int32_t scsi_unit_attention(SCSIRequest *req, uint8_t *buf)
+{
+    if (req->dev && req->dev->unit_attention.key == UNIT_ATTENTION) {
+        scsi_req_build_sense(req, req->dev->unit_attention);
+    } else if (req->bus->unit_attention.key == UNIT_ATTENTION) {
+        scsi_req_build_sense(req, req->bus->unit_attention);
+    }
+    scsi_req_complete(req, CHECK_CONDITION);
+    return 0;
+}
+
+struct SCSIReqOps reqops_unit_attention = {
+    .size         = sizeof(SCSIRequest),
+    .send_command = scsi_unit_attention
+};
+
 /* SCSIReqOps implementation for REPORT LUNS and for commands sent to
    an invalid LUN.  */
 
@@ -344,6 +362,7 @@ SCSIRequest *scsi_req_alloc(SCSIReqOps *reqops, SCSIDevice *d, uint32_t tag,
 SCSIRequest *scsi_req_new(SCSIDevice *d, uint32_t tag, uint32_t lun,
                           uint8_t *buf, void *hba_private)
 {
+    SCSIBus *bus = DO_UPCAST(SCSIBus, qbus, d->qdev.parent_bus);
     SCSIRequest *req;
     SCSICommand cmd;
 
@@ -358,7 +377,15 @@ SCSIRequest *scsi_req_new(SCSIDevice *d, uint32_t tag, uint32_t lun,
                                       cmd.lba);
         }
 
-        if (lun != d->lun ||
+        if ((d->unit_attention.key == UNIT_ATTENTION ||
+             bus->unit_attention.key == UNIT_ATTENTION) &&
+            (buf[0] != INQUIRY &&
+             buf[0] != REPORT_LUNS &&
+             buf[0] != GET_CONFIGURATION &&
+             buf[0] != GET_EVENT_STATUS_NOTIFICATION)) {
+            req = scsi_req_alloc(&reqops_unit_attention, d, tag, lun,
+                                 hba_private);
+        } else if (lun != d->lun ||
             buf[0] == REPORT_LUNS ||
             buf[0] == REQUEST_SENSE) {
             req = scsi_req_alloc(&reqops_target_command, d, tag, lun,
@@ -377,13 +404,68 @@ uint8_t *scsi_req_get_buf(SCSIRequest *req)
     return req->ops->get_buf(req);
 }
 
+static void scsi_clear_unit_attention(SCSIRequest *req)
+{
+    SCSISense *ua;
+    if (req->dev->unit_attention.key != UNIT_ATTENTION &&
+        req->bus->unit_attention.key != UNIT_ATTENTION) {
+        return;
+    }
+
+    /*
+     * If an INQUIRY command enters the enabled command state,
+     * the device server shall [not] clear any unit attention condition;
+     * See also MMC-6, paragraphs 6.5 and 6.6.2.
+     */
+    if (req->cmd.buf[0] == INQUIRY ||
+        req->cmd.buf[0] == GET_CONFIGURATION ||
+        req->cmd.buf[0] == GET_EVENT_STATUS_NOTIFICATION) {
+        return;
+    }
+
+    if (req->dev->unit_attention.key == UNIT_ATTENTION) {
+        ua = &req->dev->unit_attention;
+    } else {
+        ua = &req->bus->unit_attention;
+    }
+
+    /*
+     * If a REPORT LUNS command enters the enabled command state, [...]
+     * the device server shall clear any pending unit attention condition
+     * with an additional sense code of REPORTED LUNS DATA HAS CHANGED.
+     */
+    if (req->cmd.buf[0] == REPORT_LUNS &&
+        !(ua->asc == SENSE_CODE(REPORTED_LUNS_CHANGED).asc &&
+          ua->ascq == SENSE_CODE(REPORTED_LUNS_CHANGED).ascq)) {
+        return;
+    }
+
+    *ua = SENSE_CODE(NO_SENSE);
+}
+
 int scsi_req_get_sense(SCSIRequest *req, uint8_t *buf, int len)
 {
+    int ret;
+
     assert(len >= 14);
     if (!req->sense_len) {
         return 0;
     }
-    return scsi_build_sense(req->sense, req->sense_len, buf, len, true);
+
+    ret = scsi_build_sense(req->sense, req->sense_len, buf, len, true);
+
+    /*
+     * FIXME: clearing unit attention conditions upon autosense should be done
+     * only if the UA_INTLCK_CTRL field in the Control mode page is set to 00b
+     * (SAM-5, 5.14).
+     *
+     * We assume UA_INTLCK_CTRL to be 00b for HBAs that support autosense, and
+     * 10b for HBAs that do not support it (do not call scsi_req_get_sense).
+     * In the latter case, scsi_req_complete clears unit attention conditions
+     * after moving them to the device's sense buffer.
+     */
+    scsi_clear_unit_attention(req);
+    return ret;
 }
 
 int scsi_device_get_sense(SCSIDevice *dev, uint8_t *buf, int len, bool fixed)
@@ -983,6 +1065,13 @@ void scsi_req_complete(SCSIRequest *req, int status)
     }
     req->dev->sense_len = req->sense_len;
 
+    /*
+     * Unit attention state is now stored in the device's sense buffer
+     * if the HBA didn't do autosense.  Clear the pending unit attention
+     * flags.
+     */
+    scsi_clear_unit_attention(req);
+
     scsi_req_ref(req);
     scsi_req_dequeue(req);
     req->bus->ops->complete(req, req->status);
diff --git a/hw/scsi-defs.h b/hw/scsi-defs.h
index 977c38b..ea288fa 100644
--- a/hw/scsi-defs.h
+++ b/hw/scsi-defs.h
@@ -78,6 +78,7 @@
 #define READ_TOC              0x43
 #define REPORT_DENSITY_SUPPORT 0x44
 #define GET_CONFIGURATION     0x46
+#define GET_EVENT_STATUS_NOTIFICATION 0x4a
 #define LOG_SELECT            0x4c
 #define LOG_SENSE             0x4d
 #define MODE_SELECT_10        0x55
diff --git a/hw/scsi.h b/hw/scsi.h
index 4d5b596..09c3606 100644
--- a/hw/scsi.h
+++ b/hw/scsi.h
@@ -62,6 +62,7 @@ struct SCSIDevice
     uint32_t id;
     BlockConf conf;
     SCSIDeviceInfo *info;
+    SCSISense unit_attention;
     uint8_t sense[SCSI_SENSE_BUF_SIZE];
     uint32_t sense_len;
     QTAILQ_HEAD(, SCSIRequest) requests;
@@ -105,6 +106,7 @@ struct SCSIBus {
     BusState qbus;
     int busnr;
 
+    SCSISense unit_attention;
     int tcq, ndev;
     const SCSIBusOps *ops;
 
commit a872a3049a7b9439879a496cf7cc147af8feb3ef
Author: Paolo Bonzini <pbonzini at redhat.com>
Date:   Wed Aug 3 10:49:16 2011 +0200

    scsi: add a bunch more common sense codes
    
    Signed-off-by: Paolo Bonzini <pbonzini at redhat.com>
    Signed-off-by: Anthony Liguori <aliguori at us.ibm.com>

diff --git a/hw/scsi-bus.c b/hw/scsi-bus.c
index ab45226..bec8d82 100644
--- a/hw/scsi-bus.c
+++ b/hw/scsi-bus.c
@@ -696,6 +696,16 @@ const struct SCSISense sense_code_LUN_NOT_SUPPORTED = {
     .key = ILLEGAL_REQUEST, .asc = 0x25, .ascq = 0x00
 };
 
+/* Illegal request, Saving parameters not supported */
+const struct SCSISense sense_code_SAVING_PARAMS_NOT_SUPPORTED = {
+    .key = ILLEGAL_REQUEST, .asc = 0x39, .ascq = 0x00
+};
+
+/* Illegal request, Incompatible medium installed */
+const struct SCSISense sense_code_INCOMPATIBLE_MEDIUM = {
+    .key = ILLEGAL_REQUEST, .asc = 0x30, .ascq = 0x00
+};
+
 /* Command aborted, I/O process terminated */
 const struct SCSISense sense_code_IO_ERROR = {
     .key = ABORTED_COMMAND, .asc = 0x00, .ascq = 0x06
@@ -711,6 +721,26 @@ const struct SCSISense sense_code_LUN_FAILURE = {
     .key = ABORTED_COMMAND, .asc = 0x3e, .ascq = 0x01
 };
 
+/* Unit attention, Power on, reset or bus device reset occurred */
+const struct SCSISense sense_code_RESET = {
+    .key = UNIT_ATTENTION, .asc = 0x29, .ascq = 0x00
+};
+
+/* Unit attention, Medium may have changed */
+const struct SCSISense sense_code_MEDIUM_CHANGED = {
+    .key = UNIT_ATTENTION, .asc = 0x28, .ascq = 0x00
+};
+
+/* Unit attention, Reported LUNs data has changed */
+const struct SCSISense sense_code_REPORTED_LUNS_CHANGED = {
+    .key = UNIT_ATTENTION, .asc = 0x3f, .ascq = 0x0e
+};
+
+/* Unit attention, Device internal reset */
+const struct SCSISense sense_code_DEVICE_INTERNAL_RESET = {
+    .key = UNIT_ATTENTION, .asc = 0x29, .ascq = 0x04
+};
+
 /*
  * scsi_build_sense
  *
diff --git a/hw/scsi.h b/hw/scsi.h
index dec814a..4d5b596 100644
--- a/hw/scsi.h
+++ b/hw/scsi.h
@@ -144,12 +144,24 @@ extern const struct SCSISense sense_code_LBA_OUT_OF_RANGE;
 extern const struct SCSISense sense_code_INVALID_FIELD;
 /* Illegal request, LUN not supported */
 extern const struct SCSISense sense_code_LUN_NOT_SUPPORTED;
+/* Illegal request, Saving parameters not supported */
+extern const struct SCSISense sense_code_SAVING_PARAMS_NOT_SUPPORTED;
+/* Illegal request, Incompatible format */
+extern const struct SCSISense sense_code_INCOMPATIBLE_FORMAT;
 /* Command aborted, I/O process terminated */
 extern const struct SCSISense sense_code_IO_ERROR;
 /* Command aborted, I_T Nexus loss occurred */
 extern const struct SCSISense sense_code_I_T_NEXUS_LOSS;
 /* Command aborted, Logical Unit failure */
 extern const struct SCSISense sense_code_LUN_FAILURE;
+/* Unit attention, Power on, reset or bus device reset occurred */
+extern const struct SCSISense sense_code_RESET;
+/* Unit attention, Medium may have changed*/
+extern const struct SCSISense sense_code_MEDIUM_CHANGED;
+/* Unit attention, Reported LUNs data has changed */
+extern const struct SCSISense sense_code_REPORTED_LUNS_CHANGED;
+/* Unit attention, Device internal reset */
+extern const struct SCSISense sense_code_DEVICE_INTERNAL_RESET;
 
 #define SENSE_CODE(x) sense_code_ ## x
 
commit 739df2150d7e6291d54b3d2dcbd9ed52078e991c
Author: Paolo Bonzini <pbonzini at redhat.com>
Date:   Wed Aug 3 10:49:15 2011 +0200

    scsi: move handling of REQUEST SENSE to common code
    
    Signed-off-by: Paolo Bonzini <pbonzini at redhat.com>
    Signed-off-by: Anthony Liguori <aliguori at us.ibm.com>

diff --git a/hw/scsi-bus.c b/hw/scsi-bus.c
index 8b229af..ab45226 100644
--- a/hw/scsi-bus.c
+++ b/hw/scsi-bus.c
@@ -270,6 +270,13 @@ static int32_t scsi_target_send_command(SCSIRequest *req, uint8_t *buf)
             goto illegal_request;
         }
         break;
+    case REQUEST_SENSE:
+        if (req->cmd.xfer < 4) {
+            goto illegal_request;
+        }
+        r->len = scsi_device_get_sense(r->req.dev, r->buf, req->cmd.xfer,
+                                       (req->cmd.buf[1] & 1) == 0);
+        break;
     default:
         scsi_req_build_sense(req, SENSE_CODE(LUN_NOT_SUPPORTED));
         scsi_req_complete(req, CHECK_CONDITION);
@@ -351,8 +358,9 @@ SCSIRequest *scsi_req_new(SCSIDevice *d, uint32_t tag, uint32_t lun,
                                       cmd.lba);
         }
 
-        if ((lun != d->lun && buf[0] != REQUEST_SENSE) ||
-            buf[0] == REPORT_LUNS) {
+        if (lun != d->lun ||
+            buf[0] == REPORT_LUNS ||
+            buf[0] == REQUEST_SENSE) {
             req = scsi_req_alloc(&reqops_target_command, d, tag, lun,
                                  hba_private);
         } else {
diff --git a/hw/scsi-disk.c b/hw/scsi-disk.c
index fe7368b..a33da55 100644
--- a/hw/scsi-disk.c
+++ b/hw/scsi-disk.c
@@ -788,12 +788,6 @@ static int scsi_disk_emulate_command(SCSIDiskReq *r, uint8_t *outbuf)
         if (!bdrv_is_inserted(s->bs))
             goto not_ready;
         break;
-    case REQUEST_SENSE:
-        if (req->cmd.xfer < 4)
-            goto illegal_request;
-        buflen = scsi_device_get_sense(&s->qdev, outbuf, req->cmd.xfer,
-                                       (req->cmd.buf[1] & 1) == 0);
-        break;
     case INQUIRY:
         buflen = scsi_disk_emulate_inquiry(req, outbuf);
         if (buflen < 0)
@@ -964,7 +958,6 @@ static int32_t scsi_send_command(SCSIRequest *req, uint8_t *buf)
 
     switch (command) {
     case TEST_UNIT_READY:
-    case REQUEST_SENSE:
     case INQUIRY:
     case MODE_SENSE:
     case MODE_SENSE_10:
@@ -1063,6 +1056,8 @@ static int32_t scsi_send_command(SCSIRequest *req, uint8_t *buf)
         }
 
         break;
+    case REQUEST_SENSE:
+        abort();
     default:
         DPRINTF("Unknown SCSI command (%2.2x)\n", buf[0]);
         scsi_check_condition(r, SENSE_CODE(INVALID_OPCODE));
diff --git a/hw/scsi-generic.c b/hw/scsi-generic.c
index 70265d0..83723ac 100644
--- a/hw/scsi-generic.c
+++ b/hw/scsi-generic.c
@@ -183,22 +183,6 @@ static void scsi_read_data(SCSIRequest *req)
         return;
     }
 
-    if (r->req.cmd.buf[0] == REQUEST_SENSE) {
-        r->io_header.driver_status = 0;
-        r->io_header.status = 0;
-        r->io_header.dxfer_len =
-            scsi_device_get_sense(&s->qdev, r->buf, r->req.cmd.xfer,
-                                  (r->req.cmd.buf[1] & 1) == 0);
-        r->len = -1;
-        DPRINTF("Data ready tag=0x%x len=%d\n", r->req.tag, r->io_header.dxfer_len);
-        DPRINTF("Sense: %d %d %d %d %d %d %d %d\n",
-                r->buf[0], r->buf[1], r->buf[2], r->buf[3],
-                r->buf[4], r->buf[5], r->buf[6], r->buf[7]);
-        scsi_req_data(&r->req, r->io_header.dxfer_len);
-        /* The sense buffer is cleared when we return GOOD */
-        return;
-    }
-
     ret = execute_command(s->bs, r, SG_DXFER_FROM_DEV, scsi_read_complete);
     if (ret < 0) {
         scsi_command_complete(r, ret);
commit fdaef06917100d97782df550c1807a1da054e27e
Author: Paolo Bonzini <pbonzini at redhat.com>
Date:   Wed Aug 3 10:49:14 2011 +0200

    scsi: move handling of REPORT LUNS and invalid LUNs to common code
    
    Signed-off-by: Paolo Bonzini <pbonzini at redhat.com>
    Signed-off-by: Anthony Liguori <aliguori at us.ibm.com>

diff --git a/hw/scsi-bus.c b/hw/scsi-bus.c
index c7e7b08..8b229af 100644
--- a/hw/scsi-bus.c
+++ b/hw/scsi-bus.c
@@ -149,6 +149,172 @@ struct SCSIReqOps reqops_invalid_opcode = {
     .send_command = scsi_invalid_command
 };
 
+/* SCSIReqOps implementation for REPORT LUNS and for commands sent to
+   an invalid LUN.  */
+
+typedef struct SCSITargetReq SCSITargetReq;
+
+struct SCSITargetReq {
+    SCSIRequest req;
+    int len;
+    uint8_t buf[64];
+};
+
+static void store_lun(uint8_t *outbuf, int lun)
+{
+    if (lun < 256) {
+        outbuf[1] = lun;
+        return;
+    }
+    outbuf[1] = (lun & 255);
+    outbuf[0] = (lun >> 8) | 0x40;
+}
+
+static bool scsi_target_emulate_report_luns(SCSITargetReq *r)
+{
+    int len;
+    if (r->req.cmd.xfer < 16) {
+        return false;
+    }
+    if (r->req.cmd.buf[2] > 2) {
+        return false;
+    }
+    len = MIN(sizeof r->buf, r->req.cmd.xfer);
+    memset(r->buf, 0, len);
+    if (r->req.dev->lun != 0) {
+        r->buf[3] = 16;
+        r->len = 24;
+        store_lun(&r->buf[16], r->req.dev->lun);
+    } else {
+        r->buf[3] = 8;
+        r->len = 16;
+    }
+    return true;
+}
+
+static bool scsi_target_emulate_inquiry(SCSITargetReq *r)
+{
+    assert(r->req.dev->lun != r->req.lun);
+    if (r->req.cmd.buf[1] & 0x2) {
+        /* Command support data - optional, not implemented */
+        return false;
+    }
+
+    if (r->req.cmd.buf[1] & 0x1) {
+        /* Vital product data */
+        uint8_t page_code = r->req.cmd.buf[2];
+        if (r->req.cmd.xfer < 4) {
+            return false;
+        }
+
+        r->buf[r->len++] = page_code ; /* this page */
+        r->buf[r->len++] = 0x00;
+
+        switch (page_code) {
+        case 0x00: /* Supported page codes, mandatory */
+        {
+            int pages;
+            pages = r->len++;
+            r->buf[r->len++] = 0x00; /* list of supported pages (this page) */
+            r->buf[pages] = r->len - pages - 1; /* number of pages */
+            break;
+        }
+        default:
+            return false;
+        }
+        /* done with EVPD */
+        assert(r->len < sizeof(r->buf));
+        r->len = MIN(r->req.cmd.xfer, r->len);
+        return true;
+    }
+
+    /* Standard INQUIRY data */
+    if (r->req.cmd.buf[2] != 0) {
+        return false;
+    }
+
+    /* PAGE CODE == 0 */
+    if (r->req.cmd.xfer < 5) {
+        return -1;
+    }
+
+    r->len = MIN(r->req.cmd.xfer, 36);
+    memset(r->buf, 0, r->len);
+    if (r->req.lun != 0) {
+        r->buf[0] = TYPE_NO_LUN;
+    } else {
+        r->buf[0] = TYPE_NOT_PRESENT | TYPE_INACTIVE;
+        r->buf[2] = 5; /* Version */
+        r->buf[3] = 2 | 0x10; /* HiSup, response data format */
+        r->buf[4] = r->len - 5; /* Additional Length = (Len - 1) - 4 */
+        r->buf[7] = 0x10 | (r->req.bus->tcq ? 0x02 : 0); /* Sync, TCQ.  */
+        memcpy(&r->buf[8], "QEMU    ", 8);
+        memcpy(&r->buf[16], "QEMU TARGET     ", 16);
+        strncpy((char *) &r->buf[32], QEMU_VERSION, 4);
+    }
+    return true;
+}
+
+static int32_t scsi_target_send_command(SCSIRequest *req, uint8_t *buf)
+{
+    SCSITargetReq *r = DO_UPCAST(SCSITargetReq, req, req);
+
+    switch (buf[0]) {
+    case REPORT_LUNS:
+        if (!scsi_target_emulate_report_luns(r)) {
+            goto illegal_request;
+        }
+        break;
+    case INQUIRY:
+        if (!scsi_target_emulate_inquiry(r)) {
+            goto illegal_request;
+        }
+        break;
+    default:
+        scsi_req_build_sense(req, SENSE_CODE(LUN_NOT_SUPPORTED));
+        scsi_req_complete(req, CHECK_CONDITION);
+        return 0;
+    illegal_request:
+        scsi_req_build_sense(req, SENSE_CODE(INVALID_FIELD));
+        scsi_req_complete(req, CHECK_CONDITION);
+        return 0;
+    }
+
+    if (!r->len) {
+        scsi_req_complete(req, GOOD);
+    }
+    return r->len;
+}
+
+static void scsi_target_read_data(SCSIRequest *req)
+{
+    SCSITargetReq *r = DO_UPCAST(SCSITargetReq, req, req);
+    uint32_t n;
+
+    n = r->len;
+    if (n > 0) {
+        r->len = 0;
+        scsi_req_data(&r->req, n);
+    } else {
+        scsi_req_complete(&r->req, GOOD);
+    }
+}
+
+static uint8_t *scsi_target_get_buf(SCSIRequest *req)
+{
+    SCSITargetReq *r = DO_UPCAST(SCSITargetReq, req, req);
+
+    return r->buf;
+}
+
+struct SCSIReqOps reqops_target_command = {
+    .size         = sizeof(SCSITargetReq),
+    .send_command = scsi_target_send_command,
+    .read_data    = scsi_target_read_data,
+    .get_buf      = scsi_target_get_buf,
+};
+
+
 SCSIRequest *scsi_req_alloc(SCSIReqOps *reqops, SCSIDevice *d, uint32_t tag,
                             uint32_t lun, void *hba_private)
 {
@@ -184,7 +350,14 @@ SCSIRequest *scsi_req_new(SCSIDevice *d, uint32_t tag, uint32_t lun,
             trace_scsi_req_parsed_lba(d->id, lun, tag, buf[0],
                                       cmd.lba);
         }
-        req = d->info->alloc_req(d, tag, lun, hba_private);
+
+        if ((lun != d->lun && buf[0] != REQUEST_SENSE) ||
+            buf[0] == REPORT_LUNS) {
+            req = scsi_req_alloc(&reqops_target_command, d, tag, lun,
+                                 hba_private);
+        } else {
+            req = d->info->alloc_req(d, tag, lun, hba_private);
+        }
     }
 
     req->cmd = cmd;
diff --git a/hw/scsi-defs.h b/hw/scsi-defs.h
index 27010b7..977c38b 100644
--- a/hw/scsi-defs.h
+++ b/hw/scsi-defs.h
@@ -176,5 +176,8 @@
 #define TYPE_ENCLOSURE      0x0d    /* Enclosure Services Device */
 #define TYPE_RBC            0x0e    /* Simplified Direct-Access Device */
 #define TYPE_OSD            0x11    /* Object-storage Device */
+#define TYPE_WLUN           0x1e    /* Well known LUN */
+#define TYPE_NOT_PRESENT    0x1f
+#define TYPE_INACTIVE       0x20
 #define TYPE_NO_LUN         0x7f
 
diff --git a/hw/scsi-disk.c b/hw/scsi-disk.c
index 1abf909..fe7368b 100644
--- a/hw/scsi-disk.c
+++ b/hw/scsi-disk.c
@@ -482,11 +482,6 @@ static int scsi_disk_emulate_inquiry(SCSIRequest *req, uint8_t *outbuf)
 
     memset(outbuf, 0, buflen);
 
-    if (req->lun) {
-        outbuf[0] = 0x7f;       /* LUN not supported */
-        return buflen;
-    }
-
     outbuf[0] = s->qdev.type & 0x1f;
     if (s->qdev.type == TYPE_ROM) {
         outbuf[1] = 0x80;
@@ -918,13 +913,6 @@ static int scsi_disk_emulate_command(SCSIDiskReq *r, uint8_t *outbuf)
         }
         DPRINTF("Unsupported Service Action In\n");
         goto illegal_request;
-    case REPORT_LUNS:
-        if (req->cmd.xfer < 16)
-            goto illegal_request;
-        memset(outbuf, 0, 16);
-        outbuf[3] = 8;
-        buflen = 16;
-        break;
     case VERIFY_10:
         break;
     default:
@@ -974,14 +962,6 @@ static int32_t scsi_send_command(SCSIRequest *req, uint8_t *buf)
     }
 #endif
 
-    if (req->lun) {
-        /* Only LUN 0 supported.  */
-        DPRINTF("Unimplemented LUN %d\n", req->lun);
-        if (command != REQUEST_SENSE && command != INQUIRY) {
-            scsi_check_condition(r, SENSE_CODE(LUN_NOT_SUPPORTED));
-            return 0;
-        }
-    }
     switch (command) {
     case TEST_UNIT_READY:
     case REQUEST_SENSE:
@@ -999,7 +979,6 @@ static int32_t scsi_send_command(SCSIRequest *req, uint8_t *buf)
     case READ_TOC:
     case GET_CONFIGURATION:
     case SERVICE_ACTION_IN:
-    case REPORT_LUNS:
     case VERIFY_10:
         rc = scsi_disk_emulate_command(r, outbuf);
         if (rc < 0) {
diff --git a/hw/scsi-generic.c b/hw/scsi-generic.c
index 3b43f1c..70265d0 100644
--- a/hw/scsi-generic.c
+++ b/hw/scsi-generic.c
@@ -287,13 +287,6 @@ static int32_t scsi_send_command(SCSIRequest *req, uint8_t *cmd)
     SCSIGenericReq *r = DO_UPCAST(SCSIGenericReq, req, req);
     int ret;
 
-    if (cmd[0] != REQUEST_SENSE && req->lun != s->qdev.lun) {
-        DPRINTF("Unimplemented LUN %d\n", req->lun);
-        scsi_req_build_sense(&r->req, SENSE_CODE(LUN_NOT_SUPPORTED));
-        scsi_req_complete(&r->req, CHECK_CONDITION);
-        return 0;
-    }
-
     scsi_req_fixup(&r->req);
 
     DPRINTF("Command: lun=%d tag=0x%x len %zd data=0x%02x", lun, tag,
commit afa46c468acc18914c2773538f1b088c507766ee
Author: Paolo Bonzini <pbonzini at redhat.com>
Date:   Wed Aug 3 10:49:13 2011 +0200

    scsi: move request parsing to common code
    
    Also introduce the first occurrence of "independent" SCSIReqOps,
    to handle invalid commands in common code.
    
    Signed-off-by: Paolo Bonzini <pbonzini at redhat.com>
    Signed-off-by: Anthony Liguori <aliguori at us.ibm.com>

diff --git a/hw/scsi-bus.c b/hw/scsi-bus.c
index 3ae6762..c7e7b08 100644
--- a/hw/scsi-bus.c
+++ b/hw/scsi-bus.c
@@ -7,6 +7,7 @@
 #include "trace.h"
 
 static char *scsibus_get_fw_dev_path(DeviceState *dev);
+static int scsi_req_parse(SCSICommand *cmd, SCSIDevice *dev, uint8_t *buf);
 static int scsi_build_sense(uint8_t *in_buf, int in_len,
                             uint8_t *buf, int len, bool fixed);
 
@@ -134,6 +135,20 @@ int scsi_bus_legacy_handle_cmdline(SCSIBus *bus)
     return res;
 }
 
+/* SCSIReqOps implementation for invalid commands.  */
+
+static int32_t scsi_invalid_command(SCSIRequest *req, uint8_t *buf)
+{
+    scsi_req_build_sense(req, SENSE_CODE(INVALID_OPCODE));
+    scsi_req_complete(req, CHECK_CONDITION);
+    return 0;
+}
+
+struct SCSIReqOps reqops_invalid_opcode = {
+    .size         = sizeof(SCSIRequest),
+    .send_command = scsi_invalid_command
+};
+
 SCSIRequest *scsi_req_alloc(SCSIReqOps *reqops, SCSIDevice *d, uint32_t tag,
                             uint32_t lun, void *hba_private)
 {
@@ -157,8 +172,22 @@ SCSIRequest *scsi_req_new(SCSIDevice *d, uint32_t tag, uint32_t lun,
                           uint8_t *buf, void *hba_private)
 {
     SCSIRequest *req;
-    req = d->info->alloc_req(d, tag, lun, hba_private);
-    memcpy(req->cmd.buf, buf, 16);
+    SCSICommand cmd;
+
+    if (scsi_req_parse(&cmd, d, buf) != 0) {
+        trace_scsi_req_parse_bad(d->id, lun, tag, buf[0]);
+        req = scsi_req_alloc(&reqops_invalid_opcode, d, tag, lun, hba_private);
+    } else {
+        trace_scsi_req_parsed(d->id, lun, tag, buf[0],
+                              cmd.mode, cmd.xfer);
+        if (req->cmd.lba != -1) {
+            trace_scsi_req_parsed_lba(d->id, lun, tag, buf[0],
+                                      cmd.lba);
+        }
+        req = d->info->alloc_req(d, tag, lun, hba_private);
+    }
+
+    req->cmd = cmd;
     return req;
 }
 
@@ -424,27 +453,21 @@ static uint64_t scsi_cmd_lba(SCSICommand *cmd)
     return lba;
 }
 
-int scsi_req_parse(SCSIRequest *req, uint8_t *buf)
+int scsi_req_parse(SCSICommand *cmd, SCSIDevice *dev, uint8_t *buf)
 {
     int rc;
 
-    if (req->dev->type == TYPE_TAPE) {
-        rc = scsi_req_stream_length(&req->cmd, req->dev, buf);
+    if (dev->type == TYPE_TAPE) {
+        rc = scsi_req_stream_length(cmd, dev, buf);
     } else {
-        rc = scsi_req_length(&req->cmd, req->dev, buf);
+        rc = scsi_req_length(cmd, dev, buf);
     }
     if (rc != 0)
         return rc;
 
-    assert(buf == req->cmd.buf);
-    scsi_cmd_xfer_mode(&req->cmd);
-    req->cmd.lba = scsi_cmd_lba(&req->cmd);
-    trace_scsi_req_parsed(req->dev->id, req->lun, req->tag, buf[0],
-                          req->cmd.mode, req->cmd.xfer);
-    if (req->cmd.lba != -1) {
-        trace_scsi_req_parsed_lba(req->dev->id, req->lun, req->tag, buf[0],
-                              req->cmd.lba);
-    }
+    memcpy(cmd->buf, buf, cmd->len);
+    scsi_cmd_xfer_mode(cmd);
+    cmd->lba = scsi_cmd_lba(cmd);
     return 0;
 }
 
diff --git a/hw/scsi-disk.c b/hw/scsi-disk.c
index eda4f8e..1abf909 100644
--- a/hw/scsi-disk.c
+++ b/hw/scsi-disk.c
@@ -964,11 +964,6 @@ static int32_t scsi_send_command(SCSIRequest *req, uint8_t *buf)
     outbuf = (uint8_t *)r->iov.iov_base;
     DPRINTF("Command: lun=%d tag=0x%x data=0x%02x", req->lun, req->tag, buf[0]);
 
-    if (scsi_req_parse(&r->req, buf) != 0) {
-        BADF("Unsupported command length, command %x\n", command);
-        scsi_check_condition(r, SENSE_CODE(INVALID_OPCODE));
-        return 0;
-    }
 #ifdef DEBUG_SCSI
     {
         int i;
diff --git a/hw/scsi-generic.c b/hw/scsi-generic.c
index 8046ea6..3b43f1c 100644
--- a/hw/scsi-generic.c
+++ b/hw/scsi-generic.c
@@ -84,10 +84,6 @@ static void scsi_command_complete(void *opaque, int ret)
         case -EDOM:
             status = TASK_SET_FULL;
             break;
-        case -EINVAL:
-            status = CHECK_CONDITION;
-            scsi_req_build_sense(&r->req, SENSE_CODE(INVALID_FIELD));
-            break;
         case -ENOMEM:
             status = CHECK_CONDITION;
             scsi_req_build_sense(&r->req, SENSE_CODE(TARGET_FAILURE));
@@ -298,11 +294,6 @@ static int32_t scsi_send_command(SCSIRequest *req, uint8_t *cmd)
         return 0;
     }
 
-    if (-1 == scsi_req_parse(&r->req, cmd)) {
-        BADF("Unsupported command length, command %x\n", cmd[0]);
-        scsi_command_complete(r, -EINVAL);
-        return 0;
-    }
     scsi_req_fixup(&r->req);
 
     DPRINTF("Command: lun=%d tag=0x%x len %zd data=0x%02x", lun, tag,
diff --git a/hw/scsi.h b/hw/scsi.h
index 5a1bbe2..dec814a 100644
--- a/hw/scsi.h
+++ b/hw/scsi.h
@@ -165,7 +165,6 @@ SCSIRequest *scsi_req_ref(SCSIRequest *req);
 void scsi_req_unref(SCSIRequest *req);
 
 void scsi_req_build_sense(SCSIRequest *req, SCSISense sense);
-int scsi_req_parse(SCSIRequest *req, uint8_t *buf);
 void scsi_req_print(SCSIRequest *req);
 void scsi_req_continue(SCSIRequest *req);
 void scsi_req_data(SCSIRequest *req, int len);
commit 87dcd1b2c27e88a47be5036e9cf4c2767054eb31
Author: Paolo Bonzini <pbonzini at redhat.com>
Date:   Wed Aug 3 10:49:12 2011 +0200

    scsi: push lun field to SCSIDevice
    
    This will let SCSIBus detect requests sent to an invalid LUN, and
    handle them itself.  However, there will be still support for only one
    LUN per target
    
    Signed-off-by: Paolo Bonzini <pbonzini at redhat.com>
    Signed-off-by: Anthony Liguori <aliguori at us.ibm.com>

diff --git a/hw/scsi-bus.c b/hw/scsi-bus.c
index b52b9d2..3ae6762 100644
--- a/hw/scsi-bus.c
+++ b/hw/scsi-bus.c
@@ -16,6 +16,7 @@ static struct BusInfo scsi_bus_info = {
     .get_fw_dev_path = scsibus_get_fw_dev_path,
     .props = (Property[]) {
         DEFINE_PROP_UINT32("scsi-id", SCSIDevice, id, -1),
+        DEFINE_PROP_UINT32("lun", SCSIDevice, lun, 0),
         DEFINE_PROP_END_OF_LIST(),
     },
 };
diff --git a/hw/scsi-generic.c b/hw/scsi-generic.c
index c2bd399..8046ea6 100644
--- a/hw/scsi-generic.c
+++ b/hw/scsi-generic.c
@@ -60,7 +60,6 @@ struct SCSIGenericState
 {
     SCSIDevice qdev;
     BlockDriverState *bs;
-    int lun;
 };
 
 static void scsi_free_request(SCSIRequest *req)
@@ -292,7 +291,7 @@ static int32_t scsi_send_command(SCSIRequest *req, uint8_t *cmd)
     SCSIGenericReq *r = DO_UPCAST(SCSIGenericReq, req, req);
     int ret;
 
-    if (cmd[0] != REQUEST_SENSE && req->lun != s->lun) {
+    if (cmd[0] != REQUEST_SENSE && req->lun != s->qdev.lun) {
         DPRINTF("Unimplemented LUN %d\n", req->lun);
         scsi_req_build_sense(&r->req, SENSE_CODE(LUN_NOT_SUPPORTED));
         scsi_req_complete(&r->req, CHECK_CONDITION);
@@ -466,8 +465,6 @@ static int scsi_generic_initfn(SCSIDevice *dev)
     }
 
     /* define device state */
-    s->lun = scsiid.lun;
-    DPRINTF("LUN %d\n", s->lun);
     s->qdev.type = scsiid.scsi_type;
     DPRINTF("device type %d\n", s->qdev.type);
     if (s->qdev.type == TYPE_TAPE) {
diff --git a/hw/scsi.h b/hw/scsi.h
index f29d65f..5a1bbe2 100644
--- a/hw/scsi.h
+++ b/hw/scsi.h
@@ -65,6 +65,7 @@ struct SCSIDevice
     uint8_t sense[SCSI_SENSE_BUF_SIZE];
     uint32_t sense_len;
     QTAILQ_HEAD(, SCSIRequest) requests;
+    uint32_t lun;
     int blocksize;
     int type;
 };
commit 2599aece1b222ad4f9714275b38bf1d3e9424b54
Author: Paolo Bonzini <pbonzini at redhat.com>
Date:   Wed Aug 3 10:49:11 2011 +0200

    scsi: introduce SCSICommand
    
    This struct is currently unnamed.  Give it a name and use it
    explicitly to decouple (some parts of) CDB parsing from
    SCSIRequest.
    
    Signed-off-by: Paolo Bonzini <pbonzini at redhat.com>
    Signed-off-by: Anthony Liguori <aliguori at us.ibm.com>

diff --git a/hw/scsi-bus.c b/hw/scsi-bus.c
index 7b5a9ce..b52b9d2 100644
--- a/hw/scsi-bus.c
+++ b/hw/scsi-bus.c
@@ -217,35 +217,35 @@ static void scsi_req_dequeue(SCSIRequest *req)
     }
 }
 
-static int scsi_req_length(SCSIRequest *req, uint8_t *cmd)
+static int scsi_req_length(SCSICommand *cmd, SCSIDevice *dev, uint8_t *buf)
 {
-    switch (cmd[0] >> 5) {
+    switch (buf[0] >> 5) {
     case 0:
-        req->cmd.xfer = cmd[4];
-        req->cmd.len = 6;
+        cmd->xfer = buf[4];
+        cmd->len = 6;
         /* length 0 means 256 blocks */
-        if (req->cmd.xfer == 0)
-            req->cmd.xfer = 256;
+        if (cmd->xfer == 0) {
+            cmd->xfer = 256;
+        }
         break;
     case 1:
     case 2:
-        req->cmd.xfer = cmd[8] | (cmd[7] << 8);
-        req->cmd.len = 10;
+        cmd->xfer = buf[8] | (buf[7] << 8);
+        cmd->len = 10;
         break;
     case 4:
-        req->cmd.xfer = cmd[13] | (cmd[12] << 8) | (cmd[11] << 16) | (cmd[10] << 24);
-        req->cmd.len = 16;
+        cmd->xfer = buf[13] | (buf[12] << 8) | (buf[11] << 16) | (buf[10] << 24);
+        cmd->len = 16;
         break;
     case 5:
-        req->cmd.xfer = cmd[9] | (cmd[8] << 8) | (cmd[7] << 16) | (cmd[6] << 24);
-        req->cmd.len = 12;
+        cmd->xfer = buf[9] | (buf[8] << 8) | (buf[7] << 16) | (buf[6] << 24);
+        cmd->len = 12;
         break;
     default:
-        trace_scsi_req_parse_bad(req->dev->id, req->lun, req->tag, cmd[0]);
         return -1;
     }
 
-    switch(cmd[0]) {
+    switch (buf[0]) {
     case TEST_UNIT_READY:
     case REWIND:
     case START_STOP:
@@ -266,27 +266,27 @@ static int scsi_req_length(SCSIRequest *req, uint8_t *cmd)
     case WRITE_LONG_10:
     case MOVE_MEDIUM:
     case UPDATE_BLOCK:
-        req->cmd.xfer = 0;
+        cmd->xfer = 0;
         break;
     case MODE_SENSE:
         break;
     case WRITE_SAME_10:
-        req->cmd.xfer = 1;
+        cmd->xfer = 1;
         break;
     case READ_CAPACITY_10:
-        req->cmd.xfer = 8;
+        cmd->xfer = 8;
         break;
     case READ_BLOCK_LIMITS:
-        req->cmd.xfer = 6;
+        cmd->xfer = 6;
         break;
     case READ_POSITION:
-        req->cmd.xfer = 20;
+        cmd->xfer = 20;
         break;
     case SEND_VOLUME_TAG:
-        req->cmd.xfer *= 40;
+        cmd->xfer *= 40;
         break;
     case MEDIUM_SCAN:
-        req->cmd.xfer *= 8;
+        cmd->xfer *= 8;
         break;
     case WRITE_10:
     case WRITE_VERIFY_10:
@@ -295,7 +295,7 @@ static int scsi_req_length(SCSIRequest *req, uint8_t *cmd)
     case WRITE_VERIFY_12:
     case WRITE_16:
     case WRITE_VERIFY_16:
-        req->cmd.xfer *= req->dev->blocksize;
+        cmd->xfer *= dev->blocksize;
         break;
     case READ_10:
     case READ_6:
@@ -303,50 +303,51 @@ static int scsi_req_length(SCSIRequest *req, uint8_t *cmd)
     case RECOVER_BUFFERED_DATA:
     case READ_12:
     case READ_16:
-        req->cmd.xfer *= req->dev->blocksize;
+        cmd->xfer *= dev->blocksize;
         break;
     case INQUIRY:
-        req->cmd.xfer = cmd[4] | (cmd[3] << 8);
+        cmd->xfer = buf[4] | (buf[3] << 8);
         break;
     case MAINTENANCE_OUT:
     case MAINTENANCE_IN:
-        if (req->dev->type == TYPE_ROM) {
+        if (dev->type == TYPE_ROM) {
             /* GPCMD_REPORT_KEY and GPCMD_SEND_KEY from multi media commands */
-            req->cmd.xfer = cmd[9] | (cmd[8] << 8);
+            cmd->xfer = buf[9] | (buf[8] << 8);
         }
         break;
     }
     return 0;
 }
 
-static int scsi_req_stream_length(SCSIRequest *req, uint8_t *cmd)
+static int scsi_req_stream_length(SCSICommand *cmd, SCSIDevice *dev, uint8_t *buf)
 {
-    switch(cmd[0]) {
+    switch (buf[0]) {
     /* stream commands */
     case READ_6:
     case READ_REVERSE:
     case RECOVER_BUFFERED_DATA:
     case WRITE_6:
-        req->cmd.len = 6;
-        req->cmd.xfer = cmd[4] | (cmd[3] << 8) | (cmd[2] << 16);
-        if (cmd[1] & 0x01) /* fixed */
-            req->cmd.xfer *= req->dev->blocksize;
+        cmd->len = 6;
+        cmd->xfer = buf[4] | (buf[3] << 8) | (buf[2] << 16);
+        if (buf[1] & 0x01) { /* fixed */
+            cmd->xfer *= dev->blocksize;
+        }
         break;
     case REWIND:
     case START_STOP:
-        req->cmd.len = 6;
-        req->cmd.xfer = 0;
+        cmd->len = 6;
+        cmd->xfer = 0;
         break;
     /* generic commands */
     default:
-        return scsi_req_length(req, cmd);
+        return scsi_req_length(cmd, dev, buf);
     }
     return 0;
 }
 
-static void scsi_req_xfer_mode(SCSIRequest *req)
+static void scsi_cmd_xfer_mode(SCSICommand *cmd)
 {
-    switch (req->cmd.buf[0]) {
+    switch (cmd->buf[0]) {
     case WRITE_6:
     case WRITE_10:
     case WRITE_VERIFY_10:
@@ -378,21 +379,21 @@ static void scsi_req_xfer_mode(SCSIRequest *req)
     case SEND_VOLUME_TAG:
     case PERSISTENT_RESERVE_OUT:
     case MAINTENANCE_OUT:
-        req->cmd.mode = SCSI_XFER_TO_DEV;
+        cmd->mode = SCSI_XFER_TO_DEV;
         break;
     default:
-        if (req->cmd.xfer)
-            req->cmd.mode = SCSI_XFER_FROM_DEV;
+        if (cmd->xfer)
+            cmd->mode = SCSI_XFER_FROM_DEV;
         else {
-            req->cmd.mode = SCSI_XFER_NONE;
+            cmd->mode = SCSI_XFER_NONE;
         }
         break;
     }
 }
 
-static uint64_t scsi_req_lba(SCSIRequest *req)
+static uint64_t scsi_cmd_lba(SCSICommand *cmd)
 {
-    uint8_t *buf = req->cmd.buf;
+    uint8_t *buf = cmd->buf;
     uint64_t lba;
 
     switch (buf[0] >> 5) {
@@ -427,16 +428,16 @@ int scsi_req_parse(SCSIRequest *req, uint8_t *buf)
     int rc;
 
     if (req->dev->type == TYPE_TAPE) {
-        rc = scsi_req_stream_length(req, buf);
+        rc = scsi_req_stream_length(&req->cmd, req->dev, buf);
     } else {
-        rc = scsi_req_length(req, buf);
+        rc = scsi_req_length(&req->cmd, req->dev, buf);
     }
     if (rc != 0)
         return rc;
 
     assert(buf == req->cmd.buf);
-    scsi_req_xfer_mode(req);
-    req->cmd.lba = scsi_req_lba(req);
+    scsi_cmd_xfer_mode(&req->cmd);
+    req->cmd.lba = scsi_cmd_lba(&req->cmd);
     trace_scsi_req_parsed(req->dev->id, req->lun, req->tag, buf[0],
                           req->cmd.mode, req->cmd.xfer);
     if (req->cmd.lba != -1) {
diff --git a/hw/scsi.h b/hw/scsi.h
index 7ed7550..f29d65f 100644
--- a/hw/scsi.h
+++ b/hw/scsi.h
@@ -11,6 +11,7 @@
 
 typedef struct SCSIBus SCSIBus;
 typedef struct SCSIBusOps SCSIBusOps;
+typedef struct SCSICommand SCSICommand;
 typedef struct SCSIDevice SCSIDevice;
 typedef struct SCSIDeviceInfo SCSIDeviceInfo;
 typedef struct SCSIRequest SCSIRequest;
@@ -30,6 +31,14 @@ typedef struct SCSISense {
 
 #define SCSI_SENSE_BUF_SIZE 96
 
+struct SCSICommand {
+    uint8_t buf[SCSI_CMD_BUF_SIZE];
+    int len;
+    size_t xfer;
+    uint64_t lba;
+    enum SCSIXferMode mode;
+};
+
 struct SCSIRequest {
     SCSIBus           *bus;
     SCSIDevice        *dev;
@@ -38,13 +47,7 @@ struct SCSIRequest {
     uint32_t          tag;
     uint32_t          lun;
     uint32_t          status;
-    struct {
-        uint8_t buf[SCSI_CMD_BUF_SIZE];
-        int len;
-        size_t xfer;
-        uint64_t lba;
-        enum SCSIXferMode mode;
-    } cmd;
+    SCSICommand       cmd;
     BlockDriverAIOCB  *aiocb;
     uint8_t sense[SCSI_SENSE_BUF_SIZE];
     uint32_t sense_len;
commit c39ce112b60ffafbaf700853e32bea74cbb2c148
Author: Paolo Bonzini <pbonzini at redhat.com>
Date:   Wed Aug 3 10:49:10 2011 +0200

    scsi: pass cdb already to scsi_req_new
    
    Right now the CDB is not passed to the SCSIBus until scsi_req_enqueue.
    Passing it to scsi_req_new will let scsi_req_new dispatch common requests
    through different reqops.
    
    Moving the memcpy to scsi_req_new is a hack that will go away as
    soon as scsi_req_new will also take care of the parsing.
    
    Signed-off-by: Paolo Bonzini <pbonzini at redhat.com>
    Signed-off-by: Anthony Liguori <aliguori at us.ibm.com>

diff --git a/hw/esp.c b/hw/esp.c
index 9ddd637..be3a35d 100644
--- a/hw/esp.c
+++ b/hw/esp.c
@@ -244,8 +244,8 @@ static void do_busid_cmd(ESPState *s, uint8_t *buf, uint8_t busid)
 
     DPRINTF("do_busid_cmd: busid 0x%x\n", busid);
     lun = busid & 7;
-    s->current_req = scsi_req_new(s->current_dev, 0, lun, NULL);
-    datalen = scsi_req_enqueue(s->current_req, buf);
+    s->current_req = scsi_req_new(s->current_dev, 0, lun, buf, NULL);
+    datalen = scsi_req_enqueue(s->current_req);
     s->ti_size = datalen;
     if (datalen != 0) {
         s->rregs[ESP_RSTAT] = STAT_TC;
diff --git a/hw/lsi53c895a.c b/hw/lsi53c895a.c
index d067a02..41c2fb0 100644
--- a/hw/lsi53c895a.c
+++ b/hw/lsi53c895a.c
@@ -781,10 +781,10 @@ static void lsi_do_command(LSIState *s)
     assert(s->current == NULL);
     s->current = qemu_mallocz(sizeof(lsi_request));
     s->current->tag = s->select_tag;
-    s->current->req = scsi_req_new(dev, s->current->tag, s->current_lun,
+    s->current->req = scsi_req_new(dev, s->current->tag, s->current_lun, buf,
                                    s->current);
 
-    n = scsi_req_enqueue(s->current->req, buf);
+    n = scsi_req_enqueue(s->current->req);
     if (n) {
         if (n > 0) {
             lsi_set_phase(s, PHASE_DI);
diff --git a/hw/scsi-bus.c b/hw/scsi-bus.c
index df28cc8..7b5a9ce 100644
--- a/hw/scsi-bus.c
+++ b/hw/scsi-bus.c
@@ -153,9 +153,12 @@ SCSIRequest *scsi_req_alloc(SCSIReqOps *reqops, SCSIDevice *d, uint32_t tag,
 }
 
 SCSIRequest *scsi_req_new(SCSIDevice *d, uint32_t tag, uint32_t lun,
-                          void *hba_private)
+                          uint8_t *buf, void *hba_private)
 {
-    return d->info->alloc_req(d, tag, lun, hba_private);
+    SCSIRequest *req;
+    req = d->info->alloc_req(d, tag, lun, hba_private);
+    memcpy(req->cmd.buf, buf, 16);
+    return req;
 }
 
 uint8_t *scsi_req_get_buf(SCSIRequest *req)
@@ -189,7 +192,7 @@ void scsi_req_build_sense(SCSIRequest *req, SCSISense sense)
     req->sense_len = 18;
 }
 
-int32_t scsi_req_enqueue(SCSIRequest *req, uint8_t *buf)
+int32_t scsi_req_enqueue(SCSIRequest *req)
 {
     int32_t rc;
 
@@ -199,7 +202,7 @@ int32_t scsi_req_enqueue(SCSIRequest *req, uint8_t *buf)
     QTAILQ_INSERT_TAIL(&req->dev->requests, req, next);
 
     scsi_req_ref(req);
-    rc = req->ops->send_command(req, buf);
+    rc = req->ops->send_command(req, req->cmd.buf);
     scsi_req_unref(req);
     return rc;
 }
@@ -431,7 +434,7 @@ int scsi_req_parse(SCSIRequest *req, uint8_t *buf)
     if (rc != 0)
         return rc;
 
-    memcpy(req->cmd.buf, buf, req->cmd.len);
+    assert(buf == req->cmd.buf);
     scsi_req_xfer_mode(req);
     req->cmd.lba = scsi_req_lba(req);
     trace_scsi_req_parsed(req->dev->id, req->lun, req->tag, buf[0],
diff --git a/hw/scsi.h b/hw/scsi.h
index 5c0e076..7ed7550 100644
--- a/hw/scsi.h
+++ b/hw/scsi.h
@@ -154,8 +154,8 @@ int scsi_sense_valid(SCSISense sense);
 SCSIRequest *scsi_req_alloc(SCSIReqOps *reqops, SCSIDevice *d, uint32_t tag,
                             uint32_t lun, void *hba_private);
 SCSIRequest *scsi_req_new(SCSIDevice *d, uint32_t tag, uint32_t lun,
-                          void *hba_private);
-int32_t scsi_req_enqueue(SCSIRequest *req, uint8_t *buf);
+                          uint8_t *buf, void *hba_private);
+int32_t scsi_req_enqueue(SCSIRequest *req);
 void scsi_req_free(SCSIRequest *req);
 SCSIRequest *scsi_req_ref(SCSIRequest *req);
 void scsi_req_unref(SCSIRequest *req);
diff --git a/hw/spapr_vscsi.c b/hw/spapr_vscsi.c
index c65308c..d98d1fd 100644
--- a/hw/spapr_vscsi.c
+++ b/hw/spapr_vscsi.c
@@ -600,8 +600,8 @@ static int vscsi_queue_cmd(VSCSIState *s, vscsi_req *req)
     }
 
     req->lun = lun;
-    req->sreq = scsi_req_new(sdev, req->qtag, lun, req);
-    n = scsi_req_enqueue(req->sreq, srp->cmd.cdb);
+    req->sreq = scsi_req_new(sdev, req->qtag, lun, srp->cmd.cdb, req);
+    n = scsi_req_enqueue(req->sreq);
 
     dprintf("VSCSI: Queued command tag 0x%x CMD 0x%x ID %d LUN %d ret: %d\n",
             req->qtag, srp->cmd.cdb[0], id, lun, n);
diff --git a/hw/usb-msd.c b/hw/usb-msd.c
index 90e57fb..4072efd 100644
--- a/hw/usb-msd.c
+++ b/hw/usb-msd.c
@@ -370,8 +370,8 @@ static int usb_msd_handle_data(USBDevice *dev, USBPacket *p)
                     s->tag, cbw.flags, cbw.cmd_len, s->data_len);
             s->residue = 0;
             s->scsi_len = 0;
-            s->req = scsi_req_new(s->scsi_dev, s->tag, 0, NULL);
-            scsi_req_enqueue(s->req, cbw.cmd);
+            s->req = scsi_req_new(s->scsi_dev, s->tag, 0, cbw.cmd, NULL);
+            scsi_req_enqueue(s->req);
             /* ??? Should check that USB and SCSI data transfer
                directions match.  */
             if (s->mode != USB_MSDM_CSW && s->residue == 0) {
commit 12010e7b29a2e777153440ded6fd5bd426eed3e4
Author: Paolo Bonzini <pbonzini at redhat.com>
Date:   Wed Aug 3 10:49:09 2011 +0200

    scsi: move request-related callbacks from SCSIDeviceInfo to SCSIReqOps
    
    Signed-off-by: Paolo Bonzini <pbonzini at redhat.com>
    Signed-off-by: Anthony Liguori <aliguori at us.ibm.com>

diff --git a/hw/scsi-bus.c b/hw/scsi-bus.c
index 0ad466e..df28cc8 100644
--- a/hw/scsi-bus.c
+++ b/hw/scsi-bus.c
@@ -160,7 +160,7 @@ SCSIRequest *scsi_req_new(SCSIDevice *d, uint32_t tag, uint32_t lun,
 
 uint8_t *scsi_req_get_buf(SCSIRequest *req)
 {
-    return req->dev->info->get_buf(req);
+    return req->ops->get_buf(req);
 }
 
 int scsi_req_get_sense(SCSIRequest *req, uint8_t *buf, int len)
@@ -199,7 +199,7 @@ int32_t scsi_req_enqueue(SCSIRequest *req, uint8_t *buf)
     QTAILQ_INSERT_TAIL(&req->dev->requests, req, next);
 
     scsi_req_ref(req);
-    rc = req->dev->info->send_command(req, buf);
+    rc = req->ops->send_command(req, buf);
     scsi_req_unref(req);
     return rc;
 }
@@ -673,8 +673,8 @@ SCSIRequest *scsi_req_ref(SCSIRequest *req)
 void scsi_req_unref(SCSIRequest *req)
 {
     if (--req->refcount == 0) {
-        if (req->dev->info->free_req) {
-            req->dev->info->free_req(req);
+        if (req->ops->free_req) {
+            req->ops->free_req(req);
         }
         qemu_free(req);
     }
@@ -686,9 +686,9 @@ void scsi_req_continue(SCSIRequest *req)
 {
     trace_scsi_req_continue(req->dev->id, req->lun, req->tag);
     if (req->cmd.mode == SCSI_XFER_TO_DEV) {
-        req->dev->info->write_data(req);
+        req->ops->write_data(req);
     } else {
-        req->dev->info->read_data(req);
+        req->ops->read_data(req);
     }
 }
 
@@ -752,8 +752,8 @@ void scsi_req_complete(SCSIRequest *req, int status)
 
 void scsi_req_cancel(SCSIRequest *req)
 {
-    if (req->dev && req->dev->info->cancel_io) {
-        req->dev->info->cancel_io(req);
+    if (req->ops->cancel_io) {
+        req->ops->cancel_io(req);
     }
     scsi_req_ref(req);
     scsi_req_dequeue(req);
@@ -765,8 +765,8 @@ void scsi_req_cancel(SCSIRequest *req)
 
 void scsi_req_abort(SCSIRequest *req, int status)
 {
-    if (req->dev && req->dev->info->cancel_io) {
-        req->dev->info->cancel_io(req);
+    if (req->ops->cancel_io) {
+        req->ops->cancel_io(req);
     }
     scsi_req_complete(req, status);
 }
diff --git a/hw/scsi-disk.c b/hw/scsi-disk.c
index dddc1f3..eda4f8e 100644
--- a/hw/scsi-disk.c
+++ b/hw/scsi-disk.c
@@ -1214,6 +1214,12 @@ static int scsi_disk_initfn(SCSIDevice *dev)
 
 static SCSIReqOps scsi_disk_reqops = {
     .size         = sizeof(SCSIDiskReq),
+    .free_req     = scsi_free_request,
+    .send_command = scsi_send_command,
+    .read_data    = scsi_read_data,
+    .write_data   = scsi_write_data,
+    .cancel_io    = scsi_cancel_io,
+    .get_buf      = scsi_get_buf,
 };
 
 static SCSIRequest *scsi_new_request(SCSIDevice *d, uint32_t tag,
@@ -1244,12 +1250,6 @@ static SCSIDeviceInfo scsi_disk_info[] = {
         .init         = scsi_hd_initfn,
         .destroy      = scsi_destroy,
         .alloc_req    = scsi_new_request,
-        .free_req     = scsi_free_request,
-        .send_command = scsi_send_command,
-        .read_data    = scsi_read_data,
-        .write_data   = scsi_write_data,
-        .cancel_io    = scsi_cancel_io,
-        .get_buf      = scsi_get_buf,
         .qdev.props   = (Property[]) {
             DEFINE_SCSI_DISK_PROPERTIES(),
             DEFINE_PROP_BIT("removable", SCSIDiskState, removable, 0, false),
@@ -1264,12 +1264,6 @@ static SCSIDeviceInfo scsi_disk_info[] = {
         .init         = scsi_cd_initfn,
         .destroy      = scsi_destroy,
         .alloc_req    = scsi_new_request,
-        .free_req     = scsi_free_request,
-        .send_command = scsi_send_command,
-        .read_data    = scsi_read_data,
-        .write_data   = scsi_write_data,
-        .cancel_io    = scsi_cancel_io,
-        .get_buf      = scsi_get_buf,
         .qdev.props   = (Property[]) {
             DEFINE_SCSI_DISK_PROPERTIES(),
             DEFINE_PROP_END_OF_LIST(),
@@ -1283,12 +1277,6 @@ static SCSIDeviceInfo scsi_disk_info[] = {
         .init         = scsi_disk_initfn,
         .destroy      = scsi_destroy,
         .alloc_req    = scsi_new_request,
-        .free_req     = scsi_free_request,
-        .send_command = scsi_send_command,
-        .read_data    = scsi_read_data,
-        .write_data   = scsi_write_data,
-        .cancel_io    = scsi_cancel_io,
-        .get_buf      = scsi_get_buf,
         .qdev.props   = (Property[]) {
             DEFINE_SCSI_DISK_PROPERTIES(),
             DEFINE_PROP_BIT("removable", SCSIDiskState, removable, 0, false),
diff --git a/hw/scsi-generic.c b/hw/scsi-generic.c
index 80d1601..c2bd399 100644
--- a/hw/scsi-generic.c
+++ b/hw/scsi-generic.c
@@ -491,6 +491,12 @@ static int scsi_generic_initfn(SCSIDevice *dev)
 
 static SCSIReqOps scsi_generic_req_ops = {
     .size         = sizeof(SCSIGenericReq),
+    .free_req     = scsi_free_request,
+    .send_command = scsi_send_command,
+    .read_data    = scsi_read_data,
+    .write_data   = scsi_write_data,
+    .cancel_io    = scsi_cancel_io,
+    .get_buf      = scsi_get_buf,
 };
 
 static SCSIRequest *scsi_new_request(SCSIDevice *d, uint32_t tag, uint32_t lun,
@@ -510,12 +516,6 @@ static SCSIDeviceInfo scsi_generic_info = {
     .init         = scsi_generic_initfn,
     .destroy      = scsi_destroy,
     .alloc_req    = scsi_new_request,
-    .free_req     = scsi_free_request,
-    .send_command = scsi_send_command,
-    .read_data    = scsi_read_data,
-    .write_data   = scsi_write_data,
-    .cancel_io    = scsi_cancel_io,
-    .get_buf      = scsi_get_buf,
     .qdev.props   = (Property[]) {
         DEFINE_BLOCK_PROPERTIES(SCSIGenericState, qdev.conf),
         DEFINE_PROP_END_OF_LIST(),
diff --git a/hw/scsi.h b/hw/scsi.h
index ee76c64..5c0e076 100644
--- a/hw/scsi.h
+++ b/hw/scsi.h
@@ -73,6 +73,12 @@ int cdrom_read_toc_raw(int nb_sectors, uint8_t *buf, int msf, int session_num);
 /* scsi-bus.c */
 struct SCSIReqOps {
     size_t size;
+    void (*free_req)(SCSIRequest *req);
+    int32_t (*send_command)(SCSIRequest *req, uint8_t *buf);
+    void (*read_data)(SCSIRequest *req);
+    void (*write_data)(SCSIRequest *req);
+    void (*cancel_io)(SCSIRequest *req);
+    uint8_t *(*get_buf)(SCSIRequest *req);
 };
 
 typedef int (*scsi_qdev_initfn)(SCSIDevice *dev);
@@ -82,12 +88,7 @@ struct SCSIDeviceInfo {
     void (*destroy)(SCSIDevice *s);
     SCSIRequest *(*alloc_req)(SCSIDevice *s, uint32_t tag, uint32_t lun,
                               void *hba_private);
-    void (*free_req)(SCSIRequest *req);
-    int32_t (*send_command)(SCSIRequest *req, uint8_t *buf);
-    void (*read_data)(SCSIRequest *req);
-    void (*write_data)(SCSIRequest *req);
-    void (*cancel_io)(SCSIRequest *req);
-    uint8_t *(*get_buf)(SCSIRequest *req);
+    SCSIReqOps reqops;
 };
 
 struct SCSIBusOps {
commit 8dbd4574882cade8261c2b6225df68a65345c75c
Author: Paolo Bonzini <pbonzini at redhat.com>
Date:   Wed Aug 3 10:49:08 2011 +0200

    scsi: introduce SCSIReqOps
    
    This will let allow requests to be dispatched through different callbacks,
    either common or per-device.
    
    This patch adjusts the API, the next one will move members to SCSIReqOps.
    
    Signed-off-by: Paolo Bonzini <pbonzini at redhat.com>
    Signed-off-by: Anthony Liguori <aliguori at us.ibm.com>

diff --git a/hw/scsi-bus.c b/hw/scsi-bus.c
index af95670..0ad466e 100644
--- a/hw/scsi-bus.c
+++ b/hw/scsi-bus.c
@@ -133,12 +133,12 @@ int scsi_bus_legacy_handle_cmdline(SCSIBus *bus)
     return res;
 }
 
-SCSIRequest *scsi_req_alloc(size_t size, SCSIDevice *d, uint32_t tag,
+SCSIRequest *scsi_req_alloc(SCSIReqOps *reqops, SCSIDevice *d, uint32_t tag,
                             uint32_t lun, void *hba_private)
 {
     SCSIRequest *req;
 
-    req = qemu_mallocz(size);
+    req = qemu_mallocz(reqops->size);
     req->refcount = 1;
     req->bus = scsi_bus_from_device(d);
     req->dev = d;
@@ -147,6 +147,7 @@ SCSIRequest *scsi_req_alloc(size_t size, SCSIDevice *d, uint32_t tag,
     req->hba_private = hba_private;
     req->status = -1;
     req->sense_len = 0;
+    req->ops = reqops;
     trace_scsi_req_alloc(req->dev->id, req->lun, req->tag);
     return req;
 }
diff --git a/hw/scsi-disk.c b/hw/scsi-disk.c
index e266d6f..dddc1f3 100644
--- a/hw/scsi-disk.c
+++ b/hw/scsi-disk.c
@@ -76,19 +76,6 @@ struct SCSIDiskState
 static int scsi_handle_rw_error(SCSIDiskReq *r, int error, int type);
 static int scsi_disk_emulate_command(SCSIDiskReq *r, uint8_t *outbuf);
 
-static SCSIRequest *scsi_new_request(SCSIDevice *d, uint32_t tag,
-                                     uint32_t lun, void *hba_private)
-{
-    SCSIDiskState *s = DO_UPCAST(SCSIDiskState, qdev, d);
-    SCSIRequest *req;
-    SCSIDiskReq *r;
-
-    req = scsi_req_alloc(sizeof(SCSIDiskReq), &s->qdev, tag, lun, hba_private);
-    r = DO_UPCAST(SCSIDiskReq, req, req);
-    r->iov.iov_base = qemu_blockalign(s->bs, SCSI_DMA_BUF_SIZE);
-    return req;
-}
-
 static void scsi_free_request(SCSIRequest *req)
 {
     SCSIDiskReq *r = DO_UPCAST(SCSIDiskReq, req, req);
@@ -1225,6 +1212,23 @@ static int scsi_disk_initfn(SCSIDevice *dev)
     return scsi_initfn(dev, scsi_type);
 }
 
+static SCSIReqOps scsi_disk_reqops = {
+    .size         = sizeof(SCSIDiskReq),
+};
+
+static SCSIRequest *scsi_new_request(SCSIDevice *d, uint32_t tag,
+                                     uint32_t lun, void *hba_private)
+{
+    SCSIDiskState *s = DO_UPCAST(SCSIDiskState, qdev, d);
+    SCSIRequest *req;
+    SCSIDiskReq *r;
+
+    req = scsi_req_alloc(&scsi_disk_reqops, &s->qdev, tag, lun, hba_private);
+    r = DO_UPCAST(SCSIDiskReq, req, req);
+    r->iov.iov_base = qemu_blockalign(s->bs, SCSI_DMA_BUF_SIZE);
+    return req;
+}
+
 #define DEFINE_SCSI_DISK_PROPERTIES()                           \
     DEFINE_BLOCK_PROPERTIES(SCSIDiskState, qdev.conf),          \
     DEFINE_PROP_STRING("ver",  SCSIDiskState, version),         \
diff --git a/hw/scsi-generic.c b/hw/scsi-generic.c
index 37c5982..80d1601 100644
--- a/hw/scsi-generic.c
+++ b/hw/scsi-generic.c
@@ -63,15 +63,6 @@ struct SCSIGenericState
     int lun;
 };
 
-static SCSIRequest *scsi_new_request(SCSIDevice *d, uint32_t tag, uint32_t lun,
-                                     void *hba_private)
-{
-    SCSIRequest *req;
-
-    req = scsi_req_alloc(sizeof(SCSIGenericReq), d, tag, lun, hba_private);
-    return req;
-}
-
 static void scsi_free_request(SCSIRequest *req)
 {
     SCSIGenericReq *r = DO_UPCAST(SCSIGenericReq, req, req);
@@ -498,6 +489,19 @@ static int scsi_generic_initfn(SCSIDevice *dev)
     return 0;
 }
 
+static SCSIReqOps scsi_generic_req_ops = {
+    .size         = sizeof(SCSIGenericReq),
+};
+
+static SCSIRequest *scsi_new_request(SCSIDevice *d, uint32_t tag, uint32_t lun,
+                                     void *hba_private)
+{
+    SCSIRequest *req;
+
+    req = scsi_req_alloc(&scsi_generic_req_ops, d, tag, lun, hba_private);
+    return req;
+}
+
 static SCSIDeviceInfo scsi_generic_info = {
     .qdev.name    = "scsi-generic",
     .qdev.desc    = "pass through generic scsi device (/dev/sg*)",
diff --git a/hw/scsi.h b/hw/scsi.h
index c1cb987..ee76c64 100644
--- a/hw/scsi.h
+++ b/hw/scsi.h
@@ -14,6 +14,7 @@ typedef struct SCSIBusOps SCSIBusOps;
 typedef struct SCSIDevice SCSIDevice;
 typedef struct SCSIDeviceInfo SCSIDeviceInfo;
 typedef struct SCSIRequest SCSIRequest;
+typedef struct SCSIReqOps SCSIReqOps;
 
 enum SCSIXferMode {
     SCSI_XFER_NONE,      /*  TEST_UNIT_READY, ...            */
@@ -32,6 +33,7 @@ typedef struct SCSISense {
 struct SCSIRequest {
     SCSIBus           *bus;
     SCSIDevice        *dev;
+    SCSIReqOps        *ops;
     uint32_t          refcount;
     uint32_t          tag;
     uint32_t          lun;
@@ -69,6 +71,10 @@ int cdrom_read_toc(int nb_sectors, uint8_t *buf, int msf, int start_track);
 int cdrom_read_toc_raw(int nb_sectors, uint8_t *buf, int msf, int session_num);
 
 /* scsi-bus.c */
+struct SCSIReqOps {
+    size_t size;
+};
+
 typedef int (*scsi_qdev_initfn)(SCSIDevice *dev);
 struct SCSIDeviceInfo {
     DeviceInfo qdev;
@@ -144,7 +150,7 @@ extern const struct SCSISense sense_code_LUN_FAILURE;
 
 int scsi_sense_valid(SCSISense sense);
 
-SCSIRequest *scsi_req_alloc(size_t size, SCSIDevice *d, uint32_t tag,
+SCSIRequest *scsi_req_alloc(SCSIReqOps *reqops, SCSIDevice *d, uint32_t tag,
                             uint32_t lun, void *hba_private);
 SCSIRequest *scsi_req_new(SCSIDevice *d, uint32_t tag, uint32_t lun,
                           void *hba_private);
commit b45ef674f4c403398e75c6be02e27a0bfa813a11
Author: Paolo Bonzini <pbonzini at redhat.com>
Date:   Wed Aug 3 10:49:07 2011 +0200

    scsi: move sense handling to generic code
    
    With this patch, sense data is stored in the generic data structures
    for SCSI devices and requests.  The SCSI layer takes care of storing
    sense data in the SCSIDevice for the subsequent REQUEST SENSE command.
    
    At the same time, get_sense is removed and scsi_req_get_sense can use
    an entirely generic implementation.
    
    Reviewed-by: Christoph Hellwig <hch at lst.de>
    Signed-off-by: Paolo Bonzini <pbonzini at redhat.com>
    Signed-off-by: Anthony Liguori <aliguori at us.ibm.com>

diff --git a/hw/scsi-bus.c b/hw/scsi-bus.c
index 9637ccb..af95670 100644
--- a/hw/scsi-bus.c
+++ b/hw/scsi-bus.c
@@ -7,6 +7,8 @@
 #include "trace.h"
 
 static char *scsibus_get_fw_dev_path(DeviceState *dev);
+static int scsi_build_sense(uint8_t *in_buf, int in_len,
+                            uint8_t *buf, int len, bool fixed);
 
 static struct BusInfo scsi_bus_info = {
     .name  = "SCSI",
@@ -144,6 +146,7 @@ SCSIRequest *scsi_req_alloc(size_t size, SCSIDevice *d, uint32_t tag,
     req->lun = lun;
     req->hba_private = hba_private;
     req->status = -1;
+    req->sense_len = 0;
     trace_scsi_req_alloc(req->dev->id, req->lun, req->tag);
     return req;
 }
@@ -161,11 +164,28 @@ uint8_t *scsi_req_get_buf(SCSIRequest *req)
 
 int scsi_req_get_sense(SCSIRequest *req, uint8_t *buf, int len)
 {
-    if (req->dev->info->get_sense) {
-        return req->dev->info->get_sense(req, buf, len);
-    } else {
+    assert(len >= 14);
+    if (!req->sense_len) {
         return 0;
     }
+    return scsi_build_sense(req->sense, req->sense_len, buf, len, true);
+}
+
+int scsi_device_get_sense(SCSIDevice *dev, uint8_t *buf, int len, bool fixed)
+{
+    return scsi_build_sense(dev->sense, dev->sense_len, buf, len, fixed);
+}
+
+void scsi_req_build_sense(SCSIRequest *req, SCSISense sense)
+{
+    trace_scsi_req_build_sense(req->dev->id, req->lun, req->tag,
+                               sense.key, sense.asc, sense.ascq);
+    memset(req->sense, 0, 18);
+    req->sense[0] = 0xf0;
+    req->sense[2] = sense.key;
+    req->sense[12] = sense.asc;
+    req->sense[13] = sense.ascq;
+    req->sense_len = 18;
 }
 
 int32_t scsi_req_enqueue(SCSIRequest *req, uint8_t *buf)
@@ -484,14 +504,40 @@ const struct SCSISense sense_code_LUN_FAILURE = {
 /*
  * scsi_build_sense
  *
- * Build a sense buffer
+ * Convert between fixed and descriptor sense buffers
  */
-int scsi_build_sense(SCSISense sense, uint8_t *buf, int len, int fixed)
+int scsi_build_sense(uint8_t *in_buf, int in_len,
+                     uint8_t *buf, int len, bool fixed)
 {
+    bool fixed_in;
+    SCSISense sense;
     if (!fixed && len < 8) {
         return 0;
     }
 
+    if (in_len == 0) {
+        sense.key = NO_SENSE;
+        sense.asc = 0;
+        sense.ascq = 0;
+    } else {
+        fixed_in = (in_buf[0] & 2) == 0;
+
+        if (fixed == fixed_in) {
+            memcpy(buf, in_buf, MIN(len, in_len));
+            return MIN(len, in_len);
+        }
+
+        if (fixed_in) {
+            sense.key = in_buf[2];
+            sense.asc = in_buf[12];
+            sense.ascq = in_buf[13];
+        } else {
+            sense.key = in_buf[1];
+            sense.asc = in_buf[2];
+            sense.ascq = in_buf[3];
+        }
+    }
+
     memset(buf, 0, len);
     if (fixed) {
         /* Return fixed format sense buffer */
@@ -686,6 +732,17 @@ void scsi_req_complete(SCSIRequest *req, int status)
 {
     assert(req->status == -1);
     req->status = status;
+
+    assert(req->sense_len < sizeof(req->sense));
+    if (status == GOOD) {
+        req->sense_len = 0;
+    }
+
+    if (req->sense_len) {
+        memcpy(req->dev->sense, req->sense, req->sense_len);
+    }
+    req->dev->sense_len = req->sense_len;
+
     scsi_req_ref(req);
     scsi_req_dequeue(req);
     req->bus->ops->complete(req, req->status);
diff --git a/hw/scsi-disk.c b/hw/scsi-disk.c
index 38ebe04..e266d6f 100644
--- a/hw/scsi-disk.c
+++ b/hw/scsi-disk.c
@@ -71,7 +71,6 @@ struct SCSIDiskState
     QEMUBH *bh;
     char *version;
     char *serial;
-    SCSISense sense;
 };
 
 static int scsi_handle_rw_error(SCSIDiskReq *r, int error, int type);
@@ -97,20 +96,13 @@ static void scsi_free_request(SCSIRequest *req)
     qemu_vfree(r->iov.iov_base);
 }
 
-static void scsi_disk_clear_sense(SCSIDiskState *s)
+/* Helper function for command completion with sense.  */
+static void scsi_check_condition(SCSIDiskReq *r, SCSISense sense)
 {
-    memset(&s->sense, 0, sizeof(s->sense));
-}
-
-/* Helper function for command completion.  */
-static void scsi_command_complete(SCSIDiskReq *r, int status, SCSISense sense)
-{
-    SCSIDiskState *s = DO_UPCAST(SCSIDiskState, qdev, r->req.dev);
-
     DPRINTF("Command complete tag=0x%x status=%d sense=%d/%d/%d\n",
             r->req.tag, status, sense.key, sense.asc, sense.ascq);
-    s->sense = sense;
-    scsi_req_complete(&r->req, status);
+    scsi_req_build_sense(&r->req, sense);
+    scsi_req_complete(&r->req, CHECK_CONDITION);
 }
 
 /* Cancel a pending data transfer.  */
@@ -162,7 +154,8 @@ static void scsi_read_data(SCSIRequest *req)
     }
     DPRINTF("Read sector_count=%d\n", r->sector_count);
     if (r->sector_count == 0) {
-        scsi_command_complete(r, GOOD, SENSE_CODE(NO_SENSE));
+        /* This also clears the sense buffer for REQUEST SENSE.  */
+        scsi_req_complete(&r->req, GOOD);
         return;
     }
 
@@ -210,16 +203,13 @@ static int scsi_handle_rw_error(SCSIDiskReq *r, int error, int type)
     } else {
         switch (error) {
         case ENOMEM:
-            scsi_command_complete(r, CHECK_CONDITION,
-                                  SENSE_CODE(TARGET_FAILURE));
+            scsi_check_condition(r, SENSE_CODE(TARGET_FAILURE));
             break;
         case EINVAL:
-            scsi_command_complete(r, CHECK_CONDITION,
-                                  SENSE_CODE(INVALID_FIELD));
+            scsi_check_condition(r, SENSE_CODE(INVALID_FIELD));
             break;
         default:
-            scsi_command_complete(r, CHECK_CONDITION,
-                                  SENSE_CODE(IO_ERROR));
+            scsi_check_condition(r, SENSE_CODE(IO_ERROR));
             break;
         }
         bdrv_mon_event(s->bs, BDRV_ACTION_REPORT, is_read);
@@ -245,7 +235,7 @@ static void scsi_write_complete(void * opaque, int ret)
     r->sector += n;
     r->sector_count -= n;
     if (r->sector_count == 0) {
-        scsi_command_complete(r, GOOD, SENSE_CODE(NO_SENSE));
+        scsi_req_complete(&r->req, GOOD);
     } else {
         len = r->sector_count * 512;
         if (len > SCSI_DMA_BUF_SIZE) {
@@ -314,7 +304,7 @@ static void scsi_dma_restart_bh(void *opaque)
             case SCSI_REQ_STATUS_RETRY_FLUSH:
                 ret = scsi_disk_emulate_command(r, r->iov.iov_base);
                 if (ret == 0) {
-                    scsi_command_complete(r, GOOD, SENSE_CODE(NO_SENSE));
+                    scsi_req_complete(&r->req, GOOD);
                 }
             }
         }
@@ -342,14 +332,6 @@ static uint8_t *scsi_get_buf(SCSIRequest *req)
     return (uint8_t *)r->iov.iov_base;
 }
 
-/* Copy sense information into the provided buffer */
-static int scsi_get_sense(SCSIRequest *req, uint8_t *outbuf, int len)
-{
-    SCSIDiskState *s = DO_UPCAST(SCSIDiskState, qdev, req->dev);
-
-    return scsi_build_sense(s->sense, outbuf, len, len > 14);
-}
-
 static int scsi_disk_emulate_inquiry(SCSIRequest *req, uint8_t *outbuf)
 {
     SCSIDiskState *s = DO_UPCAST(SCSIDiskState, qdev, req->dev);
@@ -827,9 +809,8 @@ static int scsi_disk_emulate_command(SCSIDiskReq *r, uint8_t *outbuf)
     case REQUEST_SENSE:
         if (req->cmd.xfer < 4)
             goto illegal_request;
-        buflen = scsi_build_sense(s->sense, outbuf, req->cmd.xfer,
-                                  req->cmd.xfer > 13);
-        scsi_disk_clear_sense(s);
+        buflen = scsi_device_get_sense(&s->qdev, outbuf, req->cmd.xfer,
+                                       (req->cmd.buf[1] & 1) == 0);
         break;
     case INQUIRY:
         buflen = scsi_disk_emulate_inquiry(req, outbuf);
@@ -960,21 +941,21 @@ static int scsi_disk_emulate_command(SCSIDiskReq *r, uint8_t *outbuf)
     case VERIFY_10:
         break;
     default:
-        scsi_command_complete(r, CHECK_CONDITION, SENSE_CODE(INVALID_OPCODE));
+        scsi_check_condition(r, SENSE_CODE(INVALID_OPCODE));
         return -1;
     }
     return buflen;
 
 not_ready:
     if (!bdrv_is_inserted(s->bs)) {
-        scsi_command_complete(r, CHECK_CONDITION, SENSE_CODE(NO_MEDIUM));
+        scsi_check_condition(r, SENSE_CODE(NO_MEDIUM));
     } else {
-        scsi_command_complete(r, CHECK_CONDITION, SENSE_CODE(LUN_NOT_READY));
+        scsi_check_condition(r, SENSE_CODE(LUN_NOT_READY));
     }
     return -1;
 
 illegal_request:
-    scsi_command_complete(r, CHECK_CONDITION, SENSE_CODE(INVALID_FIELD));
+    scsi_check_condition(r, SENSE_CODE(INVALID_FIELD));
     return -1;
 }
 
@@ -998,7 +979,7 @@ static int32_t scsi_send_command(SCSIRequest *req, uint8_t *buf)
 
     if (scsi_req_parse(&r->req, buf) != 0) {
         BADF("Unsupported command length, command %x\n", command);
-        scsi_command_complete(r, CHECK_CONDITION, SENSE_CODE(INVALID_OPCODE));
+        scsi_check_condition(r, SENSE_CODE(INVALID_OPCODE));
         return 0;
     }
 #ifdef DEBUG_SCSI
@@ -1015,8 +996,7 @@ static int32_t scsi_send_command(SCSIRequest *req, uint8_t *buf)
         /* Only LUN 0 supported.  */
         DPRINTF("Unimplemented LUN %d\n", req->lun);
         if (command != REQUEST_SENSE && command != INQUIRY) {
-            scsi_command_complete(r, CHECK_CONDITION,
-                                  SENSE_CODE(LUN_NOT_SUPPORTED));
+            scsi_check_condition(r, SENSE_CODE(LUN_NOT_SUPPORTED));
             return 0;
         }
     }
@@ -1124,17 +1104,17 @@ static int32_t scsi_send_command(SCSIRequest *req, uint8_t *buf)
         break;
     default:
         DPRINTF("Unknown SCSI command (%2.2x)\n", buf[0]);
-        scsi_command_complete(r, CHECK_CONDITION, SENSE_CODE(INVALID_OPCODE));
+        scsi_check_condition(r, SENSE_CODE(INVALID_OPCODE));
         return 0;
     fail:
-        scsi_command_complete(r, CHECK_CONDITION, SENSE_CODE(INVALID_FIELD));
+        scsi_check_condition(r, SENSE_CODE(INVALID_FIELD));
         return 0;
     illegal_lba:
-        scsi_command_complete(r, CHECK_CONDITION, SENSE_CODE(LBA_OUT_OF_RANGE));
+        scsi_check_condition(r, SENSE_CODE(LBA_OUT_OF_RANGE));
         return 0;
     }
     if (r->sector_count == 0 && r->iov.iov_len == 0) {
-        scsi_command_complete(r, GOOD, SENSE_CODE(NO_SENSE));
+        scsi_req_complete(&r->req, GOOD);
     }
     len = r->sector_count * 512 + r->iov.iov_len;
     if (r->req.cmd.mode == SCSI_XFER_TO_DEV) {
@@ -1266,7 +1246,6 @@ static SCSIDeviceInfo scsi_disk_info[] = {
         .write_data   = scsi_write_data,
         .cancel_io    = scsi_cancel_io,
         .get_buf      = scsi_get_buf,
-        .get_sense    = scsi_get_sense,
         .qdev.props   = (Property[]) {
             DEFINE_SCSI_DISK_PROPERTIES(),
             DEFINE_PROP_BIT("removable", SCSIDiskState, removable, 0, false),
@@ -1287,7 +1266,6 @@ static SCSIDeviceInfo scsi_disk_info[] = {
         .write_data   = scsi_write_data,
         .cancel_io    = scsi_cancel_io,
         .get_buf      = scsi_get_buf,
-        .get_sense    = scsi_get_sense,
         .qdev.props   = (Property[]) {
             DEFINE_SCSI_DISK_PROPERTIES(),
             DEFINE_PROP_END_OF_LIST(),
@@ -1307,7 +1285,6 @@ static SCSIDeviceInfo scsi_disk_info[] = {
         .write_data   = scsi_write_data,
         .cancel_io    = scsi_cancel_io,
         .get_buf      = scsi_get_buf,
-        .get_sense    = scsi_get_sense,
         .qdev.props   = (Property[]) {
             DEFINE_SCSI_DISK_PROPERTIES(),
             DEFINE_PROP_BIT("removable", SCSIDiskState, removable, 0, false),
diff --git a/hw/scsi-generic.c b/hw/scsi-generic.c
index 71cbfb0..37c5982 100644
--- a/hw/scsi-generic.c
+++ b/hw/scsi-generic.c
@@ -61,41 +61,8 @@ struct SCSIGenericState
     SCSIDevice qdev;
     BlockDriverState *bs;
     int lun;
-    int driver_status;
-    uint8_t sensebuf[SCSI_SENSE_BUF_SIZE];
-    uint8_t senselen;
 };
 
-static void scsi_set_sense(SCSIGenericState *s, SCSISense sense)
-{
-    s->senselen = scsi_build_sense(sense, s->sensebuf, SCSI_SENSE_BUF_SIZE, 0);
-    s->driver_status = SG_ERR_DRIVER_SENSE;
-}
-
-static void scsi_clear_sense(SCSIGenericState *s)
-{
-    memset(s->sensebuf, 0, SCSI_SENSE_BUF_SIZE);
-    s->senselen = 0;
-    s->driver_status = 0;
-}
-
-static int scsi_get_sense(SCSIRequest *req, uint8_t *outbuf, int len)
-{
-    SCSIGenericState *s = DO_UPCAST(SCSIGenericState, qdev, req->dev);
-    int size = SCSI_SENSE_BUF_SIZE;
-
-    if (!(s->driver_status & SG_ERR_DRIVER_SENSE)) {
-        size = scsi_build_sense(SENSE_CODE(NO_SENSE), s->sensebuf,
-                                SCSI_SENSE_BUF_SIZE, 0);
-    }
-    if (size > len) {
-        size = len;
-    }
-    memcpy(outbuf, s->sensebuf, size);
-
-    return size;
-}
-
 static SCSIRequest *scsi_new_request(SCSIDevice *d, uint32_t tag, uint32_t lun,
                                      void *hba_private)
 {
@@ -117,12 +84,10 @@ static void scsi_command_complete(void *opaque, int ret)
 {
     int status;
     SCSIGenericReq *r = (SCSIGenericReq *)opaque;
-    SCSIGenericState *s = DO_UPCAST(SCSIGenericState, qdev, r->req.dev);
 
     r->req.aiocb = NULL;
-    s->driver_status = r->io_header.driver_status;
-    if (s->driver_status & SG_ERR_DRIVER_SENSE)
-        s->senselen = r->io_header.sb_len_wr;
+    if (r->io_header.driver_status & SG_ERR_DRIVER_SENSE)
+        r->req.sense_len = r->io_header.sb_len_wr;
 
     if (ret != 0) {
         switch (ret) {
@@ -131,24 +96,24 @@ static void scsi_command_complete(void *opaque, int ret)
             break;
         case -EINVAL:
             status = CHECK_CONDITION;
-            scsi_set_sense(s, SENSE_CODE(INVALID_FIELD));
+            scsi_req_build_sense(&r->req, SENSE_CODE(INVALID_FIELD));
             break;
         case -ENOMEM:
             status = CHECK_CONDITION;
-            scsi_set_sense(s, SENSE_CODE(TARGET_FAILURE));
+            scsi_req_build_sense(&r->req, SENSE_CODE(TARGET_FAILURE));
             break;
         default:
             status = CHECK_CONDITION;
-            scsi_set_sense(s, SENSE_CODE(IO_ERROR));
+            scsi_req_build_sense(&r->req, SENSE_CODE(IO_ERROR));
             break;
         }
     } else {
-        if (s->driver_status & SG_ERR_DRIVER_TIMEOUT) {
+        if (r->io_header.driver_status & SG_ERR_DRIVER_TIMEOUT) {
             status = BUSY;
             BADF("Driver Timeout\n");
         } else if (r->io_header.status) {
             status = r->io_header.status;
-        } else if (s->driver_status & SG_ERR_DRIVER_SENSE) {
+        } else if (r->io_header.driver_status & SG_ERR_DRIVER_SENSE) {
             status = CHECK_CONDITION;
         } else {
             status = GOOD;
@@ -176,16 +141,14 @@ static int execute_command(BlockDriverState *bdrv,
                            SCSIGenericReq *r, int direction,
 			   BlockDriverCompletionFunc *complete)
 {
-    SCSIGenericState *s = DO_UPCAST(SCSIGenericState, qdev, r->req.dev);
-
     r->io_header.interface_id = 'S';
     r->io_header.dxfer_direction = direction;
     r->io_header.dxferp = r->buf;
     r->io_header.dxfer_len = r->buflen;
     r->io_header.cmdp = r->req.cmd.buf;
     r->io_header.cmd_len = r->req.cmd.len;
-    r->io_header.mx_sb_len = sizeof(s->sensebuf);
-    r->io_header.sbp = s->sensebuf;
+    r->io_header.mx_sb_len = sizeof(r->req.sense);
+    r->io_header.sbp = r->req.sense;
     r->io_header.timeout = MAX_UINT;
     r->io_header.usr_ptr = r;
     r->io_header.flags |= SG_FLAG_DIRECT_IO;
@@ -234,21 +197,19 @@ static void scsi_read_data(SCSIRequest *req)
         return;
     }
 
-    if (r->req.cmd.buf[0] == REQUEST_SENSE && s->driver_status & SG_ERR_DRIVER_SENSE)
-    {
-        s->senselen = MIN(r->len, s->senselen);
-        memcpy(r->buf, s->sensebuf, s->senselen);
+    if (r->req.cmd.buf[0] == REQUEST_SENSE) {
         r->io_header.driver_status = 0;
         r->io_header.status = 0;
-        r->io_header.dxfer_len  = s->senselen;
+        r->io_header.dxfer_len =
+            scsi_device_get_sense(&s->qdev, r->buf, r->req.cmd.xfer,
+                                  (r->req.cmd.buf[1] & 1) == 0);
         r->len = -1;
-        DPRINTF("Data ready tag=0x%x len=%d\n", r->req.tag, s->senselen);
+        DPRINTF("Data ready tag=0x%x len=%d\n", r->req.tag, r->io_header.dxfer_len);
         DPRINTF("Sense: %d %d %d %d %d %d %d %d\n",
                 r->buf[0], r->buf[1], r->buf[2], r->buf[3],
                 r->buf[4], r->buf[5], r->buf[6], r->buf[7]);
-        scsi_req_data(&r->req, s->senselen);
-        /* Clear sensebuf after REQUEST_SENSE */
-        scsi_clear_sense(s);
+        scsi_req_data(&r->req, r->io_header.dxfer_len);
+        /* The sense buffer is cleared when we return GOOD */
         return;
     }
 
@@ -342,7 +303,7 @@ static int32_t scsi_send_command(SCSIRequest *req, uint8_t *cmd)
 
     if (cmd[0] != REQUEST_SENSE && req->lun != s->lun) {
         DPRINTF("Unimplemented LUN %d\n", req->lun);
-        scsi_set_sense(s, SENSE_CODE(LUN_NOT_SUPPORTED));
+        scsi_req_build_sense(&r->req, SENSE_CODE(LUN_NOT_SUPPORTED));
         scsi_req_complete(&r->req, CHECK_CONDITION);
         return 0;
     }
@@ -533,8 +494,6 @@ static int scsi_generic_initfn(SCSIDevice *dev)
         }
     }
     DPRINTF("block size %d\n", s->qdev.blocksize);
-    s->driver_status = 0;
-    memset(s->sensebuf, 0, sizeof(s->sensebuf));
     bdrv_set_removable(s->bs, 0);
     return 0;
 }
@@ -553,7 +512,6 @@ static SCSIDeviceInfo scsi_generic_info = {
     .write_data   = scsi_write_data,
     .cancel_io    = scsi_cancel_io,
     .get_buf      = scsi_get_buf,
-    .get_sense    = scsi_get_sense,
     .qdev.props   = (Property[]) {
         DEFINE_BLOCK_PROPERTIES(SCSIGenericState, qdev.conf),
         DEFINE_PROP_END_OF_LIST(),
diff --git a/hw/scsi.h b/hw/scsi.h
index 18d3643..c1cb987 100644
--- a/hw/scsi.h
+++ b/hw/scsi.h
@@ -27,6 +27,8 @@ typedef struct SCSISense {
     uint8_t ascq;
 } SCSISense;
 
+#define SCSI_SENSE_BUF_SIZE 96
+
 struct SCSIRequest {
     SCSIBus           *bus;
     SCSIDevice        *dev;
@@ -42,6 +44,8 @@ struct SCSIRequest {
         enum SCSIXferMode mode;
     } cmd;
     BlockDriverAIOCB  *aiocb;
+    uint8_t sense[SCSI_SENSE_BUF_SIZE];
+    uint32_t sense_len;
     bool enqueued;
     void *hba_private;
     QTAILQ_ENTRY(SCSIRequest) next;
@@ -53,6 +57,8 @@ struct SCSIDevice
     uint32_t id;
     BlockConf conf;
     SCSIDeviceInfo *info;
+    uint8_t sense[SCSI_SENSE_BUF_SIZE];
+    uint32_t sense_len;
     QTAILQ_HEAD(, SCSIRequest) requests;
     int blocksize;
     int type;
@@ -76,7 +82,6 @@ struct SCSIDeviceInfo {
     void (*write_data)(SCSIRequest *req);
     void (*cancel_io)(SCSIRequest *req);
     uint8_t *(*get_buf)(SCSIRequest *req);
-    int (*get_sense)(SCSIRequest *req, uint8_t *buf, int len);
 };
 
 struct SCSIBusOps {
@@ -137,7 +142,6 @@ extern const struct SCSISense sense_code_LUN_FAILURE;
 
 #define SENSE_CODE(x) sense_code_ ## x
 
-int scsi_build_sense(SCSISense sense, uint8_t *buf, int len, int fixed);
 int scsi_sense_valid(SCSISense sense);
 
 SCSIRequest *scsi_req_alloc(size_t size, SCSIDevice *d, uint32_t tag,
@@ -149,6 +153,7 @@ void scsi_req_free(SCSIRequest *req);
 SCSIRequest *scsi_req_ref(SCSIRequest *req);
 void scsi_req_unref(SCSIRequest *req);
 
+void scsi_req_build_sense(SCSIRequest *req, SCSISense sense);
 int scsi_req_parse(SCSIRequest *req, uint8_t *buf);
 void scsi_req_print(SCSIRequest *req);
 void scsi_req_continue(SCSIRequest *req);
@@ -159,5 +164,6 @@ int scsi_req_get_sense(SCSIRequest *req, uint8_t *buf, int len);
 void scsi_req_abort(SCSIRequest *req, int status);
 void scsi_req_cancel(SCSIRequest *req);
 void scsi_device_purge_requests(SCSIDevice *sdev);
+int scsi_device_get_sense(SCSIDevice *dev, uint8_t *buf, int len, bool fixed);
 
 #endif
diff --git a/trace-events b/trace-events
index 19d31e3..0daf2cc 100644
--- a/trace-events
+++ b/trace-events
@@ -251,6 +251,7 @@ disable scsi_req_continue(int target, int lun, int tag) "target %d lun %d tag %d
 disable scsi_req_parsed(int target, int lun, int tag, int cmd, int mode, int xfer) "target %d lun %d tag %d command %d dir %d length %d"
 disable scsi_req_parsed_lba(int target, int lun, int tag, int cmd, uint64_t lba) "target %d lun %d tag %d command %d lba %"PRIu64""
 disable scsi_req_parse_bad(int target, int lun, int tag, int cmd) "target %d lun %d tag %d command %d"
+disable scsi_req_build_sense(int target, int lun, int tag, int key, int asc, int ascq) "target %d lun %d tag %d key %#02x asc %#02x ascq %#02x"
 
 # vl.c
 disable vm_state_notify(int running, int reason) "running %d reason %d"
commit 682a9b213ca3c47c4de5b0518c59c2e550299106
Author: Paolo Bonzini <pbonzini at redhat.com>
Date:   Wed Aug 3 10:49:06 2011 +0200

    scsi: pass status when completing
    
    A small improvement in the SCSI request API.  Pass the status
    at the time the request is completed, so that we can assert that
    no request is completed twice.  This would have detected the
    problem fixed in the previous patch.
    
    Reviewed-by: Christoph Hellwig <hch at lst.de>
    Signed-off-by: Paolo Bonzini <pbonzini at redhat.com>
    Signed-off-by: Anthony Liguori <aliguori at us.ibm.com>

diff --git a/hw/scsi-bus.c b/hw/scsi-bus.c
index d1ef559..9637ccb 100644
--- a/hw/scsi-bus.c
+++ b/hw/scsi-bus.c
@@ -682,9 +682,10 @@ void scsi_req_print(SCSIRequest *req)
     }
 }
 
-void scsi_req_complete(SCSIRequest *req)
+void scsi_req_complete(SCSIRequest *req, int status)
 {
-    assert(req->status != -1);
+    assert(req->status == -1);
+    req->status = status;
     scsi_req_ref(req);
     scsi_req_dequeue(req);
     req->bus->ops->complete(req, req->status);
@@ -706,11 +707,10 @@ void scsi_req_cancel(SCSIRequest *req)
 
 void scsi_req_abort(SCSIRequest *req, int status)
 {
-    req->status = status;
     if (req->dev && req->dev->info->cancel_io) {
         req->dev->info->cancel_io(req);
     }
-    scsi_req_complete(req);
+    scsi_req_complete(req, status);
 }
 
 void scsi_device_purge_requests(SCSIDevice *sdev)
diff --git a/hw/scsi-disk.c b/hw/scsi-disk.c
index e38d9f0..38ebe04 100644
--- a/hw/scsi-disk.c
+++ b/hw/scsi-disk.c
@@ -102,21 +102,15 @@ static void scsi_disk_clear_sense(SCSIDiskState *s)
     memset(&s->sense, 0, sizeof(s->sense));
 }
 
-static void scsi_req_set_status(SCSIDiskReq *r, int status, SCSISense sense)
-{
-    SCSIDiskState *s = DO_UPCAST(SCSIDiskState, qdev, r->req.dev);
-
-    r->req.status = status;
-    s->sense = sense;
-}
-
 /* Helper function for command completion.  */
 static void scsi_command_complete(SCSIDiskReq *r, int status, SCSISense sense)
 {
+    SCSIDiskState *s = DO_UPCAST(SCSIDiskState, qdev, r->req.dev);
+
     DPRINTF("Command complete tag=0x%x status=%d sense=%d/%d/%d\n",
             r->req.tag, status, sense.key, sense.asc, sense.ascq);
-    scsi_req_set_status(r, status, sense);
-    scsi_req_complete(&r->req);
+    s->sense = sense;
+    scsi_req_complete(&r->req, status);
 }
 
 /* Cancel a pending data transfer.  */
@@ -969,7 +963,6 @@ static int scsi_disk_emulate_command(SCSIDiskReq *r, uint8_t *outbuf)
         scsi_command_complete(r, CHECK_CONDITION, SENSE_CODE(INVALID_OPCODE));
         return -1;
     }
-    scsi_req_set_status(r, GOOD, SENSE_CODE(NO_SENSE));
     return buflen;
 
 not_ready:
diff --git a/hw/scsi-generic.c b/hw/scsi-generic.c
index 7b0026e..71cbfb0 100644
--- a/hw/scsi-generic.c
+++ b/hw/scsi-generic.c
@@ -115,6 +115,7 @@ static void scsi_free_request(SCSIRequest *req)
 /* Helper function for command completion.  */
 static void scsi_command_complete(void *opaque, int ret)
 {
+    int status;
     SCSIGenericReq *r = (SCSIGenericReq *)opaque;
     SCSIGenericState *s = DO_UPCAST(SCSIGenericState, qdev, r->req.dev);
 
@@ -126,36 +127,37 @@ static void scsi_command_complete(void *opaque, int ret)
     if (ret != 0) {
         switch (ret) {
         case -EDOM:
-            r->req.status = TASK_SET_FULL;
+            status = TASK_SET_FULL;
             break;
         case -EINVAL:
-            r->req.status = CHECK_CONDITION;
+            status = CHECK_CONDITION;
             scsi_set_sense(s, SENSE_CODE(INVALID_FIELD));
             break;
         case -ENOMEM:
-            r->req.status = CHECK_CONDITION;
+            status = CHECK_CONDITION;
             scsi_set_sense(s, SENSE_CODE(TARGET_FAILURE));
             break;
         default:
-            r->req.status = CHECK_CONDITION;
+            status = CHECK_CONDITION;
             scsi_set_sense(s, SENSE_CODE(IO_ERROR));
             break;
         }
     } else {
         if (s->driver_status & SG_ERR_DRIVER_TIMEOUT) {
-            r->req.status = BUSY;
+            status = BUSY;
             BADF("Driver Timeout\n");
-        } else if (r->io_header.status)
-            r->req.status = r->io_header.status;
-        else if (s->driver_status & SG_ERR_DRIVER_SENSE)
-            r->req.status = CHECK_CONDITION;
-        else
-            r->req.status = GOOD;
+        } else if (r->io_header.status) {
+            status = r->io_header.status;
+        } else if (s->driver_status & SG_ERR_DRIVER_SENSE) {
+            status = CHECK_CONDITION;
+        } else {
+            status = GOOD;
+        }
     }
     DPRINTF("Command complete 0x%p tag=0x%x status=%d\n",
-            r, r->req.tag, r->req.status);
+            r, r->req.tag, status);
 
-    scsi_req_complete(&r->req);
+    scsi_req_complete(&r->req, status);
 }
 
 /* Cancel a pending data transfer.  */
@@ -341,8 +343,7 @@ static int32_t scsi_send_command(SCSIRequest *req, uint8_t *cmd)
     if (cmd[0] != REQUEST_SENSE && req->lun != s->lun) {
         DPRINTF("Unimplemented LUN %d\n", req->lun);
         scsi_set_sense(s, SENSE_CODE(LUN_NOT_SUPPORTED));
-        r->req.status = CHECK_CONDITION;
-        scsi_req_complete(&r->req);
+        scsi_req_complete(&r->req, CHECK_CONDITION);
         return 0;
     }
 
diff --git a/hw/scsi.h b/hw/scsi.h
index 6b15bbc..18d3643 100644
--- a/hw/scsi.h
+++ b/hw/scsi.h
@@ -153,7 +153,7 @@ int scsi_req_parse(SCSIRequest *req, uint8_t *buf);
 void scsi_req_print(SCSIRequest *req);
 void scsi_req_continue(SCSIRequest *req);
 void scsi_req_data(SCSIRequest *req, int len);
-void scsi_req_complete(SCSIRequest *req);
+void scsi_req_complete(SCSIRequest *req, int status);
 uint8_t *scsi_req_get_buf(SCSIRequest *req);
 int scsi_req_get_sense(SCSIRequest *req, uint8_t *buf, int len);
 void scsi_req_abort(SCSIRequest *req, int status);
commit 05751d3ff7d3c12d1468002886a71453491481ce
Author: Paolo Bonzini <pbonzini at redhat.com>
Date:   Wed Aug 3 10:49:05 2011 +0200

    vscsi: always use get_sense
    
    vscsi supports autosensing by providing sense data directly in the
    response.  When get_sense was added, the older state machine approach
    that sent REQUEST SENSE commands separately was left in place.  Remove
    it, all existing SCSIDevices do support autosensing and the next patches
    will make the support come for free from the SCSIBus.
    
    Reviewed-by: Christoph Hellwig <hch at lst.de>
    Signed-off-by: Paolo Bonzini <pbonzini at redhat.com>
    Signed-off-by: Anthony Liguori <aliguori at us.ibm.com>

diff --git a/hw/spapr_vscsi.c b/hw/spapr_vscsi.c
index 646b1e3..c65308c 100644
--- a/hw/spapr_vscsi.c
+++ b/hw/spapr_vscsi.c
@@ -80,7 +80,6 @@ typedef struct vscsi_req {
     int                     active;
     long                    data_len;
     int                     writing;
-    int                     sensing;
     int                     senselen;
     uint8_t                 sense[SCSI_SENSE_BUF_SIZE];
 
@@ -436,40 +435,6 @@ static int vscsi_preprocess_desc(vscsi_req *req)
     return 0;
 }
 
-static void vscsi_send_request_sense(VSCSIState *s, vscsi_req *req)
-{
-    uint8_t *cdb = req->iu.srp.cmd.cdb;
-    int n;
-
-    n = scsi_req_get_sense(req->sreq, req->sense, sizeof(req->sense));
-    if (n) {
-        req->senselen = n;
-        vscsi_send_rsp(s, req, CHECK_CONDITION, 0, 0);
-        vscsi_put_req(req);
-        return;
-    }
-
-    dprintf("VSCSI: Got CHECK_CONDITION, requesting sense...\n");
-    cdb[0] = 3;
-    cdb[1] = 0;
-    cdb[2] = 0;
-    cdb[3] = 0;
-    cdb[4] = 96;
-    cdb[5] = 0;
-    req->sensing = 1;
-    n = scsi_req_enqueue(req->sreq, cdb);
-    dprintf("VSCSI: Queued request sense tag 0x%x\n", req->qtag);
-    if (n < 0) {
-        fprintf(stderr, "VSCSI: REQUEST_SENSE wants write data !?!?!?\n");
-        vscsi_makeup_sense(s, req, HARDWARE_ERROR, 0, 0);
-        scsi_req_abort(req->sreq, CHECK_CONDITION);
-        return;
-    } else if (n == 0) {
-        return;
-    }
-    scsi_req_continue(req->sreq);
-}
-
 /* Callback to indicate that the SCSI layer has completed a transfer.  */
 static void vscsi_transfer_data(SCSIRequest *sreq, uint32_t len)
 {
@@ -485,23 +450,6 @@ static void vscsi_transfer_data(SCSIRequest *sreq, uint32_t len)
         return;
     }
 
-    if (req->sensing) {
-        uint8_t *buf = scsi_req_get_buf(sreq);
-
-        len = MIN(len, SCSI_SENSE_BUF_SIZE);
-        dprintf("VSCSI: Sense data, %d bytes:\n", len);
-        dprintf("       %02x  %02x  %02x  %02x  %02x  %02x  %02x  %02x\n",
-                buf[0], buf[1], buf[2], buf[3],
-                buf[4], buf[5], buf[6], buf[7]);
-        dprintf("       %02x  %02x  %02x  %02x  %02x  %02x  %02x  %02x\n",
-                buf[8], buf[9], buf[10], buf[11],
-                buf[12], buf[13], buf[14], buf[15]);
-        memcpy(req->sense, buf, len);
-        req->senselen = len;
-        scsi_req_continue(req->sreq);
-        return;
-    }
-
     if (len) {
         buf = scsi_req_get_buf(sreq);
         rc = vscsi_srp_transfer_data(s, req, req->writing, buf, len);
@@ -532,28 +480,31 @@ static void vscsi_command_complete(SCSIRequest *sreq, uint32_t status)
         return;
     }
 
-    if (!req->sensing && status == CHECK_CONDITION) {
-        vscsi_send_request_sense(s, req);
-        return;
+    if (status == CHECK_CONDITION) {
+        req->senselen = scsi_req_get_sense(req->sreq, req->sense,
+                                           sizeof(req->sense));
+        status = 0;
+        dprintf("VSCSI: Sense data, %d bytes:\n", len);
+        dprintf("       %02x  %02x  %02x  %02x  %02x  %02x  %02x  %02x\n",
+                req->sense[0], req->sense[1], req->sense[2], req->sense[3],
+                req->sense[4], req->sense[5], req->sense[6], req->sense[7]);
+        dprintf("       %02x  %02x  %02x  %02x  %02x  %02x  %02x  %02x\n",
+                req->sense[8], req->sense[9], req->sense[10], req->sense[11],
+                req->sense[12], req->sense[13], req->sense[14], req->sense[15]);
     }
 
-    if (req->sensing) {
-        dprintf("VSCSI: Sense done !\n");
-        status = CHECK_CONDITION;
-    } else {
-        dprintf("VSCSI: Command complete err=%d\n", status);
-        if (status == 0) {
-            /* We handle overflows, not underflows for normal commands,
-             * but hopefully nobody cares
-             */
-            if (req->writing) {
-                res_out = req->data_len;
-            } else {
-                res_in = req->data_len;
-            }
+    dprintf("VSCSI: Command complete err=%d\n", status);
+    if (status == 0) {
+        /* We handle overflows, not underflows for normal commands,
+         * but hopefully nobody cares
+         */
+        if (req->writing) {
+            res_out = req->data_len;
+        } else {
+            res_in = req->data_len;
         }
     }
-    vscsi_send_rsp(s, req, 0, res_in, res_out);
+    vscsi_send_rsp(s, req, status, res_in, res_out);
     vscsi_put_req(req);
 }
 
commit e44089c79da29ba026d0083e1428b4e82763eeab
Author: Paolo Bonzini <pbonzini at redhat.com>
Date:   Wed Aug 3 10:49:04 2011 +0200

    scsi-disk: no need to call scsi_req_data on a short read
    
    In fact, if the HBA's transfer_data callback goes on with scsi_req_continue
    the request will be completed successfully instead of showing a failure.
    It can even cause a segmentation fault.
    
    An easy way to trigger it is "eject -f cd" during installation (during media
    test if the installer does something like that).
    
    Reviewed-by: Christoph Hellwig <hch at lst.de>
    Signed-off-by: Paolo Bonzini <pbonzini at redhat.com>
    Signed-off-by: Anthony Liguori <aliguori at us.ibm.com>

diff --git a/hw/scsi-disk.c b/hw/scsi-disk.c
index fa198f9..e38d9f0 100644
--- a/hw/scsi-disk.c
+++ b/hw/scsi-disk.c
@@ -214,9 +214,6 @@ static int scsi_handle_rw_error(SCSIDiskReq *r, int error, int type)
         bdrv_mon_event(s->bs, BDRV_ACTION_STOP, is_read);
         vm_stop(VMSTOP_DISKFULL);
     } else {
-        if (type == SCSI_REQ_STATUS_RETRY_READ) {
-            scsi_req_data(&r->req, 0);
-        }
         switch (error) {
         case ENOMEM:
             scsi_command_complete(r, CHECK_CONDITION,
commit 4333979e3d8c129953bba36ed87ce543d33cbea1
Author: Anthony Liguori <aliguori at us.ibm.com>
Date:   Mon Aug 8 14:31:37 2011 -0500

    pc: make vgabios exit port more useful
    
    We've always listened on port 501 for vgabios panic messages.  In the entire
    time I've worked on QEMU, I've never actually seen a vgabios panic message :-)
    
    If we change the semantics of this port a little bit, it makes it possible to
    use it for more interesting use-cases.  I chose this approach instead of adding
    a new I/O port because it avoids having a guest visible change.
    
    This change allows single-byte access to port 501 and also uses the value
    written to construct an exit code.
    
    Signed-off-by: Anthony Liguori <aliguori at us.ibm.com>

diff --git a/hw/pc.c b/hw/pc.c
index 1c9d89a..4b07b35 100644
--- a/hw/pc.c
+++ b/hw/pc.c
@@ -549,8 +549,7 @@ static void bochs_bios_write(void *opaque, uint32_t addr, uint32_t val)
         /* LGPL'ed VGA BIOS messages */
     case 0x501:
     case 0x502:
-        fprintf(stderr, "VGA BIOS panic, line %d\n", val);
-        exit(1);
+        exit((val << 1) | 1);
     case 0x500:
     case 0x503:
 #ifdef DEBUG_BIOS
@@ -591,6 +590,7 @@ static void *bochs_bios_init(void)
     register_ioport_write(0x403, 1, 1, bochs_bios_write, NULL);
     register_ioport_write(0x8900, 1, 1, bochs_bios_write, NULL);
 
+    register_ioport_write(0x501, 1, 1, bochs_bios_write, NULL);
     register_ioport_write(0x501, 1, 2, bochs_bios_write, NULL);
     register_ioport_write(0x502, 1, 2, bochs_bios_write, NULL);
     register_ioport_write(0x500, 1, 1, bochs_bios_write, NULL);
commit 9b024b5f965a3c11aa65435df5b9e8f1cc24d3fa
Merge: eecaece... 85d59fe...
Author: Anthony Liguori <aliguori at us.ibm.com>
Date:   Fri Aug 12 08:06:02 2011 -0500

    Merge remote-tracking branch 'stefanha/trivial-patches' into staging

commit eecaecedec1eb6a47be370a6023bc220a3d30c85
Merge: 25a263c... 930b1e1...
Author: Anthony Liguori <aliguori at us.ibm.com>
Date:   Fri Aug 12 07:52:53 2011 -0500

    Merge remote-tracking branch 'aneesh/for-upstream-1' into staging

commit 25a263cdec8e40c81e597b13ffc81cd9397d1fec
Merge: 7cb78ee... 8df0c7e...
Author: Anthony Liguori <aliguori at us.ibm.com>
Date:   Fri Aug 12 07:51:09 2011 -0500

    Merge remote-tracking branch 'spice/spice.v41' into staging

commit 7cb78eec5cdf6e4131613c64cc1a29476f327242
Merge: 9c4dd42... f3aaaa2...
Author: Anthony Liguori <aliguori at us.ibm.com>
Date:   Fri Aug 12 07:50:35 2011 -0500

    Merge remote-tracking branch 'kraxel/usb.23' into staging

commit 9c4dd424c36a97c05063ae3524e1bd8e5a5a3324
Merge: 8cc7c39... d67c3f2...
Author: Anthony Liguori <aliguori at us.ibm.com>
Date:   Fri Aug 12 07:50:16 2011 -0500

    Merge remote-tracking branch 'kraxel/seabios' into staging

commit 85d59fef9defc78790c8b6cee833d4a77c22a490
Author: Paolo Bonzini <pbonzini at redhat.com>
Date:   Fri Aug 12 13:18:14 2011 +0200

    fix QLIST usage for RAM list
    
    Spotted while reviewing the migration thread patches.
    
    Signed-off-by: Paolo Bonzini <pbonzini at redhat.com>
    Signed-off-by: Stefan Hajnoczi <stefanha at linux.vnet.ibm.com>

diff --git a/cpu-all.h b/cpu-all.h
index fa0205c..f5c82cd 100644
--- a/cpu-all.h
+++ b/cpu-all.h
@@ -488,7 +488,7 @@ typedef struct RAMBlock {
 
 typedef struct RAMList {
     uint8_t *phys_dirty;
-    QLIST_HEAD(ram, RAMBlock) blocks;
+    QLIST_HEAD(, RAMBlock) blocks;
 } RAMList;
 extern RAMList ram_list;
 
diff --git a/exec.c b/exec.c
index be7e4b2..63adb18 100644
--- a/exec.c
+++ b/exec.c
@@ -110,7 +110,7 @@ static uint8_t *code_gen_ptr;
 int phys_ram_fd;
 static int in_migration;
 
-RAMList ram_list = { .blocks = QLIST_HEAD_INITIALIZER(ram_list) };
+RAMList ram_list = { .blocks = QLIST_HEAD_INITIALIZER(ram_list.blocks) };
 
 static MemoryRegion *system_memory;
 static MemoryRegion *system_io;
commit e92714c71a2f50b8420126e952cadb653fa0ef93
Author: Peter Maydell <peter.maydell at linaro.org>
Date:   Wed Aug 3 23:49:04 2011 +0100

    hw/qdev: Don't crash if qdev_create(NULL, ...) fails
    
    If an attempt to create a qdev device on the default sysbus (by passing
    NULL as the bus to qdev_create) fails, print a useful error message
    rather than crashing trying to dereference a NULL pointer.
    
    Signed-off-by: Peter Maydell <peter.maydell at linaro.org>
    Reviewed-by: Markus Armbruster <armbru at redhat.com>
    Signed-off-by: Stefan Hajnoczi <stefanha at linux.vnet.ibm.com>

diff --git a/hw/qdev.c b/hw/qdev.c
index 6819537..d8114c6 100644
--- a/hw/qdev.c
+++ b/hw/qdev.c
@@ -111,7 +111,12 @@ DeviceState *qdev_create(BusState *bus, const char *name)
 
     dev = qdev_try_create(bus, name);
     if (!dev) {
-        hw_error("Unknown device '%s' for bus '%s'\n", name, bus->info->name);
+        if (bus) {
+            hw_error("Unknown device '%s' for bus '%s'\n", name,
+                     bus->info->name);
+        } else {
+            hw_error("Unknown device '%s' for default sysbus\n", name);
+        }
     }
 
     return dev;
commit 645a8ad6e1909d36307f37f3dc4efca9e964334a
Author: Zhi Yong Wu <wuzhy at linux.vnet.ibm.com>
Date:   Thu Aug 4 15:40:35 2011 +0800

    scsi-bus: use DO_UPCAST
    
    Signed-off-by: Zhi Yong Wu <wuzhy at linux.vnet.ibm.com>
    Reviewed-by: Markus Armbruster <armbru at redhat.com>
    Signed-off-by: Stefan Hajnoczi <stefanha at linux.vnet.ibm.com>

diff --git a/hw/scsi-bus.c b/hw/scsi-bus.c
index 0b0344c..d1ef559 100644
--- a/hw/scsi-bus.c
+++ b/hw/scsi-bus.c
@@ -725,7 +725,7 @@ void scsi_device_purge_requests(SCSIDevice *sdev)
 
 static char *scsibus_get_fw_dev_path(DeviceState *dev)
 {
-    SCSIDevice *d = (SCSIDevice*)dev;
+    SCSIDevice *d = DO_UPCAST(SCSIDevice, qdev, dev);
     SCSIBus *bus = scsi_bus_from_device(d);
     char path[100];
     int i;
commit 8cc7c3952d4d0a681d8d4c3ac89a206a5bfd7f00
Author: Edgar E. Iglesias <edgar.iglesias at gmail.com>
Date:   Thu Aug 11 09:17:28 2011 +0200

    etrax-ser: printf -> qemu_log.
    
    Signed-off-by: Edgar E. Iglesias <edgar.iglesias at gmail.com>

diff --git a/hw/etraxfs_ser.c b/hw/etraxfs_ser.c
index b917d4d..28b86ea 100644
--- a/hw/etraxfs_ser.c
+++ b/hw/etraxfs_ser.c
@@ -24,6 +24,7 @@
 
 #include "sysbus.h"
 #include "qemu-char.h"
+#include "qemu-log.h"
 
 #define D(x)
 
@@ -100,7 +101,7 @@ static uint32_t ser_readl (void *opaque, target_phys_addr_t addr)
             break;
         default:
             r = s->regs[addr];
-            D(printf ("%s " TARGET_FMT_plx "=%x\n", __func__, addr, r));
+            D(qemu_log("%s " TARGET_FMT_plx "=%x\n", __func__, addr, r));
             break;
     }
     return r;
@@ -113,7 +114,7 @@ ser_writel (void *opaque, target_phys_addr_t addr, uint32_t value)
     unsigned char ch = value;
     D(CPUState *env = s->env);
 
-    D(printf ("%s " TARGET_FMT_plx "=%x\n",  __func__, addr, value));
+    D(qemu_log("%s " TARGET_FMT_plx "=%x\n",  __func__, addr, value));
     addr >>= 2;
     switch (addr)
     {
@@ -127,7 +128,8 @@ ser_writel (void *opaque, target_phys_addr_t addr, uint32_t value)
             if (s->pending_tx) {
                 value &= ~1;
                 s->pending_tx = 0;
-                D(printf("fixedup value=%x r_intr=%x\n", value, s->regs[R_INTR]));
+                D(qemu_log("fixedup value=%x r_intr=%x\n",
+                           value, s->regs[R_INTR]));
             }
             s->regs[addr] = value;
             s->regs[R_INTR] &= ~value;
@@ -157,7 +159,7 @@ static void serial_receive(void *opaque, const uint8_t *buf, int size)
 
     /* Got a byte.  */
     if (s->rx_fifo_len >= 16) {
-        printf("WARNING: UART dropped char.\n");
+        qemu_log("WARNING: UART dropped char.\n");
         return;
     }
 
commit d949396e5303f4f916ec3733eee0ab365f500dc8
Author: Edgar E. Iglesias <edgar.iglesias at gmail.com>
Date:   Tue Aug 9 13:24:04 2011 +0200

    etrax: QDevify the Ethernet MAC.
    
    Signed-off-by: Edgar E. Iglesias <edgar.iglesias at gmail.com>

diff --git a/hw/cris_pic_cpu.c b/hw/cris_pic_cpu.c
index a92d445..7f1e4ab 100644
--- a/hw/cris_pic_cpu.c
+++ b/hw/cris_pic_cpu.c
@@ -22,6 +22,7 @@
  * THE SOFTWARE.
  */
 
+#include "sysbus.h"
 #include "hw.h"
 #include "pc.h"
 #include "etraxfs.h"
diff --git a/hw/etraxfs.h b/hw/etraxfs.h
index 5c61f1b..1554b0b 100644
--- a/hw/etraxfs.h
+++ b/hw/etraxfs.h
@@ -25,6 +25,21 @@
 #include "etraxfs_dma.h"
 
 qemu_irq *cris_pic_init_cpu(CPUState *env);
-void etraxfs_eth_init(NICInfo *nd, target_phys_addr_t base, int phyaddr,
-                      struct etraxfs_dma_client *dma_out,
-                      struct etraxfs_dma_client *dma_in);
+
+/* Instantiate an ETRAXFS Ethernet MAC.  */
+static inline DeviceState *
+etraxfs_eth_init(NICInfo *nd, target_phys_addr_t base, int phyaddr,
+                 void *dma_out, void *dma_in)
+{
+    DeviceState *dev;
+    qemu_check_nic_model(nd, "fseth");
+
+    dev = qdev_create(NULL, "etraxfs-eth");
+    qdev_set_nic_properties(dev, nd);
+    qdev_prop_set_uint32(dev, "phyaddr", phyaddr);
+    qdev_prop_set_ptr(dev, "dma_out", dma_out);
+    qdev_prop_set_ptr(dev, "dma_in", dma_in);
+    qdev_init_nofail(dev);
+    sysbus_mmio_map(sysbus_from_qdev(dev), 0, base);
+    return dev;
+}
diff --git a/hw/etraxfs_eth.c b/hw/etraxfs_eth.c
index 6453077..92d4eca 100644
--- a/hw/etraxfs_eth.c
+++ b/hw/etraxfs_eth.c
@@ -23,7 +23,7 @@
  */
 
 #include <stdio.h>
-#include "hw.h"
+#include "sysbus.h"
 #include "net.h"
 #include "etraxfs.h"
 
@@ -319,6 +319,7 @@ static void mdio_cycle(struct qemu_mdio *bus)
 
 struct fs_eth
 {
+	SysBusDevice busdev;
 	NICState *nic;
 	NICConf conf;
 	int ethregs;
@@ -327,8 +328,14 @@ struct fs_eth
 	uint8_t macaddr[2][6];
 	uint32_t regs[FS_ETH_MAX_REGS];
 
-	struct etraxfs_dma_client *dma_out;
-	struct etraxfs_dma_client *dma_in;
+	union {
+		void *vdma_out;
+		struct etraxfs_dma_client *dma_out;
+	};
+	union {
+		void *vdma_in;
+		struct etraxfs_dma_client *dma_in;
+	};
 
 	/* MDIO bus.  */
 	struct qemu_mdio mdio_bus;
@@ -579,37 +586,50 @@ static NetClientInfo net_etraxfs_info = {
 	.link_status_changed = eth_set_link,
 };
 
-void etraxfs_eth_init(NICInfo *nd, target_phys_addr_t base, int phyaddr,
-                       struct etraxfs_dma_client *dma_out,
-                       struct etraxfs_dma_client *dma_in)
+static int fs_eth_init(SysBusDevice *dev)
 {
-	struct fs_eth *eth = NULL;
+	struct fs_eth *s = FROM_SYSBUS(typeof(*s), dev);
+	int eth_regs;
 
-	qemu_check_nic_model(nd, "fseth");
-
-	eth = qemu_mallocz(sizeof *eth);
+	if (!s->dma_out || !s->dma_in) {
+		hw_error("Unconnected ETRAX-FS Ethernet MAC.\n");
+	}
 
-	dma_out->client.push = eth_tx_push;
-	dma_out->client.opaque = eth;
-	dma_in->client.opaque = eth;
-	dma_in->client.pull = NULL;
+	s->dma_out->client.push = eth_tx_push;
+	s->dma_out->client.opaque = s;
+	s->dma_in->client.opaque = s;
+	s->dma_in->client.pull = NULL;
 
-	eth->dma_out = dma_out;
-	eth->dma_in = dma_in;
+	eth_regs = cpu_register_io_memory(eth_read, eth_write, s,
+					  DEVICE_LITTLE_ENDIAN);
+	sysbus_init_mmio(dev, 0x5c, eth_regs);
 
-	/* Connect the phy.  */
-	eth->phyaddr = phyaddr & 0x1f;
-	tdk_init(&eth->phy);
-	mdio_attach(&eth->mdio_bus, &eth->phy, eth->phyaddr);
+	qemu_macaddr_default_if_unset(&s->conf.macaddr);
+	s->nic = qemu_new_nic(&net_etraxfs_info, &s->conf,
+			      dev->qdev.info->name, dev->qdev.id, s);
+	qemu_format_nic_info_str(&s->nic->nc, s->conf.macaddr.a);
 
-	eth->ethregs = cpu_register_io_memory(eth_read, eth_write, eth,
-                                              DEVICE_NATIVE_ENDIAN);
-	cpu_register_physical_memory (base, 0x5c, eth->ethregs);
+	tdk_init(&s->phy);
+	mdio_attach(&s->mdio_bus, &s->phy, s->phyaddr);
+	return 0;
+}
 
-	eth->conf.macaddr = nd->macaddr;
-	eth->conf.vlan = nd->vlan;
-	eth->conf.peer = nd->netdev;
+static SysBusDeviceInfo etraxfs_eth_info = {
+	.init = fs_eth_init,
+	.qdev.name  = "etraxfs-eth",
+	.qdev.size  = sizeof(struct fs_eth),
+	.qdev.props = (Property[]) {
+		DEFINE_PROP_UINT32("phyaddr", struct fs_eth, phyaddr, 1),
+		DEFINE_PROP_PTR("dma_out", struct fs_eth, vdma_out),
+		DEFINE_PROP_PTR("dma_in", struct fs_eth, vdma_in),
+		DEFINE_NIC_PROPERTIES(struct fs_eth, conf),
+		DEFINE_PROP_END_OF_LIST(),
+	}
+};
 
-	eth->nic = qemu_new_nic(&net_etraxfs_info, &eth->conf,
-				nd->model, nd->name, eth);
+static void etraxfs_eth_register(void)
+{
+	sysbus_register_withprop(&etraxfs_eth_info);
 }
+
+device_init(etraxfs_eth_register)
commit 8df0c7e8fc03882230c31315f63108c049f72dac
Author: Alon Levy <alevy at redhat.com>
Date:   Wed Aug 10 19:31:46 2011 +0300

    ui/spice-core: report compiled-version in info spice/query-spice
    
    Signed-off-by: Alon Levy <alevy at redhat.com>
    Signed-off-by: Gerd Hoffmann <kraxel at redhat.com>

diff --git a/ui/spice-core.c b/ui/spice-core.c
index 3d77c01..8bb62ea 100644
--- a/ui/spice-core.c
+++ b/ui/spice-core.c
@@ -372,6 +372,8 @@ void do_info_spice_print(Monitor *mon, const QObject *data)
         monitor_printf(mon, "     address: %s:%d [tls]\n", host, port);
     }
     monitor_printf(mon, "        auth: %s\n", qdict_get_str(server, "auth"));
+    monitor_printf(mon, "    compiled: %s\n",
+                   qdict_get_str(server, "compiled-version"));
 
     channels = qdict_get_qlist(server, "channels");
     if (qlist_empty(channels)) {
@@ -388,6 +390,7 @@ void do_info_spice(Monitor *mon, QObject **ret_data)
     QList *clist;
     const char *addr;
     int port, tls_port;
+    char version_string[20]; /* 12 = |255.255.255\0| is the max */
 
     if (!spice_server) {
         *ret_data = qobject_from_jsonf("{ 'enabled': false }");
@@ -403,6 +406,11 @@ void do_info_spice(Monitor *mon, QObject **ret_data)
     qdict_put(server, "enabled", qbool_from_int(true));
     qdict_put(server, "auth", qstring_from_str(auth));
     qdict_put(server, "host", qstring_from_str(addr ? addr : "0.0.0.0"));
+    snprintf(version_string, sizeof(version_string), "%d.%d.%d",
+             (SPICE_SERVER_VERSION & 0xff0000) >> 16,
+             (SPICE_SERVER_VERSION & 0xff00) >> 8,
+             SPICE_SERVER_VERSION & 0xff);
+    qdict_put(server, "compiled-version", qstring_from_str(version_string));
     if (port) {
         qdict_put(server, "port", qint_from_int(port));
     }
commit d67c3f2cd92aed2247bfa8a9da61a902b7b2ff09
Author: Gerd Hoffmann <kraxel at redhat.com>
Date:   Wed Aug 10 17:34:13 2011 +0200

    seabios: update to master
    
    commit 8e301472e324b6d6496d8b4ffc66863e99d7a505
    
    user visible changes in seabios:
      * ahci is enabled by default (and thus in this build).
      * bootorder support for ahci.
      * two-pass pci allocator (orders bars by size for better packing).
    
    Signed-off-by: Gerd Hoffmann <kraxel at redhat.com>

diff --git a/pc-bios/bios.bin b/pc-bios/bios.bin
index bdb4831..bd9ad0e 100644
Binary files a/pc-bios/bios.bin and b/pc-bios/bios.bin differ
diff --git a/roms/seabios b/roms/seabios
index cc97564..8e30147 160000
--- a/roms/seabios
+++ b/roms/seabios
@@ -1 +1 @@
-Subproject commit cc975646af69f279396d4d5e1379ac6af80ee637
+Subproject commit 8e301472e324b6d6496d8b4ffc66863e99d7a505
commit c5f3dabba974aeea36726aaf5a7a5509ee705370
Author: Alon Levy <alevy at redhat.com>
Date:   Tue Aug 9 23:53:34 2011 +0300

    qxl: unbreak after memory API conversion
    
    Break is only noticable with newer spice-server library (0.8.2 release
    or 0.9.0 and newer on master branch).
    
    ioport_write's val was changed from uint32_t to uint64_t, this
    broke two printfs. Use PRId64 instead of %d.
    
    Signed-off-by: Alon Levy <alevy at redhat.com>
    Signed-off-by: Gerd Hoffmann <kraxel at redhat.com>

diff --git a/hw/qxl.c b/hw/qxl.c
index 7991e70..b34bccf 100644
--- a/hw/qxl.c
+++ b/hw/qxl.c
@@ -1187,7 +1187,7 @@ async_common:
         }
         d->current_async = orig_io_port;
         qemu_mutex_unlock(&d->async_lock);
-        dprint(d, 2, "start async %d (%d)\n", io_port, val);
+        dprint(d, 2, "start async %d (%"PRId64")\n", io_port, val);
         break;
     default:
         break;
@@ -1303,7 +1303,8 @@ async_common:
         break;
     }
     case QXL_IO_FLUSH_SURFACES_ASYNC:
-        dprint(d, 1, "QXL_IO_FLUSH_SURFACES_ASYNC (%d) (%s, s#=%d, res#=%d)\n",
+        dprint(d, 1, "QXL_IO_FLUSH_SURFACES_ASYNC"
+                     " (%"PRId64") (%s, s#=%d, res#=%d)\n",
                val, qxl_mode_to_string(d->mode), d->guest_surfaces.count,
                d->num_free_res);
         qxl_spice_flush_surfaces_async(d);
commit be48e9951214a78ebef025cefecfc77be3d1c13c
Author: Yonit Halperin <yhalperi at redhat.com>
Date:   Tue Aug 9 16:12:40 2011 +0300

    qxl: allowing the command rings to be not empty when spice worker is stopped RHBZ #728984
    
    same as 8927cfbba232e28304734f7afd463c1b84134031, but for qxl_check_state, that was
    triggered by qxl_pre_load (which calls qxl_hard_reset, which calls qxl_soft_reset),
    and caused the migration target to crash.
    
    Signed-off-by: Gerd Hoffmann <kraxel at redhat.com>

diff --git a/hw/qxl.c b/hw/qxl.c
index db7ae7a..7991e70 100644
--- a/hw/qxl.c
+++ b/hw/qxl.c
@@ -821,17 +821,15 @@ static void qxl_check_state(PCIQXLDevice *d)
 {
     QXLRam *ram = d->ram;
 
-    assert(SPICE_RING_IS_EMPTY(&ram->cmd_ring));
-    assert(SPICE_RING_IS_EMPTY(&ram->cursor_ring));
+    assert(!d->ssd.running || SPICE_RING_IS_EMPTY(&ram->cmd_ring));
+    assert(!d->ssd.running || SPICE_RING_IS_EMPTY(&ram->cursor_ring));
 }
 
 static void qxl_reset_state(PCIQXLDevice *d)
 {
-    QXLRam *ram = d->ram;
     QXLRom *rom = d->rom;
 
-    assert(!d->ssd.running || SPICE_RING_IS_EMPTY(&ram->cmd_ring));
-    assert(!d->ssd.running || SPICE_RING_IS_EMPTY(&ram->cursor_ring));
+    qxl_check_state(d);
     d->shadow_rom.update_id = cpu_to_le32(0);
     *rom = d->shadow_rom;
     qxl_rom_set_dirty(d);
commit f3aaaa242e701e4516594bc9fb5845ef07783a6d
Author: Gerd Hoffmann <kraxel at redhat.com>
Date:   Wed Aug 10 10:53:50 2011 +0200

    usb-hid: remove usb_hid_datain_cb
    
    No users left, all migrated over to hw/hid.[ch].
    Yea!  Zap it!
    
    Signed-off-by: Gerd Hoffmann <kraxel at redhat.com>

diff --git a/hw/usb-hid.c b/hw/usb-hid.c
index 6a75147..ba79466 100644
--- a/hw/usb-hid.c
+++ b/hw/usb-hid.c
@@ -45,8 +45,6 @@
 typedef struct USBHIDState {
     USBDevice dev;
     HIDState hid;
-    void *datain_opaque;
-    void (*datain)(void *);
 } USBHIDState;
 
 enum {
@@ -362,10 +360,6 @@ static void usb_hid_changed(HIDState *hs)
 {
     USBHIDState *us = container_of(hs, USBHIDState, hid);
 
-    if (us->datain) {
-        us->datain(us->datain_opaque);
-    }
-
     usb_wakeup(&us->dev);
 }
 
@@ -533,14 +527,6 @@ static int usb_keyboard_initfn(USBDevice *dev)
     return usb_hid_initfn(dev, HID_KEYBOARD);
 }
 
-void usb_hid_datain_cb(USBDevice *dev, void *opaque, void (*datain)(void *))
-{
-    USBHIDState *s = (USBHIDState *)dev;
-
-    s->datain_opaque = opaque;
-    s->datain = datain;
-}
-
 static const VMStateDescription vmstate_usb_ptr = {
     .name = "usb-ptr",
     .version_id = 1,
diff --git a/hw/usb.h b/hw/usb.h
index 84d04df..d784448 100644
--- a/hw/usb.h
+++ b/hw/usb.h
@@ -316,9 +316,6 @@ USBDevice *usb_host_device_open(const char *devname);
 int usb_host_device_close(const char *devname);
 void usb_host_info(Monitor *mon);
 
-/* usb-hid.c */
-void usb_hid_datain_cb(USBDevice *dev, void *opaque, void (*datain)(void *));
-
 /* usb-bt.c */
 USBDevice *usb_bt_init(HCIInfo *hci);
 
commit 4c15ba9cc96349ce1cd5396dd243cdc16ff5f016
Author: Michael Walle <michael at walle.cc>
Date:   Tue Aug 9 23:54:55 2011 +0200

    milkymist-softusb: use hid code directly
    
    Remove the dummy USB device and use the HID code directly. Use the HID code
    for the mouse support, too.
    
    Signed-off-by: Michael Walle <michael at walle.cc>
    Signed-off-by: Gerd Hoffmann <kraxel at redhat.com>

diff --git a/hw/milkymist-softusb.c b/hw/milkymist-softusb.c
index 75c85ae..fe4eedb 100644
--- a/hw/milkymist-softusb.c
+++ b/hw/milkymist-softusb.c
@@ -25,7 +25,7 @@
 #include "sysbus.h"
 #include "trace.h"
 #include "console.h"
-#include "usb.h"
+#include "hid.h"
 #include "qemu-error.h"
 
 enum {
@@ -46,9 +46,8 @@ enum {
 
 struct MilkymistSoftUsbState {
     SysBusDevice busdev;
-    USBBus usbbus;
-    USBPort usbport[2];
-    USBDevice *usbdev;
+    HIDState hid_kbd;
+    HIDState hid_mouse;
 
     qemu_irq irq;
 
@@ -62,13 +61,10 @@ struct MilkymistSoftUsbState {
     uint32_t regs[R_MAX];
 
     /* mouse state */
-    int mouse_dx;
-    int mouse_dy;
-    int mouse_dz;
-    uint8_t mouse_buttons_state;
+    uint8_t mouse_hid_buffer[4];
 
     /* keyboard state */
-    uint8_t kbd_usb_buffer[8];
+    uint8_t kbd_hid_buffer[8];
 };
 typedef struct MilkymistSoftUsbState MilkymistSoftUsbState;
 
@@ -177,16 +173,10 @@ static inline void softusb_write_pmem(MilkymistSoftUsbState *s,
 static void softusb_mouse_changed(MilkymistSoftUsbState *s)
 {
     uint8_t m;
-    uint8_t buf[4];
-
-    buf[0] = s->mouse_buttons_state;
-    buf[1] = s->mouse_dx;
-    buf[2] = s->mouse_dy;
-    buf[3] = s->mouse_dz;
 
     softusb_read_dmem(s, COMLOC_MEVT_PRODUCE, &m, 1);
     trace_milkymist_softusb_mevt(m);
-    softusb_write_dmem(s, COMLOC_MEVT_BASE + 4 * m, buf, 4);
+    softusb_write_dmem(s, COMLOC_MEVT_BASE + 4 * m, s->mouse_hid_buffer, 4);
     m = (m + 1) & 0xf;
     softusb_write_dmem(s, COMLOC_MEVT_PRODUCE, &m, 1);
 
@@ -200,7 +190,7 @@ static void softusb_kbd_changed(MilkymistSoftUsbState *s)
 
     softusb_read_dmem(s, COMLOC_KEVT_PRODUCE, &m, 1);
     trace_milkymist_softusb_kevt(m);
-    softusb_write_dmem(s, COMLOC_KEVT_BASE + 8 * m, s->kbd_usb_buffer, 8);
+    softusb_write_dmem(s, COMLOC_KEVT_BASE + 8 * m, s->kbd_hid_buffer, 8);
     m = (m + 1) & 0x7;
     softusb_write_dmem(s, COMLOC_KEVT_PRODUCE, &m, 1);
 
@@ -208,62 +198,42 @@ static void softusb_kbd_changed(MilkymistSoftUsbState *s)
     qemu_irq_pulse(s->irq);
 }
 
-static void softusb_mouse_event(void *opaque,
-       int dx, int dy, int dz, int buttons_state)
+static void softusb_kbd_hid_datain(HIDState *hs)
 {
-    MilkymistSoftUsbState *s = opaque;
+    MilkymistSoftUsbState *s = container_of(hs, MilkymistSoftUsbState, hid_kbd);
+    int len;
 
     /* if device is in reset, do nothing */
     if (s->regs[R_CTRL] & CTRL_RESET) {
         return;
     }
 
-    trace_milkymist_softusb_mouse_event(dx, dy, dz, buttons_state);
+    len = hid_keyboard_poll(hs, s->kbd_hid_buffer, sizeof(s->kbd_hid_buffer));
 
-    s->mouse_dx = dx;
-    s->mouse_dy = dy;
-    s->mouse_dz = dz;
-    s->mouse_buttons_state = buttons_state;
-
-    softusb_mouse_changed(s);
+    if (len == 8) {
+        softusb_kbd_changed(s);
+    }
 }
 
-static void softusb_usbdev_datain(void *opaque)
+static void softusb_mouse_hid_datain(HIDState *hs)
 {
-    MilkymistSoftUsbState *s = opaque;
-
-    USBPacket p;
-
-    usb_packet_init(&p);
-    usb_packet_setup(&p, USB_TOKEN_IN, 0, 1);
-    usb_packet_addbuf(&p, s->kbd_usb_buffer, sizeof(s->kbd_usb_buffer));
-    s->usbdev->info->handle_data(s->usbdev, &p);
-    usb_packet_cleanup(&p);
-
-    softusb_kbd_changed(s);
-}
+    MilkymistSoftUsbState *s =
+            container_of(hs, MilkymistSoftUsbState, hid_mouse);
+    int len;
 
-static void softusb_attach(USBPort *port)
-{
-}
+    /* if device is in reset, do nothing */
+    if (s->regs[R_CTRL] & CTRL_RESET) {
+        return;
+    }
 
-static void softusb_detach(USBPort *port)
-{
-}
+    len = hid_pointer_poll(hs, s->mouse_hid_buffer,
+            sizeof(s->mouse_hid_buffer));
 
-static void softusb_child_detach(USBPort *port, USBDevice *child)
-{
+    if (len == 4) {
+        softusb_mouse_changed(s);
+    }
 }
 
-static USBPortOps softusb_ops = {
-    .attach = softusb_attach,
-    .detach = softusb_detach,
-    .child_detach = softusb_child_detach,
-};
-
-static USBBusOps softusb_bus_ops = {
-};
-
 static void milkymist_softusb_reset(DeviceState *d)
 {
     MilkymistSoftUsbState *s =
@@ -273,11 +243,11 @@ static void milkymist_softusb_reset(DeviceState *d)
     for (i = 0; i < R_MAX; i++) {
         s->regs[i] = 0;
     }
-    s->mouse_dx = 0;
-    s->mouse_dy = 0;
-    s->mouse_dz = 0;
-    s->mouse_buttons_state = 0;
-    memset(s->kbd_usb_buffer, 0, sizeof(s->kbd_usb_buffer));
+    memset(s->kbd_hid_buffer, 0, sizeof(s->kbd_hid_buffer));
+    memset(s->mouse_hid_buffer, 0, sizeof(s->mouse_hid_buffer));
+
+    hid_reset(&s->hid_kbd);
+    hid_reset(&s->hid_mouse);
 
     /* defaults */
     s->regs[R_CTRL] = CTRL_RESET;
@@ -304,23 +274,8 @@ static int milkymist_softusb_init(SysBusDevice *dev)
     cpu_register_physical_memory(s->dmem_base, s->dmem_size,
             dmem_ram | IO_MEM_RAM);
 
-    qemu_add_mouse_event_handler(softusb_mouse_event, s, 0, "Milkymist Mouse");
-
-    /* create our usb bus */
-    usb_bus_new(&s->usbbus, &softusb_bus_ops, NULL);
-
-    /* our two ports */
-    /* FIXME: claim to support full speed devices. qemu mouse and keyboard
-     * report themselves as full speed devices. */
-    usb_register_port(&s->usbbus, &s->usbport[0], NULL, 0, &softusb_ops,
-            USB_SPEED_MASK_LOW | USB_SPEED_MASK_FULL);
-    usb_register_port(&s->usbbus, &s->usbport[1], NULL, 1, &softusb_ops,
-            USB_SPEED_MASK_LOW | USB_SPEED_MASK_FULL);
-
-    /* and finally create an usb keyboard */
-    s->usbdev = usb_create_simple(&s->usbbus, "usb-kbd");
-    usb_hid_datain_cb(s->usbdev, s, softusb_usbdev_datain);
-    s->usbdev->info->handle_reset(s->usbdev);
+    hid_init(&s->hid_kbd, HID_KEYBOARD, softusb_kbd_hid_datain);
+    hid_init(&s->hid_mouse, HID_MOUSE, softusb_mouse_hid_datain);
 
     return 0;
 }
@@ -332,11 +287,10 @@ static const VMStateDescription vmstate_milkymist_softusb = {
     .minimum_version_id_old = 1,
     .fields      = (VMStateField[]) {
         VMSTATE_UINT32_ARRAY(regs, MilkymistSoftUsbState, R_MAX),
-        VMSTATE_INT32(mouse_dx, MilkymistSoftUsbState),
-        VMSTATE_INT32(mouse_dy, MilkymistSoftUsbState),
-        VMSTATE_INT32(mouse_dz, MilkymistSoftUsbState),
-        VMSTATE_UINT8(mouse_buttons_state, MilkymistSoftUsbState),
-        VMSTATE_BUFFER(kbd_usb_buffer, MilkymistSoftUsbState),
+        VMSTATE_HID_KEYBOARD_DEVICE(hid_kbd, MilkymistSoftUsbState),
+        VMSTATE_HID_POINTER_DEVICE(hid_mouse, MilkymistSoftUsbState),
+        VMSTATE_BUFFER(kbd_hid_buffer, MilkymistSoftUsbState),
+        VMSTATE_BUFFER(mouse_hid_buffer, MilkymistSoftUsbState),
         VMSTATE_END_OF_LIST()
     }
 };
commit 1f42d22233b4f3d1a2933ff30e8d6a6d9ee2d08f
Author: Michael Walle <michael at walle.cc>
Date:   Tue Aug 9 23:54:54 2011 +0200

    usb-hid: use hid vmstate macro
    
    Use new hid vmstate macro. Version stays the same, because there is no
    reordering of the fields.
    
    Signed-off-by: Michael Walle <michael at walle.cc>
    Signed-off-by: Gerd Hoffmann <kraxel at redhat.com>

diff --git a/hw/usb-hid.c b/hw/usb-hid.c
index 6f12751..6a75147 100644
--- a/hw/usb-hid.c
+++ b/hw/usb-hid.c
@@ -541,41 +541,13 @@ void usb_hid_datain_cb(USBDevice *dev, void *opaque, void (*datain)(void *))
     s->datain = datain;
 }
 
-static int usb_hid_post_load(void *opaque, int version_id)
-{
-    USBHIDState *s = opaque;
-
-    if (s->hid.idle) {
-        hid_set_next_idle(&s->hid, qemu_get_clock_ns(vm_clock));
-    }
-    return 0;
-}
-
-static const VMStateDescription vmstate_usb_ptr_queue = {
-    .name = "usb-ptr-queue",
-    .version_id = 1,
-    .minimum_version_id = 1,
-    .fields = (VMStateField []) {
-        VMSTATE_INT32(xdx, HIDPointerEvent),
-        VMSTATE_INT32(ydy, HIDPointerEvent),
-        VMSTATE_INT32(dz, HIDPointerEvent),
-        VMSTATE_INT32(buttons_state, HIDPointerEvent),
-        VMSTATE_END_OF_LIST()
-    }
-};
 static const VMStateDescription vmstate_usb_ptr = {
     .name = "usb-ptr",
     .version_id = 1,
     .minimum_version_id = 1,
-    .post_load = usb_hid_post_load,
     .fields = (VMStateField []) {
         VMSTATE_USB_DEVICE(dev, USBHIDState),
-        VMSTATE_STRUCT_ARRAY(hid.ptr.queue, USBHIDState, QUEUE_LENGTH, 0,
-                             vmstate_usb_ptr_queue, HIDPointerEvent),
-        VMSTATE_UINT32(hid.head, USBHIDState),
-        VMSTATE_UINT32(hid.n, USBHIDState),
-        VMSTATE_INT32(hid.protocol, USBHIDState),
-        VMSTATE_UINT8(hid.idle, USBHIDState),
+        VMSTATE_HID_POINTER_DEVICE(hid, USBHIDState),
         VMSTATE_END_OF_LIST()
     }
 };
@@ -584,18 +556,9 @@ static const VMStateDescription vmstate_usb_kbd = {
     .name = "usb-kbd",
     .version_id = 1,
     .minimum_version_id = 1,
-    .post_load = usb_hid_post_load,
     .fields = (VMStateField []) {
         VMSTATE_USB_DEVICE(dev, USBHIDState),
-        VMSTATE_UINT32_ARRAY(hid.kbd.keycodes, USBHIDState, QUEUE_LENGTH),
-        VMSTATE_UINT32(hid.head, USBHIDState),
-        VMSTATE_UINT32(hid.n, USBHIDState),
-        VMSTATE_UINT16(hid.kbd.modifiers, USBHIDState),
-        VMSTATE_UINT8(hid.kbd.leds, USBHIDState),
-        VMSTATE_UINT8_ARRAY(hid.kbd.key, USBHIDState, 16),
-        VMSTATE_INT32(hid.kbd.keys, USBHIDState),
-        VMSTATE_INT32(hid.protocol, USBHIDState),
-        VMSTATE_UINT8(hid.idle, USBHIDState),
+        VMSTATE_HID_KEYBOARD_DEVICE(hid, USBHIDState),
         VMSTATE_END_OF_LIST()
     }
 };
commit ccd4ed065be4023c86252d25118cc96abf77df66
Author: Michael Walle <michael at walle.cc>
Date:   Tue Aug 9 23:54:53 2011 +0200

    hid: introduce hid vmstate macros
    
    Add VMSTATE macros to describe a HIDState. Based on usb-hid.c descriptions.
    
    Signed-off-by: Michael Walle <michael at walle.cc>
    Signed-off-by: Gerd Hoffmann <kraxel at redhat.com>

diff --git a/hw/hid.c b/hw/hid.c
index 3dc4246..ec066cf 100644
--- a/hw/hid.c
+++ b/hw/hid.c
@@ -407,3 +407,61 @@ void hid_init(HIDState *hs, int kind, HIDEventFunc event)
                                                         1, "QEMU HID Tablet");
     }
 }
+
+static int hid_post_load(void *opaque, int version_id)
+{
+    HIDState *s = opaque;
+
+    if (s->idle) {
+        hid_set_next_idle(s, qemu_get_clock_ns(vm_clock));
+    }
+    return 0;
+}
+
+static const VMStateDescription vmstate_hid_ptr_queue = {
+    .name = "HIDPointerEventQueue",
+    .version_id = 1,
+    .minimum_version_id = 1,
+    .fields = (VMStateField[]) {
+        VMSTATE_INT32(xdx, HIDPointerEvent),
+        VMSTATE_INT32(ydy, HIDPointerEvent),
+        VMSTATE_INT32(dz, HIDPointerEvent),
+        VMSTATE_INT32(buttons_state, HIDPointerEvent),
+        VMSTATE_END_OF_LIST()
+    }
+};
+
+const VMStateDescription vmstate_hid_ptr_device = {
+    .name = "HIDPointerDevice",
+    .version_id = 1,
+    .minimum_version_id = 1,
+    .post_load = hid_post_load,
+    .fields = (VMStateField[]) {
+        VMSTATE_STRUCT_ARRAY(ptr.queue, HIDState, QUEUE_LENGTH, 0,
+                             vmstate_hid_ptr_queue, HIDPointerEvent),
+        VMSTATE_UINT32(head, HIDState),
+        VMSTATE_UINT32(n, HIDState),
+        VMSTATE_INT32(protocol, HIDState),
+        VMSTATE_UINT8(idle, HIDState),
+        VMSTATE_END_OF_LIST(),
+    }
+};
+
+const VMStateDescription vmstate_hid_keyboard_device = {
+    .name = "HIDKeyboardDevice",
+    .version_id = 1,
+    .minimum_version_id = 1,
+    .post_load = hid_post_load,
+    .fields = (VMStateField[]) {
+        VMSTATE_UINT32_ARRAY(kbd.keycodes, HIDState, QUEUE_LENGTH),
+        VMSTATE_UINT32(head, HIDState),
+        VMSTATE_UINT32(n, HIDState),
+        VMSTATE_UINT16(kbd.modifiers, HIDState),
+        VMSTATE_UINT8(kbd.leds, HIDState),
+        VMSTATE_UINT8_ARRAY(kbd.key, HIDState, 16),
+        VMSTATE_INT32(kbd.keys, HIDState),
+        VMSTATE_INT32(protocol, HIDState),
+        VMSTATE_UINT8(idle, HIDState),
+        VMSTATE_END_OF_LIST(),
+    }
+};
diff --git a/hw/hw.h b/hw/hw.h
index df6ca65..a124da9 100644
--- a/hw/hw.h
+++ b/hw/hw.h
@@ -701,6 +701,26 @@ extern const VMStateDescription vmstate_ptimer;
     .offset     = vmstate_offset_pointer(_state, _field, ptimer_state), \
 }
 
+extern const VMStateDescription vmstate_hid_keyboard_device;
+
+#define VMSTATE_HID_KEYBOARD_DEVICE(_field, _state) {                \
+    .name       = (stringify(_field)),                               \
+    .size       = sizeof(HIDState),                                  \
+    .vmsd       = &vmstate_hid_keyboard_device,                      \
+    .flags      = VMS_STRUCT,                                        \
+    .offset     = vmstate_offset_value(_state, _field, HIDState),    \
+}
+
+extern const VMStateDescription vmstate_hid_ptr_device;
+
+#define VMSTATE_HID_POINTER_DEVICE(_field, _state) {                 \
+    .name       = (stringify(_field)),                               \
+    .size       = sizeof(HIDState),                                  \
+    .vmsd       = &vmstate_hid_ptr_device,                           \
+    .flags      = VMS_STRUCT,                                        \
+    .offset     = vmstate_offset_value(_state, _field, HIDState),    \
+}
+
 /* _f : field name
    _f_n : num of elements field_name
    _n : num of elements
commit bb0db5273f51629e2c900a27b45b9f8c44ad0e8d
Author: Michael Walle <michael at walle.cc>
Date:   Tue Aug 9 23:54:52 2011 +0200

    hid: register kbd hander in init()
    
    Register the keyboard event handler in hid's init() instead of its reset()
    function.
    
    Signed-off-by: Michael Walle <michael at walle.cc>
    Signed-off-by: Gerd Hoffmann <kraxel at redhat.com>

diff --git a/hw/hid.c b/hw/hid.c
index 77339f7..3dc4246 100644
--- a/hw/hid.c
+++ b/hw/hid.c
@@ -364,7 +364,6 @@ void hid_reset(HIDState *hs)
 {
     switch (hs->kind) {
     case HID_KEYBOARD:
-        qemu_add_kbd_event_handler(hid_keyboard_event, hs);
         memset(hs->kbd.keycodes, 0, sizeof(hs->kbd.keycodes));
         memset(hs->kbd.key, 0, sizeof(hs->kbd.key));
         hs->kbd.keys = 0;
@@ -398,7 +397,9 @@ void hid_init(HIDState *hs, int kind, HIDEventFunc event)
     hs->kind = kind;
     hs->event = event;
 
-    if (hs->kind == HID_MOUSE) {
+    if (hs->kind == HID_KEYBOARD) {
+        qemu_add_kbd_event_handler(hid_keyboard_event, hs);
+    } else if (hs->kind == HID_MOUSE) {
         hs->ptr.eh_entry = qemu_add_mouse_event_handler(hid_pointer_event, hs,
                                                         0, "QEMU HID Mouse");
     } else if (hs->kind == HID_TABLET) {
commit 21635e121ae0f0ab7874152a7c2f96e9d8cd642f
Author: Gerd Hoffmann <kraxel at redhat.com>
Date:   Tue Aug 9 12:35:57 2011 +0200

    usb/hid: add hid_pointer_activate, use it
    
    HID reorganziation broke the usb tablet in windows xp.  The reason is
    that xp activates idle before it starts polling, which creates a
    chicken-and-egg issue:  We don't call hid_pointer_poll because there are
    no pending events.  We don't get any events because the activation code
    in hid_pointer_poll is never executed and thus all pointer events are
    routed to the PS/2 mouse by qemu.
    
    Fix this by creating a hid_pointer_activate function and call it from
    usb-hid when the guest sets the idle state.
    
    Signed-off-by: Gerd Hoffmann <kraxel at redhat.com>

diff --git a/hw/hid.c b/hw/hid.c
index 7b5ef5f..77339f7 100644
--- a/hw/hid.c
+++ b/hw/hid.c
@@ -218,16 +218,21 @@ static inline int int_clamp(int val, int vmin, int vmax)
     }
 }
 
+void hid_pointer_activate(HIDState *hs)
+{
+    if (!hs->ptr.mouse_grabbed) {
+        qemu_activate_mouse_event_handler(hs->ptr.eh_entry);
+        hs->ptr.mouse_grabbed = 1;
+    }
+}
+
 int hid_pointer_poll(HIDState *hs, uint8_t *buf, int len)
 {
     int dx, dy, dz, b, l;
     int index;
     HIDPointerEvent *e;
 
-    if (!hs->ptr.mouse_grabbed) {
-        qemu_activate_mouse_event_handler(hs->ptr.eh_entry);
-        hs->ptr.mouse_grabbed = 1;
-    }
+    hid_pointer_activate(hs);
 
     /* When the buffer is empty, return the last event.  Relative
        movements will all be zero.  */
diff --git a/hw/hid.h b/hw/hid.h
index 4a8fa5b..9ce03b1 100644
--- a/hw/hid.h
+++ b/hw/hid.h
@@ -51,6 +51,7 @@ void hid_free(HIDState *hs);
 
 bool hid_has_events(HIDState *hs);
 void hid_set_next_idle(HIDState *hs, int64_t curtime);
+void hid_pointer_activate(HIDState *hs);
 int hid_pointer_poll(HIDState *hs, uint8_t *buf, int len);
 int hid_keyboard_poll(HIDState *hs, uint8_t *buf, int len);
 int hid_keyboard_write(HIDState *hs, uint8_t *buf, int len);
diff --git a/hw/usb-hid.c b/hw/usb-hid.c
index e5d57de..6f12751 100644
--- a/hw/usb-hid.c
+++ b/hw/usb-hid.c
@@ -454,6 +454,9 @@ static int usb_hid_handle_control(USBDevice *dev, USBPacket *p,
     case SET_IDLE:
         hs->idle = (uint8_t) (value >> 8);
         hid_set_next_idle(hs, qemu_get_clock_ns(vm_clock));
+        if (hs->kind == HID_MOUSE || hs->kind == HID_TABLET) {
+            hid_pointer_activate(hs);
+        }
         ret = 0;
         break;
     default:
commit 930b1e173b31e1a0e77535a9868dc3ec1f426a43
Author: Aneesh Kumar K.V <aneesh.kumar at linux.vnet.ibm.com>
Date:   Sat May 7 16:01:33 2011 +0530

    hw/9pfs: Update vfs_rename to use coroutines
    
    I guess TRENAME 9p operation needs an update. The 9p op should
    more similar renameat. Otherwise anything other than path cannot track
    the fid.
    
    Signed-off-by: Aneesh Kumar K.V <aneesh.kumar at linux.vnet.ibm.com>

diff --git a/hw/9pfs/virtio-9p.c b/hw/9pfs/virtio-9p.c
index 86d4dec..f2193d6 100644
--- a/hw/9pfs/virtio-9p.c
+++ b/hw/9pfs/virtio-9p.c
@@ -189,12 +189,6 @@ static int v9fs_do_truncate(V9fsState *s, V9fsString *path, off_t size)
     return s->ops->truncate(&s->ctx, path->data, size);
 }
 
-static int v9fs_do_rename(V9fsState *s, V9fsString *oldpath,
-                            V9fsString *newpath)
-{
-    return s->ops->rename(&s->ctx, oldpath->data, newpath->data);
-}
-
 static int v9fs_do_chown(V9fsState *s, V9fsString *path, uid_t uid, gid_t gid)
 {
     FsCred cred;
@@ -2633,84 +2627,74 @@ out:
     qemu_free(vs);
 }
 
-static int v9fs_complete_rename(V9fsState *s, V9fsRenameState *vs)
+static int v9fs_complete_rename(V9fsState *s, V9fsFidState *fidp,
+                                int32_t newdirfid, V9fsString *name)
 {
+    char *end;
     int err = 0;
     char *old_name, *new_name;
-    char *end;
 
-    if (vs->newdirfid != -1) {
+    if (newdirfid != -1) {
         V9fsFidState *dirfidp;
-        dirfidp = lookup_fid(s, vs->newdirfid);
-
+        dirfidp = lookup_fid(s, newdirfid);
         if (dirfidp == NULL) {
             err = -ENOENT;
             goto out;
         }
-
         BUG_ON(dirfidp->fid_type != P9_FID_NONE);
 
-        new_name = qemu_mallocz(dirfidp->path.size + vs->name.size + 2);
+        new_name = qemu_mallocz(dirfidp->path.size + name->size + 2);
 
         strcpy(new_name, dirfidp->path.data);
         strcat(new_name, "/");
-        strcat(new_name + dirfidp->path.size, vs->name.data);
+        strcat(new_name + dirfidp->path.size, name->data);
     } else {
-        old_name = vs->fidp->path.data;
+        old_name = fidp->path.data;
         end = strrchr(old_name, '/');
         if (end) {
             end++;
         } else {
             end = old_name;
         }
-        new_name = qemu_mallocz(end - old_name + vs->name.size + 1);
+        new_name = qemu_mallocz(end - old_name + name->size + 1);
 
         strncat(new_name, old_name, end - old_name);
-        strncat(new_name + (end - old_name), vs->name.data, vs->name.size);
+        strncat(new_name + (end - old_name), name->data, name->size);
     }
 
-    v9fs_string_free(&vs->name);
-    vs->name.data = qemu_strdup(new_name);
-    vs->name.size = strlen(new_name);
+    v9fs_string_free(name);
+    name->data = new_name;
+    name->size = strlen(new_name);
 
-    if (strcmp(new_name, vs->fidp->path.data) != 0) {
-        if (v9fs_do_rename(s, &vs->fidp->path, &vs->name)) {
-            err = -errno;
-        } else {
-            V9fsFidState *fidp;
-            /*
-            * Fixup fid's pointing to the old name to
-            * start pointing to the new name
-            */
-            for (fidp = s->fid_list; fidp; fidp = fidp->next) {
-                if (vs->fidp == fidp) {
-                    /*
-                    * we replace name of this fid towards the end so
-                    * that our below v9fs_path_is_ancestor check will
-                    * work
-                    */
-                    continue;
-                }
-                if (v9fs_path_is_ancestor(&vs->fidp->path, &fidp->path)) {
-                    /* replace the name */
-                    v9fs_fix_path(&fidp->path, &vs->name,
-                                  strlen(vs->fidp->path.data));
-                }
+    if (strcmp(new_name, fidp->path.data) != 0) {
+        err = v9fs_co_rename(s, &fidp->path, name);
+        if (err < 0) {
+            goto out;
+        }
+        V9fsFidState *tfidp;
+        /*
+         * Fixup fid's pointing to the old name to
+         * start pointing to the new name
+         */
+        for (tfidp = s->fid_list; tfidp; tfidp = tfidp->next) {
+            if (fidp == tfidp) {
+                /*
+                 * we replace name of this fid towards the end
+                 * so that our below strcmp will work
+                 */
+                continue;
+            }
+            if (v9fs_path_is_ancestor(&fidp->path, &tfidp->path)) {
+                /* replace the name */
+                v9fs_fix_path(&tfidp->path, name, strlen(fidp->path.data));
             }
-            v9fs_string_copy(&vs->fidp->path, &vs->name);
         }
+        v9fs_string_copy(&fidp->path, name);
     }
 out:
-    v9fs_string_free(&vs->name);
     return err;
 }
 
-static void v9fs_rename_post_rename(V9fsState *s, V9fsRenameState *vs, int err)
-{
-    complete_pdu(s, vs->pdu, err);
-    qemu_free(vs);
-}
-
 static void v9fs_wstat_post_chown(V9fsState *s, V9fsWstatState *vs, int err)
 {
     if (err < 0) {
@@ -2718,18 +2702,7 @@ static void v9fs_wstat_post_chown(V9fsState *s, V9fsWstatState *vs, int err)
     }
 
     if (vs->v9stat.name.size != 0) {
-        V9fsRenameState *vr;
-
-        vr = qemu_mallocz(sizeof(V9fsRenameState));
-        vr->newdirfid = -1;
-        vr->pdu = vs->pdu;
-        vr->fidp = vs->fidp;
-        vr->offset = vs->offset;
-        vr->name.size = vs->v9stat.name.size;
-        vr->name.data = qemu_strdup(vs->v9stat.name.data);
-
-        err = v9fs_complete_rename(s, vr);
-        qemu_free(vr);
+        err = v9fs_complete_rename(s, vs->fidp, -1, &vs->v9stat.name);
     }
     v9fs_wstat_post_rename(s, vs, err);
     return;
@@ -2742,32 +2715,31 @@ out:
 
 static void v9fs_rename(void *opaque)
 {
-    V9fsPDU *pdu = opaque;
-    V9fsState *s = pdu->s;
     int32_t fid;
-    V9fsRenameState *vs;
     ssize_t err = 0;
+    size_t offset = 7;
+    V9fsString name;
+    int32_t newdirfid;
+    V9fsFidState *fidp;
+    V9fsPDU *pdu = opaque;
+    V9fsState *s = pdu->s;
 
-    vs = qemu_malloc(sizeof(*vs));
-    vs->pdu = pdu;
-    vs->offset = 7;
-
-    pdu_unmarshal(vs->pdu, vs->offset, "dds", &fid, &vs->newdirfid, &vs->name);
+    pdu_unmarshal(pdu, offset, "dds", &fid, &newdirfid, &name);
 
-    vs->fidp = lookup_fid(s, fid);
-    if (vs->fidp == NULL) {
+    fidp = lookup_fid(s, fid);
+    if (fidp == NULL) {
         err = -ENOENT;
         goto out;
     }
+    BUG_ON(fidp->fid_type != P9_FID_NONE);
 
-    BUG_ON(vs->fidp->fid_type != P9_FID_NONE);
-
-    err = v9fs_complete_rename(s, vs);
-    v9fs_rename_post_rename(s, vs, err);
-    return;
+    err = v9fs_complete_rename(s, fidp, newdirfid, &name);
+    if (!err) {
+        err = offset;
+    }
 out:
-    complete_pdu(s, vs->pdu, err);
-    qemu_free(vs);
+    complete_pdu(s, pdu, err);
+    v9fs_string_free(&name);
 }
 
 static void v9fs_wstat_post_utime(V9fsState *s, V9fsWstatState *vs, int err)
diff --git a/hw/9pfs/virtio-9p.h b/hw/9pfs/virtio-9p.h
index 194f0ea..46d79da 100644
--- a/hw/9pfs/virtio-9p.h
+++ b/hw/9pfs/virtio-9p.h
@@ -385,15 +385,6 @@ typedef struct V9fsMkState {
     V9fsString fullname;
 } V9fsMkState;
 
-typedef struct V9fsRenameState {
-    V9fsPDU *pdu;
-    V9fsFidState *fidp;
-    size_t offset;
-    int32_t newdirfid;
-    V9fsString name;
-} V9fsRenameState;
-
-
 #define P9_LOCK_SUCCESS 0
 #define P9_LOCK_BLOCKED 1
 #define P9_LOCK_ERROR 2
commit 2a487e05def38b73ae25db61f62fdc00b9e5e732
Author: Aneesh Kumar K.V <aneesh.kumar at linux.vnet.ibm.com>
Date:   Sat May 7 16:09:10 2011 +0530

    hw/9pfs: Add yeild support to rename coroutine
    
    Signed-off-by: Aneesh Kumar K.V <aneesh.kumar at linux.vnet.ibm.com>

diff --git a/hw/9pfs/cofs.c b/hw/9pfs/cofs.c
index 8fbfe73..473ce53 100644
--- a/hw/9pfs/cofs.c
+++ b/hw/9pfs/cofs.c
@@ -155,3 +155,17 @@ int v9fs_co_remove(V9fsState *s, V9fsString *path)
         });
     return err;
 }
+
+int v9fs_co_rename(V9fsState *s, V9fsString *oldpath, V9fsString *newpath)
+{
+    int err;
+
+    v9fs_co_run_in_worker(
+        {
+            err = s->ops->rename(&s->ctx, oldpath->data, newpath->data);
+            if (err < 0) {
+                err = -errno;
+            }
+        });
+    return err;
+}
diff --git a/hw/9pfs/virtio-9p-coth.h b/hw/9pfs/virtio-9p-coth.h
index 60795c4..11272d3 100644
--- a/hw/9pfs/virtio-9p-coth.h
+++ b/hw/9pfs/virtio-9p-coth.h
@@ -75,4 +75,5 @@ extern int v9fs_co_mknod(V9fsState *, V9fsString *, uid_t,
                          gid_t, dev_t, mode_t);
 extern int v9fs_co_mkdir(V9fsState *, char *, mode_t, uid_t, gid_t);
 extern int v9fs_co_remove(V9fsState *, V9fsString *);
+extern int v9fs_co_rename(V9fsState *, V9fsString *, V9fsString *);
 #endif
commit ae1ef571fc4ce5cc016311a030357c6a8d851dfe
Author: Venkateswararao Jujjuri <jvrao at linux.vnet.ibm.com>
Date:   Mon Aug 8 23:50:20 2011 +0530

    hw/9pfs: Update v9fs_remove to use coroutines
    
    Signed-off-by: Venkateswararao Jujjuri <jvrao at linux.vnet.ibm.com>
    Signed-off-by: Aneesh Kumar K.V <aneesh.kumar at linux.vnet.ibm.com>

diff --git a/hw/9pfs/virtio-9p.c b/hw/9pfs/virtio-9p.c
index 37ba72c..86d4dec 100644
--- a/hw/9pfs/virtio-9p.c
+++ b/hw/9pfs/virtio-9p.c
@@ -211,11 +211,6 @@ static int v9fs_do_utimensat(V9fsState *s, V9fsString *path,
     return s->ops->utimensat(&s->ctx, path->data, times);
 }
 
-static int v9fs_do_remove(V9fsState *s, V9fsString *path)
-{
-    return s->ops->remove(&s->ctx, path->data);
-}
-
 static int v9fs_do_fsync(V9fsState *s, int fd, int datasync)
 {
     return s->ops->fsync(&s->ctx, fd, datasync);
@@ -2579,49 +2574,30 @@ out:
     complete_pdu(s, pdu, err);
 }
 
-static void v9fs_remove_post_remove(V9fsState *s, V9fsRemoveState *vs,
-                                                                int err)
-{
-    if (err < 0) {
-        err = -errno;
-    } else {
-        err = vs->offset;
-    }
-
-    /* For TREMOVE we need to clunk the fid even on failed remove */
-    free_fid(s, vs->fidp->fid);
-
-    complete_pdu(s, vs->pdu, err);
-    qemu_free(vs);
-}
-
 static void v9fs_remove(void *opaque)
 {
-    V9fsPDU *pdu = opaque;
-    V9fsState *s = pdu->s;
     int32_t fid;
-    V9fsRemoveState *vs;
     int err = 0;
+    size_t offset = 7;
+    V9fsFidState *fidp;
+    V9fsPDU *pdu = opaque;
 
-    vs = qemu_malloc(sizeof(*vs));
-    vs->pdu = pdu;
-    vs->offset = 7;
-
-    pdu_unmarshal(vs->pdu, vs->offset, "d", &fid);
+    pdu_unmarshal(pdu, offset, "d", &fid);
 
-    vs->fidp = lookup_fid(s, fid);
-    if (vs->fidp == NULL) {
+    fidp = lookup_fid(pdu->s, fid);
+    if (fidp == NULL) {
         err = -EINVAL;
         goto out;
     }
+    err = v9fs_co_remove(pdu->s, &fidp->path);
+    if (!err) {
+        err = offset;
+    }
 
-    err = v9fs_do_remove(s, &vs->fidp->path);
-    v9fs_remove_post_remove(s, vs, err);
-    return;
-
+    /* For TREMOVE we need to clunk the fid even on failed remove */
+    free_fid(pdu->s, fidp->fid);
 out:
-    complete_pdu(s, pdu, err);
-    qemu_free(vs);
+    complete_pdu(pdu->s, pdu, err);
 }
 
 static void v9fs_wstat_post_truncate(V9fsState *s, V9fsWstatState *vs, int err)
diff --git a/hw/9pfs/virtio-9p.h b/hw/9pfs/virtio-9p.h
index 3ed46ab..194f0ea 100644
--- a/hw/9pfs/virtio-9p.h
+++ b/hw/9pfs/virtio-9p.h
@@ -333,12 +333,6 @@ typedef struct V9fsWriteState {
     int cnt;
 } V9fsWriteState;
 
-typedef struct V9fsRemoveState {
-    V9fsPDU *pdu;
-    size_t offset;
-    V9fsFidState *fidp;
-} V9fsRemoveState;
-
 typedef struct V9fsWstatState
 {
     V9fsPDU *pdu;
commit b4b1537b96fc57b50a676006868ab97093d040c8
Author: Venkateswararao Jujjuri <jvrao at linux.vnet.ibm.com>
Date:   Mon Aug 8 23:48:29 2011 +0530

    hw/9pfs: Add yield support for remove
    
    Signed-off-by: Venkateswararao Jujjuri <jvrao at linux.vnet.ibm.com>
    Signed-off-by: Aneesh Kumar K.V <aneesh.kumar at linux.vnet.ibm.com>

diff --git a/hw/9pfs/cofs.c b/hw/9pfs/cofs.c
index 6fcedd8..8fbfe73 100644
--- a/hw/9pfs/cofs.c
+++ b/hw/9pfs/cofs.c
@@ -141,3 +141,17 @@ int v9fs_co_mknod(V9fsState *s, V9fsString *path, uid_t uid,
         });
     return err;
 }
+
+int v9fs_co_remove(V9fsState *s, V9fsString *path)
+{
+    int err;
+
+    v9fs_co_run_in_worker(
+        {
+            err = s->ops->remove(&s->ctx, path->data);
+            if (err < 0) {
+                err = -errno;
+            }
+        });
+    return err;
+}
diff --git a/hw/9pfs/virtio-9p-coth.h b/hw/9pfs/virtio-9p-coth.h
index 96e88d8..60795c4 100644
--- a/hw/9pfs/virtio-9p-coth.h
+++ b/hw/9pfs/virtio-9p-coth.h
@@ -74,4 +74,5 @@ extern int v9fs_co_lgetxattr(V9fsState *, V9fsString *,
 extern int v9fs_co_mknod(V9fsState *, V9fsString *, uid_t,
                          gid_t, dev_t, mode_t);
 extern int v9fs_co_mkdir(V9fsState *, char *, mode_t, uid_t, gid_t);
+extern int v9fs_co_remove(V9fsState *, V9fsString *);
 #endif
commit e84861f75e3bb6473cd8576870f3f4cac334d423
Author: Venkateswararao Jujjuri <jvrao at linux.vnet.ibm.com>
Date:   Mon Aug 8 23:46:14 2011 +0530

    hw/9pfs: Update mkdir to use coroutines
    
    Signed-off-by: Venkateswararao Jujjuri "<jvrao at linux.vnet.ibm.com>
    Signed-off-by: Aneesh Kumar K.V <aneesh.kumar at linux.vnet.ibm.com>

diff --git a/hw/9pfs/virtio-9p.c b/hw/9pfs/virtio-9p.c
index edbcd79..37ba72c 100644
--- a/hw/9pfs/virtio-9p.c
+++ b/hw/9pfs/virtio-9p.c
@@ -149,19 +149,6 @@ static int v9fs_do_mknod(V9fsState *s, char *name,
     return s->ops->mknod(&s->ctx, name, &cred);
 }
 
-static int v9fs_do_mkdir(V9fsState *s, char *name, mode_t mode,
-                uid_t uid, gid_t gid)
-{
-    FsCred cred;
-
-    cred_init(&cred);
-    cred.fc_uid = uid;
-    cred.fc_gid = gid;
-    cred.fc_mode = mode;
-
-    return s->ops->mkdir(&s->ctx, name, &cred);
-}
-
 static int v9fs_do_fstat(V9fsState *s, int fd, struct stat *stbuf)
 {
     return s->ops->fstat(&s->ctx, fd, stbuf);
@@ -2329,8 +2316,7 @@ out:
 
 static void v9fs_create_post_mkdir(V9fsState *s, V9fsCreateState *vs, int err)
 {
-    if (err) {
-        err = -errno;
+    if (err < 0) {
         goto out;
     }
 
@@ -2379,7 +2365,7 @@ static void v9fs_create_post_lstat(V9fsState *s, V9fsCreateState *vs, int err)
     }
 
     if (vs->perm & P9_STAT_MODE_DIR) {
-        err = v9fs_do_mkdir(s, vs->fullname.data, vs->perm & 0777,
+        err = v9fs_co_mkdir(s, vs->fullname.data, vs->perm & 0777,
                 vs->fidp->uid, -1);
         v9fs_create_post_mkdir(s, vs, err);
     } else if (vs->perm & P9_STAT_MODE_SYMLINK) {
@@ -3157,75 +3143,43 @@ out:
     qemu_free(vs);
 }
 
-static void v9fs_mkdir_post_lstat(V9fsState *s, V9fsMkState *vs, int err)
-{
-    if (err == -1) {
-        err = -errno;
-        goto out;
-    }
-
-    stat_to_qid(&vs->stbuf, &vs->qid);
-    vs->offset += pdu_marshal(vs->pdu, vs->offset, "Q", &vs->qid);
-    err = vs->offset;
-out:
-    complete_pdu(s, vs->pdu, err);
-    v9fs_string_free(&vs->fullname);
-    v9fs_string_free(&vs->name);
-    qemu_free(vs);
-}
-
-static void v9fs_mkdir_post_mkdir(V9fsState *s, V9fsMkState *vs, int err)
-{
-    if (err == -1) {
-        err = -errno;
-        goto out;
-    }
-
-    err = v9fs_do_lstat(s, &vs->fullname, &vs->stbuf);
-    v9fs_mkdir_post_lstat(s, vs, err);
-    return;
-out:
-    complete_pdu(s, vs->pdu, err);
-    v9fs_string_free(&vs->fullname);
-    v9fs_string_free(&vs->name);
-    qemu_free(vs);
-}
-
 static void v9fs_mkdir(void *opaque)
 {
     V9fsPDU *pdu = opaque;
-    V9fsState *s = pdu->s;
+    size_t offset = 7;
     int32_t fid;
-    V9fsMkState *vs;
-    int err = 0;
+    struct stat stbuf;
+    V9fsString name, fullname;
+    V9fsQID qid;
     V9fsFidState *fidp;
     gid_t gid;
     int mode;
+    int err = 0;
 
-    vs = qemu_malloc(sizeof(*vs));
-    vs->pdu = pdu;
-    vs->offset = 7;
-
-    v9fs_string_init(&vs->fullname);
-    pdu_unmarshal(vs->pdu, vs->offset, "dsdd", &fid, &vs->name, &mode,
-        &gid);
+    v9fs_string_init(&fullname);
+    pdu_unmarshal(pdu, offset, "dsdd", &fid, &name, &mode, &gid);
 
-    fidp = lookup_fid(s, fid);
+    fidp = lookup_fid(pdu->s, fid);
     if (fidp == NULL) {
         err = -ENOENT;
         goto out;
     }
-
-    v9fs_string_sprintf(&vs->fullname, "%s/%s", fidp->path.data, vs->name.data);
-    err = v9fs_do_mkdir(s, vs->fullname.data, mode, fidp->uid, gid);
-    v9fs_mkdir_post_mkdir(s, vs, err);
-    return;
-
+    v9fs_string_sprintf(&fullname, "%s/%s", fidp->path.data, name.data);
+    err = v9fs_co_mkdir(pdu->s, fullname.data, mode, fidp->uid, gid);
+    if (err < 0) {
+        goto out;
+    }
+    err = v9fs_co_lstat(pdu->s, &fullname, &stbuf);
+    if (err < 0) {
+        goto out;
+    }
+    stat_to_qid(&stbuf, &qid);
+    offset += pdu_marshal(pdu, offset, "Q", &qid);
+    err = offset;
 out:
-    complete_pdu(s, vs->pdu, err);
-    v9fs_string_free(&vs->fullname);
-    v9fs_string_free(&vs->name);
-    qemu_free(vs);
+    complete_pdu(pdu->s, pdu, err);
+    v9fs_string_free(&fullname);
+    v9fs_string_free(&name);
 }
 
 static void v9fs_xattrwalk(void *opaque)
commit d0884642b827ec90a7e66d34f5cf1caa1a031990
Author: Venkateswararao Jujjuri <jvrao at linux.vnet.ibm.com>
Date:   Mon Aug 8 23:44:24 2011 +0530

    hw/9pfs: Add yield support for mkdir coroutine
    
    Signed-off-by: Venkateswararao Jujjuri <jvrao at linux.vnet.ibm.com>
    Signed-off-by: Aneesh Kumar K.V <aneesh.kumar at linux.vnet.ibm.com>

diff --git a/hw/9pfs/codir.c b/hw/9pfs/codir.c
index 47b10df..28f2ad7 100644
--- a/hw/9pfs/codir.c
+++ b/hw/9pfs/codir.c
@@ -64,3 +64,22 @@ void v9fs_co_rewinddir(V9fsState *s, V9fsFidState *fidp)
             s->ops->rewinddir(&s->ctx, fidp->fs.dir);
         });
 }
+
+int v9fs_co_mkdir(V9fsState *s, char *name, mode_t mode, uid_t uid, gid_t gid)
+{
+    int err;
+    FsCred cred;
+
+    cred_init(&cred);
+    cred.fc_mode = mode;
+    cred.fc_uid = uid;
+    cred.fc_gid = gid;
+    v9fs_co_run_in_worker(
+        {
+            err = s->ops->mkdir(&s->ctx, name, &cred);
+            if (err < 0) {
+                err = -errno;
+            }
+        });
+    return err;
+}
diff --git a/hw/9pfs/virtio-9p-coth.h b/hw/9pfs/virtio-9p-coth.h
index d023683..96e88d8 100644
--- a/hw/9pfs/virtio-9p-coth.h
+++ b/hw/9pfs/virtio-9p-coth.h
@@ -73,4 +73,5 @@ extern int v9fs_co_lgetxattr(V9fsState *, V9fsString *,
                              V9fsString *, void *, size_t);
 extern int v9fs_co_mknod(V9fsState *, V9fsString *, uid_t,
                          gid_t, dev_t, mode_t);
+extern int v9fs_co_mkdir(V9fsState *, char *, mode_t, uid_t, gid_t);
 #endif
commit 1b733fed7fe407169523cbdb73d97bb335a7f02c
Author: Aneesh Kumar K.V <aneesh.kumar at linux.vnet.ibm.com>
Date:   Wed May 18 16:06:51 2011 -0700

    hw/9pfs: Update v9fs_mknod to use coroutines
    
    Signed-off-by: Aneesh Kumar K.V <aneesh.kumar at linux.vnet.ibm.com>

diff --git a/hw/9pfs/virtio-9p.c b/hw/9pfs/virtio-9p.c
index 757316b..edbcd79 100644
--- a/hw/9pfs/virtio-9p.c
+++ b/hw/9pfs/virtio-9p.c
@@ -3019,77 +3019,49 @@ out:
     return;
 }
 
-static void v9fs_mknod_post_lstat(V9fsState *s, V9fsMkState *vs, int err)
-{
-    if (err == -1) {
-        err = -errno;
-        goto out;
-    }
-
-    stat_to_qid(&vs->stbuf, &vs->qid);
-    vs->offset += pdu_marshal(vs->pdu, vs->offset, "Q", &vs->qid);
-    err = vs->offset;
-out:
-    complete_pdu(s, vs->pdu, err);
-    v9fs_string_free(&vs->fullname);
-    v9fs_string_free(&vs->name);
-    qemu_free(vs);
-}
-
-static void v9fs_mknod_post_mknod(V9fsState *s, V9fsMkState *vs, int err)
-{
-    if (err == -1) {
-        err = -errno;
-        goto out;
-    }
-
-    err = v9fs_do_lstat(s, &vs->fullname, &vs->stbuf);
-    v9fs_mknod_post_lstat(s, vs, err);
-    return;
-out:
-    complete_pdu(s, vs->pdu, err);
-    v9fs_string_free(&vs->fullname);
-    v9fs_string_free(&vs->name);
-    qemu_free(vs);
-}
-
 static void v9fs_mknod(void *opaque)
 {
-    V9fsPDU *pdu = opaque;
-    V9fsState *s = pdu->s;
+
+    int mode;
+    gid_t gid;
     int32_t fid;
-    V9fsMkState *vs;
+    V9fsQID qid;
     int err = 0;
-    V9fsFidState *fidp;
-    gid_t gid;
-    int mode;
     int major, minor;
+    size_t offset = 7;
+    V9fsString name;
+    struct stat stbuf;
+    V9fsString fullname;
+    V9fsFidState *fidp;
+    V9fsPDU *pdu = opaque;
+    V9fsState *s = pdu->s;
 
-    vs = qemu_malloc(sizeof(*vs));
-    vs->pdu = pdu;
-    vs->offset = 7;
-
-    v9fs_string_init(&vs->fullname);
-    pdu_unmarshal(vs->pdu, vs->offset, "dsdddd", &fid, &vs->name, &mode,
-        &major, &minor, &gid);
+    v9fs_string_init(&fullname);
+    pdu_unmarshal(pdu, offset, "dsdddd", &fid, &name, &mode,
+                  &major, &minor, &gid);
 
     fidp = lookup_fid(s, fid);
     if (fidp == NULL) {
         err = -ENOENT;
         goto out;
     }
-
-    v9fs_string_sprintf(&vs->fullname, "%s/%s", fidp->path.data, vs->name.data);
-    err = v9fs_do_mknod(s, vs->fullname.data, mode, makedev(major, minor),
-        fidp->uid, gid);
-    v9fs_mknod_post_mknod(s, vs, err);
-    return;
-
+    v9fs_string_sprintf(&fullname, "%s/%s", fidp->path.data, name.data);
+    err = v9fs_co_mknod(s, &fullname, fidp->uid, gid,
+                        makedev(major, minor), mode);
+    if (err < 0) {
+        goto out;
+    }
+    err = v9fs_co_lstat(s, &fullname, &stbuf);
+    if (err < 0) {
+        goto out;
+    }
+    stat_to_qid(&stbuf, &qid);
+    err = offset;
+    err += pdu_marshal(pdu, offset, "Q", &qid);
 out:
-    complete_pdu(s, vs->pdu, err);
-    v9fs_string_free(&vs->fullname);
-    v9fs_string_free(&vs->name);
-    qemu_free(vs);
+    complete_pdu(s, pdu, err);
+    v9fs_string_free(&fullname);
+    v9fs_string_free(&name);
 }
 
 /*
commit 00ace8c5c534d5b7d42099e7c2e82a79f8591cb7
Author: Aneesh Kumar K.V <aneesh.kumar at linux.vnet.ibm.com>
Date:   Wed May 18 16:06:38 2011 -0700

    hw/9pfs: Add yield support to mknod coroutine
    
    Signed-off-by: Aneesh Kumar K.V <aneesh.kumar at linux.vnet.ibm.com>

diff --git a/hw/9pfs/cofs.c b/hw/9pfs/cofs.c
index 7e9df85..6fcedd8 100644
--- a/hw/9pfs/cofs.c
+++ b/hw/9pfs/cofs.c
@@ -120,3 +120,24 @@ int v9fs_co_truncate(V9fsState *s, V9fsString *path, off_t size)
         });
     return err;
 }
+
+int v9fs_co_mknod(V9fsState *s, V9fsString *path, uid_t uid,
+                  gid_t gid, dev_t dev, mode_t mode)
+{
+    int err;
+    FsCred cred;
+
+    cred_init(&cred);
+    cred.fc_uid  = uid;
+    cred.fc_gid  = gid;
+    cred.fc_mode = mode;
+    cred.fc_rdev = dev;
+    v9fs_co_run_in_worker(
+        {
+            err = s->ops->mknod(&s->ctx, path->data, &cred);
+            if (err < 0) {
+                err = -errno;
+            }
+        });
+    return err;
+}
diff --git a/hw/9pfs/virtio-9p-coth.h b/hw/9pfs/virtio-9p-coth.h
index eb0c99a..d023683 100644
--- a/hw/9pfs/virtio-9p-coth.h
+++ b/hw/9pfs/virtio-9p-coth.h
@@ -71,4 +71,6 @@ extern int v9fs_co_truncate(V9fsState *, V9fsString *, off_t);
 extern int v9fs_co_llistxattr(V9fsState *, V9fsString *, void *, size_t);
 extern int v9fs_co_lgetxattr(V9fsState *, V9fsString *,
                              V9fsString *, void *, size_t);
+extern int v9fs_co_mknod(V9fsState *, V9fsString *, uid_t,
+                         gid_t, dev_t, mode_t);
 #endif
commit f10ff58d019b5abf90d5533074e45f86253e5bc0
Author: Aneesh Kumar K.V <aneesh.kumar at linux.vnet.ibm.com>
Date:   Wed May 18 16:06:26 2011 -0700

    hw/9pfs: Update v9fs_xattrcreate to use coroutines
    
    Signed-off-by: Aneesh Kumar K.V <aneesh.kumar at linux.vnet.ibm.com>

diff --git a/hw/9pfs/virtio-9p.c b/hw/9pfs/virtio-9p.c
index 124ca55..757316b 100644
--- a/hw/9pfs/virtio-9p.c
+++ b/hw/9pfs/virtio-9p.c
@@ -3346,43 +3346,42 @@ out:
 
 static void v9fs_xattrcreate(void *opaque)
 {
-    V9fsPDU *pdu = opaque;
-    V9fsState *s = pdu->s;
     int flags;
     int32_t fid;
+    int64_t size;
     ssize_t err = 0;
-    V9fsXattrState *vs;
-
-    vs = qemu_malloc(sizeof(*vs));
-    vs->pdu = pdu;
-    vs->offset = 7;
+    V9fsString name;
+    size_t offset = 7;
+    V9fsFidState *file_fidp;
+    V9fsFidState *xattr_fidp;
+    V9fsPDU *pdu = opaque;
+    V9fsState *s = pdu->s;
 
-    pdu_unmarshal(vs->pdu, vs->offset, "dsqd",
-                  &fid, &vs->name, &vs->size, &flags);
+    pdu_unmarshal(pdu, offset, "dsqd",
+                  &fid, &name, &size, &flags);
 
-    vs->file_fidp = lookup_fid(s, fid);
-    if (vs->file_fidp == NULL) {
+    file_fidp = lookup_fid(s, fid);
+    if (file_fidp == NULL) {
         err = -EINVAL;
         goto out;
     }
-
     /* Make the file fid point to xattr */
-    vs->xattr_fidp = vs->file_fidp;
-    vs->xattr_fidp->fid_type = P9_FID_XATTR;
-    vs->xattr_fidp->fs.xattr.copied_len = 0;
-    vs->xattr_fidp->fs.xattr.len = vs->size;
-    vs->xattr_fidp->fs.xattr.flags = flags;
-    v9fs_string_init(&vs->xattr_fidp->fs.xattr.name);
-    v9fs_string_copy(&vs->xattr_fidp->fs.xattr.name, &vs->name);
-    if (vs->size)
-        vs->xattr_fidp->fs.xattr.value = qemu_malloc(vs->size);
-    else
-        vs->xattr_fidp->fs.xattr.value = NULL;
-
+    xattr_fidp = file_fidp;
+    xattr_fidp->fid_type = P9_FID_XATTR;
+    xattr_fidp->fs.xattr.copied_len = 0;
+    xattr_fidp->fs.xattr.len = size;
+    xattr_fidp->fs.xattr.flags = flags;
+    v9fs_string_init(&xattr_fidp->fs.xattr.name);
+    v9fs_string_copy(&xattr_fidp->fs.xattr.name, &name);
+    if (size) {
+        xattr_fidp->fs.xattr.value = qemu_malloc(size);
+    } else {
+        xattr_fidp->fs.xattr.value = NULL;
+    }
+    err = offset;
 out:
-    complete_pdu(s, vs->pdu, err);
-    v9fs_string_free(&vs->name);
-    qemu_free(vs);
+    complete_pdu(s, pdu, err);
+    v9fs_string_free(&name);
 }
 
 static void v9fs_readlink(void *opaque)
diff --git a/hw/9pfs/virtio-9p.h b/hw/9pfs/virtio-9p.h
index 6a82649..3ed46ab 100644
--- a/hw/9pfs/virtio-9p.h
+++ b/hw/9pfs/virtio-9p.h
@@ -399,17 +399,6 @@ typedef struct V9fsRenameState {
     V9fsString name;
 } V9fsRenameState;
 
-typedef struct V9fsXattrState
-{
-    V9fsPDU *pdu;
-    size_t offset;
-    V9fsFidState *file_fidp;
-    V9fsFidState *xattr_fidp;
-    V9fsString name;
-    int64_t size;
-    int flags;
-    void *value;
-} V9fsXattrState;
 
 #define P9_LOCK_SUCCESS 0
 #define P9_LOCK_BLOCKED 1
commit 670185a64166c93d58df256c5f8ebd7596341f43
Author: Aneesh Kumar K.V <aneesh.kumar at linux.vnet.ibm.com>
Date:   Wed May 18 16:05:48 2011 -0700

    hw/9pfs: Update v9fs_xattrwalk to coroutines
    
    Signed-off-by: Aneesh Kumar K.V <aneesh.kumar at linux.vnet.ibm.com>

diff --git a/hw/9pfs/virtio-9p.c b/hw/9pfs/virtio-9p.c
index fae0900..124ca55 100644
--- a/hw/9pfs/virtio-9p.c
+++ b/hw/9pfs/virtio-9p.c
@@ -239,21 +239,6 @@ static int v9fs_do_statfs(V9fsState *s, V9fsString *path, struct statfs *stbuf)
     return s->ops->statfs(&s->ctx, path->data, stbuf);
 }
 
-static ssize_t v9fs_do_lgetxattr(V9fsState *s, V9fsString *path,
-                             V9fsString *xattr_name,
-                             void *value, size_t size)
-{
-    return s->ops->lgetxattr(&s->ctx, path->data,
-                             xattr_name->data, value, size);
-}
-
-static ssize_t v9fs_do_llistxattr(V9fsState *s, V9fsString *path,
-                              void *value, size_t size)
-{
-    return s->ops->llistxattr(&s->ctx, path->data,
-                              value, size);
-}
-
 static int v9fs_do_lsetxattr(V9fsState *s, V9fsString *path,
                              V9fsString *xattr_name,
                              void *value, size_t size, int flags)
@@ -3271,149 +3256,92 @@ out:
     qemu_free(vs);
 }
 
-static void v9fs_post_xattr_getvalue(V9fsState *s, V9fsXattrState *vs, int err)
-{
-
-    if (err < 0) {
-        err = -errno;
-        free_fid(s, vs->xattr_fidp->fid);
-        goto out;
-    }
-    vs->offset += pdu_marshal(vs->pdu, vs->offset, "q", vs->size);
-    err = vs->offset;
-out:
-    complete_pdu(s, vs->pdu, err);
-    v9fs_string_free(&vs->name);
-    qemu_free(vs);
-    return;
-}
-
-static void v9fs_post_xattr_check(V9fsState *s, V9fsXattrState *vs, ssize_t err)
-{
-    if (err < 0) {
-        err = -errno;
-        free_fid(s, vs->xattr_fidp->fid);
-        goto out;
-    }
-    /*
-     * Read the xattr value
-     */
-    vs->xattr_fidp->fs.xattr.len = vs->size;
-    vs->xattr_fidp->fid_type = P9_FID_XATTR;
-    vs->xattr_fidp->fs.xattr.copied_len = -1;
-    if (vs->size) {
-        vs->xattr_fidp->fs.xattr.value = qemu_malloc(vs->size);
-        err = v9fs_do_lgetxattr(s, &vs->xattr_fidp->path,
-                                &vs->name, vs->xattr_fidp->fs.xattr.value,
-                                vs->xattr_fidp->fs.xattr.len);
-    }
-    v9fs_post_xattr_getvalue(s, vs, err);
-    return;
-out:
-    complete_pdu(s, vs->pdu, err);
-    v9fs_string_free(&vs->name);
-    qemu_free(vs);
-}
-
-static void v9fs_post_lxattr_getvalue(V9fsState *s,
-                                      V9fsXattrState *vs, int err)
-{
-    if (err < 0) {
-        err = -errno;
-        free_fid(s, vs->xattr_fidp->fid);
-        goto out;
-    }
-    vs->offset += pdu_marshal(vs->pdu, vs->offset, "q", vs->size);
-    err = vs->offset;
-out:
-    complete_pdu(s, vs->pdu, err);
-    v9fs_string_free(&vs->name);
-    qemu_free(vs);
-    return;
-}
-
-static void v9fs_post_lxattr_check(V9fsState *s,
-                                   V9fsXattrState *vs, ssize_t err)
-{
-    if (err < 0) {
-        err = -errno;
-        free_fid(s, vs->xattr_fidp->fid);
-        goto out;
-    }
-    /*
-     * Read the xattr value
-     */
-    vs->xattr_fidp->fs.xattr.len = vs->size;
-    vs->xattr_fidp->fid_type = P9_FID_XATTR;
-    vs->xattr_fidp->fs.xattr.copied_len = -1;
-    if (vs->size) {
-        vs->xattr_fidp->fs.xattr.value = qemu_malloc(vs->size);
-        err = v9fs_do_llistxattr(s, &vs->xattr_fidp->path,
-                                 vs->xattr_fidp->fs.xattr.value,
-                                 vs->xattr_fidp->fs.xattr.len);
-    }
-    v9fs_post_lxattr_getvalue(s, vs, err);
-    return;
-out:
-    complete_pdu(s, vs->pdu, err);
-    v9fs_string_free(&vs->name);
-    qemu_free(vs);
-}
-
 static void v9fs_xattrwalk(void *opaque)
 {
-    V9fsPDU *pdu = opaque;
-    V9fsState *s = pdu->s;
+    int64_t size;
+    V9fsString name;
     ssize_t err = 0;
-    V9fsXattrState *vs;
+    size_t offset = 7;
     int32_t fid, newfid;
+    V9fsFidState *file_fidp;
+    V9fsFidState *xattr_fidp;
+    V9fsPDU *pdu = opaque;
+    V9fsState *s = pdu->s;
 
-    vs = qemu_malloc(sizeof(*vs));
-    vs->pdu = pdu;
-    vs->offset = 7;
-
-    pdu_unmarshal(vs->pdu, vs->offset, "dds", &fid, &newfid, &vs->name);
-    vs->file_fidp = lookup_fid(s, fid);
-    if (vs->file_fidp == NULL) {
+    pdu_unmarshal(pdu, offset, "dds", &fid, &newfid, &name);
+    file_fidp = lookup_fid(s, fid);
+    if (file_fidp == NULL) {
         err = -ENOENT;
         goto out;
     }
-
-    vs->xattr_fidp = alloc_fid(s, newfid);
-    if (vs->xattr_fidp == NULL) {
+    xattr_fidp = alloc_fid(s, newfid);
+    if (xattr_fidp == NULL) {
         err = -EINVAL;
         goto out;
     }
-
-    v9fs_string_copy(&vs->xattr_fidp->path, &vs->file_fidp->path);
-    if (vs->name.data[0] == 0) {
+    v9fs_string_copy(&xattr_fidp->path, &file_fidp->path);
+    if (name.data[0] == 0) {
         /*
          * listxattr request. Get the size first
          */
-        vs->size = v9fs_do_llistxattr(s, &vs->xattr_fidp->path,
-                                      NULL, 0);
-        if (vs->size < 0) {
-            err = vs->size;
+        size = v9fs_co_llistxattr(s, &xattr_fidp->path, NULL, 0);
+        if (size < 0) {
+            err = size;
+            free_fid(s, xattr_fidp->fid);
+            goto out;
         }
-        v9fs_post_lxattr_check(s, vs, err);
-        return;
+        /*
+         * Read the xattr value
+         */
+        xattr_fidp->fs.xattr.len = size;
+        xattr_fidp->fid_type = P9_FID_XATTR;
+        xattr_fidp->fs.xattr.copied_len = -1;
+        if (size) {
+            xattr_fidp->fs.xattr.value = qemu_malloc(size);
+            err = v9fs_co_llistxattr(s, &xattr_fidp->path,
+                                     xattr_fidp->fs.xattr.value,
+                                     xattr_fidp->fs.xattr.len);
+            if (err < 0) {
+                free_fid(s, xattr_fidp->fid);
+                goto out;
+            }
+        }
+        offset += pdu_marshal(pdu, offset, "q", size);
+        err = offset;
     } else {
         /*
          * specific xattr fid. We check for xattr
          * presence also collect the xattr size
          */
-        vs->size = v9fs_do_lgetxattr(s, &vs->xattr_fidp->path,
-                                     &vs->name, NULL, 0);
-        if (vs->size < 0) {
-            err = vs->size;
+        size = v9fs_co_lgetxattr(s, &xattr_fidp->path,
+                                 &name, NULL, 0);
+        if (size < 0) {
+            err = size;
+            free_fid(s, xattr_fidp->fid);
+            goto out;
         }
-        v9fs_post_xattr_check(s, vs, err);
-        return;
+        /*
+         * Read the xattr value
+         */
+        xattr_fidp->fs.xattr.len = size;
+        xattr_fidp->fid_type = P9_FID_XATTR;
+        xattr_fidp->fs.xattr.copied_len = -1;
+        if (size) {
+            xattr_fidp->fs.xattr.value = qemu_malloc(size);
+            err = v9fs_co_lgetxattr(s, &xattr_fidp->path,
+                                    &name, xattr_fidp->fs.xattr.value,
+                                    xattr_fidp->fs.xattr.len);
+            if (err < 0) {
+                free_fid(s, xattr_fidp->fid);
+                goto out;
+            }
+        }
+        offset += pdu_marshal(pdu, offset, "q", size);
+        err = offset;
     }
 out:
-    complete_pdu(s, vs->pdu, err);
-    v9fs_string_free(&vs->name);
-    qemu_free(vs);
+    complete_pdu(s, pdu, err);
+    v9fs_string_free(&name);
 }
 
 static void v9fs_xattrcreate(void *opaque)
commit 1ceffa546aa756e8085828df2e33c7e6463a307c
Author: Aneesh Kumar K.V <aneesh.kumar at linux.vnet.ibm.com>
Date:   Wed May 18 16:05:34 2011 -0700

    hw/9pfs: Add yield support to xattr related coroutine
    
    This include llistxattr and lgetxattr.
    
    Signed-off-by: Aneesh Kumar K.V <aneesh.kumar at linux.vnet.ibm.com>

diff --git a/Makefile.objs b/Makefile.objs
index efacf0f..16eef38 100644
--- a/Makefile.objs
+++ b/Makefile.objs
@@ -306,6 +306,7 @@ hw-obj-$(CONFIG_SOUND) += $(sound-obj-y)
 9pfs-nested-$(CONFIG_VIRTFS) +=  virtio-9p-local.o virtio-9p-xattr.o
 9pfs-nested-$(CONFIG_VIRTFS) +=   virtio-9p-xattr-user.o virtio-9p-posix-acl.o
 9pfs-nested-$(CONFIG_VIRTFS) += virtio-9p-coth.o cofs.o codir.o cofile.o
+9pfs-nested-$(CONFIG_VIRTFS) += coxattr.o
 
 hw-obj-$(CONFIG_REALLY_VIRTFS) += $(addprefix 9pfs/, $(9pfs-nested-y))
 $(addprefix 9pfs/, $(9pfs-nested-y)): QEMU_CFLAGS+=$(GLIB_CFLAGS)
diff --git a/hw/9pfs/coxattr.c b/hw/9pfs/coxattr.c
new file mode 100644
index 0000000..2fba2c9
--- /dev/null
+++ b/hw/9pfs/coxattr.c
@@ -0,0 +1,50 @@
+
+/*
+ * Virtio 9p backend
+ *
+ * Copyright IBM, Corp. 2011
+ *
+ * Authors:
+ *  Aneesh Kumar K.V <aneesh.kumar at linux.vnet.ibm.com>
+ *
+ * This work is licensed under the terms of the GNU GPL, version 2.  See
+ * the COPYING file in the top-level directory.
+ *
+ */
+
+#include "fsdev/qemu-fsdev.h"
+#include "qemu-thread.h"
+#include "qemu-coroutine.h"
+#include "virtio-9p-coth.h"
+
+int v9fs_co_llistxattr(V9fsState *s, V9fsString *path, void *value, size_t size)
+{
+    int err;
+
+    v9fs_co_run_in_worker(
+        {
+            err = s->ops->llistxattr(&s->ctx, path->data, value, size);
+            if (err < 0) {
+                err = -errno;
+            }
+        });
+    return err;
+}
+
+int v9fs_co_lgetxattr(V9fsState *s, V9fsString *path,
+                      V9fsString *xattr_name,
+                      void *value, size_t size)
+{
+    int err;
+
+    v9fs_co_run_in_worker(
+        {
+            err = s->ops->lgetxattr(&s->ctx, path->data,
+                                    xattr_name->data,
+                                    value, size);
+            if (err < 0) {
+                err = -errno;
+            }
+        });
+    return err;
+}
diff --git a/hw/9pfs/virtio-9p-coth.h b/hw/9pfs/virtio-9p-coth.h
index 09f232a..eb0c99a 100644
--- a/hw/9pfs/virtio-9p-coth.h
+++ b/hw/9pfs/virtio-9p-coth.h
@@ -68,4 +68,7 @@ extern int v9fs_co_chmod(V9fsState *, V9fsString *, mode_t);
 extern int v9fs_co_utimensat(V9fsState *, V9fsString *, struct timespec [2]);
 extern int v9fs_co_chown(V9fsState *, V9fsString *, uid_t, gid_t);
 extern int v9fs_co_truncate(V9fsState *, V9fsString *, off_t);
+extern int v9fs_co_llistxattr(V9fsState *, V9fsString *, void *, size_t);
+extern int v9fs_co_lgetxattr(V9fsState *, V9fsString *,
+                             V9fsString *, void *, size_t);
 #endif
commit 65c05f9a540faa9237301d8504a70ee7854eb910
Author: Aneesh Kumar K.V <aneesh.kumar at linux.vnet.ibm.com>
Date:   Wed May 18 16:05:10 2011 -0700

    hw/9pfs: Update v9fs_setattr to use coroutines
    
    Signed-off-by: Aneesh Kumar K.V <aneesh.kumar at linux.vnet.ibm.com>

diff --git a/hw/9pfs/virtio-9p.c b/hw/9pfs/virtio-9p.c
index 9fb1b3f..fae0900 100644
--- a/hw/9pfs/virtio-9p.c
+++ b/hw/9pfs/virtio-9p.c
@@ -1329,139 +1329,84 @@ out:
 #define ATTR_ATIME_SET  (1 << 7)
 #define ATTR_MTIME_SET  (1 << 8)
 
-static void v9fs_setattr_post_truncate(V9fsState *s, V9fsSetattrState *vs,
-                                                                  int err)
-{
-    if (err == -1) {
-        err = -errno;
-        goto out;
-    }
-    err = vs->offset;
-
-out:
-    complete_pdu(s, vs->pdu, err);
-    qemu_free(vs);
-}
-
-static void v9fs_setattr_post_chown(V9fsState *s, V9fsSetattrState *vs, int err)
+static void v9fs_setattr(void *opaque)
 {
-    if (err == -1) {
-        err = -errno;
-        goto out;
-    }
+    int err = 0;
+    int32_t fid;
+    V9fsFidState *fidp;
+    size_t offset = 7;
+    V9fsIattr v9iattr;
+    V9fsPDU *pdu = opaque;
+    V9fsState *s = pdu->s;
 
-    if (vs->v9iattr.valid & (ATTR_SIZE)) {
-        err = v9fs_do_truncate(s, &vs->fidp->path, vs->v9iattr.size);
-    }
-    v9fs_setattr_post_truncate(s, vs, err);
-    return;
+    pdu_unmarshal(pdu, offset, "dI", &fid, &v9iattr);
 
-out:
-    complete_pdu(s, vs->pdu, err);
-    qemu_free(vs);
-}
-
-static void v9fs_setattr_post_utimensat(V9fsState *s, V9fsSetattrState *vs,
-                                                                   int err)
-{
-    if (err == -1) {
-        err = -errno;
+    fidp = lookup_fid(s, fid);
+    if (fidp == NULL) {
+        err = -EINVAL;
         goto out;
     }
-
-    /* If the only valid entry in iattr is ctime we can call
-     * chown(-1,-1) to update the ctime of the file
-     */
-    if ((vs->v9iattr.valid & (ATTR_UID | ATTR_GID)) ||
-            ((vs->v9iattr.valid & ATTR_CTIME)
-            && !((vs->v9iattr.valid & ATTR_MASK) & ~ATTR_CTIME))) {
-        if (!(vs->v9iattr.valid & ATTR_UID)) {
-            vs->v9iattr.uid = -1;
-        }
-        if (!(vs->v9iattr.valid & ATTR_GID)) {
-            vs->v9iattr.gid = -1;
+    if (v9iattr.valid & ATTR_MODE) {
+        err = v9fs_co_chmod(s, &fidp->path, v9iattr.mode);
+        if (err < 0) {
+            goto out;
         }
-        err = v9fs_do_chown(s, &vs->fidp->path, vs->v9iattr.uid,
-                                                vs->v9iattr.gid);
     }
-    v9fs_setattr_post_chown(s, vs, err);
-    return;
-
-out:
-    complete_pdu(s, vs->pdu, err);
-    qemu_free(vs);
-}
-
-static void v9fs_setattr_post_chmod(V9fsState *s, V9fsSetattrState *vs, int err)
-{
-    if (err == -1) {
-        err = -errno;
-        goto out;
-    }
-
-    if (vs->v9iattr.valid & (ATTR_ATIME | ATTR_MTIME)) {
+    if (v9iattr.valid & (ATTR_ATIME | ATTR_MTIME)) {
         struct timespec times[2];
-        if (vs->v9iattr.valid & ATTR_ATIME) {
-            if (vs->v9iattr.valid & ATTR_ATIME_SET) {
-                times[0].tv_sec = vs->v9iattr.atime_sec;
-                times[0].tv_nsec = vs->v9iattr.atime_nsec;
+        if (v9iattr.valid & ATTR_ATIME) {
+            if (v9iattr.valid & ATTR_ATIME_SET) {
+                times[0].tv_sec = v9iattr.atime_sec;
+                times[0].tv_nsec = v9iattr.atime_nsec;
             } else {
                 times[0].tv_nsec = UTIME_NOW;
             }
         } else {
             times[0].tv_nsec = UTIME_OMIT;
         }
-
-        if (vs->v9iattr.valid & ATTR_MTIME) {
-            if (vs->v9iattr.valid & ATTR_MTIME_SET) {
-                times[1].tv_sec = vs->v9iattr.mtime_sec;
-                times[1].tv_nsec = vs->v9iattr.mtime_nsec;
+        if (v9iattr.valid & ATTR_MTIME) {
+            if (v9iattr.valid & ATTR_MTIME_SET) {
+                times[1].tv_sec = v9iattr.mtime_sec;
+                times[1].tv_nsec = v9iattr.mtime_nsec;
             } else {
                 times[1].tv_nsec = UTIME_NOW;
             }
         } else {
             times[1].tv_nsec = UTIME_OMIT;
         }
-        err = v9fs_do_utimensat(s, &vs->fidp->path, times);
+        err = v9fs_co_utimensat(s, &fidp->path, times);
+        if (err < 0) {
+            goto out;
+        }
     }
-    v9fs_setattr_post_utimensat(s, vs, err);
-    return;
-
-out:
-    complete_pdu(s, vs->pdu, err);
-    qemu_free(vs);
-}
-
-static void v9fs_setattr(void *opaque)
-{
-    V9fsPDU *pdu = opaque;
-    V9fsState *s = pdu->s;
-    int32_t fid;
-    V9fsSetattrState *vs;
-    int err = 0;
-
-    vs = qemu_malloc(sizeof(*vs));
-    vs->pdu = pdu;
-    vs->offset = 7;
-
-    pdu_unmarshal(pdu, vs->offset, "dI", &fid, &vs->v9iattr);
-
-    vs->fidp = lookup_fid(s, fid);
-    if (vs->fidp == NULL) {
-        err = -EINVAL;
-        goto out;
+    /*
+     * If the only valid entry in iattr is ctime we can call
+     * chown(-1,-1) to update the ctime of the file
+     */
+    if ((v9iattr.valid & (ATTR_UID | ATTR_GID)) ||
+        ((v9iattr.valid & ATTR_CTIME)
+         && !((v9iattr.valid & ATTR_MASK) & ~ATTR_CTIME))) {
+        if (!(v9iattr.valid & ATTR_UID)) {
+            v9iattr.uid = -1;
+        }
+        if (!(v9iattr.valid & ATTR_GID)) {
+            v9iattr.gid = -1;
+        }
+        err = v9fs_co_chown(s, &fidp->path, v9iattr.uid,
+                            v9iattr.gid);
+        if (err < 0) {
+            goto out;
+        }
     }
-
-    if (vs->v9iattr.valid & ATTR_MODE) {
-        err = v9fs_do_chmod(s, &vs->fidp->path, vs->v9iattr.mode);
+    if (v9iattr.valid & (ATTR_SIZE)) {
+        err = v9fs_co_truncate(s, &fidp->path, v9iattr.size);
+        if (err < 0) {
+            goto out;
+        }
     }
-
-    v9fs_setattr_post_chmod(s, vs, err);
-    return;
-
+    err = offset;
 out:
-    complete_pdu(s, vs->pdu, err);
-    qemu_free(vs);
+    complete_pdu(s, pdu, err);
 }
 
 static void v9fs_walk_complete(V9fsState *s, V9fsWalkState *vs, int err)
diff --git a/hw/9pfs/virtio-9p.h b/hw/9pfs/virtio-9p.h
index a62eda0..6a82649 100644
--- a/hw/9pfs/virtio-9p.h
+++ b/hw/9pfs/virtio-9p.h
@@ -374,14 +374,6 @@ typedef struct V9fsIattr
     int64_t mtime_nsec;
 } V9fsIattr;
 
-typedef struct V9fsSetattrState
-{
-    V9fsPDU *pdu;
-    size_t offset;
-    V9fsIattr v9iattr;
-    V9fsFidState *fidp;
-} V9fsSetattrState;
-
 struct virtio_9p_config
 {
     /* number of characters in tag */
commit 4011ead2fdba4da764ffef3dbcf00d2f7772cdb9
Author: Aneesh Kumar K.V <aneesh.kumar at linux.vnet.ibm.com>
Date:   Wed May 18 16:04:58 2011 -0700

    hw/9pfs: Add yield support to setattr related coroutines
    
    This include chmod, utimensat, chown and truncate.
    
    Signed-off-by: Aneesh Kumar K.V <aneesh.kumar at linux.vnet.ibm.com>

diff --git a/hw/9pfs/cofs.c b/hw/9pfs/cofs.c
index 4138e4d..7e9df85 100644
--- a/hw/9pfs/cofs.c
+++ b/hw/9pfs/cofs.c
@@ -56,3 +56,67 @@ int v9fs_co_statfs(V9fsState *s, V9fsString *path, struct statfs *stbuf)
         });
     return err;
 }
+
+int v9fs_co_chmod(V9fsState *s, V9fsString *path, mode_t mode)
+{
+    int err;
+    FsCred cred;
+
+    cred_init(&cred);
+    cred.fc_mode = mode;
+    v9fs_co_run_in_worker(
+        {
+            err = s->ops->chmod(&s->ctx, path->data, &cred);
+            if (err < 0) {
+                err = -errno;
+            }
+        });
+    return err;
+}
+
+int v9fs_co_utimensat(V9fsState *s, V9fsString *path,
+                      struct timespec times[2])
+{
+    int err;
+
+    v9fs_co_run_in_worker(
+        {
+            err = s->ops->utimensat(&s->ctx, path->data, times);
+            if (err < 0) {
+                err = -errno;
+            }
+        });
+    return err;
+}
+
+int v9fs_co_chown(V9fsState *s, V9fsString *path, uid_t uid, gid_t gid)
+{
+    int err;
+    FsCred cred;
+
+    cred_init(&cred);
+    cred.fc_uid = uid;
+    cred.fc_gid = gid;
+    v9fs_co_run_in_worker(
+        {
+            err = s->ops->chown(&s->ctx, path->data, &cred);
+            if (err < 0) {
+                err = -errno;
+            }
+        });
+    return err;
+}
+
+int v9fs_co_truncate(V9fsState *s, V9fsString *path, off_t size)
+{
+    int err;
+
+    v9fs_co_run_in_worker(
+        {
+            err = s->ops->truncate(&s->ctx, path->data, size);
+            if (err < 0) {
+                err = -errno;
+            }
+        });
+    return err;
+}
diff --git a/hw/9pfs/virtio-9p-coth.h b/hw/9pfs/virtio-9p-coth.h
index 3538d91..09f232a 100644
--- a/hw/9pfs/virtio-9p-coth.h
+++ b/hw/9pfs/virtio-9p-coth.h
@@ -64,4 +64,8 @@ extern void v9fs_co_seekdir(V9fsState *, V9fsFidState *, off_t);
 extern void v9fs_co_rewinddir(V9fsState *, V9fsFidState *);
 extern int v9fs_co_statfs(V9fsState *, V9fsString *, struct statfs *);
 extern int v9fs_co_lstat(V9fsState *, V9fsString *, struct stat *);
+extern int v9fs_co_chmod(V9fsState *, V9fsString *, mode_t);
+extern int v9fs_co_utimensat(V9fsState *, V9fsString *, struct timespec [2]);
+extern int v9fs_co_chown(V9fsState *, V9fsString *, uid_t, gid_t);
+extern int v9fs_co_truncate(V9fsState *, V9fsString *, off_t);
 #endif
commit 8db21ce73aab5e8c47053c9a7d3a833ee62de2d4
Author: Aneesh Kumar K.V <aneesh.kumar at linux.vnet.ibm.com>
Date:   Wed May 18 16:04:33 2011 -0700

    hw/9pfs: Update v9fs_getattr to use coroutines
    
    Signed-off-by: Aneesh Kumar K.V <aneesh.kumar at linux.vnet.ibm.com>

diff --git a/hw/9pfs/virtio-9p.c b/hw/9pfs/virtio-9p.c
index 69ef717..9fb1b3f 100644
--- a/hw/9pfs/virtio-9p.c
+++ b/hw/9pfs/virtio-9p.c
@@ -1086,7 +1086,7 @@ static int stat_to_v9stat(V9fsState *s, V9fsString *name,
 
 
 static void stat_to_v9stat_dotl(V9fsState *s, const struct stat *stbuf,
-                            V9fsStatDotl *v9lstat)
+                                V9fsStatDotl *v9lstat)
 {
     memset(v9lstat, 0, sizeof(*v9lstat));
 
@@ -1283,57 +1283,38 @@ out:
     qemu_free(vs);
 }
 
-static void v9fs_getattr_post_lstat(V9fsState *s, V9fsStatStateDotl *vs,
-                                                                int err)
-{
-    if (err == -1) {
-        err = -errno;
-        goto out;
-    }
-
-    stat_to_v9stat_dotl(s, &vs->stbuf, &vs->v9stat_dotl);
-    vs->offset += pdu_marshal(vs->pdu, vs->offset, "A", &vs->v9stat_dotl);
-    err = vs->offset;
-
-out:
-    complete_pdu(s, vs->pdu, err);
-    qemu_free(vs);
-}
-
 static void v9fs_getattr(void *opaque)
 {
-    V9fsPDU *pdu = opaque;
-    V9fsState *s = pdu->s;
     int32_t fid;
-    V9fsStatStateDotl *vs;
-    ssize_t err = 0;
+    size_t offset = 7;
+    ssize_t retval = 0;
+    struct stat stbuf;
     V9fsFidState *fidp;
     uint64_t request_mask;
+    V9fsStatDotl v9stat_dotl;
+    V9fsPDU *pdu = opaque;
+    V9fsState *s = pdu->s;
 
-    vs = qemu_malloc(sizeof(*vs));
-    vs->pdu = pdu;
-    vs->offset = 7;
-
-    memset(&vs->v9stat_dotl, 0, sizeof(vs->v9stat_dotl));
-
-    pdu_unmarshal(vs->pdu, vs->offset, "dq", &fid, &request_mask);
+    pdu_unmarshal(pdu, offset, "dq", &fid, &request_mask);
 
     fidp = lookup_fid(s, fid);
     if (fidp == NULL) {
-        err = -ENOENT;
+        retval = -ENOENT;
         goto out;
     }
-
-    /* Currently we only support BASIC fields in stat, so there is no
+    /*
+     * Currently we only support BASIC fields in stat, so there is no
      * need to look at request_mask.
      */
-    err = v9fs_do_lstat(s, &fidp->path, &vs->stbuf);
-    v9fs_getattr_post_lstat(s, vs, err);
-    return;
-
+    retval = v9fs_co_lstat(s, &fidp->path, &stbuf);
+    if (retval < 0) {
+        goto out;
+    }
+    stat_to_v9stat_dotl(s, &stbuf, &v9stat_dotl);
+    retval = offset;
+    retval += pdu_marshal(pdu, offset, "A", &v9stat_dotl);
 out:
-    complete_pdu(s, vs->pdu, err);
-    qemu_free(vs);
+    complete_pdu(s, pdu, retval);
 }
 
 /* From Linux kernel code */
diff --git a/hw/9pfs/virtio-9p.h b/hw/9pfs/virtio-9p.h
index eb6cd23..a62eda0 100644
--- a/hw/9pfs/virtio-9p.h
+++ b/hw/9pfs/virtio-9p.h
@@ -278,14 +278,6 @@ typedef struct V9fsStatDotl {
     uint64_t st_data_version;
 } V9fsStatDotl;
 
-typedef struct V9fsStatStateDotl {
-    V9fsPDU *pdu;
-    size_t offset;
-    V9fsStatDotl v9stat_dotl;
-    struct stat stbuf;
-} V9fsStatStateDotl;
-
-
 typedef struct V9fsWalkState {
     V9fsPDU *pdu;
     size_t offset;
commit 172198d4db28d537f9e2cfb8af3fef9cd4d2b543
Author: Aneesh Kumar K.V <aneesh.kumar at linux.vnet.ibm.com>
Date:   Wed May 18 16:04:13 2011 -0700

    hw/9pfs: Add yield support to lstat coroutine
    
    Signed-off-by: Aneesh Kumar K.V <aneesh.kumar at linux.vnet.ibm.com>

diff --git a/Makefile.objs b/Makefile.objs
index faa2a12..efacf0f 100644
--- a/Makefile.objs
+++ b/Makefile.objs
@@ -305,7 +305,7 @@ hw-obj-$(CONFIG_SOUND) += $(sound-obj-y)
 9pfs-nested-$(CONFIG_VIRTFS) = virtio-9p.o virtio-9p-debug.o
 9pfs-nested-$(CONFIG_VIRTFS) +=  virtio-9p-local.o virtio-9p-xattr.o
 9pfs-nested-$(CONFIG_VIRTFS) +=   virtio-9p-xattr-user.o virtio-9p-posix-acl.o
-9pfs-nested-$(CONFIG_VIRTFS) += virtio-9p-coth.o cofs.o codir.o
+9pfs-nested-$(CONFIG_VIRTFS) += virtio-9p-coth.o cofs.o codir.o cofile.o
 
 hw-obj-$(CONFIG_REALLY_VIRTFS) += $(addprefix 9pfs/, $(9pfs-nested-y))
 $(addprefix 9pfs/, $(9pfs-nested-y)): QEMU_CFLAGS+=$(GLIB_CFLAGS)
diff --git a/hw/9pfs/cofile.c b/hw/9pfs/cofile.c
new file mode 100644
index 0000000..a4c0ae7
--- /dev/null
+++ b/hw/9pfs/cofile.c
@@ -0,0 +1,32 @@
+
+/*
+ * Virtio 9p backend
+ *
+ * Copyright IBM, Corp. 2011
+ *
+ * Authors:
+ *  Aneesh Kumar K.V <aneesh.kumar at linux.vnet.ibm.com>
+ *
+ * This work is licensed under the terms of the GNU GPL, version 2.  See
+ * the COPYING file in the top-level directory.
+ *
+ */
+
+#include "fsdev/qemu-fsdev.h"
+#include "qemu-thread.h"
+#include "qemu-coroutine.h"
+#include "virtio-9p-coth.h"
+
+int v9fs_co_lstat(V9fsState *s, V9fsString *path, struct stat *stbuf)
+{
+    int err;
+
+    v9fs_co_run_in_worker(
+        {
+            err = s->ops->lstat(&s->ctx, path->data, stbuf);
+            if (err < 0) {
+                err = -errno;
+            }
+        });
+    return err;
+}
diff --git a/hw/9pfs/virtio-9p-coth.h b/hw/9pfs/virtio-9p-coth.h
index 5d9dc0f..3538d91 100644
--- a/hw/9pfs/virtio-9p-coth.h
+++ b/hw/9pfs/virtio-9p-coth.h
@@ -63,4 +63,5 @@ extern off_t v9fs_co_telldir(V9fsState *, V9fsFidState *);
 extern void v9fs_co_seekdir(V9fsState *, V9fsFidState *, off_t);
 extern void v9fs_co_rewinddir(V9fsState *, V9fsFidState *);
 extern int v9fs_co_statfs(V9fsState *, V9fsString *, struct statfs *);
+extern int v9fs_co_lstat(V9fsState *, V9fsString *, struct stat *);
 #endif
commit 88a4763e88e7724e739515d3e2c734f7ec0ea9cf
Author: Aneesh Kumar K.V <aneesh.kumar at linux.vnet.ibm.com>
Date:   Wed May 18 16:04:01 2011 -0700

    hw/9pfs: Update v9fs_statfs to use coroutines
    
    Signed-off-by: Aneesh Kumar K.V <aneesh.kumar at linux.vnet.ibm.com>

diff --git a/hw/9pfs/virtio-9p.c b/hw/9pfs/virtio-9p.c
index 3f5e459..69ef717 100644
--- a/hw/9pfs/virtio-9p.c
+++ b/hw/9pfs/virtio-9p.c
@@ -3036,79 +3036,75 @@ out:
     qemu_free(vs);
 }
 
-static void v9fs_statfs_post_statfs(V9fsState *s, V9fsStatfsState *vs, int err)
-{
+static int v9fs_fill_statfs(V9fsState *s, V9fsPDU *pdu, struct statfs *stbuf)
+{
+    uint32_t f_type;
+    uint32_t f_bsize;
+    uint64_t f_blocks;
+    uint64_t f_bfree;
+    uint64_t f_bavail;
+    uint64_t f_files;
+    uint64_t f_ffree;
+    uint64_t fsid_val;
+    uint32_t f_namelen;
+    size_t offset = 7;
     int32_t bsize_factor;
 
-    if (err) {
-        err = -errno;
-        goto out;
-    }
-
     /*
      * compute bsize factor based on host file system block size
      * and client msize
      */
-    bsize_factor = (s->msize - P9_IOHDRSZ)/vs->stbuf.f_bsize;
+    bsize_factor = (s->msize - P9_IOHDRSZ)/stbuf->f_bsize;
     if (!bsize_factor) {
         bsize_factor = 1;
     }
-    vs->v9statfs.f_type = vs->stbuf.f_type;
-    vs->v9statfs.f_bsize = vs->stbuf.f_bsize;
-    vs->v9statfs.f_bsize *= bsize_factor;
+    f_type  = stbuf->f_type;
+    f_bsize = stbuf->f_bsize;
+    f_bsize *= bsize_factor;
     /*
      * f_bsize is adjusted(multiplied) by bsize factor, so we need to
      * adjust(divide) the number of blocks, free blocks and available
      * blocks by bsize factor
      */
-    vs->v9statfs.f_blocks = vs->stbuf.f_blocks/bsize_factor;
-    vs->v9statfs.f_bfree = vs->stbuf.f_bfree/bsize_factor;
-    vs->v9statfs.f_bavail = vs->stbuf.f_bavail/bsize_factor;
-    vs->v9statfs.f_files = vs->stbuf.f_files;
-    vs->v9statfs.f_ffree = vs->stbuf.f_ffree;
-    vs->v9statfs.fsid_val = (unsigned int) vs->stbuf.f_fsid.__val[0] |
-			(unsigned long long)vs->stbuf.f_fsid.__val[1] << 32;
-    vs->v9statfs.f_namelen = vs->stbuf.f_namelen;
-
-    vs->offset += pdu_marshal(vs->pdu, vs->offset, "ddqqqqqqd",
-         vs->v9statfs.f_type, vs->v9statfs.f_bsize, vs->v9statfs.f_blocks,
-         vs->v9statfs.f_bfree, vs->v9statfs.f_bavail, vs->v9statfs.f_files,
-         vs->v9statfs.f_ffree, vs->v9statfs.fsid_val,
-         vs->v9statfs.f_namelen);
+    f_blocks = stbuf->f_blocks/bsize_factor;
+    f_bfree  = stbuf->f_bfree/bsize_factor;
+    f_bavail = stbuf->f_bavail/bsize_factor;
+    f_files  = stbuf->f_files;
+    f_ffree  = stbuf->f_ffree;
+    fsid_val = (unsigned int) stbuf->f_fsid.__val[0] |
+               (unsigned long long)stbuf->f_fsid.__val[1] << 32;
+    f_namelen = stbuf->f_namelen;
 
-out:
-    complete_pdu(s, vs->pdu, vs->offset);
-    qemu_free(vs);
+    return pdu_marshal(pdu, offset, "ddqqqqqqd",
+                       f_type, f_bsize, f_blocks, f_bfree,
+                       f_bavail, f_files, f_ffree,
+                       fsid_val, f_namelen);
 }
 
 static void v9fs_statfs(void *opaque)
 {
+    int32_t fid;
+    ssize_t retval = 0;
+    size_t offset = 7;
+    V9fsFidState *fidp;
+    struct statfs stbuf;
     V9fsPDU *pdu = opaque;
     V9fsState *s = pdu->s;
-    V9fsStatfsState *vs;
-    ssize_t err = 0;
 
-    vs = qemu_malloc(sizeof(*vs));
-    vs->pdu = pdu;
-    vs->offset = 7;
-
-    memset(&vs->v9statfs, 0, sizeof(vs->v9statfs));
-
-    pdu_unmarshal(vs->pdu, vs->offset, "d", &vs->fid);
-
-    vs->fidp = lookup_fid(s, vs->fid);
-    if (vs->fidp == NULL) {
-        err = -ENOENT;
+    pdu_unmarshal(pdu, offset, "d", &fid);
+    fidp = lookup_fid(s, fid);
+    if (fidp == NULL) {
+        retval = -ENOENT;
         goto out;
     }
-
-    err = v9fs_do_statfs(s, &vs->fidp->path, &vs->stbuf);
-    v9fs_statfs_post_statfs(s, vs, err);
-    return;
-
+    retval = v9fs_co_statfs(s, &fidp->path, &stbuf);
+    if (retval < 0) {
+        goto out;
+    }
+    retval = offset;
+    retval += v9fs_fill_statfs(s, pdu, &stbuf);
 out:
-    complete_pdu(s, vs->pdu, err);
-    qemu_free(vs);
+    complete_pdu(s, pdu, retval);
     return;
 }
 
diff --git a/hw/9pfs/virtio-9p.h b/hw/9pfs/virtio-9p.h
index 8196da0..eb6cd23 100644
--- a/hw/9pfs/virtio-9p.h
+++ b/hw/9pfs/virtio-9p.h
@@ -398,28 +398,6 @@ struct virtio_9p_config
     uint8_t tag[0];
 } __attribute__((packed));
 
-typedef struct V9fsStatfs
-{
-    uint32_t f_type;
-    uint32_t f_bsize;
-    uint64_t f_blocks;
-    uint64_t f_bfree;
-    uint64_t f_bavail;
-    uint64_t f_files;
-    uint64_t f_ffree;
-    uint64_t fsid_val;
-    uint32_t f_namelen;
-} V9fsStatfs;
-
-typedef struct V9fsStatfsState {
-    V9fsPDU *pdu;
-    size_t offset;
-    int32_t fid;
-    V9fsStatfs v9statfs;
-    V9fsFidState *fidp;
-    struct statfs stbuf;
-} V9fsStatfsState;
-
 typedef struct V9fsMkState {
     V9fsPDU *pdu;
     size_t offset;
commit 94840ff9f383d4f7099394cc53af48f0a7065132
Author: Aneesh Kumar K.V <aneesh.kumar at linux.vnet.ibm.com>
Date:   Wed May 18 16:03:49 2011 -0700

    hw/9pfs: Add yield support to statfs coroutine
    
    Signed-off-by: Aneesh Kumar K.V <aneesh.kumar at linux.vnet.ibm.com>

diff --git a/hw/9pfs/cofs.c b/hw/9pfs/cofs.c
index 6bb8b47..4138e4d 100644
--- a/hw/9pfs/cofs.c
+++ b/hw/9pfs/cofs.c
@@ -42,3 +42,17 @@ int v9fs_co_readlink(V9fsState *s, V9fsString *path, V9fsString *buf)
     }
     return err;
 }
+
+int v9fs_co_statfs(V9fsState *s, V9fsString *path, struct statfs *stbuf)
+{
+    int err;
+
+    v9fs_co_run_in_worker(
+        {
+            err = s->ops->statfs(&s->ctx, path->data, stbuf);
+            if (err < 0) {
+                err = -errno;
+            }
+        });
+    return err;
+}
diff --git a/hw/9pfs/virtio-9p-coth.h b/hw/9pfs/virtio-9p-coth.h
index 9aa5953..5d9dc0f 100644
--- a/hw/9pfs/virtio-9p-coth.h
+++ b/hw/9pfs/virtio-9p-coth.h
@@ -62,4 +62,5 @@ extern int v9fs_co_readdir(V9fsState *, V9fsFidState *,
 extern off_t v9fs_co_telldir(V9fsState *, V9fsFidState *);
 extern void v9fs_co_seekdir(V9fsState *, V9fsFidState *, off_t);
 extern void v9fs_co_rewinddir(V9fsState *, V9fsFidState *);
+extern int v9fs_co_statfs(V9fsState *, V9fsString *, struct statfs *);
 #endif
commit 5e4eaa79cf4645d200742901d449789dfa607230
Author: Aneesh Kumar K.V <aneesh.kumar at linux.vnet.ibm.com>
Date:   Wed May 18 15:57:17 2011 -0700

    hw/9pfs: Update v9fs_readdir to use coroutines
    
    Signed-off-by: Aneesh Kumar K.V <aneesh.kumar at linux.vnet.ibm.com>

diff --git a/hw/9pfs/virtio-9p.c b/hw/9pfs/virtio-9p.c
index a68ac3f..3f5e459 100644
--- a/hw/9pfs/virtio-9p.c
+++ b/hw/9pfs/virtio-9p.c
@@ -112,11 +112,6 @@ static off_t v9fs_do_telldir(V9fsState *s, DIR *dir)
     return s->ops->telldir(&s->ctx, dir);
 }
 
-static struct dirent *v9fs_do_readdir(V9fsState *s, DIR *dir)
-{
-    return s->ops->readdir(&s->ctx, dir);
-}
-
 static void v9fs_do_seekdir(V9fsState *s, DIR *dir, off_t off)
 {
     return s->ops->seekdir(&s->ctx, dir, off);
@@ -1966,7 +1961,7 @@ static void v9fs_read_post_dir_lstat(V9fsState *s, V9fsReadState *vs,
     v9fs_stat_free(&vs->v9stat);
     v9fs_string_free(&vs->name);
     vs->dir_pos = vs->dent->d_off;
-    vs->dent = v9fs_do_readdir(s, vs->fidp->fs.dir);
+    v9fs_co_readdir(s, vs->fidp, &vs->dent);
     v9fs_read_post_readdir(s, vs, err);
     return;
 out:
@@ -1998,7 +1993,7 @@ static void v9fs_read_post_readdir(V9fsState *s, V9fsReadState *vs, ssize_t err)
 
 static void v9fs_read_post_telldir(V9fsState *s, V9fsReadState *vs, ssize_t err)
 {
-    vs->dent = v9fs_do_readdir(s, vs->fidp->fs.dir);
+    v9fs_co_readdir(s, vs->fidp, &vs->dent);
     v9fs_read_post_readdir(s, vs, err);
     return;
 }
@@ -2127,126 +2122,102 @@ out:
     qemu_free(vs);
 }
 
-typedef struct V9fsReadDirState {
-    V9fsPDU *pdu;
-    V9fsFidState *fidp;
-    V9fsQID qid;
-    off_t saved_dir_pos;
-    struct dirent *dent;
-    int32_t count;
-    int32_t max_count;
-    size_t offset;
-    int64_t initial_offset;
-    V9fsString name;
-} V9fsReadDirState;
-
-static void v9fs_readdir_post_seekdir(V9fsState *s, V9fsReadDirState *vs)
+static size_t v9fs_readdir_data_size(V9fsString *name)
 {
-    vs->offset += pdu_marshal(vs->pdu, vs->offset, "d", vs->count);
-    vs->offset += vs->count;
-    complete_pdu(s, vs->pdu, vs->offset);
-    qemu_free(vs);
-    return;
+    /*
+     * Size of each dirent on the wire: size of qid (13) + size of offset (8)
+     * size of type (1) + size of name.size (2) + strlen(name.data)
+     */
+    return 24 + v9fs_string_size(name);
 }
 
-/* Size of each dirent on the wire: size of qid (13) + size of offset (8)
- * size of type (1) + size of name.size (2) + strlen(name.data)
- */
-#define V9_READDIR_DATA_SZ (24 + strlen(vs->name.data))
-
-static void v9fs_readdir_post_readdir(V9fsState *s, V9fsReadDirState *vs)
+static int v9fs_do_readdir(V9fsState *s, V9fsPDU *pdu,
+                           V9fsFidState *fidp, int32_t max_count)
 {
-    int len;
     size_t size;
+    V9fsQID qid;
+    V9fsString name;
+    int len, err = 0;
+    int32_t count = 0;
+    off_t saved_dir_pos;
+    struct dirent *dent;
 
-    if (vs->dent) {
-        v9fs_string_init(&vs->name);
-        v9fs_string_sprintf(&vs->name, "%s", vs->dent->d_name);
-
-        if ((vs->count + V9_READDIR_DATA_SZ) > vs->max_count) {
+    /* save the directory position */
+    saved_dir_pos = v9fs_co_telldir(s, fidp);
+    if (saved_dir_pos < 0) {
+        return saved_dir_pos;
+    }
+    while (1) {
+        err = v9fs_co_readdir(s, fidp, &dent);
+        if (err || !dent) {
+            break;
+        }
+        v9fs_string_init(&name);
+        v9fs_string_sprintf(&name, "%s", dent->d_name);
+        if ((count + v9fs_readdir_data_size(&name)) > max_count) {
             /* Ran out of buffer. Set dir back to old position and return */
-            v9fs_do_seekdir(s, vs->fidp->fs.dir, vs->saved_dir_pos);
-            v9fs_readdir_post_seekdir(s, vs);
-            return;
+            v9fs_co_seekdir(s, fidp, saved_dir_pos);
+            v9fs_string_free(&name);
+            return count;
         }
-
-        /* Fill up just the path field of qid because the client uses
+        /*
+         * Fill up just the path field of qid because the client uses
          * only that. To fill the entire qid structure we will have
          * to stat each dirent found, which is expensive
          */
-        size = MIN(sizeof(vs->dent->d_ino), sizeof(vs->qid.path));
-        memcpy(&vs->qid.path, &vs->dent->d_ino, size);
+        size = MIN(sizeof(dent->d_ino), sizeof(qid.path));
+        memcpy(&qid.path, &dent->d_ino, size);
         /* Fill the other fields with dummy values */
-        vs->qid.type = 0;
-        vs->qid.version = 0;
-
-        len = pdu_marshal(vs->pdu, vs->offset+4+vs->count, "Qqbs",
-                              &vs->qid, vs->dent->d_off,
-                              vs->dent->d_type, &vs->name);
-        vs->count += len;
-        v9fs_string_free(&vs->name);
-        vs->saved_dir_pos = vs->dent->d_off;
-        vs->dent = v9fs_do_readdir(s, vs->fidp->fs.dir);
-        v9fs_readdir_post_readdir(s, vs);
-        return;
-    }
-
-    vs->offset += pdu_marshal(vs->pdu, vs->offset, "d", vs->count);
-    vs->offset += vs->count;
-    complete_pdu(s, vs->pdu, vs->offset);
-    qemu_free(vs);
-    return;
-}
-
-static void v9fs_readdir_post_telldir(V9fsState *s, V9fsReadDirState *vs)
-{
-    vs->dent = v9fs_do_readdir(s, vs->fidp->fs.dir);
-    v9fs_readdir_post_readdir(s, vs);
-    return;
-}
+        qid.type = 0;
+        qid.version = 0;
 
-static void v9fs_readdir_post_setdir(V9fsState *s, V9fsReadDirState *vs)
-{
-    vs->saved_dir_pos = v9fs_do_telldir(s, vs->fidp->fs.dir);
-    v9fs_readdir_post_telldir(s, vs);
-    return;
+        /* 11 = 7 + 4 (7 = start offset, 4 = space for storing count) */
+        len = pdu_marshal(pdu, 11 + count, "Qqbs",
+                          &qid, dent->d_off,
+                          dent->d_type, &name);
+        count += len;
+        v9fs_string_free(&name);
+        saved_dir_pos = dent->d_off;
+    }
+    if (err < 0) {
+        return err;
+    }
+    return count;
 }
 
 static void v9fs_readdir(void *opaque)
 {
-    V9fsPDU *pdu = opaque;
-    V9fsState *s = pdu->s;
     int32_t fid;
-    V9fsReadDirState *vs;
-    ssize_t err = 0;
+    V9fsFidState *fidp;
+    ssize_t retval = 0;
     size_t offset = 7;
+    int64_t initial_offset;
+    int32_t count, max_count;
+    V9fsPDU *pdu = opaque;
+    V9fsState *s = pdu->s;
 
-    vs = qemu_malloc(sizeof(*vs));
-    vs->pdu = pdu;
-    vs->offset = 7;
-    vs->count = 0;
-
-    pdu_unmarshal(vs->pdu, offset, "dqd", &fid, &vs->initial_offset,
-                                                        &vs->max_count);
+    pdu_unmarshal(pdu, offset, "dqd", &fid, &initial_offset, &max_count);
 
-    vs->fidp = lookup_fid(s, fid);
-    if (vs->fidp == NULL || !(vs->fidp->fs.dir)) {
-        err = -EINVAL;
+    fidp = lookup_fid(s, fid);
+    if (fidp == NULL || !fidp->fs.dir) {
+        retval = -EINVAL;
         goto out;
     }
-
-    if (vs->initial_offset == 0) {
-        v9fs_do_rewinddir(s, vs->fidp->fs.dir);
+    if (initial_offset == 0) {
+        v9fs_co_rewinddir(s, fidp);
     } else {
-        v9fs_do_seekdir(s, vs->fidp->fs.dir, vs->initial_offset);
+        v9fs_co_seekdir(s, fidp, initial_offset);
     }
-
-    v9fs_readdir_post_setdir(s, vs);
-    return;
-
+    count = v9fs_do_readdir(s, pdu, fidp, max_count);
+    if (count < 0) {
+        retval = count;
+        goto out;
+    }
+    retval = offset;
+    retval += pdu_marshal(pdu, offset, "d", count);
+    retval += count;
 out:
-    complete_pdu(s, pdu, err);
-    qemu_free(vs);
+    complete_pdu(s, pdu, retval);
 }
 
 static void v9fs_write_post_pwritev(V9fsState *s, V9fsWriteState *vs,
commit dcb9dbe3c701068aacadebcb4068b23b3d495f3a
Author: Aneesh Kumar K.V <aneesh.kumar at linux.vnet.ibm.com>
Date:   Wed May 18 15:42:42 2011 -0700

    hw/9pfs: Add yield support for readdir related coroutines
    
    This include readdir, telldir, seekdir, rewinddir.
    
    Signed-off-by: Aneesh Kumar K.V <aneesh.kumar at linux.vnet.ibm.com>

diff --git a/Makefile.objs b/Makefile.objs
index a534c1c..faa2a12 100644
--- a/Makefile.objs
+++ b/Makefile.objs
@@ -305,7 +305,7 @@ hw-obj-$(CONFIG_SOUND) += $(sound-obj-y)
 9pfs-nested-$(CONFIG_VIRTFS) = virtio-9p.o virtio-9p-debug.o
 9pfs-nested-$(CONFIG_VIRTFS) +=  virtio-9p-local.o virtio-9p-xattr.o
 9pfs-nested-$(CONFIG_VIRTFS) +=   virtio-9p-xattr-user.o virtio-9p-posix-acl.o
-9pfs-nested-$(CONFIG_VIRTFS) += virtio-9p-coth.o cofs.o
+9pfs-nested-$(CONFIG_VIRTFS) += virtio-9p-coth.o cofs.o codir.o
 
 hw-obj-$(CONFIG_REALLY_VIRTFS) += $(addprefix 9pfs/, $(9pfs-nested-y))
 $(addprefix 9pfs/, $(9pfs-nested-y)): QEMU_CFLAGS+=$(GLIB_CFLAGS)
diff --git a/hw/9pfs/codir.c b/hw/9pfs/codir.c
new file mode 100644
index 0000000..47b10df
--- /dev/null
+++ b/hw/9pfs/codir.c
@@ -0,0 +1,66 @@
+
+/*
+ * Virtio 9p backend
+ *
+ * Copyright IBM, Corp. 2011
+ *
+ * Authors:
+ *  Aneesh Kumar K.V <aneesh.kumar at linux.vnet.ibm.com>
+ *
+ * This work is licensed under the terms of the GNU GPL, version 2.  See
+ * the COPYING file in the top-level directory.
+ *
+ */
+
+#include "fsdev/qemu-fsdev.h"
+#include "qemu-thread.h"
+#include "qemu-coroutine.h"
+#include "virtio-9p-coth.h"
+
+int v9fs_co_readdir(V9fsState *s, V9fsFidState *fidp, struct dirent **dent)
+{
+    int err;
+
+    v9fs_co_run_in_worker(
+        {
+            errno = 0;
+            /*FIXME!! need to switch to readdir_r */
+            *dent = s->ops->readdir(&s->ctx, fidp->fs.dir);
+            if (!*dent && errno) {
+                err = -errno;
+            } else {
+                err = 0;
+            }
+        });
+    return err;
+}
+
+off_t v9fs_co_telldir(V9fsState *s, V9fsFidState *fidp)
+{
+    off_t err;
+
+    v9fs_co_run_in_worker(
+        {
+            err = s->ops->telldir(&s->ctx, fidp->fs.dir);
+            if (err < 0) {
+                err = -errno;
+            }
+        });
+    return err;
+}
+
+void v9fs_co_seekdir(V9fsState *s, V9fsFidState *fidp, off_t offset)
+{
+    v9fs_co_run_in_worker(
+        {
+            s->ops->seekdir(&s->ctx, fidp->fs.dir, offset);
+        });
+}
+
+void v9fs_co_rewinddir(V9fsState *s, V9fsFidState *fidp)
+{
+    v9fs_co_run_in_worker(
+        {
+            s->ops->rewinddir(&s->ctx, fidp->fs.dir);
+        });
+}
diff --git a/hw/9pfs/virtio-9p-coth.h b/hw/9pfs/virtio-9p-coth.h
index 94c5147..9aa5953 100644
--- a/hw/9pfs/virtio-9p-coth.h
+++ b/hw/9pfs/virtio-9p-coth.h
@@ -57,4 +57,9 @@ typedef struct V9fsThPool {
 extern void co_run_in_worker_bh(void *);
 extern int v9fs_init_worker_threads(void);
 extern int v9fs_co_readlink(V9fsState *, V9fsString *, V9fsString *);
+extern int v9fs_co_readdir(V9fsState *, V9fsFidState *,
+                           struct dirent **);
+extern off_t v9fs_co_telldir(V9fsState *, V9fsFidState *);
+extern void v9fs_co_seekdir(V9fsState *, V9fsFidState *, off_t);
+extern void v9fs_co_rewinddir(V9fsState *, V9fsFidState *);
 #endif
commit 7a5ca31eb4cceff0191a45963c3d25260be73347
Author: Venkateswararao Jujjuri <jvrao at linux.vnet.ibm.com>
Date:   Mon Aug 8 23:36:41 2011 +0530

    hw/9pfs: Update v9fs_readlink to use coroutine
    
    Signed-off-by: Venkateswararao Jujjuri <jvrao at linux.vnet.ibm.com>
    Signed-off-by: Aneesh Kumar K.V <aneesh.kumar at linux.vnet.ibm.com>

diff --git a/hw/9pfs/virtio-9p.c b/hw/9pfs/virtio-9p.c
index 113ce1e..a68ac3f 100644
--- a/hw/9pfs/virtio-9p.c
+++ b/hw/9pfs/virtio-9p.c
@@ -82,21 +82,6 @@ static int v9fs_do_lstat(V9fsState *s, V9fsString *path, struct stat *stbuf)
     return s->ops->lstat(&s->ctx, path->data, stbuf);
 }
 
-static ssize_t v9fs_do_readlink(V9fsState *s, V9fsString *path, V9fsString *buf)
-{
-    ssize_t len;
-
-    buf->data = qemu_malloc(1024);
-
-    len = s->ops->readlink(&s->ctx, path->data, buf->data, 1024 - 1);
-    if (len > -1) {
-        buf->size = len;
-        buf->data[len] = 0;
-    }
-
-    return len;
-}
-
 static int v9fs_do_close(V9fsState *s, int fd)
 {
     return s->ops->close(&s->ctx, fd);
@@ -1054,13 +1039,10 @@ static int stat_to_v9stat(V9fsState *s, V9fsString *name,
     v9fs_string_null(&v9stat->extension);
 
     if (v9stat->mode & P9_STAT_MODE_SYMLINK) {
-        err = v9fs_do_readlink(s, name, &v9stat->extension);
-        if (err == -1) {
-            err = -errno;
+        err = v9fs_co_readlink(s, name, &v9stat->extension);
+        if (err < 0) {
             return err;
         }
-        v9stat->extension.data[err] = 0;
-        v9stat->extension.size = err;
     } else if (v9stat->mode & P9_STAT_MODE_DEVICE) {
         v9fs_string_sprintf(&v9stat->extension, "%c %u %u",
                 S_ISCHR(stbuf->st_mode) ? 'c' : 'b',
@@ -1949,13 +1931,13 @@ static void v9fs_read_post_seekdir(V9fsState *s, V9fsReadState *vs, ssize_t err)
     if (err) {
         goto out;
     }
-    v9fs_stat_free(&vs->v9stat);
-    v9fs_string_free(&vs->name);
     vs->offset += pdu_marshal(vs->pdu, vs->offset, "d", vs->count);
     vs->offset += vs->count;
     err = vs->offset;
 out:
     complete_pdu(s, vs->pdu, err);
+    v9fs_stat_free(&vs->v9stat);
+    v9fs_string_free(&vs->name);
     qemu_free(vs);
     return;
 }
@@ -3582,49 +3564,32 @@ out:
     qemu_free(vs);
 }
 
-static void v9fs_readlink_post_readlink(V9fsState *s, V9fsReadLinkState *vs,
-                                                    int err)
-{
-    if (err < 0) {
-        err = -errno;
-        goto out;
-    }
-    vs->offset += pdu_marshal(vs->pdu, vs->offset, "s", &vs->target);
-    err = vs->offset;
-out:
-    complete_pdu(s, vs->pdu, err);
-    v9fs_string_free(&vs->target);
-    qemu_free(vs);
-}
-
 static void v9fs_readlink(void *opaque)
 {
     V9fsPDU *pdu = opaque;
-    V9fsState *s = pdu->s;
+    size_t offset = 7;
+    V9fsString target;
     int32_t fid;
-    V9fsReadLinkState *vs;
     int err = 0;
     V9fsFidState *fidp;
 
-    vs = qemu_malloc(sizeof(*vs));
-    vs->pdu = pdu;
-    vs->offset = 7;
-
-    pdu_unmarshal(vs->pdu, vs->offset, "d", &fid);
-
-    fidp = lookup_fid(s, fid);
+    pdu_unmarshal(pdu, offset, "d", &fid);
+    fidp = lookup_fid(pdu->s, fid);
     if (fidp == NULL) {
         err = -ENOENT;
         goto out;
     }
 
-    v9fs_string_init(&vs->target);
-    err = v9fs_do_readlink(s, &fidp->path, &vs->target);
-    v9fs_readlink_post_readlink(s, vs, err);
-    return;
+    v9fs_string_init(&target);
+    err = v9fs_co_readlink(pdu->s, &fidp->path, &target);
+    if (err < 0) {
+        goto out;
+    }
+    offset += pdu_marshal(pdu, offset, "s", &target);
+    err = offset;
+    v9fs_string_free(&target);
 out:
-    complete_pdu(s, vs->pdu, err);
-    qemu_free(vs);
+    complete_pdu(pdu->s, pdu, err);
 }
 
 static CoroutineEntry *pdu_co_handlers[] = {
diff --git a/hw/9pfs/virtio-9p.h b/hw/9pfs/virtio-9p.h
index fb1e465..8196da0 100644
--- a/hw/9pfs/virtio-9p.h
+++ b/hw/9pfs/virtio-9p.h
@@ -495,13 +495,6 @@ typedef struct V9fsGetlockState
     V9fsGetlock *glock;
 } V9fsGetlockState;
 
-typedef struct V9fsReadLinkState
-{
-    V9fsPDU *pdu;
-    size_t offset;
-    V9fsString target;
-} V9fsReadLinkState;
-
 size_t pdu_packunpack(void *addr, struct iovec *sg, int sg_count,
                       size_t offset, size_t size, int pack);
 
@@ -512,5 +505,4 @@ static inline size_t do_pdu_unpack(void *dst, struct iovec *sg, int sg_count,
 }
 
 extern void handle_9p_output(VirtIODevice *vdev, VirtQueue *vq);
-
 #endif
commit 86e42d748211e58beee431b2639e57ac01ffe3be
Author: Venkateswararao Jujjuri (JV) <jvrao at linux.vnet.ibm.com>
Date:   Mon Aug 8 23:33:48 2011 +0530

    hw/9pfs: Add yeild support for readlink
    
    Signed-off-by: Venkateswararao Jujjuri (JV) <jvrao at linux.vnet.ibm.com>
    Signed-off-by: Aneesh Kumar K.V <aneesh.kumar at linux.vnet.ibm.com>

diff --git a/Makefile.objs b/Makefile.objs
index 9bede68..a534c1c 100644
--- a/Makefile.objs
+++ b/Makefile.objs
@@ -305,7 +305,7 @@ hw-obj-$(CONFIG_SOUND) += $(sound-obj-y)
 9pfs-nested-$(CONFIG_VIRTFS) = virtio-9p.o virtio-9p-debug.o
 9pfs-nested-$(CONFIG_VIRTFS) +=  virtio-9p-local.o virtio-9p-xattr.o
 9pfs-nested-$(CONFIG_VIRTFS) +=   virtio-9p-xattr-user.o virtio-9p-posix-acl.o
-9pfs-nested-$(CONFIG_VIRTFS) += virtio-9p-coth.o
+9pfs-nested-$(CONFIG_VIRTFS) += virtio-9p-coth.o cofs.o
 
 hw-obj-$(CONFIG_REALLY_VIRTFS) += $(addprefix 9pfs/, $(9pfs-nested-y))
 $(addprefix 9pfs/, $(9pfs-nested-y)): QEMU_CFLAGS+=$(GLIB_CFLAGS)
diff --git a/hw/9pfs/cofs.c b/hw/9pfs/cofs.c
new file mode 100644
index 0000000..6bb8b47
--- /dev/null
+++ b/hw/9pfs/cofs.c
@@ -0,0 +1,44 @@
+
+/*
+ * Virtio 9p backend
+ *
+ * Copyright IBM, Corp. 2011
+ *
+ * Authors:
+ *  Aneesh Kumar K.V <aneesh.kumar at linux.vnet.ibm.com>
+ *
+ * This work is licensed under the terms of the GNU GPL, version 2.  See
+ * the COPYING file in the top-level directory.
+ *
+ */
+
+#include "fsdev/qemu-fsdev.h"
+#include "qemu-thread.h"
+#include "qemu-coroutine.h"
+#include "virtio-9p-coth.h"
+
+int v9fs_co_readlink(V9fsState *s, V9fsString *path, V9fsString *buf)
+{
+    int err;
+    ssize_t len;
+
+    buf->data = qemu_malloc(PATH_MAX);
+    v9fs_co_run_in_worker(
+        {
+            len = s->ops->readlink(&s->ctx, path->data,
+                                   buf->data, PATH_MAX - 1);
+            if (len > -1) {
+                buf->size = len;
+                buf->data[len] = 0;
+                err = 0;
+            } else {
+                err = -errno;
+            }
+        });
+    if (err) {
+        qemu_free(buf->data);
+        buf->data = NULL;
+        buf->size = 0;
+    }
+    return err;
+}
diff --git a/hw/9pfs/virtio-9p-coth.h b/hw/9pfs/virtio-9p-coth.h
index 9388f9b..94c5147 100644
--- a/hw/9pfs/virtio-9p-coth.h
+++ b/hw/9pfs/virtio-9p-coth.h
@@ -56,4 +56,5 @@ typedef struct V9fsThPool {
 
 extern void co_run_in_worker_bh(void *);
 extern int v9fs_init_worker_threads(void);
+extern int v9fs_co_readlink(V9fsState *, V9fsString *, V9fsString *);
 #endif
commit ff06030f660647bba1c60184dc32730fa06f38fe
Author: Venkateswararao Jujjuri (JV) <jvrao at linux.vnet.ibm.com>
Date:   Wed May 18 14:18:05 2011 -0700

    [virtio-9p] Change all pdu handlers to coroutines.
    
    This patch changes the top level handlers to coroutines and sets the base.
    It will be followed up with series of patches to convert all filesystem
    calls to threaded coroutines pushing all blocking clals in VirtFS out
    of vcpu threads.
    
    Signed-off-by: Venkateswararao Jujjuri "<jvrao at linux.vnet.ibm.com>
    Signed-off-by: Aneesh Kumar K.V <aneesh.kumar at linux.vnet.ibm.com>

diff --git a/hw/9pfs/virtio-9p-coth.h b/hw/9pfs/virtio-9p-coth.h
index 8445d29..9388f9b 100644
--- a/hw/9pfs/virtio-9p-coth.h
+++ b/hw/9pfs/virtio-9p-coth.h
@@ -17,6 +17,7 @@
 
 #include "qemu-thread.h"
 #include "qemu-coroutine.h"
+#include "virtio-9p.h"
 #include <glib.h>
 
 typedef struct V9fsThPool {
diff --git a/hw/9pfs/virtio-9p.c b/hw/9pfs/virtio-9p.c
index 4890df6..113ce1e 100644
--- a/hw/9pfs/virtio-9p.c
+++ b/hw/9pfs/virtio-9p.c
@@ -19,6 +19,7 @@
 #include "fsdev/qemu-fsdev.h"
 #include "virtio-9p-debug.h"
 #include "virtio-9p-xattr.h"
+#include "virtio-9p-coth.h"
 
 int debug_9p_pdu;
 
@@ -1191,8 +1192,10 @@ static void v9fs_fix_path(V9fsString *dst, V9fsString *src, int len)
     v9fs_string_free(&str);
 }
 
-static void v9fs_version(V9fsState *s, V9fsPDU *pdu)
+static void v9fs_version(void *opaque)
 {
+    V9fsPDU *pdu = opaque;
+    V9fsState *s = pdu->s;
     V9fsString version;
     size_t offset = 7;
 
@@ -1210,10 +1213,13 @@ static void v9fs_version(V9fsState *s, V9fsPDU *pdu)
     complete_pdu(s, pdu, offset);
 
     v9fs_string_free(&version);
+    return;
 }
 
-static void v9fs_attach(V9fsState *s, V9fsPDU *pdu)
+static void v9fs_attach(void *opaque)
 {
+    V9fsPDU *pdu = opaque;
+    V9fsState *s = pdu->s;
     int32_t fid, afid, n_uname;
     V9fsString uname, aname;
     V9fsFidState *fidp;
@@ -1268,8 +1274,10 @@ out:
     qemu_free(vs);
 }
 
-static void v9fs_stat(V9fsState *s, V9fsPDU *pdu)
+static void v9fs_stat(void *opaque)
 {
+    V9fsPDU *pdu = opaque;
+    V9fsState *s = pdu->s;
     int32_t fid;
     V9fsStatState *vs;
     ssize_t err = 0;
@@ -1315,8 +1323,10 @@ out:
     qemu_free(vs);
 }
 
-static void v9fs_getattr(V9fsState *s, V9fsPDU *pdu)
+static void v9fs_getattr(void *opaque)
 {
+    V9fsPDU *pdu = opaque;
+    V9fsState *s = pdu->s;
     int32_t fid;
     V9fsStatStateDotl *vs;
     ssize_t err = 0;
@@ -1464,8 +1474,10 @@ out:
     qemu_free(vs);
 }
 
-static void v9fs_setattr(V9fsState *s, V9fsPDU *pdu)
+static void v9fs_setattr(void *opaque)
 {
+    V9fsPDU *pdu = opaque;
+    V9fsState *s = pdu->s;
     int32_t fid;
     V9fsSetattrState *vs;
     int err = 0;
@@ -1578,8 +1590,10 @@ out:
     v9fs_walk_complete(s, vs, err);
 }
 
-static void v9fs_walk(V9fsState *s, V9fsPDU *pdu)
+static void v9fs_walk(void *opaque)
 {
+    V9fsPDU *pdu = opaque;
+    V9fsState *s = pdu->s;
     int32_t fid, newfid;
     V9fsWalkState *vs;
     int err = 0;
@@ -1750,8 +1764,10 @@ out:
     qemu_free(vs);
 }
 
-static void v9fs_open(V9fsState *s, V9fsPDU *pdu)
+static void v9fs_open(void *opaque)
 {
+    V9fsPDU *pdu = opaque;
+    V9fsState *s = pdu->s;
     int32_t fid;
     V9fsOpenState *vs;
     ssize_t err = 0;
@@ -1835,8 +1851,10 @@ out:
     v9fs_post_lcreate(s, vs, err);
 }
 
-static void v9fs_lcreate(V9fsState *s, V9fsPDU *pdu)
+static void v9fs_lcreate(void *opaque)
 {
+    V9fsPDU *pdu = opaque;
+    V9fsState *s = pdu->s;
     int32_t dfid, flags, mode;
     gid_t gid;
     V9fsLcreateState *vs;
@@ -1882,8 +1900,10 @@ static void v9fs_post_do_fsync(V9fsState *s, V9fsPDU *pdu, int err)
     complete_pdu(s, pdu, err);
 }
 
-static void v9fs_fsync(V9fsState *s, V9fsPDU *pdu)
+static void v9fs_fsync(void *opaque)
 {
+    V9fsPDU *pdu = opaque;
+    V9fsState *s = pdu->s;
     int32_t fid;
     size_t offset = 7;
     V9fsFidState *fidp;
@@ -1901,8 +1921,10 @@ static void v9fs_fsync(V9fsState *s, V9fsPDU *pdu)
     v9fs_post_do_fsync(s, pdu, err);
 }
 
-static void v9fs_clunk(V9fsState *s, V9fsPDU *pdu)
+static void v9fs_clunk(void *opaque)
 {
+    V9fsPDU *pdu = opaque;
+    V9fsState *s = pdu->s;
     int32_t fid;
     size_t offset = 7;
     int err;
@@ -2067,8 +2089,10 @@ static void v9fs_xattr_read(V9fsState *s, V9fsReadState *vs)
     qemu_free(vs);
 }
 
-static void v9fs_read(V9fsState *s, V9fsPDU *pdu)
+static void v9fs_read(void *opaque)
 {
+    V9fsPDU *pdu = opaque;
+    V9fsState *s = pdu->s;
     int32_t fid;
     V9fsReadState *vs;
     ssize_t err = 0;
@@ -2206,8 +2230,10 @@ static void v9fs_readdir_post_setdir(V9fsState *s, V9fsReadDirState *vs)
     return;
 }
 
-static void v9fs_readdir(V9fsState *s, V9fsPDU *pdu)
+static void v9fs_readdir(void *opaque)
 {
+    V9fsPDU *pdu = opaque;
+    V9fsState *s = pdu->s;
     int32_t fid;
     V9fsReadDirState *vs;
     ssize_t err = 0;
@@ -2239,7 +2265,6 @@ static void v9fs_readdir(V9fsState *s, V9fsPDU *pdu)
 out:
     complete_pdu(s, pdu, err);
     qemu_free(vs);
-    return;
 }
 
 static void v9fs_write_post_pwritev(V9fsState *s, V9fsWriteState *vs,
@@ -2318,8 +2343,10 @@ out:
     qemu_free(vs);
 }
 
-static void v9fs_write(V9fsState *s, V9fsPDU *pdu)
+static void v9fs_write(void *opaque)
 {
+    V9fsPDU *pdu = opaque;
+    V9fsState *s = pdu->s;
     int32_t fid;
     V9fsWriteState *vs;
     ssize_t err;
@@ -2552,8 +2579,10 @@ out:
     v9fs_post_create(s, vs, err);
 }
 
-static void v9fs_create(V9fsState *s, V9fsPDU *pdu)
+static void v9fs_create(void *opaque)
 {
+    V9fsPDU *pdu = opaque;
+    V9fsState *s = pdu->s;
     int32_t fid;
     V9fsCreateState *vs;
     int err = 0;
@@ -2614,8 +2643,10 @@ out:
     v9fs_post_symlink(s, vs, err);
 }
 
-static void v9fs_symlink(V9fsState *s, V9fsPDU *pdu)
+static void v9fs_symlink(void *opaque)
 {
+    V9fsPDU *pdu = opaque;
+    V9fsState *s = pdu->s;
     int32_t dfid;
     V9fsSymlinkState *vs;
     int err = 0;
@@ -2650,14 +2681,19 @@ out:
     qemu_free(vs);
 }
 
-static void v9fs_flush(V9fsState *s, V9fsPDU *pdu)
+static void v9fs_flush(void *opaque)
 {
+    V9fsPDU *pdu = opaque;
+    V9fsState *s = pdu->s;
     /* A nop call with no return */
     complete_pdu(s, pdu, 7);
+    return;
 }
 
-static void v9fs_link(V9fsState *s, V9fsPDU *pdu)
+static void v9fs_link(void *opaque)
 {
+    V9fsPDU *pdu = opaque;
+    V9fsState *s = pdu->s;
     int32_t dfid, oldfid;
     V9fsFidState *dfidp, *oldfidp;
     V9fsString name, fullname;
@@ -2709,8 +2745,10 @@ static void v9fs_remove_post_remove(V9fsState *s, V9fsRemoveState *vs,
     qemu_free(vs);
 }
 
-static void v9fs_remove(V9fsState *s, V9fsPDU *pdu)
+static void v9fs_remove(void *opaque)
 {
+    V9fsPDU *pdu = opaque;
+    V9fsState *s = pdu->s;
     int32_t fid;
     V9fsRemoveState *vs;
     int err = 0;
@@ -2876,8 +2914,10 @@ out:
     qemu_free(vs);
 }
 
-static void v9fs_rename(V9fsState *s, V9fsPDU *pdu)
+static void v9fs_rename(void *opaque)
 {
+    V9fsPDU *pdu = opaque;
+    V9fsState *s = pdu->s;
     int32_t fid;
     V9fsRenameState *vs;
     ssize_t err = 0;
@@ -3001,8 +3041,10 @@ out:
     qemu_free(vs);
 }
 
-static void v9fs_wstat(V9fsState *s, V9fsPDU *pdu)
+static void v9fs_wstat(void *opaque)
 {
+    V9fsPDU *pdu = opaque;
+    V9fsState *s = pdu->s;
     int32_t fid;
     V9fsWstatState *vs;
     int err = 0;
@@ -3086,8 +3128,10 @@ out:
     qemu_free(vs);
 }
 
-static void v9fs_statfs(V9fsState *s, V9fsPDU *pdu)
+static void v9fs_statfs(void *opaque)
 {
+    V9fsPDU *pdu = opaque;
+    V9fsState *s = pdu->s;
     V9fsStatfsState *vs;
     ssize_t err = 0;
 
@@ -3112,6 +3156,7 @@ static void v9fs_statfs(V9fsState *s, V9fsPDU *pdu)
 out:
     complete_pdu(s, vs->pdu, err);
     qemu_free(vs);
+    return;
 }
 
 static void v9fs_mknod_post_lstat(V9fsState *s, V9fsMkState *vs, int err)
@@ -3148,8 +3193,10 @@ out:
     qemu_free(vs);
 }
 
-static void v9fs_mknod(V9fsState *s, V9fsPDU *pdu)
+static void v9fs_mknod(void *opaque)
 {
+    V9fsPDU *pdu = opaque;
+    V9fsState *s = pdu->s;
     int32_t fid;
     V9fsMkState *vs;
     int err = 0;
@@ -3194,8 +3241,10 @@ out:
  * So when a TLOCK request comes, always return success
  */
 
-static void v9fs_lock(V9fsState *s, V9fsPDU *pdu)
+static void v9fs_lock(void *opaque)
 {
+    V9fsPDU *pdu = opaque;
+    V9fsState *s = pdu->s;
     int32_t fid, err = 0;
     V9fsLockState *vs;
 
@@ -3239,8 +3288,10 @@ out:
  * handling is done by client's VFS layer.
  */
 
-static void v9fs_getlock(V9fsState *s, V9fsPDU *pdu)
+static void v9fs_getlock(void *opaque)
 {
+    V9fsPDU *pdu = opaque;
+    V9fsState *s = pdu->s;
     int32_t fid, err = 0;
     V9fsGetlockState *vs;
 
@@ -3308,8 +3359,10 @@ out:
     qemu_free(vs);
 }
 
-static void v9fs_mkdir(V9fsState *s, V9fsPDU *pdu)
+static void v9fs_mkdir(void *opaque)
 {
+    V9fsPDU *pdu = opaque;
+    V9fsState *s = pdu->s;
     int32_t fid;
     V9fsMkState *vs;
     int err = 0;
@@ -3432,8 +3485,10 @@ out:
     qemu_free(vs);
 }
 
-static void v9fs_xattrwalk(V9fsState *s, V9fsPDU *pdu)
+static void v9fs_xattrwalk(void *opaque)
 {
+    V9fsPDU *pdu = opaque;
+    V9fsState *s = pdu->s;
     ssize_t err = 0;
     V9fsXattrState *vs;
     int32_t fid, newfid;
@@ -3486,8 +3541,10 @@ out:
     qemu_free(vs);
 }
 
-static void v9fs_xattrcreate(V9fsState *s, V9fsPDU *pdu)
+static void v9fs_xattrcreate(void *opaque)
 {
+    V9fsPDU *pdu = opaque;
+    V9fsState *s = pdu->s;
     int flags;
     int32_t fid;
     ssize_t err = 0;
@@ -3540,8 +3597,10 @@ out:
     qemu_free(vs);
 }
 
-static void v9fs_readlink(V9fsState *s, V9fsPDU *pdu)
+static void v9fs_readlink(void *opaque)
 {
+    V9fsPDU *pdu = opaque;
+    V9fsState *s = pdu->s;
     int32_t fid;
     V9fsReadLinkState *vs;
     int err = 0;
@@ -3568,9 +3627,7 @@ out:
     qemu_free(vs);
 }
 
-typedef void (pdu_handler_t)(V9fsState *s, V9fsPDU *pdu);
-
-static pdu_handler_t *pdu_handlers[] = {
+static CoroutineEntry *pdu_co_handlers[] = {
     [P9_TREADDIR] = v9fs_readdir,
     [P9_TSTATFS] = v9fs_statfs,
     [P9_TGETATTR] = v9fs_getattr,
@@ -3605,25 +3662,28 @@ static pdu_handler_t *pdu_handlers[] = {
     [P9_TREMOVE] = v9fs_remove,
 };
 
-static void v9fs_op_not_supp(V9fsState *s, V9fsPDU *pdu)
+static void v9fs_op_not_supp(void *opaque)
 {
-    complete_pdu(s, pdu, -EOPNOTSUPP);
+    V9fsPDU *pdu = opaque;
+    complete_pdu(pdu->s, pdu, -EOPNOTSUPP);
 }
 
 static void submit_pdu(V9fsState *s, V9fsPDU *pdu)
 {
-    pdu_handler_t *handler;
+    Coroutine *co;
+    CoroutineEntry *handler;
 
     if (debug_9p_pdu) {
         pprint_pdu(pdu);
     }
-    if (pdu->id >= ARRAY_SIZE(pdu_handlers) ||
-        (pdu_handlers[pdu->id] == NULL)) {
+    if (pdu->id >= ARRAY_SIZE(pdu_co_handlers) ||
+        (pdu_co_handlers[pdu->id] == NULL)) {
         handler = v9fs_op_not_supp;
     } else {
-        handler = pdu_handlers[pdu->id];
+        handler = pdu_co_handlers[pdu->id];
     }
-    handler(s, pdu);
+    co = qemu_coroutine_create(handler);
+    qemu_coroutine_enter(co, pdu);
 }
 
 void handle_9p_output(VirtIODevice *vdev, VirtQueue *vq)
@@ -3635,7 +3695,7 @@ void handle_9p_output(VirtIODevice *vdev, VirtQueue *vq)
     while ((pdu = alloc_pdu(s)) &&
             (len = virtqueue_pop(vq, &pdu->elem)) != 0) {
         uint8_t *ptr;
-
+        pdu->s = s;
         BUG_ON(pdu->elem.out_num == 0 || pdu->elem.in_num == 0);
         BUG_ON(pdu->elem.out_sg[0].iov_len < 7);
 
@@ -3644,9 +3704,7 @@ void handle_9p_output(VirtIODevice *vdev, VirtQueue *vq)
         memcpy(&pdu->size, ptr, 4);
         pdu->id = ptr[4];
         memcpy(&pdu->tag, ptr + 5, 2);
-
         submit_pdu(s, pdu);
     }
-
     free_pdu(s, pdu);
 }
diff --git a/hw/9pfs/virtio-9p.h b/hw/9pfs/virtio-9p.h
index 2bfbe62..fb1e465 100644
--- a/hw/9pfs/virtio-9p.h
+++ b/hw/9pfs/virtio-9p.h
@@ -5,7 +5,7 @@
 #include <dirent.h>
 #include <sys/time.h>
 #include <utime.h>
-
+#include "hw/virtio.h"
 #include "fsdev/file-op-9p.h"
 
 /* The feature bitmap for virtio 9P */
@@ -114,6 +114,7 @@ static inline const char *rpath(FsContext *ctx, const char *path, char *buffer)
 #define P9_IOHDRSZ 24
 
 typedef struct V9fsPDU V9fsPDU;
+struct V9fsState;
 
 struct V9fsPDU
 {
@@ -121,6 +122,7 @@ struct V9fsPDU
     uint16_t tag;
     uint8_t id;
     VirtQueueElement elem;
+    struct V9fsState *s;
     QLIST_ENTRY(V9fsPDU) next;
 };
 
commit 39c0564e00f85e70cc94de22035517b2f921d0a0
Author: Venkateswararao Jujjuri (JV) <jvrao at linux.vnet.ibm.com>
Date:   Sat Apr 23 18:40:22 2011 -0700

    [virtio-9p] Add infrastructure to support glib threads and coroutines.
    
    This patch is originally made by Arun Bharadwaj for glib support.
    Later Harsh Prateek Bora added coroutines support.
    This version implemented with suggestions from
    Stefan Hajnoczi <stefanha at linux.vnet.ibm.com>.
    
    Signed-off-by: Arun R Bharadwaj <arun at linux.vnet.ibm.com>
    Signed-off-by: Harsh Prateek Bora <harsh at linux.vnet.ibm.com>
    Signed-off-by: Venkateswararao Jujjuri "<jvrao at linux.vnet.ibm.com>
    Signed-off-by: Aneesh Kumar K.V <aneesh.kumar at linux.vnet.ibm.com>

diff --git a/Makefile.objs b/Makefile.objs
index 432b619..9bede68 100644
--- a/Makefile.objs
+++ b/Makefile.objs
@@ -305,8 +305,10 @@ hw-obj-$(CONFIG_SOUND) += $(sound-obj-y)
 9pfs-nested-$(CONFIG_VIRTFS) = virtio-9p.o virtio-9p-debug.o
 9pfs-nested-$(CONFIG_VIRTFS) +=  virtio-9p-local.o virtio-9p-xattr.o
 9pfs-nested-$(CONFIG_VIRTFS) +=   virtio-9p-xattr-user.o virtio-9p-posix-acl.o
+9pfs-nested-$(CONFIG_VIRTFS) += virtio-9p-coth.o
 
 hw-obj-$(CONFIG_REALLY_VIRTFS) += $(addprefix 9pfs/, $(9pfs-nested-y))
+$(addprefix 9pfs/, $(9pfs-nested-y)): QEMU_CFLAGS+=$(GLIB_CFLAGS)
 
 
 ######################################################################
diff --git a/hw/9pfs/virtio-9p-coth.c b/hw/9pfs/virtio-9p-coth.c
new file mode 100644
index 0000000..ae05658
--- /dev/null
+++ b/hw/9pfs/virtio-9p-coth.c
@@ -0,0 +1,102 @@
+/*
+ * Virtio 9p backend
+ *
+ * Copyright IBM, Corp. 2010
+ *
+ * Authors:
+ *  Harsh Prateek Bora <harsh at linux.vnet.ibm.com>
+ *  Venkateswararao Jujjuri(JV) <jvrao at linux.vnet.ibm.com>
+ *
+ * This work is licensed under the terms of the GNU GPL, version 2.  See
+ * the COPYING file in the top-level directory.
+ *
+ */
+
+#include "qemu-char.h"
+#include "fsdev/qemu-fsdev.h"
+#include "qemu-thread.h"
+#include "qemu-coroutine.h"
+#include "virtio-9p-coth.h"
+
+/* v9fs glib thread pool */
+static V9fsThPool v9fs_pool;
+
+void co_run_in_worker_bh(void *opaque)
+{
+    Coroutine *co = opaque;
+    g_thread_pool_push(v9fs_pool.pool, co, NULL);
+}
+
+static void v9fs_qemu_process_req_done(void *arg)
+{
+    char byte;
+    ssize_t len;
+    Coroutine *co;
+
+    do {
+        len = read(v9fs_pool.rfd, &byte, sizeof(byte));
+    } while (len == -1 &&  errno == EINTR);
+
+    while ((co = g_async_queue_try_pop(v9fs_pool.completed)) != NULL) {
+        qemu_coroutine_enter(co, NULL);
+    }
+}
+
+static void v9fs_thread_routine(gpointer data, gpointer user_data)
+{
+    ssize_t len;
+    char byte = 0;
+    Coroutine *co = data;
+
+    qemu_coroutine_enter(co, NULL);
+
+    g_async_queue_push(v9fs_pool.completed, co);
+    do {
+        len = write(v9fs_pool.wfd, &byte, sizeof(byte));
+    } while (len == -1 && errno == EINTR);
+}
+
+int v9fs_init_worker_threads(void)
+{
+    int ret = 0;
+    int notifier_fds[2];
+    V9fsThPool *p = &v9fs_pool;
+    sigset_t set, oldset;
+
+    sigfillset(&set);
+    /* Leave signal handling to the iothread.  */
+    pthread_sigmask(SIG_SETMASK, &set, &oldset);
+
+    /* init thread system if not already initialized */
+    if (!g_thread_get_initialized()) {
+        g_thread_init(NULL);
+    }
+    if (qemu_pipe(notifier_fds) == -1) {
+        ret = -1;
+        goto err_out;
+    }
+    p->pool = g_thread_pool_new(v9fs_thread_routine, p, -1, FALSE, NULL);
+    if (!p->pool) {
+        ret = -1;
+        goto err_out;
+    }
+    p->completed = g_async_queue_new();
+    if (!p->completed) {
+        /*
+         * We are going to terminate.
+         * So don't worry about cleanup
+         */
+        ret = -1;
+        goto err_out;
+    }
+    p->rfd = notifier_fds[0];
+    p->wfd = notifier_fds[1];
+
+    fcntl(p->rfd, F_SETFL, O_NONBLOCK);
+    fcntl(p->wfd, F_SETFL, O_NONBLOCK);
+
+    qemu_set_fd_handler(p->rfd, v9fs_qemu_process_req_done, NULL, NULL);
+err_out:
+    pthread_sigmask(SIG_SETMASK, &oldset, NULL);
+    return ret;
+}
diff --git a/hw/9pfs/virtio-9p-coth.h b/hw/9pfs/virtio-9p-coth.h
new file mode 100644
index 0000000..8445d29
--- /dev/null
+++ b/hw/9pfs/virtio-9p-coth.h
@@ -0,0 +1,58 @@
+/*
+ * Virtio 9p backend
+ *
+ * Copyright IBM, Corp. 2010
+ *
+ * Authors:
+ *  Harsh Prateek Bora <harsh at linux.vnet.ibm.com>
+ *  Venkateswararao Jujjuri(JV) <jvrao at linux.vnet.ibm.com>
+ *
+ * This work is licensed under the terms of the GNU GPL, version 2.  See
+ * the COPYING file in the top-level directory.
+ *
+ */
+
+#ifndef _QEMU_VIRTIO_9P_COTH_H
+#define _QEMU_VIRTIO_9P_COTH_H
+
+#include "qemu-thread.h"
+#include "qemu-coroutine.h"
+#include <glib.h>
+
+typedef struct V9fsThPool {
+    int rfd;
+    int wfd;
+    GThreadPool *pool;
+    GAsyncQueue *completed;
+} V9fsThPool;
+
+/*
+ * we want to use bottom half because we want to make sure the below
+ * sequence of events.
+ *
+ *   1. Yield the coroutine in the QEMU thread.
+ *   2. Submit the coroutine to a worker thread.
+ *   3. Enter the coroutine in the worker thread.
+ * we cannot swap step 1 and 2, because that would imply worker thread
+ * can enter coroutine while step1 is still running
+ */
+#define v9fs_co_run_in_worker(code_block)                               \
+    do {                                                                \
+        QEMUBH *co_bh;                                                  \
+        co_bh = qemu_bh_new(co_run_in_worker_bh,                        \
+                            qemu_coroutine_self());                     \
+        qemu_bh_schedule(co_bh);                                        \
+        /*                                                              \
+         * yeild in qemu thread and re-enter back                       \
+         * in glib worker thread                                        \
+         */                                                             \
+        qemu_coroutine_yield();                                         \
+        qemu_bh_delete(co_bh);                                          \
+        code_block;                                                     \
+        /* re-enter back to qemu thread */                              \
+        qemu_coroutine_yield();                                         \
+    } while (0)
+
+extern void co_run_in_worker_bh(void *);
+extern int v9fs_init_worker_threads(void);
+#endif
diff --git a/hw/9pfs/virtio-9p-device.c b/hw/9pfs/virtio-9p-device.c
index f235236..f4bf471 100644
--- a/hw/9pfs/virtio-9p-device.c
+++ b/hw/9pfs/virtio-9p-device.c
@@ -18,6 +18,7 @@
 #include "virtio-9p.h"
 #include "fsdev/qemu-fsdev.h"
 #include "virtio-9p-xattr.h"
+#include "virtio-9p-coth.h"
 
 static uint32_t virtio_9p_get_features(VirtIODevice *vdev, uint32_t features)
 {
@@ -50,13 +51,11 @@ VirtIODevice *virtio_9p_init(DeviceState *dev, V9fsConf *conf)
     struct stat stat;
     FsTypeEntry *fse;
 
-
     s = (V9fsState *)virtio_common_init("virtio-9p",
                                     VIRTIO_ID_9P,
                                     sizeof(struct virtio_9p_config)+
                                     MAX_TAG_LEN,
                                     sizeof(V9fsState));
-
     /* initialize pdu allocator */
     QLIST_INIT(&s->free_list);
     for (i = 0; i < (MAX_REQ - 1); i++) {
@@ -132,6 +131,10 @@ VirtIODevice *virtio_9p_init(DeviceState *dev, V9fsConf *conf)
                         s->tag_len;
     s->vdev.get_config = virtio_9p_get_config;
 
+    if (v9fs_init_worker_threads() < 0) {
+        fprintf(stderr, "worker thread initialization failed\n");
+        exit(1);
+    }
     return &s->vdev;
 }
 
commit 4b76a481ee28166d5f415ef97833c624f4fc0792
Author: Stefan Hajnoczi <stefanha at linux.vnet.ibm.com>
Date:   Mon Aug 8 13:04:05 2011 +0530

    coroutine: add gthread dependency
    
    Commit 1fc7bd4a86a2bfeafcec29445871eb97469a2699 removed the gthread and
    gio dependency since qemu-ga did not require it.  Coroutines require
    gthread, so add it back in.
    
    Signed-off-by: Stefan Hajnoczi <stefanha at linux.vnet.ibm.com>

diff --git a/configure b/configure
index 0c67a4a..a6687f7 100755
--- a/configure
+++ b/configure
@@ -1844,16 +1844,14 @@ fi
 
 ##########################################
 # glib support probe
-if test "$guest_agent" != "no" ; then
-    if $pkg_config --modversion glib-2.0 > /dev/null 2>&1 ; then
-        glib_cflags=`$pkg_config --cflags glib-2.0 2>/dev/null`
-        glib_libs=`$pkg_config --libs glib-2.0 2>/dev/null`
-        libs_softmmu="$glib_libs $libs_softmmu"
-        libs_tools="$glib_libs $libs_tools"
-    else
-        echo "glib-2.0 required to compile QEMU"
-        exit 1
-    fi
+if $pkg_config --modversion 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`
+    libs_softmmu="$glib_libs $libs_softmmu"
+    libs_tools="$glib_libs $libs_tools"
+else
+    echo "glib-2.0 required to compile QEMU"
+    exit 1
 fi
 
 ##########################################


More information about the Spice-commits mailing list