[Spice-commits] 72 commits - block/sheepdog.c configure hw/arm_gic.c hw/arm_gic_common.c hw/arm_gic_internal.h hw/armv7m_nvic.c hw/cadence_ttc.c hw/ds1338.c hw/e1000.c hw/pc_piix.c hw/qxl-render.c hw/qxl.c hw/qxl.h hw/rtl8139.c hw/sun4m.c hw/sun4u.c hw/usb hw/versatilepb.c hw/vfio_pci.c hw/vfio_pci_int.h hw/virtio-net.c hw/zynq_slcr.c linux-user/main.c net.c net/clients.h net/dump.c net/dump.h net/hub.c net/hub.h net/slirp.c net/slirp.h net/socket.c net/socket.h net/tap-win32.c net/tap.c net/tap.h net/vde.c net/vde.h qemu-ga.c sparc-dis.c target-i386/translate.c target-sparc/int32_helper.c target-sparc/int64_helper.c target-sparc/translate.c tcg/sparc ui/spice-core.c ui/spice-display.c ui/spice-display.h ui/vnc.c

Gerd Hoffmann kraxel at kemper.freedesktop.org
Mon Oct 15 01:27:41 PDT 2012


 block/sheepdog.c            |   70 ++--
 configure                   |   29 -
 hw/arm_gic.c                |   46 +--
 hw/arm_gic_common.c         |   16 -
 hw/arm_gic_internal.h       |   20 -
 hw/armv7m_nvic.c            |    6 
 hw/cadence_ttc.c            |    2 
 hw/ds1338.c                 |  123 +++++---
 hw/e1000.c                  |   12 
 hw/pc_piix.c                |    8 
 hw/qxl-render.c             |    4 
 hw/qxl.c                    |   57 ---
 hw/qxl.h                    |    5 
 hw/rtl8139.c                |   24 +
 hw/sun4m.c                  |   11 
 hw/sun4u.c                  |   36 +-
 hw/usb/hcd-uhci.c           |   10 
 hw/usb/redirect.c           |   24 -
 hw/versatilepb.c            |    5 
 hw/vfio_pci.c               |  498 ++++++++++++++++++++--------------
 hw/vfio_pci_int.h           |  114 -------
 hw/virtio-net.c             |    5 
 hw/zynq_slcr.c              |    2 
 linux-user/main.c           |    5 
 net.c                       |   11 
 net/clients.h               |   55 +++
 net/dump.c                  |    2 
 net/dump.h                  |   33 --
 net/hub.c                   |    1 
 net/hub.h                   |    2 
 net/slirp.c                 |    3 
 net/slirp.h                 |    3 
 net/socket.c                |    3 
 net/socket.h                |   33 --
 net/tap-win32.c             |    2 
 net/tap.c                   |    3 
 net/tap.h                   |    6 
 net/vde.c                   |    3 
 net/vde.h                   |   37 --
 qemu-ga.c                   |    6 
 sparc-dis.c                 |    2 
 target-i386/translate.c     |    2 
 target-sparc/int32_helper.c |    5 
 target-sparc/int64_helper.c |    5 
 target-sparc/translate.c    |  119 ++++----
 tcg/sparc/tcg-target.c      |  643 +++++++++++++++++++++++++-------------------
 tcg/sparc/tcg-target.h      |    9 
 ui/spice-core.c             |   51 ---
 ui/spice-display.c          |   38 --
 ui/spice-display.h          |    5 
 ui/vnc.c                    |    4 
 51 files changed, 1131 insertions(+), 1087 deletions(-)

New commits:
commit 8b4a3df8081f3e6f1061ed5cbb303ad623ade66b
Author: malc <av1474 at comtv.ru>
Date:   Sun Oct 14 14:54:38 2012 +0400

    Fix popcnt in long mode
    
    Thanks to Andriy Gapon for initial problem report.
    
    Signed-off-by: malc <av1474 at comtv.ru>

diff --git a/target-i386/translate.c b/target-i386/translate.c
index 0a7e4e3..ee75850 100644
--- a/target-i386/translate.c
+++ b/target-i386/translate.c
@@ -7768,7 +7768,7 @@ static target_ulong disas_insn(DisasContext *s, target_ulong pc_start)
             goto illegal_op;
 
         modrm = cpu_ldub_code(cpu_single_env, s->pc++);
-        reg = ((modrm >> 3) & 7);
+        reg = ((modrm >> 3) & 7) | rex_r;
 
         if (s->prefix & PREFIX_DATA)
             ot = OT_WORD;
commit b64ba4b232e776d891a7a5137a6129221b6a9cd0
Author: Andreas Färber <afaerber at suse.de>
Date:   Fri Oct 12 04:23:08 2012 +0200

    sun4u: Pass SPARCCPU to cpu_set_ivec_irq()
    
    Needed for moving halted field to CPUState.
    
    Signed-off-by: Andreas Färber <afaerber at suse.de>
    Signed-off-by: Blue Swirl <blauwirbel at gmail.com>

diff --git a/hw/sun4u.c b/hw/sun4u.c
index 0453522..940db33 100644
--- a/hw/sun4u.c
+++ b/hw/sun4u.c
@@ -321,7 +321,8 @@ static void cpu_kick_irq(SPARCCPU *cpu)
 
 static void cpu_set_ivec_irq(void *opaque, int irq, int level)
 {
-    CPUSPARCState *env = opaque;
+    SPARCCPU *cpu = opaque;
+    CPUSPARCState *env = &cpu->env;
 
     if (level) {
         if (!(env->ivec_status & 0x20)) {
@@ -802,7 +803,6 @@ static void sun4uv_init(MemoryRegion *address_space_mem,
                         const struct hwdef *hwdef)
 {
     SPARCCPU *cpu;
-    CPUSPARCState *env;
     M48t59State *nvram;
     unsigned int i;
     uint64_t initrd_addr, initrd_size, kernel_addr, kernel_size, kernel_entry;
@@ -815,14 +815,13 @@ static void sun4uv_init(MemoryRegion *address_space_mem,
 
     /* init CPUs */
     cpu = cpu_devinit(cpu_model, hwdef);
-    env = &cpu->env;
 
     /* set up devices */
     ram_init(0, RAM_size);
 
     prom_init(hwdef->prom_addr, bios_name);
 
-    ivec_irqs = qemu_allocate_irqs(cpu_set_ivec_irq, env, IVEC_MAX);
+    ivec_irqs = qemu_allocate_irqs(cpu_set_ivec_irq, cpu, IVEC_MAX);
     pci_bus = pci_apb_init(APB_SPECIAL_BASE, APB_MEM_BASE, ivec_irqs, &pci_bus2,
                            &pci_bus3, &pbm_irqs);
     pci_vga_init(pci_bus);
commit ce18c558f08ea392b2ec79046eb40e791be5fc88
Author: Andreas Färber <afaerber at suse.de>
Date:   Fri Oct 12 04:23:07 2012 +0200

    sun4u: Pass SPARCCPU to cpu_kick_irq()
    
    Needed for changing qemu_cpu_kick() argument type to CPUState.
    
    Signed-off-by: Andreas Färber <afaerber at suse.de>
    Signed-off-by: Blue Swirl <blauwirbel at gmail.com>

diff --git a/hw/sun4u.c b/hw/sun4u.c
index 4cea102..0453522 100644
--- a/hw/sun4u.c
+++ b/hw/sun4u.c
@@ -310,8 +310,10 @@ void cpu_check_irqs(CPUSPARCState *env)
     }
 }
 
-static void cpu_kick_irq(CPUSPARCState *env)
+static void cpu_kick_irq(SPARCCPU *cpu)
 {
+    CPUSPARCState *env = &cpu->env;
+
     env->halted = 0;
     cpu_check_irqs(env);
     qemu_cpu_kick(env);
@@ -431,7 +433,7 @@ static void tick_irq(void *opaque)
     }
 
     env->softint |= SOFTINT_TIMER;
-    cpu_kick_irq(env);
+    cpu_kick_irq(cpu);
 }
 
 static void stick_irq(void *opaque)
@@ -449,7 +451,7 @@ static void stick_irq(void *opaque)
     }
 
     env->softint |= SOFTINT_STIMER;
-    cpu_kick_irq(env);
+    cpu_kick_irq(cpu);
 }
 
 static void hstick_irq(void *opaque)
@@ -467,7 +469,7 @@ static void hstick_irq(void *opaque)
     }
 
     env->softint |= SOFTINT_STIMER;
-    cpu_kick_irq(env);
+    cpu_kick_irq(cpu);
 }
 
 static int64_t cpu_to_timer_ticks(int64_t cpu_ticks, uint32_t frequency)
commit 6b678e1f9b92e21ee2e2614440740ca76fc7d2d8
Author: Andreas Färber <afaerber at suse.de>
Date:   Fri Oct 12 04:23:06 2012 +0200

    sun4u: Pass SPARCCPU to {,s,hs}tick_irq() and cpu_timer_create()
    
    Needed for changing cpu_kick_irq() argument type to SPARCCPU.
    
    Signed-off-by: Andreas Färber <afaerber at suse.de>
    Signed-off-by: Blue Swirl <blauwirbel at gmail.com>

diff --git a/hw/sun4u.c b/hw/sun4u.c
index 137a7c6..4cea102 100644
--- a/hw/sun4u.c
+++ b/hw/sun4u.c
@@ -366,7 +366,7 @@ void cpu_get_timer(QEMUFile *f, CPUTimer *s)
     qemu_get_timer(f, s->qtimer);
 }
 
-static CPUTimer* cpu_timer_create(const char* name, CPUSPARCState *env,
+static CPUTimer *cpu_timer_create(const char *name, SPARCCPU *cpu,
                                   QEMUBHFunc *cb, uint32_t frequency,
                                   uint64_t disabled_mask)
 {
@@ -379,7 +379,7 @@ static CPUTimer* cpu_timer_create(const char* name, CPUSPARCState *env,
     timer->disabled = 1;
     timer->clock_offset = qemu_get_clock_ns(vm_clock);
 
-    timer->qtimer = qemu_new_timer_ns(vm_clock, cb, env);
+    timer->qtimer = qemu_new_timer_ns(vm_clock, cb, cpu);
 
     return timer;
 }
@@ -418,7 +418,8 @@ static void main_cpu_reset(void *opaque)
 
 static void tick_irq(void *opaque)
 {
-    CPUSPARCState *env = opaque;
+    SPARCCPU *cpu = opaque;
+    CPUSPARCState *env = &cpu->env;
 
     CPUTimer* timer = env->tick;
 
@@ -435,7 +436,8 @@ static void tick_irq(void *opaque)
 
 static void stick_irq(void *opaque)
 {
-    CPUSPARCState *env = opaque;
+    SPARCCPU *cpu = opaque;
+    CPUSPARCState *env = &cpu->env;
 
     CPUTimer* timer = env->stick;
 
@@ -452,7 +454,8 @@ static void stick_irq(void *opaque)
 
 static void hstick_irq(void *opaque)
 {
-    CPUSPARCState *env = opaque;
+    SPARCCPU *cpu = opaque;
+    CPUSPARCState *env = &cpu->env;
 
     CPUTimer* timer = env->hstick;
 
@@ -772,13 +775,13 @@ static SPARCCPU *cpu_devinit(const char *cpu_model, const struct hwdef *hwdef)
     }
     env = &cpu->env;
 
-    env->tick = cpu_timer_create("tick", env, tick_irq,
+    env->tick = cpu_timer_create("tick", cpu, tick_irq,
                                   tick_frequency, TICK_NPT_MASK);
 
-    env->stick = cpu_timer_create("stick", env, stick_irq,
+    env->stick = cpu_timer_create("stick", cpu, stick_irq,
                                    stick_frequency, TICK_INT_DIS);
 
-    env->hstick = cpu_timer_create("hstick", env, hstick_irq,
+    env->hstick = cpu_timer_create("hstick", cpu, hstick_irq,
                                     hstick_frequency, TICK_INT_DIS);
 
     reset_info = g_malloc0(sizeof(ResetData));
commit 38c66cf2817366fd56af7cd2099a696d715365ce
Author: Andreas Färber <afaerber at suse.de>
Date:   Fri Oct 12 04:23:05 2012 +0200

    sun4m: Pass SPARCCPU to cpu_kick_irq()
    
    Needed for changing qemu_cpu_kick() argument type to CPUState.
    
    Signed-off-by: Andreas Färber <afaerber at suse.de>
    Signed-off-by: Blue Swirl <blauwirbel at gmail.com>

diff --git a/hw/sun4m.c b/hw/sun4m.c
index c1ee8bd..a04b485 100644
--- a/hw/sun4m.c
+++ b/hw/sun4m.c
@@ -253,8 +253,10 @@ void cpu_check_irqs(CPUSPARCState *env)
     }
 }
 
-static void cpu_kick_irq(CPUSPARCState *env)
+static void cpu_kick_irq(SPARCCPU *cpu)
 {
+    CPUSPARCState *env = &cpu->env;
+
     env->halted = 0;
     cpu_check_irqs(env);
     qemu_cpu_kick(env);
@@ -268,7 +270,7 @@ static void cpu_set_irq(void *opaque, int irq, int level)
     if (level) {
         trace_sun4m_cpu_set_irq_raise(irq);
         env->pil_in |= 1 << irq;
-        cpu_kick_irq(env);
+        cpu_kick_irq(cpu);
     } else {
         trace_sun4m_cpu_set_irq_lower(irq);
         env->pil_in &= ~(1 << irq);
commit e0bbf9b573e1a19a906abef861ee28293e44b3a2
Author: Andreas Färber <afaerber at suse.de>
Date:   Fri Oct 12 04:23:04 2012 +0200

    sun4m: Pass SPARCCPU to cpu_set_irq()
    
    Needed for changing cpu_kick_irq() argument type to SPARCCPU.
    
    Signed-off-by: Andreas Färber <afaerber at suse.de>
    Signed-off-by: Blue Swirl <blauwirbel at gmail.com>

diff --git a/hw/sun4m.c b/hw/sun4m.c
index c98cd5e..c1ee8bd 100644
--- a/hw/sun4m.c
+++ b/hw/sun4m.c
@@ -262,7 +262,8 @@ static void cpu_kick_irq(CPUSPARCState *env)
 
 static void cpu_set_irq(void *opaque, int irq, int level)
 {
-    CPUSPARCState *env = opaque;
+    SPARCCPU *cpu = opaque;
+    CPUSPARCState *env = &cpu->env;
 
     if (level) {
         trace_sun4m_cpu_set_irq_raise(irq);
@@ -840,7 +841,7 @@ static void cpu_devinit(const char *cpu_model, unsigned int id,
         qemu_register_reset(secondary_cpu_reset, cpu);
         env->halted = 1;
     }
-    *cpu_irqs = qemu_allocate_irqs(cpu_set_irq, env, MAX_PILS);
+    *cpu_irqs = qemu_allocate_irqs(cpu_set_irq, cpu, MAX_PILS);
     env->prom_addr = prom_addr;
 }
 
commit 203342d8dc852bc09488e9dc5b853aa48aeed14c
Author: Richard Henderson <rth at twiddle.net>
Date:   Wed Oct 10 09:02:47 2012 -0700

    tcg-sparc: Emit MOVR insns for setcond_i64 and movcond_64
    
    Signed-off-by: Richard Henderson <rth at twiddle.net>
    Signed-off-by: Blue Swirl <blauwirbel at gmail.com>

diff --git a/tcg/sparc/tcg-target.c b/tcg/sparc/tcg-target.c
index 3b18fce..f146647 100644
--- a/tcg/sparc/tcg-target.c
+++ b/tcg/sparc/tcg-target.c
@@ -124,6 +124,7 @@ static const int tcg_target_call_oarg_regs[] = {
 #define INSN_RS2(x) (x)
 #define INSN_ASI(x) ((x) << 5)
 
+#define INSN_IMM10(x) ((1 << 13) | ((x) & 0x3ff))
 #define INSN_IMM11(x) ((1 << 13) | ((x) & 0x7ff))
 #define INSN_IMM13(x) ((1 << 13) | ((x) & 0x1fff))
 #define INSN_OFF16(x) ((((x) >> 2) & 0x3fff) | ((((x) >> 16) & 3) << 20))
@@ -185,6 +186,7 @@ static const int tcg_target_call_oarg_regs[] = {
 #define ARITH_UDIVX (INSN_OP(2) | INSN_OP3(0x0d))
 #define ARITH_SDIVX (INSN_OP(2) | INSN_OP3(0x2d))
 #define ARITH_MOVCC (INSN_OP(2) | INSN_OP3(0x2c))
+#define ARITH_MOVR (INSN_OP(2) | INSN_OP3(0x2f))
 
 #define SHIFT_SLL  (INSN_OP(2) | INSN_OP3(0x25))
 #define SHIFT_SRL  (INSN_OP(2) | INSN_OP3(0x26))
@@ -605,12 +607,28 @@ static void tcg_out_brcond_i64(TCGContext *s, TCGCond cond, TCGArg arg1,
     tcg_out_nop(s);
 }
 
+static void tcg_out_movr(TCGContext *s, TCGCond cond, TCGArg ret, TCGArg c1,
+                         TCGArg v1, int v1const)
+{
+    tcg_out32(s, ARITH_MOVR | INSN_RD(ret) | INSN_RS1(c1)
+              | (tcg_cond_to_rcond[cond] << 10)
+              | (v1const ? INSN_IMM10(v1) : INSN_RS2(v1)));
+}
+
 static void tcg_out_movcond_i64(TCGContext *s, TCGCond cond, TCGArg ret,
                                 TCGArg c1, TCGArg c2, int c2const,
                                 TCGArg v1, int v1const)
 {
-    tcg_out_cmp(s, c1, c2, c2const);
-    tcg_out_movcc(s, cond, MOVCC_XCC, ret, v1, v1const);
+    /* For 64-bit signed comparisons vs zero, we can avoid the compare.
+       Note that the immediate range is one bit smaller, so we must check
+       for that as well.  */
+    if (c2 == 0 && !is_unsigned_cond(cond)
+        && (!v1const || check_fit_tl(v1, 10))) {
+        tcg_out_movr(s, cond, ret, c1, v1, v1const);
+    } else {
+        tcg_out_cmp(s, c1, c2, c2const);
+        tcg_out_movcc(s, cond, MOVCC_XCC, ret, v1, v1const);
+    }
 }
 #else
 static void tcg_out_brcond2_i32(TCGContext *s, TCGCond cond,
@@ -706,9 +724,16 @@ static void tcg_out_setcond_i32(TCGContext *s, TCGCond cond, TCGArg ret,
 static void tcg_out_setcond_i64(TCGContext *s, TCGCond cond, TCGArg ret,
                                 TCGArg c1, TCGArg c2, int c2const)
 {
-    tcg_out_cmp(s, c1, c2, c2const);
-    tcg_out_movi_imm13(s, ret, 0);
-    tcg_out_movcc(s, cond, MOVCC_XCC, ret, 1, 1);
+    /* For 64-bit signed comparisons vs zero, we can avoid the compare
+       if the input does not overlap the output.  */
+    if (c2 == 0 && !is_unsigned_cond(cond) && c1 != ret) {
+        tcg_out_movi_imm13(s, ret, 0);
+        tcg_out_movr(s, cond, ret, c1, 1, 1);
+    } else {
+        tcg_out_cmp(s, c1, c2, c2const);
+        tcg_out_movi_imm13(s, ret, 0);
+        tcg_out_movcc(s, cond, MOVCC_XCC, ret, 1, 1);
+    }
 }
 #else
 static void tcg_out_setcond2_i32(TCGContext *s, TCGCond cond, TCGArg ret,
commit ab1339b9b40752d076ae9784ed07f14194f130bd
Author: Richard Henderson <rth at twiddle.net>
Date:   Wed Oct 10 09:02:46 2012 -0700

    tcg-sparc: Emit BPr insns for brcond_i64
    
    Signed-off-by: Richard Henderson <rth at twiddle.net>
    Signed-off-by: Blue Swirl <blauwirbel at gmail.com>

diff --git a/tcg/sparc/tcg-target.c b/tcg/sparc/tcg-target.c
index ab47c98..3b18fce 100644
--- a/tcg/sparc/tcg-target.c
+++ b/tcg/sparc/tcg-target.c
@@ -126,6 +126,7 @@ static const int tcg_target_call_oarg_regs[] = {
 
 #define INSN_IMM11(x) ((1 << 13) | ((x) & 0x7ff))
 #define INSN_IMM13(x) ((1 << 13) | ((x) & 0x1fff))
+#define INSN_OFF16(x) ((((x) >> 2) & 0x3fff) | ((((x) >> 16) & 3) << 20))
 #define INSN_OFF19(x) (((x) >> 2) & 0x07ffff)
 #define INSN_COND(x) ((x) << 25)
 
@@ -147,6 +148,13 @@ static const int tcg_target_call_oarg_regs[] = {
 #define COND_VC    0xf
 #define BA         (INSN_OP(0) | INSN_COND(COND_A) | INSN_OP2(0x2))
 
+#define RCOND_Z    1
+#define RCOND_LEZ  2
+#define RCOND_LZ   3
+#define RCOND_NZ   5
+#define RCOND_GZ   6
+#define RCOND_GEZ  7
+
 #define MOVCC_ICC  (1 << 18)
 #define MOVCC_XCC  (1 << 18 | 1 << 12)
 
@@ -156,6 +164,8 @@ static const int tcg_target_call_oarg_regs[] = {
 #define BPCC_PN    0
 #define BPCC_A     (1 << 29)
 
+#define BPR_PT     BPCC_PT
+
 #define ARITH_ADD  (INSN_OP(2) | INSN_OP3(0x00))
 #define ARITH_ADDCC (INSN_OP(2) | INSN_OP3(0x10))
 #define ARITH_AND  (INSN_OP(2) | INSN_OP3(0x01))
@@ -251,6 +261,16 @@ static void patch_reloc(uint8_t *code_ptr, int type,
         }
         *(uint32_t *)code_ptr = value;
         break;
+    case R_SPARC_WDISP16:
+        value -= (long)code_ptr;
+        if (!check_fit_tl(value >> 2, 16)) {
+            tcg_abort();
+        }
+        insn = *(uint32_t *)code_ptr;
+        insn &= ~INSN_OFF16(-1);
+        insn |= INSN_OFF16(value);
+        *(uint32_t *)code_ptr = insn;
+        break;
     case R_SPARC_WDISP19:
         value -= (long)code_ptr;
         if (!check_fit_tl(value >> 2, 19)) {
@@ -502,6 +522,15 @@ static const uint8_t tcg_cond_to_bcond[] = {
     [TCG_COND_GTU] = COND_GU,
 };
 
+static const uint8_t tcg_cond_to_rcond[] = {
+    [TCG_COND_EQ] = RCOND_Z,
+    [TCG_COND_NE] = RCOND_NZ,
+    [TCG_COND_LT] = RCOND_LZ,
+    [TCG_COND_GT] = RCOND_GZ,
+    [TCG_COND_LE] = RCOND_LEZ,
+    [TCG_COND_GE] = RCOND_GEZ
+};
+
 static void tcg_out_bpcc0(TCGContext *s, int scond, int flags, int off19)
 {
     tcg_out32(s, INSN_OP(0) | INSN_OP2(1) | INSN_COND(scond) | flags | off19);
@@ -555,8 +584,24 @@ static void tcg_out_movcond_i32(TCGContext *s, TCGCond cond, TCGArg ret,
 static void tcg_out_brcond_i64(TCGContext *s, TCGCond cond, TCGArg arg1,
                                TCGArg arg2, int const_arg2, int label)
 {
-    tcg_out_cmp(s, arg1, arg2, const_arg2);
-    tcg_out_bpcc(s, tcg_cond_to_bcond[cond], BPCC_XCC | BPCC_PT, label);
+    /* For 64-bit signed comparisons vs zero, we can avoid the compare.  */
+    if (arg2 == 0 && !is_unsigned_cond(cond)) {
+        TCGLabel *l = &s->labels[label];
+        int off16;
+
+        if (l->has_value) {
+            off16 = INSN_OFF16(l->u.value - (unsigned long)s->code_ptr);
+        } else {
+            /* Make sure to preserve destinations during retranslation.  */
+            off16 = *(uint32_t *)s->code_ptr & INSN_OFF16(-1);
+            tcg_out_reloc(s, s->code_ptr, R_SPARC_WDISP16, label, 0);
+        }
+        tcg_out32(s, INSN_OP(0) | INSN_OP2(3) | BPR_PT | INSN_RS1(arg1)
+                  | INSN_COND(tcg_cond_to_rcond[cond]) | off16);
+    } else {
+        tcg_out_cmp(s, arg1, arg2, const_arg2);
+        tcg_out_bpcc(s, tcg_cond_to_bcond[cond], BPCC_XCC | BPCC_PT, label);
+    }
     tcg_out_nop(s);
 }
 
commit 345ce423dd58b3ddc3cfbcbb1ca2eee25546e8be
Author: Richard Henderson <rth at twiddle.net>
Date:   Wed Oct 10 09:02:45 2012 -0700

    tcg-sparc: Dump illegal opode contents
    
    Signed-off-by: Richard Henderson <rth at twiddle.net>
    Signed-off-by: Blue Swirl <blauwirbel at gmail.com>

diff --git a/sparc-dis.c b/sparc-dis.c
index cdd337a..1d017fa 100644
--- a/sparc-dis.c
+++ b/sparc-dis.c
@@ -3270,6 +3270,6 @@ print_insn_sparc (bfd_vma memaddr, disassemble_info *info)
     }
 
   info->insn_type = dis_noninsn;        /* Mark as non-valid instruction.  */
-  (*info->fprintf_func) (stream, _("unknown"));
+  (*info->fprintf_func) (stream, ".long %#08lx", insn);
   return sizeof (buffer);
 }
commit a115f3ea47cbd3ae64c754779321264857ab5bde
Author: Richard Henderson <rth at twiddle.net>
Date:   Wed Oct 10 09:02:44 2012 -0700

    tcg-sparc: Drop use of Bicc in favor of BPcc
    
    Now that we're always sparcv9, we can not bother using Bicc for
    32-bit branches and BPcc for 64-bit branches and instead always
    use BPcc.
    
    New interfaces allow less direct use of tcg_out32 and raw numbers
    inside the qemu_ld/st routines.
    
    Signed-off-by: Richard Henderson <rth at twiddle.net>
    Signed-off-by: Blue Swirl <blauwirbel at gmail.com>

diff --git a/tcg/sparc/tcg-target.c b/tcg/sparc/tcg-target.c
index 9c87cb6..ab47c98 100644
--- a/tcg/sparc/tcg-target.c
+++ b/tcg/sparc/tcg-target.c
@@ -115,101 +115,6 @@ static const int tcg_target_call_oarg_regs[] = {
     TCG_REG_O3,
 };
 
-static inline int check_fit_tl(tcg_target_long val, unsigned int bits)
-{
-    return (val << ((sizeof(tcg_target_long) * 8 - bits))
-            >> (sizeof(tcg_target_long) * 8 - bits)) == val;
-}
-
-static inline int check_fit_i32(uint32_t val, unsigned int bits)
-{
-    return ((val << (32 - bits)) >> (32 - bits)) == val;
-}
-
-static void patch_reloc(uint8_t *code_ptr, int type,
-                        tcg_target_long value, tcg_target_long addend)
-{
-    value += addend;
-    switch (type) {
-    case R_SPARC_32:
-        if (value != (uint32_t)value)
-            tcg_abort();
-        *(uint32_t *)code_ptr = value;
-        break;
-    case R_SPARC_WDISP22:
-        value -= (long)code_ptr;
-        value >>= 2;
-        if (!check_fit_tl(value, 22))
-            tcg_abort();
-        *(uint32_t *)code_ptr = ((*(uint32_t *)code_ptr) & ~0x3fffff) | value;
-        break;
-    case R_SPARC_WDISP19:
-        value -= (long)code_ptr;
-        value >>= 2;
-        if (!check_fit_tl(value, 19))
-            tcg_abort();
-        *(uint32_t *)code_ptr = ((*(uint32_t *)code_ptr) & ~0x7ffff) | value;
-        break;
-    default:
-        tcg_abort();
-    }
-}
-
-/* parse target specific constraints */
-static int target_parse_constraint(TCGArgConstraint *ct, const char **pct_str)
-{
-    const char *ct_str;
-
-    ct_str = *pct_str;
-    switch (ct_str[0]) {
-    case 'r':
-        ct->ct |= TCG_CT_REG;
-        tcg_regset_set32(ct->u.regs, 0, 0xffffffff);
-        break;
-    case 'L': /* qemu_ld/st constraint */
-        ct->ct |= TCG_CT_REG;
-        tcg_regset_set32(ct->u.regs, 0, 0xffffffff);
-        // Helper args
-        tcg_regset_reset_reg(ct->u.regs, TCG_REG_O0);
-        tcg_regset_reset_reg(ct->u.regs, TCG_REG_O1);
-        tcg_regset_reset_reg(ct->u.regs, TCG_REG_O2);
-        break;
-    case 'I':
-        ct->ct |= TCG_CT_CONST_S11;
-        break;
-    case 'J':
-        ct->ct |= TCG_CT_CONST_S13;
-        break;
-    case 'Z':
-        ct->ct |= TCG_CT_CONST_ZERO;
-        break;
-    default:
-        return -1;
-    }
-    ct_str++;
-    *pct_str = ct_str;
-    return 0;
-}
-
-/* test if a constant matches the constraint */
-static inline int tcg_target_const_match(tcg_target_long val,
-                                         const TCGArgConstraint *arg_ct)
-{
-    int ct = arg_ct->ct;
-
-    if (ct & TCG_CT_CONST) {
-        return 1;
-    } else if ((ct & TCG_CT_CONST_ZERO) && val == 0) {
-        return 1;
-    } else if ((ct & TCG_CT_CONST_S11) && check_fit_tl(val, 11)) {
-        return 1;
-    } else if ((ct & TCG_CT_CONST_S13) && check_fit_tl(val, 13)) {
-        return 1;
-    } else {
-        return 0;
-    }
-}
-
 #define INSN_OP(x)  ((x) << 30)
 #define INSN_OP2(x) ((x) << 22)
 #define INSN_OP3(x) ((x) << 19)
@@ -222,9 +127,8 @@ static inline int tcg_target_const_match(tcg_target_long val,
 #define INSN_IMM11(x) ((1 << 13) | ((x) & 0x7ff))
 #define INSN_IMM13(x) ((1 << 13) | ((x) & 0x1fff))
 #define INSN_OFF19(x) (((x) >> 2) & 0x07ffff)
-#define INSN_OFF22(x) (((x) >> 2) & 0x3fffff)
+#define INSN_COND(x) ((x) << 25)
 
-#define INSN_COND(x, a) (((x) << 25) | ((a) << 29))
 #define COND_N     0x0
 #define COND_E     0x1
 #define COND_LE    0x2
@@ -241,11 +145,17 @@ static inline int tcg_target_const_match(tcg_target_long val,
 #define COND_CC    0xd
 #define COND_POS   0xe
 #define COND_VC    0xf
-#define BA         (INSN_OP(0) | INSN_COND(COND_A, 0) | INSN_OP2(0x2))
+#define BA         (INSN_OP(0) | INSN_COND(COND_A) | INSN_OP2(0x2))
 
 #define MOVCC_ICC  (1 << 18)
 #define MOVCC_XCC  (1 << 18 | 1 << 12)
 
+#define BPCC_ICC   0
+#define BPCC_XCC   (2 << 20)
+#define BPCC_PT    (1 << 19)
+#define BPCC_PN    0
+#define BPCC_A     (1 << 29)
+
 #define ARITH_ADD  (INSN_OP(2) | INSN_OP3(0x00))
 #define ARITH_ADDCC (INSN_OP(2) | INSN_OP3(0x10))
 #define ARITH_AND  (INSN_OP(2) | INSN_OP3(0x01))
@@ -318,6 +228,99 @@ static inline int tcg_target_const_match(tcg_target_long val,
 #define STW_LE     (STWA  | INSN_ASI(ASI_PRIMARY_LITTLE))
 #define STX_LE     (STXA  | INSN_ASI(ASI_PRIMARY_LITTLE))
 
+static inline int check_fit_tl(tcg_target_long val, unsigned int bits)
+{
+    return (val << ((sizeof(tcg_target_long) * 8 - bits))
+            >> (sizeof(tcg_target_long) * 8 - bits)) == val;
+}
+
+static inline int check_fit_i32(uint32_t val, unsigned int bits)
+{
+    return ((val << (32 - bits)) >> (32 - bits)) == val;
+}
+
+static void patch_reloc(uint8_t *code_ptr, int type,
+                        tcg_target_long value, tcg_target_long addend)
+{
+    uint32_t insn;
+    value += addend;
+    switch (type) {
+    case R_SPARC_32:
+        if (value != (uint32_t)value) {
+            tcg_abort();
+        }
+        *(uint32_t *)code_ptr = value;
+        break;
+    case R_SPARC_WDISP19:
+        value -= (long)code_ptr;
+        if (!check_fit_tl(value >> 2, 19)) {
+            tcg_abort();
+        }
+        insn = *(uint32_t *)code_ptr;
+        insn &= ~INSN_OFF19(-1);
+        insn |= INSN_OFF19(value);
+        *(uint32_t *)code_ptr = insn;
+        break;
+    default:
+        tcg_abort();
+    }
+}
+
+/* parse target specific constraints */
+static int target_parse_constraint(TCGArgConstraint *ct, const char **pct_str)
+{
+    const char *ct_str;
+
+    ct_str = *pct_str;
+    switch (ct_str[0]) {
+    case 'r':
+        ct->ct |= TCG_CT_REG;
+        tcg_regset_set32(ct->u.regs, 0, 0xffffffff);
+        break;
+    case 'L': /* qemu_ld/st constraint */
+        ct->ct |= TCG_CT_REG;
+        tcg_regset_set32(ct->u.regs, 0, 0xffffffff);
+        // Helper args
+        tcg_regset_reset_reg(ct->u.regs, TCG_REG_O0);
+        tcg_regset_reset_reg(ct->u.regs, TCG_REG_O1);
+        tcg_regset_reset_reg(ct->u.regs, TCG_REG_O2);
+        break;
+    case 'I':
+        ct->ct |= TCG_CT_CONST_S11;
+        break;
+    case 'J':
+        ct->ct |= TCG_CT_CONST_S13;
+        break;
+    case 'Z':
+        ct->ct |= TCG_CT_CONST_ZERO;
+        break;
+    default:
+        return -1;
+    }
+    ct_str++;
+    *pct_str = ct_str;
+    return 0;
+}
+
+/* test if a constant matches the constraint */
+static inline int tcg_target_const_match(tcg_target_long val,
+                                         const TCGArgConstraint *arg_ct)
+{
+    int ct = arg_ct->ct;
+
+    if (ct & TCG_CT_CONST) {
+        return 1;
+    } else if ((ct & TCG_CT_CONST_ZERO) && val == 0) {
+        return 1;
+    } else if ((ct & TCG_CT_CONST_S11) && check_fit_tl(val, 11)) {
+        return 1;
+    } else if ((ct & TCG_CT_CONST_S13) && check_fit_tl(val, 13)) {
+        return 1;
+    } else {
+        return 0;
+    }
+}
+
 static inline void tcg_out_arith(TCGContext *s, int rd, int rs1, int rs2,
                                  int op)
 {
@@ -486,39 +489,6 @@ static inline void tcg_out_nop(TCGContext *s)
     tcg_out_sethi(s, TCG_REG_G0, 0);
 }
 
-static void tcg_out_branch_i32(TCGContext *s, int opc, int label_index)
-{
-    TCGLabel *l = &s->labels[label_index];
-    uint32_t off22;
-
-    if (l->has_value) {
-        off22 = INSN_OFF22(l->u.value - (unsigned long)s->code_ptr);
-    } else {
-        /* Make sure to preserve destinations during retranslation.  */
-        off22 = *(uint32_t *)s->code_ptr & INSN_OFF22(-1);
-        tcg_out_reloc(s, s->code_ptr, R_SPARC_WDISP22, label_index, 0);
-    }
-    tcg_out32(s, INSN_OP(0) | INSN_COND(opc, 0) | INSN_OP2(0x2) | off22);
-}
-
-#if TCG_TARGET_REG_BITS == 64
-static void tcg_out_branch_i64(TCGContext *s, int opc, int label_index)
-{
-    TCGLabel *l = &s->labels[label_index];
-    uint32_t off19;
-
-    if (l->has_value) {
-        off19 = INSN_OFF19(l->u.value - (unsigned long)s->code_ptr);
-    } else {
-        /* Make sure to preserve destinations during retranslation.  */
-        off19 = *(uint32_t *)s->code_ptr & INSN_OFF19(-1);
-        tcg_out_reloc(s, s->code_ptr, R_SPARC_WDISP19, label_index, 0);
-    }
-    tcg_out32(s, (INSN_OP(0) | INSN_COND(opc, 0) | INSN_OP2(0x1) |
-                  (0x5 << 19) | off19));
-}
-#endif
-
 static const uint8_t tcg_cond_to_bcond[] = {
     [TCG_COND_EQ] = COND_E,
     [TCG_COND_NE] = COND_NE,
@@ -532,17 +502,36 @@ static const uint8_t tcg_cond_to_bcond[] = {
     [TCG_COND_GTU] = COND_GU,
 };
 
+static void tcg_out_bpcc0(TCGContext *s, int scond, int flags, int off19)
+{
+    tcg_out32(s, INSN_OP(0) | INSN_OP2(1) | INSN_COND(scond) | flags | off19);
+}
+
+static void tcg_out_bpcc(TCGContext *s, int scond, int flags, int label)
+{
+    TCGLabel *l = &s->labels[label];
+    int off19;
+
+    if (l->has_value) {
+        off19 = INSN_OFF19(l->u.value - (unsigned long)s->code_ptr);
+    } else {
+        /* Make sure to preserve destinations during retranslation.  */
+        off19 = *(uint32_t *)s->code_ptr & INSN_OFF19(-1);
+        tcg_out_reloc(s, s->code_ptr, R_SPARC_WDISP19, label, 0);
+    }
+    tcg_out_bpcc0(s, scond, flags, off19);
+}
+
 static void tcg_out_cmp(TCGContext *s, TCGArg c1, TCGArg c2, int c2const)
 {
     tcg_out_arithc(s, TCG_REG_G0, c1, c2, c2const, ARITH_SUBCC);
 }
 
-static void tcg_out_brcond_i32(TCGContext *s, TCGCond cond,
-                               TCGArg arg1, TCGArg arg2, int const_arg2,
-                               int label_index)
+static void tcg_out_brcond_i32(TCGContext *s, TCGCond cond, TCGArg arg1,
+                               TCGArg arg2, int const_arg2, int label)
 {
     tcg_out_cmp(s, arg1, arg2, const_arg2);
-    tcg_out_branch_i32(s, tcg_cond_to_bcond[cond], label_index);
+    tcg_out_bpcc(s, tcg_cond_to_bcond[cond], BPCC_ICC | BPCC_PT, label);
     tcg_out_nop(s);
 }
 
@@ -563,12 +552,11 @@ static void tcg_out_movcond_i32(TCGContext *s, TCGCond cond, TCGArg ret,
 }
 
 #if TCG_TARGET_REG_BITS == 64
-static void tcg_out_brcond_i64(TCGContext *s, TCGCond cond,
-                               TCGArg arg1, TCGArg arg2, int const_arg2,
-                               int label_index)
+static void tcg_out_brcond_i64(TCGContext *s, TCGCond cond, TCGArg arg1,
+                               TCGArg arg2, int const_arg2, int label)
 {
     tcg_out_cmp(s, arg1, arg2, const_arg2);
-    tcg_out_branch_i64(s, tcg_cond_to_bcond[cond], label_index);
+    tcg_out_bpcc(s, tcg_cond_to_bcond[cond], BPCC_XCC | BPCC_PT, label);
     tcg_out_nop(s);
 }
 
@@ -585,32 +573,32 @@ static void tcg_out_brcond2_i32(TCGContext *s, TCGCond cond,
                                 TCGArg bl, int blconst,
                                 TCGArg bh, int bhconst, int label_dest)
 {
-    int cc, label_next = gen_new_label();
+    int scond, label_next = gen_new_label();
 
     tcg_out_cmp(s, ah, bh, bhconst);
 
     /* Note that we fill one of the delay slots with the second compare.  */
     switch (cond) {
     case TCG_COND_EQ:
-        tcg_out_branch_i32(s, COND_NE, label_next);
+        tcg_out_bpcc(s, COND_NE, BPCC_ICC | BPCC_PT, label_next);
         tcg_out_cmp(s, al, bl, blconst);
-        tcg_out_branch_i32(s, COND_E, label_dest);
+        tcg_out_bpcc(s, COND_E, BPCC_ICC | BPCC_PT, label_dest);
         break;
 
     case TCG_COND_NE:
-        tcg_out_branch_i32(s, COND_NE, label_dest);
+        tcg_out_bpcc(s, COND_NE, BPCC_ICC | BPCC_PT, label_dest);
         tcg_out_cmp(s, al, bl, blconst);
-        tcg_out_branch_i32(s, COND_NE, label_dest);
+        tcg_out_bpcc(s, COND_NE, BPCC_ICC | BPCC_PT, label_dest);
         break;
 
     default:
-        cc = tcg_cond_to_bcond[tcg_high_cond(cond)];
-        tcg_out_branch_i32(s, cc, label_dest);
+        scond = tcg_cond_to_bcond[tcg_high_cond(cond)];
+        tcg_out_bpcc(s, scond, BPCC_ICC | BPCC_PT, label_dest);
         tcg_out_nop(s);
-        tcg_out_branch_i32(s, COND_NE, label_next);
+        tcg_out_bpcc(s, COND_NE, BPCC_ICC | BPCC_PT, label_next);
         tcg_out_cmp(s, al, bl, blconst);
-        cc = tcg_cond_to_bcond[tcg_unsigned_cond(cond)];
-        tcg_out_branch_i32(s, cc, label_dest);
+        scond = tcg_cond_to_bcond[tcg_unsigned_cond(cond)];
+        tcg_out_bpcc(s, scond, BPCC_ICC | BPCC_PT, label_dest);
         break;
     }
     tcg_out_nop(s);
@@ -903,8 +891,8 @@ static void tcg_out_qemu_ld(TCGContext *s, const TCGArg *args, int sizeop)
 
         /* bne,pn %[xi]cc, label0 */
         label_ptr[0] = (uint32_t *)s->code_ptr;
-        tcg_out32(s, (INSN_OP(0) | INSN_COND(COND_NE, 0) | INSN_OP2(0x1)
-                      | ((TARGET_LONG_BITS == 64) << 21)));
+        tcg_out_bpcc0(s, COND_NE, BPCC_PN
+                      | (TARGET_LONG_BITS == 64 ? BPCC_XCC : BPCC_ICC), 0);
 
         /* TLB Hit.  */
         /* Load all 64-bits into an O/G register.  */
@@ -919,8 +907,7 @@ static void tcg_out_qemu_ld(TCGContext *s, const TCGArg *args, int sizeop)
 
         /* b,a,pt label1 */
         label_ptr[1] = (uint32_t *)s->code_ptr;
-        tcg_out32(s, (INSN_OP(0) | INSN_COND(COND_A, 0) | INSN_OP2(0x1)
-                      | (1 << 29) | (1 << 19)));
+        tcg_out_bpcc0(s, COND_A, BPCC_A | BPCC_PT, 0);
     } else {
         /* The fast path is exactly one insn.  Thus we can perform the
            entire TLB Hit in the (annulled) delay slot of the branch
@@ -929,9 +916,8 @@ static void tcg_out_qemu_ld(TCGContext *s, const TCGArg *args, int sizeop)
         /* beq,a,pt %[xi]cc, label0 */
         label_ptr[0] = NULL;
         label_ptr[1] = (uint32_t *)s->code_ptr;
-        tcg_out32(s, (INSN_OP(0) | INSN_COND(COND_E, 0) | INSN_OP2(0x1)
-                      | ((TARGET_LONG_BITS == 64) << 21)
-                      | (1 << 29) | (1 << 19)));
+        tcg_out_bpcc0(s, COND_E, BPCC_A | BPCC_PT
+                      | (TARGET_LONG_BITS == 64 ? BPCC_XCC : BPCC_ICC), 0);
         /* delay slot */
         tcg_out_ldst_rr(s, datalo, addr_reg, TCG_REG_O1, qemu_ld_opc[sizeop]);
     }
@@ -1050,9 +1036,8 @@ static void tcg_out_qemu_st(TCGContext *s, const TCGArg *args, int sizeop)
        TLB Hit in the (annulled) delay slot of the branch over TLB Miss.  */
     /* beq,a,pt %[xi]cc, label0 */
     label_ptr = (uint32_t *)s->code_ptr;
-    tcg_out32(s, (INSN_OP(0) | INSN_COND(COND_E, 0) | INSN_OP2(0x1)
-                  | ((TARGET_LONG_BITS == 64) << 21)
-                  | (1 << 29) | (1 << 19)));
+    tcg_out_bpcc0(s, COND_E, BPCC_A | BPCC_PT
+                  | (TARGET_LONG_BITS == 64 ? BPCC_XCC : BPCC_ICC), 0);
     /* delay slot */
     tcg_out_ldst_rr(s, datafull, addr_reg, TCG_REG_O1, qemu_st_opc[sizeop]);
 
@@ -1143,7 +1128,7 @@ static inline void tcg_out_op(TCGContext *s, TCGOpcode opc, const TCGArg *args,
         tcg_out_nop(s);
         break;
     case INDEX_op_br:
-        tcg_out_branch_i32(s, COND_A, args[0]);
+        tcg_out_bpcc(s, COND_A, BPCC_PT, args[0]);
         tcg_out_nop(s);
         break;
     case INDEX_op_movi_i32:
commit fd84ea2391c044a7840c25dd35336bdaf2a302d0
Author: Richard Henderson <rth at twiddle.net>
Date:   Wed Oct 10 09:02:43 2012 -0700

    tcg-sparc: Optimize setcond2 equality compare with 0.
    
    Signed-off-by: Richard Henderson <rth at twiddle.net>
    Signed-off-by: Blue Swirl <blauwirbel at gmail.com>

diff --git a/tcg/sparc/tcg-target.c b/tcg/sparc/tcg-target.c
index f7d52d6..9c87cb6 100644
--- a/tcg/sparc/tcg-target.c
+++ b/tcg/sparc/tcg-target.c
@@ -693,9 +693,18 @@ static void tcg_out_setcond2_i32(TCGContext *s, TCGCond cond, TCGArg ret,
     switch (cond) {
     case TCG_COND_EQ:
     case TCG_COND_NE:
-        tcg_out_setcond_i32(s, cond, tmp, al, bl, blconst);
-        tcg_out_cmp(s, ah, bh, bhconst);
-        tcg_out_mov(s, TCG_TYPE_I32, ret, tmp);
+        if (bl == 0 && bh == 0) {
+            if (cond == TCG_COND_EQ) {
+                tcg_out_arith(s, TCG_REG_G0, al, ah, ARITH_ORCC);
+                tcg_out_movi(s, TCG_TYPE_I32, ret, 1);
+            } else {
+                tcg_out_arith(s, ret, al, ah, ARITH_ORCC);
+            }
+        } else {
+            tcg_out_setcond_i32(s, cond, tmp, al, bl, blconst);
+            tcg_out_cmp(s, ah, bh, bhconst);
+            tcg_out_mov(s, TCG_TYPE_I32, ret, tmp);
+        }
         tcg_out_movcc(s, TCG_COND_NE, MOVCC_ICC, ret, cond == TCG_COND_NE, 1);
         break;
 
commit 89269f6cea17d8381e0c366c44780f58ac3c67d8
Author: Richard Henderson <rth at twiddle.net>
Date:   Wed Oct 10 09:02:42 2012 -0700

    tcg-sparc: Use Z constraint for %g0
    
    Signed-off-by: Richard Henderson <rth at twiddle.net>
    Signed-off-by: Blue Swirl <blauwirbel at gmail.com>

diff --git a/tcg/sparc/tcg-target.c b/tcg/sparc/tcg-target.c
index d6da9fa..f7d52d6 100644
--- a/tcg/sparc/tcg-target.c
+++ b/tcg/sparc/tcg-target.c
@@ -180,6 +180,9 @@ static int target_parse_constraint(TCGArgConstraint *ct, const char **pct_str)
     case 'J':
         ct->ct |= TCG_CT_CONST_S13;
         break;
+    case 'Z':
+        ct->ct |= TCG_CT_CONST_ZERO;
+        break;
     default:
         return -1;
     }
@@ -192,17 +195,19 @@ static int target_parse_constraint(TCGArgConstraint *ct, const char **pct_str)
 static inline int tcg_target_const_match(tcg_target_long val,
                                          const TCGArgConstraint *arg_ct)
 {
-    int ct;
+    int ct = arg_ct->ct;
 
-    ct = arg_ct->ct;
-    if (ct & TCG_CT_CONST)
+    if (ct & TCG_CT_CONST) {
+        return 1;
+    } else if ((ct & TCG_CT_CONST_ZERO) && val == 0) {
         return 1;
-    else if ((ct & TCG_CT_CONST_S11) && check_fit_tl(val, 11))
+    } else if ((ct & TCG_CT_CONST_S11) && check_fit_tl(val, 11)) {
         return 1;
-    else if ((ct & TCG_CT_CONST_S13) && check_fit_tl(val, 13))
+    } else if ((ct & TCG_CT_CONST_S13) && check_fit_tl(val, 13)) {
         return 1;
-    else
+    } else {
         return 0;
+    }
 }
 
 #define INSN_OP(x)  ((x) << 30)
@@ -1411,40 +1416,40 @@ static const TCGTargetOpDef sparc_op_defs[] = {
     { INDEX_op_ld16u_i32, { "r", "r" } },
     { INDEX_op_ld16s_i32, { "r", "r" } },
     { INDEX_op_ld_i32, { "r", "r" } },
-    { INDEX_op_st8_i32, { "r", "r" } },
-    { INDEX_op_st16_i32, { "r", "r" } },
-    { INDEX_op_st_i32, { "r", "r" } },
-
-    { INDEX_op_add_i32, { "r", "r", "rJ" } },
-    { INDEX_op_mul_i32, { "r", "r", "rJ" } },
-    { INDEX_op_div_i32, { "r", "r", "rJ" } },
-    { INDEX_op_divu_i32, { "r", "r", "rJ" } },
-    { INDEX_op_rem_i32, { "r", "r", "rJ" } },
-    { INDEX_op_remu_i32, { "r", "r", "rJ" } },
-    { INDEX_op_sub_i32, { "r", "r", "rJ" } },
-    { INDEX_op_and_i32, { "r", "r", "rJ" } },
-    { INDEX_op_andc_i32, { "r", "r", "rJ" } },
-    { INDEX_op_or_i32, { "r", "r", "rJ" } },
-    { INDEX_op_orc_i32, { "r", "r", "rJ" } },
-    { INDEX_op_xor_i32, { "r", "r", "rJ" } },
-
-    { INDEX_op_shl_i32, { "r", "r", "rJ" } },
-    { INDEX_op_shr_i32, { "r", "r", "rJ" } },
-    { INDEX_op_sar_i32, { "r", "r", "rJ" } },
+    { INDEX_op_st8_i32, { "rZ", "r" } },
+    { INDEX_op_st16_i32, { "rZ", "r" } },
+    { INDEX_op_st_i32, { "rZ", "r" } },
+
+    { INDEX_op_add_i32, { "r", "rZ", "rJ" } },
+    { INDEX_op_mul_i32, { "r", "rZ", "rJ" } },
+    { INDEX_op_div_i32, { "r", "rZ", "rJ" } },
+    { INDEX_op_divu_i32, { "r", "rZ", "rJ" } },
+    { INDEX_op_rem_i32, { "r", "rZ", "rJ" } },
+    { INDEX_op_remu_i32, { "r", "rZ", "rJ" } },
+    { INDEX_op_sub_i32, { "r", "rZ", "rJ" } },
+    { INDEX_op_and_i32, { "r", "rZ", "rJ" } },
+    { INDEX_op_andc_i32, { "r", "rZ", "rJ" } },
+    { INDEX_op_or_i32, { "r", "rZ", "rJ" } },
+    { INDEX_op_orc_i32, { "r", "rZ", "rJ" } },
+    { INDEX_op_xor_i32, { "r", "rZ", "rJ" } },
+
+    { INDEX_op_shl_i32, { "r", "rZ", "rJ" } },
+    { INDEX_op_shr_i32, { "r", "rZ", "rJ" } },
+    { INDEX_op_sar_i32, { "r", "rZ", "rJ" } },
 
     { INDEX_op_neg_i32, { "r", "rJ" } },
     { INDEX_op_not_i32, { "r", "rJ" } },
 
-    { INDEX_op_brcond_i32, { "r", "rJ" } },
-    { INDEX_op_setcond_i32, { "r", "r", "rJ" } },
-    { INDEX_op_movcond_i32, { "r", "r", "rJ", "rI", "0" } },
+    { INDEX_op_brcond_i32, { "rZ", "rJ" } },
+    { INDEX_op_setcond_i32, { "r", "rZ", "rJ" } },
+    { INDEX_op_movcond_i32, { "r", "rZ", "rJ", "rI", "0" } },
 
 #if TCG_TARGET_REG_BITS == 32
-    { INDEX_op_brcond2_i32, { "r", "r", "rJ", "rJ" } },
-    { INDEX_op_setcond2_i32, { "r", "r", "r", "rJ", "rJ" } },
-    { INDEX_op_add2_i32, { "r", "r", "r", "r", "rJ", "rJ" } },
-    { INDEX_op_sub2_i32, { "r", "r", "r", "r", "rJ", "rJ" } },
-    { INDEX_op_mulu2_i32, { "r", "r", "r", "rJ" } },
+    { INDEX_op_brcond2_i32, { "rZ", "rZ", "rJ", "rJ" } },
+    { INDEX_op_setcond2_i32, { "r", "rZ", "rZ", "rJ", "rJ" } },
+    { INDEX_op_add2_i32, { "r", "r", "rZ", "rZ", "rJ", "rJ" } },
+    { INDEX_op_sub2_i32, { "r", "r", "rZ", "rZ", "rJ", "rJ" } },
+    { INDEX_op_mulu2_i32, { "r", "r", "rZ", "rJ" } },
 #endif
 
 #if TCG_TARGET_REG_BITS == 64
@@ -1457,27 +1462,27 @@ static const TCGTargetOpDef sparc_op_defs[] = {
     { INDEX_op_ld32u_i64, { "r", "r" } },
     { INDEX_op_ld32s_i64, { "r", "r" } },
     { INDEX_op_ld_i64, { "r", "r" } },
-    { INDEX_op_st8_i64, { "r", "r" } },
-    { INDEX_op_st16_i64, { "r", "r" } },
-    { INDEX_op_st32_i64, { "r", "r" } },
-    { INDEX_op_st_i64, { "r", "r" } },
-
-    { INDEX_op_add_i64, { "r", "r", "rJ" } },
-    { INDEX_op_mul_i64, { "r", "r", "rJ" } },
-    { INDEX_op_div_i64, { "r", "r", "rJ" } },
-    { INDEX_op_divu_i64, { "r", "r", "rJ" } },
-    { INDEX_op_rem_i64, { "r", "r", "rJ" } },
-    { INDEX_op_remu_i64, { "r", "r", "rJ" } },
-    { INDEX_op_sub_i64, { "r", "r", "rJ" } },
-    { INDEX_op_and_i64, { "r", "r", "rJ" } },
-    { INDEX_op_andc_i64, { "r", "r", "rJ" } },
-    { INDEX_op_or_i64, { "r", "r", "rJ" } },
-    { INDEX_op_orc_i64, { "r", "r", "rJ" } },
-    { INDEX_op_xor_i64, { "r", "r", "rJ" } },
-
-    { INDEX_op_shl_i64, { "r", "r", "rJ" } },
-    { INDEX_op_shr_i64, { "r", "r", "rJ" } },
-    { INDEX_op_sar_i64, { "r", "r", "rJ" } },
+    { INDEX_op_st8_i64, { "rZ", "r" } },
+    { INDEX_op_st16_i64, { "rZ", "r" } },
+    { INDEX_op_st32_i64, { "rZ", "r" } },
+    { INDEX_op_st_i64, { "rZ", "r" } },
+
+    { INDEX_op_add_i64, { "r", "rZ", "rJ" } },
+    { INDEX_op_mul_i64, { "r", "rZ", "rJ" } },
+    { INDEX_op_div_i64, { "r", "rZ", "rJ" } },
+    { INDEX_op_divu_i64, { "r", "rZ", "rJ" } },
+    { INDEX_op_rem_i64, { "r", "rZ", "rJ" } },
+    { INDEX_op_remu_i64, { "r", "rZ", "rJ" } },
+    { INDEX_op_sub_i64, { "r", "rZ", "rJ" } },
+    { INDEX_op_and_i64, { "r", "rZ", "rJ" } },
+    { INDEX_op_andc_i64, { "r", "rZ", "rJ" } },
+    { INDEX_op_or_i64, { "r", "rZ", "rJ" } },
+    { INDEX_op_orc_i64, { "r", "rZ", "rJ" } },
+    { INDEX_op_xor_i64, { "r", "rZ", "rJ" } },
+
+    { INDEX_op_shl_i64, { "r", "rZ", "rJ" } },
+    { INDEX_op_shr_i64, { "r", "rZ", "rJ" } },
+    { INDEX_op_sar_i64, { "r", "rZ", "rJ" } },
 
     { INDEX_op_neg_i64, { "r", "rJ" } },
     { INDEX_op_not_i64, { "r", "rJ" } },
@@ -1485,9 +1490,9 @@ static const TCGTargetOpDef sparc_op_defs[] = {
     { INDEX_op_ext32s_i64, { "r", "ri" } },
     { INDEX_op_ext32u_i64, { "r", "ri" } },
 
-    { INDEX_op_brcond_i64, { "r", "rJ" } },
-    { INDEX_op_setcond_i64, { "r", "r", "rJ" } },
-    { INDEX_op_movcond_i64, { "r", "r", "rJ", "rI", "0" } },
+    { INDEX_op_brcond_i64, { "rZ", "rJ" } },
+    { INDEX_op_setcond_i64, { "r", "rZ", "rJ" } },
+    { INDEX_op_movcond_i64, { "r", "rZ", "rJ", "rI", "0" } },
 #endif
 
 #if TCG_TARGET_REG_BITS == 64
diff --git a/tcg/sparc/tcg-target.h b/tcg/sparc/tcg-target.h
index c718a52..c2fbb23 100644
--- a/tcg/sparc/tcg-target.h
+++ b/tcg/sparc/tcg-target.h
@@ -62,8 +62,9 @@ typedef enum {
     TCG_REG_I7,
 } TCGReg;
 
-#define TCG_CT_CONST_S11 0x100
-#define TCG_CT_CONST_S13 0x200
+#define TCG_CT_CONST_S11  0x100
+#define TCG_CT_CONST_S13  0x200
+#define TCG_CT_CONST_ZERO 0x400
 
 /* used for function call generation */
 #define TCG_REG_CALL_STACK TCG_REG_O6
commit 4ec28e255f532c245cb477d49d0793af657e4149
Author: Richard Henderson <rth at twiddle.net>
Date:   Wed Oct 10 09:02:41 2012 -0700

    tcg-sparc: Fix add2/sub2
    
    We must care not to clobber the high parts before we consume them.
    
    Signed-off-by: Richard Henderson <rth at twiddle.net>
    Signed-off-by: Blue Swirl <blauwirbel at gmail.com>

diff --git a/tcg/sparc/tcg-target.c b/tcg/sparc/tcg-target.c
index 31e8204..d6da9fa 100644
--- a/tcg/sparc/tcg-target.c
+++ b/tcg/sparc/tcg-target.c
@@ -704,6 +704,22 @@ static void tcg_out_setcond2_i32(TCGContext *s, TCGCond cond, TCGArg ret,
         break;
     }
 }
+
+static void tcg_out_addsub2(TCGContext *s, TCGArg rl, TCGArg rh,
+                            TCGArg al, TCGArg ah, TCGArg bl, int blconst,
+                            TCGArg bh, int bhconst, int opl, int oph)
+{
+    TCGArg tmp = TCG_REG_T1;
+
+    /* Note that the low parts are fully consumed before tmp is set.  */
+    if (rl != ah && (bhconst || rl != bh)) {
+        tmp = rl;
+    }
+
+    tcg_out_arithc(s, tmp, al, bl, blconst, opl);
+    tcg_out_arithc(s, rh, ah, bh, bhconst, oph);
+    tcg_out_mov(s, TCG_TYPE_I32, rl, tmp);
+}
 #endif
 
 /* Generate global QEMU prologue and epilogue code */
@@ -1243,16 +1259,14 @@ static inline void tcg_out_op(TCGContext *s, TCGOpcode opc, const TCGArg *args,
                              args[4], const_args[4]);
         break;
     case INDEX_op_add2_i32:
-        tcg_out_arithc(s, args[0], args[2], args[4], const_args[4],
-                       ARITH_ADDCC);
-        tcg_out_arithc(s, args[1], args[3], args[5], const_args[5],
-                       ARITH_ADDX);
+        tcg_out_addsub2(s, args[0], args[1], args[2], args[3],
+                        args[4], const_args[4], args[5], const_args[5],
+                        ARITH_ADDCC, ARITH_ADDX);
         break;
     case INDEX_op_sub2_i32:
-        tcg_out_arithc(s, args[0], args[2], args[4], const_args[4],
-                       ARITH_SUBCC);
-        tcg_out_arithc(s, args[1], args[3], args[5], const_args[5],
-                       ARITH_SUBX);
+        tcg_out_addsub2(s, args[0], args[1], args[2], args[3],
+                        args[4], const_args[4], args[5], const_args[5],
+                        ARITH_SUBCC, ARITH_SUBX);
         break;
     case INDEX_op_mulu2_i32:
         tcg_out_arithc(s, args[0], args[2], args[3], const_args[3],
commit 7d458a7567ffde5b16d7a4b5e9f585434b2afc35
Author: Richard Henderson <rth at twiddle.net>
Date:   Wed Oct 10 09:02:40 2012 -0700

    tcg-sparc: Fix setcond
    
    The set of comparisons that can immediately use the carry are LTU/GEU,
    not LTU/LEU.  Don't swap operands when we need a temp register; the
    register may already be in use from setcond2.
    
    Signed-off-by: Richard Henderson <rth at twiddle.net>
    Signed-off-by: Blue Swirl <blauwirbel at gmail.com>

diff --git a/tcg/sparc/tcg-target.c b/tcg/sparc/tcg-target.c
index 3144044..31e8204 100644
--- a/tcg/sparc/tcg-target.c
+++ b/tcg/sparc/tcg-target.c
@@ -617,32 +617,37 @@ static void tcg_out_brcond2_i32(TCGContext *s, TCGCond cond,
 static void tcg_out_setcond_i32(TCGContext *s, TCGCond cond, TCGArg ret,
                                 TCGArg c1, TCGArg c2, int c2const)
 {
-    TCGArg t;
-
     /* For 32-bit comparisons, we can play games with ADDX/SUBX.  */
     switch (cond) {
+    case TCG_COND_LTU:
+    case TCG_COND_GEU:
+        /* The result of the comparison is in the carry bit.  */
+        break;
+
     case TCG_COND_EQ:
     case TCG_COND_NE:
+        /* For equality, we can transform to inequality vs zero.  */
         if (c2 != 0) {
             tcg_out_arithc(s, ret, c1, c2, c2const, ARITH_XOR);
         }
         c1 = TCG_REG_G0, c2 = ret, c2const = 0;
-        cond = (cond == TCG_COND_EQ ? TCG_COND_LEU : TCG_COND_LTU);
+        cond = (cond == TCG_COND_EQ ? TCG_COND_GEU : TCG_COND_LTU);
 	break;
 
     case TCG_COND_GTU:
-    case TCG_COND_GEU:
-        if (c2const && c2 != 0) {
-            tcg_out_movi_imm13(s, TCG_REG_T1, c2);
-            c2 = TCG_REG_T1;
-        }
-        t = c1, c1 = c2, c2 = t, c2const = 0;
-        cond = tcg_swap_cond(cond);
-        break;
-
-    case TCG_COND_LTU:
     case TCG_COND_LEU:
-        break;
+        /* If we don't need to load a constant into a register, we can
+           swap the operands on GTU/LEU.  There's no benefit to loading
+           the constant into a temporary register.  */
+        if (!c2const || c2 == 0) {
+            TCGArg t = c1;
+            c1 = c2;
+            c2 = t;
+            c2const = 0;
+            cond = tcg_swap_cond(cond);
+            break;
+        }
+        /* FALLTHRU */
 
     default:
         tcg_out_cmp(s, c1, c2, c2const);
commit a7a49843d70232e0f179e1da330355e5f03ab182
Author: Richard Henderson <rth at twiddle.net>
Date:   Wed Oct 10 09:02:39 2012 -0700

    tcg-sparc: Fix qemu_st for 32-bit
    
    The datalo variable is still live in the miss path.  Use another
    when reconstructing the full data value.
    
    Signed-off-by: Richard Henderson <rth at twiddle.net>
    Signed-off-by: Blue Swirl <blauwirbel at gmail.com>

diff --git a/tcg/sparc/tcg-target.c b/tcg/sparc/tcg-target.c
index bdc282d..3144044 100644
--- a/tcg/sparc/tcg-target.c
+++ b/tcg/sparc/tcg-target.c
@@ -985,7 +985,7 @@ static void tcg_out_qemu_st(TCGContext *s, const TCGArg *args, int sizeop)
 {
     int addrlo_idx = 1, datalo, datahi, addr_reg;
 #if defined(CONFIG_SOFTMMU)
-    int memi_idx, memi, n;
+    int memi_idx, memi, n, datafull;
     uint32_t *label_ptr;
 #endif
 
@@ -1002,12 +1002,13 @@ static void tcg_out_qemu_st(TCGContext *s, const TCGArg *args, int sizeop)
     addr_reg = tcg_out_tlb_load(s, addrlo_idx, memi, sizeop, args,
                                 offsetof(CPUTLBEntry, addr_write));
 
+    datafull = datalo;
     if (TCG_TARGET_REG_BITS == 32 && sizeop == 3) {
         /* Reconstruct the full 64-bit value.  */
         tcg_out_arithi(s, TCG_REG_T1, datalo, 0, SHIFT_SRL);
         tcg_out_arithi(s, TCG_REG_O2, datahi, 32, SHIFT_SLLX);
         tcg_out_arith(s, TCG_REG_O2, TCG_REG_T1, TCG_REG_O2, ARITH_OR);
-        datalo = TCG_REG_O2;
+        datafull = TCG_REG_O2;
     }
 
     /* The fast path is exactly one insn.  Thus we can perform the entire
@@ -1018,7 +1019,7 @@ static void tcg_out_qemu_st(TCGContext *s, const TCGArg *args, int sizeop)
                   | ((TARGET_LONG_BITS == 64) << 21)
                   | (1 << 29) | (1 << 19)));
     /* delay slot */
-    tcg_out_ldst_rr(s, datalo, addr_reg, TCG_REG_O1, qemu_st_opc[sizeop]);
+    tcg_out_ldst_rr(s, datafull, addr_reg, TCG_REG_O1, qemu_st_opc[sizeop]);
 
     /* TLB Miss.  */
 
commit dda73c782ffb1333eaf96444e27dcce5bc658454
Author: Richard Henderson <rth at twiddle.net>
Date:   Wed Oct 10 09:02:38 2012 -0700

    tcg-sparc: Fix setcond2
    
    Like brcond2, use tcg_high_cond.  Use movcc instead of branches.
    
    Signed-off-by: Richard Henderson <rth at twiddle.net>
    Signed-off-by: Blue Swirl <blauwirbel at gmail.com>

diff --git a/tcg/sparc/tcg-target.c b/tcg/sparc/tcg-target.c
index 79530ec..bdc282d 100644
--- a/tcg/sparc/tcg-target.c
+++ b/tcg/sparc/tcg-target.c
@@ -337,7 +337,9 @@ static void tcg_out_arithc(TCGContext *s, int rd, int rs1,
 static inline void tcg_out_mov(TCGContext *s, TCGType type,
                                TCGReg ret, TCGReg arg)
 {
-    tcg_out_arith(s, ret, arg, TCG_REG_G0, ARITH_OR);
+    if (ret != arg) {
+        tcg_out_arith(s, ret, arg, TCG_REG_G0, ARITH_OR);
+    }
 }
 
 static inline void tcg_out_sethi(TCGContext *s, int ret, uint32_t arg)
@@ -671,33 +673,29 @@ static void tcg_out_setcond2_i32(TCGContext *s, TCGCond cond, TCGArg ret,
                                  TCGArg bl, int blconst,
                                  TCGArg bh, int bhconst)
 {
-    int lab;
+    int tmp = TCG_REG_T1;
+
+    /* Note that the low parts are fully consumed before tmp is set.  */
+    if (ret != ah && (bhconst || ret != bh)) {
+        tmp = ret;
+    }
 
     switch (cond) {
     case TCG_COND_EQ:
-        tcg_out_setcond_i32(s, TCG_COND_EQ, TCG_REG_T1, al, bl, blconst);
-        tcg_out_setcond_i32(s, TCG_COND_EQ, ret, ah, bh, bhconst);
-        tcg_out_arith(s, ret, ret, TCG_REG_T1, ARITH_AND);
-        break;
-
     case TCG_COND_NE:
-        tcg_out_setcond_i32(s, TCG_COND_NE, TCG_REG_T1, al, al, blconst);
-        tcg_out_setcond_i32(s, TCG_COND_NE, ret, ah, bh, bhconst);
-        tcg_out_arith(s, ret, ret, TCG_REG_T1, ARITH_OR);
+        tcg_out_setcond_i32(s, cond, tmp, al, bl, blconst);
+        tcg_out_cmp(s, ah, bh, bhconst);
+        tcg_out_mov(s, TCG_TYPE_I32, ret, tmp);
+        tcg_out_movcc(s, TCG_COND_NE, MOVCC_ICC, ret, cond == TCG_COND_NE, 1);
         break;
 
     default:
-        lab = gen_new_label();
-
+        /* <= : ah < bh | (ah == bh && al <= bl) */
+        tcg_out_setcond_i32(s, tcg_unsigned_cond(cond), tmp, al, bl, blconst);
         tcg_out_cmp(s, ah, bh, bhconst);
-        tcg_out_branch_i32(s, INSN_COND(tcg_cond_to_bcond[cond], 1), lab);
-        tcg_out_movi_imm13(s, ret, 1);
-        tcg_out_branch_i32(s, INSN_COND(COND_NE, 1), lab);
-        tcg_out_movi_imm13(s, ret, 0);
-
-        tcg_out_setcond_i32(s, tcg_unsigned_cond(cond), ret, al, bl, blconst);
-
-        tcg_out_label(s, lab, s->code_ptr);
+        tcg_out_mov(s, TCG_TYPE_I32, ret, tmp);
+        tcg_out_movcc(s, TCG_COND_NE, MOVCC_ICC, ret, 0, 1);
+        tcg_out_movcc(s, tcg_high_cond(cond), MOVCC_ICC, ret, 1, 1);
         break;
     }
 }
commit ded37f0d96f81b6294c728d4693d9880135e3cb9
Author: Richard Henderson <rth at twiddle.net>
Date:   Wed Oct 10 09:02:37 2012 -0700

    tcg-sparc: Implement movcond.
    
    Signed-off-by: Richard Henderson <rth at twiddle.net>
    Signed-off-by: Blue Swirl <blauwirbel at gmail.com>

diff --git a/tcg/sparc/tcg-target.c b/tcg/sparc/tcg-target.c
index 2475808..79530ec 100644
--- a/tcg/sparc/tcg-target.c
+++ b/tcg/sparc/tcg-target.c
@@ -539,6 +539,22 @@ static void tcg_out_brcond_i32(TCGContext *s, TCGCond cond,
     tcg_out_nop(s);
 }
 
+static void tcg_out_movcc(TCGContext *s, TCGCond cond, int cc, TCGArg ret,
+                          TCGArg v1, int v1const)
+{
+    tcg_out32(s, ARITH_MOVCC | cc | INSN_RD(ret)
+              | INSN_RS1(tcg_cond_to_bcond[cond])
+              | (v1const ? INSN_IMM11(v1) : INSN_RS2(v1)));
+}
+
+static void tcg_out_movcond_i32(TCGContext *s, TCGCond cond, TCGArg ret,
+                                TCGArg c1, TCGArg c2, int c2const,
+                                TCGArg v1, int v1const)
+{
+    tcg_out_cmp(s, c1, c2, c2const);
+    tcg_out_movcc(s, cond, MOVCC_ICC, ret, v1, v1const);
+}
+
 #if TCG_TARGET_REG_BITS == 64
 static void tcg_out_brcond_i64(TCGContext *s, TCGCond cond,
                                TCGArg arg1, TCGArg arg2, int const_arg2,
@@ -548,6 +564,14 @@ static void tcg_out_brcond_i64(TCGContext *s, TCGCond cond,
     tcg_out_branch_i64(s, tcg_cond_to_bcond[cond], label_index);
     tcg_out_nop(s);
 }
+
+static void tcg_out_movcond_i64(TCGContext *s, TCGCond cond, TCGArg ret,
+                                TCGArg c1, TCGArg c2, int c2const,
+                                TCGArg v1, int v1const)
+{
+    tcg_out_cmp(s, c1, c2, c2const);
+    tcg_out_movcc(s, cond, MOVCC_XCC, ret, v1, v1const);
+}
 #else
 static void tcg_out_brcond2_i32(TCGContext *s, TCGCond cond,
                                 TCGArg al, TCGArg ah,
@@ -621,9 +645,7 @@ static void tcg_out_setcond_i32(TCGContext *s, TCGCond cond, TCGArg ret,
     default:
         tcg_out_cmp(s, c1, c2, c2const);
         tcg_out_movi_imm13(s, ret, 0);
-        tcg_out32(s, ARITH_MOVCC | INSN_RD(ret)
-                  | INSN_RS1(tcg_cond_to_bcond[cond])
-                  | MOVCC_ICC | INSN_IMM11(1));
+        tcg_out_movcc(s, cond, MOVCC_ICC, ret, 1, 1);
         return;
     }
 
@@ -641,9 +663,7 @@ static void tcg_out_setcond_i64(TCGContext *s, TCGCond cond, TCGArg ret,
 {
     tcg_out_cmp(s, c1, c2, c2const);
     tcg_out_movi_imm13(s, ret, 0);
-    tcg_out32 (s, ARITH_MOVCC | INSN_RD(ret)
-               | INSN_RS1(tcg_cond_to_bcond[cond])
-               | MOVCC_XCC | INSN_IMM11(1));
+    tcg_out_movcc(s, cond, MOVCC_XCC, ret, 1, 1);
 }
 #else
 static void tcg_out_setcond2_i32(TCGContext *s, TCGCond cond, TCGArg ret,
@@ -1202,6 +1222,10 @@ static inline void tcg_out_op(TCGContext *s, TCGOpcode opc, const TCGArg *args,
         tcg_out_setcond_i32(s, args[3], args[0], args[1],
                             args[2], const_args[2]);
         break;
+    case INDEX_op_movcond_i32:
+        tcg_out_movcond_i32(s, args[5], args[0], args[1],
+                            args[2], const_args[2], args[3], const_args[3]);
+        break;
 
 #if TCG_TARGET_REG_BITS == 32
     case INDEX_op_brcond2_i32:
@@ -1337,7 +1361,10 @@ static inline void tcg_out_op(TCGContext *s, TCGOpcode opc, const TCGArg *args,
         tcg_out_setcond_i64(s, args[3], args[0], args[1],
                             args[2], const_args[2]);
         break;
-
+    case INDEX_op_movcond_i64:
+        tcg_out_movcond_i64(s, args[5], args[0], args[1],
+                            args[2], const_args[2], args[3], const_args[3]);
+        break;
 #endif
     gen_arith:
         tcg_out_arithc(s, args[0], args[1], args[2], const_args[2], c);
@@ -1392,6 +1419,7 @@ static const TCGTargetOpDef sparc_op_defs[] = {
 
     { INDEX_op_brcond_i32, { "r", "rJ" } },
     { INDEX_op_setcond_i32, { "r", "r", "rJ" } },
+    { INDEX_op_movcond_i32, { "r", "r", "rJ", "rI", "0" } },
 
 #if TCG_TARGET_REG_BITS == 32
     { INDEX_op_brcond2_i32, { "r", "r", "rJ", "rJ" } },
@@ -1441,6 +1469,7 @@ static const TCGTargetOpDef sparc_op_defs[] = {
 
     { INDEX_op_brcond_i64, { "r", "rJ" } },
     { INDEX_op_setcond_i64, { "r", "r", "rJ" } },
+    { INDEX_op_movcond_i64, { "r", "r", "rJ", "rI", "0" } },
 #endif
 
 #if TCG_TARGET_REG_BITS == 64
diff --git a/tcg/sparc/tcg-target.h b/tcg/sparc/tcg-target.h
index 6314ffb..c718a52 100644
--- a/tcg/sparc/tcg-target.h
+++ b/tcg/sparc/tcg-target.h
@@ -99,7 +99,7 @@ typedef enum {
 #define TCG_TARGET_HAS_nand_i32         0
 #define TCG_TARGET_HAS_nor_i32          0
 #define TCG_TARGET_HAS_deposit_i32      0
-#define TCG_TARGET_HAS_movcond_i32      0
+#define TCG_TARGET_HAS_movcond_i32      1
 
 #if TCG_TARGET_REG_BITS == 64
 #define TCG_TARGET_HAS_div_i64          1
@@ -121,7 +121,7 @@ typedef enum {
 #define TCG_TARGET_HAS_nand_i64         0
 #define TCG_TARGET_HAS_nor_i64          0
 #define TCG_TARGET_HAS_deposit_i64      0
-#define TCG_TARGET_HAS_movcond_i64      0
+#define TCG_TARGET_HAS_movcond_i64      1
 #endif
 
 #define TCG_TARGET_HAS_GUEST_BASE
commit 24c7f75459a042ac5467e0efdcb67e6c2127d5ea
Author: Richard Henderson <rth at twiddle.net>
Date:   Wed Oct 10 09:02:36 2012 -0700

    tcg-sparc: Fix brcond2
    
    Much the same problem as recently fixed for hppa.
    
    Signed-off-by: Richard Henderson <rth at twiddle.net>
    Signed-off-by: Blue Swirl <blauwirbel at gmail.com>

diff --git a/tcg/sparc/tcg-target.c b/tcg/sparc/tcg-target.c
index 0c32baa..2475808 100644
--- a/tcg/sparc/tcg-target.c
+++ b/tcg/sparc/tcg-target.c
@@ -561,33 +561,24 @@ static void tcg_out_brcond2_i32(TCGContext *s, TCGCond cond,
     /* Note that we fill one of the delay slots with the second compare.  */
     switch (cond) {
     case TCG_COND_EQ:
-        cc = INSN_COND(tcg_cond_to_bcond[TCG_COND_NE], 0);
-        tcg_out_branch_i32(s, cc, label_next);
+        tcg_out_branch_i32(s, COND_NE, label_next);
         tcg_out_cmp(s, al, bl, blconst);
-        cc = INSN_COND(tcg_cond_to_bcond[TCG_COND_EQ], 0);
-        tcg_out_branch_i32(s, cc, label_dest);
+        tcg_out_branch_i32(s, COND_E, label_dest);
         break;
 
     case TCG_COND_NE:
-        cc = INSN_COND(tcg_cond_to_bcond[TCG_COND_NE], 0);
-        tcg_out_branch_i32(s, cc, label_dest);
+        tcg_out_branch_i32(s, COND_NE, label_dest);
         tcg_out_cmp(s, al, bl, blconst);
-        tcg_out_branch_i32(s, cc, label_dest);
+        tcg_out_branch_i32(s, COND_NE, label_dest);
         break;
 
     default:
-        /* ??? One could fairly easily special-case 64-bit unsigned
-           compares against 32-bit zero-extended constants.  For instance,
-           we know that (unsigned)AH < 0 is false and need not emit it.
-           Similarly, (unsigned)AH > 0 being true implies AH != 0, so the
-           second branch will never be taken.  */
-        cc = INSN_COND(tcg_cond_to_bcond[cond], 0);
+        cc = tcg_cond_to_bcond[tcg_high_cond(cond)];
         tcg_out_branch_i32(s, cc, label_dest);
         tcg_out_nop(s);
-        cc = INSN_COND(tcg_cond_to_bcond[TCG_COND_NE], 0);
-        tcg_out_branch_i32(s, cc, label_next);
+        tcg_out_branch_i32(s, COND_NE, label_next);
         tcg_out_cmp(s, al, bl, blconst);
-        cc = INSN_COND(tcg_cond_to_bcond[tcg_unsigned_cond(cond)], 0);
+        cc = tcg_cond_to_bcond[tcg_unsigned_cond(cond)];
         tcg_out_branch_i32(s, cc, label_dest);
         break;
     }
commit 20132b96055e1da1d114067c15bf53e78a25d1c4
Author: Richard Henderson <rth at twiddle.net>
Date:   Tue Oct 9 14:50:00 2012 -0700

    target-sparc: Don't compute full flags value so often
    
    Avoid speculatively computing flags before every potentially trapping
    operation and instead do the flags computation when a trap actually
    occurs.  This gives approximately 30% speedup in emulation.
    
    Signed-off-by: Richard Henderson <rth at twiddle.net>
    Signed-off-by: Blue Swirl <blauwirbel at gmail.com>

diff --git a/linux-user/main.c b/linux-user/main.c
index 9f3476b..f4bbe69 100644
--- a/linux-user/main.c
+++ b/linux-user/main.c
@@ -1114,6 +1114,11 @@ void cpu_loop (CPUSPARCState *env)
     while (1) {
         trapnr = cpu_sparc_exec (env);
 
+        /* Compute PSR before exposing state.  */
+        if (env->cc_op != CC_OP_FLAGS) {
+            cpu_get_psr(env);
+        }
+
         switch (trapnr) {
 #ifndef TARGET_SPARC64
         case 0x88:
diff --git a/target-sparc/int32_helper.c b/target-sparc/int32_helper.c
index 9ac5aac..507c355 100644
--- a/target-sparc/int32_helper.c
+++ b/target-sparc/int32_helper.c
@@ -62,6 +62,11 @@ void do_interrupt(CPUSPARCState *env)
 {
     int cwp, intno = env->exception_index;
 
+    /* Compute PSR before exposing state.  */
+    if (env->cc_op != CC_OP_FLAGS) {
+        cpu_get_psr(env);
+    }
+
 #ifdef DEBUG_PCALL
     if (qemu_loglevel_mask(CPU_LOG_INT)) {
         static int count;
diff --git a/target-sparc/int64_helper.c b/target-sparc/int64_helper.c
index 5d0bc6c..df37aa1 100644
--- a/target-sparc/int64_helper.c
+++ b/target-sparc/int64_helper.c
@@ -64,6 +64,11 @@ void do_interrupt(CPUSPARCState *env)
     int intno = env->exception_index;
     trap_state *tsptr;
 
+    /* Compute PSR before exposing state.  */
+    if (env->cc_op != CC_OP_FLAGS) {
+        cpu_get_psr(env);
+    }
+
 #ifdef DEBUG_PCALL
     if (qemu_loglevel_mask(CPU_LOG_INT)) {
         static int count;
diff --git a/target-sparc/translate.c b/target-sparc/translate.c
index 65e6f23..6cef96b 100644
--- a/target-sparc/translate.c
+++ b/target-sparc/translate.c
@@ -1005,14 +1005,17 @@ static inline void save_npc(DisasContext *dc)
     }
 }
 
-static inline void save_state(DisasContext *dc)
+static inline void update_psr(DisasContext *dc)
 {
-    tcg_gen_movi_tl(cpu_pc, dc->pc);
-    /* flush pending conditional evaluations before exposing cpu state */
     if (dc->cc_op != CC_OP_FLAGS) {
         dc->cc_op = CC_OP_FLAGS;
         gen_helper_compute_psr(cpu_env);
     }
+}
+
+static inline void save_state(DisasContext *dc)
+{
+    tcg_gen_movi_tl(cpu_pc, dc->pc);
     save_npc(dc);
 }
 
@@ -2704,7 +2707,7 @@ static void disas_sparc_insn(DisasContext * dc, unsigned int insn)
                     break;
 #ifdef TARGET_SPARC64
                 case 0x2: /* V9 rdccr */
-                    gen_helper_compute_psr(cpu_env);
+                    update_psr(dc);
                     gen_helper_rdccr(cpu_dst, cpu_env);
                     gen_movl_TN_reg(rd, cpu_dst);
                     break;
@@ -2783,10 +2786,10 @@ static void disas_sparc_insn(DisasContext * dc, unsigned int insn)
 #if !defined(CONFIG_USER_ONLY)
             } else if (xop == 0x29) { /* rdpsr / UA2005 rdhpr */
 #ifndef TARGET_SPARC64
-                if (!supervisor(dc))
+                if (!supervisor(dc)) {
                     goto priv_insn;
-                gen_helper_compute_psr(cpu_env);
-                dc->cc_op = CC_OP_FLAGS;
+                }
+                update_psr(dc);
                 gen_helper_rdpsr(cpu_dst, cpu_env);
 #else
                 CHECK_IU_FEATURE(dc, HYPV);
@@ -3612,7 +3615,7 @@ static void disas_sparc_insn(DisasContext * dc, unsigned int insn)
                         dc->cc_op = CC_OP_TSUBTV;
                         break;
                     case 0x24: /* mulscc */
-                        gen_helper_compute_psr(cpu_env);
+                        update_psr(dc);
                         gen_op_mulscc(cpu_dst, cpu_src1, cpu_src2);
                         gen_movl_TN_reg(rd, cpu_dst);
                         tcg_gen_movi_i32(cpu_cc_op, CC_OP_ADD);
@@ -4651,12 +4654,6 @@ static void disas_sparc_insn(DisasContext * dc, unsigned int insn)
         {
             unsigned int xop = GET_FIELD(insn, 7, 12);
 
-            /* flush pending conditional evaluations before exposing
-               cpu state */
-            if (dc->cc_op != CC_OP_FLAGS) {
-                dc->cc_op = CC_OP_FLAGS;
-                gen_helper_compute_psr(cpu_env);
-            }
             cpu_src1 = get_src1(insn, cpu_src1);
             if (xop == 0x3c || xop == 0x3e) { // V9 casa/casxa
                 rs2 = GET_FIELD(insn, 27, 31);
@@ -5507,9 +5504,4 @@ void restore_state_to_opc(CPUSPARCState *env, TranslationBlock *tb, int pc_pos)
     } else {
         env->npc = npc;
     }
-
-    /* flush pending conditional evaluations before exposing cpu state */
-    if (CC_OP != CC_OP_FLAGS) {
-        helper_compute_psr(env);
-    }
 }
commit 6234ac09a947d1402f92b6d25ccea6faa4433b5b
Author: Richard Henderson <rth at twiddle.net>
Date:   Tue Oct 9 14:49:59 2012 -0700

    target-sparc: Avoid unnecessary local temporaries
    
    Now that save_state never ends a BB, we don't need to copy
    values into local temps around it.
    
    Signed-off-by: Richard Henderson <rth at twiddle.net>
    Signed-off-by: Blue Swirl <blauwirbel at gmail.com>

diff --git a/target-sparc/translate.c b/target-sparc/translate.c
index 4409f69..65e6f23 100644
--- a/target-sparc/translate.c
+++ b/target-sparc/translate.c
@@ -143,7 +143,7 @@ static TCGv_i32 gen_load_fpr_F(DisasContext *dc, unsigned int src)
     if (src & 1) {
         return MAKE_TCGV_I32(GET_TCGV_I64(cpu_fpr[src / 2]));
     } else {
-        TCGv_i32 ret = tcg_temp_local_new_i32();
+        TCGv_i32 ret = tcg_temp_new_i32();
         TCGv_i64 t = tcg_temp_new_i64();
 
         tcg_gen_shri_i64(t, cpu_fpr[src / 2], 32);
@@ -3885,28 +3885,16 @@ static void disas_sparc_insn(DisasContext * dc, unsigned int insn)
                                 tcg_gen_mov_tl(cpu_tbr, cpu_tmp0);
                                 break;
                             case 6: // pstate
-                                {
-                                    TCGv r_tmp = tcg_temp_local_new();
-
-                                    tcg_gen_mov_tl(r_tmp, cpu_tmp0);
-                                    save_state(dc);
-                                    gen_helper_wrpstate(cpu_env, r_tmp);
-                                    tcg_temp_free(r_tmp);
-                                    dc->npc = DYNAMIC_PC;
-                                }
+                                save_state(dc);
+                                gen_helper_wrpstate(cpu_env, cpu_tmp0);
+                                dc->npc = DYNAMIC_PC;
                                 break;
                             case 7: // tl
-                                {
-                                    TCGv r_tmp = tcg_temp_local_new();
-
-                                    tcg_gen_mov_tl(r_tmp, cpu_tmp0);
-                                    save_state(dc);
-                                    tcg_gen_trunc_tl_i32(cpu_tmp32, r_tmp);
-                                    tcg_temp_free(r_tmp);
-                                    tcg_gen_st_i32(cpu_tmp32, cpu_env,
-                                                   offsetof(CPUSPARCState, tl));
-                                    dc->npc = DYNAMIC_PC;
-                                }
+                                save_state(dc);
+                                tcg_gen_trunc_tl_i32(cpu_tmp32, cpu_tmp0);
+                                tcg_gen_st_i32(cpu_tmp32, cpu_env,
+                                               offsetof(CPUSPARCState, tl));
+                                dc->npc = DYNAMIC_PC;
                                 break;
                             case 8: // pil
                                 gen_helper_wrpil(cpu_env, cpu_tmp0);
commit 96b5a3d3cf49d27e6da7ceac683a1b38d122e6fa
Author: Richard Henderson <rth at twiddle.net>
Date:   Tue Oct 9 14:49:58 2012 -0700

    target-sparc: Optimize CC_OP_LOGIC conditions
    
    Signed-off-by: Richard Henderson <rth at twiddle.net>
    Signed-off-by: Blue Swirl <blauwirbel at gmail.com>

diff --git a/target-sparc/translate.c b/target-sparc/translate.c
index 71b9d65..4409f69 100644
--- a/target-sparc/translate.c
+++ b/target-sparc/translate.c
@@ -1050,7 +1050,7 @@ static void gen_compare(DisasCompare *cmp, bool xcc, unsigned int cond,
                         DisasContext *dc)
 {
     static int subcc_cond[16] = {
-        -1, /* never */
+        TCG_COND_NEVER,
         TCG_COND_EQ,
         TCG_COND_LE,
         TCG_COND_LT,
@@ -1058,7 +1058,7 @@ static void gen_compare(DisasCompare *cmp, bool xcc, unsigned int cond,
         TCG_COND_LTU,
         -1, /* neg */
         -1, /* overflow */
-        -1, /* always */
+        TCG_COND_ALWAYS,
         TCG_COND_NE,
         TCG_COND_GT,
         TCG_COND_GE,
@@ -1068,6 +1068,25 @@ static void gen_compare(DisasCompare *cmp, bool xcc, unsigned int cond,
         -1, /* no overflow */
     };
 
+    static int logic_cond[16] = {
+        TCG_COND_NEVER,
+        TCG_COND_EQ,     /* eq:  Z */
+        TCG_COND_LE,     /* le:  Z | (N ^ V) -> Z | N */
+        TCG_COND_LT,     /* lt:  N ^ V -> N */
+        TCG_COND_EQ,     /* leu: C | Z -> Z */
+        TCG_COND_NEVER,  /* ltu: C -> 0 */
+        TCG_COND_LT,     /* neg: N */
+        TCG_COND_NEVER,  /* vs:  V -> 0 */
+        TCG_COND_ALWAYS,
+        TCG_COND_NE,     /* ne:  !Z */
+        TCG_COND_GT,     /* gt:  !(Z | (N ^ V)) -> !(Z | N) */
+        TCG_COND_GE,     /* ge:  !(N ^ V) -> !N */
+        TCG_COND_NE,     /* gtu: !(C | Z) -> !Z */
+        TCG_COND_ALWAYS, /* geu: !C -> 1 */
+        TCG_COND_GE,     /* pos: !N */
+        TCG_COND_ALWAYS, /* vc:  !V -> 1 */
+    };
+
     TCGv_i32 r_src;
     TCGv r_dst;
 
@@ -1082,28 +1101,31 @@ static void gen_compare(DisasCompare *cmp, bool xcc, unsigned int cond,
 #endif
 
     switch (dc->cc_op) {
+    case CC_OP_LOGIC:
+        cmp->cond = logic_cond[cond];
+    do_compare_dst_0:
+        cmp->is_bool = false;
+        cmp->g2 = false;
+        cmp->c2 = tcg_const_tl(0);
+#ifdef TARGET_SPARC64
+        if (!xcc) {
+            cmp->g1 = false;
+            cmp->c1 = tcg_temp_new();
+            tcg_gen_ext32s_tl(cmp->c1, cpu_cc_dst);
+            break;
+        }
+#endif
+        cmp->g1 = true;
+        cmp->c1 = cpu_cc_dst;
+        break;
+
     case CC_OP_SUB:
         switch (cond) {
         case 6:  /* neg */
         case 14: /* pos */
             cmp->cond = (cond == 6 ? TCG_COND_LT : TCG_COND_GE);
-            cmp->is_bool = false;
-            cmp->g2 = false;
-            cmp->c2 = tcg_const_tl(0);
-#ifdef TARGET_SPARC64
-            if (!xcc) {
-                cmp->g1 = false;
-                cmp->c1 = tcg_temp_new();
-                tcg_gen_ext32s_tl(cmp->c1, cpu_cc_dst);
-                break;
-            }
-#endif
-            cmp->g1 = true;
-            cmp->c1 = cpu_cc_dst;
-            break;
+            goto do_compare_dst_0;
 
-        case 0: /* never */
-        case 8: /* always */
         case 7: /* overflow */
         case 15: /* !overflow */
             goto do_dynamic;
commit 0fa2a0660c7516d13bc149ff9a3b417e9778137e
Author: Richard Henderson <rth at twiddle.net>
Date:   Tue Oct 9 14:49:57 2012 -0700

    target-sparc: Fix optimized %icc comparisons
    
    Signed-off-by: Richard Henderson <rth at twiddle.net>
    Tested-by: Aurelien Jarno <aurelien at aurel32.net>
    Signed-off-by: Blue Swirl <blauwirbel at gmail.com>

diff --git a/target-sparc/translate.c b/target-sparc/translate.c
index 472eb51..71b9d65 100644
--- a/target-sparc/translate.c
+++ b/target-sparc/translate.c
@@ -1120,6 +1120,7 @@ static void gen_compare(DisasCompare *cmp, bool xcc, unsigned int cond,
                 cmp->c2 = tcg_temp_new();
                 tcg_gen_ext32s_tl(cmp->c1, cpu_cc_src);
                 tcg_gen_ext32s_tl(cmp->c2, cpu_cc_src2);
+                break;
             }
 #endif
             cmp->g1 = cmp->g2 = true;
commit ae72f3f5391cc761665824eeea542d3c5ad7ca67
Merge: 5d9619a... fae1528...
Author: Anthony Liguori <aliguori at us.ibm.com>
Date:   Fri Oct 12 11:20:14 2012 -0500

    Merge remote-tracking branch 'pmaydell/arm-devs.for-upstream' into staging
    
    * pmaydell/arm-devs.for-upstream:
      arm_gic: Rename gic_state to GICState
      zynq_slcr: Fixed ResetValues enum
      versatilepb: add gpio pl061 support
      hw/ds1338: Implement state save/restore
      hw/ds1338: Remove 'now' field from state struct
      hw/ds1338: Recapture current time when register pointer wraps around
      hw/ds1338: Fix mishandling of register pointer
      hw/arm_gic.c: Fix improper DPRINTF output.
      cadence_ttc: Fix 'clear on read' behavior

commit 5d9619aa1fc348fe8894553c15c1ec886fa33939
Merge: 628cc97... 417b0b8...
Author: Anthony Liguori <aliguori at us.ibm.com>
Date:   Fri Oct 12 11:19:56 2012 -0500

    Merge remote-tracking branch 'stefanha/trivial-patches' into staging
    
    * stefanha/trivial-patches:
      vnc: fix "info vnc" with "-vnc ..., reverse=on"
      sheepdog: use bool for boolean variables
      configure: Tidy up remnants of non-64-bit physaddrs

commit 628cc97df70476c9e1f30791dcfb70511bb1ebdd
Merge: 453162e... 883bca7...
Author: Anthony Liguori <aliguori at us.ibm.com>
Date:   Fri Oct 12 09:14:32 2012 -0500

    Merge remote-tracking branch 'kraxel/usb.67' into staging
    
    * kraxel/usb.67:
      uhci: Raise interrupt when requested even for non active tds
      usb-redir: Don't make migration fail in none seamless case
      usb-redir: Change usbredir_open_chardev into usbredir_create_parser

commit 453162e132023b319a23e6d7d25f51ba498105a7
Merge: 557e01a... 9d6f1b7...
Author: Anthony Liguori <aliguori at us.ibm.com>
Date:   Fri Oct 12 09:14:23 2012 -0500

    Merge remote-tracking branch 'mdroth/qga-pull-10-9-12' into staging
    
    * mdroth/qga-pull-10-9-12:
      qemu-ga: ga_open_pidfile(): add new line to pidfile
      qemu-ga: use state dir from CONFIG_QEMU_LOCALSTATEDIR
      configure: add --localstatedir

commit 557e01a3f9956ba53f804a7394dc1ff2a9540109
Merge: 4336ef7... 3a4f281...
Author: Anthony Liguori <aliguori at us.ibm.com>
Date:   Fri Oct 12 09:14:14 2012 -0500

    Merge remote-tracking branch 'awilliam/tags/vfio-pci-for-qemu-20121008.0' into staging
    
    * awilliam/tags/vfio-pci-for-qemu-20121008.0:
      vfio-pci: Fix BAR->VFIODevice translation in
      vfio-pci: Clang cleanup
      vfio-pci: Cleanup on INTx setup failure
      vfio-pci: Extend reset
      vfio-pci: Remove setting of MSI qsize
      vfio-pci: Use uintptr_t for void* cast
      vfio-pci: Don't peak at msi_supported
      vfio-pci: Roll the header into the .c file
      vfio-pci: No spurious MSIs
      vfio-pci: Rework MSIX setup/teardown
      vfio-pci: Unmap and retry DMA mapping
      vfio-pci: Re-order map/unmap
      vfio-pci: Update slow path INTx algorithm

commit 4336ef7a55751c867422c0df9f42877c5661c278
Merge: 3f42ac8... a245fc1...
Author: Anthony Liguori <aliguori at us.ibm.com>
Date:   Fri Oct 12 09:14:04 2012 -0500

    Merge remote-tracking branch 'stefanha/net' into staging
    
    * stefanha/net:
      net: consolidate NetClientState header files into one
      virtio-net: update nc.link_down in virtio_net_load()
      e1000: update nc.link_down in e1000_post_load()
      rtl8139: implement 8139cp link status

commit 3f42ac89ba7197872c1bc6ddc850184fc83622a0
Merge: b4ae3cf... 591af14...
Author: Anthony Liguori <aliguori at us.ibm.com>
Date:   Fri Oct 12 09:13:58 2012 -0500

    Merge remote-tracking branch 'spice/spice.v61' into staging
    
    * spice/spice.v61:
      qxl: set default revision to 4
      spice: raise requirement to 0.12
      hw/qxl: qxl_dirty_surfaces: use uintptr_t
      hw/qxl: fix condition for exiting guest_bug
      hw/qxl: exit on failure to register qxl interface
      qxl: fix range check for rev3 io commands.
      qxl/update_area_io: cleanup invalid parameters handling
      qxl: always update displaysurface on resize

commit fae15286751d8a8209724b14b62d065f1111e621
Author: Peter Maydell <peter.maydell at linaro.org>
Date:   Fri Oct 12 11:54:39 2012 +0100

    arm_gic: Rename gic_state to GICState
    
    Rename the gic_state struct to match QEMU's coding style conventions
    for structure names, since the impending KVM-for-ARM patches will
    create another subclass of it. This patch was created using:
      sed -i 's/gic_state/GICState/g' hw/arm_gic.c hw/arm_gic_common.c \
        hw/arm_gic_internal.h hw/armv7m_nvic.c
    
    Acked-by: Andreas Färber <afaerber at suse.de>
    Signed-off-by: Peter Maydell <peter.maydell at linaro.org>

diff --git a/hw/arm_gic.c b/hw/arm_gic.c
index 4024dae..56376c0 100644
--- a/hw/arm_gic.c
+++ b/hw/arm_gic.c
@@ -36,7 +36,7 @@ static const uint8_t gic_id[] = {
 
 #define NUM_CPU(s) ((s)->num_cpu)
 
-static inline int gic_get_current_cpu(gic_state *s)
+static inline int gic_get_current_cpu(GICState *s)
 {
     if (s->num_cpu > 1) {
         return cpu_single_env->cpu_index;
@@ -46,7 +46,7 @@ static inline int gic_get_current_cpu(gic_state *s)
 
 /* TODO: Many places that call this routine could be optimized.  */
 /* Update interrupt status after enabled or pending bits have been changed.  */
-void gic_update(gic_state *s)
+void gic_update(GICState *s)
 {
     int best_irq;
     int best_prio;
@@ -84,7 +84,7 @@ void gic_update(gic_state *s)
     }
 }
 
-void gic_set_pending_private(gic_state *s, int cpu, int irq)
+void gic_set_pending_private(GICState *s, int cpu, int irq)
 {
     int cm = 1 << cpu;
 
@@ -105,7 +105,7 @@ static void gic_set_irq(void *opaque, int irq, int level)
      *  [N+32..N+63] : PPI (internal interrupts for CPU 1
      *  ...
      */
-    gic_state *s = (gic_state *)opaque;
+    GICState *s = (GICState *)opaque;
     int cm, target;
     if (irq < (s->num_irq - GIC_INTERNAL)) {
         /* The first external input line is internal interrupt 32.  */
@@ -137,7 +137,7 @@ static void gic_set_irq(void *opaque, int irq, int level)
     gic_update(s);
 }
 
-static void gic_set_running_irq(gic_state *s, int cpu, int irq)
+static void gic_set_running_irq(GICState *s, int cpu, int irq)
 {
     s->running_irq[cpu] = irq;
     if (irq == 1023) {
@@ -148,7 +148,7 @@ static void gic_set_running_irq(gic_state *s, int cpu, int irq)
     gic_update(s);
 }
 
-uint32_t gic_acknowledge_irq(gic_state *s, int cpu)
+uint32_t gic_acknowledge_irq(GICState *s, int cpu)
 {
     int new_irq;
     int cm = 1 << cpu;
@@ -167,7 +167,7 @@ uint32_t gic_acknowledge_irq(gic_state *s, int cpu)
     return new_irq;
 }
 
-void gic_complete_irq(gic_state *s, int cpu, int irq)
+void gic_complete_irq(GICState *s, int cpu, int irq)
 {
     int update = 0;
     int cm = 1 << cpu;
@@ -214,7 +214,7 @@ void gic_complete_irq(gic_state *s, int cpu, int irq)
 
 static uint32_t gic_dist_readb(void *opaque, target_phys_addr_t offset)
 {
-    gic_state *s = (gic_state *)opaque;
+    GICState *s = (GICState *)opaque;
     uint32_t res;
     int irq;
     int i;
@@ -347,7 +347,7 @@ static uint32_t gic_dist_readl(void *opaque, target_phys_addr_t offset)
 static void gic_dist_writeb(void *opaque, target_phys_addr_t offset,
                             uint32_t value)
 {
-    gic_state *s = (gic_state *)opaque;
+    GICState *s = (GICState *)opaque;
     int irq;
     int i;
     int cpu;
@@ -500,7 +500,7 @@ static void gic_dist_writew(void *opaque, target_phys_addr_t offset,
 static void gic_dist_writel(void *opaque, target_phys_addr_t offset,
                             uint32_t value)
 {
-    gic_state *s = (gic_state *)opaque;
+    GICState *s = (GICState *)opaque;
     if (offset == 0xf00) {
         int cpu;
         int irq;
@@ -539,7 +539,7 @@ static const MemoryRegionOps gic_dist_ops = {
     .endianness = DEVICE_NATIVE_ENDIAN,
 };
 
-static uint32_t gic_cpu_read(gic_state *s, int cpu, int offset)
+static uint32_t gic_cpu_read(GICState *s, int cpu, int offset)
 {
     switch (offset) {
     case 0x00: /* Control */
@@ -561,7 +561,7 @@ static uint32_t gic_cpu_read(gic_state *s, int cpu, int offset)
     }
 }
 
-static void gic_cpu_write(gic_state *s, int cpu, int offset, uint32_t value)
+static void gic_cpu_write(GICState *s, int cpu, int offset, uint32_t value)
 {
     switch (offset) {
     case 0x00: /* Control */
@@ -587,25 +587,25 @@ static void gic_cpu_write(gic_state *s, int cpu, int offset, uint32_t value)
 static uint64_t gic_thiscpu_read(void *opaque, target_phys_addr_t addr,
                                  unsigned size)
 {
-    gic_state *s = (gic_state *)opaque;
+    GICState *s = (GICState *)opaque;
     return gic_cpu_read(s, gic_get_current_cpu(s), addr);
 }
 
 static void gic_thiscpu_write(void *opaque, target_phys_addr_t addr,
                               uint64_t value, unsigned size)
 {
-    gic_state *s = (gic_state *)opaque;
+    GICState *s = (GICState *)opaque;
     gic_cpu_write(s, gic_get_current_cpu(s), addr, value);
 }
 
 /* Wrappers to read/write the GIC CPU interface for a specific CPU.
- * These just decode the opaque pointer into gic_state* + cpu id.
+ * These just decode the opaque pointer into GICState* + cpu id.
  */
 static uint64_t gic_do_cpu_read(void *opaque, target_phys_addr_t addr,
                                 unsigned size)
 {
-    gic_state **backref = (gic_state **)opaque;
-    gic_state *s = *backref;
+    GICState **backref = (GICState **)opaque;
+    GICState *s = *backref;
     int id = (backref - s->backref);
     return gic_cpu_read(s, id, addr);
 }
@@ -613,8 +613,8 @@ static uint64_t gic_do_cpu_read(void *opaque, target_phys_addr_t addr,
 static void gic_do_cpu_write(void *opaque, target_phys_addr_t addr,
                              uint64_t value, unsigned size)
 {
-    gic_state **backref = (gic_state **)opaque;
-    gic_state *s = *backref;
+    GICState **backref = (GICState **)opaque;
+    GICState *s = *backref;
     int id = (backref - s->backref);
     gic_cpu_write(s, id, addr, value);
 }
@@ -631,7 +631,7 @@ static const MemoryRegionOps gic_cpu_ops = {
     .endianness = DEVICE_NATIVE_ENDIAN,
 };
 
-void gic_init_irqs_and_distributor(gic_state *s, int num_irq)
+void gic_init_irqs_and_distributor(GICState *s, int num_irq)
 {
     int i;
 
@@ -657,7 +657,7 @@ static int arm_gic_init(SysBusDevice *dev)
 {
     /* Device instance init function for the GIC sysbus device */
     int i;
-    gic_state *s = FROM_SYSBUS(gic_state, dev);
+    GICState *s = FROM_SYSBUS(GICState, dev);
     ARMGICClass *agc = ARM_GIC_GET_CLASS(s);
 
     agc->parent_init(dev);
@@ -701,7 +701,7 @@ static void arm_gic_class_init(ObjectClass *klass, void *data)
 static TypeInfo arm_gic_info = {
     .name = TYPE_ARM_GIC,
     .parent = TYPE_ARM_GIC_COMMON,
-    .instance_size = sizeof(gic_state),
+    .instance_size = sizeof(GICState),
     .class_init = arm_gic_class_init,
     .class_size = sizeof(ARMGICClass),
 };
diff --git a/hw/arm_gic_common.c b/hw/arm_gic_common.c
index 360e782..8369309 100644
--- a/hw/arm_gic_common.c
+++ b/hw/arm_gic_common.c
@@ -22,7 +22,7 @@
 
 static void gic_save(QEMUFile *f, void *opaque)
 {
-    gic_state *s = (gic_state *)opaque;
+    GICState *s = (GICState *)opaque;
     int i;
     int j;
 
@@ -56,7 +56,7 @@ static void gic_save(QEMUFile *f, void *opaque)
 
 static int gic_load(QEMUFile *f, void *opaque, int version_id)
 {
-    gic_state *s = (gic_state *)opaque;
+    GICState *s = (GICState *)opaque;
     int i;
     int j;
 
@@ -96,7 +96,7 @@ static int gic_load(QEMUFile *f, void *opaque, int version_id)
 
 static int arm_gic_common_init(SysBusDevice *dev)
 {
-    gic_state *s = FROM_SYSBUS(gic_state, dev);
+    GICState *s = FROM_SYSBUS(GICState, dev);
     int num_irq = s->num_irq;
 
     if (s->num_cpu > NCPU) {
@@ -123,7 +123,7 @@ static int arm_gic_common_init(SysBusDevice *dev)
 
 static void arm_gic_common_reset(DeviceState *dev)
 {
-    gic_state *s = FROM_SYSBUS(gic_state, sysbus_from_qdev(dev));
+    GICState *s = FROM_SYSBUS(GICState, sysbus_from_qdev(dev));
     int i;
     memset(s->irq_state, 0, GIC_MAXIRQ * sizeof(gic_irq_state));
     for (i = 0 ; i < s->num_cpu; i++) {
@@ -147,13 +147,13 @@ static void arm_gic_common_reset(DeviceState *dev)
 }
 
 static Property arm_gic_common_properties[] = {
-    DEFINE_PROP_UINT32("num-cpu", gic_state, num_cpu, 1),
-    DEFINE_PROP_UINT32("num-irq", gic_state, num_irq, 32),
+    DEFINE_PROP_UINT32("num-cpu", GICState, num_cpu, 1),
+    DEFINE_PROP_UINT32("num-irq", GICState, num_irq, 32),
     /* Revision can be 1 or 2 for GIC architecture specification
      * versions 1 or 2, or 0 to indicate the legacy 11MPCore GIC.
      * (Internally, 0xffffffff also indicates "not a GIC but an NVIC".)
      */
-    DEFINE_PROP_UINT32("revision", gic_state, revision, 1),
+    DEFINE_PROP_UINT32("revision", GICState, revision, 1),
     DEFINE_PROP_END_OF_LIST(),
 };
 
@@ -170,7 +170,7 @@ static void arm_gic_common_class_init(ObjectClass *klass, void *data)
 static TypeInfo arm_gic_common_type = {
     .name = TYPE_ARM_GIC_COMMON,
     .parent = TYPE_SYS_BUS_DEVICE,
-    .instance_size = sizeof(gic_state),
+    .instance_size = sizeof(GICState),
     .class_size = sizeof(ARMGICCommonClass),
     .class_init = arm_gic_common_class_init,
     .abstract = true,
diff --git a/hw/arm_gic_internal.h b/hw/arm_gic_internal.h
index db4fad5..699352c 100644
--- a/hw/arm_gic_internal.h
+++ b/hw/arm_gic_internal.h
@@ -69,7 +69,7 @@ typedef struct gic_irq_state {
     unsigned trigger:1; /* nonzero = edge triggered.  */
 } gic_irq_state;
 
-typedef struct gic_state {
+typedef struct GICState {
     SysBusDevice busdev;
     qemu_irq parent_irq[NCPU];
     int enabled;
@@ -92,25 +92,25 @@ typedef struct gic_state {
     /* This is just so we can have an opaque pointer which identifies
      * both this GIC and which CPU interface we should be accessing.
      */
-    struct gic_state *backref[NCPU];
+    struct GICState *backref[NCPU];
     MemoryRegion cpuiomem[NCPU+1]; /* CPU interfaces */
     uint32_t num_irq;
     uint32_t revision;
-} gic_state;
+} GICState;
 
 /* The special cases for the revision property: */
 #define REV_11MPCORE 0
 #define REV_NVIC 0xffffffff
 
-void gic_set_pending_private(gic_state *s, int cpu, int irq);
-uint32_t gic_acknowledge_irq(gic_state *s, int cpu);
-void gic_complete_irq(gic_state *s, int cpu, int irq);
-void gic_update(gic_state *s);
-void gic_init_irqs_and_distributor(gic_state *s, int num_irq);
+void gic_set_pending_private(GICState *s, int cpu, int irq);
+uint32_t gic_acknowledge_irq(GICState *s, int cpu);
+void gic_complete_irq(GICState *s, int cpu, int irq);
+void gic_update(GICState *s);
+void gic_init_irqs_and_distributor(GICState *s, int num_irq);
 
 #define TYPE_ARM_GIC_COMMON "arm_gic_common"
 #define ARM_GIC_COMMON(obj) \
-     OBJECT_CHECK(gic_state, (obj), TYPE_ARM_GIC_COMMON)
+     OBJECT_CHECK(GICState, (obj), TYPE_ARM_GIC_COMMON)
 #define ARM_GIC_COMMON_CLASS(klass) \
      OBJECT_CLASS_CHECK(ARMGICCommonClass, (klass), TYPE_ARM_GIC_COMMON)
 #define ARM_GIC_COMMON_GET_CLASS(obj) \
@@ -122,7 +122,7 @@ typedef struct ARMGICCommonClass {
 
 #define TYPE_ARM_GIC "arm_gic"
 #define ARM_GIC(obj) \
-     OBJECT_CHECK(gic_state, (obj), TYPE_ARM_GIC)
+     OBJECT_CHECK(GICState, (obj), TYPE_ARM_GIC)
 #define ARM_GIC_CLASS(klass) \
      OBJECT_CLASS_CHECK(ARMGICClass, (klass), TYPE_ARM_GIC)
 #define ARM_GIC_GET_CLASS(obj) \
diff --git a/hw/armv7m_nvic.c b/hw/armv7m_nvic.c
index 5c09116..c449e08 100644
--- a/hw/armv7m_nvic.c
+++ b/hw/armv7m_nvic.c
@@ -17,7 +17,7 @@
 #include "arm_gic_internal.h"
 
 typedef struct {
-    gic_state gic;
+    GICState gic;
     struct {
         uint32_t control;
         uint32_t reload;
@@ -505,9 +505,9 @@ static void armv7m_nvic_instance_init(Object *obj)
      * than our superclass. This function runs after qdev init
      * has set the defaults from the Property array and before
      * any user-specified property setting, so just modify the
-     * value in the gic_state struct.
+     * value in the GICState struct.
      */
-    gic_state *s = ARM_GIC_COMMON(obj);
+    GICState *s = ARM_GIC_COMMON(obj);
     /* The ARM v7m may have anything from 0 to 496 external interrupt
      * IRQ lines. We default to 64. Other boards may differ and should
      * set the num-irq property appropriately.
commit fa2ddcb4f5f33c07c68cec67615c88a98fab02de
Author: Peter A. G. Crosthwaite <peter.crosthwaite at petalogix.com>
Date:   Fri Oct 12 11:54:39 2012 +0100

    zynq_slcr: Fixed ResetValues enum
    
    There is a gap in the reset region of the address space at offset 0x208. This
    throws out all these enum values by one when translating them to address offsets.
    Fixed by putting the corresponding gap in the enum as well.
    
    Signed-off-by: Peter A. G. Crosthwaite <peter.crosthwaite at petalogix.com>
    Reviewed-by: Peter Maydell <peter.maydell at linaro.org>
    Signed-off-by: Peter Maydell <peter.maydell at linaro.org>

diff --git a/hw/zynq_slcr.c b/hw/zynq_slcr.c
index 4f97575..8acba01 100644
--- a/hw/zynq_slcr.c
+++ b/hw/zynq_slcr.c
@@ -91,7 +91,7 @@ typedef enum {
 typedef enum {
   PSS,
   DDDR,
-  DMAC,
+  DMAC = 3,
   USB,
   GEM,
   SDIO,
commit 853e65e0b45403477c8a89afdb4c0abd4c3f97da
Author: Jean-Christophe PLAGNIOL-VILLARD <plagnioj at jcrosoft.com>
Date:   Fri Oct 12 11:54:39 2012 +0100

    versatilepb: add gpio pl061 support
    
    Signed-off-by: Jean-Christophe PLAGNIOL-VILLARD <plagnioj at jcrosoft.com>
    Signed-off-by: Peter Maydell <peter.maydell at linaro.org>

diff --git a/hw/versatilepb.c b/hw/versatilepb.c
index b3f8077..7b1b025 100644
--- a/hw/versatilepb.c
+++ b/hw/versatilepb.c
@@ -266,6 +266,11 @@ static void versatile_init(ram_addr_t ram_size,
     sysbus_create_simple("sp804", 0x101e2000, pic[4]);
     sysbus_create_simple("sp804", 0x101e3000, pic[5]);
 
+    sysbus_create_simple("pl061", 0x101e4000, pic[6]);
+    sysbus_create_simple("pl061", 0x101e5000, pic[7]);
+    sysbus_create_simple("pl061", 0x101e6000, pic[8]);
+    sysbus_create_simple("pl061", 0x101e7000, pic[9]);
+
     /* The versatile/PB actually has a modified Color LCD controller
        that includes hardware cursor support from the PL111.  */
     dev = sysbus_create_simple("pl110_versatile", 0x10120000, pic[16]);
commit f4741402ab8afe9014b6a54aed4cb0423041dbcb
Author: Peter Maydell <peter.maydell at linaro.org>
Date:   Fri Oct 12 11:54:38 2012 +0100

    hw/ds1338: Implement state save/restore
    
    Implement state save/restore for the DS1338. This requires
    the usual minor adjustment of types in the state struct to
    get fixed-width ones with vmstate macros.
    
    Signed-off-by: Peter Maydell <peter.maydell at linaro.org>

diff --git a/hw/ds1338.c b/hw/ds1338.c
index 16aba4b..b576d56 100644
--- a/hw/ds1338.c
+++ b/hw/ds1338.c
@@ -19,12 +19,27 @@
 
 typedef struct {
     I2CSlave i2c;
-    time_t offset;
+    int64_t offset;
     uint8_t nvram[NVRAM_SIZE];
-    int ptr;
-    int addr_byte;
+    int32_t ptr;
+    bool addr_byte;
 } DS1338State;
 
+static const VMStateDescription vmstate_ds1338 = {
+    .name = "ds1338",
+    .version_id = 1,
+    .minimum_version_id = 1,
+    .minimum_version_id_old = 1,
+    .fields = (VMStateField[]) {
+        VMSTATE_I2C_SLAVE(i2c, DS1338State),
+        VMSTATE_INT64(offset, DS1338State),
+        VMSTATE_UINT8_ARRAY(nvram, DS1338State, NVRAM_SIZE),
+        VMSTATE_INT32(ptr, DS1338State),
+        VMSTATE_BOOL(addr_byte, DS1338State),
+        VMSTATE_END_OF_LIST()
+    }
+};
+
 static void capture_current_time(DS1338State *s)
 {
     /* Capture the current time into the secondary registers
@@ -74,7 +89,7 @@ static void ds1338_event(I2CSlave *i2c, enum i2c_event event)
         capture_current_time(s);
         break;
     case I2C_START_SEND:
-        s->addr_byte = 1;
+        s->addr_byte = true;
         break;
     default:
         break;
@@ -96,7 +111,7 @@ static int ds1338_send(I2CSlave *i2c, uint8_t data)
     DS1338State *s = FROM_I2C_SLAVE(DS1338State, i2c);
     if (s->addr_byte) {
         s->ptr = data & (NVRAM_SIZE - 1);
-        s->addr_byte = 0;
+        s->addr_byte = false;
         return 0;
     }
     if (s->ptr < 8) {
@@ -153,12 +168,14 @@ static int ds1338_init(I2CSlave *i2c)
 
 static void ds1338_class_init(ObjectClass *klass, void *data)
 {
+    DeviceClass *dc = DEVICE_CLASS(klass);
     I2CSlaveClass *k = I2C_SLAVE_CLASS(klass);
 
     k->init = ds1338_init;
     k->event = ds1338_event;
     k->recv = ds1338_recv;
     k->send = ds1338_send;
+    dc->vmsd = &vmstate_ds1338;
 }
 
 static TypeInfo ds1338_info = {
commit 7f7fd0f2e4d6b4f2ec137cda67f6c9a140668ea3
Author: Peter Maydell <peter.maydell at linaro.org>
Date:   Fri Oct 12 11:54:38 2012 +0100

    hw/ds1338: Remove 'now' field from state struct
    
    The 'struct tm now' field in the state structure is in fact only
    ever used as a temporary (the actual RTC state is held in 'offset').
    Remove it from the state structure in favour of using local variables
    to avoid confusion about whether it needs to be saved on migration.
    
    Signed-off-by: Peter Maydell <peter.maydell at linaro.org>

diff --git a/hw/ds1338.c b/hw/ds1338.c
index 842d2de..16aba4b 100644
--- a/hw/ds1338.c
+++ b/hw/ds1338.c
@@ -20,7 +20,6 @@
 typedef struct {
     I2CSlave i2c;
     time_t offset;
-    struct tm now;
     uint8_t nvram[NVRAM_SIZE];
     int ptr;
     int addr_byte;
@@ -31,21 +30,22 @@ static void capture_current_time(DS1338State *s)
     /* Capture the current time into the secondary registers
      * which will be actually read by the data transfer operation.
      */
-    qemu_get_timedate(&s->now, s->offset);
-    s->nvram[0] = to_bcd(s->now.tm_sec);
-    s->nvram[1] = to_bcd(s->now.tm_min);
+    struct tm now;
+    qemu_get_timedate(&now, s->offset);
+    s->nvram[0] = to_bcd(now.tm_sec);
+    s->nvram[1] = to_bcd(now.tm_min);
     if (s->nvram[2] & 0x40) {
-        s->nvram[2] = (to_bcd((s->now.tm_hour % 12)) + 1) | 0x40;
-        if (s->now.tm_hour >= 12) {
+        s->nvram[2] = (to_bcd((now.tm_hour % 12)) + 1) | 0x40;
+        if (now.tm_hour >= 12) {
             s->nvram[2] |= 0x20;
         }
     } else {
-        s->nvram[2] = to_bcd(s->now.tm_hour);
+        s->nvram[2] = to_bcd(now.tm_hour);
     }
-    s->nvram[3] = to_bcd(s->now.tm_wday) + 1;
-    s->nvram[4] = to_bcd(s->now.tm_mday);
-    s->nvram[5] = to_bcd(s->now.tm_mon) + 1;
-    s->nvram[6] = to_bcd(s->now.tm_year - 100);
+    s->nvram[3] = to_bcd(now.tm_wday) + 1;
+    s->nvram[4] = to_bcd(now.tm_mday);
+    s->nvram[5] = to_bcd(now.tm_mon) + 1;
+    s->nvram[6] = to_bcd(now.tm_year - 100);
 }
 
 static void inc_regptr(DS1338State *s)
@@ -100,14 +100,15 @@ static int ds1338_send(I2CSlave *i2c, uint8_t data)
         return 0;
     }
     if (s->ptr < 8) {
-        qemu_get_timedate(&s->now, s->offset);
+        struct tm now;
+        qemu_get_timedate(&now, s->offset);
         switch(s->ptr) {
         case 0:
             /* TODO: Implement CH (stop) bit.  */
-            s->now.tm_sec = from_bcd(data & 0x7f);
+            now.tm_sec = from_bcd(data & 0x7f);
             break;
         case 1:
-            s->now.tm_min = from_bcd(data & 0x7f);
+            now.tm_min = from_bcd(data & 0x7f);
             break;
         case 2:
             if (data & 0x40) {
@@ -119,25 +120,25 @@ static int ds1338_send(I2CSlave *i2c, uint8_t data)
             } else {
                 data = from_bcd(data);
             }
-            s->now.tm_hour = data;
+            now.tm_hour = data;
             break;
         case 3:
-            s->now.tm_wday = from_bcd(data & 7) - 1;
+            now.tm_wday = from_bcd(data & 7) - 1;
             break;
         case 4:
-            s->now.tm_mday = from_bcd(data & 0x3f);
+            now.tm_mday = from_bcd(data & 0x3f);
             break;
         case 5:
-            s->now.tm_mon = from_bcd(data & 0x1f) - 1;
+            now.tm_mon = from_bcd(data & 0x1f) - 1;
             break;
         case 6:
-            s->now.tm_year = from_bcd(data) + 100;
+            now.tm_year = from_bcd(data) + 100;
             break;
         case 7:
             /* Control register. Currently ignored.  */
             break;
         }
-        s->offset = qemu_timedate_diff(&s->now);
+        s->offset = qemu_timedate_diff(&now);
     } else {
         s->nvram[s->ptr] = data;
     }
commit 35b87a861394ed088c4db3b7ba9a67d8bb2b289e
Author: Peter Maydell <peter.maydell at linaro.org>
Date:   Fri Oct 12 11:54:38 2012 +0100

    hw/ds1338: Recapture current time when register pointer wraps around
    
    The DS1338 datasheet documents that the current time is captured into
    the secondary registers when the register pointer wraps round to zero
    as well as at a START condition. Implement this.
    
    Signed-off-by: Peter Maydell <peter.maydell at linaro.org>

diff --git a/hw/ds1338.c b/hw/ds1338.c
index be68140..842d2de 100644
--- a/hw/ds1338.c
+++ b/hw/ds1338.c
@@ -26,27 +26,52 @@ typedef struct {
     int addr_byte;
 } DS1338State;
 
+static void capture_current_time(DS1338State *s)
+{
+    /* Capture the current time into the secondary registers
+     * which will be actually read by the data transfer operation.
+     */
+    qemu_get_timedate(&s->now, s->offset);
+    s->nvram[0] = to_bcd(s->now.tm_sec);
+    s->nvram[1] = to_bcd(s->now.tm_min);
+    if (s->nvram[2] & 0x40) {
+        s->nvram[2] = (to_bcd((s->now.tm_hour % 12)) + 1) | 0x40;
+        if (s->now.tm_hour >= 12) {
+            s->nvram[2] |= 0x20;
+        }
+    } else {
+        s->nvram[2] = to_bcd(s->now.tm_hour);
+    }
+    s->nvram[3] = to_bcd(s->now.tm_wday) + 1;
+    s->nvram[4] = to_bcd(s->now.tm_mday);
+    s->nvram[5] = to_bcd(s->now.tm_mon) + 1;
+    s->nvram[6] = to_bcd(s->now.tm_year - 100);
+}
+
+static void inc_regptr(DS1338State *s)
+{
+    /* The register pointer wraps around after 0x3F; wraparound
+     * causes the current time/date to be retransferred into
+     * the secondary registers.
+     */
+    s->ptr = (s->ptr + 1) & (NVRAM_SIZE - 1);
+    if (!s->ptr) {
+        capture_current_time(s);
+    }
+}
+
 static void ds1338_event(I2CSlave *i2c, enum i2c_event event)
 {
     DS1338State *s = FROM_I2C_SLAVE(DS1338State, i2c);
 
     switch (event) {
     case I2C_START_RECV:
-        qemu_get_timedate(&s->now, s->offset);
-        s->nvram[0] = to_bcd(s->now.tm_sec);
-        s->nvram[1] = to_bcd(s->now.tm_min);
-        if (s->nvram[2] & 0x40) {
-            s->nvram[2] = (to_bcd((s->now.tm_hour % 12)) + 1) | 0x40;
-            if (s->now.tm_hour >= 12) {
-                s->nvram[2] |= 0x20;
-            }
-        } else {
-            s->nvram[2] = to_bcd(s->now.tm_hour);
-        }
-        s->nvram[3] = to_bcd(s->now.tm_wday) + 1;
-        s->nvram[4] = to_bcd(s->now.tm_mday);
-        s->nvram[5] = to_bcd(s->now.tm_mon) + 1;
-        s->nvram[6] = to_bcd(s->now.tm_year - 100);
+        /* In h/w, capture happens on any START condition, not just a
+         * START_RECV, but there is no need to actually capture on
+         * START_SEND, because the guest can't get at that data
+         * without going through a START_RECV which would overwrite it.
+         */
+        capture_current_time(s);
         break;
     case I2C_START_SEND:
         s->addr_byte = 1;
@@ -62,7 +87,7 @@ static int ds1338_recv(I2CSlave *i2c)
     uint8_t res;
 
     res  = s->nvram[s->ptr];
-    s->ptr = (s->ptr + 1) & (NVRAM_SIZE - 1);
+    inc_regptr(s);
     return res;
 }
 
@@ -116,7 +141,7 @@ static int ds1338_send(I2CSlave *i2c, uint8_t data)
     } else {
         s->nvram[s->ptr] = data;
     }
-    s->ptr = (s->ptr + 1) & (NVRAM_SIZE - 1);
+    inc_regptr(s);
     return 0;
 }
 
commit ba4906a9b64e165a958e12f6208ca834dc7a36dc
Author: Peter Maydell <peter.maydell at linaro.org>
Date:   Fri Oct 12 11:54:38 2012 +0100

    hw/ds1338: Fix mishandling of register pointer
    
    Correct several deficiencies in the handling of the register pointer:
     * it should wrap around after 0x3f, not 0xff
     * guard against the caller handing us an out of range pointer
       (on h/w this can never happen, because only a 7 bit value is
       transferred over the I2C bus)
     * there was confusion over whether nvram[] holds only the 56 bytes
       of guest-accessible NVRAM, or also the secondary registers
       which hold the value of the clock captured at the start of a
       multibyte read. Correct to consistently be the latter, by fixing
       the array size and the offset used for NVRAM writes.
     * ds1338_send was attempting to use 'data' as both the data and
       the register offset simultaneously, which meant that writes to
       any register were broken; fix to use the register pointer.
    
    Signed-off-by: Peter Maydell <peter.maydell at linaro.org>

diff --git a/hw/ds1338.c b/hw/ds1338.c
index d590d9c..be68140 100644
--- a/hw/ds1338.c
+++ b/hw/ds1338.c
@@ -12,11 +12,16 @@
 
 #include "i2c.h"
 
+/* Size of NVRAM including both the user-accessible area and the
+ * secondary register area.
+ */
+#define NVRAM_SIZE 64
+
 typedef struct {
     I2CSlave i2c;
     time_t offset;
     struct tm now;
-    uint8_t nvram[56];
+    uint8_t nvram[NVRAM_SIZE];
     int ptr;
     int addr_byte;
 } DS1338State;
@@ -57,7 +62,7 @@ static int ds1338_recv(I2CSlave *i2c)
     uint8_t res;
 
     res  = s->nvram[s->ptr];
-    s->ptr = (s->ptr + 1) & 0xff;
+    s->ptr = (s->ptr + 1) & (NVRAM_SIZE - 1);
     return res;
 }
 
@@ -65,14 +70,13 @@ static int ds1338_send(I2CSlave *i2c, uint8_t data)
 {
     DS1338State *s = FROM_I2C_SLAVE(DS1338State, i2c);
     if (s->addr_byte) {
-        s->ptr = data;
+        s->ptr = data & (NVRAM_SIZE - 1);
         s->addr_byte = 0;
         return 0;
     }
-    s->nvram[s->ptr - 8] = data;
-    if (data < 8) {
+    if (s->ptr < 8) {
         qemu_get_timedate(&s->now, s->offset);
-        switch(data) {
+        switch(s->ptr) {
         case 0:
             /* TODO: Implement CH (stop) bit.  */
             s->now.tm_sec = from_bcd(data & 0x7f);
@@ -109,8 +113,10 @@ static int ds1338_send(I2CSlave *i2c, uint8_t data)
             break;
         }
         s->offset = qemu_timedate_diff(&s->now);
+    } else {
+        s->nvram[s->ptr] = data;
     }
-    s->ptr = (s->ptr + 1) & 0xff;
+    s->ptr = (s->ptr + 1) & (NVRAM_SIZE - 1);
     return 0;
 }
 
commit 9ab1b6053f03d58ba8e7accc8f19c882fbffb66f
Author: Evgeny Voevodin <e.voevodin at samsung.com>
Date:   Fri Oct 12 11:54:37 2012 +0100

    hw/arm_gic.c: Fix improper DPRINTF output.
    
    s->cpu_enabled is an array, so s->cpu_enabled ? "En" : "Dis" returns
    "En" always. We should use s->cpu_enabled[cpu] here.
    
    Signed-off-by: Evgeny Voevodin <e.voevodin at samsung.com>
    Signed-off-by: Peter Maydell <peter.maydell at linaro.org>

diff --git a/hw/arm_gic.c b/hw/arm_gic.c
index 55871fa..4024dae 100644
--- a/hw/arm_gic.c
+++ b/hw/arm_gic.c
@@ -566,7 +566,7 @@ static void gic_cpu_write(gic_state *s, int cpu, int offset, uint32_t value)
     switch (offset) {
     case 0x00: /* Control */
         s->cpu_enabled[cpu] = (value & 1);
-        DPRINTF("CPU %d %sabled\n", cpu, s->cpu_enabled ? "En" : "Dis");
+        DPRINTF("CPU %d %sabled\n", cpu, s->cpu_enabled[cpu] ? "En" : "Dis");
         break;
     case 0x04: /* Priority mask */
         s->priority_mask[cpu] = (value & 0xff);
commit 884285bf646d93e9dfa4a605bca9f8dc5280b23d
Author: Soren Brinkmann <soren.brinkmann at xilinx.com>
Date:   Fri Oct 12 11:54:37 2012 +0100

    cadence_ttc: Fix 'clear on read' behavior
    
    A missing call to qemu_set_irq() when reading the IRQ register
    required SW to write to the IRQ register to acknowledge an
    interrupt. With this patch the behavior is fixed:
     - Reading the interrupt register clears it and updates the timers
       interrupt status
     - Writes to the interrupt register are ignored
    
    Signed-off-by: Soren Brinkmann <soren.brinkmann at xilinx.com>
    Signed-off-by: Peter Crosthwaite <peter.crosthwaite at xilinx.com>
    Signed-off-by: Peter Maydell <peter.maydell at linaro.org>

diff --git a/hw/cadence_ttc.c b/hw/cadence_ttc.c
index dd02f86..77b6976 100644
--- a/hw/cadence_ttc.c
+++ b/hw/cadence_ttc.c
@@ -274,6 +274,7 @@ static uint32_t cadence_ttc_read_imp(void *opaque, target_phys_addr_t offset)
         /* cleared after read */
         value = s->reg_intr;
         s->reg_intr = 0;
+        cadence_timer_update(s);
         return value;
 
     case 0x60: /* interrupt enable */
@@ -355,7 +356,6 @@ static void cadence_ttc_write(void *opaque, target_phys_addr_t offset,
     case 0x54: /* interrupt register */
     case 0x58:
     case 0x5c:
-        s->reg_intr &= (~value & 0xfff);
         break;
 
     case 0x60: /* interrupt enable */
commit 417b0b88904fe1dd8c41bff8092dfbab0134d9cb
Author: Paolo Bonzini <pbonzini at redhat.com>
Date:   Wed Oct 10 14:30:58 2012 +0200

    vnc: fix "info vnc" with "-vnc ..., reverse=on"
    
    When reverse connection is in use, there is no active VNC server
    socket.  Because of this, getsockopt(-1, ...) is attempted and
    the following error is emitted:
    
        $ socat TCP-LISTEN:5900,reuseaddr TCP-LISTEN:5901,reuseaddr &
        $ x86_64-softmmu/qemu-system-x86_64 -vnc localhost:5900,reverse -monitor stdio
        QEMU 1.2.50 monitor - type 'help' for more information
        (qemu) info vnc
        An undefined error has occurred
    
    Because however the host, family, service and auth fields are
    optional, we can just exit if there is no active server socket.
    
        $ x86_64-softmmu/qemu-system-x86_64 -vnc localhost:5900,reverse -monitor stdio
        QEMU 1.2.50 monitor - type 'help' for more information
        (qemu) info vnc
        Server:
        Client:
             address: 127.0.0.1:5900
          x509_dname: none
            username: none
    
    Signed-off-by: Paolo Bonzini <pbonzini at redhat.com>
    Signed-off-by: Stefan Hajnoczi <stefanha at redhat.com>

diff --git a/ui/vnc.c b/ui/vnc.c
index 01b2daf..33e6386 100644
--- a/ui/vnc.c
+++ b/ui/vnc.c
@@ -372,6 +372,10 @@ VncInfo *qmp_query_vnc(Error **errp)
             }
         }
 
+        if (vnc_display->lsock == -1) {
+            return info;
+        }
+
         if (getsockname(vnc_display->lsock, (struct sockaddr *)&sa,
                         &salen) == -1) {
             error_set(errp, QERR_UNDEFINED_ERROR);
commit 2f5368017f8a0c00e982c3e315acb332a0907792
Author: MORITA Kazutaka <morita.kazutaka at lab.ntt.co.jp>
Date:   Sun Oct 7 01:57:14 2012 +0900

    sheepdog: use bool for boolean variables
    
    This improves readability.
    
    Signed-off-by: MORITA Kazutaka <morita.kazutaka at lab.ntt.co.jp>
    Signed-off-by: Stefan Hajnoczi <stefanha at redhat.com>

diff --git a/block/sheepdog.c b/block/sheepdog.c
index f35ff5b..9306174 100644
--- a/block/sheepdog.c
+++ b/block/sheepdog.c
@@ -201,12 +201,12 @@ static inline uint64_t fnv_64a_buf(void *buf, size_t len, uint64_t hval)
     return hval;
 }
 
-static inline int is_data_obj_writable(SheepdogInode *inode, unsigned int idx)
+static inline bool is_data_obj_writable(SheepdogInode *inode, unsigned int idx)
 {
     return inode->vdi_id == inode->data_vdi_id[idx];
 }
 
-static inline int is_data_obj(uint64_t oid)
+static inline bool is_data_obj(uint64_t oid)
 {
     return !(VDI_BIT & oid);
 }
@@ -231,7 +231,7 @@ static inline uint64_t vid_to_data_oid(uint32_t vid, uint32_t idx)
     return ((uint64_t)vid << VDI_SPACE_SHIFT) | idx;
 }
 
-static inline int is_snapshot(struct SheepdogInode *inode)
+static inline bool is_snapshot(struct SheepdogInode *inode)
 {
     return !!inode->snap_ctime;
 }
@@ -281,7 +281,7 @@ struct SheepdogAIOCB {
     Coroutine *coroutine;
     void (*aio_done_func)(SheepdogAIOCB *);
 
-    int canceled;
+    bool canceled;
     int nr_pending;
 };
 
@@ -292,8 +292,8 @@ typedef struct BDRVSheepdogState {
     uint32_t max_dirty_data_idx;
 
     char name[SD_MAX_VDI_LEN];
-    int is_snapshot;
-    uint8_t cache_enabled;
+    bool is_snapshot;
+    bool cache_enabled;
 
     char *addr;
     char *port;
@@ -417,7 +417,7 @@ static void sd_aio_cancel(BlockDriverAIOCB *blockacb)
      */
     acb->ret = -EIO;
     qemu_coroutine_enter(acb->coroutine, NULL);
-    acb->canceled = 1;
+    acb->canceled = true;
 }
 
 static AIOPool sd_aio_pool = {
@@ -439,7 +439,7 @@ static SheepdogAIOCB *sd_aio_setup(BlockDriverState *bs, QEMUIOVector *qiov,
     acb->nb_sectors = nb_sectors;
 
     acb->aio_done_func = NULL;
-    acb->canceled = 0;
+    acb->canceled = false;
     acb->coroutine = qemu_coroutine_self();
     acb->ret = 0;
     acb->nr_pending = 0;
@@ -613,7 +613,7 @@ static int do_req(int sockfd, SheepdogReq *hdr, void *data,
 }
 
 static int coroutine_fn add_aio_request(BDRVSheepdogState *s, AIOReq *aio_req,
-                           struct iovec *iov, int niov, int create,
+                           struct iovec *iov, int niov, bool create,
                            enum AIOCBState aiocb_type);
 
 
@@ -646,7 +646,7 @@ static void coroutine_fn send_pending_req(BDRVSheepdogState *s, uint64_t oid)
         QLIST_REMOVE(aio_req, aio_siblings);
         QLIST_INSERT_HEAD(&s->inflight_aio_head, aio_req, aio_siblings);
         ret = add_aio_request(s, aio_req, acb->qiov->iov,
-                              acb->qiov->niov, 0, acb->aiocb_type);
+                              acb->qiov->niov, false, acb->aiocb_type);
         if (ret < 0) {
             error_report("add_aio_request is failed");
             free_aio_req(s, aio_req);
@@ -943,7 +943,7 @@ out:
 }
 
 static int coroutine_fn add_aio_request(BDRVSheepdogState *s, AIOReq *aio_req,
-                           struct iovec *iov, int niov, int create,
+                           struct iovec *iov, int niov, bool create,
                            enum AIOCBState aiocb_type)
 {
     int nr_copies = s->inode.nr_copies;
@@ -1022,7 +1022,7 @@ static int coroutine_fn add_aio_request(BDRVSheepdogState *s, AIOReq *aio_req,
 
 static int read_write_object(int fd, char *buf, uint64_t oid, int copies,
                              unsigned int datalen, uint64_t offset,
-                             int write, int create, uint8_t cache)
+                             bool write, bool create, bool cache)
 {
     SheepdogObjReq hdr;
     SheepdogObjRsp *rsp = (SheepdogObjRsp *)&hdr;
@@ -1071,18 +1071,18 @@ static int read_write_object(int fd, char *buf, uint64_t oid, int copies,
 }
 
 static int read_object(int fd, char *buf, uint64_t oid, int copies,
-                       unsigned int datalen, uint64_t offset, uint8_t cache)
+                       unsigned int datalen, uint64_t offset, bool cache)
 {
-    return read_write_object(fd, buf, oid, copies, datalen, offset, 0, 0,
-                             cache);
+    return read_write_object(fd, buf, oid, copies, datalen, offset, false,
+                             false, cache);
 }
 
 static int write_object(int fd, char *buf, uint64_t oid, int copies,
-                        unsigned int datalen, uint64_t offset, int create,
-                        uint8_t cache)
+                        unsigned int datalen, uint64_t offset, bool create,
+                        bool cache)
 {
-    return read_write_object(fd, buf, oid, copies, datalen, offset, 1, create,
-                             cache);
+    return read_write_object(fd, buf, oid, copies, datalen, offset, true,
+                             create, cache);
 }
 
 static int sd_open(BlockDriverState *bs, const char *filename, int flags)
@@ -1117,7 +1117,7 @@ static int sd_open(BlockDriverState *bs, const char *filename, int flags)
         goto out;
     }
 
-    s->cache_enabled = 1;
+    s->cache_enabled = true;
     s->flush_fd = connect_to_sdog(s->addr, s->port);
     if (s->flush_fd < 0) {
         error_report("failed to connect");
@@ -1127,7 +1127,7 @@ static int sd_open(BlockDriverState *bs, const char *filename, int flags)
 
     if (snapid || tag[0] != '\0') {
         dprintf("%" PRIx32 " snapshot inode was open.\n", vid);
-        s->is_snapshot = 1;
+        s->is_snapshot = true;
     }
 
     fd = connect_to_sdog(s->addr, s->port);
@@ -1270,7 +1270,7 @@ static int sd_create(const char *filename, QEMUOptionParameter *options)
     BDRVSheepdogState *s;
     char vdi[SD_MAX_VDI_LEN], tag[SD_MAX_VDI_TAG_LEN];
     uint32_t snapid;
-    int prealloc = 0;
+    bool prealloc = false;
     const char *vdiname;
 
     s = g_malloc0(sizeof(BDRVSheepdogState));
@@ -1292,9 +1292,9 @@ static int sd_create(const char *filename, QEMUOptionParameter *options)
             backing_file = options->value.s;
         } else if (!strcmp(options->name, BLOCK_OPT_PREALLOC)) {
             if (!options->value.s || !strcmp(options->value.s, "off")) {
-                prealloc = 0;
+                prealloc = false;
             } else if (!strcmp(options->value.s, "full")) {
-                prealloc = 1;
+                prealloc = true;
             } else {
                 error_report("Invalid preallocation mode: '%s'",
                              options->value.s);
@@ -1422,7 +1422,7 @@ static int sd_truncate(BlockDriverState *bs, int64_t offset)
     datalen = SD_INODE_SIZE - sizeof(s->inode.data_vdi_id);
     s->inode.vdi_size = offset;
     ret = write_object(fd, (char *)&s->inode, vid_to_vdi_oid(s->inode.vdi_id),
-                       s->inode.nr_copies, datalen, 0, 0, s->cache_enabled);
+                       s->inode.nr_copies, datalen, 0, false, s->cache_enabled);
     close(fd);
 
     if (ret < 0) {
@@ -1461,7 +1461,7 @@ static void coroutine_fn sd_write_done(SheepdogAIOCB *acb)
         aio_req = alloc_aio_req(s, acb, vid_to_vdi_oid(s->inode.vdi_id),
                                 data_len, offset, 0, 0, offset);
         QLIST_INSERT_HEAD(&s->inflight_aio_head, aio_req, aio_siblings);
-        ret = add_aio_request(s, aio_req, &iov, 1, 0, AIOCB_WRITE_UDATA);
+        ret = add_aio_request(s, aio_req, &iov, 1, false, AIOCB_WRITE_UDATA);
         if (ret) {
             free_aio_req(s, aio_req);
             acb->ret = -EIO;
@@ -1515,7 +1515,7 @@ static int sd_create_branch(BDRVSheepdogState *s)
 
     memcpy(&s->inode, buf, sizeof(s->inode));
 
-    s->is_snapshot = 0;
+    s->is_snapshot = false;
     ret = 0;
     dprintf("%" PRIx32 " was newly created.\n", s->inode.vdi_id);
 
@@ -1570,7 +1570,7 @@ static int coroutine_fn sd_co_rw_vector(void *p)
     while (done != total) {
         uint8_t flags = 0;
         uint64_t old_oid = 0;
-        int create = 0;
+        bool create = false;
 
         oid = vid_to_data_oid(inode->data_vdi_id[idx], idx);
 
@@ -1585,10 +1585,10 @@ static int coroutine_fn sd_co_rw_vector(void *p)
             break;
         case AIOCB_WRITE_UDATA:
             if (!inode->data_vdi_id[idx]) {
-                create = 1;
+                create = true;
             } else if (!is_data_obj_writable(inode, idx)) {
                 /* Copy-On-Write */
-                create = 1;
+                create = true;
                 old_oid = oid;
                 flags = SD_FLAG_CMD_COW;
             }
@@ -1722,7 +1722,7 @@ static int coroutine_fn sd_co_flush_to_disk(BlockDriverState *bs)
     if (rsp->result == SD_RES_INVALID_PARMS) {
         dprintf("disable write cache since the server doesn't support it\n");
 
-        s->cache_enabled = 0;
+        s->cache_enabled = false;
         closesocket(s->flush_fd);
         return 0;
     }
@@ -1773,7 +1773,7 @@ static int sd_snapshot_create(BlockDriverState *bs, QEMUSnapshotInfo *sn_info)
     }
 
     ret = write_object(fd, (char *)&s->inode, vid_to_vdi_oid(s->inode.vdi_id),
-                       s->inode.nr_copies, datalen, 0, 0, s->cache_enabled);
+                       s->inode.nr_copies, datalen, 0, false, s->cache_enabled);
     if (ret < 0) {
         error_report("failed to write snapshot's inode.");
         goto cleanup;
@@ -1860,7 +1860,7 @@ static int sd_snapshot_goto(BlockDriverState *bs, const char *snapshot_id)
         goto out;
     }
 
-    s->is_snapshot = 1;
+    s->is_snapshot = true;
 
     g_free(buf);
     g_free(old_s);
@@ -1978,8 +1978,8 @@ out:
 static int do_load_save_vmstate(BDRVSheepdogState *s, uint8_t *data,
                                 int64_t pos, int size, int load)
 {
-    int fd, create;
-    int ret = 0, remaining = size;
+    bool create;
+    int fd, ret = 0, remaining = size;
     unsigned int data_len;
     uint64_t vmstate_oid;
     uint32_t vdi_index;
commit 1e14afef00493bd375264dcea5fb8c7718b23355
Author: Peter Maydell <peter.maydell at linaro.org>
Date:   Fri Oct 5 17:33:22 2012 +0100

    configure: Tidy up remnants of non-64-bit physaddrs
    
    Tidy up some remnants of code to support non-64-bit physaddrs
    which were accidentally omitted from commit 4be403c8.
    
    Signed-off-by: Peter Maydell <peter.maydell at linaro.org>
    Signed-off-by: Stefan Hajnoczi <stefanha at redhat.com>

diff --git a/configure b/configure
index c4a7837..f1c56eb 100755
--- a/configure
+++ b/configure
@@ -3733,7 +3733,6 @@ case "$target_arch2" in
   ;;
   x86_64)
     TARGET_BASE_ARCH=i386
-    target_phys_bits=64
     target_long_alignment=8
   ;;
   alpha)
@@ -3836,7 +3835,6 @@ case "$target_arch2" in
     target_long_alignment=8
   ;;
   unicore32)
-    target_phys_bits=32
   ;;
   xtensa|xtensaeb)
     TARGET_ARCH=xtensa
commit 883bca776daa43111e9c39008f0038f7c62ae723
Author: Hans de Goede <hdegoede at redhat.com>
Date:   Wed Oct 10 15:50:36 2012 +0200

    uhci: Raise interrupt when requested even for non active tds
    
    According to the spec we must raise an interrupt when one is requested
    even for non active tds.
    
    Linux depends on this, for bulk transfers it runs an inactivity timer
    to work around a bug in early uhci revisions, when we take longer then
    200 ms to process a packet, this timer goes of, and as part of the
    handling Linux then unlinks the qh, and relinks it after the frindex
    has increased by atleast 1, the problem is Linux only checks for the
    frindex increases on an interrupt, and we don't send that, causing
    the qh to go inactive for more then 32 frames, at which point we
    consider the packet cancelled.
    
    Signed-off-by: Hans de Goede <hdegoede at redhat.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 cdc8bc3..c2f08e3 100644
--- a/hw/usb/hcd-uhci.c
+++ b/hw/usb/hcd-uhci.c
@@ -826,8 +826,16 @@ static int uhci_handle_td(UHCIState *s, uint32_t addr, UHCI_TD *td,
     USBEndpoint *ep;
 
     /* Is active ? */
-    if (!(td->ctrl & TD_CTRL_ACTIVE))
+    if (!(td->ctrl & TD_CTRL_ACTIVE)) {
+        /*
+         * ehci11d spec page 22: "Even if the Active bit in the TD is already
+         * cleared when the TD is fetched ... an IOC interrupt is generated"
+         */
+        if (td->ctrl & TD_CTRL_IOC) {
+                *int_mask |= 0x01;
+        }
         return TD_RESULT_NEXT_QH;
+    }
 
     async = uhci_async_find_td(s, addr, td);
     if (async) {
commit 5c16f767813602fbf57414e2a11057e252e0d422
Author: Hans de Goede <hdegoede at redhat.com>
Date:   Thu Sep 27 17:25:45 2012 +0200

    usb-redir: Don't make migration fail in none seamless case
    
    Instead simple disconnect the device like host redirection does on
    migration.
    
    Signed-off-by: Hans de Goede <hdegoede at redhat.com>
    Signed-off-by: Gerd Hoffmann <kraxel at redhat.com>

diff --git a/hw/usb/redirect.c b/hw/usb/redirect.c
index 5e0f98d..2283565 100644
--- a/hw/usb/redirect.c
+++ b/hw/usb/redirect.c
@@ -1614,12 +1614,17 @@ static int usbredir_get_parser(QEMUFile *f, void *priv, size_t unused)
     }
 
     /*
-     * Our chardev should be open already at this point, otherwise
-     * the usbredir channel will be broken (ie spice without seamless)
+     * If our chardev is not open already at this point the usbredir connection
+     * has been broken (non seamless migration, or restore from disk).
+     *
+     * In this case create a temporary parser to receive the migration data,
+     * and schedule the close_bh to report the device as disconnected to the
+     * guest and to destroy the parser again.
      */
     if (dev->parser == NULL) {
-        ERROR("get_parser called with closed chardev, failing migration\n");
-        return -1;
+        WARNING("usb-redir connection broken during migration\n");
+        usbredir_create_parser(dev);
+        qemu_bh_schedule(dev->chardev_close_bh);
     }
 
     data = g_malloc(len);
commit dbbf01958e777b6f03fc4ab425879f84800b9cda
Author: Hans de Goede <hdegoede at redhat.com>
Date:   Thu Sep 27 17:25:44 2012 +0200

    usb-redir: Change usbredir_open_chardev into usbredir_create_parser
    
    As we need to create the parser at more places.
    
    Signed-off-by: Hans de Goede <hdegoede at redhat.com>
    Signed-off-by: Gerd Hoffmann <kraxel at redhat.com>

diff --git a/hw/usb/redirect.c b/hw/usb/redirect.c
index b10241a..5e0f98d 100644
--- a/hw/usb/redirect.c
+++ b/hw/usb/redirect.c
@@ -862,15 +862,11 @@ static void usbredir_chardev_close_bh(void *opaque)
     }
 }
 
-static void usbredir_chardev_open(USBRedirDevice *dev)
+static void usbredir_create_parser(USBRedirDevice *dev)
 {
     uint32_t caps[USB_REDIR_CAPS_SIZE] = { 0, };
     int flags = 0;
 
-    /* Make sure any pending closes are handled (no-op if none pending) */
-    usbredir_chardev_close_bh(dev);
-    qemu_bh_cancel(dev->chardev_close_bh);
-
     DPRINTF("creating usbredirparser\n");
 
     dev->parser = qemu_oom_check(usbredirparser_create());
@@ -982,7 +978,10 @@ static void usbredir_chardev_event(void *opaque, int event)
     switch (event) {
     case CHR_EVENT_OPENED:
         DPRINTF("chardev open\n");
-        usbredir_chardev_open(dev);
+        /* Make sure any pending closes are handled (no-op if none pending) */
+        usbredir_chardev_close_bh(dev);
+        qemu_bh_cancel(dev->chardev_close_bh);
+        usbredir_create_parser(dev);
         break;
     case CHR_EVENT_CLOSED:
         DPRINTF("chardev close\n");
commit 9d6f1b73f83a02fb28438fa9a487f5c7d245e4af
Author: Luiz Capitulino <lcapitulino at redhat.com>
Date:   Wed Oct 3 18:40:01 2012 -0300

    qemu-ga: ga_open_pidfile(): add new line to pidfile
    
    FHS requires that pid files should end with a new line. Also change to
    snprintf() while there.
    
    Signed-off-by: Luiz Capitulino <lcapitulino at redhat.com>
    Reviewed-by: Michael Roth <mdroth at linux.vnet.ibm.com>
    Signed-off-by: Michael Roth <mdroth at linux.vnet.ibm.com>

diff --git a/qemu-ga.c b/qemu-ga.c
index daeaea5..9b59a52 100644
--- a/qemu-ga.c
+++ b/qemu-ga.c
@@ -255,7 +255,7 @@ static bool ga_open_pidfile(const char *pidfile)
         g_critical("Failed to truncate pid file");
         goto fail;
     }
-    sprintf(pidstr, "%d", getpid());
+    snprintf(pidstr, sizeof(pidstr), "%d\n", getpid());
     if (write(pidfd, pidstr, strlen(pidstr)) != strlen(pidstr)) {
         g_critical("Failed to write pid file");
         goto fail;
commit 6a3c8c14c8467c5db3539f1b6e43e03318e5e21b
Author: Luiz Capitulino <lcapitulino at redhat.com>
Date:   Wed Oct 3 18:35:58 2012 -0300

    qemu-ga: use state dir from CONFIG_QEMU_LOCALSTATEDIR
    
    Has the side effect of changing the default directory used to
    save the freeze status file from /tmp to ${prefix}/var/run.
    
    This is a beneficial change for two reasons:
    
      1. FHS states that programs must not assume that files in /tmp will
         still exist between invocations of the program. This defeats
    	 the purpose of the freeze status file
    
      2. FHS dictates that /var/run must be cleaned on boot, this
         ensures that a stale freeze status file will be removed on boot
    
    Signed-off-by: Luiz Capitulino <lcapitulino at redhat.com>
    Reviewed-by: Paolo Bonzini <pbonzini at redhat.com>
    Reviewed-by: Michael Roth <mdroth at linux.vnet.ibm.com>
    Signed-off-by: Michael Roth <mdroth at linux.vnet.ibm.com>

diff --git a/qemu-ga.c b/qemu-ga.c
index b747470..daeaea5 100644
--- a/qemu-ga.c
+++ b/qemu-ga.c
@@ -40,8 +40,8 @@
 #else
 #define QGA_VIRTIO_PATH_DEFAULT "\\\\.\\Global\\org.qemu.guest_agent.0"
 #endif
-#define QGA_PIDFILE_DEFAULT "/var/run/qemu-ga.pid"
-#define QGA_STATEDIR_DEFAULT "/tmp"
+#define QGA_STATEDIR_DEFAULT CONFIG_QEMU_LOCALSTATEDIR "/run"
+#define QGA_PIDFILE_DEFAULT QGA_STATEDIR_DEFAULT "/qemu-ga.pid"
 #define QGA_SENTINEL_BYTE 0xFF
 
 struct GAState {
commit 785c23ae5cf1d697834a635daf45b0a6bd93c00f
Author: Luiz Capitulino <lcapitulino at redhat.com>
Date:   Wed Oct 3 18:35:57 2012 -0300

    configure: add --localstatedir
    
    Next commit wants to use it.
    
    Signed-off-by: Luiz Capitulino <lcapitulino at redhat.com>
    Reviewed-by: Paolo Bonzini <pbonzini at redhat.com>
    Reviewed-by: Michael Roth <mdroth at linux.vnet.ibm.com>
    Signed-off-by: Michael Roth <mdroth at linux.vnet.ibm.com>

diff --git a/configure b/configure
index c4a7837..6600d88 100755
--- a/configure
+++ b/configure
@@ -185,6 +185,7 @@ libdir="\${prefix}/lib"
 libexecdir="\${prefix}/libexec"
 includedir="\${prefix}/include"
 sysconfdir="\${prefix}/etc"
+local_statedir="\${prefix}/var"
 confsuffix="/qemu"
 slirp="yes"
 fmod_lib=""
@@ -554,6 +555,7 @@ EOF
   qemu_docdir="\${prefix}"
   bindir="\${prefix}"
   sysconfdir="\${prefix}"
+  local_statedir="\${prefix}"
   confsuffix=""
   libs_qga="-lws2_32 -lwinmm -lpowrprof $libs_qga"
 fi
@@ -630,7 +632,9 @@ for opt do
   ;;
   --sysconfdir=*) sysconfdir="$optarg"
   ;;
-  --sbindir=*|--sharedstatedir=*|--localstatedir=*|\
+  --localstatedir=*) local_statedir="$optarg"
+  ;;
+  --sbindir=*|--sharedstatedir=*|\
   --oldincludedir=*|--datarootdir=*|--infodir=*|--localedir=*|\
   --htmldir=*|--dvidir=*|--pdfdir=*|--psdir=*)
     # These switches are silently ignored, for compatibility with
@@ -1028,6 +1032,7 @@ echo "  --datadir=PATH           install firmware in PATH$confsuffix"
 echo "  --docdir=PATH            install documentation in PATH$confsuffix"
 echo "  --bindir=PATH            install binaries in PATH"
 echo "  --sysconfdir=PATH        install config in PATH$confsuffix"
+echo "  --localstatedir=PATH     install local state in PATH"
 echo "  --with-confsuffix=SUFFIX suffix for QEMU data inside datadir and sysconfdir [$confsuffix]"
 echo "  --enable-debug-tcg       enable TCG debugging"
 echo "  --disable-debug-tcg      disable TCG debugging (default)"
@@ -3117,6 +3122,7 @@ echo "library directory `eval echo $libdir`"
 echo "libexec directory `eval echo $libexecdir`"
 echo "include directory `eval echo $includedir`"
 echo "config directory  `eval echo $sysconfdir`"
+echo "local state directory   `eval echo $local_statedir`"
 if test "$mingw32" = "no" ; then
 echo "Manual directory  `eval echo $mandir`"
 echo "ELF interp prefix $interp_prefix"
@@ -3226,6 +3232,7 @@ echo "sysconfdir=$sysconfdir" >> $config_host_mak
 echo "qemu_confdir=$qemu_confdir" >> $config_host_mak
 echo "qemu_datadir=$qemu_datadir" >> $config_host_mak
 echo "qemu_docdir=$qemu_docdir" >> $config_host_mak
+echo "qemu_localstatedir=$local_statedir" >> $config_host_mak
 echo "CONFIG_QEMU_HELPERDIR=\"$libexecdir\"" >> $config_host_mak
 
 echo "ARCH=$ARCH" >> $config_host_mak
commit 3a4f2816fac1b0f9cc197bb2208ddf03dc7bc592
Author: Jan Kiszka <jan.kiszka at siemens.com>
Date:   Mon Oct 8 08:45:31 2012 -0600

    vfio-pci: Fix BAR->VFIODevice translation in
    
    DO_UPCAST is supposed to translate from the first member of a struct to
    that struct, not from arbitrary ones. And it (usually) breaks the build
    when neglecting this rule. Use container_of to fix the build breakage
    and likely also the runtime behavior.
    
    Signed-off-by: Jan Kiszka <jan.kiszka at siemens.com>
    aw: runtime behavior is actually the same, but clearly misuse of DO_UPCAST
    Signed-off-by: Alex Williamson <alex.williamson at redhat.com>

diff --git a/hw/vfio_pci.c b/hw/vfio_pci.c
index 85b16bb..639371e 100644
--- a/hw/vfio_pci.c
+++ b/hw/vfio_pci.c
@@ -721,7 +721,7 @@ static void vfio_bar_write(void *opaque, target_phys_addr_t addr,
      * which access will service the interrupt, so we're potentially
      * getting quite a few host interrupts per guest interrupt.
      */
-    vfio_eoi(DO_UPCAST(VFIODevice, bars[bar->nr], bar));
+    vfio_eoi(container_of(bar, VFIODevice, bars[bar->nr]));
 }
 
 static uint64_t vfio_bar_read(void *opaque,
@@ -761,7 +761,7 @@ static uint64_t vfio_bar_read(void *opaque,
             __func__, bar->nr, addr, size, data);
 
     /* Same as write above */
-    vfio_eoi(DO_UPCAST(VFIODevice, bars[bar->nr], bar));
+    vfio_eoi(container_of(bar, VFIODevice, bars[bar->nr]));
 
     return data;
 }
commit 1a40313381262ebb5f30fb95d5550b674280f396
Author: Alex Williamson <alex.williamson at redhat.com>
Date:   Mon Oct 8 08:45:31 2012 -0600

    vfio-pci: Clang cleanup
    
    Blue Swirl reports that Clang doesn't like the structure we define to
    avoid dynamic allocation for a number of calls to VFIO_DEVICE_SET_IRQS.
    Adding an element after a variable sized type is a GNU extension.
    Switch back to dynamic allocation, which really isn't a problem since
    this is only done on interrupt setup changes.
    
    Cc: Blue Swirl <blauwirbel at gmail.com>
    Signed-off-by: Alex Williamson <alex.williamson at redhat.com>

diff --git a/hw/vfio_pci.c b/hw/vfio_pci.c
index 2325272..85b16bb 100644
--- a/hw/vfio_pci.c
+++ b/hw/vfio_pci.c
@@ -248,24 +248,12 @@ static void vfio_eoi(VFIODevice *vdev)
     vfio_unmask_intx(vdev);
 }
 
-typedef struct QEMU_PACKED VFIOIRQSetFD {
-    struct vfio_irq_set irq_set;
-    int32_t fd;
-} VFIOIRQSetFD;
-
 static int vfio_enable_intx(VFIODevice *vdev)
 {
-    VFIOIRQSetFD irq_set_fd = {
-        .irq_set = {
-            .argsz = sizeof(irq_set_fd),
-            .flags = VFIO_IRQ_SET_DATA_EVENTFD | VFIO_IRQ_SET_ACTION_TRIGGER,
-            .index = VFIO_PCI_INTX_IRQ_INDEX,
-            .start = 0,
-            .count = 1,
-        },
-    };
     uint8_t pin = vfio_pci_read_config(&vdev->pdev, PCI_INTERRUPT_PIN, 1);
-    int ret;
+    int ret, argsz;
+    struct vfio_irq_set *irq_set;
+    int32_t *pfd;
 
     if (!pin) {
         return 0;
@@ -280,12 +268,24 @@ static int vfio_enable_intx(VFIODevice *vdev)
         return ret;
     }
 
-    irq_set_fd.fd = event_notifier_get_fd(&vdev->intx.interrupt);
-    qemu_set_fd_handler(irq_set_fd.fd, vfio_intx_interrupt, NULL, vdev);
+    argsz = sizeof(*irq_set) + sizeof(*pfd);
+
+    irq_set = g_malloc0(argsz);
+    irq_set->argsz = argsz;
+    irq_set->flags = VFIO_IRQ_SET_DATA_EVENTFD | VFIO_IRQ_SET_ACTION_TRIGGER;
+    irq_set->index = VFIO_PCI_INTX_IRQ_INDEX;
+    irq_set->start = 0;
+    irq_set->count = 1;
+    pfd = (int32_t *)&irq_set->data;
+
+    *pfd = event_notifier_get_fd(&vdev->intx.interrupt);
+    qemu_set_fd_handler(*pfd, vfio_intx_interrupt, NULL, vdev);
 
-    if (ioctl(vdev->fd, VFIO_DEVICE_SET_IRQS, &irq_set_fd)) {
+    ret = ioctl(vdev->fd, VFIO_DEVICE_SET_IRQS, irq_set);
+    g_free(irq_set);
+    if (ret) {
         error_report("vfio: Error: Failed to setup INTx fd: %m\n");
-        qemu_set_fd_handler(irq_set_fd.fd, NULL, NULL, vdev);
+        qemu_set_fd_handler(*pfd, NULL, NULL, vdev);
         event_notifier_cleanup(&vdev->intx.interrupt);
         return -errno;
     }
@@ -426,18 +426,25 @@ static int vfio_msix_vector_use(PCIDevice *pdev,
             error_report("vfio: failed to enable vectors, %d\n", ret);
         }
     } else {
-        VFIOIRQSetFD irq_set_fd = {
-            .irq_set = {
-                .argsz = sizeof(irq_set_fd),
-                .flags = VFIO_IRQ_SET_DATA_EVENTFD |
-                         VFIO_IRQ_SET_ACTION_TRIGGER,
-                .index = VFIO_PCI_MSIX_IRQ_INDEX,
-                .start = nr,
-                .count = 1,
-            },
-            .fd = event_notifier_get_fd(&vector->interrupt),
-        };
-        ret = ioctl(vdev->fd, VFIO_DEVICE_SET_IRQS, &irq_set_fd);
+        int argsz;
+        struct vfio_irq_set *irq_set;
+        int32_t *pfd;
+
+        argsz = sizeof(*irq_set) + sizeof(*pfd);
+
+        irq_set = g_malloc0(argsz);
+        irq_set->argsz = argsz;
+        irq_set->flags = VFIO_IRQ_SET_DATA_EVENTFD |
+                         VFIO_IRQ_SET_ACTION_TRIGGER;
+        irq_set->index = VFIO_PCI_MSIX_IRQ_INDEX;
+        irq_set->start = nr;
+        irq_set->count = 1;
+        pfd = (int32_t *)&irq_set->data;
+
+        *pfd = event_notifier_get_fd(&vector->interrupt);
+
+        ret = ioctl(vdev->fd, VFIO_DEVICE_SET_IRQS, irq_set);
+        g_free(irq_set);
         if (ret) {
             error_report("vfio: failed to modify vector, %d\n", ret);
         }
@@ -450,17 +457,9 @@ static void vfio_msix_vector_release(PCIDevice *pdev, unsigned int nr)
 {
     VFIODevice *vdev = DO_UPCAST(VFIODevice, pdev, pdev);
     VFIOMSIVector *vector = &vdev->msi_vectors[nr];
-    VFIOIRQSetFD irq_set_fd = {
-        .irq_set = {
-            .argsz = sizeof(irq_set_fd),
-            .flags = VFIO_IRQ_SET_DATA_EVENTFD |
-                     VFIO_IRQ_SET_ACTION_TRIGGER,
-            .index = VFIO_PCI_MSIX_IRQ_INDEX,
-            .start = nr,
-            .count = 1,
-        },
-        .fd = -1,
-    };
+    int argsz;
+    struct vfio_irq_set *irq_set;
+    int32_t *pfd;
 
     DPRINTF("%s(%04x:%02x:%02x.%x) vector %d released\n", __func__,
             vdev->host.domain, vdev->host.bus, vdev->host.slot,
@@ -472,7 +471,23 @@ static void vfio_msix_vector_release(PCIDevice *pdev, unsigned int nr)
      * bouncing through userspace and let msix.c drop it?  Not sure.
      */
     msix_vector_unuse(pdev, nr);
-    ioctl(vdev->fd, VFIO_DEVICE_SET_IRQS, &irq_set_fd);
+
+    argsz = sizeof(*irq_set) + sizeof(*pfd);
+
+    irq_set = g_malloc0(argsz);
+    irq_set->argsz = argsz;
+    irq_set->flags = VFIO_IRQ_SET_DATA_EVENTFD |
+                     VFIO_IRQ_SET_ACTION_TRIGGER;
+    irq_set->index = VFIO_PCI_MSIX_IRQ_INDEX;
+    irq_set->start = nr;
+    irq_set->count = 1;
+    pfd = (int32_t *)&irq_set->data;
+
+    *pfd = -1;
+
+    ioctl(vdev->fd, VFIO_DEVICE_SET_IRQS, irq_set);
+
+    g_free(irq_set);
 
     if (vector->virq < 0) {
         qemu_set_fd_handler(event_notifier_get_fd(&vector->interrupt),
commit ce59af2dba6fde2e3990b831f4c9a83641f5609e
Author: Alex Williamson <alex.williamson at redhat.com>
Date:   Mon Oct 8 08:45:30 2012 -0600

    vfio-pci: Cleanup on INTx setup failure
    
    Missing some unwind code.
    
    Signed-off-by: Alex Williamson <alex.williamson at redhat.com>

diff --git a/hw/vfio_pci.c b/hw/vfio_pci.c
index b2383c4..2325272 100644
--- a/hw/vfio_pci.c
+++ b/hw/vfio_pci.c
@@ -285,6 +285,8 @@ static int vfio_enable_intx(VFIODevice *vdev)
 
     if (ioctl(vdev->fd, VFIO_DEVICE_SET_IRQS, &irq_set_fd)) {
         error_report("vfio: Error: Failed to setup INTx fd: %m\n");
+        qemu_set_fd_handler(irq_set_fd.fd, NULL, NULL, vdev);
+        event_notifier_cleanup(&vdev->intx.interrupt);
         return -errno;
     }
 
commit 5834a83f4803de88949162346e6dfa2060d3fca6
Author: Alex Williamson <alex.williamson at redhat.com>
Date:   Mon Oct 8 08:45:30 2012 -0600

    vfio-pci: Extend reset
    
    Take what we've learned from pci-assign and apply it to vfio-pci.
    On reset, disable previous interrupt config, perform a device
    reset if available, re-enable INTx, and disable memory regions on
    the device to prevent continuing DMA.
    
    Signed-off-by: Alex Williamson <alex.williamson at redhat.com>

diff --git a/hw/vfio_pci.c b/hw/vfio_pci.c
index a554e7c..b2383c4 100644
--- a/hw/vfio_pci.c
+++ b/hw/vfio_pci.c
@@ -1891,16 +1891,31 @@ static void vfio_pci_reset(DeviceState *dev)
 {
     PCIDevice *pdev = DO_UPCAST(PCIDevice, qdev, dev);
     VFIODevice *vdev = DO_UPCAST(VFIODevice, pdev, pdev);
+    uint16_t cmd;
 
-    if (!vdev->reset_works) {
-        return;
-    }
+    DPRINTF("%s(%04x:%02x:%02x.%x)\n", __func__, vdev->host.domain,
+            vdev->host.bus, vdev->host.slot, vdev->host.function);
+
+    vfio_disable_interrupts(vdev);
 
-    if (ioctl(vdev->fd, VFIO_DEVICE_RESET)) {
-        error_report("vfio: Error unable to reset physical device "
-                     "(%04x:%02x:%02x.%x): %m\n", vdev->host.domain,
-                     vdev->host.bus, vdev->host.slot, vdev->host.function);
+    /*
+     * Stop any ongoing DMA by disconecting I/O, MMIO, and bus master.
+     * Also put INTx Disable in known state.
+     */
+    cmd = vfio_pci_read_config(pdev, PCI_COMMAND, 2);
+    cmd &= ~(PCI_COMMAND_IO | PCI_COMMAND_MEMORY | PCI_COMMAND_MASTER |
+             PCI_COMMAND_INTX_DISABLE);
+    vfio_pci_write_config(pdev, PCI_COMMAND, cmd, 2);
+
+    if (vdev->reset_works) {
+        if (ioctl(vdev->fd, VFIO_DEVICE_RESET)) {
+            error_report("vfio: Error unable to reset physical device "
+                         "(%04x:%02x:%02x.%x): %m\n", vdev->host.domain,
+                         vdev->host.bus, vdev->host.slot, vdev->host.function);
+        }
     }
+
+    vfio_enable_intx(vdev);
 }
 
 static Property vfio_pci_dev_properties[] = {
commit 9b1e45c8f1355592cb60c6aed9ac1f90b606a1a8
Author: Alex Williamson <alex.williamson at redhat.com>
Date:   Mon Oct 8 08:45:30 2012 -0600

    vfio-pci: Remove setting of MSI qsize
    
    This was a misinterpretation of the spec, hardware doesn't get to
    specify how many were actually enabled through this field.
    
    Signed-off-by: Alex Williamson <alex.williamson at redhat.com>

diff --git a/hw/vfio_pci.c b/hw/vfio_pci.c
index 0ca77cf..a554e7c 100644
--- a/hw/vfio_pci.c
+++ b/hw/vfio_pci.c
@@ -508,20 +508,6 @@ static MSIMessage msi_get_msg(PCIDevice *pdev, unsigned int vector)
     return msg;
 }
 
-/* So should this */
-static void msi_set_qsize(PCIDevice *pdev, uint8_t size)
-{
-    uint8_t *config = pdev->config + pdev->msi_cap;
-    uint16_t flags;
-
-    flags = pci_get_word(config + PCI_MSI_FLAGS);
-    flags = le16_to_cpu(flags);
-    flags &= ~PCI_MSI_FLAGS_QSIZE;
-    flags |= (size & 0x7) << 4;
-    flags = cpu_to_le16(flags);
-    pci_set_word(config + PCI_MSI_FLAGS, flags);
-}
-
 static void vfio_enable_msix(VFIODevice *vdev)
 {
     vfio_disable_interrupts(vdev);
@@ -609,8 +595,6 @@ retry:
         return;
     }
 
-    msi_set_qsize(&vdev->pdev, vdev->nr_vectors);
-
     vdev->interrupt = VFIO_INT_MSI;
 
     DPRINTF("%s(%04x:%02x:%02x.%x) Enabled %d MSI vectors\n", __func__,
@@ -671,8 +655,6 @@ static void vfio_disable_msi(VFIODevice *vdev)
 
     vfio_disable_msi_common(vdev);
 
-    msi_set_qsize(&vdev->pdev, 0); /* Actually still means 1 vector */
-
     DPRINTF("%s(%04x:%02x:%02x.%x)\n", __func__, vdev->host.domain,
             vdev->host.bus, vdev->host.slot, vdev->host.function);
 }
commit 5976cdd58b657692e8c1af5310d55a60aecc9089
Author: Alex Williamson <alex.williamson at redhat.com>
Date:   Mon Oct 8 08:45:30 2012 -0600

    vfio-pci: Use uintptr_t for void* cast
    
    We don't seem to run into any sign extension problems, but
    unsigned looks more correct.
    
    Signed-off-by: Alex williamson <alex.williamson at redhat.com>

diff --git a/hw/vfio_pci.c b/hw/vfio_pci.c
index d62ddd1..0ca77cf 100644
--- a/hw/vfio_pci.c
+++ b/hw/vfio_pci.c
@@ -907,7 +907,7 @@ static int vfio_dma_map(VFIOContainer *container, target_phys_addr_t iova,
     struct vfio_iommu_type1_dma_map map = {
         .argsz = sizeof(map),
         .flags = VFIO_DMA_MAP_FLAG_READ,
-        .vaddr = (__u64)(intptr_t)vaddr,
+        .vaddr = (__u64)(uintptr_t)vaddr,
         .iova = iova,
         .size = size,
     };
commit e43b9a5a4fb2b501fbbec411faff899b74a2d451
Author: Alex Williamson <alex.williamson at redhat.com>
Date:   Mon Oct 8 08:45:30 2012 -0600

    vfio-pci: Don't peak at msi_supported
    
    Let the init function fail, just don't warn for -ENOTSUP.
    
    Signed-off-by: Alex Williamson <alex.williamson at redhat.com>

diff --git a/hw/vfio_pci.c b/hw/vfio_pci.c
index 4d01707..d62ddd1 100644
--- a/hw/vfio_pci.c
+++ b/hw/vfio_pci.c
@@ -1084,14 +1084,6 @@ static int vfio_setup_msi(VFIODevice *vdev, int pos)
     bool msi_64bit, msi_maskbit;
     int ret, entries;
 
-    /*
-     * TODO: don't peek into msi_supported, let msi_init fail and
-     * check for ENOTSUP
-     */
-    if (!msi_supported) {
-        return 0;
-    }
-
     if (pread(vdev->fd, &ctrl, sizeof(ctrl),
               vdev->config_offset + pos + PCI_CAP_FLAGS) != sizeof(ctrl)) {
         return -errno;
@@ -1107,6 +1099,9 @@ static int vfio_setup_msi(VFIODevice *vdev, int pos)
 
     ret = msi_init(&vdev->pdev, pos, entries, msi_64bit, msi_maskbit);
     if (ret < 0) {
+        if (ret == -ENOTSUP) {
+            return 0;
+        }
         error_report("vfio: msi_init failed\n");
         return ret;
     }
@@ -1173,20 +1168,15 @@ static int vfio_setup_msix(VFIODevice *vdev, int pos)
 {
     int ret;
 
-    /*
-     * TODO: don't peek into msi_supported, let msix_init fail and
-     * check for ENOTSUP
-     */
-    if (!msi_supported) {
-        return 0;
-    }
-
     ret = msix_init(&vdev->pdev, vdev->msix->entries,
                     &vdev->bars[vdev->msix->table_bar].mem,
                     vdev->msix->table_bar, vdev->msix->table_offset,
                     &vdev->bars[vdev->msix->pba_bar].mem,
                     vdev->msix->pba_bar, vdev->msix->pba_offset, pos);
     if (ret < 0) {
+        if (ret == -ENOTSUP) {
+            return 0;
+        }
         error_report("vfio: msix_init failed\n");
         return ret;
     }
commit 5c97e5eba665b66395eee87d88cf2f8301594145
Author: Alex Williamson <alex.williamson at redhat.com>
Date:   Mon Oct 8 08:45:30 2012 -0600

    vfio-pci: Roll the header into the .c file
    
    It's only ~100 lines and nobody else should be using this.
    Suggested by Michael Tsirkin.
    
    Signed-off-by: Alex Williamson <alex.williamson at redhat.com>

diff --git a/hw/vfio_pci.c b/hw/vfio_pci.c
index bca4083..4d01707 100644
--- a/hw/vfio_pci.c
+++ b/hw/vfio_pci.c
@@ -33,9 +33,11 @@
 #include "memory.h"
 #include "msi.h"
 #include "msix.h"
+#include "pci.h"
+#include "qemu-common.h"
 #include "qemu-error.h"
+#include "qemu-queue.h"
 #include "range.h"
-#include "vfio_pci_int.h"
 
 /* #define DEBUG_VFIO */
 #ifdef DEBUG_VFIO
@@ -46,6 +48,99 @@
     do { } while (0)
 #endif
 
+typedef struct VFIOBAR {
+    off_t fd_offset; /* offset of BAR within device fd */
+    int fd; /* device fd, allows us to pass VFIOBAR as opaque data */
+    MemoryRegion mem; /* slow, read/write access */
+    MemoryRegion mmap_mem; /* direct mapped access */
+    void *mmap;
+    size_t size;
+    uint32_t flags; /* VFIO region flags (rd/wr/mmap) */
+    uint8_t nr; /* cache the BAR number for debug */
+} VFIOBAR;
+
+typedef struct VFIOINTx {
+    bool pending; /* interrupt pending */
+    bool kvm_accel; /* set when QEMU bypass through KVM enabled */
+    uint8_t pin; /* which pin to pull for qemu_set_irq */
+    EventNotifier interrupt; /* eventfd triggered on interrupt */
+    EventNotifier unmask; /* eventfd for unmask on QEMU bypass */
+    PCIINTxRoute route; /* routing info for QEMU bypass */
+    uint32_t mmap_timeout; /* delay to re-enable mmaps after interrupt */
+    QEMUTimer *mmap_timer; /* enable mmaps after periods w/o interrupts */
+} VFIOINTx;
+
+struct VFIODevice;
+
+typedef struct VFIOMSIVector {
+    EventNotifier interrupt; /* eventfd triggered on interrupt */
+    struct VFIODevice *vdev; /* back pointer to device */
+    int virq; /* KVM irqchip route for QEMU bypass */
+    bool use;
+} VFIOMSIVector;
+
+enum {
+    VFIO_INT_NONE = 0,
+    VFIO_INT_INTx = 1,
+    VFIO_INT_MSI  = 2,
+    VFIO_INT_MSIX = 3,
+};
+
+struct VFIOGroup;
+
+typedef struct VFIOContainer {
+    int fd; /* /dev/vfio/vfio, empowered by the attached groups */
+    struct {
+        /* enable abstraction to support various iommu backends */
+        union {
+            MemoryListener listener; /* Used by type1 iommu */
+        };
+        void (*release)(struct VFIOContainer *);
+    } iommu_data;
+    QLIST_HEAD(, VFIOGroup) group_list;
+    QLIST_ENTRY(VFIOContainer) next;
+} VFIOContainer;
+
+/* Cache of MSI-X setup plus extra mmap and memory region for split BAR map */
+typedef struct VFIOMSIXInfo {
+    uint8_t table_bar;
+    uint8_t pba_bar;
+    uint16_t entries;
+    uint32_t table_offset;
+    uint32_t pba_offset;
+    MemoryRegion mmap_mem;
+    void *mmap;
+} VFIOMSIXInfo;
+
+typedef struct VFIODevice {
+    PCIDevice pdev;
+    int fd;
+    VFIOINTx intx;
+    unsigned int config_size;
+    off_t config_offset; /* Offset of config space region within device fd */
+    unsigned int rom_size;
+    off_t rom_offset; /* Offset of ROM region within device fd */
+    int msi_cap_size;
+    VFIOMSIVector *msi_vectors;
+    VFIOMSIXInfo *msix;
+    int nr_vectors; /* Number of MSI/MSIX vectors currently in use */
+    int interrupt; /* Current interrupt type */
+    VFIOBAR bars[PCI_NUM_REGIONS - 1]; /* No ROM */
+    PCIHostDeviceAddress host;
+    QLIST_ENTRY(VFIODevice) next;
+    struct VFIOGroup *group;
+    bool reset_works;
+} VFIODevice;
+
+typedef struct VFIOGroup {
+    int fd;
+    int groupid;
+    VFIOContainer *container;
+    QLIST_HEAD(, VFIODevice) device_list;
+    QLIST_ENTRY(VFIOGroup) next;
+    QLIST_ENTRY(VFIOGroup) container_next;
+} VFIOGroup;
+
 #define MSIX_CAP_LENGTH 12
 
 static QLIST_HEAD(, VFIOContainer)
diff --git a/hw/vfio_pci_int.h b/hw/vfio_pci_int.h
deleted file mode 100644
index e69bf5f..0000000
--- a/hw/vfio_pci_int.h
+++ /dev/null
@@ -1,114 +0,0 @@
-/*
- * vfio based device assignment support
- *
- * Copyright Red Hat, Inc. 2012
- *
- * Authors:
- *  Alex Williamson <alex.williamson at redhat.com>
- *
- * This work is licensed under the terms of the GNU GPL, version 2.  See
- * the COPYING file in the top-level directory.
- */
-
-#ifndef HW_VFIO_PCI_INT_H
-#define HW_VFIO_PCI_INT_H
-
-#include "qemu-common.h"
-#include "qemu-queue.h"
-#include "pci.h"
-#include "event_notifier.h"
-
-typedef struct VFIOBAR {
-    off_t fd_offset; /* offset of BAR within device fd */
-    int fd; /* device fd, allows us to pass VFIOBAR as opaque data */
-    MemoryRegion mem; /* slow, read/write access */
-    MemoryRegion mmap_mem; /* direct mapped access */
-    void *mmap;
-    size_t size;
-    uint32_t flags; /* VFIO region flags (rd/wr/mmap) */
-    uint8_t nr; /* cache the BAR number for debug */
-} VFIOBAR;
-
-typedef struct VFIOINTx {
-    bool pending; /* interrupt pending */
-    bool kvm_accel; /* set when QEMU bypass through KVM enabled */
-    uint8_t pin; /* which pin to pull for qemu_set_irq */
-    EventNotifier interrupt; /* eventfd triggered on interrupt */
-    EventNotifier unmask; /* eventfd for unmask on QEMU bypass */
-    PCIINTxRoute route; /* routing info for QEMU bypass */
-    uint32_t mmap_timeout; /* delay to re-enable mmaps after interrupt */
-    QEMUTimer *mmap_timer; /* enable mmaps after periods w/o interrupts */
-} VFIOINTx;
-
-struct VFIODevice;
-
-typedef struct VFIOMSIVector {
-    EventNotifier interrupt; /* eventfd triggered on interrupt */
-    struct VFIODevice *vdev; /* back pointer to device */
-    int virq; /* KVM irqchip route for QEMU bypass */
-    bool use;
-} VFIOMSIVector;
-
-enum {
-    VFIO_INT_NONE = 0,
-    VFIO_INT_INTx = 1,
-    VFIO_INT_MSI  = 2,
-    VFIO_INT_MSIX = 3,
-};
-
-struct VFIOGroup;
-
-typedef struct VFIOContainer {
-    int fd; /* /dev/vfio/vfio, empowered by the attached groups */
-    struct {
-        /* enable abstraction to support various iommu backends */
-        union {
-            MemoryListener listener; /* Used by type1 iommu */
-        };
-        void (*release)(struct VFIOContainer *);
-    } iommu_data;
-    QLIST_HEAD(, VFIOGroup) group_list;
-    QLIST_ENTRY(VFIOContainer) next;
-} VFIOContainer;
-
-/* Cache of MSI-X setup plus extra mmap and memory region for split BAR map */
-typedef struct VFIOMSIXInfo {
-    uint8_t table_bar;
-    uint8_t pba_bar;
-    uint16_t entries;
-    uint32_t table_offset;
-    uint32_t pba_offset;
-    MemoryRegion mmap_mem;
-    void *mmap;
-} VFIOMSIXInfo;
-
-typedef struct VFIODevice {
-    PCIDevice pdev;
-    int fd;
-    VFIOINTx intx;
-    unsigned int config_size;
-    off_t config_offset; /* Offset of config space region within device fd */
-    unsigned int rom_size;
-    off_t rom_offset; /* Offset of ROM region within device fd */
-    int msi_cap_size;
-    VFIOMSIVector *msi_vectors;
-    VFIOMSIXInfo *msix;
-    int nr_vectors; /* Number of MSI/MSIX vectors currently in use */
-    int interrupt; /* Current interrupt type */
-    VFIOBAR bars[PCI_NUM_REGIONS - 1]; /* No ROM */
-    PCIHostDeviceAddress host;
-    QLIST_ENTRY(VFIODevice) next;
-    struct VFIOGroup *group;
-    bool reset_works;
-} VFIODevice;
-
-typedef struct VFIOGroup {
-    int fd;
-    int groupid;
-    VFIOContainer *container;
-    QLIST_HEAD(, VFIODevice) device_list;
-    QLIST_ENTRY(VFIOGroup) next;
-    QLIST_ENTRY(VFIOGroup) container_next;
-} VFIOGroup;
-
-#endif /* HW_VFIO_PCI_INT_H */
commit 98cd5a5eaf4ad96d240e680eb1b26460dc278c33
Author: Alex Williamson <alex.williamson at redhat.com>
Date:   Mon Oct 8 08:45:29 2012 -0600

    vfio-pci: No spurious MSIs
    
    FreeBSD doesn't like these spurious MSIs, remove them as they're
    mostly paranoia anyway.
    
    Signed-off-by: Alex Williamson <alex.williamson at redhat.com>

diff --git a/hw/vfio_pci.c b/hw/vfio_pci.c
index 89e00ba..bca4083 100644
--- a/hw/vfio_pci.c
+++ b/hw/vfio_pci.c
@@ -322,21 +322,12 @@ static int vfio_msix_vector_use(PCIDevice *pdev,
      * increase them as needed.
      */
     if (vdev->nr_vectors < nr + 1) {
-        int i;
-
         vfio_disable_irqindex(vdev, VFIO_PCI_MSIX_IRQ_INDEX);
         vdev->nr_vectors = nr + 1;
         ret = vfio_enable_vectors(vdev, true);
         if (ret) {
             error_report("vfio: failed to enable vectors, %d\n", ret);
         }
-
-        /* We don't know if we've missed interrupts in the interim... */
-        for (i = 0; i < vdev->msix->entries; i++) {
-            if (vdev->msi_vectors[i].use) {
-                msix_notify(&vdev->pdev, i);
-            }
-        }
     } else {
         VFIOIRQSetFD irq_set_fd = {
             .irq_set = {
@@ -353,12 +344,6 @@ static int vfio_msix_vector_use(PCIDevice *pdev,
         if (ret) {
             error_report("vfio: failed to modify vector, %d\n", ret);
         }
-
-        /*
-         * If we were connected to the hardware PBA we could skip this,
-         * until then, a spurious interrupt is better than starvation.
-         */
-        msix_notify(&vdev->pdev, nr);
     }
 
     return 0;
commit fd704adc479810477606c3418aeb64a590f51fe3
Author: Alex Williamson <alex.williamson at redhat.com>
Date:   Mon Oct 8 08:45:29 2012 -0600

    vfio-pci: Rework MSIX setup/teardown
    
    We try to do lazy initialization of MSIX since we don't actually need
    to setup anything until MSIX vectors start getting used.  This leads
    to problems if MSIX is enabled, but never used (we can end up trying
    to re-enable INTx while it's still enabled).  We also run into
    problems trying to expand our reset function to tear down interrupts
    as we can then get vector release notifications after we've released
    data structures.  By making explicit initialization and teardown we
    can avoid both of these problems and behave more similar to bare
    metal.
    
    Signed-off-by: Alex Williamson <alex.williamson at redhat.com>

diff --git a/hw/vfio_pci.c b/hw/vfio_pci.c
index 7413f2d..89e00ba 100644
--- a/hw/vfio_pci.c
+++ b/hw/vfio_pci.c
@@ -72,8 +72,6 @@ static void vfio_disable_irqindex(VFIODevice *vdev, int index)
     };
 
     ioctl(vdev->fd, VFIO_DEVICE_SET_IRQS, &irq_set);
-
-    vdev->interrupt = VFIO_INT_NONE;
 }
 
 /*
@@ -278,10 +276,6 @@ static int vfio_enable_vectors(VFIODevice *vdev, bool msix)
 
     g_free(irq_set);
 
-    if (!ret) {
-        vdev->interrupt = msix ? VFIO_INT_MSIX : VFIO_INT_MSI;
-    }
-
     return ret;
 }
 
@@ -296,15 +290,6 @@ static int vfio_msix_vector_use(PCIDevice *pdev,
             vdev->host.domain, vdev->host.bus, vdev->host.slot,
             vdev->host.function, nr);
 
-    if (vdev->interrupt != VFIO_INT_MSIX) {
-        vfio_disable_interrupts(vdev);
-    }
-
-    if (!vdev->msi_vectors) {
-        vdev->msi_vectors = g_malloc0(vdev->msix->entries *
-                                      sizeof(VFIOMSIVector));
-    }
-
     vector = &vdev->msi_vectors[nr];
     vector->vdev = vdev;
     vector->use = true;
@@ -457,6 +442,23 @@ static void msi_set_qsize(PCIDevice *pdev, uint8_t size)
     pci_set_word(config + PCI_MSI_FLAGS, flags);
 }
 
+static void vfio_enable_msix(VFIODevice *vdev)
+{
+    vfio_disable_interrupts(vdev);
+
+    vdev->msi_vectors = g_malloc0(vdev->msix->entries * sizeof(VFIOMSIVector));
+
+    vdev->interrupt = VFIO_INT_MSIX;
+
+    if (msix_set_vector_notifiers(&vdev->pdev, vfio_msix_vector_use,
+                                  vfio_msix_vector_release)) {
+        error_report("vfio: msix_set_vector_notifiers failed\n");
+    }
+
+    DPRINTF("%s(%04x:%02x:%02x.%x)\n", __func__, vdev->host.domain,
+            vdev->host.bus, vdev->host.slot, vdev->host.function);
+}
+
 static void vfio_enable_msi(VFIODevice *vdev)
 {
     int ret, i;
@@ -529,17 +531,43 @@ retry:
 
     msi_set_qsize(&vdev->pdev, vdev->nr_vectors);
 
+    vdev->interrupt = VFIO_INT_MSI;
+
     DPRINTF("%s(%04x:%02x:%02x.%x) Enabled %d MSI vectors\n", __func__,
             vdev->host.domain, vdev->host.bus, vdev->host.slot,
             vdev->host.function, vdev->nr_vectors);
 }
 
-static void vfio_disable_msi_x(VFIODevice *vdev, bool msix)
+static void vfio_disable_msi_common(VFIODevice *vdev)
+{
+    g_free(vdev->msi_vectors);
+    vdev->msi_vectors = NULL;
+    vdev->nr_vectors = 0;
+    vdev->interrupt = VFIO_INT_NONE;
+
+    vfio_enable_intx(vdev);
+}
+
+static void vfio_disable_msix(VFIODevice *vdev)
+{
+    msix_unset_vector_notifiers(&vdev->pdev);
+
+    if (vdev->nr_vectors) {
+        vfio_disable_irqindex(vdev, VFIO_PCI_MSIX_IRQ_INDEX);
+    }
+
+    vfio_disable_msi_common(vdev);
+
+    DPRINTF("%s(%04x:%02x:%02x.%x, msi%s)\n", __func__,
+            vdev->host.domain, vdev->host.bus, vdev->host.slot,
+            vdev->host.function, msix ? "x" : "");
+}
+
+static void vfio_disable_msi(VFIODevice *vdev)
 {
     int i;
 
-    vfio_disable_irqindex(vdev, msix ? VFIO_PCI_MSIX_IRQ_INDEX :
-                                       VFIO_PCI_MSI_IRQ_INDEX);
+    vfio_disable_irqindex(vdev, VFIO_PCI_MSI_IRQ_INDEX);
 
     for (i = 0; i < vdev->nr_vectors; i++) {
         VFIOMSIVector *vector = &vdev->msi_vectors[i];
@@ -558,26 +586,15 @@ static void vfio_disable_msi_x(VFIODevice *vdev, bool msix)
                                 NULL, NULL, NULL);
         }
 
-        if (msix) {
-            msix_vector_unuse(&vdev->pdev, i);
-        }
-
         event_notifier_cleanup(&vector->interrupt);
     }
 
-    g_free(vdev->msi_vectors);
-    vdev->msi_vectors = NULL;
-    vdev->nr_vectors = 0;
-
-    if (!msix) {
-        msi_set_qsize(&vdev->pdev, 0); /* Actually still means 1 vector */
-    }
+    vfio_disable_msi_common(vdev);
 
-    DPRINTF("%s(%04x:%02x:%02x.%x, msi%s)\n", __func__,
-            vdev->host.domain, vdev->host.bus, vdev->host.slot,
-            vdev->host.function, msix ? "x" : "");
+    msi_set_qsize(&vdev->pdev, 0); /* Actually still means 1 vector */
 
-    vfio_enable_intx(vdev);
+    DPRINTF("%s(%04x:%02x:%02x.%x)\n", __func__, vdev->host.domain,
+            vdev->host.bus, vdev->host.slot, vdev->host.function);
 }
 
 /*
@@ -763,7 +780,7 @@ static void vfio_pci_write_config(PCIDevice *pdev, uint32_t addr,
         if (!was_enabled && is_enabled) {
             vfio_enable_msi(vdev);
         } else if (was_enabled && !is_enabled) {
-            vfio_disable_msi_x(vdev, false);
+            vfio_disable_msi(vdev);
         }
     }
 
@@ -776,9 +793,9 @@ static void vfio_pci_write_config(PCIDevice *pdev, uint32_t addr,
         is_enabled = msix_enabled(pdev);
 
         if (!was_enabled && is_enabled) {
-            /* vfio_msix_vector_use handles this automatically */
+            vfio_enable_msix(vdev);
         } else if (was_enabled && !is_enabled) {
-            vfio_disable_msi_x(vdev, true);
+            vfio_disable_msix(vdev);
         }
     }
 }
@@ -973,10 +990,10 @@ static void vfio_disable_interrupts(VFIODevice *vdev)
         vfio_disable_intx(vdev);
         break;
     case VFIO_INT_MSI:
-        vfio_disable_msi_x(vdev, false);
+        vfio_disable_msi(vdev);
         break;
     case VFIO_INT_MSIX:
-        vfio_disable_msi_x(vdev, true);
+        vfio_disable_msix(vdev);
         break;
     }
 }
@@ -1094,15 +1111,6 @@ static int vfio_setup_msix(VFIODevice *vdev, int pos)
         return ret;
     }
 
-    ret = msix_set_vector_notifiers(&vdev->pdev, vfio_msix_vector_use,
-                                    vfio_msix_vector_release);
-    if (ret) {
-        error_report("vfio: msix_set_vector_notifiers failed %d\n", ret);
-        msix_uninit(&vdev->pdev, &vdev->bars[vdev->msix->table_bar].mem,
-                    &vdev->bars[vdev->msix->pba_bar].mem);
-        return ret;
-    }
-
     return 0;
 }
 
@@ -1111,12 +1119,6 @@ static void vfio_teardown_msi(VFIODevice *vdev)
     msi_uninit(&vdev->pdev);
 
     if (vdev->msix) {
-        /* FIXME: Why can't unset just silently do nothing?? */
-        if (vdev->pdev.msix_vector_use_notifier &&
-            vdev->pdev.msix_vector_release_notifier) {
-            msix_unset_vector_notifiers(&vdev->pdev);
-        }
-
         msix_uninit(&vdev->pdev, &vdev->bars[vdev->msix->table_bar].mem,
                     &vdev->bars[vdev->msix->pba_bar].mem);
     }
commit 12af1344871aee4a8df011c3b0548f7c77332d54
Author: Alex Williamson <alex.williamson at redhat.com>
Date:   Mon Oct 8 08:45:29 2012 -0600

    vfio-pci: Unmap and retry DMA mapping
    
    Occasionally we get regions added that overlap with existing mappings.
    These always seems to be in the VGA ROM range.  VFIO returns EBUSY
    for these mapping attempts.  We can try a little harder and assume
    that the latest mapping is correct by removing any overlapping ranges
    and retrying the original request.
    
    Signed-off-by: Alex Williamson <alex.williamson at redhat.com>

diff --git a/hw/vfio_pci.c b/hw/vfio_pci.c
index 2d89d17..7413f2d 100644
--- a/hw/vfio_pci.c
+++ b/hw/vfio_pci.c
@@ -819,12 +819,19 @@ static int vfio_dma_map(VFIOContainer *container, target_phys_addr_t iova,
         map.flags |= VFIO_DMA_MAP_FLAG_WRITE;
     }
 
-    if (ioctl(container->fd, VFIO_IOMMU_MAP_DMA, &map)) {
-        DPRINTF("VFIO_MAP_DMA: %d\n", -errno);
-        return -errno;
+    /*
+     * Try the mapping, if it fails with EBUSY, unmap the region and try
+     * again.  This shouldn't be necessary, but we sometimes see it in
+     * the the VGA ROM space.
+     */
+    if (ioctl(container->fd, VFIO_IOMMU_MAP_DMA, &map) == 0 ||
+        (errno == EBUSY && vfio_dma_unmap(container, iova, size) == 0 &&
+         ioctl(container->fd, VFIO_IOMMU_MAP_DMA, &map) == 0)) {
+        return 0;
     }
 
-    return 0;
+    DPRINTF("VFIO_MAP_DMA: %d\n", -errno);
+    return -errno;
 }
 
 static void vfio_listener_dummy1(MemoryListener *listener)
commit af6bc27e39fafadbc03c8876ffa95851c5869683
Author: Alex Williamson <alex.williamson at redhat.com>
Date:   Mon Oct 8 08:45:29 2012 -0600

    vfio-pci: Re-order map/unmap
    
    This cleans up the next patch that calls unmap from map.
    
    Signed-off-by: Alex Williamson <alex.williamson at redhat.com>

diff --git a/hw/vfio_pci.c b/hw/vfio_pci.c
index 7ec9c30..2d89d17 100644
--- a/hw/vfio_pci.c
+++ b/hw/vfio_pci.c
@@ -786,6 +786,24 @@ static void vfio_pci_write_config(PCIDevice *pdev, uint32_t addr,
 /*
  * DMA - Mapping and unmapping for the "type1" IOMMU interface used on x86
  */
+static int vfio_dma_unmap(VFIOContainer *container,
+                          target_phys_addr_t iova, ram_addr_t size)
+{
+    struct vfio_iommu_type1_dma_unmap unmap = {
+        .argsz = sizeof(unmap),
+        .flags = 0,
+        .iova = iova,
+        .size = size,
+    };
+
+    if (ioctl(container->fd, VFIO_IOMMU_UNMAP_DMA, &unmap)) {
+        DPRINTF("VFIO_UNMAP_DMA: %d\n", -errno);
+        return -errno;
+    }
+
+    return 0;
+}
+
 static int vfio_dma_map(VFIOContainer *container, target_phys_addr_t iova,
                         ram_addr_t size, void *vaddr, bool readonly)
 {
@@ -809,24 +827,6 @@ static int vfio_dma_map(VFIOContainer *container, target_phys_addr_t iova,
     return 0;
 }
 
-static int vfio_dma_unmap(VFIOContainer *container,
-                          target_phys_addr_t iova, ram_addr_t size)
-{
-    struct vfio_iommu_type1_dma_unmap unmap = {
-        .argsz = sizeof(unmap),
-        .flags = 0,
-        .iova = iova,
-        .size = size,
-    };
-
-    if (ioctl(container->fd, VFIO_IOMMU_UNMAP_DMA, &unmap)) {
-        DPRINTF("VFIO_UNMAP_DMA: %d\n", -errno);
-        return -errno;
-    }
-
-    return 0;
-}
-
 static void vfio_listener_dummy1(MemoryListener *listener)
 {
     /* We don't do batching (begin/commit) or care about logging */
commit ea486926b07d2ebd73ef67315ebb1eecf39faf5a
Author: Alex Williamson <alex.williamson at redhat.com>
Date:   Mon Oct 8 08:45:29 2012 -0600

    vfio-pci: Update slow path INTx algorithm
    
    We can't afford the overhead of switching out and back into mmap mode
    around each interrupt, but we can do it lazily via a timer.  On INTx
    interrupt, disable the mmap'd memory regions and set a timer.  On
    every interrupt, push the timer out.  If the timer expires and the
    interrupt is no longer pending, switch back to mmap mode.
    
    This has the benefit that things like graphics cards, which rarely or
    never, fire an interrupt don't need manual user intervention to add
    the x-intx=off parameter.  They'll just remain in mmap mode until they
    trigger an interrupt, and if they don't continue to regularly fire
    interrupts, they'll switch back.
    
    The default timeout is tuned for network cards so that a ping is just
    enough to keep them in non-mmap mode, where they have much better
    latency.  It is tunable with an experimental option,
    x-intx-mmap-timeout-ms.  A value of 0 keeps the device in non-mmap
    mode after the first interrupt.
    
    It's possible we could look at the class code of devices and come up
    with reasonable per-class defaults based on expected interrupt
    frequency and latency.  None of this is used for MSI interrupts and
    also won't be used if we can bypass through KVM.
    
    Signed-off-by: Alex Williamson <alex.williamson at redhat.com>

diff --git a/hw/vfio_pci.c b/hw/vfio_pci.c
index a1eeced..7ec9c30 100644
--- a/hw/vfio_pci.c
+++ b/hw/vfio_pci.c
@@ -92,6 +92,34 @@ static void vfio_unmask_intx(VFIODevice *vdev)
     ioctl(vdev->fd, VFIO_DEVICE_SET_IRQS, &irq_set);
 }
 
+/*
+ * Disabling BAR mmaping can be slow, but toggling it around INTx can
+ * also be a huge overhead.  We try to get the best of both worlds by
+ * waiting until an interrupt to disable mmaps (subsequent transitions
+ * to the same state are effectively no overhead).  If the interrupt has
+ * been serviced and the time gap is long enough, we re-enable mmaps for
+ * performance.  This works well for things like graphics cards, which
+ * may not use their interrupt at all and are penalized to an unusable
+ * level by read/write BAR traps.  Other devices, like NICs, have more
+ * regular interrupts and see much better latency by staying in non-mmap
+ * mode.  We therefore set the default mmap_timeout such that a ping
+ * is just enough to keep the mmap disabled.  Users can experiment with
+ * other options with the x-intx-mmap-timeout-ms parameter (a value of
+ * zero disables the timer).
+ */
+static void vfio_intx_mmap_enable(void *opaque)
+{
+    VFIODevice *vdev = opaque;
+
+    if (vdev->intx.pending) {
+        qemu_mod_timer(vdev->intx.mmap_timer,
+                       qemu_get_clock_ms(vm_clock) + vdev->intx.mmap_timeout);
+        return;
+    }
+
+    vfio_mmap_set_enabled(vdev, true);
+}
+
 static void vfio_intx_interrupt(void *opaque)
 {
     VFIODevice *vdev = opaque;
@@ -106,6 +134,11 @@ static void vfio_intx_interrupt(void *opaque)
 
     vdev->intx.pending = true;
     qemu_set_irq(vdev->pdev.irq[vdev->intx.pin], 1);
+    vfio_mmap_set_enabled(vdev, false);
+    if (vdev->intx.mmap_timeout) {
+        qemu_mod_timer(vdev->intx.mmap_timer,
+                       qemu_get_clock_ms(vm_clock) + vdev->intx.mmap_timeout);
+    }
 }
 
 static void vfio_eoi(VFIODevice *vdev)
@@ -141,7 +174,7 @@ static int vfio_enable_intx(VFIODevice *vdev)
     uint8_t pin = vfio_pci_read_config(&vdev->pdev, PCI_INTERRUPT_PIN, 1);
     int ret;
 
-    if (vdev->intx.disabled || !pin) {
+    if (!pin) {
         return 0;
     }
 
@@ -162,16 +195,6 @@ static int vfio_enable_intx(VFIODevice *vdev)
         return -errno;
     }
 
-    /*
-     * Disable mmaps so we can trap on BAR accesses.  We interpret any
-     * access as a response to an interrupt and unmask the physical
-     * device.  The device will re-assert if the interrupt is still
-     * pending.  We'll likely retrigger on the host multiple times per
-     * guest interrupt, but without EOI notification it's better than
-     * nothing.  Acceleration paths through KVM will avoid this.
-     */
-    vfio_mmap_set_enabled(vdev, false);
-
     vdev->interrupt = VFIO_INT_INTx;
 
     DPRINTF("%s(%04x:%02x:%02x.%x)\n", __func__, vdev->host.domain,
@@ -184,6 +207,7 @@ static void vfio_disable_intx(VFIODevice *vdev)
 {
     int fd;
 
+    qemu_del_timer(vdev->intx.mmap_timer);
     vfio_disable_irqindex(vdev, VFIO_PCI_INTX_IRQ_INDEX);
     vdev->intx.pending = false;
     qemu_set_irq(vdev->pdev.irq[vdev->intx.pin], 0);
@@ -1766,17 +1790,8 @@ static int vfio_initfn(PCIDevice *pdev)
     }
 
     if (vfio_pci_read_config(&vdev->pdev, PCI_INTERRUPT_PIN, 1)) {
-        if (vdev->intx.intx && strcmp(vdev->intx.intx, "off")) {
-            error_report("vfio: Unknown option x-intx=%s, "
-                         "valid options: \"off\".\n", vdev->intx.intx);
-            ret = -EINVAL;
-            goto out_teardown;
-        }
-
-        if (vdev->intx.intx && !strcmp(vdev->intx.intx, "off")) {
-            vdev->intx.disabled = true;
-        }
-
+        vdev->intx.mmap_timer = qemu_new_timer_ms(vm_clock,
+                                                  vfio_intx_mmap_enable, vdev);
         ret = vfio_enable_intx(vdev);
         if (ret) {
             goto out_teardown;
@@ -1802,6 +1817,9 @@ static void vfio_exitfn(PCIDevice *pdev)
 
     pci_device_set_intx_routing_notifier(&vdev->pdev, NULL);
     vfio_disable_interrupts(vdev);
+    if (vdev->intx.mmap_timer) {
+        qemu_free_timer(vdev->intx.mmap_timer);
+    }
     vfio_teardown_msi(vdev);
     vfio_unmap_bars(vdev);
     vfio_put_device(vdev);
@@ -1826,7 +1844,8 @@ static void vfio_pci_reset(DeviceState *dev)
 
 static Property vfio_pci_dev_properties[] = {
     DEFINE_PROP_PCI_HOST_DEVADDR("host", VFIODevice, host),
-    DEFINE_PROP_STRING("x-intx", VFIODevice, intx.intx),
+    DEFINE_PROP_UINT32("x-intx-mmap-timeout-ms", VFIODevice,
+                       intx.mmap_timeout, 1100),
     /*
      * TODO - support passed fds... is this necessary?
      * DEFINE_PROP_STRING("vfiofd", VFIODevice, vfiofd_name),
diff --git a/hw/vfio_pci_int.h b/hw/vfio_pci_int.h
index 3812d8d..e69bf5f 100644
--- a/hw/vfio_pci_int.h
+++ b/hw/vfio_pci_int.h
@@ -36,8 +36,8 @@ typedef struct VFIOINTx {
     EventNotifier interrupt; /* eventfd triggered on interrupt */
     EventNotifier unmask; /* eventfd for unmask on QEMU bypass */
     PCIINTxRoute route; /* routing info for QEMU bypass */
-    bool disabled;
-    char *intx;
+    uint32_t mmap_timeout; /* delay to re-enable mmaps after interrupt */
+    QEMUTimer *mmap_timer; /* enable mmaps after periods w/o interrupts */
 } VFIOINTx;
 
 struct VFIODevice;
commit a245fc18352fe286ba45ae0661a73b3841514889
Author: Paolo Bonzini <pbonzini at redhat.com>
Date:   Mon Sep 17 18:43:51 2012 +0200

    net: consolidate NetClientState header files into one
    
    This patch doesn't seem much useful alone, I must admit.  However,
    it makes sense as part of the upcoming directory reorganization,
    where I want to have include/net/tap.h as the net<->hw interface
    for tap.  Then having both net/tap.h and include/net/tap.h does
    not work.  "Fixed" by moving all the init functions to a single
    header file net/clients.h.
    
    The patch also adopts a uniform style for including net/*.h files
    from net/*.c, without the net/ path.
    
    Signed-off-by: Paolo Bonzini <pbonzini at redhat.com>
    Signed-off-by: Stefan Hajnoczi <stefanha at gmail.com>

diff --git a/net.c b/net.c
index a187a7b..ae4bc0d 100644
--- a/net.c
+++ b/net.c
@@ -21,17 +21,14 @@
  * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
  * THE SOFTWARE.
  */
-#include "net.h"
-
 #include "config-host.h"
 
-#include "net/tap.h"
-#include "net/socket.h"
-#include "net/dump.h"
-#include "net/slirp.h"
-#include "net/vde.h"
+#include "net.h"
+#include "net/clients.h"
 #include "net/hub.h"
+#include "net/slirp.h"
 #include "net/util.h"
+
 #include "monitor.h"
 #include "qemu-common.h"
 #include "qemu_socket.h"
diff --git a/net/clients.h b/net/clients.h
new file mode 100644
index 0000000..c58cc60
--- /dev/null
+++ b/net/clients.h
@@ -0,0 +1,55 @@
+/*
+ * QEMU System Emulator
+ *
+ * Copyright (c) 2003-2008 Fabrice Bellard
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+#ifndef QEMU_NET_CLIENTS_H
+#define QEMU_NET_CLIENTS_H
+
+#include "net.h"
+#include "qapi-types.h"
+
+int net_init_dump(const NetClientOptions *opts, const char *name,
+                  NetClientState *peer);
+
+#ifdef CONFIG_SLIRP
+int net_init_slirp(const NetClientOptions *opts, const char *name,
+                   NetClientState *peer);
+#endif
+
+int net_init_hubport(const NetClientOptions *opts, const char *name,
+                     NetClientState *peer);
+
+int net_init_socket(const NetClientOptions *opts, const char *name,
+                    NetClientState *peer);
+
+int net_init_tap(const NetClientOptions *opts, const char *name,
+                 NetClientState *peer);
+
+int net_init_bridge(const NetClientOptions *opts, const char *name,
+                    NetClientState *peer);
+
+#ifdef CONFIG_VDE
+int net_init_vde(const NetClientOptions *opts, const char *name,
+                 NetClientState *peer);
+#endif
+
+#endif /* QEMU_NET_CLIENTS_H */
diff --git a/net/dump.c b/net/dump.c
index 004231d..e0a5d74 100644
--- a/net/dump.c
+++ b/net/dump.c
@@ -22,7 +22,7 @@
  * THE SOFTWARE.
  */
 
-#include "dump.h"
+#include "clients.h"
 #include "qemu-common.h"
 #include "qemu-error.h"
 #include "qemu-log.h"
diff --git a/net/dump.h b/net/dump.h
deleted file mode 100644
index 33f152b..0000000
--- a/net/dump.h
+++ /dev/null
@@ -1,33 +0,0 @@
-/*
- * QEMU System Emulator
- *
- * Copyright (c) 2003-2008 Fabrice Bellard
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
- * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
- * THE SOFTWARE.
- */
-#ifndef QEMU_NET_DUMP_H
-#define QEMU_NET_DUMP_H
-
-#include "net.h"
-#include "qapi-types.h"
-
-int net_init_dump(const NetClientOptions *opts, const char *name,
-                  NetClientState *peer);
-
-#endif /* QEMU_NET_DUMP_H */
diff --git a/net/hub.c b/net/hub.c
index 650a8b4..be41301 100644
--- a/net/hub.c
+++ b/net/hub.c
@@ -14,6 +14,7 @@
 
 #include "monitor.h"
 #include "net.h"
+#include "clients.h"
 #include "hub.h"
 #include "iov.h"
 
diff --git a/net/hub.h b/net/hub.h
index 26a1ade..4cbfdb1 100644
--- a/net/hub.h
+++ b/net/hub.h
@@ -17,8 +17,6 @@
 
 #include "qemu-common.h"
 
-int net_init_hubport(const NetClientOptions *opts, const char *name,
-                     NetClientState *peer);
 NetClientState *net_hub_add_port(int hub_id, const char *name);
 NetClientState *net_hub_find_client_by_name(int hub_id, const char *name);
 void net_hub_info(Monitor *mon);
diff --git a/net/slirp.c b/net/slirp.c
index 8db66ea..bf86a44 100644
--- a/net/slirp.c
+++ b/net/slirp.c
@@ -30,7 +30,8 @@
 #include <sys/wait.h>
 #endif
 #include "net.h"
-#include "net/hub.h"
+#include "clients.h"
+#include "hub.h"
 #include "monitor.h"
 #include "qemu_socket.h"
 #include "slirp/libslirp.h"
diff --git a/net/slirp.h b/net/slirp.h
index 5f685c4..2ca09b6 100644
--- a/net/slirp.h
+++ b/net/slirp.h
@@ -31,9 +31,6 @@
 
 #ifdef CONFIG_SLIRP
 
-int net_init_slirp(const NetClientOptions *opts, const char *name,
-                   NetClientState *peer);
-
 void net_slirp_hostfwd_add(Monitor *mon, const QDict *qdict);
 void net_slirp_hostfwd_remove(Monitor *mon, const QDict *qdict);
 
diff --git a/net/socket.c b/net/socket.c
index f3d7878..b75d567 100644
--- a/net/socket.c
+++ b/net/socket.c
@@ -21,11 +21,10 @@
  * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
  * THE SOFTWARE.
  */
-#include "net/socket.h"
-
 #include "config-host.h"
 
 #include "net.h"
+#include "clients.h"
 #include "monitor.h"
 #include "qemu-char.h"
 #include "qemu-common.h"
diff --git a/net/socket.h b/net/socket.h
deleted file mode 100644
index 3f8a092..0000000
--- a/net/socket.h
+++ /dev/null
@@ -1,33 +0,0 @@
-/*
- * QEMU System Emulator
- *
- * Copyright (c) 2003-2008 Fabrice Bellard
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
- * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
- * THE SOFTWARE.
- */
-#ifndef QEMU_NET_SOCKET_H
-#define QEMU_NET_SOCKET_H
-
-#include "net.h"
-#include "qapi-types.h"
-
-int net_init_socket(const NetClientOptions *opts, const char *name,
-                    NetClientState *peer);
-
-#endif /* QEMU_NET_SOCKET_H */
diff --git a/net/tap-win32.c b/net/tap-win32.c
index c0ea954..f1801e2 100644
--- a/net/tap-win32.c
+++ b/net/tap-win32.c
@@ -26,7 +26,7 @@
  *  distribution); if not, see <http://www.gnu.org/licenses/>.
  */
 
-#include "net/tap.h"
+#include "tap.h"
 
 #include "qemu-common.h"
 #include "net.h"
diff --git a/net/tap.c b/net/tap.c
index a88ae8f..df89caa 100644
--- a/net/tap.c
+++ b/net/tap.c
@@ -23,7 +23,7 @@
  * THE SOFTWARE.
  */
 
-#include "net/tap.h"
+#include "tap.h"
 
 #include "config-host.h"
 
@@ -34,6 +34,7 @@
 #include <net/if.h>
 
 #include "net.h"
+#include "clients.h"
 #include "monitor.h"
 #include "sysemu.h"
 #include "qemu-char.h"
diff --git a/net/tap.h b/net/tap.h
index 0fb018c..d44d83a 100644
--- a/net/tap.h
+++ b/net/tap.h
@@ -32,9 +32,6 @@
 #define DEFAULT_NETWORK_SCRIPT "/etc/qemu-ifup"
 #define DEFAULT_NETWORK_DOWN_SCRIPT "/etc/qemu-ifdown"
 
-int net_init_tap(const NetClientOptions *opts, const char *name,
-                 NetClientState *peer);
-
 int tap_open(char *ifname, int ifname_size, int *vnet_hdr, int vnet_hdr_required);
 
 ssize_t tap_read_packet(int tapfd, uint8_t *buf, int maxlen);
@@ -58,7 +55,4 @@ int tap_get_fd(NetClientState *nc);
 struct vhost_net;
 struct vhost_net *tap_get_vhost_net(NetClientState *nc);
 
-int net_init_bridge(const NetClientOptions *opts, const char *name,
-                    NetClientState *peer);
-
 #endif /* QEMU_NET_TAP_H */
diff --git a/net/vde.c b/net/vde.c
index b91a6c7..275bda9 100644
--- a/net/vde.c
+++ b/net/vde.c
@@ -21,13 +21,12 @@
  * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
  * THE SOFTWARE.
  */
-#include "net/vde.h"
-
 #include "config-host.h"
 
 #include <libvdeplug.h>
 
 #include "net.h"
+#include "clients.h"
 #include "qemu-char.h"
 #include "qemu-common.h"
 #include "qemu-option.h"
diff --git a/net/vde.h b/net/vde.h
deleted file mode 100644
index 6ce6698..0000000
--- a/net/vde.h
+++ /dev/null
@@ -1,37 +0,0 @@
-/*
- * QEMU System Emulator
- *
- * Copyright (c) 2003-2008 Fabrice Bellard
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
- * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
- * THE SOFTWARE.
- */
-#ifndef QEMU_NET_VDE_H
-#define QEMU_NET_VDE_H
-
-#include "qemu-common.h"
-#include "qapi-types.h"
-
-#ifdef CONFIG_VDE
-
-int net_init_vde(const NetClientOptions *opts, const char *name,
-                 NetClientState *peer);
-
-#endif /* CONFIG_VDE */
-
-#endif /* QEMU_NET_VDE_H */
commit 9899148110627da388f82c02997bca6d678d1aa1
Author: Amos Kong <akong at redhat.com>
Date:   Fri Sep 28 10:06:02 2012 +0800

    virtio-net: update nc.link_down in virtio_net_load()
    
    nc.link_down could not be migrated, this patch updates link_down in
    virtio_post_load() to keep it coincident with real link status.
    
    Signed-off-by: Amos Kong <akong at redhat.com>
    Signed-off-by: Stefan Hajnoczi <stefanha at gmail.com>

diff --git a/hw/virtio-net.c b/hw/virtio-net.c
index 247d7be..8342391 100644
--- a/hw/virtio-net.c
+++ b/hw/virtio-net.c
@@ -973,6 +973,11 @@ static int virtio_net_load(QEMUFile *f, void *opaque, int version_id)
         }
     }
     n->mac_table.first_multi = i;
+
+    /* nc.link_down can't be migrated, so infer link_down according
+     * to link status bit in n->status */
+    n->nic->nc.link_down = (n->status & VIRTIO_NET_S_LINK_UP) == 0;
+
     return 0;
 }
 
commit e4b823644044de1b8070fde82d0aad8053dc3333
Author: Amos Kong <akong at redhat.com>
Date:   Fri Sep 28 10:06:01 2012 +0800

    e1000: update nc.link_down in e1000_post_load()
    
    This patch introduced e1000_post_load(), it will be called in the end of
    migration. nc.link_down could not be migrated, this patch updates
    link_down in e1000_post_load() to keep it coincident with real link
    status.
    
    Signed-off-by: Amos Kong <akong at redhat.com>
    Signed-off-by: Stefan Hajnoczi <stefanha at gmail.com>

diff --git a/hw/e1000.c b/hw/e1000.c
index ec3a7c4..63fee10 100644
--- a/hw/e1000.c
+++ b/hw/e1000.c
@@ -1079,11 +1079,23 @@ static bool is_version_1(void *opaque, int version_id)
     return version_id == 1;
 }
 
+static int e1000_post_load(void *opaque, int version_id)
+{
+    E1000State *s = opaque;
+
+    /* nc.link_down can't be migrated, so infer link_down according
+     * to link status bit in mac_reg[STATUS] */
+    s->nic->nc.link_down = (s->mac_reg[STATUS] & E1000_STATUS_LU) == 0;
+
+    return 0;
+}
+
 static const VMStateDescription vmstate_e1000 = {
     .name = "e1000",
     .version_id = 2,
     .minimum_version_id = 1,
     .minimum_version_id_old = 1,
+    .post_load = e1000_post_load,
     .fields      = (VMStateField []) {
         VMSTATE_PCI_DEVICE(dev, E1000State),
         VMSTATE_UNUSED_TEST(is_version_1, 4), /* was instance id */
commit 9e12c5aff2cfdd1574bf732c4bbf579d0c2e85c1
Author: Jason Wang <jasowang at redhat.com>
Date:   Fri Sep 28 10:06:00 2012 +0800

    rtl8139: implement 8139cp link status
    
    Add a link status chang callback and change the link status bit in BMSR
    & MSR accordingly. Tested in Linux/Windows guests.
    
    The link status bit of MediaStatus is infered from BasicModeStatus,
    they are inverse.
    
    nc.link_down could not be migrated, this patch updates link_down in
    rtl8139_post_load() to keep it coincident with real link status.
    
    Signed-off-by: Jason Wang <jasowang at redhat.com>
    Signed-off-by: Amos Kong <akong at redhat.com>
    Signed-off-by: Stefan Hajnoczi <stefanha at gmail.com>

diff --git a/hw/rtl8139.c b/hw/rtl8139.c
index b7c82ee..6b28fea 100644
--- a/hw/rtl8139.c
+++ b/hw/rtl8139.c
@@ -167,7 +167,7 @@ enum IntrStatusBits {
     PCIErr = 0x8000,
     PCSTimeout = 0x4000,
     RxFIFOOver = 0x40,
-    RxUnderrun = 0x20,
+    RxUnderrun = 0x20, /* Packet Underrun / Link Change */
     RxOverflow = 0x10,
     TxErr = 0x08,
     TxOK = 0x04,
@@ -3003,7 +3003,8 @@ static uint32_t rtl8139_io_readb(void *opaque, uint8_t addr)
             break;
 
         case MediaStatus:
-            ret = 0xd0;
+            /* The LinkDown bit of MediaStatus is inverse with link status */
+            ret = 0xd0 | (~s->BasicModeStatus & 0x04);
             DPRINTF("MediaStatus read 0x%x\n", ret);
             break;
 
@@ -3258,6 +3259,10 @@ static int rtl8139_post_load(void *opaque, int version_id)
         s->cplus_enabled = s->CpCmd != 0;
     }
 
+    /* nc.link_down can't be migrated, so infer link_down according
+     * to link status bit in BasicModeStatus */
+    s->nic->nc.link_down = (s->BasicModeStatus & 0x04) == 0;
+
     return 0;
 }
 
@@ -3449,12 +3454,27 @@ static void pci_rtl8139_uninit(PCIDevice *dev)
     qemu_del_net_client(&s->nic->nc);
 }
 
+static void rtl8139_set_link_status(NetClientState *nc)
+{
+    RTL8139State *s = DO_UPCAST(NICState, nc, nc)->opaque;
+
+    if (nc->link_down) {
+        s->BasicModeStatus &= ~0x04;
+    } else {
+        s->BasicModeStatus |= 0x04;
+    }
+
+    s->IntrStatus |= RxUnderrun;
+    rtl8139_update_irq(s);
+}
+
 static NetClientInfo net_rtl8139_info = {
     .type = NET_CLIENT_OPTIONS_KIND_NIC,
     .size = sizeof(NICState),
     .can_receive = rtl8139_can_receive,
     .receive = rtl8139_receive,
     .cleanup = rtl8139_cleanup,
+    .link_status_changed = rtl8139_set_link_status,
 };
 
 static int pci_rtl8139_init(PCIDevice *dev)
commit 591af14359f698d89cd334622237a20f19ae7060
Author: Gerd Hoffmann <kraxel at redhat.com>
Date:   Mon Oct 8 10:05:22 2012 +0200

    qxl: set default revision to 4
    
    Set qxl pci revision to 4 (for pc-1.3+) so guests know
    spice-server 0.12 features are available.
    
    Signed-off-by: Gerd Hoffmann <kraxel at redhat.com>

diff --git a/hw/pc_piix.c b/hw/pc_piix.c
index fd5898f..82364ab 100644
--- a/hw/pc_piix.c
+++ b/hw/pc_piix.c
@@ -371,6 +371,14 @@ static QEMUMachine pc_machine_v1_3 = {
             .driver   = "ivshmem",\
             .property = "use64",\
             .value    = "0",\
+        },{\
+            .driver   = "qxl",\
+            .property = "revision",\
+            .value    = stringify(3),\
+        },{\
+            .driver   = "qxl-vga",\
+            .property = "revision",\
+            .value    = stringify(3),\
         }
 
 static QEMUMachine pc_machine_v1_2 = {
diff --git a/hw/qxl.h b/hw/qxl.h
index 5553824..e583cfb 100644
--- a/hw/qxl.h
+++ b/hw/qxl.h
@@ -129,12 +129,7 @@ typedef struct PCIQXLDevice {
         }                                                               \
     } while (0)
 
-#if 0
-/* spice-server 0.12 is still in development */
 #define QXL_DEFAULT_REVISION QXL_REVISION_STABLE_V12
-#else
-#define QXL_DEFAULT_REVISION QXL_REVISION_STABLE_V10
-#endif
 
 /* qxl.c */
 void *qxl_phys2virt(PCIQXLDevice *qxl, QXLPHYSICAL phys, int group_id);
commit 67be6726b6459472103ee87ceaf2e8e97c154965
Author: Gerd Hoffmann <kraxel at redhat.com>
Date:   Mon Sep 24 10:23:40 2012 +0200

    spice: raise requirement to 0.12
    
    With the next qemu version (1.3) we are going to bump the qxl device
    revision to 4.  The new features available require a recent spice-server
    version, so raise up the bar.  Otherwise we would end up with different
    qxl revisions depending on the spice-server version installed, which
    would be a major PITA when it comes to compat properties.
    
    Clear out a big bunch of #ifdefs which are not needed any more.
    
    Signed-off-by: Gerd Hoffmann <kraxel at redhat.com>

diff --git a/configure b/configure
index c4a7837..c0226fc 100755
--- a/configure
+++ b/configure
@@ -2716,20 +2716,14 @@ int main(void) { spice_server_new(); return 0; }
 EOF
   spice_cflags=$($pkg_config --cflags spice-protocol spice-server 2>/dev/null)
   spice_libs=$($pkg_config --libs spice-protocol spice-server 2>/dev/null)
-  if $pkg_config --atleast-version=0.8.2 spice-server >/dev/null 2>&1 && \
-     $pkg_config --atleast-version=0.8.1 spice-protocol > /dev/null 2>&1 && \
+  if $pkg_config --atleast-version=0.12.0 spice-server >/dev/null 2>&1 && \
+     $pkg_config --atleast-version=0.12.2 spice-protocol > /dev/null 2>&1 && \
      compile_prog "$spice_cflags" "$spice_libs" ; then
     spice="yes"
     libs_softmmu="$libs_softmmu $spice_libs"
     QEMU_CFLAGS="$QEMU_CFLAGS $spice_cflags"
     spice_protocol_version=$($pkg_config --modversion spice-protocol)
     spice_server_version=$($pkg_config --modversion spice-server)
-    if $pkg_config --atleast-version=0.12.0 spice-protocol >/dev/null 2>&1; then
-        spice_qxl_io_monitors_config_async="yes"
-    fi
-    if $pkg_config --atleast-version=0.12.2 spice-protocol > /dev/null 2>&1; then
-        spice_qxl_client_monitors_config="yes"
-    fi
   else
     if test "$spice" = "yes" ; then
       feature_not_found "spice"
@@ -3474,14 +3468,6 @@ if test "$spice" = "yes" ; then
   echo "CONFIG_SPICE=y" >> $config_host_mak
 fi
 
-if test "$spice_qxl_io_monitors_config_async" = "yes" ; then
-  echo "CONFIG_QXL_IO_MONITORS_CONFIG_ASYNC=y" >> $config_host_mak
-fi
-
-if test "$spice_qxl_client_monitors_config" = "yes" ; then
-  echo "CONFIG_QXL_CLIENT_MONITORS_CONFIG=y" >> $config_host_mak
-fi
-
 if test "$smartcard" = "yes" ; then
   echo "CONFIG_SMARTCARD=y" >> $config_host_mak
 fi
diff --git a/hw/qxl.c b/hw/qxl.c
index c246147..1d16863 100644
--- a/hw/qxl.c
+++ b/hw/qxl.c
@@ -29,11 +29,6 @@
 
 #include "qxl.h"
 
-#ifndef CONFIG_QXL_IO_MONITORS_CONFIG_ASYNC
-/* spice-protocol is too old, add missing definitions */
-#define QXL_IO_MONITORS_CONFIG_ASYNC (QXL_IO_FLUSH_RELEASE + 1)
-#endif
-
 /*
  * NOTE: SPICE_RING_PROD_ITEM accesses memory on the pci bar and as
  * such can be changed by the guest, so to avoid a guest trigerrable
@@ -262,9 +257,6 @@ static void qxl_spice_destroy_surfaces(PCIQXLDevice *qxl, qxl_async_io async)
 static void qxl_spice_monitors_config_async(PCIQXLDevice *qxl, int replay)
 {
     trace_qxl_spice_monitors_config(qxl->id);
-/* 0x000b01 == 0.11.1 */
-#if SPICE_SERVER_VERSION >= 0x000b01 && \
-    defined(CONFIG_QXL_IO_MONITORS_CONFIG_ASYNC)
     if (replay) {
         /*
          * don't use QXL_COOKIE_TYPE_IO:
@@ -286,10 +278,6 @@ static void qxl_spice_monitors_config_async(PCIQXLDevice *qxl, int replay)
                 (uintptr_t)qxl_cookie_new(QXL_COOKIE_TYPE_IO,
                                           QXL_IO_MONITORS_CONFIG_ASYNC));
     }
-#else
-    fprintf(stderr, "qxl: too old spice-protocol/spice-server for "
-            "QXL_IO_MONITORS_CONFIG_ASYNC\n");
-#endif
 }
 
 void qxl_spice_reset_image_cache(PCIQXLDevice *qxl)
@@ -948,8 +936,6 @@ static void interface_async_complete(QXLInstance *sin, uint64_t cookie_token)
     }
 }
 
-#if SPICE_SERVER_VERSION >= 0x000b04
-
 /* called from spice server thread context only */
 static void interface_set_client_capabilities(QXLInstance *sin,
                                               uint8_t client_present,
@@ -971,11 +957,6 @@ static void interface_set_client_capabilities(QXLInstance *sin,
     qxl_send_events(qxl, QXL_INTERRUPT_CLIENT);
 }
 
-#endif
-
-#if defined(CONFIG_QXL_CLIENT_MONITORS_CONFIG) \
-    && SPICE_SERVER_VERSION >= 0x000b05
-
 static uint32_t qxl_crc32(const uint8_t *p, unsigned len)
 {
     /*
@@ -1044,7 +1025,6 @@ static int interface_client_monitors_config(QXLInstance *sin,
     qxl_send_events(qxl, QXL_INTERRUPT_CLIENT_MONITORS_CONFIG);
     return 1;
 }
-#endif
 
 static const QXLInterface qxl_interface = {
     .base.type               = SPICE_INTERFACE_QXL,
@@ -1067,13 +1047,8 @@ static const QXLInterface qxl_interface = {
     .flush_resources         = interface_flush_resources,
     .async_complete          = interface_async_complete,
     .update_area_complete    = interface_update_area_complete,
-#if SPICE_SERVER_VERSION >= 0x000b04
     .set_client_capabilities = interface_set_client_capabilities,
-#endif
-#if SPICE_SERVER_VERSION >= 0x000b05 && \
-    defined(CONFIG_QXL_CLIENT_MONITORS_CONFIG)
     .client_monitors_config = interface_client_monitors_config,
-#endif
 };
 
 static void qxl_enter_vga_mode(PCIQXLDevice *d)
@@ -1847,7 +1822,6 @@ static void qxl_vm_change_state_handler(void *opaque, int running,
                                         RunState state)
 {
     PCIQXLDevice *qxl = opaque;
-    qemu_spice_vm_change_state_handler(&qxl->ssd, running, state);
 
     if (running) {
         /*
@@ -1964,14 +1938,10 @@ static int qxl_init_common(PCIQXLDevice *qxl)
         pci_device_rev = QXL_REVISION_STABLE_V10;
         io_size = 32; /* PCI region size must be pow2 */
         break;
-/* 0x000b01 == 0.11.1 */
-#if SPICE_SERVER_VERSION >= 0x000b01 && \
-        defined(CONFIG_QXL_IO_MONITORS_CONFIG_ASYNC)
     case 4: /* qxl-4 */
         pci_device_rev = QXL_REVISION_STABLE_V12;
         io_size = msb_mask(QXL_IO_RANGE_SIZE * 2 - 1);
         break;
-#endif
     default:
         error_report("Invalid revision %d for qxl device (max %d)",
                      qxl->revision, QXL_DEFAULT_REVISION);
diff --git a/ui/spice-core.c b/ui/spice-core.c
index ba0d0bd..5147365 100644
--- a/ui/spice-core.c
+++ b/ui/spice-core.c
@@ -223,7 +223,6 @@ static void channel_event(int event, SpiceChannelEventInfo *info)
     client = qdict_new();
     server = qdict_new();
 
-#ifdef SPICE_CHANNEL_EVENT_FLAG_ADDR_EXT
     if (info->flags & SPICE_CHANNEL_EVENT_FLAG_ADDR_EXT) {
         add_addr_info(client, (struct sockaddr *)&info->paddr_ext,
                       info->plen_ext);
@@ -232,12 +231,7 @@ static void channel_event(int event, SpiceChannelEventInfo *info)
     } else {
         error_report("spice: %s, extended address is expected",
                      __func__);
-#endif
-        add_addr_info(client, &info->paddr, info->plen);
-        add_addr_info(server, &info->laddr, info->llen);
-#ifdef SPICE_CHANNEL_EVENT_FLAG_ADDR_EXT
     }
-#endif
 
     if (event == SPICE_CHANNEL_EVENT_INITIALIZED) {
         qdict_put(server, "auth", qstring_from_str(auth));
@@ -276,7 +270,6 @@ static SpiceCoreInterface core_interface = {
     .channel_event      = channel_event,
 };
 
-#ifdef SPICE_INTERFACE_MIGRATION
 typedef struct SpiceMigration {
     SpiceMigrateInstance sin;
     struct {
@@ -313,7 +306,6 @@ static void migrate_end_complete_cb(SpiceMigrateInstance *sin)
     monitor_protocol_event(QEVENT_SPICE_MIGRATE_COMPLETED, NULL);
     spice_migration_completed = true;
 }
-#endif
 
 /* config string parsing */
 
@@ -393,17 +385,13 @@ static SpiceChannelList *qmp_query_spice_channels(void)
         chan = g_malloc0(sizeof(*chan));
         chan->value = g_malloc0(sizeof(*chan->value));
 
-#ifdef SPICE_CHANNEL_EVENT_FLAG_ADDR_EXT
         if (item->info->flags & SPICE_CHANNEL_EVENT_FLAG_ADDR_EXT) {
             paddr = (struct sockaddr *)&item->info->paddr_ext;
             plen = item->info->plen_ext;
         } else {
-#endif
             paddr = &item->info->paddr;
             plen = item->info->plen;
-#ifdef SPICE_CHANNEL_EVENT_FLAG_ADDR_EXT
         }
-#endif
 
         getnameinfo(paddr, plen,
                     host, sizeof(host), port, sizeof(port),
@@ -473,13 +461,10 @@ SpiceInfo *qmp_query_spice(Error **errp)
         info->tls_port = tls_port;
     }
 
-#if SPICE_SERVER_VERSION >= 0x000a03 /* 0.10.3 */
     info->mouse_mode = spice_server_is_server_mouse(spice_server) ?
                        SPICE_QUERY_MOUSE_MODE_SERVER :
                        SPICE_QUERY_MOUSE_MODE_CLIENT;
-#else
-    info->mouse_mode = SPICE_QUERY_MOUSE_MODE_UNKNOWN;
-#endif
+
     /* for compatibility with the original command */
     info->has_channels = true;
     info->channels = qmp_query_spice_channels();
@@ -492,19 +477,11 @@ static void migration_state_notifier(Notifier *notifier, void *data)
     MigrationState *s = data;
 
     if (migration_is_active(s)) {
-#ifdef SPICE_INTERFACE_MIGRATION
         spice_server_migrate_start(spice_server);
-#endif
     } else if (migration_has_finished(s)) {
-#ifndef SPICE_INTERFACE_MIGRATION
-        spice_server_migrate_switch(spice_server);
-        monitor_protocol_event(QEVENT_SPICE_MIGRATE_COMPLETED, NULL);
-        spice_migration_completed = true;
-#else
         spice_server_migrate_end(spice_server, true);
     } else if (migration_has_failed(s)) {
         spice_server_migrate_end(spice_server, false);
-#endif
     }
 }
 
@@ -513,16 +490,11 @@ int qemu_spice_migrate_info(const char *hostname, int port, int tls_port,
                             MonitorCompletion *cb, void *opaque)
 {
     int ret;
-#ifdef SPICE_INTERFACE_MIGRATION
+
     spice_migrate.connect_complete.cb = cb;
     spice_migrate.connect_complete.opaque = opaque;
     ret = spice_server_migrate_connect(spice_server, hostname,
                                        port, tls_port, subject);
-#else
-    ret = spice_server_migrate_info(spice_server, hostname,
-                                    port, tls_port, subject);
-    cb(opaque, NULL);
-#endif
     return ret;
 }
 
@@ -561,7 +533,6 @@ static int add_channel(const char *name, const char *value, void *opaque)
 static void vm_change_state_handler(void *opaque, int running,
                                     RunState state)
 {
-#if SPICE_SERVER_VERSION >= 0x000b02 /* 0.11.2 */
     if (running) {
         qemu_spice_display_start();
         spice_server_vm_start(spice_server);
@@ -569,7 +540,6 @@ static void vm_change_state_handler(void *opaque, int running,
         spice_server_vm_stop(spice_server);
         qemu_spice_display_stop();
     }
-#endif
 }
 
 void qemu_spice_init(void)
@@ -585,9 +555,7 @@ void qemu_spice_init(void)
     int port, tls_port, len, addr_flags;
     spice_image_compression_t compression;
     spice_wan_compression_t wan_compr;
-#if SPICE_SERVER_VERSION >= 0x000b02 /* 0.11.2 */
     bool seamless_migration;
-#endif
 
     qemu_thread_get_self(&me);
 
@@ -672,16 +640,11 @@ void qemu_spice_init(void)
         spice_server_set_ticket(spice_server, password, 0, 0, 0);
     }
     if (qemu_opt_get_bool(opts, "sasl", 0)) {
-#if SPICE_SERVER_VERSION >= 0x000900 /* 0.9.0 */
         if (spice_server_set_sasl_appname(spice_server, "qemu") == -1 ||
             spice_server_set_sasl(spice_server, 1) == -1) {
             error_report("spice: failed to enable sasl");
             exit(1);
         }
-#else
-        error_report("spice: sasl is not available (spice >= 0.9 required)");
-        exit(1);
-#endif
     }
     if (qemu_opt_get_bool(opts, "disable-ticketing", 0)) {
         auth = "none";
@@ -726,15 +689,11 @@ void qemu_spice_init(void)
 
     qemu_opt_foreach(opts, add_channel, &tls_port, 0);
 
-#if SPICE_SERVER_VERSION >= 0x000a02 /* 0.10.2 */
     spice_server_set_name(spice_server, qemu_name);
     spice_server_set_uuid(spice_server, qemu_uuid);
-#endif
 
-#if SPICE_SERVER_VERSION >= 0x000b02 /* 0.11.2 */
     seamless_migration = qemu_opt_get_bool(opts, "seamless-migration", 0);
     spice_server_set_seamless_migration(spice_server, seamless_migration);
-#endif
     if (0 != spice_server_init(spice_server, &core_interface)) {
         error_report("failed to initialize spice server");
         exit(1);
@@ -743,11 +702,9 @@ void qemu_spice_init(void)
 
     migration_state.notify = migration_state_notifier;
     add_migration_state_change_notifier(&migration_state);
-#ifdef SPICE_INTERFACE_MIGRATION
     spice_migrate.sin.base.sif = &migrate_interface.base;
     spice_migrate.connect_complete.cb = NULL;
     qemu_spice_add_interface(&spice_migrate.sin.base);
-#endif
 
     qemu_spice_input_init();
     qemu_spice_audio_init();
@@ -815,15 +772,11 @@ int qemu_spice_set_pw_expire(time_t expires)
 
 int qemu_spice_display_add_client(int csock, int skipauth, int tls)
 {
-#if SPICE_SERVER_VERSION >= 0x000a01
     if (tls) {
         return spice_server_add_ssl_client(spice_server, csock, skipauth);
     } else {
         return spice_server_add_client(spice_server, csock, skipauth);
     }
-#else
-    return -1;
-#endif
 }
 
 static void spice_register_config(void)
diff --git a/ui/spice-display.c b/ui/spice-display.c
index 50fbefb..b61764f 100644
--- a/ui/spice-display.c
+++ b/ui/spice-display.c
@@ -126,21 +126,6 @@ void qemu_spice_wakeup(SimpleSpiceDisplay *ssd)
     ssd->worker->wakeup(ssd->worker);
 }
 
-#if SPICE_SERVER_VERSION < 0x000b02 /* before 0.11.2 */
-static void qemu_spice_start(SimpleSpiceDisplay *ssd)
-{
-    trace_qemu_spice_start(ssd->qxl.id);
-    ssd->worker->start(ssd->worker);
-}
-
-static void qemu_spice_stop(SimpleSpiceDisplay *ssd)
-{
-    trace_qemu_spice_stop(ssd->qxl.id);
-    ssd->worker->stop(ssd->worker);
-}
-
-#else
-
 static int spice_display_is_running;
 
 void qemu_spice_display_start(void)
@@ -153,15 +138,9 @@ void qemu_spice_display_stop(void)
     spice_display_is_running = false;
 }
 
-#endif
-
 int qemu_spice_display_is_running(SimpleSpiceDisplay *ssd)
 {
-#if SPICE_SERVER_VERSION < 0x000b02 /* before 0.11.2 */
-    return ssd->running;
-#else
     return spice_display_is_running;
-#endif
 }
 
 static void qemu_spice_create_one_update(SimpleSpiceDisplay *ssd,
@@ -364,22 +343,6 @@ void qemu_spice_destroy_host_primary(SimpleSpiceDisplay *ssd)
     qemu_spice_destroy_primary_surface(ssd, 0, QXL_SYNC);
 }
 
-void qemu_spice_vm_change_state_handler(void *opaque, int running,
-                                        RunState state)
-{
-#if SPICE_SERVER_VERSION < 0x000b02 /* before 0.11.2 */
-    SimpleSpiceDisplay *ssd = opaque;
-
-    if (running) {
-        ssd->running = true;
-        qemu_spice_start(ssd);
-    } else {
-        qemu_spice_stop(ssd);
-        ssd->running = false;
-    }
-#endif
-}
-
 void qemu_spice_display_init_common(SimpleSpiceDisplay *ssd, DisplayState *ds)
 {
     ssd->ds = ds;
@@ -623,7 +586,6 @@ void qemu_spice_display_init(DisplayState *ds)
     qemu_spice_add_interface(&sdpy.qxl.base);
     assert(sdpy.worker);
 
-    qemu_add_vm_change_state_handler(qemu_spice_vm_change_state_handler, &sdpy);
     qemu_spice_create_host_memslot(&sdpy);
     qemu_spice_create_host_primary(&sdpy);
 }
diff --git a/ui/spice-display.h b/ui/spice-display.h
index dea41c1..d766927 100644
--- a/ui/spice-display.h
+++ b/ui/spice-display.h
@@ -83,9 +83,6 @@ struct SimpleSpiceDisplay {
 
     QXLRect dirty;
     int notify;
-#if SPICE_SERVER_VERSION < 0x000b02 /* before 0.11.2 */
-    int running;
-#endif
 
     /*
      * All struct members below this comment can be accessed from
@@ -133,8 +130,6 @@ void qemu_spice_create_primary_surface(SimpleSpiceDisplay *ssd, uint32_t id,
 void qemu_spice_destroy_primary_surface(SimpleSpiceDisplay *ssd,
                                         uint32_t id, qxl_async_io async);
 void qemu_spice_wakeup(SimpleSpiceDisplay *ssd);
-#if SPICE_SERVER_VERSION >= 0x000b02 /* before 0.11.2 */
 void qemu_spice_display_start(void);
 void qemu_spice_display_stop(void);
-#endif
 int qemu_spice_display_is_running(SimpleSpiceDisplay *ssd);
commit c5825ac6c861bfe1a4adfa27517931b56079e298
Author: Alon Levy <alevy at redhat.com>
Date:   Sun Oct 7 17:03:35 2012 +0200

    hw/qxl: qxl_dirty_surfaces: use uintptr_t
    
    As suggested by Paolo Bonzini, to avoid possible integer overflow issues.
    
    Signed-off-by: Alon Levy <alevy at redhat.com>
    Signed-off-by: Gerd Hoffmann <kraxel at redhat.com>

diff --git a/hw/qxl.c b/hw/qxl.c
index 772b6c0..c246147 100644
--- a/hw/qxl.c
+++ b/hw/qxl.c
@@ -1804,7 +1804,7 @@ static void qxl_hw_text_update(void *opaque, console_ch_t *chardata)
 
 static void qxl_dirty_surfaces(PCIQXLDevice *qxl)
 {
-    intptr_t vram_start;
+    uintptr_t vram_start;
     int i;
 
     if (qxl->mode != QXL_MODE_NATIVE && qxl->mode != QXL_MODE_COMPAT) {
@@ -1815,7 +1815,7 @@ static void qxl_dirty_surfaces(PCIQXLDevice *qxl)
     qxl_set_dirty(&qxl->vga.vram, qxl->shadow_rom.draw_area_offset,
                   qxl->shadow_rom.surface0_area_size);
 
-    vram_start =  (intptr_t)memory_region_get_ram_ptr(&qxl->vram_bar);
+    vram_start = (uintptr_t)memory_region_get_ram_ptr(&qxl->vram_bar);
 
     /* dirty the off-screen surfaces */
     for (i = 0; i < qxl->ssd.num_surfaces; i++) {
commit d96aafca057845a4d58cd7b36771f2c97c78cd56
Author: Alon Levy <alevy at redhat.com>
Date:   Tue Oct 2 11:39:14 2012 +0200

    hw/qxl: fix condition for exiting guest_bug
    
    Reported and suggested by Paolo Bonzini, thanks.
    
    Signed-off-by: Alon Levy <alevy at redhat.com>
    Signed-off-by: Gerd Hoffmann <kraxel at redhat.com>

diff --git a/hw/qxl.c b/hw/qxl.c
index e99ed55..772b6c0 100644
--- a/hw/qxl.c
+++ b/hw/qxl.c
@@ -1461,7 +1461,7 @@ static void ioport_write(void *opaque, target_phys_addr_t addr,
     qxl_async_io async = QXL_SYNC;
     uint32_t orig_io_port = io_port;
 
-    if (d->guest_bug && !io_port == QXL_IO_RESET) {
+    if (d->guest_bug && io_port != QXL_IO_RESET) {
         return;
     }
 
commit e25a0651f4be22099122b5e14c77c354be0aa88b
Author: Alon Levy <alevy at redhat.com>
Date:   Wed Oct 3 20:13:58 2012 +0200

    hw/qxl: exit on failure to register qxl interface
    
    This prevents a segfault later on when the device reset handler
    tries to access a NULL ssd.worker since interface_attach_worker has
    not been called.
    
    Signed-off-by: Alon Levy <alevy at redhat.com>
    Signed-off-by: Gerd Hoffmann <kraxel at redhat.com>

diff --git a/hw/qxl.c b/hw/qxl.c
index eb7707c..e99ed55 100644
--- a/hw/qxl.c
+++ b/hw/qxl.c
@@ -2037,7 +2037,11 @@ static int qxl_init_common(PCIQXLDevice *qxl)
 
     qxl->ssd.qxl.base.sif = &qxl_interface.base;
     qxl->ssd.qxl.id = qxl->id;
-    qemu_spice_add_interface(&qxl->ssd.qxl.base);
+    if (qemu_spice_add_interface(&qxl->ssd.qxl.base) != 0) {
+        error_report("qxl interface %d.%d not supported by spice-server\n",
+                     SPICE_INTERFACE_QXL_MAJOR, SPICE_INTERFACE_QXL_MINOR);
+        return -1;
+    }
     qemu_add_vm_change_state_handler(qxl_vm_change_state_handler, qxl);
 
     init_pipe_signaling(qxl);
commit ffe01e599f106bedf13ba0e0f6956735b1942a0c
Author: Gerd Hoffmann <kraxel at redhat.com>
Date:   Tue Sep 25 13:56:40 2012 +0200

    qxl: fix range check for rev3 io commands.
    
    Enables QXL_IO_FLUSH_SURFACES_ASYNC and QXL_IO_FLUSH_RELEASE
    which are part of the qxl rev3 feature set.
    
    Signed-off-by: Gerd Hoffmann <kraxel at redhat.com>

diff --git a/hw/qxl.c b/hw/qxl.c
index 3c82c2a..eb7707c 100644
--- a/hw/qxl.c
+++ b/hw/qxl.c
@@ -1466,7 +1466,7 @@ static void ioport_write(void *opaque, target_phys_addr_t addr,
     }
 
     if (d->revision <= QXL_REVISION_STABLE_V10 &&
-        io_port >= QXL_IO_FLUSH_SURFACES_ASYNC) {
+        io_port > QXL_IO_FLUSH_RELEASE) {
         qxl_set_guest_bug(d, "unsupported io %d for revision %d\n",
             io_port, d->revision);
         return;
commit 36a03e0ba5202cf49749b2128bb62d41983681d6
Author: Michael Tokarev <mjt at tls.msk.ru>
Date:   Wed Sep 19 17:41:26 2012 +0400

    qxl/update_area_io: cleanup invalid parameters handling
    
    This cleans up two additions of almost the same code in commits
    511b13e2c9 and ccc2960d654.  While at it, make error paths
    consistent (always use 'break' instead of 'return').
    
    Signed-off-by: Michael Tokarev <mjt at tls.msk.ru>
    Cc: Dunrong Huang <riegamaths at gmail.com>
    Cc: Alon Levy <alevy at redhat.com>
    Signed-off-by: Gerd Hoffmann <kraxel at redhat.com>

diff --git a/hw/qxl.c b/hw/qxl.c
index 33169f3..3c82c2a 100644
--- a/hw/qxl.c
+++ b/hw/qxl.c
@@ -1547,20 +1547,13 @@ async_common:
         if (d->ram->update_surface > d->ssd.num_surfaces) {
             qxl_set_guest_bug(d, "QXL_IO_UPDATE_AREA: invalid surface id %d\n",
                               d->ram->update_surface);
-            return;
+            break;
         }
-        if (update.left >= update.right || update.top >= update.bottom) {
+        if (update.left >= update.right || update.top >= update.bottom ||
+            update.left < 0 || update.top < 0) {
             qxl_set_guest_bug(d,
                     "QXL_IO_UPDATE_AREA: invalid area (%ux%u)x(%ux%u)\n",
                     update.left, update.top, update.right, update.bottom);
-            return;
-        }
-
-        if (update.left < 0 || update.top < 0 || update.left >= update.right ||
-            update.top >= update.bottom) {
-            qxl_set_guest_bug(d, "QXL_IO_UPDATE_AREA: "
-                              "invalid area(%d,%d,%d,%d)\n", update.left,
-                              update.right, update.top, update.bottom);
             break;
         }
         if (async == QXL_ASYNC) {
commit 0ec8df3974d2a4ff95b5fd4785b9bd3def7252f3
Author: Gerd Hoffmann <kraxel at redhat.com>
Date:   Fri Sep 14 22:09:23 2012 +0200

    qxl: always update displaysurface on resize
    
    Don't try to be clever and skip displaysurface reinitialization in case
    the size hasn't changed.  Other parameters might have changed
    nevertheless, for example depth or stride, resulting in rendering being
    broken then.
    
    Trigger: boot linux guest with vesafb, start X11, make sure both vesafb
    and X11 use the display same resolution.  Then watch X11 screen being
    upside down.
    
    Signed-off-by: Gerd Hoffmann <kraxel at redhat.com>

diff --git a/hw/qxl-render.c b/hw/qxl-render.c
index e2e3fe2..b66c168 100644
--- a/hw/qxl-render.c
+++ b/hw/qxl-render.c
@@ -99,7 +99,6 @@ static void qxl_render_update_area_unlocked(PCIQXLDevice *qxl)
 {
     VGACommonState *vga = &qxl->vga;
     int i;
-    DisplaySurface *surface = vga->ds->surface;
 
     if (qxl->guest_primary.resized) {
         qxl->guest_primary.resized = 0;
@@ -112,9 +111,6 @@ static void qxl_render_update_area_unlocked(PCIQXLDevice *qxl)
                qxl->guest_primary.qxl_stride,
                qxl->guest_primary.bytes_pp,
                qxl->guest_primary.bits_pp);
-    }
-    if (surface->width != qxl->guest_primary.surface.width ||
-        surface->height != qxl->guest_primary.surface.height) {
         if (qxl->guest_primary.qxl_stride > 0) {
             qemu_free_displaysurface(vga->ds);
             qemu_create_displaysurface_from(qxl->guest_primary.surface.width,


More information about the Spice-commits mailing list