[Spice-commits] 173 commits - MAINTAINERS Makefile.target arm-semi.c audio/coreaudio.c block-migration.c block/qcow2.c block/sheepdog.c blockdev.c bsd-user/main.c cmd.c configure console.c cpu-all.h cpu-common.h cpu-exec.c cpus.c darwin-user/main.c disas.c error.c error.h exec-all.h exec.c gdbstub.c hw/9pfs hw/ac97.c hw/acpi_piix4.c hw/apb_pci.c hw/armv7m.c hw/bonito.c hw/cirrus_vga.c hw/dec_pci.c hw/e1000.c hw/eepro100.c hw/es1370.c hw/grackle_pci.c hw/gt64xxx.c hw/hw.h hw/ide hw/intel-hda.c hw/ioh3420.c hw/ivshmem.c hw/kvmclock.c hw/kvmclock.h hw/lm32_sys.c hw/lm32_timer.c hw/lm32_uart.c hw/lsi53c895a.c hw/milkymist-ac97.c hw/milkymist-memcard.c hw/milkymist-minimac2.c hw/milkymist-pfpu.c hw/milkymist-softusb.c hw/milkymist-sysctl.c hw/milkymist-tmu2.c hw/msi.c hw/msix.c hw/ne2000.c hw/pc.h hw/pc_piix.c hw/pci.c hw/pci.h hw/pci_ids.h hw/pci_regs.h hw/pcie_aer.c hw/pcnet-pci.c hw/piix4.c hw/piix_pci.c hw/ppce500_pci.c hw/qdev.c hw/qxl.c hw/rtl8139.c hw/sh7750.c hw/sh_pci.c hw/spapr _hcall.c hw/strongarm.c hw/sun4u.c hw/syborg_virtio.c hw/unin_pci.c hw/usb-bus.c hw/usb-ccid.c hw/usb-desc.c hw/usb-ehci.c hw/usb-msd.c hw/usb-ohci.c hw/usb-uhci.c hw/usb.h hw/versatile_pci.c hw/vga-pci.c hw/vga.c hw/vhost_net.c hw/virtio-pci.c hw/virtio-pci.h hw/virtio-serial-bus.c hw/virtio.c hw/virtio.h hw/vmware_vga.c hw/vt82c686.c hw/wdt_i6300esb.c hw/xen_common.h hw/xen_platform.c hw/xio3130_downstream.c hw/xio3130_upstream.c kvm-all.c kvm-stub.c kvm.h linux-headers/COPYING linux-headers/README linux-headers/asm-powerpc linux-headers/asm-s390 linux-headers/asm-x86 linux-headers/linux linux-user/elfload.c linux-user/flatload.c linux-user/linuxload.c linux-user/main.c linux-user/qemu.h linux-user/signal.c linux-user/syscall.c m68k-semi.c monitor.c net.c net.h net/socket.c qemu-common.h qemu-error.c qemu-img.c savevm.c scripts/get_maintainer.pl scripts/update-linux-headers.sh sysemu.h target-alpha/cpu.h target-alpha/exec.h target-alpha/helper.c target-alpha/op_helper.c ta rget-alpha/translate.c target-arm/cpu.h target-arm/exec.h target-arm/helper.c target-arm/op_helper.c target-arm/translate.c target-cris/cpu.h target-cris/exec.h target-cris/helper.c target-cris/mmu.c target-cris/op_helper.c target-cris/translate.c target-cris/translate_v10.c target-i386/cpu.h target-i386/cpuid.c target-i386/exec.h target-i386/helper.c target-i386/kvm.c target-i386/machine.c target-i386/op_helper.c target-i386/translate.c target-lm32/cpu.h target-lm32/exec.h target-lm32/helper.c target-lm32/op_helper.c target-lm32/translate.c target-m68k/cpu.h target-m68k/exec.h target-m68k/helper.c target-m68k/op_helper.c target-m68k/translate.c target-microblaze/cpu.h target-microblaze/exec.h target-microblaze/helper.c target-microblaze/mmu.c target-microblaze/op_helper.c target-microblaze/translate.c target-mips/cpu.h target-mips/exec.h target-mips/helper.c target-mips/machine.c target-mips/op_helper.c target-mips/translate.c target-ppc/cpu.h target-ppc/exec.h target-ppc/h elper.c target-ppc/kvm.c target-ppc/op_helper.c target-ppc/translate.c target-s390x/cpu.h target-s390x/exec.h target-s390x/helper.c target-s390x/op_helper.c target-s390x/translate.c target-sh4/cpu.h target-sh4/exec.h target-sh4/helper.c target-sh4/op_helper.c target-sh4/translate.c target-sparc/cpu.h target-sparc/exec.h target-sparc/helper.c target-sparc/machine.c target-sparc/op_helper.c target-sparc/translate.c target-unicore32/cpu.h target-unicore32/exec.h target-unicore32/helper.c target-unicore32/op_helper.c target-unicore32/translate.c tcg/arm tcg/hppa tcg/i386 tcg/ia64 tcg/mips tcg/ppc tcg/ppc64 tcg/s390 tcg/sparc tcg/tcg.c tcg/tcg.h trace-events translate-all.c ui/vnc-enc-tight.c usb-bsd.c usb-linux.c user-exec.c vl.c xen-all.c xen-mapcache-stub.c xen-mapcache.c xen-mapcache.h

Gerd Hoffmann kraxel at kemper.freedesktop.org
Wed Jun 29 02:45:33 PDT 2011


 MAINTAINERS                          |    2 
 Makefile.target                      |   14 
 arm-semi.c                           |    5 
 audio/coreaudio.c                    |    6 
 block-migration.c                    |    2 
 block/qcow2.c                        |    2 
 block/sheepdog.c                     |   90 -
 blockdev.c                           |    2 
 bsd-user/main.c                      |    4 
 cmd.c                                |    6 
 configure                            |  184 --
 console.c                            |    9 
 cpu-all.h                            |    2 
 cpu-common.h                         |    1 
 cpu-exec.c                           |  150 --
 cpus.c                               |    6 
 darwin-user/main.c                   |    2 
 disas.c                              |    1 
 error.c                              |    3 
 error.h                              |    3 
 exec-all.h                           |    3 
 exec.c                               |  138 +-
 gdbstub.c                            |    2 
 hw/9pfs/virtio-9p-device.c           |   10 
 hw/ac97.c                            |    9 
 hw/acpi_piix4.c                      |    8 
 hw/apb_pci.c                         |   13 
 hw/armv7m.c                          |    4 
 hw/bonito.c                          |    9 
 hw/cirrus_vga.c                      |   15 
 hw/dec_pci.c                         |   26 
 hw/e1000.c                           |    8 
 hw/eepro100.c                        |   74 -
 hw/es1370.c                          |   24 
 hw/grackle_pci.c                     |    8 
 hw/gt64xxx.c                         |    8 
 hw/hw.h                              |    3 
 hw/ide/cmd646.c                      |   10 
 hw/ide/ich.c                         |   11 
 hw/ide/piix.c                        |   32 
 hw/ide/via.c                         |    8 
 hw/intel-hda.c                       |    8 
 hw/ioh3420.c                         |    7 
 hw/ivshmem.c                         |    8 
 hw/kvmclock.c                        |    9 
 hw/kvmclock.h                        |   10 
 hw/lm32_sys.c                        |    2 
 hw/lm32_timer.c                      |    4 
 hw/lm32_uart.c                       |    4 
 hw/lsi53c895a.c                      |   15 
 hw/milkymist-ac97.c                  |    4 
 hw/milkymist-memcard.c               |    4 
 hw/milkymist-minimac2.c              |    6 
 hw/milkymist-pfpu.c                  |    4 
 hw/milkymist-softusb.c               |    8 
 hw/milkymist-sysctl.c                |    4 
 hw/milkymist-tmu2.c                  |    8 
 hw/msi.c                             |    2 
 hw/msix.c                            |   40 
 hw/ne2000.c                          |    6 
 hw/pc.h                              |    1 
 hw/pc_piix.c                         |   58 
 hw/pci.c                             |   56 
 hw/pci.h                             |    7 
 hw/pci_ids.h                         |    2 
 hw/pci_regs.h                        |   60 
 hw/pcie_aer.c                        |    9 
 hw/pcnet-pci.c                       |    8 
 hw/piix4.c                           |   10 
 hw/piix_pci.c                        |   85 -
 hw/ppce500_pci.c                     |   13 
 hw/qdev.c                            |    3 
 hw/qxl.c                             |    7 
 hw/rtl8139.c                         |    8 
 hw/sh7750.c                          |    1 
 hw/sh_pci.c                          |    4 
 hw/spapr_hcall.c                     |    1 
 hw/strongarm.c                       |    4 
 hw/sun4u.c                           |    8 
 hw/syborg_virtio.c                   |    4 
 hw/unin_pci.c                        |   33 
 hw/usb-bus.c                         |   31 
 hw/usb-ccid.c                        |    3 
 hw/usb-desc.c                        |   14 
 hw/usb-ehci.c                        |   52 
 hw/usb-msd.c                         |   19 
 hw/usb-ohci.c                        |   24 
 hw/usb-uhci.c                        |   46 
 hw/usb.h                             |    4 
 hw/versatile_pci.c                   |    8 
 hw/vga-pci.c                         |   11 
 hw/vga.c                             |   13 
 hw/vhost_net.c                       |    8 
 hw/virtio-pci.c                      |   66 -
 hw/virtio-pci.h                      |    8 
 hw/virtio-serial-bus.c               |   34 
 hw/virtio.c                          |  101 +
 hw/virtio.h                          |    9 
 hw/vmware_vga.c                      |   13 
 hw/vt82c686.c                        |   35 
 hw/wdt_i6300esb.c                    |    9 
 hw/xen_common.h                      |   14 
 hw/xen_platform.c                    |  340 +++++
 hw/xio3130_downstream.c              |    6 
 hw/xio3130_upstream.c                |    6 
 kvm-all.c                            |   13 
 kvm-stub.c                           |   20 
 kvm.h                                |    2 
 linux-headers/COPYING                |  356 +++++
 linux-headers/README                 |    2 
 linux-headers/asm-powerpc/kvm.h      |  275 ++++
 linux-headers/asm-powerpc/kvm_para.h |   53 
 linux-headers/asm-s390/kvm.h         |   44 
 linux-headers/asm-s390/kvm_para.h    |   17 
 linux-headers/asm-x86/hyperv.h       |  193 +++
 linux-headers/asm-x86/kvm.h          |  324 +++++
 linux-headers/asm-x86/kvm_para.h     |   79 +
 linux-headers/linux/kvm.h            |  804 +++++++++++++
 linux-headers/linux/kvm_para.h       |   28 
 linux-headers/linux/vhost.h          |  130 ++
 linux-headers/linux/virtio_config.h  |   54 
 linux-headers/linux/virtio_ring.h    |  163 ++
 linux-user/elfload.c                 |  185 +--
 linux-user/flatload.c                |    8 
 linux-user/linuxload.c               |   25 
 linux-user/main.c                    |   42 
 linux-user/qemu.h                    |    3 
 linux-user/signal.c                  |   21 
 linux-user/syscall.c                 |  240 +++
 m68k-semi.c                          |    5 
 monitor.c                            |    2 
 net.c                                |   44 
 net.h                                |    3 
 net/socket.c                         |    6 
 qemu-common.h                        |    5 
 qemu-error.c                         |    2 
 qemu-img.c                           |   12 
 savevm.c                             |    1 
 scripts/get_maintainer.pl            | 2149 +++++++++++++++++++++++++++++++++++
 scripts/update-linux-headers.sh      |   55 
 sysemu.h                             |    5 
 target-alpha/cpu.h                   |   22 
 target-alpha/exec.h                  |   21 
 target-alpha/helper.c                |    1 
 target-alpha/op_helper.c             |    6 
 target-alpha/translate.c             |   11 
 target-arm/cpu.h                     |   13 
 target-arm/exec.h                    |   13 
 target-arm/helper.c                  |    1 
 target-arm/op_helper.c               |    6 
 target-arm/translate.c               |    1 
 target-cris/cpu.h                    |   11 
 target-cris/exec.h                   |   12 
 target-cris/helper.c                 |    1 
 target-cris/mmu.c                    |    1 
 target-cris/op_helper.c              |    4 
 target-cris/translate.c              |    1 
 target-cris/translate_v10.c          |    3 
 target-i386/cpu.h                    |   61 
 target-i386/cpuid.c                  |   20 
 target-i386/exec.h                   |   57 
 target-i386/helper.c                 |    1 
 target-i386/kvm.c                    |  148 --
 target-i386/machine.c                |   25 
 target-i386/op_helper.c              |  106 +
 target-i386/translate.c              |    1 
 target-lm32/cpu.h                    |   13 
 target-lm32/exec.h                   |   12 
 target-lm32/helper.c                 |    1 
 target-lm32/op_helper.c              |    6 
 target-lm32/translate.c              |    1 
 target-m68k/cpu.h                    |   15 
 target-m68k/exec.h                   |   12 
 target-m68k/helper.c                 |    1 
 target-m68k/op_helper.c              |   35 
 target-m68k/translate.c              |    1 
 target-microblaze/cpu.h              |   13 
 target-microblaze/exec.h             |   12 
 target-microblaze/helper.c           |    1 
 target-microblaze/mmu.c              |    1 
 target-microblaze/op_helper.c        |    4 
 target-microblaze/translate.c        |    1 
 target-mips/cpu.h                    |   24 
 target-mips/exec.h                   |   23 
 target-mips/helper.c                 |    1 
 target-mips/machine.c                |    2 
 target-mips/op_helper.c              |    4 
 target-mips/translate.c              |    1 
 target-ppc/cpu.h                     |   12 
 target-ppc/exec.h                    |   12 
 target-ppc/helper.c                  |    1 
 target-ppc/kvm.c                     |   23 
 target-ppc/op_helper.c               |    2 
 target-ppc/translate.c               |    1 
 target-s390x/cpu.h                   |   21 
 target-s390x/exec.h                  |   13 
 target-s390x/helper.c                |    1 
 target-s390x/op_helper.c             |   17 
 target-s390x/translate.c             |    1 
 target-sh4/cpu.h                     |   13 
 target-sh4/exec.h                    |   12 
 target-sh4/helper.c                  |    1 
 target-sh4/op_helper.c               |   10 
 target-sh4/translate.c               |    1 
 target-sparc/cpu.h                   |   22 
 target-sparc/exec.h                  |   16 
 target-sparc/helper.c                |  243 +++
 target-sparc/machine.c               |   28 
 target-sparc/op_helper.c             |  279 ----
 target-sparc/translate.c             |    1 
 target-unicore32/cpu.h               |    6 
 target-unicore32/exec.h              |    7 
 target-unicore32/helper.c            |    1 
 target-unicore32/op_helper.c         |    2 
 target-unicore32/translate.c         |    1 
 tcg/arm/tcg-target.c                 |   19 
 tcg/hppa/tcg-target.c                |    8 
 tcg/i386/tcg-target.c                |   32 
 tcg/ia64/tcg-target.c                |    7 
 tcg/mips/tcg-target.c                |   10 
 tcg/ppc/tcg-target.c                 |   13 
 tcg/ppc64/tcg-target.c               |   13 
 tcg/s390/tcg-target.c                |    7 
 tcg/sparc/tcg-target.c               |    9 
 tcg/tcg.c                            |   22 
 tcg/tcg.h                            |    7 
 trace-events                         |    4 
 translate-all.c                      |    3 
 ui/vnc-enc-tight.c                   |   10 
 usb-bsd.c                            |    2 
 usb-linux.c                          |  124 +-
 user-exec.c                          |   11 
 vl.c                                 |   10 
 xen-all.c                            |  283 ++++
 xen-mapcache-stub.c                  |   10 
 xen-mapcache.c                       |  141 +-
 xen-mapcache.h                       |   16 
 237 files changed, 7827 insertions(+), 2108 deletions(-)

New commits:
commit 1dfdcaa83f9ce34aded8bc0669e81753d94f1b7d
Author: Edgar E. Iglesias <edgar.iglesias at gmail.com>
Date:   Tue Jun 28 20:57:09 2011 +0200

    user: Fix -d debug logging for usermode emulation
    
    Signed-off-by: Edgar E. Iglesias <edgar.iglesias at gmail.com>

diff --git a/bsd-user/main.c b/bsd-user/main.c
index 5f790b2..6018a41 100644
--- a/bsd-user/main.c
+++ b/bsd-user/main.c
@@ -866,7 +866,7 @@ int main(int argc, char **argv)
         int mask;
         const CPULogItem *item;
 
-        mask = cpu_str_to_log_mask(r);
+        mask = cpu_str_to_log_mask(log_mask);
         if (!mask) {
             printf("Log items (comma separated):\n");
             for (item = cpu_log_items; item->mask != 0; item++) {
diff --git a/darwin-user/main.c b/darwin-user/main.c
index a6dc859..35196a1 100644
--- a/darwin-user/main.c
+++ b/darwin-user/main.c
@@ -819,7 +819,7 @@ int main(int argc, char **argv)
         int mask;
         CPULogItem *item;
 
-        mask = cpu_str_to_log_mask(r);
+        mask = cpu_str_to_log_mask(log_mask);
         if (!mask) {
             printf("Log items (comma separated):\n");
             for (item = cpu_log_items; item->mask != 0; item++) {
diff --git a/linux-user/main.c b/linux-user/main.c
index db5577b..289054b 100644
--- a/linux-user/main.c
+++ b/linux-user/main.c
@@ -3030,7 +3030,7 @@ int main(int argc, char **argv, char **envp)
         int mask;
         const CPULogItem *item;
 
-        mask = cpu_str_to_log_mask(r);
+        mask = cpu_str_to_log_mask(log_mask);
         if (!mask) {
             printf("Log items (comma separated):\n");
             for (item = cpu_log_items; item->mask != 0; item++) {
commit 3ab20e206ce74299e836bfec5ec27b7f261826be
Author: Edgar E. Iglesias <edgar.iglesias at gmail.com>
Date:   Tue Jun 28 20:52:37 2011 +0200

    cris: Handle opcode zero
    
    It's a valid branch pc + 2.
    
    Signed-off-by: Edgar E. Iglesias <edgar.iglesias at gmail.com>

diff --git a/target-cris/translate_v10.c b/target-cris/translate_v10.c
index 5b14157..637ac20 100644
--- a/target-cris/translate_v10.c
+++ b/target-cris/translate_v10.c
@@ -262,9 +262,6 @@ static unsigned int dec10_quick_imm(DisasContext *dc)
             break;
 
         case CRISV10_QIMM_BCC_R0:
-            if (!dc->ir) {
-                cpu_abort(dc->env, "opcode zero\n");
-            }
         case CRISV10_QIMM_BCC_R1:
         case CRISV10_QIMM_BCC_R2:
         case CRISV10_QIMM_BCC_R3:
commit c24a9c6ef946ec1b5b280061d4f7b579aaac6707
Author: malc <av1474 at comtv.ru>
Date:   Tue Jun 28 02:27:52 2011 +0400

    tcg/ppc64: Remove tcg_out_addi
    
    The only user (within tcg.c) was removed
    
    Signed-off-by: malc <av1474 at comtv.ru>

diff --git a/tcg/ppc64/tcg-target.c b/tcg/ppc64/tcg-target.c
index 3218438..065c710 100644
--- a/tcg/ppc64/tcg-target.c
+++ b/tcg/ppc64/tcg-target.c
@@ -968,11 +968,6 @@ static void ppc_addi64 (TCGContext *s, int rt, int ra, tcg_target_long si)
     }
 }
 
-static void tcg_out_addi (TCGContext *s, int reg, tcg_target_long val)
-{
-    ppc_addi64 (s, reg, reg, val);
-}
-
 static void tcg_out_cmp (TCGContext *s, int cond, TCGArg arg1, TCGArg arg2,
                          int const_arg2, int cr, int arch64)
 {
commit 1a2eb1624140b674987f2d82d990ad8af5904ad9
Author: malc <av1474 at comtv.ru>
Date:   Tue Jun 28 02:26:06 2011 +0400

    tcg/ppc: Remove tcg_out_addi
    
    The only user (within tcg.c) was removed
    
    Signed-off-by: malc <av1474 at comtv.ru>

diff --git a/tcg/ppc/tcg-target.c b/tcg/ppc/tcg-target.c
index dde4e18..0cd8873 100644
--- a/tcg/ppc/tcg-target.c
+++ b/tcg/ppc/tcg-target.c
@@ -982,11 +982,6 @@ static void ppc_addi (TCGContext *s, int rt, int ra, tcg_target_long si)
     }
 }
 
-static void tcg_out_addi(TCGContext *s, int reg, tcg_target_long val)
-{
-    ppc_addi (s, reg, reg, val);
-}
-
 static void tcg_out_cmp (TCGContext *s, int cond, TCGArg arg1, TCGArg arg2,
                          int const_arg2, int cr)
 {
commit 656acddb39ee924b843df7f57d4c1798e49be058
Merge: c45d1fc... a7fb71d...
Author: Anthony Liguori <aliguori at us.ibm.com>
Date:   Mon Jun 27 14:59:08 2011 -0500

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

commit c45d1fc191bba333086f066247dd6096175db0da
Merge: cd59dd8... d2e4d08...
Author: Anthony Liguori <aliguori at us.ibm.com>
Date:   Mon Jun 27 11:27:15 2011 -0500

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

diff --cc hw/virtio-serial-bus.c
index bff4004,7cedf18..7f6db7b
--- a/hw/virtio-serial-bus.c
+++ b/hw/virtio-serial-bus.c
@@@ -328,18 -328,11 +328,11 @@@ static void handle_control_message(Virt
      cpkt.event = lduw_p(&gcpkt->event);
      cpkt.value = lduw_p(&gcpkt->value);
  
-     port = find_port_by_id(vser, ldl_p(&gcpkt->id));
-     if (!port && cpkt.event != VIRTIO_CONSOLE_DEVICE_READY)
-         return;
- 
-     info = DO_UPCAST(VirtIOSerialPortInfo, qdev, port->dev.info);
- 
-     switch(cpkt.event) {
-     case VIRTIO_CONSOLE_DEVICE_READY:
+     if (cpkt.event == VIRTIO_CONSOLE_DEVICE_READY) {
          if (!cpkt.value) {
 -            error_report("virtio-serial-bus: Guest failure in adding device %s\n",
 +            error_report("virtio-serial-bus: Guest failure in adding device %s",
                           vser->bus.qbus.name);
-             break;
+             return;
          }
          /*
           * The device is up, we can now tell the device about all the
@@@ -348,11 -341,22 +341,22 @@@
          QTAILQ_FOREACH(port, &vser->ports, next) {
              send_control_event(port, VIRTIO_CONSOLE_PORT_ADD, 1);
          }
-         break;
+         return;
+     }
  
+     port = find_port_by_id(vser, ldl_p(&gcpkt->id));
+     if (!port) {
+         error_report("virtio-serial-bus: Unexpected port id %u for device %s\n",
+                      ldl_p(&gcpkt->id), vser->bus.qbus.name);
+         return;
+     }
+ 
+     info = DO_UPCAST(VirtIOSerialPortInfo, qdev, port->dev.info);
+ 
+     switch(cpkt.event) {
      case VIRTIO_CONSOLE_PORT_READY:
          if (!cpkt.value) {
 -            error_report("virtio-serial-bus: Guest failure in adding port %u for device %s\n",
 +            error_report("virtio-serial-bus: Guest failure in adding port %u for device %s",
                           port->id, vser->bus.qbus.name);
              break;
          }
commit cd59dd8734bebe5bd06be8a3fa79a9f4facf6633
Merge: bb820c0... bfcedc5...
Author: Anthony Liguori <aliguori at us.ibm.com>
Date:   Mon Jun 27 11:26:47 2011 -0500

    Merge remote-tracking branch 'riku/linux-user-for-upstream' into staging

commit bb820c03e2d638038fd48f42ee71e4004e55aba8
Merge: 2fb0c09... 20fa53e...
Author: Anthony Liguori <aliguori at us.ibm.com>
Date:   Mon Jun 27 11:25:23 2011 -0500

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

commit 2fb0c09f4ff036f68474277ed4edc036f6529de8
Author: Stefan Weil <weil at mail.berlios.de>
Date:   Sun Jun 26 19:29:13 2011 +0000

    vnc: Fix compilation with --enable-vnc-png
    
    Commit f26e428da505709ec03b2ed2c9eb3db82b30bd7b fixed compilation
    with --enable-vnc-png, but broke it with --enable-vnc-png.
    
    The breakage is caused by pngconfig.h which checks whether
    setjmp.h was already included and fails because qemu-common.h
    includes setjmp.h.
    
    The check is disabled by defining PNG_SKIP_SETJMP_CHECK.
    
    Cc: Blue Swirl <blauwirbel at gmail.com>
    Signed-off-by: Stefan Weil <weil at mail.berlios.de>
    Reviewed-by: Stefan Hajnoczi <stefanha at linux.vnet.ibm.com>
    Signed-off-by: Anthony Liguori <aliguori at us.ibm.com>

diff --git a/ui/vnc-enc-tight.c b/ui/vnc-enc-tight.c
index 6d36a7f..5c02803 100644
--- a/ui/vnc-enc-tight.c
+++ b/ui/vnc-enc-tight.c
@@ -34,6 +34,9 @@
 #include "qemu-common.h"
 
 #ifdef CONFIG_VNC_PNG
+/* The following define is needed by pngconf.h. Otherwise it won't compile,
+   because setjmp.h was already included by qemu-common.h. */
+#define PNG_SKIP_SETJMP_CHECK
 #include <png.h>
 #endif
 #ifdef CONFIG_VNC_JPEG
commit d2e4d08b3e02deb2d5824b17283c63c1354b7696
Author: Luiz Capitulino <lcapitulino at redhat.com>
Date:   Fri Jun 17 15:58:08 2011 -0300

    virtio-serial: Fix segfault on guest boot
    
    If I start qemu with:
    
      # qemu -hda disks/test.img -enable-kvm -m 1G -snapshot \
             -device virtio-serial \
             -chardev socket,host=localhost,port=1234,server,nowait,id=foo \
             -device virtserialport,chardev=foo,name=org.qemu.guest_agent
    
    I get a segfault when booting a Fedora 14 guest. The backtrace says:
    
      Program terminated with signal 11, Segmentation fault.
        #0  0x0000000000420850 in handle_control_message (vser=0x3732bd0, buf=0x2c173e0, len=8) at /home/lcapitulino/src/qmp-unstable/hw/virtio-serial-bus.c:335
        335     info = DO_UPCAST(VirtIOSerialPortInfo, qdev, port->dev.info);
    
    What's happening is VIRTIO_CONSOLE_DEVICE_READY is a message for the
    whole device, not for an individual port. So port is NULL. This bug was
    introduced by commit a15bb0d6a981de749452a5180fc8084d625671da.
    
    This commit fixes that by making the port returned by find_port_by_id()
    be used only by the VIRTIO_CONSOLE_PORT_READY and
    VIRTIO_CONSOLE_PORT_OPEN messages.
    
    Signed-off-by: Luiz Capitulino <lcapitulino at redhat.com>
    Reviewed-by: Markus Armbruster <armbru at redhat.com>
    Signed-off-by: Amit Shah <amit.shah at redhat.com>

diff --git a/hw/virtio-serial-bus.c b/hw/virtio-serial-bus.c
index 9a12104..7cedf18 100644
--- a/hw/virtio-serial-bus.c
+++ b/hw/virtio-serial-bus.c
@@ -328,18 +328,11 @@ static void handle_control_message(VirtIOSerial *vser, void *buf, size_t len)
     cpkt.event = lduw_p(&gcpkt->event);
     cpkt.value = lduw_p(&gcpkt->value);
 
-    port = find_port_by_id(vser, ldl_p(&gcpkt->id));
-    if (!port && cpkt.event != VIRTIO_CONSOLE_DEVICE_READY)
-        return;
-
-    info = DO_UPCAST(VirtIOSerialPortInfo, qdev, port->dev.info);
-
-    switch(cpkt.event) {
-    case VIRTIO_CONSOLE_DEVICE_READY:
+    if (cpkt.event == VIRTIO_CONSOLE_DEVICE_READY) {
         if (!cpkt.value) {
             error_report("virtio-serial-bus: Guest failure in adding device %s\n",
                          vser->bus.qbus.name);
-            break;
+            return;
         }
         /*
          * The device is up, we can now tell the device about all the
@@ -348,8 +341,19 @@ static void handle_control_message(VirtIOSerial *vser, void *buf, size_t len)
         QTAILQ_FOREACH(port, &vser->ports, next) {
             send_control_event(port, VIRTIO_CONSOLE_PORT_ADD, 1);
         }
-        break;
+        return;
+    }
 
+    port = find_port_by_id(vser, ldl_p(&gcpkt->id));
+    if (!port) {
+        error_report("virtio-serial-bus: Unexpected port id %u for device %s\n",
+                     ldl_p(&gcpkt->id), vser->bus.qbus.name);
+        return;
+    }
+
+    info = DO_UPCAST(VirtIOSerialPortInfo, qdev, port->dev.info);
+
+    switch(cpkt.event) {
     case VIRTIO_CONSOLE_PORT_READY:
         if (!cpkt.value) {
             error_report("virtio-serial-bus: Guest failure in adding port %u for device %s\n",
commit f26e428da505709ec03b2ed2c9eb3db82b30bd7b
Author: Roy Tam <roytam at gmail.com>
Date:   Sat Jun 18 13:13:39 2011 +0800

    Fix MinGW compilation when --enable-vnc-jpeg is specified
    
    Fix conflicting types for 'INT32' in basetsd.h and jmorecfg.h by
    including qemu-common.h first.
    
    Signed-off-by: Roy Tam <roytam at gmail.com>
    Acked-by: Stefan Weil <weil at mail.berlios.de>
    Signed-off-by: Blue Swirl <blauwirbel at gmail.com>

diff --git a/ui/vnc-enc-tight.c b/ui/vnc-enc-tight.c
index 87fdf35..6d36a7f 100644
--- a/ui/vnc-enc-tight.c
+++ b/ui/vnc-enc-tight.c
@@ -28,6 +28,11 @@
 
 #include "config-host.h"
 
+/* This needs to be before jpeglib.h line because of conflict with
+   INT32 definitions between jmorecfg.h (included by jpeglib.h) and
+   Win32 basetsd.h (included by windows.h). */
+#include "qemu-common.h"
+
 #ifdef CONFIG_VNC_PNG
 #include <png.h>
 #endif
@@ -36,8 +41,6 @@
 #include <jpeglib.h>
 #endif
 
-#include "qemu-common.h"
-
 #include "bswap.h"
 #include "qint.h"
 #include "vnc.h"
commit f44c99607a46484c52f03aed373e3a3a194af721
Author: Blue Swirl <blauwirbel at gmail.com>
Date:   Sat May 14 17:06:56 2011 +0000

    TCG/Sparc64: use stack for TCG temps
    
    Use stack instead of temp_buf array in CPUState for TCG temps.
    
    On Sparc64, stack pointer is not aligned but there is a fixed bias of 2047,
    so don't try to enforce alignment.
    
    Signed-off-by: Blue Swirl <blauwirbel at gmail.com>

diff --git a/tcg/sparc/tcg-target.c b/tcg/sparc/tcg-target.c
index 86f8c1e..ac76e11 100644
--- a/tcg/sparc/tcg-target.c
+++ b/tcg/sparc/tcg-target.c
@@ -693,8 +693,11 @@ static void tcg_out_setcond2_i32(TCGContext *s, TCGCond cond, TCGArg ret,
 /* Generate global QEMU prologue and epilogue code */
 static void tcg_target_qemu_prologue(TCGContext *s)
 {
+    tcg_set_frame(s, TCG_REG_I6, TCG_TARGET_CALL_STACK_OFFSET,
+                  CPU_TEMP_BUF_NLONGS * (int)sizeof(long));
     tcg_out32(s, SAVE | INSN_RD(TCG_REG_O6) | INSN_RS1(TCG_REG_O6) |
-              INSN_IMM13(-TCG_TARGET_STACK_MINFRAME));
+              INSN_IMM13(-(TCG_TARGET_STACK_MINFRAME +
+                           CPU_TEMP_BUF_NLONGS * (int)sizeof(long))));
     tcg_out32(s, JMPL | INSN_RD(TCG_REG_G0) | INSN_RS1(TCG_REG_I1) |
               INSN_RS2(TCG_REG_G0));
     tcg_out_mov(s, TCG_TYPE_PTR, TCG_AREG0, TCG_REG_I0);
@@ -1566,6 +1569,4 @@ static void tcg_target_init(TCGContext *s)
     tcg_regset_set_reg(s->reserved_regs, TCG_REG_O6);
     tcg_regset_set_reg(s->reserved_regs, TCG_REG_O7);
     tcg_add_target_add_op_defs(sparc_op_defs);
-    tcg_set_frame(s, TCG_AREG0, offsetof(CPUState, temp_buf),
-                  CPU_TEMP_BUF_NLONGS * sizeof(long));
 }
diff --git a/tcg/tcg.c b/tcg/tcg.c
index 29cd7a2..c05413b 100644
--- a/tcg/tcg.c
+++ b/tcg/tcg.c
@@ -1439,9 +1439,11 @@ static void temp_allocate_frame(TCGContext *s, int temp)
 {
     TCGTemp *ts;
     ts = &s->temps[temp];
+#ifndef __sparc_v9__ /* Sparc64 stack is accessed with offset of 2047 */
     s->current_frame_offset = (s->current_frame_offset +
                                (tcg_target_long)sizeof(tcg_target_long) - 1) &
         ~(sizeof(tcg_target_long) - 1);
+#endif
     if (s->current_frame_offset + (tcg_target_long)sizeof(tcg_target_long) >
         s->frame_end) {
         tcg_abort();
commit ac0275dcfea6ec21705b30fe83c21686871e9d70
Author: Blue Swirl <blauwirbel at gmail.com>
Date:   Sat May 14 13:14:45 2011 +0000

    TCG/x86: use stack for TCG temps
    
    Use stack instead of temp_buf array in CPUState for TCG
    temps.
    
    Signed-off-by: Blue Swirl <blauwirbel at gmail.com>

diff --git a/tcg/i386/tcg-target.c b/tcg/i386/tcg-target.c
index 4c29ced..7529677 100644
--- a/tcg/i386/tcg-target.c
+++ b/tcg/i386/tcg-target.c
@@ -1918,20 +1918,24 @@ static void tcg_target_qemu_prologue(TCGContext *s)
 
     /* TB prologue */
 
-    /* Save all callee saved registers.  */
-    for (i = 0; i < ARRAY_SIZE(tcg_target_callee_save_regs); i++) {
-        tcg_out_push(s, tcg_target_callee_save_regs[i]);
-    }
-
-    /* Reserve some stack space.  */
+    /* Reserve some stack space, also for TCG temps.  */
     push_size = 1 + ARRAY_SIZE(tcg_target_callee_save_regs);
     push_size *= TCG_TARGET_REG_BITS / 8;
 
-    frame_size = push_size + TCG_STATIC_CALL_ARGS_SIZE;
+    frame_size = push_size + TCG_STATIC_CALL_ARGS_SIZE +
+        CPU_TEMP_BUF_NLONGS * sizeof(long);
     frame_size = (frame_size + TCG_TARGET_STACK_ALIGN - 1) &
         ~(TCG_TARGET_STACK_ALIGN - 1);
     stack_addend = frame_size - push_size;
-    tcg_out_addi(s, TCG_REG_CALL_STACK, -stack_addend);
+    tcg_set_frame(s, TCG_REG_CALL_STACK, TCG_STATIC_CALL_ARGS_SIZE,
+                  CPU_TEMP_BUF_NLONGS * sizeof(long));
+
+    /* Save all callee saved registers.  */
+    for (i = 0; i < ARRAY_SIZE(tcg_target_callee_save_regs); i++) {
+        tcg_out_push(s, tcg_target_callee_save_regs[i]);
+    }
+
+    tcg_out_addi(s, TCG_REG_ESP, -stack_addend);
 
     tcg_out_mov(s, TCG_TYPE_PTR, TCG_AREG0, tcg_target_call_iarg_regs[0]);
 
@@ -1981,6 +1985,4 @@ static void tcg_target_init(TCGContext *s)
     tcg_regset_set_reg(s->reserved_regs, TCG_REG_CALL_STACK);
 
     tcg_add_target_add_op_defs(x86_op_defs);
-    tcg_set_frame(s, TCG_AREG0, offsetof(CPUState, temp_buf),
-                  CPU_TEMP_BUF_NLONGS * sizeof(long));
 }
commit e83c80f7180fc70570c2592ee5af5835e2a6942b
Author: Blue Swirl <blauwirbel at gmail.com>
Date:   Sat May 28 06:51:52 2011 +0000

    TCG/x86: use TCG_REG_CALL_STACK instead of TCG_REG_ESP
    
    Except for specific cases where the use of %esp changes the encoding of
    the instruction, it's cleaner to use TCG_REG_CALL_STACK instead of
    TCG_REG_ESP.
    
    Signed-off-by: Blue Swirl <blauwirbel at gmail.com>

diff --git a/tcg/i386/tcg-target.c b/tcg/i386/tcg-target.c
index 3ff9105..4c29ced 100644
--- a/tcg/i386/tcg-target.c
+++ b/tcg/i386/tcg-target.c
@@ -1398,7 +1398,7 @@ static void tcg_out_qemu_st(TCGContext *s, const TCGArg *args,
         /* Pop and discard.  This is 2 bytes smaller than the add.  */
         tcg_out_pop(s, TCG_REG_ECX);
     } else if (stack_adjust != 0) {
-        tcg_out_addi(s, TCG_REG_ESP, stack_adjust);
+        tcg_out_addi(s, TCG_REG_CALL_STACK, stack_adjust);
     }
 
     /* label2: */
@@ -1931,7 +1931,7 @@ static void tcg_target_qemu_prologue(TCGContext *s)
     frame_size = (frame_size + TCG_TARGET_STACK_ALIGN - 1) &
         ~(TCG_TARGET_STACK_ALIGN - 1);
     stack_addend = frame_size - push_size;
-    tcg_out_addi(s, TCG_REG_ESP, -stack_addend);
+    tcg_out_addi(s, TCG_REG_CALL_STACK, -stack_addend);
 
     tcg_out_mov(s, TCG_TYPE_PTR, TCG_AREG0, tcg_target_call_iarg_regs[0]);
 
@@ -1941,7 +1941,7 @@ static void tcg_target_qemu_prologue(TCGContext *s)
     /* TB epilogue */
     tb_ret_addr = s->code_ptr;
 
-    tcg_out_addi(s, TCG_REG_ESP, stack_addend);
+    tcg_out_addi(s, TCG_REG_CALL_STACK, stack_addend);
 
     for (i = ARRAY_SIZE(tcg_target_callee_save_regs) - 1; i >= 0; i--) {
         tcg_out_pop(s, tcg_target_callee_save_regs[i]);
@@ -1978,7 +1978,7 @@ static void tcg_target_init(TCGContext *s)
     }
 
     tcg_regset_clear(s->reserved_regs);
-    tcg_regset_set_reg(s->reserved_regs, TCG_REG_ESP);
+    tcg_regset_set_reg(s->reserved_regs, TCG_REG_CALL_STACK);
 
     tcg_add_target_add_op_defs(x86_op_defs);
     tcg_set_frame(s, TCG_AREG0, offsetof(CPUState, temp_buf),
commit 345649c054648ce5812bb2b247969d188dcb0f87
Author: Blue Swirl <blauwirbel at gmail.com>
Date:   Sat May 28 07:13:05 2011 +0000

    TCG: remove broken stack allocation for call arguments
    
    The code for stack allocation for call arguments is way too simplistic
    to actually work on targets with non-trivial stack allocation policies,
    e.g. ppc64. We've also already allocated TCG_STATIC_CALL_ARGS_SIZE worth
    of stack for calls which should be well more than any helper needs.
    
    Remove broken dynamic stack allocation code and replace it with an assert.
    Should dynamic stack allocation ever be needed again, target specific
    functions should be added.
    
    Thanks to Richard Henderson for the analysis.
    
    Signed-off-by: Blue Swirl <blauwirbel at gmail.com>

diff --git a/tcg/tcg.c b/tcg/tcg.c
index d8bf721..29cd7a2 100644
--- a/tcg/tcg.c
+++ b/tcg/tcg.c
@@ -1845,13 +1845,14 @@ static int tcg_reg_alloc_call(TCGContext *s, const TCGOpDef *def,
         nb_regs = nb_params;
 
     /* assign stack slots first */
-    /* XXX: preallocate call stack */
     call_stack_size = (nb_params - nb_regs) * sizeof(tcg_target_long);
     call_stack_size = (call_stack_size + TCG_TARGET_STACK_ALIGN - 1) & 
         ~(TCG_TARGET_STACK_ALIGN - 1);
     allocate_args = (call_stack_size > TCG_STATIC_CALL_ARGS_SIZE);
     if (allocate_args) {
-        tcg_out_addi(s, TCG_REG_CALL_STACK, -STACK_DIR(call_stack_size));
+        /* XXX: if more than TCG_STATIC_CALL_ARGS_SIZE is needed,
+           preallocate call stack */
+        tcg_abort();
     }
 
     stack_offset = TCG_TARGET_CALL_STACK_OFFSET;
@@ -1970,10 +1971,6 @@ static int tcg_reg_alloc_call(TCGContext *s, const TCGOpDef *def,
     }
 
     tcg_out_op(s, opc, &func_arg, &const_func_arg);
-    
-    if (allocate_args) {
-        tcg_out_addi(s, TCG_REG_CALL_STACK, STACK_DIR(call_stack_size));
-    }
 
     /* assign output registers and emit moves if needed */
     for(i = 0; i < nb_oargs; i++) {
commit b591dc59bc98ee558db4ca512aa117748ebfdeef
Author: Blue Swirl <blauwirbel at gmail.com>
Date:   Sat May 14 14:03:22 2011 +0000

    TCG: fix negative frame offset calculations
    
    size_t is unsigned, so the frame offset calculations can be incorrect for
    negative offsets.
    
    Signed-off-by: Blue Swirl <blauwirbel at gmail.com>

diff --git a/tcg/tcg.c b/tcg/tcg.c
index debf47f..d8bf721 100644
--- a/tcg/tcg.c
+++ b/tcg/tcg.c
@@ -1439,13 +1439,17 @@ static void temp_allocate_frame(TCGContext *s, int temp)
 {
     TCGTemp *ts;
     ts = &s->temps[temp];
-    s->current_frame_offset = (s->current_frame_offset + sizeof(tcg_target_long) - 1) & ~(sizeof(tcg_target_long) - 1);
-    if (s->current_frame_offset + sizeof(tcg_target_long) > s->frame_end)
+    s->current_frame_offset = (s->current_frame_offset +
+                               (tcg_target_long)sizeof(tcg_target_long) - 1) &
+        ~(sizeof(tcg_target_long) - 1);
+    if (s->current_frame_offset + (tcg_target_long)sizeof(tcg_target_long) >
+        s->frame_end) {
         tcg_abort();
+    }
     ts->mem_offset = s->current_frame_offset;
     ts->mem_reg = s->frame_reg;
     ts->mem_allocated = 1;
-    s->current_frame_offset += sizeof(tcg_target_long);
+    s->current_frame_offset += (tcg_target_long)sizeof(tcg_target_long);
 }
 
 /* free register 'reg' by spilling the corresponding temporary if necessary */
commit 614f104dfd2bf6d25170fb0afc086920cc7c407b
Author: Blue Swirl <blauwirbel at gmail.com>
Date:   Sat May 14 12:58:04 2011 +0000

    Delegate setup of TCG temporaries to targets
    
    Delegate TCG temp_buf setup to targets, so that they can use a stack
    frame later instead.
    
    Signed-off-by: Blue Swirl <blauwirbel at gmail.com>

diff --git a/tcg/arm/tcg-target.c b/tcg/arm/tcg-target.c
index 457ad7e..93eb0f1 100644
--- a/tcg/arm/tcg-target.c
+++ b/tcg/arm/tcg-target.c
@@ -1804,6 +1804,8 @@ static void tcg_target_init(TCGContext *s)
     tcg_regset_set_reg(s->reserved_regs, TCG_REG_PC);
 
     tcg_add_target_add_op_defs(arm_op_defs);
+    tcg_set_frame(s, TCG_AREG0, offsetof(CPUState, temp_buf),
+                  CPU_TEMP_BUF_NLONGS * sizeof(long));
 }
 
 static inline void tcg_out_ld(TCGContext *s, TCGType type, int arg,
diff --git a/tcg/hppa/tcg-target.c b/tcg/hppa/tcg-target.c
index 7248520..79bca63 100644
--- a/tcg/hppa/tcg-target.c
+++ b/tcg/hppa/tcg-target.c
@@ -1682,4 +1682,6 @@ static void tcg_target_init(TCGContext *s)
     tcg_regset_set_reg(s->reserved_regs, TCG_REG_R31); /* ble link reg */
 
     tcg_add_target_add_op_defs(hppa_op_defs);
+    tcg_set_frame(s, TCG_AREG0, offsetof(CPUState, temp_buf),
+                  CPU_TEMP_BUF_NLONGS * sizeof(long));
 }
diff --git a/tcg/i386/tcg-target.c b/tcg/i386/tcg-target.c
index 72b3a48..3ff9105 100644
--- a/tcg/i386/tcg-target.c
+++ b/tcg/i386/tcg-target.c
@@ -1981,4 +1981,6 @@ static void tcg_target_init(TCGContext *s)
     tcg_regset_set_reg(s->reserved_regs, TCG_REG_ESP);
 
     tcg_add_target_add_op_defs(x86_op_defs);
+    tcg_set_frame(s, TCG_AREG0, offsetof(CPUState, temp_buf),
+                  CPU_TEMP_BUF_NLONGS * sizeof(long));
 }
diff --git a/tcg/ia64/tcg-target.c b/tcg/ia64/tcg-target.c
index 246b2c0..6386a5b 100644
--- a/tcg/ia64/tcg-target.c
+++ b/tcg/ia64/tcg-target.c
@@ -2388,4 +2388,6 @@ static void tcg_target_init(TCGContext *s)
     tcg_regset_set_reg(s->reserved_regs, TCG_REG_R6);
 
     tcg_add_target_add_op_defs(ia64_op_defs);
+    tcg_set_frame(s, TCG_AREG0, offsetof(CPUState, temp_buf),
+                  CPU_TEMP_BUF_NLONGS * sizeof(long));
 }
diff --git a/tcg/mips/tcg-target.c b/tcg/mips/tcg-target.c
index cb2ab8b..12ff9d5 100644
--- a/tcg/mips/tcg-target.c
+++ b/tcg/mips/tcg-target.c
@@ -1528,4 +1528,6 @@ static void tcg_target_init(TCGContext *s)
     tcg_regset_set_reg(s->reserved_regs, TCG_REG_SP);   /* stack pointer */
 
     tcg_add_target_add_op_defs(mips_op_defs);
+    tcg_set_frame(s, TCG_AREG0, offsetof(CPUState, temp_buf),
+                  CPU_TEMP_BUF_NLONGS * sizeof(long));
 }
diff --git a/tcg/ppc/tcg-target.c b/tcg/ppc/tcg-target.c
index 266e699..dde4e18 100644
--- a/tcg/ppc/tcg-target.c
+++ b/tcg/ppc/tcg-target.c
@@ -1919,4 +1919,6 @@ static void tcg_target_init(TCGContext *s)
 #endif
 
     tcg_add_target_add_op_defs(ppc_op_defs);
+    tcg_set_frame(s, TCG_AREG0, offsetof(CPUState, temp_buf),
+                  CPU_TEMP_BUF_NLONGS * sizeof(long));
 }
diff --git a/tcg/ppc64/tcg-target.c b/tcg/ppc64/tcg-target.c
index 2e3cd2b..3218438 100644
--- a/tcg/ppc64/tcg-target.c
+++ b/tcg/ppc64/tcg-target.c
@@ -1696,4 +1696,6 @@ static void tcg_target_init (TCGContext *s)
     tcg_regset_set_reg (s->reserved_regs, TCG_REG_R13);
 
     tcg_add_target_add_op_defs (ppc_op_defs);
+    tcg_set_frame(s, TCG_AREG0, offsetof(CPUState, temp_buf),
+                  CPU_TEMP_BUF_NLONGS * sizeof(long));
 }
diff --git a/tcg/s390/tcg-target.c b/tcg/s390/tcg-target.c
index 8d8498c..2fc5646 100644
--- a/tcg/s390/tcg-target.c
+++ b/tcg/s390/tcg-target.c
@@ -2291,6 +2291,8 @@ static void tcg_target_init(TCGContext *s)
     tcg_regset_set_reg(s->reserved_regs, TCG_REG_CALL_STACK);
 
     tcg_add_target_add_op_defs(s390_op_defs);
+    tcg_set_frame(s, TCG_AREG0, offsetof(CPUState, temp_buf),
+                  CPU_TEMP_BUF_NLONGS * sizeof(long));
 }
 
 static void tcg_target_qemu_prologue(TCGContext *s)
diff --git a/tcg/sparc/tcg-target.c b/tcg/sparc/tcg-target.c
index ecf7ace..86f8c1e 100644
--- a/tcg/sparc/tcg-target.c
+++ b/tcg/sparc/tcg-target.c
@@ -1566,4 +1566,6 @@ static void tcg_target_init(TCGContext *s)
     tcg_regset_set_reg(s->reserved_regs, TCG_REG_O6);
     tcg_regset_set_reg(s->reserved_regs, TCG_REG_O7);
     tcg_add_target_add_op_defs(sparc_op_defs);
+    tcg_set_frame(s, TCG_AREG0, offsetof(CPUState, temp_buf),
+                  CPU_TEMP_BUF_NLONGS * sizeof(long));
 }
diff --git a/translate-all.c b/translate-all.c
index 24878aa..041c108 100644
--- a/translate-all.c
+++ b/translate-all.c
@@ -43,8 +43,6 @@ uint8_t gen_opc_instr_start[OPC_BUF_SIZE];
 void cpu_gen_init(void)
 {
     tcg_context_init(&tcg_ctx); 
-    tcg_set_frame(&tcg_ctx, TCG_AREG0, offsetof(CPUState, temp_buf),
-                  CPU_TEMP_BUF_NLONGS * sizeof(long));
 }
 
 /* return non zero if the very first instruction is invalid so that
commit cea5f9a28faa528b6b1b117c9ab2d8828f473fef
Author: Blue Swirl <blauwirbel at gmail.com>
Date:   Sun May 15 16:03:25 2011 +0000

    cpu-exec.c: avoid AREG0 use
    
    Make functions take a parameter for CPUState instead of relying
    on global env. Pass CPUState pointer to TCG prologue, which moves
    it to AREG0.
    
    Thanks to Peter Maydell and Laurent Desnogues for the ARM prologue
    change.
    
    Revert the hacks to avoid AREG0 use on Sparc hosts.
    
    Move cpu_has_work() and cpu_pc_from_tb() from exec.h to cpu.h.
    
    Compile the file without HELPER_CFLAGS.
    
    Signed-off-by: Blue Swirl <blauwirbel at gmail.com>

diff --git a/Makefile.target b/Makefile.target
index d3971a6..38afdb8 100644
--- a/Makefile.target
+++ b/Makefile.target
@@ -94,7 +94,7 @@ tcg/tcg.o: cpu.h
 
 # HELPER_CFLAGS is used for all the code compiled with static register
 # variables
-%_helper.o cpu-exec.o user-exec.o: QEMU_CFLAGS += $(HELPER_CFLAGS)
+%_helper.o user-exec.o: QEMU_CFLAGS += $(HELPER_CFLAGS)
 
 # Note: this is a workaround. The real fix is to avoid compiling
 # cpu_signal_handler() in user-exec.c.
diff --git a/cpu-exec.c b/cpu-exec.c
index 49de9e0..20e3ec4 100644
--- a/cpu-exec.c
+++ b/cpu-exec.c
@@ -17,17 +17,11 @@
  * License along with this library; if not, see <http://www.gnu.org/licenses/>.
  */
 #include "config.h"
-#include "exec.h"
+#include "cpu.h"
 #include "disas.h"
 #include "tcg.h"
 #include "qemu-barrier.h"
 
-#if defined(__sparc__) && !defined(CONFIG_SOLARIS)
-// Work around ugly bugs in glibc that mangle global register contents
-#undef env
-#define env cpu_single_env
-#endif
-
 int tb_invalidated_flag;
 
 //#define CONFIG_DEBUG_EXEC
@@ -37,20 +31,18 @@ bool qemu_cpu_has_work(CPUState *env)
     return cpu_has_work(env);
 }
 
-void cpu_loop_exit(CPUState *env1)
+void cpu_loop_exit(CPUState *env)
 {
-    env1->current_tb = NULL;
-    longjmp(env1->jmp_env, 1);
+    env->current_tb = NULL;
+    longjmp(env->jmp_env, 1);
 }
 
 /* exit the current TB from a signal handler. The host registers are
    restored in a state compatible with the CPU emulator
  */
 #if defined(CONFIG_SOFTMMU)
-void cpu_resume_from_signal(CPUState *env1, void *puc)
+void cpu_resume_from_signal(CPUState *env, void *puc)
 {
-    env = env1;
-
     /* XXX: restore cpu registers saved in host registers */
 
     env->exception_index = -1;
@@ -60,7 +52,8 @@ void cpu_resume_from_signal(CPUState *env1, void *puc)
 
 /* Execute the code without caching the generated code. An interpreter
    could be used if available. */
-static void cpu_exec_nocache(int max_cycles, TranslationBlock *orig_tb)
+static void cpu_exec_nocache(CPUState *env, int max_cycles,
+                             TranslationBlock *orig_tb)
 {
     unsigned long next_tb;
     TranslationBlock *tb;
@@ -74,7 +67,7 @@ static void cpu_exec_nocache(int max_cycles, TranslationBlock *orig_tb)
                      max_cycles);
     env->current_tb = tb;
     /* execute the generated code */
-    next_tb = tcg_qemu_tb_exec(tb->tc_ptr);
+    next_tb = tcg_qemu_tb_exec(env, tb->tc_ptr);
     env->current_tb = NULL;
 
     if ((next_tb & 3) == 2) {
@@ -86,7 +79,8 @@ static void cpu_exec_nocache(int max_cycles, TranslationBlock *orig_tb)
     tb_free(tb);
 }
 
-static TranslationBlock *tb_find_slow(target_ulong pc,
+static TranslationBlock *tb_find_slow(CPUState *env,
+                                      target_ulong pc,
                                       target_ulong cs_base,
                                       uint64_t flags)
 {
@@ -140,7 +134,7 @@ static TranslationBlock *tb_find_slow(target_ulong pc,
     return tb;
 }
 
-static inline TranslationBlock *tb_find_fast(void)
+static inline TranslationBlock *tb_find_fast(CPUState *env)
 {
     TranslationBlock *tb;
     target_ulong cs_base, pc;
@@ -153,7 +147,7 @@ static inline TranslationBlock *tb_find_fast(void)
     tb = env->tb_jmp_cache[tb_jmp_cache_hash_func(pc)];
     if (unlikely(!tb || tb->pc != pc || tb->cs_base != cs_base ||
                  tb->flags != flags)) {
-        tb = tb_find_slow(pc, cs_base, flags);
+        tb = tb_find_slow(env, pc, cs_base, flags);
     }
     return tb;
 }
@@ -186,31 +180,22 @@ static void cpu_handle_debug_exception(CPUState *env)
 
 volatile sig_atomic_t exit_request;
 
-int cpu_exec(CPUState *env1)
+int cpu_exec(CPUState *env)
 {
-    volatile host_reg_t saved_env_reg;
     int ret, interrupt_request;
     TranslationBlock *tb;
     uint8_t *tc_ptr;
     unsigned long next_tb;
 
-    if (env1->halted) {
-        if (!cpu_has_work(env1)) {
+    if (env->halted) {
+        if (!cpu_has_work(env)) {
             return EXCP_HALTED;
         }
 
-        env1->halted = 0;
+        env->halted = 0;
     }
 
-    cpu_single_env = env1;
-
-    /* the access to env below is actually saving the global register's
-       value, so that files not including target-xyz/exec.h are free to
-       use it.  */
-    QEMU_BUILD_BUG_ON (sizeof (saved_env_reg) != sizeof (env));
-    saved_env_reg = (host_reg_t) env;
-    barrier();
-    env = env1;
+    cpu_single_env = env;
 
     if (unlikely(exit_request)) {
         env->exit_request = 1;
@@ -246,11 +231,6 @@ int cpu_exec(CPUState *env1)
     /* prepare setjmp context for exception handling */
     for(;;) {
         if (setjmp(env->jmp_env) == 0) {
-#if defined(__sparc__) && !defined(CONFIG_SOLARIS)
-#undef env
-            env = cpu_single_env;
-#define env cpu_single_env
-#endif
             /* if an exception is pending, we execute it here */
             if (env->exception_index >= 0) {
                 if (env->exception_index >= EXCP_INTERRUPT) {
@@ -336,11 +316,6 @@ int cpu_exec(CPUState *env1)
                             env->interrupt_request &= ~(CPU_INTERRUPT_HARD | CPU_INTERRUPT_VIRQ);
                             intno = cpu_get_pic_interrupt(env);
                             qemu_log_mask(CPU_LOG_TB_IN_ASM, "Servicing hardware INT=0x%02x\n", intno);
-#if defined(__sparc__) && !defined(CONFIG_SOLARIS)
-#undef env
-                    env = cpu_single_env;
-#define env cpu_single_env
-#endif
                             do_interrupt_x86_hardirq(env, intno, 1);
                             /* ensure that no TB jump will be modified as
                                the program flow was changed */
@@ -547,7 +522,7 @@ int cpu_exec(CPUState *env1)
                 }
 #endif /* DEBUG_DISAS || CONFIG_DEBUG_EXEC */
                 spin_lock(&tb_lock);
-                tb = tb_find_fast();
+                tb = tb_find_fast(env);
                 /* Note: we do it here to avoid a gcc bug on Mac OS X when
                    doing it in tb_find_slow */
                 if (tb_invalidated_flag) {
@@ -579,12 +554,7 @@ int cpu_exec(CPUState *env1)
                 if (likely(!env->exit_request)) {
                     tc_ptr = tb->tc_ptr;
                 /* execute the generated code */
-#if defined(__sparc__) && !defined(CONFIG_SOLARIS)
-#undef env
-                    env = cpu_single_env;
-#define env cpu_single_env
-#endif
-                    next_tb = tcg_qemu_tb_exec(tc_ptr);
+                    next_tb = tcg_qemu_tb_exec(env, tc_ptr);
                     if ((next_tb & 3) == 2) {
                         /* Instruction counter expired.  */
                         int insns_left;
@@ -605,7 +575,7 @@ int cpu_exec(CPUState *env1)
                         } else {
                             if (insns_left > 0) {
                                 /* Execute remaining instructions.  */
-                                cpu_exec_nocache(insns_left, tb);
+                                cpu_exec_nocache(env, insns_left, tb);
                             }
                             env->exception_index = EXCP_INTERRUPT;
                             next_tb = 0;
@@ -647,10 +617,6 @@ int cpu_exec(CPUState *env1)
 #error unsupported target CPU
 #endif
 
-    /* restore global registers */
-    barrier();
-    env = (void *) saved_env_reg;
-
     /* fail safe : never use cpu_single_env outside cpu_exec() */
     cpu_single_env = NULL;
     return ret;
diff --git a/tcg/arm/tcg-target.c b/tcg/arm/tcg-target.c
index fb858d8..457ad7e 100644
--- a/tcg/arm/tcg-target.c
+++ b/tcg/arm/tcg-target.c
@@ -1846,15 +1846,18 @@ static inline void tcg_out_movi(TCGContext *s, TCGType type,
 
 static void tcg_target_qemu_prologue(TCGContext *s)
 {
-    /* There is no need to save r7, it is used to store the address
-       of the env structure and is not modified by GCC. */
+    /* Calling convention requires us to save r4-r11 and lr;
+     * save also r12 to maintain stack 8-alignment.
+     */
+
+    /* stmdb sp!, { r4 - r12, lr } */
+    tcg_out32(s, (COND_AL << 28) | 0x092d5ff0);
 
-    /* stmdb sp!, { r4 - r6, r8 - r11, lr } */
-    tcg_out32(s, (COND_AL << 28) | 0x092d4f70);
+    tcg_out_mov(s, TCG_TYPE_PTR, TCG_AREG0, tcg_target_call_iarg_regs[0]);
 
-    tcg_out_bx(s, COND_AL, TCG_REG_R0);
+    tcg_out_bx(s, COND_AL, tcg_target_call_iarg_regs[1]);
     tb_ret_addr = s->code_ptr;
 
-    /* ldmia sp!, { r4 - r6, r8 - r11, pc } */
-    tcg_out32(s, (COND_AL << 28) | 0x08bd8f70);
+    /* ldmia sp!, { r4 - r12, pc } */
+    tcg_out32(s, (COND_AL << 28) | 0x08bd9ff0);
 }
diff --git a/tcg/hppa/tcg-target.c b/tcg/hppa/tcg-target.c
index 7f4653e..7248520 100644
--- a/tcg/hppa/tcg-target.c
+++ b/tcg/hppa/tcg-target.c
@@ -1596,7 +1596,7 @@ static int tcg_target_callee_save_regs[] = {
     TCG_REG_R14,
     TCG_REG_R15,
     TCG_REG_R16,
-    /* R17 is the global env, so no need to save.  */
+    TCG_REG_R17, /* R17 is the global env.  */
     TCG_REG_R18
 };
 
@@ -1635,8 +1635,10 @@ static void tcg_target_qemu_prologue(TCGContext *s)
     }
 #endif
 
+    tcg_out_mov(s, TCG_TYPE_PTR, TCG_AREG0, tcg_target_call_iarg_regs[0]);
+
     /* Jump to TB, and adjust R18 to be the return address.  */
-    tcg_out32(s, INSN_BLE_SR4 | INSN_R2(TCG_REG_R26));
+    tcg_out32(s, INSN_BLE_SR4 | INSN_R2(tcg_target_call_iarg_regs[1]));
     tcg_out_mov(s, TCG_TYPE_I32, TCG_REG_R18, TCG_REG_R31);
 
     /* Restore callee saved registers.  */
diff --git a/tcg/i386/tcg-target.c b/tcg/i386/tcg-target.c
index bb19a95..72b3a48 100644
--- a/tcg/i386/tcg-target.c
+++ b/tcg/i386/tcg-target.c
@@ -1901,10 +1901,10 @@ static int tcg_target_callee_save_regs[] = {
     TCG_REG_RBX,
     TCG_REG_R12,
     TCG_REG_R13,
-    /* TCG_REG_R14, */ /* Currently used for the global env. */
+    TCG_REG_R14, /* Currently used for the global env. */
     TCG_REG_R15,
 #else
-    /* TCG_REG_EBP, */ /* Currently used for the global env. */
+    TCG_REG_EBP, /* Currently used for the global env. */
     TCG_REG_EBX,
     TCG_REG_ESI,
     TCG_REG_EDI,
@@ -1933,8 +1933,10 @@ static void tcg_target_qemu_prologue(TCGContext *s)
     stack_addend = frame_size - push_size;
     tcg_out_addi(s, TCG_REG_ESP, -stack_addend);
 
+    tcg_out_mov(s, TCG_TYPE_PTR, TCG_AREG0, tcg_target_call_iarg_regs[0]);
+
     /* jmp *tb.  */
-    tcg_out_modrm(s, OPC_GRP5, EXT5_JMPN_Ev, tcg_target_call_iarg_regs[0]);
+    tcg_out_modrm(s, OPC_GRP5, EXT5_JMPN_Ev, tcg_target_call_iarg_regs[1]);
 
     /* TB epilogue */
     tb_ret_addr = s->code_ptr;
diff --git a/tcg/ia64/tcg-target.c b/tcg/ia64/tcg-target.c
index 8dac7f7..246b2c0 100644
--- a/tcg/ia64/tcg-target.c
+++ b/tcg/ia64/tcg-target.c
@@ -2292,7 +2292,7 @@ static void tcg_target_qemu_prologue(TCGContext *s)
                    tcg_opc_m34(TCG_REG_P0, OPC_ALLOC_M34,
                                TCG_REG_R33, 32, 24, 0),
                    tcg_opc_i21(TCG_REG_P0, OPC_MOV_I21,
-                               TCG_REG_B6, TCG_REG_R32, 0),
+                               TCG_REG_B6, TCG_REG_R33, 0),
                    tcg_opc_i22(TCG_REG_P0, OPC_MOV_I22,
                                TCG_REG_R32, TCG_REG_B0));
 
@@ -2308,7 +2308,8 @@ static void tcg_target_qemu_prologue(TCGContext *s)
     }
 
     tcg_out_bundle(s, miB,
-                   tcg_opc_m48(TCG_REG_P0, OPC_NOP_M48, 0),
+                   tcg_opc_m48(TCG_REG_P0, OPC_MOV_I21,
+                               TCG_REG_AREG0, TCG_REG_R32, 0),
                    tcg_opc_a4 (TCG_REG_P0, OPC_ADDS_A4,
                                TCG_REG_R12, -frame_size, TCG_REG_R12),
                    tcg_opc_b4 (TCG_REG_P0, OPC_BR_SPTK_MANY_B4, TCG_REG_B6));
diff --git a/tcg/mips/tcg-target.c b/tcg/mips/tcg-target.c
index e04b0dc..cb2ab8b 100644
--- a/tcg/mips/tcg-target.c
+++ b/tcg/mips/tcg-target.c
@@ -1452,9 +1452,7 @@ static const TCGTargetOpDef mips_op_defs[] = {
 };
 
 static int tcg_target_callee_save_regs[] = {
-#if 0 /* used for the global env (TCG_AREG0), so no need to save */
-    TCG_REG_S0,
-#endif
+    TCG_REG_S0,       /* used for the global env (TCG_AREG0) */
     TCG_REG_S1,
     TCG_REG_S2,
     TCG_REG_S3,
@@ -1486,8 +1484,8 @@ static void tcg_target_qemu_prologue(TCGContext *s)
     }
 
     /* Call generated code */
-    tcg_out_opc_reg(s, OPC_JR, 0, TCG_REG_A0, 0);
-    tcg_out_nop(s);
+    tcg_out_opc_reg(s, OPC_JR, 0, tcg_target_call_iarg_regs[1]), 0);
+    tcg_out_mov(s, TCG_TYPE_PTR, TCG_AREG0, tcg_target_call_iarg_regs[0]);
     tb_ret_addr = s->code_ptr;
 
     /* TB epilogue */
diff --git a/tcg/ppc/tcg-target.c b/tcg/ppc/tcg-target.c
index 7970268..266e699 100644
--- a/tcg/ppc/tcg-target.c
+++ b/tcg/ppc/tcg-target.c
@@ -160,8 +160,7 @@ static const int tcg_target_callee_save_regs[] = {
     TCG_REG_R24,
     TCG_REG_R25,
     TCG_REG_R26,
-    /* TCG_REG_R27, */ /* currently used for the global env, so no
-                          need to save */
+    TCG_REG_R27, /* currently used for the global env */
     TCG_REG_R28,
     TCG_REG_R29,
     TCG_REG_R30,
@@ -939,7 +938,8 @@ static void tcg_target_qemu_prologue (TCGContext *s)
     }
 #endif
 
-    tcg_out32 (s, MTSPR | RS (3) | CTR);
+    tcg_out_mov (s, TCG_TYPE_PTR, TCG_AREG0, tcg_target_call_iarg_regs[0]);
+    tcg_out32 (s, MTSPR | RS (tcg_target_call_iarg_regs[1]) | CTR);
     tcg_out32 (s, BCCTR | BO_ALWAYS);
     tb_ret_addr = s->code_ptr;
 
diff --git a/tcg/ppc64/tcg-target.c b/tcg/ppc64/tcg-target.c
index ebbee34..2e3cd2b 100644
--- a/tcg/ppc64/tcg-target.c
+++ b/tcg/ppc64/tcg-target.c
@@ -151,8 +151,7 @@ static const int tcg_target_callee_save_regs[] = {
     TCG_REG_R24,
     TCG_REG_R25,
     TCG_REG_R26,
-    /* TCG_REG_R27, */ /* currently used for the global env, so no
-                          need to save */
+    TCG_REG_R27, /* currently used for the global env */
     TCG_REG_R28,
     TCG_REG_R29,
     TCG_REG_R30,
@@ -905,7 +904,8 @@ static void tcg_target_qemu_prologue (TCGContext *s)
     }
 #endif
 
-    tcg_out32 (s, MTSPR | RS (3) | CTR);
+    tcg_out_mov (s, TCG_TYPE_PTR, TCG_AREG0, tcg_target_call_iarg_regs[0]);
+    tcg_out32 (s, MTSPR | RS (tcg_target_call_iarg_regs[1]) | CTR);
     tcg_out32 (s, BCCTR | BO_ALWAYS);
 
     /* Epilogue */
diff --git a/tcg/s390/tcg-target.c b/tcg/s390/tcg-target.c
index 450fcab..8d8498c 100644
--- a/tcg/s390/tcg-target.c
+++ b/tcg/s390/tcg-target.c
@@ -2306,8 +2306,9 @@ static void tcg_target_qemu_prologue(TCGContext *s)
         tcg_regset_set_reg(s->reserved_regs, TCG_GUEST_BASE_REG);
     }
 
-    /* br %r2 (go to TB) */
-    tcg_out_insn(s, RR, BCR, S390_CC_ALWAYS, TCG_REG_R2);
+    tcg_out_mov(s, TCG_TYPE_PTR, TCG_AREG0, tcg_target_call_iarg_regs[0]);
+    /* br %r3 (go to TB) */
+    tcg_out_insn(s, RR, BCR, S390_CC_ALWAYS, tcg_target_call_iarg_regs[1]);
 
     tb_ret_addr = s->code_ptr;
 
diff --git a/tcg/sparc/tcg-target.c b/tcg/sparc/tcg-target.c
index 5f1353a..ecf7ace 100644
--- a/tcg/sparc/tcg-target.c
+++ b/tcg/sparc/tcg-target.c
@@ -695,9 +695,9 @@ static void tcg_target_qemu_prologue(TCGContext *s)
 {
     tcg_out32(s, SAVE | INSN_RD(TCG_REG_O6) | INSN_RS1(TCG_REG_O6) |
               INSN_IMM13(-TCG_TARGET_STACK_MINFRAME));
-    tcg_out32(s, JMPL | INSN_RD(TCG_REG_G0) | INSN_RS1(TCG_REG_I0) |
+    tcg_out32(s, JMPL | INSN_RD(TCG_REG_G0) | INSN_RS1(TCG_REG_I1) |
               INSN_RS2(TCG_REG_G0));
-    tcg_out_nop(s);
+    tcg_out_mov(s, TCG_TYPE_PTR, TCG_AREG0, TCG_REG_I0);
 }
 
 #if defined(CONFIG_SOFTMMU)
diff --git a/tcg/tcg.h b/tcg/tcg.h
index 3647390..a2dd8b8 100644
--- a/tcg/tcg.h
+++ b/tcg/tcg.h
@@ -515,8 +515,9 @@ TCGv_i64 tcg_const_local_i64(int64_t val);
 
 extern uint8_t code_gen_prologue[];
 #if defined(_ARCH_PPC) && !defined(_ARCH_PPC64)
-#define tcg_qemu_tb_exec(tb_ptr) \
-    ((long REGPARM __attribute__ ((longcall)) (*)(void *))code_gen_prologue)(tb_ptr)
+#define tcg_qemu_tb_exec(env, tb_ptr)                                    \
+    ((long REGPARM __attribute__ ((longcall)) (*)(void *, void *))code_gen_prologue)(env, tb_ptr)
 #else
-#define tcg_qemu_tb_exec(tb_ptr) ((long REGPARM (*)(void *))code_gen_prologue)(tb_ptr)
+#define tcg_qemu_tb_exec(env, tb_ptr)                                    \
+    ((long REGPARM (*)(void *, void *))code_gen_prologue)(env, tb_ptr)
 #endif
commit 2b41f10e186ccb4f0058815161586f8d6d006ea3
Author: Blue Swirl <blauwirbel at gmail.com>
Date:   Sun Jun 19 20:38:22 2011 +0000

    Remove exec-all.h include directives
    
    Most exec-all.h include directives are now useless, remove them.
    
    Signed-off-by: Blue Swirl <blauwirbel at gmail.com>

diff --git a/bsd-user/main.c b/bsd-user/main.c
index 0af8a7e..5f790b2 100644
--- a/bsd-user/main.c
+++ b/bsd-user/main.c
@@ -29,7 +29,7 @@
 #include "qemu.h"
 #include "qemu-common.h"
 /* For tb_lock */
-#include "exec-all.h"
+#include "cpu.h"
 #include "tcg.h"
 #include "qemu-timer.h"
 #include "envlist.h"
diff --git a/cpus.c b/cpus.c
index 0699f37..e299794 100644
--- a/cpus.c
+++ b/cpus.c
@@ -30,7 +30,6 @@
 #include "gdbstub.h"
 #include "dma.h"
 #include "kvm.h"
-#include "exec-all.h"
 
 #include "qemu-thread.h"
 #include "cpus.h"
diff --git a/disas.c b/disas.c
index d208c52..1334b8e 100644
--- a/disas.c
+++ b/disas.c
@@ -5,7 +5,6 @@
 #include <errno.h>
 
 #include "cpu.h"
-#include "exec-all.h"
 #include "disas.h"
 
 /* Filled in by elfload.c.  Simplistic, but will do for now. */
diff --git a/exec.c b/exec.c
index b03b5be..21507fb 100644
--- a/exec.c
+++ b/exec.c
@@ -26,7 +26,6 @@
 
 #include "qemu-common.h"
 #include "cpu.h"
-#include "exec-all.h"
 #include "tcg.h"
 #include "hw/hw.h"
 #include "hw/qdev.h"
diff --git a/gdbstub.c b/gdbstub.c
index b9ae30d..c085a5a 100644
--- a/gdbstub.c
+++ b/gdbstub.c
@@ -37,7 +37,7 @@
 
 #define MAX_PACKET_LENGTH 4096
 
-#include "exec-all.h"
+#include "cpu.h"
 #include "qemu_socket.h"
 #include "kvm.h"
 
diff --git a/hw/sh7750.c b/hw/sh7750.c
index 19d5bf8..4f279e7 100644
--- a/hw/sh7750.c
+++ b/hw/sh7750.c
@@ -29,7 +29,6 @@
 #include "sh7750_regs.h"
 #include "sh7750_regnames.h"
 #include "sh_intc.h"
-#include "exec-all.h"
 #include "cpu.h"
 
 #define NB_DEVICES 4
diff --git a/hw/spapr_hcall.c b/hw/spapr_hcall.c
index 43c441d..84da8fc 100644
--- a/hw/spapr_hcall.c
+++ b/hw/spapr_hcall.c
@@ -3,7 +3,6 @@
 #include "qemu-char.h"
 #include "sysemu.h"
 #include "qemu-char.h"
-#include "exec-all.h"
 #include "exec.h"
 #include "helper_regs.h"
 #include "hw/spapr.h"
diff --git a/kvm-stub.c b/kvm-stub.c
index 1e835c6..06064b9 100644
--- a/kvm-stub.c
+++ b/kvm-stub.c
@@ -12,7 +12,7 @@
 
 #include "qemu-common.h"
 #include "hw/hw.h"
-#include "exec-all.h"
+#include "cpu.h"
 #include "gdbstub.h"
 #include "kvm.h"
 
diff --git a/linux-user/main.c b/linux-user/main.c
index 71dd253..1c91c30 100644
--- a/linux-user/main.c
+++ b/linux-user/main.c
@@ -29,8 +29,7 @@
 #include "qemu.h"
 #include "qemu-common.h"
 #include "cache-utils.h"
-/* For tb_lock */
-#include "exec-all.h"
+#include "cpu.h"
 #include "tcg.h"
 #include "qemu-timer.h"
 #include "envlist.h"
diff --git a/monitor.c b/monitor.c
index 6af6a4d..67ceb46 100644
--- a/monitor.c
+++ b/monitor.c
@@ -56,7 +56,7 @@
 #include "json-streamer.h"
 #include "json-parser.h"
 #include "osdep.h"
-#include "exec-all.h"
+#include "cpu.h"
 #ifdef CONFIG_SIMPLE_TRACE
 #include "trace.h"
 #endif
diff --git a/target-alpha/exec.h b/target-alpha/exec.h
index f508996..afb01d3 100644
--- a/target-alpha/exec.h
+++ b/target-alpha/exec.h
@@ -31,7 +31,6 @@ register struct CPUAlphaState *env asm(AREG0);
 #define FP_STATUS (env->fp_status)
 
 #include "cpu.h"
-#include "exec-all.h"
 
 #if !defined(CONFIG_USER_ONLY)
 #include "softmmu_exec.h"
diff --git a/target-alpha/helper.c b/target-alpha/helper.c
index 32c2cf9..7049c80 100644
--- a/target-alpha/helper.c
+++ b/target-alpha/helper.c
@@ -22,7 +22,6 @@
 #include <stdio.h>
 
 #include "cpu.h"
-#include "exec-all.h"
 #include "softfloat.h"
 
 uint64_t cpu_alpha_load_fpcr (CPUState *env)
diff --git a/target-alpha/translate.c b/target-alpha/translate.c
index 936760c..c61906a 100644
--- a/target-alpha/translate.c
+++ b/target-alpha/translate.c
@@ -22,7 +22,6 @@
 #include <stdio.h>
 
 #include "cpu.h"
-#include "exec-all.h"
 #include "disas.h"
 #include "host-utils.h"
 #include "tcg-op.h"
diff --git a/target-arm/exec.h b/target-arm/exec.h
index 007b7cb..6793288 100644
--- a/target-arm/exec.h
+++ b/target-arm/exec.h
@@ -22,7 +22,6 @@
 register struct CPUARMState *env asm(AREG0);
 
 #include "cpu.h"
-#include "exec-all.h"
 
 #if !defined(CONFIG_USER_ONLY)
 #include "softmmu_exec.h"
diff --git a/target-arm/helper.c b/target-arm/helper.c
index 1208416..f4d12aa 100644
--- a/target-arm/helper.c
+++ b/target-arm/helper.c
@@ -3,7 +3,6 @@
 #include <string.h>
 
 #include "cpu.h"
-#include "exec-all.h"
 #include "gdbstub.h"
 #include "helper.h"
 #include "qemu-common.h"
diff --git a/target-arm/translate.c b/target-arm/translate.c
index f5507ec..badbc5f 100644
--- a/target-arm/translate.c
+++ b/target-arm/translate.c
@@ -25,7 +25,6 @@
 #include <inttypes.h>
 
 #include "cpu.h"
-#include "exec-all.h"
 #include "disas.h"
 #include "tcg-op.h"
 #include "qemu-log.h"
diff --git a/target-cris/exec.h b/target-cris/exec.h
index 9838159..3294abe 100644
--- a/target-cris/exec.h
+++ b/target-cris/exec.h
@@ -22,7 +22,6 @@
 register struct CPUCRISState *env asm(AREG0);
 
 #include "cpu.h"
-#include "exec-all.h"
 
 #if !defined(CONFIG_USER_ONLY)
 #include "softmmu_exec.h"
diff --git a/target-cris/helper.c b/target-cris/helper.c
index 2a4403b..962d214 100644
--- a/target-cris/helper.c
+++ b/target-cris/helper.c
@@ -24,7 +24,6 @@
 #include "config.h"
 #include "cpu.h"
 #include "mmu.h"
-#include "exec-all.h"
 #include "host-utils.h"
 
 
diff --git a/target-cris/mmu.c b/target-cris/mmu.c
index 1243745..d481e39 100644
--- a/target-cris/mmu.c
+++ b/target-cris/mmu.c
@@ -27,7 +27,6 @@
 #include "config.h"
 #include "cpu.h"
 #include "mmu.h"
-#include "exec-all.h"
 
 #ifdef DEBUG
 #define D(x) x
diff --git a/target-cris/translate.c b/target-cris/translate.c
index e2607d6..dd85859 100644
--- a/target-cris/translate.c
+++ b/target-cris/translate.c
@@ -30,7 +30,6 @@
 #include <inttypes.h>
 
 #include "cpu.h"
-#include "exec-all.h"
 #include "disas.h"
 #include "tcg-op.h"
 #include "helper.h"
diff --git a/target-i386/exec.h b/target-i386/exec.h
index 90a6b36..dd9bce4 100644
--- a/target-i386/exec.h
+++ b/target-i386/exec.h
@@ -34,7 +34,6 @@ register struct CPUX86State *env asm(AREG0);
 #include "qemu-log.h"
 
 #include "cpu.h"
-#include "exec-all.h"
 
 /* op_helper.c */
 void QEMU_NORETURN raise_exception_err(int exception_index, int error_code);
diff --git a/target-i386/helper.c b/target-i386/helper.c
index 509d68c..e9be104 100644
--- a/target-i386/helper.c
+++ b/target-i386/helper.c
@@ -23,7 +23,6 @@
 #include <inttypes.h>
 
 #include "cpu.h"
-#include "exec-all.h"
 #include "qemu-common.h"
 #include "kvm.h"
 #ifndef CONFIG_USER_ONLY
diff --git a/target-i386/machine.c b/target-i386/machine.c
index 7662aa2..9aca8e0 100644
--- a/target-i386/machine.c
+++ b/target-i386/machine.c
@@ -3,7 +3,7 @@
 #include "hw/pc.h"
 #include "hw/isa.h"
 
-#include "exec-all.h"
+#include "cpu.h"
 #include "kvm.h"
 
 static const VMStateDescription vmstate_segment = {
diff --git a/target-i386/op_helper.c b/target-i386/op_helper.c
index db038a7..315e18b 100644
--- a/target-i386/op_helper.c
+++ b/target-i386/op_helper.c
@@ -19,7 +19,6 @@
 
 #include <math.h>
 #include "exec.h"
-#include "exec-all.h"
 #include "host-utils.h"
 #include "ioport.h"
 
diff --git a/target-i386/translate.c b/target-i386/translate.c
index 10bd72a..ccef381 100644
--- a/target-i386/translate.c
+++ b/target-i386/translate.c
@@ -24,7 +24,6 @@
 #include <signal.h>
 
 #include "cpu.h"
-#include "exec-all.h"
 #include "disas.h"
 #include "tcg-op.h"
 
diff --git a/target-lm32/exec.h b/target-lm32/exec.h
index 61eb914..2a227b2 100644
--- a/target-lm32/exec.h
+++ b/target-lm32/exec.h
@@ -22,7 +22,6 @@
 register struct CPULM32State *env asm(AREG0);
 
 #include "cpu.h"
-#include "exec-all.h"
 
 static inline int cpu_halted(CPUState *env)
 {
diff --git a/target-lm32/helper.c b/target-lm32/helper.c
index 4f3e7e0..e79428d 100644
--- a/target-lm32/helper.c
+++ b/target-lm32/helper.c
@@ -23,7 +23,6 @@
 
 #include "config.h"
 #include "cpu.h"
-#include "exec-all.h"
 #include "host-utils.h"
 
 int cpu_lm32_handle_mmu_fault(CPUState *env, target_ulong address, int rw,
diff --git a/target-lm32/translate.c b/target-lm32/translate.c
index 5e19725..0be105d 100644
--- a/target-lm32/translate.c
+++ b/target-lm32/translate.c
@@ -25,7 +25,6 @@
 #include <assert.h>
 
 #include "cpu.h"
-#include "exec-all.h"
 #include "disas.h"
 #include "helper.h"
 #include "tcg-op.h"
diff --git a/target-m68k/exec.h b/target-m68k/exec.h
index 568260c..93e7912 100644
--- a/target-m68k/exec.h
+++ b/target-m68k/exec.h
@@ -22,7 +22,6 @@
 register struct CPUM68KState *env asm(AREG0);
 
 #include "cpu.h"
-#include "exec-all.h"
 
 #if !defined(CONFIG_USER_ONLY)
 #include "softmmu_exec.h"
diff --git a/target-m68k/helper.c b/target-m68k/helper.c
index faa8c42..a936fe7 100644
--- a/target-m68k/helper.c
+++ b/target-m68k/helper.c
@@ -23,7 +23,6 @@
 
 #include "config.h"
 #include "cpu.h"
-#include "exec-all.h"
 #include "qemu-common.h"
 #include "gdbstub.h"
 
diff --git a/target-m68k/translate.c b/target-m68k/translate.c
index 26f0ee4..0e7f1fe 100644
--- a/target-m68k/translate.c
+++ b/target-m68k/translate.c
@@ -25,7 +25,6 @@
 
 #include "config.h"
 #include "cpu.h"
-#include "exec-all.h"
 #include "disas.h"
 #include "tcg-op.h"
 #include "qemu-log.h"
diff --git a/target-microblaze/exec.h b/target-microblaze/exec.h
index b7f85cf..71b4d39 100644
--- a/target-microblaze/exec.h
+++ b/target-microblaze/exec.h
@@ -21,7 +21,6 @@
 register struct CPUMBState *env asm(AREG0);
 
 #include "cpu.h"
-#include "exec-all.h"
 
 #if !defined(CONFIG_USER_ONLY)
 #include "softmmu_exec.h"
diff --git a/target-microblaze/helper.c b/target-microblaze/helper.c
index a623c7b..299259c 100644
--- a/target-microblaze/helper.c
+++ b/target-microblaze/helper.c
@@ -23,7 +23,6 @@
 
 #include "config.h"
 #include "cpu.h"
-#include "exec-all.h"
 #include "host-utils.h"
 
 #define D(x)
diff --git a/target-microblaze/mmu.c b/target-microblaze/mmu.c
index b38f7d9..281fc8d 100644
--- a/target-microblaze/mmu.c
+++ b/target-microblaze/mmu.c
@@ -22,7 +22,6 @@
 
 #include "config.h"
 #include "cpu.h"
-#include "exec-all.h"
 
 #define D(x)
 
diff --git a/target-microblaze/translate.c b/target-microblaze/translate.c
index b47b92e..31e8306 100644
--- a/target-microblaze/translate.c
+++ b/target-microblaze/translate.c
@@ -25,7 +25,6 @@
 #include <assert.h>
 
 #include "cpu.h"
-#include "exec-all.h"
 #include "disas.h"
 #include "tcg-op.h"
 #include "helper.h"
diff --git a/target-mips/exec.h b/target-mips/exec.h
index a3a7262..e787e9a 100644
--- a/target-mips/exec.h
+++ b/target-mips/exec.h
@@ -11,7 +11,6 @@
 register struct CPUMIPSState *env asm(AREG0);
 
 #include "cpu.h"
-#include "exec-all.h"
 
 #if !defined(CONFIG_USER_ONLY)
 #include "softmmu_exec.h"
diff --git a/target-mips/helper.c b/target-mips/helper.c
index 0f057c2..ecf6182 100644
--- a/target-mips/helper.c
+++ b/target-mips/helper.c
@@ -24,7 +24,6 @@
 #include <signal.h>
 
 #include "cpu.h"
-#include "exec-all.h"
 
 enum {
     TLBRET_DIRTY = -4,
diff --git a/target-mips/machine.c b/target-mips/machine.c
index 9ffac71..be72b36 100644
--- a/target-mips/machine.c
+++ b/target-mips/machine.c
@@ -1,7 +1,7 @@
 #include "hw/hw.h"
 #include "hw/boards.h"
 
-#include "exec-all.h"
+#include "cpu.h"
 
 static void save_tc(QEMUFile *f, TCState *tc)
 {
diff --git a/target-mips/translate.c b/target-mips/translate.c
index 4eaa826..2848c6a 100644
--- a/target-mips/translate.c
+++ b/target-mips/translate.c
@@ -27,7 +27,6 @@
 #include <inttypes.h>
 
 #include "cpu.h"
-#include "exec-all.h"
 #include "disas.h"
 #include "tcg-op.h"
 #include "qemu-common.h"
diff --git a/target-ppc/exec.h b/target-ppc/exec.h
index 1e144be..f4453e4 100644
--- a/target-ppc/exec.h
+++ b/target-ppc/exec.h
@@ -24,7 +24,6 @@
 #include "dyngen-exec.h"
 
 #include "cpu.h"
-#include "exec-all.h"
 
 register struct CPUPPCState *env asm(AREG0);
 
diff --git a/target-ppc/helper.c b/target-ppc/helper.c
index cf2a368..395ea0e 100644
--- a/target-ppc/helper.c
+++ b/target-ppc/helper.c
@@ -23,7 +23,6 @@
 #include <inttypes.h>
 
 #include "cpu.h"
-#include "exec-all.h"
 #include "helper_regs.h"
 #include "qemu-common.h"
 #include "kvm.h"
diff --git a/target-ppc/translate.c b/target-ppc/translate.c
index 59aef85..0a03b44 100644
--- a/target-ppc/translate.c
+++ b/target-ppc/translate.c
@@ -24,7 +24,6 @@
 #include <inttypes.h>
 
 #include "cpu.h"
-#include "exec-all.h"
 #include "disas.h"
 #include "tcg-op.h"
 #include "qemu-common.h"
diff --git a/target-s390x/exec.h b/target-s390x/exec.h
index d40640b..fb73f31 100644
--- a/target-s390x/exec.h
+++ b/target-s390x/exec.h
@@ -23,7 +23,6 @@ register struct CPUS390XState *env asm(AREG0);
 
 #include "config.h"
 #include "cpu.h"
-#include "exec-all.h"
 
 #if !defined(CONFIG_USER_ONLY)
 #include "softmmu_exec.h"
diff --git a/target-s390x/helper.c b/target-s390x/helper.c
index 745d8c5..1ce7079 100644
--- a/target-s390x/helper.c
+++ b/target-s390x/helper.c
@@ -23,7 +23,6 @@
 #include <string.h>
 
 #include "cpu.h"
-#include "exec-all.h"
 #include "gdbstub.h"
 #include "qemu-common.h"
 #include "qemu-timer.h"
diff --git a/target-s390x/translate.c b/target-s390x/translate.c
index eda4624..77fb448 100644
--- a/target-s390x/translate.c
+++ b/target-s390x/translate.c
@@ -35,7 +35,6 @@
 #endif
 
 #include "cpu.h"
-#include "exec-all.h"
 #include "disas.h"
 #include "tcg-op.h"
 #include "qemu-log.h"
diff --git a/target-sh4/exec.h b/target-sh4/exec.h
index a537672..4a6ae58 100644
--- a/target-sh4/exec.h
+++ b/target-sh4/exec.h
@@ -25,7 +25,6 @@
 register struct CPUSH4State *env asm(AREG0);
 
 #include "cpu.h"
-#include "exec-all.h"
 
 #ifndef CONFIG_USER_ONLY
 #include "softmmu_exec.h"
diff --git a/target-sh4/helper.c b/target-sh4/helper.c
index 8f36d31..20e9b13 100644
--- a/target-sh4/helper.c
+++ b/target-sh4/helper.c
@@ -24,7 +24,6 @@
 #include <signal.h>
 
 #include "cpu.h"
-#include "exec-all.h"
 #include "hw/sh_intc.h"
 
 #if defined(CONFIG_USER_ONLY)
diff --git a/target-sh4/translate.c b/target-sh4/translate.c
index 93c8636..569bc73 100644
--- a/target-sh4/translate.c
+++ b/target-sh4/translate.c
@@ -27,7 +27,6 @@
 //#define SH4_SINGLE_STEP
 
 #include "cpu.h"
-#include "exec-all.h"
 #include "disas.h"
 #include "tcg-op.h"
 #include "qemu-common.h"
diff --git a/target-sparc/helper.c b/target-sparc/helper.c
index 6b35105..7eea1ac 100644
--- a/target-sparc/helper.c
+++ b/target-sparc/helper.c
@@ -23,7 +23,6 @@
 #include <inttypes.h>
 
 #include "cpu.h"
-#include "exec-all.h"
 #include "qemu-common.h"
 
 //#define DEBUG_MMU
diff --git a/target-sparc/machine.c b/target-sparc/machine.c
index bae23c5..56ae041 100644
--- a/target-sparc/machine.c
+++ b/target-sparc/machine.c
@@ -2,7 +2,7 @@
 #include "hw/boards.h"
 #include "qemu-timer.h"
 
-#include "exec-all.h"
+#include "cpu.h"
 
 void cpu_save(QEMUFile *f, void *opaque)
 {
diff --git a/target-sparc/translate.c b/target-sparc/translate.c
index 0cc47e9..992cd77 100644
--- a/target-sparc/translate.c
+++ b/target-sparc/translate.c
@@ -25,7 +25,6 @@
 #include <inttypes.h>
 
 #include "cpu.h"
-#include "exec-all.h"
 #include "disas.h"
 #include "helper.h"
 #include "tcg-op.h"
diff --git a/target-unicore32/exec.h b/target-unicore32/exec.h
index 6b9b499..7912105 100644
--- a/target-unicore32/exec.h
+++ b/target-unicore32/exec.h
@@ -16,7 +16,6 @@
 register struct CPUState_UniCore32 *env asm(AREG0);
 
 #include "cpu.h"
-#include "exec-all.h"
 
 static inline void env_to_regs(void)
 {
diff --git a/target-unicore32/helper.c b/target-unicore32/helper.c
index 483aeae..02707d5 100644
--- a/target-unicore32/helper.c
+++ b/target-unicore32/helper.c
@@ -10,7 +10,6 @@
 #include <string.h>
 
 #include "cpu.h"
-#include "exec-all.h"
 #include "gdbstub.h"
 #include "helper.h"
 #include "qemu-common.h"
diff --git a/target-unicore32/translate.c b/target-unicore32/translate.c
index 98eaeb3..a15e42d 100644
--- a/target-unicore32/translate.c
+++ b/target-unicore32/translate.c
@@ -14,7 +14,6 @@
 #include <inttypes.h>
 
 #include "cpu.h"
-#include "exec-all.h"
 #include "disas.h"
 #include "tcg-op.h"
 #include "qemu-log.h"
diff --git a/tcg/tcg.c b/tcg/tcg.c
index 184c208..debf47f 100644
--- a/tcg/tcg.c
+++ b/tcg/tcg.c
@@ -54,7 +54,6 @@
    instructions */
 #define NO_CPU_IO_DEFS
 #include "cpu.h"
-#include "exec-all.h"
 
 #include "tcg-op.h"
 #include "elf.h"
diff --git a/translate-all.c b/translate-all.c
index 2ca190c..24878aa 100644
--- a/translate-all.c
+++ b/translate-all.c
@@ -26,7 +26,6 @@
 
 #define NO_CPU_IO_DEFS
 #include "cpu.h"
-#include "exec-all.h"
 #include "disas.h"
 #include "tcg.h"
 #include "qemu-timer.h"
diff --git a/xen-mapcache-stub.c b/xen-mapcache-stub.c
index 5eb3dac..90a994d 100644
--- a/xen-mapcache-stub.c
+++ b/xen-mapcache-stub.c
@@ -9,7 +9,6 @@
 #include "config.h"
 
 #include "cpu.h"
-#include "exec-all.h"
 #include "qemu-common.h"
 #include "cpu-common.h"
 #include "xen-mapcache.h"
commit f081c76ccfdbc1fdaa90fa5eb6abad46c1b5bfa8
Author: Blue Swirl <blauwirbel at gmail.com>
Date:   Sat May 21 07:10:23 2011 +0000

    Move cpu_has_work and cpu_pc_from_tb to cpu.h
    
    Move functions cpu_has_work() and cpu_pc_from_tb() from exec.h to cpu.h. This is
    needed by later patches.
    
    Signed-off-by: Blue Swirl <blauwirbel at gmail.com>

diff --git a/exec-all.h b/exec-all.h
index efef1cd..21a69d6 100644
--- a/exec-all.h
+++ b/exec-all.h
@@ -40,6 +40,7 @@ typedef ram_addr_t tb_page_addr_t;
 #define DISAS_UPDATE  2 /* cpu state was modified dynamically */
 #define DISAS_TB_JUMP 3 /* only pc was modified statically */
 
+struct TranslationBlock;
 typedef struct TranslationBlock TranslationBlock;
 
 /* XXX: make safe guess about sizes */
diff --git a/target-alpha/cpu.h b/target-alpha/cpu.h
index e98b325..411bd55 100644
--- a/target-alpha/cpu.h
+++ b/target-alpha/cpu.h
@@ -492,4 +492,26 @@ static inline void cpu_set_tls(CPUState *env, target_ulong newtls)
 }
 #endif
 
+static inline bool cpu_has_work(CPUState *env)
+{
+    /* Here we are checking to see if the CPU should wake up from HALT.
+       We will have gotten into this state only for WTINT from PALmode.  */
+    /* ??? I'm not sure how the IPL state works with WTINT to keep a CPU
+       asleep even if (some) interrupts have been asserted.  For now,
+       assume that if a CPU really wants to stay asleep, it will mask
+       interrupts at the chipset level, which will prevent these bits
+       from being set in the first place.  */
+    return env->interrupt_request & (CPU_INTERRUPT_HARD
+                                     | CPU_INTERRUPT_TIMER
+                                     | CPU_INTERRUPT_SMP
+                                     | CPU_INTERRUPT_MCHK);
+}
+
+#include "exec-all.h"
+
+static inline void cpu_pc_from_tb(CPUState *env, TranslationBlock *tb)
+{
+    env->pc = tb->pc;
+}
+
 #endif /* !defined (__CPU_ALPHA_H__) */
diff --git a/target-alpha/exec.h b/target-alpha/exec.h
index 0f9b827..f508996 100644
--- a/target-alpha/exec.h
+++ b/target-alpha/exec.h
@@ -37,24 +37,4 @@ register struct CPUAlphaState *env asm(AREG0);
 #include "softmmu_exec.h"
 #endif /* !defined(CONFIG_USER_ONLY) */
 
-static inline bool cpu_has_work(CPUState *env)
-{
-    /* Here we are checking to see if the CPU should wake up from HALT.
-       We will have gotten into this state only for WTINT from PALmode.  */
-    /* ??? I'm not sure how the IPL state works with WTINT to keep a CPU
-       asleep even if (some) interrupts have been asserted.  For now, 
-       assume that if a CPU really wants to stay asleep, it will mask
-       interrupts at the chipset level, which will prevent these bits
-       from being set in the first place.  */
-    return env->interrupt_request & (CPU_INTERRUPT_HARD
-                                     | CPU_INTERRUPT_TIMER
-                                     | CPU_INTERRUPT_SMP
-                                     | CPU_INTERRUPT_MCHK);
-}
-
-static inline void cpu_pc_from_tb(CPUState *env, TranslationBlock *tb)
-{
-    env->pc = tb->pc;
-}
-
 #endif /* !defined (__ALPHA_EXEC_H__) */
diff --git a/target-arm/cpu.h b/target-arm/cpu.h
index 01f5b57..116131e 100644
--- a/target-arm/cpu.h
+++ b/target-arm/cpu.h
@@ -512,4 +512,17 @@ static inline void cpu_get_tb_cpu_state(CPUState *env, target_ulong *pc,
     }
 }
 
+static inline bool cpu_has_work(CPUState *env)
+{
+    return env->interrupt_request &
+        (CPU_INTERRUPT_FIQ | CPU_INTERRUPT_HARD | CPU_INTERRUPT_EXITTB);
+}
+
+#include "exec-all.h"
+
+static inline void cpu_pc_from_tb(CPUState *env, TranslationBlock *tb)
+{
+    env->regs[15] = tb->pc;
+}
+
 #endif
diff --git a/target-arm/exec.h b/target-arm/exec.h
index 9c31418..007b7cb 100644
--- a/target-arm/exec.h
+++ b/target-arm/exec.h
@@ -24,20 +24,8 @@ register struct CPUARMState *env asm(AREG0);
 #include "cpu.h"
 #include "exec-all.h"
 
-static inline bool cpu_has_work(CPUState *env)
-{
-    return env->interrupt_request &
-        (CPU_INTERRUPT_FIQ | CPU_INTERRUPT_HARD | CPU_INTERRUPT_EXITTB);
-}
-
 #if !defined(CONFIG_USER_ONLY)
 #include "softmmu_exec.h"
 #endif
 
 void raise_exception(int);
-
-static inline void cpu_pc_from_tb(CPUState *env, TranslationBlock *tb)
-{
-    env->regs[15] = tb->pc;
-}
-
diff --git a/target-cris/cpu.h b/target-cris/cpu.h
index 2bc35e4..ecb0df1 100644
--- a/target-cris/cpu.h
+++ b/target-cris/cpu.h
@@ -268,4 +268,15 @@ static inline void cpu_get_tb_cpu_state(CPUState *env, target_ulong *pc,
 #define cpu_list cris_cpu_list
 void cris_cpu_list(FILE *f, fprintf_function cpu_fprintf);
 
+static inline bool cpu_has_work(CPUState *env)
+{
+    return env->interrupt_request & (CPU_INTERRUPT_HARD | CPU_INTERRUPT_NMI);
+}
+
+#include "exec-all.h"
+
+static inline void cpu_pc_from_tb(CPUState *env, TranslationBlock *tb)
+{
+    env->pc = tb->pc;
+}
 #endif
diff --git a/target-cris/exec.h b/target-cris/exec.h
index 70d99d1..9838159 100644
--- a/target-cris/exec.h
+++ b/target-cris/exec.h
@@ -27,14 +27,3 @@ register struct CPUCRISState *env asm(AREG0);
 #if !defined(CONFIG_USER_ONLY)
 #include "softmmu_exec.h"
 #endif
-
-static inline bool cpu_has_work(CPUState *env)
-{
-    return env->interrupt_request & (CPU_INTERRUPT_HARD | CPU_INTERRUPT_NMI);
-}
-
-static inline void cpu_pc_from_tb(CPUState *env, TranslationBlock *tb)
-{
-    env->pc = tb->pc;
-}
-
diff --git a/target-i386/cpu.h b/target-i386/cpu.h
index 656d360..9819b5f 100644
--- a/target-i386/cpu.h
+++ b/target-i386/cpu.h
@@ -957,6 +957,36 @@ static inline int cpu_mmu_index (CPUState *env)
     return (env->hflags & HF_CPL_MASK) == 3 ? 1 : 0;
 }
 
+#undef EAX
+#define EAX (env->regs[R_EAX])
+#undef ECX
+#define ECX (env->regs[R_ECX])
+#undef EDX
+#define EDX (env->regs[R_EDX])
+#undef EBX
+#define EBX (env->regs[R_EBX])
+#undef ESP
+#define ESP (env->regs[R_ESP])
+#undef EBP
+#define EBP (env->regs[R_EBP])
+#undef ESI
+#define ESI (env->regs[R_ESI])
+#undef EDI
+#define EDI (env->regs[R_EDI])
+#undef EIP
+#define EIP (env->eip)
+#define DF  (env->df)
+
+#define CC_SRC (env->cc_src)
+#define CC_DST (env->cc_dst)
+#define CC_OP  (env->cc_op)
+
+/* float macros */
+#define FT0    (env->ft0)
+#define ST0    (env->fpregs[env->fpstt].d)
+#define ST(n)  (env->fpregs[(env->fpstt + (n)) & 7].d)
+#define ST1    ST(1)
+
 /* translate.c */
 void optimize_flags_init(void);
 
@@ -981,6 +1011,23 @@ static inline void cpu_clone_regs(CPUState *env, target_ulong newsp)
 #include "hw/apic.h"
 #endif
 
+static inline bool cpu_has_work(CPUState *env)
+{
+    return ((env->interrupt_request & CPU_INTERRUPT_HARD) &&
+            (env->eflags & IF_MASK)) ||
+           (env->interrupt_request & (CPU_INTERRUPT_NMI |
+                                      CPU_INTERRUPT_INIT |
+                                      CPU_INTERRUPT_SIPI |
+                                      CPU_INTERRUPT_MCE));
+}
+
+#include "exec-all.h"
+
+static inline void cpu_pc_from_tb(CPUState *env, TranslationBlock *tb)
+{
+    env->eip = tb->pc - tb->cs_base;
+}
+
 static inline void cpu_get_tb_cpu_state(CPUState *env, target_ulong *pc,
                                         target_ulong *cs_base, int *flags)
 {
diff --git a/target-i386/exec.h b/target-i386/exec.h
index 77bb356..90a6b36 100644
--- a/target-i386/exec.h
+++ b/target-i386/exec.h
@@ -33,36 +33,6 @@ register struct CPUX86State *env asm(AREG0);
 #include "qemu-common.h"
 #include "qemu-log.h"
 
-#undef EAX
-#define EAX (env->regs[R_EAX])
-#undef ECX
-#define ECX (env->regs[R_ECX])
-#undef EDX
-#define EDX (env->regs[R_EDX])
-#undef EBX
-#define EBX (env->regs[R_EBX])
-#undef ESP
-#define ESP (env->regs[R_ESP])
-#undef EBP
-#define EBP (env->regs[R_EBP])
-#undef ESI
-#define ESI (env->regs[R_ESI])
-#undef EDI
-#define EDI (env->regs[R_EDI])
-#undef EIP
-#define EIP (env->eip)
-#define DF  (env->df)
-
-#define CC_SRC (env->cc_src)
-#define CC_DST (env->cc_dst)
-#define CC_OP  (env->cc_op)
-
-/* float macros */
-#define FT0    (env->ft0)
-#define ST0    (env->fpregs[env->fpstt].d)
-#define ST(n)  (env->fpregs[(env->fpstt + (n)) & 7].d)
-#define ST1    ST(1)
-
 #include "cpu.h"
 #include "exec-all.h"
 
@@ -160,16 +130,6 @@ static inline void load_eflags(int eflags, int update_mask)
         (eflags & update_mask) | 0x2;
 }
 
-static inline bool cpu_has_work(CPUState *env)
-{
-    return ((env->interrupt_request & CPU_INTERRUPT_HARD) &&
-            (env->eflags & IF_MASK)) ||
-           (env->interrupt_request & (CPU_INTERRUPT_NMI |
-                                      CPU_INTERRUPT_INIT |
-                                      CPU_INTERRUPT_SIPI |
-                                      CPU_INTERRUPT_MCE));
-}
-
 /* load efer and update the corresponding hflags. XXX: do consistency
    checks with cpuid bits ? */
 static inline void cpu_load_efer(CPUState *env, uint64_t val)
@@ -181,9 +141,3 @@ static inline void cpu_load_efer(CPUState *env, uint64_t val)
     if (env->efer & MSR_EFER_SVME)
         env->hflags |= HF_SVME_MASK;
 }
-
-static inline void cpu_pc_from_tb(CPUState *env, TranslationBlock *tb)
-{
-    env->eip = tb->pc - tb->cs_base;
-}
-
diff --git a/target-lm32/cpu.h b/target-lm32/cpu.h
index 8e2d26b..876b5be 100644
--- a/target-lm32/cpu.h
+++ b/target-lm32/cpu.h
@@ -241,4 +241,17 @@ static inline void cpu_get_tb_cpu_state(CPUState *env, target_ulong *pc,
     *cs_base = 0;
     *flags = 0;
 }
+
+static inline bool cpu_has_work(CPUState *env)
+{
+    return env->interrupt_request & CPU_INTERRUPT_HARD;
+}
+
+#include "exec-all.h"
+
+static inline void cpu_pc_from_tb(CPUState *env, TranslationBlock *tb)
+{
+    env->pc = tb->pc;
+}
+
 #endif
diff --git a/target-lm32/exec.h b/target-lm32/exec.h
index 83ddb65..61eb914 100644
--- a/target-lm32/exec.h
+++ b/target-lm32/exec.h
@@ -24,11 +24,6 @@ register struct CPULM32State *env asm(AREG0);
 #include "cpu.h"
 #include "exec-all.h"
 
-static inline bool cpu_has_work(CPUState *env)
-{
-    return env->interrupt_request & CPU_INTERRUPT_HARD;
-}
-
 static inline int cpu_halted(CPUState *env)
 {
     if (!env->halted) {
@@ -42,9 +37,3 @@ static inline int cpu_halted(CPUState *env)
     }
     return EXCP_HALTED;
 }
-
-static inline void cpu_pc_from_tb(CPUState *env, TranslationBlock *tb)
-{
-    env->pc = tb->pc;
-}
-
diff --git a/target-m68k/cpu.h b/target-m68k/cpu.h
index 4d8ba28..e0f9b32 100644
--- a/target-m68k/cpu.h
+++ b/target-m68k/cpu.h
@@ -255,4 +255,16 @@ static inline void cpu_get_tb_cpu_state(CPUState *env, target_ulong *pc,
             | ((env->macsr >> 4) & 0xf);        /* Bits 0-3 */
 }
 
+static inline bool cpu_has_work(CPUState *env)
+{
+    return env->interrupt_request & CPU_INTERRUPT_HARD;
+}
+
+#include "exec-all.h"
+
+static inline void cpu_pc_from_tb(CPUState *env, TranslationBlock *tb)
+{
+    env->pc = tb->pc;
+}
+
 #endif
diff --git a/target-m68k/exec.h b/target-m68k/exec.h
index f7abbf4..568260c 100644
--- a/target-m68k/exec.h
+++ b/target-m68k/exec.h
@@ -27,14 +27,3 @@ register struct CPUM68KState *env asm(AREG0);
 #if !defined(CONFIG_USER_ONLY)
 #include "softmmu_exec.h"
 #endif
-
-static inline bool cpu_has_work(CPUState *env)
-{
-    return env->interrupt_request & (CPU_INTERRUPT_HARD);
-}
-
-static inline void cpu_pc_from_tb(CPUState *env, TranslationBlock *tb)
-{
-    env->pc = tb->pc;
-}
-
diff --git a/target-microblaze/cpu.h b/target-microblaze/cpu.h
index 78fe14f..51a13e3 100644
--- a/target-microblaze/cpu.h
+++ b/target-microblaze/cpu.h
@@ -350,4 +350,17 @@ static inline void cpu_get_tb_cpu_state(CPUState *env, target_ulong *pc,
 void do_unassigned_access(target_phys_addr_t addr, int is_write, int is_exec,
                           int is_asi, int size);
 #endif
+
+static inline bool cpu_has_work(CPUState *env)
+{
+    return env->interrupt_request & (CPU_INTERRUPT_HARD | CPU_INTERRUPT_NMI);
+}
+
+#include "exec-all.h"
+
+static inline void cpu_pc_from_tb(CPUState *env, TranslationBlock *tb)
+{
+    env->sregs[SR_PC] = tb->pc;
+}
+
 #endif
diff --git a/target-microblaze/exec.h b/target-microblaze/exec.h
index bb2b7db..b7f85cf 100644
--- a/target-microblaze/exec.h
+++ b/target-microblaze/exec.h
@@ -26,14 +26,3 @@ register struct CPUMBState *env asm(AREG0);
 #if !defined(CONFIG_USER_ONLY)
 #include "softmmu_exec.h"
 #endif
-
-static inline bool cpu_has_work(CPUState *env)
-{
-    return env->interrupt_request & (CPU_INTERRUPT_HARD | CPU_INTERRUPT_NMI);
-}
-
-static inline void cpu_pc_from_tb(CPUState *env, TranslationBlock *tb)
-{
-    env->sregs[SR_PC] = tb->pc;
-}
-
diff --git a/target-mips/cpu.h b/target-mips/cpu.h
index 0b98d10..b0ac4da 100644
--- a/target-mips/cpu.h
+++ b/target-mips/cpu.h
@@ -656,4 +656,28 @@ static inline void cpu_set_tls(CPUState *env, target_ulong newtls)
     env->tls_value = newtls;
 }
 
+static inline int cpu_has_work(CPUState *env)
+{
+    int has_work = 0;
+
+    /* It is implementation dependent if non-enabled interrupts
+       wake-up the CPU, however most of the implementations only
+       check for interrupts that can be taken. */
+    if ((env->interrupt_request & CPU_INTERRUPT_HARD) &&
+        cpu_mips_hw_interrupts_pending(env)) {
+        has_work = 1;
+    }
+
+    return has_work;
+}
+
+#include "exec-all.h"
+
+static inline void cpu_pc_from_tb(CPUState *env, TranslationBlock *tb)
+{
+    env->active_tc.PC = tb->pc;
+    env->hflags &= ~MIPS_HFLAG_BMASK;
+    env->hflags |= tb->flags & MIPS_HFLAG_BMASK;
+}
+
 #endif /* !defined (__MIPS_CPU_H__) */
diff --git a/target-mips/exec.h b/target-mips/exec.h
index e908c3f..a3a7262 100644
--- a/target-mips/exec.h
+++ b/target-mips/exec.h
@@ -17,21 +17,6 @@ register struct CPUMIPSState *env asm(AREG0);
 #include "softmmu_exec.h"
 #endif /* !defined(CONFIG_USER_ONLY) */
 
-static inline bool cpu_has_work(CPUState *env)
-{
-    int has_work = 0;
-
-    /* It is implementation dependent if non-enabled interrupts
-       wake-up the CPU, however most of the implementations only
-       check for interrupts that can be taken. */
-    if ((env->interrupt_request & CPU_INTERRUPT_HARD) &&
-        cpu_mips_hw_interrupts_pending(env)) {
-        has_work = 1;
-    }
-
-    return has_work;
-}
-
 static inline void compute_hflags(CPUState *env)
 {
     env->hflags &= ~(MIPS_HFLAG_COP1X | MIPS_HFLAG_64 | MIPS_HFLAG_CP0 |
@@ -73,11 +58,4 @@ static inline void compute_hflags(CPUState *env)
     }
 }
 
-static inline void cpu_pc_from_tb(CPUState *env, TranslationBlock *tb)
-{
-    env->active_tc.PC = tb->pc;
-    env->hflags &= ~MIPS_HFLAG_BMASK;
-    env->hflags |= tb->flags & MIPS_HFLAG_BMASK;
-}
-
 #endif /* !defined(__QEMU_MIPS_EXEC_H__) */
diff --git a/target-ppc/cpu.h b/target-ppc/cpu.h
index 8e4582f..6d60d14 100644
--- a/target-ppc/cpu.h
+++ b/target-ppc/cpu.h
@@ -1999,4 +1999,16 @@ static inline ppcemb_tlb_t *booke206_get_tlbe(CPUState *env, const int tlbn,
 
 extern void (*cpu_ppc_hypercall)(CPUState *);
 
+static inline bool cpu_has_work(CPUState *env)
+{
+    return msr_ee && (env->interrupt_request & CPU_INTERRUPT_HARD);
+}
+
+#include "exec-all.h"
+
+static inline void cpu_pc_from_tb(CPUState *env, TranslationBlock *tb)
+{
+    env->nip = tb->pc;
+}
+
 #endif /* !defined (__CPU_PPC_H__) */
diff --git a/target-ppc/exec.h b/target-ppc/exec.h
index 81c3c54..1e144be 100644
--- a/target-ppc/exec.h
+++ b/target-ppc/exec.h
@@ -32,15 +32,4 @@ register struct CPUPPCState *env asm(AREG0);
 #include "softmmu_exec.h"
 #endif /* !defined(CONFIG_USER_ONLY) */
 
-static inline bool cpu_has_work(CPUState *env)
-{
-    return msr_ee && (env->interrupt_request & CPU_INTERRUPT_HARD);
-}
-
-
-static inline void cpu_pc_from_tb(CPUState *env, TranslationBlock *tb)
-{
-    env->nip = tb->pc;
-}
-
 #endif /* !defined (__PPC_H__) */
diff --git a/target-s390x/cpu.h b/target-s390x/cpu.h
index b5e587f..d48a9b7 100644
--- a/target-s390x/cpu.h
+++ b/target-s390x/cpu.h
@@ -962,4 +962,15 @@ static inline void cpu_inject_ext(CPUState *env, uint32_t code, uint32_t param,
     cpu_interrupt(env, CPU_INTERRUPT_HARD);
 }
 
+static inline bool cpu_has_work(CPUState *env)
+{
+    return (env->interrupt_request & CPU_INTERRUPT_HARD) &&
+        (env->psw.mask & PSW_MASK_EXT);
+}
+
+static inline void cpu_pc_from_tb(CPUState *env, TranslationBlock* tb)
+{
+    env->psw.addr = tb->pc;
+}
+
 #endif
diff --git a/target-s390x/exec.h b/target-s390x/exec.h
index 9ababe1..d40640b 100644
--- a/target-s390x/exec.h
+++ b/target-s390x/exec.h
@@ -29,12 +29,6 @@ register struct CPUS390XState *env asm(AREG0);
 #include "softmmu_exec.h"
 #endif /* !defined(CONFIG_USER_ONLY) */
 
-static inline bool cpu_has_work(CPUState *env)
-{
-    return (env->interrupt_request & CPU_INTERRUPT_HARD) &&
-        (env->psw.mask & PSW_MASK_EXT);
-}
-
 static inline void regs_to_env(void)
 {
 }
@@ -42,9 +36,3 @@ static inline void regs_to_env(void)
 static inline void env_to_regs(void)
 {
 }
-
-static inline void cpu_pc_from_tb(CPUState *env, TranslationBlock* tb)
-{
-    env->psw.addr = tb->pc;
-}
-
diff --git a/target-sh4/cpu.h b/target-sh4/cpu.h
index 74ff97a..00e32f2 100644
--- a/target-sh4/cpu.h
+++ b/target-sh4/cpu.h
@@ -361,4 +361,17 @@ static inline void cpu_get_tb_cpu_state(CPUState *env, target_ulong *pc,
             | (env->movcal_backup ? TB_FLAG_PENDING_MOVCA : 0); /* Bit 4 */
 }
 
+static inline bool cpu_has_work(CPUState *env)
+{
+    return env->interrupt_request & CPU_INTERRUPT_HARD;
+}
+
+#include "exec-all.h"
+
+static inline void cpu_pc_from_tb(CPUState *env, TranslationBlock *tb)
+{
+    env->pc = tb->pc;
+    env->flags = tb->flags;
+}
+
 #endif				/* _CPU_SH4_H */
diff --git a/target-sh4/exec.h b/target-sh4/exec.h
index ff068c5..a537672 100644
--- a/target-sh4/exec.h
+++ b/target-sh4/exec.h
@@ -27,19 +27,8 @@ register struct CPUSH4State *env asm(AREG0);
 #include "cpu.h"
 #include "exec-all.h"
 
-static inline bool cpu_has_work(CPUState *env)
-{
-    return env->interrupt_request & CPU_INTERRUPT_HARD;
-}
-
 #ifndef CONFIG_USER_ONLY
 #include "softmmu_exec.h"
 #endif
 
-static inline void cpu_pc_from_tb(CPUState *env, TranslationBlock *tb)
-{
-    env->pc = tb->pc;
-    env->flags = tb->flags;
-}
-
 #endif				/* _EXEC_SH4_H */
diff --git a/target-sparc/cpu.h b/target-sparc/cpu.h
index 94321f8..4edae78 100644
--- a/target-sparc/cpu.h
+++ b/target-sparc/cpu.h
@@ -662,4 +662,18 @@ static inline void cpu_get_tb_cpu_state(CPUState *env, target_ulong *pc,
 /* helper.c */
 void do_interrupt(CPUState *env);
 
+static inline bool cpu_has_work(CPUState *env1)
+{
+    return (env1->interrupt_request & CPU_INTERRUPT_HARD) &&
+           cpu_interrupts_enabled(env1);
+}
+
+#include "exec-all.h"
+
+static inline void cpu_pc_from_tb(CPUState *env, TranslationBlock *tb)
+{
+    env->pc = tb->pc;
+    env->npc = tb->cs_base;
+}
+
 #endif
diff --git a/target-sparc/exec.h b/target-sparc/exec.h
index c1ac2fd..2395b00 100644
--- a/target-sparc/exec.h
+++ b/target-sparc/exec.h
@@ -12,18 +12,4 @@ register struct CPUSPARCState *env asm(AREG0);
 #include "softmmu_exec.h"
 #endif /* !defined(CONFIG_USER_ONLY) */
 
-/* op_helper.c */
-static inline bool cpu_has_work(CPUState *env1)
-{
-    return (env1->interrupt_request & CPU_INTERRUPT_HARD) &&
-           cpu_interrupts_enabled(env1);
-}
-
-
-static inline void cpu_pc_from_tb(CPUState *env, TranslationBlock *tb)
-{
-    env->pc = tb->pc;
-    env->npc = tb->cs_base;
-}
-
 #endif
diff --git a/target-unicore32/cpu.h b/target-unicore32/cpu.h
index 1e10049..9817607 100644
--- a/target-unicore32/cpu.h
+++ b/target-unicore32/cpu.h
@@ -179,4 +179,10 @@ void uc32_translate_init(void);
 void do_interrupt(CPUState *);
 void switch_mode(CPUState_UniCore32 *, int);
 
+static inline bool cpu_has_work(CPUState *env)
+{
+    return env->interrupt_request &
+        (CPU_INTERRUPT_HARD | CPU_INTERRUPT_EXITTB);
+}
+
 #endif /* __CPU_UC32_H__ */
diff --git a/target-unicore32/exec.h b/target-unicore32/exec.h
index ce4132f..6b9b499 100644
--- a/target-unicore32/exec.h
+++ b/target-unicore32/exec.h
@@ -26,12 +26,6 @@ static inline void regs_to_env(void)
 {
 }
 
-static inline bool cpu_has_work(CPUState *env)
-{
-    return env->interrupt_request &
-        (CPU_INTERRUPT_HARD | CPU_INTERRUPT_EXITTB);
-}
-
 static inline int cpu_halted(CPUState *env)
 {
     if (!env->halted) {
diff --git a/xen-mapcache-stub.c b/xen-mapcache-stub.c
index 8a2380a..5eb3dac 100644
--- a/xen-mapcache-stub.c
+++ b/xen-mapcache-stub.c
@@ -8,6 +8,7 @@
 
 #include "config.h"
 
+#include "cpu.h"
 #include "exec-all.h"
 #include "qemu-common.h"
 #include "cpu-common.h"
commit f3e270377acd074f62e08960ef9444adf67d3590
Author: Blue Swirl <blauwirbel at gmail.com>
Date:   Sat May 21 12:16:05 2011 +0000

    exec.h: fix coding style and change cpu_has_work to return bool
    
    Before the next patch, fix coding style of the areas affected.
    
    Change the type of the return value from cpu_has_work() and
    qemu_cpu_has_work() to bool.
    
    Signed-off-by: Blue Swirl <blauwirbel at gmail.com>

diff --git a/cpu-all.h b/cpu-all.h
index 880f570..e839100 100644
--- a/cpu-all.h
+++ b/cpu-all.h
@@ -847,7 +847,7 @@ void cpu_reset_interrupt(CPUState *env, int mask);
 
 void cpu_exit(CPUState *s);
 
-int qemu_cpu_has_work(CPUState *env);
+bool qemu_cpu_has_work(CPUState *env);
 
 /* Breakpoint/watchpoint flags */
 #define BP_MEM_READ           0x01
diff --git a/cpu-exec.c b/cpu-exec.c
index ecd201e..49de9e0 100644
--- a/cpu-exec.c
+++ b/cpu-exec.c
@@ -32,7 +32,7 @@ int tb_invalidated_flag;
 
 //#define CONFIG_DEBUG_EXEC
 
-int qemu_cpu_has_work(CPUState *env)
+bool qemu_cpu_has_work(CPUState *env)
 {
     return cpu_has_work(env);
 }
diff --git a/target-alpha/exec.h b/target-alpha/exec.h
index 7a325e7..0f9b827 100644
--- a/target-alpha/exec.h
+++ b/target-alpha/exec.h
@@ -37,7 +37,7 @@ register struct CPUAlphaState *env asm(AREG0);
 #include "softmmu_exec.h"
 #endif /* !defined(CONFIG_USER_ONLY) */
 
-static inline int cpu_has_work(CPUState *env)
+static inline bool cpu_has_work(CPUState *env)
 {
     /* Here we are checking to see if the CPU should wake up from HALT.
        We will have gotten into this state only for WTINT from PALmode.  */
diff --git a/target-arm/exec.h b/target-arm/exec.h
index db6608e..9c31418 100644
--- a/target-arm/exec.h
+++ b/target-arm/exec.h
@@ -24,10 +24,10 @@ register struct CPUARMState *env asm(AREG0);
 #include "cpu.h"
 #include "exec-all.h"
 
-static inline int cpu_has_work(CPUState *env)
+static inline bool cpu_has_work(CPUState *env)
 {
-    return (env->interrupt_request &
-            (CPU_INTERRUPT_FIQ | CPU_INTERRUPT_HARD | CPU_INTERRUPT_EXITTB));
+    return env->interrupt_request &
+        (CPU_INTERRUPT_FIQ | CPU_INTERRUPT_HARD | CPU_INTERRUPT_EXITTB);
 }
 
 #if !defined(CONFIG_USER_ONLY)
diff --git a/target-cris/exec.h b/target-cris/exec.h
index 2d5d297..70d99d1 100644
--- a/target-cris/exec.h
+++ b/target-cris/exec.h
@@ -28,9 +28,9 @@ register struct CPUCRISState *env asm(AREG0);
 #include "softmmu_exec.h"
 #endif
 
-static inline int cpu_has_work(CPUState *env)
+static inline bool cpu_has_work(CPUState *env)
 {
-    return (env->interrupt_request & (CPU_INTERRUPT_HARD | CPU_INTERRUPT_NMI));
+    return env->interrupt_request & (CPU_INTERRUPT_HARD | CPU_INTERRUPT_NMI);
 }
 
 static inline void cpu_pc_from_tb(CPUState *env, TranslationBlock *tb)
diff --git a/target-i386/exec.h b/target-i386/exec.h
index 5dbee96..77bb356 100644
--- a/target-i386/exec.h
+++ b/target-i386/exec.h
@@ -160,7 +160,7 @@ static inline void load_eflags(int eflags, int update_mask)
         (eflags & update_mask) | 0x2;
 }
 
-static inline int cpu_has_work(CPUState *env)
+static inline bool cpu_has_work(CPUState *env)
 {
     return ((env->interrupt_request & CPU_INTERRUPT_HARD) &&
             (env->eflags & IF_MASK)) ||
diff --git a/target-lm32/exec.h b/target-lm32/exec.h
index 348b723..83ddb65 100644
--- a/target-lm32/exec.h
+++ b/target-lm32/exec.h
@@ -24,7 +24,7 @@ register struct CPULM32State *env asm(AREG0);
 #include "cpu.h"
 #include "exec-all.h"
 
-static inline int cpu_has_work(CPUState *env)
+static inline bool cpu_has_work(CPUState *env)
 {
     return env->interrupt_request & CPU_INTERRUPT_HARD;
 }
diff --git a/target-m68k/exec.h b/target-m68k/exec.h
index 91daa6b..f7abbf4 100644
--- a/target-m68k/exec.h
+++ b/target-m68k/exec.h
@@ -28,9 +28,9 @@ register struct CPUM68KState *env asm(AREG0);
 #include "softmmu_exec.h"
 #endif
 
-static inline int cpu_has_work(CPUState *env)
+static inline bool cpu_has_work(CPUState *env)
 {
-    return (env->interrupt_request & (CPU_INTERRUPT_HARD));
+    return env->interrupt_request & (CPU_INTERRUPT_HARD);
 }
 
 static inline void cpu_pc_from_tb(CPUState *env, TranslationBlock *tb)
diff --git a/target-microblaze/exec.h b/target-microblaze/exec.h
index 1efff30..bb2b7db 100644
--- a/target-microblaze/exec.h
+++ b/target-microblaze/exec.h
@@ -27,9 +27,9 @@ register struct CPUMBState *env asm(AREG0);
 #include "softmmu_exec.h"
 #endif
 
-static inline int cpu_has_work(CPUState *env)
+static inline bool cpu_has_work(CPUState *env)
 {
-    return (env->interrupt_request & (CPU_INTERRUPT_HARD | CPU_INTERRUPT_NMI));
+    return env->interrupt_request & (CPU_INTERRUPT_HARD | CPU_INTERRUPT_NMI);
 }
 
 static inline void cpu_pc_from_tb(CPUState *env, TranslationBlock *tb)
diff --git a/target-mips/exec.h b/target-mips/exec.h
index 607edf1..e908c3f 100644
--- a/target-mips/exec.h
+++ b/target-mips/exec.h
@@ -17,7 +17,7 @@ register struct CPUMIPSState *env asm(AREG0);
 #include "softmmu_exec.h"
 #endif /* !defined(CONFIG_USER_ONLY) */
 
-static inline int cpu_has_work(CPUState *env)
+static inline bool cpu_has_work(CPUState *env)
 {
     int has_work = 0;
 
diff --git a/target-ppc/exec.h b/target-ppc/exec.h
index f87847a..81c3c54 100644
--- a/target-ppc/exec.h
+++ b/target-ppc/exec.h
@@ -32,9 +32,9 @@ register struct CPUPPCState *env asm(AREG0);
 #include "softmmu_exec.h"
 #endif /* !defined(CONFIG_USER_ONLY) */
 
-static inline int cpu_has_work(CPUState *env)
+static inline bool cpu_has_work(CPUState *env)
 {
-    return (msr_ee && (env->interrupt_request & CPU_INTERRUPT_HARD));
+    return msr_ee && (env->interrupt_request & CPU_INTERRUPT_HARD);
 }
 
 
diff --git a/target-s390x/exec.h b/target-s390x/exec.h
index 7a87fff..9ababe1 100644
--- a/target-s390x/exec.h
+++ b/target-s390x/exec.h
@@ -29,10 +29,10 @@ register struct CPUS390XState *env asm(AREG0);
 #include "softmmu_exec.h"
 #endif /* !defined(CONFIG_USER_ONLY) */
 
-static inline int cpu_has_work(CPUState *env)
+static inline bool cpu_has_work(CPUState *env)
 {
-    return ((env->interrupt_request & CPU_INTERRUPT_HARD) &&
-            (env->psw.mask & PSW_MASK_EXT));
+    return (env->interrupt_request & CPU_INTERRUPT_HARD) &&
+        (env->psw.mask & PSW_MASK_EXT);
 }
 
 static inline void regs_to_env(void)
diff --git a/target-sh4/exec.h b/target-sh4/exec.h
index 9f1c1f6..ff068c5 100644
--- a/target-sh4/exec.h
+++ b/target-sh4/exec.h
@@ -27,9 +27,9 @@ register struct CPUSH4State *env asm(AREG0);
 #include "cpu.h"
 #include "exec-all.h"
 
-static inline int cpu_has_work(CPUState *env)
+static inline bool cpu_has_work(CPUState *env)
 {
-    return (env->interrupt_request & CPU_INTERRUPT_HARD);
+    return env->interrupt_request & CPU_INTERRUPT_HARD;
 }
 
 #ifndef CONFIG_USER_ONLY
diff --git a/target-sparc/exec.h b/target-sparc/exec.h
index becdaf5..c1ac2fd 100644
--- a/target-sparc/exec.h
+++ b/target-sparc/exec.h
@@ -13,7 +13,7 @@ register struct CPUSPARCState *env asm(AREG0);
 #endif /* !defined(CONFIG_USER_ONLY) */
 
 /* op_helper.c */
-static inline int cpu_has_work(CPUState *env1)
+static inline bool cpu_has_work(CPUState *env1)
 {
     return (env1->interrupt_request & CPU_INTERRUPT_HARD) &&
            cpu_interrupts_enabled(env1);
diff --git a/target-unicore32/exec.h b/target-unicore32/exec.h
index 4ab55f4..ce4132f 100644
--- a/target-unicore32/exec.h
+++ b/target-unicore32/exec.h
@@ -26,7 +26,7 @@ static inline void regs_to_env(void)
 {
 }
 
-static inline int cpu_has_work(CPUState *env)
+static inline bool cpu_has_work(CPUState *env)
 {
     return env->interrupt_request &
         (CPU_INTERRUPT_HARD | CPU_INTERRUPT_EXITTB);
commit d8108fb187bb68459cfe7dca4b5c983db33bcc7b
Author: Blue Swirl <blauwirbel at gmail.com>
Date:   Sat May 21 08:17:08 2011 +0000

    cpu-exec: unify do_interrupt call
    
    Now that all targets use common function signature for do_interrupt(), there is no
    need for the #ifdeffery anymore.
    
    Signed-off-by: Blue Swirl <blauwirbel at gmail.com>

diff --git a/cpu-exec.c b/cpu-exec.c
index 6440f12..ecd201e 100644
--- a/cpu-exec.c
+++ b/cpu-exec.c
@@ -271,33 +271,7 @@ int cpu_exec(CPUState *env1)
                     ret = env->exception_index;
                     break;
 #else
-#if defined(TARGET_I386)
-                    do_interrupt(env);
-#elif defined(TARGET_PPC)
-                    do_interrupt(env);
-#elif defined(TARGET_LM32)
-                    do_interrupt(env);
-#elif defined(TARGET_MICROBLAZE)
-                    do_interrupt(env);
-#elif defined(TARGET_MIPS)
-                    do_interrupt(env);
-#elif defined(TARGET_SPARC)
-                    do_interrupt(env);
-#elif defined(TARGET_ARM)
                     do_interrupt(env);
-#elif defined(TARGET_UNICORE32)
-                    do_interrupt(env);
-#elif defined(TARGET_SH4)
-		    do_interrupt(env);
-#elif defined(TARGET_ALPHA)
-                    do_interrupt(env);
-#elif defined(TARGET_CRIS)
-                    do_interrupt(env);
-#elif defined(TARGET_M68K)
-                    do_interrupt(env);
-#elif defined(TARGET_S390X)
-                    do_interrupt(env);
-#endif
                     env->exception_index = -1;
 #endif
                 }
commit 3c688828bcb3afa2744e1f1729a40eef4a575b56
Author: Blue Swirl <blauwirbel at gmail.com>
Date:   Sat May 21 07:55:24 2011 +0000

    m68k: use caller supplied CPUState for interrupt related stuff
    
    Pass CPUState to do_interrupt(). This is needed by later patches.
    
    It would be cleaner to move the function to helper.c, but there are
    a few dependencies between do_interrupt() and other functions.
    
    Signed-off-by: Blue Swirl <blauwirbel at gmail.com>

diff --git a/cpu-exec.c b/cpu-exec.c
index 1f3c4bb..6440f12 100644
--- a/cpu-exec.c
+++ b/cpu-exec.c
@@ -294,7 +294,7 @@ int cpu_exec(CPUState *env1)
 #elif defined(TARGET_CRIS)
                     do_interrupt(env);
 #elif defined(TARGET_M68K)
-                    do_interrupt(0);
+                    do_interrupt(env);
 #elif defined(TARGET_S390X)
                     do_interrupt(env);
 #endif
@@ -529,7 +529,7 @@ int cpu_exec(CPUState *env1)
                            provide/save the vector when the interrupt is
                            first signalled.  */
                         env->exception_index = env->pending_vector;
-                        do_interrupt(1);
+                        do_interrupt_m68k_hardirq(env);
                         next_tb = 0;
                     }
 #elif defined(TARGET_S390X) && !defined(CONFIG_USER_ONLY)
diff --git a/target-m68k/cpu.h b/target-m68k/cpu.h
index b025b66..4d8ba28 100644
--- a/target-m68k/cpu.h
+++ b/target-m68k/cpu.h
@@ -119,7 +119,8 @@ void m68k_tcg_init(void);
 CPUM68KState *cpu_m68k_init(const char *cpu_model);
 int cpu_m68k_exec(CPUM68KState *s);
 void cpu_m68k_close(CPUM68KState *s);
-void do_interrupt(int is_hw);
+void do_interrupt(CPUState *env1);
+void do_interrupt_m68k_hardirq(CPUState *env1);
 /* 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-m68k/op_helper.c b/target-m68k/op_helper.c
index 084a182..237fc4c 100644
--- a/target-m68k/op_helper.c
+++ b/target-m68k/op_helper.c
@@ -21,9 +21,13 @@
 
 #if defined(CONFIG_USER_ONLY)
 
-void do_interrupt(int is_hw)
+void do_interrupt(CPUState *env1)
+{
+    env1->exception_index = -1;
+}
+
+void do_interrupt_m68k_hardirq(CPUState *env1)
 {
-    env->exception_index = -1;
 }
 
 #else
@@ -90,7 +94,7 @@ static void do_rte(void)
     env->aregs[7] = sp + 8;
 }
 
-void do_interrupt(int is_hw)
+static void do_interrupt_all(int is_hw)
 {
     uint32_t sp;
     uint32_t fmt;
@@ -155,6 +159,25 @@ void do_interrupt(int is_hw)
     env->pc = ldl_kernel(env->vbr + vector);
 }
 
+void do_interrupt(CPUState *env1)
+{
+    CPUState *saved_env;
+
+    saved_env = env;
+    env = env1;
+    do_interrupt_all(0);
+    env = saved_env;
+}
+
+void do_interrupt_m68k_hardirq(CPUState *env1)
+{
+    CPUState *saved_env;
+
+    saved_env = env;
+    env = env1;
+    do_interrupt_all(1);
+    env = saved_env;
+}
 #endif
 
 static void raise_exception(int tt)
commit e694d4e289b05d0c9b118850eff961aa9ca33183
Author: Blue Swirl <blauwirbel at gmail.com>
Date:   Mon May 16 19:38:48 2011 +0000

    x86: use caller supplied CPUState for interrupt related stuff
    
    Several x86 specific functions are called from cpu-exec.c with the
    assumption that global env register is valid. This will be changed
    later, so make the functions use caller supplied CPUState parameter.
    
    It would be cleaner to move the functions to helper.c, but there are
    quite a lot of dependencies between do_interrupt() and other functions.
    
    Add helpers for svm_check_intercept() and cpu_cc_compute_all() instead
    of calling the helper (which uses global env, AREG0) directly.
    
    Signed-off-by: Blue Swirl <blauwirbel at gmail.com>

diff --git a/cpu-exec.c b/cpu-exec.c
index d5f492f..1f3c4bb 100644
--- a/cpu-exec.c
+++ b/cpu-exec.c
@@ -266,26 +266,13 @@ int cpu_exec(CPUState *env1)
                        which will be handled outside the cpu execution
                        loop */
 #if defined(TARGET_I386)
-                    do_interrupt_user(env->exception_index,
-                                      env->exception_is_int,
-                                      env->error_code,
-                                      env->exception_next_eip);
-                    /* successfully delivered */
-                    env->old_exception = -1;
+                    do_interrupt(env);
 #endif
                     ret = env->exception_index;
                     break;
 #else
 #if defined(TARGET_I386)
-                    /* simulate a real cpu exception. On i386, it can
-                       trigger new exceptions, but we do not handle
-                       double or triple faults yet. */
-                    do_interrupt(env->exception_index,
-                                 env->exception_is_int,
-                                 env->error_code,
-                                 env->exception_next_eip, 0);
-                    /* successfully delivered */
-                    env->old_exception = -1;
+                    do_interrupt(env);
 #elif defined(TARGET_PPC)
                     do_interrupt(env);
 #elif defined(TARGET_LM32)
@@ -341,7 +328,7 @@ int cpu_exec(CPUState *env1)
 #endif
 #if defined(TARGET_I386)
                     if (interrupt_request & CPU_INTERRUPT_INIT) {
-                            svm_check_intercept(SVM_EXIT_INIT);
+                            svm_check_intercept(env, SVM_EXIT_INIT);
                             do_cpu_init(env);
                             env->exception_index = EXCP_HALTED;
                             cpu_loop_exit(env);
@@ -350,19 +337,19 @@ int cpu_exec(CPUState *env1)
                     } else if (env->hflags2 & HF2_GIF_MASK) {
                         if ((interrupt_request & CPU_INTERRUPT_SMI) &&
                             !(env->hflags & HF_SMM_MASK)) {
-                            svm_check_intercept(SVM_EXIT_SMI);
+                            svm_check_intercept(env, SVM_EXIT_SMI);
                             env->interrupt_request &= ~CPU_INTERRUPT_SMI;
-                            do_smm_enter();
+                            do_smm_enter(env);
                             next_tb = 0;
                         } else if ((interrupt_request & CPU_INTERRUPT_NMI) &&
                                    !(env->hflags2 & HF2_NMI_MASK)) {
                             env->interrupt_request &= ~CPU_INTERRUPT_NMI;
                             env->hflags2 |= HF2_NMI_MASK;
-                            do_interrupt(EXCP02_NMI, 0, 0, 0, 1);
+                            do_interrupt_x86_hardirq(env, EXCP02_NMI, 1);
                             next_tb = 0;
 			} else if (interrupt_request & CPU_INTERRUPT_MCE) {
                             env->interrupt_request &= ~CPU_INTERRUPT_MCE;
-                            do_interrupt(EXCP12_MCHK, 0, 0, 0, 0);
+                            do_interrupt_x86_hardirq(env, EXCP12_MCHK, 0);
                             next_tb = 0;
                         } else if ((interrupt_request & CPU_INTERRUPT_HARD) &&
                                    (((env->hflags2 & HF2_VINTR_MASK) && 
@@ -371,7 +358,7 @@ int cpu_exec(CPUState *env1)
                                      (env->eflags & IF_MASK && 
                                       !(env->hflags & HF_INHIBIT_IRQ_MASK))))) {
                             int intno;
-                            svm_check_intercept(SVM_EXIT_INTR);
+                            svm_check_intercept(env, SVM_EXIT_INTR);
                             env->interrupt_request &= ~(CPU_INTERRUPT_HARD | CPU_INTERRUPT_VIRQ);
                             intno = cpu_get_pic_interrupt(env);
                             qemu_log_mask(CPU_LOG_TB_IN_ASM, "Servicing hardware INT=0x%02x\n", intno);
@@ -380,7 +367,7 @@ int cpu_exec(CPUState *env1)
                     env = cpu_single_env;
 #define env cpu_single_env
 #endif
-                            do_interrupt(intno, 0, 0, 0, 1);
+                            do_interrupt_x86_hardirq(env, intno, 1);
                             /* ensure that no TB jump will be modified as
                                the program flow was changed */
                             next_tb = 0;
@@ -390,10 +377,10 @@ int cpu_exec(CPUState *env1)
                                    !(env->hflags & HF_INHIBIT_IRQ_MASK)) {
                             int intno;
                             /* FIXME: this should respect TPR */
-                            svm_check_intercept(SVM_EXIT_VINTR);
+                            svm_check_intercept(env, SVM_EXIT_VINTR);
                             intno = ldl_phys(env->vm_vmcb + offsetof(struct vmcb, control.int_vector));
                             qemu_log_mask(CPU_LOG_TB_IN_ASM, "Servicing virtual hardware INT=0x%02x\n", intno);
-                            do_interrupt(intno, 0, 0, 0, 1);
+                            do_interrupt_x86_hardirq(env, intno, 1);
                             env->interrupt_request &= ~CPU_INTERRUPT_VIRQ;
                             next_tb = 0;
 #endif
@@ -570,7 +557,8 @@ int cpu_exec(CPUState *env1)
                 if (qemu_loglevel_mask(CPU_LOG_TB_CPU)) {
                     /* restore flags in standard format */
 #if defined(TARGET_I386)
-                    env->eflags = env->eflags | helper_cc_compute_all(CC_OP) | (DF & DF_MASK);
+                    env->eflags = env->eflags | cpu_cc_compute_all(env, CC_OP)
+                        | (DF & DF_MASK);
                     log_cpu_state(env, X86_DUMP_CCOP);
                     env->eflags &= ~(DF_MASK | CC_O | CC_S | CC_Z | CC_A | CC_P | CC_C);
 #elif defined(TARGET_M68K)
@@ -661,7 +649,8 @@ int cpu_exec(CPUState *env1)
 
 #if defined(TARGET_I386)
     /* restore flags in standard format */
-    env->eflags = env->eflags | helper_cc_compute_all(CC_OP) | (DF & DF_MASK);
+    env->eflags = env->eflags | cpu_cc_compute_all(env, CC_OP)
+        | (DF & DF_MASK);
 #elif defined(TARGET_ARM)
     /* XXX: Save/restore host fpu exception state?.  */
 #elif defined(TARGET_UNICORE32)
diff --git a/target-i386/cpu.h b/target-i386/cpu.h
index cdf68ff..656d360 100644
--- a/target-i386/cpu.h
+++ b/target-i386/cpu.h
@@ -1000,4 +1000,14 @@ void cpu_x86_inject_mce(Monitor *mon, CPUState *cenv, int bank,
                         uint64_t status, uint64_t mcg_status, uint64_t addr,
                         uint64_t misc, int flags);
 
+/* op_helper.c */
+void do_interrupt(CPUState *env);
+void do_interrupt_x86_hardirq(CPUState *env, int intno, int is_hw);
+
+void do_smm_enter(CPUState *env1);
+
+void svm_check_intercept(CPUState *env1, uint32_t type);
+
+uint32_t cpu_cc_compute_all(CPUState *env1, int op);
+
 #endif /* CPU_I386_H */
diff --git a/target-i386/exec.h b/target-i386/exec.h
index 9bd080e..5dbee96 100644
--- a/target-i386/exec.h
+++ b/target-i386/exec.h
@@ -67,14 +67,9 @@ register struct CPUX86State *env asm(AREG0);
 #include "exec-all.h"
 
 /* op_helper.c */
-void do_interrupt(int intno, int is_int, int error_code,
-                  target_ulong next_eip, int is_hw);
-void do_interrupt_user(int intno, int is_int, int error_code,
-                       target_ulong next_eip);
 void QEMU_NORETURN raise_exception_err(int exception_index, int error_code);
 void QEMU_NORETURN raise_exception(int exception_index);
 void QEMU_NORETURN raise_exception_env(int exception_index, CPUState *nenv);
-void do_smm_enter(void);
 
 /* n must be a constant to be efficient */
 static inline target_long lshift(target_long x, int n)
@@ -87,11 +82,6 @@ static inline target_long lshift(target_long x, int n)
 
 #include "helper.h"
 
-static inline void svm_check_intercept(uint32_t type)
-{
-    helper_svm_check_intercept_param(type, 0);
-}
-
 #if !defined(CONFIG_USER_ONLY)
 
 #include "softmmu_exec.h"
diff --git a/target-i386/op_helper.c b/target-i386/op_helper.c
index 70a309a..db038a7 100644
--- a/target-i386/op_helper.c
+++ b/target-i386/op_helper.c
@@ -1150,9 +1150,10 @@ static void do_interrupt_real(int intno, int is_int, int error_code,
     env->eflags &= ~(IF_MASK | TF_MASK | AC_MASK | RF_MASK);
 }
 
+#if defined(CONFIG_USER_ONLY)
 /* fake user mode interrupt */
-void do_interrupt_user(int intno, int is_int, int error_code,
-                       target_ulong next_eip)
+static void do_interrupt_user(int intno, int is_int, int error_code,
+                              target_ulong next_eip)
 {
     SegmentCache *dt;
     target_ulong ptr;
@@ -1181,7 +1182,8 @@ void do_interrupt_user(int intno, int is_int, int error_code,
         EIP = next_eip;
 }
 
-#if !defined(CONFIG_USER_ONLY)
+#else
+
 static void handle_even_inj(int intno, int is_int, int error_code,
 		int is_hw, int rm)
 {
@@ -1207,8 +1209,8 @@ static void handle_even_inj(int intno, int is_int, int error_code,
  * the int instruction. next_eip is the EIP value AFTER the interrupt
  * instruction. It is only relevant if is_int is TRUE.
  */
-void do_interrupt(int intno, int is_int, int error_code,
-                  target_ulong next_eip, int is_hw)
+static void do_interrupt_all(int intno, int is_int, int error_code,
+                             target_ulong next_eip, int is_hw)
 {
     if (qemu_loglevel_mask(CPU_LOG_INT)) {
         if ((env->cr[0] & CR0_PE_MASK)) {
@@ -1270,6 +1272,46 @@ void do_interrupt(int intno, int is_int, int error_code,
 #endif
 }
 
+void do_interrupt(CPUState *env1)
+{
+    CPUState *saved_env;
+
+    saved_env = env;
+    env = env1;
+#if defined(CONFIG_USER_ONLY)
+    /* if user mode only, we simulate a fake exception
+       which will be handled outside the cpu execution
+       loop */
+    do_interrupt_user(env->exception_index,
+                      env->exception_is_int,
+                      env->error_code,
+                      env->exception_next_eip);
+    /* successfully delivered */
+    env->old_exception = -1;
+#else
+    /* simulate a real cpu exception. On i386, it can
+       trigger new exceptions, but we do not handle
+       double or triple faults yet. */
+    do_interrupt_all(env->exception_index,
+                     env->exception_is_int,
+                     env->error_code,
+                     env->exception_next_eip, 0);
+    /* successfully delivered */
+    env->old_exception = -1;
+#endif
+    env = saved_env;
+}
+
+void do_interrupt_x86_hardirq(CPUState *env1, int intno, int is_hw)
+{
+    CPUState *saved_env;
+
+    saved_env = env;
+    env = env1;
+    do_interrupt_all(intno, 0, 0, 0, is_hw);
+    env = saved_env;
+}
+
 /* This should come from sysemu.h - if we could include it here... */
 void qemu_system_reset_request(void);
 
@@ -1359,7 +1401,7 @@ void raise_exception_env(int exception_index, CPUState *nenv)
 
 #if defined(CONFIG_USER_ONLY)
 
-void do_smm_enter(void)
+void do_smm_enter(CPUState *env1)
 {
 }
 
@@ -1375,11 +1417,15 @@ void helper_rsm(void)
 #define SMM_REVISION_ID 0x00020000
 #endif
 
-void do_smm_enter(void)
+void do_smm_enter(CPUState *env1)
 {
     target_ulong sm_state;
     SegmentCache *dt;
     int i, offset;
+    CPUState *saved_env;
+
+    saved_env = env;
+    env = env1;
 
     qemu_log_mask(CPU_LOG_INT, "SMM: enter\n");
     log_cpu_state_mask(CPU_LOG_INT, env, X86_DUMP_CCOP);
@@ -1506,6 +1552,7 @@ void do_smm_enter(void)
     cpu_x86_update_cr4(env, 0);
     env->dr[7] = 0x00000400;
     CC_OP = CC_OP_EFLAGS;
+    env = saved_env;
 }
 
 void helper_rsm(void)
@@ -4859,6 +4906,10 @@ void helper_svm_check_intercept_param(uint32_t type, uint64_t param)
 {
 }
 
+void svm_check_intercept(CPUState *env1, uint32_t type)
+{
+}
+
 void helper_svm_check_io(uint32_t port, uint32_t param, 
                          uint32_t next_eip_addend)
 {
@@ -5040,7 +5091,7 @@ void helper_vmrun(int aflag, int next_eip_addend)
                 env->exception_next_eip = -1;
                 qemu_log_mask(CPU_LOG_TB_IN_ASM, "INTR");
                 /* XXX: is it always correct ? */
-                do_interrupt(vector, 0, 0, 0, 1);
+                do_interrupt_all(vector, 0, 0, 0, 1);
                 break;
         case SVM_EVTINJ_TYPE_NMI:
                 env->exception_index = EXCP02_NMI;
@@ -5249,6 +5300,16 @@ void helper_svm_check_intercept_param(uint32_t type, uint64_t param)
     }
 }
 
+void svm_check_intercept(CPUState *env1, uint32_t type)
+{
+    CPUState *saved_env;
+
+    saved_env = env;
+    env = env1;
+    helper_svm_check_intercept_param(type, 0);
+    env = saved_env;
+}
+
 void helper_svm_check_io(uint32_t port, uint32_t param, 
                          uint32_t next_eip_addend)
 {
@@ -5575,6 +5636,18 @@ uint32_t helper_cc_compute_all(int op)
     }
 }
 
+uint32_t cpu_cc_compute_all(CPUState *env1, int op)
+{
+    CPUState *saved_env;
+    uint32_t ret;
+
+    saved_env = env;
+    env = env1;
+    ret = helper_cc_compute_all(op);
+    env = saved_env;
+    return ret;
+}
+
 uint32_t helper_cc_compute_c(int op)
 {
     switch (op) {
commit e67768d0f13c78144f17bcca8a64b9b812918198
Author: Blue Swirl <blauwirbel at gmail.com>
Date:   Sun May 15 16:11:04 2011 +0000

    sparc: move do_interrupt to helper.c
    
    do_interrupt() was mixing CPUState pointer passed from caller
    and global env (AREG0).
    
    Fix by moving the function to helper.c. Introduce a helper for calling
    change_pstate() safely from outside of execution context.
    
    Signed-off-by: Blue Swirl <blauwirbel at gmail.com>

diff --git a/target-sparc/cpu.h b/target-sparc/cpu.h
index a220bf4..94321f8 100644
--- a/target-sparc/cpu.h
+++ b/target-sparc/cpu.h
@@ -476,6 +476,7 @@ target_ulong cpu_get_ccr(CPUState *env1);
 void cpu_put_ccr(CPUState *env1, target_ulong val);
 target_ulong cpu_get_cwp64(CPUState *env1);
 void cpu_put_cwp64(CPUState *env1, int cwp);
+void cpu_change_pstate(CPUState *env1, uint32_t new_pstate);
 #endif
 int cpu_cwp_inc(CPUState *env1, int cwp);
 int cpu_cwp_dec(CPUState *env1, int cwp);
@@ -658,4 +659,7 @@ static inline void cpu_get_tb_cpu_state(CPUState *env, target_ulong *pc,
 #endif
 }
 
+/* helper.c */
+void do_interrupt(CPUState *env);
+
 #endif
diff --git a/target-sparc/exec.h b/target-sparc/exec.h
index f5c221e..becdaf5 100644
--- a/target-sparc/exec.h
+++ b/target-sparc/exec.h
@@ -13,8 +13,6 @@ register struct CPUSPARCState *env asm(AREG0);
 #endif /* !defined(CONFIG_USER_ONLY) */
 
 /* op_helper.c */
-void do_interrupt(CPUState *env);
-
 static inline int cpu_has_work(CPUState *env1)
 {
     return (env1->interrupt_request & CPU_INTERRUPT_HARD) &&
diff --git a/target-sparc/helper.c b/target-sparc/helper.c
index e9b42d0..6b35105 100644
--- a/target-sparc/helper.c
+++ b/target-sparc/helper.c
@@ -729,6 +729,248 @@ target_phys_addr_t cpu_get_phys_page_debug(CPUState *env, target_ulong addr)
 }
 #endif
 
+#ifdef TARGET_SPARC64
+#ifdef DEBUG_PCALL
+static const char * const excp_names[0x80] = {
+    [TT_TFAULT] = "Instruction Access Fault",
+    [TT_TMISS] = "Instruction Access MMU Miss",
+    [TT_CODE_ACCESS] = "Instruction Access Error",
+    [TT_ILL_INSN] = "Illegal Instruction",
+    [TT_PRIV_INSN] = "Privileged Instruction",
+    [TT_NFPU_INSN] = "FPU Disabled",
+    [TT_FP_EXCP] = "FPU Exception",
+    [TT_TOVF] = "Tag Overflow",
+    [TT_CLRWIN] = "Clean Windows",
+    [TT_DIV_ZERO] = "Division By Zero",
+    [TT_DFAULT] = "Data Access Fault",
+    [TT_DMISS] = "Data Access MMU Miss",
+    [TT_DATA_ACCESS] = "Data Access Error",
+    [TT_DPROT] = "Data Protection Error",
+    [TT_UNALIGNED] = "Unaligned Memory Access",
+    [TT_PRIV_ACT] = "Privileged Action",
+    [TT_EXTINT | 0x1] = "External Interrupt 1",
+    [TT_EXTINT | 0x2] = "External Interrupt 2",
+    [TT_EXTINT | 0x3] = "External Interrupt 3",
+    [TT_EXTINT | 0x4] = "External Interrupt 4",
+    [TT_EXTINT | 0x5] = "External Interrupt 5",
+    [TT_EXTINT | 0x6] = "External Interrupt 6",
+    [TT_EXTINT | 0x7] = "External Interrupt 7",
+    [TT_EXTINT | 0x8] = "External Interrupt 8",
+    [TT_EXTINT | 0x9] = "External Interrupt 9",
+    [TT_EXTINT | 0xa] = "External Interrupt 10",
+    [TT_EXTINT | 0xb] = "External Interrupt 11",
+    [TT_EXTINT | 0xc] = "External Interrupt 12",
+    [TT_EXTINT | 0xd] = "External Interrupt 13",
+    [TT_EXTINT | 0xe] = "External Interrupt 14",
+    [TT_EXTINT | 0xf] = "External Interrupt 15",
+};
+#endif
+
+void do_interrupt(CPUState *env)
+{
+    int intno = env->exception_index;
+    trap_state *tsptr;
+
+#ifdef DEBUG_PCALL
+    if (qemu_loglevel_mask(CPU_LOG_INT)) {
+        static int count;
+        const char *name;
+
+        if (intno < 0 || intno >= 0x180) {
+            name = "Unknown";
+        } else if (intno >= 0x100) {
+            name = "Trap Instruction";
+        } else if (intno >= 0xc0) {
+            name = "Window Fill";
+        } else if (intno >= 0x80) {
+            name = "Window Spill";
+        } else {
+            name = excp_names[intno];
+            if (!name) {
+                name = "Unknown";
+            }
+        }
+
+        qemu_log("%6d: %s (v=%04x) pc=%016" PRIx64 " npc=%016" PRIx64
+                " SP=%016" PRIx64 "\n",
+                count, name, intno,
+                env->pc,
+                env->npc, env->regwptr[6]);
+        log_cpu_state(env, 0);
+#if 0
+        {
+            int i;
+            uint8_t *ptr;
+
+            qemu_log("       code=");
+            ptr = (uint8_t *)env->pc;
+            for (i = 0; i < 16; i++) {
+                qemu_log(" %02x", ldub(ptr + i));
+            }
+            qemu_log("\n");
+        }
+#endif
+        count++;
+    }
+#endif
+#if !defined(CONFIG_USER_ONLY)
+    if (env->tl >= env->maxtl) {
+        cpu_abort(env, "Trap 0x%04x while trap level (%d) >= MAXTL (%d),"
+                  " Error state", env->exception_index, env->tl, env->maxtl);
+        return;
+    }
+#endif
+    if (env->tl < env->maxtl - 1) {
+        env->tl++;
+    } else {
+        env->pstate |= PS_RED;
+        if (env->tl < env->maxtl) {
+            env->tl++;
+        }
+    }
+    tsptr = cpu_tsptr(env);
+
+    tsptr->tstate = (cpu_get_ccr(env) << 32) |
+        ((env->asi & 0xff) << 24) | ((env->pstate & 0xf3f) << 8) |
+        cpu_get_cwp64(env);
+    tsptr->tpc = env->pc;
+    tsptr->tnpc = env->npc;
+    tsptr->tt = intno;
+
+    switch (intno) {
+    case TT_IVEC:
+        cpu_change_pstate(env, PS_PEF | PS_PRIV | PS_IG);
+        break;
+    case TT_TFAULT:
+    case TT_DFAULT:
+    case TT_TMISS ... TT_TMISS + 3:
+    case TT_DMISS ... TT_DMISS + 3:
+    case TT_DPROT ... TT_DPROT + 3:
+        cpu_change_pstate(env, PS_PEF | PS_PRIV | PS_MG);
+        break;
+    default:
+        cpu_change_pstate(env, PS_PEF | PS_PRIV | PS_AG);
+        break;
+    }
+
+    if (intno == TT_CLRWIN) {
+        cpu_set_cwp(env, cpu_cwp_dec(env, env->cwp - 1));
+    } else if ((intno & 0x1c0) == TT_SPILL) {
+        cpu_set_cwp(env, cpu_cwp_dec(env, env->cwp - env->cansave - 2));
+    } else if ((intno & 0x1c0) == TT_FILL) {
+        cpu_set_cwp(env, cpu_cwp_inc(env, env->cwp + 1));
+    }
+    env->tbr &= ~0x7fffULL;
+    env->tbr |= ((env->tl > 1) ? 1 << 14 : 0) | (intno << 5);
+    env->pc = env->tbr;
+    env->npc = env->pc + 4;
+    env->exception_index = -1;
+}
+#else
+#ifdef DEBUG_PCALL
+static const char * const excp_names[0x80] = {
+    [TT_TFAULT] = "Instruction Access Fault",
+    [TT_ILL_INSN] = "Illegal Instruction",
+    [TT_PRIV_INSN] = "Privileged Instruction",
+    [TT_NFPU_INSN] = "FPU Disabled",
+    [TT_WIN_OVF] = "Window Overflow",
+    [TT_WIN_UNF] = "Window Underflow",
+    [TT_UNALIGNED] = "Unaligned Memory Access",
+    [TT_FP_EXCP] = "FPU Exception",
+    [TT_DFAULT] = "Data Access Fault",
+    [TT_TOVF] = "Tag Overflow",
+    [TT_EXTINT | 0x1] = "External Interrupt 1",
+    [TT_EXTINT | 0x2] = "External Interrupt 2",
+    [TT_EXTINT | 0x3] = "External Interrupt 3",
+    [TT_EXTINT | 0x4] = "External Interrupt 4",
+    [TT_EXTINT | 0x5] = "External Interrupt 5",
+    [TT_EXTINT | 0x6] = "External Interrupt 6",
+    [TT_EXTINT | 0x7] = "External Interrupt 7",
+    [TT_EXTINT | 0x8] = "External Interrupt 8",
+    [TT_EXTINT | 0x9] = "External Interrupt 9",
+    [TT_EXTINT | 0xa] = "External Interrupt 10",
+    [TT_EXTINT | 0xb] = "External Interrupt 11",
+    [TT_EXTINT | 0xc] = "External Interrupt 12",
+    [TT_EXTINT | 0xd] = "External Interrupt 13",
+    [TT_EXTINT | 0xe] = "External Interrupt 14",
+    [TT_EXTINT | 0xf] = "External Interrupt 15",
+    [TT_TOVF] = "Tag Overflow",
+    [TT_CODE_ACCESS] = "Instruction Access Error",
+    [TT_DATA_ACCESS] = "Data Access Error",
+    [TT_DIV_ZERO] = "Division By Zero",
+    [TT_NCP_INSN] = "Coprocessor Disabled",
+};
+#endif
+
+void do_interrupt(CPUState *env)
+{
+    int cwp, intno = env->exception_index;
+
+#ifdef DEBUG_PCALL
+    if (qemu_loglevel_mask(CPU_LOG_INT)) {
+        static int count;
+        const char *name;
+
+        if (intno < 0 || intno >= 0x100) {
+            name = "Unknown";
+        } else if (intno >= 0x80) {
+            name = "Trap Instruction";
+        } else {
+            name = excp_names[intno];
+            if (!name) {
+                name = "Unknown";
+            }
+        }
+
+        qemu_log("%6d: %s (v=%02x) pc=%08x npc=%08x SP=%08x\n",
+                count, name, intno,
+                env->pc,
+                env->npc, env->regwptr[6]);
+        log_cpu_state(env, 0);
+#if 0
+        {
+            int i;
+            uint8_t *ptr;
+
+            qemu_log("       code=");
+            ptr = (uint8_t *)env->pc;
+            for (i = 0; i < 16; i++) {
+                qemu_log(" %02x", ldub(ptr + i));
+            }
+            qemu_log("\n");
+        }
+#endif
+        count++;
+    }
+#endif
+#if !defined(CONFIG_USER_ONLY)
+    if (env->psret == 0) {
+        cpu_abort(env, "Trap 0x%02x while interrupts disabled, Error state",
+                  env->exception_index);
+        return;
+    }
+#endif
+    env->psret = 0;
+    cwp = cpu_cwp_dec(env, env->cwp - 1);
+    cpu_set_cwp(env, cwp);
+    env->regwptr[9] = env->pc;
+    env->regwptr[10] = env->npc;
+    env->psrps = env->psrs;
+    env->psrs = 1;
+    env->tbr = (env->tbr & TBR_BASE_MASK) | (intno << 4);
+    env->pc = env->tbr;
+    env->npc = env->pc + 4;
+    env->exception_index = -1;
+
+#if !defined(CONFIG_USER_ONLY)
+    /* IRQ acknowledgment */
+    if ((intno & ~15) == TT_EXTINT && env->qemu_irq_ack != NULL) {
+        env->qemu_irq_ack(env->irq_manager, intno);
+    }
+#endif
+}
+#endif
+
 void cpu_reset(CPUSPARCState *env)
 {
     if (qemu_loglevel_mask(CPU_LOG_RESET)) {
diff --git a/target-sparc/op_helper.c b/target-sparc/op_helper.c
index f049e38..fd0cfbd 100644
--- a/target-sparc/op_helper.c
+++ b/target-sparc/op_helper.c
@@ -4029,6 +4029,16 @@ void helper_wrpstate(target_ulong new_state)
 #endif
 }
 
+void cpu_change_pstate(CPUState *env1, uint32_t new_pstate)
+{
+    CPUState *saved_env;
+
+    saved_env = env;
+    env = env1;
+    change_pstate(new_pstate);
+    env = saved_env;
+}
+
 void helper_wrpil(target_ulong new_pil)
 {
 #if !defined(CONFIG_USER_ONLY)
@@ -4115,250 +4125,10 @@ void helper_write_softint(uint64_t value)
 #endif
 
 #ifdef TARGET_SPARC64
-#ifdef DEBUG_PCALL
-static const char * const excp_names[0x80] = {
-    [TT_TFAULT] = "Instruction Access Fault",
-    [TT_TMISS] = "Instruction Access MMU Miss",
-    [TT_CODE_ACCESS] = "Instruction Access Error",
-    [TT_ILL_INSN] = "Illegal Instruction",
-    [TT_PRIV_INSN] = "Privileged Instruction",
-    [TT_NFPU_INSN] = "FPU Disabled",
-    [TT_FP_EXCP] = "FPU Exception",
-    [TT_TOVF] = "Tag Overflow",
-    [TT_CLRWIN] = "Clean Windows",
-    [TT_DIV_ZERO] = "Division By Zero",
-    [TT_DFAULT] = "Data Access Fault",
-    [TT_DMISS] = "Data Access MMU Miss",
-    [TT_DATA_ACCESS] = "Data Access Error",
-    [TT_DPROT] = "Data Protection Error",
-    [TT_UNALIGNED] = "Unaligned Memory Access",
-    [TT_PRIV_ACT] = "Privileged Action",
-    [TT_EXTINT | 0x1] = "External Interrupt 1",
-    [TT_EXTINT | 0x2] = "External Interrupt 2",
-    [TT_EXTINT | 0x3] = "External Interrupt 3",
-    [TT_EXTINT | 0x4] = "External Interrupt 4",
-    [TT_EXTINT | 0x5] = "External Interrupt 5",
-    [TT_EXTINT | 0x6] = "External Interrupt 6",
-    [TT_EXTINT | 0x7] = "External Interrupt 7",
-    [TT_EXTINT | 0x8] = "External Interrupt 8",
-    [TT_EXTINT | 0x9] = "External Interrupt 9",
-    [TT_EXTINT | 0xa] = "External Interrupt 10",
-    [TT_EXTINT | 0xb] = "External Interrupt 11",
-    [TT_EXTINT | 0xc] = "External Interrupt 12",
-    [TT_EXTINT | 0xd] = "External Interrupt 13",
-    [TT_EXTINT | 0xe] = "External Interrupt 14",
-    [TT_EXTINT | 0xf] = "External Interrupt 15",
-};
-#endif
-
 trap_state* cpu_tsptr(CPUState* env)
 {
     return &env->ts[env->tl & MAXTL_MASK];
 }
-
-void do_interrupt(CPUState *env)
-{
-    int intno = env->exception_index;
-    trap_state *tsptr;
-
-#ifdef DEBUG_PCALL
-    if (qemu_loglevel_mask(CPU_LOG_INT)) {
-        static int count;
-        const char *name;
-
-        if (intno < 0 || intno >= 0x180) {
-            name = "Unknown";
-        } else if (intno >= 0x100) {
-            name = "Trap Instruction";
-        } else if (intno >= 0xc0) {
-            name = "Window Fill";
-        } else if (intno >= 0x80) {
-            name = "Window Spill";
-        } else {
-            name = excp_names[intno];
-            if (!name) {
-                name = "Unknown";
-            }
-        }
-
-        qemu_log("%6d: %s (v=%04x) pc=%016" PRIx64 " npc=%016" PRIx64
-                " SP=%016" PRIx64 "\n",
-                count, name, intno,
-                env->pc,
-                env->npc, env->regwptr[6]);
-        log_cpu_state(env, 0);
-#if 0
-        {
-            int i;
-            uint8_t *ptr;
-
-            qemu_log("       code=");
-            ptr = (uint8_t *)env->pc;
-            for (i = 0; i < 16; i++) {
-                qemu_log(" %02x", ldub(ptr + i));
-            }
-            qemu_log("\n");
-        }
-#endif
-        count++;
-    }
-#endif
-#if !defined(CONFIG_USER_ONLY)
-    if (env->tl >= env->maxtl) {
-        cpu_abort(env, "Trap 0x%04x while trap level (%d) >= MAXTL (%d),"
-                  " Error state", env->exception_index, env->tl, env->maxtl);
-        return;
-    }
-#endif
-    if (env->tl < env->maxtl - 1) {
-        env->tl++;
-    } else {
-        env->pstate |= PS_RED;
-        if (env->tl < env->maxtl) {
-            env->tl++;
-        }
-    }
-    tsptr = cpu_tsptr(env);
-
-    tsptr->tstate = (get_ccr() << 32) |
-        ((env->asi & 0xff) << 24) | ((env->pstate & 0xf3f) << 8) |
-        get_cwp64();
-    tsptr->tpc = env->pc;
-    tsptr->tnpc = env->npc;
-    tsptr->tt = intno;
-
-    switch (intno) {
-    case TT_IVEC:
-        change_pstate(PS_PEF | PS_PRIV | PS_IG);
-        break;
-    case TT_TFAULT:
-    case TT_DFAULT:
-    case TT_TMISS ... TT_TMISS + 3:
-    case TT_DMISS ... TT_DMISS + 3:
-    case TT_DPROT ... TT_DPROT + 3:
-        change_pstate(PS_PEF | PS_PRIV | PS_MG);
-        break;
-    default:
-        change_pstate(PS_PEF | PS_PRIV | PS_AG);
-        break;
-    }
-
-    if (intno == TT_CLRWIN) {
-        set_cwp(cwp_dec(env->cwp - 1));
-    } else if ((intno & 0x1c0) == TT_SPILL) {
-        set_cwp(cwp_dec(env->cwp - env->cansave - 2));
-    } else if ((intno & 0x1c0) == TT_FILL) {
-        set_cwp(cwp_inc(env->cwp + 1));
-    }
-    env->tbr &= ~0x7fffULL;
-    env->tbr |= ((env->tl > 1) ? 1 << 14 : 0) | (intno << 5);
-    env->pc = env->tbr;
-    env->npc = env->pc + 4;
-    env->exception_index = -1;
-}
-#else
-#ifdef DEBUG_PCALL
-static const char * const excp_names[0x80] = {
-    [TT_TFAULT] = "Instruction Access Fault",
-    [TT_ILL_INSN] = "Illegal Instruction",
-    [TT_PRIV_INSN] = "Privileged Instruction",
-    [TT_NFPU_INSN] = "FPU Disabled",
-    [TT_WIN_OVF] = "Window Overflow",
-    [TT_WIN_UNF] = "Window Underflow",
-    [TT_UNALIGNED] = "Unaligned Memory Access",
-    [TT_FP_EXCP] = "FPU Exception",
-    [TT_DFAULT] = "Data Access Fault",
-    [TT_TOVF] = "Tag Overflow",
-    [TT_EXTINT | 0x1] = "External Interrupt 1",
-    [TT_EXTINT | 0x2] = "External Interrupt 2",
-    [TT_EXTINT | 0x3] = "External Interrupt 3",
-    [TT_EXTINT | 0x4] = "External Interrupt 4",
-    [TT_EXTINT | 0x5] = "External Interrupt 5",
-    [TT_EXTINT | 0x6] = "External Interrupt 6",
-    [TT_EXTINT | 0x7] = "External Interrupt 7",
-    [TT_EXTINT | 0x8] = "External Interrupt 8",
-    [TT_EXTINT | 0x9] = "External Interrupt 9",
-    [TT_EXTINT | 0xa] = "External Interrupt 10",
-    [TT_EXTINT | 0xb] = "External Interrupt 11",
-    [TT_EXTINT | 0xc] = "External Interrupt 12",
-    [TT_EXTINT | 0xd] = "External Interrupt 13",
-    [TT_EXTINT | 0xe] = "External Interrupt 14",
-    [TT_EXTINT | 0xf] = "External Interrupt 15",
-    [TT_TOVF] = "Tag Overflow",
-    [TT_CODE_ACCESS] = "Instruction Access Error",
-    [TT_DATA_ACCESS] = "Data Access Error",
-    [TT_DIV_ZERO] = "Division By Zero",
-    [TT_NCP_INSN] = "Coprocessor Disabled",
-};
-#endif
-
-void do_interrupt(CPUState *env)
-{
-    int cwp, intno = env->exception_index;
-
-#ifdef DEBUG_PCALL
-    if (qemu_loglevel_mask(CPU_LOG_INT)) {
-        static int count;
-        const char *name;
-
-        if (intno < 0 || intno >= 0x100) {
-            name = "Unknown";
-        } else if (intno >= 0x80) {
-            name = "Trap Instruction";
-        } else {
-            name = excp_names[intno];
-            if (!name) {
-                name = "Unknown";
-            }
-        }
-
-        qemu_log("%6d: %s (v=%02x) pc=%08x npc=%08x SP=%08x\n",
-                count, name, intno,
-                env->pc,
-                env->npc, env->regwptr[6]);
-        log_cpu_state(env, 0);
-#if 0
-        {
-            int i;
-            uint8_t *ptr;
-
-            qemu_log("       code=");
-            ptr = (uint8_t *)env->pc;
-            for (i = 0; i < 16; i++) {
-                qemu_log(" %02x", ldub(ptr + i));
-            }
-            qemu_log("\n");
-        }
-#endif
-        count++;
-    }
-#endif
-#if !defined(CONFIG_USER_ONLY)
-    if (env->psret == 0) {
-        cpu_abort(env, "Trap 0x%02x while interrupts disabled, Error state",
-                  env->exception_index);
-        return;
-    }
-#endif
-    env->psret = 0;
-    cwp = cwp_dec(env->cwp - 1);
-    set_cwp(cwp);
-    env->regwptr[9] = env->pc;
-    env->regwptr[10] = env->npc;
-    env->psrps = env->psrs;
-    env->psrs = 1;
-    env->tbr = (env->tbr & TBR_BASE_MASK) | (intno << 4);
-    env->pc = env->tbr;
-    env->npc = env->pc + 4;
-    env->exception_index = -1;
-
-#if !defined(CONFIG_USER_ONLY)
-    /* IRQ acknowledgment */
-    if ((intno & ~15) == TT_EXTINT && env->qemu_irq_ack != NULL) {
-        env->qemu_irq_ack(env->irq_manager, intno);
-    }
-#endif
-}
 #endif
 
 #if !defined(CONFIG_USER_ONLY)
commit fa3c9559dbb102340cd1e0b1428e192fed4b0ee3
Author: Blue Swirl <blauwirbel at gmail.com>
Date:   Sat May 21 11:41:50 2011 +0000

    sparc: fix coding style of the area to be moved
    
    Before the next patch, fix coding style of the areas affected.
    
    Signed-off-by: Blue Swirl <blauwirbel at gmail.com>

diff --git a/target-sparc/op_helper.c b/target-sparc/op_helper.c
index 52a894e..f049e38 100644
--- a/target-sparc/op_helper.c
+++ b/target-sparc/op_helper.c
@@ -4159,25 +4159,26 @@ trap_state* cpu_tsptr(CPUState* env)
 void do_interrupt(CPUState *env)
 {
     int intno = env->exception_index;
-    trap_state* tsptr;
+    trap_state *tsptr;
 
 #ifdef DEBUG_PCALL
     if (qemu_loglevel_mask(CPU_LOG_INT)) {
         static int count;
         const char *name;
 
-        if (intno < 0 || intno >= 0x180)
+        if (intno < 0 || intno >= 0x180) {
             name = "Unknown";
-        else if (intno >= 0x100)
+        } else if (intno >= 0x100) {
             name = "Trap Instruction";
-        else if (intno >= 0xc0)
+        } else if (intno >= 0xc0) {
             name = "Window Fill";
-        else if (intno >= 0x80)
+        } else if (intno >= 0x80) {
             name = "Window Spill";
-        else {
+        } else {
             name = excp_names[intno];
-            if (!name)
+            if (!name) {
                 name = "Unknown";
+            }
         }
 
         qemu_log("%6d: %s (v=%04x) pc=%016" PRIx64 " npc=%016" PRIx64
@@ -4193,7 +4194,7 @@ void do_interrupt(CPUState *env)
 
             qemu_log("       code=");
             ptr = (uint8_t *)env->pc;
-            for(i = 0; i < 16; i++) {
+            for (i = 0; i < 16; i++) {
                 qemu_log(" %02x", ldub(ptr + i));
             }
             qemu_log("\n");
@@ -4213,8 +4214,9 @@ void do_interrupt(CPUState *env)
         env->tl++;
     } else {
         env->pstate |= PS_RED;
-        if (env->tl < env->maxtl)
+        if (env->tl < env->maxtl) {
             env->tl++;
+        }
     }
     tsptr = cpu_tsptr(env);
 
@@ -4299,14 +4301,15 @@ void do_interrupt(CPUState *env)
         static int count;
         const char *name;
 
-        if (intno < 0 || intno >= 0x100)
+        if (intno < 0 || intno >= 0x100) {
             name = "Unknown";
-        else if (intno >= 0x80)
+        } else if (intno >= 0x80) {
             name = "Trap Instruction";
-        else {
+        } else {
             name = excp_names[intno];
-            if (!name)
+            if (!name) {
                 name = "Unknown";
+            }
         }
 
         qemu_log("%6d: %s (v=%02x) pc=%08x npc=%08x SP=%08x\n",
@@ -4321,7 +4324,7 @@ void do_interrupt(CPUState *env)
 
             qemu_log("       code=");
             ptr = (uint8_t *)env->pc;
-            for(i = 0; i < 16; i++) {
+            for (i = 0; i < 16; i++) {
                 qemu_log(" %02x", ldub(ptr + i));
             }
             qemu_log("\n");
commit 1162c041c11a49b8ba50bf5f73a72352421787a8
Author: Blue Swirl <blauwirbel at gmail.com>
Date:   Sat May 14 12:52:35 2011 +0000

    cpu_loop_exit: avoid using AREG0
    
    Make cpu_loop_exit() take a parameter for CPUState instead of relying
    on global env.
    
    Signed-off-by: Blue Swirl <blauwirbel at gmail.com>

diff --git a/cpu-exec.c b/cpu-exec.c
index 7aa1d00..d5f492f 100644
--- a/cpu-exec.c
+++ b/cpu-exec.c
@@ -37,10 +37,10 @@ int qemu_cpu_has_work(CPUState *env)
     return cpu_has_work(env);
 }
 
-void cpu_loop_exit(void)
+void cpu_loop_exit(CPUState *env1)
 {
-    env->current_tb = NULL;
-    longjmp(env->jmp_env, 1);
+    env1->current_tb = NULL;
+    longjmp(env1->jmp_env, 1);
 }
 
 /* exit the current TB from a signal handler. The host registers are
@@ -327,7 +327,7 @@ int cpu_exec(CPUState *env1)
                     if (interrupt_request & CPU_INTERRUPT_DEBUG) {
                         env->interrupt_request &= ~CPU_INTERRUPT_DEBUG;
                         env->exception_index = EXCP_DEBUG;
-                        cpu_loop_exit();
+                        cpu_loop_exit(env);
                     }
 #if defined(TARGET_ARM) || defined(TARGET_SPARC) || defined(TARGET_MIPS) || \
     defined(TARGET_PPC) || defined(TARGET_ALPHA) || defined(TARGET_CRIS) || \
@@ -336,7 +336,7 @@ int cpu_exec(CPUState *env1)
                         env->interrupt_request &= ~CPU_INTERRUPT_HALT;
                         env->halted = 1;
                         env->exception_index = EXCP_HLT;
-                        cpu_loop_exit();
+                        cpu_loop_exit(env);
                     }
 #endif
 #if defined(TARGET_I386)
@@ -344,7 +344,7 @@ int cpu_exec(CPUState *env1)
                             svm_check_intercept(SVM_EXIT_INIT);
                             do_cpu_init(env);
                             env->exception_index = EXCP_HALTED;
-                            cpu_loop_exit();
+                            cpu_loop_exit(env);
                     } else if (interrupt_request & CPU_INTERRUPT_SIPI) {
                             do_cpu_sipi(env);
                     } else if (env->hflags2 & HF2_GIF_MASK) {
@@ -564,7 +564,7 @@ int cpu_exec(CPUState *env1)
                 if (unlikely(env->exit_request)) {
                     env->exit_request = 0;
                     env->exception_index = EXCP_INTERRUPT;
-                    cpu_loop_exit();
+                    cpu_loop_exit(env);
                 }
 #if defined(DEBUG_DISAS) || defined(CONFIG_DEBUG_EXEC)
                 if (qemu_loglevel_mask(CPU_LOG_TB_CPU)) {
@@ -647,7 +647,7 @@ int cpu_exec(CPUState *env1)
                             }
                             env->exception_index = EXCP_INTERRUPT;
                             next_tb = 0;
-                            cpu_loop_exit();
+                            cpu_loop_exit(env);
                         }
                     }
                 }
diff --git a/exec-all.h b/exec-all.h
index 2a13a95..efef1cd 100644
--- a/exec-all.h
+++ b/exec-all.h
@@ -95,7 +95,7 @@ TranslationBlock *tb_gen_code(CPUState *env,
                               target_ulong pc, target_ulong cs_base, int flags,
                               int cflags);
 void cpu_exec_init(CPUState *env);
-void QEMU_NORETURN cpu_loop_exit(void);
+void QEMU_NORETURN cpu_loop_exit(CPUState *env1);
 int page_unprotect(target_ulong address, unsigned long pc, void *puc);
 void tb_invalidate_phys_page_range(tb_page_addr_t start, tb_page_addr_t end,
                                    int is_cpu_write_access);
diff --git a/target-alpha/op_helper.c b/target-alpha/op_helper.c
index d332719..51d1bd7 100644
--- a/target-alpha/op_helper.c
+++ b/target-alpha/op_helper.c
@@ -32,7 +32,7 @@ void QEMU_NORETURN helper_excp(int excp, int error)
 {
     env->exception_index = excp;
     env->error_code = error;
-    cpu_loop_exit();
+    cpu_loop_exit(env);
 }
 
 static void do_restore_state(void *retaddr)
@@ -53,7 +53,7 @@ static void QEMU_NORETURN dynamic_excp(int excp, int error)
     env->exception_index = excp;
     env->error_code = error;
     do_restore_state(GETPC());
-    cpu_loop_exit();
+    cpu_loop_exit(env);
 }
 
 static void QEMU_NORETURN arith_excp(int exc, uint64_t mask)
@@ -1341,7 +1341,7 @@ void tlb_fill (target_ulong addr, int is_write, int mmu_idx, void *retaddr)
     if (unlikely(ret != 0)) {
         do_restore_state(retaddr);
         /* Exception index and error code are already set */
-        cpu_loop_exit();
+        cpu_loop_exit(env);
     }
     env = saved_env;
 }
diff --git a/target-arm/op_helper.c b/target-arm/op_helper.c
index 8334fbc..4635884 100644
--- a/target-arm/op_helper.c
+++ b/target-arm/op_helper.c
@@ -25,7 +25,7 @@
 void raise_exception(int tt)
 {
     env->exception_index = tt;
-    cpu_loop_exit();
+    cpu_loop_exit(env);
 }
 
 uint32_t HELPER(neon_tbl)(uint32_t ireg, uint32_t def,
@@ -234,13 +234,13 @@ void HELPER(wfi)(void)
 {
     env->exception_index = EXCP_HLT;
     env->halted = 1;
-    cpu_loop_exit();
+    cpu_loop_exit(env);
 }
 
 void HELPER(exception)(uint32_t excp)
 {
     env->exception_index = excp;
-    cpu_loop_exit();
+    cpu_loop_exit(env);
 }
 
 uint32_t HELPER(cpsr_read)(void)
diff --git a/target-cris/op_helper.c b/target-cris/op_helper.c
index 34329e2..b3ddd33 100644
--- a/target-cris/op_helper.c
+++ b/target-cris/op_helper.c
@@ -83,7 +83,7 @@ void tlb_fill (target_ulong addr, int is_write, int mmu_idx, void *retaddr)
                 helper_top_evaluate_flags();
             }
         }
-        cpu_loop_exit();
+        cpu_loop_exit(env);
     }
     env = saved_env;
 }
@@ -93,7 +93,7 @@ void tlb_fill (target_ulong addr, int is_write, int mmu_idx, void *retaddr)
 void helper_raise_exception(uint32_t index)
 {
 	env->exception_index = index;
-	cpu_loop_exit();
+        cpu_loop_exit(env);
 }
 
 void helper_tlb_flush_pid(uint32_t pid)
diff --git a/target-i386/op_helper.c b/target-i386/op_helper.c
index cec0c76..70a309a 100644
--- a/target-i386/op_helper.c
+++ b/target-i386/op_helper.c
@@ -1000,7 +1000,7 @@ void helper_syscall(int next_eip_addend)
 {
     env->exception_index = EXCP_SYSCALL;
     env->exception_next_eip = env->eip + next_eip_addend;
-    cpu_loop_exit();
+    cpu_loop_exit(env);
 }
 #else
 void helper_syscall(int next_eip_addend)
@@ -1335,7 +1335,7 @@ static void QEMU_NORETURN raise_interrupt(int intno, int is_int, int error_code,
     env->error_code = error_code;
     env->exception_is_int = is_int;
     env->exception_next_eip = env->eip + next_eip_addend;
-    cpu_loop_exit();
+    cpu_loop_exit(env);
 }
 
 /* shortcuts to generate exceptions */
@@ -4658,7 +4658,7 @@ static void do_hlt(void)
     env->hflags &= ~HF_INHIBIT_IRQ_MASK; /* needed if sti is just before */
     env->halted = 1;
     env->exception_index = EXCP_HLT;
-    cpu_loop_exit();
+    cpu_loop_exit(env);
 }
 
 void helper_hlt(int next_eip_addend)
@@ -4696,7 +4696,7 @@ void helper_mwait(int next_eip_addend)
 void helper_debug(void)
 {
     env->exception_index = EXCP_DEBUG;
-    cpu_loop_exit();
+    cpu_loop_exit(env);
 }
 
 void helper_reset_rf(void)
@@ -5048,7 +5048,7 @@ void helper_vmrun(int aflag, int next_eip_addend)
                 env->exception_is_int = 0;
                 env->exception_next_eip = EIP;
                 qemu_log_mask(CPU_LOG_TB_IN_ASM, "NMI");
-                cpu_loop_exit();
+                cpu_loop_exit(env);
                 break;
         case SVM_EVTINJ_TYPE_EXEPT:
                 env->exception_index = vector;
@@ -5056,7 +5056,7 @@ void helper_vmrun(int aflag, int next_eip_addend)
                 env->exception_is_int = 0;
                 env->exception_next_eip = -1;
                 qemu_log_mask(CPU_LOG_TB_IN_ASM, "EXEPT");
-                cpu_loop_exit();
+                cpu_loop_exit(env);
                 break;
         case SVM_EVTINJ_TYPE_SOFT:
                 env->exception_index = vector;
@@ -5064,7 +5064,7 @@ void helper_vmrun(int aflag, int next_eip_addend)
                 env->exception_is_int = 1;
                 env->exception_next_eip = EIP;
                 qemu_log_mask(CPU_LOG_TB_IN_ASM, "SOFT");
-                cpu_loop_exit();
+                cpu_loop_exit(env);
                 break;
         }
         qemu_log_mask(CPU_LOG_TB_IN_ASM, " %#x %#x\n", env->exception_index, env->error_code);
@@ -5400,7 +5400,7 @@ void helper_vmexit(uint32_t exit_code, uint64_t exit_info_1)
     env->error_code = 0;
     env->old_exception = -1;
 
-    cpu_loop_exit();
+    cpu_loop_exit(env);
 }
 
 #endif
diff --git a/target-lm32/op_helper.c b/target-lm32/op_helper.c
index c72b1df..a34cecd 100644
--- a/target-lm32/op_helper.c
+++ b/target-lm32/op_helper.c
@@ -20,14 +20,14 @@
 void helper_raise_exception(uint32_t index)
 {
     env->exception_index = index;
-    cpu_loop_exit();
+    cpu_loop_exit(env);
 }
 
 void helper_hlt(void)
 {
     env->halted = 1;
     env->exception_index = EXCP_HLT;
-    cpu_loop_exit();
+    cpu_loop_exit(env);
 }
 
 void helper_wcsr_im(uint32_t im)
@@ -98,7 +98,7 @@ void tlb_fill(target_ulong addr, int is_write, int mmu_idx, void *retaddr)
                 cpu_restore_state(tb, env, pc);
             }
         }
-        cpu_loop_exit();
+        cpu_loop_exit(env);
     }
     env = saved_env;
 }
diff --git a/target-m68k/op_helper.c b/target-m68k/op_helper.c
index 9b13bdb..084a182 100644
--- a/target-m68k/op_helper.c
+++ b/target-m68k/op_helper.c
@@ -71,7 +71,7 @@ void tlb_fill (target_ulong addr, int is_write, int mmu_idx, void *retaddr)
                 cpu_restore_state(tb, env, pc);
             }
         }
-        cpu_loop_exit();
+        cpu_loop_exit(env);
     }
     env = saved_env;
 }
@@ -118,7 +118,7 @@ void do_interrupt(int is_hw)
             }
             env->halted = 1;
             env->exception_index = EXCP_HLT;
-            cpu_loop_exit();
+            cpu_loop_exit(env);
             return;
         }
         if (env->exception_index >= EXCP_TRAP0
@@ -160,7 +160,7 @@ void do_interrupt(int is_hw)
 static void raise_exception(int tt)
 {
     env->exception_index = tt;
-    cpu_loop_exit();
+    cpu_loop_exit(env);
 }
 
 void HELPER(raise_exception)(uint32_t tt)
diff --git a/target-microblaze/op_helper.c b/target-microblaze/op_helper.c
index c7b2f97..1a0a476 100644
--- a/target-microblaze/op_helper.c
+++ b/target-microblaze/op_helper.c
@@ -63,7 +63,7 @@ void tlb_fill (target_ulong addr, int is_write, int mmu_idx, void *retaddr)
                 cpu_restore_state(tb, env, pc);
             }
         }
-        cpu_loop_exit();
+        cpu_loop_exit(env);
     }
     env = saved_env;
 }
@@ -107,7 +107,7 @@ uint32_t helper_get(uint32_t id, uint32_t ctrl)
 void helper_raise_exception(uint32_t index)
 {
     env->exception_index = index;
-    cpu_loop_exit();
+    cpu_loop_exit(env);
 }
 
 void helper_debug(void)
diff --git a/target-mips/op_helper.c b/target-mips/op_helper.c
index b8e4991..6b966b1 100644
--- a/target-mips/op_helper.c
+++ b/target-mips/op_helper.c
@@ -38,7 +38,7 @@ void helper_raise_exception_err (uint32_t exception, int error_code)
 #endif
     env->exception_index = exception;
     env->error_code = error_code;
-    cpu_loop_exit();
+    cpu_loop_exit(env);
 }
 
 void helper_raise_exception (uint32_t exception)
@@ -277,7 +277,7 @@ static inline target_phys_addr_t do_translate_address(target_ulong address, int
     lladdr = cpu_mips_translate_address(env, address, rw);
 
     if (lladdr == -1LL) {
-        cpu_loop_exit();
+        cpu_loop_exit(env);
     } else {
         return lladdr;
     }
diff --git a/target-ppc/op_helper.c b/target-ppc/op_helper.c
index 15d9222..29f72e1 100644
--- a/target-ppc/op_helper.c
+++ b/target-ppc/op_helper.c
@@ -44,7 +44,7 @@ void helper_raise_exception_err (uint32_t exception, uint32_t error_code)
 #endif
     env->exception_index = exception;
     env->error_code = error_code;
-    cpu_loop_exit();
+    cpu_loop_exit(env);
 }
 
 void helper_raise_exception (uint32_t exception)
diff --git a/target-s390x/op_helper.c b/target-s390x/op_helper.c
index 6a3c1f6..cd33f99 100644
--- a/target-s390x/op_helper.c
+++ b/target-s390x/op_helper.c
@@ -73,7 +73,7 @@ void tlb_fill (target_ulong addr, int is_write, int mmu_idx, void *retaddr)
                 cpu_restore_state(tb, env, pc);
             }
         }
-        cpu_loop_exit();
+        cpu_loop_exit(env);
     }
     env = saved_env;
 }
@@ -92,7 +92,7 @@ void HELPER(exception)(uint32_t excp)
 {
     HELPER_LOG("%s: exception %d\n", __FUNCTION__, excp);
     env->exception_index = excp;
-    cpu_loop_exit();
+    cpu_loop_exit(env);
 }
 
 #ifndef CONFIG_USER_ONLY
@@ -2326,7 +2326,7 @@ void HELPER(tr)(uint32_t len, uint64_t array, uint64_t trans)
 void HELPER(load_psw)(uint64_t mask, uint64_t addr)
 {
     load_psw(env, mask, addr);
-    cpu_loop_exit();
+    cpu_loop_exit(env);
 }
 
 static void program_interrupt(CPUState *env, uint32_t code, int ilc)
@@ -2341,7 +2341,7 @@ static void program_interrupt(CPUState *env, uint32_t code, int ilc)
         env->int_pgm_code = code;
         env->int_pgm_ilc = ilc;
         env->exception_index = EXCP_PGM;
-        cpu_loop_exit();
+        cpu_loop_exit(env);
     }
 }
 
@@ -2828,12 +2828,12 @@ static uint32_t mvc_asc(int64_t l, uint64_t a1, uint64_t mode1, uint64_t a2,
     }
 
     if (mmu_translate(env, a1 & TARGET_PAGE_MASK, 1, mode1, &dest, &flags)) {
-        cpu_loop_exit();
+        cpu_loop_exit(env);
     }
     dest |= a1 & ~TARGET_PAGE_MASK;
 
     if (mmu_translate(env, a2 & TARGET_PAGE_MASK, 0, mode2, &src, &flags)) {
-        cpu_loop_exit();
+        cpu_loop_exit(env);
     }
     src |= a2 & ~TARGET_PAGE_MASK;
 
diff --git a/target-sh4/op_helper.c b/target-sh4/op_helper.c
index b909d18..a932225 100644
--- a/target-sh4/op_helper.c
+++ b/target-sh4/op_helper.c
@@ -66,7 +66,7 @@ void tlb_fill(target_ulong addr, int is_write, int mmu_idx, void *retaddr)
     if (ret) {
         /* now we have a real cpu fault */
         cpu_restore_state_from_retaddr(retaddr);
-	cpu_loop_exit();
+        cpu_loop_exit(env);
     }
     env = saved_env;
 }
@@ -87,7 +87,7 @@ static inline void raise_exception(int index, void *retaddr)
 {
     env->exception_index = index;
     cpu_restore_state_from_retaddr(retaddr);
-    cpu_loop_exit();
+    cpu_loop_exit(env);
 }
 
 void helper_raise_illegal_instruction(void)
@@ -113,7 +113,7 @@ void helper_raise_slot_fpu_disable(void)
 void helper_debug(void)
 {
     env->exception_index = EXCP_DEBUG;
-    cpu_loop_exit();
+    cpu_loop_exit(env);
 }
 
 void helper_sleep(uint32_t next_pc)
@@ -122,7 +122,7 @@ void helper_sleep(uint32_t next_pc)
     env->in_sleep = 1;
     env->exception_index = EXCP_HLT;
     env->pc = next_pc;
-    cpu_loop_exit();
+    cpu_loop_exit(env);
 }
 
 void helper_trapa(uint32_t tra)
@@ -482,7 +482,7 @@ static void update_fpscr(void *retaddr)
         if (cause & enable) {
             cpu_restore_state_from_retaddr(retaddr);
             env->exception_index = 0x120;
-            cpu_loop_exit();
+            cpu_loop_exit(env);
         }
     }
 }
diff --git a/target-sparc/op_helper.c b/target-sparc/op_helper.c
index e9cc1f5..52a894e 100644
--- a/target-sparc/op_helper.c
+++ b/target-sparc/op_helper.c
@@ -316,7 +316,7 @@ static inline target_ulong asi_address_mask(CPUState *env1,
 static void raise_exception(int tt)
 {
     env->exception_index = tt;
-    cpu_loop_exit();
+    cpu_loop_exit(env);
 }
 
 void HELPER(raise_exception)(int tt)
@@ -3724,7 +3724,7 @@ void helper_ldxfsr(uint64_t new_fsr)
 void helper_debug(void)
 {
     env->exception_index = EXCP_DEBUG;
-    cpu_loop_exit();
+    cpu_loop_exit(env);
 }
 
 #ifndef TARGET_SPARC64
@@ -4424,7 +4424,7 @@ void tlb_fill(target_ulong addr, int is_write, int mmu_idx, void *retaddr)
     ret = cpu_sparc_handle_mmu_fault(env, addr, is_write, mmu_idx, 1);
     if (ret) {
         cpu_restore_state2(retaddr);
-        cpu_loop_exit();
+        cpu_loop_exit(env);
     }
     env = saved_env;
 }
diff --git a/target-unicore32/op_helper.c b/target-unicore32/op_helper.c
index 31e4b11..541e6f0 100644
--- a/target-unicore32/op_helper.c
+++ b/target-unicore32/op_helper.c
@@ -16,7 +16,7 @@
 void HELPER(exception)(uint32_t excp)
 {
     env->exception_index = excp;
-    cpu_loop_exit();
+    cpu_loop_exit(env);
 }
 
 static target_ulong asr_read(void)
diff --git a/user-exec.c b/user-exec.c
index d4a6abb..02c2f8b 100644
--- a/user-exec.c
+++ b/user-exec.c
@@ -37,13 +37,14 @@
 
 //#define DEBUG_SIGNAL
 
+static void exception_action(CPUState *env1)
+{
 #if defined(TARGET_I386)
-#define EXCEPTION_ACTION                                        \
-    raise_exception_err(env->exception_index, env->error_code)
+    raise_exception_err(env1->exception_index, env1->error_code);
 #else
-#define EXCEPTION_ACTION                                        \
-    cpu_loop_exit()
+    cpu_loop_exit(env1);
 #endif
+}
 
 /* exit the current TB from a signal handler. The host registers are
    restored in a state compatible with the CPU emulator
@@ -118,7 +119,7 @@ static inline int handle_cpu_signal(unsigned long pc, unsigned long address,
     /* we restore the process signal mask as the sigreturn should
        do it (XXX: use sigsetjmp) */
     sigprocmask(SIG_SETMASK, old_set, NULL);
-    EXCEPTION_ACTION;
+    exception_action(env);
 
     /* never comes here */
     return 1;
commit 4d2c2b77f3d0c59642dd2ce799a0fb4c2a91aca8
Author: Blue Swirl <blauwirbel at gmail.com>
Date:   Sat Jun 18 20:27:05 2011 +0000

    Sparc32: dummy implementation of MXCC MMU breakpoint registers
    
    Add dummy registers for SuperSPARC MXCC MMU counter breakpoints, save
    and load all MXCC registers.
    
    Signed-off-by: Blue Swirl <blauwirbel at gmail.com>

diff --git a/target-sparc/cpu.h b/target-sparc/cpu.h
index 320530e..a220bf4 100644
--- a/target-sparc/cpu.h
+++ b/target-sparc/cpu.h
@@ -403,6 +403,8 @@ typedef struct CPUSPARCState {
     uint32_t mmuregs[32];
     uint64_t mxccdata[4];
     uint64_t mxccregs[8];
+    uint32_t mmubpctrv, mmubpctrc, mmubpctrs;
+    uint64_t mmubpaction;
     uint64_t mmubpregs[4];
     uint64_t prom_addr;
 #endif
@@ -521,7 +523,7 @@ int cpu_sparc_signal_handler(int host_signum, void *pinfo, void *puc);
 #define cpu_signal_handler cpu_sparc_signal_handler
 #define cpu_list sparc_cpu_list
 
-#define CPU_SAVE_VERSION 6
+#define CPU_SAVE_VERSION 7
 
 /* MMU modes definitions */
 #if defined (TARGET_SPARC64)
diff --git a/target-sparc/machine.c b/target-sparc/machine.c
index 752e431..bae23c5 100644
--- a/target-sparc/machine.c
+++ b/target-sparc/machine.c
@@ -45,6 +45,19 @@ void cpu_save(QEMUFile *f, void *opaque)
     /* MMU */
     for (i = 0; i < 32; i++)
         qemu_put_be32s(f, &env->mmuregs[i]);
+    for (i = 0; i < 4; i++) {
+        qemu_put_be64s(f, &env->mxccdata[i]);
+    }
+    for (i = 0; i < 8; i++) {
+        qemu_put_be64s(f, &env->mxccregs[i]);
+    }
+    qemu_put_be32s(f, &env->mmubpctrv);
+    qemu_put_be32s(f, &env->mmubpctrc);
+    qemu_put_be32s(f, &env->mmubpctrs);
+    qemu_put_be64s(f, &env->mmubpaction);
+    for (i = 0; i < 4; i++) {
+        qemu_put_be64s(f, &env->mmubpregs[i]);
+    }
 #else
     qemu_put_be64s(f, &env->lsu);
     for (i = 0; i < 16; i++) {
@@ -141,6 +154,19 @@ int cpu_load(QEMUFile *f, void *opaque, int version_id)
     /* MMU */
     for (i = 0; i < 32; i++)
         qemu_get_be32s(f, &env->mmuregs[i]);
+    for (i = 0; i < 4; i++) {
+        qemu_get_be64s(f, &env->mxccdata[i]);
+    }
+    for (i = 0; i < 8; i++) {
+        qemu_get_be64s(f, &env->mxccregs[i]);
+    }
+    qemu_get_be32s(f, &env->mmubpctrv);
+    qemu_get_be32s(f, &env->mmubpctrc);
+    qemu_get_be32s(f, &env->mmubpctrs);
+    qemu_get_be64s(f, &env->mmubpaction);
+    for (i = 0; i < 4; i++) {
+        qemu_get_be64s(f, &env->mmubpregs[i]);
+    }
 #else
     qemu_get_be64s(f, &env->lsu);
     for (i = 0; i < 16; i++) {
diff --git a/target-sparc/op_helper.c b/target-sparc/op_helper.c
index b38691e..e9cc1f5 100644
--- a/target-sparc/op_helper.c
+++ b/target-sparc/op_helper.c
@@ -1940,7 +1940,6 @@ uint64_t helper_ld_asi(target_ulong addr, int asi, int size, int sign)
     case 0x31: // Turbosparc RAM snoop
     case 0x32: // Turbosparc page table descriptor diagnostic
     case 0x39: /* data cache diagnostic register */
-    case 0x4c: /* SuperSPARC MMU Breakpoint Action register */
         ret = 0;
         break;
     case 0x38: /* SuperSPARC MMU Breakpoint Control Registers */
@@ -1966,6 +1965,18 @@ uint64_t helper_ld_asi(target_ulong addr, int asi, int size, int sign)
                         ret);
         }
         break;
+    case 0x49: /* SuperSPARC MMU Counter Breakpoint Value */
+        ret = env->mmubpctrv;
+        break;
+    case 0x4a: /* SuperSPARC MMU Counter Breakpoint Control */
+        ret = env->mmubpctrc;
+        break;
+    case 0x4b: /* SuperSPARC MMU Counter Breakpoint Status */
+        ret = env->mmubpctrs;
+        break;
+    case 0x4c: /* SuperSPARC MMU Breakpoint Action */
+        ret = env->mmubpaction;
+        break;
     case 8: /* User code access, XXX */
     default:
         do_unassigned_access(addr, 0, 0, asi, size);
@@ -2304,7 +2315,6 @@ void helper_st_asi(target_ulong addr, uint64_t val, int asi, int size)
                // descriptor diagnostic
     case 0x36: /* I-cache flash clear */
     case 0x37: /* D-cache flash clear */
-    case 0x4c: /* breakpoint action */
         break;
     case 0x38: /* SuperSPARC MMU Breakpoint Control Registers*/
         {
@@ -2328,6 +2338,18 @@ void helper_st_asi(target_ulong addr, uint64_t val, int asi, int size)
                         env->mmuregs[reg]);
         }
         break;
+    case 0x49: /* SuperSPARC MMU Counter Breakpoint Value */
+        env->mmubpctrv = val & 0xffffffff;
+        break;
+    case 0x4a: /* SuperSPARC MMU Counter Breakpoint Control */
+        env->mmubpctrc = val & 0x3;
+        break;
+    case 0x4b: /* SuperSPARC MMU Counter Breakpoint Status */
+        env->mmubpctrs = val & 0x3;
+        break;
+    case 0x4c: /* SuperSPARC MMU Breakpoint Action */
+        env->mmubpaction = val & 0x1fff;
+        break;
     case 8: /* User code access, XXX */
     case 9: /* Supervisor code access, XXX */
     default:
commit af2be2077734e0ebfc8afbe6caf0f89a1474eef2
Author: Jan Kiszka <jan.kiszka at siemens.com>
Date:   Thu Jun 23 10:05:12 2011 +0200

    Fix fallouts from Linux header inclusion
    
    This is an all-in-one fix for the smaller and bigger mistakes of the
    build system changes for accompanied Linux headers:
     - only enable KVM and vhost on Linux hosts
     - fix powerpc asm header symlink
     - do not use Linux headers on non-Linux hosts
     - fix kvmclock for !CONFIG_KVM
     - fix s390 build on non-Linux hosts
    
    Signed-off-by: Jan Kiszka <jan.kiszka at siemens.com>
    Tested-by: Andreas Färber <andreas.faerber at web.de>
    Tested-by: Stefan Weil <weil at mail.berlios.de>
    Signed-off-by: Blue Swirl <blauwirbel at gmail.com>

diff --git a/Makefile.target b/Makefile.target
index 03d3646..d3971a6 100644
--- a/Makefile.target
+++ b/Makefile.target
@@ -14,7 +14,10 @@ endif
 
 TARGET_PATH=$(SRC_PATH)/target-$(TARGET_BASE_ARCH)
 $(call set-vpath, $(SRC_PATH):$(TARGET_PATH):$(SRC_PATH)/hw)
-QEMU_CFLAGS+= -I.. -I../linux-headers -I$(TARGET_PATH) -DNEED_CPU_H
+ifdef CONFIG_LINUX
+QEMU_CFLAGS += -I../linux-headers
+endif
+QEMU_CFLAGS += -I.. -I$(TARGET_PATH) -DNEED_CPU_H
 
 include $(SRC_PATH)/Makefile.objs
 
@@ -234,7 +237,8 @@ obj-i386-y += cirrus_vga.o sga.o apic.o ioapic.o piix_pci.o
 obj-i386-y += vmport.o
 obj-i386-y += device-hotplug.o pci-hotplug.o smbios.o wdt_ib700.o
 obj-i386-y += debugcon.o multiboot.o
-obj-i386-y += pc_piix.o kvmclock.o
+obj-i386-y += pc_piix.o
+obj-i386-$(CONFIG_KVM) += kvmclock.o
 obj-i386-$(CONFIG_SPICE) += qxl.o qxl-logger.o qxl-render.o
 
 # shared objects
diff --git a/configure b/configure
index 856b41e..e523976 100755
--- a/configure
+++ b/configure
@@ -113,7 +113,7 @@ curl=""
 curses=""
 docs=""
 fdt=""
-kvm="yes"
+kvm=""
 nptl=""
 sdl=""
 vnc="yes"
@@ -129,7 +129,7 @@ xen=""
 xen_ctrl_version=""
 linux_aio=""
 attr=""
-vhost_net="yes"
+vhost_net=""
 xfs=""
 
 gprof="no"
@@ -457,6 +457,8 @@ Haiku)
   linux="yes"
   linux_user="yes"
   usb="linux"
+  kvm="yes"
+  vhost_net="yes"
   if [ "$cpu" = "i386" -o "$cpu" = "x86_64" ] ; then
     audio_possible_drivers="$audio_possible_drivers fmod"
   fi
@@ -3444,19 +3446,21 @@ if test "$target_linux_user" = "yes" -o "$target_bsd_user" = "yes" ; then
 fi
 
 # use included Linux headers
-includes="-I\$(SRC_PATH)/linux-headers $includes"
-mkdir -p linux-headers
-case "$cpu" in
-i386|x86_64)
-  symlink $source_path/linux-headers/asm-x86 linux-headers/asm
-  ;;
-ppcemb|ppc|ppc64)
-  symlink $source_path/linux-headers/asm-x86 linux-headers/asm
-  ;;
-s390x)
-  symlink $source_path/linux-headers/asm-s390 linux-headers/asm
-  ;;
-esac
+if test "$linux" = "yes" ; then
+  includes="-I\$(SRC_PATH)/linux-headers $includes"
+  mkdir -p linux-headers
+  case "$cpu" in
+  i386|x86_64)
+    symlink $source_path/linux-headers/asm-x86 linux-headers/asm
+    ;;
+  ppcemb|ppc|ppc64)
+    symlink $source_path/linux-headers/asm-powerpc linux-headers/asm
+    ;;
+  s390x)
+    symlink $source_path/linux-headers/asm-s390 linux-headers/asm
+    ;;
+  esac
+fi
 
 echo "LDFLAGS+=$ldflags" >> $config_target_mak
 echo "QEMU_CFLAGS+=$cflags" >> $config_target_mak
diff --git a/hw/kvmclock.h b/hw/kvmclock.h
index 7a83cbe..252ea13 100644
--- a/hw/kvmclock.h
+++ b/hw/kvmclock.h
@@ -11,4 +11,14 @@
  *
  */
 
+#ifdef CONFIG_KVM
+
 void kvmclock_create(void);
+
+#else /* CONFIG_KVM */
+
+static inline void kvmclock_create(void)
+{
+}
+
+#endif /* !CONFIG_KVM */
diff --git a/target-s390x/op_helper.c b/target-s390x/op_helper.c
index 9429698..6a3c1f6 100644
--- a/target-s390x/op_helper.c
+++ b/target-s390x/op_helper.c
@@ -23,8 +23,10 @@
 #include "helpers.h"
 #include <string.h>
 #include "kvm.h"
-#include <linux/kvm.h>
 #include "qemu-timer.h"
+#ifdef CONFIG_KVM
+#include <linux/kvm.h>
+#endif
 
 /*****************************************************************************/
 /* Softmmu support */
@@ -2332,7 +2334,9 @@ static void program_interrupt(CPUState *env, uint32_t code, int ilc)
     qemu_log("program interrupt at %#" PRIx64 "\n", env->psw.addr);
 
     if (kvm_enabled()) {
+#ifdef CONFIG_KVM
         kvm_s390_interrupt(env, KVM_S390_PROGRAM_INT, code);
+#endif
     } else {
         env->int_pgm_code = code;
         env->int_pgm_ilc = ilc;
commit 20fa53ece42bec6ce5db801bead125277b26ab8a
Author: Marc-Antoine Perennou <Marc-Antoine at Perennou.com>
Date:   Fri Apr 29 05:59:19 2011 +0000

    qemu-kvm: fix pulseaudio detection in configure
    
    pulse/simple.h does not include stdlib.h
    We cannot use NULL since it may not be defined
    Use 0 instead
    
    Signed-off-by: Marc-Antoine Perennou <Marc-Antoine at Perennou.com>
    Reviewed-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 4fa9a57..a311071 100755
--- a/configure
+++ b/configure
@@ -1638,7 +1638,7 @@ for drv in $audio_drv_list; do
 
     pa)
     audio_drv_probe $drv pulse/simple.h "-lpulse-simple -lpulse" \
-        "pa_simple *s = NULL; pa_simple_free(s); return 0;"
+        "pa_simple *s = 0; pa_simple_free(s); return 0;"
     libs_softmmu="-lpulse -lpulse-simple $libs_softmmu"
     audio_pt_int="yes"
     ;;
commit 4429ab4419609f3a0b470e4b15c37c6cb5a6a400
Author: Juan Quintela <quintela at redhat.com>
Date:   Thu Jun 2 01:53:44 2011 +0000

    exec: last_first_tb was only used in !ONLY_USER case
    
    Once there, use a better variable name.
    
    Signed-off-by: Juan Quintela <quintela at redhat.com>
    Reviewed-by: Peter Maydell <peter.maydell at linaro.org>
    Signed-off-by: Stefan Hajnoczi <stefanha at linux.vnet.ibm.com>

diff --git a/exec.c b/exec.c
index b03b5be..7236281 100644
--- a/exec.c
+++ b/exec.c
@@ -1208,12 +1208,16 @@ static inline void tb_alloc_page(TranslationBlock *tb,
                                  unsigned int n, tb_page_addr_t page_addr)
 {
     PageDesc *p;
-    TranslationBlock *last_first_tb;
+#ifndef CONFIG_USER_ONLY
+    bool page_already_protected;
+#endif
 
     tb->page_addr[n] = page_addr;
     p = page_find_alloc(page_addr >> TARGET_PAGE_BITS, 1);
     tb->page_next[n] = p->first_tb;
-    last_first_tb = p->first_tb;
+#ifndef CONFIG_USER_ONLY
+    page_already_protected = p->first_tb != NULL;
+#endif
     p->first_tb = (TranslationBlock *)((long)tb | n);
     invalidate_page_bitmap(p);
 
@@ -1249,7 +1253,7 @@ static inline void tb_alloc_page(TranslationBlock *tb,
     /* if some code is already present, then the pages are already
        protected. So we handle the case where only the first TB is
        allocated in a physical page */
-    if (!last_first_tb) {
+    if (!page_already_protected) {
         tlb_protect_code(page_addr);
     }
 #endif
commit 6a33e7b6097138a07fb16a56e5ab667f05473eca
Author: Stefan Weil <weil at mail.berlios.de>
Date:   Fri Jun 24 12:15:49 2011 +0200

    w32: Remove redundant definitions of PRI*64
    
    The PRI*64 macros are defined in MinGW's inttypes.h since 2002,
    so they are not needed in qemu-common.h (which includes inttypes.h).
    
    Signed-off-by: Stefan Weil <weil at mail.berlios.de>
    Signed-off-by: Stefan Hajnoczi <stefanha at linux.vnet.ibm.com>

diff --git a/qemu-common.h b/qemu-common.h
index 109498d..abd7a75 100644
--- a/qemu-common.h
+++ b/qemu-common.h
@@ -112,11 +112,6 @@ static inline char *realpath(const char *path, char *resolved_path)
     _fullpath(resolved_path, path, _MAX_PATH);
     return resolved_path;
 }
-
-#define PRId64 "I64d"
-#define PRIx64 "I64x"
-#define PRIu64 "I64u"
-#define PRIo64 "I64o"
 #endif
 
 /* FIXME: Remove NEED_CPU_H.  */
commit 0ff0fc19cde2e122c86a7af697df65cf8a5e222e
Author: Jan Kiszka <jan.kiszka at siemens.com>
Date:   Thu Jun 23 10:15:55 2011 +0200

    Do not include compatfd for WIN32
    
    sigset_t, used by that header, is not available in mingw32 environments.
    
    Signed-off-by: Jan Kiszka <jan.kiszka at siemens.com>
    Signed-off-by: Stefan Hajnoczi <stefanha at linux.vnet.ibm.com>

diff --git a/cpus.c b/cpus.c
index 0699f37..ded2100 100644
--- a/cpus.c
+++ b/cpus.c
@@ -34,7 +34,10 @@
 
 #include "qemu-thread.h"
 #include "cpus.h"
+
+#ifndef _WIN32
 #include "compatfd.h"
+#endif
 
 #ifdef SIGRTMIN
 #define SIG_IPI (SIGRTMIN+4)
commit 2167f7bc289a90b043826961c2a3271298d51ef6
Author: Matthew Fernandez <matthew.fernandez at gmail.com>
Date:   Thu Jun 23 10:59:26 2011 +1000

    Fix comment typos in hw/armv7m.c
    
    Fix a couple of typos in comments.
    
    Signed-off-by: Matthew Fernandez <matthew.fernandez at gmail.com>
    Acked-by: Stefan Weil <weil at mail.berlios.de>
    Signed-off-by: Stefan Hajnoczi <stefanha at linux.vnet.ibm.com>

diff --git a/hw/armv7m.c b/hw/armv7m.c
index 72d010a..83f3393 100644
--- a/hw/armv7m.c
+++ b/hw/armv7m.c
@@ -4,7 +4,7 @@
  * Copyright (c) 2006-2007 CodeSourcery.
  * Written by Paul Brook
  *
- * This code is licenced under the GPL.
+ * This code is licensed under the GPL.
  */
 
 #include "sysbus.h"
@@ -14,7 +14,7 @@
 
 /* Bitbanded IO.  Each word corresponds to a single bit.  */
 
-/* Get the byte address of the real memory for a bitband acess.  */
+/* Get the byte address of the real memory for a bitband access.  */
 static inline uint32_t bitband_addr(void * opaque, uint32_t addr)
 {
     uint32_t res;
commit d6eec7a2bffd88495e489e3a3c7178d27f6561f9
Author: Peter Maydell <peter.maydell at linaro.org>
Date:   Wed Jun 22 15:45:01 2011 +0100

    MAINTAINERS: Fix typo in email address
    
    Fix a typo in one of the copies of Aurelien Jarno's email address.
    
    Signed-off-by: Peter Maydell <peter.maydell at linaro.org>
    Signed-off-by: Stefan Hajnoczi <stefanha at linux.vnet.ibm.com>

diff --git a/MAINTAINERS b/MAINTAINERS
index 35d4496..6115e4e 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -480,7 +480,7 @@ S: Maintained
 F: tcg/ia64/
 
 MIPS target
-M: Aurelien Jarno <aurelien at aurel32.ne>
+M: Aurelien Jarno <aurelien at aurel32.net>
 S: Maintained
 F: tcg/mips/
 
commit e4080f9becfb3e96252cf2d9c4e14c4ae569a0ea
Author: Markus Armbruster <armbru at redhat.com>
Date:   Wed Jun 22 14:03:57 2011 +0200

    blockdev: Put space after comma in error message
    
    Signed-off-by: Markus Armbruster <armbru at redhat.com>
    Signed-off-by: Stefan Hajnoczi <stefanha at linux.vnet.ibm.com>

diff --git a/blockdev.c b/blockdev.c
index 1502575..7d579d6 100644
--- a/blockdev.c
+++ b/blockdev.c
@@ -293,7 +293,7 @@ DriveInfo *drive_init(QemuOpts *opts, int default_to_scsi)
 
     if ((buf = qemu_opt_get(opts, "trans")) != NULL) {
         if (!cyls) {
-            error_report("'%s' trans must be used with cyls,heads and secs",
+            error_report("'%s' trans must be used with cyls, heads and secs",
                          buf);
             return NULL;
         }
commit dd3d677512ae3f15b2e85254cec10023825210ec
Author: Markus Armbruster <armbru at redhat.com>
Date:   Wed Jun 22 14:03:56 2011 +0200

    Spell "unkown" correctly in error_report() arguments
    
    Signed-off-by: Markus Armbruster <armbru at redhat.com>
    Signed-off-by: Stefan Hajnoczi <stefanha at linux.vnet.ibm.com>

diff --git a/hw/lm32_sys.c b/hw/lm32_sys.c
index 427b05f..e5ff962 100644
--- a/hw/lm32_sys.c
+++ b/hw/lm32_sys.c
@@ -83,7 +83,7 @@ static void sys_write(void *opaque, target_phys_addr_t addr, uint32_t value)
         break;
 
     default:
-        error_report("lm32_sys: write access to unkown register 0x"
+        error_report("lm32_sys: write access to unknown register 0x"
                 TARGET_FMT_plx, addr << 2);
         break;
     }
diff --git a/hw/lm32_timer.c b/hw/lm32_timer.c
index ed28984..49cbb22 100644
--- a/hw/lm32_timer.c
+++ b/hw/lm32_timer.c
@@ -86,7 +86,7 @@ static uint32_t timer_read(void *opaque, target_phys_addr_t addr)
         r = (uint32_t)ptimer_get_count(s->ptimer);
         break;
     default:
-        error_report("lm32_timer: read access to unkown register 0x"
+        error_report("lm32_timer: read access to unknown register 0x"
                 TARGET_FMT_plx, addr << 2);
         break;
     }
@@ -124,7 +124,7 @@ static void timer_write(void *opaque, target_phys_addr_t addr, uint32_t value)
                 TARGET_FMT_plx, addr << 2);
         break;
     default:
-        error_report("lm32_timer: write access to unkown register 0x"
+        error_report("lm32_timer: write access to unknown register 0x"
                 TARGET_FMT_plx, addr << 2);
         break;
     }
diff --git a/hw/lm32_uart.c b/hw/lm32_uart.c
index e225087..09090e9 100644
--- a/hw/lm32_uart.c
+++ b/hw/lm32_uart.c
@@ -149,7 +149,7 @@ static uint32_t uart_read(void *opaque, target_phys_addr_t addr)
                 TARGET_FMT_plx, addr << 2);
         break;
     default:
-        error_report("lm32_uart: read access to unkown register 0x"
+        error_report("lm32_uart: read access to unknown register 0x"
                 TARGET_FMT_plx, addr << 2);
         break;
     }
@@ -185,7 +185,7 @@ static void uart_write(void *opaque, target_phys_addr_t addr, uint32_t value)
                 TARGET_FMT_plx, addr << 2);
         break;
     default:
-        error_report("lm32_uart: write access to unkown register 0x"
+        error_report("lm32_uart: write access to unknown register 0x"
                 TARGET_FMT_plx, addr << 2);
         break;
     }
diff --git a/hw/milkymist-ac97.c b/hw/milkymist-ac97.c
index 6c9e318..6104732 100644
--- a/hw/milkymist-ac97.c
+++ b/hw/milkymist-ac97.c
@@ -103,7 +103,7 @@ static uint32_t ac97_read(void *opaque, target_phys_addr_t addr)
         break;
 
     default:
-        error_report("milkymist_ac97: read access to unkown register 0x"
+        error_report("milkymist_ac97: read access to unknown register 0x"
                 TARGET_FMT_plx, addr << 2);
         break;
     }
@@ -152,7 +152,7 @@ static void ac97_write(void *opaque, target_phys_addr_t addr, uint32_t value)
         break;
 
     default:
-        error_report("milkymist_ac97: write access to unkown register 0x"
+        error_report("milkymist_ac97: write access to unknown register 0x"
                 TARGET_FMT_plx, addr);
         break;
     }
diff --git a/hw/milkymist-memcard.c b/hw/milkymist-memcard.c
index 06077af..22dc377 100644
--- a/hw/milkymist-memcard.c
+++ b/hw/milkymist-memcard.c
@@ -154,7 +154,7 @@ static uint32_t memcard_read(void *opaque, target_phys_addr_t addr)
         break;
 
     default:
-        error_report("milkymist_memcard: read access to unkown register 0x"
+        error_report("milkymist_memcard: read access to unknown register 0x"
                 TARGET_FMT_plx, addr << 2);
         break;
     }
@@ -210,7 +210,7 @@ static void memcard_write(void *opaque, target_phys_addr_t addr, uint32_t value)
         break;
 
     default:
-        error_report("milkymist_memcard: write access to unkown register 0x"
+        error_report("milkymist_memcard: write access to unknown register 0x"
                 TARGET_FMT_plx, addr << 2);
         break;
     }
diff --git a/hw/milkymist-sysctl.c b/hw/milkymist-sysctl.c
index 6bd0cb9..7b2d544 100644
--- a/hw/milkymist-sysctl.c
+++ b/hw/milkymist-sysctl.c
@@ -119,7 +119,7 @@ static uint32_t sysctl_read(void *opaque, target_phys_addr_t addr)
         break;
 
     default:
-        error_report("milkymist_sysctl: read access to unkown register 0x"
+        error_report("milkymist_sysctl: read access to unknown register 0x"
                 TARGET_FMT_plx, addr << 2);
         break;
     }
@@ -189,7 +189,7 @@ static void sysctl_write(void *opaque, target_phys_addr_t addr, uint32_t value)
         break;
 
     default:
-        error_report("milkymist_sysctl: write access to unkown register 0x"
+        error_report("milkymist_sysctl: write access to unknown register 0x"
                 TARGET_FMT_plx, addr << 2);
         break;
     }
commit 9d42e15dc9384e528891c01b036a81a9c4e516e9
Author: Markus Armbruster <armbru at redhat.com>
Date:   Wed Jun 22 14:03:55 2011 +0200

    qemu-img: Don't prepend qemu-img to error messages twice.
    
    error_report() prepends the location already.  Example:
    
    $ qemu-img convert -6
    qemu-img: qemu-img: option -6 is deprecated, please use '-o compat6' instead!
    
    Signed-off-by: Markus Armbruster <armbru at redhat.com>
    Signed-off-by: Stefan Hajnoczi <stefanha at linux.vnet.ibm.com>

diff --git a/qemu-img.c b/qemu-img.c
index 1a37828..32628b3 100644
--- a/qemu-img.c
+++ b/qemu-img.c
@@ -304,11 +304,11 @@ static int img_create(int argc, char **argv)
             fmt = optarg;
             break;
         case 'e':
-            error_report("qemu-img: option -e is deprecated, please use \'-o "
+            error_report("option -e is deprecated, please use \'-o "
                   "encryption\' instead!");
             return 1;
         case '6':
-            error_report("qemu-img: option -6 is deprecated, please use \'-o "
+            error_report("option -6 is deprecated, please use \'-o "
                   "compat6\' instead!");
             return 1;
         case 'o':
@@ -633,11 +633,11 @@ static int img_convert(int argc, char **argv)
             compress = 1;
             break;
         case 'e':
-            error_report("qemu-img: option -e is deprecated, please use \'-o "
+            error_report("option -e is deprecated, please use \'-o "
                   "encryption\' instead!");
             return 1;
         case '6':
-            error_report("qemu-img: option -6 is deprecated, please use \'-o "
+            error_report("option -6 is deprecated, please use \'-o "
                   "compat6\' instead!");
             return 1;
         case 'o':
commit 6daf194dde15acda153b824299f36f12dfa527a6
Author: Markus Armbruster <armbru at redhat.com>
Date:   Wed Jun 22 14:03:54 2011 +0200

    Strip trailing '\n' from error_report()'s first argument
    
    error_report() prepends location, and appends a newline.  The message
    constructed from the arguments should not contain a newline.  Fix the
    obvious offenders.
    
    Signed-off-by: Markus Armbruster <armbru at redhat.com>
    Signed-off-by: Stefan Hajnoczi <stefanha at linux.vnet.ibm.com>

diff --git a/block-migration.c b/block-migration.c
index 8d06a23..0936c7d 100644
--- a/block-migration.c
+++ b/block-migration.c
@@ -671,7 +671,7 @@ static int block_load(QEMUFile *f, void *opaque, int version_id)
                 bs_prev = bs;
                 total_sectors = bdrv_getlength(bs) >> BDRV_SECTOR_BITS;
                 if (total_sectors <= 0) {
-                    error_report("Error getting length of block device %s\n",
+                    error_report("Error getting length of block device %s",
                                  device_name);
                     return -EINVAL;
                 }
diff --git a/block/qcow2.c b/block/qcow2.c
index 2c51e7c..48e1b95 100644
--- a/block/qcow2.c
+++ b/block/qcow2.c
@@ -936,7 +936,7 @@ static int qcow2_create2(const char *filename, int64_t total_size,
         (1 << cluster_bits) != cluster_size)
     {
         error_report(
-            "Cluster size must be a power of two between %d and %dk\n",
+            "Cluster size must be a power of two between %d and %dk",
             1 << MIN_CLUSTER_BITS, 1 << (MAX_CLUSTER_BITS - 10));
         return -EINVAL;
     }
diff --git a/block/sheepdog.c b/block/sheepdog.c
index 2180299..80d106c 100644
--- a/block/sheepdog.c
+++ b/block/sheepdog.c
@@ -444,7 +444,7 @@ static SheepdogAIOCB *sd_aio_setup(BlockDriverState *bs, QEMUIOVector *qiov,
 static int sd_schedule_bh(QEMUBHFunc *cb, SheepdogAIOCB *acb)
 {
     if (acb->bh) {
-        error_report("bug: %d %d\n", acb->aiocb_type, acb->aiocb_type);
+        error_report("bug: %d %d", acb->aiocb_type, acb->aiocb_type);
         return -EIO;
     }
 
@@ -592,7 +592,7 @@ static int connect_to_sdog(const char *addr, const char *port)
 
     ret = getaddrinfo(addr, port, &hints, &res0);
     if (ret) {
-        error_report("unable to get address info %s, %s\n",
+        error_report("unable to get address info %s, %s",
                      addr, strerror(errno));
         return -1;
     }
@@ -622,7 +622,7 @@ static int connect_to_sdog(const char *addr, const char *port)
         goto success;
     }
     fd = -1;
-    error_report("failed connect to %s:%s\n", addr, port);
+    error_report("failed connect to %s:%s", addr, port);
 success:
     freeaddrinfo(res0);
     return fd;
@@ -638,7 +638,7 @@ again:
         if (errno == EINTR || errno == EAGAIN) {
             goto again;
         }
-        error_report("failed to recv a rsp, %s\n", strerror(errno));
+        error_report("failed to recv a rsp, %s", strerror(errno));
         return 1;
     }
 
@@ -697,7 +697,7 @@ static int send_req(int sockfd, SheepdogReq *hdr, void *data,
 
     ret = do_writev(sockfd, iov, sizeof(*hdr) + *wlen, 0);
     if (ret) {
-        error_report("failed to send a req, %s\n", strerror(errno));
+        error_report("failed to send a req, %s", strerror(errno));
         ret = -1;
     }
 
@@ -717,7 +717,7 @@ static int do_req(int sockfd, SheepdogReq *hdr, void *data,
 
     ret = do_read(sockfd, hdr, sizeof(*hdr));
     if (ret) {
-        error_report("failed to get a rsp, %s\n", strerror(errno));
+        error_report("failed to get a rsp, %s", strerror(errno));
         ret = -1;
         goto out;
     }
@@ -729,7 +729,7 @@ static int do_req(int sockfd, SheepdogReq *hdr, void *data,
     if (*rlen) {
         ret = do_read(sockfd, data, *rlen);
         if (ret) {
-            error_report("failed to get the data, %s\n", strerror(errno));
+            error_report("failed to get the data, %s", strerror(errno));
             ret = -1;
             goto out;
         }
@@ -766,7 +766,7 @@ static void send_pending_req(BDRVSheepdogState *s, uint64_t oid, uint32_t id)
         ret = add_aio_request(s, aio_req, acb->qiov->iov,
                               acb->qiov->niov, 0, acb->aiocb_type);
         if (ret < 0) {
-            error_report("add_aio_request is failed\n");
+            error_report("add_aio_request is failed");
             free_aio_req(s, aio_req);
             if (QLIST_EMPTY(&acb->aioreq_head)) {
                 sd_finish_aiocb(acb);
@@ -799,7 +799,7 @@ static void aio_read_response(void *opaque)
     /* read a header */
     ret = do_read(fd, &rsp, sizeof(rsp));
     if (ret) {
-        error_report("failed to get the header, %s\n", strerror(errno));
+        error_report("failed to get the header, %s", strerror(errno));
         return;
     }
 
@@ -810,7 +810,7 @@ static void aio_read_response(void *opaque)
         }
     }
     if (!aio_req) {
-        error_report("cannot find aio_req %x\n", rsp.id);
+        error_report("cannot find aio_req %x", rsp.id);
         return;
     }
 
@@ -846,7 +846,7 @@ static void aio_read_response(void *opaque)
         ret = do_readv(fd, acb->qiov->iov, rsp.data_length,
                        aio_req->iov_offset);
         if (ret) {
-            error_report("failed to get the data, %s\n", strerror(errno));
+            error_report("failed to get the data, %s", strerror(errno));
             return;
         }
         break;
@@ -854,7 +854,7 @@ static void aio_read_response(void *opaque)
 
     if (rsp.result != SD_RES_SUCCESS) {
         acb->ret = -EIO;
-        error_report("%s\n", sd_strerror(rsp.result));
+        error_report("%s", sd_strerror(rsp.result));
     }
 
     rest = free_aio_req(s, aio_req);
@@ -911,7 +911,7 @@ static int get_sheep_fd(BDRVSheepdogState *s)
 
     fd = connect_to_sdog(s->addr, s->port);
     if (fd < 0) {
-        error_report("%s\n", strerror(errno));
+        error_report("%s", strerror(errno));
         return -1;
     }
 
@@ -919,7 +919,7 @@ static int get_sheep_fd(BDRVSheepdogState *s)
 
     ret = set_nodelay(fd);
     if (ret) {
-        error_report("%s\n", strerror(errno));
+        error_report("%s", strerror(errno));
         closesocket(fd);
         return -1;
     }
@@ -1035,7 +1035,7 @@ static int find_vdi_name(BDRVSheepdogState *s, char *filename, uint32_t snapid,
     }
 
     if (rsp->result != SD_RES_SUCCESS) {
-        error_report("cannot get vdi info, %s, %s %d %s\n",
+        error_report("cannot get vdi info, %s, %s %d %s",
                      sd_strerror(rsp->result), filename, snapid, tag);
         ret = -1;
         goto out;
@@ -1063,7 +1063,7 @@ static int add_aio_request(BDRVSheepdogState *s, AIOReq *aio_req,
     uint64_t old_oid = aio_req->base_oid;
 
     if (!nr_copies) {
-        error_report("bug\n");
+        error_report("bug");
     }
 
     memset(&hdr, 0, sizeof(hdr));
@@ -1096,14 +1096,14 @@ static int add_aio_request(BDRVSheepdogState *s, AIOReq *aio_req,
     /* send a header */
     ret = do_write(s->fd, &hdr, sizeof(hdr));
     if (ret) {
-        error_report("failed to send a req, %s\n", strerror(errno));
+        error_report("failed to send a req, %s", strerror(errno));
         return -EIO;
     }
 
     if (wlen) {
         ret = do_writev(s->fd, iov, wlen, aio_req->iov_offset);
         if (ret) {
-            error_report("failed to send a data, %s\n", strerror(errno));
+            error_report("failed to send a data, %s", strerror(errno));
             return -EIO;
         }
     }
@@ -1145,7 +1145,7 @@ static int read_write_object(int fd, char *buf, uint64_t oid, int copies,
 
     ret = do_req(fd, (SheepdogReq *)&hdr, buf, &wlen, &rlen);
     if (ret) {
-        error_report("failed to send a request to the sheep\n");
+        error_report("failed to send a request to the sheep");
         return -1;
     }
 
@@ -1153,7 +1153,7 @@ static int read_write_object(int fd, char *buf, uint64_t oid, int copies,
     case SD_RES_SUCCESS:
         return 0;
     default:
-        error_report("%s\n", sd_strerror(rsp->result));
+        error_report("%s", sd_strerror(rsp->result));
         return -1;
     }
 }
@@ -1206,7 +1206,7 @@ static int sd_open(BlockDriverState *bs, const char *filename, int flags)
 
     fd = connect_to_sdog(s->addr, s->port);
     if (fd < 0) {
-        error_report("failed to connect\n");
+        error_report("failed to connect");
         goto out;
     }
 
@@ -1275,7 +1275,7 @@ static int do_sd_create(char *filename, int64_t vdi_size,
     }
 
     if (rsp->result != SD_RES_SUCCESS) {
-        error_report("%s, %s\n", sd_strerror(rsp->result), filename);
+        error_report("%s, %s", sd_strerror(rsp->result), filename);
         return -EIO;
     }
 
@@ -1302,7 +1302,7 @@ static int sd_create(const char *filename, QEMUOptionParameter *options)
     memset(vdi, 0, sizeof(vdi));
     memset(tag, 0, sizeof(tag));
     if (parse_vdiname(&s, filename, vdi, &snapid, tag) < 0) {
-        error_report("invalid filename\n");
+        error_report("invalid filename");
         return -EINVAL;
     }
 
@@ -1316,7 +1316,7 @@ static int sd_create(const char *filename, QEMUOptionParameter *options)
     }
 
     if (vdi_size > SD_MAX_VDI_SIZE) {
-        error_report("too big image size\n");
+        error_report("too big image size");
         return -EINVAL;
     }
 
@@ -1328,7 +1328,7 @@ static int sd_create(const char *filename, QEMUOptionParameter *options)
         /* Currently, only Sheepdog backing image is supported. */
         drv = bdrv_find_protocol(backing_file);
         if (!drv || strcmp(drv->protocol_name, "sheepdog") != 0) {
-            error_report("backing_file must be a sheepdog image\n");
+            error_report("backing_file must be a sheepdog image");
             return -EINVAL;
         }
 
@@ -1339,7 +1339,7 @@ static int sd_create(const char *filename, QEMUOptionParameter *options)
         s = bs->opaque;
 
         if (!is_snapshot(&s->inode)) {
-            error_report("cannot clone from a non snapshot vdi\n");
+            error_report("cannot clone from a non snapshot vdi");
             bdrv_delete(bs);
             return -EINVAL;
         }
@@ -1379,7 +1379,7 @@ static void sd_close(BlockDriverState *bs)
 
     if (!ret && rsp->result != SD_RES_SUCCESS &&
         rsp->result != SD_RES_VDI_NOT_LOCKED) {
-        error_report("%s, %s\n", sd_strerror(rsp->result), s->name);
+        error_report("%s, %s", sd_strerror(rsp->result), s->name);
     }
 
     qemu_aio_set_fd_handler(s->fd, NULL, NULL, NULL, NULL, NULL);
@@ -1401,10 +1401,10 @@ static int sd_truncate(BlockDriverState *bs, int64_t offset)
     unsigned int datalen;
 
     if (offset < s->inode.vdi_size) {
-        error_report("shrinking is not supported\n");
+        error_report("shrinking is not supported");
         return -EINVAL;
     } else if (offset > SD_MAX_VDI_SIZE) {
-        error_report("too big image size\n");
+        error_report("too big image size");
         return -EINVAL;
     }
 
@@ -1421,7 +1421,7 @@ static int sd_truncate(BlockDriverState *bs, int64_t offset)
     close(fd);
 
     if (ret < 0) {
-        error_report("failed to update an inode.\n");
+        error_report("failed to update an inode.");
         return -EIO;
     }
 
@@ -1494,7 +1494,7 @@ static int sd_create_branch(BDRVSheepdogState *s)
 
     fd = connect_to_sdog(s->addr, s->port);
     if (fd < 0) {
-        error_report("failed to connect\n");
+        error_report("failed to connect");
         goto out;
     }
 
@@ -1612,7 +1612,7 @@ static void sd_readv_writev_bh_cb(void *p)
         ret = add_aio_request(s, aio_req, acb->qiov->iov, acb->qiov->niov,
                               create, acb->aiocb_type);
         if (ret < 0) {
-            error_report("add_aio_request is failed\n");
+            error_report("add_aio_request is failed");
             free_aio_req(s, aio_req);
             acb->ret = -EIO;
             goto out;
@@ -1689,7 +1689,7 @@ static int sd_snapshot_create(BlockDriverState *bs, QEMUSnapshotInfo *sn_info)
 
     if (s->is_snapshot) {
         error_report("You can't create a snapshot of a snapshot VDI, "
-                     "%s (%" PRIu32 ").\n", s->name, s->inode.vdi_id);
+                     "%s (%" PRIu32 ").", s->name, s->inode.vdi_id);
 
         return -EINVAL;
     }
@@ -1712,7 +1712,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);
     if (ret < 0) {
-        error_report("failed to write snapshot's inode.\n");
+        error_report("failed to write snapshot's inode.");
         ret = -EIO;
         goto cleanup;
     }
@@ -1720,7 +1720,7 @@ static int sd_snapshot_create(BlockDriverState *bs, QEMUSnapshotInfo *sn_info)
     ret = do_sd_create(s->name, s->inode.vdi_size, s->inode.vdi_id, &new_vid, 1,
                        s->addr, s->port);
     if (ret < 0) {
-        error_report("failed to create inode for snapshot. %s\n",
+        error_report("failed to create inode for snapshot. %s",
                      strerror(errno));
         ret = -EIO;
         goto cleanup;
@@ -1732,7 +1732,7 @@ static int sd_snapshot_create(BlockDriverState *bs, QEMUSnapshotInfo *sn_info)
                       s->inode.nr_copies, datalen, 0);
 
     if (ret < 0) {
-        error_report("failed to read new inode info. %s\n", strerror(errno));
+        error_report("failed to read new inode info. %s", strerror(errno));
         ret = -EIO;
         goto cleanup;
     }
@@ -1771,14 +1771,14 @@ static int sd_snapshot_goto(BlockDriverState *bs, const char *snapshot_id)
 
     ret = find_vdi_name(s, vdi, snapid, tag, &vid, 1);
     if (ret) {
-        error_report("Failed to find_vdi_name\n");
+        error_report("Failed to find_vdi_name");
         ret = -ENOENT;
         goto out;
     }
 
     fd = connect_to_sdog(s->addr, s->port);
     if (fd < 0) {
-        error_report("failed to connect\n");
+        error_report("failed to connect");
         goto out;
     }
 
@@ -1796,7 +1796,7 @@ static int sd_snapshot_goto(BlockDriverState *bs, const char *snapshot_id)
     memcpy(&s->inode, buf, sizeof(s->inode));
 
     if (!s->inode.vm_state_size) {
-        error_report("Invalid snapshot\n");
+        error_report("Invalid snapshot");
         ret = -ENOENT;
         goto out;
     }
@@ -1813,7 +1813,7 @@ out:
     qemu_free(buf);
     qemu_free(old_s);
 
-    error_report("failed to open. recover old bdrv_sd_state.\n");
+    error_report("failed to open. recover old bdrv_sd_state.");
 
     return ret;
 }
@@ -1868,7 +1868,7 @@ static int sd_snapshot_list(BlockDriverState *bs, QEMUSnapshotInfo **psn_tab)
 
     fd = connect_to_sdog(s->addr, s->port);
     if (fd < 0) {
-        error_report("failed to connect\n");
+        error_report("failed to connect");
         goto out;
     }
 
@@ -1942,7 +1942,7 @@ static int do_load_save_vmstate(BDRVSheepdogState *s, uint8_t *data,
         }
 
         if (ret < 0) {
-            error_report("failed to save vmstate %s\n", strerror(errno));
+            error_report("failed to save vmstate %s", strerror(errno));
             ret = -EIO;
             goto cleanup;
         }
diff --git a/hw/milkymist-minimac2.c b/hw/milkymist-minimac2.c
index c4e2818..cd36026 100644
--- a/hw/milkymist-minimac2.c
+++ b/hw/milkymist-minimac2.c
@@ -234,20 +234,20 @@ static void minimac2_tx(MilkymistMinimac2State *s)
     uint8_t *buf = s->tx_buf;
 
     if (txcount < 64) {
-        error_report("milkymist_minimac2: ethernet frame too small (%u < %u)\n",
+        error_report("milkymist_minimac2: ethernet frame too small (%u < %u)",
                 txcount, 64);
         goto err;
     }
 
     if (txcount > MINIMAC2_MTU) {
-        error_report("milkymist_minimac2: MTU exceeded (%u > %u)\n",
+        error_report("milkymist_minimac2: MTU exceeded (%u > %u)",
                 txcount, MINIMAC2_MTU);
         goto err;
     }
 
     if (memcmp(buf, preamble_sfd, 8) != 0) {
         error_report("milkymist_minimac2: frame doesn't contain the preamble "
-                "and/or the SFD (%02x %02x %02x %02x %02x %02x %02x %02x)\n",
+                "and/or the SFD (%02x %02x %02x %02x %02x %02x %02x %02x)",
                 buf[0], buf[1], buf[2], buf[3], buf[4], buf[5], buf[6], buf[7]);
         goto err;
     }
diff --git a/hw/milkymist-pfpu.c b/hw/milkymist-pfpu.c
index 94e6315..306d1ce 100644
--- a/hw/milkymist-pfpu.c
+++ b/hw/milkymist-pfpu.c
@@ -301,7 +301,7 @@ static int pfpu_decode_insn(MilkymistPFPUState *s)
     } break;
 
     default:
-        error_report("milkymist_pfpu: unknown opcode %d\n", op);
+        error_report("milkymist_pfpu: unknown opcode %d", op);
         break;
     }
 
@@ -358,7 +358,7 @@ static void pfpu_start(MilkymistPFPUState *s)
                 /* decode at most MICROCODE_WORDS instructions */
                 if (i++ >= MICROCODE_WORDS) {
                     error_report("milkymist_pfpu: too many instructions "
-                            "executed in microcode. No VECTOUT?\n");
+                            "executed in microcode. No VECTOUT?");
                     break;
                 }
             }
diff --git a/hw/milkymist-softusb.c b/hw/milkymist-softusb.c
index 028f3b7..5ab35c3 100644
--- a/hw/milkymist-softusb.c
+++ b/hw/milkymist-softusb.c
@@ -131,7 +131,7 @@ static inline void softusb_read_dmem(MilkymistSoftUsbState *s,
 {
     if (offset + len >= s->dmem_size) {
         error_report("milkymist_softusb: read dmem out of bounds "
-                "at offset 0x%x, len %d\n", offset, len);
+                "at offset 0x%x, len %d", offset, len);
         return;
     }
 
@@ -143,7 +143,7 @@ static inline void softusb_write_dmem(MilkymistSoftUsbState *s,
 {
     if (offset + len >= s->dmem_size) {
         error_report("milkymist_softusb: write dmem out of bounds "
-                "at offset 0x%x, len %d\n", offset, len);
+                "at offset 0x%x, len %d", offset, len);
         return;
     }
 
@@ -155,7 +155,7 @@ static inline void softusb_read_pmem(MilkymistSoftUsbState *s,
 {
     if (offset + len >= s->pmem_size) {
         error_report("milkymist_softusb: read pmem out of bounds "
-                "at offset 0x%x, len %d\n", offset, len);
+                "at offset 0x%x, len %d", offset, len);
         return;
     }
 
@@ -167,7 +167,7 @@ static inline void softusb_write_pmem(MilkymistSoftUsbState *s,
 {
     if (offset + len >= s->pmem_size) {
         error_report("milkymist_softusb: write pmem out of bounds "
-                "at offset 0x%x, len %d\n", offset, len);
+                "at offset 0x%x, len %d", offset, len);
         return;
     }
 
diff --git a/hw/milkymist-tmu2.c b/hw/milkymist-tmu2.c
index 9cebe31..790cdcb 100644
--- a/hw/milkymist-tmu2.c
+++ b/hw/milkymist-tmu2.c
@@ -352,21 +352,21 @@ static uint32_t tmu2_read(void *opaque, target_phys_addr_t addr)
 static void tmu2_check_registers(MilkymistTMU2State *s)
 {
     if (s->regs[R_BRIGHTNESS] > MAX_BRIGHTNESS) {
-        error_report("milkymist_tmu2: max brightness is %d\n", MAX_BRIGHTNESS);
+        error_report("milkymist_tmu2: max brightness is %d", MAX_BRIGHTNESS);
     }
 
     if (s->regs[R_ALPHA] > MAX_ALPHA) {
-        error_report("milkymist_tmu2: max alpha is %d\n", MAX_ALPHA);
+        error_report("milkymist_tmu2: max alpha is %d", MAX_ALPHA);
     }
 
     if (s->regs[R_VERTICESADDR] & 0x07) {
         error_report("milkymist_tmu2: vertex mesh address has to be 64-bit "
-                "aligned\n");
+                "aligned");
     }
 
     if (s->regs[R_TEXFBUF] & 0x01) {
         error_report("milkymist_tmu2: texture buffer address has to be "
-                "16-bit aligned\n");
+                "16-bit aligned");
     }
 }
 
diff --git a/hw/qdev.c b/hw/qdev.c
index 2987901..292b52f 100644
--- a/hw/qdev.c
+++ b/hw/qdev.c
@@ -371,7 +371,7 @@ void qdev_init_nofail(DeviceState *dev)
     DeviceInfo *info = dev->info;
 
     if (qdev_init(dev) < 0) {
-        error_report("Initialization of device %s failed\n", info->name);
+        error_report("Initialization of device %s failed", info->name);
         exit(1);
     }
 }
diff --git a/hw/strongarm.c b/hw/strongarm.c
index de08bdf..0e03d61 100644
--- a/hw/strongarm.c
+++ b/hw/strongarm.c
@@ -1536,14 +1536,14 @@ StrongARMState *sa1110_init(unsigned int sdram_size, const char *rev)
     }
 
     if (strncmp(rev, "sa1110", 6)) {
-        error_report("Machine requires a SA1110 processor.\n");
+        error_report("Machine requires a SA1110 processor.");
         exit(1);
     }
 
     s->env = cpu_init(rev);
 
     if (!s->env) {
-        error_report("Unable to find CPU definition\n");
+        error_report("Unable to find CPU definition");
         exit(1);
     }
 
diff --git a/hw/usb-ccid.c b/hw/usb-ccid.c
index 59c6431..524b841 100644
--- a/hw/usb-ccid.c
+++ b/hw/usb-ccid.c
@@ -1240,7 +1240,7 @@ static int ccid_card_init(DeviceState *qdev, DeviceInfo *base)
         return -1;
     }
     if (s->card != NULL) {
-        error_report("Warning: usb-ccid card already full, not adding\n");
+        error_report("Warning: usb-ccid card already full, not adding");
         return -1;
     }
     ret = info->initfn ? info->initfn(card) : ret;
diff --git a/hw/virtio-serial-bus.c b/hw/virtio-serial-bus.c
index 9a12104..bff4004 100644
--- a/hw/virtio-serial-bus.c
+++ b/hw/virtio-serial-bus.c
@@ -337,7 +337,7 @@ static void handle_control_message(VirtIOSerial *vser, void *buf, size_t len)
     switch(cpkt.event) {
     case VIRTIO_CONSOLE_DEVICE_READY:
         if (!cpkt.value) {
-            error_report("virtio-serial-bus: Guest failure in adding device %s\n",
+            error_report("virtio-serial-bus: Guest failure in adding device %s",
                          vser->bus.qbus.name);
             break;
         }
@@ -352,7 +352,7 @@ static void handle_control_message(VirtIOSerial *vser, void *buf, size_t len)
 
     case VIRTIO_CONSOLE_PORT_READY:
         if (!cpkt.value) {
-            error_report("virtio-serial-bus: Guest failure in adding port %u for device %s\n",
+            error_report("virtio-serial-bus: Guest failure in adding port %u for device %s",
                          port->id, vser->bus.qbus.name);
             break;
         }
@@ -741,7 +741,7 @@ static int virtser_port_qdev_init(DeviceState *qdev, DeviceInfo *base)
     plugging_port0 = info->is_console && !find_port_by_id(port->vser, 0);
 
     if (find_port_by_id(port->vser, port->id)) {
-        error_report("virtio-serial-bus: A port already exists at id %u\n",
+        error_report("virtio-serial-bus: A port already exists at id %u",
                      port->id);
         return -1;
     }
@@ -752,7 +752,7 @@ static int virtser_port_qdev_init(DeviceState *qdev, DeviceInfo *base)
         } else {
             port->id = find_free_port_id(port->vser);
             if (port->id == VIRTIO_CONSOLE_BAD_ID) {
-                error_report("virtio-serial-bus: Maximum port limit for this device reached\n");
+                error_report("virtio-serial-bus: Maximum port limit for this device reached");
                 return -1;
             }
         }
@@ -760,7 +760,7 @@ static int virtser_port_qdev_init(DeviceState *qdev, DeviceInfo *base)
 
     max_nr_ports = tswap32(port->vser->config.max_nr_ports);
     if (port->id >= max_nr_ports) {
-        error_report("virtio-serial-bus: Out-of-range port id specified, max. allowed: %u\n",
+        error_report("virtio-serial-bus: Out-of-range port id specified, max. allowed: %u",
                      max_nr_ports - 1);
         return -1;
     }
diff --git a/hw/virtio.c b/hw/virtio.c
index e6043de..cc47a06 100644
--- a/hw/virtio.c
+++ b/hw/virtio.c
@@ -797,7 +797,7 @@ int virtio_load(VirtIODevice *vdev, QEMUFile *f)
             /* Check it isn't doing very strange things with descriptor numbers. */
             if (nheads > vdev->vq[i].vring.num) {
                 error_report("VQ %d size 0x%x Guest index 0x%x "
-                             "inconsistent with Host index 0x%x: delta 0x%x\n",
+                             "inconsistent with Host index 0x%x: delta 0x%x",
                              i, vdev->vq[i].vring.num,
                              vring_avail_idx(&vdev->vq[i]),
                              vdev->vq[i].last_avail_idx, nheads);
@@ -805,7 +805,7 @@ int virtio_load(VirtIODevice *vdev, QEMUFile *f)
             }
         } else if (vdev->vq[i].last_avail_idx) {
             error_report("VQ %d address 0x0 "
-                         "inconsistent with Host index 0x%x\n",
+                         "inconsistent with Host index 0x%x",
                          i, vdev->vq[i].last_avail_idx);
                 return -1;
 	}
diff --git a/net.c b/net.c
index a104976..66123ad 100644
--- a/net.c
+++ b/net.c
@@ -710,7 +710,7 @@ int qemu_find_nic_model(NICInfo *nd, const char * const *models,
             return i;
     }
 
-    error_report("qemu: Unsupported NIC model: %s", nd->model);
+    error_report("Unsupported NIC model: %s", nd->model);
     return -1;
 }
 
diff --git a/net/socket.c b/net/socket.c
index 7337f4f..bc1bf58 100644
--- a/net/socket.c
+++ b/net/socket.c
@@ -530,7 +530,7 @@ int net_init_socket(QemuOpts *opts,
             qemu_opt_get(opts, "connect") ||
             qemu_opt_get(opts, "mcast") ||
             qemu_opt_get(opts, "localaddr")) {
-            error_report("listen=, connect=, mcast= and localaddr= is invalid with fd=\n");
+            error_report("listen=, connect=, mcast= and localaddr= is invalid with fd=");
             return -1;
         }
 
@@ -550,7 +550,7 @@ int net_init_socket(QemuOpts *opts,
             qemu_opt_get(opts, "connect") ||
             qemu_opt_get(opts, "mcast") ||
             qemu_opt_get(opts, "localaddr")) {
-            error_report("fd=, connect=, mcast= and localaddr= is invalid with listen=\n");
+            error_report("fd=, connect=, mcast= and localaddr= is invalid with listen=");
             return -1;
         }
 
@@ -566,7 +566,7 @@ int net_init_socket(QemuOpts *opts,
             qemu_opt_get(opts, "listen") ||
             qemu_opt_get(opts, "mcast") ||
             qemu_opt_get(opts, "localaddr")) {
-            error_report("fd=, listen=, mcast= and localaddr= is invalid with connect=\n");
+            error_report("fd=, listen=, mcast= and localaddr= is invalid with connect=");
             return -1;
         }
 
diff --git a/qemu-error.c b/qemu-error.c
index 41c191d..4b20d28 100644
--- a/qemu-error.c
+++ b/qemu-error.c
@@ -193,6 +193,8 @@ void error_print_loc(void)
 
 /*
  * Print an error message to current monitor if we have one, else to stderr.
+ * Format arguments like sprintf().  The result should not contain
+ * newlines.
  * Prepend the current location and append a newline.
  * It's wrong to call this in a QMP monitor.  Use qerror_report() there.
  */
diff --git a/qemu-img.c b/qemu-img.c
index 4f162d1..1a37828 100644
--- a/qemu-img.c
+++ b/qemu-img.c
@@ -690,12 +690,12 @@ static int img_convert(int argc, char **argv)
 
     if (snapshot_name != NULL) {
         if (bs_n > 1) {
-            error_report("No support for concatenating multiple snapshot\n");
+            error_report("No support for concatenating multiple snapshot");
             ret = -1;
             goto out;
         }
         if (bdrv_snapshot_load_tmp(bs[0], snapshot_name) < 0) {
-            error_report("Failed to load snapshot\n");
+            error_report("Failed to load snapshot");
             ret = -1;
             goto out;
         }
commit db78ef5b0a93b16ad56b70a70e21b1c5e7d06ba8
Author: Markus Armbruster <armbru at redhat.com>
Date:   Wed Jun 22 14:03:53 2011 +0200

    sheepdog: qemu_bh_new() can't return null pointer, drop check
    
    Signed-off-by: Markus Armbruster <armbru at redhat.com>
    Signed-off-by: Stefan Hajnoczi <stefanha at linux.vnet.ibm.com>

diff --git a/block/sheepdog.c b/block/sheepdog.c
index 0392ca8..2180299 100644
--- a/block/sheepdog.c
+++ b/block/sheepdog.c
@@ -449,13 +449,7 @@ static int sd_schedule_bh(QEMUBHFunc *cb, SheepdogAIOCB *acb)
     }
 
     acb->bh = qemu_bh_new(cb, acb);
-    if (!acb->bh) {
-        error_report("oom: %d %d\n", acb->aiocb_type, acb->aiocb_type);
-        return -EIO;
-    }
-
     qemu_bh_schedule(acb->bh);
-
     return 0;
 }
 
commit 1802651cb5660d692756f36318e4daed0728c295
Author: Jan Kiszka <jan.kiszka at siemens.com>
Date:   Sun Jun 19 11:53:02 2011 +0200

    Align dummy display to fixed-size active console
    
    This fixes e.g. '-vga none -monitor vc:120Cx50C'.
    
    Signed-off-by: Jan Kiszka <jan.kiszka at siemens.com>
    Signed-off-by: Stefan Hajnoczi <stefanha at linux.vnet.ibm.com>

diff --git a/console.c b/console.c
index 9c6addf..acd8ca1 100644
--- a/console.c
+++ b/console.c
@@ -1349,8 +1349,15 @@ static struct DisplayAllocator default_allocator = {
 static void dumb_display_init(void)
 {
     DisplayState *ds = qemu_mallocz(sizeof(DisplayState));
+    int width = 640;
+    int height = 480;
+
     ds->allocator = &default_allocator;
-    ds->surface = qemu_create_displaysurface(ds, 640, 480);
+    if (is_fixedsize_console()) {
+        width = active_console->g_width;
+        height = active_console->g_height;
+    }
+    ds->surface = qemu_create_displaysurface(ds, width, height);
     register_displaystate(ds);
 }
 
commit f9245e100f12f03338a4e7660879139defb4ae3e
Author: Peter Maydell <peter.maydell at linaro.org>
Date:   Fri Jun 3 17:10:40 2011 +0100

    configure: Don't create symlinks to nonexistent targets
    
    When we create the symlinks to source tree files, don't create them
    if the file is not actually present in the source tree; this will
    happen if the file is in a git submodule that wasn't checked out.
    
    This also avoids the odd effect where an in-source-tree configure
    will end up creating the missing file as a symlink to itself.
    
    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 856b41e..4fa9a57 100755
--- a/configure
+++ b/configure
@@ -3479,7 +3479,9 @@ for bios_file in $source_path/pc-bios/*.bin $source_path/pc-bios/*.rom $source_p
 done
 mkdir -p $DIRS
 for f in $FILES ; do
-    test -e $f || symlink $source_path/$f $f
+    if [ -e "$source_path/$f" ] && ! [ -e "$f" ]; then
+        symlink "$source_path/$f" "$f"
+    fi
 done
 
 # temporary config to build submodules
commit a7fb71d1b2a992a0c4842f06e2b450889e2442ec
Author: Gerd Hoffmann <kraxel at redhat.com>
Date:   Thu Jun 23 17:15:43 2011 +0200

    usb: ignore USB_DT_DEBUG
    
    Signed-off-by: Gerd Hoffmann <kraxel at redhat.com>

diff --git a/hw/usb-desc.c b/hw/usb-desc.c
index 0b9d351..bc6858f 100644
--- a/hw/usb-desc.c
+++ b/hw/usb-desc.c
@@ -385,6 +385,10 @@ int usb_desc_get_descriptor(USBDevice *dev, int value, uint8_t *dest, size_t len
         trace_usb_desc_other_speed_config(dev->addr, index, len, ret);
         break;
 
+    case USB_DT_DEBUG:
+        /* ignore silently */
+        break;
+
     default:
         fprintf(stderr, "%s: %d unknown type %d (len %zd)\n", __FUNCTION__,
                 dev->addr, type, len);
diff --git a/hw/usb.h b/hw/usb.h
index a6b311f..076e2ff 100644
--- a/hw/usb.h
+++ b/hw/usb.h
@@ -130,6 +130,7 @@
 #define USB_DT_ENDPOINT			0x05
 #define USB_DT_DEVICE_QUALIFIER         0x06
 #define USB_DT_OTHER_SPEED_CONFIG       0x07
+#define USB_DT_DEBUG                    0x0A
 #define USB_DT_INTERFACE_ASSOC          0x0B
 
 #define USB_ENDPOINT_XFER_CONTROL	0
commit c3a90cb120e3b274eb87e65fbdd15d4328e8685f
Author: Markus Armbruster <armbru at redhat.com>
Date:   Fri Jun 17 10:52:36 2011 +0200

    usb-storage: Turn drive serial into a qdev property usb-storage.serial
    
    It needs to be a qdev property, because it belongs to the drive's
    guest part.  Precedence: commit a0fef654 and 6ced55a5.
    
    Bonus: info qtree now shows the serial number.
    
    Signed-off-by: Markus Armbruster <armbru at redhat.com>
    Signed-off-by: Gerd Hoffmann <kraxel at redhat.com>

diff --git a/hw/usb-msd.c b/hw/usb-msd.c
index a75948b..86582cc 100644
--- a/hw/usb-msd.c
+++ b/hw/usb-msd.c
@@ -51,6 +51,7 @@ typedef struct {
     SCSIRequest *req;
     SCSIBus bus;
     BlockConf conf;
+    char *serial;
     SCSIDevice *scsi_dev;
     uint32_t removable;
     int result;
@@ -532,9 +533,15 @@ static int usb_msd_initfn(USBDevice *dev)
     bdrv_detach(bs, &s->dev.qdev);
     s->conf.bs = NULL;
 
-    dinfo = drive_get_by_blockdev(bs);
-    if (dinfo && dinfo->serial) {
-        usb_desc_set_string(dev, STR_SERIALNUMBER, dinfo->serial);
+    if (!s->serial) {
+        /* try to fall back to value set with legacy -drive serial=... */
+        dinfo = drive_get_by_blockdev(bs);
+        if (*dinfo->serial) {
+            s->serial = strdup(dinfo->serial);
+        }
+    }
+    if (s->serial) {
+        usb_desc_set_string(dev, STR_SERIALNUMBER, s->serial);
     }
 
     usb_desc_init(dev);
@@ -633,6 +640,7 @@ static struct USBDeviceInfo msd_info = {
     .usbdevice_init = usb_msd_init,
     .qdev.props     = (Property[]) {
         DEFINE_BLOCK_PROPERTIES(MSDState, conf),
+        DEFINE_PROP_STRING("serial", MSDState, serial),
         DEFINE_PROP_BIT("removable", MSDState, removable, 0, false),
         DEFINE_PROP_END_OF_LIST(),
     },
commit 744d3644181ddb16ef5944a0f9217e46961c8c84
Author: Andreas Färber <andreas.faerber at web.de>
Date:   Thu Jun 23 16:24:45 2011 +0200

    coreaudio: Fix OSStatus format specifier
    
    OSStatus type is defined as SInt32. That's signed int on __LP64__ and
    signed long otherwise.
    Since it is an explicit 32-bit-width type, cast to corresponsing POSIX type
    and use PRId32 format specifier. This avoids a warning on ppc64.
    
    Cc: malc <av1474 at comtv.ru>
    Signed-off-by: Andreas Faerber <andreas.faerber at web.de>
    Signed-off-by: malc <av1474 at comtv.ru>

diff --git a/audio/coreaudio.c b/audio/coreaudio.c
index 0c6f1ef..5964c62 100644
--- a/audio/coreaudio.c
+++ b/audio/coreaudio.c
@@ -104,7 +104,7 @@ static void coreaudio_logstatus (OSStatus status)
         break;
 
     default:
-        AUD_log (AUDIO_CAP, "Reason: status code %ld\n", status);
+        AUD_log (AUDIO_CAP, "Reason: status code %" PRId32 "\n", (int32_t)status);
         return;
     }
 
commit cbc36cb05d56bc510e85d14059ee0ae2ae6e3126
Author: Andreas Färber <andreas.faerber at web.de>
Date:   Thu Jun 23 16:24:46 2011 +0200

    coreaudio: Avoid formatting UInt32 type
    
    coreaudioVoiceOut's audioDevicePropertyBufferFrameSize is defined as UInt32
    and is being used by reference for AudioDevice{Get,Set}Property().
    UInt32 is unsigned int on __LP64__ but unsigned long otherwise.
    
    Cast to POSIX type and use PRIu32 format specifier to hide the details.
    This avoids a warning on ppc64.
    
    Cc: malc <av1474 at comtv.ru>
    Signed-off-by: Andreas Faerber <andreas.faerber at web.de>
    Signed-off-by: malc <av1474 at comtv.ru>

diff --git a/audio/coreaudio.c b/audio/coreaudio.c
index 3bd75cd..0c6f1ef 100644
--- a/audio/coreaudio.c
+++ b/audio/coreaudio.c
@@ -360,8 +360,8 @@ static int coreaudio_init_out (HWVoiceOut *hw, struct audsettings *as)
         &core->audioDevicePropertyBufferFrameSize);
     if (status != kAudioHardwareNoError) {
         coreaudio_logerr2 (status, typ,
-                           "Could not set device buffer frame size %ld\n",
-                           core->audioDevicePropertyBufferFrameSize);
+                           "Could not set device buffer frame size %" PRIu32 "\n",
+                           (uint32_t)core->audioDevicePropertyBufferFrameSize);
         return -1;
     }
 
commit f3dc0051dcd68b395861b6f1f3d5a900d44bd767
Author: Peter Maydell <peter.maydell at linaro.org>
Date:   Wed Jun 15 18:22:35 2011 +0100

    hw/usb-ohci.c: Fix handling of remote wakeup corner cases
    
    Correct a number of minor errors in the OHCI wakeup implementation:
     * when the port is suspended but the controller is not, raise RHSC
     * when the controller is suspended but the port is not, raise RD
     * when the controller is suspended, move it to resume state
    
    These fix some edge cases where a USB device might not successfully get
    the attention of the guest OS if it tried to do so at the wrong time.
    
    Signed-off-by: Peter Maydell <peter.maydell at linaro.org>
    Signed-off-by: Gerd Hoffmann <kraxel at redhat.com>

diff --git a/hw/usb-ohci.c b/hw/usb-ohci.c
index 5d2ae01..1c29b9f 100644
--- a/hw/usb-ohci.c
+++ b/hw/usb-ohci.c
@@ -373,14 +373,25 @@ static void ohci_wakeup(USBDevice *dev)
     OHCIState *s = container_of(bus, OHCIState, bus);
     int portnum = dev->port->index;
     OHCIPort *port = &s->rhport[portnum];
+    uint32_t intr = 0;
     if (port->ctrl & OHCI_PORT_PSS) {
         DPRINTF("usb-ohci: port %d: wakeup\n", portnum);
         port->ctrl |= OHCI_PORT_PSSC;
         port->ctrl &= ~OHCI_PORT_PSS;
-        if ((s->ctl & OHCI_CTL_HCFS) == OHCI_USB_SUSPEND) {
-            ohci_set_interrupt(s, OHCI_INTR_RD);
-        }
+        intr = OHCI_INTR_RHSC;
+    }
+    /* Note that the controller can be suspended even if this port is not */
+    if ((s->ctl & OHCI_CTL_HCFS) == OHCI_USB_SUSPEND) {
+        DPRINTF("usb-ohci: remote-wakeup: SUSPEND->RESUME\n");
+        /* This is the one state transition the controller can do by itself */
+        s->ctl &= ~OHCI_CTL_HCFS;
+        s->ctl |= OHCI_USB_RESUME;
+        /* In suspend mode only ResumeDetected is possible, not RHSC:
+         * see the OHCI spec 5.1.2.3.
+         */
+        intr = OHCI_INTR_RD;
     }
+    ohci_set_interrupt(s, intr);
 }
 
 /* Reset the controller */
commit bf5547f5365c1bfeba9d5c3e87653b9803a875a5
Author: Hans de Goede <hdegoede at redhat.com>
Date:   Fri May 27 14:50:39 2011 +0200

    usb-bus: Don't allow speed mismatch while attaching devices
    
    Signed-off-by: Gerd Hoffmann <kraxel at redhat.com>

diff --git a/hw/usb-bus.c b/hw/usb-bus.c
index fc72018..2abce12 100644
--- a/hw/usb-bus.c
+++ b/hw/usb-bus.c
@@ -200,6 +200,11 @@ static int do_attach(USBDevice *dev)
     } else {
         port = QTAILQ_FIRST(&bus->free);
     }
+    if (!(port->speedmask & dev->speedmask)) {
+        error_report("Warning: speed mismatch trying to attach usb device %s to bus %s\n",
+                dev->product_desc, bus->qbus.name);
+        return -1;
+    }
 
     dev->attached++;
     QTAILQ_REMOVE(&bus->free, port, next);
commit e4b17767659828cf4057e39b6a4f9d687b2f7cc3
Author: Hans de Goede <hdegoede at redhat.com>
Date:   Mon May 30 11:40:45 2011 +0200

    usb-linux: allow "compatible" high speed devices to connect at fullspeed
    
    Some usb2 highspeed devices, like usb-msd devices, work fine when redirected
    to a usb1 virtual controller. Allow this to avoid the new speedhecks causing
    regressions for users who do not enable the new experimental ehci code.
    
    Signed-off-by: Gerd Hoffmann <kraxel at redhat.com>

diff --git a/usb-linux.c b/usb-linux.c
index 4d22c9c..1a2deb3 100644
--- a/usb-linux.c
+++ b/usb-linux.c
@@ -1088,6 +1088,42 @@ static int usb_linux_update_endp_table(USBHostDevice *s)
     return 0;
 }
 
+/*
+ * Check if we can safely redirect a usb2 device to a usb1 virtual controller,
+ * this function assumes this is safe, if:
+ * 1) There are no isoc endpoints
+ * 2) There are no interrupt endpoints with a max_packet_size > 64
+ * Note bulk endpoints with a max_packet_size > 64 in theory also are not
+ * usb1 compatible, but in practice this seems to work fine.
+ */
+static int usb_linux_full_speed_compat(USBHostDevice *dev)
+{
+    int i, packet_size;
+
+    /*
+     * usb_linux_update_endp_table only registers info about ep in the current
+     * interface altsettings, so we need to parse the descriptors again.
+     */
+    for (i = 0; (i + 5) < dev->descr_len; i += dev->descr[i]) {
+        if (dev->descr[i + 1] == USB_DT_ENDPOINT) {
+            switch (dev->descr[i + 3] & 0x3) {
+            case 0x00: /* CONTROL */
+                break;
+            case 0x01: /* ISO */
+                return 0;
+            case 0x02: /* BULK */
+                break;
+            case 0x03: /* INTERRUPT */
+                packet_size = dev->descr[i + 4] + (dev->descr[i + 5] << 8);
+                if (packet_size > 64)
+                    return 0;
+                break;
+            }
+        }
+    }
+    return 1;
+}
+
 static int usb_host_open(USBHostDevice *dev, int bus_num,
                         int addr, char *port, const char *prod_name, int speed)
 {
@@ -1168,6 +1204,9 @@ static int usb_host_open(USBHostDevice *dev, int bus_num,
     }
     dev->dev.speed = speed;
     dev->dev.speedmask = (1 << speed);
+    if (dev->dev.speed == USB_SPEED_HIGH && usb_linux_full_speed_compat(dev)) {
+        dev->dev.speedmask |= USB_SPEED_MASK_FULL;
+    }
 
     printf("husb: grabbed usb device %d.%d\n", bus_num, addr);
 
commit ba3f9bfba9ad8d2bbcb9a9fa9ed0f07347fc1c58
Author: Hans de Goede <hdegoede at redhat.com>
Date:   Fri May 27 14:27:18 2011 +0200

    usb: Add a speedmask to devices
    
    This is used to indicate at which speed[s] the device can operate,
    so that this can be checked to match the ports capabilities when it gets
    attached to a bus.
    
    Note that currently all usb1 emulated device claim to be fullspeed, this
    seems to not cause any problems, but still seems wrong, because with real
    hardware keyboards, mice and tablets usually are lo-speed, so reporting these
    as fullspeed devices seems wrong.
    
    Signed-off-by: Gerd Hoffmann <kraxel at redhat.com>

diff --git a/hw/usb-ccid.c b/hw/usb-ccid.c
index 59c6431..30bb4d6 100644
--- a/hw/usb-ccid.c
+++ b/hw/usb-ccid.c
@@ -1271,6 +1271,7 @@ static int ccid_initfn(USBDevice *dev)
     s->migration_target_ip = 0;
     s->migration_target_port = 0;
     s->dev.speed = USB_SPEED_FULL;
+    s->dev.speedmask = USB_SPEED_MASK_FULL;
     s->notify_slot_change = false;
     s->powered = true;
     s->pending_answers_num = 0;
diff --git a/hw/usb-desc.c b/hw/usb-desc.c
index e4a4680..0b9d351 100644
--- a/hw/usb-desc.c
+++ b/hw/usb-desc.c
@@ -242,7 +242,17 @@ static void usb_desc_setdefaults(USBDevice *dev)
 
 void usb_desc_init(USBDevice *dev)
 {
+    const USBDesc *desc = dev->info->usb_desc;
+
+    assert(desc != NULL);
     dev->speed = USB_SPEED_FULL;
+    dev->speedmask = 0;
+    if (desc->full) {
+        dev->speedmask |= USB_SPEED_MASK_FULL;
+    }
+    if (desc->high) {
+        dev->speedmask |= USB_SPEED_MASK_HIGH;
+    }
     usb_desc_setdefaults(dev);
 }
 
diff --git a/hw/usb.h b/hw/usb.h
index 06ce058..a6b311f 100644
--- a/hw/usb.h
+++ b/hw/usb.h
@@ -168,7 +168,10 @@ struct USBDevice {
     char *port_path;
     void *opaque;
 
+    /* Actual connected speed */
     int speed;
+    /* Supported speeds, not in info because it may be variable (hostdevs) */
+    int speedmask;
     uint8_t addr;
     char product_desc[32];
     int auto_attach;
diff --git a/usb-bsd.c b/usb-bsd.c
index c1bcc4a..3b97eb4 100644
--- a/usb-bsd.c
+++ b/usb-bsd.c
@@ -367,8 +367,10 @@ USBDevice *usb_host_device_open(const char *devname)
 
     if (dev_info.udi_speed == 1) {
         dev->dev.speed = USB_SPEED_LOW - 1;
+        dev->dev.speedmask = USB_SPEED_MASK_LOW;
     } else {
         dev->dev.speed = USB_SPEED_FULL - 1;
+        dev->dev.speedmask = USB_SPEED_MASK_FULL;
     }
 
     if (strncmp(dev_info.udi_product, "product", 7) != 0) {
diff --git a/usb-linux.c b/usb-linux.c
index 9b6f2be..4d22c9c 100644
--- a/usb-linux.c
+++ b/usb-linux.c
@@ -1167,6 +1167,7 @@ static int usb_host_open(USBHostDevice *dev, int bus_num,
         }
     }
     dev->dev.speed = speed;
+    dev->dev.speedmask = (1 << speed);
 
     printf("husb: grabbed usb device %d.%d\n", bus_num, addr);
 
commit fa19bf831b8c87006533645ece58bc620aca00bc
Author: Hans de Goede <hdegoede at redhat.com>
Date:   Fri May 27 19:05:15 2011 +0200

    usb: Proper error propagation for usb_device_attach errors
    
    Signed-off-by: Gerd Hoffmann <kraxel at redhat.com>

diff --git a/hw/usb-bus.c b/hw/usb-bus.c
index 0a49921..fc72018 100644
--- a/hw/usb-bus.c
+++ b/hw/usb-bus.c
@@ -75,7 +75,7 @@ static int usb_qdev_init(DeviceState *qdev, DeviceInfo *base)
     QLIST_INIT(&dev->strings);
     rc = dev->info->init(dev);
     if (rc == 0 && dev->auto_attach)
-        usb_device_attach(dev);
+        rc = usb_device_attach(dev);
     return rc;
 }
 
@@ -121,7 +121,7 @@ USBDevice *usb_create(USBBus *bus, const char *name)
         bus = usb_bus_find(-1);
         if (!bus)
             return NULL;
-        fprintf(stderr, "%s: no bus specified, using \"%s\" for \"%s\"\n",
+        error_report("%s: no bus specified, using \"%s\" for \"%s\"\n",
                 __FUNCTION__, bus->qbus.name, name);
     }
 #endif
@@ -171,20 +171,20 @@ void usb_unregister_port(USBBus *bus, USBPort *port)
     bus->nfree--;
 }
 
-static void do_attach(USBDevice *dev)
+static int do_attach(USBDevice *dev)
 {
     USBBus *bus = usb_bus_from_device(dev);
     USBPort *port;
 
     if (dev->attached) {
-        fprintf(stderr, "Warning: tried to attach usb device %s twice\n",
+        error_report("Error: tried to attach usb device %s twice\n",
                 dev->product_desc);
-        return;
+        return -1;
     }
     if (bus->nfree == 0) {
-        fprintf(stderr, "Warning: tried to attach usb device %s to a bus with no free ports\n",
+        error_report("Error: tried to attach usb device %s to a bus with no free ports\n",
                 dev->product_desc);
-        return;
+        return -1;
     }
     if (dev->port_path) {
         QTAILQ_FOREACH(port, &bus->free, next) {
@@ -193,9 +193,9 @@ static void do_attach(USBDevice *dev)
             }
         }
         if (port == NULL) {
-            fprintf(stderr, "Warning: usb port %s (bus %s) not found\n",
+            error_report("Error: usb port %s (bus %s) not found\n",
                     dev->port_path, bus->qbus.name);
-            return;
+            return -1;
         }
     } else {
         port = QTAILQ_FIRST(&bus->free);
@@ -209,6 +209,8 @@ static void do_attach(USBDevice *dev)
 
     QTAILQ_INSERT_TAIL(&bus->used, port, next);
     bus->nused++;
+
+    return 0;
 }
 
 int usb_device_attach(USBDevice *dev)
@@ -220,8 +222,7 @@ int usb_device_attach(USBDevice *dev)
            (unless a physical port location is specified). */
         usb_create_simple(bus, "usb-hub");
     }
-    do_attach(dev);
-    return 0;
+    return do_attach(dev);
 }
 
 int usb_device_detach(USBDevice *dev)
@@ -230,7 +231,7 @@ int usb_device_detach(USBDevice *dev)
     USBPort *port;
 
     if (!dev->attached) {
-        fprintf(stderr, "Warning: tried to detach unattached usb device %s\n",
+        error_report("Error: tried to detach unattached usb device %s\n",
                 dev->product_desc);
         return -1;
     }
diff --git a/hw/usb-msd.c b/hw/usb-msd.c
index c59797b..a75948b 100644
--- a/hw/usb-msd.c
+++ b/hw/usb-msd.c
@@ -497,8 +497,9 @@ static void usb_msd_password_cb(void *opaque, int err)
     MSDState *s = opaque;
 
     if (!err)
-        usb_device_attach(&s->dev);
-    else
+        err = usb_device_attach(&s->dev);
+
+    if (err)
         qdev_unplug(&s->dev.qdev);
 }
 
diff --git a/usb-linux.c b/usb-linux.c
index 42baafe..9b6f2be 100644
--- a/usb-linux.c
+++ b/usb-linux.c
@@ -1178,10 +1178,14 @@ static int usb_host_open(USBHostDevice *dev, int bus_num,
                 prod_name);
     }
 
+    ret = usb_device_attach(&dev->dev);
+    if (ret) {
+        goto fail;
+    }
+
     /* USB devio uses 'write' flag to check for async completions */
     qemu_set_fd_handler(dev->fd, NULL, async_complete, dev);
 
-    usb_device_attach(&dev->dev);
     return 0;
 
 fail:
commit ee210d6390761bb0fd6febe0fb8f94ee0dcba0db
Author: Hans de Goede <hdegoede at redhat.com>
Date:   Fri May 27 14:46:27 2011 +0200

    usb-bus: Don't allow attaching a device to a bus with no free ports
    
    Signed-off-by: Gerd Hoffmann <kraxel at redhat.com>

diff --git a/hw/usb-bus.c b/hw/usb-bus.c
index 480956d..0a49921 100644
--- a/hw/usb-bus.c
+++ b/hw/usb-bus.c
@@ -181,6 +181,11 @@ static void do_attach(USBDevice *dev)
                 dev->product_desc);
         return;
     }
+    if (bus->nfree == 0) {
+        fprintf(stderr, "Warning: tried to attach usb device %s to a bus with no free ports\n",
+                dev->product_desc);
+        return;
+    }
     if (dev->port_path) {
         QTAILQ_FOREACH(port, &bus->free, next) {
             if (strcmp(port->path, dev->port_path) == 0) {
commit adddecb169c63913786dcf3a5879e89a300dbb20
Author: Gerd Hoffmann <kraxel at redhat.com>
Date:   Tue May 31 12:23:13 2011 +0200

    ehci: switch to nanoseconds
    
    Make ehci use nanoseconds everywhere.
    Simplifies time calculations.
    
    Signed-off-by: Gerd Hoffmann <kraxel at redhat.com>

diff --git a/hw/usb-ehci.c b/hw/usb-ehci.c
index fa9792e..91fb7de 100644
--- a/hw/usb-ehci.c
+++ b/hw/usb-ehci.c
@@ -130,7 +130,7 @@
 #define PORTSC_CONNECT       (1 << 0)     // Current Connect Status
 
 #define FRAME_TIMER_FREQ 1000
-#define FRAME_TIMER_USEC (1000000 / FRAME_TIMER_FREQ)
+#define FRAME_TIMER_NS   (1000000000 / FRAME_TIMER_FREQ)
 
 #define NB_MAXINTRATE    8        // Max rate at which controller issues ints
 #define NB_PORTS         4        // Number of downstream ports
@@ -348,7 +348,8 @@ struct EHCIQueue {
     EHCIState *ehci;
     QTAILQ_ENTRY(EHCIQueue) next;
     bool async_schedule;
-    uint32_t seen, ts;
+    uint32_t seen;
+    uint64_t ts;
 
     /* cached data from guest - needs to be flushed
      * when guest removes an entry (doorbell, handshake sequence)
@@ -418,12 +419,11 @@ struct EHCIState {
     uint8_t ibuffer[BUFF_SIZE];
     int isoch_pause;
 
-    uint32_t last_run_usec;
-    uint32_t frame_end_usec;
+    uint64_t last_run_ns;
 };
 
 #define SET_LAST_RUN_CLOCK(s) \
-    (s)->last_run_usec = qemu_get_clock_ns(vm_clock) / 1000;
+    (s)->last_run_ns = qemu_get_clock_ns(vm_clock);
 
 /* nifty macros from Arnon's EHCI version  */
 #define get_field(data, field) \
@@ -690,10 +690,10 @@ static void ehci_queues_rip_unused(EHCIState *ehci)
     QTAILQ_FOREACH_SAFE(q, &ehci->queues, next, tmp) {
         if (q->seen) {
             q->seen = 0;
-            q->ts = ehci->last_run_usec;
+            q->ts = ehci->last_run_ns;
             continue;
         }
-        if (ehci->last_run_usec < q->ts + 250000) {
+        if (ehci->last_run_ns < q->ts + 250000000) {
             /* allow 0.25 sec idle */
             continue;
         }
@@ -2045,23 +2045,16 @@ static void ehci_frame_timer(void *opaque)
 {
     EHCIState *ehci = opaque;
     int64_t expire_time, t_now;
-    int usec_elapsed;
+    uint64_t ns_elapsed;
     int frames;
-    int usec_now;
     int i;
     int skipped_frames = 0;
 
-
     t_now = qemu_get_clock_ns(vm_clock);
     expire_time = t_now + (get_ticks_per_sec() / ehci->freq);
-    if (expire_time == t_now) {
-        expire_time++;
-    }
 
-    usec_now = t_now / 1000;
-    usec_elapsed = usec_now - ehci->last_run_usec;
-    frames = usec_elapsed / FRAME_TIMER_USEC;
-    ehci->frame_end_usec = usec_now + FRAME_TIMER_USEC - 10;
+    ns_elapsed = t_now - ehci->last_run_ns;
+    frames = ns_elapsed / FRAME_TIMER_NS;
 
     for (i = 0; i < frames; i++) {
         if ( !(ehci->usbsts & USBSTS_HALT)) {
@@ -2084,7 +2077,7 @@ static void ehci_frame_timer(void *opaque)
             ehci_advance_periodic_state(ehci);
         }
 
-        ehci->last_run_usec += FRAME_TIMER_USEC;
+        ehci->last_run_ns += FRAME_TIMER_NS;
     }
 
 #if 0
commit 16a2dee6b98ec0d4f60fa17f78ca989ce5c7f831
Author: Gerd Hoffmann <kraxel at redhat.com>
Date:   Mon May 30 16:24:29 2011 +0200

    ehci: add freq + maxframes properties
    
    Add properties for the wakeup rate and the max number of frames ehci
    will process at once.
    
    The wakeup rate defaults to 1000 which equals the usb frame rate.  This
    can be reduced to make qemu wake up less often when ehci is active.
    
    In case the wakeup rate is reduced or the ehci timer is delayed due to
    latency issues elsewhere in qemu ehci will process multiple frames at
    once.  The maxframes property specifies the upper limit for this.
    
    Signed-off-by: Gerd Hoffmann <kraxel at redhat.com>

diff --git a/hw/usb-ehci.c b/hw/usb-ehci.c
index e33e546..fa9792e 100644
--- a/hw/usb-ehci.c
+++ b/hw/usb-ehci.c
@@ -373,6 +373,11 @@ struct EHCIState {
     target_phys_addr_t mem_base;
     int mem;
     int num_ports;
+
+    /* properties */
+    uint32_t freq;
+    uint32_t maxframes;
+
     /*
      *  EHCI spec version 1.0 Section 2.3
      *  Host Controller Operational Registers
@@ -2048,7 +2053,7 @@ static void ehci_frame_timer(void *opaque)
 
 
     t_now = qemu_get_clock_ns(vm_clock);
-    expire_time = t_now + (get_ticks_per_sec() / FRAME_TIMER_FREQ);
+    expire_time = t_now + (get_ticks_per_sec() / ehci->freq);
     if (expire_time == t_now) {
         expire_time++;
     }
@@ -2073,7 +2078,7 @@ static void ehci_frame_timer(void *opaque)
             ehci->sofv &= 0x000003ff;
         }
 
-        if (frames - i > 10) {
+        if (frames - i > ehci->maxframes) {
             skipped_frames++;
         } else {
             ehci_advance_periodic_state(ehci);
@@ -2146,6 +2151,11 @@ static PCIDeviceInfo ehci_info = {
     .device_id    = PCI_DEVICE_ID_INTEL_82801D,
     .revision     = 0x10,
     .class_id     = PCI_CLASS_SERIAL_USB,
+    .qdev.props   = (Property[]) {
+        DEFINE_PROP_UINT32("freq",      EHCIState, freq, FRAME_TIMER_FREQ),
+        DEFINE_PROP_UINT32("maxframes", EHCIState, maxframes, 128),
+        DEFINE_PROP_END_OF_LIST(),
+    },
 };
 
 static int usb_ehci_initfn(PCIDevice *dev)
commit 82887262569d9222befadb6a98bf364beae30a7e
Author: Gerd Hoffmann <kraxel at redhat.com>
Date:   Fri Jun 10 14:00:24 2011 +0200

    usb-linux: track inflight iso urb count
    
    Track the number of iso urbs which are currently in flight.
    Log a message in case the count goes down to zero.  Also
    warn in case many urbs are returned at the same time.
    
    Signed-off-by: Gerd Hoffmann <kraxel at redhat.com>

diff --git a/usb-linux.c b/usb-linux.c
index f65dcb7..42baafe 100644
--- a/usb-linux.c
+++ b/usb-linux.c
@@ -100,6 +100,7 @@ struct endp_data {
     int iso_urb_idx;
     int iso_buffer_used;
     int max_packet_size;
+    int inflight;
 };
 
 struct USBAutoFilter {
@@ -184,7 +185,19 @@ static void clear_iso_started(USBHostDevice *s, int ep)
 
 static void set_iso_started(USBHostDevice *s, int ep)
 {
-    get_endp(s, ep)->iso_started = 1;
+    struct endp_data *e = get_endp(s, ep);
+    if (!e->iso_started) {
+        e->iso_started = 1;
+        e->inflight = 0;
+    }
+}
+
+static int change_iso_inflight(USBHostDevice *s, int ep, int value)
+{
+    struct endp_data *e = get_endp(s, ep);
+
+    e->inflight += value;
+    return e->inflight;
 }
 
 static void set_iso_urb(USBHostDevice *s, int ep, AsyncURB *iso_urb)
@@ -282,6 +295,7 @@ static void async_complete(void *opaque)
 {
     USBHostDevice *s = opaque;
     AsyncURB *aurb;
+    int urbs = 0;
 
     while (1) {
         USBPacket *p;
@@ -289,6 +303,9 @@ static void async_complete(void *opaque)
         int r = ioctl(s->fd, USBDEVFS_REAPURBNDELAY, &aurb);
         if (r < 0) {
             if (errno == EAGAIN) {
+                if (urbs > 2) {
+                    fprintf(stderr, "husb: %d iso urbs finished at once\n", urbs);
+                }
                 return;
             }
             if (errno == ENODEV && !s->closing) {
@@ -306,10 +323,16 @@ static void async_complete(void *opaque)
         /* If this is a buffered iso urb mark it as complete and don't do
            anything else (it is handled further in usb_host_handle_iso_data) */
         if (aurb->iso_frame_idx == -1) {
+            int inflight;
             if (aurb->urb.status == -EPIPE) {
                 set_halt(s, aurb->urb.endpoint & 0xf);
             }
             aurb->iso_frame_idx = 0;
+            urbs++;
+            inflight = change_iso_inflight(s, aurb->urb.endpoint & 0xf, -1);
+            if (inflight == 0 && is_iso_started(s, aurb->urb.endpoint & 0xf)) {
+                fprintf(stderr, "husb: out of buffers for iso stream\n");
+            }
             continue;
         }
 
@@ -670,6 +693,7 @@ static int usb_host_handle_iso_data(USBHostDevice *s, USBPacket *p, int in)
                     break;
                 }
                 aurb[i].iso_frame_idx = -1;
+                change_iso_inflight(s, p->devep, +1);
             }
         }
     }
commit b81bcd8aa0f5d16e5590fdc4cf6561b57adab931
Author: Gerd Hoffmann <kraxel at redhat.com>
Date:   Fri Jun 10 14:03:56 2011 +0200

    usb-linux: make iso urb count contigurable
    
    Add a qdev property for the number of iso urbs which
    usb-linux keeps in flight, so it can be configured at
    runtime.  Make it default to four (old hardcoded value
    used to be three).
    
    Signed-off-by: Gerd Hoffmann <kraxel at redhat.com>

diff --git a/usb-linux.c b/usb-linux.c
index 3c6156a..f65dcb7 100644
--- a/usb-linux.c
+++ b/usb-linux.c
@@ -85,7 +85,6 @@ static int usb_fs_type;
 
 /* endpoint association data */
 #define ISO_FRAME_DESC_PER_URB 32
-#define ISO_URB_COUNT 3
 #define INVALID_EP_TYPE 255
 
 /* devio.c limits single requests to 16k */
@@ -120,6 +119,7 @@ typedef struct USBHostDevice {
     int       configuration;
     int       ninterfaces;
     int       closing;
+    uint32_t  iso_urb_count;
     Notifier  exit;
 
     struct endp_data endp_table[MAX_ENDPOINTS];
@@ -505,8 +505,8 @@ static AsyncURB *usb_host_alloc_iso(USBHostDevice *s, uint8_t ep, int in)
     AsyncURB *aurb;
     int i, j, len = get_max_packet_size(s, ep);
 
-    aurb = qemu_mallocz(ISO_URB_COUNT * sizeof(*aurb));
-    for (i = 0; i < ISO_URB_COUNT; i++) {
+    aurb = qemu_mallocz(s->iso_urb_count * sizeof(*aurb));
+    for (i = 0; i < s->iso_urb_count; i++) {
         aurb[i].urb.endpoint      = ep;
         aurb[i].urb.buffer_length = ISO_FRAME_DESC_PER_URB * len;
         aurb[i].urb.buffer        = qemu_malloc(aurb[i].urb.buffer_length);
@@ -536,7 +536,7 @@ static void usb_host_stop_n_free_iso(USBHostDevice *s, uint8_t ep)
         return;
     }
 
-    for (i = 0; i < ISO_URB_COUNT; i++) {
+    for (i = 0; i < s->iso_urb_count; i++) {
         /* in flight? */
         if (aurb[i].iso_frame_idx == -1) {
             ret = ioctl(s->fd, USBDEVFS_DISCARDURB, &aurb[i]);
@@ -554,7 +554,7 @@ static void usb_host_stop_n_free_iso(USBHostDevice *s, uint8_t ep)
         async_complete(s);
     }
 
-    for (i = 0; i < ISO_URB_COUNT; i++) {
+    for (i = 0; i < s->iso_urb_count; i++) {
         qemu_free(aurb[i].urb.buffer);
     }
 
@@ -639,7 +639,7 @@ static int usb_host_handle_iso_data(USBHostDevice *s, USBPacket *p, int in)
         }
         aurb[i].iso_frame_idx++;
         if (aurb[i].iso_frame_idx == ISO_FRAME_DESC_PER_URB) {
-            i = (i + 1) % ISO_URB_COUNT;
+            i = (i + 1) % s->iso_urb_count;
             set_iso_urb_idx(s, p->devep, i);
         }
     } else {
@@ -652,7 +652,7 @@ static int usb_host_handle_iso_data(USBHostDevice *s, USBPacket *p, int in)
 
     if (is_iso_started(s, p->devep)) {
         /* (Re)-submit all fully consumed / filled urbs */
-        for (i = 0; i < ISO_URB_COUNT; i++) {
+        for (i = 0; i < s->iso_urb_count; i++) {
             if (aurb[i].iso_frame_idx == ISO_FRAME_DESC_PER_URB) {
                 ret = ioctl(s->fd, USBDEVFS_SUBMITURB, &aurb[i]);
                 if (ret < 0) {
@@ -1233,6 +1233,7 @@ static struct USBDeviceInfo usb_host_dev_info = {
         DEFINE_PROP_STRING("hostport", USBHostDevice, match.port),
         DEFINE_PROP_HEX32("vendorid",  USBHostDevice, match.vendor_id,  0),
         DEFINE_PROP_HEX32("productid", USBHostDevice, match.product_id, 0),
+        DEFINE_PROP_UINT32("isobufs",  USBHostDevice, iso_urb_count,    4),
         DEFINE_PROP_END_OF_LIST(),
     },
 };
commit ca3a36cf2b86a752fde4b1c545bd2a5a6c811f44
Author: Gerd Hoffmann <kraxel at redhat.com>
Date:   Fri Jun 10 13:34:10 2011 +0200

    usb-linux: add get_endp()
    
    Add a helper function to get the endpoint data structure
    and put it into use.
    
    Signed-off-by: Gerd Hoffmann <kraxel at redhat.com>

diff --git a/usb-linux.c b/usb-linux.c
index 5d2ec5c..3c6156a 100644
--- a/usb-linux.c
+++ b/usb-linux.c
@@ -142,74 +142,79 @@ static void usb_host_auto_check(void *unused);
 static int usb_host_read_file(char *line, size_t line_size,
                             const char *device_file, const char *device_name);
 
+static struct endp_data *get_endp(USBHostDevice *s, int ep)
+{
+    return s->endp_table + ep - 1;
+}
+
 static int is_isoc(USBHostDevice *s, int ep)
 {
-    return s->endp_table[ep - 1].type == USBDEVFS_URB_TYPE_ISO;
+    return get_endp(s, ep)->type == USBDEVFS_URB_TYPE_ISO;
 }
 
 static int is_valid(USBHostDevice *s, int ep)
 {
-    return s->endp_table[ep - 1].type != INVALID_EP_TYPE;
+    return get_endp(s, ep)->type != INVALID_EP_TYPE;
 }
 
 static int is_halted(USBHostDevice *s, int ep)
 {
-    return s->endp_table[ep - 1].halted;
+    return get_endp(s, ep)->halted;
 }
 
 static void clear_halt(USBHostDevice *s, int ep)
 {
-    s->endp_table[ep - 1].halted = 0;
+    get_endp(s, ep)->halted = 0;
 }
 
 static void set_halt(USBHostDevice *s, int ep)
 {
-    s->endp_table[ep - 1].halted = 1;
+    get_endp(s, ep)->halted = 1;
 }
 
 static int is_iso_started(USBHostDevice *s, int ep)
 {
-    return s->endp_table[ep - 1].iso_started;
+    return get_endp(s, ep)->iso_started;
 }
 
 static void clear_iso_started(USBHostDevice *s, int ep)
 {
-    s->endp_table[ep - 1].iso_started = 0;
+    get_endp(s, ep)->iso_started = 0;
 }
 
 static void set_iso_started(USBHostDevice *s, int ep)
 {
-    s->endp_table[ep - 1].iso_started = 1;
+    get_endp(s, ep)->iso_started = 1;
 }
 
 static void set_iso_urb(USBHostDevice *s, int ep, AsyncURB *iso_urb)
 {
-    s->endp_table[ep - 1].iso_urb = iso_urb;
+    get_endp(s, ep)->iso_urb = iso_urb;
 }
 
 static AsyncURB *get_iso_urb(USBHostDevice *s, int ep)
 {
-    return s->endp_table[ep - 1].iso_urb;
+    return get_endp(s, ep)->iso_urb;
 }
 
 static void set_iso_urb_idx(USBHostDevice *s, int ep, int i)
 {
-    s->endp_table[ep - 1].iso_urb_idx = i;
+    get_endp(s, ep)->iso_urb_idx = i;
 }
 
 static int get_iso_urb_idx(USBHostDevice *s, int ep)
 {
-    return s->endp_table[ep - 1].iso_urb_idx;
+    return get_endp(s, ep)->iso_urb_idx;
 }
 
 static void set_iso_buffer_used(USBHostDevice *s, int ep, int i)
 {
-    s->endp_table[ep - 1].iso_buffer_used = i;
+    get_endp(s, ep)->iso_buffer_used = i;
 }
 
 static int get_iso_buffer_used(USBHostDevice *s, int ep)
 {
-    return s->endp_table[ep - 1].iso_buffer_used;
+    return get_endp(s, ep)->iso_buffer_used;
 }
 
 static void set_max_packet_size(USBHostDevice *s, int ep, uint8_t *descriptor)
@@ -223,14 +228,12 @@ static void set_max_packet_size(USBHostDevice *s, int ep, uint8_t *descriptor)
     case 2:  microframes = 3; break;
     default: microframes = 1; break;
     }
-    DPRINTF("husb: max packet size: 0x%x -> %d x %d\n",
-            raw, microframes, size);
-    s->endp_table[ep - 1].max_packet_size = size * microframes;
+    get_endp(s, ep)->max_packet_size = size * microframes;
 }
 
 static int get_max_packet_size(USBHostDevice *s, int ep)
 {
-    return s->endp_table[ep - 1].max_packet_size;
+    return get_endp(s, ep)->max_packet_size;
 }
 
 /*
commit 48e2faf222cbf4abab7c8e4b3f44229ec98eae7f
Author: Peter Maydell <peter.maydell at linaro.org>
Date:   Fri May 20 16:50:01 2011 +0100

    net: Warn about "-net nic" options which were ignored
    
    Diagnose the case where the user asked for a NIC via "-net nic"
    but the board didn't instantiate that NIC (for example where the
    user asked for two NICs but the board only supports one). Note
    that this diagnostic doesn't apply to NICs created through -device,
    because those are always instantiated.
    
    Signed-off-by: Peter Maydell <peter.maydell at linaro.org>
    Signed-off-by: Anthony Liguori <aliguori at us.ibm.com>

diff --git a/hw/qdev.c b/hw/qdev.c
index 9519f5d..2987901 100644
--- a/hw/qdev.c
+++ b/hw/qdev.c
@@ -468,6 +468,7 @@ void qdev_set_nic_properties(DeviceState *dev, NICInfo *nd)
         qdev_prop_exists(dev, "vectors")) {
         qdev_prop_set_uint32(dev, "vectors", nd->nvectors);
     }
+    nd->instantiated = 1;
 }
 
 BusState *qdev_get_child_bus(DeviceState *dev, const char *name)
diff --git a/net.c b/net.c
index 68c2840..a104976 100644
--- a/net.c
+++ b/net.c
@@ -1304,6 +1304,7 @@ void net_check_clients(void)
 {
     VLANState *vlan;
     VLANClientState *vc;
+    int i;
 
     /* Don't warn about the default network setup that you get if
      * no command line -net or -netdev options are specified. There
@@ -1348,6 +1349,20 @@ void net_check_clients(void)
                     vc->name);
         }
     }
+
+    /* Check that all NICs requested via -net nic actually got created.
+     * NICs created via -device don't need to be checked here because
+     * they are always instantiated.
+     */
+    for (i = 0; i < MAX_NICS; i++) {
+        NICInfo *nd = &nd_table[i];
+        if (nd->used && !nd->instantiated) {
+            fprintf(stderr, "Warning: requested NIC (%s, model %s) "
+                    "was not created (not supported by this machine?)\n",
+                    nd->name ? nd->name : "anonymous",
+                    nd->model ? nd->model : "unspecified");
+        }
+    }
 }
 
 static int net_init_client(QemuOpts *opts, void *dummy)
diff --git a/net.h b/net.h
index 6ceca50..5b883a9 100644
--- a/net.h
+++ b/net.h
@@ -133,7 +133,8 @@ struct NICInfo {
     char *devaddr;
     VLANState *vlan;
     VLANClientState *netdev;
-    int used;
+    int used;         /* is this slot in nd_table[] being used? */
+    int instantiated; /* does this NICInfo correspond to an instantiated NIC? */
     int nvectors;
 };
 
commit 641f6eae757e5b2cf854fec14038ffd229e9adea
Author: Peter Maydell <peter.maydell at linaro.org>
Date:   Fri May 20 16:50:00 2011 +0100

    net: Don't warn about the default network setup
    
    Don't warn about the default network setup that you get if no command line
    -net options are specified.  There are two cases that we would otherwise
    complain about:
    
    (1) board doesn't support a NIC but the implicit "-net nic" requested one
    (2) CONFIG_SLIRP not set, so the implicit "-net nic" sets up a nic that
    isn't connected to anything
    
    Signed-off-by: Peter Maydell <peter.maydell at linaro.org>
    Signed-off-by: Anthony Liguori <aliguori at us.ibm.com>

diff --git a/net.c b/net.c
index 1b521a9..68c2840 100644
--- a/net.c
+++ b/net.c
@@ -1305,6 +1305,18 @@ void net_check_clients(void)
     VLANState *vlan;
     VLANClientState *vc;
 
+    /* Don't warn about the default network setup that you get if
+     * no command line -net or -netdev options are specified. There
+     * are two cases that we would otherwise complain about:
+     * (1) board doesn't support a NIC but the implicit "-net nic"
+     * requested one
+     * (2) CONFIG_SLIRP not set, in which case the implicit "-net nic"
+     * sets up a nic that isn't connected to anything.
+     */
+    if (default_net) {
+        return;
+    }
+
     QTAILQ_FOREACH(vlan, &vlans, next) {
         int has_nic = 0, has_host_dev = 0;
 
commit 1d66f1709435c2c72e2773549729b541e6d3d626
Author: Peter Maydell <peter.maydell at linaro.org>
Date:   Fri May 20 16:49:59 2011 +0100

    Revert "net: Improve the warnings for dubious command line option combinations"
    
    This reverts commit f68b9d672b90dedc79aeb9b44607f484dbe46a6b.
    That attempt at diagnosing unused -net nic options failed to account
    for NICs created via -device; back it out cleanly in preparation
    for implementing in a different manner.
    
    Signed-off-by: Peter Maydell <peter.maydell at linaro.org>
    Signed-off-by: Anthony Liguori <aliguori at us.ibm.com>

diff --git a/net.c b/net.c
index 4f777c3..1b521a9 100644
--- a/net.c
+++ b/net.c
@@ -1304,22 +1304,6 @@ void net_check_clients(void)
 {
     VLANState *vlan;
     VLANClientState *vc;
-    int seen_nics = 0;
-
-    /* Don't warn about the default network setup that you get if
-     * no command line -net options are specified. There are two
-     * cases that we would otherwise complain about:
-     * (1) board doesn't support a NIC but the implicit "-net nic"
-     * requested one; we'd otherwise complain about more NICs being
-     * specified than we support, and also that the vlan set up by
-     * the implicit "-net user" didn't have any NICs connected to it
-     * (2) CONFIG_SLIRP not set: we'd otherwise complain about the
-     * implicit "-net nic" setting up a nic that wasn't connected to
-     * anything.
-     */
-    if (default_net) {
-        return;
-    }
 
     QTAILQ_FOREACH(vlan, &vlans, next) {
         int has_nic = 0, has_host_dev = 0;
@@ -1327,7 +1311,6 @@ void net_check_clients(void)
         QTAILQ_FOREACH(vc, &vlan->clients, next) {
             switch (vc->info->type) {
             case NET_CLIENT_TYPE_NIC:
-                seen_nics++;
                 has_nic = 1;
                 break;
             case NET_CLIENT_TYPE_SLIRP:
@@ -1347,26 +1330,12 @@ void net_check_clients(void)
                     vlan->id);
     }
     QTAILQ_FOREACH(vc, &non_vlan_clients, next) {
-        if (vc->info->type == NET_CLIENT_TYPE_NIC) {
-            seen_nics++;
-        }
         if (!vc->peer) {
             fprintf(stderr, "Warning: %s %s has no peer\n",
                     vc->info->type == NET_CLIENT_TYPE_NIC ? "nic" : "netdev",
                     vc->name);
         }
     }
-    if (seen_nics != nb_nics) {
-        /* Number of NICs requested by user on command line doesn't match
-         * the number the model actually registered with us.
-         * This will generally only happen for models of embedded boards
-         * with no PCI bus or similar. PCI based machines can instantiate
-         * all requested NICs as PCI devices but usually embedded boards
-         * only have a single NIC.
-         */
-        fprintf(stderr, "Warning: more nics requested than this machine "
-                "supports; some have been ignored\n");
-    }
 }
 
 static int net_init_client(QemuOpts *opts, void *dummy)
commit f8e378f27f2a8b99bf9be0a9168ba0ea19eeb740
Author: Avi Kivity <avi at redhat.com>
Date:   Mon Jun 20 11:12:47 2011 +0300

    Optimize screendump
    
    When running kvm-autotest, fputc() is often the second highest (sometimes #1)
    function showing up in a profile.  This is due to fputc() locking the file
    for every byte written.
    
    Optimize by buffering a line's worth of pixels and writing that out in a
    single call.
    
    Reviewed-by: Stefan Hajnoczi <stefanha at linux.vnet.ibm.com>
    Signed-off-by: Avi Kivity <avi at redhat.com>
    Signed-off-by: Anthony Liguori <aliguori at us.ibm.com>

diff --git a/hw/vga.c b/hw/vga.c
index 124295a..0f54734 100644
--- a/hw/vga.c
+++ b/hw/vga.c
@@ -2346,15 +2346,19 @@ int ppm_save(const char *filename, struct DisplaySurface *ds)
     uint32_t v;
     int y, x;
     uint8_t r, g, b;
+    int ret;
+    char *linebuf, *pbuf;
 
     f = fopen(filename, "wb");
     if (!f)
         return -1;
     fprintf(f, "P6\n%d %d\n%d\n",
             ds->width, ds->height, 255);
+    linebuf = qemu_malloc(ds->width * 3);
     d1 = ds->data;
     for(y = 0; y < ds->height; y++) {
         d = d1;
+        pbuf = linebuf;
         for(x = 0; x < ds->width; x++) {
             if (ds->pf.bits_per_pixel == 32)
                 v = *(uint32_t *)d;
@@ -2366,13 +2370,16 @@ int ppm_save(const char *filename, struct DisplaySurface *ds)
                 (ds->pf.gmax + 1);
             b = ((v >> ds->pf.bshift) & ds->pf.bmax) * 256 /
                 (ds->pf.bmax + 1);
-            fputc(r, f);
-            fputc(g, f);
-            fputc(b, f);
+            *pbuf++ = r;
+            *pbuf++ = g;
+            *pbuf++ = b;
             d += ds->pf.bytes_per_pixel;
         }
         d1 += ds->linesize;
+        ret = fwrite(linebuf, 1, pbuf - linebuf, f);
+        (void)ret;
     }
+    qemu_free(linebuf);
     fclose(f);
     return 0;
 }
commit 9319a6d3a6af9ae85556261e4a759eaddb49d734
Merge: d6034a3... 5a8a49d...
Author: Anthony Liguori <aliguori at us.ibm.com>
Date:   Wed Jun 22 07:14:00 2011 -0500

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

commit d6034a3a61235042a0d79dcc1dfed0fbf461fb18
Merge: fdba959... ca98557...
Author: Anthony Liguori <aliguori at us.ibm.com>
Date:   Wed Jun 22 07:13:10 2011 -0500

    Merge remote-tracking branch 'qemu-kvm/uq/master' into staging

commit fdba9594df8eb2e2ac16bba95308e4159ffbb9e4
Merge: 7ee28fd... 0e6264d...
Author: Anthony Liguori <aliguori at us.ibm.com>
Date:   Wed Jun 22 07:11:09 2011 -0500

    Merge remote-tracking branch 'mst/for_anthony' into staging
    
    Conflicts:
    	hw/usb-uhci.c

diff --cc hw/piix_pci.c
index 3e2698d,e0da0bd..26ce904
--- a/hw/piix_pci.c
+++ b/hw/piix_pci.c
@@@ -465,7 -452,19 +453,11 @@@ static PCIDeviceInfo i440fx_info[] = 
          .no_hotplug   = 1,
          .init         = i440fx_initfn,
          .config_write = i440fx_write_config,
+         .vendor_id    = PCI_VENDOR_ID_INTEL,
+         .device_id    = PCI_DEVICE_ID_INTEL_82441,
+         .revision     = 0x02,
+         .class_id     = PCI_CLASS_BRIDGE_HOST,
      },{
 -        .qdev.name    = "i440FX-xen",
 -        .qdev.desc    = "Host bridge",
 -        .qdev.size    = sizeof(PCII440FXState),
 -        .qdev.vmsd    = &vmstate_i440fx,
 -        .qdev.no_user = 1,
 -        .init         = i440fx_initfn,
 -        .config_write = i440fx_write_config_xen,
 -    },{
          .qdev.name    = "PIIX3",
          .qdev.desc    = "ISA bridge",
          .qdev.size    = sizeof(PIIX3State),
@@@ -474,16 -473,10 +466,19 @@@
          .no_hotplug   = 1,
          .init         = piix3_initfn,
          .config_write = piix3_write_config,
+         .vendor_id    = PCI_VENDOR_ID_INTEL,
+         .device_id    = PCI_DEVICE_ID_INTEL_82371SB_0, // 82371SB PIIX3 PCI-to-ISA bridge (Step A1)
+         .class_id     = PCI_CLASS_BRIDGE_ISA,
      },{
 +        .qdev.name    = "PIIX3-xen",
 +        .qdev.desc    = "ISA bridge",
 +        .qdev.size    = sizeof(PIIX3State),
 +        .qdev.vmsd    = &vmstate_piix3,
 +        .qdev.no_user = 1,
 +        .no_hotplug   = 1,
 +        .init         = piix3_initfn,
 +        .config_write = piix3_write_config_xen,
 +    },{
          /* end of list */
      }
  };
diff --cc hw/usb-uhci.c
index 75cd231,872a995..405fa7b
--- a/hw/usb-uhci.c
+++ b/hw/usb-uhci.c
@@@ -1110,23 -1088,18 +1110,22 @@@ static USBPortOps uhci_port_ops = 
      .complete = uhci_async_complete,
  };
  
 +static USBBusOps uhci_bus_ops = {
 +    .device_destroy = uhci_device_destroy,
 +};
 +
- static int usb_uhci_common_initfn(UHCIState *s)
+ static int usb_uhci_common_initfn(PCIDevice *dev)
  {
+     UHCIState *s = DO_UPCAST(UHCIState, dev, dev);
      uint8_t *pci_conf = s->dev.config;
      int i;
  
-     pci_conf[PCI_REVISION_ID] = 0x01; // revision number
      pci_conf[PCI_CLASS_PROG] = 0x00;
-     pci_config_set_class(pci_conf, PCI_CLASS_SERIAL_USB);
      /* TODO: reset value should be 0. */
      pci_conf[PCI_INTERRUPT_PIN] = 4; // interrupt pin 3
 -    pci_conf[0x60] = 0x10; // release number
 +    pci_conf[USB_SBRN] = USB_RELEASE_1; // release number
  
 -    usb_bus_new(&s->bus, &s->dev.qdev);
 +    usb_bus_new(&s->bus, &uhci_bus_ops, &s->dev.qdev);
      for(i = 0; i < NB_PORTS; i++) {
          usb_register_port(&s->bus, &s->ports[i].port, s, i, &uhci_port_ops,
                            USB_SPEED_MASK_LOW | USB_SPEED_MASK_FULL);
commit 7ee28fd303003d70bb4c142e6ad4b92b7383b5b4
Merge: bcd2491... 01195b7...
Author: Anthony Liguori <aliguori at us.ibm.com>
Date:   Wed Jun 22 07:07:55 2011 -0500

    Merge remote-tracking branch 'agraf/xen-next' into staging

commit bfcedc572bb77f3d21cd3a297b4215389a2f7df4
Author: Riku Voipio <riku.voipio at iki.fi>
Date:   Mon Jun 20 16:24:39 2011 +0300

    linux-user: Fix sync_file_range on 32bit mips
    
    As noticed while looking at "Bump do_syscall() up to 8 syscall arguments"
    patch, sync_file_range uses a pad argument on 32bit mips. Deal with it
    by reading the correct arguments when on mips.
    
    Signed-off-by: Riku Voipio <riku.voipio at iki.fi>

diff --git a/linux-user/syscall.c b/linux-user/syscall.c
index 9e14937..fed7a8f 100644
--- a/linux-user/syscall.c
+++ b/linux-user/syscall.c
@@ -7862,8 +7862,13 @@ abi_long do_syscall(void *cpu_env, int num, abi_long arg1,
 #if defined(TARGET_NR_sync_file_range)
     case TARGET_NR_sync_file_range:
 #if TARGET_ABI_BITS == 32
+#if defined(TARGET_MIPS)
+        ret = get_errno(sync_file_range(arg1, target_offset64(arg3, arg4),
+                                        target_offset64(arg5, arg6), arg7));
+#else
         ret = get_errno(sync_file_range(arg1, target_offset64(arg2, arg3),
                                         target_offset64(arg4, arg5), arg6));
+#endif /* !TARGET_MIPS */
 #else
         ret = get_errno(sync_file_range(arg1, arg2, arg3, arg4));
 #endif
commit c7b016ba04aa0ba71e068deb24163fb8b4dcd421
Author: Peter Maydell <peter.maydell at linaro.org>
Date:   Thu Jun 16 17:37:15 2011 +0100

    linux-user/signal.c: Remove unused fenab
    
    Remove fenab as it is only written, never used. Add a FIXME
    comment about the discrepancy between our behaviour and that
    of the Linux kernel for this routine.
    
    Signed-off-by: Peter Maydell <peter.maydell at linaro.org>
    Signed-off-by: Riku Voipio <riku.voipio at iki.fi>

diff --git a/linux-user/signal.c b/linux-user/signal.c
index 4edd974..7d168e1 100644
--- a/linux-user/signal.c
+++ b/linux-user/signal.c
@@ -2228,7 +2228,6 @@ void sparc64_set_context(CPUSPARCState *env)
     target_mc_gregset_t *grp;
     abi_ulong pc, npc, tstate;
     abi_ulong fp, i7, w_addr;
-    unsigned char fenab;
     int err;
     unsigned int i;
 
@@ -2293,7 +2292,11 @@ void sparc64_set_context(CPUSPARCState *env)
     if (put_user(i7, w_addr + offsetof(struct target_reg_window, ins[7]), 
                  abi_ulong) != 0)
         goto do_sigsegv;
-    err |= __get_user(fenab, &(ucp->tuc_mcontext.mc_fpregs.mcfpu_enab));
+    /* FIXME this does not match how the kernel handles the FPU in
+     * its sparc64_set_context implementation. In particular the FPU
+     * is only restored if fenab is non-zero in:
+     *   __get_user(fenab, &(ucp->tuc_mcontext.mc_fpregs.mcfpu_enab));
+     */
     err |= __get_user(env->fprs, &(ucp->tuc_mcontext.mc_fpregs.mcfpu_fprs));
     {
         uint32_t *src, *dst;
commit 2aec3a27d78075c4b4c44a241f32f27e9a7b9a8a
Author: Peter Maydell <peter.maydell at linaro.org>
Date:   Thu Jun 16 17:37:14 2011 +0100

    linux-user/signal.c: Remove only-ever-set variable fpu_save_addr
    
    Move the access of fpu_save into the commented out skeleton code for
    restoring FPU registers on SPARC sigreturn, thus silencing a gcc
    4.6 "variable set but never used" warning.
    (This doesn't affect the calculation of 'err' because in fact
    __get_user() can never fail.)
    
    Signed-off-by: Peter Maydell <peter.maydell at linaro.org>
    Signed-off-by: Riku Voipio <riku.voipio at iki.fi>

diff --git a/linux-user/signal.c b/linux-user/signal.c
index cb7138f..4edd974 100644
--- a/linux-user/signal.c
+++ b/linux-user/signal.c
@@ -2080,7 +2080,6 @@ long do_sigreturn(CPUState *env)
         uint32_t up_psr, pc, npc;
         target_sigset_t set;
         sigset_t host_set;
-        abi_ulong fpu_save_addr;
         int err, i;
 
         sf_addr = env->regwptr[UREG_FP];
@@ -2120,10 +2119,11 @@ long do_sigreturn(CPUState *env)
 		err |= __get_user(env->regwptr[i + UREG_I0], &sf->info.si_regs.u_regs[i+8]);
 	}
 
-        err |= __get_user(fpu_save_addr, &sf->fpu_save);
-
-        //if (fpu_save)
-        //        err |= restore_fpu_state(env, fpu_save);
+        /* FIXME: implement FPU save/restore:
+         * __get_user(fpu_save, &sf->fpu_save);
+         * if (fpu_save)
+         *        err |= restore_fpu_state(env, fpu_save);
+         */
 
         /* This is pretty much atomic, no amount locking would prevent
          * the races which exist anyways.
commit 5945cfcb4b862a57fbbbf794f5e4b0fa4499624a
Author: Peter Maydell <peter.maydell at linaro.org>
Date:   Thu Jun 16 17:37:13 2011 +0100

    linux-user: Bump do_syscall() up to 8 syscall arguments
    
    On 32 bit MIPS a few syscalls have 7 arguments, and so to call
    them via NR_syscall the guest needs to be able to pass 8 arguments
    to do_syscall(). Raise the number of arguments do_syscall() takes
    accordingly.
    
    This fixes some gcc 4.6 compiler warnings about arg7 and arg8
    variables being set and never used.
    
    Signed-off-by: Peter Maydell <peter.maydell at linaro.org>
    Signed-off-by: Riku Voipio <riku.voipio at iki.fi>

diff --git a/linux-user/main.c b/linux-user/main.c
index 71dd253..1293450 100644
--- a/linux-user/main.c
+++ b/linux-user/main.c
@@ -319,7 +319,8 @@ void cpu_loop(CPUX86State *env)
                                           env->regs[R_EDX],
                                           env->regs[R_ESI],
                                           env->regs[R_EDI],
-                                          env->regs[R_EBP]);
+                                          env->regs[R_EBP],
+                                          0, 0);
             break;
 #ifndef TARGET_ABI32
         case EXCP_SYSCALL:
@@ -331,7 +332,8 @@ void cpu_loop(CPUX86State *env)
                                           env->regs[R_EDX],
                                           env->regs[10],
                                           env->regs[8],
-                                          env->regs[9]);
+                                          env->regs[9],
+                                          0, 0);
             env->eip = env->exception_next_eip;
             break;
 #endif
@@ -735,7 +737,8 @@ void cpu_loop(CPUARMState *env)
                                                   env->regs[2],
                                                   env->regs[3],
                                                   env->regs[4],
-                                                  env->regs[5]);
+                                                  env->regs[5],
+                                                  0, 0);
                     }
                 } else {
                     goto error;
@@ -831,7 +834,8 @@ void cpu_loop(CPUState *env)
                                                   env->regs[2],
                                                   env->regs[3],
                                                   env->regs[4],
-                                                  env->regs[5]);
+                                                  env->regs[5],
+                                                  0, 0);
                     }
                 } else {
                     goto error;
@@ -1018,7 +1022,8 @@ void cpu_loop (CPUSPARCState *env)
             ret = do_syscall (env, env->gregs[1],
                               env->regwptr[0], env->regwptr[1],
                               env->regwptr[2], env->regwptr[3],
-                              env->regwptr[4], env->regwptr[5]);
+                              env->regwptr[4], env->regwptr[5],
+                              0, 0);
             if ((abi_ulong)ret >= (abi_ulong)(-515)) {
 #if defined(TARGET_SPARC64) && !defined(TARGET_ABI32)
                 env->xcc |= PSR_CARRY;
@@ -1611,7 +1616,7 @@ void cpu_loop(CPUPPCState *env)
             env->crf[0] &= ~0x1;
             ret = do_syscall(env, env->gpr[0], env->gpr[3], env->gpr[4],
                              env->gpr[5], env->gpr[6], env->gpr[7],
-                             env->gpr[8]);
+                             env->gpr[8], 0, 0);
             if (ret == (uint32_t)(-TARGET_QEMU_ESIGRETURN)) {
                 /* Returning from a successful sigreturn syscall.
                    Avoid corrupting register state.  */
@@ -2072,7 +2077,7 @@ void cpu_loop(CPUMIPSState *env)
                                  env->active_tc.gpr[5],
                                  env->active_tc.gpr[6],
                                  env->active_tc.gpr[7],
-                                 arg5, arg6/*, arg7, arg8*/);
+                                 arg5, arg6, arg7, arg8);
             }
             if (ret == -TARGET_QEMU_ESIGRETURN) {
                 /* Returning from a successful sigreturn syscall.
@@ -2160,7 +2165,8 @@ void cpu_loop (CPUState *env)
                              env->gregs[6],
                              env->gregs[7],
                              env->gregs[0],
-                             env->gregs[1]);
+                             env->gregs[1],
+                             0, 0);
             env->gregs[0] = ret;
             break;
         case EXCP_INTERRUPT:
@@ -2229,7 +2235,8 @@ void cpu_loop (CPUState *env)
                              env->regs[12], 
                              env->regs[13], 
                              env->pregs[7], 
-                             env->pregs[11]);
+                             env->pregs[11],
+                             0, 0);
             env->regs[10] = ret;
             break;
         case EXCP_DEBUG:
@@ -2288,7 +2295,8 @@ void cpu_loop (CPUState *env)
                              env->regs[7], 
                              env->regs[8], 
                              env->regs[9], 
-                             env->regs[10]);
+                             env->regs[10],
+                             0, 0);
             env->regs[3] = ret;
             env->sregs[SR_PC] = env->regs[14];
             break;
@@ -2398,7 +2406,8 @@ void cpu_loop(CPUM68KState *env)
                                           env->dregs[3],
                                           env->dregs[4],
                                           env->dregs[5],
-                                          env->aregs[0]);
+                                          env->aregs[0],
+                                          0, 0);
             }
             break;
         case EXCP_INTERRUPT:
@@ -2576,7 +2585,8 @@ void cpu_loop (CPUState *env)
                 sysret = do_syscall(env, trapnr,
                                     env->ir[IR_A0], env->ir[IR_A1],
                                     env->ir[IR_A2], env->ir[IR_A3],
-                                    env->ir[IR_A4], env->ir[IR_A5]);
+                                    env->ir[IR_A4], env->ir[IR_A5],
+                                    0, 0);
                 if (trapnr == TARGET_NR_sigreturn
                     || trapnr == TARGET_NR_rt_sigreturn) {
                     break;
@@ -2707,7 +2717,8 @@ void cpu_loop(CPUS390XState *env)
                            env->regs[4],
                            env->regs[5],
                            env->regs[6],
-                           env->regs[7]);
+                           env->regs[7],
+                           0, 0);
             }
             break;
         case EXCP_ADDR:
diff --git a/linux-user/qemu.h b/linux-user/qemu.h
index 237386c..627c8b3 100644
--- a/linux-user/qemu.h
+++ b/linux-user/qemu.h
@@ -192,7 +192,8 @@ abi_long do_brk(abi_ulong new_brk);
 void syscall_init(void);
 abi_long do_syscall(void *cpu_env, int num, abi_long arg1,
                     abi_long arg2, abi_long arg3, abi_long arg4,
-                    abi_long arg5, abi_long arg6);
+                    abi_long arg5, abi_long arg6, abi_long arg7,
+                    abi_long arg8);
 void gemu_log(const char *fmt, ...) GCC_FMT_ATTR(1, 2);
 extern THREAD CPUState *thread_env;
 void cpu_loop(CPUState *env);
diff --git a/linux-user/syscall.c b/linux-user/syscall.c
index 5a919f6..9e14937 100644
--- a/linux-user/syscall.c
+++ b/linux-user/syscall.c
@@ -4532,7 +4532,8 @@ int get_osversion(void)
    All errnos that do_syscall() returns must be -TARGET_<errcode>. */
 abi_long do_syscall(void *cpu_env, int num, abi_long arg1,
                     abi_long arg2, abi_long arg3, abi_long arg4,
-                    abi_long arg5, abi_long arg6)
+                    abi_long arg5, abi_long arg6, abi_long arg7,
+                    abi_long arg8)
 {
     abi_long ret;
     struct stat st;
@@ -6172,8 +6173,9 @@ abi_long do_syscall(void *cpu_env, int num, abi_long arg1,
 #endif
 #ifdef TARGET_NR_syscall
     case TARGET_NR_syscall:
-    	ret = do_syscall(cpu_env,arg1 & 0xffff,arg2,arg3,arg4,arg5,arg6,0);
-    	break;
+        ret = do_syscall(cpu_env, arg1 & 0xffff, arg2, arg3, arg4, arg5,
+                         arg6, arg7, arg8, 0);
+        break;
 #endif
     case TARGET_NR_wait4:
         {
commit 3002fa8472b1b9293cac785ca032df727540f85d
Author: Juan Quintela <quintela at redhat.com>
Date:   Thu Jun 16 17:37:12 2011 +0100

    flatload: memp was a write-only variable
    
    Signed-off-by: Juan Quintela <quintela at redhat.com>
    Signed-off-by: Peter Maydell <peter.maydell at linaro.org>
    Signed-off-by: Riku Voipio <riku.voipio at iki.fi>

diff --git a/linux-user/flatload.c b/linux-user/flatload.c
index 6fb78f5..1062da3 100644
--- a/linux-user/flatload.c
+++ b/linux-user/flatload.c
@@ -379,7 +379,6 @@ static int load_flat_file(struct linux_binprm * bprm,
     abi_long result;
     abi_ulong realdatastart = 0;
     abi_ulong text_len, data_len, bss_len, stack_len, flags;
-    abi_ulong memp = 0; /* for finding the brk area */
     abi_ulong extra;
     abi_ulong reloc = 0, rp;
     int i, rev, relocs = 0;
@@ -491,7 +490,6 @@ static int load_flat_file(struct linux_binprm * bprm,
         }
 
         reloc = datapos + (ntohl(hdr->reloc_start) - text_len);
-        memp = realdatastart;
 
     } else {
 
@@ -506,7 +504,6 @@ static int load_flat_file(struct linux_binprm * bprm,
         realdatastart = textpos + ntohl(hdr->data_start);
         datapos = realdatastart + indx_len;
         reloc = (textpos + ntohl(hdr->reloc_start) + indx_len);
-        memp = textpos;
 
 #ifdef CONFIG_BINFMT_ZFLAT
 #error code needs checking
commit e7730352fb63879da816893d868e6d77be9594a3
Author: Juan Quintela <quintela at redhat.com>
Date:   Thu Jun 16 17:37:11 2011 +0100

    flatload: end_code was only used in a debug message
    
    Just unfold its definition in only use.
    
    Signed-off-by: Juan Quintela <quintela at redhat.com>
    [peter.maydell at linaro.org: fixed typo in the debug code,
    added parentheses to fix precedence issue]
    Signed-off-by: Peter Maydell <peter.maydell at linaro.org>
    Signed-off-by: Riku Voipio <riku.voipio at iki.fi>

diff --git a/linux-user/flatload.c b/linux-user/flatload.c
index cd7af7c..6fb78f5 100644
--- a/linux-user/flatload.c
+++ b/linux-user/flatload.c
@@ -384,7 +384,7 @@ static int load_flat_file(struct linux_binprm * bprm,
     abi_ulong reloc = 0, rp;
     int i, rev, relocs = 0;
     abi_ulong fpos;
-    abi_ulong start_code, end_code;
+    abi_ulong start_code;
     abi_ulong indx_len;
 
     hdr = ((struct flat_hdr *) bprm->buf);		/* exec-header */
@@ -552,11 +552,10 @@ static int load_flat_file(struct linux_binprm * bprm,
 
     /* The main program needs a little extra setup in the task structure */
     start_code = textpos + sizeof (struct flat_hdr);
-    end_code = textpos + text_len;
 
     DBG_FLT("%s %s: TEXT=%x-%x DATA=%x-%x BSS=%x-%x\n",
             id ? "Lib" : "Load", bprm->filename,
-            (int) start_code, (int) end_code,
+            (int) start_code, (int) (textpos + text_len),
             (int) datapos,
             (int) (datapos + data_len),
             (int) (datapos + data_len),
commit bc088ba1db4ec9e5c3bc3e6b2bac816673d9cbdd
Author: Juan Quintela <quintela at redhat.com>
Date:   Thu Jun 16 17:37:10 2011 +0100

    linux-user: syscall should use sanitized arg1
    
    Looking at the other architectures, we should be using "how" not "arg1".
    
    Signed-off-by: Juan Quintela <quintela at redhat.com>
    [peter.maydell at linaro.org: remove unnecessary initialisation of how]
    Signed-off-by: Peter Maydell <peter.maydell at linaro.org>
    Signed-off-by: Riku Voipio <riku.voipio at iki.fi>

diff --git a/linux-user/syscall.c b/linux-user/syscall.c
index 00484f1..5a919f6 100644
--- a/linux-user/syscall.c
+++ b/linux-user/syscall.c
@@ -7201,7 +7201,7 @@ abi_long do_syscall(void *cpu_env, int num, abi_long arg1,
     case TARGET_NR_osf_sigprocmask:
         {
             abi_ulong mask;
-            int how = arg1;
+            int how;
             sigset_t set, oldset;
 
             switch(arg1) {
@@ -7220,7 +7220,7 @@ abi_long do_syscall(void *cpu_env, int num, abi_long arg1,
             }
             mask = arg2;
             target_to_host_old_sigset(&set, &mask);
-            sigprocmask(arg1, &set, &oldset);
+            sigprocmask(how, &set, &oldset);
             host_to_target_old_sigset(&mask, &oldset);
             ret = mask;
         }
commit 1add86983cbc972a3431368203f630e290c3f2bb
Author: Juan Quintela <quintela at redhat.com>
Date:   Thu Jun 16 17:37:09 2011 +0100

    syscall: really return ret code
    
    We assign ret with the error code, but then return 0 unconditionally.
    
    Signed-off-by: Juan Quintela <quintela at redhat.com>
    Signed-off-by: Peter Maydell <peter.maydell at linaro.org>
    Signed-off-by: Riku Voipio <riku.voipio at iki.fi>

diff --git a/linux-user/syscall.c b/linux-user/syscall.c
index 9f9693e..00484f1 100644
--- a/linux-user/syscall.c
+++ b/linux-user/syscall.c
@@ -3799,10 +3799,10 @@ static abi_long do_get_thread_area(CPUX86State *env, abi_ulong ptr)
 #ifndef TARGET_ABI32
 static abi_long do_arch_prctl(CPUX86State *env, int code, abi_ulong addr)
 {
-    abi_long ret;
+    abi_long ret = 0;
     abi_ulong val;
     int idx;
-    
+
     switch(code) {
     case TARGET_ARCH_SET_GS:
     case TARGET_ARCH_SET_FS:
@@ -3821,13 +3821,13 @@ static abi_long do_arch_prctl(CPUX86State *env, int code, abi_ulong addr)
             idx = R_FS;
         val = env->segs[idx].base;
         if (put_user(val, addr, abi_ulong))
-            return -TARGET_EFAULT;
+            ret = -TARGET_EFAULT;
         break;
     default:
         ret = -TARGET_EINVAL;
         break;
     }
-    return 0;
+    return ret;
 }
 #endif
 
commit 331c23b5ca44293d13299d12f1a36826395d7254
Author: Juan Quintela <quintela at redhat.com>
Date:   Thu Jun 16 17:37:08 2011 +0100

    linuxload: id_change was a write only variable
    
    Signed-off-by: Juan Quintela <quintela at redhat.com>
    Signed-off-by: Peter Maydell <peter.maydell at linaro.org>
    Signed-off-by: Riku Voipio <riku.voipio at iki.fi>

diff --git a/linux-user/linuxload.c b/linux-user/linuxload.c
index ac8c486..62ebc7e 100644
--- a/linux-user/linuxload.c
+++ b/linux-user/linuxload.c
@@ -26,22 +26,6 @@ abi_long memcpy_to_target(abi_ulong dest, const void *src,
     return 0;
 }
 
-static int in_group_p(gid_t g)
-{
-    /* return TRUE if we're in the specified group, FALSE otherwise */
-    int		ngroup;
-    int		i;
-    gid_t	grouplist[NGROUPS];
-
-    ngroup = getgroups(NGROUPS, grouplist);
-    for(i = 0; i < ngroup; i++) {
-	if(grouplist[i] == g) {
-	    return 1;
-	}
-    }
-    return 0;
-}
-
 static int count(char ** vec)
 {
     int		i;
@@ -57,7 +41,7 @@ static int prepare_binprm(struct linux_binprm *bprm)
 {
     struct stat		st;
     int mode;
-    int retval, id_change;
+    int retval;
 
     if(fstat(bprm->fd, &st) < 0) {
 	return(-errno);
@@ -73,14 +57,10 @@ static int prepare_binprm(struct linux_binprm *bprm)
 
     bprm->e_uid = geteuid();
     bprm->e_gid = getegid();
-    id_change = 0;
 
     /* Set-uid? */
     if(mode & S_ISUID) {
     	bprm->e_uid = st.st_uid;
-	if(bprm->e_uid != geteuid()) {
-	    id_change = 1;
-	}
     }
 
     /* Set-gid? */
@@ -91,9 +71,6 @@ static int prepare_binprm(struct linux_binprm *bprm)
      */
     if ((mode & (S_ISGID | S_IXGRP)) == (S_ISGID | S_IXGRP)) {
 	bprm->e_gid = st.st_gid;
-	if (!in_group_p(bprm->e_gid)) {
-		id_change = 1;
-	}
     }
 
     retval = read(bprm->fd, bprm->buf, BPRM_BUF_SIZE);
commit 14322bad88c46e41b962ff8f4a6f524dd883670c
Author: Laurent ALFONSI <laurent.alfonsi at st.com>
Date:   Mon Jun 20 08:43:13 2011 +0200

    linux-user: Define AT_RANDOM to support target stack protection mechanism.
    
    The dynamic linker from the GNU C library v2.10+ uses the ELF
    auxiliary vector AT_RANDOM [1] as a pointer to 16 bytes with random
    values to initialize the stack protection mechanism.  Technically the
    emulated GNU dynamic linker crashes due to a NULL pointer
    derefencement if it is built with stack protection enabled and if
    AT_RANDOM is not defined by the QEMU ELF loader.
    
    [1] This ELF auxiliary vector was introduced in Linux v2.6.29.
    
    This patch can be tested with the code above:
    
        #include <elf.h>       /* Elf*_auxv_t, AT_RANDOM, */
        #include <stdio.h>     /* printf(3), */
        #include <stdlib.h>    /* exit(3), EXIT_*, */
        #include <stdint.h>    /* uint8_t, */
        #include <string.h>    /* memcpy(3), */
    
        #if defined(__LP64__) || defined(__ILP64__) || defined(__LLP64__)
        #    define Elf_auxv_t Elf64_auxv_t
        #else
        #    define Elf_auxv_t Elf32_auxv_t
        #endif
    
        main(int argc, char* argv[], char* envp[])
        {
            Elf_auxv_t *auxv;
    
            /* *envp = NULL marks end of envp. */
            while (*envp++ != NULL);
    
            /* auxv->a_type = AT_NULL marks the end of auxv. */
            for (auxv = (Elf_auxv_t *)envp; auxv->a_type != AT_NULL; auxv++) {
                if (auxv->a_type == AT_RANDOM) {
                    int i;
                    uint8_t rand_bytes[16];
    
                    printf("AT_RANDOM is: 0x%x\n", auxv->a_un.a_val);
                    memcpy(rand_bytes, (const uint8_t *)auxv->a_un.a_val, sizeof(rand_bytes));
                    printf("it points to: ");
                    for (i = 0; i < 16; i++) {
                        printf("0x%02x ", rand_bytes[i]);
                    }
                    printf("\n");
                    exit(EXIT_SUCCESS);
                }
            }
            exit(EXIT_FAILURE);
        }
    
    Changes introduced in v2 and v3:
    
        * Fix typos + thinko (AT_RANDOM is used for stack canary, not for
          ASLR)
    
        * AT_RANDOM points to 16 random bytes stored inside the user
          stack.
    
        * Add a small test program.
    
    Signed-off-by: Cédric VINCENT <cedric.vincent at st.com>
    Signed-off-by: Laurent ALFONSI <laurent.alfonsi at st.com>
    Signed-off-by: Riku Voipio <riku.voipio at iki.fi>

diff --git a/linux-user/elfload.c b/linux-user/elfload.c
index a13eb7b..b2746f2 100644
--- a/linux-user/elfload.c
+++ b/linux-user/elfload.c
@@ -927,7 +927,7 @@ struct exec
 #define TARGET_ELF_PAGESTART(_v) ((_v) & ~(unsigned long)(TARGET_ELF_EXEC_PAGESIZE-1))
 #define TARGET_ELF_PAGEOFFSET(_v) ((_v) & (TARGET_ELF_EXEC_PAGESIZE-1))
 
-#define DLINFO_ITEMS 12
+#define DLINFO_ITEMS 13
 
 static inline void memcpy_fromfs(void * to, const void * from, unsigned long n)
 {
@@ -1202,6 +1202,9 @@ static abi_ulong create_elf_tables(abi_ulong p, int argc, int envc,
 {
     abi_ulong sp;
     int size;
+    int i;
+    abi_ulong u_rand_bytes;
+    uint8_t k_rand_bytes[16];
     abi_ulong u_platform;
     const char *k_platform;
     const int n = sizeof(elf_addr_t);
@@ -1231,6 +1234,20 @@ static abi_ulong create_elf_tables(abi_ulong p, int argc, int envc,
         /* FIXME - check return value of memcpy_to_target() for failure */
         memcpy_to_target(sp, k_platform, len);
     }
+
+    /*
+     * Generate 16 random bytes for userspace PRNG seeding (not
+     * cryptically secure but it's not the aim of QEMU).
+     */
+    srand((unsigned int) time(NULL));
+    for (i = 0; i < 16; i++) {
+        k_rand_bytes[i] = rand();
+    }
+    sp -= 16;
+    u_rand_bytes = sp;
+    /* FIXME - check return value of memcpy_to_target() for failure */
+    memcpy_to_target(sp, k_rand_bytes, 16);
+
     /*
      * Force 16 byte _final_ alignment here for generality.
      */
@@ -1271,6 +1288,8 @@ static abi_ulong create_elf_tables(abi_ulong p, int argc, int envc,
     NEW_AUX_ENT(AT_EGID, (abi_ulong) getegid());
     NEW_AUX_ENT(AT_HWCAP, (abi_ulong) ELF_HWCAP);
     NEW_AUX_ENT(AT_CLKTCK, (abi_ulong) sysconf(_SC_CLK_TCK));
+    NEW_AUX_ENT(AT_RANDOM, (abi_ulong) u_rand_bytes);
+
     if (k_platform)
         NEW_AUX_ENT(AT_PLATFORM, u_platform);
 #ifdef ARCH_DLINFO
commit 055e090687d31429b4cd080626d2bf9ce8bbfe59
Author: Mike Frysinger <vapier at gentoo.org>
Date:   Fri Jun 3 17:01:49 2011 -0400

    linux-user: add pselect6 syscall support
    
    Some architectures (like Blackfin) only implement pselect6 (and skip
    select/newselect).  So add support for it.
    
    Signed-off-by: Mike Frysinger <vapier at gentoo.org>
    Signed-off-by: Riku Voipio <riku.voipio at iki.fi>

diff --git a/linux-user/syscall.c b/linux-user/syscall.c
index 608924a..9f9693e 100644
--- a/linux-user/syscall.c
+++ b/linux-user/syscall.c
@@ -550,6 +550,15 @@ _syscall5(int, sys_ppoll, struct pollfd *, fds, nfds_t, nfds,
           size_t, sigsetsize)
 #endif
 
+#if defined(TARGET_NR_pselect6)
+#ifndef __NR_pselect6
+# define __NR_pselect6 -1
+#endif
+#define __NR_sys_pselect6 __NR_pselect6
+_syscall6(int, sys_pselect6, int, nfds, fd_set *, readfds, fd_set *, writefds,
+          fd_set *, exceptfds, struct timespec *, timeout, void *, sig);
+#endif
+
 extern int personality(int);
 extern int flock(int, int);
 extern int setfsuid(int);
@@ -819,6 +828,20 @@ static inline abi_long copy_from_user_fdset(fd_set *fds,
     return 0;
 }
 
+static inline abi_ulong copy_from_user_fdset_ptr(fd_set *fds, fd_set **fds_ptr,
+                                                 abi_ulong target_fds_addr,
+                                                 int n)
+{
+    if (target_fds_addr) {
+        if (copy_from_user_fdset(fds, target_fds_addr, n))
+            return -TARGET_EFAULT;
+        *fds_ptr = fds;
+    } else {
+        *fds_ptr = NULL;
+    }
+    return 0;
+}
+
 static inline abi_long copy_to_user_fdset(abi_ulong target_fds_addr,
                                           const fd_set *fds,
                                           int n)
@@ -984,6 +1007,7 @@ static inline abi_long copy_to_user_mq_attr(abi_ulong target_mq_attr_addr,
 }
 #endif
 
+#if defined(TARGET_NR_select) || defined(TARGET_NR__newselect)
 /* do_select() must return target values and target errnos. */
 static abi_long do_select(int n,
                           abi_ulong rfd_addr, abi_ulong wfd_addr,
@@ -994,26 +1018,17 @@ static abi_long do_select(int n,
     struct timeval tv, *tv_ptr;
     abi_long ret;
 
-    if (rfd_addr) {
-        if (copy_from_user_fdset(&rfds, rfd_addr, n))
-            return -TARGET_EFAULT;
-        rfds_ptr = &rfds;
-    } else {
-        rfds_ptr = NULL;
+    ret = copy_from_user_fdset_ptr(&rfds, &rfds_ptr, rfd_addr, n);
+    if (ret) {
+        return ret;
     }
-    if (wfd_addr) {
-        if (copy_from_user_fdset(&wfds, wfd_addr, n))
-            return -TARGET_EFAULT;
-        wfds_ptr = &wfds;
-    } else {
-        wfds_ptr = NULL;
+    ret = copy_from_user_fdset_ptr(&wfds, &wfds_ptr, wfd_addr, n);
+    if (ret) {
+        return ret;
     }
-    if (efd_addr) {
-        if (copy_from_user_fdset(&efds, efd_addr, n))
-            return -TARGET_EFAULT;
-        efds_ptr = &efds;
-    } else {
-        efds_ptr = NULL;
+    ret = copy_from_user_fdset_ptr(&efds, &efds_ptr, efd_addr, n);
+    if (ret) {
+        return ret;
     }
 
     if (target_tv_addr) {
@@ -1040,6 +1055,7 @@ static abi_long do_select(int n,
 
     return ret;
 }
+#endif
 
 static abi_long do_pipe2(int host_pipe[], int flags)
 {
@@ -5601,7 +5617,102 @@ abi_long do_syscall(void *cpu_env, int num, abi_long arg1,
 #endif
 #ifdef TARGET_NR_pselect6
     case TARGET_NR_pselect6:
-	    goto unimplemented_nowarn;
+        {
+            abi_long rfd_addr, wfd_addr, efd_addr, n, ts_addr;
+            fd_set rfds, wfds, efds;
+            fd_set *rfds_ptr, *wfds_ptr, *efds_ptr;
+            struct timespec ts, *ts_ptr;
+
+            /*
+             * The 6th arg is actually two args smashed together,
+             * so we cannot use the C library.
+             */
+            sigset_t set;
+            struct {
+                sigset_t *set;
+                size_t size;
+            } sig, *sig_ptr;
+
+            abi_ulong arg_sigset, arg_sigsize, *arg7;
+            target_sigset_t *target_sigset;
+
+            n = arg1;
+            rfd_addr = arg2;
+            wfd_addr = arg3;
+            efd_addr = arg4;
+            ts_addr = arg5;
+
+            ret = copy_from_user_fdset_ptr(&rfds, &rfds_ptr, rfd_addr, n);
+            if (ret) {
+                goto fail;
+            }
+            ret = copy_from_user_fdset_ptr(&wfds, &wfds_ptr, wfd_addr, n);
+            if (ret) {
+                goto fail;
+            }
+            ret = copy_from_user_fdset_ptr(&efds, &efds_ptr, efd_addr, n);
+            if (ret) {
+                goto fail;
+            }
+
+            /*
+             * This takes a timespec, and not a timeval, so we cannot
+             * use the do_select() helper ...
+             */
+            if (ts_addr) {
+                if (target_to_host_timespec(&ts, ts_addr)) {
+                    goto efault;
+                }
+                ts_ptr = &ts;
+            } else {
+                ts_ptr = NULL;
+            }
+
+            /* Extract the two packed args for the sigset */
+            if (arg6) {
+                sig_ptr = &sig;
+                sig.size = _NSIG / 8;
+
+                arg7 = lock_user(VERIFY_READ, arg6, sizeof(*arg7) * 2, 1);
+                if (!arg7) {
+                    goto efault;
+                }
+                arg_sigset = tswapl(arg7[0]);
+                arg_sigsize = tswapl(arg7[1]);
+                unlock_user(arg7, arg6, 0);
+
+                if (arg_sigset) {
+                    sig.set = &set;
+                    target_sigset = lock_user(VERIFY_READ, arg_sigset,
+                                              sizeof(*target_sigset), 1);
+                    if (!target_sigset) {
+                        goto efault;
+                    }
+                    target_to_host_sigset(&set, target_sigset);
+                    unlock_user(target_sigset, arg_sigset, 0);
+                } else {
+                    sig.set = NULL;
+                }
+            } else {
+                sig_ptr = NULL;
+            }
+
+            ret = get_errno(sys_pselect6(n, rfds_ptr, wfds_ptr, efds_ptr,
+                                         ts_ptr, sig_ptr));
+
+            if (!is_error(ret)) {
+                if (rfd_addr && copy_to_user_fdset(rfd_addr, &rfds, n))
+                    goto efault;
+                if (wfd_addr && copy_to_user_fdset(wfd_addr, &wfds, n))
+                    goto efault;
+                if (efd_addr && copy_to_user_fdset(efd_addr, &efds, n))
+                    goto efault;
+
+                if (ts_addr && host_to_target_timespec(ts_addr, &ts))
+                    goto efault;
+            }
+        }
+        break;
 #endif
     case TARGET_NR_symlink:
         {
commit 4d1de87c75007ee7e29dd271ebb4afdcf01ad7aa
Author: vincent <cedric.vincent at st.com>
Date:   Tue Jun 14 21:56:33 2011 +0000

    linux-user: Fix the computation of the requested heap size
    
    There were several remaining bugs in the previous implementation of
    do_brk():
    
        1. the value of "new_alloc_size" was one page too large when the
           requested brk was aligned on a host page boundary.
    
        2. no new pages should be (re-)allocated when the requested brk is
           in the range of the pages that were already allocated
           previsouly (for the same purpose).  Technically these pages are
           never unmapped in the current implementation.
    
    The problem/fix can be reproduced/validated with the test-suite above:
    
        #include <unistd.h>       /* syscall(2),      */
        #include <sys/syscall.h>  /* SYS_brk,         */
        #include <stdio.h>        /* puts(3),         */
        #include <stdlib.h>       /* exit(3), EXIT_*, */
        #include <stdint.h>       /* uint*_t,         */
        #include <sys/mman.h>     /* mmap(2), MAP_*,  */
        #include <string.h>       /* memset(3), */
    
        int main()
        {
            int exit_status = EXIT_SUCCESS;
            uint8_t *current_brk = 0;
            uint8_t *initial_brk;
            uint8_t *new_brk;
            uint8_t *old_brk;
            int failure = 0;
            int i;
    
            void test_brk(int increment, int expected_result) {
                new_brk = (uint8_t *)syscall(SYS_brk, current_brk + increment);
                if ((new_brk == current_brk) == expected_result)
                    failure = 1;
                current_brk = (uint8_t *)syscall(SYS_brk, 0);
            }
    
            void test_result() {
                if (!failure)
                    puts("OK");
                else {
                    puts("failure");
                    exit_status = EXIT_FAILURE;
                }
            }
    
            void test_title(const char *title) {
                failure = 0;
                printf("%-45s : ", title);
                fflush(stdout);
            }
    
            test_title("Initialization");
            test_brk(0, 1);
            initial_brk = current_brk;
            test_result();
    
            test_title("Don't overlap \"brk\" pages");
            test_brk(HOST_PAGE_SIZE, 1);
            test_brk(HOST_PAGE_SIZE, 1);
            test_result();
    
            /* Preparation for the test "Re-allocated heap is initialized".  */
            old_brk = current_brk - HOST_PAGE_SIZE;
            memset(old_brk, 0xFF, HOST_PAGE_SIZE);
    
            test_title("Don't allocate the same \"brk\" page twice");
            test_brk(-HOST_PAGE_SIZE, 1);
            test_brk(HOST_PAGE_SIZE, 1);
            test_result();
    
            test_title("Re-allocated \"brk\" pages are initialized");
            for (i = 0; i < HOST_PAGE_SIZE; i++) {
                if (old_brk[i] != 0) {
                    printf("(index = %d, value = 0x%x) ", i, old_brk[i]);
                    failure = 1;
                    break;
                }
            }
            test_result();
    
            test_title("Don't allocate \"brk\" pages over \"mmap\" pages");
            new_brk = mmap(current_brk, HOST_PAGE_SIZE / 2, PROT_READ, MAP_PRIVATE | MAP_ANONYMOUS | MAP_FIXED, -1, 0);
            if (new_brk == (void *) -1)
                puts("unknown");
            else {
                test_brk(HOST_PAGE_SIZE, 0);
                test_result();
            }
    
            test_title("All \"brk\" pages are writable (please wait)");
            if (munmap(current_brk, HOST_PAGE_SIZE / 2) != 0)
                puts("unknown");
            else {
                while (current_brk - initial_brk < 2*1024*1024*1024UL) {
                    old_brk = current_brk;
    
                    test_brk(HOST_PAGE_SIZE, -1);
                    if (old_brk == current_brk)
                        break;
    
                    for (i = 0; i < HOST_PAGE_SIZE; i++)
                        old_brk[i] = 0xAA;
                }
                puts("OK");
            }
    
            test_title("Maximum size of the heap > 16MB");
            failure = (current_brk - initial_brk) < 16*1024*1024;
            test_result();
    
            exit(exit_status);
        }
    
    Changes introduced in patch v2:
    
        * extend the "brk" test-suite embedded within the commit message;
    
        * heap contents have to be initialized to zero, this bug was
          exposed by "tst-calloc.c" from the GNU C library;
    
        * don't [try to] allocate a new host page if the new "brk" is
          equal to the latest allocated host page ("brk_page"); and
    
        * print some debug information when DEBUGF_BRK is defined.
    
    Signed-off-by: Cédric VINCENT <cedric.vincent at st.com>
    Reviewed-by: Christophe Guillon <christophe.guillon at st.com>
    Cc: Riku Voipio <riku.voipio at iki.fi>
    Signed-off-by: Riku Voipio <riku.voipio at iki.fi>

diff --git a/linux-user/syscall.c b/linux-user/syscall.c
index b975730..608924a 100644
--- a/linux-user/syscall.c
+++ b/linux-user/syscall.c
@@ -709,29 +709,44 @@ char *target_strerror(int err)
 
 static abi_ulong target_brk;
 static abi_ulong target_original_brk;
+static abi_ulong brk_page;
 
 void target_set_brk(abi_ulong new_brk)
 {
     target_original_brk = target_brk = HOST_PAGE_ALIGN(new_brk);
+    brk_page = HOST_PAGE_ALIGN(target_brk);
 }
 
+//#define DEBUGF_BRK(message, args...) do { fprintf(stderr, (message), ## args); } while (0)
+#define DEBUGF_BRK(message, args...)
+
 /* do_brk() must return target values and target errnos. */
 abi_long do_brk(abi_ulong new_brk)
 {
-    abi_ulong brk_page;
     abi_long mapped_addr;
     int	new_alloc_size;
 
-    if (!new_brk)
+    DEBUGF_BRK("do_brk(%#010x) -> ", new_brk);
+
+    if (!new_brk) {
+        DEBUGF_BRK("%#010x (!new_brk)\n", target_brk);
         return target_brk;
-    if (new_brk < target_original_brk)
+    }
+    if (new_brk < target_original_brk) {
+        DEBUGF_BRK("%#010x (new_brk < target_original_brk)\n", target_brk);
         return target_brk;
+    }
 
-    brk_page = HOST_PAGE_ALIGN(target_brk);
-
-    /* If the new brk is less than this, set it and we're done... */
-    if (new_brk < brk_page) {
+    /* If the new brk is less than the highest page reserved to the
+     * target heap allocation, set it and we're almost done...  */
+    if (new_brk <= brk_page) {
+        /* Heap contents are initialized to zero, as for anonymous
+         * mapped pages.  */
+        if (new_brk > target_brk) {
+            memset(g2h(target_brk), 0, new_brk - target_brk);
+        }
 	target_brk = new_brk;
+        DEBUGF_BRK("%#010x (new_brk <= brk_page)\n", target_brk);
     	return target_brk;
     }
 
@@ -741,13 +756,15 @@ abi_long do_brk(abi_ulong new_brk)
      * itself); instead we treat "mapped but at wrong address" as
      * a failure and unmap again.
      */
-    new_alloc_size = HOST_PAGE_ALIGN(new_brk - brk_page + 1);
+    new_alloc_size = HOST_PAGE_ALIGN(new_brk - brk_page);
     mapped_addr = get_errno(target_mmap(brk_page, new_alloc_size,
                                         PROT_READ|PROT_WRITE,
                                         MAP_ANON|MAP_PRIVATE, 0, 0));
 
     if (mapped_addr == brk_page) {
         target_brk = new_brk;
+        brk_page = HOST_PAGE_ALIGN(target_brk);
+        DEBUGF_BRK("%#010x (mapped_addr == brk_page)\n", target_brk);
         return target_brk;
     } else if (mapped_addr != -1) {
         /* Mapped but at wrong address, meaning there wasn't actually
@@ -755,6 +772,10 @@ abi_long do_brk(abi_ulong new_brk)
          */
         target_munmap(mapped_addr, new_alloc_size);
         mapped_addr = -1;
+        DEBUGF_BRK("%#010x (mapped_addr != -1)\n", target_brk);
+    }
+    else {
+        DEBUGF_BRK("%#010x (otherwise)\n", target_brk);
     }
 
 #if defined(TARGET_ALPHA)
commit 5382a012e8ce7cf5ea612d291286be827574c181
Author: Peter Maydell <peter.maydell at linaro.org>
Date:   Mon Apr 18 16:34:26 2011 +0100

    m68k-semi.c: Use correct check for failure of do_brk()
    
    In the m68k semihosting implementation of HOSTED_INIT_SIM, use the correct
    check for whether do_brk() has failed -- it does not return -1 but the
    previous value of the break limit.
    
    Signed-off-by: Peter Maydell <peter.maydell at linaro.org>
    Signed-off-by: Riku Voipio <riku.voipio at iki.fi>

diff --git a/m68k-semi.c b/m68k-semi.c
index 0371089..7fde10e 100644
--- a/m68k-semi.c
+++ b/m68k-semi.c
@@ -370,7 +370,7 @@ void do_m68k_semihosting(CPUM68KState *env, int nr)
         TaskState *ts = env->opaque;
         /* Allocate the heap using sbrk.  */
         if (!ts->heap_limit) {
-            long ret;
+            abi_ulong ret;
             uint32_t size;
             uint32_t base;
 
@@ -379,8 +379,9 @@ void do_m68k_semihosting(CPUM68KState *env, int nr)
             /* Try a big heap, and reduce the size if that fails.  */
             for (;;) {
                 ret = do_brk(base + size);
-                if (ret != -1)
+                if (ret >= (base + size)) {
                     break;
+                }
                 size >>= 1;
             }
             ts->heap_limit = base + size;
commit 206ae74aea5593f5f5bad769a6b4f101f17bc6fd
Author: Peter Maydell <peter.maydell at linaro.org>
Date:   Mon Apr 18 16:34:25 2011 +0100

    arm-semi.c: Use correct check for failure of do_brk()
    
    In the ARM semihosting implementation of SYS_HEAPINFO, use the correct
    check for whether do_brk() has failed -- it does not return -1 but the
    previous value of the break limit.
    
    Signed-off-by: Peter Maydell <peter.maydell at linaro.org>
    Signed-off-by: Riku Voipio <riku.voipio at iki.fi>

diff --git a/arm-semi.c b/arm-semi.c
index e9e6f89..5a62d03 100644
--- a/arm-semi.c
+++ b/arm-semi.c
@@ -440,15 +440,16 @@ uint32_t do_arm_semihosting(CPUState *env)
             /* Some C libraries assume the heap immediately follows .bss, so
                allocate it using sbrk.  */
             if (!ts->heap_limit) {
-                long ret;
+                abi_ulong ret;
 
                 ts->heap_base = do_brk(0);
                 limit = ts->heap_base + ARM_ANGEL_HEAP_SIZE;
                 /* Try a big heap, and reduce the size if that fails.  */
                 for (;;) {
                     ret = do_brk(limit);
-                    if (ret != -1)
+                    if (ret >= limit) {
                         break;
+                    }
                     limit = (ts->heap_base >> 1) + (limit >> 1);
                 }
                 ts->heap_limit = limit;
commit 00faf08c951fcc351467faac5697307a86edb077
Author: Peter Maydell <peter.maydell at linaro.org>
Date:   Mon Apr 18 16:34:24 2011 +0100

    linux-user: Don't use MAP_FIXED in do_brk()
    
    Since mmap() with MAP_FIXED will map over the top of existing mappings,
    it's a bad idea to use it to implement brk(), because brk() with a
    large size is likely to overwrite important things like qemu itself
    or the host libc. So we drop MAP_FIXED and handle "mapped but at
    different address" as an error case instead.
    
    Signed-off-by: Peter Maydell <peter.maydell at linaro.org>
    Signed-off-by: Riku Voipio <riku.voipio at iki.fi>

diff --git a/linux-user/syscall.c b/linux-user/syscall.c
index 5cb27c7..b975730 100644
--- a/linux-user/syscall.c
+++ b/linux-user/syscall.c
@@ -735,23 +735,34 @@ abi_long do_brk(abi_ulong new_brk)
     	return target_brk;
     }
 
-    /* We need to allocate more memory after the brk... */
+    /* We need to allocate more memory after the brk... Note that
+     * we don't use MAP_FIXED because that will map over the top of
+     * any existing mapping (like the one with the host libc or qemu
+     * itself); instead we treat "mapped but at wrong address" as
+     * a failure and unmap again.
+     */
     new_alloc_size = HOST_PAGE_ALIGN(new_brk - brk_page + 1);
     mapped_addr = get_errno(target_mmap(brk_page, new_alloc_size,
                                         PROT_READ|PROT_WRITE,
-                                        MAP_ANON|MAP_FIXED|MAP_PRIVATE, 0, 0));
+                                        MAP_ANON|MAP_PRIVATE, 0, 0));
+
+    if (mapped_addr == brk_page) {
+        target_brk = new_brk;
+        return target_brk;
+    } else if (mapped_addr != -1) {
+        /* Mapped but at wrong address, meaning there wasn't actually
+         * enough space for this brk.
+         */
+        target_munmap(mapped_addr, new_alloc_size);
+        mapped_addr = -1;
+    }
 
 #if defined(TARGET_ALPHA)
     /* We (partially) emulate OSF/1 on Alpha, which requires we
        return a proper errno, not an unchanged brk value.  */
-    if (is_error(mapped_addr)) {
-        return -TARGET_ENOMEM;
-    }
+    return -TARGET_ENOMEM;
 #endif
-
-    if (!is_error(mapped_addr)) {
-	target_brk = new_brk;
-    }
+    /* For everything else, return the previous break. */
     return target_brk;
 }
 
commit f3ed1f5d476bfc18c4b2e27bf2386f54c98561f1
Author: Peter Maydell <peter.maydell at linaro.org>
Date:   Tue May 17 13:34:46 2011 +0100

    linux-user: Handle images where lowest vaddr is not page aligned
    
    Fix a bug in the linux-user ELF loader code where it was not correctly
    handling images where the lowest vaddr to be loaded was not page aligned.
    The problem was that the code to probe for a suitable guest base address
    was changing the 'loaddr' variable (by rounding it to a page boundary),
    which meant that the load bias would then be incorrectly calculated
    unless loaddr happened to already be page-aligned.
    
    Binaries generated by gcc with the default linker script do start with
    a loadable segment at a page-aligned vaddr, so were unaffected. This
    bug was noticed with a binary created by the Google Go toolchain for ARM.
    
    We fix the bug by refactoring the "probe for guest base" code out into
    its own self-contained function.
    
    Signed-off-by: Peter Maydell <peter.maydell at linaro.org>
    Signed-off-by: Riku Voipio <riku.voipio at iki.fi>

diff --git a/linux-user/elfload.c b/linux-user/elfload.c
index a4aabd5..a13eb7b 100644
--- a/linux-user/elfload.c
+++ b/linux-user/elfload.c
@@ -1288,6 +1288,78 @@ static abi_ulong create_elf_tables(abi_ulong p, int argc, int envc,
     return sp;
 }
 
+static void probe_guest_base(const char *image_name,
+                             abi_ulong loaddr, abi_ulong hiaddr)
+{
+    /* Probe for a suitable guest base address, if the user has not set
+     * it explicitly, and set guest_base appropriately.
+     * In case of error we will print a suitable message and exit.
+     */
+#if defined(CONFIG_USE_GUEST_BASE)
+    const char *errmsg;
+    if (!have_guest_base && !reserved_va) {
+        unsigned long host_start, real_start, host_size;
+
+        /* Round addresses to page boundaries.  */
+        loaddr &= qemu_host_page_mask;
+        hiaddr = HOST_PAGE_ALIGN(hiaddr);
+
+        if (loaddr < mmap_min_addr) {
+            host_start = HOST_PAGE_ALIGN(mmap_min_addr);
+        } else {
+            host_start = loaddr;
+            if (host_start != loaddr) {
+                errmsg = "Address overflow loading ELF binary";
+                goto exit_errmsg;
+            }
+        }
+        host_size = hiaddr - loaddr;
+        while (1) {
+            /* Do not use mmap_find_vma here because that is limited to the
+               guest address space.  We are going to make the
+               guest address space fit whatever we're given.  */
+            real_start = (unsigned long)
+                mmap((void *)host_start, host_size, PROT_NONE,
+                     MAP_ANONYMOUS | MAP_PRIVATE | MAP_NORESERVE, -1, 0);
+            if (real_start == (unsigned long)-1) {
+                goto exit_perror;
+            }
+            if (real_start == host_start) {
+                break;
+            }
+            /* That address didn't work.  Unmap and try a different one.
+               The address the host picked because is typically right at
+               the top of the host address space and leaves the guest with
+               no usable address space.  Resort to a linear search.  We
+               already compensated for mmap_min_addr, so this should not
+               happen often.  Probably means we got unlucky and host
+               address space randomization put a shared library somewhere
+               inconvenient.  */
+            munmap((void *)real_start, host_size);
+            host_start += qemu_host_page_size;
+            if (host_start == loaddr) {
+                /* Theoretically possible if host doesn't have any suitably
+                   aligned areas.  Normally the first mmap will fail.  */
+                errmsg = "Unable to find space for application";
+                goto exit_errmsg;
+            }
+        }
+        qemu_log("Relocating guest address space from 0x"
+                 TARGET_ABI_FMT_lx " to 0x%lx\n",
+                 loaddr, real_start);
+        guest_base = real_start - loaddr;
+    }
+    return;
+
+exit_perror:
+    errmsg = strerror(errno);
+exit_errmsg:
+    fprintf(stderr, "%s: %s\n", image_name, errmsg);
+    exit(-1);
+#endif
+}
+
+
 /* Load an ELF image into the address space.
 
    IMAGE_NAME is the filename of the image, to use in error messages.
@@ -1373,63 +1445,7 @@ static void load_elf_image(const char *image_name, int image_fd,
         /* This is the main executable.  Make sure that the low
            address does not conflict with MMAP_MIN_ADDR or the
            QEMU application itself.  */
-#if defined(CONFIG_USE_GUEST_BASE)
-        /*
-         * In case where user has not explicitly set the guest_base, we
-         * probe here that should we set it automatically.
-         */
-        if (!have_guest_base && !reserved_va) {
-            unsigned long host_start, real_start, host_size;
-
-            /* Round addresses to page boundaries.  */
-            loaddr &= qemu_host_page_mask;
-            hiaddr = HOST_PAGE_ALIGN(hiaddr);
-
-            if (loaddr < mmap_min_addr) {
-                host_start = HOST_PAGE_ALIGN(mmap_min_addr);
-            } else {
-                host_start = loaddr;
-                if (host_start != loaddr) {
-                    errmsg = "Address overflow loading ELF binary";
-                    goto exit_errmsg;
-                }
-            }
-            host_size = hiaddr - loaddr;
-            while (1) {
-                /* Do not use mmap_find_vma here because that is limited to the
-                   guest address space.  We are going to make the
-                   guest address space fit whatever we're given.  */
-                real_start = (unsigned long)
-                    mmap((void *)host_start, host_size, PROT_NONE,
-                         MAP_ANONYMOUS | MAP_PRIVATE | MAP_NORESERVE, -1, 0);
-                if (real_start == (unsigned long)-1) {
-                    goto exit_perror;
-                }
-                if (real_start == host_start) {
-                    break;
-                }
-                /* That address didn't work.  Unmap and try a different one.
-                   The address the host picked because is typically right at
-                   the top of the host address space and leaves the guest with
-                   no usable address space.  Resort to a linear search.  We
-                   already compensated for mmap_min_addr, so this should not
-                   happen often.  Probably means we got unlucky and host
-                   address space randomization put a shared library somewhere
-                   inconvenient.  */
-                munmap((void *)real_start, host_size);
-                host_start += qemu_host_page_size;
-                if (host_start == loaddr) {
-                    /* Theoretically possible if host doesn't have any suitably
-                       aligned areas.  Normally the first mmap will fail.  */
-                    errmsg = "Unable to find space for application";
-                    goto exit_errmsg;
-                }
-            }
-            qemu_log("Relocating guest address space from 0x"
-                     TARGET_ABI_FMT_lx " to 0x%lx\n", loaddr, real_start);
-            guest_base = real_start - loaddr;
-        }
-#endif
+        probe_guest_base(image_name, loaddr, hiaddr);
     }
     load_bias = load_addr - loaddr;
 
commit b947527941b17c8f4a31f95dfa114e467ba1325d
Author: Cédric VINCENT <cedric.vincent at st.com>
Date:   Wed Jun 1 14:36:38 2011 +0200

    linux-user: Fix the load of ELF files that have no "useful" symbol
    
    This patch fixes a "double free()" due to "realloc(syms, 0)" in the
    loader when the ELF file has no "useful" symbol, as with the following
    example (compiled with "sh4-linux-gcc -nostdlib"):
    
        .text
        .align 1
        .global _start
        _start:
            mov     #1, r3
            trapa   #40     // syscall(__NR_exit)
            nop
    
    The bug appears when the log (option "-d") is enabled.
    
    Signed-off-by: Cédric VINCENT <cedric.vincent at st.com>
    Signed-off-by: Yves JANIN <yves.janin at st.com>
    Signed-off-by: Riku Voipio <riku.voipio at iki.fi>
    Reviewed-by: Richard Henderson <rth at twiddle.net>

diff --git a/linux-user/elfload.c b/linux-user/elfload.c
index dcfeb7a..a4aabd5 100644
--- a/linux-user/elfload.c
+++ b/linux-user/elfload.c
@@ -1643,9 +1643,9 @@ static void load_symbols(struct elfhdr *hdr, int fd, abi_ulong load_bias)
 {
     int i, shnum, nsyms, sym_idx = 0, str_idx = 0;
     struct elf_shdr *shdr;
-    char *strings;
-    struct syminfo *s;
-    struct elf_sym *syms, *new_syms;
+    char *strings = NULL;
+    struct syminfo *s = NULL;
+    struct elf_sym *new_syms, *syms = NULL;
 
     shnum = hdr->e_shnum;
     i = shnum * sizeof(struct elf_shdr);
@@ -1670,24 +1670,19 @@ static void load_symbols(struct elfhdr *hdr, int fd, abi_ulong load_bias)
     /* Now know where the strtab and symtab are.  Snarf them.  */
     s = malloc(sizeof(*s));
     if (!s) {
-        return;
+        goto give_up;
     }
 
     i = shdr[str_idx].sh_size;
     s->disas_strtab = strings = malloc(i);
     if (!strings || pread(fd, strings, i, shdr[str_idx].sh_offset) != i) {
-        free(s);
-        free(strings);
-        return;
+        goto give_up;
     }
 
     i = shdr[sym_idx].sh_size;
     syms = malloc(i);
     if (!syms || pread(fd, syms, i, shdr[sym_idx].sh_offset) != i) {
-        free(s);
-        free(strings);
-        free(syms);
-        return;
+        goto give_up;
     }
 
     nsyms = i / sizeof(struct elf_sym);
@@ -1710,16 +1705,18 @@ static void load_symbols(struct elfhdr *hdr, int fd, abi_ulong load_bias)
         }
     }
 
+    /* No "useful" symbol.  */
+    if (nsyms == 0) {
+        goto give_up;
+    }
+
     /* Attempt to free the storage associated with the local symbols
        that we threw away.  Whether or not this has any effect on the
        memory allocation depends on the malloc implementation and how
        many symbols we managed to discard.  */
     new_syms = realloc(syms, nsyms * sizeof(*syms));
     if (new_syms == NULL) {
-        free(s);
-        free(syms);
-        free(strings);
-        return;
+        goto give_up;
     }
     syms = new_syms;
 
@@ -1734,6 +1731,13 @@ static void load_symbols(struct elfhdr *hdr, int fd, abi_ulong load_bias)
     s->lookup_symbol = lookup_symbolxx;
     s->next = syminfos;
     syminfos = s;
+
+    return;
+
+give_up:
+    free(s);
+    free(strings);
+    free(syms);
 }
 
 int load_elf_binary(struct linux_binprm * bprm, struct target_pt_regs * regs,
commit ca98557ad2510eaeb6538b4c4d9972818e83b6c2
Author: Marcelo Tosatti <mtosatti at redhat.com>
Date:   Tue Jun 21 13:53:18 2011 -0300

    kvm: fix FPU state subsection
    
    There is no need to specify version on the subsection fields.
    
    Signed-off-by: Marcelo Tosatti <mtosatti at redhat.com>

diff --git a/target-i386/machine.c b/target-i386/machine.c
index d22a731..7662aa2 100644
--- a/target-i386/machine.c
+++ b/target-i386/machine.c
@@ -303,9 +303,9 @@ static const VMStateDescription vmstate_fpop_ip_dp = {
     .minimum_version_id = 1,
     .minimum_version_id_old = 1,
     .fields      = (VMStateField []) {
-        VMSTATE_UINT16_V(fpop, CPUState, 13),
-        VMSTATE_UINT64_V(fpip, CPUState, 13),
-        VMSTATE_UINT64_V(fpdp, CPUState, 13),
+        VMSTATE_UINT16(fpop, CPUState),
+        VMSTATE_UINT64(fpip, CPUState),
+        VMSTATE_UINT64(fpdp, CPUState),
         VMSTATE_END_OF_LIST()
     }
 };
commit 31e8c69697becf5e0b54a6a0cef1d27109d469e9
Author: Andre Przywara <andre.przywara at amd.com>
Date:   Fri Jun 10 15:56:28 2011 +0200

    KVM: Fix XSAVE feature bit enumeration
    
    When iterating through the XSAVE feature enumeration CPUID leaf (0xD)
    we should not stop at the first zero EAX, but instead keep scanning
    since there are gaps in the enumeration (ECX=1 for instance).
    This fixes the proper usage of AVX in KVM guests.
    
    Signed-off-by: Andre Przywara <andre.przywara at amd.com>
    Signed-off-by: Marcelo Tosatti <mtosatti at redhat.com>

diff --git a/target-i386/kvm.c b/target-i386/kvm.c
index 938e0a3..10fb2c4 100644
--- a/target-i386/kvm.c
+++ b/target-i386/kvm.c
@@ -416,6 +416,9 @@ int kvm_arch_init_vcpu(CPUState *env)
         case 0xb:
         case 0xd:
             for (j = 0; ; j++) {
+                if (i == 0xd && j == 64) {
+                    break;
+                }
                 c->function = i;
                 c->flags = KVM_CPUID_FLAG_SIGNIFCANT_INDEX;
                 c->index = j;
@@ -428,7 +431,7 @@ int kvm_arch_init_vcpu(CPUState *env)
                     break;
                 }
                 if (i == 0xd && c->eax == 0) {
-                    break;
+                    continue;
                 }
                 c = &cpuid_data.entries[cpuid_i++];
             }
commit 3d39c9593314946258bb334737aa7a4d113731d8
Author: Jan Kiszka <jan.kiszka at siemens.com>
Date:   Wed Jun 8 16:11:06 2011 +0200

    Remove unneeded kvm.h from cpu-exec.c
    
    This was obsoleted by 6792a57bf1.
    
    Signed-off-by: Jan Kiszka <jan.kiszka at siemens.com>
    Signed-off-by: Marcelo Tosatti <mtosatti at redhat.com>

diff --git a/cpu-exec.c b/cpu-exec.c
index e1de56b..7aa1d00 100644
--- a/cpu-exec.c
+++ b/cpu-exec.c
@@ -20,7 +20,6 @@
 #include "exec.h"
 #include "disas.h"
 #include "tcg.h"
-#include "kvm.h"
 #include "qemu-barrier.h"
 
 #if defined(__sparc__) && !defined(CONFIG_SOLARIS)
commit ba9bc59e1f5dc91caf35e0ef08da137b3a5e7386
Author: Jan Kiszka <jan.kiszka at siemens.com>
Date:   Wed Jun 8 16:11:05 2011 +0200

    kvm: x86: Pass KVMState to kvm_arch_get_supported_cpuid
    
    kvm_arch_get_supported_cpuid checks for global cpuid restrictions, it
    does not require any CPUState reference. Changing its interface allows
    to call it before any VCPU is initialized.
    
    CC: Eduardo Habkost <ehabkost at redhat.com>
    Signed-off-by: Jan Kiszka <jan.kiszka at siemens.com>
    Signed-off-by: Marcelo Tosatti <mtosatti at redhat.com>

diff --git a/kvm.h b/kvm.h
index d565dba..243b063 100644
--- a/kvm.h
+++ b/kvm.h
@@ -157,7 +157,7 @@ bool kvm_arch_stop_on_emulation_error(CPUState *env);
 
 int kvm_check_extension(KVMState *s, unsigned int extension);
 
-uint32_t kvm_arch_get_supported_cpuid(CPUState *env, uint32_t function,
+uint32_t kvm_arch_get_supported_cpuid(KVMState *env, uint32_t function,
                                       uint32_t index, int reg);
 void kvm_cpu_synchronize_state(CPUState *env);
 void kvm_cpu_synchronize_post_reset(CPUState *env);
diff --git a/target-i386/cpuid.c b/target-i386/cpuid.c
index 79e7580..e1ae3af 100644
--- a/target-i386/cpuid.c
+++ b/target-i386/cpuid.c
@@ -1144,10 +1144,12 @@ void cpu_x86_cpuid(CPUX86State *env, uint32_t index, uint32_t count,
         break;
     case 7:
         if (kvm_enabled()) {
-            *eax = kvm_arch_get_supported_cpuid(env, 0x7, count, R_EAX);
-            *ebx = kvm_arch_get_supported_cpuid(env, 0x7, count, R_EBX);
-            *ecx = kvm_arch_get_supported_cpuid(env, 0x7, count, R_ECX);
-            *edx = kvm_arch_get_supported_cpuid(env, 0x7, count, R_EDX);
+            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;
@@ -1179,10 +1181,12 @@ void cpu_x86_cpuid(CPUX86State *env, uint32_t index, uint32_t count,
             break;
         }
         if (kvm_enabled()) {
-            *eax = kvm_arch_get_supported_cpuid(env, 0xd, count, R_EAX);
-            *ebx = kvm_arch_get_supported_cpuid(env, 0xd, count, R_EBX);
-            *ecx = kvm_arch_get_supported_cpuid(env, 0xd, count, R_ECX);
-            *edx = kvm_arch_get_supported_cpuid(env, 0xd, count, R_EDX);
+            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;
diff --git a/target-i386/kvm.c b/target-i386/kvm.c
index 5db33ea..938e0a3 100644
--- a/target-i386/kvm.c
+++ b/target-i386/kvm.c
@@ -98,12 +98,12 @@ struct kvm_para_features {
     { -1, -1 }
 };
 
-static int get_para_features(CPUState *env)
+static int get_para_features(KVMState *s)
 {
     int i, features = 0;
 
     for (i = 0; i < ARRAY_SIZE(para_features) - 1; i++) {
-        if (kvm_check_extension(env->kvm_state, para_features[i].cap)) {
+        if (kvm_check_extension(s, para_features[i].cap)) {
             features |= (1 << para_features[i].feature);
         }
     }
@@ -112,7 +112,7 @@ static int get_para_features(CPUState *env)
 }
 
 
-uint32_t kvm_arch_get_supported_cpuid(CPUState *env, uint32_t function,
+uint32_t kvm_arch_get_supported_cpuid(KVMState *s, uint32_t function,
                                       uint32_t index, int reg)
 {
     struct kvm_cpuid2 *cpuid;
@@ -122,7 +122,7 @@ uint32_t kvm_arch_get_supported_cpuid(CPUState *env, uint32_t function,
     int has_kvm_features = 0;
 
     max = 1;
-    while ((cpuid = try_get_cpuid(env->kvm_state, max)) == NULL) {
+    while ((cpuid = try_get_cpuid(s, max)) == NULL) {
         max *= 2;
     }
 
@@ -153,7 +153,7 @@ uint32_t kvm_arch_get_supported_cpuid(CPUState *env, uint32_t function,
                     /* On Intel, kvm returns cpuid according to the Intel spec,
                      * so add missing bits according to the AMD spec:
                      */
-                    cpuid_1_edx = kvm_arch_get_supported_cpuid(env, 1, 0, R_EDX);
+                    cpuid_1_edx = kvm_arch_get_supported_cpuid(s, 1, 0, R_EDX);
                     ret |= cpuid_1_edx & 0x183f7ff;
                     break;
                 }
@@ -166,7 +166,7 @@ uint32_t kvm_arch_get_supported_cpuid(CPUState *env, uint32_t function,
 
     /* fallback for older kernels */
     if (!has_kvm_features && (function == KVM_CPUID_FEATURES)) {
-        ret = get_para_features(env);
+        ret = get_para_features(s);
     }
 
     return ret;
@@ -349,25 +349,25 @@ int kvm_arch_init_vcpu(CPUState *env)
         struct kvm_cpuid2 cpuid;
         struct kvm_cpuid_entry2 entries[100];
     } __attribute__((packed)) cpuid_data;
+    KVMState *s = env->kvm_state;
     uint32_t limit, i, j, cpuid_i;
     uint32_t unused;
     struct kvm_cpuid_entry2 *c;
     uint32_t signature[3];
 
-    env->cpuid_features &= kvm_arch_get_supported_cpuid(env, 1, 0, R_EDX);
+    env->cpuid_features &= kvm_arch_get_supported_cpuid(s, 1, 0, R_EDX);
 
     i = env->cpuid_ext_features & CPUID_EXT_HYPERVISOR;
-    env->cpuid_ext_features &= kvm_arch_get_supported_cpuid(env, 1, 0, R_ECX);
+    env->cpuid_ext_features &= kvm_arch_get_supported_cpuid(s, 1, 0, R_ECX);
     env->cpuid_ext_features |= i;
 
-    env->cpuid_ext2_features &= kvm_arch_get_supported_cpuid(env, 0x80000001,
+    env->cpuid_ext2_features &= kvm_arch_get_supported_cpuid(s, 0x80000001,
                                                              0, R_EDX);
-    env->cpuid_ext3_features &= kvm_arch_get_supported_cpuid(env, 0x80000001,
+    env->cpuid_ext3_features &= kvm_arch_get_supported_cpuid(s, 0x80000001,
                                                              0, R_ECX);
-    env->cpuid_svm_features  &= kvm_arch_get_supported_cpuid(env, 0x8000000A,
+    env->cpuid_svm_features  &= kvm_arch_get_supported_cpuid(s, 0x8000000A,
                                                              0, R_EDX);
 
-
     cpuid_i = 0;
 
     /* Paravirtualization CPUIDs */
@@ -383,8 +383,8 @@ int kvm_arch_init_vcpu(CPUState *env)
     c = &cpuid_data.entries[cpuid_i++];
     memset(c, 0, sizeof(*c));
     c->function = KVM_CPUID_FEATURES;
-    c->eax = env->cpuid_kvm_features & kvm_arch_get_supported_cpuid(env,
-                                                KVM_CPUID_FEATURES, 0, R_EAX);
+    c->eax = env->cpuid_kvm_features &
+        kvm_arch_get_supported_cpuid(s, KVM_CPUID_FEATURES, 0, R_EAX);
 
     has_msr_async_pf_en = c->eax & (1 << KVM_FEATURE_ASYNC_PF);
 
@@ -453,7 +453,7 @@ int kvm_arch_init_vcpu(CPUState *env)
     /* Call Centaur's CPUID instructions they are supported. */
     if (env->cpuid_xlevel2 > 0) {
         env->cpuid_ext4_features &=
-            kvm_arch_get_supported_cpuid(env, 0xC0000001, 0, R_EDX);
+            kvm_arch_get_supported_cpuid(s, 0xC0000001, 0, R_EDX);
         cpu_x86_cpuid(env, 0xC0000000, 0, &limit, &unused, &unused, &unused);
 
         for (i = 0xC0000000; i <= limit; i++) {
commit 4bef75b5333799da5cf5287705250dc562a41307
Author: Jan Kiszka <jan.kiszka at siemens.com>
Date:   Wed Jun 8 16:11:04 2011 +0200

    kvm: Clean up stubs
    
    No one references kvm_check_extension, kvm_has_vcpu_events, and
    kvm_has_robust_singlestep outside KVM code.
    
    kvm_update_guest_debug is never called, thus has no job besides
    returning an error.
    
    Signed-off-by: Jan Kiszka <jan.kiszka at siemens.com>
    Signed-off-by: Marcelo Tosatti <mtosatti at redhat.com>

diff --git a/kvm-stub.c b/kvm-stub.c
index 1c95452..1e835c6 100644
--- a/kvm-stub.c
+++ b/kvm-stub.c
@@ -42,11 +42,6 @@ int kvm_uncoalesce_mmio_region(target_phys_addr_t start, ram_addr_t size)
     return -ENOSYS;
 }
 
-int kvm_check_extension(KVMState *s, unsigned int extension)
-{
-    return 0;
-}
-
 int kvm_init(void)
 {
     return -ENOSYS;
@@ -78,16 +73,6 @@ int kvm_has_sync_mmu(void)
     return 0;
 }
 
-int kvm_has_vcpu_events(void)
-{
-    return 0;
-}
-
-int kvm_has_robust_singlestep(void)
-{
-    return 0;
-}
-
 int kvm_has_many_ioeventfds(void)
 {
     return 0;
@@ -99,8 +84,7 @@ void kvm_setup_guest_memory(void *start, size_t size)
 
 int kvm_update_guest_debug(CPUState *env, unsigned long reinject_trap)
 {
-    tb_flush(env);
-    return 0;
+    return -ENOSYS;
 }
 
 int kvm_insert_breakpoint(CPUState *current_env, target_ulong addr,
commit 3d0388f76f4bd8bd11f4a0747da0613d3b9ce32d
Author: Jan Kiszka <jan.kiszka at siemens.com>
Date:   Wed Jun 8 16:11:03 2011 +0200

    kvm: ppc: Drop KVM_CAP build dependencies
    
    No longer needed with accompanied kernel headers.
    
    CC: Alexander Graf <agraf at suse.de>
    Signed-off-by: Jan Kiszka <jan.kiszka at siemens.com>
    Reviewed-by: Alexander Graf <agraf at suse.de>
    Signed-off-by: Marcelo Tosatti <mtosatti at redhat.com>

diff --git a/target-ppc/kvm.c b/target-ppc/kvm.c
index 0500e3f..21f35af 100644
--- a/target-ppc/kvm.c
+++ b/target-ppc/kvm.c
@@ -65,18 +65,10 @@ static void kvm_kick_env(void *env)
 
 int kvm_arch_init(KVMState *s)
 {
-#ifdef KVM_CAP_PPC_UNSET_IRQ
     cap_interrupt_unset = kvm_check_extension(s, KVM_CAP_PPC_UNSET_IRQ);
-#endif
-#ifdef KVM_CAP_PPC_IRQ_LEVEL
     cap_interrupt_level = kvm_check_extension(s, KVM_CAP_PPC_IRQ_LEVEL);
-#endif
-#ifdef KVM_CAP_PPC_SEGSTATE
     cap_segstate = kvm_check_extension(s, KVM_CAP_PPC_SEGSTATE);
-#endif
-#ifdef KVM_CAP_PPC_BOOKE_SREGS
     cap_booke_sregs = kvm_check_extension(s, KVM_CAP_PPC_BOOKE_SREGS);
-#endif
 
     if (!cap_interrupt_level) {
         fprintf(stderr, "KVM: Couldn't find level irq capability. Expect the "
@@ -217,7 +209,6 @@ int kvm_arch_get_registers(CPUState *env)
             return ret;
         }
 
-#ifdef KVM_CAP_PPC_BOOKE_SREGS
         if (sregs.u.e.features & KVM_SREGS_E_BASE) {
             env->spr[SPR_BOOKE_CSRR0] = sregs.u.e.csrr0;
             env->spr[SPR_BOOKE_CSRR1] = sregs.u.e.csrr1;
@@ -314,7 +305,6 @@ int kvm_arch_get_registers(CPUState *env)
                 env->spr[SPR_BOOKE_PID2] = sregs.u.e.impl.fsl.pid2;
             }
         }
-#endif
     }
 
     if (cap_segstate) {
@@ -323,7 +313,6 @@ int kvm_arch_get_registers(CPUState *env)
             return ret;
         }
 
-#ifdef KVM_CAP_PPC_SEGSTATE
         ppc_store_sdr1(env, sregs.u.s.sdr1);
 
         /* Sync SLB */
@@ -346,7 +335,6 @@ int kvm_arch_get_registers(CPUState *env)
             env->IBAT[0][i] = sregs.u.s.ppc32.ibat[i] & 0xffffffff;
             env->IBAT[1][i] = sregs.u.s.ppc32.ibat[i] >> 32;
         }
-#endif
     }
 
     return 0;
@@ -525,7 +513,6 @@ int kvmppc_get_hypercall(CPUState *env, uint8_t *buf, int buf_len)
 {
     uint32_t *hc = (uint32_t*)buf;
 
-#ifdef KVM_CAP_PPC_GET_PVINFO
     struct kvm_ppc_pvinfo pvinfo;
 
     if (kvm_check_extension(env->kvm_state, KVM_CAP_PPC_GET_PVINFO) &&
@@ -534,7 +521,6 @@ int kvmppc_get_hypercall(CPUState *env, uint8_t *buf, int buf_len)
 
         return 0;
     }
-#endif
 
     /*
      * Fallback to always fail hypercalls:
commit e56ff191b6f73b2f7c20e2805a13173c70a568c8
Author: Jan Kiszka <jan.kiszka at siemens.com>
Date:   Wed Jun 8 16:11:02 2011 +0200

    kvm: x86: Drop KVM_CAP build dependencies
    
    No longer needed with accompanied kernel headers.
    
    Signed-off-by: Jan Kiszka <jan.kiszka at siemens.com>
    Signed-off-by: Marcelo Tosatti <mtosatti at redhat.com>

diff --git a/target-i386/kvm.c b/target-i386/kvm.c
index eb36e9f..5db33ea 100644
--- a/target-i386/kvm.c
+++ b/target-i386/kvm.c
@@ -94,9 +94,7 @@ struct kvm_para_features {
     { KVM_CAP_CLOCKSOURCE, KVM_FEATURE_CLOCKSOURCE },
     { KVM_CAP_NOP_IO_DELAY, KVM_FEATURE_NOP_IO_DELAY },
     { KVM_CAP_PV_MMU, KVM_FEATURE_MMU_OP },
-#ifdef KVM_CAP_ASYNC_PF
     { KVM_CAP_ASYNC_PF, KVM_FEATURE_ASYNC_PF },
-#endif
     { -1, -1 }
 };
 
@@ -193,7 +191,6 @@ static void kvm_unpoison_all(void *param)
     }
 }
 
-#ifdef KVM_CAP_MCE
 static void kvm_hwpoison_page_add(ram_addr_t ram_addr)
 {
     HWPoisonPage *page;
@@ -239,7 +236,6 @@ static void kvm_mce_inject(CPUState *env, target_phys_addr_t paddr, int code)
                        cpu_x86_support_mca_broadcast(env) ?
                        MCE_INJECT_BROADCAST : 0);
 }
-#endif /* KVM_CAP_MCE */
 
 static void hardware_memory_error(void)
 {
@@ -249,7 +245,6 @@ static void hardware_memory_error(void)
 
 int kvm_arch_on_sigbus_vcpu(CPUState *env, int code, void *addr)
 {
-#ifdef KVM_CAP_MCE
     ram_addr_t ram_addr;
     target_phys_addr_t paddr;
 
@@ -269,9 +264,7 @@ int kvm_arch_on_sigbus_vcpu(CPUState *env, int code, void *addr)
         }
         kvm_hwpoison_page_add(ram_addr);
         kvm_mce_inject(env, paddr, code);
-    } else
-#endif /* KVM_CAP_MCE */
-    {
+    } else {
         if (code == BUS_MCEERR_AO) {
             return 0;
         } else if (code == BUS_MCEERR_AR) {
@@ -285,7 +278,6 @@ int kvm_arch_on_sigbus_vcpu(CPUState *env, int code, void *addr)
 
 int kvm_arch_on_sigbus(int code, void *addr)
 {
-#ifdef KVM_CAP_MCE
     if ((first_cpu->mcg_cap & MCG_SER_P) && addr && code == BUS_MCEERR_AO) {
         ram_addr_t ram_addr;
         target_phys_addr_t paddr;
@@ -300,9 +292,7 @@ int kvm_arch_on_sigbus(int code, void *addr)
         }
         kvm_hwpoison_page_add(ram_addr);
         kvm_mce_inject(first_cpu, paddr, code);
-    } else
-#endif /* KVM_CAP_MCE */
-    {
+    } else {
         if (code == BUS_MCEERR_AO) {
             return 0;
         } else if (code == BUS_MCEERR_AR) {
@@ -316,7 +306,6 @@ int kvm_arch_on_sigbus(int code, void *addr)
 
 static int kvm_inject_mce_oldstyle(CPUState *env)
 {
-#ifdef KVM_CAP_MCE
     if (!kvm_has_vcpu_events() && env->exception_injected == EXCP12_MCHK) {
         unsigned int bank, bank_num = env->mcg_cap & 0xff;
         struct kvm_x86_mce mce;
@@ -342,7 +331,6 @@ static int kvm_inject_mce_oldstyle(CPUState *env)
 
         return kvm_vcpu_ioctl(env, KVM_X86_SET_MCE, &mce);
     }
-#endif /* KVM_CAP_MCE */
     return 0;
 }
 
@@ -398,9 +386,7 @@ int kvm_arch_init_vcpu(CPUState *env)
     c->eax = env->cpuid_kvm_features & kvm_arch_get_supported_cpuid(env,
                                                 KVM_CPUID_FEATURES, 0, R_EAX);
 
-#ifdef KVM_CAP_ASYNC_PF
     has_msr_async_pf_en = c->eax & (1 << KVM_FEATURE_ASYNC_PF);
-#endif
 
     cpu_x86_cpuid(env, 0, 0, &limit, &unused, &unused, &unused);
 
@@ -481,7 +467,6 @@ int kvm_arch_init_vcpu(CPUState *env)
 
     cpuid_data.cpuid.nent = cpuid_i;
 
-#ifdef KVM_CAP_MCE
     if (((env->cpuid_version >> 8)&0xF) >= 6
         && (env->cpuid_features&(CPUID_MCE|CPUID_MCA)) == (CPUID_MCE|CPUID_MCA)
         && kvm_check_extension(env->kvm_state, KVM_CAP_MCE) > 0) {
@@ -508,7 +493,6 @@ int kvm_arch_init_vcpu(CPUState *env)
 
         env->mcg_cap = mcg_cap;
     }
-#endif
 
     qemu_add_vm_change_state_handler(cpu_update_state, env);
 
@@ -600,7 +584,6 @@ int kvm_arch_init(KVMState *s)
      * that case we need to stick with the default, i.e. a 256K maximum BIOS
      * size.
      */
-#ifdef KVM_CAP_SET_IDENTITY_MAP_ADDR
     if (kvm_check_extension(s, KVM_CAP_SET_IDENTITY_MAP_ADDR)) {
         /* Allows up to 16M BIOSes. */
         identity_base = 0xfeffc000;
@@ -610,7 +593,7 @@ int kvm_arch_init(KVMState *s)
             return ret;
         }
     }
-#endif
+
     /* Set TSS base one page after EPT identity map. */
     ret = kvm_vm_ioctl(s, KVM_SET_TSS_ADDR, identity_base + 0x1000);
     if (ret < 0) {
@@ -748,7 +731,6 @@ static int kvm_put_fpu(CPUState *env)
     return kvm_vcpu_ioctl(env, KVM_SET_FPU, &fpu);
 }
 
-#ifdef KVM_CAP_XSAVE
 #define XSAVE_CWD_RIP     2
 #define XSAVE_CWD_RDP     4
 #define XSAVE_MXCSR       6
@@ -756,11 +738,9 @@ static int kvm_put_fpu(CPUState *env)
 #define XSAVE_XMM_SPACE   40
 #define XSAVE_XSTATE_BV   128
 #define XSAVE_YMMH_SPACE  144
-#endif
 
 static int kvm_put_xsave(CPUState *env)
 {
-#ifdef KVM_CAP_XSAVE
     int i, r;
     struct kvm_xsave* xsave;
     uint16_t cwd, swd, twd;
@@ -793,14 +773,10 @@ static int kvm_put_xsave(CPUState *env)
     r = kvm_vcpu_ioctl(env, KVM_SET_XSAVE, xsave);
     qemu_free(xsave);
     return r;
-#else
-    return kvm_put_fpu(env);
-#endif
 }
 
 static int kvm_put_xcrs(CPUState *env)
 {
-#ifdef KVM_CAP_XCRS
     struct kvm_xcrs xcrs;
 
     if (!kvm_has_xcrs()) {
@@ -812,9 +788,6 @@ static int kvm_put_xcrs(CPUState *env)
     xcrs.xcrs[0].xcr = 0;
     xcrs.xcrs[0].value = env->xcr0;
     return kvm_vcpu_ioctl(env, KVM_SET_XCRS, &xcrs);
-#else
-    return 0;
-#endif
 }
 
 static int kvm_put_sregs(CPUState *env)
@@ -923,7 +896,6 @@ static int kvm_put_msrs(CPUState *env, int level)
                               env->async_pf_en_msr);
         }
     }
-#ifdef KVM_CAP_MCE
     if (env->mcg_cap) {
         int i;
 
@@ -933,7 +905,6 @@ static int kvm_put_msrs(CPUState *env, int level)
             kvm_msr_entry_set(&msrs[n++], MSR_MC0_CTL + i, env->mce_banks[i]);
         }
     }
-#endif
 
     msr_data.info.nmsrs = n;
 
@@ -970,7 +941,6 @@ static int kvm_get_fpu(CPUState *env)
 
 static int kvm_get_xsave(CPUState *env)
 {
-#ifdef KVM_CAP_XSAVE
     struct kvm_xsave* xsave;
     int ret, i;
     uint16_t cwd, swd, twd;
@@ -1008,14 +978,10 @@ static int kvm_get_xsave(CPUState *env)
             sizeof env->ymmh_regs);
     qemu_free(xsave);
     return 0;
-#else
-    return kvm_get_fpu(env);
-#endif
 }
 
 static int kvm_get_xcrs(CPUState *env)
 {
-#ifdef KVM_CAP_XCRS
     int i, ret;
     struct kvm_xcrs xcrs;
 
@@ -1036,9 +1002,6 @@ static int kvm_get_xcrs(CPUState *env)
         }
     }
     return 0;
-#else
-    return 0;
-#endif
 }
 
 static int kvm_get_sregs(CPUState *env)
@@ -1166,7 +1129,6 @@ static int kvm_get_msrs(CPUState *env)
         msrs[n++].index = MSR_KVM_ASYNC_PF_EN;
     }
 
-#ifdef KVM_CAP_MCE
     if (env->mcg_cap) {
         msrs[n++].index = MSR_MCG_STATUS;
         msrs[n++].index = MSR_MCG_CTL;
@@ -1174,7 +1136,6 @@ static int kvm_get_msrs(CPUState *env)
             msrs[n++].index = MSR_MC0_CTL + i;
         }
     }
-#endif
 
     msr_data.info.nmsrs = n;
     ret = kvm_vcpu_ioctl(env, KVM_GET_MSRS, &msr_data);
@@ -1225,21 +1186,17 @@ static int kvm_get_msrs(CPUState *env)
         case MSR_KVM_WALL_CLOCK:
             env->wall_clock_msr = msrs[i].data;
             break;
-#ifdef KVM_CAP_MCE
         case MSR_MCG_STATUS:
             env->mcg_status = msrs[i].data;
             break;
         case MSR_MCG_CTL:
             env->mcg_ctl = msrs[i].data;
             break;
-#endif
         default:
-#ifdef KVM_CAP_MCE
             if (msrs[i].index >= MSR_MC0_CTL &&
                 msrs[i].index < MSR_MC0_CTL + (env->mcg_cap & 0xff) * 4) {
                 env->mce_banks[msrs[i].index - MSR_MC0_CTL] = msrs[i].data;
             }
-#endif
             break;
         case MSR_KVM_ASYNC_PF_EN:
             env->async_pf_en_msr = msrs[i].data;
@@ -1275,7 +1232,6 @@ static int kvm_get_mp_state(CPUState *env)
 
 static int kvm_put_vcpu_events(CPUState *env, int level)
 {
-#ifdef KVM_CAP_VCPU_EVENTS
     struct kvm_vcpu_events events;
 
     if (!kvm_has_vcpu_events()) {
@@ -1304,14 +1260,10 @@ static int kvm_put_vcpu_events(CPUState *env, int level)
     }
 
     return kvm_vcpu_ioctl(env, KVM_SET_VCPU_EVENTS, &events);
-#else
-    return 0;
-#endif
 }
 
 static int kvm_get_vcpu_events(CPUState *env)
 {
-#ifdef KVM_CAP_VCPU_EVENTS
     struct kvm_vcpu_events events;
     int ret;
 
@@ -1341,7 +1293,6 @@ static int kvm_get_vcpu_events(CPUState *env)
     }
 
     env->sipi_vector = events.sipi_vector;
-#endif
 
     return 0;
 }
@@ -1349,7 +1300,6 @@ static int kvm_get_vcpu_events(CPUState *env)
 static int kvm_guest_debug_workarounds(CPUState *env)
 {
     int ret = 0;
-#ifdef KVM_CAP_SET_GUEST_DEBUG
     unsigned long reinject_trap = 0;
 
     if (!kvm_has_vcpu_events()) {
@@ -1373,13 +1323,11 @@ static int kvm_guest_debug_workarounds(CPUState *env)
         (!kvm_has_robust_singlestep() && env->singlestep_enabled)) {
         ret = kvm_update_guest_debug(env, reinject_trap);
     }
-#endif /* KVM_CAP_SET_GUEST_DEBUG */
     return ret;
 }
 
 static int kvm_put_debugregs(CPUState *env)
 {
-#ifdef KVM_CAP_DEBUGREGS
     struct kvm_debugregs dbgregs;
     int i;
 
@@ -1395,14 +1343,10 @@ static int kvm_put_debugregs(CPUState *env)
     dbgregs.flags = 0;
 
     return kvm_vcpu_ioctl(env, KVM_SET_DEBUGREGS, &dbgregs);
-#else
-    return 0;
-#endif
 }
 
 static int kvm_get_debugregs(CPUState *env)
 {
-#ifdef KVM_CAP_DEBUGREGS
     struct kvm_debugregs dbgregs;
     int i, ret;
 
@@ -1419,7 +1363,6 @@ static int kvm_get_debugregs(CPUState *env)
     }
     env->dr[4] = env->dr[6] = dbgregs.dr6;
     env->dr[5] = env->dr[7] = dbgregs.dr7;
-#endif
 
     return 0;
 }
@@ -1645,7 +1588,6 @@ static int kvm_handle_halt(CPUState *env)
     return 0;
 }
 
-#ifdef KVM_CAP_SET_GUEST_DEBUG
 int kvm_arch_insert_sw_breakpoint(CPUState *env, struct kvm_sw_breakpoint *bp)
 {
     static const uint8_t int3 = 0xcc;
@@ -1826,7 +1768,6 @@ void kvm_arch_update_guest_debug(CPUState *env, struct kvm_guest_debug *dbg)
         }
     }
 }
-#endif /* KVM_CAP_SET_GUEST_DEBUG */
 
 static bool host_supports_vmx(void)
 {
@@ -1873,12 +1814,10 @@ int kvm_arch_handle_exit(CPUState *env, struct kvm_run *run)
                 run->ex.exception, run->ex.error_code);
         ret = -1;
         break;
-#ifdef KVM_CAP_SET_GUEST_DEBUG
     case KVM_EXIT_DEBUG:
         DPRINTF("kvm_exit_debug\n");
         ret = kvm_handle_debug(&run->debug.arch);
         break;
-#endif /* KVM_CAP_SET_GUEST_DEBUG */
     default:
         fprintf(stderr, "KVM: unknown exit reason %d\n", run->exit_reason);
         ret = -1;
commit ba4047cf848a3f593777aac19551a216682fc248
Author: Jan Kiszka <jan.kiszka at siemens.com>
Date:   Wed Jun 8 16:11:01 2011 +0200

    kvm: Drop KVM_CAP build dependencies
    
    No longer needed with accompanied kernel headers. We are only left with
    build dependencies that are controlled by kvm arch headers.
    
    CC: Alexander Graf <agraf at suse.de>
    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 4a9910a..cbc2532 100644
--- a/kvm-all.c
+++ b/kvm-all.c
@@ -757,21 +757,17 @@ int kvm_init(void)
     s->coalesced_mmio = kvm_check_extension(s, KVM_CAP_COALESCED_MMIO);
 
     s->broken_set_mem_region = 1;
-#ifdef KVM_CAP_JOIN_MEMORY_REGIONS_WORKS
     ret = kvm_check_extension(s, KVM_CAP_JOIN_MEMORY_REGIONS_WORKS);
     if (ret > 0) {
         s->broken_set_mem_region = 0;
     }
-#endif
 
 #ifdef KVM_CAP_VCPU_EVENTS
     s->vcpu_events = kvm_check_extension(s, KVM_CAP_VCPU_EVENTS);
 #endif
 
-#ifdef KVM_CAP_X86_ROBUST_SINGLESTEP
     s->robust_singlestep =
         kvm_check_extension(s, KVM_CAP_X86_ROBUST_SINGLESTEP);
-#endif
 
 #ifdef KVM_CAP_DEBUGREGS
     s->debugregs = kvm_check_extension(s, KVM_CAP_DEBUGREGS);
@@ -850,7 +846,6 @@ static void kvm_handle_io(uint16_t port, void *data, int direction, int size,
     }
 }
 
-#ifdef KVM_CAP_INTERNAL_ERROR_DATA
 static int kvm_handle_internal_error(CPUState *env, struct kvm_run *run)
 {
     fprintf(stderr, "KVM internal error.");
@@ -877,7 +872,6 @@ static int kvm_handle_internal_error(CPUState *env, struct kvm_run *run)
      */
     return -1;
 }
-#endif
 
 void kvm_flush_coalesced_mmio_buffer(void)
 {
@@ -1008,11 +1002,9 @@ int kvm_cpu_exec(CPUState *env)
                     (uint64_t)run->hw.hardware_exit_reason);
             ret = -1;
             break;
-#ifdef KVM_CAP_INTERNAL_ERROR_DATA
         case KVM_EXIT_INTERNAL_ERROR:
             ret = kvm_handle_internal_error(env, run);
             break;
-#endif
         default:
             DPRINTF("kvm_arch_handle_exit\n");
             ret = kvm_arch_handle_exit(env, run);
commit 1480b74f9a9b13dc3d9bcc4318461b02f86799f8
Author: Jan Kiszka <jan.kiszka at siemens.com>
Date:   Wed Jun 8 16:11:00 2011 +0200

    kvm: Drop useless zero-initializations
    
    Backing KVMState is alreay zero-initialized.
    
    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 106eb3a..4a9910a 100644
--- a/kvm-all.c
+++ b/kvm-all.c
@@ -764,28 +764,23 @@ int kvm_init(void)
     }
 #endif
 
-    s->vcpu_events = 0;
 #ifdef KVM_CAP_VCPU_EVENTS
     s->vcpu_events = kvm_check_extension(s, KVM_CAP_VCPU_EVENTS);
 #endif
 
-    s->robust_singlestep = 0;
 #ifdef KVM_CAP_X86_ROBUST_SINGLESTEP
     s->robust_singlestep =
         kvm_check_extension(s, KVM_CAP_X86_ROBUST_SINGLESTEP);
 #endif
 
-    s->debugregs = 0;
 #ifdef KVM_CAP_DEBUGREGS
     s->debugregs = kvm_check_extension(s, KVM_CAP_DEBUGREGS);
 #endif
 
-    s->xsave = 0;
 #ifdef KVM_CAP_XSAVE
     s->xsave = kvm_check_extension(s, KVM_CAP_XSAVE);
 #endif
 
-    s->xcrs = 0;
 #ifdef KVM_CAP_XCRS
     s->xcrs = kvm_check_extension(s, KVM_CAP_XCRS);
 #endif
commit 0bed3bba7d68b35e4b0c63d597b377c49a14e509
Author: Jan Kiszka <jan.kiszka at siemens.com>
Date:   Wed Jun 8 16:10:59 2011 +0200

    kvm: ppc: Drop CONFIG_KVM_PPC_PVR
    
    Required header support is now unconditionally available.
    
    CC: Alexander Graf <agraf at suse.de>
    Signed-off-by: Jan Kiszka <jan.kiszka at siemens.com>
    Reviewed-by: Alexander Graf <agraf at suse.de>
    Signed-off-by: Marcelo Tosatti <mtosatti at redhat.com>

diff --git a/configure b/configure
index ebd5d56..3286e33 100755
--- a/configure
+++ b/configure
@@ -3226,7 +3226,6 @@ case "$target_arch2" in
       if test $vhost_net = "yes" ; then
         echo "CONFIG_VHOST_NET=y" >> $config_target_mak
       fi
-      echo "CONFIG_KVM_PPC_PVR=y" >> $config_target_mak
     fi
 esac
 if test "$target_bigendian" = "yes" ; then
diff --git a/target-ppc/kvm.c b/target-ppc/kvm.c
index e7b1b10..0500e3f 100644
--- a/target-ppc/kvm.c
+++ b/target-ppc/kvm.c
@@ -104,21 +104,12 @@ static int kvm_arch_sync_sregs(CPUState *cenv)
         }
     }
 
-#if !defined(CONFIG_KVM_PPC_PVR)
-    if (1) {
-        fprintf(stderr, "kvm error: missing PVR setting capability\n");
-        return -ENOSYS;
-    }
-#endif
-
     ret = kvm_vcpu_ioctl(cenv, KVM_GET_SREGS, &sregs);
     if (ret) {
         return ret;
     }
 
-#ifdef CONFIG_KVM_PPC_PVR
     sregs.pvr = cenv->spr[SPR_PVR];
-#endif
     return kvm_vcpu_ioctl(cenv, KVM_SET_SREGS, &sregs);
 }
 
commit 5802e066ebcca382dbb81df3417930ee23873252
Author: Jan Kiszka <jan.kiszka at siemens.com>
Date:   Wed Jun 8 16:10:58 2011 +0200

    kvm: Drop CONFIG_KVM_PARA
    
    The kvm_para.h header is now always available.
    
    Signed-off-by: Jan Kiszka <jan.kiszka at siemens.com>
    Signed-off-by: Marcelo Tosatti <mtosatti at redhat.com>

diff --git a/configure b/configure
index 8df6485..ebd5d56 100755
--- a/configure
+++ b/configure
@@ -3223,7 +3223,6 @@ case "$target_arch2" in
       \( "$target_arch2" = "x86_64" -a "$cpu" = "i386"   \) -o \
       \( "$target_arch2" = "i386"   -a "$cpu" = "x86_64" \) \) ; then
       echo "CONFIG_KVM=y" >> $config_target_mak
-      echo "CONFIG_KVM_PARA=y" >> $config_target_mak
       if test $vhost_net = "yes" ; then
         echo "CONFIG_VHOST_NET=y" >> $config_target_mak
       fi
diff --git a/hw/kvmclock.c b/hw/kvmclock.c
index 004c4ad..692ad18 100644
--- a/hw/kvmclock.c
+++ b/hw/kvmclock.c
@@ -17,8 +17,6 @@
 #include "kvm.h"
 #include "kvmclock.h"
 
-#if defined(CONFIG_KVM_PARA) && defined(KVM_CAP_ADJUST_CLOCK)
-
 #include <linux/kvm.h>
 #include <linux/kvm_para.h>
 
@@ -120,10 +118,3 @@ static void kvmclock_register_device(void)
 }
 
 device_init(kvmclock_register_device);
-
-#else /* !(CONFIG_KVM_PARA && KVM_CAP_ADJUST_CLOCK) */
-
-void kvmclock_create(void)
-{
-}
-#endif /* !(CONFIG_KVM_PARA && KVM_CAP_ADJUST_CLOCK) */
diff --git a/target-i386/kvm.c b/target-i386/kvm.c
index 16e8213..eb36e9f 100644
--- a/target-i386/kvm.c
+++ b/target-i386/kvm.c
@@ -18,6 +18,7 @@
 #include <sys/utsname.h>
 
 #include <linux/kvm.h>
+#include <linux/kvm_para.h>
 
 #include "qemu-common.h"
 #include "sysemu.h"
@@ -29,10 +30,6 @@
 #include "hw/apic.h"
 #include "ioport.h"
 
-#ifdef CONFIG_KVM_PARA
-#include <linux/kvm_para.h>
-#endif
-//
 //#define DEBUG_KVM
 
 #ifdef DEBUG_KVM
@@ -62,9 +59,7 @@ const KVMCapabilityInfo kvm_arch_required_capabilities[] = {
 
 static bool has_msr_star;
 static bool has_msr_hsave_pa;
-#if defined(CONFIG_KVM_PARA) && defined(KVM_CAP_ASYNC_PF)
 static bool has_msr_async_pf_en;
-#endif
 static int lm_capable_kernel;
 
 static struct kvm_cpuid2 *try_get_cpuid(KVMState *s, int max)
@@ -92,7 +87,6 @@ static struct kvm_cpuid2 *try_get_cpuid(KVMState *s, int max)
     return cpuid;
 }
 
-#ifdef CONFIG_KVM_PARA
 struct kvm_para_features {
     int cap;
     int feature;
@@ -118,7 +112,6 @@ static int get_para_features(CPUState *env)
 
     return features;
 }
-#endif
 
 
 uint32_t kvm_arch_get_supported_cpuid(CPUState *env, uint32_t function,
@@ -128,9 +121,7 @@ uint32_t kvm_arch_get_supported_cpuid(CPUState *env, uint32_t function,
     int i, max;
     uint32_t ret = 0;
     uint32_t cpuid_1_edx;
-#ifdef CONFIG_KVM_PARA
     int has_kvm_features = 0;
-#endif
 
     max = 1;
     while ((cpuid = try_get_cpuid(env->kvm_state, max)) == NULL) {
@@ -140,11 +131,9 @@ uint32_t kvm_arch_get_supported_cpuid(CPUState *env, uint32_t function,
     for (i = 0; i < cpuid->nent; ++i) {
         if (cpuid->entries[i].function == function &&
             cpuid->entries[i].index == index) {
-#ifdef CONFIG_KVM_PARA
             if (cpuid->entries[i].function == KVM_CPUID_FEATURES) {
                 has_kvm_features = 1;
             }
-#endif
             switch (reg) {
             case R_EAX:
                 ret = cpuid->entries[i].eax;
@@ -177,12 +166,10 @@ uint32_t kvm_arch_get_supported_cpuid(CPUState *env, uint32_t function,
 
     qemu_free(cpuid);
 
-#ifdef CONFIG_KVM_PARA
     /* fallback for older kernels */
     if (!has_kvm_features && (function == KVM_CPUID_FEATURES)) {
         ret = get_para_features(env);
     }
-#endif
 
     return ret;
 }
@@ -377,9 +364,7 @@ int kvm_arch_init_vcpu(CPUState *env)
     uint32_t limit, i, j, cpuid_i;
     uint32_t unused;
     struct kvm_cpuid_entry2 *c;
-#ifdef CONFIG_KVM_PARA
     uint32_t signature[3];
-#endif
 
     env->cpuid_features &= kvm_arch_get_supported_cpuid(env, 1, 0, R_EDX);
 
@@ -397,7 +382,6 @@ int kvm_arch_init_vcpu(CPUState *env)
 
     cpuid_i = 0;
 
-#ifdef CONFIG_KVM_PARA
     /* Paravirtualization CPUIDs */
     memcpy(signature, "KVMKVMKVM\0\0\0", 12);
     c = &cpuid_data.entries[cpuid_i++];
@@ -418,8 +402,6 @@ int kvm_arch_init_vcpu(CPUState *env)
     has_msr_async_pf_en = c->eax & (1 << KVM_FEATURE_ASYNC_PF);
 #endif
 
-#endif
-
     cpu_x86_cpuid(env, 0, 0, &limit, &unused, &unused, &unused);
 
     for (i = 0; i <= limit; i++) {
@@ -936,12 +918,10 @@ static int kvm_put_msrs(CPUState *env, int level)
         kvm_msr_entry_set(&msrs[n++], MSR_KVM_SYSTEM_TIME,
                           env->system_time_msr);
         kvm_msr_entry_set(&msrs[n++], MSR_KVM_WALL_CLOCK, env->wall_clock_msr);
-#if defined(CONFIG_KVM_PARA) && defined(KVM_CAP_ASYNC_PF)
         if (has_msr_async_pf_en) {
             kvm_msr_entry_set(&msrs[n++], MSR_KVM_ASYNC_PF_EN,
                               env->async_pf_en_msr);
         }
-#endif
     }
 #ifdef KVM_CAP_MCE
     if (env->mcg_cap) {
@@ -1182,11 +1162,9 @@ static int kvm_get_msrs(CPUState *env)
 #endif
     msrs[n++].index = MSR_KVM_SYSTEM_TIME;
     msrs[n++].index = MSR_KVM_WALL_CLOCK;
-#if defined(CONFIG_KVM_PARA) && defined(KVM_CAP_ASYNC_PF)
     if (has_msr_async_pf_en) {
         msrs[n++].index = MSR_KVM_ASYNC_PF_EN;
     }
-#endif
 
 #ifdef KVM_CAP_MCE
     if (env->mcg_cap) {
@@ -1263,11 +1241,9 @@ static int kvm_get_msrs(CPUState *env)
             }
 #endif
             break;
-#if defined(CONFIG_KVM_PARA) && defined(KVM_CAP_ASYNC_PF)
         case MSR_KVM_ASYNC_PF_EN:
             env->async_pf_en_msr = msrs[i].data;
             break;
-#endif
         }
     }
 
commit e205c7902f01664f4ad6dccc32ba1472e6d32d34
Author: Jan Kiszka <jan.kiszka at siemens.com>
Date:   Wed Jun 8 16:10:57 2011 +0200

    Switch build system to accompanied kernel headers
    
    This helps reducing our build-time checks for feature support in the
    available Linux kernel headers. And it helps users that do not have
    sufficiently recent headers installed on their build machine.
    
    Consequently, the patch removes and build-time checks for kvm and vhost
    in configure, the --kerneldir switch, and KVM_CFLAGS. Kernel headers are
    supposed to be provided by QEMU only.
    
    s390 needs some extra love as it carries redefinitions from kernel
    headers.
    
    CC: Alexander Graf <agraf at suse.de>
    Signed-off-by: Jan Kiszka <jan.kiszka at siemens.com>
    Signed-off-by: Marcelo Tosatti <mtosatti at redhat.com>

diff --git a/Makefile.target b/Makefile.target
index b1a0f6d..db2fa6e 100644
--- a/Makefile.target
+++ b/Makefile.target
@@ -14,7 +14,7 @@ endif
 
 TARGET_PATH=$(SRC_PATH)/target-$(TARGET_BASE_ARCH)
 $(call set-vpath, $(SRC_PATH):$(TARGET_PATH):$(SRC_PATH)/hw)
-QEMU_CFLAGS+= -I.. -I$(TARGET_PATH) -DNEED_CPU_H
+QEMU_CFLAGS+= -I.. -I../linux-headers -I$(TARGET_PATH) -DNEED_CPU_H
 
 include $(SRC_PATH)/Makefile.objs
 
@@ -37,8 +37,6 @@ ifndef CONFIG_HAIKU
 LIBS+=-lm
 endif
 
-kvm.o kvm-all.o vhost.o vhost_net.o kvmclock.o: QEMU_CFLAGS+=$(KVM_CFLAGS)
-
 config-target.h: config-target.h-timestamp
 config-target.h-timestamp: config-target.mak
 
diff --git a/configure b/configure
index 44c092a..8df6485 100755
--- a/configure
+++ b/configure
@@ -113,8 +113,7 @@ curl=""
 curses=""
 docs=""
 fdt=""
-kvm=""
-kvm_para=""
+kvm="yes"
 nptl=""
 sdl=""
 vnc="yes"
@@ -130,7 +129,7 @@ xen=""
 xen_ctrl_version=""
 linux_aio=""
 attr=""
-vhost_net=""
+vhost_net="yes"
 xfs=""
 
 gprof="no"
@@ -166,7 +165,6 @@ guest_base=""
 uname_release=""
 io_thread="no"
 mixemu="no"
-kerneldir=""
 aix="no"
 blobs="yes"
 pkgversion=""
@@ -715,8 +713,6 @@ for opt do
   ;;
   --disable-blobs) blobs="no"
   ;;
-  --kerneldir=*) kerneldir="$optarg"
-  ;;
   --with-pkgversion=*) pkgversion=" ($optarg)"
   ;;
   --disable-docs) docs="no"
@@ -1005,7 +1001,6 @@ echo "  --disable-attr           disables attr and xattr support"
 echo "  --enable-attr            enable attr and xattr support"
 echo "  --enable-io-thread       enable IO thread"
 echo "  --disable-blobs          disable installing provided firmware blobs"
-echo "  --kerneldir=PATH         look for kernel includes in PATH"
 echo "  --enable-docs            enable documentation build"
 echo "  --disable-docs           disable documentation build"
 echo "  --disable-vhost-net      disable vhost-net acceleration support"
@@ -1779,124 +1774,6 @@ EOF
 fi
 
 ##########################################
-# kvm probe
-if test "$kvm" != "no" ; then
-    cat > $TMPC <<EOF
-#include <linux/kvm.h>
-#if !defined(KVM_API_VERSION) || KVM_API_VERSION < 12 || KVM_API_VERSION > 12
-#error Invalid KVM version
-#endif
-EOF
-    must_have_caps="KVM_CAP_USER_MEMORY \
-                    KVM_CAP_DESTROY_MEMORY_REGION_WORKS \
-                    KVM_CAP_COALESCED_MMIO \
-                    KVM_CAP_SYNC_MMU \
-                   "
-    if test \( "$cpu" = "i386" -o "$cpu" = "x86_64" \) ; then
-      must_have_caps="$caps \
-                      KVM_CAP_SET_TSS_ADDR \
-                      KVM_CAP_EXT_CPUID \
-                      KVM_CAP_CLOCKSOURCE \
-                      KVM_CAP_NOP_IO_DELAY \
-                      KVM_CAP_PV_MMU \
-                      KVM_CAP_MP_STATE \
-                      KVM_CAP_USER_NMI \
-                     "
-    fi
-    for c in $must_have_caps ; do
-      cat >> $TMPC <<EOF
-#if !defined($c)
-#error Missing KVM capability $c
-#endif
-EOF
-    done
-    cat >> $TMPC <<EOF
-int main(void) { return 0; }
-EOF
-  if test "$kerneldir" != "" ; then
-      kvm_cflags=-I"$kerneldir"/include
-      if test \( "$cpu" = "i386" -o "$cpu" = "x86_64" \) \
-         -a -d "$kerneldir/arch/x86/include" ; then
-            kvm_cflags="$kvm_cflags -I$kerneldir/arch/x86/include"
-	elif test "$cpu" = "ppc" -a -d "$kerneldir/arch/powerpc/include" ; then
-	    kvm_cflags="$kvm_cflags -I$kerneldir/arch/powerpc/include"
-	elif test "$cpu" = "s390x" -a -d "$kerneldir/arch/s390/include" ; then
-	    kvm_cflags="$kvm_cflags -I$kerneldir/arch/s390/include"
-        elif test -d "$kerneldir/arch/$cpu/include" ; then
-            kvm_cflags="$kvm_cflags -I$kerneldir/arch/$cpu/include"
-      fi
-  else
-    kvm_cflags=`$pkg_config --cflags kvm-kmod 2>/dev/null`
-  fi
-  if compile_prog "$kvm_cflags" "" ; then
-    kvm=yes
-    cat > $TMPC <<EOF
-#include <linux/kvm_para.h>
-int main(void) { return 0; }
-EOF
-    if compile_prog "$kvm_cflags" "" ; then
-      kvm_para=yes
-    fi
-  else
-    if test "$kvm" = "yes" ; then
-      if has awk && has grep; then
-        kvmerr=`LANG=C $cc $QEMU_CFLAGS -o $TMPE $kvm_cflags $TMPC 2>&1 \
-	| grep "error: " \
-	| awk -F "error: " '{if (NR>1) printf(", "); printf("%s",$2);}'`
-        if test "$kvmerr" != "" ; then
-          echo -e "${kvmerr}\n\
-NOTE: To enable KVM support, update your kernel to 2.6.29+ or install \
-recent kvm-kmod from http://sourceforge.net/projects/kvm."
-        fi
-      fi
-      feature_not_found "kvm"
-    fi
-    kvm=no
-  fi
-fi
-
-##########################################
-# test for ppc kvm pvr setting
-
-if test "$kvm" = "yes" && test "$cpu" = "ppc" -o "$cpu" = "ppc64"; then
-            cat > $TMPC <<EOF
-    #include <asm/kvm.h>
-    int main(void) { struct kvm_sregs s; s.pvr = 0; return 0; }
-EOF
-    if compile_prog "$kvm_cflags" "" ; then
-        kvm_ppc_pvr=yes
-    else
-        kvm_ppc_pvr=no
-    fi
-fi
-
-##########################################
-# test for vhost net
-
-if test "$vhost_net" != "no"; then
-    if test "$kvm" != "no"; then
-            cat > $TMPC <<EOF
-    #include <linux/vhost.h>
-    int main(void) { return 0; }
-EOF
-            if compile_prog "$kvm_cflags" "" ; then
-                vhost_net=yes
-            else
-                if test "$vhost_net" = "yes" ; then
-                    feature_not_found "vhost-net"
-                fi
-                vhost_net=no
-            fi
-    else
-            if test "$vhost_net" = "yes" ; then
-                echo "NOTE: vhost-net feature requires KVM (--enable-kvm)."
-                feature_not_found "vhost-net"
-            fi
-            vhost_net=no
-    fi
-fi
-
-##########################################
 # pthread probe
 PTHREADLIBS_LIST="-lpthread -lpthreadGC2"
 
@@ -3346,16 +3223,11 @@ case "$target_arch2" in
       \( "$target_arch2" = "x86_64" -a "$cpu" = "i386"   \) -o \
       \( "$target_arch2" = "i386"   -a "$cpu" = "x86_64" \) \) ; then
       echo "CONFIG_KVM=y" >> $config_target_mak
-      echo "KVM_CFLAGS=$kvm_cflags" >> $config_target_mak
-      if test "$kvm_para" = "yes"; then
-        echo "CONFIG_KVM_PARA=y" >> $config_target_mak
-      fi
+      echo "CONFIG_KVM_PARA=y" >> $config_target_mak
       if test $vhost_net = "yes" ; then
         echo "CONFIG_VHOST_NET=y" >> $config_target_mak
       fi
-      if test "$kvm_ppc_pvr" = "yes" ; then
-        echo "CONFIG_KVM_PPC_PVR=y" >> $config_target_mak
-      fi
+      echo "CONFIG_KVM_PPC_PVR=y" >> $config_target_mak
     fi
 esac
 if test "$target_bigendian" = "yes" ; then
@@ -3546,6 +3418,21 @@ if test "$target_linux_user" = "yes" -o "$target_bsd_user" = "yes" ; then
   esac
 fi
 
+# use included Linux headers
+includes="-I\$(SRC_PATH)/linux-headers $includes"
+mkdir -p linux-headers
+case "$cpu" in
+i386|x86_64)
+  symlink $source_path/linux-headers/asm-x86 linux-headers/asm
+  ;;
+ppcemb|ppc|ppc64)
+  symlink $source_path/linux-headers/asm-x86 linux-headers/asm
+  ;;
+s390x)
+  symlink $source_path/linux-headers/asm-s390 linux-headers/asm
+  ;;
+esac
+
 echo "LDFLAGS+=$ldflags" >> $config_target_mak
 echo "QEMU_CFLAGS+=$cflags" >> $config_target_mak
 echo "QEMU_INCLUDES+=$includes" >> $config_target_mak
diff --git a/target-s390x/cpu.h b/target-s390x/cpu.h
index 4e5c391..b5e587f 100644
--- a/target-s390x/cpu.h
+++ b/target-s390x/cpu.h
@@ -313,16 +313,6 @@ CPUState *s390_cpu_addr2state(uint16_t cpu_addr);
 /* from s390-virtio-bus */
 extern const target_phys_addr_t virtio_size;
 
-#ifndef KVM_S390_SIGP_STOP
-#define KVM_S390_SIGP_STOP              0
-#define KVM_S390_PROGRAM_INT            0
-#define KVM_S390_SIGP_SET_PREFIX        0
-#define KVM_S390_RESTART                0
-#define KVM_S390_INT_VIRTIO             0
-#define KVM_S390_INT_SERVICE            0
-#define KVM_S390_INT_EMERGENCY          0
-#endif
-
 #endif
 void cpu_lock(void);
 void cpu_unlock(void);
diff --git a/target-s390x/op_helper.c b/target-s390x/op_helper.c
index db03a79..9429698 100644
--- a/target-s390x/op_helper.c
+++ b/target-s390x/op_helper.c
@@ -23,6 +23,7 @@
 #include "helpers.h"
 #include <string.h>
 #include "kvm.h"
+#include <linux/kvm.h>
 #include "qemu-timer.h"
 
 /*****************************************************************************/
commit 51b24e34d4f56e51b8541f54b8c01d935dbe9eca
Author: Jan Kiszka <jan.kiszka at siemens.com>
Date:   Wed Jun 8 16:10:56 2011 +0200

    Import kernel headers
    
    These kernel headers and the COPYING file were automatically imported
    from current Linux git, cb0a02ecf9 (post 3.0-rc2).
    
    Licensing:
    asm-powerpc	GPLv2
    asm-s390	GPLv2
    asm-x86		Linux top-level license (GPLv2 with exception)
    linux/kvm*:	Linux top-level license (GPLv2 with exception)
    linux/vhost:	Linux top-level license (GPLv2 with exception)
    linux/virtio*:	3-clause BSB
    
    CC: Alexander Graf <agraf at suse.de>
    Signed-off-by: Jan Kiszka <jan.kiszka at siemens.com>
    Signed-off-by: Marcelo Tosatti <mtosatti at redhat.com>

diff --git a/linux-headers/COPYING b/linux-headers/COPYING
new file mode 100644
index 0000000..ca442d3
--- /dev/null
+++ b/linux-headers/COPYING
@@ -0,0 +1,356 @@
+
+   NOTE! This copyright does *not* cover user programs that use kernel
+ services by normal system calls - this is merely considered normal use
+ of the kernel, and does *not* fall under the heading of "derived work".
+ Also note that the GPL below is copyrighted by the Free Software
+ Foundation, but the instance of code that it refers to (the Linux
+ kernel) is copyrighted by me and others who actually wrote it.
+
+ Also note that the only valid version of the GPL as far as the kernel
+ is concerned is _this_ particular version of the license (ie v2, not
+ v2.2 or v3.x or whatever), unless explicitly otherwise stated.
+
+			Linus Torvalds
+
+----------------------------------------
+
+		    GNU GENERAL PUBLIC LICENSE
+		       Version 2, June 1991
+
+ Copyright (C) 1989, 1991 Free Software Foundation, Inc.
+                       51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
+ Everyone is permitted to copy and distribute verbatim copies
+ of this license document, but changing it is not allowed.
+
+			    Preamble
+
+  The licenses for most software are designed to take away your
+freedom to share and change it.  By contrast, the GNU General Public
+License is intended to guarantee your freedom to share and change free
+software--to make sure the software is free for all its users.  This
+General Public License applies to most of the Free Software
+Foundation's software and to any other program whose authors commit to
+using it.  (Some other Free Software Foundation software is covered by
+the GNU Library General Public License instead.)  You can apply it to
+your programs, too.
+
+  When we speak of free software, we are referring to freedom, not
+price.  Our General Public Licenses are designed to make sure that you
+have the freedom to distribute copies of free software (and charge for
+this service if you wish), that you receive source code or can get it
+if you want it, that you can change the software or use pieces of it
+in new free programs; and that you know you can do these things.
+
+  To protect your rights, we need to make restrictions that forbid
+anyone to deny you these rights or to ask you to surrender the rights.
+These restrictions translate to certain responsibilities for you if you
+distribute copies of the software, or if you modify it.
+
+  For example, if you distribute copies of such a program, whether
+gratis or for a fee, you must give the recipients all the rights that
+you have.  You must make sure that they, too, receive or can get the
+source code.  And you must show them these terms so they know their
+rights.
+
+  We protect your rights with two steps: (1) copyright the software, and
+(2) offer you this license which gives you legal permission to copy,
+distribute and/or modify the software.
+
+  Also, for each author's protection and ours, we want to make certain
+that everyone understands that there is no warranty for this free
+software.  If the software is modified by someone else and passed on, we
+want its recipients to know that what they have is not the original, so
+that any problems introduced by others will not reflect on the original
+authors' reputations.
+
+  Finally, any free program is threatened constantly by software
+patents.  We wish to avoid the danger that redistributors of a free
+program will individually obtain patent licenses, in effect making the
+program proprietary.  To prevent this, we have made it clear that any
+patent must be licensed for everyone's free use or not licensed at all.
+
+  The precise terms and conditions for copying, distribution and
+modification follow.
+
+		    GNU GENERAL PUBLIC LICENSE
+   TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
+
+  0. This License applies to any program or other work which contains
+a notice placed by the copyright holder saying it may be distributed
+under the terms of this General Public License.  The "Program", below,
+refers to any such program or work, and a "work based on the Program"
+means either the Program or any derivative work under copyright law:
+that is to say, a work containing the Program or a portion of it,
+either verbatim or with modifications and/or translated into another
+language.  (Hereinafter, translation is included without limitation in
+the term "modification".)  Each licensee is addressed as "you".
+
+Activities other than copying, distribution and modification are not
+covered by this License; they are outside its scope.  The act of
+running the Program is not restricted, and the output from the Program
+is covered only if its contents constitute a work based on the
+Program (independent of having been made by running the Program).
+Whether that is true depends on what the Program does.
+
+  1. You may copy and distribute verbatim copies of the Program's
+source code as you receive it, in any medium, provided that you
+conspicuously and appropriately publish on each copy an appropriate
+copyright notice and disclaimer of warranty; keep intact all the
+notices that refer to this License and to the absence of any warranty;
+and give any other recipients of the Program a copy of this License
+along with the Program.
+
+You may charge a fee for the physical act of transferring a copy, and
+you may at your option offer warranty protection in exchange for a fee.
+
+  2. You may modify your copy or copies of the Program or any portion
+of it, thus forming a work based on the Program, and copy and
+distribute such modifications or work under the terms of Section 1
+above, provided that you also meet all of these conditions:
+
+    a) You must cause the modified files to carry prominent notices
+    stating that you changed the files and the date of any change.
+
+    b) You must cause any work that you distribute or publish, that in
+    whole or in part contains or is derived from the Program or any
+    part thereof, to be licensed as a whole at no charge to all third
+    parties under the terms of this License.
+
+    c) If the modified program normally reads commands interactively
+    when run, you must cause it, when started running for such
+    interactive use in the most ordinary way, to print or display an
+    announcement including an appropriate copyright notice and a
+    notice that there is no warranty (or else, saying that you provide
+    a warranty) and that users may redistribute the program under
+    these conditions, and telling the user how to view a copy of this
+    License.  (Exception: if the Program itself is interactive but
+    does not normally print such an announcement, your work based on
+    the Program is not required to print an announcement.)
+
+These requirements apply to the modified work as a whole.  If
+identifiable sections of that work are not derived from the Program,
+and can be reasonably considered independent and separate works in
+themselves, then this License, and its terms, do not apply to those
+sections when you distribute them as separate works.  But when you
+distribute the same sections as part of a whole which is a work based
+on the Program, the distribution of the whole must be on the terms of
+this License, whose permissions for other licensees extend to the
+entire whole, and thus to each and every part regardless of who wrote it.
+
+Thus, it is not the intent of this section to claim rights or contest
+your rights to work written entirely by you; rather, the intent is to
+exercise the right to control the distribution of derivative or
+collective works based on the Program.
+
+In addition, mere aggregation of another work not based on the Program
+with the Program (or with a work based on the Program) on a volume of
+a storage or distribution medium does not bring the other work under
+the scope of this License.
+
+  3. You may copy and distribute the Program (or a work based on it,
+under Section 2) in object code or executable form under the terms of
+Sections 1 and 2 above provided that you also do one of the following:
+
+    a) Accompany it with the complete corresponding machine-readable
+    source code, which must be distributed under the terms of Sections
+    1 and 2 above on a medium customarily used for software interchange; or,
+
+    b) Accompany it with a written offer, valid for at least three
+    years, to give any third party, for a charge no more than your
+    cost of physically performing source distribution, a complete
+    machine-readable copy of the corresponding source code, to be
+    distributed under the terms of Sections 1 and 2 above on a medium
+    customarily used for software interchange; or,
+
+    c) Accompany it with the information you received as to the offer
+    to distribute corresponding source code.  (This alternative is
+    allowed only for noncommercial distribution and only if you
+    received the program in object code or executable form with such
+    an offer, in accord with Subsection b above.)
+
+The source code for a work means the preferred form of the work for
+making modifications to it.  For an executable work, complete source
+code means all the source code for all modules it contains, plus any
+associated interface definition files, plus the scripts used to
+control compilation and installation of the executable.  However, as a
+special exception, the source code distributed need not include
+anything that is normally distributed (in either source or binary
+form) with the major components (compiler, kernel, and so on) of the
+operating system on which the executable runs, unless that component
+itself accompanies the executable.
+
+If distribution of executable or object code is made by offering
+access to copy from a designated place, then offering equivalent
+access to copy the source code from the same place counts as
+distribution of the source code, even though third parties are not
+compelled to copy the source along with the object code.
+
+  4. You may not copy, modify, sublicense, or distribute the Program
+except as expressly provided under this License.  Any attempt
+otherwise to copy, modify, sublicense or distribute the Program is
+void, and will automatically terminate your rights under this License.
+However, parties who have received copies, or rights, from you under
+this License will not have their licenses terminated so long as such
+parties remain in full compliance.
+
+  5. You are not required to accept this License, since you have not
+signed it.  However, nothing else grants you permission to modify or
+distribute the Program or its derivative works.  These actions are
+prohibited by law if you do not accept this License.  Therefore, by
+modifying or distributing the Program (or any work based on the
+Program), you indicate your acceptance of this License to do so, and
+all its terms and conditions for copying, distributing or modifying
+the Program or works based on it.
+
+  6. Each time you redistribute the Program (or any work based on the
+Program), the recipient automatically receives a license from the
+original licensor to copy, distribute or modify the Program subject to
+these terms and conditions.  You may not impose any further
+restrictions on the recipients' exercise of the rights granted herein.
+You are not responsible for enforcing compliance by third parties to
+this License.
+
+  7. If, as a consequence of a court judgment or allegation of patent
+infringement or for any other reason (not limited to patent issues),
+conditions are imposed on you (whether by court order, agreement or
+otherwise) that contradict the conditions of this License, they do not
+excuse you from the conditions of this License.  If you cannot
+distribute so as to satisfy simultaneously your obligations under this
+License and any other pertinent obligations, then as a consequence you
+may not distribute the Program at all.  For example, if a patent
+license would not permit royalty-free redistribution of the Program by
+all those who receive copies directly or indirectly through you, then
+the only way you could satisfy both it and this License would be to
+refrain entirely from distribution of the Program.
+
+If any portion of this section is held invalid or unenforceable under
+any particular circumstance, the balance of the section is intended to
+apply and the section as a whole is intended to apply in other
+circumstances.
+
+It is not the purpose of this section to induce you to infringe any
+patents or other property right claims or to contest validity of any
+such claims; this section has the sole purpose of protecting the
+integrity of the free software distribution system, which is
+implemented by public license practices.  Many people have made
+generous contributions to the wide range of software distributed
+through that system in reliance on consistent application of that
+system; it is up to the author/donor to decide if he or she is willing
+to distribute software through any other system and a licensee cannot
+impose that choice.
+
+This section is intended to make thoroughly clear what is believed to
+be a consequence of the rest of this License.
+
+  8. If the distribution and/or use of the Program is restricted in
+certain countries either by patents or by copyrighted interfaces, the
+original copyright holder who places the Program under this License
+may add an explicit geographical distribution limitation excluding
+those countries, so that distribution is permitted only in or among
+countries not thus excluded.  In such case, this License incorporates
+the limitation as if written in the body of this License.
+
+  9. The Free Software Foundation may publish revised and/or new versions
+of the General Public License from time to time.  Such new versions will
+be similar in spirit to the present version, but may differ in detail to
+address new problems or concerns.
+
+Each version is given a distinguishing version number.  If the Program
+specifies a version number of this License which applies to it and "any
+later version", you have the option of following the terms and conditions
+either of that version or of any later version published by the Free
+Software Foundation.  If the Program does not specify a version number of
+this License, you may choose any version ever published by the Free Software
+Foundation.
+
+  10. If you wish to incorporate parts of the Program into other free
+programs whose distribution conditions are different, write to the author
+to ask for permission.  For software which is copyrighted by the Free
+Software Foundation, write to the Free Software Foundation; we sometimes
+make exceptions for this.  Our decision will be guided by the two goals
+of preserving the free status of all derivatives of our free software and
+of promoting the sharing and reuse of software generally.
+
+			    NO WARRANTY
+
+  11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
+FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW.  EXCEPT WHEN
+OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES
+PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED
+OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.  THE ENTIRE RISK AS
+TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU.  SHOULD THE
+PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING,
+REPAIR OR CORRECTION.
+
+  12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
+WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR
+REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES,
+INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING
+OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED
+TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY
+YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER
+PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE
+POSSIBILITY OF SUCH DAMAGES.
+
+		     END OF TERMS AND CONDITIONS
+
+	    How to Apply These Terms to Your New Programs
+
+  If you develop a new program, and you want it to be of the greatest
+possible use to the public, the best way to achieve this is to make it
+free software which everyone can redistribute and change under these terms.
+
+  To do so, attach the following notices to the program.  It is safest
+to attach them to the start of each source file to most effectively
+convey the exclusion of warranty; and each file should have at least
+the "copyright" line and a pointer to where the full notice is found.
+
+    <one line to give the program's name and a brief idea of what it does.>
+    Copyright (C) <year>  <name of author>
+
+    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, write to the Free Software
+    Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
+
+
+Also add information on how to contact you by electronic and paper mail.
+
+If the program is interactive, make it output a short notice like this
+when it starts in an interactive mode:
+
+    Gnomovision version 69, Copyright (C) year name of author
+    Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
+    This is free software, and you are welcome to redistribute it
+    under certain conditions; type `show c' for details.
+
+The hypothetical commands `show w' and `show c' should show the appropriate
+parts of the General Public License.  Of course, the commands you use may
+be called something other than `show w' and `show c'; they could even be
+mouse-clicks or menu items--whatever suits your program.
+
+You should also get your employer (if you work as a programmer) or your
+school, if any, to sign a "copyright disclaimer" for the program, if
+necessary.  Here is a sample; alter the names:
+
+  Yoyodyne, Inc., hereby disclaims all copyright interest in the program
+  `Gnomovision' (which makes passes at compilers) written by James Hacker.
+
+  <signature of Ty Coon>, 1 April 1989
+  Ty Coon, President of Vice
+
+This General Public License does not permit incorporating your program into
+proprietary programs.  If your program is a subroutine library, you may
+consider it more useful to permit linking proprietary applications with the
+library.  If this is what you want to do, use the GNU Library General
+Public License instead of this License.
diff --git a/linux-headers/asm-powerpc/kvm.h b/linux-headers/asm-powerpc/kvm.h
new file mode 100644
index 0000000..777d307
--- /dev/null
+++ b/linux-headers/asm-powerpc/kvm.h
@@ -0,0 +1,275 @@
+/*
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License, version 2, as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+ *
+ * Copyright IBM Corp. 2007
+ *
+ * Authors: Hollis Blanchard <hollisb at us.ibm.com>
+ */
+
+#ifndef __LINUX_KVM_POWERPC_H
+#define __LINUX_KVM_POWERPC_H
+
+#include <linux/types.h>
+
+struct kvm_regs {
+	__u64 pc;
+	__u64 cr;
+	__u64 ctr;
+	__u64 lr;
+	__u64 xer;
+	__u64 msr;
+	__u64 srr0;
+	__u64 srr1;
+	__u64 pid;
+
+	__u64 sprg0;
+	__u64 sprg1;
+	__u64 sprg2;
+	__u64 sprg3;
+	__u64 sprg4;
+	__u64 sprg5;
+	__u64 sprg6;
+	__u64 sprg7;
+
+	__u64 gpr[32];
+};
+
+#define KVM_SREGS_E_IMPL_NONE	0
+#define KVM_SREGS_E_IMPL_FSL	1
+
+#define KVM_SREGS_E_FSL_PIDn	(1 << 0) /* PID1/PID2 */
+
+/*
+ * Feature bits indicate which sections of the sregs struct are valid,
+ * both in KVM_GET_SREGS and KVM_SET_SREGS.  On KVM_SET_SREGS, registers
+ * corresponding to unset feature bits will not be modified.  This allows
+ * restoring a checkpoint made without that feature, while keeping the
+ * default values of the new registers.
+ *
+ * KVM_SREGS_E_BASE contains:
+ * CSRR0/1 (refers to SRR2/3 on 40x)
+ * ESR
+ * DEAR
+ * MCSR
+ * TSR
+ * TCR
+ * DEC
+ * TB
+ * VRSAVE (USPRG0)
+ */
+#define KVM_SREGS_E_BASE		(1 << 0)
+
+/*
+ * KVM_SREGS_E_ARCH206 contains:
+ *
+ * PIR
+ * MCSRR0/1
+ * DECAR
+ * IVPR
+ */
+#define KVM_SREGS_E_ARCH206		(1 << 1)
+
+/*
+ * Contains EPCR, plus the upper half of 64-bit registers
+ * that are 32-bit on 32-bit implementations.
+ */
+#define KVM_SREGS_E_64			(1 << 2)
+
+#define KVM_SREGS_E_SPRG8		(1 << 3)
+#define KVM_SREGS_E_MCIVPR		(1 << 4)
+
+/*
+ * IVORs are used -- contains IVOR0-15, plus additional IVORs
+ * in combination with an appropriate feature bit.
+ */
+#define KVM_SREGS_E_IVOR		(1 << 5)
+
+/*
+ * Contains MAS0-4, MAS6-7, TLBnCFG, MMUCFG.
+ * Also TLBnPS if MMUCFG[MAVN] = 1.
+ */
+#define KVM_SREGS_E_ARCH206_MMU		(1 << 6)
+
+/* DBSR, DBCR, IAC, DAC, DVC */
+#define KVM_SREGS_E_DEBUG		(1 << 7)
+
+/* Enhanced debug -- DSRR0/1, SPRG9 */
+#define KVM_SREGS_E_ED			(1 << 8)
+
+/* Embedded Floating Point (SPE) -- IVOR32-34 if KVM_SREGS_E_IVOR */
+#define KVM_SREGS_E_SPE			(1 << 9)
+
+/* External Proxy (EXP) -- EPR */
+#define KVM_SREGS_EXP			(1 << 10)
+
+/* External PID (E.PD) -- EPSC/EPLC */
+#define KVM_SREGS_E_PD			(1 << 11)
+
+/* Processor Control (E.PC) -- IVOR36-37 if KVM_SREGS_E_IVOR */
+#define KVM_SREGS_E_PC			(1 << 12)
+
+/* Page table (E.PT) -- EPTCFG */
+#define KVM_SREGS_E_PT			(1 << 13)
+
+/* Embedded Performance Monitor (E.PM) -- IVOR35 if KVM_SREGS_E_IVOR */
+#define KVM_SREGS_E_PM			(1 << 14)
+
+/*
+ * Special updates:
+ *
+ * Some registers may change even while a vcpu is not running.
+ * To avoid losing these changes, by default these registers are
+ * not updated by KVM_SET_SREGS.  To force an update, set the bit
+ * in u.e.update_special corresponding to the register to be updated.
+ *
+ * The update_special field is zero on return from KVM_GET_SREGS.
+ *
+ * When restoring a checkpoint, the caller can set update_special
+ * to 0xffffffff to ensure that everything is restored, even new features
+ * that the caller doesn't know about.
+ */
+#define KVM_SREGS_E_UPDATE_MCSR		(1 << 0)
+#define KVM_SREGS_E_UPDATE_TSR		(1 << 1)
+#define KVM_SREGS_E_UPDATE_DEC		(1 << 2)
+#define KVM_SREGS_E_UPDATE_DBSR		(1 << 3)
+
+/*
+ * In KVM_SET_SREGS, reserved/pad fields must be left untouched from a
+ * previous KVM_GET_REGS.
+ *
+ * Unless otherwise indicated, setting any register with KVM_SET_SREGS
+ * directly sets its value.  It does not trigger any special semantics such
+ * as write-one-to-clear.  Calling KVM_SET_SREGS on an unmodified struct
+ * just received from KVM_GET_SREGS is always a no-op.
+ */
+struct kvm_sregs {
+	__u32 pvr;
+	union {
+		struct {
+			__u64 sdr1;
+			struct {
+				struct {
+					__u64 slbe;
+					__u64 slbv;
+				} slb[64];
+			} ppc64;
+			struct {
+				__u32 sr[16];
+				__u64 ibat[8];
+				__u64 dbat[8];
+			} ppc32;
+		} s;
+		struct {
+			union {
+				struct { /* KVM_SREGS_E_IMPL_FSL */
+					__u32 features; /* KVM_SREGS_E_FSL_ */
+					__u32 svr;
+					__u64 mcar;
+					__u32 hid0;
+
+					/* KVM_SREGS_E_FSL_PIDn */
+					__u32 pid1, pid2;
+				} fsl;
+				__u8 pad[256];
+			} impl;
+
+			__u32 features; /* KVM_SREGS_E_ */
+			__u32 impl_id;	/* KVM_SREGS_E_IMPL_ */
+			__u32 update_special; /* KVM_SREGS_E_UPDATE_ */
+			__u32 pir;	/* read-only */
+			__u64 sprg8;
+			__u64 sprg9;	/* E.ED */
+			__u64 csrr0;
+			__u64 dsrr0;	/* E.ED */
+			__u64 mcsrr0;
+			__u32 csrr1;
+			__u32 dsrr1;	/* E.ED */
+			__u32 mcsrr1;
+			__u32 esr;
+			__u64 dear;
+			__u64 ivpr;
+			__u64 mcivpr;
+			__u64 mcsr;	/* KVM_SREGS_E_UPDATE_MCSR */
+
+			__u32 tsr;	/* KVM_SREGS_E_UPDATE_TSR */
+			__u32 tcr;
+			__u32 decar;
+			__u32 dec;	/* KVM_SREGS_E_UPDATE_DEC */
+
+			/*
+			 * Userspace can read TB directly, but the
+			 * value reported here is consistent with "dec".
+			 *
+			 * Read-only.
+			 */
+			__u64 tb;
+
+			__u32 dbsr;	/* KVM_SREGS_E_UPDATE_DBSR */
+			__u32 dbcr[3];
+			__u32 iac[4];
+			__u32 dac[2];
+			__u32 dvc[2];
+			__u8 num_iac;	/* read-only */
+			__u8 num_dac;	/* read-only */
+			__u8 num_dvc;	/* read-only */
+			__u8 pad;
+
+			__u32 epr;	/* EXP */
+			__u32 vrsave;	/* a.k.a. USPRG0 */
+			__u32 epcr;	/* KVM_SREGS_E_64 */
+
+			__u32 mas0;
+			__u32 mas1;
+			__u64 mas2;
+			__u64 mas7_3;
+			__u32 mas4;
+			__u32 mas6;
+
+			__u32 ivor_low[16]; /* IVOR0-15 */
+			__u32 ivor_high[18]; /* IVOR32+, plus room to expand */
+
+			__u32 mmucfg;	/* read-only */
+			__u32 eptcfg;	/* E.PT, read-only */
+			__u32 tlbcfg[4];/* read-only */
+			__u32 tlbps[4]; /* read-only */
+
+			__u32 eplc, epsc; /* E.PD */
+		} e;
+		__u8 pad[1020];
+	} u;
+};
+
+struct kvm_fpu {
+	__u64 fpr[32];
+};
+
+struct kvm_debug_exit_arch {
+};
+
+/* for KVM_SET_GUEST_DEBUG */
+struct kvm_guest_debug_arch {
+};
+
+#define KVM_REG_MASK		0x001f
+#define KVM_REG_EXT_MASK	0xffe0
+#define KVM_REG_GPR		0x0000
+#define KVM_REG_FPR		0x0020
+#define KVM_REG_QPR		0x0040
+#define KVM_REG_FQPR		0x0060
+
+#define KVM_INTERRUPT_SET	-1U
+#define KVM_INTERRUPT_UNSET	-2U
+#define KVM_INTERRUPT_SET_LEVEL	-3U
+
+#endif /* __LINUX_KVM_POWERPC_H */
diff --git a/linux-headers/asm-powerpc/kvm_para.h b/linux-headers/asm-powerpc/kvm_para.h
new file mode 100644
index 0000000..ad58c90
--- /dev/null
+++ b/linux-headers/asm-powerpc/kvm_para.h
@@ -0,0 +1,53 @@
+/*
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License, version 2, as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+ *
+ * Copyright IBM Corp. 2008
+ *
+ * Authors: Hollis Blanchard <hollisb at us.ibm.com>
+ */
+
+#ifndef __POWERPC_KVM_PARA_H__
+#define __POWERPC_KVM_PARA_H__
+
+#include <linux/types.h>
+
+struct kvm_vcpu_arch_shared {
+	__u64 scratch1;
+	__u64 scratch2;
+	__u64 scratch3;
+	__u64 critical;		/* Guest may not get interrupts if == r1 */
+	__u64 sprg0;
+	__u64 sprg1;
+	__u64 sprg2;
+	__u64 sprg3;
+	__u64 srr0;
+	__u64 srr1;
+	__u64 dar;
+	__u64 msr;
+	__u32 dsisr;
+	__u32 int_pending;	/* Tells the guest if we have an interrupt */
+	__u32 sr[16];
+};
+
+#define KVM_SC_MAGIC_R0		0x4b564d21 /* "KVM!" */
+#define HC_VENDOR_KVM		(42 << 16)
+#define HC_EV_SUCCESS		0
+#define HC_EV_UNIMPLEMENTED	12
+
+#define KVM_FEATURE_MAGIC_PAGE	1
+
+#define KVM_MAGIC_FEAT_SR	(1 << 0)
+
+
+#endif /* __POWERPC_KVM_PARA_H__ */
diff --git a/linux-headers/asm-s390/kvm.h b/linux-headers/asm-s390/kvm.h
new file mode 100644
index 0000000..82b32a1
--- /dev/null
+++ b/linux-headers/asm-s390/kvm.h
@@ -0,0 +1,44 @@
+#ifndef __LINUX_KVM_S390_H
+#define __LINUX_KVM_S390_H
+/*
+ * asm-s390/kvm.h - KVM s390 specific structures and definitions
+ *
+ * Copyright IBM Corp. 2008
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License (version 2 only)
+ * as published by the Free Software Foundation.
+ *
+ *    Author(s): Carsten Otte <cotte at de.ibm.com>
+ *               Christian Borntraeger <borntraeger at de.ibm.com>
+ */
+#include <linux/types.h>
+
+#define __KVM_S390
+
+/* for KVM_GET_REGS and KVM_SET_REGS */
+struct kvm_regs {
+	/* general purpose regs for s390 */
+	__u64 gprs[16];
+};
+
+/* for KVM_GET_SREGS and KVM_SET_SREGS */
+struct kvm_sregs {
+	__u32 acrs[16];
+	__u64 crs[16];
+};
+
+/* for KVM_GET_FPU and KVM_SET_FPU */
+struct kvm_fpu {
+	__u32 fpc;
+	__u64 fprs[16];
+};
+
+struct kvm_debug_exit_arch {
+};
+
+/* for KVM_SET_GUEST_DEBUG */
+struct kvm_guest_debug_arch {
+};
+
+#endif
diff --git a/linux-headers/asm-s390/kvm_para.h b/linux-headers/asm-s390/kvm_para.h
new file mode 100644
index 0000000..8e2dd67
--- /dev/null
+++ b/linux-headers/asm-s390/kvm_para.h
@@ -0,0 +1,17 @@
+/*
+ * asm-s390/kvm_para.h - definition for paravirtual devices on s390
+ *
+ * Copyright IBM Corp. 2008
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License (version 2 only)
+ * as published by the Free Software Foundation.
+ *
+ *    Author(s): Christian Borntraeger <borntraeger at de.ibm.com>
+ */
+
+#ifndef __S390_KVM_PARA_H
+#define __S390_KVM_PARA_H
+
+
+#endif /* __S390_KVM_PARA_H */
diff --git a/linux-headers/asm-x86/hyperv.h b/linux-headers/asm-x86/hyperv.h
new file mode 100644
index 0000000..5df477a
--- /dev/null
+++ b/linux-headers/asm-x86/hyperv.h
@@ -0,0 +1,193 @@
+#ifndef _ASM_X86_HYPERV_H
+#define _ASM_X86_HYPERV_H
+
+#include <linux/types.h>
+
+/*
+ * The below CPUID leaves are present if VersionAndFeatures.HypervisorPresent
+ * is set by CPUID(HvCpuIdFunctionVersionAndFeatures).
+ */
+#define HYPERV_CPUID_VENDOR_AND_MAX_FUNCTIONS	0x40000000
+#define HYPERV_CPUID_INTERFACE			0x40000001
+#define HYPERV_CPUID_VERSION			0x40000002
+#define HYPERV_CPUID_FEATURES			0x40000003
+#define HYPERV_CPUID_ENLIGHTMENT_INFO		0x40000004
+#define HYPERV_CPUID_IMPLEMENT_LIMITS		0x40000005
+
+#define HYPERV_HYPERVISOR_PRESENT_BIT		0x80000000
+#define HYPERV_CPUID_MIN			0x40000005
+#define HYPERV_CPUID_MAX			0x4000ffff
+
+/*
+ * Feature identification. EAX indicates which features are available
+ * to the partition based upon the current partition privileges.
+ */
+
+/* VP Runtime (HV_X64_MSR_VP_RUNTIME) available */
+#define HV_X64_MSR_VP_RUNTIME_AVAILABLE		(1 << 0)
+/* Partition Reference Counter (HV_X64_MSR_TIME_REF_COUNT) available*/
+#define HV_X64_MSR_TIME_REF_COUNT_AVAILABLE	(1 << 1)
+/*
+ * Basic SynIC MSRs (HV_X64_MSR_SCONTROL through HV_X64_MSR_EOM
+ * and HV_X64_MSR_SINT0 through HV_X64_MSR_SINT15) available
+ */
+#define HV_X64_MSR_SYNIC_AVAILABLE		(1 << 2)
+/*
+ * Synthetic Timer MSRs (HV_X64_MSR_STIMER0_CONFIG through
+ * HV_X64_MSR_STIMER3_COUNT) available
+ */
+#define HV_X64_MSR_SYNTIMER_AVAILABLE		(1 << 3)
+/*
+ * APIC access MSRs (HV_X64_MSR_EOI, HV_X64_MSR_ICR and HV_X64_MSR_TPR)
+ * are available
+ */
+#define HV_X64_MSR_APIC_ACCESS_AVAILABLE	(1 << 4)
+/* Hypercall MSRs (HV_X64_MSR_GUEST_OS_ID and HV_X64_MSR_HYPERCALL) available*/
+#define HV_X64_MSR_HYPERCALL_AVAILABLE		(1 << 5)
+/* Access virtual processor index MSR (HV_X64_MSR_VP_INDEX) available*/
+#define HV_X64_MSR_VP_INDEX_AVAILABLE		(1 << 6)
+/* Virtual system reset MSR (HV_X64_MSR_RESET) is available*/
+#define HV_X64_MSR_RESET_AVAILABLE		(1 << 7)
+ /*
+  * Access statistics pages MSRs (HV_X64_MSR_STATS_PARTITION_RETAIL_PAGE,
+  * HV_X64_MSR_STATS_PARTITION_INTERNAL_PAGE, HV_X64_MSR_STATS_VP_RETAIL_PAGE,
+  * HV_X64_MSR_STATS_VP_INTERNAL_PAGE) available
+  */
+#define HV_X64_MSR_STAT_PAGES_AVAILABLE		(1 << 8)
+
+/*
+ * Feature identification: EBX indicates which flags were specified at
+ * partition creation. The format is the same as the partition creation
+ * flag structure defined in section Partition Creation Flags.
+ */
+#define HV_X64_CREATE_PARTITIONS		(1 << 0)
+#define HV_X64_ACCESS_PARTITION_ID		(1 << 1)
+#define HV_X64_ACCESS_MEMORY_POOL		(1 << 2)
+#define HV_X64_ADJUST_MESSAGE_BUFFERS		(1 << 3)
+#define HV_X64_POST_MESSAGES			(1 << 4)
+#define HV_X64_SIGNAL_EVENTS			(1 << 5)
+#define HV_X64_CREATE_PORT			(1 << 6)
+#define HV_X64_CONNECT_PORT			(1 << 7)
+#define HV_X64_ACCESS_STATS			(1 << 8)
+#define HV_X64_DEBUGGING			(1 << 11)
+#define HV_X64_CPU_POWER_MANAGEMENT		(1 << 12)
+#define HV_X64_CONFIGURE_PROFILER		(1 << 13)
+
+/*
+ * Feature identification. EDX indicates which miscellaneous features
+ * are available to the partition.
+ */
+/* The MWAIT instruction is available (per section MONITOR / MWAIT) */
+#define HV_X64_MWAIT_AVAILABLE				(1 << 0)
+/* Guest debugging support is available */
+#define HV_X64_GUEST_DEBUGGING_AVAILABLE		(1 << 1)
+/* Performance Monitor support is available*/
+#define HV_X64_PERF_MONITOR_AVAILABLE			(1 << 2)
+/* Support for physical CPU dynamic partitioning events is available*/
+#define HV_X64_CPU_DYNAMIC_PARTITIONING_AVAILABLE	(1 << 3)
+/*
+ * Support for passing hypercall input parameter block via XMM
+ * registers is available
+ */
+#define HV_X64_HYPERCALL_PARAMS_XMM_AVAILABLE		(1 << 4)
+/* Support for a virtual guest idle state is available */
+#define HV_X64_GUEST_IDLE_STATE_AVAILABLE		(1 << 5)
+
+/*
+ * Implementation recommendations. Indicates which behaviors the hypervisor
+ * recommends the OS implement for optimal performance.
+ */
+ /*
+  * Recommend using hypercall for address space switches rather
+  * than MOV to CR3 instruction
+  */
+#define HV_X64_MWAIT_RECOMMENDED		(1 << 0)
+/* Recommend using hypercall for local TLB flushes rather
+ * than INVLPG or MOV to CR3 instructions */
+#define HV_X64_LOCAL_TLB_FLUSH_RECOMMENDED	(1 << 1)
+/*
+ * Recommend using hypercall for remote TLB flushes rather
+ * than inter-processor interrupts
+ */
+#define HV_X64_REMOTE_TLB_FLUSH_RECOMMENDED	(1 << 2)
+/*
+ * Recommend using MSRs for accessing APIC registers
+ * EOI, ICR and TPR rather than their memory-mapped counterparts
+ */
+#define HV_X64_APIC_ACCESS_RECOMMENDED		(1 << 3)
+/* Recommend using the hypervisor-provided MSR to initiate a system RESET */
+#define HV_X64_SYSTEM_RESET_RECOMMENDED		(1 << 4)
+/*
+ * Recommend using relaxed timing for this partition. If used,
+ * the VM should disable any watchdog timeouts that rely on the
+ * timely delivery of external interrupts
+ */
+#define HV_X64_RELAXED_TIMING_RECOMMENDED	(1 << 5)
+
+/* MSR used to identify the guest OS. */
+#define HV_X64_MSR_GUEST_OS_ID			0x40000000
+
+/* MSR used to setup pages used to communicate with the hypervisor. */
+#define HV_X64_MSR_HYPERCALL			0x40000001
+
+/* MSR used to provide vcpu index */
+#define HV_X64_MSR_VP_INDEX			0x40000002
+
+/* MSR used to read the per-partition time reference counter */
+#define HV_X64_MSR_TIME_REF_COUNT		0x40000020
+
+/* Define the virtual APIC registers */
+#define HV_X64_MSR_EOI				0x40000070
+#define HV_X64_MSR_ICR				0x40000071
+#define HV_X64_MSR_TPR				0x40000072
+#define HV_X64_MSR_APIC_ASSIST_PAGE		0x40000073
+
+/* Define synthetic interrupt controller model specific registers. */
+#define HV_X64_MSR_SCONTROL			0x40000080
+#define HV_X64_MSR_SVERSION			0x40000081
+#define HV_X64_MSR_SIEFP			0x40000082
+#define HV_X64_MSR_SIMP				0x40000083
+#define HV_X64_MSR_EOM				0x40000084
+#define HV_X64_MSR_SINT0			0x40000090
+#define HV_X64_MSR_SINT1			0x40000091
+#define HV_X64_MSR_SINT2			0x40000092
+#define HV_X64_MSR_SINT3			0x40000093
+#define HV_X64_MSR_SINT4			0x40000094
+#define HV_X64_MSR_SINT5			0x40000095
+#define HV_X64_MSR_SINT6			0x40000096
+#define HV_X64_MSR_SINT7			0x40000097
+#define HV_X64_MSR_SINT8			0x40000098
+#define HV_X64_MSR_SINT9			0x40000099
+#define HV_X64_MSR_SINT10			0x4000009A
+#define HV_X64_MSR_SINT11			0x4000009B
+#define HV_X64_MSR_SINT12			0x4000009C
+#define HV_X64_MSR_SINT13			0x4000009D
+#define HV_X64_MSR_SINT14			0x4000009E
+#define HV_X64_MSR_SINT15			0x4000009F
+
+
+#define HV_X64_MSR_HYPERCALL_ENABLE		0x00000001
+#define HV_X64_MSR_HYPERCALL_PAGE_ADDRESS_SHIFT	12
+#define HV_X64_MSR_HYPERCALL_PAGE_ADDRESS_MASK	\
+		(~((1ull << HV_X64_MSR_HYPERCALL_PAGE_ADDRESS_SHIFT) - 1))
+
+/* Declare the various hypercall operations. */
+#define HV_X64_HV_NOTIFY_LONG_SPIN_WAIT		0x0008
+
+#define HV_X64_MSR_APIC_ASSIST_PAGE_ENABLE		0x00000001
+#define HV_X64_MSR_APIC_ASSIST_PAGE_ADDRESS_SHIFT	12
+#define HV_X64_MSR_APIC_ASSIST_PAGE_ADDRESS_MASK	\
+		(~((1ull << HV_X64_MSR_APIC_ASSIST_PAGE_ADDRESS_SHIFT) - 1))
+
+#define HV_PROCESSOR_POWER_STATE_C0		0
+#define HV_PROCESSOR_POWER_STATE_C1		1
+#define HV_PROCESSOR_POWER_STATE_C2		2
+#define HV_PROCESSOR_POWER_STATE_C3		3
+
+/* hypercall status code */
+#define HV_STATUS_SUCCESS			0
+#define HV_STATUS_INVALID_HYPERCALL_CODE	2
+#define HV_STATUS_INVALID_HYPERCALL_INPUT	3
+#define HV_STATUS_INVALID_ALIGNMENT		4
+
+#endif
diff --git a/linux-headers/asm-x86/kvm.h b/linux-headers/asm-x86/kvm.h
new file mode 100644
index 0000000..4d8dcbd
--- /dev/null
+++ b/linux-headers/asm-x86/kvm.h
@@ -0,0 +1,324 @@
+#ifndef _ASM_X86_KVM_H
+#define _ASM_X86_KVM_H
+
+/*
+ * KVM x86 specific structures and definitions
+ *
+ */
+
+#include <linux/types.h>
+#include <linux/ioctl.h>
+
+/* Select x86 specific features in <linux/kvm.h> */
+#define __KVM_HAVE_PIT
+#define __KVM_HAVE_IOAPIC
+#define __KVM_HAVE_DEVICE_ASSIGNMENT
+#define __KVM_HAVE_MSI
+#define __KVM_HAVE_USER_NMI
+#define __KVM_HAVE_GUEST_DEBUG
+#define __KVM_HAVE_MSIX
+#define __KVM_HAVE_MCE
+#define __KVM_HAVE_PIT_STATE2
+#define __KVM_HAVE_XEN_HVM
+#define __KVM_HAVE_VCPU_EVENTS
+#define __KVM_HAVE_DEBUGREGS
+#define __KVM_HAVE_XSAVE
+#define __KVM_HAVE_XCRS
+
+/* Architectural interrupt line count. */
+#define KVM_NR_INTERRUPTS 256
+
+struct kvm_memory_alias {
+	__u32 slot;  /* this has a different namespace than memory slots */
+	__u32 flags;
+	__u64 guest_phys_addr;
+	__u64 memory_size;
+	__u64 target_phys_addr;
+};
+
+/* for KVM_GET_IRQCHIP and KVM_SET_IRQCHIP */
+struct kvm_pic_state {
+	__u8 last_irr;	/* edge detection */
+	__u8 irr;		/* interrupt request register */
+	__u8 imr;		/* interrupt mask register */
+	__u8 isr;		/* interrupt service register */
+	__u8 priority_add;	/* highest irq priority */
+	__u8 irq_base;
+	__u8 read_reg_select;
+	__u8 poll;
+	__u8 special_mask;
+	__u8 init_state;
+	__u8 auto_eoi;
+	__u8 rotate_on_auto_eoi;
+	__u8 special_fully_nested_mode;
+	__u8 init4;		/* true if 4 byte init */
+	__u8 elcr;		/* PIIX edge/trigger selection */
+	__u8 elcr_mask;
+};
+
+#define KVM_IOAPIC_NUM_PINS  24
+struct kvm_ioapic_state {
+	__u64 base_address;
+	__u32 ioregsel;
+	__u32 id;
+	__u32 irr;
+	__u32 pad;
+	union {
+		__u64 bits;
+		struct {
+			__u8 vector;
+			__u8 delivery_mode:3;
+			__u8 dest_mode:1;
+			__u8 delivery_status:1;
+			__u8 polarity:1;
+			__u8 remote_irr:1;
+			__u8 trig_mode:1;
+			__u8 mask:1;
+			__u8 reserve:7;
+			__u8 reserved[4];
+			__u8 dest_id;
+		} fields;
+	} redirtbl[KVM_IOAPIC_NUM_PINS];
+};
+
+#define KVM_IRQCHIP_PIC_MASTER   0
+#define KVM_IRQCHIP_PIC_SLAVE    1
+#define KVM_IRQCHIP_IOAPIC       2
+#define KVM_NR_IRQCHIPS          3
+
+/* for KVM_GET_REGS and KVM_SET_REGS */
+struct kvm_regs {
+	/* out (KVM_GET_REGS) / in (KVM_SET_REGS) */
+	__u64 rax, rbx, rcx, rdx;
+	__u64 rsi, rdi, rsp, rbp;
+	__u64 r8,  r9,  r10, r11;
+	__u64 r12, r13, r14, r15;
+	__u64 rip, rflags;
+};
+
+/* for KVM_GET_LAPIC and KVM_SET_LAPIC */
+#define KVM_APIC_REG_SIZE 0x400
+struct kvm_lapic_state {
+	char regs[KVM_APIC_REG_SIZE];
+};
+
+struct kvm_segment {
+	__u64 base;
+	__u32 limit;
+	__u16 selector;
+	__u8  type;
+	__u8  present, dpl, db, s, l, g, avl;
+	__u8  unusable;
+	__u8  padding;
+};
+
+struct kvm_dtable {
+	__u64 base;
+	__u16 limit;
+	__u16 padding[3];
+};
+
+
+/* for KVM_GET_SREGS and KVM_SET_SREGS */
+struct kvm_sregs {
+	/* out (KVM_GET_SREGS) / in (KVM_SET_SREGS) */
+	struct kvm_segment cs, ds, es, fs, gs, ss;
+	struct kvm_segment tr, ldt;
+	struct kvm_dtable gdt, idt;
+	__u64 cr0, cr2, cr3, cr4, cr8;
+	__u64 efer;
+	__u64 apic_base;
+	__u64 interrupt_bitmap[(KVM_NR_INTERRUPTS + 63) / 64];
+};
+
+/* for KVM_GET_FPU and KVM_SET_FPU */
+struct kvm_fpu {
+	__u8  fpr[8][16];
+	__u16 fcw;
+	__u16 fsw;
+	__u8  ftwx;  /* in fxsave format */
+	__u8  pad1;
+	__u16 last_opcode;
+	__u64 last_ip;
+	__u64 last_dp;
+	__u8  xmm[16][16];
+	__u32 mxcsr;
+	__u32 pad2;
+};
+
+struct kvm_msr_entry {
+	__u32 index;
+	__u32 reserved;
+	__u64 data;
+};
+
+/* for KVM_GET_MSRS and KVM_SET_MSRS */
+struct kvm_msrs {
+	__u32 nmsrs; /* number of msrs in entries */
+	__u32 pad;
+
+	struct kvm_msr_entry entries[0];
+};
+
+/* for KVM_GET_MSR_INDEX_LIST */
+struct kvm_msr_list {
+	__u32 nmsrs; /* number of msrs in entries */
+	__u32 indices[0];
+};
+
+
+struct kvm_cpuid_entry {
+	__u32 function;
+	__u32 eax;
+	__u32 ebx;
+	__u32 ecx;
+	__u32 edx;
+	__u32 padding;
+};
+
+/* for KVM_SET_CPUID */
+struct kvm_cpuid {
+	__u32 nent;
+	__u32 padding;
+	struct kvm_cpuid_entry entries[0];
+};
+
+struct kvm_cpuid_entry2 {
+	__u32 function;
+	__u32 index;
+	__u32 flags;
+	__u32 eax;
+	__u32 ebx;
+	__u32 ecx;
+	__u32 edx;
+	__u32 padding[3];
+};
+
+#define KVM_CPUID_FLAG_SIGNIFCANT_INDEX 1
+#define KVM_CPUID_FLAG_STATEFUL_FUNC    2
+#define KVM_CPUID_FLAG_STATE_READ_NEXT  4
+
+/* for KVM_SET_CPUID2 */
+struct kvm_cpuid2 {
+	__u32 nent;
+	__u32 padding;
+	struct kvm_cpuid_entry2 entries[0];
+};
+
+/* for KVM_GET_PIT and KVM_SET_PIT */
+struct kvm_pit_channel_state {
+	__u32 count; /* can be 65536 */
+	__u16 latched_count;
+	__u8 count_latched;
+	__u8 status_latched;
+	__u8 status;
+	__u8 read_state;
+	__u8 write_state;
+	__u8 write_latch;
+	__u8 rw_mode;
+	__u8 mode;
+	__u8 bcd;
+	__u8 gate;
+	__s64 count_load_time;
+};
+
+struct kvm_debug_exit_arch {
+	__u32 exception;
+	__u32 pad;
+	__u64 pc;
+	__u64 dr6;
+	__u64 dr7;
+};
+
+#define KVM_GUESTDBG_USE_SW_BP		0x00010000
+#define KVM_GUESTDBG_USE_HW_BP		0x00020000
+#define KVM_GUESTDBG_INJECT_DB		0x00040000
+#define KVM_GUESTDBG_INJECT_BP		0x00080000
+
+/* for KVM_SET_GUEST_DEBUG */
+struct kvm_guest_debug_arch {
+	__u64 debugreg[8];
+};
+
+struct kvm_pit_state {
+	struct kvm_pit_channel_state channels[3];
+};
+
+#define KVM_PIT_FLAGS_HPET_LEGACY  0x00000001
+
+struct kvm_pit_state2 {
+	struct kvm_pit_channel_state channels[3];
+	__u32 flags;
+	__u32 reserved[9];
+};
+
+struct kvm_reinject_control {
+	__u8 pit_reinject;
+	__u8 reserved[31];
+};
+
+/* When set in flags, include corresponding fields on KVM_SET_VCPU_EVENTS */
+#define KVM_VCPUEVENT_VALID_NMI_PENDING	0x00000001
+#define KVM_VCPUEVENT_VALID_SIPI_VECTOR	0x00000002
+#define KVM_VCPUEVENT_VALID_SHADOW	0x00000004
+
+/* Interrupt shadow states */
+#define KVM_X86_SHADOW_INT_MOV_SS	0x01
+#define KVM_X86_SHADOW_INT_STI		0x02
+
+/* for KVM_GET/SET_VCPU_EVENTS */
+struct kvm_vcpu_events {
+	struct {
+		__u8 injected;
+		__u8 nr;
+		__u8 has_error_code;
+		__u8 pad;
+		__u32 error_code;
+	} exception;
+	struct {
+		__u8 injected;
+		__u8 nr;
+		__u8 soft;
+		__u8 shadow;
+	} interrupt;
+	struct {
+		__u8 injected;
+		__u8 pending;
+		__u8 masked;
+		__u8 pad;
+	} nmi;
+	__u32 sipi_vector;
+	__u32 flags;
+	__u32 reserved[10];
+};
+
+/* for KVM_GET/SET_DEBUGREGS */
+struct kvm_debugregs {
+	__u64 db[4];
+	__u64 dr6;
+	__u64 dr7;
+	__u64 flags;
+	__u64 reserved[9];
+};
+
+/* for KVM_CAP_XSAVE */
+struct kvm_xsave {
+	__u32 region[1024];
+};
+
+#define KVM_MAX_XCRS	16
+
+struct kvm_xcr {
+	__u32 xcr;
+	__u32 reserved;
+	__u64 value;
+};
+
+struct kvm_xcrs {
+	__u32 nr_xcrs;
+	__u32 flags;
+	struct kvm_xcr xcrs[KVM_MAX_XCRS];
+	__u64 padding[16];
+};
+
+#endif /* _ASM_X86_KVM_H */
diff --git a/linux-headers/asm-x86/kvm_para.h b/linux-headers/asm-x86/kvm_para.h
new file mode 100644
index 0000000..834d71e
--- /dev/null
+++ b/linux-headers/asm-x86/kvm_para.h
@@ -0,0 +1,79 @@
+#ifndef _ASM_X86_KVM_PARA_H
+#define _ASM_X86_KVM_PARA_H
+
+#include <linux/types.h>
+#include <asm/hyperv.h>
+
+/* This CPUID returns the signature 'KVMKVMKVM' in ebx, ecx, and edx.  It
+ * should be used to determine that a VM is running under KVM.
+ */
+#define KVM_CPUID_SIGNATURE	0x40000000
+
+/* This CPUID returns a feature bitmap in eax.  Before enabling a particular
+ * paravirtualization, the appropriate feature bit should be checked.
+ */
+#define KVM_CPUID_FEATURES	0x40000001
+#define KVM_FEATURE_CLOCKSOURCE		0
+#define KVM_FEATURE_NOP_IO_DELAY	1
+#define KVM_FEATURE_MMU_OP		2
+/* This indicates that the new set of kvmclock msrs
+ * are available. The use of 0x11 and 0x12 is deprecated
+ */
+#define KVM_FEATURE_CLOCKSOURCE2        3
+#define KVM_FEATURE_ASYNC_PF		4
+
+/* The last 8 bits are used to indicate how to interpret the flags field
+ * in pvclock structure. If no bits are set, all flags are ignored.
+ */
+#define KVM_FEATURE_CLOCKSOURCE_STABLE_BIT	24
+
+#define MSR_KVM_WALL_CLOCK  0x11
+#define MSR_KVM_SYSTEM_TIME 0x12
+
+/* Custom MSRs falls in the range 0x4b564d00-0x4b564dff */
+#define MSR_KVM_WALL_CLOCK_NEW  0x4b564d00
+#define MSR_KVM_SYSTEM_TIME_NEW 0x4b564d01
+#define MSR_KVM_ASYNC_PF_EN 0x4b564d02
+
+#define KVM_MAX_MMU_OP_BATCH           32
+
+#define KVM_ASYNC_PF_ENABLED			(1 << 0)
+#define KVM_ASYNC_PF_SEND_ALWAYS		(1 << 1)
+
+/* Operations for KVM_HC_MMU_OP */
+#define KVM_MMU_OP_WRITE_PTE            1
+#define KVM_MMU_OP_FLUSH_TLB	        2
+#define KVM_MMU_OP_RELEASE_PT	        3
+
+/* Payload for KVM_HC_MMU_OP */
+struct kvm_mmu_op_header {
+	__u32 op;
+	__u32 pad;
+};
+
+struct kvm_mmu_op_write_pte {
+	struct kvm_mmu_op_header header;
+	__u64 pte_phys;
+	__u64 pte_val;
+};
+
+struct kvm_mmu_op_flush_tlb {
+	struct kvm_mmu_op_header header;
+};
+
+struct kvm_mmu_op_release_pt {
+	struct kvm_mmu_op_header header;
+	__u64 pt_phys;
+};
+
+#define KVM_PV_REASON_PAGE_NOT_PRESENT 1
+#define KVM_PV_REASON_PAGE_READY 2
+
+struct kvm_vcpu_pv_apf_data {
+	__u32 reason;
+	__u8 pad[60];
+	__u32 enabled;
+};
+
+
+#endif /* _ASM_X86_KVM_PARA_H */
diff --git a/linux-headers/linux/kvm.h b/linux-headers/linux/kvm.h
new file mode 100644
index 0000000..fc63b73
--- /dev/null
+++ b/linux-headers/linux/kvm.h
@@ -0,0 +1,804 @@
+#ifndef __LINUX_KVM_H
+#define __LINUX_KVM_H
+
+/*
+ * Userspace interface for /dev/kvm - kernel based virtual machine
+ *
+ * Note: you must update KVM_API_VERSION if you change this interface.
+ */
+
+#include <linux/types.h>
+
+#include <linux/ioctl.h>
+#include <asm/kvm.h>
+
+#define KVM_API_VERSION 12
+
+/* *** Deprecated interfaces *** */
+
+#define KVM_TRC_SHIFT           16
+
+#define KVM_TRC_ENTRYEXIT       (1 << KVM_TRC_SHIFT)
+#define KVM_TRC_HANDLER         (1 << (KVM_TRC_SHIFT + 1))
+
+#define KVM_TRC_VMENTRY         (KVM_TRC_ENTRYEXIT + 0x01)
+#define KVM_TRC_VMEXIT          (KVM_TRC_ENTRYEXIT + 0x02)
+#define KVM_TRC_PAGE_FAULT      (KVM_TRC_HANDLER + 0x01)
+
+#define KVM_TRC_HEAD_SIZE       12
+#define KVM_TRC_CYCLE_SIZE      8
+#define KVM_TRC_EXTRA_MAX       7
+
+#define KVM_TRC_INJ_VIRQ         (KVM_TRC_HANDLER + 0x02)
+#define KVM_TRC_REDELIVER_EVT    (KVM_TRC_HANDLER + 0x03)
+#define KVM_TRC_PEND_INTR        (KVM_TRC_HANDLER + 0x04)
+#define KVM_TRC_IO_READ          (KVM_TRC_HANDLER + 0x05)
+#define KVM_TRC_IO_WRITE         (KVM_TRC_HANDLER + 0x06)
+#define KVM_TRC_CR_READ          (KVM_TRC_HANDLER + 0x07)
+#define KVM_TRC_CR_WRITE         (KVM_TRC_HANDLER + 0x08)
+#define KVM_TRC_DR_READ          (KVM_TRC_HANDLER + 0x09)
+#define KVM_TRC_DR_WRITE         (KVM_TRC_HANDLER + 0x0A)
+#define KVM_TRC_MSR_READ         (KVM_TRC_HANDLER + 0x0B)
+#define KVM_TRC_MSR_WRITE        (KVM_TRC_HANDLER + 0x0C)
+#define KVM_TRC_CPUID            (KVM_TRC_HANDLER + 0x0D)
+#define KVM_TRC_INTR             (KVM_TRC_HANDLER + 0x0E)
+#define KVM_TRC_NMI              (KVM_TRC_HANDLER + 0x0F)
+#define KVM_TRC_VMMCALL          (KVM_TRC_HANDLER + 0x10)
+#define KVM_TRC_HLT              (KVM_TRC_HANDLER + 0x11)
+#define KVM_TRC_CLTS             (KVM_TRC_HANDLER + 0x12)
+#define KVM_TRC_LMSW             (KVM_TRC_HANDLER + 0x13)
+#define KVM_TRC_APIC_ACCESS      (KVM_TRC_HANDLER + 0x14)
+#define KVM_TRC_TDP_FAULT        (KVM_TRC_HANDLER + 0x15)
+#define KVM_TRC_GTLB_WRITE       (KVM_TRC_HANDLER + 0x16)
+#define KVM_TRC_STLB_WRITE       (KVM_TRC_HANDLER + 0x17)
+#define KVM_TRC_STLB_INVAL       (KVM_TRC_HANDLER + 0x18)
+#define KVM_TRC_PPC_INSTR        (KVM_TRC_HANDLER + 0x19)
+
+struct kvm_user_trace_setup {
+	__u32 buf_size;
+	__u32 buf_nr;
+};
+
+#define __KVM_DEPRECATED_MAIN_W_0x06 \
+	_IOW(KVMIO, 0x06, struct kvm_user_trace_setup)
+#define __KVM_DEPRECATED_MAIN_0x07 _IO(KVMIO, 0x07)
+#define __KVM_DEPRECATED_MAIN_0x08 _IO(KVMIO, 0x08)
+
+#define __KVM_DEPRECATED_VM_R_0x70 _IOR(KVMIO, 0x70, struct kvm_assigned_irq)
+
+struct kvm_breakpoint {
+	__u32 enabled;
+	__u32 padding;
+	__u64 address;
+};
+
+struct kvm_debug_guest {
+	__u32 enabled;
+	__u32 pad;
+	struct kvm_breakpoint breakpoints[4];
+	__u32 singlestep;
+};
+
+#define __KVM_DEPRECATED_VCPU_W_0x87 _IOW(KVMIO, 0x87, struct kvm_debug_guest)
+
+/* *** End of deprecated interfaces *** */
+
+
+/* for KVM_CREATE_MEMORY_REGION */
+struct kvm_memory_region {
+	__u32 slot;
+	__u32 flags;
+	__u64 guest_phys_addr;
+	__u64 memory_size; /* bytes */
+};
+
+/* for KVM_SET_USER_MEMORY_REGION */
+struct kvm_userspace_memory_region {
+	__u32 slot;
+	__u32 flags;
+	__u64 guest_phys_addr;
+	__u64 memory_size; /* bytes */
+	__u64 userspace_addr; /* start of the userspace allocated memory */
+};
+
+/* for kvm_memory_region::flags */
+#define KVM_MEM_LOG_DIRTY_PAGES  1UL
+#define KVM_MEMSLOT_INVALID      (1UL << 1)
+
+/* for KVM_IRQ_LINE */
+struct kvm_irq_level {
+	/*
+	 * ACPI gsi notion of irq.
+	 * For IA-64 (APIC model) IOAPIC0: irq 0-23; IOAPIC1: irq 24-47..
+	 * For X86 (standard AT mode) PIC0/1: irq 0-15. IOAPIC0: 0-23..
+	 */
+	union {
+		__u32 irq;
+		__s32 status;
+	};
+	__u32 level;
+};
+
+
+struct kvm_irqchip {
+	__u32 chip_id;
+	__u32 pad;
+        union {
+		char dummy[512];  /* reserving space */
+#ifdef __KVM_HAVE_PIT
+		struct kvm_pic_state pic;
+#endif
+#ifdef __KVM_HAVE_IOAPIC
+		struct kvm_ioapic_state ioapic;
+#endif
+	} chip;
+};
+
+/* for KVM_CREATE_PIT2 */
+struct kvm_pit_config {
+	__u32 flags;
+	__u32 pad[15];
+};
+
+#define KVM_PIT_SPEAKER_DUMMY     1
+
+#define KVM_EXIT_UNKNOWN          0
+#define KVM_EXIT_EXCEPTION        1
+#define KVM_EXIT_IO               2
+#define KVM_EXIT_HYPERCALL        3
+#define KVM_EXIT_DEBUG            4
+#define KVM_EXIT_HLT              5
+#define KVM_EXIT_MMIO             6
+#define KVM_EXIT_IRQ_WINDOW_OPEN  7
+#define KVM_EXIT_SHUTDOWN         8
+#define KVM_EXIT_FAIL_ENTRY       9
+#define KVM_EXIT_INTR             10
+#define KVM_EXIT_SET_TPR          11
+#define KVM_EXIT_TPR_ACCESS       12
+#define KVM_EXIT_S390_SIEIC       13
+#define KVM_EXIT_S390_RESET       14
+#define KVM_EXIT_DCR              15
+#define KVM_EXIT_NMI              16
+#define KVM_EXIT_INTERNAL_ERROR   17
+#define KVM_EXIT_OSI              18
+
+/* For KVM_EXIT_INTERNAL_ERROR */
+#define KVM_INTERNAL_ERROR_EMULATION 1
+#define KVM_INTERNAL_ERROR_SIMUL_EX 2
+
+/* for KVM_RUN, returned by mmap(vcpu_fd, offset=0) */
+struct kvm_run {
+	/* in */
+	__u8 request_interrupt_window;
+	__u8 padding1[7];
+
+	/* out */
+	__u32 exit_reason;
+	__u8 ready_for_interrupt_injection;
+	__u8 if_flag;
+	__u8 padding2[2];
+
+	/* in (pre_kvm_run), out (post_kvm_run) */
+	__u64 cr8;
+	__u64 apic_base;
+
+#ifdef __KVM_S390
+	/* the processor status word for s390 */
+	__u64 psw_mask; /* psw upper half */
+	__u64 psw_addr; /* psw lower half */
+#endif
+	union {
+		/* KVM_EXIT_UNKNOWN */
+		struct {
+			__u64 hardware_exit_reason;
+		} hw;
+		/* KVM_EXIT_FAIL_ENTRY */
+		struct {
+			__u64 hardware_entry_failure_reason;
+		} fail_entry;
+		/* KVM_EXIT_EXCEPTION */
+		struct {
+			__u32 exception;
+			__u32 error_code;
+		} ex;
+		/* KVM_EXIT_IO */
+		struct {
+#define KVM_EXIT_IO_IN  0
+#define KVM_EXIT_IO_OUT 1
+			__u8 direction;
+			__u8 size; /* bytes */
+			__u16 port;
+			__u32 count;
+			__u64 data_offset; /* relative to kvm_run start */
+		} io;
+		struct {
+			struct kvm_debug_exit_arch arch;
+		} debug;
+		/* KVM_EXIT_MMIO */
+		struct {
+			__u64 phys_addr;
+			__u8  data[8];
+			__u32 len;
+			__u8  is_write;
+		} mmio;
+		/* KVM_EXIT_HYPERCALL */
+		struct {
+			__u64 nr;
+			__u64 args[6];
+			__u64 ret;
+			__u32 longmode;
+			__u32 pad;
+		} hypercall;
+		/* KVM_EXIT_TPR_ACCESS */
+		struct {
+			__u64 rip;
+			__u32 is_write;
+			__u32 pad;
+		} tpr_access;
+		/* KVM_EXIT_S390_SIEIC */
+		struct {
+			__u8 icptcode;
+			__u16 ipa;
+			__u32 ipb;
+		} s390_sieic;
+		/* KVM_EXIT_S390_RESET */
+#define KVM_S390_RESET_POR       1
+#define KVM_S390_RESET_CLEAR     2
+#define KVM_S390_RESET_SUBSYSTEM 4
+#define KVM_S390_RESET_CPU_INIT  8
+#define KVM_S390_RESET_IPL       16
+		__u64 s390_reset_flags;
+		/* KVM_EXIT_DCR */
+		struct {
+			__u32 dcrn;
+			__u32 data;
+			__u8  is_write;
+		} dcr;
+		struct {
+			__u32 suberror;
+			/* Available with KVM_CAP_INTERNAL_ERROR_DATA: */
+			__u32 ndata;
+			__u64 data[16];
+		} internal;
+		/* KVM_EXIT_OSI */
+		struct {
+			__u64 gprs[32];
+		} osi;
+		/* Fix the size of the union. */
+		char padding[256];
+	};
+};
+
+/* for KVM_REGISTER_COALESCED_MMIO / KVM_UNREGISTER_COALESCED_MMIO */
+
+struct kvm_coalesced_mmio_zone {
+	__u64 addr;
+	__u32 size;
+	__u32 pad;
+};
+
+struct kvm_coalesced_mmio {
+	__u64 phys_addr;
+	__u32 len;
+	__u32 pad;
+	__u8  data[8];
+};
+
+struct kvm_coalesced_mmio_ring {
+	__u32 first, last;
+	struct kvm_coalesced_mmio coalesced_mmio[0];
+};
+
+#define KVM_COALESCED_MMIO_MAX \
+	((PAGE_SIZE - sizeof(struct kvm_coalesced_mmio_ring)) / \
+	 sizeof(struct kvm_coalesced_mmio))
+
+/* for KVM_TRANSLATE */
+struct kvm_translation {
+	/* in */
+	__u64 linear_address;
+
+	/* out */
+	__u64 physical_address;
+	__u8  valid;
+	__u8  writeable;
+	__u8  usermode;
+	__u8  pad[5];
+};
+
+/* for KVM_INTERRUPT */
+struct kvm_interrupt {
+	/* in */
+	__u32 irq;
+};
+
+/* for KVM_GET_DIRTY_LOG */
+struct kvm_dirty_log {
+	__u32 slot;
+	__u32 padding1;
+	union {
+		void *dirty_bitmap; /* one bit per page */
+		__u64 padding2;
+	};
+};
+
+/* for KVM_SET_SIGNAL_MASK */
+struct kvm_signal_mask {
+	__u32 len;
+	__u8  sigset[0];
+};
+
+/* for KVM_TPR_ACCESS_REPORTING */
+struct kvm_tpr_access_ctl {
+	__u32 enabled;
+	__u32 flags;
+	__u32 reserved[8];
+};
+
+/* for KVM_SET_VAPIC_ADDR */
+struct kvm_vapic_addr {
+	__u64 vapic_addr;
+};
+
+/* for KVM_SET_MPSTATE */
+
+#define KVM_MP_STATE_RUNNABLE          0
+#define KVM_MP_STATE_UNINITIALIZED     1
+#define KVM_MP_STATE_INIT_RECEIVED     2
+#define KVM_MP_STATE_HALTED            3
+#define KVM_MP_STATE_SIPI_RECEIVED     4
+
+struct kvm_mp_state {
+	__u32 mp_state;
+};
+
+struct kvm_s390_psw {
+	__u64 mask;
+	__u64 addr;
+};
+
+/* valid values for type in kvm_s390_interrupt */
+#define KVM_S390_SIGP_STOP		0xfffe0000u
+#define KVM_S390_PROGRAM_INT		0xfffe0001u
+#define KVM_S390_SIGP_SET_PREFIX	0xfffe0002u
+#define KVM_S390_RESTART		0xfffe0003u
+#define KVM_S390_INT_VIRTIO		0xffff2603u
+#define KVM_S390_INT_SERVICE		0xffff2401u
+#define KVM_S390_INT_EMERGENCY		0xffff1201u
+
+struct kvm_s390_interrupt {
+	__u32 type;
+	__u32 parm;
+	__u64 parm64;
+};
+
+/* for KVM_SET_GUEST_DEBUG */
+
+#define KVM_GUESTDBG_ENABLE		0x00000001
+#define KVM_GUESTDBG_SINGLESTEP		0x00000002
+
+struct kvm_guest_debug {
+	__u32 control;
+	__u32 pad;
+	struct kvm_guest_debug_arch arch;
+};
+
+enum {
+	kvm_ioeventfd_flag_nr_datamatch,
+	kvm_ioeventfd_flag_nr_pio,
+	kvm_ioeventfd_flag_nr_deassign,
+	kvm_ioeventfd_flag_nr_max,
+};
+
+#define KVM_IOEVENTFD_FLAG_DATAMATCH (1 << kvm_ioeventfd_flag_nr_datamatch)
+#define KVM_IOEVENTFD_FLAG_PIO       (1 << kvm_ioeventfd_flag_nr_pio)
+#define KVM_IOEVENTFD_FLAG_DEASSIGN  (1 << kvm_ioeventfd_flag_nr_deassign)
+
+#define KVM_IOEVENTFD_VALID_FLAG_MASK  ((1 << kvm_ioeventfd_flag_nr_max) - 1)
+
+struct kvm_ioeventfd {
+	__u64 datamatch;
+	__u64 addr;        /* legal pio/mmio address */
+	__u32 len;         /* 1, 2, 4, or 8 bytes    */
+	__s32 fd;
+	__u32 flags;
+	__u8  pad[36];
+};
+
+/* for KVM_ENABLE_CAP */
+struct kvm_enable_cap {
+	/* in */
+	__u32 cap;
+	__u32 flags;
+	__u64 args[4];
+	__u8  pad[64];
+};
+
+/* for KVM_PPC_GET_PVINFO */
+struct kvm_ppc_pvinfo {
+	/* out */
+	__u32 flags;
+	__u32 hcall[4];
+	__u8  pad[108];
+};
+
+#define KVMIO 0xAE
+
+/*
+ * ioctls for /dev/kvm fds:
+ */
+#define KVM_GET_API_VERSION       _IO(KVMIO,   0x00)
+#define KVM_CREATE_VM             _IO(KVMIO,   0x01) /* returns a VM fd */
+#define KVM_GET_MSR_INDEX_LIST    _IOWR(KVMIO, 0x02, struct kvm_msr_list)
+
+#define KVM_S390_ENABLE_SIE       _IO(KVMIO,   0x06)
+/*
+ * Check if a kvm extension is available.  Argument is extension number,
+ * return is 1 (yes) or 0 (no, sorry).
+ */
+#define KVM_CHECK_EXTENSION       _IO(KVMIO,   0x03)
+/*
+ * Get size for mmap(vcpu_fd)
+ */
+#define KVM_GET_VCPU_MMAP_SIZE    _IO(KVMIO,   0x04) /* in bytes */
+#define KVM_GET_SUPPORTED_CPUID   _IOWR(KVMIO, 0x05, struct kvm_cpuid2)
+#define KVM_TRACE_ENABLE          __KVM_DEPRECATED_MAIN_W_0x06
+#define KVM_TRACE_PAUSE           __KVM_DEPRECATED_MAIN_0x07
+#define KVM_TRACE_DISABLE         __KVM_DEPRECATED_MAIN_0x08
+
+/*
+ * Extension capability list.
+ */
+#define KVM_CAP_IRQCHIP	  0
+#define KVM_CAP_HLT	  1
+#define KVM_CAP_MMU_SHADOW_CACHE_CONTROL 2
+#define KVM_CAP_USER_MEMORY 3
+#define KVM_CAP_SET_TSS_ADDR 4
+#define KVM_CAP_VAPIC 6
+#define KVM_CAP_EXT_CPUID 7
+#define KVM_CAP_CLOCKSOURCE 8
+#define KVM_CAP_NR_VCPUS 9       /* returns max vcpus per vm */
+#define KVM_CAP_NR_MEMSLOTS 10   /* returns max memory slots per vm */
+#define KVM_CAP_PIT 11
+#define KVM_CAP_NOP_IO_DELAY 12
+#define KVM_CAP_PV_MMU 13
+#define KVM_CAP_MP_STATE 14
+#define KVM_CAP_COALESCED_MMIO 15
+#define KVM_CAP_SYNC_MMU 16  /* Changes to host mmap are reflected in guest */
+#ifdef __KVM_HAVE_DEVICE_ASSIGNMENT
+#define KVM_CAP_DEVICE_ASSIGNMENT 17
+#endif
+#define KVM_CAP_IOMMU 18
+#ifdef __KVM_HAVE_MSI
+#define KVM_CAP_DEVICE_MSI 20
+#endif
+/* Bug in KVM_SET_USER_MEMORY_REGION fixed: */
+#define KVM_CAP_DESTROY_MEMORY_REGION_WORKS 21
+#ifdef __KVM_HAVE_USER_NMI
+#define KVM_CAP_USER_NMI 22
+#endif
+#ifdef __KVM_HAVE_GUEST_DEBUG
+#define KVM_CAP_SET_GUEST_DEBUG 23
+#endif
+#ifdef __KVM_HAVE_PIT
+#define KVM_CAP_REINJECT_CONTROL 24
+#endif
+#ifdef __KVM_HAVE_IOAPIC
+#define KVM_CAP_IRQ_ROUTING 25
+#endif
+#define KVM_CAP_IRQ_INJECT_STATUS 26
+#ifdef __KVM_HAVE_DEVICE_ASSIGNMENT
+#define KVM_CAP_DEVICE_DEASSIGNMENT 27
+#endif
+#ifdef __KVM_HAVE_MSIX
+#define KVM_CAP_DEVICE_MSIX 28
+#endif
+#define KVM_CAP_ASSIGN_DEV_IRQ 29
+/* Another bug in KVM_SET_USER_MEMORY_REGION fixed: */
+#define KVM_CAP_JOIN_MEMORY_REGIONS_WORKS 30
+#ifdef __KVM_HAVE_MCE
+#define KVM_CAP_MCE 31
+#endif
+#define KVM_CAP_IRQFD 32
+#ifdef __KVM_HAVE_PIT
+#define KVM_CAP_PIT2 33
+#endif
+#define KVM_CAP_SET_BOOT_CPU_ID 34
+#ifdef __KVM_HAVE_PIT_STATE2
+#define KVM_CAP_PIT_STATE2 35
+#endif
+#define KVM_CAP_IOEVENTFD 36
+#define KVM_CAP_SET_IDENTITY_MAP_ADDR 37
+#ifdef __KVM_HAVE_XEN_HVM
+#define KVM_CAP_XEN_HVM 38
+#endif
+#define KVM_CAP_ADJUST_CLOCK 39
+#define KVM_CAP_INTERNAL_ERROR_DATA 40
+#ifdef __KVM_HAVE_VCPU_EVENTS
+#define KVM_CAP_VCPU_EVENTS 41
+#endif
+#define KVM_CAP_S390_PSW 42
+#define KVM_CAP_PPC_SEGSTATE 43
+#define KVM_CAP_HYPERV 44
+#define KVM_CAP_HYPERV_VAPIC 45
+#define KVM_CAP_HYPERV_SPIN 46
+#define KVM_CAP_PCI_SEGMENT 47
+#define KVM_CAP_PPC_PAIRED_SINGLES 48
+#define KVM_CAP_INTR_SHADOW 49
+#ifdef __KVM_HAVE_DEBUGREGS
+#define KVM_CAP_DEBUGREGS 50
+#endif
+#define KVM_CAP_X86_ROBUST_SINGLESTEP 51
+#define KVM_CAP_PPC_OSI 52
+#define KVM_CAP_PPC_UNSET_IRQ 53
+#define KVM_CAP_ENABLE_CAP 54
+#ifdef __KVM_HAVE_XSAVE
+#define KVM_CAP_XSAVE 55
+#endif
+#ifdef __KVM_HAVE_XCRS
+#define KVM_CAP_XCRS 56
+#endif
+#define KVM_CAP_PPC_GET_PVINFO 57
+#define KVM_CAP_PPC_IRQ_LEVEL 58
+#define KVM_CAP_ASYNC_PF 59
+#define KVM_CAP_TSC_CONTROL 60
+#define KVM_CAP_GET_TSC_KHZ 61
+#define KVM_CAP_PPC_BOOKE_SREGS 62
+
+#ifdef KVM_CAP_IRQ_ROUTING
+
+struct kvm_irq_routing_irqchip {
+	__u32 irqchip;
+	__u32 pin;
+};
+
+struct kvm_irq_routing_msi {
+	__u32 address_lo;
+	__u32 address_hi;
+	__u32 data;
+	__u32 pad;
+};
+
+/* gsi routing entry types */
+#define KVM_IRQ_ROUTING_IRQCHIP 1
+#define KVM_IRQ_ROUTING_MSI 2
+
+struct kvm_irq_routing_entry {
+	__u32 gsi;
+	__u32 type;
+	__u32 flags;
+	__u32 pad;
+	union {
+		struct kvm_irq_routing_irqchip irqchip;
+		struct kvm_irq_routing_msi msi;
+		__u32 pad[8];
+	} u;
+};
+
+struct kvm_irq_routing {
+	__u32 nr;
+	__u32 flags;
+	struct kvm_irq_routing_entry entries[0];
+};
+
+#endif
+
+#ifdef KVM_CAP_MCE
+/* x86 MCE */
+struct kvm_x86_mce {
+	__u64 status;
+	__u64 addr;
+	__u64 misc;
+	__u64 mcg_status;
+	__u8 bank;
+	__u8 pad1[7];
+	__u64 pad2[3];
+};
+#endif
+
+#ifdef KVM_CAP_XEN_HVM
+struct kvm_xen_hvm_config {
+	__u32 flags;
+	__u32 msr;
+	__u64 blob_addr_32;
+	__u64 blob_addr_64;
+	__u8 blob_size_32;
+	__u8 blob_size_64;
+	__u8 pad2[30];
+};
+#endif
+
+#define KVM_IRQFD_FLAG_DEASSIGN (1 << 0)
+
+struct kvm_irqfd {
+	__u32 fd;
+	__u32 gsi;
+	__u32 flags;
+	__u8  pad[20];
+};
+
+struct kvm_clock_data {
+	__u64 clock;
+	__u32 flags;
+	__u32 pad[9];
+};
+
+/*
+ * ioctls for VM fds
+ */
+#define KVM_SET_MEMORY_REGION     _IOW(KVMIO,  0x40, struct kvm_memory_region)
+/*
+ * KVM_CREATE_VCPU receives as a parameter the vcpu slot, and returns
+ * a vcpu fd.
+ */
+#define KVM_CREATE_VCPU           _IO(KVMIO,   0x41)
+#define KVM_GET_DIRTY_LOG         _IOW(KVMIO,  0x42, struct kvm_dirty_log)
+/* KVM_SET_MEMORY_ALIAS is obsolete: */
+#define KVM_SET_MEMORY_ALIAS      _IOW(KVMIO,  0x43, struct kvm_memory_alias)
+#define KVM_SET_NR_MMU_PAGES      _IO(KVMIO,   0x44)
+#define KVM_GET_NR_MMU_PAGES      _IO(KVMIO,   0x45)
+#define KVM_SET_USER_MEMORY_REGION _IOW(KVMIO, 0x46, \
+					struct kvm_userspace_memory_region)
+#define KVM_SET_TSS_ADDR          _IO(KVMIO,   0x47)
+#define KVM_SET_IDENTITY_MAP_ADDR _IOW(KVMIO,  0x48, __u64)
+/* Device model IOC */
+#define KVM_CREATE_IRQCHIP        _IO(KVMIO,   0x60)
+#define KVM_IRQ_LINE              _IOW(KVMIO,  0x61, struct kvm_irq_level)
+#define KVM_GET_IRQCHIP           _IOWR(KVMIO, 0x62, struct kvm_irqchip)
+#define KVM_SET_IRQCHIP           _IOR(KVMIO,  0x63, struct kvm_irqchip)
+#define KVM_CREATE_PIT            _IO(KVMIO,   0x64)
+#define KVM_GET_PIT               _IOWR(KVMIO, 0x65, struct kvm_pit_state)
+#define KVM_SET_PIT               _IOR(KVMIO,  0x66, struct kvm_pit_state)
+#define KVM_IRQ_LINE_STATUS       _IOWR(KVMIO, 0x67, struct kvm_irq_level)
+#define KVM_REGISTER_COALESCED_MMIO \
+			_IOW(KVMIO,  0x67, struct kvm_coalesced_mmio_zone)
+#define KVM_UNREGISTER_COALESCED_MMIO \
+			_IOW(KVMIO,  0x68, struct kvm_coalesced_mmio_zone)
+#define KVM_ASSIGN_PCI_DEVICE     _IOR(KVMIO,  0x69, \
+				       struct kvm_assigned_pci_dev)
+#define KVM_SET_GSI_ROUTING       _IOW(KVMIO,  0x6a, struct kvm_irq_routing)
+/* deprecated, replaced by KVM_ASSIGN_DEV_IRQ */
+#define KVM_ASSIGN_IRQ            __KVM_DEPRECATED_VM_R_0x70
+#define KVM_ASSIGN_DEV_IRQ        _IOW(KVMIO,  0x70, struct kvm_assigned_irq)
+#define KVM_REINJECT_CONTROL      _IO(KVMIO,   0x71)
+#define KVM_DEASSIGN_PCI_DEVICE   _IOW(KVMIO,  0x72, \
+				       struct kvm_assigned_pci_dev)
+#define KVM_ASSIGN_SET_MSIX_NR    _IOW(KVMIO,  0x73, \
+				       struct kvm_assigned_msix_nr)
+#define KVM_ASSIGN_SET_MSIX_ENTRY _IOW(KVMIO,  0x74, \
+				       struct kvm_assigned_msix_entry)
+#define KVM_DEASSIGN_DEV_IRQ      _IOW(KVMIO,  0x75, struct kvm_assigned_irq)
+#define KVM_IRQFD                 _IOW(KVMIO,  0x76, struct kvm_irqfd)
+#define KVM_CREATE_PIT2		  _IOW(KVMIO,  0x77, struct kvm_pit_config)
+#define KVM_SET_BOOT_CPU_ID       _IO(KVMIO,   0x78)
+#define KVM_IOEVENTFD             _IOW(KVMIO,  0x79, struct kvm_ioeventfd)
+#define KVM_XEN_HVM_CONFIG        _IOW(KVMIO,  0x7a, struct kvm_xen_hvm_config)
+#define KVM_SET_CLOCK             _IOW(KVMIO,  0x7b, struct kvm_clock_data)
+#define KVM_GET_CLOCK             _IOR(KVMIO,  0x7c, struct kvm_clock_data)
+/* Available with KVM_CAP_PIT_STATE2 */
+#define KVM_GET_PIT2              _IOR(KVMIO,  0x9f, struct kvm_pit_state2)
+#define KVM_SET_PIT2              _IOW(KVMIO,  0xa0, struct kvm_pit_state2)
+/* Available with KVM_CAP_PPC_GET_PVINFO */
+#define KVM_PPC_GET_PVINFO	  _IOW(KVMIO,  0xa1, struct kvm_ppc_pvinfo)
+/* Available with KVM_CAP_TSC_CONTROL */
+#define KVM_SET_TSC_KHZ           _IO(KVMIO,  0xa2)
+#define KVM_GET_TSC_KHZ           _IO(KVMIO,  0xa3)
+
+/*
+ * ioctls for vcpu fds
+ */
+#define KVM_RUN                   _IO(KVMIO,   0x80)
+#define KVM_GET_REGS              _IOR(KVMIO,  0x81, struct kvm_regs)
+#define KVM_SET_REGS              _IOW(KVMIO,  0x82, struct kvm_regs)
+#define KVM_GET_SREGS             _IOR(KVMIO,  0x83, struct kvm_sregs)
+#define KVM_SET_SREGS             _IOW(KVMIO,  0x84, struct kvm_sregs)
+#define KVM_TRANSLATE             _IOWR(KVMIO, 0x85, struct kvm_translation)
+#define KVM_INTERRUPT             _IOW(KVMIO,  0x86, struct kvm_interrupt)
+/* KVM_DEBUG_GUEST is no longer supported, use KVM_SET_GUEST_DEBUG instead */
+#define KVM_DEBUG_GUEST           __KVM_DEPRECATED_VCPU_W_0x87
+#define KVM_GET_MSRS              _IOWR(KVMIO, 0x88, struct kvm_msrs)
+#define KVM_SET_MSRS              _IOW(KVMIO,  0x89, struct kvm_msrs)
+#define KVM_SET_CPUID             _IOW(KVMIO,  0x8a, struct kvm_cpuid)
+#define KVM_SET_SIGNAL_MASK       _IOW(KVMIO,  0x8b, struct kvm_signal_mask)
+#define KVM_GET_FPU               _IOR(KVMIO,  0x8c, struct kvm_fpu)
+#define KVM_SET_FPU               _IOW(KVMIO,  0x8d, struct kvm_fpu)
+#define KVM_GET_LAPIC             _IOR(KVMIO,  0x8e, struct kvm_lapic_state)
+#define KVM_SET_LAPIC             _IOW(KVMIO,  0x8f, struct kvm_lapic_state)
+#define KVM_SET_CPUID2            _IOW(KVMIO,  0x90, struct kvm_cpuid2)
+#define KVM_GET_CPUID2            _IOWR(KVMIO, 0x91, struct kvm_cpuid2)
+/* Available with KVM_CAP_VAPIC */
+#define KVM_TPR_ACCESS_REPORTING  _IOWR(KVMIO, 0x92, struct kvm_tpr_access_ctl)
+/* Available with KVM_CAP_VAPIC */
+#define KVM_SET_VAPIC_ADDR        _IOW(KVMIO,  0x93, struct kvm_vapic_addr)
+/* valid for virtual machine (for floating interrupt)_and_ vcpu */
+#define KVM_S390_INTERRUPT        _IOW(KVMIO,  0x94, struct kvm_s390_interrupt)
+/* store status for s390 */
+#define KVM_S390_STORE_STATUS_NOADDR    (-1ul)
+#define KVM_S390_STORE_STATUS_PREFIXED  (-2ul)
+#define KVM_S390_STORE_STATUS	  _IOW(KVMIO,  0x95, unsigned long)
+/* initial ipl psw for s390 */
+#define KVM_S390_SET_INITIAL_PSW  _IOW(KVMIO,  0x96, struct kvm_s390_psw)
+/* initial reset for s390 */
+#define KVM_S390_INITIAL_RESET    _IO(KVMIO,   0x97)
+#define KVM_GET_MP_STATE          _IOR(KVMIO,  0x98, struct kvm_mp_state)
+#define KVM_SET_MP_STATE          _IOW(KVMIO,  0x99, struct kvm_mp_state)
+/* Available with KVM_CAP_NMI */
+#define KVM_NMI                   _IO(KVMIO,   0x9a)
+/* Available with KVM_CAP_SET_GUEST_DEBUG */
+#define KVM_SET_GUEST_DEBUG       _IOW(KVMIO,  0x9b, struct kvm_guest_debug)
+/* MCE for x86 */
+#define KVM_X86_SETUP_MCE         _IOW(KVMIO,  0x9c, __u64)
+#define KVM_X86_GET_MCE_CAP_SUPPORTED _IOR(KVMIO,  0x9d, __u64)
+#define KVM_X86_SET_MCE           _IOW(KVMIO,  0x9e, struct kvm_x86_mce)
+/* IA64 stack access */
+#define KVM_IA64_VCPU_GET_STACK   _IOR(KVMIO,  0x9a, void *)
+#define KVM_IA64_VCPU_SET_STACK   _IOW(KVMIO,  0x9b, void *)
+/* Available with KVM_CAP_VCPU_EVENTS */
+#define KVM_GET_VCPU_EVENTS       _IOR(KVMIO,  0x9f, struct kvm_vcpu_events)
+#define KVM_SET_VCPU_EVENTS       _IOW(KVMIO,  0xa0, struct kvm_vcpu_events)
+/* Available with KVM_CAP_DEBUGREGS */
+#define KVM_GET_DEBUGREGS         _IOR(KVMIO,  0xa1, struct kvm_debugregs)
+#define KVM_SET_DEBUGREGS         _IOW(KVMIO,  0xa2, struct kvm_debugregs)
+#define KVM_ENABLE_CAP            _IOW(KVMIO,  0xa3, struct kvm_enable_cap)
+/* Available with KVM_CAP_XSAVE */
+#define KVM_GET_XSAVE		  _IOR(KVMIO,  0xa4, struct kvm_xsave)
+#define KVM_SET_XSAVE		  _IOW(KVMIO,  0xa5, struct kvm_xsave)
+/* Available with KVM_CAP_XCRS */
+#define KVM_GET_XCRS		  _IOR(KVMIO,  0xa6, struct kvm_xcrs)
+#define KVM_SET_XCRS		  _IOW(KVMIO,  0xa7, struct kvm_xcrs)
+
+#define KVM_DEV_ASSIGN_ENABLE_IOMMU	(1 << 0)
+
+struct kvm_assigned_pci_dev {
+	__u32 assigned_dev_id;
+	__u32 busnr;
+	__u32 devfn;
+	__u32 flags;
+	__u32 segnr;
+	union {
+		__u32 reserved[11];
+	};
+};
+
+#define KVM_DEV_IRQ_HOST_INTX    (1 << 0)
+#define KVM_DEV_IRQ_HOST_MSI     (1 << 1)
+#define KVM_DEV_IRQ_HOST_MSIX    (1 << 2)
+
+#define KVM_DEV_IRQ_GUEST_INTX   (1 << 8)
+#define KVM_DEV_IRQ_GUEST_MSI    (1 << 9)
+#define KVM_DEV_IRQ_GUEST_MSIX   (1 << 10)
+
+#define KVM_DEV_IRQ_HOST_MASK	 0x00ff
+#define KVM_DEV_IRQ_GUEST_MASK   0xff00
+
+struct kvm_assigned_irq {
+	__u32 assigned_dev_id;
+	__u32 host_irq;
+	__u32 guest_irq;
+	__u32 flags;
+	union {
+		struct {
+			__u32 addr_lo;
+			__u32 addr_hi;
+			__u32 data;
+		} guest_msi;
+		__u32 reserved[12];
+	};
+};
+
+
+struct kvm_assigned_msix_nr {
+	__u32 assigned_dev_id;
+	__u16 entry_nr;
+	__u16 padding;
+};
+
+#define KVM_MAX_MSIX_PER_DEV		256
+struct kvm_assigned_msix_entry {
+	__u32 assigned_dev_id;
+	__u32 gsi;
+	__u16 entry; /* The index of entry in the MSI-X table */
+	__u16 padding[3];
+};
+
+#endif /* __LINUX_KVM_H */
diff --git a/linux-headers/linux/kvm_para.h b/linux-headers/linux/kvm_para.h
new file mode 100644
index 0000000..7bdcf93
--- /dev/null
+++ b/linux-headers/linux/kvm_para.h
@@ -0,0 +1,28 @@
+#ifndef __LINUX_KVM_PARA_H
+#define __LINUX_KVM_PARA_H
+
+/*
+ * This header file provides a method for making a hypercall to the host
+ * Architectures should define:
+ * - kvm_hypercall0, kvm_hypercall1...
+ * - kvm_arch_para_features
+ * - kvm_para_available
+ */
+
+/* Return values for hypercalls */
+#define KVM_ENOSYS		1000
+#define KVM_EFAULT		EFAULT
+#define KVM_E2BIG		E2BIG
+#define KVM_EPERM		EPERM
+
+#define KVM_HC_VAPIC_POLL_IRQ		1
+#define KVM_HC_MMU_OP			2
+#define KVM_HC_FEATURES			3
+#define KVM_HC_PPC_MAP_MAGIC_PAGE	4
+
+/*
+ * hypercalls use architecture specific
+ */
+#include <asm/kvm_para.h>
+
+#endif /* __LINUX_KVM_PARA_H */
diff --git a/linux-headers/linux/vhost.h b/linux-headers/linux/vhost.h
new file mode 100644
index 0000000..165a484
--- /dev/null
+++ b/linux-headers/linux/vhost.h
@@ -0,0 +1,130 @@
+#ifndef _LINUX_VHOST_H
+#define _LINUX_VHOST_H
+/* Userspace interface for in-kernel virtio accelerators. */
+
+/* vhost is used to reduce the number of system calls involved in virtio.
+ *
+ * Existing virtio net code is used in the guest without modification.
+ *
+ * This header includes interface used by userspace hypervisor for
+ * device configuration.
+ */
+
+#include <linux/types.h>
+
+#include <linux/ioctl.h>
+#include <linux/virtio_config.h>
+#include <linux/virtio_ring.h>
+
+struct vhost_vring_state {
+	unsigned int index;
+	unsigned int num;
+};
+
+struct vhost_vring_file {
+	unsigned int index;
+	int fd; /* Pass -1 to unbind from file. */
+
+};
+
+struct vhost_vring_addr {
+	unsigned int index;
+	/* Option flags. */
+	unsigned int flags;
+	/* Flag values: */
+	/* Whether log address is valid. If set enables logging. */
+#define VHOST_VRING_F_LOG 0
+
+	/* Start of array of descriptors (virtually contiguous) */
+	__u64 desc_user_addr;
+	/* Used structure address. Must be 32 bit aligned */
+	__u64 used_user_addr;
+	/* Available structure address. Must be 16 bit aligned */
+	__u64 avail_user_addr;
+	/* Logging support. */
+	/* Log writes to used structure, at offset calculated from specified
+	 * address. Address must be 32 bit aligned. */
+	__u64 log_guest_addr;
+};
+
+struct vhost_memory_region {
+	__u64 guest_phys_addr;
+	__u64 memory_size; /* bytes */
+	__u64 userspace_addr;
+	__u64 flags_padding; /* No flags are currently specified. */
+};
+
+/* All region addresses and sizes must be 4K aligned. */
+#define VHOST_PAGE_SIZE 0x1000
+
+struct vhost_memory {
+	__u32 nregions;
+	__u32 padding;
+	struct vhost_memory_region regions[0];
+};
+
+/* ioctls */
+
+#define VHOST_VIRTIO 0xAF
+
+/* Features bitmask for forward compatibility.  Transport bits are used for
+ * vhost specific features. */
+#define VHOST_GET_FEATURES	_IOR(VHOST_VIRTIO, 0x00, __u64)
+#define VHOST_SET_FEATURES	_IOW(VHOST_VIRTIO, 0x00, __u64)
+
+/* Set current process as the (exclusive) owner of this file descriptor.  This
+ * must be called before any other vhost command.  Further calls to
+ * VHOST_OWNER_SET fail until VHOST_OWNER_RESET is called. */
+#define VHOST_SET_OWNER _IO(VHOST_VIRTIO, 0x01)
+/* Give up ownership, and reset the device to default values.
+ * Allows subsequent call to VHOST_OWNER_SET to succeed. */
+#define VHOST_RESET_OWNER _IO(VHOST_VIRTIO, 0x02)
+
+/* Set up/modify memory layout */
+#define VHOST_SET_MEM_TABLE	_IOW(VHOST_VIRTIO, 0x03, struct vhost_memory)
+
+/* Write logging setup. */
+/* Memory writes can optionally be logged by setting bit at an offset
+ * (calculated from the physical address) from specified log base.
+ * The bit is set using an atomic 32 bit operation. */
+/* Set base address for logging. */
+#define VHOST_SET_LOG_BASE _IOW(VHOST_VIRTIO, 0x04, __u64)
+/* Specify an eventfd file descriptor to signal on log write. */
+#define VHOST_SET_LOG_FD _IOW(VHOST_VIRTIO, 0x07, int)
+
+/* Ring setup. */
+/* Set number of descriptors in ring. This parameter can not
+ * be modified while ring is running (bound to a device). */
+#define VHOST_SET_VRING_NUM _IOW(VHOST_VIRTIO, 0x10, struct vhost_vring_state)
+/* Set addresses for the ring. */
+#define VHOST_SET_VRING_ADDR _IOW(VHOST_VIRTIO, 0x11, struct vhost_vring_addr)
+/* Base value where queue looks for available descriptors */
+#define VHOST_SET_VRING_BASE _IOW(VHOST_VIRTIO, 0x12, struct vhost_vring_state)
+/* Get accessor: reads index, writes value in num */
+#define VHOST_GET_VRING_BASE _IOWR(VHOST_VIRTIO, 0x12, struct vhost_vring_state)
+
+/* The following ioctls use eventfd file descriptors to signal and poll
+ * for events. */
+
+/* Set eventfd to poll for added buffers */
+#define VHOST_SET_VRING_KICK _IOW(VHOST_VIRTIO, 0x20, struct vhost_vring_file)
+/* Set eventfd to signal when buffers have beed used */
+#define VHOST_SET_VRING_CALL _IOW(VHOST_VIRTIO, 0x21, struct vhost_vring_file)
+/* Set eventfd to signal an error */
+#define VHOST_SET_VRING_ERR _IOW(VHOST_VIRTIO, 0x22, struct vhost_vring_file)
+
+/* VHOST_NET specific defines */
+
+/* Attach virtio net ring to a raw socket, or tap device.
+ * The socket must be already bound to an ethernet device, this device will be
+ * used for transmit.  Pass fd -1 to unbind from the socket and the transmit
+ * device.  This can be used to stop the ring (e.g. for migration). */
+#define VHOST_NET_SET_BACKEND _IOW(VHOST_VIRTIO, 0x30, struct vhost_vring_file)
+
+/* Feature bits */
+/* Log all write descriptors. Can be changed while device is active. */
+#define VHOST_F_LOG_ALL 26
+/* vhost-net should add virtio_net_hdr for RX, and strip for TX packets. */
+#define VHOST_NET_F_VIRTIO_NET_HDR 27
+
+#endif
diff --git a/linux-headers/linux/virtio_config.h b/linux-headers/linux/virtio_config.h
new file mode 100644
index 0000000..4f51d8f
--- /dev/null
+++ b/linux-headers/linux/virtio_config.h
@@ -0,0 +1,54 @@
+#ifndef _LINUX_VIRTIO_CONFIG_H
+#define _LINUX_VIRTIO_CONFIG_H
+/* This header, excluding the #ifdef __KERNEL__ part, is BSD licensed so
+ * anyone can use the definitions to implement compatible drivers/servers.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. 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.
+ * 3. Neither the name of IBM 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 IBM OR CONTRIBUTORS 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. */
+
+/* Virtio devices use a standardized configuration space to define their
+ * features and pass configuration information, but each implementation can
+ * store and access that space differently. */
+#include <linux/types.h>
+
+/* Status byte for guest to report progress, and synchronize features. */
+/* We have seen device and processed generic fields (VIRTIO_CONFIG_F_VIRTIO) */
+#define VIRTIO_CONFIG_S_ACKNOWLEDGE	1
+/* We have found a driver for the device. */
+#define VIRTIO_CONFIG_S_DRIVER		2
+/* Driver has used its parts of the config, and is happy */
+#define VIRTIO_CONFIG_S_DRIVER_OK	4
+/* We've given up on this device. */
+#define VIRTIO_CONFIG_S_FAILED		0x80
+
+/* Some virtio feature bits (currently bits 28 through 31) are reserved for the
+ * transport being used (eg. virtio_ring), the rest are per-device feature
+ * bits. */
+#define VIRTIO_TRANSPORT_F_START	28
+#define VIRTIO_TRANSPORT_F_END		32
+
+/* Do we get callbacks when the ring is completely used, even if we've
+ * suppressed them? */
+#define VIRTIO_F_NOTIFY_ON_EMPTY	24
+
+#endif /* _LINUX_VIRTIO_CONFIG_H */
diff --git a/linux-headers/linux/virtio_ring.h b/linux-headers/linux/virtio_ring.h
new file mode 100644
index 0000000..78289ee
--- /dev/null
+++ b/linux-headers/linux/virtio_ring.h
@@ -0,0 +1,163 @@
+#ifndef _LINUX_VIRTIO_RING_H
+#define _LINUX_VIRTIO_RING_H
+/* An interface for efficient virtio implementation, currently for use by KVM
+ * and lguest, but hopefully others soon.  Do NOT change this since it will
+ * break existing servers and clients.
+ *
+ * This header is BSD licensed so anyone can use the definitions to implement
+ * compatible drivers/servers.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. 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.
+ * 3. Neither the name of IBM 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 IBM OR CONTRIBUTORS 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.
+ *
+ * Copyright Rusty Russell IBM Corporation 2007. */
+#include <linux/types.h>
+
+/* This marks a buffer as continuing via the next field. */
+#define VRING_DESC_F_NEXT	1
+/* This marks a buffer as write-only (otherwise read-only). */
+#define VRING_DESC_F_WRITE	2
+/* This means the buffer contains a list of buffer descriptors. */
+#define VRING_DESC_F_INDIRECT	4
+
+/* The Host uses this in used->flags to advise the Guest: don't kick me when
+ * you add a buffer.  It's unreliable, so it's simply an optimization.  Guest
+ * will still kick if it's out of buffers. */
+#define VRING_USED_F_NO_NOTIFY	1
+/* The Guest uses this in avail->flags to advise the Host: don't interrupt me
+ * when you consume a buffer.  It's unreliable, so it's simply an
+ * optimization.  */
+#define VRING_AVAIL_F_NO_INTERRUPT	1
+
+/* We support indirect buffer descriptors */
+#define VIRTIO_RING_F_INDIRECT_DESC	28
+
+/* The Guest publishes the used index for which it expects an interrupt
+ * at the end of the avail ring. Host should ignore the avail->flags field. */
+/* The Host publishes the avail index for which it expects a kick
+ * at the end of the used ring. Guest should ignore the used->flags field. */
+#define VIRTIO_RING_F_EVENT_IDX		29
+
+/* Virtio ring descriptors: 16 bytes.  These can chain together via "next". */
+struct vring_desc {
+	/* Address (guest-physical). */
+	__u64 addr;
+	/* Length. */
+	__u32 len;
+	/* The flags as indicated above. */
+	__u16 flags;
+	/* We chain unused descriptors via this, too */
+	__u16 next;
+};
+
+struct vring_avail {
+	__u16 flags;
+	__u16 idx;
+	__u16 ring[];
+};
+
+/* u32 is used here for ids for padding reasons. */
+struct vring_used_elem {
+	/* Index of start of used descriptor chain. */
+	__u32 id;
+	/* Total length of the descriptor chain which was used (written to) */
+	__u32 len;
+};
+
+struct vring_used {
+	__u16 flags;
+	__u16 idx;
+	struct vring_used_elem ring[];
+};
+
+struct vring {
+	unsigned int num;
+
+	struct vring_desc *desc;
+
+	struct vring_avail *avail;
+
+	struct vring_used *used;
+};
+
+/* The standard layout for the ring is a continuous chunk of memory which looks
+ * like this.  We assume num is a power of 2.
+ *
+ * struct vring
+ * {
+ *	// The actual descriptors (16 bytes each)
+ *	struct vring_desc desc[num];
+ *
+ *	// A ring of available descriptor heads with free-running index.
+ *	__u16 avail_flags;
+ *	__u16 avail_idx;
+ *	__u16 available[num];
+ *	__u16 used_event_idx;
+ *
+ *	// Padding to the next align boundary.
+ *	char pad[];
+ *
+ *	// A ring of used descriptor heads with free-running index.
+ *	__u16 used_flags;
+ *	__u16 used_idx;
+ *	struct vring_used_elem used[num];
+ *	__u16 avail_event_idx;
+ * };
+ */
+/* We publish the used event index at the end of the available ring, and vice
+ * versa. They are at the end for backwards compatibility. */
+#define vring_used_event(vr) ((vr)->avail->ring[(vr)->num])
+#define vring_avail_event(vr) (*(__u16 *)&(vr)->used->ring[(vr)->num])
+
+static __inline__ void vring_init(struct vring *vr, unsigned int num, void *p,
+			      unsigned long align)
+{
+	vr->num = num;
+	vr->desc = p;
+	vr->avail = p + num*sizeof(struct vring_desc);
+	vr->used = (void *)(((unsigned long)&vr->avail->ring[num] + align-1)
+			    & ~(align - 1));
+}
+
+static __inline__ unsigned vring_size(unsigned int num, unsigned long align)
+{
+	return ((sizeof(struct vring_desc) * num + sizeof(__u16) * (2 + num)
+		 + align - 1) & ~(align - 1))
+		+ sizeof(__u16) * 3 + sizeof(struct vring_used_elem) * num;
+}
+
+/* The following is used with USED_EVENT_IDX and AVAIL_EVENT_IDX */
+/* Assuming a given event_idx value from the other size, if
+ * we have just incremented index from old to new_idx,
+ * should we trigger an event? */
+static __inline__ int vring_need_event(__u16 event_idx, __u16 new_idx, __u16 old)
+{
+	/* Note: Xen has similar logic for notification hold-off
+	 * in include/xen/interface/io/ring.h with req_event and req_prod
+	 * corresponding to event_idx + 1 and new_idx respectively.
+	 * Note also that req_event and req_prod in Xen start at 1,
+	 * event indexes in virtio start at 0. */
+	return (__u16)(new_idx - event_idx - 1) < (__u16)(new_idx - old);
+}
+
+#endif /* _LINUX_VIRTIO_RING_H */
commit 87fdd47668895c2eb968000aa82eaa3b2cbaff63
Author: Jan Kiszka <jan.kiszka at siemens.com>
Date:   Wed Jun 8 18:22:17 2011 +0200

    Add kernel header update script
    
    This helper pulls the required kernel headers for KVM and vhost into a
    specified directory. The update is triggered via
    
        scripts/update-linux-headers.sh LINUX_PATH
    
    and will place the output under linux-headers/linux and linux-headers/asm-*.
    It also imports the COPYING to care for headers without an explicit license.
    
    CC: Alexander Graf <agraf at suse.de>
    CC: Christoph Hellwig <hch at lst.de>
    CC: Peter Maydell <peter.maydell at linaro.org>
    CC: Andreas Färber <andreas.faerber at web.de>
    Signed-off-by: Jan Kiszka <jan.kiszka at siemens.com>
    Reviewed-by: Peter Maydell <peter.maydell at linaro.org>
    Signed-off-by: Marcelo Tosatti <mtosatti at redhat.com>

diff --git a/linux-headers/README b/linux-headers/README
new file mode 100644
index 0000000..5c9026b
--- /dev/null
+++ b/linux-headers/README
@@ -0,0 +1,2 @@
+Automatically imported Linux kernel headers.
+Only use scripts/update-linux-headers.sh to update!
diff --git a/scripts/update-linux-headers.sh b/scripts/update-linux-headers.sh
new file mode 100755
index 0000000..9d2a4bc
--- /dev/null
+++ b/scripts/update-linux-headers.sh
@@ -0,0 +1,55 @@
+#!/bin/sh -e
+#
+# Update Linux kernel headers QEMU requires from a specified kernel tree.
+#
+# Copyright (C) 2011 Siemens AG
+#
+# Authors:
+#  Jan Kiszka        <jan.kiszka at siemens.com>
+#
+# This work is licensed under the terms of the GNU GPL version 2.
+# See the COPYING file in the top-level directory.
+
+tmpdir=`mktemp -d`
+linux="$1"
+output="$2"
+
+if [ -z "$linux" ] || ! [ -d "$linux" ]; then
+    cat << EOF
+usage: update-kernel-headers.sh LINUX_PATH [OUTPUT_PATH]
+
+LINUX_PATH      Linux kernel directory to obtain the headers from
+OUTPUT_PATH     output directory, usually the qemu source tree (default: $PWD)
+EOF
+    exit 1
+fi
+
+if [ -z "$output" ]; then
+    output="$PWD"
+fi
+
+for arch in x86 powerpc s390; do
+    make -C "$linux" INSTALL_HDR_PATH="$tmpdir" SRCARCH=$arch headers_install
+
+    rm -rf "$output/linux-headers/asm-$arch"
+    mkdir -p "$output/linux-headers/asm-$arch"
+    for header in kvm.h kvm_para.h; do
+        cp "$tmpdir/include/asm/$header" "$output/linux-headers/asm-$arch"
+    done
+    if [ $arch = x86 ]; then
+        cp "$tmpdir/include/asm/hyperv.h" "$output/linux-headers/asm-x86"
+    fi
+done
+
+rm -rf "$output/linux-headers/linux"
+mkdir -p "$output/linux-headers/linux"
+for header in kvm.h kvm_para.h vhost.h virtio_config.h virtio_ring.h; do
+    cp "$tmpdir/include/linux/$header" "$output/linux-headers/linux"
+done
+if [ -L "$linux/source" ]; then
+    cp "$linux/source/COPYING" "$output/linux-headers"
+else
+    cp "$linux/COPYING" "$output/linux-headers"
+fi
+
+rm -rf "$tmpdir"
commit bcd2491a48787542160d75fb7468907971b04478
Author: Frediano Ziglio <freddy77 at gmail.com>
Date:   Mon Jun 20 17:08:57 2011 +0100

    cmd: fix operator precedence
    
    Signed-off-by: Frediano Ziglio <freddy77 at gmail.com>
    Signed-off-by: Stefan Hajnoczi <stefanha at linux.vnet.ibm.com>

diff --git a/cmd.c b/cmd.c
index db2c9c4..ecca167 100644
--- a/cmd.c
+++ b/cmd.c
@@ -486,7 +486,7 @@ timestr(
 			snprintf(ts, size, "%u:%02u.%02u",
 				(unsigned int) MINUTES(tv->tv_sec),
 				(unsigned int) SECONDS(tv->tv_sec),
-				(unsigned int) usec * 100);
+				(unsigned int) (usec * 100));
 			return;
 		}
 		format |= VERBOSE_FIXED_TIME;	/* fallback if hours needed */
@@ -497,9 +497,9 @@ timestr(
 			(unsigned int) HOURS(tv->tv_sec),
 			(unsigned int) MINUTES(tv->tv_sec),
 			(unsigned int) SECONDS(tv->tv_sec),
-			(unsigned int) usec * 100);
+			(unsigned int) (usec * 100));
 	} else {
-		snprintf(ts, size, "0.%04u sec", (unsigned int) usec * 10000);
+		snprintf(ts, size, "0.%04u sec", (unsigned int) (usec * 10000));
 	}
 }
 
commit 77bec68668915cf9cbccf6f869e030b016b31b93
Author: Alexandre Raymond <cerbere at gmail.com>
Date:   Mon Jun 13 22:16:36 2011 -0400

    Fix typo in cpus.c
    
    filed -> failed
    
    Signed-off-by: Alexandre Raymond <cerbere at gmail.com>
    Signed-off-by: Stefan Hajnoczi <stefanha at linux.vnet.ibm.com>

diff --git a/cpus.c b/cpus.c
index 17e96b5..0699f37 100644
--- a/cpus.c
+++ b/cpus.c
@@ -297,7 +297,7 @@ static void qemu_event_increment(void)
 
     /* EAGAIN is fine, a read must be pending.  */
     if (ret < 0 && errno != EAGAIN) {
-        fprintf(stderr, "qemu_event_increment: write() filed: %s\n",
+        fprintf(stderr, "qemu_event_increment: write() failed: %s\n",
                 strerror(errno));
         exit (1);
     }
commit bf79d499828cffc15274da28f8e579e36c086642
Author: Christophe Fergeau <cfergeau at redhat.com>
Date:   Wed Jun 1 14:56:30 2011 +0200

    lsi: Fix unused-but-set-variable warning
    
    This warning is new in gcc 4.6.
    
    Signed-off-by: Christophe Fergeau <cfergeau at redhat.com>
    Acked-by: Paolo Bonzini <pbonzini at redhat.com>
    Signed-off-by: Stefan Hajnoczi <stefanha at linux.vnet.ibm.com>

diff --git a/hw/lsi53c895a.c b/hw/lsi53c895a.c
index 83084b6..90c6cbc 100644
--- a/hw/lsi53c895a.c
+++ b/hw/lsi53c895a.c
@@ -889,7 +889,6 @@ static void lsi_do_msgout(LSIState *s)
     uint8_t msg;
     int len;
     uint32_t current_tag;
-    SCSIDevice *current_dev;
     lsi_request *current_req, *p, *p_next;
     int id;
 
@@ -901,7 +900,6 @@ static void lsi_do_msgout(LSIState *s)
         current_req = lsi_find_by_tag(s, current_tag);
     }
     id = (current_tag >> 8) & 0xf;
-    current_dev = s->bus.devs[id];
 
     DPRINTF("MSG out len=%d\n", s->dbc);
     while (s->dbc) {
commit 9a826d7854baf6b90de46fea785d1bfc5d2c22a7
Author: Mike McCormack <mj.mccormack at samsung.com>
Date:   Wed Jun 1 15:14:37 2011 +0900

    Don't translate pointer when in restore_sigcontext
    
    Fixes crash in i386 when user emulation base address is non-zero.
    
    21797 rt_sigreturn(8,1082124603,1,0,1082126048,1082126248)Exit reason and status: signal 11
    
    Signed-off-by: Mike McCormack <mj.mccormack at samsung.com>
    Signed-off-by: Riku Voipio <riku.voipio at iki.fi>

diff --git a/linux-user/signal.c b/linux-user/signal.c
index 11b25be..cb7138f 100644
--- a/linux-user/signal.c
+++ b/linux-user/signal.c
@@ -981,8 +981,8 @@ restore_sigcontext(CPUX86State *env, struct target_sigcontext *sc, int *peax)
         env->regs[R_ECX] = tswapl(sc->ecx);
         env->eip = tswapl(sc->eip);
 
-        cpu_x86_load_seg(env, R_CS, lduw(&sc->cs) | 3);
-        cpu_x86_load_seg(env, R_SS, lduw(&sc->ss) | 3);
+        cpu_x86_load_seg(env, R_CS, lduw_p(&sc->cs) | 3);
+        cpu_x86_load_seg(env, R_SS, lduw_p(&sc->ss) | 3);
 
         tmpflags = tswapl(sc->eflags);
         env->eflags = (env->eflags & ~0x40DD5) | (tmpflags & 0x40DD5);
commit 42cc8fa620cbc73e349e96d84cf46469e828ec34
Author: Jan Kiszka <jan.kiszka at siemens.com>
Date:   Wed Jun 15 15:17:26 2011 +0200

    kvm: x86: Save/restore FPU OP, IP and DP
    
    These FPU states are properly maintained by KVM but not yet by TCG. So
    far we unconditionally set them to 0 in the guest which may cause
    state corruptions, though not with modern guests.
    
    To avoid breaking backward migration, use a conditional subsection that
    is only written if any of the three fields is non-zero. The guest's
    FNINIT clears them frequently, and cleared IA32_MISC_ENABLE MSR[2]
    reduces the probability of non-zero values further so that this
    subsection is not expected to restrict migration in any common scenario.
    
    Signed-off-by: Jan Kiszka <jan.kiszka at siemens.com>
    Signed-off-by: Avi Kivity <avi at redhat.com>

diff --git a/target-i386/cpu.h b/target-i386/cpu.h
index 9c3340d..cdf68ff 100644
--- a/target-i386/cpu.h
+++ b/target-i386/cpu.h
@@ -641,6 +641,10 @@ typedef struct CPUX86State {
     uint16_t fpuc;
     uint8_t fptags[8];   /* 0 = valid, 1 = empty */
     FPReg fpregs[8];
+    /* KVM-only so far */
+    uint16_t fpop;
+    uint64_t fpip;
+    uint64_t fpdp;
 
     /* emulator internal variables */
     float_status fp_status;
diff --git a/target-i386/kvm.c b/target-i386/kvm.c
index 1ae2d61..16e8213 100644
--- a/target-i386/kvm.c
+++ b/target-i386/kvm.c
@@ -753,6 +753,9 @@ static int kvm_put_fpu(CPUState *env)
     fpu.fsw = env->fpus & ~(7 << 11);
     fpu.fsw |= (env->fpstt & 7) << 11;
     fpu.fcw = env->fpuc;
+    fpu.last_opcode = env->fpop;
+    fpu.last_ip = env->fpip;
+    fpu.last_dp = env->fpdp;
     for (i = 0; i < 8; ++i) {
         fpu.ftwx |= (!env->fptags[i]) << i;
     }
@@ -778,7 +781,7 @@ static int kvm_put_xsave(CPUState *env)
 #ifdef KVM_CAP_XSAVE
     int i, r;
     struct kvm_xsave* xsave;
-    uint16_t cwd, swd, twd, fop;
+    uint16_t cwd, swd, twd;
 
     if (!kvm_has_xsave()) {
         return kvm_put_fpu(env);
@@ -786,7 +789,7 @@ static int kvm_put_xsave(CPUState *env)
 
     xsave = qemu_memalign(4096, sizeof(struct kvm_xsave));
     memset(xsave, 0, sizeof(struct kvm_xsave));
-    cwd = swd = twd = fop = 0;
+    cwd = swd = twd = 0;
     swd = env->fpus & ~(7 << 11);
     swd |= (env->fpstt & 7) << 11;
     cwd = env->fpuc;
@@ -794,7 +797,9 @@ static int kvm_put_xsave(CPUState *env)
         twd |= (!env->fptags[i]) << i;
     }
     xsave->region[0] = (uint32_t)(swd << 16) + cwd;
-    xsave->region[1] = (uint32_t)(fop << 16) + twd;
+    xsave->region[1] = (uint32_t)(env->fpop << 16) + twd;
+    memcpy(&xsave->region[XSAVE_CWD_RIP], &env->fpip, sizeof(env->fpip));
+    memcpy(&xsave->region[XSAVE_CWD_RDP], &env->fpdp, sizeof(env->fpdp));
     memcpy(&xsave->region[XSAVE_ST_SPACE], env->fpregs,
             sizeof env->fpregs);
     memcpy(&xsave->region[XSAVE_XMM_SPACE], env->xmm_regs,
@@ -970,6 +975,9 @@ static int kvm_get_fpu(CPUState *env)
     env->fpstt = (fpu.fsw >> 11) & 7;
     env->fpus = fpu.fsw;
     env->fpuc = fpu.fcw;
+    env->fpop = fpu.last_opcode;
+    env->fpip = fpu.last_ip;
+    env->fpdp = fpu.last_dp;
     for (i = 0; i < 8; ++i) {
         env->fptags[i] = !((fpu.ftwx >> i) & 1);
     }
@@ -985,7 +993,7 @@ static int kvm_get_xsave(CPUState *env)
 #ifdef KVM_CAP_XSAVE
     struct kvm_xsave* xsave;
     int ret, i;
-    uint16_t cwd, swd, twd, fop;
+    uint16_t cwd, swd, twd;
 
     if (!kvm_has_xsave()) {
         return kvm_get_fpu(env);
@@ -1001,13 +1009,15 @@ static int kvm_get_xsave(CPUState *env)
     cwd = (uint16_t)xsave->region[0];
     swd = (uint16_t)(xsave->region[0] >> 16);
     twd = (uint16_t)xsave->region[1];
-    fop = (uint16_t)(xsave->region[1] >> 16);
+    env->fpop = (uint16_t)(xsave->region[1] >> 16);
     env->fpstt = (swd >> 11) & 7;
     env->fpus = swd;
     env->fpuc = cwd;
     for (i = 0; i < 8; ++i) {
         env->fptags[i] = !((twd >> i) & 1);
     }
+    memcpy(&env->fpip, &xsave->region[XSAVE_CWD_RIP], sizeof(env->fpip));
+    memcpy(&env->fpdp, &xsave->region[XSAVE_CWD_RDP], sizeof(env->fpdp));
     env->mxcsr = xsave->region[XSAVE_MXCSR];
     memcpy(env->fpregs, &xsave->region[XSAVE_ST_SPACE],
             sizeof env->fpregs);
diff --git a/target-i386/machine.c b/target-i386/machine.c
index bbeae88..d22a731 100644
--- a/target-i386/machine.c
+++ b/target-i386/machine.c
@@ -290,6 +290,26 @@ static const VMStateDescription vmstate_async_pf_msr = {
     }
 };
 
+static bool fpop_ip_dp_needed(void *opaque)
+{
+    CPUState *env = opaque;
+
+    return env->fpop != 0 || env->fpip != 0 || env->fpdp != 0;
+}
+
+static const VMStateDescription vmstate_fpop_ip_dp = {
+    .name = "cpu/fpop_ip_dp",
+    .version_id = 1,
+    .minimum_version_id = 1,
+    .minimum_version_id_old = 1,
+    .fields      = (VMStateField []) {
+        VMSTATE_UINT16_V(fpop, CPUState, 13),
+        VMSTATE_UINT64_V(fpip, CPUState, 13),
+        VMSTATE_UINT64_V(fpdp, CPUState, 13),
+        VMSTATE_END_OF_LIST()
+    }
+};
+
 static const VMStateDescription vmstate_cpu = {
     .name = "cpu",
     .version_id = CPU_SAVE_VERSION,
@@ -398,6 +418,9 @@ static const VMStateDescription vmstate_cpu = {
             .vmsd = &vmstate_async_pf_msr,
             .needed = async_pf_msr_needed,
         } , {
+            .vmsd = &vmstate_fpop_ip_dp,
+            .needed = fpop_ip_dp_needed,
+        } , {
             /* empty */
         }
     }
commit 01195b7347e341a49fa554959882b26c666a3616
Author: Steven Smith <ssmith at xensource.com>
Date:   Thu Jun 16 17:05:17 2011 +0100

    xen: Add the Xen platform pci device
    
    Introduce a new emulated PCI device, specific to fully virtualized Xen
    guests.  The device is necessary for PV on HVM drivers to work.
    
    Signed-off-by: Steven Smith <ssmith at xensource.com>
    Signed-off-by: Anthony PERARD <anthony.perard at citrix.com>
    Signed-off-by: Stefano Stabellini <stefano.stabellini at eu.citrix.com>
    Signed-off-by: Alexander Graf <agraf at suse.de>

diff --git a/Makefile.target b/Makefile.target
index b1a0f6d..760aa02 100644
--- a/Makefile.target
+++ b/Makefile.target
@@ -218,6 +218,8 @@ obj-$(CONFIG_NO_XEN) += xen-stub.o
 obj-i386-$(CONFIG_XEN_MAPCACHE) += xen-mapcache.o
 obj-$(CONFIG_NO_XEN_MAPCACHE) += xen-mapcache-stub.o
 
+obj-i386-$(CONFIG_XEN) += xen_platform.o
+
 # Inter-VM PCI shared memory
 CONFIG_IVSHMEM =
 ifeq ($(CONFIG_KVM), y)
diff --git a/hw/hw.h b/hw/hw.h
index 56447a7..9dd7096 100644
--- a/hw/hw.h
+++ b/hw/hw.h
@@ -780,6 +780,9 @@ extern const VMStateDescription vmstate_ptimer;
 #define VMSTATE_INT32_LE(_f, _s)                                   \
     VMSTATE_SINGLE(_f, _s, 0, vmstate_info_int32_le, int32_t)
 
+#define VMSTATE_UINT8_TEST(_f, _s, _t)                               \
+    VMSTATE_SINGLE_TEST(_f, _s, _t, 0, vmstate_info_uint8, uint8_t)
+
 #define VMSTATE_UINT16_TEST(_f, _s, _t)                               \
     VMSTATE_SINGLE_TEST(_f, _s, _t, 0, vmstate_info_uint16, uint16_t)
 
diff --git a/hw/pc_piix.c b/hw/pc_piix.c
index ba198de..8dbeb0c 100644
--- a/hw/pc_piix.c
+++ b/hw/pc_piix.c
@@ -136,6 +136,10 @@ static void pc_init1(ram_addr_t ram_size,
 
     pc_vga_init(pci_enabled? pci_bus: NULL);
 
+    if (xen_enabled()) {
+        pci_create_simple(pci_bus, -1, "xen-platform");
+    }
+
     /* init basic PC hardware */
     pc_basic_device_init(isa_irq, &rtc_state, xen_enabled());
 
diff --git a/hw/pci_ids.h b/hw/pci_ids.h
index d9457ed..d94578c 100644
--- a/hw/pci_ids.h
+++ b/hw/pci_ids.h
@@ -109,3 +109,5 @@
 #define PCI_DEVICE_ID_INTEL_82371AB      0x7111
 #define PCI_DEVICE_ID_INTEL_82371AB_2    0x7112
 #define PCI_DEVICE_ID_INTEL_82371AB_3    0x7113
+
+#define PCI_VENDOR_ID_XENSOURCE          0x5853
diff --git a/hw/xen_platform.c b/hw/xen_platform.c
new file mode 100644
index 0000000..b167eee
--- /dev/null
+++ b/hw/xen_platform.c
@@ -0,0 +1,340 @@
+/*
+ * XEN platform pci device, formerly known as the event channel device
+ *
+ * Copyright (c) 2003-2004 Intel Corp.
+ * Copyright (c) 2006 XenSource
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+
+#include <assert.h>
+
+#include "hw.h"
+#include "pc.h"
+#include "pci.h"
+#include "irq.h"
+#include "xen_common.h"
+#include "net.h"
+#include "xen_backend.h"
+#include "rwhandler.h"
+#include "trace.h"
+
+#include <xenguest.h>
+
+//#define DEBUG_PLATFORM
+
+#ifdef DEBUG_PLATFORM
+#define DPRINTF(fmt, ...) do { \
+    fprintf(stderr, "xen_platform: " fmt, ## __VA_ARGS__); \
+} while (0)
+#else
+#define DPRINTF(fmt, ...) do { } while (0)
+#endif
+
+#define PFFLAG_ROM_LOCK 1 /* Sets whether ROM memory area is RW or RO */
+
+typedef struct PCIXenPlatformState {
+    PCIDevice  pci_dev;
+    uint8_t flags; /* used only for version_id == 2 */
+    int drivers_blacklisted;
+    uint16_t driver_product_version;
+
+    /* Log from guest drivers */
+    char log_buffer[4096];
+    int log_buffer_off;
+} PCIXenPlatformState;
+
+#define XEN_PLATFORM_IOPORT 0x10
+
+/* Send bytes to syslog */
+static void log_writeb(PCIXenPlatformState *s, char val)
+{
+    if (val == '\n' || s->log_buffer_off == sizeof(s->log_buffer) - 1) {
+        /* Flush buffer */
+        s->log_buffer[s->log_buffer_off] = 0;
+        trace_xen_platform_log(s->log_buffer);
+        s->log_buffer_off = 0;
+    } else {
+        s->log_buffer[s->log_buffer_off++] = val;
+    }
+}
+
+/* Xen Platform, Fixed IOPort */
+
+static void platform_fixed_ioport_writew(void *opaque, uint32_t addr, uint32_t val)
+{
+    PCIXenPlatformState *s = opaque;
+
+    switch (addr - XEN_PLATFORM_IOPORT) {
+    case 0:
+        /* TODO: */
+        /* Unplug devices.  Value is a bitmask of which devices to
+           unplug, with bit 0 the IDE devices, bit 1 the network
+           devices, and bit 2 the non-primary-master IDE devices. */
+        break;
+    case 2:
+        switch (val) {
+        case 1:
+            DPRINTF("Citrix Windows PV drivers loaded in guest\n");
+            break;
+        case 0:
+            DPRINTF("Guest claimed to be running PV product 0?\n");
+            break;
+        default:
+            DPRINTF("Unknown PV product %d loaded in guest\n", val);
+            break;
+        }
+        s->driver_product_version = val;
+        break;
+    }
+}
+
+static void platform_fixed_ioport_writel(void *opaque, uint32_t addr,
+                                         uint32_t val)
+{
+    switch (addr - XEN_PLATFORM_IOPORT) {
+    case 0:
+        /* PV driver version */
+        break;
+    }
+}
+
+static void platform_fixed_ioport_writeb(void *opaque, uint32_t addr, uint32_t val)
+{
+    PCIXenPlatformState *s = opaque;
+
+    switch (addr - XEN_PLATFORM_IOPORT) {
+    case 0: /* Platform flags */ {
+        hvmmem_type_t mem_type = (val & PFFLAG_ROM_LOCK) ?
+            HVMMEM_ram_ro : HVMMEM_ram_rw;
+        if (xc_hvm_set_mem_type(xen_xc, xen_domid, mem_type, 0xc0, 0x40)) {
+            DPRINTF("unable to change ro/rw state of ROM memory area!\n");
+        } else {
+            s->flags = val & PFFLAG_ROM_LOCK;
+            DPRINTF("changed ro/rw state of ROM memory area. now is %s state.\n",
+                    (mem_type == HVMMEM_ram_ro ? "ro":"rw"));
+        }
+        break;
+    }
+    case 2:
+        log_writeb(s, val);
+        break;
+    }
+}
+
+static uint32_t platform_fixed_ioport_readw(void *opaque, uint32_t addr)
+{
+    PCIXenPlatformState *s = opaque;
+
+    switch (addr - XEN_PLATFORM_IOPORT) {
+    case 0:
+        if (s->drivers_blacklisted) {
+            /* The drivers will recognise this magic number and refuse
+             * to do anything. */
+            return 0xd249;
+        } else {
+            /* Magic value so that you can identify the interface. */
+            return 0x49d2;
+        }
+    default:
+        return 0xffff;
+    }
+}
+
+static uint32_t platform_fixed_ioport_readb(void *opaque, uint32_t addr)
+{
+    PCIXenPlatformState *s = opaque;
+
+    switch (addr - XEN_PLATFORM_IOPORT) {
+    case 0:
+        /* Platform flags */
+        return s->flags;
+    case 2:
+        /* Version number */
+        return 1;
+    default:
+        return 0xff;
+    }
+}
+
+static void platform_fixed_ioport_reset(void *opaque)
+{
+    PCIXenPlatformState *s = opaque;
+
+    platform_fixed_ioport_writeb(s, XEN_PLATFORM_IOPORT, 0);
+}
+
+static void platform_fixed_ioport_init(PCIXenPlatformState* s)
+{
+    register_ioport_write(XEN_PLATFORM_IOPORT, 16, 4, platform_fixed_ioport_writel, s);
+    register_ioport_write(XEN_PLATFORM_IOPORT, 16, 2, platform_fixed_ioport_writew, s);
+    register_ioport_write(XEN_PLATFORM_IOPORT, 16, 1, platform_fixed_ioport_writeb, s);
+    register_ioport_read(XEN_PLATFORM_IOPORT, 16, 2, platform_fixed_ioport_readw, s);
+    register_ioport_read(XEN_PLATFORM_IOPORT, 16, 1, platform_fixed_ioport_readb, s);
+}
+
+/* Xen Platform PCI Device */
+
+static uint32_t xen_platform_ioport_readb(void *opaque, uint32_t addr)
+{
+    addr &= 0xff;
+
+    if (addr == 0) {
+        return platform_fixed_ioport_readb(opaque, XEN_PLATFORM_IOPORT);
+    } else {
+        return ~0u;
+    }
+}
+
+static void xen_platform_ioport_writeb(void *opaque, uint32_t addr, uint32_t val)
+{
+    PCIXenPlatformState *s = opaque;
+
+    addr &= 0xff;
+    val  &= 0xff;
+
+    switch (addr) {
+    case 0: /* Platform flags */
+        platform_fixed_ioport_writeb(opaque, XEN_PLATFORM_IOPORT, val);
+        break;
+    case 8:
+        log_writeb(s, val);
+        break;
+    default:
+        break;
+    }
+}
+
+static void platform_ioport_map(PCIDevice *pci_dev, int region_num, pcibus_t addr, pcibus_t size, int type)
+{
+    PCIXenPlatformState *d = DO_UPCAST(PCIXenPlatformState, pci_dev, pci_dev);
+
+    register_ioport_write(addr, size, 1, xen_platform_ioport_writeb, d);
+    register_ioport_read(addr, size, 1, xen_platform_ioport_readb, d);
+}
+
+static uint32_t platform_mmio_read(ReadWriteHandler *handler, pcibus_t addr, int len)
+{
+    DPRINTF("Warning: attempted read from physical address "
+            "0x" TARGET_FMT_plx " in xen platform mmio space\n", addr);
+
+    return 0;
+}
+
+static void platform_mmio_write(ReadWriteHandler *handler, pcibus_t addr,
+                                uint32_t val, int len)
+{
+    DPRINTF("Warning: attempted write of 0x%x to physical "
+            "address 0x" TARGET_FMT_plx " in xen platform mmio space\n",
+            val, addr);
+}
+
+static ReadWriteHandler platform_mmio_handler = {
+    .read = &platform_mmio_read,
+    .write = &platform_mmio_write,
+};
+
+static void platform_mmio_map(PCIDevice *d, int region_num,
+                              pcibus_t addr, pcibus_t size, int type)
+{
+    int mmio_io_addr;
+
+    mmio_io_addr = cpu_register_io_memory_simple(&platform_mmio_handler,
+                                                 DEVICE_NATIVE_ENDIAN);
+
+    cpu_register_physical_memory(addr, size, mmio_io_addr);
+}
+
+static int xen_platform_post_load(void *opaque, int version_id)
+{
+    PCIXenPlatformState *s = opaque;
+
+    platform_fixed_ioport_writeb(s, XEN_PLATFORM_IOPORT, s->flags);
+
+    return 0;
+}
+
+static const VMStateDescription vmstate_xen_platform = {
+    .name = "platform",
+    .version_id = 4,
+    .minimum_version_id = 4,
+    .minimum_version_id_old = 4,
+    .post_load = xen_platform_post_load,
+    .fields = (VMStateField []) {
+        VMSTATE_PCI_DEVICE(pci_dev, PCIXenPlatformState),
+        VMSTATE_UINT8(flags, PCIXenPlatformState),
+        VMSTATE_END_OF_LIST()
+    }
+};
+
+static int xen_platform_initfn(PCIDevice *dev)
+{
+    PCIXenPlatformState *d = DO_UPCAST(PCIXenPlatformState, pci_dev, dev);
+    uint8_t *pci_conf;
+
+    pci_conf = d->pci_dev.config;
+
+    pci_config_set_vendor_id(pci_conf, PCI_VENDOR_ID_XENSOURCE);
+    pci_config_set_device_id(pci_conf, 0x0001);
+    pci_set_word(pci_conf + PCI_SUBSYSTEM_VENDOR_ID, PCI_VENDOR_ID_XENSOURCE);
+    pci_set_word(pci_conf + PCI_SUBSYSTEM_ID, 0x0001);
+
+    pci_set_word(pci_conf + PCI_COMMAND, PCI_COMMAND_IO | PCI_COMMAND_MEMORY);
+
+    pci_config_set_revision(pci_conf, 1);
+    pci_config_set_prog_interface(pci_conf, 0);
+
+    pci_config_set_class(pci_conf, PCI_CLASS_OTHERS << 8 | 0x80);
+
+    pci_conf[PCI_INTERRUPT_PIN] = 1;
+
+    pci_register_bar(&d->pci_dev, 0, 0x100,
+            PCI_BASE_ADDRESS_SPACE_IO, platform_ioport_map);
+
+    /* reserve 16MB mmio address for share memory*/
+    pci_register_bar(&d->pci_dev, 1, 0x1000000,
+            PCI_BASE_ADDRESS_MEM_PREFETCH, platform_mmio_map);
+
+    platform_fixed_ioport_init(d);
+
+    return 0;
+}
+
+static void platform_reset(DeviceState *dev)
+{
+    PCIXenPlatformState *s = DO_UPCAST(PCIXenPlatformState, pci_dev.qdev, dev);
+
+    platform_fixed_ioport_reset(s);
+}
+
+static PCIDeviceInfo xen_platform_info = {
+    .init = xen_platform_initfn,
+    .qdev.name = "xen-platform",
+    .qdev.desc = "XEN platform pci device",
+    .qdev.size = sizeof(PCIXenPlatformState),
+    .qdev.vmsd = &vmstate_xen_platform,
+    .qdev.reset = platform_reset,
+};
+
+static void xen_platform_register(void)
+{
+    pci_qdev_register(&xen_platform_info);
+}
+
+device_init(xen_platform_register);
diff --git a/trace-events b/trace-events
index 46a19d3..bebf612 100644
--- a/trace-events
+++ b/trace-events
@@ -407,3 +407,6 @@ disable xen_unmap_block(void* addr, unsigned long size) "%p, size %#lx"
 
 # exec.c
 disable qemu_put_ram_ptr(void* addr) "%p"
+
+# hw/xen_platform.c
+disable xen_platform_log(char *s) "xen platform: %s"
commit bf09551a6b2282a1c59bd8335c1ef6e58704de98
Author: Stefano Stabellini <stefano.stabellini at eu.citrix.com>
Date:   Wed Jun 15 17:36:56 2011 +0100

    xen: fix interrupt routing
    
    Compared to the last version I only added a comment to the code.
    
    - remove i440FX-xen and i440fx_write_config_xen
    we don't need to intercept pci config writes to i440FX anymore;
    
    - introduce PIIX3-xen and piix3_write_config_xen
    we do need to intercept pci config write to the PCI-ISA bridge to update
    the PCI link routing;
    
    - set the number of PIIX3-xen interrupts line to 128;
    
    Signed-off-by: Stefano Stabellini <stefano.stabellini at eu.citrix.com>
    Signed-off-by: Alexander Graf <agraf at suse.de>

diff --git a/hw/pc.h b/hw/pc.h
index 0dcbee7..6d5730b 100644
--- a/hw/pc.h
+++ b/hw/pc.h
@@ -176,7 +176,6 @@ struct PCII440FXState;
 typedef struct PCII440FXState PCII440FXState;
 
 PCIBus *i440fx_init(PCII440FXState **pi440fx_state, int *piix_devfn, qemu_irq *pic, ram_addr_t ram_size);
-PCIBus *i440fx_xen_init(PCII440FXState **pi440fx_state, int *piix3_devfn, qemu_irq *pic, ram_addr_t ram_size);
 void i440fx_init_memory_mappings(PCII440FXState *d);
 
 /* piix4.c */
diff --git a/hw/pc_piix.c b/hw/pc_piix.c
index 9a22a8a..ba198de 100644
--- a/hw/pc_piix.c
+++ b/hw/pc_piix.c
@@ -124,11 +124,7 @@ static void pc_init1(ram_addr_t ram_size,
     isa_irq = qemu_allocate_irqs(isa_irq_handler, isa_irq_state, 24);
 
     if (pci_enabled) {
-        if (!xen_enabled()) {
-            pci_bus = i440fx_init(&i440fx_state, &piix3_devfn, isa_irq, ram_size);
-        } else {
-            pci_bus = i440fx_xen_init(&i440fx_state, &piix3_devfn, isa_irq, ram_size);
-        }
+        pci_bus = i440fx_init(&i440fx_state, &piix3_devfn, isa_irq, ram_size);
     } else {
         pci_bus = NULL;
         i440fx_state = NULL;
diff --git a/hw/piix_pci.c b/hw/piix_pci.c
index 85a320e..3e2698d 100644
--- a/hw/piix_pci.c
+++ b/hw/piix_pci.c
@@ -40,6 +40,7 @@ typedef PCIHostState I440FXState;
 
 #define PIIX_NUM_PIC_IRQS       16      /* i8259 * 2 */
 #define PIIX_NUM_PIRQS          4ULL    /* PIRQ[A-D] */
+#define XEN_PIIX_NUM_PIRQS      128ULL
 #define PIIX_PIRQC              0x60
 
 typedef struct PIIX3State {
@@ -78,6 +79,8 @@ struct PCII440FXState {
 #define I440FX_SMRAM    0x72
 
 static void piix3_set_irq(void *opaque, int pirq, int level);
+static void piix3_write_config_xen(PCIDevice *dev,
+                               uint32_t address, uint32_t val, int len);
 
 /* return the global irq number corresponding to a given device irq
    pin. We could also use the bus number to have a more precise
@@ -173,13 +176,6 @@ static void i440fx_write_config(PCIDevice *dev,
     }
 }
 
-static void i440fx_write_config_xen(PCIDevice *dev,
-                                    uint32_t address, uint32_t val, int len)
-{
-    xen_piix_pci_write_config_client(address, val, len);
-    i440fx_write_config(dev, address, val, len);
-}
-
 static int i440fx_load_old(QEMUFile* f, void *opaque, int version_id)
 {
     PCII440FXState *d = opaque;
@@ -267,8 +263,21 @@ static PCIBus *i440fx_common_init(const char *device_name,
     d = pci_create_simple(b, 0, device_name);
     *pi440fx_state = DO_UPCAST(PCII440FXState, dev, d);
 
-    piix3 = DO_UPCAST(PIIX3State, dev,
-                      pci_create_simple_multifunction(b, -1, true, "PIIX3"));
+    /* Xen supports additional interrupt routes from the PCI devices to
+     * the IOAPIC: the four pins of each PCI device on the bus are also
+     * connected to the IOAPIC directly.
+     * These additional routes can be discovered through ACPI. */
+    if (xen_enabled()) {
+        piix3 = DO_UPCAST(PIIX3State, dev,
+                pci_create_simple_multifunction(b, -1, true, "PIIX3-xen"));
+        pci_bus_irqs(b, xen_piix3_set_irq, xen_pci_slot_get_pirq,
+                piix3, XEN_PIIX_NUM_PIRQS);
+    } else {
+        piix3 = DO_UPCAST(PIIX3State, dev,
+                pci_create_simple_multifunction(b, -1, true, "PIIX3"));
+        pci_bus_irqs(b, piix3_set_irq, pci_slot_get_pirq, piix3,
+                PIIX_NUM_PIRQS);
+    }
     piix3->pic = pic;
 
     (*pi440fx_state)->piix3 = piix3;
@@ -289,21 +298,6 @@ PCIBus *i440fx_init(PCII440FXState **pi440fx_state, int *piix3_devfn,
     PCIBus *b;
 
     b = i440fx_common_init("i440FX", pi440fx_state, piix3_devfn, pic, ram_size);
-    pci_bus_irqs(b, piix3_set_irq, pci_slot_get_pirq, (*pi440fx_state)->piix3,
-                 PIIX_NUM_PIRQS);
-
-    return b;
-}
-
-PCIBus *i440fx_xen_init(PCII440FXState **pi440fx_state, int *piix3_devfn,
-                        qemu_irq *pic, ram_addr_t ram_size)
-{
-    PCIBus *b;
-
-    b = i440fx_common_init("i440FX-xen", pi440fx_state, piix3_devfn, pic, ram_size);
-    pci_bus_irqs(b, xen_piix3_set_irq, xen_pci_slot_get_pirq,
-                 (*pi440fx_state)->piix3, PIIX_NUM_PIRQS);
-
     return b;
 }
 
@@ -365,6 +359,13 @@ static void piix3_write_config(PCIDevice *dev,
     }
 }
 
+static void piix3_write_config_xen(PCIDevice *dev,
+                               uint32_t address, uint32_t val, int len)
+{
+    xen_piix_pci_write_config_client(address, val, len);
+    piix3_write_config(dev, address, val, len);
+}
+
 static void piix3_reset(void *opaque)
 {
     PIIX3State *d = opaque;
@@ -465,14 +466,6 @@ static PCIDeviceInfo i440fx_info[] = {
         .init         = i440fx_initfn,
         .config_write = i440fx_write_config,
     },{
-        .qdev.name    = "i440FX-xen",
-        .qdev.desc    = "Host bridge",
-        .qdev.size    = sizeof(PCII440FXState),
-        .qdev.vmsd    = &vmstate_i440fx,
-        .qdev.no_user = 1,
-        .init         = i440fx_initfn,
-        .config_write = i440fx_write_config_xen,
-    },{
         .qdev.name    = "PIIX3",
         .qdev.desc    = "ISA bridge",
         .qdev.size    = sizeof(PIIX3State),
@@ -482,6 +475,15 @@ static PCIDeviceInfo i440fx_info[] = {
         .init         = piix3_initfn,
         .config_write = piix3_write_config,
     },{
+        .qdev.name    = "PIIX3-xen",
+        .qdev.desc    = "ISA bridge",
+        .qdev.size    = sizeof(PIIX3State),
+        .qdev.vmsd    = &vmstate_piix3,
+        .qdev.no_user = 1,
+        .no_hotplug   = 1,
+        .init         = piix3_initfn,
+        .config_write = piix3_write_config_xen,
+    },{
         /* end of list */
     }
 };
commit ebed85058b6e89a5202112e9aa2abab3aa3804c3
Author: Stefano Stabellini <stefano.stabellini at eu.citrix.com>
Date:   Wed Jun 15 17:29:27 2011 +0100

    xen: only track the linear framebuffer
    
    Xen can only do dirty bit tracking for one memory region, so we should
    explicitly avoid trying to track anything but the vga vram region.
    
    Signed-off-by: Stefano Stabellini <stefano.stabellini at eu.citrix.com>
    Signed-off-by: Alexander Graf <agraf at suse.de>

diff --git a/xen-all.c b/xen-all.c
index 75a82c2..fe75ddd 100644
--- a/xen-all.c
+++ b/xen-all.c
@@ -215,6 +215,7 @@ static int xen_add_to_physmap(XenIOState *state,
     int rc = 0;
     XenPhysmap *physmap = NULL;
     target_phys_addr_t pfn, start_gpfn;
+    RAMBlock *block;
 
     if (get_physmapping(state, start_addr, size)) {
         return 0;
@@ -223,6 +224,19 @@ static int xen_add_to_physmap(XenIOState *state,
         return -1;
     }
 
+    /* Xen can only handle a single dirty log region for now and we want
+     * the linear framebuffer to be that region.
+     * Avoid tracking any regions that is not videoram and avoid tracking
+     * the legacy vga region. */
+    QLIST_FOREACH(block, &ram_list.blocks, next) {
+        if (!strcmp(block->idstr, "vga.vram") && block->offset == phys_offset
+                && start_addr > 0xbffff) {
+            goto go_physmap;
+        }
+    }
+    return -1;
+
+go_physmap:
     DPRINTF("mapping vram to %llx - %llx, from %llx\n",
             start_addr, start_addr + size, phys_offset);
 
commit 45dcd36e1ebbb3c085bdd157bffaf9276ffd8c46
Author: Stefano Stabellini <stefano.stabellini at eu.citrix.com>
Date:   Fri Jun 3 16:56:54 2011 +0100

    cirrus_vga: reset lfb_addr after a pci config write if the BAR is unmapped
    
    If the cirrus_vga PCI BAR is unmapped than we should not only reset
    map_addr but also lfb_addr, otherwise we'll keep trying to map
    the old lfb_addr in map_linear_vram.
    
    Signed-off-by: Stefano Stabellini <stefano.stabellini at eu.citrix.com>
    Acked-by: Jan Kiszka <jan.kiszka at siemens.com>
    Signed-off-by: Alexander Graf <agraf at suse.de>

diff --git a/hw/cirrus_vga.c b/hw/cirrus_vga.c
index 722cac7..3c5043e 100644
--- a/hw/cirrus_vga.c
+++ b/hw/cirrus_vga.c
@@ -3088,8 +3088,11 @@ static void pci_cirrus_write_config(PCIDevice *d,
     CirrusVGAState *s = &pvs->cirrus_vga;
 
     pci_default_write_config(d, address, val, len);
-    if (s->vga.map_addr && d->io_regions[0].addr == PCI_BAR_UNMAPPED)
+    if (s->vga.map_addr && d->io_regions[0].addr == PCI_BAR_UNMAPPED) {
         s->vga.map_addr = 0;
+        s->vga.lfb_addr = 0;
+        s->vga.lfb_end = 0;
+    }
     cirrus_update_memory_access(s);
 }
 
commit 712c2b41490a986a5dd99bec99b854bac4322201
Author: Stefano Stabellini <stefano.stabellini at eu.citrix.com>
Date:   Thu May 19 18:35:46 2011 +0100

    xen: mapcache performance improvements
    
    Use qemu_invalidate_entry in cpu_physical_memory_unmap.
    
    Do not lock mapcache entries in qemu_get_ram_ptr if the address falls in
    the ramblock with offset == 0. We don't need to do that because the
    callers of qemu_get_ram_ptr either try to map an entire block, other
    from the main ramblock, or until the end of a page to implement a single
    read or write in the main ramblock.
    If we don't lock mapcache entries in qemu_get_ram_ptr we don't need to
    call qemu_invalidate_entry in qemu_put_ram_ptr anymore because we can
    leave with few long lived block mappings requested by devices.
    
    Also move the call to qemu_ram_addr_from_mapcache at the beginning of
    qemu_ram_addr_from_host.
    
    Signed-off-by: Stefano Stabellini <stefano.stabellini at eu.citrix.com>
    Signed-off-by: Alexander Graf <agraf at suse.de>

diff --git a/exec.c b/exec.c
index 238c173..7f14332 100644
--- a/exec.c
+++ b/exec.c
@@ -3085,9 +3085,10 @@ void *qemu_get_ram_ptr(ram_addr_t addr)
             if (xen_mapcache_enabled()) {
                 /* We need to check if the requested address is in the RAM
                  * because we don't want to map the entire memory in QEMU.
+                 * In that case just map until the end of the page.
                  */
                 if (block->offset == 0) {
-                    return qemu_map_cache(addr, 0, 1);
+                    return qemu_map_cache(addr, 0, 0);
                 } else if (block->host == NULL) {
                     block->host = qemu_map_cache(block->offset, block->length, 1);
                 }
@@ -3114,9 +3115,10 @@ void *qemu_safe_ram_ptr(ram_addr_t addr)
             if (xen_mapcache_enabled()) {
                 /* We need to check if the requested address is in the RAM
                  * because we don't want to map the entire memory in QEMU.
+                 * In that case just map until the end of the page.
                  */
                 if (block->offset == 0) {
-                    return qemu_map_cache(addr, 0, 1);
+                    return qemu_map_cache(addr, 0, 0);
                 } else if (block->host == NULL) {
                     block->host = qemu_map_cache(block->offset, block->length, 1);
                 }
@@ -3159,10 +3161,6 @@ void *qemu_ram_ptr_length(target_phys_addr_t addr, target_phys_addr_t *size)
 void qemu_put_ram_ptr(void *addr)
 {
     trace_qemu_put_ram_ptr(addr);
-
-    if (xen_mapcache_enabled()) {
-            qemu_invalidate_entry(block->host);
-    }
 }
 
 int qemu_ram_addr_from_host(void *ptr, ram_addr_t *ram_addr)
@@ -3170,6 +3168,11 @@ int qemu_ram_addr_from_host(void *ptr, ram_addr_t *ram_addr)
     RAMBlock *block;
     uint8_t *host = ptr;
 
+    if (xen_mapcache_enabled()) {
+        *ram_addr = qemu_ram_addr_from_mapcache(ptr);
+        return 0;
+    }
+
     QLIST_FOREACH(block, &ram_list.blocks, next) {
         /* This case append when the block is not mapped. */
         if (block->host == NULL) {
@@ -3181,11 +3184,6 @@ int qemu_ram_addr_from_host(void *ptr, ram_addr_t *ram_addr)
         }
     }
 
-    if (xen_mapcache_enabled()) {
-        *ram_addr = qemu_ram_addr_from_mapcache(ptr);
-        return 0;
-    }
-
     return -1;
 }
 
@@ -4086,13 +4084,7 @@ void cpu_physical_memory_unmap(void *buffer, target_phys_addr_t len,
             }
         }
         if (xen_mapcache_enabled()) {
-            uint8_t *buffer1 = buffer;
-            uint8_t *end_buffer = buffer + len;
-
-            while (buffer1 < end_buffer) {
-                qemu_put_ram_ptr(buffer1);
-                buffer1 += TARGET_PAGE_SIZE;
-            }
+            qemu_invalidate_entry(buffer);
         }
         return;
     }
commit 38bee5dc94ee355640b030d28f311b03ee2f13d1
Author: Stefano Stabellini <stefano.stabellini at eu.citrix.com>
Date:   Thu May 19 18:35:45 2011 +0100

    exec.c: refactor cpu_physical_memory_map
    
    Introduce qemu_ram_ptr_length that takes an address and a size as
    parameters rather than just an address.
    
    Refactor cpu_physical_memory_map so that we call qemu_ram_ptr_length only
    once rather than calling qemu_get_ram_ptr one time per page.
    This is not only more efficient but also tries to simplify the logic of
    the function.
    Currently we are relying on the fact that all the pages are mapped
    contiguously in qemu's address space: we have a check to make sure that
    the virtual address returned by qemu_get_ram_ptr from the second call on
    is consecutive. Now we are making this more explicit replacing all the
    calls to qemu_get_ram_ptr with a single call to qemu_ram_ptr_length
    passing a size argument.
    
    Signed-off-by: Stefano Stabellini <stefano.stabellini at eu.citrix.com>
    CC: agraf at suse.de
    CC: anthony at codemonkey.ws
    Signed-off-by: Alexander Graf <agraf at suse.de>

diff --git a/cpu-common.h b/cpu-common.h
index 9f59172..b027e43 100644
--- a/cpu-common.h
+++ b/cpu-common.h
@@ -65,6 +65,7 @@ void qemu_ram_free_from_ptr(ram_addr_t addr);
 void qemu_ram_remap(ram_addr_t addr, ram_addr_t length);
 /* This should only be used for ram local to a device.  */
 void *qemu_get_ram_ptr(ram_addr_t addr);
+void *qemu_ram_ptr_length(target_phys_addr_t addr, target_phys_addr_t *size);
 /* Same but slower, to use for migration, where the order of
  * RAMBlocks must not change. */
 void *qemu_safe_ram_ptr(ram_addr_t addr);
diff --git a/exec.c b/exec.c
index e11c1dd..238c173 100644
--- a/exec.c
+++ b/exec.c
@@ -3131,6 +3131,31 @@ void *qemu_safe_ram_ptr(ram_addr_t addr)
     return NULL;
 }
 
+/* Return a host pointer to guest's ram. Similar to qemu_get_ram_ptr
+ * but takes a size argument */
+void *qemu_ram_ptr_length(target_phys_addr_t addr, target_phys_addr_t *size)
+{
+    if (xen_mapcache_enabled())
+        return qemu_map_cache(addr, *size, 1);
+    else {
+        RAMBlock *block;
+
+        QLIST_FOREACH(block, &ram_list.blocks, next) {
+            if (addr - block->offset < block->length) {
+                if (addr - block->offset + *size > block->length)
+                    *size = block->length - addr + block->offset;
+                return block->host + (addr - block->offset);
+            }
+        }
+
+        fprintf(stderr, "Bad ram offset %" PRIx64 "\n", (uint64_t)addr);
+        abort();
+
+        *size = 0;
+        return NULL;
+    }
+}
+
 void qemu_put_ram_ptr(void *addr)
 {
     trace_qemu_put_ram_ptr(addr);
@@ -3992,14 +4017,12 @@ void *cpu_physical_memory_map(target_phys_addr_t addr,
                               int is_write)
 {
     target_phys_addr_t len = *plen;
-    target_phys_addr_t done = 0;
+    target_phys_addr_t todo = 0;
     int l;
-    uint8_t *ret = NULL;
-    uint8_t *ptr;
     target_phys_addr_t page;
     unsigned long pd;
     PhysPageDesc *p;
-    unsigned long addr1;
+    target_phys_addr_t addr1 = addr;
 
     while (len > 0) {
         page = addr & TARGET_PAGE_MASK;
@@ -4014,7 +4037,7 @@ void *cpu_physical_memory_map(target_phys_addr_t addr,
         }
 
         if ((pd & ~TARGET_PAGE_MASK) != IO_MEM_RAM) {
-            if (done || bounce.buffer) {
+            if (todo || bounce.buffer) {
                 break;
             }
             bounce.buffer = qemu_memalign(TARGET_PAGE_SIZE, TARGET_PAGE_SIZE);
@@ -4023,23 +4046,17 @@ void *cpu_physical_memory_map(target_phys_addr_t addr,
             if (!is_write) {
                 cpu_physical_memory_read(addr, bounce.buffer, l);
             }
-            ptr = bounce.buffer;
-        } else {
-            addr1 = (pd & TARGET_PAGE_MASK) + (addr & ~TARGET_PAGE_MASK);
-            ptr = qemu_get_ram_ptr(addr1);
-        }
-        if (!done) {
-            ret = ptr;
-        } else if (ret + done != ptr) {
-            break;
+
+            *plen = l;
+            return bounce.buffer;
         }
 
         len -= l;
         addr += l;
-        done += l;
+        todo += l;
     }
-    *plen = done;
-    return ret;
+    *plen = todo;
+    return qemu_ram_ptr_length(addr1, plen);
 }
 
 /* Unmaps a memory region previously mapped by cpu_physical_memory_map().
commit 6506e4f995967b1a48cc34418c77b318df92ce35
Author: Stefano Stabellini <stefano.stabellini at eu.citrix.com>
Date:   Thu May 19 18:35:44 2011 +0100

    xen: remove xen_map_block and xen_unmap_block
    
    Replace xen_map_block with qemu_map_cache with the appropriate locking
    and size parameters.
    Replace xen_unmap_block with qemu_invalidate_entry.
    
    Signed-off-by: Stefano Stabellini <stefano.stabellini at eu.citrix.com>
    Signed-off-by: Alexander Graf <agraf at suse.de>

diff --git a/exec.c b/exec.c
index 01f33bb..e11c1dd 100644
--- a/exec.c
+++ b/exec.c
@@ -53,6 +53,7 @@
 #endif
 #else /* !CONFIG_USER_ONLY */
 #include "xen-mapcache.h"
+#include "trace.h"
 #endif
 
 //#define DEBUG_TB_INVALIDATE
@@ -3088,7 +3089,7 @@ void *qemu_get_ram_ptr(ram_addr_t addr)
                 if (block->offset == 0) {
                     return qemu_map_cache(addr, 0, 1);
                 } else if (block->host == NULL) {
-                    block->host = xen_map_block(block->offset, block->length);
+                    block->host = qemu_map_cache(block->offset, block->length, 1);
                 }
             }
             return block->host + (addr - block->offset);
@@ -3117,7 +3118,7 @@ void *qemu_safe_ram_ptr(ram_addr_t addr)
                 if (block->offset == 0) {
                     return qemu_map_cache(addr, 0, 1);
                 } else if (block->host == NULL) {
-                    block->host = xen_map_block(block->offset, block->length);
+                    block->host = qemu_map_cache(block->offset, block->length, 1);
                 }
             }
             return block->host + (addr - block->offset);
@@ -3135,19 +3136,7 @@ void qemu_put_ram_ptr(void *addr)
     trace_qemu_put_ram_ptr(addr);
 
     if (xen_mapcache_enabled()) {
-        RAMBlock *block;
-
-        QLIST_FOREACH(block, &ram_list.blocks, next) {
-            if (addr == block->host) {
-                break;
-            }
-        }
-        if (block && block->host) {
-            xen_unmap_block(block->host, block->length);
-            block->host = NULL;
-        } else {
-            qemu_invalidate_entry(addr);
-        }
+            qemu_invalidate_entry(block->host);
     }
 }
 
diff --git a/xen-mapcache-stub.c b/xen-mapcache-stub.c
index 60f712b..8a2380a 100644
--- a/xen-mapcache-stub.c
+++ b/xen-mapcache-stub.c
@@ -34,7 +34,3 @@ void qemu_invalidate_map_cache(void)
 void qemu_invalidate_entry(uint8_t *buffer)
 {
 }
-uint8_t *xen_map_block(target_phys_addr_t phys_addr, target_phys_addr_t size)
-{
-    return NULL;
-}
diff --git a/xen-mapcache.c b/xen-mapcache.c
index 57fe24d..fac47cd 100644
--- a/xen-mapcache.c
+++ b/xen-mapcache.c
@@ -362,34 +362,3 @@ void qemu_invalidate_map_cache(void)
 
     mapcache_unlock();
 }
-
-uint8_t *xen_map_block(target_phys_addr_t phys_addr, target_phys_addr_t size)
-{
-    uint8_t *vaddr_base;
-    xen_pfn_t *pfns;
-    int *err;
-    unsigned int i;
-    target_phys_addr_t nb_pfn = size >> XC_PAGE_SHIFT;
-
-    trace_xen_map_block(phys_addr, size);
-    phys_addr >>= XC_PAGE_SHIFT;
-
-    pfns = qemu_mallocz(nb_pfn * sizeof (xen_pfn_t));
-    err = qemu_mallocz(nb_pfn * sizeof (int));
-
-    for (i = 0; i < nb_pfn; i++) {
-        pfns[i] = phys_addr + i;
-    }
-
-    vaddr_base = xc_map_foreign_bulk(xen_xc, xen_domid, PROT_READ|PROT_WRITE,
-                                     pfns, err, nb_pfn);
-    if (vaddr_base == NULL) {
-        perror("xc_map_foreign_bulk");
-        exit(-1);
-    }
-
-    qemu_free(pfns);
-    qemu_free(err);
-
-    return vaddr_base;
-}
diff --git a/xen-mapcache.h b/xen-mapcache.h
index b89b8f9..6216cc3 100644
--- a/xen-mapcache.h
+++ b/xen-mapcache.h
@@ -9,27 +9,12 @@
 #ifndef XEN_MAPCACHE_H
 #define XEN_MAPCACHE_H
 
-#include <sys/mman.h>
-#include "trace.h"
-
 void     qemu_map_cache_init(void);
 uint8_t  *qemu_map_cache(target_phys_addr_t phys_addr, target_phys_addr_t size, uint8_t lock);
 ram_addr_t qemu_ram_addr_from_mapcache(void *ptr);
 void     qemu_invalidate_entry(uint8_t *buffer);
 void     qemu_invalidate_map_cache(void);
 
-uint8_t *xen_map_block(target_phys_addr_t phys_addr, target_phys_addr_t size);
-
-static inline void xen_unmap_block(void *addr, ram_addr_t size)
-{
-    trace_xen_unmap_block(addr, size);
-
-    if (munmap(addr, size) != 0) {
-        hw_error("xen_unmap_block: %s", strerror(errno));
-    }
-}
-
-
 #define mapcache_lock()   ((void)0)
 #define mapcache_unlock() ((void)0)
 
commit cd306087e5a9ea4091071a0a41c0ea99fac60ab0
Author: Stefano Stabellini <stefano.stabellini at eu.citrix.com>
Date:   Thu May 19 18:35:43 2011 +0100

    xen: remove qemu_map_cache_unlock
    
    There is no need for qemu_map_cache_unlock, just use
    qemu_invalidate_entry instead.
    
    Signed-off-by: Stefano Stabellini <stefano.stabellini at eu.citrix.com>
    Signed-off-by: Alexander Graf <agraf at suse.de>

diff --git a/exec.c b/exec.c
index 09928a3..01f33bb 100644
--- a/exec.c
+++ b/exec.c
@@ -3146,7 +3146,7 @@ void qemu_put_ram_ptr(void *addr)
             xen_unmap_block(block->host, block->length);
             block->host = NULL;
         } else {
-            qemu_map_cache_unlock(addr);
+            qemu_invalidate_entry(addr);
         }
     }
 }
diff --git a/xen-mapcache-stub.c b/xen-mapcache-stub.c
index 7c14b3d..60f712b 100644
--- a/xen-mapcache-stub.c
+++ b/xen-mapcache-stub.c
@@ -22,10 +22,6 @@ uint8_t *qemu_map_cache(target_phys_addr_t phys_addr, target_phys_addr_t size, u
     return qemu_get_ram_ptr(phys_addr);
 }
 
-void qemu_map_cache_unlock(void *buffer)
-{
-}
-
 ram_addr_t qemu_ram_addr_from_mapcache(void *ptr)
 {
     return -1;
diff --git a/xen-mapcache.c b/xen-mapcache.c
index 90fbd49..57fe24d 100644
--- a/xen-mapcache.c
+++ b/xen-mapcache.c
@@ -230,39 +230,6 @@ uint8_t *qemu_map_cache(target_phys_addr_t phys_addr, target_phys_addr_t size, u
     return mapcache->last_address_vaddr + address_offset;
 }
 
-void qemu_map_cache_unlock(void *buffer)
-{
-    MapCacheEntry *entry = NULL, *pentry = NULL;
-    MapCacheRev *reventry;
-    target_phys_addr_t paddr_index;
-    int found = 0;
-
-    QTAILQ_FOREACH(reventry, &mapcache->locked_entries, next) {
-        if (reventry->vaddr_req == buffer) {
-            paddr_index = reventry->paddr_index;
-            found = 1;
-            break;
-        }
-    }
-    if (!found) {
-        return;
-    }
-    QTAILQ_REMOVE(&mapcache->locked_entries, reventry, next);
-    qemu_free(reventry);
-
-    entry = &mapcache->entry[paddr_index % mapcache->nr_buckets];
-    while (entry && entry->paddr_index != paddr_index) {
-        pentry = entry;
-        entry = entry->next;
-    }
-    if (!entry) {
-        return;
-    }
-    if (entry->lock > 0) {
-        entry->lock--;
-    }
-}
-
 ram_addr_t qemu_ram_addr_from_mapcache(void *ptr)
 {
     MapCacheEntry *entry = NULL, *pentry = NULL;
diff --git a/xen-mapcache.h b/xen-mapcache.h
index 339444c..b89b8f9 100644
--- a/xen-mapcache.h
+++ b/xen-mapcache.h
@@ -14,7 +14,6 @@
 
 void     qemu_map_cache_init(void);
 uint8_t  *qemu_map_cache(target_phys_addr_t phys_addr, target_phys_addr_t size, uint8_t lock);
-void     qemu_map_cache_unlock(void *phys_addr);
 ram_addr_t qemu_ram_addr_from_mapcache(void *ptr);
 void     qemu_invalidate_entry(uint8_t *buffer);
 void     qemu_invalidate_map_cache(void);
commit c13390cd384a9564e6dded127d01ef0627b6b1c5
Author: Stefano Stabellini <stefano.stabellini at eu.citrix.com>
Date:   Thu May 19 18:35:42 2011 +0100

    xen: fix qemu_map_cache with size != MCACHE_BUCKET_SIZE
    
    Fix the implementation of qemu_map_cache: correctly support size
    arguments different from 0 or MCACHE_BUCKET_SIZE.
    The new implementation supports locked mapcache entries with size
    multiple of MCACHE_BUCKET_SIZE. qemu_invalidate_entry can correctly
    find and unmap these "large" mapcache entries given that the virtual
    address passed to qemu_invalidate_entry is the same returned by
    qemu_map_cache when the locked mapcache entry was created.
    
    Signed-off-by: Stefano Stabellini <stefano.stabellini at eu.citrix.com>
    Signed-off-by: Alexander Graf <agraf at suse.de>

diff --git a/xen-mapcache.c b/xen-mapcache.c
index 349cc62..90fbd49 100644
--- a/xen-mapcache.c
+++ b/xen-mapcache.c
@@ -43,14 +43,16 @@
 typedef struct MapCacheEntry {
     target_phys_addr_t paddr_index;
     uint8_t *vaddr_base;
-    DECLARE_BITMAP(valid_mapping, MCACHE_BUCKET_SIZE >> XC_PAGE_SHIFT);
+    unsigned long *valid_mapping;
     uint8_t lock;
+    target_phys_addr_t size;
     struct MapCacheEntry *next;
 } MapCacheEntry;
 
 typedef struct MapCacheRev {
     uint8_t *vaddr_req;
     target_phys_addr_t paddr_index;
+    target_phys_addr_t size;
     QTAILQ_ENTRY(MapCacheRev) next;
 } MapCacheRev;
 
@@ -68,6 +70,15 @@ typedef struct MapCache {
 
 static MapCache *mapcache;
 
+static inline int test_bits(int nr, int size, const unsigned long *addr)
+{
+    unsigned long res = find_next_zero_bit(addr, size + nr, nr);
+    if (res >= nr + size)
+        return 1;
+    else
+        return 0;
+}
+
 void qemu_map_cache_init(void)
 {
     unsigned long size;
@@ -115,11 +126,15 @@ static void qemu_remap_bucket(MapCacheEntry *entry,
     err = qemu_mallocz(nb_pfn * sizeof (int));
 
     if (entry->vaddr_base != NULL) {
-        if (munmap(entry->vaddr_base, size) != 0) {
+        if (munmap(entry->vaddr_base, entry->size) != 0) {
             perror("unmap fails");
             exit(-1);
         }
     }
+    if (entry->valid_mapping != NULL) {
+        qemu_free(entry->valid_mapping);
+        entry->valid_mapping = NULL;
+    }
 
     for (i = 0; i < nb_pfn; i++) {
         pfns[i] = (address_index << (MCACHE_BUCKET_SHIFT-XC_PAGE_SHIFT)) + i;
@@ -134,6 +149,9 @@ static void qemu_remap_bucket(MapCacheEntry *entry,
 
     entry->vaddr_base = vaddr_base;
     entry->paddr_index = address_index;
+    entry->size = size;
+    entry->valid_mapping = (unsigned long *) qemu_mallocz(sizeof(unsigned long) *
+            BITS_TO_LONGS(size >> XC_PAGE_SHIFT));
 
     bitmap_zero(entry->valid_mapping, nb_pfn);
     for (i = 0; i < nb_pfn; i++) {
@@ -151,32 +169,47 @@ uint8_t *qemu_map_cache(target_phys_addr_t phys_addr, target_phys_addr_t size, u
     MapCacheEntry *entry, *pentry = NULL;
     target_phys_addr_t address_index  = phys_addr >> MCACHE_BUCKET_SHIFT;
     target_phys_addr_t address_offset = phys_addr & (MCACHE_BUCKET_SIZE - 1);
+    target_phys_addr_t __size = size;
 
     trace_qemu_map_cache(phys_addr);
 
-    if (address_index == mapcache->last_address_index && !lock) {
+    if (address_index == mapcache->last_address_index && !lock && !__size) {
         trace_qemu_map_cache_return(mapcache->last_address_vaddr + address_offset);
         return mapcache->last_address_vaddr + address_offset;
     }
 
+    /* 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)
+        __size = MCACHE_BUCKET_SIZE;
+
     entry = &mapcache->entry[address_index % mapcache->nr_buckets];
 
-    while (entry && entry->lock && entry->paddr_index != address_index && entry->vaddr_base) {
+    while (entry && entry->lock && entry->vaddr_base &&
+            (entry->paddr_index != address_index || entry->size != __size ||
+             !test_bits(address_offset >> XC_PAGE_SHIFT, size >> XC_PAGE_SHIFT,
+                 entry->valid_mapping))) {
         pentry = entry;
         entry = entry->next;
     }
     if (!entry) {
         entry = qemu_mallocz(sizeof (MapCacheEntry));
         pentry->next = entry;
-        qemu_remap_bucket(entry, size ? : MCACHE_BUCKET_SIZE, address_index);
+        qemu_remap_bucket(entry, __size, address_index);
     } else if (!entry->lock) {
         if (!entry->vaddr_base || entry->paddr_index != address_index ||
-            !test_bit(address_offset >> XC_PAGE_SHIFT, entry->valid_mapping)) {
-            qemu_remap_bucket(entry, size ? : MCACHE_BUCKET_SIZE, address_index);
+                entry->size != __size ||
+                !test_bits(address_offset >> XC_PAGE_SHIFT, size >> XC_PAGE_SHIFT,
+                    entry->valid_mapping)) {
+            qemu_remap_bucket(entry, __size, address_index);
         }
     }
 
-    if (!test_bit(address_offset >> XC_PAGE_SHIFT, entry->valid_mapping)) {
+    if(!test_bits(address_offset >> XC_PAGE_SHIFT, size >> XC_PAGE_SHIFT,
+                entry->valid_mapping)) {
         mapcache->last_address_index = -1;
         trace_qemu_map_cache_return(NULL);
         return NULL;
@@ -189,6 +222,7 @@ uint8_t *qemu_map_cache(target_phys_addr_t phys_addr, target_phys_addr_t size, u
         entry->lock++;
         reventry->vaddr_req = mapcache->last_address_vaddr + address_offset;
         reventry->paddr_index = mapcache->last_address_index;
+        reventry->size = entry->size;
         QTAILQ_INSERT_HEAD(&mapcache->locked_entries, reventry, next);
     }
 
@@ -231,13 +265,16 @@ void qemu_map_cache_unlock(void *buffer)
 
 ram_addr_t qemu_ram_addr_from_mapcache(void *ptr)
 {
+    MapCacheEntry *entry = NULL, *pentry = NULL;
     MapCacheRev *reventry;
     target_phys_addr_t paddr_index;
+    target_phys_addr_t size;
     int found = 0;
 
     QTAILQ_FOREACH(reventry, &mapcache->locked_entries, next) {
         if (reventry->vaddr_req == ptr) {
             paddr_index = reventry->paddr_index;
+            size = reventry->size;
             found = 1;
             break;
         }
@@ -252,7 +289,17 @@ ram_addr_t qemu_ram_addr_from_mapcache(void *ptr)
         return 0;
     }
 
-    return paddr_index << MCACHE_BUCKET_SHIFT;
+    entry = &mapcache->entry[paddr_index % mapcache->nr_buckets];
+    while (entry && (entry->paddr_index != paddr_index || entry->size != size)) {
+        pentry = entry;
+        entry = entry->next;
+    }
+    if (!entry) {
+        DPRINTF("Trying to find address %p that is not in the mapcache!\n", ptr);
+        return 0;
+    }
+    return (reventry->paddr_index << MCACHE_BUCKET_SHIFT) +
+        ((unsigned long) ptr - (unsigned long) entry->vaddr_base);
 }
 
 void qemu_invalidate_entry(uint8_t *buffer)
@@ -260,6 +307,7 @@ void qemu_invalidate_entry(uint8_t *buffer)
     MapCacheEntry *entry = NULL, *pentry = NULL;
     MapCacheRev *reventry;
     target_phys_addr_t paddr_index;
+    target_phys_addr_t size;
     int found = 0;
 
     if (mapcache->last_address_vaddr == buffer) {
@@ -269,6 +317,7 @@ void qemu_invalidate_entry(uint8_t *buffer)
     QTAILQ_FOREACH(reventry, &mapcache->locked_entries, next) {
         if (reventry->vaddr_req == buffer) {
             paddr_index = reventry->paddr_index;
+            size = reventry->size;
             found = 1;
             break;
         }
@@ -284,7 +333,7 @@ void qemu_invalidate_entry(uint8_t *buffer)
     qemu_free(reventry);
 
     entry = &mapcache->entry[paddr_index % mapcache->nr_buckets];
-    while (entry && entry->paddr_index != paddr_index) {
+    while (entry && (entry->paddr_index != paddr_index || entry->size != size)) {
         pentry = entry;
         entry = entry->next;
     }
@@ -298,10 +347,11 @@ void qemu_invalidate_entry(uint8_t *buffer)
     }
 
     pentry->next = entry->next;
-    if (munmap(entry->vaddr_base, MCACHE_BUCKET_SIZE) != 0) {
+    if (munmap(entry->vaddr_base, entry->size) != 0) {
         perror("unmap fails");
         exit(-1);
     }
+    qemu_free(entry->valid_mapping);
     qemu_free(entry);
 }
 
@@ -328,13 +378,16 @@ void qemu_invalidate_map_cache(void)
             continue;
         }
 
-        if (munmap(entry->vaddr_base, MCACHE_BUCKET_SIZE) != 0) {
+        if (munmap(entry->vaddr_base, entry->size) != 0) {
             perror("unmap fails");
             exit(-1);
         }
 
         entry->paddr_index = 0;
         entry->vaddr_base = NULL;
+        entry->size = 0;
+        qemu_free(entry->valid_mapping);
+        entry->valid_mapping = NULL;
     }
 
     mapcache->last_address_index = -1;
commit b4dd7802cac7749de80ceadd622d4209fc31b507
Author: Anthony PERARD <anthony.perard at citrix.com>
Date:   Tue May 24 14:34:21 2011 +0100

    xen: Introduce VGA sync dirty bitmap support
    
    This patch introduces phys memory client for Xen.
    
    Only sync dirty_bitmap and set_memory are actually implemented.
    migration_log will stay empty for the moment.
    
    Xen can only log one range for bit change, so only the range in the
    first call will be synced.
    
    Signed-off-by: Anthony PERARD <anthony.perard at citrix.com>
    Signed-off-by: Alexander Graf <agraf at suse.de>

diff --git a/trace-events b/trace-events
index f1230f1..46a19d3 100644
--- a/trace-events
+++ b/trace-events
@@ -396,6 +396,7 @@ disable milkymist_vgafb_memory_write(uint32_t addr, uint32_t value) "addr %08x v
 
 # xen-all.c
 disable xen_ram_alloc(unsigned long ram_addr, unsigned long size) "requested: %#lx, size %#lx"
+disable xen_client_set_memory(uint64_t start_addr, unsigned long size, unsigned long phys_offset, bool log_dirty) "%#"PRIx64" size %#lx, offset %#lx, log_dirty %i"
 
 # xen-mapcache.c
 disable qemu_map_cache(uint64_t phys_addr) "want %#"PRIx64""
diff --git a/xen-all.c b/xen-all.c
index 0eac202..75a82c2 100644
--- a/xen-all.c
+++ b/xen-all.c
@@ -13,6 +13,7 @@
 #include "hw/xen_common.h"
 #include "hw/xen_backend.h"
 
+#include "range.h"
 #include "xen-mapcache.h"
 #include "trace.h"
 
@@ -54,6 +55,14 @@ static inline ioreq_t *xen_vcpu_ioreq(shared_iopage_t *shared_page, int vcpu)
 
 #define BUFFER_IO_MAX_DELAY  100
 
+typedef struct XenPhysmap {
+    target_phys_addr_t start_addr;
+    ram_addr_t size;
+    target_phys_addr_t phys_offset;
+
+    QLIST_ENTRY(XenPhysmap) list;
+} XenPhysmap;
+
 typedef struct XenIOState {
     shared_iopage_t *shared_page;
     buffered_iopage_t *buffered_io_page;
@@ -66,6 +75,9 @@ typedef struct XenIOState {
     int send_vcpu;
 
     struct xs_handle *xenstore;
+    CPUPhysMemoryClient client;
+    QLIST_HEAD(, XenPhysmap) physmap;
+    const XenPhysmap *log_for_dirtybit;
 
     Notifier exit;
 } XenIOState;
@@ -178,6 +190,256 @@ void xen_ram_alloc(ram_addr_t ram_addr, ram_addr_t size)
     qemu_free(pfn_list);
 }
 
+static XenPhysmap *get_physmapping(XenIOState *state,
+                                   target_phys_addr_t start_addr, ram_addr_t size)
+{
+    XenPhysmap *physmap = NULL;
+
+    start_addr &= TARGET_PAGE_MASK;
+
+    QLIST_FOREACH(physmap, &state->physmap, list) {
+        if (range_covers_byte(physmap->start_addr, physmap->size, start_addr)) {
+            return physmap;
+        }
+    }
+    return NULL;
+}
+
+#if CONFIG_XEN_CTRL_INTERFACE_VERSION >= 340
+static int xen_add_to_physmap(XenIOState *state,
+                              target_phys_addr_t start_addr,
+                              ram_addr_t size,
+                              target_phys_addr_t phys_offset)
+{
+    unsigned long i = 0;
+    int rc = 0;
+    XenPhysmap *physmap = NULL;
+    target_phys_addr_t pfn, start_gpfn;
+
+    if (get_physmapping(state, start_addr, size)) {
+        return 0;
+    }
+    if (size <= 0) {
+        return -1;
+    }
+
+    DPRINTF("mapping vram to %llx - %llx, from %llx\n",
+            start_addr, start_addr + size, phys_offset);
+
+    pfn = phys_offset >> TARGET_PAGE_BITS;
+    start_gpfn = start_addr >> TARGET_PAGE_BITS;
+    for (i = 0; i < size >> TARGET_PAGE_BITS; i++) {
+        unsigned long idx = pfn + i;
+        xen_pfn_t gpfn = start_gpfn + i;
+
+        rc = xc_domain_add_to_physmap(xen_xc, xen_domid, XENMAPSPACE_gmfn, idx, gpfn);
+        if (rc) {
+            DPRINTF("add_to_physmap MFN %"PRI_xen_pfn" to PFN %"
+                    PRI_xen_pfn" failed: %d\n", idx, gpfn, rc);
+            return -rc;
+        }
+    }
+
+    physmap = qemu_malloc(sizeof (XenPhysmap));
+
+    physmap->start_addr = start_addr;
+    physmap->size = size;
+    physmap->phys_offset = phys_offset;
+
+    QLIST_INSERT_HEAD(&state->physmap, physmap, list);
+
+    xc_domain_pin_memory_cacheattr(xen_xc, xen_domid,
+                                   start_addr >> TARGET_PAGE_BITS,
+                                   (start_addr + size) >> TARGET_PAGE_BITS,
+                                   XEN_DOMCTL_MEM_CACHEATTR_WB);
+    return 0;
+}
+
+static int xen_remove_from_physmap(XenIOState *state,
+                                   target_phys_addr_t start_addr,
+                                   ram_addr_t size)
+{
+    unsigned long i = 0;
+    int rc = 0;
+    XenPhysmap *physmap = NULL;
+    target_phys_addr_t phys_offset = 0;
+
+    physmap = get_physmapping(state, start_addr, size);
+    if (physmap == NULL) {
+        return -1;
+    }
+
+    phys_offset = physmap->phys_offset;
+    size = physmap->size;
+
+    DPRINTF("unmapping vram to %llx - %llx, from %llx\n",
+            phys_offset, phys_offset + size, start_addr);
+
+    size >>= TARGET_PAGE_BITS;
+    start_addr >>= TARGET_PAGE_BITS;
+    phys_offset >>= TARGET_PAGE_BITS;
+    for (i = 0; i < size; i++) {
+        unsigned long idx = start_addr + i;
+        xen_pfn_t gpfn = phys_offset + i;
+
+        rc = xc_domain_add_to_physmap(xen_xc, xen_domid, XENMAPSPACE_gmfn, idx, gpfn);
+        if (rc) {
+            fprintf(stderr, "add_to_physmap MFN %"PRI_xen_pfn" to PFN %"
+                    PRI_xen_pfn" failed: %d\n", idx, gpfn, rc);
+            return -rc;
+        }
+    }
+
+    QLIST_REMOVE(physmap, list);
+    if (state->log_for_dirtybit == physmap) {
+        state->log_for_dirtybit = NULL;
+    }
+    free(physmap);
+
+    return 0;
+}
+
+#else
+static int xen_add_to_physmap(XenIOState *state,
+                              target_phys_addr_t start_addr,
+                              ram_addr_t size,
+                              target_phys_addr_t phys_offset)
+{
+    return -ENOSYS;
+}
+
+static int xen_remove_from_physmap(XenIOState *state,
+                                   target_phys_addr_t start_addr,
+                                   ram_addr_t size)
+{
+    return -ENOSYS;
+}
+#endif
+
+static void xen_client_set_memory(struct CPUPhysMemoryClient *client,
+                                  target_phys_addr_t start_addr,
+                                  ram_addr_t size,
+                                  ram_addr_t phys_offset,
+                                  bool log_dirty)
+{
+    XenIOState *state = container_of(client, XenIOState, client);
+    ram_addr_t flags = phys_offset & ~TARGET_PAGE_MASK;
+    hvmmem_type_t mem_type;
+
+    if (!(start_addr != phys_offset
+          && ( (log_dirty && flags < IO_MEM_UNASSIGNED)
+               || (!log_dirty && flags == IO_MEM_UNASSIGNED)))) {
+        return;
+    }
+
+    trace_xen_client_set_memory(start_addr, size, phys_offset, log_dirty);
+
+    start_addr &= TARGET_PAGE_MASK;
+    size = TARGET_PAGE_ALIGN(size);
+    phys_offset &= TARGET_PAGE_MASK;
+
+    switch (flags) {
+    case IO_MEM_RAM:
+        xen_add_to_physmap(state, start_addr, size, phys_offset);
+        break;
+    case IO_MEM_ROM:
+        mem_type = HVMMEM_ram_ro;
+        if (xc_hvm_set_mem_type(xen_xc, xen_domid, mem_type,
+                                start_addr >> TARGET_PAGE_BITS,
+                                size >> TARGET_PAGE_BITS)) {
+            DPRINTF("xc_hvm_set_mem_type error, addr: "TARGET_FMT_plx"\n",
+                    start_addr);
+        }
+        break;
+    case IO_MEM_UNASSIGNED:
+        if (xen_remove_from_physmap(state, start_addr, size) < 0) {
+            DPRINTF("physmapping does not exist at "TARGET_FMT_plx"\n", start_addr);
+        }
+        break;
+    }
+}
+
+static int xen_sync_dirty_bitmap(XenIOState *state,
+                                 target_phys_addr_t start_addr,
+                                 ram_addr_t size)
+{
+    target_phys_addr_t npages = size >> TARGET_PAGE_BITS;
+    target_phys_addr_t vram_offset = 0;
+    const int width = sizeof(unsigned long) * 8;
+    unsigned long bitmap[(npages + width - 1) / width];
+    int rc, i, j;
+    const XenPhysmap *physmap = NULL;
+
+    physmap = get_physmapping(state, start_addr, size);
+    if (physmap == NULL) {
+        /* not handled */
+        return -1;
+    }
+
+    if (state->log_for_dirtybit == NULL) {
+        state->log_for_dirtybit = physmap;
+    } else if (state->log_for_dirtybit != physmap) {
+        return -1;
+    }
+    vram_offset = physmap->phys_offset;
+
+    rc = xc_hvm_track_dirty_vram(xen_xc, xen_domid,
+                                 start_addr >> TARGET_PAGE_BITS, npages,
+                                 bitmap);
+    if (rc) {
+        return rc;
+    }
+
+    for (i = 0; i < ARRAY_SIZE(bitmap); i++) {
+        unsigned long map = bitmap[i];
+        while (map != 0) {
+            j = ffsl(map) - 1;
+            map &= ~(1ul << j);
+            cpu_physical_memory_set_dirty(vram_offset + (i * width + j) * TARGET_PAGE_SIZE);
+        };
+    }
+
+    return 0;
+}
+
+static int xen_log_start(CPUPhysMemoryClient *client, target_phys_addr_t phys_addr, ram_addr_t size)
+{
+    XenIOState *state = container_of(client, XenIOState, client);
+
+    return xen_sync_dirty_bitmap(state, phys_addr, size);
+}
+
+static int xen_log_stop(CPUPhysMemoryClient *client, target_phys_addr_t phys_addr, ram_addr_t size)
+{
+    XenIOState *state = container_of(client, XenIOState, client);
+
+    state->log_for_dirtybit = NULL;
+    /* Disable dirty bit tracking */
+    return xc_hvm_track_dirty_vram(xen_xc, xen_domid, 0, 0, NULL);
+}
+
+static int xen_client_sync_dirty_bitmap(struct CPUPhysMemoryClient *client,
+                                        target_phys_addr_t start_addr,
+                                        target_phys_addr_t end_addr)
+{
+    XenIOState *state = container_of(client, XenIOState, client);
+
+    return xen_sync_dirty_bitmap(state, start_addr, end_addr - start_addr);
+}
+
+static int xen_client_migration_log(struct CPUPhysMemoryClient *client,
+                                    int enable)
+{
+    return 0;
+}
+
+static CPUPhysMemoryClient xen_cpu_phys_memory_client = {
+    .set_memory = xen_client_set_memory,
+    .sync_dirty_bitmap = xen_client_sync_dirty_bitmap,
+    .migration_log = xen_client_migration_log,
+    .log_start = xen_log_start,
+    .log_stop = xen_log_stop,
+};
 
 /* VCPU Operations, MMIO, IO ring ... */
 
@@ -581,6 +843,11 @@ int xen_hvm_init(void)
 
     qemu_add_vm_change_state_handler(xen_vm_change_state_handler, state);
 
+    state->client = xen_cpu_phys_memory_client;
+    QLIST_INIT(&state->physmap);
+    cpu_register_phys_memory_client(&state->client);
+    state->log_for_dirtybit = NULL;
+
     return 0;
 }
 
commit b87de24e6c568d40d4f231b10e1707aed1ebe92e
Author: Anthony PERARD <anthony.perard at citrix.com>
Date:   Tue May 24 14:34:20 2011 +0100

    xen: Add xc_domain_add_to_physmap to xen_interface.
    
    This function will be used to support sync dirty bitmap.
    
    This come with a check against every Xen release, and special
    implementation for Xen version that doesn't have this specific call.
    
    This function will not be usable with Xen 3.3 because the behavior is
    different.
    
    Signed-off-by: Anthony PERARD <anthony.perard at citrix.com>
    Signed-off-by: Alexander Graf <agraf at suse.de>

diff --git a/configure b/configure
index 44c092a..b63b49f 100755
--- a/configure
+++ b/configure
@@ -1210,6 +1210,7 @@ int main(void) {
   xc = xc_interface_open(0, 0, 0);
   xc_hvm_set_mem_type(0, 0, HVMMEM_ram_ro, 0, 0);
   xc_gnttab_open(NULL, 0);
+  xc_domain_add_to_physmap(0, 0, XENMAPSPACE_gmfn, 0, 0);
   return 0;
 }
 EOF
@@ -1228,10 +1229,14 @@ EOF
 # error HVM_MAX_VCPUS not defined
 #endif
 int main(void) {
+  struct xen_add_to_physmap xatp = {
+    .domid = 0, .space = XENMAPSPACE_gmfn, .idx = 0, .gpfn = 0,
+  };
   xs_daemon_open();
   xc_interface_open();
   xc_gnttab_open();
   xc_hvm_set_mem_type(0, 0, HVMMEM_ram_ro, 0, 0);
+  xc_memory_op(0, XENMEM_add_to_physmap, &xatp);
   return 0;
 }
 EOF
@@ -1240,7 +1245,29 @@ EOF
     xen_ctrl_version=400
     xen=yes
 
-  # Xen 3.3.0, 3.4.0
+  # Xen 3.4.0
+  elif (
+      cat > $TMPC <<EOF
+#include <xenctrl.h>
+#include <xs.h>
+int main(void) {
+  struct xen_add_to_physmap xatp = {
+    .domid = 0, .space = XENMAPSPACE_gmfn, .idx = 0, .gpfn = 0,
+  };
+  xs_daemon_open();
+  xc_interface_open();
+  xc_gnttab_open();
+  xc_hvm_set_mem_type(0, 0, HVMMEM_ram_ro, 0, 0);
+  xc_memory_op(0, XENMEM_add_to_physmap, &xatp);
+  return 0;
+}
+EOF
+      compile_prog "" "$xen_libs"
+    ) ; then
+    xen_ctrl_version=340
+    xen=yes
+
+  # Xen 3.3.0
   elif (
       cat > $TMPC <<EOF
 #include <xenctrl.h>
diff --git a/hw/xen_common.h b/hw/xen_common.h
index a1958a0..2c79af6 100644
--- a/hw/xen_common.h
+++ b/hw/xen_common.h
@@ -71,6 +71,20 @@ static inline int xc_domain_populate_physmap_exact
         (xc_handle, domid, nr_extents, extent_order, mem_flags, extent_start);
 }
 
+static inline int xc_domain_add_to_physmap(int xc_handle, uint32_t domid,
+                                           unsigned int space, unsigned long idx,
+                                           xen_pfn_t gpfn)
+{
+    struct xen_add_to_physmap xatp = {
+        .domid = domid,
+        .space = space,
+        .idx = idx,
+        .gpfn = gpfn,
+    };
+
+    return xc_memory_op(xc_handle, XENMEM_add_to_physmap, &xatp);
+}
+
 
 /* Xen 4.1 */
 #else
commit 5a8a49d7aa78b31a853e8f5d31f5b12811caeb27
Author: Jan Kiszka <jan.kiszka at siemens.com>
Date:   Tue Jun 14 18:29:45 2011 +0200

    Reset system before loadvm
    
    In case we load the vmstate during incoming migration, we start from a
    clean, default machine state as we went through system reset before. But
    if we load from a snapshot, the machine can be in any state. That can
    cause troubles if loading an older image which does not carry all state
    information the executing QEMU requires. Hardly any device takes care of
    this scenario.
    
    However, fixing this is trivial. We just need to issue a system reset
    during loadvm as well.
    
    Signed-off-by: Jan Kiszka <jan.kiszka at siemens.com>
    Signed-off-by: Luiz Capitulino <lcapitulino at redhat.com>

diff --git a/savevm.c b/savevm.c
index 939845c..8139bc7 100644
--- a/savevm.c
+++ b/savevm.c
@@ -2073,6 +2073,7 @@ int load_vmstate(const char *name)
         return -EINVAL;
     }
 
+    qemu_system_reset(VMRESET_SILENT);
     ret = qemu_loadvm_state(f);
 
     qemu_fclose(f);
commit e063eb1f4a6d42371e7d288dfdb690d5821190ed
Author: Jan Kiszka <jan.kiszka at siemens.com>
Date:   Tue Jun 14 18:29:43 2011 +0200

    Allow silent system resets
    
    This allows qemu_system_reset to be issued silently for internal
    purposes, ie. without sending out a monitor event. Convert the system
    reset after startup to the silent mode.
    
    Signed-off-by: Jan Kiszka <jan.kiszka at siemens.com>
    Signed-off-by: Luiz Capitulino <lcapitulino at redhat.com>

diff --git a/sysemu.h b/sysemu.h
index 7e70daa..d3013f5 100644
--- a/sysemu.h
+++ b/sysemu.h
@@ -34,6 +34,9 @@ void qemu_del_vm_change_state_handler(VMChangeStateEntry *e);
 #define VMSTOP_LOADVM    7
 #define VMSTOP_MIGRATE   8
 
+#define VMRESET_SILENT   false
+#define VMRESET_REPORT   true
+
 void vm_start(void);
 void vm_stop(int reason);
 
@@ -50,7 +53,7 @@ int qemu_powerdown_requested(void);
 void qemu_system_killed(int signal, pid_t pid);
 void qemu_kill_report(void);
 extern qemu_irq qemu_system_powerdown;
-void qemu_system_reset(void);
+void qemu_system_reset(bool report);
 
 void qemu_add_exit_notifier(Notifier *notify);
 void qemu_remove_exit_notifier(Notifier *notify);
diff --git a/vl.c b/vl.c
index dbdec71..52402a2 100644
--- a/vl.c
+++ b/vl.c
@@ -1253,7 +1253,7 @@ void qemu_unregister_reset(QEMUResetHandler *func, void *opaque)
     }
 }
 
-void qemu_system_reset(void)
+void qemu_system_reset(bool report)
 {
     QEMUResetEntry *re, *nre;
 
@@ -1261,7 +1261,9 @@ void qemu_system_reset(void)
     QTAILQ_FOREACH_SAFE(re, &reset_handlers, entry, nre) {
         re->func(re->opaque);
     }
-    monitor_protocol_event(QEVENT_RESET, NULL);
+    if (report) {
+        monitor_protocol_event(QEVENT_RESET, NULL);
+    }
     cpu_synchronize_all_post_reset();
 }
 
@@ -1403,7 +1405,7 @@ static void main_loop(void)
         if (qemu_reset_requested()) {
             pause_all_vcpus();
             cpu_synchronize_all_states();
-            qemu_system_reset();
+            qemu_system_reset(VMRESET_REPORT);
             resume_all_vcpus();
         }
         if (qemu_powerdown_requested()) {
@@ -3293,7 +3295,7 @@ int main(int argc, char **argv, char **envp)
     qemu_register_reset(qbus_reset_all_fn, sysbus_get_default());
     qemu_run_machine_init_done_notifiers();
 
-    qemu_system_reset();
+    qemu_system_reset(VMRESET_SILENT);
     if (loadvm) {
         if (load_vmstate(loadvm) < 0) {
             autostart = 0;
diff --git a/xen-all.c b/xen-all.c
index 0eac202..41fd98a 100644
--- a/xen-all.c
+++ b/xen-all.c
@@ -452,7 +452,7 @@ static void cpu_handle_ioreq(void *opaque)
                 destroy_hvm_domain();
             }
             if (qemu_reset_requested_get()) {
-                qemu_system_reset();
+                qemu_system_reset(VMRESET_REPORT);
             }
         }
 
commit e4ea5e2d0e0e4c5188ab45b66f3195062ae059dc
Author: Stefan Weil <weil at mail.berlios.de>
Date:   Mon Jun 13 23:01:53 2011 +0200

    error framework: Fix compilation for w32/w64
    
    The declaration of function error_set() should use macro GCC_FMT_ATTR
    instead of gcc's format printf attribute.
    
    For w32/w64, both declarations are different and GCC_FMT_ATTR is needed.
    Compilation for w64 even failed with the original code because mingw64
    defines a macro for printf.
    
    GCC_FMT_ATTR requires qemu-common.h, so add it in error.c
    (it's also included by error_int.h but too late).
    
    Remove assert.h which is included by qemu-common.h.
    
    Cc: Luiz Capitulino <lcapitulino at redhat.com>
    Cc: Anthony Liguori <aliguori at us.ibm.com>
    Signed-off-by: Stefan Weil <weil at mail.berlios.de>
    Signed-off-by: Luiz Capitulino <lcapitulino at redhat.com>

diff --git a/error.c b/error.c
index 867eec2..74d7398 100644
--- a/error.c
+++ b/error.c
@@ -9,11 +9,12 @@
  * This work is licensed under the terms of the GNU LGPL, version 2.  See
  * the COPYING.LIB file in the top-level directory.
  */
+
+#include "qemu-common.h"
 #include "error.h"
 #include "error_int.h"
 #include "qemu-objects.h"
 #include "qerror.h"
-#include <assert.h>
 
 struct Error
 {
diff --git a/error.h b/error.h
index 003c855..0f92a6f 100644
--- a/error.h
+++ b/error.h
@@ -25,8 +25,7 @@ typedef struct Error Error;
  * Currently, qerror.h defines these error formats.  This function is not
  * meant to be used outside of QEMU.
  */
-void error_set(Error **err, const char *fmt, ...)
-    __attribute__((format(printf, 2, 3)));
+void error_set(Error **err, const char *fmt, ...) GCC_FMT_ATTR(2, 3);
 
 /**
  * Returns true if an indirect pointer to an error is pointing to a valid
commit 0e6264db2c04dfad79be60240bfacfcaf47f9d6c
Author: Michael S. Tsirkin <mst at redhat.com>
Date:   Tue Jun 14 17:29:34 2011 +0300

    wdt: remove unused variables
    
    Signed-off-by: Michael S. Tsirkin <mst at redhat.com>
    Acked-off-by: Isaku Yamahata <yamahata at valinux.co.jp>

diff --git a/hw/wdt_i6300esb.c b/hw/wdt_i6300esb.c
index bd57fd3..53786ce 100644
--- a/hw/wdt_i6300esb.c
+++ b/hw/wdt_i6300esb.c
@@ -381,7 +381,6 @@ static const VMStateDescription vmstate_i6300esb = {
 static int i6300esb_init(PCIDevice *dev)
 {
     I6300State *d = DO_UPCAST(I6300State, dev, dev);
-    uint8_t *pci_conf;
     int io_mem;
     static CPUReadMemoryFunc * const mem_read[3] = {
         i6300esb_mem_readb,
@@ -399,8 +398,6 @@ static int i6300esb_init(PCIDevice *dev)
     d->timer = qemu_new_timer_ns(vm_clock, i6300esb_timer_expired, d);
     d->previous_reboot_flag = 0;
 
-    pci_conf = d->dev.config;
-
     io_mem = cpu_register_io_memory(mem_read, mem_write, d,
                                     DEVICE_NATIVE_ENDIAN);
     pci_register_bar_simple(&d->dev, 0, 0x10, 0, io_mem);
commit efa6435159e4f8a12f8201fadf738f63a8a5132e
Author: Michael S. Tsirkin <mst at redhat.com>
Date:   Tue Jun 14 20:06:06 2011 +0300

    alpha: remove unused variable
    
    Signed-off-by: Michael S. Tsirkin <mst at redhat.com>
    Acked-by: Richard Henderson  <rth at twiddle.net>

diff --git a/target-alpha/translate.c b/target-alpha/translate.c
index 5d7454c..936760c 100644
--- a/target-alpha/translate.c
+++ b/target-alpha/translate.c
@@ -1661,7 +1661,10 @@ static void gen_mtpr(int rb, int regno)
 static ExitStatus translate_one(DisasContext *ctx, uint32_t insn)
 {
     uint32_t palcode;
-    int32_t disp21, disp16, disp12;
+    int32_t disp21, disp16;
+#ifndef CONFIG_USER_ONLY
+    int32_t disp12;
+#endif
     uint16_t fn11;
     uint8_t opc, ra, rb, rc, fpfn, fn7, islit, real_islit;
     uint8_t lit;
@@ -1681,7 +1684,9 @@ static ExitStatus translate_one(DisasContext *ctx, uint32_t insn)
     palcode = insn & 0x03FFFFFF;
     disp21 = ((int32_t)((insn & 0x001FFFFF) << 11)) >> 11;
     disp16 = (int16_t)(insn & 0x0000FFFF);
+#ifndef CONFIG_USER_ONLY
     disp12 = (int32_t)((insn & 0x00000FFF) << 20) >> 20;
+#endif
     fn11 = (insn >> 5) & 0x000007FF;
     fpfn = fn11 & 0x3F;
     fn7 = (insn >> 5) & 0x0000007F;
commit b6fb147cc03a618757d3f02fb9c44287079da7ee
Author: Michael S. Tsirkin <mst at redhat.com>
Date:   Tue Jun 14 18:06:40 2011 +0300

    alpha/translate: remve unused variables
    
    Signed-off-by: Michael S. Tsirkin <mst at redhat.com>
    Acked-by: Richard Henderson  <rth at twiddle.net>

diff --git a/target-alpha/translate.c b/target-alpha/translate.c
index ad6c2ca..5d7454c 100644
--- a/target-alpha/translate.c
+++ b/target-alpha/translate.c
@@ -1663,7 +1663,7 @@ static ExitStatus translate_one(DisasContext *ctx, uint32_t insn)
     uint32_t palcode;
     int32_t disp21, disp16, disp12;
     uint16_t fn11;
-    uint8_t opc, ra, rb, rc, fpfn, fn7, fn2, islit, real_islit;
+    uint8_t opc, ra, rb, rc, fpfn, fn7, islit, real_islit;
     uint8_t lit;
     ExitStatus ret;
 
@@ -1685,7 +1685,6 @@ static ExitStatus translate_one(DisasContext *ctx, uint32_t insn)
     fn11 = (insn >> 5) & 0x000007FF;
     fpfn = fn11 & 0x3F;
     fn7 = (insn >> 5) & 0x0000007F;
-    fn2 = (insn >> 5) & 0x00000003;
     LOG_DISAS("opc %02x ra %2d rb %2d rc %2d disp16 %6d\n",
               opc, ra, rb, rc, disp16);
 
commit 990def582ba06cb0d87b89cb5b6c4a79bb61f0ee
Author: Michael S. Tsirkin <mst at redhat.com>
Date:   Tue Jun 14 20:15:41 2011 +0300

    get_maintainer: update to match qemu tree
    
    Signed-off-by: Michael S. Tsirkin <mst at redhat.com>

diff --git a/scripts/get_maintainer.pl b/scripts/get_maintainer.pl
index d29a8d7..d9c48e0 100755
--- a/scripts/get_maintainer.pl
+++ b/scripts/get_maintainer.pl
@@ -258,9 +258,9 @@ if ($email &&
     die "$P: Please select at least 1 email option\n";
 }
 
-if (!top_of_kernel_tree($lk_path)) {
+if (!top_of_tree($lk_path)) {
     die "$P: The current directory does not appear to be "
-	. "a linux kernel source tree.\n";
+	. "a QEMU source tree.\n";
 }
 
 ## Read MAINTAINERS for type/value pairs
@@ -792,7 +792,7 @@ Notes:
           --git-min-signatures, --git-max-maintainers, --git-min-percent, and
           --git-blame
       Use --hg-since not --git-since to control date selection
-  File ".get_maintainer.conf", if it exists in the linux kernel source root
+  File ".get_maintainer.conf", if it exists in the QEMU source root
       directory, can change whatever get_maintainer defaults are desired.
       Entries in this file can be any command line argument.
       This file is prepended to any additional command line arguments.
@@ -800,28 +800,18 @@ Notes:
 EOT
 }
 
-sub top_of_kernel_tree {
+sub top_of_tree {
     my ($lk_path) = @_;
 
     if ($lk_path ne "" && substr($lk_path,length($lk_path)-1,1) ne "/") {
 	$lk_path .= "/";
     }
-    if (   (-f "${lk_path}COPYING")
-	&& (-f "${lk_path}CREDITS")
-	&& (-f "${lk_path}Kbuild")
-	&& (-f "${lk_path}MAINTAINERS")
-	&& (-f "${lk_path}Makefile")
-	&& (-f "${lk_path}README")
-	&& (-d "${lk_path}Documentation")
-	&& (-d "${lk_path}arch")
-	&& (-d "${lk_path}include")
-	&& (-d "${lk_path}drivers")
-	&& (-d "${lk_path}fs")
-	&& (-d "${lk_path}init")
-	&& (-d "${lk_path}ipc")
-	&& (-d "${lk_path}kernel")
-	&& (-d "${lk_path}lib")
-	&& (-d "${lk_path}scripts")) {
+    if (    (-f "${lk_path}COPYING")
+        && (-f "${lk_path}MAINTAINERS")
+        && (-f "${lk_path}Makefile")
+        && (-d "${lk_path}docs")
+        && (-f "${lk_path}VERSION")
+        && (-f "${lk_path}vl.c")) {
 	return 1;
     }
     return 0;
@@ -1387,8 +1377,8 @@ sub vcs_exists {
     if (!$printed_novcs) {
 	warn("$P: No supported VCS found.  Add --nogit to options?\n");
 	warn("Using a git repository produces better results.\n");
-	warn("Try Linus Torvalds' latest git repository using:\n");
-	warn("git clone git://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux-2.6.git\n");
+	warn("Try latest git repository using:\n");
+	warn("git clone git://git.qemu.org/qemu.git\n");
 	$printed_novcs = 1;
     }
     return 0;
commit c6a99b6051823ab167f3b0dc80b120d1a787a00f
Author: Michael S. Tsirkin <mst at redhat.com>
Date:   Tue Jun 14 20:13:42 2011 +0300

    get_maintainer.pl: copy utility from Linux
    
    Our MAINTAINERS file format matches Linux so
    get the utility to parse it from there.
    Updated as of linux 3.0-rc3
    
    Signed-off-by: Michael S. Tsirkin <mst at redhat.com>

diff --git a/scripts/get_maintainer.pl b/scripts/get_maintainer.pl
new file mode 100755
index 0000000..d29a8d7
--- /dev/null
+++ b/scripts/get_maintainer.pl
@@ -0,0 +1,2159 @@
+#!/usr/bin/perl -w
+# (c) 2007, Joe Perches <joe at perches.com>
+#           created from checkpatch.pl
+#
+# Print selected MAINTAINERS information for
+# the files modified in a patch or for a file
+#
+# usage: perl scripts/get_maintainer.pl [OPTIONS] <patch>
+#        perl scripts/get_maintainer.pl [OPTIONS] -f <file>
+#
+# Licensed under the terms of the GNU GPL License version 2
+
+use strict;
+
+my $P = $0;
+my $V = '0.26';
+
+use Getopt::Long qw(:config no_auto_abbrev);
+
+my $lk_path = "./";
+my $email = 1;
+my $email_usename = 1;
+my $email_maintainer = 1;
+my $email_list = 1;
+my $email_subscriber_list = 0;
+my $email_git_penguin_chiefs = 0;
+my $email_git = 0;
+my $email_git_all_signature_types = 0;
+my $email_git_blame = 0;
+my $email_git_blame_signatures = 1;
+my $email_git_fallback = 1;
+my $email_git_min_signatures = 1;
+my $email_git_max_maintainers = 5;
+my $email_git_min_percent = 5;
+my $email_git_since = "1-year-ago";
+my $email_hg_since = "-365";
+my $interactive = 0;
+my $email_remove_duplicates = 1;
+my $email_use_mailmap = 1;
+my $output_multiline = 1;
+my $output_separator = ", ";
+my $output_roles = 0;
+my $output_rolestats = 1;
+my $scm = 0;
+my $web = 0;
+my $subsystem = 0;
+my $status = 0;
+my $keywords = 1;
+my $sections = 0;
+my $file_emails = 0;
+my $from_filename = 0;
+my $pattern_depth = 0;
+my $version = 0;
+my $help = 0;
+
+my $vcs_used = 0;
+
+my $exit = 0;
+
+my %commit_author_hash;
+my %commit_signer_hash;
+
+my @penguin_chief = ();
+push(@penguin_chief, "Linus Torvalds:torvalds\@linux-foundation.org");
+#Andrew wants in on most everything - 2009/01/14
+#push(@penguin_chief, "Andrew Morton:akpm\@linux-foundation.org");
+
+my @penguin_chief_names = ();
+foreach my $chief (@penguin_chief) {
+    if ($chief =~ m/^(.*):(.*)/) {
+	my $chief_name = $1;
+	my $chief_addr = $2;
+	push(@penguin_chief_names, $chief_name);
+    }
+}
+my $penguin_chiefs = "\(" . join("|", @penguin_chief_names) . "\)";
+
+# Signature types of people who are either
+# 	a) responsible for the code in question, or
+# 	b) familiar enough with it to give relevant feedback
+my @signature_tags = ();
+push(@signature_tags, "Signed-off-by:");
+push(@signature_tags, "Reviewed-by:");
+push(@signature_tags, "Acked-by:");
+
+# rfc822 email address - preloaded methods go here.
+my $rfc822_lwsp = "(?:(?:\\r\\n)?[ \\t])";
+my $rfc822_char = '[\\000-\\377]';
+
+# VCS command support: class-like functions and strings
+
+my %VCS_cmds;
+
+my %VCS_cmds_git = (
+    "execute_cmd" => \&git_execute_cmd,
+    "available" => '(which("git") ne "") && (-d ".git")',
+    "find_signers_cmd" =>
+	"git log --no-color --since=\$email_git_since " .
+	    '--format="GitCommit: %H%n' .
+		      'GitAuthor: %an <%ae>%n' .
+		      'GitDate: %aD%n' .
+		      'GitSubject: %s%n' .
+		      '%b%n"' .
+	    " -- \$file",
+    "find_commit_signers_cmd" =>
+	"git log --no-color " .
+	    '--format="GitCommit: %H%n' .
+		      'GitAuthor: %an <%ae>%n' .
+		      'GitDate: %aD%n' .
+		      'GitSubject: %s%n' .
+		      '%b%n"' .
+	    " -1 \$commit",
+    "find_commit_author_cmd" =>
+	"git log --no-color " .
+	    '--format="GitCommit: %H%n' .
+		      'GitAuthor: %an <%ae>%n' .
+		      'GitDate: %aD%n' .
+		      'GitSubject: %s%n"' .
+	    " -1 \$commit",
+    "blame_range_cmd" => "git blame -l -L \$diff_start,+\$diff_length \$file",
+    "blame_file_cmd" => "git blame -l \$file",
+    "commit_pattern" => "^GitCommit: ([0-9a-f]{40,40})",
+    "blame_commit_pattern" => "^([0-9a-f]+) ",
+    "author_pattern" => "^GitAuthor: (.*)",
+    "subject_pattern" => "^GitSubject: (.*)",
+);
+
+my %VCS_cmds_hg = (
+    "execute_cmd" => \&hg_execute_cmd,
+    "available" => '(which("hg") ne "") && (-d ".hg")',
+    "find_signers_cmd" =>
+	"hg log --date=\$email_hg_since " .
+	    "--template='HgCommit: {node}\\n" .
+	                "HgAuthor: {author}\\n" .
+			"HgSubject: {desc}\\n'" .
+	    " -- \$file",
+    "find_commit_signers_cmd" =>
+	"hg log " .
+	    "--template='HgSubject: {desc}\\n'" .
+	    " -r \$commit",
+    "find_commit_author_cmd" =>
+	"hg log " .
+	    "--template='HgCommit: {node}\\n" .
+		        "HgAuthor: {author}\\n" .
+			"HgSubject: {desc|firstline}\\n'" .
+	    " -r \$commit",
+    "blame_range_cmd" => "",		# not supported
+    "blame_file_cmd" => "hg blame -n \$file",
+    "commit_pattern" => "^HgCommit: ([0-9a-f]{40,40})",
+    "blame_commit_pattern" => "^([ 0-9a-f]+):",
+    "author_pattern" => "^HgAuthor: (.*)",
+    "subject_pattern" => "^HgSubject: (.*)",
+);
+
+my $conf = which_conf(".get_maintainer.conf");
+if (-f $conf) {
+    my @conf_args;
+    open(my $conffile, '<', "$conf")
+	or warn "$P: Can't find a readable .get_maintainer.conf file $!\n";
+
+    while (<$conffile>) {
+	my $line = $_;
+
+	$line =~ s/\s*\n?$//g;
+	$line =~ s/^\s*//g;
+	$line =~ s/\s+/ /g;
+
+	next if ($line =~ m/^\s*#/);
+	next if ($line =~ m/^\s*$/);
+
+	my @words = split(" ", $line);
+	foreach my $word (@words) {
+	    last if ($word =~ m/^#/);
+	    push (@conf_args, $word);
+	}
+    }
+    close($conffile);
+    unshift(@ARGV, @conf_args) if @conf_args;
+}
+
+if (!GetOptions(
+		'email!' => \$email,
+		'git!' => \$email_git,
+		'git-all-signature-types!' => \$email_git_all_signature_types,
+		'git-blame!' => \$email_git_blame,
+		'git-blame-signatures!' => \$email_git_blame_signatures,
+		'git-fallback!' => \$email_git_fallback,
+		'git-chief-penguins!' => \$email_git_penguin_chiefs,
+		'git-min-signatures=i' => \$email_git_min_signatures,
+		'git-max-maintainers=i' => \$email_git_max_maintainers,
+		'git-min-percent=i' => \$email_git_min_percent,
+		'git-since=s' => \$email_git_since,
+		'hg-since=s' => \$email_hg_since,
+		'i|interactive!' => \$interactive,
+		'remove-duplicates!' => \$email_remove_duplicates,
+		'mailmap!' => \$email_use_mailmap,
+		'm!' => \$email_maintainer,
+		'n!' => \$email_usename,
+		'l!' => \$email_list,
+		's!' => \$email_subscriber_list,
+		'multiline!' => \$output_multiline,
+		'roles!' => \$output_roles,
+		'rolestats!' => \$output_rolestats,
+		'separator=s' => \$output_separator,
+		'subsystem!' => \$subsystem,
+		'status!' => \$status,
+		'scm!' => \$scm,
+		'web!' => \$web,
+		'pattern-depth=i' => \$pattern_depth,
+		'k|keywords!' => \$keywords,
+		'sections!' => \$sections,
+		'fe|file-emails!' => \$file_emails,
+		'f|file' => \$from_filename,
+		'v|version' => \$version,
+		'h|help|usage' => \$help,
+		)) {
+    die "$P: invalid argument - use --help if necessary\n";
+}
+
+if ($help != 0) {
+    usage();
+    exit 0;
+}
+
+if ($version != 0) {
+    print("${P} ${V}\n");
+    exit 0;
+}
+
+if (-t STDIN && !@ARGV) {
+    # We're talking to a terminal, but have no command line arguments.
+    die "$P: missing patchfile or -f file - use --help if necessary\n";
+}
+
+$output_multiline = 0 if ($output_separator ne ", ");
+$output_rolestats = 1 if ($interactive);
+$output_roles = 1 if ($output_rolestats);
+
+if ($sections) {
+    $email = 0;
+    $email_list = 0;
+    $scm = 0;
+    $status = 0;
+    $subsystem = 0;
+    $web = 0;
+    $keywords = 0;
+    $interactive = 0;
+} else {
+    my $selections = $email + $scm + $status + $subsystem + $web;
+    if ($selections == 0) {
+	die "$P:  Missing required option: email, scm, status, subsystem or web\n";
+    }
+}
+
+if ($email &&
+    ($email_maintainer + $email_list + $email_subscriber_list +
+     $email_git + $email_git_penguin_chiefs + $email_git_blame) == 0) {
+    die "$P: Please select at least 1 email option\n";
+}
+
+if (!top_of_kernel_tree($lk_path)) {
+    die "$P: The current directory does not appear to be "
+	. "a linux kernel source tree.\n";
+}
+
+## Read MAINTAINERS for type/value pairs
+
+my @typevalue = ();
+my %keyword_hash;
+
+open (my $maint, '<', "${lk_path}MAINTAINERS")
+    or die "$P: Can't open MAINTAINERS: $!\n";
+while (<$maint>) {
+    my $line = $_;
+
+    if ($line =~ m/^(\C):\s*(.*)/) {
+	my $type = $1;
+	my $value = $2;
+
+	##Filename pattern matching
+	if ($type eq "F" || $type eq "X") {
+	    $value =~ s@\.@\\\. at g;       ##Convert . to \.
+	    $value =~ s/\*/\.\*/g;       ##Convert * to .*
+	    $value =~ s/\?/\./g;         ##Convert ? to .
+	    ##if pattern is a directory and it lacks a trailing slash, add one
+	    if ((-d $value)) {
+		$value =~ s@([^/])$@$1/@;
+	    }
+	} elsif ($type eq "K") {
+	    $keyword_hash{@typevalue} = $value;
+	}
+	push(@typevalue, "$type:$value");
+    } elsif (!/^(\s)*$/) {
+	$line =~ s/\n$//g;
+	push(@typevalue, $line);
+    }
+}
+close($maint);
+
+
+#
+# Read mail address map
+#
+
+my $mailmap;
+
+read_mailmap();
+
+sub read_mailmap {
+    $mailmap = {
+	names => {},
+	addresses => {}
+    };
+
+    return if (!$email_use_mailmap || !(-f "${lk_path}.mailmap"));
+
+    open(my $mailmap_file, '<', "${lk_path}.mailmap")
+	or warn "$P: Can't open .mailmap: $!\n";
+
+    while (<$mailmap_file>) {
+	s/#.*$//; #strip comments
+	s/^\s+|\s+$//g; #trim
+
+	next if (/^\s*$/); #skip empty lines
+	#entries have one of the following formats:
+	# name1 <mail1>
+	# <mail1> <mail2>
+	# name1 <mail1> <mail2>
+	# name1 <mail1> name2 <mail2>
+	# (see man git-shortlog)
+	if (/^(.+)<(.+)>$/) {
+	    my $real_name = $1;
+	    my $address = $2;
+
+	    $real_name =~ s/\s+$//;
+	    ($real_name, $address) = parse_email("$real_name <$address>");
+	    $mailmap->{names}->{$address} = $real_name;
+
+	} elsif (/^<([^\s]+)>\s*<([^\s]+)>$/) {
+	    my $real_address = $1;
+	    my $wrong_address = $2;
+
+	    $mailmap->{addresses}->{$wrong_address} = $real_address;
+
+	} elsif (/^(.+)<([^\s]+)>\s*<([^\s]+)>$/) {
+	    my $real_name = $1;
+	    my $real_address = $2;
+	    my $wrong_address = $3;
+
+	    $real_name =~ s/\s+$//;
+	    ($real_name, $real_address) =
+		parse_email("$real_name <$real_address>");
+	    $mailmap->{names}->{$wrong_address} = $real_name;
+	    $mailmap->{addresses}->{$wrong_address} = $real_address;
+
+	} elsif (/^(.+)<([^\s]+)>\s*([^\s].*)<([^\s]+)>$/) {
+	    my $real_name = $1;
+	    my $real_address = $2;
+	    my $wrong_name = $3;
+	    my $wrong_address = $4;
+
+	    $real_name =~ s/\s+$//;
+	    ($real_name, $real_address) =
+		parse_email("$real_name <$real_address>");
+
+	    $wrong_name =~ s/\s+$//;
+	    ($wrong_name, $wrong_address) =
+		parse_email("$wrong_name <$wrong_address>");
+
+	    my $wrong_email = format_email($wrong_name, $wrong_address, 1);
+	    $mailmap->{names}->{$wrong_email} = $real_name;
+	    $mailmap->{addresses}->{$wrong_email} = $real_address;
+	}
+    }
+    close($mailmap_file);
+}
+
+## use the filenames on the command line or find the filenames in the patchfiles
+
+my @files = ();
+my @range = ();
+my @keyword_tvi = ();
+my @file_emails = ();
+
+if (!@ARGV) {
+    push(@ARGV, "&STDIN");
+}
+
+foreach my $file (@ARGV) {
+    if ($file ne "&STDIN") {
+	##if $file is a directory and it lacks a trailing slash, add one
+	if ((-d $file)) {
+	    $file =~ s@([^/])$@$1/@;
+	} elsif (!(-f $file)) {
+	    die "$P: file '${file}' not found\n";
+	}
+    }
+    if ($from_filename) {
+	push(@files, $file);
+	if ($file ne "MAINTAINERS" && -f $file && ($keywords || $file_emails)) {
+	    open(my $f, '<', $file)
+		or die "$P: Can't open $file: $!\n";
+	    my $text = do { local($/) ; <$f> };
+	    close($f);
+	    if ($keywords) {
+		foreach my $line (keys %keyword_hash) {
+		    if ($text =~ m/$keyword_hash{$line}/x) {
+			push(@keyword_tvi, $line);
+		    }
+		}
+	    }
+	    if ($file_emails) {
+		my @poss_addr = $text =~ m$[A-Za-zÀ-ÿ\"\' \,\.\+-]*\s*[\,]*\s*[\(\<\{]{0,1}[A-Za-z0-9_\.\+-]+\@[A-Za-z0-9\.-]+\.[A-Za-z0-9]+[\)\>\}]{0,1}$g;
+		push(@file_emails, clean_file_emails(@poss_addr));
+	    }
+	}
+    } else {
+	my $file_cnt = @files;
+	my $lastfile;
+
+	open(my $patch, "< $file")
+	    or die "$P: Can't open $file: $!\n";
+
+	# We can check arbitrary information before the patch
+	# like the commit message, mail headers, etc...
+	# This allows us to match arbitrary keywords against any part
+	# of a git format-patch generated file (subject tags, etc...)
+
+	my $patch_prefix = "";			#Parsing the intro
+
+	while (<$patch>) {
+	    my $patch_line = $_;
+	    if (m/^\+\+\+\s+(\S+)/) {
+		my $filename = $1;
+		$filename =~ s@^[^/]*/@@;
+		$filename =~ s@\n@@;
+		$lastfile = $filename;
+		push(@files, $filename);
+		$patch_prefix = "^[+-].*";	#Now parsing the actual patch
+	    } elsif (m/^\@\@ -(\d+),(\d+)/) {
+		if ($email_git_blame) {
+		    push(@range, "$lastfile:$1:$2");
+		}
+	    } elsif ($keywords) {
+		foreach my $line (keys %keyword_hash) {
+		    if ($patch_line =~ m/${patch_prefix}$keyword_hash{$line}/x) {
+			push(@keyword_tvi, $line);
+		    }
+		}
+	    }
+	}
+	close($patch);
+
+	if ($file_cnt == @files) {
+	    warn "$P: file '${file}' doesn't appear to be a patch.  "
+		. "Add -f to options?\n";
+	}
+	@files = sort_and_uniq(@files);
+    }
+}
+
+ at file_emails = uniq(@file_emails);
+
+my %email_hash_name;
+my %email_hash_address;
+my @email_to = ();
+my %hash_list_to;
+my @list_to = ();
+my @scm = ();
+my @web = ();
+my @subsystem = ();
+my @status = ();
+my %deduplicate_name_hash = ();
+my %deduplicate_address_hash = ();
+my $signature_pattern;
+
+my @maintainers = get_maintainers();
+
+if (@maintainers) {
+    @maintainers = merge_email(@maintainers);
+    output(@maintainers);
+}
+
+if ($scm) {
+    @scm = uniq(@scm);
+    output(@scm);
+}
+
+if ($status) {
+    @status = uniq(@status);
+    output(@status);
+}
+
+if ($subsystem) {
+    @subsystem = uniq(@subsystem);
+    output(@subsystem);
+}
+
+if ($web) {
+    @web = uniq(@web);
+    output(@web);
+}
+
+exit($exit);
+
+sub range_is_maintained {
+    my ($start, $end) = @_;
+
+    for (my $i = $start; $i < $end; $i++) {
+	my $line = $typevalue[$i];
+	if ($line =~ m/^(\C):\s*(.*)/) {
+	    my $type = $1;
+	    my $value = $2;
+	    if ($type eq 'S') {
+		if ($value =~ /(maintain|support)/i) {
+		    return 1;
+		}
+	    }
+	}
+    }
+    return 0;
+}
+
+sub range_has_maintainer {
+    my ($start, $end) = @_;
+
+    for (my $i = $start; $i < $end; $i++) {
+	my $line = $typevalue[$i];
+	if ($line =~ m/^(\C):\s*(.*)/) {
+	    my $type = $1;
+	    my $value = $2;
+	    if ($type eq 'M') {
+		return 1;
+	    }
+	}
+    }
+    return 0;
+}
+
+sub get_maintainers {
+    %email_hash_name = ();
+    %email_hash_address = ();
+    %commit_author_hash = ();
+    %commit_signer_hash = ();
+    @email_to = ();
+    %hash_list_to = ();
+    @list_to = ();
+    @scm = ();
+    @web = ();
+    @subsystem = ();
+    @status = ();
+    %deduplicate_name_hash = ();
+    %deduplicate_address_hash = ();
+    if ($email_git_all_signature_types) {
+	$signature_pattern = "(.+?)[Bb][Yy]:";
+    } else {
+	$signature_pattern = "\(" . join("|", @signature_tags) . "\)";
+    }
+
+    # Find responsible parties
+
+    my %exact_pattern_match_hash = ();
+
+    foreach my $file (@files) {
+
+	my %hash;
+	my $tvi = find_first_section();
+	while ($tvi < @typevalue) {
+	    my $start = find_starting_index($tvi);
+	    my $end = find_ending_index($tvi);
+	    my $exclude = 0;
+	    my $i;
+
+	    #Do not match excluded file patterns
+
+	    for ($i = $start; $i < $end; $i++) {
+		my $line = $typevalue[$i];
+		if ($line =~ m/^(\C):\s*(.*)/) {
+		    my $type = $1;
+		    my $value = $2;
+		    if ($type eq 'X') {
+			if (file_match_pattern($file, $value)) {
+			    $exclude = 1;
+			    last;
+			}
+		    }
+		}
+	    }
+
+	    if (!$exclude) {
+		for ($i = $start; $i < $end; $i++) {
+		    my $line = $typevalue[$i];
+		    if ($line =~ m/^(\C):\s*(.*)/) {
+			my $type = $1;
+			my $value = $2;
+			if ($type eq 'F') {
+			    if (file_match_pattern($file, $value)) {
+				my $value_pd = ($value =~ tr@/@@);
+				my $file_pd = ($file  =~ tr@/@@);
+				$value_pd++ if (substr($value,-1,1) ne "/");
+				$value_pd = -1 if ($value =~ /^\.\*/);
+				if ($value_pd >= $file_pd &&
+				    range_is_maintained($start, $end) &&
+				    range_has_maintainer($start, $end)) {
+				    $exact_pattern_match_hash{$file} = 1;
+				}
+				if ($pattern_depth == 0 ||
+				    (($file_pd - $value_pd) < $pattern_depth)) {
+				    $hash{$tvi} = $value_pd;
+				}
+			    }
+			}
+		    }
+		}
+	    }
+	    $tvi = $end + 1;
+	}
+
+	foreach my $line (sort {$hash{$b} <=> $hash{$a}} keys %hash) {
+	    add_categories($line);
+	    if ($sections) {
+		my $i;
+		my $start = find_starting_index($line);
+		my $end = find_ending_index($line);
+		for ($i = $start; $i < $end; $i++) {
+		    my $line = $typevalue[$i];
+		    if ($line =~ /^[FX]:/) {		##Restore file patterns
+			$line =~ s/([^\\])\.([^\*])/$1\?$2/g;
+			$line =~ s/([^\\])\.$/$1\?/g;	##Convert . back to ?
+			$line =~ s/\\\./\./g;       	##Convert \. to .
+			$line =~ s/\.\*/\*/g;       	##Convert .* to *
+		    }
+		    $line =~ s/^([A-Z]):/$1:\t/g;
+		    print("$line\n");
+		}
+		print("\n");
+	    }
+	}
+    }
+
+    if ($keywords) {
+	@keyword_tvi = sort_and_uniq(@keyword_tvi);
+	foreach my $line (@keyword_tvi) {
+	    add_categories($line);
+	}
+    }
+
+    foreach my $email (@email_to, @list_to) {
+	$email->[0] = deduplicate_email($email->[0]);
+    }
+
+    foreach my $file (@files) {
+	if ($email &&
+	    ($email_git || ($email_git_fallback &&
+			    !$exact_pattern_match_hash{$file}))) {
+	    vcs_file_signoffs($file);
+	}
+	if ($email && $email_git_blame) {
+	    vcs_file_blame($file);
+	}
+    }
+
+    if ($email) {
+	foreach my $chief (@penguin_chief) {
+	    if ($chief =~ m/^(.*):(.*)/) {
+		my $email_address;
+
+		$email_address = format_email($1, $2, $email_usename);
+		if ($email_git_penguin_chiefs) {
+		    push(@email_to, [$email_address, 'chief penguin']);
+		} else {
+		    @email_to = grep($_->[0] !~ /${email_address}/, @email_to);
+		}
+	    }
+	}
+
+	foreach my $email (@file_emails) {
+	    my ($name, $address) = parse_email($email);
+
+	    my $tmp_email = format_email($name, $address, $email_usename);
+	    push_email_address($tmp_email, '');
+	    add_role($tmp_email, 'in file');
+	}
+    }
+
+    my @to = ();
+    if ($email || $email_list) {
+	if ($email) {
+	    @to = (@to, @email_to);
+	}
+	if ($email_list) {
+	    @to = (@to, @list_to);
+	}
+    }
+
+    if ($interactive) {
+	@to = interactive_get_maintainers(\@to);
+    }
+
+    return @to;
+}
+
+sub file_match_pattern {
+    my ($file, $pattern) = @_;
+    if (substr($pattern, -1) eq "/") {
+	if ($file =~ m@^$pattern@) {
+	    return 1;
+	}
+    } else {
+	if ($file =~ m@^$pattern@) {
+	    my $s1 = ($file =~ tr@/@@);
+	    my $s2 = ($pattern =~ tr@/@@);
+	    if ($s1 == $s2) {
+		return 1;
+	    }
+	}
+    }
+    return 0;
+}
+
+sub usage {
+    print <<EOT;
+usage: $P [options] patchfile
+       $P [options] -f file|directory
+version: $V
+
+MAINTAINER field selection options:
+  --email => print email address(es) if any
+    --git => include recent git \*-by: signers
+    --git-all-signature-types => include signers regardless of signature type
+        or use only ${signature_pattern} signers (default: $email_git_all_signature_types)
+    --git-fallback => use git when no exact MAINTAINERS pattern (default: $email_git_fallback)
+    --git-chief-penguins => include ${penguin_chiefs}
+    --git-min-signatures => number of signatures required (default: $email_git_min_signatures)
+    --git-max-maintainers => maximum maintainers to add (default: $email_git_max_maintainers)
+    --git-min-percent => minimum percentage of commits required (default: $email_git_min_percent)
+    --git-blame => use git blame to find modified commits for patch or file
+    --git-since => git history to use (default: $email_git_since)
+    --hg-since => hg history to use (default: $email_hg_since)
+    --interactive => display a menu (mostly useful if used with the --git option)
+    --m => include maintainer(s) if any
+    --n => include name 'Full Name <addr\@domain.tld>'
+    --l => include list(s) if any
+    --s => include subscriber only list(s) if any
+    --remove-duplicates => minimize duplicate email names/addresses
+    --roles => show roles (status:subsystem, git-signer, list, etc...)
+    --rolestats => show roles and statistics (commits/total_commits, %)
+    --file-emails => add email addresses found in -f file (default: 0 (off))
+  --scm => print SCM tree(s) if any
+  --status => print status if any
+  --subsystem => print subsystem name if any
+  --web => print website(s) if any
+
+Output type options:
+  --separator [, ] => separator for multiple entries on 1 line
+    using --separator also sets --nomultiline if --separator is not [, ]
+  --multiline => print 1 entry per line
+
+Other options:
+  --pattern-depth => Number of pattern directory traversals (default: 0 (all))
+  --keywords => scan patch for keywords (default: $keywords)
+  --sections => print all of the subsystem sections with pattern matches
+  --mailmap => use .mailmap file (default: $email_use_mailmap)
+  --version => show version
+  --help => show this help information
+
+Default options:
+  [--email --nogit --git-fallback --m --n --l --multiline -pattern-depth=0
+   --remove-duplicates --rolestats]
+
+Notes:
+  Using "-f directory" may give unexpected results:
+      Used with "--git", git signators for _all_ files in and below
+          directory are examined as git recurses directories.
+          Any specified X: (exclude) pattern matches are _not_ ignored.
+      Used with "--nogit", directory is used as a pattern match,
+          no individual file within the directory or subdirectory
+          is matched.
+      Used with "--git-blame", does not iterate all files in directory
+  Using "--git-blame" is slow and may add old committers and authors
+      that are no longer active maintainers to the output.
+  Using "--roles" or "--rolestats" with git send-email --cc-cmd or any
+      other automated tools that expect only ["name"] <email address>
+      may not work because of additional output after <email address>.
+  Using "--rolestats" and "--git-blame" shows the #/total=% commits,
+      not the percentage of the entire file authored.  # of commits is
+      not a good measure of amount of code authored.  1 major commit may
+      contain a thousand lines, 5 trivial commits may modify a single line.
+  If git is not installed, but mercurial (hg) is installed and an .hg
+      repository exists, the following options apply to mercurial:
+          --git,
+          --git-min-signatures, --git-max-maintainers, --git-min-percent, and
+          --git-blame
+      Use --hg-since not --git-since to control date selection
+  File ".get_maintainer.conf", if it exists in the linux kernel source root
+      directory, can change whatever get_maintainer defaults are desired.
+      Entries in this file can be any command line argument.
+      This file is prepended to any additional command line arguments.
+      Multiple lines and # comments are allowed.
+EOT
+}
+
+sub top_of_kernel_tree {
+    my ($lk_path) = @_;
+
+    if ($lk_path ne "" && substr($lk_path,length($lk_path)-1,1) ne "/") {
+	$lk_path .= "/";
+    }
+    if (   (-f "${lk_path}COPYING")
+	&& (-f "${lk_path}CREDITS")
+	&& (-f "${lk_path}Kbuild")
+	&& (-f "${lk_path}MAINTAINERS")
+	&& (-f "${lk_path}Makefile")
+	&& (-f "${lk_path}README")
+	&& (-d "${lk_path}Documentation")
+	&& (-d "${lk_path}arch")
+	&& (-d "${lk_path}include")
+	&& (-d "${lk_path}drivers")
+	&& (-d "${lk_path}fs")
+	&& (-d "${lk_path}init")
+	&& (-d "${lk_path}ipc")
+	&& (-d "${lk_path}kernel")
+	&& (-d "${lk_path}lib")
+	&& (-d "${lk_path}scripts")) {
+	return 1;
+    }
+    return 0;
+}
+
+sub parse_email {
+    my ($formatted_email) = @_;
+
+    my $name = "";
+    my $address = "";
+
+    if ($formatted_email =~ /^([^<]+)<(.+\@.*)>.*$/) {
+	$name = $1;
+	$address = $2;
+    } elsif ($formatted_email =~ /^\s*<(.+\@\S*)>.*$/) {
+	$address = $1;
+    } elsif ($formatted_email =~ /^(.+\@\S*).*$/) {
+	$address = $1;
+    }
+
+    $name =~ s/^\s+|\s+$//g;
+    $name =~ s/^\"|\"$//g;
+    $address =~ s/^\s+|\s+$//g;
+
+    if ($name =~ /[^\w \-]/i) {  	 ##has "must quote" chars
+	$name =~ s/(?<!\\)"/\\"/g;       ##escape quotes
+	$name = "\"$name\"";
+    }
+
+    return ($name, $address);
+}
+
+sub format_email {
+    my ($name, $address, $usename) = @_;
+
+    my $formatted_email;
+
+    $name =~ s/^\s+|\s+$//g;
+    $name =~ s/^\"|\"$//g;
+    $address =~ s/^\s+|\s+$//g;
+
+    if ($name =~ /[^\w \-]/i) {          ##has "must quote" chars
+	$name =~ s/(?<!\\)"/\\"/g;       ##escape quotes
+	$name = "\"$name\"";
+    }
+
+    if ($usename) {
+	if ("$name" eq "") {
+	    $formatted_email = "$address";
+	} else {
+	    $formatted_email = "$name <$address>";
+	}
+    } else {
+	$formatted_email = $address;
+    }
+
+    return $formatted_email;
+}
+
+sub find_first_section {
+    my $index = 0;
+
+    while ($index < @typevalue) {
+	my $tv = $typevalue[$index];
+	if (($tv =~ m/^(\C):\s*(.*)/)) {
+	    last;
+	}
+	$index++;
+    }
+
+    return $index;
+}
+
+sub find_starting_index {
+    my ($index) = @_;
+
+    while ($index > 0) {
+	my $tv = $typevalue[$index];
+	if (!($tv =~ m/^(\C):\s*(.*)/)) {
+	    last;
+	}
+	$index--;
+    }
+
+    return $index;
+}
+
+sub find_ending_index {
+    my ($index) = @_;
+
+    while ($index < @typevalue) {
+	my $tv = $typevalue[$index];
+	if (!($tv =~ m/^(\C):\s*(.*)/)) {
+	    last;
+	}
+	$index++;
+    }
+
+    return $index;
+}
+
+sub get_maintainer_role {
+    my ($index) = @_;
+
+    my $i;
+    my $start = find_starting_index($index);
+    my $end = find_ending_index($index);
+
+    my $role;
+    my $subsystem = $typevalue[$start];
+    if (length($subsystem) > 20) {
+	$subsystem = substr($subsystem, 0, 17);
+	$subsystem =~ s/\s*$//;
+	$subsystem = $subsystem . "...";
+    }
+
+    for ($i = $start + 1; $i < $end; $i++) {
+	my $tv = $typevalue[$i];
+	if ($tv =~ m/^(\C):\s*(.*)/) {
+	    my $ptype = $1;
+	    my $pvalue = $2;
+	    if ($ptype eq "S") {
+		$role = $pvalue;
+	    }
+	}
+    }
+
+    $role = lc($role);
+    if      ($role eq "supported") {
+	$role = "supporter";
+    } elsif ($role eq "maintained") {
+	$role = "maintainer";
+    } elsif ($role eq "odd fixes") {
+	$role = "odd fixer";
+    } elsif ($role eq "orphan") {
+	$role = "orphan minder";
+    } elsif ($role eq "obsolete") {
+	$role = "obsolete minder";
+    } elsif ($role eq "buried alive in reporters") {
+	$role = "chief penguin";
+    }
+
+    return $role . ":" . $subsystem;
+}
+
+sub get_list_role {
+    my ($index) = @_;
+
+    my $i;
+    my $start = find_starting_index($index);
+    my $end = find_ending_index($index);
+
+    my $subsystem = $typevalue[$start];
+    if (length($subsystem) > 20) {
+	$subsystem = substr($subsystem, 0, 17);
+	$subsystem =~ s/\s*$//;
+	$subsystem = $subsystem . "...";
+    }
+
+    if ($subsystem eq "THE REST") {
+	$subsystem = "";
+    }
+
+    return $subsystem;
+}
+
+sub add_categories {
+    my ($index) = @_;
+
+    my $i;
+    my $start = find_starting_index($index);
+    my $end = find_ending_index($index);
+
+    push(@subsystem, $typevalue[$start]);
+
+    for ($i = $start + 1; $i < $end; $i++) {
+	my $tv = $typevalue[$i];
+	if ($tv =~ m/^(\C):\s*(.*)/) {
+	    my $ptype = $1;
+	    my $pvalue = $2;
+	    if ($ptype eq "L") {
+		my $list_address = $pvalue;
+		my $list_additional = "";
+		my $list_role = get_list_role($i);
+
+		if ($list_role ne "") {
+		    $list_role = ":" . $list_role;
+		}
+		if ($list_address =~ m/([^\s]+)\s+(.*)$/) {
+		    $list_address = $1;
+		    $list_additional = $2;
+		}
+		if ($list_additional =~ m/subscribers-only/) {
+		    if ($email_subscriber_list) {
+			if (!$hash_list_to{lc($list_address)}) {
+			    $hash_list_to{lc($list_address)} = 1;
+			    push(@list_to, [$list_address,
+					    "subscriber list${list_role}"]);
+			}
+		    }
+		} else {
+		    if ($email_list) {
+			if (!$hash_list_to{lc($list_address)}) {
+			    $hash_list_to{lc($list_address)} = 1;
+			    push(@list_to, [$list_address,
+					    "open list${list_role}"]);
+			}
+		    }
+		}
+	    } elsif ($ptype eq "M") {
+		my ($name, $address) = parse_email($pvalue);
+		if ($name eq "") {
+		    if ($i > 0) {
+			my $tv = $typevalue[$i - 1];
+			if ($tv =~ m/^(\C):\s*(.*)/) {
+			    if ($1 eq "P") {
+				$name = $2;
+				$pvalue = format_email($name, $address, $email_usename);
+			    }
+			}
+		    }
+		}
+		if ($email_maintainer) {
+		    my $role = get_maintainer_role($i);
+		    push_email_addresses($pvalue, $role);
+		}
+	    } elsif ($ptype eq "T") {
+		push(@scm, $pvalue);
+	    } elsif ($ptype eq "W") {
+		push(@web, $pvalue);
+	    } elsif ($ptype eq "S") {
+		push(@status, $pvalue);
+	    }
+	}
+    }
+}
+
+sub email_inuse {
+    my ($name, $address) = @_;
+
+    return 1 if (($name eq "") && ($address eq ""));
+    return 1 if (($name ne "") && exists($email_hash_name{lc($name)}));
+    return 1 if (($address ne "") && exists($email_hash_address{lc($address)}));
+
+    return 0;
+}
+
+sub push_email_address {
+    my ($line, $role) = @_;
+
+    my ($name, $address) = parse_email($line);
+
+    if ($address eq "") {
+	return 0;
+    }
+
+    if (!$email_remove_duplicates) {
+	push(@email_to, [format_email($name, $address, $email_usename), $role]);
+    } elsif (!email_inuse($name, $address)) {
+	push(@email_to, [format_email($name, $address, $email_usename), $role]);
+	$email_hash_name{lc($name)}++ if ($name ne "");
+	$email_hash_address{lc($address)}++;
+    }
+
+    return 1;
+}
+
+sub push_email_addresses {
+    my ($address, $role) = @_;
+
+    my @address_list = ();
+
+    if (rfc822_valid($address)) {
+	push_email_address($address, $role);
+    } elsif (@address_list = rfc822_validlist($address)) {
+	my $array_count = shift(@address_list);
+	while (my $entry = shift(@address_list)) {
+	    push_email_address($entry, $role);
+	}
+    } else {
+	if (!push_email_address($address, $role)) {
+	    warn("Invalid MAINTAINERS address: '" . $address . "'\n");
+	}
+    }
+}
+
+sub add_role {
+    my ($line, $role) = @_;
+
+    my ($name, $address) = parse_email($line);
+    my $email = format_email($name, $address, $email_usename);
+
+    foreach my $entry (@email_to) {
+	if ($email_remove_duplicates) {
+	    my ($entry_name, $entry_address) = parse_email($entry->[0]);
+	    if (($name eq $entry_name || $address eq $entry_address)
+		&& ($role eq "" || !($entry->[1] =~ m/$role/))
+	    ) {
+		if ($entry->[1] eq "") {
+		    $entry->[1] = "$role";
+		} else {
+		    $entry->[1] = "$entry->[1],$role";
+		}
+	    }
+	} else {
+	    if ($email eq $entry->[0]
+		&& ($role eq "" || !($entry->[1] =~ m/$role/))
+	    ) {
+		if ($entry->[1] eq "") {
+		    $entry->[1] = "$role";
+		} else {
+		    $entry->[1] = "$entry->[1],$role";
+		}
+	    }
+	}
+    }
+}
+
+sub which {
+    my ($bin) = @_;
+
+    foreach my $path (split(/:/, $ENV{PATH})) {
+	if (-e "$path/$bin") {
+	    return "$path/$bin";
+	}
+    }
+
+    return "";
+}
+
+sub which_conf {
+    my ($conf) = @_;
+
+    foreach my $path (split(/:/, ".:$ENV{HOME}:.scripts")) {
+	if (-e "$path/$conf") {
+	    return "$path/$conf";
+	}
+    }
+
+    return "";
+}
+
+sub mailmap_email {
+    my ($line) = @_;
+
+    my ($name, $address) = parse_email($line);
+    my $email = format_email($name, $address, 1);
+    my $real_name = $name;
+    my $real_address = $address;
+
+    if (exists $mailmap->{names}->{$email} ||
+	exists $mailmap->{addresses}->{$email}) {
+	if (exists $mailmap->{names}->{$email}) {
+	    $real_name = $mailmap->{names}->{$email};
+	}
+	if (exists $mailmap->{addresses}->{$email}) {
+	    $real_address = $mailmap->{addresses}->{$email};
+	}
+    } else {
+	if (exists $mailmap->{names}->{$address}) {
+	    $real_name = $mailmap->{names}->{$address};
+	}
+	if (exists $mailmap->{addresses}->{$address}) {
+	    $real_address = $mailmap->{addresses}->{$address};
+	}
+    }
+    return format_email($real_name, $real_address, 1);
+}
+
+sub mailmap {
+    my (@addresses) = @_;
+
+    my @mapped_emails = ();
+    foreach my $line (@addresses) {
+	push(@mapped_emails, mailmap_email($line));
+    }
+    merge_by_realname(@mapped_emails) if ($email_use_mailmap);
+    return @mapped_emails;
+}
+
+sub merge_by_realname {
+    my %address_map;
+    my (@emails) = @_;
+
+    foreach my $email (@emails) {
+	my ($name, $address) = parse_email($email);
+	if (exists $address_map{$name}) {
+	    $address = $address_map{$name};
+	    $email = format_email($name, $address, 1);
+	} else {
+	    $address_map{$name} = $address;
+	}
+    }
+}
+
+sub git_execute_cmd {
+    my ($cmd) = @_;
+    my @lines = ();
+
+    my $output = `$cmd`;
+    $output =~ s/^\s*//gm;
+    @lines = split("\n", $output);
+
+    return @lines;
+}
+
+sub hg_execute_cmd {
+    my ($cmd) = @_;
+    my @lines = ();
+
+    my $output = `$cmd`;
+    @lines = split("\n", $output);
+
+    return @lines;
+}
+
+sub extract_formatted_signatures {
+    my (@signature_lines) = @_;
+
+    my @type = @signature_lines;
+
+    s/\s*(.*):.*/$1/ for (@type);
+
+    # cut -f2- -d":"
+    s/\s*.*:\s*(.+)\s*/$1/ for (@signature_lines);
+
+## Reformat email addresses (with names) to avoid badly written signatures
+
+    foreach my $signer (@signature_lines) {
+	$signer = deduplicate_email($signer);
+    }
+
+    return (\@type, \@signature_lines);
+}
+
+sub vcs_find_signers {
+    my ($cmd) = @_;
+    my $commits;
+    my @lines = ();
+    my @signatures = ();
+
+    @lines = &{$VCS_cmds{"execute_cmd"}}($cmd);
+
+    my $pattern = $VCS_cmds{"commit_pattern"};
+
+    $commits = grep(/$pattern/, @lines);	# of commits
+
+    @signatures = grep(/^[ \t]*${signature_pattern}.*\@.*$/, @lines);
+
+    return (0, @signatures) if !@signatures;
+
+    save_commits_by_author(@lines) if ($interactive);
+    save_commits_by_signer(@lines) if ($interactive);
+
+    if (!$email_git_penguin_chiefs) {
+	@signatures = grep(!/${penguin_chiefs}/i, @signatures);
+    }
+
+    my ($types_ref, $signers_ref) = extract_formatted_signatures(@signatures);
+
+    return ($commits, @$signers_ref);
+}
+
+sub vcs_find_author {
+    my ($cmd) = @_;
+    my @lines = ();
+
+    @lines = &{$VCS_cmds{"execute_cmd"}}($cmd);
+
+    if (!$email_git_penguin_chiefs) {
+	@lines = grep(!/${penguin_chiefs}/i, @lines);
+    }
+
+    return @lines if !@lines;
+
+    my @authors = ();
+    foreach my $line (@lines) {
+	if ($line =~ m/$VCS_cmds{"author_pattern"}/) {
+	    my $author = $1;
+	    my ($name, $address) = parse_email($author);
+	    $author = format_email($name, $address, 1);
+	    push(@authors, $author);
+	}
+    }
+
+    save_commits_by_author(@lines) if ($interactive);
+    save_commits_by_signer(@lines) if ($interactive);
+
+    return @authors;
+}
+
+sub vcs_save_commits {
+    my ($cmd) = @_;
+    my @lines = ();
+    my @commits = ();
+
+    @lines = &{$VCS_cmds{"execute_cmd"}}($cmd);
+
+    foreach my $line (@lines) {
+	if ($line =~ m/$VCS_cmds{"blame_commit_pattern"}/) {
+	    push(@commits, $1);
+	}
+    }
+
+    return @commits;
+}
+
+sub vcs_blame {
+    my ($file) = @_;
+    my $cmd;
+    my @commits = ();
+
+    return @commits if (!(-f $file));
+
+    if (@range && $VCS_cmds{"blame_range_cmd"} eq "") {
+	my @all_commits = ();
+
+	$cmd = $VCS_cmds{"blame_file_cmd"};
+	$cmd =~ s/(\$\w+)/$1/eeg;		#interpolate $cmd
+	@all_commits = vcs_save_commits($cmd);
+
+	foreach my $file_range_diff (@range) {
+	    next if (!($file_range_diff =~ m/(.+):(.+):(.+)/));
+	    my $diff_file = $1;
+	    my $diff_start = $2;
+	    my $diff_length = $3;
+	    next if ("$file" ne "$diff_file");
+	    for (my $i = $diff_start; $i < $diff_start + $diff_length; $i++) {
+		push(@commits, $all_commits[$i]);
+	    }
+	}
+    } elsif (@range) {
+	foreach my $file_range_diff (@range) {
+	    next if (!($file_range_diff =~ m/(.+):(.+):(.+)/));
+	    my $diff_file = $1;
+	    my $diff_start = $2;
+	    my $diff_length = $3;
+	    next if ("$file" ne "$diff_file");
+	    $cmd = $VCS_cmds{"blame_range_cmd"};
+	    $cmd =~ s/(\$\w+)/$1/eeg;		#interpolate $cmd
+	    push(@commits, vcs_save_commits($cmd));
+	}
+    } else {
+	$cmd = $VCS_cmds{"blame_file_cmd"};
+	$cmd =~ s/(\$\w+)/$1/eeg;		#interpolate $cmd
+	@commits = vcs_save_commits($cmd);
+    }
+
+    foreach my $commit (@commits) {
+	$commit =~ s/^\^//g;
+    }
+
+    return @commits;
+}
+
+my $printed_novcs = 0;
+sub vcs_exists {
+    %VCS_cmds = %VCS_cmds_git;
+    return 1 if eval $VCS_cmds{"available"};
+    %VCS_cmds = %VCS_cmds_hg;
+    return 2 if eval $VCS_cmds{"available"};
+    %VCS_cmds = ();
+    if (!$printed_novcs) {
+	warn("$P: No supported VCS found.  Add --nogit to options?\n");
+	warn("Using a git repository produces better results.\n");
+	warn("Try Linus Torvalds' latest git repository using:\n");
+	warn("git clone git://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux-2.6.git\n");
+	$printed_novcs = 1;
+    }
+    return 0;
+}
+
+sub vcs_is_git {
+    vcs_exists();
+    return $vcs_used == 1;
+}
+
+sub vcs_is_hg {
+    return $vcs_used == 2;
+}
+
+sub interactive_get_maintainers {
+    my ($list_ref) = @_;
+    my @list = @$list_ref;
+
+    vcs_exists();
+
+    my %selected;
+    my %authored;
+    my %signed;
+    my $count = 0;
+    my $maintained = 0;
+    foreach my $entry (@list) {
+	$maintained = 1 if ($entry->[1] =~ /^(maintainer|supporter)/i);
+	$selected{$count} = 1;
+	$authored{$count} = 0;
+	$signed{$count} = 0;
+	$count++;
+    }
+
+    #menu loop
+    my $done = 0;
+    my $print_options = 0;
+    my $redraw = 1;
+    while (!$done) {
+	$count = 0;
+	if ($redraw) {
+	    printf STDERR "\n%1s %2s %-65s",
+			  "*", "#", "email/list and role:stats";
+	    if ($email_git ||
+		($email_git_fallback && !$maintained) ||
+		$email_git_blame) {
+		print STDERR "auth sign";
+	    }
+	    print STDERR "\n";
+	    foreach my $entry (@list) {
+		my $email = $entry->[0];
+		my $role = $entry->[1];
+		my $sel = "";
+		$sel = "*" if ($selected{$count});
+		my $commit_author = $commit_author_hash{$email};
+		my $commit_signer = $commit_signer_hash{$email};
+		my $authored = 0;
+		my $signed = 0;
+		$authored++ for (@{$commit_author});
+		$signed++ for (@{$commit_signer});
+		printf STDERR "%1s %2d %-65s", $sel, $count + 1, $email;
+		printf STDERR "%4d %4d", $authored, $signed
+		    if ($authored > 0 || $signed > 0);
+		printf STDERR "\n     %s\n", $role;
+		if ($authored{$count}) {
+		    my $commit_author = $commit_author_hash{$email};
+		    foreach my $ref (@{$commit_author}) {
+			print STDERR "     Author: @{$ref}[1]\n";
+		    }
+		}
+		if ($signed{$count}) {
+		    my $commit_signer = $commit_signer_hash{$email};
+		    foreach my $ref (@{$commit_signer}) {
+			print STDERR "     @{$ref}[2]: @{$ref}[1]\n";
+		    }
+		}
+
+		$count++;
+	    }
+	}
+	my $date_ref = \$email_git_since;
+	$date_ref = \$email_hg_since if (vcs_is_hg());
+	if ($print_options) {
+	    $print_options = 0;
+	    if (vcs_exists()) {
+		print STDERR <<EOT
+
+Version Control options:
+g  use git history      [$email_git]
+gf use git-fallback     [$email_git_fallback]
+b  use git blame        [$email_git_blame]
+bs use blame signatures [$email_git_blame_signatures]
+c# minimum commits      [$email_git_min_signatures]
+%# min percent          [$email_git_min_percent]
+d# history to use       [$$date_ref]
+x# max maintainers      [$email_git_max_maintainers]
+t  all signature types  [$email_git_all_signature_types]
+m  use .mailmap         [$email_use_mailmap]
+EOT
+	    }
+	    print STDERR <<EOT
+
+Additional options:
+0  toggle all
+tm toggle maintainers
+tg toggle git entries
+tl toggle open list entries
+ts toggle subscriber list entries
+f  emails in file       [$file_emails]
+k  keywords in file     [$keywords]
+r  remove duplicates    [$email_remove_duplicates]
+p# pattern match depth  [$pattern_depth]
+EOT
+	}
+	print STDERR
+"\n#(toggle), A#(author), S#(signed) *(all), ^(none), O(options), Y(approve): ";
+
+	my $input = <STDIN>;
+	chomp($input);
+
+	$redraw = 1;
+	my $rerun = 0;
+	my @wish = split(/[, ]+/, $input);
+	foreach my $nr (@wish) {
+	    $nr = lc($nr);
+	    my $sel = substr($nr, 0, 1);
+	    my $str = substr($nr, 1);
+	    my $val = 0;
+	    $val = $1 if $str =~ /^(\d+)$/;
+
+	    if ($sel eq "y") {
+		$interactive = 0;
+		$done = 1;
+		$output_rolestats = 0;
+		$output_roles = 0;
+		last;
+	    } elsif ($nr =~ /^\d+$/ && $nr > 0 && $nr <= $count) {
+		$selected{$nr - 1} = !$selected{$nr - 1};
+	    } elsif ($sel eq "*" || $sel eq '^') {
+		my $toggle = 0;
+		$toggle = 1 if ($sel eq '*');
+		for (my $i = 0; $i < $count; $i++) {
+		    $selected{$i} = $toggle;
+		}
+	    } elsif ($sel eq "0") {
+		for (my $i = 0; $i < $count; $i++) {
+		    $selected{$i} = !$selected{$i};
+		}
+	    } elsif ($sel eq "t") {
+		if (lc($str) eq "m") {
+		    for (my $i = 0; $i < $count; $i++) {
+			$selected{$i} = !$selected{$i}
+			    if ($list[$i]->[1] =~ /^(maintainer|supporter)/i);
+		    }
+		} elsif (lc($str) eq "g") {
+		    for (my $i = 0; $i < $count; $i++) {
+			$selected{$i} = !$selected{$i}
+			    if ($list[$i]->[1] =~ /^(author|commit|signer)/i);
+		    }
+		} elsif (lc($str) eq "l") {
+		    for (my $i = 0; $i < $count; $i++) {
+			$selected{$i} = !$selected{$i}
+			    if ($list[$i]->[1] =~ /^(open list)/i);
+		    }
+		} elsif (lc($str) eq "s") {
+		    for (my $i = 0; $i < $count; $i++) {
+			$selected{$i} = !$selected{$i}
+			    if ($list[$i]->[1] =~ /^(subscriber list)/i);
+		    }
+		}
+	    } elsif ($sel eq "a") {
+		if ($val > 0 && $val <= $count) {
+		    $authored{$val - 1} = !$authored{$val - 1};
+		} elsif ($str eq '*' || $str eq '^') {
+		    my $toggle = 0;
+		    $toggle = 1 if ($str eq '*');
+		    for (my $i = 0; $i < $count; $i++) {
+			$authored{$i} = $toggle;
+		    }
+		}
+	    } elsif ($sel eq "s") {
+		if ($val > 0 && $val <= $count) {
+		    $signed{$val - 1} = !$signed{$val - 1};
+		} elsif ($str eq '*' || $str eq '^') {
+		    my $toggle = 0;
+		    $toggle = 1 if ($str eq '*');
+		    for (my $i = 0; $i < $count; $i++) {
+			$signed{$i} = $toggle;
+		    }
+		}
+	    } elsif ($sel eq "o") {
+		$print_options = 1;
+		$redraw = 1;
+	    } elsif ($sel eq "g") {
+		if ($str eq "f") {
+		    bool_invert(\$email_git_fallback);
+		} else {
+		    bool_invert(\$email_git);
+		}
+		$rerun = 1;
+	    } elsif ($sel eq "b") {
+		if ($str eq "s") {
+		    bool_invert(\$email_git_blame_signatures);
+		} else {
+		    bool_invert(\$email_git_blame);
+		}
+		$rerun = 1;
+	    } elsif ($sel eq "c") {
+		if ($val > 0) {
+		    $email_git_min_signatures = $val;
+		    $rerun = 1;
+		}
+	    } elsif ($sel eq "x") {
+		if ($val > 0) {
+		    $email_git_max_maintainers = $val;
+		    $rerun = 1;
+		}
+	    } elsif ($sel eq "%") {
+		if ($str ne "" && $val >= 0) {
+		    $email_git_min_percent = $val;
+		    $rerun = 1;
+		}
+	    } elsif ($sel eq "d") {
+		if (vcs_is_git()) {
+		    $email_git_since = $str;
+		} elsif (vcs_is_hg()) {
+		    $email_hg_since = $str;
+		}
+		$rerun = 1;
+	    } elsif ($sel eq "t") {
+		bool_invert(\$email_git_all_signature_types);
+		$rerun = 1;
+	    } elsif ($sel eq "f") {
+		bool_invert(\$file_emails);
+		$rerun = 1;
+	    } elsif ($sel eq "r") {
+		bool_invert(\$email_remove_duplicates);
+		$rerun = 1;
+	    } elsif ($sel eq "m") {
+		bool_invert(\$email_use_mailmap);
+		read_mailmap();
+		$rerun = 1;
+	    } elsif ($sel eq "k") {
+		bool_invert(\$keywords);
+		$rerun = 1;
+	    } elsif ($sel eq "p") {
+		if ($str ne "" && $val >= 0) {
+		    $pattern_depth = $val;
+		    $rerun = 1;
+		}
+	    } elsif ($sel eq "h" || $sel eq "?") {
+		print STDERR <<EOT
+
+Interactive mode allows you to select the various maintainers, submitters,
+commit signers and mailing lists that could be CC'd on a patch.
+
+Any *'d entry is selected.
+
+If you have git or hg installed, you can choose to summarize the commit
+history of files in the patch.  Also, each line of the current file can
+be matched to its commit author and that commits signers with blame.
+
+Various knobs exist to control the length of time for active commit
+tracking, the maximum number of commit authors and signers to add,
+and such.
+
+Enter selections at the prompt until you are satisfied that the selected
+maintainers are appropriate.  You may enter multiple selections separated
+by either commas or spaces.
+
+EOT
+	    } else {
+		print STDERR "invalid option: '$nr'\n";
+		$redraw = 0;
+	    }
+	}
+	if ($rerun) {
+	    print STDERR "git-blame can be very slow, please have patience..."
+		if ($email_git_blame);
+	    goto &get_maintainers;
+	}
+    }
+
+    #drop not selected entries
+    $count = 0;
+    my @new_emailto = ();
+    foreach my $entry (@list) {
+	if ($selected{$count}) {
+	    push(@new_emailto, $list[$count]);
+	}
+	$count++;
+    }
+    return @new_emailto;
+}
+
+sub bool_invert {
+    my ($bool_ref) = @_;
+
+    if ($$bool_ref) {
+	$$bool_ref = 0;
+    } else {
+	$$bool_ref = 1;
+    }
+}
+
+sub deduplicate_email {
+    my ($email) = @_;
+
+    my $matched = 0;
+    my ($name, $address) = parse_email($email);
+    $email = format_email($name, $address, 1);
+    $email = mailmap_email($email);
+
+    return $email if (!$email_remove_duplicates);
+
+    ($name, $address) = parse_email($email);
+
+    if ($name ne "" && $deduplicate_name_hash{lc($name)}) {
+	$name = $deduplicate_name_hash{lc($name)}->[0];
+	$address = $deduplicate_name_hash{lc($name)}->[1];
+	$matched = 1;
+    } elsif ($deduplicate_address_hash{lc($address)}) {
+	$name = $deduplicate_address_hash{lc($address)}->[0];
+	$address = $deduplicate_address_hash{lc($address)}->[1];
+	$matched = 1;
+    }
+    if (!$matched) {
+	$deduplicate_name_hash{lc($name)} = [ $name, $address ];
+	$deduplicate_address_hash{lc($address)} = [ $name, $address ];
+    }
+    $email = format_email($name, $address, 1);
+    $email = mailmap_email($email);
+    return $email;
+}
+
+sub save_commits_by_author {
+    my (@lines) = @_;
+
+    my @authors = ();
+    my @commits = ();
+    my @subjects = ();
+
+    foreach my $line (@lines) {
+	if ($line =~ m/$VCS_cmds{"author_pattern"}/) {
+	    my $author = $1;
+	    $author = deduplicate_email($author);
+	    push(@authors, $author);
+	}
+	push(@commits, $1) if ($line =~ m/$VCS_cmds{"commit_pattern"}/);
+	push(@subjects, $1) if ($line =~ m/$VCS_cmds{"subject_pattern"}/);
+    }
+
+    for (my $i = 0; $i < @authors; $i++) {
+	my $exists = 0;
+	foreach my $ref(@{$commit_author_hash{$authors[$i]}}) {
+	    if (@{$ref}[0] eq $commits[$i] &&
+		@{$ref}[1] eq $subjects[$i]) {
+		$exists = 1;
+		last;
+	    }
+	}
+	if (!$exists) {
+	    push(@{$commit_author_hash{$authors[$i]}},
+		 [ ($commits[$i], $subjects[$i]) ]);
+	}
+    }
+}
+
+sub save_commits_by_signer {
+    my (@lines) = @_;
+
+    my $commit = "";
+    my $subject = "";
+
+    foreach my $line (@lines) {
+	$commit = $1 if ($line =~ m/$VCS_cmds{"commit_pattern"}/);
+	$subject = $1 if ($line =~ m/$VCS_cmds{"subject_pattern"}/);
+	if ($line =~ /^[ \t]*${signature_pattern}.*\@.*$/) {
+	    my @signatures = ($line);
+	    my ($types_ref, $signers_ref) = extract_formatted_signatures(@signatures);
+	    my @types = @$types_ref;
+	    my @signers = @$signers_ref;
+
+	    my $type = $types[0];
+	    my $signer = $signers[0];
+
+	    $signer = deduplicate_email($signer);
+
+	    my $exists = 0;
+	    foreach my $ref(@{$commit_signer_hash{$signer}}) {
+		if (@{$ref}[0] eq $commit &&
+		    @{$ref}[1] eq $subject &&
+		    @{$ref}[2] eq $type) {
+		    $exists = 1;
+		    last;
+		}
+	    }
+	    if (!$exists) {
+		push(@{$commit_signer_hash{$signer}},
+		     [ ($commit, $subject, $type) ]);
+	    }
+	}
+    }
+}
+
+sub vcs_assign {
+    my ($role, $divisor, @lines) = @_;
+
+    my %hash;
+    my $count = 0;
+
+    return if (@lines <= 0);
+
+    if ($divisor <= 0) {
+	warn("Bad divisor in " . (caller(0))[3] . ": $divisor\n");
+	$divisor = 1;
+    }
+
+    @lines = mailmap(@lines);
+
+    return if (@lines <= 0);
+
+    @lines = sort(@lines);
+
+    # uniq -c
+    $hash{$_}++ for @lines;
+
+    # sort -rn
+    foreach my $line (sort {$hash{$b} <=> $hash{$a}} keys %hash) {
+	my $sign_offs = $hash{$line};
+	my $percent = $sign_offs * 100 / $divisor;
+
+	$percent = 100 if ($percent > 100);
+	$count++;
+	last if ($sign_offs < $email_git_min_signatures ||
+		 $count > $email_git_max_maintainers ||
+		 $percent < $email_git_min_percent);
+	push_email_address($line, '');
+	if ($output_rolestats) {
+	    my $fmt_percent = sprintf("%.0f", $percent);
+	    add_role($line, "$role:$sign_offs/$divisor=$fmt_percent%");
+	} else {
+	    add_role($line, $role);
+	}
+    }
+}
+
+sub vcs_file_signoffs {
+    my ($file) = @_;
+
+    my @signers = ();
+    my $commits;
+
+    $vcs_used = vcs_exists();
+    return if (!$vcs_used);
+
+    my $cmd = $VCS_cmds{"find_signers_cmd"};
+    $cmd =~ s/(\$\w+)/$1/eeg;		# interpolate $cmd
+
+    ($commits, @signers) = vcs_find_signers($cmd);
+
+    foreach my $signer (@signers) {
+	$signer = deduplicate_email($signer);
+    }
+
+    vcs_assign("commit_signer", $commits, @signers);
+}
+
+sub vcs_file_blame {
+    my ($file) = @_;
+
+    my @signers = ();
+    my @all_commits = ();
+    my @commits = ();
+    my $total_commits;
+    my $total_lines;
+
+    $vcs_used = vcs_exists();
+    return if (!$vcs_used);
+
+    @all_commits = vcs_blame($file);
+    @commits = uniq(@all_commits);
+    $total_commits = @commits;
+    $total_lines = @all_commits;
+
+    if ($email_git_blame_signatures) {
+	if (vcs_is_hg()) {
+	    my $commit_count;
+	    my @commit_signers = ();
+	    my $commit = join(" -r ", @commits);
+	    my $cmd;
+
+	    $cmd = $VCS_cmds{"find_commit_signers_cmd"};
+	    $cmd =~ s/(\$\w+)/$1/eeg;	#substitute variables in $cmd
+
+	    ($commit_count, @commit_signers) = vcs_find_signers($cmd);
+
+	    push(@signers, @commit_signers);
+	} else {
+	    foreach my $commit (@commits) {
+		my $commit_count;
+		my @commit_signers = ();
+		my $cmd;
+
+		$cmd = $VCS_cmds{"find_commit_signers_cmd"};
+		$cmd =~ s/(\$\w+)/$1/eeg;	#substitute variables in $cmd
+
+		($commit_count, @commit_signers) = vcs_find_signers($cmd);
+
+		push(@signers, @commit_signers);
+	    }
+	}
+    }
+
+    if ($from_filename) {
+	if ($output_rolestats) {
+	    my @blame_signers;
+	    if (vcs_is_hg()) {{		# Double brace for last exit
+		my $commit_count;
+		my @commit_signers = ();
+		@commits = uniq(@commits);
+		@commits = sort(@commits);
+		my $commit = join(" -r ", @commits);
+		my $cmd;
+
+		$cmd = $VCS_cmds{"find_commit_author_cmd"};
+		$cmd =~ s/(\$\w+)/$1/eeg;	#substitute variables in $cmd
+
+		my @lines = ();
+
+		@lines = &{$VCS_cmds{"execute_cmd"}}($cmd);
+
+		if (!$email_git_penguin_chiefs) {
+		    @lines = grep(!/${penguin_chiefs}/i, @lines);
+		}
+
+		last if !@lines;
+
+		my @authors = ();
+		foreach my $line (@lines) {
+		    if ($line =~ m/$VCS_cmds{"author_pattern"}/) {
+			my $author = $1;
+			$author = deduplicate_email($author);
+			push(@authors, $author);
+		    }
+		}
+
+		save_commits_by_author(@lines) if ($interactive);
+		save_commits_by_signer(@lines) if ($interactive);
+
+		push(@signers, @authors);
+	    }}
+	    else {
+		foreach my $commit (@commits) {
+		    my $i;
+		    my $cmd = $VCS_cmds{"find_commit_author_cmd"};
+		    $cmd =~ s/(\$\w+)/$1/eeg;	#interpolate $cmd
+		    my @author = vcs_find_author($cmd);
+		    next if !@author;
+
+		    my $formatted_author = deduplicate_email($author[0]);
+
+		    my $count = grep(/$commit/, @all_commits);
+		    for ($i = 0; $i < $count ; $i++) {
+			push(@blame_signers, $formatted_author);
+		    }
+		}
+	    }
+	    if (@blame_signers) {
+		vcs_assign("authored lines", $total_lines, @blame_signers);
+	    }
+	}
+	foreach my $signer (@signers) {
+	    $signer = deduplicate_email($signer);
+	}
+	vcs_assign("commits", $total_commits, @signers);
+    } else {
+	foreach my $signer (@signers) {
+	    $signer = deduplicate_email($signer);
+	}
+	vcs_assign("modified commits", $total_commits, @signers);
+    }
+}
+
+sub uniq {
+    my (@parms) = @_;
+
+    my %saw;
+    @parms = grep(!$saw{$_}++, @parms);
+    return @parms;
+}
+
+sub sort_and_uniq {
+    my (@parms) = @_;
+
+    my %saw;
+    @parms = sort @parms;
+    @parms = grep(!$saw{$_}++, @parms);
+    return @parms;
+}
+
+sub clean_file_emails {
+    my (@file_emails) = @_;
+    my @fmt_emails = ();
+
+    foreach my $email (@file_emails) {
+	$email =~ s/[\(\<\{]{0,1}([A-Za-z0-9_\.\+-]+\@[A-Za-z0-9\.-]+)[\)\>\}]{0,1}/\<$1\>/g;
+	my ($name, $address) = parse_email($email);
+	if ($name eq '"[,\.]"') {
+	    $name = "";
+	}
+
+	my @nw = split(/[^A-Za-zÀ-ÿ\'\,\.\+-]/, $name);
+	if (@nw > 2) {
+	    my $first = $nw[@nw - 3];
+	    my $middle = $nw[@nw - 2];
+	    my $last = $nw[@nw - 1];
+
+	    if (((length($first) == 1 && $first =~ m/[A-Za-z]/) ||
+		 (length($first) == 2 && substr($first, -1) eq ".")) ||
+		(length($middle) == 1 ||
+		 (length($middle) == 2 && substr($middle, -1) eq "."))) {
+		$name = "$first $middle $last";
+	    } else {
+		$name = "$middle $last";
+	    }
+	}
+
+	if (substr($name, -1) =~ /[,\.]/) {
+	    $name = substr($name, 0, length($name) - 1);
+	} elsif (substr($name, -2) =~ /[,\.]"/) {
+	    $name = substr($name, 0, length($name) - 2) . '"';
+	}
+
+	if (substr($name, 0, 1) =~ /[,\.]/) {
+	    $name = substr($name, 1, length($name) - 1);
+	} elsif (substr($name, 0, 2) =~ /"[,\.]/) {
+	    $name = '"' . substr($name, 2, length($name) - 2);
+	}
+
+	my $fmt_email = format_email($name, $address, $email_usename);
+	push(@fmt_emails, $fmt_email);
+    }
+    return @fmt_emails;
+}
+
+sub merge_email {
+    my @lines;
+    my %saw;
+
+    for (@_) {
+	my ($address, $role) = @$_;
+	if (!$saw{$address}) {
+	    if ($output_roles) {
+		push(@lines, "$address ($role)");
+	    } else {
+		push(@lines, $address);
+	    }
+	    $saw{$address} = 1;
+	}
+    }
+
+    return @lines;
+}
+
+sub output {
+    my (@parms) = @_;
+
+    if ($output_multiline) {
+	foreach my $line (@parms) {
+	    print("${line}\n");
+	}
+    } else {
+	print(join($output_separator, @parms));
+	print("\n");
+    }
+}
+
+my $rfc822re;
+
+sub make_rfc822re {
+#   Basic lexical tokens are specials, domain_literal, quoted_string, atom, and
+#   comment.  We must allow for rfc822_lwsp (or comments) after each of these.
+#   This regexp will only work on addresses which have had comments stripped
+#   and replaced with rfc822_lwsp.
+
+    my $specials = '()<>@,;:\\\\".\\[\\]';
+    my $controls = '\\000-\\037\\177';
+
+    my $dtext = "[^\\[\\]\\r\\\\]";
+    my $domain_literal = "\\[(?:$dtext|\\\\.)*\\]$rfc822_lwsp*";
+
+    my $quoted_string = "\"(?:[^\\\"\\r\\\\]|\\\\.|$rfc822_lwsp)*\"$rfc822_lwsp*";
+
+#   Use zero-width assertion to spot the limit of an atom.  A simple
+#   $rfc822_lwsp* causes the regexp engine to hang occasionally.
+    my $atom = "[^$specials $controls]+(?:$rfc822_lwsp+|\\Z|(?=[\\[\"$specials]))";
+    my $word = "(?:$atom|$quoted_string)";
+    my $localpart = "$word(?:\\.$rfc822_lwsp*$word)*";
+
+    my $sub_domain = "(?:$atom|$domain_literal)";
+    my $domain = "$sub_domain(?:\\.$rfc822_lwsp*$sub_domain)*";
+
+    my $addr_spec = "$localpart\@$rfc822_lwsp*$domain";
+
+    my $phrase = "$word*";
+    my $route = "(?:\@$domain(?:,\@$rfc822_lwsp*$domain)*:$rfc822_lwsp*)";
+    my $route_addr = "\\<$rfc822_lwsp*$route?$addr_spec\\>$rfc822_lwsp*";
+    my $mailbox = "(?:$addr_spec|$phrase$route_addr)";
+
+    my $group = "$phrase:$rfc822_lwsp*(?:$mailbox(?:,\\s*$mailbox)*)?;\\s*";
+    my $address = "(?:$mailbox|$group)";
+
+    return "$rfc822_lwsp*$address";
+}
+
+sub rfc822_strip_comments {
+    my $s = shift;
+#   Recursively remove comments, and replace with a single space.  The simpler
+#   regexps in the Email Addressing FAQ are imperfect - they will miss escaped
+#   chars in atoms, for example.
+
+    while ($s =~ s/^((?:[^"\\]|\\.)*
+                    (?:"(?:[^"\\]|\\.)*"(?:[^"\\]|\\.)*)*)
+                    \((?:[^()\\]|\\.)*\)/$1 /osx) {}
+    return $s;
+}
+
+#   valid: returns true if the parameter is an RFC822 valid address
+#
+sub rfc822_valid {
+    my $s = rfc822_strip_comments(shift);
+
+    if (!$rfc822re) {
+        $rfc822re = make_rfc822re();
+    }
+
+    return $s =~ m/^$rfc822re$/so && $s =~ m/^$rfc822_char*$/;
+}
+
+#   validlist: In scalar context, returns true if the parameter is an RFC822
+#              valid list of addresses.
+#
+#              In list context, returns an empty list on failure (an invalid
+#              address was found); otherwise a list whose first element is the
+#              number of addresses found and whose remaining elements are the
+#              addresses.  This is needed to disambiguate failure (invalid)
+#              from success with no addresses found, because an empty string is
+#              a valid list.
+
+sub rfc822_validlist {
+    my $s = rfc822_strip_comments(shift);
+
+    if (!$rfc822re) {
+        $rfc822re = make_rfc822re();
+    }
+    # * null list items are valid according to the RFC
+    # * the '1' business is to aid in distinguishing failure from no results
+
+    my @r;
+    if ($s =~ m/^(?:$rfc822re)?(?:,(?:$rfc822re)?)*$/so &&
+	$s =~ m/^$rfc822_char*$/) {
+        while ($s =~ m/(?:^|,$rfc822_lwsp*)($rfc822re)/gos) {
+            push(@r, $1);
+        }
+        return wantarray ? (scalar(@r), @r) : 1;
+    }
+    return wantarray ? () : 0;
+}
commit 9047c0b40654ce3578c148f6754f878218569252
Author: Michael S. Tsirkin <mst at redhat.com>
Date:   Tue Jun 14 17:15:34 2011 +0300

    usb-ehci: move device/vendor/class id to qdev
    
    Signed-off-by: Michael S. Tsirkin <mst at redhat.com>

diff --git a/hw/usb-ehci.c b/hw/usb-ehci.c
index f63519e..4d6989a 100644
--- a/hw/usb-ehci.c
+++ b/hw/usb-ehci.c
@@ -1945,6 +1945,10 @@ static PCIDeviceInfo ehci_info = {
     .qdev.name    = "usb-ehci",
     .qdev.size    = sizeof(EHCIState),
     .init         = usb_ehci_initfn,
+    .vendor_id    = PCI_VENDOR_ID_INTEL,
+    .device_id    = PCI_DEVICE_ID_INTEL_82801D,
+    .revision     = 0x10,
+    .class_id     = PCI_CLASS_SERIAL_USB,
 };
 
 static int usb_ehci_initfn(PCIDevice *dev)
@@ -1953,12 +1957,7 @@ static int usb_ehci_initfn(PCIDevice *dev)
     uint8_t *pci_conf = s->dev.config;
     int i;
 
-    pci_config_set_vendor_id(pci_conf, PCI_VENDOR_ID_INTEL);
-    pci_config_set_device_id(pci_conf, PCI_DEVICE_ID_INTEL_82801D);
-    pci_set_byte(&pci_conf[PCI_REVISION_ID], 0x10);
     pci_set_byte(&pci_conf[PCI_CLASS_PROG], 0x20);
-    pci_config_set_class(pci_conf, PCI_CLASS_SERIAL_USB);
-    pci_set_byte(&pci_conf[PCI_HEADER_TYPE], PCI_HEADER_TYPE_NORMAL);
 
     /* capabilities pointer */
     pci_set_byte(&pci_conf[PCI_CAPABILITY_LIST], 0x00);
commit cdfdec7f10fc1576c1b59db0584c2ae4ec6ec06f
Author: Michael S. Tsirkin <mst at redhat.com>
Date:   Tue Jun 14 17:14:52 2011 +0300

    ppce500: move device/vendor/class id to qdev
    
    Signed-off-by: Michael S. Tsirkin <mst at redhat.com>

diff --git a/hw/ppce500_pci.c b/hw/ppce500_pci.c
index 069af96..fc11af4 100644
--- a/hw/ppce500_pci.c
+++ b/hw/ppce500_pci.c
@@ -304,20 +304,13 @@ static int e500_pcihost_initfn(SysBusDevice *dev)
     return 0;
 }
 
-static int e500_host_bridge_initfn(PCIDevice *dev)
-{
-    pci_config_set_vendor_id(dev->config, PCI_VENDOR_ID_FREESCALE);
-    pci_config_set_device_id(dev->config, PCI_DEVICE_ID_MPC8533E);
-    pci_config_set_class(dev->config, PCI_CLASS_PROCESSOR_POWERPC);
-
-    return 0;
-}
-
 static PCIDeviceInfo e500_host_bridge_info = {
     .qdev.name    = "e500-host-bridge",
     .qdev.desc    = "Host bridge",
     .qdev.size    = sizeof(PCIDevice),
-    .init         = e500_host_bridge_initfn,
+    .vendor_id    = PCI_VENDOR_ID_FREESCALE,
+    .device_id    = PCI_DEVICE_ID_MPC8533E,
+    .class_id     = PCI_CLASS_PROCESSOR_POWERPC,
 };
 
 static SysBusDeviceInfo e500_pcihost_info = {
commit c2afc92290f2b5a8eb6f7b75338815012f90a5c7
Author: Isaku Yamahata <yamahata at valinux.co.jp>
Date:   Wed Jun 15 07:37:47 2011 +0900

    pci: don't call qdev pci init method
    
    As pci id initialization is moved to common layer,
    some initialization function can be empty.
    So don't call init method if NULL.
    
    Signed-off-by: Isaku Yamahata <yamahata at valinux.co.jp>
    Signed-off-by: Michael S. Tsirkin <mst at redhat.com>

diff --git a/hw/pci.c b/hw/pci.c
index ba0598b..b904a4e 100644
--- a/hw/pci.c
+++ b/hw/pci.c
@@ -1681,10 +1681,12 @@ static int pci_qdev_init(DeviceState *qdev, DeviceInfo *base)
         do_pci_unregister_device(pci_dev);
         return -1;
     }
-    rc = info->init(pci_dev);
-    if (rc != 0) {
-        do_pci_unregister_device(pci_dev);
-        return rc;
+    if (info->init) {
+        rc = info->init(pci_dev);
+        if (rc != 0) {
+            do_pci_unregister_device(pci_dev);
+            return rc;
+        }
     }
 
     /* rom loading */
commit befeac45d4d9afb587eca9a27d975db4a7950960
Merge: 35f7546... 0b862ce...
Author: Michael S. Tsirkin <mst at redhat.com>
Date:   Tue Jun 14 17:51:11 2011 +0300

    Merge remote-tracking branch 'origin/master' into pci
    
    Conflicts:
    	hw/virtio-pci.c

diff --cc hw/9pfs/virtio-9p-device.c
index 0000000,a2b6acc..f235236
mode 000000,100644..100644
--- a/hw/9pfs/virtio-9p-device.c
+++ b/hw/9pfs/virtio-9p-device.c
@@@ -1,0 -1,173 +1,173 @@@
+ /*
+  * Virtio 9p backend
+  *
+  * Copyright IBM, Corp. 2010
+  *
+  * Authors:
+  *  Anthony Liguori   <aliguori at us.ibm.com>
+  *
+  * This work is licensed under the terms of the GNU GPL, version 2.  See
+  * the COPYING file in the top-level directory.
+  *
+  */
+ 
+ #include "hw/virtio.h"
+ #include "hw/pc.h"
+ #include "qemu_socket.h"
+ #include "hw/virtio-pci.h"
+ #include "virtio-9p.h"
+ #include "fsdev/qemu-fsdev.h"
+ #include "virtio-9p-xattr.h"
+ 
+ static uint32_t virtio_9p_get_features(VirtIODevice *vdev, uint32_t features)
+ {
+     features |= 1 << VIRTIO_9P_MOUNT_TAG;
+     return features;
+ }
+ 
+ static V9fsState *to_virtio_9p(VirtIODevice *vdev)
+ {
+     return (V9fsState *)vdev;
+ }
+ 
+ static void virtio_9p_get_config(VirtIODevice *vdev, uint8_t *config)
+ {
+     struct virtio_9p_config *cfg;
+     V9fsState *s = to_virtio_9p(vdev);
+ 
+     cfg = qemu_mallocz(sizeof(struct virtio_9p_config) +
+                         s->tag_len);
+     stw_raw(&cfg->tag_len, s->tag_len);
+     memcpy(cfg->tag, s->tag, s->tag_len);
+     memcpy(config, cfg, s->config_size);
+     qemu_free(cfg);
+ }
+ 
+ VirtIODevice *virtio_9p_init(DeviceState *dev, V9fsConf *conf)
+  {
+     V9fsState *s;
+     int i, len;
+     struct stat stat;
+     FsTypeEntry *fse;
+ 
+ 
+     s = (V9fsState *)virtio_common_init("virtio-9p",
+                                     VIRTIO_ID_9P,
+                                     sizeof(struct virtio_9p_config)+
+                                     MAX_TAG_LEN,
+                                     sizeof(V9fsState));
+ 
+     /* initialize pdu allocator */
+     QLIST_INIT(&s->free_list);
+     for (i = 0; i < (MAX_REQ - 1); i++) {
+         QLIST_INSERT_HEAD(&s->free_list, &s->pdus[i], next);
+     }
+ 
+     s->vq = virtio_add_queue(&s->vdev, MAX_REQ, handle_9p_output);
+ 
+     fse = get_fsdev_fsentry(conf->fsdev_id);
+ 
+     if (!fse) {
+         /* We don't have a fsdev identified by fsdev_id */
+         fprintf(stderr, "Virtio-9p device couldn't find fsdev with the "
+                 "id = %s\n", conf->fsdev_id ? conf->fsdev_id : "NULL");
+         exit(1);
+     }
+ 
+     if (!fse->path || !conf->tag) {
+         /* we haven't specified a mount_tag or the path */
+         fprintf(stderr, "fsdev with id %s needs path "
+                 "and Virtio-9p device needs mount_tag arguments\n",
+                 conf->fsdev_id);
+         exit(1);
+     }
+ 
+     if (!strcmp(fse->security_model, "passthrough")) {
+         /* Files on the Fileserver set to client user credentials */
+         s->ctx.fs_sm = SM_PASSTHROUGH;
+         s->ctx.xops = passthrough_xattr_ops;
+     } else if (!strcmp(fse->security_model, "mapped")) {
+         /* Files on the fileserver are set to QEMU credentials.
+          * Client user credentials are saved in extended attributes.
+          */
+         s->ctx.fs_sm = SM_MAPPED;
+         s->ctx.xops = mapped_xattr_ops;
+     } else if (!strcmp(fse->security_model, "none")) {
+         /*
+          * Files on the fileserver are set to QEMU credentials.
+          */
+         s->ctx.fs_sm = SM_NONE;
+         s->ctx.xops = none_xattr_ops;
+     } else {
+         fprintf(stderr, "Default to security_model=none. You may want"
+                 " enable advanced security model using "
+                 "security option:\n\t security_model=passthrough\n\t "
+                 "security_model=mapped\n");
+         s->ctx.fs_sm = SM_NONE;
+         s->ctx.xops = none_xattr_ops;
+     }
+ 
+     if (lstat(fse->path, &stat)) {
+         fprintf(stderr, "share path %s does not exist\n", fse->path);
+         exit(1);
+     } else if (!S_ISDIR(stat.st_mode)) {
+         fprintf(stderr, "share path %s is not a directory\n", fse->path);
+         exit(1);
+     }
+ 
+     s->ctx.fs_root = qemu_strdup(fse->path);
+     len = strlen(conf->tag);
+     if (len > MAX_TAG_LEN) {
+         len = MAX_TAG_LEN;
+     }
+     /* s->tag is non-NULL terminated string */
+     s->tag = qemu_malloc(len);
+     memcpy(s->tag, conf->tag, len);
+     s->tag_len = len;
+     s->ctx.uid = -1;
+ 
+     s->ops = fse->ops;
+     s->vdev.get_features = virtio_9p_get_features;
+     s->config_size = sizeof(struct virtio_9p_config) +
+                         s->tag_len;
+     s->vdev.get_config = virtio_9p_get_config;
+ 
+     return &s->vdev;
+ }
+ 
+ static int virtio_9p_init_pci(PCIDevice *pci_dev)
+ {
+     VirtIOPCIProxy *proxy = DO_UPCAST(VirtIOPCIProxy, pci_dev, pci_dev);
+     VirtIODevice *vdev;
+ 
+     vdev = virtio_9p_init(&pci_dev->qdev, &proxy->fsconf);
+     vdev->nvectors = proxy->nvectors;
 -    virtio_init_pci(proxy, vdev,
 -                    PCI_VENDOR_ID_REDHAT_QUMRANET,
 -                    0x1009,
 -                    0x2,
 -                    0x00);
++    virtio_init_pci(proxy, vdev);
+     /* make the actual value visible */
+     proxy->nvectors = vdev->nvectors;
+     return 0;
+ }
+ 
+ static PCIDeviceInfo virtio_9p_info = {
+     .qdev.name = "virtio-9p-pci",
+     .qdev.size = sizeof(VirtIOPCIProxy),
+     .init      = virtio_9p_init_pci,
++    .vendor_id = PCI_VENDOR_ID_REDHAT_QUMRANET,
++    .device_id = 0x1009,
++    .revision  = VIRTIO_PCI_ABI_VERSION,
++    .class_id  = 0x2,
+     .qdev.props = (Property[]) {
+         DEFINE_PROP_UINT32("vectors", VirtIOPCIProxy, nvectors, 2),
+         DEFINE_VIRTIO_COMMON_FEATURES(VirtIOPCIProxy, host_features),
+         DEFINE_PROP_STRING("mount_tag", VirtIOPCIProxy, fsconf.tag),
+         DEFINE_PROP_STRING("fsdev", VirtIOPCIProxy, fsconf.fsdev_id),
+         DEFINE_PROP_END_OF_LIST(),
+     }
+ };
+ 
+ static void virtio_9p_register_devices(void)
+ {
+     pci_qdev_register(&virtio_9p_info);
+ }
+ 
+ device_init(virtio_9p_register_devices)
diff --cc hw/ide/ich.c
index 976cc92,6150ce3..054e073
--- a/hw/ide/ich.c
+++ b/hw/ide/ich.c
@@@ -90,12 -93,14 +90,12 @@@ static int pci_ich9_ahci_init(PCIDevic
  
      qemu_register_reset(ahci_reset, d);
  
-     /* XXX BAR size should be 1k, but that breaks, so bump it to 4k for now */
-     pci_register_bar_simple(&d->card, 5, 0x1000, 0, d->ahci.mem);
- 
      msi_init(dev, 0x50, 1, true, false);
 -
 -    ahci_init(&d->ahci, &dev->qdev, 6);
      d->ahci.irq = d->card.irq[0];
  
+     /* XXX BAR size should be 1k, but that breaks, so bump it to 4k for now */
+     pci_register_bar_simple(&d->card, 5, 0x1000, 0, d->ahci.mem);
+ 
      return 0;
  }
  
diff --cc hw/msix.c
index 28559b6,af40e26..03d7bec
--- a/hw/msix.c
+++ b/hw/msix.c
@@@ -71,12 -82,12 +71,12 @@@ static int msix_add_config(struct PCIDe
  
      pci_set_word(config + PCI_MSIX_FLAGS, nentries - 1);
      /* Table on top of BAR */
 -    pci_set_long(config + MSIX_TABLE_OFFSET, bar_size | bar_nr);
 +    pci_set_long(config + PCI_MSIX_TABLE, bar_size | bar_nr);
      /* Pending bits on top of that */
 -    pci_set_long(config + MSIX_PBA_OFFSET, (bar_size + MSIX_PAGE_PENDING) |
 +    pci_set_long(config + PCI_MSIX_PBA, (bar_size + MSIX_PAGE_PENDING) |
                   bar_nr);
      pdev->msix_cap = config_offset;
-     /* Make flags bit writeable. */
+     /* Make flags bit writable. */
      pdev->wmask[config_offset + MSIX_CONTROL_OFFSET] |= MSIX_ENABLE_MASK |
  	    MSIX_MASKALL_MASK;
      return 0;
diff --cc hw/piix_pci.c
index b927f01,85a320e..e0da0bd
--- a/hw/piix_pci.c
+++ b/hw/piix_pci.c
@@@ -417,11 -464,15 +452,19 @@@ static PCIDeviceInfo i440fx_info[] = 
          .no_hotplug   = 1,
          .init         = i440fx_initfn,
          .config_write = i440fx_write_config,
 +        .vendor_id    = PCI_VENDOR_ID_INTEL,
 +        .device_id    = PCI_DEVICE_ID_INTEL_82441,
 +        .revision     = 0x02,
 +        .class_id     = PCI_CLASS_BRIDGE_HOST,
      },{
+         .qdev.name    = "i440FX-xen",
+         .qdev.desc    = "Host bridge",
+         .qdev.size    = sizeof(PCII440FXState),
+         .qdev.vmsd    = &vmstate_i440fx,
+         .qdev.no_user = 1,
+         .init         = i440fx_initfn,
+         .config_write = i440fx_write_config_xen,
+     },{
          .qdev.name    = "PIIX3",
          .qdev.desc    = "ISA bridge",
          .qdev.size    = sizeof(PIIX3State),
diff --cc hw/usb-uhci.c
index 536c24c,c0de05b..872a995
--- a/hw/usb-uhci.c
+++ b/hw/usb-uhci.c
@@@ -1113,11 -1085,11 +1085,12 @@@ static USBPortOps uhci_port_ops = 
      .attach = uhci_attach,
      .detach = uhci_detach,
      .wakeup = uhci_wakeup,
+     .complete = uhci_async_complete,
  };
  
 -static int usb_uhci_common_initfn(UHCIState *s)
 +static int usb_uhci_common_initfn(PCIDevice *dev)
  {
 +    UHCIState *s = DO_UPCAST(UHCIState, dev, dev);
      uint8_t *pci_conf = s->dev.config;
      int i;
  
diff --cc hw/virtio-pci.c
index b86c441,c018351..b3e7ba5
--- a/hw/virtio-pci.c
+++ b/hw/virtio-pci.c
@@@ -74,9 -75,9 +75,6 @@@
                                           VIRTIO_PCI_CONFIG_MSI : \
                                           VIRTIO_PCI_CONFIG_NOMSI)
  
--/* Virtio ABI version, if we increment this, we break the guest driver. */
--#define VIRTIO_PCI_ABI_VERSION          0
--
  /* How many bits to shift physical queue address written to QUEUE_PFN.
   * 12 is historical, and due to x86 page size. */
  #define VIRTIO_PCI_QUEUE_ADDR_SHIFT    12
@@@ -671,7 -649,9 +648,7 @@@ static const VirtIOBindings virtio_pci_
      .vmstate_change = virtio_pci_vmstate_change,
  };
  
- static void virtio_init_pci(VirtIOPCIProxy *proxy, VirtIODevice *vdev)
 -void virtio_init_pci(VirtIOPCIProxy *proxy, VirtIODevice *vdev,
 -                            uint16_t vendor, uint16_t device,
 -                            uint16_t class_code, uint8_t pif)
++void virtio_init_pci(VirtIOPCIProxy *proxy, VirtIODevice *vdev)
  {
      uint8_t *config;
      uint32_t size;
diff --cc hw/virtio-pci.h
index 0000000,a4b5fd3..b518917
mode 000000,100644..100644
--- a/hw/virtio-pci.h
+++ b/hw/virtio-pci.h
@@@ -1,0 -1,43 +1,45 @@@
+ /*
+  * Virtio PCI Bindings
+  *
+  * Copyright IBM, Corp. 2007
+  * Copyright (c) 2009 CodeSourcery
+  *
+  * Authors:
+  *  Anthony Liguori   <aliguori at us.ibm.com>
+  *  Paul Brook        <paul at codesourcery.com>
+  *
+  * This work is licensed under the terms of the GNU GPL, version 2.  See
+  * the COPYING file in the top-level directory.
+  */
+ 
+ #ifndef QEMU_VIRTIO_PCI_H
+ #define QEMU_VIRTIO_PCI_H
+ 
+ #include "virtio-net.h"
+ #include "virtio-serial.h"
+ 
+ typedef struct {
+     PCIDevice pci_dev;
+     VirtIODevice *vdev;
+     uint32_t flags;
+     uint32_t addr;
+     uint32_t class_code;
+     uint32_t nvectors;
+     BlockConf block;
+     NICConf nic;
+     uint32_t host_features;
+ #ifdef CONFIG_LINUX
+     V9fsConf fsconf;
+ #endif
+     virtio_serial_conf serial;
+     virtio_net_conf net;
+     bool ioeventfd_disabled;
+     bool ioeventfd_started;
+ } VirtIOPCIProxy;
+ 
 -extern void virtio_init_pci(VirtIOPCIProxy *proxy, VirtIODevice *vdev,
 -                            uint16_t vendor, uint16_t device,
 -                            uint16_t class_code, uint8_t pif);
++void virtio_init_pci(VirtIOPCIProxy *proxy, VirtIODevice *vdev);
++
++/* Virtio ABI version, if we increment this, we break the guest driver. */
++#define VIRTIO_PCI_ABI_VERSION          0
++
+ #endif
commit 35f754620615138aaae0ef72602f84c88fd8de0f
Author: Michael Tokarev <mjt at tls.msk.ru>
Date:   Fri Jun 10 00:55:57 2011 +0400

    print meaningful error message in case of --disable-vhost-net
    
    When qemu gets compiled without support of vhost-net, any attempt
    to use it fails with a very clear error message:
    
     qemu-system-x86_64: -netdev ...,vhost=on: vhost-net requested but could not be initialized
    
    there's absolutely no reason given _why_ it coult not be
    initialized, and even strace'ing the process in question
    does not reveal any errors.  So print a message telling
    what's going on.
    
    Signed-off-by: Michael Tokarev <mjt at tls.msk.ru>
    Signed-off-by: Michael S. Tsirkin <mst at redhat.com>

diff --git a/hw/vhost_net.c b/hw/vhost_net.c
index e8c9e94..b6dc592 100644
--- a/hw/vhost_net.c
+++ b/hw/vhost_net.c
@@ -15,6 +15,7 @@
 
 #include "virtio-net.h"
 #include "vhost_net.h"
+#include "qemu-error.h"
 
 #include "config.h"
 
@@ -203,6 +204,7 @@ void vhost_net_cleanup(struct vhost_net *net)
 struct vhost_net *vhost_net_init(VLANClientState *backend, int devfd,
                                  bool force)
 {
+    error_report("vhost-net support is not compiled in");
     return NULL;
 }
 
commit b91cb44215101da1d005804392807d5785b9ebfb
Author: Michael S. Tsirkin <mst at redhat.com>
Date:   Sun Jun 12 16:31:38 2011 +0300

    virtio: compat event idx support
    
    Disable event index for compat machine types.
    
    Signed-off-by: Michael S. Tsirkin <mst at redhat.com>

diff --git a/hw/pc_piix.c b/hw/pc_piix.c
index a85214b..1aba09f 100644
--- a/hw/pc_piix.c
+++ b/hw/pc_piix.c
@@ -244,6 +244,18 @@ static QEMUMachine pc_machine_v0_13 = {
             .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",
         },
         { /* end of list */ }
     },
@@ -275,6 +287,18 @@ static QEMUMachine pc_machine_v0_12 = {
             .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",
         },
         { /* end of list */ }
     }
@@ -314,6 +338,18 @@ static QEMUMachine pc_machine_v0_11 = {
             .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",
         },
         { /* end of list */ }
     }
@@ -365,6 +401,18 @@ static QEMUMachine pc_machine_v0_10 = {
             .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",
         },
         { /* end of list */ }
     },
commit bcbabae8ff7f7ec114da9fe2aa7f25f420f35306
Author: Michael S. Tsirkin <mst at redhat.com>
Date:   Sun Jun 12 16:21:57 2011 +0300

    virtio: event index support
    
    Add support for event_idx feature, and utilize it to
    reduce the number of interrupts and exits for the guest.
    
    Signed-off-by: Michael S. Tsirkin <mst at redhat.com>

diff --git a/hw/vhost_net.c b/hw/vhost_net.c
index 420e05f..e8c9e94 100644
--- a/hw/vhost_net.c
+++ b/hw/vhost_net.c
@@ -50,6 +50,9 @@ unsigned vhost_net_get_features(struct vhost_net *net, unsigned features)
     if (!(net->dev.features & (1 << VIRTIO_RING_F_INDIRECT_DESC))) {
         features &= ~(1 << VIRTIO_RING_F_INDIRECT_DESC);
     }
+    if (!(net->dev.features & (1 << VIRTIO_RING_F_EVENT_IDX))) {
+        features &= ~(1 << VIRTIO_RING_F_EVENT_IDX);
+    }
     if (!(net->dev.features & (1 << VIRTIO_NET_F_MRG_RXBUF))) {
         features &= ~(1 << VIRTIO_NET_F_MRG_RXBUF);
     }
@@ -65,6 +68,9 @@ void vhost_net_ack_features(struct vhost_net *net, unsigned features)
     if (features & (1 << VIRTIO_RING_F_INDIRECT_DESC)) {
         net->dev.acked_features |= (1 << VIRTIO_RING_F_INDIRECT_DESC);
     }
+    if (features & (1 << VIRTIO_RING_F_EVENT_IDX)) {
+        net->dev.acked_features |= (1 << VIRTIO_RING_F_EVENT_IDX);
+    }
     if (features & (1 << VIRTIO_NET_F_MRG_RXBUF)) {
         net->dev.acked_features |= (1 << VIRTIO_NET_F_MRG_RXBUF);
     }
diff --git a/hw/virtio.c b/hw/virtio.c
index 36b8f35..e6043de 100644
--- a/hw/virtio.c
+++ b/hw/virtio.c
@@ -71,7 +71,17 @@ struct VirtQueue
     VRing vring;
     target_phys_addr_t pa;
     uint16_t last_avail_idx;
+    /* Last used index value we have signalled on */
+    uint16_t signalled_used;
+
+    /* Last used index value we have signalled on */
+    bool signalled_used_valid;
+
+    /* Notification enabled? */
+    bool notification;
+
     int inuse;
+
     uint16_t vector;
     void (*handle_output)(VirtIODevice *vdev, VirtQueue *vq);
     VirtIODevice *vdev;
@@ -140,6 +150,11 @@ static inline uint16_t vring_avail_ring(VirtQueue *vq, int i)
     return lduw_phys(pa);
 }
 
+static inline uint16_t vring_used_event(VirtQueue *vq)
+{
+    return vring_avail_ring(vq, vq->vring.num);
+}
+
 static inline void vring_used_ring_id(VirtQueue *vq, int i, uint32_t val)
 {
     target_phys_addr_t pa;
@@ -161,11 +176,11 @@ static uint16_t vring_used_idx(VirtQueue *vq)
     return lduw_phys(pa);
 }
 
-static inline void vring_used_idx_increment(VirtQueue *vq, uint16_t val)
+static inline void vring_used_idx_set(VirtQueue *vq, uint16_t val)
 {
     target_phys_addr_t pa;
     pa = vq->vring.used + offsetof(VRingUsed, idx);
-    stw_phys(pa, vring_used_idx(vq) + val);
+    stw_phys(pa, val);
 }
 
 static inline void vring_used_flags_set_bit(VirtQueue *vq, int mask)
@@ -182,12 +197,26 @@ static inline void vring_used_flags_unset_bit(VirtQueue *vq, int mask)
     stw_phys(pa, lduw_phys(pa) & ~mask);
 }
 
+static inline void vring_avail_event(VirtQueue *vq, uint16_t val)
+{
+    target_phys_addr_t pa;
+    if (!vq->notification) {
+        return;
+    }
+    pa = vq->vring.used + offsetof(VRingUsed, ring[vq->vring.num]);
+    stw_phys(pa, val);
+}
+
 void virtio_queue_set_notification(VirtQueue *vq, int enable)
 {
-    if (enable)
+    vq->notification = enable;
+    if (vq->vdev->guest_features & (1 << VIRTIO_RING_F_EVENT_IDX)) {
+        vring_avail_event(vq, vring_avail_idx(vq));
+    } else if (enable) {
         vring_used_flags_unset_bit(vq, VRING_USED_F_NO_NOTIFY);
-    else
+    } else {
         vring_used_flags_set_bit(vq, VRING_USED_F_NO_NOTIFY);
+    }
 }
 
 int virtio_queue_ready(VirtQueue *vq)
@@ -233,11 +262,16 @@ void virtqueue_fill(VirtQueue *vq, const VirtQueueElement *elem,
 
 void virtqueue_flush(VirtQueue *vq, unsigned int count)
 {
+    uint16_t old, new;
     /* Make sure buffer is written before we update index. */
     wmb();
     trace_virtqueue_flush(vq, count);
-    vring_used_idx_increment(vq, count);
+    old = vring_used_idx(vq);
+    new = old + count;
+    vring_used_idx_set(vq, new);
     vq->inuse -= count;
+    if (unlikely((int16_t)(new - vq->signalled_used) < (uint16_t)(new - old)))
+        vq->signalled_used_valid = false;
 }
 
 void virtqueue_push(VirtQueue *vq, const VirtQueueElement *elem,
@@ -394,6 +428,9 @@ int virtqueue_pop(VirtQueue *vq, VirtQueueElement *elem)
     max = vq->vring.num;
 
     i = head = virtqueue_get_head(vq, vq->last_avail_idx++);
+    if (vq->vdev->guest_features & (1 << VIRTIO_RING_F_EVENT_IDX)) {
+        vring_avail_event(vq, vring_avail_idx(vq));
+    }
 
     if (vring_desc_flags(desc_pa, i) & VRING_DESC_F_INDIRECT) {
         if (vring_desc_len(desc_pa, i) % sizeof(VRingDesc)) {
@@ -477,6 +514,9 @@ void virtio_reset(void *opaque)
         vdev->vq[i].last_avail_idx = 0;
         vdev->vq[i].pa = 0;
         vdev->vq[i].vector = VIRTIO_NO_VECTOR;
+        vdev->vq[i].signalled_used = 0;
+        vdev->vq[i].signalled_used_valid = false;
+        vdev->vq[i].notification = true;
     }
 }
 
@@ -626,13 +666,45 @@ void virtio_irq(VirtQueue *vq)
     virtio_notify_vector(vq->vdev, vq->vector);
 }
 
-void virtio_notify(VirtIODevice *vdev, VirtQueue *vq)
+/* Assuming a given event_idx value from the other size, if
+ * we have just incremented index from old to new_idx,
+ * should we trigger an event? */
+static inline int vring_need_event(uint16_t event, uint16_t new, uint16_t old)
 {
+	/* Note: Xen has similar logic for notification hold-off
+	 * in include/xen/interface/io/ring.h with req_event and req_prod
+	 * corresponding to event_idx + 1 and new respectively.
+	 * Note also that req_event and req_prod in Xen start at 1,
+	 * event indexes in virtio start at 0. */
+	return (uint16_t)(new - event - 1) < (uint16_t)(new - old);
+}
+
+static bool vring_notify(VirtIODevice *vdev, VirtQueue *vq)
+{
+    uint16_t old, new;
+    bool v;
     /* Always notify when queue is empty (when feature acknowledge) */
-    if ((vring_avail_flags(vq) & VRING_AVAIL_F_NO_INTERRUPT) &&
-        (!(vdev->guest_features & (1 << VIRTIO_F_NOTIFY_ON_EMPTY)) ||
-         (vq->inuse || vring_avail_idx(vq) != vq->last_avail_idx)))
+    if (((vdev->guest_features & (1 << VIRTIO_F_NOTIFY_ON_EMPTY)) &&
+         !vq->inuse && vring_avail_idx(vq) == vq->last_avail_idx)) {
+        return true;
+    }
+
+    if (!(vdev->guest_features & (1 << VIRTIO_RING_F_EVENT_IDX))) {
+        return !(vring_avail_flags(vq) & VRING_AVAIL_F_NO_INTERRUPT);
+    }
+
+    v = vq->signalled_used_valid;
+    vq->signalled_used_valid = true;
+    old = vq->signalled_used;
+    new = vq->signalled_used = vring_used_idx(vq);
+    return !v || vring_need_event(vring_used_event(vq), new, old);
+}
+
+void virtio_notify(VirtIODevice *vdev, VirtQueue *vq)
+{
+    if (!vring_notify(vdev, vq)) {
         return;
+    }
 
     trace_virtio_notify(vdev, vq);
     vdev->isr |= 0x01;
@@ -715,6 +787,8 @@ int virtio_load(VirtIODevice *vdev, QEMUFile *f)
         vdev->vq[i].vring.num = qemu_get_be32(f);
         vdev->vq[i].pa = qemu_get_be64(f);
         qemu_get_be16s(f, &vdev->vq[i].last_avail_idx);
+        vdev->vq[i].signalled_used_valid = false;
+        vdev->vq[i].notification = true;
 
         if (vdev->vq[i].pa) {
             uint16_t nheads;
diff --git a/hw/virtio.h b/hw/virtio.h
index bc72289..69e6bb1 100644
--- a/hw/virtio.h
+++ b/hw/virtio.h
@@ -46,6 +46,11 @@
 #define VIRTIO_F_NOTIFY_ON_EMPTY        24
 /* We support indirect buffer descriptors */
 #define VIRTIO_RING_F_INDIRECT_DESC     28
+/* The Guest publishes the used index for which it expects an interrupt
+ * at the end of the avail ring. Host should ignore the avail->flags field. */
+/* The Host publishes the avail index for which it expects a kick
+ * at the end of the used ring. Guest should ignore the used->flags field. */
+#define VIRTIO_RING_F_EVENT_IDX         29
 /* A guest should never accept this.  It implies negotiation is broken. */
 #define VIRTIO_F_BAD_FEATURE		30
 
@@ -210,7 +215,9 @@ void virtio_serial_exit(VirtIODevice *vdev);
 
 #define DEFINE_VIRTIO_COMMON_FEATURES(_state, _field) \
 	DEFINE_PROP_BIT("indirect_desc", _state, _field, \
-			VIRTIO_RING_F_INDIRECT_DESC, true)
+			VIRTIO_RING_F_INDIRECT_DESC, true), \
+	DEFINE_PROP_BIT("event_idx", _state, _field, \
+			VIRTIO_RING_F_EVENT_IDX, true)
 
 target_phys_addr_t virtio_queue_get_desc_addr(VirtIODevice *vdev, int n);
 target_phys_addr_t virtio_queue_get_avail_addr(VirtIODevice *vdev, int n);
commit 01731cfb39ae234a8df852f56fc21efd155dbc26
Author: Jan Kiszka <jan.kiszka at siemens.com>
Date:   Thu Jun 9 09:39:56 2011 +0200

    msix: Use replace local defines with pci_regs versions
    
    This also cleans up an open-coded 64-bit message address readout.
    
    Signed-off-by: Jan Kiszka <jan.kiszka at siemens.com>
    Signed-off-by: Michael S. Tsirkin <mst at redhat.com>

diff --git a/hw/msix.c b/hw/msix.c
index daaf9b7..28559b6 100644
--- a/hw/msix.c
+++ b/hw/msix.c
@@ -16,9 +16,6 @@
 #include "pci.h"
 #include "range.h"
 
-/* MSI-X capability structure */
-#define MSIX_TABLE_OFFSET 4
-#define MSIX_PBA_OFFSET 8
 #define MSIX_CAP_LENGTH 12
 
 /* MSI enable bit and maskall bit are in byte 1 in FLAGS register */
@@ -26,14 +23,6 @@
 #define MSIX_ENABLE_MASK (PCI_MSIX_FLAGS_ENABLE >> 8)
 #define MSIX_MASKALL_MASK (PCI_MSIX_FLAGS_MASKALL >> 8)
 
-/* MSI-X table format */
-#define MSIX_MSG_ADDR 0
-#define MSIX_MSG_UPPER_ADDR 4
-#define MSIX_MSG_DATA 8
-#define MSIX_VECTOR_CTRL 12
-#define MSIX_ENTRY_SIZE 16
-#define MSIX_VECTOR_MASK 0x1
-
 /* How much space does an MSIX table need. */
 /* The spec requires giving the table structure
  * a 4K aligned region all by itself. */
@@ -82,9 +71,9 @@ static int msix_add_config(struct PCIDevice *pdev, unsigned short nentries,
 
     pci_set_word(config + PCI_MSIX_FLAGS, nentries - 1);
     /* Table on top of BAR */
-    pci_set_long(config + MSIX_TABLE_OFFSET, bar_size | bar_nr);
+    pci_set_long(config + PCI_MSIX_TABLE, bar_size | bar_nr);
     /* Pending bits on top of that */
-    pci_set_long(config + MSIX_PBA_OFFSET, (bar_size + MSIX_PAGE_PENDING) |
+    pci_set_long(config + PCI_MSIX_PBA, (bar_size + MSIX_PAGE_PENDING) |
                  bar_nr);
     pdev->msix_cap = config_offset;
     /* Make flags bit writeable. */
@@ -140,9 +129,10 @@ static int msix_function_masked(PCIDevice *dev)
 
 static int msix_is_masked(PCIDevice *dev, int vector)
 {
-    unsigned offset = vector * MSIX_ENTRY_SIZE + MSIX_VECTOR_CTRL;
+    unsigned offset =
+        vector * PCI_MSIX_ENTRY_SIZE + PCI_MSIX_ENTRY_VECTOR_CTRL;
     return msix_function_masked(dev) ||
-	   dev->msix_table_page[offset] & MSIX_VECTOR_MASK;
+	   dev->msix_table_page[offset] & PCI_MSIX_ENTRY_CTRL_MASKBIT;
 }
 
 static void msix_handle_mask_update(PCIDevice *dev, int vector)
@@ -184,7 +174,7 @@ static void msix_mmio_writel(void *opaque, target_phys_addr_t addr,
 {
     PCIDevice *dev = opaque;
     unsigned int offset = addr & (MSIX_PAGE_SIZE - 1) & ~0x3;
-    int vector = offset / MSIX_ENTRY_SIZE;
+    int vector = offset / PCI_MSIX_ENTRY_SIZE;
     pci_set_long(dev->msix_table_page + offset, val);
     msix_handle_mask_update(dev, vector);
 }
@@ -208,7 +198,7 @@ void msix_mmio_map(PCIDevice *d, int region_num,
                    pcibus_t addr, pcibus_t size, int type)
 {
     uint8_t *config = d->config + d->msix_cap;
-    uint32_t table = pci_get_long(config + MSIX_TABLE_OFFSET);
+    uint32_t table = pci_get_long(config + PCI_MSIX_TABLE);
     uint32_t offset = table & ~(MSIX_PAGE_SIZE - 1);
     /* TODO: for assigned devices, we'll want to make it possible to map
      * pending bits separately in case they are in a separate bar. */
@@ -226,8 +216,9 @@ static void msix_mask_all(struct PCIDevice *dev, unsigned nentries)
 {
     int vector;
     for (vector = 0; vector < nentries; ++vector) {
-        unsigned offset = vector * MSIX_ENTRY_SIZE + MSIX_VECTOR_CTRL;
-        dev->msix_table_page[offset] |= MSIX_VECTOR_MASK;
+        unsigned offset =
+            vector * PCI_MSIX_ENTRY_SIZE + PCI_MSIX_ENTRY_VECTOR_CTRL;
+        dev->msix_table_page[offset] |= PCI_MSIX_ENTRY_CTRL_MASKBIT;
     }
 }
 
@@ -313,7 +304,7 @@ void msix_save(PCIDevice *dev, QEMUFile *f)
         return;
     }
 
-    qemu_put_buffer(f, dev->msix_table_page, n * MSIX_ENTRY_SIZE);
+    qemu_put_buffer(f, dev->msix_table_page, n * PCI_MSIX_ENTRY_SIZE);
     qemu_put_buffer(f, dev->msix_table_page + MSIX_PAGE_PENDING, (n + 7) / 8);
 }
 
@@ -327,7 +318,7 @@ void msix_load(PCIDevice *dev, QEMUFile *f)
     }
 
     msix_free_irq_entries(dev);
-    qemu_get_buffer(f, dev->msix_table_page, n * MSIX_ENTRY_SIZE);
+    qemu_get_buffer(f, dev->msix_table_page, n * PCI_MSIX_ENTRY_SIZE);
     qemu_get_buffer(f, dev->msix_table_page + MSIX_PAGE_PENDING, (n + 7) / 8);
 }
 
@@ -355,7 +346,7 @@ uint32_t msix_bar_size(PCIDevice *dev)
 /* Send an MSI-X message */
 void msix_notify(PCIDevice *dev, unsigned vector)
 {
-    uint8_t *table_entry = dev->msix_table_page + vector * MSIX_ENTRY_SIZE;
+    uint8_t *table_entry = dev->msix_table_page + vector * PCI_MSIX_ENTRY_SIZE;
     uint64_t address;
     uint32_t data;
 
@@ -366,9 +357,8 @@ void msix_notify(PCIDevice *dev, unsigned vector)
         return;
     }
 
-    address = pci_get_long(table_entry + MSIX_MSG_UPPER_ADDR);
-    address = (address << 32) | pci_get_long(table_entry + MSIX_MSG_ADDR);
-    data = pci_get_long(table_entry + MSIX_MSG_DATA);
+    address = pci_get_quad(table_entry + PCI_MSIX_ENTRY_LOWER_ADDR);
+    data = pci_get_long(table_entry + PCI_MSIX_ENTRY_DATA);
     stl_phys(address, data);
 }
 
commit 81486b55f4e08601fdbe71182aa9efaac11d806b
Author: Jan Kiszka <jan.kiszka at siemens.com>
Date:   Thu Jun 9 09:18:30 2011 +0200

    pci: Update pci_regs header
    
    Pulls in latest version from kernel 3.0-rc2.
    
    Some changes around AER now require local defines as QEMU accesses the
    error source identification register via sub-words.
    
    CC: Isaku Yamahata <yamahata at valinux.co.jp>
    Signed-off-by: Jan Kiszka <jan.kiszka at siemens.com>
    Signed-off-by: Michael S. Tsirkin <mst at redhat.com>

diff --git a/hw/pci_regs.h b/hw/pci_regs.h
index dd0bed4..63e8956 100644
--- a/hw/pci_regs.h
+++ b/hw/pci_regs.h
@@ -300,12 +300,22 @@
 #define PCI_MSI_DATA_64		12	/* 16 bits of data for 64-bit devices */
 #define PCI_MSI_MASK_64		16	/* Mask bits register for 64-bit devices */
 
-/* MSI-X registers (these are at offset PCI_MSIX_FLAGS) */
+/* MSI-X registers */
 #define PCI_MSIX_FLAGS		2
 #define  PCI_MSIX_FLAGS_QSIZE	0x7FF
 #define  PCI_MSIX_FLAGS_ENABLE	(1 << 15)
 #define  PCI_MSIX_FLAGS_MASKALL	(1 << 14)
-#define PCI_MSIX_FLAGS_BIRMASK	(7 << 0)
+#define PCI_MSIX_TABLE		4
+#define PCI_MSIX_PBA		8
+#define  PCI_MSIX_FLAGS_BIRMASK	(7 << 0)
+
+/* MSI-X entry's format */
+#define PCI_MSIX_ENTRY_SIZE		16
+#define  PCI_MSIX_ENTRY_LOWER_ADDR	0
+#define  PCI_MSIX_ENTRY_UPPER_ADDR	4
+#define  PCI_MSIX_ENTRY_DATA		8
+#define  PCI_MSIX_ENTRY_VECTOR_CTRL	12
+#define   PCI_MSIX_ENTRY_CTRL_MASKBIT	1
 
 /* CompactPCI Hotswap Register */
 
@@ -365,6 +375,11 @@
 #define  PCI_X_STATUS_266MHZ	0x40000000	/* 266 MHz capable */
 #define  PCI_X_STATUS_533MHZ	0x80000000	/* 533 MHz capable */
 
+/* PCI Bridge Subsystem ID registers */
+
+#define PCI_SSVID_VENDOR_ID     4	/* PCI-Bridge subsystem vendor id register */
+#define PCI_SSVID_DEVICE_ID     6	/* PCI-Bridge subsystem device id register */
+
 /* PCI Express capability registers */
 
 #define PCI_EXP_FLAGS		2	/* Capabilities register */
@@ -420,7 +435,7 @@
 #define  PCI_EXP_LNKCAP_L0SEL	0x00007000 /* L0s Exit Latency */
 #define  PCI_EXP_LNKCAP_L1EL	0x00038000 /* L1 Exit Latency */
 #define  PCI_EXP_LNKCAP_CLKPM	0x00040000 /* L1 Clock Power Management */
-#define  PCI_EXP_LNKCAP_SDERC	0x00080000 /* Suprise Down Error Reporting Capable */
+#define  PCI_EXP_LNKCAP_SDERC	0x00080000 /* Surprise Down Error Reporting Capable */
 #define  PCI_EXP_LNKCAP_DLLLARC	0x00100000 /* Data Link Layer Link Active Reporting Capable */
 #define  PCI_EXP_LNKCAP_LBNC	0x00200000 /* Link Bandwidth Notification Capability */
 #define  PCI_EXP_LNKCAP_PN	0xff000000 /* Port Number */
@@ -437,7 +452,10 @@
 #define  PCI_EXP_LNKCTL_LABIE	0x0800	/* Lnk Autonomous Bandwidth Interrupt Enable */
 #define PCI_EXP_LNKSTA		18	/* Link Status */
 #define  PCI_EXP_LNKSTA_CLS	0x000f	/* Current Link Speed */
+#define  PCI_EXP_LNKSTA_CLS_2_5GB 0x01	/* Current Link Speed 2.5GT/s */
+#define  PCI_EXP_LNKSTA_CLS_5_0GB 0x02	/* Current Link Speed 5.0GT/s */
 #define  PCI_EXP_LNKSTA_NLW	0x03f0	/* Nogotiated Link Width */
+#define  PCI_EXP_LNKSTA_NLW_SHIFT 4	/* start of NLW mask in link status */
 #define  PCI_EXP_LNKSTA_LT	0x0800	/* Link Training */
 #define  PCI_EXP_LNKSTA_SLC	0x1000	/* Slot Clock Configuration */
 #define  PCI_EXP_LNKSTA_DLLLA	0x2000	/* Data Link Layer Link Active */
@@ -486,10 +504,22 @@
 #define  PCI_EXP_RTCTL_CRSSVE	0x10	/* CRS Software Visibility Enable */
 #define PCI_EXP_RTCAP		30	/* Root Capabilities */
 #define PCI_EXP_RTSTA		32	/* Root Status */
+#define PCI_EXP_RTSTA_PME	0x10000 /* PME status */
+#define PCI_EXP_RTSTA_PENDING	0x20000 /* PME pending */
 #define PCI_EXP_DEVCAP2		36	/* Device Capabilities 2 */
 #define  PCI_EXP_DEVCAP2_ARI	0x20	/* Alternative Routing-ID */
+#define  PCI_EXP_DEVCAP2_LTR	0x800	/* Latency tolerance reporting */
+#define  PCI_EXP_OBFF_MASK	0xc0000 /* OBFF support mechanism */
+#define  PCI_EXP_OBFF_MSG	0x40000 /* New message signaling */
+#define  PCI_EXP_OBFF_WAKE	0x80000 /* Re-use WAKE# for OBFF */
 #define PCI_EXP_DEVCTL2		40	/* Device Control 2 */
 #define  PCI_EXP_DEVCTL2_ARI	0x20	/* Alternative Routing-ID */
+#define  PCI_EXP_IDO_REQ_EN	0x100	/* ID-based ordering request enable */
+#define  PCI_EXP_IDO_CMP_EN	0x200	/* ID-based ordering completion enable */
+#define  PCI_EXP_LTR_EN		0x400	/* Latency tolerance reporting */
+#define  PCI_EXP_OBFF_MSGA_EN	0x2000	/* OBFF enable with Message type A */
+#define  PCI_EXP_OBFF_MSGB_EN	0x4000	/* OBFF enable with Message type B */
+#define  PCI_EXP_OBFF_WAKE_EN	0x6000	/* OBFF using WAKE# signaling */
 #define PCI_EXP_LNKCTL2		48	/* Link Control 2 */
 #define PCI_EXP_SLTCTL2		56	/* Slot Control 2 */
 
@@ -502,9 +532,12 @@
 #define PCI_EXT_CAP_ID_VC	2
 #define PCI_EXT_CAP_ID_DSN	3
 #define PCI_EXT_CAP_ID_PWR	4
+#define PCI_EXT_CAP_ID_VNDR	11
+#define PCI_EXT_CAP_ID_ACS	13
 #define PCI_EXT_CAP_ID_ARI	14
 #define PCI_EXT_CAP_ID_ATS	15
 #define PCI_EXT_CAP_ID_SRIOV	16
+#define PCI_EXT_CAP_ID_LTR	24
 
 /* Advanced Error Reporting */
 #define PCI_ERR_UNCOR_STATUS	4	/* Uncorrectable Error Status */
@@ -556,8 +589,7 @@
 #define PCI_ERR_ROOT_FIRST_FATAL	0x00000010	/* First Fatal */
 #define PCI_ERR_ROOT_NONFATAL_RCV	0x00000020	/* Non-Fatal Received */
 #define PCI_ERR_ROOT_FATAL_RCV		0x00000040	/* Fatal Received */
-#define PCI_ERR_ROOT_COR_SRC	52
-#define PCI_ERR_ROOT_SRC	54
+#define PCI_ERR_ROOT_ERR_SRC	52	/* Error Source Identification */
 
 /* Virtual Channel */
 #define PCI_VC_PORT_REG1	4
@@ -662,4 +694,22 @@
 #define  PCI_SRIOV_VFM_MO	0x2	/* Active.MigrateOut */
 #define  PCI_SRIOV_VFM_AV	0x3	/* Active.Available */
 
+#define PCI_LTR_MAX_SNOOP_LAT	0x4
+#define PCI_LTR_MAX_NOSNOOP_LAT	0x6
+#define  PCI_LTR_VALUE_MASK	0x000003ff
+#define  PCI_LTR_SCALE_MASK	0x00001c00
+#define  PCI_LTR_SCALE_SHIFT	10
+
+/* Access Control Service */
+#define PCI_ACS_CAP		0x04	/* ACS Capability Register */
+#define  PCI_ACS_SV		0x01	/* Source Validation */
+#define  PCI_ACS_TB		0x02	/* Translation Blocking */
+#define  PCI_ACS_RR		0x04	/* P2P Request Redirect */
+#define  PCI_ACS_CR		0x08	/* P2P Completion Redirect */
+#define  PCI_ACS_UF		0x10	/* Upstream Forwarding */
+#define  PCI_ACS_EC		0x20	/* P2P Egress Control */
+#define  PCI_ACS_DT		0x40	/* Direct Translated P2P */
+#define PCI_ACS_CTRL		0x06	/* ACS Control Register */
+#define PCI_ACS_EGRESS_CTL_V	0x08	/* ACS Egress Control Vector */
+
 #endif /* LINUX_PCI_REGS_H */
diff --git a/hw/pcie_aer.c b/hw/pcie_aer.c
index 0c4e8a5..b872010 100644
--- a/hw/pcie_aer.c
+++ b/hw/pcie_aer.c
@@ -38,6 +38,9 @@
 #define PCIE_DEV_PRINTF(dev, fmt, ...)                                  \
     PCIE_DPRINTF("%s:%x "fmt, (dev)->name, (dev)->devfn, ## __VA_ARGS__)
 
+#define PCI_ERR_SRC_COR_OFFS    0
+#define PCI_ERR_SRC_UNCOR_OFFS  2
+
 /* From 6.2.7 Error Listing and Rules. Table 6-2, 6-3 and 6-4 */
 static uint32_t pcie_aer_uncor_default_severity(uint32_t status)
 {
@@ -320,7 +323,8 @@ static void pcie_aer_msg_root_port(PCIDevice *dev, const PCIEAERMsg *msg)
         if (root_status & PCI_ERR_ROOT_COR_RCV) {
             root_status |= PCI_ERR_ROOT_MULTI_COR_RCV;
         } else {
-            pci_set_word(aer_cap + PCI_ERR_ROOT_COR_SRC, msg->source_id);
+            pci_set_word(aer_cap + PCI_ERR_ROOT_ERR_SRC + PCI_ERR_SRC_COR_OFFS,
+                         msg->source_id);
         }
         root_status |= PCI_ERR_ROOT_COR_RCV;
         break;
@@ -341,7 +345,8 @@ static void pcie_aer_msg_root_port(PCIDevice *dev, const PCIEAERMsg *msg)
         if (root_status & PCI_ERR_ROOT_UNCOR_RCV) {
             root_status |= PCI_ERR_ROOT_MULTI_UNCOR_RCV;
         } else {
-            pci_set_word(aer_cap + PCI_ERR_ROOT_SRC, msg->source_id);
+            pci_set_word(aer_cap + PCI_ERR_ROOT_ERR_SRC +
+                         PCI_ERR_SRC_UNCOR_OFFS, msg->source_id);
         }
         root_status |= PCI_ERR_ROOT_UNCOR_RCV;
     }
commit 4dad7f1ec51e13b40d2554d666cc122ed898d8e6
Author: Jan Kiszka <jan.kiszka at siemens.com>
Date:   Tue Jun 7 19:26:20 2011 +0200

    msi: Fix copy&paste mistake in msi_uninit
    
    Signed-off-by: Jan Kiszka <jan.kiszka at siemens.com>
    Signed-off-by: Michael S. Tsirkin <mst at redhat.com>

diff --git a/hw/msi.c b/hw/msi.c
index b0795bd..941b339 100644
--- a/hw/msi.c
+++ b/hw/msi.c
@@ -172,7 +172,7 @@ void msi_uninit(struct PCIDevice *dev)
     }
     flags = pci_get_word(dev->config + msi_flags_off(dev));
     cap_size = msi_cap_sizeof(flags);
-    pci_del_capability(dev, PCI_CAP_ID_MSIX, cap_size);
+    pci_del_capability(dev, PCI_CAP_ID_MSI, cap_size);
     dev->cap_present &= ~QEMU_PCI_CAP_MSI;
 
     MSI_DEV_PRINTF(dev, "uninit\n");
commit d3674c5754775eb65ec2f2fd5f8cfe9b032ca0b1
Author: Jason Wang <jasowang at redhat.com>
Date:   Wed May 18 13:57:37 2011 +0800

    virtio: correctly initialize vm_running
    
    Current vm_running was not explicitly initialized and its value was changed by
    vm state notifier, this may confuse the virtio device being hotplugged such as
    virtio-net with vhost backend as it may think the vm was not running. Solve this
    by initialize this value explicitly in virtio_common_init().
    
    Signed-off-by: Jason Wang <jasowang at redhat.com>
    Signed-off-by: Michael S. Tsirkin <mst at redhat.com>

diff --git a/hw/virtio.c b/hw/virtio.c
index a651860..36b8f35 100644
--- a/hw/virtio.c
+++ b/hw/virtio.c
@@ -787,6 +787,7 @@ VirtIODevice *virtio_common_init(const char *name, uint16_t device_id,
     vdev->queue_sel = 0;
     vdev->config_vector = VIRTIO_NO_VECTOR;
     vdev->vq = qemu_mallocz(sizeof(VirtQueue) * VIRTIO_PCI_QUEUE_MAX);
+    vdev->vm_running = vm_running;
     for(i = 0; i < VIRTIO_PCI_QUEUE_MAX; i++) {
         vdev->vq[i].vector = VIRTIO_NO_VECTOR;
         vdev->vq[i].vdev = vdev;
commit 7157e2e23e89adcd436caeab31fdd6b47eded377
Author: Stefan Hajnoczi <stefanha at linux.vnet.ibm.com>
Date:   Sun May 8 22:29:07 2011 +0100

    virtio: guard against negative vq notifies
    
    The virtio_queue_notify() function checks that the virtqueue number is
    less than the maximum number of virtqueues.  A signed comparison is used
    but the virtqueue number could be negative if a buggy or malicious guest
    is run.  This results in memory accesses outside of the virtqueue array.
    
    It is risky doing input validation in common code instead of at the
    guest<->host boundary.  Note that virtio_queue_set_addr(),
    virtio_queue_get_addr(), virtio_queue_get_num(), and many other virtio
    functions do *not* validate the virtqueue number argument.
    
    Instead of fixing the comparison in virtio_queue_notify(), move the
    comparison to the virtio bindings (just like VIRTIO_PCI_QUEUE_SEL) where
    we have a uint32_t value and can avoid ever calling into common virtio
    code if the virtqueue number is invalid.
    
    Signed-off-by: Stefan Hajnoczi <stefanha at linux.vnet.ibm.com>
    Signed-off-by: Michael S. Tsirkin <mst at redhat.com>

diff --git a/hw/syborg_virtio.c b/hw/syborg_virtio.c
index 2f3e6da..00c7be8 100644
--- a/hw/syborg_virtio.c
+++ b/hw/syborg_virtio.c
@@ -146,7 +146,9 @@ static void syborg_virtio_writel(void *opaque, target_phys_addr_t offset,
             vdev->queue_sel = value;
         break;
     case SYBORG_VIRTIO_QUEUE_NOTIFY:
-        virtio_queue_notify(vdev, value);
+        if (value < VIRTIO_PCI_QUEUE_MAX) {
+            virtio_queue_notify(vdev, value);
+        }
         break;
     case SYBORG_VIRTIO_STATUS:
         virtio_set_status(vdev, value & 0xFF);
diff --git a/hw/virtio-pci.c b/hw/virtio-pci.c
index 270e2c7..b86c441 100644
--- a/hw/virtio-pci.c
+++ b/hw/virtio-pci.c
@@ -348,7 +348,9 @@ static void virtio_ioport_write(void *opaque, uint32_t addr, uint32_t val)
             vdev->queue_sel = val;
         break;
     case VIRTIO_PCI_QUEUE_NOTIFY:
-        virtio_queue_notify(vdev, val);
+        if (val < VIRTIO_PCI_QUEUE_MAX) {
+            virtio_queue_notify(vdev, val);
+        }
         break;
     case VIRTIO_PCI_STATUS:
         if (!(val & VIRTIO_CONFIG_S_DRIVER_OK)) {
diff --git a/hw/virtio.c b/hw/virtio.c
index 6e8814c..a651860 100644
--- a/hw/virtio.c
+++ b/hw/virtio.c
@@ -585,9 +585,7 @@ void virtio_queue_notify_vq(VirtQueue *vq)
 
 void virtio_queue_notify(VirtIODevice *vdev, int n)
 {
-    if (n < VIRTIO_PCI_QUEUE_MAX) {
-        virtio_queue_notify_vq(&vdev->vq[n]);
-    }
+    virtio_queue_notify_vq(&vdev->vq[n]);
 }
 
 uint16_t virtio_queue_vector(VirtIODevice *vdev, int n)
commit e75ccf2c033fb0503d6cb7ddd0fd1dfa0aa4fc16
Author: Isaku Yamahata <yamahata at valinux.co.jp>
Date:   Wed May 25 10:58:36 2011 +0900

    virtio-pci.c: convert to PCIDEviceInfo to initialize ids
    
    use PCIDeviceInfo to initialize ids.
    
    Signed-off-by: Isaku Yamahata <yamahata at valinux.co.jp>
    Signed-off-by: Michael S. Tsirkin <mst at redhat.com>

diff --git a/hw/virtio-pci.c b/hw/virtio-pci.c
index c19629d..270e2c7 100644
--- a/hw/virtio-pci.c
+++ b/hw/virtio-pci.c
@@ -669,9 +669,7 @@ static const VirtIOBindings virtio_pci_bindings = {
     .vmstate_change = virtio_pci_vmstate_change,
 };
 
-static void virtio_init_pci(VirtIOPCIProxy *proxy, VirtIODevice *vdev,
-                            uint16_t vendor, uint16_t device,
-                            uint16_t class_code, uint8_t pif)
+static void virtio_init_pci(VirtIOPCIProxy *proxy, VirtIODevice *vdev)
 {
     uint8_t *config;
     uint32_t size;
@@ -679,19 +677,12 @@ static void virtio_init_pci(VirtIOPCIProxy *proxy, VirtIODevice *vdev,
     proxy->vdev = vdev;
 
     config = proxy->pci_dev.config;
-    pci_config_set_vendor_id(config, vendor);
-    pci_config_set_device_id(config, device);
-
-    config[0x08] = VIRTIO_PCI_ABI_VERSION;
-
-    config[0x09] = pif;
-    pci_config_set_class(config, class_code);
-
-    config[0x2c] = vendor & 0xFF;
-    config[0x2d] = (vendor >> 8) & 0xFF;
-    config[0x2e] = vdev->device_id & 0xFF;
-    config[0x2f] = (vdev->device_id >> 8) & 0xFF;
 
+    if (proxy->class_code) {
+        pci_config_set_class(config, proxy->class_code);
+    }
+    pci_set_word(config + 0x2c, pci_get_word(config + PCI_VENDOR_ID));
+    pci_set_word(config + 0x2e, vdev->device_id);
     config[0x3d] = 1;
 
     if (vdev->nvectors && !msix_init(&proxy->pci_dev, vdev->nvectors, 1, 0)) {
@@ -735,10 +726,7 @@ static int virtio_blk_init_pci(PCIDevice *pci_dev)
         return -1;
     }
     vdev->nvectors = proxy->nvectors;
-    virtio_init_pci(proxy, vdev,
-                    PCI_VENDOR_ID_REDHAT_QUMRANET,
-                    PCI_DEVICE_ID_VIRTIO_BLOCK,
-                    proxy->class_code, 0x00);
+    virtio_init_pci(proxy, vdev);
     /* make the actual value visible */
     proxy->nvectors = vdev->nvectors;
     return 0;
@@ -776,10 +764,7 @@ static int virtio_serial_init_pci(PCIDevice *pci_dev)
     vdev->nvectors = proxy->nvectors == DEV_NVECTORS_UNSPECIFIED
                                         ? proxy->serial.max_virtserial_ports + 1
                                         : proxy->nvectors;
-    virtio_init_pci(proxy, vdev,
-                    PCI_VENDOR_ID_REDHAT_QUMRANET,
-                    PCI_DEVICE_ID_VIRTIO_CONSOLE,
-                    proxy->class_code, 0x00);
+    virtio_init_pci(proxy, vdev);
     proxy->nvectors = vdev->nvectors;
     return 0;
 }
@@ -801,11 +786,7 @@ static int virtio_net_init_pci(PCIDevice *pci_dev)
     vdev = virtio_net_init(&pci_dev->qdev, &proxy->nic, &proxy->net);
 
     vdev->nvectors = proxy->nvectors;
-    virtio_init_pci(proxy, vdev,
-                    PCI_VENDOR_ID_REDHAT_QUMRANET,
-                    PCI_DEVICE_ID_VIRTIO_NET,
-                    PCI_CLASS_NETWORK_ETHERNET,
-                    0x00);
+    virtio_init_pci(proxy, vdev);
 
     /* make the actual value visible */
     proxy->nvectors = vdev->nvectors;
@@ -827,11 +808,7 @@ static int virtio_balloon_init_pci(PCIDevice *pci_dev)
     VirtIODevice *vdev;
 
     vdev = virtio_balloon_init(&pci_dev->qdev);
-    virtio_init_pci(proxy, vdev,
-                    PCI_VENDOR_ID_REDHAT_QUMRANET,
-                    PCI_DEVICE_ID_VIRTIO_BALLOON,
-                    PCI_CLASS_MEMORY_RAM,
-                    0x00);
+    virtio_init_pci(proxy, vdev);
     return 0;
 }
 
@@ -843,11 +820,7 @@ static int virtio_9p_init_pci(PCIDevice *pci_dev)
 
     vdev = virtio_9p_init(&pci_dev->qdev, &proxy->fsconf);
     vdev->nvectors = proxy->nvectors;
-    virtio_init_pci(proxy, vdev,
-                    PCI_VENDOR_ID_REDHAT_QUMRANET,
-                    0x1009,
-                    0x2,
-                    0x00);
+    virtio_init_pci(proxy, vdev);
     /* make the actual value visible */
     proxy->nvectors = vdev->nvectors;
     return 0;
@@ -861,6 +834,10 @@ static PCIDeviceInfo virtio_info[] = {
         .qdev.size = sizeof(VirtIOPCIProxy),
         .init      = virtio_blk_init_pci,
         .exit      = virtio_blk_exit_pci,
+        .vendor_id = PCI_VENDOR_ID_REDHAT_QUMRANET,
+        .device_id = PCI_DEVICE_ID_VIRTIO_BLOCK,
+        .revision  = VIRTIO_PCI_ABI_VERSION,
+        .class_id  = PCI_CLASS_STORAGE_SCSI,
         .qdev.props = (Property[]) {
             DEFINE_PROP_HEX32("class", VirtIOPCIProxy, class_code, 0),
             DEFINE_BLOCK_PROPERTIES(VirtIOPCIProxy, block),
@@ -878,6 +855,10 @@ static PCIDeviceInfo virtio_info[] = {
         .init       = virtio_net_init_pci,
         .exit       = virtio_net_exit_pci,
         .romfile    = "pxe-virtio.rom",
+        .vendor_id  = PCI_VENDOR_ID_REDHAT_QUMRANET,
+        .device_id  = PCI_DEVICE_ID_VIRTIO_NET,
+        .revision   = VIRTIO_PCI_ABI_VERSION,
+        .class_id   = PCI_CLASS_NETWORK_ETHERNET,
         .qdev.props = (Property[]) {
             DEFINE_PROP_BIT("ioeventfd", VirtIOPCIProxy, flags,
                             VIRTIO_PCI_FLAG_USE_IOEVENTFD_BIT, false),
@@ -898,6 +879,10 @@ static PCIDeviceInfo virtio_info[] = {
         .qdev.size = sizeof(VirtIOPCIProxy),
         .init      = virtio_serial_init_pci,
         .exit      = virtio_serial_exit_pci,
+        .vendor_id = PCI_VENDOR_ID_REDHAT_QUMRANET,
+        .device_id = PCI_DEVICE_ID_VIRTIO_CONSOLE,
+        .revision  = VIRTIO_PCI_ABI_VERSION,
+        .class_id  = PCI_CLASS_COMMUNICATION_OTHER,
         .qdev.props = (Property[]) {
             DEFINE_PROP_BIT("ioeventfd", VirtIOPCIProxy, flags,
                             VIRTIO_PCI_FLAG_USE_IOEVENTFD_BIT, true),
@@ -916,6 +901,10 @@ static PCIDeviceInfo virtio_info[] = {
         .qdev.size = sizeof(VirtIOPCIProxy),
         .init      = virtio_balloon_init_pci,
         .exit      = virtio_exit_pci,
+        .vendor_id = PCI_VENDOR_ID_REDHAT_QUMRANET,
+        .device_id = PCI_DEVICE_ID_VIRTIO_BALLOON,
+        .revision  = VIRTIO_PCI_ABI_VERSION,
+        .class_id  = PCI_CLASS_MEMORY_RAM,
         .qdev.props = (Property[]) {
             DEFINE_VIRTIO_COMMON_FEATURES(VirtIOPCIProxy, host_features),
             DEFINE_PROP_END_OF_LIST(),
@@ -927,6 +916,10 @@ static PCIDeviceInfo virtio_info[] = {
         .qdev.alias = "virtio-9p",
         .qdev.size = sizeof(VirtIOPCIProxy),
         .init      = virtio_9p_init_pci,
+        .vendor_id = PCI_VENDOR_ID_REDHAT_QUMRANET,
+        .device_id = 0x1009,
+        .revision  = VIRTIO_PCI_ABI_VERSION,
+        .class_id  = 0x2,
         .qdev.props = (Property[]) {
             DEFINE_PROP_UINT32("vectors", VirtIOPCIProxy, nvectors, 2),
             DEFINE_VIRTIO_COMMON_FEATURES(VirtIOPCIProxy, host_features),
commit 5844997a280cc4101363895c5953fea38350cb73
Author: Isaku Yamahata <yamahata at valinux.co.jp>
Date:   Wed May 25 10:58:35 2011 +0900

    hw/xio3130_upstream.c: convert to PCIDeviceInfo to initialize ids
    
    use PCIDeviceInfo to initialize ids.
    
    Signed-off-by: Isaku Yamahata <yamahata at valinux.co.jp>
    Signed-off-by: Michael S. Tsirkin <mst at redhat.com>

diff --git a/hw/xio3130_upstream.c b/hw/xio3130_upstream.c
index a7640f5..8283695 100644
--- a/hw/xio3130_upstream.c
+++ b/hw/xio3130_upstream.c
@@ -65,9 +65,6 @@ static int xio3130_upstream_initfn(PCIDevice *d)
     }
 
     pcie_port_init_reg(d);
-    pci_config_set_vendor_id(d->config, PCI_VENDOR_ID_TI);
-    pci_config_set_device_id(d->config, PCI_DEVICE_ID_TI_XIO3130U);
-    d->config[PCI_REVISION_ID] = XIO3130_REVISION;
 
     rc = msi_init(d, XIO3130_MSI_OFFSET, XIO3130_MSI_NR_VECTOR,
                   XIO3130_MSI_SUPPORTED_FLAGS & PCI_MSI_FLAGS_64BIT,
@@ -159,6 +156,9 @@ static PCIDeviceInfo xio3130_upstream_info = {
     .config_write = xio3130_upstream_write_config,
     .init = xio3130_upstream_initfn,
     .exit = xio3130_upstream_exitfn,
+    .vendor_id = PCI_VENDOR_ID_TI,
+    .device_id = PCI_DEVICE_ID_TI_XIO3130U,
+    .revision = XIO3130_REVISION,
 
     .qdev.props = (Property[]) {
         DEFINE_PROP_UINT8("port", PCIEPort, port, 0),
commit 3ec39b2d20a25505382619e31e6572e3d04f311e
Author: Isaku Yamahata <yamahata at valinux.co.jp>
Date:   Wed May 25 10:58:34 2011 +0900

    hw/xio3130_downstream.c: convert to PCIDeviceInfo to initialize ids
    
    use PCIDeviceInfo to initialize ids.
    
    Signed-off-by: Isaku Yamahata <yamahata at valinux.co.jp>
    Signed-off-by: Michael S. Tsirkin <mst at redhat.com>

diff --git a/hw/xio3130_downstream.c b/hw/xio3130_downstream.c
index 5aa6a6b..d3c387d 100644
--- a/hw/xio3130_downstream.c
+++ b/hw/xio3130_downstream.c
@@ -69,9 +69,6 @@ static int xio3130_downstream_initfn(PCIDevice *d)
     }
 
     pcie_port_init_reg(d);
-    pci_config_set_vendor_id(d->config, PCI_VENDOR_ID_TI);
-    pci_config_set_device_id(d->config, PCI_DEVICE_ID_TI_XIO3130D);
-    d->config[PCI_REVISION_ID] = XIO3130_REVISION;
 
     rc = msi_init(d, XIO3130_MSI_OFFSET, XIO3130_MSI_NR_VECTOR,
                   XIO3130_MSI_SUPPORTED_FLAGS & PCI_MSI_FLAGS_64BIT,
@@ -182,6 +179,9 @@ static PCIDeviceInfo xio3130_downstream_info = {
     .config_write = xio3130_downstream_write_config,
     .init = xio3130_downstream_initfn,
     .exit = xio3130_downstream_exitfn,
+    .vendor_id = PCI_VENDOR_ID_TI,
+    .device_id = PCI_DEVICE_ID_TI_XIO3130D,
+    .revision = XIO3130_REVISION,
 
     .qdev.props = (Property[]) {
         DEFINE_PROP_UINT8("port", PCIESlot, port.port, 0),
commit 24b856ca63f1c72b5043af6b291e7cc35900f4d6
Author: Isaku Yamahata <yamahata at valinux.co.jp>
Date:   Wed May 25 10:58:33 2011 +0900

    hw/wdt_i6300esb.c: convert to PCIDeviceInfo to initialize ids
    
    use PCIDeviceInfo to initialize ids.
    
    Signed-off-by: Isaku Yamahata <yamahata at valinux.co.jp>
    Signed-off-by: Michael S. Tsirkin <mst at redhat.com>

diff --git a/hw/wdt_i6300esb.c b/hw/wdt_i6300esb.c
index 0791721..bd57fd3 100644
--- a/hw/wdt_i6300esb.c
+++ b/hw/wdt_i6300esb.c
@@ -400,9 +400,6 @@ static int i6300esb_init(PCIDevice *dev)
     d->previous_reboot_flag = 0;
 
     pci_conf = d->dev.config;
-    pci_config_set_vendor_id(pci_conf, PCI_VENDOR_ID_INTEL);
-    pci_config_set_device_id(pci_conf, PCI_DEVICE_ID_INTEL_ESB_9);
-    pci_config_set_class(pci_conf, PCI_CLASS_SYSTEM_OTHER);
 
     io_mem = cpu_register_io_memory(mem_read, mem_write, d,
                                     DEVICE_NATIVE_ENDIAN);
@@ -425,6 +422,9 @@ static PCIDeviceInfo i6300esb_info = {
     .config_read  = i6300esb_config_read,
     .config_write = i6300esb_config_write,
     .init         = i6300esb_init,
+    .vendor_id    = PCI_VENDOR_ID_INTEL,
+    .device_id    = PCI_DEVICE_ID_INTEL_ESB_9,
+    .class_id     = PCI_CLASS_SYSTEM_OTHER,
 };
 
 static void i6300esb_register_devices(void)
commit 1cf0d2b8352a2df35919030b84dbfc713ee9b9be
Author: Isaku Yamahata <yamahata at valinux.co.jp>
Date:   Wed May 25 10:58:32 2011 +0900

    hw/vt82c686.c: convert to PCIDeviceInfo to initialize ids
    
    use PCIDeviceInfo to initialize ids.
    
    Signed-off-by: Isaku Yamahata <yamahata at valinux.co.jp>
    Signed-off-by: Michael S. Tsirkin <mst at redhat.com>

diff --git a/hw/vt82c686.c b/hw/vt82c686.c
index ca8f826..5c973ed 100644
--- a/hw/vt82c686.c
+++ b/hw/vt82c686.c
@@ -326,11 +326,6 @@ static int vt82c686b_ac97_initfn(PCIDevice *dev)
     VT686AC97State *s = DO_UPCAST(VT686AC97State, dev, dev);
     uint8_t *pci_conf = s->dev.config;
 
-    pci_config_set_vendor_id(pci_conf, PCI_VENDOR_ID_VIA);
-    pci_config_set_device_id(pci_conf, PCI_DEVICE_ID_VIA_AC97);
-    pci_config_set_class(pci_conf, PCI_CLASS_MULTIMEDIA_AUDIO);
-    pci_config_set_revision(pci_conf, 0x50);
-
     pci_set_word(pci_conf + PCI_COMMAND, PCI_COMMAND_INVALIDATE |
                  PCI_COMMAND_PARITY);
     pci_set_word(pci_conf + PCI_STATUS, PCI_STATUS_CAP_LIST |
@@ -353,6 +348,10 @@ static PCIDeviceInfo via_ac97_info = {
     .qdev.desc          = "AC97",
     .qdev.size          = sizeof(VT686AC97State),
     .init               = vt82c686b_ac97_initfn,
+    .vendor_id          = PCI_VENDOR_ID_VIA,
+    .device_id          = PCI_DEVICE_ID_VIA_AC97,
+    .revision           = 0x50,
+    .class_id           = PCI_CLASS_MULTIMEDIA_AUDIO,
 };
 
 static void vt82c686b_ac97_register(void)
@@ -367,11 +366,6 @@ static int vt82c686b_mc97_initfn(PCIDevice *dev)
     VT686MC97State *s = DO_UPCAST(VT686MC97State, dev, dev);
     uint8_t *pci_conf = s->dev.config;
 
-    pci_config_set_vendor_id(pci_conf, PCI_VENDOR_ID_VIA);
-    pci_config_set_device_id(pci_conf, PCI_DEVICE_ID_VIA_MC97);
-    pci_config_set_class(pci_conf, PCI_CLASS_COMMUNICATION_OTHER);
-    pci_config_set_revision(pci_conf, 0x30);
-
     pci_set_word(pci_conf + PCI_COMMAND, PCI_COMMAND_INVALIDATE |
                  PCI_COMMAND_VGA_PALETTE);
     pci_set_word(pci_conf + PCI_STATUS, PCI_STATUS_DEVSEL_MEDIUM);
@@ -393,6 +387,10 @@ static PCIDeviceInfo via_mc97_info = {
     .qdev.desc          = "MC97",
     .qdev.size          = sizeof(VT686MC97State),
     .init               = vt82c686b_mc97_initfn,
+    .vendor_id          = PCI_VENDOR_ID_VIA,
+    .device_id          = PCI_DEVICE_ID_VIA_MC97,
+    .class_id           = PCI_CLASS_COMMUNICATION_OTHER,
+    .revision           = 0x30,
 };
 
 static void vt82c686b_mc97_register(void)
@@ -409,11 +407,6 @@ static int vt82c686b_pm_initfn(PCIDevice *dev)
     uint8_t *pci_conf;
 
     pci_conf = s->dev.config;
-    pci_config_set_vendor_id(pci_conf, PCI_VENDOR_ID_VIA);
-    pci_config_set_device_id(pci_conf, PCI_DEVICE_ID_VIA_ACPI);
-    pci_config_set_class(pci_conf, PCI_CLASS_BRIDGE_OTHER);
-    pci_config_set_revision(pci_conf, 0x40);
-
     pci_set_word(pci_conf + PCI_COMMAND, 0);
     pci_set_word(pci_conf + PCI_STATUS, PCI_STATUS_FAST_BACK |
                  PCI_STATUS_DEVSEL_MEDIUM);
@@ -462,6 +455,10 @@ static PCIDeviceInfo via_pm_info = {
     .qdev.vmsd          = &vmstate_acpi,
     .init               = vt82c686b_pm_initfn,
     .config_write       = pm_write_config,
+    .vendor_id          = PCI_VENDOR_ID_VIA,
+    .device_id          = PCI_DEVICE_ID_VIA_ACPI,
+    .class_id           = PCI_CLASS_BRIDGE_OTHER,
+    .revision           = 0x40,
     .qdev.props         = (Property[]) {
         DEFINE_PROP_UINT32("smb_io_base", VT686PMState, smb_io_base, 0),
         DEFINE_PROP_END_OF_LIST(),
@@ -496,11 +493,7 @@ static int vt82c686b_initfn(PCIDevice *d)
     isa_bus_new(&d->qdev);
 
     pci_conf = d->config;
-    pci_config_set_vendor_id(pci_conf, PCI_VENDOR_ID_VIA);
-    pci_config_set_device_id(pci_conf, PCI_DEVICE_ID_VIA_ISA_BRIDGE);
-    pci_config_set_class(pci_conf, PCI_CLASS_BRIDGE_ISA);
     pci_config_set_prog_interface(pci_conf, 0x0);
-    pci_config_set_revision(pci_conf,0x40); /* Revision 4.0 */
 
     wmask = d->wmask;
     for (i = 0x00; i < 0xff; i++) {
@@ -531,6 +524,10 @@ static PCIDeviceInfo via_info = {
     .qdev.no_user = 1,
     .init         = vt82c686b_initfn,
     .config_write = vt82c686b_write_config,
+    .vendor_id    = PCI_VENDOR_ID_VIA,
+    .device_id    = PCI_DEVICE_ID_VIA_ISA_BRIDGE,
+    .class_id     = PCI_CLASS_BRIDGE_ISA,
+    .revision     = 0x40,
 };
 
 static void vt82c686b_register(void)
commit 32902772833dbe424f754d5b841d996b90be87b2
Author: Isaku Yamahata <yamahata at valinux.co.jp>
Date:   Wed May 25 10:58:31 2011 +0900

    hw/vga-pci.c: convert to PCIDeviceInfo to initialize ids
    
    use PCIDeviceInfo to initialize ids.
    
    Signed-off-by: Isaku Yamahata <yamahata at valinux.co.jp>
    Signed-off-by: Michael S. Tsirkin <mst at redhat.com>

diff --git a/hw/vga-pci.c b/hw/vga-pci.c
index ce9ec45..481f448 100644
--- a/hw/vga-pci.c
+++ b/hw/vga-pci.c
@@ -74,7 +74,6 @@ static int pci_vga_initfn(PCIDevice *dev)
 {
      PCIVGAState *d = DO_UPCAST(PCIVGAState, dev, dev);
      VGACommonState *s = &d->vga;
-     uint8_t *pci_conf = d->dev.config;
 
      // vga + console init
      vga_common_init(s, VGA_RAM_SIZE);
@@ -83,11 +82,6 @@ static int pci_vga_initfn(PCIDevice *dev)
      s->ds = graphic_console_init(s->update, s->invalidate,
                                   s->screen_dump, s->text_update, s);
 
-     // dummy VGA (same as Bochs ID)
-     pci_config_set_vendor_id(pci_conf, PCI_VENDOR_ID_QEMU);
-     pci_config_set_device_id(pci_conf, PCI_DEVICE_ID_QEMU_VGA);
-     pci_config_set_class(pci_conf, PCI_CLASS_DISPLAY_VGA);
-
      /* XXX: VGA_RAM_SIZE must be a power of two */
      pci_register_bar(&d->dev, 0, VGA_RAM_SIZE,
                       PCI_BASE_ADDRESS_MEM_PREFETCH, vga_map);
@@ -114,6 +108,11 @@ static PCIDeviceInfo vga_info = {
     .init         = pci_vga_initfn,
     .config_write = pci_vga_write_config,
     .romfile      = "vgabios-stdvga.bin",
+
+    /* dummy VGA (same as Bochs ID) */
+    .vendor_id    = PCI_VENDOR_ID_QEMU,
+    .device_id    = PCI_DEVICE_ID_QEMU_VGA,
+    .class_id     = PCI_CLASS_DISPLAY_VGA,
 };
 
 static void vga_register(void)
commit 56fe6408d71264ef35049e24213f7003ade5bc14
Author: Isaku Yamahata <yamahata at valinux.co.jp>
Date:   Wed May 25 10:58:30 2011 +0900

    hw/versatile_pci.c: convert to PCIDeviceInfo to initialize ids
    
    use PCIDeviceInfo to initialize ids.
    
    Signed-off-by: Isaku Yamahata <yamahata at valinux.co.jp>
    Signed-off-by: Michael S. Tsirkin <mst at redhat.com>

diff --git a/hw/versatile_pci.c b/hw/versatile_pci.c
index 2fed8a0..8e75ffc 100644
--- a/hw/versatile_pci.c
+++ b/hw/versatile_pci.c
@@ -133,12 +133,8 @@ static int pci_realview_init(SysBusDevice *dev)
 
 static int versatile_pci_host_init(PCIDevice *d)
 {
-    pci_config_set_vendor_id(d->config, PCI_VENDOR_ID_XILINX);
-    /* Both boards have the same device ID.  Oh well.  */
-    pci_config_set_device_id(d->config, PCI_DEVICE_ID_XILINX_XC2VP30);
     pci_set_word(d->config + PCI_STATUS,
 		 PCI_STATUS_66MHZ | PCI_STATUS_DEVSEL_MEDIUM);
-    pci_config_set_class(d->config, PCI_CLASS_PROCESSOR_CO);
     pci_set_byte(d->config + PCI_LATENCY_TIMER, 0x10);
     return 0;
 }
@@ -147,6 +143,10 @@ static PCIDeviceInfo versatile_pci_host_info = {
     .qdev.name = "versatile_pci_host",
     .qdev.size = sizeof(PCIDevice),
     .init      = versatile_pci_host_init,
+    .vendor_id = PCI_VENDOR_ID_XILINX,
+    /* Both boards have the same device ID.  Oh well.  */
+    .device_id = PCI_DEVICE_ID_XILINX_XC2VP30,
+    .class_id  = PCI_CLASS_PROCESSOR_CO,
 };
 
 static void versatile_pci_register_devices(void)
commit a8eae58556c7dc693d757a9144045fbee7434c6c
Author: Isaku Yamahata <yamahata at valinux.co.jp>
Date:   Wed May 25 10:58:29 2011 +0900

    hw/usb-ohci.c: convert to PCIDeviceInfo to initialize ids
    
    use PCIDeviceInfo to initialize ids.
    
    Signed-off-by: Isaku Yamahata <yamahata at valinux.co.jp>
    Signed-off-by: Michael S. Tsirkin <mst at redhat.com>

diff --git a/hw/usb-ohci.c b/hw/usb-ohci.c
index d21c820..7ff2322 100644
--- a/hw/usb-ohci.c
+++ b/hw/usb-ohci.c
@@ -1716,11 +1716,7 @@ static int usb_ohci_initfn_pci(struct PCIDevice *dev)
     OHCIPCIState *ohci = DO_UPCAST(OHCIPCIState, pci_dev, dev);
     int num_ports = 3;
 
-    pci_config_set_vendor_id(ohci->pci_dev.config, PCI_VENDOR_ID_APPLE);
-    pci_config_set_device_id(ohci->pci_dev.config,
-                             PCI_DEVICE_ID_APPLE_IPID_USB);
     ohci->pci_dev.config[PCI_CLASS_PROG] = 0x10; /* OHCI */
-    pci_config_set_class(ohci->pci_dev.config, PCI_CLASS_SERIAL_USB);
     /* TODO: RST# value should be 0. */
     ohci->pci_dev.config[PCI_INTERRUPT_PIN] = 0x01; /* interrupt pin 1 */
 
@@ -1760,6 +1756,9 @@ static PCIDeviceInfo ohci_pci_info = {
     .qdev.desc    = "Apple USB Controller",
     .qdev.size    = sizeof(OHCIPCIState),
     .init         = usb_ohci_initfn_pci,
+    .vendor_id    = PCI_VENDOR_ID_APPLE,
+    .device_id    = PCI_DEVICE_ID_APPLE_IPID_USB,
+    .class_id     = PCI_CLASS_SERIAL_USB,
 };
 
 static SysBusDeviceInfo ohci_sysbus_info = {
commit d7b61ecc61f84d23f98f1ee270fb48b41834ca00
Author: Isaku Yamahata <yamahata at valinux.co.jp>
Date:   Wed May 25 10:58:28 2011 +0900

    hw/unin_pci.c: convert to PCIDeviceInfo to initialize ids
    
    use PCIDeviceInfo to initialize ids.
    
    Signed-off-by: Isaku Yamahata <yamahata at valinux.co.jp>
    Signed-off-by: Michael S. Tsirkin <mst at redhat.com>

diff --git a/hw/unin_pci.c b/hw/unin_pci.c
index c57c0a1..d364daa 100644
--- a/hw/unin_pci.c
+++ b/hw/unin_pci.c
@@ -279,10 +279,6 @@ PCIBus *pci_pmac_u3_init(qemu_irq *pic)
 
 static int unin_main_pci_host_init(PCIDevice *d)
 {
-    pci_config_set_vendor_id(d->config, PCI_VENDOR_ID_APPLE);
-    pci_config_set_device_id(d->config, PCI_DEVICE_ID_APPLE_UNI_N_PCI);
-    d->config[0x08] = 0x00; // revision
-    pci_config_set_class(d->config, PCI_CLASS_BRIDGE_HOST);
     d->config[0x0C] = 0x08; // cache_line_size
     d->config[0x0D] = 0x10; // latency_timer
     d->config[0x34] = 0x00; // capabilities_pointer
@@ -291,10 +287,6 @@ static int unin_main_pci_host_init(PCIDevice *d)
 
 static int unin_agp_pci_host_init(PCIDevice *d)
 {
-    pci_config_set_vendor_id(d->config, PCI_VENDOR_ID_APPLE);
-    pci_config_set_device_id(d->config, PCI_DEVICE_ID_APPLE_UNI_N_AGP);
-    d->config[0x08] = 0x00; // revision
-    pci_config_set_class(d->config, PCI_CLASS_BRIDGE_HOST);
     d->config[0x0C] = 0x08; // cache_line_size
     d->config[0x0D] = 0x10; // latency_timer
     //    d->config[0x34] = 0x80; // capabilities_pointer
@@ -303,11 +295,6 @@ static int unin_agp_pci_host_init(PCIDevice *d)
 
 static int u3_agp_pci_host_init(PCIDevice *d)
 {
-    pci_config_set_vendor_id(d->config, PCI_VENDOR_ID_APPLE);
-    pci_config_set_device_id(d->config, PCI_DEVICE_ID_APPLE_U3_AGP);
-    /* revision */
-    d->config[0x08] = 0x00;
-    pci_config_set_class(d->config, PCI_CLASS_BRIDGE_HOST);
     /* cache line size */
     d->config[0x0C] = 0x08;
     /* latency timer */
@@ -317,10 +304,6 @@ static int u3_agp_pci_host_init(PCIDevice *d)
 
 static int unin_internal_pci_host_init(PCIDevice *d)
 {
-    pci_config_set_vendor_id(d->config, PCI_VENDOR_ID_APPLE);
-    pci_config_set_device_id(d->config, PCI_DEVICE_ID_APPLE_UNI_N_I_PCI);
-    d->config[0x08] = 0x00; // revision
-    pci_config_set_class(d->config, PCI_CLASS_BRIDGE_HOST);
     d->config[0x0C] = 0x08; // cache_line_size
     d->config[0x0D] = 0x10; // latency_timer
     d->config[0x34] = 0x00; // capabilities_pointer
@@ -331,24 +314,40 @@ static PCIDeviceInfo unin_main_pci_host_info = {
     .qdev.name = "uni-north",
     .qdev.size = sizeof(PCIDevice),
     .init      = unin_main_pci_host_init,
+    .vendor_id = PCI_VENDOR_ID_APPLE,
+    .device_id = PCI_DEVICE_ID_APPLE_UNI_N_PCI,
+    .revision  = 0x00,
+    .class_id  = PCI_CLASS_BRIDGE_HOST,
 };
 
 static PCIDeviceInfo u3_agp_pci_host_info = {
     .qdev.name = "u3-agp",
     .qdev.size = sizeof(PCIDevice),
     .init      = u3_agp_pci_host_init,
+    .vendor_id = PCI_VENDOR_ID_APPLE,
+    .device_id = PCI_DEVICE_ID_APPLE_U3_AGP,
+    .revision  = 0x00,
+    .class_id  = PCI_CLASS_BRIDGE_HOST,
 };
 
 static PCIDeviceInfo unin_agp_pci_host_info = {
     .qdev.name = "uni-north-agp",
     .qdev.size = sizeof(PCIDevice),
     .init      = unin_agp_pci_host_init,
+    .vendor_id = PCI_VENDOR_ID_APPLE,
+    .device_id = PCI_DEVICE_ID_APPLE_UNI_N_AGP,
+    .revision  = 0x00,
+    .class_id  = PCI_CLASS_BRIDGE_HOST,
 };
 
 static PCIDeviceInfo unin_internal_pci_host_info = {
     .qdev.name = "uni-north-pci",
     .qdev.size = sizeof(PCIDevice),
     .init      = unin_internal_pci_host_init,
+    .vendor_id = PCI_VENDOR_ID_APPLE,
+    .device_id = PCI_DEVICE_ID_APPLE_UNI_N_I_PCI,
+    .revision  = 0x00,
+    .class_id  = PCI_CLASS_BRIDGE_HOST,
 };
 
 static void unin_register_devices(void)
commit e8b36ba92e0394815b64d96b00e81db3c851f6e2
Author: Isaku Yamahata <yamahata at valinux.co.jp>
Date:   Wed May 25 10:58:27 2011 +0900

    hw/sun4u.c: convert to PCIDeviceInfo to initialize ids
    
    use PCIDeviceInfo to initialize ids.
    
    Signed-off-by: Isaku Yamahata <yamahata at valinux.co.jp>
    Signed-off-by: Michael S. Tsirkin <mst at redhat.com>

diff --git a/hw/sun4u.c b/hw/sun4u.c
index 5eb38cf..d7dcaf0 100644
--- a/hw/sun4u.c
+++ b/hw/sun4u.c
@@ -553,15 +553,11 @@ pci_ebus_init1(PCIDevice *s)
 {
     isa_bus_new(&s->qdev);
 
-    pci_config_set_vendor_id(s->config, PCI_VENDOR_ID_SUN);
-    pci_config_set_device_id(s->config, PCI_DEVICE_ID_SUN_EBUS);
     s->config[0x04] = 0x06; // command = bus master, pci mem
     s->config[0x05] = 0x00;
     s->config[0x06] = 0xa0; // status = fast back-to-back, 66MHz, no error
     s->config[0x07] = 0x03; // status = medium devsel
-    s->config[0x08] = 0x01; // revision
     s->config[0x09] = 0x00; // programming i/f
-    pci_config_set_class(s->config, PCI_CLASS_BRIDGE_OTHER);
     s->config[0x0D] = 0x0a; // latency_timer
 
     pci_register_bar(s, 0, 0x1000000, PCI_BASE_ADDRESS_SPACE_MEMORY,
@@ -575,6 +571,10 @@ static PCIDeviceInfo ebus_info = {
     .qdev.name = "ebus",
     .qdev.size = sizeof(PCIDevice),
     .init = pci_ebus_init1,
+    .vendor_id = PCI_VENDOR_ID_SUN,
+    .device_id = PCI_DEVICE_ID_SUN_EBUS,
+    .revision = 0x01,
+    .class_id = PCI_CLASS_BRIDGE_OTHER,
 };
 
 static void pci_ebus_register(void)
commit ae2ebad7331930280324005c06bc0891f02eef53
Author: Isaku Yamahata <yamahata at valinux.co.jp>
Date:   Wed May 25 10:58:26 2011 +0900

    hw/sh_pci.c: convert to PCIDeviceInfo to initialize ids
    
    use PCIDeviceInfo to initialize ids.
    
    Signed-off-by: Isaku Yamahata <yamahata at valinux.co.jp>
    Signed-off-by: Michael S. Tsirkin <mst at redhat.com>

diff --git a/hw/sh_pci.c b/hw/sh_pci.c
index e99d8db..a076cf2 100644
--- a/hw/sh_pci.c
+++ b/hw/sh_pci.c
@@ -137,8 +137,6 @@ static int sh_pci_init_device(SysBusDevice *dev)
 
 static int sh_pci_host_init(PCIDevice *d)
 {
-    pci_config_set_vendor_id(d->config, PCI_VENDOR_ID_HITACHI);
-    pci_config_set_device_id(d->config, PCI_DEVICE_ID_HITACHI_SH7751R);
     pci_set_word(d->config + PCI_COMMAND, PCI_COMMAND_WAIT);
     pci_set_word(d->config + PCI_STATUS, PCI_STATUS_CAP_LIST |
                  PCI_STATUS_FAST_BACK | PCI_STATUS_DEVSEL_MEDIUM);
@@ -149,6 +147,8 @@ static PCIDeviceInfo sh_pci_host_info = {
     .qdev.name = "sh_pci_host",
     .qdev.size = sizeof(PCIDevice),
     .init      = sh_pci_host_init,
+    .vendor_id = PCI_VENDOR_ID_HITACHI,
+    .device_id = PCI_DEVICE_ID_HITACHI_SH7751R,
 };
 
 static void sh_pci_register_devices(void)
commit 7cba16a748b3ed7aba1a94304869fcfa9b5c0396
Author: Isaku Yamahata <yamahata at valinux.co.jp>
Date:   Wed May 25 10:58:25 2011 +0900

    hw/rtl8139.c: convert to PCIDeviceInfo to initialize ids
    
    use PCIDeviceInfo to initialize ids.
    
    Signed-off-by: Isaku Yamahata <yamahata at valinux.co.jp>
    Signed-off-by: Michael S. Tsirkin <mst at redhat.com>

diff --git a/hw/rtl8139.c b/hw/rtl8139.c
index c7c7a3c..34e3a9e 100644
--- a/hw/rtl8139.c
+++ b/hw/rtl8139.c
@@ -3453,10 +3453,6 @@ static int pci_rtl8139_init(PCIDevice *dev)
     uint8_t *pci_conf;
 
     pci_conf = s->dev.config;
-    pci_config_set_vendor_id(pci_conf, PCI_VENDOR_ID_REALTEK);
-    pci_config_set_device_id(pci_conf, PCI_DEVICE_ID_REALTEK_8139);
-    pci_conf[PCI_REVISION_ID] = RTL8139_PCI_REVID; /* >=0x20 is for 8139C+ */
-    pci_config_set_class(pci_conf, PCI_CLASS_NETWORK_ETHERNET);
     pci_conf[PCI_INTERRUPT_PIN] = 1;    /* interrupt pin 0 */
     /* TODO: start of capability list, but no capability
      * list bit in status register, and offset 0xdc seems unused. */
@@ -3510,6 +3506,10 @@ static PCIDeviceInfo rtl8139_info = {
     .init       = pci_rtl8139_init,
     .exit       = pci_rtl8139_uninit,
     .romfile    = "pxe-rtl8139.rom",
+    .vendor_id  = PCI_VENDOR_ID_REALTEK,
+    .device_id  = PCI_DEVICE_ID_REALTEK_8139,
+    .revision   = RTL8139_PCI_REVID, /* >=0x20 is for 8139C+ */
+    .class_id   = PCI_CLASS_NETWORK_ETHERNET,
     .qdev.props = (Property[]) {
         DEFINE_NIC_PROPERTIES(RTL8139State, conf),
         DEFINE_PROP_END_OF_LIST(),
commit 96c05abc904c6f74b60981d956cee531920e4cdf
Author: Isaku Yamahata <yamahata at valinux.co.jp>
Date:   Wed May 25 10:58:24 2011 +0900

    hw/qxl.c: convert to PCIDeviceInfo to initialize ids
    
    use PCIDeviceInfo to initialize ids.
    
    Signed-off-by: Isaku Yamahata <yamahata at valinux.co.jp>
    Signed-off-by: Michael S. Tsirkin <mst at redhat.com>

diff --git a/hw/qxl.c b/hw/qxl.c
index fe4212b..63cffc3 100644
--- a/hw/qxl.c
+++ b/hw/qxl.c
@@ -1233,7 +1233,6 @@ static int qxl_init_common(PCIQXLDevice *qxl)
         break;
     }
 
-    pci_config_set_vendor_id(config, REDHAT_PCI_VENDOR_ID);
     pci_config_set_device_id(config, pci_device_id);
     pci_set_byte(&config[PCI_REVISION_ID], pci_device_rev);
     pci_set_byte(&config[PCI_INTERRUPT_PIN], 1);
@@ -1310,7 +1309,6 @@ static int qxl_init_primary(PCIDevice *dev)
     qxl0 = qxl;
     register_displaychangelistener(vga->ds, &display_listener);
 
-    pci_config_set_class(dev->config, PCI_CLASS_DISPLAY_VGA);
     return qxl_init_common(qxl);
 }
 
@@ -1330,7 +1328,6 @@ static int qxl_init_secondary(PCIDevice *dev)
                                           qxl->vga.vram_size);
     qxl->vga.vram_ptr = qemu_get_ram_ptr(qxl->vga.vram_offset);
 
-    pci_config_set_class(dev->config, PCI_CLASS_DISPLAY_OTHER);
     return qxl_init_common(qxl);
 }
 
@@ -1493,6 +1490,8 @@ static PCIDeviceInfo qxl_info_primary = {
     .init         = qxl_init_primary,
     .config_write = qxl_write_config,
     .romfile      = "vgabios-qxl.bin",
+    .vendor_id    = REDHAT_PCI_VENDOR_ID,
+    .class_id     = PCI_CLASS_DISPLAY_VGA,
     .qdev.props = (Property[]) {
         DEFINE_PROP_UINT32("ram_size", PCIQXLDevice, vga.vram_size, 64 * 1024 * 1024),
         DEFINE_PROP_UINT32("vram_size", PCIQXLDevice, vram_size, 64 * 1024 * 1024),
@@ -1511,6 +1510,8 @@ static PCIDeviceInfo qxl_info_secondary = {
     .qdev.reset   = qxl_reset_handler,
     .qdev.vmsd    = &qxl_vmstate,
     .init         = qxl_init_secondary,
+    .vendor_id    = REDHAT_PCI_VENDOR_ID,
+    .class_id     = PCI_CLASS_DISPLAY_OTHER,
     .qdev.props = (Property[]) {
         DEFINE_PROP_UINT32("ram_size", PCIQXLDevice, vga.vram_size, 64 * 1024 * 1024),
         DEFINE_PROP_UINT32("vram_size", PCIQXLDevice, vram_size, 64 * 1024 * 1024),
commit 3a9d85491ed2be8158fe93041dcbb34c13dfdb05
Author: Isaku Yamahata <yamahata at valinux.co.jp>
Date:   Wed May 25 10:58:23 2011 +0900

    hw/piix_pci.c: convert to PCIDeviceInfo to initialize ids
    
    use PCIDeviceInfo to initialize ids.
    
    Signed-off-by: Isaku Yamahata <yamahata at valinux.co.jp>
    Signed-off-by: Michael S. Tsirkin <mst at redhat.com>

diff --git a/hw/piix_pci.c b/hw/piix_pci.c
index 5f0d92f..b927f01 100644
--- a/hw/piix_pci.c
+++ b/hw/piix_pci.c
@@ -228,11 +228,6 @@ static int i440fx_initfn(PCIDevice *dev)
 {
     PCII440FXState *d = DO_UPCAST(PCII440FXState, dev, dev);
 
-    pci_config_set_vendor_id(d->dev.config, PCI_VENDOR_ID_INTEL);
-    pci_config_set_device_id(d->dev.config, PCI_DEVICE_ID_INTEL_82441);
-    d->dev.config[0x08] = 0x02; // revision
-    pci_config_set_class(d->dev.config, PCI_CLASS_BRIDGE_HOST);
-
     d->dev.config[I440FX_SMRAM] = 0x02;
 
     cpu_smm_register(&i440fx_set_smm, d);
@@ -406,15 +401,8 @@ static const VMStateDescription vmstate_piix3 = {
 static int piix3_initfn(PCIDevice *dev)
 {
     PIIX3State *d = DO_UPCAST(PIIX3State, dev, dev);
-    uint8_t *pci_conf;
 
     isa_bus_new(&d->dev.qdev);
-
-    pci_conf = d->dev.config;
-    pci_config_set_vendor_id(pci_conf, PCI_VENDOR_ID_INTEL);
-    pci_config_set_device_id(pci_conf, PCI_DEVICE_ID_INTEL_82371SB_0); // 82371SB PIIX3 PCI-to-ISA bridge (Step A1)
-    pci_config_set_class(pci_conf, PCI_CLASS_BRIDGE_ISA);
-
     qemu_register_reset(piix3_reset, d);
     return 0;
 }
@@ -429,6 +417,10 @@ static PCIDeviceInfo i440fx_info[] = {
         .no_hotplug   = 1,
         .init         = i440fx_initfn,
         .config_write = i440fx_write_config,
+        .vendor_id    = PCI_VENDOR_ID_INTEL,
+        .device_id    = PCI_DEVICE_ID_INTEL_82441,
+        .revision     = 0x02,
+        .class_id     = PCI_CLASS_BRIDGE_HOST,
     },{
         .qdev.name    = "PIIX3",
         .qdev.desc    = "ISA bridge",
@@ -438,6 +430,9 @@ static PCIDeviceInfo i440fx_info[] = {
         .no_hotplug   = 1,
         .init         = piix3_initfn,
         .config_write = piix3_write_config,
+        .vendor_id    = PCI_VENDOR_ID_INTEL,
+        .device_id    = PCI_DEVICE_ID_INTEL_82371SB_0, // 82371SB PIIX3 PCI-to-ISA bridge (Step A1)
+        .class_id     = PCI_CLASS_BRIDGE_ISA,
     },{
         /* end of list */
     }
commit 146beee5d9f94d96ab3bf54ac355a263290b75ac
Author: Isaku Yamahata <yamahata at valinux.co.jp>
Date:   Wed May 25 10:58:22 2011 +0900

    hw/piix4.c: convert to PCIDeviceInfo to initialize ids
    
    use PCIDeviceInfo to initialize ids.
    
    Signed-off-by: Isaku Yamahata <yamahata at valinux.co.jp>
    Signed-off-by: Michael S. Tsirkin <mst at redhat.com>

diff --git a/hw/piix4.c b/hw/piix4.c
index 71f1f84..9590e7b 100644
--- a/hw/piix4.c
+++ b/hw/piix4.c
@@ -86,15 +86,8 @@ static const VMStateDescription vmstate_piix4 = {
 static int piix4_initfn(PCIDevice *dev)
 {
     PIIX4State *d = DO_UPCAST(PIIX4State, dev, dev);
-    uint8_t *pci_conf;
 
     isa_bus_new(&d->dev.qdev);
-
-    pci_conf = d->dev.config;
-    pci_config_set_vendor_id(pci_conf, PCI_VENDOR_ID_INTEL);
-    pci_config_set_device_id(pci_conf, PCI_DEVICE_ID_INTEL_82371AB_0); // 82371AB/EB/MB PIIX4 PCI-to-ISA bridge
-    pci_config_set_class(pci_conf, PCI_CLASS_BRIDGE_ISA);
-
     piix4_dev = &d->dev;
     qemu_register_reset(piix4_reset, d);
     return 0;
@@ -117,6 +110,9 @@ static PCIDeviceInfo piix4_info[] = {
         .qdev.no_user = 1,
         .no_hotplug   = 1,
         .init         = piix4_initfn,
+        .vendor_id    = PCI_VENDOR_ID_INTEL,
+        .device_id    = PCI_DEVICE_ID_INTEL_82371AB_0, // 82371AB/EB/MB PIIX4 PCI-to-ISA bridge
+        .class_id     = PCI_CLASS_BRIDGE_ISA,
     },{
         /* end of list */
     }
commit d7dccd11683d17e4658606349544312a0769ecea
Author: Isaku Yamahata <yamahata at valinux.co.jp>
Date:   Wed May 25 10:58:21 2011 +0900

    hw/pcnet-pci.c: convert to PCIDeviceInfo to initialize ids
    
    use PCIDeviceInfo to initialize ids.
    
    Signed-off-by: Isaku Yamahata <yamahata at valinux.co.jp>
    Signed-off-by: Michael S. Tsirkin <mst at redhat.com>

diff --git a/hw/pcnet-pci.c b/hw/pcnet-pci.c
index 9415a1e..216cf81 100644
--- a/hw/pcnet-pci.c
+++ b/hw/pcnet-pci.c
@@ -265,12 +265,8 @@ static int pci_pcnet_init(PCIDevice *pci_dev)
 
     pci_conf = pci_dev->config;
 
-    pci_config_set_vendor_id(pci_conf, PCI_VENDOR_ID_AMD);
-    pci_config_set_device_id(pci_conf, PCI_DEVICE_ID_AMD_LANCE);
     pci_set_word(pci_conf + PCI_STATUS,
                  PCI_STATUS_FAST_BACK | PCI_STATUS_DEVSEL_MEDIUM);
-    pci_conf[PCI_REVISION_ID] = 0x10;
-    pci_config_set_class(pci_conf, PCI_CLASS_NETWORK_ETHERNET);
 
     pci_set_word(pci_conf + PCI_SUBSYSTEM_VENDOR_ID, 0x0);
     pci_set_word(pci_conf + PCI_SUBSYSTEM_ID, 0x0);
@@ -318,6 +314,10 @@ static PCIDeviceInfo pcnet_info = {
     .qdev.vmsd  = &vmstate_pci_pcnet,
     .init       = pci_pcnet_init,
     .exit       = pci_pcnet_uninit,
+    .vendor_id  = PCI_VENDOR_ID_AMD,
+    .device_id  = PCI_DEVICE_ID_AMD_LANCE,
+    .revision   = 0x10,
+    .class_id   = PCI_CLASS_NETWORK_ETHERNET,
     .qdev.props = (Property[]) {
         DEFINE_NIC_PROPERTIES(PCIPCNetState, state.conf),
         DEFINE_PROP_END_OF_LIST(),
commit 18f1c729b88eb7f0f408332132b85dc896bfb145
Author: Isaku Yamahata <yamahata at valinux.co.jp>
Date:   Wed May 25 10:58:20 2011 +0900

    hw/ne2000.c: convert to PCIDeviceInfo to initialize ids
    
    use PCIDeviceInfo to initialize ids.
    
    Signed-off-by: Isaku Yamahata <yamahata at valinux.co.jp>
    Signed-off-by: Michael S. Tsirkin <mst at redhat.com>

diff --git a/hw/ne2000.c b/hw/ne2000.c
index b668ad1..f8acaae 100644
--- a/hw/ne2000.c
+++ b/hw/ne2000.c
@@ -721,9 +721,6 @@ static int pci_ne2000_init(PCIDevice *pci_dev)
     uint8_t *pci_conf;
 
     pci_conf = d->dev.config;
-    pci_config_set_vendor_id(pci_conf, PCI_VENDOR_ID_REALTEK);
-    pci_config_set_device_id(pci_conf, PCI_DEVICE_ID_REALTEK_8029);
-    pci_config_set_class(pci_conf, PCI_CLASS_NETWORK_ETHERNET);
     /* TODO: RST# value should be 0. PCI spec 6.2.4 */
     pci_conf[PCI_INTERRUPT_PIN] = 1; // interrupt pin 0
 
@@ -767,6 +764,9 @@ static PCIDeviceInfo ne2000_info = {
     .qdev.vmsd  = &vmstate_pci_ne2000,
     .init       = pci_ne2000_init,
     .exit       = pci_ne2000_exit,
+    .vendor_id  = PCI_VENDOR_ID_REALTEK,
+    .device_id  = PCI_DEVICE_ID_REALTEK_8029,
+    .class_id   = PCI_CLASS_NETWORK_ETHERNET,
     .qdev.props = (Property[]) {
         DEFINE_NIC_PROPERTIES(PCINE2000State, ne2000.c),
         DEFINE_PROP_END_OF_LIST(),
commit af5374aa044af8ebc5a7dd387ea0dec48b5d956b
Author: Isaku Yamahata <yamahata at valinux.co.jp>
Date:   Wed May 25 10:58:19 2011 +0900

    hw/lsi53c895a.c: convert to PCIDeviceInfo to initialize ids
    
    use PCIDeviceInfo to initialize ids.
    
    Signed-off-by: Isaku Yamahata <yamahata at valinux.co.jp>
    Signed-off-by: Michael S. Tsirkin <mst at redhat.com>

diff --git a/hw/lsi53c895a.c b/hw/lsi53c895a.c
index be4df58..6b9c904 100644
--- a/hw/lsi53c895a.c
+++ b/hw/lsi53c895a.c
@@ -2212,15 +2212,6 @@ static int lsi_scsi_init(PCIDevice *dev)
 
     pci_conf = s->dev.config;
 
-    /* PCI Vendor ID (word) */
-    pci_config_set_vendor_id(pci_conf, PCI_VENDOR_ID_LSI_LOGIC);
-    /* PCI device ID (word) */
-    pci_config_set_device_id(pci_conf, PCI_DEVICE_ID_LSI_53C895A);
-    /* PCI base class code */
-    pci_config_set_class(pci_conf, PCI_CLASS_STORAGE_SCSI);
-    /* PCI subsystem ID */
-    pci_conf[PCI_SUBSYSTEM_ID] = 0x00;
-    pci_conf[PCI_SUBSYSTEM_ID + 1] = 0x10;
     /* PCI latency timer = 255 */
     pci_conf[PCI_LATENCY_TIMER] = 0xff;
     /* TODO: RST# value should be 0 */
@@ -2256,6 +2247,10 @@ static PCIDeviceInfo lsi_info = {
     .qdev.vmsd  = &vmstate_lsi_scsi,
     .init       = lsi_scsi_init,
     .exit       = lsi_scsi_uninit,
+    .vendor_id  = PCI_VENDOR_ID_LSI_LOGIC,
+    .device_id  = PCI_DEVICE_ID_LSI_53C895A,
+    .class_id   = PCI_CLASS_STORAGE_SCSI,
+    .subsystem_id = 0x1000,
 };
 
 static void lsi53c895a_register_devices(void)
commit 7aff0f218cf623fbc4e2fe86c3ed8985ca3f2a9a
Author: Isaku Yamahata <yamahata at valinux.co.jp>
Date:   Wed May 25 10:58:18 2011 +0900

    hw/ivshmem.c: convert to PCIDeviceInfo to initialize ids
    
    use PCIDeviceInfo to initialize ids.
    
    Signed-off-by: Isaku Yamahata <yamahata at valinux.co.jp>
    Signed-off-by: Michael S. Tsirkin <mst at redhat.com>

diff --git a/hw/ivshmem.c b/hw/ivshmem.c
index 7b19a81..3055dd2 100644
--- a/hw/ivshmem.c
+++ b/hw/ivshmem.c
@@ -706,12 +706,7 @@ static int pci_ivshmem_init(PCIDevice *dev)
     }
 
     pci_conf = s->dev.config;
-    pci_config_set_vendor_id(pci_conf, PCI_VENDOR_ID_REDHAT_QUMRANET);
-    pci_conf[0x02] = 0x10;
-    pci_conf[0x03] = 0x11;
     pci_conf[PCI_COMMAND] = PCI_COMMAND_IO | PCI_COMMAND_MEMORY;
-    pci_config_set_class(pci_conf, PCI_CLASS_MEMORY_RAM);
-    pci_conf[PCI_HEADER_TYPE] = PCI_HEADER_TYPE_NORMAL;
 
     pci_config_set_interrupt_pin(pci_conf, 1);
 
@@ -809,6 +804,9 @@ static PCIDeviceInfo ivshmem_info = {
     .qdev.reset = ivshmem_reset,
     .init       = pci_ivshmem_init,
     .exit       = pci_ivshmem_uninit,
+    .vendor_id  = PCI_VENDOR_ID_REDHAT_QUMRANET,
+    .device_id  = 0x1110,
+    .class_id   = PCI_CLASS_MEMORY_RAM,
     .qdev.props = (Property[]) {
         DEFINE_PROP_CHR("chardev", IVShmemState, server_chr),
         DEFINE_PROP_STRING("size", IVShmemState, sizearg),
commit 3d0b1e704bd808b3daafb723c7264e2015120bee
Author: Isaku Yamahata <yamahata at valinux.co.jp>
Date:   Wed May 25 10:58:17 2011 +0900

    hw/ioh3420.c: convert to PCIDeviceInfo to initialize ids
    
    use PCIDeviceInfo to initialize ids.
    
    Signed-off-by: Isaku Yamahata <yamahata at valinux.co.jp>
    Signed-off-by: Michael S. Tsirkin <mst at redhat.com>

diff --git a/hw/ioh3420.c b/hw/ioh3420.c
index 95adf09..a6bfbb9 100644
--- a/hw/ioh3420.c
+++ b/hw/ioh3420.c
@@ -104,12 +104,8 @@ static int ioh3420_initfn(PCIDevice *d)
         return rc;
     }
 
-    d->config[PCI_REVISION_ID] = PCI_DEVICE_ID_IOH_REV;
     pcie_port_init_reg(d);
 
-    pci_config_set_vendor_id(d->config, PCI_VENDOR_ID_INTEL);
-    pci_config_set_device_id(d->config, PCI_DEVICE_ID_IOH_EPORT);
-
     rc = pci_bridge_ssvid_init(d, IOH_EP_SSVID_OFFSET,
                                IOH_EP_SSVID_SVID, IOH_EP_SSVID_SSID);
     if (rc < 0) {
@@ -217,6 +213,9 @@ static PCIDeviceInfo ioh3420_info = {
     .config_write = ioh3420_write_config,
     .init = ioh3420_initfn,
     .exit = ioh3420_exitfn,
+    .vendor_id = PCI_VENDOR_ID_INTEL,
+    .device_id = PCI_DEVICE_ID_IOH_EPORT,
+    .revision = PCI_DEVICE_ID_IOH_REV,
 
     .qdev.props = (Property[]) {
         DEFINE_PROP_UINT8("port", PCIESlot, port.port, 0),
commit d15fda639ba356148fc7161bba863866fd2797ef
Author: Isaku Yamahata <yamahata at valinux.co.jp>
Date:   Wed May 25 10:58:16 2011 +0900

    hw/intel-hda.c: convert to PCIDeviceInfo to initialize ids
    
    use PCIDeviceInfo to initialize ids.
    
    Signed-off-by: Isaku Yamahata <yamahata at valinux.co.jp>
    Signed-off-by: Michael S. Tsirkin <mst at redhat.com>

diff --git a/hw/intel-hda.c b/hw/intel-hda.c
index 5485745..0ffffce 100644
--- a/hw/intel-hda.c
+++ b/hw/intel-hda.c
@@ -1138,10 +1138,6 @@ static int intel_hda_init(PCIDevice *pci)
 
     d->name = d->pci.qdev.info->name;
 
-    pci_config_set_vendor_id(conf, PCI_VENDOR_ID_INTEL);
-    pci_config_set_device_id(conf, 0x2668);
-    pci_config_set_revision(conf, 1);
-    pci_config_set_class(conf, PCI_CLASS_MULTIMEDIA_HD_AUDIO);
     pci_config_set_interrupt_pin(conf, 1);
 
     /* HDCTL off 0x40 bit 0 selects signaling mode (1-HDA, 0 - Ac97) 18.1.19 */
@@ -1265,6 +1261,10 @@ static PCIDeviceInfo intel_hda_info = {
     .init         = intel_hda_init,
     .exit         = intel_hda_exit,
     .config_write = intel_hda_write_config,
+    .vendor_id    = PCI_VENDOR_ID_INTEL,
+    .device_id    = 0x2668,
+    .revision     = 1,
+    .class_id     = PCI_CLASS_MULTIMEDIA_HD_AUDIO,
     .qdev.props   = (Property[]) {
         DEFINE_PROP_UINT32("debug", IntelHDAState, debug, 0),
         DEFINE_PROP_UINT32("msi", IntelHDAState, msi, 1),
commit 65ff544b41c4e097d49a0c81b97cb2f9f9b039b8
Author: Isaku Yamahata <yamahata at valinux.co.jp>
Date:   Wed May 25 10:58:15 2011 +0900

    hw/ide/via.c: convert to PCIDeviceInfo to initialize ids
    
    use PCIDeviceInfo to initialize ids.
    
    Signed-off-by: Isaku Yamahata <yamahata at valinux.co.jp>
    Signed-off-by: Michael S. Tsirkin <mst at redhat.com>

diff --git a/hw/ide/via.c b/hw/ide/via.c
index 04f3290..3474c37 100644
--- a/hw/ide/via.c
+++ b/hw/ide/via.c
@@ -160,11 +160,7 @@ static int vt82c686b_ide_initfn(PCIDevice *dev)
     PCIIDEState *d = DO_UPCAST(PCIIDEState, dev, dev);;
     uint8_t *pci_conf = d->dev.config;
 
-    pci_config_set_vendor_id(pci_conf, PCI_VENDOR_ID_VIA);
-    pci_config_set_device_id(pci_conf, PCI_DEVICE_ID_VIA_IDE);
-    pci_config_set_class(pci_conf, PCI_CLASS_STORAGE_IDE);
     pci_config_set_prog_interface(pci_conf, 0x8a); /* legacy ATA mode */
-    pci_config_set_revision(pci_conf,0x06); /* Revision 0.6 */
     pci_set_long(pci_conf + PCI_CAPABILITY_LIST, 0x000000c0);
 
     qemu_register_reset(via_reset, d);
@@ -191,6 +187,10 @@ static PCIDeviceInfo via_ide_info = {
     .qdev.size    = sizeof(PCIIDEState),
     .qdev.no_user = 1,
     .init         = vt82c686b_ide_initfn,
+    .vendor_id    = PCI_VENDOR_ID_VIA,
+    .device_id    = PCI_DEVICE_ID_VIA_IDE,
+    .revision     = 0x06,
+    .class_id     = PCI_CLASS_STORAGE_IDE,
 };
 
 static void via_ide_register(void)
commit 03f1c14379d74b0c76a368681843c7c47c1e0627
Author: Isaku Yamahata <yamahata at valinux.co.jp>
Date:   Wed May 25 10:58:14 2011 +0900

    hw/ide/ich.c: convert to PCIDeviceInfo to initialize ids
    
    use PCIDeviceInfo to initialize ids.
    
    Signed-off-by: Isaku Yamahata <yamahata at valinux.co.jp>
    Signed-off-by: Michael S. Tsirkin <mst at redhat.com>

diff --git a/hw/ide/ich.c b/hw/ide/ich.c
index 5ce0a88..976cc92 100644
--- a/hw/ide/ich.c
+++ b/hw/ide/ich.c
@@ -79,11 +79,6 @@ static int pci_ich9_ahci_init(PCIDevice *dev)
 
     ahci_init(&d->ahci, &dev->qdev, 6);
 
-    pci_config_set_vendor_id(d->card.config, PCI_VENDOR_ID_INTEL);
-    pci_config_set_device_id(d->card.config, PCI_DEVICE_ID_INTEL_82801IR);
-
-    pci_config_set_class(d->card.config, PCI_CLASS_STORAGE_SATA);
-    pci_config_set_revision(d->card.config, 0x02);
     pci_config_set_prog_interface(d->card.config, AHCI_PROGMODE_MAJOR_REV_1);
 
     d->card.config[PCI_CACHE_LINE_SIZE] = 0x08;  /* Cache line size */
@@ -131,6 +126,10 @@ static PCIDeviceInfo ich_ahci_info[] = {
         .init         = pci_ich9_ahci_init,
         .exit         = pci_ich9_uninit,
         .config_write = pci_ich9_write_config,
+        .vendor_id    = PCI_VENDOR_ID_INTEL,
+        .device_id    = PCI_DEVICE_ID_INTEL_82801IR,
+        .revision     = 0x02,
+        .class_id     = PCI_CLASS_STORAGE_SATA,
     },{
         /* end of list */
     }
commit c04ca0756da8087e15579915d55fdca816c9ef4e
Author: Isaku Yamahata <yamahata at valinux.co.jp>
Date:   Wed May 25 10:58:13 2011 +0900

    hw/ide/cmd646.c: convert to PCIDeviceInfo to initialize ids
    
    use PCIDeviceInfo to initialize ids.
    
    Signed-off-by: Isaku Yamahata <yamahata at valinux.co.jp>
    Signed-off-by: Michael S. Tsirkin <mst at redhat.com>

diff --git a/hw/ide/cmd646.c b/hw/ide/cmd646.c
index 5d5464a..56302b5 100644
--- a/hw/ide/cmd646.c
+++ b/hw/ide/cmd646.c
@@ -226,14 +226,8 @@ static int pci_cmd646_ide_initfn(PCIDevice *dev)
     qemu_irq *irq;
     int i;
 
-    pci_config_set_vendor_id(pci_conf, PCI_VENDOR_ID_CMD);
-    pci_config_set_device_id(pci_conf, PCI_DEVICE_ID_CMD_646);
-
-    pci_conf[PCI_REVISION_ID] = 0x07; // IDE controller revision
     pci_conf[PCI_CLASS_PROG] = 0x8f;
 
-    pci_config_set_class(pci_conf, PCI_CLASS_STORAGE_IDE);
-
     pci_conf[0x51] = 0x04; // enable IDE0
     if (d->secondary) {
         /* XXX: if not enabled, really disable the seconday IDE controller */
@@ -282,6 +276,10 @@ static PCIDeviceInfo cmd646_ide_info[] = {
         .qdev.name    = "cmd646-ide",
         .qdev.size    = sizeof(PCIIDEState),
         .init         = pci_cmd646_ide_initfn,
+        .vendor_id    = PCI_VENDOR_ID_CMD,
+        .device_id    = PCI_DEVICE_ID_CMD_646,
+        .revision     = 0x07, // IDE controller revision
+        .class_id     = PCI_CLASS_STORAGE_IDE,
         .qdev.props   = (Property[]) {
             DEFINE_PROP_UINT32("secondary", PCIIDEState, secondary, 0),
             DEFINE_PROP_END_OF_LIST(),
commit 231f5f43dc8ee40c86b00473df67226721d00832
Author: Isaku Yamahata <yamahata at valinux.co.jp>
Date:   Wed May 25 10:58:12 2011 +0900

    hw/gt64xxx.c: convert to PCIDeviceInfo to initialize ids
    
    use PCIDeviceInfo to initialize ids.
    
    Signed-off-by: Isaku Yamahata <yamahata at valinux.co.jp>
    Signed-off-by: Michael S. Tsirkin <mst at redhat.com>

diff --git a/hw/gt64xxx.c b/hw/gt64xxx.c
index c66188f..8e1f6a0 100644
--- a/hw/gt64xxx.c
+++ b/hw/gt64xxx.c
@@ -1118,14 +1118,10 @@ static int gt64120_init(SysBusDevice *dev)
 static int gt64120_pci_init(PCIDevice *d)
 {
     /* FIXME: Malta specific hw assumptions ahead */
-    pci_config_set_vendor_id(d->config, PCI_VENDOR_ID_MARVELL);
-    pci_config_set_device_id(d->config, PCI_DEVICE_ID_MARVELL_GT6412X);
     pci_set_word(d->config + PCI_COMMAND, 0);
     pci_set_word(d->config + PCI_STATUS,
                  PCI_STATUS_FAST_BACK | PCI_STATUS_DEVSEL_MEDIUM);
-    pci_set_byte(d->config + PCI_CLASS_REVISION, 0x10);
     pci_config_set_prog_interface(d->config, 0);
-    pci_config_set_class(d->config, PCI_CLASS_BRIDGE_HOST);
     pci_set_long(d->config + PCI_BASE_ADDRESS_0, 0x00000008);
     pci_set_long(d->config + PCI_BASE_ADDRESS_1, 0x01000008);
     pci_set_long(d->config + PCI_BASE_ADDRESS_2, 0x1c000000);
@@ -1141,6 +1137,10 @@ static PCIDeviceInfo gt64120_pci_info = {
     .qdev.name = "gt64120_pci",
     .qdev.size = sizeof(PCIDevice),
     .init      = gt64120_pci_init,
+    .vendor_id = PCI_VENDOR_ID_MARVELL,
+    .device_id = PCI_DEVICE_ID_MARVELL_GT6412X,
+    .revision  = 0x10,
+    .class_id  = PCI_CLASS_BRIDGE_HOST,
 };
 
 static void gt64120_pci_register_devices(void)
commit a614f52dc70fd4c424a6248ae98c42494b9a89e7
Author: Isaku Yamahata <yamahata at valinux.co.jp>
Date:   Wed May 25 10:58:11 2011 +0900

    hw/grackle_pci.c: convert to PCIDeviceInfo to initialize ids
    
    use PCIDeviceInfo to initialize ids.
    
    Signed-off-by: Isaku Yamahata <yamahata at valinux.co.jp>
    Signed-off-by: Michael S. Tsirkin <mst at redhat.com>

diff --git a/hw/grackle_pci.c b/hw/grackle_pci.c
index d35701f..cee07e0 100644
--- a/hw/grackle_pci.c
+++ b/hw/grackle_pci.c
@@ -104,11 +104,7 @@ static int pci_grackle_init_device(SysBusDevice *dev)
 
 static int grackle_pci_host_init(PCIDevice *d)
 {
-    pci_config_set_vendor_id(d->config, PCI_VENDOR_ID_MOTOROLA);
-    pci_config_set_device_id(d->config, PCI_DEVICE_ID_MOTOROLA_MPC106);
-    d->config[0x08] = 0x00; // revision
     d->config[0x09] = 0x01;
-    pci_config_set_class(d->config, PCI_CLASS_BRIDGE_HOST);
     return 0;
 }
 
@@ -116,6 +112,10 @@ static PCIDeviceInfo grackle_pci_host_info = {
     .qdev.name = "grackle",
     .qdev.size = sizeof(PCIDevice),
     .init      = grackle_pci_host_init,
+    .vendor_id = PCI_VENDOR_ID_MOTOROLA,
+    .device_id = PCI_DEVICE_ID_MOTOROLA_MPC106,
+    .revision  = 0x00,
+    .class_id  = PCI_CLASS_BRIDGE_HOST,
 };
 
 static void grackle_register_devices(void)
commit 0b8c537fd2fcbd9fa7dd2559c9d4110393d91107
Author: Isaku Yamahata <yamahata at valinux.co.jp>
Date:   Wed May 25 10:58:10 2011 +0900

    hw/es1370.c: convert to PCIDeviceInfo to initialize ids
    
    use PCIDeviceInfo to initialize ids.
    
    Signed-off-by: Isaku Yamahata <yamahata at valinux.co.jp>
    Signed-off-by: Michael S. Tsirkin <mst at redhat.com>

diff --git a/hw/es1370.c b/hw/es1370.c
index 40cb48c..1ed62b7 100644
--- a/hw/es1370.c
+++ b/hw/es1370.c
@@ -998,21 +998,9 @@ static int es1370_initfn (PCIDevice *dev)
     ES1370State *s = DO_UPCAST (ES1370State, dev, dev);
     uint8_t *c = s->dev.config;
 
-    pci_config_set_vendor_id (c, PCI_VENDOR_ID_ENSONIQ);
-    pci_config_set_device_id (c, PCI_DEVICE_ID_ENSONIQ_ES1370);
     c[PCI_STATUS + 1] = PCI_STATUS_DEVSEL_SLOW >> 8;
-    pci_config_set_class (c, PCI_CLASS_MULTIMEDIA_AUDIO);
 
-#if 1
-    c[PCI_SUBSYSTEM_VENDOR_ID] = 0x42;
-    c[PCI_SUBSYSTEM_VENDOR_ID + 1] = 0x49;
-    c[PCI_SUBSYSTEM_ID] = 0x4c;
-    c[PCI_SUBSYSTEM_ID + 1] = 0x4c;
-#else
-    c[PCI_SUBSYSTEM_VENDOR_ID] = 0x74;
-    c[PCI_SUBSYSTEM_VENDOR_ID + 1] = 0x12;
-    c[PCI_SUBSYSTEM_ID] = 0x71;
-    c[PCI_SUBSYSTEM_ID + 1] = 0x13;
+#if 0
     c[PCI_CAPABILITY_LIST] = 0xdc;
     c[PCI_INTERRUPT_LINE] = 10;
     c[0xdc] = 0x00;
@@ -1043,6 +1031,16 @@ static PCIDeviceInfo es1370_info = {
     .qdev.size    = sizeof (ES1370State),
     .qdev.vmsd    = &vmstate_es1370,
     .init         = es1370_initfn,
+    .vendor_id    = PCI_VENDOR_ID_ENSONIQ,
+    .device_id    = PCI_DEVICE_ID_ENSONIQ_ES1370,
+    .class_id     = PCI_CLASS_MULTIMEDIA_AUDIO,
+#if 1
+    .subsystem_vendor_id = 0x4942,
+    .subsystem_id = 0x4c4c,
+#else
+    .subsystem_vendor_id = 0x1274,
+    .subsystem_id = 0x1371,
+#endif
 };
 
 static void es1370_register (void)
commit e72d5c9d1876baada0645bc69137987d5ba8db2d
Author: Isaku Yamahata <yamahata at valinux.co.jp>
Date:   Wed May 25 10:58:09 2011 +0900

    hw/e1000.c: convert to PCIDeviceInfo to initialize ids
    
    use PCIDeviceInfo to initialize ids.
    
    Signed-off-by: Isaku Yamahata <yamahata at valinux.co.jp>
    Signed-off-by: Michael S. Tsirkin <mst at redhat.com>

diff --git a/hw/e1000.c b/hw/e1000.c
index f160bfc..96d84f9 100644
--- a/hw/e1000.c
+++ b/hw/e1000.c
@@ -1164,12 +1164,8 @@ static int pci_e1000_init(PCIDevice *pci_dev)
 
     pci_conf = d->dev.config;
 
-    pci_config_set_vendor_id(pci_conf, PCI_VENDOR_ID_INTEL);
-    pci_config_set_device_id(pci_conf, E1000_DEVID);
     /* TODO: we have no capabilities, so why is this bit set? */
     pci_set_word(pci_conf + PCI_STATUS, PCI_STATUS_CAP_LIST);
-    pci_conf[PCI_REVISION_ID] = 0x03;
-    pci_config_set_class(pci_conf, PCI_CLASS_NETWORK_ETHERNET);
     /* TODO: RST# value should be 0, PCI spec 6.2.4 */
     pci_conf[PCI_CACHE_LINE_SIZE] = 0x10;
 
@@ -1221,6 +1217,10 @@ static PCIDeviceInfo e1000_info = {
     .init       = pci_e1000_init,
     .exit       = pci_e1000_uninit,
     .romfile    = "pxe-e1000.rom",
+    .vendor_id  = PCI_VENDOR_ID_INTEL,
+    .device_id  = E1000_DEVID,
+    .revision   = 0x03,
+    .class_id   = PCI_CLASS_NETWORK_ETHERNET,
     .qdev.props = (Property[]) {
         DEFINE_NIC_PROPERTIES(E1000State, conf),
         DEFINE_PROP_END_OF_LIST(),
commit 5b96d8f997897bdef1ea41529689b418e3bcbec1
Author: Isaku Yamahata <yamahata at valinux.co.jp>
Date:   Wed May 25 10:58:08 2011 +0900

    hw/cirrus_vga.c: convert to PCIDeviceInfo to initialize ids
    
    use PCIDeviceInfo to initialize ids.
    
    Signed-off-by: Isaku Yamahata <yamahata at valinux.co.jp>
    Signed-off-by: Michael S. Tsirkin <mst at redhat.com>

diff --git a/hw/cirrus_vga.c b/hw/cirrus_vga.c
index 722cac7..79874b1 100644
--- a/hw/cirrus_vga.c
+++ b/hw/cirrus_vga.c
@@ -3097,8 +3097,8 @@ static int pci_cirrus_vga_initfn(PCIDevice *dev)
 {
      PCICirrusVGAState *d = DO_UPCAST(PCICirrusVGAState, dev, dev);
      CirrusVGAState *s = &d->cirrus_vga;
-     uint8_t *pci_conf = d->dev.config;
-     int device_id = CIRRUS_ID_CLGD5446;
+     PCIDeviceInfo *info = DO_UPCAST(PCIDeviceInfo, qdev, dev->qdev.info);
+     int16_t device_id = info->device_id;
 
      /* setup VGA */
      vga_common_init(&s->vga, VGA_RAM_SIZE);
@@ -3108,9 +3108,6 @@ static int pci_cirrus_vga_initfn(PCIDevice *dev)
                                       &s->vga);
 
      /* setup PCI */
-     pci_config_set_vendor_id(pci_conf, PCI_VENDOR_ID_CIRRUS);
-     pci_config_set_device_id(pci_conf, device_id);
-     pci_config_set_class(pci_conf, PCI_CLASS_DISPLAY_VGA);
 
      /* setup memory space */
      /* memory #0 LFB */
@@ -3139,6 +3136,9 @@ static PCIDeviceInfo cirrus_vga_info = {
     .init         = pci_cirrus_vga_initfn,
     .romfile      = VGABIOS_CIRRUS_FILENAME,
     .config_write = pci_cirrus_write_config,
+    .vendor_id    = PCI_VENDOR_ID_CIRRUS,
+    .device_id    = CIRRUS_ID_CLGD5446,
+    .class_id     = PCI_CLASS_DISPLAY_VGA,
 };
 
 static void cirrus_vga_register(void)
commit 51387f864c7421aba07b5b445cd7835bbc496a07
Author: Isaku Yamahata <yamahata at valinux.co.jp>
Date:   Wed May 25 10:58:07 2011 +0900

    hw/bonito.c: convert to PCIDeviceInfo to initialize ids
    
    use PCIDeviceInfo to initialize ids.
    
    Signed-off-by: Isaku Yamahata <yamahata at valinux.co.jp>
    Signed-off-by: Michael S. Tsirkin <mst at redhat.com>

diff --git a/hw/bonito.c b/hw/bonito.c
index 65a4a63..e8c57a3 100644
--- a/hw/bonito.c
+++ b/hw/bonito.c
@@ -691,11 +691,7 @@ static int bonito_initfn(PCIDevice *dev)
     PCIBonitoState *s = DO_UPCAST(PCIBonitoState, dev, dev);
 
     /* Bonito North Bridge, built on FPGA, VENDOR_ID/DEVICE_ID are "undefined" */
-    pci_config_set_vendor_id(dev->config, 0xdf53);
-    pci_config_set_device_id(dev->config, 0x00d5);
-    pci_config_set_class(dev->config, PCI_CLASS_BRIDGE_HOST);
     pci_config_set_prog_interface(dev->config, 0x00);
-    pci_config_set_revision(dev->config, 0x01);
 
     /* set the north bridge register mapping */
     s->bonito_reg_handle = cpu_register_io_memory(bonito_read, bonito_write, s,
@@ -796,6 +792,11 @@ static PCIDeviceInfo bonito_info = {
     .qdev.vmsd    = &vmstate_bonito,
     .qdev.no_user = 1,
     .init         = bonito_initfn,
+    /*Bonito North Bridge, built on FPGA, VENDOR_ID/DEVICE_ID are "undefined"*/
+    .vendor_id    = 0xdf53,
+    .device_id    = 0x00d5,
+    .revision     = 0x01,
+    .class_id     = PCI_CLASS_BRIDGE_HOST,
 };
 
 static SysBusDeviceInfo bonito_pcihost_info = {
commit 580b7295e10d08d3a228ad2b1d5f3f3af9218ec5
Author: Isaku Yamahata <yamahata at valinux.co.jp>
Date:   Wed May 25 10:58:06 2011 +0900

    hw/acpi_piix4.c: convert to PCIDeviceInfo to initialize ids
    
    use PCIDeviceInfo to initialize ids.
    
    Signed-off-by: Isaku Yamahata <yamahata at valinux.co.jp>
    Signed-off-by: Michael S. Tsirkin <mst at redhat.com>

diff --git a/hw/acpi_piix4.c b/hw/acpi_piix4.c
index 96f5222..232008d 100644
--- a/hw/acpi_piix4.c
+++ b/hw/acpi_piix4.c
@@ -317,13 +317,9 @@ static int piix4_pm_initfn(PCIDevice *dev)
     uint8_t *pci_conf;
 
     pci_conf = s->dev.config;
-    pci_config_set_vendor_id(pci_conf, PCI_VENDOR_ID_INTEL);
-    pci_config_set_device_id(pci_conf, PCI_DEVICE_ID_INTEL_82371AB_3);
     pci_conf[0x06] = 0x80;
     pci_conf[0x07] = 0x02;
-    pci_conf[0x08] = 0x03; // revision number
     pci_conf[0x09] = 0x00;
-    pci_config_set_class(pci_conf, PCI_CLASS_BRIDGE_OTHER);
     pci_conf[0x3d] = 0x01; // interrupt pin 1
 
     pci_conf[0x40] = 0x01; /* PM io base read only bit */
@@ -394,6 +390,10 @@ static PCIDeviceInfo piix4_pm_info = {
     .no_hotplug         = 1,
     .init               = piix4_pm_initfn,
     .config_write       = pm_write_config,
+    .vendor_id          = PCI_VENDOR_ID_INTEL,
+    .device_id          = PCI_DEVICE_ID_INTEL_82371AB_3,
+    .revision           = 0x03,
+    .class_id           = PCI_CLASS_BRIDGE_OTHER,
     .qdev.props         = (Property[]) {
         DEFINE_PROP_UINT32("smb_io_base", PIIX4PMState, smb_io_base, 0),
         DEFINE_PROP_END_OF_LIST(),
commit 0647b949a25f49090bfd0e83d8a90c18b4045bb7
Author: Isaku Yamahata <yamahata at valinux.co.jp>
Date:   Wed May 25 10:58:05 2011 +0900

    hw/ac97.c: convert to PCIDeviceInfo to initialize ids
    
    use PCIDeviceInfo to initialize ids.
    
    Signed-off-by: Isaku Yamahata <yamahata at valinux.co.jp>
    Signed-off-by: Michael S. Tsirkin <mst at redhat.com>

diff --git a/hw/ac97.c b/hw/ac97.c
index d71072d..c26a86d 100644
--- a/hw/ac97.c
+++ b/hw/ac97.c
@@ -1281,9 +1281,6 @@ static int ac97_initfn (PCIDevice *dev)
     AC97LinkState *s = DO_UPCAST (AC97LinkState, dev, dev);
     uint8_t *c = s->dev.config;
 
-    pci_config_set_vendor_id (c, PCI_VENDOR_ID_INTEL); /* ro */
-    pci_config_set_device_id (c, PCI_DEVICE_ID_INTEL_82801AA_5); /* ro */
-
     /* TODO: no need to override */
     c[PCI_COMMAND] = 0x00;      /* pcicmd pci command rw, ro */
     c[PCI_COMMAND + 1] = 0x00;
@@ -1292,9 +1289,7 @@ static int ac97_initfn (PCIDevice *dev)
     c[PCI_STATUS] = PCI_STATUS_FAST_BACK;      /* pcists pci status rwc, ro */
     c[PCI_STATUS + 1] = PCI_STATUS_DEVSEL_MEDIUM >> 8;
 
-    c[PCI_REVISION_ID] = 0x01;      /* rid revision ro */
     c[PCI_CLASS_PROG] = 0x00;      /* pi programming interface ro */
-    pci_config_set_class (c, PCI_CLASS_MULTIMEDIA_AUDIO); /* ro */
 
     /* TODO set when bar is registered. no need to override. */
     /* nabmar native audio mixer base address rw */
@@ -1341,6 +1336,10 @@ static PCIDeviceInfo ac97_info = {
     .qdev.size    = sizeof (AC97LinkState),
     .qdev.vmsd    = &vmstate_ac97,
     .init         = ac97_initfn,
+    .vendor_id    = PCI_VENDOR_ID_INTEL,
+    .device_id    = PCI_DEVICE_ID_INTEL_82801AA_5,
+    .revision     = 0x01,
+    .class_id     = PCI_CLASS_MULTIMEDIA_AUDIO,
 };
 
 static void ac97_register (void)
commit 310faaede80a2eb270a021a26183d6afbde81180
Author: Isaku Yamahata <yamahata at valinux.co.jp>
Date:   Wed May 25 10:58:04 2011 +0900

    vmware_vga.c: convert to PCIDeviceInfo to initialize ids
    
    use PCIDeviceInfo to initialize ids.
    
    Signed-off-by: Isaku Yamahata <yamahata at valinux.co.jp>
    Signed-off-by: Michael S. Tsirkin <mst at redhat.com>

diff --git a/hw/vmware_vga.c b/hw/vmware_vga.c
index 4656767..354c221 100644
--- a/hw/vmware_vga.c
+++ b/hw/vmware_vga.c
@@ -1280,15 +1280,8 @@ static int pci_vmsvga_initfn(PCIDevice *dev)
     struct pci_vmsvga_state_s *s =
         DO_UPCAST(struct pci_vmsvga_state_s, card, dev);
 
-    pci_config_set_vendor_id(s->card.config, PCI_VENDOR_ID_VMWARE);
-    pci_config_set_device_id(s->card.config, SVGA_PCI_DEVICE_ID);
-    pci_config_set_class(s->card.config, PCI_CLASS_DISPLAY_VGA);
     s->card.config[PCI_CACHE_LINE_SIZE]	= 0x08;		/* Cache line size */
     s->card.config[PCI_LATENCY_TIMER] = 0x40;		/* Latency timer */
-    s->card.config[PCI_SUBSYSTEM_VENDOR_ID] = PCI_VENDOR_ID_VMWARE & 0xff;
-    s->card.config[PCI_SUBSYSTEM_VENDOR_ID + 1]	= PCI_VENDOR_ID_VMWARE >> 8;
-    s->card.config[PCI_SUBSYSTEM_ID] = SVGA_PCI_DEVICE_ID & 0xff;
-    s->card.config[PCI_SUBSYSTEM_ID + 1] = SVGA_PCI_DEVICE_ID >> 8;
     s->card.config[PCI_INTERRUPT_LINE] = 0xff;		/* End */
 
     pci_register_bar(&s->card, 0, 0x10,
@@ -1316,6 +1309,12 @@ static PCIDeviceInfo vmsvga_info = {
     .no_hotplug   = 1,
     .init         = pci_vmsvga_initfn,
     .romfile      = "vgabios-vmware.bin",
+
+    .vendor_id    =  PCI_VENDOR_ID_VMWARE,
+    .device_id    = SVGA_PCI_DEVICE_ID,
+    .class_id     = PCI_CLASS_DISPLAY_VGA,
+    .subsystem_vendor_id = PCI_VENDOR_ID_VMWARE,
+    .subsystem_id = SVGA_PCI_DEVICE_ID,
 };
 
 static void vmsvga_register(void)
commit 25f8e2f512d87f0a77fc5c0b367dd200a7834d21
Author: Isaku Yamahata <yamahata at valinux.co.jp>
Date:   Wed May 25 10:58:03 2011 +0900

    ide/piix: convert to PCIDeviceInfo to initialize ids
    
    use PCIDeviceInfo to initialize ids.
    
    Signed-off-by: Isaku Yamahata <yamahata at valinux.co.jp>
    Signed-off-by: Michael S. Tsirkin <mst at redhat.com>

diff --git a/hw/ide/piix.c b/hw/ide/piix.c
index c349644..84f72b0 100644
--- a/hw/ide/piix.c
+++ b/hw/ide/piix.c
@@ -131,12 +131,12 @@ static void pci_piix_init_ports(PCIIDEState *d) {
     }
 }
 
-static int pci_piix_ide_initfn(PCIIDEState *d)
+static int pci_piix_ide_initfn(PCIDevice *dev)
 {
+    PCIIDEState *d = DO_UPCAST(PCIIDEState, dev, dev);
     uint8_t *pci_conf = d->dev.config;
 
     pci_conf[PCI_CLASS_PROG] = 0x80; // legacy ATA mode
-    pci_config_set_class(pci_conf, PCI_CLASS_STORAGE_IDE);
 
     qemu_register_reset(piix3_reset, d);
 
@@ -149,24 +149,6 @@ static int pci_piix_ide_initfn(PCIIDEState *d)
     return 0;
 }
 
-static int pci_piix3_ide_initfn(PCIDevice *dev)
-{
-    PCIIDEState *d = DO_UPCAST(PCIIDEState, dev, dev);
-
-    pci_config_set_vendor_id(d->dev.config, PCI_VENDOR_ID_INTEL);
-    pci_config_set_device_id(d->dev.config, PCI_DEVICE_ID_INTEL_82371SB_1);
-    return pci_piix_ide_initfn(d);
-}
-
-static int pci_piix4_ide_initfn(PCIDevice *dev)
-{
-    PCIIDEState *d = DO_UPCAST(PCIIDEState, dev, dev);
-
-    pci_config_set_vendor_id(d->dev.config, PCI_VENDOR_ID_INTEL);
-    pci_config_set_device_id(d->dev.config, PCI_DEVICE_ID_INTEL_82371AB);
-    return pci_piix_ide_initfn(d);
-}
-
 /* hd_table must contain 4 block drivers */
 /* NOTE: for the PIIX3, the IRQs and IOports are hardcoded */
 PCIDevice *pci_piix3_ide_init(PCIBus *bus, DriveInfo **hd_table, int devfn)
@@ -195,13 +177,19 @@ static PCIDeviceInfo piix_ide_info[] = {
         .qdev.size    = sizeof(PCIIDEState),
         .qdev.no_user = 1,
         .no_hotplug   = 1,
-        .init         = pci_piix3_ide_initfn,
+        .init         = pci_piix_ide_initfn,
+        .vendor_id    = PCI_VENDOR_ID_INTEL,
+        .device_id    = PCI_DEVICE_ID_INTEL_82371SB_1,
+        .class_id     = PCI_CLASS_STORAGE_IDE,
     },{
         .qdev.name    = "piix4-ide",
         .qdev.size    = sizeof(PCIIDEState),
         .qdev.no_user = 1,
         .no_hotplug   = 1,
-        .init         = pci_piix4_ide_initfn,
+        .init         = pci_piix_ide_initfn,
+        .vendor_id    = PCI_VENDOR_ID_INTEL,
+        .device_id    = PCI_DEVICE_ID_INTEL_82371AB,
+        .class_id     = PCI_CLASS_STORAGE_IDE,
     },{
         /* end of list */
     }
commit 92f9a4f13ea29de4644bd0b077643e1dff96ab29
Author: Isaku Yamahata <yamahata at valinux.co.jp>
Date:   Wed May 25 10:58:02 2011 +0900

    apb_pci: convert to PCIDeviceInfo to initialize ids
    
    Use PCIDeviceInfo to initialize ids.
    
    Signed-off-by: Isaku Yamahata <yamahata at valinux.co.jp>
    Signed-off-by: Michael S. Tsirkin <mst at redhat.com>

diff --git a/hw/apb_pci.c b/hw/apb_pci.c
index 84e9af7..974c87a 100644
--- a/hw/apb_pci.c
+++ b/hw/apb_pci.c
@@ -304,9 +304,6 @@ static int apb_pci_bridge_initfn(PCIDevice *dev)
         return rc;
     }
 
-    pci_config_set_vendor_id(dev->config, PCI_VENDOR_ID_SUN);
-    pci_config_set_device_id(dev->config, PCI_DEVICE_ID_SUN_SIMBA);
-
     /*
      * command register:
      * According to PCI bridge spec, after reset
@@ -321,7 +318,6 @@ static int apb_pci_bridge_initfn(PCIDevice *dev)
     pci_set_word(dev->config + PCI_STATUS,
                  PCI_STATUS_FAST_BACK | PCI_STATUS_66MHZ |
                  PCI_STATUS_DEVSEL_MEDIUM);
-    pci_set_byte(dev->config + PCI_REVISION_ID, 0x11);
     return 0;
 }
 
@@ -436,14 +432,11 @@ static int pci_pbm_init_device(SysBusDevice *dev)
 
 static int pbm_pci_host_init(PCIDevice *d)
 {
-    pci_config_set_vendor_id(d->config, PCI_VENDOR_ID_SUN);
-    pci_config_set_device_id(d->config, PCI_DEVICE_ID_SUN_SABRE);
     pci_set_word(d->config + PCI_COMMAND,
                  PCI_COMMAND_MEMORY | PCI_COMMAND_MASTER);
     pci_set_word(d->config + PCI_STATUS,
                  PCI_STATUS_FAST_BACK | PCI_STATUS_66MHZ |
                  PCI_STATUS_DEVSEL_MEDIUM);
-    pci_config_set_class(d->config, PCI_CLASS_BRIDGE_HOST);
     return 0;
 }
 
@@ -451,6 +444,9 @@ static PCIDeviceInfo pbm_pci_host_info = {
     .qdev.name = "pbm",
     .qdev.size = sizeof(PCIDevice),
     .init      = pbm_pci_host_init,
+    .vendor_id = PCI_VENDOR_ID_SUN,
+    .device_id = PCI_DEVICE_ID_SUN_SABRE,
+    .class_id  = PCI_CLASS_BRIDGE_HOST,
     .is_bridge = 1,
 };
 
@@ -468,6 +464,9 @@ static PCIDeviceInfo pbm_pci_bridge_info = {
     .qdev.reset = pci_bridge_reset,
     .init = apb_pci_bridge_initfn,
     .exit = pci_bridge_exitfn,
+    .vendor_id = PCI_VENDOR_ID_SUN,
+    .device_id = PCI_DEVICE_ID_SUN_SIMBA,
+    .revision = 0x11,
     .config_write = pci_bridge_write_config,
     .is_bridge = 1,
 };
commit e7b9bc3e89152f14f426fa4d150d2a6ca02583c1
Author: Isaku Yamahata <yamahata at valinux.co.jp>
Date:   Wed May 25 10:58:01 2011 +0900

    dec_pci: convert to PCIDeviceInfo to initialize ids
    
    use PCIDeviceInfo to initialize ids.
    
    Signed-off-by: Isaku Yamahata <yamahata at valinux.co.jp>
    Signed-off-by: Michael S. Tsirkin <mst at redhat.com>

diff --git a/hw/dec_pci.c b/hw/dec_pci.c
index bf88f2a..a35f382 100644
--- a/hw/dec_pci.c
+++ b/hw/dec_pci.c
@@ -50,28 +50,16 @@ static int dec_map_irq(PCIDevice *pci_dev, int irq_num)
     return irq_num;
 }
 
-static int dec_21154_initfn(PCIDevice *dev)
-{
-    int rc;
-
-    rc = pci_bridge_initfn(dev);
-    if (rc < 0) {
-        return rc;
-    }
-
-    pci_config_set_vendor_id(dev->config, PCI_VENDOR_ID_DEC);
-    pci_config_set_device_id(dev->config, PCI_DEVICE_ID_DEC_21154);
-    return 0;
-}
-
 static PCIDeviceInfo dec_21154_pci_bridge_info = {
     .qdev.name = "dec-21154-p2p-bridge",
     .qdev.desc = "DEC 21154 PCI-PCI bridge",
     .qdev.size = sizeof(PCIBridge),
     .qdev.vmsd = &vmstate_pci_device,
     .qdev.reset = pci_bridge_reset,
-    .init = dec_21154_initfn,
+    .init = pci_bridge_initfn,
     .exit = pci_bridge_exitfn,
+    .vendor_id = PCI_VENDOR_ID_DEC,
+    .device_id = PCI_DEVICE_ID_DEC_21154,
     .config_write = pci_bridge_write_config,
     .is_bridge = 1,
 };
@@ -108,10 +96,6 @@ static int pci_dec_21154_init_device(SysBusDevice *dev)
 static int dec_21154_pci_host_init(PCIDevice *d)
 {
     /* PCI2PCI bridge same values as PearPC - check this */
-    pci_config_set_vendor_id(d->config, PCI_VENDOR_ID_DEC);
-    pci_config_set_device_id(d->config, PCI_DEVICE_ID_DEC_21154);
-    pci_set_byte(d->config + PCI_REVISION_ID, 0x02);
-    pci_config_set_class(d->config, PCI_CLASS_BRIDGE_PCI);
     return 0;
 }
 
@@ -119,6 +103,10 @@ static PCIDeviceInfo dec_21154_pci_host_info = {
     .qdev.name = "dec-21154",
     .qdev.size = sizeof(PCIDevice),
     .init      = dec_21154_pci_host_init,
+    .vendor_id = PCI_VENDOR_ID_DEC,
+    .device_id = PCI_DEVICE_ID_DEC_21154,
+    .revision = 0x02,
+    .class_id = PCI_CLASS_BRIDGE_PCI,
     .is_bridge  = 1,
 };
 
commit ad03502b3fa1c7e3046775077965030cc595b36e
Author: Isaku Yamahata <yamahata at valinux.co.jp>
Date:   Wed May 25 10:58:00 2011 +0900

    eepro100: convert to PCIDeviceInfo to initialize ids
    
    use PCIDeviceInfo to initialize ids.
    
    Signed-off-by: Isaku Yamahata <yamahata at valinux.co.jp>
    Signed-off-by: Michael S. Tsirkin <mst at redhat.com>

diff --git a/hw/eepro100.c b/hw/eepro100.c
index 05450e8..84b98c0 100644
--- a/hw/eepro100.c
+++ b/hw/eepro100.c
@@ -129,8 +129,6 @@
 typedef struct {
     PCIDeviceInfo pci;
     uint32_t device;
-    uint16_t device_id;
-    uint8_t revision;
     uint8_t stats_size;
     bool has_extended_tcb_support;
     bool power_management;
@@ -526,16 +524,9 @@ static void e100_pci_reset(EEPRO100State * s, E100PCIDeviceInfo *e100_device)
 
     TRACE(OTHER, logout("%p\n", s));
 
-    /* PCI Vendor ID */
-    pci_config_set_vendor_id(pci_conf, PCI_VENDOR_ID_INTEL);
-    /* PCI Device ID */
-    pci_config_set_device_id(pci_conf, e100_device->device_id);
     /* PCI Status */
     pci_set_word(pci_conf + PCI_STATUS, PCI_STATUS_DEVSEL_MEDIUM |
                                         PCI_STATUS_FAST_BACK);
-    /* PCI Revision ID */
-    pci_config_set_revision(pci_conf, e100_device->revision);
-    pci_config_set_class(pci_conf, PCI_CLASS_NETWORK_ETHERNET);
     /* PCI Latency Timer */
     pci_set_byte(pci_conf + PCI_LATENCY_TIMER, 0x20);   /* latency timer = 32 clocks */
     /* Capability Pointer is set by PCI framework. */
@@ -563,12 +554,7 @@ static void e100_pci_reset(EEPRO100State * s, E100PCIDeviceInfo *e100_device)
     case i82559ER:
     case i82562:
     case i82801:
-        break;
     case i82559C:
-#if EEPROM_SIZE > 0
-        pci_set_word(pci_conf + PCI_SUBSYSTEM_VENDOR_ID, PCI_VENDOR_ID_INTEL);
-        pci_set_word(pci_conf + PCI_SUBSYSTEM_ID, 0x0040);
-#endif
         break;
     default:
         logout("Device %X is undefined!\n", device);
@@ -2040,9 +2026,9 @@ static E100PCIDeviceInfo e100_devices[] = {
         .pci.qdev.desc = "Intel i82550 Ethernet",
         .device = i82550,
         /* TODO: check device id. */
-        .device_id = PCI_DEVICE_ID_INTEL_82551IT,
+        .pci.device_id = PCI_DEVICE_ID_INTEL_82551IT,
         /* Revision ID: 0x0c, 0x0d, 0x0e. */
-        .revision = 0x0e,
+        .pci.revision = 0x0e,
         /* TODO: check size of statistical counters. */
         .stats_size = 80,
         /* TODO: check extended tcb support. */
@@ -2052,9 +2038,9 @@ static E100PCIDeviceInfo e100_devices[] = {
         .pci.qdev.name = "i82551",
         .pci.qdev.desc = "Intel i82551 Ethernet",
         .device = i82551,
-        .device_id = PCI_DEVICE_ID_INTEL_82551IT,
+        .pci.device_id = PCI_DEVICE_ID_INTEL_82551IT,
         /* Revision ID: 0x0f, 0x10. */
-        .revision = 0x0f,
+        .pci.revision = 0x0f,
         /* TODO: check size of statistical counters. */
         .stats_size = 80,
         .has_extended_tcb_support = true,
@@ -2063,29 +2049,29 @@ static E100PCIDeviceInfo e100_devices[] = {
         .pci.qdev.name = "i82557a",
         .pci.qdev.desc = "Intel i82557A Ethernet",
         .device = i82557A,
-        .device_id = PCI_DEVICE_ID_INTEL_82557,
-        .revision = 0x01,
+        .pci.device_id = PCI_DEVICE_ID_INTEL_82557,
+        .pci.revision = 0x01,
         .power_management = false,
     },{
         .pci.qdev.name = "i82557b",
         .pci.qdev.desc = "Intel i82557B Ethernet",
         .device = i82557B,
-        .device_id = PCI_DEVICE_ID_INTEL_82557,
-        .revision = 0x02,
+        .pci.device_id = PCI_DEVICE_ID_INTEL_82557,
+        .pci.revision = 0x02,
         .power_management = false,
     },{
         .pci.qdev.name = "i82557c",
         .pci.qdev.desc = "Intel i82557C Ethernet",
         .device = i82557C,
-        .device_id = PCI_DEVICE_ID_INTEL_82557,
-        .revision = 0x03,
+        .pci.device_id = PCI_DEVICE_ID_INTEL_82557,
+        .pci.revision = 0x03,
         .power_management = false,
     },{
         .pci.qdev.name = "i82558a",
         .pci.qdev.desc = "Intel i82558A Ethernet",
         .device = i82558A,
-        .device_id = PCI_DEVICE_ID_INTEL_82557,
-        .revision = 0x04,
+        .pci.device_id = PCI_DEVICE_ID_INTEL_82557,
+        .pci.revision = 0x04,
         .stats_size = 76,
         .has_extended_tcb_support = true,
         .power_management = true,
@@ -2093,8 +2079,8 @@ static E100PCIDeviceInfo e100_devices[] = {
         .pci.qdev.name = "i82558b",
         .pci.qdev.desc = "Intel i82558B Ethernet",
         .device = i82558B,
-        .device_id = PCI_DEVICE_ID_INTEL_82557,
-        .revision = 0x05,
+        .pci.device_id = PCI_DEVICE_ID_INTEL_82557,
+        .pci.revision = 0x05,
         .stats_size = 76,
         .has_extended_tcb_support = true,
         .power_management = true,
@@ -2102,8 +2088,8 @@ static E100PCIDeviceInfo e100_devices[] = {
         .pci.qdev.name = "i82559a",
         .pci.qdev.desc = "Intel i82559A Ethernet",
         .device = i82559A,
-        .device_id = PCI_DEVICE_ID_INTEL_82557,
-        .revision = 0x06,
+        .pci.device_id = PCI_DEVICE_ID_INTEL_82557,
+        .pci.revision = 0x06,
         .stats_size = 80,
         .has_extended_tcb_support = true,
         .power_management = true,
@@ -2111,8 +2097,8 @@ static E100PCIDeviceInfo e100_devices[] = {
         .pci.qdev.name = "i82559b",
         .pci.qdev.desc = "Intel i82559B Ethernet",
         .device = i82559B,
-        .device_id = PCI_DEVICE_ID_INTEL_82557,
-        .revision = 0x07,
+        .pci.device_id = PCI_DEVICE_ID_INTEL_82557,
+        .pci.revision = 0x07,
         .stats_size = 80,
         .has_extended_tcb_support = true,
         .power_management = true,
@@ -2120,12 +2106,16 @@ static E100PCIDeviceInfo e100_devices[] = {
         .pci.qdev.name = "i82559c",
         .pci.qdev.desc = "Intel i82559C Ethernet",
         .device = i82559C,
-        .device_id = PCI_DEVICE_ID_INTEL_82557,
+        .pci.device_id = PCI_DEVICE_ID_INTEL_82557,
 #if 0
-        .revision = 0x08,
+        .pci.revision = 0x08,
 #endif
         /* TODO: Windows wants revision id 0x0c. */
-        .revision = 0x0c,
+        .pci.revision = 0x0c,
+#if EEPROM_SIZE > 0
+        .pci.subsystem_vendor_id = PCI_VENDOR_ID_INTEL,
+        .pci.subsystem_id = 0x0040,
+#endif
         .stats_size = 80,
         .has_extended_tcb_support = true,
         .power_management = true,
@@ -2133,8 +2123,8 @@ static E100PCIDeviceInfo e100_devices[] = {
         .pci.qdev.name = "i82559er",
         .pci.qdev.desc = "Intel i82559ER Ethernet",
         .device = i82559ER,
-        .device_id = PCI_DEVICE_ID_INTEL_82551IT,
-        .revision = 0x09,
+        .pci.device_id = PCI_DEVICE_ID_INTEL_82551IT,
+        .pci.revision = 0x09,
         .stats_size = 80,
         .has_extended_tcb_support = true,
         .power_management = true,
@@ -2143,9 +2133,9 @@ static E100PCIDeviceInfo e100_devices[] = {
         .pci.qdev.desc = "Intel i82562 Ethernet",
         .device = i82562,
         /* TODO: check device id. */
-        .device_id = PCI_DEVICE_ID_INTEL_82551IT,
+        .pci.device_id = PCI_DEVICE_ID_INTEL_82551IT,
         /* TODO: wrong revision id. */
-        .revision = 0x0e,
+        .pci.revision = 0x0e,
         .stats_size = 80,
         .has_extended_tcb_support = true,
         .power_management = true,
@@ -2154,8 +2144,8 @@ static E100PCIDeviceInfo e100_devices[] = {
         .pci.qdev.name = "i82801",
         .pci.qdev.desc = "Intel i82801 Ethernet",
         .device = i82801,
-        .device_id = 0x2449,
-        .revision = 0x03,
+        .pci.device_id = 0x2449,
+        .pci.revision = 0x03,
         .stats_size = 80,
         .has_extended_tcb_support = true,
         .power_management = true,
@@ -2174,6 +2164,8 @@ static void eepro100_register_devices(void)
         PCIDeviceInfo *pci_dev = &e100_devices[i].pci;
         /* We use the same rom file for all device ids.
            QEMU fixes the device id during rom load. */
+        pci_dev->vendor_id = PCI_VENDOR_ID_INTEL;
+        pci_dev->class_id = PCI_CLASS_NETWORK_ETHERNET;
         pci_dev->romfile = "pxe-eepro100.rom";
         pci_dev->init = e100_nic_init;
         pci_dev->exit = pci_nic_uninit;
commit dc638fadb54c911019227ae37656560c49a209b9
Author: Isaku Yamahata <yamahata at valinux.co.jp>
Date:   Wed May 25 10:57:59 2011 +0900

    usb-uhci: convert to PCIDEviceInfo to initialize ids
    
    use PCIDeviceInfo to initialize ids.
    
    Signed-off-by: Isaku Yamahata <yamahata at valinux.co.jp>
    Signed-off-by: Michael S. Tsirkin <mst at redhat.com>

diff --git a/hw/usb-uhci.c b/hw/usb-uhci.c
index 346db3e..536c24c 100644
--- a/hw/usb-uhci.c
+++ b/hw/usb-uhci.c
@@ -1115,14 +1115,13 @@ static USBPortOps uhci_port_ops = {
     .wakeup = uhci_wakeup,
 };
 
-static int usb_uhci_common_initfn(UHCIState *s)
+static int usb_uhci_common_initfn(PCIDevice *dev)
 {
+    UHCIState *s = DO_UPCAST(UHCIState, dev, dev);
     uint8_t *pci_conf = s->dev.config;
     int i;
 
-    pci_conf[PCI_REVISION_ID] = 0x01; // revision number
     pci_conf[PCI_CLASS_PROG] = 0x00;
-    pci_config_set_class(pci_conf, PCI_CLASS_SERIAL_USB);
     /* TODO: reset value should be 0. */
     pci_conf[PCI_INTERRUPT_PIN] = 4; // interrupt pin 3
     pci_conf[0x60] = 0x10; // release number
@@ -1148,34 +1147,11 @@ static int usb_uhci_common_initfn(UHCIState *s)
     return 0;
 }
 
-static int usb_uhci_piix3_initfn(PCIDevice *dev)
-{
-    UHCIState *s = DO_UPCAST(UHCIState, dev, dev);
-    uint8_t *pci_conf = s->dev.config;
-
-    pci_config_set_vendor_id(pci_conf, PCI_VENDOR_ID_INTEL);
-    pci_config_set_device_id(pci_conf, PCI_DEVICE_ID_INTEL_82371SB_2);
-    return usb_uhci_common_initfn(s);
-}
-
-static int usb_uhci_piix4_initfn(PCIDevice *dev)
-{
-    UHCIState *s = DO_UPCAST(UHCIState, dev, dev);
-    uint8_t *pci_conf = s->dev.config;
-
-    pci_config_set_vendor_id(pci_conf, PCI_VENDOR_ID_INTEL);
-    pci_config_set_device_id(pci_conf, PCI_DEVICE_ID_INTEL_82371AB_2);
-    return usb_uhci_common_initfn(s);
-}
-
 static int usb_uhci_vt82c686b_initfn(PCIDevice *dev)
 {
     UHCIState *s = DO_UPCAST(UHCIState, dev, dev);
     uint8_t *pci_conf = s->dev.config;
 
-    pci_config_set_vendor_id(pci_conf, PCI_VENDOR_ID_VIA);
-    pci_config_set_device_id(pci_conf, PCI_DEVICE_ID_VIA_UHCI);
-
     /* USB misc control 1/2 */
     pci_set_long(pci_conf + 0x40,0x00001000);
     /* PM capability */
@@ -1183,7 +1159,7 @@ static int usb_uhci_vt82c686b_initfn(PCIDevice *dev)
     /* USB legacy support  */
     pci_set_long(pci_conf + 0xc0,0x00002000);
 
-    return usb_uhci_common_initfn(s);
+    return usb_uhci_common_initfn(dev);
 }
 
 static PCIDeviceInfo uhci_info[] = {
@@ -1191,17 +1167,29 @@ static PCIDeviceInfo uhci_info[] = {
         .qdev.name    = "piix3-usb-uhci",
         .qdev.size    = sizeof(UHCIState),
         .qdev.vmsd    = &vmstate_uhci,
-        .init         = usb_uhci_piix3_initfn,
+        .init         = usb_uhci_common_initfn,
+        .vendor_id    = PCI_VENDOR_ID_INTEL,
+        .device_id    = PCI_DEVICE_ID_INTEL_82371SB_2,
+        .revision     = 0x01,
+        .class_id     = PCI_CLASS_SERIAL_USB,
     },{
         .qdev.name    = "piix4-usb-uhci",
         .qdev.size    = sizeof(UHCIState),
         .qdev.vmsd    = &vmstate_uhci,
-        .init         = usb_uhci_piix4_initfn,
+        .init         = usb_uhci_common_initfn,
+        .vendor_id    = PCI_VENDOR_ID_INTEL,
+        .device_id    = PCI_DEVICE_ID_INTEL_82371AB_2,
+        .revision     = 0x01,
+        .class_id     = PCI_CLASS_SERIAL_USB,
     },{
         .qdev.name    = "vt82c686b-usb-uhci",
         .qdev.size    = sizeof(UHCIState),
         .qdev.vmsd    = &vmstate_uhci,
         .init         = usb_uhci_vt82c686b_initfn,
+        .vendor_id    = PCI_VENDOR_ID_VIA,
+        .device_id    = PCI_DEVICE_ID_VIA_UHCI,
+        .revision     = 0x01,
+        .class_id     = PCI_CLASS_SERIAL_USB,
     },{
         /* end of list */
     }
commit 113f89df42479924380cad562ab86fd2c8e2d11b
Author: Isaku Yamahata <yamahata at valinux.co.jp>
Date:   Wed May 25 10:57:58 2011 +0900

    pci: move ids of config space into PCIDeviceInfo
    
    vender id/device id... in configuration space are read-only registers
    which are commonly defined for all pci devices.
    So move those initialization into common place.
    
    Signed-off-by: Isaku Yamahata <yamahata at valinux.co.jp>
    Signed-off-by: Michael S. Tsirkin <mst at redhat.com>

diff --git a/hw/pci.c b/hw/pci.c
index 0875654..0e97a02 100644
--- a/hw/pci.c
+++ b/hw/pci.c
@@ -726,10 +726,11 @@ static void pci_config_free(PCIDevice *pci_dev)
 /* -1 for devfn means auto assign */
 static PCIDevice *do_pci_register_device(PCIDevice *pci_dev, PCIBus *bus,
                                          const char *name, int devfn,
-                                         PCIConfigReadFunc *config_read,
-                                         PCIConfigWriteFunc *config_write,
-                                         bool is_bridge)
+                                         const PCIDeviceInfo *info)
 {
+    PCIConfigReadFunc *config_read = info->config_read;
+    PCIConfigWriteFunc *config_write = info->config_write;
+
     if (devfn < 0) {
         for(devfn = bus->devfn_min ; devfn < ARRAY_SIZE(bus->devices);
             devfn += PCI_FUNC_MAX) {
@@ -750,13 +751,29 @@ static PCIDevice *do_pci_register_device(PCIDevice *pci_dev, PCIBus *bus,
     pci_dev->irq_state = 0;
     pci_config_alloc(pci_dev);
 
-    if (!is_bridge) {
-        pci_set_default_subsystem_id(pci_dev);
+    pci_config_set_vendor_id(pci_dev->config, info->vendor_id);
+    pci_config_set_device_id(pci_dev->config, info->device_id);
+    pci_config_set_revision(pci_dev->config, info->revision);
+    pci_config_set_class(pci_dev->config, info->class_id);
+
+    if (!info->is_bridge) {
+        if (info->subsystem_vendor_id || info->subsystem_id) {
+            pci_set_word(pci_dev->config + PCI_SUBSYSTEM_VENDOR_ID,
+                         info->subsystem_vendor_id);
+            pci_set_word(pci_dev->config + PCI_SUBSYSTEM_ID,
+                         info->subsystem_id);
+        } else {
+            pci_set_default_subsystem_id(pci_dev);
+        }
+    } else {
+        /* subsystem_vendor_id/subsystem_id are only for header type 0 */
+        assert(!info->subsystem_vendor_id);
+        assert(!info->subsystem_id);
     }
     pci_init_cmask(pci_dev);
     pci_init_wmask(pci_dev);
     pci_init_w1cmask(pci_dev);
-    if (is_bridge) {
+    if (info->is_bridge) {
         pci_init_wmask_bridge(pci_dev);
     }
     if (pci_init_multifunction(bus, pci_dev)) {
@@ -783,17 +800,20 @@ static void do_pci_unregister_device(PCIDevice *pci_dev)
     pci_config_free(pci_dev);
 }
 
+/* TODO: obsolete. eliminate this once all pci devices are qdevifed. */
 PCIDevice *pci_register_device(PCIBus *bus, const char *name,
                                int instance_size, int devfn,
                                PCIConfigReadFunc *config_read,
                                PCIConfigWriteFunc *config_write)
 {
     PCIDevice *pci_dev;
+    PCIDeviceInfo info = {
+        .config_read = config_read,
+        .config_write = config_write,
+    };
 
     pci_dev = qemu_mallocz(instance_size);
-    pci_dev = do_pci_register_device(pci_dev, bus, name, devfn,
-                                     config_read, config_write,
-                                     PCI_HEADER_TYPE_NORMAL);
+    pci_dev = do_pci_register_device(pci_dev, bus, name, devfn, &info);
     if (pci_dev == NULL) {
         hw_error("PCI: can't register device\n");
     }
@@ -1643,7 +1663,7 @@ static int pci_qdev_init(DeviceState *qdev, DeviceInfo *base)
     PCIDevice *pci_dev = (PCIDevice *)qdev;
     PCIDeviceInfo *info = container_of(base, PCIDeviceInfo, qdev);
     PCIBus *bus;
-    int devfn, rc;
+    int rc;
     bool is_default_rom;
 
     /* initialize cap_present for pci_is_express() and pci_config_size() */
@@ -1652,10 +1672,8 @@ static int pci_qdev_init(DeviceState *qdev, DeviceInfo *base)
     }
 
     bus = FROM_QBUS(PCIBus, qdev_get_parent_bus(qdev));
-    devfn = pci_dev->devfn;
-    pci_dev = do_pci_register_device(pci_dev, bus, base->name, devfn,
-                                     info->config_read, info->config_write,
-                                     info->is_bridge);
+    pci_dev = do_pci_register_device(pci_dev, bus, base->name,
+                                     pci_dev->devfn, info);
     if (pci_dev == NULL)
         return -1;
     if (qdev->hotplugged && info->no_hotplug) {
diff --git a/hw/pci.h b/hw/pci.h
index c6a6eb6..ce214f4 100644
--- a/hw/pci.h
+++ b/hw/pci.h
@@ -433,6 +433,13 @@ typedef struct {
     PCIConfigReadFunc *config_read;
     PCIConfigWriteFunc *config_write;
 
+    uint16_t vendor_id;
+    uint16_t device_id;
+    uint8_t revision;
+    uint16_t class_id;
+    uint16_t subsystem_vendor_id;       /* only for header type = 0 */
+    uint16_t subsystem_id;              /* only for header type = 0 */
+
     /*
      * pci-to-pci bridge or normal device.
      * This doesn't mean pci host switch.
commit 2173a75fb714193c4df9d5ddf9d015786566b19a
Author: Alex Williamson <alex.williamson at redhat.com>
Date:   Tue May 3 12:36:58 2011 -0600

    CPUPhysMemoryClient: batch addresses in catchup
    
    When a phys memory client registers and we play catchup by walking
    the page tables, we can make a huge improvement in the number of
    times the set_memory callback is called by batching contiguous
    pages together.  With a 4G guest, this reduces the number of callbacks
    at registration from 1048866 to 296.
    
    Signed-off-by: Alex Williamson <alex.williamson at redhat.com>
    Signed-off-by: Michael S. Tsirkin <mst at redhat.com>

diff --git a/exec.c b/exec.c
index 308a86d..66c92bc 100644
--- a/exec.c
+++ b/exec.c
@@ -1750,14 +1750,21 @@ static int cpu_notify_migration_log(int enable)
     return 0;
 }
 
+struct last_map {
+    target_phys_addr_t start_addr;
+    ram_addr_t size;
+    ram_addr_t phys_offset;
+};
+
 /* The l1_phys_map provides the upper P_L1_BITs of the guest physical
  * address.  Each intermediate table provides the next L2_BITs of guest
  * physical address space.  The number of levels vary based on host and
  * guest configuration, making it efficient to build the final guest
  * physical address by seeding the L1 offset and shifting and adding in
  * each L2 offset as we recurse through them. */
-static void phys_page_for_each_1(CPUPhysMemoryClient *client,
-                                 int level, void **lp, target_phys_addr_t addr)
+static void phys_page_for_each_1(CPUPhysMemoryClient *client, int level,
+                                 void **lp, target_phys_addr_t addr,
+                                 struct last_map *map)
 {
     int i;
 
@@ -1769,15 +1776,29 @@ static void phys_page_for_each_1(CPUPhysMemoryClient *client,
         addr <<= L2_BITS + TARGET_PAGE_BITS;
         for (i = 0; i < L2_SIZE; ++i) {
             if (pd[i].phys_offset != IO_MEM_UNASSIGNED) {
-                client->set_memory(client, addr | i << TARGET_PAGE_BITS,
-                                   TARGET_PAGE_SIZE, pd[i].phys_offset, false);
+                target_phys_addr_t start_addr = addr | i << TARGET_PAGE_BITS;
+
+                if (map->size &&
+                    start_addr == map->start_addr + map->size &&
+                    pd[i].phys_offset == map->phys_offset + map->size) {
+
+                    map->size += TARGET_PAGE_SIZE;
+                    continue;
+                } else if (map->size) {
+                    client->set_memory(client, map->start_addr,
+                                       map->size, map->phys_offset, false);
+                }
+
+                map->start_addr = start_addr;
+                map->size = TARGET_PAGE_SIZE;
+                map->phys_offset = pd[i].phys_offset;
             }
         }
     } else {
         void **pp = *lp;
         for (i = 0; i < L2_SIZE; ++i) {
             phys_page_for_each_1(client, level - 1, pp + i,
-                                 (addr << L2_BITS) | i);
+                                 (addr << L2_BITS) | i, map);
         }
     }
 }
@@ -1785,9 +1806,15 @@ static void phys_page_for_each_1(CPUPhysMemoryClient *client,
 static void phys_page_for_each(CPUPhysMemoryClient *client)
 {
     int i;
+    struct last_map map = { };
+
     for (i = 0; i < P_L1_SIZE; ++i) {
         phys_page_for_each_1(client, P_L1_SHIFT / L2_BITS - 1,
-                             l1_phys_map + i, i);
+                             l1_phys_map + i, i, &map);
+    }
+    if (map.size) {
+        client->set_memory(client, map.start_addr, map.size, map.phys_offset,
+                           false);
     }
 }
 
commit 69c8944f17cb6c084567a16c080cfa7bc780e668
Author: Michael S. Tsirkin <mst at redhat.com>
Date:   Sun May 15 19:27:34 2011 +0300

    ich/ahci: fix uninitialized memory use
    
    The commit 667bb59d2358daeef179583c944becba3f1f9680
    uses d->ahci.mem before it is initialized by
    ahci_init(). Fix this by calling ahci_init() first thing
    so that it's safe to use all fields in the ahci state struct.
    
    Reported-by: Alexey Zaytsev <alexey.zaytsev at gmail.com>
    Reported-by: Jan Kiszka <jan.kiszka at web.de>
    Tested-by: Alexey Zaytsev <alexey.zaytsev at gmail.com>
    Signed-off-by: Michael S. Tsirkin <mst at redhat.com>

diff --git a/hw/ide/ich.c b/hw/ide/ich.c
index e44339b..5ce0a88 100644
--- a/hw/ide/ich.c
+++ b/hw/ide/ich.c
@@ -77,6 +77,8 @@ static int pci_ich9_ahci_init(PCIDevice *dev)
     struct AHCIPCIState *d;
     d = DO_UPCAST(struct AHCIPCIState, card, dev);
 
+    ahci_init(&d->ahci, &dev->qdev, 6);
+
     pci_config_set_vendor_id(d->card.config, PCI_VENDOR_ID_INTEL);
     pci_config_set_device_id(d->card.config, PCI_DEVICE_ID_INTEL_82801IR);
 
@@ -97,8 +99,6 @@ static int pci_ich9_ahci_init(PCIDevice *dev)
     pci_register_bar_simple(&d->card, 5, 0x1000, 0, d->ahci.mem);
 
     msi_init(dev, 0x50, 1, true, false);
-
-    ahci_init(&d->ahci, &dev->qdev, 6);
     d->ahci.irq = d->card.irq[0];
 
     return 0;


More information about the Spice-commits mailing list