[Spice-commits] 68 commits - MAINTAINERS block.c block/mirror.c cpus.c disas/libvixl hmp-commands.hx hw/arm hw/block hw/core hw/ide hw/intc hw/ppc hw/s390x hw/scsi hw/timer hw/usb include/hw kvm-all.c memory.c pc-bios/openbios-ppc pc-bios/openbios-sparc32 pc-bios/openbios-sparc64 qapi-schema.json qemu-img.c qmp-commands.hx roms/openbios scripts/checkpatch.pl scripts/qapi.py scripts/tracetool target-arm/cpu.h target-arm/cpu64.c target-arm/helper.c target-i386/cpu.c target-i386/cpu.h target-i386/helper.c target-i386/kvm.c target-i386/machine.c target-ppc/cpu-qom.h target-ppc/excp_helper.c tests/Makefile tests/libqtest.c tests/qemu-iotests tests/usb-hcd-ohci-test.c tests/usb-hcd-uhci-test.c tests/usb-hcd-xhci-test.c trace-events vl.c xen-hvm.c

Gerd Hoffmann kraxel at kemper.freedesktop.org
Tue Sep 2 00:37:57 PDT 2014


 MAINTAINERS                           |    2 
 block.c                               |   14 +
 block/mirror.c                        |    4 
 cpus.c                                |   17 -
 disas/libvixl/README                  |    2 
 disas/libvixl/a64/assembler-a64.h     |  363 ++++++++++++++++++++++++++++++----
 disas/libvixl/a64/constants-a64.h     |   68 +++++-
 disas/libvixl/a64/cpu-a64.h           |   27 ++
 disas/libvixl/a64/decoder-a64.cc      |   15 -
 disas/libvixl/a64/decoder-a64.h       |    1 
 disas/libvixl/a64/disasm-a64.cc       |   88 ++++++--
 disas/libvixl/a64/disasm-a64.h        |    2 
 disas/libvixl/a64/instructions-a64.cc |   25 +-
 disas/libvixl/a64/instructions-a64.h  |   10 
 disas/libvixl/platform.h              |    8 
 disas/libvixl/utils.cc                |   10 
 disas/libvixl/utils.h                 |   32 ++
 hmp-commands.hx                       |    6 
 hw/arm/virt.c                         |    2 
 hw/block/block.c                      |   18 -
 hw/block/virtio-blk.c                 |    7 
 hw/core/Makefile.objs                 |    1 
 hw/core/nmi.c                         |   84 +++++++
 hw/ide/qdev.c                         |   11 -
 hw/intc/arm_gic.c                     |   17 -
 hw/intc/arm_gic_common.c              |    2 
 hw/ppc/spapr.c                        |   21 +
 hw/s390x/s390-virtio-ccw.c            |   49 +++-
 hw/s390x/s390-virtio.c                |   59 +++--
 hw/s390x/s390-virtio.h                |    3 
 hw/scsi/lsi53c895a.c                  |    1 
 hw/scsi/scsi-bus.c                    |   70 +++---
 hw/scsi/scsi-disk.c                   |   83 ++++---
 hw/scsi/scsi-generic.c                |   40 +--
 hw/scsi/virtio-scsi.c                 |    6 
 hw/timer/mc146818rtc.c                |    1 
 hw/usb/bus.c                          |   11 -
 hw/usb/hcd-ehci-pci.c                 |   14 +
 hw/usb/hcd-ehci.c                     |   29 ++
 hw/usb/hcd-ehci.h                     |    2 
 hw/usb/hcd-ohci.c                     |   27 ++
 hw/usb/hcd-uhci.c                     |   24 ++
 hw/usb/hcd-xhci.c                     |   50 ++++
 include/hw/block/block.h              |    6 
 include/hw/nmi.h                      |   49 ++++
 include/hw/scsi/scsi.h                |    4 
 include/hw/usb.h                      |    1 
 kvm-all.c                             |   18 +
 memory.c                              |    4 
 pc-bios/openbios-ppc                  |binary
 pc-bios/openbios-sparc32              |binary
 pc-bios/openbios-sparc64              |binary
 qapi-schema.json                      |    4 
 qemu-img.c                            |   25 --
 qmp-commands.hx                       |    3 
 roms/openbios                         |    2 
 scripts/checkpatch.pl                 |    8 
 scripts/qapi.py                       |    8 
 scripts/tracetool/backend/__init__.py |    3 
 target-arm/cpu.h                      |   27 ++
 target-arm/cpu64.c                    |    3 
 target-arm/helper.c                   |  138 +++++++++---
 target-i386/cpu.c                     |   14 +
 target-i386/cpu.h                     |    4 
 target-i386/helper.c                  |    4 
 target-i386/kvm.c                     |  101 +++++++++
 target-i386/machine.c                 |    2 
 target-ppc/cpu-qom.h                  |    1 
 target-ppc/excp_helper.c              |    8 
 tests/Makefile                        |   10 
 tests/libqtest.c                      |    1 
 tests/qemu-iotests/051.out            |    2 
 tests/usb-hcd-ohci-test.c             |   35 +++
 tests/usb-hcd-uhci-test.c             |   35 +++
 tests/usb-hcd-xhci-test.c             |   35 +++
 trace-events                          |    3 
 vl.c                                  |   10 
 xen-hvm.c                             |   11 -
 78 files changed, 1521 insertions(+), 384 deletions(-)

New commits:
commit 8b3030114a449e66c68450acaac4b66f26d91416
Merge: d9aa688 0614601
Author: Peter Maydell <peter.maydell at linaro.org>
Date:   Fri Aug 29 15:48:15 2014 +0100

    Merge remote-tracking branch 'remotes/pmaydell/tags/pull-target-arm-20140829' into staging
    
    target-arm queue:
     * support PMCCNTR in ARMv8
     * various GIC fixes and cleanups
     * Correct Cortex-A57 ISAR5 and AA64ISAR0 ID register values
     * Fix regression that disabled VFP for ARMv5 CPUs
     * Update to upstream VIXL 1.5
    
    # gpg: Signature made Fri 29 Aug 2014 15:34:47 BST using RSA key ID 14360CDE
    # gpg: Good signature from "Peter Maydell <peter.maydell at linaro.org>"
    
    * remotes/pmaydell/tags/pull-target-arm-20140829:
      target-arm: Implement pmccfiltr_write function
      target-arm: Remove old code and replace with new functions
      target-arm: Implement pmccntr_sync function
      target-arm: Add arm_ccnt_enabled function
      target-arm: Implement PMCCNTR_EL0 and related registers
      arm: Implement PMCCNTR 32b read-modify-write
      target-arm: Make the ARM PMCCNTR register 64-bit
      hw/intc/arm_gic: honor target mask in gic_update()
      aarch64: raise max_cpus to 8
      arm_gic: Use GIC_NR_SGIS constant
      arm_gic: Do not force PPIs to edge-triggered mode
      arm_gic: GICD_ICFGR: Write model only for pre v1 GICs
      arm_gic: Fix read of GICD_ICFGR
      target-arm: Correct Cortex-A57 ISAR5 and AA64ISAR0 ID register values
      target-arm: Fix regression that disabled VFP for ARMv5 CPUs
      disas/libvixl: Update to upstream VIXL 1.5
    
    Signed-off-by: Peter Maydell <peter.maydell at linaro.org>

commit 0614601cecc8e5d9c6c5fa606b39fe388a18583a
Author: Alistair Francis <alistair.francis at xilinx.com>
Date:   Fri Aug 29 15:00:30 2014 +0100

    target-arm: Implement pmccfiltr_write function
    
    This is the function that is called when writing to the
    PMCCFILTR_EL0 register
    
    Signed-off-by: Alistair Francis <alistair.francis at xilinx.com>
    Signed-off-by: Peter Crosthwaite <peter.crosthwaite at xilinx.com>
    Message-id: 73da3da6404855b17d5ae82975a32ff3a4dcae3d.1409025949.git.peter.crosthwaite at xilinx.com
    Signed-off-by: Peter Maydell <peter.maydell at linaro.org>

diff --git a/target-arm/helper.c b/target-arm/helper.c
index d213ed1..2b95f33 100644
--- a/target-arm/helper.c
+++ b/target-arm/helper.c
@@ -650,6 +650,14 @@ void pmccntr_sync(CPUARMState *env)
 
 #endif
 
+static void pmccfiltr_write(CPUARMState *env, const ARMCPRegInfo *ri,
+                            uint64_t value)
+{
+    pmccntr_sync(env);
+    env->cp15.pmccfiltr_el0 = value & 0x7E000000;
+    pmccntr_sync(env);
+}
+
 static void pmcntenset_write(CPUARMState *env, const ARMCPRegInfo *ri,
                             uint64_t value)
 {
@@ -801,6 +809,7 @@ static const ARMCPRegInfo v7_cp_reginfo[] = {
 #endif
     { .name = "PMCCFILTR_EL0", .state = ARM_CP_STATE_AA64,
       .opc0 = 3, .opc1 = 3, .crn = 14, .crm = 15, .opc2 = 7,
+      .writefn = pmccfiltr_write,
       .access = PL0_RW, .accessfn = pmreg_access,
       .type = ARM_CP_IO,
       .fieldoffset = offsetof(CPUARMState, cp15.pmccfiltr_el0),
commit 942a155b2098d7cd9b6f93e251cd06fe11d96bcf
Author: Alistair Francis <alistair.francis at xilinx.com>
Date:   Fri Aug 29 15:00:30 2014 +0100

    target-arm: Remove old code and replace with new functions
    
    Remove the old PMCCNTR code and replace it with calls to the new
    pmccntr_sync() and arm_ccnt_enabled() functions.
    
    Signed-off-by: Alistair Francis <alistair.francis at xilinx.com>
    Signed-off-by: Peter Crosthwaite <peter.crosthwaite at xilinx.com>
    Message-id: 693a6e437d915c2195fd3dc7303f384ca538b7bf.1409025949.git.peter.crosthwaite at xilinx.com
    Signed-off-by: Peter Maydell <peter.maydell at linaro.org>

diff --git a/target-arm/helper.c b/target-arm/helper.c
index fa79dfa..d213ed1 100644
--- a/target-arm/helper.c
+++ b/target-arm/helper.c
@@ -580,20 +580,7 @@ void pmccntr_sync(CPUARMState *env)
 static void pmcr_write(CPUARMState *env, const ARMCPRegInfo *ri,
                        uint64_t value)
 {
-    uint64_t temp_ticks;
-
-    temp_ticks = muldiv64(qemu_clock_get_us(QEMU_CLOCK_VIRTUAL),
-                          get_ticks_per_sec(), 1000000);
-
-    if (env->cp15.c9_pmcr & PMCRE) {
-        /* If the counter is enabled */
-        if (env->cp15.c9_pmcr & PMCRD) {
-            /* Increment once every 64 processor clock cycles */
-            env->cp15.c15_ccnt = (temp_ticks/64) - env->cp15.c15_ccnt;
-        } else {
-            env->cp15.c15_ccnt = temp_ticks - env->cp15.c15_ccnt;
-        }
-    }
+    pmccntr_sync(env);
 
     if (value & PMCRC) {
         /* The counter has been reset */
@@ -604,20 +591,14 @@ static void pmcr_write(CPUARMState *env, const ARMCPRegInfo *ri,
     env->cp15.c9_pmcr &= ~0x39;
     env->cp15.c9_pmcr |= (value & 0x39);
 
-    if (env->cp15.c9_pmcr & PMCRE) {
-        if (env->cp15.c9_pmcr & PMCRD) {
-            /* Increment once every 64 processor clock cycles */
-            temp_ticks /= 64;
-        }
-        env->cp15.c15_ccnt = temp_ticks - env->cp15.c15_ccnt;
-    }
+    pmccntr_sync(env);
 }
 
 static uint64_t pmccntr_read(CPUARMState *env, const ARMCPRegInfo *ri)
 {
     uint64_t total_ticks;
 
-    if (!(env->cp15.c9_pmcr & PMCRE)) {
+    if (!arm_ccnt_enabled(env)) {
         /* Counter is disabled, do not change value */
         return env->cp15.c15_ccnt;
     }
@@ -637,7 +618,7 @@ static void pmccntr_write(CPUARMState *env, const ARMCPRegInfo *ri,
 {
     uint64_t total_ticks;
 
-    if (!(env->cp15.c9_pmcr & PMCRE)) {
+    if (!arm_ccnt_enabled(env)) {
         /* Counter is disabled, set the absolute value */
         env->cp15.c15_ccnt = value;
         return;
commit ec7b4ce4c7864337a336721721d48456b4b5b51d
Author: Alistair Francis <alistair.francis at xilinx.com>
Date:   Fri Aug 29 15:00:29 2014 +0100

    target-arm: Implement pmccntr_sync function
    
    This is used to synchronise the PMCCNTR counter and swap its
    state between enabled and disabled if required. It must always
    be called twice, both before and after any logic that could
    change the state of the PMCCNTR counter.
    
    Signed-off-by: Alistair Francis <alistair.francis at xilinx.com>
    Signed-off-by: Peter Crosthwaite <peter.crosthwaite at xilinx.com>
    Message-id: 62811d4c0f7b1384f7aab62ea2fcfda3dcb0db50.1409025949.git.peter.crosthwaite at xilinx.com
    [PMM: fixed minor typos in pmccntr_sync doc comment]
    Signed-off-by: Peter Maydell <peter.maydell at linaro.org>

diff --git a/target-arm/cpu.h b/target-arm/cpu.h
index 60dea03..51bedc8 100644
--- a/target-arm/cpu.h
+++ b/target-arm/cpu.h
@@ -353,6 +353,17 @@ int cpu_arm_signal_handler(int host_signum, void *pinfo,
 int arm_cpu_handle_mmu_fault(CPUState *cpu, vaddr address, int rw,
                              int mmu_idx);
 
+/**
+ * pmccntr_sync
+ * @env: CPUARMState
+ *
+ * Synchronises the counter in the PMCCNTR. This must always be called twice,
+ * once before any action that might affect the timer and again afterwards.
+ * The function is used to swap the state of the register if required.
+ * This only happens when not in user mode (!CONFIG_USER_ONLY)
+ */
+void pmccntr_sync(CPUARMState *env);
+
 /* SCTLR bit meanings. Several bits have been reused in newer
  * versions of the architecture; in that case we define constants
  * for both old and new bit meanings. Code which tests against those
diff --git a/target-arm/helper.c b/target-arm/helper.c
index e6c82ab..fa79dfa 100644
--- a/target-arm/helper.c
+++ b/target-arm/helper.c
@@ -560,6 +560,23 @@ static inline bool arm_ccnt_enabled(CPUARMState *env)
     return true;
 }
 
+void pmccntr_sync(CPUARMState *env)
+{
+    uint64_t temp_ticks;
+
+    temp_ticks = muldiv64(qemu_clock_get_us(QEMU_CLOCK_VIRTUAL),
+                          get_ticks_per_sec(), 1000000);
+
+    if (env->cp15.c9_pmcr & PMCRD) {
+        /* Increment once every 64 processor clock cycles */
+        temp_ticks /= 64;
+    }
+
+    if (arm_ccnt_enabled(env)) {
+        env->cp15.c15_ccnt = temp_ticks - env->cp15.c15_ccnt;
+    }
+}
+
 static void pmcr_write(CPUARMState *env, const ARMCPRegInfo *ri,
                        uint64_t value)
 {
@@ -644,6 +661,12 @@ static void pmccntr_write32(CPUARMState *env, const ARMCPRegInfo *ri,
     pmccntr_write(env, ri, deposit64(cur_val, 0, 32, value));
 }
 
+#else /* CONFIG_USER_ONLY */
+
+void pmccntr_sync(CPUARMState *env)
+{
+}
+
 #endif
 
 static void pmcntenset_write(CPUARMState *env, const ARMCPRegInfo *ri,
commit 87124fdea443322924be00eb79430a6243cf0747
Author: Alistair Francis <alistair.francis at xilinx.com>
Date:   Fri Aug 29 15:00:29 2014 +0100

    target-arm: Add arm_ccnt_enabled function
    
    Include a helper function to determine if the CCNT counter
    is enabled.
    
    Signed-off-by: Alistair Francis <alistair.francis at xilinx.com>
    Signed-off-by: Peter Crosthwaite <peter.crosthwaite at xilinx.com>
    Message-id: e1a64f17a756e06c8bda8238ad4826d705049f7a.1409025949.git.peter.crosthwaite at xilinx.com
    [ PC changes
      * Remove EL based checks
    ]
    Signed-off-by: Peter Crosthwaite <peter.crosthwaite at xilinx.com>
    Signed-off-by: Peter Maydell <peter.maydell at linaro.org>

diff --git a/target-arm/helper.c b/target-arm/helper.c
index 13507f7..e6c82ab 100644
--- a/target-arm/helper.c
+++ b/target-arm/helper.c
@@ -548,6 +548,18 @@ static CPAccessResult pmreg_access(CPUARMState *env, const ARMCPRegInfo *ri)
 }
 
 #ifndef CONFIG_USER_ONLY
+
+static inline bool arm_ccnt_enabled(CPUARMState *env)
+{
+    /* This does not support checking PMCCFILTR_EL0 register */
+
+    if (!(env->cp15.c9_pmcr & PMCRE)) {
+        return false;
+    }
+
+    return true;
+}
+
 static void pmcr_write(CPUARMState *env, const ARMCPRegInfo *ri,
                        uint64_t value)
 {
commit 8521466b391f92681d64eabfeeca17de9b03585d
Author: Alistair Francis <alistair.francis at xilinx.com>
Date:   Fri Aug 29 15:00:29 2014 +0100

    target-arm: Implement PMCCNTR_EL0 and related registers
    
    This patch adds support for the ARMv8 version of the PMCCNTR and
    related registers. It also starts to implement the PMCCFILTR_EL0
    register.
    
    Signed-off-by: Alistair Francis <alistair.francis at xilinx.com>
    Signed-off-by: Peter Crosthwaite <peter.crosthwaite at xilinx.com>
    Message-id: b5d1094764a5416363ee95216799b394ecd011e8.1409025949.git.peter.crosthwaite at xilinx.com
    Signed-off-by: Peter Maydell <peter.maydell at linaro.org>

diff --git a/target-arm/cpu.h b/target-arm/cpu.h
index 986c249..60dea03 100644
--- a/target-arm/cpu.h
+++ b/target-arm/cpu.h
@@ -191,8 +191,8 @@ typedef struct CPUARMState {
         uint64_t par_el1;  /* Translation result. */
         uint32_t c9_insn; /* Cache lockdown registers.  */
         uint32_t c9_data;
-        uint32_t c9_pmcr; /* performance monitor control register */
-        uint32_t c9_pmcnten; /* perf monitor counter enables */
+        uint64_t c9_pmcr; /* performance monitor control register */
+        uint64_t c9_pmcnten; /* perf monitor counter enables */
         uint32_t c9_pmovsr; /* perf monitor overflow status */
         uint32_t c9_pmxevtyper; /* perf monitor event type */
         uint32_t c9_pmuserenr; /* perf monitor user enable */
@@ -225,6 +225,7 @@ typedef struct CPUARMState {
          * was reset. Otherwise it stores the counter value
          */
         uint64_t c15_ccnt;
+        uint64_t pmccfiltr_el0; /* Performance Monitor Filter Register */
     } cp15;
 
     struct {
diff --git a/target-arm/helper.c b/target-arm/helper.c
index 0d2ee41..13507f7 100644
--- a/target-arm/helper.c
+++ b/target-arm/helper.c
@@ -736,16 +736,28 @@ static const ARMCPRegInfo v7_cp_reginfo[] = {
      * or PL0_RO as appropriate and then check PMUSERENR in the helper fn.
      */
     { .name = "PMCNTENSET", .cp = 15, .crn = 9, .crm = 12, .opc1 = 0, .opc2 = 1,
-      .access = PL0_RW, .resetvalue = 0,
-      .fieldoffset = offsetof(CPUARMState, cp15.c9_pmcnten),
+      .access = PL0_RW, .type = ARM_CP_NO_MIGRATE,
+      .fieldoffset = offsetoflow32(CPUARMState, cp15.c9_pmcnten),
       .writefn = pmcntenset_write,
       .accessfn = pmreg_access,
       .raw_writefn = raw_write },
+    { .name = "PMCNTENSET_EL0", .state = ARM_CP_STATE_AA64,
+      .opc0 = 3, .opc1 = 3, .crn = 9, .crm = 12, .opc2 = 1,
+      .access = PL0_RW, .accessfn = pmreg_access,
+      .fieldoffset = offsetof(CPUARMState, cp15.c9_pmcnten), .resetvalue = 0,
+      .writefn = pmcntenset_write, .raw_writefn = raw_write },
     { .name = "PMCNTENCLR", .cp = 15, .crn = 9, .crm = 12, .opc1 = 0, .opc2 = 2,
-      .access = PL0_RW, .fieldoffset = offsetof(CPUARMState, cp15.c9_pmcnten),
+      .access = PL0_RW,
+      .fieldoffset = offsetoflow32(CPUARMState, cp15.c9_pmcnten),
       .accessfn = pmreg_access,
       .writefn = pmcntenclr_write,
       .type = ARM_CP_NO_MIGRATE },
+    { .name = "PMCNTENCLR_EL0", .state = ARM_CP_STATE_AA64,
+      .opc0 = 3, .opc1 = 3, .crn = 9, .crm = 12, .opc2 = 2,
+      .access = PL0_RW, .accessfn = pmreg_access,
+      .type = ARM_CP_NO_MIGRATE,
+      .fieldoffset = offsetof(CPUARMState, cp15.c9_pmcnten),
+      .writefn = pmcntenclr_write },
     { .name = "PMOVSR", .cp = 15, .crn = 9, .crm = 12, .opc1 = 0, .opc2 = 3,
       .access = PL0_RW, .fieldoffset = offsetof(CPUARMState, cp15.c9_pmovsr),
       .accessfn = pmreg_access,
@@ -765,7 +777,18 @@ static const ARMCPRegInfo v7_cp_reginfo[] = {
       .access = PL0_RW, .resetvalue = 0, .type = ARM_CP_IO,
       .readfn = pmccntr_read, .writefn = pmccntr_write32,
       .accessfn = pmreg_access },
+    { .name = "PMCCNTR_EL0", .state = ARM_CP_STATE_AA64,
+      .opc0 = 3, .opc1 = 3, .crn = 9, .crm = 13, .opc2 = 0,
+      .access = PL0_RW, .accessfn = pmreg_access,
+      .type = ARM_CP_IO,
+      .readfn = pmccntr_read, .writefn = pmccntr_write, },
 #endif
+    { .name = "PMCCFILTR_EL0", .state = ARM_CP_STATE_AA64,
+      .opc0 = 3, .opc1 = 3, .crn = 14, .crm = 15, .opc2 = 7,
+      .access = PL0_RW, .accessfn = pmreg_access,
+      .type = ARM_CP_IO,
+      .fieldoffset = offsetof(CPUARMState, cp15.pmccfiltr_el0),
+      .resetvalue = 0, },
     { .name = "PMXEVTYPER", .cp = 15, .crn = 9, .crm = 13, .opc1 = 0, .opc2 = 1,
       .access = PL0_RW,
       .fieldoffset = offsetof(CPUARMState, cp15.c9_pmxevtyper),
@@ -2394,13 +2417,23 @@ void register_cp_regs_for_features(ARMCPU *cpu)
 #ifndef CONFIG_USER_ONLY
         ARMCPRegInfo pmcr = {
             .name = "PMCR", .cp = 15, .crn = 9, .crm = 12, .opc1 = 0, .opc2 = 0,
-            .access = PL0_RW, .resetvalue = cpu->midr & 0xff000000,
-            .type = ARM_CP_IO,
-            .fieldoffset = offsetof(CPUARMState, cp15.c9_pmcr),
+            .access = PL0_RW,
+            .type = ARM_CP_IO | ARM_CP_NO_MIGRATE,
+            .fieldoffset = offsetoflow32(CPUARMState, cp15.c9_pmcr),
             .accessfn = pmreg_access, .writefn = pmcr_write,
             .raw_writefn = raw_write,
         };
+        ARMCPRegInfo pmcr64 = {
+            .name = "PMCR_EL0", .state = ARM_CP_STATE_AA64,
+            .opc0 = 3, .opc1 = 3, .crn = 9, .crm = 12, .opc2 = 0,
+            .access = PL0_RW, .accessfn = pmreg_access,
+            .type = ARM_CP_IO,
+            .fieldoffset = offsetof(CPUARMState, cp15.c9_pmcr),
+            .resetvalue = cpu->midr & 0xff000000,
+            .writefn = pmcr_write, .raw_writefn = raw_write,
+        };
         define_one_arm_cp_reg(cpu, &pmcr);
+        define_one_arm_cp_reg(cpu, &pmcr64);
 #endif
         ARMCPRegInfo clidr = {
             .name = "CLIDR", .state = ARM_CP_STATE_BOTH,
commit 421c7ebd93d33a3276b78985b9e25cfea35692f0
Author: Peter Crosthwaite <peter.crosthwaite at xilinx.com>
Date:   Fri Aug 29 15:00:29 2014 +0100

    arm: Implement PMCCNTR 32b read-modify-write
    
    The register is now 64bit, however a 32 bit write to the register
    should leave the higher bits unchanged. The open coded write handler
    does not implement this, so we need to read-modify-write accordingly.
    
    Signed-off-by: Peter Crosthwaite <peter.crosthwaite at xilinx.com>
    Reviewed-by: Alistair Francis <alistair23 at gmail.com>
    Message-id: ec350573424bb2adc1701c3b9278d26598e2f2d1.1409025949.git.peter.crosthwaite at xilinx.com
    Signed-off-by: Peter Maydell <peter.maydell at linaro.org>

diff --git a/target-arm/helper.c b/target-arm/helper.c
index 711ca12..0d2ee41 100644
--- a/target-arm/helper.c
+++ b/target-arm/helper.c
@@ -623,6 +623,15 @@ static void pmccntr_write(CPUARMState *env, const ARMCPRegInfo *ri,
     }
     env->cp15.c15_ccnt = total_ticks - value;
 }
+
+static void pmccntr_write32(CPUARMState *env, const ARMCPRegInfo *ri,
+                            uint64_t value)
+{
+    uint64_t cur_val = pmccntr_read(env, NULL);
+
+    pmccntr_write(env, ri, deposit64(cur_val, 0, 32, value));
+}
+
 #endif
 
 static void pmcntenset_write(CPUARMState *env, const ARMCPRegInfo *ri,
@@ -754,7 +763,7 @@ static const ARMCPRegInfo v7_cp_reginfo[] = {
 #ifndef CONFIG_USER_ONLY
     { .name = "PMCCNTR", .cp = 15, .crn = 9, .crm = 13, .opc1 = 0, .opc2 = 0,
       .access = PL0_RW, .resetvalue = 0, .type = ARM_CP_IO,
-      .readfn = pmccntr_read, .writefn = pmccntr_write,
+      .readfn = pmccntr_read, .writefn = pmccntr_write32,
       .accessfn = pmreg_access },
 #endif
     { .name = "PMXEVTYPER", .cp = 15, .crn = 9, .crm = 13, .opc1 = 0, .opc2 = 1,
commit c92c06872a092eaba64ea7e56ceff762be48b093
Author: Alistair Francis <alistair.francis at xilinx.com>
Date:   Fri Aug 29 15:00:29 2014 +0100

    target-arm: Make the ARM PMCCNTR register 64-bit
    
    This makes the PMCCNTR register 64-bit to allow for the
    64-bit ARMv8 version.
    
    Signed-off-by: Peter Crosthwaite <peter.crosthwaite at xilinx.com>
    Signed-off-by: Alistair Francis <alistair.francis at xilinx.com>
    Message-id: 6c5bac5fd0ea54963b1fc0e7f9464909f2e19a73.1409025949.git.peter.crosthwaite at xilinx.com
    Signed-off-by: Peter Maydell <peter.maydell at linaro.org>

diff --git a/target-arm/cpu.h b/target-arm/cpu.h
index 659b104..986c249 100644
--- a/target-arm/cpu.h
+++ b/target-arm/cpu.h
@@ -224,7 +224,7 @@ typedef struct CPUARMState {
         /* If the counter is enabled, this stores the last time the counter
          * was reset. Otherwise it stores the counter value
          */
-        uint32_t c15_ccnt;
+        uint64_t c15_ccnt;
     } cp15;
 
     struct {
diff --git a/target-arm/helper.c b/target-arm/helper.c
index 2a77c97..711ca12 100644
--- a/target-arm/helper.c
+++ b/target-arm/helper.c
@@ -551,11 +551,10 @@ static CPAccessResult pmreg_access(CPUARMState *env, const ARMCPRegInfo *ri)
 static void pmcr_write(CPUARMState *env, const ARMCPRegInfo *ri,
                        uint64_t value)
 {
-    /* Don't computer the number of ticks in user mode */
-    uint32_t temp_ticks;
+    uint64_t temp_ticks;
 
-    temp_ticks = qemu_clock_get_us(QEMU_CLOCK_VIRTUAL) *
-                  get_ticks_per_sec() / 1000000;
+    temp_ticks = muldiv64(qemu_clock_get_us(QEMU_CLOCK_VIRTUAL),
+                          get_ticks_per_sec(), 1000000);
 
     if (env->cp15.c9_pmcr & PMCRE) {
         /* If the counter is enabled */
@@ -587,15 +586,15 @@ static void pmcr_write(CPUARMState *env, const ARMCPRegInfo *ri,
 
 static uint64_t pmccntr_read(CPUARMState *env, const ARMCPRegInfo *ri)
 {
-    uint32_t total_ticks;
+    uint64_t total_ticks;
 
     if (!(env->cp15.c9_pmcr & PMCRE)) {
         /* Counter is disabled, do not change value */
         return env->cp15.c15_ccnt;
     }
 
-    total_ticks = qemu_clock_get_us(QEMU_CLOCK_VIRTUAL) *
-                  get_ticks_per_sec() / 1000000;
+    total_ticks = muldiv64(qemu_clock_get_us(QEMU_CLOCK_VIRTUAL),
+                           get_ticks_per_sec(), 1000000);
 
     if (env->cp15.c9_pmcr & PMCRD) {
         /* Increment once every 64 processor clock cycles */
@@ -607,7 +606,7 @@ static uint64_t pmccntr_read(CPUARMState *env, const ARMCPRegInfo *ri)
 static void pmccntr_write(CPUARMState *env, const ARMCPRegInfo *ri,
                         uint64_t value)
 {
-    uint32_t total_ticks;
+    uint64_t total_ticks;
 
     if (!(env->cp15.c9_pmcr & PMCRE)) {
         /* Counter is disabled, set the absolute value */
@@ -615,8 +614,8 @@ static void pmccntr_write(CPUARMState *env, const ARMCPRegInfo *ri,
         return;
     }
 
-    total_ticks = qemu_clock_get_us(QEMU_CLOCK_VIRTUAL) *
-                  get_ticks_per_sec() / 1000000;
+    total_ticks = muldiv64(qemu_clock_get_us(QEMU_CLOCK_VIRTUAL),
+                           get_ticks_per_sec(), 1000000);
 
     if (env->cp15.c9_pmcr & PMCRD) {
         /* Increment once every 64 processor clock cycles */
commit b52b81e44f7d087a7b06217eb83cd79f8bf2fb05
Author: Sergey Fedorov <serge.fdrv at gmail.com>
Date:   Fri Aug 29 15:00:29 2014 +0100

    hw/intc/arm_gic: honor target mask in gic_update()
    
    Take IRQ target mask into account when determining the highest priority
    pending interrupt.
    
    Signed-off-by: Sergey Fedorov <serge.fdrv at gmail.com>
    Acked-by: Christoffer Dall <christoffer.dall at linaro.org>
    Message-id: 1407947471-26981-1-git-send-email-serge.fdrv at gmail.com
    Signed-off-by: Peter Maydell <peter.maydell at linaro.org>

diff --git a/hw/intc/arm_gic.c b/hw/intc/arm_gic.c
index 55019c9..db9110c 100644
--- a/hw/intc/arm_gic.c
+++ b/hw/intc/arm_gic.c
@@ -66,7 +66,8 @@ void gic_update(GICState *s)
         best_prio = 0x100;
         best_irq = 1023;
         for (irq = 0; irq < s->num_irq; irq++) {
-            if (GIC_TEST_ENABLED(irq, cm) && gic_test_pending(s, irq, cm)) {
+            if (GIC_TEST_ENABLED(irq, cm) && gic_test_pending(s, irq, cm) &&
+                (irq < GIC_INTERNAL || GIC_TARGET(irq) & cm)) {
                 if (GIC_GET_PRIORITY(irq, cpu) < best_prio) {
                     best_prio = GIC_GET_PRIORITY(irq, cpu);
                     best_irq = irq;
commit d3579f362f61addb6b8b9c683f398d29af47eb23
Author: Joel Schopp <joel.schopp at amd.com>
Date:   Fri Aug 29 15:00:29 2014 +0100

    aarch64: raise max_cpus to 8
    
    I'm running on a system with 8 cpus and it would be nice to have qemu
    support all of them.  The attached patch does that and has been tested.
    
    That said, I'm not sure if 8 is enough or if we want to bump this even higher
    now before systems with many more cpus come along. 255 anyone?
    
    Cc: Peter Maydell <peter.maydell at linaro.org>
    Signed-off-by: Joel Schopp <joel.schopp at amd.com>
    Message-id: 20140819213304.19537.2834.stgit at joelaarch64.amd.com
    Signed-off-by: Peter Maydell <peter.maydell at linaro.org>

diff --git a/hw/arm/virt.c b/hw/arm/virt.c
index bd206a0..d6fffc7 100644
--- a/hw/arm/virt.c
+++ b/hw/arm/virt.c
@@ -541,7 +541,7 @@ static QEMUMachine machvirt_a15_machine = {
     .name = "virt",
     .desc = "ARM Virtual Machine",
     .init = machvirt_init,
-    .max_cpus = 4,
+    .max_cpus = 8,
 };
 
 static void machvirt_machine_init(void)
commit 93b5f6f1a630f8db141d7ce9030d4fc2e3fa5b14
Author: Adam Lackorzynski <adam at os.inf.tu-dresden.de>
Date:   Fri Aug 29 15:00:29 2014 +0100

    arm_gic: Use GIC_NR_SGIS constant
    
    Use constant rather than a plain number.
    
    Acked-by: Christoffer Dall <christoffer.dall at linaro.org>
    Signed-off-by: Adam Lackorzynski <adam at os.inf.tu-dresden.de>
    Message-id: 1408372255-12358-5-git-send-email-adam at os.inf.tu-dresden.de
    Signed-off-by: Peter Maydell <peter.maydell at linaro.org>

diff --git a/hw/intc/arm_gic_common.c b/hw/intc/arm_gic_common.c
index 6d884ec..18b01ba 100644
--- a/hw/intc/arm_gic_common.c
+++ b/hw/intc/arm_gic_common.c
@@ -128,7 +128,7 @@ static void arm_gic_common_reset(DeviceState *dev)
         s->running_priority[i] = 0x100;
         s->cpu_enabled[i] = false;
     }
-    for (i = 0; i < 16; i++) {
+    for (i = 0; i < GIC_NR_SGIS; i++) {
         GIC_SET_ENABLED(i, ALL_CPU_MASK);
         GIC_SET_EDGE_TRIGGER(i);
     }
commit de7a900f0cdeeb5ebcb9d4a56cba2f0da7477001
Author: Adam Lackorzynski <adam at os.inf.tu-dresden.de>
Date:   Fri Aug 29 15:00:28 2014 +0100

    arm_gic: Do not force PPIs to edge-triggered mode
    
    Only SGIs must be WI, done by forcing them to their default
    (edge-triggered).
    
    Acked-by: Christoffer Dall <christoffer.dall at linaro.org>
    Signed-off-by: Adam Lackorzynski <adam at os.inf.tu-dresden.de>
    Message-id: 1408372255-12358-4-git-send-email-adam at os.inf.tu-dresden.de
    Signed-off-by: Peter Maydell <peter.maydell at linaro.org>

diff --git a/hw/intc/arm_gic.c b/hw/intc/arm_gic.c
index e546647..55019c9 100644
--- a/hw/intc/arm_gic.c
+++ b/hw/intc/arm_gic.c
@@ -558,7 +558,7 @@ static void gic_dist_writeb(void *opaque, hwaddr offset,
         irq = (offset - 0xc00) * 4 + GIC_BASE_IRQ;
         if (irq >= s->num_irq)
             goto bad_reg;
-        if (irq < GIC_INTERNAL)
+        if (irq < GIC_NR_SGIS)
             value |= 0xaa;
         for (i = 0; i < 4; i++) {
             if (s->revision == REV_11MPCORE || s->revision == REV_NVIC) {
commit 24b790df4388009c25cee311a4eff792c89cada1
Author: Adam Lackorzynski <adam at os.inf.tu-dresden.de>
Date:   Fri Aug 29 15:00:28 2014 +0100

    arm_gic: GICD_ICFGR: Write model only for pre v1 GICs
    
    Setting the model is only available in pre-v1 GIC models.
    
    Acked-by: Christoffer Dall <christoffer.dall at linaro.org>
    Signed-off-by: Adam Lackorzynski <adam at os.inf.tu-dresden.de>
    Message-id: 1408372255-12358-3-git-send-email-adam at os.inf.tu-dresden.de
    Signed-off-by: Peter Maydell <peter.maydell at linaro.org>

diff --git a/hw/intc/arm_gic.c b/hw/intc/arm_gic.c
index d2b1aaf..e546647 100644
--- a/hw/intc/arm_gic.c
+++ b/hw/intc/arm_gic.c
@@ -561,10 +561,12 @@ static void gic_dist_writeb(void *opaque, hwaddr offset,
         if (irq < GIC_INTERNAL)
             value |= 0xaa;
         for (i = 0; i < 4; i++) {
-            if (value & (1 << (i * 2))) {
-                GIC_SET_MODEL(irq + i);
-            } else {
-                GIC_CLEAR_MODEL(irq + i);
+            if (s->revision == REV_11MPCORE || s->revision == REV_NVIC) {
+                if (value & (1 << (i * 2))) {
+                    GIC_SET_MODEL(irq + i);
+                } else {
+                    GIC_CLEAR_MODEL(irq + i);
+                }
             }
             if (value & (2 << (i * 2))) {
                 GIC_SET_EDGE_TRIGGER(irq + i);
commit 71a62046ae7accb4fdd4b2413a77342fc5e0c554
Author: Adam Lackorzynski <adam at os.inf.tu-dresden.de>
Date:   Fri Aug 29 15:00:28 2014 +0100

    arm_gic: Fix read of GICD_ICFGR
    
    The GICD_ICFGR register covers 4 interrupts per byte.
    
    Acked-by: Christoffer Dall <christoffer.dall at linaro.org>
    Signed-off-by: Adam Lackorzynski <adam at os.inf.tu-dresden.de>
    Message-id: 1408372255-12358-2-git-send-email-adam at os.inf.tu-dresden.de
    Signed-off-by: Peter Maydell <peter.maydell at linaro.org>

diff --git a/hw/intc/arm_gic.c b/hw/intc/arm_gic.c
index 1532ef9..d2b1aaf 100644
--- a/hw/intc/arm_gic.c
+++ b/hw/intc/arm_gic.c
@@ -372,7 +372,7 @@ static uint32_t gic_dist_readb(void *opaque, hwaddr offset)
         }
     } else if (offset < 0xf00) {
         /* Interrupt Configuration.  */
-        irq = (offset - 0xc00) * 2 + GIC_BASE_IRQ;
+        irq = (offset - 0xc00) * 4 + GIC_BASE_IRQ;
         if (irq >= s->num_irq)
             goto bad_reg;
         res = 0;
commit c379621451e64cad166a60f42e1d67f0438b8d1b
Author: Peter Maydell <peter.maydell at linaro.org>
Date:   Fri Aug 29 15:00:28 2014 +0100

    target-arm: Correct Cortex-A57 ISAR5 and AA64ISAR0 ID register values
    
    We implement the crypto extensions but were incorrectly reporting
    ID register values for the Cortex-A57 which did not advertise
    crypto. Use the correct values as described in the TRM.
    With this fix Linux correctly detects presence of the crypto
    features and advertises them in /proc/cpuinfo.
    
    Reported-by: Ard Biesheuvel <ard.biesheuvel at linaro.org>
    Signed-off-by: Peter Maydell <peter.maydell at linaro.org>
    Message-id: 1408718660-7295-1-git-send-email-peter.maydell at linaro.org
    Cc: qemu-stable at nongnu.org
    Signed-off-by: Peter Maydell <peter.maydell at linaro.org>

diff --git a/target-arm/cpu64.c b/target-arm/cpu64.c
index 38d2b84..aa42803 100644
--- a/target-arm/cpu64.c
+++ b/target-arm/cpu64.c
@@ -123,9 +123,10 @@ static void aarch64_a57_initfn(Object *obj)
     cpu->id_isar2 = 0x21232042;
     cpu->id_isar3 = 0x01112131;
     cpu->id_isar4 = 0x00011142;
+    cpu->id_isar5 = 0x00011121;
     cpu->id_aa64pfr0 = 0x00002222;
     cpu->id_aa64dfr0 = 0x10305106;
-    cpu->id_aa64isar0 = 0x00010000;
+    cpu->id_aa64isar0 = 0x00011120;
     cpu->id_aa64mmfr0 = 0x00001124;
     cpu->dbgdidr = 0x3516d000;
     cpu->clidr = 0x0a200023;
commit ed1f13d607e2c64c66bea49d6f4edaf278d3d246
Author: Peter Maydell <peter.maydell at linaro.org>
Date:   Fri Aug 29 15:00:28 2014 +0100

    target-arm: Fix regression that disabled VFP for ARMv5 CPUs
    
    Commit 2c7ffc414 added support for honouring the CPACR coprocessor
    access control register bits which may disable access to VFP
    and Neon instructions. However it failed to account for the
    fact that the CPACR is only present starting from the ARMv6
    architecture version, so it accidentally disabled VFP completely
    for ARMv5 CPUs like the ARM926. Linux would detect this as
    "no VFP present" and probably fall back to its own emulation,
    but other guest OSes might crash or misbehave.
    
    This fixes bug LP:1359930.
    
    Reported-by: Jakub Jermar <jakub at jermar.eu>
    Signed-off-by: Peter Maydell <peter.maydell at linaro.org>
    Message-id: 1408714940-7192-1-git-send-email-peter.maydell at linaro.org
    Cc: qemu-stable at nongnu.org
    Signed-off-by: Peter Maydell <peter.maydell at linaro.org>

diff --git a/target-arm/cpu.h b/target-arm/cpu.h
index 8098b8d..659b104 100644
--- a/target-arm/cpu.h
+++ b/target-arm/cpu.h
@@ -1255,7 +1255,14 @@ static inline bool arm_singlestep_active(CPUARMState *env)
 static inline void cpu_get_tb_cpu_state(CPUARMState *env, target_ulong *pc,
                                         target_ulong *cs_base, int *flags)
 {
-    int fpen = extract32(env->cp15.c1_coproc, 20, 2);
+    int fpen;
+
+    if (arm_feature(env, ARM_FEATURE_V6)) {
+        fpen = extract32(env->cp15.c1_coproc, 20, 2);
+    } else {
+        /* CPACR doesn't exist before v6, so VFP is always accessible */
+        fpen = 3;
+    }
 
     if (is_a64(env)) {
         *pc = env->pc;
commit 508280f5666a706a3681462b2a1d7de8107fd6fb
Author: Peter Maydell <peter.maydell at linaro.org>
Date:   Fri Aug 29 15:00:27 2014 +0100

    disas/libvixl: Update to upstream VIXL 1.5
    
    Update our copy of libvixl to upstream's 1.5 release.
    This includes the upstream versions of the fixes we
    were carrying locally (commit ffebe899).
    
    Signed-off-by: Peter Maydell <peter.maydell at linaro.org>
    Message-id: 1407162987-4659-1-git-send-email-peter.maydell at linaro.org

diff --git a/disas/libvixl/README b/disas/libvixl/README
index a0ecac3..8301996 100644
--- a/disas/libvixl/README
+++ b/disas/libvixl/README
@@ -2,7 +2,7 @@
 The code in this directory is a subset of libvixl:
  https://github.com/armvixl/vixl
 (specifically, it is the set of files needed for disassembly only,
-taken from libvixl 1.4).
+taken from libvixl 1.5).
 Bugfixes should preferably be sent upstream initially.
 
 The disassembler does not currently support the entire A64 instruction
diff --git a/disas/libvixl/a64/assembler-a64.h b/disas/libvixl/a64/assembler-a64.h
index 1e2947b..cc0b758 100644
--- a/disas/libvixl/a64/assembler-a64.h
+++ b/disas/libvixl/a64/assembler-a64.h
@@ -28,6 +28,7 @@
 #define VIXL_A64_ASSEMBLER_A64_H_
 
 #include <list>
+#include <stack>
 
 #include "globals.h"
 #include "utils.h"
@@ -574,34 +575,107 @@ class MemOperand {
 
 class Label {
  public:
-  Label() : is_bound_(false), link_(NULL), target_(NULL) {}
+  Label() : location_(kLocationUnbound) {}
   ~Label() {
     // If the label has been linked to, it needs to be bound to a target.
     VIXL_ASSERT(!IsLinked() || IsBound());
   }
 
-  inline Instruction* link() const { return link_; }
-  inline Instruction* target() const { return target_; }
+  inline bool IsBound() const { return location_ >= 0; }
+  inline bool IsLinked() const { return !links_.empty(); }
 
-  inline bool IsBound() const { return is_bound_; }
-  inline bool IsLinked() const { return link_ != NULL; }
+ private:
+  // The list of linked instructions is stored in a stack-like structure. We
+  // don't use std::stack directly because it's slow for the common case where
+  // only one or two instructions refer to a label, and labels themselves are
+  // short-lived. This class behaves like std::stack, but the first few links
+  // are preallocated (configured by kPreallocatedLinks).
+  //
+  // If more than N links are required, this falls back to std::stack.
+  class LinksStack {
+   public:
+    LinksStack() : size_(0), links_extended_(NULL) {}
+    ~LinksStack() {
+      delete links_extended_;
+    }
 
-  inline void set_link(Instruction* new_link) { link_ = new_link; }
+    size_t size() const {
+      return size_;
+    }
 
-  static const int kEndOfChain = 0;
+    bool empty() const {
+      return size_ == 0;
+    }
 
- private:
-  // Indicates if the label has been bound, ie its location is fixed.
-  bool is_bound_;
-  // Branches instructions branching to this label form a chained list, with
-  // their offset indicating where the next instruction is located.
-  // link_ points to the latest branch instruction generated branching to this
-  // branch.
-  // If link_ is not NULL, the label has been linked to.
-  Instruction* link_;
+    void push(ptrdiff_t value) {
+      if (size_ < kPreallocatedLinks) {
+        links_[size_] = value;
+      } else {
+        if (links_extended_ == NULL) {
+          links_extended_ = new std::stack<ptrdiff_t>();
+        }
+        VIXL_ASSERT(size_ == (links_extended_->size() + kPreallocatedLinks));
+        links_extended_->push(value);
+      }
+      size_++;
+    }
+
+    ptrdiff_t top() const {
+      return (size_ <= kPreallocatedLinks) ? links_[size_ - 1]
+                                           : links_extended_->top();
+    }
+
+    void pop() {
+      size_--;
+      if (size_ >= kPreallocatedLinks) {
+        links_extended_->pop();
+        VIXL_ASSERT(size_ == (links_extended_->size() + kPreallocatedLinks));
+      }
+    }
+
+   private:
+    static const size_t kPreallocatedLinks = 4;
+
+    size_t size_;
+    ptrdiff_t links_[kPreallocatedLinks];
+    std::stack<ptrdiff_t> * links_extended_;
+  };
+
+  inline ptrdiff_t location() const { return location_; }
+
+  inline void Bind(ptrdiff_t location) {
+    // Labels can only be bound once.
+    VIXL_ASSERT(!IsBound());
+    location_ = location;
+  }
+
+  inline void AddLink(ptrdiff_t instruction) {
+    // If a label is bound, the assembler already has the information it needs
+    // to write the instruction, so there is no need to add it to links_.
+    VIXL_ASSERT(!IsBound());
+    links_.push(instruction);
+  }
+
+  inline ptrdiff_t GetAndRemoveNextLink() {
+    VIXL_ASSERT(IsLinked());
+    ptrdiff_t link = links_.top();
+    links_.pop();
+    return link;
+  }
+
+  // The offsets of the instructions that have linked to this label.
+  LinksStack links_;
   // The label location.
-  Instruction* target_;
+  ptrdiff_t location_;
 
+  static const ptrdiff_t kLocationUnbound = -1;
+
+  // It is not safe to copy labels, so disable the copy constructor by declaring
+  // it private (without an implementation).
+  Label(const Label&);
+
+  // The Assembler class is responsible for binding and linking labels, since
+  // the stored offsets need to be consistent with the Assembler's buffer.
   friend class Assembler;
 };
 
@@ -635,10 +709,49 @@ class Literal {
 };
 
 
+// Control whether or not position-independent code should be emitted.
+enum PositionIndependentCodeOption {
+  // All code generated will be position-independent; all branches and
+  // references to labels generated with the Label class will use PC-relative
+  // addressing.
+  PositionIndependentCode,
+
+  // Allow VIXL to generate code that refers to absolute addresses. With this
+  // option, it will not be possible to copy the code buffer and run it from a
+  // different address; code must be generated in its final location.
+  PositionDependentCode,
+
+  // Allow VIXL to assume that the bottom 12 bits of the address will be
+  // constant, but that the top 48 bits may change. This allows `adrp` to
+  // function in systems which copy code between pages, but otherwise maintain
+  // 4KB page alignment.
+  PageOffsetDependentCode
+};
+
+
+// Control how scaled- and unscaled-offset loads and stores are generated.
+enum LoadStoreScalingOption {
+  // Prefer scaled-immediate-offset instructions, but emit unscaled-offset,
+  // register-offset, pre-index or post-index instructions if necessary.
+  PreferScaledOffset,
+
+  // Prefer unscaled-immediate-offset instructions, but emit scaled-offset,
+  // register-offset, pre-index or post-index instructions if necessary.
+  PreferUnscaledOffset,
+
+  // Require scaled-immediate-offset instructions.
+  RequireScaledOffset,
+
+  // Require unscaled-immediate-offset instructions.
+  RequireUnscaledOffset
+};
+
+
 // Assembler.
 class Assembler {
  public:
-  Assembler(byte* buffer, unsigned buffer_size);
+  Assembler(byte* buffer, unsigned buffer_size,
+            PositionIndependentCodeOption pic = PositionIndependentCode);
 
   // The destructor asserts that one of the following is true:
   //  * The Assembler object has not been used.
@@ -662,12 +775,15 @@ class Assembler {
   // Label.
   // Bind a label to the current PC.
   void bind(Label* label);
-  int UpdateAndGetByteOffsetTo(Label* label);
-  inline int UpdateAndGetInstructionOffsetTo(Label* label) {
-    VIXL_ASSERT(Label::kEndOfChain == 0);
-    return UpdateAndGetByteOffsetTo(label) >> kInstructionSizeLog2;
-  }
 
+  // Return the address of a bound label.
+  template <typename T>
+  inline T GetLabelAddress(const Label * label) {
+    VIXL_ASSERT(label->IsBound());
+    VIXL_STATIC_ASSERT(sizeof(T) >= sizeof(uintptr_t));
+    VIXL_STATIC_ASSERT(sizeof(*buffer_) == 1);
+    return reinterpret_cast<T>(buffer_ + label->location());
+  }
 
   // Instruction set functions.
 
@@ -733,6 +849,12 @@ class Assembler {
   // Calculate the address of a PC offset.
   void adr(const Register& rd, int imm21);
 
+  // Calculate the page address of a label.
+  void adrp(const Register& rd, Label* label);
+
+  // Calculate the page address of a PC offset.
+  void adrp(const Register& rd, int imm21);
+
   // Data Processing instructions.
   // Add.
   void add(const Register& rd,
@@ -1112,31 +1234,76 @@ class Assembler {
 
   // Memory instructions.
   // Load integer or FP register.
-  void ldr(const CPURegister& rt, const MemOperand& src);
+  void ldr(const CPURegister& rt, const MemOperand& src,
+           LoadStoreScalingOption option = PreferScaledOffset);
 
   // Store integer or FP register.
-  void str(const CPURegister& rt, const MemOperand& dst);
+  void str(const CPURegister& rt, const MemOperand& dst,
+           LoadStoreScalingOption option = PreferScaledOffset);
 
   // Load word with sign extension.
-  void ldrsw(const Register& rt, const MemOperand& src);
+  void ldrsw(const Register& rt, const MemOperand& src,
+             LoadStoreScalingOption option = PreferScaledOffset);
 
   // Load byte.
-  void ldrb(const Register& rt, const MemOperand& src);
+  void ldrb(const Register& rt, const MemOperand& src,
+            LoadStoreScalingOption option = PreferScaledOffset);
 
   // Store byte.
-  void strb(const Register& rt, const MemOperand& dst);
+  void strb(const Register& rt, const MemOperand& dst,
+            LoadStoreScalingOption option = PreferScaledOffset);
 
   // Load byte with sign extension.
-  void ldrsb(const Register& rt, const MemOperand& src);
+  void ldrsb(const Register& rt, const MemOperand& src,
+             LoadStoreScalingOption option = PreferScaledOffset);
 
   // Load half-word.
-  void ldrh(const Register& rt, const MemOperand& src);
+  void ldrh(const Register& rt, const MemOperand& src,
+            LoadStoreScalingOption option = PreferScaledOffset);
 
   // Store half-word.
-  void strh(const Register& rt, const MemOperand& dst);
+  void strh(const Register& rt, const MemOperand& dst,
+            LoadStoreScalingOption option = PreferScaledOffset);
 
   // Load half-word with sign extension.
-  void ldrsh(const Register& rt, const MemOperand& src);
+  void ldrsh(const Register& rt, const MemOperand& src,
+             LoadStoreScalingOption option = PreferScaledOffset);
+
+  // Load integer or FP register (with unscaled offset).
+  void ldur(const CPURegister& rt, const MemOperand& src,
+            LoadStoreScalingOption option = PreferUnscaledOffset);
+
+  // Store integer or FP register (with unscaled offset).
+  void stur(const CPURegister& rt, const MemOperand& src,
+            LoadStoreScalingOption option = PreferUnscaledOffset);
+
+  // Load word with sign extension.
+  void ldursw(const Register& rt, const MemOperand& src,
+              LoadStoreScalingOption option = PreferUnscaledOffset);
+
+  // Load byte (with unscaled offset).
+  void ldurb(const Register& rt, const MemOperand& src,
+             LoadStoreScalingOption option = PreferUnscaledOffset);
+
+  // Store byte (with unscaled offset).
+  void sturb(const Register& rt, const MemOperand& dst,
+             LoadStoreScalingOption option = PreferUnscaledOffset);
+
+  // Load byte with sign extension (and unscaled offset).
+  void ldursb(const Register& rt, const MemOperand& src,
+              LoadStoreScalingOption option = PreferUnscaledOffset);
+
+  // Load half-word (with unscaled offset).
+  void ldurh(const Register& rt, const MemOperand& src,
+             LoadStoreScalingOption option = PreferUnscaledOffset);
+
+  // Store half-word (with unscaled offset).
+  void sturh(const Register& rt, const MemOperand& dst,
+             LoadStoreScalingOption option = PreferUnscaledOffset);
+
+  // Load half-word with sign extension (and unscaled offset).
+  void ldursh(const Register& rt, const MemOperand& src,
+              LoadStoreScalingOption option = PreferUnscaledOffset);
 
   // Load integer or FP register pair.
   void ldp(const CPURegister& rt, const CPURegister& rt2,
@@ -1166,6 +1333,79 @@ class Assembler {
   // Load single precision floating point literal to FP register.
   void ldr(const FPRegister& ft, float imm);
 
+  // Store exclusive byte.
+  void stxrb(const Register& rs, const Register& rt, const MemOperand& dst);
+
+  // Store exclusive half-word.
+  void stxrh(const Register& rs, const Register& rt, const MemOperand& dst);
+
+  // Store exclusive register.
+  void stxr(const Register& rs, const Register& rt, const MemOperand& dst);
+
+  // Load exclusive byte.
+  void ldxrb(const Register& rt, const MemOperand& src);
+
+  // Load exclusive half-word.
+  void ldxrh(const Register& rt, const MemOperand& src);
+
+  // Load exclusive register.
+  void ldxr(const Register& rt, const MemOperand& src);
+
+  // Store exclusive register pair.
+  void stxp(const Register& rs,
+            const Register& rt,
+            const Register& rt2,
+            const MemOperand& dst);
+
+  // Load exclusive register pair.
+  void ldxp(const Register& rt, const Register& rt2, const MemOperand& src);
+
+  // Store-release exclusive byte.
+  void stlxrb(const Register& rs, const Register& rt, const MemOperand& dst);
+
+  // Store-release exclusive half-word.
+  void stlxrh(const Register& rs, const Register& rt, const MemOperand& dst);
+
+  // Store-release exclusive register.
+  void stlxr(const Register& rs, const Register& rt, const MemOperand& dst);
+
+  // Load-acquire exclusive byte.
+  void ldaxrb(const Register& rt, const MemOperand& src);
+
+  // Load-acquire exclusive half-word.
+  void ldaxrh(const Register& rt, const MemOperand& src);
+
+  // Load-acquire exclusive register.
+  void ldaxr(const Register& rt, const MemOperand& src);
+
+  // Store-release exclusive register pair.
+  void stlxp(const Register& rs,
+             const Register& rt,
+             const Register& rt2,
+             const MemOperand& dst);
+
+  // Load-acquire exclusive register pair.
+  void ldaxp(const Register& rt, const Register& rt2, const MemOperand& src);
+
+  // Store-release byte.
+  void stlrb(const Register& rt, const MemOperand& dst);
+
+  // Store-release half-word.
+  void stlrh(const Register& rt, const MemOperand& dst);
+
+  // Store-release register.
+  void stlr(const Register& rt, const MemOperand& dst);
+
+  // Load-acquire byte.
+  void ldarb(const Register& rt, const MemOperand& src);
+
+  // Load-acquire half-word.
+  void ldarh(const Register& rt, const MemOperand& src);
+
+  // Load-acquire register.
+  void ldar(const Register& rt, const MemOperand& src);
+
+
   // Move instructions. The default shift of -1 indicates that the move
   // instruction will calculate an appropriate 16-bit immediate and left shift
   // that is equal to the 64-bit immediate argument. If an explicit left shift
@@ -1214,6 +1454,9 @@ class Assembler {
   // System hint.
   void hint(SystemHint code);
 
+  // Clear exclusive monitor.
+  void clrex(int imm4 = 0xf);
+
   // Data memory barrier.
   void dmb(BarrierDomain domain, BarrierType type);
 
@@ -1429,6 +1672,11 @@ class Assembler {
     return rt2.code() << Rt2_offset;
   }
 
+  static Instr Rs(CPURegister rs) {
+    VIXL_ASSERT(rs.code() != kSPRegInternalCode);
+    return rs.code() << Rs_offset;
+  }
+
   // These encoding functions allow the stack pointer to be encoded, and
   // disallow the zero register.
   static Instr RdSP(Register rd) {
@@ -1619,6 +1867,11 @@ class Assembler {
     return imm7 << ImmHint_offset;
   }
 
+  static Instr CRm(int imm4) {
+    VIXL_ASSERT(is_uint4(imm4));
+    return imm4 << CRm_offset;
+  }
+
   static Instr ImmBarrierDomain(int imm2) {
     VIXL_ASSERT(is_uint2(imm2));
     return imm2 << ImmBarrierDomain_offset;
@@ -1660,16 +1913,20 @@ class Assembler {
   }
 
   // Size of the code generated in bytes
-  uint64_t SizeOfCodeGenerated() const {
+  size_t SizeOfCodeGenerated() const {
     VIXL_ASSERT((pc_ >= buffer_) && (pc_ < (buffer_ + buffer_size_)));
     return pc_ - buffer_;
   }
 
   // Size of the code generated since label to the current position.
-  uint64_t SizeOfCodeGeneratedSince(Label* label) const {
+  size_t SizeOfCodeGeneratedSince(Label* label) const {
+    size_t pc_offset = SizeOfCodeGenerated();
+
     VIXL_ASSERT(label->IsBound());
-    VIXL_ASSERT((pc_ >= label->target()) && (pc_ < (buffer_ + buffer_size_)));
-    return pc_ - label->target();
+    VIXL_ASSERT(pc_offset >= static_cast<size_t>(label->location()));
+    VIXL_ASSERT(pc_offset < buffer_size_);
+
+    return pc_offset - label->location();
   }
 
 
@@ -1693,6 +1950,15 @@ class Assembler {
   void EmitLiteralPool(LiteralPoolEmitOption option = NoJumpRequired);
   size_t LiteralPoolSize();
 
+  inline PositionIndependentCodeOption pic() {
+    return pic_;
+  }
+
+  inline bool AllowPageOffsetDependentCode() {
+    return (pic() == PageOffsetDependentCode) ||
+           (pic() == PositionDependentCode);
+  }
+
  protected:
   inline const Register& AppropriateZeroRegFor(const CPURegister& reg) const {
     return reg.Is64Bits() ? xzr : wzr;
@@ -1701,7 +1967,8 @@ class Assembler {
 
   void LoadStore(const CPURegister& rt,
                  const MemOperand& addr,
-                 LoadStoreOp op);
+                 LoadStoreOp op,
+                 LoadStoreScalingOption option = PreferScaledOffset);
   static bool IsImmLSUnscaled(ptrdiff_t offset);
   static bool IsImmLSScaled(ptrdiff_t offset, LSDataSize size);
 
@@ -1717,9 +1984,9 @@ class Assembler {
                         LogicalOp op);
   static bool IsImmLogical(uint64_t value,
                            unsigned width,
-                           unsigned* n,
-                           unsigned* imm_s,
-                           unsigned* imm_r);
+                           unsigned* n = NULL,
+                           unsigned* imm_s = NULL,
+                           unsigned* imm_r = NULL);
 
   void ConditionalCompare(const Register& rn,
                           const Operand& operand,
@@ -1823,6 +2090,17 @@ class Assembler {
 
   void RecordLiteral(int64_t imm, unsigned size);
 
+  // Link the current (not-yet-emitted) instruction to the specified label, then
+  // return an offset to be encoded in the instruction. If the label is not yet
+  // bound, an offset of 0 is returned.
+  ptrdiff_t LinkAndGetByteOffsetTo(Label * label);
+  ptrdiff_t LinkAndGetInstructionOffsetTo(Label * label);
+  ptrdiff_t LinkAndGetPageOffsetTo(Label * label);
+
+  // A common implementation for the LinkAndGet<Type>OffsetTo helpers.
+  template <int element_size>
+  ptrdiff_t LinkAndGetOffsetTo(Label* label);
+
   // Emit the instruction at pc_.
   void Emit(Instr instruction) {
     VIXL_STATIC_ASSERT(sizeof(*pc_) == 1);
@@ -1864,12 +2142,15 @@ class Assembler {
   // The buffer into which code and relocation info are generated.
   Instruction* buffer_;
   // Buffer size, in bytes.
-  unsigned buffer_size_;
+  size_t buffer_size_;
   Instruction* pc_;
   std::list<Literal*> literals_;
   Instruction* next_literal_pool_check_;
   unsigned literal_pool_monitor_;
 
+  PositionIndependentCodeOption pic_;
+
+  friend class Label;
   friend class BlockLiteralPoolScope;
 
 #ifdef DEBUG
diff --git a/disas/libvixl/a64/constants-a64.h b/disas/libvixl/a64/constants-a64.h
index 99677c1..7a14f85 100644
--- a/disas/libvixl/a64/constants-a64.h
+++ b/disas/libvixl/a64/constants-a64.h
@@ -46,13 +46,13 @@ R(24) R(25) R(26) R(27) R(28) R(29) R(30) R(31)
 
 #define INSTRUCTION_FIELDS_LIST(V_)                                            \
 /* Register fields */                                                          \
-V_(Rd, 4, 0, Bits)                        /* Destination register.     */      \
-V_(Rn, 9, 5, Bits)                        /* First source register.    */      \
-V_(Rm, 20, 16, Bits)                      /* Second source register.   */      \
-V_(Ra, 14, 10, Bits)                      /* Third source register.    */      \
-V_(Rt, 4, 0, Bits)                        /* Load dest / store source. */      \
-V_(Rt2, 14, 10, Bits)                     /* Load second dest /        */      \
-                                         /* store second source.      */       \
+V_(Rd, 4, 0, Bits)                        /* Destination register.        */   \
+V_(Rn, 9, 5, Bits)                        /* First source register.       */   \
+V_(Rm, 20, 16, Bits)                      /* Second source register.      */   \
+V_(Ra, 14, 10, Bits)                      /* Third source register.       */   \
+V_(Rt, 4, 0, Bits)                        /* Load/store register.         */   \
+V_(Rt2, 14, 10, Bits)                     /* Load/store second register.  */   \
+V_(Rs, 20, 16, Bits)                      /* Exclusive access status.     */   \
 V_(PrefetchMode, 4, 0, Bits)                                                   \
                                                                                \
 /* Common bits */                                                              \
@@ -126,6 +126,13 @@ V_(SysOp1, 18, 16, Bits)                                                       \
 V_(SysOp2, 7, 5, Bits)                                                         \
 V_(CRn, 15, 12, Bits)                                                          \
 V_(CRm, 11, 8, Bits)                                                           \
+                                                                               \
+/* Load-/store-exclusive */                                                    \
+V_(LdStXLoad, 22, 22, Bits)                                                    \
+V_(LdStXNotExclusive, 23, 23, Bits)                                            \
+V_(LdStXAcquireRelease, 15, 15, Bits)                                          \
+V_(LdStXSizeLog2, 31, 30, Bits)                                                \
+V_(LdStXPair, 21, 21, Bits)                                                    \
 
 
 #define SYSTEM_REGISTER_FIELDS_LIST(V_, M_)                                    \
@@ -585,6 +592,13 @@ enum MemBarrierOp {
   ISB             = MemBarrierFixed | 0x00000040
 };
 
+enum SystemExclusiveMonitorOp {
+  SystemExclusiveMonitorFixed = 0xD503305F,
+  SystemExclusiveMonitorFMask = 0xFFFFF0FF,
+  SystemExclusiveMonitorMask  = 0xFFFFF0FF,
+  CLREX                       = SystemExclusiveMonitorFixed
+};
+
 // Any load or store.
 enum LoadStoreAnyOp {
   LoadStoreAnyFMask = 0x0a000000,
@@ -702,7 +716,7 @@ enum LoadStoreUnscaledOffsetOp {
 
 // Load/store (post, pre, offset and unsigned.)
 enum LoadStoreOp {
-  LoadStoreOpMask   = 0xC4C00000,
+  LoadStoreOpMask = 0xC4C00000,
   #define LOAD_STORE(A, B, C, D)  \
   A##B##_##C = D
   LOAD_STORE_OP_LIST(LOAD_STORE),
@@ -756,6 +770,44 @@ enum LoadStoreRegisterOffset {
   #undef LOAD_STORE_REGISTER_OFFSET
 };
 
+enum LoadStoreExclusive {
+  LoadStoreExclusiveFixed = 0x08000000,
+  LoadStoreExclusiveFMask = 0x3F000000,
+  LoadStoreExclusiveMask  = 0xFFE08000,
+  STXRB_w  = LoadStoreExclusiveFixed | 0x00000000,
+  STXRH_w  = LoadStoreExclusiveFixed | 0x40000000,
+  STXR_w   = LoadStoreExclusiveFixed | 0x80000000,
+  STXR_x   = LoadStoreExclusiveFixed | 0xC0000000,
+  LDXRB_w  = LoadStoreExclusiveFixed | 0x00400000,
+  LDXRH_w  = LoadStoreExclusiveFixed | 0x40400000,
+  LDXR_w   = LoadStoreExclusiveFixed | 0x80400000,
+  LDXR_x   = LoadStoreExclusiveFixed | 0xC0400000,
+  STXP_w   = LoadStoreExclusiveFixed | 0x80200000,
+  STXP_x   = LoadStoreExclusiveFixed | 0xC0200000,
+  LDXP_w   = LoadStoreExclusiveFixed | 0x80600000,
+  LDXP_x   = LoadStoreExclusiveFixed | 0xC0600000,
+  STLXRB_w = LoadStoreExclusiveFixed | 0x00008000,
+  STLXRH_w = LoadStoreExclusiveFixed | 0x40008000,
+  STLXR_w  = LoadStoreExclusiveFixed | 0x80008000,
+  STLXR_x  = LoadStoreExclusiveFixed | 0xC0008000,
+  LDAXRB_w = LoadStoreExclusiveFixed | 0x00408000,
+  LDAXRH_w = LoadStoreExclusiveFixed | 0x40408000,
+  LDAXR_w  = LoadStoreExclusiveFixed | 0x80408000,
+  LDAXR_x  = LoadStoreExclusiveFixed | 0xC0408000,
+  STLXP_w  = LoadStoreExclusiveFixed | 0x80208000,
+  STLXP_x  = LoadStoreExclusiveFixed | 0xC0208000,
+  LDAXP_w  = LoadStoreExclusiveFixed | 0x80608000,
+  LDAXP_x  = LoadStoreExclusiveFixed | 0xC0608000,
+  STLRB_w  = LoadStoreExclusiveFixed | 0x00808000,
+  STLRH_w  = LoadStoreExclusiveFixed | 0x40808000,
+  STLR_w   = LoadStoreExclusiveFixed | 0x80808000,
+  STLR_x   = LoadStoreExclusiveFixed | 0xC0808000,
+  LDARB_w  = LoadStoreExclusiveFixed | 0x00C08000,
+  LDARH_w  = LoadStoreExclusiveFixed | 0x40C08000,
+  LDAR_w   = LoadStoreExclusiveFixed | 0x80C08000,
+  LDAR_x   = LoadStoreExclusiveFixed | 0xC0C08000
+};
+
 // Conditional compare.
 enum ConditionalCompareOp {
   ConditionalCompareMask = 0x60000000,
diff --git a/disas/libvixl/a64/cpu-a64.h b/disas/libvixl/a64/cpu-a64.h
index dfd8f01..59b7974 100644
--- a/disas/libvixl/a64/cpu-a64.h
+++ b/disas/libvixl/a64/cpu-a64.h
@@ -28,6 +28,7 @@
 #define VIXL_CPU_A64_H
 
 #include "globals.h"
+#include "instructions-a64.h"
 
 namespace vixl {
 
@@ -42,6 +43,32 @@ class CPU {
   // safely run.
   static void EnsureIAndDCacheCoherency(void *address, size_t length);
 
+  // Handle tagged pointers.
+  template <typename T>
+  static T SetPointerTag(T pointer, uint64_t tag) {
+    VIXL_ASSERT(is_uintn(kAddressTagWidth, tag));
+
+    // Use C-style casts to get static_cast behaviour for integral types (T),
+    // and reinterpret_cast behaviour for other types.
+
+    uint64_t raw = (uint64_t)pointer;
+    VIXL_STATIC_ASSERT(sizeof(pointer) == sizeof(raw));
+
+    raw = (raw & ~kAddressTagMask) | (tag << kAddressTagOffset);
+    return (T)raw;
+  }
+
+  template <typename T>
+  static uint64_t GetPointerTag(T pointer) {
+    // Use C-style casts to get static_cast behaviour for integral types (T),
+    // and reinterpret_cast behaviour for other types.
+
+    uint64_t raw = (uint64_t)pointer;
+    VIXL_STATIC_ASSERT(sizeof(pointer) == sizeof(raw));
+
+    return (raw & kAddressTagMask) >> kAddressTagOffset;
+  }
+
  private:
   // Return the content of the cache type register.
   static uint32_t GetCacheType();
diff --git a/disas/libvixl/a64/decoder-a64.cc b/disas/libvixl/a64/decoder-a64.cc
index 8450eb3..5831b73 100644
--- a/disas/libvixl/a64/decoder-a64.cc
+++ b/disas/libvixl/a64/decoder-a64.cc
@@ -171,9 +171,9 @@ void Decoder::DecodePCRelAddressing(Instruction* instr) {
 
 void Decoder::DecodeBranchSystemException(Instruction* instr) {
   VIXL_ASSERT((instr->Bits(27, 24) == 0x4) ||
-         (instr->Bits(27, 24) == 0x5) ||
-         (instr->Bits(27, 24) == 0x6) ||
-         (instr->Bits(27, 24) == 0x7) );
+              (instr->Bits(27, 24) == 0x5) ||
+              (instr->Bits(27, 24) == 0x6) ||
+              (instr->Bits(27, 24) == 0x7) );
 
   switch (instr->Bits(31, 29)) {
     case 0:
@@ -272,16 +272,15 @@ void Decoder::DecodeBranchSystemException(Instruction* instr) {
 
 void Decoder::DecodeLoadStore(Instruction* instr) {
   VIXL_ASSERT((instr->Bits(27, 24) == 0x8) ||
-         (instr->Bits(27, 24) == 0x9) ||
-         (instr->Bits(27, 24) == 0xC) ||
-         (instr->Bits(27, 24) == 0xD) );
+              (instr->Bits(27, 24) == 0x9) ||
+              (instr->Bits(27, 24) == 0xC) ||
+              (instr->Bits(27, 24) == 0xD) );
 
   if (instr->Bit(24) == 0) {
     if (instr->Bit(28) == 0) {
       if (instr->Bit(29) == 0) {
         if (instr->Bit(26) == 0) {
-          // TODO: VisitLoadStoreExclusive.
-          VisitUnimplemented(instr);
+          VisitLoadStoreExclusive(instr);
         } else {
           DecodeAdvSIMDLoadStore(instr);
         }
diff --git a/disas/libvixl/a64/decoder-a64.h b/disas/libvixl/a64/decoder-a64.h
index bbbbd81..72c1519 100644
--- a/disas/libvixl/a64/decoder-a64.h
+++ b/disas/libvixl/a64/decoder-a64.h
@@ -59,6 +59,7 @@
   V(LoadStorePreIndex)              \
   V(LoadStoreRegisterOffset)        \
   V(LoadStoreUnsignedOffset)        \
+  V(LoadStoreExclusive)             \
   V(LogicalShifted)                 \
   V(AddSubShifted)                  \
   V(AddSubExtended)                 \
diff --git a/disas/libvixl/a64/disasm-a64.cc b/disas/libvixl/a64/disasm-a64.cc
index f81ce4b..248ebfd 100644
--- a/disas/libvixl/a64/disasm-a64.cc
+++ b/disas/libvixl/a64/disasm-a64.cc
@@ -24,6 +24,7 @@
 // OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 
+#include <cstdlib>
 #include "a64/disasm-a64.h"
 
 namespace vixl {
@@ -529,7 +530,7 @@ void Disassembler::VisitExtract(Instruction* instr) {
 void Disassembler::VisitPCRelAddressing(Instruction* instr) {
   switch (instr->Mask(PCRelAddressingMask)) {
     case ADR: Format(instr, "adr", "'Xd, 'AddrPCRelByte"); break;
-    // ADRP is not implemented.
+    case ADRP: Format(instr, "adrp", "'Xd, 'AddrPCRelPage"); break;
     default: Format(instr, "unimplemented", "(PCRelAddressing)");
   }
 }
@@ -943,6 +944,49 @@ void Disassembler::VisitLoadStorePairNonTemporal(Instruction* instr) {
 }
 
 
+void Disassembler::VisitLoadStoreExclusive(Instruction* instr) {
+  const char *mnemonic = "unimplemented";
+  const char *form;
+
+  switch (instr->Mask(LoadStoreExclusiveMask)) {
+    case STXRB_w: mnemonic = "stxrb"; form = "'Ws, 'Wt, ['Xns]"; break;
+    case STXRH_w: mnemonic = "stxrh"; form = "'Ws, 'Wt, ['Xns]"; break;
+    case STXR_w: mnemonic = "stxr"; form = "'Ws, 'Wt, ['Xns]"; break;
+    case STXR_x: mnemonic = "stxr"; form = "'Ws, 'Xt, ['Xns]"; break;
+    case LDXRB_w: mnemonic = "ldxrb"; form = "'Wt, ['Xns]"; break;
+    case LDXRH_w: mnemonic = "ldxrh"; form = "'Wt, ['Xns]"; break;
+    case LDXR_w: mnemonic = "ldxr"; form = "'Wt, ['Xns]"; break;
+    case LDXR_x: mnemonic = "ldxr"; form = "'Xt, ['Xns]"; break;
+    case STXP_w: mnemonic = "stxp"; form = "'Ws, 'Wt, 'Wt2, ['Xns]"; break;
+    case STXP_x: mnemonic = "stxp"; form = "'Ws, 'Xt, 'Xt2, ['Xns]"; break;
+    case LDXP_w: mnemonic = "ldxp"; form = "'Wt, 'Wt2, ['Xns]"; break;
+    case LDXP_x: mnemonic = "ldxp"; form = "'Xt, 'Xt2, ['Xns]"; break;
+    case STLXRB_w: mnemonic = "stlxrb"; form = "'Ws, 'Wt, ['Xns]"; break;
+    case STLXRH_w: mnemonic = "stlxrh"; form = "'Ws, 'Wt, ['Xns]"; break;
+    case STLXR_w: mnemonic = "stlxr"; form = "'Ws, 'Wt, ['Xns]"; break;
+    case STLXR_x: mnemonic = "stlxr"; form = "'Ws, 'Xt, ['Xns]"; break;
+    case LDAXRB_w: mnemonic = "ldaxrb"; form = "'Wt, ['Xns]"; break;
+    case LDAXRH_w: mnemonic = "ldaxrh"; form = "'Wt, ['Xns]"; break;
+    case LDAXR_w: mnemonic = "ldaxr"; form = "'Wt, ['Xns]"; break;
+    case LDAXR_x: mnemonic = "ldaxr"; form = "'Xt, ['Xns]"; break;
+    case STLXP_w: mnemonic = "stlxp"; form = "'Ws, 'Wt, 'Wt2, ['Xns]"; break;
+    case STLXP_x: mnemonic = "stlxp"; form = "'Ws, 'Xt, 'Xt2, ['Xns]"; break;
+    case LDAXP_w: mnemonic = "ldaxp"; form = "'Wt, 'Wt2, ['Xns]"; break;
+    case LDAXP_x: mnemonic = "ldaxp"; form = "'Xt, 'Xt2, ['Xns]"; break;
+    case STLRB_w: mnemonic = "stlrb"; form = "'Wt, ['Xns]"; break;
+    case STLRH_w: mnemonic = "stlrh"; form = "'Wt, ['Xns]"; break;
+    case STLR_w: mnemonic = "stlr"; form = "'Wt, ['Xns]"; break;
+    case STLR_x: mnemonic = "stlr"; form = "'Xt, ['Xns]"; break;
+    case LDARB_w: mnemonic = "ldarb"; form = "'Wt, ['Xns]"; break;
+    case LDARH_w: mnemonic = "ldarh"; form = "'Wt, ['Xns]"; break;
+    case LDAR_w: mnemonic = "ldar"; form = "'Wt, ['Xns]"; break;
+    case LDAR_x: mnemonic = "ldar"; form = "'Xt, ['Xns]"; break;
+    default: form = "(LoadStoreExclusive)";
+  }
+  Format(instr, mnemonic, form);
+}
+
+
 void Disassembler::VisitFPCompare(Instruction* instr) {
   const char *mnemonic = "unimplemented";
   const char *form = "'Fn, 'Fm";
@@ -1162,7 +1206,15 @@ void Disassembler::VisitSystem(Instruction* instr) {
   const char *mnemonic = "unimplemented";
   const char *form = "(System)";
 
-  if (instr->Mask(SystemSysRegFMask) == SystemSysRegFixed) {
+  if (instr->Mask(SystemExclusiveMonitorFMask) == SystemExclusiveMonitorFixed) {
+    switch (instr->Mask(SystemExclusiveMonitorMask)) {
+      case CLREX: {
+        mnemonic = "clrex";
+        form = (instr->CRm() == 0xf) ? NULL : "'IX";
+        break;
+      }
+    }
+  } else if (instr->Mask(SystemSysRegFMask) == SystemSysRegFixed) {
     switch (instr->Mask(SystemSysRegMask)) {
       case MRS: {
         mnemonic = "mrs";
@@ -1184,7 +1236,6 @@ void Disassembler::VisitSystem(Instruction* instr) {
       }
     }
   } else if (instr->Mask(SystemHintFMask) == SystemHintFixed) {
-    VIXL_ASSERT(instr->Mask(SystemHintMask) == HINT);
     switch (instr->ImmHint()) {
       case NOP: {
         mnemonic = "nop";
@@ -1312,6 +1363,7 @@ int Disassembler::SubstituteRegisterField(Instruction* instr,
     case 'n': reg_num = instr->Rn(); break;
     case 'm': reg_num = instr->Rm(); break;
     case 'a': reg_num = instr->Ra(); break;
+    case 's': reg_num = instr->Rs(); break;
     case 't': {
       if (format[2] == '2') {
         reg_num = instr->Rt2();
@@ -1458,6 +1510,10 @@ int Disassembler::SubstituteImmediateField(Instruction* instr,
       AppendToOutput("#0x%" PRIx64, instr->ImmException());
       return 6;
     }
+    case 'X': {  // IX - CLREX instruction.
+      AppendToOutput("#0x%" PRIx64, instr->CRm());
+      return 2;
+    }
     default: {
       VIXL_UNIMPLEMENTED();
       return 0;
@@ -1564,21 +1620,20 @@ int Disassembler::SubstituteConditionField(Instruction* instr,
 
 int Disassembler::SubstitutePCRelAddressField(Instruction* instr,
                                               const char* format) {
-  USE(format);
-  VIXL_ASSERT(strncmp(format, "AddrPCRel", 9) == 0);
+  VIXL_ASSERT((strcmp(format, "AddrPCRelByte") == 0) ||   // Used by `adr`.
+              (strcmp(format, "AddrPCRelPage") == 0));    // Used by `adrp`.
 
-  int offset = instr->ImmPCRel();
+  int64_t offset = instr->ImmPCRel();
+  Instruction * base = instr;
 
-  // Only ADR (AddrPCRelByte) is supported.
-  VIXL_ASSERT(strcmp(format, "AddrPCRelByte") == 0);
-
-  char sign = '+';
-  if (offset < 0) {
-    offset = -offset;
-    sign = '-';
+  if (format[9] == 'P') {
+    offset *= kPageSize;
+    base = AlignDown(base, kPageSize);
   }
-  VIXL_STATIC_ASSERT(sizeof(*instr) == 1);
-  AppendToOutput("#%c0x%x (addr %p)", sign, offset, instr + offset);
+
+  char sign = (offset < 0) ? '-' : '+';
+  void * target = reinterpret_cast<void *>(base + offset);
+  AppendToOutput("#%c0x%" PRIx64 " (addr %p)", sign, std::abs(offset), target);
   return 13;
 }
 
@@ -1606,7 +1661,8 @@ int Disassembler::SubstituteBranchTargetField(Instruction* instr,
     sign = '-';
   }
   VIXL_STATIC_ASSERT(sizeof(*instr) == 1);
-  AppendToOutput("#%c0x%" PRIx64 " (addr %p)", sign, offset, instr + offset);
+  void * address = reinterpret_cast<void *>(instr + offset);
+  AppendToOutput("#%c0x%" PRIx64 " (addr %p)", sign, offset, address);
   return 8;
 }
 
diff --git a/disas/libvixl/a64/disasm-a64.h b/disas/libvixl/a64/disasm-a64.h
index 3a56e15..06ee43f 100644
--- a/disas/libvixl/a64/disasm-a64.h
+++ b/disas/libvixl/a64/disasm-a64.h
@@ -85,7 +85,7 @@ class Disassembler: public DecoderVisitor {
   bool IsMovzMovnImm(unsigned reg_size, uint64_t value);
 
   void ResetOutput();
-  void AppendToOutput(const char* string, ...);
+  void AppendToOutput(const char* string, ...) PRINTF_CHECK(2, 3);
 
   char* buffer_;
   uint32_t buffer_pos_;
diff --git a/disas/libvixl/a64/instructions-a64.cc b/disas/libvixl/a64/instructions-a64.cc
index c4eb7c4..e9caceb 100644
--- a/disas/libvixl/a64/instructions-a64.cc
+++ b/disas/libvixl/a64/instructions-a64.cc
@@ -149,17 +149,24 @@ LSDataSize CalcLSPairDataSize(LoadStorePairOp op) {
 
 
 Instruction* Instruction::ImmPCOffsetTarget() {
+  Instruction * base = this;
   ptrdiff_t offset;
   if (IsPCRelAddressing()) {
-    // PC-relative addressing. Only ADR is supported.
+    // ADR and ADRP.
     offset = ImmPCRel();
+    if (Mask(PCRelAddressingMask) == ADRP) {
+      base = AlignDown(base, kPageSize);
+      offset *= kPageSize;
+    } else {
+      VIXL_ASSERT(Mask(PCRelAddressingMask) == ADR);
+    }
   } else {
     // All PC-relative branches.
     VIXL_ASSERT(BranchType() != UnknownBranchType);
     // Relative branch offsets are instruction-size-aligned.
     offset = ImmBranch() << kInstructionSizeLog2;
   }
-  return this + offset;
+  return base + offset;
 }
 
 
@@ -185,10 +192,16 @@ void Instruction::SetImmPCOffsetTarget(Instruction* target) {
 
 
 void Instruction::SetPCRelImmTarget(Instruction* target) {
-  // ADRP is not supported, so 'this' must point to an ADR instruction.
-  VIXL_ASSERT(Mask(PCRelAddressingMask) == ADR);
-
-  Instr imm = Assembler::ImmPCRelAddress(target - this);
+  int32_t imm21;
+  if ((Mask(PCRelAddressingMask) == ADR)) {
+    imm21 = target - this;
+  } else {
+    VIXL_ASSERT(Mask(PCRelAddressingMask) == ADRP);
+    uintptr_t this_page = reinterpret_cast<uintptr_t>(this) / kPageSize;
+    uintptr_t target_page = reinterpret_cast<uintptr_t>(target) / kPageSize;
+    imm21 = target_page - this_page;
+  }
+  Instr imm = Assembler::ImmPCRelAddress(imm21);
 
   SetInstructionBits(Mask(~ImmPCRel_mask) | imm);
 }
diff --git a/disas/libvixl/a64/instructions-a64.h b/disas/libvixl/a64/instructions-a64.h
index a4240d7..d5b90c5 100644
--- a/disas/libvixl/a64/instructions-a64.h
+++ b/disas/libvixl/a64/instructions-a64.h
@@ -41,6 +41,10 @@ const unsigned kLiteralEntrySize = 4;
 const unsigned kLiteralEntrySizeLog2 = 2;
 const unsigned kMaxLoadLiteralRange = 1 * MBytes;
 
+// This is the nominal page size (as used by the adrp instruction); the actual
+// size of the memory pages allocated by the kernel is likely to differ.
+const unsigned kPageSize = 4 * KBytes;
+
 const unsigned kWRegSize = 32;
 const unsigned kWRegSizeLog2 = 5;
 const unsigned kWRegSizeInBytes = kWRegSize / 8;
@@ -79,6 +83,12 @@ const unsigned kZeroRegCode = 31;
 const unsigned kSPRegInternalCode = 63;
 const unsigned kRegCodeMask = 0x1f;
 
+const unsigned kAddressTagOffset = 56;
+const unsigned kAddressTagWidth = 8;
+const uint64_t kAddressTagMask =
+    ((UINT64_C(1) << kAddressTagWidth) - 1) << kAddressTagOffset;
+VIXL_STATIC_ASSERT(kAddressTagMask == UINT64_C(0xff00000000000000));
+
 // AArch64 floating-point specifics. These match IEEE-754.
 const unsigned kDoubleMantissaBits = 52;
 const unsigned kDoubleExponentBits = 11;
diff --git a/disas/libvixl/platform.h b/disas/libvixl/platform.h
index b5c2085..de2b110 100644
--- a/disas/libvixl/platform.h
+++ b/disas/libvixl/platform.h
@@ -28,14 +28,10 @@
 #define PLATFORM_H
 
 // Define platform specific functionalities.
+#include <signal.h>
 
 namespace vixl {
-#ifdef USE_SIMULATOR
-// Currently we assume running the simulator implies running on x86 hardware.
-inline void HostBreakpoint() { asm("int3"); }
-#else
-inline void HostBreakpoint() { asm("brk"); }
-#endif
+inline void HostBreakpoint() { raise(SIGINT); }
 }  // namespace vixl
 
 #endif
diff --git a/disas/libvixl/utils.cc b/disas/libvixl/utils.cc
index c9c05d1..4d4fcbd 100644
--- a/disas/libvixl/utils.cc
+++ b/disas/libvixl/utils.cc
@@ -124,4 +124,14 @@ int CountSetBits(uint64_t value, int width) {
 
   return value;
 }
+
+
+uint64_t LowestSetBit(uint64_t value) {
+  return value & -value;
+}
+
+
+bool IsPowerOf2(int64_t value) {
+  return (value != 0) && ((value & (value - 1)) == 0);
+}
 }  // namespace vixl
diff --git a/disas/libvixl/utils.h b/disas/libvixl/utils.h
index 83c928c..b472f0e 100644
--- a/disas/libvixl/utils.h
+++ b/disas/libvixl/utils.h
@@ -33,6 +33,14 @@
 
 namespace vixl {
 
+// Macros for compile-time format checking.
+#if defined(__GNUC__)
+#define PRINTF_CHECK(format_index, varargs_index) \
+  __attribute__((format(printf, format_index, varargs_index)))
+#else
+#define PRINTF_CHECK(format_index, varargs_index)
+#endif
+
 // Check number width.
 inline bool is_intn(unsigned n, int64_t x) {
   VIXL_ASSERT((0 < n) && (n < 64));
@@ -155,6 +163,8 @@ int CountLeadingZeros(uint64_t value, int width);
 int CountLeadingSignBits(int64_t value, int width);
 int CountTrailingZeros(uint64_t value, int width);
 int CountSetBits(uint64_t value, int width);
+uint64_t LowestSetBit(uint64_t value);
+bool IsPowerOf2(int64_t value);
 
 // Pointer alignment
 // TODO: rename/refactor to make it specific to instructions.
@@ -167,21 +177,31 @@ bool IsWordAligned(T pointer) {
 // Increment a pointer until it has the specified alignment.
 template<class T>
 T AlignUp(T pointer, size_t alignment) {
-  VIXL_STATIC_ASSERT(sizeof(pointer) == sizeof(uintptr_t));
-  uintptr_t pointer_raw = reinterpret_cast<uintptr_t>(pointer);
+  // Use C-style casts to get static_cast behaviour for integral types (T), and
+  // reinterpret_cast behaviour for other types.
+
+  uintptr_t pointer_raw = (uintptr_t)pointer;
+  VIXL_STATIC_ASSERT(sizeof(pointer) == sizeof(pointer_raw));
+
   size_t align_step = (alignment - pointer_raw) % alignment;
   VIXL_ASSERT((pointer_raw + align_step) % alignment == 0);
-  return reinterpret_cast<T>(pointer_raw + align_step);
+
+  return (T)(pointer_raw + align_step);
 }
 
 // Decrement a pointer until it has the specified alignment.
 template<class T>
 T AlignDown(T pointer, size_t alignment) {
-  VIXL_STATIC_ASSERT(sizeof(pointer) == sizeof(uintptr_t));
-  uintptr_t pointer_raw = reinterpret_cast<uintptr_t>(pointer);
+  // Use C-style casts to get static_cast behaviour for integral types (T), and
+  // reinterpret_cast behaviour for other types.
+
+  uintptr_t pointer_raw = (uintptr_t)pointer;
+  VIXL_STATIC_ASSERT(sizeof(pointer) == sizeof(pointer_raw));
+
   size_t align_step = pointer_raw % alignment;
   VIXL_ASSERT((pointer_raw - align_step) % alignment == 0);
-  return reinterpret_cast<T>(pointer_raw - align_step);
+
+  return (T)(pointer_raw - align_step);
 }
 
 
commit d9aa68855724752a5684c6acfb17d8db15cec2f8
Merge: a6aebb3 25e89ec
Author: Peter Maydell <peter.maydell at linaro.org>
Date:   Fri Aug 29 13:08:04 2014 +0100

    Merge remote-tracking branch 'remotes/kraxel/tags/pull-usb-20140829-1' into staging
    
    usb: bugfix collection.
    usb: add cleanup functions for host adapters,
         in preparation for hotplug support.
    usb: add simple qtests for uhci,ohci,xhci.
    
    # gpg: Signature made Fri 29 Aug 2014 12:56:20 BST using RSA key ID D3E87138
    # gpg: Good signature from "Gerd Hoffmann (work) <kraxel at redhat.com>"
    # gpg:                 aka "Gerd Hoffmann <gerd at kraxel.org>"
    # gpg:                 aka "Gerd Hoffmann (private) <kraxel at gmail.com>"
    
    * remotes/kraxel/tags/pull-usb-20140829-1:
      tests: add xHCI qtest
      tests: add UHCI qtest
      tests: add OHCI qtest
      usb: add usb host adapters exit trace
      usb-xhci: add exit function
      usb-ehci: add ehci-pci device exit function
      usb-ehci: add ehci unrealize funciton
      usb-ehci: add vmstate properity for EHCIState
      usb-uhci: clean up uhci resource when pci-uhci exit
      usb-ohci: add exit function
      usb-ohci: Fix memory leak for ohci timer
      usb: add usb_bus_release function
      Revert "xhci: Fix number of streams allocated when using streams"
      xhci: use (1u << i)
      Fix OHCI ISO TD state never being written back.
      xhci: fix debug print compiling error
      usb: Fix bootindex for portnr > 9
    
    Signed-off-by: Peter Maydell <peter.maydell at linaro.org>

commit 25e89ec5d2c7f8d953cb1ca558afa74974ff8930
Author: Gonglei <arei.gonglei at huawei.com>
Date:   Mon Jun 23 19:53:53 2014 +0800

    tests: add xHCI qtest
    
    Signed-off-by: Gonglei <arei.gonglei at huawei.com>
    Signed-off-by: Gerd Hoffmann <kraxel at redhat.com>

diff --git a/tests/Makefile b/tests/Makefile
index 6eff8cd..469c0a5 100644
--- a/tests/Makefile
+++ b/tests/Makefile
@@ -163,6 +163,8 @@ check-qtest-i386-y += tests/usb-hcd-ehci-test$(EXESUF)
 gcov-files-i386-y += hw/usb/hcd-ehci.c
 gcov-files-i386-y += hw/usb/dev-hid.c
 gcov-files-i386-y += hw/usb/dev-storage.c
+check-qtest-i386-y += tests/usb-hcd-xhci-test$(EXESUF)
+gcov-files-i386-y += hw/usb/hcd-xhci.c
 check-qtest-i386-$(CONFIG_LINUX) += tests/vhost-user-test$(EXESUF)
 check-qtest-x86_64-y = $(check-qtest-i386-y)
 gcov-files-i386-y += i386-softmmu/hw/timer/mc146818rtc.c
@@ -341,6 +343,7 @@ tests/ioh3420-test$(EXESUF): tests/ioh3420-test.o
 tests/usb-hcd-ohci-test$(EXESUF): tests/usb-hcd-ohci-test.o
 tests/usb-hcd-uhci-test$(EXESUF): tests/usb-hcd-uhci-test.o
 tests/usb-hcd-ehci-test$(EXESUF): tests/usb-hcd-ehci-test.o $(libqos-pc-obj-y)
+tests/usb-hcd-xhci-test$(EXESUF): tests/usb-hcd-xhci-test.o
 tests/vhost-user-test$(EXESUF): tests/vhost-user-test.o qemu-char.o qemu-timer.o $(qtest-obj-y)
 tests/qemu-iotests/socket_scm_helper$(EXESUF): tests/qemu-iotests/socket_scm_helper.o
 tests/test-qemu-opts$(EXESUF): tests/test-qemu-opts.o libqemuutil.a libqemustub.a
diff --git a/tests/usb-hcd-xhci-test.c b/tests/usb-hcd-xhci-test.c
new file mode 100644
index 0000000..743e979
--- /dev/null
+++ b/tests/usb-hcd-xhci-test.c
@@ -0,0 +1,35 @@
+/*
+ * QTest testcase for USB xHCI controller
+ *
+ * Copyright (c) 2014 HUAWEI TECHNOLOGIES CO.,LTD.
+ *
+ * This work is licensed under the terms of the GNU GPL, version 2 or later.
+ * See the COPYING file in the top-level directory.
+ */
+
+#include <glib.h>
+#include <string.h>
+#include "libqtest.h"
+#include "qemu/osdep.h"
+
+
+static void test_xhci_init(void)
+{
+    qtest_start("-device nec-usb-xhci,id=xhci");
+
+    qtest_end();
+}
+
+
+int main(int argc, char **argv)
+{
+    int ret;
+
+    g_test_init(&argc, &argv, NULL);
+
+    qtest_add_func("/xhci/pci/init", test_xhci_init);
+
+    ret = g_test_run();
+
+    return ret;
+}
commit 44ced58e3adf1bb16cac9d5b7bb178f75405902f
Author: Gonglei <arei.gonglei at huawei.com>
Date:   Mon Jun 23 19:53:52 2014 +0800

    tests: add UHCI qtest
    
    Signed-off-by: Gonglei <arei.gonglei at huawei.com>
    Signed-off-by: Gerd Hoffmann <kraxel at redhat.com>

diff --git a/tests/Makefile b/tests/Makefile
index 5d67a55..6eff8cd 100644
--- a/tests/Makefile
+++ b/tests/Makefile
@@ -157,9 +157,10 @@ check-qtest-i386-y += tests/ioh3420-test$(EXESUF)
 gcov-files-i386-y += hw/pci-bridge/ioh3420.c
 check-qtest-i386-y += tests/usb-hcd-ohci-test$(EXESUF)
 gcov-files-i386-y += hw/usb/hcd-ohci.c
+check-qtest-i386-y += tests/usb-hcd-uhci-test$(EXESUF)
+gcov-files-i386-y += hw/usb/hcd-uhci.c
 check-qtest-i386-y += tests/usb-hcd-ehci-test$(EXESUF)
 gcov-files-i386-y += hw/usb/hcd-ehci.c
-gcov-files-i386-y += hw/usb/hcd-uhci.c
 gcov-files-i386-y += hw/usb/dev-hid.c
 gcov-files-i386-y += hw/usb/dev-storage.c
 check-qtest-i386-$(CONFIG_LINUX) += tests/vhost-user-test$(EXESUF)
@@ -338,6 +339,7 @@ tests/es1370-test$(EXESUF): tests/es1370-test.o
 tests/intel-hda-test$(EXESUF): tests/intel-hda-test.o
 tests/ioh3420-test$(EXESUF): tests/ioh3420-test.o
 tests/usb-hcd-ohci-test$(EXESUF): tests/usb-hcd-ohci-test.o
+tests/usb-hcd-uhci-test$(EXESUF): tests/usb-hcd-uhci-test.o
 tests/usb-hcd-ehci-test$(EXESUF): tests/usb-hcd-ehci-test.o $(libqos-pc-obj-y)
 tests/vhost-user-test$(EXESUF): tests/vhost-user-test.o qemu-char.o qemu-timer.o $(qtest-obj-y)
 tests/qemu-iotests/socket_scm_helper$(EXESUF): tests/qemu-iotests/socket_scm_helper.o
diff --git a/tests/usb-hcd-uhci-test.c b/tests/usb-hcd-uhci-test.c
new file mode 100644
index 0000000..94e858f
--- /dev/null
+++ b/tests/usb-hcd-uhci-test.c
@@ -0,0 +1,35 @@
+/*
+ * QTest testcase for USB UHCI controller
+ *
+ * Copyright (c) 2014 HUAWEI TECHNOLOGIES CO.,LTD.
+ *
+ * This work is licensed under the terms of the GNU GPL, version 2 or later.
+ * See the COPYING file in the top-level directory.
+ */
+
+#include <glib.h>
+#include <string.h>
+#include "libqtest.h"
+#include "qemu/osdep.h"
+
+
+static void test_uhci_init(void)
+{
+    qtest_start("-device piix3-usb-uhci,id=uhci");
+
+    qtest_end();
+}
+
+
+int main(int argc, char **argv)
+{
+    int ret;
+
+    g_test_init(&argc, &argv, NULL);
+
+    qtest_add_func("/uhci/pci/init", test_uhci_init);
+
+    ret = g_test_run();
+
+    return ret;
+}
commit 28edfce0f3e8536b30573343618635f8713d6326
Author: Gonglei <arei.gonglei at huawei.com>
Date:   Mon Jun 23 19:53:51 2014 +0800

    tests: add OHCI qtest
    
    Signed-off-by: Gonglei <arei.gonglei at huawei.com>
    Signed-off-by: Gerd Hoffmann <kraxel at redhat.com>

diff --git a/MAINTAINERS b/MAINTAINERS
index 59940f9..a74c04c 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -614,7 +614,7 @@ USB
 M: Gerd Hoffmann <kraxel at redhat.com>
 S: Maintained
 F: hw/usb/*
-F: tests/usb-hcd-ehci-test.c
+F: tests/usb-*-test.c
 
 VFIO
 M: Alex Williamson <alex.williamson at redhat.com>
diff --git a/tests/Makefile b/tests/Makefile
index 837e9c8..5d67a55 100644
--- a/tests/Makefile
+++ b/tests/Makefile
@@ -155,6 +155,8 @@ check-qtest-i386-y += tests/i82801b11-test$(EXESUF)
 gcov-files-i386-y += hw/pci-bridge/i82801b11.c
 check-qtest-i386-y += tests/ioh3420-test$(EXESUF)
 gcov-files-i386-y += hw/pci-bridge/ioh3420.c
+check-qtest-i386-y += tests/usb-hcd-ohci-test$(EXESUF)
+gcov-files-i386-y += hw/usb/hcd-ohci.c
 check-qtest-i386-y += tests/usb-hcd-ehci-test$(EXESUF)
 gcov-files-i386-y += hw/usb/hcd-ehci.c
 gcov-files-i386-y += hw/usb/hcd-uhci.c
@@ -335,6 +337,7 @@ tests/ac97-test$(EXESUF): tests/ac97-test.o
 tests/es1370-test$(EXESUF): tests/es1370-test.o
 tests/intel-hda-test$(EXESUF): tests/intel-hda-test.o
 tests/ioh3420-test$(EXESUF): tests/ioh3420-test.o
+tests/usb-hcd-ohci-test$(EXESUF): tests/usb-hcd-ohci-test.o
 tests/usb-hcd-ehci-test$(EXESUF): tests/usb-hcd-ehci-test.o $(libqos-pc-obj-y)
 tests/vhost-user-test$(EXESUF): tests/vhost-user-test.o qemu-char.o qemu-timer.o $(qtest-obj-y)
 tests/qemu-iotests/socket_scm_helper$(EXESUF): tests/qemu-iotests/socket_scm_helper.o
diff --git a/tests/usb-hcd-ohci-test.c b/tests/usb-hcd-ohci-test.c
new file mode 100644
index 0000000..fbc3ffe
--- /dev/null
+++ b/tests/usb-hcd-ohci-test.c
@@ -0,0 +1,35 @@
+/*
+ * QTest testcase for USB OHCI controller
+ *
+ * Copyright (c) 2014 HUAWEI TECHNOLOGIES CO.,LTD.
+ *
+ * This work is licensed under the terms of the GNU GPL, version 2 or later.
+ * See the COPYING file in the top-level directory.
+ */
+
+#include <glib.h>
+#include <string.h>
+#include "libqtest.h"
+#include "qemu/osdep.h"
+
+
+static void test_ohci_init(void)
+{
+    qtest_start("-device pci-ohci,id=ohci");
+
+    qtest_end();
+}
+
+
+int main(int argc, char **argv)
+{
+    int ret;
+
+    g_test_init(&argc, &argv, NULL);
+
+    qtest_add_func("/ohci/pci/init", test_ohci_init);
+
+    ret = g_test_run();
+
+    return ret;
+}
commit d733f74c333184179770e4d5017366da4b449cce
Author: Gonglei <arei.gonglei at huawei.com>
Date:   Wed Jun 4 16:31:55 2014 +0800

    usb: add usb host adapters exit trace
    
    Signed-off-by: Gonglei <arei.gonglei at huawei.com>
    Signed-off-by: Gerd Hoffmann <kraxel at redhat.com>

diff --git a/hw/usb/hcd-ehci.c b/hw/usb/hcd-ehci.c
index 2aa06bb..bacb7ce 100644
--- a/hw/usb/hcd-ehci.c
+++ b/hw/usb/hcd-ehci.c
@@ -2473,6 +2473,8 @@ void usb_ehci_realize(EHCIState *s, DeviceState *dev, Error **errp)
 
 void usb_ehci_unrealize(EHCIState *s, DeviceState *dev, Error **errp)
 {
+    trace_usb_ehci_unrealize();
+
     if (s->frame_timer) {
         timer_del(s->frame_timer);
         timer_free(s->frame_timer);
diff --git a/hw/usb/hcd-uhci.c b/hw/usb/hcd-uhci.c
index 220115b..3b3ebcd 100644
--- a/hw/usb/hcd-uhci.c
+++ b/hw/usb/hcd-uhci.c
@@ -1260,6 +1260,8 @@ static void usb_uhci_exit(PCIDevice *dev)
 {
     UHCIState *s = DO_UPCAST(UHCIState, dev, dev);
 
+    trace_usb_uhci_exit();
+
     if (s->frame_timer) {
         timer_del(s->frame_timer);
         timer_free(s->frame_timer);
diff --git a/hw/usb/hcd-xhci.c b/hw/usb/hcd-xhci.c
index a9245d8..bbe4c5f 100644
--- a/hw/usb/hcd-xhci.c
+++ b/hw/usb/hcd-xhci.c
@@ -3649,6 +3649,8 @@ static void usb_xhci_exit(PCIDevice *dev)
     int i;
     XHCIState *xhci = XHCI(dev);
 
+    trace_usb_xhci_exit();
+
     for (i = 0; i < xhci->numslots; i++) {
         xhci_disable_slot(xhci, i + 1);
     }
diff --git a/trace-events b/trace-events
index 81bc915..03ac5d2 100644
--- a/trace-events
+++ b/trace-events
@@ -297,6 +297,7 @@ usb_port_release(int bus, const char *port) "bus %d, port %s"
 
 # hw/usb/hcd-ehci.c
 usb_ehci_reset(void) "=== RESET ==="
+usb_ehci_unrealize(void) "=== UNREALIZE ==="
 usb_ehci_opreg_read(uint32_t addr, const char *str, uint32_t val) "rd mmio %04x [%s] = %x"
 usb_ehci_opreg_write(uint32_t addr, const char *str, uint32_t val) "wr mmio %04x [%s] = %x"
 usb_ehci_opreg_change(uint32_t addr, const char *str, uint32_t new, uint32_t old) "ch mmio %04x [%s] = %x (old: %x)"
@@ -329,6 +330,7 @@ usb_ehci_dma_error(void) ""
 
 # hw/usb/hcd-uhci.c
 usb_uhci_reset(void) "=== RESET ==="
+usb_uhci_exit(void) "=== EXIT ==="
 usb_uhci_schedule_start(void) ""
 usb_uhci_schedule_stop(void) ""
 usb_uhci_frame_start(uint32_t num) "nr %d"
@@ -358,6 +360,7 @@ usb_uhci_td_complete(uint32_t qh, uint32_t td) "qh 0x%x, td 0x%x"
 
 # hw/usb/hcd-xhci.c
 usb_xhci_reset(void) "=== RESET ==="
+usb_xhci_exit(void) "=== EXIT ==="
 usb_xhci_run(void) ""
 usb_xhci_stop(void) ""
 usb_xhci_cap_read(uint32_t off, uint32_t val) "off 0x%04x, ret 0x%08x"
commit 53c30545fb34c43c84d62ea1c2b0dc6b53303c34
Author: Gonglei <arei.gonglei at huawei.com>
Date:   Wed Jun 4 16:31:53 2014 +0800

    usb-xhci: add exit function
    
    clean up xhci resource when xhci pci device exit.
    
    Signed-off-by: Gonglei <arei.gonglei at huawei.com>
    Signed-off-by: Gerd Hoffmann <kraxel at redhat.com>

diff --git a/hw/usb/hcd-xhci.c b/hw/usb/hcd-xhci.c
index 88660e8..a9245d8 100644
--- a/hw/usb/hcd-xhci.c
+++ b/hw/usb/hcd-xhci.c
@@ -3644,6 +3644,41 @@ static int usb_xhci_initfn(struct PCIDevice *dev)
     return 0;
 }
 
+static void usb_xhci_exit(PCIDevice *dev)
+{
+    int i;
+    XHCIState *xhci = XHCI(dev);
+
+    for (i = 0; i < xhci->numslots; i++) {
+        xhci_disable_slot(xhci, i + 1);
+    }
+
+    if (xhci->mfwrap_timer) {
+        timer_del(xhci->mfwrap_timer);
+        timer_free(xhci->mfwrap_timer);
+        xhci->mfwrap_timer = NULL;
+    }
+
+    memory_region_del_subregion(&xhci->mem, &xhci->mem_cap);
+    memory_region_del_subregion(&xhci->mem, &xhci->mem_oper);
+    memory_region_del_subregion(&xhci->mem, &xhci->mem_runtime);
+    memory_region_del_subregion(&xhci->mem, &xhci->mem_doorbell);
+
+    for (i = 0; i < xhci->numports; i++) {
+        XHCIPort *port = &xhci->ports[i];
+        memory_region_del_subregion(&xhci->mem, &port->mem);
+    }
+
+    /* destroy msix memory region */
+    if (dev->msix_table && dev->msix_pba
+        && dev->msix_entry_used) {
+        memory_region_del_subregion(&xhci->mem, &dev->msix_table_mmio);
+        memory_region_del_subregion(&xhci->mem, &dev->msix_pba_mmio);
+    }
+
+    usb_bus_release(&xhci->bus);
+}
+
 static int usb_xhci_post_load(void *opaque, int version_id)
 {
     XHCIState *xhci = opaque;
@@ -3836,6 +3871,7 @@ static void xhci_class_init(ObjectClass *klass, void *data)
     dc->hotpluggable   = false;
     set_bit(DEVICE_CATEGORY_USB, dc->categories);
     k->init         = usb_xhci_initfn;
+    k->exit         = usb_xhci_exit;
     k->vendor_id    = PCI_VENDOR_ID_NEC;
     k->device_id    = PCI_DEVICE_ID_NEC_UPD720200;
     k->class_id     = PCI_CLASS_SERIAL_USB;
commit 96e14926c66dc7da99bea80d639a30cce0772991
Author: Gonglei <arei.gonglei at huawei.com>
Date:   Wed Jun 4 16:31:52 2014 +0800

    usb-ehci: add ehci-pci device exit function
    
    clean up ehci resource when ehci pci device exit.
    
    Signed-off-by: Gonglei <arei.gonglei at huawei.com>
    Signed-off-by: Gerd Hoffmann <kraxel at redhat.com>

diff --git a/hw/usb/hcd-ehci-pci.c b/hw/usb/hcd-ehci-pci.c
index 505741a..289ca3b 100644
--- a/hw/usb/hcd-ehci-pci.c
+++ b/hw/usb/hcd-ehci-pci.c
@@ -84,6 +84,19 @@ static void usb_ehci_pci_init(Object *obj)
     usb_ehci_init(s, DEVICE(obj));
 }
 
+static void usb_ehci_pci_exit(PCIDevice *dev)
+{
+    EHCIPCIState *i = PCI_EHCI(dev);
+    EHCIState *s = &i->ehci;
+
+    usb_ehci_unrealize(s, DEVICE(dev), NULL);
+
+    if (s->irq) {
+        g_free(s->irq);
+        s->irq = NULL;
+    }
+}
+
 static void usb_ehci_pci_write_config(PCIDevice *dev, uint32_t addr,
                                       uint32_t val, int l)
 {
@@ -121,6 +134,7 @@ static void ehci_class_init(ObjectClass *klass, void *data)
     PCIDeviceClass *k = PCI_DEVICE_CLASS(klass);
 
     k->init = usb_ehci_pci_initfn;
+    k->exit = usb_ehci_pci_exit;
     k->class_id = PCI_CLASS_SERIAL_USB;
     k->config_write = usb_ehci_pci_write_config;
     dc->hotpluggable = false;
commit 4e130cf6a83193218e357e6db49a7ade24ab9675
Author: Gonglei <arei.gonglei at huawei.com>
Date:   Wed Jun 4 16:31:51 2014 +0800

    usb-ehci: add ehci unrealize funciton
    
    cleanup ehci controller resource, both pci and sysbus
    if they're necessary.
    
    Signed-off-by: Gonglei <arei.gonglei at huawei.com>
    Signed-off-by: Gerd Hoffmann <kraxel at redhat.com>

diff --git a/hw/usb/hcd-ehci.c b/hw/usb/hcd-ehci.c
index ef26f36..2aa06bb 100644
--- a/hw/usb/hcd-ehci.c
+++ b/hw/usb/hcd-ehci.c
@@ -2471,6 +2471,31 @@ void usb_ehci_realize(EHCIState *s, DeviceState *dev, Error **errp)
     s->vmstate = qemu_add_vm_change_state_handler(usb_ehci_vm_state_change, s);
 }
 
+void usb_ehci_unrealize(EHCIState *s, DeviceState *dev, Error **errp)
+{
+    if (s->frame_timer) {
+        timer_del(s->frame_timer);
+        timer_free(s->frame_timer);
+        s->frame_timer = NULL;
+    }
+    if (s->async_bh) {
+        qemu_bh_delete(s->async_bh);
+    }
+
+    ehci_queues_rip_all(s, 0);
+    ehci_queues_rip_all(s, 1);
+
+    memory_region_del_subregion(&s->mem, &s->mem_caps);
+    memory_region_del_subregion(&s->mem, &s->mem_opreg);
+    memory_region_del_subregion(&s->mem, &s->mem_ports);
+
+    usb_bus_release(&s->bus);
+
+    if (s->vmstate) {
+        qemu_del_vm_change_state_handler(s->vmstate);
+    }
+}
+
 void usb_ehci_init(EHCIState *s, DeviceState *dev)
 {
     /* 2.2 host controller interface version */
diff --git a/hw/usb/hcd-ehci.h b/hw/usb/hcd-ehci.h
index 594d9d3..4858b7e 100644
--- a/hw/usb/hcd-ehci.h
+++ b/hw/usb/hcd-ehci.h
@@ -323,6 +323,7 @@ extern const VMStateDescription vmstate_ehci;
 
 void usb_ehci_init(EHCIState *s, DeviceState *dev);
 void usb_ehci_realize(EHCIState *s, DeviceState *dev, Error **errp);
+void usb_ehci_unrealize(EHCIState *s, DeviceState *dev, Error **errp);
 
 #define TYPE_PCI_EHCI "pci-ehci-usb"
 #define PCI_EHCI(obj) OBJECT_CHECK(EHCIPCIState, (obj), TYPE_PCI_EHCI)
commit 05a36991c54e32a95d096337fa008938340878d3
Author: Gonglei <arei.gonglei at huawei.com>
Date:   Wed Jun 4 16:31:50 2014 +0800

    usb-ehci: add vmstate properity for EHCIState
    
    since hotunplug the ehci host adapter, we should
    delete vm_change_state_handler also, so the
    VMChangeStateEntry should be saved in EHCIState.
    
    Signed-off-by: Gonglei <arei.gonglei at huawei.com>
    Signed-off-by: Gerd Hoffmann <kraxel at redhat.com>

diff --git a/hw/usb/hcd-ehci.c b/hw/usb/hcd-ehci.c
index 448e007..ef26f36 100644
--- a/hw/usb/hcd-ehci.c
+++ b/hw/usb/hcd-ehci.c
@@ -2468,7 +2468,7 @@ void usb_ehci_realize(EHCIState *s, DeviceState *dev, Error **errp)
     s->device = dev;
 
     qemu_register_reset(ehci_reset, s);
-    qemu_add_vm_change_state_handler(usb_ehci_vm_state_change, s);
+    s->vmstate = qemu_add_vm_change_state_handler(usb_ehci_vm_state_change, s);
 }
 
 void usb_ehci_init(EHCIState *s, DeviceState *dev)
diff --git a/hw/usb/hcd-ehci.h b/hw/usb/hcd-ehci.h
index 1ad4b96..594d9d3 100644
--- a/hw/usb/hcd-ehci.h
+++ b/hw/usb/hcd-ehci.h
@@ -316,6 +316,7 @@ struct EHCIState {
     uint32_t async_stepdown;
     uint32_t periodic_sched_active;
     bool int_req_by_async;
+    VMChangeStateEntry *vmstate;
 };
 
 extern const VMStateDescription vmstate_ehci;
commit 3a3464b000776c21d0b650036cbdfdc45e9eb172
Author: Gonglei <arei.gonglei at huawei.com>
Date:   Wed Jun 4 16:31:49 2014 +0800

    usb-uhci: clean up uhci resource when pci-uhci exit
    
    clean up uhci resource when uhci pci device exit.
    
    Signed-off-by: Gonglei <arei.gonglei at huawei.com>
    Signed-off-by: Gerd Hoffmann <kraxel at redhat.com>

diff --git a/hw/usb/hcd-uhci.c b/hw/usb/hcd-uhci.c
index ee5f112..220115b 100644
--- a/hw/usb/hcd-uhci.c
+++ b/hw/usb/hcd-uhci.c
@@ -1256,6 +1256,27 @@ static int usb_uhci_vt82c686b_initfn(PCIDevice *dev)
     return usb_uhci_common_initfn(dev);
 }
 
+static void usb_uhci_exit(PCIDevice *dev)
+{
+    UHCIState *s = DO_UPCAST(UHCIState, dev, dev);
+
+    if (s->frame_timer) {
+        timer_del(s->frame_timer);
+        timer_free(s->frame_timer);
+        s->frame_timer = NULL;
+    }
+
+    if (s->bh) {
+        qemu_bh_delete(s->bh);
+    }
+
+    uhci_async_cancel_all(s);
+
+    if (!s->masterbus) {
+        usb_bus_release(&s->bus);
+    }
+}
+
 static Property uhci_properties[] = {
     DEFINE_PROP_STRING("masterbus", UHCIState, masterbus),
     DEFINE_PROP_UINT32("firstport", UHCIState, firstport, 0),
@@ -1272,6 +1293,7 @@ static void uhci_class_init(ObjectClass *klass, void *data)
     UHCIInfo *info = data;
 
     k->init = info->initfn ? info->initfn : usb_uhci_common_initfn;
+    k->exit = info->unplug ? usb_uhci_exit : NULL;
     k->vendor_id = info->vendor_id;
     k->device_id = info->device_id;
     k->revision  = info->revision;
commit 07832c38d3c359f909609c4ab68ccc0d3282d7ee
Author: Gonglei <arei.gonglei at huawei.com>
Date:   Wed Jun 4 16:31:48 2014 +0800

    usb-ohci: add exit function
    
    clean up ohci resource when ohci pci device exit.
    
    Signed-off-by: Gonglei <arei.gonglei at huawei.com>
    Signed-off-by: Gerd Hoffmann <kraxel at redhat.com>

diff --git a/hw/usb/hcd-ohci.c b/hw/usb/hcd-ohci.c
index 5505f0a..83bec34 100644
--- a/hw/usb/hcd-ohci.c
+++ b/hw/usb/hcd-ohci.c
@@ -1954,6 +1954,24 @@ static int usb_ohci_initfn_pci(PCIDevice *dev)
     return 0;
 }
 
+static void usb_ohci_exit(PCIDevice *dev)
+{
+    OHCIPCIState *ohci = PCI_OHCI(dev);
+    OHCIState *s = &ohci->state;
+
+    ohci_bus_stop(s);
+
+    if (s->async_td) {
+        usb_cancel_packet(&s->usb_packet);
+        s->async_td = 0;
+    }
+    ohci_stop_endpoints(s);
+
+    if (!ohci->masterbus) {
+        usb_bus_release(&s->bus);
+    }
+}
+
 #define TYPE_SYSBUS_OHCI "sysbus-ohci"
 #define SYSBUS_OHCI(obj) OBJECT_CHECK(OHCISysBusState, (obj), TYPE_SYSBUS_OHCI)
 
@@ -2091,6 +2109,7 @@ static void ohci_pci_class_init(ObjectClass *klass, void *data)
     PCIDeviceClass *k = PCI_DEVICE_CLASS(klass);
 
     k->init = usb_ohci_initfn_pci;
+    k->exit = usb_ohci_exit;
     k->vendor_id = PCI_VENDOR_ID_APPLE;
     k->device_id = PCI_DEVICE_ID_APPLE_IPID_USB;
     k->class_id = PCI_CLASS_SERIAL_USB;
commit 80be63df5a19816629343f704345b71e83e6d960
Author: Gonglei <arei.gonglei at huawei.com>
Date:   Wed Jun 4 16:31:47 2014 +0800

    usb-ohci: Fix memory leak for ohci timer
    
    Signed-off-by: Gonglei <arei.gonglei at huawei.com>
    Signed-off-by: Gerd Hoffmann <kraxel at redhat.com>

diff --git a/hw/usb/hcd-ohci.c b/hw/usb/hcd-ohci.c
index cacf7b0..5505f0a 100644
--- a/hw/usb/hcd-ohci.c
+++ b/hw/usb/hcd-ohci.c
@@ -1371,8 +1371,10 @@ static int ohci_bus_start(OHCIState *ohci)
 /* Stop sending SOF tokens on the bus */
 static void ohci_bus_stop(OHCIState *ohci)
 {
-    if (ohci->eof_timer)
+    if (ohci->eof_timer) {
         timer_del(ohci->eof_timer);
+        timer_free(ohci->eof_timer);
+    }
     ohci->eof_timer = NULL;
 }
 
commit e5a9bece9b5064d0cb0fda68ff68b9361085f400
Author: Gonglei <arei.gonglei at huawei.com>
Date:   Wed Jun 4 16:31:46 2014 +0800

    usb: add usb_bus_release function
    
    add global variables releasing logic when the usb buses
    were removed or hot-unpluged.
    
    Signed-off-by: Gonglei <arei.gonglei at huawei.com>
    Signed-off-by: Gerd Hoffmann <kraxel at redhat.com>

diff --git a/hw/usb/bus.c b/hw/usb/bus.c
index 516fb52..c7c4dad 100644
--- a/hw/usb/bus.c
+++ b/hw/usb/bus.c
@@ -87,6 +87,13 @@ void usb_bus_new(USBBus *bus, size_t bus_size,
     QTAILQ_INSERT_TAIL(&busses, bus, next);
 }
 
+void usb_bus_release(USBBus *bus)
+{
+    assert(next_usb_bus > 0);
+
+    QTAILQ_REMOVE(&busses, bus, next);
+}
+
 USBBus *usb_bus_find(int busnr)
 {
     USBBus *bus;
diff --git a/include/hw/usb.h b/include/hw/usb.h
index 223a5ae..6b32a3b 100644
--- a/include/hw/usb.h
+++ b/include/hw/usb.h
@@ -529,6 +529,7 @@ struct USBBusOps {
 
 void usb_bus_new(USBBus *bus, size_t bus_size,
                  USBBusOps *ops, DeviceState *host);
+void usb_bus_release(USBBus *bus);
 USBBus *usb_bus_find(int busnr);
 void usb_legacy_register(const char *typename, const char *usbdevice_name,
                          USBDevice *(*usbdevice_init)(USBBus *bus,
commit f90e160b502fb5c464eb9417ac075a78f13e9801
Author: Gerd Hoffmann <kraxel at redhat.com>
Date:   Fri Aug 29 12:40:55 2014 +0200

    Revert "xhci: Fix number of streams allocated when using streams"
    
    This reverts commit d063c3112c4cd23a479ee18720c2bd119da2d315.
    
    "2 << x" is the same as "2 ^ (x + 1)", so the old code is correct.
    
    Signed-off-by: Gerd Hoffmann <kraxel at redhat.com>

diff --git a/hw/usb/hcd-xhci.c b/hw/usb/hcd-xhci.c
index f7f9fed..88660e8 100644
--- a/hw/usb/hcd-xhci.c
+++ b/hw/usb/hcd-xhci.c
@@ -1151,7 +1151,7 @@ static void xhci_reset_streams(XHCIEPContext *epctx)
 static void xhci_alloc_streams(XHCIEPContext *epctx, dma_addr_t base)
 {
     assert(epctx->pstreams == NULL);
-    epctx->nr_pstreams = 2 << (epctx->max_pstreams + 1);
+    epctx->nr_pstreams = 2 << epctx->max_pstreams;
     epctx->pstreams = xhci_alloc_stream_contexts(epctx->nr_pstreams, base);
 }
 
commit 3d80365b5558eb1b0a8374362c41570c37a4aba9
Author: Gerd Hoffmann <kraxel at redhat.com>
Date:   Thu Aug 28 10:51:35 2014 +0200

    xhci: use (1u << i)
    
    Signed-off-by: Gerd Hoffmann <kraxel at redhat.com>
    Reviewed-by: Peter Maydell <peter.maydell at linaro.org>

diff --git a/hw/usb/hcd-xhci.c b/hw/usb/hcd-xhci.c
index aed8e9f..f7f9fed 100644
--- a/hw/usb/hcd-xhci.c
+++ b/hw/usb/hcd-xhci.c
@@ -1180,7 +1180,7 @@ static int xhci_epmask_to_eps_with_streams(XHCIState *xhci,
     slot = &xhci->slots[slotid - 1];
 
     for (i = 2, j = 0; i <= 31; i++) {
-        if (!(epmask & (1 << i))) {
+        if (!(epmask & (1u << i))) {
             continue;
         }
 
@@ -2465,7 +2465,7 @@ static TRBCCode xhci_configure_slot(XHCIState *xhci, unsigned int slotid,
     res = xhci_alloc_device_streams(xhci, slotid, ictl_ctx[1]);
     if (res != CC_SUCCESS) {
         for (i = 2; i <= 31; i++) {
-            if (ictl_ctx[1] & (1 << i)) {
+            if (ictl_ctx[1] & (1u << i)) {
                 xhci_disable_ep(xhci, slotid, i);
             }
         }
commit cae7f29c47dee0bd0474fa7f1dda28b115a34d33
Author: Jack Un <jack.un at gmail.com>
Date:   Sat Aug 9 23:34:36 2014 +0300

    Fix OHCI ISO TD state never being written back.
    
    There appears to be typo in OHCI with isochronous transfers
    resulting in isoch. transfer descriptor state never being written back.
    The'put_words' function is in a OR statement hence it is never called.
    
    Signed-off-by: Jack Un <jack.un at gmail.com>
    Signed-off-by: Gerd Hoffmann <kraxel at redhat.com>

diff --git a/hw/usb/hcd-ohci.c b/hw/usb/hcd-ohci.c
index 13afdf5..cacf7b0 100644
--- a/hw/usb/hcd-ohci.c
+++ b/hw/usb/hcd-ohci.c
@@ -619,8 +619,8 @@ static inline int ohci_put_td(OHCIState *ohci,
 static inline int ohci_put_iso_td(OHCIState *ohci,
                                   dma_addr_t addr, struct ohci_iso_td *td)
 {
-    return put_dwords(ohci, addr, (uint32_t *)td, 4 ||
-           put_words(ohci, addr + 16, td->offset, 8));
+    return put_dwords(ohci, addr, (uint32_t *)td, 4) ||
+           put_words(ohci, addr + 16, td->offset, 8);
 }
 
 static inline int ohci_put_hcca(OHCIState *ohci,
commit 8c244210d842b71e838c8fc5219b6ab3e4063d71
Author: Gonglei <arei.gonglei at huawei.com>
Date:   Thu Aug 21 20:48:58 2014 +0800

    xhci: fix debug print compiling error
    
    after commit 003e15a180373048f0c1f4df0bfe303746eb2676
    the DPRINTF will broke compiling, adjust its location.
    
    Signed-off-by: Gonglei <arei.gonglei at huawei.com>
    Signed-off-by: Gerd Hoffmann <kraxel at redhat.com>

diff --git a/hw/usb/hcd-xhci.c b/hw/usb/hcd-xhci.c
index 58c4b11..aed8e9f 100644
--- a/hw/usb/hcd-xhci.c
+++ b/hw/usb/hcd-xhci.c
@@ -1380,14 +1380,11 @@ static void xhci_init_epctx(XHCIEPContext *epctx,
     dequeue = xhci_addr64(ctx[2] & ~0xf, ctx[3]);
 
     epctx->type = (ctx[1] >> EP_TYPE_SHIFT) & EP_TYPE_MASK;
-    DPRINTF("xhci: endpoint %d.%d type is %d\n", epid/2, epid%2, epctx->type);
     epctx->pctx = pctx;
     epctx->max_psize = ctx[1]>>16;
     epctx->max_psize *= 1+((ctx[1]>>8)&0xff);
     epctx->max_pstreams = (ctx[0] >> 10) & 0xf;
     epctx->lsa = (ctx[0] >> 15) & 1;
-    DPRINTF("xhci: endpoint %d.%d max transaction (burst) size is %d\n",
-            epid/2, epid%2, epctx->max_psize);
     if (epctx->max_pstreams) {
         xhci_alloc_streams(epctx, dequeue);
     } else {
@@ -1418,6 +1415,9 @@ static TRBCCode xhci_enable_ep(XHCIState *xhci, unsigned int slotid,
     slot->eps[epid-1] = epctx;
     xhci_init_epctx(epctx, pctx, ctx);
 
+    DPRINTF("xhci: endpoint %d.%d type is %d, max transaction (burst) "
+            "size is %d\n", epid/2, epid%2, epctx->type, epctx->max_psize);
+
     epctx->mfindex_last = 0;
 
     epctx->state = EP_RUNNING;
commit 830cd54fca126f5dab9b34b48a61304f2401e982
Author: Markus Armbruster <armbru at redhat.com>
Date:   Fri Aug 15 13:32:36 2014 +0200

    usb: Fix bootindex for portnr > 9
    
    We identify devices by their Open Firmware device paths.  The encoding
    of the host controller and hub port numbers is incorrect:
    usb_get_fw_dev_path() formats them in decimal, while SeaBIOS uses
    hexadecimal.  When some port number > 9, SeaBIOS will miss the
    bootindex (lucky case), or apply it to another device (unlucky case).
    
    The relevant spec[*] agrees with SeaBIOS (and OVMF, for that matter).
    Change %d to %x.
    
    Bug can bite only with host controllers or hubs sporting more than ten
    ports.  I'm not aware of any.
    
    [*] Open Firmware Recommended Practice: Universal Serial Bus,
    Version 1, Section 3.2.1 Device Node Address Representation
    http://www.openfirmware.org/1275/bindings/usb/usb-1_0.ps
    
    Signed-off-by: Markus Armbruster <armbru at redhat.com>
    Reviewed-by: Laszlo Ersek <lersek at redhat.com>
    
    Note: xhci can be configured with up to 15 ports (default is 4 ports).
    
    Signed-off-by: Gerd Hoffmann <kraxel at redhat.com>

diff --git a/hw/usb/bus.c b/hw/usb/bus.c
index 927a47b..516fb52 100644
--- a/hw/usb/bus.c
+++ b/hw/usb/bus.c
@@ -589,11 +589,11 @@ static char *usb_get_fw_dev_path(DeviceState *qdev)
         nr = strtol(in, &in, 10);
         if (in[0] == '.') {
             /* some hub between root port and device */
-            pos += snprintf(fw_path + pos, fw_len - pos, "hub@%ld/", nr);
+            pos += snprintf(fw_path + pos, fw_len - pos, "hub@%lx/", nr);
             in++;
         } else {
             /* the device itself */
-            pos += snprintf(fw_path + pos, fw_len - pos, "%s@%ld",
+            pos += snprintf(fw_path + pos, fw_len - pos, "%s@%lx",
                             qdev_fw_name(qdev), nr);
             break;
         }
commit a6aebb38ba4682951ab04fe6d6e6b169bd9e4dca
Merge: 38a01e5 d1dd32a
Author: Peter Maydell <peter.maydell at linaro.org>
Date:   Thu Aug 28 17:08:13 2014 +0100

    Merge remote-tracking branch 'remotes/bonzini/tags/for-upstream' into staging
    
    SCSI patches include bug fixes from Fam and Peter, improved error
    reporting from Fam and a fix for DPRINTF bitrot.  Memory patches try
    again to initialize name from the QOM name.
    
    # gpg: Signature made Thu 28 Aug 2014 15:10:31 BST using RSA key ID 9B4D86F2
    # gpg: Good signature from "Paolo Bonzini <pbonzini at redhat.com>"
    # gpg:                 aka "Paolo Bonzini <bonzini at gnu.org>"
    
    * remotes/bonzini/tags/for-upstream:
      memory: Lazy init name from QOM name as needed
      xen: hvm: Abstract away memory region name ref
      xen-hvm: Constify string
      virtio-scsi: Report error if num_queues is 0 or too large
      scsi-generic: remove superfluous DPRINTF avoid to break compiling
      block/iscsi: fix memory corruption on iscsi resize
      scsi-bus: Convert DeviceClass init to realize
      block: Pass errp in blkconf_geometry
    
    Signed-off-by: Peter Maydell <peter.maydell at linaro.org>

commit 38a01e55d268aeba68c84eea425252e7f810feaf
Merge: 795c050 172dbc5
Author: Peter Maydell <peter.maydell at linaro.org>
Date:   Thu Aug 28 16:07:23 2014 +0100

    Merge remote-tracking branch 'remotes/kvm/tags/for-upstream' into staging
    
    Mostly bugfixes + Alexey's interface-based implementation
    of the NMI monitor command.
    
    # gpg: Signature made Thu 28 Aug 2014 15:07:22 BST using RSA key ID 9B4D86F2
    # gpg: Good signature from "Paolo Bonzini <pbonzini at redhat.com>"
    # gpg:                 aka "Paolo Bonzini <bonzini at gnu.org>"
    
    * remotes/kvm/tags/for-upstream:
      mc146818rtc: reinitialize irq_reinject_on_ack_count on reset
      target-i386: Add "tsc_adjust" CPU feature name
      target-i386: Add "mpx" CPU feature name
      vl: process -object after other backend options
      checkpatch.pl: adjust typedef definition to QEMU coding style
      x86: Clear MTRRs on vCPU reset
      x86: kvm: Add MTRR support for kvm_get|put_msrs()
      x86: Use common variable range MTRR counts
      target-i386: Don't forbid NX bit on PAE PDEs and PTEs
      spapr: Add support for new NMI interface
      s390x: Migrate to new NMI interface
      s390x: Convert QEMUMachine to MachineClass
      cpus: Define callback for QEMU "nmi" command
      kvm: run cpu state synchronization on target vcpu thread
    
    Signed-off-by: Peter Maydell <peter.maydell at linaro.org>

commit d1dd32af6f37e5bb8e6b2024d07fce74f510a668
Author: Peter Crosthwaite <peter.crosthwaite at xilinx.com>
Date:   Mon Aug 25 20:10:24 2014 -0700

    memory: Lazy init name from QOM name as needed
    
    To support name retrieval of MemoryRegions that were created
    dynamically (that is, not via memory_region_init and friends). We
    cache the name in MemoryRegion's state as
    object_get_canonical_path_component mallocs the returned value
    so it's not suitable for direct return to callers. Memory already
    frees the name field, so this will be garbage collected along with
    the MR object.
    
    Signed-off-by: Peter Crosthwaite <peter.crosthwaite at xilinx.com>
    Signed-off-by: Paolo Bonzini <pbonzini at redhat.com>

diff --git a/memory.c b/memory.c
index 42317a2..ef0be1c 100644
--- a/memory.c
+++ b/memory.c
@@ -1309,6 +1309,10 @@ uint64_t memory_region_size(MemoryRegion *mr)
 
 const char *memory_region_name(const MemoryRegion *mr)
 {
+    if (!mr->name) {
+        ((MemoryRegion *)mr)->name =
+            object_get_canonical_path_component(OBJECT(mr));
+    }
     return mr->name;
 }
 
commit 3e1f50867b6872130cc19b7eadd93ab9ce268cdc
Author: Peter Crosthwaite <peter.crosthwaite at xilinx.com>
Date:   Mon Aug 25 20:09:48 2014 -0700

    xen: hvm: Abstract away memory region name ref
    
    The mr->name field is removed. This slipped through compile testing.
    Fix.
    
    Reviewed-by: Stefan Weil <sw at weilnetz.de>
    Signed-off-by: Peter Crosthwaite <peter.crosthwaite at xilinx.com>
    Signed-off-by: Paolo Bonzini <pbonzini at redhat.com>

diff --git a/xen-hvm.c b/xen-hvm.c
index d763e86..0d09940 100644
--- a/xen-hvm.c
+++ b/xen-hvm.c
@@ -291,6 +291,7 @@ static int xen_add_to_physmap(XenIOState *state,
     hwaddr pfn, start_gpfn;
     hwaddr phys_offset = memory_region_get_ram_addr(mr);
     char path[80], value[17];
+    const char *mr_name;
 
     if (get_physmapping(state, start_addr, size)) {
         return 0;
@@ -326,11 +327,13 @@ go_physmap:
         }
     }
 
+    mr_name = memory_region_name(mr);
+
     physmap = g_malloc(sizeof (XenPhysmap));
 
     physmap->start_addr = start_addr;
     physmap->size = size;
-    physmap->name = mr->name;
+    physmap->name = mr_name;
     physmap->phys_offset = phys_offset;
 
     QLIST_INSERT_HEAD(&state->physmap, physmap, list);
@@ -354,11 +357,11 @@ go_physmap:
     if (!xs_write(state->xenstore, 0, path, value, strlen(value))) {
         return -1;
     }
-    if (mr->name) {
+    if (mr_name) {
         snprintf(path, sizeof(path),
                 "/local/domain/0/device-model/%d/physmap/%"PRIx64"/name",
                 xen_domid, (uint64_t)phys_offset);
-        if (!xs_write(state->xenstore, 0, path, mr->name, strlen(mr->name))) {
+        if (!xs_write(state->xenstore, 0, path, mr_name, strlen(mr_name))) {
             return -1;
         }
     }
commit dc6c4fe8378b2e94bcf2ee2efa62ed0aba9aa5cc
Author: Peter Crosthwaite <peter.crosthwaite at xilinx.com>
Date:   Mon Aug 25 20:09:13 2014 -0700

    xen-hvm: Constify string
    
    It's constant, and sourced from existing const strings. Avoid dodgy
    casts by converting to const.
    
    Signed-off-by: Peter Crosthwaite <peter.crosthwaite at xilinx.com>
    Reviewed-by: Stefan Weil <sw at weilnetz.de>
    Signed-off-by: Paolo Bonzini <pbonzini at redhat.com>

diff --git a/xen-hvm.c b/xen-hvm.c
index 91de2e2..d763e86 100644
--- a/xen-hvm.c
+++ b/xen-hvm.c
@@ -71,7 +71,7 @@ static inline ioreq_t *xen_vcpu_ioreq(shared_iopage_t *shared_page, int vcpu)
 typedef struct XenPhysmap {
     hwaddr start_addr;
     ram_addr_t size;
-    char *name;
+    const char *name;
     hwaddr phys_offset;
 
     QLIST_ENTRY(XenPhysmap) list;
@@ -330,7 +330,7 @@ go_physmap:
 
     physmap->start_addr = start_addr;
     physmap->size = size;
-    physmap->name = (char *)mr->name;
+    physmap->name = mr->name;
     physmap->phys_offset = phys_offset;
 
     QLIST_INSERT_HEAD(&state->physmap, physmap, list);
commit 795c050e379ab21b75fc2bbb30699fe8752be157
Merge: 0265361 00c6d40
Author: Peter Maydell <peter.maydell at linaro.org>
Date:   Thu Aug 28 14:51:12 2014 +0100

    Merge remote-tracking branch 'remotes/stefanha/tags/fix-buildbot-12082014-pull-request' into staging
    
    Pull request
    
    # gpg: Signature made Thu 28 Aug 2014 13:43:00 BST using RSA key ID 81AB73C8
    # gpg: Good signature from "Stefan Hajnoczi <stefanha at redhat.com>"
    # gpg:                 aka "Stefan Hajnoczi <stefanha at gmail.com>"
    
    * remotes/stefanha/tags/fix-buildbot-12082014-pull-request:
      Revert "qemu-img: sort block formats in help message"
      block: sort formats alphabetically in bdrv_iterate_format()
      mirror: fix uninitialized variable delay_ns warnings
      trace: avoid Python 2.5 all() in tracetool
      libqtest: launch QEMU with QEMU_AUDIO_DRV=none
      qapi.py: avoid Python 2.5+ any() function
    
    Signed-off-by: Peter Maydell <peter.maydell at linaro.org>

commit 00c6d403a3ac303ebdcb1706ee983e13ba8e2d5f
Author: Stefan Hajnoczi <stefanha at redhat.com>
Date:   Wed Aug 27 12:08:56 2014 +0100

    Revert "qemu-img: sort block formats in help message"
    
    This reverts commit 1a443c1b8b4314d365e82bddeb1de5b4b1c15fb3 and the
    later commit 395071a76328189f50c778f4dee6dabb90503dd9.
    
    GSequence was introduced in glib 2.14.  RHEL 5 fails to compile since it
    uses glib 2.12.3.
    
    Now that bdrv_iterate_format() invokes the iteration callback in sorted
    order these commits are unnecessary.
    
    Signed-off-by: Stefan Hajnoczi <stefanha at redhat.com>
    Reviewed-by: Benoît Canet <benoit.canet at nodalink.com>

diff --git a/qemu-img.c b/qemu-img.c
index c843420..2052b14 100644
--- a/qemu-img.c
+++ b/qemu-img.c
@@ -32,7 +32,6 @@
 #include "block/block_int.h"
 #include "block/qapi.h"
 #include <getopt.h>
-#include <glib.h>
 
 #define QEMU_IMG_VERSION "qemu-img version " QEMU_VERSION \
                           ", Copyright (c) 2004-2008 Fabrice Bellard\n"
@@ -56,22 +55,9 @@ typedef enum OutputFormat {
 #define BDRV_O_FLAGS BDRV_O_CACHE_WB
 #define BDRV_DEFAULT_CACHE "writeback"
 
-static gint compare_data(gconstpointer a, gconstpointer b, gpointer user)
+static void format_print(void *opaque, const char *name)
 {
-    return g_strcmp0(a, b);
-}
-
-static void print_format(gpointer data, gpointer user)
-{
-    printf(" %s", (char *)data);
-}
-
-static void add_format_to_seq(void *opaque, const char *fmt_name)
-{
-    GSequence *seq = opaque;
-
-    g_sequence_insert_sorted(seq, (gpointer)fmt_name,
-                             compare_data, NULL);
+    printf(" %s", name);
 }
 
 static void QEMU_NORETURN GCC_FMT_ATTR(1, 2) error_exit(const char *fmt, ...)
@@ -157,15 +143,10 @@ static void QEMU_NORETURN help(void)
            "  '-f' first image format\n"
            "  '-F' second image format\n"
            "  '-s' run in Strict mode - fail on different image size or sector allocation\n";
-    GSequence *seq;
 
     printf("%s\nSupported formats:", help_msg);
-    seq = g_sequence_new(NULL);
-    bdrv_iterate_format(add_format_to_seq, seq);
-    g_sequence_foreach(seq, print_format, NULL);
+    bdrv_iterate_format(format_print, NULL);
     printf("\n");
-    g_sequence_free(seq);
-
     exit(EXIT_SUCCESS);
 }
 
commit ada4240103470371533967334cda9965854fcbda
Author: Stefan Hajnoczi <stefanha at redhat.com>
Date:   Wed Aug 27 12:08:55 2014 +0100

    block: sort formats alphabetically in bdrv_iterate_format()
    
    Format names are best consumed in alphabetical order.  This makes
    human-readable output easy to produce.
    
    bdrv_iterate_format() already has an array of format strings.  Sort them
    before invoking the iteration callback.
    
    Signed-off-by: Stefan Hajnoczi <stefanha at redhat.com>
    Reviewed-by: Benoît Canet <benoit.canet at nodalink.com>

diff --git a/block.c b/block.c
index e9380f6..1df13ac 100644
--- a/block.c
+++ b/block.c
@@ -3744,11 +3744,17 @@ const char *bdrv_get_format_name(BlockDriverState *bs)
     return bs->drv ? bs->drv->format_name : NULL;
 }
 
+static int qsort_strcmp(const void *a, const void *b)
+{
+    return strcmp(a, b);
+}
+
 void bdrv_iterate_format(void (*it)(void *opaque, const char *name),
                          void *opaque)
 {
     BlockDriver *drv;
     int count = 0;
+    int i;
     const char **formats = NULL;
 
     QLIST_FOREACH(drv, &bdrv_drivers, list) {
@@ -3762,10 +3768,16 @@ void bdrv_iterate_format(void (*it)(void *opaque, const char *name),
             if (!found) {
                 formats = g_renew(const char *, formats, count + 1);
                 formats[count++] = drv->format_name;
-                it(opaque, drv->format_name);
             }
         }
     }
+
+    qsort(formats, count, sizeof(formats[0]), qsort_strcmp);
+
+    for (i = 0; i < count; i++) {
+        it(opaque, formats[i]);
+    }
+
     g_free(formats);
 }
 
commit 6d0de8eb21b7a581999ca89a9b447fd1c91e23db
Author: Stefan Hajnoczi <stefanha at redhat.com>
Date:   Wed Aug 27 12:08:54 2014 +0100

    mirror: fix uninitialized variable delay_ns warnings
    
    The gcc 4.1.2 compiler warns that delay_ns may be uninitialized in
    mirror_iteration().
    
    There are two break statements in the do ... while loop that skip over
    the delay_ns assignment.  These are probably the cause of the warning.
    
    Signed-off-by: Stefan Hajnoczi <stefanha at redhat.com>
    Reviewed-by: Benoît Canet <benoit.canet at nodalink.com>

diff --git a/block/mirror.c b/block/mirror.c
index 5e7a166..18b18e0 100644
--- a/block/mirror.c
+++ b/block/mirror.c
@@ -157,7 +157,7 @@ static uint64_t coroutine_fn mirror_iteration(MirrorBlockJob *s)
     BlockDriverState *source = s->common.bs;
     int nb_sectors, sectors_per_chunk, nb_chunks;
     int64_t end, sector_num, next_chunk, next_sector, hbitmap_next_sector;
-    uint64_t delay_ns;
+    uint64_t delay_ns = 0;
     MirrorOp *op;
 
     s->sector_num = hbitmap_iter_next(&s->hbi);
@@ -247,8 +247,6 @@ static uint64_t coroutine_fn mirror_iteration(MirrorBlockJob *s)
         next_chunk += added_chunks;
         if (!s->synced && s->common.speed) {
             delay_ns = ratelimit_calculate_delay(&s->limit, added_sectors);
-        } else {
-            delay_ns = 0;
         }
     } while (delay_ns == 0 && next_sector < end);
 
commit 73735f72188bd5fe25c3478aa4a2f1a17cb878d8
Author: Stefan Hajnoczi <stefanha at redhat.com>
Date:   Wed Aug 27 12:08:53 2014 +0100

    trace: avoid Python 2.5 all() in tracetool
    
    Red Hat Enterprise Linux 5 ships Python 2.4.3.  The all() function was
    added in Python 2.5 so we cannot use it.
    
    Signed-off-by: Stefan Hajnoczi <stefanha at redhat.com>
    Reviewed-by: Benoît Canet <benoit.canet at nodalink.com>

diff --git a/scripts/tracetool/backend/__init__.py b/scripts/tracetool/backend/__init__.py
index 5bfa1ef..d4b6dab 100644
--- a/scripts/tracetool/backend/__init__.py
+++ b/scripts/tracetool/backend/__init__.py
@@ -102,7 +102,8 @@ class Wrapper:
     def __init__(self, backends, format):
         self._backends = [backend.replace("-", "_") for backend in backends]
         self._format = format.replace("-", "_")
-        assert all(exists(backend) for backend in self._backends)
+        for backend in self._backends:
+            assert exists(backend)
         assert tracetool.format.exists(self._format)
 
     def _run_function(self, name, *args, **kwargs):
commit 6b029216056b8e64a6b5b7c43d1342cd4ef7ebc0
Author: Stefan Hajnoczi <stefanha at redhat.com>
Date:   Wed Aug 27 12:08:52 2014 +0100

    libqtest: launch QEMU with QEMU_AUDIO_DRV=none
    
    No test case actually uses the audio backend.  Disable audio to prevent
    warnings on hosts with no sound hardware present:
    
      GTESTER check-qtest-aarch64
      sdl: SDL_OpenAudio failed
      sdl: Reason: No available audio device
      sdl: SDL_OpenAudio failed
      sdl: Reason: No available audio device
      audio: Failed to create voice `lm4549.out'
    
    Signed-off-by: Stefan Hajnoczi <stefanha at redhat.com>
    Reviewed-by: Gerd Hoffmann <kraxel at redhat.com>

diff --git a/tests/libqtest.c b/tests/libqtest.c
index ed55686..5e458e8 100644
--- a/tests/libqtest.c
+++ b/tests/libqtest.c
@@ -165,6 +165,7 @@ QTestState *qtest_init(const char *extra_args)
 
     s->qemu_pid = fork();
     if (s->qemu_pid == 0) {
+        setenv("QEMU_AUDIO_DRV", "none", true);
         command = g_strdup_printf("exec %s "
                                   "-qtest unix:%s,nowait "
                                   "-qtest-log %s "
commit 7ac9a9d6e1fbc702dee8d2a2eb3151bc704104dc
Author: Stefan Hajnoczi <stefanha at redhat.com>
Date:   Wed Aug 27 12:08:51 2014 +0100

    qapi.py: avoid Python 2.5+ any() function
    
    There is one instance of any() in qapi.py that breaks builds on older
    distros that ship Python 2.4 (like RHEL5):
    
      GEN   qmp-commands.h
    Traceback (most recent call last):
      File "build/scripts/qapi-commands.py", line 445, in ?
        exprs = parse_schema(input_file)
      File "build/scripts/qapi.py", line 329, in parse_schema
        schema = QAPISchema(open(input_file, "r"))
      File "build/scripts/qapi.py", line 110, in __init__
        if any(include_path == elem[1]
    NameError: global name 'any' is not defined
    
    Signed-off-by: Stefan Hajnoczi <stefanha at redhat.com>
    Reviewed-by: Benoît Canet <benoit.canet at nodalink.com>

diff --git a/scripts/qapi.py b/scripts/qapi.py
index f2c6d1f..77d46aa 100644
--- a/scripts/qapi.py
+++ b/scripts/qapi.py
@@ -107,10 +107,10 @@ class QAPISchema:
                                         'Expected a file name (string), got: %s'
                                         % include)
                 include_path = os.path.join(self.input_dir, include)
-                if any(include_path == elem[1]
-                       for elem in self.include_hist):
-                    raise QAPIExprError(expr_info, "Inclusion loop for %s"
-                                        % include)
+                for elem in self.include_hist:
+                    if include_path == elem[1]:
+                        raise QAPIExprError(expr_info, "Inclusion loop for %s"
+                                            % include)
                 # skip multiple include of the same file
                 if include_path in previously_included:
                     continue
commit 172dbc52b39c86d7569af5251cca78cb2c74c912
Author: Paolo Bonzini <pbonzini at redhat.com>
Date:   Wed Aug 27 17:54:52 2014 +0200

    mc146818rtc: reinitialize irq_reinject_on_ack_count on reset
    
    This field was forgotten, and it makes the state after reset
    non-deterministic.
    
    Signed-off-by: Paolo Bonzini <pbonzini at redhat.com>

diff --git a/hw/timer/mc146818rtc.c b/hw/timer/mc146818rtc.c
index 233fc70..4df650f 100644
--- a/hw/timer/mc146818rtc.c
+++ b/hw/timer/mc146818rtc.c
@@ -792,6 +792,7 @@ static void rtc_reset(void *opaque)
 #ifdef TARGET_I386
     if (s->lost_tick_policy == LOST_TICK_POLICY_SLEW) {
         s->irq_coalesced = 0;
+        s->irq_reinject_on_ack_count = 0;		
     }
 #endif
 }
commit 0265361a722f396cbdb35ecffbadb93142a6e87d
Merge: c47c61b d2a68f3
Author: Peter Maydell <peter.maydell at linaro.org>
Date:   Tue Aug 26 14:18:40 2014 +0100

    Merge remote-tracking branch 'remotes/mcayland/qemu-openbios' into staging
    
    * remotes/mcayland/qemu-openbios:
      Update OpenBIOS images
    
    Signed-off-by: Peter Maydell <peter.maydell at linaro.org>

commit 7b458bfd12a71b3da6b531daedc417492c9334e0
Author: Eduardo Habkost <ehabkost at redhat.com>
Date:   Mon Aug 25 17:02:13 2014 -0300

    target-i386: Add "tsc_adjust" CPU feature name
    
    tsc_adjust migration support is already implemented (commit
    f28558d3d37ad3bc4e35e8ac93f7bf81a0d5622c), so we can add it to the list
    of known feature names.
    
    Signed-off-by: Eduardo Habkost <ehabkost at redhat.com>
    Signed-off-by: Paolo Bonzini <pbonzini at redhat.com>

diff --git a/target-i386/cpu.c b/target-i386/cpu.c
index f4ee353..fa811a0 100644
--- a/target-i386/cpu.c
+++ b/target-i386/cpu.c
@@ -257,7 +257,7 @@ static const char *svm_feature_name[] = {
 };
 
 static const char *cpuid_7_0_ebx_feature_name[] = {
-    "fsgsbase", NULL, NULL, "bmi1", "hle", "avx2", NULL, "smep",
+    "fsgsbase", "tsc_adjust", NULL, "bmi1", "hle", "avx2", NULL, "smep",
     "bmi2", "erms", "invpcid", "rtm", NULL, NULL, "mpx", NULL,
     NULL, NULL, "rdseed", "adx", "smap", NULL, NULL, NULL,
     NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
commit 5bd8ff07e65d066f1e90f05d49ee634f3ccd2664
Author: Eduardo Habkost <ehabkost at redhat.com>
Date:   Mon Aug 25 17:02:12 2014 -0300

    target-i386: Add "mpx" CPU feature name
    
    Migration support for MPX is already implemented (commit
    79e9ebebbf2a00c46fcedb6dc7dd5e12bbd30216), so we can add it to the list
    of known feature names.
    
    Signed-off-by: Eduardo Habkost <ehabkost at redhat.com>
    Signed-off-by: Paolo Bonzini <pbonzini at redhat.com>

diff --git a/target-i386/cpu.c b/target-i386/cpu.c
index 52e335f..f4ee353 100644
--- a/target-i386/cpu.c
+++ b/target-i386/cpu.c
@@ -258,7 +258,7 @@ static const char *svm_feature_name[] = {
 
 static const char *cpuid_7_0_ebx_feature_name[] = {
     "fsgsbase", NULL, NULL, "bmi1", "hle", "avx2", NULL, "smep",
-    "bmi2", "erms", "invpcid", "rtm", NULL, NULL, NULL, NULL,
+    "bmi2", "erms", "invpcid", "rtm", NULL, NULL, "mpx", NULL,
     NULL, NULL, "rdseed", "adx", "smap", NULL, NULL, NULL,
     NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
 };
commit d2a68f3a303ce0ad10ac9bec98290c91df06eccd
Author: Mark Cave-Ayland <mark.cave-ayland at ilande.co.uk>
Date:   Tue Aug 26 13:52:15 2014 +0100

    Update OpenBIOS images
    
    Update OpenBIOS images to SVN r1316 built from submodule.
    
    Signed-off-by: Mark Cave-Ayland <mark.cave-ayland at ilande.co.uk>

diff --git a/pc-bios/openbios-ppc b/pc-bios/openbios-ppc
index 0f2fc3a..e136516 100644
Binary files a/pc-bios/openbios-ppc and b/pc-bios/openbios-ppc differ
diff --git a/pc-bios/openbios-sparc32 b/pc-bios/openbios-sparc32
index 8917b55..2274bcf 100644
Binary files a/pc-bios/openbios-sparc32 and b/pc-bios/openbios-sparc32 differ
diff --git a/pc-bios/openbios-sparc64 b/pc-bios/openbios-sparc64
index cf72a59..635fe7e 100644
Binary files a/pc-bios/openbios-sparc64 and b/pc-bios/openbios-sparc64 differ
diff --git a/roms/openbios b/roms/openbios
index a056ccb..d9e38ba 160000
--- a/roms/openbios
+++ b/roms/openbios
@@ -1 +1 @@
-Subproject commit a056ccbebaa802b22bed59e2e07ea78f256243cb
+Subproject commit d9e38ba2ffd2d2cdfa840ea9bc7dd4a64472f2c7
commit 7b71758d79106a63a0b8aba02df752d9995ea50c
Author: Paolo Bonzini <pbonzini at redhat.com>
Date:   Mon Aug 25 13:47:00 2014 +0200

    vl: process -object after other backend options
    
    QOM backends can refer to chardevs, but not vice versa.  So
    process -chardev and -fsdev options before -object
    
    This fixes the rng-egd backend to virtio-rng.
    
    Reported-by: Amos Kong <akong at redhat.com>
    Cc: qemu-stable at nongnu.org
    Signed-off-by: Paolo Bonzini <pbonzini at redhat.com>

diff --git a/vl.c b/vl.c
index b796c67..95be92d 100644
--- a/vl.c
+++ b/vl.c
@@ -4033,11 +4033,6 @@ int main(int argc, char **argv, char **envp)
         qemu_set_version(machine_class->hw_version);
     }
 
-    if (qemu_opts_foreach(qemu_find_opts("object"),
-                          object_create, NULL, 0) != 0) {
-        exit(1);
-    }
-
     /* Init CPU def lists, based on config
      * - Must be called after all the qemu_read_config_file() calls
      * - Must be called before list_cpus()
@@ -4249,6 +4244,11 @@ int main(int argc, char **argv, char **envp)
         exit(0);
     }
 
+    if (qemu_opts_foreach(qemu_find_opts("object"),
+                          object_create, NULL, 0) != 0) {
+        exit(1);
+    }
+
     machine_opts = qemu_get_machine_opts();
     if (qemu_opt_foreach(machine_opts, object_set_property, current_machine,
                          1) < 0) {
commit a6859deb6908261c9a9adf9cc4b8863fc0897b5c
Author: Paolo Bonzini <pbonzini at redhat.com>
Date:   Tue Jun 10 10:52:02 2014 +0200

    checkpatch.pl: adjust typedef definition to QEMU coding style
    
    Most QEMU typedefs are camelcase, starting with one uppercase letter
    and containing at least one lowercase letter.  There are a few
    all-uppercase types, add the most common too.
    
    This fixes recognition of types in lines such as
    
        static __attribute__((unused)) inline void tcg_out8(TCGContext *s, uint8_t v)
    
    (Example provided by Peter Maydell).
    
    Reported-by: Alexey Kardashevskiy <aik at ozlabs.ru>
    Reviewed-by: Markus Armbruster <armbru at redhat.com>
    Cc: Peter Maydell <peter.maydell at linaro.org>
    Cc: Stefan Weil <sw at weilnetz.de>
    Signed-off-by: Paolo Bonzini <pbonzini at redhat.com>

diff --git a/scripts/checkpatch.pl b/scripts/checkpatch.pl
index 9d46e5a..053e432 100755
--- a/scripts/checkpatch.pl
+++ b/scripts/checkpatch.pl
@@ -206,9 +206,13 @@ our $UTF8	= qr {
 	|  \xF4[\x80-\x8F][\x80-\xBF]{2}     # plane 16
 }x;
 
+# There are still some false positives, but this catches most
+# common cases.
 our $typeTypedefs = qr{(?x:
-	(?:__)?(?:u|s|be|le)(?:8|16|32|64)|
-	atomic_t
+        [A-Z][A-Z\d_]*[a-z][A-Za-z\d_]*     # camelcase
+        | [A-Z][A-Z\d_]*AIOCB               # all uppercase
+        | [A-Z][A-Z\d_]*CPU                 # all uppercase
+        | QEMUBH                            # all uppercase
 )};
 
 our $logFunctions = qr{(?x:
commit c9f6552803d852d593dec9ef5bb39b7a61091963
Author: Fam Zheng <famz at redhat.com>
Date:   Tue Aug 26 14:30:30 2014 +0800

    virtio-scsi: Report error if num_queues is 0 or too large
    
    No cmd vq surprises guest (Linux panics in virtscsi_probe), too many
    queues abort qemu (in the following virtio_add_queue).
    
    Signed-off-by: Fam Zheng <famz at redhat.com>
    Signed-off-by: Paolo Bonzini <pbonzini at redhat.com>

diff --git a/hw/scsi/virtio-scsi.c b/hw/scsi/virtio-scsi.c
index 2dd9255..86aba88 100644
--- a/hw/scsi/virtio-scsi.c
+++ b/hw/scsi/virtio-scsi.c
@@ -699,6 +699,12 @@ void virtio_scsi_common_realize(DeviceState *dev, Error **errp,
     virtio_init(vdev, "virtio-scsi", VIRTIO_ID_SCSI,
                 sizeof(VirtIOSCSIConfig));
 
+    if (s->conf.num_queues <= 0 || s->conf.num_queues > VIRTIO_PCI_QUEUE_MAX) {
+        error_setg(errp, "Invalid number of queues (= %" PRId32 "), "
+                         "must be a positive integer less than %d.",
+                   s->conf.num_queues, VIRTIO_PCI_QUEUE_MAX);
+        return;
+    }
     s->cmd_vqs = g_malloc0(s->conf.num_queues * sizeof(VirtQueue *));
     s->sense_size = VIRTIO_SCSI_SENSE_SIZE;
     s->cdb_size = VIRTIO_SCSI_CDB_SIZE;
commit f93d2c15d603b811c877efbf2a47e418bf975f0c
Author: Gonglei <arei.gonglei at huawei.com>
Date:   Fri Aug 22 10:01:50 2014 +0800

    scsi-generic: remove superfluous DPRINTF avoid to break compiling
    
    variables lun and tag had been eliminated, break compiling
    when enable debug switch. Meanwhile traces provide the same
    information with this DPRINTF, so remove it.
    
    Signed-off-by: Gonglei <arei.gonglei at huawei.com>
    Signed-off-by: Paolo Bonzini <pbonzini at redhat.com>

diff --git a/hw/scsi/scsi-generic.c b/hw/scsi/scsi-generic.c
index 3ebe4a6..20587b4 100644
--- a/hw/scsi/scsi-generic.c
+++ b/hw/scsi/scsi-generic.c
@@ -303,9 +303,6 @@ static int32_t scsi_send_command(SCSIRequest *req, uint8_t *cmd)
     SCSIDevice *s = r->req.dev;
     int ret;
 
-    DPRINTF("Command: lun=%d tag=0x%x len %zd data=0x%02x", lun, tag,
-            r->req.cmd.xfer, cmd[0]);
-
 #ifdef DEBUG_SCSI
     {
         int i;
commit 9db693f76441e2fc7e1b05dc454e7db4d3298dcb
Author: Peter Lieven <pl at kamp.de>
Date:   Fri Aug 22 10:08:49 2014 +0200

    block/iscsi: fix memory corruption on iscsi resize
    
    bs->total_sectors is not yet updated at this point. resulting
    in memory corruption if the volume has grown and data is written
    to the newly availble areas.
    
    CC: qemu-stable at nongnu.org
    Signed-off-by: Peter Lieven <pl at kamp.de>
    Signed-off-by: Paolo Bonzini <pbonzini at redhat.com>

diff --git a/block/iscsi.c b/block/iscsi.c
index 2c9cfc1..0bde13d 100644
--- a/block/iscsi.c
+++ b/block/iscsi.c
@@ -1512,7 +1512,8 @@ static int iscsi_truncate(BlockDriverState *bs, int64_t offset)
     if (iscsilun->allocationmap != NULL) {
         g_free(iscsilun->allocationmap);
         iscsilun->allocationmap =
-            bitmap_new(DIV_ROUND_UP(bs->total_sectors,
+            bitmap_new(DIV_ROUND_UP(sector_lun2qemu(iscsilun->num_blocks,
+                                                    iscsilun),
                                     iscsilun->cluster_sectors));
     }
 
commit a818a4b69d47ca3826dee36878074395aeac2083
Author: Fam Zheng <famz at redhat.com>
Date:   Tue Aug 12 10:12:55 2014 +0800

    scsi-bus: Convert DeviceClass init to realize
    
    Replace "init/destroy" with "realize/unrealize" in SCSIDeviceClass,
    which has errp as a parameter. So all the implementations now use
    error_setg instead of error_report for reporting error.
    
    Also in scsi_bus_legacy_handle_cmdline, report the error when
    initializing the if=scsi devices, before returning it, because in the
    callee, error_report is changed to error_setg. And the callers don't
    have the right locations (e.g. "-drive if=scsi").
    
    Reviewed-by: Stefan Hajnoczi <stefanha at redhat.com>
    Signed-off-by: Fam Zheng <famz at redhat.com>
    Signed-off-by: Paolo Bonzini <pbonzini at redhat.com>

diff --git a/hw/scsi/lsi53c895a.c b/hw/scsi/lsi53c895a.c
index 513ea47..d9b4c7e 100644
--- a/hw/scsi/lsi53c895a.c
+++ b/hw/scsi/lsi53c895a.c
@@ -19,6 +19,7 @@
 #include "hw/pci/pci.h"
 #include "hw/scsi/scsi.h"
 #include "sysemu/dma.h"
+#include "qemu/error-report.h"
 
 //#define DEBUG_LSI
 //#define DEBUG_LSI_REG
diff --git a/hw/scsi/scsi-bus.c b/hw/scsi/scsi-bus.c
index 6f4462b..954c607 100644
--- a/hw/scsi/scsi-bus.c
+++ b/hw/scsi/scsi-bus.c
@@ -36,20 +36,19 @@ static const TypeInfo scsi_bus_info = {
 };
 static int next_scsi_bus;
 
-static int scsi_device_init(SCSIDevice *s)
+static void scsi_device_realize(SCSIDevice *s, Error **errp)
 {
     SCSIDeviceClass *sc = SCSI_DEVICE_GET_CLASS(s);
-    if (sc->init) {
-        return sc->init(s);
+    if (sc->realize) {
+        sc->realize(s, errp);
     }
-    return 0;
 }
 
-static void scsi_device_destroy(SCSIDevice *s)
+static void scsi_device_unrealize(SCSIDevice *s, Error **errp)
 {
     SCSIDeviceClass *sc = SCSI_DEVICE_GET_CLASS(s);
-    if (sc->destroy) {
-        sc->destroy(s);
+    if (sc->unrealize) {
+        sc->unrealize(s, errp);
     }
 }
 
@@ -143,24 +142,24 @@ static void scsi_dma_restart_cb(void *opaque, int running, RunState state)
     }
 }
 
-static int scsi_qdev_init(DeviceState *qdev)
+static void scsi_qdev_realize(DeviceState *qdev, Error **errp)
 {
     SCSIDevice *dev = SCSI_DEVICE(qdev);
     SCSIBus *bus = DO_UPCAST(SCSIBus, qbus, dev->qdev.parent_bus);
     SCSIDevice *d;
-    int rc = -1;
+    Error *local_err = NULL;
 
     if (dev->channel > bus->info->max_channel) {
-        error_report("bad scsi channel id: %d", dev->channel);
-        goto err;
+        error_setg(errp, "bad scsi channel id: %d", dev->channel);
+        return;
     }
     if (dev->id != -1 && dev->id > bus->info->max_target) {
-        error_report("bad scsi device id: %d", dev->id);
-        goto err;
+        error_setg(errp, "bad scsi device id: %d", dev->id);
+        return;
     }
     if (dev->lun != -1 && dev->lun > bus->info->max_lun) {
-        error_report("bad scsi device lun: %d", dev->lun);
-        goto err;
+        error_setg(errp, "bad scsi device lun: %d", dev->lun);
+        return;
     }
 
     if (dev->id == -1) {
@@ -172,8 +171,8 @@ static int scsi_qdev_init(DeviceState *qdev)
             d = scsi_device_find(bus, dev->channel, ++id, dev->lun);
         } while (d && d->lun == dev->lun && id < bus->info->max_target);
         if (d && d->lun == dev->lun) {
-            error_report("no free target");
-            goto err;
+            error_setg(errp, "no free target");
+            return;
         }
         dev->id = id;
     } else if (dev->lun == -1) {
@@ -182,43 +181,41 @@ static int scsi_qdev_init(DeviceState *qdev)
             d = scsi_device_find(bus, dev->channel, dev->id, ++lun);
         } while (d && d->lun == lun && lun < bus->info->max_lun);
         if (d && d->lun == lun) {
-            error_report("no free lun");
-            goto err;
+            error_setg(errp, "no free lun");
+            return;
         }
         dev->lun = lun;
     } else {
         d = scsi_device_find(bus, dev->channel, dev->id, dev->lun);
         assert(d);
         if (d->lun == dev->lun && dev != d) {
-            error_report("lun already used by '%s'", d->qdev.id);
-            goto err;
+            error_setg(errp, "lun already used by '%s'", d->qdev.id);
+            return;
         }
     }
 
     QTAILQ_INIT(&dev->requests);
-    rc = scsi_device_init(dev);
-    if (rc == 0) {
-        dev->vmsentry = qemu_add_vm_change_state_handler(scsi_dma_restart_cb,
-                                                         dev);
+    scsi_device_realize(dev, &local_err);
+    if (local_err) {
+        error_propagate(errp, local_err);
+        return;
     }
+    dev->vmsentry = qemu_add_vm_change_state_handler(scsi_dma_restart_cb,
+                                                     dev);
 
     if (bus->info->hotplug) {
         bus->info->hotplug(bus, dev);
     }
-
-err:
-    return rc;
 }
 
-static int scsi_qdev_exit(DeviceState *qdev)
+static void scsi_qdev_unrealize(DeviceState *qdev, Error **errp)
 {
     SCSIDevice *dev = SCSI_DEVICE(qdev);
 
     if (dev->vmsentry) {
         qemu_del_vm_change_state_handler(dev->vmsentry);
     }
-    scsi_device_destroy(dev);
-    return 0;
+    scsi_device_unrealize(dev, errp);
 }
 
 /* handle legacy '-drive if=scsi,...' cmd line args */
@@ -273,6 +270,7 @@ void scsi_bus_legacy_handle_cmdline(SCSIBus *bus, Error **errp)
         scsi_bus_legacy_add_drive(bus, dinfo->bdrv, unit, false, -1, NULL,
                                   &err);
         if (err != NULL) {
+            error_report("%s", error_get_pretty(err));
             error_propagate(errp, err);
             break;
         }
@@ -1992,11 +1990,11 @@ static void scsi_device_class_init(ObjectClass *klass, void *data)
 {
     DeviceClass *k = DEVICE_CLASS(klass);
     set_bit(DEVICE_CATEGORY_STORAGE, k->categories);
-    k->bus_type = TYPE_SCSI_BUS;
-    k->init     = scsi_qdev_init;
-    k->unplug   = scsi_qdev_unplug;
-    k->exit     = scsi_qdev_exit;
-    k->props    = scsi_props;
+    k->bus_type  = TYPE_SCSI_BUS;
+    k->realize   = scsi_qdev_realize;
+    k->unplug    = scsi_qdev_unplug;
+    k->unrealize = scsi_qdev_unrealize;
+    k->props     = scsi_props;
 }
 
 static const TypeInfo scsi_device_type_info = {
diff --git a/hw/scsi/scsi-disk.c b/hw/scsi/scsi-disk.c
index b7ebdd7..e34a544 100644
--- a/hw/scsi/scsi-disk.c
+++ b/hw/scsi/scsi-disk.c
@@ -2151,7 +2151,7 @@ static void scsi_disk_reset(DeviceState *dev)
     s->tray_open = 0;
 }
 
-static void scsi_destroy(SCSIDevice *dev)
+static void scsi_unrealize(SCSIDevice *dev, Error **errp)
 {
     SCSIDiskState *s = DO_UPCAST(SCSIDiskState, qdev, dev);
 
@@ -2234,29 +2234,28 @@ static void scsi_disk_unit_attention_reported(SCSIDevice *dev)
     }
 }
 
-static int scsi_initfn(SCSIDevice *dev)
+static void scsi_realize(SCSIDevice *dev, Error **errp)
 {
     SCSIDiskState *s = DO_UPCAST(SCSIDiskState, qdev, dev);
     Error *err = NULL;
 
     if (!s->qdev.conf.bs) {
-        error_report("drive property not set");
-        return -1;
+        error_setg(errp, "drive property not set");
+        return;
     }
 
     if (!(s->features & (1 << SCSI_DISK_F_REMOVABLE)) &&
         !bdrv_is_inserted(s->qdev.conf.bs)) {
-        error_report("Device needs media, but drive is empty");
-        return -1;
+        error_setg(errp, "Device needs media, but drive is empty");
+        return;
     }
 
     blkconf_serial(&s->qdev.conf, &s->serial);
     if (dev->type == TYPE_DISK) {
         blkconf_geometry(&dev->conf, NULL, 65535, 255, 255, &err);
         if (err) {
-            error_report("%s", error_get_pretty(err));
-            error_free(err);
-            return -1;
+            error_propagate(errp, err);
+            return;
         }
     }
 
@@ -2273,8 +2272,8 @@ static int scsi_initfn(SCSIDevice *dev)
     }
 
     if (bdrv_is_sg(s->qdev.conf.bs)) {
-        error_report("unwanted /dev/sg*");
-        return -1;
+        error_setg(errp, "unwanted /dev/sg*");
+        return;
     }
 
     if ((s->features & (1 << SCSI_DISK_F_REMOVABLE)) &&
@@ -2287,10 +2286,9 @@ static int scsi_initfn(SCSIDevice *dev)
 
     bdrv_iostatus_enable(s->qdev.conf.bs);
     add_boot_device_path(s->qdev.conf.bootindex, &dev->qdev, NULL);
-    return 0;
 }
 
-static int scsi_hd_initfn(SCSIDevice *dev)
+static void scsi_hd_realize(SCSIDevice *dev, Error **errp)
 {
     SCSIDiskState *s = DO_UPCAST(SCSIDiskState, qdev, dev);
     s->qdev.blocksize = s->qdev.conf.logical_block_size;
@@ -2298,10 +2296,10 @@ static int scsi_hd_initfn(SCSIDevice *dev)
     if (!s->product) {
         s->product = g_strdup("QEMU HARDDISK");
     }
-    return scsi_initfn(&s->qdev);
+    scsi_realize(&s->qdev, errp);
 }
 
-static int scsi_cd_initfn(SCSIDevice *dev)
+static void scsi_cd_realize(SCSIDevice *dev, Error **errp)
 {
     SCSIDiskState *s = DO_UPCAST(SCSIDiskState, qdev, dev);
     s->qdev.blocksize = 2048;
@@ -2310,22 +2308,26 @@ static int scsi_cd_initfn(SCSIDevice *dev)
     if (!s->product) {
         s->product = g_strdup("QEMU CD-ROM");
     }
-    return scsi_initfn(&s->qdev);
+    scsi_realize(&s->qdev, errp);
 }
 
-static int scsi_disk_initfn(SCSIDevice *dev)
+static void scsi_disk_realize(SCSIDevice *dev, Error **errp)
 {
     DriveInfo *dinfo;
+    Error *local_err = NULL;
 
     if (!dev->conf.bs) {
-        return scsi_initfn(dev);  /* ... and die there */
+        scsi_realize(dev, &local_err);
+        assert(local_err);
+        error_propagate(errp, local_err);
+        return;
     }
 
     dinfo = drive_get_by_blockdev(dev->conf.bs);
     if (dinfo->media_cd) {
-        return scsi_cd_initfn(dev);
+        scsi_cd_realize(dev, errp);
     } else {
-        return scsi_hd_initfn(dev);
+        scsi_hd_realize(dev, errp);
     }
 }
 
@@ -2457,35 +2459,35 @@ static int get_device_type(SCSIDiskState *s)
     return 0;
 }
 
-static int scsi_block_initfn(SCSIDevice *dev)
+static void scsi_block_realize(SCSIDevice *dev, Error **errp)
 {
     SCSIDiskState *s = DO_UPCAST(SCSIDiskState, qdev, dev);
     int sg_version;
     int rc;
 
     if (!s->qdev.conf.bs) {
-        error_report("drive property not set");
-        return -1;
+        error_setg(errp, "drive property not set");
+        return;
     }
 
     /* check we are using a driver managing SG_IO (version 3 and after) */
     rc = bdrv_ioctl(s->qdev.conf.bs, SG_GET_VERSION_NUM, &sg_version);
     if (rc < 0) {
-        error_report("cannot get SG_IO version number: %s.  "
+        error_setg(errp, "cannot get SG_IO version number: %s.  "
                      "Is this a SCSI device?",
                      strerror(-rc));
-        return -1;
+        return;
     }
     if (sg_version < 30000) {
-        error_report("scsi generic interface too old");
-        return -1;
+        error_setg(errp, "scsi generic interface too old");
+        return;
     }
 
     /* get device type from INQUIRY data */
     rc = get_device_type(s);
     if (rc < 0) {
-        error_report("INQUIRY failed");
-        return -1;
+        error_setg(errp, "INQUIRY failed");
+        return;
     }
 
     /* Make a guess for the block size, we'll fix it when the guest sends.
@@ -2503,7 +2505,7 @@ static int scsi_block_initfn(SCSIDevice *dev)
      */
     s->features |= (1 << SCSI_DISK_F_NO_REMOVABLE_DEVOPS);
 
-    return scsi_initfn(&s->qdev);
+    scsi_realize(&s->qdev, errp);
 }
 
 static bool scsi_block_is_passthrough(SCSIDiskState *s, uint8_t *buf)
@@ -2626,8 +2628,8 @@ static void scsi_hd_class_initfn(ObjectClass *klass, void *data)
     DeviceClass *dc = DEVICE_CLASS(klass);
     SCSIDeviceClass *sc = SCSI_DEVICE_CLASS(klass);
 
-    sc->init         = scsi_hd_initfn;
-    sc->destroy      = scsi_destroy;
+    sc->realize      = scsi_hd_realize;
+    sc->unrealize    = scsi_unrealize;
     sc->alloc_req    = scsi_new_request;
     sc->unit_attention_reported = scsi_disk_unit_attention_reported;
     dc->fw_name = "disk";
@@ -2657,8 +2659,8 @@ static void scsi_cd_class_initfn(ObjectClass *klass, void *data)
     DeviceClass *dc = DEVICE_CLASS(klass);
     SCSIDeviceClass *sc = SCSI_DEVICE_CLASS(klass);
 
-    sc->init         = scsi_cd_initfn;
-    sc->destroy      = scsi_destroy;
+    sc->realize      = scsi_cd_realize;
+    sc->unrealize    = scsi_unrealize;
     sc->alloc_req    = scsi_new_request;
     sc->unit_attention_reported = scsi_disk_unit_attention_reported;
     dc->fw_name = "disk";
@@ -2687,8 +2689,8 @@ static void scsi_block_class_initfn(ObjectClass *klass, void *data)
     DeviceClass *dc = DEVICE_CLASS(klass);
     SCSIDeviceClass *sc = SCSI_DEVICE_CLASS(klass);
 
-    sc->init         = scsi_block_initfn;
-    sc->destroy      = scsi_destroy;
+    sc->realize      = scsi_block_realize;
+    sc->unrealize    = scsi_unrealize;
     sc->alloc_req    = scsi_block_new_request;
     sc->parse_cdb    = scsi_block_parse_cdb;
     dc->fw_name = "disk";
@@ -2725,8 +2727,8 @@ static void scsi_disk_class_initfn(ObjectClass *klass, void *data)
     DeviceClass *dc = DEVICE_CLASS(klass);
     SCSIDeviceClass *sc = SCSI_DEVICE_CLASS(klass);
 
-    sc->init         = scsi_disk_initfn;
-    sc->destroy      = scsi_destroy;
+    sc->realize      = scsi_disk_realize;
+    sc->unrealize    = scsi_unrealize;
     sc->alloc_req    = scsi_new_request;
     sc->unit_attention_reported = scsi_disk_unit_attention_reported;
     dc->fw_name = "disk";
diff --git a/hw/scsi/scsi-generic.c b/hw/scsi/scsi-generic.c
index 0b2ff90..3ebe4a6 100644
--- a/hw/scsi/scsi-generic.c
+++ b/hw/scsi/scsi-generic.c
@@ -386,49 +386,49 @@ static void scsi_generic_reset(DeviceState *dev)
     scsi_device_purge_requests(s, SENSE_CODE(RESET));
 }
 
-static void scsi_destroy(SCSIDevice *s)
+static void scsi_unrealize(SCSIDevice *s, Error **errp)
 {
     scsi_device_purge_requests(s, SENSE_CODE(NO_SENSE));
     blockdev_mark_auto_del(s->conf.bs);
 }
 
-static int scsi_generic_initfn(SCSIDevice *s)
+static void scsi_generic_realize(SCSIDevice *s, Error **errp)
 {
     int rc;
     int sg_version;
     struct sg_scsi_id scsiid;
 
     if (!s->conf.bs) {
-        error_report("drive property not set");
-        return -1;
+        error_setg(errp, "drive property not set");
+        return;
     }
 
     if (bdrv_get_on_error(s->conf.bs, 0) != BLOCKDEV_ON_ERROR_ENOSPC) {
-        error_report("Device doesn't support drive option werror");
-        return -1;
+        error_setg(errp, "Device doesn't support drive option werror");
+        return;
     }
     if (bdrv_get_on_error(s->conf.bs, 1) != BLOCKDEV_ON_ERROR_REPORT) {
-        error_report("Device doesn't support drive option rerror");
-        return -1;
+        error_setg(errp, "Device doesn't support drive option rerror");
+        return;
     }
 
     /* check we are using a driver managing SG_IO (version 3 and after */
     rc = bdrv_ioctl(s->conf.bs, SG_GET_VERSION_NUM, &sg_version);
     if (rc < 0) {
-        error_report("cannot get SG_IO version number: %s.  "
-                     "Is this a SCSI device?",
-                     strerror(-rc));
-        return -1;
+        error_setg(errp, "cannot get SG_IO version number: %s.  "
+                         "Is this a SCSI device?",
+                         strerror(-rc));
+        return;
     }
     if (sg_version < 30000) {
-        error_report("scsi generic interface too old");
-        return -1;
+        error_setg(errp, "scsi generic interface too old");
+        return;
     }
 
     /* get LUN of the /dev/sg? */
     if (bdrv_ioctl(s->conf.bs, SG_GET_SCSI_ID, &scsiid)) {
-        error_report("SG_GET_SCSI_ID ioctl failed");
-        return -1;
+        error_setg(errp, "SG_GET_SCSI_ID ioctl failed");
+        return;
     }
 
     /* define device state */
@@ -460,7 +460,6 @@ static int scsi_generic_initfn(SCSIDevice *s)
     }
 
     DPRINTF("block size %d\n", s->blocksize);
-    return 0;
 }
 
 const SCSIReqOps scsi_generic_req_ops = {
@@ -501,8 +500,8 @@ static void scsi_generic_class_initfn(ObjectClass *klass, void *data)
     DeviceClass *dc = DEVICE_CLASS(klass);
     SCSIDeviceClass *sc = SCSI_DEVICE_CLASS(klass);
 
-    sc->init         = scsi_generic_initfn;
-    sc->destroy      = scsi_destroy;
+    sc->realize      = scsi_generic_realize;
+    sc->unrealize    = scsi_unrealize;
     sc->alloc_req    = scsi_new_request;
     sc->parse_cdb    = scsi_generic_parse_cdb;
     dc->fw_name = "disk";
diff --git a/include/hw/scsi/scsi.h b/include/hw/scsi/scsi.h
index a7a28e6..2e3a8f9 100644
--- a/include/hw/scsi/scsi.h
+++ b/include/hw/scsi/scsi.h
@@ -74,8 +74,8 @@ struct SCSIRequest {
 
 typedef struct SCSIDeviceClass {
     DeviceClass parent_class;
-    int (*init)(SCSIDevice *dev);
-    void (*destroy)(SCSIDevice *s);
+    void (*realize)(SCSIDevice *dev, Error **errp);
+    void (*unrealize)(SCSIDevice *dev, Error **errp);
     int (*parse_cdb)(SCSIDevice *dev, SCSICommand *cmd, uint8_t *buf,
                      void *hba_private);
     SCSIRequest *(*alloc_req)(SCSIDevice *s, uint32_t tag, uint32_t lun,
diff --git a/tests/qemu-iotests/051.out b/tests/qemu-iotests/051.out
index d7b0f50..a3f2820 100644
--- a/tests/qemu-iotests/051.out
+++ b/tests/qemu-iotests/051.out
@@ -149,13 +149,11 @@ QEMU_PROG: -device ide-hd,drive=disk: Device 'ide-hd' could not be initialized
 Testing: -drive if=none,id=disk -device lsi53c895a -device scsi-disk,drive=disk
 QEMU X.Y.Z monitor - type 'help' for more information
 (qemu) QEMU_PROG: -device scsi-disk,drive=disk: Device needs media, but drive is empty
-QEMU_PROG: -device scsi-disk,drive=disk: Device initialization failed.
 QEMU_PROG: -device scsi-disk,drive=disk: Device 'scsi-disk' could not be initialized
 
 Testing: -drive if=none,id=disk -device lsi53c895a -device scsi-hd,drive=disk
 QEMU X.Y.Z monitor - type 'help' for more information
 (qemu) QEMU_PROG: -device scsi-hd,drive=disk: Device needs media, but drive is empty
-QEMU_PROG: -device scsi-hd,drive=disk: Device initialization failed.
 QEMU_PROG: -device scsi-hd,drive=disk: Device 'scsi-hd' could not be initialized
 
 
commit 5ff5efb46c4526f111e14c2247609f1c56f0f8f3
Author: Fam Zheng <famz at redhat.com>
Date:   Tue Aug 12 10:12:54 2014 +0800

    block: Pass errp in blkconf_geometry
    
    This allows us to pass error information to caller.
    
    Reviewed-by: Andreas Färber <afaerber at suse.de>
    Reviewed-by: Stefan Hajnoczi <stefanha at redhat.com>
    Signed-off-by: Fam Zheng <famz at redhat.com>
    Signed-off-by: Paolo Bonzini <pbonzini at redhat.com>

diff --git a/hw/block/block.c b/hw/block/block.c
index 33dd3f3..b6a6dc6 100644
--- a/hw/block/block.c
+++ b/hw/block/block.c
@@ -22,8 +22,9 @@ void blkconf_serial(BlockConf *conf, char **serial)
     }
 }
 
-int blkconf_geometry(BlockConf *conf, int *ptrans,
-                     unsigned cyls_max, unsigned heads_max, unsigned secs_max)
+void blkconf_geometry(BlockConf *conf, int *ptrans,
+                      unsigned cyls_max, unsigned heads_max, unsigned secs_max,
+                      Error **errp)
 {
     DriveInfo *dinfo;
 
@@ -46,17 +47,16 @@ int blkconf_geometry(BlockConf *conf, int *ptrans,
     }
     if (conf->cyls || conf->heads || conf->secs) {
         if (conf->cyls < 1 || conf->cyls > cyls_max) {
-            error_report("cyls must be between 1 and %u", cyls_max);
-            return -1;
+            error_setg(errp, "cyls must be between 1 and %u", cyls_max);
+            return;
         }
         if (conf->heads < 1 || conf->heads > heads_max) {
-            error_report("heads must be between 1 and %u", heads_max);
-            return -1;
+            error_setg(errp, "heads must be between 1 and %u", heads_max);
+            return;
         }
         if (conf->secs < 1 || conf->secs > secs_max) {
-            error_report("secs must be between 1 and %u", secs_max);
-            return -1;
+            error_setg(errp, "secs must be between 1 and %u", secs_max);
+            return;
         }
     }
-    return 0;
 }
diff --git a/hw/block/virtio-blk.c b/hw/block/virtio-blk.c
index 302c39e..0b68a17 100644
--- a/hw/block/virtio-blk.c
+++ b/hw/block/virtio-blk.c
@@ -728,9 +728,7 @@ static void virtio_blk_device_realize(DeviceState *dev, Error **errp)
     VirtIODevice *vdev = VIRTIO_DEVICE(dev);
     VirtIOBlock *s = VIRTIO_BLK(dev);
     VirtIOBlkConf *blk = &(s->blk);
-#ifdef CONFIG_VIRTIO_BLK_DATA_PLANE
     Error *err = NULL;
-#endif
     static int virtio_blk_id;
 
     if (!blk->conf.bs) {
@@ -744,8 +742,9 @@ static void virtio_blk_device_realize(DeviceState *dev, Error **errp)
 
     blkconf_serial(&blk->conf, &blk->serial);
     s->original_wce = bdrv_enable_write_cache(blk->conf.bs);
-    if (blkconf_geometry(&blk->conf, NULL, 65535, 255, 255) < 0) {
-        error_setg(errp, "Error setting geometry");
+    blkconf_geometry(&blk->conf, NULL, 65535, 255, 255, &err);
+    if (err) {
+        error_propagate(errp, err);
         return;
     }
 
diff --git a/hw/ide/qdev.c b/hw/ide/qdev.c
index 6e475e6..b4a4671 100644
--- a/hw/ide/qdev.c
+++ b/hw/ide/qdev.c
@@ -151,6 +151,7 @@ static int ide_dev_initfn(IDEDevice *dev, IDEDriveKind kind)
 {
     IDEBus *bus = DO_UPCAST(IDEBus, qbus, dev->qdev.parent_bus);
     IDEState *s = bus->ifs + dev->unit;
+    Error *err = NULL;
 
     if (dev->conf.discard_granularity == -1) {
         dev->conf.discard_granularity = 512;
@@ -161,9 +162,13 @@ static int ide_dev_initfn(IDEDevice *dev, IDEDriveKind kind)
     }
 
     blkconf_serial(&dev->conf, &dev->serial);
-    if (kind != IDE_CD
-        && blkconf_geometry(&dev->conf, &dev->chs_trans, 65536, 16, 255) < 0) {
-        return -1;
+    if (kind != IDE_CD) {
+        blkconf_geometry(&dev->conf, &dev->chs_trans, 65536, 16, 255, &err);
+        if (err) {
+            error_report("%s", error_get_pretty(err));
+            error_free(err);
+            return -1;
+        }
     }
 
     if (ide_init_drive(s, dev->conf.bs, kind,
diff --git a/hw/scsi/scsi-disk.c b/hw/scsi/scsi-disk.c
index d55521d..b7ebdd7 100644
--- a/hw/scsi/scsi-disk.c
+++ b/hw/scsi/scsi-disk.c
@@ -2237,6 +2237,7 @@ static void scsi_disk_unit_attention_reported(SCSIDevice *dev)
 static int scsi_initfn(SCSIDevice *dev)
 {
     SCSIDiskState *s = DO_UPCAST(SCSIDiskState, qdev, dev);
+    Error *err = NULL;
 
     if (!s->qdev.conf.bs) {
         error_report("drive property not set");
@@ -2250,9 +2251,13 @@ static int scsi_initfn(SCSIDevice *dev)
     }
 
     blkconf_serial(&s->qdev.conf, &s->serial);
-    if (dev->type == TYPE_DISK
-        && blkconf_geometry(&dev->conf, NULL, 65535, 255, 255) < 0) {
-        return -1;
+    if (dev->type == TYPE_DISK) {
+        blkconf_geometry(&dev->conf, NULL, 65535, 255, 255, &err);
+        if (err) {
+            error_report("%s", error_get_pretty(err));
+            error_free(err);
+            return -1;
+        }
     }
 
     if (s->qdev.conf.discard_granularity == -1) {
diff --git a/include/hw/block/block.h b/include/hw/block/block.h
index 7c3d6c8..3a01488 100644
--- a/include/hw/block/block.h
+++ b/include/hw/block/block.h
@@ -12,6 +12,7 @@
 #define HW_BLOCK_COMMON_H
 
 #include "qemu-common.h"
+#include "qapi/error.h"
 
 /* Configuration */
 
@@ -60,8 +61,9 @@ static inline unsigned int get_physical_block_exp(BlockConf *conf)
 /* Configuration helpers */
 
 void blkconf_serial(BlockConf *conf, char **serial);
-int blkconf_geometry(BlockConf *conf, int *trans,
-                     unsigned cyls_max, unsigned heads_max, unsigned secs_max);
+void blkconf_geometry(BlockConf *conf, int *trans,
+                      unsigned cyls_max, unsigned heads_max, unsigned secs_max,
+                      Error **errp);
 
 /* Hard disk geometry */
 
commit 9db2efd95e13330075bff027cd682a063d725332
Author: Alex Williamson <alex.williamson at redhat.com>
Date:   Thu Aug 14 15:39:39 2014 -0600

    x86: Clear MTRRs on vCPU reset
    
    The SDM specifies (June 2014 Vol3 11.11.5):
    
        On a hardware reset, the P6 and more recent processors clear the
        valid flags in variable-range MTRRs and clear the E flag in the
        IA32_MTRR_DEF_TYPE MSR to disable all MTRRs. All other bits in the
        MTRRs are undefined.
    
    We currently do none of that, so whatever MTRR settings you had prior
    to reset is what you have after reset.  Usually this doesn't matter
    because KVM often ignores the guest mappings and uses write-back
    anyway.  However, if you have an assigned device and an IOMMU that
    allows NoSnoop for that device, KVM defers to the guest memory
    mappings which are now stale after reset.  The result is that OVMF
    rebooting on such a configuration takes a full minute to LZMA
    decompress the firmware volume, a process that is nearly instant on
    the initial boot.
    
    Signed-off-by: Alex Williamson <alex.williamson at redhat.com>
    Reviewed-by: Laszlo Ersek <lersek at redhat.com>
    Cc: qemu-stable at nongnu.org
    Signed-off-by: Paolo Bonzini <pbonzini at redhat.com>

diff --git a/target-i386/cpu.c b/target-i386/cpu.c
index 217500c..52e335f 100644
--- a/target-i386/cpu.c
+++ b/target-i386/cpu.c
@@ -2588,6 +2588,16 @@ static void x86_cpu_reset(CPUState *s)
 
     env->xcr0 = 1;
 
+    /*
+     * SDM 11.11.5 requires:
+     *  - IA32_MTRR_DEF_TYPE MSR.E = 0
+     *  - IA32_MTRR_PHYSMASKn.V = 0
+     * All other bits are undefined.  For simplification, zero it all.
+     */
+    env->mtrr_deftype = 0;
+    memset(env->mtrr_var, 0, sizeof(env->mtrr_var));
+    memset(env->mtrr_fixed, 0, sizeof(env->mtrr_fixed));
+
 #if !defined(CONFIG_USER_ONLY)
     /* We hard-wire the BSP to the first CPU. */
     if (s->cpu_index == 0) {
commit d1ae67f626c5ed5729e1d8212834291b409d26df
Author: Alex Williamson <alex.williamson at redhat.com>
Date:   Thu Aug 14 15:39:33 2014 -0600

    x86: kvm: Add MTRR support for kvm_get|put_msrs()
    
    The MTRR state in KVM currently runs completely independent of the
    QEMU state in CPUX86State.mtrr_*.  This means that on migration, the
    target loses MTRR state from the source.  Generally that's ok though
    because KVM ignores it and maps everything as write-back anyway.  The
    exception to this rule is when we have an assigned device and an IOMMU
    that doesn't promote NoSnoop transactions from that device to be cache
    coherent.  In that case KVM trusts the guest mapping of memory as
    configured in the MTRR.
    
    This patch updates kvm_get|put_msrs() so that we retrieve the actual
    vCPU MTRR settings and therefore keep CPUX86State synchronized for
    migration.  kvm_put_msrs() is also used on vCPU reset and therefore
    allows future modificaitons of MTRR state at reset to be realized.
    
    Note that the entries array used by both functions was already
    slightly undersized for holding every possible MSR, so this patch
    increases it beyond the 28 new entries necessary for MTRR state.
    
    Signed-off-by: Alex Williamson <alex.williamson at redhat.com>
    Reviewed-by: Laszlo Ersek <lersek at redhat.com>
    Cc: qemu-stable at nongnu.org
    Signed-off-by: Paolo Bonzini <pbonzini at redhat.com>

diff --git a/target-i386/cpu.h b/target-i386/cpu.h
index d37d857..3460b12 100644
--- a/target-i386/cpu.h
+++ b/target-i386/cpu.h
@@ -337,6 +337,8 @@
 #define MSR_MTRRphysBase(reg)           (0x200 + 2 * (reg))
 #define MSR_MTRRphysMask(reg)           (0x200 + 2 * (reg) + 1)
 
+#define MSR_MTRRphysIndex(addr)         ((((addr) & ~1u) - 0x200) / 2)
+
 #define MSR_MTRRfix64K_00000            0x250
 #define MSR_MTRRfix16K_80000            0x258
 #define MSR_MTRRfix16K_A0000            0x259
diff --git a/target-i386/kvm.c b/target-i386/kvm.c
index 097fe11..ddedc73 100644
--- a/target-i386/kvm.c
+++ b/target-i386/kvm.c
@@ -79,6 +79,7 @@ static int lm_capable_kernel;
 static bool has_msr_hv_hypercall;
 static bool has_msr_hv_vapic;
 static bool has_msr_hv_tsc;
+static bool has_msr_mtrr;
 
 static bool has_msr_architectural_pmu;
 static uint32_t num_architectural_pmu_counters;
@@ -739,6 +740,10 @@ int kvm_arch_init_vcpu(CPUState *cs)
         env->kvm_xsave_buf = qemu_memalign(4096, sizeof(struct kvm_xsave));
     }
 
+    if (env->features[FEAT_1_EDX] & CPUID_MTRR) {
+        has_msr_mtrr = true;
+    }
+
     return 0;
 }
 
@@ -1183,7 +1188,7 @@ static int kvm_put_msrs(X86CPU *cpu, int level)
     CPUX86State *env = &cpu->env;
     struct {
         struct kvm_msrs info;
-        struct kvm_msr_entry entries[100];
+        struct kvm_msr_entry entries[150];
     } msr_data;
     struct kvm_msr_entry *msrs = msr_data.entries;
     int n = 0, i;
@@ -1278,6 +1283,37 @@ static int kvm_put_msrs(X86CPU *cpu, int level)
             kvm_msr_entry_set(&msrs[n++], HV_X64_MSR_REFERENCE_TSC,
                               env->msr_hv_tsc);
         }
+        if (has_msr_mtrr) {
+            kvm_msr_entry_set(&msrs[n++], MSR_MTRRdefType, env->mtrr_deftype);
+            kvm_msr_entry_set(&msrs[n++],
+                              MSR_MTRRfix64K_00000, env->mtrr_fixed[0]);
+            kvm_msr_entry_set(&msrs[n++],
+                              MSR_MTRRfix16K_80000, env->mtrr_fixed[1]);
+            kvm_msr_entry_set(&msrs[n++],
+                              MSR_MTRRfix16K_A0000, env->mtrr_fixed[2]);
+            kvm_msr_entry_set(&msrs[n++],
+                              MSR_MTRRfix4K_C0000, env->mtrr_fixed[3]);
+            kvm_msr_entry_set(&msrs[n++],
+                              MSR_MTRRfix4K_C8000, env->mtrr_fixed[4]);
+            kvm_msr_entry_set(&msrs[n++],
+                              MSR_MTRRfix4K_D0000, env->mtrr_fixed[5]);
+            kvm_msr_entry_set(&msrs[n++],
+                              MSR_MTRRfix4K_D8000, env->mtrr_fixed[6]);
+            kvm_msr_entry_set(&msrs[n++],
+                              MSR_MTRRfix4K_E0000, env->mtrr_fixed[7]);
+            kvm_msr_entry_set(&msrs[n++],
+                              MSR_MTRRfix4K_E8000, env->mtrr_fixed[8]);
+            kvm_msr_entry_set(&msrs[n++],
+                              MSR_MTRRfix4K_F0000, env->mtrr_fixed[9]);
+            kvm_msr_entry_set(&msrs[n++],
+                              MSR_MTRRfix4K_F8000, env->mtrr_fixed[10]);
+            for (i = 0; i < MSR_MTRRcap_VCNT; i++) {
+                kvm_msr_entry_set(&msrs[n++],
+                                  MSR_MTRRphysBase(i), env->mtrr_var[i].base);
+                kvm_msr_entry_set(&msrs[n++],
+                                  MSR_MTRRphysMask(i), env->mtrr_var[i].mask);
+            }
+        }
 
         /* Note: MSR_IA32_FEATURE_CONTROL is written separately, see
          *       kvm_put_msr_feature_control. */
@@ -1484,7 +1520,7 @@ static int kvm_get_msrs(X86CPU *cpu)
     CPUX86State *env = &cpu->env;
     struct {
         struct kvm_msrs info;
-        struct kvm_msr_entry entries[100];
+        struct kvm_msr_entry entries[150];
     } msr_data;
     struct kvm_msr_entry *msrs = msr_data.entries;
     int ret, i, n;
@@ -1572,6 +1608,24 @@ static int kvm_get_msrs(X86CPU *cpu)
     if (has_msr_hv_tsc) {
         msrs[n++].index = HV_X64_MSR_REFERENCE_TSC;
     }
+    if (has_msr_mtrr) {
+        msrs[n++].index = MSR_MTRRdefType;
+        msrs[n++].index = MSR_MTRRfix64K_00000;
+        msrs[n++].index = MSR_MTRRfix16K_80000;
+        msrs[n++].index = MSR_MTRRfix16K_A0000;
+        msrs[n++].index = MSR_MTRRfix4K_C0000;
+        msrs[n++].index = MSR_MTRRfix4K_C8000;
+        msrs[n++].index = MSR_MTRRfix4K_D0000;
+        msrs[n++].index = MSR_MTRRfix4K_D8000;
+        msrs[n++].index = MSR_MTRRfix4K_E0000;
+        msrs[n++].index = MSR_MTRRfix4K_E8000;
+        msrs[n++].index = MSR_MTRRfix4K_F0000;
+        msrs[n++].index = MSR_MTRRfix4K_F8000;
+        for (i = 0; i < MSR_MTRRcap_VCNT; i++) {
+            msrs[n++].index = MSR_MTRRphysBase(i);
+            msrs[n++].index = MSR_MTRRphysMask(i);
+        }
+    }
 
     msr_data.info.nmsrs = n;
     ret = kvm_vcpu_ioctl(CPU(cpu), KVM_GET_MSRS, &msr_data);
@@ -1692,6 +1746,49 @@ static int kvm_get_msrs(X86CPU *cpu)
         case HV_X64_MSR_REFERENCE_TSC:
             env->msr_hv_tsc = msrs[i].data;
             break;
+        case MSR_MTRRdefType:
+            env->mtrr_deftype = msrs[i].data;
+            break;
+        case MSR_MTRRfix64K_00000:
+            env->mtrr_fixed[0] = msrs[i].data;
+            break;
+        case MSR_MTRRfix16K_80000:
+            env->mtrr_fixed[1] = msrs[i].data;
+            break;
+        case MSR_MTRRfix16K_A0000:
+            env->mtrr_fixed[2] = msrs[i].data;
+            break;
+        case MSR_MTRRfix4K_C0000:
+            env->mtrr_fixed[3] = msrs[i].data;
+            break;
+        case MSR_MTRRfix4K_C8000:
+            env->mtrr_fixed[4] = msrs[i].data;
+            break;
+        case MSR_MTRRfix4K_D0000:
+            env->mtrr_fixed[5] = msrs[i].data;
+            break;
+        case MSR_MTRRfix4K_D8000:
+            env->mtrr_fixed[6] = msrs[i].data;
+            break;
+        case MSR_MTRRfix4K_E0000:
+            env->mtrr_fixed[7] = msrs[i].data;
+            break;
+        case MSR_MTRRfix4K_E8000:
+            env->mtrr_fixed[8] = msrs[i].data;
+            break;
+        case MSR_MTRRfix4K_F0000:
+            env->mtrr_fixed[9] = msrs[i].data;
+            break;
+        case MSR_MTRRfix4K_F8000:
+            env->mtrr_fixed[10] = msrs[i].data;
+            break;
+        case MSR_MTRRphysBase(0) ... MSR_MTRRphysMask(MSR_MTRRcap_VCNT - 1):
+            if (index & 1) {
+                env->mtrr_var[MSR_MTRRphysIndex(index)].mask = msrs[i].data;
+            } else {
+                env->mtrr_var[MSR_MTRRphysIndex(index)].base = msrs[i].data;
+            }
+            break;
         }
     }
 
commit d8b5c67b05420d966664664ff287af05b884bdd1
Author: Alex Williamson <alex.williamson at redhat.com>
Date:   Thu Aug 14 15:39:27 2014 -0600

    x86: Use common variable range MTRR counts
    
    We currently define the number of variable range MTRR registers as 8
    in the CPUX86State structure and vmstate, but use MSR_MTRRcap_VCNT
    (also 8) to report to guests the number available.  Change this to
    use MSR_MTRRcap_VCNT consistently.
    
    Signed-off-by: Alex Williamson <alex.williamson at redhat.com>
    Reviewed-by: Laszlo Ersek <lersek at redhat.com>
    Cc: qemu-stable at nongnu.org
    Signed-off-by: Paolo Bonzini <pbonzini at redhat.com>

diff --git a/target-i386/cpu.h b/target-i386/cpu.h
index e634d83..d37d857 100644
--- a/target-i386/cpu.h
+++ b/target-i386/cpu.h
@@ -930,7 +930,7 @@ typedef struct CPUX86State {
     /* MTRRs */
     uint64_t mtrr_fixed[11];
     uint64_t mtrr_deftype;
-    MTRRVar mtrr_var[8];
+    MTRRVar mtrr_var[MSR_MTRRcap_VCNT];
 
     /* For KVM */
     uint32_t mp_state;
diff --git a/target-i386/machine.c b/target-i386/machine.c
index 16d2f6a..fb89065 100644
--- a/target-i386/machine.c
+++ b/target-i386/machine.c
@@ -677,7 +677,7 @@ VMStateDescription vmstate_x86_cpu = {
         /* MTRRs */
         VMSTATE_UINT64_ARRAY_V(env.mtrr_fixed, X86CPU, 11, 8),
         VMSTATE_UINT64_V(env.mtrr_deftype, X86CPU, 8),
-        VMSTATE_MTRR_VARS(env.mtrr_var, X86CPU, 8, 8),
+        VMSTATE_MTRR_VARS(env.mtrr_var, X86CPU, MSR_MTRRcap_VCNT, 8),
         /* KVM-related states */
         VMSTATE_INT32_V(env.interrupt_injected, X86CPU, 9),
         VMSTATE_UINT32_V(env.mp_state, X86CPU, 9),
commit 1844e68ecabbdfdf0228774bcd5cf0f63ffc2e57
Author: William Grant <wgrant at ubuntu.com>
Date:   Sun Aug 24 15:13:48 2014 +1000

    target-i386: Don't forbid NX bit on PAE PDEs and PTEs
    
    Commit e8f6d00c30ed88910d0d985f4b2bf41654172ceb ("target-i386: raise
    page fault for reserved physical address bits") added a check that the
    NX bit is not set on PAE PDPEs, but it also added it to rsvd_mask for
    the rest of the function. This caused any PDEs or PTEs with NX set to be
    erroneously rejected, making PAE guests with NX support unusable.
    
    Signed-off-by: William Grant <wgrant at ubuntu.com>
    Cc: qemu-stable at nongnu.org
    Signed-off-by: Paolo Bonzini <pbonzini at redhat.com>

diff --git a/target-i386/helper.c b/target-i386/helper.c
index 47b982b..30cb0d0 100644
--- a/target-i386/helper.c
+++ b/target-i386/helper.c
@@ -615,8 +615,8 @@ int x86_cpu_handle_mmu_fault(CPUState *cs, vaddr addr,
             if (!(pdpe & PG_PRESENT_MASK)) {
                 goto do_fault;
             }
-            rsvd_mask |= PG_HI_USER_MASK | PG_NX_MASK;
-            if (pdpe & rsvd_mask) {
+            rsvd_mask |= PG_HI_USER_MASK;
+            if (pdpe & (rsvd_mask | PG_NX_MASK)) {
                 goto do_fault_rsvd;
             }
             ptep = PG_NX_MASK | PG_USER_MASK | PG_RW_MASK;
commit 3431648272d317ed768fe46183c7a1cea4803732
Author: Alexey Kardashevskiy <aik at ozlabs.ru>
Date:   Wed Aug 20 22:16:36 2014 +1000

    spapr: Add support for new NMI interface
    
    This implements an NMI interface POWERPC SPAPR machine.
    This enables an "nmi" HMP/QMP command supported on SPAPR.
    
    This calls POWERPC_EXCP_RESET (vector 0x100) in the guest to deliver NMI
    to every CPU. The expected result is XMON (in-kernel debugger) invocation.
    
    Signed-off-by: Alexey Kardashevskiy <aik at ozlabs.ru>
    Reviewed-by: Alexander Graf <agraf at suse.de>
    Signed-off-by: Paolo Bonzini <pbonzini at redhat.com>

diff --git a/hw/ppc/spapr.c b/hw/ppc/spapr.c
index d01978f..5cb452f 100644
--- a/hw/ppc/spapr.c
+++ b/hw/ppc/spapr.c
@@ -55,6 +55,7 @@
 #include "qemu/config-file.h"
 #include "qemu/error-report.h"
 #include "trace.h"
+#include "hw/nmi.h"
 
 #include <libfdt.h>
 
@@ -1576,10 +1577,28 @@ static void spapr_machine_initfn(Object *obj)
                             spapr_get_kvm_type, spapr_set_kvm_type, NULL);
 }
 
+static void ppc_cpu_do_nmi_on_cpu(void *arg)
+{
+    CPUState *cs = arg;
+
+    cpu_synchronize_state(cs);
+    ppc_cpu_do_system_reset(cs);
+}
+
+static void spapr_nmi(NMIState *n, int cpu_index, Error **errp)
+{
+    CPUState *cs;
+
+    CPU_FOREACH(cs) {
+        async_run_on_cpu(cs, ppc_cpu_do_nmi_on_cpu, cs);
+    }
+}
+
 static void spapr_machine_class_init(ObjectClass *oc, void *data)
 {
     MachineClass *mc = MACHINE_CLASS(oc);
     FWPathProviderClass *fwc = FW_PATH_PROVIDER_CLASS(oc);
+    NMIClass *nc = NMI_CLASS(oc);
 
     mc->name = "pseries";
     mc->desc = "pSeries Logical Partition (PAPR compliant)";
@@ -1593,6 +1612,7 @@ static void spapr_machine_class_init(ObjectClass *oc, void *data)
     mc->kvm_type = spapr_kvm_type;
 
     fwc->get_dev_path = spapr_get_fw_dev_path;
+    nc->nmi_monitor_handler = spapr_nmi;
 }
 
 static const TypeInfo spapr_machine_info = {
@@ -1603,6 +1623,7 @@ static const TypeInfo spapr_machine_info = {
     .class_init    = spapr_machine_class_init,
     .interfaces = (InterfaceInfo[]) {
         { TYPE_FW_PATH_PROVIDER },
+        { TYPE_NMI },
         { }
     },
 };
diff --git a/target-ppc/cpu-qom.h b/target-ppc/cpu-qom.h
index 0fee36f..a379f79 100644
--- a/target-ppc/cpu-qom.h
+++ b/target-ppc/cpu-qom.h
@@ -127,6 +127,7 @@ int ppc64_cpu_write_elf64_qemunote(WriteCoreDumpFunction f,
 int ppc64_cpu_write_elf64_note(WriteCoreDumpFunction f, CPUState *cs,
                                int cpuid, void *opaque);
 #ifndef CONFIG_USER_ONLY
+void ppc_cpu_do_system_reset(CPUState *cs);
 extern const struct VMStateDescription vmstate_ppc_cpu;
 
 typedef struct PPCTimebase {
diff --git a/target-ppc/excp_helper.c b/target-ppc/excp_helper.c
index be71590..922e86d 100644
--- a/target-ppc/excp_helper.c
+++ b/target-ppc/excp_helper.c
@@ -810,6 +810,14 @@ void ppc_hw_interrupt(CPUPPCState *env)
         }
     }
 }
+
+void ppc_cpu_do_system_reset(CPUState *cs)
+{
+    PowerPCCPU *cpu = POWERPC_CPU(cs);
+    CPUPPCState *env = &cpu->env;
+
+    powerpc_excp(cpu, env->excp_model, POWERPC_EXCP_RESET);
+}
 #endif /* !CONFIG_USER_ONLY */
 
 #if defined(DEBUG_OP)
commit 3dd7852f1925ec1b3eca32c894e1a84882e145f1
Author: Alexey Kardashevskiy <aik at ozlabs.ru>
Date:   Wed Aug 20 22:16:35 2014 +1000

    s390x: Migrate to new NMI interface
    
    This implements an NMI interface for s390 and s390-ccw machines.
    
    This removes #ifdef s390 branch in qmp_inject_nmi so new s390's
    nmi_monitor_handler() callback is going to be used for NMI.
    
    Since nmi_monitor_handler()-calling code is platform independent,
    CPUState::cpu_index is used instead of S390CPU::env.cpu_num.
    There should not be any change in behaviour as both @cpu_index and
    @cpu_num are global CPU numbers.
    
    Note that s390_cpu_restart() already takes care of the specified cpu,
    so we don't need to schedule via async_run_on_cpu().
    
    Since the only error s390_cpu_restart() can return is ENOSYS, convert
    it to QERR_UNSUPPORTED.
    
    Signed-off-by: Alexey Kardashevskiy <aik at ozlabs.ru>
    Reviewed-by: Alexander Graf <agraf at suse.de>
    Reviewed-by: Cornelia Huck <cornelia.huck at de.ibm.com>
    Signed-off-by: Paolo Bonzini <pbonzini at redhat.com>

diff --git a/cpus.c b/cpus.c
index 37d90f4..eb1ac85 100644
--- a/cpus.c
+++ b/cpus.c
@@ -1537,20 +1537,6 @@ void qmp_inject_nmi(Error **errp)
             apic_deliver_nmi(cpu->apic_state);
         }
     }
-#elif defined(TARGET_S390X)
-    CPUState *cs;
-    S390CPU *cpu;
-
-    CPU_FOREACH(cs) {
-        cpu = S390_CPU(cs);
-        if (cpu->env.cpu_num == monitor_get_cpu_index()) {
-            if (s390_cpu_restart(S390_CPU(cs)) == -1) {
-                error_set(errp, QERR_UNSUPPORTED);
-                return;
-            }
-            break;
-        }
-    }
 #else
     nmi_monitor_handle(monitor_get_cpu_index(), errp);
 #endif
diff --git a/hw/s390x/s390-virtio-ccw.c b/hw/s390x/s390-virtio-ccw.c
index 05311b8..004b2c2 100644
--- a/hw/s390x/s390-virtio-ccw.c
+++ b/hw/s390x/s390-virtio-ccw.c
@@ -139,6 +139,7 @@ static void ccw_init(MachineState *machine)
 static void ccw_machine_class_init(ObjectClass *oc, void *data)
 {
     MachineClass *mc = MACHINE_CLASS(oc);
+    NMIClass *nc = NMI_CLASS(oc);
 
     mc->name = "s390-ccw-virtio";
     mc->alias = "s390-ccw";
@@ -152,12 +153,17 @@ static void ccw_machine_class_init(ObjectClass *oc, void *data)
     mc->no_sdcard = 1;
     mc->use_sclp = 1,
     mc->max_cpus = 255;
+    nc->nmi_monitor_handler = s390_nmi;
 }
 
 static const TypeInfo ccw_machine_info = {
     .name          = TYPE_S390_CCW_MACHINE,
     .parent        = TYPE_MACHINE,
     .class_init    = ccw_machine_class_init,
+    .interfaces = (InterfaceInfo[]) {
+        { TYPE_NMI },
+        { }
+    },
 };
 
 static void ccw_machine_register_types(void)
diff --git a/hw/s390x/s390-virtio.c b/hw/s390x/s390-virtio.c
index f1e0dbc..1a75a1c 100644
--- a/hw/s390x/s390-virtio.c
+++ b/hw/s390x/s390-virtio.c
@@ -280,9 +280,19 @@ static void s390_init(MachineState *machine)
     s390_create_virtio_net((BusState *)s390_bus, "virtio-net-s390");
 }
 
+void s390_nmi(NMIState *n, int cpu_index, Error **errp)
+{
+    CPUState *cs = qemu_get_cpu(cpu_index);
+
+    if (s390_cpu_restart(S390_CPU(cs))) {
+        error_set(errp, QERR_UNSUPPORTED);
+    }
+}
+
 static void s390_machine_class_init(ObjectClass *oc, void *data)
 {
     MachineClass *mc = MACHINE_CLASS(oc);
+    NMIClass *nc = NMI_CLASS(oc);
 
     mc->name = "s390-virtio";
     mc->alias = "s390";
@@ -297,12 +307,17 @@ static void s390_machine_class_init(ObjectClass *oc, void *data)
     mc->no_cdrom = 1;
     mc->no_sdcard = 1;
     mc->is_default = 1;
+    nc->nmi_monitor_handler = s390_nmi;
 }
 
 static const TypeInfo s390_machine_info = {
     .name          = TYPE_S390_MACHINE,
     .parent        = TYPE_MACHINE,
     .class_init    = s390_machine_class_init,
+    .interfaces = (InterfaceInfo[]) {
+        { TYPE_NMI },
+        { }
+    },
 };
 
 static void s390_machine_register_types(void)
diff --git a/hw/s390x/s390-virtio.h b/hw/s390x/s390-virtio.h
index 5c405e7..33847ae 100644
--- a/hw/s390x/s390-virtio.h
+++ b/hw/s390x/s390-virtio.h
@@ -12,6 +12,8 @@
 #ifndef HW_S390_VIRTIO_H
 #define HW_S390_VIRTIO_H 1
 
+#include "hw/nmi.h"
+
 #define KVM_S390_VIRTIO_NOTIFY          0
 #define KVM_S390_VIRTIO_RESET           1
 #define KVM_S390_VIRTIO_SET_STATUS      2
@@ -26,4 +28,5 @@ void s390_init_ipl_dev(const char *kernel_filename,
                        const char *initrd_filename,
                        const char *firmware);
 void s390_create_virtio_net(BusState *bus, const char *name);
+void s390_nmi(NMIState *n, int cpu_index, Error **errp);
 #endif
commit d07aa7c7bb06fdc9973059889b33dfca1d2efe55
Author: Alexey Kardashevskiy <aik at ozlabs.ru>
Date:   Wed Aug 20 22:16:34 2014 +1000

    s390x: Convert QEMUMachine to MachineClass
    
    This converts s390-virtio and s390-ccw-virtio machines to QOM MachineClass.
    This brings ability to add interfaces to the machine classes. The first
    interface for addition will be NMI.
    
    The patch is mechanical so no change in behavior is expected.
    
    Signed-off-by: Alexey Kardashevskiy <aik at ozlabs.ru>
    Reviewed-by: Cornelia Huck <cornelia.huck at de.ibm.com>
    Reviewed-by: Alexander Graf <agraf at suse.de>
    Signed-off-by: Paolo Bonzini <pbonzini at redhat.com>

diff --git a/hw/s390x/s390-virtio-ccw.c b/hw/s390x/s390-virtio-ccw.c
index 42f5cec..05311b8 100644
--- a/hw/s390x/s390-virtio-ccw.c
+++ b/hw/s390x/s390-virtio-ccw.c
@@ -18,6 +18,8 @@
 #include "css.h"
 #include "virtio-ccw.h"
 
+#define TYPE_S390_CCW_MACHINE               "s390-ccw-machine"
+
 void io_subsystem_reset(void)
 {
     DeviceState *css, *sclp, *flic;
@@ -134,24 +136,33 @@ static void ccw_init(MachineState *machine)
     s390_create_virtio_net(BUS(css_bus), "virtio-net-ccw");
 }
 
-static QEMUMachine ccw_machine = {
-    .name = "s390-ccw-virtio",
-    .alias = "s390-ccw",
-    .desc = "VirtIO-ccw based S390 machine",
-    .init = ccw_init,
-    .block_default_type = IF_VIRTIO,
-    .no_cdrom = 1,
-    .no_floppy = 1,
-    .no_serial = 1,
-    .no_parallel = 1,
-    .no_sdcard = 1,
-    .use_sclp = 1,
-    .max_cpus = 255,
+static void ccw_machine_class_init(ObjectClass *oc, void *data)
+{
+    MachineClass *mc = MACHINE_CLASS(oc);
+
+    mc->name = "s390-ccw-virtio";
+    mc->alias = "s390-ccw";
+    mc->desc = "VirtIO-ccw based S390 machine";
+    mc->init = ccw_init;
+    mc->block_default_type = IF_VIRTIO;
+    mc->no_cdrom = 1;
+    mc->no_floppy = 1;
+    mc->no_serial = 1;
+    mc->no_parallel = 1;
+    mc->no_sdcard = 1;
+    mc->use_sclp = 1,
+    mc->max_cpus = 255;
+}
+
+static const TypeInfo ccw_machine_info = {
+    .name          = TYPE_S390_CCW_MACHINE,
+    .parent        = TYPE_MACHINE,
+    .class_init    = ccw_machine_class_init,
 };
 
-static void ccw_machine_init(void)
+static void ccw_machine_register_types(void)
 {
-    qemu_register_machine(&ccw_machine);
+    type_register_static(&ccw_machine_info);
 }
 
-machine_init(ccw_machine_init)
+type_init(ccw_machine_register_types)
diff --git a/hw/s390x/s390-virtio.c b/hw/s390x/s390-virtio.c
index 93c7ace..f1e0dbc 100644
--- a/hw/s390x/s390-virtio.c
+++ b/hw/s390x/s390-virtio.c
@@ -51,6 +51,7 @@
 
 #define MAX_BLK_DEVS                    10
 #define ZIPL_FILENAME                   "s390-zipl.rom"
+#define TYPE_S390_MACHINE               "s390-machine"
 
 static VirtIOS390Bus *s390_bus;
 static S390CPU **ipi_states;
@@ -279,25 +280,34 @@ static void s390_init(MachineState *machine)
     s390_create_virtio_net((BusState *)s390_bus, "virtio-net-s390");
 }
 
-static QEMUMachine s390_machine = {
-    .name = "s390-virtio",
-    .alias = "s390",
-    .desc = "VirtIO based S390 machine",
-    .init = s390_init,
-    .block_default_type = IF_VIRTIO,
-    .no_cdrom = 1,
-    .no_floppy = 1,
-    .no_serial = 1,
-    .no_parallel = 1,
-    .no_sdcard = 1,
-    .use_virtcon = 1,
-    .max_cpus = 255,
-    .is_default = 1,
+static void s390_machine_class_init(ObjectClass *oc, void *data)
+{
+    MachineClass *mc = MACHINE_CLASS(oc);
+
+    mc->name = "s390-virtio";
+    mc->alias = "s390";
+    mc->desc = "VirtIO based S390 machine";
+    mc->init = s390_init;
+    mc->block_default_type = IF_VIRTIO;
+    mc->max_cpus = 255;
+    mc->no_serial = 1;
+    mc->no_parallel = 1;
+    mc->use_virtcon = 1;
+    mc->no_floppy = 1;
+    mc->no_cdrom = 1;
+    mc->no_sdcard = 1;
+    mc->is_default = 1;
+}
+
+static const TypeInfo s390_machine_info = {
+    .name          = TYPE_S390_MACHINE,
+    .parent        = TYPE_MACHINE,
+    .class_init    = s390_machine_class_init,
 };
 
-static void s390_machine_init(void)
+static void s390_machine_register_types(void)
 {
-    qemu_register_machine(&s390_machine);
+    type_register_static(&s390_machine_info);
 }
 
-machine_init(s390_machine_init);
+type_init(s390_machine_register_types)
commit 9cb805fd2674f474d058fee6d7aa9e83fcd3d336
Author: Alexey Kardashevskiy <aik at ozlabs.ru>
Date:   Wed Aug 20 22:16:33 2014 +1000

    cpus: Define callback for QEMU "nmi" command
    
    This introduces an NMI (Non Maskable Interrupt) interface with
    a single nmi_monitor_handler() method. A machine or a device can
    implement it. This searches for an QOM object with this interface
    and if it is implemented, calls it. The callback implements an action
    required to cause debug crash dump on in-kernel debugger invocation.
    The callback returns Error**.
    
    This adds a nmi_monitor_handle() helper which walks through
    all objects to find the interface. The interface method is called
    for all found instances.
    
    This adds support for it in qmp_inject_nmi(). Since no architecture
    supports it at the moment, there is no change in behaviour.
    
    This changes inject-nmi command description for HMP and QMP.
    
    Signed-off-by: Alexey Kardashevskiy <aik at ozlabs.ru>
    Reviewed-by: Alexander Graf <agraf at suse.de>
    Signed-off-by: Paolo Bonzini <pbonzini at redhat.com>

diff --git a/cpus.c b/cpus.c
index 2b5c0bd..37d90f4 100644
--- a/cpus.c
+++ b/cpus.c
@@ -40,6 +40,7 @@
 #include "qemu/bitmap.h"
 #include "qemu/seqlock.h"
 #include "qapi-event.h"
+#include "hw/nmi.h"
 
 #ifndef _WIN32
 #include "qemu/compatfd.h"
@@ -1551,7 +1552,7 @@ void qmp_inject_nmi(Error **errp)
         }
     }
 #else
-    error_set(errp, QERR_UNSUPPORTED);
+    nmi_monitor_handle(monitor_get_cpu_index(), errp);
 #endif
 }
 
diff --git a/hmp-commands.hx b/hmp-commands.hx
index d0943b1..f859f8d 100644
--- a/hmp-commands.hx
+++ b/hmp-commands.hx
@@ -832,19 +832,17 @@ The values that can be specified here depend on the machine type, but are
 the same that can be specified in the @code{-boot} command line option.
 ETEXI
 
-#if defined(TARGET_I386) || defined(TARGET_S390X)
     {
         .name       = "nmi",
         .args_type  = "",
         .params     = "",
-        .help       = "inject an NMI on all guest's CPUs",
+        .help       = "inject an NMI",
         .mhandler.cmd = hmp_inject_nmi,
     },
-#endif
 STEXI
 @item nmi @var{cpu}
 @findex nmi
-Inject an NMI (x86) or RESTART (s390x) on the given CPU.
+Inject an NMI on the default CPU (x86/s390) or all CPUs (ppc64).
 
 ETEXI
 
diff --git a/hw/core/Makefile.objs b/hw/core/Makefile.objs
index 5377d05..17845df 100644
--- a/hw/core/Makefile.objs
+++ b/hw/core/Makefile.objs
@@ -4,6 +4,7 @@ common-obj-y += fw-path-provider.o
 # irq.o needed for qdev GPIO handling:
 common-obj-y += irq.o
 common-obj-y += hotplug.o
+common-obj-y += nmi.o
 
 common-obj-$(CONFIG_EMPTY_SLOT) += empty_slot.o
 common-obj-$(CONFIG_XILINX_AXI) += stream.o
diff --git a/hw/core/nmi.c b/hw/core/nmi.c
new file mode 100644
index 0000000..3dff020
--- /dev/null
+++ b/hw/core/nmi.c
@@ -0,0 +1,84 @@
+/*
+ *  NMI monitor handler class and helpers.
+ *
+ *  Copyright IBM Corp., 2014
+ *
+ *  Author: Alexey Kardashevskiy <aik at ozlabs.ru>
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2 of the License,
+ *  or (at your option) any later version.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with this program; if not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include "hw/nmi.h"
+#include "qapi/qmp/qerror.h"
+
+struct do_nmi_s {
+    int cpu_index;
+    Error *errp;
+    bool handled;
+};
+
+static void nmi_children(Object *o, struct do_nmi_s *ns);
+
+static int do_nmi(Object *o, void *opaque)
+{
+    struct do_nmi_s *ns = opaque;
+    NMIState *n = (NMIState *) object_dynamic_cast(o, TYPE_NMI);
+
+    if (n) {
+        NMIClass *nc = NMI_GET_CLASS(n);
+
+        ns->handled = true;
+        nc->nmi_monitor_handler(n, ns->cpu_index, &ns->errp);
+        if (ns->errp) {
+            return -1;
+        }
+    }
+    nmi_children(o, ns);
+
+    return 0;
+}
+
+static void nmi_children(Object *o, struct do_nmi_s *ns)
+{
+    object_child_foreach(o, do_nmi, ns);
+}
+
+void nmi_monitor_handle(int cpu_index, Error **errp)
+{
+    struct do_nmi_s ns = {
+        .cpu_index = cpu_index,
+        .errp = NULL,
+        .handled = false
+    };
+
+    nmi_children(object_get_root(), &ns);
+    if (ns.handled) {
+        error_propagate(errp, ns.errp);
+    } else {
+        error_set(errp, QERR_UNSUPPORTED);
+    }
+}
+
+static const TypeInfo nmi_info = {
+    .name          = TYPE_NMI,
+    .parent        = TYPE_INTERFACE,
+    .class_size    = sizeof(NMIClass),
+};
+
+static void nmi_register_types(void)
+{
+    type_register_static(&nmi_info);
+}
+
+type_init(nmi_register_types)
diff --git a/include/hw/nmi.h b/include/hw/nmi.h
new file mode 100644
index 0000000..b541772
--- /dev/null
+++ b/include/hw/nmi.h
@@ -0,0 +1,49 @@
+/*
+ *  NMI monitor handler class and helpers definitions.
+ *
+ *  Copyright IBM Corp., 2014
+ *
+ *  Author: Alexey Kardashevskiy <aik at ozlabs.ru>
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2 of the License,
+ *  or (at your option) any later version.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with this program; if not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef NMI_H
+#define NMI_H 1
+
+#include "qemu-common.h"
+#include "qom/object.h"
+
+#define TYPE_NMI "nmi"
+
+#define NMI_CLASS(klass) \
+     OBJECT_CLASS_CHECK(NMIClass, (klass), TYPE_NMI)
+#define NMI_GET_CLASS(obj) \
+    OBJECT_GET_CLASS(NMIClass, (obj), TYPE_NMI)
+#define NMI(obj) \
+     INTERFACE_CHECK(NMI, (obj), TYPE_NMI)
+
+typedef struct NMIState {
+    Object parent_obj;
+} NMIState;
+
+typedef struct NMIClass {
+    InterfaceClass parent_class;
+
+    void (*nmi_monitor_handler)(NMIState *n, int cpu_index, Error **errp);
+} NMIClass;
+
+void nmi_monitor_handle(int cpu_index, Error **errp);
+
+#endif /* NMI_H */
diff --git a/qapi-schema.json b/qapi-schema.json
index 341f417..689b548 100644
--- a/qapi-schema.json
+++ b/qapi-schema.json
@@ -1186,13 +1186,13 @@
 ##
 # @inject-nmi:
 #
-# Injects an Non-Maskable Interrupt into all guest's VCPUs.
+# Injects a Non-Maskable Interrupt into the default CPU (x86/s390) or all CPUs (ppc64).
 #
 # Returns:  If successful, nothing
 #
 # Since:  0.14.0
 #
-# Notes: Only x86 Virtual Machines support this command.
+# Note: prior to 2.1, this command was only supported for x86 and s390 VMs
 ##
 { 'command': 'inject-nmi' }
 
diff --git a/qmp-commands.hx b/qmp-commands.hx
index 4be4765..7658d4b 100644
--- a/qmp-commands.hx
+++ b/qmp-commands.hx
@@ -477,7 +477,7 @@ SQMP
 inject-nmi
 ----------
 
-Inject an NMI on guest's CPUs.
+Inject an NMI on the default CPU (x86/s390) or all CPUs (ppc64).
 
 Arguments: None.
 
@@ -487,7 +487,6 @@ Example:
 <- { "return": {} }
 
 Note: inject-nmi fails when the guest doesn't support injecting.
-      Currently, only x86 (NMI) and s390x (RESTART) guests do.
 
 EQMP
 
commit c8e2085d8e7a64d753eb2a43e4aeae674a99d2ff
Author: David Hildenbrand <dahi at linux.vnet.ibm.com>
Date:   Wed Aug 20 14:55:25 2014 +0200

    kvm: run cpu state synchronization on target vcpu thread
    
    As already done for kvm_cpu_synchronize_state(), let's trigger
    kvm_arch_put_registers() via run_on_cpu() for kvm_cpu_synchronize_post_reset()
    and kvm_cpu_synchronize_post_init().
    
    This way, we make sure that the register synchronizing ioctls are
    called from the proper vcpu thread; this avoids calls to
    synchronize_rcu() in the kernel.
    
    Reviewed-by: Cornelia Huck <cornelia.huck at de.ibm.com>
    Signed-off-by: David Hildenbrand <dahi at linux.vnet.ibm.com>
    Signed-off-by: Paolo Bonzini <pbonzini at redhat.com>

diff --git a/kvm-all.c b/kvm-all.c
index 1402f4f..b240bf8 100644
--- a/kvm-all.c
+++ b/kvm-all.c
@@ -1669,18 +1669,32 @@ void kvm_cpu_synchronize_state(CPUState *cpu)
     }
 }
 
-void kvm_cpu_synchronize_post_reset(CPUState *cpu)
+static void do_kvm_cpu_synchronize_post_reset(void *arg)
 {
+    CPUState *cpu = arg;
+
     kvm_arch_put_registers(cpu, KVM_PUT_RESET_STATE);
     cpu->kvm_vcpu_dirty = false;
 }
 
-void kvm_cpu_synchronize_post_init(CPUState *cpu)
+void kvm_cpu_synchronize_post_reset(CPUState *cpu)
+{
+    run_on_cpu(cpu, do_kvm_cpu_synchronize_post_reset, cpu);
+}
+
+static void do_kvm_cpu_synchronize_post_init(void *arg)
 {
+    CPUState *cpu = arg;
+
     kvm_arch_put_registers(cpu, KVM_PUT_FULL_STATE);
     cpu->kvm_vcpu_dirty = false;
 }
 
+void kvm_cpu_synchronize_post_init(CPUState *cpu)
+{
+    run_on_cpu(cpu, do_kvm_cpu_synchronize_post_init, cpu);
+}
+
 int kvm_cpu_exec(CPUState *cpu)
 {
     struct kvm_run *run = cpu->kvm_run;


More information about the Spice-commits mailing list