[Spice-commits] 370 commits - CODING_STYLE MAINTAINERS Makefile Makefile.objs Makefile.target QMP/qmp-spec.txt arch_init.c block.c block.h block/blkdebug.c block/cow.c block/curl.c block/qcow.c block/qcow2-cluster.c block/qcow2.c block/qed-check.c block/qed.c block/qed.h block/raw.c block/sheepdog.c block/stream.c block/vdi.c block/vmdk.c block/vpc.c block_int.h blockdev.c bsd-user/main.c check-qdict.c check-qfloat.c check-qint.c check-qjson.c check-qlist.c check-qstring.c configure coroutine-gthread.c cpu-all.h cpu-defs.h cpu-exec.c cpus.c cpus.h def-helper.h dis-asm.h disas.c dma-helpers.c dma.h docs/ccid.txt docs/qapi-code-gen.txt docs/specs elf.h exec-all.h exec.c fpu/softfloat.c fsdev/virtfs-proxy-helper.texi gdbstub.c hmp-commands.hx hmp.c hmp.h hw/a15mpcore.c hw/a9mpcore.c hw/acpi_piix4.c hw/arm11mpcore.c hw/arm_gic.c hw/armv7m_nvic.c hw/blizzard.c hw/eepro100.c hw/exynos4210.c hw/exynos4210.h hw/exynos4210_combiner.c hw/exynos4210_gic.c hw/exynos4210_uart.c hw/exynos4_boards .c hw/ide hw/irq.c hw/irq.h hw/ivshmem.c hw/kvm hw/lsi53c895a.c hw/mc146818rtc.c hw/mc146818rtc.h hw/mc146818rtc_regs.h hw/milkymist-sysctl.c hw/milkymist-vgafb.c hw/ne2000.c hw/omap1.c hw/omap_lcdc.c hw/opencores_eth.c hw/pc.c hw/pc_piix.c hw/pci-hotplug.c hw/pci.c hw/pci.h hw/pci_bridge.c hw/pci_bridge_dev.c hw/pci_host.c hw/pci_regs.h hw/pcie_port.c hw/pcnet.c hw/pcnet.h hw/petalogix_s3adsp1800_mmu.c hw/piix_pci.c hw/pl031.c hw/ppc440_bamboo.c hw/ppc_prep.c hw/ppce500_mpc8544ds.c hw/ps2.c hw/ps2.h hw/pxa2xx.c hw/qdev-monitor.c hw/qdev-properties.c hw/qdev.c hw/qdev.h hw/realview_gic.c hw/rtl8139.c hw/serial.c hw/shpc.c hw/shpc.h hw/slotid_cap.c hw/slotid_cap.h hw/spapr.h hw/spapr_llan.c hw/spapr_pci.c hw/spapr_rtas.c hw/spapr_vio.c hw/spapr_vio.h hw/spapr_vscsi.c hw/spapr_vty.c hw/strongarm.c hw/sun4m.c hw/sun4u.c hw/twl92230.c hw/usb hw/vga.c hw/vhost.c hw/virtio-net.h hw/virtio-pci.c hw/xen.h hw/xen_apic.c hw/xen_backend.c hw/xen_console.c hw/xen_disk.c hw/xen_platform. c include/qemu ioport.c kvm-all.c kvm-stub.c kvm.h libcacard/vcard_emul_nss.c linux-aio.c linux-headers/asm-powerpc linux-headers/asm-s390 linux-headers/linux linux-user/arm linux-user/elfload.c linux-user/ioctls.h linux-user/main.c linux-user/mmap.c linux-user/qemu.h linux-user/syscall.c linux-user/syscall_defs.h linux-user/syscall_types.h lm32-dis.c main-loop.c main-loop.h memory.c migration.c monitor.c nbd.c net.c net.h osdep.h oslib-win32.c pc-bios/optionrom ppc-dis.c qapi-schema-test.json qapi-schema.json qapi/qmp-input-visitor.c qapi/qmp-input-visitor.h qapi/qmp-output-visitor.c qemu-aio.h qemu-char.c qemu-common.h qemu-doc.texi qemu-img.c qemu-io.c qemu-nbd.texi qemu-options.hx qemu-os-win32.h qemu-queue.h qemu-timer.c qemu-timer.h qemu_socket.h qerror.c qerror.h qga/commands-posix.c qmp-commands.hx qom/container.c qom/object.c qtest.c qtest.h rules.mak savevm.c scripts/create_config scripts/gtester-cat scripts/kvm scripts/qapi-commands.py scripts/qapi-types.py script s/qapi-visit.py scripts/qapi.py scripts/qemu-gdb.py scripts/qtest scripts/signrom.py scripts/signrom.sh scripts/texi2pod.pl scripts/tracetool slirp/misc.c slirp/sbuf.c slirp/slirp.h slirp/tcp.h slirp/tcp_subr.c softmmu_header.h softmmu_template.h target-alpha/STATUS target-alpha/cpu-qom.h target-alpha/cpu.c target-alpha/cpu.h target-alpha/fpu_helper.c target-alpha/helper.c target-alpha/helper.h target-alpha/int_helper.c target-alpha/mem_helper.c target-alpha/op_helper.c target-alpha/sys_helper.c target-alpha/translate.c target-arm/cpu-qom.h target-arm/cpu.c target-arm/cpu.h target-arm/helper.c target-arm/op_helper.c target-arm/translate.c target-cris/op_helper.c target-i386/cpu-qom.h target-i386/cpu.c target-i386/cpu.h target-i386/cpuid.c target-i386/helper.c target-i386/op_helper.c target-lm32/cpu-qom.h target-lm32/cpu.c target-lm32/cpu.h target-lm32/helper.c target-lm32/op_helper.c target-m68k/op_helper.c target-microblaze/helper.c target-microblaze/mmu.c target-microblaze /op_helper.c target-microblaze/translate.c target-mips/TODO target-mips/cpu.h target-mips/helper.h target-mips/op_helper.c target-ppc/cpu-qom.h target-ppc/cpu.h target-ppc/helper.c target-ppc/kvm.c target-ppc/kvm_ppc.c target-ppc/kvm_ppc.h target-ppc/machine.c target-ppc/op_helper.c target-ppc/translate.c target-ppc/translate_init.c target-s390x/cpu-qom.h target-s390x/cpu.c target-s390x/cpu.h target-s390x/helper.c target-s390x/op_helper.c target-sh4/op_helper.c target-sparc/cpu-qom.h target-sparc/cpu.c target-sparc/cpu.h target-sparc/cpu_init.c target-sparc/helper.h target-sparc/ldst_helper.c target-sparc/mmu_helper.c target-unicore32/cpu-qom.h target-unicore32/cpu.c target-unicore32/cpu.h target-unicore32/helper.c target-unicore32/helper.h target-unicore32/op_helper.c target-unicore32/translate.c target-xtensa/core-dc232b.c target-xtensa/core-dc233c target-xtensa/core-dc233c.c target-xtensa/core-fsf.c target-xtensa/cpu-qom.h target-xtensa/cpu.c target-xtensa/cpu.h target-xt ensa/helper.c target-xtensa/helper.h target-xtensa/helpers.h target-xtensa/op_helper.c target-xtensa/translate.c tcg/hppa tcg/i386 tcg/ppc64 tcg/sparc tcg/tcg.c tcg/tcg.h tci.c test-coroutine.c test-qmp-commands.c test-qmp-input-visitor.c test-qmp-output-visitor.c test-string-input-visitor.c test-string-output-visitor.c tests/Makefile tests/check-qdict.c tests/check-qfloat.c tests/check-qint.c tests/check-qjson.c tests/check-qlist.c tests/check-qstring.c tests/libqtest.c tests/libqtest.h tests/qemu-iotests tests/rtc-test.c tests/tcg tests/test-coroutine.c tests/test-qmp-commands.c tests/test-qmp-input-strict.c tests/test-qmp-input-visitor.c tests/test-qmp-output-visitor.c tests/test-string-input-visitor.c tests/test-string-output-visitor.c thunk.c thunk.h trace-events translate-all.c ui/cocoa.m ui/spice-display.c user-exec.c vl.c xen-all.c xen-mapcache.c xen-stub.c xtensa-semi.c

Gerd Hoffmann kraxel at kemper.freedesktop.org
Wed Apr 18 03:20:17 PDT 2012


 CODING_STYLE                           |    2 
 MAINTAINERS                            |    5 
 Makefile                               |   12 
 Makefile.objs                          |    7 
 Makefile.target                        |   19 
 QMP/qmp-spec.txt                       |   20 
 arch_init.c                            |    2 
 block.c                                |   88 +
 block.h                                |   21 
 block/blkdebug.c                       |    7 
 block/cow.c                            |    6 
 block/curl.c                           |    2 
 block/qcow.c                           |    6 
 block/qcow2-cluster.c                  |   18 
 block/qcow2.c                          |    6 
 block/qed-check.c                      |    9 
 block/qed.c                            |   33 
 block/qed.h                            |    2 
 block/raw.c                            |    6 
 block/sheepdog.c                       |  144 ++-
 block/stream.c                         |   41 
 block/vdi.c                            |  429 ++-------
 block/vmdk.c                           |    4 
 block/vpc.c                            |    9 
 block_int.h                            |  135 ++
 blockdev.c                             |   12 
 bsd-user/main.c                        |    1 
 check-qdict.c                          |  378 --------
 check-qfloat.c                         |   53 -
 check-qint.c                           |   87 -
 check-qjson.c                          |  728 ---------------
 check-qlist.c                          |  127 --
 check-qstring.c                        |  107 --
 configure                              |   65 +
 coroutine-gthread.c                    |   96 +-
 cpu-all.h                              |   15 
 cpu-defs.h                             |   14 
 cpu-exec.c                             |    5 
 cpus.c                                 |   85 +
 cpus.h                                 |    2 
 def-helper.h                           |    7 
 dis-asm.h                              |    3 
 disas.c                                |   32 
 dma-helpers.c                          |   21 
 dma.h                                  |   13 
 docs/ccid.txt                          |    2 
 docs/qapi-code-gen.txt                 |    4 
 docs/specs/acpi_pci_hotplug.txt        |   18 
 docs/specs/ivshmem_device_spec.txt     |    2 
 elf.h                                  |   37 
 exec-all.h                             |   40 
 exec.c                                 |  112 +-
 fpu/softfloat.c                        |   12 
 fsdev/virtfs-proxy-helper.texi         |    2 
 gdbstub.c                              |   42 
 hmp-commands.hx                        |    3 
 hmp.c                                  |    9 
 hmp.h                                  |    1 
 hw/a15mpcore.c                         |   46 -
 hw/a9mpcore.c                          |   72 -
 hw/acpi_piix4.c                        |  134 +-
 hw/arm11mpcore.c                       |   56 -
 hw/arm_gic.c                           |  157 ++-
 hw/armv7m_nvic.c                       |   24 
 hw/blizzard.c                          |    4 
 hw/eepro100.c                          |   25 
 hw/exynos4210.c                        |   30 
 hw/exynos4210.h                        |    3 
 hw/exynos4210_combiner.c               |   10 
 hw/exynos4210_gic.c                    |   48 -
 hw/exynos4210_uart.c                   |    6 
 hw/exynos4_boards.c                    |    1 
 hw/ide/core.c                          |   60 +
 hw/ide/internal.h                      |    7 
 hw/ide/macio.c                         |    3 
 hw/ide/qdev.c                          |    7 
 hw/irq.c                               |   17 
 hw/irq.h                               |    5 
 hw/ivshmem.c                           |   58 -
 hw/kvm/clock.c                         |   16 
 hw/lsi53c895a.c                        |    1 
 hw/mc146818rtc.c                       |   33 
 hw/mc146818rtc.h                       |    3 
 hw/mc146818rtc_regs.h                  |   62 +
 hw/milkymist-sysctl.c                  |   26 
 hw/milkymist-vgafb.c                   |    5 
 hw/ne2000.c                            |   24 
 hw/omap1.c                             |   10 
 hw/omap_lcdc.c                         |    5 
 hw/opencores_eth.c                     |   25 
 hw/pc.c                                |   10 
 hw/pc_piix.c                           |  318 +-----
 hw/pci-hotplug.c                       |   14 
 hw/pci.c                               |   28 
 hw/pci.h                               |   11 
 hw/pci_bridge.c                        |   22 
 hw/pci_bridge_dev.c                    |  174 +++
 hw/pci_host.c                          |    3 
 hw/pci_regs.h                          |    3 
 hw/pcie_port.c                         |   12 
 hw/pcnet.c                             |   13 
 hw/pcnet.h                             |    1 
 hw/petalogix_s3adsp1800_mmu.c          |    1 
 hw/piix_pci.c                          |    5 
 hw/pl031.c                             |   75 +
 hw/ppc440_bamboo.c                     |    2 
 hw/ppc_prep.c                          |    2 
 hw/ppce500_mpc8544ds.c                 |    2 
 hw/ps2.c                               |    2 
 hw/ps2.h                               |   29 
 hw/pxa2xx.c                            |   28 
 hw/qdev-monitor.c                      |   27 
 hw/qdev-properties.c                   |   46 +
 hw/qdev.c                              |   39 
 hw/qdev.h                              |    8 
 hw/realview_gic.c                      |   46 -
 hw/rtl8139.c                           |   92 +-
 hw/serial.c                            |    5 
 hw/shpc.c                              |  681 ++++++++++++++
 hw/shpc.h                              |   48 +
 hw/slotid_cap.c                        |   44 
 hw/slotid_cap.h                        |   11 
 hw/spapr.h                             |    2 
 hw/spapr_llan.c                        |   26 
 hw/spapr_pci.c                         |  117 +-
 hw/spapr_rtas.c                        |   17 
 hw/spapr_vio.c                         |   62 -
 hw/spapr_vio.h                         |    5 
 hw/spapr_vscsi.c                       |   15 
 hw/spapr_vty.c                         |    4 
 hw/strongarm.c                         |   10 
 hw/sun4m.c                             |   12 
 hw/sun4u.c                             |   36 
 hw/twl92230.c                          |    9 
 hw/usb/dev-storage.c                   |    2 
 hw/vga.c                               |    2 
 hw/vhost.c                             |   10 
 hw/virtio-net.h                        |    1 
 hw/virtio-pci.c                        |    8 
 hw/xen.h                               |    1 
 hw/xen_apic.c                          |   90 +
 hw/xen_backend.c                       |   17 
 hw/xen_console.c                       |    3 
 hw/xen_disk.c                          |   15 
 hw/xen_platform.c                      |    4 
 include/qemu/object.h                  |   24 
 ioport.c                               |    2 
 kvm-all.c                              |   23 
 kvm-stub.c                             |    8 
 kvm.h                                  |    5 
 libcacard/vcard_emul_nss.c             |   36 
 linux-aio.c                            |    1 
 linux-headers/asm-powerpc/kvm.h        |    1 
 linux-headers/asm-s390/kvm.h           |    2 
 linux-headers/linux/kvm.h              |    9 
 linux-user/arm/syscall_nr.h            |    2 
 linux-user/elfload.c                   |   32 
 linux-user/ioctls.h                    |   34 
 linux-user/main.c                      |   51 -
 linux-user/mmap.c                      |   35 
 linux-user/qemu.h                      |    2 
 linux-user/syscall.c                   |  307 ++++++
 linux-user/syscall_defs.h              |   26 
 linux-user/syscall_types.h             |   40 
 lm32-dis.c                             |  361 +++++++
 main-loop.c                            |  149 +--
 main-loop.h                            |    1 
 memory.c                               |   19 
 migration.c                            |    1 
 monitor.c                              |    3 
 nbd.c                                  |    2 
 net.c                                  |   23 
 net.h                                  |    3 
 osdep.h                                |    2 
 oslib-win32.c                          |    3 
 pc-bios/optionrom/Makefile             |    2 
 ppc-dis.c                              |    2 
 qapi-schema-test.json                  |    2 
 qapi-schema.json                       |   20 
 qapi/qmp-input-visitor.c               |  120 +-
 qapi/qmp-input-visitor.h               |    2 
 qapi/qmp-output-visitor.c              |    8 
 qemu-aio.h                             |   21 
 qemu-char.c                            |    1 
 qemu-common.h                          |    2 
 qemu-doc.texi                          |    8 
 qemu-img.c                             |   12 
 qemu-io.c                              |   10 
 qemu-nbd.texi                          |    2 
 qemu-options.hx                        |   33 
 qemu-os-win32.h                        |   35 
 qemu-queue.h                           |    2 
 qemu-timer.c                           |   12 
 qemu-timer.h                           |    1 
 qemu_socket.h                          |    4 
 qerror.c                               |    7 
 qerror.h                               |    4 
 qga/commands-posix.c                   |  111 +-
 qmp-commands.hx                        |    9 
 qom/container.c                        |   23 
 qom/object.c                           |   33 
 qtest.c                                |  444 +++++++++
 qtest.h                                |   35 
 rules.mak                              |    2 
 savevm.c                               |    3 
 scripts/create_config                  |    6 
 scripts/gtester-cat                    |   26 
 scripts/kvm/kvm_flightrecorder         |  126 ++
 scripts/qapi-commands.py               |   16 
 scripts/qapi-types.py                  |    4 
 scripts/qapi-visit.py                  |   24 
 scripts/qapi.py                        |    5 
 scripts/qemu-gdb.py                    |   89 +
 scripts/qtest                          |    5 
 scripts/signrom.py                     |   40 
 scripts/signrom.sh                     |   45 
 scripts/texi2pod.pl                    |    9 
 scripts/tracetool                      |   30 
 slirp/misc.c                           |   46 -
 slirp/sbuf.c                           |    6 
 slirp/slirp.h                          |   14 
 slirp/tcp.h                            |   21 
 slirp/tcp_subr.c                       |    4 
 softmmu_header.h                       |   15 
 softmmu_template.h                     |   42 
 target-alpha/STATUS                    |    2 
 target-alpha/cpu-qom.h                 |   71 +
 target-alpha/cpu.c                     |   58 +
 target-alpha/cpu.h                     |    7 
 target-alpha/fpu_helper.c              |  822 ++++++++++++++++++
 target-alpha/helper.c                  |   60 +
 target-alpha/helper.h                  |  143 +--
 target-alpha/int_helper.c              |  319 +++++++
 target-alpha/mem_helper.c              |  151 +++
 target-alpha/op_helper.c               | 1379 ------------------------------
 target-alpha/sys_helper.c              |   87 +
 target-alpha/translate.c               |  234 ++---
 target-arm/cpu-qom.h                   |   71 +
 target-arm/cpu.c                       |   60 +
 target-arm/cpu.h                       |   35 
 target-arm/helper.c                    |   23 
 target-arm/op_helper.c                 |    8 
 target-arm/translate.c                 |   13 
 target-cris/op_helper.c                |   12 
 target-i386/cpu-qom.h                  |   75 +
 target-i386/cpu.c                      | 1503 +++++++++++++++++++++++++++++++++
 target-i386/cpu.h                      |    3 
 target-i386/cpuid.c                    | 1369 ------------------------------
 target-i386/helper.c                   |  100 --
 target-i386/op_helper.c                |    8 
 target-lm32/cpu-qom.h                  |   71 +
 target-lm32/cpu.c                      |   81 +
 target-lm32/cpu.h                      |    1 
 target-lm32/helper.c                   |   19 
 target-lm32/op_helper.c                |    8 
 target-m68k/op_helper.c                |    8 
 target-microblaze/helper.c             |    1 
 target-microblaze/mmu.c                |    1 
 target-microblaze/op_helper.c          |    9 
 target-microblaze/translate.c          |    1 
 target-mips/TODO                       |    4 
 target-mips/cpu.h                      |    2 
 target-mips/helper.h                   |    4 
 target-mips/op_helper.c                |   21 
 target-ppc/cpu-qom.h                   |   77 +
 target-ppc/cpu.h                       |    9 
 target-ppc/helper.c                    |   75 -
 target-ppc/kvm.c                       |   16 
 target-ppc/kvm_ppc.c                   |    2 
 target-ppc/kvm_ppc.h                   |    5 
 target-ppc/machine.c                   |    8 
 target-ppc/op_helper.c                 |    8 
 target-ppc/translate.c                 |    2 
 target-ppc/translate_init.c            |  176 +++
 target-s390x/cpu-qom.h                 |   71 +
 target-s390x/cpu.c                     |   96 ++
 target-s390x/cpu.h                     |    5 
 target-s390x/helper.c                  |   41 
 target-s390x/op_helper.c               |    8 
 target-sh4/op_helper.c                 |   14 
 target-sparc/cpu-qom.h                 |   75 +
 target-sparc/cpu.c                     |  899 +++++++++++++++++++
 target-sparc/cpu.h                     |    6 
 target-sparc/cpu_init.c                |  849 ------------------
 target-sparc/helper.h                  |    2 
 target-sparc/ldst_helper.c             |   12 
 target-sparc/mmu_helper.c              |   19 
 target-unicore32/cpu-qom.h             |   59 +
 target-unicore32/cpu.c                 |  104 ++
 target-unicore32/cpu.h                 |    4 
 target-unicore32/helper.c              |   65 -
 target-unicore32/helper.h              |    3 
 target-unicore32/op_helper.c           |    3 
 target-unicore32/translate.c           |    3 
 target-xtensa/core-dc232b.c            |   27 
 target-xtensa/core-dc233c.c            |   55 +
 target-xtensa/core-dc233c/core-isa.h   |  474 ++++++++++
 target-xtensa/core-dc233c/gdb-config.c |  145 +++
 target-xtensa/core-fsf.c               |   27 
 target-xtensa/cpu-qom.h                |   80 +
 target-xtensa/cpu.c                    |   88 +
 target-xtensa/cpu.h                    |    2 
 target-xtensa/helper.c                 |   20 
 target-xtensa/helper.h                 |   39 
 target-xtensa/helpers.h                |   39 
 target-xtensa/op_helper.c              |   40 
 target-xtensa/translate.c              |    8 
 tcg/hppa/tcg-target.c                  |  103 +-
 tcg/i386/tcg-target.c                  |  157 +++
 tcg/ppc64/tcg-target.c                 |    1 
 tcg/sparc/tcg-target.c                 |   63 +
 tcg/tcg.c                              |  283 ++++++
 tcg/tcg.h                              |    2 
 tci.c                                  |   35 
 test-coroutine.c                       |  219 ----
 test-qmp-commands.c                    |  142 ---
 test-qmp-input-visitor.c               |  289 ------
 test-qmp-output-visitor.c              |  457 ----------
 test-string-input-visitor.c            |  195 ----
 test-string-output-visitor.c           |  188 ----
 tests/Makefile                         |  164 ++-
 tests/check-qdict.c                    |  378 ++++++++
 tests/check-qfloat.c                   |   53 +
 tests/check-qint.c                     |   87 +
 tests/check-qjson.c                    |  728 +++++++++++++++
 tests/check-qlist.c                    |  127 ++
 tests/check-qstring.c                  |  107 ++
 tests/libqtest.c                       |  387 ++++++++
 tests/libqtest.h                       |  335 +++++++
 tests/qemu-iotests/009                 |    4 
 tests/qemu-iotests/010                 |    6 
 tests/qemu-iotests/011                 |    2 
 tests/qemu-iotests/031                 |   72 +
 tests/qemu-iotests/031.out             |   76 +
 tests/qemu-iotests/common.rc           |    9 
 tests/qemu-iotests/group               |    1 
 tests/qemu-iotests/qcow2.py            |  207 ++++
 tests/rtc-test.c                       |  263 +++++
 tests/tcg/lm32/Makefile                |   13 
 tests/tcg/xtensa/Makefile              |    3 
 tests/tcg/xtensa/macros.inc            |   17 
 tests/tcg/xtensa/test_break.S          |   34 
 tests/tcg/xtensa/test_loop.S           |   50 +
 tests/test-coroutine.c                 |  219 ++++
 tests/test-qmp-commands.c              |  139 +++
 tests/test-qmp-input-strict.c          |  234 +++++
 tests/test-qmp-input-visitor.c         |  308 ++++++
 tests/test-qmp-output-visitor.c        |  477 ++++++++++
 tests/test-string-input-visitor.c      |  195 ++++
 tests/test-string-output-visitor.c     |  188 ++++
 thunk.c                                |   28 
 thunk.h                                |   28 
 trace-events                           |    4 
 translate-all.c                        |    6 
 ui/cocoa.m                             |    2 
 ui/spice-display.c                     |   24 
 user-exec.c                            |    2 
 vl.c                                   |   14 
 xen-all.c                              |   50 -
 xen-mapcache.c                         |   15 
 xen-stub.c                             |    4 
 xtensa-semi.c                          |    2 
 362 files changed, 17570 insertions(+), 9401 deletions(-)

New commits:
commit 158fd3ce98afd21f2e2639600f6414ea703a9121
Author: Peter Portante <peter.portante at redhat.com>
Date:   Thu Apr 5 11:00:45 2012 -0400

    qemu-timer.c: Remove 250us timeouts
    
    Basically, the main wait loop calls qemu_run_all_timers() unconditionally. The
    first thing this routine used to do is to see if a timer had been serviced,
    and then reset the loop timeout to the next deadline.
    
    However, the new deadlines had not been calculated at that point, as
    qemu_run_timers() had not been called yet for each of the clocks. So
    qemu_rearm_alarm_timer() would end up with a negative or zero deadline, and
    default to setting a 250us timeout for the loop.
    
    As qemu_run_timers() is called for each clock, the real deadlines would be put
    in place, but because a loop timeout was already set, the loop timeout would
    not be changed.
    
    Once that 250us timeout fired, the real deadline would be used for the
    subsequent timeout.
    
    For idle VMs, this effectively doubles the number of times through the loop,
    doubling the number of select() system calls, timer calls, etc. putting added
    scheduling pressure on the kernel. And under cgroups, this really causes a big
    problem because the cgroup code does not scale well.
    
    By simply running the timers before trying to rearm the timer, we always rearm
    with a non-zero deadline, effectively halving the number of system calls.
    
    Signed-off-by: Peter Portante <pportant at redhat.com>
    Signed-off-by: Anthony Liguori <aliguori at us.ibm.com>

diff --git a/qemu-timer.c b/qemu-timer.c
index 80bcc56..17915df 100644
--- a/qemu-timer.c
+++ b/qemu-timer.c
@@ -472,16 +472,16 @@ void qemu_run_all_timers(void)
 {
     alarm_timer->pending = 0;
 
+    /* vm time timers */
+    qemu_run_timers(vm_clock);
+    qemu_run_timers(rt_clock);
+    qemu_run_timers(host_clock);
+
     /* rearm timer, if not periodic */
     if (alarm_timer->expired) {
         alarm_timer->expired = 0;
         qemu_rearm_alarm_timer(alarm_timer);
     }
-
-    /* vm time timers */
-    qemu_run_timers(vm_clock);
-    qemu_run_timers(rt_clock);
-    qemu_run_timers(host_clock);
 }
 
 #ifdef _WIN32
commit fc34e77bb3dd41a9932ec5830c06bcade1f5a08e
Merge: 52346e8... 9bea6a2...
Author: Anthony Liguori <aliguori at us.ibm.com>
Date:   Mon Apr 16 12:56:28 2012 -0500

    Merge remote-tracking branch 'kiszka/queues/pending' into staging
    
    * kiszka/queues/pending:
      vapic: Disable for pre-1.1 machines
      Kick io-thread on qemu_chr_accept_input
      pcnet: Properly handle TX requests during Link Fail
      pcnet: Clear ERR in CSR0 on stop
      signrom: Rewrite as python script
    
    Conflicts:
    	hw/pc_piix.c
    
    Signed-off-by: Anthony Liguori <aliguori at us.ibm.com>

diff --cc hw/pc_piix.c
index 5c08245,44995bf..907d723
--- a/hw/pc_piix.c
+++ b/hw/pc_piix.c
@@@ -360,21 -359,6 +360,25 @@@ static QEMUMachine pc_machine_v1_1 = 
      .is_default = 1,
  };
  
 +#define PC_COMPAT_1_0 \
 +        {\
 +            .driver   = "pc-sysfw",\
 +            .property = "rom_only",\
 +            .value    = stringify(1),\
 +        }, {\
 +            .driver   = "isa-fdc",\
 +            .property = "check_media_rate",\
 +            .value    = "off",\
 +        }, {\
 +            .driver   = "virtio-balloon-pci",\
 +            .property = "class",\
 +            .value    = stringify(PCI_CLASS_MEMORY_RAM),\
++        },{\
++            .driver   = "apic",\
++            .property = "vapic",\
++            .value    = "off",\
 +        }
 +
  static QEMUMachine pc_machine_v1_0 = {
      .name = "pc-1.0",
      .desc = "Standard PC",
commit 52346e8c75eba1ece4a782565d5a5ce2e23d5117
Merge: 8a6b870... cdde6ff...
Author: Anthony Liguori <aliguori at us.ibm.com>
Date:   Mon Apr 16 12:52:22 2012 -0500

    Merge remote-tracking branch 'mst/tags/for_anthony' into staging
    
    * mst/tags/for_anthony:
      pci: fix corrupted pci conf index register by unaligned write
      acpi: explicitly account for >1 device per slot
      acpi_piix4: Re-define PCI hotplug eject register read
      acpi_piix4: Remove PCI_RMV_BASE write code
      acpi_piix4: Fix PCI hotplug race
      acpi_piix4: Disallow write to up/down PCI hotplug registers
      virtio-pci: change virtio balloon PCI class code
      ivshmem: add missing msix calls
      vhost: readd assert statement
      vhost: Fix size of dirty log sync on resize
      pc: reduce duplication in compat machine types
      piix_pci: fix typo in i400FX chipset init code

commit 8a6b8708e37a4df064aa3b36d7baa786110871f4
Merge: e6f5d0b... fda1f76...
Author: Anthony Liguori <aliguori at us.ibm.com>
Date:   Mon Apr 16 12:50:12 2012 -0500

    Merge remote-tracking branch 'sstabellini/for_anthony' into staging
    
    * sstabellini/for_anthony:
      xen: introduce an event channel for buffered io event notifications
      xen-mapcache: don't unmap locked entry during mapcache invalidation
      Xen, mapcache: Fix the compute of the size of bucket.
      xen: handle backend deletion from xenstore
      Xen: Add xen-apic support and hook it up.
      Xen: basic HVM MSI injection support.

commit 9bea6a2956e5d473b8914b2a5483fbf187b33844
Author: Jan Kiszka <jan.kiszka at siemens.com>
Date:   Thu Mar 29 14:07:46 2012 +0200

    vapic: Disable for pre-1.1 machines
    
    The kvmvapic was not present in older QEMU versions, thus must be
    disabled in compat machines.
    
    Signed-off-by: Jan Kiszka <jan.kiszka at siemens.com>

diff --git a/hw/pc_piix.c b/hw/pc_piix.c
index fadca4c..44995bf 100644
--- a/hw/pc_piix.c
+++ b/hw/pc_piix.c
@@ -373,6 +373,10 @@ static QEMUMachine pc_machine_v1_0 = {
             .driver   = "isa-fdc",
             .property = "check_media_rate",
             .value    = "off",
+        },{
+            .driver   = "apic",
+            .property = "vapic",
+            .value    = "off",
         },
         { /* end of list */ }
     },
@@ -392,6 +396,10 @@ static QEMUMachine pc_machine_v0_15 = {
             .driver   = "isa-fdc",
             .property = "check_media_rate",
             .value    = "off",
+        },{
+            .driver   = "apic",
+            .property = "vapic",
+            .value    = "off",
         },
         { /* end of list */ }
     },
@@ -431,11 +439,14 @@ static QEMUMachine pc_machine_v0_14 = {
             .driver   = "isa-fdc",
             .property = "check_media_rate",
             .value    = "off",
-        },
-        {
+        },{
             .driver   = "pc-sysfw",
             .property = "rom_only",
             .value    = stringify(1),
+        },{
+            .driver   = "apic",
+            .property = "vapic",
+            .value    = "off",
         },
         { /* end of list */ }
     },
@@ -487,11 +498,14 @@ static QEMUMachine pc_machine_v0_13 = {
             .driver   = "isa-fdc",
             .property = "check_media_rate",
             .value    = "off",
-        },
-        {
+        },{
             .driver   = "pc-sysfw",
             .property = "rom_only",
             .value    = stringify(1),
+        },{
+            .driver   = "apic",
+            .property = "vapic",
+            .value    = "off",
         },
         { /* end of list */ }
     },
@@ -547,11 +561,14 @@ static QEMUMachine pc_machine_v0_12 = {
             .driver   = "isa-fdc",
             .property = "check_media_rate",
             .value    = "off",
-        },
-        {
+        },{
             .driver   = "pc-sysfw",
             .property = "rom_only",
             .value    = stringify(1),
+        },{
+            .driver   = "apic",
+            .property = "vapic",
+            .value    = "off",
         },
         { /* end of list */ }
     }
@@ -615,11 +632,14 @@ static QEMUMachine pc_machine_v0_11 = {
             .driver   = "isa-fdc",
             .property = "check_media_rate",
             .value    = "off",
-        },
-        {
+        },{
             .driver   = "pc-sysfw",
             .property = "rom_only",
             .value    = stringify(1),
+        },{
+            .driver   = "apic",
+            .property = "vapic",
+            .value    = "off",
         },
         { /* end of list */ }
     }
@@ -695,11 +715,14 @@ static QEMUMachine pc_machine_v0_10 = {
             .driver   = "isa-fdc",
             .property = "check_media_rate",
             .value    = "off",
-        },
-        {
+        },{
             .driver   = "pc-sysfw",
             .property = "rom_only",
             .value    = stringify(1),
+        },{
+            .driver   = "apic",
+            .property = "vapic",
+            .value    = "off",
         },
         { /* end of list */ }
     },
commit 98c8ee1da81b88252263f9215ca23b2044650696
Author: Jan Kiszka <jan.kiszka at siemens.com>
Date:   Fri Mar 16 13:18:00 2012 +0100

    Kick io-thread on qemu_chr_accept_input
    
    Once a chr frontend is able to receive input again, we need to inform
    the io-thread about this fact. Otherwise, main_loop_wait may continue to
    select without the related backend file descriptor in its set. This can
    cause high input latencies if only low-rate events arrive otherwise.
    
    Signed-off-by: Jan Kiszka <jan.kiszka at siemens.com>

diff --git a/qemu-char.c b/qemu-char.c
index bb9e3f5..74c60e1 100644
--- a/qemu-char.c
+++ b/qemu-char.c
@@ -177,6 +177,7 @@ void qemu_chr_accept_input(CharDriverState *s)
 {
     if (s->chr_accept_input)
         s->chr_accept_input(s);
+    qemu_notify_event();
 }
 
 void qemu_chr_fe_printf(CharDriverState *s, const char *fmt, ...)
commit ef45c9147f534531ef5d8a20315089d43ea4ddef
Author: Jan Kiszka <jan.kiszka at siemens.com>
Date:   Wed Feb 29 15:37:43 2012 +0100

    pcnet: Properly handle TX requests during Link Fail
    
    As long as we have no link and we aren't in internal loopback mode, no
    packet must be sent. Instead, LCAR needs to be set in any active TX
    descriptor and also CERR in CSR0.
    
    Signed-off-by: Jan Kiszka <jan.kiszka at siemens.com>

diff --git a/hw/pcnet.c b/hw/pcnet.c
index 7413409..d769b08 100644
--- a/hw/pcnet.c
+++ b/hw/pcnet.c
@@ -77,6 +77,7 @@ struct qemu_ether_header {
 #define CSR_DTX(S)       !!(((S)->csr[15])&0x0002)
 #define CSR_LOOP(S)      !!(((S)->csr[15])&0x0004)
 #define CSR_DXMTFCS(S)   !!(((S)->csr[15])&0x0008)
+#define CSR_INTL(S)      !!(((S)->csr[15])&0x0040)
 #define CSR_DRCVPA(S)    !!(((S)->csr[15])&0x2000)
 #define CSR_DRCVBC(S)    !!(((S)->csr[15])&0x4000)
 #define CSR_PROM(S)      !!(((S)->csr[15])&0x8000)
@@ -1234,6 +1235,15 @@ static void pcnet_transmit(PCNetState *s)
             if (BCR_SWSTYLE(s) != 1)
                 add_crc = GET_FIELD(tmd.status, TMDS, ADDFCS);
         }
+        if (s->lnkst == 0 &&
+            (!CSR_LOOP(s) || (!CSR_INTL(s) && !BCR_TMAULOOP(s)))) {
+            SET_FIELD(&tmd.misc, TMDM, LCAR, 1);
+            SET_FIELD(&tmd.status, TMDS, ERR, 1);
+            SET_FIELD(&tmd.status, TMDS, OWN, 0);
+            s->csr[0] |= 0xa000; /* ERR | CERR */
+            s->xmit_pos = -1;
+            goto txdone;
+        }
         if (!GET_FIELD(tmd.status, TMDS, ENP)) {
             int bcnt = 4096 - GET_FIELD(tmd.length, TMDL, BCNT);
             s->phys_mem_read(s->dma_opaque, PHYSADDR(s, tmd.tbadr),
@@ -1262,6 +1272,7 @@ static void pcnet_transmit(PCNetState *s)
             s->xmit_pos = -1;
         }
 
+    txdone:
         SET_FIELD(&tmd.status, TMDS, OWN, 0);
         TMDSTORE(&tmd, PHYSADDR(s,CSR_CXDA(s)));
         if (!CSR_TOKINTD(s) || (CSR_LTINTEN(s) && GET_FIELD(tmd.status, TMDS, LTINT)))
diff --git a/hw/pcnet.h b/hw/pcnet.h
index edc81c9..803a2cc 100644
--- a/hw/pcnet.h
+++ b/hw/pcnet.h
@@ -20,6 +20,7 @@
 #define BCR_SWS      20
 #define BCR_PLAT     22
 
+#define BCR_TMAULOOP(S)  !!((S)->bcr[BCR_MC  ] & 0x4000)
 #define BCR_APROMWE(S)   !!((S)->bcr[BCR_MC  ] & 0x0100)
 #define BCR_DWIO(S)      !!((S)->bcr[BCR_BSBC] & 0x0080)
 #define BCR_SSIZE32(S)   !!((S)->bcr[BCR_SWS ] & 0x0100)
commit 6655124ddd6442b19a4b43b27e7d5a3846c4e6a8
Author: Jan Kiszka <jan.kiszka at siemens.com>
Date:   Wed Feb 29 15:33:48 2012 +0100

    pcnet: Clear ERR in CSR0 on stop
    
    pcnet_stop already clears any reason (BABL, CERR, MISS, MERR) why ERR
    (bit 15) should be set in CRS0. So we have to clear that bit as well.
    
    Signed-off-by: Jan Kiszka <jan.kiszka at siemens.com>

diff --git a/hw/pcnet.c b/hw/pcnet.c
index c53f06e..7413409 100644
--- a/hw/pcnet.c
+++ b/hw/pcnet.c
@@ -884,7 +884,7 @@ static void pcnet_stop(PCNetState *s)
 #ifdef PCNET_DEBUG
     printf("pcnet_stop\n");
 #endif
-    s->csr[0] &= ~0x7feb;
+    s->csr[0] &= ~0xffeb;
     s->csr[0] |= 0x0014;
     s->csr[4] &= ~0x02c2;
     s->csr[5] &= ~0x0011;
commit 0d6b9cc7420dd2d531b48508f0d4083d1c6a632a
Author: Jan Kiszka <jan.kiszka at siemens.com>
Date:   Fri Jan 27 19:44:53 2012 +0100

    signrom: Rewrite as python script
    
    Now that we have a hard dependency on python anyway, we can replace the
    slow shell script to calculate the option ROM checksum with a fast AND
    portable python version. Tested both with python 2.7 and 3.1.
    
    Signed-off-by: Jan Kiszka <jan.kiszka at siemens.com>

diff --git a/pc-bios/optionrom/Makefile b/pc-bios/optionrom/Makefile
index f6b4027..57d8bd0 100644
--- a/pc-bios/optionrom/Makefile
+++ b/pc-bios/optionrom/Makefile
@@ -26,7 +26,7 @@ build-all: multiboot.bin linuxboot.bin kvmvapic.bin
 	$(call quiet-command,$(OBJCOPY) -O binary -j .text $< $@,"  Building $(TARGET_DIR)$@")
 
 %.bin: %.raw
-	$(call quiet-command,$(SHELL) $(SRC_PATH)/scripts/signrom.sh $< $@,"  Signing $(TARGET_DIR)$@")
+	$(call quiet-command,$(PYTHON) $(SRC_PATH)/scripts/signrom.py $< $@,"  Signing $(TARGET_DIR)$@")
 
 clean:
 	rm -f *.o *.d *.raw *.img *.bin *~
diff --git a/scripts/signrom.py b/scripts/signrom.py
new file mode 100644
index 0000000..f9c35cc
--- /dev/null
+++ b/scripts/signrom.py
@@ -0,0 +1,40 @@
+#
+# Option ROM signing utility
+#
+# Authors:
+#  Jan Kiszka <jan.kiszka at siemens.com>
+#
+# This work is licensed under the terms of the GNU GPL, version 2 or later.
+# See the COPYING file in the top-level directory.
+
+import sys
+import struct
+
+if len(sys.argv) < 3:
+    print('usage: signrom.py input output')
+    sys.exit(1)
+
+fin = open(sys.argv[1], 'rb')
+fout = open(sys.argv[2], 'wb')
+
+fin.seek(2)
+size = ord(fin.read(1)) * 512 - 1
+
+fin.seek(0)
+data = fin.read(size)
+fout.write(data)
+
+checksum = 0
+for b in data:
+    # catch Python 2 vs. 3 differences
+    if isinstance(b, int):
+        checksum += b
+    else:
+        checksum += ord(b)
+checksum = (256 - checksum) % 256
+
+# Python 3 no longer allows chr(checksum)
+fout.write(struct.pack('B', checksum))
+
+fin.close()
+fout.close()
diff --git a/scripts/signrom.sh b/scripts/signrom.sh
deleted file mode 100755
index 9dc5c63..0000000
--- a/scripts/signrom.sh
+++ /dev/null
@@ -1,45 +0,0 @@
-#!/bin/sh
-
-# Option ROM Signing utility
-#
-# This program is free software; you can redistribute it and/or modify
-# it under the terms of the GNU General Public License as published by
-# the Free Software Foundation; either version 2 of the License, or
-# (at your option) any later version.
-#
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-# GNU General Public License for more details.
-#
-# You should have received a copy of the GNU General Public License
-# along with this program; if not, see <http://www.gnu.org/licenses/>.
-#
-# Copyright Novell Inc, 2009
-#   Authors: Alexander Graf <agraf at suse.de>
-#
-# Syntax: signrom.sh <input> <output>
-
-# did we get proper arguments?
-test "$1" -a "$2" || exit 1
-
-sum=0
-
-# find out the file size
-x=`dd if="$1" bs=1 count=1 skip=2 2>/dev/null | od -t u1 -A n`
-#size=`expr $x \* 512 - 1`
-size=$(( $x * 512 - 1 ))
-
-# now get the checksum
-nums=`od -A n -t u1 -v -N $size "$1"`
-for i in ${nums}; do
-    # add each byte's value to sum
-    sum=`expr \( $sum + $i \) % 256`
-done
-
-sum=$(( (256 - $sum) % 256 ))
-sum_octal=$( printf "%o" $sum )
-
-# and write the output file
-cp "$1" "$2"
-printf "\\$sum_octal" | dd of="$2" bs=1 count=1 seek=$size conv=notrunc 2>/dev/null
commit e6f5d0be730a41bacb10edba19d1369ec2949486
Merge: 9444006... 55dd9ff...
Author: Blue Swirl <blauwirbel at gmail.com>
Date:   Sun Apr 15 19:56:06 2012 +0000

    Merge branch 'w64' of git://qemu.weilnetz.de/qemu
    
    * 'w64' of git://qemu.weilnetz.de/qemu:
      w64: Fix time conversion for some versions of MinGW-w64
      nbd: Fix compiler warning (w64)
      disas: Replace 'unsigned long' by 'uintptr_t'
      cpu-exec: Remove non-portable type cast and fix format string
      target-mips: Fix type cast for w64 (uintptr_t)
      w64: Fix type cast in os_host_main_loop_wait
      w64: Fix data types in softmmu*.h
      w64: Use uintptr_t in exec.c
      softmmu: Use uintptr_t for physaddr and rename it
      w64: Fix struct CPUTLBEntry
      w64: Fix definition of setjmp
      w32: Move defines for socket specific errors to qemu-os-win32.h
      w64: Use larger alignment for section with generated code
      w64: Fix data types in cpu-all.h, exec.c
      w64: Fix type casts used in some macros in cpu-all.h
      tcg/i386: Add support for w64 ABI
      tcg/i386: Use GDB JIT debugging interface only for hosts with ELF

commit 9444006fa6ba1d5e4079ee534a7236124b66ea77
Author: Andreas Färber <afaerber at suse.de>
Date:   Sat Apr 7 01:19:45 2012 +0200

    target-alpha: QOM'ify CPU init
    
    Move code from cpu_alpha_init() into a CPU initializer.
    
    Signed-off-by: Andreas Färber <afaerber at suse.de>
    Acked-by: Richard Henderson <rth at twiddle.net>

diff --git a/target-alpha/cpu.c b/target-alpha/cpu.c
index 315b0c1..62d2a66 100644
--- a/target-alpha/cpu.c
+++ b/target-alpha/cpu.c
@@ -1,6 +1,7 @@
 /*
  * QEMU Alpha CPU
  *
+ * Copyright (c) 2007 Jocelyn Mayer
  * Copyright (c) 2012 SUSE LINUX Products GmbH
  *
  * This library is free software; you can redistribute it and/or
@@ -22,10 +23,29 @@
 #include "qemu-common.h"
 
 
+static void alpha_cpu_initfn(Object *obj)
+{
+    AlphaCPU *cpu = ALPHA_CPU(obj);
+    CPUAlphaState *env = &cpu->env;
+
+    cpu_exec_init(env);
+    tlb_flush(env, 1);
+
+#if defined(CONFIG_USER_ONLY)
+    env->ps = PS_USER_MODE;
+    cpu_alpha_store_fpcr(env, (FPCR_INVD | FPCR_DZED | FPCR_OVFD
+                               | FPCR_UNFD | FPCR_INED | FPCR_DNOD
+                               | FPCR_DYN_NORMAL));
+#endif
+    env->lock_addr = -1;
+    env->fen = 1;
+}
+
 static const TypeInfo alpha_cpu_type_info = {
     .name = TYPE_ALPHA_CPU,
     .parent = TYPE_CPU,
     .instance_size = sizeof(AlphaCPU),
+    .instance_init = alpha_cpu_initfn,
     .abstract = false,
     .class_size = sizeof(AlphaCPUClass),
 };
diff --git a/target-alpha/translate.c b/target-alpha/translate.c
index f773e6c..12de6a3 100644
--- a/target-alpha/translate.c
+++ b/target-alpha/translate.c
@@ -3531,9 +3531,8 @@ CPUAlphaState * cpu_alpha_init (const char *cpu_model)
 
     cpu = ALPHA_CPU(object_new(TYPE_ALPHA_CPU));
     env = &cpu->env;
-    cpu_exec_init(env);
+
     alpha_translate_init();
-    tlb_flush(env, 1);
 
     /* Default to ev67; no reason not to emulate insns by default.  */
     implver = IMPLVER_21264;
@@ -3551,15 +3550,6 @@ CPUAlphaState * cpu_alpha_init (const char *cpu_model)
     env->implver = implver;
     env->amask = amask;
 
-#if defined (CONFIG_USER_ONLY)
-    env->ps = PS_USER_MODE;
-    cpu_alpha_store_fpcr(env, (FPCR_INVD | FPCR_DZED | FPCR_OVFD
-                               | FPCR_UNFD | FPCR_INED | FPCR_DNOD
-                               | FPCR_DYN_NORMAL));
-#endif
-    env->lock_addr = -1;
-    env->fen = 1;
-
     qemu_init_vcpu(env);
     return env;
 }
commit 25ebd80f1d0e4b8863968d56ccfe634ea577d365
Author: Andreas Färber <afaerber at suse.de>
Date:   Fri Apr 6 19:46:48 2012 +0200

    target-alpha: QOM'ify CPU
    
    Embed CPUAlphaState as first member of AlphaCPU.
    
    Signed-off-by: Andreas Färber <afaerber at suse.de>
    Acked-by: Richard Henderson <rth at twiddle.net>

diff --git a/Makefile.target b/Makefile.target
index 3ab791a..61dfe3b 100644
--- a/Makefile.target
+++ b/Makefile.target
@@ -104,6 +104,7 @@ libobj-$(TARGET_SPARC64) += int64_helper.o
 libobj-$(TARGET_UNICORE32) += cpu.o
 libobj-$(TARGET_XTENSA) += cpu.o
 libobj-$(TARGET_ALPHA) += int_helper.o fpu_helper.o sys_helper.o mem_helper.o
+libobj-$(TARGET_ALPHA) += cpu.o
 
 libobj-y += disas.o
 libobj-$(CONFIG_TCI_DIS) += tci-dis.o
diff --git a/target-alpha/cpu-qom.h b/target-alpha/cpu-qom.h
new file mode 100644
index 0000000..6b4ca6d
--- /dev/null
+++ b/target-alpha/cpu-qom.h
@@ -0,0 +1,71 @@
+/*
+ * QEMU Alpha CPU
+ *
+ * Copyright (c) 2012 SUSE LINUX Products GmbH
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, see
+ * <http://www.gnu.org/licenses/lgpl-2.1.html>
+ */
+#ifndef QEMU_ALPHA_CPU_QOM_H
+#define QEMU_ALPHA_CPU_QOM_H
+
+#include "qemu/cpu.h"
+#include "cpu.h"
+
+#define TYPE_ALPHA_CPU "alpha-cpu"
+
+#define ALPHA_CPU_CLASS(klass) \
+    OBJECT_CLASS_CHECK(AlphaCPUClass, (klass), TYPE_ALPHA_CPU)
+#define ALPHA_CPU(obj) \
+    OBJECT_CHECK(AlphaCPU, (obj), TYPE_ALPHA_CPU)
+#define ALPHA_CPU_GET_CLASS(obj) \
+    OBJECT_GET_CLASS(AlphaCPUClass, (obj), TYPE_ALPHA_CPU)
+
+/**
+ * AlphaCPUClass:
+ * @parent_reset: The parent class' reset handler.
+ *
+ * An Alpha CPU model.
+ */
+typedef struct AlphaCPUClass {
+    /*< private >*/
+    CPUClass parent_class;
+    /*< public >*/
+
+    void (*parent_reset)(CPUState *cpu);
+} AlphaCPUClass;
+
+/**
+ * AlphaCPU:
+ * @env: #CPUAlphaState
+ *
+ * An Alpha CPU.
+ */
+typedef struct AlphaCPU {
+    /*< private >*/
+    CPUState parent_obj;
+    /*< public >*/
+
+    CPUAlphaState env;
+} AlphaCPU;
+
+static inline AlphaCPU *alpha_env_get_cpu(CPUAlphaState *env)
+{
+    return ALPHA_CPU(container_of(env, AlphaCPU, env));
+}
+
+#define ENV_GET_CPU(e) CPU(alpha_env_get_cpu(e))
+
+
+#endif
diff --git a/target-alpha/cpu.c b/target-alpha/cpu.c
new file mode 100644
index 0000000..315b0c1
--- /dev/null
+++ b/target-alpha/cpu.c
@@ -0,0 +1,38 @@
+/*
+ * QEMU Alpha CPU
+ *
+ * Copyright (c) 2012 SUSE LINUX Products GmbH
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, see
+ * <http://www.gnu.org/licenses/lgpl-2.1.html>
+ */
+
+#include "cpu-qom.h"
+#include "qemu-common.h"
+
+
+static const TypeInfo alpha_cpu_type_info = {
+    .name = TYPE_ALPHA_CPU,
+    .parent = TYPE_CPU,
+    .instance_size = sizeof(AlphaCPU),
+    .abstract = false,
+    .class_size = sizeof(AlphaCPUClass),
+};
+
+static void alpha_cpu_register_types(void)
+{
+    type_register_static(&alpha_cpu_type_info);
+}
+
+type_init(alpha_cpu_register_types)
diff --git a/target-alpha/cpu.h b/target-alpha/cpu.h
index fd578ce..99f9ee1 100644
--- a/target-alpha/cpu.h
+++ b/target-alpha/cpu.h
@@ -292,6 +292,7 @@ struct CPUAlphaState {
 #define cpu_signal_handler cpu_alpha_signal_handler
 
 #include "cpu-all.h"
+#include "cpu-qom.h"
 
 enum {
     FEATURE_ASN    = 0x00000001,
diff --git a/target-alpha/translate.c b/target-alpha/translate.c
index 1f4565d..f773e6c 100644
--- a/target-alpha/translate.c
+++ b/target-alpha/translate.c
@@ -3525,10 +3525,12 @@ static const struct cpu_def_t cpu_defs[] = {
 
 CPUAlphaState * cpu_alpha_init (const char *cpu_model)
 {
+    AlphaCPU *cpu;
     CPUAlphaState *env;
     int implver, amask, i, max;
 
-    env = g_malloc0(sizeof(CPUAlphaState));
+    cpu = ALPHA_CPU(object_new(TYPE_ALPHA_CPU));
+    env = &cpu->env;
     cpu_exec_init(env);
     alpha_translate_init();
     tlb_flush(env, 1);
commit 55dd9ffa70eb44f461b12c248c3df106ba8deca9
Author: Stefan Weil <sw at weilnetz.de>
Date:   Thu Apr 12 22:33:12 2012 +0200

    w64: Fix time conversion for some versions of MinGW-w64
    
    tb.time is a time value, but not necessarily of the same size as time_t:
    while time_t is 64 bit for w64, tb.time still is 32 bit only.
    
    Therefore we need en explicit conversion.
    
    Signed-off-by: Stefan Weil <sw at weilnetz.de>

diff --git a/savevm.c b/savevm.c
index 12fb209..2d18bab 100644
--- a/savevm.c
+++ b/savevm.c
@@ -2106,7 +2106,8 @@ void do_savevm(Monitor *mon, const QDict *qdict)
         }
     } else {
 #ifdef _WIN32
-        ptm = localtime(&tb.time);
+        time_t t = tb.time;
+        ptm = localtime(&t);
         strftime(sn->name, sizeof(sn->name), "vm-%Y%m%d%H%M%S", ptm);
 #else
         /* cast below needed for OpenBSD where tv_sec is still 'long' */
commit 0fee8f342884e96b29d7df28475d0c485a317d54
Author: Stefan Weil <sw at weilnetz.de>
Date:   Thu Apr 12 22:30:16 2012 +0200

    nbd: Fix compiler warning (w64)
    
    Portable printing of dev_offset (data type off_t) needs a type cast.
    
    Signed-off-by: Stefan Weil <sw at weilnetz.de>

diff --git a/nbd.c b/nbd.c
index 567e94e..406e555 100644
--- a/nbd.c
+++ b/nbd.c
@@ -813,7 +813,7 @@ static void nbd_trip(void *opaque)
             LOG("From: %" PRIu64 ", Len: %u, Size: %" PRIu64
             ", Offset: %" PRIu64 "\n",
                     request.from, request.len,
-                    (uint64_t)exp->size, exp->dev_offset);
+                    (uint64_t)exp->size, (uint64_t)exp->dev_offset);
         LOG("requested operation past EOF--bad client?");
         goto invalid_request;
     }
commit b0b0f1c964bb7643a6d4469ffd8157de84741d1f
Author: Stefan Weil <sw at weilnetz.de>
Date:   Thu Apr 12 15:44:35 2012 +0200

    disas: Replace 'unsigned long' by 'uintptr_t'
    
    This is needed for w64. It changes nothing for other hosts.
    
    Signed-off-by: Stefan Weil <sw at weilnetz.de>

diff --git a/disas.c b/disas.c
index 4f2c4e4..27071c3 100644
--- a/disas.c
+++ b/disas.c
@@ -268,7 +268,7 @@ void target_disas(FILE *out, target_ulong code, target_ulong size, int flags)
 /* Disassemble this for me please... (debugging). */
 void disas(FILE *out, void *code, unsigned long size)
 {
-    unsigned long pc;
+    uintptr_t pc;
     int count;
     struct disassemble_info disasm_info;
     int (*print_insn)(bfd_vma pc, disassemble_info *info);
@@ -276,7 +276,7 @@ void disas(FILE *out, void *code, unsigned long size)
     INIT_DISASSEMBLE_INFO(disasm_info, out, fprintf);
 
     disasm_info.buffer = code;
-    disasm_info.buffer_vma = (unsigned long)code;
+    disasm_info.buffer_vma = (uintptr_t)code;
     disasm_info.buffer_length = size;
 
 #ifdef HOST_WORDS_BIGENDIAN
@@ -320,8 +320,8 @@ void disas(FILE *out, void *code, unsigned long size)
 	    (long) code);
     return;
 #endif
-    for (pc = (unsigned long)code; size > 0; pc += count, size -= count) {
-	fprintf(out, "0x%08lx:  ", pc);
+    for (pc = (uintptr_t)code; size > 0; pc += count, size -= count) {
+        fprintf(out, "0x%08" PRIxPTR ":  ", pc);
 	count = print_insn(pc, &disasm_info);
 	fprintf(out, "\n");
 	if (count < 0)
commit 3ba19255450666869ecfe764774c2371f989e68b
Author: Stefan Weil <sw at weilnetz.de>
Date:   Thu Apr 12 15:44:24 2012 +0200

    cpu-exec: Remove non-portable type cast and fix format string
    
    This change is needed for w64, but also changes the code for other hosts.
    
    Signed-off-by: Stefan Weil <sw at weilnetz.de>

diff --git a/cpu-exec.c b/cpu-exec.c
index d153f97..0344cd5 100644
--- a/cpu-exec.c
+++ b/cpu-exec.c
@@ -541,8 +541,8 @@ int cpu_exec(CPUArchState *env)
                     tb_invalidated_flag = 0;
                 }
 #ifdef CONFIG_DEBUG_EXEC
-                qemu_log_mask(CPU_LOG_EXEC, "Trace 0x%08lx [" TARGET_FMT_lx "] %s\n",
-                             (long)tb->tc_ptr, tb->pc,
+                qemu_log_mask(CPU_LOG_EXEC, "Trace %p [" TARGET_FMT_lx "] %s\n",
+                             tb->tc_ptr, tb->pc,
                              lookup_symbol(tb->pc));
 #endif
                 /* see if we can patch the calling TB. When the TB
commit b69e48a84d83162efd4782472572783e99840cf5
Author: Stefan Weil <sw at weilnetz.de>
Date:   Thu Apr 12 15:43:09 2012 +0200

    target-mips: Fix type cast for w64 (uintptr_t)
    
    This changes nothing for other hosts.
    
    Signed-off-by: Stefan Weil <sw at weilnetz.de>

diff --git a/target-mips/op_helper.c b/target-mips/op_helper.c
index bca1d70..5627447 100644
--- a/target-mips/op_helper.c
+++ b/target-mips/op_helper.c
@@ -2275,7 +2275,7 @@ void helper_pmon (int function)
         break;
     case 158:
         {
-            unsigned char *fmt = (void *)(unsigned long)env->active_tc.gpr[4];
+            unsigned char *fmt = (void *)(uintptr_t)env->active_tc.gpr[4];
             printf("%s", fmt);
         }
         break;
commit 58b9630d7e2252d077b632c3a26d1aa334cf5fe6
Author: Stefan Weil <sw at weilnetz.de>
Date:   Thu Apr 12 20:42:34 2012 +0200

    w64: Fix type cast in os_host_main_loop_wait
    
    Casting a pointer to an integer must use (DWORD_PTR) instead of (DWORD).
    This also matches the definition of 'fd' (gint for w32, gint64 for w64).
    
    Signed-off-by: Stefan Weil <sw at weilnetz.de>

diff --git a/main-loop.c b/main-loop.c
index 1ebdc4b..4887c73 100644
--- a/main-loop.c
+++ b/main-loop.c
@@ -430,7 +430,7 @@ static int os_host_main_loop_wait(int timeout)
     g_assert(n_poll_fds <= ARRAY_SIZE(poll_fds));
 
     for (i = 0; i < w->num; i++) {
-        poll_fds[n_poll_fds + i].fd = (DWORD) w->events[i];
+        poll_fds[n_poll_fds + i].fd = (DWORD_PTR)w->events[i];
         poll_fds[n_poll_fds + i].events = G_IO_IN;
     }
 
commit b065927a02cbbaca032ed20d3039baca0914165c
Author: Stefan Weil <sw at weilnetz.de>
Date:   Thu Apr 12 14:14:51 2012 +0200

    w64: Fix data types in softmmu*.h
    
    w64 requires uintptr_t.
    
    Signed-off-by: Stefan Weil <sw at weilnetz.de>

diff --git a/softmmu_header.h b/softmmu_header.h
index 289dae2..cf1aa38 100644
--- a/softmmu_header.h
+++ b/softmmu_header.h
@@ -111,7 +111,7 @@ glue(glue(glue(CPU_PREFIX, ld), USUFFIX), MEMSUFFIX)(ENV_PARAM
                                                                      mmu_idx);
     } else {
         uintptr_t hostaddr = addr + env->tlb_table[mmu_idx][page_index].addend;
-        res = glue(glue(ld, USUFFIX), _raw)((uint8_t *)hostaddr);
+        res = glue(glue(ld, USUFFIX), _raw)(hostaddr);
     }
     return res;
 }
@@ -134,7 +134,7 @@ glue(glue(glue(CPU_PREFIX, lds), SUFFIX), MEMSUFFIX)(ENV_PARAM
                                MMUSUFFIX)(ENV_VAR addr, mmu_idx);
     } else {
         uintptr_t hostaddr = addr + env->tlb_table[mmu_idx][page_index].addend;
-        res = glue(glue(lds, SUFFIX), _raw)((uint8_t *)hostaddr);
+        res = glue(glue(lds, SUFFIX), _raw)(hostaddr);
     }
     return res;
 }
@@ -161,7 +161,7 @@ glue(glue(glue(CPU_PREFIX, st), SUFFIX), MEMSUFFIX)(ENV_PARAM target_ulong ptr,
                                                                mmu_idx);
     } else {
         uintptr_t hostaddr = addr + env->tlb_table[mmu_idx][page_index].addend;
-        glue(glue(st, SUFFIX), _raw)((uint8_t *)hostaddr, v);
+        glue(glue(st, SUFFIX), _raw)(hostaddr, v);
     }
 }
 
diff --git a/softmmu_template.h b/softmmu_template.h
index b285d78..b8bd700 100644
--- a/softmmu_template.h
+++ b/softmmu_template.h
@@ -112,7 +112,6 @@ glue(glue(glue(HELPER_PREFIX, ld), SUFFIX), MMUSUFFIX)(ENV_PARAM
     int index;
     target_ulong tlb_addr;
     target_phys_addr_t ioaddr;
-    unsigned long addend;
     uintptr_t retaddr;
 
     /* test if there is match for unaligned or IO access */
@@ -139,6 +138,7 @@ glue(glue(glue(HELPER_PREFIX, ld), SUFFIX), MMUSUFFIX)(ENV_PARAM
                                                          mmu_idx, retaddr);
         } else {
             /* unaligned/aligned access in the same page */
+            uintptr_t addend;
 #ifdef ALIGNED_ONLY
             if ((addr & (DATA_SIZE - 1)) != 0) {
                 retaddr = GETPC();
@@ -146,7 +146,8 @@ glue(glue(glue(HELPER_PREFIX, ld), SUFFIX), MMUSUFFIX)(ENV_PARAM
             }
 #endif
             addend = env->tlb_table[mmu_idx][index].addend;
-            res = glue(glue(ld, USUFFIX), _raw)((uint8_t *)(long)(addr+addend));
+            res = glue(glue(ld, USUFFIX), _raw)((uint8_t *)(intptr_t)
+                                                (addr + addend));
         }
     } else {
         /* the page is not in the TLB : fill it */
@@ -171,7 +172,6 @@ glue(glue(slow_ld, SUFFIX), MMUSUFFIX)(ENV_PARAM
     DATA_TYPE res, res1, res2;
     int index, shift;
     target_phys_addr_t ioaddr;
-    unsigned long addend;
     target_ulong tlb_addr, addr1, addr2;
 
     index = (addr >> TARGET_PAGE_BITS) & (CPU_TLB_SIZE - 1);
@@ -202,8 +202,9 @@ glue(glue(slow_ld, SUFFIX), MMUSUFFIX)(ENV_PARAM
             res = (DATA_TYPE)res;
         } else {
             /* unaligned/aligned access in the same page */
-            addend = env->tlb_table[mmu_idx][index].addend;
-            res = glue(glue(ld, USUFFIX), _raw)((uint8_t *)(long)(addr+addend));
+            uintptr_t addend = env->tlb_table[mmu_idx][index].addend;
+            res = glue(glue(ld, USUFFIX), _raw)((uint8_t *)(intptr_t)
+                                                (addr + addend));
         }
     } else {
         /* the page is not in the TLB : fill it */
@@ -258,7 +259,6 @@ void glue(glue(glue(HELPER_PREFIX, st), SUFFIX), MMUSUFFIX)(ENV_PARAM
                                                             int mmu_idx)
 {
     target_phys_addr_t ioaddr;
-    unsigned long addend;
     target_ulong tlb_addr;
     uintptr_t retaddr;
     int index;
@@ -284,6 +284,7 @@ void glue(glue(glue(HELPER_PREFIX, st), SUFFIX), MMUSUFFIX)(ENV_PARAM
                                                    mmu_idx, retaddr);
         } else {
             /* aligned/unaligned access in the same page */
+            uintptr_t addend;
 #ifdef ALIGNED_ONLY
             if ((addr & (DATA_SIZE - 1)) != 0) {
                 retaddr = GETPC();
@@ -291,7 +292,8 @@ void glue(glue(glue(HELPER_PREFIX, st), SUFFIX), MMUSUFFIX)(ENV_PARAM
             }
 #endif
             addend = env->tlb_table[mmu_idx][index].addend;
-            glue(glue(st, SUFFIX), _raw)((uint8_t *)(long)(addr+addend), val);
+            glue(glue(st, SUFFIX), _raw)((uint8_t *)(intptr_t)
+                                         (addr + addend), val);
         }
     } else {
         /* the page is not in the TLB : fill it */
@@ -313,7 +315,6 @@ static void glue(glue(slow_st, SUFFIX), MMUSUFFIX)(ENV_PARAM
                                                    uintptr_t retaddr)
 {
     target_phys_addr_t ioaddr;
-    unsigned long addend;
     target_ulong tlb_addr;
     int index, i;
 
@@ -345,8 +346,9 @@ static void glue(glue(slow_st, SUFFIX), MMUSUFFIX)(ENV_PARAM
             }
         } else {
             /* aligned/unaligned access in the same page */
-            addend = env->tlb_table[mmu_idx][index].addend;
-            glue(glue(st, SUFFIX), _raw)((uint8_t *)(long)(addr+addend), val);
+            uintptr_t addend = env->tlb_table[mmu_idx][index].addend;
+            glue(glue(st, SUFFIX), _raw)((uint8_t *)(intptr_t)
+                                         (addr + addend), val);
         }
     } else {
         /* the page is not in the TLB : fill it */
commit 8efe0ca83eb9c5f996acc7a37d522da5c542ec79
Author: Stefan Weil <sw at weilnetz.de>
Date:   Thu Apr 12 15:42:19 2012 +0200

    w64: Use uintptr_t in exec.c
    
    Replace all type casts to 'long' or 'unsigned long' by 'intptr_t' or 'uintptr_t'.
    
    For type casts which are only used to extract the lower bits of an address
    or to modify those bits, signedness does not matter. There I always use 'uintptr_t'.
    
    Signed-off-by: Stefan Weil <sw at weilnetz.de>

diff --git a/exec.c b/exec.c
index 6d10595..77d6866 100644
--- a/exec.c
+++ b/exec.c
@@ -887,8 +887,8 @@ static inline void tb_page_remove(TranslationBlock **ptb, TranslationBlock *tb)
 
     for(;;) {
         tb1 = *ptb;
-        n1 = (long)tb1 & 3;
-        tb1 = (TranslationBlock *)((long)tb1 & ~3);
+        n1 = (uintptr_t)tb1 & 3;
+        tb1 = (TranslationBlock *)((uintptr_t)tb1 & ~3);
         if (tb1 == tb) {
             *ptb = tb1->page_next[n1];
             break;
@@ -908,8 +908,8 @@ static inline void tb_jmp_remove(TranslationBlock *tb, int n)
         /* find tb(n) in circular list */
         for(;;) {
             tb1 = *ptb;
-            n1 = (long)tb1 & 3;
-            tb1 = (TranslationBlock *)((long)tb1 & ~3);
+            n1 = (uintptr_t)tb1 & 3;
+            tb1 = (TranslationBlock *)((uintptr_t)tb1 & ~3);
             if (n1 == n && tb1 == tb)
                 break;
             if (n1 == 2) {
@@ -929,7 +929,7 @@ static inline void tb_jmp_remove(TranslationBlock *tb, int n)
    another TB */
 static inline void tb_reset_jump(TranslationBlock *tb, int n)
 {
-    tb_set_jmp_target(tb, n, (unsigned long)(tb->tc_ptr + tb->tb_next_offset[n]));
+    tb_set_jmp_target(tb, n, (uintptr_t)(tb->tc_ptr + tb->tb_next_offset[n]));
 }
 
 void tb_phys_invalidate(TranslationBlock *tb, tb_page_addr_t page_addr)
@@ -974,16 +974,16 @@ void tb_phys_invalidate(TranslationBlock *tb, tb_page_addr_t page_addr)
     /* suppress any remaining jumps to this TB */
     tb1 = tb->jmp_first;
     for(;;) {
-        n1 = (long)tb1 & 3;
+        n1 = (uintptr_t)tb1 & 3;
         if (n1 == 2)
             break;
-        tb1 = (TranslationBlock *)((long)tb1 & ~3);
+        tb1 = (TranslationBlock *)((uintptr_t)tb1 & ~3);
         tb2 = tb1->jmp_next[n1];
         tb_reset_jump(tb1, n1);
         tb1->jmp_next[n1] = NULL;
         tb1 = tb2;
     }
-    tb->jmp_first = (TranslationBlock *)((long)tb | 2); /* fail safe */
+    tb->jmp_first = (TranslationBlock *)((uintptr_t)tb | 2); /* fail safe */
 
     tb_phys_invalidate_count++;
 }
@@ -1024,8 +1024,8 @@ static void build_page_bitmap(PageDesc *p)
 
     tb = p->first_tb;
     while (tb != NULL) {
-        n = (long)tb & 3;
-        tb = (TranslationBlock *)((long)tb & ~3);
+        n = (uintptr_t)tb & 3;
+        tb = (TranslationBlock *)((uintptr_t)tb & ~3);
         /* NOTE: this is subtle as a TB may span two physical pages */
         if (n == 0) {
             /* NOTE: tb_end may be after the end of the page, but
@@ -1069,7 +1069,8 @@ TranslationBlock *tb_gen_code(CPUArchState *env,
     tb->flags = flags;
     tb->cflags = cflags;
     cpu_gen_code(env, tb, &code_gen_size);
-    code_gen_ptr = (void *)(((unsigned long)code_gen_ptr + code_gen_size + CODE_GEN_ALIGN - 1) & ~(CODE_GEN_ALIGN - 1));
+    code_gen_ptr = (void *)(((uintptr_t)code_gen_ptr + code_gen_size +
+                             CODE_GEN_ALIGN - 1) & ~(CODE_GEN_ALIGN - 1));
 
     /* check next page if needed */
     virt_page2 = (pc + tb->size - 1) & TARGET_PAGE_MASK;
@@ -1117,8 +1118,8 @@ void tb_invalidate_phys_page_range(tb_page_addr_t start, tb_page_addr_t end,
     /* XXX: see if in some cases it could be faster to invalidate all the code */
     tb = p->first_tb;
     while (tb != NULL) {
-        n = (long)tb & 3;
-        tb = (TranslationBlock *)((long)tb & ~3);
+        n = (uintptr_t)tb & 3;
+        tb = (TranslationBlock *)((uintptr_t)tb & ~3);
         tb_next = tb->page_next[n];
         /* NOTE: this is subtle as a TB may span two physical pages */
         if (n == 0) {
@@ -1201,7 +1202,8 @@ static inline void tb_invalidate_phys_page_fast(tb_page_addr_t start, int len)
         qemu_log("modifying code at 0x%x size=%d EIP=%x PC=%08x\n",
                   cpu_single_env->mem_io_vaddr, len,
                   cpu_single_env->eip,
-                  cpu_single_env->eip + (long)cpu_single_env->segs[R_CS].base);
+                  cpu_single_env->eip +
+                  (intptr_t)cpu_single_env->segs[R_CS].base);
     }
 #endif
     p = page_find(start >> TARGET_PAGE_BITS);
@@ -1245,8 +1247,8 @@ static void tb_invalidate_phys_page(tb_page_addr_t addr,
     }
 #endif
     while (tb != NULL) {
-        n = (long)tb & 3;
-        tb = (TranslationBlock *)((long)tb & ~3);
+        n = (uintptr_t)tb & 3;
+        tb = (TranslationBlock *)((uintptr_t)tb & ~3);
 #ifdef TARGET_HAS_PRECISE_SMC
         if (current_tb == tb &&
             (current_tb->cflags & CF_COUNT_MASK) != 1) {
@@ -1294,7 +1296,7 @@ static inline void tb_alloc_page(TranslationBlock *tb,
 #ifndef CONFIG_USER_ONLY
     page_already_protected = p->first_tb != NULL;
 #endif
-    p->first_tb = (TranslationBlock *)((long)tb | n);
+    p->first_tb = (TranslationBlock *)((uintptr_t)tb | n);
     invalidate_page_bitmap(p);
 
 #if defined(TARGET_HAS_SMC) || 1
@@ -1361,7 +1363,7 @@ void tb_link_page(TranslationBlock *tb,
     else
         tb->page_addr[1] = -1;
 
-    tb->jmp_first = (TranslationBlock *)((long)tb | 2);
+    tb->jmp_first = (TranslationBlock *)((uintptr_t)tb | 2);
     tb->jmp_next[0] = NULL;
     tb->jmp_next[1] = NULL;
 
@@ -1382,21 +1384,22 @@ void tb_link_page(TranslationBlock *tb,
 TranslationBlock *tb_find_pc(uintptr_t tc_ptr)
 {
     int m_min, m_max, m;
-    unsigned long v;
+    uintptr_t v;
     TranslationBlock *tb;
 
     if (nb_tbs <= 0)
         return NULL;
-    if (tc_ptr < (unsigned long)code_gen_buffer ||
-        tc_ptr >= (unsigned long)code_gen_ptr)
+    if (tc_ptr < (uintptr_t)code_gen_buffer ||
+        tc_ptr >= (uintptr_t)code_gen_ptr) {
         return NULL;
+    }
     /* binary search (cf Knuth) */
     m_min = 0;
     m_max = nb_tbs - 1;
     while (m_min <= m_max) {
         m = (m_min + m_max) >> 1;
         tb = &tbs[m];
-        v = (unsigned long)tb->tc_ptr;
+        v = (uintptr_t)tb->tc_ptr;
         if (v == tc_ptr)
             return tb;
         else if (tc_ptr < v) {
@@ -1419,8 +1422,8 @@ static inline void tb_reset_jump_recursive2(TranslationBlock *tb, int n)
     if (tb1 != NULL) {
         /* find head of list */
         for(;;) {
-            n1 = (long)tb1 & 3;
-            tb1 = (TranslationBlock *)((long)tb1 & ~3);
+            n1 = (uintptr_t)tb1 & 3;
+            tb1 = (TranslationBlock *)((uintptr_t)tb1 & ~3);
             if (n1 == 2)
                 break;
             tb1 = tb1->jmp_next[n1];
@@ -1432,8 +1435,8 @@ static inline void tb_reset_jump_recursive2(TranslationBlock *tb, int n)
         ptb = &tb_next->jmp_first;
         for(;;) {
             tb1 = *ptb;
-            n1 = (long)tb1 & 3;
-            tb1 = (TranslationBlock *)((long)tb1 & ~3);
+            n1 = (uintptr_t)tb1 & 3;
+            tb1 = (TranslationBlock *)((uintptr_t)tb1 & ~3);
             if (n1 == n && tb1 == tb)
                 break;
             ptb = &tb1->jmp_next[n1];
@@ -2040,9 +2043,9 @@ static bool tlb_is_dirty_ram(CPUTLBEntry *tlbe)
 }
 
 static inline void tlb_reset_dirty_range(CPUTLBEntry *tlb_entry,
-                                         unsigned long start, unsigned long length)
+                                         uintptr_t start, uintptr_t length)
 {
-    unsigned long addr;
+    uintptr_t addr;
     if (tlb_is_dirty_ram(tlb_entry)) {
         addr = (tlb_entry->addr_write & TARGET_PAGE_MASK) + tlb_entry->addend;
         if ((addr - start) < length) {
@@ -2056,7 +2059,7 @@ void cpu_physical_memory_reset_dirty(ram_addr_t start, ram_addr_t end,
                                      int dirty_flags)
 {
     CPUArchState *env;
-    unsigned long length, start1;
+    uintptr_t length, start1;
     int i;
 
     start &= TARGET_PAGE_MASK;
@@ -2069,10 +2072,10 @@ void cpu_physical_memory_reset_dirty(ram_addr_t start, ram_addr_t end,
 
     /* we modify the TLB cache so that the dirty bit will be set again
        when accessing the range */
-    start1 = (unsigned long)qemu_safe_ram_ptr(start);
+    start1 = (uintptr_t)qemu_safe_ram_ptr(start);
     /* Check that we don't span multiple blocks - this breaks the
        address comparisons below.  */
-    if ((unsigned long)qemu_safe_ram_ptr(end - 1) - start1
+    if ((uintptr_t)qemu_safe_ram_ptr(end - 1) - start1
             != (end - 1) - start) {
         abort();
     }
@@ -2100,7 +2103,7 @@ static inline void tlb_update_dirty(CPUTLBEntry *tlb_entry)
     void *p;
 
     if (tlb_is_dirty_ram(tlb_entry)) {
-        p = (void *)(unsigned long)((tlb_entry->addr_write & TARGET_PAGE_MASK)
+        p = (void *)(uintptr_t)((tlb_entry->addr_write & TARGET_PAGE_MASK)
             + tlb_entry->addend);
         ram_addr = qemu_ram_addr_from_host_nofail(p);
         if (!cpu_physical_memory_is_dirty(ram_addr)) {
@@ -2190,7 +2193,7 @@ void tlb_set_page(CPUArchState *env, target_ulong vaddr,
     unsigned int index;
     target_ulong address;
     target_ulong code_address;
-    unsigned long addend;
+    uintptr_t addend;
     CPUTLBEntry *te;
     CPUWatchpoint *wp;
     target_phys_addr_t iotlb;
@@ -2212,7 +2215,7 @@ void tlb_set_page(CPUArchState *env, target_ulong vaddr,
         address |= TLB_MMIO;
     }
     if (is_ram_rom_romd(section)) {
-        addend = (unsigned long)memory_region_get_ram_ptr(section->mr)
+        addend = (uintptr_t)memory_region_get_ram_ptr(section->mr)
                                  + section_addr(section, paddr);
     } else {
         addend = 0;
@@ -2302,7 +2305,7 @@ struct walk_memory_regions_data
 {
     walk_memory_regions_fn fn;
     void *priv;
-    unsigned long start;
+    uintptr_t start;
     int prot;
 };
 
@@ -2363,7 +2366,7 @@ static int walk_memory_regions_1(struct walk_memory_regions_data *data,
 int walk_memory_regions(void *priv, walk_memory_regions_fn fn)
 {
     struct walk_memory_regions_data data;
-    unsigned long i;
+    uintptr_t i;
 
     data.fn = fn;
     data.priv = priv;
@@ -2551,7 +2554,7 @@ int page_unprotect(target_ulong address, uintptr_t pc, void *puc)
 }
 
 static inline void tlb_set_dirty(CPUArchState *env,
-                                 unsigned long addr, target_ulong vaddr)
+                                 uintptr_t addr, target_ulong vaddr)
 {
 }
 #endif /* defined(CONFIG_USER_ONLY) */
commit 23ddbf08bfe3cf3e9d6993bd7918b6c4339ba2bb
Author: Stefan Weil <sw at weilnetz.de>
Date:   Sun Apr 15 21:02:09 2012 +0200

    softmmu: Use uintptr_t for physaddr and rename it
    
    Variable physaddr is a host address which should be represented by
    data type 'uintptr_t'.
    
    This is needed for w64 and changes nothing for other hosts.
    
    v2:
    Rename physaddr -> hostaddr (suggested by Blue Swirl).
    
    Signed-off-by: Stefan Weil <sw at weilnetz.de>

diff --git a/softmmu_header.h b/softmmu_header.h
index 6b72093..289dae2 100644
--- a/softmmu_header.h
+++ b/softmmu_header.h
@@ -99,7 +99,6 @@ glue(glue(glue(CPU_PREFIX, ld), USUFFIX), MEMSUFFIX)(ENV_PARAM
     int page_index;
     RES_TYPE res;
     target_ulong addr;
-    unsigned long physaddr;
     int mmu_idx;
 
     addr = ptr;
@@ -111,8 +110,8 @@ glue(glue(glue(CPU_PREFIX, ld), USUFFIX), MEMSUFFIX)(ENV_PARAM
                                                                      addr,
                                                                      mmu_idx);
     } else {
-        physaddr = addr + env->tlb_table[mmu_idx][page_index].addend;
-        res = glue(glue(ld, USUFFIX), _raw)((uint8_t *)physaddr);
+        uintptr_t hostaddr = addr + env->tlb_table[mmu_idx][page_index].addend;
+        res = glue(glue(ld, USUFFIX), _raw)((uint8_t *)hostaddr);
     }
     return res;
 }
@@ -124,7 +123,6 @@ glue(glue(glue(CPU_PREFIX, lds), SUFFIX), MEMSUFFIX)(ENV_PARAM
 {
     int res, page_index;
     target_ulong addr;
-    unsigned long physaddr;
     int mmu_idx;
 
     addr = ptr;
@@ -135,8 +133,8 @@ glue(glue(glue(CPU_PREFIX, lds), SUFFIX), MEMSUFFIX)(ENV_PARAM
         res = (DATA_STYPE)glue(glue(glue(HELPER_PREFIX, ld), SUFFIX),
                                MMUSUFFIX)(ENV_VAR addr, mmu_idx);
     } else {
-        physaddr = addr + env->tlb_table[mmu_idx][page_index].addend;
-        res = glue(glue(lds, SUFFIX), _raw)((uint8_t *)physaddr);
+        uintptr_t hostaddr = addr + env->tlb_table[mmu_idx][page_index].addend;
+        res = glue(glue(lds, SUFFIX), _raw)((uint8_t *)hostaddr);
     }
     return res;
 }
@@ -152,7 +150,6 @@ glue(glue(glue(CPU_PREFIX, st), SUFFIX), MEMSUFFIX)(ENV_PARAM target_ulong ptr,
 {
     int page_index;
     target_ulong addr;
-    unsigned long physaddr;
     int mmu_idx;
 
     addr = ptr;
@@ -163,8 +160,8 @@ glue(glue(glue(CPU_PREFIX, st), SUFFIX), MEMSUFFIX)(ENV_PARAM target_ulong ptr,
         glue(glue(glue(HELPER_PREFIX, st), SUFFIX), MMUSUFFIX)(ENV_VAR addr, v,
                                                                mmu_idx);
     } else {
-        physaddr = addr + env->tlb_table[mmu_idx][page_index].addend;
-        glue(glue(st, SUFFIX), _raw)((uint8_t *)physaddr, v);
+        uintptr_t hostaddr = addr + env->tlb_table[mmu_idx][page_index].addend;
+        glue(glue(st, SUFFIX), _raw)((uint8_t *)hostaddr, v);
     }
 }
 
commit 3b2992e42f8945f4bc6b9151f83dbf2bb5bcd538
Author: Stefan Weil <sw at weilnetz.de>
Date:   Thu Apr 12 20:29:36 2012 +0200

    w64: Fix struct CPUTLBEntry
    
    For w64, some entries need 'uintptr_t' instead of 'unsigned long'.
    
    For other host systems, both data types are identical, so nothing changes.
    
    Signed-off-by: Stefan Weil <sw at weilnetz.de>

diff --git a/cpu-defs.h b/cpu-defs.h
index 88d8093..f49e950 100644
--- a/cpu-defs.h
+++ b/cpu-defs.h
@@ -98,12 +98,12 @@ typedef struct CPUTLBEntry {
     target_ulong addr_code;
     /* Addend to virtual address to get host address.  IO accesses
        use the corresponding iotlb value.  */
-    unsigned long addend;
+    uintptr_t addend;
     /* padding to get a power of two size */
-    uint8_t dummy[(1 << CPU_TLB_ENTRY_BITS) - 
-                  (sizeof(target_ulong) * 3 + 
-                   ((-sizeof(target_ulong) * 3) & (sizeof(unsigned long) - 1)) + 
-                   sizeof(unsigned long))];
+    uint8_t dummy[(1 << CPU_TLB_ENTRY_BITS) -
+                  (sizeof(target_ulong) * 3 +
+                   ((-sizeof(target_ulong) * 3) & (sizeof(uintptr_t) - 1)) +
+                   sizeof(uintptr_t))];
 } CPUTLBEntry;
 
 extern int CPUTLBEntry_wrong_size[sizeof(CPUTLBEntry) == (1 << CPU_TLB_ENTRY_BITS) ? 1 : -1];
commit 5cf6dd51abb252d25cb77d3b7a95a744bed1a69c
Author: Stefan Weil <sw at weilnetz.de>
Date:   Thu Apr 12 21:13:28 2012 +0200

    w64: Fix definition of setjmp
    
    The default definition of setjmp which is implemented in MinGW-w64
    cannot be used with programs like QEMU which call longjmp from
    code without structured exception handling (SEH).
    
    This code therefore disables stack unwinding.
    
    We could also implement SEH for QEMU's generated JIT code, but
    that is much more difficult. Stack unwinding would also cost
    execution time.
    
    Signed-off-by: Stefan Weil <sw at weilnetz.de>

diff --git a/qemu-os-win32.h b/qemu-os-win32.h
index b6533c0..753679b 100644
--- a/qemu-os-win32.h
+++ b/qemu-os-win32.h
@@ -56,6 +56,15 @@
 # define EWOULDBLOCK  WSAEWOULDBLOCK
 #endif
 
+#if defined(_WIN64)
+/* On w64, setjmp is implemented by _setjmp which needs a second parameter.
+ * If this parameter is NULL, longjump does no stack unwinding.
+ * That is what we need for QEMU. Passing the value of register rsp (default)
+ * lets longjmp try a stack unwinding which will crash with generated code. */
+# undef setjmp
+# define setjmp(env) _setjmp(env, NULL)
+#endif
+
 /* Declaration of ffs() is missing in MinGW's strings.h. */
 int ffs(int i);
 
commit acf126ba58425f11e74fbb9c1095224cb142fffa
Author: Stefan Weil <sw at weilnetz.de>
Date:   Thu Apr 12 21:13:15 2012 +0200

    w32: Move defines for socket specific errors to qemu-os-win32.h
    
    As those defines are only used for w32,
    they should be in the header file for w32.
    
    All files which include slirp.h or qemu_socket.h also
    include qemu-os-win32.h.
    
    Signed-off-by: Stefan Weil <sw at weilnetz.de>

diff --git a/qemu-os-win32.h b/qemu-os-win32.h
index 8eda4bd..b6533c0 100644
--- a/qemu-os-win32.h
+++ b/qemu-os-win32.h
@@ -30,6 +30,32 @@
 #include <winsock2.h>
 #include "main-loop.h"
 
+/* Workaround for older versions of MinGW. */
+#ifndef ECONNREFUSED
+# define ECONNREFUSED WSAECONNREFUSED
+#endif
+#ifndef EINPROGRESS
+# define EINPROGRESS  WSAEINPROGRESS
+#endif
+#ifndef EHOSTUNREACH
+# define EHOSTUNREACH WSAEHOSTUNREACH
+#endif
+#ifndef EINTR
+# define EINTR        WSAEINTR
+#endif
+#ifndef EINPROGRESS
+# define EINPROGRESS  WSAEINPROGRESS
+#endif
+#ifndef ENETUNREACH
+# define ENETUNREACH  WSAENETUNREACH
+#endif
+#ifndef ENOTCONN
+# define ENOTCONN     WSAENOTCONN
+#endif
+#ifndef EWOULDBLOCK
+# define EWOULDBLOCK  WSAEWOULDBLOCK
+#endif
+
 /* Declaration of ffs() is missing in MinGW's strings.h. */
 int ffs(int i);
 
diff --git a/qemu_socket.h b/qemu_socket.h
index 51ad210..a5d0a84 100644
--- a/qemu_socket.h
+++ b/qemu_socket.h
@@ -8,12 +8,6 @@
 #include <ws2tcpip.h>
 
 #define socket_error() WSAGetLastError()
-#undef EWOULDBLOCK
-#undef EINTR
-#undef EINPROGRESS
-#define EWOULDBLOCK WSAEWOULDBLOCK
-#define EINTR       WSAEINTR
-#define EINPROGRESS WSAEINPROGRESS
 
 int inet_aton(const char *cp, struct in_addr *ia);
 
diff --git a/slirp/slirp.h b/slirp/slirp.h
index 46bfe46..f2c5eca 100644
--- a/slirp/slirp.h
+++ b/slirp/slirp.h
@@ -15,18 +15,6 @@ typedef char *caddr_t;
 # include <sys/timeb.h>
 # include <iphlpapi.h>
 
-# undef EWOULDBLOCK
-# undef EINPROGRESS
-# undef ENOTCONN
-# undef EHOSTUNREACH
-# undef ENETUNREACH
-# undef ECONNREFUSED
-# define EWOULDBLOCK WSAEWOULDBLOCK
-# define EINPROGRESS WSAEINPROGRESS
-# define ENOTCONN WSAENOTCONN
-# define EHOSTUNREACH WSAEHOSTUNREACH
-# define ENETUNREACH WSAENETUNREACH
-# define ECONNREFUSED WSAECONNREFUSED
 #else
 # define ioctlsocket ioctl
 # define closesocket(s) close(s)
commit 6840981dfb76a1a1d2401efdb237ed5ddac8bf2f
Author: Stefan Weil <sw at weilnetz.de>
Date:   Wed Apr 4 07:45:21 2012 +0200

    w64: Use larger alignment for section with generated code
    
    The MinGW-w64 compiler allows __attribute__((aligned (32)).
    
    Signed-off-by: Stefan Weil <sw at weilnetz.de>

diff --git a/exec.c b/exec.c
index 3dda2ca..6d10595 100644
--- a/exec.c
+++ b/exec.c
@@ -93,8 +93,7 @@ spinlock_t tb_lock = SPIN_LOCK_UNLOCKED;
 #define code_gen_section                                \
     __attribute__((__section__(".gen_code")))           \
     __attribute__((aligned (32)))
-#elif defined(_WIN32)
-/* Maximum alignment for Win32 is 16. */
+#elif defined(_WIN32) && !defined(_WIN64)
 #define code_gen_section                                \
     __attribute__((aligned (16)))
 #else
commit c6d506742fd997a29b611fda11f67c53d60dd5ef
Author: Stefan Weil <sw at weilnetz.de>
Date:   Fri Mar 16 20:23:49 2012 +0100

    w64: Fix data types in cpu-all.h, exec.c
    
    w64 needs uintptr_t instead of unsigned long.
    For other hosts, nothing changes.
    
    Signed-off-by: Stefan Weil <sw at weilnetz.de>

diff --git a/cpu-all.h b/cpu-all.h
index 58420be..f7d6867 100644
--- a/cpu-all.h
+++ b/cpu-all.h
@@ -299,10 +299,10 @@ extern unsigned long reserved_va;
 #define TARGET_PAGE_MASK ~(TARGET_PAGE_SIZE - 1)
 #define TARGET_PAGE_ALIGN(addr) (((addr) + TARGET_PAGE_SIZE - 1) & TARGET_PAGE_MASK)
 
-/* ??? These should be the larger of unsigned long and target_ulong.  */
-extern unsigned long qemu_real_host_page_size;
-extern unsigned long qemu_host_page_size;
-extern unsigned long qemu_host_page_mask;
+/* ??? These should be the larger of uintptr_t and target_ulong.  */
+extern uintptr_t qemu_real_host_page_size;
+extern uintptr_t qemu_host_page_size;
+extern uintptr_t qemu_host_page_mask;
 
 #define HOST_PAGE_ALIGN(addr) (((addr) + qemu_host_page_size - 1) & qemu_host_page_mask)
 
diff --git a/exec.c b/exec.c
index 68b8a6a..3dda2ca 100644
--- a/exec.c
+++ b/exec.c
@@ -177,9 +177,9 @@ typedef struct PageDesc {
 
 #define V_L1_SHIFT (L1_MAP_ADDR_SPACE_BITS - TARGET_PAGE_BITS - V_L1_BITS)
 
-unsigned long qemu_real_host_page_size;
-unsigned long qemu_host_page_size;
-unsigned long qemu_host_page_mask;
+uintptr_t qemu_real_host_page_size;
+uintptr_t qemu_host_page_size;
+uintptr_t qemu_host_page_mask;
 
 /* This is a multi-level map on the virtual address space.
    The bottom level has pointers to PageDesc.  */
commit 27b0dc16b4e50b59aeefff2bfa73cf2eb8c7a70d
Author: Stefan Weil <sw at weilnetz.de>
Date:   Sun Apr 15 15:18:29 2012 +0200

    w64: Fix type casts used in some macros in cpu-all.h
    
    Instead of type casts to long, w64 needs type casts to intptr_t.
    For other hosts, this changes nothing.
    
    Signed-off-by: Stefan Weil <sw at weilnetz.de>

diff --git a/cpu-all.h b/cpu-all.h
index 4512518..58420be 100644
--- a/cpu-all.h
+++ b/cpu-all.h
@@ -222,8 +222,8 @@ extern unsigned long reserved_va;
 #else /* !CONFIG_USER_ONLY */
 /* NOTE: we use double casts if pointers and target_ulong have
    different sizes */
-#define saddr(x) (uint8_t *)(long)(x)
-#define laddr(x) (uint8_t *)(long)(x)
+#define saddr(x) (uint8_t *)(intptr_t)(x)
+#define laddr(x) (uint8_t *)(intptr_t)(x)
 #endif
 
 #define ldub_raw(p) ldub_p(laddr((p)))
commit 8d918718edcd6753aa12be96b71d1bd4fb6ed7cd
Author: Stefan Weil <sw at weilnetz.de>
Date:   Thu Apr 12 20:46:32 2012 +0200

    tcg/i386: Add support for w64 ABI
    
    w64 uses the registers rcx, rdx, r8 and r9 for function arguments,
    so it needs a different declaration of tcg_target_call_iarg_regs.
    
    rax, rcx, rdx, r8, r9, r10 and r11 may be changed by function calls.
    
    rbx, rbp, rdi, rsi, r12, r13, r14 and r15 remain unchanged by function calls.
    
    Reviewed-by: Richard Henderson <rth at twiddle.net>
    Signed-off-by: Stefan Weil <sw at weilnetz.de>

diff --git a/tcg/i386/tcg-target.c b/tcg/i386/tcg-target.c
index 79545e3..da17bba 100644
--- a/tcg/i386/tcg-target.c
+++ b/tcg/i386/tcg-target.c
@@ -63,10 +63,15 @@ static const int tcg_target_reg_alloc_order[] = {
 
 static const int tcg_target_call_iarg_regs[] = {
 #if TCG_TARGET_REG_BITS == 64
+#if defined(_WIN64)
+    TCG_REG_RCX,
+    TCG_REG_RDX,
+#else
     TCG_REG_RDI,
     TCG_REG_RSI,
     TCG_REG_RDX,
     TCG_REG_RCX,
+#endif
     TCG_REG_R8,
     TCG_REG_R9,
 #else
@@ -176,10 +181,10 @@ static int target_parse_constraint(TCGArgConstraint *ct, const char **pct_str)
         ct->ct |= TCG_CT_REG;
         if (TCG_TARGET_REG_BITS == 64) {
             tcg_regset_set32(ct->u.regs, 0, 0xffff);
-            tcg_regset_reset_reg(ct->u.regs, TCG_REG_RSI);
-            tcg_regset_reset_reg(ct->u.regs, TCG_REG_RDI);
+            tcg_regset_reset_reg(ct->u.regs, tcg_target_call_iarg_regs[0]);
+            tcg_regset_reset_reg(ct->u.regs, tcg_target_call_iarg_regs[1]);
 #ifdef CONFIG_TCG_PASS_AREG0
-            tcg_regset_reset_reg(ct->u.regs, TCG_REG_RDX);
+            tcg_regset_reset_reg(ct->u.regs, tcg_target_call_iarg_regs[2]);
 #endif
         } else {
             tcg_regset_set32(ct->u.regs, 0, 0xff);
@@ -1300,9 +1305,12 @@ static void tcg_out_qemu_ld(TCGContext *s, const TCGArg *args,
                use the ADDR32 prefix.  For now, do nothing.  */
 
             if (offset != GUEST_BASE) {
-                tcg_out_movi(s, TCG_TYPE_I64, TCG_REG_RDI, GUEST_BASE);
-                tgen_arithr(s, ARITH_ADD + P_REXW, TCG_REG_RDI, base);
-                base = TCG_REG_RDI, offset = 0;
+                tcg_out_movi(s, TCG_TYPE_I64,
+                             tcg_target_call_iarg_regs[0], GUEST_BASE);
+                tgen_arithr(s, ARITH_ADD + P_REXW,
+                            tcg_target_call_iarg_regs[0], base);
+                base = tcg_target_call_iarg_regs[0];
+                offset = 0;
             }
         }
 
@@ -1434,8 +1442,8 @@ static void tcg_out_qemu_st(TCGContext *s, const TCGArg *args,
 #endif
 #else
     tcg_out_mov(s, (opc == 3 ? TCG_TYPE_I64 : TCG_TYPE_I32),
-                TCG_REG_RSI, data_reg);
-    tcg_out_movi(s, TCG_TYPE_I32, TCG_REG_RDX, mem_index);
+                tcg_target_call_iarg_regs[1], data_reg);
+    tcg_out_movi(s, TCG_TYPE_I32, tcg_target_call_iarg_regs[2], mem_index);
     stack_adjust = 0;
 #ifdef CONFIG_TCG_PASS_AREG0
     /* XXX/FIXME: suboptimal */
@@ -1474,9 +1482,12 @@ static void tcg_out_qemu_st(TCGContext *s, const TCGArg *args,
                use the ADDR32 prefix.  For now, do nothing.  */
 
             if (offset != GUEST_BASE) {
-                tcg_out_movi(s, TCG_TYPE_I64, TCG_REG_RDI, GUEST_BASE);
-                tgen_arithr(s, ARITH_ADD + P_REXW, TCG_REG_RDI, base);
-                base = TCG_REG_RDI, offset = 0;
+                tcg_out_movi(s, TCG_TYPE_I64,
+                             tcg_target_call_iarg_regs[0], GUEST_BASE);
+                tgen_arithr(s, ARITH_ADD + P_REXW,
+                            tcg_target_call_iarg_regs[0], base);
+                base = tcg_target_call_iarg_regs[0];
+                offset = 0;
             }
         }
 
@@ -1977,6 +1988,10 @@ static int tcg_target_callee_save_regs[] = {
 #if TCG_TARGET_REG_BITS == 64
     TCG_REG_RBP,
     TCG_REG_RBX,
+#if defined(_WIN64)
+    TCG_REG_RDI,
+    TCG_REG_RSI,
+#endif
     TCG_REG_R12,
     TCG_REG_R13,
     TCG_REG_R14, /* Currently used for the global env. */
@@ -2064,8 +2079,10 @@ static void tcg_target_init(TCGContext *s)
     tcg_regset_set_reg(tcg_target_call_clobber_regs, TCG_REG_EDX);
     tcg_regset_set_reg(tcg_target_call_clobber_regs, TCG_REG_ECX);
     if (TCG_TARGET_REG_BITS == 64) {
+#if !defined(_WIN64)
         tcg_regset_set_reg(tcg_target_call_clobber_regs, TCG_REG_RDI);
         tcg_regset_set_reg(tcg_target_call_clobber_regs, TCG_REG_RSI);
+#endif
         tcg_regset_set_reg(tcg_target_call_clobber_regs, TCG_REG_R8);
         tcg_regset_set_reg(tcg_target_call_clobber_regs, TCG_REG_R9);
         tcg_regset_set_reg(tcg_target_call_clobber_regs, TCG_REG_R10);
commit c170cb66490aa20bfc8d2c2421481dd9195dbb8b
Author: Stefan Weil <sw at weilnetz.de>
Date:   Fri Apr 6 08:06:41 2012 +0200

    tcg/i386: Use GDB JIT debugging interface only for hosts with ELF
    
    Not all i386 / x86_64 hosts use ELF.
    Ask the compiler whether ELF is used.
    
    On w64, gdb crashes when ELF_HOST_MACHINE is defined.
    
    Cc: Blue Swirl <blauwirbel at gmail.com>
    Acked-by: Richard Henderson <rth at twiddle.net>
    Signed-off-by: Stefan Weil <sw at weilnetz.de>

diff --git a/tcg/i386/tcg-target.c b/tcg/i386/tcg-target.c
index 871a7e7..79545e3 100644
--- a/tcg/i386/tcg-target.c
+++ b/tcg/i386/tcg-target.c
@@ -2102,7 +2102,9 @@ typedef struct {
     DebugFrameFDE fde;
 } DebugFrame;
 
-#if TCG_TARGET_REG_BITS == 64
+#if !defined(__ELF__)
+    /* Host machine without ELF. */
+#elif TCG_TARGET_REG_BITS == 64
 #define ELF_HOST_MACHINE EM_X86_64
 static DebugFrame debug_frame = {
     .cie.len = sizeof(DebugFrameCIE)-4, /* length after .len member */
@@ -2156,6 +2158,7 @@ static DebugFrame debug_frame = {
 };
 #endif
 
+#if defined(ELF_HOST_MACHINE)
 void tcg_register_jit(void *buf, size_t buf_size)
 {
     /* We're expecting a 2 byte uleb128 encoded value.  */
@@ -2166,3 +2169,4 @@ void tcg_register_jit(void *buf, size_t buf_size)
 
     tcg_register_jit_int(buf, buf_size, &debug_frame, sizeof(debug_frame));
 }
+#endif
commit 4d0365165dd831b9f5d305a1480447dd83810a55
Merge: b79b38e... c17491b...
Author: Blue Swirl <blauwirbel at gmail.com>
Date:   Sun Apr 15 18:39:55 2012 +0000

    Merge branch 'ppc-for-upstream' of git://repo.or.cz/qemu/agraf
    
    * 'ppc-for-upstream' of git://repo.or.cz/qemu/agraf:
      pseries: Fix reset of VIO network device
      pseries: Reset vscsi properly
      pseries: Correctly use the device model reset hooks
      pseries: Remove old hcalls hook stub
      pseries: Remove old debug leftovers from spapr_vscsi
      pseries: Fix RTAS based config access
      target-ppc/machine.c: Drop unnecessary ifdefs
      target-ppc: Init dcache and icache size for e500 user mode
      target-ppc: Fix type casts for w64 (uintptr_t)
      target-ppc: QOM'ify CPU reset
      target-ppc: Start QOM'ifying CPU init
      target-ppc: QOM'ify CPU
      target-ppc: Add hooks for handling tcg and kvm limitations
      target-ppc: Drop cpu_ppc_close()
      pseries: Consolidate hack for RTAS display-character usage
      pseries: Remove unused fields from VIOsPAPRBus structure
      pseries: Implement RTAS system-reboot call
      pseries: Fix bug with reset of VIO CRQs
      pseries: Clean up hcall_dprintf() debugging messages
      PPC: Fix TLB invalidation bug within the PPC interrupt handler.

commit c17491b63e198ac48d533f8a9d301d11c5880a36
Author: David Gibson <david at gibson.dropbear.id.au>
Date:   Thu Apr 12 12:44:15 2012 +1000

    pseries: Fix reset of VIO network device
    
    Currently, the PAPR VIO network device does not have a reset handler.  This
    means that after a hard reset, H_REGISTER_LOGICAL_LAN will return an error
    when the new guest boot attempts to initialize the device.
    
    This patch corrects this, adding a suitable reset hook.
    
    Signed-off-by: David Gibson <david at gibson.dropbear.id.au>
    Signed-off-by: Andreas Färber <afaerber at suse.de>

diff --git a/hw/spapr_llan.c b/hw/spapr_llan.c
index 32dce17..e18d2eb 100644
--- a/hw/spapr_llan.c
+++ b/hw/spapr_llan.c
@@ -182,6 +182,15 @@ static NetClientInfo net_spapr_vlan_info = {
     .receive = spapr_vlan_receive,
 };
 
+static void spapr_vlan_reset(VIOsPAPRDevice *sdev)
+{
+    VIOsPAPRVLANDevice *dev = DO_UPCAST(VIOsPAPRVLANDevice, sdev, sdev);
+
+    dev->buf_list = 0;
+    dev->rx_bufs = 0;
+    dev->isopen = 0;
+}
+
 static int spapr_vlan_init(VIOsPAPRDevice *sdev)
 {
     VIOsPAPRVLANDevice *dev = (VIOsPAPRVLANDevice *)sdev;
@@ -335,9 +344,7 @@ static target_ulong h_free_logical_lan(CPUPPCState *env, sPAPREnvironment *spapr
         return H_RESOURCE;
     }
 
-    dev->buf_list = 0;
-    dev->rx_bufs = 0;
-    dev->isopen = 0;
+    spapr_vlan_reset(sdev);
     return H_SUCCESS;
 }
 
@@ -484,6 +491,7 @@ static void spapr_vlan_class_init(ObjectClass *klass, void *data)
     VIOsPAPRDeviceClass *k = VIO_SPAPR_DEVICE_CLASS(klass);
 
     k->init = spapr_vlan_init;
+    k->reset = spapr_vlan_reset;
     k->devnode = spapr_vlan_devnode;
     k->dt_name = "l-lan";
     k->dt_type = "network";
commit 3cabba609de07e06b3dacf4f30403f6e9e293f2c
Author: David Gibson <david at gibson.dropbear.id.au>
Date:   Thu Apr 12 12:44:14 2012 +1000

    pseries: Reset vscsi properly
    
    Currently the PAPR vscsi implementation does not properly clear its table
    of request tags when the system is reset.  This patch adds a reset hook
    to do so.
    
    Signed-off-by: David Gibson <david at gibson.dropbear.id.au>
    Signed-off-by: Andreas Färber <afaerber at suse.de>

diff --git a/hw/spapr_vscsi.c b/hw/spapr_vscsi.c
index 3530a38..538e0b7 100644
--- a/hw/spapr_vscsi.c
+++ b/hw/spapr_vscsi.c
@@ -893,16 +893,20 @@ static const struct SCSIBusInfo vscsi_scsi_info = {
     .cancel = vscsi_request_cancelled
 };
 
-static int spapr_vscsi_init(VIOsPAPRDevice *dev)
+static void spapr_vscsi_reset(VIOsPAPRDevice *dev)
 {
     VSCSIState *s = DO_UPCAST(VSCSIState, vdev, dev);
     int i;
 
-    /* Initialize qemu request tags */
     memset(s->reqs, 0, sizeof(s->reqs));
     for (i = 0; i < VSCSI_REQ_LIMIT; i++) {
         s->reqs[i].qtag = i;
     }
+}
+
+static int spapr_vscsi_init(VIOsPAPRDevice *dev)
+{
+    VSCSIState *s = DO_UPCAST(VSCSIState, vdev, dev);
 
     dev->crq.SendFunc = vscsi_do_crq;
 
@@ -952,6 +956,7 @@ static void spapr_vscsi_class_init(ObjectClass *klass, void *data)
     VIOsPAPRDeviceClass *k = VIO_SPAPR_DEVICE_CLASS(klass);
 
     k->init = spapr_vscsi_init;
+    k->reset = spapr_vscsi_reset;
     k->devnode = spapr_vscsi_devnode;
     k->dt_name = "v-scsi";
     k->dt_type = "vscsi";
commit b1c7f725a3bc5fec87912e907066edd6b80b878c
Author: David Gibson <david at gibson.dropbear.id.au>
Date:   Thu Apr 12 12:44:13 2012 +1000

    pseries: Correctly use the device model reset hooks
    
    Recently we added code to properly clean away VIO CRQs on reset  However,
    this directly uses qemu_register, rather than the existing device model
    reset callbacks.  This patch cleans this up by adding proper use of the
    reset hook to the VIO bus model.  The existing CRQ reset code is converted
    to the new method.
    
    Signed-off-by: David Gibson <david at gibson.dropbear.id.au>
    Signed-off-by: Andreas Färber <afaerber at suse.de>

diff --git a/hw/spapr_vio.c b/hw/spapr_vio.c
index 0bf2c31..fccf48b 100644
--- a/hw/spapr_vio.c
+++ b/hw/spapr_vio.c
@@ -648,13 +648,18 @@ static int spapr_vio_check_reg(VIOsPAPRDevice *sdev)
     return 0;
 }
 
-static void spapr_vio_busdev_reset(void *opaque)
+static void spapr_vio_busdev_reset(DeviceState *qdev)
 {
-    VIOsPAPRDevice *dev = (VIOsPAPRDevice *)opaque;
+    VIOsPAPRDevice *dev = DO_UPCAST(VIOsPAPRDevice, qdev, qdev);
+    VIOsPAPRDeviceClass *pc = VIO_SPAPR_DEVICE_GET_CLASS(dev);
 
     if (dev->crq.qsize) {
         free_crq(dev);
     }
+
+    if (pc->reset) {
+        pc->reset(dev);
+    }
 }
 
 static int spapr_vio_busdev_init(DeviceState *qdev)
@@ -685,8 +690,6 @@ static int spapr_vio_busdev_init(DeviceState *qdev)
 
     rtce_init(dev);
 
-    qemu_register_reset(spapr_vio_busdev_reset, dev);
-
     return pc->init(dev);
 }
 
@@ -776,6 +779,7 @@ static void vio_spapr_device_class_init(ObjectClass *klass, void *data)
 {
     DeviceClass *k = DEVICE_CLASS(klass);
     k->init = spapr_vio_busdev_init;
+    k->reset = spapr_vio_busdev_reset;
     k->bus_info = &spapr_vio_bus_info;
 }
 
diff --git a/hw/spapr_vio.h b/hw/spapr_vio.h
index 626d04f..10ab359 100644
--- a/hw/spapr_vio.h
+++ b/hw/spapr_vio.h
@@ -64,6 +64,7 @@ typedef struct VIOsPAPRDeviceClass {
     const char *dt_name, *dt_type, *dt_compatible;
     target_ulong signal_mask;
     int (*init)(VIOsPAPRDevice *dev);
+    void (*reset)(VIOsPAPRDevice *dev);
     int (*devnode)(VIOsPAPRDevice *dev, void *fdt, int node_off);
 } VIOsPAPRDeviceClass;
 
commit 91067bf8689ad4a4489a5080812619a9eb932716
Author: David Gibson <david at gibson.dropbear.id.au>
Date:   Thu Apr 12 12:44:12 2012 +1000

    pseries: Remove old hcalls hook stub
    
    Some time ago we removed all use of the 'hcalls' callback in the pseries
    VIO code, which was used to workaround an ordering problem which has since
    been solved properly.  However, the function pointer for the hook remains.
    This patch cleans it away.
    
    Signed-off-by: David Gibson <david at gibson.dropbear.id.au>
    Signed-off-by: Andreas Färber <afaerber at suse.de>

diff --git a/hw/spapr_vio.h b/hw/spapr_vio.h
index fd29c5e..626d04f 100644
--- a/hw/spapr_vio.h
+++ b/hw/spapr_vio.h
@@ -64,7 +64,6 @@ typedef struct VIOsPAPRDeviceClass {
     const char *dt_name, *dt_type, *dt_compatible;
     target_ulong signal_mask;
     int (*init)(VIOsPAPRDevice *dev);
-    void (*hcalls)(VIOsPAPRBus *bus);
     int (*devnode)(VIOsPAPRDevice *dev, void *fdt, int node_off);
 } VIOsPAPRDeviceClass;
 
commit e2d9154dfab73c36ead3cd368e7bc702dfb2ab68
Author: David Gibson <david at gibson.dropbear.id.au>
Date:   Thu Apr 12 12:44:11 2012 +1000

    pseries: Remove old debug leftovers from spapr_vscsi
    
    The PAPR VSCSI emulation contains a few lines of code which were once used
    for debug but now do nothing at all.  This patch removes them.
    
    Signed-off-by: David Gibson <david at gibson.dropbear.id.au>
    Signed-off-by: Andreas Färber <afaerber at suse.de>

diff --git a/hw/spapr_vscsi.c b/hw/spapr_vscsi.c
index 2167017..3530a38 100644
--- a/hw/spapr_vscsi.c
+++ b/hw/spapr_vscsi.c
@@ -99,10 +99,6 @@ typedef struct {
     vscsi_req reqs[VSCSI_REQ_LIMIT];
 } VSCSIState;
 
-/* XXX Debug only */
-static VSCSIState *dbg_vscsi_state;
-
-
 static struct vscsi_req *vscsi_get_req(VSCSIState *s)
 {
     vscsi_req *req;
@@ -902,8 +898,6 @@ static int spapr_vscsi_init(VIOsPAPRDevice *dev)
     VSCSIState *s = DO_UPCAST(VSCSIState, vdev, dev);
     int i;
 
-    dbg_vscsi_state = s;
-
     /* Initialize qemu request tags */
     memset(s->reqs, 0, sizeof(s->reqs));
     for (i = 0; i < VSCSI_REQ_LIMIT; i++) {
commit 92615a5ab96cd2b4981e2aaef40bece6cd7553b6
Author: David Gibson <david at gibson.dropbear.id.au>
Date:   Mon Apr 2 14:17:35 2012 +1000

    pseries: Fix RTAS based config access
    
    On the pseries platform, access to PCI config space is via RTAS calls(
    which go to the hypervisor) rather than MMIO.  This means we don't use
    the same code path as nearly everyone else which goes through pci_host.c
    and we're missing some of the parameter checking along the way.
    
    We do have some parameter checking in the RTAS calls, but it's not enough.
    It checks for overruns, but does not check for unaligned accesses,
    oversized accesses (which means the guest could trigger an assertion
    failure from pci_host_config_{read,write}_common().  Worse it doesn't do
    the basic checking for the number of RTAS arguments and results before
    accessing them.
    
    This patch fixes these bugs.
    
    Cc: Michael S. Tsirkin <mst at redhat.com>
    
    Signed-off-by: David Gibson <david at gibson.dropbear.id.au>
    [AF: Fix typos spotted by mst]
    Signed-off-by: Andreas Färber <afaerber at suse.de>

diff --git a/hw/spapr_pci.c b/hw/spapr_pci.c
index e7ef551..a564c00 100644
--- a/hw/spapr_pci.c
+++ b/hw/spapr_pci.c
@@ -57,26 +57,38 @@ static PCIDevice *find_dev(sPAPREnvironment *spapr,
 
 static uint32_t rtas_pci_cfgaddr(uint32_t arg)
 {
+    /* This handles the encoding of extended config space addresses */
     return ((arg >> 20) & 0xf00) | (arg & 0xff);
 }
 
-static uint32_t rtas_read_pci_config_do(PCIDevice *pci_dev, uint32_t addr,
-                                        uint32_t limit, uint32_t len)
+static void finish_read_pci_config(sPAPREnvironment *spapr, uint64_t buid,
+                                   uint32_t addr, uint32_t size,
+                                   target_ulong rets)
 {
-    if ((addr + len) <= limit) {
-        return pci_host_config_read_common(pci_dev, addr, limit, len);
-    } else {
-        return ~0x0;
+    PCIDevice *pci_dev;
+    uint32_t val;
+
+    if ((size != 1) && (size != 2) && (size != 4)) {
+        /* access must be 1, 2 or 4 bytes */
+        rtas_st(rets, 0, -1);
+        return;
     }
-}
 
-static void rtas_write_pci_config_do(PCIDevice *pci_dev, uint32_t addr,
-                                     uint32_t limit, uint32_t val,
-                                     uint32_t len)
-{
-    if ((addr + len) <= limit) {
-        pci_host_config_write_common(pci_dev, addr, limit, val, len);
+    pci_dev = find_dev(spapr, buid, addr);
+    addr = rtas_pci_cfgaddr(addr);
+
+    if (!pci_dev || (addr % size) || (addr >= pci_config_size(pci_dev))) {
+        /* Access must be to a valid device, within bounds and
+         * naturally aligned */
+        rtas_st(rets, 0, -1);
+        return;
     }
+
+    val = pci_host_config_read_common(pci_dev, addr,
+                                      pci_config_size(pci_dev), size);
+
+    rtas_st(rets, 0, 0);
+    rtas_st(rets, 1, val);
 }
 
 static void rtas_ibm_read_pci_config(sPAPREnvironment *spapr,
@@ -84,19 +96,19 @@ static void rtas_ibm_read_pci_config(sPAPREnvironment *spapr,
                                      target_ulong args,
                                      uint32_t nret, target_ulong rets)
 {
-    uint32_t val, size, addr;
-    uint64_t buid = ((uint64_t)rtas_ld(args, 1) << 32) | rtas_ld(args, 2);
-    PCIDevice *dev = find_dev(spapr, buid, rtas_ld(args, 0));
+    uint64_t buid;
+    uint32_t size, addr;
 
-    if (!dev) {
+    if ((nargs != 4) || (nret != 2)) {
         rtas_st(rets, 0, -1);
         return;
     }
+
+    buid = ((uint64_t)rtas_ld(args, 1) << 32) | rtas_ld(args, 2);
     size = rtas_ld(args, 3);
-    addr = rtas_pci_cfgaddr(rtas_ld(args, 0));
-    val = rtas_read_pci_config_do(dev, addr, pci_config_size(dev), size);
-    rtas_st(rets, 0, 0);
-    rtas_st(rets, 1, val);
+    addr = rtas_ld(args, 0);
+
+    finish_read_pci_config(spapr, buid, addr, size, rets);
 }
 
 static void rtas_read_pci_config(sPAPREnvironment *spapr,
@@ -104,18 +116,45 @@ static void rtas_read_pci_config(sPAPREnvironment *spapr,
                                  target_ulong args,
                                  uint32_t nret, target_ulong rets)
 {
-    uint32_t val, size, addr;
-    PCIDevice *dev = find_dev(spapr, 0, rtas_ld(args, 0));
+    uint32_t size, addr;
 
-    if (!dev) {
+    if ((nargs != 2) || (nret != 2)) {
         rtas_st(rets, 0, -1);
         return;
     }
+
     size = rtas_ld(args, 1);
-    addr = rtas_pci_cfgaddr(rtas_ld(args, 0));
-    val = rtas_read_pci_config_do(dev, addr, pci_config_size(dev), size);
+    addr = rtas_ld(args, 0);
+
+    finish_read_pci_config(spapr, 0, addr, size, rets);
+}
+
+static void finish_write_pci_config(sPAPREnvironment *spapr, uint64_t buid,
+                                    uint32_t addr, uint32_t size,
+                                    uint32_t val, target_ulong rets)
+{
+    PCIDevice *pci_dev;
+
+    if ((size != 1) && (size != 2) && (size != 4)) {
+        /* access must be 1, 2 or 4 bytes */
+        rtas_st(rets, 0, -1);
+        return;
+    }
+
+    pci_dev = find_dev(spapr, buid, addr);
+    addr = rtas_pci_cfgaddr(addr);
+
+    if (!pci_dev || (addr % size) || (addr >= pci_config_size(pci_dev))) {
+        /* Access must be to a valid device, within bounds and
+         * naturally aligned */
+        rtas_st(rets, 0, -1);
+        return;
+    }
+
+    pci_host_config_write_common(pci_dev, addr, pci_config_size(pci_dev),
+                                 val, size);
+
     rtas_st(rets, 0, 0);
-    rtas_st(rets, 1, val);
 }
 
 static void rtas_ibm_write_pci_config(sPAPREnvironment *spapr,
@@ -123,19 +162,20 @@ static void rtas_ibm_write_pci_config(sPAPREnvironment *spapr,
                                       target_ulong args,
                                       uint32_t nret, target_ulong rets)
 {
+    uint64_t buid;
     uint32_t val, size, addr;
-    uint64_t buid = ((uint64_t)rtas_ld(args, 1) << 32) | rtas_ld(args, 2);
-    PCIDevice *dev = find_dev(spapr, buid, rtas_ld(args, 0));
 
-    if (!dev) {
+    if ((nargs != 5) || (nret != 1)) {
         rtas_st(rets, 0, -1);
         return;
     }
+
+    buid = ((uint64_t)rtas_ld(args, 1) << 32) | rtas_ld(args, 2);
     val = rtas_ld(args, 4);
     size = rtas_ld(args, 3);
-    addr = rtas_pci_cfgaddr(rtas_ld(args, 0));
-    rtas_write_pci_config_do(dev, addr, pci_config_size(dev), val, size);
-    rtas_st(rets, 0, 0);
+    addr = rtas_ld(args, 0);
+
+    finish_write_pci_config(spapr, buid, addr, size, val, rets);
 }
 
 static void rtas_write_pci_config(sPAPREnvironment *spapr,
@@ -144,17 +184,18 @@ static void rtas_write_pci_config(sPAPREnvironment *spapr,
                                   uint32_t nret, target_ulong rets)
 {
     uint32_t val, size, addr;
-    PCIDevice *dev = find_dev(spapr, 0, rtas_ld(args, 0));
 
-    if (!dev) {
+    if ((nargs != 3) || (nret != 1)) {
         rtas_st(rets, 0, -1);
         return;
     }
+
+
     val = rtas_ld(args, 2);
     size = rtas_ld(args, 1);
-    addr = rtas_pci_cfgaddr(rtas_ld(args, 0));
-    rtas_write_pci_config_do(dev, addr, pci_config_size(dev), val, size);
-    rtas_st(rets, 0, 0);
+    addr = rtas_ld(args, 0);
+
+    finish_write_pci_config(spapr, 0, addr, size, val, rets);
 }
 
 static int pci_spapr_map_irq(PCIDevice *pci_dev, int irq_num)
commit b79b38e4b3199984a6ad0ead5be2431c8e804eaa
Author: Max Filippov <jcmvbkbc at gmail.com>
Date:   Sun Apr 15 19:12:18 2012 +0400

    target-xtensa: add license to core-fsf.c
    
    Signed-off-by: Max Filippov <jcmvbkbc at gmail.com>
    Reviewed-by: Andreas Färber <afaerber at suse.de>
    Signed-off-by: Blue Swirl <blauwirbel at gmail.com>

diff --git a/target-xtensa/core-fsf.c b/target-xtensa/core-fsf.c
index c11d970..e36b0de 100644
--- a/target-xtensa/core-fsf.c
+++ b/target-xtensa/core-fsf.c
@@ -1,3 +1,30 @@
+/*
+ * Copyright (c) 2011, Max Filippov, Open Source and Linux Lab.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *     * Redistributions of source code must retain the above copyright
+ *       notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above copyright
+ *       notice, this list of conditions and the following disclaimer in the
+ *       documentation and/or other materials provided with the distribution.
+ *     * Neither the name of the Open Source and Linux Lab nor the
+ *       names of its contributors may be used to endorse or promote products
+ *       derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
 #include "cpu.h"
 #include "exec-all.h"
 #include "gdbstub.h"
commit fbaa9fb5cbfad74e7df1230acf4b7f5cb4a9f089
Author: Max Filippov <jcmvbkbc at gmail.com>
Date:   Sun Apr 15 19:12:17 2012 +0400

    target-xtensa: add license to core-dc232b.c
    
    Signed-off-by: Max Filippov <jcmvbkbc at gmail.com>
    Reviewed-by: Andreas Färber <afaerber at suse.de>
    Signed-off-by: Blue Swirl <blauwirbel at gmail.com>

diff --git a/target-xtensa/core-dc232b.c b/target-xtensa/core-dc232b.c
index 7c03835..804fdef 100644
--- a/target-xtensa/core-dc232b.c
+++ b/target-xtensa/core-dc232b.c
@@ -1,3 +1,30 @@
+/*
+ * Copyright (c) 2011, Max Filippov, Open Source and Linux Lab.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *     * Redistributions of source code must retain the above copyright
+ *       notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above copyright
+ *       notice, this list of conditions and the following disclaimer in the
+ *       documentation and/or other materials provided with the distribution.
+ *     * Neither the name of the Open Source and Linux Lab nor the
+ *       names of its contributors may be used to endorse or promote products
+ *       derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
 #include "cpu.h"
 #include "exec-all.h"
 #include "gdbstub.h"
commit 176ac95ed19f7728985d3d904671732a54eb42e7
Author: Max Filippov <jcmvbkbc at gmail.com>
Date:   Sun Apr 15 19:12:16 2012 +0400

    target-xtensa: add dc233c core
    
    This is Diamond 233L Standard Core Rev.C (LE), implemented through
    linux/gdb overlay.
    
    Signed-off-by: Max Filippov <jcmvbkbc at gmail.com>
    Reviewed-by: Andreas Färber <afaerber at suse.de>
    Signed-off-by: Blue Swirl <blauwirbel at gmail.com>

diff --git a/Makefile.target b/Makefile.target
index 65fb8f0..3ab791a 100644
--- a/Makefile.target
+++ b/Makefile.target
@@ -416,6 +416,7 @@ obj-xtensa-y += xtensa_sim.o
 obj-xtensa-y += xtensa_lx60.o
 obj-xtensa-y += xtensa-semi.o
 obj-xtensa-y += core-dc232b.o
+obj-xtensa-y += core-dc233c.o
 obj-xtensa-y += core-fsf.o
 
 main.o: QEMU_CFLAGS+=$(GPROF_CFLAGS)
diff --git a/target-xtensa/core-dc233c.c b/target-xtensa/core-dc233c.c
new file mode 100644
index 0000000..d643f41
--- /dev/null
+++ b/target-xtensa/core-dc233c.c
@@ -0,0 +1,55 @@
+/*
+ * Copyright (c) 2012, Max Filippov, Open Source and Linux Lab.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *     * Redistributions of source code must retain the above copyright
+ *       notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above copyright
+ *       notice, this list of conditions and the following disclaimer in the
+ *       documentation and/or other materials provided with the distribution.
+ *     * Neither the name of the Open Source and Linux Lab nor the
+ *       names of its contributors may be used to endorse or promote products
+ *       derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "cpu.h"
+#include "exec-all.h"
+#include "gdbstub.h"
+#include "qemu-common.h"
+#include "host-utils.h"
+
+#include "core-dc233c/core-isa.h"
+#include "overlay_tool.h"
+
+static const XtensaConfig dc233c = {
+    .name = "dc233c",
+    .options = XTENSA_OPTIONS,
+    .gdb_regmap = {
+        .num_regs = 121,
+        .num_core_regs = 52,
+        .reg = {
+#include "core-dc233c/gdb-config.c"
+        }
+    },
+    .nareg = XCHAL_NUM_AREGS,
+    .ndepc = 1,
+    EXCEPTIONS_SECTION,
+    INTERRUPTS_SECTION,
+    TLB_SECTION,
+    .clock_freq_khz = 10000,
+};
+
+REGISTER_CORE(dc233c)
diff --git a/target-xtensa/core-dc233c/core-isa.h b/target-xtensa/core-dc233c/core-isa.h
new file mode 100644
index 0000000..e82c3cb
--- /dev/null
+++ b/target-xtensa/core-dc233c/core-isa.h
@@ -0,0 +1,474 @@
+/*
+ * xtensa/config/core-isa.h -- HAL definitions that are dependent on Xtensa
+ *                              processor CORE configuration
+ *
+ *  See <xtensa/config/core.h>, which includes this file, for more details.
+ */
+
+/* Xtensa processor core configuration information.
+
+   Copyright (c) 1999-2010 Tensilica Inc.
+
+   Permission is hereby granted, free of charge, to any person obtaining
+   a copy of this software and associated documentation files (the
+   "Software"), to deal in the Software without restriction, including
+   without limitation the rights to use, copy, modify, merge, publish,
+   distribute, sublicense, and/or sell copies of the Software, and to
+   permit persons to whom the Software is furnished to do so, subject to
+   the following conditions:
+
+   The above copyright notice and this permission notice shall be included
+   in all copies or substantial portions of the Software.
+
+   THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+   EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+   MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+   IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
+   CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+   TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+   SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.  */
+
+#ifndef _XTENSA_CORE_CONFIGURATION_H
+#define _XTENSA_CORE_CONFIGURATION_H
+
+
+/****************************************************************************
+            Parameters Useful for Any Code, USER or PRIVILEGED
+ ****************************************************************************/
+
+/*
+ *  Note:  Macros of the form XCHAL_HAVE_*** have a value of 1 if the option is
+ *  configured, and a value of 0 otherwise.  These macros are always defined.
+ */
+
+
+/*----------------------------------------------------------------------
+                                ISA
+  ----------------------------------------------------------------------*/
+
+#define XCHAL_HAVE_BE                   0       /* big-endian byte ordering */
+#define XCHAL_HAVE_WINDOWED             1       /* windowed registers option */
+#define XCHAL_NUM_AREGS                 32      /* num of physical addr regs */
+#define XCHAL_NUM_AREGS_LOG2            5       /* log2(XCHAL_NUM_AREGS) */
+#define XCHAL_MAX_INSTRUCTION_SIZE      3       /* max instr bytes (3..8) */
+#define XCHAL_HAVE_DEBUG                1       /* debug option */
+#define XCHAL_HAVE_DENSITY              1       /* 16-bit instructions */
+#define XCHAL_HAVE_LOOPS                1       /* zero-overhead loops */
+#define XCHAL_HAVE_NSA                  1       /* NSA/NSAU instructions */
+#define XCHAL_HAVE_MINMAX               1       /* MIN/MAX instructions */
+#define XCHAL_HAVE_SEXT                 1       /* SEXT instruction */
+#define XCHAL_HAVE_CLAMPS               1       /* CLAMPS instruction */
+#define XCHAL_HAVE_MUL16                1       /* MUL16S/MUL16U instructions */
+#define XCHAL_HAVE_MUL32                1       /* MULL instruction */
+#define XCHAL_HAVE_MUL32_HIGH           0       /* MULUH/MULSH instructions */
+#define XCHAL_HAVE_DIV32                1       /* QUOS/QUOU/REMS/REMU instructions */
+#define XCHAL_HAVE_L32R                 1       /* L32R instruction */
+#define XCHAL_HAVE_ABSOLUTE_LITERALS    1       /* non-PC-rel (extended) L32R */
+#define XCHAL_HAVE_CONST16              0       /* CONST16 instruction */
+#define XCHAL_HAVE_ADDX                 1       /* ADDX#/SUBX# instructions */
+#define XCHAL_HAVE_WIDE_BRANCHES        0       /* B*.W18 or B*.W15 instr's */
+#define XCHAL_HAVE_PREDICTED_BRANCHES   0       /* B[EQ/EQZ/NE/NEZ]T instr's */
+#define XCHAL_HAVE_CALL4AND12           1       /* (obsolete option) */
+#define XCHAL_HAVE_ABS                  1       /* ABS instruction */
+/*#define XCHAL_HAVE_POPC               0*/     /* POPC instruction */
+/*#define XCHAL_HAVE_CRC                0*/     /* CRC instruction */
+#define XCHAL_HAVE_RELEASE_SYNC         1       /* L32AI/S32RI instructions */
+#define XCHAL_HAVE_S32C1I               1       /* S32C1I instruction */
+#define XCHAL_HAVE_SPECULATION          0       /* speculation */
+#define XCHAL_HAVE_FULL_RESET           1       /* all regs/state reset */
+#define XCHAL_NUM_CONTEXTS              1       /* */
+#define XCHAL_NUM_MISC_REGS             2       /* num of scratch regs (0..4) */
+#define XCHAL_HAVE_TAP_MASTER           0       /* JTAG TAP control instr's */
+#define XCHAL_HAVE_PRID                 1       /* processor ID register */
+#define XCHAL_HAVE_EXTERN_REGS          1       /* WER/RER instructions */
+#define XCHAL_HAVE_MP_INTERRUPTS        0       /* interrupt distributor port */
+#define XCHAL_HAVE_MP_RUNSTALL          0       /* core RunStall control port */
+#define XCHAL_HAVE_THREADPTR            1       /* THREADPTR register */
+#define XCHAL_HAVE_BOOLEANS             0       /* boolean registers */
+#define XCHAL_HAVE_CP                   1       /* CPENABLE reg (coprocessor) */
+#define XCHAL_CP_MAXCFG                 8       /* max allowed cp id plus one */
+#define XCHAL_HAVE_MAC16                1       /* MAC16 package */
+#define XCHAL_HAVE_VECTORFPU2005        0       /* vector floating-point pkg */
+#define XCHAL_HAVE_FP                   0       /* floating point pkg */
+#define XCHAL_HAVE_DFP                  0       /* double precision FP pkg */
+#define XCHAL_HAVE_DFP_accel            0       /* double precision FP acceleration pkg */
+#define XCHAL_HAVE_VECTRA1              0       /* Vectra I  pkg */
+#define XCHAL_HAVE_VECTRALX             0       /* Vectra LX pkg */
+#define XCHAL_HAVE_HIFIPRO              0       /* HiFiPro Audio Engine pkg */
+#define XCHAL_HAVE_HIFI2                0       /* HiFi2 Audio Engine pkg */
+#define XCHAL_HAVE_HIFI2EP      0       /* HiFi2EP */
+#define XCHAL_HAVE_CONNXD2              0       /* ConnX D2 pkg */
+#define XCHAL_HAVE_BBE16                0       /* ConnX BBE16 pkg */
+#define XCHAL_HAVE_BBE16_RSQRT          0       /* BBE16 & vector recip sqrt */
+#define XCHAL_HAVE_BBE16_VECDIV         0       /* BBE16 & vector divide */
+#define XCHAL_HAVE_BBE16_DESPREAD       0       /* BBE16 & despread */
+#define XCHAL_HAVE_BSP3                 0       /* ConnX BSP3 pkg */
+#define XCHAL_HAVE_SSP16                0       /* ConnX SSP16 pkg */
+#define XCHAL_HAVE_SSP16_VITERBI        0       /* SSP16 & viterbi */
+#define XCHAL_HAVE_TURBO16              0       /* ConnX Turbo16 pkg */
+#define XCHAL_HAVE_BBP16                0       /* ConnX BBP16 pkg */
+
+
+/*----------------------------------------------------------------------
+                                MISC
+  ----------------------------------------------------------------------*/
+
+#define XCHAL_NUM_WRITEBUFFER_ENTRIES   8       /* size of write buffer */
+#define XCHAL_INST_FETCH_WIDTH          4       /* instr-fetch width in bytes */
+#define XCHAL_DATA_WIDTH                4       /* data width in bytes */
+/*  In T1050, applies to selected core load and store instructions (see ISA): */
+#define XCHAL_UNALIGNED_LOAD_EXCEPTION  1       /* unaligned loads cause exc. */
+#define XCHAL_UNALIGNED_STORE_EXCEPTION 1       /* unaligned stores cause exc.*/
+#define XCHAL_UNALIGNED_LOAD_HW         0       /* unaligned loads work in hw */
+#define XCHAL_UNALIGNED_STORE_HW        0       /* unaligned stores work in hw*/
+
+#define XCHAL_SW_VERSION                900001  /* sw version of this header */
+
+#define XCHAL_CORE_ID                   "dc233c"        /* alphanum core name
+(CoreID) set in the Xtensa
+Processor Generator */
+
+#define XCHAL_CORE_DESCRIPTION          "dc233c"
+#define XCHAL_BUILD_UNIQUE_ID           0x00004B21      /* 22-bit sw build ID */
+
+/*
+ *  These definitions describe the hardware targeted by this software.
+ */
+#define XCHAL_HW_CONFIGID0              0xC56707FE      /* ConfigID hi 32 bits*/
+#define XCHAL_HW_CONFIGID1              0x14404B21      /* ConfigID lo 32 bits*/
+#define XCHAL_HW_VERSION_NAME           "LX4.0.1"       /* full version name */
+#define XCHAL_HW_VERSION_MAJOR          2400    /* major ver# of targeted hw */
+#define XCHAL_HW_VERSION_MINOR          1       /* minor ver# of targeted hw */
+#define XCHAL_HW_VERSION                240001  /* major*100+minor */
+#define XCHAL_HW_REL_LX4                1
+#define XCHAL_HW_REL_LX4_0              1
+#define XCHAL_HW_REL_LX4_0_1            1
+#define XCHAL_HW_CONFIGID_RELIABLE      1
+/*  If software targets a *range* of hardware versions, these are the bounds: */
+#define XCHAL_HW_MIN_VERSION_MAJOR      2400    /* major v of earliest tgt hw */
+#define XCHAL_HW_MIN_VERSION_MINOR      1       /* minor v of earliest tgt hw */
+#define XCHAL_HW_MIN_VERSION            240001  /* earliest targeted hw */
+#define XCHAL_HW_MAX_VERSION_MAJOR      2400    /* major v of latest tgt hw */
+#define XCHAL_HW_MAX_VERSION_MINOR      1       /* minor v of latest tgt hw */
+#define XCHAL_HW_MAX_VERSION            240001  /* latest targeted hw */
+
+
+/*----------------------------------------------------------------------
+                                CACHE
+  ----------------------------------------------------------------------*/
+
+#define XCHAL_ICACHE_LINESIZE           32      /* I-cache line size in bytes */
+#define XCHAL_DCACHE_LINESIZE           32      /* D-cache line size in bytes */
+#define XCHAL_ICACHE_LINEWIDTH          5       /* log2(I line size in bytes) */
+#define XCHAL_DCACHE_LINEWIDTH          5       /* log2(D line size in bytes) */
+
+#define XCHAL_ICACHE_SIZE               16384   /* I-cache size in bytes or 0 */
+#define XCHAL_DCACHE_SIZE               16384   /* D-cache size in bytes or 0 */
+
+#define XCHAL_DCACHE_IS_WRITEBACK       1       /* writeback feature */
+#define XCHAL_DCACHE_IS_COHERENT        0       /* MP coherence feature */
+
+#define XCHAL_HAVE_PREFETCH             0       /* PREFCTL register */
+
+
+
+
+/****************************************************************************
+    Parameters Useful for PRIVILEGED (Supervisory or Non-Virtualized) Code
+ ****************************************************************************/
+
+
+#ifndef XTENSA_HAL_NON_PRIVILEGED_ONLY
+
+/*----------------------------------------------------------------------
+                                CACHE
+  ----------------------------------------------------------------------*/
+
+#define XCHAL_HAVE_PIF                  1       /* any outbound PIF present */
+
+/*  If present, cache size in bytes == (ways * 2^(linewidth + setwidth)).  */
+
+/*  Number of cache sets in log2(lines per way):  */
+#define XCHAL_ICACHE_SETWIDTH           7
+#define XCHAL_DCACHE_SETWIDTH           7
+
+/*  Cache set associativity (number of ways):  */
+#define XCHAL_ICACHE_WAYS               4
+#define XCHAL_DCACHE_WAYS               4
+
+/*  Cache features:  */
+#define XCHAL_ICACHE_LINE_LOCKABLE      1
+#define XCHAL_DCACHE_LINE_LOCKABLE      1
+#define XCHAL_ICACHE_ECC_PARITY         0
+#define XCHAL_DCACHE_ECC_PARITY         0
+
+/*  Cache access size in bytes (affects operation of SICW instruction):  */
+#define XCHAL_ICACHE_ACCESS_SIZE        4
+#define XCHAL_DCACHE_ACCESS_SIZE        4
+
+/*  Number of encoded cache attr bits (see <xtensa/hal.h> for decoded bits):  */
+#define XCHAL_CA_BITS                   4
+
+
+/*----------------------------------------------------------------------
+                        INTERNAL I/D RAM/ROMs and XLMI
+  ----------------------------------------------------------------------*/
+
+#define XCHAL_NUM_INSTROM               0       /* number of core instr. ROMs */
+#define XCHAL_NUM_INSTRAM               0       /* number of core instr. RAMs */
+#define XCHAL_NUM_DATAROM               0       /* number of core data ROMs */
+#define XCHAL_NUM_DATARAM               0       /* number of core data RAMs */
+#define XCHAL_NUM_URAM                  0       /* number of core unified RAMs*/
+#define XCHAL_NUM_XLMI                  0       /* number of core XLMI ports */
+
+#define XCHAL_HAVE_IMEM_LOADSTORE       1       /* can load/store to IROM/IRAM*/
+
+
+/*----------------------------------------------------------------------
+                        INTERRUPTS and TIMERS
+  ----------------------------------------------------------------------*/
+
+#define XCHAL_HAVE_INTERRUPTS           1       /* interrupt option */
+#define XCHAL_HAVE_HIGHPRI_INTERRUPTS   1       /* med/high-pri. interrupts */
+#define XCHAL_HAVE_NMI                  1       /* non-maskable interrupt */
+#define XCHAL_HAVE_CCOUNT               1       /* CCOUNT reg. (timer option) */
+#define XCHAL_NUM_TIMERS                3       /* number of CCOMPAREn regs */
+#define XCHAL_NUM_INTERRUPTS            22      /* number of interrupts */
+#define XCHAL_NUM_INTERRUPTS_LOG2       5       /* ceil(log2(NUM_INTERRUPTS)) */
+#define XCHAL_NUM_EXTINTERRUPTS         17      /* num of external interrupts */
+#define XCHAL_NUM_INTLEVELS             6       /* number of interrupt levels
+(not including level zero) */
+#define XCHAL_EXCM_LEVEL                3       /* level masked by PS.EXCM */
+/* (always 1 in XEA1; levels 2 .. EXCM_LEVEL are "medium priority") */
+
+/*  Masks of interrupts at each interrupt level:  */
+#define XCHAL_INTLEVEL1_MASK            0x001F80FF
+#define XCHAL_INTLEVEL2_MASK            0x00000100
+#define XCHAL_INTLEVEL3_MASK            0x00200E00
+#define XCHAL_INTLEVEL4_MASK            0x00001000
+#define XCHAL_INTLEVEL5_MASK            0x00002000
+#define XCHAL_INTLEVEL6_MASK            0x00000000
+#define XCHAL_INTLEVEL7_MASK            0x00004000
+
+/*  Masks of interrupts at each range 1..n of interrupt levels:  */
+#define XCHAL_INTLEVEL1_ANDBELOW_MASK   0x001F80FF
+#define XCHAL_INTLEVEL2_ANDBELOW_MASK   0x001F81FF
+#define XCHAL_INTLEVEL3_ANDBELOW_MASK   0x003F8FFF
+#define XCHAL_INTLEVEL4_ANDBELOW_MASK   0x003F9FFF
+#define XCHAL_INTLEVEL5_ANDBELOW_MASK   0x003FBFFF
+#define XCHAL_INTLEVEL6_ANDBELOW_MASK   0x003FBFFF
+#define XCHAL_INTLEVEL7_ANDBELOW_MASK   0x003FFFFF
+
+/*  Level of each interrupt:  */
+#define XCHAL_INT0_LEVEL                1
+#define XCHAL_INT1_LEVEL                1
+#define XCHAL_INT2_LEVEL                1
+#define XCHAL_INT3_LEVEL                1
+#define XCHAL_INT4_LEVEL                1
+#define XCHAL_INT5_LEVEL                1
+#define XCHAL_INT6_LEVEL                1
+#define XCHAL_INT7_LEVEL                1
+#define XCHAL_INT8_LEVEL                2
+#define XCHAL_INT9_LEVEL                3
+#define XCHAL_INT10_LEVEL               3
+#define XCHAL_INT11_LEVEL               3
+#define XCHAL_INT12_LEVEL               4
+#define XCHAL_INT13_LEVEL               5
+#define XCHAL_INT14_LEVEL               7
+#define XCHAL_INT15_LEVEL               1
+#define XCHAL_INT16_LEVEL               1
+#define XCHAL_INT17_LEVEL               1
+#define XCHAL_INT18_LEVEL               1
+#define XCHAL_INT19_LEVEL               1
+#define XCHAL_INT20_LEVEL               1
+#define XCHAL_INT21_LEVEL               3
+#define XCHAL_DEBUGLEVEL                6       /* debug interrupt level */
+#define XCHAL_HAVE_DEBUG_EXTERN_INT     1       /* OCD external db interrupt */
+#define XCHAL_NMILEVEL                  7       /* NMI "level" (for use with
+EXCSAVE/EPS/EPC_n, RFI n) */
+
+/*  Type of each interrupt:  */
+#define XCHAL_INT0_TYPE         XTHAL_INTTYPE_EXTERN_LEVEL
+#define XCHAL_INT1_TYPE         XTHAL_INTTYPE_EXTERN_LEVEL
+#define XCHAL_INT2_TYPE         XTHAL_INTTYPE_EXTERN_LEVEL
+#define XCHAL_INT3_TYPE         XTHAL_INTTYPE_EXTERN_LEVEL
+#define XCHAL_INT4_TYPE         XTHAL_INTTYPE_EXTERN_LEVEL
+#define XCHAL_INT5_TYPE         XTHAL_INTTYPE_EXTERN_LEVEL
+#define XCHAL_INT6_TYPE         XTHAL_INTTYPE_TIMER
+#define XCHAL_INT7_TYPE         XTHAL_INTTYPE_SOFTWARE
+#define XCHAL_INT8_TYPE         XTHAL_INTTYPE_EXTERN_LEVEL
+#define XCHAL_INT9_TYPE         XTHAL_INTTYPE_EXTERN_LEVEL
+#define XCHAL_INT10_TYPE        XTHAL_INTTYPE_TIMER
+#define XCHAL_INT11_TYPE        XTHAL_INTTYPE_SOFTWARE
+#define XCHAL_INT12_TYPE        XTHAL_INTTYPE_EXTERN_LEVEL
+#define XCHAL_INT13_TYPE        XTHAL_INTTYPE_TIMER
+#define XCHAL_INT14_TYPE        XTHAL_INTTYPE_NMI
+#define XCHAL_INT15_TYPE        XTHAL_INTTYPE_EXTERN_EDGE
+#define XCHAL_INT16_TYPE        XTHAL_INTTYPE_EXTERN_EDGE
+#define XCHAL_INT17_TYPE        XTHAL_INTTYPE_EXTERN_EDGE
+#define XCHAL_INT18_TYPE        XTHAL_INTTYPE_EXTERN_EDGE
+#define XCHAL_INT19_TYPE        XTHAL_INTTYPE_EXTERN_EDGE
+#define XCHAL_INT20_TYPE        XTHAL_INTTYPE_EXTERN_EDGE
+#define XCHAL_INT21_TYPE        XTHAL_INTTYPE_EXTERN_EDGE
+
+/*  Masks of interrupts for each type of interrupt:  */
+#define XCHAL_INTTYPE_MASK_UNCONFIGURED 0xFFC00000
+#define XCHAL_INTTYPE_MASK_SOFTWARE     0x00000880
+#define XCHAL_INTTYPE_MASK_EXTERN_EDGE  0x003F8000
+#define XCHAL_INTTYPE_MASK_EXTERN_LEVEL 0x0000133F
+#define XCHAL_INTTYPE_MASK_TIMER        0x00002440
+#define XCHAL_INTTYPE_MASK_NMI          0x00004000
+#define XCHAL_INTTYPE_MASK_WRITE_ERROR  0x00000000
+
+/*  Interrupt numbers assigned to specific interrupt sources:  */
+#define XCHAL_TIMER0_INTERRUPT          6       /* CCOMPARE0 */
+#define XCHAL_TIMER1_INTERRUPT          10      /* CCOMPARE1 */
+#define XCHAL_TIMER2_INTERRUPT          13      /* CCOMPARE2 */
+#define XCHAL_TIMER3_INTERRUPT          XTHAL_TIMER_UNCONFIGURED
+#define XCHAL_NMI_INTERRUPT             14      /* non-maskable interrupt */
+
+/*  Interrupt numbers for levels at which only one interrupt is configured:  */
+#define XCHAL_INTLEVEL2_NUM             8
+#define XCHAL_INTLEVEL4_NUM             12
+#define XCHAL_INTLEVEL5_NUM             13
+#define XCHAL_INTLEVEL7_NUM             14
+/*  (There are many interrupts each at level(s) 1, 3.)  */
+
+
+/*
+ *  External interrupt vectors/levels.
+ *  These macros describe how Xtensa processor interrupt numbers
+ *  (as numbered internally, eg. in INTERRUPT and INTENABLE registers)
+ *  map to external BInterrupt<n> pins, for those interrupts
+ *  configured as external (level-triggered, edge-triggered, or NMI).
+ *  See the Xtensa processor databook for more details.
+ */
+
+/*  Core interrupt numbers mapped to each EXTERNAL interrupt number:  */
+#define XCHAL_EXTINT0_NUM               0       /* (intlevel 1) */
+#define XCHAL_EXTINT1_NUM               1       /* (intlevel 1) */
+#define XCHAL_EXTINT2_NUM               2       /* (intlevel 1) */
+#define XCHAL_EXTINT3_NUM               3       /* (intlevel 1) */
+#define XCHAL_EXTINT4_NUM               4       /* (intlevel 1) */
+#define XCHAL_EXTINT5_NUM               5       /* (intlevel 1) */
+#define XCHAL_EXTINT6_NUM               8       /* (intlevel 2) */
+#define XCHAL_EXTINT7_NUM               9       /* (intlevel 3) */
+#define XCHAL_EXTINT8_NUM               12      /* (intlevel 4) */
+#define XCHAL_EXTINT9_NUM               14      /* (intlevel 7) */
+#define XCHAL_EXTINT10_NUM              15      /* (intlevel 1) */
+#define XCHAL_EXTINT11_NUM              16      /* (intlevel 1) */
+#define XCHAL_EXTINT12_NUM              17      /* (intlevel 1) */
+#define XCHAL_EXTINT13_NUM              18      /* (intlevel 1) */
+#define XCHAL_EXTINT14_NUM              19      /* (intlevel 1) */
+#define XCHAL_EXTINT15_NUM              20      /* (intlevel 1) */
+#define XCHAL_EXTINT16_NUM              21      /* (intlevel 3) */
+
+
+/*----------------------------------------------------------------------
+                        EXCEPTIONS and VECTORS
+  ----------------------------------------------------------------------*/
+
+#define XCHAL_XEA_VERSION               2       /* Xtensa Exception Architecture
+number: 1 == XEA1 (old)
+2 == XEA2 (new)
+0 == XEAX (extern) or TX */
+#define XCHAL_HAVE_XEA1                 0       /* Exception Architecture 1 */
+#define XCHAL_HAVE_XEA2                 1       /* Exception Architecture 2 */
+#define XCHAL_HAVE_XEAX                 0       /* External Exception Arch. */
+#define XCHAL_HAVE_EXCEPTIONS           1       /* exception option */
+#define XCHAL_HAVE_HALT                 0       /* halt architecture option */
+#define XCHAL_HAVE_BOOTLOADER           0       /* boot loader (for TX) */
+#define XCHAL_HAVE_MEM_ECC_PARITY       0       /* local memory ECC/parity */
+#define XCHAL_HAVE_VECTOR_SELECT        1       /* relocatable vectors */
+#define XCHAL_HAVE_VECBASE              1       /* relocatable vectors */
+#define XCHAL_VECBASE_RESET_VADDR       0x00002000  /* VECBASE reset value */
+#define XCHAL_VECBASE_RESET_PADDR       0x00002000
+#define XCHAL_RESET_VECBASE_OVERLAP     0
+
+#define XCHAL_RESET_VECTOR0_VADDR       0xFE000000
+#define XCHAL_RESET_VECTOR0_PADDR       0xFE000000
+#define XCHAL_RESET_VECTOR1_VADDR       0x00001000
+#define XCHAL_RESET_VECTOR1_PADDR       0x00001000
+#define XCHAL_RESET_VECTOR_VADDR        0xFE000000
+#define XCHAL_RESET_VECTOR_PADDR        0xFE000000
+#define XCHAL_USER_VECOFS               0x00000340
+#define XCHAL_USER_VECTOR_VADDR         0x00002340
+#define XCHAL_USER_VECTOR_PADDR         0x00002340
+#define XCHAL_KERNEL_VECOFS             0x00000300
+#define XCHAL_KERNEL_VECTOR_VADDR       0x00002300
+#define XCHAL_KERNEL_VECTOR_PADDR       0x00002300
+#define XCHAL_DOUBLEEXC_VECOFS          0x000003C0
+#define XCHAL_DOUBLEEXC_VECTOR_VADDR    0x000023C0
+#define XCHAL_DOUBLEEXC_VECTOR_PADDR    0x000023C0
+#define XCHAL_WINDOW_OF4_VECOFS         0x00000000
+#define XCHAL_WINDOW_UF4_VECOFS         0x00000040
+#define XCHAL_WINDOW_OF8_VECOFS         0x00000080
+#define XCHAL_WINDOW_UF8_VECOFS         0x000000C0
+#define XCHAL_WINDOW_OF12_VECOFS        0x00000100
+#define XCHAL_WINDOW_UF12_VECOFS        0x00000140
+#define XCHAL_WINDOW_VECTORS_VADDR      0x00002000
+#define XCHAL_WINDOW_VECTORS_PADDR      0x00002000
+#define XCHAL_INTLEVEL2_VECOFS          0x00000180
+#define XCHAL_INTLEVEL2_VECTOR_VADDR    0x00002180
+#define XCHAL_INTLEVEL2_VECTOR_PADDR    0x00002180
+#define XCHAL_INTLEVEL3_VECOFS          0x000001C0
+#define XCHAL_INTLEVEL3_VECTOR_VADDR    0x000021C0
+#define XCHAL_INTLEVEL3_VECTOR_PADDR    0x000021C0
+#define XCHAL_INTLEVEL4_VECOFS          0x00000200
+#define XCHAL_INTLEVEL4_VECTOR_VADDR    0x00002200
+#define XCHAL_INTLEVEL4_VECTOR_PADDR    0x00002200
+#define XCHAL_INTLEVEL5_VECOFS          0x00000240
+#define XCHAL_INTLEVEL5_VECTOR_VADDR    0x00002240
+#define XCHAL_INTLEVEL5_VECTOR_PADDR    0x00002240
+#define XCHAL_INTLEVEL6_VECOFS          0x00000280
+#define XCHAL_INTLEVEL6_VECTOR_VADDR    0x00002280
+#define XCHAL_INTLEVEL6_VECTOR_PADDR    0x00002280
+#define XCHAL_DEBUG_VECOFS              XCHAL_INTLEVEL6_VECOFS
+#define XCHAL_DEBUG_VECTOR_VADDR        XCHAL_INTLEVEL6_VECTOR_VADDR
+#define XCHAL_DEBUG_VECTOR_PADDR        XCHAL_INTLEVEL6_VECTOR_PADDR
+#define XCHAL_NMI_VECOFS                0x000002C0
+#define XCHAL_NMI_VECTOR_VADDR          0x000022C0
+#define XCHAL_NMI_VECTOR_PADDR          0x000022C0
+#define XCHAL_INTLEVEL7_VECOFS          XCHAL_NMI_VECOFS
+#define XCHAL_INTLEVEL7_VECTOR_VADDR    XCHAL_NMI_VECTOR_VADDR
+#define XCHAL_INTLEVEL7_VECTOR_PADDR    XCHAL_NMI_VECTOR_PADDR
+
+
+/*----------------------------------------------------------------------
+                                DEBUG
+  ----------------------------------------------------------------------*/
+
+#define XCHAL_HAVE_OCD                  1       /* OnChipDebug option */
+#define XCHAL_NUM_IBREAK                2       /* number of IBREAKn regs */
+#define XCHAL_NUM_DBREAK                2       /* number of DBREAKn regs */
+#define XCHAL_HAVE_OCD_DIR_ARRAY        1       /* faster OCD option */
+
+
+/*----------------------------------------------------------------------
+                                MMU
+  ----------------------------------------------------------------------*/
+
+/*  See core-matmap.h header file for more details.  */
+
+#define XCHAL_HAVE_TLBS                 1       /* inverse of HAVE_CACHEATTR */
+#define XCHAL_HAVE_SPANNING_WAY         1       /* one way maps I+D 4GB vaddr */
+#define XCHAL_SPANNING_WAY              6       /* TLB spanning way number */
+#define XCHAL_HAVE_IDENTITY_MAP         0       /* vaddr == paddr always */
+#define XCHAL_HAVE_CACHEATTR            0       /* CACHEATTR register present */
+#define XCHAL_HAVE_MIMIC_CACHEATTR      0       /* region protection */
+#define XCHAL_HAVE_XLT_CACHEATTR        0       /* region prot. w/translation */
+#define XCHAL_HAVE_PTP_MMU              1       /* full MMU (with page table
+[autorefill] and protection)
+usable for an MMU-based OS */
+/*  If none of the above last 4 are set, it's a custom TLB configuration.  */
+#define XCHAL_ITLB_ARF_ENTRIES_LOG2     2       /* log2(autorefill way size) */
+#define XCHAL_DTLB_ARF_ENTRIES_LOG2     2       /* log2(autorefill way size) */
+
+#define XCHAL_MMU_ASID_BITS             8       /* number of bits in ASIDs */
+#define XCHAL_MMU_RINGS                 4       /* number of rings (1..4) */
+#define XCHAL_MMU_RING_BITS             2       /* num of bits in RING field */
+
+#endif /* !XTENSA_HAL_NON_PRIVILEGED_ONLY */
+
+
+#endif /* _XTENSA_CORE_CONFIGURATION_H */
diff --git a/target-xtensa/core-dc233c/gdb-config.c b/target-xtensa/core-dc233c/gdb-config.c
new file mode 100644
index 0000000..b632341
--- /dev/null
+++ b/target-xtensa/core-dc233c/gdb-config.c
@@ -0,0 +1,145 @@
+/* Configuration for the Xtensa architecture for GDB, the GNU debugger.
+
+   Copyright (c) 2003-2010 Tensilica Inc.
+
+   Permission is hereby granted, free of charge, to any person obtaining
+   a copy of this software and associated documentation files (the
+   "Software"), to deal in the Software without restriction, including
+   without limitation the rights to use, copy, modify, merge, publish,
+   distribute, sublicense, and/or sell copies of the Software, and to
+   permit persons to whom the Software is furnished to do so, subject to
+   the following conditions:
+
+   The above copyright notice and this permission notice shall be included
+   in all copies or substantial portions of the Software.
+
+   THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+   EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+   MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+   IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
+   CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+   TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+   SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.  */
+
+/*    idx ofs bi sz al targno  flags cp typ group name  */
+XTREG(0,  0, 32, 4, 4, 0x0020, 0x0006, -2, 9, 0x0100, pc,          0, 0, 0, 0, 0, 0)
+XTREG(1,  4, 32, 4, 4, 0x0100, 0x0006, -2, 1, 0x0002, ar0,         0, 0, 0, 0, 0, 0)
+XTREG(2,  8, 32, 4, 4, 0x0101, 0x0006, -2, 1, 0x0002, ar1,         0, 0, 0, 0, 0, 0)
+XTREG(3, 12, 32, 4, 4, 0x0102, 0x0006, -2, 1, 0x0002, ar2,         0, 0, 0, 0, 0, 0)
+XTREG(4, 16, 32, 4, 4, 0x0103, 0x0006, -2, 1, 0x0002, ar3,         0, 0, 0, 0, 0, 0)
+XTREG(5, 20, 32, 4, 4, 0x0104, 0x0006, -2, 1, 0x0002, ar4,         0, 0, 0, 0, 0, 0)
+XTREG(6, 24, 32, 4, 4, 0x0105, 0x0006, -2, 1, 0x0002, ar5,         0, 0, 0, 0, 0, 0)
+XTREG(7, 28, 32, 4, 4, 0x0106, 0x0006, -2, 1, 0x0002, ar6,         0, 0, 0, 0, 0, 0)
+XTREG(8, 32, 32, 4, 4, 0x0107, 0x0006, -2, 1, 0x0002, ar7,         0, 0, 0, 0, 0, 0)
+XTREG(9, 36, 32, 4, 4, 0x0108, 0x0006, -2, 1, 0x0002, ar8,         0, 0, 0, 0, 0, 0)
+XTREG(10, 40, 32, 4, 4, 0x0109, 0x0006, -2, 1, 0x0002, ar9,         0, 0, 0, 0, 0, 0)
+XTREG(11, 44, 32, 4, 4, 0x010a, 0x0006, -2, 1, 0x0002, ar10,        0, 0, 0, 0, 0, 0)
+XTREG(12, 48, 32, 4, 4, 0x010b, 0x0006, -2, 1, 0x0002, ar11,        0, 0, 0, 0, 0, 0)
+XTREG(13, 52, 32, 4, 4, 0x010c, 0x0006, -2, 1, 0x0002, ar12,        0, 0, 0, 0, 0, 0)
+XTREG(14, 56, 32, 4, 4, 0x010d, 0x0006, -2, 1, 0x0002, ar13,        0, 0, 0, 0, 0, 0)
+XTREG(15, 60, 32, 4, 4, 0x010e, 0x0006, -2, 1, 0x0002, ar14,        0, 0, 0, 0, 0, 0)
+XTREG(16, 64, 32, 4, 4, 0x010f, 0x0006, -2, 1, 0x0002, ar15,        0, 0, 0, 0, 0, 0)
+XTREG(17, 68, 32, 4, 4, 0x0110, 0x0006, -2, 1, 0x0002, ar16,        0, 0, 0, 0, 0, 0)
+XTREG(18, 72, 32, 4, 4, 0x0111, 0x0006, -2, 1, 0x0002, ar17,        0, 0, 0, 0, 0, 0)
+XTREG(19, 76, 32, 4, 4, 0x0112, 0x0006, -2, 1, 0x0002, ar18,        0, 0, 0, 0, 0, 0)
+XTREG(20, 80, 32, 4, 4, 0x0113, 0x0006, -2, 1, 0x0002, ar19,        0, 0, 0, 0, 0, 0)
+XTREG(21, 84, 32, 4, 4, 0x0114, 0x0006, -2, 1, 0x0002, ar20,        0, 0, 0, 0, 0, 0)
+XTREG(22, 88, 32, 4, 4, 0x0115, 0x0006, -2, 1, 0x0002, ar21,        0, 0, 0, 0, 0, 0)
+XTREG(23, 92, 32, 4, 4, 0x0116, 0x0006, -2, 1, 0x0002, ar22,        0, 0, 0, 0, 0, 0)
+XTREG(24, 96, 32, 4, 4, 0x0117, 0x0006, -2, 1, 0x0002, ar23,        0, 0, 0, 0, 0, 0)
+XTREG(25, 100, 32, 4, 4, 0x0118, 0x0006, -2, 1, 0x0002, ar24,        0, 0, 0, 0, 0, 0)
+XTREG(26, 104, 32, 4, 4, 0x0119, 0x0006, -2, 1, 0x0002, ar25,        0, 0, 0, 0, 0, 0)
+XTREG(27, 108, 32, 4, 4, 0x011a, 0x0006, -2, 1, 0x0002, ar26,        0, 0, 0, 0, 0, 0)
+XTREG(28, 112, 32, 4, 4, 0x011b, 0x0006, -2, 1, 0x0002, ar27,        0, 0, 0, 0, 0, 0)
+XTREG(29, 116, 32, 4, 4, 0x011c, 0x0006, -2, 1, 0x0002, ar28,        0, 0, 0, 0, 0, 0)
+XTREG(30, 120, 32, 4, 4, 0x011d, 0x0006, -2, 1, 0x0002, ar29,        0, 0, 0, 0, 0, 0)
+XTREG(31, 124, 32, 4, 4, 0x011e, 0x0006, -2, 1, 0x0002, ar30,        0, 0, 0, 0, 0, 0)
+XTREG(32, 128, 32, 4, 4, 0x011f, 0x0006, -2, 1, 0x0002, ar31,        0, 0, 0, 0, 0, 0)
+XTREG(33, 132, 32, 4, 4, 0x0200, 0x0006, -2, 2, 0x1100, lbeg,        0, 0, 0, 0, 0, 0)
+XTREG(34, 136, 32, 4, 4, 0x0201, 0x0006, -2, 2, 0x1100, lend,        0, 0, 0, 0, 0, 0)
+XTREG(35, 140, 32, 4, 4, 0x0202, 0x0006, -2, 2, 0x1100, lcount,      0, 0, 0, 0, 0, 0)
+XTREG(36, 144, 6, 4, 4, 0x0203, 0x0006, -2, 2, 0x1100, sar,         0, 0, 0, 0, 0, 0)
+XTREG(37, 148, 32, 4, 4, 0x0205, 0x0006, -2, 2, 0x1100, litbase,     0, 0, 0, 0, 0, 0)
+XTREG(38, 152, 3, 4, 4, 0x0248, 0x0006, -2, 2, 0x1002, windowbase,  0, 0, 0, 0, 0, 0)
+XTREG(39, 156, 8, 4, 4, 0x0249, 0x0006, -2, 2, 0x1002, windowstart, 0, 0, 0, 0, 0, 0)
+XTREG(40, 160, 32, 4, 4, 0x02b0, 0x0002, -2, 2, 0x1000, sr176,       0, 0, 0, 0, 0, 0)
+XTREG(41, 164, 32, 4, 4, 0x02d0, 0x0002, -2, 2, 0x1000, sr208,       0, 0, 0, 0, 0, 0)
+XTREG(42, 168, 19, 4, 4, 0x02e6, 0x0006, -2, 2, 0x1100, ps,          0, 0, 0, 0, 0, 0)
+XTREG(43, 172, 32, 4, 4, 0x03e7, 0x0006, -2, 3, 0x0110, threadptr,   0, 0, 0, 0, 0, 0)
+XTREG(44, 176, 32, 4, 4, 0x020c, 0x0006, -1, 2, 0x1100, scompare1,   0, 0, 0, 0, 0, 0)
+XTREG(45, 180, 32, 4, 4, 0x0210, 0x0006, -1, 2, 0x1100, acclo,       0, 0, 0, 0, 0, 0)
+XTREG(46, 184, 8, 4, 4, 0x0211, 0x0006, -1, 2, 0x1100, acchi,       0, 0, 0, 0, 0, 0)
+XTREG(47, 188, 32, 4, 4, 0x0220, 0x0006, -1, 2, 0x1100, m0,          0, 0, 0, 0, 0, 0)
+XTREG(48, 192, 32, 4, 4, 0x0221, 0x0006, -1, 2, 0x1100, m1,          0, 0, 0, 0, 0, 0)
+XTREG(49, 196, 32, 4, 4, 0x0222, 0x0006, -1, 2, 0x1100, m2,          0, 0, 0, 0, 0, 0)
+XTREG(50, 200, 32, 4, 4, 0x0223, 0x0006, -1, 2, 0x1100, m3,          0, 0, 0, 0, 0, 0)
+XTREG(51, 204, 32, 4, 4, 0x03e6, 0x000e, -1, 3, 0x0110, expstate,    0, 0, 0, 0, 0, 0)
+XTREG(52, 208, 32, 4, 4, 0x0253, 0x0007, -2, 2, 0x1000, ptevaddr,    0, 0, 0, 0, 0, 0)
+XTREG(53, 212, 32, 4, 4, 0x0259, 0x000d, -2, 2, 0x1000, mmid,        0, 0, 0, 0, 0, 0)
+XTREG(54, 216, 32, 4, 4, 0x025a, 0x0007, -2, 2, 0x1000, rasid,       0, 0, 0, 0, 0, 0)
+XTREG(55, 220, 25, 4, 4, 0x025b, 0x0007, -2, 2, 0x1000, itlbcfg,     0, 0, 0, 0, 0, 0)
+XTREG(56, 224, 25, 4, 4, 0x025c, 0x0007, -2, 2, 0x1000, dtlbcfg,     0, 0, 0, 0, 0, 0)
+XTREG(57, 228, 2, 4, 4, 0x0260, 0x0007, -2, 2, 0x1000, ibreakenable, 0, 0, 0, 0, 0, 0)
+XTREG(58, 232, 6, 4, 4, 0x0263, 0x0007, -2, 2, 0x1000, atomctl,     0, 0, 0, 0, 0, 0)
+XTREG(59, 236, 32, 4, 4, 0x0268, 0x0007, -2, 2, 0x1000, ddr,         0, 0, 0, 0, 0, 0)
+XTREG(60, 240, 32, 4, 4, 0x0280, 0x0007, -2, 2, 0x1000, ibreaka0,    0, 0, 0, 0, 0, 0)
+XTREG(61, 244, 32, 4, 4, 0x0281, 0x0007, -2, 2, 0x1000, ibreaka1,    0, 0, 0, 0, 0, 0)
+XTREG(62, 248, 32, 4, 4, 0x0290, 0x0007, -2, 2, 0x1000, dbreaka0,    0, 0, 0, 0, 0, 0)
+XTREG(63, 252, 32, 4, 4, 0x0291, 0x0007, -2, 2, 0x1000, dbreaka1,    0, 0, 0, 0, 0, 0)
+XTREG(64, 256, 32, 4, 4, 0x02a0, 0x0007, -2, 2, 0x1000, dbreakc0,    0, 0, 0, 0, 0, 0)
+XTREG(65, 260, 32, 4, 4, 0x02a1, 0x0007, -2, 2, 0x1000, dbreakc1,    0, 0, 0, 0, 0, 0)
+XTREG(66, 264, 32, 4, 4, 0x02b1, 0x0007, -2, 2, 0x1000, epc1,        0, 0, 0, 0, 0, 0)
+XTREG(67, 268, 32, 4, 4, 0x02b2, 0x0007, -2, 2, 0x1000, epc2,        0, 0, 0, 0, 0, 0)
+XTREG(68, 272, 32, 4, 4, 0x02b3, 0x0007, -2, 2, 0x1000, epc3,        0, 0, 0, 0, 0, 0)
+XTREG(69, 276, 32, 4, 4, 0x02b4, 0x0007, -2, 2, 0x1000, epc4,        0, 0, 0, 0, 0, 0)
+XTREG(70, 280, 32, 4, 4, 0x02b5, 0x0007, -2, 2, 0x1000, epc5,        0, 0, 0, 0, 0, 0)
+XTREG(71, 284, 32, 4, 4, 0x02b6, 0x0007, -2, 2, 0x1000, epc6,        0, 0, 0, 0, 0, 0)
+XTREG(72, 288, 32, 4, 4, 0x02b7, 0x0007, -2, 2, 0x1000, epc7,        0, 0, 0, 0, 0, 0)
+XTREG(73, 292, 32, 4, 4, 0x02c0, 0x0007, -2, 2, 0x1000, depc,        0, 0, 0, 0, 0, 0)
+XTREG(74, 296, 19, 4, 4, 0x02c2, 0x0007, -2, 2, 0x1000, eps2,        0, 0, 0, 0, 0, 0)
+XTREG(75, 300, 19, 4, 4, 0x02c3, 0x0007, -2, 2, 0x1000, eps3,        0, 0, 0, 0, 0, 0)
+XTREG(76, 304, 19, 4, 4, 0x02c4, 0x0007, -2, 2, 0x1000, eps4,        0, 0, 0, 0, 0, 0)
+XTREG(77, 308, 19, 4, 4, 0x02c5, 0x0007, -2, 2, 0x1000, eps5,        0, 0, 0, 0, 0, 0)
+XTREG(78, 312, 19, 4, 4, 0x02c6, 0x0007, -2, 2, 0x1000, eps6,        0, 0, 0, 0, 0, 0)
+XTREG(79, 316, 19, 4, 4, 0x02c7, 0x0007, -2, 2, 0x1000, eps7,        0, 0, 0, 0, 0, 0)
+XTREG(80, 320, 32, 4, 4, 0x02d1, 0x0007, -2, 2, 0x1000, excsave1,    0, 0, 0, 0, 0, 0)
+XTREG(81, 324, 32, 4, 4, 0x02d2, 0x0007, -2, 2, 0x1000, excsave2,    0, 0, 0, 0, 0, 0)
+XTREG(82, 328, 32, 4, 4, 0x02d3, 0x0007, -2, 2, 0x1000, excsave3,    0, 0, 0, 0, 0, 0)
+XTREG(83, 332, 32, 4, 4, 0x02d4, 0x0007, -2, 2, 0x1000, excsave4,    0, 0, 0, 0, 0, 0)
+XTREG(84, 336, 32, 4, 4, 0x02d5, 0x0007, -2, 2, 0x1000, excsave5,    0, 0, 0, 0, 0, 0)
+XTREG(85, 340, 32, 4, 4, 0x02d6, 0x0007, -2, 2, 0x1000, excsave6,    0, 0, 0, 0, 0, 0)
+XTREG(86, 344, 32, 4, 4, 0x02d7, 0x0007, -2, 2, 0x1000, excsave7,    0, 0, 0, 0, 0, 0)
+XTREG(87, 348, 8, 4, 4, 0x02e0, 0x0007, -2, 2, 0x1000, cpenable,    0, 0, 0, 0, 0, 0)
+XTREG(88, 352, 22, 4, 4, 0x02e2, 0x000b, -2, 2, 0x1000, interrupt,   0, 0, 0, 0, 0, 0)
+XTREG(89, 356, 22, 4, 4, 0x02e2, 0x000d, -2, 2, 0x1000, intset,      0, 0, 0, 0, 0, 0)
+XTREG(90, 360, 22, 4, 4, 0x02e3, 0x000d, -2, 2, 0x1000, intclear,    0, 0, 0, 0, 0, 0)
+XTREG(91, 364, 22, 4, 4, 0x02e4, 0x0007, -2, 2, 0x1000, intenable,   0, 0, 0, 0, 0, 0)
+XTREG(92, 368, 32, 4, 4, 0x02e7, 0x0007, -2, 2, 0x1000, vecbase,     0, 0, 0, 0, 0, 0)
+XTREG(93, 372, 6, 4, 4, 0x02e8, 0x0007, -2, 2, 0x1000, exccause,    0, 0, 0, 0, 0, 0)
+XTREG(94, 376, 12, 4, 4, 0x02e9, 0x0003, -2, 2, 0x1000, debugcause,  0, 0, 0, 0, 0, 0)
+XTREG(95, 380, 32, 4, 4, 0x02ea, 0x000f, -2, 2, 0x1000, ccount,      0, 0, 0, 0, 0, 0)
+XTREG(96, 384, 32, 4, 4, 0x02eb, 0x0003, -2, 2, 0x1000, prid,        0, 0, 0, 0, 0, 0)
+XTREG(97, 388, 32, 4, 4, 0x02ec, 0x000f, -2, 2, 0x1000, icount,      0, 0, 0, 0, 0, 0)
+XTREG(98, 392, 4, 4, 4, 0x02ed, 0x0007, -2, 2, 0x1000, icountlevel, 0, 0, 0, 0, 0, 0)
+XTREG(99, 396, 32, 4, 4, 0x02ee, 0x0007, -2, 2, 0x1000, excvaddr,    0, 0, 0, 0, 0, 0)
+XTREG(100, 400, 32, 4, 4, 0x02f0, 0x000f, -2, 2, 0x1000, ccompare0,   0, 0, 0, 0, 0, 0)
+XTREG(101, 404, 32, 4, 4, 0x02f1, 0x000f, -2, 2, 0x1000, ccompare1,   0, 0, 0, 0, 0, 0)
+XTREG(102, 408, 32, 4, 4, 0x02f2, 0x000f, -2, 2, 0x1000, ccompare2,   0, 0, 0, 0, 0, 0)
+XTREG(103, 412, 32, 4, 4, 0x02f4, 0x0007, -2, 2, 0x1000, misc0,       0, 0, 0, 0, 0, 0)
+XTREG(104, 416, 32, 4, 4, 0x02f5, 0x0007, -2, 2, 0x1000, misc1,       0, 0, 0, 0, 0, 0)
+XTREG(105, 420, 32, 4, 4, 0x0000, 0x0006, -2, 8, 0x0100, a0,          0, 0, 0, 0, 0, 0)
+XTREG(106, 424, 32, 4, 4, 0x0001, 0x0006, -2, 8, 0x0100, a1,          0, 0, 0, 0, 0, 0)
+XTREG(107, 428, 32, 4, 4, 0x0002, 0x0006, -2, 8, 0x0100, a2,          0, 0, 0, 0, 0, 0)
+XTREG(108, 432, 32, 4, 4, 0x0003, 0x0006, -2, 8, 0x0100, a3,          0, 0, 0, 0, 0, 0)
+XTREG(109, 436, 32, 4, 4, 0x0004, 0x0006, -2, 8, 0x0100, a4,          0, 0, 0, 0, 0, 0)
+XTREG(110, 440, 32, 4, 4, 0x0005, 0x0006, -2, 8, 0x0100, a5,          0, 0, 0, 0, 0, 0)
+XTREG(111, 444, 32, 4, 4, 0x0006, 0x0006, -2, 8, 0x0100, a6,          0, 0, 0, 0, 0, 0)
+XTREG(112, 448, 32, 4, 4, 0x0007, 0x0006, -2, 8, 0x0100, a7,          0, 0, 0, 0, 0, 0)
+XTREG(113, 452, 32, 4, 4, 0x0008, 0x0006, -2, 8, 0x0100, a8,          0, 0, 0, 0, 0, 0)
+XTREG(114, 456, 32, 4, 4, 0x0009, 0x0006, -2, 8, 0x0100, a9,          0, 0, 0, 0, 0, 0)
+XTREG(115, 460, 32, 4, 4, 0x000a, 0x0006, -2, 8, 0x0100, a10,         0, 0, 0, 0, 0, 0)
+XTREG(116, 464, 32, 4, 4, 0x000b, 0x0006, -2, 8, 0x0100, a11,         0, 0, 0, 0, 0, 0)
+XTREG(117, 468, 32, 4, 4, 0x000c, 0x0006, -2, 8, 0x0100, a12,         0, 0, 0, 0, 0, 0)
+XTREG(118, 472, 32, 4, 4, 0x000d, 0x0006, -2, 8, 0x0100, a13,         0, 0, 0, 0, 0, 0)
+XTREG(119, 476, 32, 4, 4, 0x000e, 0x0006, -2, 8, 0x0100, a14,         0, 0, 0, 0, 0, 0)
+XTREG(120, 480, 32, 4, 4, 0x000f, 0x0006, -2, 8, 0x0100, a15,         0, 0, 0, 0, 0, 0)
commit 11ea40905259f29e448af816ff00d9d9f0951818
Author: Andreas Färber <afaerber at suse.de>
Date:   Sun Apr 15 18:51:01 2012 +0200

    linux-user: Fix exit syscall with QOM CPU
    
    For QOM'ified CPUs we cannot g_free() CPUArchState, we must
    object_delete() the object it is embedded into.
    
    Fixes LP#982321 (invalid free() while executing pacman with qemu-arm).
    
    Reported-by: Serge Schneider <serge at xecdesign.com>
    Reported-by: Russell Keith Davis <russell at russelldavis.org>
    Signed-off-by: Andreas Färber <afaerber at suse.de>
    Reviewed-by: Peter Maydell <peter.maydell at linaro.org>
    Tested-by: Serge Schneider <serge at xecdesign.com>
    Tested-by: Russell Keith Davis <russell at russelldavis.org>
    Signed-off-by: Blue Swirl <blauwirbel at gmail.com>

diff --git a/linux-user/syscall.c b/linux-user/syscall.c
index 8a92162..7128618 100644
--- a/linux-user/syscall.c
+++ b/linux-user/syscall.c
@@ -5045,7 +5045,11 @@ abi_long do_syscall(void *cpu_env, int num, abi_long arg1,
                         NULL, NULL, 0);
           }
           thread_env = NULL;
+#ifdef ENV_GET_CPU
+          object_delete(OBJECT(ENV_GET_CPU(cpu_env)));
+#else
           g_free(cpu_env);
+#endif
           g_free(ts);
           pthread_exit(NULL);
       }
commit 45e45ed2d61fb287adf03e49c74c152bfd2c975a
Author: Juan Quintela <quintela at redhat.com>
Date:   Mon Mar 19 23:57:36 2012 +0100

    target-ppc/machine.c: Drop unnecessary ifdefs
    
    machine.c is only compiled for softmmu targets, so checks for
    !defined(CONFIG_USER_ONLY) are unnecessary and can be dropped.
    
    Signed-off-by: Juan Quintela <quintela at redhat.com>
    [AF: Use more verbose commit message suggested by PMM]
    Reviewed-by: Peter Maydell <peter.maydell at linaro.org>
    Signed-off-by: Andreas Färber <afaerber at suse.de>

diff --git a/target-ppc/machine.c b/target-ppc/machine.c
index 70e2582..d6c2ee4 100644
--- a/target-ppc/machine.c
+++ b/target-ppc/machine.c
@@ -32,7 +32,6 @@ void cpu_save(QEMUFile *f, void *opaque)
     }
     qemu_put_be32s(f, &env->fpscr);
     qemu_put_sbe32s(f, &env->access_type);
-#if !defined(CONFIG_USER_ONLY)
 #if defined(TARGET_PPC64)
     qemu_put_betls(f, &env->asr);
     qemu_put_sbe32s(f, &env->slb_nr);
@@ -62,7 +61,6 @@ void cpu_save(QEMUFile *f, void *opaque)
     }
     for (i = 0; i < 4; i++)
         qemu_put_betls(f, &env->pb[i]);
-#endif
     for (i = 0; i < 1024; i++)
         qemu_put_betls(f, &env->spr[i]);
     qemu_put_be32s(f, &env->vscr);
@@ -72,7 +70,6 @@ void cpu_save(QEMUFile *f, void *opaque)
     qemu_put_be32s(f, &env->flags);
     qemu_put_sbe32s(f, &env->error_code);
     qemu_put_be32s(f, &env->pending_interrupts);
-#if !defined(CONFIG_USER_ONLY)
     qemu_put_be32s(f, &env->irq_input_state);
     for (i = 0; i < POWERPC_EXCP_NB; i++)
         qemu_put_betls(f, &env->excp_vectors[i]);
@@ -81,7 +78,6 @@ void cpu_save(QEMUFile *f, void *opaque)
     qemu_put_betls(f, &env->ivor_mask);
     qemu_put_betls(f, &env->ivpr_mask);
     qemu_put_betls(f, &env->hreset_vector);
-#endif
     qemu_put_betls(f, &env->nip);
     qemu_put_betls(f, &env->hflags);
     qemu_put_betls(f, &env->hflags_nmsr);
@@ -120,7 +116,6 @@ int cpu_load(QEMUFile *f, void *opaque, int version_id)
     }
     qemu_get_be32s(f, &env->fpscr);
     qemu_get_sbe32s(f, &env->access_type);
-#if !defined(CONFIG_USER_ONLY)
 #if defined(TARGET_PPC64)
     qemu_get_betls(f, &env->asr);
     qemu_get_sbe32s(f, &env->slb_nr);
@@ -150,7 +145,6 @@ int cpu_load(QEMUFile *f, void *opaque, int version_id)
     }
     for (i = 0; i < 4; i++)
         qemu_get_betls(f, &env->pb[i]);
-#endif
     for (i = 0; i < 1024; i++)
         qemu_get_betls(f, &env->spr[i]);
     ppc_store_sdr1(env, sdr1);
@@ -161,7 +155,6 @@ int cpu_load(QEMUFile *f, void *opaque, int version_id)
     qemu_get_be32s(f, &env->flags);
     qemu_get_sbe32s(f, &env->error_code);
     qemu_get_be32s(f, &env->pending_interrupts);
-#if !defined(CONFIG_USER_ONLY)
     qemu_get_be32s(f, &env->irq_input_state);
     for (i = 0; i < POWERPC_EXCP_NB; i++)
         qemu_get_betls(f, &env->excp_vectors[i]);
@@ -170,7 +163,6 @@ int cpu_load(QEMUFile *f, void *opaque, int version_id)
     qemu_get_betls(f, &env->ivor_mask);
     qemu_get_betls(f, &env->ivpr_mask);
     qemu_get_betls(f, &env->hreset_vector);
-#endif
     qemu_get_betls(f, &env->nip);
     qemu_get_betls(f, &env->hflags);
     qemu_get_betls(f, &env->hflags_nmsr);
commit a5cabbda760c798bb551d53a697058de28fce51c
Author: Meador Inge <meadori at codesourcery.com>
Date:   Tue Apr 10 15:04:23 2012 -0500

    target-ppc: Init dcache and icache size for e500 user mode
    
    commit f7aa558396dd0f6b7a2b22c05cb503c655854102 pulled the dcache and icache
    line size initialization inside of a '#if !defined(CONFIG_USER_ONLY)' block.
    This is not correct because instructions like 'dcbz' need the dcache size
    initialized even for user mode.
    
    Signed-off-by: Meador Inge <meadori at codesourcery.com>
    Cc: Varun Sethi <Varun.Sethi at freescale.com>
    [AF: Simplify #ifdefs by using cache line size 32 for *-user as before]
    Suggested-by: Scott Wood <scottwood at freescale.com>
    Signed-off-by: Andreas Färber <afaerber at suse.de>

diff --git a/target-ppc/translate_init.c b/target-ppc/translate_init.c
index fdc0a5f..ba4b84d 100644
--- a/target-ppc/translate_init.c
+++ b/target-ppc/translate_init.c
@@ -4462,7 +4462,10 @@ static void init_proc_e500 (CPUPPCState *env, int version)
                  &spr_read_spefscr, &spr_write_spefscr,
                  0x00000000);
     /* Memory management */
-#if !defined(CONFIG_USER_ONLY)
+#if defined(CONFIG_USER_ONLY)
+    env->dcache_line_size = 32;
+    env->icache_line_size = 32;
+#else /* !defined(CONFIG_USER_ONLY) */
     env->nb_pids = 3;
     env->nb_ways = 2;
     env->id_tlbs = 0;
commit 5724753e6576fc26ff4a563a6c2ccb8ce3b02cb8
Author: Stefan Weil <sw at weilnetz.de>
Date:   Sun Apr 15 16:13:48 2012 +0200

    target-ppc: Fix type casts for w64 (uintptr_t)
    
    This changes nothing for other hosts.
    
    Signed-off-by: Stefan Weil <sw at weilnetz.de>
    Signed-off-by: Andreas Färber <afaerber at suse.de>

diff --git a/target-ppc/translate_init.c b/target-ppc/translate_init.c
index 025122d..fdc0a5f 100644
--- a/target-ppc/translate_init.c
+++ b/target-ppc/translate_init.c
@@ -9504,12 +9504,12 @@ enum {
 
 static inline int is_indirect_opcode (void *handler)
 {
-    return ((unsigned long)handler & 0x03) == PPC_INDIRECT;
+    return ((uintptr_t)handler & 0x03) == PPC_INDIRECT;
 }
 
 static inline opc_handler_t **ind_table(void *handler)
 {
-    return (opc_handler_t **)((unsigned long)handler & ~3);
+    return (opc_handler_t **)((uintptr_t)handler & ~3);
 }
 
 /* Instruction table creation */
@@ -9528,7 +9528,7 @@ static int create_new_table (opc_handler_t **table, unsigned char idx)
 
     tmp = malloc(0x20 * sizeof(opc_handler_t));
     fill_new_table(tmp, 0x20);
-    table[idx] = (opc_handler_t *)((unsigned long)tmp | PPC_INDIRECT);
+    table[idx] = (opc_handler_t *)((uintptr_t)tmp | PPC_INDIRECT);
 
     return 0;
 }
commit a13895420561da4f8eae03f4d423a7c2fdb83f65
Author: Andreas Färber <afaerber at suse.de>
Date:   Fri Apr 6 15:35:34 2012 +0200

    target-ppc: QOM'ify CPU reset
    
    Move code from cpu_state_reset() into ppc_cpu_reset().
    Reorder #include of helper_regs.h to use it in translate_init.c.
    
    Adjust whitespace and add braces.
    
    Signed-off-by: Andreas Färber <afaerber at suse.de>
    Acked-by: David Gibson <david at gibson.dropbear.id.au>

diff --git a/target-ppc/helper.c b/target-ppc/helper.c
index c5de0ea..c610ce3 100644
--- a/target-ppc/helper.c
+++ b/target-ppc/helper.c
@@ -3138,50 +3138,7 @@ void cpu_dump_rfi (target_ulong RA, target_ulong msr)
 
 void cpu_state_reset(CPUPPCState *env)
 {
-    target_ulong msr;
-
-    if (qemu_loglevel_mask(CPU_LOG_RESET)) {
-        qemu_log("CPU Reset (CPU %d)\n", env->cpu_index);
-        log_cpu_state(env, 0);
-    }
-
-    msr = (target_ulong)0;
-    if (0) {
-        /* XXX: find a suitable condition to enable the hypervisor mode */
-        msr |= (target_ulong)MSR_HVB;
-    }
-    msr |= (target_ulong)0 << MSR_AP; /* TO BE CHECKED */
-    msr |= (target_ulong)0 << MSR_SA; /* TO BE CHECKED */
-    msr |= (target_ulong)1 << MSR_EP;
-#if defined (DO_SINGLE_STEP) && 0
-    /* Single step trace mode */
-    msr |= (target_ulong)1 << MSR_SE;
-    msr |= (target_ulong)1 << MSR_BE;
-#endif
-#if defined(CONFIG_USER_ONLY)
-    msr |= (target_ulong)1 << MSR_FP; /* Allow floating point usage */
-    msr |= (target_ulong)1 << MSR_VR; /* Allow altivec usage */
-    msr |= (target_ulong)1 << MSR_SPE; /* Allow SPE usage */
-    msr |= (target_ulong)1 << MSR_PR;
-#else
-    env->excp_prefix = env->hreset_excp_prefix;
-    env->nip = env->hreset_vector | env->excp_prefix;
-    if (env->mmu_model != POWERPC_MMU_REAL)
-        ppc_tlb_invalidate_all(env);
-#endif
-    env->msr = msr & env->msr_mask;
-#if defined(TARGET_PPC64)
-    if (env->mmu_model & POWERPC_MMU_64)
-        env->msr |= (1ULL << MSR_SF);
-#endif
-    hreg_compute_hflags(env);
-    env->reserve_addr = (target_ulong)-1ULL;
-    /* Be sure no exception or interrupt is pending */
-    env->pending_interrupts = 0;
-    env->exception_index = POWERPC_EXCP_NONE;
-    env->error_code = 0;
-    /* Flush all TLBs */
-    tlb_flush(env, 1);
+    cpu_reset(ENV_GET_CPU(env));
 }
 
 CPUPPCState *cpu_ppc_init (const char *cpu_model)
diff --git a/target-ppc/translate.c b/target-ppc/translate.c
index c9a503a..cf59765 100644
--- a/target-ppc/translate.c
+++ b/target-ppc/translate.c
@@ -9306,8 +9306,8 @@ GEN_SPEOP_LDST(evstwwe, 0x1C, 2),
 GEN_SPEOP_LDST(evstwwo, 0x1E, 2),
 };
 
-#include "translate_init.c"
 #include "helper_regs.h"
+#include "translate_init.c"
 
 /*****************************************************************************/
 /* Misc PowerPC helpers */
diff --git a/target-ppc/translate_init.c b/target-ppc/translate_init.c
index 5a7ac77..025122d 100644
--- a/target-ppc/translate_init.c
+++ b/target-ppc/translate_init.c
@@ -10211,10 +10211,54 @@ static void ppc_cpu_reset(CPUState *s)
     PowerPCCPU *cpu = POWERPC_CPU(s);
     PowerPCCPUClass *pcc = POWERPC_CPU_GET_CLASS(cpu);
     CPUPPCState *env = &cpu->env;
+    target_ulong msr;
+
+    if (qemu_loglevel_mask(CPU_LOG_RESET)) {
+        qemu_log("CPU Reset (CPU %d)\n", env->cpu_index);
+        log_cpu_state(env, 0);
+    }
 
     pcc->parent_reset(s);
 
-    cpu_state_reset(env);
+    msr = (target_ulong)0;
+    if (0) {
+        /* XXX: find a suitable condition to enable the hypervisor mode */
+        msr |= (target_ulong)MSR_HVB;
+    }
+    msr |= (target_ulong)0 << MSR_AP; /* TO BE CHECKED */
+    msr |= (target_ulong)0 << MSR_SA; /* TO BE CHECKED */
+    msr |= (target_ulong)1 << MSR_EP;
+#if defined(DO_SINGLE_STEP) && 0
+    /* Single step trace mode */
+    msr |= (target_ulong)1 << MSR_SE;
+    msr |= (target_ulong)1 << MSR_BE;
+#endif
+#if defined(CONFIG_USER_ONLY)
+    msr |= (target_ulong)1 << MSR_FP; /* Allow floating point usage */
+    msr |= (target_ulong)1 << MSR_VR; /* Allow altivec usage */
+    msr |= (target_ulong)1 << MSR_SPE; /* Allow SPE usage */
+    msr |= (target_ulong)1 << MSR_PR;
+#else
+    env->excp_prefix = env->hreset_excp_prefix;
+    env->nip = env->hreset_vector | env->excp_prefix;
+    if (env->mmu_model != POWERPC_MMU_REAL) {
+        ppc_tlb_invalidate_all(env);
+    }
+#endif
+    env->msr = msr & env->msr_mask;
+#if defined(TARGET_PPC64)
+    if (env->mmu_model & POWERPC_MMU_64) {
+        env->msr |= (1ULL << MSR_SF);
+    }
+#endif
+    hreg_compute_hflags(env);
+    env->reserve_addr = (target_ulong)-1ULL;
+    /* Be sure no exception or interrupt is pending */
+    env->pending_interrupts = 0;
+    env->exception_index = POWERPC_EXCP_NONE;
+    env->error_code = 0;
+    /* Flush all TLBs */
+    tlb_flush(env, 1);
 }
 
 static void ppc_cpu_initfn(Object *obj)
commit 6cca7ad686de0270fe30ae303e31c6a27b53d7a9
Author: Andreas Färber <afaerber at suse.de>
Date:   Fri Apr 6 15:09:01 2012 +0200

    target-ppc: Start QOM'ifying CPU init
    
    Move code not dependent on ppc_def_t from cpu_ppc_init() into an initfn.
    
    Signed-off-by: Andreas Färber <afaerber at suse.de>
    Acked-by: David Gibson <david at gibson.dropbear.id.au>

diff --git a/target-ppc/helper.c b/target-ppc/helper.c
index 0d904dd..c5de0ea 100644
--- a/target-ppc/helper.c
+++ b/target-ppc/helper.c
@@ -3196,10 +3196,11 @@ CPUPPCState *cpu_ppc_init (const char *cpu_model)
 
     cpu = POWERPC_CPU(object_new(TYPE_POWERPC_CPU));
     env = &cpu->env;
-    cpu_exec_init(env);
+
     if (tcg_enabled()) {
         ppc_translate_init();
     }
+
     env->cpu_model_str = cpu_model;
     cpu_ppc_register_internal(env, def);
 
diff --git a/target-ppc/translate_init.c b/target-ppc/translate_init.c
index e4d15a5..5a7ac77 100644
--- a/target-ppc/translate_init.c
+++ b/target-ppc/translate_init.c
@@ -10217,6 +10217,14 @@ static void ppc_cpu_reset(CPUState *s)
     cpu_state_reset(env);
 }
 
+static void ppc_cpu_initfn(Object *obj)
+{
+    PowerPCCPU *cpu = POWERPC_CPU(obj);
+    CPUPPCState *env = &cpu->env;
+
+    cpu_exec_init(env);
+}
+
 static void ppc_cpu_class_init(ObjectClass *oc, void *data)
 {
     PowerPCCPUClass *pcc = POWERPC_CPU_CLASS(oc);
@@ -10230,6 +10238,7 @@ static const TypeInfo ppc_cpu_type_info = {
     .name = TYPE_POWERPC_CPU,
     .parent = TYPE_CPU,
     .instance_size = sizeof(PowerPCCPU),
+    .instance_init = ppc_cpu_initfn,
     .abstract = false,
     .class_size = sizeof(PowerPCCPUClass),
     .class_init = ppc_cpu_class_init,
commit 1d0cb67da9eff798420d0f6479fec6026c4dc41f
Author: Andreas Färber <afaerber at suse.de>
Date:   Fri Apr 6 14:39:03 2012 +0200

    target-ppc: QOM'ify CPU
    
    Embed CPUPPCState as first member of PowerPCCPU.
    Distinguish between "powerpc-cpu", "powerpc64-cpu" and
    "embedded-powerpc-cpu".
    
    Let CPUClass::reset() call cpu_state_reset() for now.
    
    Signed-off-by: Andreas Färber <afaerber at suse.de>
    Acked-by: David Gibson <david at gibson.dropbear.id.au>

diff --git a/target-ppc/cpu-qom.h b/target-ppc/cpu-qom.h
new file mode 100644
index 0000000..fef6f95
--- /dev/null
+++ b/target-ppc/cpu-qom.h
@@ -0,0 +1,77 @@
+/*
+ * QEMU PowerPC CPU
+ *
+ * Copyright (c) 2012 SUSE LINUX Products GmbH
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, see
+ * <http://www.gnu.org/licenses/lgpl-2.1.html>
+ */
+#ifndef QEMU_PPC_CPU_QOM_H
+#define QEMU_PPC_CPU_QOM_H
+
+#include "qemu/cpu.h"
+#include "cpu.h"
+
+#ifdef TARGET_PPC64
+#define TYPE_POWERPC_CPU "powerpc64-cpu"
+#elif defined(TARGET_PPCEMB)
+#define TYPE_POWERPC_CPU "embedded-powerpc-cpu"
+#else
+#define TYPE_POWERPC_CPU "powerpc-cpu"
+#endif
+
+#define POWERPC_CPU_CLASS(klass) \
+    OBJECT_CLASS_CHECK(PowerPCCPUClass, (klass), TYPE_POWERPC_CPU)
+#define POWERPC_CPU(obj) \
+    OBJECT_CHECK(PowerPCCPU, (obj), TYPE_POWERPC_CPU)
+#define POWERPC_CPU_GET_CLASS(obj) \
+    OBJECT_GET_CLASS(PowerPCCPUClass, (obj), TYPE_POWERPC_CPU)
+
+/**
+ * PowerPCCPUClass:
+ * @parent_reset: The parent class' reset handler.
+ *
+ * A PowerPC CPU model.
+ */
+typedef struct PowerPCCPUClass {
+    /*< private >*/
+    CPUClass parent_class;
+    /*< public >*/
+
+    void (*parent_reset)(CPUState *cpu);
+} PowerPCCPUClass;
+
+/**
+ * PowerPCCPU:
+ * @env: #CPUPPCState
+ *
+ * A PowerPC CPU.
+ */
+typedef struct PowerPCCPU {
+    /*< private >*/
+    CPUState parent_obj;
+    /*< public >*/
+
+    CPUPPCState env;
+} PowerPCCPU;
+
+static inline PowerPCCPU *ppc_env_get_cpu(CPUPPCState *env)
+{
+    return POWERPC_CPU(container_of(env, PowerPCCPU, env));
+}
+
+#define ENV_GET_CPU(e) CPU(ppc_env_get_cpu(e))
+
+
+#endif
diff --git a/target-ppc/cpu.h b/target-ppc/cpu.h
index 1d5c602..84c9674 100644
--- a/target-ppc/cpu.h
+++ b/target-ppc/cpu.h
@@ -1096,6 +1096,8 @@ struct mmu_ctx_t {
 };
 #endif
 
+#include "cpu-qom.h"
+
 /*****************************************************************************/
 CPUPPCState *cpu_ppc_init (const char *cpu_model);
 void ppc_translate_init(void);
diff --git a/target-ppc/helper.c b/target-ppc/helper.c
index b34dcbe..0d904dd 100644
--- a/target-ppc/helper.c
+++ b/target-ppc/helper.c
@@ -3186,6 +3186,7 @@ void cpu_state_reset(CPUPPCState *env)
 
 CPUPPCState *cpu_ppc_init (const char *cpu_model)
 {
+    PowerPCCPU *cpu;
     CPUPPCState *env;
     const ppc_def_t *def;
 
@@ -3193,7 +3194,8 @@ CPUPPCState *cpu_ppc_init (const char *cpu_model)
     if (!def)
         return NULL;
 
-    env = g_malloc0(sizeof(CPUPPCState));
+    cpu = POWERPC_CPU(object_new(TYPE_POWERPC_CPU));
+    env = &cpu->env;
     cpu_exec_init(env);
     if (tcg_enabled()) {
         ppc_translate_init();
diff --git a/target-ppc/translate_init.c b/target-ppc/translate_init.c
index 067e07e..e4d15a5 100644
--- a/target-ppc/translate_init.c
+++ b/target-ppc/translate_init.c
@@ -10204,3 +10204,40 @@ void ppc_cpu_list (FILE *f, fprintf_function cpu_fprintf)
                        ppc_defs[i].name, ppc_defs[i].pvr);
     }
 }
+
+/* CPUClass::reset() */
+static void ppc_cpu_reset(CPUState *s)
+{
+    PowerPCCPU *cpu = POWERPC_CPU(s);
+    PowerPCCPUClass *pcc = POWERPC_CPU_GET_CLASS(cpu);
+    CPUPPCState *env = &cpu->env;
+
+    pcc->parent_reset(s);
+
+    cpu_state_reset(env);
+}
+
+static void ppc_cpu_class_init(ObjectClass *oc, void *data)
+{
+    PowerPCCPUClass *pcc = POWERPC_CPU_CLASS(oc);
+    CPUClass *cc = CPU_CLASS(oc);
+
+    pcc->parent_reset = cc->reset;
+    cc->reset = ppc_cpu_reset;
+}
+
+static const TypeInfo ppc_cpu_type_info = {
+    .name = TYPE_POWERPC_CPU,
+    .parent = TYPE_CPU,
+    .instance_size = sizeof(PowerPCCPU),
+    .abstract = false,
+    .class_size = sizeof(PowerPCCPUClass),
+    .class_init = ppc_cpu_class_init,
+};
+
+static void ppc_cpu_register_types(void)
+{
+    type_register_static(&ppc_cpu_type_info);
+}
+
+type_init(ppc_cpu_register_types)
commit 12b1143b2807a5b760e477fac0e1028a9760b6c6
Author: David Gibson <david at gibson.dropbear.id.au>
Date:   Wed Apr 4 15:02:05 2012 +1000

    target-ppc: Add hooks for handling tcg and kvm limitations
    
    On target-ppc, our table of CPU types and features encodes the features as
    found on the hardware, regardless of whether these features are actually
    usable under TCG or KVM.  We already have cases where the information from
    the cpu table must be fixed up to account for limitations in the emulation
    method we're using.  e.g. TCG does not support the DFP and VSX instructions
    and KVM needs different numbering of the CPUs in order to tell it the
    correct thread to core mappings.
    
    This patch cleans up these hacks to handle emulation limitations by
    consolidating them into a pair of functions specifically for the purpose.
    
    Signed-off-by: David Gibson <david at gibson.dropbear.id.au>
    [AF: Style and typo fixes, rename new functions and drop ppc_def_t arg]
    Signed-off-by: Andreas Färber <afaerber at suse.de>

diff --git a/target-ppc/helper.c b/target-ppc/helper.c
index f61b8b2..b34dcbe 100644
--- a/target-ppc/helper.c
+++ b/target-ppc/helper.c
@@ -3198,15 +3198,6 @@ CPUPPCState *cpu_ppc_init (const char *cpu_model)
     if (tcg_enabled()) {
         ppc_translate_init();
     }
-    /* Adjust cpu index for SMT */
-#if !defined(CONFIG_USER_ONLY)
-    if (kvm_enabled()) {
-        int smt = kvmppc_smt_threads();
-
-        env->cpu_index = (env->cpu_index / smp_threads)*smt
-            + (env->cpu_index % smp_threads);
-    }
-#endif /* !CONFIG_USER_ONLY */
     env->cpu_model_str = cpu_model;
     cpu_ppc_register_internal(env, def);
 
diff --git a/target-ppc/kvm.c b/target-ppc/kvm.c
index d929213..c09cc39 100644
--- a/target-ppc/kvm.c
+++ b/target-ppc/kvm.c
@@ -27,6 +27,7 @@
 #include "kvm.h"
 #include "kvm_ppc.h"
 #include "cpu.h"
+#include "cpus.h"
 #include "device_tree.h"
 #include "hw/sysbus.h"
 #include "hw/spapr.h"
@@ -938,6 +939,19 @@ const ppc_def_t *kvmppc_host_cpu_def(void)
     return spec;
 }
 
+int kvmppc_fixup_cpu(CPUPPCState *env)
+{
+    int smt;
+
+    /* Adjust cpu index for SMT */
+    smt = kvmppc_smt_threads();
+    env->cpu_index = (env->cpu_index / smp_threads) * smt
+        + (env->cpu_index % smp_threads);
+
+    return 0;
+}
+
+
 bool kvm_arch_stop_on_emulation_error(CPUPPCState *env)
 {
     return true;
diff --git a/target-ppc/kvm_ppc.h b/target-ppc/kvm_ppc.h
index 8f1267c..34ecad3 100644
--- a/target-ppc/kvm_ppc.h
+++ b/target-ppc/kvm_ppc.h
@@ -29,6 +29,7 @@ void *kvmppc_create_spapr_tce(uint32_t liobn, uint32_t window_size, int *pfd);
 int kvmppc_remove_spapr_tce(void *table, int pfd, uint32_t window_size);
 #endif /* !CONFIG_USER_ONLY */
 const ppc_def_t *kvmppc_host_cpu_def(void);
+int kvmppc_fixup_cpu(CPUPPCState *env);
 
 #else
 
@@ -95,6 +96,10 @@ static inline const ppc_def_t *kvmppc_host_cpu_def(void)
     return NULL;
 }
 
+static inline int kvmppc_fixup_cpu(CPUPPCState *env)
+{
+    return -1;
+}
 #endif
 
 #ifndef CONFIG_KVM
diff --git a/target-ppc/translate_init.c b/target-ppc/translate_init.c
index b1f8785..067e07e 100644
--- a/target-ppc/translate_init.c
+++ b/target-ppc/translate_init.c
@@ -9889,6 +9889,28 @@ static int gdb_set_spe_reg(CPUPPCState *env, uint8_t *mem_buf, int n)
     return 0;
 }
 
+static int ppc_fixup_cpu(CPUPPCState *env)
+{
+    /* TCG doesn't (yet) emulate some groups of instructions that
+     * are implemented on some otherwise supported CPUs (e.g. VSX
+     * and decimal floating point instructions on POWER7).  We
+     * remove unsupported instruction groups from the cpu state's
+     * instruction masks and hope the guest can cope.  For at
+     * least the pseries machine, the unavailability of these
+     * instructions can be advertised to the guest via the device
+     * tree. */
+    if ((env->insns_flags & ~PPC_TCG_INSNS)
+        || (env->insns_flags2 & ~PPC_TCG_INSNS2)) {
+        fprintf(stderr, "Warning: Disabling some instructions which are not "
+                "emulated by TCG (0x%" PRIx64 ", 0x%" PRIx64 ")\n",
+                env->insns_flags & ~PPC_TCG_INSNS,
+                env->insns_flags2 & ~PPC_TCG_INSNS2);
+    }
+    env->insns_flags &= PPC_TCG_INSNS;
+    env->insns_flags2 &= PPC_TCG_INSNS2;
+    return 0;
+}
+
 int cpu_ppc_register_internal (CPUPPCState *env, const ppc_def_t *def)
 {
     env->msr_mask = def->msr_mask;
@@ -9897,25 +9919,22 @@ int cpu_ppc_register_internal (CPUPPCState *env, const ppc_def_t *def)
     env->bus_model = def->bus_model;
     env->insns_flags = def->insns_flags;
     env->insns_flags2 = def->insns_flags2;
-    if (!kvm_enabled()) {
-        /* TCG doesn't (yet) emulate some groups of instructions that
-         * are implemented on some otherwise supported CPUs (e.g. VSX
-         * and decimal floating point instructions on POWER7).  We
-         * remove unsupported instruction groups from the cpu state's
-         * instruction masks and hope the guest can cope.  For at
-         * least the pseries machine, the unavailability of these
-         * instructions can be advertise to the guest via the device
-         * tree.
-         *
-         * FIXME: we should have a similar masking for CPU features
-         * not accessible under KVM, but so far, there aren't any of
-         * those. */
-        env->insns_flags &= PPC_TCG_INSNS;
-        env->insns_flags2 &= PPC_TCG_INSNS2;
-    }
     env->flags = def->flags;
     env->bfd_mach = def->bfd_mach;
     env->check_pow = def->check_pow;
+
+    if (kvm_enabled()) {
+        if (kvmppc_fixup_cpu(env) != 0) {
+            fprintf(stderr, "Unable to virtualize selected CPU with KVM\n");
+            exit(1);
+        }
+    } else {
+        if (ppc_fixup_cpu(env) != 0) {
+            fprintf(stderr, "Unable to emulate selected CPU with TCG\n");
+            exit(1);
+        }
+    }
+
     if (create_ppc_opcodes(env, def) < 0)
         return -1;
     init_ppc_proc(env, def);
commit e2fbb432fc4ec64d0a53c41588ede31450b6c6a8
Author: Andreas Färber <afaerber at suse.de>
Date:   Fri Apr 6 14:42:59 2012 +0200

    target-ppc: Drop cpu_ppc_close()
    
    It is unused, so avoid QOM'ifying it unneededly.
    
    Signed-off-by: Andreas Färber <afaerber at suse.de>
    Acked-by: David Gibson <david at gibson.dropbear.id.au>

diff --git a/target-ppc/cpu.h b/target-ppc/cpu.h
index e7fb364..1d5c602 100644
--- a/target-ppc/cpu.h
+++ b/target-ppc/cpu.h
@@ -1100,7 +1100,6 @@ struct mmu_ctx_t {
 CPUPPCState *cpu_ppc_init (const char *cpu_model);
 void ppc_translate_init(void);
 int cpu_ppc_exec (CPUPPCState *s);
-void cpu_ppc_close (CPUPPCState *s);
 /* you can call this signal handler from your SIGBUS and SIGSEGV
    signal handlers to inform the virtual CPU of exceptions. non zero
    is returned if the signal was handled by the virtual CPU.  */
diff --git a/target-ppc/helper.c b/target-ppc/helper.c
index f0ea1c3..f61b8b2 100644
--- a/target-ppc/helper.c
+++ b/target-ppc/helper.c
@@ -3214,9 +3214,3 @@ CPUPPCState *cpu_ppc_init (const char *cpu_model)
 
     return env;
 }
-
-void cpu_ppc_close (CPUPPCState *env)
-{
-    /* Should also remove all opcode tables... */
-    g_free(env);
-}
commit 5f2e2ba2625d6fa4ecbc2af86e076c20ab84c171
Author: David Gibson <david at gibson.dropbear.id.au>
Date:   Wed Apr 4 15:02:07 2012 +1000

    pseries: Consolidate hack for RTAS display-character usage
    
    Currently the pseries machine contains not one but two somewhat ugly hacks
    to allow printing of early debug messages before the guest has properly
    read the device tree.
    
    First, we special case H_PUT_TERM_CHAR so that a vtermno of 0 (usually
    invalid) will look for a suitable vty and use that.  This supports Linux's
    early debug code which will use H_PUT_TERM_CHAR with vtermno==0 before
    reading the device tree.  Second, we support the RTAS display-character call.
    This takes no vtermno so we assume the address of the default first VTY.
    
    This patch makes things more consistent by folding the second hack into the
    first.  Now, display-character uses the existing vty_lookup() function to
    do the same search for a suitable VTY.
    
    Signed-off-by: David Gibson <david at gibson.dropbear.id.au>
    Signed-off-by: Andreas Färber <afaerber at suse.de>

diff --git a/hw/spapr_rtas.c b/hw/spapr_rtas.c
index 480a4ae..ae18595 100644
--- a/hw/spapr_rtas.c
+++ b/hw/spapr_rtas.c
@@ -44,8 +44,7 @@ static void rtas_display_character(sPAPREnvironment *spapr,
                                    uint32_t nret, target_ulong rets)
 {
     uint8_t c = rtas_ld(args, 0);
-    VIOsPAPRDevice *sdev = spapr_vio_find_by_reg(spapr->vio_bus,
-                                                 SPAPR_VTY_BASE_ADDRESS);
+    VIOsPAPRDevice *sdev = vty_lookup(spapr, 0);
 
     if (!sdev) {
         rtas_st(rets, 0, -1);
diff --git a/hw/spapr_vio.h b/hw/spapr_vio.h
index ae3283c..fd29c5e 100644
--- a/hw/spapr_vio.h
+++ b/hw/spapr_vio.h
@@ -117,6 +117,7 @@ uint64_t ldq_tce(VIOsPAPRDevice *dev, uint64_t taddr);
 
 int spapr_vio_send_crq(VIOsPAPRDevice *dev, uint8_t *crq);
 
+VIOsPAPRDevice *vty_lookup(sPAPREnvironment *spapr, target_ulong reg);
 void vty_putchars(VIOsPAPRDevice *sdev, uint8_t *buf, int len);
 void spapr_vty_create(VIOsPAPRBus *bus, uint32_t reg, CharDriverState *chardev);
 void spapr_vlan_create(VIOsPAPRBus *bus, uint32_t reg, NICInfo *nd);
diff --git a/hw/spapr_vty.c b/hw/spapr_vty.c
index 60e22b1..a30c040 100644
--- a/hw/spapr_vty.c
+++ b/hw/spapr_vty.c
@@ -70,8 +70,6 @@ static int spapr_vty_init(VIOsPAPRDevice *sdev)
 }
 
 /* Forward declaration */
-static VIOsPAPRDevice *vty_lookup(sPAPREnvironment *spapr, target_ulong reg);
-
 static target_ulong h_put_term_char(CPUPPCState *env, sPAPREnvironment *spapr,
                                     target_ulong opcode, target_ulong *args)
 {
@@ -195,7 +193,7 @@ VIOsPAPRDevice *spapr_vty_get_default(VIOsPAPRBus *bus)
     return selected;
 }
 
-static VIOsPAPRDevice *vty_lookup(sPAPREnvironment *spapr, target_ulong reg)
+VIOsPAPRDevice *vty_lookup(sPAPREnvironment *spapr, target_ulong reg)
 {
     VIOsPAPRDevice *sdev;
 
commit 3b768df95a877577a9b8d7ea98166240b017ca84
Author: David Gibson <david at gibson.dropbear.id.au>
Date:   Wed Apr 4 15:02:06 2012 +1000

    pseries: Remove unused fields from VIOsPAPRBus structure
    
    The VIOsPAPRBus structure, used on the pseries machine contains some old
    fields which are no longer used anywhere.  This patch removes them.
    
    Signed-off-by: David Gibson <david at gibson.dropbear.id.au>
    Signed-off-by: Andreas Färber <afaerber at suse.de>

diff --git a/hw/spapr_vio.h b/hw/spapr_vio.h
index d8527be..ae3283c 100644
--- a/hw/spapr_vio.h
+++ b/hw/spapr_vio.h
@@ -89,8 +89,6 @@ struct VIOsPAPRDevice {
 
 struct VIOsPAPRBus {
     BusState bus;
-    const char *dt_name, *dt_type, *dt_compatible;
-    target_ulong signal_mask;
     int (*init)(VIOsPAPRDevice *dev);
     int (*devnode)(VIOsPAPRDevice *dev, void *fdt, int node_off);
 };
commit c821a43c60e55fdfb8bc9c64696238e409d96192
Author: David Gibson <david at gibson.dropbear.id.au>
Date:   Thu Mar 29 08:39:47 2012 +1100

    pseries: Implement RTAS system-reboot call
    
    This patch adds the PAPR defined RTAS system-reboot call to the pseries
    machine emulation, providing the guest with a way to trigger a reboot.
    
    Signed-off-by: David Gibson <david at gibson.dropbear.id.au>
    Signed-off-by: Andreas Färber <afaerber at suse.de>

diff --git a/hw/spapr_rtas.c b/hw/spapr_rtas.c
index 0946585..480a4ae 100644
--- a/hw/spapr_rtas.c
+++ b/hw/spapr_rtas.c
@@ -112,6 +112,19 @@ static void rtas_power_off(sPAPREnvironment *spapr,
     rtas_st(rets, 0, 0);
 }
 
+static void rtas_system_reboot(sPAPREnvironment *spapr,
+                               uint32_t token, uint32_t nargs,
+                               target_ulong args,
+                               uint32_t nret, target_ulong rets)
+{
+    if (nargs != 0 || nret != 1) {
+        rtas_st(rets, 0, -3);
+        return;
+    }
+    qemu_system_reset_request();
+    rtas_st(rets, 0, 0);
+}
+
 static void rtas_query_cpu_stopped_state(sPAPREnvironment *spapr,
                                          uint32_t token, uint32_t nargs,
                                          target_ulong args,
@@ -294,6 +307,7 @@ static void core_rtas_register_types(void)
     spapr_rtas_register("get-time-of-day", rtas_get_time_of_day);
     spapr_rtas_register("set-time-of-day", rtas_set_time_of_day);
     spapr_rtas_register("power-off", rtas_power_off);
+    spapr_rtas_register("system-reboot", rtas_system_reboot);
     spapr_rtas_register("query-cpu-stopped-state",
                         rtas_query_cpu_stopped_state);
     spapr_rtas_register("start-cpu", rtas_start_cpu);
commit 8e01f355db4c7e54b0877a6d9508e83d0afbc4b6
Author: David Gibson <david at gibson.dropbear.id.au>
Date:   Thu Mar 29 08:39:46 2012 +1100

    pseries: Fix bug with reset of VIO CRQs
    
    PAPR specifies a Command Response Queue (CRQ) mechanism used for virtual
    IO, which we implement.  However, we don't correctly clean up registered
    CRQs when we reset the system.
    
    This patch adds a reset handler to fix this bug.  While we're at it, add
    in some of the extra debug messages that were used to track the problem
    down.
    
    Signed-off-by: David Gibson <david at gibson.dropbear.id.au>
    [AF: Updated hcall_dprintf()s to not duplicate the function name]
    Signed-off-by: Andreas Färber <afaerber at suse.de>

diff --git a/hw/spapr_vio.c b/hw/spapr_vio.c
index 1f67e64..0bf2c31 100644
--- a/hw/spapr_vio.c
+++ b/hw/spapr_vio.c
@@ -431,12 +431,13 @@ static target_ulong h_reg_crq(CPUPPCState *env, sPAPREnvironment *spapr,
 
     /* Check if device supports CRQs */
     if (!dev->crq.SendFunc) {
+        hcall_dprintf("Device does not support CRQ\n");
         return H_NOT_FOUND;
     }
 
-
     /* Already a queue ? */
     if (dev->crq.qsize) {
+        hcall_dprintf("CRQ already registered\n");
         return H_RESOURCE;
     }
     dev->crq.qladdr = queue_addr;
@@ -449,6 +450,17 @@ static target_ulong h_reg_crq(CPUPPCState *env, sPAPREnvironment *spapr,
     return H_SUCCESS;
 }
 
+static target_ulong free_crq(VIOsPAPRDevice *dev)
+{
+    dev->crq.qladdr = 0;
+    dev->crq.qsize = 0;
+    dev->crq.qnext = 0;
+
+    dprintf("CRQ for dev 0x%" PRIx32 " freed\n", dev->reg);
+
+    return H_SUCCESS;
+}
+
 static target_ulong h_free_crq(CPUPPCState *env, sPAPREnvironment *spapr,
                                target_ulong opcode, target_ulong *args)
 {
@@ -460,13 +472,7 @@ static target_ulong h_free_crq(CPUPPCState *env, sPAPREnvironment *spapr,
         return H_PARAMETER;
     }
 
-    dev->crq.qladdr = 0;
-    dev->crq.qsize = 0;
-    dev->crq.qnext = 0;
-
-    dprintf("CRQ for dev 0x" TARGET_FMT_lx " freed\n", reg);
-
-    return H_SUCCESS;
+    return free_crq(dev);
 }
 
 static target_ulong h_send_crq(CPUPPCState *env, sPAPREnvironment *spapr,
@@ -642,6 +648,15 @@ static int spapr_vio_check_reg(VIOsPAPRDevice *sdev)
     return 0;
 }
 
+static void spapr_vio_busdev_reset(void *opaque)
+{
+    VIOsPAPRDevice *dev = (VIOsPAPRDevice *)opaque;
+
+    if (dev->crq.qsize) {
+        free_crq(dev);
+    }
+}
+
 static int spapr_vio_busdev_init(DeviceState *qdev)
 {
     VIOsPAPRDevice *dev = (VIOsPAPRDevice *)qdev;
@@ -670,6 +685,8 @@ static int spapr_vio_busdev_init(DeviceState *qdev)
 
     rtce_init(dev);
 
+    qemu_register_reset(spapr_vio_busdev_reset, dev);
+
     return pc->init(dev);
 }
 
commit d9599c9205089805cd6ef55985beeb06aef0c819
Author: David Gibson <david at gibson.dropbear.id.au>
Date:   Thu Mar 29 08:39:45 2012 +1100

    pseries: Clean up hcall_dprintf() debugging messages
    
    The pseries machine code has a number of debug messages for debugging PAPR
    hypercalls, dependent on DEBUG_SPAPR_HCALLS.  This patch cleans these
    messages up a bit, by adding __func__ to the hcall_dprintf() macro and
    simplifying up a number of the individual messages accordingly.
    
    Signed-off-by: David Gibson <david at gibson.dropbear.id.au>
    Signed-off-by: Andreas Färber <afaerber at suse.de>

diff --git a/hw/spapr.h b/hw/spapr.h
index 11160b0..654a7a8 100644
--- a/hw/spapr.h
+++ b/hw/spapr.h
@@ -272,7 +272,7 @@ extern sPAPREnvironment *spapr;
 
 #ifdef DEBUG_SPAPR_HCALLS
 #define hcall_dprintf(fmt, ...) \
-    do { fprintf(stderr, fmt, ## __VA_ARGS__); } while (0)
+    do { fprintf(stderr, "%s: " fmt, __func__, ## __VA_ARGS__); } while (0)
 #else
 #define hcall_dprintf(fmt, ...) \
     do { } while (0)
diff --git a/hw/spapr_llan.c b/hw/spapr_llan.c
index cfc7778..32dce17 100644
--- a/hw/spapr_llan.c
+++ b/hw/spapr_llan.c
@@ -279,21 +279,19 @@ static target_ulong h_register_logical_lan(CPUPPCState *env,
 
     if (check_bd(dev, VLAN_VALID_BD(buf_list, SPAPR_VIO_TCE_PAGE_SIZE),
                  SPAPR_VIO_TCE_PAGE_SIZE) < 0) {
-        hcall_dprintf("Bad buf_list 0x" TARGET_FMT_lx " for "
-                      "H_REGISTER_LOGICAL_LAN\n", buf_list);
+        hcall_dprintf("Bad buf_list 0x" TARGET_FMT_lx "\n", buf_list);
         return H_PARAMETER;
     }
 
     filter_list_bd = VLAN_VALID_BD(filter_list, SPAPR_VIO_TCE_PAGE_SIZE);
     if (check_bd(dev, filter_list_bd, SPAPR_VIO_TCE_PAGE_SIZE) < 0) {
-        hcall_dprintf("Bad filter_list 0x" TARGET_FMT_lx " for "
-                      "H_REGISTER_LOGICAL_LAN\n", filter_list);
+        hcall_dprintf("Bad filter_list 0x" TARGET_FMT_lx "\n", filter_list);
         return H_PARAMETER;
     }
 
     if (!(rec_queue & VLAN_BD_VALID)
         || (check_bd(dev, rec_queue, VLAN_RQ_ALIGNMENT) < 0)) {
-        hcall_dprintf("Bad receive queue for H_REGISTER_LOGICAL_LAN\n");
+        hcall_dprintf("Bad receive queue\n");
         return H_PARAMETER;
     }
 
@@ -358,13 +356,13 @@ static target_ulong h_add_logical_lan_buffer(CPUPPCState *env,
             ", 0x" TARGET_FMT_lx ")\n", reg, buf);
 
     if (!sdev) {
-        hcall_dprintf("Wrong device in h_add_logical_lan_buffer\n");
+        hcall_dprintf("Bad device\n");
         return H_PARAMETER;
     }
 
     if ((check_bd(dev, buf, 4) < 0)
         || (VLAN_BD_LEN(buf) < 16)) {
-        hcall_dprintf("Bad buffer enqueued in h_add_logical_lan_buffer\n");
+        hcall_dprintf("Bad buffer enqueued\n");
         return H_PARAMETER;
     }
 
diff --git a/hw/spapr_vio.c b/hw/spapr_vio.c
index dbf5a90..1f67e64 100644
--- a/hw/spapr_vio.c
+++ b/hw/spapr_vio.c
@@ -204,8 +204,7 @@ static target_ulong h_put_tce(CPUPPCState *env, sPAPREnvironment *spapr,
     VIOsPAPR_RTCE *rtce;
 
     if (!dev) {
-        hcall_dprintf("spapr_vio_put_tce on non-existent LIOBN "
-                      TARGET_FMT_lx "\n", liobn);
+        hcall_dprintf("LIOBN 0x" TARGET_FMT_lx " does not exist\n", liobn);
         return H_PARAMETER;
     }
 
@@ -217,8 +216,7 @@ static target_ulong h_put_tce(CPUPPCState *env, sPAPREnvironment *spapr,
 #endif
 
     if (ioba >= dev->rtce_window_size) {
-        hcall_dprintf("spapr_vio_put_tce on out-of-boards IOBA 0x"
-                      TARGET_FMT_lx "\n", ioba);
+        hcall_dprintf("Out-of-bounds IOBA 0x" TARGET_FMT_lx "\n", ioba);
         return H_PARAMETER;
     }
 
@@ -414,22 +412,20 @@ static target_ulong h_reg_crq(CPUPPCState *env, sPAPREnvironment *spapr,
     VIOsPAPRDevice *dev = spapr_vio_find_by_reg(spapr->vio_bus, reg);
 
     if (!dev) {
-        hcall_dprintf("h_reg_crq on non-existent unit 0x"
-                      TARGET_FMT_lx "\n", reg);
+        hcall_dprintf("Unit 0x" TARGET_FMT_lx " does not exist\n", reg);
         return H_PARAMETER;
     }
 
     /* We can't grok a queue size bigger than 256M for now */
     if (queue_len < 0x1000 || queue_len > 0x10000000) {
-        hcall_dprintf("h_reg_crq, queue size too small or too big (0x%llx)\n",
-                      (unsigned long long)queue_len);
+        hcall_dprintf("Queue size too small or too big (0x" TARGET_FMT_lx
+                      ")\n", queue_len);
         return H_PARAMETER;
     }
 
     /* Check queue alignment */
     if (queue_addr & 0xfff) {
-        hcall_dprintf("h_reg_crq, queue not aligned (0x%llx)\n",
-                      (unsigned long long)queue_addr);
+        hcall_dprintf("Queue not aligned (0x" TARGET_FMT_lx ")\n", queue_addr);
         return H_PARAMETER;
     }
 
@@ -460,8 +456,7 @@ static target_ulong h_free_crq(CPUPPCState *env, sPAPREnvironment *spapr,
     VIOsPAPRDevice *dev = spapr_vio_find_by_reg(spapr->vio_bus, reg);
 
     if (!dev) {
-        hcall_dprintf("h_free_crq on non-existent unit 0x"
-                      TARGET_FMT_lx "\n", reg);
+        hcall_dprintf("Unit 0x" TARGET_FMT_lx " does not exist\n", reg);
         return H_PARAMETER;
     }
 
@@ -484,8 +479,7 @@ static target_ulong h_send_crq(CPUPPCState *env, sPAPREnvironment *spapr,
     uint64_t crq_mangle[2];
 
     if (!dev) {
-        hcall_dprintf("h_send_crq on non-existent unit 0x"
-                      TARGET_FMT_lx "\n", reg);
+        hcall_dprintf("Unit 0x" TARGET_FMT_lx " does not exist\n", reg);
         return H_PARAMETER;
     }
     crq_mangle[0] = cpu_to_be64(msg_hi);
@@ -505,8 +499,7 @@ static target_ulong h_enable_crq(CPUPPCState *env, sPAPREnvironment *spapr,
     VIOsPAPRDevice *dev = spapr_vio_find_by_reg(spapr->vio_bus, reg);
 
     if (!dev) {
-        hcall_dprintf("h_enable_crq on non-existent unit 0x"
-                      TARGET_FMT_lx "\n", reg);
+        hcall_dprintf("Unit 0x" TARGET_FMT_lx " does not exist\n", reg);
         return H_PARAMETER;
     }
 
commit 52d631dcc70144b6ce8293db78cd6de635331c83
Author: Mark Cave-Ayland <mark.cave-ayland at ilande.co.uk>
Date:   Tue Mar 27 16:41:55 2012 +0100

    PPC: Fix TLB invalidation bug within the PPC interrupt handler.
    
    Commit 41557447d30eeb944e42069513df13585f5e6c7f also introduced a subtle TLB
    flush bug. By applying a mask to the interrupt MSR which cleared the IR/DR
    bits at the start of the interrupt handler, the logic towards the end of the
    handler to force a TLB flush if either one of these bits were set would never
    be triggered.
    
    This patch simply changes the IR/DR bit check in the TLB flush logic to use
    the original MSR value (albeit with some interrupt-specific bits cleared) so
    that the IR/DR bits are preserved at the point where the check takes place.
    
    Signed-off-by: Mark Cave-Ayland <mark.cave-ayland at ilande.co.uk>
    Acked-by: David Gibson <david at gibson.dropbear.id.au>
    Signed-off-by: Andreas Färber <afaerber at suse.de>

diff --git a/target-ppc/helper.c b/target-ppc/helper.c
index e13b749..f0ea1c3 100644
--- a/target-ppc/helper.c
+++ b/target-ppc/helper.c
@@ -2960,7 +2960,7 @@ static inline void powerpc_excp(CPUPPCState *env, int excp_model, int excp)
     if (asrr1 != -1)
         env->spr[asrr1] = env->spr[srr1];
     /* If we disactivated any translation, flush TLBs */
-    if (new_msr & ((1 << MSR_IR) | (1 << MSR_DR)))
+    if (msr & ((1 << MSR_IR) | (1 << MSR_DR)))
         tlb_flush(env, 1);
 
     if (msr_ile) {
commit cdde6ffc27517bdf069734fbc5693ce2b14edc75
Author: Avi Kivity <avi at redhat.com>
Date:   Wed Jan 4 16:28:42 2012 +0200

    pci: fix corrupted pci conf index register by unaligned write
    
    Commit d0ed8076cbdc261 converted the PCI config access to the memory
    API, but also inadvertantly changed it to accept unaligned writes,
    and corrupt the index register in the process.  This causes a regression
    booting NetBSD.
    
    Fix by ignoring unaligned or non-dword writes.
    
    https://bugs.launchpad.net/qemu/+bug/897771
    
    Reported-by: Andreas Gustafsson <gson at gson.org>
    Signed-off-by: Avi Kivity <avi at redhat.com>
    Signed-off-by: Michael S. Tsirkin <mst at redhat.com>

diff --git a/hw/pci_host.c b/hw/pci_host.c
index 44c6c20..8041778 100644
--- a/hw/pci_host.c
+++ b/hw/pci_host.c
@@ -101,6 +101,9 @@ static void pci_host_config_write(void *opaque, target_phys_addr_t addr,
 
     PCI_DPRINTF("%s addr " TARGET_FMT_plx " len %d val %"PRIx64"\n",
                 __func__, addr, len, val);
+    if (addr != 0 || len != 4) {
+        return;
+    }
     s->config_reg = val;
 }
 
commit 54bfa546a0b5af335128ef5c477f8af9834df498
Author: Michael S. Tsirkin <mst at redhat.com>
Date:   Sun Apr 15 12:00:52 2012 +0300

    acpi: explicitly account for >1 device per slot
    
    Slot present bit is cleared apparently for each device. Hotplug and non
    hotplug devices should not mix normally, and we only set the bit when we
    add a device so it should all work out, but it's more robust to
    explicitly account for more than one device per slot.
    
    Acked-by: Alex Williamson <alex.williamson at redhat.com>
    Signed-off-by: Michael S. Tsirkin <mst at redhat.com>

diff --git a/hw/acpi_piix4.c b/hw/acpi_piix4.c
index 11c1f85..585da4e 100644
--- a/hw/acpi_piix4.c
+++ b/hw/acpi_piix4.c
@@ -287,6 +287,7 @@ static void acpi_piix_eject_slot(PIIX4PMState *s, unsigned slots)
     DeviceState *qdev, *next;
     BusState *bus = qdev_get_parent_bus(&s->dev.qdev);
     int slot = ffs(slots) - 1;
+    bool slot_free = true;
 
     /* Mark request as complete */
     s->pci0_status.down &= ~(1U << slot);
@@ -294,11 +295,17 @@ static void acpi_piix_eject_slot(PIIX4PMState *s, unsigned slots)
     QTAILQ_FOREACH_SAFE(qdev, &bus->children, sibling, next) {
         PCIDevice *dev = PCI_DEVICE(qdev);
         PCIDeviceClass *pc = PCI_DEVICE_GET_CLASS(dev);
-        if (PCI_SLOT(dev->devfn) == slot && !pc->no_hotplug) {
-            s->pci0_slot_device_present &= ~(1U << slot);
-            qdev_free(qdev);
+        if (PCI_SLOT(dev->devfn) == slot) {
+            if (pc->no_hotplug) {
+                slot_free = false;
+            } else {
+                qdev_free(qdev);
+            }
         }
     }
+    if (slot_free) {
+        s->pci0_slot_device_present &= ~(1U << slot);
+    }
 }
 
 static void piix4_update_hotplug(PIIX4PMState *s)
commit 9290f364c1f0c0a5a2ee8e03607f4804455c0d0e
Author: Alex Williamson <alex.williamson at redhat.com>
Date:   Thu Apr 5 11:07:28 2012 -0600

    acpi_piix4: Re-define PCI hotplug eject register read
    
    The PCI hotplug eject register has always returned 0, so let's redefine
    it as a hotplug feature register.  The existing model of using separate
    up & down read-only registers and an eject via write to this register
    becomes the base implementation.  As we make use of new interfaces we'll
    set bits here to allow the BIOS and AML implementation to optimize for
    the platform implementation.
    
    Signed-off-by: Alex Williamson <alex.williamson at redhat.com>
    Signed-off-by: Michael S. Tsirkin <mst at redhat.com>

diff --git a/docs/specs/acpi_pci_hotplug.txt b/docs/specs/acpi_pci_hotplug.txt
index 1883d63..a839434 100644
--- a/docs/specs/acpi_pci_hotplug.txt
+++ b/docs/specs/acpi_pci_hotplug.txt
@@ -27,8 +27,16 @@ events.  Read-only.
 PCI device eject (IO port 0xae08-0xae0b, 4-byte access):
 ----------------------------------------
 
-Used by ACPI BIOS _EJ0 method to request device removal. One bit per slot.
-Reads return 0.
+Write: Used by ACPI BIOS _EJ0 method to request device removal.
+One bit per slot.
+
+Read: Hotplug features register.  Used by platform to identify features
+available.  Current base feature set (no bits set):
+ - Read-only "up" register @0xae00, 4-byte access, bit per slot
+ - Read-only "down" register @0xae04, 4-byte access, bit per slot
+ - Read/write "eject" register @0xae08, 4-byte access,
+   write: bit per slot eject, read: hotplug feature set
+ - Read-only hotplug capable register @0xae0c, 4-byte access, bit per slot
 
 PCI removability status (IO port 0xae0c-0xae0f, 4-byte access):
 -----------------------------------------------
diff --git a/hw/acpi_piix4.c b/hw/acpi_piix4.c
index 5d3b0ba..11c1f85 100644
--- a/hw/acpi_piix4.c
+++ b/hw/acpi_piix4.c
@@ -511,9 +511,10 @@ static uint32_t pci_down_read(void *opaque, uint32_t addr)
     return val;
 }
 
-static uint32_t pciej_read(void *opaque, uint32_t addr)
+static uint32_t pci_features_read(void *opaque, uint32_t addr)
 {
-    PIIX4_DPRINTF("pciej read %x\n", addr);
+    /* No feature defined yet */
+    PIIX4_DPRINTF("pci_features_read %x\n", 0);
     return 0;
 }
 
@@ -545,7 +546,7 @@ static void piix4_acpi_system_hot_add_init(PCIBus *bus, PIIX4PMState *s)
     register_ioport_read(PCI_DOWN_BASE, 4, 4, pci_down_read, s);
 
     register_ioport_write(PCI_EJ_BASE, 4, 4, pciej_write, s);
-    register_ioport_read(PCI_EJ_BASE, 4, 4,  pciej_read, s);
+    register_ioport_read(PCI_EJ_BASE, 4, 4,  pci_features_read, s);
 
     register_ioport_read(PCI_RMV_BASE, 4, 4,  pcirmv_read, s);
 
commit 31745aabcd6dce5583dbd0e5ddee93ff9fdfe3e6
Author: Alex Williamson <alex.williamson at redhat.com>
Date:   Thu Apr 5 11:07:21 2012 -0600

    acpi_piix4: Remove PCI_RMV_BASE write code
    
    Clarify this register as read-only and remove write code.  No
    change in existing behavior.
    
    Signed-off-by: Alex Williamson <alex.williamson at redhat.com>
    Signed-off-by: Michael S. Tsirkin <mst at redhat.com>

diff --git a/docs/specs/acpi_pci_hotplug.txt b/docs/specs/acpi_pci_hotplug.txt
index 1e2c8a2..1883d63 100644
--- a/docs/specs/acpi_pci_hotplug.txt
+++ b/docs/specs/acpi_pci_hotplug.txt
@@ -34,4 +34,4 @@ PCI removability status (IO port 0xae0c-0xae0f, 4-byte access):
 -----------------------------------------------
 
 Used by ACPI BIOS _RMV method to indicate removability status to OS. One
-bit per slot.
+bit per slot.  Read-only
diff --git a/hw/acpi_piix4.c b/hw/acpi_piix4.c
index 0e7af51..5d3b0ba 100644
--- a/hw/acpi_piix4.c
+++ b/hw/acpi_piix4.c
@@ -531,11 +531,6 @@ static uint32_t pcirmv_read(void *opaque, uint32_t addr)
     return s->pci0_hotplug_enable;
 }
 
-static void pcirmv_write(void *opaque, uint32_t addr, uint32_t val)
-{
-    return;
-}
-
 static int piix4_device_hotplug(DeviceState *qdev, PCIDevice *dev,
                                 PCIHotplugState state);
 
@@ -552,7 +547,6 @@ static void piix4_acpi_system_hot_add_init(PCIBus *bus, PIIX4PMState *s)
     register_ioport_write(PCI_EJ_BASE, 4, 4, pciej_write, s);
     register_ioport_read(PCI_EJ_BASE, 4, 4,  pciej_read, s);
 
-    register_ioport_write(PCI_RMV_BASE, 4, 4, pcirmv_write, s);
     register_ioport_read(PCI_RMV_BASE, 4, 4,  pcirmv_read, s);
 
     pci_bus_hotplug(bus, piix4_device_hotplug, &s->dev.qdev);
commit 7faa8075d898ae56d2c533c530569bb25ab86eaf
Author: Alex Williamson <alex.williamson at redhat.com>
Date:   Thu Apr 5 11:07:15 2012 -0600

    acpi_piix4: Fix PCI hotplug race
    
    As Michael Tsirkin demonstrated, current PCI hotplug is vulnerable
    to a few races.  The first is a race with other hotplug operations
    because we clear the up & down registers at each event.  If a new
    event comes before the last is processed, up/down is cleared and
    the event is lost.
    
    To fix this for the down register, we create a life cycle for
    the event request that starts with the hot unplug request in
    piix4_device_hotplug() and ends when the device is ejected.
    This allows us to mask and clear individual bits, preserving them
    against races.  For the up register, we have no clear end point
    for when the event is finished.  We could modify the BIOS to
    acknowledge the bit and clear it, but this creates BIOS compatibiliy
    issues without offering a complete solution.  Instead we note that
    gratuitous ACPI device checks are not harmful, which allows us to
    issue a device check for every slot.  We know which slots are present
    and we know which slots are hotpluggable, so we can easily reduce
    this to a more manageable set for the guest.
    
    The other race Michael noted was that an unplug request followed
    by reset may also lose the eject notification, which may also
    result in the eject request being lost which a subsequent add
    or remove.  Once we're in reset, the device is unused and we can
    flush the queue of device removals ourselves.  Previously if a
    device_del was issued to a guest without ACPI PCI hotplug support,
    it was necessary to shutdown the guest to recover the device.
    With this, a guest reboot is sufficient.
    
    Signed-off-by: Alex Williamson <alex.williamson at redhat.com>
    Signed-off-by: Michael S. Tsirkin <mst at redhat.com>

diff --git a/hw/acpi_piix4.c b/hw/acpi_piix4.c
index 5e8b261..0e7af51 100644
--- a/hw/acpi_piix4.c
+++ b/hw/acpi_piix4.c
@@ -48,7 +48,7 @@
 #define PIIX4_PCI_HOTPLUG_STATUS 2
 
 struct pci_status {
-    uint32_t up;
+    uint32_t up; /* deprecated, maintained for migration compatibility */
     uint32_t down;
 };
 
@@ -70,6 +70,7 @@ typedef struct PIIX4PMState {
     /* for pci hotplug */
     struct pci_status pci0_status;
     uint32_t pci0_hotplug_enable;
+    uint32_t pci0_slot_device_present;
 } PIIX4PMState;
 
 static void piix4_acpi_system_hot_add_init(PCIBus *bus, PIIX4PMState *s);
@@ -205,6 +206,17 @@ static void pm_write_config(PCIDevice *d,
         pm_io_space_update((PIIX4PMState *)d);
 }
 
+static void vmstate_pci_status_pre_save(void *opaque)
+{
+    struct pci_status *pci0_status = opaque;
+    PIIX4PMState *s = container_of(pci0_status, PIIX4PMState, pci0_status);
+
+    /* We no longer track up, so build a safe value for migrating
+     * to a version that still does... of course these might get lost
+     * by an old buggy implementation, but we try. */
+    pci0_status->up = s->pci0_slot_device_present & s->pci0_hotplug_enable;
+}
+
 static int vmstate_acpi_post_load(void *opaque, int version_id)
 {
     PIIX4PMState *s = opaque;
@@ -241,6 +253,7 @@ static const VMStateDescription vmstate_pci_status = {
     .version_id = 1,
     .minimum_version_id = 1,
     .minimum_version_id_old = 1,
+    .pre_save = vmstate_pci_status_pre_save,
     .fields      = (VMStateField []) {
         VMSTATE_UINT32(up, struct pci_status),
         VMSTATE_UINT32(down, struct pci_status),
@@ -269,13 +282,38 @@ static const VMStateDescription vmstate_acpi = {
     }
 };
 
+static void acpi_piix_eject_slot(PIIX4PMState *s, unsigned slots)
+{
+    DeviceState *qdev, *next;
+    BusState *bus = qdev_get_parent_bus(&s->dev.qdev);
+    int slot = ffs(slots) - 1;
+
+    /* Mark request as complete */
+    s->pci0_status.down &= ~(1U << slot);
+
+    QTAILQ_FOREACH_SAFE(qdev, &bus->children, sibling, next) {
+        PCIDevice *dev = PCI_DEVICE(qdev);
+        PCIDeviceClass *pc = PCI_DEVICE_GET_CLASS(dev);
+        if (PCI_SLOT(dev->devfn) == slot && !pc->no_hotplug) {
+            s->pci0_slot_device_present &= ~(1U << slot);
+            qdev_free(qdev);
+        }
+    }
+}
+
 static void piix4_update_hotplug(PIIX4PMState *s)
 {
     PCIDevice *dev = &s->dev;
     BusState *bus = qdev_get_parent_bus(&dev->qdev);
     DeviceState *qdev, *next;
 
+    /* Execute any pending removes during reset */
+    while (s->pci0_status.down) {
+        acpi_piix_eject_slot(s, s->pci0_status.down);
+    }
+
     s->pci0_hotplug_enable = ~0;
+    s->pci0_slot_device_present = 0;
 
     QTAILQ_FOREACH_SAFE(qdev, &bus->children, sibling, next) {
         PCIDevice *pdev = PCI_DEVICE(qdev);
@@ -283,8 +321,10 @@ static void piix4_update_hotplug(PIIX4PMState *s)
         int slot = PCI_SLOT(pdev->devfn);
 
         if (pc->no_hotplug) {
-            s->pci0_hotplug_enable &= ~(1 << slot);
+            s->pci0_hotplug_enable &= ~(1U << slot);
         }
+
+        s->pci0_slot_device_present |= (1U << slot);
     }
 }
 
@@ -452,7 +492,11 @@ static void gpe_writeb(void *opaque, uint32_t addr, uint32_t val)
 static uint32_t pci_up_read(void *opaque, uint32_t addr)
 {
     PIIX4PMState *s = opaque;
-    uint32_t val = s->pci0_status.up;
+    uint32_t val;
+
+    /* Manufacture an "up" value to cause a device check on any hotplug
+     * slot with a device.  Extra device checks are harmless. */
+    val = s->pci0_slot_device_present & s->pci0_hotplug_enable;
 
     PIIX4_DPRINTF("pci_up_read %x\n", val);
     return val;
@@ -475,18 +519,7 @@ static uint32_t pciej_read(void *opaque, uint32_t addr)
 
 static void pciej_write(void *opaque, uint32_t addr, uint32_t val)
 {
-    BusState *bus = opaque;
-    DeviceState *qdev, *next;
-    int slot = ffs(val) - 1;
-
-    QTAILQ_FOREACH_SAFE(qdev, &bus->children, sibling, next) {
-        PCIDevice *dev = PCI_DEVICE(qdev);
-        PCIDeviceClass *pc = PCI_DEVICE_GET_CLASS(dev);
-        if (PCI_SLOT(dev->devfn) == slot && !pc->no_hotplug) {
-            qdev_free(qdev);
-        }
-    }
-
+    acpi_piix_eject_slot(opaque, val);
 
     PIIX4_DPRINTF("pciej write %x <== %d\n", addr, val);
 }
@@ -516,8 +549,8 @@ static void piix4_acpi_system_hot_add_init(PCIBus *bus, PIIX4PMState *s)
     register_ioport_read(PCI_UP_BASE, 4, 4, pci_up_read, s);
     register_ioport_read(PCI_DOWN_BASE, 4, 4, pci_down_read, s);
 
-    register_ioport_write(PCI_EJ_BASE, 4, 4, pciej_write, bus);
-    register_ioport_read(PCI_EJ_BASE, 4, 4,  pciej_read, bus);
+    register_ioport_write(PCI_EJ_BASE, 4, 4, pciej_write, s);
+    register_ioport_read(PCI_EJ_BASE, 4, 4,  pciej_read, s);
 
     register_ioport_write(PCI_RMV_BASE, 4, 4, pcirmv_write, s);
     register_ioport_read(PCI_RMV_BASE, 4, 4,  pcirmv_read, s);
@@ -528,13 +561,13 @@ static void piix4_acpi_system_hot_add_init(PCIBus *bus, PIIX4PMState *s)
 static void enable_device(PIIX4PMState *s, int slot)
 {
     s->ar.gpe.sts[0] |= PIIX4_PCI_HOTPLUG_STATUS;
-    s->pci0_status.up |= (1 << slot);
+    s->pci0_slot_device_present |= (1U << slot);
 }
 
 static void disable_device(PIIX4PMState *s, int slot)
 {
     s->ar.gpe.sts[0] |= PIIX4_PCI_HOTPLUG_STATUS;
-    s->pci0_status.down |= (1 << slot);
+    s->pci0_status.down |= (1U << slot);
 }
 
 static int piix4_device_hotplug(DeviceState *qdev, PCIDevice *dev,
@@ -548,11 +581,10 @@ static int piix4_device_hotplug(DeviceState *qdev, PCIDevice *dev,
      * it is present on boot, no hotplug event is necessary. We do send an
      * event when the device is disabled later. */
     if (state == PCI_COLDPLUG_ENABLED) {
+        s->pci0_slot_device_present |= (1U << slot);
         return 0;
     }
 
-    s->pci0_status.up = 0;
-    s->pci0_status.down = 0;
     if (state == PCI_HOTPLUG_ENABLED) {
         enable_device(s, slot);
     } else {
commit ba737541edddf9d0026460eb7b1d1c599b4c8ae9
Author: Alex Williamson <alex.williamson at redhat.com>
Date:   Thu Apr 5 11:07:08 2012 -0600

    acpi_piix4: Disallow write to up/down PCI hotplug registers
    
    The write side of these registers is never used and actually can't be
    used as defined because any read/modify/write sequence from the guest
    potentially races with qemu.  Drop the write support and define these
    as read-only registers.
    
    Signed-off-by: Alex Williamson <alex.williamson at redhat.com>
    Signed-off-by: Michael S. Tsirkin <mst at redhat.com>

diff --git a/docs/specs/acpi_pci_hotplug.txt b/docs/specs/acpi_pci_hotplug.txt
index f0f74a7..1e2c8a2 100644
--- a/docs/specs/acpi_pci_hotplug.txt
+++ b/docs/specs/acpi_pci_hotplug.txt
@@ -15,14 +15,14 @@ PCI slot injection notification pending (IO port 0xae00-0xae03, 4-byte access):
 Slot injection notification pending. One bit per slot.
 
 Read by ACPI BIOS GPE.1 handler to notify OS of injection
-events.
+events.  Read-only.
 
 PCI slot removal notification (IO port 0xae04-0xae07, 4-byte access):
 -----------------------------------------------------
 Slot removal notification pending. One bit per slot.
 
 Read by ACPI BIOS GPE.1 handler to notify OS of removal
-events.
+events.  Read-only.
 
 PCI device eject (IO port 0xae08-0xae0b, 4-byte access):
 ----------------------------------------
diff --git a/hw/acpi_piix4.c b/hw/acpi_piix4.c
index 797ed24..5e8b261 100644
--- a/hw/acpi_piix4.c
+++ b/hw/acpi_piix4.c
@@ -40,7 +40,8 @@
 
 #define GPE_BASE 0xafe0
 #define GPE_LEN 4
-#define PCI_BASE 0xae00
+#define PCI_UP_BASE 0xae00
+#define PCI_DOWN_BASE 0xae04
 #define PCI_EJ_BASE 0xae08
 #define PCI_RMV_BASE 0xae0c
 
@@ -448,38 +449,22 @@ static void gpe_writeb(void *opaque, uint32_t addr, uint32_t val)
     PIIX4_DPRINTF("gpe write %x <== %d\n", addr, val);
 }
 
-static uint32_t pcihotplug_read(void *opaque, uint32_t addr)
+static uint32_t pci_up_read(void *opaque, uint32_t addr)
 {
-    uint32_t val = 0;
-    struct pci_status *g = opaque;
-    switch (addr) {
-        case PCI_BASE:
-            val = g->up;
-            break;
-        case PCI_BASE + 4:
-            val = g->down;
-            break;
-        default:
-            break;
-    }
+    PIIX4PMState *s = opaque;
+    uint32_t val = s->pci0_status.up;
 
-    PIIX4_DPRINTF("pcihotplug read %x == %x\n", addr, val);
+    PIIX4_DPRINTF("pci_up_read %x\n", val);
     return val;
 }
 
-static void pcihotplug_write(void *opaque, uint32_t addr, uint32_t val)
+static uint32_t pci_down_read(void *opaque, uint32_t addr)
 {
-    struct pci_status *g = opaque;
-    switch (addr) {
-        case PCI_BASE:
-            g->up = val;
-            break;
-        case PCI_BASE + 4:
-            g->down = val;
-            break;
-   }
-
-    PIIX4_DPRINTF("pcihotplug write %x <== %d\n", addr, val);
+    PIIX4PMState *s = opaque;
+    uint32_t val = s->pci0_status.down;
+
+    PIIX4_DPRINTF("pci_down_read %x\n", val);
+    return val;
 }
 
 static uint32_t pciej_read(void *opaque, uint32_t addr)
@@ -523,14 +508,13 @@ static int piix4_device_hotplug(DeviceState *qdev, PCIDevice *dev,
 
 static void piix4_acpi_system_hot_add_init(PCIBus *bus, PIIX4PMState *s)
 {
-    struct pci_status *pci0_status = &s->pci0_status;
 
     register_ioport_write(GPE_BASE, GPE_LEN, 1, gpe_writeb, s);
     register_ioport_read(GPE_BASE, GPE_LEN, 1,  gpe_readb, s);
     acpi_gpe_blk(&s->ar, GPE_BASE);
 
-    register_ioport_write(PCI_BASE, 8, 4, pcihotplug_write, pci0_status);
-    register_ioport_read(PCI_BASE, 8, 4,  pcihotplug_read, pci0_status);
+    register_ioport_read(PCI_UP_BASE, 4, 4, pci_up_read, s);
+    register_ioport_read(PCI_DOWN_BASE, 4, 4, pci_down_read, s);
 
     register_ioport_write(PCI_EJ_BASE, 4, 4, pciej_write, bus);
     register_ioport_read(PCI_EJ_BASE, 4, 4,  pciej_read, bus);
commit da12872a0973718997c00f1c1e8e5b91ee4c713a
Author: Hervé Poussineau <hpoussin at reactos.org>
Date:   Sat Apr 14 22:51:33 2012 +0200

    pcspk: initialize PC speaker if compiled in
    
    PC speaker has been moved to target-independant code in 71093711589dafcb920dc3bc9bb811eaf8b14101,
    so do not depend of target to include it or not.
    
    Cc: malc <av1474 at comtv.ru>
    Cc: Blue Swirl <blauwirbel at gmail.com>
    Signed-off-by: Herv? Poussineau <hpoussin at reactos.org>
    Signed-off-by: malc <av1474 at comtv.ru>

diff --git a/arch_init.c b/arch_init.c
index 595badf..9a35aee 100644
--- a/arch_init.c
+++ b/arch_init.c
@@ -475,7 +475,7 @@ struct soundhw {
 
 static struct soundhw soundhw[] = {
 #ifdef HAS_AUDIO_CHOICE
-#if defined(TARGET_I386) || defined(TARGET_MIPS)
+#ifdef CONFIG_PCSPK
     {
         "pcspk",
         "PC speaker",
commit 2ad596079ecc9b379bcd253157bd0c911058e0e1
Author: Paolo Bonzini <pbonzini at redhat.com>
Date:   Sat Mar 31 12:50:21 2012 +0200

    tests: remove .SECONDARY special target
    
    The special target should not be needed anymore, and caused (perhaps
    due to a Make bug) a failure with "make -j2".  In any case, the
    main makefile is a better place for such special targets rather
    than an included makefile.
    
    Reported-by: Luiz Capitulino <lcapitulino at redhat.com>
    Signed-off-by: Paolo Bonzini <pbonzini at redhat.com>
    Tested-by: Luiz Capitulino <lcapitulino at redhat.com>
    Signed-off-by: Blue Swirl <blauwirbel at gmail.com>

diff --git a/tests/Makefile b/tests/Makefile
index a98a848..baf1d70 100644
--- a/tests/Makefile
+++ b/tests/Makefile
@@ -92,8 +92,6 @@ check-help:
 	@echo "Default options are -k and (for make V=1) --verbose; they can be"
 	@echo "changed with variable GTESTER_OPTIONS."
 
-.SECONDARY:
-
 SPEED = quick
 GTESTER_OPTIONS = -k $(if $(V),--verbose,-q)
 
commit ad4ccc9370339e4f311a9e1d2c7cae77a9d45639
Author: Max Filippov <jcmvbkbc at gmail.com>
Date:   Tue Apr 10 02:48:20 2012 +0400

    target-xtensa: add test for IBREAK invalidation
    
    Signed-off-by: Max Filippov <jcmvbkbc at gmail.com>
    Signed-off-by: Blue Swirl <blauwirbel at gmail.com>

diff --git a/tests/tcg/xtensa/test_break.S b/tests/tcg/xtensa/test_break.S
index 8a8db80..7574cbe 100644
--- a/tests/tcg/xtensa/test_break.S
+++ b/tests/tcg/xtensa/test_break.S
@@ -91,6 +91,40 @@ test ibreak
     assert  eq, a2, a3
 test_end
 
+test ibreak_remove
+    set_vector debug_vector, 3f
+    rsil    a2, debug_level - 1
+    movi    a2, 2f
+    wsr     a2, ibreaka0
+    movi    a3, 1
+1:
+    wsr     a3, ibreakenable
+    isync
+2:
+    beqz    a3, 4f
+    test_fail
+3:
+    assert  eqi, a3, 1
+    rsr     a2, ps
+    movi    a3, 0x1f
+    and     a2, a2, a3
+    movi    a3, 0x10 | debug_level
+    assert  eq, a2, a3
+    rsr     a2, epc6
+    movi    a3, 2b
+    assert  eq, a2, a3
+    rsr     a2, debugcause
+    movi    a3, 0x2
+    assert  eq, a2, a3
+
+    movi    a2, 0x40000
+    wsr     a2, ps
+    isync
+    movi    a3, 0
+    j       1b
+4:
+test_end
+
 test ibreak_priority
     set_vector debug_vector, 2f
     rsil    a2, debug_level - 1
commit ec9fe93efe3a1211caa182771725833bbca733e0
Author: Max Filippov <jcmvbkbc at gmail.com>
Date:   Tue Apr 10 02:48:19 2012 +0400

    target-xtensa: add tests for LBEG/LEND invalidation
    
    Signed-off-by: Max Filippov <jcmvbkbc at gmail.com>
    Signed-off-by: Blue Swirl <blauwirbel at gmail.com>

diff --git a/tests/tcg/xtensa/test_loop.S b/tests/tcg/xtensa/test_loop.S
index a5ea933..5cead47 100644
--- a/tests/tcg/xtensa/test_loop.S
+++ b/tests/tcg/xtensa/test_loop.S
@@ -74,4 +74,54 @@ test loop_excm
     assert  eqi, a2, 1
 test_end
 
+test lbeg_invalidation
+    movi    a2, 0
+    movi    a3, 1
+    movi    a4, 1f
+    movi    a5, 3f
+    wsr     a3, lcount
+    wsr     a4, lbeg
+    wsr     a5, lend
+    isync
+    j       1f
+.align 4
+1:
+    addi    a2, a2, 1
+    j       2f
+.align 4
+2:
+    addi    a2, a2, 2
+    movi    a3, 2b
+    wsr     a3, lbeg
+    isync
+    nop
+3:
+    assert  eqi, a2, 5
+test_end
+
+test lend_invalidation
+    movi    a2, 0
+    movi    a3, 5
+    movi    a4, 1f
+    movi    a5, 2f
+    wsr     a3, lcount
+    wsr     a4, lbeg
+    wsr     a5, lend
+    isync
+    j       1f
+.align 4
+1:
+    addi    a2, a2, 1
+2:
+    beqi    a3, 3, 1f
+    assert  eqi, a2, 6
+    movi    a3, 3
+    wsr     a3, lcount
+    wsr     a4, lend
+    isync
+    j       1b
+1:
+    assert  eqi, a2, 7
+test_end
+
 test_suite_end
commit 3d0be8a5c135dadcfbd68ed354007a8cece98849
Author: Max Filippov <jcmvbkbc at gmail.com>
Date:   Tue Apr 10 02:48:18 2012 +0400

    target-xtensa: fix tb invalidation for IBREAK and LOOP
    
    Instruction breakpoint/zero overhead loop handling code is built into
    TBs pointed to by IBREAKA/LEND SRs. When these or related SRs get
    changed TBs at virtual addresses corresponding to their old and their
    new values must be invalidated.
    
    Virtual address range is passed to the tb_invalidate_phys_page_range,
    which is incorrect in system emulation mode.
    
    To fix it use guest TLB/MMU to translate virtual address to physical
    address.
    
    However the guest may not have virtual-to-physical mapping at the moment
    of IBREAKA/LEND change, thus this fix is not 100% accurate.
    
    Signed-off-by: Max Filippov <jcmvbkbc at gmail.com>
    Signed-off-by: Blue Swirl <blauwirbel at gmail.com>

diff --git a/target-xtensa/op_helper.c b/target-xtensa/op_helper.c
index a6dd72d..364dc19 100644
--- a/target-xtensa/op_helper.c
+++ b/target-xtensa/op_helper.c
@@ -98,6 +98,18 @@ void tlb_fill(CPUXtensaState *env1, target_ulong vaddr, int is_write, int mmu_id
     env = saved_env;
 }
 
+static void tb_invalidate_virtual_addr(CPUXtensaState *env, uint32_t vaddr)
+{
+    uint32_t paddr;
+    uint32_t page_size;
+    unsigned access;
+    int ret = xtensa_get_physical_addr(env, vaddr, 2, 0,
+            &paddr, &page_size, &access);
+    if (ret == 0) {
+        tb_invalidate_phys_addr(paddr);
+    }
+}
+
 void HELPER(exception)(uint32_t excp)
 {
     env->exception_index = excp;
@@ -357,8 +369,7 @@ void HELPER(movsp)(uint32_t pc)
 void HELPER(wsr_lbeg)(uint32_t v)
 {
     if (env->sregs[LBEG] != v) {
-        tb_invalidate_phys_page_range(
-                env->sregs[LEND] - 1, env->sregs[LEND], 0);
+        tb_invalidate_virtual_addr(env, env->sregs[LEND] - 1);
         env->sregs[LBEG] = v;
     }
 }
@@ -366,11 +377,9 @@ void HELPER(wsr_lbeg)(uint32_t v)
 void HELPER(wsr_lend)(uint32_t v)
 {
     if (env->sregs[LEND] != v) {
-        tb_invalidate_phys_page_range(
-                env->sregs[LEND] - 1, env->sregs[LEND], 0);
+        tb_invalidate_virtual_addr(env, env->sregs[LEND] - 1);
         env->sregs[LEND] = v;
-        tb_invalidate_phys_page_range(
-                env->sregs[LEND] - 1, env->sregs[LEND], 0);
+        tb_invalidate_virtual_addr(env, env->sregs[LEND] - 1);
     }
 }
 
@@ -691,8 +700,7 @@ void HELPER(wsr_ibreakenable)(uint32_t v)
 
     for (i = 0; i < env->config->nibreak; ++i) {
         if (change & (1 << i)) {
-            tb_invalidate_phys_page_range(
-                    env->sregs[IBREAKA + i], env->sregs[IBREAKA + i] + 1, 0);
+            tb_invalidate_virtual_addr(env, env->sregs[IBREAKA + i]);
         }
     }
     env->sregs[IBREAKENABLE] = v & ((1 << env->config->nibreak) - 1);
@@ -701,9 +709,8 @@ void HELPER(wsr_ibreakenable)(uint32_t v)
 void HELPER(wsr_ibreaka)(uint32_t i, uint32_t v)
 {
     if (env->sregs[IBREAKENABLE] & (1 << i) && env->sregs[IBREAKA + i] != v) {
-        tb_invalidate_phys_page_range(
-                env->sregs[IBREAKA + i], env->sregs[IBREAKA + i] + 1, 0);
-        tb_invalidate_phys_page_range(v, v + 1, 0);
+        tb_invalidate_virtual_addr(env, env->sregs[IBREAKA + i]);
+        tb_invalidate_virtual_addr(env, v);
     }
     env->sregs[IBREAKA + i] = v;
 }
diff --git a/target-xtensa/translate.c b/target-xtensa/translate.c
index 492dbcc..6900123 100644
--- a/target-xtensa/translate.c
+++ b/target-xtensa/translate.c
@@ -459,11 +459,13 @@ static void gen_rsr(DisasContext *dc, TCGv_i32 d, uint32_t sr)
 static void gen_wsr_lbeg(DisasContext *dc, uint32_t sr, TCGv_i32 s)
 {
     gen_helper_wsr_lbeg(s);
+    gen_jumpi_check_loop_end(dc, 0);
 }
 
 static void gen_wsr_lend(DisasContext *dc, uint32_t sr, TCGv_i32 s)
 {
     gen_helper_wsr_lend(s);
+    gen_jumpi_check_loop_end(dc, 0);
 }
 
 static void gen_wsr_sar(DisasContext *dc, uint32_t sr, TCGv_i32 s)
commit 1e7855a558085d6acd0aba4e3278b594d05df1ec
Author: Max Filippov <jcmvbkbc at gmail.com>
Date:   Tue Apr 10 02:48:17 2012 +0400

    exec: provide tb_invalidate_phys_addr function
    
    Allow TB invalidation by its physical address, extract implementation
    from the breakpoint_invalidate function.
    
    Signed-off-by: Max Filippov <jcmvbkbc at gmail.com>
    Signed-off-by: Blue Swirl <blauwirbel at gmail.com>

diff --git a/exec-all.h b/exec-all.h
index fccce88..6bcc075 100644
--- a/exec-all.h
+++ b/exec-all.h
@@ -102,6 +102,7 @@ void tlb_flush(CPUArchState *env, int flush_global);
 void tlb_set_page(CPUArchState *env, target_ulong vaddr,
                   target_phys_addr_t paddr, int prot,
                   int mmu_idx, target_ulong size);
+void tb_invalidate_phys_addr(target_phys_addr_t addr);
 #endif
 
 #define CODE_GEN_ALIGN           16 /* must be >= of the size of a icache line */
diff --git a/exec.c b/exec.c
index 63a0d2f..68b8a6a 100644
--- a/exec.c
+++ b/exec.c
@@ -1463,13 +1463,11 @@ static void breakpoint_invalidate(CPUArchState *env, target_ulong pc)
     tb_invalidate_phys_page_range(pc, pc + 1, 0);
 }
 #else
-static void breakpoint_invalidate(CPUArchState *env, target_ulong pc)
+void tb_invalidate_phys_addr(target_phys_addr_t addr)
 {
-    target_phys_addr_t addr;
     ram_addr_t ram_addr;
     MemoryRegionSection *section;
 
-    addr = cpu_get_phys_page_debug(env, pc);
     section = phys_page_find(addr >> TARGET_PAGE_BITS);
     if (!(memory_region_is_ram(section->mr)
           || (section->mr->rom_device && section->mr->readable))) {
@@ -1479,6 +1477,11 @@ static void breakpoint_invalidate(CPUArchState *env, target_ulong pc)
         + section_addr(section, addr);
     tb_invalidate_phys_page_range(ram_addr, ram_addr + 1, 0);
 }
+
+static void breakpoint_invalidate(CPUArchState *env, target_ulong pc)
+{
+    tb_invalidate_phys_addr(cpu_get_phys_page_debug(env, pc));
+}
 #endif
 #endif /* TARGET_HAS_ICE */
 
commit 2050396801ca0c8359364d61eaadece951006057
Author: Blue Swirl <blauwirbel at gmail.com>
Date:   Mon Apr 9 14:20:20 2012 +0000

    Use uintptr_t for various op related functions
    
    Use uintptr_t instead of void * or unsigned long in
    several op related functions, env->mem_io_pc and
    GETPC() macro.
    
    Reviewed-by: Stefan Weil <sw at weilnetz.de>
    Signed-off-by: Blue Swirl <blauwirbel at gmail.com>

diff --git a/cpu-defs.h b/cpu-defs.h
index 3268968..88d8093 100644
--- a/cpu-defs.h
+++ b/cpu-defs.h
@@ -166,8 +166,8 @@ typedef struct CPUWatchpoint {
     /* in order to avoid passing too many arguments to the MMIO         \
        helpers, we store some rarely used information in the CPU        \
        context) */                                                      \
-    unsigned long mem_io_pc; /* host pc at which the memory was         \
-                                accessed */                             \
+    uintptr_t mem_io_pc; /* host pc at which the memory was             \
+                            accessed */                                 \
     target_ulong mem_io_vaddr; /* target virtual addr at which the      \
                                      memory was accessed */             \
     uint32_t halted; /* Nonzero if the CPU is in suspend state */       \
diff --git a/exec-all.h b/exec-all.h
index fa7bdfe..fccce88 100644
--- a/exec-all.h
+++ b/exec-all.h
@@ -87,7 +87,7 @@ int cpu_gen_code(CPUArchState *env, struct TranslationBlock *tb,
 int cpu_restore_state(struct TranslationBlock *tb,
                       CPUArchState *env, uintptr_t searched_pc);
 void QEMU_NORETURN cpu_resume_from_signal(CPUArchState *env1, void *puc);
-void QEMU_NORETURN cpu_io_recompile(CPUArchState *env, void *retaddr);
+void QEMU_NORETURN cpu_io_recompile(CPUArchState *env, uintptr_t retaddr);
 TranslationBlock *tb_gen_code(CPUArchState *env, 
                               target_ulong pc, target_ulong cs_base, int flags,
                               int cflags);
@@ -287,13 +287,13 @@ extern void *tci_tb_ptr;
 # endif
 #elif defined(__s390__) && !defined(__s390x__)
 # define GETPC() \
-    ((void *)(((uintptr_t)__builtin_return_address(0) & 0x7fffffffUL) - 1))
+    (((uintptr_t)__builtin_return_address(0) & 0x7fffffffUL) - 1)
 #elif defined(__arm__)
 /* Thumb return addresses have the low bit set, so we need to subtract two.
    This is still safe in ARM mode because instructions are 4 bytes.  */
-# define GETPC() ((void *)((uintptr_t)__builtin_return_address(0) - 2))
+# define GETPC() ((uintptr_t)__builtin_return_address(0) - 2)
 #else
-# define GETPC() ((void *)((uintptr_t)__builtin_return_address(0) - 1))
+# define GETPC() ((uintptr_t)__builtin_return_address(0) - 1)
 #endif
 
 #if !defined(CONFIG_USER_ONLY)
@@ -305,7 +305,7 @@ void io_mem_write(struct MemoryRegion *mr, target_phys_addr_t addr,
                   uint64_t value, unsigned size);
 
 void tlb_fill(CPUArchState *env1, target_ulong addr, int is_write, int mmu_idx,
-              void *retaddr);
+              uintptr_t retaddr);
 
 #include "softmmu_defs.h"
 
diff --git a/exec.c b/exec.c
index 03d3a6b..63a0d2f 100644
--- a/exec.c
+++ b/exec.c
@@ -1221,7 +1221,7 @@ static inline void tb_invalidate_phys_page_fast(tb_page_addr_t start, int len)
 
 #if !defined(CONFIG_SOFTMMU)
 static void tb_invalidate_phys_page(tb_page_addr_t addr,
-                                    unsigned long pc, void *puc)
+                                    uintptr_t pc, void *puc)
 {
     TranslationBlock *tb;
     PageDesc *p;
@@ -4477,20 +4477,20 @@ int cpu_memory_rw_debug(CPUArchState *env, target_ulong addr,
 
 /* in deterministic execution mode, instructions doing device I/Os
    must be at the end of the TB */
-void cpu_io_recompile(CPUArchState *env, void *retaddr)
+void cpu_io_recompile(CPUArchState *env, uintptr_t retaddr)
 {
     TranslationBlock *tb;
     uint32_t n, cflags;
     target_ulong pc, cs_base;
     uint64_t flags;
 
-    tb = tb_find_pc((uintptr_t)retaddr);
+    tb = tb_find_pc(retaddr);
     if (!tb) {
         cpu_abort(env, "cpu_io_recompile: could not find TB for pc=%p", 
-                  retaddr);
+                  (void *)retaddr);
     }
     n = env->icount_decr.u16.low + tb->icount;
-    cpu_restore_state(tb, env, (unsigned long)retaddr);
+    cpu_restore_state(tb, env, retaddr);
     /* Calculate how many instructions had been executed before the fault
        occurred.  */
     n = n - env->icount_decr.u16.low;
@@ -4638,7 +4638,7 @@ bool virtio_is_big_endian(void)
 
 #define MMUSUFFIX _cmmu
 #undef GETPC
-#define GETPC() NULL
+#define GETPC() ((uintptr_t)0)
 #define env cpu_single_env
 #define SOFTMMU_CODE_ACCESS
 
diff --git a/softmmu_template.h b/softmmu_template.h
index afcab1e..b285d78 100644
--- a/softmmu_template.h
+++ b/softmmu_template.h
@@ -69,17 +69,17 @@
 static DATA_TYPE glue(glue(slow_ld, SUFFIX), MMUSUFFIX)(ENV_PARAM
                                                         target_ulong addr,
                                                         int mmu_idx,
-                                                        void *retaddr);
+                                                        uintptr_t retaddr);
 static inline DATA_TYPE glue(io_read, SUFFIX)(ENV_PARAM
                                               target_phys_addr_t physaddr,
                                               target_ulong addr,
-                                              void *retaddr)
+                                              uintptr_t retaddr)
 {
     DATA_TYPE res;
     MemoryRegion *mr = iotlb_to_region(physaddr);
 
     physaddr = (physaddr & TARGET_PAGE_MASK) + addr;
-    env->mem_io_pc = (unsigned long)retaddr;
+    env->mem_io_pc = retaddr;
     if (mr != &io_mem_ram && mr != &io_mem_rom
         && mr != &io_mem_unassigned
         && mr != &io_mem_notdirty
@@ -113,7 +113,7 @@ glue(glue(glue(HELPER_PREFIX, ld), SUFFIX), MMUSUFFIX)(ENV_PARAM
     target_ulong tlb_addr;
     target_phys_addr_t ioaddr;
     unsigned long addend;
-    void *retaddr;
+    uintptr_t retaddr;
 
     /* test if there is match for unaligned or IO access */
     /* XXX: could done more in memory macro in a non portable way */
@@ -166,7 +166,7 @@ static DATA_TYPE
 glue(glue(slow_ld, SUFFIX), MMUSUFFIX)(ENV_PARAM
                                        target_ulong addr,
                                        int mmu_idx,
-                                       void *retaddr)
+                                       uintptr_t retaddr)
 {
     DATA_TYPE res, res1, res2;
     int index, shift;
@@ -219,13 +219,13 @@ static void glue(glue(slow_st, SUFFIX), MMUSUFFIX)(ENV_PARAM
                                                    target_ulong addr,
                                                    DATA_TYPE val,
                                                    int mmu_idx,
-                                                   void *retaddr);
+                                                   uintptr_t retaddr);
 
 static inline void glue(io_write, SUFFIX)(ENV_PARAM
                                           target_phys_addr_t physaddr,
                                           DATA_TYPE val,
                                           target_ulong addr,
-                                          void *retaddr)
+                                          uintptr_t retaddr)
 {
     MemoryRegion *mr = iotlb_to_region(physaddr);
 
@@ -238,7 +238,7 @@ static inline void glue(io_write, SUFFIX)(ENV_PARAM
     }
 
     env->mem_io_vaddr = addr;
-    env->mem_io_pc = (unsigned long)retaddr;
+    env->mem_io_pc = retaddr;
 #if SHIFT <= 2
     io_mem_write(mr, physaddr, val, 1 << SHIFT);
 #else
@@ -260,7 +260,7 @@ void glue(glue(glue(HELPER_PREFIX, st), SUFFIX), MMUSUFFIX)(ENV_PARAM
     target_phys_addr_t ioaddr;
     unsigned long addend;
     target_ulong tlb_addr;
-    void *retaddr;
+    uintptr_t retaddr;
     int index;
 
     index = (addr >> TARGET_PAGE_BITS) & (CPU_TLB_SIZE - 1);
@@ -310,7 +310,7 @@ static void glue(glue(slow_st, SUFFIX), MMUSUFFIX)(ENV_PARAM
                                                    target_ulong addr,
                                                    DATA_TYPE val,
                                                    int mmu_idx,
-                                                   void *retaddr)
+                                                   uintptr_t retaddr)
 {
     target_phys_addr_t ioaddr;
     unsigned long addend;
diff --git a/target-alpha/cpu.h b/target-alpha/cpu.h
index 74bf7f7..fd578ce 100644
--- a/target-alpha/cpu.h
+++ b/target-alpha/cpu.h
@@ -433,9 +433,9 @@ int cpu_alpha_handle_mmu_fault (CPUAlphaState *env, uint64_t address, int rw,
                                 int mmu_idx);
 #define cpu_handle_mmu_fault cpu_alpha_handle_mmu_fault
 void do_interrupt (CPUAlphaState *env);
-void do_restore_state(CPUAlphaState *, void *retaddr);
-void QEMU_NORETURN dynamic_excp(CPUAlphaState *, void *, int, int);
-void QEMU_NORETURN arith_excp(CPUAlphaState *, void *, int, uint64_t);
+void do_restore_state(CPUAlphaState *, uintptr_t retaddr);
+void QEMU_NORETURN dynamic_excp(CPUAlphaState *, uintptr_t, int, int);
+void QEMU_NORETURN arith_excp(CPUAlphaState *, uintptr_t, int, uint64_t);
 
 uint64_t cpu_alpha_load_fpcr (CPUAlphaState *env);
 void cpu_alpha_store_fpcr (CPUAlphaState *env, uint64_t val);
diff --git a/target-alpha/fpu_helper.c b/target-alpha/fpu_helper.c
index dda1103..fe988ec 100644
--- a/target-alpha/fpu_helper.c
+++ b/target-alpha/fpu_helper.c
@@ -44,7 +44,7 @@ uint32_t helper_fp_exc_get(CPUAlphaState *env)
     return get_float_exception_flags(&FP_STATUS);
 }
 
-static inline void inline_fp_exc_raise(CPUAlphaState *env, void *retaddr,
+static inline void inline_fp_exc_raise(CPUAlphaState *env, uintptr_t retaddr,
                                        uint32_t exc, uint32_t regno)
 {
     if (exc) {
@@ -160,7 +160,7 @@ static uint64_t float32_to_f(float32 fa)
     return r;
 }
 
-static float32 f_to_float32(CPUAlphaState *env, void *retaddr, uint64_t a)
+static float32 f_to_float32(CPUAlphaState *env, uintptr_t retaddr, uint64_t a)
 {
     uint32_t exp, mant_sig;
     CPU_FloatU r;
@@ -291,7 +291,7 @@ static uint64_t float64_to_g(float64 fa)
     return r;
 }
 
-static float64 g_to_float64(CPUAlphaState *env, void *retaddr, uint64_t a)
+static float64 g_to_float64(CPUAlphaState *env, uintptr_t retaddr, uint64_t a)
 {
     uint64_t exp, mant_sig;
     CPU_DoubleU r;
diff --git a/target-alpha/helper.c b/target-alpha/helper.c
index 765e650..81d4763 100644
--- a/target-alpha/helper.c
+++ b/target-alpha/helper.c
@@ -494,13 +494,12 @@ void cpu_dump_state (CPUAlphaState *env, FILE *f, fprintf_function cpu_fprintf,
     cpu_fprintf(f, "\n");
 }
 
-void do_restore_state(CPUAlphaState *env, void *retaddr)
+void do_restore_state(CPUAlphaState *env, uintptr_t retaddr)
 {
-    uintptr_t pc = (uintptr_t)retaddr;
-    if (pc) {
-        TranslationBlock *tb = tb_find_pc(pc);
+    if (retaddr) {
+        TranslationBlock *tb = tb_find_pc(retaddr);
         if (tb) {
-            cpu_restore_state(tb, env, pc);
+            cpu_restore_state(tb, env, retaddr);
         }
     }
 }
@@ -515,7 +514,7 @@ void QEMU_NORETURN helper_excp(CPUAlphaState *env, int excp, int error)
 }
 
 /* This may be called from any of the helpers to set up EXCEPTION_INDEX.  */
-void QEMU_NORETURN dynamic_excp(CPUAlphaState *env, void *retaddr,
+void QEMU_NORETURN dynamic_excp(CPUAlphaState *env, uintptr_t retaddr,
                                 int excp, int error)
 {
     env->exception_index = excp;
@@ -524,7 +523,7 @@ void QEMU_NORETURN dynamic_excp(CPUAlphaState *env, void *retaddr,
     cpu_loop_exit(env);
 }
 
-void QEMU_NORETURN arith_excp(CPUAlphaState *env, void *retaddr,
+void QEMU_NORETURN arith_excp(CPUAlphaState *env, uintptr_t retaddr,
                               int exc, uint64_t mask)
 {
     env->trap_arg0 = exc;
diff --git a/target-alpha/mem_helper.c b/target-alpha/mem_helper.c
index dd5ca49..87cada4 100644
--- a/target-alpha/mem_helper.c
+++ b/target-alpha/mem_helper.c
@@ -89,7 +89,7 @@ uint64_t helper_stq_c_phys(CPUAlphaState *env, uint64_t p, uint64_t v)
 }
 
 static void do_unaligned_access(CPUAlphaState *env, target_ulong addr,
-                                int is_write, int is_user, void *retaddr)
+                                int is_write, int is_user, uintptr_t retaddr)
 {
     uint64_t pc;
     uint32_t insn;
@@ -112,7 +112,7 @@ void cpu_unassigned_access(CPUAlphaState *env, target_phys_addr_t addr,
 {
     env->trap_arg0 = addr;
     env->trap_arg1 = is_write;
-    dynamic_excp(env, NULL, EXCP_MCHK, 0);
+    dynamic_excp(env, 0, EXCP_MCHK, 0);
 }
 
 #include "softmmu_exec.h"
@@ -137,7 +137,7 @@ void cpu_unassigned_access(CPUAlphaState *env, target_phys_addr_t addr,
    from generated code or from helper.c) */
 /* XXX: fix it to restore all registers */
 void tlb_fill(CPUAlphaState *env, target_ulong addr, int is_write,
-              int mmu_idx, void *retaddr)
+              int mmu_idx, uintptr_t retaddr)
 {
     int ret;
 
diff --git a/target-arm/op_helper.c b/target-arm/op_helper.c
index c728432..b53369d 100644
--- a/target-arm/op_helper.c
+++ b/target-arm/op_helper.c
@@ -76,11 +76,10 @@ uint32_t HELPER(neon_tbl)(uint32_t ireg, uint32_t def,
    from generated code or from helper.c) */
 /* XXX: fix it to restore all registers */
 void tlb_fill(CPUARMState *env1, target_ulong addr, int is_write, int mmu_idx,
-              void *retaddr)
+              uintptr_t retaddr)
 {
     TranslationBlock *tb;
     CPUARMState *saved_env;
-    unsigned long pc;
     int ret;
 
     saved_env = env;
@@ -89,12 +88,11 @@ void tlb_fill(CPUARMState *env1, target_ulong addr, int is_write, int mmu_idx,
     if (unlikely(ret)) {
         if (retaddr) {
             /* now we have a real cpu fault */
-            pc = (unsigned long)retaddr;
-            tb = tb_find_pc(pc);
+            tb = tb_find_pc(retaddr);
             if (tb) {
                 /* the PC is inside the translated code. It means that we have
                    a virtual CPU fault */
-                cpu_restore_state(tb, env, pc);
+                cpu_restore_state(tb, env, retaddr);
             }
         }
         raise_exception(env->exception_index);
diff --git a/target-cris/op_helper.c b/target-cris/op_helper.c
index c568e2b..b92c106 100644
--- a/target-cris/op_helper.c
+++ b/target-cris/op_helper.c
@@ -57,28 +57,26 @@
    from generated code or from helper.c) */
 /* XXX: fix it to restore all registers */
 void tlb_fill(CPUCRISState *env1, target_ulong addr, int is_write, int mmu_idx,
-              void *retaddr)
+              uintptr_t retaddr)
 {
     TranslationBlock *tb;
     CPUCRISState *saved_env;
-    unsigned long pc;
     int ret;
 
     saved_env = env;
     env = env1;
 
-    D_LOG("%s pc=%x tpc=%x ra=%x\n", __func__, 
-	     env->pc, env->debug1, retaddr);
+    D_LOG("%s pc=%x tpc=%x ra=%p\n", __func__,
+          env->pc, env->debug1, (void *)retaddr);
     ret = cpu_cris_handle_mmu_fault(env, addr, is_write, mmu_idx);
     if (unlikely(ret)) {
         if (retaddr) {
             /* now we have a real cpu fault */
-            pc = (unsigned long)retaddr;
-            tb = tb_find_pc(pc);
+            tb = tb_find_pc(retaddr);
             if (tb) {
                 /* the PC is inside the translated code. It means that we have
                    a virtual CPU fault */
-                cpu_restore_state(tb, env, pc);
+                cpu_restore_state(tb, env, retaddr);
 
 		/* Evaluate flags after retranslation.  */
                 helper_top_evaluate_flags();
diff --git a/target-i386/op_helper.c b/target-i386/op_helper.c
index c04ae44..bc3b94e 100644
--- a/target-i386/op_helper.c
+++ b/target-i386/op_helper.c
@@ -5003,11 +5003,10 @@ void helper_boundl(target_ulong a0, int v)
    from generated code or from helper.c) */
 /* XXX: fix it to restore all registers */
 void tlb_fill(CPUX86State *env1, target_ulong addr, int is_write, int mmu_idx,
-              void *retaddr)
+              uintptr_t retaddr)
 {
     TranslationBlock *tb;
     int ret;
-    unsigned long pc;
     CPUX86State *saved_env;
 
     saved_env = env;
@@ -5017,12 +5016,11 @@ void tlb_fill(CPUX86State *env1, target_ulong addr, int is_write, int mmu_idx,
     if (ret) {
         if (retaddr) {
             /* now we have a real cpu fault */
-            pc = (unsigned long)retaddr;
-            tb = tb_find_pc(pc);
+            tb = tb_find_pc(retaddr);
             if (tb) {
                 /* the PC is inside the translated code. It means that we have
                    a virtual CPU fault */
-                cpu_restore_state(tb, env, pc);
+                cpu_restore_state(tb, env, retaddr);
             }
         }
         raise_exception_err(env->exception_index, env->error_code);
diff --git a/target-lm32/op_helper.c b/target-lm32/op_helper.c
index e9c9638..51edc1a 100644
--- a/target-lm32/op_helper.c
+++ b/target-lm32/op_helper.c
@@ -76,11 +76,10 @@ uint32_t helper_rcsr_jrx(void)
    from generated code or from helper.c) */
 /* XXX: fix it to restore all registers */
 void tlb_fill(CPULM32State *env1, target_ulong addr, int is_write, int mmu_idx,
-              void *retaddr)
+              uintptr_t retaddr)
 {
     TranslationBlock *tb;
     CPULM32State *saved_env;
-    unsigned long pc;
     int ret;
 
     saved_env = env;
@@ -90,12 +89,11 @@ void tlb_fill(CPULM32State *env1, target_ulong addr, int is_write, int mmu_idx,
     if (unlikely(ret)) {
         if (retaddr) {
             /* now we have a real cpu fault */
-            pc = (unsigned long)retaddr;
-            tb = tb_find_pc(pc);
+            tb = tb_find_pc(retaddr);
             if (tb) {
                 /* the PC is inside the translated code. It means that we have
                    a virtual CPU fault */
-                cpu_restore_state(tb, env, pc);
+                cpu_restore_state(tb, env, retaddr);
             }
         }
         cpu_loop_exit(env);
diff --git a/target-m68k/op_helper.c b/target-m68k/op_helper.c
index bc8c1f0..1971a57 100644
--- a/target-m68k/op_helper.c
+++ b/target-m68k/op_helper.c
@@ -56,11 +56,10 @@ extern int semihosting_enabled;
    from generated code or from helper.c) */
 /* XXX: fix it to restore all registers */
 void tlb_fill(CPUM68KState *env1, target_ulong addr, int is_write, int mmu_idx,
-              void *retaddr)
+              uintptr_t retaddr)
 {
     TranslationBlock *tb;
     CPUM68KState *saved_env;
-    unsigned long pc;
     int ret;
 
     saved_env = env;
@@ -69,12 +68,11 @@ void tlb_fill(CPUM68KState *env1, target_ulong addr, int is_write, int mmu_idx,
     if (unlikely(ret)) {
         if (retaddr) {
             /* now we have a real cpu fault */
-            pc = (unsigned long)retaddr;
-            tb = tb_find_pc(pc);
+            tb = tb_find_pc(retaddr);
             if (tb) {
                 /* the PC is inside the translated code. It means that we have
                    a virtual CPU fault */
-                cpu_restore_state(tb, env, pc);
+                cpu_restore_state(tb, env, retaddr);
             }
         }
         cpu_loop_exit(env);
diff --git a/target-microblaze/op_helper.c b/target-microblaze/op_helper.c
index a83da8d..3b1f072 100644
--- a/target-microblaze/op_helper.c
+++ b/target-microblaze/op_helper.c
@@ -44,11 +44,10 @@
    from generated code or from helper.c) */
 /* XXX: fix it to restore all registers */
 void tlb_fill(CPUMBState *env1, target_ulong addr, int is_write, int mmu_idx,
-              void *retaddr)
+              uintptr_t retaddr)
 {
     TranslationBlock *tb;
     CPUMBState *saved_env;
-    unsigned long pc;
     int ret;
 
     saved_env = env;
@@ -58,12 +57,11 @@ void tlb_fill(CPUMBState *env1, target_ulong addr, int is_write, int mmu_idx,
     if (unlikely(ret)) {
         if (retaddr) {
             /* now we have a real cpu fault */
-            pc = (unsigned long)retaddr;
-            tb = tb_find_pc(pc);
+            tb = tb_find_pc(retaddr);
             if (tb) {
                 /* the PC is inside the translated code. It means that we have
                    a virtual CPU fault */
-                cpu_restore_state(tb, env, pc);
+                cpu_restore_state(tb, env, retaddr);
             }
         }
         cpu_loop_exit(env);
diff --git a/target-mips/op_helper.c b/target-mips/op_helper.c
index ce01225..bca1d70 100644
--- a/target-mips/op_helper.c
+++ b/target-mips/op_helper.c
@@ -101,11 +101,10 @@ void helper_raise_exception (uint32_t exception)
 }
 
 #if !defined(CONFIG_USER_ONLY)
-static void do_restore_state (void *pc_ptr)
+static void do_restore_state(uintptr_t pc)
 {
     TranslationBlock *tb;
-    unsigned long pc = (unsigned long) pc_ptr;
-    
+
     tb = tb_find_pc (pc);
     if (tb) {
         cpu_restore_state(tb, env, pc);
@@ -2293,7 +2292,7 @@ void helper_wait (void)
 #if !defined(CONFIG_USER_ONLY)
 
 static void QEMU_NORETURN do_unaligned_access(target_ulong addr, int is_write,
-                                              int is_user, void *retaddr);
+                                              int is_user, uintptr_t retaddr);
 
 #define MMUSUFFIX _mmu
 #define ALIGNED_ONLY
@@ -2310,7 +2309,8 @@ static void QEMU_NORETURN do_unaligned_access(target_ulong addr, int is_write,
 #define SHIFT 3
 #include "softmmu_template.h"
 
-static void do_unaligned_access (target_ulong addr, int is_write, int is_user, void *retaddr)
+static void do_unaligned_access(target_ulong addr, int is_write,
+                                int is_user, uintptr_t retaddr)
 {
     env->CP0_BadVAddr = addr;
     do_restore_state (retaddr);
@@ -2318,11 +2318,10 @@ static void do_unaligned_access (target_ulong addr, int is_write, int is_user, v
 }
 
 void tlb_fill(CPUMIPSState *env1, target_ulong addr, int is_write, int mmu_idx,
-              void *retaddr)
+              uintptr_t retaddr)
 {
     TranslationBlock *tb;
     CPUMIPSState *saved_env;
-    unsigned long pc;
     int ret;
 
     saved_env = env;
@@ -2331,12 +2330,11 @@ void tlb_fill(CPUMIPSState *env1, target_ulong addr, int is_write, int mmu_idx,
     if (ret) {
         if (retaddr) {
             /* now we have a real cpu fault */
-            pc = (unsigned long)retaddr;
-            tb = tb_find_pc(pc);
+            tb = tb_find_pc(retaddr);
             if (tb) {
                 /* the PC is inside the translated code. It means that we have
                    a virtual CPU fault */
-                cpu_restore_state(tb, env, pc);
+                cpu_restore_state(tb, env, retaddr);
             }
         }
         helper_raise_exception_err(env->exception_index, env->error_code);
diff --git a/target-ppc/op_helper.c b/target-ppc/op_helper.c
index 40927b6..4ef2332 100644
--- a/target-ppc/op_helper.c
+++ b/target-ppc/op_helper.c
@@ -3715,11 +3715,10 @@ uint32_t helper_efdcmpeq (uint64_t op1, uint64_t op2)
    from generated code or from helper.c) */
 /* XXX: fix it to restore all registers */
 void tlb_fill(CPUPPCState *env1, target_ulong addr, int is_write, int mmu_idx,
-              void *retaddr)
+              uintptr_t retaddr)
 {
     TranslationBlock *tb;
     CPUPPCState *saved_env;
-    unsigned long pc;
     int ret;
 
     saved_env = env;
@@ -3728,12 +3727,11 @@ void tlb_fill(CPUPPCState *env1, target_ulong addr, int is_write, int mmu_idx,
     if (unlikely(ret != 0)) {
         if (likely(retaddr)) {
             /* now we have a real cpu fault */
-            pc = (unsigned long)retaddr;
-            tb = tb_find_pc(pc);
+            tb = tb_find_pc(retaddr);
             if (likely(tb)) {
                 /* the PC is inside the translated code. It means that we have
                    a virtual CPU fault */
-                cpu_restore_state(tb, env, pc);
+                cpu_restore_state(tb, env, retaddr);
             }
         }
         helper_raise_exception_err(env->exception_index, env->error_code);
diff --git a/target-s390x/op_helper.c b/target-s390x/op_helper.c
index 18fdbb2..7b72473 100644
--- a/target-s390x/op_helper.c
+++ b/target-s390x/op_helper.c
@@ -57,11 +57,10 @@
    from generated code or from helper.c) */
 /* XXX: fix it to restore all registers */
 void tlb_fill(CPUS390XState *env1, target_ulong addr, int is_write, int mmu_idx,
-              void *retaddr)
+              uintptr_t retaddr)
 {
     TranslationBlock *tb;
     CPUS390XState *saved_env;
-    unsigned long pc;
     int ret;
 
     saved_env = env;
@@ -70,12 +69,11 @@ void tlb_fill(CPUS390XState *env1, target_ulong addr, int is_write, int mmu_idx,
     if (unlikely(ret != 0)) {
         if (likely(retaddr)) {
             /* now we have a real cpu fault */
-            pc = (unsigned long)retaddr;
-            tb = tb_find_pc(pc);
+            tb = tb_find_pc(retaddr);
             if (likely(tb)) {
                 /* the PC is inside the translated code. It means that we have
                    a virtual CPU fault */
-                cpu_restore_state(tb, env, pc);
+                cpu_restore_state(tb, env, retaddr);
             }
         }
         cpu_loop_exit(env);
diff --git a/target-sh4/op_helper.c b/target-sh4/op_helper.c
index 30f762f..4054791 100644
--- a/target-sh4/op_helper.c
+++ b/target-sh4/op_helper.c
@@ -22,18 +22,16 @@
 #include "dyngen-exec.h"
 #include "helper.h"
 
-static void cpu_restore_state_from_retaddr(void *retaddr)
+static void cpu_restore_state_from_retaddr(uintptr_t retaddr)
 {
     TranslationBlock *tb;
-    unsigned long pc;
 
     if (retaddr) {
-        pc = (unsigned long) retaddr;
-        tb = tb_find_pc(pc);
+        tb = tb_find_pc(retaddr);
         if (tb) {
             /* the PC is inside the translated code. It means that we have
                a virtual CPU fault */
-            cpu_restore_state(tb, env, pc);
+            cpu_restore_state(tb, env, retaddr);
         }
     }
 }
@@ -56,7 +54,7 @@ static void cpu_restore_state_from_retaddr(void *retaddr)
 #include "softmmu_template.h"
 
 void tlb_fill(CPUSH4State *env1, target_ulong addr, int is_write, int mmu_idx,
-              void *retaddr)
+              uintptr_t retaddr)
 {
     CPUSH4State *saved_env;
     int ret;
@@ -84,7 +82,7 @@ void helper_ldtlb(void)
 #endif
 }
 
-static inline void raise_exception(int index, void *retaddr)
+static inline void raise_exception(int index, uintptr_t retaddr)
 {
     env->exception_index = index;
     cpu_restore_state_from_retaddr(retaddr);
@@ -447,7 +445,7 @@ void helper_ld_fpscr(uint32_t val)
     set_flush_to_zero((val & FPSCR_DN) != 0, &env->fp_status);
 }
 
-static void update_fpscr(void *retaddr)
+static void update_fpscr(uintptr_t retaddr)
 {
     int xcpt, cause, enable;
 
diff --git a/target-sparc/cpu.h b/target-sparc/cpu.h
index 865288c..29c63c7 100644
--- a/target-sparc/cpu.h
+++ b/target-sparc/cpu.h
@@ -702,7 +702,7 @@ trap_state* cpu_tsptr(CPUSPARCState* env);
 #endif
 void QEMU_NORETURN do_unaligned_access(CPUSPARCState *env, target_ulong addr,
                                        int is_write, int is_user,
-                                       void *retaddr);
+                                       uintptr_t retaddr);
 
 #define TB_FLAG_FPU_ENABLED (1 << 4)
 #define TB_FLAG_AM_ENABLED (1 << 5)
diff --git a/target-sparc/ldst_helper.c b/target-sparc/ldst_helper.c
index 1418205..04ffddf 100644
--- a/target-sparc/ldst_helper.c
+++ b/target-sparc/ldst_helper.c
@@ -2376,25 +2376,23 @@ void cpu_unassigned_access(CPUSPARCState *env, target_phys_addr_t addr,
 
 #if !defined(CONFIG_USER_ONLY)
 /* XXX: make it generic ? */
-static void cpu_restore_state2(CPUSPARCState *env, void *retaddr)
+static void cpu_restore_state2(CPUSPARCState *env, uintptr_t retaddr)
 {
     TranslationBlock *tb;
-    unsigned long pc;
 
     if (retaddr) {
         /* now we have a real cpu fault */
-        pc = (unsigned long)retaddr;
-        tb = tb_find_pc(pc);
+        tb = tb_find_pc(retaddr);
         if (tb) {
             /* the PC is inside the translated code. It means that we have
                a virtual CPU fault */
-            cpu_restore_state(tb, env, pc);
+            cpu_restore_state(tb, env, retaddr);
         }
     }
 }
 
 void do_unaligned_access(CPUSPARCState *env, target_ulong addr, int is_write,
-                         int is_user, void *retaddr)
+                         int is_user, uintptr_t retaddr)
 {
 #ifdef DEBUG_UNALIGNED
     printf("Unaligned access to 0x" TARGET_FMT_lx " from 0x" TARGET_FMT_lx
@@ -2409,7 +2407,7 @@ void do_unaligned_access(CPUSPARCState *env, target_ulong addr, int is_write,
    from generated code or from helper.c) */
 /* XXX: fix it to restore all registers */
 void tlb_fill(CPUSPARCState *env, target_ulong addr, int is_write, int mmu_idx,
-              void *retaddr)
+              uintptr_t retaddr)
 {
     int ret;
 
diff --git a/target-xtensa/op_helper.c b/target-xtensa/op_helper.c
index 806384f..a6dd72d 100644
--- a/target-xtensa/op_helper.c
+++ b/target-xtensa/op_helper.c
@@ -31,7 +31,7 @@
 #include "host-utils.h"
 
 static void do_unaligned_access(target_ulong addr, int is_write, int is_user,
-        void *retaddr);
+                                uintptr_t retaddr);
 
 #define ALIGNED_ONLY
 #define MMUSUFFIX _mmu
@@ -48,10 +48,9 @@ static void do_unaligned_access(target_ulong addr, int is_write, int is_user,
 #define SHIFT 3
 #include "softmmu_template.h"
 
-static void do_restore_state(void *pc_ptr)
+static void do_restore_state(uintptr_t pc)
 {
     TranslationBlock *tb;
-    uint32_t pc = (uint32_t)(intptr_t)pc_ptr;
 
     tb = tb_find_pc(pc);
     if (tb) {
@@ -60,7 +59,7 @@ static void do_restore_state(void *pc_ptr)
 }
 
 static void do_unaligned_access(target_ulong addr, int is_write, int is_user,
-        void *retaddr)
+                                uintptr_t retaddr)
 {
     if (xtensa_option_enabled(env->config, XTENSA_OPTION_UNALIGNED_EXCEPTION) &&
             !xtensa_option_enabled(env->config, XTENSA_OPTION_HW_ALIGNMENT)) {
@@ -71,7 +70,7 @@ static void do_unaligned_access(target_ulong addr, int is_write, int is_user,
 }
 
 void tlb_fill(CPUXtensaState *env1, target_ulong vaddr, int is_write, int mmu_idx,
-              void *retaddr)
+              uintptr_t retaddr)
 {
     CPUXtensaState *saved_env = env;
 
diff --git a/user-exec.c b/user-exec.c
index cd905ff..be6bc4f 100644
--- a/user-exec.c
+++ b/user-exec.c
@@ -82,7 +82,7 @@ void cpu_resume_from_signal(CPUArchState *env1, void *puc)
    the effective address of the memory exception. 'is_write' is 1 if a
    write caused the exception and otherwise 0'. 'old_set' is the
    signal set which should be restored */
-static inline int handle_cpu_signal(unsigned long pc, unsigned long address,
+static inline int handle_cpu_signal(uintptr_t pc, unsigned long address,
                                     int is_write, sigset_t *old_set,
                                     void *puc)
 {
commit d1b719e98ce8b506d122a845d405f941a7a497c1
Author: Peter Maydell <peter.maydell at linaro.org>
Date:   Sat Mar 3 04:52:56 2012 +0000

    coroutine-gthread.c: Avoid threading APIs deprecated in GLib 2.31
    
    The GLib threading APIs were revamped in GLib 2.31 and a number
    of the old interfaces were deprecated, which means they provoke
    compilation warnings (errors if -Werror) now. Add support for the
    new interfaces while retaining the old ones so we can still compile
    on older versions of GLib too.
    
    Signed-off-by: Peter Maydell <peter.maydell at linaro.org>
    Signed-off-by: Blue Swirl <blauwirbel at gmail.com>

diff --git a/coroutine-gthread.c b/coroutine-gthread.c
index 662801b..30c24c9 100644
--- a/coroutine-gthread.c
+++ b/coroutine-gthread.c
@@ -26,13 +26,93 @@ typedef struct {
     Coroutine base;
     GThread *thread;
     bool runnable;
+    bool free_on_thread_exit;
     CoroutineAction action;
 } CoroutineGThread;
 
-static GCond *coroutine_cond;
 static GStaticMutex coroutine_lock = G_STATIC_MUTEX_INIT;
+
+/* GLib 2.31 and beyond deprecated various parts of the thread API,
+ * but the new interfaces are not available in older GLib versions
+ * so we have to cope with both.
+ */
+#if GLIB_CHECK_VERSION(2, 31, 0)
+/* Default zero-initialisation is sufficient for 2.31+ GCond */
+static GCond the_coroutine_cond;
+static GCond *coroutine_cond = &the_coroutine_cond;
+static inline void init_coroutine_cond(void)
+{
+}
+
+/* Awkwardly, the GPrivate API doesn't provide a way to update the
+ * GDestroyNotify handler for the coroutine key dynamically. So instead
+ * we track whether or not the CoroutineGThread should be freed on
+ * thread exit / coroutine key update using the free_on_thread_exit
+ * field.
+ */
+static void coroutine_destroy_notify(gpointer data)
+{
+    CoroutineGThread *co = data;
+    if (co && co->free_on_thread_exit) {
+        g_free(co);
+    }
+}
+
+static GPrivate coroutine_key = G_PRIVATE_INIT(coroutine_destroy_notify);
+
+static inline CoroutineGThread *get_coroutine_key(void)
+{
+    return g_private_get(&coroutine_key);
+}
+
+static inline void set_coroutine_key(CoroutineGThread *co,
+                                     bool free_on_thread_exit)
+{
+    /* Unlike g_static_private_set() this does not call the GDestroyNotify
+     * if the previous value of the key was NULL. Fortunately we only need
+     * the GDestroyNotify in the non-NULL key case.
+     */
+    co->free_on_thread_exit = free_on_thread_exit;
+    g_private_replace(&coroutine_key, co);
+}
+
+static inline GThread *create_thread(GThreadFunc func, gpointer data)
+{
+    return g_thread_new("coroutine", func, data);
+}
+
+#else
+
+/* Handle older GLib versions */
+static GCond *coroutine_cond;
+static inline void init_coroutine_cond(void)
+{
+    coroutine_cond = g_cond_new();
+}
+
 static GStaticPrivate coroutine_key = G_STATIC_PRIVATE_INIT;
 
+static inline CoroutineGThread *get_coroutine_key(void)
+{
+    return g_static_private_get(&coroutine_key);
+}
+
+static inline void set_coroutine_key(CoroutineGThread *co,
+                                     bool free_on_thread_exit)
+{
+    g_static_private_set(&coroutine_key, co,
+                         free_on_thread_exit ? (GDestroyNotify)g_free : NULL);
+}
+
+static inline GThread *create_thread(GThreadFunc func, gpointer data)
+{
+    return g_thread_create_full(func, data, 0, TRUE, TRUE,
+                                G_THREAD_PRIORITY_NORMAL, NULL);
+}
+
+#endif
+
+
 static void __attribute__((constructor)) coroutine_init(void)
 {
     if (!g_thread_supported()) {
@@ -44,7 +124,7 @@ static void __attribute__((constructor)) coroutine_init(void)
 #endif
     }
 
-    coroutine_cond = g_cond_new();
+    init_coroutine_cond();
 }
 
 static void coroutine_wait_runnable_locked(CoroutineGThread *co)
@@ -65,7 +145,7 @@ static gpointer coroutine_thread(gpointer opaque)
 {
     CoroutineGThread *co = opaque;
 
-    g_static_private_set(&coroutine_key, co, NULL);
+    set_coroutine_key(co, false);
     coroutine_wait_runnable(co);
     co->base.entry(co->base.entry_arg);
     qemu_coroutine_switch(&co->base, co->base.caller, COROUTINE_TERMINATE);
@@ -77,8 +157,7 @@ Coroutine *qemu_coroutine_new(void)
     CoroutineGThread *co;
 
     co = g_malloc0(sizeof(*co));
-    co->thread = g_thread_create_full(coroutine_thread, co, 0, TRUE, TRUE,
-                                      G_THREAD_PRIORITY_NORMAL, NULL);
+    co->thread = create_thread(coroutine_thread, co);
     if (!co->thread) {
         g_free(co);
         return NULL;
@@ -117,12 +196,11 @@ CoroutineAction qemu_coroutine_switch(Coroutine *from_,
 
 Coroutine *qemu_coroutine_self(void)
 {
-    CoroutineGThread *co = g_static_private_get(&coroutine_key);
-
+    CoroutineGThread *co = get_coroutine_key();
     if (!co) {
         co = g_malloc0(sizeof(*co));
         co->runnable = true;
-        g_static_private_set(&coroutine_key, co, (GDestroyNotify)g_free);
+        set_coroutine_key(co, true);
     }
 
     return &co->base;
@@ -130,7 +208,7 @@ Coroutine *qemu_coroutine_self(void)
 
 bool qemu_in_coroutine(void)
 {
-    CoroutineGThread *co = g_static_private_get(&coroutine_key);
+    CoroutineGThread *co = get_coroutine_key();
 
     return co && co->base.caller;
 }
commit 044c62aaf223b3b5a8eae4f5f79b210a65501e23
Merge: e92861c... e554bbc...
Author: Blue Swirl <blauwirbel at gmail.com>
Date:   Sat Apr 14 10:56:04 2012 +0000

    Merge branch 'xtensa' of git://jcmvbkbc.spb.ru/dumb/qemu-xtensa
    
    * 'xtensa' of git://jcmvbkbc.spb.ru/dumb/qemu-xtensa:
      target-xtensa: Start QOM'ifying CPU init
      target-xtensa: QOM'ify CPU reset
      target-xtensa: QOM'ify CPU
      target-xtensa: improve unit tests debugging
      target-xtensa: Move helpers.h to helper.h

commit e92861ccb166883b0672b1ddfebce4f5de85e23d
Merge: 7672725... c79981c...
Author: Blue Swirl <blauwirbel at gmail.com>
Date:   Sat Apr 14 10:55:00 2012 +0000

    Merge branch 'arm-devs.for-upstream' of git://git.linaro.org/people/pmaydell/qemu-arm
    
    * 'arm-devs.for-upstream' of git://git.linaro.org/people/pmaydell/qemu-arm:
      hw/arm_gic: Remove stray hardcoded tab
      hw/arm_gic: gic_set_pending_private() is NVIC only
      hw/arm_gic: Use NVIC instead of LEGACY_INCLUDED_GIC define
      hw/arm_gic: Make gic_reset a sysbus reset function
      hw/arm11mpcore: Convert to using sysbus GIC device
      hw/exynos4210_gic: Convert to using sysbus GIC
      hw/realview_gic: switch to sysbus GIC
      hw/a9mpcore: Switch to using sysbus GIC
      hw/a15mpcore: switch to using sysbus GIC
      hw/arm_gic: Make the GIC its own sysbus device
      hw/arm_gic: Expose PPI inputs as gpio inputs
      hw/arm_gic: Move gic_get_current_cpu into arm_gic.c
      hw/arm_gic: Move NCPU definition to arm_gic.c
      hw/exynos4210_combiner.c: Drop excessive read/write access check.
      ARM: Exynos4210: Drop gic_cpu_write() after initialization.
      Fix bit test in Exynos4210 UART emulation to use & instead of &&

commit e554bbc6892394e506f5995ff4e0ca21cfe04a25
Author: Andreas Färber <afaerber at suse.de>
Date:   Wed Apr 11 18:24:50 2012 +0200

    target-xtensa: Start QOM'ifying CPU init
    
    Move XtensaConfig-independent code from cpu_xtensa_init() into a
    QOM initfn, as a start.
    
    Signed-off-by: Andreas Färber <afaerber at suse.de>
    Signed-off-by: Max Filippov <jcmvbkbc at gmail.com>

diff --git a/target-xtensa/cpu.c b/target-xtensa/cpu.c
index 55d2dea..97deacb 100644
--- a/target-xtensa/cpu.c
+++ b/target-xtensa/cpu.c
@@ -53,6 +53,14 @@ static void xtensa_cpu_reset(CPUState *s)
     reset_mmu(env);
 }
 
+static void xtensa_cpu_initfn(Object *obj)
+{
+    XtensaCPU *cpu = XTENSA_CPU(obj);
+    CPUXtensaState *env = &cpu->env;
+
+    cpu_exec_init(env);
+}
+
 static void xtensa_cpu_class_init(ObjectClass *oc, void *data)
 {
     CPUClass *cc = CPU_CLASS(oc);
@@ -66,6 +74,7 @@ static const TypeInfo xtensa_cpu_type_info = {
     .name = TYPE_XTENSA_CPU,
     .parent = TYPE_CPU,
     .instance_size = sizeof(XtensaCPU),
+    .instance_init = xtensa_cpu_initfn,
     .abstract = false,
     .class_size = sizeof(XtensaCPUClass),
     .class_init = xtensa_cpu_class_init,
diff --git a/target-xtensa/helper.c b/target-xtensa/helper.c
index 000f965..2094227 100644
--- a/target-xtensa/helper.c
+++ b/target-xtensa/helper.c
@@ -102,7 +102,6 @@ CPUXtensaState *cpu_xtensa_init(const char *cpu_model)
     cpu = XTENSA_CPU(object_new(TYPE_XTENSA_CPU));
     env = &cpu->env;
     env->config = config;
-    cpu_exec_init(env);
 
     if (!tcg_inited) {
         tcg_inited = 1;
commit 5087a72cb3e94f48c1d447babd67e33bfd9dda12
Author: Andreas Färber <afaerber at suse.de>
Date:   Wed Apr 11 18:24:49 2012 +0200

    target-xtensa: QOM'ify CPU reset
    
    Move code from cpu_state_reset() into QOM xtensa_cpu_reset().
    To avoid moving reset_mmu() and dependencies, make it non-static.
    
    Signed-off-by: Andreas Färber <afaerber at suse.de>
    Signed-off-by: Max Filippov <jcmvbkbc at gmail.com>

diff --git a/target-xtensa/cpu.c b/target-xtensa/cpu.c
index d68be22..55d2dea 100644
--- a/target-xtensa/cpu.c
+++ b/target-xtensa/cpu.c
@@ -1,6 +1,7 @@
 /*
  * QEMU Xtensa CPU
  *
+ * Copyright (c) 2011, Max Filippov, Open Source and Linux Lab.
  * Copyright (c) 2012 SUSE LINUX Products GmbH
  * All rights reserved.
  *
@@ -40,7 +41,16 @@ static void xtensa_cpu_reset(CPUState *s)
 
     xcc->parent_reset(s);
 
-    cpu_state_reset(env);
+    env->exception_taken = 0;
+    env->pc = env->config->exception_vector[EXC_RESET];
+    env->sregs[LITBASE] &= ~1;
+    env->sregs[PS] = xtensa_option_enabled(env->config,
+            XTENSA_OPTION_INTERRUPT) ? 0x1f : 0x10;
+    env->sregs[VECBASE] = env->config->vecbase;
+    env->sregs[IBREAKENABLE] = 0;
+
+    env->pending_irq_level = 0;
+    reset_mmu(env);
 }
 
 static void xtensa_cpu_class_init(ObjectClass *oc, void *data)
diff --git a/target-xtensa/cpu.h b/target-xtensa/cpu.h
index 2de5144..6d0ea7c 100644
--- a/target-xtensa/cpu.h
+++ b/target-xtensa/cpu.h
@@ -375,6 +375,7 @@ void xtensa_tlb_set_entry(CPUXtensaState *env, bool dtlb,
 int xtensa_get_physical_addr(CPUXtensaState *env,
         uint32_t vaddr, int is_write, int mmu_idx,
         uint32_t *paddr, uint32_t *page_size, unsigned *access);
+void reset_mmu(CPUXtensaState *env);
 void dump_mmu(FILE *f, fprintf_function cpu_fprintf, CPUXtensaState *env);
 void debug_exception_env(CPUXtensaState *new_env, uint32_t cause);
 
diff --git a/target-xtensa/helper.c b/target-xtensa/helper.c
index 20338e6..000f965 100644
--- a/target-xtensa/helper.c
+++ b/target-xtensa/helper.c
@@ -33,20 +33,9 @@
 #include "hw/loader.h"
 #endif
 
-static void reset_mmu(CPUXtensaState *env);
-
 void cpu_state_reset(CPUXtensaState *env)
 {
-    env->exception_taken = 0;
-    env->pc = env->config->exception_vector[EXC_RESET];
-    env->sregs[LITBASE] &= ~1;
-    env->sregs[PS] = xtensa_option_enabled(env->config,
-            XTENSA_OPTION_INTERRUPT) ? 0x1f : 0x10;
-    env->sregs[VECBASE] = env->config->vecbase;
-    env->sregs[IBREAKENABLE] = 0;
-
-    env->pending_irq_level = 0;
-    reset_mmu(env);
+    cpu_reset(ENV_GET_CPU(env));
 }
 
 static struct XtensaConfigList *xtensa_cores;
@@ -336,7 +325,7 @@ static void reset_tlb_region_way0(CPUXtensaState *env,
     }
 }
 
-static void reset_mmu(CPUXtensaState *env)
+void reset_mmu(CPUXtensaState *env)
 {
     if (xtensa_option_enabled(env->config, XTENSA_OPTION_MMU)) {
         env->sregs[RASID] = 0x04030201;
commit a4633e16d77bd1cf0c25e500d15943499b94f2f9
Author: Andreas Färber <afaerber at suse.de>
Date:   Wed Apr 11 18:24:48 2012 +0200

    target-xtensa: QOM'ify CPU
    
    Embed CPUXtensaState as first member of XtensaCPU.
    Let CPUClass::reset() call cpu_state_reset() for now.
    
    Signed-off-by: Andreas Färber <afaerber at suse.de>
    Signed-off-by: Max Filippov <jcmvbkbc at gmail.com>

diff --git a/Makefile.target b/Makefile.target
index e88b896..75b97ae 100644
--- a/Makefile.target
+++ b/Makefile.target
@@ -102,6 +102,7 @@ endif
 libobj-$(TARGET_SPARC) += int32_helper.o
 libobj-$(TARGET_SPARC64) += int64_helper.o
 libobj-$(TARGET_UNICORE32) += cpu.o
+libobj-$(TARGET_XTENSA) += cpu.o
 libobj-$(TARGET_ALPHA) += int_helper.o fpu_helper.o sys_helper.o mem_helper.o
 
 libobj-y += disas.o
diff --git a/target-xtensa/cpu-qom.h b/target-xtensa/cpu-qom.h
new file mode 100644
index 0000000..1fd2f27
--- /dev/null
+++ b/target-xtensa/cpu-qom.h
@@ -0,0 +1,80 @@
+/*
+ * QEMU Xtensa CPU
+ *
+ * Copyright (c) 2012 SUSE LINUX Products GmbH
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *     * Redistributions of source code must retain the above copyright
+ *       notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above copyright
+ *       notice, this list of conditions and the following disclaimer in the
+ *       documentation and/or other materials provided with the distribution.
+ *     * Neither the name of the Open Source and Linux Lab nor the
+ *       names of its contributors may be used to endorse or promote products
+ *       derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+#ifndef QEMU_XTENSA_CPU_QOM_H
+#define QEMU_XTENSA_CPU_QOM_H
+
+#include "qemu/cpu.h"
+#include "cpu.h"
+
+#define TYPE_XTENSA_CPU "xtensa-cpu"
+
+#define XTENSA_CPU_CLASS(class) \
+    OBJECT_CLASS_CHECK(XtensaCPUClass, (class), TYPE_XTENSA_CPU)
+#define XTENSA_CPU(obj) \
+    OBJECT_CHECK(XtensaCPU, (obj), TYPE_XTENSA_CPU)
+#define XTENSA_CPU_GET_CLASS(obj) \
+    OBJECT_GET_CLASS(XtensaCPUClass, (obj), TYPE_XTENSA_CPU)
+
+/**
+ * XtensaCPUClass:
+ * @parent_reset: The parent class' reset handler.
+ *
+ * An Xtensa CPU model.
+ */
+typedef struct XtensaCPUClass {
+    /*< private >*/
+    CPUClass parent_class;
+    /*< public >*/
+
+    void (*parent_reset)(CPUState *cpu);
+} XtensaCPUClass;
+
+/**
+ * XtensaCPU:
+ * @env: #CPUXtensaState
+ *
+ * An Xtensa CPU.
+ */
+typedef struct XtensaCPU {
+    /*< private >*/
+    CPUState parent_obj;
+    /*< public >*/
+
+    CPUXtensaState env;
+} XtensaCPU;
+
+static inline XtensaCPU *xtensa_env_get_cpu(const CPUXtensaState *env)
+{
+    return XTENSA_CPU(container_of(env, XtensaCPU, env));
+}
+
+#define ENV_GET_CPU(e) CPU(xtensa_env_get_cpu(e))
+
+
+#endif
diff --git a/target-xtensa/cpu.c b/target-xtensa/cpu.c
new file mode 100644
index 0000000..d68be22
--- /dev/null
+++ b/target-xtensa/cpu.c
@@ -0,0 +1,69 @@
+/*
+ * QEMU Xtensa CPU
+ *
+ * Copyright (c) 2012 SUSE LINUX Products GmbH
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *     * Redistributions of source code must retain the above copyright
+ *       notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above copyright
+ *       notice, this list of conditions and the following disclaimer in the
+ *       documentation and/or other materials provided with the distribution.
+ *     * Neither the name of the Open Source and Linux Lab nor the
+ *       names of its contributors may be used to endorse or promote products
+ *       derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "cpu-qom.h"
+#include "qemu-common.h"
+
+
+/* CPUClass::reset() */
+static void xtensa_cpu_reset(CPUState *s)
+{
+    XtensaCPU *cpu = XTENSA_CPU(s);
+    XtensaCPUClass *xcc = XTENSA_CPU_GET_CLASS(cpu);
+    CPUXtensaState *env = &cpu->env;
+
+    xcc->parent_reset(s);
+
+    cpu_state_reset(env);
+}
+
+static void xtensa_cpu_class_init(ObjectClass *oc, void *data)
+{
+    CPUClass *cc = CPU_CLASS(oc);
+    XtensaCPUClass *xcc = XTENSA_CPU_CLASS(cc);
+
+    xcc->parent_reset = cc->reset;
+    cc->reset = xtensa_cpu_reset;
+}
+
+static const TypeInfo xtensa_cpu_type_info = {
+    .name = TYPE_XTENSA_CPU,
+    .parent = TYPE_CPU,
+    .instance_size = sizeof(XtensaCPU),
+    .abstract = false,
+    .class_size = sizeof(XtensaCPUClass),
+    .class_init = xtensa_cpu_class_init,
+};
+
+static void xtensa_cpu_register_types(void)
+{
+    type_register_static(&xtensa_cpu_type_info);
+}
+
+type_init(xtensa_cpu_register_types)
diff --git a/target-xtensa/cpu.h b/target-xtensa/cpu.h
index a7bcf52..2de5144 100644
--- a/target-xtensa/cpu.h
+++ b/target-xtensa/cpu.h
@@ -470,6 +470,7 @@ static inline void cpu_get_tb_cpu_state(CPUXtensaState *env, target_ulong *pc,
 }
 
 #include "cpu-all.h"
+#include "cpu-qom.h"
 #include "exec-all.h"
 
 static inline int cpu_has_work(CPUXtensaState *env)
diff --git a/target-xtensa/helper.c b/target-xtensa/helper.c
index dab135c..20338e6 100644
--- a/target-xtensa/helper.c
+++ b/target-xtensa/helper.c
@@ -95,6 +95,7 @@ CPUXtensaState *cpu_xtensa_init(const char *cpu_model)
 {
     static int tcg_inited;
     static int debug_handler_inited;
+    XtensaCPU *cpu;
     CPUXtensaState *env;
     const XtensaConfig *config = NULL;
     XtensaConfigList *core = xtensa_cores;
@@ -109,7 +110,8 @@ CPUXtensaState *cpu_xtensa_init(const char *cpu_model)
         return NULL;
     }
 
-    env = g_malloc0(sizeof(*env));
+    cpu = XTENSA_CPU(object_new(TYPE_XTENSA_CPU));
+    env = &cpu->env;
     env->config = config;
     cpu_exec_init(env);
 
commit 7d6b9f0a3838632b4c553e0a387af0bbdf4297c0
Author: Max Filippov <jcmvbkbc at gmail.com>
Date:   Fri Mar 16 01:24:57 2012 +0400

    target-xtensa: improve unit tests debugging
    
    - add testcase announcement;
    - add global symbols for individual tests;
    - add host-debug-* makefile target.
    
    Signed-off-by: Max Filippov <jcmvbkbc at gmail.com>

diff --git a/tests/tcg/xtensa/Makefile b/tests/tcg/xtensa/Makefile
index 7e1e619..0ff0ccf 100644
--- a/tests/tcg/xtensa/Makefile
+++ b/tests/tcg/xtensa/Makefile
@@ -72,5 +72,8 @@ run-test_fail.tst: test_fail.tst
 debug-%.tst: %.tst
 	$(SIM) $(SIMDEBUG) $(SIMFLAGS) ./$<
 
+host-debug-%.tst: %.tst
+	gdb --args $(SIM) $(SIMFLAGS) ./$<
+
 clean:
 	$(RM) -fr $(TESTCASES) $(CRT)
diff --git a/tests/tcg/xtensa/macros.inc b/tests/tcg/xtensa/macros.inc
index 2d4515e..23bf3e9 100644
--- a/tests/tcg/xtensa/macros.inc
+++ b/tests/tcg/xtensa/macros.inc
@@ -29,7 +29,24 @@ main:
     exit
 .endm
 
+.macro print text
+.data
+97: .ascii "\text\n"
+98:
+    .align 4
+.text
+    movi    a2, 4
+    movi    a3, 2
+    movi    a4, 97b
+    movi    a5, 98b
+    sub     a5, a5, a4
+    simcall
+.endm
+
 .macro test name
+    //print test_\name
+test_\name:
+.global test_\name
 .endm
 
 .macro test_end
commit 16c1deae215d4aac5b9b4fc090844b92852a0c5b
Author: Lluís Vilanova <vilanova at ac.upc.edu>
Date:   Mon Feb 13 16:33:58 2012 +0100

    target-xtensa: Move helpers.h to helper.h
    
    Provides a file naming scheme consistent with other targets.
    
    Signed-off-by: Lluís Vilanova <vilanova at ac.upc.edu>
    Signed-off-by: Max Filippov <jcmvbkbc at gmail.com>

diff --git a/target-xtensa/helper.h b/target-xtensa/helper.h
new file mode 100644
index 0000000..48a741e
--- /dev/null
+++ b/target-xtensa/helper.h
@@ -0,0 +1,39 @@
+#include "def-helper.h"
+
+DEF_HELPER_1(exception, void, i32)
+DEF_HELPER_2(exception_cause, void, i32, i32)
+DEF_HELPER_3(exception_cause_vaddr, void, i32, i32, i32)
+DEF_HELPER_2(debug_exception, void, i32, i32)
+
+DEF_HELPER_1(nsa, i32, i32)
+DEF_HELPER_1(nsau, i32, i32)
+DEF_HELPER_1(wsr_windowbase, void, i32)
+DEF_HELPER_3(entry, void, i32, i32, i32)
+DEF_HELPER_1(retw, i32, i32)
+DEF_HELPER_1(rotw, void, i32)
+DEF_HELPER_2(window_check, void, i32, i32)
+DEF_HELPER_0(restore_owb, void)
+DEF_HELPER_1(movsp, void, i32)
+DEF_HELPER_1(wsr_lbeg, void, i32)
+DEF_HELPER_1(wsr_lend, void, i32)
+DEF_HELPER_1(simcall, void, env)
+DEF_HELPER_0(dump_state, void)
+
+DEF_HELPER_2(waiti, void, i32, i32)
+DEF_HELPER_2(timer_irq, void, i32, i32)
+DEF_HELPER_1(advance_ccount, void, i32)
+DEF_HELPER_1(check_interrupts, void, env)
+
+DEF_HELPER_1(wsr_rasid, void, i32)
+DEF_HELPER_2(rtlb0, i32, i32, i32)
+DEF_HELPER_2(rtlb1, i32, i32, i32)
+DEF_HELPER_2(itlb, void, i32, i32)
+DEF_HELPER_2(ptlb, i32, i32, i32)
+DEF_HELPER_3(wtlb, void, i32, i32, i32)
+
+DEF_HELPER_1(wsr_ibreakenable, void, i32)
+DEF_HELPER_2(wsr_ibreaka, void, i32, i32)
+DEF_HELPER_2(wsr_dbreaka, void, i32, i32)
+DEF_HELPER_2(wsr_dbreakc, void, i32, i32)
+
+#include "def-helper.h"
diff --git a/target-xtensa/helpers.h b/target-xtensa/helpers.h
deleted file mode 100644
index 48a741e..0000000
--- a/target-xtensa/helpers.h
+++ /dev/null
@@ -1,39 +0,0 @@
-#include "def-helper.h"
-
-DEF_HELPER_1(exception, void, i32)
-DEF_HELPER_2(exception_cause, void, i32, i32)
-DEF_HELPER_3(exception_cause_vaddr, void, i32, i32, i32)
-DEF_HELPER_2(debug_exception, void, i32, i32)
-
-DEF_HELPER_1(nsa, i32, i32)
-DEF_HELPER_1(nsau, i32, i32)
-DEF_HELPER_1(wsr_windowbase, void, i32)
-DEF_HELPER_3(entry, void, i32, i32, i32)
-DEF_HELPER_1(retw, i32, i32)
-DEF_HELPER_1(rotw, void, i32)
-DEF_HELPER_2(window_check, void, i32, i32)
-DEF_HELPER_0(restore_owb, void)
-DEF_HELPER_1(movsp, void, i32)
-DEF_HELPER_1(wsr_lbeg, void, i32)
-DEF_HELPER_1(wsr_lend, void, i32)
-DEF_HELPER_1(simcall, void, env)
-DEF_HELPER_0(dump_state, void)
-
-DEF_HELPER_2(waiti, void, i32, i32)
-DEF_HELPER_2(timer_irq, void, i32, i32)
-DEF_HELPER_1(advance_ccount, void, i32)
-DEF_HELPER_1(check_interrupts, void, env)
-
-DEF_HELPER_1(wsr_rasid, void, i32)
-DEF_HELPER_2(rtlb0, i32, i32, i32)
-DEF_HELPER_2(rtlb1, i32, i32, i32)
-DEF_HELPER_2(itlb, void, i32, i32)
-DEF_HELPER_2(ptlb, i32, i32, i32)
-DEF_HELPER_3(wtlb, void, i32, i32, i32)
-
-DEF_HELPER_1(wsr_ibreakenable, void, i32)
-DEF_HELPER_2(wsr_ibreaka, void, i32, i32)
-DEF_HELPER_2(wsr_dbreaka, void, i32, i32)
-DEF_HELPER_2(wsr_dbreakc, void, i32, i32)
-
-#include "def-helper.h"
diff --git a/target-xtensa/op_helper.c b/target-xtensa/op_helper.c
index cdef0db..806384f 100644
--- a/target-xtensa/op_helper.c
+++ b/target-xtensa/op_helper.c
@@ -27,7 +27,7 @@
 
 #include "cpu.h"
 #include "dyngen-exec.h"
-#include "helpers.h"
+#include "helper.h"
 #include "host-utils.h"
 
 static void do_unaligned_access(target_ulong addr, int is_write, int is_user,
diff --git a/target-xtensa/translate.c b/target-xtensa/translate.c
index e0ff72b..492dbcc 100644
--- a/target-xtensa/translate.c
+++ b/target-xtensa/translate.c
@@ -37,9 +37,9 @@
 #include "qemu-log.h"
 #include "sysemu.h"
 
-#include "helpers.h"
+#include "helper.h"
 #define GEN_HELPER 1
-#include "helpers.h"
+#include "helper.h"
 
 typedef struct DisasContext {
     const XtensaConfig *config;
@@ -183,7 +183,7 @@ void xtensa_translate_init(void)
         }
     }
 #define GEN_HELPER 2
-#include "helpers.h"
+#include "helper.h"
 }
 
 static inline bool option_bits_enabled(DisasContext *dc, uint64_t opt)
diff --git a/xtensa-semi.c b/xtensa-semi.c
index 5754b77..b7c8c34 100644
--- a/xtensa-semi.c
+++ b/xtensa-semi.c
@@ -31,7 +31,7 @@
 #include <stddef.h>
 #include "cpu.h"
 #include "dyngen-exec.h"
-#include "helpers.h"
+#include "helper.h"
 #include "qemu-log.h"
 
 enum {
commit fda1f7684935ae7290c8a31e3ba9fdb30eead4ed
Author: Stefano Stabellini <stefano.stabellini at eu.citrix.com>
Date:   Fri Apr 13 17:46:01 2012 +0000

    xen: introduce an event channel for buffered io event notifications
    
    Use the newly introduced HVM_PARAM_BUFIOREQ_EVTCHN to receive
    notifications for buffered io events.
    After the first notification is received leave the event channel masked
    and setup a timer to process the rest of the batch.
    Once we have completed processing the batch, unmask the event channel
    and delete the timer.
    
    Signed-off-by: Stefano Stabellini <stefano.stabellini at eu.citrix.com>

diff --git a/xen-all.c b/xen-all.c
index abd2b2d..a08eec0 100644
--- a/xen-all.c
+++ b/xen-all.c
@@ -59,6 +59,9 @@ static inline ioreq_t *xen_vcpu_ioreq(shared_iopage_t *shared_page, int vcpu)
 }
 #  define FMT_ioreq_size "u"
 #endif
+#ifndef HVM_PARAM_BUFIOREQ_EVTCHN
+#define HVM_PARAM_BUFIOREQ_EVTCHN 26
+#endif
 
 #define BUFFER_IO_MAX_DELAY  100
 
@@ -77,6 +80,8 @@ typedef struct XenIOState {
     QEMUTimer *buffered_io_timer;
     /* the evtchn port for polling the notification, */
     evtchn_port_t *ioreq_local_port;
+    /* evtchn local port for buffered io */
+    evtchn_port_t bufioreq_local_port;
     /* the evtchn fd for polling */
     XenEvtchn xce_handle;
     /* which vcpu we are serving */
@@ -629,6 +634,12 @@ static ioreq_t *cpu_get_ioreq(XenIOState *state)
     evtchn_port_t port;
 
     port = xc_evtchn_pending(state->xce_handle);
+    if (port == state->bufioreq_local_port) {
+        qemu_mod_timer(state->buffered_io_timer,
+                BUFFER_IO_MAX_DELAY + qemu_get_clock_ms(rt_clock));
+        return NULL;
+    }
+
     if (port != -1) {
         for (i = 0; i < smp_cpus; i++) {
             if (state->ioreq_local_port[i] == port) {
@@ -777,16 +788,18 @@ static void handle_ioreq(ioreq_t *req)
     }
 }
 
-static void handle_buffered_iopage(XenIOState *state)
+static int handle_buffered_iopage(XenIOState *state)
 {
     buf_ioreq_t *buf_req = NULL;
     ioreq_t req;
     int qw;
 
     if (!state->buffered_io_page) {
-        return;
+        return 0;
     }
 
+    memset(&req, 0x00, sizeof(req));
+
     while (state->buffered_io_page->read_pointer != state->buffered_io_page->write_pointer) {
         buf_req = &state->buffered_io_page->buf_ioreq[
             state->buffered_io_page->read_pointer % IOREQ_BUFFER_SLOT_NUM];
@@ -811,15 +824,21 @@ static void handle_buffered_iopage(XenIOState *state)
         xen_mb();
         state->buffered_io_page->read_pointer += qw ? 2 : 1;
     }
+
+    return req.count;
 }
 
 static void handle_buffered_io(void *opaque)
 {
     XenIOState *state = opaque;
 
-    handle_buffered_iopage(state);
-    qemu_mod_timer(state->buffered_io_timer,
-                   BUFFER_IO_MAX_DELAY + qemu_get_clock_ms(rt_clock));
+    if (handle_buffered_iopage(state)) {
+        qemu_mod_timer(state->buffered_io_timer,
+                BUFFER_IO_MAX_DELAY + qemu_get_clock_ms(rt_clock));
+    } else {
+        qemu_del_timer(state->buffered_io_timer);
+        xc_evtchn_unmask(state->xce_handle, state->bufioreq_local_port);
+    }
 }
 
 static void cpu_handle_ioreq(void *opaque)
@@ -949,7 +968,6 @@ static void xen_main_loop_prepare(XenIOState *state)
 
     state->buffered_io_timer = qemu_new_timer_ms(rt_clock, handle_buffered_io,
                                                  state);
-    qemu_mod_timer(state->buffered_io_timer, qemu_get_clock_ms(rt_clock));
 
     if (evtchn_fd != -1) {
         qemu_set_fd_handler(evtchn_fd, cpu_handle_ioreq, NULL, state);
@@ -1050,6 +1068,7 @@ int xen_hvm_init(void)
 {
     int i, rc;
     unsigned long ioreq_pfn;
+    unsigned long bufioreq_evtchn;
     XenIOState *state;
 
     state = g_malloc0(sizeof (XenIOState));
@@ -1102,6 +1121,20 @@ int xen_hvm_init(void)
         state->ioreq_local_port[i] = rc;
     }
 
+    rc = xc_get_hvm_param(xen_xc, xen_domid, HVM_PARAM_BUFIOREQ_EVTCHN,
+            &bufioreq_evtchn);
+    if (rc < 0) {
+        fprintf(stderr, "failed to get HVM_PARAM_BUFIOREQ_EVTCHN\n");
+        return -1;
+    }
+    rc = xc_evtchn_bind_interdomain(state->xce_handle, xen_domid,
+            (uint32_t)bufioreq_evtchn);
+    if (rc == -1) {
+        fprintf(stderr, "bind interdomain ioctl error %d\n", errno);
+        return -1;
+    }
+    state->bufioreq_local_port = rc;
+
     /* Init RAM management */
     xen_map_cache_init(xen_phys_offset_to_gaddr, state);
     xen_ram_init(ram_size);
commit 852a7cec90f12516eb335bb29ed1398c2f0b7c2c
Author: Julien Grall <julien.grall at citrix.com>
Date:   Fri Apr 13 17:33:02 2012 +0000

    xen-mapcache: don't unmap locked entry during mapcache invalidation
    
    When an IOREQ_TYPE_INVALIDATE is sent to QEMU, it invalidates all entry
    of the map cache even if it's locked.
    
    QEMU is not able to know that entry was invalidated, so when an IO
    access is requested a segfault occured.
    
    Signed-off-by: Julien Grall <julien.grall at citrix.com>
    Signed-off-by: Stefano Stabellini <stefano.stabellini at eu.citrix.com>

diff --git a/xen-mapcache.c b/xen-mapcache.c
index 75ac313..59ba085 100644
--- a/xen-mapcache.c
+++ b/xen-mapcache.c
@@ -387,6 +387,9 @@ void xen_invalidate_map_cache(void)
         if (entry->vaddr_base == NULL) {
             continue;
         }
+        if (entry->lock > 0) {
+            continue;
+        }
 
         if (munmap(entry->vaddr_base, entry->size) != 0) {
             perror("unmap fails");
commit 09ab48ee6c7ec082f56f85e234b066ed4fd874e2
Author: Anthony PERARD <anthony.perard at citrix.com>
Date:   Fri Apr 13 17:18:56 2012 +0000

    Xen, mapcache: Fix the compute of the size of bucket.
    
    Because the size of a mapping is wrong when there is an offset and a
    size >= bucket_size.
    
    Signed-off-by: Anthony PERARD <anthony.perard at citrix.com>
    Signed-off-by: Stefano Stabellini <stefano.stabellini at eu.citrix.com>

diff --git a/xen-mapcache.c b/xen-mapcache.c
index a456479..75ac313 100644
--- a/xen-mapcache.c
+++ b/xen-mapcache.c
@@ -216,12 +216,14 @@ tryagain:
     }
 
     /* size is always a multiple of MCACHE_BUCKET_SIZE */
-    if ((address_offset + (__size % MCACHE_BUCKET_SIZE)) > MCACHE_BUCKET_SIZE)
-        __size += MCACHE_BUCKET_SIZE;
-    if (__size % MCACHE_BUCKET_SIZE)
-        __size += MCACHE_BUCKET_SIZE - (__size % MCACHE_BUCKET_SIZE);
-    if (!__size)
+    if (size) {
+        __size = size + address_offset;
+        if (__size % MCACHE_BUCKET_SIZE) {
+            __size += MCACHE_BUCKET_SIZE - (__size % MCACHE_BUCKET_SIZE);
+        }
+    } else {
         __size = MCACHE_BUCKET_SIZE;
+    }
 
     entry = &mapcache->entry[address_index % mapcache->nr_buckets];
 
commit 77ba8fef8972854b7fad89d97a14f4f9c3eae7a8
Author: Stefano Stabellini <stefano.stabellini at eu.citrix.com>
Date:   Fri Mar 30 14:33:03 2012 +0000

    xen: handle backend deletion from xenstore
    
    Signed-off-by: Stefano Stabellini <stefano.stabellini at eu.citrix.com>

diff --git a/hw/xen_backend.c b/hw/xen_backend.c
index 2673ace..66cb144 100644
--- a/hw/xen_backend.c
+++ b/hw/xen_backend.c
@@ -592,7 +592,7 @@ static void xenstore_update_be(char *watch, char *type, int dom,
                                struct XenDevOps *ops)
 {
     struct XenDevice *xendev;
-    char path[XEN_BUFSIZE], *dom0;
+    char path[XEN_BUFSIZE], *dom0, *bepath;
     unsigned int len, dev;
 
     dom0 = xs_get_domain_path(xenstore, 0);
@@ -611,15 +611,16 @@ static void xenstore_update_be(char *watch, char *type, int dom,
         return;
     }
 
-    if (0) {
-        /* FIXME: detect devices being deleted from xenstore ... */
-        xen_be_del_xendev(dom, dev);
-    }
-
     xendev = xen_be_get_xendev(type, dom, dev, ops);
     if (xendev != NULL) {
-        xen_be_backend_changed(xendev, path);
-        xen_be_check_state(xendev);
+        bepath = xs_read(xenstore, 0, xendev->be, &len);
+        if (bepath == NULL) {
+            xen_be_del_xendev(dom, dev);
+        } else {
+            free(bepath);
+            xen_be_backend_changed(xendev, path);
+            xen_be_check_state(xendev);
+        }
     }
 }
 
diff --git a/hw/xen_disk.c b/hw/xen_disk.c
index 9719395..22dbd10 100644
--- a/hw/xen_disk.c
+++ b/hw/xen_disk.c
@@ -745,6 +745,10 @@ static int blk_free(struct XenDevice *xendev)
     struct XenBlkDev *blkdev = container_of(xendev, struct XenBlkDev, xendev);
     struct ioreq *ioreq;
 
+    if (blkdev->bs || blkdev->sring) {
+        blk_disconnect(xendev);
+    }
+
     while (!QLIST_EMPTY(&blkdev->freelist)) {
         ioreq = QLIST_FIRST(&blkdev->freelist);
         QLIST_REMOVE(ioreq, list);
commit 9468e9c41a89b1c9f3a905b8959e1dd3f055c732
Author: Wei Liu <wei.liu2 at citrix.com>
Date:   Thu Apr 12 10:02:47 2012 +0000

    Xen: Add xen-apic support and hook it up.
    
    Signed-off-by: Wei Liu <wei.liu2 at citrix.com>
    Signed-off-by: Stefano Stabellini <stefano.stabellini at eu.citrix.com>
    Acked-by: Paolo Bonzini <pbonzini at redhat.com>

diff --git a/Makefile.target b/Makefile.target
index e88b896..f9ce361 100644
--- a/Makefile.target
+++ b/Makefile.target
@@ -237,7 +237,7 @@ QEMU_CFLAGS += $(VNC_PNG_CFLAGS)
 obj-$(CONFIG_XEN) += xen-all.o xen_machine_pv.o xen_domainbuild.o xen-mapcache.o
 obj-$(CONFIG_NO_XEN) += xen-stub.o
 
-obj-i386-$(CONFIG_XEN) += xen_platform.o
+obj-i386-$(CONFIG_XEN) += xen_platform.o xen_apic.o
 
 # Inter-VM PCI shared memory
 CONFIG_IVSHMEM =
diff --git a/hw/pc.c b/hw/pc.c
index 67f0479..1f5aacb 100644
--- a/hw/pc.c
+++ b/hw/pc.c
@@ -42,6 +42,7 @@
 #include "sysbus.h"
 #include "sysemu.h"
 #include "kvm.h"
+#include "xen.h"
 #include "blockdev.h"
 #include "ui/qemu-spice.h"
 #include "memory.h"
@@ -891,9 +892,12 @@ static DeviceState *apic_init(void *env, uint8_t apic_id)
 
     if (kvm_irqchip_in_kernel()) {
         dev = qdev_create(NULL, "kvm-apic");
+    } else if (xen_enabled()) {
+        dev = qdev_create(NULL, "xen-apic");
     } else {
         dev = qdev_create(NULL, "apic");
     }
+
     qdev_prop_set_uint8(dev, "id", apic_id);
     qdev_prop_set_ptr(dev, "cpu_env", env);
     qdev_init_nofail(dev);
@@ -912,6 +916,10 @@ static DeviceState *apic_init(void *env, uint8_t apic_id)
         msi_supported = true;
     }
 
+    if (xen_enabled()) {
+        msi_supported = true;
+    }
+
     return dev;
 }
 
diff --git a/hw/xen_apic.c b/hw/xen_apic.c
new file mode 100644
index 0000000..1725ff6
--- /dev/null
+++ b/hw/xen_apic.c
@@ -0,0 +1,90 @@
+/*
+ * Xen basic APIC support
+ *
+ * Copyright (c) 2012 Citrix
+ *
+ * Authors:
+ *  Wei Liu <wei.liu2 at citrix.com>
+ *
+ * This work is licensed under the terms of the GNU GPL version 2 or
+ * later. See the COPYING file in the top-level directory.
+ */
+#include "hw/apic_internal.h"
+#include "hw/msi.h"
+#include "xen.h"
+
+static uint64_t xen_apic_mem_read(void *opaque, target_phys_addr_t addr,
+                                  unsigned size)
+{
+    return ~(uint64_t)0;
+}
+
+static void xen_apic_mem_write(void *opaque, target_phys_addr_t addr,
+                               uint64_t data, unsigned size)
+{
+    if (size != sizeof(uint32_t)) {
+        fprintf(stderr, "Xen: APIC write data size = %d, invalid\n", size);
+        return;
+    }
+
+    xen_hvm_inject_msi(addr, data);
+}
+
+static const MemoryRegionOps xen_apic_io_ops = {
+    .read = xen_apic_mem_read,
+    .write = xen_apic_mem_write,
+    .endianness = DEVICE_NATIVE_ENDIAN,
+};
+
+static void xen_apic_init(APICCommonState *s)
+{
+    memory_region_init_io(&s->io_memory, &xen_apic_io_ops, s, "xen-apic-msi",
+                          MSI_SPACE_SIZE);
+}
+
+static void xen_apic_set_base(APICCommonState *s, uint64_t val)
+{
+}
+
+static void xen_apic_set_tpr(APICCommonState *s, uint8_t val)
+{
+}
+
+static uint8_t xen_apic_get_tpr(APICCommonState *s)
+{
+    return 0;
+}
+
+static void xen_apic_vapic_base_update(APICCommonState *s)
+{
+}
+
+static void xen_apic_external_nmi(APICCommonState *s)
+{
+}
+
+static void xen_apic_class_init(ObjectClass *klass, void *data)
+{
+    APICCommonClass *k = APIC_COMMON_CLASS(klass);
+
+    k->init = xen_apic_init;
+    k->set_base = xen_apic_set_base;
+    k->set_tpr = xen_apic_set_tpr;
+    k->get_tpr = xen_apic_get_tpr;
+    k->vapic_base_update = xen_apic_vapic_base_update;
+    k->external_nmi = xen_apic_external_nmi;
+}
+
+static TypeInfo xen_apic_info = {
+    .name = "xen-apic",
+    .parent = TYPE_APIC_COMMON,
+    .instance_size = sizeof(APICCommonState),
+    .class_init = xen_apic_class_init,
+};
+
+static void xen_apic_register_types(void)
+{
+    type_register_static(&xen_apic_info);
+}
+
+type_init(xen_apic_register_types)
commit f1dbf015dfb0aa7f66f710a1f1bc58b662951de2
Author: Wei Liu <wei.liu2 at citrix.com>
Date:   Thu Apr 12 10:01:43 2012 +0000

    Xen: basic HVM MSI injection support.
    
    Signed-off-by: Wei Liu <wei.liu2 at citrix.com>
    Signed-off-by: Stefano Stabellini <stefano.stabellini at eu.citrix.com>

diff --git a/hw/xen.h b/hw/xen.h
index b46879c..e5926b7 100644
--- a/hw/xen.h
+++ b/hw/xen.h
@@ -34,6 +34,7 @@ static inline int xen_enabled(void)
 int xen_pci_slot_get_pirq(PCIDevice *pci_dev, int irq_num);
 void xen_piix3_set_irq(void *opaque, int irq_num, int level);
 void xen_piix_pci_write_config_client(uint32_t address, uint32_t val, int len);
+void xen_hvm_inject_msi(uint64_t addr, uint32_t data);
 void xen_cmos_set_s3_resume(void *opaque, int irq, int level);
 
 qemu_irq *xen_interrupt_controller_init(void);
diff --git a/xen-all.c b/xen-all.c
index 3e6de41..abd2b2d 100644
--- a/xen-all.c
+++ b/xen-all.c
@@ -122,6 +122,11 @@ void xen_piix_pci_write_config_client(uint32_t address, uint32_t val, int len)
     }
 }
 
+void xen_hvm_inject_msi(uint64_t addr, uint32_t data)
+{
+    xc_hvm_inject_msi(xen_xc, xen_domid, addr, data);
+}
+
 static void xen_suspend_notifier(Notifier *notifier, void *data)
 {
     xc_set_hvm_param(xen_xc, xen_domid, HVM_PARAM_ACPI_S_STATE, 3);
diff --git a/xen-stub.c b/xen-stub.c
index 9ea02d4..8ff2b79 100644
--- a/xen-stub.c
+++ b/xen-stub.c
@@ -29,6 +29,10 @@ void xen_piix_pci_write_config_client(uint32_t address, uint32_t val, int len)
 {
 }
 
+void xen_hvm_inject_msi(uint64_t addr, uint32_t data)
+{
+}
+
 void xen_cmos_set_s3_resume(void *opaque, int irq, int level)
 {
 }
commit 7672725d41d1a04195affc1a7bd5676ba6314b14
Merge: 3cbe19b... 6ccea1e...
Author: Anthony Liguori <aliguori at us.ibm.com>
Date:   Fri Apr 13 08:04:43 2012 -0500

    Merge remote-tracking branch 'stefanha/trivial-patches' into staging
    
    * stefanha/trivial-patches:
      configure: Insist on a Python 2, not Python 3
      bsd-user: fix compile failure
      ps2: avoid repeated header file includes
      make: Always set LC_ALL=C for makeinfo
      configure: Fix wrong preprocessor statement
      configure: Remove useless uses of ARCH_CFLAGS

commit 3cbe19b2e27238caa8b7518182eb674b8169b8df
Merge: a602e48... f349c12...
Author: Anthony Liguori <aliguori at us.ibm.com>
Date:   Fri Apr 13 08:04:31 2012 -0500

    Merge remote-tracking branch 'qemu-kvm/uq/master' into staging
    
    * qemu-kvm/uq/master:
      kvmclock: guest stop notification
      kvm: update linux headers
      kvm: set gsi_bits and max_gsi correctly
      kvm: Drop unused kvm_pit_in_kernel
      kvm: allow arbitrarily sized mmio ioeventfd
      kvm: Drop redundant kvm_enabled from cpu_thread_is_idle
      kvm: add flightrecorder script

commit a602e48958eb70b33415407e6f64bc883e019c37
Merge: dadc106... 3eab169...
Author: Anthony Liguori <aliguori at us.ibm.com>
Date:   Fri Apr 13 08:04:13 2012 -0500

    Merge remote-tracking branch 'afaerber/qom-cpu-lm32.v3' into staging
    
    * afaerber/qom-cpu-lm32.v3:
      target-lm32: QOM'ify CPU reset
      target-lm32: QOM'ify CPU init
      target-lm32: QOM'ify CPU

commit c79981ceec3ae1e712aa9c21cba94c152eea2fb5
Author: Peter Maydell <peter.maydell at linaro.org>
Date:   Fri Apr 13 11:39:09 2012 +0000

    hw/arm_gic: Remove stray hardcoded tab
    
    Remove the single instance of a hardcoded tab from hw/arm_gic.c.
    
    Signed-off-by: Peter Maydell <peter.maydell at linaro.org>

diff --git a/hw/arm_gic.c b/hw/arm_gic.c
index ba6117a..72298b4 100644
--- a/hw/arm_gic.c
+++ b/hw/arm_gic.c
@@ -160,7 +160,7 @@ static void gic_update(gic_state *s)
         cm = 1 << cpu;
         s->current_pending[cpu] = 1023;
         if (!s->enabled || !s->cpu_enabled[cpu]) {
-	    qemu_irq_lower(s->parent_irq[cpu]);
+            qemu_irq_lower(s->parent_irq[cpu]);
             return;
         }
         best_prio = 0x100;
commit b7dc1a597ab2d755c135852ce22d98fa00ab414f
Author: Peter Maydell <peter.maydell at linaro.org>
Date:   Fri Apr 13 11:39:09 2012 +0000

    hw/arm_gic: gic_set_pending_private() is NVIC only
    
    The function gic_set_pending_private() is now used by the NVIC
    only (for the GIC we now set PPI interrupts via gpio lines and
    gic_set_irq()). So make it #ifdef NVIC and remove the 'attribute
    unused' annotation.
    
    Signed-off-by: Peter Maydell <peter.maydell at linaro.org>

diff --git a/hw/arm_gic.c b/hw/arm_gic.c
index 589ac5e..ba6117a 100644
--- a/hw/arm_gic.c
+++ b/hw/arm_gic.c
@@ -185,8 +185,8 @@ static void gic_update(gic_state *s)
     }
 }
 
-static void __attribute__((unused))
-gic_set_pending_private(gic_state *s, int cpu, int irq)
+#ifdef NVIC
+static void gic_set_pending_private(gic_state *s, int cpu, int irq)
 {
     int cm = 1 << cpu;
 
@@ -197,6 +197,7 @@ gic_set_pending_private(gic_state *s, int cpu, int irq)
     GIC_SET_PENDING(irq, cm);
     gic_update(s);
 }
+#endif
 
 /* Process a change in an external IRQ input.  */
 static void gic_set_irq(void *opaque, int irq, int level)
commit 0d256bdc8f540a52fe1f0475aeeed3bc9f6e2de4
Author: Peter Maydell <peter.maydell at linaro.org>
Date:   Fri Apr 13 11:39:09 2012 +0000

    hw/arm_gic: Use NVIC instead of LEGACY_INCLUDED_GIC define
    
    Now all the A profile cores have been switched to use the standalone
    sysbus GIC, the only remaining code which #includes arm_gic.c is
    the v7M NVIC. The coupling is much closer here so it's not so
    easily disentangled. For now, add a comment about how arm_gic.c
    is compiled, and assume that the NVIC always includes arm_gic.c
    and the non-NVIC GIC is always compiled standalone.
    
    Signed-off-by: Peter Maydell <peter.maydell at linaro.org>

diff --git a/hw/arm_gic.c b/hw/arm_gic.c
index 81858c3..589ac5e 100644
--- a/hw/arm_gic.c
+++ b/hw/arm_gic.c
@@ -8,8 +8,15 @@
  */
 
 /* This file contains implementation code for the RealView EB interrupt
-   controller, MPCore distributed interrupt controller and ARMv7-M
-   Nested Vectored Interrupt Controller.  */
+ * controller, MPCore distributed interrupt controller and ARMv7-M
+ * Nested Vectored Interrupt Controller.
+ * It is compiled in two ways:
+ *  (1) as a standalone file to produce a sysbus device which is a GIC
+ *  that can be used on the realview board and as one of the builtin
+ *  private peripherals for the ARM MP CPUs (11MPCore, A9, etc)
+ *  (2) by being directly #included into armv7m_nvic.c to produce the
+ *  armv7m_nvic device.
+ */
 
 #include "sysbus.h"
 
@@ -909,7 +916,7 @@ static void gic_init(gic_state *s, int num_irq)
     register_savevm(NULL, "arm_gic", -1, 2, gic_save, gic_load, s);
 }
 
-#ifndef LEGACY_INCLUDED_GIC
+#ifndef NVIC
 
 static int arm_gic_init(SysBusDevice *dev)
 {
diff --git a/hw/armv7m_nvic.c b/hw/armv7m_nvic.c
index 5cfa971..986a6bb 100644
--- a/hw/armv7m_nvic.c
+++ b/hw/armv7m_nvic.c
@@ -16,7 +16,6 @@
 #include "exec-memory.h"
 
 #define NVIC 1
-#define LEGACY_INCLUDED_GIC
 
 static uint32_t nvic_readl(void *opaque, uint32_t offset);
 static void nvic_writel(void *opaque, uint32_t offset, uint32_t value);
commit aecff6924dab0197b6c8f132e44502b25fd98a38
Author: Peter Maydell <peter.maydell at linaro.org>
Date:   Fri Apr 13 11:39:09 2012 +0000

    hw/arm_gic: Make gic_reset a sysbus reset function
    
    Make gic_reset a sysbus reset function, so we actually
    reset the GIC on system reset rather than only at init.
    For the NVIC this requires us also to implement reset
    of the SysTick.
    
    Signed-off-by: Peter Maydell <peter.maydell at linaro.org>

diff --git a/hw/arm_gic.c b/hw/arm_gic.c
index b543570..81858c3 100644
--- a/hw/arm_gic.c
+++ b/hw/arm_gic.c
@@ -741,8 +741,9 @@ static const MemoryRegionOps gic_cpu_ops = {
 };
 #endif
 
-static void gic_reset(gic_state *s)
+static void gic_reset(DeviceState *dev)
 {
+    gic_state *s = FROM_SYSBUS(gic_state, sysbus_from_qdev(dev));
     int i;
     memset(s->irq_state, 0, GIC_MAXIRQ * sizeof(gic_irq_state));
     for (i = 0 ; i < NUM_CPU(s); i++) {
@@ -905,7 +906,6 @@ static void gic_init(gic_state *s, int num_irq)
     }
 #endif
 
-    gic_reset(s);
     register_savevm(NULL, "arm_gic", -1, 2, gic_save, gic_load, s);
 }
 
@@ -938,6 +938,7 @@ static void arm_gic_class_init(ObjectClass *klass, void *data)
     SysBusDeviceClass *sbc = SYS_BUS_DEVICE_CLASS(klass);
     sbc->init = arm_gic_init;
     dc->props = arm_gic_properties;
+    dc->reset = gic_reset;
     dc->no_user = 1;
 }
 
diff --git a/hw/armv7m_nvic.c b/hw/armv7m_nvic.c
index 79cf448..5cfa971 100644
--- a/hw/armv7m_nvic.c
+++ b/hw/armv7m_nvic.c
@@ -76,6 +76,14 @@ static void systick_timer_tick(void * opaque)
     }
 }
 
+static void systick_reset(nvic_state *s)
+{
+    s->systick.control = 0;
+    s->systick.reload = 0;
+    s->systick.tick = 0;
+    qemu_del_timer(s->systick.timer);
+}
+
 /* The external routines use the hardware vector numbering, ie. the first
    IRQ is #16.  The internal GIC routines use #32 as the first IRQ.  */
 void armv7m_nvic_set_pending(void *opaque, int irq)
@@ -371,6 +379,13 @@ static const VMStateDescription vmstate_nvic = {
     }
 };
 
+static void armv7m_nvic_reset(DeviceState *dev)
+{
+    nvic_state *s = FROM_SYSBUSGIC(nvic_state, sysbus_from_qdev(dev));
+    gic_reset(&s->gic.busdev.qdev);
+    systick_reset(s);
+}
+
 static int armv7m_nvic_init(SysBusDevice *dev)
 {
     nvic_state *s= FROM_SYSBUSGIC(nvic_state, dev);
@@ -400,6 +415,7 @@ static void armv7m_nvic_class_init(ObjectClass *klass, void *data)
 
     sdc->init = armv7m_nvic_init;
     dc->vmsd  = &vmstate_nvic;
+    dc->reset = armv7m_nvic_reset;
     dc->props = armv7m_nvic_properties;
 }
 
commit 2e9dfe20a62d93f145ea12a1b4755bb9cd61c327
Author: Peter Maydell <peter.maydell at linaro.org>
Date:   Fri Apr 13 11:39:08 2012 +0000

    hw/arm11mpcore: Convert to using sysbus GIC device
    
    Convert arm11mpcore to using the standalone sysbus GIC device.
    
    Signed-off-by: Peter Maydell <peter.maydell at linaro.org>

diff --git a/hw/arm11mpcore.c b/hw/arm11mpcore.c
index e876a0e..c528d7a 100644
--- a/hw/arm11mpcore.c
+++ b/hw/arm11mpcore.c
@@ -10,21 +10,18 @@
 #include "sysbus.h"
 #include "qemu-timer.h"
 
-#define LEGACY_INCLUDED_GIC
-#include "arm_gic.c"
-
 /* MPCore private memory region.  */
 
 typedef struct mpcore_priv_state {
-    gic_state gic;
+    SysBusDevice busdev;
     uint32_t scu_control;
     int iomemtype;
     uint32_t old_timer_status[8];
     uint32_t num_cpu;
-    qemu_irq *timer_irq;
     MemoryRegion iomem;
     MemoryRegion container;
     DeviceState *mptimer;
+    DeviceState *gic;
     uint32_t num_irq;
 } mpcore_priv_state;
 
@@ -74,18 +71,16 @@ static const MemoryRegionOps mpcore_scu_ops = {
     .endianness = DEVICE_NATIVE_ENDIAN,
 };
 
-static void mpcore_timer_irq_handler(void *opaque, int irq, int level)
+static void mpcore_priv_set_irq(void *opaque, int irq, int level)
 {
     mpcore_priv_state *s = (mpcore_priv_state *)opaque;
-    if (level && !s->old_timer_status[irq]) {
-        gic_set_pending_private(&s->gic, irq >> 1, 29 + (irq & 1));
-    }
-    s->old_timer_status[irq] = level;
+    qemu_set_irq(qdev_get_gpio_in(s->gic, irq), level);
 }
 
 static void mpcore_priv_map_setup(mpcore_priv_state *s)
 {
     int i;
+    SysBusDevice *gicbusdev = sysbus_from_qdev(s->gic);
     SysBusDevice *busdev = sysbus_from_qdev(s->mptimer);
     memory_region_init(&s->container, "mpcode-priv-container", 0x2000);
     memory_region_init_io(&s->iomem, &mpcore_scu_ops, s, "mpcore-scu", 0x100);
@@ -95,31 +90,47 @@ static void mpcore_priv_map_setup(mpcore_priv_state *s)
      */
     for (i = 0; i < (s->num_cpu + 1); i++) {
         target_phys_addr_t offset = 0x100 + (i * 0x100);
-        memory_region_add_subregion(&s->container, offset, &s->gic.cpuiomem[i]);
+        memory_region_add_subregion(&s->container, offset,
+                                    sysbus_mmio_get_region(gicbusdev, i + 1));
     }
     /* Add the regions for timer and watchdog for "current CPU" and
      * for each specific CPU.
      */
-    s->timer_irq = qemu_allocate_irqs(mpcore_timer_irq_handler,
-                                      s, (s->num_cpu + 1) * 2);
     for (i = 0; i < (s->num_cpu + 1) * 2; i++) {
         /* Timers at 0x600, 0x700, ...; watchdogs at 0x620, 0x720, ... */
         target_phys_addr_t offset = 0x600 + (i >> 1) * 0x100 + (i & 1) * 0x20;
         memory_region_add_subregion(&s->container, offset,
                                     sysbus_mmio_get_region(busdev, i));
     }
-    memory_region_add_subregion(&s->container, 0x1000, &s->gic.iomem);
-    /* Wire up the interrupt from each watchdog and timer. */
-    for (i = 0; i < s->num_cpu * 2; i++) {
-        sysbus_connect_irq(busdev, i, s->timer_irq[i]);
+    memory_region_add_subregion(&s->container, 0x1000,
+                                sysbus_mmio_get_region(gicbusdev, 0));
+    /* Wire up the interrupt from each watchdog and timer.
+     * For each core the timer is PPI 29 and the watchdog PPI 30.
+     */
+    for (i = 0; i < s->num_cpu; i++) {
+        int ppibase = (s->num_irq - 32) + i * 32;
+        sysbus_connect_irq(busdev, i * 2,
+                           qdev_get_gpio_in(s->gic, ppibase + 29));
+        sysbus_connect_irq(busdev, i * 2 + 1,
+                           qdev_get_gpio_in(s->gic, ppibase + 30));
     }
 }
 
 static int mpcore_priv_init(SysBusDevice *dev)
 {
-    mpcore_priv_state *s = FROM_SYSBUSGIC(mpcore_priv_state, dev);
+    mpcore_priv_state *s = FROM_SYSBUS(mpcore_priv_state, dev);
+
+    s->gic = qdev_create(NULL, "arm_gic");
+    qdev_prop_set_uint32(s->gic, "num-cpu", s->num_cpu);
+    qdev_prop_set_uint32(s->gic, "num-irq", s->num_irq);
+    qdev_init_nofail(s->gic);
+
+    /* Pass through outbound IRQ lines from the GIC */
+    sysbus_pass_irq(dev, sysbus_from_qdev(s->gic));
+
+    /* Pass through inbound GPIO lines to the GIC */
+    qdev_init_gpio_in(&s->busdev.qdev, mpcore_priv_set_irq, s->num_irq - 32);
 
-    gic_init(&s->gic, s->num_cpu, s->num_irq);
     s->mptimer = qdev_create(NULL, "arm_mptimer");
     qdev_prop_set_uint32(s->mptimer, "num-cpu", s->num_cpu);
     qdev_init_nofail(s->mptimer);
commit 23b92f60280fd250fbe421727ecfe15676d9f6ca
Author: Peter Maydell <peter.maydell at linaro.org>
Date:   Fri Apr 13 11:39:08 2012 +0000

    hw/exynos4210_gic: Convert to using sysbus GIC
    
    Convert the Exynos GIC code to use the standalone sysbus
    GIC device.
    
    Signed-off-by: Peter Maydell <peter.maydell at linaro.org>
    Reviewed-by: Evgeny Voevodin <e.voevodin at samsung.com>

diff --git a/hw/exynos4210_gic.c b/hw/exynos4210_gic.c
index a05dab2..e1b215e 100644
--- a/hw/exynos4210_gic.c
+++ b/hw/exynos4210_gic.c
@@ -262,28 +262,44 @@ uint32_t exynos4210_get_irq(uint32_t grp, uint32_t bit)
 
 /********* GIC part *********/
 
-#define LEGACY_INCLUDED_GIC
-#include "arm_gic.c"
-
 typedef struct {
-    gic_state gic;
+    SysBusDevice busdev;
     MemoryRegion cpu_container;
     MemoryRegion dist_container;
     MemoryRegion cpu_alias[EXYNOS4210_NCPUS];
     MemoryRegion dist_alias[EXYNOS4210_NCPUS];
     uint32_t num_cpu;
+    DeviceState *gic;
 } Exynos4210GicState;
 
+static void exynos4210_gic_set_irq(void *opaque, int irq, int level)
+{
+    Exynos4210GicState *s = (Exynos4210GicState *)opaque;
+    qemu_set_irq(qdev_get_gpio_in(s->gic, irq), level);
+}
+
 static int exynos4210_gic_init(SysBusDevice *dev)
 {
-    Exynos4210GicState *s = FROM_SYSBUSGIC(Exynos4210GicState, dev);
+    Exynos4210GicState *s = FROM_SYSBUS(Exynos4210GicState, dev);
     uint32_t i;
     const char cpu_prefix[] = "exynos4210-gic-alias_cpu";
     const char dist_prefix[] = "exynos4210-gic-alias_dist";
     char cpu_alias_name[sizeof(cpu_prefix) + 3];
     char dist_alias_name[sizeof(cpu_prefix) + 3];
+    SysBusDevice *busdev;
+
+    s->gic = qdev_create(NULL, "arm_gic");
+    qdev_prop_set_uint32(s->gic, "num-cpu", s->num_cpu);
+    qdev_prop_set_uint32(s->gic, "num-irq", EXYNOS4210_GIC_NIRQ);
+    qdev_init_nofail(s->gic);
+    busdev = sysbus_from_qdev(s->gic);
+
+    /* Pass through outbound IRQ lines from the GIC */
+    sysbus_pass_irq(dev, busdev);
 
-    gic_init(&s->gic, s->num_cpu, EXYNOS4210_GIC_NIRQ);
+    /* Pass through inbound GPIO lines to the GIC */
+    qdev_init_gpio_in(&s->busdev.qdev, exynos4210_gic_set_irq,
+                      EXYNOS4210_GIC_NIRQ - 32);
 
     memory_region_init(&s->cpu_container, "exynos4210-cpu-container",
             EXYNOS4210_EXT_GIC_CPU_REGION_SIZE);
@@ -295,7 +311,7 @@ static int exynos4210_gic_init(SysBusDevice *dev)
         sprintf(cpu_alias_name, "%s%x", cpu_prefix, i);
         memory_region_init_alias(&s->cpu_alias[i],
                                  cpu_alias_name,
-                                 &s->gic.cpuiomem[0],
+                                 sysbus_mmio_get_region(busdev, 1),
                                  0,
                                  EXYNOS4210_GIC_CPU_REGION_SIZE);
         memory_region_add_subregion(&s->cpu_container,
@@ -305,7 +321,7 @@ static int exynos4210_gic_init(SysBusDevice *dev)
         sprintf(dist_alias_name, "%s%x", dist_prefix, i);
         memory_region_init_alias(&s->dist_alias[i],
                                  dist_alias_name,
-                                 &s->gic.iomem,
+                                 sysbus_mmio_get_region(busdev, 0),
                                  0,
                                  EXYNOS4210_GIC_DIST_REGION_SIZE);
         memory_region_add_subregion(&s->dist_container,
commit fbbd05dc2ad0965d3ffd7556b8af8a74b156f9f9
Author: Peter Maydell <peter.maydell at linaro.org>
Date:   Fri Apr 13 11:39:08 2012 +0000

    hw/realview_gic: switch to sysbus GIC
    
    Switch the realview_gic device to the standalone sysbus GIC.
    
    Signed-off-by: Peter Maydell <peter.maydell at linaro.org>

diff --git a/hw/realview_gic.c b/hw/realview_gic.c
index a3b5a04..5bc37a7 100644
--- a/hw/realview_gic.c
+++ b/hw/realview_gic.c
@@ -9,31 +9,45 @@
 
 #include "sysbus.h"
 
-#define LEGACY_INCLUDED_GIC
-#include "arm_gic.c"
-
 typedef struct {
-    gic_state gic;
+    SysBusDevice busdev;
+    DeviceState *gic;
     MemoryRegion container;
 } RealViewGICState;
 
-static void realview_gic_map_setup(RealViewGICState *s)
+static void realview_gic_set_irq(void *opaque, int irq, int level)
 {
-    memory_region_init(&s->container, "realview-gic-container", 0x2000);
-    memory_region_add_subregion(&s->container, 0, &s->gic.cpuiomem[0]);
-    memory_region_add_subregion(&s->container, 0x1000, &s->gic.iomem);
+    RealViewGICState *s = (RealViewGICState *)opaque;
+    qemu_set_irq(qdev_get_gpio_in(s->gic, irq), level);
 }
 
 static int realview_gic_init(SysBusDevice *dev)
 {
-    RealViewGICState *s = FROM_SYSBUSGIC(RealViewGICState, dev);
-
+    RealViewGICState *s = FROM_SYSBUS(RealViewGICState, dev);
+    SysBusDevice *busdev;
     /* The GICs on the RealView boards have a fixed nonconfigurable
      * number of interrupt lines, so we don't need to expose this as
      * a qdev property.
      */
-    gic_init(&s->gic, 1, 96);
-    realview_gic_map_setup(s);
+    int numirq = 96;
+
+    s->gic = qdev_create(NULL, "arm_gic");
+    qdev_prop_set_uint32(s->gic, "num-cpu", 1);
+    qdev_prop_set_uint32(s->gic, "num-irq", numirq);
+    qdev_init_nofail(s->gic);
+    busdev = sysbus_from_qdev(s->gic);
+
+    /* Pass through outbound IRQ lines from the GIC */
+    sysbus_pass_irq(dev, busdev);
+
+    /* Pass through inbound GPIO lines to the GIC */
+    qdev_init_gpio_in(&s->busdev.qdev, realview_gic_set_irq, numirq - 32);
+
+    memory_region_init(&s->container, "realview-gic-container", 0x2000);
+    memory_region_add_subregion(&s->container, 0,
+                                sysbus_mmio_get_region(busdev, 1));
+    memory_region_add_subregion(&s->container, 0x1000,
+                                sysbus_mmio_get_region(busdev, 0));
     sysbus_init_mmio(dev, &s->container);
     return 0;
 }
commit ddd761653b14ffde7ee18d31f0350429f0402ab4
Author: Peter Maydell <peter.maydell at linaro.org>
Date:   Fri Apr 13 11:39:08 2012 +0000

    hw/a9mpcore: Switch to using sysbus GIC
    
    Switch the a9mpcore to using the sysbus GIC device rather
    than having the a9mp private memory region device subclass
    the GIC.
    
    Signed-off-by: Peter Maydell <peter.maydell at linaro.org>

diff --git a/hw/a9mpcore.c b/hw/a9mpcore.c
index 164a0d3..c2ff74d 100644
--- a/hw/a9mpcore.c
+++ b/hw/a9mpcore.c
@@ -10,22 +10,19 @@
 
 #include "sysbus.h"
 
-#define LEGACY_INCLUDED_GIC
-#include "arm_gic.c"
-
 /* A9MP private memory region.  */
 
 typedef struct a9mp_priv_state {
-    gic_state gic;
+    SysBusDevice busdev;
     uint32_t scu_control;
     uint32_t scu_status;
     uint32_t old_timer_status[8];
     uint32_t num_cpu;
-    qemu_irq *timer_irq;
     MemoryRegion scu_iomem;
     MemoryRegion ptimer_iomem;
     MemoryRegion container;
     DeviceState *mptimer;
+    DeviceState *gic;
     uint32_t num_irq;
 } a9mp_priv_state;
 
@@ -114,18 +111,9 @@ static const MemoryRegionOps a9_scu_ops = {
     .endianness = DEVICE_NATIVE_ENDIAN,
 };
 
-static void a9mpcore_timer_irq_handler(void *opaque, int irq, int level)
-{
-    a9mp_priv_state *s = (a9mp_priv_state *)opaque;
-    if (level && !s->old_timer_status[irq]) {
-        gic_set_pending_private(&s->gic, irq >> 1, 29 + (irq & 1));
-    }
-    s->old_timer_status[irq] = level;
-}
-
 static void a9mp_priv_reset(DeviceState *dev)
 {
-    a9mp_priv_state *s = FROM_SYSBUSGIC(a9mp_priv_state, sysbus_from_qdev(dev));
+    a9mp_priv_state *s = FROM_SYSBUS(a9mp_priv_state, sysbus_from_qdev(dev));
     int i;
     s->scu_control = 0;
     for (i = 0; i < ARRAY_SIZE(s->old_timer_status); i++) {
@@ -133,13 +121,29 @@ static void a9mp_priv_reset(DeviceState *dev)
     }
 }
 
+static void a9mp_priv_set_irq(void *opaque, int irq, int level)
+{
+    a9mp_priv_state *s = (a9mp_priv_state *)opaque;
+    qemu_set_irq(qdev_get_gpio_in(s->gic, irq), level);
+}
+
 static int a9mp_priv_init(SysBusDevice *dev)
 {
-    a9mp_priv_state *s = FROM_SYSBUSGIC(a9mp_priv_state, dev);
-    SysBusDevice *busdev;
+    a9mp_priv_state *s = FROM_SYSBUS(a9mp_priv_state, dev);
+    SysBusDevice *busdev, *gicbusdev;
     int i;
 
-    gic_init(&s->gic, s->num_cpu, s->num_irq);
+    s->gic = qdev_create(NULL, "arm_gic");
+    qdev_prop_set_uint32(s->gic, "num-cpu", s->num_cpu);
+    qdev_prop_set_uint32(s->gic, "num-irq", s->num_irq);
+    qdev_init_nofail(s->gic);
+    gicbusdev = sysbus_from_qdev(s->gic);
+
+    /* Pass through outbound IRQ lines from the GIC */
+    sysbus_pass_irq(dev, gicbusdev);
+
+    /* Pass through inbound GPIO lines to the GIC */
+    qdev_init_gpio_in(&s->busdev.qdev, a9mp_priv_set_irq, s->num_irq - 32);
 
     s->mptimer = qdev_create(NULL, "arm_mptimer");
     qdev_prop_set_uint32(s->mptimer, "num-cpu", s->num_cpu);
@@ -161,7 +165,8 @@ static int a9mp_priv_init(SysBusDevice *dev)
     memory_region_init_io(&s->scu_iomem, &a9_scu_ops, s, "a9mp-scu", 0x100);
     memory_region_add_subregion(&s->container, 0, &s->scu_iomem);
     /* GIC CPU interface */
-    memory_region_add_subregion(&s->container, 0x100, &s->gic.cpuiomem[0]);
+    memory_region_add_subregion(&s->container, 0x100,
+                                sysbus_mmio_get_region(gicbusdev, 1));
     /* Note that the A9 exposes only the "timer/watchdog for this core"
      * memory region, not the "timer/watchdog for core X" ones 11MPcore has.
      */
@@ -169,15 +174,20 @@ static int a9mp_priv_init(SysBusDevice *dev)
                                 sysbus_mmio_get_region(busdev, 0));
     memory_region_add_subregion(&s->container, 0x620,
                                 sysbus_mmio_get_region(busdev, 1));
-    memory_region_add_subregion(&s->container, 0x1000, &s->gic.iomem);
+    memory_region_add_subregion(&s->container, 0x1000,
+                                sysbus_mmio_get_region(gicbusdev, 0));
 
     sysbus_init_mmio(dev, &s->container);
 
-    /* Wire up the interrupt from each watchdog and timer. */
-    s->timer_irq = qemu_allocate_irqs(a9mpcore_timer_irq_handler,
-                                      s, (s->num_cpu + 1) * 2);
-    for (i = 0; i < s->num_cpu * 2; i++) {
-        sysbus_connect_irq(busdev, i, s->timer_irq[i]);
+    /* Wire up the interrupt from each watchdog and timer.
+     * For each core the timer is PPI 29 and the watchdog PPI 30.
+     */
+    for (i = 0; i < s->num_cpu; i++) {
+        int ppibase = (s->num_irq - 32) + i * 32;
+        sysbus_connect_irq(busdev, i * 2,
+                           qdev_get_gpio_in(s->gic, ppibase + 29));
+        sysbus_connect_irq(busdev, i * 2 + 1,
+                           qdev_get_gpio_in(s->gic, ppibase + 30));
     }
     return 0;
 }
commit 4637a02752f29f1b28c4a4ddb0c168d2d1299227
Author: Peter Maydell <peter.maydell at linaro.org>
Date:   Fri Apr 13 11:39:07 2012 +0000

    hw/a15mpcore: switch to using sysbus GIC
    
    Switch the a15mpcore private peripheral region to using
    the standalone sysbus GIC device.
    
    Signed-off-by: Peter Maydell <peter.maydell at linaro.org>

diff --git a/hw/a15mpcore.c b/hw/a15mpcore.c
index 54c0dbf..5a7b365 100644
--- a/hw/a15mpcore.c
+++ b/hw/a15mpcore.c
@@ -20,23 +20,38 @@
 
 #include "sysbus.h"
 
-#define LEGACY_INCLUDED_GIC
-#include "arm_gic.c"
-
 /* A15MP private memory region.  */
 
 typedef struct A15MPPrivState {
-    gic_state gic;
+    SysBusDevice busdev;
     uint32_t num_cpu;
     uint32_t num_irq;
     MemoryRegion container;
+    DeviceState *gic;
 } A15MPPrivState;
 
+static void a15mp_priv_set_irq(void *opaque, int irq, int level)
+{
+    A15MPPrivState *s = (A15MPPrivState *)opaque;
+    qemu_set_irq(qdev_get_gpio_in(s->gic, irq), level);
+}
+
 static int a15mp_priv_init(SysBusDevice *dev)
 {
-    A15MPPrivState *s = FROM_SYSBUSGIC(A15MPPrivState, dev);
+    A15MPPrivState *s = FROM_SYSBUS(A15MPPrivState, dev);
+    SysBusDevice *busdev;
+
+    s->gic = qdev_create(NULL, "arm_gic");
+    qdev_prop_set_uint32(s->gic, "num-cpu", s->num_cpu);
+    qdev_prop_set_uint32(s->gic, "num-irq", s->num_irq);
+    qdev_init_nofail(s->gic);
+    busdev = sysbus_from_qdev(s->gic);
+
+    /* Pass through outbound IRQ lines from the GIC */
+    sysbus_pass_irq(dev, busdev);
 
-    gic_init(&s->gic, s->num_cpu, s->num_irq);
+    /* Pass through inbound GPIO lines to the GIC */
+    qdev_init_gpio_in(&s->busdev.qdev, a15mp_priv_set_irq, s->num_irq - 32);
 
     /* Memory map (addresses are offsets from PERIPHBASE):
      *  0x0000-0x0fff -- reserved
@@ -47,8 +62,10 @@ static int a15mp_priv_init(SysBusDevice *dev)
      *  0x6000-0x7fff -- GIC virtual CPU interface (not modelled)
      */
     memory_region_init(&s->container, "a15mp-priv-container", 0x8000);
-    memory_region_add_subregion(&s->container, 0x1000, &s->gic.iomem);
-    memory_region_add_subregion(&s->container, 0x2000, &s->gic.cpuiomem[0]);
+    memory_region_add_subregion(&s->container, 0x1000,
+                                sysbus_mmio_get_region(busdev, 0));
+    memory_region_add_subregion(&s->container, 0x2000,
+                                sysbus_mmio_get_region(busdev, 1));
 
     sysbus_init_mmio(dev, &s->container);
     return 0;
@@ -72,7 +89,7 @@ static void a15mp_priv_class_init(ObjectClass *klass, void *data)
     SysBusDeviceClass *k = SYS_BUS_DEVICE_CLASS(klass);
     k->init = a15mp_priv_init;
     dc->props = a15mp_priv_properties;
-    /* We currently have no savable state outside the common GIC state */
+    /* We currently have no savable state */
 }
 
 static TypeInfo a15mp_priv_info = {
commit 496dbcd1a38c2ae4ada848445e4a1aa758af9f43
Author: Peter Maydell <peter.maydell at linaro.org>
Date:   Fri Apr 13 11:39:07 2012 +0000

    hw/arm_gic: Make the GIC its own sysbus device
    
    Compile arm_gic.c as a standalone C file to produce a self contained
    sysbus GIC device. Support the legacy usage by #include of the .c file
    by making those users #define LEGACY_INCLUDED_GIC, so we can convert
    them one by one.
    
    Signed-off-by: Peter Maydell <peter.maydell at linaro.org>
    Reviewed-by: Evgeny Voevodin <e.voevodin at samsung.com>

diff --git a/Makefile.target b/Makefile.target
index 1110796..0f09180 100644
--- a/Makefile.target
+++ b/Makefile.target
@@ -365,6 +365,7 @@ obj-arm-y += cadence_uart.o
 obj-arm-y += cadence_ttc.o
 obj-arm-y += cadence_gem.o
 obj-arm-y += xilinx_zynq.o zynq_slcr.o
+obj-arm-y += arm_gic.o
 obj-arm-y += realview_gic.o realview.o arm_sysctl.o arm11mpcore.o a9mpcore.o
 obj-arm-y += exynos4210_gic.o exynos4210_combiner.o exynos4210.o
 obj-arm-y += exynos4_boards.o exynos4210_uart.o exynos4210_pwm.o
diff --git a/hw/a15mpcore.c b/hw/a15mpcore.c
index 2e2ed42..54c0dbf 100644
--- a/hw/a15mpcore.c
+++ b/hw/a15mpcore.c
@@ -20,6 +20,7 @@
 
 #include "sysbus.h"
 
+#define LEGACY_INCLUDED_GIC
 #include "arm_gic.c"
 
 /* A15MP private memory region.  */
diff --git a/hw/a9mpcore.c b/hw/a9mpcore.c
index 1d83c37..164a0d3 100644
--- a/hw/a9mpcore.c
+++ b/hw/a9mpcore.c
@@ -10,6 +10,7 @@
 
 #include "sysbus.h"
 
+#define LEGACY_INCLUDED_GIC
 #include "arm_gic.c"
 
 /* A9MP private memory region.  */
diff --git a/hw/arm11mpcore.c b/hw/arm11mpcore.c
index c4829d8..e876a0e 100644
--- a/hw/arm11mpcore.c
+++ b/hw/arm11mpcore.c
@@ -10,6 +10,7 @@
 #include "sysbus.h"
 #include "qemu-timer.h"
 
+#define LEGACY_INCLUDED_GIC
 #include "arm_gic.c"
 
 /* MPCore private memory region.  */
diff --git a/hw/arm_gic.c b/hw/arm_gic.c
index fabbcc5..b543570 100644
--- a/hw/arm_gic.c
+++ b/hw/arm_gic.c
@@ -11,6 +11,8 @@
    controller, MPCore distributed interrupt controller and ARMv7-M
    Nested Vectored Interrupt Controller.  */
 
+#include "sysbus.h"
+
 /* Maximum number of possible interrupts, determined by the GIC architecture */
 #define GIC_MAXIRQ 1020
 /* First 32 are private to each CPU (SGIs and PPIs). */
@@ -112,7 +114,7 @@ typedef struct gic_state
     int current_pending[NCPU];
 
 #if NCPU > 1
-    int num_cpu;
+    uint32_t num_cpu;
 #endif
 
     MemoryRegion iomem; /* Distributor */
@@ -906,3 +908,51 @@ static void gic_init(gic_state *s, int num_irq)
     gic_reset(s);
     register_savevm(NULL, "arm_gic", -1, 2, gic_save, gic_load, s);
 }
+
+#ifndef LEGACY_INCLUDED_GIC
+
+static int arm_gic_init(SysBusDevice *dev)
+{
+    /* Device instance init function for the GIC sysbus device */
+    int i;
+    gic_state *s = FROM_SYSBUS(gic_state, dev);
+    gic_init(s, s->num_cpu, s->num_irq);
+    /* Distributor */
+    sysbus_init_mmio(dev, &s->iomem);
+    /* cpu interfaces (one for "current cpu" plus one per cpu) */
+    for (i = 0; i <= NUM_CPU(s); i++) {
+        sysbus_init_mmio(dev, &s->cpuiomem[i]);
+    }
+    return 0;
+}
+
+static Property arm_gic_properties[] = {
+    DEFINE_PROP_UINT32("num-cpu", gic_state, num_cpu, 1),
+    DEFINE_PROP_UINT32("num-irq", gic_state, num_irq, 32),
+    DEFINE_PROP_END_OF_LIST(),
+};
+
+static void arm_gic_class_init(ObjectClass *klass, void *data)
+{
+    DeviceClass *dc = DEVICE_CLASS(klass);
+    SysBusDeviceClass *sbc = SYS_BUS_DEVICE_CLASS(klass);
+    sbc->init = arm_gic_init;
+    dc->props = arm_gic_properties;
+    dc->no_user = 1;
+}
+
+static TypeInfo arm_gic_info = {
+    .name = "arm_gic",
+    .parent = TYPE_SYS_BUS_DEVICE,
+    .instance_size = sizeof(gic_state),
+    .class_init = arm_gic_class_init,
+};
+
+static void arm_gic_register_types(void)
+{
+    type_register_static(&arm_gic_info);
+}
+
+type_init(arm_gic_register_types)
+
+#endif
diff --git a/hw/armv7m_nvic.c b/hw/armv7m_nvic.c
index 99ed85b..79cf448 100644
--- a/hw/armv7m_nvic.c
+++ b/hw/armv7m_nvic.c
@@ -16,6 +16,7 @@
 #include "exec-memory.h"
 
 #define NVIC 1
+#define LEGACY_INCLUDED_GIC
 
 static uint32_t nvic_readl(void *opaque, uint32_t offset);
 static void nvic_writel(void *opaque, uint32_t offset, uint32_t value);
diff --git a/hw/exynos4210_gic.c b/hw/exynos4210_gic.c
index ff7ab84..a05dab2 100644
--- a/hw/exynos4210_gic.c
+++ b/hw/exynos4210_gic.c
@@ -262,6 +262,7 @@ uint32_t exynos4210_get_irq(uint32_t grp, uint32_t bit)
 
 /********* GIC part *********/
 
+#define LEGACY_INCLUDED_GIC
 #include "arm_gic.c"
 
 typedef struct {
diff --git a/hw/realview_gic.c b/hw/realview_gic.c
index aa780fe..a3b5a04 100644
--- a/hw/realview_gic.c
+++ b/hw/realview_gic.c
@@ -9,6 +9,7 @@
 
 #include "sysbus.h"
 
+#define LEGACY_INCLUDED_GIC
 #include "arm_gic.c"
 
 typedef struct {
commit 544d1afa7013fce155f5afbbc24737f2fc0c0f26
Author: Peter Maydell <peter.maydell at linaro.org>
Date:   Fri Apr 13 11:39:07 2012 +0000

    hw/arm_gic: Expose PPI inputs as gpio inputs
    
    Expose the Private Peripheral Interrupt inputs as GPIO inputs.
    The layout of the GPIO array is thus:
      [0..N-1] SPIs
      [N..N+31] PPIs for CPU 0
      [N+32..N+63] PPIs for CPU 1
      ...
    
    Treating PPIs as being another kind of input line is in line with the
    GIC architecture specification, where they are clearly described that
    way. The 11MPCore TRM is a bit more ambiguous, but there is no practical
    difference between "set PPI X as pending" and "0->1 transition on a
    PPI input line configured as edge triggered", and PPIs are always
    edge triggered, so this change won't affect behaviour.
    
    Signed-off-by: Peter Maydell <peter.maydell at linaro.org>

diff --git a/hw/arm_gic.c b/hw/arm_gic.c
index df1a34b..fabbcc5 100644
--- a/hw/arm_gic.c
+++ b/hw/arm_gic.c
@@ -192,20 +192,40 @@ gic_set_pending_private(gic_state *s, int cpu, int irq)
 /* Process a change in an external IRQ input.  */
 static void gic_set_irq(void *opaque, int irq, int level)
 {
+    /* Meaning of the 'irq' parameter:
+     *  [0..N-1] : external interrupts
+     *  [N..N+31] : PPI (internal) interrupts for CPU 0
+     *  [N+32..N+63] : PPI (internal interrupts for CPU 1
+     *  ...
+     */
     gic_state *s = (gic_state *)opaque;
-    /* The first external input line is internal interrupt 32.  */
-    irq += GIC_INTERNAL;
-    if (level == GIC_TEST_LEVEL(irq, ALL_CPU_MASK))
+    int cm, target;
+    if (irq < (s->num_irq - GIC_INTERNAL)) {
+        /* The first external input line is internal interrupt 32.  */
+        cm = ALL_CPU_MASK;
+        irq += GIC_INTERNAL;
+        target = GIC_TARGET(irq);
+    } else {
+        int cpu;
+        irq -= (s->num_irq - GIC_INTERNAL);
+        cpu = irq / GIC_INTERNAL;
+        irq %= GIC_INTERNAL;
+        cm = 1 << cpu;
+        target = cm;
+    }
+
+    if (level == GIC_TEST_LEVEL(irq, cm)) {
         return;
+    }
 
     if (level) {
-        GIC_SET_LEVEL(irq, ALL_CPU_MASK);
-        if (GIC_TEST_TRIGGER(irq) || GIC_TEST_ENABLED(irq, ALL_CPU_MASK)) {
-            DPRINTF("Set %d pending mask %x\n", irq, GIC_TARGET(irq));
-            GIC_SET_PENDING(irq, GIC_TARGET(irq));
+        GIC_SET_LEVEL(irq, cm);
+        if (GIC_TEST_TRIGGER(irq) || GIC_TEST_ENABLED(irq, cm)) {
+            DPRINTF("Set %d pending mask %x\n", irq, target);
+            GIC_SET_PENDING(irq, target);
         }
     } else {
-        GIC_CLEAR_LEVEL(irq, ALL_CPU_MASK);
+        GIC_CLEAR_LEVEL(irq, cm);
     }
     gic_update(s);
 }
@@ -849,7 +869,18 @@ static void gic_init(gic_state *s, int num_irq)
                  num_irq);
     }
 
-    qdev_init_gpio_in(&s->busdev.qdev, gic_set_irq, s->num_irq - GIC_INTERNAL);
+    i = s->num_irq - GIC_INTERNAL;
+#ifndef NVIC
+    /* For the GIC, also expose incoming GPIO lines for PPIs for each CPU.
+     * GPIO array layout is thus:
+     *  [0..N-1] SPIs
+     *  [N..N+31] PPIs for CPU 0
+     *  [N+32..N+63] PPIs for CPU 1
+     *   ...
+     */
+    i += (GIC_INTERNAL * num_cpu);
+#endif
+    qdev_init_gpio_in(&s->busdev.qdev, gic_set_irq, i);
     for (i = 0; i < NUM_CPU(s); i++) {
         sysbus_init_irq(&s->busdev, &s->parent_irq[i]);
     }
commit 926c4aff6ecf2b26b3508773196314a774bf5c4c
Author: Peter Maydell <peter.maydell at linaro.org>
Date:   Fri Apr 13 11:39:07 2012 +0000

    hw/arm_gic: Move gic_get_current_cpu into arm_gic.c
    
    Move the gic_get_current_cpu() function into arm_gic.c.
    There are only two implementations: (1) "get the index
    of the currently executing CPU", used by all multicore
    GICs, and (2) "always 0", used by all GICs instantiated
    with a single CPU interface (the Realview board GIC and
    the v7M NVIC). So we can move this into the main GIC
    source file.
    
    Signed-off-by: Peter Maydell <peter.maydell at linaro.org>
    Reviewed-by: Evgeny Voevodin <e.voevodin at samsung.com>

diff --git a/hw/a15mpcore.c b/hw/a15mpcore.c
index 67206ec..2e2ed42 100644
--- a/hw/a15mpcore.c
+++ b/hw/a15mpcore.c
@@ -20,14 +20,6 @@
 
 #include "sysbus.h"
 
-/* Configuration for arm_gic.c:
- * how to ID current CPU
- */
-static inline int gic_get_current_cpu(void)
-{
-  return cpu_single_env->cpu_index;
-}
-
 #include "arm_gic.c"
 
 /* A15MP private memory region.  */
diff --git a/hw/a9mpcore.c b/hw/a9mpcore.c
index 5bbe3c7..1d83c37 100644
--- a/hw/a9mpcore.c
+++ b/hw/a9mpcore.c
@@ -10,15 +10,6 @@
 
 #include "sysbus.h"
 
-/* Configuration for arm_gic.c:
- * how to ID current CPU
- */
-static inline int
-gic_get_current_cpu(void)
-{
-  return cpu_single_env->cpu_index;
-}
-
 #include "arm_gic.c"
 
 /* A9MP private memory region.  */
diff --git a/hw/arm11mpcore.c b/hw/arm11mpcore.c
index 99c1826..c4829d8 100644
--- a/hw/arm11mpcore.c
+++ b/hw/arm11mpcore.c
@@ -10,12 +10,6 @@
 #include "sysbus.h"
 #include "qemu-timer.h"
 
-static inline int
-gic_get_current_cpu(void)
-{
-  return cpu_single_env->cpu_index;
-}
-
 #include "arm_gic.c"
 
 /* MPCore private memory region.  */
diff --git a/hw/arm_gic.c b/hw/arm_gic.c
index f64a001..df1a34b 100644
--- a/hw/arm_gic.c
+++ b/hw/arm_gic.c
@@ -126,6 +126,16 @@ typedef struct gic_state
     uint32_t num_irq;
 } gic_state;
 
+static inline int gic_get_current_cpu(gic_state *s)
+{
+#if NCPU > 1
+    if (s->num_cpu > 1) {
+        return cpu_single_env->cpu_index;
+    }
+#endif
+    return 0;
+}
+
 /* TODO: Many places that call this routine could be optimized.  */
 /* Update interrupt status after enabled or pending bits have been changed.  */
 static void gic_update(gic_state *s)
@@ -285,7 +295,7 @@ static uint32_t gic_dist_readb(void *opaque, target_phys_addr_t offset)
     int cm;
     int mask;
 
-    cpu = gic_get_current_cpu();
+    cpu = gic_get_current_cpu(s);
     cm = 1 << cpu;
     if (offset < 0x100) {
 #ifndef NVIC
@@ -420,7 +430,7 @@ static void gic_dist_writeb(void *opaque, target_phys_addr_t offset,
     int i;
     int cpu;
 
-    cpu = gic_get_current_cpu();
+    cpu = gic_get_current_cpu(s);
     if (offset < 0x100) {
 #ifdef NVIC
         goto bad_reg;
@@ -582,7 +592,7 @@ static void gic_dist_writel(void *opaque, target_phys_addr_t offset,
         int irq;
         int mask;
 
-        cpu = gic_get_current_cpu();
+        cpu = gic_get_current_cpu(s);
         irq = value & 0x3ff;
         switch ((value >> 24) & 3) {
         case 0:
@@ -665,14 +675,14 @@ static uint64_t gic_thiscpu_read(void *opaque, target_phys_addr_t addr,
                                  unsigned size)
 {
     gic_state *s = (gic_state *)opaque;
-    return gic_cpu_read(s, gic_get_current_cpu(), addr);
+    return gic_cpu_read(s, gic_get_current_cpu(s), addr);
 }
 
 static void gic_thiscpu_write(void *opaque, target_phys_addr_t addr,
                               uint64_t value, unsigned size)
 {
     gic_state *s = (gic_state *)opaque;
-    gic_cpu_write(s, gic_get_current_cpu(), addr, value);
+    gic_cpu_write(s, gic_get_current_cpu(s), addr, value);
 }
 
 /* Wrappers to read/write the GIC CPU interface for a specific CPU.
diff --git a/hw/armv7m_nvic.c b/hw/armv7m_nvic.c
index bdab709..99ed85b 100644
--- a/hw/armv7m_nvic.c
+++ b/hw/armv7m_nvic.c
@@ -17,13 +17,6 @@
 
 #define NVIC 1
 
-/* Only a single "CPU" interface is present.  */
-static inline int
-gic_get_current_cpu(void)
-{
-    return 0;
-}
-
 static uint32_t nvic_readl(void *opaque, uint32_t offset);
 static void nvic_writel(void *opaque, uint32_t offset, uint32_t value);
 
diff --git a/hw/exynos4210_gic.c b/hw/exynos4210_gic.c
index 426f540..ff7ab84 100644
--- a/hw/exynos4210_gic.c
+++ b/hw/exynos4210_gic.c
@@ -262,12 +262,6 @@ uint32_t exynos4210_get_irq(uint32_t grp, uint32_t bit)
 
 /********* GIC part *********/
 
-static inline int
-gic_get_current_cpu(void)
-{
-    return cpu_single_env->cpu_index;
-}
-
 #include "arm_gic.c"
 
 typedef struct {
diff --git a/hw/realview_gic.c b/hw/realview_gic.c
index d114242..aa780fe 100644
--- a/hw/realview_gic.c
+++ b/hw/realview_gic.c
@@ -9,13 +9,6 @@
 
 #include "sysbus.h"
 
-/* Only a single "CPU" interface is present.  */
-static inline int
-gic_get_current_cpu(void)
-{
-  return 0;
-}
-
 #include "arm_gic.c"
 
 typedef struct {
commit 386e29554e8f1a7e910682789418aed2094b4ef6
Author: Peter Maydell <peter.maydell at linaro.org>
Date:   Fri Apr 13 11:39:07 2012 +0000

    hw/arm_gic: Move NCPU definition to arm_gic.c
    
    Move the NCPU definition to arm_gic.c: the maximum number
    of CPU interfaces is defined by the GIC architecture specification
    to be 8, so we don't need to have this #define in each of the
    sources files which currently includes arm_gic.c.
    
    Signed-off-by: Peter Maydell <peter.maydell at linaro.org>
    Reviewed-by: Evgeny Voevodin <e.voevodin at samsung.com>

diff --git a/hw/a15mpcore.c b/hw/a15mpcore.c
index 71142e5..67206ec 100644
--- a/hw/a15mpcore.c
+++ b/hw/a15mpcore.c
@@ -21,10 +21,8 @@
 #include "sysbus.h"
 
 /* Configuration for arm_gic.c:
- * max number of CPUs, how to ID current CPU
+ * how to ID current CPU
  */
-#define NCPU 4
-
 static inline int gic_get_current_cpu(void)
 {
   return cpu_single_env->cpu_index;
@@ -45,10 +43,6 @@ static int a15mp_priv_init(SysBusDevice *dev)
 {
     A15MPPrivState *s = FROM_SYSBUSGIC(A15MPPrivState, dev);
 
-    if (s->num_cpu > NCPU) {
-        hw_error("a15mp_priv_init: num-cpu may not be more than %d\n", NCPU);
-    }
-
     gic_init(&s->gic, s->num_cpu, s->num_irq);
 
     /* Memory map (addresses are offsets from PERIPHBASE):
diff --git a/hw/a9mpcore.c b/hw/a9mpcore.c
index 03b128c..5bbe3c7 100644
--- a/hw/a9mpcore.c
+++ b/hw/a9mpcore.c
@@ -11,10 +11,8 @@
 #include "sysbus.h"
 
 /* Configuration for arm_gic.c:
- * max number of CPUs, how to ID current CPU
+ * how to ID current CPU
  */
-#define NCPU 4
-
 static inline int
 gic_get_current_cpu(void)
 {
@@ -149,10 +147,6 @@ static int a9mp_priv_init(SysBusDevice *dev)
     SysBusDevice *busdev;
     int i;
 
-    if (s->num_cpu > NCPU) {
-        hw_error("a9mp_priv_init: num-cpu may not be more than %d\n", NCPU);
-    }
-
     gic_init(&s->gic, s->num_cpu, s->num_irq);
 
     s->mptimer = qdev_create(NULL, "arm_mptimer");
diff --git a/hw/arm11mpcore.c b/hw/arm11mpcore.c
index ba6a89d..99c1826 100644
--- a/hw/arm11mpcore.c
+++ b/hw/arm11mpcore.c
@@ -10,8 +10,6 @@
 #include "sysbus.h"
 #include "qemu-timer.h"
 
-#define NCPU 4
-
 static inline int
 gic_get_current_cpu(void)
 {
diff --git a/hw/arm_gic.c b/hw/arm_gic.c
index 6b34c06..f64a001 100644
--- a/hw/arm_gic.c
+++ b/hw/arm_gic.c
@@ -15,6 +15,13 @@
 #define GIC_MAXIRQ 1020
 /* First 32 are private to each CPU (SGIs and PPIs). */
 #define GIC_INTERNAL 32
+/* Maximum number of possible CPU interfaces, determined by GIC architecture */
+#ifdef NVIC
+#define NCPU 1
+#else
+#define NCPU 8
+#endif
+
 //#define DEBUG_GIC
 
 #ifdef DEBUG_GIC
@@ -50,7 +57,7 @@ typedef struct gic_irq_state
     unsigned trigger:1; /* nonzero = edge triggered.  */
 } gic_irq_state;
 
-#define ALL_CPU_MASK ((1 << NCPU) - 1)
+#define ALL_CPU_MASK ((unsigned)(((1 << NCPU) - 1)))
 #if NCPU > 1
 #define NUM_CPU(s) ((s)->num_cpu)
 #else
@@ -813,6 +820,10 @@ static void gic_init(gic_state *s, int num_irq)
 
 #if NCPU > 1
     s->num_cpu = num_cpu;
+    if (s->num_cpu > NCPU) {
+        hw_error("requested %u CPUs exceeds GIC maximum %d\n",
+                 num_cpu, NCPU);
+    }
 #endif
     s->num_irq = num_irq + GIC_BASE_IRQ;
     if (s->num_irq > GIC_MAXIRQ) {
diff --git a/hw/armv7m_nvic.c b/hw/armv7m_nvic.c
index 3210129..bdab709 100644
--- a/hw/armv7m_nvic.c
+++ b/hw/armv7m_nvic.c
@@ -15,7 +15,6 @@
 #include "arm-misc.h"
 #include "exec-memory.h"
 
-#define NCPU 1
 #define NVIC 1
 
 /* Only a single "CPU" interface is present.  */
diff --git a/hw/exynos4210_gic.c b/hw/exynos4210_gic.c
index 3ba9063..426f540 100644
--- a/hw/exynos4210_gic.c
+++ b/hw/exynos4210_gic.c
@@ -174,7 +174,6 @@ combiner_grp_to_gic_id[64-EXYNOS4210_MAX_EXT_COMBINER_OUT_IRQ][8] = {
 };
 
 #define EXYNOS4210_GIC_NIRQ 160
-#define NCPU                EXYNOS4210_NCPUS
 
 #define EXYNOS4210_EXT_GIC_CPU_REGION_SIZE     0x10000
 #define EXYNOS4210_EXT_GIC_DIST_REGION_SIZE    0x10000
@@ -275,8 +274,8 @@ typedef struct {
     gic_state gic;
     MemoryRegion cpu_container;
     MemoryRegion dist_container;
-    MemoryRegion cpu_alias[NCPU];
-    MemoryRegion dist_alias[NCPU];
+    MemoryRegion cpu_alias[EXYNOS4210_NCPUS];
+    MemoryRegion dist_alias[EXYNOS4210_NCPUS];
     uint32_t num_cpu;
 } Exynos4210GicState;
 
@@ -359,7 +358,7 @@ type_init(exynos4210_gic_register_types)
 typedef struct {
     SysBusDevice busdev;
 
-    qemu_irq pic_irq[NCPU]; /* output IRQs to PICs */
+    qemu_irq pic_irq[EXYNOS4210_NCPUS]; /* output IRQs to PICs */
     uint32_t gpio_level[EXYNOS4210_IRQ_GATE_NINPUTS]; /* Input levels */
 } Exynos4210IRQGateState;
 
@@ -424,7 +423,7 @@ static int exynos4210_irq_gate_init(SysBusDevice *dev)
             EXYNOS4210_IRQ_GATE_NINPUTS);
 
     /* Connect SysBusDev irqs to device specific irqs */
-    for (i = 0; i < NCPU; i++) {
+    for (i = 0; i < EXYNOS4210_NCPUS; i++) {
         sysbus_init_irq(dev, &s->pic_irq[i]);
     }
 
diff --git a/hw/realview_gic.c b/hw/realview_gic.c
index 071ef13..d114242 100644
--- a/hw/realview_gic.c
+++ b/hw/realview_gic.c
@@ -9,8 +9,6 @@
 
 #include "sysbus.h"
 
-#define NCPU 1
-
 /* Only a single "CPU" interface is present.  */
 static inline int
 gic_get_current_cpu(void)
@@ -40,7 +38,7 @@ static int realview_gic_init(SysBusDevice *dev)
      * number of interrupt lines, so we don't need to expose this as
      * a qdev property.
      */
-    gic_init(&s->gic, 96);
+    gic_init(&s->gic, 1, 96);
     realview_gic_map_setup(s);
     sysbus_init_mmio(dev, &s->container);
     return 0;
commit 5181b50fc89d321cf79ed2f2fff5bec0b55e3011
Author: Evgeny Voevodin <e.voevodin at samsung.com>
Date:   Fri Apr 13 11:39:06 2012 +0000

    hw/exynos4210_combiner.c: Drop excessive read/write access check.
    
    Access to reserved area at offset higher than 0x3c is allowed in
    External Combiner. Samsung Galaxy Kernel implements this. So, drop
    excessive checks in read/write functions.
    
    Signed-off-by: Evgeny Voevodin <e.voevodin at samsung.com>
    Signed-off-by: Peter Maydell <peter.maydell at linaro.org>

diff --git a/hw/exynos4210_combiner.c b/hw/exynos4210_combiner.c
index 6110c19..80af22c 100644
--- a/hw/exynos4210_combiner.c
+++ b/hw/exynos4210_combiner.c
@@ -184,11 +184,6 @@ exynos4210_combiner_read(void *opaque, target_phys_addr_t offset, unsigned size)
     uint32_t reg_n;              /* Register number inside the quad */
     uint32_t val;
 
-    if (s->external && (offset > 0x3c && offset != 0x100)) {
-        hw_error("exynos4210.combiner: unallowed read access at offset 0x"
-                TARGET_FMT_plx "\n", offset);
-    }
-
     req_quad_base_n = offset >> 4;
     grp_quad_base_n = req_quad_base_n << 2;
     reg_n = (offset - (req_quad_base_n << 4)) >> 2;
@@ -281,11 +276,6 @@ static void exynos4210_combiner_write(void *opaque, target_phys_addr_t offset,
     uint32_t grp_quad_base_n;    /* Base of group quad */
     uint32_t reg_n;              /* Register number inside the quad */
 
-    if (s->external && (offset > 0x3c && offset != 0x100)) {
-        hw_error("exynos4210.combiner: unallowed write access at offset 0x"
-                TARGET_FMT_plx "\n", offset);
-    }
-
     req_quad_base_n = offset >> 4;
     grp_quad_base_n = req_quad_base_n << 2;
     reg_n = (offset - (req_quad_base_n << 4)) >> 2;
commit 3f088e36de5a72a69e530d4bbf1fabaa507da0db
Author: Evgeny Voevodin <e.voevodin at samsung.com>
Date:   Fri Apr 13 11:39:06 2012 +0000

    ARM: Exynos4210: Drop gic_cpu_write() after initialization.
    
    Remove gic_cpu_write() call after initialization that was emulating
    functionality of earliest SOC bootloader which enables external
    GIC CPU1 interface. Instead introduce Exynos4210-specific secondary
    CPU bootloader, which enables both Internal and External GIC CPU1
    interfaces.
    
    Signed-off-by: Evgeny Voevodin <e.voevodin at samsung.com>
    Signed-off-by: Peter Maydell <peter.maydell at linaro.org>

diff --git a/hw/exynos4210.c b/hw/exynos4210.c
index f904370..afc4bdc 100644
--- a/hw/exynos4210.c
+++ b/hw/exynos4210.c
@@ -25,6 +25,7 @@
 #include "sysemu.h"
 #include "sysbus.h"
 #include "arm-misc.h"
+#include "loader.h"
 #include "exynos4210.h"
 
 #define EXYNOS4210_CHIPID_ADDR         0x10000000
@@ -64,6 +65,35 @@
 static uint8_t chipid_and_omr[] = { 0x11, 0x02, 0x21, 0x43,
                                     0x09, 0x00, 0x00, 0x00 };
 
+void exynos4210_write_secondary(CPUARMState *env,
+        const struct arm_boot_info *info)
+{
+    int n;
+    uint32_t smpboot[] = {
+        0xe59f3024, /* ldr r3, External gic_cpu_if */
+        0xe59f2024, /* ldr r2, Internal gic_cpu_if */
+        0xe59f0024, /* ldr r0, startaddr */
+        0xe3a01001, /* mov r1, #1 */
+        0xe5821000, /* str r1, [r2] */
+        0xe5831000, /* str r1, [r3] */
+        0xe320f003, /* wfi */
+        0xe5901000, /* ldr     r1, [r0] */
+        0xe1110001, /* tst     r1, r1 */
+        0x0afffffb, /* beq     <wfi> */
+        0xe12fff11, /* bx      r1 */
+        EXYNOS4210_EXT_GIC_CPU_BASE_ADDR,
+        0,          /* gic_cpu_if: base address of Internal GIC CPU interface */
+        0           /* bootreg: Boot register address is held here */
+    };
+    smpboot[ARRAY_SIZE(smpboot) - 1] = info->smp_bootreg_addr;
+    smpboot[ARRAY_SIZE(smpboot) - 2] = info->gic_cpu_if_addr;
+    for (n = 0; n < ARRAY_SIZE(smpboot); n++) {
+        smpboot[n] = tswap32(smpboot[n]);
+    }
+    rom_add_blob_fixed("smpboot", smpboot, sizeof(smpboot),
+                       info->smp_loader_start);
+}
+
 Exynos4210State *exynos4210_init(MemoryRegion *system_mem,
         unsigned long ram_size)
 {
diff --git a/hw/exynos4210.h b/hw/exynos4210.h
index c112e03..f7c7027 100644
--- a/hw/exynos4210.h
+++ b/hw/exynos4210.h
@@ -97,6 +97,9 @@ typedef struct Exynos4210State {
     MemoryRegion bootreg_mem;
 } Exynos4210State;
 
+void exynos4210_write_secondary(CPUARMState *env,
+        const struct arm_boot_info *info);
+
 Exynos4210State *exynos4210_init(MemoryRegion *system_mem,
         unsigned long ram_size);
 
diff --git a/hw/exynos4210_gic.c b/hw/exynos4210_gic.c
index ec13140..3ba9063 100644
--- a/hw/exynos4210_gic.c
+++ b/hw/exynos4210_gic.c
@@ -321,8 +321,6 @@ static int exynos4210_gic_init(SysBusDevice *dev)
     sysbus_init_mmio(dev, &s->cpu_container);
     sysbus_init_mmio(dev, &s->dist_container);
 
-    gic_cpu_write(&s->gic, 1, 0, 1);
-
     return 0;
 }
 
diff --git a/hw/exynos4_boards.c b/hw/exynos4_boards.c
index 553a02b..ea32c51 100644
--- a/hw/exynos4_boards.c
+++ b/hw/exynos4_boards.c
@@ -70,6 +70,7 @@ static struct arm_boot_info exynos4_board_binfo = {
     .loader_start     = EXYNOS4210_BASE_BOOT_ADDR,
     .smp_loader_start = EXYNOS4210_SMP_BOOT_ADDR,
     .nb_cpus          = EXYNOS4210_NCPUS,
+    .write_secondary_boot = exynos4210_write_secondary,
 };
 
 static QEMUMachine exynos4_machines[EXYNOS4_NUM_OF_BOARDS];
commit b85f62d7811c80646065f8f96c2248ea86cfd911
Author: Daniel P. Berrange <berrange at redhat.com>
Date:   Fri Apr 13 11:39:06 2012 +0000

    Fix bit test in Exynos4210 UART emulation to use & instead of &&
    
    * hw/exynos4210_uart.c: s/&&/&/
    
    Signed-off-by: Daniel P. Berrange <berrange at redhat.com>
    Signed-off-by: Peter Maydell <peter.maydell at linaro.org>

diff --git a/hw/exynos4210_uart.c b/hw/exynos4210_uart.c
index 73a9c18..ccc4780 100644
--- a/hw/exynos4210_uart.c
+++ b/hw/exynos4210_uart.c
@@ -246,7 +246,7 @@ static uint32_t exynos4210_uart_Tx_FIFO_trigger_level(Exynos4210UartState *s)
     uint32_t level = 0;
     uint32_t reg;
 
-    reg = (s->reg[I_(UFCON)] && UFCON_Tx_FIFO_TRIGGER_LEVEL) >>
+    reg = (s->reg[I_(UFCON)] & UFCON_Tx_FIFO_TRIGGER_LEVEL) >>
             UFCON_Tx_FIFO_TRIGGER_LEVEL_SHIFT;
 
     switch (s->channel) {
@@ -275,9 +275,9 @@ static void exynos4210_uart_update_irq(Exynos4210UartState *s)
      * The Tx interrupt is always requested if the number of data in the
      * transmit FIFO is smaller than the trigger level.
      */
-    if (s->reg[I_(UFCON)] && UFCON_FIFO_ENABLE) {
+    if (s->reg[I_(UFCON)] & UFCON_FIFO_ENABLE) {
 
-        uint32_t count = (s->reg[I_(UFSTAT)] && UFSTAT_Tx_FIFO_COUNT) >>
+        uint32_t count = (s->reg[I_(UFSTAT)] & UFSTAT_Tx_FIFO_COUNT) >>
                 UFSTAT_Tx_FIFO_COUNT_SHIFT;
 
         if (count <= exynos4210_uart_Tx_FIFO_trigger_level(s)) {
commit 6ccea1e4d9a39d0bcf5be5a7b49270c2132b9dcb
Author: Peter Maydell <peter.maydell at linaro.org>
Date:   Thu Apr 12 19:09:52 2012 +0100

    configure: Insist on a Python 2, not Python 3
    
    Our Python scripts require Python 2 and will fail on Python 3, eg:
      File "/home/petmay01/linaro/qemu-from-laptop/qemu/scripts/qapi-commands.py", line 378
          except getopt.GetoptError, err:
                                   ^
      SyntaxError: invalid syntax
    
    Add a check to configure that Python is not a Python 3, so we can
    fail with a comprehensible error rather than an obscure one.
    
    Reported-by: Boris Matti <swiftos at lavabit.com>
    Signed-off-by: Peter Maydell <peter.maydell at linaro.org>
    Signed-off-by: Stefan Hajnoczi <stefanha at linux.vnet.ibm.com>

diff --git a/configure b/configure
index b392c6f..1d94acd 100755
--- a/configure
+++ b/configure
@@ -1242,6 +1242,14 @@ if ! has $python; then
   exit 1
 fi
 
+# Note that if the Python conditional here evaluates True we will exit
+# with status 1 which is a shell 'false' value.
+if ! "$python" -c 'import sys; sys.exit(sys.version_info[0] >= 3)'; then
+  echo "Python 2 required but '$python' is version 3 or better."
+  echo "Use --python=/path/to/python to specify a Python 2."
+  exit 1
+fi
+
 if test -z "$target_list" ; then
     target_list="$default_target_list"
 else
commit d6ef40bf1881ddc82c8d64e72d412090efe1190e
Author: Peter Maydell <peter.maydell at linaro.org>
Date:   Thu Apr 12 12:43:41 2012 +0100

    bsd-user: fix compile failure
    
    bsd-user doesn't actually support reserving a memory area for the
    guest address space, but we need to at least define the reserved_va
    global so that cpu-all.h's RESERVED_VA macro will work correctly.
    
    This fixes a compilation error introduced in commit 39879bb
    which added a use of RESERVED_VA to h2g_valid().
    
    Reported-by: Brad Smith <brad at comstyle.com>
    Signed-off-by: Peter Maydell <peter.maydell at linaro.org>
    Reviewed-by: Stefan Weil <sw at weilnetz.de>
    Signed-off-by: Stefan Hajnoczi <stefanha at linux.vnet.ibm.com>

diff --git a/bsd-user/main.c b/bsd-user/main.c
index 48cb715..0689e38 100644
--- a/bsd-user/main.c
+++ b/bsd-user/main.c
@@ -41,6 +41,7 @@ int singlestep;
 unsigned long mmap_min_addr;
 unsigned long guest_base;
 int have_guest_base;
+unsigned long reserved_va;
 #endif
 
 static const char *interp_prefix = CONFIG_QEMU_INTERP_PREFIX;
commit f349c12c0434e29c79ecde89029320c4002f7253
Author: Eric B Munson <emunson at mgebm.net>
Date:   Sat Apr 7 06:17:47 2012 +0530

    kvmclock: guest stop notification
    
    Often when a guest is stopped from the qemu console, it will report spurious
    soft lockup warnings on resume.  There are kernel patches being discussed that
    will give the host the ability to tell the guest that it is being stopped and
    should ignore the soft lockup warning that generates.  This patch uses the qemu
    Notifier system to tell the guest it is about to be stopped.
    
    Signed-off-by: Eric B Munson <emunson at mgebm.net>
    Signed-off-by: Raghavendra K T <raghavendra.kt at linux.vnet.ibm.com>
    Reviewed-by: Andreas Färber <afaerber at suse.de>
    Signed-off-by: Marcelo Tosatti <mtosatti at redhat.com>

diff --git a/hw/kvm/clock.c b/hw/kvm/clock.c
index 446bd62..824b978 100644
--- a/hw/kvm/clock.c
+++ b/hw/kvm/clock.c
@@ -65,9 +65,25 @@ static void kvmclock_vm_state_change(void *opaque, int running,
                                      RunState state)
 {
     KVMClockState *s = opaque;
+    CPUArchState *penv = first_cpu;
+    int cap_clock_ctrl = kvm_check_extension(kvm_state, KVM_CAP_KVMCLOCK_CTRL);
+    int ret;
 
     if (running) {
         s->clock_valid = false;
+
+        if (!cap_clock_ctrl) {
+            return;
+        }
+        for (penv = first_cpu; penv != NULL; penv = penv->next_cpu) {
+            ret = kvm_vcpu_ioctl(penv, KVM_KVMCLOCK_CTRL, 0);
+            if (ret) {
+                if (ret != -EINVAL) {
+                    fprintf(stderr, "%s: %s\n", __func__, strerror(-ret));
+                }
+                return;
+            }
+        }
     }
 }
 
commit 9ab2195dcb2e7d202287b6db7cfaa4f9e01941f6
Author: Marcelo Tosatti <mtosatti at redhat.com>
Date:   Thu Apr 12 00:43:27 2012 -0300

    kvm: update linux headers
    
    Signed-off-by: Marcelo Tosatti <mtosatti at redhat.com>

diff --git a/linux-headers/asm-powerpc/kvm.h b/linux-headers/asm-powerpc/kvm.h
index b921c3f..1bea4d8 100644
--- a/linux-headers/asm-powerpc/kvm.h
+++ b/linux-headers/asm-powerpc/kvm.h
@@ -277,6 +277,7 @@ struct kvm_sync_regs {
 #define KVM_CPU_E500V2		2
 #define KVM_CPU_3S_32		3
 #define KVM_CPU_3S_64		4
+#define KVM_CPU_E500MC		5
 
 /* for KVM_CAP_SPAPR_TCE */
 struct kvm_create_spapr_tce {
diff --git a/linux-headers/asm-s390/kvm.h b/linux-headers/asm-s390/kvm.h
index 9acbde4..9607667 100644
--- a/linux-headers/asm-s390/kvm.h
+++ b/linux-headers/asm-s390/kvm.h
@@ -44,10 +44,12 @@ struct kvm_guest_debug_arch {
 #define KVM_SYNC_PREFIX (1UL << 0)
 #define KVM_SYNC_GPRS   (1UL << 1)
 #define KVM_SYNC_ACRS   (1UL << 2)
+#define KVM_SYNC_CRS    (1UL << 3)
 /* definition of registers in kvm_run */
 struct kvm_sync_regs {
 	__u64 prefix;	/* prefix register */
 	__u64 gprs[16];	/* general purpose registers */
 	__u32 acrs[16];	/* access registers */
+	__u64 crs[16];	/* control registers */
 };
 #endif
diff --git a/linux-headers/linux/kvm.h b/linux-headers/linux/kvm.h
index f6b5343..ee7bd9c 100644
--- a/linux-headers/linux/kvm.h
+++ b/linux-headers/linux/kvm.h
@@ -588,6 +588,8 @@ struct kvm_ppc_pvinfo {
 #define KVM_CAP_TSC_DEADLINE_TIMER 72
 #define KVM_CAP_S390_UCONTROL 73
 #define KVM_CAP_SYNC_REGS 74
+#define KVM_CAP_PCI_2_3 75
+#define KVM_CAP_KVMCLOCK_CTRL 76
 
 #ifdef KVM_CAP_IRQ_ROUTING
 
@@ -784,6 +786,9 @@ struct kvm_s390_ucas_mapping {
 /* Available with KVM_CAP_TSC_CONTROL */
 #define KVM_SET_TSC_KHZ           _IO(KVMIO,  0xa2)
 #define KVM_GET_TSC_KHZ           _IO(KVMIO,  0xa3)
+/* Available with KVM_CAP_PCI_2_3 */
+#define KVM_ASSIGN_SET_INTX_MASK  _IOW(KVMIO,  0xa4, \
+				       struct kvm_assigned_pci_dev)
 
 /*
  * ioctls for vcpu fds
@@ -855,8 +860,12 @@ struct kvm_s390_ucas_mapping {
 /* Available with KVM_CAP_ONE_REG */
 #define KVM_GET_ONE_REG		  _IOW(KVMIO,  0xab, struct kvm_one_reg)
 #define KVM_SET_ONE_REG		  _IOW(KVMIO,  0xac, struct kvm_one_reg)
+/* VM is being stopped by host */
+#define KVM_KVMCLOCK_CTRL	  _IO(KVMIO,   0xad)
 
 #define KVM_DEV_ASSIGN_ENABLE_IOMMU	(1 << 0)
+#define KVM_DEV_ASSIGN_PCI_2_3		(1 << 1)
+#define KVM_DEV_ASSIGN_MASK_INTX	(1 << 2)
 
 struct kvm_assigned_pci_dev {
 	__u32 assigned_dev_id;
commit bc8c6788b60cbbe56700568bcb645e139ab29b7d
Author: Jason Baron <jbaron at redhat.com>
Date:   Wed Mar 28 14:18:05 2012 -0400

    kvm: set gsi_bits and max_gsi correctly
    
    The current kvm_init_irq_routing() doesn't set up the used_gsi_bitmap
    correctly, and as a consequence pins max_gsi to 32 when it really
    should be 1024. I ran into this limitation while testing pci
    passthrough, where I consistently got an -ENOSPC return from
    kvm_get_irq_route_gsi() called from assigned_dev_update_msix_mmio().
    
    Signed-off-by: Jason Baron <jbaron at redhat.com>
    Acked-by: Alex Williamson <alex.williamson at redhat.com>
    Acked-by: Jan Kiszka <jan.kiszka at siemens.com>
    Signed-off-by: Marcelo Tosatti <mtosatti at redhat.com>

diff --git a/kvm-all.c b/kvm-all.c
index 5ff954a..b8e9dc6 100644
--- a/kvm-all.c
+++ b/kvm-all.c
@@ -871,7 +871,7 @@ static void kvm_init_irq_routing(KVMState *s)
         unsigned int gsi_bits, i;
 
         /* Round up so we can search ints using ffs */
-        gsi_bits = (gsi_count + 31) / 32;
+        gsi_bits = ALIGN(gsi_count, 32);
         s->used_gsi_bitmap = g_malloc0(gsi_bits / 8);
         s->max_gsi = gsi_bits;
 
commit c73b00973b13a4a1e823ce935bcfe264c758b40b
Author: Jan Kiszka <jan.kiszka at siemens.com>
Date:   Thu Mar 22 00:00:48 2012 +0100

    kvm: Drop unused kvm_pit_in_kernel
    
    This is now implied by kvm_irqchip_in_kernel.
    
    Signed-off-by: Jan Kiszka <jan.kiszka at siemens.com>
    Signed-off-by: Marcelo Tosatti <mtosatti at redhat.com>

diff --git a/kvm-all.c b/kvm-all.c
index f1cb69f..5ff954a 100644
--- a/kvm-all.c
+++ b/kvm-all.c
@@ -75,7 +75,6 @@ struct KVMState
 #ifdef KVM_CAP_SET_GUEST_DEBUG
     struct kvm_sw_breakpoint_head kvm_sw_breakpoints;
 #endif
-    int pit_in_kernel;
     int pit_state2;
     int xsave, xcrs;
     int many_ioeventfds;
@@ -198,11 +197,6 @@ static void kvm_reset_vcpu(void *opaque)
     kvm_arch_reset_vcpu(env);
 }
 
-int kvm_pit_in_kernel(void)
-{
-    return kvm_state->pit_in_kernel;
-}
-
 int kvm_init_vcpu(CPUArchState *env)
 {
     KVMState *s = kvm_state;
diff --git a/kvm-stub.c b/kvm-stub.c
index 0d426db..47c573d 100644
--- a/kvm-stub.c
+++ b/kvm-stub.c
@@ -16,12 +16,6 @@
 #include "gdbstub.h"
 #include "kvm.h"
 
-int kvm_pit_in_kernel(void)
-{
-    return 0;
-}
-
-
 int kvm_init_vcpu(CPUArchState *env)
 {
     return -ENOSYS;
diff --git a/kvm.h b/kvm.h
index 9bdbdb0..4ccae8c 100644
--- a/kvm.h
+++ b/kvm.h
@@ -83,8 +83,6 @@ int kvm_update_guest_debug(CPUArchState *env, unsigned long reinject_trap);
 int kvm_set_signal_mask(CPUArchState *env, const sigset_t *sigset);
 #endif
 
-int kvm_pit_in_kernel(void);
-
 int kvm_on_sigbus_vcpu(CPUArchState *env, int code, void *addr);
 int kvm_on_sigbus(int code, void *addr);
 
commit 4b8f1c88e9de2ded754b12a967a93d395bed1245
Author: Michael S. Tsirkin <mst at redhat.com>
Date:   Tue Mar 20 14:31:38 2012 +0200

    kvm: allow arbitrarily sized mmio ioeventfd
    
    We use a 2 byte ioeventfd for virtio memory,
    add support for this.
    
    Signed-off-by: Michael S. Tsirkin <mst at redhat.com>
    Reviewed-by: Amos Kong <akong at redhat.com>
    Signed-off-by: Avi Kivity <avi at redhat.com>

diff --git a/hw/ivshmem.c b/hw/ivshmem.c
index b80aa8f..df4f50a 100644
--- a/hw/ivshmem.c
+++ b/hw/ivshmem.c
@@ -354,8 +354,8 @@ static void close_guest_eventfds(IVShmemState *s, int posn)
     guest_curr_max = s->peers[posn].nb_eventfds;
 
     for (i = 0; i < guest_curr_max; i++) {
-        kvm_set_ioeventfd_mmio_long(s->peers[posn].eventfds[i],
-                    s->mmio_addr + DOORBELL, (posn << 16) | i, 0);
+        kvm_set_ioeventfd_mmio(s->peers[posn].eventfds[i],
+                    s->mmio_addr + DOORBELL, (posn << 16) | i, 0, 4);
         close(s->peers[posn].eventfds[i]);
     }
 
@@ -500,8 +500,8 @@ static void ivshmem_read(void *opaque, const uint8_t * buf, int flags)
     }
 
     if (ivshmem_has_feature(s, IVSHMEM_IOEVENTFD)) {
-        if (kvm_set_ioeventfd_mmio_long(incoming_fd, s->mmio_addr + DOORBELL,
-                        (incoming_posn << 16) | guest_max_eventfd, 1) < 0) {
+        if (kvm_set_ioeventfd_mmio(incoming_fd, s->mmio_addr + DOORBELL,
+                        (incoming_posn << 16) | guest_max_eventfd, 1, 4) < 0) {
             fprintf(stderr, "ivshmem: ioeventfd not available\n");
         }
     }
diff --git a/kvm-all.c b/kvm-all.c
index ba2cee1..f1cb69f 100644
--- a/kvm-all.c
+++ b/kvm-all.c
@@ -747,10 +747,10 @@ static void kvm_mem_ioeventfd_add(MemoryRegionSection *section,
 {
     int r;
 
-    assert(match_data && section->size == 4);
+    assert(match_data && section->size <= 8);
 
-    r = kvm_set_ioeventfd_mmio_long(fd, section->offset_within_address_space,
-                                    data, true);
+    r = kvm_set_ioeventfd_mmio(fd, section->offset_within_address_space,
+                               data, true, section->size);
     if (r < 0) {
         abort();
     }
@@ -761,8 +761,8 @@ static void kvm_mem_ioeventfd_del(MemoryRegionSection *section,
 {
     int r;
 
-    r = kvm_set_ioeventfd_mmio_long(fd, section->offset_within_address_space,
-                                    data, false);
+    r = kvm_set_ioeventfd_mmio(fd, section->offset_within_address_space,
+                               data, false, section->size);
     if (r < 0) {
         abort();
     }
@@ -1642,14 +1642,15 @@ int kvm_set_signal_mask(CPUArchState *env, const sigset_t *sigset)
     return r;
 }
 
-int kvm_set_ioeventfd_mmio_long(int fd, uint32_t addr, uint32_t val, bool assign)
+int kvm_set_ioeventfd_mmio(int fd, uint32_t addr, uint32_t val, bool assign,
+                           uint32_t size)
 {
     int ret;
     struct kvm_ioeventfd iofd;
 
     iofd.datamatch = val;
     iofd.addr = addr;
-    iofd.len = 4;
+    iofd.len = size;
     iofd.flags = KVM_IOEVENTFD_FLAG_DATAMATCH;
     iofd.fd = fd;
 
diff --git a/kvm-stub.c b/kvm-stub.c
index 69a1228..0d426db 100644
--- a/kvm-stub.c
+++ b/kvm-stub.c
@@ -120,7 +120,7 @@ int kvm_set_ioeventfd_pio_word(int fd, uint16_t addr, uint16_t val, bool assign)
     return -ENOSYS;
 }
 
-int kvm_set_ioeventfd_mmio_long(int fd, uint32_t adr, uint32_t val, bool assign)
+int kvm_set_ioeventfd_mmio(int fd, uint32_t adr, uint32_t val, bool assign, uint32_t len)
 {
     return -ENOSYS;
 }
diff --git a/kvm.h b/kvm.h
index 330f17b..9bdbdb0 100644
--- a/kvm.h
+++ b/kvm.h
@@ -210,7 +210,8 @@ int kvm_physical_memory_addr_from_host(KVMState *s, void *ram_addr,
 #endif
 
 #endif
-int kvm_set_ioeventfd_mmio_long(int fd, uint32_t adr, uint32_t val, bool assign);
+int kvm_set_ioeventfd_mmio(int fd, uint32_t adr, uint32_t val, bool assign,
+                           uint32_t size);
 
 int kvm_set_ioeventfd_pio_word(int fd, uint16_t adr, uint16_t val, bool assign);
 #endif
commit 56b9ead234439317629054fa370c547c652ab09a
Author: Jan Kiszka <jan.kiszka at siemens.com>
Date:   Wed Mar 21 13:36:22 2012 +0100

    kvm: Drop redundant kvm_enabled from cpu_thread_is_idle
    
    This is now implied by kvm_irqchip_in_kernel.
    
    Signed-off-by: Jan Kiszka <jan.kiszka at siemens.com>
    Signed-off-by: Avi Kivity <avi at redhat.com>

diff --git a/cpus.c b/cpus.c
index eb22bd5..b182b3d 100644
--- a/cpus.c
+++ b/cpus.c
@@ -441,8 +441,7 @@ static bool cpu_thread_is_idle(CPUArchState *env)
     if (env->stopped || !runstate_is_running()) {
         return true;
     }
-    if (!env->halted || qemu_cpu_has_work(env) ||
-        (kvm_enabled() && kvm_irqchip_in_kernel())) {
+    if (!env->halted || qemu_cpu_has_work(env) || kvm_irqchip_in_kernel()) {
         return false;
     }
     return true;
commit b3c09bde4842f1b157bc4431135aad4f2031e312
Author: Stefan Hajnoczi <stefanha at linux.vnet.ibm.com>
Date:   Fri Mar 9 14:13:40 2012 +0000

    kvm: add flightrecorder script
    
    The kvm kernel module includes a number of trace events which can be
    useful when debugging system behavior.  Even on production systems these
    trace events can be used to observe guest behavior and identify the
    source of problems.
    
    The kvm_flightrecorder script is a command-line wrapper for the
    /sys/kernel/debug/tracing interface.  Kernel symbols do not need to be
    installed.
    
    This script captures a fixed-size buffer of KVM trace events.  Recent
    events overwrite the oldest events when the buffer size is exceeded and
    it is possible to leave KVM tracing enabled for any period of time with
    just a fixed-size buffer.  If the buffer is large enough this script is
    a useful tool for collecting detailed information after an issue occurs
    with a guest.  Hence the name "flight recorder".
    
    The script can also be used in 'tail' mode to simply view KVM trace
    events as they occur.  This is handy for development and to ensure that
    the guest is indeed running.
    
    Signed-off-by: Stefan Hajnoczi <stefanha at linux.vnet.ibm.com>
    Signed-off-by: Marcelo Tosatti <mtosatti at redhat.com>

diff --git a/scripts/kvm/kvm_flightrecorder b/scripts/kvm/kvm_flightrecorder
new file mode 100755
index 0000000..7fb1c2d
--- /dev/null
+++ b/scripts/kvm/kvm_flightrecorder
@@ -0,0 +1,126 @@
+#!/usr/bin/env python
+#
+# KVM Flight Recorder - ring buffer tracing script
+#
+# Copyright (C) 2012 IBM Corp
+#
+# Author: Stefan Hajnoczi <stefanha at linux.vnet.ibm.com>
+#
+# This script provides a command-line interface to kvm ftrace and is designed
+# to be used as a flight recorder that is always running.  To start in-memory
+# recording:
+#
+# sudo kvm_flightrecorder start 8192  # 8 MB per-cpu ring buffers
+#
+# The per-cpu ring buffer size can be given in KB as an optional argument to
+# the 'start' subcommand.
+#
+# To stop the flight recorder:
+#
+# sudo kvm_flightrecorder stop
+#
+# To dump the contents of the flight recorder (this can be done when the
+# recorder is stopped or while it is running):
+#
+# sudo kvm_flightrecorder dump >/path/to/dump.txt
+#
+# To observe the trace while it is running, use the 'tail' subcommand:
+#
+# sudo kvm_flightrecorder tail
+#
+# Note that the flight recorder may impact overall system performance by
+# consuming CPU cycles.  No disk I/O is performed since the ring buffer holds a
+# fixed-size in-memory trace.
+
+import sys
+import os
+
+tracing_dir = '/sys/kernel/debug/tracing'
+
+def trace_path(*args):
+    return os.path.join(tracing_dir, *args)
+
+def write_file(path, data):
+    open(path, 'wb').write(data)
+
+def enable_event(subsystem, event, enable):
+    write_file(trace_path('events', subsystem, event, 'enable'), '1' if enable else '0')
+
+def enable_subsystem(subsystem, enable):
+    write_file(trace_path('events', subsystem, 'enable'), '1' if enable else '0')
+
+def start_tracing():
+    enable_subsystem('kvm', True)
+    write_file(trace_path('tracing_on'), '1')
+
+def stop_tracing():
+    write_file(trace_path('tracing_on'), '0')
+    enable_subsystem('kvm', False)
+    write_file(trace_path('events', 'enable'), '0')
+    write_file(trace_path('current_tracer'), 'nop')
+
+def dump_trace():
+    tracefile = open(trace_path('trace'), 'r')
+    try:
+        lines = True
+        while lines:
+            lines = tracefile.readlines(64 * 1024)
+            sys.stdout.writelines(lines)
+    except KeyboardInterrupt:
+        pass
+
+def tail_trace():
+    try:
+        for line in open(trace_path('trace_pipe'), 'r'):
+            sys.stdout.write(line)
+    except KeyboardInterrupt:
+        pass
+
+def usage():
+    print 'Usage: %s start [buffer_size_kb] | stop | dump | tail' % sys.argv[0]
+    print 'Control the KVM flight recorder tracing.'
+    sys.exit(0)
+
+def main():
+    if len(sys.argv) < 2:
+        usage()
+
+    cmd = sys.argv[1]
+    if cmd == '--version':
+        print 'kvm_flightrecorder version 1.0'
+        sys.exit(0)
+
+    if not os.path.isdir(tracing_dir):
+        print 'Unable to tracing debugfs directory, try:'
+        print 'mount -t debugfs none /sys/kernel/debug'
+        sys.exit(1)
+    if not os.access(tracing_dir, os.W_OK):
+        print 'Unable to write to tracing debugfs directory, please run as root'
+        sys.exit(1)
+
+    if cmd == 'start':
+        stop_tracing() # clean up first
+
+        if len(sys.argv) == 3:
+            try:
+                buffer_size_kb = int(sys.argv[2])
+            except ValueError:
+                print 'Invalid per-cpu trace buffer size in KB'
+                sys.exit(1)
+            write_file(trace_path('buffer_size_kb'), str(buffer_size_kb))
+            print 'Per-CPU ring buffer size set to %d KB' % buffer_size_kb
+
+        start_tracing()
+        print 'KVM flight recorder enabled'
+    elif cmd == 'stop':
+        stop_tracing()
+        print 'KVM flight recorder disabled'
+    elif cmd == 'dump':
+        dump_trace()
+    elif cmd == 'tail':
+        tail_trace()
+    else:
+        usage()
+
+if __name__ == '__main__':
+    sys.exit(main())
commit fd65f595fe14dafeee1cd34df0dbe288ed6a5f06
Author: Wanpeng Li <liwp at linux.vnet.ibm.com>
Date:   Wed Apr 11 09:02:21 2012 +0800

    ps2: avoid repeated header file includes
    
    Signed-off-by: Wanpeng Li <liwp at linux.vnet.ibm.com>
    Signed-off-by: Stefan Hajnoczi <stefanha at linux.vnet.ibm.com>

diff --git a/hw/ps2.h b/hw/ps2.h
index 32a4231..7c45ce7 100644
--- a/hw/ps2.h
+++ b/hw/ps2.h
@@ -1,3 +1,30 @@
+/*
+ * QEMU PS/2 keyboard/mouse emulation
+ *
+ * Copyright (C) 2003 Fabrice Bellard
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+
+#ifndef HW_PS2_H
+#define HW_PS2_H
+
 /* ps2.c */
 void *ps2_kbd_init(void (*update_irq)(void *, int), void *update_arg);
 void *ps2_mouse_init(void (*update_irq)(void *, int), void *update_arg);
@@ -7,3 +34,5 @@ uint32_t ps2_read_data(void *);
 void ps2_queue(void *, int b);
 void ps2_keyboard_set_translation(void *opaque, int mode);
 void ps2_mouse_fake_event(void *opaque);
+
+#endif /* !HW_PS2_H */
commit 952ef67cc06a636fe11344e3a11137d146222bc4
Author: Stefan Weil <sw at weilnetz.de>
Date:   Tue Mar 27 19:15:27 2012 +0200

    make: Always set LC_ALL=C for makeinfo
    
    Otherwise the generated file qemu-doc.html will contain "Anhang"
    instead of "Appendix" with a German locale (de_DE.UTF-8).
    
    Signed-off-by: Stefan Weil <sw at weilnetz.de>
    Signed-off-by: Stefan Hajnoczi <stefanha at linux.vnet.ibm.com>

diff --git a/Makefile b/Makefile
index a78f53d..e0fe680 100644
--- a/Makefile
+++ b/Makefile
@@ -328,7 +328,7 @@ TEXIFLAG=$(if $(V),,--quiet)
 	$(call quiet-command,texi2dvi $(TEXIFLAG) -I . $<,"  GEN   $@")
 
 %.html: %.texi
-	$(call quiet-command,$(MAKEINFO) $(MAKEINFOFLAGS) --html $< -o $@, \
+	$(call quiet-command,LC_ALL=C $(MAKEINFO) $(MAKEINFOFLAGS) --html $< -o $@, \
 	"  GEN   $@")
 
 %.info: %.texi
commit e172fe1177ffa14f6d13cc539dd80d2a2705aa73
Author: Stefan Weil <sw at weilnetz.de>
Date:   Fri Apr 6 21:33:20 2012 +0200

    configure: Fix wrong preprocessor statement
    
    #abort is not a preprocessor statement. It aborts, but the preprocessor
    statement #error is more common to abort a compilation.
    
    Signed-off-by: Stefan Weil <sw at weilnetz.de>
    Signed-off-by: Stefan Hajnoczi <stefanha at linux.vnet.ibm.com>

diff --git a/configure b/configure
index 5aaafa1..b392c6f 100755
--- a/configure
+++ b/configure
@@ -2624,7 +2624,7 @@ int main(void) {
 #if defined(_POSIX_SYNCHRONIZED_IO) && _POSIX_SYNCHRONIZED_IO > 0
 return fdatasync(0);
 #else
-#abort Not supported
+#error Not supported
 #endif
 }
 EOF
commit 8fb03151651cc61f68f8032374c9c08dc129b9d9
Author: Peter Maydell <peter.maydell at linaro.org>
Date:   Wed Apr 4 17:03:15 2012 +0100

    configure: Remove useless uses of ARCH_CFLAGS
    
    Remove some useless uses of ARCH_CFLAGS -- this variable was never set
    so will always be empty. The uses were accidental: in commit 0c439cbf8
    Juan Quintela removed ARCH_CFLAGS in favour of CFLAGS (which in turn
    became QEMU_CFLAGS). However in commit be17dc90 a use of it was
    reintroduced (apparently accidentally) by Michael S. Tsirkin, and then
    I subsequently cut-n-pasted that into a number of other configure
    feature tests.
    
    Signed-off-by: Peter Maydell <peter.maydell at linaro.org>
    Reviewed-by: Andreas Färber <afaerber at suse.de>
    Reviewed-by: Juan Quintela <quintela at redhat.com>
    Signed-off-by: Stefan Hajnoczi <stefanha at linux.vnet.ibm.com>

diff --git a/configure b/configure
index e05f34b..5aaafa1 100755
--- a/configure
+++ b/configure
@@ -2369,7 +2369,7 @@ int main(void)
     return 0;
 }
 EOF
-if compile_prog "$ARCH_CFLAGS" "" ; then
+if compile_prog "" "" ; then
   fallocate=yes
 fi
 
@@ -2384,7 +2384,7 @@ int main(void)
     return 0;
 }
 EOF
-if compile_prog "$ARCH_CFLAGS" "" ; then
+if compile_prog "" "" ; then
   sync_file_range=yes
 fi
 
@@ -2401,7 +2401,7 @@ int main(void)
     return 0;
 }
 EOF
-if compile_prog "$ARCH_CFLAGS" "" ; then
+if compile_prog "" "" ; then
   fiemap=yes
 fi
 
@@ -2431,7 +2431,7 @@ int main(void)
     return 0;
 }
 EOF
-if compile_prog "$ARCH_CFLAGS" "" ; then
+if compile_prog "" "" ; then
   epoll=yes
 fi
 
@@ -2454,7 +2454,7 @@ int main(void)
     return epoll_create1 == epoll_create1;
 }
 EOF
-if compile_prog "$ARCH_CFLAGS" "" ; then
+if compile_prog "" "" ; then
   epoll_create1=yes
 fi
 
@@ -2468,7 +2468,7 @@ int main(void)
     return 0;
 }
 EOF
-if compile_prog "$ARCH_CFLAGS" "" ; then
+if compile_prog "" "" ; then
   epoll_pwait=yes
 fi
 
commit dadc1064c348545695b8a14d9dc72ccaa2983be7
Author: Peter A. G. Crosthwaite <peter.crosthwaite at petalogix.com>
Date:   Thu Apr 12 14:30:30 2012 +1000

    target-microblaze: added PetaLogix copyright
    
    Microblaze cpu development has been driven and funded by PetaLogix. Added (c)
    PetaLogix line accordingly.
    
    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/target-microblaze/helper.c b/target-microblaze/helper.c
index 6e0e411..2412a58 100644
--- a/target-microblaze/helper.c
+++ b/target-microblaze/helper.c
@@ -2,6 +2,7 @@
  *  MicroBlaze helper routines.
  *
  *  Copyright (c) 2009 Edgar E. Iglesias <edgar.iglesias at gmail.com>
+ *  Copyright (c) 2009-2012 PetaLogix Qld Pty Ltd.
  *
  * This library is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
diff --git a/target-microblaze/mmu.c b/target-microblaze/mmu.c
index 43092e5..53ad263 100644
--- a/target-microblaze/mmu.c
+++ b/target-microblaze/mmu.c
@@ -2,6 +2,7 @@
  *  Microblaze MMU emulation for qemu.
  *
  *  Copyright (c) 2009 Edgar E. Iglesias
+ *  Copyright (c) 2009-2012 PetaLogix Qld Pty Ltd.
  *
  * This library is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
diff --git a/target-microblaze/op_helper.c b/target-microblaze/op_helper.c
index 76cc0e0..a83da8d 100644
--- a/target-microblaze/op_helper.c
+++ b/target-microblaze/op_helper.c
@@ -2,6 +2,7 @@
  *  Microblaze helper routines.
  *
  *  Copyright (c) 2009 Edgar E. Iglesias <edgar.iglesias at gmail.com>.
+ *  Copyright (c) 2009-2012 PetaLogix Qld Pty Ltd.
  *
  * This library is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
diff --git a/target-microblaze/translate.c b/target-microblaze/translate.c
index 64cbfb8..b602820 100644
--- a/target-microblaze/translate.c
+++ b/target-microblaze/translate.c
@@ -2,6 +2,7 @@
  *  Xilinx MicroBlaze emulation for qemu: main translation routines.
  *
  *  Copyright (c) 2009 Edgar E. Iglesias.
+ *  Copyright (c) 2009-2012 PetaLogix Qld Pty Ltd.
  *
  * This library is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
commit 3eab1690851fa68698612d9dd9d5231759f549c2
Author: Andreas Färber <afaerber at suse.de>
Date:   Wed Apr 11 01:37:45 2012 +0200

    target-lm32: QOM'ify CPU reset
    
    Move code from cpu_state_reset() into QOM lm32_cpu_reset().
    
    Signed-off-by: Andreas Färber <afaerber at suse.de>
    Acked-by: Michael Walle <michael at walle.cc>

diff --git a/target-lm32/cpu.c b/target-lm32/cpu.c
index 70251d0..48a5fe3 100644
--- a/target-lm32/cpu.c
+++ b/target-lm32/cpu.c
@@ -29,9 +29,17 @@ static void lm32_cpu_reset(CPUState *s)
     LM32CPUClass *lcc = LM32_CPU_GET_CLASS(cpu);
     CPULM32State *env = &cpu->env;
 
+    if (qemu_loglevel_mask(CPU_LOG_RESET)) {
+        qemu_log("CPU Reset (CPU %d)\n", env->cpu_index);
+        log_cpu_state(env, 0);
+    }
+
     lcc->parent_reset(s);
 
-    cpu_state_reset(env);
+    tlb_flush(env, 1);
+
+    /* reset cpu state */
+    memset(env, 0, offsetof(CPULM32State, breakpoints));
 }
 
 static void lm32_cpu_initfn(Object *obj)
diff --git a/target-lm32/helper.c b/target-lm32/helper.c
index 9de777f..d0bc193 100644
--- a/target-lm32/helper.c
+++ b/target-lm32/helper.c
@@ -236,14 +236,6 @@ void cpu_lm32_set_phys_msb_ignore(CPULM32State *env, int value)
 
 void cpu_state_reset(CPULM32State *env)
 {
-    if (qemu_loglevel_mask(CPU_LOG_RESET)) {
-        qemu_log("CPU Reset (CPU %d)\n", env->cpu_index);
-        log_cpu_state(env, 0);
-    }
-
-    tlb_flush(env, 1);
-
-    /* reset cpu state */
-    memset(env, 0, offsetof(CPULM32State, breakpoints));
+    cpu_reset(ENV_GET_CPU(env));
 }
 
commit 8d7d505adda444220c93ee5ad09df4176b366bd7
Author: Andreas Färber <afaerber at suse.de>
Date:   Wed Apr 11 01:33:33 2012 +0200

    target-lm32: QOM'ify CPU init
    
    Move code from cpu_lm32_init() to an initfn; call cpu_reset()
    instead of cpu_state_reset().
    
    Signed-off-by: Andreas Färber <afaerber at suse.de>
    Acked-by: Michael Walle <michael at walle.cc>

diff --git a/target-lm32/cpu.c b/target-lm32/cpu.c
index 4ce7e3b..70251d0 100644
--- a/target-lm32/cpu.c
+++ b/target-lm32/cpu.c
@@ -34,6 +34,18 @@ static void lm32_cpu_reset(CPUState *s)
     cpu_state_reset(env);
 }
 
+static void lm32_cpu_initfn(Object *obj)
+{
+    LM32CPU *cpu = LM32_CPU(obj);
+    CPULM32State *env = &cpu->env;
+
+    cpu_exec_init(env);
+
+    env->flags = 0;
+
+    cpu_reset(CPU(cpu));
+}
+
 static void lm32_cpu_class_init(ObjectClass *oc, void *data)
 {
     LM32CPUClass *lcc = LM32_CPU_CLASS(oc);
@@ -47,6 +59,7 @@ static const TypeInfo lm32_cpu_type_info = {
     .name = TYPE_LM32_CPU,
     .parent = TYPE_CPU,
     .instance_size = sizeof(LM32CPU),
+    .instance_init = lm32_cpu_initfn,
     .abstract = false,
     .class_size = sizeof(LM32CPUClass),
     .class_init = lm32_cpu_class_init,
diff --git a/target-lm32/helper.c b/target-lm32/helper.c
index 3cf86d7..9de777f 100644
--- a/target-lm32/helper.c
+++ b/target-lm32/helper.c
@@ -211,10 +211,7 @@ CPULM32State *cpu_lm32_init(const char *cpu_model)
     env->num_bps = def->num_breakpoints;
     env->num_wps = def->num_watchpoints;
     env->cfg = cfg_by_def(def);
-    env->flags = 0;
 
-    cpu_exec_init(env);
-    cpu_state_reset(env);
     qemu_init_vcpu(env);
 
     if (tcg_enabled() && !tcg_initialized) {
commit fc0ced2fbd8d40672fcdd2f655bbdcd3e278f3ab
Author: Andreas Färber <afaerber at suse.de>
Date:   Wed Apr 11 01:22:08 2012 +0200

    target-lm32: QOM'ify CPU
    
    Embed CPULM32State as first member of QOM LM32CPU.
    Let CPUClass::reset() call cpu_state_reset() for now.
    
    Signed-off-by: Andreas Färber <afaerber at suse.de>
    Acked-by: Michael Walle <michael at walle.cc>

diff --git a/Makefile.target b/Makefile.target
index 1110796..e88b896 100644
--- a/Makefile.target
+++ b/Makefile.target
@@ -93,6 +93,7 @@ libobj-$(TARGET_SPARC64) += vis_helper.o
 libobj-$(CONFIG_NEED_MMU) += mmu.o
 libobj-$(TARGET_ARM) += neon_helper.o iwmmxt_helper.o
 libobj-$(TARGET_ARM) += cpu.o
+libobj-$(TARGET_LM32) += cpu.o
 libobj-$(TARGET_S390X) += cpu.o
 ifeq ($(TARGET_BASE_ARCH), sparc)
 libobj-y += fop_helper.o cc_helper.o win_helper.o mmu_helper.o ldst_helper.o
diff --git a/target-lm32/cpu-qom.h b/target-lm32/cpu-qom.h
new file mode 100644
index 0000000..4ae2edd
--- /dev/null
+++ b/target-lm32/cpu-qom.h
@@ -0,0 +1,71 @@
+/*
+ * QEMU LatticeMico32 CPU
+ *
+ * Copyright (c) 2012 SUSE LINUX Products GmbH
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, see
+ * <http://www.gnu.org/licenses/lgpl-2.1.html>
+ */
+#ifndef QEMU_LM32_CPU_QOM_H
+#define QEMU_LM32_CPU_QOM_H
+
+#include "qemu/cpu.h"
+#include "cpu.h"
+
+#define TYPE_LM32_CPU "lm32-cpu"
+
+#define LM32_CPU_CLASS(klass) \
+    OBJECT_CLASS_CHECK(LM32CPUClass, (klass), TYPE_LM32_CPU)
+#define LM32_CPU(obj) \
+    OBJECT_CHECK(LM32CPU, (obj), TYPE_LM32_CPU)
+#define LM32_CPU_GET_CLASS(obj) \
+    OBJECT_GET_CLASS(LM32CPUClass, (obj), TYPE_LM32_CPU)
+
+/**
+ * LM32CPUClass:
+ * @parent_reset: The parent class' reset handler.
+ *
+ * A LatticeMico32 CPU model.
+ */
+typedef struct LM32CPUClass {
+    /*< private >*/
+    CPUClass parent_class;
+    /*< public >*/
+
+    void (*parent_reset)(CPUState *cpu);
+} LM32CPUClass;
+
+/**
+ * LM32CPU:
+ * @env: #CPULM32State
+ *
+ * A LatticeMico32 CPU.
+ */
+typedef struct LM32CPU {
+    /*< private >*/
+    CPUState parent_obj;
+    /*< public >*/
+
+    CPULM32State env;
+} LM32CPU;
+
+static inline LM32CPU *lm32_env_get_cpu(CPULM32State *env)
+{
+    return LM32_CPU(container_of(env, LM32CPU, env));
+}
+
+#define ENV_GET_CPU(e) CPU(lm32_env_get_cpu(e))
+
+
+#endif
diff --git a/target-lm32/cpu.c b/target-lm32/cpu.c
new file mode 100644
index 0000000..4ce7e3b
--- /dev/null
+++ b/target-lm32/cpu.c
@@ -0,0 +1,60 @@
+/*
+ * QEMU LatticeMico32 CPU
+ *
+ * Copyright (c) 2012 SUSE LINUX Products GmbH
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, see
+ * <http://www.gnu.org/licenses/lgpl-2.1.html>
+ */
+
+#include "cpu-qom.h"
+#include "qemu-common.h"
+
+
+/* CPUClass::reset() */
+static void lm32_cpu_reset(CPUState *s)
+{
+    LM32CPU *cpu = LM32_CPU(s);
+    LM32CPUClass *lcc = LM32_CPU_GET_CLASS(cpu);
+    CPULM32State *env = &cpu->env;
+
+    lcc->parent_reset(s);
+
+    cpu_state_reset(env);
+}
+
+static void lm32_cpu_class_init(ObjectClass *oc, void *data)
+{
+    LM32CPUClass *lcc = LM32_CPU_CLASS(oc);
+    CPUClass *cc = CPU_CLASS(oc);
+
+    lcc->parent_reset = cc->reset;
+    cc->reset = lm32_cpu_reset;
+}
+
+static const TypeInfo lm32_cpu_type_info = {
+    .name = TYPE_LM32_CPU,
+    .parent = TYPE_CPU,
+    .instance_size = sizeof(LM32CPU),
+    .abstract = false,
+    .class_size = sizeof(LM32CPUClass),
+    .class_init = lm32_cpu_class_init,
+};
+
+static void lm32_cpu_register_types(void)
+{
+    type_register_static(&lm32_cpu_type_info);
+}
+
+type_init(lm32_cpu_register_types)
diff --git a/target-lm32/cpu.h b/target-lm32/cpu.h
index a7d9546..422a55b 100644
--- a/target-lm32/cpu.h
+++ b/target-lm32/cpu.h
@@ -184,6 +184,7 @@ struct CPULM32State {
 
 };
 
+#include "cpu-qom.h"
 
 CPULM32State *cpu_lm32_init(const char *cpu_model);
 void cpu_lm32_list(FILE *f, fprintf_function cpu_fprintf);
diff --git a/target-lm32/helper.c b/target-lm32/helper.c
index 78076e4..3cf86d7 100644
--- a/target-lm32/helper.c
+++ b/target-lm32/helper.c
@@ -194,6 +194,7 @@ static uint32_t cfg_by_def(const LM32Def *def)
 
 CPULM32State *cpu_lm32_init(const char *cpu_model)
 {
+    LM32CPU *cpu;
     CPULM32State *env;
     const LM32Def *def;
     static int tcg_initialized;
@@ -203,7 +204,8 @@ CPULM32State *cpu_lm32_init(const char *cpu_model)
         return NULL;
     }
 
-    env = g_malloc0(sizeof(CPULM32State));
+    cpu = LM32_CPU(object_new(TYPE_LM32_CPU));
+    env = &cpu->env;
 
     env->features = def->features;
     env->num_bps = def->num_breakpoints;
commit 3e48dd4a2d48aabafe22ce3611d65544d0234a69
Author: Stefan Hajnoczi <stefanha at linux.vnet.ibm.com>
Date:   Wed Apr 11 12:01:44 2012 +0100

    rtl8139: do not assume TxStatus[] and TxAddr[] are adjacent
    
    Commit afe0a595356192d5f79703cf6462fcc112df007c ("rtl8139: support byte
    read to TxStatus registers") reused rtl8139_TxStatus_read() for reading
    TxAddr registers.  It relies on the fact that TxStatus[] and TxAddr[]
    are adjacent.
    
    This causes a gcc warning because the compiler can detect that array
    access is out-of-bounds:
    
      hw/rtl8139.c:2501:27: error: array subscript is above array bounds [-Werror=array-bounds]
    
    This patch refactors the function so that we don't rely on out-of-bounds
    accesses.
    
    Cc: Jason Wang <jasonwang at redhat.com>
    Signed-off-by: Stefan Hajnoczi <stefanha at linux.vnet.ibm.com>
    Signed-off-by: Anthony Liguori <aliguori at us.ibm.com>

diff --git a/hw/rtl8139.c b/hw/rtl8139.c
index 4d553a8..4d0f5ba 100644
--- a/hw/rtl8139.c
+++ b/hw/rtl8139.c
@@ -2482,15 +2482,17 @@ static void rtl8139_TxStatus_write(RTL8139State *s, uint32_t txRegOffset, uint32
     rtl8139_transmit(s);
 }
 
-static uint32_t rtl8139_TxStatus_read(RTL8139State *s, uint8_t addr, int size)
+static uint32_t rtl8139_TxStatus_TxAddr_read(RTL8139State *s, uint32_t regs[],
+                                             uint32_t base, uint8_t addr,
+                                             int size)
 {
-    uint32_t reg = (addr - TxStatus0) / 4;
+    uint32_t reg = (addr - base) / 4;
     uint32_t offset = addr & 0x3;
     uint32_t ret = 0;
 
     if (addr & (size - 1)) {
-        DPRINTF("not implemented read for TxStatus addr=0x%x size=0x%x\n", addr,
-                size);
+        DPRINTF("not implemented read for TxStatus/TxAddr "
+                "addr=0x%x size=0x%x\n", addr, size);
         return ret;
     }
 
@@ -2498,12 +2500,12 @@ static uint32_t rtl8139_TxStatus_read(RTL8139State *s, uint8_t addr, int size)
     case 1: /* fall through */
     case 2: /* fall through */
     case 4:
-        ret = (s->TxStatus[reg] >> offset * 8) & ((1 << (size * 8)) - 1);
-        DPRINTF("TxStatus[%d] read addr=0x%x size=0x%x val=0x%08x\n", reg, addr,
-                size, ret);
+        ret = (regs[reg] >> offset * 8) & ((1 << (size * 8)) - 1);
+        DPRINTF("TxStatus/TxAddr[%d] read addr=0x%x size=0x%x val=0x%08x\n",
+                reg, addr, size, ret);
         break;
     default:
-        DPRINTF("unsupported size 0x%x of TxStatus reading\n", size);
+        DPRINTF("unsupported size 0x%x of TxStatus/TxAddr reading\n", size);
         break;
     }
 
@@ -2977,7 +2979,8 @@ static uint32_t rtl8139_io_readb(void *opaque, uint8_t addr)
             ret = s->mult[addr - MAR0];
             break;
         case TxStatus0 ... TxStatus0+4*4-1:
-            ret = rtl8139_TxStatus_read(s, addr, 1);
+            ret = rtl8139_TxStatus_TxAddr_read(s, s->TxStatus, TxStatus0,
+                                               addr, 1);
             break;
         case ChipCmd:
             ret = rtl8139_ChipCmd_read(s);
@@ -3043,7 +3046,7 @@ static uint32_t rtl8139_io_readw(void *opaque, uint8_t addr)
     switch (addr)
     {
         case TxAddr0 ... TxAddr0+4*4-1:
-            ret = rtl8139_TxStatus_read(s, addr, 2);
+            ret = rtl8139_TxStatus_TxAddr_read(s, s->TxAddr, TxAddr0, addr, 2);
             break;
         case IntrMask:
             ret = rtl8139_IntrMask_read(s);
@@ -3135,7 +3138,8 @@ static uint32_t rtl8139_io_readl(void *opaque, uint8_t addr)
             break;
 
         case TxStatus0 ... TxStatus0+4*4-1:
-            ret = rtl8139_TxStatus_read(s, addr, 4);
+            ret = rtl8139_TxStatus_TxAddr_read(s, s->TxStatus, TxStatus0,
+                                               addr, 4);
             break;
 
         case TxAddr0 ... TxAddr0+4*4-1:
commit 2ba1d381c2f5f5868fe071b45977c2ed459d78f0
Author: David Gibson <david at gibson.dropbear.id.au>
Date:   Tue Apr 3 17:24:11 2012 +0300

    virtio-pci: change virtio balloon PCI class code
    
    Currently the virtio balloon device, when using the virtio-pci interface
    advertises itself with PCI class code MEMORY_RAM.  This is wrong; the
    balloon is vaguely related to memory, but is nothing like a PCI memory
    device in the meaning of the class code, and this code is not required
    or suggested by the virtio PCI specification.
    
    Worse, this patch causes problems on the pseries machine, because the
    firmware, seeing this class code, advertises the device as memory in the
    device tree, and then a guest kernel bug causes it to see this "memory"
    before the real system memory, leading to a crash in early boot.
    
    This patch fixes the problem by removing the bogus PCI class code on the
    balloon device.  The backwards compatibility PC machines get new compat
    properties so that they don't change.
    
    Cc: Rusty Russell <rusty at rustcorp.com.au>
    Signed-off-by: David Gibson <david at gibson.dropbear.id.au>
    Signed-off-by: Michael S. Tsirkin <mst at redhat.com>

diff --git a/hw/pc_piix.c b/hw/pc_piix.c
index 0f61f00..5c08245 100644
--- a/hw/pc_piix.c
+++ b/hw/pc_piix.c
@@ -28,6 +28,7 @@
 #include "pc.h"
 #include "apic.h"
 #include "pci.h"
+#include "pci_ids.h"
 #include "net.h"
 #include "boards.h"
 #include "ide.h"
@@ -368,6 +369,10 @@ static QEMUMachine pc_machine_v1_1 = {
             .driver   = "isa-fdc",\
             .property = "check_media_rate",\
             .value    = "off",\
+        }, {\
+            .driver   = "virtio-balloon-pci",\
+            .property = "class",\
+            .value    = stringify(PCI_CLASS_MEMORY_RAM),\
         }
 
 static QEMUMachine pc_machine_v1_0 = {
diff --git a/hw/virtio-pci.c b/hw/virtio-pci.c
index a0fb7c1..4a4413d 100644
--- a/hw/virtio-pci.c
+++ b/hw/virtio-pci.c
@@ -790,6 +790,11 @@ static int virtio_balloon_init_pci(PCIDevice *pci_dev)
     VirtIOPCIProxy *proxy = DO_UPCAST(VirtIOPCIProxy, pci_dev, pci_dev);
     VirtIODevice *vdev;
 
+    if (proxy->class_code != PCI_CLASS_OTHERS &&
+        proxy->class_code != PCI_CLASS_MEMORY_RAM) { /* qemu < 1.1 */
+        proxy->class_code = PCI_CLASS_OTHERS;
+    }
+
     vdev = virtio_balloon_init(&pci_dev->qdev);
     if (!vdev) {
         return -1;
@@ -906,6 +911,7 @@ static TypeInfo virtio_serial_info = {
 
 static Property virtio_balloon_properties[] = {
     DEFINE_VIRTIO_COMMON_FEATURES(VirtIOPCIProxy, host_features),
+    DEFINE_PROP_HEX32("class", VirtIOPCIProxy, class_code, 0),
     DEFINE_PROP_END_OF_LIST(),
 };
 
@@ -919,7 +925,7 @@ static void virtio_balloon_class_init(ObjectClass *klass, void *data)
     k->vendor_id = PCI_VENDOR_ID_REDHAT_QUMRANET;
     k->device_id = PCI_DEVICE_ID_VIRTIO_BALLOON;
     k->revision = VIRTIO_PCI_ABI_VERSION;
-    k->class_id = PCI_CLASS_MEMORY_RAM;
+    k->class_id = PCI_CLASS_OTHERS;
     dc->reset = virtio_pci_reset;
     dc->props = virtio_balloon_properties;
 }
commit 4490c71191b59dce2dd88f5f9ab49f2c92ab410c
Author: Michael S. Tsirkin <mst at redhat.com>
Date:   Mon Dec 5 21:48:43 2011 +0200

    ivshmem: add missing msix calls
    
    ivshmem used msix but didn't call it on either reset or
    config write paths. This used to partically work since
    guests don't use all of msi-x configuration fields,
    and reset is rarely used, but the patch 'msix: track function masked
    in pci device state' broke that. Fix by adding appropriate calls.
    
    Signed-off-by: Michael S. Tsirkin <mst at redhat.com>
    Reported-by: Cam Macdonell <cam at cs.ualberta.ca>
    Tested-by: Cam Macdonell <cam at cs.ualberta.ca>

diff --git a/hw/ivshmem.c b/hw/ivshmem.c
index b80aa8f..c2bdd92 100644
--- a/hw/ivshmem.c
+++ b/hw/ivshmem.c
@@ -509,11 +509,29 @@ static void ivshmem_read(void *opaque, const uint8_t * buf, int flags)
     return;
 }
 
+/* Select the MSI-X vectors used by device.
+ * ivshmem maps events to vectors statically, so
+ * we just enable all vectors on init and after reset. */
+static void ivshmem_use_msix(IVShmemState * s)
+{
+    int i;
+
+    if (!msix_present(&s->dev)) {
+        return;
+    }
+
+    for (i = 0; i < s->vectors; i++) {
+        msix_vector_use(&s->dev, i);
+    }
+}
+
 static void ivshmem_reset(DeviceState *d)
 {
     IVShmemState *s = DO_UPCAST(IVShmemState, dev.qdev, d);
 
     s->intrstatus = 0;
+    msix_reset(&s->dev);
+    ivshmem_use_msix(s);
     return;
 }
 
@@ -544,12 +562,8 @@ static uint64_t ivshmem_get_size(IVShmemState * s) {
     return value;
 }
 
-static void ivshmem_setup_msi(IVShmemState * s) {
-
-    int i;
-
-    /* allocate the MSI-X vectors */
-
+static void ivshmem_setup_msi(IVShmemState * s)
+{
     memory_region_init(&s->msix_bar, "ivshmem-msix", 4096);
     if (!msix_init(&s->dev, s->vectors, &s->msix_bar, 1, 0)) {
         pci_register_bar(&s->dev, 1, PCI_BASE_ADDRESS_SPACE_MEMORY,
@@ -560,13 +574,10 @@ static void ivshmem_setup_msi(IVShmemState * s) {
         exit(1);
     }
 
-    /* 'activate' the vectors */
-    for (i = 0; i < s->vectors; i++) {
-        msix_vector_use(&s->dev, i);
-    }
-
     /* allocate QEMU char devices for receiving interrupts */
     s->eventfd_table = g_malloc0(s->vectors * sizeof(EventfdEntry));
+
+    ivshmem_use_msix(s);
 }
 
 static void ivshmem_save(QEMUFile* f, void *opaque)
@@ -590,7 +601,7 @@ static int ivshmem_load(QEMUFile* f, void *opaque, int version_id)
     IVSHMEM_DPRINTF("ivshmem_load\n");
 
     IVShmemState *proxy = opaque;
-    int ret, i;
+    int ret;
 
     if (version_id > 0) {
         return -EINVAL;
@@ -608,9 +619,7 @@ static int ivshmem_load(QEMUFile* f, void *opaque, int version_id)
 
     if (ivshmem_has_feature(proxy, IVSHMEM_MSI)) {
         msix_load(&proxy->dev, f);
-        for (i = 0; i < proxy->vectors; i++) {
-            msix_vector_use(&proxy->dev, i);
-        }
+	ivshmem_use_msix(proxy);
     } else {
         proxy->intrstatus = qemu_get_be32(f);
         proxy->intrmask = qemu_get_be32(f);
@@ -619,6 +628,13 @@ static int ivshmem_load(QEMUFile* f, void *opaque, int version_id)
     return 0;
 }
 
+static void ivshmem_write_config(PCIDevice *pci_dev, uint32_t address,
+				 uint32_t val, int len)
+{
+    pci_default_write_config(pci_dev, address, val, len);
+    msix_write_config(pci_dev, address, val, len);
+}
+
 static int pci_ivshmem_init(PCIDevice *dev)
 {
     IVShmemState *s = DO_UPCAST(IVShmemState, dev, dev);
@@ -744,6 +760,8 @@ static int pci_ivshmem_init(PCIDevice *dev)
 
     }
 
+    s->dev.config_write = ivshmem_write_config;
+
     return 0;
 }
 
commit fbbaf9ae88286f18b2ab32fb4174ebdbdc1d5919
Author: Michael S. Tsirkin <mst at redhat.com>
Date:   Sun Apr 1 11:39:43 2012 +0300

    vhost: readd assert statement
    
    It's clear from the surrounding code that
    start < end so it's enough to assert end < log_size.
    However, it's better to make this explicit in case
    we refactor the code again.
    
    Signed-off-by: Michael S. Tsirkin <mst at redhat.com>

diff --git a/hw/vhost.c b/hw/vhost.c
index 7e282dd..43664e7 100644
--- a/hw/vhost.c
+++ b/hw/vhost.c
@@ -35,6 +35,7 @@ static void vhost_dev_sync_region(struct vhost_dev *dev,
         return;
     }
     assert(end / VHOST_LOG_CHUNK < dev->log_size);
+    assert(start / VHOST_LOG_CHUNK < dev->log_size);
 
     for (;from < to; ++from) {
         vhost_log_chunk_t log;
commit e314672a8a95f5dc98534f0682fce50fb83dbc5c
Author: Alex Williamson <alex.williamson at redhat.com>
Date:   Fri Aug 13 09:54:52 2010 -0400

    vhost: Fix size of dirty log sync on resize
    
    When the vhost log is resized, we want to sync up to
    the size of the old log.  With that end address in place,
    ignore regions that start after then end rather than
    hitting assert.
    
    This also addresses the following crash report:
    When migrating a vm using vhost-net we hit the following assertion:
    
    qemu-kvm: /usr/src/packages/BUILD/qemu-kvm-0.15.1/hw/vhost.c:30:
    vhost_dev_sync_region: Assertion `start / (0x1000 * (8 *
    sizeof(vhost_log_chunk_t))) < dev->log_size' failed.
    
    The cases which the end < start check is intended to catch, such as
    for vga video memory, will also likely trigger the assertion.
    Reorder the code to handle this correctly.
    
    Reported-by: Josh Durgin <josh.durgin at dreamhost.com>
    Signed-off-by: Bruce Rogers <brogers at suse.com>
    Signed-off-by: Alex Williamson <alex.williamson at redhat.com>
    Signed-off-by: Michael S. Tsirkin <mst at redhat.com>

diff --git a/hw/vhost.c b/hw/vhost.c
index 8d3ba5b..7e282dd 100644
--- a/hw/vhost.c
+++ b/hw/vhost.c
@@ -31,11 +31,11 @@ static void vhost_dev_sync_region(struct vhost_dev *dev,
     vhost_log_chunk_t *to = dev->log + end / VHOST_LOG_CHUNK + 1;
     uint64_t addr = (start / VHOST_LOG_CHUNK) * VHOST_LOG_CHUNK;
 
-    assert(end / VHOST_LOG_CHUNK < dev->log_size);
-    assert(start / VHOST_LOG_CHUNK < dev->log_size);
     if (end < start) {
         return;
     }
+    assert(end / VHOST_LOG_CHUNK < dev->log_size);
+
     for (;from < to; ++from) {
         vhost_log_chunk_t log;
         int bit;
@@ -277,8 +277,9 @@ static inline void vhost_dev_log_resize(struct vhost_dev* dev, uint64_t size)
     r = ioctl(dev->control, VHOST_SET_LOG_BASE, &log_base);
     assert(r >= 0);
     for (i = 0; i < dev->n_mem_sections; ++i) {
-        vhost_sync_dirty_bitmap(dev, &dev->mem_sections[i],
-                                0, (target_phys_addr_t)~0x0ull);
+        /* Sync only the range covered by the old log */
+        vhost_sync_dirty_bitmap(dev, &dev->mem_sections[i], 0,
+                                dev->log_size * VHOST_LOG_CHUNK - 1);
     }
     if (dev->log) {
         g_free(dev->log);
commit d6c730086cbf24382eb8cff25551798769edfd84
Author: Michael S. Tsirkin <mst at redhat.com>
Date:   Mon Mar 26 11:26:16 2012 +0200

    pc: reduce duplication in compat machine types
    
    Make it easier to add compat properties, by
    adding macros for properties duplicated across
    machine types.
    
    Note: there could be bugs in compat properties,
    this patch does not attempt to address them,
    the code is bug for bug identical to the original.
    
    Tested by: generated a preprocessed file, sorted and
    compared to sorted original.
    Lightly tested on x86_64.
    
    Signed-off-by: Michael S. Tsirkin <mst at redhat.com>

diff --git a/hw/pc_piix.c b/hw/pc_piix.c
index fadca4c..0f61f00 100644
--- a/hw/pc_piix.c
+++ b/hw/pc_piix.c
@@ -359,50 +359,69 @@ static QEMUMachine pc_machine_v1_1 = {
     .is_default = 1,
 };
 
+#define PC_COMPAT_1_0 \
+        {\
+            .driver   = "pc-sysfw",\
+            .property = "rom_only",\
+            .value    = stringify(1),\
+        }, {\
+            .driver   = "isa-fdc",\
+            .property = "check_media_rate",\
+            .value    = "off",\
+        }
+
 static QEMUMachine pc_machine_v1_0 = {
     .name = "pc-1.0",
     .desc = "Standard PC",
     .init = pc_init_pci,
     .max_cpus = 255,
     .compat_props = (GlobalProperty[]) {
-        {
-            .driver   = "pc-sysfw",
-            .property = "rom_only",
-            .value    = stringify(1),
-        }, {
-            .driver   = "isa-fdc",
-            .property = "check_media_rate",
-            .value    = "off",
-        },
+        PC_COMPAT_1_0,
         { /* end of list */ }
     },
 };
 
+#define PC_COMPAT_0_15 \
+        PC_COMPAT_1_0
+
 static QEMUMachine pc_machine_v0_15 = {
     .name = "pc-0.15",
     .desc = "Standard PC",
     .init = pc_init_pci,
     .max_cpus = 255,
     .compat_props = (GlobalProperty[]) {
-        {
-            .driver   = "pc-sysfw",
-            .property = "rom_only",
-            .value    = stringify(1),
-        }, {
-            .driver   = "isa-fdc",
-            .property = "check_media_rate",
-            .value    = "off",
-        },
+        PC_COMPAT_0_15,
         { /* end of list */ }
     },
 };
 
+#define PC_COMPAT_0_14 \
+        PC_COMPAT_0_15,\
+        {\
+            .driver   = "virtio-blk-pci",\
+            .property = "event_idx",\
+            .value    = "off",\
+        },{\
+            .driver   = "virtio-serial-pci",\
+            .property = "event_idx",\
+            .value    = "off",\
+        },{\
+            .driver   = "virtio-net-pci",\
+            .property = "event_idx",\
+            .value    = "off",\
+        },{\
+            .driver   = "virtio-balloon-pci",\
+            .property = "event_idx",\
+            .value    = "off",\
+        }
+
 static QEMUMachine pc_machine_v0_14 = {
     .name = "pc-0.14",
     .desc = "Standard PC",
     .init = pc_init_pci,
     .max_cpus = 255,
     .compat_props = (GlobalProperty[]) {
+        PC_COMPAT_0_14, 
         {
             .driver   = "qxl",
             .property = "revision",
@@ -411,42 +430,30 @@ static QEMUMachine pc_machine_v0_14 = {
             .driver   = "qxl-vga",
             .property = "revision",
             .value    = stringify(2),
-        },{
-            .driver   = "virtio-blk-pci",
-            .property = "event_idx",
-            .value    = "off",
-        },{
-            .driver   = "virtio-serial-pci",
-            .property = "event_idx",
-            .value    = "off",
-        },{
-            .driver   = "virtio-net-pci",
-            .property = "event_idx",
-            .value    = "off",
-        },{
-            .driver   = "virtio-balloon-pci",
-            .property = "event_idx",
-            .value    = "off",
-        },{
-            .driver   = "isa-fdc",
-            .property = "check_media_rate",
-            .value    = "off",
-        },
-        {
-            .driver   = "pc-sysfw",
-            .property = "rom_only",
-            .value    = stringify(1),
         },
         { /* end of list */ }
     },
 };
 
+#define PC_COMPAT_0_13 \
+        PC_COMPAT_0_14,\
+        {\
+            .driver   = "PCI",\
+            .property = "command_serr_enable",\
+            .value    = "off",\
+        },{\
+            .driver   = "AC97",\
+            .property = "use_broken_id",\
+            .value    = stringify(1),\
+        }
+
 static QEMUMachine pc_machine_v0_13 = {
     .name = "pc-0.13",
     .desc = "Standard PC",
     .init = pc_init_pci_no_kvmclock,
     .max_cpus = 255,
     .compat_props = (GlobalProperty[]) {
+        PC_COMPAT_0_13,
         {
             .driver   = "virtio-9p-pci",
             .property = "vectors",
@@ -459,59 +466,31 @@ static QEMUMachine pc_machine_v0_13 = {
             .driver   = "vmware-svga",
             .property = "rombar",
             .value    = stringify(0),
-        },{
-            .driver   = "PCI",
-            .property = "command_serr_enable",
-            .value    = "off",
-        },{
-            .driver   = "virtio-blk-pci",
-            .property = "event_idx",
-            .value    = "off",
-        },{
-            .driver   = "virtio-serial-pci",
-            .property = "event_idx",
-            .value    = "off",
-        },{
-            .driver   = "virtio-net-pci",
-            .property = "event_idx",
-            .value    = "off",
-        },{
-            .driver   = "virtio-balloon-pci",
-            .property = "event_idx",
-            .value    = "off",
-        },{
-            .driver   = "AC97",
-            .property = "use_broken_id",
-            .value    = stringify(1),
-        },{
-            .driver   = "isa-fdc",
-            .property = "check_media_rate",
-            .value    = "off",
-        },
-        {
-            .driver   = "pc-sysfw",
-            .property = "rom_only",
-            .value    = stringify(1),
         },
         { /* end of list */ }
     },
 };
 
+#define PC_COMPAT_0_12 \
+        PC_COMPAT_0_13,\
+        {\
+            .driver   = "virtio-serial-pci",\
+            .property = "max_ports",\
+            .value    = stringify(1),\
+        },{\
+            .driver   = "virtio-serial-pci",\
+            .property = "vectors",\
+            .value    = stringify(0),\
+        }
+
 static QEMUMachine pc_machine_v0_12 = {
     .name = "pc-0.12",
     .desc = "Standard PC",
     .init = pc_init_pci_no_kvmclock,
     .max_cpus = 255,
     .compat_props = (GlobalProperty[]) {
+        PC_COMPAT_0_12,
         {
-            .driver   = "virtio-serial-pci",
-            .property = "max_ports",
-            .value    = stringify(1),
-        },{
-            .driver   = "virtio-serial-pci",
-            .property = "vectors",
-            .value    = stringify(0),
-        },{
             .driver   = "VGA",
             .property = "rombar",
             .value    = stringify(0),
@@ -519,63 +498,27 @@ static QEMUMachine pc_machine_v0_12 = {
             .driver   = "vmware-svga",
             .property = "rombar",
             .value    = stringify(0),
-        },{
-            .driver   = "PCI",
-            .property = "command_serr_enable",
-            .value    = "off",
-        },{
-            .driver   = "virtio-blk-pci",
-            .property = "event_idx",
-            .value    = "off",
-        },{
-            .driver   = "virtio-serial-pci",
-            .property = "event_idx",
-            .value    = "off",
-        },{
-            .driver   = "virtio-net-pci",
-            .property = "event_idx",
-            .value    = "off",
-        },{
-            .driver   = "virtio-balloon-pci",
-            .property = "event_idx",
-            .value    = "off",
-        },{
-            .driver   = "AC97",
-            .property = "use_broken_id",
-            .value    = stringify(1),
-        },{
-            .driver   = "isa-fdc",
-            .property = "check_media_rate",
-            .value    = "off",
-        },
-        {
-            .driver   = "pc-sysfw",
-            .property = "rom_only",
-            .value    = stringify(1),
         },
         { /* end of list */ }
     }
 };
 
+#define PC_COMPAT_0_11 \
+        PC_COMPAT_0_12,\
+        {\
+            .driver   = "virtio-blk-pci",\
+            .property = "vectors",\
+            .value    = stringify(0),\
+        }
+
 static QEMUMachine pc_machine_v0_11 = {
     .name = "pc-0.11",
     .desc = "Standard PC, qemu 0.11",
     .init = pc_init_pci_no_kvmclock,
     .max_cpus = 255,
     .compat_props = (GlobalProperty[]) {
+        PC_COMPAT_0_11,
         {
-            .driver   = "virtio-blk-pci",
-            .property = "vectors",
-            .value    = stringify(0),
-        },{
-            .driver   = "virtio-serial-pci",
-            .property = "max_ports",
-            .value    = stringify(1),
-        },{
-            .driver   = "virtio-serial-pci",
-            .property = "vectors",
-            .value    = stringify(0),
-        },{
             .driver   = "ide-drive",
             .property = "ver",
             .value    = "0.11",
@@ -583,43 +526,6 @@ static QEMUMachine pc_machine_v0_11 = {
             .driver   = "scsi-disk",
             .property = "ver",
             .value    = "0.11",
-        },{
-            .driver   = "PCI",
-            .property = "rombar",
-            .value    = stringify(0),
-        },{
-            .driver   = "PCI",
-            .property = "command_serr_enable",
-            .value    = "off",
-        },{
-            .driver   = "virtio-blk-pci",
-            .property = "event_idx",
-            .value    = "off",
-        },{
-            .driver   = "virtio-serial-pci",
-            .property = "event_idx",
-            .value    = "off",
-        },{
-            .driver   = "virtio-net-pci",
-            .property = "event_idx",
-            .value    = "off",
-        },{
-            .driver   = "virtio-balloon-pci",
-            .property = "event_idx",
-            .value    = "off",
-        },{
-            .driver   = "AC97",
-            .property = "use_broken_id",
-            .value    = stringify(1),
-        },{
-            .driver   = "isa-fdc",
-            .property = "check_media_rate",
-            .value    = "off",
-        },
-        {
-            .driver   = "pc-sysfw",
-            .property = "rom_only",
-            .value    = stringify(1),
         },
         { /* end of list */ }
     }
@@ -631,6 +537,7 @@ static QEMUMachine pc_machine_v0_10 = {
     .init = pc_init_pci_no_kvmclock,
     .max_cpus = 255,
     .compat_props = (GlobalProperty[]) {
+        PC_COMPAT_0_11,
         {
             .driver   = "virtio-blk-pci",
             .property = "class",
@@ -640,22 +547,10 @@ static QEMUMachine pc_machine_v0_10 = {
             .property = "class",
             .value    = stringify(PCI_CLASS_DISPLAY_OTHER),
         },{
-            .driver   = "virtio-serial-pci",
-            .property = "max_ports",
-            .value    = stringify(1),
-        },{
-            .driver   = "virtio-serial-pci",
-            .property = "vectors",
-            .value    = stringify(0),
-        },{
             .driver   = "virtio-net-pci",
             .property = "vectors",
             .value    = stringify(0),
         },{
-            .driver   = "virtio-blk-pci",
-            .property = "vectors",
-            .value    = stringify(0),
-        },{
             .driver   = "ide-drive",
             .property = "ver",
             .value    = "0.10",
@@ -663,43 +558,6 @@ static QEMUMachine pc_machine_v0_10 = {
             .driver   = "scsi-disk",
             .property = "ver",
             .value    = "0.10",
-        },{
-            .driver   = "PCI",
-            .property = "rombar",
-            .value    = stringify(0),
-        },{
-            .driver   = "PCI",
-            .property = "command_serr_enable",
-            .value    = "off",
-        },{
-            .driver   = "virtio-blk-pci",
-            .property = "event_idx",
-            .value    = "off",
-        },{
-            .driver   = "virtio-serial-pci",
-            .property = "event_idx",
-            .value    = "off",
-        },{
-            .driver   = "virtio-net-pci",
-            .property = "event_idx",
-            .value    = "off",
-        },{
-            .driver   = "virtio-balloon-pci",
-            .property = "event_idx",
-            .value    = "off",
-        },{
-            .driver   = "AC97",
-            .property = "use_broken_id",
-            .value    = stringify(1),
-        },{
-            .driver   = "isa-fdc",
-            .property = "check_media_rate",
-            .value    = "off",
-        },
-        {
-            .driver   = "pc-sysfw",
-            .property = "rom_only",
-            .value    = stringify(1),
         },
         { /* end of list */ }
     },
commit d50c6c8b0fc28c2dd91f3f7ab2a0bbb56419214b
Author: Alexey Korolev <alexey.korolev at endace.com>
Date:   Wed Feb 29 14:35:14 2012 +1300

    piix_pci: fix typo in i400FX chipset init code
    
    There is a typo in i440FX init code. This is causing problems when
    somebody wants to access the 64bit PCI range.
    
    Signed-off-by: Alexey Korolev <alexey.korolev at endace.com>
    Signed-off-by: Michael S. Tsirkin <mst at redhat.com>

diff --git a/hw/piix_pci.c b/hw/piix_pci.c
index 179d9a6..09e84f5 100644
--- a/hw/piix_pci.c
+++ b/hw/piix_pci.c
@@ -349,7 +349,7 @@ PCIBus *i440fx_init(PCII440FXState **pi440fx_state, int *piix3_devfn,
     b = i440fx_common_init("i440FX", pi440fx_state, piix3_devfn, isa_bus, pic,
                            address_space_mem, address_space_io, ram_size,
                            pci_hole_start, pci_hole_size,
-                           pci_hole64_size, pci_hole64_size,
+                           pci_hole64_start, pci_hole64_size,
                            pci_memory, ram_memory);
     return b;
 }
commit c1958aea51a14199d05d392edce932a956e1674d
Author: Andreas Färber <afaerber at suse.de>
Date:   Tue Apr 3 00:16:24 2012 +0200

    target-i386: QOM'ify CPU reset
    
    Move code from cpu_state_reset() into QOM x86_cpu_reset(),
    fixing style issues for FPU init.
    
    Signed-off-by: Andreas Färber <afaerber at suse.de>

diff --git a/target-i386/cpu.c b/target-i386/cpu.c
index f4463e1..3df53ca 100644
--- a/target-i386/cpu.c
+++ b/target-i386/cpu.c
@@ -1374,10 +1374,80 @@ static void x86_cpu_reset(CPUState *s)
     X86CPU *cpu = X86_CPU(s);
     X86CPUClass *xcc = X86_CPU_GET_CLASS(cpu);
     CPUX86State *env = &cpu->env;
+    int i;
+
+    if (qemu_loglevel_mask(CPU_LOG_RESET)) {
+        qemu_log("CPU Reset (CPU %d)\n", env->cpu_index);
+        log_cpu_state(env, X86_DUMP_FPU | X86_DUMP_CCOP);
+    }
 
     xcc->parent_reset(s);
 
-    cpu_state_reset(env);
+
+    memset(env, 0, offsetof(CPUX86State, breakpoints));
+
+    tlb_flush(env, 1);
+
+    env->old_exception = -1;
+
+    /* init to reset state */
+
+#ifdef CONFIG_SOFTMMU
+    env->hflags |= HF_SOFTMMU_MASK;
+#endif
+    env->hflags2 |= HF2_GIF_MASK;
+
+    cpu_x86_update_cr0(env, 0x60000010);
+    env->a20_mask = ~0x0;
+    env->smbase = 0x30000;
+
+    env->idt.limit = 0xffff;
+    env->gdt.limit = 0xffff;
+    env->ldt.limit = 0xffff;
+    env->ldt.flags = DESC_P_MASK | (2 << DESC_TYPE_SHIFT);
+    env->tr.limit = 0xffff;
+    env->tr.flags = DESC_P_MASK | (11 << DESC_TYPE_SHIFT);
+
+    cpu_x86_load_seg_cache(env, R_CS, 0xf000, 0xffff0000, 0xffff,
+                           DESC_P_MASK | DESC_S_MASK | DESC_CS_MASK |
+                           DESC_R_MASK | DESC_A_MASK);
+    cpu_x86_load_seg_cache(env, R_DS, 0, 0, 0xffff,
+                           DESC_P_MASK | DESC_S_MASK | DESC_W_MASK |
+                           DESC_A_MASK);
+    cpu_x86_load_seg_cache(env, R_ES, 0, 0, 0xffff,
+                           DESC_P_MASK | DESC_S_MASK | DESC_W_MASK |
+                           DESC_A_MASK);
+    cpu_x86_load_seg_cache(env, R_SS, 0, 0, 0xffff,
+                           DESC_P_MASK | DESC_S_MASK | DESC_W_MASK |
+                           DESC_A_MASK);
+    cpu_x86_load_seg_cache(env, R_FS, 0, 0, 0xffff,
+                           DESC_P_MASK | DESC_S_MASK | DESC_W_MASK |
+                           DESC_A_MASK);
+    cpu_x86_load_seg_cache(env, R_GS, 0, 0, 0xffff,
+                           DESC_P_MASK | DESC_S_MASK | DESC_W_MASK |
+                           DESC_A_MASK);
+
+    env->eip = 0xfff0;
+    env->regs[R_EDX] = env->cpuid_version;
+
+    env->eflags = 0x2;
+
+    /* FPU init */
+    for (i = 0; i < 8; i++) {
+        env->fptags[i] = 1;
+    }
+    env->fpuc = 0x37f;
+
+    env->mxcsr = 0x1f80;
+
+    env->pat = 0x0007040600070406ULL;
+    env->msr_ia32_misc_enable = MSR_IA32_MISC_ENABLE_DEFAULT;
+
+    memset(env->dr, 0, sizeof(env->dr));
+    env->dr[6] = DR6_FIXED_1;
+    env->dr[7] = DR7_FIXED_1;
+    cpu_breakpoint_remove_all(env, BP_CPU);
+    cpu_watchpoint_remove_all(env, BP_CPU);
 }
 
 static void mce_init(X86CPU *cpu)
diff --git a/target-i386/helper.c b/target-i386/helper.c
index d8ceee1..87954f0 100644
--- a/target-i386/helper.c
+++ b/target-i386/helper.c
@@ -29,76 +29,7 @@
 /* NOTE: must be called outside the CPU execute loop */
 void cpu_state_reset(CPUX86State *env)
 {
-    int i;
-
-    if (qemu_loglevel_mask(CPU_LOG_RESET)) {
-        qemu_log("CPU Reset (CPU %d)\n", env->cpu_index);
-        log_cpu_state(env, X86_DUMP_FPU | X86_DUMP_CCOP);
-    }
-
-    memset(env, 0, offsetof(CPUX86State, breakpoints));
-
-    tlb_flush(env, 1);
-
-    env->old_exception = -1;
-
-    /* init to reset state */
-
-#ifdef CONFIG_SOFTMMU
-    env->hflags |= HF_SOFTMMU_MASK;
-#endif
-    env->hflags2 |= HF2_GIF_MASK;
-
-    cpu_x86_update_cr0(env, 0x60000010);
-    env->a20_mask = ~0x0;
-    env->smbase = 0x30000;
-
-    env->idt.limit = 0xffff;
-    env->gdt.limit = 0xffff;
-    env->ldt.limit = 0xffff;
-    env->ldt.flags = DESC_P_MASK | (2 << DESC_TYPE_SHIFT);
-    env->tr.limit = 0xffff;
-    env->tr.flags = DESC_P_MASK | (11 << DESC_TYPE_SHIFT);
-
-    cpu_x86_load_seg_cache(env, R_CS, 0xf000, 0xffff0000, 0xffff,
-                           DESC_P_MASK | DESC_S_MASK | DESC_CS_MASK |
-                           DESC_R_MASK | DESC_A_MASK);
-    cpu_x86_load_seg_cache(env, R_DS, 0, 0, 0xffff,
-                           DESC_P_MASK | DESC_S_MASK | DESC_W_MASK |
-                           DESC_A_MASK);
-    cpu_x86_load_seg_cache(env, R_ES, 0, 0, 0xffff,
-                           DESC_P_MASK | DESC_S_MASK | DESC_W_MASK |
-                           DESC_A_MASK);
-    cpu_x86_load_seg_cache(env, R_SS, 0, 0, 0xffff,
-                           DESC_P_MASK | DESC_S_MASK | DESC_W_MASK |
-                           DESC_A_MASK);
-    cpu_x86_load_seg_cache(env, R_FS, 0, 0, 0xffff,
-                           DESC_P_MASK | DESC_S_MASK | DESC_W_MASK |
-                           DESC_A_MASK);
-    cpu_x86_load_seg_cache(env, R_GS, 0, 0, 0xffff,
-                           DESC_P_MASK | DESC_S_MASK | DESC_W_MASK |
-                           DESC_A_MASK);
-
-    env->eip = 0xfff0;
-    env->regs[R_EDX] = env->cpuid_version;
-
-    env->eflags = 0x2;
-
-    /* FPU init */
-    for(i = 0;i < 8; i++)
-        env->fptags[i] = 1;
-    env->fpuc = 0x37f;
-
-    env->mxcsr = 0x1f80;
-
-    env->pat = 0x0007040600070406ULL;
-    env->msr_ia32_misc_enable = MSR_IA32_MISC_ENABLE_DEFAULT;
-
-    memset(env->dr, 0, sizeof(env->dr));
-    env->dr[6] = DR6_FIXED_1;
-    env->dr[7] = DR7_FIXED_1;
-    cpu_breakpoint_remove_all(env, BP_CPU);
-    cpu_watchpoint_remove_all(env, BP_CPU);
+    cpu_reset(ENV_GET_CPU(env));
 }
 
 static void cpu_x86_version(CPUX86State *env, int *family, int *model)
commit de024815e3b523addf58f1f79846b7fe74643678
Author: Andreas Färber <afaerber at suse.de>
Date:   Tue Apr 3 00:00:17 2012 +0200

    target-i386: QOM'ify CPU init
    
    Move code from cpu_x86_init() to new QOM x86_cpu_initfn().
    Also move mce_init() to cpu.c since it's used nowhere else.
    
    Signed-off-by: Andreas Färber <afaerber at suse.de>

diff --git a/target-i386/cpu.c b/target-i386/cpu.c
index 36790da..f4463e1 100644
--- a/target-i386/cpu.c
+++ b/target-i386/cpu.c
@@ -1380,6 +1380,32 @@ static void x86_cpu_reset(CPUState *s)
     cpu_state_reset(env);
 }
 
+static void mce_init(X86CPU *cpu)
+{
+    CPUX86State *cenv = &cpu->env;
+    unsigned int bank;
+
+    if (((cenv->cpuid_version >> 8) & 0xf) >= 6
+        && (cenv->cpuid_features & (CPUID_MCE | CPUID_MCA)) ==
+            (CPUID_MCE | CPUID_MCA)) {
+        cenv->mcg_cap = MCE_CAP_DEF | MCE_BANKS_DEF;
+        cenv->mcg_ctl = ~(uint64_t)0;
+        for (bank = 0; bank < MCE_BANKS_DEF; bank++) {
+            cenv->mce_banks[bank * 4] = ~(uint64_t)0;
+        }
+    }
+}
+
+static void x86_cpu_initfn(Object *obj)
+{
+    X86CPU *cpu = X86_CPU(obj);
+    CPUX86State *env = &cpu->env;
+
+    cpu_exec_init(env);
+    env->cpuid_apic_id = env->cpu_index;
+    mce_init(cpu);
+}
+
 static void x86_cpu_common_class_init(ObjectClass *oc, void *data)
 {
     X86CPUClass *xcc = X86_CPU_CLASS(oc);
@@ -1393,6 +1419,7 @@ static const TypeInfo x86_cpu_type_info = {
     .name = TYPE_X86_CPU,
     .parent = TYPE_CPU,
     .instance_size = sizeof(X86CPU),
+    .instance_init = x86_cpu_initfn,
     .abstract = false,
     .class_size = sizeof(X86CPUClass),
     .class_init = x86_cpu_common_class_init,
diff --git a/target-i386/helper.c b/target-i386/helper.c
index fb87975..d8ceee1 100644
--- a/target-i386/helper.c
+++ b/target-i386/helper.c
@@ -1197,21 +1197,6 @@ void cpu_report_tpr_access(CPUX86State *env, TPRAccess access)
 }
 #endif /* !CONFIG_USER_ONLY */
 
-static void mce_init(CPUX86State *cenv)
-{
-    unsigned int bank;
-
-    if (((cenv->cpuid_version >> 8) & 0xf) >= 6
-        && (cenv->cpuid_features & (CPUID_MCE | CPUID_MCA)) ==
-            (CPUID_MCE | CPUID_MCA)) {
-        cenv->mcg_cap = MCE_CAP_DEF | MCE_BANKS_DEF;
-        cenv->mcg_ctl = ~(uint64_t)0;
-        for (bank = 0; bank < MCE_BANKS_DEF; bank++) {
-            cenv->mce_banks[bank * 4] = ~(uint64_t)0;
-        }
-    }
-}
-
 int cpu_x86_get_descr_debug(CPUX86State *env, unsigned int selector,
                             target_ulong *base, unsigned int *limit,
                             unsigned int *flags)
@@ -1249,7 +1234,6 @@ CPUX86State *cpu_x86_init(const char *cpu_model)
 
     cpu = X86_CPU(object_new(TYPE_X86_CPU));
     env = &cpu->env;
-    cpu_exec_init(env);
     env->cpu_model_str = cpu_model;
 
     /* init various static tables used in TCG mode */
@@ -1265,8 +1249,6 @@ CPUX86State *cpu_x86_init(const char *cpu_model)
         object_delete(OBJECT(cpu));
         return NULL;
     }
-    env->cpuid_apic_id = env->cpu_index;
-    mce_init(env);
 
     qemu_init_vcpu(env);
 
commit 5fd2087a1b7b3075828de741d76188441ee35bc8
Author: Andreas Färber <afaerber at suse.de>
Date:   Mon Apr 2 23:20:08 2012 +0200

    target-i386: QOM'ify CPU
    
    Embed CPUX86State as first member of X86CPU.
    Distinguish between "x86_64-cpu" and "i386-cpu".
    Drop cpu_x86_close() in favor of calling object_delete() directly.
    
    For now let CPUClass::reset() call cpu_state_reset().
    
    Signed-off-by: Andreas Färber <afaerber at suse.de>

diff --git a/target-i386/cpu-qom.h b/target-i386/cpu-qom.h
new file mode 100644
index 0000000..40635c4
--- /dev/null
+++ b/target-i386/cpu-qom.h
@@ -0,0 +1,75 @@
+/*
+ * QEMU x86 CPU
+ *
+ * Copyright (c) 2012 SUSE LINUX Products GmbH
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, see
+ * <http://www.gnu.org/licenses/lgpl-2.1.html>
+ */
+#ifndef QEMU_I386_CPU_QOM_H
+#define QEMU_I386_CPU_QOM_H
+
+#include "qemu/cpu.h"
+#include "cpu.h"
+
+#ifdef TARGET_X86_64
+#define TYPE_X86_CPU "x86_64-cpu"
+#else
+#define TYPE_X86_CPU "i386-cpu"
+#endif
+
+#define X86_CPU_CLASS(klass) \
+    OBJECT_CLASS_CHECK(X86CPUClass, (klass), TYPE_X86_CPU)
+#define X86_CPU(obj) \
+    OBJECT_CHECK(X86CPU, (obj), TYPE_X86_CPU)
+#define X86_CPU_GET_CLASS(obj) \
+    OBJECT_GET_CLASS(X86CPUClass, (obj), TYPE_X86_CPU)
+
+/**
+ * X86CPUClass:
+ * @parent_reset: The parent class' reset handler.
+ *
+ * An x86 CPU model or family.
+ */
+typedef struct X86CPUClass {
+    /*< private >*/
+    CPUClass parent_class;
+    /*< public >*/
+
+    void (*parent_reset)(CPUState *cpu);
+} X86CPUClass;
+
+/**
+ * X86CPU:
+ * @env: #CPUX86State
+ *
+ * An x86 CPU.
+ */
+typedef struct X86CPU {
+    /*< private >*/
+    CPUState parent_obj;
+    /*< public >*/
+
+    CPUX86State env;
+} X86CPU;
+
+static inline X86CPU *x86_env_get_cpu(CPUX86State *env)
+{
+    return X86_CPU(container_of(env, X86CPU, env));
+}
+
+#define ENV_GET_CPU(e) CPU(x86_env_get_cpu(e))
+
+
+#endif
diff --git a/target-i386/cpu.c b/target-i386/cpu.c
index 465ea15..36790da 100644
--- a/target-i386/cpu.c
+++ b/target-i386/cpu.c
@@ -1367,3 +1367,40 @@ void cpu_x86_cpuid(CPUX86State *env, uint32_t index, uint32_t count,
         break;
     }
 }
+
+/* CPUClass::reset() */
+static void x86_cpu_reset(CPUState *s)
+{
+    X86CPU *cpu = X86_CPU(s);
+    X86CPUClass *xcc = X86_CPU_GET_CLASS(cpu);
+    CPUX86State *env = &cpu->env;
+
+    xcc->parent_reset(s);
+
+    cpu_state_reset(env);
+}
+
+static void x86_cpu_common_class_init(ObjectClass *oc, void *data)
+{
+    X86CPUClass *xcc = X86_CPU_CLASS(oc);
+    CPUClass *cc = CPU_CLASS(oc);
+
+    xcc->parent_reset = cc->reset;
+    cc->reset = x86_cpu_reset;
+}
+
+static const TypeInfo x86_cpu_type_info = {
+    .name = TYPE_X86_CPU,
+    .parent = TYPE_CPU,
+    .instance_size = sizeof(X86CPU),
+    .abstract = false,
+    .class_size = sizeof(X86CPUClass),
+    .class_init = x86_cpu_common_class_init,
+};
+
+static void x86_cpu_register_types(void)
+{
+    type_register_static(&x86_cpu_type_info);
+}
+
+type_init(x86_cpu_register_types)
diff --git a/target-i386/cpu.h b/target-i386/cpu.h
index a1ed3e7..4bb4592 100644
--- a/target-i386/cpu.h
+++ b/target-i386/cpu.h
@@ -783,9 +783,10 @@ typedef struct CPUX86State {
     TPRAccess tpr_access_type;
 } CPUX86State;
 
+#include "cpu-qom.h"
+
 CPUX86State *cpu_x86_init(const char *cpu_model);
 int cpu_x86_exec(CPUX86State *s);
-void cpu_x86_close(CPUX86State *s);
 void x86_cpu_list (FILE *f, fprintf_function cpu_fprintf, const char *optarg);
 void x86_cpudef_setup(void);
 int cpu_x86_support_mca_broadcast(CPUX86State *env);
diff --git a/target-i386/helper.c b/target-i386/helper.c
index 83122bf..fb87975 100644
--- a/target-i386/helper.c
+++ b/target-i386/helper.c
@@ -101,11 +101,6 @@ void cpu_state_reset(CPUX86State *env)
     cpu_watchpoint_remove_all(env, BP_CPU);
 }
 
-void cpu_x86_close(CPUX86State *env)
-{
-    g_free(env);
-}
-
 static void cpu_x86_version(CPUX86State *env, int *family, int *model)
 {
     int cpuver = env->cpuid_version;
@@ -1248,10 +1243,12 @@ int cpu_x86_get_descr_debug(CPUX86State *env, unsigned int selector,
 
 CPUX86State *cpu_x86_init(const char *cpu_model)
 {
+    X86CPU *cpu;
     CPUX86State *env;
     static int inited;
 
-    env = g_malloc0(sizeof(CPUX86State));
+    cpu = X86_CPU(object_new(TYPE_X86_CPU));
+    env = &cpu->env;
     cpu_exec_init(env);
     env->cpu_model_str = cpu_model;
 
@@ -1265,7 +1262,7 @@ CPUX86State *cpu_x86_init(const char *cpu_model)
 #endif
     }
     if (cpu_x86_register(env, cpu_model) < 0) {
-        cpu_x86_close(env);
+        object_delete(OBJECT(cpu));
         return NULL;
     }
     env->cpuid_apic_id = env->cpu_index;
commit 30471bc94e1eb4ce1c87a56b6210a3baa1698d58
Author: Andreas Färber <afaerber at suse.de>
Date:   Mon Apr 2 22:22:12 2012 +0200

    target-i386: Rename cpuid.c
    
    Name it cpu.c to align with other QOM'ified targets.
    
    Signed-off-by: Andreas Färber <afaerber at suse.de>

diff --git a/Makefile.target b/Makefile.target
index 14c8fa1..1110796 100644
--- a/Makefile.target
+++ b/Makefile.target
@@ -87,7 +87,7 @@ endif
 endif
 libobj-y += helper.o
 ifeq ($(TARGET_BASE_ARCH), i386)
-libobj-y += cpuid.o
+libobj-y += cpu.o
 endif
 libobj-$(TARGET_SPARC64) += vis_helper.o
 libobj-$(CONFIG_NEED_MMU) += mmu.o
diff --git a/target-i386/cpu.c b/target-i386/cpu.c
new file mode 100644
index 0000000..465ea15
--- /dev/null
+++ b/target-i386/cpu.c
@@ -0,0 +1,1369 @@
+/*
+ *  i386 CPUID helper functions
+ *
+ *  Copyright (c) 2003 Fabrice Bellard
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, see <http://www.gnu.org/licenses/>.
+ */
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+#include <inttypes.h>
+
+#include "cpu.h"
+#include "kvm.h"
+
+#include "qemu-option.h"
+#include "qemu-config.h"
+
+#include "hyperv.h"
+
+/* feature flags taken from "Intel Processor Identification and the CPUID
+ * Instruction" and AMD's "CPUID Specification".  In cases of disagreement
+ * between feature naming conventions, aliases may be added.
+ */
+static const char *feature_name[] = {
+    "fpu", "vme", "de", "pse",
+    "tsc", "msr", "pae", "mce",
+    "cx8", "apic", NULL, "sep",
+    "mtrr", "pge", "mca", "cmov",
+    "pat", "pse36", "pn" /* Intel psn */, "clflush" /* Intel clfsh */,
+    NULL, "ds" /* Intel dts */, "acpi", "mmx",
+    "fxsr", "sse", "sse2", "ss",
+    "ht" /* Intel htt */, "tm", "ia64", "pbe",
+};
+static const char *ext_feature_name[] = {
+    "pni|sse3" /* Intel,AMD sse3 */, "pclmulqdq|pclmuldq", "dtes64", "monitor",
+    "ds_cpl", "vmx", "smx", "est",
+    "tm2", "ssse3", "cid", NULL,
+    "fma", "cx16", "xtpr", "pdcm",
+    NULL, NULL, "dca", "sse4.1|sse4_1",
+    "sse4.2|sse4_2", "x2apic", "movbe", "popcnt",
+    "tsc-deadline", "aes", "xsave", "osxsave",
+    "avx", NULL, NULL, "hypervisor",
+};
+static const char *ext2_feature_name[] = {
+    "fpu", "vme", "de", "pse",
+    "tsc", "msr", "pae", "mce",
+    "cx8" /* AMD CMPXCHG8B */, "apic", NULL, "syscall",
+    "mtrr", "pge", "mca", "cmov",
+    "pat", "pse36", NULL, NULL /* Linux mp */,
+    "nx|xd", NULL, "mmxext", "mmx",
+    "fxsr", "fxsr_opt|ffxsr", "pdpe1gb" /* AMD Page1GB */, "rdtscp",
+    NULL, "lm|i64", "3dnowext", "3dnow",
+};
+static const char *ext3_feature_name[] = {
+    "lahf_lm" /* AMD LahfSahf */, "cmp_legacy", "svm", "extapic" /* AMD ExtApicSpace */,
+    "cr8legacy" /* AMD AltMovCr8 */, "abm", "sse4a", "misalignsse",
+    "3dnowprefetch", "osvw", "ibs", "xop",
+    "skinit", "wdt", NULL, NULL,
+    "fma4", NULL, "cvt16", "nodeid_msr",
+    NULL, NULL, NULL, NULL,
+    NULL, NULL, NULL, NULL,
+    NULL, NULL, NULL, NULL,
+};
+
+static const char *kvm_feature_name[] = {
+    "kvmclock", "kvm_nopiodelay", "kvm_mmu", "kvmclock", "kvm_asyncpf", NULL, NULL, NULL,
+    NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+    NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+    NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+};
+
+static const char *svm_feature_name[] = {
+    "npt", "lbrv", "svm_lock", "nrip_save",
+    "tsc_scale", "vmcb_clean",  "flushbyasid", "decodeassists",
+    NULL, NULL, "pause_filter", NULL,
+    "pfthreshold", NULL, NULL, NULL,
+    NULL, NULL, NULL, NULL,
+    NULL, NULL, NULL, NULL,
+    NULL, NULL, NULL, NULL,
+    NULL, NULL, NULL, NULL,
+};
+
+/* collects per-function cpuid data
+ */
+typedef struct model_features_t {
+    uint32_t *guest_feat;
+    uint32_t *host_feat;
+    uint32_t check_feat;
+    const char **flag_names;
+    uint32_t cpuid;
+    } model_features_t;
+
+int check_cpuid = 0;
+int enforce_cpuid = 0;
+
+void host_cpuid(uint32_t function, uint32_t count,
+                uint32_t *eax, uint32_t *ebx, uint32_t *ecx, uint32_t *edx)
+{
+#if defined(CONFIG_KVM)
+    uint32_t vec[4];
+
+#ifdef __x86_64__
+    asm volatile("cpuid"
+                 : "=a"(vec[0]), "=b"(vec[1]),
+                   "=c"(vec[2]), "=d"(vec[3])
+                 : "0"(function), "c"(count) : "cc");
+#else
+    asm volatile("pusha \n\t"
+                 "cpuid \n\t"
+                 "mov %%eax, 0(%2) \n\t"
+                 "mov %%ebx, 4(%2) \n\t"
+                 "mov %%ecx, 8(%2) \n\t"
+                 "mov %%edx, 12(%2) \n\t"
+                 "popa"
+                 : : "a"(function), "c"(count), "S"(vec)
+                 : "memory", "cc");
+#endif
+
+    if (eax)
+        *eax = vec[0];
+    if (ebx)
+        *ebx = vec[1];
+    if (ecx)
+        *ecx = vec[2];
+    if (edx)
+        *edx = vec[3];
+#endif
+}
+
+#define iswhite(c) ((c) && ((c) <= ' ' || '~' < (c)))
+
+/* general substring compare of *[s1..e1) and *[s2..e2).  sx is start of
+ * a substring.  ex if !NULL points to the first char after a substring,
+ * otherwise the string is assumed to sized by a terminating nul.
+ * Return lexical ordering of *s1:*s2.
+ */
+static int sstrcmp(const char *s1, const char *e1, const char *s2,
+    const char *e2)
+{
+    for (;;) {
+        if (!*s1 || !*s2 || *s1 != *s2)
+            return (*s1 - *s2);
+        ++s1, ++s2;
+        if (s1 == e1 && s2 == e2)
+            return (0);
+        else if (s1 == e1)
+            return (*s2);
+        else if (s2 == e2)
+            return (*s1);
+    }
+}
+
+/* compare *[s..e) to *altstr.  *altstr may be a simple string or multiple
+ * '|' delimited (possibly empty) strings in which case search for a match
+ * within the alternatives proceeds left to right.  Return 0 for success,
+ * non-zero otherwise.
+ */
+static int altcmp(const char *s, const char *e, const char *altstr)
+{
+    const char *p, *q;
+
+    for (q = p = altstr; ; ) {
+        while (*p && *p != '|')
+            ++p;
+        if ((q == p && !*s) || (q != p && !sstrcmp(s, e, q, p)))
+            return (0);
+        if (!*p)
+            return (1);
+        else
+            q = ++p;
+    }
+}
+
+/* search featureset for flag *[s..e), if found set corresponding bit in
+ * *pval and return true, otherwise return false
+ */
+static bool lookup_feature(uint32_t *pval, const char *s, const char *e,
+                           const char **featureset)
+{
+    uint32_t mask;
+    const char **ppc;
+    bool found = false;
+
+    for (mask = 1, ppc = featureset; mask; mask <<= 1, ++ppc) {
+        if (*ppc && !altcmp(s, e, *ppc)) {
+            *pval |= mask;
+            found = true;
+        }
+    }
+    return found;
+}
+
+static void add_flagname_to_bitmaps(const char *flagname, uint32_t *features,
+                                    uint32_t *ext_features,
+                                    uint32_t *ext2_features,
+                                    uint32_t *ext3_features,
+                                    uint32_t *kvm_features,
+                                    uint32_t *svm_features)
+{
+    if (!lookup_feature(features, flagname, NULL, feature_name) &&
+        !lookup_feature(ext_features, flagname, NULL, ext_feature_name) &&
+        !lookup_feature(ext2_features, flagname, NULL, ext2_feature_name) &&
+        !lookup_feature(ext3_features, flagname, NULL, ext3_feature_name) &&
+        !lookup_feature(kvm_features, flagname, NULL, kvm_feature_name) &&
+        !lookup_feature(svm_features, flagname, NULL, svm_feature_name))
+            fprintf(stderr, "CPU feature %s not found\n", flagname);
+}
+
+typedef struct x86_def_t {
+    struct x86_def_t *next;
+    const char *name;
+    uint32_t level;
+    uint32_t vendor1, vendor2, vendor3;
+    int family;
+    int model;
+    int stepping;
+    int tsc_khz;
+    uint32_t features, ext_features, ext2_features, ext3_features;
+    uint32_t kvm_features, svm_features;
+    uint32_t xlevel;
+    char model_id[48];
+    int vendor_override;
+    uint32_t flags;
+    /* Store the results of Centaur's CPUID instructions */
+    uint32_t ext4_features;
+    uint32_t xlevel2;
+} x86_def_t;
+
+#define I486_FEATURES (CPUID_FP87 | CPUID_VME | CPUID_PSE)
+#define PENTIUM_FEATURES (I486_FEATURES | CPUID_DE | CPUID_TSC | \
+          CPUID_MSR | CPUID_MCE | CPUID_CX8 | CPUID_MMX | CPUID_APIC)
+#define PENTIUM2_FEATURES (PENTIUM_FEATURES | CPUID_PAE | CPUID_SEP | \
+          CPUID_MTRR | CPUID_PGE | CPUID_MCA | CPUID_CMOV | CPUID_PAT | \
+          CPUID_PSE36 | CPUID_FXSR)
+#define PENTIUM3_FEATURES (PENTIUM2_FEATURES | CPUID_SSE)
+#define PPRO_FEATURES (CPUID_FP87 | CPUID_DE | CPUID_PSE | CPUID_TSC | \
+          CPUID_MSR | CPUID_MCE | CPUID_CX8 | CPUID_PGE | CPUID_CMOV | \
+          CPUID_PAT | CPUID_FXSR | CPUID_MMX | CPUID_SSE | CPUID_SSE2 | \
+          CPUID_PAE | CPUID_SEP | CPUID_APIC)
+#define EXT2_FEATURE_MASK 0x0183F3FF
+
+#define TCG_FEATURES (CPUID_FP87 | CPUID_PSE | CPUID_TSC | CPUID_MSR | \
+          CPUID_PAE | CPUID_MCE | CPUID_CX8 | CPUID_APIC | CPUID_SEP | \
+          CPUID_MTRR | CPUID_PGE | CPUID_MCA | CPUID_CMOV | CPUID_PAT | \
+          CPUID_PSE36 | CPUID_CLFLUSH | CPUID_ACPI | CPUID_MMX | \
+          CPUID_FXSR | CPUID_SSE | CPUID_SSE2 | CPUID_SS)
+          /* partly implemented:
+          CPUID_MTRR, CPUID_MCA, CPUID_CLFLUSH (needed for Win64)
+          CPUID_PSE36 (needed for Solaris) */
+          /* missing:
+          CPUID_VME, CPUID_DTS, CPUID_SS, CPUID_HT, CPUID_TM, CPUID_PBE */
+#define TCG_EXT_FEATURES (CPUID_EXT_SSE3 | CPUID_EXT_MONITOR | \
+          CPUID_EXT_CX16 | CPUID_EXT_POPCNT | \
+          CPUID_EXT_HYPERVISOR)
+          /* missing:
+          CPUID_EXT_DTES64, CPUID_EXT_DSCPL, CPUID_EXT_VMX, CPUID_EXT_EST,
+          CPUID_EXT_TM2, CPUID_EXT_XTPR, CPUID_EXT_PDCM, CPUID_EXT_XSAVE */
+#define TCG_EXT2_FEATURES ((TCG_FEATURES & EXT2_FEATURE_MASK) | \
+          CPUID_EXT2_NX | CPUID_EXT2_MMXEXT | CPUID_EXT2_RDTSCP | \
+          CPUID_EXT2_3DNOW | CPUID_EXT2_3DNOWEXT)
+          /* missing:
+          CPUID_EXT2_PDPE1GB */
+#define TCG_EXT3_FEATURES (CPUID_EXT3_LAHF_LM | CPUID_EXT3_SVM | \
+          CPUID_EXT3_CR8LEG | CPUID_EXT3_ABM | CPUID_EXT3_SSE4A)
+#define TCG_SVM_FEATURES 0
+
+/* maintains list of cpu model definitions
+ */
+static x86_def_t *x86_defs = {NULL};
+
+/* built-in cpu model definitions (deprecated)
+ */
+static x86_def_t builtin_x86_defs[] = {
+    {
+        .name = "qemu64",
+        .level = 4,
+        .vendor1 = CPUID_VENDOR_AMD_1,
+        .vendor2 = CPUID_VENDOR_AMD_2,
+        .vendor3 = CPUID_VENDOR_AMD_3,
+        .family = 6,
+        .model = 2,
+        .stepping = 3,
+        .features = PPRO_FEATURES |
+            CPUID_MTRR | CPUID_CLFLUSH | CPUID_MCA |
+            CPUID_PSE36,
+        .ext_features = CPUID_EXT_SSE3 | CPUID_EXT_CX16 | CPUID_EXT_POPCNT,
+        .ext2_features = (PPRO_FEATURES & EXT2_FEATURE_MASK) |
+            CPUID_EXT2_LM | CPUID_EXT2_SYSCALL | CPUID_EXT2_NX,
+        .ext3_features = CPUID_EXT3_LAHF_LM | CPUID_EXT3_SVM |
+            CPUID_EXT3_ABM | CPUID_EXT3_SSE4A,
+        .xlevel = 0x8000000A,
+        .model_id = "QEMU Virtual CPU version " QEMU_VERSION,
+    },
+    {
+        .name = "phenom",
+        .level = 5,
+        .vendor1 = CPUID_VENDOR_AMD_1,
+        .vendor2 = CPUID_VENDOR_AMD_2,
+        .vendor3 = CPUID_VENDOR_AMD_3,
+        .family = 16,
+        .model = 2,
+        .stepping = 3,
+        .features = PPRO_FEATURES |
+            CPUID_MTRR | CPUID_CLFLUSH | CPUID_MCA |
+            CPUID_PSE36 | CPUID_VME | CPUID_HT,
+        .ext_features = CPUID_EXT_SSE3 | CPUID_EXT_MONITOR | CPUID_EXT_CX16 |
+            CPUID_EXT_POPCNT,
+        .ext2_features = (PPRO_FEATURES & EXT2_FEATURE_MASK) |
+            CPUID_EXT2_LM | CPUID_EXT2_SYSCALL | CPUID_EXT2_NX |
+            CPUID_EXT2_3DNOW | CPUID_EXT2_3DNOWEXT | CPUID_EXT2_MMXEXT |
+            CPUID_EXT2_FFXSR | CPUID_EXT2_PDPE1GB | CPUID_EXT2_RDTSCP,
+        /* Missing: CPUID_EXT3_CMP_LEG, CPUID_EXT3_EXTAPIC,
+                    CPUID_EXT3_CR8LEG,
+                    CPUID_EXT3_MISALIGNSSE, CPUID_EXT3_3DNOWPREFETCH,
+                    CPUID_EXT3_OSVW, CPUID_EXT3_IBS */
+        .ext3_features = CPUID_EXT3_LAHF_LM | CPUID_EXT3_SVM |
+            CPUID_EXT3_ABM | CPUID_EXT3_SSE4A,
+        .svm_features = CPUID_SVM_NPT | CPUID_SVM_LBRV,
+        .xlevel = 0x8000001A,
+        .model_id = "AMD Phenom(tm) 9550 Quad-Core Processor"
+    },
+    {
+        .name = "core2duo",
+        .level = 10,
+        .family = 6,
+        .model = 15,
+        .stepping = 11,
+        .features = PPRO_FEATURES |
+            CPUID_MTRR | CPUID_CLFLUSH | CPUID_MCA |
+            CPUID_PSE36 | CPUID_VME | CPUID_DTS | CPUID_ACPI | CPUID_SS |
+            CPUID_HT | CPUID_TM | CPUID_PBE,
+        .ext_features = CPUID_EXT_SSE3 | CPUID_EXT_MONITOR | CPUID_EXT_SSSE3 |
+            CPUID_EXT_DTES64 | CPUID_EXT_DSCPL | CPUID_EXT_VMX | CPUID_EXT_EST |
+            CPUID_EXT_TM2 | CPUID_EXT_CX16 | CPUID_EXT_XTPR | CPUID_EXT_PDCM,
+        .ext2_features = CPUID_EXT2_LM | CPUID_EXT2_SYSCALL | CPUID_EXT2_NX,
+        .ext3_features = CPUID_EXT3_LAHF_LM,
+        .xlevel = 0x80000008,
+        .model_id = "Intel(R) Core(TM)2 Duo CPU     T7700  @ 2.40GHz",
+    },
+    {
+        .name = "kvm64",
+        .level = 5,
+        .vendor1 = CPUID_VENDOR_INTEL_1,
+        .vendor2 = CPUID_VENDOR_INTEL_2,
+        .vendor3 = CPUID_VENDOR_INTEL_3,
+        .family = 15,
+        .model = 6,
+        .stepping = 1,
+        /* Missing: CPUID_VME, CPUID_HT */
+        .features = PPRO_FEATURES |
+            CPUID_MTRR | CPUID_CLFLUSH | CPUID_MCA |
+            CPUID_PSE36,
+        /* Missing: CPUID_EXT_POPCNT, CPUID_EXT_MONITOR */
+        .ext_features = CPUID_EXT_SSE3 | CPUID_EXT_CX16,
+        /* Missing: CPUID_EXT2_PDPE1GB, CPUID_EXT2_RDTSCP */
+        .ext2_features = (PPRO_FEATURES & EXT2_FEATURE_MASK) |
+            CPUID_EXT2_LM | CPUID_EXT2_SYSCALL | CPUID_EXT2_NX,
+        /* Missing: CPUID_EXT3_LAHF_LM, CPUID_EXT3_CMP_LEG, CPUID_EXT3_EXTAPIC,
+                    CPUID_EXT3_CR8LEG, CPUID_EXT3_ABM, CPUID_EXT3_SSE4A,
+                    CPUID_EXT3_MISALIGNSSE, CPUID_EXT3_3DNOWPREFETCH,
+                    CPUID_EXT3_OSVW, CPUID_EXT3_IBS, CPUID_EXT3_SVM */
+        .ext3_features = 0,
+        .xlevel = 0x80000008,
+        .model_id = "Common KVM processor"
+    },
+    {
+        .name = "qemu32",
+        .level = 4,
+        .family = 6,
+        .model = 3,
+        .stepping = 3,
+        .features = PPRO_FEATURES,
+        .ext_features = CPUID_EXT_SSE3 | CPUID_EXT_POPCNT,
+        .xlevel = 0x80000004,
+        .model_id = "QEMU Virtual CPU version " QEMU_VERSION,
+    },
+    {
+        .name = "kvm32",
+        .level = 5,
+        .family = 15,
+        .model = 6,
+        .stepping = 1,
+        .features = PPRO_FEATURES |
+            CPUID_MTRR | CPUID_CLFLUSH | CPUID_MCA | CPUID_PSE36,
+        .ext_features = CPUID_EXT_SSE3,
+        .ext2_features = PPRO_FEATURES & EXT2_FEATURE_MASK,
+        .ext3_features = 0,
+        .xlevel = 0x80000008,
+        .model_id = "Common 32-bit KVM processor"
+    },
+    {
+        .name = "coreduo",
+        .level = 10,
+        .family = 6,
+        .model = 14,
+        .stepping = 8,
+        .features = PPRO_FEATURES | CPUID_VME |
+            CPUID_MTRR | CPUID_CLFLUSH | CPUID_MCA | CPUID_DTS | CPUID_ACPI |
+            CPUID_SS | CPUID_HT | CPUID_TM | CPUID_PBE,
+        .ext_features = CPUID_EXT_SSE3 | CPUID_EXT_MONITOR | CPUID_EXT_VMX |
+            CPUID_EXT_EST | CPUID_EXT_TM2 | CPUID_EXT_XTPR | CPUID_EXT_PDCM,
+        .ext2_features = CPUID_EXT2_NX,
+        .xlevel = 0x80000008,
+        .model_id = "Genuine Intel(R) CPU           T2600  @ 2.16GHz",
+    },
+    {
+        .name = "486",
+        .level = 1,
+        .family = 4,
+        .model = 0,
+        .stepping = 0,
+        .features = I486_FEATURES,
+        .xlevel = 0,
+    },
+    {
+        .name = "pentium",
+        .level = 1,
+        .family = 5,
+        .model = 4,
+        .stepping = 3,
+        .features = PENTIUM_FEATURES,
+        .xlevel = 0,
+    },
+    {
+        .name = "pentium2",
+        .level = 2,
+        .family = 6,
+        .model = 5,
+        .stepping = 2,
+        .features = PENTIUM2_FEATURES,
+        .xlevel = 0,
+    },
+    {
+        .name = "pentium3",
+        .level = 2,
+        .family = 6,
+        .model = 7,
+        .stepping = 3,
+        .features = PENTIUM3_FEATURES,
+        .xlevel = 0,
+    },
+    {
+        .name = "athlon",
+        .level = 2,
+        .vendor1 = CPUID_VENDOR_AMD_1,
+        .vendor2 = CPUID_VENDOR_AMD_2,
+        .vendor3 = CPUID_VENDOR_AMD_3,
+        .family = 6,
+        .model = 2,
+        .stepping = 3,
+        .features = PPRO_FEATURES | CPUID_PSE36 | CPUID_VME | CPUID_MTRR | CPUID_MCA,
+        .ext2_features = (PPRO_FEATURES & EXT2_FEATURE_MASK) | CPUID_EXT2_MMXEXT | CPUID_EXT2_3DNOW | CPUID_EXT2_3DNOWEXT,
+        .xlevel = 0x80000008,
+        /* XXX: put another string ? */
+        .model_id = "QEMU Virtual CPU version " QEMU_VERSION,
+    },
+    {
+        .name = "n270",
+        /* original is on level 10 */
+        .level = 5,
+        .family = 6,
+        .model = 28,
+        .stepping = 2,
+        .features = PPRO_FEATURES |
+            CPUID_MTRR | CPUID_CLFLUSH | CPUID_MCA | CPUID_VME | CPUID_DTS |
+            CPUID_ACPI | CPUID_SS | CPUID_HT | CPUID_TM | CPUID_PBE,
+            /* Some CPUs got no CPUID_SEP */
+        .ext_features = CPUID_EXT_SSE3 | CPUID_EXT_MONITOR | CPUID_EXT_SSSE3 |
+            CPUID_EXT_DSCPL | CPUID_EXT_EST | CPUID_EXT_TM2 | CPUID_EXT_XTPR,
+        .ext2_features = (PPRO_FEATURES & EXT2_FEATURE_MASK) | CPUID_EXT2_NX,
+        .ext3_features = CPUID_EXT3_LAHF_LM,
+        .xlevel = 0x8000000A,
+        .model_id = "Intel(R) Atom(TM) CPU N270   @ 1.60GHz",
+    },
+};
+
+static int cpu_x86_fill_model_id(char *str)
+{
+    uint32_t eax = 0, ebx = 0, ecx = 0, edx = 0;
+    int i;
+
+    for (i = 0; i < 3; i++) {
+        host_cpuid(0x80000002 + i, 0, &eax, &ebx, &ecx, &edx);
+        memcpy(str + i * 16 +  0, &eax, 4);
+        memcpy(str + i * 16 +  4, &ebx, 4);
+        memcpy(str + i * 16 +  8, &ecx, 4);
+        memcpy(str + i * 16 + 12, &edx, 4);
+    }
+    return 0;
+}
+
+static int cpu_x86_fill_host(x86_def_t *x86_cpu_def)
+{
+    uint32_t eax = 0, ebx = 0, ecx = 0, edx = 0;
+
+    x86_cpu_def->name = "host";
+    host_cpuid(0x0, 0, &eax, &ebx, &ecx, &edx);
+    x86_cpu_def->level = eax;
+    x86_cpu_def->vendor1 = ebx;
+    x86_cpu_def->vendor2 = edx;
+    x86_cpu_def->vendor3 = ecx;
+
+    host_cpuid(0x1, 0, &eax, &ebx, &ecx, &edx);
+    x86_cpu_def->family = ((eax >> 8) & 0x0F) + ((eax >> 20) & 0xFF);
+    x86_cpu_def->model = ((eax >> 4) & 0x0F) | ((eax & 0xF0000) >> 12);
+    x86_cpu_def->stepping = eax & 0x0F;
+    x86_cpu_def->ext_features = ecx;
+    x86_cpu_def->features = edx;
+
+    host_cpuid(0x80000000, 0, &eax, &ebx, &ecx, &edx);
+    x86_cpu_def->xlevel = eax;
+
+    host_cpuid(0x80000001, 0, &eax, &ebx, &ecx, &edx);
+    x86_cpu_def->ext2_features = edx;
+    x86_cpu_def->ext3_features = ecx;
+    cpu_x86_fill_model_id(x86_cpu_def->model_id);
+    x86_cpu_def->vendor_override = 0;
+
+    /* Call Centaur's CPUID instruction. */
+    if (x86_cpu_def->vendor1 == CPUID_VENDOR_VIA_1 &&
+        x86_cpu_def->vendor2 == CPUID_VENDOR_VIA_2 &&
+        x86_cpu_def->vendor3 == CPUID_VENDOR_VIA_3) {
+        host_cpuid(0xC0000000, 0, &eax, &ebx, &ecx, &edx);
+        if (eax >= 0xC0000001) {
+            /* Support VIA max extended level */
+            x86_cpu_def->xlevel2 = eax;
+            host_cpuid(0xC0000001, 0, &eax, &ebx, &ecx, &edx);
+            x86_cpu_def->ext4_features = edx;
+        }
+    }
+
+    /*
+     * Every SVM feature requires emulation support in KVM - so we can't just
+     * read the host features here. KVM might even support SVM features not
+     * available on the host hardware. Just set all bits and mask out the
+     * unsupported ones later.
+     */
+    x86_cpu_def->svm_features = -1;
+
+    return 0;
+}
+
+static int unavailable_host_feature(struct model_features_t *f, uint32_t mask)
+{
+    int i;
+
+    for (i = 0; i < 32; ++i)
+        if (1 << i & mask) {
+            fprintf(stderr, "warning: host cpuid %04x_%04x lacks requested"
+                " flag '%s' [0x%08x]\n",
+                f->cpuid >> 16, f->cpuid & 0xffff,
+                f->flag_names[i] ? f->flag_names[i] : "[reserved]", mask);
+            break;
+        }
+    return 0;
+}
+
+/* best effort attempt to inform user requested cpu flags aren't making
+ * their way to the guest.  Note: ft[].check_feat ideally should be
+ * specified via a guest_def field to suppress report of extraneous flags.
+ */
+static int check_features_against_host(x86_def_t *guest_def)
+{
+    x86_def_t host_def;
+    uint32_t mask;
+    int rv, i;
+    struct model_features_t ft[] = {
+        {&guest_def->features, &host_def.features,
+            ~0, feature_name, 0x00000000},
+        {&guest_def->ext_features, &host_def.ext_features,
+            ~CPUID_EXT_HYPERVISOR, ext_feature_name, 0x00000001},
+        {&guest_def->ext2_features, &host_def.ext2_features,
+            ~PPRO_FEATURES, ext2_feature_name, 0x80000000},
+        {&guest_def->ext3_features, &host_def.ext3_features,
+            ~CPUID_EXT3_SVM, ext3_feature_name, 0x80000001}};
+
+    cpu_x86_fill_host(&host_def);
+    for (rv = 0, i = 0; i < ARRAY_SIZE(ft); ++i)
+        for (mask = 1; mask; mask <<= 1)
+            if (ft[i].check_feat & mask && *ft[i].guest_feat & mask &&
+                !(*ft[i].host_feat & mask)) {
+                    unavailable_host_feature(&ft[i], mask);
+                    rv = 1;
+                }
+    return rv;
+}
+
+static void x86_cpuid_version_set_family(CPUX86State *env, int family)
+{
+    env->cpuid_version &= ~0xff00f00;
+    if (family > 0x0f) {
+        env->cpuid_version |= 0xf00 | ((family - 0x0f) << 20);
+    } else {
+        env->cpuid_version |= family << 8;
+    }
+}
+
+static void x86_cpuid_version_set_model(CPUX86State *env, int model)
+{
+    env->cpuid_version &= ~0xf00f0;
+    env->cpuid_version |= ((model & 0xf) << 4) | ((model >> 4) << 16);
+}
+
+static void x86_cpuid_version_set_stepping(CPUX86State *env, int stepping)
+{
+    env->cpuid_version &= ~0xf;
+    env->cpuid_version |= stepping & 0xf;
+}
+
+static void x86_cpuid_set_model_id(CPUX86State *env, const char *model_id)
+{
+    int c, len, i;
+
+    if (model_id == NULL) {
+        model_id = "";
+    }
+    len = strlen(model_id);
+    for (i = 0; i < 48; i++) {
+        if (i >= len) {
+            c = '\0';
+        } else {
+            c = (uint8_t)model_id[i];
+        }
+        env->cpuid_model[i >> 2] |= c << (8 * (i & 3));
+    }
+}
+
+static int cpu_x86_find_by_name(x86_def_t *x86_cpu_def, const char *cpu_model)
+{
+    unsigned int i;
+    x86_def_t *def;
+
+    char *s = g_strdup(cpu_model);
+    char *featurestr, *name = strtok(s, ",");
+    /* Features to be added*/
+    uint32_t plus_features = 0, plus_ext_features = 0;
+    uint32_t plus_ext2_features = 0, plus_ext3_features = 0;
+    uint32_t plus_kvm_features = 0, plus_svm_features = 0;
+    /* Features to be removed */
+    uint32_t minus_features = 0, minus_ext_features = 0;
+    uint32_t minus_ext2_features = 0, minus_ext3_features = 0;
+    uint32_t minus_kvm_features = 0, minus_svm_features = 0;
+    uint32_t numvalue;
+
+    for (def = x86_defs; def; def = def->next)
+        if (name && !strcmp(name, def->name))
+            break;
+    if (kvm_enabled() && name && strcmp(name, "host") == 0) {
+        cpu_x86_fill_host(x86_cpu_def);
+    } else if (!def) {
+        goto error;
+    } else {
+        memcpy(x86_cpu_def, def, sizeof(*def));
+    }
+
+    plus_kvm_features = ~0; /* not supported bits will be filtered out later */
+
+    add_flagname_to_bitmaps("hypervisor", &plus_features,
+        &plus_ext_features, &plus_ext2_features, &plus_ext3_features,
+        &plus_kvm_features, &plus_svm_features);
+
+    featurestr = strtok(NULL, ",");
+
+    while (featurestr) {
+        char *val;
+        if (featurestr[0] == '+') {
+            add_flagname_to_bitmaps(featurestr + 1, &plus_features,
+                            &plus_ext_features, &plus_ext2_features,
+                            &plus_ext3_features, &plus_kvm_features,
+                            &plus_svm_features);
+        } else if (featurestr[0] == '-') {
+            add_flagname_to_bitmaps(featurestr + 1, &minus_features,
+                            &minus_ext_features, &minus_ext2_features,
+                            &minus_ext3_features, &minus_kvm_features,
+                            &minus_svm_features);
+        } else if ((val = strchr(featurestr, '='))) {
+            *val = 0; val++;
+            if (!strcmp(featurestr, "family")) {
+                char *err;
+                numvalue = strtoul(val, &err, 0);
+                if (!*val || *err) {
+                    fprintf(stderr, "bad numerical value %s\n", val);
+                    goto error;
+                }
+                x86_cpu_def->family = numvalue;
+            } else if (!strcmp(featurestr, "model")) {
+                char *err;
+                numvalue = strtoul(val, &err, 0);
+                if (!*val || *err || numvalue > 0xff) {
+                    fprintf(stderr, "bad numerical value %s\n", val);
+                    goto error;
+                }
+                x86_cpu_def->model = numvalue;
+            } else if (!strcmp(featurestr, "stepping")) {
+                char *err;
+                numvalue = strtoul(val, &err, 0);
+                if (!*val || *err || numvalue > 0xf) {
+                    fprintf(stderr, "bad numerical value %s\n", val);
+                    goto error;
+                }
+                x86_cpu_def->stepping = numvalue ;
+            } else if (!strcmp(featurestr, "level")) {
+                char *err;
+                numvalue = strtoul(val, &err, 0);
+                if (!*val || *err) {
+                    fprintf(stderr, "bad numerical value %s\n", val);
+                    goto error;
+                }
+                x86_cpu_def->level = numvalue;
+            } else if (!strcmp(featurestr, "xlevel")) {
+                char *err;
+                numvalue = strtoul(val, &err, 0);
+                if (!*val || *err) {
+                    fprintf(stderr, "bad numerical value %s\n", val);
+                    goto error;
+                }
+                if (numvalue < 0x80000000) {
+                    numvalue += 0x80000000;
+                }
+                x86_cpu_def->xlevel = numvalue;
+            } else if (!strcmp(featurestr, "vendor")) {
+                if (strlen(val) != 12) {
+                    fprintf(stderr, "vendor string must be 12 chars long\n");
+                    goto error;
+                }
+                x86_cpu_def->vendor1 = 0;
+                x86_cpu_def->vendor2 = 0;
+                x86_cpu_def->vendor3 = 0;
+                for(i = 0; i < 4; i++) {
+                    x86_cpu_def->vendor1 |= ((uint8_t)val[i    ]) << (8 * i);
+                    x86_cpu_def->vendor2 |= ((uint8_t)val[i + 4]) << (8 * i);
+                    x86_cpu_def->vendor3 |= ((uint8_t)val[i + 8]) << (8 * i);
+                }
+                x86_cpu_def->vendor_override = 1;
+            } else if (!strcmp(featurestr, "model_id")) {
+                pstrcpy(x86_cpu_def->model_id, sizeof(x86_cpu_def->model_id),
+                        val);
+            } else if (!strcmp(featurestr, "tsc_freq")) {
+                int64_t tsc_freq;
+                char *err;
+
+                tsc_freq = strtosz_suffix_unit(val, &err,
+                                               STRTOSZ_DEFSUFFIX_B, 1000);
+                if (tsc_freq < 0 || *err) {
+                    fprintf(stderr, "bad numerical value %s\n", val);
+                    goto error;
+                }
+                x86_cpu_def->tsc_khz = tsc_freq / 1000;
+            } else if (!strcmp(featurestr, "hv_spinlocks")) {
+                char *err;
+                numvalue = strtoul(val, &err, 0);
+                if (!*val || *err) {
+                    fprintf(stderr, "bad numerical value %s\n", val);
+                    goto error;
+                }
+                hyperv_set_spinlock_retries(numvalue);
+            } else {
+                fprintf(stderr, "unrecognized feature %s\n", featurestr);
+                goto error;
+            }
+        } else if (!strcmp(featurestr, "check")) {
+            check_cpuid = 1;
+        } else if (!strcmp(featurestr, "enforce")) {
+            check_cpuid = enforce_cpuid = 1;
+        } else if (!strcmp(featurestr, "hv_relaxed")) {
+            hyperv_enable_relaxed_timing(true);
+        } else if (!strcmp(featurestr, "hv_vapic")) {
+            hyperv_enable_vapic_recommended(true);
+        } else {
+            fprintf(stderr, "feature string `%s' not in format (+feature|-feature|feature=xyz)\n", featurestr);
+            goto error;
+        }
+        featurestr = strtok(NULL, ",");
+    }
+    x86_cpu_def->features |= plus_features;
+    x86_cpu_def->ext_features |= plus_ext_features;
+    x86_cpu_def->ext2_features |= plus_ext2_features;
+    x86_cpu_def->ext3_features |= plus_ext3_features;
+    x86_cpu_def->kvm_features |= plus_kvm_features;
+    x86_cpu_def->svm_features |= plus_svm_features;
+    x86_cpu_def->features &= ~minus_features;
+    x86_cpu_def->ext_features &= ~minus_ext_features;
+    x86_cpu_def->ext2_features &= ~minus_ext2_features;
+    x86_cpu_def->ext3_features &= ~minus_ext3_features;
+    x86_cpu_def->kvm_features &= ~minus_kvm_features;
+    x86_cpu_def->svm_features &= ~minus_svm_features;
+    if (check_cpuid) {
+        if (check_features_against_host(x86_cpu_def) && enforce_cpuid)
+            goto error;
+    }
+    g_free(s);
+    return 0;
+
+error:
+    g_free(s);
+    return -1;
+}
+
+/* generate a composite string into buf of all cpuid names in featureset
+ * selected by fbits.  indicate truncation at bufsize in the event of overflow.
+ * if flags, suppress names undefined in featureset.
+ */
+static void listflags(char *buf, int bufsize, uint32_t fbits,
+    const char **featureset, uint32_t flags)
+{
+    const char **p = &featureset[31];
+    char *q, *b, bit;
+    int nc;
+
+    b = 4 <= bufsize ? buf + (bufsize -= 3) - 1 : NULL;
+    *buf = '\0';
+    for (q = buf, bit = 31; fbits && bufsize; --p, fbits &= ~(1 << bit), --bit)
+        if (fbits & 1 << bit && (*p || !flags)) {
+            if (*p)
+                nc = snprintf(q, bufsize, "%s%s", q == buf ? "" : " ", *p);
+            else
+                nc = snprintf(q, bufsize, "%s[%d]", q == buf ? "" : " ", bit);
+            if (bufsize <= nc) {
+                if (b) {
+                    memcpy(b, "...", sizeof("..."));
+                }
+                return;
+            }
+            q += nc;
+            bufsize -= nc;
+        }
+}
+
+/* generate CPU information:
+ * -?        list model names
+ * -?model   list model names/IDs
+ * -?dump    output all model (x86_def_t) data
+ * -?cpuid   list all recognized cpuid flag names
+ */
+void x86_cpu_list(FILE *f, fprintf_function cpu_fprintf, const char *optarg)
+{
+    unsigned char model = !strcmp("?model", optarg);
+    unsigned char dump = !strcmp("?dump", optarg);
+    unsigned char cpuid = !strcmp("?cpuid", optarg);
+    x86_def_t *def;
+    char buf[256];
+
+    if (cpuid) {
+        (*cpu_fprintf)(f, "Recognized CPUID flags:\n");
+        listflags(buf, sizeof (buf), (uint32_t)~0, feature_name, 1);
+        (*cpu_fprintf)(f, "  f_edx: %s\n", buf);
+        listflags(buf, sizeof (buf), (uint32_t)~0, ext_feature_name, 1);
+        (*cpu_fprintf)(f, "  f_ecx: %s\n", buf);
+        listflags(buf, sizeof (buf), (uint32_t)~0, ext2_feature_name, 1);
+        (*cpu_fprintf)(f, "  extf_edx: %s\n", buf);
+        listflags(buf, sizeof (buf), (uint32_t)~0, ext3_feature_name, 1);
+        (*cpu_fprintf)(f, "  extf_ecx: %s\n", buf);
+        return;
+    }
+    for (def = x86_defs; def; def = def->next) {
+        snprintf(buf, sizeof (buf), def->flags ? "[%s]": "%s", def->name);
+        if (model || dump) {
+            (*cpu_fprintf)(f, "x86 %16s  %-48s\n", buf, def->model_id);
+        } else {
+            (*cpu_fprintf)(f, "x86 %16s\n", buf);
+        }
+        if (dump) {
+            memcpy(buf, &def->vendor1, sizeof (def->vendor1));
+            memcpy(buf + 4, &def->vendor2, sizeof (def->vendor2));
+            memcpy(buf + 8, &def->vendor3, sizeof (def->vendor3));
+            buf[12] = '\0';
+            (*cpu_fprintf)(f,
+                "  family %d model %d stepping %d level %d xlevel 0x%x"
+                " vendor \"%s\"\n",
+                def->family, def->model, def->stepping, def->level,
+                def->xlevel, buf);
+            listflags(buf, sizeof (buf), def->features, feature_name, 0);
+            (*cpu_fprintf)(f, "  feature_edx %08x (%s)\n", def->features,
+                buf);
+            listflags(buf, sizeof (buf), def->ext_features, ext_feature_name,
+                0);
+            (*cpu_fprintf)(f, "  feature_ecx %08x (%s)\n", def->ext_features,
+                buf);
+            listflags(buf, sizeof (buf), def->ext2_features, ext2_feature_name,
+                0);
+            (*cpu_fprintf)(f, "  extfeature_edx %08x (%s)\n",
+                def->ext2_features, buf);
+            listflags(buf, sizeof (buf), def->ext3_features, ext3_feature_name,
+                0);
+            (*cpu_fprintf)(f, "  extfeature_ecx %08x (%s)\n",
+                def->ext3_features, buf);
+            (*cpu_fprintf)(f, "\n");
+        }
+    }
+    if (kvm_enabled()) {
+        (*cpu_fprintf)(f, "x86 %16s\n", "[host]");
+    }
+}
+
+int cpu_x86_register (CPUX86State *env, const char *cpu_model)
+{
+    x86_def_t def1, *def = &def1;
+
+    memset(def, 0, sizeof(*def));
+
+    if (cpu_x86_find_by_name(def, cpu_model) < 0)
+        return -1;
+    if (def->vendor1) {
+        env->cpuid_vendor1 = def->vendor1;
+        env->cpuid_vendor2 = def->vendor2;
+        env->cpuid_vendor3 = def->vendor3;
+    } else {
+        env->cpuid_vendor1 = CPUID_VENDOR_INTEL_1;
+        env->cpuid_vendor2 = CPUID_VENDOR_INTEL_2;
+        env->cpuid_vendor3 = CPUID_VENDOR_INTEL_3;
+    }
+    env->cpuid_vendor_override = def->vendor_override;
+    env->cpuid_level = def->level;
+    x86_cpuid_version_set_family(env, def->family);
+    x86_cpuid_version_set_model(env, def->model);
+    x86_cpuid_version_set_stepping(env, def->stepping);
+    env->cpuid_features = def->features;
+    env->cpuid_ext_features = def->ext_features;
+    env->cpuid_ext2_features = def->ext2_features;
+    env->cpuid_ext3_features = def->ext3_features;
+    env->cpuid_xlevel = def->xlevel;
+    env->cpuid_kvm_features = def->kvm_features;
+    env->cpuid_svm_features = def->svm_features;
+    env->cpuid_ext4_features = def->ext4_features;
+    env->cpuid_xlevel2 = def->xlevel2;
+    env->tsc_khz = def->tsc_khz;
+    if (!kvm_enabled()) {
+        env->cpuid_features &= TCG_FEATURES;
+        env->cpuid_ext_features &= TCG_EXT_FEATURES;
+        env->cpuid_ext2_features &= (TCG_EXT2_FEATURES
+#ifdef TARGET_X86_64
+            | CPUID_EXT2_SYSCALL | CPUID_EXT2_LM
+#endif
+            );
+        env->cpuid_ext3_features &= TCG_EXT3_FEATURES;
+        env->cpuid_svm_features &= TCG_SVM_FEATURES;
+    }
+    x86_cpuid_set_model_id(env, def->model_id);
+    return 0;
+}
+
+#if !defined(CONFIG_USER_ONLY)
+/* copy vendor id string to 32 bit register, nul pad as needed
+ */
+static void cpyid(const char *s, uint32_t *id)
+{
+    char *d = (char *)id;
+    char i;
+
+    for (i = sizeof (*id); i--; )
+        *d++ = *s ? *s++ : '\0';
+}
+
+/* interpret radix and convert from string to arbitrary scalar,
+ * otherwise flag failure
+ */
+#define setscalar(pval, str, perr)                      \
+{                                                       \
+    char *pend;                                         \
+    unsigned long ul;                                   \
+                                                        \
+    ul = strtoul(str, &pend, 0);                        \
+    *str && !*pend ? (*pval = ul) : (*perr = 1);        \
+}
+
+/* map cpuid options to feature bits, otherwise return failure
+ * (option tags in *str are delimited by whitespace)
+ */
+static void setfeatures(uint32_t *pval, const char *str,
+    const char **featureset, int *perr)
+{
+    const char *p, *q;
+
+    for (q = p = str; *p || *q; q = p) {
+        while (iswhite(*p))
+            q = ++p;
+        while (*p && !iswhite(*p))
+            ++p;
+        if (!*q && !*p)
+            return;
+        if (!lookup_feature(pval, q, p, featureset)) {
+            fprintf(stderr, "error: feature \"%.*s\" not available in set\n",
+                (int)(p - q), q);
+            *perr = 1;
+            return;
+        }
+    }
+}
+
+/* map config file options to x86_def_t form
+ */
+static int cpudef_setfield(const char *name, const char *str, void *opaque)
+{
+    x86_def_t *def = opaque;
+    int err = 0;
+
+    if (!strcmp(name, "name")) {
+        g_free((void *)def->name);
+        def->name = g_strdup(str);
+    } else if (!strcmp(name, "model_id")) {
+        strncpy(def->model_id, str, sizeof (def->model_id));
+    } else if (!strcmp(name, "level")) {
+        setscalar(&def->level, str, &err)
+    } else if (!strcmp(name, "vendor")) {
+        cpyid(&str[0], &def->vendor1);
+        cpyid(&str[4], &def->vendor2);
+        cpyid(&str[8], &def->vendor3);
+    } else if (!strcmp(name, "family")) {
+        setscalar(&def->family, str, &err)
+    } else if (!strcmp(name, "model")) {
+        setscalar(&def->model, str, &err)
+    } else if (!strcmp(name, "stepping")) {
+        setscalar(&def->stepping, str, &err)
+    } else if (!strcmp(name, "feature_edx")) {
+        setfeatures(&def->features, str, feature_name, &err);
+    } else if (!strcmp(name, "feature_ecx")) {
+        setfeatures(&def->ext_features, str, ext_feature_name, &err);
+    } else if (!strcmp(name, "extfeature_edx")) {
+        setfeatures(&def->ext2_features, str, ext2_feature_name, &err);
+    } else if (!strcmp(name, "extfeature_ecx")) {
+        setfeatures(&def->ext3_features, str, ext3_feature_name, &err);
+    } else if (!strcmp(name, "xlevel")) {
+        setscalar(&def->xlevel, str, &err)
+    } else {
+        fprintf(stderr, "error: unknown option [%s = %s]\n", name, str);
+        return (1);
+    }
+    if (err) {
+        fprintf(stderr, "error: bad option value [%s = %s]\n", name, str);
+        return (1);
+    }
+    return (0);
+}
+
+/* register config file entry as x86_def_t
+ */
+static int cpudef_register(QemuOpts *opts, void *opaque)
+{
+    x86_def_t *def = g_malloc0(sizeof (x86_def_t));
+
+    qemu_opt_foreach(opts, cpudef_setfield, def, 1);
+    def->next = x86_defs;
+    x86_defs = def;
+    return (0);
+}
+
+void cpu_clear_apic_feature(CPUX86State *env)
+{
+    env->cpuid_features &= ~CPUID_APIC;
+}
+
+#endif /* !CONFIG_USER_ONLY */
+
+/* register "cpudef" models defined in configuration file.  Here we first
+ * preload any built-in definitions
+ */
+void x86_cpudef_setup(void)
+{
+    int i;
+
+    for (i = 0; i < ARRAY_SIZE(builtin_x86_defs); ++i) {
+        builtin_x86_defs[i].next = x86_defs;
+        builtin_x86_defs[i].flags = 1;
+        x86_defs = &builtin_x86_defs[i];
+    }
+#if !defined(CONFIG_USER_ONLY)
+    qemu_opts_foreach(qemu_find_opts("cpudef"), cpudef_register, NULL, 0);
+#endif
+}
+
+static void get_cpuid_vendor(CPUX86State *env, uint32_t *ebx,
+                             uint32_t *ecx, uint32_t *edx)
+{
+    *ebx = env->cpuid_vendor1;
+    *edx = env->cpuid_vendor2;
+    *ecx = env->cpuid_vendor3;
+
+    /* sysenter isn't supported on compatibility mode on AMD, syscall
+     * isn't supported in compatibility mode on Intel.
+     * Normally we advertise the actual cpu vendor, but you can override
+     * this if you want to use KVM's sysenter/syscall emulation
+     * in compatibility mode and when doing cross vendor migration
+     */
+    if (kvm_enabled() && ! env->cpuid_vendor_override) {
+        host_cpuid(0, 0, NULL, ebx, ecx, edx);
+    }
+}
+
+void cpu_x86_cpuid(CPUX86State *env, uint32_t index, uint32_t count,
+                   uint32_t *eax, uint32_t *ebx,
+                   uint32_t *ecx, uint32_t *edx)
+{
+    /* test if maximum index reached */
+    if (index & 0x80000000) {
+        if (index > env->cpuid_xlevel) {
+            if (env->cpuid_xlevel2 > 0) {
+                /* Handle the Centaur's CPUID instruction. */
+                if (index > env->cpuid_xlevel2) {
+                    index = env->cpuid_xlevel2;
+                } else if (index < 0xC0000000) {
+                    index = env->cpuid_xlevel;
+                }
+            } else {
+                index =  env->cpuid_xlevel;
+            }
+        }
+    } else {
+        if (index > env->cpuid_level)
+            index = env->cpuid_level;
+    }
+
+    switch(index) {
+    case 0:
+        *eax = env->cpuid_level;
+        get_cpuid_vendor(env, ebx, ecx, edx);
+        break;
+    case 1:
+        *eax = env->cpuid_version;
+        *ebx = (env->cpuid_apic_id << 24) | 8 << 8; /* CLFLUSH size in quad words, Linux wants it. */
+        *ecx = env->cpuid_ext_features;
+        *edx = env->cpuid_features;
+        if (env->nr_cores * env->nr_threads > 1) {
+            *ebx |= (env->nr_cores * env->nr_threads) << 16;
+            *edx |= 1 << 28;    /* HTT bit */
+        }
+        break;
+    case 2:
+        /* cache info: needed for Pentium Pro compatibility */
+        *eax = 1;
+        *ebx = 0;
+        *ecx = 0;
+        *edx = 0x2c307d;
+        break;
+    case 4:
+        /* cache info: needed for Core compatibility */
+        if (env->nr_cores > 1) {
+            *eax = (env->nr_cores - 1) << 26;
+        } else {
+            *eax = 0;
+        }
+        switch (count) {
+            case 0: /* L1 dcache info */
+                *eax |= 0x0000121;
+                *ebx = 0x1c0003f;
+                *ecx = 0x000003f;
+                *edx = 0x0000001;
+                break;
+            case 1: /* L1 icache info */
+                *eax |= 0x0000122;
+                *ebx = 0x1c0003f;
+                *ecx = 0x000003f;
+                *edx = 0x0000001;
+                break;
+            case 2: /* L2 cache info */
+                *eax |= 0x0000143;
+                if (env->nr_threads > 1) {
+                    *eax |= (env->nr_threads - 1) << 14;
+                }
+                *ebx = 0x3c0003f;
+                *ecx = 0x0000fff;
+                *edx = 0x0000001;
+                break;
+            default: /* end of info */
+                *eax = 0;
+                *ebx = 0;
+                *ecx = 0;
+                *edx = 0;
+                break;
+        }
+        break;
+    case 5:
+        /* mwait info: needed for Core compatibility */
+        *eax = 0; /* Smallest monitor-line size in bytes */
+        *ebx = 0; /* Largest monitor-line size in bytes */
+        *ecx = CPUID_MWAIT_EMX | CPUID_MWAIT_IBE;
+        *edx = 0;
+        break;
+    case 6:
+        /* Thermal and Power Leaf */
+        *eax = 0;
+        *ebx = 0;
+        *ecx = 0;
+        *edx = 0;
+        break;
+    case 7:
+        if (kvm_enabled()) {
+            KVMState *s = env->kvm_state;
+
+            *eax = kvm_arch_get_supported_cpuid(s, 0x7, count, R_EAX);
+            *ebx = kvm_arch_get_supported_cpuid(s, 0x7, count, R_EBX);
+            *ecx = kvm_arch_get_supported_cpuid(s, 0x7, count, R_ECX);
+            *edx = kvm_arch_get_supported_cpuid(s, 0x7, count, R_EDX);
+        } else {
+            *eax = 0;
+            *ebx = 0;
+            *ecx = 0;
+            *edx = 0;
+        }
+        break;
+    case 9:
+        /* Direct Cache Access Information Leaf */
+        *eax = 0; /* Bits 0-31 in DCA_CAP MSR */
+        *ebx = 0;
+        *ecx = 0;
+        *edx = 0;
+        break;
+    case 0xA:
+        /* Architectural Performance Monitoring Leaf */
+        if (kvm_enabled()) {
+            KVMState *s = env->kvm_state;
+
+            *eax = kvm_arch_get_supported_cpuid(s, 0xA, count, R_EAX);
+            *ebx = kvm_arch_get_supported_cpuid(s, 0xA, count, R_EBX);
+            *ecx = kvm_arch_get_supported_cpuid(s, 0xA, count, R_ECX);
+            *edx = kvm_arch_get_supported_cpuid(s, 0xA, count, R_EDX);
+        } else {
+            *eax = 0;
+            *ebx = 0;
+            *ecx = 0;
+            *edx = 0;
+        }
+        break;
+    case 0xD:
+        /* Processor Extended State */
+        if (!(env->cpuid_ext_features & CPUID_EXT_XSAVE)) {
+            *eax = 0;
+            *ebx = 0;
+            *ecx = 0;
+            *edx = 0;
+            break;
+        }
+        if (kvm_enabled()) {
+            KVMState *s = env->kvm_state;
+
+            *eax = kvm_arch_get_supported_cpuid(s, 0xd, count, R_EAX);
+            *ebx = kvm_arch_get_supported_cpuid(s, 0xd, count, R_EBX);
+            *ecx = kvm_arch_get_supported_cpuid(s, 0xd, count, R_ECX);
+            *edx = kvm_arch_get_supported_cpuid(s, 0xd, count, R_EDX);
+        } else {
+            *eax = 0;
+            *ebx = 0;
+            *ecx = 0;
+            *edx = 0;
+        }
+        break;
+    case 0x80000000:
+        *eax = env->cpuid_xlevel;
+        *ebx = env->cpuid_vendor1;
+        *edx = env->cpuid_vendor2;
+        *ecx = env->cpuid_vendor3;
+        break;
+    case 0x80000001:
+        *eax = env->cpuid_version;
+        *ebx = 0;
+        *ecx = env->cpuid_ext3_features;
+        *edx = env->cpuid_ext2_features;
+
+        /* The Linux kernel checks for the CMPLegacy bit and
+         * discards multiple thread information if it is set.
+         * So dont set it here for Intel to make Linux guests happy.
+         */
+        if (env->nr_cores * env->nr_threads > 1) {
+            uint32_t tebx, tecx, tedx;
+            get_cpuid_vendor(env, &tebx, &tecx, &tedx);
+            if (tebx != CPUID_VENDOR_INTEL_1 ||
+                tedx != CPUID_VENDOR_INTEL_2 ||
+                tecx != CPUID_VENDOR_INTEL_3) {
+                *ecx |= 1 << 1;    /* CmpLegacy bit */
+            }
+        }
+        break;
+    case 0x80000002:
+    case 0x80000003:
+    case 0x80000004:
+        *eax = env->cpuid_model[(index - 0x80000002) * 4 + 0];
+        *ebx = env->cpuid_model[(index - 0x80000002) * 4 + 1];
+        *ecx = env->cpuid_model[(index - 0x80000002) * 4 + 2];
+        *edx = env->cpuid_model[(index - 0x80000002) * 4 + 3];
+        break;
+    case 0x80000005:
+        /* cache info (L1 cache) */
+        *eax = 0x01ff01ff;
+        *ebx = 0x01ff01ff;
+        *ecx = 0x40020140;
+        *edx = 0x40020140;
+        break;
+    case 0x80000006:
+        /* cache info (L2 cache) */
+        *eax = 0;
+        *ebx = 0x42004200;
+        *ecx = 0x02008140;
+        *edx = 0;
+        break;
+    case 0x80000008:
+        /* virtual & phys address size in low 2 bytes. */
+/* XXX: This value must match the one used in the MMU code. */
+        if (env->cpuid_ext2_features & CPUID_EXT2_LM) {
+            /* 64 bit processor */
+/* XXX: The physical address space is limited to 42 bits in exec.c. */
+            *eax = 0x00003028;	/* 48 bits virtual, 40 bits physical */
+        } else {
+            if (env->cpuid_features & CPUID_PSE36)
+                *eax = 0x00000024; /* 36 bits physical */
+            else
+                *eax = 0x00000020; /* 32 bits physical */
+        }
+        *ebx = 0;
+        *ecx = 0;
+        *edx = 0;
+        if (env->nr_cores * env->nr_threads > 1) {
+            *ecx |= (env->nr_cores * env->nr_threads) - 1;
+        }
+        break;
+    case 0x8000000A:
+	if (env->cpuid_ext3_features & CPUID_EXT3_SVM) {
+		*eax = 0x00000001; /* SVM Revision */
+		*ebx = 0x00000010; /* nr of ASIDs */
+		*ecx = 0;
+		*edx = env->cpuid_svm_features; /* optional features */
+	} else {
+		*eax = 0;
+		*ebx = 0;
+		*ecx = 0;
+		*edx = 0;
+	}
+        break;
+    case 0xC0000000:
+        *eax = env->cpuid_xlevel2;
+        *ebx = 0;
+        *ecx = 0;
+        *edx = 0;
+        break;
+    case 0xC0000001:
+        /* Support for VIA CPU's CPUID instruction */
+        *eax = env->cpuid_version;
+        *ebx = 0;
+        *ecx = 0;
+        *edx = env->cpuid_ext4_features;
+        break;
+    case 0xC0000002:
+    case 0xC0000003:
+    case 0xC0000004:
+        /* Reserved for the future, and now filled with zero */
+        *eax = 0;
+        *ebx = 0;
+        *ecx = 0;
+        *edx = 0;
+        break;
+    default:
+        /* reserved values: zero */
+        *eax = 0;
+        *ebx = 0;
+        *ecx = 0;
+        *edx = 0;
+        break;
+    }
+}
diff --git a/target-i386/cpuid.c b/target-i386/cpuid.c
deleted file mode 100644
index 465ea15..0000000
--- a/target-i386/cpuid.c
+++ /dev/null
@@ -1,1369 +0,0 @@
-/*
- *  i386 CPUID helper functions
- *
- *  Copyright (c) 2003 Fabrice Bellard
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2 of the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, see <http://www.gnu.org/licenses/>.
- */
-#include <stdlib.h>
-#include <stdio.h>
-#include <string.h>
-#include <inttypes.h>
-
-#include "cpu.h"
-#include "kvm.h"
-
-#include "qemu-option.h"
-#include "qemu-config.h"
-
-#include "hyperv.h"
-
-/* feature flags taken from "Intel Processor Identification and the CPUID
- * Instruction" and AMD's "CPUID Specification".  In cases of disagreement
- * between feature naming conventions, aliases may be added.
- */
-static const char *feature_name[] = {
-    "fpu", "vme", "de", "pse",
-    "tsc", "msr", "pae", "mce",
-    "cx8", "apic", NULL, "sep",
-    "mtrr", "pge", "mca", "cmov",
-    "pat", "pse36", "pn" /* Intel psn */, "clflush" /* Intel clfsh */,
-    NULL, "ds" /* Intel dts */, "acpi", "mmx",
-    "fxsr", "sse", "sse2", "ss",
-    "ht" /* Intel htt */, "tm", "ia64", "pbe",
-};
-static const char *ext_feature_name[] = {
-    "pni|sse3" /* Intel,AMD sse3 */, "pclmulqdq|pclmuldq", "dtes64", "monitor",
-    "ds_cpl", "vmx", "smx", "est",
-    "tm2", "ssse3", "cid", NULL,
-    "fma", "cx16", "xtpr", "pdcm",
-    NULL, NULL, "dca", "sse4.1|sse4_1",
-    "sse4.2|sse4_2", "x2apic", "movbe", "popcnt",
-    "tsc-deadline", "aes", "xsave", "osxsave",
-    "avx", NULL, NULL, "hypervisor",
-};
-static const char *ext2_feature_name[] = {
-    "fpu", "vme", "de", "pse",
-    "tsc", "msr", "pae", "mce",
-    "cx8" /* AMD CMPXCHG8B */, "apic", NULL, "syscall",
-    "mtrr", "pge", "mca", "cmov",
-    "pat", "pse36", NULL, NULL /* Linux mp */,
-    "nx|xd", NULL, "mmxext", "mmx",
-    "fxsr", "fxsr_opt|ffxsr", "pdpe1gb" /* AMD Page1GB */, "rdtscp",
-    NULL, "lm|i64", "3dnowext", "3dnow",
-};
-static const char *ext3_feature_name[] = {
-    "lahf_lm" /* AMD LahfSahf */, "cmp_legacy", "svm", "extapic" /* AMD ExtApicSpace */,
-    "cr8legacy" /* AMD AltMovCr8 */, "abm", "sse4a", "misalignsse",
-    "3dnowprefetch", "osvw", "ibs", "xop",
-    "skinit", "wdt", NULL, NULL,
-    "fma4", NULL, "cvt16", "nodeid_msr",
-    NULL, NULL, NULL, NULL,
-    NULL, NULL, NULL, NULL,
-    NULL, NULL, NULL, NULL,
-};
-
-static const char *kvm_feature_name[] = {
-    "kvmclock", "kvm_nopiodelay", "kvm_mmu", "kvmclock", "kvm_asyncpf", NULL, NULL, NULL,
-    NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
-    NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
-    NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
-};
-
-static const char *svm_feature_name[] = {
-    "npt", "lbrv", "svm_lock", "nrip_save",
-    "tsc_scale", "vmcb_clean",  "flushbyasid", "decodeassists",
-    NULL, NULL, "pause_filter", NULL,
-    "pfthreshold", NULL, NULL, NULL,
-    NULL, NULL, NULL, NULL,
-    NULL, NULL, NULL, NULL,
-    NULL, NULL, NULL, NULL,
-    NULL, NULL, NULL, NULL,
-};
-
-/* collects per-function cpuid data
- */
-typedef struct model_features_t {
-    uint32_t *guest_feat;
-    uint32_t *host_feat;
-    uint32_t check_feat;
-    const char **flag_names;
-    uint32_t cpuid;
-    } model_features_t;
-
-int check_cpuid = 0;
-int enforce_cpuid = 0;
-
-void host_cpuid(uint32_t function, uint32_t count,
-                uint32_t *eax, uint32_t *ebx, uint32_t *ecx, uint32_t *edx)
-{
-#if defined(CONFIG_KVM)
-    uint32_t vec[4];
-
-#ifdef __x86_64__
-    asm volatile("cpuid"
-                 : "=a"(vec[0]), "=b"(vec[1]),
-                   "=c"(vec[2]), "=d"(vec[3])
-                 : "0"(function), "c"(count) : "cc");
-#else
-    asm volatile("pusha \n\t"
-                 "cpuid \n\t"
-                 "mov %%eax, 0(%2) \n\t"
-                 "mov %%ebx, 4(%2) \n\t"
-                 "mov %%ecx, 8(%2) \n\t"
-                 "mov %%edx, 12(%2) \n\t"
-                 "popa"
-                 : : "a"(function), "c"(count), "S"(vec)
-                 : "memory", "cc");
-#endif
-
-    if (eax)
-        *eax = vec[0];
-    if (ebx)
-        *ebx = vec[1];
-    if (ecx)
-        *ecx = vec[2];
-    if (edx)
-        *edx = vec[3];
-#endif
-}
-
-#define iswhite(c) ((c) && ((c) <= ' ' || '~' < (c)))
-
-/* general substring compare of *[s1..e1) and *[s2..e2).  sx is start of
- * a substring.  ex if !NULL points to the first char after a substring,
- * otherwise the string is assumed to sized by a terminating nul.
- * Return lexical ordering of *s1:*s2.
- */
-static int sstrcmp(const char *s1, const char *e1, const char *s2,
-    const char *e2)
-{
-    for (;;) {
-        if (!*s1 || !*s2 || *s1 != *s2)
-            return (*s1 - *s2);
-        ++s1, ++s2;
-        if (s1 == e1 && s2 == e2)
-            return (0);
-        else if (s1 == e1)
-            return (*s2);
-        else if (s2 == e2)
-            return (*s1);
-    }
-}
-
-/* compare *[s..e) to *altstr.  *altstr may be a simple string or multiple
- * '|' delimited (possibly empty) strings in which case search for a match
- * within the alternatives proceeds left to right.  Return 0 for success,
- * non-zero otherwise.
- */
-static int altcmp(const char *s, const char *e, const char *altstr)
-{
-    const char *p, *q;
-
-    for (q = p = altstr; ; ) {
-        while (*p && *p != '|')
-            ++p;
-        if ((q == p && !*s) || (q != p && !sstrcmp(s, e, q, p)))
-            return (0);
-        if (!*p)
-            return (1);
-        else
-            q = ++p;
-    }
-}
-
-/* search featureset for flag *[s..e), if found set corresponding bit in
- * *pval and return true, otherwise return false
- */
-static bool lookup_feature(uint32_t *pval, const char *s, const char *e,
-                           const char **featureset)
-{
-    uint32_t mask;
-    const char **ppc;
-    bool found = false;
-
-    for (mask = 1, ppc = featureset; mask; mask <<= 1, ++ppc) {
-        if (*ppc && !altcmp(s, e, *ppc)) {
-            *pval |= mask;
-            found = true;
-        }
-    }
-    return found;
-}
-
-static void add_flagname_to_bitmaps(const char *flagname, uint32_t *features,
-                                    uint32_t *ext_features,
-                                    uint32_t *ext2_features,
-                                    uint32_t *ext3_features,
-                                    uint32_t *kvm_features,
-                                    uint32_t *svm_features)
-{
-    if (!lookup_feature(features, flagname, NULL, feature_name) &&
-        !lookup_feature(ext_features, flagname, NULL, ext_feature_name) &&
-        !lookup_feature(ext2_features, flagname, NULL, ext2_feature_name) &&
-        !lookup_feature(ext3_features, flagname, NULL, ext3_feature_name) &&
-        !lookup_feature(kvm_features, flagname, NULL, kvm_feature_name) &&
-        !lookup_feature(svm_features, flagname, NULL, svm_feature_name))
-            fprintf(stderr, "CPU feature %s not found\n", flagname);
-}
-
-typedef struct x86_def_t {
-    struct x86_def_t *next;
-    const char *name;
-    uint32_t level;
-    uint32_t vendor1, vendor2, vendor3;
-    int family;
-    int model;
-    int stepping;
-    int tsc_khz;
-    uint32_t features, ext_features, ext2_features, ext3_features;
-    uint32_t kvm_features, svm_features;
-    uint32_t xlevel;
-    char model_id[48];
-    int vendor_override;
-    uint32_t flags;
-    /* Store the results of Centaur's CPUID instructions */
-    uint32_t ext4_features;
-    uint32_t xlevel2;
-} x86_def_t;
-
-#define I486_FEATURES (CPUID_FP87 | CPUID_VME | CPUID_PSE)
-#define PENTIUM_FEATURES (I486_FEATURES | CPUID_DE | CPUID_TSC | \
-          CPUID_MSR | CPUID_MCE | CPUID_CX8 | CPUID_MMX | CPUID_APIC)
-#define PENTIUM2_FEATURES (PENTIUM_FEATURES | CPUID_PAE | CPUID_SEP | \
-          CPUID_MTRR | CPUID_PGE | CPUID_MCA | CPUID_CMOV | CPUID_PAT | \
-          CPUID_PSE36 | CPUID_FXSR)
-#define PENTIUM3_FEATURES (PENTIUM2_FEATURES | CPUID_SSE)
-#define PPRO_FEATURES (CPUID_FP87 | CPUID_DE | CPUID_PSE | CPUID_TSC | \
-          CPUID_MSR | CPUID_MCE | CPUID_CX8 | CPUID_PGE | CPUID_CMOV | \
-          CPUID_PAT | CPUID_FXSR | CPUID_MMX | CPUID_SSE | CPUID_SSE2 | \
-          CPUID_PAE | CPUID_SEP | CPUID_APIC)
-#define EXT2_FEATURE_MASK 0x0183F3FF
-
-#define TCG_FEATURES (CPUID_FP87 | CPUID_PSE | CPUID_TSC | CPUID_MSR | \
-          CPUID_PAE | CPUID_MCE | CPUID_CX8 | CPUID_APIC | CPUID_SEP | \
-          CPUID_MTRR | CPUID_PGE | CPUID_MCA | CPUID_CMOV | CPUID_PAT | \
-          CPUID_PSE36 | CPUID_CLFLUSH | CPUID_ACPI | CPUID_MMX | \
-          CPUID_FXSR | CPUID_SSE | CPUID_SSE2 | CPUID_SS)
-          /* partly implemented:
-          CPUID_MTRR, CPUID_MCA, CPUID_CLFLUSH (needed for Win64)
-          CPUID_PSE36 (needed for Solaris) */
-          /* missing:
-          CPUID_VME, CPUID_DTS, CPUID_SS, CPUID_HT, CPUID_TM, CPUID_PBE */
-#define TCG_EXT_FEATURES (CPUID_EXT_SSE3 | CPUID_EXT_MONITOR | \
-          CPUID_EXT_CX16 | CPUID_EXT_POPCNT | \
-          CPUID_EXT_HYPERVISOR)
-          /* missing:
-          CPUID_EXT_DTES64, CPUID_EXT_DSCPL, CPUID_EXT_VMX, CPUID_EXT_EST,
-          CPUID_EXT_TM2, CPUID_EXT_XTPR, CPUID_EXT_PDCM, CPUID_EXT_XSAVE */
-#define TCG_EXT2_FEATURES ((TCG_FEATURES & EXT2_FEATURE_MASK) | \
-          CPUID_EXT2_NX | CPUID_EXT2_MMXEXT | CPUID_EXT2_RDTSCP | \
-          CPUID_EXT2_3DNOW | CPUID_EXT2_3DNOWEXT)
-          /* missing:
-          CPUID_EXT2_PDPE1GB */
-#define TCG_EXT3_FEATURES (CPUID_EXT3_LAHF_LM | CPUID_EXT3_SVM | \
-          CPUID_EXT3_CR8LEG | CPUID_EXT3_ABM | CPUID_EXT3_SSE4A)
-#define TCG_SVM_FEATURES 0
-
-/* maintains list of cpu model definitions
- */
-static x86_def_t *x86_defs = {NULL};
-
-/* built-in cpu model definitions (deprecated)
- */
-static x86_def_t builtin_x86_defs[] = {
-    {
-        .name = "qemu64",
-        .level = 4,
-        .vendor1 = CPUID_VENDOR_AMD_1,
-        .vendor2 = CPUID_VENDOR_AMD_2,
-        .vendor3 = CPUID_VENDOR_AMD_3,
-        .family = 6,
-        .model = 2,
-        .stepping = 3,
-        .features = PPRO_FEATURES |
-            CPUID_MTRR | CPUID_CLFLUSH | CPUID_MCA |
-            CPUID_PSE36,
-        .ext_features = CPUID_EXT_SSE3 | CPUID_EXT_CX16 | CPUID_EXT_POPCNT,
-        .ext2_features = (PPRO_FEATURES & EXT2_FEATURE_MASK) |
-            CPUID_EXT2_LM | CPUID_EXT2_SYSCALL | CPUID_EXT2_NX,
-        .ext3_features = CPUID_EXT3_LAHF_LM | CPUID_EXT3_SVM |
-            CPUID_EXT3_ABM | CPUID_EXT3_SSE4A,
-        .xlevel = 0x8000000A,
-        .model_id = "QEMU Virtual CPU version " QEMU_VERSION,
-    },
-    {
-        .name = "phenom",
-        .level = 5,
-        .vendor1 = CPUID_VENDOR_AMD_1,
-        .vendor2 = CPUID_VENDOR_AMD_2,
-        .vendor3 = CPUID_VENDOR_AMD_3,
-        .family = 16,
-        .model = 2,
-        .stepping = 3,
-        .features = PPRO_FEATURES |
-            CPUID_MTRR | CPUID_CLFLUSH | CPUID_MCA |
-            CPUID_PSE36 | CPUID_VME | CPUID_HT,
-        .ext_features = CPUID_EXT_SSE3 | CPUID_EXT_MONITOR | CPUID_EXT_CX16 |
-            CPUID_EXT_POPCNT,
-        .ext2_features = (PPRO_FEATURES & EXT2_FEATURE_MASK) |
-            CPUID_EXT2_LM | CPUID_EXT2_SYSCALL | CPUID_EXT2_NX |
-            CPUID_EXT2_3DNOW | CPUID_EXT2_3DNOWEXT | CPUID_EXT2_MMXEXT |
-            CPUID_EXT2_FFXSR | CPUID_EXT2_PDPE1GB | CPUID_EXT2_RDTSCP,
-        /* Missing: CPUID_EXT3_CMP_LEG, CPUID_EXT3_EXTAPIC,
-                    CPUID_EXT3_CR8LEG,
-                    CPUID_EXT3_MISALIGNSSE, CPUID_EXT3_3DNOWPREFETCH,
-                    CPUID_EXT3_OSVW, CPUID_EXT3_IBS */
-        .ext3_features = CPUID_EXT3_LAHF_LM | CPUID_EXT3_SVM |
-            CPUID_EXT3_ABM | CPUID_EXT3_SSE4A,
-        .svm_features = CPUID_SVM_NPT | CPUID_SVM_LBRV,
-        .xlevel = 0x8000001A,
-        .model_id = "AMD Phenom(tm) 9550 Quad-Core Processor"
-    },
-    {
-        .name = "core2duo",
-        .level = 10,
-        .family = 6,
-        .model = 15,
-        .stepping = 11,
-        .features = PPRO_FEATURES |
-            CPUID_MTRR | CPUID_CLFLUSH | CPUID_MCA |
-            CPUID_PSE36 | CPUID_VME | CPUID_DTS | CPUID_ACPI | CPUID_SS |
-            CPUID_HT | CPUID_TM | CPUID_PBE,
-        .ext_features = CPUID_EXT_SSE3 | CPUID_EXT_MONITOR | CPUID_EXT_SSSE3 |
-            CPUID_EXT_DTES64 | CPUID_EXT_DSCPL | CPUID_EXT_VMX | CPUID_EXT_EST |
-            CPUID_EXT_TM2 | CPUID_EXT_CX16 | CPUID_EXT_XTPR | CPUID_EXT_PDCM,
-        .ext2_features = CPUID_EXT2_LM | CPUID_EXT2_SYSCALL | CPUID_EXT2_NX,
-        .ext3_features = CPUID_EXT3_LAHF_LM,
-        .xlevel = 0x80000008,
-        .model_id = "Intel(R) Core(TM)2 Duo CPU     T7700  @ 2.40GHz",
-    },
-    {
-        .name = "kvm64",
-        .level = 5,
-        .vendor1 = CPUID_VENDOR_INTEL_1,
-        .vendor2 = CPUID_VENDOR_INTEL_2,
-        .vendor3 = CPUID_VENDOR_INTEL_3,
-        .family = 15,
-        .model = 6,
-        .stepping = 1,
-        /* Missing: CPUID_VME, CPUID_HT */
-        .features = PPRO_FEATURES |
-            CPUID_MTRR | CPUID_CLFLUSH | CPUID_MCA |
-            CPUID_PSE36,
-        /* Missing: CPUID_EXT_POPCNT, CPUID_EXT_MONITOR */
-        .ext_features = CPUID_EXT_SSE3 | CPUID_EXT_CX16,
-        /* Missing: CPUID_EXT2_PDPE1GB, CPUID_EXT2_RDTSCP */
-        .ext2_features = (PPRO_FEATURES & EXT2_FEATURE_MASK) |
-            CPUID_EXT2_LM | CPUID_EXT2_SYSCALL | CPUID_EXT2_NX,
-        /* Missing: CPUID_EXT3_LAHF_LM, CPUID_EXT3_CMP_LEG, CPUID_EXT3_EXTAPIC,
-                    CPUID_EXT3_CR8LEG, CPUID_EXT3_ABM, CPUID_EXT3_SSE4A,
-                    CPUID_EXT3_MISALIGNSSE, CPUID_EXT3_3DNOWPREFETCH,
-                    CPUID_EXT3_OSVW, CPUID_EXT3_IBS, CPUID_EXT3_SVM */
-        .ext3_features = 0,
-        .xlevel = 0x80000008,
-        .model_id = "Common KVM processor"
-    },
-    {
-        .name = "qemu32",
-        .level = 4,
-        .family = 6,
-        .model = 3,
-        .stepping = 3,
-        .features = PPRO_FEATURES,
-        .ext_features = CPUID_EXT_SSE3 | CPUID_EXT_POPCNT,
-        .xlevel = 0x80000004,
-        .model_id = "QEMU Virtual CPU version " QEMU_VERSION,
-    },
-    {
-        .name = "kvm32",
-        .level = 5,
-        .family = 15,
-        .model = 6,
-        .stepping = 1,
-        .features = PPRO_FEATURES |
-            CPUID_MTRR | CPUID_CLFLUSH | CPUID_MCA | CPUID_PSE36,
-        .ext_features = CPUID_EXT_SSE3,
-        .ext2_features = PPRO_FEATURES & EXT2_FEATURE_MASK,
-        .ext3_features = 0,
-        .xlevel = 0x80000008,
-        .model_id = "Common 32-bit KVM processor"
-    },
-    {
-        .name = "coreduo",
-        .level = 10,
-        .family = 6,
-        .model = 14,
-        .stepping = 8,
-        .features = PPRO_FEATURES | CPUID_VME |
-            CPUID_MTRR | CPUID_CLFLUSH | CPUID_MCA | CPUID_DTS | CPUID_ACPI |
-            CPUID_SS | CPUID_HT | CPUID_TM | CPUID_PBE,
-        .ext_features = CPUID_EXT_SSE3 | CPUID_EXT_MONITOR | CPUID_EXT_VMX |
-            CPUID_EXT_EST | CPUID_EXT_TM2 | CPUID_EXT_XTPR | CPUID_EXT_PDCM,
-        .ext2_features = CPUID_EXT2_NX,
-        .xlevel = 0x80000008,
-        .model_id = "Genuine Intel(R) CPU           T2600  @ 2.16GHz",
-    },
-    {
-        .name = "486",
-        .level = 1,
-        .family = 4,
-        .model = 0,
-        .stepping = 0,
-        .features = I486_FEATURES,
-        .xlevel = 0,
-    },
-    {
-        .name = "pentium",
-        .level = 1,
-        .family = 5,
-        .model = 4,
-        .stepping = 3,
-        .features = PENTIUM_FEATURES,
-        .xlevel = 0,
-    },
-    {
-        .name = "pentium2",
-        .level = 2,
-        .family = 6,
-        .model = 5,
-        .stepping = 2,
-        .features = PENTIUM2_FEATURES,
-        .xlevel = 0,
-    },
-    {
-        .name = "pentium3",
-        .level = 2,
-        .family = 6,
-        .model = 7,
-        .stepping = 3,
-        .features = PENTIUM3_FEATURES,
-        .xlevel = 0,
-    },
-    {
-        .name = "athlon",
-        .level = 2,
-        .vendor1 = CPUID_VENDOR_AMD_1,
-        .vendor2 = CPUID_VENDOR_AMD_2,
-        .vendor3 = CPUID_VENDOR_AMD_3,
-        .family = 6,
-        .model = 2,
-        .stepping = 3,
-        .features = PPRO_FEATURES | CPUID_PSE36 | CPUID_VME | CPUID_MTRR | CPUID_MCA,
-        .ext2_features = (PPRO_FEATURES & EXT2_FEATURE_MASK) | CPUID_EXT2_MMXEXT | CPUID_EXT2_3DNOW | CPUID_EXT2_3DNOWEXT,
-        .xlevel = 0x80000008,
-        /* XXX: put another string ? */
-        .model_id = "QEMU Virtual CPU version " QEMU_VERSION,
-    },
-    {
-        .name = "n270",
-        /* original is on level 10 */
-        .level = 5,
-        .family = 6,
-        .model = 28,
-        .stepping = 2,
-        .features = PPRO_FEATURES |
-            CPUID_MTRR | CPUID_CLFLUSH | CPUID_MCA | CPUID_VME | CPUID_DTS |
-            CPUID_ACPI | CPUID_SS | CPUID_HT | CPUID_TM | CPUID_PBE,
-            /* Some CPUs got no CPUID_SEP */
-        .ext_features = CPUID_EXT_SSE3 | CPUID_EXT_MONITOR | CPUID_EXT_SSSE3 |
-            CPUID_EXT_DSCPL | CPUID_EXT_EST | CPUID_EXT_TM2 | CPUID_EXT_XTPR,
-        .ext2_features = (PPRO_FEATURES & EXT2_FEATURE_MASK) | CPUID_EXT2_NX,
-        .ext3_features = CPUID_EXT3_LAHF_LM,
-        .xlevel = 0x8000000A,
-        .model_id = "Intel(R) Atom(TM) CPU N270   @ 1.60GHz",
-    },
-};
-
-static int cpu_x86_fill_model_id(char *str)
-{
-    uint32_t eax = 0, ebx = 0, ecx = 0, edx = 0;
-    int i;
-
-    for (i = 0; i < 3; i++) {
-        host_cpuid(0x80000002 + i, 0, &eax, &ebx, &ecx, &edx);
-        memcpy(str + i * 16 +  0, &eax, 4);
-        memcpy(str + i * 16 +  4, &ebx, 4);
-        memcpy(str + i * 16 +  8, &ecx, 4);
-        memcpy(str + i * 16 + 12, &edx, 4);
-    }
-    return 0;
-}
-
-static int cpu_x86_fill_host(x86_def_t *x86_cpu_def)
-{
-    uint32_t eax = 0, ebx = 0, ecx = 0, edx = 0;
-
-    x86_cpu_def->name = "host";
-    host_cpuid(0x0, 0, &eax, &ebx, &ecx, &edx);
-    x86_cpu_def->level = eax;
-    x86_cpu_def->vendor1 = ebx;
-    x86_cpu_def->vendor2 = edx;
-    x86_cpu_def->vendor3 = ecx;
-
-    host_cpuid(0x1, 0, &eax, &ebx, &ecx, &edx);
-    x86_cpu_def->family = ((eax >> 8) & 0x0F) + ((eax >> 20) & 0xFF);
-    x86_cpu_def->model = ((eax >> 4) & 0x0F) | ((eax & 0xF0000) >> 12);
-    x86_cpu_def->stepping = eax & 0x0F;
-    x86_cpu_def->ext_features = ecx;
-    x86_cpu_def->features = edx;
-
-    host_cpuid(0x80000000, 0, &eax, &ebx, &ecx, &edx);
-    x86_cpu_def->xlevel = eax;
-
-    host_cpuid(0x80000001, 0, &eax, &ebx, &ecx, &edx);
-    x86_cpu_def->ext2_features = edx;
-    x86_cpu_def->ext3_features = ecx;
-    cpu_x86_fill_model_id(x86_cpu_def->model_id);
-    x86_cpu_def->vendor_override = 0;
-
-    /* Call Centaur's CPUID instruction. */
-    if (x86_cpu_def->vendor1 == CPUID_VENDOR_VIA_1 &&
-        x86_cpu_def->vendor2 == CPUID_VENDOR_VIA_2 &&
-        x86_cpu_def->vendor3 == CPUID_VENDOR_VIA_3) {
-        host_cpuid(0xC0000000, 0, &eax, &ebx, &ecx, &edx);
-        if (eax >= 0xC0000001) {
-            /* Support VIA max extended level */
-            x86_cpu_def->xlevel2 = eax;
-            host_cpuid(0xC0000001, 0, &eax, &ebx, &ecx, &edx);
-            x86_cpu_def->ext4_features = edx;
-        }
-    }
-
-    /*
-     * Every SVM feature requires emulation support in KVM - so we can't just
-     * read the host features here. KVM might even support SVM features not
-     * available on the host hardware. Just set all bits and mask out the
-     * unsupported ones later.
-     */
-    x86_cpu_def->svm_features = -1;
-
-    return 0;
-}
-
-static int unavailable_host_feature(struct model_features_t *f, uint32_t mask)
-{
-    int i;
-
-    for (i = 0; i < 32; ++i)
-        if (1 << i & mask) {
-            fprintf(stderr, "warning: host cpuid %04x_%04x lacks requested"
-                " flag '%s' [0x%08x]\n",
-                f->cpuid >> 16, f->cpuid & 0xffff,
-                f->flag_names[i] ? f->flag_names[i] : "[reserved]", mask);
-            break;
-        }
-    return 0;
-}
-
-/* best effort attempt to inform user requested cpu flags aren't making
- * their way to the guest.  Note: ft[].check_feat ideally should be
- * specified via a guest_def field to suppress report of extraneous flags.
- */
-static int check_features_against_host(x86_def_t *guest_def)
-{
-    x86_def_t host_def;
-    uint32_t mask;
-    int rv, i;
-    struct model_features_t ft[] = {
-        {&guest_def->features, &host_def.features,
-            ~0, feature_name, 0x00000000},
-        {&guest_def->ext_features, &host_def.ext_features,
-            ~CPUID_EXT_HYPERVISOR, ext_feature_name, 0x00000001},
-        {&guest_def->ext2_features, &host_def.ext2_features,
-            ~PPRO_FEATURES, ext2_feature_name, 0x80000000},
-        {&guest_def->ext3_features, &host_def.ext3_features,
-            ~CPUID_EXT3_SVM, ext3_feature_name, 0x80000001}};
-
-    cpu_x86_fill_host(&host_def);
-    for (rv = 0, i = 0; i < ARRAY_SIZE(ft); ++i)
-        for (mask = 1; mask; mask <<= 1)
-            if (ft[i].check_feat & mask && *ft[i].guest_feat & mask &&
-                !(*ft[i].host_feat & mask)) {
-                    unavailable_host_feature(&ft[i], mask);
-                    rv = 1;
-                }
-    return rv;
-}
-
-static void x86_cpuid_version_set_family(CPUX86State *env, int family)
-{
-    env->cpuid_version &= ~0xff00f00;
-    if (family > 0x0f) {
-        env->cpuid_version |= 0xf00 | ((family - 0x0f) << 20);
-    } else {
-        env->cpuid_version |= family << 8;
-    }
-}
-
-static void x86_cpuid_version_set_model(CPUX86State *env, int model)
-{
-    env->cpuid_version &= ~0xf00f0;
-    env->cpuid_version |= ((model & 0xf) << 4) | ((model >> 4) << 16);
-}
-
-static void x86_cpuid_version_set_stepping(CPUX86State *env, int stepping)
-{
-    env->cpuid_version &= ~0xf;
-    env->cpuid_version |= stepping & 0xf;
-}
-
-static void x86_cpuid_set_model_id(CPUX86State *env, const char *model_id)
-{
-    int c, len, i;
-
-    if (model_id == NULL) {
-        model_id = "";
-    }
-    len = strlen(model_id);
-    for (i = 0; i < 48; i++) {
-        if (i >= len) {
-            c = '\0';
-        } else {
-            c = (uint8_t)model_id[i];
-        }
-        env->cpuid_model[i >> 2] |= c << (8 * (i & 3));
-    }
-}
-
-static int cpu_x86_find_by_name(x86_def_t *x86_cpu_def, const char *cpu_model)
-{
-    unsigned int i;
-    x86_def_t *def;
-
-    char *s = g_strdup(cpu_model);
-    char *featurestr, *name = strtok(s, ",");
-    /* Features to be added*/
-    uint32_t plus_features = 0, plus_ext_features = 0;
-    uint32_t plus_ext2_features = 0, plus_ext3_features = 0;
-    uint32_t plus_kvm_features = 0, plus_svm_features = 0;
-    /* Features to be removed */
-    uint32_t minus_features = 0, minus_ext_features = 0;
-    uint32_t minus_ext2_features = 0, minus_ext3_features = 0;
-    uint32_t minus_kvm_features = 0, minus_svm_features = 0;
-    uint32_t numvalue;
-
-    for (def = x86_defs; def; def = def->next)
-        if (name && !strcmp(name, def->name))
-            break;
-    if (kvm_enabled() && name && strcmp(name, "host") == 0) {
-        cpu_x86_fill_host(x86_cpu_def);
-    } else if (!def) {
-        goto error;
-    } else {
-        memcpy(x86_cpu_def, def, sizeof(*def));
-    }
-
-    plus_kvm_features = ~0; /* not supported bits will be filtered out later */
-
-    add_flagname_to_bitmaps("hypervisor", &plus_features,
-        &plus_ext_features, &plus_ext2_features, &plus_ext3_features,
-        &plus_kvm_features, &plus_svm_features);
-
-    featurestr = strtok(NULL, ",");
-
-    while (featurestr) {
-        char *val;
-        if (featurestr[0] == '+') {
-            add_flagname_to_bitmaps(featurestr + 1, &plus_features,
-                            &plus_ext_features, &plus_ext2_features,
-                            &plus_ext3_features, &plus_kvm_features,
-                            &plus_svm_features);
-        } else if (featurestr[0] == '-') {
-            add_flagname_to_bitmaps(featurestr + 1, &minus_features,
-                            &minus_ext_features, &minus_ext2_features,
-                            &minus_ext3_features, &minus_kvm_features,
-                            &minus_svm_features);
-        } else if ((val = strchr(featurestr, '='))) {
-            *val = 0; val++;
-            if (!strcmp(featurestr, "family")) {
-                char *err;
-                numvalue = strtoul(val, &err, 0);
-                if (!*val || *err) {
-                    fprintf(stderr, "bad numerical value %s\n", val);
-                    goto error;
-                }
-                x86_cpu_def->family = numvalue;
-            } else if (!strcmp(featurestr, "model")) {
-                char *err;
-                numvalue = strtoul(val, &err, 0);
-                if (!*val || *err || numvalue > 0xff) {
-                    fprintf(stderr, "bad numerical value %s\n", val);
-                    goto error;
-                }
-                x86_cpu_def->model = numvalue;
-            } else if (!strcmp(featurestr, "stepping")) {
-                char *err;
-                numvalue = strtoul(val, &err, 0);
-                if (!*val || *err || numvalue > 0xf) {
-                    fprintf(stderr, "bad numerical value %s\n", val);
-                    goto error;
-                }
-                x86_cpu_def->stepping = numvalue ;
-            } else if (!strcmp(featurestr, "level")) {
-                char *err;
-                numvalue = strtoul(val, &err, 0);
-                if (!*val || *err) {
-                    fprintf(stderr, "bad numerical value %s\n", val);
-                    goto error;
-                }
-                x86_cpu_def->level = numvalue;
-            } else if (!strcmp(featurestr, "xlevel")) {
-                char *err;
-                numvalue = strtoul(val, &err, 0);
-                if (!*val || *err) {
-                    fprintf(stderr, "bad numerical value %s\n", val);
-                    goto error;
-                }
-                if (numvalue < 0x80000000) {
-                    numvalue += 0x80000000;
-                }
-                x86_cpu_def->xlevel = numvalue;
-            } else if (!strcmp(featurestr, "vendor")) {
-                if (strlen(val) != 12) {
-                    fprintf(stderr, "vendor string must be 12 chars long\n");
-                    goto error;
-                }
-                x86_cpu_def->vendor1 = 0;
-                x86_cpu_def->vendor2 = 0;
-                x86_cpu_def->vendor3 = 0;
-                for(i = 0; i < 4; i++) {
-                    x86_cpu_def->vendor1 |= ((uint8_t)val[i    ]) << (8 * i);
-                    x86_cpu_def->vendor2 |= ((uint8_t)val[i + 4]) << (8 * i);
-                    x86_cpu_def->vendor3 |= ((uint8_t)val[i + 8]) << (8 * i);
-                }
-                x86_cpu_def->vendor_override = 1;
-            } else if (!strcmp(featurestr, "model_id")) {
-                pstrcpy(x86_cpu_def->model_id, sizeof(x86_cpu_def->model_id),
-                        val);
-            } else if (!strcmp(featurestr, "tsc_freq")) {
-                int64_t tsc_freq;
-                char *err;
-
-                tsc_freq = strtosz_suffix_unit(val, &err,
-                                               STRTOSZ_DEFSUFFIX_B, 1000);
-                if (tsc_freq < 0 || *err) {
-                    fprintf(stderr, "bad numerical value %s\n", val);
-                    goto error;
-                }
-                x86_cpu_def->tsc_khz = tsc_freq / 1000;
-            } else if (!strcmp(featurestr, "hv_spinlocks")) {
-                char *err;
-                numvalue = strtoul(val, &err, 0);
-                if (!*val || *err) {
-                    fprintf(stderr, "bad numerical value %s\n", val);
-                    goto error;
-                }
-                hyperv_set_spinlock_retries(numvalue);
-            } else {
-                fprintf(stderr, "unrecognized feature %s\n", featurestr);
-                goto error;
-            }
-        } else if (!strcmp(featurestr, "check")) {
-            check_cpuid = 1;
-        } else if (!strcmp(featurestr, "enforce")) {
-            check_cpuid = enforce_cpuid = 1;
-        } else if (!strcmp(featurestr, "hv_relaxed")) {
-            hyperv_enable_relaxed_timing(true);
-        } else if (!strcmp(featurestr, "hv_vapic")) {
-            hyperv_enable_vapic_recommended(true);
-        } else {
-            fprintf(stderr, "feature string `%s' not in format (+feature|-feature|feature=xyz)\n", featurestr);
-            goto error;
-        }
-        featurestr = strtok(NULL, ",");
-    }
-    x86_cpu_def->features |= plus_features;
-    x86_cpu_def->ext_features |= plus_ext_features;
-    x86_cpu_def->ext2_features |= plus_ext2_features;
-    x86_cpu_def->ext3_features |= plus_ext3_features;
-    x86_cpu_def->kvm_features |= plus_kvm_features;
-    x86_cpu_def->svm_features |= plus_svm_features;
-    x86_cpu_def->features &= ~minus_features;
-    x86_cpu_def->ext_features &= ~minus_ext_features;
-    x86_cpu_def->ext2_features &= ~minus_ext2_features;
-    x86_cpu_def->ext3_features &= ~minus_ext3_features;
-    x86_cpu_def->kvm_features &= ~minus_kvm_features;
-    x86_cpu_def->svm_features &= ~minus_svm_features;
-    if (check_cpuid) {
-        if (check_features_against_host(x86_cpu_def) && enforce_cpuid)
-            goto error;
-    }
-    g_free(s);
-    return 0;
-
-error:
-    g_free(s);
-    return -1;
-}
-
-/* generate a composite string into buf of all cpuid names in featureset
- * selected by fbits.  indicate truncation at bufsize in the event of overflow.
- * if flags, suppress names undefined in featureset.
- */
-static void listflags(char *buf, int bufsize, uint32_t fbits,
-    const char **featureset, uint32_t flags)
-{
-    const char **p = &featureset[31];
-    char *q, *b, bit;
-    int nc;
-
-    b = 4 <= bufsize ? buf + (bufsize -= 3) - 1 : NULL;
-    *buf = '\0';
-    for (q = buf, bit = 31; fbits && bufsize; --p, fbits &= ~(1 << bit), --bit)
-        if (fbits & 1 << bit && (*p || !flags)) {
-            if (*p)
-                nc = snprintf(q, bufsize, "%s%s", q == buf ? "" : " ", *p);
-            else
-                nc = snprintf(q, bufsize, "%s[%d]", q == buf ? "" : " ", bit);
-            if (bufsize <= nc) {
-                if (b) {
-                    memcpy(b, "...", sizeof("..."));
-                }
-                return;
-            }
-            q += nc;
-            bufsize -= nc;
-        }
-}
-
-/* generate CPU information:
- * -?        list model names
- * -?model   list model names/IDs
- * -?dump    output all model (x86_def_t) data
- * -?cpuid   list all recognized cpuid flag names
- */
-void x86_cpu_list(FILE *f, fprintf_function cpu_fprintf, const char *optarg)
-{
-    unsigned char model = !strcmp("?model", optarg);
-    unsigned char dump = !strcmp("?dump", optarg);
-    unsigned char cpuid = !strcmp("?cpuid", optarg);
-    x86_def_t *def;
-    char buf[256];
-
-    if (cpuid) {
-        (*cpu_fprintf)(f, "Recognized CPUID flags:\n");
-        listflags(buf, sizeof (buf), (uint32_t)~0, feature_name, 1);
-        (*cpu_fprintf)(f, "  f_edx: %s\n", buf);
-        listflags(buf, sizeof (buf), (uint32_t)~0, ext_feature_name, 1);
-        (*cpu_fprintf)(f, "  f_ecx: %s\n", buf);
-        listflags(buf, sizeof (buf), (uint32_t)~0, ext2_feature_name, 1);
-        (*cpu_fprintf)(f, "  extf_edx: %s\n", buf);
-        listflags(buf, sizeof (buf), (uint32_t)~0, ext3_feature_name, 1);
-        (*cpu_fprintf)(f, "  extf_ecx: %s\n", buf);
-        return;
-    }
-    for (def = x86_defs; def; def = def->next) {
-        snprintf(buf, sizeof (buf), def->flags ? "[%s]": "%s", def->name);
-        if (model || dump) {
-            (*cpu_fprintf)(f, "x86 %16s  %-48s\n", buf, def->model_id);
-        } else {
-            (*cpu_fprintf)(f, "x86 %16s\n", buf);
-        }
-        if (dump) {
-            memcpy(buf, &def->vendor1, sizeof (def->vendor1));
-            memcpy(buf + 4, &def->vendor2, sizeof (def->vendor2));
-            memcpy(buf + 8, &def->vendor3, sizeof (def->vendor3));
-            buf[12] = '\0';
-            (*cpu_fprintf)(f,
-                "  family %d model %d stepping %d level %d xlevel 0x%x"
-                " vendor \"%s\"\n",
-                def->family, def->model, def->stepping, def->level,
-                def->xlevel, buf);
-            listflags(buf, sizeof (buf), def->features, feature_name, 0);
-            (*cpu_fprintf)(f, "  feature_edx %08x (%s)\n", def->features,
-                buf);
-            listflags(buf, sizeof (buf), def->ext_features, ext_feature_name,
-                0);
-            (*cpu_fprintf)(f, "  feature_ecx %08x (%s)\n", def->ext_features,
-                buf);
-            listflags(buf, sizeof (buf), def->ext2_features, ext2_feature_name,
-                0);
-            (*cpu_fprintf)(f, "  extfeature_edx %08x (%s)\n",
-                def->ext2_features, buf);
-            listflags(buf, sizeof (buf), def->ext3_features, ext3_feature_name,
-                0);
-            (*cpu_fprintf)(f, "  extfeature_ecx %08x (%s)\n",
-                def->ext3_features, buf);
-            (*cpu_fprintf)(f, "\n");
-        }
-    }
-    if (kvm_enabled()) {
-        (*cpu_fprintf)(f, "x86 %16s\n", "[host]");
-    }
-}
-
-int cpu_x86_register (CPUX86State *env, const char *cpu_model)
-{
-    x86_def_t def1, *def = &def1;
-
-    memset(def, 0, sizeof(*def));
-
-    if (cpu_x86_find_by_name(def, cpu_model) < 0)
-        return -1;
-    if (def->vendor1) {
-        env->cpuid_vendor1 = def->vendor1;
-        env->cpuid_vendor2 = def->vendor2;
-        env->cpuid_vendor3 = def->vendor3;
-    } else {
-        env->cpuid_vendor1 = CPUID_VENDOR_INTEL_1;
-        env->cpuid_vendor2 = CPUID_VENDOR_INTEL_2;
-        env->cpuid_vendor3 = CPUID_VENDOR_INTEL_3;
-    }
-    env->cpuid_vendor_override = def->vendor_override;
-    env->cpuid_level = def->level;
-    x86_cpuid_version_set_family(env, def->family);
-    x86_cpuid_version_set_model(env, def->model);
-    x86_cpuid_version_set_stepping(env, def->stepping);
-    env->cpuid_features = def->features;
-    env->cpuid_ext_features = def->ext_features;
-    env->cpuid_ext2_features = def->ext2_features;
-    env->cpuid_ext3_features = def->ext3_features;
-    env->cpuid_xlevel = def->xlevel;
-    env->cpuid_kvm_features = def->kvm_features;
-    env->cpuid_svm_features = def->svm_features;
-    env->cpuid_ext4_features = def->ext4_features;
-    env->cpuid_xlevel2 = def->xlevel2;
-    env->tsc_khz = def->tsc_khz;
-    if (!kvm_enabled()) {
-        env->cpuid_features &= TCG_FEATURES;
-        env->cpuid_ext_features &= TCG_EXT_FEATURES;
-        env->cpuid_ext2_features &= (TCG_EXT2_FEATURES
-#ifdef TARGET_X86_64
-            | CPUID_EXT2_SYSCALL | CPUID_EXT2_LM
-#endif
-            );
-        env->cpuid_ext3_features &= TCG_EXT3_FEATURES;
-        env->cpuid_svm_features &= TCG_SVM_FEATURES;
-    }
-    x86_cpuid_set_model_id(env, def->model_id);
-    return 0;
-}
-
-#if !defined(CONFIG_USER_ONLY)
-/* copy vendor id string to 32 bit register, nul pad as needed
- */
-static void cpyid(const char *s, uint32_t *id)
-{
-    char *d = (char *)id;
-    char i;
-
-    for (i = sizeof (*id); i--; )
-        *d++ = *s ? *s++ : '\0';
-}
-
-/* interpret radix and convert from string to arbitrary scalar,
- * otherwise flag failure
- */
-#define setscalar(pval, str, perr)                      \
-{                                                       \
-    char *pend;                                         \
-    unsigned long ul;                                   \
-                                                        \
-    ul = strtoul(str, &pend, 0);                        \
-    *str && !*pend ? (*pval = ul) : (*perr = 1);        \
-}
-
-/* map cpuid options to feature bits, otherwise return failure
- * (option tags in *str are delimited by whitespace)
- */
-static void setfeatures(uint32_t *pval, const char *str,
-    const char **featureset, int *perr)
-{
-    const char *p, *q;
-
-    for (q = p = str; *p || *q; q = p) {
-        while (iswhite(*p))
-            q = ++p;
-        while (*p && !iswhite(*p))
-            ++p;
-        if (!*q && !*p)
-            return;
-        if (!lookup_feature(pval, q, p, featureset)) {
-            fprintf(stderr, "error: feature \"%.*s\" not available in set\n",
-                (int)(p - q), q);
-            *perr = 1;
-            return;
-        }
-    }
-}
-
-/* map config file options to x86_def_t form
- */
-static int cpudef_setfield(const char *name, const char *str, void *opaque)
-{
-    x86_def_t *def = opaque;
-    int err = 0;
-
-    if (!strcmp(name, "name")) {
-        g_free((void *)def->name);
-        def->name = g_strdup(str);
-    } else if (!strcmp(name, "model_id")) {
-        strncpy(def->model_id, str, sizeof (def->model_id));
-    } else if (!strcmp(name, "level")) {
-        setscalar(&def->level, str, &err)
-    } else if (!strcmp(name, "vendor")) {
-        cpyid(&str[0], &def->vendor1);
-        cpyid(&str[4], &def->vendor2);
-        cpyid(&str[8], &def->vendor3);
-    } else if (!strcmp(name, "family")) {
-        setscalar(&def->family, str, &err)
-    } else if (!strcmp(name, "model")) {
-        setscalar(&def->model, str, &err)
-    } else if (!strcmp(name, "stepping")) {
-        setscalar(&def->stepping, str, &err)
-    } else if (!strcmp(name, "feature_edx")) {
-        setfeatures(&def->features, str, feature_name, &err);
-    } else if (!strcmp(name, "feature_ecx")) {
-        setfeatures(&def->ext_features, str, ext_feature_name, &err);
-    } else if (!strcmp(name, "extfeature_edx")) {
-        setfeatures(&def->ext2_features, str, ext2_feature_name, &err);
-    } else if (!strcmp(name, "extfeature_ecx")) {
-        setfeatures(&def->ext3_features, str, ext3_feature_name, &err);
-    } else if (!strcmp(name, "xlevel")) {
-        setscalar(&def->xlevel, str, &err)
-    } else {
-        fprintf(stderr, "error: unknown option [%s = %s]\n", name, str);
-        return (1);
-    }
-    if (err) {
-        fprintf(stderr, "error: bad option value [%s = %s]\n", name, str);
-        return (1);
-    }
-    return (0);
-}
-
-/* register config file entry as x86_def_t
- */
-static int cpudef_register(QemuOpts *opts, void *opaque)
-{
-    x86_def_t *def = g_malloc0(sizeof (x86_def_t));
-
-    qemu_opt_foreach(opts, cpudef_setfield, def, 1);
-    def->next = x86_defs;
-    x86_defs = def;
-    return (0);
-}
-
-void cpu_clear_apic_feature(CPUX86State *env)
-{
-    env->cpuid_features &= ~CPUID_APIC;
-}
-
-#endif /* !CONFIG_USER_ONLY */
-
-/* register "cpudef" models defined in configuration file.  Here we first
- * preload any built-in definitions
- */
-void x86_cpudef_setup(void)
-{
-    int i;
-
-    for (i = 0; i < ARRAY_SIZE(builtin_x86_defs); ++i) {
-        builtin_x86_defs[i].next = x86_defs;
-        builtin_x86_defs[i].flags = 1;
-        x86_defs = &builtin_x86_defs[i];
-    }
-#if !defined(CONFIG_USER_ONLY)
-    qemu_opts_foreach(qemu_find_opts("cpudef"), cpudef_register, NULL, 0);
-#endif
-}
-
-static void get_cpuid_vendor(CPUX86State *env, uint32_t *ebx,
-                             uint32_t *ecx, uint32_t *edx)
-{
-    *ebx = env->cpuid_vendor1;
-    *edx = env->cpuid_vendor2;
-    *ecx = env->cpuid_vendor3;
-
-    /* sysenter isn't supported on compatibility mode on AMD, syscall
-     * isn't supported in compatibility mode on Intel.
-     * Normally we advertise the actual cpu vendor, but you can override
-     * this if you want to use KVM's sysenter/syscall emulation
-     * in compatibility mode and when doing cross vendor migration
-     */
-    if (kvm_enabled() && ! env->cpuid_vendor_override) {
-        host_cpuid(0, 0, NULL, ebx, ecx, edx);
-    }
-}
-
-void cpu_x86_cpuid(CPUX86State *env, uint32_t index, uint32_t count,
-                   uint32_t *eax, uint32_t *ebx,
-                   uint32_t *ecx, uint32_t *edx)
-{
-    /* test if maximum index reached */
-    if (index & 0x80000000) {
-        if (index > env->cpuid_xlevel) {
-            if (env->cpuid_xlevel2 > 0) {
-                /* Handle the Centaur's CPUID instruction. */
-                if (index > env->cpuid_xlevel2) {
-                    index = env->cpuid_xlevel2;
-                } else if (index < 0xC0000000) {
-                    index = env->cpuid_xlevel;
-                }
-            } else {
-                index =  env->cpuid_xlevel;
-            }
-        }
-    } else {
-        if (index > env->cpuid_level)
-            index = env->cpuid_level;
-    }
-
-    switch(index) {
-    case 0:
-        *eax = env->cpuid_level;
-        get_cpuid_vendor(env, ebx, ecx, edx);
-        break;
-    case 1:
-        *eax = env->cpuid_version;
-        *ebx = (env->cpuid_apic_id << 24) | 8 << 8; /* CLFLUSH size in quad words, Linux wants it. */
-        *ecx = env->cpuid_ext_features;
-        *edx = env->cpuid_features;
-        if (env->nr_cores * env->nr_threads > 1) {
-            *ebx |= (env->nr_cores * env->nr_threads) << 16;
-            *edx |= 1 << 28;    /* HTT bit */
-        }
-        break;
-    case 2:
-        /* cache info: needed for Pentium Pro compatibility */
-        *eax = 1;
-        *ebx = 0;
-        *ecx = 0;
-        *edx = 0x2c307d;
-        break;
-    case 4:
-        /* cache info: needed for Core compatibility */
-        if (env->nr_cores > 1) {
-            *eax = (env->nr_cores - 1) << 26;
-        } else {
-            *eax = 0;
-        }
-        switch (count) {
-            case 0: /* L1 dcache info */
-                *eax |= 0x0000121;
-                *ebx = 0x1c0003f;
-                *ecx = 0x000003f;
-                *edx = 0x0000001;
-                break;
-            case 1: /* L1 icache info */
-                *eax |= 0x0000122;
-                *ebx = 0x1c0003f;
-                *ecx = 0x000003f;
-                *edx = 0x0000001;
-                break;
-            case 2: /* L2 cache info */
-                *eax |= 0x0000143;
-                if (env->nr_threads > 1) {
-                    *eax |= (env->nr_threads - 1) << 14;
-                }
-                *ebx = 0x3c0003f;
-                *ecx = 0x0000fff;
-                *edx = 0x0000001;
-                break;
-            default: /* end of info */
-                *eax = 0;
-                *ebx = 0;
-                *ecx = 0;
-                *edx = 0;
-                break;
-        }
-        break;
-    case 5:
-        /* mwait info: needed for Core compatibility */
-        *eax = 0; /* Smallest monitor-line size in bytes */
-        *ebx = 0; /* Largest monitor-line size in bytes */
-        *ecx = CPUID_MWAIT_EMX | CPUID_MWAIT_IBE;
-        *edx = 0;
-        break;
-    case 6:
-        /* Thermal and Power Leaf */
-        *eax = 0;
-        *ebx = 0;
-        *ecx = 0;
-        *edx = 0;
-        break;
-    case 7:
-        if (kvm_enabled()) {
-            KVMState *s = env->kvm_state;
-
-            *eax = kvm_arch_get_supported_cpuid(s, 0x7, count, R_EAX);
-            *ebx = kvm_arch_get_supported_cpuid(s, 0x7, count, R_EBX);
-            *ecx = kvm_arch_get_supported_cpuid(s, 0x7, count, R_ECX);
-            *edx = kvm_arch_get_supported_cpuid(s, 0x7, count, R_EDX);
-        } else {
-            *eax = 0;
-            *ebx = 0;
-            *ecx = 0;
-            *edx = 0;
-        }
-        break;
-    case 9:
-        /* Direct Cache Access Information Leaf */
-        *eax = 0; /* Bits 0-31 in DCA_CAP MSR */
-        *ebx = 0;
-        *ecx = 0;
-        *edx = 0;
-        break;
-    case 0xA:
-        /* Architectural Performance Monitoring Leaf */
-        if (kvm_enabled()) {
-            KVMState *s = env->kvm_state;
-
-            *eax = kvm_arch_get_supported_cpuid(s, 0xA, count, R_EAX);
-            *ebx = kvm_arch_get_supported_cpuid(s, 0xA, count, R_EBX);
-            *ecx = kvm_arch_get_supported_cpuid(s, 0xA, count, R_ECX);
-            *edx = kvm_arch_get_supported_cpuid(s, 0xA, count, R_EDX);
-        } else {
-            *eax = 0;
-            *ebx = 0;
-            *ecx = 0;
-            *edx = 0;
-        }
-        break;
-    case 0xD:
-        /* Processor Extended State */
-        if (!(env->cpuid_ext_features & CPUID_EXT_XSAVE)) {
-            *eax = 0;
-            *ebx = 0;
-            *ecx = 0;
-            *edx = 0;
-            break;
-        }
-        if (kvm_enabled()) {
-            KVMState *s = env->kvm_state;
-
-            *eax = kvm_arch_get_supported_cpuid(s, 0xd, count, R_EAX);
-            *ebx = kvm_arch_get_supported_cpuid(s, 0xd, count, R_EBX);
-            *ecx = kvm_arch_get_supported_cpuid(s, 0xd, count, R_ECX);
-            *edx = kvm_arch_get_supported_cpuid(s, 0xd, count, R_EDX);
-        } else {
-            *eax = 0;
-            *ebx = 0;
-            *ecx = 0;
-            *edx = 0;
-        }
-        break;
-    case 0x80000000:
-        *eax = env->cpuid_xlevel;
-        *ebx = env->cpuid_vendor1;
-        *edx = env->cpuid_vendor2;
-        *ecx = env->cpuid_vendor3;
-        break;
-    case 0x80000001:
-        *eax = env->cpuid_version;
-        *ebx = 0;
-        *ecx = env->cpuid_ext3_features;
-        *edx = env->cpuid_ext2_features;
-
-        /* The Linux kernel checks for the CMPLegacy bit and
-         * discards multiple thread information if it is set.
-         * So dont set it here for Intel to make Linux guests happy.
-         */
-        if (env->nr_cores * env->nr_threads > 1) {
-            uint32_t tebx, tecx, tedx;
-            get_cpuid_vendor(env, &tebx, &tecx, &tedx);
-            if (tebx != CPUID_VENDOR_INTEL_1 ||
-                tedx != CPUID_VENDOR_INTEL_2 ||
-                tecx != CPUID_VENDOR_INTEL_3) {
-                *ecx |= 1 << 1;    /* CmpLegacy bit */
-            }
-        }
-        break;
-    case 0x80000002:
-    case 0x80000003:
-    case 0x80000004:
-        *eax = env->cpuid_model[(index - 0x80000002) * 4 + 0];
-        *ebx = env->cpuid_model[(index - 0x80000002) * 4 + 1];
-        *ecx = env->cpuid_model[(index - 0x80000002) * 4 + 2];
-        *edx = env->cpuid_model[(index - 0x80000002) * 4 + 3];
-        break;
-    case 0x80000005:
-        /* cache info (L1 cache) */
-        *eax = 0x01ff01ff;
-        *ebx = 0x01ff01ff;
-        *ecx = 0x40020140;
-        *edx = 0x40020140;
-        break;
-    case 0x80000006:
-        /* cache info (L2 cache) */
-        *eax = 0;
-        *ebx = 0x42004200;
-        *ecx = 0x02008140;
-        *edx = 0;
-        break;
-    case 0x80000008:
-        /* virtual & phys address size in low 2 bytes. */
-/* XXX: This value must match the one used in the MMU code. */
-        if (env->cpuid_ext2_features & CPUID_EXT2_LM) {
-            /* 64 bit processor */
-/* XXX: The physical address space is limited to 42 bits in exec.c. */
-            *eax = 0x00003028;	/* 48 bits virtual, 40 bits physical */
-        } else {
-            if (env->cpuid_features & CPUID_PSE36)
-                *eax = 0x00000024; /* 36 bits physical */
-            else
-                *eax = 0x00000020; /* 32 bits physical */
-        }
-        *ebx = 0;
-        *ecx = 0;
-        *edx = 0;
-        if (env->nr_cores * env->nr_threads > 1) {
-            *ecx |= (env->nr_cores * env->nr_threads) - 1;
-        }
-        break;
-    case 0x8000000A:
-	if (env->cpuid_ext3_features & CPUID_EXT3_SVM) {
-		*eax = 0x00000001; /* SVM Revision */
-		*ebx = 0x00000010; /* nr of ASIDs */
-		*ecx = 0;
-		*edx = env->cpuid_svm_features; /* optional features */
-	} else {
-		*eax = 0;
-		*ebx = 0;
-		*ecx = 0;
-		*edx = 0;
-	}
-        break;
-    case 0xC0000000:
-        *eax = env->cpuid_xlevel2;
-        *ebx = 0;
-        *ecx = 0;
-        *edx = 0;
-        break;
-    case 0xC0000001:
-        /* Support for VIA CPU's CPUID instruction */
-        *eax = env->cpuid_version;
-        *ebx = 0;
-        *ecx = 0;
-        *edx = env->cpuid_ext4_features;
-        break;
-    case 0xC0000002:
-    case 0xC0000003:
-    case 0xC0000004:
-        /* Reserved for the future, and now filled with zero */
-        *eax = 0;
-        *ebx = 0;
-        *ecx = 0;
-        *edx = 0;
-        break;
-    default:
-        /* reserved values: zero */
-        *eax = 0;
-        *ebx = 0;
-        *ecx = 0;
-        *edx = 0;
-        break;
-    }
-}
commit 4e1957acc854b2f3f3068c75cef2a429f9b97011
Merge: 6da25bd... ff71f2e...
Author: Anthony Liguori <aliguori at us.ibm.com>
Date:   Tue Apr 10 08:21:58 2012 -0500

    Merge commit 'ff71f2e8cacefae99179993204172bc65e4303df' into staging
    
    * commit 'ff71f2e8cacefae99179993204172bc65e4303df': (21 commits)
      rtl8139: do the network/host communication only in normal operating mode
      rtl8139: correctly check the opmode
      net: move compute_mcast_idx() to net.h
      rtl8139: support byte read to TxStatus registers
      rtl8139: remove unused marco
      rtl8139: limit transmission buffer size in c+ mode
      pci_regs: Add PCI_EXP_TYPE_PCIE_BRIDGE
      virtio-net: add DATA_VALID flag
      pci_bridge: upper 32 bit are long registers
      pci: fix bridge IO/BASE
      pcie: drop functionality moved to core
      pci: set memory type for memory behind the bridge
      pci: add standard bridge device
      slotid: add slot id capability
      shpc: standard hot plug controller
      pci_bridge: user-friendly default bus name
      pci: make another unused extern function static
      pci: don't export an internal function
      pci_regs: Fix value of PCI_EXP_TYPE_RC_EC.
      pci: Do not check if a bus exist in pci_parse_devaddr.
      ...

commit 6da25bd5e8355230b9562417e386728c31783002
Merge: bb5d8dd... a15fef2...
Author: Anthony Liguori <aliguori at us.ibm.com>
Date:   Tue Apr 10 08:17:36 2012 -0500

    Merge remote-tracking branch 'qmp/queue/qmp' into staging
    
    * qmp/queue/qmp:
      qapi: convert device_del
      qdev: qdev_unplug(): use error_set()

commit bb5d8dd757eaa8f9a048c5205c69bed20ea373d1
Merge: 72fe3aa... 50d30c2...
Author: Anthony Liguori <aliguori at us.ibm.com>
Date:   Tue Apr 10 08:16:12 2012 -0500

    Merge remote-tracking branch 'kwolf/for-anthony' into staging
    
    * kwolf/for-anthony: (46 commits)
      qed: remove incoming live migration blocker
      qed: honor BDRV_O_INCOMING for incoming live migration
      migration: clear BDRV_O_INCOMING flags on end of incoming live migration
      qed: add bdrv_invalidate_cache to be called after incoming live migration
      blockdev: open images with BDRV_O_INCOMING on incoming live migration
      block: add a function to clear incoming live migration flags
      block: Add new BDRV_O_INCOMING flag to notice incoming live migration
      block stream: close unused files and update ->backing_hd
      qemu-iotests: Fix call syntax for qemu-io
      qemu-iotests: Fix call syntax for qemu-img
      qemu-iotests: Test unknown qcow2 header extensions
      qemu-iotests: qcow2.py
      sheepdog: fix send req helpers
      sheepdog: implement SD_OP_FLUSH_VDI operation
      block: bdrv_append() fixes
      qed: track dirty flag status
      qemu-img: add dirty flag status
      qed: image fragmentation statistics
      qemu-img: add image fragmentation statistics
      block: document job API
      ...

commit 72fe3aaed94936739abfa158fa28f147b75ae9ff
Merge: 2c097f6... 53fbf7b...
Author: Anthony Liguori <aliguori at us.ibm.com>
Date:   Tue Apr 10 08:10:41 2012 -0500

    Merge remote-tracking branch 'stefanha/trivial-patches' into staging
    
    * stefanha/trivial-patches:
      make: fix clean rule by removing build file in qom/
      configure: Link qga against UST tracing related libraries
      configure: Link QEMU against 'liburcu-bp'
      main-loop: make qemu_event_handle static
      block/curl: Replace usleep by g_usleep
      qtest: Add missing GCC_FMT_ATTR
      w32: Undefine error constants before their redefinition
      configure: fix mingw32 libs_qga typo

commit 2c097f6003f2a11416706ae3252c2860ed2257a9
Author: Peter A. G. Crosthwaite <peter.crosthwaite at petalogix.com>
Date:   Tue Apr 10 14:05:52 2012 +1000

    petalogix_s3adsp1800: deleted bad FIXME comment
    
    This FIXME has already been actioned. Deleted comment.
    
    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/petalogix_s3adsp1800_mmu.c b/hw/petalogix_s3adsp1800_mmu.c
index ff154c7..8b37336 100644
--- a/hw/petalogix_s3adsp1800_mmu.c
+++ b/hw/petalogix_s3adsp1800_mmu.c
@@ -51,7 +51,6 @@
 
 static void machine_cpu_reset(CPUMBState *env)
 {
-    /* FIXME: move to machine specfic cpu reset */
     env->pvr.regs[10] = 0x0c000000; /* spartan 3a dsp family.  */
 }
 
commit a15fef21c746e3aa0a94cf7b5bd9799886236666
Author: Luiz Capitulino <lcapitulino at redhat.com>
Date:   Thu Mar 29 12:38:50 2012 -0300

    qapi: convert device_del
    
    Signed-off-by: Anthony Liguori <aliguori at us.ibm.com>
    Signed-off-by: Luiz Capitulino <lcapitulino at redhat.com>
    Reviewed-by: Stefan Hajnoczi <stefanha at linux.vnet.ibm.com>

diff --git a/hmp-commands.hx b/hmp-commands.hx
index bd35a3e..a6f5a84 100644
--- a/hmp-commands.hx
+++ b/hmp-commands.hx
@@ -622,8 +622,7 @@ ETEXI
         .args_type  = "id:s",
         .params     = "device",
         .help       = "remove device",
-        .user_print = monitor_user_noop,
-        .mhandler.cmd_new = do_device_del,
+        .mhandler.cmd = hmp_device_del,
     },
 
 STEXI
diff --git a/hmp.c b/hmp.c
index 9cf2d13..f3e5163 100644
--- a/hmp.c
+++ b/hmp.c
@@ -934,3 +934,12 @@ void hmp_migrate(Monitor *mon, const QDict *qdict)
         qemu_mod_timer(status->timer, qemu_get_clock_ms(rt_clock));
     }
 }
+
+void hmp_device_del(Monitor *mon, const QDict *qdict)
+{
+    const char *id = qdict_get_str(qdict, "id");
+    Error *err = NULL;
+
+    qmp_device_del(id, &err);
+    hmp_handle_error(mon, &err);
+}
diff --git a/hmp.h b/hmp.h
index 8807853..443b812 100644
--- a/hmp.h
+++ b/hmp.h
@@ -60,5 +60,6 @@ void hmp_block_stream(Monitor *mon, const QDict *qdict);
 void hmp_block_job_set_speed(Monitor *mon, const QDict *qdict);
 void hmp_block_job_cancel(Monitor *mon, const QDict *qdict);
 void hmp_migrate(Monitor *mon, const QDict *qdict);
+void hmp_device_del(Monitor *mon, const QDict *qdict);
 
 #endif
diff --git a/hw/qdev-monitor.c b/hw/qdev-monitor.c
index fd56afe..81d6548 100644
--- a/hw/qdev-monitor.c
+++ b/hw/qdev-monitor.c
@@ -19,6 +19,7 @@
 
 #include "qdev.h"
 #include "monitor.h"
+#include "qmp-commands.h"
 
 /*
  * Aliases were a bad idea from the start.  Let's keep them
@@ -570,26 +571,17 @@ int do_device_add(Monitor *mon, const QDict *qdict, QObject **ret_data)
     return 0;
 }
 
-int do_device_del(Monitor *mon, const QDict *qdict, QObject **ret_data)
+void qmp_device_del(const char *id, Error **errp)
 {
-    const char *id = qdict_get_str(qdict, "id");
-    Error *local_err = NULL;
     DeviceState *dev;
 
     dev = qdev_find_recursive(sysbus_get_default(), id);
     if (NULL == dev) {
-        qerror_report(QERR_DEVICE_NOT_FOUND, id);
-        return -1;
-    }
-
-    qdev_unplug(dev, &local_err);
-    if (error_is_set(&local_err)) {
-        qerror_report_err(local_err);
-        error_free(local_err);
-        return -1;
+        error_set(errp, QERR_DEVICE_NOT_FOUND, id);
+        return;
     }
 
-    return 0;
+    qdev_unplug(dev, errp);
 }
 
 void qdev_machine_init(void)
diff --git a/qapi-schema.json b/qapi-schema.json
index 0d11d6e..ace55f3 100644
--- a/qapi-schema.json
+++ b/qapi-schema.json
@@ -1701,3 +1701,23 @@
 # Since: 1.1
 ##
 { 'command': 'xen-save-devices-state', 'data': {'filename': 'str'} }
+
+##
+# @device_del:
+#
+# Remove a device from a guest
+#
+# @id: the name of the device
+#
+# Returns: Nothing on success
+#          If @id is not a valid device, DeviceNotFound
+#          If the device does not support unplug, BusNoHotplug
+#
+# Notes: When this command completes, the device may not be removed from the
+#        guest.  Hot removal is an operation that requires guest cooperation.
+#        This command merely requests that the guest begin the hot removal
+#        process.
+#
+# Since: 0.14.0
+##
+{ 'command': 'device_del', 'data': {'id': 'str'} }
diff --git a/qmp-commands.hx b/qmp-commands.hx
index 9447871..c09ee85 100644
--- a/qmp-commands.hx
+++ b/qmp-commands.hx
@@ -314,10 +314,7 @@ EQMP
     {
         .name       = "device_del",
         .args_type  = "id:s",
-        .params     = "device",
-        .help       = "remove device",
-        .user_print = monitor_user_noop,
-        .mhandler.cmd_new = do_device_del,
+        .mhandler.cmd_new = qmp_marshal_input_device_del,
     },
 
 SQMP
commit 56f9107e439c32aa00d58d117a9b664551328f1e
Author: Luiz Capitulino <lcapitulino at redhat.com>
Date:   Wed Mar 14 17:37:38 2012 -0300

    qdev: qdev_unplug(): use error_set()
    
    It currently uses qerror_report(), but next commit will convert
    the drive_del command to the QAPI and this requires using
    error_set().
    
    One particularity of qerror_report() is that it knows when it's
    running on monitor context or command-line context and prints the
    error message accordingly. error_set() doesn't do this, so we
    have to be careful not to drop error messages.
    
    qdev_unplug() has three kinds of usages:
    
     1. It's called when hot adding a device fails, to undo anything
        that has been done before hitting the error
    
     2. It's called by function monitor functions like device_del(),
        to unplug a device
    
     3. It's used by xen_platform.c in a way that doesn't _seem_ to
        be in monitor context
    
    Only item 2 can print an error message to the user, this commit
    maintains that.
    
    Signed-off-by: Luiz Capitulino <lcapitulino at redhat.com>
    Reviewed-by: Stefan Hajnoczi <stefanha at linux.vnet.ibm.com>

diff --git a/hw/pci-hotplug.c b/hw/pci-hotplug.c
index 5c6307f..c55d8b9 100644
--- a/hw/pci-hotplug.c
+++ b/hw/pci-hotplug.c
@@ -32,6 +32,7 @@
 #include "virtio-blk.h"
 #include "qemu-config.h"
 #include "blockdev.h"
+#include "error.h"
 
 #if defined(TARGET_I386)
 static PCIDevice *qemu_pci_hot_add_nic(Monitor *mon,
@@ -191,7 +192,7 @@ static PCIDevice *qemu_pci_hot_add_storage(Monitor *mon,
             dev = NULL;
         if (dev && dinfo) {
             if (scsi_hot_add(mon, &dev->qdev, dinfo, 0) != 0) {
-                qdev_unplug(&dev->qdev);
+                qdev_unplug(&dev->qdev, NULL);
                 dev = NULL;
             }
         }
@@ -258,6 +259,7 @@ static int pci_device_hot_remove(Monitor *mon, const char *pci_addr)
     PCIDevice *d;
     int dom, bus;
     unsigned slot;
+    Error *local_err = NULL;
 
     if (pci_read_devaddr(mon, pci_addr, &dom, &bus, &slot)) {
         return -1;
@@ -268,7 +270,15 @@ static int pci_device_hot_remove(Monitor *mon, const char *pci_addr)
         monitor_printf(mon, "slot %d empty\n", slot);
         return -1;
     }
-    return qdev_unplug(&d->qdev);
+
+    qdev_unplug(&d->qdev, &local_err);
+    if (error_is_set(&local_err)) {
+        monitor_printf(mon, "%s\n", error_get_pretty(local_err));
+        error_free(local_err);
+        return -1;
+    }
+
+    return 0;
 }
 
 void do_pci_device_hot_remove(Monitor *mon, const QDict *qdict)
diff --git a/hw/qdev-monitor.c b/hw/qdev-monitor.c
index 4783366..fd56afe 100644
--- a/hw/qdev-monitor.c
+++ b/hw/qdev-monitor.c
@@ -573,6 +573,7 @@ int do_device_add(Monitor *mon, const QDict *qdict, QObject **ret_data)
 int do_device_del(Monitor *mon, const QDict *qdict, QObject **ret_data)
 {
     const char *id = qdict_get_str(qdict, "id");
+    Error *local_err = NULL;
     DeviceState *dev;
 
     dev = qdev_find_recursive(sysbus_get_default(), id);
@@ -580,7 +581,15 @@ int do_device_del(Monitor *mon, const QDict *qdict, QObject **ret_data)
         qerror_report(QERR_DEVICE_NOT_FOUND, id);
         return -1;
     }
-    return qdev_unplug(dev);
+
+    qdev_unplug(dev, &local_err);
+    if (error_is_set(&local_err)) {
+        qerror_report_err(local_err);
+        error_free(local_err);
+        return -1;
+    }
+
+    return 0;
 }
 
 void qdev_machine_init(void)
diff --git a/hw/qdev.c b/hw/qdev.c
index 0d3c0fc..afbc975 100644
--- a/hw/qdev.c
+++ b/hw/qdev.c
@@ -28,6 +28,7 @@
 #include "net.h"
 #include "qdev.h"
 #include "sysemu.h"
+#include "error.h"
 
 int qdev_hotplug = 0;
 static bool qdev_hot_added = false;
@@ -182,19 +183,22 @@ void qdev_set_legacy_instance_id(DeviceState *dev, int alias_id,
     dev->alias_required_for_version = required_for_version;
 }
 
-int qdev_unplug(DeviceState *dev)
+void qdev_unplug(DeviceState *dev, Error **errp)
 {
     DeviceClass *dc = DEVICE_GET_CLASS(dev);
 
     if (!dev->parent_bus->allow_hotplug) {
-        qerror_report(QERR_BUS_NO_HOTPLUG, dev->parent_bus->name);
-        return -1;
+        error_set(errp, QERR_BUS_NO_HOTPLUG, dev->parent_bus->name);
+        return;
     }
     assert(dc->unplug != NULL);
 
     qdev_hot_removed = true;
 
-    return dc->unplug(dev);
+    if (dc->unplug(dev) < 0) {
+        error_set(errp, QERR_UNDEFINED_ERROR);
+        return;
+    }
 }
 
 static int qdev_reset_one(DeviceState *dev, void *opaque)
diff --git a/hw/qdev.h b/hw/qdev.h
index a8df42f..7cafa8c 100644
--- a/hw/qdev.h
+++ b/hw/qdev.h
@@ -7,6 +7,7 @@
 #include "qemu-option.h"
 #include "qapi/qapi-visit-core.h"
 #include "qemu/object.h"
+#include "error.h"
 
 typedef struct Property Property;
 
@@ -148,7 +149,7 @@ int qdev_init(DeviceState *dev) QEMU_WARN_UNUSED_RESULT;
 void qdev_init_nofail(DeviceState *dev);
 void qdev_set_legacy_instance_id(DeviceState *dev, int alias_id,
                                  int required_for_version);
-int qdev_unplug(DeviceState *dev);
+void qdev_unplug(DeviceState *dev, Error **errp);
 void qdev_free(DeviceState *dev);
 int qdev_simple_unplug_cb(DeviceState *dev);
 void qdev_machine_creation_done(void);
diff --git a/hw/usb/dev-storage.c b/hw/usb/dev-storage.c
index bdbe7bd..d865a5e 100644
--- a/hw/usb/dev-storage.c
+++ b/hw/usb/dev-storage.c
@@ -499,7 +499,7 @@ static void usb_msd_password_cb(void *opaque, int err)
         err = usb_device_attach(&s->dev);
 
     if (err)
-        qdev_unplug(&s->dev.qdev);
+        qdev_unplug(&s->dev.qdev, NULL);
 }
 
 static const struct SCSIBusInfo usb_msd_scsi_info = {
diff --git a/hw/xen_platform.c b/hw/xen_platform.c
index 5a7c4cc..a9c52a6 100644
--- a/hw/xen_platform.c
+++ b/hw/xen_platform.c
@@ -87,7 +87,7 @@ static void unplug_nic(PCIBus *b, PCIDevice *d)
 {
     if (pci_get_word(d->config + PCI_CLASS_DEVICE) ==
             PCI_CLASS_NETWORK_ETHERNET) {
-        qdev_unplug(&(d->qdev));
+        qdev_unplug(&(d->qdev), NULL);
     }
 }
 
@@ -100,7 +100,7 @@ static void unplug_disks(PCIBus *b, PCIDevice *d)
 {
     if (pci_get_word(d->config + PCI_CLASS_DEVICE) ==
             PCI_CLASS_STORAGE_IDE) {
-        qdev_unplug(&(d->qdev));
+        qdev_unplug(&(d->qdev), NULL);
     }
 }
 
commit 7914cb3c738a03a5d5f7cb32c3768bc62eb1e944
Merge: 4266717... 221b3a3...
Author: Blue Swirl <blauwirbel at gmail.com>
Date:   Sun Apr 8 18:00:42 2012 +0000

    Merge branch 'memory/core' of git://git.kernel.org/pub/scm/virt/kvm/qemu-kvm
    
    * 'memory/core' of git://git.kernel.org/pub/scm/virt/kvm/qemu-kvm:
      memory: check address space when a listener is registered
      memory: print aliased IO ranges in info mtree
      ioport: use INT64_MAX for IO ranges

commit 4266717d690987993d52f5e4745064f4dbb29824
Author: Stefan Weil <sw at weilnetz.de>
Date:   Sat Apr 7 17:58:34 2012 +0200

    Add QEMU_NORETURN to function cpu_io_recompile
    
    cpu_io_recompile terminates by calling either cpu_abort or
    cpu_resume_from_signal which both never return.
    
    Signed-off-by: Stefan Weil <sw at weilnetz.de>
    Signed-off-by: Blue Swirl <blauwirbel at gmail.com>

diff --git a/exec-all.h b/exec-all.h
index 4758d88..fa7bdfe 100644
--- a/exec-all.h
+++ b/exec-all.h
@@ -87,7 +87,7 @@ int cpu_gen_code(CPUArchState *env, struct TranslationBlock *tb,
 int cpu_restore_state(struct TranslationBlock *tb,
                       CPUArchState *env, uintptr_t searched_pc);
 void QEMU_NORETURN cpu_resume_from_signal(CPUArchState *env1, void *puc);
-void cpu_io_recompile(CPUArchState *env, void *retaddr);
+void QEMU_NORETURN cpu_io_recompile(CPUArchState *env, void *retaddr);
 TranslationBlock *tb_gen_code(CPUArchState *env, 
                               target_ulong pc, target_ulong cs_base, int flags,
                               int cflags);
commit 38c30fb7a534da82371311ca7a56f2141008b2a5
Author: Stefan Weil <sw at weilnetz.de>
Date:   Sat Apr 7 17:58:33 2012 +0200

    Add QEMU_NORETURN to function cpu_resume_from_signal
    
    cpu_resume_from_signal terminates by calling longjmp.
    
    Signed-off-by: Stefan Weil <sw at weilnetz.de>
    Signed-off-by: Blue Swirl <blauwirbel at gmail.com>

diff --git a/exec-all.h b/exec-all.h
index a6d6519..4758d88 100644
--- a/exec-all.h
+++ b/exec-all.h
@@ -86,7 +86,7 @@ int cpu_gen_code(CPUArchState *env, struct TranslationBlock *tb,
                  int *gen_code_size_ptr);
 int cpu_restore_state(struct TranslationBlock *tb,
                       CPUArchState *env, uintptr_t searched_pc);
-void cpu_resume_from_signal(CPUArchState *env1, void *puc);
+void QEMU_NORETURN cpu_resume_from_signal(CPUArchState *env1, void *puc);
 void cpu_io_recompile(CPUArchState *env, void *retaddr);
 TranslationBlock *tb_gen_code(CPUArchState *env, 
                               target_ulong pc, target_ulong cs_base, int flags,
commit 5cbdb3a34bce4ee64dd203cfd74979409fa3d51e
Author: Stefan Weil <sw at weilnetz.de>
Date:   Sat Apr 7 09:23:39 2012 +0200

    Replace Qemu by QEMU in comments
    
    The official spelling is QEMU.
    
    Signed-off-by: Stefan Weil <sw at weilnetz.de>
    Reviewed-by: Andreas Färber <afaerber at suse.de>
    [blauwirbel at gmail.com: fixed comment style in hw/sun4m.c]
    Signed-off-by: Blue Swirl <blauwirbel at gmail.com>

diff --git a/hw/ivshmem.c b/hw/ivshmem.c
index 64e1cd9..b80aa8f 100644
--- a/hw/ivshmem.c
+++ b/hw/ivshmem.c
@@ -565,7 +565,7 @@ static void ivshmem_setup_msi(IVShmemState * s) {
         msix_vector_use(&s->dev, i);
     }
 
-    /* allocate Qemu char devices for receiving interrupts */
+    /* allocate QEMU char devices for receiving interrupts */
     s->eventfd_table = g_malloc0(s->vectors * sizeof(EventfdEntry));
 }
 
diff --git a/hw/pc.c b/hw/pc.c
index 83a1b5b..67f0479 100644
--- a/hw/pc.c
+++ b/hw/pc.c
@@ -776,7 +776,7 @@ static void load_linux(void *fw_cfg,
     }
 
     /* loader type */
-    /* High nybble = B reserved for Qemu; low nybble is revision number.
+    /* High nybble = B reserved for QEMU; low nybble is revision number.
        If this code is substantially changed, you may want to consider
        incrementing the revision. */
     if (protocol >= 0x200)
diff --git a/hw/ppc440_bamboo.c b/hw/ppc440_bamboo.c
index 220c81d..f0a3ae4 100644
--- a/hw/ppc440_bamboo.c
+++ b/hw/ppc440_bamboo.c
@@ -1,5 +1,5 @@
 /*
- * Qemu PowerPC 440 Bamboo board emulation
+ * QEMU PowerPC 440 Bamboo board emulation
  *
  * Copyright 2007 IBM Corporation.
  * Authors:
diff --git a/hw/ppce500_mpc8544ds.c b/hw/ppce500_mpc8544ds.c
index 5ee8cb3..f1dfbe1 100644
--- a/hw/ppce500_mpc8544ds.c
+++ b/hw/ppce500_mpc8544ds.c
@@ -1,5 +1,5 @@
 /*
- * Qemu PowerPC MPC8544DS board emualtion
+ * QEMU PowerPC MPC8544DS board emulation
  *
  * Copyright (C) 2009 Freescale Semiconductor, Inc. All rights reserved.
  *
diff --git a/hw/ps2.c b/hw/ps2.c
index b1a67bc..f93cd24 100644
--- a/hw/ps2.c
+++ b/hw/ps2.c
@@ -88,7 +88,7 @@ typedef struct {
 typedef struct {
     PS2State common;
     int scan_enabled;
-    /* Qemu uses translated PC scancodes internally.  To avoid multiple
+    /* QEMU uses translated PC scancodes internally.  To avoid multiple
        conversions we do the translation (if any) in the PS/2 emulation
        not the keyboard controller.  */
     int translate;
diff --git a/hw/sun4m.c b/hw/sun4m.c
index 7bcbf37..34088ad 100644
--- a/hw/sun4m.c
+++ b/hw/sun4m.c
@@ -932,8 +932,8 @@ static void sun4m_hw_init(const struct sun4m_hwdef *hwdef, ram_addr_t RAM_size,
 
     slavio_serial_ms_kbd_init(hwdef->ms_kb_base, slavio_irq[14],
                               display_type == DT_NOGRAPHIC, ESCC_CLOCK, 1);
-    // Slavio TTYA (base+4, Linux ttyS0) is the first Qemu serial device
-    // Slavio TTYB (base+0, Linux ttyS1) is the second Qemu serial device
+    /* Slavio TTYA (base+4, Linux ttyS0) is the first QEMU serial device
+       Slavio TTYB (base+0, Linux ttyS1) is the second QEMU serial device */
     escc_init(hwdef->serial_base, slavio_irq[15], slavio_irq[15],
               serial_hds[0], serial_hds[1], ESCC_CLOCK, 1);
 
@@ -1581,8 +1581,8 @@ static void sun4d_hw_init(const struct sun4d_hwdef *hwdef, ram_addr_t RAM_size,
 
     slavio_serial_ms_kbd_init(hwdef->ms_kb_base, sbi_irq[12],
                               display_type == DT_NOGRAPHIC, ESCC_CLOCK, 1);
-    // Slavio TTYA (base+4, Linux ttyS0) is the first Qemu serial device
-    // Slavio TTYB (base+0, Linux ttyS1) is the second Qemu serial device
+    /* Slavio TTYA (base+4, Linux ttyS0) is the first QEMU serial device
+       Slavio TTYB (base+0, Linux ttyS1) is the second QEMU serial device */
     escc_init(hwdef->serial_base, sbi_irq[12], sbi_irq[12],
               serial_hds[0], serial_hds[1], ESCC_CLOCK, 1);
 
@@ -1762,8 +1762,8 @@ static void sun4c_hw_init(const struct sun4c_hwdef *hwdef, ram_addr_t RAM_size,
 
     slavio_serial_ms_kbd_init(hwdef->ms_kb_base, slavio_irq[1],
                               display_type == DT_NOGRAPHIC, ESCC_CLOCK, 1);
-    // Slavio TTYA (base+4, Linux ttyS0) is the first Qemu serial device
-    // Slavio TTYB (base+0, Linux ttyS1) is the second Qemu serial device
+    /* Slavio TTYA (base+4, Linux ttyS0) is the first QEMU serial device
+       Slavio TTYB (base+0, Linux ttyS1) is the second QEMU serial device */
     escc_init(hwdef->serial_base, slavio_irq[1],
               slavio_irq[1], serial_hds[0], serial_hds[1],
               ESCC_CLOCK, 1);
diff --git a/ppc-dis.c b/ppc-dis.c
index ffdbec1..bc98cbe 100644
--- a/ppc-dis.c
+++ b/ppc-dis.c
@@ -5152,7 +5152,7 @@ powerpc_dialect (struct disassemble_info *info)
   return dialect;
 }
 
-/* Qemu default */
+/* QEMU default */
 int
 print_insn_ppc (bfd_vma memaddr, struct disassemble_info *info)
 {
diff --git a/qemu-queue.h b/qemu-queue.h
index 74d7122..9288cd8 100644
--- a/qemu-queue.h
+++ b/qemu-queue.h
@@ -1,7 +1,7 @@
 /*      $NetBSD: queue.h,v 1.52 2009/04/20 09:56:08 mschuett Exp $ */
 
 /*
- * Qemu version: Copy from netbsd, removed debug code, removed some of
+ * QEMU version: Copy from netbsd, removed debug code, removed some of
  * the implementations.  Left in singly-linked lists, lists, simple
  * queues, and tail queues.
  */
diff --git a/target-alpha/cpu.h b/target-alpha/cpu.h
index 6c5d28b..74bf7f7 100644
--- a/target-alpha/cpu.h
+++ b/target-alpha/cpu.h
@@ -276,7 +276,7 @@ struct CPUAlphaState {
     target_ulong t0, t1;
 #endif
 
-    /* Those resources are used only in Qemu core */
+    /* Those resources are used only in QEMU core */
     CPU_COMMON
 
     int error_code;
diff --git a/target-mips/cpu.h b/target-mips/cpu.h
index 7430aa5..257c4c4 100644
--- a/target-mips/cpu.h
+++ b/target-mips/cpu.h
@@ -418,7 +418,7 @@ struct CPUMIPSState {
     /* We waste some space so we can handle shadow registers like TCs. */
     TCState tcs[MIPS_SHADOW_SET_MAX];
     CPUMIPSFPUContext fpus[MIPS_FPU_MAX];
-    /* Qemu */
+    /* QEMU */
     int error_code;
     uint32_t hflags;    /* CPU State */
     /* TMASK defines different execution modes */
diff --git a/target-ppc/cpu.h b/target-ppc/cpu.h
index ca6f1cb..e7fb364 100644
--- a/target-ppc/cpu.h
+++ b/target-ppc/cpu.h
@@ -233,10 +233,10 @@ enum {
     POWERPC_EXCP_DTLBE    = 93, /* Data TLB error                            */
     /* EOL                                                                   */
     POWERPC_EXCP_NB       = 96,
-    /* Qemu exceptions: used internally during code translation              */
+    /* QEMU exceptions: used internally during code translation              */
     POWERPC_EXCP_STOP         = 0x200, /* stop translation                   */
     POWERPC_EXCP_BRANCH       = 0x201, /* branch instruction                 */
-    /* Qemu exceptions: special cases we want to stop translation            */
+    /* QEMU exceptions: special cases we want to stop translation            */
     POWERPC_EXCP_SYNC         = 0x202, /* context synchronizing instruction  */
     POWERPC_EXCP_SYSCALL_USER = 0x203, /* System call in user mode only      */
     POWERPC_EXCP_STCX         = 0x204 /* Conditional stores in user mode     */
@@ -1041,7 +1041,7 @@ struct CPUPPCState {
     /* opcode handlers */
     opc_handler_t *opcodes[0x40];
 
-    /* Those resources are used only in Qemu core */
+    /* Those resources are used only in QEMU core */
     target_ulong hflags;      /* hflags is a MSR & HFLAGS_MASK         */
     target_ulong hflags_nmsr; /* specific hflags, not coming from MSR */
     int mmu_idx;         /* precomputed MMU index to speed up mem accesses */
diff --git a/target-ppc/helper.c b/target-ppc/helper.c
index 39dcc27..e13b749 100644
--- a/target-ppc/helper.c
+++ b/target-ppc/helper.c
@@ -365,7 +365,7 @@ void ppc6xx_tlb_store (CPUPPCState *env, target_ulong EPN, int way, int is_code,
     tlb = &env->tlb.tlb6[nr];
     LOG_SWTLB("Set TLB %d/%d EPN " TARGET_FMT_lx " PTE0 " TARGET_FMT_lx
               " PTE1 " TARGET_FMT_lx "\n", nr, env->nb_tlb, EPN, pte0, pte1);
-    /* Invalidate any pending reference in Qemu for this virtual address */
+    /* Invalidate any pending reference in QEMU for this virtual address */
     __ppc6xx_tlb_invalidate_virt(env, EPN, is_code, 1);
     tlb->pte0 = pte0;
     tlb->pte1 = pte1;
@@ -729,7 +729,7 @@ void ppc_slb_invalidate_all (CPUPPCState *env)
             slb->esid &= ~SLB_ESID_V;
             /* XXX: given the fact that segment size is 256 MB or 1TB,
              *      and we still don't have a tlb_flush_mask(env, n, mask)
-             *      in Qemu, we just invalidate all TLBs
+             *      in QEMU, we just invalidate all TLBs
              */
             do_invalidate = 1;
         }
@@ -752,7 +752,7 @@ void ppc_slb_invalidate_one (CPUPPCState *env, uint64_t T0)
 
         /* XXX: given the fact that segment size is 256 MB or 1TB,
          *      and we still don't have a tlb_flush_mask(env, n, mask)
-         *      in Qemu, we just invalidate all TLBs
+         *      in QEMU, we just invalidate all TLBs
          */
         tlb_flush(env, 1);
     }
@@ -2319,7 +2319,7 @@ void ppc_tlb_invalidate_one (CPUPPCState *env, target_ulong addr)
     case POWERPC_MMU_2_06:
         /* tlbie invalidate TLBs for all segments */
         /* XXX: given the fact that there are too many segments to invalidate,
-         *      and we still don't have a tlb_flush_mask(env, n, mask) in Qemu,
+         *      and we still don't have a tlb_flush_mask(env, n, mask) in QEMU,
          *      we just invalidate all TLBs
          */
         tlb_flush(env, 1);
diff --git a/target-ppc/kvm.c b/target-ppc/kvm.c
index 724f4c7..d929213 100644
--- a/target-ppc/kvm.c
+++ b/target-ppc/kvm.c
@@ -470,7 +470,7 @@ void kvm_arch_pre_run(CPUPPCState *env, struct kvm_run *run)
     int r;
     unsigned irq;
 
-    /* PowerPC Qemu tracks the various core input pins (interrupt, critical
+    /* PowerPC QEMU tracks the various core input pins (interrupt, critical
      * interrupt, reset, etc) in PPC-specific env->irq_input_state. */
     if (!cap_interrupt_level &&
         run->ready_for_interrupt_injection &&
diff --git a/target-ppc/kvm_ppc.c b/target-ppc/kvm_ppc.c
index 24fc6bc..a2e49cd 100644
--- a/target-ppc/kvm_ppc.c
+++ b/target-ppc/kvm_ppc.c
@@ -31,7 +31,7 @@ void kvmppc_init(void)
 {
     /* XXX The only reason KVM yields control back to qemu is device IO. Since
      * an idle guest does no IO, qemu's device model will never get a chance to
-     * run. So, until Qemu gains IO threads, we create this timer to ensure
+     * run. So, until QEMU gains IO threads, we create this timer to ensure
      * that the device model gets a chance to run. */
     kvmppc_timer_rate = get_ticks_per_sec() / 10;
     kvmppc_timer = qemu_new_timer_ns(vm_clock, &kvmppc_timer_hack, NULL);
diff --git a/target-ppc/translate_init.c b/target-ppc/translate_init.c
index 367eefa..b1f8785 100644
--- a/target-ppc/translate_init.c
+++ b/target-ppc/translate_init.c
@@ -1796,17 +1796,17 @@ static void gen_spr_440 (CPUPPCState *env)
 static void gen_spr_40x (CPUPPCState *env)
 {
     /* Cache */
-    /* not emulated, as Qemu do not emulate caches */
+    /* not emulated, as QEMU do not emulate caches */
     spr_register(env, SPR_40x_DCCR, "DCCR",
                  SPR_NOACCESS, SPR_NOACCESS,
                  &spr_read_generic, &spr_write_generic,
                  0x00000000);
-    /* not emulated, as Qemu do not emulate caches */
+    /* not emulated, as QEMU do not emulate caches */
     spr_register(env, SPR_40x_ICCR, "ICCR",
                  SPR_NOACCESS, SPR_NOACCESS,
                  &spr_read_generic, &spr_write_generic,
                  0x00000000);
-    /* not emulated, as Qemu do not emulate caches */
+    /* not emulated, as QEMU do not emulate caches */
     spr_register(env, SPR_BOOKE_ICDBDR, "ICDBDR",
                  SPR_NOACCESS, SPR_NOACCESS,
                  &spr_read_generic, SPR_NOACCESS,
@@ -1974,7 +1974,7 @@ static void gen_spr_401_403 (CPUPPCState *env)
                  SPR_NOACCESS, &spr_write_tbu,
                  0x00000000);
     /* Debug */
-    /* not emulated, as Qemu do not emulate caches */
+    /* not emulated, as QEMU do not emulate caches */
     spr_register(env, SPR_403_CDBCR, "CDBCR",
                  SPR_NOACCESS, SPR_NOACCESS,
                  &spr_read_generic, &spr_write_generic,
@@ -2012,12 +2012,12 @@ static void gen_spr_401 (CPUPPCState *env)
                  SPR_NOACCESS, SPR_NOACCESS,
                  &spr_read_generic, &spr_write_40x_sler,
                  0x00000000);
-    /* not emulated, as Qemu never does speculative access */
+    /* not emulated, as QEMU never does speculative access */
     spr_register(env, SPR_40x_SGR, "SGR",
                  SPR_NOACCESS, SPR_NOACCESS,
                  &spr_read_generic, &spr_write_generic,
                  0xFFFFFFFF);
-    /* not emulated, as Qemu do not emulate caches */
+    /* not emulated, as QEMU do not emulate caches */
     spr_register(env, SPR_40x_DCWR, "DCWR",
                  SPR_NOACCESS, SPR_NOACCESS,
                  &spr_read_generic, &spr_write_generic,
@@ -3436,12 +3436,12 @@ static void init_proc_403GCX (CPUPPCState *env)
     gen_spr_403_real(env);
     gen_spr_403_mmu(env);
     /* Bus access control */
-    /* not emulated, as Qemu never does speculative access */
+    /* not emulated, as QEMU never does speculative access */
     spr_register(env, SPR_40x_SGR, "SGR",
                  SPR_NOACCESS, SPR_NOACCESS,
                  &spr_read_generic, &spr_write_generic,
                  0xFFFFFFFF);
-    /* not emulated, as Qemu do not emulate caches */
+    /* not emulated, as QEMU do not emulate caches */
     spr_register(env, SPR_40x_DCWR, "DCWR",
                  SPR_NOACCESS, SPR_NOACCESS,
                  &spr_read_generic, &spr_write_generic,
@@ -3488,12 +3488,12 @@ static void init_proc_405 (CPUPPCState *env)
     gen_spr_40x(env);
     gen_spr_405(env);
     /* Bus access control */
-    /* not emulated, as Qemu never does speculative access */
+    /* not emulated, as QEMU never does speculative access */
     spr_register(env, SPR_40x_SGR, "SGR",
                  SPR_NOACCESS, SPR_NOACCESS,
                  &spr_read_generic, &spr_write_generic,
                  0xFFFFFFFF);
-    /* not emulated, as Qemu do not emulate caches */
+    /* not emulated, as QEMU do not emulate caches */
     spr_register(env, SPR_40x_DCWR, "DCWR",
                  SPR_NOACCESS, SPR_NOACCESS,
                  &spr_read_generic, &spr_write_generic,
@@ -9442,13 +9442,13 @@ static void init_ppc_proc (CPUPPCState *env, const ppc_def_t *def)
     }
     if (env->irq_inputs == NULL) {
         fprintf(stderr, "WARNING: no internal IRQ controller registered.\n"
-                " Attempt Qemu to crash very soon !\n");
+                " Attempt QEMU to crash very soon !\n");
     }
 #endif
     if (env->check_pow == NULL) {
         fprintf(stderr, "WARNING: no power management check handler "
                 "registered.\n"
-                " Attempt Qemu to crash very soon !\n");
+                " Attempt QEMU to crash very soon !\n");
     }
 }
 
diff --git a/ui/cocoa.m b/ui/cocoa.m
index 0711205..e7d6e89 100644
--- a/ui/cocoa.m
+++ b/ui/cocoa.m
@@ -772,7 +772,7 @@ QemuCocoaView *cocoaView;
               modalForWindow:normalWindow modalDelegate:self
               didEndSelector:@selector(openPanelDidEnd:returnCode:contextInfo:) contextInfo:NULL];
     } else {
-        // or Launch Qemu, with the global args
+        // or launch QEMU, with the global args
         [self startEmulationWithArgc:gArgc argv:(char **)gArgv];
     }
 }
diff --git a/ui/spice-display.c b/ui/spice-display.c
index cb8a7ad..5418eb3 100644
--- a/ui/spice-display.c
+++ b/ui/spice-display.c
@@ -219,7 +219,7 @@ 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:
+ * when calling qemu functions.  QEMU interfaces used:
  *    - g_free (underlying glibc free is re-entrant).
  */
 void qemu_spice_destroy_update(SimpleSpiceDisplay *sdpy, SimpleSpiceUpdate *update)
commit c5ec15ea3b9374e6d493f8de7dfc170cec058068
Author: Stefan Weil <sw at weilnetz.de>
Date:   Sat Apr 7 09:23:38 2012 +0200

    Replace Qemu by QEMU in w32 installation path (prefix)
    
    The official spelling is QEMU.
    
    Signed-off-by: Stefan Weil <sw at weilnetz.de>
    Reviewed-by: Andreas Färber <afaerber at suse.de>
    Signed-off-by: Blue Swirl <blauwirbel at gmail.com>

diff --git a/configure b/configure
index 6f850a6..671b232 100755
--- a/configure
+++ b/configure
@@ -519,7 +519,7 @@ EOF
   if compile_prog "" "-liberty" ; then
     LIBS="-liberty $LIBS"
   fi
-  prefix="c:/Program Files/Qemu"
+  prefix="c:/Program Files/QEMU"
   mandir="\${prefix}"
   datadir="\${prefix}"
   docdir="\${prefix}"
diff --git a/qemu-doc.texi b/qemu-doc.texi
index d18dff0..9e07ba6 100644
--- a/qemu-doc.texi
+++ b/qemu-doc.texi
@@ -2709,9 +2709,9 @@ MinGW's default header and linker search paths.
 @file{make}.  If you have problems using SDL, verify that
 @file{sdl-config} can be launched from the MSYS command line.
 
- at item You can install QEMU in @file{Program Files/Qemu} by typing
+ at item You can install QEMU in @file{Program Files/QEMU} by typing
 @file{make install}. Don't forget to copy @file{SDL.dll} in
- at file{Program Files/Qemu}.
+ at file{Program Files/QEMU}.
 
 @end itemize
 
@@ -2745,7 +2745,7 @@ The example assumes @file{sdl-config} is installed under @file{/usr/i686-pc-ming
 MinGW cross compilation tools have names like @file{i686-pc-mingw32-gcc} and @file{i686-pc-mingw32-strip}.
 We set the @code{PATH} environment variable to ensure the MinGW version of @file{sdl-config} is used and
 use --cross-prefix to specify the name of the cross compiler.
-You can also use --prefix to set the Win32 install path which defaults to @file{c:/Program Files/Qemu}.
+You can also use --prefix to set the Win32 install path which defaults to @file{c:/Program Files/QEMU}.
 
 Under Fedora Linux, you can run:
 @example
commit 6576b74b0ba068f252cc23c5a541c59621270483
Author: Stefan Weil <sw at weilnetz.de>
Date:   Sat Apr 7 09:23:37 2012 +0200

    Replace Qemu by QEMU in internal documentation
    
    The official spelling is QEMU.
    
    Signed-off-by: Stefan Weil <sw at weilnetz.de>
    Reviewed-by: Andreas Färber <afaerber at suse.de>
    Signed-off-by: Blue Swirl <blauwirbel at gmail.com>

diff --git a/CODING_STYLE b/CODING_STYLE
index 7c82d4d..dcbce28 100644
--- a/CODING_STYLE
+++ b/CODING_STYLE
@@ -1,4 +1,4 @@
-Qemu Coding Style
+QEMU Coding Style
 =================
 
 Please use the script checkpatch.pl in the scripts directory to check
diff --git a/docs/ccid.txt b/docs/ccid.txt
index b8e504a..450a66a 100644
--- a/docs/ccid.txt
+++ b/docs/ccid.txt
@@ -1,4 +1,4 @@
-Qemu CCID Device Documentation.
+QEMU CCID Device Documentation.
 
 Contents
 1. USB CCID device
diff --git a/docs/specs/ivshmem_device_spec.txt b/docs/specs/ivshmem_device_spec.txt
index 23dd2ba..667a862 100644
--- a/docs/specs/ivshmem_device_spec.txt
+++ b/docs/specs/ivshmem_device_spec.txt
@@ -24,7 +24,7 @@ The device currently supports 4 registers of 32-bits each.  Registers
 are used for synchronization between guests sharing the same memory object when
 interrupts are supported (this requires using the shared memory server).
 
-The server assigns each VM an ID number and sends this ID number to the Qemu
+The server assigns each VM an ID number and sends this ID number to the QEMU
 process when the guest starts.
 
 enum ivshmem_registers {
diff --git a/target-alpha/STATUS b/target-alpha/STATUS
index 742e370..6c97445 100644
--- a/target-alpha/STATUS
+++ b/target-alpha/STATUS
@@ -4,7 +4,7 @@ Alpha emulation structure:
 cpu.h           : CPU definitions globally exported
 exec.h          : CPU definitions used only for translated code execution
 helper.c        : helpers that can be called either by the translated code
-                  or the Qemu core, including the exception handler.
+                  or the QEMU core, including the exception handler.
 op_helper.c     : helpers that can be called only from TCG
 helper.h        : TCG helpers prototypes
 translate.c     : Alpha instructions to micro-operations translator
diff --git a/target-mips/TODO b/target-mips/TODO
index 9101881..2a3546f 100644
--- a/target-mips/TODO
+++ b/target-mips/TODO
@@ -16,7 +16,7 @@ General
   Existing documentation is x86-centric.
 - Reverse endianness bit not implemented
 - The TLB emulation is very inefficient:
-  Qemu's softmmu implements a x86-style MMU, with separate entries
+  QEMU's softmmu implements a x86-style MMU, with separate entries
   for read/write/execute, a TLB index which is just a modulo of the
   virtual address, and a set of TLBs for each user/kernel/supervisor
   MMU mode.
@@ -25,7 +25,7 @@ General
   up to 256 ASID tags as additional matching criterion (which roughly
   equates to 256 MMU modes). It also has a global flag which causes
   entries to match regardless of ASID.
-  To cope with these differences, Qemu currently flushes the TLB at
+  To cope with these differences, QEMU currently flushes the TLB at
   each ASID change. Using the MMU modes to implement ASIDs hinges on
   implementing the global bit efficiently.
 - save/restore of the CPU state is not implemented (see machine.c).
commit 071c93945825dcf8b8ec0d81f09e631d7c96142d
Author: Stefan Weil <sw at weilnetz.de>
Date:   Sat Apr 7 09:23:36 2012 +0200

    Replace Qemu by QEMU in user visible documentation
    
    The official spelling is QEMU.
    
    Signed-off-by: Stefan Weil <sw at weilnetz.de>
    Reviewed-by: Andreas Färber <afaerber at suse.de>
    Signed-off-by: Blue Swirl <blauwirbel at gmail.com>

diff --git a/fsdev/virtfs-proxy-helper.texi b/fsdev/virtfs-proxy-helper.texi
index faa0434..e60e3b9 100644
--- a/fsdev/virtfs-proxy-helper.texi
+++ b/fsdev/virtfs-proxy-helper.texi
@@ -24,7 +24,7 @@ in non-root mode, but doing privileged operations using socket IO.
 Proxy helper(a stand alone binary part of qemu) is invoked with
 root privileges. Proxy helper chroots into 9p export path and creates
 a socket pair or a named socket based on the command line parameter.
-Qemu and proxy helper communicate using this socket. QEMU proxy fs
+QEMU and proxy helper communicate using this socket. QEMU proxy fs
 driver sends filesystem request to proxy helper and receives the
 response from it.
 
diff --git a/qemu-doc.texi b/qemu-doc.texi
index 83b2ad5..d18dff0 100644
--- a/qemu-doc.texi
+++ b/qemu-doc.texi
@@ -968,7 +968,7 @@ monitor (@pxref{pcsys_keys}).
 
 QEMU emulates a PCI UHCI USB controller. You can virtually plug
 virtual USB devices or real host USB devices (experimental, works only
-on Linux hosts).  Qemu will automatically create and connect virtual USB hubs
+on Linux hosts).  QEMU will automatically create and connect virtual USB hubs
 as necessary to connect multiple USB devices.
 
 @menu
diff --git a/qemu-nbd.texi b/qemu-nbd.texi
index 44996cc..6955d90 100644
--- a/qemu-nbd.texi
+++ b/qemu-nbd.texi
@@ -6,7 +6,7 @@ usage: qemu-nbd [OPTION]...  @var{filename}
 
 @c man begin DESCRIPTION
 
-Export Qemu disk image using NBD protocol.
+Export QEMU disk image using NBD protocol.
 
 @c man end
 
diff --git a/qemu-options.hx b/qemu-options.hx
index f72f9a0..a169792 100644
--- a/qemu-options.hx
+++ b/qemu-options.hx
@@ -1310,7 +1310,7 @@ and a @var{name} can be assigned for use in monitor commands.
 Optionally, for PCI cards, you can specify the number @var{v} of MSI-X vectors
 that the card should have; this option currently only affects virtio cards; set
 @var{v} = 0 to disable MSI-X. If no @option{-net} option is specified, a single
-NIC is created.  Qemu can emulate several different models of network card.
+NIC is created.  QEMU can emulate several different models of network card.
 Valid values for @var{type} are
 @code{virtio}, @code{i82551}, @code{i82557b}, @code{i82559er},
 @code{ne2k_pci}, @code{ne2k_isa}, @code{pcnet}, @code{rtl8139},
@@ -2133,7 +2133,7 @@ activates telnet remote echo and single char transfer, then you can
 use the following options to step up a netcat redirector to allow
 telnet on port 5555 to access the qemu port.
 @table @code
- at item Qemu Options:
+ at item QEMU Options:
 -serial udp::4555@@:4556
 @item netcat options:
 -u -P 4555 -L 0.0.0.0:4556 -t -p 5555 -I -T
commit 97a33880e7c06332ea3498437c70a903cbbfe361
Author: Wanpeng Li <liwp at linux.vnet.ibm.com>
Date:   Fri Apr 6 15:52:09 2012 +0800

    remove useless comments in dma
    
    This comment is useless, just removes it and makes the codes clear.
    
    Signed-off-by: Wanpeng Li <liwp at linux.vnet.ibm.com>
    Signed-off-by: Blue Swirl <blauwirbel at gmail.com>

diff --git a/dma.h b/dma.h
index 20e86d2..5bd1fc8 100644
--- a/dma.h
+++ b/dma.h
@@ -11,7 +11,6 @@
 #define DMA_H
 
 #include <stdio.h>
-//#include "cpu.h"
 #include "hw/hw.h"
 #include "block.h"
 
commit 3b2aba2f1309cebbcb72a5f006479f2467aa4e9f
Author: Stefan Weil <sw at weilnetz.de>
Date:   Sat Apr 7 11:48:39 2012 +0200

    tci: Support targets with CONFIG_TCG_PASS_AREG0 (fix broken build)
    
    Builds with --enable-tcg-interpreter failed because more and more
    targets (currently alpha and sparc) replaced the global env in AREG0
    by function parameters.
    
    Convert the TCG interpreter to use the new helper functions and add
    defines for those targets which still use AREG0.
    
    Cc: Blue Swirl <blauwirbel at gmail.com>
    Signed-off-by: Stefan Weil <sw at weilnetz.de>
    Signed-off-by: Blue Swirl <blauwirbel at gmail.com>

diff --git a/tci.c b/tci.c
index 70e7bfb..c43fe7d 100644
--- a/tci.c
+++ b/tci.c
@@ -63,6 +63,17 @@ void *tci_tb_ptr;
 
 static tcg_target_ulong tci_reg[TCG_TARGET_NB_REGS];
 
+#if !defined(CONFIG_TCG_PASS_AREG0)
+# define helper_ldb_mmu(env, addr, mmu_idx) __ldb_mmu(addr, mmu_idx)
+# define helper_ldw_mmu(env, addr, mmu_idx) __ldw_mmu(addr, mmu_idx)
+# define helper_ldl_mmu(env, addr, mmu_idx) __ldl_mmu(addr, mmu_idx)
+# define helper_ldq_mmu(env, addr, mmu_idx) __ldq_mmu(addr, mmu_idx)
+# define helper_stb_mmu(env, addr, val, mmu_idx) __stb_mmu(addr, val, mmu_idx)
+# define helper_stw_mmu(env, addr, val, mmu_idx) __stw_mmu(addr, val, mmu_idx)
+# define helper_stl_mmu(env, addr, val, mmu_idx) __stl_mmu(addr, val, mmu_idx)
+# define helper_stq_mmu(env, addr, val, mmu_idx) __stq_mmu(addr, val, mmu_idx)
+#endif /* !CONFIG_TCG_PASS_AREG0 */
+
 static tcg_target_ulong tci_read_reg(TCGReg index)
 {
     assert(index < ARRAY_SIZE(tci_reg));
@@ -1049,7 +1060,7 @@ tcg_target_ulong tcg_qemu_tb_exec(CPUArchState *cpustate, uint8_t *tb_ptr)
             t0 = *tb_ptr++;
             taddr = tci_read_ulong(&tb_ptr);
 #ifdef CONFIG_SOFTMMU
-            tmp8 = __ldb_mmu(taddr, tci_read_i(&tb_ptr));
+            tmp8 = helper_ldb_mmu(env, taddr, tci_read_i(&tb_ptr));
 #else
             host_addr = (tcg_target_ulong)taddr;
             assert(taddr == host_addr);
@@ -1061,7 +1072,7 @@ tcg_target_ulong tcg_qemu_tb_exec(CPUArchState *cpustate, uint8_t *tb_ptr)
             t0 = *tb_ptr++;
             taddr = tci_read_ulong(&tb_ptr);
 #ifdef CONFIG_SOFTMMU
-            tmp8 = __ldb_mmu(taddr, tci_read_i(&tb_ptr));
+            tmp8 = helper_ldb_mmu(env, taddr, tci_read_i(&tb_ptr));
 #else
             host_addr = (tcg_target_ulong)taddr;
             assert(taddr == host_addr);
@@ -1073,7 +1084,7 @@ tcg_target_ulong tcg_qemu_tb_exec(CPUArchState *cpustate, uint8_t *tb_ptr)
             t0 = *tb_ptr++;
             taddr = tci_read_ulong(&tb_ptr);
 #ifdef CONFIG_SOFTMMU
-            tmp16 = __ldw_mmu(taddr, tci_read_i(&tb_ptr));
+            tmp16 = helper_ldw_mmu(env, taddr, tci_read_i(&tb_ptr));
 #else
             host_addr = (tcg_target_ulong)taddr;
             assert(taddr == host_addr);
@@ -1085,7 +1096,7 @@ tcg_target_ulong tcg_qemu_tb_exec(CPUArchState *cpustate, uint8_t *tb_ptr)
             t0 = *tb_ptr++;
             taddr = tci_read_ulong(&tb_ptr);
 #ifdef CONFIG_SOFTMMU
-            tmp16 = __ldw_mmu(taddr, tci_read_i(&tb_ptr));
+            tmp16 = helper_ldw_mmu(env, taddr, tci_read_i(&tb_ptr));
 #else
             host_addr = (tcg_target_ulong)taddr;
             assert(taddr == host_addr);
@@ -1098,7 +1109,7 @@ tcg_target_ulong tcg_qemu_tb_exec(CPUArchState *cpustate, uint8_t *tb_ptr)
             t0 = *tb_ptr++;
             taddr = tci_read_ulong(&tb_ptr);
 #ifdef CONFIG_SOFTMMU
-            tmp32 = __ldl_mmu(taddr, tci_read_i(&tb_ptr));
+            tmp32 = helper_ldl_mmu(env, taddr, tci_read_i(&tb_ptr));
 #else
             host_addr = (tcg_target_ulong)taddr;
             assert(taddr == host_addr);
@@ -1110,7 +1121,7 @@ tcg_target_ulong tcg_qemu_tb_exec(CPUArchState *cpustate, uint8_t *tb_ptr)
             t0 = *tb_ptr++;
             taddr = tci_read_ulong(&tb_ptr);
 #ifdef CONFIG_SOFTMMU
-            tmp32 = __ldl_mmu(taddr, tci_read_i(&tb_ptr));
+            tmp32 = helper_ldl_mmu(env, taddr, tci_read_i(&tb_ptr));
 #else
             host_addr = (tcg_target_ulong)taddr;
             assert(taddr == host_addr);
@@ -1123,7 +1134,7 @@ tcg_target_ulong tcg_qemu_tb_exec(CPUArchState *cpustate, uint8_t *tb_ptr)
             t0 = *tb_ptr++;
             taddr = tci_read_ulong(&tb_ptr);
 #ifdef CONFIG_SOFTMMU
-            tmp32 = __ldl_mmu(taddr, tci_read_i(&tb_ptr));
+            tmp32 = helper_ldl_mmu(env, taddr, tci_read_i(&tb_ptr));
 #else
             host_addr = (tcg_target_ulong)taddr;
             assert(taddr == host_addr);
@@ -1138,7 +1149,7 @@ tcg_target_ulong tcg_qemu_tb_exec(CPUArchState *cpustate, uint8_t *tb_ptr)
 #endif
             taddr = tci_read_ulong(&tb_ptr);
 #ifdef CONFIG_SOFTMMU
-            tmp64 = __ldq_mmu(taddr, tci_read_i(&tb_ptr));
+            tmp64 = helper_ldq_mmu(env, taddr, tci_read_i(&tb_ptr));
 #else
             host_addr = (tcg_target_ulong)taddr;
             assert(taddr == host_addr);
@@ -1154,7 +1165,7 @@ tcg_target_ulong tcg_qemu_tb_exec(CPUArchState *cpustate, uint8_t *tb_ptr)
             taddr = tci_read_ulong(&tb_ptr);
 #ifdef CONFIG_SOFTMMU
             t2 = tci_read_i(&tb_ptr);
-            __stb_mmu(taddr, t0, t2);
+            helper_stb_mmu(env, taddr, t0, t2);
 #else
             host_addr = (tcg_target_ulong)taddr;
             assert(taddr == host_addr);
@@ -1166,7 +1177,7 @@ tcg_target_ulong tcg_qemu_tb_exec(CPUArchState *cpustate, uint8_t *tb_ptr)
             taddr = tci_read_ulong(&tb_ptr);
 #ifdef CONFIG_SOFTMMU
             t2 = tci_read_i(&tb_ptr);
-            __stw_mmu(taddr, t0, t2);
+            helper_stw_mmu(env, taddr, t0, t2);
 #else
             host_addr = (tcg_target_ulong)taddr;
             assert(taddr == host_addr);
@@ -1178,7 +1189,7 @@ tcg_target_ulong tcg_qemu_tb_exec(CPUArchState *cpustate, uint8_t *tb_ptr)
             taddr = tci_read_ulong(&tb_ptr);
 #ifdef CONFIG_SOFTMMU
             t2 = tci_read_i(&tb_ptr);
-            __stl_mmu(taddr, t0, t2);
+            helper_stl_mmu(env, taddr, t0, t2);
 #else
             host_addr = (tcg_target_ulong)taddr;
             assert(taddr == host_addr);
@@ -1190,7 +1201,7 @@ tcg_target_ulong tcg_qemu_tb_exec(CPUArchState *cpustate, uint8_t *tb_ptr)
             taddr = tci_read_ulong(&tb_ptr);
 #ifdef CONFIG_SOFTMMU
             t2 = tci_read_i(&tb_ptr);
-            __stq_mmu(taddr, tmp64, t2);
+            helper_stq_mmu(env, taddr, tmp64, t2);
 #else
             host_addr = (tcg_target_ulong)taddr;
             assert(taddr == host_addr);
commit adcd61f7fcd5a24e65b2ec087bfae2356805993b
Merge: 6375e09... d8fd295...
Author: Blue Swirl <blauwirbel at gmail.com>
Date:   Sat Apr 7 11:45:25 2012 +0000

    Merge branch 'linux-user-for-upstream' of git://git.linaro.org/people/rikuvoipio/qemu
    
    * 'linux-user-for-upstream' of git://git.linaro.org/people/rikuvoipio/qemu:
      Userspace ARM BE8 support
      elf.h: Update EF_ARM_ constants to newer ABI versions
      arm-linux-user: fix elfload.c's AT_HWCAP to reflect cpu features.
      linux-user/arm/syscall_nr.h: Add syscall number for ppoll
      linux-user: Add support for prctl PR_GET_NAME and PR_SET_NAME
      linux-user/syscall.c: Fix indentation in prctl handling
      linux-user: reserve 4GB of vmem for 32-on-64
      linux-user: resolve reserved_va vma downwards
      linux-user: take RESERVED_VA into account for g2h_valid()
      linux-user: fix fallocate
      linux-user: Add ioctl for BLKBSZGET
      linux-user: add BLKSSZGET ioctl wrapper
      linux-user: fix BLK ioctl arguments
      linux-user: add struct old_dev_t compat
      linux-user: implement device mapper ioctls
      linux-user: target_argv is placed on ts->bprm->argv and can't be freed()
      linux-user: improve fake /proc/self/stat making `ps` not segfault.

commit 6375e09e79964fa6eac3e8426d25c8b759185482
Author: Stefan Weil <sw at weilnetz.de>
Date:   Fri Apr 6 22:26:15 2012 +0200

    w64: Fix data type of tb_next and other variables used for host addresses
    
    QEMU host addresses must use uintptr_t to be portable for hosts with
    an unusual size of long (w64).
    
    tb_jmp_offset is an uint16_t value, therefore the local variable offset
    in function tb_set_jmp_target was changed from unsigned long to uint16_t.
    
    The type cast to long in function tb_add_jump now also uses uintptr_t.
    For the bit operation used here, the signedness of the type cast does
    not matter.
    
    Some remaining unsigned long values are either only used for ARM assembler
    code or will be fixed in a later patch for PPC.
    
    v2:
    Fix signature of tb_find_pc in exec.c, too (hint from Blue Swirl, thanks).
    There remain lots of other long / unsigned long in exec.c which must be
    replaced by uintptr_t. This will be done in a separate patch. Here
    only one of these type casts is fixed.
    
    v3:
    Also fix signature of page_unprotect.
    
    Signed-off-by: Stefan Weil <sw at weilnetz.de>
    Signed-off-by: Blue Swirl <blauwirbel at gmail.com>

diff --git a/exec-all.h b/exec-all.h
index 93a5b22..a6d6519 100644
--- a/exec-all.h
+++ b/exec-all.h
@@ -85,7 +85,7 @@ void cpu_gen_init(void);
 int cpu_gen_code(CPUArchState *env, struct TranslationBlock *tb,
                  int *gen_code_size_ptr);
 int cpu_restore_state(struct TranslationBlock *tb,
-                      CPUArchState *env, unsigned long searched_pc);
+                      CPUArchState *env, uintptr_t searched_pc);
 void cpu_resume_from_signal(CPUArchState *env1, void *puc);
 void cpu_io_recompile(CPUArchState *env, void *retaddr);
 TranslationBlock *tb_gen_code(CPUArchState *env, 
@@ -93,7 +93,7 @@ TranslationBlock *tb_gen_code(CPUArchState *env,
                               int cflags);
 void cpu_exec_init(CPUArchState *env);
 void QEMU_NORETURN cpu_loop_exit(CPUArchState *env1);
-int page_unprotect(target_ulong address, unsigned long pc, void *puc);
+int page_unprotect(target_ulong address, uintptr_t pc, void *puc);
 void tb_invalidate_phys_page_range(tb_page_addr_t start, tb_page_addr_t end,
                                    int is_cpu_write_access);
 void tlb_flush_page(CPUArchState *env, target_ulong addr);
@@ -150,7 +150,7 @@ struct TranslationBlock {
 #ifdef USE_DIRECT_JUMP
     uint16_t tb_jmp_offset[2]; /* offset of jump instruction */
 #else
-    unsigned long tb_next[2]; /* address of jump generated code */
+    uintptr_t tb_next[2]; /* address of jump generated code */
 #endif
     /* list of TBs jumping to this one. This is a circular list using
        the two least significant bits of the pointers to tell what is
@@ -202,14 +202,14 @@ static inline void tb_set_jmp_target1(uintptr_t jmp_addr, uintptr_t addr)
 void ppc_tb_set_jmp_target(unsigned long jmp_addr, unsigned long addr);
 #define tb_set_jmp_target1 ppc_tb_set_jmp_target
 #elif defined(__i386__) || defined(__x86_64__)
-static inline void tb_set_jmp_target1(unsigned long jmp_addr, unsigned long addr)
+static inline void tb_set_jmp_target1(uintptr_t jmp_addr, uintptr_t addr)
 {
     /* patch the branch destination */
     *(uint32_t *)jmp_addr = addr - (jmp_addr + 4);
     /* no need to flush icache explicitly */
 }
 #elif defined(__arm__)
-static inline void tb_set_jmp_target1(unsigned long jmp_addr, unsigned long addr)
+static inline void tb_set_jmp_target1(uintptr_t jmp_addr, uintptr_t addr)
 {
 #if !QEMU_GNUC_PREREQ(4, 1)
     register unsigned long _beg __asm ("a1");
@@ -237,19 +237,17 @@ static inline void tb_set_jmp_target1(unsigned long jmp_addr, unsigned long addr
 #endif
 
 static inline void tb_set_jmp_target(TranslationBlock *tb,
-                                     int n, unsigned long addr)
+                                     int n, uintptr_t addr)
 {
-    unsigned long offset;
-
-    offset = tb->tb_jmp_offset[n];
-    tb_set_jmp_target1((unsigned long)(tb->tc_ptr + offset), addr);
+    uint16_t offset = tb->tb_jmp_offset[n];
+    tb_set_jmp_target1((uintptr_t)(tb->tc_ptr + offset), addr);
 }
 
 #else
 
 /* set the jump target */
 static inline void tb_set_jmp_target(TranslationBlock *tb,
-                                     int n, unsigned long addr)
+                                     int n, uintptr_t addr)
 {
     tb->tb_next[n] = addr;
 }
@@ -262,15 +260,15 @@ static inline void tb_add_jump(TranslationBlock *tb, int n,
     /* NOTE: this test is only needed for thread safety */
     if (!tb->jmp_next[n]) {
         /* patch the native jump address */
-        tb_set_jmp_target(tb, n, (unsigned long)tb_next->tc_ptr);
+        tb_set_jmp_target(tb, n, (uintptr_t)tb_next->tc_ptr);
 
         /* add in TB jmp circular list */
         tb->jmp_next[n] = tb_next->jmp_first;
-        tb_next->jmp_first = (TranslationBlock *)((long)(tb) | (n));
+        tb_next->jmp_first = (TranslationBlock *)((uintptr_t)(tb) | (n));
     }
 }
 
-TranslationBlock *tb_find_pc(unsigned long pc_ptr);
+TranslationBlock *tb_find_pc(uintptr_t pc_ptr);
 
 #include "qemu-lock.h"
 
@@ -288,13 +286,14 @@ extern void *tci_tb_ptr;
 #  define GETPC() tci_tb_ptr
 # endif
 #elif defined(__s390__) && !defined(__s390x__)
-# define GETPC() ((void*)(((unsigned long)__builtin_return_address(0) & 0x7fffffffUL) - 1))
+# define GETPC() \
+    ((void *)(((uintptr_t)__builtin_return_address(0) & 0x7fffffffUL) - 1))
 #elif defined(__arm__)
 /* Thumb return addresses have the low bit set, so we need to subtract two.
    This is still safe in ARM mode because instructions are 4 bytes.  */
-# define GETPC() ((void *)((unsigned long)__builtin_return_address(0) - 2))
+# define GETPC() ((void *)((uintptr_t)__builtin_return_address(0) - 2))
 #else
-# define GETPC() ((void *)((unsigned long)__builtin_return_address(0) - 1))
+# define GETPC() ((void *)((uintptr_t)__builtin_return_address(0) - 1))
 #endif
 
 #if !defined(CONFIG_USER_ONLY)
diff --git a/exec.c b/exec.c
index 6731ab8..03d3a6b 100644
--- a/exec.c
+++ b/exec.c
@@ -1380,7 +1380,7 @@ void tb_link_page(TranslationBlock *tb,
 
 /* find the TB 'tb' such that tb[0].tc_ptr <= tc_ptr <
    tb[1].tc_ptr. Return NULL if not found */
-TranslationBlock *tb_find_pc(unsigned long tc_ptr)
+TranslationBlock *tb_find_pc(uintptr_t tc_ptr)
 {
     int m_min, m_max, m;
     unsigned long v;
@@ -2502,7 +2502,7 @@ int page_check_range(target_ulong start, target_ulong len, int flags)
 
 /* called from signal handler: invalidate the code and unprotect the
    page. Return TRUE if the fault was successfully handled. */
-int page_unprotect(target_ulong address, unsigned long pc, void *puc)
+int page_unprotect(target_ulong address, uintptr_t pc, void *puc)
 {
     unsigned int prot;
     PageDesc *p;
@@ -4484,7 +4484,7 @@ void cpu_io_recompile(CPUArchState *env, void *retaddr)
     target_ulong pc, cs_base;
     uint64_t flags;
 
-    tb = tb_find_pc((unsigned long)retaddr);
+    tb = tb_find_pc((uintptr_t)retaddr);
     if (!tb) {
         cpu_abort(env, "cpu_io_recompile: could not find TB for pc=%p", 
                   retaddr);
diff --git a/translate-all.c b/translate-all.c
index 8c7d303..5bd2d37 100644
--- a/translate-all.c
+++ b/translate-all.c
@@ -109,11 +109,11 @@ int cpu_gen_code(CPUArchState *env, TranslationBlock *tb, int *gen_code_size_ptr
 /* The cpu state corresponding to 'searched_pc' is restored.
  */
 int cpu_restore_state(TranslationBlock *tb,
-                      CPUArchState *env, unsigned long searched_pc)
+                      CPUArchState *env, uintptr_t searched_pc)
 {
     TCGContext *s = &tcg_ctx;
     int j;
-    unsigned long tc_ptr;
+    uintptr_t tc_ptr;
 #ifdef CONFIG_PROFILER
     int64_t ti;
 #endif
@@ -133,7 +133,7 @@ int cpu_restore_state(TranslationBlock *tb,
     }
 
     /* find opc index corresponding to search_pc */
-    tc_ptr = (unsigned long)tb->tc_ptr;
+    tc_ptr = (uintptr_t)tb->tc_ptr;
     if (searched_pc < tc_ptr)
         return -1;
 
commit 760e141613f5f7c09f5c141658f1e7c23b4a5c33
Author: Peter Maydell <peter.maydell at linaro.org>
Date:   Thu Apr 5 19:12:35 2012 +0100

    softfloat: roundAndPackInt{32, 64}: Don't assume int32 is 32 bits
    
    Fix code in roundAndPackInt32 that assumed that int32 was only
    32 bits, by simply using int32_t instead. Fix the parallel bug
    in roundAndPackInt64 as well, although that one is only theoretical
    since it's unlikely that int64 will ever be more than 64 bits.
    
    Signed-off-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 074fbc3..d37090a 100644
--- a/fpu/softfloat.c
+++ b/fpu/softfloat.c
@@ -117,7 +117,7 @@ static int32 roundAndPackInt32( flag zSign, uint64_t absZ STATUS_PARAM)
     int8 roundingMode;
     flag roundNearestEven;
     int8 roundIncrement, roundBits;
-    int32 z;
+    int32_t z;
 
     roundingMode = STATUS(float_rounding_mode);
     roundNearestEven = ( roundingMode == float_round_nearest_even );
@@ -166,7 +166,7 @@ static int64 roundAndPackInt64( flag zSign, uint64_t absZ0, uint64_t absZ1 STATU
 {
     int8 roundingMode;
     flag roundNearestEven, increment;
-    int64 z;
+    int64_t z;
 
     roundingMode = STATUS(float_rounding_mode);
     roundNearestEven = ( roundingMode == float_round_nearest_even );
commit b3a6a2e0417c78ec5491347eb85a7d125a5fefdc
Author: Peter Maydell <peter.maydell at linaro.org>
Date:   Thu Apr 5 19:12:34 2012 +0100

    softfloat: float*_to_int32_round_to_zero: don't assume int32 is 32 bits
    
    Code in the float64_to_int32_round_to_zero() function was assuming
    that int32 would not be wider than 32 bits; this meant it might
    not correctly detect the overflow case. We take the simple approach
    of using int32_t. Also fix equivalent issues in the functions
    for other float sizes.
    
    Signed-off-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 81a7d1a..074fbc3 100644
--- a/fpu/softfloat.c
+++ b/fpu/softfloat.c
@@ -1378,7 +1378,7 @@ int32 float32_to_int32_round_to_zero( float32 a STATUS_PARAM )
     flag aSign;
     int16 aExp, shiftCount;
     uint32_t aSig;
-    int32 z;
+    int32_t z;
     a = float32_squash_input_denormal(a STATUS_VAR);
 
     aSig = extractFloat32Frac( a );
@@ -2762,7 +2762,7 @@ int32 float64_to_int32_round_to_zero( float64 a STATUS_PARAM )
     flag aSign;
     int16 aExp, shiftCount;
     uint64_t aSig, savedASig;
-    int32 z;
+    int32_t z;
     a = float64_squash_input_denormal(a STATUS_VAR);
 
     aSig = extractFloat64Frac( a );
@@ -4248,7 +4248,7 @@ int32 floatx80_to_int32_round_to_zero( floatx80 a STATUS_PARAM )
     flag aSign;
     int32 aExp, shiftCount;
     uint64_t aSig, savedASig;
-    int32 z;
+    int32_t z;
 
     aSig = extractFloatx80Frac( a );
     aExp = extractFloatx80Exp( a );
@@ -5277,7 +5277,7 @@ int32 float128_to_int32_round_to_zero( float128 a STATUS_PARAM )
     flag aSign;
     int32 aExp, shiftCount;
     uint64_t aSig0, aSig1, savedASig;
-    int32 z;
+    int32_t z;
 
     aSig1 = extractFloat128Frac1( a );
     aSig0 = extractFloat128Frac0( a );
commit a52d28afb4e825a5b28815370a268904a4c6dc11
Author: Paolo Bonzini <pbonzini at redhat.com>
Date:   Thu Apr 5 13:01:54 2012 +0200

    configure: require glib 2.12, 2.20 for mingw32
    
    These are pretty sane requirements to move forward with glib usage.
    2.12 is the version found in RHEL/CentOS 5, and 2.20 is the
    first version to support g_poll.  Without g_poll, we cannot
    integrate well with the glib main loop.
    
    Signed-off-by: Paolo Bonzini <pbonzini at redhat.com>
    Signed-off-by: Blue Swirl <blauwirbel at gmail.com>

diff --git a/configure b/configure
index 4b3adc9..6f850a6 100755
--- a/configure
+++ b/configure
@@ -1993,13 +1993,21 @@ fi
 
 ##########################################
 # glib support probe
-if $pkg_config --modversion gthread-2.0 > /dev/null 2>&1 ; then
+
+if test "$mingw32" = yes; then
+    # g_poll is required in order to integrate with the glib main loop.
+    glib_req_ver=2.20
+else
+    glib_req_ver=2.12
+fi
+if $pkg_config --atleast-version=$glib_req_ver gthread-2.0 > /dev/null 2>&1
+then
     glib_cflags=`$pkg_config --cflags gthread-2.0 2>/dev/null`
     glib_libs=`$pkg_config --libs gthread-2.0 2>/dev/null`
     LIBS="$glib_libs $LIBS"
     libs_qga="$glib_libs $libs_qga"
 else
-    echo "glib-2.0 required to compile QEMU"
+    echo "glib-$glib_req_ver required to compile QEMU"
     exit 1
 fi
 
commit ea26ce765cb661a13e4055f38744036a19465e87
Author: Paolo Bonzini <pbonzini at redhat.com>
Date:   Tue Mar 20 10:49:21 2012 +0100

    main-loop: integrate glib sources for w32
    
    Signed-off-by: Paolo Bonzini <pbonzini at redhat.com>
    Signed-off-by: Blue Swirl <blauwirbel at gmail.com>

diff --git a/main-loop.c b/main-loop.c
index 4d02568..7e163f9 100644
--- a/main-loop.c
+++ b/main-loop.c
@@ -221,11 +221,10 @@ int main_loop_init(void)
 static fd_set rfds, wfds, xfds;
 static int nfds;
 static GPollFD poll_fds[1024 * 2]; /* this is probably overkill */
-
-#ifndef _WIN32
 static int n_poll_fds;
 static int max_priority;
 
+#ifndef _WIN32
 static void glib_select_fill(int *max_fd, fd_set *rfds, fd_set *wfds,
                              fd_set *xfds, int *cur_timeout)
 {
@@ -403,6 +402,7 @@ void qemu_fd_register(int fd)
 
 static int os_host_main_loop_wait(int timeout)
 {
+    GMainContext *context = g_main_context_default();
     int ret, i;
     PollingEntry *pe;
     WaitObjects *w = &wait_objects;
@@ -424,17 +424,22 @@ static int os_host_main_loop_wait(int 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 < w->num; i++) {
-        poll_fds[i].fd = (DWORD) w->events[i];
-        poll_fds[i].events = G_IO_IN;
+        poll_fds[n_poll_fds + i].fd = (DWORD) w->events[i];
+        poll_fds[n_poll_fds + i].events = G_IO_IN;
     }
 
     qemu_mutex_unlock_iothread();
-    ret = g_poll(poll_fds, w->num, timeout);
+    ret = g_poll(poll_fds, n_poll_fds + w->num, timeout);
     qemu_mutex_lock_iothread();
     if (ret > 0) {
         for (i = 0; i < w->num; i++) {
-            w->revents[i] = poll_fds[i].revents;
+            w->revents[i] = poll_fds[n_poll_fds + i].revents;
         }
         for (i = 0; i < w->num; i++) {
             if (w->revents[i] && w->func[i]) {
@@ -443,6 +448,10 @@ static int os_host_main_loop_wait(int timeout)
         }
     }
 
+    if (g_main_context_check(context, max_priority, poll_fds, n_poll_fds)) {
+        g_main_context_dispatch(context);
+    }
+
     /* If an edge-triggered socket event occurred, select will return a
      * positive result on the next iteration.  We do not need to do anything
      * here.
commit 06ac7d49797daf8a5c05c7d25db0b205efda8e30
Author: Paolo Bonzini <pbonzini at redhat.com>
Date:   Tue Mar 20 10:49:20 2012 +0100

    main-loop: replace WaitForMultipleObjects with g_poll
    
    On w32, glib implements g_poll using WaitForMultipleObjects
    or MsgWaitForMultipleObjects.  This means that we can simplify
    our code by switching to g_poll, and at the same time prepare for
    adding back glib sources.
    
    Signed-off-by: Paolo Bonzini <pbonzini at redhat.com>
    Signed-off-by: Blue Swirl <blauwirbel at gmail.com>

diff --git a/main-loop.c b/main-loop.c
index 7364074..4d02568 100644
--- a/main-loop.c
+++ b/main-loop.c
@@ -220,9 +220,9 @@ int main_loop_init(void)
 
 static fd_set rfds, wfds, xfds;
 static int nfds;
+static GPollFD poll_fds[1024 * 2]; /* this is probably overkill */
 
 #ifndef _WIN32
-static GPollFD poll_fds[1024 * 2]; /* this is probably overkill */
 static int n_poll_fds;
 static int max_priority;
 
@@ -351,6 +351,7 @@ void qemu_del_polling_cb(PollingFunc *func, void *opaque)
 /* Wait objects support */
 typedef struct WaitObjects {
     int num;
+    int revents[MAXIMUM_WAIT_OBJECTS + 1];
     HANDLE events[MAXIMUM_WAIT_OBJECTS + 1];
     WaitObjectFunc *func[MAXIMUM_WAIT_OBJECTS + 1];
     void *opaque[MAXIMUM_WAIT_OBJECTS + 1];
@@ -367,6 +368,7 @@ int qemu_add_wait_object(HANDLE handle, WaitObjectFunc *func, void *opaque)
     w->events[w->num] = handle;
     w->func[w->num] = func;
     w->opaque[w->num] = opaque;
+    w->revents[w->num] = 0;
     w->num++;
     return 0;
 }
@@ -385,6 +387,7 @@ void qemu_del_wait_object(HANDLE handle, WaitObjectFunc *func, void *opaque)
             w->events[i] = w->events[i + 1];
             w->func[i] = w->func[i + 1];
             w->opaque[i] = w->opaque[i + 1];
+            w->revents[i] = w->revents[i + 1];
         }
     }
     if (found) {
@@ -400,9 +403,8 @@ void qemu_fd_register(int fd)
 
 static int os_host_main_loop_wait(int timeout)
 {
-    int ret, ret2, i;
+    int ret, i;
     PollingEntry *pe;
-    int err;
     WaitObjects *w = &wait_objects;
     static struct timeval tv0;
 
@@ -422,33 +424,25 @@ static int os_host_main_loop_wait(int timeout)
         }
     }
 
+    for (i = 0; i < w->num; i++) {
+        poll_fds[i].fd = (DWORD) w->events[i];
+        poll_fds[i].events = G_IO_IN;
+    }
+
     qemu_mutex_unlock_iothread();
-    ret = WaitForMultipleObjects(w->num, w->events, FALSE, timeout);
+    ret = g_poll(poll_fds, w->num, timeout);
     qemu_mutex_lock_iothread();
-    if (WAIT_OBJECT_0 + 0 <= ret && ret <= WAIT_OBJECT_0 + w->num - 1) {
-        if (w->func[ret - WAIT_OBJECT_0]) {
-            w->func[ret - WAIT_OBJECT_0](w->opaque[ret - WAIT_OBJECT_0]);
+    if (ret > 0) {
+        for (i = 0; i < w->num; i++) {
+            w->revents[i] = poll_fds[i].revents;
         }
-
-        /* Check for additional signaled events */
-        for (i = (ret - WAIT_OBJECT_0 + 1); i < w->num; i++) {
-            /* Check if event is signaled */
-            ret2 = WaitForSingleObject(w->events[i], 0);
-            if (ret2 == WAIT_OBJECT_0) {
-                if (w->func[i]) {
-                    w->func[i](w->opaque[i]);
-                }
-            } else if (ret2 != WAIT_TIMEOUT) {
-                err = GetLastError();
-                fprintf(stderr, "WaitForSingleObject error %d %d\n", i, err);
+        for (i = 0; i < w->num; i++) {
+            if (w->revents[i] && w->func[i]) {
+                w->func[i](w->opaque[i]);
             }
         }
-    } else if (ret != WAIT_TIMEOUT) {
-        err = GetLastError();
-        fprintf(stderr, "WaitForMultipleObjects error %d %d\n", ret, err);
     }
 
-
     /* If an edge-triggered socket event occurred, select will return a
      * positive result on the next iteration.  We do not need to do anything
      * here.
commit d3385eb448e38f828c78f8f68ec5d79c66a58b5d
Author: Paolo Bonzini <pbonzini at redhat.com>
Date:   Tue Mar 20 10:49:19 2012 +0100

    main-loop: interrupt wait when data arrives on a socket
    
    Right now, the main loop is not interrupted when data arrives on a
    socket.  To fix this, register each socket to interrupt the main loop
    with WSAEventSelect.  This does not replace select, it only communicates
    a change in socket state that requires a select call.
    
    Since the interrupt fires only once per recv call, or only once
    after a send call returns EWOULDBLOCK we can activate it on all events
    unconditionally.  If QEMU is momentarily uninterested on some condition,
    the main loop will not busy wait.  Instead, it may get one extra wakeup,
    but then it will ignore the condition until progress occurs and/or
    qemu_set_fd_handler is called to set a callback.  At this point the
    condition will be tested via select and the callback will be invoked
    even if it is still disabled on the event.
    
    Signed-off-by: Paolo Bonzini <pbonzini at redhat.com>
    Signed-off-by: Blue Swirl <blauwirbel at gmail.com>

diff --git a/main-loop.c b/main-loop.c
index dc6bdb5..7364074 100644
--- a/main-loop.c
+++ b/main-loop.c
@@ -392,10 +392,18 @@ void qemu_del_wait_object(HANDLE handle, WaitObjectFunc *func, void *opaque)
     }
 }
 
+void qemu_fd_register(int fd)
+{
+    WSAEventSelect(fd, qemu_event_handle, FD_READ | FD_ACCEPT | FD_CLOSE |
+                   FD_CONNECT | FD_WRITE | FD_OOB);
+}
+
 static int os_host_main_loop_wait(int timeout)
 {
     int ret, ret2, i;
     PollingEntry *pe;
+    int err;
+    WaitObjects *w = &wait_objects;
     static struct timeval tv0;
 
     /* XXX: need to suppress polling by better using win32 events */
@@ -403,38 +411,49 @@ static int os_host_main_loop_wait(int timeout)
     for (pe = first_polling_entry; pe != NULL; pe = pe->next) {
         ret |= pe->func(pe->opaque);
     }
-    if (ret == 0) {
-        int err;
-        WaitObjects *w = &wait_objects;
+    if (ret != 0) {
+        return ret;
+    }
 
-        qemu_mutex_unlock_iothread();
-        ret = WaitForMultipleObjects(w->num, w->events, FALSE, timeout);
-        qemu_mutex_lock_iothread();
-        if (WAIT_OBJECT_0 + 0 <= ret && ret <= WAIT_OBJECT_0 + w->num - 1) {
-            if (w->func[ret - WAIT_OBJECT_0]) {
-                w->func[ret - WAIT_OBJECT_0](w->opaque[ret - WAIT_OBJECT_0]);
-            }
+    if (nfds >= 0) {
+        ret = select(nfds + 1, &rfds, &wfds, &xfds, &tv0);
+        if (ret != 0) {
+            timeout = 0;
+        }
+    }
 
-            /* Check for additional signaled events */
-            for (i = (ret - WAIT_OBJECT_0 + 1); i < w->num; i++) {
-                /* Check if event is signaled */
-                ret2 = WaitForSingleObject(w->events[i], 0);
-                if (ret2 == WAIT_OBJECT_0) {
-                    if (w->func[i]) {
-                        w->func[i](w->opaque[i]);
-                    }
-                } else if (ret2 != WAIT_TIMEOUT) {
-                    err = GetLastError();
-                    fprintf(stderr, "WaitForSingleObject error %d %d\n", i, err);
+    qemu_mutex_unlock_iothread();
+    ret = WaitForMultipleObjects(w->num, w->events, FALSE, timeout);
+    qemu_mutex_lock_iothread();
+    if (WAIT_OBJECT_0 + 0 <= ret && ret <= WAIT_OBJECT_0 + w->num - 1) {
+        if (w->func[ret - WAIT_OBJECT_0]) {
+            w->func[ret - WAIT_OBJECT_0](w->opaque[ret - WAIT_OBJECT_0]);
+        }
+
+        /* Check for additional signaled events */
+        for (i = (ret - WAIT_OBJECT_0 + 1); i < w->num; i++) {
+            /* Check if event is signaled */
+            ret2 = WaitForSingleObject(w->events[i], 0);
+            if (ret2 == WAIT_OBJECT_0) {
+                if (w->func[i]) {
+                    w->func[i](w->opaque[i]);
                 }
+            } else if (ret2 != WAIT_TIMEOUT) {
+                err = GetLastError();
+                fprintf(stderr, "WaitForSingleObject error %d %d\n", i, err);
             }
-        } else if (ret != WAIT_TIMEOUT) {
-            err = GetLastError();
-            fprintf(stderr, "WaitForMultipleObjects error %d %d\n", ret, err);
         }
+    } else if (ret != WAIT_TIMEOUT) {
+        err = GetLastError();
+        fprintf(stderr, "WaitForMultipleObjects error %d %d\n", ret, err);
     }
 
-    ret = select(nfds + 1, &rfds, &wfds, &xfds, &tv0);
+
+    /* If an edge-triggered socket event occurred, select will return a
+     * positive result on the next iteration.  We do not need to do anything
+     * here.
+     */
+
     return ret;
 }
 #endif
diff --git a/main-loop.h b/main-loop.h
index 4987041..e743aa0 100644
--- a/main-loop.h
+++ b/main-loop.h
@@ -359,6 +359,7 @@ void qemu_mutex_unlock_iothread(void);
 
 /* internal interfaces */
 
+void qemu_fd_register(int fd);
 void qemu_iohandler_fill(int *pnfds, fd_set *readfds, fd_set *writefds, fd_set *xfds);
 void qemu_iohandler_poll(fd_set *readfds, fd_set *writefds, fd_set *xfds, int rc);
 
diff --git a/oslib-win32.c b/oslib-win32.c
index ce3021e..ffbc6d0 100644
--- a/oslib-win32.c
+++ b/oslib-win32.c
@@ -28,6 +28,7 @@
 #include <windows.h>
 #include "config-host.h"
 #include "sysemu.h"
+#include "main-loop.h"
 #include "trace.h"
 #include "qemu_socket.h"
 
@@ -76,6 +77,7 @@ void qemu_vfree(void *ptr)
 void socket_set_block(int fd)
 {
     unsigned long opt = 0;
+    WSAEventSelect(fd, NULL, 0);
     ioctlsocket(fd, FIONBIO, &opt);
 }
 
@@ -83,6 +85,7 @@ void socket_set_nonblock(int fd)
 {
     unsigned long opt = 1;
     ioctlsocket(fd, FIONBIO, &opt);
+    qemu_fd_register(fd);
 }
 
 int inet_aton(const char *cp, struct in_addr *ia)
commit 15455536df5ef652759ccf465d5e6f73acb493df
Author: Paolo Bonzini <pbonzini at redhat.com>
Date:   Tue Mar 20 10:49:18 2012 +0100

    main-loop: disable fd_set-based glib integration under w32
    
    Using select with glib pollfds is wrong under w32.  Restrict
    the code to the POSIX case.
    
    Signed-off-by: Paolo Bonzini <pbonzini at redhat.com>
    Signed-off-by: Blue Swirl <blauwirbel at gmail.com>

diff --git a/main-loop.c b/main-loop.c
index a3fd993..dc6bdb5 100644
--- a/main-loop.c
+++ b/main-loop.c
@@ -218,7 +218,10 @@ int main_loop_init(void)
     return 0;
 }
 
+static fd_set rfds, wfds, xfds;
+static int nfds;
 
+#ifndef _WIN32
 static GPollFD poll_fds[1024 * 2]; /* this is probably overkill */
 static int n_poll_fds;
 static int max_priority;
@@ -286,7 +289,29 @@ static void glib_select_poll(fd_set *rfds, fd_set *wfds, fd_set *xfds,
     }
 }
 
-#ifdef _WIN32
+static int os_host_main_loop_wait(int timeout)
+{
+    struct timeval tv;
+    int ret;
+
+    glib_select_fill(&nfds, &rfds, &wfds, &xfds, &timeout);
+
+    if (timeout > 0) {
+        qemu_mutex_unlock_iothread();
+    }
+
+    tv.tv_sec = timeout / 1000;
+    tv.tv_usec = (timeout % 1000) * 1000;
+    ret = select(nfds + 1, &rfds, &wfds, &xfds, &tv);
+
+    if (timeout > 0) {
+        qemu_mutex_lock_iothread();
+    }
+
+    glib_select_poll(&rfds, &wfds, &xfds, (ret < 0));
+    return ret;
+}
+#else
 /***********************************************************/
 /* Polling handling */
 
@@ -367,10 +392,11 @@ void qemu_del_wait_object(HANDLE handle, WaitObjectFunc *func, void *opaque)
     }
 }
 
-static void os_host_main_loop_wait(int *timeout)
+static int os_host_main_loop_wait(int timeout)
 {
     int ret, ret2, i;
     PollingEntry *pe;
+    static struct timeval tv0;
 
     /* XXX: need to suppress polling by better using win32 events */
     ret = 0;
@@ -382,7 +408,7 @@ static void os_host_main_loop_wait(int *timeout)
         WaitObjects *w = &wait_objects;
 
         qemu_mutex_unlock_iothread();
-        ret = WaitForMultipleObjects(w->num, w->events, FALSE, *timeout);
+        ret = WaitForMultipleObjects(w->num, w->events, FALSE, timeout);
         qemu_mutex_lock_iothread();
         if (WAIT_OBJECT_0 + 0 <= ret && ret <= WAIT_OBJECT_0 + w->num - 1) {
             if (w->func[ret - WAIT_OBJECT_0]) {
@@ -408,20 +434,14 @@ static void os_host_main_loop_wait(int *timeout)
         }
     }
 
-    *timeout = 0;
-}
-#else
-static inline void os_host_main_loop_wait(int *timeout)
-{
+    ret = select(nfds + 1, &rfds, &wfds, &xfds, &tv0);
+    return ret;
 }
 #endif
 
 int main_loop_wait(int nonblocking)
 {
-    fd_set rfds, wfds, xfds;
-    int ret, nfds;
-    struct timeval tv;
-    int timeout;
+    int ret, timeout;
 
     if (nonblocking) {
         timeout = 0;
@@ -441,24 +461,7 @@ int main_loop_wait(int nonblocking)
     slirp_select_fill(&nfds, &rfds, &wfds, &xfds);
 #endif
     qemu_iohandler_fill(&nfds, &rfds, &wfds, &xfds);
-
-    glib_select_fill(&nfds, &rfds, &wfds, &xfds, &timeout);
-    os_host_main_loop_wait(&timeout);
-
-    tv.tv_sec = timeout / 1000;
-    tv.tv_usec = (timeout % 1000) * 1000;
-
-    if (timeout > 0) {
-        qemu_mutex_unlock_iothread();
-    }
-
-    ret = select(nfds + 1, &rfds, &wfds, &xfds, &tv);
-
-    if (timeout > 0) {
-        qemu_mutex_lock_iothread();
-    }
-
-    glib_select_poll(&rfds, &wfds, &xfds, (ret < 0));
+    ret = os_host_main_loop_wait(timeout);
     qemu_iohandler_poll(&rfds, &wfds, &xfds, ret);
 #ifdef CONFIG_SLIRP
     slirp_select_poll(&rfds, &wfds, &xfds, (ret < 0));
commit 4dae83aeac63863af6b59f58552da68b35b1a40d
Author: Paolo Bonzini <pbonzini at redhat.com>
Date:   Tue Mar 20 10:49:17 2012 +0100

    main loop: use msec-based timeout in glib_select_fill
    
    The timeval-based timeout is not needed until we actually invoke select,
    so compute it only then.  Also group the two calls that modify the
    timeout, glib_select_fill and os_host_main_loop_wait.
    
    Signed-off-by: Paolo Bonzini <pbonzini at redhat.com>
    Signed-off-by: Blue Swirl <blauwirbel at gmail.com>

diff --git a/main-loop.c b/main-loop.c
index db23de0..a3fd993 100644
--- a/main-loop.c
+++ b/main-loop.c
@@ -224,11 +224,11 @@ 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)
+                             fd_set *xfds, int *cur_timeout)
 {
     GMainContext *context = g_main_context_default();
     int i;
-    int timeout = 0, cur_timeout;
+    int timeout = 0;
 
     g_main_context_prepare(context, &max_priority);
 
@@ -253,10 +253,8 @@ static void glib_select_fill(int *max_fd, fd_set *rfds, fd_set *wfds,
         }
     }
 
-    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;
+    if (timeout >= 0 && timeout < *cur_timeout) {
+        *cur_timeout = timeout;
     }
 }
 
@@ -432,11 +430,6 @@ int main_loop_wait(int nonblocking)
         qemu_bh_update_timeout(&timeout);
     }
 
-    os_host_main_loop_wait(&timeout);
-
-    tv.tv_sec = timeout / 1000;
-    tv.tv_usec = (timeout % 1000) * 1000;
-
     /* poll any events */
     /* XXX: separate device handlers from system ones */
     nfds = -1;
@@ -448,7 +441,12 @@ int main_loop_wait(int nonblocking)
     slirp_select_fill(&nfds, &rfds, &wfds, &xfds);
 #endif
     qemu_iohandler_fill(&nfds, &rfds, &wfds, &xfds);
-    glib_select_fill(&nfds, &rfds, &wfds, &xfds, &tv);
+
+    glib_select_fill(&nfds, &rfds, &wfds, &xfds, &timeout);
+    os_host_main_loop_wait(&timeout);
+
+    tv.tv_sec = timeout / 1000;
+    tv.tv_usec = (timeout % 1000) * 1000;
 
     if (timeout > 0) {
         qemu_mutex_unlock_iothread();
commit ab7ab3d74c357e73a37b241fba27ea7f0595c085
Author: Andreas Färber <afaerber at suse.de>
Date:   Thu Apr 5 01:29:40 2012 +0200

    target-sparc: QOM'ify CPU
    
    Embed CPUSPARCState as first member of SPARCCPU.
    Drop cpu_sparc_close() in favor of object_delete() and a finalizer.
    Let cpu_state_reset() call cpu_reset().
    
    Make TYPE_SPARC_CPU non-abstract for now.
    Distinguish between "sparc-cpu" and "sparc64-cpu".
    
    Signed-off-by: Andreas Färber <afaerber at suse.de>
    Signed-off-by: Blue Swirl <blauwirbel at gmail.com>

diff --git a/target-sparc/cpu-qom.h b/target-sparc/cpu-qom.h
new file mode 100644
index 0000000..3d3ac0f
--- /dev/null
+++ b/target-sparc/cpu-qom.h
@@ -0,0 +1,75 @@
+/*
+ * QEMU SPARC CPU
+ *
+ * Copyright (c) 2012 SUSE LINUX Products GmbH
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, see
+ * <http://www.gnu.org/licenses/lgpl-2.1.html>
+ */
+#ifndef QEMU_SPARC_CPU_QOM_H
+#define QEMU_SPARC_CPU_QOM_H
+
+#include "qemu/cpu.h"
+#include "cpu.h"
+
+#ifdef TARGET_SPARC64
+#define TYPE_SPARC_CPU "sparc64-cpu"
+#else
+#define TYPE_SPARC_CPU "sparc-cpu"
+#endif
+
+#define SPARC_CPU_CLASS(klass) \
+    OBJECT_CLASS_CHECK(SPARCCPUClass, (klass), TYPE_SPARC_CPU)
+#define SPARC_CPU(obj) \
+    OBJECT_CHECK(SPARCCPU, (obj), TYPE_SPARC_CPU)
+#define SPARC_CPU_GET_CLASS(obj) \
+    OBJECT_GET_CLASS(SPARCCPUClass, (obj), TYPE_SPARC_CPU)
+
+/**
+ * SPARCCPUClass:
+ * @parent_reset: The parent class' reset handler.
+ *
+ * A SPARC CPU model.
+ */
+typedef struct SPARCCPUClass {
+    /*< private >*/
+    CPUClass parent_class;
+    /*< public >*/
+
+    void (*parent_reset)(CPUState *cpu);
+} SPARCCPUClass;
+
+/**
+ * SPARCCPU:
+ * @env: #CPUSPARCState
+ *
+ * A SPARC CPU.
+ */
+typedef struct SPARCCPU {
+    /*< private >*/
+    CPUState parent_obj;
+    /*< public >*/
+
+    CPUSPARCState env;
+} SPARCCPU;
+
+static inline SPARCCPU *sparc_env_get_cpu(CPUSPARCState *env)
+{
+    return SPARC_CPU(container_of(env, SPARCCPU, env));
+}
+
+#define ENV_GET_CPU(e) CPU(sparc_env_get_cpu(e))
+
+
+#endif
diff --git a/target-sparc/cpu.c b/target-sparc/cpu.c
index 5c03f0b..24f90f1 100644
--- a/target-sparc/cpu.c
+++ b/target-sparc/cpu.c
@@ -25,11 +25,23 @@ static int cpu_sparc_find_by_name(sparc_def_t *cpu_def, const char *cpu_model);
 
 void cpu_state_reset(CPUSPARCState *env)
 {
+    cpu_reset(ENV_GET_CPU(env));
+}
+
+/* CPUClass::reset() */
+static void sparc_cpu_reset(CPUState *s)
+{
+    SPARCCPU *cpu = SPARC_CPU(s);
+    SPARCCPUClass *scc = SPARC_CPU_GET_CLASS(cpu);
+    CPUSPARCState *env = &cpu->env;
+
     if (qemu_loglevel_mask(CPU_LOG_RESET)) {
         qemu_log("CPU Reset (CPU %d)\n", env->cpu_index);
         log_cpu_state(env, 0);
     }
 
+    scc->parent_reset(s);
+
     memset(env, 0, offsetof(CPUSPARCState, breakpoints));
     tlb_flush(env, 1);
     env->cwp = 0;
@@ -99,23 +111,18 @@ static int cpu_sparc_register(CPUSPARCState *env, const char *cpu_model)
     return 0;
 }
 
-static void cpu_sparc_close(CPUSPARCState *env)
-{
-    g_free(env->def);
-    g_free(env);
-}
-
 CPUSPARCState *cpu_sparc_init(const char *cpu_model)
 {
+    SPARCCPU *cpu;
     CPUSPARCState *env;
 
-    env = g_new0(CPUSPARCState, 1);
-    cpu_exec_init(env);
+    cpu = SPARC_CPU(object_new(TYPE_SPARC_CPU));
+    env = &cpu->env;
 
     gen_intermediate_code_init(env);
 
     if (cpu_sparc_register(env, cpu_model) < 0) {
-        cpu_sparc_close(env);
+        object_delete(OBJECT(cpu));
         return NULL;
     }
     qemu_init_vcpu(env);
@@ -847,3 +854,46 @@ void cpu_dump_state(CPUSPARCState *env, FILE *f, fprintf_function cpu_fprintf,
                 env->fsr, env->y);
 #endif
 }
+
+static void sparc_cpu_initfn(Object *obj)
+{
+    SPARCCPU *cpu = SPARC_CPU(obj);
+    CPUSPARCState *env = &cpu->env;
+
+    cpu_exec_init(env);
+}
+
+static void sparc_cpu_uninitfn(Object *obj)
+{
+    SPARCCPU *cpu = SPARC_CPU(obj);
+    CPUSPARCState *env = &cpu->env;
+
+    g_free(env->def);
+}
+
+static void sparc_cpu_class_init(ObjectClass *oc, void *data)
+{
+    SPARCCPUClass *scc = SPARC_CPU_CLASS(oc);
+    CPUClass *cc = CPU_CLASS(oc);
+
+    scc->parent_reset = cc->reset;
+    cc->reset = sparc_cpu_reset;
+}
+
+static const TypeInfo sparc_cpu_type_info = {
+    .name = TYPE_SPARC_CPU,
+    .parent = TYPE_CPU,
+    .instance_size = sizeof(SPARCCPU),
+    .instance_init = sparc_cpu_initfn,
+    .instance_finalize = sparc_cpu_uninitfn,
+    .abstract = false,
+    .class_size = sizeof(SPARCCPUClass),
+    .class_init = sparc_cpu_class_init,
+};
+
+static void sparc_cpu_register_types(void)
+{
+    type_register_static(&sparc_cpu_type_info);
+}
+
+type_init(sparc_cpu_register_types)
diff --git a/target-sparc/cpu.h b/target-sparc/cpu.h
index 885ad45..865288c 100644
--- a/target-sparc/cpu.h
+++ b/target-sparc/cpu.h
@@ -691,6 +691,7 @@ static inline void cpu_clone_regs(CPUSPARCState *env, target_ulong newsp)
 #endif
 
 #include "cpu-all.h"
+#include "cpu-qom.h"
 
 #ifdef TARGET_SPARC64
 /* sun4u.c */
commit 88ca012a1f0bb89d481e506eb4738382062da55f
Author: Andreas Färber <afaerber at suse.de>
Date:   Thu Apr 5 01:29:39 2012 +0200

    target-sparc: Rename cpu_init.c
    
    Align QOM'ified targets, with a view to simplify Makefile.target.
    
    Signed-off-by: Andreas Färber <afaerber at suse.de>
    Signed-off-by: Blue Swirl <blauwirbel at gmail.com>

diff --git a/Makefile.target b/Makefile.target
index 999a968..14c8fa1 100644
--- a/Makefile.target
+++ b/Makefile.target
@@ -96,7 +96,7 @@ libobj-$(TARGET_ARM) += cpu.o
 libobj-$(TARGET_S390X) += cpu.o
 ifeq ($(TARGET_BASE_ARCH), sparc)
 libobj-y += fop_helper.o cc_helper.o win_helper.o mmu_helper.o ldst_helper.o
-libobj-y += cpu_init.o
+libobj-y += cpu.o
 endif
 libobj-$(TARGET_SPARC) += int32_helper.o
 libobj-$(TARGET_SPARC64) += int64_helper.o
diff --git a/target-sparc/cpu.c b/target-sparc/cpu.c
new file mode 100644
index 0000000..5c03f0b
--- /dev/null
+++ b/target-sparc/cpu.c
@@ -0,0 +1,849 @@
+/*
+ * Sparc CPU init helpers
+ *
+ *  Copyright (c) 2003-2005 Fabrice Bellard
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include "cpu.h"
+
+//#define DEBUG_FEATURES
+
+static int cpu_sparc_find_by_name(sparc_def_t *cpu_def, const char *cpu_model);
+
+void cpu_state_reset(CPUSPARCState *env)
+{
+    if (qemu_loglevel_mask(CPU_LOG_RESET)) {
+        qemu_log("CPU Reset (CPU %d)\n", env->cpu_index);
+        log_cpu_state(env, 0);
+    }
+
+    memset(env, 0, offsetof(CPUSPARCState, breakpoints));
+    tlb_flush(env, 1);
+    env->cwp = 0;
+#ifndef TARGET_SPARC64
+    env->wim = 1;
+#endif
+    env->regwptr = env->regbase + (env->cwp * 16);
+    CC_OP = CC_OP_FLAGS;
+#if defined(CONFIG_USER_ONLY)
+#ifdef TARGET_SPARC64
+    env->cleanwin = env->nwindows - 2;
+    env->cansave = env->nwindows - 2;
+    env->pstate = PS_RMO | PS_PEF | PS_IE;
+    env->asi = 0x82; /* Primary no-fault */
+#endif
+#else
+#if !defined(TARGET_SPARC64)
+    env->psret = 0;
+    env->psrs = 1;
+    env->psrps = 1;
+#endif
+#ifdef TARGET_SPARC64
+    env->pstate = PS_PRIV|PS_RED|PS_PEF|PS_AG;
+    env->hpstate = cpu_has_hypervisor(env) ? HS_PRIV : 0;
+    env->tl = env->maxtl;
+    cpu_tsptr(env)->tt = TT_POWER_ON_RESET;
+    env->lsu = 0;
+#else
+    env->mmuregs[0] &= ~(MMU_E | MMU_NF);
+    env->mmuregs[0] |= env->def->mmu_bm;
+#endif
+    env->pc = 0;
+    env->npc = env->pc + 4;
+#endif
+    env->cache_control = 0;
+}
+
+static int cpu_sparc_register(CPUSPARCState *env, const char *cpu_model)
+{
+    sparc_def_t def1, *def = &def1;
+
+    if (cpu_sparc_find_by_name(def, cpu_model) < 0) {
+        return -1;
+    }
+
+    env->def = g_new0(sparc_def_t, 1);
+    memcpy(env->def, def, sizeof(*def));
+#if defined(CONFIG_USER_ONLY)
+    if ((env->def->features & CPU_FEATURE_FLOAT)) {
+        env->def->features |= CPU_FEATURE_FLOAT128;
+    }
+#endif
+    env->cpu_model_str = cpu_model;
+    env->version = def->iu_version;
+    env->fsr = def->fpu_version;
+    env->nwindows = def->nwindows;
+#if !defined(TARGET_SPARC64)
+    env->mmuregs[0] |= def->mmu_version;
+    cpu_sparc_set_id(env, 0);
+    env->mxccregs[7] |= def->mxcc_version;
+#else
+    env->mmu_version = def->mmu_version;
+    env->maxtl = def->maxtl;
+    env->version |= def->maxtl << 8;
+    env->version |= def->nwindows - 1;
+#endif
+    return 0;
+}
+
+static void cpu_sparc_close(CPUSPARCState *env)
+{
+    g_free(env->def);
+    g_free(env);
+}
+
+CPUSPARCState *cpu_sparc_init(const char *cpu_model)
+{
+    CPUSPARCState *env;
+
+    env = g_new0(CPUSPARCState, 1);
+    cpu_exec_init(env);
+
+    gen_intermediate_code_init(env);
+
+    if (cpu_sparc_register(env, cpu_model) < 0) {
+        cpu_sparc_close(env);
+        return NULL;
+    }
+    qemu_init_vcpu(env);
+
+    return env;
+}
+
+void cpu_sparc_set_id(CPUSPARCState *env, unsigned int cpu)
+{
+#if !defined(TARGET_SPARC64)
+    env->mxccregs[7] = ((cpu + 8) & 0xf) << 24;
+#endif
+}
+
+static const sparc_def_t sparc_defs[] = {
+#ifdef TARGET_SPARC64
+    {
+        .name = "Fujitsu Sparc64",
+        .iu_version = ((0x04ULL << 48) | (0x02ULL << 32) | (0ULL << 24)),
+        .fpu_version = 0x00000000,
+        .mmu_version = mmu_us_12,
+        .nwindows = 4,
+        .maxtl = 4,
+        .features = CPU_DEFAULT_FEATURES,
+    },
+    {
+        .name = "Fujitsu Sparc64 III",
+        .iu_version = ((0x04ULL << 48) | (0x03ULL << 32) | (0ULL << 24)),
+        .fpu_version = 0x00000000,
+        .mmu_version = mmu_us_12,
+        .nwindows = 5,
+        .maxtl = 4,
+        .features = CPU_DEFAULT_FEATURES,
+    },
+    {
+        .name = "Fujitsu Sparc64 IV",
+        .iu_version = ((0x04ULL << 48) | (0x04ULL << 32) | (0ULL << 24)),
+        .fpu_version = 0x00000000,
+        .mmu_version = mmu_us_12,
+        .nwindows = 8,
+        .maxtl = 5,
+        .features = CPU_DEFAULT_FEATURES,
+    },
+    {
+        .name = "Fujitsu Sparc64 V",
+        .iu_version = ((0x04ULL << 48) | (0x05ULL << 32) | (0x51ULL << 24)),
+        .fpu_version = 0x00000000,
+        .mmu_version = mmu_us_12,
+        .nwindows = 8,
+        .maxtl = 5,
+        .features = CPU_DEFAULT_FEATURES,
+    },
+    {
+        .name = "TI UltraSparc I",
+        .iu_version = ((0x17ULL << 48) | (0x10ULL << 32) | (0x40ULL << 24)),
+        .fpu_version = 0x00000000,
+        .mmu_version = mmu_us_12,
+        .nwindows = 8,
+        .maxtl = 5,
+        .features = CPU_DEFAULT_FEATURES,
+    },
+    {
+        .name = "TI UltraSparc II",
+        .iu_version = ((0x17ULL << 48) | (0x11ULL << 32) | (0x20ULL << 24)),
+        .fpu_version = 0x00000000,
+        .mmu_version = mmu_us_12,
+        .nwindows = 8,
+        .maxtl = 5,
+        .features = CPU_DEFAULT_FEATURES,
+    },
+    {
+        .name = "TI UltraSparc IIi",
+        .iu_version = ((0x17ULL << 48) | (0x12ULL << 32) | (0x91ULL << 24)),
+        .fpu_version = 0x00000000,
+        .mmu_version = mmu_us_12,
+        .nwindows = 8,
+        .maxtl = 5,
+        .features = CPU_DEFAULT_FEATURES,
+    },
+    {
+        .name = "TI UltraSparc IIe",
+        .iu_version = ((0x17ULL << 48) | (0x13ULL << 32) | (0x14ULL << 24)),
+        .fpu_version = 0x00000000,
+        .mmu_version = mmu_us_12,
+        .nwindows = 8,
+        .maxtl = 5,
+        .features = CPU_DEFAULT_FEATURES,
+    },
+    {
+        .name = "Sun UltraSparc III",
+        .iu_version = ((0x3eULL << 48) | (0x14ULL << 32) | (0x34ULL << 24)),
+        .fpu_version = 0x00000000,
+        .mmu_version = mmu_us_12,
+        .nwindows = 8,
+        .maxtl = 5,
+        .features = CPU_DEFAULT_FEATURES,
+    },
+    {
+        .name = "Sun UltraSparc III Cu",
+        .iu_version = ((0x3eULL << 48) | (0x15ULL << 32) | (0x41ULL << 24)),
+        .fpu_version = 0x00000000,
+        .mmu_version = mmu_us_3,
+        .nwindows = 8,
+        .maxtl = 5,
+        .features = CPU_DEFAULT_FEATURES,
+    },
+    {
+        .name = "Sun UltraSparc IIIi",
+        .iu_version = ((0x3eULL << 48) | (0x16ULL << 32) | (0x34ULL << 24)),
+        .fpu_version = 0x00000000,
+        .mmu_version = mmu_us_12,
+        .nwindows = 8,
+        .maxtl = 5,
+        .features = CPU_DEFAULT_FEATURES,
+    },
+    {
+        .name = "Sun UltraSparc IV",
+        .iu_version = ((0x3eULL << 48) | (0x18ULL << 32) | (0x31ULL << 24)),
+        .fpu_version = 0x00000000,
+        .mmu_version = mmu_us_4,
+        .nwindows = 8,
+        .maxtl = 5,
+        .features = CPU_DEFAULT_FEATURES,
+    },
+    {
+        .name = "Sun UltraSparc IV+",
+        .iu_version = ((0x3eULL << 48) | (0x19ULL << 32) | (0x22ULL << 24)),
+        .fpu_version = 0x00000000,
+        .mmu_version = mmu_us_12,
+        .nwindows = 8,
+        .maxtl = 5,
+        .features = CPU_DEFAULT_FEATURES | CPU_FEATURE_CMT,
+    },
+    {
+        .name = "Sun UltraSparc IIIi+",
+        .iu_version = ((0x3eULL << 48) | (0x22ULL << 32) | (0ULL << 24)),
+        .fpu_version = 0x00000000,
+        .mmu_version = mmu_us_3,
+        .nwindows = 8,
+        .maxtl = 5,
+        .features = CPU_DEFAULT_FEATURES,
+    },
+    {
+        .name = "Sun UltraSparc T1",
+        /* defined in sparc_ifu_fdp.v and ctu.h */
+        .iu_version = ((0x3eULL << 48) | (0x23ULL << 32) | (0x02ULL << 24)),
+        .fpu_version = 0x00000000,
+        .mmu_version = mmu_sun4v,
+        .nwindows = 8,
+        .maxtl = 6,
+        .features = CPU_DEFAULT_FEATURES | CPU_FEATURE_HYPV | CPU_FEATURE_CMT
+        | CPU_FEATURE_GL,
+    },
+    {
+        .name = "Sun UltraSparc T2",
+        /* defined in tlu_asi_ctl.v and n2_revid_cust.v */
+        .iu_version = ((0x3eULL << 48) | (0x24ULL << 32) | (0x02ULL << 24)),
+        .fpu_version = 0x00000000,
+        .mmu_version = mmu_sun4v,
+        .nwindows = 8,
+        .maxtl = 6,
+        .features = CPU_DEFAULT_FEATURES | CPU_FEATURE_HYPV | CPU_FEATURE_CMT
+        | CPU_FEATURE_GL,
+    },
+    {
+        .name = "NEC UltraSparc I",
+        .iu_version = ((0x22ULL << 48) | (0x10ULL << 32) | (0x40ULL << 24)),
+        .fpu_version = 0x00000000,
+        .mmu_version = mmu_us_12,
+        .nwindows = 8,
+        .maxtl = 5,
+        .features = CPU_DEFAULT_FEATURES,
+    },
+#else
+    {
+        .name = "Fujitsu MB86900",
+        .iu_version = 0x00 << 24, /* Impl 0, ver 0 */
+        .fpu_version = 4 << 17, /* FPU version 4 (Meiko) */
+        .mmu_version = 0x00 << 24, /* Impl 0, ver 0 */
+        .mmu_bm = 0x00004000,
+        .mmu_ctpr_mask = 0x007ffff0,
+        .mmu_cxr_mask = 0x0000003f,
+        .mmu_sfsr_mask = 0xffffffff,
+        .mmu_trcr_mask = 0xffffffff,
+        .nwindows = 7,
+        .features = CPU_FEATURE_FLOAT | CPU_FEATURE_FSMULD,
+    },
+    {
+        .name = "Fujitsu MB86904",
+        .iu_version = 0x04 << 24, /* Impl 0, ver 4 */
+        .fpu_version = 4 << 17, /* FPU version 4 (Meiko) */
+        .mmu_version = 0x04 << 24, /* Impl 0, ver 4 */
+        .mmu_bm = 0x00004000,
+        .mmu_ctpr_mask = 0x00ffffc0,
+        .mmu_cxr_mask = 0x000000ff,
+        .mmu_sfsr_mask = 0x00016fff,
+        .mmu_trcr_mask = 0x00ffffff,
+        .nwindows = 8,
+        .features = CPU_DEFAULT_FEATURES,
+    },
+    {
+        .name = "Fujitsu MB86907",
+        .iu_version = 0x05 << 24, /* Impl 0, ver 5 */
+        .fpu_version = 4 << 17, /* FPU version 4 (Meiko) */
+        .mmu_version = 0x05 << 24, /* Impl 0, ver 5 */
+        .mmu_bm = 0x00004000,
+        .mmu_ctpr_mask = 0xffffffc0,
+        .mmu_cxr_mask = 0x000000ff,
+        .mmu_sfsr_mask = 0x00016fff,
+        .mmu_trcr_mask = 0xffffffff,
+        .nwindows = 8,
+        .features = CPU_DEFAULT_FEATURES,
+    },
+    {
+        .name = "LSI L64811",
+        .iu_version = 0x10 << 24, /* Impl 1, ver 0 */
+        .fpu_version = 1 << 17, /* FPU version 1 (LSI L64814) */
+        .mmu_version = 0x10 << 24,
+        .mmu_bm = 0x00004000,
+        .mmu_ctpr_mask = 0x007ffff0,
+        .mmu_cxr_mask = 0x0000003f,
+        .mmu_sfsr_mask = 0xffffffff,
+        .mmu_trcr_mask = 0xffffffff,
+        .nwindows = 8,
+        .features = CPU_FEATURE_FLOAT | CPU_FEATURE_SWAP | CPU_FEATURE_FSQRT |
+        CPU_FEATURE_FSMULD,
+    },
+    {
+        .name = "Cypress CY7C601",
+        .iu_version = 0x11 << 24, /* Impl 1, ver 1 */
+        .fpu_version = 3 << 17, /* FPU version 3 (Cypress CY7C602) */
+        .mmu_version = 0x10 << 24,
+        .mmu_bm = 0x00004000,
+        .mmu_ctpr_mask = 0x007ffff0,
+        .mmu_cxr_mask = 0x0000003f,
+        .mmu_sfsr_mask = 0xffffffff,
+        .mmu_trcr_mask = 0xffffffff,
+        .nwindows = 8,
+        .features = CPU_FEATURE_FLOAT | CPU_FEATURE_SWAP | CPU_FEATURE_FSQRT |
+        CPU_FEATURE_FSMULD,
+    },
+    {
+        .name = "Cypress CY7C611",
+        .iu_version = 0x13 << 24, /* Impl 1, ver 3 */
+        .fpu_version = 3 << 17, /* FPU version 3 (Cypress CY7C602) */
+        .mmu_version = 0x10 << 24,
+        .mmu_bm = 0x00004000,
+        .mmu_ctpr_mask = 0x007ffff0,
+        .mmu_cxr_mask = 0x0000003f,
+        .mmu_sfsr_mask = 0xffffffff,
+        .mmu_trcr_mask = 0xffffffff,
+        .nwindows = 8,
+        .features = CPU_FEATURE_FLOAT | CPU_FEATURE_SWAP | CPU_FEATURE_FSQRT |
+        CPU_FEATURE_FSMULD,
+    },
+    {
+        .name = "TI MicroSparc I",
+        .iu_version = 0x41000000,
+        .fpu_version = 4 << 17,
+        .mmu_version = 0x41000000,
+        .mmu_bm = 0x00004000,
+        .mmu_ctpr_mask = 0x007ffff0,
+        .mmu_cxr_mask = 0x0000003f,
+        .mmu_sfsr_mask = 0x00016fff,
+        .mmu_trcr_mask = 0x0000003f,
+        .nwindows = 7,
+        .features = CPU_FEATURE_FLOAT | CPU_FEATURE_SWAP | CPU_FEATURE_MUL |
+        CPU_FEATURE_DIV | CPU_FEATURE_FLUSH | CPU_FEATURE_FSQRT |
+        CPU_FEATURE_FMUL,
+    },
+    {
+        .name = "TI MicroSparc II",
+        .iu_version = 0x42000000,
+        .fpu_version = 4 << 17,
+        .mmu_version = 0x02000000,
+        .mmu_bm = 0x00004000,
+        .mmu_ctpr_mask = 0x00ffffc0,
+        .mmu_cxr_mask = 0x000000ff,
+        .mmu_sfsr_mask = 0x00016fff,
+        .mmu_trcr_mask = 0x00ffffff,
+        .nwindows = 8,
+        .features = CPU_DEFAULT_FEATURES,
+    },
+    {
+        .name = "TI MicroSparc IIep",
+        .iu_version = 0x42000000,
+        .fpu_version = 4 << 17,
+        .mmu_version = 0x04000000,
+        .mmu_bm = 0x00004000,
+        .mmu_ctpr_mask = 0x00ffffc0,
+        .mmu_cxr_mask = 0x000000ff,
+        .mmu_sfsr_mask = 0x00016bff,
+        .mmu_trcr_mask = 0x00ffffff,
+        .nwindows = 8,
+        .features = CPU_DEFAULT_FEATURES,
+    },
+    {
+        .name = "TI SuperSparc 40", /* STP1020NPGA */
+        .iu_version = 0x41000000, /* SuperSPARC 2.x */
+        .fpu_version = 0 << 17,
+        .mmu_version = 0x00000800, /* SuperSPARC 2.x, no MXCC */
+        .mmu_bm = 0x00002000,
+        .mmu_ctpr_mask = 0xffffffc0,
+        .mmu_cxr_mask = 0x0000ffff,
+        .mmu_sfsr_mask = 0xffffffff,
+        .mmu_trcr_mask = 0xffffffff,
+        .nwindows = 8,
+        .features = CPU_DEFAULT_FEATURES,
+    },
+    {
+        .name = "TI SuperSparc 50", /* STP1020PGA */
+        .iu_version = 0x40000000, /* SuperSPARC 3.x */
+        .fpu_version = 0 << 17,
+        .mmu_version = 0x01000800, /* SuperSPARC 3.x, no MXCC */
+        .mmu_bm = 0x00002000,
+        .mmu_ctpr_mask = 0xffffffc0,
+        .mmu_cxr_mask = 0x0000ffff,
+        .mmu_sfsr_mask = 0xffffffff,
+        .mmu_trcr_mask = 0xffffffff,
+        .nwindows = 8,
+        .features = CPU_DEFAULT_FEATURES,
+    },
+    {
+        .name = "TI SuperSparc 51",
+        .iu_version = 0x40000000, /* SuperSPARC 3.x */
+        .fpu_version = 0 << 17,
+        .mmu_version = 0x01000000, /* SuperSPARC 3.x, MXCC */
+        .mmu_bm = 0x00002000,
+        .mmu_ctpr_mask = 0xffffffc0,
+        .mmu_cxr_mask = 0x0000ffff,
+        .mmu_sfsr_mask = 0xffffffff,
+        .mmu_trcr_mask = 0xffffffff,
+        .mxcc_version = 0x00000104,
+        .nwindows = 8,
+        .features = CPU_DEFAULT_FEATURES,
+    },
+    {
+        .name = "TI SuperSparc 60", /* STP1020APGA */
+        .iu_version = 0x40000000, /* SuperSPARC 3.x */
+        .fpu_version = 0 << 17,
+        .mmu_version = 0x01000800, /* SuperSPARC 3.x, no MXCC */
+        .mmu_bm = 0x00002000,
+        .mmu_ctpr_mask = 0xffffffc0,
+        .mmu_cxr_mask = 0x0000ffff,
+        .mmu_sfsr_mask = 0xffffffff,
+        .mmu_trcr_mask = 0xffffffff,
+        .nwindows = 8,
+        .features = CPU_DEFAULT_FEATURES,
+    },
+    {
+        .name = "TI SuperSparc 61",
+        .iu_version = 0x44000000, /* SuperSPARC 3.x */
+        .fpu_version = 0 << 17,
+        .mmu_version = 0x01000000, /* SuperSPARC 3.x, MXCC */
+        .mmu_bm = 0x00002000,
+        .mmu_ctpr_mask = 0xffffffc0,
+        .mmu_cxr_mask = 0x0000ffff,
+        .mmu_sfsr_mask = 0xffffffff,
+        .mmu_trcr_mask = 0xffffffff,
+        .mxcc_version = 0x00000104,
+        .nwindows = 8,
+        .features = CPU_DEFAULT_FEATURES,
+    },
+    {
+        .name = "TI SuperSparc II",
+        .iu_version = 0x40000000, /* SuperSPARC II 1.x */
+        .fpu_version = 0 << 17,
+        .mmu_version = 0x08000000, /* SuperSPARC II 1.x, MXCC */
+        .mmu_bm = 0x00002000,
+        .mmu_ctpr_mask = 0xffffffc0,
+        .mmu_cxr_mask = 0x0000ffff,
+        .mmu_sfsr_mask = 0xffffffff,
+        .mmu_trcr_mask = 0xffffffff,
+        .mxcc_version = 0x00000104,
+        .nwindows = 8,
+        .features = CPU_DEFAULT_FEATURES,
+    },
+    {
+        .name = "Ross RT625",
+        .iu_version = 0x1e000000,
+        .fpu_version = 1 << 17,
+        .mmu_version = 0x1e000000,
+        .mmu_bm = 0x00004000,
+        .mmu_ctpr_mask = 0x007ffff0,
+        .mmu_cxr_mask = 0x0000003f,
+        .mmu_sfsr_mask = 0xffffffff,
+        .mmu_trcr_mask = 0xffffffff,
+        .nwindows = 8,
+        .features = CPU_DEFAULT_FEATURES,
+    },
+    {
+        .name = "Ross RT620",
+        .iu_version = 0x1f000000,
+        .fpu_version = 1 << 17,
+        .mmu_version = 0x1f000000,
+        .mmu_bm = 0x00004000,
+        .mmu_ctpr_mask = 0x007ffff0,
+        .mmu_cxr_mask = 0x0000003f,
+        .mmu_sfsr_mask = 0xffffffff,
+        .mmu_trcr_mask = 0xffffffff,
+        .nwindows = 8,
+        .features = CPU_DEFAULT_FEATURES,
+    },
+    {
+        .name = "BIT B5010",
+        .iu_version = 0x20000000,
+        .fpu_version = 0 << 17, /* B5010/B5110/B5120/B5210 */
+        .mmu_version = 0x20000000,
+        .mmu_bm = 0x00004000,
+        .mmu_ctpr_mask = 0x007ffff0,
+        .mmu_cxr_mask = 0x0000003f,
+        .mmu_sfsr_mask = 0xffffffff,
+        .mmu_trcr_mask = 0xffffffff,
+        .nwindows = 8,
+        .features = CPU_FEATURE_FLOAT | CPU_FEATURE_SWAP | CPU_FEATURE_FSQRT |
+        CPU_FEATURE_FSMULD,
+    },
+    {
+        .name = "Matsushita MN10501",
+        .iu_version = 0x50000000,
+        .fpu_version = 0 << 17,
+        .mmu_version = 0x50000000,
+        .mmu_bm = 0x00004000,
+        .mmu_ctpr_mask = 0x007ffff0,
+        .mmu_cxr_mask = 0x0000003f,
+        .mmu_sfsr_mask = 0xffffffff,
+        .mmu_trcr_mask = 0xffffffff,
+        .nwindows = 8,
+        .features = CPU_FEATURE_FLOAT | CPU_FEATURE_MUL | CPU_FEATURE_FSQRT |
+        CPU_FEATURE_FSMULD,
+    },
+    {
+        .name = "Weitek W8601",
+        .iu_version = 0x90 << 24, /* Impl 9, ver 0 */
+        .fpu_version = 3 << 17, /* FPU version 3 (Weitek WTL3170/2) */
+        .mmu_version = 0x10 << 24,
+        .mmu_bm = 0x00004000,
+        .mmu_ctpr_mask = 0x007ffff0,
+        .mmu_cxr_mask = 0x0000003f,
+        .mmu_sfsr_mask = 0xffffffff,
+        .mmu_trcr_mask = 0xffffffff,
+        .nwindows = 8,
+        .features = CPU_DEFAULT_FEATURES,
+    },
+    {
+        .name = "LEON2",
+        .iu_version = 0xf2000000,
+        .fpu_version = 4 << 17, /* FPU version 4 (Meiko) */
+        .mmu_version = 0xf2000000,
+        .mmu_bm = 0x00004000,
+        .mmu_ctpr_mask = 0x007ffff0,
+        .mmu_cxr_mask = 0x0000003f,
+        .mmu_sfsr_mask = 0xffffffff,
+        .mmu_trcr_mask = 0xffffffff,
+        .nwindows = 8,
+        .features = CPU_DEFAULT_FEATURES | CPU_FEATURE_TA0_SHUTDOWN,
+    },
+    {
+        .name = "LEON3",
+        .iu_version = 0xf3000000,
+        .fpu_version = 4 << 17, /* FPU version 4 (Meiko) */
+        .mmu_version = 0xf3000000,
+        .mmu_bm = 0x00000000,
+        .mmu_ctpr_mask = 0x007ffff0,
+        .mmu_cxr_mask = 0x0000003f,
+        .mmu_sfsr_mask = 0xffffffff,
+        .mmu_trcr_mask = 0xffffffff,
+        .nwindows = 8,
+        .features = CPU_DEFAULT_FEATURES | CPU_FEATURE_TA0_SHUTDOWN |
+        CPU_FEATURE_ASR17 | CPU_FEATURE_CACHE_CTRL,
+    },
+#endif
+};
+
+static const char * const feature_name[] = {
+    "float",
+    "float128",
+    "swap",
+    "mul",
+    "div",
+    "flush",
+    "fsqrt",
+    "fmul",
+    "vis1",
+    "vis2",
+    "fsmuld",
+    "hypv",
+    "cmt",
+    "gl",
+};
+
+static void print_features(FILE *f, fprintf_function cpu_fprintf,
+                           uint32_t features, const char *prefix)
+{
+    unsigned int i;
+
+    for (i = 0; i < ARRAY_SIZE(feature_name); i++) {
+        if (feature_name[i] && (features & (1 << i))) {
+            if (prefix) {
+                (*cpu_fprintf)(f, "%s", prefix);
+            }
+            (*cpu_fprintf)(f, "%s ", feature_name[i]);
+        }
+    }
+}
+
+static void add_flagname_to_bitmaps(const char *flagname, uint32_t *features)
+{
+    unsigned int i;
+
+    for (i = 0; i < ARRAY_SIZE(feature_name); i++) {
+        if (feature_name[i] && !strcmp(flagname, feature_name[i])) {
+            *features |= 1 << i;
+            return;
+        }
+    }
+    fprintf(stderr, "CPU feature %s not found\n", flagname);
+}
+
+static int cpu_sparc_find_by_name(sparc_def_t *cpu_def, const char *cpu_model)
+{
+    unsigned int i;
+    const sparc_def_t *def = NULL;
+    char *s = strdup(cpu_model);
+    char *featurestr, *name = strtok(s, ",");
+    uint32_t plus_features = 0;
+    uint32_t minus_features = 0;
+    uint64_t iu_version;
+    uint32_t fpu_version, mmu_version, nwindows;
+
+    for (i = 0; i < ARRAY_SIZE(sparc_defs); i++) {
+        if (strcasecmp(name, sparc_defs[i].name) == 0) {
+            def = &sparc_defs[i];
+        }
+    }
+    if (!def) {
+        goto error;
+    }
+    memcpy(cpu_def, def, sizeof(*def));
+
+    featurestr = strtok(NULL, ",");
+    while (featurestr) {
+        char *val;
+
+        if (featurestr[0] == '+') {
+            add_flagname_to_bitmaps(featurestr + 1, &plus_features);
+        } else if (featurestr[0] == '-') {
+            add_flagname_to_bitmaps(featurestr + 1, &minus_features);
+        } else if ((val = strchr(featurestr, '='))) {
+            *val = 0; val++;
+            if (!strcmp(featurestr, "iu_version")) {
+                char *err;
+
+                iu_version = strtoll(val, &err, 0);
+                if (!*val || *err) {
+                    fprintf(stderr, "bad numerical value %s\n", val);
+                    goto error;
+                }
+                cpu_def->iu_version = iu_version;
+#ifdef DEBUG_FEATURES
+                fprintf(stderr, "iu_version %" PRIx64 "\n", iu_version);
+#endif
+            } else if (!strcmp(featurestr, "fpu_version")) {
+                char *err;
+
+                fpu_version = strtol(val, &err, 0);
+                if (!*val || *err) {
+                    fprintf(stderr, "bad numerical value %s\n", val);
+                    goto error;
+                }
+                cpu_def->fpu_version = fpu_version;
+#ifdef DEBUG_FEATURES
+                fprintf(stderr, "fpu_version %x\n", fpu_version);
+#endif
+            } else if (!strcmp(featurestr, "mmu_version")) {
+                char *err;
+
+                mmu_version = strtol(val, &err, 0);
+                if (!*val || *err) {
+                    fprintf(stderr, "bad numerical value %s\n", val);
+                    goto error;
+                }
+                cpu_def->mmu_version = mmu_version;
+#ifdef DEBUG_FEATURES
+                fprintf(stderr, "mmu_version %x\n", mmu_version);
+#endif
+            } else if (!strcmp(featurestr, "nwindows")) {
+                char *err;
+
+                nwindows = strtol(val, &err, 0);
+                if (!*val || *err || nwindows > MAX_NWINDOWS ||
+                    nwindows < MIN_NWINDOWS) {
+                    fprintf(stderr, "bad numerical value %s\n", val);
+                    goto error;
+                }
+                cpu_def->nwindows = nwindows;
+#ifdef DEBUG_FEATURES
+                fprintf(stderr, "nwindows %d\n", nwindows);
+#endif
+            } else {
+                fprintf(stderr, "unrecognized feature %s\n", featurestr);
+                goto error;
+            }
+        } else {
+            fprintf(stderr, "feature string `%s' not in format "
+                    "(+feature|-feature|feature=xyz)\n", featurestr);
+            goto error;
+        }
+        featurestr = strtok(NULL, ",");
+    }
+    cpu_def->features |= plus_features;
+    cpu_def->features &= ~minus_features;
+#ifdef DEBUG_FEATURES
+    print_features(stderr, fprintf, cpu_def->features, NULL);
+#endif
+    free(s);
+    return 0;
+
+ error:
+    free(s);
+    return -1;
+}
+
+void sparc_cpu_list(FILE *f, fprintf_function cpu_fprintf)
+{
+    unsigned int i;
+
+    for (i = 0; i < ARRAY_SIZE(sparc_defs); i++) {
+        (*cpu_fprintf)(f, "Sparc %16s IU " TARGET_FMT_lx
+                       " FPU %08x MMU %08x NWINS %d ",
+                       sparc_defs[i].name,
+                       sparc_defs[i].iu_version,
+                       sparc_defs[i].fpu_version,
+                       sparc_defs[i].mmu_version,
+                       sparc_defs[i].nwindows);
+        print_features(f, cpu_fprintf, CPU_DEFAULT_FEATURES &
+                       ~sparc_defs[i].features, "-");
+        print_features(f, cpu_fprintf, ~CPU_DEFAULT_FEATURES &
+                       sparc_defs[i].features, "+");
+        (*cpu_fprintf)(f, "\n");
+    }
+    (*cpu_fprintf)(f, "Default CPU feature flags (use '-' to remove): ");
+    print_features(f, cpu_fprintf, CPU_DEFAULT_FEATURES, NULL);
+    (*cpu_fprintf)(f, "\n");
+    (*cpu_fprintf)(f, "Available CPU feature flags (use '+' to add): ");
+    print_features(f, cpu_fprintf, ~CPU_DEFAULT_FEATURES, NULL);
+    (*cpu_fprintf)(f, "\n");
+    (*cpu_fprintf)(f, "Numerical features (use '=' to set): iu_version "
+                   "fpu_version mmu_version nwindows\n");
+}
+
+static void cpu_print_cc(FILE *f, fprintf_function cpu_fprintf,
+                         uint32_t cc)
+{
+    cpu_fprintf(f, "%c%c%c%c", cc & PSR_NEG ? 'N' : '-',
+                cc & PSR_ZERO ? 'Z' : '-', cc & PSR_OVF ? 'V' : '-',
+                cc & PSR_CARRY ? 'C' : '-');
+}
+
+#ifdef TARGET_SPARC64
+#define REGS_PER_LINE 4
+#else
+#define REGS_PER_LINE 8
+#endif
+
+void cpu_dump_state(CPUSPARCState *env, FILE *f, fprintf_function cpu_fprintf,
+                    int flags)
+{
+    int i, x;
+
+    cpu_fprintf(f, "pc: " TARGET_FMT_lx "  npc: " TARGET_FMT_lx "\n", env->pc,
+                env->npc);
+    cpu_fprintf(f, "General Registers:\n");
+
+    for (i = 0; i < 8; i++) {
+        if (i % REGS_PER_LINE == 0) {
+            cpu_fprintf(f, "%%g%d-%d:", i, i + REGS_PER_LINE - 1);
+        }
+        cpu_fprintf(f, " " TARGET_FMT_lx, env->gregs[i]);
+        if (i % REGS_PER_LINE == REGS_PER_LINE - 1) {
+            cpu_fprintf(f, "\n");
+        }
+    }
+    cpu_fprintf(f, "\nCurrent Register Window:\n");
+    for (x = 0; x < 3; x++) {
+        for (i = 0; i < 8; i++) {
+            if (i % REGS_PER_LINE == 0) {
+                cpu_fprintf(f, "%%%c%d-%d: ",
+                            x == 0 ? 'o' : (x == 1 ? 'l' : 'i'),
+                            i, i + REGS_PER_LINE - 1);
+            }
+            cpu_fprintf(f, TARGET_FMT_lx " ", env->regwptr[i + x * 8]);
+            if (i % REGS_PER_LINE == REGS_PER_LINE - 1) {
+                cpu_fprintf(f, "\n");
+            }
+        }
+    }
+    cpu_fprintf(f, "\nFloating Point Registers:\n");
+    for (i = 0; i < TARGET_DPREGS; i++) {
+        if ((i & 3) == 0) {
+            cpu_fprintf(f, "%%f%02d:", i * 2);
+        }
+        cpu_fprintf(f, " %016" PRIx64, env->fpr[i].ll);
+        if ((i & 3) == 3) {
+            cpu_fprintf(f, "\n");
+        }
+    }
+#ifdef TARGET_SPARC64
+    cpu_fprintf(f, "pstate: %08x ccr: %02x (icc: ", env->pstate,
+                (unsigned)cpu_get_ccr(env));
+    cpu_print_cc(f, cpu_fprintf, cpu_get_ccr(env) << PSR_CARRY_SHIFT);
+    cpu_fprintf(f, " xcc: ");
+    cpu_print_cc(f, cpu_fprintf, cpu_get_ccr(env) << (PSR_CARRY_SHIFT - 4));
+    cpu_fprintf(f, ") asi: %02x tl: %d pil: %x\n", env->asi, env->tl,
+                env->psrpil);
+    cpu_fprintf(f, "cansave: %d canrestore: %d otherwin: %d wstate: %d "
+                "cleanwin: %d cwp: %d\n",
+                env->cansave, env->canrestore, env->otherwin, env->wstate,
+                env->cleanwin, env->nwindows - 1 - env->cwp);
+    cpu_fprintf(f, "fsr: " TARGET_FMT_lx " y: " TARGET_FMT_lx " fprs: "
+                TARGET_FMT_lx "\n", env->fsr, env->y, env->fprs);
+#else
+    cpu_fprintf(f, "psr: %08x (icc: ", cpu_get_psr(env));
+    cpu_print_cc(f, cpu_fprintf, cpu_get_psr(env));
+    cpu_fprintf(f, " SPE: %c%c%c) wim: %08x\n", env->psrs ? 'S' : '-',
+                env->psrps ? 'P' : '-', env->psret ? 'E' : '-',
+                env->wim);
+    cpu_fprintf(f, "fsr: " TARGET_FMT_lx " y: " TARGET_FMT_lx "\n",
+                env->fsr, env->y);
+#endif
+}
diff --git a/target-sparc/cpu_init.c b/target-sparc/cpu_init.c
deleted file mode 100644
index 5c03f0b..0000000
--- a/target-sparc/cpu_init.c
+++ /dev/null
@@ -1,849 +0,0 @@
-/*
- * Sparc CPU init helpers
- *
- *  Copyright (c) 2003-2005 Fabrice Bellard
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2 of the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, see <http://www.gnu.org/licenses/>.
- */
-
-#include "cpu.h"
-
-//#define DEBUG_FEATURES
-
-static int cpu_sparc_find_by_name(sparc_def_t *cpu_def, const char *cpu_model);
-
-void cpu_state_reset(CPUSPARCState *env)
-{
-    if (qemu_loglevel_mask(CPU_LOG_RESET)) {
-        qemu_log("CPU Reset (CPU %d)\n", env->cpu_index);
-        log_cpu_state(env, 0);
-    }
-
-    memset(env, 0, offsetof(CPUSPARCState, breakpoints));
-    tlb_flush(env, 1);
-    env->cwp = 0;
-#ifndef TARGET_SPARC64
-    env->wim = 1;
-#endif
-    env->regwptr = env->regbase + (env->cwp * 16);
-    CC_OP = CC_OP_FLAGS;
-#if defined(CONFIG_USER_ONLY)
-#ifdef TARGET_SPARC64
-    env->cleanwin = env->nwindows - 2;
-    env->cansave = env->nwindows - 2;
-    env->pstate = PS_RMO | PS_PEF | PS_IE;
-    env->asi = 0x82; /* Primary no-fault */
-#endif
-#else
-#if !defined(TARGET_SPARC64)
-    env->psret = 0;
-    env->psrs = 1;
-    env->psrps = 1;
-#endif
-#ifdef TARGET_SPARC64
-    env->pstate = PS_PRIV|PS_RED|PS_PEF|PS_AG;
-    env->hpstate = cpu_has_hypervisor(env) ? HS_PRIV : 0;
-    env->tl = env->maxtl;
-    cpu_tsptr(env)->tt = TT_POWER_ON_RESET;
-    env->lsu = 0;
-#else
-    env->mmuregs[0] &= ~(MMU_E | MMU_NF);
-    env->mmuregs[0] |= env->def->mmu_bm;
-#endif
-    env->pc = 0;
-    env->npc = env->pc + 4;
-#endif
-    env->cache_control = 0;
-}
-
-static int cpu_sparc_register(CPUSPARCState *env, const char *cpu_model)
-{
-    sparc_def_t def1, *def = &def1;
-
-    if (cpu_sparc_find_by_name(def, cpu_model) < 0) {
-        return -1;
-    }
-
-    env->def = g_new0(sparc_def_t, 1);
-    memcpy(env->def, def, sizeof(*def));
-#if defined(CONFIG_USER_ONLY)
-    if ((env->def->features & CPU_FEATURE_FLOAT)) {
-        env->def->features |= CPU_FEATURE_FLOAT128;
-    }
-#endif
-    env->cpu_model_str = cpu_model;
-    env->version = def->iu_version;
-    env->fsr = def->fpu_version;
-    env->nwindows = def->nwindows;
-#if !defined(TARGET_SPARC64)
-    env->mmuregs[0] |= def->mmu_version;
-    cpu_sparc_set_id(env, 0);
-    env->mxccregs[7] |= def->mxcc_version;
-#else
-    env->mmu_version = def->mmu_version;
-    env->maxtl = def->maxtl;
-    env->version |= def->maxtl << 8;
-    env->version |= def->nwindows - 1;
-#endif
-    return 0;
-}
-
-static void cpu_sparc_close(CPUSPARCState *env)
-{
-    g_free(env->def);
-    g_free(env);
-}
-
-CPUSPARCState *cpu_sparc_init(const char *cpu_model)
-{
-    CPUSPARCState *env;
-
-    env = g_new0(CPUSPARCState, 1);
-    cpu_exec_init(env);
-
-    gen_intermediate_code_init(env);
-
-    if (cpu_sparc_register(env, cpu_model) < 0) {
-        cpu_sparc_close(env);
-        return NULL;
-    }
-    qemu_init_vcpu(env);
-
-    return env;
-}
-
-void cpu_sparc_set_id(CPUSPARCState *env, unsigned int cpu)
-{
-#if !defined(TARGET_SPARC64)
-    env->mxccregs[7] = ((cpu + 8) & 0xf) << 24;
-#endif
-}
-
-static const sparc_def_t sparc_defs[] = {
-#ifdef TARGET_SPARC64
-    {
-        .name = "Fujitsu Sparc64",
-        .iu_version = ((0x04ULL << 48) | (0x02ULL << 32) | (0ULL << 24)),
-        .fpu_version = 0x00000000,
-        .mmu_version = mmu_us_12,
-        .nwindows = 4,
-        .maxtl = 4,
-        .features = CPU_DEFAULT_FEATURES,
-    },
-    {
-        .name = "Fujitsu Sparc64 III",
-        .iu_version = ((0x04ULL << 48) | (0x03ULL << 32) | (0ULL << 24)),
-        .fpu_version = 0x00000000,
-        .mmu_version = mmu_us_12,
-        .nwindows = 5,
-        .maxtl = 4,
-        .features = CPU_DEFAULT_FEATURES,
-    },
-    {
-        .name = "Fujitsu Sparc64 IV",
-        .iu_version = ((0x04ULL << 48) | (0x04ULL << 32) | (0ULL << 24)),
-        .fpu_version = 0x00000000,
-        .mmu_version = mmu_us_12,
-        .nwindows = 8,
-        .maxtl = 5,
-        .features = CPU_DEFAULT_FEATURES,
-    },
-    {
-        .name = "Fujitsu Sparc64 V",
-        .iu_version = ((0x04ULL << 48) | (0x05ULL << 32) | (0x51ULL << 24)),
-        .fpu_version = 0x00000000,
-        .mmu_version = mmu_us_12,
-        .nwindows = 8,
-        .maxtl = 5,
-        .features = CPU_DEFAULT_FEATURES,
-    },
-    {
-        .name = "TI UltraSparc I",
-        .iu_version = ((0x17ULL << 48) | (0x10ULL << 32) | (0x40ULL << 24)),
-        .fpu_version = 0x00000000,
-        .mmu_version = mmu_us_12,
-        .nwindows = 8,
-        .maxtl = 5,
-        .features = CPU_DEFAULT_FEATURES,
-    },
-    {
-        .name = "TI UltraSparc II",
-        .iu_version = ((0x17ULL << 48) | (0x11ULL << 32) | (0x20ULL << 24)),
-        .fpu_version = 0x00000000,
-        .mmu_version = mmu_us_12,
-        .nwindows = 8,
-        .maxtl = 5,
-        .features = CPU_DEFAULT_FEATURES,
-    },
-    {
-        .name = "TI UltraSparc IIi",
-        .iu_version = ((0x17ULL << 48) | (0x12ULL << 32) | (0x91ULL << 24)),
-        .fpu_version = 0x00000000,
-        .mmu_version = mmu_us_12,
-        .nwindows = 8,
-        .maxtl = 5,
-        .features = CPU_DEFAULT_FEATURES,
-    },
-    {
-        .name = "TI UltraSparc IIe",
-        .iu_version = ((0x17ULL << 48) | (0x13ULL << 32) | (0x14ULL << 24)),
-        .fpu_version = 0x00000000,
-        .mmu_version = mmu_us_12,
-        .nwindows = 8,
-        .maxtl = 5,
-        .features = CPU_DEFAULT_FEATURES,
-    },
-    {
-        .name = "Sun UltraSparc III",
-        .iu_version = ((0x3eULL << 48) | (0x14ULL << 32) | (0x34ULL << 24)),
-        .fpu_version = 0x00000000,
-        .mmu_version = mmu_us_12,
-        .nwindows = 8,
-        .maxtl = 5,
-        .features = CPU_DEFAULT_FEATURES,
-    },
-    {
-        .name = "Sun UltraSparc III Cu",
-        .iu_version = ((0x3eULL << 48) | (0x15ULL << 32) | (0x41ULL << 24)),
-        .fpu_version = 0x00000000,
-        .mmu_version = mmu_us_3,
-        .nwindows = 8,
-        .maxtl = 5,
-        .features = CPU_DEFAULT_FEATURES,
-    },
-    {
-        .name = "Sun UltraSparc IIIi",
-        .iu_version = ((0x3eULL << 48) | (0x16ULL << 32) | (0x34ULL << 24)),
-        .fpu_version = 0x00000000,
-        .mmu_version = mmu_us_12,
-        .nwindows = 8,
-        .maxtl = 5,
-        .features = CPU_DEFAULT_FEATURES,
-    },
-    {
-        .name = "Sun UltraSparc IV",
-        .iu_version = ((0x3eULL << 48) | (0x18ULL << 32) | (0x31ULL << 24)),
-        .fpu_version = 0x00000000,
-        .mmu_version = mmu_us_4,
-        .nwindows = 8,
-        .maxtl = 5,
-        .features = CPU_DEFAULT_FEATURES,
-    },
-    {
-        .name = "Sun UltraSparc IV+",
-        .iu_version = ((0x3eULL << 48) | (0x19ULL << 32) | (0x22ULL << 24)),
-        .fpu_version = 0x00000000,
-        .mmu_version = mmu_us_12,
-        .nwindows = 8,
-        .maxtl = 5,
-        .features = CPU_DEFAULT_FEATURES | CPU_FEATURE_CMT,
-    },
-    {
-        .name = "Sun UltraSparc IIIi+",
-        .iu_version = ((0x3eULL << 48) | (0x22ULL << 32) | (0ULL << 24)),
-        .fpu_version = 0x00000000,
-        .mmu_version = mmu_us_3,
-        .nwindows = 8,
-        .maxtl = 5,
-        .features = CPU_DEFAULT_FEATURES,
-    },
-    {
-        .name = "Sun UltraSparc T1",
-        /* defined in sparc_ifu_fdp.v and ctu.h */
-        .iu_version = ((0x3eULL << 48) | (0x23ULL << 32) | (0x02ULL << 24)),
-        .fpu_version = 0x00000000,
-        .mmu_version = mmu_sun4v,
-        .nwindows = 8,
-        .maxtl = 6,
-        .features = CPU_DEFAULT_FEATURES | CPU_FEATURE_HYPV | CPU_FEATURE_CMT
-        | CPU_FEATURE_GL,
-    },
-    {
-        .name = "Sun UltraSparc T2",
-        /* defined in tlu_asi_ctl.v and n2_revid_cust.v */
-        .iu_version = ((0x3eULL << 48) | (0x24ULL << 32) | (0x02ULL << 24)),
-        .fpu_version = 0x00000000,
-        .mmu_version = mmu_sun4v,
-        .nwindows = 8,
-        .maxtl = 6,
-        .features = CPU_DEFAULT_FEATURES | CPU_FEATURE_HYPV | CPU_FEATURE_CMT
-        | CPU_FEATURE_GL,
-    },
-    {
-        .name = "NEC UltraSparc I",
-        .iu_version = ((0x22ULL << 48) | (0x10ULL << 32) | (0x40ULL << 24)),
-        .fpu_version = 0x00000000,
-        .mmu_version = mmu_us_12,
-        .nwindows = 8,
-        .maxtl = 5,
-        .features = CPU_DEFAULT_FEATURES,
-    },
-#else
-    {
-        .name = "Fujitsu MB86900",
-        .iu_version = 0x00 << 24, /* Impl 0, ver 0 */
-        .fpu_version = 4 << 17, /* FPU version 4 (Meiko) */
-        .mmu_version = 0x00 << 24, /* Impl 0, ver 0 */
-        .mmu_bm = 0x00004000,
-        .mmu_ctpr_mask = 0x007ffff0,
-        .mmu_cxr_mask = 0x0000003f,
-        .mmu_sfsr_mask = 0xffffffff,
-        .mmu_trcr_mask = 0xffffffff,
-        .nwindows = 7,
-        .features = CPU_FEATURE_FLOAT | CPU_FEATURE_FSMULD,
-    },
-    {
-        .name = "Fujitsu MB86904",
-        .iu_version = 0x04 << 24, /* Impl 0, ver 4 */
-        .fpu_version = 4 << 17, /* FPU version 4 (Meiko) */
-        .mmu_version = 0x04 << 24, /* Impl 0, ver 4 */
-        .mmu_bm = 0x00004000,
-        .mmu_ctpr_mask = 0x00ffffc0,
-        .mmu_cxr_mask = 0x000000ff,
-        .mmu_sfsr_mask = 0x00016fff,
-        .mmu_trcr_mask = 0x00ffffff,
-        .nwindows = 8,
-        .features = CPU_DEFAULT_FEATURES,
-    },
-    {
-        .name = "Fujitsu MB86907",
-        .iu_version = 0x05 << 24, /* Impl 0, ver 5 */
-        .fpu_version = 4 << 17, /* FPU version 4 (Meiko) */
-        .mmu_version = 0x05 << 24, /* Impl 0, ver 5 */
-        .mmu_bm = 0x00004000,
-        .mmu_ctpr_mask = 0xffffffc0,
-        .mmu_cxr_mask = 0x000000ff,
-        .mmu_sfsr_mask = 0x00016fff,
-        .mmu_trcr_mask = 0xffffffff,
-        .nwindows = 8,
-        .features = CPU_DEFAULT_FEATURES,
-    },
-    {
-        .name = "LSI L64811",
-        .iu_version = 0x10 << 24, /* Impl 1, ver 0 */
-        .fpu_version = 1 << 17, /* FPU version 1 (LSI L64814) */
-        .mmu_version = 0x10 << 24,
-        .mmu_bm = 0x00004000,
-        .mmu_ctpr_mask = 0x007ffff0,
-        .mmu_cxr_mask = 0x0000003f,
-        .mmu_sfsr_mask = 0xffffffff,
-        .mmu_trcr_mask = 0xffffffff,
-        .nwindows = 8,
-        .features = CPU_FEATURE_FLOAT | CPU_FEATURE_SWAP | CPU_FEATURE_FSQRT |
-        CPU_FEATURE_FSMULD,
-    },
-    {
-        .name = "Cypress CY7C601",
-        .iu_version = 0x11 << 24, /* Impl 1, ver 1 */
-        .fpu_version = 3 << 17, /* FPU version 3 (Cypress CY7C602) */
-        .mmu_version = 0x10 << 24,
-        .mmu_bm = 0x00004000,
-        .mmu_ctpr_mask = 0x007ffff0,
-        .mmu_cxr_mask = 0x0000003f,
-        .mmu_sfsr_mask = 0xffffffff,
-        .mmu_trcr_mask = 0xffffffff,
-        .nwindows = 8,
-        .features = CPU_FEATURE_FLOAT | CPU_FEATURE_SWAP | CPU_FEATURE_FSQRT |
-        CPU_FEATURE_FSMULD,
-    },
-    {
-        .name = "Cypress CY7C611",
-        .iu_version = 0x13 << 24, /* Impl 1, ver 3 */
-        .fpu_version = 3 << 17, /* FPU version 3 (Cypress CY7C602) */
-        .mmu_version = 0x10 << 24,
-        .mmu_bm = 0x00004000,
-        .mmu_ctpr_mask = 0x007ffff0,
-        .mmu_cxr_mask = 0x0000003f,
-        .mmu_sfsr_mask = 0xffffffff,
-        .mmu_trcr_mask = 0xffffffff,
-        .nwindows = 8,
-        .features = CPU_FEATURE_FLOAT | CPU_FEATURE_SWAP | CPU_FEATURE_FSQRT |
-        CPU_FEATURE_FSMULD,
-    },
-    {
-        .name = "TI MicroSparc I",
-        .iu_version = 0x41000000,
-        .fpu_version = 4 << 17,
-        .mmu_version = 0x41000000,
-        .mmu_bm = 0x00004000,
-        .mmu_ctpr_mask = 0x007ffff0,
-        .mmu_cxr_mask = 0x0000003f,
-        .mmu_sfsr_mask = 0x00016fff,
-        .mmu_trcr_mask = 0x0000003f,
-        .nwindows = 7,
-        .features = CPU_FEATURE_FLOAT | CPU_FEATURE_SWAP | CPU_FEATURE_MUL |
-        CPU_FEATURE_DIV | CPU_FEATURE_FLUSH | CPU_FEATURE_FSQRT |
-        CPU_FEATURE_FMUL,
-    },
-    {
-        .name = "TI MicroSparc II",
-        .iu_version = 0x42000000,
-        .fpu_version = 4 << 17,
-        .mmu_version = 0x02000000,
-        .mmu_bm = 0x00004000,
-        .mmu_ctpr_mask = 0x00ffffc0,
-        .mmu_cxr_mask = 0x000000ff,
-        .mmu_sfsr_mask = 0x00016fff,
-        .mmu_trcr_mask = 0x00ffffff,
-        .nwindows = 8,
-        .features = CPU_DEFAULT_FEATURES,
-    },
-    {
-        .name = "TI MicroSparc IIep",
-        .iu_version = 0x42000000,
-        .fpu_version = 4 << 17,
-        .mmu_version = 0x04000000,
-        .mmu_bm = 0x00004000,
-        .mmu_ctpr_mask = 0x00ffffc0,
-        .mmu_cxr_mask = 0x000000ff,
-        .mmu_sfsr_mask = 0x00016bff,
-        .mmu_trcr_mask = 0x00ffffff,
-        .nwindows = 8,
-        .features = CPU_DEFAULT_FEATURES,
-    },
-    {
-        .name = "TI SuperSparc 40", /* STP1020NPGA */
-        .iu_version = 0x41000000, /* SuperSPARC 2.x */
-        .fpu_version = 0 << 17,
-        .mmu_version = 0x00000800, /* SuperSPARC 2.x, no MXCC */
-        .mmu_bm = 0x00002000,
-        .mmu_ctpr_mask = 0xffffffc0,
-        .mmu_cxr_mask = 0x0000ffff,
-        .mmu_sfsr_mask = 0xffffffff,
-        .mmu_trcr_mask = 0xffffffff,
-        .nwindows = 8,
-        .features = CPU_DEFAULT_FEATURES,
-    },
-    {
-        .name = "TI SuperSparc 50", /* STP1020PGA */
-        .iu_version = 0x40000000, /* SuperSPARC 3.x */
-        .fpu_version = 0 << 17,
-        .mmu_version = 0x01000800, /* SuperSPARC 3.x, no MXCC */
-        .mmu_bm = 0x00002000,
-        .mmu_ctpr_mask = 0xffffffc0,
-        .mmu_cxr_mask = 0x0000ffff,
-        .mmu_sfsr_mask = 0xffffffff,
-        .mmu_trcr_mask = 0xffffffff,
-        .nwindows = 8,
-        .features = CPU_DEFAULT_FEATURES,
-    },
-    {
-        .name = "TI SuperSparc 51",
-        .iu_version = 0x40000000, /* SuperSPARC 3.x */
-        .fpu_version = 0 << 17,
-        .mmu_version = 0x01000000, /* SuperSPARC 3.x, MXCC */
-        .mmu_bm = 0x00002000,
-        .mmu_ctpr_mask = 0xffffffc0,
-        .mmu_cxr_mask = 0x0000ffff,
-        .mmu_sfsr_mask = 0xffffffff,
-        .mmu_trcr_mask = 0xffffffff,
-        .mxcc_version = 0x00000104,
-        .nwindows = 8,
-        .features = CPU_DEFAULT_FEATURES,
-    },
-    {
-        .name = "TI SuperSparc 60", /* STP1020APGA */
-        .iu_version = 0x40000000, /* SuperSPARC 3.x */
-        .fpu_version = 0 << 17,
-        .mmu_version = 0x01000800, /* SuperSPARC 3.x, no MXCC */
-        .mmu_bm = 0x00002000,
-        .mmu_ctpr_mask = 0xffffffc0,
-        .mmu_cxr_mask = 0x0000ffff,
-        .mmu_sfsr_mask = 0xffffffff,
-        .mmu_trcr_mask = 0xffffffff,
-        .nwindows = 8,
-        .features = CPU_DEFAULT_FEATURES,
-    },
-    {
-        .name = "TI SuperSparc 61",
-        .iu_version = 0x44000000, /* SuperSPARC 3.x */
-        .fpu_version = 0 << 17,
-        .mmu_version = 0x01000000, /* SuperSPARC 3.x, MXCC */
-        .mmu_bm = 0x00002000,
-        .mmu_ctpr_mask = 0xffffffc0,
-        .mmu_cxr_mask = 0x0000ffff,
-        .mmu_sfsr_mask = 0xffffffff,
-        .mmu_trcr_mask = 0xffffffff,
-        .mxcc_version = 0x00000104,
-        .nwindows = 8,
-        .features = CPU_DEFAULT_FEATURES,
-    },
-    {
-        .name = "TI SuperSparc II",
-        .iu_version = 0x40000000, /* SuperSPARC II 1.x */
-        .fpu_version = 0 << 17,
-        .mmu_version = 0x08000000, /* SuperSPARC II 1.x, MXCC */
-        .mmu_bm = 0x00002000,
-        .mmu_ctpr_mask = 0xffffffc0,
-        .mmu_cxr_mask = 0x0000ffff,
-        .mmu_sfsr_mask = 0xffffffff,
-        .mmu_trcr_mask = 0xffffffff,
-        .mxcc_version = 0x00000104,
-        .nwindows = 8,
-        .features = CPU_DEFAULT_FEATURES,
-    },
-    {
-        .name = "Ross RT625",
-        .iu_version = 0x1e000000,
-        .fpu_version = 1 << 17,
-        .mmu_version = 0x1e000000,
-        .mmu_bm = 0x00004000,
-        .mmu_ctpr_mask = 0x007ffff0,
-        .mmu_cxr_mask = 0x0000003f,
-        .mmu_sfsr_mask = 0xffffffff,
-        .mmu_trcr_mask = 0xffffffff,
-        .nwindows = 8,
-        .features = CPU_DEFAULT_FEATURES,
-    },
-    {
-        .name = "Ross RT620",
-        .iu_version = 0x1f000000,
-        .fpu_version = 1 << 17,
-        .mmu_version = 0x1f000000,
-        .mmu_bm = 0x00004000,
-        .mmu_ctpr_mask = 0x007ffff0,
-        .mmu_cxr_mask = 0x0000003f,
-        .mmu_sfsr_mask = 0xffffffff,
-        .mmu_trcr_mask = 0xffffffff,
-        .nwindows = 8,
-        .features = CPU_DEFAULT_FEATURES,
-    },
-    {
-        .name = "BIT B5010",
-        .iu_version = 0x20000000,
-        .fpu_version = 0 << 17, /* B5010/B5110/B5120/B5210 */
-        .mmu_version = 0x20000000,
-        .mmu_bm = 0x00004000,
-        .mmu_ctpr_mask = 0x007ffff0,
-        .mmu_cxr_mask = 0x0000003f,
-        .mmu_sfsr_mask = 0xffffffff,
-        .mmu_trcr_mask = 0xffffffff,
-        .nwindows = 8,
-        .features = CPU_FEATURE_FLOAT | CPU_FEATURE_SWAP | CPU_FEATURE_FSQRT |
-        CPU_FEATURE_FSMULD,
-    },
-    {
-        .name = "Matsushita MN10501",
-        .iu_version = 0x50000000,
-        .fpu_version = 0 << 17,
-        .mmu_version = 0x50000000,
-        .mmu_bm = 0x00004000,
-        .mmu_ctpr_mask = 0x007ffff0,
-        .mmu_cxr_mask = 0x0000003f,
-        .mmu_sfsr_mask = 0xffffffff,
-        .mmu_trcr_mask = 0xffffffff,
-        .nwindows = 8,
-        .features = CPU_FEATURE_FLOAT | CPU_FEATURE_MUL | CPU_FEATURE_FSQRT |
-        CPU_FEATURE_FSMULD,
-    },
-    {
-        .name = "Weitek W8601",
-        .iu_version = 0x90 << 24, /* Impl 9, ver 0 */
-        .fpu_version = 3 << 17, /* FPU version 3 (Weitek WTL3170/2) */
-        .mmu_version = 0x10 << 24,
-        .mmu_bm = 0x00004000,
-        .mmu_ctpr_mask = 0x007ffff0,
-        .mmu_cxr_mask = 0x0000003f,
-        .mmu_sfsr_mask = 0xffffffff,
-        .mmu_trcr_mask = 0xffffffff,
-        .nwindows = 8,
-        .features = CPU_DEFAULT_FEATURES,
-    },
-    {
-        .name = "LEON2",
-        .iu_version = 0xf2000000,
-        .fpu_version = 4 << 17, /* FPU version 4 (Meiko) */
-        .mmu_version = 0xf2000000,
-        .mmu_bm = 0x00004000,
-        .mmu_ctpr_mask = 0x007ffff0,
-        .mmu_cxr_mask = 0x0000003f,
-        .mmu_sfsr_mask = 0xffffffff,
-        .mmu_trcr_mask = 0xffffffff,
-        .nwindows = 8,
-        .features = CPU_DEFAULT_FEATURES | CPU_FEATURE_TA0_SHUTDOWN,
-    },
-    {
-        .name = "LEON3",
-        .iu_version = 0xf3000000,
-        .fpu_version = 4 << 17, /* FPU version 4 (Meiko) */
-        .mmu_version = 0xf3000000,
-        .mmu_bm = 0x00000000,
-        .mmu_ctpr_mask = 0x007ffff0,
-        .mmu_cxr_mask = 0x0000003f,
-        .mmu_sfsr_mask = 0xffffffff,
-        .mmu_trcr_mask = 0xffffffff,
-        .nwindows = 8,
-        .features = CPU_DEFAULT_FEATURES | CPU_FEATURE_TA0_SHUTDOWN |
-        CPU_FEATURE_ASR17 | CPU_FEATURE_CACHE_CTRL,
-    },
-#endif
-};
-
-static const char * const feature_name[] = {
-    "float",
-    "float128",
-    "swap",
-    "mul",
-    "div",
-    "flush",
-    "fsqrt",
-    "fmul",
-    "vis1",
-    "vis2",
-    "fsmuld",
-    "hypv",
-    "cmt",
-    "gl",
-};
-
-static void print_features(FILE *f, fprintf_function cpu_fprintf,
-                           uint32_t features, const char *prefix)
-{
-    unsigned int i;
-
-    for (i = 0; i < ARRAY_SIZE(feature_name); i++) {
-        if (feature_name[i] && (features & (1 << i))) {
-            if (prefix) {
-                (*cpu_fprintf)(f, "%s", prefix);
-            }
-            (*cpu_fprintf)(f, "%s ", feature_name[i]);
-        }
-    }
-}
-
-static void add_flagname_to_bitmaps(const char *flagname, uint32_t *features)
-{
-    unsigned int i;
-
-    for (i = 0; i < ARRAY_SIZE(feature_name); i++) {
-        if (feature_name[i] && !strcmp(flagname, feature_name[i])) {
-            *features |= 1 << i;
-            return;
-        }
-    }
-    fprintf(stderr, "CPU feature %s not found\n", flagname);
-}
-
-static int cpu_sparc_find_by_name(sparc_def_t *cpu_def, const char *cpu_model)
-{
-    unsigned int i;
-    const sparc_def_t *def = NULL;
-    char *s = strdup(cpu_model);
-    char *featurestr, *name = strtok(s, ",");
-    uint32_t plus_features = 0;
-    uint32_t minus_features = 0;
-    uint64_t iu_version;
-    uint32_t fpu_version, mmu_version, nwindows;
-
-    for (i = 0; i < ARRAY_SIZE(sparc_defs); i++) {
-        if (strcasecmp(name, sparc_defs[i].name) == 0) {
-            def = &sparc_defs[i];
-        }
-    }
-    if (!def) {
-        goto error;
-    }
-    memcpy(cpu_def, def, sizeof(*def));
-
-    featurestr = strtok(NULL, ",");
-    while (featurestr) {
-        char *val;
-
-        if (featurestr[0] == '+') {
-            add_flagname_to_bitmaps(featurestr + 1, &plus_features);
-        } else if (featurestr[0] == '-') {
-            add_flagname_to_bitmaps(featurestr + 1, &minus_features);
-        } else if ((val = strchr(featurestr, '='))) {
-            *val = 0; val++;
-            if (!strcmp(featurestr, "iu_version")) {
-                char *err;
-
-                iu_version = strtoll(val, &err, 0);
-                if (!*val || *err) {
-                    fprintf(stderr, "bad numerical value %s\n", val);
-                    goto error;
-                }
-                cpu_def->iu_version = iu_version;
-#ifdef DEBUG_FEATURES
-                fprintf(stderr, "iu_version %" PRIx64 "\n", iu_version);
-#endif
-            } else if (!strcmp(featurestr, "fpu_version")) {
-                char *err;
-
-                fpu_version = strtol(val, &err, 0);
-                if (!*val || *err) {
-                    fprintf(stderr, "bad numerical value %s\n", val);
-                    goto error;
-                }
-                cpu_def->fpu_version = fpu_version;
-#ifdef DEBUG_FEATURES
-                fprintf(stderr, "fpu_version %x\n", fpu_version);
-#endif
-            } else if (!strcmp(featurestr, "mmu_version")) {
-                char *err;
-
-                mmu_version = strtol(val, &err, 0);
-                if (!*val || *err) {
-                    fprintf(stderr, "bad numerical value %s\n", val);
-                    goto error;
-                }
-                cpu_def->mmu_version = mmu_version;
-#ifdef DEBUG_FEATURES
-                fprintf(stderr, "mmu_version %x\n", mmu_version);
-#endif
-            } else if (!strcmp(featurestr, "nwindows")) {
-                char *err;
-
-                nwindows = strtol(val, &err, 0);
-                if (!*val || *err || nwindows > MAX_NWINDOWS ||
-                    nwindows < MIN_NWINDOWS) {
-                    fprintf(stderr, "bad numerical value %s\n", val);
-                    goto error;
-                }
-                cpu_def->nwindows = nwindows;
-#ifdef DEBUG_FEATURES
-                fprintf(stderr, "nwindows %d\n", nwindows);
-#endif
-            } else {
-                fprintf(stderr, "unrecognized feature %s\n", featurestr);
-                goto error;
-            }
-        } else {
-            fprintf(stderr, "feature string `%s' not in format "
-                    "(+feature|-feature|feature=xyz)\n", featurestr);
-            goto error;
-        }
-        featurestr = strtok(NULL, ",");
-    }
-    cpu_def->features |= plus_features;
-    cpu_def->features &= ~minus_features;
-#ifdef DEBUG_FEATURES
-    print_features(stderr, fprintf, cpu_def->features, NULL);
-#endif
-    free(s);
-    return 0;
-
- error:
-    free(s);
-    return -1;
-}
-
-void sparc_cpu_list(FILE *f, fprintf_function cpu_fprintf)
-{
-    unsigned int i;
-
-    for (i = 0; i < ARRAY_SIZE(sparc_defs); i++) {
-        (*cpu_fprintf)(f, "Sparc %16s IU " TARGET_FMT_lx
-                       " FPU %08x MMU %08x NWINS %d ",
-                       sparc_defs[i].name,
-                       sparc_defs[i].iu_version,
-                       sparc_defs[i].fpu_version,
-                       sparc_defs[i].mmu_version,
-                       sparc_defs[i].nwindows);
-        print_features(f, cpu_fprintf, CPU_DEFAULT_FEATURES &
-                       ~sparc_defs[i].features, "-");
-        print_features(f, cpu_fprintf, ~CPU_DEFAULT_FEATURES &
-                       sparc_defs[i].features, "+");
-        (*cpu_fprintf)(f, "\n");
-    }
-    (*cpu_fprintf)(f, "Default CPU feature flags (use '-' to remove): ");
-    print_features(f, cpu_fprintf, CPU_DEFAULT_FEATURES, NULL);
-    (*cpu_fprintf)(f, "\n");
-    (*cpu_fprintf)(f, "Available CPU feature flags (use '+' to add): ");
-    print_features(f, cpu_fprintf, ~CPU_DEFAULT_FEATURES, NULL);
-    (*cpu_fprintf)(f, "\n");
-    (*cpu_fprintf)(f, "Numerical features (use '=' to set): iu_version "
-                   "fpu_version mmu_version nwindows\n");
-}
-
-static void cpu_print_cc(FILE *f, fprintf_function cpu_fprintf,
-                         uint32_t cc)
-{
-    cpu_fprintf(f, "%c%c%c%c", cc & PSR_NEG ? 'N' : '-',
-                cc & PSR_ZERO ? 'Z' : '-', cc & PSR_OVF ? 'V' : '-',
-                cc & PSR_CARRY ? 'C' : '-');
-}
-
-#ifdef TARGET_SPARC64
-#define REGS_PER_LINE 4
-#else
-#define REGS_PER_LINE 8
-#endif
-
-void cpu_dump_state(CPUSPARCState *env, FILE *f, fprintf_function cpu_fprintf,
-                    int flags)
-{
-    int i, x;
-
-    cpu_fprintf(f, "pc: " TARGET_FMT_lx "  npc: " TARGET_FMT_lx "\n", env->pc,
-                env->npc);
-    cpu_fprintf(f, "General Registers:\n");
-
-    for (i = 0; i < 8; i++) {
-        if (i % REGS_PER_LINE == 0) {
-            cpu_fprintf(f, "%%g%d-%d:", i, i + REGS_PER_LINE - 1);
-        }
-        cpu_fprintf(f, " " TARGET_FMT_lx, env->gregs[i]);
-        if (i % REGS_PER_LINE == REGS_PER_LINE - 1) {
-            cpu_fprintf(f, "\n");
-        }
-    }
-    cpu_fprintf(f, "\nCurrent Register Window:\n");
-    for (x = 0; x < 3; x++) {
-        for (i = 0; i < 8; i++) {
-            if (i % REGS_PER_LINE == 0) {
-                cpu_fprintf(f, "%%%c%d-%d: ",
-                            x == 0 ? 'o' : (x == 1 ? 'l' : 'i'),
-                            i, i + REGS_PER_LINE - 1);
-            }
-            cpu_fprintf(f, TARGET_FMT_lx " ", env->regwptr[i + x * 8]);
-            if (i % REGS_PER_LINE == REGS_PER_LINE - 1) {
-                cpu_fprintf(f, "\n");
-            }
-        }
-    }
-    cpu_fprintf(f, "\nFloating Point Registers:\n");
-    for (i = 0; i < TARGET_DPREGS; i++) {
-        if ((i & 3) == 0) {
-            cpu_fprintf(f, "%%f%02d:", i * 2);
-        }
-        cpu_fprintf(f, " %016" PRIx64, env->fpr[i].ll);
-        if ((i & 3) == 3) {
-            cpu_fprintf(f, "\n");
-        }
-    }
-#ifdef TARGET_SPARC64
-    cpu_fprintf(f, "pstate: %08x ccr: %02x (icc: ", env->pstate,
-                (unsigned)cpu_get_ccr(env));
-    cpu_print_cc(f, cpu_fprintf, cpu_get_ccr(env) << PSR_CARRY_SHIFT);
-    cpu_fprintf(f, " xcc: ");
-    cpu_print_cc(f, cpu_fprintf, cpu_get_ccr(env) << (PSR_CARRY_SHIFT - 4));
-    cpu_fprintf(f, ") asi: %02x tl: %d pil: %x\n", env->asi, env->tl,
-                env->psrpil);
-    cpu_fprintf(f, "cansave: %d canrestore: %d otherwin: %d wstate: %d "
-                "cleanwin: %d cwp: %d\n",
-                env->cansave, env->canrestore, env->otherwin, env->wstate,
-                env->cleanwin, env->nwindows - 1 - env->cwp);
-    cpu_fprintf(f, "fsr: " TARGET_FMT_lx " y: " TARGET_FMT_lx " fprs: "
-                TARGET_FMT_lx "\n", env->fsr, env->y, env->fprs);
-#else
-    cpu_fprintf(f, "psr: %08x (icc: ", cpu_get_psr(env));
-    cpu_print_cc(f, cpu_fprintf, cpu_get_psr(env));
-    cpu_fprintf(f, " SPE: %c%c%c) wim: %08x\n", env->psrs ? 'S' : '-',
-                env->psrps ? 'P' : '-', env->psret ? 'E' : '-',
-                env->wim);
-    cpu_fprintf(f, "fsr: " TARGET_FMT_lx " y: " TARGET_FMT_lx "\n",
-                env->fsr, env->y);
-#endif
-}
commit d8fd2954996255ba6ad610917e7849832d0120b7
Author: Paul Brook <paul at codesourcery.com>
Date:   Fri Mar 30 18:02:50 2012 +0100

    Userspace ARM BE8 support
    
    Add support for ARM BE8 userspace binaries.
    i.e. big-endian data and little-endian code.
    In principle LE8 mode is also possible, but AFAIK has never actually
    been implemented/used.
    
    System emulation doesn't have any useable big-endian board models,
    but should in principle work once you fix that.
    Dynamic endianness switching requires messing with data accesses,
    preferably with TCG cooperation, and is orthogonal to BE8 support.
    
    Signed-off-by: Paul Brook <paul at codesourcery.com>
    [PMM: various changes, mostly as per my suggestions in code review:
     * rebase
     * use EF_ defines rather than hardcoded constants
     * make bswap_code a bool for future VMSTATE macro compatibility
     * update comment in cpu.h about TB flags bit field usage
     * factor out load-code-and-swap into arm_ld*_code functions and
       get_user_code* macros
     * fix stray trailing space at end of line
     * added braces in disas.c to satisfy checkpatch
    ]
    Signed-off-by: Peter Maydell <peter.maydell at linaro.org>
    Signed-off-by: Riku Voipio <riku.voipio at linaro.org>

diff --git a/disas.c b/disas.c
index 9485824..4f2c4e4 100644
--- a/disas.c
+++ b/disas.c
@@ -138,7 +138,7 @@ print_insn_thumb1(bfd_vma pc, disassemble_info *info)
 /* Disassemble this for me please... (debugging). 'flags' has the following
    values:
     i386 - 1 means 16 bit code, 2 means 64 bit code
-    arm  - nonzero means thumb code
+    arm  - bit 0 = thumb, bit 1 = reverse endian
     ppc  - nonzero means little endian
     other targets - unused
  */
@@ -169,10 +169,18 @@ void target_disas(FILE *out, target_ulong code, target_ulong size, int flags)
         disasm_info.mach = bfd_mach_i386_i386;
     print_insn = print_insn_i386;
 #elif defined(TARGET_ARM)
-    if (flags)
-	print_insn = print_insn_thumb1;
-    else
-	print_insn = print_insn_arm;
+    if (flags & 1) {
+        print_insn = print_insn_thumb1;
+    } else {
+        print_insn = print_insn_arm;
+    }
+    if (flags & 2) {
+#ifdef TARGET_WORDS_BIGENDIAN
+        disasm_info.endian = BFD_ENDIAN_LITTLE;
+#else
+        disasm_info.endian = BFD_ENDIAN_BIG;
+#endif
+    }
 #elif defined(TARGET_SPARC)
     print_insn = print_insn_sparc;
 #ifdef TARGET_SPARC64
diff --git a/linux-user/elfload.c b/linux-user/elfload.c
index 4ce9743..f3b1552 100644
--- a/linux-user/elfload.c
+++ b/linux-user/elfload.c
@@ -1576,6 +1576,7 @@ static void load_elf_image(const char *image_name, int image_fd,
     info->start_data = -1;
     info->end_data = 0;
     info->brk = 0;
+    info->elf_flags = ehdr->e_flags;
 
     for (i = 0; i < ehdr->e_phnum; i++) {
         struct elf_phdr *eppnt = phdr + i;
diff --git a/linux-user/main.c b/linux-user/main.c
index 23ad357..191b750 100644
--- a/linux-user/main.c
+++ b/linux-user/main.c
@@ -33,6 +33,7 @@
 #include "tcg.h"
 #include "qemu-timer.h"
 #include "envlist.h"
+#include "elf.h"
 
 #define DEBUG_LOGFILE "/tmp/qemu.log"
 
@@ -474,6 +475,22 @@ void cpu_loop(CPUX86State *env)
 
 #ifdef TARGET_ARM
 
+#define get_user_code_u32(x, gaddr, doswap)             \
+    ({ abi_long __r = get_user_u32((x), (gaddr));       \
+        if (!__r && (doswap)) {                         \
+            (x) = bswap32(x);                           \
+        }                                               \
+        __r;                                            \
+    })
+
+#define get_user_code_u16(x, gaddr, doswap)             \
+    ({ abi_long __r = get_user_u16((x), (gaddr));       \
+        if (!__r && (doswap)) {                         \
+            (x) = bswap16(x);                           \
+        }                                               \
+        __r;                                            \
+    })
+
 /*
  * See the Linux kernel's Documentation/arm/kernel_user_helpers.txt
  * Input:
@@ -707,7 +724,7 @@ void cpu_loop(CPUARMState *env)
                 /* we handle the FPU emulation here, as Linux */
                 /* we get the opcode */
                 /* FIXME - what to do if get_user() fails? */
-                get_user_u32(opcode, env->regs[15]);
+                get_user_code_u32(opcode, env->regs[15], env->bswap_code);
 
                 rc = EmulateAll(opcode, &ts->fpa, env);
                 if (rc == 0) { /* illegal instruction */
@@ -777,23 +794,25 @@ void cpu_loop(CPUARMState *env)
                 if (trapnr == EXCP_BKPT) {
                     if (env->thumb) {
                         /* FIXME - what to do if get_user() fails? */
-                        get_user_u16(insn, env->regs[15]);
+                        get_user_code_u16(insn, env->regs[15], env->bswap_code);
                         n = insn & 0xff;
                         env->regs[15] += 2;
                     } else {
                         /* FIXME - what to do if get_user() fails? */
-                        get_user_u32(insn, env->regs[15]);
+                        get_user_code_u32(insn, env->regs[15], env->bswap_code);
                         n = (insn & 0xf) | ((insn >> 4) & 0xff0);
                         env->regs[15] += 4;
                     }
                 } else {
                     if (env->thumb) {
                         /* FIXME - what to do if get_user() fails? */
-                        get_user_u16(insn, env->regs[15] - 2);
+                        get_user_code_u16(insn, env->regs[15] - 2,
+                                          env->bswap_code);
                         n = insn & 0xff;
                     } else {
                         /* FIXME - what to do if get_user() fails? */
-                        get_user_u32(insn, env->regs[15] - 4);
+                        get_user_code_u32(insn, env->regs[15] - 4,
+                                          env->bswap_code);
                         n = insn & 0xffffff;
                     }
                 }
@@ -3657,6 +3676,11 @@ int main(int argc, char **argv, char **envp)
         for(i = 0; i < 16; i++) {
             env->regs[i] = regs->uregs[i];
         }
+        /* Enable BE8.  */
+        if (EF_ARM_EABI_VERSION(info->elf_flags) >= EF_ARM_EABI_VER4
+            && (info->elf_flags & EF_ARM_BE8)) {
+            env->bswap_code = 1;
+        }
     }
 #elif defined(TARGET_UNICORE32)
     {
diff --git a/linux-user/qemu.h b/linux-user/qemu.h
index dd74cc0..7b299b7 100644
--- a/linux-user/qemu.h
+++ b/linux-user/qemu.h
@@ -51,6 +51,7 @@ struct image_info {
         abi_ulong       auxv_len;
         abi_ulong       arg_start;
         abi_ulong       arg_end;
+        uint32_t        elf_flags;
 	int		personality;
 #ifdef CONFIG_USE_FDPIC
         abi_ulong       loadmap_addr;
diff --git a/target-arm/cpu.h b/target-arm/cpu.h
index e176c5f..c208c80 100644
--- a/target-arm/cpu.h
+++ b/target-arm/cpu.h
@@ -216,6 +216,9 @@ typedef struct CPUARMState {
         uint32_t cregs[16];
     } iwmmxt;
 
+    /* For mixed endian mode.  */
+    bool bswap_code;
+
 #if defined(CONFIG_USER_ONLY)
     /* For usermode syscall translation.  */
     int eabi;
@@ -491,7 +494,9 @@ static inline void cpu_clone_regs(CPUARMState *env, target_ulong newsp)
 #define ARM_TBFLAG_VFPEN_MASK       (1 << ARM_TBFLAG_VFPEN_SHIFT)
 #define ARM_TBFLAG_CONDEXEC_SHIFT   8
 #define ARM_TBFLAG_CONDEXEC_MASK    (0xff << ARM_TBFLAG_CONDEXEC_SHIFT)
-/* Bits 31..16 are currently unused. */
+#define ARM_TBFLAG_BSWAP_CODE_SHIFT 16
+#define ARM_TBFLAG_BSWAP_CODE_MASK  (1 << ARM_TBFLAG_BSWAP_CODE_SHIFT)
+/* Bits 31..17 are currently unused. */
 
 /* some convenience accessor macros */
 #define ARM_TBFLAG_THUMB(F) \
@@ -506,6 +511,8 @@ static inline void cpu_clone_regs(CPUARMState *env, target_ulong newsp)
     (((F) & ARM_TBFLAG_VFPEN_MASK) >> ARM_TBFLAG_VFPEN_SHIFT)
 #define ARM_TBFLAG_CONDEXEC(F) \
     (((F) & ARM_TBFLAG_CONDEXEC_MASK) >> ARM_TBFLAG_CONDEXEC_SHIFT)
+#define ARM_TBFLAG_BSWAP_CODE(F) \
+    (((F) & ARM_TBFLAG_BSWAP_CODE_MASK) >> ARM_TBFLAG_BSWAP_CODE_SHIFT)
 
 static inline void cpu_get_tb_cpu_state(CPUARMState *env, target_ulong *pc,
                                         target_ulong *cs_base, int *flags)
@@ -516,7 +523,8 @@ static inline void cpu_get_tb_cpu_state(CPUARMState *env, target_ulong *pc,
     *flags = (env->thumb << ARM_TBFLAG_THUMB_SHIFT)
         | (env->vfp.vec_len << ARM_TBFLAG_VECLEN_SHIFT)
         | (env->vfp.vec_stride << ARM_TBFLAG_VECSTRIDE_SHIFT)
-        | (env->condexec_bits << ARM_TBFLAG_CONDEXEC_SHIFT);
+        | (env->condexec_bits << ARM_TBFLAG_CONDEXEC_SHIFT)
+        | (env->bswap_code << ARM_TBFLAG_BSWAP_CODE_SHIFT);
     if (arm_feature(env, ARM_FEATURE_M)) {
         privmode = !((env->v7m.exception == 0) && (env->v7m.control & 1));
     } else {
@@ -543,4 +551,24 @@ static inline void cpu_pc_from_tb(CPUARMState *env, TranslationBlock *tb)
     env->regs[15] = tb->pc;
 }
 
+/* Load an instruction and return it in the standard little-endian order */
+static inline uint32_t arm_ldl_code(uint32_t addr, bool do_swap)
+{
+    uint32_t insn = ldl_code(addr);
+    if (do_swap) {
+        return bswap32(insn);
+    }
+    return insn;
+}
+
+/* Ditto, for a halfword (Thumb) instruction */
+static inline uint16_t arm_lduw_code(uint32_t addr, bool do_swap)
+{
+    uint16_t insn = lduw_code(addr);
+    if (do_swap) {
+        return bswap16(insn);
+    }
+    return insn;
+}
+
 #endif
diff --git a/target-arm/helper.c b/target-arm/helper.c
index d974b57..28f127b 100644
--- a/target-arm/helper.c
+++ b/target-arm/helper.c
@@ -842,7 +842,7 @@ static void do_interrupt_v7m(CPUARMState *env)
     case EXCP_BKPT:
         if (semihosting_enabled) {
             int nr;
-            nr = lduw_code(env->regs[15]) & 0xff;
+            nr = arm_lduw_code(env->regs[15], env->bswap_code) & 0xff;
             if (nr == 0xab) {
                 env->regs[15] += 2;
                 env->regs[0] = do_arm_semihosting(env);
@@ -914,9 +914,10 @@ void do_interrupt(CPUARMState *env)
         if (semihosting_enabled) {
             /* Check for semihosting interrupt.  */
             if (env->thumb) {
-                mask = lduw_code(env->regs[15] - 2) & 0xff;
+                mask = arm_lduw_code(env->regs[15] - 2, env->bswap_code) & 0xff;
             } else {
-                mask = ldl_code(env->regs[15] - 4) & 0xffffff;
+                mask = arm_ldl_code(env->regs[15] - 4, env->bswap_code)
+                    & 0xffffff;
             }
             /* Only intercept calls from privileged modes, to provide some
                semblance of security.  */
@@ -936,7 +937,7 @@ void do_interrupt(CPUARMState *env)
     case EXCP_BKPT:
         /* See if this is a semihosting syscall.  */
         if (env->thumb && semihosting_enabled) {
-            mask = lduw_code(env->regs[15]) & 0xff;
+            mask = arm_lduw_code(env->regs[15], env->bswap_code) & 0xff;
             if (mask == 0xab
                   && (env->uncached_cpsr & CPSR_M) != ARM_CPU_MODE_USR) {
                 env->regs[15] += 2;
diff --git a/target-arm/translate.c b/target-arm/translate.c
index 46d1d3e..7a3c7d6 100644
--- a/target-arm/translate.c
+++ b/target-arm/translate.c
@@ -59,6 +59,7 @@ typedef struct DisasContext {
     struct TranslationBlock *tb;
     int singlestep_enabled;
     int thumb;
+    int bswap_code;
 #if !defined(CONFIG_USER_ONLY)
     int user;
 #endif
@@ -6705,7 +6706,7 @@ static void disas_arm_insn(CPUARMState * env, DisasContext *s)
     TCGv addr;
     TCGv_i64 tmp64;
 
-    insn = ldl_code(s->pc);
+    insn = arm_ldl_code(s->pc, s->bswap_code);
     s->pc += 4;
 
     /* M variants do not implement ARM mode.  */
@@ -8133,7 +8134,7 @@ static int disas_thumb2_insn(CPUARMState *env, DisasContext *s, uint16_t insn_hw
         /* Fall through to 32-bit decode.  */
     }
 
-    insn = lduw_code(s->pc);
+    insn = arm_lduw_code(s->pc, s->bswap_code);
     s->pc += 2;
     insn |= (uint32_t)insn_hw1 << 16;
 
@@ -9163,7 +9164,7 @@ static void disas_thumb_insn(CPUARMState *env, DisasContext *s)
         }
     }
 
-    insn = lduw_code(s->pc);
+    insn = arm_lduw_code(s->pc, s->bswap_code);
     s->pc += 2;
 
     switch (insn >> 12) {
@@ -9872,6 +9873,7 @@ static inline void gen_intermediate_code_internal(CPUARMState *env,
     dc->singlestep_enabled = env->singlestep_enabled;
     dc->condjmp = 0;
     dc->thumb = ARM_TBFLAG_THUMB(tb->flags);
+    dc->bswap_code = ARM_TBFLAG_BSWAP_CODE(tb->flags);
     dc->condexec_mask = (ARM_TBFLAG_CONDEXEC(tb->flags) & 0xf) << 1;
     dc->condexec_cond = ARM_TBFLAG_CONDEXEC(tb->flags) >> 4;
 #if !defined(CONFIG_USER_ONLY)
@@ -10105,7 +10107,8 @@ done_generating:
     if (qemu_loglevel_mask(CPU_LOG_TB_IN_ASM)) {
         qemu_log("----------------\n");
         qemu_log("IN: %s\n", lookup_symbol(pc_start));
-        log_target_disas(pc_start, dc->pc - pc_start, dc->thumb);
+        log_target_disas(pc_start, dc->pc - pc_start,
+                         dc->thumb | (dc->bswap_code << 1));
         qemu_log("\n");
     }
 #endif
commit ef8b0c0474aa7eab5172e866dc37428b41ff2934
Author: Peter Maydell <peter.maydell at linaro.org>
Date:   Fri Mar 30 18:02:49 2012 +0100

    elf.h: Update EF_ARM_ constants to newer ABI versions
    
    Update the EF_ARM_* constants (for the ELF header e_flags field)
    to include the newer flags specified for later versions of the ABI.
    (This set of constants is from include/elf/arm.h from binutils-2.17
    and so licensed under GPL-v2-or-later.)
    
    Signed-off-by: Peter Maydell <peter.maydell at linaro.org>
    Signed-off-by: Riku Voipio <riku.voipio at linaro.org>

diff --git a/elf.h b/elf.h
index 36bcac4..e1422b8 100644
--- a/elf.h
+++ b/elf.h
@@ -538,6 +538,27 @@ typedef struct {
 #define EF_ALIGN8          0x40		/* 8-bit structure alignment is in use */
 #define EF_NEW_ABI         0x80
 #define EF_OLD_ABI         0x100
+#define EF_ARM_SOFT_FLOAT  0x200
+#define EF_ARM_VFP_FLOAT   0x400
+#define EF_ARM_MAVERICK_FLOAT 0x800
+
+/* Other constants defined in the ARM ELF spec. version B-01.  */
+#define EF_ARM_SYMSARESORTED 0x04       /* NB conflicts with EF_INTERWORK */
+#define EF_ARM_DYNSYMSUSESEGIDX 0x08    /* NB conflicts with EF_APCS26 */
+#define EF_ARM_MAPSYMSFIRST 0x10        /* NB conflicts with EF_APCS_FLOAT */
+#define EF_ARM_EABIMASK      0xFF000000
+
+/* Constants defined in AAELF.  */
+#define EF_ARM_BE8          0x00800000
+#define EF_ARM_LE8          0x00400000
+
+#define EF_ARM_EABI_VERSION(flags) ((flags) & EF_ARM_EABIMASK)
+#define EF_ARM_EABI_UNKNOWN  0x00000000
+#define EF_ARM_EABI_VER1     0x01000000
+#define EF_ARM_EABI_VER2     0x02000000
+#define EF_ARM_EABI_VER3     0x03000000
+#define EF_ARM_EABI_VER4     0x04000000
+#define EF_ARM_EABI_VER5     0x05000000
 
 /* Additional symbol types for Thumb */
 #define STT_ARM_TFUNC      0xd
commit adf050b1b9f0fe7f921780eeb1888ce53d94d10b
Author: Benoit Canet <benoit.canet at gmail.com>
Date:   Wed Nov 9 03:37:23 2011 +0000

    arm-linux-user: fix elfload.c's AT_HWCAP to reflect cpu features.
    
    The cpu capabilities passed by the elf loader in AT_HWCAP where
    a constant.
    Make AT_HWCAP reflect the emulated cpu features in order to give
    correct clues to eglibc.
    
    Riku Voipio: fixed to apply to current head
    
    Fix :  [Bug 887516] [NEW] VFP support reported for the PXA270
    
    Signed-off-by: Benoit Canet <benoit.canet at gmail.com>
    Signed-off-by: Riku Voipio <riku.voipio at linaro.org>

diff --git a/linux-user/elfload.c b/linux-user/elfload.c
index e502b39..4ce9743 100644
--- a/linux-user/elfload.c
+++ b/linux-user/elfload.c
@@ -375,10 +375,33 @@ bool guest_validate_base(unsigned long guest_base)
     return 1; /* All good */
 }
 
-#define ELF_HWCAP (ARM_HWCAP_ARM_SWP | ARM_HWCAP_ARM_HALF               \
-                   | ARM_HWCAP_ARM_THUMB | ARM_HWCAP_ARM_FAST_MULT      \
-                   | ARM_HWCAP_ARM_FPA | ARM_HWCAP_ARM_VFP              \
-                   | ARM_HWCAP_ARM_NEON | ARM_HWCAP_ARM_VFPv3 )
+
+#define ELF_HWCAP get_elf_hwcap()
+
+static uint32_t get_elf_hwcap(void)
+{
+    CPUARMState *e = thread_env;
+    uint32_t hwcaps = 0;
+
+    hwcaps |= ARM_HWCAP_ARM_SWP;
+    hwcaps |= ARM_HWCAP_ARM_HALF;
+    hwcaps |= ARM_HWCAP_ARM_THUMB;
+    hwcaps |= ARM_HWCAP_ARM_FAST_MULT;
+    hwcaps |= ARM_HWCAP_ARM_FPA;
+
+    /* probe for the extra features */
+#define GET_FEATURE(feat, hwcap) \
+    do {if (arm_feature(e, feat)) { hwcaps |= hwcap; } } while (0)
+    GET_FEATURE(ARM_FEATURE_VFP, ARM_HWCAP_ARM_VFP);
+    GET_FEATURE(ARM_FEATURE_IWMMXT, ARM_HWCAP_ARM_IWMMXT);
+    GET_FEATURE(ARM_FEATURE_THUMB2EE, ARM_HWCAP_ARM_THUMBEE);
+    GET_FEATURE(ARM_FEATURE_NEON, ARM_HWCAP_ARM_NEON);
+    GET_FEATURE(ARM_FEATURE_VFP3, ARM_HWCAP_ARM_VFPv3);
+    GET_FEATURE(ARM_FEATURE_VFP_FP16, ARM_HWCAP_ARM_VFPv3D16);
+#undef GET_FEATURE
+
+    return hwcaps;
+}
 
 #endif
 
commit d1b02ea0dcd20998ef178ddc55fb9765f6aa1d44
Author: Peter Maydell <peter.maydell at linaro.org>
Date:   Fri Mar 16 17:16:36 2012 +0000

    linux-user/arm/syscall_nr.h: Add syscall number for ppoll
    
    The list of ARM syscall numbers was missing the entry for ppoll,
    which meant we were accidentally not providing it. (This wasn't
    causing any practical issues beyond warnings about unimplemented
    syscalls, because glibc will fall back to another code path if the
    syscall isn't present.)
    
    Signed-off-by: Peter Maydell <peter.maydell at linaro.org>
    Signed-off-by: Riku Voipio <riku.voipio at linaro.org>

diff --git a/linux-user/arm/syscall_nr.h b/linux-user/arm/syscall_nr.h
index 7f05879..5356395 100644
--- a/linux-user/arm/syscall_nr.h
+++ b/linux-user/arm/syscall_nr.h
@@ -339,7 +339,7 @@
 #define TARGET_NR_fchmodat			(333)
 #define TARGET_NR_faccessat			(334)
 #define TARGET_NR_pselect6			(335)
-					/* 336 for ppoll */
+#define TARGET_NR_ppoll                         (336)
 #define TARGET_NR_unshare			(337)
 #define TARGET_NR_set_robust_list		(338)
 #define TARGET_NR_get_robust_list		(339)
commit db9526b10a956fd80c08727685c300b63d5a7465
Author: Peter Maydell <peter.maydell at linaro.org>
Date:   Fri Feb 3 14:48:03 2012 +0000

    linux-user: Add support for prctl PR_GET_NAME and PR_SET_NAME
    
    Add support for the prctl options PR_GET_NAME and PR_SET_NAME,
    which take or return a name in a 16 byte buffer pointed to by arg2.
    
    Signed-off-by: Peter Maydell <peter.maydell at linaro.org>
    Signed-off-by: Riku Voipio <riku.voipio at linaro.org>

diff --git a/linux-user/syscall.c b/linux-user/syscall.c
index ea44f99..8a92162 100644
--- a/linux-user/syscall.c
+++ b/linux-user/syscall.c
@@ -7253,6 +7253,30 @@ abi_long do_syscall(void *cpu_env, int num, abi_long arg1,
             }
             break;
         }
+#ifdef PR_GET_NAME
+        case PR_GET_NAME:
+        {
+            void *name = lock_user(VERIFY_WRITE, arg2, 16, 1);
+            if (!name) {
+                goto efault;
+            }
+            ret = get_errno(prctl(arg1, (unsigned long)name,
+                                  arg3, arg4, arg5));
+            unlock_user(name, arg2, 16);
+            break;
+        }
+        case PR_SET_NAME:
+        {
+            void *name = lock_user(VERIFY_READ, arg2, 16, 1);
+            if (!name) {
+                goto efault;
+            }
+            ret = get_errno(prctl(arg1, (unsigned long)name,
+                                  arg3, arg4, arg5));
+            unlock_user(name, arg2, 0);
+            break;
+        }
+#endif
         default:
             /* Most prctl options have no pointer arguments */
             ret = get_errno(prctl(arg1, arg2, arg3, arg4, arg5));
commit 1e6722f8b0c1eaff305c39d32c07054450ebdad1
Author: Peter Maydell <peter.maydell at linaro.org>
Date:   Fri Feb 3 14:48:03 2012 +0000

    linux-user/syscall.c: Fix indentation in prctl handling
    
    Clean up the odd indentation of this switch statement before
    we double its size by adding new cases to it.
    
    Signed-off-by: Peter Maydell <peter.maydell at linaro.org>
    Signed-off-by: Riku Voipio <riku.voipio at linaro.org>

diff --git a/linux-user/syscall.c b/linux-user/syscall.c
index fdd49b1..ea44f99 100644
--- a/linux-user/syscall.c
+++ b/linux-user/syscall.c
@@ -7242,21 +7242,22 @@ abi_long do_syscall(void *cpu_env, int num, abi_long arg1,
         goto unimplemented;
 #endif
     case TARGET_NR_prctl:
-        switch (arg1)
-            {
-            case PR_GET_PDEATHSIG:
-                {
-                    int deathsig;
-                    ret = get_errno(prctl(arg1, &deathsig, arg3, arg4, arg5));
-                    if (!is_error(ret) && arg2
-                        && put_user_ual(deathsig, arg2))
-                        goto efault;
-                }
-                break;
-            default:
-                ret = get_errno(prctl(arg1, arg2, arg3, arg4, arg5));
-                break;
+        switch (arg1) {
+        case PR_GET_PDEATHSIG:
+        {
+            int deathsig;
+            ret = get_errno(prctl(arg1, &deathsig, arg3, arg4, arg5));
+            if (!is_error(ret) && arg2
+                && put_user_ual(deathsig, arg2)) {
+                goto efault;
             }
+            break;
+        }
+        default:
+            /* Most prctl options have no pointer arguments */
+            ret = get_errno(prctl(arg1, arg2, arg3, arg4, arg5));
+            break;
+        }
         break;
 #ifdef TARGET_NR_arch_prctl
     case TARGET_NR_arch_prctl:
commit 288e65b9eea0c9b3cbe21be46f3e24e4e8b2a090
Author: Alexander Graf <agraf at suse.de>
Date:   Wed Dec 14 00:33:28 2011 +0100

    linux-user: reserve 4GB of vmem for 32-on-64
    
    When running 32-on-64 bit guests, we should always reserve as much
    virtual memory as we possibly can for the guest process, so it can
    never overlap with QEMU address space.
    
    Fortunately we already have the infrastructure for that. All that's
    missing is some sane default value to also make use of it!
    
    Signed-off-by: Alexander Graf <agraf at suse.de>
    Signed-off-by: Riku Voipio <riku.voipio at linaro.org>

diff --git a/linux-user/main.c b/linux-user/main.c
index aa95db3..23ad357 100644
--- a/linux-user/main.c
+++ b/linux-user/main.c
@@ -48,8 +48,19 @@ unsigned long mmap_min_addr;
 #if defined(CONFIG_USE_GUEST_BASE)
 unsigned long guest_base;
 int have_guest_base;
+#if (TARGET_LONG_BITS == 32) && (HOST_LONG_BITS == 64)
+/*
+ * When running 32-on-64 we should make sure we can fit all of the possible
+ * guest address space into a contiguous chunk of virtual host memory.
+ *
+ * This way we will never overlap with our own libraries or binaries or stack
+ * or anything else that QEMU maps.
+ */
+unsigned long reserved_va = 0xf7000000;
+#else
 unsigned long reserved_va;
 #endif
+#endif
 
 static void usage(void);
 
commit 59e9d91c7ae1b655997aec61c08eec1685414117
Author: Peter Maydell <peter.maydell at linaro.org>
Date:   Thu Mar 8 14:40:33 2012 +0000

    linux-user: resolve reserved_va vma downwards
    
    After consulting with Paul Brook, we concluded that it's best to search
    the VMA space downwards, so that we don't even get the chance to conflict
    with the brk range.
    
    This patch resolves a bunch of allocation conflicts when using -R.
    
    Signed-off-by: Alexander Graf <agraf at suse.de>
    [minor changes to get it to apply -- PMM]
    
    Signed-off-by: Riku Voipio <riku.voipio at linaro.org>

diff --git a/linux-user/main.c b/linux-user/main.c
index 2570140..aa95db3 100644
--- a/linux-user/main.c
+++ b/linux-user/main.c
@@ -3420,6 +3420,7 @@ int main(int argc, char **argv, char **envp)
             guest_base = HOST_PAGE_ALIGN((unsigned long)p);
         }
         qemu_log("Reserved 0x%lx bytes of guest address space\n", reserved_va);
+        mmap_next_start = reserved_va;
     }
 
     if (reserved_va || have_guest_base) {
diff --git a/linux-user/mmap.c b/linux-user/mmap.c
index 994c02b..7125d1c 100644
--- a/linux-user/mmap.c
+++ b/linux-user/mmap.c
@@ -212,7 +212,7 @@ static int mmap_frag(abi_ulong real_start,
 #else
 # define TASK_UNMAPPED_BASE  0x40000000
 #endif
-static abi_ulong mmap_next_start = TASK_UNMAPPED_BASE;
+abi_ulong mmap_next_start = TASK_UNMAPPED_BASE;
 
 unsigned long last_brk;
 
@@ -222,7 +222,7 @@ unsigned long last_brk;
 static abi_ulong mmap_find_vma_reserved(abi_ulong start, abi_ulong size)
 {
     abi_ulong addr;
-    abi_ulong last_addr;
+    abi_ulong end_addr;
     int prot;
     int looped = 0;
 
@@ -230,25 +230,38 @@ static abi_ulong mmap_find_vma_reserved(abi_ulong start, abi_ulong size)
         return (abi_ulong)-1;
     }
 
-    last_addr = start;
-    for (addr = start; last_addr + size != addr; addr += qemu_host_page_size) {
-        if (last_addr + size >= RESERVED_VA
-            || (abi_ulong)(last_addr + size) < last_addr) {
+    size = HOST_PAGE_ALIGN(size);
+    end_addr = start + size;
+    if (end_addr > RESERVED_VA) {
+        end_addr = RESERVED_VA;
+    }
+    addr = end_addr - qemu_host_page_size;
+
+    while (1) {
+        if (addr > end_addr) {
             if (looped) {
                 return (abi_ulong)-1;
             }
-            last_addr = qemu_host_page_size;
-            addr = 0;
+            end_addr = RESERVED_VA;
+            addr = end_addr - qemu_host_page_size;
             looped = 1;
             continue;
         }
         prot = page_get_flags(addr);
         if (prot) {
-            last_addr = addr + qemu_host_page_size;
+            end_addr = addr;
+        }
+        if (addr + size == end_addr) {
+            break;
         }
+        addr -= qemu_host_page_size;
+    }
+
+    if (start == mmap_next_start) {
+        mmap_next_start = addr;
     }
-    mmap_next_start = addr;
-    return last_addr;
+
+    return addr;
 }
 #endif
 
diff --git a/linux-user/qemu.h b/linux-user/qemu.h
index 6889567..dd74cc0 100644
--- a/linux-user/qemu.h
+++ b/linux-user/qemu.h
@@ -251,6 +251,7 @@ abi_long target_mremap(abi_ulong old_addr, abi_ulong old_size,
                        abi_ulong new_addr);
 int target_msync(abi_ulong start, abi_ulong len, int flags);
 extern unsigned long last_brk;
+extern abi_ulong mmap_next_start;
 void mmap_lock(void);
 void mmap_unlock(void);
 abi_ulong mmap_find_vma(abi_ulong, abi_ulong);
commit 39879bbbea4661a4004ca26673e3d1e6ae1e0bc3
Author: Alexander Graf <agraf at suse.de>
Date:   Thu Feb 2 03:14:18 2012 +0100

    linux-user: take RESERVED_VA into account for g2h_valid()
    
    When running with -R (RESERVED_VA > 0) all guest virtual addresses
    are within the [0..RESERVED_VA] range. Reflect this with g2h_valid()
    too so we can safely check for boundaries of our guest address space.
    
    This is required to have the /proc/self/maps code not show maps that
    aren't accessible from the guest process's point of view.
    
    Signed-off-by: Alexander Graf <agraf at suse.de>
    Signed-off-by: Riku Voipio <riku.voipio at linaro.org>

diff --git a/cpu-all.h b/cpu-all.h
index 9621c3c..4512518 100644
--- a/cpu-all.h
+++ b/cpu-all.h
@@ -204,7 +204,8 @@ extern unsigned long reserved_va;
 #else
 #define h2g_valid(x) ({ \
     unsigned long __guest = (unsigned long)(x) - GUEST_BASE; \
-    __guest < (1ul << TARGET_VIRT_ADDR_SPACE_BITS); \
+    (__guest < (1ul << TARGET_VIRT_ADDR_SPACE_BITS)) && \
+    (!RESERVED_VA || (__guest < RESERVED_VA)); \
 })
 #endif
 
commit 20249ae189ac0baa5011770bccabf3ee802eb2ab
Author: Alexander Graf <agraf at suse.de>
Date:   Mon Feb 6 21:37:07 2012 +0100

    linux-user: fix fallocate
    
    Fallocate gets off_t parameters passed in, so we should also read them out
    accordingly.
    
    Signed-off-by: Alexander Graf <agraf at suse.de>
    
    ---
    
    v1 -> v2:
    
      - unbreak 64-bit guests
    
    Signed-off-by: Riku Voipio <riku.voipio at linaro.org>

diff --git a/linux-user/syscall.c b/linux-user/syscall.c
index 9d1c8b2..fdd49b1 100644
--- a/linux-user/syscall.c
+++ b/linux-user/syscall.c
@@ -8485,7 +8485,12 @@ abi_long do_syscall(void *cpu_env, int num, abi_long arg1,
 #endif /* CONFIG_EVENTFD  */
 #if defined(CONFIG_FALLOCATE) && defined(TARGET_NR_fallocate)
     case TARGET_NR_fallocate:
+#if TARGET_ABI_BITS == 32
+        ret = get_errno(fallocate(arg1, arg2, target_offset64(arg3, arg4),
+                                  target_offset64(arg5, arg6)));
+#else
         ret = get_errno(fallocate(arg1, arg2, arg3, arg4));
+#endif
         break;
 #endif
 #if defined(CONFIG_SYNC_FILE_RANGE)
commit 354a0008270e9167ce89527fdf8f1a85c3a7fb87
Author: Alexander Graf <agraf at suse.de>
Date:   Thu Feb 2 02:22:34 2012 +0100

    linux-user: Add ioctl for BLKBSZGET
    
    This patch adds the ioctl wrapper definition for BLKBSZGET.
    
    Signed-off-by: Alexander Graf <agraf at suse.de>
    Signed-off-by: Riku Voipio <riku.voipio at linaro.org>

diff --git a/linux-user/ioctls.h b/linux-user/ioctls.h
index 5b70f92..eb96a08 100644
--- a/linux-user/ioctls.h
+++ b/linux-user/ioctls.h
@@ -75,6 +75,7 @@
      IOCTL(BLKRASET, 0, TYPE_INT)
      IOCTL(BLKRAGET, IOC_R, MK_PTR(TYPE_LONG))
      IOCTL(BLKSSZGET, IOC_R, MK_PTR(TYPE_LONG))
+     IOCTL(BLKBSZGET, IOC_R, MK_PTR(TYPE_INT))
 #ifdef FIBMAP
      IOCTL(FIBMAP, IOC_W | IOC_R, MK_PTR(TYPE_LONG))
 #endif
commit 49e9a0775224039701d34b208d8a1da982477fc9
Author: Alexander Graf <agraf at suse.de>
Date:   Tue Jan 31 20:11:37 2012 +0100

    linux-user: add BLKSSZGET ioctl wrapper
    
    This patch adds an ioctl definition for BLKSSZGET.
    
    Signed-off-by: Alexander Graf <agraf at suse.de>
    Signed-off-by: Riku Voipio <riku.voipio at linaro.org>

diff --git a/linux-user/ioctls.h b/linux-user/ioctls.h
index fd8b7bb..5b70f92 100644
--- a/linux-user/ioctls.h
+++ b/linux-user/ioctls.h
@@ -74,6 +74,7 @@
      IOCTL(BLKFLSBUF, 0, TYPE_NULL)
      IOCTL(BLKRASET, 0, TYPE_INT)
      IOCTL(BLKRAGET, IOC_R, MK_PTR(TYPE_LONG))
+     IOCTL(BLKSSZGET, IOC_R, MK_PTR(TYPE_LONG))
 #ifdef FIBMAP
      IOCTL(FIBMAP, IOC_W | IOC_R, MK_PTR(TYPE_LONG))
 #endif
commit edafea1330133eb8f6580a1c4f84fc5ec766eb4c
Author: Alexander Graf <agraf at suse.de>
Date:   Tue Jan 31 20:10:20 2012 +0100

    linux-user: fix BLK ioctl arguments
    
    Some BLK ioctls passed sizeof(x) into a macro that already did sizeof() on
    the passed in argument, rendering the size information inside the ioctl be
    the size of the host default integer type.
    
    Signed-off-by: Alexander Graf <agraf at suse.de>
    Signed-off-by: Riku Voipio <riku.voipio at linaro.org>

diff --git a/linux-user/syscall_defs.h b/linux-user/syscall_defs.h
index f8f3af3..a79b67d 100644
--- a/linux-user/syscall_defs.h
+++ b/linux-user/syscall_defs.h
@@ -832,9 +832,11 @@ struct target_pollfd {
 #define TARGET_BLKSECTGET TARGET_IO(0x12,103)/* get max sectors per request (ll_rw_blk.c) */
 #define TARGET_BLKSSZGET  TARGET_IO(0x12,104)/* get block device sector size */
 /* A jump here: 108-111 have been used for various private purposes. */
-#define TARGET_BLKBSZGET  TARGET_IOR(0x12,112,sizeof(int))
-#define TARGET_BLKBSZSET  TARGET_IOW(0x12,113,sizeof(int))
-#define TARGET_BLKGETSIZE64 TARGET_IOR(0x12,114,sizeof(uint64_t)) /* return device size in bytes (u64 *arg) */
+#define TARGET_BLKBSZGET  TARGET_IOR(0x12,112,int)
+#define TARGET_BLKBSZSET  TARGET_IOW(0x12,113,int)
+#define TARGET_BLKGETSIZE64 TARGET_IOR(0x12,114,abi_ulong)
+                                             /* return device size in bytes
+                                                (u64 *arg) */
 #define TARGET_FIBMAP     TARGET_IO(0x00,1)  /* bmap access */
 #define TARGET_FIGETBSZ   TARGET_IO(0x00,2)  /* get the block size used for bmap */
 #define TARGET_FS_IOC_FIEMAP TARGET_IOWR('f',11,struct fiemap)
commit 6083abd9aa134c9b0804e584f8279f54e6c90a1c
Author: Alexander Graf <agraf at suse.de>
Date:   Tue Jan 31 19:44:41 2012 +0100

    linux-user: add struct old_dev_t compat
    
    The compat LOOP_SET_STATUS ioctl uses struct old_dev_t in its passed
    struct. That variable type is vastly different between different
    architectures. Implement wrapping around it so we can use it.
    
    This fixes running arm kpartx on an x86_64 host for me.
    
    Signed-off-by: Alexander Graf <agraf at suse.de>
    Signed-off-by: Riku Voipio <riku.voipio at linaro.org>

diff --git a/linux-user/syscall_types.h b/linux-user/syscall_types.h
index fb8c9c9..601618d 100644
--- a/linux-user/syscall_types.h
+++ b/linux-user/syscall_types.h
@@ -83,9 +83,9 @@ STRUCT(mixer_info,
 /* loop device ioctls */
 STRUCT(loop_info,
        TYPE_INT,                 /* lo_number */
-       TYPE_SHORT,               /* lo_device */
+       TYPE_OLDDEVT,             /* lo_device */
        TYPE_ULONG,               /* lo_inode */
-       TYPE_SHORT,               /* lo_rdevice */
+       TYPE_OLDDEVT,             /* lo_rdevice */
        TYPE_INT,                 /* lo_offset */
        TYPE_INT,                 /* lo_encrypt_type */
        TYPE_INT,                 /* lo_encrypt_key_size */
diff --git a/thunk.c b/thunk.c
index 0657188..8ebbbb4 100644
--- a/thunk.c
+++ b/thunk.c
@@ -46,6 +46,7 @@ static inline const argtype *thunk_type_next(const argtype *type_ptr)
     case TYPE_LONG:
     case TYPE_ULONG:
     case TYPE_PTRVOID:
+    case TYPE_OLDDEVT:
         return type_ptr;
     case TYPE_PTR:
         return thunk_type_next_ptr(type_ptr);
@@ -188,6 +189,33 @@ const argtype *thunk_convert(void *dst, const void *src,
 #else
 #warning unsupported conversion
 #endif
+    case TYPE_OLDDEVT:
+    {
+        uint64_t val = 0;
+        switch (thunk_type_size(type_ptr - 1, !to_host)) {
+        case 2:
+            val = *(uint16_t *)src;
+            break;
+        case 4:
+            val = *(uint32_t *)src;
+            break;
+        case 8:
+            val = *(uint64_t *)src;
+            break;
+        }
+        switch (thunk_type_size(type_ptr - 1, to_host)) {
+        case 2:
+            *(uint16_t *)dst = tswap16(val);
+            break;
+        case 4:
+            *(uint32_t *)dst = tswap32(val);
+            break;
+        case 8:
+            *(uint64_t *)dst = tswap64(val);
+            break;
+        }
+        break;
+    }
     case TYPE_ARRAY:
         {
             int array_length, i, dst_size, src_size;
diff --git a/thunk.h b/thunk.h
index 9810743..5be8f91 100644
--- a/thunk.h
+++ b/thunk.h
@@ -37,6 +37,7 @@ typedef enum argtype {
     TYPE_PTR,
     TYPE_ARRAY,
     TYPE_STRUCT,
+    TYPE_OLDDEVT,
 } argtype;
 
 #define MK_PTR(type) TYPE_PTR, type
@@ -104,6 +105,31 @@ static inline int thunk_type_size(const argtype *type_ptr, int is_host)
             return TARGET_ABI_BITS / 8;
         }
         break;
+    case TYPE_OLDDEVT:
+        if (is_host) {
+#if defined(HOST_X86_64)
+            return 8;
+#elif defined(HOST_ALPHA) || defined(HOST_IA64) || defined(HOST_MIPS) || \
+      defined(HOST_PARISC) || defined(HOST_SPARC64)
+            return 4;
+#elif defined(HOST_PPC)
+            return HOST_LONG_SIZE;
+#else
+            return 2;
+#endif
+        } else {
+#if defined(TARGET_X86_64)
+            return 8;
+#elif defined(TARGET_ALPHA) || defined(TARGET_IA64) || defined(TARGET_MIPS) || \
+      defined(TARGET_PARISC) || defined(TARGET_SPARC64)
+            return 4;
+#elif defined(TARGET_PPC)
+            return TARGET_ABI_BITS / 8;
+#else
+            return 2;
+#endif
+        }
+        break;
     case TYPE_ARRAY:
         size = type_ptr[1];
         return size * thunk_type_size_array(type_ptr + 2, is_host);
@@ -141,6 +167,8 @@ static inline int thunk_type_align(const argtype *type_ptr, int is_host)
             return TARGET_ABI_BITS / 8;
         }
         break;
+    case TYPE_OLDDEVT:
+        return thunk_type_size(type_ptr, is_host);
     case TYPE_ARRAY:
         return thunk_type_align_array(type_ptr + 2, is_host);
     case TYPE_STRUCT:
commit 56e904ecb2018e30b10e9ec846635ff3b1e1d923
Author: Alexander Graf <agraf at suse.de>
Date:   Tue Jan 31 18:42:06 2012 +0100

    linux-user: implement device mapper ioctls
    
    This patch implements all ioctls currently implemented by device mapper,
    enabling us to run dmsetup and kpartx inside of linux-user.
    
    Signed-off-by: Alexander Graf <agraf at suse.de>
    Signed-off-by: Riku Voipio <riku.voipio at linaro.org>

diff --git a/linux-user/ioctls.h b/linux-user/ioctls.h
index 6514502..fd8b7bb 100644
--- a/linux-user/ioctls.h
+++ b/linux-user/ioctls.h
@@ -345,3 +345,35 @@
   IOCTL(VT_SETMODE, IOC_RW, MK_PTR(MK_STRUCT(STRUCT_vt_mode)))
   IOCTL(VT_RELDISP, 0, TYPE_INT)
   IOCTL(VT_DISALLOCATE, 0, TYPE_INT)
+
+  IOCTL(DM_VERSION, IOC_RW, MK_PTR(MK_STRUCT(STRUCT_dm_ioctl)))
+  IOCTL_SPECIAL(DM_REMOVE_ALL,   IOC_RW, do_ioctl_dm,
+                MK_PTR(MK_STRUCT(STRUCT_dm_ioctl)))
+  IOCTL_SPECIAL(DM_LIST_DEVICES, IOC_RW, do_ioctl_dm,
+                MK_PTR(MK_STRUCT(STRUCT_dm_ioctl)))
+  IOCTL_SPECIAL(DM_DEV_CREATE,   IOC_RW, do_ioctl_dm,
+                MK_PTR(MK_STRUCT(STRUCT_dm_ioctl)))
+  IOCTL_SPECIAL(DM_DEV_REMOVE,   IOC_RW, do_ioctl_dm,
+                MK_PTR(MK_STRUCT(STRUCT_dm_ioctl)))
+  IOCTL_SPECIAL(DM_DEV_RENAME,   IOC_RW, do_ioctl_dm,
+                MK_PTR(MK_STRUCT(STRUCT_dm_ioctl)))
+  IOCTL_SPECIAL(DM_DEV_SUSPEND,  IOC_RW, do_ioctl_dm,
+                MK_PTR(MK_STRUCT(STRUCT_dm_ioctl)))
+  IOCTL_SPECIAL(DM_DEV_STATUS,   IOC_RW, do_ioctl_dm,
+                MK_PTR(MK_STRUCT(STRUCT_dm_ioctl)))
+  IOCTL_SPECIAL(DM_DEV_WAIT,     IOC_RW, do_ioctl_dm,
+                MK_PTR(MK_STRUCT(STRUCT_dm_ioctl)))
+  IOCTL_SPECIAL(DM_TABLE_LOAD,   IOC_RW, do_ioctl_dm,
+                MK_PTR(MK_STRUCT(STRUCT_dm_ioctl)))
+  IOCTL_SPECIAL(DM_TABLE_CLEAR,  IOC_RW, do_ioctl_dm,
+                MK_PTR(MK_STRUCT(STRUCT_dm_ioctl)))
+  IOCTL_SPECIAL(DM_TABLE_DEPS,   IOC_RW, do_ioctl_dm,
+                MK_PTR(MK_STRUCT(STRUCT_dm_ioctl)))
+  IOCTL_SPECIAL(DM_TABLE_STATUS, IOC_RW, do_ioctl_dm,
+                MK_PTR(MK_STRUCT(STRUCT_dm_ioctl)))
+  IOCTL_SPECIAL(DM_LIST_VERSIONS,IOC_RW, do_ioctl_dm,
+                MK_PTR(MK_STRUCT(STRUCT_dm_ioctl)))
+  IOCTL_SPECIAL(DM_TARGET_MSG,   IOC_RW, do_ioctl_dm,
+                MK_PTR(MK_STRUCT(STRUCT_dm_ioctl)))
+  IOCTL_SPECIAL(DM_DEV_SET_GEOMETRY, IOC_RW, do_ioctl_dm,
+                MK_PTR(MK_STRUCT(STRUCT_dm_ioctl)))
diff --git a/linux-user/syscall.c b/linux-user/syscall.c
index 0e74ee0..9d1c8b2 100644
--- a/linux-user/syscall.c
+++ b/linux-user/syscall.c
@@ -95,6 +95,7 @@ int __clone2(int (*fn)(void *), void *child_stack_base,
 #endif
 #include <linux/fb.h>
 #include <linux/vt.h>
+#include <linux/dm-ioctl.h>
 #include "linux_loop.h"
 #include "cpu-uname.h"
 
@@ -3354,6 +3355,231 @@ static abi_long do_ioctl_ifconf(const IOCTLEntry *ie, uint8_t *buf_temp,
     return ret;
 }
 
+static abi_long do_ioctl_dm(const IOCTLEntry *ie, uint8_t *buf_temp, int fd,
+                            abi_long cmd, abi_long arg)
+{
+    void *argptr;
+    struct dm_ioctl *host_dm;
+    abi_long guest_data;
+    uint32_t guest_data_size;
+    int target_size;
+    const argtype *arg_type = ie->arg_type;
+    abi_long ret;
+    void *big_buf = NULL;
+    char *host_data;
+
+    arg_type++;
+    target_size = thunk_type_size(arg_type, 0);
+    argptr = lock_user(VERIFY_READ, arg, target_size, 1);
+    if (!argptr) {
+        ret = -TARGET_EFAULT;
+        goto out;
+    }
+    thunk_convert(buf_temp, argptr, arg_type, THUNK_HOST);
+    unlock_user(argptr, arg, 0);
+
+    /* buf_temp is too small, so fetch things into a bigger buffer */
+    big_buf = g_malloc0(((struct dm_ioctl*)buf_temp)->data_size * 2);
+    memcpy(big_buf, buf_temp, target_size);
+    buf_temp = big_buf;
+    host_dm = big_buf;
+
+    guest_data = arg + host_dm->data_start;
+    if ((guest_data - arg) < 0) {
+        ret = -EINVAL;
+        goto out;
+    }
+    guest_data_size = host_dm->data_size - host_dm->data_start;
+    host_data = (char*)host_dm + host_dm->data_start;
+
+    argptr = lock_user(VERIFY_READ, guest_data, guest_data_size, 1);
+    switch (ie->host_cmd) {
+    case DM_REMOVE_ALL:
+    case DM_LIST_DEVICES:
+    case DM_DEV_CREATE:
+    case DM_DEV_REMOVE:
+    case DM_DEV_SUSPEND:
+    case DM_DEV_STATUS:
+    case DM_DEV_WAIT:
+    case DM_TABLE_STATUS:
+    case DM_TABLE_CLEAR:
+    case DM_TABLE_DEPS:
+    case DM_LIST_VERSIONS:
+        /* no input data */
+        break;
+    case DM_DEV_RENAME:
+    case DM_DEV_SET_GEOMETRY:
+        /* data contains only strings */
+        memcpy(host_data, argptr, guest_data_size);
+        break;
+    case DM_TARGET_MSG:
+        memcpy(host_data, argptr, guest_data_size);
+        *(uint64_t*)host_data = tswap64(*(uint64_t*)argptr);
+        break;
+    case DM_TABLE_LOAD:
+    {
+        void *gspec = argptr;
+        void *cur_data = host_data;
+        const argtype arg_type[] = { MK_STRUCT(STRUCT_dm_target_spec) };
+        int spec_size = thunk_type_size(arg_type, 0);
+        int i;
+
+        for (i = 0; i < host_dm->target_count; i++) {
+            struct dm_target_spec *spec = cur_data;
+            uint32_t next;
+            int slen;
+
+            thunk_convert(spec, gspec, arg_type, THUNK_HOST);
+            slen = strlen((char*)gspec + spec_size) + 1;
+            next = spec->next;
+            spec->next = sizeof(*spec) + slen;
+            strcpy((char*)&spec[1], gspec + spec_size);
+            gspec += next;
+            cur_data += spec->next;
+        }
+        break;
+    }
+    default:
+        ret = -TARGET_EINVAL;
+        goto out;
+    }
+    unlock_user(argptr, guest_data, 0);
+
+    ret = get_errno(ioctl(fd, ie->host_cmd, buf_temp));
+    if (!is_error(ret)) {
+        guest_data = arg + host_dm->data_start;
+        guest_data_size = host_dm->data_size - host_dm->data_start;
+        argptr = lock_user(VERIFY_WRITE, guest_data, guest_data_size, 0);
+        switch (ie->host_cmd) {
+        case DM_REMOVE_ALL:
+        case DM_DEV_CREATE:
+        case DM_DEV_REMOVE:
+        case DM_DEV_RENAME:
+        case DM_DEV_SUSPEND:
+        case DM_DEV_STATUS:
+        case DM_TABLE_LOAD:
+        case DM_TABLE_CLEAR:
+        case DM_TARGET_MSG:
+        case DM_DEV_SET_GEOMETRY:
+            /* no return data */
+            break;
+        case DM_LIST_DEVICES:
+        {
+            struct dm_name_list *nl = (void*)host_dm + host_dm->data_start;
+            uint32_t remaining_data = guest_data_size;
+            void *cur_data = argptr;
+            const argtype arg_type[] = { MK_STRUCT(STRUCT_dm_name_list) };
+            int nl_size = 12; /* can't use thunk_size due to alignment */
+
+            while (1) {
+                uint32_t next = nl->next;
+                if (next) {
+                    nl->next = nl_size + (strlen(nl->name) + 1);
+                }
+                if (remaining_data < nl->next) {
+                    host_dm->flags |= DM_BUFFER_FULL_FLAG;
+                    break;
+                }
+                thunk_convert(cur_data, nl, arg_type, THUNK_TARGET);
+                strcpy(cur_data + nl_size, nl->name);
+                cur_data += nl->next;
+                remaining_data -= nl->next;
+                if (!next) {
+                    break;
+                }
+                nl = (void*)nl + next;
+            }
+            break;
+        }
+        case DM_DEV_WAIT:
+        case DM_TABLE_STATUS:
+        {
+            struct dm_target_spec *spec = (void*)host_dm + host_dm->data_start;
+            void *cur_data = argptr;
+            const argtype arg_type[] = { MK_STRUCT(STRUCT_dm_target_spec) };
+            int spec_size = thunk_type_size(arg_type, 0);
+            int i;
+
+            for (i = 0; i < host_dm->target_count; i++) {
+                uint32_t next = spec->next;
+                int slen = strlen((char*)&spec[1]) + 1;
+                spec->next = (cur_data - argptr) + spec_size + slen;
+                if (guest_data_size < spec->next) {
+                    host_dm->flags |= DM_BUFFER_FULL_FLAG;
+                    break;
+                }
+                thunk_convert(cur_data, spec, arg_type, THUNK_TARGET);
+                strcpy(cur_data + spec_size, (char*)&spec[1]);
+                cur_data = argptr + spec->next;
+                spec = (void*)host_dm + host_dm->data_start + next;
+            }
+            break;
+        }
+        case DM_TABLE_DEPS:
+        {
+            void *hdata = (void*)host_dm + host_dm->data_start;
+            int count = *(uint32_t*)hdata;
+            uint64_t *hdev = hdata + 8;
+            uint64_t *gdev = argptr + 8;
+            int i;
+
+            *(uint32_t*)argptr = tswap32(count);
+            for (i = 0; i < count; i++) {
+                *gdev = tswap64(*hdev);
+                gdev++;
+                hdev++;
+            }
+            break;
+        }
+        case DM_LIST_VERSIONS:
+        {
+            struct dm_target_versions *vers = (void*)host_dm + host_dm->data_start;
+            uint32_t remaining_data = guest_data_size;
+            void *cur_data = argptr;
+            const argtype arg_type[] = { MK_STRUCT(STRUCT_dm_target_versions) };
+            int vers_size = thunk_type_size(arg_type, 0);
+
+            while (1) {
+                uint32_t next = vers->next;
+                if (next) {
+                    vers->next = vers_size + (strlen(vers->name) + 1);
+                }
+                if (remaining_data < vers->next) {
+                    host_dm->flags |= DM_BUFFER_FULL_FLAG;
+                    break;
+                }
+                thunk_convert(cur_data, vers, arg_type, THUNK_TARGET);
+                strcpy(cur_data + vers_size, vers->name);
+                cur_data += vers->next;
+                remaining_data -= vers->next;
+                if (!next) {
+                    break;
+                }
+                vers = (void*)vers + next;
+            }
+            break;
+        }
+        default:
+            ret = -TARGET_EINVAL;
+            goto out;
+        }
+        unlock_user(argptr, guest_data, guest_data_size);
+
+        argptr = lock_user(VERIFY_WRITE, arg, target_size, 0);
+        if (!argptr) {
+            ret = -TARGET_EFAULT;
+            goto out;
+        }
+        thunk_convert(argptr, buf_temp, arg_type, THUNK_TARGET);
+        unlock_user(argptr, arg, target_size);
+    }
+out:
+    if (big_buf) {
+        free(big_buf);
+    }
+    return ret;
+}
+
 static IOCTLEntry ioctl_entries[] = {
 #define IOCTL(cmd, access, ...) \
     { TARGET_ ## cmd, cmd, #cmd, access, 0, {  __VA_ARGS__ } },
diff --git a/linux-user/syscall_defs.h b/linux-user/syscall_defs.h
index 41f0ff8..f8f3af3 100644
--- a/linux-user/syscall_defs.h
+++ b/linux-user/syscall_defs.h
@@ -989,6 +989,24 @@ struct target_pollfd {
 #define TARGET_VT_RELDISP             0x5605
 #define TARGET_VT_DISALLOCATE         0x5608
 
+/* device mapper */
+#define TARGET_DM_VERSION             TARGET_IOWRU(0xfd, 0x00)
+#define TARGET_DM_REMOVE_ALL          TARGET_IOWRU(0xfd, 0x01)
+#define TARGET_DM_LIST_DEVICES        TARGET_IOWRU(0xfd, 0x02)
+#define TARGET_DM_DEV_CREATE          TARGET_IOWRU(0xfd, 0x03)
+#define TARGET_DM_DEV_REMOVE          TARGET_IOWRU(0xfd, 0x04)
+#define TARGET_DM_DEV_RENAME          TARGET_IOWRU(0xfd, 0x05)
+#define TARGET_DM_DEV_SUSPEND         TARGET_IOWRU(0xfd, 0x06)
+#define TARGET_DM_DEV_STATUS          TARGET_IOWRU(0xfd, 0x07)
+#define TARGET_DM_DEV_WAIT            TARGET_IOWRU(0xfd, 0x08)
+#define TARGET_DM_TABLE_LOAD          TARGET_IOWRU(0xfd, 0x09)
+#define TARGET_DM_TABLE_CLEAR         TARGET_IOWRU(0xfd, 0x0a)
+#define TARGET_DM_TABLE_DEPS          TARGET_IOWRU(0xfd, 0x0b)
+#define TARGET_DM_TABLE_STATUS        TARGET_IOWRU(0xfd, 0x0c)
+#define TARGET_DM_LIST_VERSIONS       TARGET_IOWRU(0xfd, 0x0d)
+#define TARGET_DM_TARGET_MSG          TARGET_IOWRU(0xfd, 0x0e)
+#define TARGET_DM_DEV_SET_GEOMETRY    TARGET_IOWRU(0xfd, 0x0f)
+
 /* from asm/termbits.h */
 
 #define TARGET_NCC 8
diff --git a/linux-user/syscall_types.h b/linux-user/syscall_types.h
index c370125..fb8c9c9 100644
--- a/linux-user/syscall_types.h
+++ b/linux-user/syscall_types.h
@@ -186,6 +186,42 @@ STRUCT(vt_mode,
        TYPE_SHORT, /* acqsig */
        TYPE_SHORT) /* frsig  */
 
+STRUCT(dm_ioctl,
+       MK_ARRAY(TYPE_INT, 3), /* version */
+       TYPE_INT, /* data_size */
+       TYPE_INT, /* data_start */
+       TYPE_INT, /* target_count*/
+       TYPE_INT, /* open_count */
+       TYPE_INT, /* flags */
+       TYPE_INT, /* event_nr */
+       TYPE_INT, /* padding */
+       TYPE_ULONGLONG, /* dev */
+       MK_ARRAY(TYPE_CHAR, 128), /* name */
+       MK_ARRAY(TYPE_CHAR, 129), /* uuid */
+       MK_ARRAY(TYPE_CHAR, 7)) /* data */
+
+STRUCT(dm_target_spec,
+       TYPE_ULONGLONG, /* sector_start */
+       TYPE_ULONGLONG, /* length */
+       TYPE_INT, /* status */
+       TYPE_INT, /* next */
+       MK_ARRAY(TYPE_CHAR, 16)) /* target_type */
+
+STRUCT(dm_target_deps,
+       TYPE_INT, /* count */
+       TYPE_INT) /* padding */
+
+STRUCT(dm_name_list,
+       TYPE_ULONGLONG, /* dev */
+       TYPE_INT) /* next */
+
+STRUCT(dm_target_versions,
+       TYPE_INT, /* next */
+       MK_ARRAY(TYPE_INT, 3)) /* version*/
+
+STRUCT(dm_target_msg,
+       TYPE_ULONGLONG) /* sector */
+
 STRUCT(fiemap_extent,
        TYPE_ULONGLONG, /* fe_logical */
        TYPE_ULONGLONG, /* fe_physical */
commit 84803b87a183bd71963584c3be5ca838d32c55df
Author: Fabio Erculiani <lxnay at sabayon.org>
Date:   Tue Jan 3 09:38:35 2012 +0000

    linux-user: target_argv is placed on ts->bprm->argv and can't be freed()
    
    TaskState contains linux_bprm struct which encapsulates argv among
    other things.
    argv might be used around the code and is expected to contain valid
    data. Before this patch, ts->bprm->argv was NULL due to it being
    freed right after loader_exec().
    
    Signed-off-by: Fabio Erculiani <lxnay at sabayon.org>
    Acked-by: Alexander Graf <agraf at suse.de>
    Signed-off-by: Alexander Graf <agraf at suse.de>
    Signed-off-by: Riku Voipio <riku.voipio at linaro.org>

diff --git a/linux-user/main.c b/linux-user/main.c
index 962677e..2570140 100644
--- a/linux-user/main.c
+++ b/linux-user/main.c
@@ -3486,11 +3486,6 @@ int main(int argc, char **argv, char **envp)
         _exit(1);
     }
 
-    for (i = 0; i < target_argc; i++) {
-        free(target_argv[i]);
-    }
-    free(target_argv);
-
     for (wrk = target_environ; *wrk; wrk++) {
         free(*wrk);
     }
commit e0e65bee16ae8515315d2bad02e021f3fb5dd236
Author: Fabio Erculiani <lxnay at sabayon.org>
Date:   Tue Jan 3 09:38:34 2012 +0000

    linux-user: improve fake /proc/self/stat making `ps` not segfault.
    
    With the current fake /proc/self/stat implementation `ps` is
    segfaulting because it expects to read PID and argv[0] as first and
    second field respectively, with the latter being enclosed between
    backets.
    
    Reproducing is as easy as running: `ps` inside qemu-user chroot
    with /proc mounted.
    
    Signed-off-by: Fabio Erculiani <lxnay at sabayon.org>
    Acked-by: Alexander Graf <agraf at suse.de>
    Signed-off-by: Alexander Graf <agraf at suse.de>
    Signed-off-by: Riku Voipio <riku.voipio at linaro.org>

diff --git a/linux-user/syscall.c b/linux-user/syscall.c
index 9f5e53a..0e74ee0 100644
--- a/linux-user/syscall.c
+++ b/linux-user/syscall.c
@@ -4662,11 +4662,22 @@ static int open_self_stat(void *cpu_env, int fd)
       int len;
       uint64_t val = 0;
 
-      if (i == 27) {
-          /* stack bottom */
-          val = start_stack;
+      if (i == 0) {
+        /* pid */
+        val = getpid();
+        snprintf(buf, sizeof(buf), "%"PRId64 " ", val);
+      } else if (i == 1) {
+        /* app name */
+        snprintf(buf, sizeof(buf), "(%s) ", ts->bprm->argv[0]);
+      } else if (i == 27) {
+        /* stack bottom */
+        val = start_stack;
+        snprintf(buf, sizeof(buf), "%"PRId64 " ", val);
+      } else {
+        /* for the rest, there is MasterCard */
+        snprintf(buf, sizeof(buf), "0%c", i == 43 ? '\n' : ' ');
       }
-      snprintf(buf, sizeof(buf), "%"PRId64 "%c", val, i == 43 ? '\n' : ' ');
+
       len = strlen(buf);
       if (write(fd, buf, len) != len) {
           return -1;
commit 50d30c267563bf492fd403dd23abc7888f3e220c
Author: Benoît Canet <benoit.canet at gmail.com>
Date:   Fri Mar 23 08:36:54 2012 +0100

    qed: remove incoming live migration blocker
    
    Signed-off-by: Benoit Canet <benoit.canet at gmail.com>
    Reviewed-by: Stefan Hajnoczi <stefanha at gmail.com>
    Signed-off-by: Kevin Wolf <kwolf at redhat.com>

diff --git a/block/qed.c b/block/qed.c
index aea2772..366cde7 100644
--- a/block/qed.c
+++ b/block/qed.c
@@ -498,12 +498,6 @@ static int bdrv_qed_open(BlockDriverState *bs, int flags)
     s->need_check_timer = qemu_new_timer_ns(vm_clock,
                                             qed_need_check_timer_cb, s);
 
-    error_set(&s->migration_blocker,
-              QERR_BLOCK_FORMAT_FEATURE_NOT_SUPPORTED,
-              "qed", bs->device_name, "live migration");
-    migrate_add_blocker(s->migration_blocker);
-
-
 out:
     if (ret) {
         qed_free_l2_cache(&s->l2_cache);
@@ -516,9 +510,6 @@ static void bdrv_qed_close(BlockDriverState *bs)
 {
     BDRVQEDState *s = bs->opaque;
 
-    migrate_del_blocker(s->migration_blocker);
-    error_free(s->migration_blocker);
-
     qed_cancel_need_check_timer(s);
     qemu_free_timer(s->need_check_timer);
 
diff --git a/block/qed.h b/block/qed.h
index 62624a1..c716772 100644
--- a/block/qed.h
+++ b/block/qed.h
@@ -169,8 +169,6 @@ typedef struct {
 
     /* Periodic flush and clear need check flag */
     QEMUTimer *need_check_timer;
-
-    Error *migration_blocker;
 } BDRVQEDState;
 
 enum {
commit 2d1f3c2360053dec7dacc0292f52cff17104feff
Author: Benoît Canet <benoit.canet at gmail.com>
Date:   Fri Mar 23 08:36:53 2012 +0100

    qed: honor BDRV_O_INCOMING for incoming live migration
    
    From original commit with Patchwork-id: 31108 by
    Stefan Hajnoczi <stefanha at linux.vnet.ibm.com>
    
    "The QED image format includes a file header bit to mark images dirty.
    QED normally checks dirty images on open and fixes inconsistent
    metadata.  This is undesirable during live migration since the dirty bit
    may be set if the source host is modifying the image file.  The check
    should be postponed until migration completes.
    
    Skip operations that modify the image file if the BDRV_O_INCOMING flag
    is set."
    
    Signed-off-by: Benoit Canet <benoit.canet at gmail.com>
    Reviewed-by: Stefan Hajnoczi <stefanha at gmail.com>
    Signed-off-by: Kevin Wolf <kwolf at redhat.com>

diff --git a/block/qed.c b/block/qed.c
index a5e9d57..aea2772 100644
--- a/block/qed.c
+++ b/block/qed.c
@@ -450,7 +450,7 @@ static int bdrv_qed_open(BlockDriverState *bs, int flags)
      * feature is no longer valid.
      */
     if ((s->header.autoclear_features & ~QED_AUTOCLEAR_FEATURE_MASK) != 0 &&
-        !bdrv_is_read_only(bs->file)) {
+        !bdrv_is_read_only(bs->file) && !(flags & BDRV_O_INCOMING)) {
         s->header.autoclear_features &= QED_AUTOCLEAR_FEATURE_MASK;
 
         ret = qed_write_header_sync(s);
@@ -477,7 +477,8 @@ static int bdrv_qed_open(BlockDriverState *bs, int flags)
          * potentially inconsistent images to be opened read-only.  This can
          * aid data recovery from an otherwise inconsistent image.
          */
-        if (!bdrv_is_read_only(bs->file)) {
+        if (!bdrv_is_read_only(bs->file) &&
+            !(flags & BDRV_O_INCOMING)) {
             BdrvCheckResult result = {0};
 
             ret = qed_check(s, &result, true);
commit 901862cbf49639aaef23a575d40ae81282b6fcfc
Author: Benoît Canet <benoit.canet at gmail.com>
Date:   Fri Mar 23 08:36:52 2012 +0100

    migration: clear BDRV_O_INCOMING flags on end of incoming live migration
    
    Signed-off-by: Benoît Canet <benoit.canet at gmail.com>
    Reviewed-by: Stefan Hajnoczi <stefanha at gmail.com>
    Signed-off-by: Kevin Wolf <kwolf at redhat.com>

diff --git a/migration.c b/migration.c
index 8c119ba..94f7839 100644
--- a/migration.c
+++ b/migration.c
@@ -91,6 +91,7 @@ void process_incoming_migration(QEMUFile *f)
     qemu_announce_self();
     DPRINTF("successfully loaded vm state\n");
 
+    bdrv_clear_incoming_migration_all();
     /* Make sure all file formats flush their mutable metadata */
     bdrv_invalidate_cache_all();
 
commit c82954e529929c2d650589d8bccaaf19dec33431
Author: Benoît Canet <benoit.canet at gmail.com>
Date:   Fri Mar 23 08:36:51 2012 +0100

    qed: add bdrv_invalidate_cache to be called after incoming live migration
    
    The QED image is reopened to flush metadata and check consistency.
    
    Signed-off-by: Benoit Canet <benoit.canet at gmail.com>
    Reviewed-by: Stefan Hajnoczi <stefanha at gmail.com>
    Signed-off-by: Kevin Wolf <kwolf at redhat.com>

diff --git a/block/qed.c b/block/qed.c
index 19d87f3..a5e9d57 100644
--- a/block/qed.c
+++ b/block/qed.c
@@ -1510,6 +1510,15 @@ static int bdrv_qed_change_backing_file(BlockDriverState *bs,
     return ret;
 }
 
+static void bdrv_qed_invalidate_cache(BlockDriverState *bs)
+{
+    BDRVQEDState *s = bs->opaque;
+
+    bdrv_qed_close(bs);
+    memset(s, 0, sizeof(BDRVQEDState));
+    bdrv_qed_open(bs, bs->open_flags);
+}
+
 static int bdrv_qed_check(BlockDriverState *bs, BdrvCheckResult *result)
 {
     BDRVQEDState *s = bs->opaque;
@@ -1561,6 +1570,7 @@ static BlockDriver bdrv_qed = {
     .bdrv_getlength           = bdrv_qed_getlength,
     .bdrv_get_info            = bdrv_qed_get_info,
     .bdrv_change_backing_file = bdrv_qed_change_backing_file,
+    .bdrv_invalidate_cache    = bdrv_qed_invalidate_cache,
     .bdrv_check               = bdrv_qed_check,
 };
 
commit ed9d4205cecb2f6c06821cb9d8fe9e1ca5f9b8ab
Author: Benoît Canet <benoit.canet at gmail.com>
Date:   Fri Mar 23 08:36:50 2012 +0100

    blockdev: open images with BDRV_O_INCOMING on incoming live migration
    
    Open images with BDRV_O_INCOMING in order to inform block drivers
    that an incoming live migration is coming.
    
    Signed-off-by: Benoit Canet <benoit.canet at gmail.com>
    Reviewed-by: Stefan Hajnoczi <stefanha at gmail.com>
    Signed-off-by: Kevin Wolf <kwolf at redhat.com>

diff --git a/blockdev.c b/blockdev.c
index 4d17486..0c2440e 100644
--- a/blockdev.c
+++ b/blockdev.c
@@ -595,6 +595,10 @@ DriveInfo *drive_init(QemuOpts *opts, int default_to_scsi)
         bdrv_flags |= BDRV_O_COPY_ON_READ;
     }
 
+    if (runstate_check(RUN_STATE_INMIGRATE)) {
+        bdrv_flags |= BDRV_O_INCOMING;
+    }
+
     if (media == MEDIA_CDROM) {
         /* CDROM is fine for any interface, don't check.  */
         ro = 1;
commit 077892696b900ebf88052fef917367213db80477
Author: Benoît Canet <benoit.canet at gmail.com>
Date:   Fri Mar 23 08:36:49 2012 +0100

    block: add a function to clear incoming live migration flags
    
    This function will clear all BDRV_O_INCOMING flags.
    
    Signed-off-by: Benoit Canet <benoit.canet at gmail.com>
    Reviewed-by: Stefan Hajnoczi <stefanha at gmail.com>
    Signed-off-by: Kevin Wolf <kwolf at redhat.com>

diff --git a/block.c b/block.c
index b3117ef..c0c90f0 100644
--- a/block.c
+++ b/block.c
@@ -3624,6 +3624,15 @@ void bdrv_invalidate_cache_all(void)
     }
 }
 
+void bdrv_clear_incoming_migration_all(void)
+{
+    BlockDriverState *bs;
+
+    QTAILQ_FOREACH(bs, &bdrv_states, list) {
+        bs->open_flags = bs->open_flags & ~(BDRV_O_INCOMING);
+    }
+}
+
 int bdrv_flush(BlockDriverState *bs)
 {
     Coroutine *co;
diff --git a/block.h b/block.h
index 5151dea..f163e54 100644
--- a/block.h
+++ b/block.h
@@ -229,6 +229,8 @@ BlockDriverAIOCB *bdrv_aio_ioctl(BlockDriverState *bs,
 void bdrv_invalidate_cache(BlockDriverState *bs);
 void bdrv_invalidate_cache_all(void);
 
+void bdrv_clear_incoming_migration_all(void);
+
 /* Ensure contents are flushed to disk.  */
 int bdrv_flush(BlockDriverState *bs);
 int coroutine_fn bdrv_co_flush(BlockDriverState *bs);
commit ccb1f4a7b32fbebcf0d49beab1d2614f0a657d5a
Author: Benoît Canet <benoit.canet at gmail.com>
Date:   Fri Mar 23 08:36:48 2012 +0100

    block: Add new BDRV_O_INCOMING flag to notice incoming live migration
    
    From original patch with Patchwork-id: 31110 by
    Stefan Hajnoczi <stefanha at linux.vnet.ibm.com>
    
    "Add a flag to indicate that incoming migration is pending and care needs
    to be taken for data consistency.  Block drivers should not modify the
    image file before incoming migration is complete since the migration
    source host is still using the image file."
    
    The rationale for not using bdrv->read_only is the following.
    
    "Unfortunately this is not possible because too many other places in QEMU
    test bdrv_is_read_only() and use it for their own evil purposes.  For
    example, ide_init_drive() will error out because read-only harddisks are
    not supported.  We're mixing guest and host side read-only concepts so
    this simpler alternative does not work."
    
    Signed-off-by: Benoit Canet <benoit.canet at gmail.com>
    Reviewed-by: Stefan Hajnoczi <stefanha at gmail.com>
    Signed-off-by: Kevin Wolf <kwolf at redhat.com>

diff --git a/block.h b/block.h
index 4e99e18..5151dea 100644
--- a/block.h
+++ b/block.h
@@ -78,6 +78,7 @@ typedef struct BlockDevOps {
 #define BDRV_O_NO_BACKING  0x0100 /* don't open the backing file */
 #define BDRV_O_NO_FLUSH    0x0200 /* disable flushing on this disk */
 #define BDRV_O_COPY_ON_READ 0x0400 /* copy read backing sectors into image */
+#define BDRV_O_INCOMING    0x0800  /* consistency hint for incoming migration */
 
 #define BDRV_O_CACHE_MASK  (BDRV_O_NOCACHE | BDRV_O_CACHE_WB | BDRV_O_NO_FLUSH)
 
commit 5a67a1048e1294b35940e7432d57d8cd801e6571
Author: Marcelo Tosatti <mtosatti at redhat.com>
Date:   Mon Mar 26 21:22:10 2012 -0300

    block stream: close unused files and update ->backing_hd
    
    Close the now unused images that were part of the previous backing file
    chain and adjust ->backing_hd, backing_filename and backing_format
    properly.
    
    Fixes https://bugzilla.redhat.com/show_bug.cgi?id=801449
    
    Signed-off-by: Marcelo Tosatti <mtosatti at redhat.com>
    Reviewed-by: Stefan Hajnoczi <stefanha at linux.vnet.ibm.com>
    Signed-off-by: Kevin Wolf <kwolf at redhat.com>

diff --git a/block/stream.c b/block/stream.c
index 61ff7a2..0efe1ad 100644
--- a/block/stream.c
+++ b/block/stream.c
@@ -76,6 +76,39 @@ static int coroutine_fn stream_populate(BlockDriverState *bs,
     return bdrv_co_copy_on_readv(bs, sector_num, nb_sectors, &qiov);
 }
 
+static void close_unused_images(BlockDriverState *top, BlockDriverState *base,
+                                const char *base_id)
+{
+    BlockDriverState *intermediate;
+    intermediate = top->backing_hd;
+
+    while (intermediate) {
+        BlockDriverState *unused;
+
+        /* reached base */
+        if (intermediate == base) {
+            break;
+        }
+
+        unused = intermediate;
+        intermediate = intermediate->backing_hd;
+        unused->backing_hd = NULL;
+        bdrv_delete(unused);
+    }
+    top->backing_hd = base;
+
+    pstrcpy(top->backing_file, sizeof(top->backing_file), "");
+    pstrcpy(top->backing_format, sizeof(top->backing_format), "");
+    if (base_id) {
+        pstrcpy(top->backing_file, sizeof(top->backing_file), base_id);
+        if (base->drv) {
+            pstrcpy(top->backing_format, sizeof(top->backing_format),
+                    base->drv->format_name);
+        }
+    }
+
+}
+
 /*
  * Given an image chain: [BASE] -> [INTER1] -> [INTER2] -> [TOP]
  *
@@ -223,6 +256,7 @@ retry:
             base_id = s->backing_file_id;
         }
         ret = bdrv_change_backing_file(bs, base_id, NULL);
+        close_unused_images(bs, base, base_id);
     }
 
     qemu_vfree(buf);
commit 28d3d1658a3692f9c34c3ecce14941faa1d2fe92
Author: Stefan Weil <sw at weilnetz.de>
Date:   Wed Mar 14 19:57:24 2012 +0100

    qemu-iotests: Fix call syntax for qemu-io
    
    qemu-io requires options first, then fixed parameters.
    
    GNU getopt also allows options at the end, but POSIX getopt
    doesn't. Try "export POSIXLY_CORRECT=y" to get the POSIX
    behaviour with GNU getopt, too.
    
    Cc: Kevin Wolf <kwolf at redhat.com>
    Signed-off-by: Stefan Weil <sw at weilnetz.de>
    Signed-off-by: Kevin Wolf <kwolf at redhat.com>

diff --git a/tests/qemu-iotests/009 b/tests/qemu-iotests/009
index f7262b5..25368c8 100755
--- a/tests/qemu-iotests/009
+++ b/tests/qemu-iotests/009
@@ -53,10 +53,10 @@ _make_test_img $size
 echo
 echo "creating pattern"
 $QEMU_IO \
-	-c "write 2048k 4k -P 65" \
+	-c "write -P 65 2048k 4k" \
 	-c "write 4k 4k" \
 	-c "write 9M 4k" \
-	-c "read 2044k 8k -P 65 -s 4k -l 4k" \
+	-c "read -P 65 -s 4k -l 4k 2044k 8k" \
 $TEST_IMG | _filter_qemu_io
 
 echo
diff --git a/tests/qemu-iotests/010 b/tests/qemu-iotests/010
index e3205aa..7b57929 100755
--- a/tests/qemu-iotests/010
+++ b/tests/qemu-iotests/010
@@ -53,11 +53,11 @@ _make_test_img $size
 echo
 echo "creating pattern"
 $QEMU_IO \
-	-c "write 2048k 4k -P 165" \
+	-c "write -P 165 2048k 4k" \
 	-c "write 64k 4k" \
 	-c "write 9M 4k" \
-	-c "write 2044k 4k -P 165" \
-	-c "write 8M 4k -P 99" \
+	-c "write -P 165 2044k 4k" \
+	-c "write -P 99 8M 4k" \
 	-c "read -P 165 2044k 8k" \
 $TEST_IMG | _filter_qemu_io
 
diff --git a/tests/qemu-iotests/011 b/tests/qemu-iotests/011
index 59df1ae..b03df68 100755
--- a/tests/qemu-iotests/011
+++ b/tests/qemu-iotests/011
@@ -60,7 +60,7 @@ for i in `seq 1 10`; do
     # Note that we filter away the actual offset.  That's because qemu
     # may re-order the two aio requests.  We only want to make sure the
     # filesystem isn't corrupted afterwards anyway.
-    $QEMU_IO $TEST_IMG -c "aio_write $off1 1M" -c "aio_write $off2 1M" | \
+    $QEMU_IO -c "aio_write $off1 1M" -c "aio_write $off2 1M" $TEST_IMG | \
     	_filter_qemu_io | \
 	sed -e 's/bytes at offset [0-9]*/bytes at offset XXX/g'
 done
commit 21af81488799e2290cb2e58eb2a91d1d8044ebc4
Author: Stefan Weil <sw at weilnetz.de>
Date:   Wed Mar 14 19:57:23 2012 +0100

    qemu-iotests: Fix call syntax for qemu-img
    
    qemu-img requires first options, then file name, then size.
    
    GNU getopt also allows options at the end, but POSIX getopt
    doesn't. Try "export POSIXLY_CORRECT=y" to get the POSIX
    behaviour with GNU getopt, too.
    
    Cc: Kevin Wolf <kwolf at redhat.com>
    Signed-off-by: Stefan Weil <sw at weilnetz.de>
    Signed-off-by: Kevin Wolf <kwolf at redhat.com>

diff --git a/tests/qemu-iotests/common.rc b/tests/qemu-iotests/common.rc
index 26811ca..4cb8dae 100644
--- a/tests/qemu-iotests/common.rc
+++ b/tests/qemu-iotests/common.rc
@@ -57,16 +57,21 @@ _make_test_img()
 {
     # extra qemu-img options can be added by tests
     # at least one argument (the image size) needs to be added
-    local extra_img_options=$*
+    local extra_img_options=""
     local cluster_size_filter="s# cluster_size=[0-9]\\+##g"
+    local image_size=$*
 
+    if [ "$1" = "-b" ]; then
+        extra_img_options="$1 $2"
+        image_size=$3
+    fi
     if [ \( "$IMGFMT" = "qcow2" -o "$IMGFMT" = "qed" \) -a -n "$CLUSTER_SIZE" ]; then
         extra_img_options="-o cluster_size=$CLUSTER_SIZE $extra_img_options"
         cluster_size_filter=""
     fi
 
     # XXX(hch): have global image options?
-    $QEMU_IMG create -f $IMGFMT $TEST_IMG $extra_img_options | \
+    $QEMU_IMG create -f $IMGFMT $extra_img_options $TEST_IMG $image_size | \
     	sed -e "s#$IMGPROTO:$TEST_DIR#TEST_DIR#g" | \
     	sed -e "s#$TEST_DIR#TEST_DIR#g" | \
     	sed -e "s#$IMGFMT#IMGFMT#g" | \
commit f394f1feb921d5a4b278e7ac95bdaa49e34a52f2
Author: Kevin Wolf <kwolf at redhat.com>
Date:   Thu Feb 16 16:55:01 2012 +0100

    qemu-iotests: Test unknown qcow2 header extensions
    
    The immportant thing here is that header extensions don't get silently
    dropped when the header is rewritten, e.g. during a rebase.
    
    Signed-off-by: Kevin Wolf <kwolf at redhat.com>

diff --git a/tests/qemu-iotests/031 b/tests/qemu-iotests/031
new file mode 100755
index 0000000..6365f28
--- /dev/null
+++ b/tests/qemu-iotests/031
@@ -0,0 +1,72 @@
+#!/bin/bash
+#
+# Test that all qcow2 header extensions survive a header rewrite
+#
+# Copyright (C) 2011 Red Hat, Inc.
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program.  If not, see <http://www.gnu.org/licenses/>.
+#
+
+# creator
+owner=kwolf at redhat.com
+
+seq=`basename $0`
+echo "QA output created by $seq"
+
+here=`pwd`
+tmp=/tmp/$$
+status=1	# failure is the default!
+
+_cleanup()
+{
+	_cleanup_test_img
+}
+trap "_cleanup; exit \$status" 0 1 2 3 15
+
+# get standard environment, filters and checks
+. ./common.rc
+. ./common.filter
+. ./common.pattern
+
+# This tests qcow2-specific low-level functionality
+_supported_fmt qcow2
+_supported_proto generic
+_supported_os Linux
+
+CLUSTER_SIZE=65536
+echo
+echo === Create image with unknown header extension ===
+echo
+_make_test_img 64M
+./qcow2.py $TEST_IMG add-header-ext 0x12345678 "This is a test header extension"
+./qcow2.py $TEST_IMG dump-header
+_check_test_img
+
+echo
+echo === Rewrite header with no backing file ===
+echo
+$QEMU_IMG rebase -u -b "" $TEST_IMG
+./qcow2.py $TEST_IMG dump-header
+_check_test_img
+
+echo
+echo === Add a backing file and format ===
+echo
+$QEMU_IMG rebase -u -b "/some/backing/file/path" -F host_device $TEST_IMG
+./qcow2.py $TEST_IMG dump-header
+
+# success, all done
+echo "*** done"
+rm -f $seq.full
+status=0
diff --git a/tests/qemu-iotests/031.out b/tests/qemu-iotests/031.out
new file mode 100644
index 0000000..0f1bf68
--- /dev/null
+++ b/tests/qemu-iotests/031.out
@@ -0,0 +1,76 @@
+QA output created by 031
+
+=== Create image with unknown header extension ===
+
+Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=67108864 cluster_size=65536 
+magic                     0x514649fb
+version                   2
+backing_file_offset       0x0
+backing_file_size         0x0
+cluster_bits              16
+size                      67108864
+crypt_method              0
+l1_size                   1
+l1_table_offset           0x30000
+refcount_table_offset     0x10000
+refcount_table_clusters   1
+nb_snapshots              0
+snapshot_offset           0x0
+
+Header extension:
+magic                     0x12345678
+length                    31
+data                      'This is a test header extension'
+
+No errors were found on the image.
+
+=== Rewrite header with no backing file ===
+
+magic                     0x514649fb
+version                   2
+backing_file_offset       0x0
+backing_file_size         0x0
+cluster_bits              16
+size                      67108864
+crypt_method              0
+l1_size                   1
+l1_table_offset           0x30000
+refcount_table_offset     0x10000
+refcount_table_clusters   1
+nb_snapshots              0
+snapshot_offset           0x0
+
+Header extension:
+magic                     0x12345678
+length                    31
+data                      'This is a test header extension'
+
+No errors were found on the image.
+
+=== Add a backing file and format ===
+
+magic                     0x514649fb
+version                   2
+backing_file_offset       0x90
+backing_file_size         0x17
+cluster_bits              16
+size                      67108864
+crypt_method              0
+l1_size                   1
+l1_table_offset           0x30000
+refcount_table_offset     0x10000
+refcount_table_clusters   1
+nb_snapshots              0
+snapshot_offset           0x0
+
+Header extension:
+magic                     0xe2792aca
+length                    11
+data                      'host_device'
+
+Header extension:
+magic                     0x12345678
+length                    31
+data                      'This is a test header extension'
+
+*** done
diff --git a/tests/qemu-iotests/group b/tests/qemu-iotests/group
index b549f10..1742ede 100644
--- a/tests/qemu-iotests/group
+++ b/tests/qemu-iotests/group
@@ -37,3 +37,4 @@
 028 rw backing auto
 029 rw auto quick
 030 rw auto
+031 rw auto quick
commit 6e19b3c4e0b40b08ccb550a0c0a65798f3a17ac8
Author: Kevin Wolf <kwolf at redhat.com>
Date:   Wed Feb 15 16:36:03 2012 +0100

    qemu-iotests: qcow2.py
    
    This adds a tool that is meant to inspect and edit qcow2 files in a
    low-level way, that wouldn't be possible with qemu-img/io, for example
    by adding yet unknown extensions or flags. This way we can test whether
    qemu deals properly with future backwards compatible extensions.
    
    For now, let's start with the image header and header extensions.
    
    Signed-off-by: Kevin Wolf <kwolf at redhat.com>

diff --git a/tests/qemu-iotests/qcow2.py b/tests/qemu-iotests/qcow2.py
new file mode 100755
index 0000000..bfb47e8
--- /dev/null
+++ b/tests/qemu-iotests/qcow2.py
@@ -0,0 +1,207 @@
+#!/usr/bin/env python
+
+import sys
+import struct
+import string
+
+class QcowHeaderExtension:
+
+    def __init__(self, magic, length, data):
+        self.magic  = magic
+        self.length = length
+        self.data   = data
+
+    @classmethod
+    def create(cls, magic, data):
+        return QcowHeaderExtension(magic, len(data), data)
+
+class QcowHeader:
+
+    uint32_t = 'I'
+    uint64_t = 'Q'
+
+    fields = [
+        # Version 2 header fields
+        [ uint32_t, '%#x',  'magic' ],
+        [ uint32_t, '%d',   'version' ],
+        [ uint64_t, '%#x',  'backing_file_offset' ],
+        [ uint32_t, '%#x',  'backing_file_size' ],
+        [ uint32_t, '%d',   'cluster_bits' ],
+        [ uint64_t, '%d',   'size' ],
+        [ uint32_t, '%d',   'crypt_method' ],
+        [ uint32_t, '%d',   'l1_size' ],
+        [ uint64_t, '%#x',  'l1_table_offset' ],
+        [ uint64_t, '%#x',  'refcount_table_offset' ],
+        [ uint32_t, '%d',   'refcount_table_clusters' ],
+        [ uint32_t, '%d',   'nb_snapshots' ],
+        [ uint64_t, '%#x',  'snapshot_offset' ],
+    ];
+
+    fmt = '>' + ''.join(field[0] for field in fields)
+
+    def __init__(self, fd):
+
+        buf_size = struct.calcsize(QcowHeader.fmt)
+
+        fd.seek(0)
+        buf = fd.read(buf_size)
+
+        header = struct.unpack(QcowHeader.fmt, buf)
+        self.__dict__ = dict((field[2], header[i])
+            for i, field in enumerate(QcowHeader.fields))
+
+        self.cluster_size = 1 << self.cluster_bits
+
+        fd.seek(self.get_header_length())
+        self.load_extensions(fd)
+
+        if self.backing_file_offset:
+            fd.seek(self.backing_file_offset)
+            self.backing_file = fd.read(self.backing_file_size)
+        else:
+            self.backing_file = None
+
+    def get_header_length(self):
+        if self.version == 2:
+            return 72
+        else:
+            raise Exception("version != 2 not supported")
+
+    def load_extensions(self, fd):
+        self.extensions = []
+
+        if self.backing_file_offset != 0:
+            end = min(self.cluster_size, self.backing_file_offset)
+        else:
+            end = self.cluster_size
+
+        while fd.tell() < end:
+            (magic, length) = struct.unpack('>II', fd.read(8))
+            if magic == 0:
+                break
+            else:
+                padded = (length + 7) & ~7
+                data = fd.read(padded)
+                self.extensions.append(QcowHeaderExtension(magic, length, data))
+
+    def update_extensions(self, fd):
+
+        fd.seek(self.get_header_length())
+        extensions = self.extensions
+        extensions.append(QcowHeaderExtension(0, 0, ""))
+        for ex in extensions:
+            buf = struct.pack('>II', ex.magic, ex.length)
+            fd.write(buf)
+            fd.write(ex.data)
+
+        if self.backing_file != None:
+            self.backing_file_offset = fd.tell()
+            fd.write(self.backing_file)
+
+        if fd.tell() > self.cluster_size:
+            raise Exception("I think I just broke the image...")
+
+
+    def update(self, fd):
+        header_bytes = self.get_header_length()
+
+        self.update_extensions(fd)
+
+        fd.seek(0)
+        header = tuple(self.__dict__[f] for t, p, f in QcowHeader.fields)
+        buf = struct.pack(QcowHeader.fmt, *header)
+        buf = buf[0:header_bytes-1]
+        fd.write(buf)
+
+    def dump(self):
+        for f in QcowHeader.fields:
+            print "%-25s" % f[2], f[1] % self.__dict__[f[2]]
+        print ""
+
+    def dump_extensions(self):
+        for ex in self.extensions:
+
+            data = ex.data[:ex.length]
+            if all(c in string.printable for c in data):
+                data = "'%s'" % data
+            else:
+                data = "<binary>"
+
+            print "Header extension:"
+            print "%-25s %#x" % ("magic", ex.magic)
+            print "%-25s %d" % ("length", ex.length)
+            print "%-25s %s" % ("data", data)
+            print ""
+
+
+def cmd_dump_header(fd):
+    h = QcowHeader(fd)
+    h.dump()
+    h.dump_extensions()
+
+def cmd_add_header_ext(fd, magic, data):
+    try:
+        magic = int(magic, 0)
+    except:
+        print "'%s' is not a valid magic number" % magic
+        sys.exit(1)
+
+    h = QcowHeader(fd)
+    h.extensions.append(QcowHeaderExtension.create(magic, data))
+    h.update(fd)
+
+def cmd_del_header_ext(fd, magic):
+    try:
+        magic = int(magic, 0)
+    except:
+        print "'%s' is not a valid magic number" % magic
+        sys.exit(1)
+
+    h = QcowHeader(fd)
+    found = False
+
+    for ex in h.extensions:
+        if ex.magic == magic:
+            found = True
+            h.extensions.remove(ex)
+
+    if not found:
+        print "No such header extension"
+        return
+
+    h.update(fd)
+
+cmds = [
+    [ 'dump-header',    cmd_dump_header,    0, 'Dump image header and header extensions' ],
+    [ 'add-header-ext', cmd_add_header_ext, 2, 'Add a header extension' ],
+    [ 'del-header-ext', cmd_del_header_ext, 1, 'Delete a header extension' ],
+]
+
+def main(filename, cmd, args):
+    fd = open(filename, "r+b")
+    try:
+        for name, handler, num_args, desc in cmds:
+            if name != cmd:
+                continue
+            elif len(args) != num_args:
+                usage()
+                return
+            else:
+                handler(fd, *args)
+                return
+        print "Unknown command '%s'" % cmd
+    finally:
+        fd.close()
+
+def usage():
+    print "Usage: %s <file> <cmd> [<arg>, ...]" % sys.argv[0]
+    print ""
+    print "Supported commands:"
+    for name, handler, num_args, desc in cmds:
+        print "    %-20s - %s" % (name, desc)
+
+if len(sys.argv) < 3:
+    usage()
+    sys.exit(1)
+
+main(sys.argv[1], sys.argv[2], sys.argv[3:])
commit eb09218077a495bc55d84de91f448f72fe78a60b
Author: Liu Yuan <tailai.ly at taobao.com>
Date:   Tue Apr 3 18:04:21 2012 +0800

    sheepdog: fix send req helpers
    
    We should return if reading of the header fails.
    
    Cc: Kevin Wolf <kwolf at redhat.com>
    Cc: MORITA Kazutaka <morita.kazutaka at lab.ntt.co.jp>
    Signed-off-by: Liu Yuan <tailai.ly at taobao.com>
    Acked-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 1248534..3eaf625 100644
--- a/block/sheepdog.c
+++ b/block/sheepdog.c
@@ -510,6 +510,7 @@ static int send_req(int sockfd, SheepdogReq *hdr, void *data,
     ret = qemu_send_full(sockfd, hdr, sizeof(*hdr), 0);
     if (ret < sizeof(*hdr)) {
         error_report("failed to send a req, %s", strerror(errno));
+        return ret;
     }
 
     ret = qemu_send_full(sockfd, data, *wlen, 0);
@@ -528,6 +529,7 @@ static int send_co_req(int sockfd, SheepdogReq *hdr, void *data,
     ret = qemu_co_send(sockfd, hdr, sizeof(*hdr));
     if (ret < sizeof(*hdr)) {
         error_report("failed to send a req, %s", strerror(errno));
+        return ret;
     }
 
     ret = qemu_co_send(sockfd, data, *wlen);
commit 47622c44d0d9a717c1a8f7f5fec6c25ff3b30eec
Author: Liu Yuan <tailai.ly at taobao.com>
Date:   Wed Apr 4 04:03:58 2012 +0800

    sheepdog: implement SD_OP_FLUSH_VDI operation
    
    Flush operation is supposed to flush the write-back cache of
    sheepdog cluster.
    
    By issuing flush operation, we can assure the Guest of data
    reaching the sheepdog cluster storage.
    
    Cc: Kevin Wolf <kwolf at redhat.com>
    Cc: MORITA Kazutaka <morita.kazutaka at lab.ntt.co.jp>
    Signed-off-by: Liu Yuan <tailai.ly at taobao.com>
    Signed-off-by: Kevin Wolf <kwolf at redhat.com>

diff --git a/block/sheepdog.c b/block/sheepdog.c
index 00276f6..1248534 100644
--- a/block/sheepdog.c
+++ b/block/sheepdog.c
@@ -32,9 +32,11 @@
 #define SD_OP_RELEASE_VDI    0x13
 #define SD_OP_GET_VDI_INFO   0x14
 #define SD_OP_READ_VDIS      0x15
+#define SD_OP_FLUSH_VDI      0x16
 
 #define SD_FLAG_CMD_WRITE    0x01
 #define SD_FLAG_CMD_COW      0x02
+#define SD_FLAG_CMD_CACHE    0x04
 
 #define SD_RES_SUCCESS       0x00 /* Success */
 #define SD_RES_UNKNOWN       0x01 /* Unknown error */
@@ -293,10 +295,12 @@ typedef struct BDRVSheepdogState {
 
     char name[SD_MAX_VDI_LEN];
     int is_snapshot;
+    uint8_t cache_enabled;
 
     char *addr;
     char *port;
     int fd;
+    int flush_fd;
 
     CoMutex lock;
     Coroutine *co_send;
@@ -516,6 +520,23 @@ static int send_req(int sockfd, SheepdogReq *hdr, void *data,
     return ret;
 }
 
+static int send_co_req(int sockfd, SheepdogReq *hdr, void *data,
+                       unsigned int *wlen)
+{
+    int ret;
+
+    ret = qemu_co_send(sockfd, hdr, sizeof(*hdr));
+    if (ret < sizeof(*hdr)) {
+        error_report("failed to send a req, %s", strerror(errno));
+    }
+
+    ret = qemu_co_send(sockfd, data, *wlen);
+    if (ret < *wlen) {
+        error_report("failed to send a req, %s", strerror(errno));
+    }
+
+    return ret;
+}
 static int do_req(int sockfd, SheepdogReq *hdr, void *data,
                   unsigned int *wlen, unsigned int *rlen)
 {
@@ -550,6 +571,40 @@ out:
     return ret;
 }
 
+static int do_co_req(int sockfd, SheepdogReq *hdr, void *data,
+                     unsigned int *wlen, unsigned int *rlen)
+{
+    int ret;
+
+    socket_set_block(sockfd);
+    ret = send_co_req(sockfd, hdr, data, wlen);
+    if (ret < 0) {
+        goto out;
+    }
+
+    ret = qemu_co_recv(sockfd, hdr, sizeof(*hdr));
+    if (ret < sizeof(*hdr)) {
+        error_report("failed to get a rsp, %s", strerror(errno));
+        goto out;
+    }
+
+    if (*rlen > hdr->data_length) {
+        *rlen = hdr->data_length;
+    }
+
+    if (*rlen) {
+        ret = qemu_co_recv(sockfd, data, *rlen);
+        if (ret < *rlen) {
+            error_report("failed to get the data, %s", strerror(errno));
+            goto out;
+        }
+    }
+    ret = 0;
+out:
+    socket_set_nonblock(sockfd);
+    return ret;
+}
+
 static int coroutine_fn add_aio_request(BDRVSheepdogState *s, AIOReq *aio_req,
                            struct iovec *iov, int niov, int create,
                            enum AIOCBState aiocb_type);
@@ -900,6 +955,10 @@ static int coroutine_fn add_aio_request(BDRVSheepdogState *s, AIOReq *aio_req,
         hdr.flags = SD_FLAG_CMD_WRITE | flags;
     }
 
+    if (s->cache_enabled) {
+        hdr.flags |= SD_FLAG_CMD_CACHE;
+    }
+
     hdr.oid = oid;
     hdr.cow_oid = old_oid;
     hdr.copies = s->inode.nr_copies;
@@ -942,7 +1001,7 @@ static int coroutine_fn add_aio_request(BDRVSheepdogState *s, AIOReq *aio_req,
 
 static int read_write_object(int fd, char *buf, uint64_t oid, int copies,
                              unsigned int datalen, uint64_t offset,
-                             int write, int create)
+                             int write, int create, uint8_t cache)
 {
     SheepdogObjReq hdr;
     SheepdogObjRsp *rsp = (SheepdogObjRsp *)&hdr;
@@ -965,6 +1024,11 @@ static int read_write_object(int fd, char *buf, uint64_t oid, int copies,
         rlen = datalen;
         hdr.opcode = SD_OP_READ_OBJ;
     }
+
+    if (cache) {
+        hdr.flags |= SD_FLAG_CMD_CACHE;
+    }
+
     hdr.oid = oid;
     hdr.data_length = datalen;
     hdr.offset = offset;
@@ -986,15 +1050,18 @@ static int read_write_object(int fd, char *buf, uint64_t oid, int copies,
 }
 
 static int read_object(int fd, char *buf, uint64_t oid, int copies,
-                       unsigned int datalen, uint64_t offset)
+                       unsigned int datalen, uint64_t offset, uint8_t cache)
 {
-    return read_write_object(fd, buf, oid, copies, datalen, offset, 0, 0);
+    return read_write_object(fd, buf, oid, copies, datalen, offset, 0, 0,
+                             cache);
 }
 
 static int write_object(int fd, char *buf, uint64_t oid, int copies,
-                        unsigned int datalen, uint64_t offset, int create)
+                        unsigned int datalen, uint64_t offset, int create,
+                        uint8_t cache)
 {
-    return read_write_object(fd, buf, oid, copies, datalen, offset, 1, create);
+    return read_write_object(fd, buf, oid, copies, datalen, offset, 1, create,
+                             cache);
 }
 
 static int sd_open(BlockDriverState *bs, const char *filename, int flags)
@@ -1026,6 +1093,15 @@ static int sd_open(BlockDriverState *bs, const char *filename, int flags)
         goto out;
     }
 
+    if (flags & BDRV_O_CACHE_WB) {
+        s->cache_enabled = 1;
+        s->flush_fd = connect_to_sdog(s->addr, s->port);
+        if (s->flush_fd < 0) {
+            error_report("failed to connect");
+            goto out;
+        }
+    }
+
     if (snapid) {
         dprintf("%" PRIx32 " snapshot inode was open.\n", vid);
         s->is_snapshot = 1;
@@ -1038,7 +1114,8 @@ static int sd_open(BlockDriverState *bs, const char *filename, int flags)
     }
 
     buf = g_malloc(SD_INODE_SIZE);
-    ret = read_object(fd, buf, vid_to_vdi_oid(vid), 0, SD_INODE_SIZE, 0);
+    ret = read_object(fd, buf, vid_to_vdi_oid(vid), 0, SD_INODE_SIZE, 0,
+                      s->cache_enabled);
 
     closesocket(fd);
 
@@ -1272,6 +1349,9 @@ static void sd_close(BlockDriverState *bs)
 
     qemu_aio_set_fd_handler(s->fd, NULL, NULL, NULL, NULL, NULL);
     closesocket(s->fd);
+    if (s->cache_enabled) {
+        closesocket(s->flush_fd);
+    }
     g_free(s->addr);
 }
 
@@ -1305,7 +1385,7 @@ static int sd_truncate(BlockDriverState *bs, int64_t offset)
     datalen = SD_INODE_SIZE - sizeof(s->inode.data_vdi_id);
     s->inode.vdi_size = offset;
     ret = write_object(fd, (char *)&s->inode, vid_to_vdi_oid(s->inode.vdi_id),
-                       s->inode.nr_copies, datalen, 0, 0);
+                       s->inode.nr_copies, datalen, 0, 0, s->cache_enabled);
     close(fd);
 
     if (ret < 0) {
@@ -1387,7 +1467,7 @@ static int sd_create_branch(BDRVSheepdogState *s)
     }
 
     ret = read_object(fd, buf, vid_to_vdi_oid(vid), s->inode.nr_copies,
-                      SD_INODE_SIZE, 0);
+                      SD_INODE_SIZE, 0, s->cache_enabled);
 
     closesocket(fd);
 
@@ -1575,6 +1655,36 @@ static coroutine_fn int sd_co_readv(BlockDriverState *bs, int64_t sector_num,
     return acb->ret;
 }
 
+static int coroutine_fn sd_co_flush_to_disk(BlockDriverState *bs)
+{
+    BDRVSheepdogState *s = bs->opaque;
+    SheepdogObjReq hdr = { 0 };
+    SheepdogObjRsp *rsp = (SheepdogObjRsp *)&hdr;
+    SheepdogInode *inode = &s->inode;
+    int ret;
+    unsigned int wlen = 0, rlen = 0;
+
+    if (!s->cache_enabled) {
+        return 0;
+    }
+
+    hdr.opcode = SD_OP_FLUSH_VDI;
+    hdr.oid = vid_to_vdi_oid(inode->vdi_id);
+
+    ret = do_co_req(s->flush_fd, (SheepdogReq *)&hdr, NULL, &wlen, &rlen);
+    if (ret) {
+        error_report("failed to send a request to the sheep");
+        return ret;
+    }
+
+    if (rsp->result != SD_RES_SUCCESS) {
+        error_report("%s", sd_strerror(rsp->result));
+        return -EIO;
+    }
+
+    return 0;
+}
+
 static int sd_snapshot_create(BlockDriverState *bs, QEMUSnapshotInfo *sn_info)
 {
     BDRVSheepdogState *s = bs->opaque;
@@ -1610,7 +1720,7 @@ static int sd_snapshot_create(BlockDriverState *bs, QEMUSnapshotInfo *sn_info)
     }
 
     ret = write_object(fd, (char *)&s->inode, vid_to_vdi_oid(s->inode.vdi_id),
-                       s->inode.nr_copies, datalen, 0, 0);
+                       s->inode.nr_copies, datalen, 0, 0, s->cache_enabled);
     if (ret < 0) {
         error_report("failed to write snapshot's inode.");
         ret = -EIO;
@@ -1629,7 +1739,7 @@ static int sd_snapshot_create(BlockDriverState *bs, QEMUSnapshotInfo *sn_info)
     inode = (SheepdogInode *)g_malloc(datalen);
 
     ret = read_object(fd, (char *)inode, vid_to_vdi_oid(new_vid),
-                      s->inode.nr_copies, datalen, 0);
+                      s->inode.nr_copies, datalen, 0, s->cache_enabled);
 
     if (ret < 0) {
         error_report("failed to read new inode info. %s", strerror(errno));
@@ -1684,7 +1794,7 @@ static int sd_snapshot_goto(BlockDriverState *bs, const char *snapshot_id)
 
     buf = g_malloc(SD_INODE_SIZE);
     ret = read_object(fd, buf, vid_to_vdi_oid(vid), s->inode.nr_copies,
-                      SD_INODE_SIZE, 0);
+                      SD_INODE_SIZE, 0, s->cache_enabled);
 
     closesocket(fd);
 
@@ -1779,7 +1889,8 @@ static int sd_snapshot_list(BlockDriverState *bs, QEMUSnapshotInfo **psn_tab)
 
         /* we don't need to read entire object */
         ret = read_object(fd, (char *)&inode, vid_to_vdi_oid(vid),
-                          0, SD_INODE_SIZE - sizeof(inode.data_vdi_id), 0);
+                          0, SD_INODE_SIZE - sizeof(inode.data_vdi_id), 0,
+                          s->cache_enabled);
 
         if (ret) {
             continue;
@@ -1835,10 +1946,12 @@ static int do_load_save_vmstate(BDRVSheepdogState *s, uint8_t *data,
         create = (offset == 0);
         if (load) {
             ret = read_object(fd, (char *)data, vmstate_oid,
-                              s->inode.nr_copies, data_len, offset);
+                              s->inode.nr_copies, data_len, offset,
+                              s->cache_enabled);
         } else {
             ret = write_object(fd, (char *)data, vmstate_oid,
-                               s->inode.nr_copies, data_len, offset, create);
+                               s->inode.nr_copies, data_len, offset, create,
+                               s->cache_enabled);
         }
 
         if (ret < 0) {
@@ -1904,6 +2017,7 @@ BlockDriver bdrv_sheepdog = {
 
     .bdrv_co_readv  = sd_co_readv,
     .bdrv_co_writev = sd_co_writev,
+    .bdrv_co_flush_to_disk  = sd_co_flush_to_disk,
 
     .bdrv_snapshot_create   = sd_snapshot_create,
     .bdrv_snapshot_goto     = sd_snapshot_goto,
commit f6801b83d0e77ca025867800d805ee80f6bda938
Author: Jeff Cody <jcody at redhat.com>
Date:   Tue Mar 27 16:30:19 2012 -0400

    block: bdrv_append() fixes
    
    A few fixups for bdrv_append():
    
    The new bs (bs_new) passed into bdrv_append() should be anonymous.  Rather
    than call bdrv_make_anon() to enforce this, use an assert to catch when a caller
    is passing in a bs_new that is not anonymous.
    
    Also, the new top layer should have its backing_format reflect the original
    top's format.
    
    And last, after the swap of bs contents, the device_name will have been copied
    down. This needs to be cleared to reflect the anonymity of the bs that was
    pushed down.
    
    Signed-off-by: Jeff Cody <jcody at redhat.com>
    Signed-off-by: Kevin Wolf <kwolf at redhat.com>

diff --git a/block.c b/block.c
index 33630eb..b3117ef 100644
--- a/block.c
+++ b/block.c
@@ -892,14 +892,16 @@ void bdrv_make_anon(BlockDriverState *bs)
  * This will modify the BlockDriverState fields, and swap contents
  * between bs_new and bs_top. Both bs_new and bs_top are modified.
  *
+ * bs_new is required to be anonymous.
+ *
  * This function does not create any image files.
  */
 void bdrv_append(BlockDriverState *bs_new, BlockDriverState *bs_top)
 {
     BlockDriverState tmp;
 
-    /* the new bs must not be in bdrv_states */
-    bdrv_make_anon(bs_new);
+    /* bs_new must be anonymous */
+    assert(bs_new->device_name[0] == '\0');
 
     tmp = *bs_new;
 
@@ -944,11 +946,18 @@ void bdrv_append(BlockDriverState *bs_new, BlockDriverState *bs_top)
      * swapping bs_new and bs_top contents. */
     tmp.backing_hd = bs_new;
     pstrcpy(tmp.backing_file, sizeof(tmp.backing_file), bs_top->filename);
+    bdrv_get_format(bs_top, tmp.backing_format, sizeof(tmp.backing_format));
 
     /* swap contents of the fixed new bs and the current top */
     *bs_new = *bs_top;
     *bs_top = tmp;
 
+    /* device_name[] was carried over from the old bs_top.  bs_new
+     * shouldn't be in bdrv_states, so we need to make device_name[]
+     * reflect the anonymity of bs_new
+     */
+    bs_new->device_name[0] = '\0';
+
     /* clear the copied fields in the new backing file */
     bdrv_detach_dev(bs_new, bs_new->dev);
 
commit d68dbee80e3964d9bb0ab29ad64675da148c3cac
Author: Dong Xu Wang <wdongxu at linux.vnet.ibm.com>
Date:   Thu Mar 15 20:13:34 2012 +0800

    qed: track dirty flag status
    
    Signed-off-by: Dong Xu Wang <wdongxu at linux.vnet.ibm.com>
    Reviewed-by: Stefan Hajnoczi <stefanha at linux.vnet.ibm.com>
    Signed-off-by: Kevin Wolf <kwolf at redhat.com>

diff --git a/block/qed.c b/block/qed.c
index d6c1580..19d87f3 100644
--- a/block/qed.c
+++ b/block/qed.c
@@ -1434,6 +1434,7 @@ static int bdrv_qed_get_info(BlockDriverState *bs, BlockDriverInfo *bdi)
 
     memset(bdi, 0, sizeof(*bdi));
     bdi->cluster_size = s->header.cluster_size;
+    bdi->is_dirty = s->header.features & QED_F_NEED_CHECK;
     return 0;
 }
 
commit 64c79160b456c2d6aabc63e40b32e392a9ea3c90
Author: Dong Xu Wang <wdongxu at linux.vnet.ibm.com>
Date:   Thu Mar 15 20:13:33 2012 +0800

    qemu-img: add dirty flag status
    
    Some block drivers can verify their image files are clean or not. So we can show
    it while using "qemu-img info".
    
    Signed-off-by: Dong Xu Wang <wdongxu at linux.vnet.ibm.com>
    Reviewed-by: Stefan Hajnoczi <stefanha at linux.vnet.ibm.com>
    Signed-off-by: Kevin Wolf <kwolf at redhat.com>

diff --git a/block.h b/block.h
index ea12f5d..4e99e18 100644
--- a/block.h
+++ b/block.h
@@ -15,6 +15,7 @@ typedef struct BlockDriverInfo {
     int cluster_size;
     /* offset at which the VM state can be saved (0 if not possible) */
     int64_t vm_state_offset;
+    bool is_dirty;
 } BlockDriverInfo;
 
 typedef struct BlockFragInfo {
diff --git a/qemu-img.c b/qemu-img.c
index 4de48ba..6a61ca8 100644
--- a/qemu-img.c
+++ b/qemu-img.c
@@ -1132,6 +1132,9 @@ static int img_info(int argc, char **argv)
         if (bdi.cluster_size != 0) {
             printf("cluster_size: %d\n", bdi.cluster_size);
         }
+        if (bdi.is_dirty) {
+            printf("cleanly shut down: no\n");
+        }
     }
     bdrv_get_backing_filename(bs, backing_filename, sizeof(backing_filename));
     if (backing_filename[0] != '\0') {
commit 11c9c615c8e776e59ad0c6c6ed00ec7d38b5d865
Author: Dong Xu Wang <wdongxu at linux.vnet.ibm.com>
Date:   Thu Mar 15 20:13:32 2012 +0800

    qed: image fragmentation statistics
    
    Signed-off-by: Dong Xu Wang <wdongxu at linux.vnet.ibm.com>
    Reviewed-by: Stefan Hajnoczi <stefanha at linux.vnet.ibm.com>
    Signed-off-by: Kevin Wolf <kwolf at redhat.com>

diff --git a/block/qed-check.c b/block/qed-check.c
index e4a49ce..94327ff 100644
--- a/block/qed-check.c
+++ b/block/qed-check.c
@@ -68,6 +68,7 @@ static unsigned int qed_check_l2_table(QEDCheck *check, QEDTable *table)
 {
     BDRVQEDState *s = check->s;
     unsigned int i, num_invalid = 0;
+    uint64_t last_offset = 0;
 
     for (i = 0; i < s->table_nelems; i++) {
         uint64_t offset = table->offsets[i];
@@ -76,6 +77,11 @@ static unsigned int qed_check_l2_table(QEDCheck *check, QEDTable *table)
             qed_offset_is_zero_cluster(offset)) {
             continue;
         }
+        check->result->bfi.allocated_clusters++;
+        if (last_offset && (last_offset + s->header.cluster_size != offset)) {
+            check->result->bfi.fragmented_clusters++;
+        }
+        last_offset = offset;
 
         /* Detect invalid cluster offset */
         if (!qed_check_cluster_offset(s, offset)) {
@@ -200,6 +206,9 @@ int qed_check(BDRVQEDState *s, BdrvCheckResult *result, bool fix)
     check.used_clusters = g_malloc0(((check.nclusters + 31) / 32) *
                                        sizeof(check.used_clusters[0]));
 
+    check.result->bfi.total_clusters =
+        (s->header.image_size + s->header.cluster_size - 1) /
+            s->header.cluster_size;
     ret = qed_check_l1_table(&check, s->l1_table);
     if (ret == 0) {
         /* Only check for leaks if entire image was scanned successfully */
commit f8111c241afa75544032dcfa23df0699c91f9866
Author: Dong Xu Wang <wdongxu at linux.vnet.ibm.com>
Date:   Thu Mar 15 20:13:31 2012 +0800

    qemu-img: add image fragmentation statistics
    
    Discussion can be found at:
    http://patchwork.ozlabs.org/patch/128730/
    
    This patch add image fragmentation statistics while using qemu-img check.
    
    Signed-off-by: Dong Xu Wang <wdongxu at linux.vnet.ibm.com>
    Reviewed-by: Stefan Hajnoczi <stefanha at linux.vnet.ibm.com>
    Signed-off-by: Kevin Wolf <kwolf at redhat.com>

diff --git a/block.h b/block.h
index c51ab16..ea12f5d 100644
--- a/block.h
+++ b/block.h
@@ -17,6 +17,12 @@ typedef struct BlockDriverInfo {
     int64_t vm_state_offset;
 } BlockDriverInfo;
 
+typedef struct BlockFragInfo {
+    uint64_t allocated_clusters;
+    uint64_t total_clusters;
+    uint64_t fragmented_clusters;
+} BlockFragInfo;
+
 typedef struct QEMUSnapshotInfo {
     char id_str[128]; /* unique snapshot id */
     /* the following fields are informative. They are not needed for
@@ -175,6 +181,7 @@ typedef struct BdrvCheckResult {
     int corruptions;
     int leaks;
     int check_errors;
+    BlockFragInfo bfi;
 } BdrvCheckResult;
 
 int bdrv_check(BlockDriverState *bs, BdrvCheckResult *res);
diff --git a/qemu-img.c b/qemu-img.c
index 0e48b35..4de48ba 100644
--- a/qemu-img.c
+++ b/qemu-img.c
@@ -428,6 +428,13 @@ static int img_check(int argc, char **argv)
         }
     }
 
+    if (result.bfi.total_clusters != 0 && result.bfi.allocated_clusters != 0) {
+        printf("%" PRId64 "/%" PRId64 "= %0.2f%% allocated, %0.2f%% fragmented\n",
+        result.bfi.allocated_clusters, result.bfi.total_clusters,
+        result.bfi.allocated_clusters * 100.0 / result.bfi.total_clusters,
+        result.bfi.fragmented_clusters * 100.0 / result.bfi.allocated_clusters);
+    }
+
     bdrv_delete(bs);
 
     if (ret < 0 || result.check_errors) {
@@ -716,7 +723,7 @@ static int img_convert(int argc, char **argv)
         ret = -1;
         goto out;
     }
-        
+
     qemu_progress_init(progress, 2.0);
     qemu_progress_print(0, 100);
 
commit dc534f8fc045a51a8eb678ab3d330fba1e9e631c
Author: Paolo Bonzini <pbonzini at redhat.com>
Date:   Fri Mar 30 13:17:13 2012 +0200

    block: document job API
    
    I am not sure that these are really proper GtkDoc, but they follow
    the existing documentation in block_int.h.
    
    Signed-off-by: Paolo Bonzini <pbonzini at redhat.com>
    Reviewed-by: Stefan Hajnoczi <stefanha at linux.vnet.ibm.com>
    Signed-off-by: Kevin Wolf <kwolf at redhat.com>

diff --git a/block_int.h b/block_int.h
index a96aabd..0e5a032 100644
--- a/block_int.h
+++ b/block_int.h
@@ -63,8 +63,13 @@ typedef struct BlockIOBaseValue {
     uint64_t ios[2];
 } BlockIOBaseValue;
 
-typedef void BlockJobCancelFunc(void *opaque);
 typedef struct BlockJob BlockJob;
+
+/**
+ * BlockJobType:
+ *
+ * A class type for block job objects.
+ */
 typedef struct BlockJobType {
     /** Derived BlockJob struct size */
     size_t instance_size;
@@ -77,20 +82,48 @@ typedef struct BlockJobType {
 } BlockJobType;
 
 /**
- * Long-running operation on a BlockDriverState
+ * BlockJob:
+ *
+ * Long-running operation on a BlockDriverState.
  */
 struct BlockJob {
+    /** The job type, including the job vtable.  */
     const BlockJobType *job_type;
+
+    /** The block device on which the job is operating.  */
     BlockDriverState *bs;
+
+    /**
+     * Set to true if the job should cancel itself.  The flag must
+     * always be tested just before toggling the busy flag from false
+     * to true.  After a job has detected that the cancelled flag is
+     * true, it should not anymore issue any I/O operation to the
+     * block device.
+     */
     bool cancelled;
+
+    /**
+     * Set to false by the job while it is in a quiescent state, where
+     * no I/O is pending and cancellation can be processed without
+     * issuing new I/O.  The busy flag must be set to false when the
+     * job goes to sleep on any condition that is not detected by
+     * #qemu_aio_wait, such as a timer.
+     */
     bool busy;
 
-    /* These fields are published by the query-block-jobs QMP API */
+    /** Offset that is published by the query-block-jobs QMP API */
     int64_t offset;
+
+    /** Length that is published by the query-block-jobs QMP API */
     int64_t len;
+
+    /** Speed that was set with @block_job_set_speed.  */
     int64_t speed;
 
+    /** The completion function that will be called when the job completes.  */
     BlockDriverCompletionFunc *cb;
+
+    /** The opaque value that is passed to the completion function.  */
     void *opaque;
 };
 
@@ -306,14 +339,90 @@ void bdrv_set_io_limits(BlockDriverState *bs,
 int is_windows_drive(const char *filename);
 #endif
 
+/**
+ * block_job_create:
+ * @job_type: The class object for the newly-created job.
+ * @bs: The block
+ * @cb: Completion function for the job.
+ * @opaque: Opaque pointer value passed to @cb.
+ *
+ * Create a new long-running block device job and return it.  The job
+ * will call @cb asynchronously when the job completes.  Note that
+ * @bs may have been closed at the time the @cb it is called.  If
+ * this is the case, the job may be reported as either cancelled or
+ * completed.
+ *
+ * This function is not part of the public job interface; it should be
+ * called from a wrapper that is specific to the job type.
+ */
 void *block_job_create(const BlockJobType *job_type, BlockDriverState *bs,
                        BlockDriverCompletionFunc *cb, void *opaque);
+
+/**
+ * block_job_complete:
+ * @job: The job being completed.
+ * @ret: The status code.
+ *
+ * Call the completion function that was registered at creation time, and
+ * free @job.
+ */
 void block_job_complete(BlockJob *job, int ret);
+
+/**
+ * block_job_set_speed:
+ * @job: The job to set the speed for.
+ * @speed: The new value
+ *
+ * Set a rate-limiting parameter for the job; the actual meaning may
+ * vary depending on the job type.
+ */
 int block_job_set_speed(BlockJob *job, int64_t value);
+
+/**
+ * block_job_cancel:
+ * @job: The job to be canceled.
+ *
+ * Asynchronously cancel the specified job.
+ */
 void block_job_cancel(BlockJob *job);
+
+/**
+ * block_job_is_cancelled:
+ * @job: The job being queried.
+ *
+ * Returns whether the job is scheduled for cancellation.
+ */
 bool block_job_is_cancelled(BlockJob *job);
+
+/**
+ * block_job_cancel:
+ * @job: The job to be canceled.
+ *
+ * Asynchronously cancel the job and wait for it to reach a quiescent
+ * state.  Note that the completion callback will still be called
+ * asynchronously, hence it is *not* valid to call #bdrv_delete
+ * immediately after #block_job_cancel_sync.  Users of block jobs
+ * will usually protect the BlockDriverState objects with a reference
+ * count, should this be a concern.
+ */
 void block_job_cancel_sync(BlockJob *job);
 
+/**
+ * stream_start:
+ * @bs: Block device to operate on.
+ * @base: Block device that will become the new base, or %NULL to
+ * flatten the whole backing file chain onto @bs.
+ * @base_id: The file name that will be written to @bs as the new
+ * backing file if the job completes.  Ignored if @base is %NULL.
+ * @cb: Completion function for the job.
+ * @opaque: Opaque pointer value passed to @cb.
+ *
+ * Start a streaming operation on @bs.  Clusters that are unallocated
+ * in @bs, but allocated in any image between @base and @bs (both
+ * exclusive) will be written to @bs.  At the end of a successful
+ * streaming job, the backing file of @bs will be changed to
+ * @base_id in the written image and to @base in the live BlockDriverState.
+ */
 int stream_start(BlockDriverState *bs, BlockDriverState *base,
                  const char *base_id, BlockDriverCompletionFunc *cb,
                  void *opaque);
commit 9f25eccc1cdbe6ee985b7a5954fa621c2012912e
Author: Paolo Bonzini <pbonzini at redhat.com>
Date:   Fri Mar 30 13:17:12 2012 +0200

    block: set job->speed in block_set_speed
    
    There is no need to do this in every implementation of set_speed
    (even though there is only one right now).
    
    Signed-off-by: Paolo Bonzini <pbonzini at redhat.com>
    Reviewed-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 16e14fa..33630eb 100644
--- a/block.c
+++ b/block.c
@@ -4085,10 +4085,16 @@ void block_job_complete(BlockJob *job, int ret)
 
 int block_job_set_speed(BlockJob *job, int64_t value)
 {
+    int rc;
+
     if (!job->job_type->set_speed) {
         return -ENOTSUP;
     }
-    return job->job_type->set_speed(job, value);
+    rc = job->job_type->set_speed(job, value);
+    if (rc == 0) {
+        job->speed = value;
+    }
+    return rc;
 }
 
 void block_job_cancel(BlockJob *job)
diff --git a/block/stream.c b/block/stream.c
index f186bfd..61ff7a2 100644
--- a/block/stream.c
+++ b/block/stream.c
@@ -236,7 +236,6 @@ static int stream_set_speed(BlockJob *job, int64_t value)
     if (value < 0) {
         return -EINVAL;
     }
-    job->speed = value;
     ratelimit_set_speed(&s->limit, value / BDRV_SECTOR_SIZE);
     return 0;
 }
commit 3e914655f268f627ef004a8f1ea0355311b5aca6
Author: Paolo Bonzini <pbonzini at redhat.com>
Date:   Fri Mar 30 13:17:11 2012 +0200

    block: fix streaming/closing race
    
    Streaming can issue I/O while qcow2_close is running.  This causes the
    L2 caches to become very confused or, alternatively, could cause a
    segfault when the streaming coroutine is reentered after closing its
    block device.  The fix is to cancel streaming jobs when closing their
    underlying device.
    
    The cancellation must be synchronous, on the other hand qemu_aio_wait
    will not restart a coroutine that is sleeping in co_sleep.  So add
    a flag saying whether streaming has in-flight I/O.  If the busy flag
    is false, the coroutine is quiescent and, when cancelled, will not
    issue any new I/O.
    
    This protects streaming against closing, but not against deleting.
    We have a reference count protecting us against concurrent deletion,
    but I still added an assertion to ensure nothing bad happens.
    
    Signed-off-by: Paolo Bonzini <pbonzini at redhat.com>
    Reviewed-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 0344673..16e14fa 100644
--- a/block.c
+++ b/block.c
@@ -813,6 +813,9 @@ unlink_and_fail:
 void bdrv_close(BlockDriverState *bs)
 {
     if (bs->drv) {
+        if (bs->job) {
+            block_job_cancel_sync(bs->job);
+        }
         if (bs == bs_snapshots) {
             bs_snapshots = NULL;
         }
@@ -966,6 +969,8 @@ void bdrv_append(BlockDriverState *bs_new, BlockDriverState *bs_top)
 void bdrv_delete(BlockDriverState *bs)
 {
     assert(!bs->dev);
+    assert(!bs->job);
+    assert(!bs->in_use);
 
     /* remove from list, if necessary */
     bdrv_make_anon(bs);
@@ -4095,3 +4100,14 @@ bool block_job_is_cancelled(BlockJob *job)
 {
     return job->cancelled;
 }
+
+void block_job_cancel_sync(BlockJob *job)
+{
+    BlockDriverState *bs = job->bs;
+
+    assert(bs->job == job);
+    block_job_cancel(job);
+    while (bs->job != NULL && bs->job->busy) {
+        qemu_aio_wait();
+    }
+}
diff --git a/block/stream.c b/block/stream.c
index d1b3986..f186bfd 100644
--- a/block/stream.c
+++ b/block/stream.c
@@ -175,7 +175,7 @@ retry:
             break;
         }
 
-
+        s->common.busy = true;
         if (base) {
             ret = is_allocated_base(bs, base, sector_num,
                                     STREAM_BUFFER_SIZE / BDRV_SECTOR_SIZE, &n);
@@ -189,6 +189,7 @@ retry:
             if (s->common.speed) {
                 uint64_t delay_ns = ratelimit_calculate_delay(&s->limit, n);
                 if (delay_ns > 0) {
+                    s->common.busy = false;
                     co_sleep_ns(rt_clock, delay_ns);
 
                     /* Recheck cancellation and that sectors are unallocated */
@@ -208,6 +209,7 @@ retry:
         /* Note that even when no rate limit is applied we need to yield
          * with no pending I/O here so that qemu_aio_flush() returns.
          */
+        s->common.busy = false;
         co_sleep_ns(rt_clock, 0);
     }
 
@@ -215,7 +217,7 @@ retry:
         bdrv_disable_copy_on_read(bs);
     }
 
-    if (sector_num == end && ret == 0) {
+    if (!block_job_is_cancelled(&s->common) && sector_num == end && ret == 0) {
         const char *base_id = NULL;
         if (base) {
             base_id = s->backing_file_id;
diff --git a/block_int.h b/block_int.h
index 22c86a5..a96aabd 100644
--- a/block_int.h
+++ b/block_int.h
@@ -83,6 +83,7 @@ struct BlockJob {
     const BlockJobType *job_type;
     BlockDriverState *bs;
     bool cancelled;
+    bool busy;
 
     /* These fields are published by the query-block-jobs QMP API */
     int64_t offset;
@@ -311,6 +312,7 @@ void block_job_complete(BlockJob *job, int ret);
 int block_job_set_speed(BlockJob *job, int64_t value);
 void block_job_cancel(BlockJob *job);
 bool block_job_is_cancelled(BlockJob *job);
+void block_job_cancel_sync(BlockJob *job);
 
 int stream_start(BlockDriverState *bs, BlockDriverState *base,
                  const char *base_id, BlockDriverCompletionFunc *cb,
commit 12bde0eed6b740787bca2c998a838b20c556d0ec
Author: Paolo Bonzini <pbonzini at redhat.com>
Date:   Fri Mar 30 13:17:10 2012 +0200

    block: cancel jobs when a device is ready to go away
    
    We do not want jobs to keep a device busy for a possibly very long
    time, and management could become confused because they thought a
    device was not even there anymore.  So, cancel long-running jobs
    as soon as their device is going to disappear.
    
    Signed-off-by: Paolo Bonzini <pbonzini at redhat.com>
    Reviewed-by: Stefan Hajnoczi <stefanha at linux.vnet.ibm.com>
    Signed-off-by: Kevin Wolf <kwolf at redhat.com>

diff --git a/blockdev.c b/blockdev.c
index f5e7dba..4d17486 100644
--- a/blockdev.c
+++ b/blockdev.c
@@ -64,6 +64,9 @@ void blockdev_mark_auto_del(BlockDriverState *bs)
 {
     DriveInfo *dinfo = drive_get_by_blockdev(bs);
 
+    if (bs->job) {
+        block_job_cancel(bs->job);
+    }
     if (dinfo) {
         dinfo->auto_del = 1;
     }
commit 498e386c58497f621a37301ea6e8ca886f9f2e07
Author: Zhi Yong Wu <wuzhy at linux.vnet.ibm.com>
Date:   Mon Apr 2 18:59:34 2012 +0800

    block: disable I/O throttling on sync api
    
    Signed-off-by: Stefan Hajnoczi <stefanha at linux.vnet.ibm.com>
    Signed-off-by: Zhi Yong Wu <wuzhy at linux.vnet.ibm.com>
    Reviewed-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 8858be0..0344673 100644
--- a/block.c
+++ b/block.c
@@ -1463,6 +1463,17 @@ static int bdrv_rw_co(BlockDriverState *bs, int64_t sector_num, uint8_t *buf,
 
     qemu_iovec_init_external(&qiov, &iov, 1);
 
+    /**
+     * In sync call context, when the vcpu is blocked, this throttling timer
+     * will not fire; so the I/O throttling function has to be disabled here
+     * if it has been enabled.
+     */
+    if (bs->io_limits_enabled) {
+        fprintf(stderr, "Disabling I/O throttling on '%s' due "
+                        "to synchronous I/O.\n", bdrv_get_device_name(bs));
+        bdrv_io_limits_disable(bs);
+    }
+
     if (qemu_in_coroutine()) {
         /* Fast-path if already in coroutine context */
         bdrv_rw_co_entry(&rwco);
@@ -1969,10 +1980,19 @@ static int guess_disk_lchs(BlockDriverState *bs,
     struct partition *p;
     uint32_t nr_sects;
     uint64_t nb_sectors;
+    bool enabled;
 
     bdrv_get_geometry(bs, &nb_sectors);
 
+    /**
+     * The function will be invoked during startup not only in sync I/O mode,
+     * but also in async I/O mode. So the I/O throttling function has to
+     * be disabled temporarily here, not permanently.
+     */
+    enabled = bs->io_limits_enabled;
+    bs->io_limits_enabled = false;
     ret = bdrv_read(bs, 0, buf, 1);
+    bs->io_limits_enabled = enabled;
     if (ret < 0)
         return -1;
     /* test msdos magic */
commit 43cf8ae69ba8510e45d7bd42dd67bc8ae13c48ec
Author: David Gibson <david at gibson.dropbear.id.au>
Date:   Tue Mar 27 13:42:23 2012 +1100

    Use DMADirection type for dma_bdrv_io
    
    Currently dma_bdrv_io() takes a 'to_dev' boolean parameter to
    determine the direction of DMA it is emulating.  We already have a
    DMADirection enum designed specifically to encode DMA directions.
    This patch uses it for dma_bdrv_io() as well.  This involves removing
    the DMADirection definition from the #ifdef it was inside, but since that
    only existed to protect the definition of dma_addr_t from places where
    config.h is not included, there wasn't any reason for it to be there in
    the first place.
    
    Signed-off-by: David Gibson <david at gibson.dropbear.id.au>
    Reviewed-by: Stefan Hajnoczi <stefanha at linux.vnet.ibm.com>
    Reviewed-by: Andreas Färber <afaerber at suse.de>
    Signed-off-by: Kevin Wolf <kwolf at redhat.com>

diff --git a/dma-helpers.c b/dma-helpers.c
index 7fcc86d..7971a89 100644
--- a/dma-helpers.c
+++ b/dma-helpers.c
@@ -41,7 +41,7 @@ typedef struct {
     BlockDriverAIOCB *acb;
     QEMUSGList *sg;
     uint64_t sector_num;
-    bool to_dev;
+    DMADirection dir;
     bool in_cancel;
     int sg_cur_index;
     dma_addr_t sg_cur_byte;
@@ -75,7 +75,8 @@ static void dma_bdrv_unmap(DMAAIOCB *dbs)
 
     for (i = 0; i < dbs->iov.niov; ++i) {
         cpu_physical_memory_unmap(dbs->iov.iov[i].iov_base,
-                                  dbs->iov.iov[i].iov_len, !dbs->to_dev,
+                                  dbs->iov.iov[i].iov_len,
+                                  dbs->dir != DMA_DIRECTION_TO_DEVICE,
                                   dbs->iov.iov[i].iov_len);
     }
     qemu_iovec_reset(&dbs->iov);
@@ -122,7 +123,8 @@ static void dma_bdrv_cb(void *opaque, int ret)
     while (dbs->sg_cur_index < dbs->sg->nsg) {
         cur_addr = dbs->sg->sg[dbs->sg_cur_index].base + dbs->sg_cur_byte;
         cur_len = dbs->sg->sg[dbs->sg_cur_index].len - dbs->sg_cur_byte;
-        mem = cpu_physical_memory_map(cur_addr, &cur_len, !dbs->to_dev);
+        mem = cpu_physical_memory_map(cur_addr, &cur_len,
+                                      dbs->dir != DMA_DIRECTION_TO_DEVICE);
         if (!mem)
             break;
         qemu_iovec_add(&dbs->iov, mem, cur_len);
@@ -169,11 +171,11 @@ static AIOPool dma_aio_pool = {
 BlockDriverAIOCB *dma_bdrv_io(
     BlockDriverState *bs, QEMUSGList *sg, uint64_t sector_num,
     DMAIOFunc *io_func, BlockDriverCompletionFunc *cb,
-    void *opaque, bool to_dev)
+    void *opaque, DMADirection dir)
 {
     DMAAIOCB *dbs = qemu_aio_get(&dma_aio_pool, bs, cb, opaque);
 
-    trace_dma_bdrv_io(dbs, bs, sector_num, to_dev);
+    trace_dma_bdrv_io(dbs, bs, sector_num, (dir == DMA_DIRECTION_TO_DEVICE));
 
     dbs->acb = NULL;
     dbs->bs = bs;
@@ -181,7 +183,7 @@ BlockDriverAIOCB *dma_bdrv_io(
     dbs->sector_num = sector_num;
     dbs->sg_cur_index = 0;
     dbs->sg_cur_byte = 0;
-    dbs->to_dev = to_dev;
+    dbs->dir = dir;
     dbs->io_func = io_func;
     dbs->bh = NULL;
     qemu_iovec_init(&dbs->iov, sg->nsg);
@@ -194,14 +196,16 @@ BlockDriverAIOCB *dma_bdrv_read(BlockDriverState *bs,
                                 QEMUSGList *sg, uint64_t sector,
                                 void (*cb)(void *opaque, int ret), void *opaque)
 {
-    return dma_bdrv_io(bs, sg, sector, bdrv_aio_readv, cb, opaque, false);
+    return dma_bdrv_io(bs, sg, sector, bdrv_aio_readv, cb, opaque,
+                       DMA_DIRECTION_FROM_DEVICE);
 }
 
 BlockDriverAIOCB *dma_bdrv_write(BlockDriverState *bs,
                                  QEMUSGList *sg, uint64_t sector,
                                  void (*cb)(void *opaque, int ret), void *opaque)
 {
-    return dma_bdrv_io(bs, sg, sector, bdrv_aio_writev, cb, opaque, true);
+    return dma_bdrv_io(bs, sg, sector, bdrv_aio_writev, cb, opaque,
+                       DMA_DIRECTION_TO_DEVICE);
 }
 
 
diff --git a/dma.h b/dma.h
index 20e86d2..05ac325 100644
--- a/dma.h
+++ b/dma.h
@@ -17,6 +17,11 @@
 
 typedef struct ScatterGatherEntry ScatterGatherEntry;
 
+typedef enum {
+    DMA_DIRECTION_TO_DEVICE = 0,
+    DMA_DIRECTION_FROM_DEVICE = 1,
+} DMADirection;
+
 struct QEMUSGList {
     ScatterGatherEntry *sg;
     int nsg;
@@ -29,11 +34,6 @@ typedef target_phys_addr_t dma_addr_t;
 
 #define DMA_ADDR_FMT TARGET_FMT_plx
 
-typedef enum {
-    DMA_DIRECTION_TO_DEVICE = 0,
-    DMA_DIRECTION_FROM_DEVICE = 1,
-} DMADirection;
-
 struct ScatterGatherEntry {
     dma_addr_t base;
     dma_addr_t len;
@@ -51,7 +51,7 @@ typedef BlockDriverAIOCB *DMAIOFunc(BlockDriverState *bs, int64_t sector_num,
 BlockDriverAIOCB *dma_bdrv_io(BlockDriverState *bs,
                               QEMUSGList *sg, uint64_t sector_num,
                               DMAIOFunc *io_func, BlockDriverCompletionFunc *cb,
-                              void *opaque, bool to_dev);
+                              void *opaque, DMADirection dir);
 BlockDriverAIOCB *dma_bdrv_read(BlockDriverState *bs,
                                 QEMUSGList *sg, uint64_t sector,
                                 BlockDriverCompletionFunc *cb, void *opaque);
diff --git a/hw/ide/core.c b/hw/ide/core.c
index 6e25338..35723fd 100644
--- a/hw/ide/core.c
+++ b/hw/ide/core.c
@@ -618,7 +618,8 @@ void ide_dma_cb(void *opaque, int ret)
         break;
     case IDE_DMA_TRIM:
         s->bus->dma->aiocb = dma_bdrv_io(s->bs, &s->sg, sector_num,
-                                         ide_issue_trim, ide_dma_cb, s, true);
+                                         ide_issue_trim, ide_dma_cb, s,
+                                         DMA_DIRECTION_TO_DEVICE);
         break;
     }
     return;
diff --git a/hw/ide/macio.c b/hw/ide/macio.c
index a4df244..7b38d9e 100644
--- a/hw/ide/macio.c
+++ b/hw/ide/macio.c
@@ -149,7 +149,8 @@ static void pmac_ide_transfer_cb(void *opaque, int ret)
         break;
     case IDE_DMA_TRIM:
         m->aiocb = dma_bdrv_io(s->bs, &s->sg, sector_num,
-                               ide_issue_trim, pmac_ide_transfer_cb, s, true);
+                               ide_issue_trim, pmac_ide_transfer_cb, s,
+                               DMA_DIRECTION_TO_DEVICE);
         break;
     }
     return;
commit eb9566d13e30dd7e20d978632a13915cbdb9a668
Author: Paolo Bonzini <pbonzini at redhat.com>
Date:   Mon Mar 19 18:07:51 2012 +0100

    vdi: change goto to loop
    
    Finally reindent all code and change goto statements to a loop.
    
    Acked-by: Stefan Weil <sw at weilnetz.de>
    Signed-off-by: Paolo Bonzini <pbonzini at redhat.com>
    Signed-off-by: Kevin Wolf <kwolf at redhat.com>

diff --git a/block/vdi.c b/block/vdi.c
index bfeafea..119d3c7 100644
--- a/block/vdi.c
+++ b/block/vdi.c
@@ -474,41 +474,38 @@ static int vdi_co_read(BlockDriverState *bs,
     uint32_t block_index;
     uint32_t sector_in_block;
     uint32_t n_sectors;
-    int ret;
+    int ret = 0;
 
     logout("\n");
 
-restart:
-    block_index = sector_num / s->block_sectors;
-    sector_in_block = sector_num % s->block_sectors;
-    n_sectors = s->block_sectors - sector_in_block;
-    if (n_sectors > nb_sectors) {
-        n_sectors = nb_sectors;
-    }
-
-    logout("will read %u sectors starting at sector %" PRIu64 "\n",
-           n_sectors, sector_num);
+    while (ret >= 0 && nb_sectors > 0) {
+        block_index = sector_num / s->block_sectors;
+        sector_in_block = sector_num % s->block_sectors;
+        n_sectors = s->block_sectors - sector_in_block;
+        if (n_sectors > nb_sectors) {
+            n_sectors = nb_sectors;
+        }
 
-    /* prepare next AIO request */
-    bmap_entry = le32_to_cpu(s->bmap[block_index]);
-    if (!VDI_IS_ALLOCATED(bmap_entry)) {
-        /* Block not allocated, return zeros, no need to wait. */
-        memset(buf, 0, n_sectors * SECTOR_SIZE);
-        ret = 0;
-    } else {
-        uint64_t offset = s->header.offset_data / SECTOR_SIZE +
-                          (uint64_t)bmap_entry * s->block_sectors +
-                          sector_in_block;
-        ret = bdrv_read(bs->file, offset, buf, n_sectors);
-    }
-    logout("%u sectors read\n", n_sectors);
+        logout("will read %u sectors starting at sector %" PRIu64 "\n",
+               n_sectors, sector_num);
 
-    nb_sectors -= n_sectors;
-    sector_num += n_sectors;
-    buf += n_sectors * SECTOR_SIZE;
+        /* prepare next AIO request */
+        bmap_entry = le32_to_cpu(s->bmap[block_index]);
+        if (!VDI_IS_ALLOCATED(bmap_entry)) {
+            /* Block not allocated, return zeros, no need to wait. */
+            memset(buf, 0, n_sectors * SECTOR_SIZE);
+            ret = 0;
+        } else {
+            uint64_t offset = s->header.offset_data / SECTOR_SIZE +
+                              (uint64_t)bmap_entry * s->block_sectors +
+                              sector_in_block;
+            ret = bdrv_read(bs->file, offset, buf, n_sectors);
+        }
+        logout("%u sectors read\n", n_sectors);
 
-    if (ret >= 0 && nb_sectors > 0) {
-        goto restart;
+        nb_sectors -= n_sectors;
+        sector_num += n_sectors;
+        buf += n_sectors * SECTOR_SIZE;
     }
 
     return ret;
@@ -525,57 +522,55 @@ static int vdi_co_write(BlockDriverState *bs,
     uint32_t bmap_first = VDI_UNALLOCATED;
     uint32_t bmap_last = VDI_UNALLOCATED;
     uint8_t *block = NULL;
-    int ret;
+    int ret = 0;
 
     logout("\n");
 
-restart:
-    block_index = sector_num / s->block_sectors;
-    sector_in_block = sector_num % s->block_sectors;
-    n_sectors = s->block_sectors - sector_in_block;
-    if (n_sectors > nb_sectors) {
-        n_sectors = nb_sectors;
-    }
-
-    logout("will write %u sectors starting at sector %" PRIu64 "\n",
-           n_sectors, sector_num);
+    while (ret >= 0 && nb_sectors > 0) {
+        block_index = sector_num / s->block_sectors;
+        sector_in_block = sector_num % s->block_sectors;
+        n_sectors = s->block_sectors - sector_in_block;
+        if (n_sectors > nb_sectors) {
+            n_sectors = nb_sectors;
+        }
 
-    /* prepare next AIO request */
-    bmap_entry = le32_to_cpu(s->bmap[block_index]);
-    if (!VDI_IS_ALLOCATED(bmap_entry)) {
-        /* Allocate new block and write to it. */
-        uint64_t offset;
-        bmap_entry = s->header.blocks_allocated;
-        s->bmap[block_index] = cpu_to_le32(bmap_entry);
-        s->header.blocks_allocated++;
-        offset = s->header.offset_data / SECTOR_SIZE +
-                 (uint64_t)bmap_entry * s->block_sectors;
-        if (block == NULL) {
-            block = g_malloc(s->block_size);
-            bmap_first = block_index;
+        logout("will write %u sectors starting at sector %" PRIu64 "\n",
+               n_sectors, sector_num);
+
+        /* prepare next AIO request */
+        bmap_entry = le32_to_cpu(s->bmap[block_index]);
+        if (!VDI_IS_ALLOCATED(bmap_entry)) {
+            /* Allocate new block and write to it. */
+            uint64_t offset;
+            bmap_entry = s->header.blocks_allocated;
+            s->bmap[block_index] = cpu_to_le32(bmap_entry);
+            s->header.blocks_allocated++;
+            offset = s->header.offset_data / SECTOR_SIZE +
+                     (uint64_t)bmap_entry * s->block_sectors;
+            if (block == NULL) {
+                block = g_malloc(s->block_size);
+                bmap_first = block_index;
+            }
+            bmap_last = block_index;
+            /* Copy data to be written to new block and zero unused parts. */
+            memset(block, 0, sector_in_block * SECTOR_SIZE);
+            memcpy(block + sector_in_block * SECTOR_SIZE,
+                   buf, n_sectors * SECTOR_SIZE);
+            memset(block + (sector_in_block + n_sectors) * SECTOR_SIZE, 0,
+                   (s->block_sectors - n_sectors - sector_in_block) * SECTOR_SIZE);
+            ret = bdrv_write(bs->file, offset, block, s->block_sectors);
+        } else {
+            uint64_t offset = s->header.offset_data / SECTOR_SIZE +
+                              (uint64_t)bmap_entry * s->block_sectors +
+                              sector_in_block;
+            ret = bdrv_write(bs->file, offset, buf, n_sectors);
         }
-        bmap_last = block_index;
-        /* Copy data to be written to new block and zero unused parts. */
-        memset(block, 0, sector_in_block * SECTOR_SIZE);
-        memcpy(block + sector_in_block * SECTOR_SIZE,
-               buf, n_sectors * SECTOR_SIZE);
-        memset(block + (sector_in_block + n_sectors) * SECTOR_SIZE, 0,
-               (s->block_sectors - n_sectors - sector_in_block) * SECTOR_SIZE);
-        ret = bdrv_write(bs->file, offset, block, s->block_sectors);
-    } else {
-        uint64_t offset = s->header.offset_data / SECTOR_SIZE +
-                          (uint64_t)bmap_entry * s->block_sectors +
-                          sector_in_block;
-        ret = bdrv_write(bs->file, offset, buf, n_sectors);
-    }
 
-    nb_sectors -= n_sectors;
-    sector_num += n_sectors;
-    buf += n_sectors * SECTOR_SIZE;
+        nb_sectors -= n_sectors;
+        sector_num += n_sectors;
+        buf += n_sectors * SECTOR_SIZE;
 
-    logout("%u sectors written\n", n_sectors);
-    if (ret >= 0 && nb_sectors > 0) {
-        goto restart;
+        logout("%u sectors written\n", n_sectors);
     }
 
     logout("finished data write\n");
commit 4eea78e6345518bfe87493d8b163e1e268e64f74
Author: Paolo Bonzini <pbonzini at redhat.com>
Date:   Mon Mar 19 18:07:50 2012 +0100

    vdi: do not create useless iovecs
    
    Reads and writes to the underlying file can also occur with the simple
    non-vectored I/O interfaces.
    
    Acked-by: Stefan Weil <sw at weilnetz.de>
    Signed-off-by: Paolo Bonzini <pbonzini at redhat.com>
    Signed-off-by: Kevin Wolf <kwolf at redhat.com>

diff --git a/block/vdi.c b/block/vdi.c
index 790b61e..bfeafea 100644
--- a/block/vdi.c
+++ b/block/vdi.c
@@ -474,8 +474,6 @@ static int vdi_co_read(BlockDriverState *bs,
     uint32_t block_index;
     uint32_t sector_in_block;
     uint32_t n_sectors;
-    struct iovec hd_iov;
-    QEMUIOVector hd_qiov;
     int ret;
 
     logout("\n");
@@ -501,10 +499,7 @@ restart:
         uint64_t offset = s->header.offset_data / SECTOR_SIZE +
                           (uint64_t)bmap_entry * s->block_sectors +
                           sector_in_block;
-        hd_iov.iov_base = (void *)buf;
-        hd_iov.iov_len = n_sectors * SECTOR_SIZE;
-        qemu_iovec_init_external(&hd_qiov, &hd_iov, 1);
-        ret = bdrv_co_readv(bs->file, offset, n_sectors, &hd_qiov);
+        ret = bdrv_read(bs->file, offset, buf, n_sectors);
     }
     logout("%u sectors read\n", n_sectors);
 
@@ -529,8 +524,6 @@ static int vdi_co_write(BlockDriverState *bs,
     uint32_t n_sectors;
     uint32_t bmap_first = VDI_UNALLOCATED;
     uint32_t bmap_last = VDI_UNALLOCATED;
-    struct iovec hd_iov;
-    QEMUIOVector hd_qiov;
     uint8_t *block = NULL;
     int ret;
 
@@ -568,18 +561,12 @@ restart:
                buf, n_sectors * SECTOR_SIZE);
         memset(block + (sector_in_block + n_sectors) * SECTOR_SIZE, 0,
                (s->block_sectors - n_sectors - sector_in_block) * SECTOR_SIZE);
-        hd_iov.iov_base = (void *)block;
-        hd_iov.iov_len = s->block_size;
-        qemu_iovec_init_external(&hd_qiov, &hd_iov, 1);
-        ret = bdrv_co_writev(bs->file, offset, s->block_sectors, &hd_qiov);
+        ret = bdrv_write(bs->file, offset, block, s->block_sectors);
     } else {
         uint64_t offset = s->header.offset_data / SECTOR_SIZE +
                           (uint64_t)bmap_entry * s->block_sectors +
                           sector_in_block;
-        hd_iov.iov_base = (void *)buf;
-        hd_iov.iov_len = n_sectors * SECTOR_SIZE;
-        qemu_iovec_init_external(&hd_qiov, &hd_iov, 1);
-        ret = bdrv_co_writev(bs->file, offset, n_sectors, &hd_qiov);
+        ret = bdrv_write(bs->file, offset, buf, n_sectors);
     }
 
     nb_sectors -= n_sectors;
@@ -592,39 +579,39 @@ restart:
     }
 
     logout("finished data write\n");
-    if (ret >= 0) {
-        ret = 0;
-        if (block) {
-            VdiHeader *header = (VdiHeader *) block;
-            logout("now writing modified header\n");
-            assert(VDI_IS_ALLOCATED(bmap_first));
-            *header = s->header;
-            vdi_header_to_le(header);
-            hd_iov.iov_base = block;
-            hd_iov.iov_len = SECTOR_SIZE;
-            qemu_iovec_init_external(&hd_qiov, &hd_iov, 1);
-            ret = bdrv_co_writev(bs->file, 0, 1, &hd_qiov);
-        }
+    if (ret < 0) {
+        return ret;
+    }
+
+    if (block) {
+        /* One or more new blocks were allocated. */
+        VdiHeader *header = (VdiHeader *) block;
+        uint8_t *base;
+        uint64_t offset;
+
+        logout("now writing modified header\n");
+        assert(VDI_IS_ALLOCATED(bmap_first));
+        *header = s->header;
+        vdi_header_to_le(header);
+        ret = bdrv_write(bs->file, 0, block, 1);
         g_free(block);
         block = NULL;
-        if (ret >= 0 && VDI_IS_ALLOCATED(bmap_first)) {
-            /* One or more new blocks were allocated. */
-            uint64_t offset;
-            logout("now writing modified block map entry %u...%u\n",
-                   bmap_first, bmap_last);
-            /* Write modified sectors from block map. */
-            bmap_first /= (SECTOR_SIZE / sizeof(uint32_t));
-            bmap_last /= (SECTOR_SIZE / sizeof(uint32_t));
-            n_sectors = bmap_last - bmap_first + 1;
-            offset = s->bmap_sector + bmap_first;
-            hd_iov.iov_base = (void *)((uint8_t *)&s->bmap[0] +
-                                            bmap_first * SECTOR_SIZE);
-            hd_iov.iov_len = n_sectors * SECTOR_SIZE;
-            qemu_iovec_init_external(&hd_qiov, &hd_iov, 1);
-            logout("will write %u block map sectors starting from entry %u\n",
-                   n_sectors, bmap_first);
-            ret = bdrv_co_writev(bs->file, offset, n_sectors, &hd_qiov);
+
+        if (ret < 0) {
+            return ret;
         }
+
+        logout("now writing modified block map entry %u...%u\n",
+               bmap_first, bmap_last);
+        /* Write modified sectors from block map. */
+        bmap_first /= (SECTOR_SIZE / sizeof(uint32_t));
+        bmap_last /= (SECTOR_SIZE / sizeof(uint32_t));
+        n_sectors = bmap_last - bmap_first + 1;
+        offset = s->bmap_sector + bmap_first;
+        base = ((uint8_t *)&s->bmap[0]) + bmap_first * SECTOR_SIZE;
+        logout("will write %u block map sectors starting from entry %u\n",
+               n_sectors, bmap_first);
+        ret = bdrv_write(bs->file, offset, base, n_sectors);
     }
 
     return ret;
commit a7a43aa199571a336b76a9a9310c95476c6dc5c4
Author: Paolo Bonzini <pbonzini at redhat.com>
Date:   Mon Mar 19 18:07:49 2012 +0100

    vdi: leave bounce buffering to block layer
    
    vdi.c really works as if it implemented bdrv_read and bdrv_write.  However,
    because only vector I/O is supported by the asynchronous callbacks, it
    went through extra pain to bounce-buffer the I/O.  This can be handled
    by the block layer now that the format is coroutine-based.
    
    Acked-by: Stefan Weil <sw at weilnetz.de>
    Signed-off-by: Paolo Bonzini <pbonzini at redhat.com>
    Signed-off-by: Kevin Wolf <kwolf at redhat.com>

diff --git a/block/vdi.c b/block/vdi.c
index 0c1cff6..790b61e 100644
--- a/block/vdi.c
+++ b/block/vdi.c
@@ -144,12 +144,6 @@ void uuid_unparse(const uuid_t uu, char *out)
 #endif
 
 typedef struct {
-    BlockDriverAIOCB common;
-    uint8_t *buf;
-    void *orig_buf;
-} VdiAIOCB;
-
-typedef struct {
     char text[0x40];
     uint32_t signature;
     uint32_t version;
@@ -472,31 +466,9 @@ static int coroutine_fn vdi_co_is_allocated(BlockDriverState *bs,
     return VDI_IS_ALLOCATED(bmap_entry);
 }
 
-static AIOPool vdi_aio_pool = {
-    .aiocb_size = sizeof(VdiAIOCB),
-};
-
-static VdiAIOCB *vdi_aio_setup(BlockDriverState *bs, QEMUIOVector *qiov)
+static int vdi_co_read(BlockDriverState *bs,
+        int64_t sector_num, uint8_t *buf, int nb_sectors)
 {
-    VdiAIOCB *acb;
-
-    logout("%p, %p\n", bs, qiov);
-
-    acb = qemu_aio_get(&vdi_aio_pool, bs, NULL, NULL);
-
-    if (qiov->niov > 1) {
-        acb->buf = qemu_blockalign(bs, qiov->size);
-        acb->orig_buf = acb->buf;
-    } else {
-        acb->buf = (uint8_t *)qiov->iov->iov_base;
-    }
-    return acb;
-}
-
-static int vdi_co_readv(BlockDriverState *bs,
-        int64_t sector_num, int nb_sectors, QEMUIOVector *qiov)
-{
-    VdiAIOCB *acb;
     BDRVVdiState *s = bs->opaque;
     uint32_t bmap_entry;
     uint32_t block_index;
@@ -507,7 +479,6 @@ static int vdi_co_readv(BlockDriverState *bs,
     int ret;
 
     logout("\n");
-    acb = vdi_aio_setup(bs, qiov);
 
 restart:
     block_index = sector_num / s->block_sectors;
@@ -524,13 +495,13 @@ restart:
     bmap_entry = le32_to_cpu(s->bmap[block_index]);
     if (!VDI_IS_ALLOCATED(bmap_entry)) {
         /* Block not allocated, return zeros, no need to wait. */
-        memset(acb->buf, 0, n_sectors * SECTOR_SIZE);
+        memset(buf, 0, n_sectors * SECTOR_SIZE);
         ret = 0;
     } else {
         uint64_t offset = s->header.offset_data / SECTOR_SIZE +
                           (uint64_t)bmap_entry * s->block_sectors +
                           sector_in_block;
-        hd_iov.iov_base = (void *)acb->buf;
+        hd_iov.iov_base = (void *)buf;
         hd_iov.iov_len = n_sectors * SECTOR_SIZE;
         qemu_iovec_init_external(&hd_qiov, &hd_iov, 1);
         ret = bdrv_co_readv(bs->file, offset, n_sectors, &hd_qiov);
@@ -539,24 +510,18 @@ restart:
 
     nb_sectors -= n_sectors;
     sector_num += n_sectors;
-    acb->buf += n_sectors * SECTOR_SIZE;
+    buf += n_sectors * SECTOR_SIZE;
 
     if (ret >= 0 && nb_sectors > 0) {
         goto restart;
     }
 
-    if (acb->orig_buf) {
-        qemu_iovec_from_buffer(qiov, acb->orig_buf, qiov->size);
-        qemu_vfree(acb->orig_buf);
-    }
-    qemu_aio_release(acb);
     return ret;
 }
 
-static int vdi_co_writev(BlockDriverState *bs,
-        int64_t sector_num, int nb_sectors, QEMUIOVector *qiov)
+static int vdi_co_write(BlockDriverState *bs,
+        int64_t sector_num, const uint8_t *buf, int nb_sectors)
 {
-    VdiAIOCB *acb;
     BDRVVdiState *s = bs->opaque;
     uint32_t bmap_entry;
     uint32_t block_index;
@@ -570,10 +535,6 @@ static int vdi_co_writev(BlockDriverState *bs,
     int ret;
 
     logout("\n");
-    acb = vdi_aio_setup(bs, qiov);
-    if (acb->orig_buf) {
-        qemu_iovec_to_buffer(qiov, acb->buf);
-    }
 
 restart:
     block_index = sector_num / s->block_sectors;
@@ -604,7 +565,7 @@ restart:
         /* Copy data to be written to new block and zero unused parts. */
         memset(block, 0, sector_in_block * SECTOR_SIZE);
         memcpy(block + sector_in_block * SECTOR_SIZE,
-               acb->buf, n_sectors * SECTOR_SIZE);
+               buf, n_sectors * SECTOR_SIZE);
         memset(block + (sector_in_block + n_sectors) * SECTOR_SIZE, 0,
                (s->block_sectors - n_sectors - sector_in_block) * SECTOR_SIZE);
         hd_iov.iov_base = (void *)block;
@@ -615,7 +576,7 @@ restart:
         uint64_t offset = s->header.offset_data / SECTOR_SIZE +
                           (uint64_t)bmap_entry * s->block_sectors +
                           sector_in_block;
-        hd_iov.iov_base = (void *)acb->buf;
+        hd_iov.iov_base = (void *)buf;
         hd_iov.iov_len = n_sectors * SECTOR_SIZE;
         qemu_iovec_init_external(&hd_qiov, &hd_iov, 1);
         ret = bdrv_co_writev(bs->file, offset, n_sectors, &hd_qiov);
@@ -623,7 +584,7 @@ restart:
 
     nb_sectors -= n_sectors;
     sector_num += n_sectors;
-    acb->buf += n_sectors * SECTOR_SIZE;
+    buf += n_sectors * SECTOR_SIZE;
 
     logout("%u sectors written\n", n_sectors);
     if (ret >= 0 && nb_sectors > 0) {
@@ -666,10 +627,6 @@ restart:
         }
     }
 
-    if (acb->orig_buf) {
-        qemu_vfree(acb->orig_buf);
-    }
-    qemu_aio_release(acb);
     return ret;
 }
 
@@ -821,9 +778,9 @@ static BlockDriver bdrv_vdi = {
     .bdrv_co_is_allocated = vdi_co_is_allocated,
     .bdrv_make_empty = vdi_make_empty,
 
-    .bdrv_co_readv = vdi_co_readv,
+    .bdrv_read = vdi_co_read,
 #if defined(CONFIG_VDI_WRITE)
-    .bdrv_co_writev = vdi_co_writev,
+    .bdrv_write = vdi_co_write,
 #endif
 
     .bdrv_get_info = vdi_get_info,
commit bfc45fc183619eb4f76e3979598a510f41cd88e3
Author: Paolo Bonzini <pbonzini at redhat.com>
Date:   Mon Mar 19 18:07:48 2012 +0100

    vdi: move aiocb fields to locals
    
    Most of the AIOCB really holds local variables that need to persist
    across callback invocation.  It can go away now.
    
    Acked-by: Stefan Weil <sw at weilnetz.de>
    Signed-off-by: Paolo Bonzini <pbonzini at redhat.com>
    Signed-off-by: Kevin Wolf <kwolf at redhat.com>

diff --git a/block/vdi.c b/block/vdi.c
index 407fccc..0c1cff6 100644
--- a/block/vdi.c
+++ b/block/vdi.c
@@ -145,24 +145,8 @@ void uuid_unparse(const uuid_t uu, char *out)
 
 typedef struct {
     BlockDriverAIOCB common;
-    int64_t sector_num;
-    QEMUIOVector *qiov;
     uint8_t *buf;
-    /* Total number of sectors. */
-    int nb_sectors;
-    /* Number of sectors for current AIO. */
-    int n_sectors;
-    /* New allocated block map entry. */
-    uint32_t bmap_first;
-    uint32_t bmap_last;
-    /* Buffer for new allocated block. */
-    void *block_buffer;
     void *orig_buf;
-    bool is_write;
-    int header_modified;
-    struct iovec hd_iov;
-    QEMUIOVector hd_qiov;
-    QEMUBH *bh;
 } VdiAIOCB;
 
 typedef struct {
@@ -492,34 +476,20 @@ static AIOPool vdi_aio_pool = {
     .aiocb_size = sizeof(VdiAIOCB),
 };
 
-static VdiAIOCB *vdi_aio_setup(BlockDriverState *bs, int64_t sector_num,
-        QEMUIOVector *qiov, int nb_sectors, int is_write)
+static VdiAIOCB *vdi_aio_setup(BlockDriverState *bs, QEMUIOVector *qiov)
 {
     VdiAIOCB *acb;
 
-    logout("%p, %" PRId64 ", %p, %d, %p, %p, %d\n",
-           bs, sector_num, qiov, nb_sectors, is_write);
+    logout("%p, %p\n", bs, qiov);
 
     acb = qemu_aio_get(&vdi_aio_pool, bs, NULL, NULL);
-    acb->sector_num = sector_num;
-    acb->qiov = qiov;
-    acb->is_write = is_write;
 
     if (qiov->niov > 1) {
         acb->buf = qemu_blockalign(bs, qiov->size);
         acb->orig_buf = acb->buf;
-        if (is_write) {
-            qemu_iovec_to_buffer(qiov, acb->buf);
-        }
     } else {
         acb->buf = (uint8_t *)qiov->iov->iov_base;
     }
-    acb->nb_sectors = nb_sectors;
-    acb->n_sectors = 0;
-    acb->bmap_first = VDI_UNALLOCATED;
-    acb->bmap_last = VDI_UNALLOCATED;
-    acb->block_buffer = NULL;
-    acb->header_modified = 0;
     return acb;
 }
 
@@ -532,24 +502,25 @@ static int vdi_co_readv(BlockDriverState *bs,
     uint32_t block_index;
     uint32_t sector_in_block;
     uint32_t n_sectors;
+    struct iovec hd_iov;
+    QEMUIOVector hd_qiov;
     int ret;
 
     logout("\n");
-    acb = vdi_aio_setup(bs, sector_num, qiov, nb_sectors, 0);
+    acb = vdi_aio_setup(bs, qiov);
 
 restart:
-    block_index = acb->sector_num / s->block_sectors;
-    sector_in_block = acb->sector_num % s->block_sectors;
+    block_index = sector_num / s->block_sectors;
+    sector_in_block = sector_num % s->block_sectors;
     n_sectors = s->block_sectors - sector_in_block;
-    if (n_sectors > acb->nb_sectors) {
-        n_sectors = acb->nb_sectors;
+    if (n_sectors > nb_sectors) {
+        n_sectors = nb_sectors;
     }
 
     logout("will read %u sectors starting at sector %" PRIu64 "\n",
-           n_sectors, acb->sector_num);
+           n_sectors, sector_num);
 
     /* prepare next AIO request */
-    acb->n_sectors = n_sectors;
     bmap_entry = le32_to_cpu(s->bmap[block_index]);
     if (!VDI_IS_ALLOCATED(bmap_entry)) {
         /* Block not allocated, return zeros, no need to wait. */
@@ -559,23 +530,23 @@ restart:
         uint64_t offset = s->header.offset_data / SECTOR_SIZE +
                           (uint64_t)bmap_entry * s->block_sectors +
                           sector_in_block;
-        acb->hd_iov.iov_base = (void *)acb->buf;
-        acb->hd_iov.iov_len = n_sectors * SECTOR_SIZE;
-        qemu_iovec_init_external(&acb->hd_qiov, &acb->hd_iov, 1);
-        ret = bdrv_co_readv(bs->file, offset, n_sectors, &acb->hd_qiov);
+        hd_iov.iov_base = (void *)acb->buf;
+        hd_iov.iov_len = n_sectors * SECTOR_SIZE;
+        qemu_iovec_init_external(&hd_qiov, &hd_iov, 1);
+        ret = bdrv_co_readv(bs->file, offset, n_sectors, &hd_qiov);
     }
-    logout("%u sectors read\n", acb->n_sectors);
+    logout("%u sectors read\n", n_sectors);
 
-    acb->nb_sectors -= acb->n_sectors;
-    acb->sector_num += acb->n_sectors;
-    acb->buf += acb->n_sectors * SECTOR_SIZE;
+    nb_sectors -= n_sectors;
+    sector_num += n_sectors;
+    acb->buf += n_sectors * SECTOR_SIZE;
 
-    if (ret >= 0 && acb->nb_sectors > 0) {
+    if (ret >= 0 && nb_sectors > 0) {
         goto restart;
     }
 
-    if (acb->qiov->niov > 1) {
-        qemu_iovec_from_buffer(acb->qiov, acb->orig_buf, acb->qiov->size);
+    if (acb->orig_buf) {
+        qemu_iovec_from_buffer(qiov, acb->orig_buf, qiov->size);
         qemu_vfree(acb->orig_buf);
     }
     qemu_aio_release(acb);
@@ -591,96 +562,93 @@ static int vdi_co_writev(BlockDriverState *bs,
     uint32_t block_index;
     uint32_t sector_in_block;
     uint32_t n_sectors;
+    uint32_t bmap_first = VDI_UNALLOCATED;
+    uint32_t bmap_last = VDI_UNALLOCATED;
+    struct iovec hd_iov;
+    QEMUIOVector hd_qiov;
+    uint8_t *block = NULL;
     int ret;
 
     logout("\n");
-    acb = vdi_aio_setup(bs, sector_num, qiov, nb_sectors, 1);
+    acb = vdi_aio_setup(bs, qiov);
+    if (acb->orig_buf) {
+        qemu_iovec_to_buffer(qiov, acb->buf);
+    }
 
 restart:
-    block_index = acb->sector_num / s->block_sectors;
-    sector_in_block = acb->sector_num % s->block_sectors;
+    block_index = sector_num / s->block_sectors;
+    sector_in_block = sector_num % s->block_sectors;
     n_sectors = s->block_sectors - sector_in_block;
-    if (n_sectors > acb->nb_sectors) {
-        n_sectors = acb->nb_sectors;
+    if (n_sectors > nb_sectors) {
+        n_sectors = nb_sectors;
     }
 
     logout("will write %u sectors starting at sector %" PRIu64 "\n",
-           n_sectors, acb->sector_num);
+           n_sectors, sector_num);
 
     /* prepare next AIO request */
-    acb->n_sectors = n_sectors;
     bmap_entry = le32_to_cpu(s->bmap[block_index]);
     if (!VDI_IS_ALLOCATED(bmap_entry)) {
         /* Allocate new block and write to it. */
         uint64_t offset;
-        uint8_t *block;
         bmap_entry = s->header.blocks_allocated;
         s->bmap[block_index] = cpu_to_le32(bmap_entry);
         s->header.blocks_allocated++;
         offset = s->header.offset_data / SECTOR_SIZE +
                  (uint64_t)bmap_entry * s->block_sectors;
-        block = acb->block_buffer;
         if (block == NULL) {
             block = g_malloc(s->block_size);
-            acb->block_buffer = block;
-            acb->bmap_first = block_index;
-            assert(!acb->header_modified);
-            acb->header_modified = 1;
+            bmap_first = block_index;
         }
-        acb->bmap_last = block_index;
+        bmap_last = block_index;
         /* Copy data to be written to new block and zero unused parts. */
         memset(block, 0, sector_in_block * SECTOR_SIZE);
         memcpy(block + sector_in_block * SECTOR_SIZE,
                acb->buf, n_sectors * SECTOR_SIZE);
         memset(block + (sector_in_block + n_sectors) * SECTOR_SIZE, 0,
                (s->block_sectors - n_sectors - sector_in_block) * SECTOR_SIZE);
-        acb->hd_iov.iov_base = (void *)block;
-        acb->hd_iov.iov_len = s->block_size;
-        qemu_iovec_init_external(&acb->hd_qiov, &acb->hd_iov, 1);
-        ret = bdrv_co_writev(bs->file, offset, s->block_sectors, &acb->hd_qiov);
+        hd_iov.iov_base = (void *)block;
+        hd_iov.iov_len = s->block_size;
+        qemu_iovec_init_external(&hd_qiov, &hd_iov, 1);
+        ret = bdrv_co_writev(bs->file, offset, s->block_sectors, &hd_qiov);
     } else {
         uint64_t offset = s->header.offset_data / SECTOR_SIZE +
                           (uint64_t)bmap_entry * s->block_sectors +
                           sector_in_block;
-        acb->hd_iov.iov_base = (void *)acb->buf;
-        acb->hd_iov.iov_len = n_sectors * SECTOR_SIZE;
-        qemu_iovec_init_external(&acb->hd_qiov, &acb->hd_iov, 1);
-        ret = bdrv_co_writev(bs->file, offset, n_sectors, &acb->hd_qiov);
+        hd_iov.iov_base = (void *)acb->buf;
+        hd_iov.iov_len = n_sectors * SECTOR_SIZE;
+        qemu_iovec_init_external(&hd_qiov, &hd_iov, 1);
+        ret = bdrv_co_writev(bs->file, offset, n_sectors, &hd_qiov);
     }
 
-    acb->nb_sectors -= acb->n_sectors;
-    acb->sector_num += acb->n_sectors;
-    acb->buf += acb->n_sectors * SECTOR_SIZE;
+    nb_sectors -= n_sectors;
+    sector_num += n_sectors;
+    acb->buf += n_sectors * SECTOR_SIZE;
 
-    logout("%u sectors written\n", acb->n_sectors);
-    if (ret >= 0 && acb->nb_sectors > 0) {
+    logout("%u sectors written\n", n_sectors);
+    if (ret >= 0 && nb_sectors > 0) {
         goto restart;
     }
 
     logout("finished data write\n");
     if (ret >= 0) {
         ret = 0;
-        if (acb->header_modified) {
-            VdiHeader *header = acb->block_buffer;
+        if (block) {
+            VdiHeader *header = (VdiHeader *) block;
             logout("now writing modified header\n");
-            assert(VDI_IS_ALLOCATED(acb->bmap_first));
+            assert(VDI_IS_ALLOCATED(bmap_first));
             *header = s->header;
             vdi_header_to_le(header);
-            acb->header_modified = 0;
-            acb->hd_iov.iov_base = acb->block_buffer;
-            acb->hd_iov.iov_len = SECTOR_SIZE;
-            qemu_iovec_init_external(&acb->hd_qiov, &acb->hd_iov, 1);
-            ret = bdrv_co_writev(bs->file, 0, 1, &acb->hd_qiov);
+            hd_iov.iov_base = block;
+            hd_iov.iov_len = SECTOR_SIZE;
+            qemu_iovec_init_external(&hd_qiov, &hd_iov, 1);
+            ret = bdrv_co_writev(bs->file, 0, 1, &hd_qiov);
         }
-        if (ret >= 0 && VDI_IS_ALLOCATED(acb->bmap_first)) {
+        g_free(block);
+        block = NULL;
+        if (ret >= 0 && VDI_IS_ALLOCATED(bmap_first)) {
             /* One or more new blocks were allocated. */
             uint64_t offset;
-            uint32_t bmap_first;
-            uint32_t bmap_last;
-            g_free(acb->block_buffer);
-            acb->block_buffer = NULL;
-            bmap_first = acb->bmap_first;
-            bmap_last = acb->bmap_last;
             logout("now writing modified block map entry %u...%u\n",
                    bmap_first, bmap_last);
             /* Write modified sectors from block map. */
@@ -688,18 +656,17 @@ restart:
             bmap_last /= (SECTOR_SIZE / sizeof(uint32_t));
             n_sectors = bmap_last - bmap_first + 1;
             offset = s->bmap_sector + bmap_first;
-            acb->bmap_first = VDI_UNALLOCATED;
-            acb->hd_iov.iov_base = (void *)((uint8_t *)&s->bmap[0] +
+            hd_iov.iov_base = (void *)((uint8_t *)&s->bmap[0] +
                                             bmap_first * SECTOR_SIZE);
-            acb->hd_iov.iov_len = n_sectors * SECTOR_SIZE;
-            qemu_iovec_init_external(&acb->hd_qiov, &acb->hd_iov, 1);
+            hd_iov.iov_len = n_sectors * SECTOR_SIZE;
+            qemu_iovec_init_external(&hd_qiov, &hd_iov, 1);
             logout("will write %u block map sectors starting from entry %u\n",
                    n_sectors, bmap_first);
-            ret = bdrv_co_writev(bs->file, offset, n_sectors, &acb->hd_qiov);
+            ret = bdrv_co_writev(bs->file, offset, n_sectors, &hd_qiov);
         }
     }
 
-    if (acb->qiov->niov > 1) {
+    if (acb->orig_buf) {
         qemu_vfree(acb->orig_buf);
     }
     qemu_aio_release(acb);
commit 4de659e8eb75df995310c5e57018c5a089c8fc6f
Author: Paolo Bonzini <pbonzini at redhat.com>
Date:   Mon Mar 19 18:07:47 2012 +0100

    vdi: merge aio_read_cb and aio_write_cb into callers
    
    Now inline the former AIO callbacks into vdi_co_readv and vdi_co_writev.
    While many cleanups are possible, the code now really looks synchronous.
    
    Acked-by: Stefan Weil <sw at weilnetz.de>
    Signed-off-by: Paolo Bonzini <pbonzini at redhat.com>
    Signed-off-by: Kevin Wolf <kwolf at redhat.com>

diff --git a/block/vdi.c b/block/vdi.c
index df0f431..407fccc 100644
--- a/block/vdi.c
+++ b/block/vdi.c
@@ -523,15 +523,19 @@ static VdiAIOCB *vdi_aio_setup(BlockDriverState *bs, int64_t sector_num,
     return acb;
 }
 
-static int vdi_aio_read_cb(void *opaque, int ret)
+static int vdi_co_readv(BlockDriverState *bs,
+        int64_t sector_num, int nb_sectors, QEMUIOVector *qiov)
 {
-    VdiAIOCB *acb = opaque;
-    BlockDriverState *bs = acb->common.bs;
+    VdiAIOCB *acb;
     BDRVVdiState *s = bs->opaque;
     uint32_t bmap_entry;
     uint32_t block_index;
     uint32_t sector_in_block;
     uint32_t n_sectors;
+    int ret;
+
+    logout("\n");
+    acb = vdi_aio_setup(bs, sector_num, qiov, nb_sectors, 0);
 
 restart:
     block_index = acb->sector_num / s->block_sectors;
@@ -578,27 +582,19 @@ restart:
     return ret;
 }
 
-static int vdi_co_readv(BlockDriverState *bs,
+static int vdi_co_writev(BlockDriverState *bs,
         int64_t sector_num, int nb_sectors, QEMUIOVector *qiov)
 {
     VdiAIOCB *acb;
-    int ret;
-
-    logout("\n");
-    acb = vdi_aio_setup(bs, sector_num, qiov, nb_sectors, 0);
-    ret = vdi_aio_read_cb(acb, 0);
-    return ret;
-}
-
-static int vdi_aio_write_cb(void *opaque, int ret)
-{
-    VdiAIOCB *acb = opaque;
-    BlockDriverState *bs = acb->common.bs;
     BDRVVdiState *s = bs->opaque;
     uint32_t bmap_entry;
     uint32_t block_index;
     uint32_t sector_in_block;
     uint32_t n_sectors;
+    int ret;
+
+    logout("\n");
+    acb = vdi_aio_setup(bs, sector_num, qiov, nb_sectors, 1);
 
 restart:
     block_index = acb->sector_num / s->block_sectors;
@@ -710,18 +706,6 @@ restart:
     return ret;
 }
 
-static int vdi_co_writev(BlockDriverState *bs,
-        int64_t sector_num, int nb_sectors, QEMUIOVector *qiov)
-{
-    VdiAIOCB *acb;
-    int ret;
-
-    logout("\n");
-    acb = vdi_aio_setup(bs, sector_num, qiov, nb_sectors, 1);
-    ret = vdi_aio_write_cb(acb, 0);
-    return ret;
-}
-
 static int vdi_create(const char *filename, QEMUOptionParameter *options)
 {
     int fd;
commit 0c7bfc321b4d19c91a59f1ff7b31418e67b8681a
Author: Paolo Bonzini <pbonzini at redhat.com>
Date:   Mon Mar 19 18:07:46 2012 +0100

    vdi: move end-of-I/O handling at the end
    
    The next step is to take code that only triggers after the first operation,
    and move it at the end of vdi_aio_read_cb and vdi_aio_write_cb.
    
    Acked-by: Stefan Weil <sw at weilnetz.de>
    Signed-off-by: Paolo Bonzini <pbonzini at redhat.com>
    Signed-off-by: Kevin Wolf <kwolf at redhat.com>

diff --git a/block/vdi.c b/block/vdi.c
index 5fd8700..df0f431 100644
--- a/block/vdi.c
+++ b/block/vdi.c
@@ -533,20 +533,7 @@ static int vdi_aio_read_cb(void *opaque, int ret)
     uint32_t sector_in_block;
     uint32_t n_sectors;
 
-    logout("%u sectors read\n", acb->n_sectors);
-
 restart:
-    acb->nb_sectors -= acb->n_sectors;
-
-    if (acb->nb_sectors == 0) {
-        /* request completed */
-        ret = 0;
-        goto done;
-    }
-
-    acb->sector_num += acb->n_sectors;
-    acb->buf += acb->n_sectors * SECTOR_SIZE;
-
     block_index = acb->sector_num / s->block_sectors;
     sector_in_block = acb->sector_num % s->block_sectors;
     n_sectors = s->block_sectors - sector_in_block;
@@ -573,11 +560,16 @@ restart:
         qemu_iovec_init_external(&acb->hd_qiov, &acb->hd_iov, 1);
         ret = bdrv_co_readv(bs->file, offset, n_sectors, &acb->hd_qiov);
     }
-    if (ret >= 0) {
+    logout("%u sectors read\n", acb->n_sectors);
+
+    acb->nb_sectors -= acb->n_sectors;
+    acb->sector_num += acb->n_sectors;
+    acb->buf += acb->n_sectors * SECTOR_SIZE;
+
+    if (ret >= 0 && acb->nb_sectors > 0) {
         goto restart;
     }
 
-done:
     if (acb->qiov->niov > 1) {
         qemu_iovec_from_buffer(acb->qiov, acb->orig_buf, acb->qiov->size);
         qemu_vfree(acb->orig_buf);
@@ -609,56 +601,6 @@ static int vdi_aio_write_cb(void *opaque, int ret)
     uint32_t n_sectors;
 
 restart:
-    acb->nb_sectors -= acb->n_sectors;
-    acb->sector_num += acb->n_sectors;
-    acb->buf += acb->n_sectors * SECTOR_SIZE;
-
-    if (acb->nb_sectors == 0) {
-        logout("finished data write\n");
-        acb->n_sectors = 0;
-        ret = 0;
-        if (acb->header_modified) {
-            VdiHeader *header = acb->block_buffer;
-            logout("now writing modified header\n");
-            assert(VDI_IS_ALLOCATED(acb->bmap_first));
-            *header = s->header;
-            vdi_header_to_le(header);
-            acb->header_modified = 0;
-            acb->hd_iov.iov_base = acb->block_buffer;
-            acb->hd_iov.iov_len = SECTOR_SIZE;
-            qemu_iovec_init_external(&acb->hd_qiov, &acb->hd_iov, 1);
-            ret = bdrv_co_writev(bs->file, 0, 1, &acb->hd_qiov);
-        }
-        if (ret >= 0 && VDI_IS_ALLOCATED(acb->bmap_first)) {
-            /* One or more new blocks were allocated. */
-            uint64_t offset;
-            uint32_t bmap_first;
-            uint32_t bmap_last;
-            g_free(acb->block_buffer);
-            acb->block_buffer = NULL;
-            bmap_first = acb->bmap_first;
-            bmap_last = acb->bmap_last;
-            logout("now writing modified block map entry %u...%u\n",
-                   bmap_first, bmap_last);
-            /* Write modified sectors from block map. */
-            bmap_first /= (SECTOR_SIZE / sizeof(uint32_t));
-            bmap_last /= (SECTOR_SIZE / sizeof(uint32_t));
-            n_sectors = bmap_last - bmap_first + 1;
-            offset = s->bmap_sector + bmap_first;
-            acb->bmap_first = VDI_UNALLOCATED;
-            acb->hd_iov.iov_base = (void *)((uint8_t *)&s->bmap[0] +
-                                            bmap_first * SECTOR_SIZE);
-            acb->hd_iov.iov_len = n_sectors * SECTOR_SIZE;
-            qemu_iovec_init_external(&acb->hd_qiov, &acb->hd_iov, 1);
-            logout("will write %u block map sectors starting from entry %u\n",
-                   n_sectors, bmap_first);
-            ret = bdrv_co_writev(bs->file, offset, n_sectors, &acb->hd_qiov);
-        }
-        goto done;
-    }
-
-    logout("%u sectors written\n", acb->n_sectors);
-
     block_index = acb->sector_num / s->block_sectors;
     sector_in_block = acb->sector_num % s->block_sectors;
     n_sectors = s->block_sectors - sector_in_block;
@@ -709,11 +651,58 @@ restart:
         qemu_iovec_init_external(&acb->hd_qiov, &acb->hd_iov, 1);
         ret = bdrv_co_writev(bs->file, offset, n_sectors, &acb->hd_qiov);
     }
-    if (ret >= 0) {
+
+    acb->nb_sectors -= acb->n_sectors;
+    acb->sector_num += acb->n_sectors;
+    acb->buf += acb->n_sectors * SECTOR_SIZE;
+
+    logout("%u sectors written\n", acb->n_sectors);
+    if (ret >= 0 && acb->nb_sectors > 0) {
         goto restart;
     }
 
-done:
+    logout("finished data write\n");
+    if (ret >= 0) {
+        ret = 0;
+        if (acb->header_modified) {
+            VdiHeader *header = acb->block_buffer;
+            logout("now writing modified header\n");
+            assert(VDI_IS_ALLOCATED(acb->bmap_first));
+            *header = s->header;
+            vdi_header_to_le(header);
+            acb->header_modified = 0;
+            acb->hd_iov.iov_base = acb->block_buffer;
+            acb->hd_iov.iov_len = SECTOR_SIZE;
+            qemu_iovec_init_external(&acb->hd_qiov, &acb->hd_iov, 1);
+            ret = bdrv_co_writev(bs->file, 0, 1, &acb->hd_qiov);
+        }
+        if (ret >= 0 && VDI_IS_ALLOCATED(acb->bmap_first)) {
+            /* One or more new blocks were allocated. */
+            uint64_t offset;
+            uint32_t bmap_first;
+            uint32_t bmap_last;
+            g_free(acb->block_buffer);
+            acb->block_buffer = NULL;
+            bmap_first = acb->bmap_first;
+            bmap_last = acb->bmap_last;
+            logout("now writing modified block map entry %u...%u\n",
+                   bmap_first, bmap_last);
+            /* Write modified sectors from block map. */
+            bmap_first /= (SECTOR_SIZE / sizeof(uint32_t));
+            bmap_last /= (SECTOR_SIZE / sizeof(uint32_t));
+            n_sectors = bmap_last - bmap_first + 1;
+            offset = s->bmap_sector + bmap_first;
+            acb->bmap_first = VDI_UNALLOCATED;
+            acb->hd_iov.iov_base = (void *)((uint8_t *)&s->bmap[0] +
+                                            bmap_first * SECTOR_SIZE);
+            acb->hd_iov.iov_len = n_sectors * SECTOR_SIZE;
+            qemu_iovec_init_external(&acb->hd_qiov, &acb->hd_iov, 1);
+            logout("will write %u block map sectors starting from entry %u\n",
+                   n_sectors, bmap_first);
+            ret = bdrv_co_writev(bs->file, offset, n_sectors, &acb->hd_qiov);
+        }
+    }
+
     if (acb->qiov->niov > 1) {
         qemu_vfree(acb->orig_buf);
     }
commit 3d46a75aa5031788cb283ab4429acca23cf1cf92
Author: Paolo Bonzini <pbonzini at redhat.com>
Date:   Mon Mar 19 18:07:45 2012 +0100

    vdi: basic conversion to coroutines
    
    Even a basic conversion changing the bdrv_aio_readv/bdrv_aio_writev calls
    to bdrv_co_readv/bdrv_co_writev, and callbacks to goto statements can
    eliminate a lot of code.  This is because error handling is simplified
    and indirections through bottom halves can go away.
    
    After this patch, I/O to the underlying file already happens via
    coroutines, but the code still looks a lot like if asynchronous I/O was
    being used.
    
    Acked-by: Stefan Weil <sw at weilnetz.de>
    Signed-off-by: Paolo Bonzini <pbonzini at redhat.com>
    Signed-off-by: Kevin Wolf <kwolf at redhat.com>

diff --git a/block/vdi.c b/block/vdi.c
index f8fa865..5fd8700 100644
--- a/block/vdi.c
+++ b/block/vdi.c
@@ -160,7 +160,6 @@ typedef struct {
     void *orig_buf;
     bool is_write;
     int header_modified;
-    BlockDriverAIOCB *hd_aiocb;
     struct iovec hd_iov;
     QEMUIOVector hd_qiov;
     QEMUBH *bh;
@@ -489,33 +488,19 @@ static int coroutine_fn vdi_co_is_allocated(BlockDriverState *bs,
     return VDI_IS_ALLOCATED(bmap_entry);
 }
 
-static void vdi_aio_cancel(BlockDriverAIOCB *blockacb)
-{
-    /* TODO: This code is untested. How can I get it executed? */
-    VdiAIOCB *acb = container_of(blockacb, VdiAIOCB, common);
-    logout("\n");
-    if (acb->hd_aiocb) {
-        bdrv_aio_cancel(acb->hd_aiocb);
-    }
-    qemu_aio_release(acb);
-}
-
 static AIOPool vdi_aio_pool = {
     .aiocb_size = sizeof(VdiAIOCB),
-    .cancel = vdi_aio_cancel,
 };
 
 static VdiAIOCB *vdi_aio_setup(BlockDriverState *bs, int64_t sector_num,
-        QEMUIOVector *qiov, int nb_sectors,
-        BlockDriverCompletionFunc *cb, void *opaque, int is_write)
+        QEMUIOVector *qiov, int nb_sectors, int is_write)
 {
     VdiAIOCB *acb;
 
     logout("%p, %" PRId64 ", %p, %d, %p, %p, %d\n",
-           bs, sector_num, qiov, nb_sectors, cb, opaque, is_write);
+           bs, sector_num, qiov, nb_sectors, is_write);
 
-    acb = qemu_aio_get(&vdi_aio_pool, bs, cb, opaque);
-    acb->hd_aiocb = NULL;
+    acb = qemu_aio_get(&vdi_aio_pool, bs, NULL, NULL);
     acb->sector_num = sector_num;
     acb->qiov = qiov;
     acb->is_write = is_write;
@@ -538,42 +523,7 @@ static VdiAIOCB *vdi_aio_setup(BlockDriverState *bs, int64_t sector_num,
     return acb;
 }
 
-static int vdi_schedule_bh(QEMUBHFunc *cb, VdiAIOCB *acb)
-{
-    logout("\n");
-
-    if (acb->bh) {
-        return -EIO;
-    }
-
-    acb->bh = qemu_bh_new(cb, acb);
-    if (!acb->bh) {
-        return -EIO;
-    }
-
-    qemu_bh_schedule(acb->bh);
-
-    return 0;
-}
-
-static void vdi_aio_read_cb(void *opaque, int ret);
-static void vdi_aio_write_cb(void *opaque, int ret);
-
-static void vdi_aio_rw_bh(void *opaque)
-{
-    VdiAIOCB *acb = opaque;
-    logout("\n");
-    qemu_bh_delete(acb->bh);
-    acb->bh = NULL;
-
-    if (acb->is_write) {
-        vdi_aio_write_cb(opaque, 0);
-    } else {
-        vdi_aio_read_cb(opaque, 0);
-    }
-}
-
-static void vdi_aio_read_cb(void *opaque, int ret)
+static int vdi_aio_read_cb(void *opaque, int ret)
 {
     VdiAIOCB *acb = opaque;
     BlockDriverState *bs = acb->common.bs;
@@ -585,12 +535,7 @@ static void vdi_aio_read_cb(void *opaque, int ret)
 
     logout("%u sectors read\n", acb->n_sectors);
 
-    acb->hd_aiocb = NULL;
-
-    if (ret < 0) {
-        goto done;
-    }
-
+restart:
     acb->nb_sectors -= acb->n_sectors;
 
     if (acb->nb_sectors == 0) {
@@ -618,10 +563,7 @@ static void vdi_aio_read_cb(void *opaque, int ret)
     if (!VDI_IS_ALLOCATED(bmap_entry)) {
         /* Block not allocated, return zeros, no need to wait. */
         memset(acb->buf, 0, n_sectors * SECTOR_SIZE);
-        ret = vdi_schedule_bh(vdi_aio_rw_bh, acb);
-        if (ret < 0) {
-            goto done;
-        }
+        ret = 0;
     } else {
         uint64_t offset = s->header.offset_data / SECTOR_SIZE +
                           (uint64_t)bmap_entry * s->block_sectors +
@@ -629,41 +571,34 @@ static void vdi_aio_read_cb(void *opaque, int ret)
         acb->hd_iov.iov_base = (void *)acb->buf;
         acb->hd_iov.iov_len = n_sectors * SECTOR_SIZE;
         qemu_iovec_init_external(&acb->hd_qiov, &acb->hd_iov, 1);
-        acb->hd_aiocb = bdrv_aio_readv(bs->file, offset, &acb->hd_qiov,
-                                       n_sectors, vdi_aio_read_cb, acb);
+        ret = bdrv_co_readv(bs->file, offset, n_sectors, &acb->hd_qiov);
+    }
+    if (ret >= 0) {
+        goto restart;
     }
-    return;
+
 done:
     if (acb->qiov->niov > 1) {
         qemu_iovec_from_buffer(acb->qiov, acb->orig_buf, acb->qiov->size);
         qemu_vfree(acb->orig_buf);
     }
-    acb->common.cb(acb->common.opaque, ret);
     qemu_aio_release(acb);
+    return ret;
 }
 
-static BlockDriverAIOCB *vdi_aio_readv(BlockDriverState *bs,
-        int64_t sector_num, QEMUIOVector *qiov, int nb_sectors,
-        BlockDriverCompletionFunc *cb, void *opaque)
+static int vdi_co_readv(BlockDriverState *bs,
+        int64_t sector_num, int nb_sectors, QEMUIOVector *qiov)
 {
     VdiAIOCB *acb;
     int ret;
 
     logout("\n");
-    acb = vdi_aio_setup(bs, sector_num, qiov, nb_sectors, cb, opaque, 0);
-    ret = vdi_schedule_bh(vdi_aio_rw_bh, acb);
-    if (ret < 0) {
-        if (acb->qiov->niov > 1) {
-            qemu_vfree(acb->orig_buf);
-        }
-        qemu_aio_release(acb);
-        return NULL;
-    }
-
-    return &acb->common;
+    acb = vdi_aio_setup(bs, sector_num, qiov, nb_sectors, 0);
+    ret = vdi_aio_read_cb(acb, 0);
+    return ret;
 }
 
-static void vdi_aio_write_cb(void *opaque, int ret)
+static int vdi_aio_write_cb(void *opaque, int ret)
 {
     VdiAIOCB *acb = opaque;
     BlockDriverState *bs = acb->common.bs;
@@ -673,12 +608,7 @@ static void vdi_aio_write_cb(void *opaque, int ret)
     uint32_t sector_in_block;
     uint32_t n_sectors;
 
-    acb->hd_aiocb = NULL;
-
-    if (ret < 0) {
-        goto done;
-    }
-
+restart:
     acb->nb_sectors -= acb->n_sectors;
     acb->sector_num += acb->n_sectors;
     acb->buf += acb->n_sectors * SECTOR_SIZE;
@@ -686,6 +616,7 @@ static void vdi_aio_write_cb(void *opaque, int ret)
     if (acb->nb_sectors == 0) {
         logout("finished data write\n");
         acb->n_sectors = 0;
+        ret = 0;
         if (acb->header_modified) {
             VdiHeader *header = acb->block_buffer;
             logout("now writing modified header\n");
@@ -696,10 +627,9 @@ static void vdi_aio_write_cb(void *opaque, int ret)
             acb->hd_iov.iov_base = acb->block_buffer;
             acb->hd_iov.iov_len = SECTOR_SIZE;
             qemu_iovec_init_external(&acb->hd_qiov, &acb->hd_iov, 1);
-            acb->hd_aiocb = bdrv_aio_writev(bs->file, 0, &acb->hd_qiov, 1,
-                                            vdi_aio_write_cb, acb);
-            return;
-        } else if (VDI_IS_ALLOCATED(acb->bmap_first)) {
+            ret = bdrv_co_writev(bs->file, 0, 1, &acb->hd_qiov);
+        }
+        if (ret >= 0 && VDI_IS_ALLOCATED(acb->bmap_first)) {
             /* One or more new blocks were allocated. */
             uint64_t offset;
             uint32_t bmap_first;
@@ -722,11 +652,8 @@ static void vdi_aio_write_cb(void *opaque, int ret)
             qemu_iovec_init_external(&acb->hd_qiov, &acb->hd_iov, 1);
             logout("will write %u block map sectors starting from entry %u\n",
                    n_sectors, bmap_first);
-            acb->hd_aiocb = bdrv_aio_writev(bs->file, offset, &acb->hd_qiov,
-                                            n_sectors, vdi_aio_write_cb, acb);
-            return;
+            ret = bdrv_co_writev(bs->file, offset, n_sectors, &acb->hd_qiov);
         }
-        ret = 0;
         goto done;
     }
 
@@ -772,9 +699,7 @@ static void vdi_aio_write_cb(void *opaque, int ret)
         acb->hd_iov.iov_base = (void *)block;
         acb->hd_iov.iov_len = s->block_size;
         qemu_iovec_init_external(&acb->hd_qiov, &acb->hd_iov, 1);
-        acb->hd_aiocb = bdrv_aio_writev(bs->file, offset,
-                                        &acb->hd_qiov, s->block_sectors,
-                                        vdi_aio_write_cb, acb);
+        ret = bdrv_co_writev(bs->file, offset, s->block_sectors, &acb->hd_qiov);
     } else {
         uint64_t offset = s->header.offset_data / SECTOR_SIZE +
                           (uint64_t)bmap_entry * s->block_sectors +
@@ -782,39 +707,30 @@ static void vdi_aio_write_cb(void *opaque, int ret)
         acb->hd_iov.iov_base = (void *)acb->buf;
         acb->hd_iov.iov_len = n_sectors * SECTOR_SIZE;
         qemu_iovec_init_external(&acb->hd_qiov, &acb->hd_iov, 1);
-        acb->hd_aiocb = bdrv_aio_writev(bs->file, offset, &acb->hd_qiov,
-                                        n_sectors, vdi_aio_write_cb, acb);
+        ret = bdrv_co_writev(bs->file, offset, n_sectors, &acb->hd_qiov);
+    }
+    if (ret >= 0) {
+        goto restart;
     }
-
-    return;
 
 done:
     if (acb->qiov->niov > 1) {
         qemu_vfree(acb->orig_buf);
     }
-    acb->common.cb(acb->common.opaque, ret);
     qemu_aio_release(acb);
+    return ret;
 }
 
-static BlockDriverAIOCB *vdi_aio_writev(BlockDriverState *bs,
-        int64_t sector_num, QEMUIOVector *qiov, int nb_sectors,
-        BlockDriverCompletionFunc *cb, void *opaque)
+static int vdi_co_writev(BlockDriverState *bs,
+        int64_t sector_num, int nb_sectors, QEMUIOVector *qiov)
 {
     VdiAIOCB *acb;
     int ret;
 
     logout("\n");
-    acb = vdi_aio_setup(bs, sector_num, qiov, nb_sectors, cb, opaque, 1);
-    ret = vdi_schedule_bh(vdi_aio_rw_bh, acb);
-    if (ret < 0) {
-        if (acb->qiov->niov > 1) {
-            qemu_vfree(acb->orig_buf);
-        }
-        qemu_aio_release(acb);
-        return NULL;
-    }
-
-    return &acb->common;
+    acb = vdi_aio_setup(bs, sector_num, qiov, nb_sectors, 1);
+    ret = vdi_aio_write_cb(acb, 0);
+    return ret;
 }
 
 static int vdi_create(const char *filename, QEMUOptionParameter *options)
@@ -965,9 +881,9 @@ static BlockDriver bdrv_vdi = {
     .bdrv_co_is_allocated = vdi_co_is_allocated,
     .bdrv_make_empty = vdi_make_empty,
 
-    .bdrv_aio_readv = vdi_aio_readv,
+    .bdrv_co_readv = vdi_co_readv,
 #if defined(CONFIG_VDI_WRITE)
-    .bdrv_aio_writev = vdi_aio_writev,
+    .bdrv_co_writev = vdi_co_writev,
 #endif
 
     .bdrv_get_info = vdi_get_info,
commit 1fc86bf963a0617bc9eabfa6c14dbca76cd57976
Author: Stefan Hajnoczi <stefanha at linux.vnet.ibm.com>
Date:   Wed Mar 14 15:57:06 2012 +0000

    block: enforce constraints on block size properties
    
    Nicolae Mogoreanu <mogo at google.com> noticed that I/O requests can lead
    to QEMU crashes when the logical_block_size property is smaller than 512
    bytes.
    
    Using the new "blocksize" property we can properly enforce constraints
    on the block size such that QEMU's block layer is able to operate
    correctly.
    
    Reported-by: Nicolae Mogoreanu <mogo at google.com>
    Reported-by: Michael Halcrow <mhalcrow at google.com>
    Signed-off-by: Stefan Hajnoczi <stefanha at linux.vnet.ibm.com>
    Reviewed-by: Paolo Bonzini <pbonzini at redhat.com>
    Signed-off-by: Kevin Wolf <kwolf at redhat.com>

diff --git a/block.h b/block.h
index e670606..c51ab16 100644
--- a/block.h
+++ b/block.h
@@ -435,10 +435,10 @@ static inline unsigned int get_physical_block_exp(BlockConf *conf)
 
 #define DEFINE_BLOCK_PROPERTIES(_state, _conf)                          \
     DEFINE_PROP_DRIVE("drive", _state, _conf.bs),                       \
-    DEFINE_PROP_UINT16("logical_block_size", _state,                    \
-                       _conf.logical_block_size, 512),                  \
-    DEFINE_PROP_UINT16("physical_block_size", _state,                   \
-                       _conf.physical_block_size, 512),                 \
+    DEFINE_PROP_BLOCKSIZE("logical_block_size", _state,                 \
+                          _conf.logical_block_size, 512),               \
+    DEFINE_PROP_BLOCKSIZE("physical_block_size", _state,                \
+                          _conf.physical_block_size, 512),              \
     DEFINE_PROP_UINT16("min_io_size", _state, _conf.min_io_size, 0),  \
     DEFINE_PROP_UINT32("opt_io_size", _state, _conf.opt_io_size, 0),    \
     DEFINE_PROP_INT32("bootindex", _state, _conf.bootindex, -1),        \
commit 02fda01c3024463e561820afb0ba09daba4014d9
Author: Stefan Hajnoczi <stefanha at linux.vnet.ibm.com>
Date:   Wed Mar 14 15:57:05 2012 +0000

    qdev: add blocksize property type
    
    Storage interfaces like virtio-blk can be configured with block size
    information so that the guest can take advantage of efficient I/O
    request sizes.
    
    According to the SCSI Block Commands (SBC) standard a device's block
    size is "almost always greater than one byte and may be a multiple of
    512 bytes".  QEMU currently has a 512 byte minimum block size because
    the block layer functions work at that granularity.  Furthermore, the
    block size should be a power of 2 because QEMU calculates bitmasks from
    the value.
    
    Introduce a "blocksize" property type so devices can enforce these
    constraints on block size values.  If the constraints are relaxed in the
    future then this property can be updated.
    
    Introduce the new PropertyValueNotPowerOf2 QError so QMP clients know
    exactly why a block size value was rejected.
    
    Signed-off-by: Stefan Hajnoczi <stefanha at linux.vnet.ibm.com>
    Reviewed-by: Paolo Bonzini <pbonzini at redhat.com>
    Signed-off-by: Kevin Wolf <kwolf at redhat.com>

diff --git a/hw/qdev-properties.c b/hw/qdev-properties.c
index bff9152..98dd06a 100644
--- a/hw/qdev-properties.c
+++ b/hw/qdev-properties.c
@@ -877,6 +877,52 @@ PropertyInfo qdev_prop_pci_devfn = {
     .max   = 0xFFFFFFFFULL,
 };
 
+/* --- blocksize --- */
+
+static void set_blocksize(Object *obj, Visitor *v, void *opaque,
+                          const char *name, Error **errp)
+{
+    DeviceState *dev = DEVICE(obj);
+    Property *prop = opaque;
+    int16_t *ptr = qdev_get_prop_ptr(dev, prop);
+    Error *local_err = NULL;
+    int64_t value;
+
+    if (dev->state != DEV_STATE_CREATED) {
+        error_set(errp, QERR_PERMISSION_DENIED);
+        return;
+    }
+
+    visit_type_int(v, &value, name, &local_err);
+    if (local_err) {
+        error_propagate(errp, local_err);
+        return;
+    }
+    if (value < prop->info->min || value > prop->info->max) {
+        error_set(errp, QERR_PROPERTY_VALUE_OUT_OF_RANGE,
+                  dev->id?:"", name, value, prop->info->min,
+                  prop->info->max);
+        return;
+    }
+
+    /* We rely on power-of-2 blocksizes for bitmasks */
+    if ((value & (value - 1)) != 0) {
+        error_set(errp, QERR_PROPERTY_VALUE_NOT_POWER_OF_2,
+                  dev->id?:"", name, value);
+        return;
+    }
+
+    *ptr = value;
+}
+
+PropertyInfo qdev_prop_blocksize = {
+    .name  = "blocksize",
+    .get   = get_int16,
+    .set   = set_blocksize,
+    .min   = 512,
+    .max   = 65024,
+};
+
 /* --- public helpers --- */
 
 static Property *qdev_prop_walk(Property *props, const char *name)
diff --git a/hw/qdev.h b/hw/qdev.h
index a8df42f..1c10960 100644
--- a/hw/qdev.h
+++ b/hw/qdev.h
@@ -223,6 +223,7 @@ extern PropertyInfo qdev_prop_drive;
 extern PropertyInfo qdev_prop_netdev;
 extern PropertyInfo qdev_prop_vlan;
 extern PropertyInfo qdev_prop_pci_devfn;
+extern PropertyInfo qdev_prop_blocksize;
 
 #define DEFINE_PROP(_name, _state, _field, _prop, _type) { \
         .name      = (_name),                                    \
@@ -284,6 +285,8 @@ extern PropertyInfo qdev_prop_pci_devfn;
 #define DEFINE_PROP_LOSTTICKPOLICY(_n, _s, _f, _d) \
     DEFINE_PROP_DEFAULT(_n, _s, _f, _d, qdev_prop_losttickpolicy, \
                         LostTickPolicy)
+#define DEFINE_PROP_BLOCKSIZE(_n, _s, _f, _d) \
+    DEFINE_PROP_DEFAULT(_n, _s, _f, _d, qdev_prop_blocksize, uint16_t)
 
 #define DEFINE_PROP_END_OF_LIST()               \
     {}
diff --git a/qerror.c b/qerror.c
index 1f565fc..96fbe71 100644
--- a/qerror.c
+++ b/qerror.c
@@ -241,6 +241,11 @@ static const QErrorStringTable qerror_table[] = {
         .desc      = "Property '%(device).%(property)' can't find value '%(value)'",
     },
     {
+        .error_fmt = QERR_PROPERTY_VALUE_NOT_POWER_OF_2,
+        .desc      = "Property '%(device).%(property)' doesn't take "
+                     "value '%(value)', it's not a power of 2",
+    },
+    {
         .error_fmt = QERR_PROPERTY_VALUE_OUT_OF_RANGE,
         .desc      = "Property '%(device).%(property)' doesn't take "
                      "value %(value) (minimum: %(min), maximum: %(max))",
diff --git a/qerror.h b/qerror.h
index e16f9c2..5c23c1f 100644
--- a/qerror.h
+++ b/qerror.h
@@ -202,6 +202,10 @@ QError *qobject_to_qerror(const QObject *obj);
 #define QERR_PROPERTY_VALUE_NOT_FOUND \
     "{ 'class': 'PropertyValueNotFound', 'data': { 'device': %s, 'property': %s, 'value': %s } }"
 
+#define QERR_PROPERTY_VALUE_NOT_POWER_OF_2 \
+    "{ 'class': 'PropertyValueNotPowerOf2', 'data': { " \
+    "'device': %s, 'property': %s, 'value': %"PRId64" } }"
+
 #define QERR_PROPERTY_VALUE_OUT_OF_RANGE \
     "{ 'class': 'PropertyValueOutOfRange', 'data': { 'device': %s, 'property': %s, 'value': %"PRId64", 'min': %"PRId64", 'max': %"PRId64" } }"
 
commit 41453412ca16ff1871ed2bd6ee83cb9a5c734823
Author: Stefan Hajnoczi <stefanha at linux.vnet.ibm.com>
Date:   Wed Mar 14 15:57:04 2012 +0000

    qerror: fix QERR_PROPERTY_VALUE_OUT_OF_RANGE description
    
    Fix a typo in the description for QERR_PROPERTY_VALUE_OUT_OF_RANGE where
    "'" was used instead of ")".
    
    Signed-off-by: Stefan Hajnoczi <stefanha at linux.vnet.ibm.com>
    Reviewed-by: Paolo Bonzini <pbonzini at redhat.com>
    Signed-off-by: Kevin Wolf <kwolf at redhat.com>

diff --git a/qerror.c b/qerror.c
index 41c729a..1f565fc 100644
--- a/qerror.c
+++ b/qerror.c
@@ -243,7 +243,7 @@ static const QErrorStringTable qerror_table[] = {
     {
         .error_fmt = QERR_PROPERTY_VALUE_OUT_OF_RANGE,
         .desc      = "Property '%(device).%(property)' doesn't take "
-                     "value %(value) (minimum: %(min), maximum: %(max)'",
+                     "value %(value) (minimum: %(min), maximum: %(max))",
     },
     {
         .error_fmt = QERR_QGA_COMMAND_FAILED,
commit c088b691363070d151f80cc1fde4b7c151bdfe8f
Author: Zhang Shengju <zhangsju at gmail.com>
Date:   Tue Mar 13 22:38:13 2012 +0800

    block/vpc: write checksum back to footer after check
    
    After validation check, the 'checksum' is not written back
    to footer, which leave it with zero.
    
    This results in errors while loadding it under Microsoft's
    Hyper-V environment, and also errors from utilities like
    Citrix's vhd-util.
    
    Signed-off-by: Zhang Shengju <sean_zhang at trendmicro.com.cn>
    Signed-off-by: Kevin Wolf <kwolf at redhat.com>

diff --git a/block/vpc.c b/block/vpc.c
index 706faf3..5cd13d1 100644
--- a/block/vpc.c
+++ b/block/vpc.c
@@ -189,6 +189,9 @@ static int vpc_open(BlockDriverState *bs, int flags)
         fprintf(stderr, "block-vpc: The header checksum of '%s' is "
             "incorrect.\n", bs->filename);
 
+    /* Write 'checksum' back to footer, or else will leave it with zero. */
+    footer->checksum = be32_to_cpu(checksum);
+
     // The visible size of a image in Virtual PC depends on the geometry
     // rather than on the size stored in the footer (the size in the footer
     // is too large usually)
commit 95ebda85e09ed2b7f00deb2adbdafa5ccf5db948
Author: Floris Bos <bos at je-eigen-domein.nl>
Date:   Tue Mar 13 13:31:47 2012 +0100

    ide: Adds wwn=hex qdev option
    
    Allow the user to specify a disk's World Wide Name.
    
    Linux guests can address disks by their unique World Wide Name number
    (e.g. /dev/disk/by-id/wwn-0x5001517959123522). This patch adds support
    for assigning a World Wide Name number to a virtual IDE disk.
    
    Cc: kwolf at redhat.com
    Signed-off-by: Floris Bos <dev at noc-ps.com>
    Signed-off-by: Kevin Wolf <kwolf at redhat.com>

diff --git a/hw/ide/core.c b/hw/ide/core.c
index 5647694..6e25338 100644
--- a/hw/ide/core.c
+++ b/hw/ide/core.c
@@ -142,8 +142,12 @@ static void ide_identify(IDEState *s)
     put_le16(p + 82, (1 << 14) | (1 << 5) | 1);
     /* 13=flush_cache_ext,12=flush_cache,10=lba48 */
     put_le16(p + 83, (1 << 14) | (1 << 13) | (1 <<12) | (1 << 10));
-    /* 14=set to 1, 1=SMART self test, 0=SMART error logging */
-    put_le16(p + 84, (1 << 14) | 0);
+    /* 14=set to 1, 8=has WWN, 1=SMART self test, 0=SMART error logging */
+    if (s->wwn) {
+        put_le16(p + 84, (1 << 14) | (1 << 8) | 0);
+    } else {
+        put_le16(p + 84, (1 << 14) | 0);
+    }
     /* 14 = NOP supported, 5=WCACHE enabled, 0=SMART feature set enabled */
     if (bdrv_enable_write_cache(s->bs))
          put_le16(p + 85, (1 << 14) | (1 << 5) | 1);
@@ -151,8 +155,12 @@ static void ide_identify(IDEState *s)
          put_le16(p + 85, (1 << 14) | 1);
     /* 13=flush_cache_ext,12=flush_cache,10=lba48 */
     put_le16(p + 86, (1 << 13) | (1 <<12) | (1 << 10));
-    /* 14=set to 1, 1=smart self test, 0=smart error logging */
-    put_le16(p + 87, (1 << 14) | 0);
+    /* 14=set to 1, 8=has WWN, 1=SMART self test, 0=SMART error logging */
+    if (s->wwn) {
+        put_le16(p + 87, (1 << 14) | (1 << 8) | 0);
+    } else {
+        put_le16(p + 87, (1 << 14) | 0);
+    }
     put_le16(p + 88, 0x3f | (1 << 13)); /* udma5 set and supported */
     put_le16(p + 93, 1 | (1 << 14) | 0x2000);
     put_le16(p + 100, s->nb_sectors);
@@ -162,6 +170,13 @@ static void ide_identify(IDEState *s)
 
     if (dev && dev->conf.physical_block_size)
         put_le16(p + 106, 0x6000 | get_physical_block_exp(&dev->conf));
+    if (s->wwn) {
+        /* LE 16-bit words 111-108 contain 64-bit World Wide Name */
+        put_le16(p + 108, s->wwn >> 48);
+        put_le16(p + 109, s->wwn >> 32);
+        put_le16(p + 110, s->wwn >> 16);
+        put_le16(p + 111, s->wwn);
+    }
     if (dev && dev->conf.discard_granularity) {
         put_le16(p + 169, 1); /* TRIM support */
     }
@@ -1833,7 +1848,8 @@ static const BlockDevOps ide_cd_block_ops = {
 };
 
 int ide_init_drive(IDEState *s, BlockDriverState *bs, IDEDriveKind kind,
-                   const char *version, const char *serial, const char *model)
+                   const char *version, const char *serial, const char *model,
+                   uint64_t wwn)
 {
     int cylinders, heads, secs;
     uint64_t nb_sectors;
@@ -1859,6 +1875,7 @@ int ide_init_drive(IDEState *s, BlockDriverState *bs, IDEDriveKind kind,
     s->heads = heads;
     s->sectors = secs;
     s->nb_sectors = nb_sectors;
+    s->wwn = wwn;
     /* The SMART values should be preserved across power cycles
        but they aren't.  */
     s->smart_enabled = 1;
@@ -1993,7 +2010,7 @@ void ide_init2_with_non_qdev_drives(IDEBus *bus, DriveInfo *hd0,
             if (ide_init_drive(&bus->ifs[i], dinfo->bdrv,
                                dinfo->media_cd ? IDE_CD : IDE_HD, NULL,
                                *dinfo->serial ? dinfo->serial : NULL,
-                               NULL) < 0) {
+                               NULL, 0) < 0) {
                 error_report("Can't set up IDE drive %s", dinfo->id);
                 exit(1);
             }
diff --git a/hw/ide/internal.h b/hw/ide/internal.h
index b1319dc..100efd3 100644
--- a/hw/ide/internal.h
+++ b/hw/ide/internal.h
@@ -349,6 +349,7 @@ struct IDEState {
     int drive_serial;
     char drive_serial_str[21];
     char drive_model_str[41];
+    uint64_t wwn;
     /* ide regs */
     uint8_t feature;
     uint8_t error;
@@ -470,6 +471,7 @@ struct IDEDevice {
     char *version;
     char *serial;
     char *model;
+    uint64_t wwn;
 };
 
 #define BM_STATUS_DMAING 0x01
@@ -536,7 +538,8 @@ void ide_data_writel(void *opaque, uint32_t addr, uint32_t val);
 uint32_t ide_data_readl(void *opaque, uint32_t addr);
 
 int ide_init_drive(IDEState *s, BlockDriverState *bs, IDEDriveKind kind,
-                   const char *version, const char *serial, const char *model);
+                   const char *version, const char *serial, const char *model,
+                   uint64_t wwn);
 void ide_init2(IDEBus *bus, qemu_irq irq);
 void ide_init2_with_non_qdev_drives(IDEBus *bus, DriveInfo *hd0,
                                     DriveInfo *hd1, qemu_irq irq);
diff --git a/hw/ide/qdev.c b/hw/ide/qdev.c
index 07227c7..a46578d 100644
--- a/hw/ide/qdev.c
+++ b/hw/ide/qdev.c
@@ -137,7 +137,7 @@ static int ide_dev_initfn(IDEDevice *dev, IDEDriveKind kind)
     }
 
     if (ide_init_drive(s, dev->conf.bs, kind,
-                       dev->version, serial, dev->model) < 0) {
+                       dev->version, serial, dev->model, dev->wwn) < 0) {
         return -1;
     }
 
@@ -174,6 +174,7 @@ static int ide_drive_initfn(IDEDevice *dev)
 #define DEFINE_IDE_DEV_PROPERTIES()                     \
     DEFINE_BLOCK_PROPERTIES(IDEDrive, dev.conf),        \
     DEFINE_PROP_STRING("ver",  IDEDrive, dev.version),  \
+    DEFINE_PROP_HEX64("wwn",  IDEDrive, dev.wwn, 0),    \
     DEFINE_PROP_STRING("serial",  IDEDrive, dev.serial),\
     DEFINE_PROP_STRING("model", IDEDrive, dev.model)
 
commit aa2c91bdfebbfa314e9522573a9656626e21ac67
Author: Floris Bos <bos at je-eigen-domein.nl>
Date:   Mon Mar 12 21:05:10 2012 +0100

    ide: Change serial number strncpy() to pstrcpy()
    
    strncpy may not null-terminate the destination string.
    
    Cc: kwolf at redhat.com
    Signed-off-by: Floris Bos <dev at noc-ps.com>
    Signed-off-by: Kevin Wolf <kwolf at redhat.com>

diff --git a/blockdev.c b/blockdev.c
index 1a500b8..f5e7dba 100644
--- a/blockdev.c
+++ b/blockdev.c
@@ -532,8 +532,9 @@ DriveInfo *drive_init(QemuOpts *opts, int default_to_scsi)
     dinfo->unit = unit_id;
     dinfo->opts = opts;
     dinfo->refcount = 1;
-    if (serial)
-        strncpy(dinfo->serial, serial, sizeof(dinfo->serial) - 1);
+    if (serial) {
+        pstrcpy(dinfo->serial, sizeof(dinfo->serial), serial);
+    }
     QTAILQ_INSERT_TAIL(&drives, dinfo, next);
 
     bdrv_set_on_error(dinfo->bdrv, on_read_error, on_write_error);
diff --git a/hw/ide/core.c b/hw/ide/core.c
index e38cace..5647694 100644
--- a/hw/ide/core.c
+++ b/hw/ide/core.c
@@ -1879,7 +1879,7 @@ int ide_init_drive(IDEState *s, BlockDriverState *bs, IDEDriveKind kind,
         }
     }
     if (serial) {
-        strncpy(s->drive_serial_str, serial, sizeof(s->drive_serial_str));
+        pstrcpy(s->drive_serial_str, sizeof(s->drive_serial_str), serial);
     } else {
         snprintf(s->drive_serial_str, sizeof(s->drive_serial_str),
                  "QM%05d", s->drive_serial);
commit 27e0c9a1bbd166a67c16291016fba298a8e47140
Author: Floris Bos <bos at je-eigen-domein.nl>
Date:   Mon Mar 12 21:05:09 2012 +0100

    ide: Add "model=s" qdev option
    
    Allow the user to override the default disk model name "QEMU HARDDISK".
    
    Some Linux distributions use the /dev/disk/by-id/scsi-SATA_name-of-disk-
    model_serial addressing scheme when refering to partitions in /etc/fstab
    and elsewhere. This causes problems when starting a disk image taken from
    an existing physical server under qemu, because when running under qemu
    name-of-disk-model is always "QEMU HARDDISK".
    
    This patch introduces a model=s option which in combination with the
    existing serial=s option can be used to fake the disk the operating
    system was previously on, allowing the OS to boot properly.
    
    Cc: kwolf at redhat.com
    Signed-off-by: Floris Bos <dev at noc-ps.com>
    Reviewed-by: Stefan Hajnoczi <stefanha at linux.vnet.ibm.com>
    Signed-off-by: Kevin Wolf <kwolf at redhat.com>

diff --git a/hw/ide/core.c b/hw/ide/core.c
index 771811c..e38cace 100644
--- a/hw/ide/core.c
+++ b/hw/ide/core.c
@@ -100,7 +100,7 @@ static void ide_identify(IDEState *s)
     put_le16(p + 21, 512); /* cache size in sectors */
     put_le16(p + 22, 4); /* ecc bytes */
     padstr((char *)(p + 23), s->version, 8); /* firmware version */
-    padstr((char *)(p + 27), "QEMU HARDDISK", 40); /* model */
+    padstr((char *)(p + 27), s->drive_model_str, 40); /* model */
 #if MAX_MULT_SECTORS > 1
     put_le16(p + 47, 0x8000 | MAX_MULT_SECTORS);
 #endif
@@ -188,7 +188,7 @@ static void ide_atapi_identify(IDEState *s)
     put_le16(p + 21, 512); /* cache size in sectors */
     put_le16(p + 22, 4); /* ecc bytes */
     padstr((char *)(p + 23), s->version, 8); /* firmware version */
-    padstr((char *)(p + 27), "QEMU DVD-ROM", 40); /* model */
+    padstr((char *)(p + 27), s->drive_model_str, 40); /* model */
     put_le16(p + 48, 1); /* dword I/O (XXX: should not be set on CDROM) */
 #ifdef USE_DMA_CDROM
     put_le16(p + 49, 1 << 9 | 1 << 8); /* DMA and LBA supported */
@@ -245,7 +245,7 @@ static void ide_cfata_identify(IDEState *s)
     padstr((char *)(p + 10), s->drive_serial_str, 20); /* serial number */
     put_le16(p + 22, 0x0004);			/* ECC bytes */
     padstr((char *) (p + 23), s->version, 8);	/* Firmware Revision */
-    padstr((char *) (p + 27), "QEMU MICRODRIVE", 40);/* Model number */
+    padstr((char *) (p + 27), s->drive_model_str, 40);/* Model number */
 #if MAX_MULT_SECTORS > 1
     put_le16(p + 47, 0x8000 | MAX_MULT_SECTORS);
 #else
@@ -1833,7 +1833,7 @@ static const BlockDevOps ide_cd_block_ops = {
 };
 
 int ide_init_drive(IDEState *s, BlockDriverState *bs, IDEDriveKind kind,
-                   const char *version, const char *serial)
+                   const char *version, const char *serial, const char *model)
 {
     int cylinders, heads, secs;
     uint64_t nb_sectors;
@@ -1884,6 +1884,22 @@ int ide_init_drive(IDEState *s, BlockDriverState *bs, IDEDriveKind kind,
         snprintf(s->drive_serial_str, sizeof(s->drive_serial_str),
                  "QM%05d", s->drive_serial);
     }
+    if (model) {
+        pstrcpy(s->drive_model_str, sizeof(s->drive_model_str), model);
+    } else {
+        switch (kind) {
+        case IDE_CD:
+            strcpy(s->drive_model_str, "QEMU DVD-ROM");
+            break;
+        case IDE_CFATA:
+            strcpy(s->drive_model_str, "QEMU MICRODRIVE");
+            break;
+        default:
+            strcpy(s->drive_model_str, "QEMU HARDDISK");
+            break;
+        }
+    }
+
     if (version) {
         pstrcpy(s->version, sizeof(s->version), version);
     } else {
@@ -1976,7 +1992,8 @@ void ide_init2_with_non_qdev_drives(IDEBus *bus, DriveInfo *hd0,
         if (dinfo) {
             if (ide_init_drive(&bus->ifs[i], dinfo->bdrv,
                                dinfo->media_cd ? IDE_CD : IDE_HD, NULL,
-                               *dinfo->serial ? dinfo->serial : NULL) < 0) {
+                               *dinfo->serial ? dinfo->serial : NULL,
+                               NULL) < 0) {
                 error_report("Can't set up IDE drive %s", dinfo->id);
                 exit(1);
             }
diff --git a/hw/ide/internal.h b/hw/ide/internal.h
index c808a0d..b1319dc 100644
--- a/hw/ide/internal.h
+++ b/hw/ide/internal.h
@@ -348,6 +348,7 @@ struct IDEState {
     uint8_t identify_data[512];
     int drive_serial;
     char drive_serial_str[21];
+    char drive_model_str[41];
     /* ide regs */
     uint8_t feature;
     uint8_t error;
@@ -468,6 +469,7 @@ struct IDEDevice {
     BlockConf conf;
     char *version;
     char *serial;
+    char *model;
 };
 
 #define BM_STATUS_DMAING 0x01
@@ -534,7 +536,7 @@ void ide_data_writel(void *opaque, uint32_t addr, uint32_t val);
 uint32_t ide_data_readl(void *opaque, uint32_t addr);
 
 int ide_init_drive(IDEState *s, BlockDriverState *bs, IDEDriveKind kind,
-                   const char *version, const char *serial);
+                   const char *version, const char *serial, const char *model);
 void ide_init2(IDEBus *bus, qemu_irq irq);
 void ide_init2_with_non_qdev_drives(IDEBus *bus, DriveInfo *hd0,
                                     DriveInfo *hd1, qemu_irq irq);
diff --git a/hw/ide/qdev.c b/hw/ide/qdev.c
index f6a4896..07227c7 100644
--- a/hw/ide/qdev.c
+++ b/hw/ide/qdev.c
@@ -136,7 +136,8 @@ static int ide_dev_initfn(IDEDevice *dev, IDEDriveKind kind)
         }
     }
 
-    if (ide_init_drive(s, dev->conf.bs, kind, dev->version, serial) < 0) {
+    if (ide_init_drive(s, dev->conf.bs, kind,
+                       dev->version, serial, dev->model) < 0) {
         return -1;
     }
 
@@ -173,7 +174,8 @@ static int ide_drive_initfn(IDEDevice *dev)
 #define DEFINE_IDE_DEV_PROPERTIES()                     \
     DEFINE_BLOCK_PROPERTIES(IDEDrive, dev.conf),        \
     DEFINE_PROP_STRING("ver",  IDEDrive, dev.version),  \
-    DEFINE_PROP_STRING("serial",  IDEDrive, dev.serial)
+    DEFINE_PROP_STRING("serial",  IDEDrive, dev.serial),\
+    DEFINE_PROP_STRING("model", IDEDrive, dev.model)
 
 static Property ide_hd_properties[] = {
     DEFINE_IDE_DEV_PROPERTIES(),
commit 2844bdd99a96dc32a6ebf464f49e65be31da1c14
Author: Kevin Wolf <kwolf at redhat.com>
Date:   Tue Mar 13 14:44:22 2012 +0100

    ide: IDENTIFY word 86 bit 14 is reserved
    
    Reserved bits should be cleared to zero.
    
    Signed-off-by: Kevin Wolf <kwolf at redhat.com>
    Reviewed-by: Stefan Hajnoczi <stefanha at linux.vnet.ibm.com>

diff --git a/hw/ide/core.c b/hw/ide/core.c
index 6f06d28..771811c 100644
--- a/hw/ide/core.c
+++ b/hw/ide/core.c
@@ -150,7 +150,7 @@ static void ide_identify(IDEState *s)
     else
          put_le16(p + 85, (1 << 14) | 1);
     /* 13=flush_cache_ext,12=flush_cache,10=lba48 */
-    put_le16(p + 86, (1 << 14) | (1 << 13) | (1 <<12) | (1 << 10));
+    put_le16(p + 86, (1 << 13) | (1 <<12) | (1 << 10));
     /* 14=set to 1, 1=smart self test, 0=smart error logging */
     put_le16(p + 87, (1 << 14) | 0);
     put_le16(p + 88, 0x3f | (1 << 13)); /* udma5 set and supported */
commit 85e8dab1efc7228bb674e72f6fb3be78c1e883bf
Author: Paolo Bonzini <pbonzini at redhat.com>
Date:   Mon Mar 12 17:01:48 2012 +0100

    aio: move BlockDriverAIOCB to qemu-aio.h
    
    And remove several block_int.h inclusions that should not be there.
    
    Signed-off-by: Paolo Bonzini <pbonzini at redhat.com>
    Reviewed-by: Stefan Hajnoczi <stefanha at linux.vnet.ibm.com>
    Signed-off-by: Kevin Wolf <kwolf at redhat.com>

diff --git a/block.h b/block.h
index 415bb17..e670606 100644
--- a/block.h
+++ b/block.h
@@ -180,8 +180,6 @@ typedef struct BdrvCheckResult {
 int bdrv_check(BlockDriverState *bs, BdrvCheckResult *res);
 
 /* async block I/O */
-typedef struct BlockDriverAIOCB BlockDriverAIOCB;
-typedef void BlockDriverCompletionFunc(void *opaque, int ret);
 typedef void BlockDriverDirtyHandler(BlockDriverState *bs, int64_t sector,
                                      int sector_num);
 BlockDriverAIOCB *bdrv_aio_readv(BlockDriverState *bs, int64_t sector_num,
diff --git a/block_int.h b/block_int.h
index b460c36..22c86a5 100644
--- a/block_int.h
+++ b/block_int.h
@@ -53,12 +53,6 @@
 
 typedef struct BdrvTrackedRequest BdrvTrackedRequest;
 
-typedef struct AIOPool {
-    void (*cancel)(BlockDriverAIOCB *acb);
-    int aiocb_size;
-    BlockDriverAIOCB *free_aiocb;
-} AIOPool;
-
 typedef struct BlockIOLimit {
     int64_t bps[3];
     int64_t iops[3];
@@ -302,20 +296,8 @@ struct BlockDriverState {
     BlockJob *job;
 };
 
-struct BlockDriverAIOCB {
-    AIOPool *pool;
-    BlockDriverState *bs;
-    BlockDriverCompletionFunc *cb;
-    void *opaque;
-    BlockDriverAIOCB *next;
-};
-
 void get_tmp_filename(char *filename, int size);
 
-void *qemu_aio_get(AIOPool *pool, BlockDriverState *bs,
-                   BlockDriverCompletionFunc *cb, void *opaque);
-void qemu_aio_release(void *p);
-
 void bdrv_set_io_limits(BlockDriverState *bs,
                         BlockIOLimit *io_limits);
 
diff --git a/dma-helpers.c b/dma-helpers.c
index c29ea6d..7fcc86d 100644
--- a/dma-helpers.c
+++ b/dma-helpers.c
@@ -8,7 +8,6 @@
  */
 
 #include "dma.h"
-#include "block_int.h"
 #include "trace.h"
 
 void qemu_sglist_init(QEMUSGList *qsg, int alloc_hint)
diff --git a/hw/ide/core.c b/hw/ide/core.c
index 4d568ac..6f06d28 100644
--- a/hw/ide/core.c
+++ b/hw/ide/core.c
@@ -31,7 +31,6 @@
 #include "sysemu.h"
 #include "dma.h"
 #include "blockdev.h"
-#include "block_int.h"
 
 #include <hw/ide/internal.h>
 
diff --git a/hw/lsi53c895a.c b/hw/lsi53c895a.c
index edc09b7..f022a02 100644
--- a/hw/lsi53c895a.c
+++ b/hw/lsi53c895a.c
@@ -15,7 +15,6 @@
 #include "hw.h"
 #include "pci.h"
 #include "scsi.h"
-#include "block_int.h"
 #include "dma.h"
 
 //#define DEBUG_LSI
diff --git a/linux-aio.c b/linux-aio.c
index d2fc2e7..15261ec 100644
--- a/linux-aio.c
+++ b/linux-aio.c
@@ -9,7 +9,6 @@
  */
 #include "qemu-common.h"
 #include "qemu-aio.h"
-#include "block_int.h"
 #include "block/raw-posix-aio.h"
 
 #include <sys/eventfd.h>
diff --git a/qemu-aio.h b/qemu-aio.h
index 3bdd749..230c2f7 100644
--- a/qemu-aio.h
+++ b/qemu-aio.h
@@ -17,6 +17,27 @@
 #include "qemu-common.h"
 #include "qemu-char.h"
 
+typedef struct BlockDriverAIOCB BlockDriverAIOCB;
+typedef void BlockDriverCompletionFunc(void *opaque, int ret);
+
+typedef struct AIOPool {
+    void (*cancel)(BlockDriverAIOCB *acb);
+    int aiocb_size;
+    BlockDriverAIOCB *free_aiocb;
+} AIOPool;
+
+struct BlockDriverAIOCB {
+    AIOPool *pool;
+    BlockDriverState *bs;
+    BlockDriverCompletionFunc *cb;
+    void *opaque;
+    BlockDriverAIOCB *next;
+};
+
+void *qemu_aio_get(AIOPool *pool, BlockDriverState *bs,
+                   BlockDriverCompletionFunc *cb, void *opaque);
+void qemu_aio_release(void *p);
+
 /* Returns 1 if there are still outstanding AIO requests; 0 otherwise */
 typedef int (AioFlushHandler)(void *opaque);
 
commit 29cdb2513c3f22f51d6f3585b41009576485cb35
Author: Paolo Bonzini <pbonzini at redhat.com>
Date:   Mon Mar 12 18:26:01 2012 +0100

    block: push recursive flushing up from drivers
    
    Signed-off-by: Paolo Bonzini <pbonzini at redhat.com>
    Signed-off-by: Kevin Wolf <kwolf at redhat.com>

diff --git a/block.c b/block.c
index b88ee90..8858be0 100644
--- a/block.c
+++ b/block.c
@@ -2331,9 +2331,7 @@ void bdrv_flush_all(void)
     BlockDriverState *bs;
 
     QTAILQ_FOREACH(bs, &bdrv_states, list) {
-        if (!bdrv_is_read_only(bs) && bdrv_is_inserted(bs)) {
-            bdrv_flush(bs);
-        }
+        bdrv_flush(bs);
     }
 }
 
@@ -3520,7 +3518,7 @@ int coroutine_fn bdrv_co_flush(BlockDriverState *bs)
 {
     int ret;
 
-    if (!bs->drv) {
+    if (!bs || !bdrv_is_inserted(bs) || bdrv_is_read_only(bs)) {
         return 0;
     }
 
@@ -3538,7 +3536,7 @@ int coroutine_fn bdrv_co_flush(BlockDriverState *bs)
     }
 
     if (bs->drv->bdrv_co_flush_to_disk) {
-        return bs->drv->bdrv_co_flush_to_disk(bs);
+        ret = bs->drv->bdrv_co_flush_to_disk(bs);
     } else if (bs->drv->bdrv_aio_flush) {
         BlockDriverAIOCB *acb;
         CoroutineIOCompletion co = {
@@ -3547,10 +3545,10 @@ int coroutine_fn bdrv_co_flush(BlockDriverState *bs)
 
         acb = bs->drv->bdrv_aio_flush(bs, bdrv_co_io_em_complete, &co);
         if (acb == NULL) {
-            return -EIO;
+            ret = -EIO;
         } else {
             qemu_coroutine_yield();
-            return co.ret;
+            ret = co.ret;
         }
     } else {
         /*
@@ -3564,8 +3562,16 @@ int coroutine_fn bdrv_co_flush(BlockDriverState *bs)
          *
          * Let's hope the user knows what he's doing.
          */
-        return 0;
+        ret = 0;
     }
+    if (ret < 0) {
+        return ret;
+    }
+
+    /* Now flush the underlying protocol.  It will also have BDRV_O_NO_FLUSH
+     * in the case of cache=unsafe, so there are no useless flushes.
+     */
+    return bdrv_co_flush(bs->file);
 }
 
 void bdrv_invalidate_cache(BlockDriverState *bs)
diff --git a/block/blkdebug.c b/block/blkdebug.c
index a251802..e56e37d 100644
--- a/block/blkdebug.c
+++ b/block/blkdebug.c
@@ -397,12 +397,6 @@ static void blkdebug_close(BlockDriverState *bs)
     }
 }
 
-static BlockDriverAIOCB *blkdebug_aio_flush(BlockDriverState *bs,
-    BlockDriverCompletionFunc *cb, void *opaque)
-{
-    return bdrv_aio_flush(bs->file, cb, opaque);
-}
-
 static void process_rule(BlockDriverState *bs, struct BlkdebugRule *rule,
     BlkdebugVars *old_vars)
 {
@@ -452,7 +446,6 @@ static BlockDriver bdrv_blkdebug = {
 
     .bdrv_aio_readv     = blkdebug_aio_readv,
     .bdrv_aio_writev    = blkdebug_aio_writev,
-    .bdrv_aio_flush     = blkdebug_aio_flush,
 
     .bdrv_debug_event   = blkdebug_debug_event,
 };
diff --git a/block/cow.c b/block/cow.c
index bb5927c..8d3c9f8 100644
--- a/block/cow.c
+++ b/block/cow.c
@@ -318,11 +318,6 @@ exit:
     return ret;
 }
 
-static coroutine_fn int cow_co_flush(BlockDriverState *bs)
-{
-    return bdrv_co_flush(bs->file);
-}
-
 static QEMUOptionParameter cow_create_options[] = {
     {
         .name = BLOCK_OPT_SIZE,
@@ -348,7 +343,6 @@ static BlockDriver bdrv_cow = {
 
     .bdrv_read              = cow_co_read,
     .bdrv_write             = cow_co_write,
-    .bdrv_co_flush_to_disk  = cow_co_flush,
     .bdrv_co_is_allocated   = cow_co_is_allocated,
 
     .create_options = cow_create_options,
diff --git a/block/qcow.c b/block/qcow.c
index b1cfe1f..35dff49 100644
--- a/block/qcow.c
+++ b/block/qcow.c
@@ -835,11 +835,6 @@ fail:
     return ret;
 }
 
-static coroutine_fn int qcow_co_flush(BlockDriverState *bs)
-{
-    return bdrv_co_flush(bs->file);
-}
-
 static int qcow_get_info(BlockDriverState *bs, BlockDriverInfo *bdi)
 {
     BDRVQcowState *s = bs->opaque;
@@ -877,7 +872,6 @@ static BlockDriver bdrv_qcow = {
 
     .bdrv_co_readv          = qcow_co_readv,
     .bdrv_co_writev         = qcow_co_writev,
-    .bdrv_co_flush_to_disk  = qcow_co_flush,
     .bdrv_co_is_allocated   = qcow_co_is_allocated,
 
     .bdrv_set_key           = qcow_set_key,
diff --git a/block/qcow2.c b/block/qcow2.c
index 7aece65..70d3141 100644
--- a/block/qcow2.c
+++ b/block/qcow2.c
@@ -1253,11 +1253,6 @@ static coroutine_fn int qcow2_co_flush_to_os(BlockDriverState *bs)
     return 0;
 }
 
-static coroutine_fn int qcow2_co_flush_to_disk(BlockDriverState *bs)
-{
-    return bdrv_co_flush(bs->file);
-}
-
 static int64_t qcow2_vm_state_offset(BDRVQcowState *s)
 {
 	return (int64_t)s->l1_vm_state_index << (s->cluster_bits + s->l2_bits);
@@ -1377,7 +1372,6 @@ static BlockDriver bdrv_qcow2 = {
     .bdrv_co_readv          = qcow2_co_readv,
     .bdrv_co_writev         = qcow2_co_writev,
     .bdrv_co_flush_to_os    = qcow2_co_flush_to_os,
-    .bdrv_co_flush_to_disk  = qcow2_co_flush_to_disk,
 
     .bdrv_co_discard        = qcow2_co_discard,
     .bdrv_truncate          = qcow2_truncate,
diff --git a/block/qed.c b/block/qed.c
index a041d31..d6c1580 100644
--- a/block/qed.c
+++ b/block/qed.c
@@ -1350,13 +1350,6 @@ static BlockDriverAIOCB *bdrv_qed_aio_writev(BlockDriverState *bs,
                          opaque, QED_AIOCB_WRITE);
 }
 
-static BlockDriverAIOCB *bdrv_qed_aio_flush(BlockDriverState *bs,
-                                            BlockDriverCompletionFunc *cb,
-                                            void *opaque)
-{
-    return bdrv_aio_flush(bs->file, cb, opaque);
-}
-
 typedef struct {
     Coroutine *co;
     int ret;
@@ -1562,7 +1555,6 @@ static BlockDriver bdrv_qed = {
     .bdrv_make_empty          = bdrv_qed_make_empty,
     .bdrv_aio_readv           = bdrv_qed_aio_readv,
     .bdrv_aio_writev          = bdrv_qed_aio_writev,
-    .bdrv_aio_flush           = bdrv_qed_aio_flush,
     .bdrv_co_write_zeroes     = bdrv_qed_co_write_zeroes,
     .bdrv_truncate            = bdrv_qed_truncate,
     .bdrv_getlength           = bdrv_qed_getlength,
diff --git a/block/raw.c b/block/raw.c
index 1cdac0c..7086e31 100644
--- a/block/raw.c
+++ b/block/raw.c
@@ -25,11 +25,6 @@ static void raw_close(BlockDriverState *bs)
 {
 }
 
-static int coroutine_fn raw_co_flush(BlockDriverState *bs)
-{
-    return bdrv_co_flush(bs->file);
-}
-
 static int64_t raw_getlength(BlockDriverState *bs)
 {
     return bdrv_getlength(bs->file);
@@ -113,7 +108,6 @@ static BlockDriver bdrv_raw = {
 
     .bdrv_co_readv          = raw_co_readv,
     .bdrv_co_writev         = raw_co_writev,
-    .bdrv_co_flush_to_disk  = raw_co_flush,
     .bdrv_co_discard        = raw_co_discard,
 
     .bdrv_probe         = raw_probe,
diff --git a/block/vdi.c b/block/vdi.c
index 6a0011f..f8fa865 100644
--- a/block/vdi.c
+++ b/block/vdi.c
@@ -930,13 +930,6 @@ static void vdi_close(BlockDriverState *bs)
     error_free(s->migration_blocker);
 }
 
-static coroutine_fn int vdi_co_flush(BlockDriverState *bs)
-{
-    logout("\n");
-    return bdrv_co_flush(bs->file);
-}
-
-
 static QEMUOptionParameter vdi_create_options[] = {
     {
         .name = BLOCK_OPT_SIZE,
@@ -969,7 +962,6 @@ static BlockDriver bdrv_vdi = {
     .bdrv_open = vdi_open,
     .bdrv_close = vdi_close,
     .bdrv_create = vdi_create,
-    .bdrv_co_flush_to_disk = vdi_co_flush,
     .bdrv_co_is_allocated = vdi_co_is_allocated,
     .bdrv_make_empty = vdi_make_empty,
 
diff --git a/block/vmdk.c b/block/vmdk.c
index 45c003a..18e9b4c 100644
--- a/block/vmdk.c
+++ b/block/vmdk.c
@@ -1525,10 +1525,10 @@ static void vmdk_close(BlockDriverState *bs)
 
 static coroutine_fn int vmdk_co_flush(BlockDriverState *bs)
 {
-    int i, ret, err;
     BDRVVmdkState *s = bs->opaque;
+    int i, err;
+    int ret = 0;
 
-    ret = bdrv_co_flush(bs->file);
     for (i = 0; i < s->num_extents; i++) {
         err = bdrv_co_flush(s->extents[i].file);
         if (err < 0) {
diff --git a/block/vpc.c b/block/vpc.c
index 6b4816f..706faf3 100644
--- a/block/vpc.c
+++ b/block/vpc.c
@@ -507,11 +507,6 @@ static coroutine_fn int vpc_co_write(BlockDriverState *bs, int64_t sector_num,
     return ret;
 }
 
-static coroutine_fn int vpc_co_flush(BlockDriverState *bs)
-{
-    return bdrv_co_flush(bs->file);
-}
-
 /*
  * Calculates the number of cylinders, heads and sectors per cylinder
  * based on a given number of sectors. This is the algorithm described
@@ -789,7 +784,6 @@ static BlockDriver bdrv_vpc = {
 
     .bdrv_read              = vpc_co_read,
     .bdrv_write             = vpc_co_write,
-    .bdrv_co_flush_to_disk  = vpc_co_flush,
 
     .create_options = vpc_create_options,
 };
commit d7bb72c83cfbcfd0563e158800e4052819223524
Author: Stefan Hajnoczi <stefanha at linux.vnet.ibm.com>
Date:   Mon Mar 12 16:36:07 2012 +0000

    qemu-io: add option to enable tracing
    
    It can be useful to enable QEMU tracing when trying out block layer
    interfaces via qemu-io.  Tracing can be enabled using the new -T FILE
    option where the given file contains a list of trace events to enable
    (just like the qemu --trace events=FILE option).
    
      $ echo qemu_vfree >my-events
      $ ./qemu-io -T my-events ...
    
    Remember to use ./configure --enable-trace-backend=BACKEND when building
    qemu-io.
    
    Signed-off-by: Stefan Hajnoczi <stefanha at linux.vnet.ibm.com>
    Signed-off-by: Kevin Wolf <kwolf at redhat.com>

diff --git a/qemu-io.c b/qemu-io.c
index 3189530..e6fcd77 100644
--- a/qemu-io.c
+++ b/qemu-io.c
@@ -17,6 +17,7 @@
 #include "qemu-common.h"
 #include "block_int.h"
 #include "cmd.h"
+#include "trace/control.h"
 
 #define VERSION	"0.0.1"
 
@@ -1783,6 +1784,7 @@ static void usage(const char *name)
 "  -g, --growable       allow file to grow (only applies to protocols)\n"
 "  -m, --misalign       misalign allocations for O_DIRECT\n"
 "  -k, --native-aio     use kernel AIO implementation (on Linux only)\n"
+"  -T, --trace FILE     enable trace events listed in the given file\n"
 "  -h, --help           display this help and exit\n"
 "  -V, --version        output version information and exit\n"
 "\n",
@@ -1794,7 +1796,7 @@ int main(int argc, char **argv)
 {
     int readonly = 0;
     int growable = 0;
-    const char *sopt = "hVc:rsnmgk";
+    const char *sopt = "hVc:rsnmgkT:";
     const struct option lopt[] = {
         { "help", 0, NULL, 'h' },
         { "version", 0, NULL, 'V' },
@@ -1806,6 +1808,7 @@ int main(int argc, char **argv)
         { "misalign", 0, NULL, 'm' },
         { "growable", 0, NULL, 'g' },
         { "native-aio", 0, NULL, 'k' },
+        { "trace", 1, NULL, 'T' },
         { NULL, 0, NULL, 0 }
     };
     int c;
@@ -1837,6 +1840,11 @@ int main(int argc, char **argv)
         case 'k':
             flags |= BDRV_O_NATIVE_AIO;
             break;
+        case 'T':
+            if (!trace_backend_init(optarg, NULL)) {
+                exit(1); /* error message will have been printed */
+            }
+            break;
         case 'V':
             printf("%s version %s\n", progname, VERSION);
             exit(0);
commit 3948d1d4876065160583e79533bf604481063833
Author: Kevin Wolf <kwolf at redhat.com>
Date:   Mon Mar 12 17:46:51 2012 +0100

    qcow2: Remove unused parameter in get_cluster_table()
    
    Since everything goes through the cache, callers don't use the L2 table
    offset any more.
    
    Signed-off-by: Kevin Wolf <kwolf at redhat.com>
    Reviewed-by: Stefan Hajnoczi <stefanha at linux.vnet.ibm.com>

diff --git a/block/qcow2-cluster.c b/block/qcow2-cluster.c
index e0fb907..cbd224d 100644
--- a/block/qcow2-cluster.c
+++ b/block/qcow2-cluster.c
@@ -466,7 +466,6 @@ out:
  */
 static int get_cluster_table(BlockDriverState *bs, uint64_t offset,
                              uint64_t **new_l2_table,
-                             uint64_t *new_l2_offset,
                              int *new_l2_index)
 {
     BDRVQcowState *s = bs->opaque;
@@ -514,7 +513,6 @@ static int get_cluster_table(BlockDriverState *bs, uint64_t offset,
     l2_index = (offset >> s->cluster_bits) & (s->l2_size - 1);
 
     *new_l2_table = l2_table;
-    *new_l2_offset = l2_offset;
     *new_l2_index = l2_index;
 
     return 0;
@@ -539,11 +537,11 @@ uint64_t qcow2_alloc_compressed_cluster_offset(BlockDriverState *bs,
 {
     BDRVQcowState *s = bs->opaque;
     int l2_index, ret;
-    uint64_t l2_offset, *l2_table;
+    uint64_t *l2_table;
     int64_t cluster_offset;
     int nb_csectors;
 
-    ret = get_cluster_table(bs, offset, &l2_table, &l2_offset, &l2_index);
+    ret = get_cluster_table(bs, offset, &l2_table, &l2_index);
     if (ret < 0) {
         return 0;
     }
@@ -588,7 +586,7 @@ int qcow2_alloc_cluster_link_l2(BlockDriverState *bs, QCowL2Meta *m)
 {
     BDRVQcowState *s = bs->opaque;
     int i, j = 0, l2_index, ret;
-    uint64_t *old_cluster, start_sect, l2_offset, *l2_table;
+    uint64_t *old_cluster, start_sect, *l2_table;
     uint64_t cluster_offset = m->alloc_offset;
     bool cow = false;
 
@@ -633,7 +631,7 @@ int qcow2_alloc_cluster_link_l2(BlockDriverState *bs, QCowL2Meta *m)
     }
 
     qcow2_cache_set_dependency(bs, s->l2_table_cache, s->refcount_block_cache);
-    ret = get_cluster_table(bs, m->offset, &l2_table, &l2_offset, &l2_index);
+    ret = get_cluster_table(bs, m->offset, &l2_table, &l2_index);
     if (ret < 0) {
         goto err;
     }
@@ -817,7 +815,7 @@ int qcow2_alloc_cluster_offset(BlockDriverState *bs, uint64_t offset,
 {
     BDRVQcowState *s = bs->opaque;
     int l2_index, ret, sectors;
-    uint64_t l2_offset, *l2_table;
+    uint64_t *l2_table;
     unsigned int nb_clusters, keep_clusters;
     uint64_t cluster_offset;
 
@@ -825,7 +823,7 @@ int qcow2_alloc_cluster_offset(BlockDriverState *bs, uint64_t offset,
                                       n_start, n_end);
 
     /* Find L2 entry for the first involved cluster */
-    ret = get_cluster_table(bs, offset, &l2_table, &l2_offset, &l2_index);
+    ret = get_cluster_table(bs, offset, &l2_table, &l2_index);
     if (ret < 0) {
         return ret;
     }
@@ -1000,12 +998,12 @@ static int discard_single_l2(BlockDriverState *bs, uint64_t offset,
     unsigned int nb_clusters)
 {
     BDRVQcowState *s = bs->opaque;
-    uint64_t l2_offset, *l2_table;
+    uint64_t *l2_table;
     int l2_index;
     int ret;
     int i;
 
-    ret = get_cluster_table(bs, offset, &l2_table, &l2_offset, &l2_index);
+    ret = get_cluster_table(bs, offset, &l2_table, &l2_index);
     if (ret < 0) {
         return ret;
     }
commit fa6b8733c93107d7fcd7018d1822e93ba9edaa94
Author: Kevin Wolf <kwolf at redhat.com>
Date:   Mon Mar 12 10:30:02 2012 +0100

    tracetool: Forbid argument name 'next'
    
    It has happened more than once that patches that look perfectly sane
    and work with simpletrace broke systemtap because they use 'next' as an
    argument name for a tracing function. However, 'next' is a keyword for
    systemtap, so we shouldn't use it.
    
    Signed-off-by: Kevin Wolf <kwolf at redhat.com>

diff --git a/scripts/tracetool b/scripts/tracetool
index 47389b6..7b1c142 100755
--- a/scripts/tracetool
+++ b/scripts/tracetool
@@ -81,6 +81,10 @@ get_args()
     args=${1#*\(}
     args=${args%%\)*}
     echo "$args"
+
+    if (echo "$args" | grep "[ *]next\($\|[, ]\)" > /dev/null 2>&1); then
+        echo -e "\n#error 'next' is a bad argument name (clash with systemtap keyword)\n "
+    fi
 }
 
 # Get the argument name list of a trace event
commit bfe24e1a26d33d57df3c75e7f44273f0b0ca5943
Author: Kevin Wolf <kwolf at redhat.com>
Date:   Mon Mar 12 10:28:34 2012 +0100

    trace-events: Rename 'next' argument
    
    'next' is a systemtap keyword, so it's a bad idea to use it as an
    argument name.
    
    Signed-off-by: Kevin Wolf <kwolf at redhat.com>

diff --git a/trace-events b/trace-events
index db2cd39..a5f276d 100644
--- a/trace-events
+++ b/trace-events
@@ -562,7 +562,7 @@ qemu_coroutine_terminate(void *co) "self %p"
 
 # qemu-coroutine-lock.c
 qemu_co_queue_next_bh(void) ""
-qemu_co_queue_next(void *next) "next %p"
+qemu_co_queue_next(void *nxt) "next %p"
 qemu_co_mutex_lock_entry(void *mutex, void *self) "mutex %p self %p"
 qemu_co_mutex_lock_return(void *mutex, void *self) "mutex %p self %p"
 qemu_co_mutex_unlock_entry(void *mutex, void *self) "mutex %p self %p"
commit 221b3a3f1e5edb9e41a48bfa384803800184b397
Author: Julien Grall <julien.grall at citrix.com>
Date:   Wed Apr 4 15:15:41 2012 +0100

    memory: check address space when a listener is registered
    
    This patch resolves a bug in memory listener registration.
    "range_add" callback  was called on each section of the both
    address space (IO and memory space) even if it doesn't match
    the address space filter.
    
    Signed-off-by: Julien Grall <julien.grall at citrix.com>
    Signed-off-by: Avi Kivity <avi at redhat.com>

diff --git a/memory.c b/memory.c
index a3f5b59..aab4a31 100644
--- a/memory.c
+++ b/memory.c
@@ -1444,6 +1444,11 @@ static void listener_add_address_space(MemoryListener *listener,
 {
     FlatRange *fr;
 
+    if (listener->address_space_filter
+        && listener->address_space_filter != as->root) {
+        return;
+    }
+
     if (global_dirty_log) {
         listener->log_global_start(listener);
     }
commit 8f8d364f2447e58768132fc10f48a67af371ee38
Merge: a7be9ba... b8ba679...
Author: Blue Swirl <blauwirbel at gmail.com>
Date:   Wed Apr 4 20:45:03 2012 +0000

    Merge branch 's390-for-upstream' of git://repo.or.cz/qemu/agraf
    
    * 's390-for-upstream' of git://repo.or.cz/qemu/agraf:
      target-s390x: Update s390x_{tod,cpu}_timer() to use S390CPU
      target-s390x: QOM'ify CPU init
      target-s390x: QOM'ify CPU reset
      target-s390x: QOM'ify CPU

commit a7be9bad33d81d4bab2a51935b5443d258e7d082
Author: Artyom Tarasenko <atar4qemu at gmail.com>
Date:   Tue Apr 3 17:49:05 2012 +0200

    Improve interrupt handling priority
    
    The vector interrupt has higher priority than interrupt_level_n.
    Also check only interrupt_level_n concurency when TL > 0, the traps of
    other types may be nested.
    
    Signed-off-by: Artyom Tarasenko <atar4qemu at gmail.com>
    Signed-off-by: Blue Swirl <blauwirbel at gmail.com>

diff --git a/hw/sun4u.c b/hw/sun4u.c
index 50bc0d2..fe33138 100644
--- a/hw/sun4u.c
+++ b/hw/sun4u.c
@@ -248,6 +248,10 @@ void cpu_check_irqs(CPUSPARCState *env)
     uint32_t pil = env->pil_in |
                   (env->softint & ~(SOFTINT_TIMER | SOFTINT_STIMER));
 
+    /* TT_IVEC has a higher priority (16) than TT_EXTINT (31..17) */
+    if (env->ivec_status & 0x20) {
+        return;
+    }
     /* check if TM or SM in SOFTINT are set
        setting these also causes interrupt 14 */
     if (env->softint & (SOFTINT_TIMER | SOFTINT_STIMER)) {
@@ -275,7 +279,8 @@ void cpu_check_irqs(CPUSPARCState *env)
                 int old_interrupt = env->interrupt_index;
                 int new_interrupt = TT_EXTINT | i;
 
-                if (env->tl > 0 && cpu_tsptr(env)->tt > new_interrupt) {
+                if (unlikely(env->tl > 0 && cpu_tsptr(env)->tt > new_interrupt
+                  && ((cpu_tsptr(env)->tt & 0x1f0) == TT_EXTINT))) {
                     CPUIRQ_DPRINTF("Not setting CPU IRQ: TL=%d "
                                    "current %x >= pending %x\n",
                                    env->tl, cpu_tsptr(env)->tt, new_interrupt);
commit 23cf96e1971f04f21ec4bb048df4d9e2e9933018
Author: Artyom Tarasenko <atar4qemu at gmail.com>
Date:   Tue Apr 3 17:49:04 2012 +0200

    Fix vector interrupt handling
    
    Don't produce stray irq 5, don't overwrite ivec_data if still busy with
    processing of the previous interrupt.
    
    Signed-off-by: Artyom Tarasenko <atar4qemu at gmail.com>
    Signed-off-by: Blue Swirl <blauwirbel at gmail.com>

diff --git a/hw/sun4u.c b/hw/sun4u.c
index 237e20c..50bc0d2 100644
--- a/hw/sun4u.c
+++ b/hw/sun4u.c
@@ -309,19 +309,22 @@ static void cpu_set_ivec_irq(void *opaque, int irq, int level)
     CPUSPARCState *env = opaque;
 
     if (level) {
-        CPUIRQ_DPRINTF("Raise IVEC IRQ %d\n", irq);
-        env->interrupt_index = TT_IVEC;
-        env->pil_in |= 1 << 5;
-        env->ivec_status |= 0x20;
-        env->ivec_data[0] = (0x1f << 6) | irq;
-        env->ivec_data[1] = 0;
-        env->ivec_data[2] = 0;
-        cpu_interrupt(env, CPU_INTERRUPT_HARD);
-      } else {
-        CPUIRQ_DPRINTF("Lower IVEC IRQ %d\n", irq);
-        env->pil_in &= ~(1 << 5);
-        env->ivec_status &= ~0x20;
-        cpu_reset_interrupt(env, CPU_INTERRUPT_HARD);
+        if (!(env->ivec_status & 0x20)) {
+            CPUIRQ_DPRINTF("Raise IVEC IRQ %d\n", irq);
+            env->halted = 0;
+            env->interrupt_index = TT_IVEC;
+            env->ivec_status |= 0x20;
+            env->ivec_data[0] = (0x1f << 6) | irq;
+            env->ivec_data[1] = 0;
+            env->ivec_data[2] = 0;
+            cpu_interrupt(env, CPU_INTERRUPT_HARD);
+        }
+    } else {
+        if (env->ivec_status & 0x20) {
+            CPUIRQ_DPRINTF("Lower IVEC IRQ %d\n", irq);
+            env->ivec_status &= ~0x20;
+            cpu_reset_interrupt(env, CPU_INTERRUPT_HARD);
+        }
     }
 }
 
commit b8ba6799f41cccd1e81ec2986f2f80fc916ef86f
Author: Andreas Färber <afaerber at suse.de>
Date:   Mon Apr 2 14:00:43 2012 +0200

    target-s390x: Update s390x_{tod,cpu}_timer() to use S390CPU
    
    In place of CPUS390XState pass S390CPU as opaque from the new initfn.
    cpu_interrupt() is anticipated to take a CPUState in the future.
    
    Signed-off-by: Andreas Färber <afaerber at suse.de>
    Tested-by: Christian Borntraeger <borntraeger at de.ibm.com>

diff --git a/target-s390x/cpu.c b/target-s390x/cpu.c
index 72ec349..f183213 100644
--- a/target-s390x/cpu.c
+++ b/target-s390x/cpu.c
@@ -60,8 +60,8 @@ static void s390_cpu_initfn(Object *obj)
     env->tod_offset = TOD_UNIX_EPOCH +
                       (time2tod(mktimegm(&tm)) * 1000000000ULL);
     env->tod_basetime = 0;
-    env->tod_timer = qemu_new_timer_ns(vm_clock, s390x_tod_timer, env);
-    env->cpu_timer = qemu_new_timer_ns(vm_clock, s390x_cpu_timer, env);
+    env->tod_timer = qemu_new_timer_ns(vm_clock, s390x_tod_timer, cpu);
+    env->cpu_timer = qemu_new_timer_ns(vm_clock, s390x_cpu_timer, cpu);
 #endif
     env->cpu_num = cpu_num++;
     env->ext_index = -1;
diff --git a/target-s390x/helper.c b/target-s390x/helper.c
index 6233f9a..209a696 100644
--- a/target-s390x/helper.c
+++ b/target-s390x/helper.c
@@ -53,7 +53,8 @@
 #ifndef CONFIG_USER_ONLY
 void s390x_tod_timer(void *opaque)
 {
-    CPUS390XState *env = opaque;
+    S390CPU *cpu = opaque;
+    CPUS390XState *env = &cpu->env;
 
     env->pending_int |= INTERRUPT_TOD;
     cpu_interrupt(env, CPU_INTERRUPT_HARD);
@@ -61,7 +62,8 @@ void s390x_tod_timer(void *opaque)
 
 void s390x_cpu_timer(void *opaque)
 {
-    CPUS390XState *env = opaque;
+    S390CPU *cpu = opaque;
+    CPUS390XState *env = &cpu->env;
 
     env->pending_int |= INTERRUPT_CPUTIMER;
     cpu_interrupt(env, CPU_INTERRUPT_HARD);
commit 8f22e0df803697c11e8b10c90cc2e67df6e42884
Author: Andreas Färber <afaerber at suse.de>
Date:   Mon Apr 2 13:56:29 2012 +0200

    target-s390x: QOM'ify CPU init
    
    Move code from cpu_s390x_init() into an initfn.
    
    Signed-off-by: Andreas Färber <afaerber at suse.de>
    Tested-by: Christian Borntraeger <borntraeger at de.ibm.com>

diff --git a/target-s390x/cpu.c b/target-s390x/cpu.c
index cae0b18..72ec349 100644
--- a/target-s390x/cpu.c
+++ b/target-s390x/cpu.c
@@ -45,6 +45,30 @@ static void s390_cpu_reset(CPUState *s)
     s390_add_running_cpu(env);
 }
 
+static void s390_cpu_initfn(Object *obj)
+{
+    S390CPU *cpu = S390_CPU(obj);
+    CPUS390XState *env = &cpu->env;
+    static int cpu_num = 0;
+#if !defined(CONFIG_USER_ONLY)
+    struct tm tm;
+#endif
+
+    cpu_exec_init(env);
+#if !defined(CONFIG_USER_ONLY)
+    qemu_get_timedate(&tm, 0);
+    env->tod_offset = TOD_UNIX_EPOCH +
+                      (time2tod(mktimegm(&tm)) * 1000000000ULL);
+    env->tod_basetime = 0;
+    env->tod_timer = qemu_new_timer_ns(vm_clock, s390x_tod_timer, env);
+    env->cpu_timer = qemu_new_timer_ns(vm_clock, s390x_cpu_timer, env);
+#endif
+    env->cpu_num = cpu_num++;
+    env->ext_index = -1;
+
+    cpu_reset(CPU(cpu));
+}
+
 static void s390_cpu_class_init(ObjectClass *oc, void *data)
 {
     S390CPUClass *scc = S390_CPU_CLASS(oc);
@@ -58,6 +82,7 @@ static const TypeInfo s390_cpu_type_info = {
     .name = TYPE_S390_CPU,
     .parent = TYPE_CPU,
     .instance_size = sizeof(S390CPU),
+    .instance_init = s390_cpu_initfn,
     .abstract = false,
     .class_size = sizeof(S390CPUClass),
     .class_init = s390_cpu_class_init,
diff --git a/target-s390x/cpu.h b/target-s390x/cpu.h
index c6ee959..2f3f394 100644
--- a/target-s390x/cpu.h
+++ b/target-s390x/cpu.h
@@ -288,6 +288,9 @@ int cpu_s390x_handle_mmu_fault (CPUS390XState *env, target_ulong address, int rw
 
 
 #ifndef CONFIG_USER_ONLY
+void s390x_tod_timer(void *opaque);
+void s390x_cpu_timer(void *opaque);
+
 int s390_virtio_hypercall(CPUS390XState *env, uint64_t mem, uint64_t hypercall);
 
 #ifdef CONFIG_KVM
diff --git a/target-s390x/helper.c b/target-s390x/helper.c
index cd3e8f5..6233f9a 100644
--- a/target-s390x/helper.c
+++ b/target-s390x/helper.c
@@ -51,7 +51,7 @@
 #endif
 
 #ifndef CONFIG_USER_ONLY
-static void s390x_tod_timer(void *opaque)
+void s390x_tod_timer(void *opaque)
 {
     CPUS390XState *env = opaque;
 
@@ -59,7 +59,7 @@ static void s390x_tod_timer(void *opaque)
     cpu_interrupt(env, CPU_INTERRUPT_HARD);
 }
 
-static void s390x_cpu_timer(void *opaque)
+void s390x_cpu_timer(void *opaque)
 {
     CPUS390XState *env = opaque;
 
@@ -72,32 +72,17 @@ CPUS390XState *cpu_s390x_init(const char *cpu_model)
 {
     S390CPU *cpu;
     CPUS390XState *env;
-#if !defined (CONFIG_USER_ONLY)
-    struct tm tm;
-#endif
     static int inited = 0;
-    static int cpu_num = 0;
 
     cpu = S390_CPU(object_new(TYPE_S390_CPU));
     env = &cpu->env;
-    cpu_exec_init(env);
+
     if (tcg_enabled() && !inited) {
         inited = 1;
         s390x_translate_init();
     }
 
-#if !defined(CONFIG_USER_ONLY)
-    qemu_get_timedate(&tm, 0);
-    env->tod_offset = TOD_UNIX_EPOCH +
-                      (time2tod(mktimegm(&tm)) * 1000000000ULL);
-    env->tod_basetime = 0;
-    env->tod_timer = qemu_new_timer_ns(vm_clock, s390x_tod_timer, env);
-    env->cpu_timer = qemu_new_timer_ns(vm_clock, s390x_cpu_timer, env);
-#endif
     env->cpu_model_str = cpu_model;
-    env->cpu_num = cpu_num++;
-    env->ext_index = -1;
-    cpu_reset(CPU(cpu));
     qemu_init_vcpu(env);
     return env;
 }
commit 1ac1a7499bcb44174735780e0bd0421a1ac7a323
Author: Andreas Färber <afaerber at suse.de>
Date:   Mon Apr 2 13:31:59 2012 +0200

    target-s390x: QOM'ify CPU reset
    
    Move code from cpu_state_reset() to s390_cpu_reset().
    
    Signed-off-by: Andreas Färber <afaerber at suse.de>
    Tested-by: Christian Borntraeger <borntraeger at de.ibm.com>

diff --git a/target-s390x/cpu.c b/target-s390x/cpu.c
index 94320f2..cae0b18 100644
--- a/target-s390x/cpu.c
+++ b/target-s390x/cpu.c
@@ -1,6 +1,8 @@
 /*
  * QEMU S/390 CPU
  *
+ * Copyright (c) 2009 Ulrich Hecht
+ * Copyright (c) 2011 Alexander Graf
  * Copyright (c) 2012 SUSE LINUX Products GmbH
  *
  * This library is free software; you can redistribute it and/or
@@ -23,15 +25,24 @@
 #include "qemu-timer.h"
 
 
+/* CPUClass::reset() */
 static void s390_cpu_reset(CPUState *s)
 {
     S390CPU *cpu = S390_CPU(s);
     S390CPUClass *scc = S390_CPU_GET_CLASS(cpu);
     CPUS390XState *env = &cpu->env;
 
+    if (qemu_loglevel_mask(CPU_LOG_RESET)) {
+        qemu_log("CPU Reset (CPU %d)\n", env->cpu_index);
+        log_cpu_state(env, 0);
+    }
+
     scc->parent_reset(s);
 
-    cpu_state_reset(env);
+    memset(env, 0, offsetof(CPUS390XState, breakpoints));
+    /* FIXME: reset vector? */
+    tlb_flush(env, 1);
+    s390_add_running_cpu(env);
 }
 
 static void s390_cpu_class_init(ObjectClass *oc, void *data)
diff --git a/target-s390x/helper.c b/target-s390x/helper.c
index ae57ab3..cd3e8f5 100644
--- a/target-s390x/helper.c
+++ b/target-s390x/helper.c
@@ -97,7 +97,7 @@ CPUS390XState *cpu_s390x_init(const char *cpu_model)
     env->cpu_model_str = cpu_model;
     env->cpu_num = cpu_num++;
     env->ext_index = -1;
-    cpu_state_reset(env);
+    cpu_reset(CPU(cpu));
     qemu_init_vcpu(env);
     return env;
 }
@@ -123,15 +123,7 @@ int cpu_s390x_handle_mmu_fault (CPUS390XState *env, target_ulong address, int rw
 
 void cpu_state_reset(CPUS390XState *env)
 {
-    if (qemu_loglevel_mask(CPU_LOG_RESET)) {
-        qemu_log("CPU Reset (CPU %d)\n", env->cpu_index);
-        log_cpu_state(env, 0);
-    }
-
-    memset(env, 0, offsetof(CPUS390XState, breakpoints));
-    /* FIXME: reset vector? */
-    tlb_flush(env, 1);
-    s390_add_running_cpu(env);
+    cpu_reset(ENV_GET_CPU(env));
 }
 
 #ifndef CONFIG_USER_ONLY
commit 29e4bcb26b80f975920508c83a9f24f29eb6bc1a
Author: Andreas Färber <afaerber at suse.de>
Date:   Mon Apr 2 11:39:23 2012 +0200

    target-s390x: QOM'ify CPU
    
    Embed CPUS390XState as first member of S390CPU.
    Since -cpu is being ignored, make TYPE_S390_CPU non-abstract.
    
    Signed-off-by: Andreas Färber <afaerber at suse.de>
    Tested-by: Christian Borntraeger <borntraeger at de.ibm.com>

diff --git a/Makefile.target b/Makefile.target
index cff15f0..999a968 100644
--- a/Makefile.target
+++ b/Makefile.target
@@ -93,6 +93,7 @@ libobj-$(TARGET_SPARC64) += vis_helper.o
 libobj-$(CONFIG_NEED_MMU) += mmu.o
 libobj-$(TARGET_ARM) += neon_helper.o iwmmxt_helper.o
 libobj-$(TARGET_ARM) += cpu.o
+libobj-$(TARGET_S390X) += cpu.o
 ifeq ($(TARGET_BASE_ARCH), sparc)
 libobj-y += fop_helper.o cc_helper.o win_helper.o mmu_helper.o ldst_helper.o
 libobj-y += cpu_init.o
diff --git a/target-s390x/cpu-qom.h b/target-s390x/cpu-qom.h
new file mode 100644
index 0000000..6fa55a8
--- /dev/null
+++ b/target-s390x/cpu-qom.h
@@ -0,0 +1,71 @@
+/*
+ * QEMU S/390 CPU
+ *
+ * Copyright (c) 2012 SUSE LINUX Products GmbH
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, see
+ * <http://www.gnu.org/licenses/lgpl-2.1.html>
+ */
+#ifndef QEMU_S390_CPU_QOM_H
+#define QEMU_S390_CPU_QOM_H
+
+#include "qemu/cpu.h"
+#include "cpu.h"
+
+#define TYPE_S390_CPU "s390-cpu"
+
+#define S390_CPU_CLASS(klass) \
+    OBJECT_CLASS_CHECK(S390CPUClass, (klass), TYPE_S390_CPU)
+#define S390_CPU(obj) \
+    OBJECT_CHECK(S390CPU, (obj), TYPE_S390_CPU)
+#define S390_CPU_GET_CLASS(obj) \
+    OBJECT_GET_CLASS(S390CPUClass, (obj), TYPE_S390_CPU)
+
+/**
+ * S390CPUClass:
+ * @parent_reset: The parent class' reset handler.
+ *
+ * An S/390 CPU model.
+ */
+typedef struct S390CPUClass {
+    /*< private >*/
+    CPUClass parent_class;
+    /*< public >*/
+
+    void (*parent_reset)(CPUState *cpu);
+} S390CPUClass;
+
+/**
+ * S390CPU:
+ * @env: #CPUS390XState.
+ *
+ * An S/390 CPU.
+ */
+typedef struct S390CPU {
+    /*< private >*/
+    CPUState parent_obj;
+    /*< public >*/
+
+    CPUS390XState env;
+} S390CPU;
+
+static inline S390CPU *s390_env_get_cpu(CPUS390XState *env)
+{
+    return S390_CPU(container_of(env, S390CPU, env));
+}
+
+#define ENV_GET_CPU(e) CPU(s390_env_get_cpu(e))
+
+
+#endif
diff --git a/target-s390x/cpu.c b/target-s390x/cpu.c
new file mode 100644
index 0000000..94320f2
--- /dev/null
+++ b/target-s390x/cpu.c
@@ -0,0 +1,60 @@
+/*
+ * QEMU S/390 CPU
+ *
+ * Copyright (c) 2012 SUSE LINUX Products GmbH
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, see
+ * <http://www.gnu.org/licenses/lgpl-2.1.html>
+ */
+
+#include "cpu-qom.h"
+#include "qemu-common.h"
+#include "qemu-timer.h"
+
+
+static void s390_cpu_reset(CPUState *s)
+{
+    S390CPU *cpu = S390_CPU(s);
+    S390CPUClass *scc = S390_CPU_GET_CLASS(cpu);
+    CPUS390XState *env = &cpu->env;
+
+    scc->parent_reset(s);
+
+    cpu_state_reset(env);
+}
+
+static void s390_cpu_class_init(ObjectClass *oc, void *data)
+{
+    S390CPUClass *scc = S390_CPU_CLASS(oc);
+    CPUClass *cc = CPU_CLASS(scc);
+
+    scc->parent_reset = cc->reset;
+    cc->reset = s390_cpu_reset;
+}
+
+static const TypeInfo s390_cpu_type_info = {
+    .name = TYPE_S390_CPU,
+    .parent = TYPE_CPU,
+    .instance_size = sizeof(S390CPU),
+    .abstract = false,
+    .class_size = sizeof(S390CPUClass),
+    .class_init = s390_cpu_class_init,
+};
+
+static void s390_cpu_register_types(void)
+{
+    type_register_static(&s390_cpu_type_info);
+}
+
+type_init(s390_cpu_register_types)
diff --git a/target-s390x/cpu.h b/target-s390x/cpu.h
index ea849fc..c6ee959 100644
--- a/target-s390x/cpu.h
+++ b/target-s390x/cpu.h
@@ -991,4 +991,6 @@ static inline void cpu_pc_from_tb(CPUS390XState *env, TranslationBlock* tb)
     env->psw.addr = tb->pc;
 }
 
+#include "cpu-qom.h"
+
 #endif
diff --git a/target-s390x/helper.c b/target-s390x/helper.c
index 44d5048..ae57ab3 100644
--- a/target-s390x/helper.c
+++ b/target-s390x/helper.c
@@ -70,6 +70,7 @@ static void s390x_cpu_timer(void *opaque)
 
 CPUS390XState *cpu_s390x_init(const char *cpu_model)
 {
+    S390CPU *cpu;
     CPUS390XState *env;
 #if !defined (CONFIG_USER_ONLY)
     struct tm tm;
@@ -77,7 +78,8 @@ CPUS390XState *cpu_s390x_init(const char *cpu_model)
     static int inited = 0;
     static int cpu_num = 0;
 
-    env = g_malloc0(sizeof(CPUS390XState));
+    cpu = S390_CPU(object_new(TYPE_S390_CPU));
+    env = &cpu->env;
     cpu_exec_init(env);
     if (tcg_enabled() && !inited) {
         inited = 1;
commit 53fbf7b5391c76cc474d469bfed6a69a1243f4de
Author: Anthony PERARD <anthony.perard at citrix.com>
Date:   Mon Apr 2 16:10:39 2012 +0100

    make: fix clean rule by removing build file in qom/
    
    Make clean does not clean the 'qom' directory, leaving *.o and *.d files. This
    patch fixes this.
    
    Signed-off-by: Anthony PERARD <anthony.perard at citrix.com>
    Signed-off-by: Stefan Hajnoczi <stefanha at linux.vnet.ibm.com>

diff --git a/Makefile b/Makefile
index 35c7a2a..a78f53d 100644
--- a/Makefile
+++ b/Makefile
@@ -217,6 +217,7 @@ clean:
 	rm -f *.o *.d *.a *.lo $(TOOLS) $(HELPERS-y) qemu-ga TAGS cscope.* *.pod *~ */*~
 	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 qom/*.o qom/*.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
commit c9a2e37c7d70e1b1f11997f7ecab202393bff9fc
Author: Lluís Vilanova <vilanova at ac.upc.edu>
Date:   Mon Apr 2 14:49:49 2012 +0200

    configure: Link qga against UST tracing related libraries
    
    Signed-off-by: Harsh Prateek Bora <harsh at linux.vnet.ibm.com>
    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/configure b/configure
index 319355b..520bd93 100755
--- a/configure
+++ b/configure
@@ -2673,6 +2673,7 @@ int main(void) { return 0; }
 EOF
   if compile_prog "" "" ; then
     LIBS="-lust -lurcu-bp $LIBS"
+    libs_qga="-lust -lurcu-bp $libs_qga"
   else
     echo
     echo "Error: Trace backend 'ust' missing libust header files"
commit 94b4fefae6aa8ee7739b2b9ad6ef14a07baf78be
Author: Lluís Vilanova <vilanova at ac.upc.edu>
Date:   Mon Apr 2 14:49:44 2012 +0200

    configure: Link QEMU against 'liburcu-bp'
    
    This library is needed when using 'ust/tracepoint.h'.
    
    Signed-off-by: Harsh Prateek Bora <harsh at linux.vnet.ibm.com>
    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/configure b/configure
index c0a542b..319355b 100755
--- a/configure
+++ b/configure
@@ -2672,7 +2672,7 @@ if test "$trace_backend" = "ust"; then
 int main(void) { return 0; }
 EOF
   if compile_prog "" "" ; then
-    LIBS="-lust $LIBS"
+    LIBS="-lust -lurcu-bp $LIBS"
   else
     echo
     echo "Error: Trace backend 'ust' missing libust header files"
commit a92433afcc1e48b0ba7a014bb6d2f0a7cd416a31
Author: Frediano Ziglio <freddy77 at gmail.com>
Date:   Sat Mar 31 19:32:14 2012 +0100

    main-loop: make qemu_event_handle static
    
    Signed-off-by: Frediano Ziglio <freddy77 at gmail.com>
    Signed-off-by: Stefan Hajnoczi <stefanha at linux.vnet.ibm.com>

diff --git a/main-loop.c b/main-loop.c
index db23de0..fc738d1 100644
--- a/main-loop.c
+++ b/main-loop.c
@@ -164,7 +164,7 @@ static int qemu_signal_init(void)
 
 #else /* _WIN32 */
 
-HANDLE qemu_event_handle = NULL;
+static HANDLE qemu_event_handle = NULL;
 
 static void dummy_event_handler(void *opaque)
 {
commit fb7c8e8a2d3ac99c9310a01d17a2b46584320bc9
Author: Stefan Weil <sw at weilnetz.de>
Date:   Sat Mar 31 17:34:41 2012 +0200

    block/curl: Replace usleep by g_usleep
    
    The function usleep is not available for all supported platforms:
    at least some versions of MinGW don't support it.
    
    usleep was also declared obsolete by POSIX.1-2001.
    
    The function g_usleep is part of glib2.0, so it is available for
    all supported platforms.
    
    Using nanosleep would also be possible but needs more code.
    
    Signed-off-by: Stefan Weil <sw at weilnetz.de>
    Signed-off-by: Stefan Hajnoczi <stefanha at linux.vnet.ibm.com>

diff --git a/block/curl.c b/block/curl.c
index e9102e3..a909eca 100644
--- a/block/curl.c
+++ b/block/curl.c
@@ -282,7 +282,7 @@ static CURLState *curl_init_state(BDRVCURLState *s)
             break;
         }
         if (!state) {
-            usleep(100);
+            g_usleep(100);
             curl_multi_do(s);
         }
     } while(!state);
commit 3f97fd851cf7b16b822c2c366e02708070f713bb
Author: Stefan Weil <sw at weilnetz.de>
Date:   Sat Mar 31 17:11:31 2012 +0200

    qtest: Add missing GCC_FMT_ATTR
    
    gcc reports an error when the code is compiled with -Wmissing-format-attribute.
    
    Signed-off-by: Stefan Weil <sw at weilnetz.de>
    Signed-off-by: Stefan Hajnoczi <stefanha at linux.vnet.ibm.com>

diff --git a/qtest.c b/qtest.c
index daeabb7..18afcd9 100644
--- a/qtest.c
+++ b/qtest.c
@@ -156,7 +156,8 @@ static void qtest_send_prefix(CharDriverState *chr)
             tv.tv_sec, tv.tv_usec);
 }
 
-static void qtest_send(CharDriverState *chr, const char *fmt, ...)
+static void GCC_FMT_ATTR(2, 3) qtest_send(CharDriverState *chr,
+                                          const char *fmt, ...)
 {
     va_list ap;
     char buffer[1024];
commit 6cec29c4a0338bfd96dec42cce51c9c447facb23
Author: Jan Kiszka <jan.kiszka at siemens.com>
Date:   Wed Mar 28 20:56:38 2012 +0200

    w32: Undefine error constants before their redefinition
    
    Avoids lots of warnings.
    
    Signed-off-by: Jan Kiszka <jan.kiszka at siemens.com>
    Signed-off-by: Stefan Hajnoczi <stefanha at linux.vnet.ibm.com>

diff --git a/qemu_socket.h b/qemu_socket.h
index fe4cf6c..51ad210 100644
--- a/qemu_socket.h
+++ b/qemu_socket.h
@@ -8,7 +8,9 @@
 #include <ws2tcpip.h>
 
 #define socket_error() WSAGetLastError()
+#undef EWOULDBLOCK
 #undef EINTR
+#undef EINPROGRESS
 #define EWOULDBLOCK WSAEWOULDBLOCK
 #define EINTR       WSAEINTR
 #define EINPROGRESS WSAEINPROGRESS
commit 368542b8356038593c4d394d87ee086ef65a6da3
Author: Stefan Hajnoczi <stefanha at linux.vnet.ibm.com>
Date:   Tue Mar 27 08:26:18 2012 +0100

    configure: fix mingw32 libs_qga typo
    
    It's typical to prepend or append parameters to an argument string so
    that other places in ./configure can add parameters without clobbering
    the string.  In the mingw32 libs_qga case there is a typo "$lib_qga"
    instead of "$libs_qga".
    
    Signed-off-by: Stefan Hajnoczi <stefanha at linux.vnet.ibm.com>
    Reviewed-by: Andreas Färber <afaerber at suse.de>

diff --git a/configure b/configure
index 4b3adc9..c0a542b 100755
--- a/configure
+++ b/configure
@@ -526,7 +526,7 @@ EOF
   bindir="\${prefix}"
   sysconfdir="\${prefix}"
   confsuffix=""
-  libs_qga="-lws2_32 -lwinmm -lpowrprof $lib_qga"
+  libs_qga="-lws2_32 -lwinmm -lpowrprof $libs_qga"
 fi
 
 werror=""
commit f05f6b4adb4db3affb0cdd17383b0a7e905e66e1
Author: Paolo Bonzini <pbonzini at redhat.com>
Date:   Wed Mar 28 16:34:12 2012 +0200

    qdev: put all devices under /machine
    
    Avoid cluttering too much the QOM root.
    
    Signed-off-by: Paolo Bonzini <pbonzini at redhat.com>
    Signed-off-by: Anthony Liguori <aliguori at us.ibm.com>

diff --git a/hw/piix_pci.c b/hw/piix_pci.c
index 9017565..179d9a6 100644
--- a/hw/piix_pci.c
+++ b/hw/piix_pci.c
@@ -276,7 +276,7 @@ static PCIBus *i440fx_common_init(const char *device_name,
     b = pci_bus_new(&s->busdev.qdev, NULL, pci_address_space,
                     address_space_io, 0);
     s->bus = b;
-    object_property_add_child(object_get_root(), "i440fx", OBJECT(dev), NULL);
+    object_property_add_child(qdev_get_machine(), "i440fx", OBJECT(dev), NULL);
     qdev_init_nofail(dev);
 
     d = pci_create_simple(b, 0, device_name);
diff --git a/hw/ppc_prep.c b/hw/ppc_prep.c
index 86c9336..9d8e659 100644
--- a/hw/ppc_prep.c
+++ b/hw/ppc_prep.c
@@ -615,7 +615,7 @@ static void ppc_prep_init (ram_addr_t ram_size,
     sys = sysbus_from_qdev(dev);
     pcihost = DO_UPCAST(PCIHostState, busdev, sys);
     pcihost->address_space = get_system_memory();
-    object_property_add_child(object_get_root(), "raven", OBJECT(dev), NULL);
+    object_property_add_child(qdev_get_machine(), "raven", OBJECT(dev), NULL);
     qdev_init_nofail(dev);
     pci_bus = (PCIBus *)qdev_get_child_bus(dev, "pci.0");
     if (pci_bus == NULL) {
diff --git a/hw/qdev-monitor.c b/hw/qdev-monitor.c
index 031cb83..4783366 100644
--- a/hw/qdev-monitor.c
+++ b/hw/qdev-monitor.c
@@ -180,7 +180,7 @@ static Object *qdev_get_peripheral(void)
     static Object *dev;
 
     if (dev == NULL) {
-        dev = container_get("/peripheral");
+        dev = container_get("/machine/peripheral");
     }
 
     return dev;
@@ -191,7 +191,7 @@ static Object *qdev_get_peripheral_anon(void)
     static Object *dev;
 
     if (dev == NULL) {
-        dev = container_get("/peripheral-anon");
+        dev = container_get("/machine/peripheral-anon");
     }
 
     return dev;
diff --git a/hw/qdev.c b/hw/qdev.c
index f5c716e..0d3c0fc 100644
--- a/hw/qdev.c
+++ b/hw/qdev.c
@@ -157,7 +157,7 @@ int qdev_init(DeviceState *dev)
         static int unattached_count = 0;
         gchar *name = g_strdup_printf("device[%d]", unattached_count++);
 
-        object_property_add_child(container_get("/unattached"), name,
+        object_property_add_child(container_get("/machine/unattached"), name,
                                   OBJECT(dev), NULL);
         g_free(name);
     }
@@ -668,6 +668,17 @@ void device_reset(DeviceState *dev)
     }
 }
 
+Object *qdev_get_machine(void)
+{
+    static Object *dev;
+
+    if (dev == NULL) {
+        dev = container_get("/machine");
+    }
+
+    return dev;
+}
+
 static TypeInfo device_type_info = {
     .name = TYPE_DEVICE,
     .parent = TYPE_OBJECT,
diff --git a/hw/qdev.h b/hw/qdev.h
index 9cc3f98..a8df42f 100644
--- a/hw/qdev.h
+++ b/hw/qdev.h
@@ -349,6 +349,8 @@ BusInfo *qdev_get_bus_info(DeviceState *dev);
 
 Property *qdev_get_props(DeviceState *dev);
 
+Object *qdev_get_machine(void);
+
 /* FIXME: make this a link<> */
 void qdev_set_parent_bus(DeviceState *dev, BusState *bus);
 
commit da57febfed7bad11be79f047b59719c38abd0712
Author: Paolo Bonzini <pbonzini at redhat.com>
Date:   Tue Mar 27 18:38:47 2012 +0200

    qdev: give all devices a canonical path
    
    A strong limitation of QOM right now is that unconverted ports
    (e.g. all...) do not give a canonical path to devices that are
    part of the board.  This in turn makes it impossible to replace
    PROP_PTR with a QOM link for example.
    
    Reviewed-by: Anthony Liguori <aliguori at us.ibm.com>
    Signed-off-by: Paolo Bonzini <pbonzini at redhat.com>
    Signed-off-by: Anthony Liguori <aliguori at us.ibm.com>

diff --git a/hw/qdev.c b/hw/qdev.c
index ee21d90..f5c716e 100644
--- a/hw/qdev.c
+++ b/hw/qdev.c
@@ -113,14 +113,14 @@ DeviceState *qdev_create(BusState *bus, const char *name)
     return dev;
 }
 
-DeviceState *qdev_try_create(BusState *bus, const char *name)
+DeviceState *qdev_try_create(BusState *bus, const char *type)
 {
     DeviceState *dev;
 
-    if (object_class_by_name(name) == NULL) {
+    if (object_class_by_name(type) == NULL) {
         return NULL;
     }
-    dev = DEVICE(object_new(name));
+    dev = DEVICE(object_new(type));
     if (!dev) {
         return NULL;
     }
@@ -152,6 +152,16 @@ int qdev_init(DeviceState *dev)
         qdev_free(dev);
         return rc;
     }
+
+    if (!OBJECT(dev)->parent) {
+        static int unattached_count = 0;
+        gchar *name = g_strdup_printf("device[%d]", unattached_count++);
+
+        object_property_add_child(container_get("/unattached"), name,
+                                  OBJECT(dev), NULL);
+        g_free(name);
+    }
+
     if (qdev_get_vmsd(dev)) {
         vmstate_register_with_alias_id(dev, -1, qdev_get_vmsd(dev), dev,
                                        dev->instance_id_alias,
commit f424d5c4c9de67b56594384eac3c08dc33de9344
Author: Paolo Bonzini <pbonzini at redhat.com>
Date:   Tue Mar 27 18:38:46 2012 +0200

    qdev: add children before qdev_init
    
    We want the composition tree to to be in order by the time we call
    qdev_init, so that a single set of the toplevel realize property can
    propagate all the way down the composition tree.
    
    This is not the case so far.  Unfortunately, this is incompatible
    with calling qdev_init in the constructor wrappers for devices,
    so for now we need to unattach some devices that are created through
    those wrappers.  This will be fixed by removing qdev_init and instead
    setting the toplevel realize property after machine init.
    
    Reviewed-by: Anthony Liguori <aliguori at us.ibm.com>
    Signed-off-by: Paolo Bonzini <pbonzini at redhat.com>
    Signed-off-by: Anthony Liguori <aliguori at us.ibm.com>

diff --git a/hw/pc_piix.c b/hw/pc_piix.c
index ec5118f..fadca4c 100644
--- a/hw/pc_piix.c
+++ b/hw/pc_piix.c
@@ -149,7 +149,6 @@ static void pc_init1(MemoryRegion *system_memory,
     MemoryRegion *ram_memory;
     MemoryRegion *pci_memory;
     MemoryRegion *rom_memory;
-    DeviceState *dev;
 
     pc_cpus_init(cpu_model);
 
@@ -227,11 +226,7 @@ static void pc_init1(MemoryRegion *system_memory,
 
     pc_register_ferr_irq(gsi[13]);
 
-    dev = pc_vga_init(isa_bus, pci_enabled ? pci_bus : NULL);
-    if (dev) {
-        object_property_add_child(object_get_root(), "vga", OBJECT(dev), NULL);
-    }
-
+    pc_vga_init(isa_bus, pci_enabled ? pci_bus : NULL);
     if (xen_enabled()) {
         pci_create_simple(pci_bus, -1, "xen-platform");
     }
@@ -258,17 +253,6 @@ static void pc_init1(MemoryRegion *system_memory,
         }
         idebus[0] = qdev_get_child_bus(&dev->qdev, "ide.0");
         idebus[1] = qdev_get_child_bus(&dev->qdev, "ide.1");
-
-        /* FIXME there's some major spaghetti here.  Somehow we create the
-         * devices on the PIIX before we actually create it.  We create the
-         * PIIX3 deep in the recess of the i440fx creation too and then lose
-         * the DeviceState.
-         *
-         * For now, let's "fix" this by making judicious use of paths.  This
-         * is not generally the right way to do this.
-         */
-        object_property_add_child(object_resolve_path("/i440fx/piix3", NULL),
-                                  "rtc", (Object *)rtc_state, NULL);
     } else {
         for(i = 0; i < MAX_IDE_BUS; i++) {
             ISADevice *dev;
diff --git a/hw/piix_pci.c b/hw/piix_pci.c
index e0268fe..9017565 100644
--- a/hw/piix_pci.c
+++ b/hw/piix_pci.c
@@ -276,8 +276,8 @@ static PCIBus *i440fx_common_init(const char *device_name,
     b = pci_bus_new(&s->busdev.qdev, NULL, pci_address_space,
                     address_space_io, 0);
     s->bus = b;
-    qdev_init_nofail(dev);
     object_property_add_child(object_get_root(), "i440fx", OBJECT(dev), NULL);
+    qdev_init_nofail(dev);
 
     d = pci_create_simple(b, 0, device_name);
     *pi440fx_state = DO_UPCAST(PCII440FXState, dev, d);
@@ -316,7 +316,6 @@ static PCIBus *i440fx_common_init(const char *device_name,
         pci_bus_irqs(b, piix3_set_irq, pci_slot_get_pirq, piix3,
                 PIIX_NUM_PIRQS);
     }
-    object_property_add_child(OBJECT(dev), "piix3", OBJECT(piix3), NULL);
     piix3->pic = pic;
     *isa_bus = DO_UPCAST(ISABus, qbus,
                          qdev_get_child_bus(&piix3->dev.qdev, "isa.0"));
diff --git a/hw/ppc_prep.c b/hw/ppc_prep.c
index 06d589d..86c9336 100644
--- a/hw/ppc_prep.c
+++ b/hw/ppc_prep.c
@@ -615,8 +615,8 @@ static void ppc_prep_init (ram_addr_t ram_size,
     sys = sysbus_from_qdev(dev);
     pcihost = DO_UPCAST(PCIHostState, busdev, sys);
     pcihost->address_space = get_system_memory();
-    qdev_init_nofail(dev);
     object_property_add_child(object_get_root(), "raven", OBJECT(dev), NULL);
+    qdev_init_nofail(dev);
     pci_bus = (PCIBus *)qdev_get_child_bus(dev, "pci.0");
     if (pci_bus == NULL) {
         fprintf(stderr, "Couldn't create PCI host controller.\n");
diff --git a/hw/qdev-monitor.c b/hw/qdev-monitor.c
index 2e82962..031cb83 100644
--- a/hw/qdev-monitor.c
+++ b/hw/qdev-monitor.c
@@ -458,10 +458,6 @@ DeviceState *qdev_device_add(QemuOpts *opts)
         qdev_free(qdev);
         return NULL;
     }
-    if (qdev_init(qdev) < 0) {
-        qerror_report(QERR_DEVICE_INIT_FAILED, driver);
-        return NULL;
-    }
     if (qdev->id) {
         object_property_add_child(qdev_get_peripheral(), qdev->id,
                                   OBJECT(qdev), NULL);
@@ -472,6 +468,10 @@ DeviceState *qdev_device_add(QemuOpts *opts)
                                   OBJECT(qdev), NULL);
         g_free(name);
     }        
+    if (qdev_init(qdev) < 0) {
+        qerror_report(QERR_DEVICE_INIT_FAILED, driver);
+        return NULL;
+    }
     qdev->opts = opts;
     return qdev;
 }
commit a612b2a6635fa1a3a29a8bcf41b31f1f3fae1110
Author: Paolo Bonzini <pbonzini at redhat.com>
Date:   Tue Mar 27 18:38:45 2012 +0200

    qom: add container_get
    
    This is QOM "mkdir -p".  It is useful when referring to
    container objects such as "/machine".
    
    Reviewed-by: Anthony Liguori <aliguori at us.ibm.com>
    Signed-off-by: Paolo Bonzini <pbonzini at redhat.com>
    Signed-off-by: Anthony Liguori <aliguori at us.ibm.com>

diff --git a/hw/qdev-monitor.c b/hw/qdev-monitor.c
index a310cc7..2e82962 100644
--- a/hw/qdev-monitor.c
+++ b/hw/qdev-monitor.c
@@ -180,9 +180,7 @@ static Object *qdev_get_peripheral(void)
     static Object *dev;
 
     if (dev == NULL) {
-        dev = object_new("container");
-        object_property_add_child(object_get_root(), "peripheral",
-                                  OBJECT(dev), NULL);
+        dev = container_get("/peripheral");
     }
 
     return dev;
@@ -193,9 +191,7 @@ static Object *qdev_get_peripheral_anon(void)
     static Object *dev;
 
     if (dev == NULL) {
-        dev = object_new("container");
-        object_property_add_child(object_get_root(), "peripheral-anon",
-                                  OBJECT(dev), NULL);
+        dev = container_get("/peripheral-anon");
     }
 
     return dev;
diff --git a/include/qemu/object.h b/include/qemu/object.h
index e8fc126..a675937 100644
--- a/include/qemu/object.h
+++ b/include/qemu/object.h
@@ -837,6 +837,18 @@ Object *object_resolve_path_type(const char *path, const char *typename,
                                  bool *ambiguous);
 
 /**
+ * object_resolve_path_component:
+ * @parent: the object in which to resolve the path
+ * @part: the component to resolve.
+ *
+ * This is similar to object_resolve_path with an absolute path, but it
+ * only resolves one element (@part) and takes the others from @parent.
+ *
+ * Returns: The resolved object or NULL on path lookup failure.
+ */
+Object *object_resolve_path_component(Object *parent, gchar *part);
+
+/**
  * object_property_add_child:
  * @obj: the object to add a property to
  * @name: the name of the property
@@ -891,4 +903,16 @@ void object_property_add_str(Object *obj, const char *name,
                              void (*set)(Object *, const char *, struct Error **),
                              struct Error **errp);
 
+/**
+ * container_get:
+ * @path: path to the container
+ *
+ * Return a container object whose path is @path.  Create more containers
+ * along the path if necessary.
+ *
+ * Returns: the container object.
+ */
+Object *container_get(const char *path);
+
+
 #endif
diff --git a/qom/container.c b/qom/container.c
index f107208..67e9e8a 100644
--- a/qom/container.c
+++ b/qom/container.c
@@ -12,6 +12,7 @@
 
 #include "qemu/object.h"
 #include "module.h"
+#include <assert.h>
 
 static TypeInfo container_info = {
     .name          = "container",
@@ -24,4 +25,26 @@ static void container_register_types(void)
     type_register_static(&container_info);
 }
 
+Object *container_get(const char *path)
+{
+    Object *obj, *child;
+    gchar **parts;
+    int i;
+
+    parts = g_strsplit(path, "/", 0);
+    assert(parts != NULL && parts[0] != NULL && !parts[0][0]);
+    obj = object_get_root();
+
+    for (i = 1; parts[i] != NULL; i++, obj = child) {
+        child = object_resolve_path_component(obj, parts[i]);
+        if (!child) {
+            child = object_new("container");
+            object_property_add_child(obj, parts[i], child, NULL);
+        }
+    }
+
+    return obj;
+}
+
+
 type_init(container_register_types)
diff --git a/qom/object.c b/qom/object.c
index 9cd9506..e721fc2 100644
--- a/qom/object.c
+++ b/qom/object.c
@@ -1022,12 +1022,27 @@ gchar *object_get_canonical_path(Object *obj)
     return newpath;
 }
 
+Object *object_resolve_path_component(Object *parent, gchar *part)
+{
+    ObjectProperty *prop = object_property_find(parent, part);
+    if (prop == NULL) {
+        return NULL;
+    }
+
+    if (strstart(prop->type, "link<", NULL)) {
+        return *(Object **)prop->opaque;
+    } else if (strstart(prop->type, "child<", NULL)) {
+        return prop->opaque;
+    } else {
+        return NULL;
+    }
+}
+
 static Object *object_resolve_abs_path(Object *parent,
                                           gchar **parts,
                                           const char *typename,
                                           int index)
 {
-    ObjectProperty *prop;
     Object *child;
 
     if (parts[index] == NULL) {
@@ -1038,21 +1053,7 @@ static Object *object_resolve_abs_path(Object *parent,
         return object_resolve_abs_path(parent, parts, typename, index + 1);
     }
 
-    prop = object_property_find(parent, parts[index]);
-    if (prop == NULL) {
-        return NULL;
-    }
-
-    child = NULL;
-    if (strstart(prop->type, "link<", NULL)) {
-        Object **pchild = prop->opaque;
-        if (*pchild) {
-            child = *pchild;
-        }
-    } else if (strstart(prop->type, "child<", NULL)) {
-        child = prop->opaque;
-    }
-
+    child = object_resolve_path_component(parent, parts[index]);
     if (!child) {
         return NULL;
     }
commit cefc898806e0346eef87d15ddaac9475b57b7d84
Merge: aba8e41... 8607301...
Author: Anthony Liguori <aliguori at us.ibm.com>
Date:   Mon Apr 2 09:46:45 2012 -0500

    Merge remote-tracking branch 'kiszka/queues/slirp' into staging
    
    * kiszka/queues/slirp:
      slirp: Signal free input buffer space to io-thread
      w32/slirp: Undefine error constants before their redefinition
      slirp: use socket_set_nonblock
      slirp: clean up conflicts with system headers

commit aba8e41e8666e4c0287cef1f6298985d4e03211d
Merge: dfe844c... 703e01e...
Author: Anthony Liguori <aliguori at us.ibm.com>
Date:   Mon Apr 2 09:44:35 2012 -0500

    Merge remote-tracking branch 'stefanha/tracing' into staging
    
    * stefanha/tracing:
      tracetool: dtrace: handle in and next reserved words
      tracetool: dtrace disabled-events fix
      Makefile.target: code stp dependency on trace-events

commit dfe844c9043815497b6472bfaf470b0f8d2e7312
Author: Anthony Liguori <aliguori at us.ibm.com>
Date:   Sun Apr 1 14:18:30 2012 -0500

    serial: clear LSR.TEMT when populating the TSR
    
    We never actually clear the TEMT (transmit sending register empty) flag when
    populating the TSR.  We set the flag, but since it's never cleared, setting it
    is sort of pointless..
    
    I found this with a unit test case.
    
    Signed-off-by: Anthony Liguori <aliguori at us.ibm.com>

diff --git a/hw/serial.c b/hw/serial.c
index b499bca..a421d1e 100644
--- a/hw/serial.c
+++ b/hw/serial.c
@@ -332,6 +332,7 @@ static void serial_xmit(void *opaque)
         } else {
             s->tsr = s->thr;
             s->lsr |= UART_LSR_THRE;
+            s->lsr &= ~UART_LSR_TEMT;
         }
     }
 
commit 67c5322d7000fd105a926eec44bc1765b7d70bdd
Author: Anthony Liguori <aliguori at us.ibm.com>
Date:   Sun Apr 1 14:03:21 2012 -0500

    serial: fix retry logic
    
    I'm not sure if the retry logic has ever worked when not using FIFO mode.  I
    found this while writing a test case although code inspection confirms it is
    definitely broken.
    
    The TSR retry logic will never actually happen because it is guarded by an
    'if (s->tsr_rety > 0)' but this is the only place that can ever make the
    variable greater than zero.  That effectively makes the retry logic an 'if (0)'.
    
    I believe this is a typo and the intention was >= 0.  Once this is fixed though,
    I see double transmits with my test case.  This is because in the non FIFO
    case, serial_xmit may get invoked while LSR.THRE is still high because the
    character was processed but the retransmit timer was still active.
    
    We can handle this by simply checking for LSR.THRE and returning early.  It's
    possible that the FIFO paths also need some attention.
    
    Cc: Stefano Stabellini <stefano.stabellini at eu.citrix.com>
    Signed-off-by: Anthony Liguori <aliguori at us.ibm.com>

diff --git a/hw/serial.c b/hw/serial.c
index c0ee55d..b499bca 100644
--- a/hw/serial.c
+++ b/hw/serial.c
@@ -327,6 +327,8 @@ static void serial_xmit(void *opaque)
             s->tsr = fifo_get(s,XMIT_FIFO);
             if (!s->xmit_fifo.count)
                 s->lsr |= UART_LSR_THRE;
+        } else if ((s->lsr & UART_LSR_THRE)) {
+            return;
         } else {
             s->tsr = s->thr;
             s->lsr |= UART_LSR_THRE;
@@ -337,7 +339,7 @@ static void serial_xmit(void *opaque)
         /* in loopback mode, say that we just received a char */
         serial_receive1(s, &s->tsr, 1);
     } else if (qemu_chr_fe_write(s->chr, &s->tsr, 1) != 1) {
-        if ((s->tsr_retry > 0) && (s->tsr_retry <= MAX_XMIT_RETRY)) {
+        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);
             return;
commit 6e92466a7c16bc5a33a674b76964f4b1ac7fa44d
Author: Anthony Liguori <aliguori at us.ibm.com>
Date:   Fri Mar 30 14:04:04 2012 -0500

    qtest: use qemu_gettimeofday()
    
    On linux, qemu_timeval will always be two long ints.  On windows, we use our
    own struct definition.  This should fix win64.
    
    Signed-of