[Spice-commits] 81 commits - VERSION arm-semi.c audio/paaudio.c block.c block/iscsi.c block/qcow2-cluster.c block/qcow2.c block/sheepdog.c configure cputlb.c hmp.c hw/ac97.c hw/apb_pci.c hw/fdc.c hw/pc_sysfw.c hw/qdev-properties.c hw/qxl-logger.c hw/qxl-render.c hw/qxl.c hw/qxl.h hw/rtl8139.c hw/scsi-bus.c hw/scsi-defs.h hw/scsi-disk.c include/qemu input.c linux-user/syscall.c migration.c monitor.c qapi-schema.json qemu-timer.c qemu-timer.h qmp.c qom/container.c scripts/qemu-binfmt-conf.sh target-arm/cpu.h target-arm/neon_helper.c target-mips/op_helper.c target-sparc/ldst_helper.c target-sparc/translate.c tcg/ppc tcg/ppc64 tci.c ui/spice-core.c user-exec.c vl.c

Gerd Hoffmann kraxel at kemper.freedesktop.org
Mon May 14 01:23:06 PDT 2012


 VERSION                     |    2 
 arm-semi.c                  |   86 +++++++++++++-------------
 audio/paaudio.c             |   30 ++++++++-
 block.c                     |   44 ++++++++++++-
 block/iscsi.c               |   86 ++++++++++++++++++++++----
 block/qcow2-cluster.c       |   14 ++--
 block/qcow2.c               |    3 
 block/sheepdog.c            |    8 ++
 configure                   |   21 +++---
 cputlb.c                    |    4 -
 hmp.c                       |    2 
 hw/ac97.c                   |   67 ++++++++++++++------
 hw/apb_pci.c                |   18 +++++
 hw/fdc.c                    |   29 +++-----
 hw/pc_sysfw.c               |    3 
 hw/qdev-properties.c        |    1 
 hw/qxl-logger.c             |   51 +++++++++++----
 hw/qxl-render.c             |   14 +++-
 hw/qxl.c                    |  145 +++++++++++++++++++++++++++++++++-----------
 hw/qxl.h                    |    6 -
 hw/rtl8139.c                |    2 
 hw/scsi-bus.c               |  100 ++++++++++++++++++------------
 hw/scsi-defs.h              |    1 
 hw/scsi-disk.c              |   66 +++++++++-----------
 include/qemu/cpu.h          |    4 -
 input.c                     |    4 -
 linux-user/syscall.c        |   46 ++++++++++++-
 migration.c                 |    1 
 monitor.c                   |   12 +++
 qapi-schema.json            |   35 +++++++++-
 qemu-timer.c                |   38 ++++-------
 qemu-timer.h                |    4 +
 qmp.c                       |    2 
 qom/container.c             |    2 
 scripts/qemu-binfmt-conf.sh |    1 
 target-arm/cpu.h            |   10 ++-
 target-arm/neon_helper.c    |    2 
 target-mips/op_helper.c     |    6 -
 target-sparc/ldst_helper.c  |    2 
 target-sparc/translate.c    |   25 +++++++
 tcg/ppc/tcg-target.c        |   83 ++++++++++++++-----------
 tcg/ppc64/tcg-target.c      |   36 +++++-----
 tci.c                       |    2 
 ui/spice-core.c             |    7 ++
 user-exec.c                 |    3 
 vl.c                        |   37 ++++++-----
 46 files changed, 809 insertions(+), 356 deletions(-)

New commits:
commit 94d1991445fa3582c042ee4e5b72606e2fc39cc2
Author: Artyom Tarasenko <atar4qemu at gmail.com>
Date:   Sat May 12 11:15:23 2012 +0200

    sun4u: implement interrupt clearing registers
    
    Implement registers for clearing OBIO and PCI interrupts
    
    Signed-off-by: Artyom Tarasenko <atar4qemu at gmail.com>
    Signed-off-by: Blue Swirl <blauwirbel at gmail.com>

diff --git a/hw/apb_pci.c b/hw/apb_pci.c
index d4e11bc..c28411a 100644
--- a/hw/apb_pci.c
+++ b/hw/apb_pci.c
@@ -85,6 +85,8 @@ typedef struct APBState {
     unsigned int nr_resets;
 } APBState;
 
+static void pci_apb_set_irq(void *opaque, int irq_num, int level);
+
 static void apb_config_writel (void *opaque, target_phys_addr_t addr,
                                uint64_t val, unsigned size)
 {
@@ -113,6 +115,16 @@ static void apb_config_writel (void *opaque, target_phys_addr_t addr,
             s->obio_irq_map[(addr & 0xff) >> 3] |= val & ~PBM_PCI_IMR_MASK;
         }
         break;
+    case 0x1400 ... 0x143f: /* PCI interrupt clear */
+        if (addr & 4) {
+            pci_apb_set_irq(s, (addr & 0x3f) >> 3, 0);
+        }
+        break;
+    case 0x1800 ... 0x1860: /* OBIO interrupt clear */
+        if (addr & 4) {
+            pci_apb_set_irq(s, 0x20 | ((addr & 0xff) >> 3), 0);
+        }
+        break;
     case 0x2000 ... 0x202f: /* PCI control */
         s->pci_control[(addr & 0x3f) >> 2] = val;
         break;
commit d1d80055baddf2c107d9da893f79c9199362e2e9
Author: Artyom Tarasenko <atar4qemu at gmail.com>
Date:   Sat May 12 11:15:22 2012 +0200

    sun4u: initialize OBIO interrupt mappings
    
    Similarly to PCI interrupt mappings, the OBIO ones have to be initialized.
    
    Signed-off-by: Artyom Tarasenko <atar4qemu at gmail.com>
    Signed-off-by: Blue Swirl <blauwirbel at gmail.com>

diff --git a/hw/apb_pci.c b/hw/apb_pci.c
index 7e28808..d4e11bc 100644
--- a/hw/apb_pci.c
+++ b/hw/apb_pci.c
@@ -404,6 +404,9 @@ static void pci_pbm_reset(DeviceState *d)
     for (i = 0; i < 8; i++) {
         s->pci_irq_map[i] &= PBM_PCI_IMR_MASK;
     }
+    for (i = 0; i < 32; i++) {
+        s->obio_irq_map[i] &= PBM_PCI_IMR_MASK;
+    }
 
     if (s->nr_resets++ == 0) {
         /* Power on reset */
@@ -426,6 +429,9 @@ static int pci_pbm_init_device(SysBusDevice *dev)
     for (i = 0; i < 8; i++) {
         s->pci_irq_map[i] = (0x1f << 6) | (i << 2);
     }
+    for (i = 0; i < 32; i++) {
+        s->obio_irq_map[i] = ((0x1f << 6) | 0x20) + i;
+    }
     s->pbm_irqs = qemu_allocate_irqs(pci_apb_set_irq, s, MAX_IVEC);
 
     /* apb_config */
commit 00b2ace50904068256239b0e2e5b680381aea262
Author: Artyom Tarasenko <atar4qemu at gmail.com>
Date:   Sat May 12 11:15:21 2012 +0200

    fix block loads broken in commit 30038fd818
    
    Fix UltraSPARC/JPS1/UA2007 VIS block load instructions broken in
    30038fd81808f7c3bca92be2369e74c8ca7b3d69.
    
    Signed-off-by: Artyom Tarasenko <atar4qemu at gmail.com>
    [blauwirbel at gmail.com: trimmed unwanted part of patch]
    Signed-off-by: Blue Swirl <blauwirbel at gmail.com>

diff --git a/target-sparc/ldst_helper.c b/target-sparc/ldst_helper.c
index 04ffddf..efe5e70 100644
--- a/target-sparc/ldst_helper.c
+++ b/target-sparc/ldst_helper.c
@@ -2098,7 +2098,7 @@ void helper_ldf_asi(CPUSPARCState *env, target_ulong addr, int asi, int size,
             return;
         }
         helper_check_align(env, addr, 0x3f);
-        for (i = 0; i < 8; i++, rd += 2, addr += 4) {
+        for (i = 0; i < 8; i++, rd += 2, addr += 8) {
             env->fpr[rd / 2].ll = helper_ld_asi(env, addr, asi & 0x19, 8, 0);
         }
         return;
commit 22036a49dd618051d932177b5d93daee746e5609
Author: Artyom Tarasenko <atar4qemu at gmail.com>
Date:   Sat May 12 11:15:20 2012 +0200

    Implement address masking for SPARC v9 CPUs
    
    According to UltraSPARC - IIi User's manual:
    
    14.1.11 Address Masking (Impdep #125)
    When PSTATE.AM=1, the CALL, JMPL, and RDPC instructions and all traps
    transmit zero in the high-order 32-bits of the PC to their specified
    destination registers.
    
    Signed-off-by: Artyom Tarasenko <atar4qemu at gmail.com>
    Signed-off-by: Blue Swirl <blauwirbel at gmail.com>

diff --git a/target-sparc/translate.c b/target-sparc/translate.c
index 4967152..b95f91c 100644
--- a/target-sparc/translate.c
+++ b/target-sparc/translate.c
@@ -1343,6 +1343,11 @@ static void do_branch(DisasContext *dc, int32_t offset, uint32_t insn, int cc,
     unsigned int cond = GET_FIELD(insn, 3, 6), a = (insn & (1 << 29));
     target_ulong target = dc->pc + offset;
 
+#ifdef TARGET_SPARC64
+    if (unlikely(AM_CHECK(dc))) {
+        target &= 0xffffffffULL;
+    }
+#endif
     if (cond == 0x0) {
         /* unconditional not taken */
         if (a) {
@@ -1388,6 +1393,11 @@ static void do_fbranch(DisasContext *dc, int32_t offset, uint32_t insn, int cc,
     unsigned int cond = GET_FIELD(insn, 3, 6), a = (insn & (1 << 29));
     target_ulong target = dc->pc + offset;
 
+#ifdef TARGET_SPARC64
+    if (unlikely(AM_CHECK(dc))) {
+        target &= 0xffffffffULL;
+    }
+#endif
     if (cond == 0x0) {
         /* unconditional not taken */
         if (a) {
@@ -1434,6 +1444,9 @@ static void do_branch_reg(DisasContext *dc, int32_t offset, uint32_t insn,
     unsigned int cond = GET_FIELD_SP(insn, 25, 27), a = (insn & (1 << 29));
     target_ulong target = dc->pc + offset;
 
+    if (unlikely(AM_CHECK(dc))) {
+        target &= 0xffffffffULL;
+    }
     flush_cond(dc, r_cond);
     gen_cond_reg(r_cond, cond, r_reg);
     if (a) {
@@ -2486,6 +2499,11 @@ static void disas_sparc_insn(DisasContext * dc, unsigned int insn)
             tcg_temp_free(r_const);
             target += dc->pc;
             gen_mov_pc_npc(dc, cpu_cond);
+#ifdef TARGET_SPARC64
+            if (unlikely(AM_CHECK(dc))) {
+                target &= 0xffffffffULL;
+            }
+#endif
             dc->npc = target;
         }
         goto jmp_insn;
@@ -2610,7 +2628,11 @@ static void disas_sparc_insn(DisasContext * dc, unsigned int insn)
                     {
                         TCGv r_const;
 
-                        r_const = tcg_const_tl(dc->pc);
+                        if (unlikely(AM_CHECK(dc))) {
+                            r_const = tcg_const_tl(dc->pc & 0xffffffffULL);
+                        } else {
+                           r_const = tcg_const_tl(dc->pc);
+                        }
                         gen_movl_TN_reg(rd, r_const);
                         tcg_temp_free(r_const);
                     }
@@ -4579,6 +4601,7 @@ static void disas_sparc_insn(DisasContext * dc, unsigned int insn)
                         r_const = tcg_const_i32(3);
                         gen_helper_check_align(cpu_env, cpu_dst, r_const);
                         tcg_temp_free_i32(r_const);
+                        gen_address_mask(dc, cpu_dst);
                         tcg_gen_mov_tl(cpu_npc, cpu_dst);
                         dc->npc = DYNAMIC_PC;
                     }
commit 7f1b17f2974ba0981e12615129e56b92ce31afa4
Author: Paolo Bonzini <pbonzini at redhat.com>
Date:   Thu May 10 09:39:17 2012 +0200

    vga: disable default VGA if appropriate -device is used
    
    This is a partial revert of commits a369da5 (vga: improve VGA logic,
    committed 2012-01-22) and c5bd4f3 (vga: fix -nodefaults -device VGA,
    2012-01-24) which broke command-line option parsing in different ways.
    
    Since commit a369da5 it has become impossible to specify a VGA device
    entirely with QemuOpts-enabled options, i.e. without needing an explicit
    "-vga none".
    
    In addition, until commit c5bd4f3 -nodefaults would not disable the device
    you specified with the legacy "-vga" option, independent of the order.
    Since commit c5bd4f3 QEMU -nodefaults will override a previous -vga
    option.
    
    I did not reintroduce machine->no_vga.  Boards can simply ignore the
    vga_interface_type variable, and most will indeed do so.
    
    Signed-off-by: Paolo Bonzini <pbonzini at redhat.com>
    Signed-off-by: Blue Swirl <blauwirbel at gmail.com>

diff --git a/vl.c b/vl.c
index 5e0080b..c4f87e8 100644
--- a/vl.c
+++ b/vl.c
@@ -273,6 +273,7 @@ static int default_monitor = 1;
 static int default_floppy = 1;
 static int default_cdrom = 1;
 static int default_sdcard = 1;
+static int default_vga = 1;
 
 static struct {
     const char *driver;
@@ -288,6 +289,12 @@ static struct {
     { .driver = "virtio-serial-pci",    .flag = &default_virtcon   },
     { .driver = "virtio-serial-s390",   .flag = &default_virtcon   },
     { .driver = "virtio-serial",        .flag = &default_virtcon   },
+    { .driver = "VGA",                  .flag = &default_vga       },
+    { .driver = "isa-vga",              .flag = &default_vga       },
+    { .driver = "cirrus-vga",           .flag = &default_vga       },
+    { .driver = "isa-cirrus-vga",       .flag = &default_vga       },
+    { .driver = "vmware-svga",          .flag = &default_vga       },
+    { .driver = "qxl-vga",              .flag = &default_vga       },
 };
 
 static void res_free(void)
@@ -2277,7 +2284,7 @@ int main(int argc, char **argv, char **envp)
     const char *loadvm = NULL;
     QEMUMachine *machine;
     const char *cpu_model;
-    const char *vga_model = NULL;
+    const char *vga_model = "none";
     const char *pid_file = NULL;
     const char *incoming = NULL;
 #ifdef CONFIG_VNC
@@ -2709,6 +2716,7 @@ int main(int argc, char **argv, char **envp)
                 break;
             case QEMU_OPTION_vga:
                 vga_model = optarg;
+                default_vga = 0;
                 break;
             case QEMU_OPTION_g:
                 {
@@ -3118,7 +3126,7 @@ int main(int argc, char **argv, char **envp)
                 default_floppy = 0;
                 default_cdrom = 0;
                 default_sdcard = 0;
-                vga_model = "none";
+                default_vga = 0;
                 break;
             case QEMU_OPTION_xen_domid:
                 if (!(xen_available())) {
@@ -3488,14 +3496,11 @@ int main(int argc, char **argv, char **envp)
     if (foreach_device_config(DEV_DEBUGCON, debugcon_parse) < 0)
         exit(1);
 
-    /* must be after qdev registration but before machine init */
-    if (vga_model) {
-        select_vgahw(vga_model);
-    } else if (cirrus_vga_available()) {
-        select_vgahw("cirrus");
-    } else {
-        select_vgahw("none");
+    /* If no default VGA is requested, the default is "none".  */
+    if (default_vga && cirrus_vga_available()) {
+        vga_model = "cirrus";
     }
+    select_vgahw(vga_model);
 
     if (qemu_opts_foreach(qemu_find_opts("device"), device_help_func, NULL, 0) != 0)
         exit(0);
commit 56eb21e15827fd0326c57dcab59771cb03ad9df6
Author: Max Filippov <jcmvbkbc at gmail.com>
Date:   Sun May 6 01:44:31 2012 +0400

    cputlb: fix watchpoints handling
    
    Cleanup commit e554861766d9ae84dd5720baa4869f4ed711506f have changed
    code_address calculation in the tlb_set_page function in case of access
    to a page with a watchpoint. This caused QEMU segfault in the xtensa
    test_break unit test. Fix it by moving code_address assignment above
    memory_region_section_get_iotlb call.
    
    Signed-off-by: Max Filippov <jcmvbkbc at gmail.com>
    Signed-off-by: Blue Swirl <blauwirbel at gmail.com>

diff --git a/cputlb.c b/cputlb.c
index 7f40a62..0d1e252 100644
--- a/cputlb.c
+++ b/cputlb.c
@@ -272,10 +272,10 @@ void tlb_set_page(CPUArchState *env, target_ulong vaddr,
     } else {
         addend = 0;
     }
-    iotlb = memory_region_section_get_iotlb(env, section, vaddr, paddr, prot,
-                                            &address);
 
     code_address = address;
+    iotlb = memory_region_section_get_iotlb(env, section, vaddr, paddr, prot,
+                                            &address);
 
     index = (vaddr >> TARGET_PAGE_BITS) & (CPU_TLB_SIZE - 1);
     env->iotlb[mmu_idx][index] = iotlb - vaddr;
commit ad37ad5b25592d2829989111b8386b8007ea0d83
Author: Peter Maydell <peter.maydell at linaro.org>
Date:   Thu May 10 12:56:09 2012 +0000

    target-arm/cpu.h: Make cpu_init("nonexistent cpu") return NULL
    
    The macro definition of cpu_init meant that if cpu_arm_init()
    returned NULL this wouldn't result in cpu_init() itself returning
    NULL. This had the effect that "-cpu foo" for some unknown CPU
    name 'foo' would cause ARM targets to segfault rather than
    generating a useful error message. Fix this by making cpu_init
    a simple inline function.
    
    Signed-off-by: Peter Maydell <peter.maydell at linaro.org>
    Acked-by: Andreas Färber <afaerber at suse.de>

diff --git a/target-arm/cpu.h b/target-arm/cpu.h
index 5eac070..d01285f 100644
--- a/target-arm/cpu.h
+++ b/target-arm/cpu.h
@@ -458,7 +458,15 @@ void cpu_arm_set_cp_io(CPUARMState *env, int cpnum,
 #define TARGET_PHYS_ADDR_SPACE_BITS 32
 #define TARGET_VIRT_ADDR_SPACE_BITS 32
 
-#define cpu_init(model) (&cpu_arm_init(model)->env)
+static inline CPUARMState *cpu_init(const char *cpu_model)
+{
+    ARMCPU *cpu = cpu_arm_init(cpu_model);
+    if (cpu) {
+        return &cpu->env;
+    }
+    return NULL;
+}
+
 #define cpu_exec cpu_arm_exec
 #define cpu_gen_code cpu_arm_gen_code
 #define cpu_signal_handler cpu_arm_signal_handler
commit 7e598de023e4f3f612be7f16acea2ec5dac010ec
Author: Matt Craighead <mjcraighead at gmail.com>
Date:   Thu May 10 12:56:08 2012 +0000

    target-arm: When setting FPSCR.QC, don't clear other FPSCR bits
    
    This patch fixes a bug affecting a variety of Neon instructions, such as
    VQADD.
    
    Signed-off-by: Matt Craighead <mjcraighead at gmail.com>
    Signed-off-by: Peter Maydell <peter.maydell at linaro.org>

diff --git a/target-arm/neon_helper.c b/target-arm/neon_helper.c
index 1e02d61..e0b9dbf 100644
--- a/target-arm/neon_helper.c
+++ b/target-arm/neon_helper.c
@@ -16,7 +16,7 @@
 #define SIGNBIT (uint32_t)0x80000000
 #define SIGNBIT64 ((uint64_t)1 << 63)
 
-#define SET_QC() env->vfp.xregs[ARM_VFP_FPSCR] = CPSR_Q
+#define SET_QC() env->vfp.xregs[ARM_VFP_FPSCR] |= CPSR_Q
 
 #define NEON_TYPE1(name, type) \
 typedef struct \
commit 9f34841a812dc622f8de98bc6141925c22f0ee93
Author: Anthony Liguori <aliguori at us.ibm.com>
Date:   Wed May 9 16:39:57 2012 -0500

    Update version for 1.1.0-rc0 release
    
    Signed-off-by: Anthony Liguori <aliguori at us.ibm.com>

diff --git a/VERSION b/VERSION
index ac2282a..34b3170 100644
--- a/VERSION
+++ b/VERSION
@@ -1 +1 @@
-1.0.90
+1.0.91
commit 1b3e76ebd1e270eae27e502ea8b836c31d95f801
Author: Andreas Färber <afaerber at suse.de>
Date:   Wed May 9 19:26:59 2012 +0200

    tcg/ppc: Fix CONFIG_TCG_PASS_AREG0 mode
    
    Adjust the tcg_out_qemu_{ld,st}() slow paths to pass AREG0 in r3,
    based on patches by malc.
    
    Also adjust the registers clobbered, based on patch by Alex.
    
    Signed-off-by: Andreas Färber <afaerber at suse.de>
    Acked-by: Alexander Graf <agraf at suse.de>
    [AF: Do not hardcode r3 for AREG0, requested by Alex]
    Signed-off-by: Anthony Liguori <aliguori at us.ibm.com>

diff --git a/tcg/ppc/tcg-target.c b/tcg/ppc/tcg-target.c
index 20888e2..4cde48d 100644
--- a/tcg/ppc/tcg-target.c
+++ b/tcg/ppc/tcg-target.c
@@ -244,9 +244,19 @@ static int target_parse_constraint(TCGArgConstraint *ct, const char **pct_str)
         tcg_regset_set32(ct->u.regs, 0, 0xffffffff);
         tcg_regset_reset_reg(ct->u.regs, TCG_REG_R3);
         tcg_regset_reset_reg(ct->u.regs, TCG_REG_R4);
+#ifdef CONFIG_TCG_PASS_AREG0
+        tcg_regset_reset_reg(ct->u.regs, TCG_REG_R5);
+#if TARGET_LONG_BITS == 64
+        tcg_regset_reset_reg(ct->u.regs, TCG_REG_R6);
+#ifdef TCG_TARGET_CALL_ALIGN_ARGS
+        tcg_regset_reset_reg(ct->u.regs, TCG_REG_R7);
+#endif
+#endif
+#else /* !AREG0 */
 #if TARGET_LONG_BITS == 64
         tcg_regset_reset_reg(ct->u.regs, TCG_REG_R5);
 #endif
+#endif
         break;
     case 'K':                   /* qemu_st[8..32] constraint */
         ct->ct |= TCG_CT_REG;
@@ -254,9 +264,19 @@ static int target_parse_constraint(TCGArgConstraint *ct, const char **pct_str)
         tcg_regset_reset_reg(ct->u.regs, TCG_REG_R3);
         tcg_regset_reset_reg(ct->u.regs, TCG_REG_R4);
         tcg_regset_reset_reg(ct->u.regs, TCG_REG_R5);
+#ifdef CONFIG_TCG_PASS_AREG0
+        tcg_regset_reset_reg(ct->u.regs, TCG_REG_R6);
+#if TARGET_LONG_BITS == 64
+        tcg_regset_reset_reg(ct->u.regs, TCG_REG_R7);
+#ifdef TCG_TARGET_CALL_ALIGN_ARGS
+        tcg_regset_reset_reg(ct->u.regs, TCG_REG_R8);
+#endif
+#endif
+#else /* !AREG0 */
 #if TARGET_LONG_BITS == 64
         tcg_regset_reset_reg(ct->u.regs, TCG_REG_R6);
 #endif
+#endif
         break;
     case 'M':                   /* qemu_st64 constraint */
         ct->ct |= TCG_CT_REG;
@@ -266,6 +286,12 @@ static int target_parse_constraint(TCGArgConstraint *ct, const char **pct_str)
         tcg_regset_reset_reg(ct->u.regs, TCG_REG_R5);
         tcg_regset_reset_reg(ct->u.regs, TCG_REG_R6);
         tcg_regset_reset_reg(ct->u.regs, TCG_REG_R7);
+#if defined(CONFIG_TCG_PASS_AREG0)
+        tcg_regset_reset_reg(ct->u.regs, TCG_REG_R8);
+#ifdef TCG_TARGET_CALL_ALIGN_ARGS
+        tcg_regset_reset_reg(ct->u.regs, TCG_REG_R9);
+#endif
+#endif
         break;
 #else
     case 'L':
@@ -512,7 +538,6 @@ static void tcg_out_call (TCGContext *s, tcg_target_long arg, int const_arg)
 #include "../../softmmu_defs.h"
 
 #ifdef CONFIG_TCG_PASS_AREG0
-#error CONFIG_TCG_PASS_AREG0 is not supported
 /* helper signature: helper_ld_mmu(CPUState *env, target_ulong addr,
    int mmu_idx) */
 static const void * const qemu_ld_helpers[4] = {
@@ -618,6 +643,9 @@ static void tcg_out_qemu_ld (TCGContext *s, const TCGArg *args, int opc)
 
     /* slow path */
     ir = 3;
+#ifdef CONFIG_TCG_PASS_AREG0
+    tcg_out_mov (s, TCG_TYPE_I32, ir++, TCG_AREG0);
+#endif
 #if TARGET_LONG_BITS == 32
     tcg_out_mov (s, TCG_TYPE_I32, ir++, addr_reg);
 #else
@@ -817,6 +845,9 @@ static void tcg_out_qemu_st (TCGContext *s, const TCGArg *args, int opc)
 
     /* slow path */
     ir = 3;
+#ifdef CONFIG_TCG_PASS_AREG0
+    tcg_out_mov (s, TCG_TYPE_I32, ir++, TCG_AREG0);
+#endif
 #if TARGET_LONG_BITS == 32
     tcg_out_mov (s, TCG_TYPE_I32, ir++, addr_reg);
 #else
commit a082615b0752e113e40537e7f820ffb4bbb15750
Author: Andreas Färber <afaerber at suse.de>
Date:   Wed May 9 19:26:58 2012 +0200

    tcg/ppc: Clobber r5 for 64-bit qemu_ld
    
    This accounts for the additional addr_reg2 register.
    
    Signed-off-by: Andreas Färber <afaerber at suse.de>
    Acked-by: Alexander Graf <agraf at suse.de>
    Signed-off-by: Anthony Liguori <aliguori at us.ibm.com>

diff --git a/tcg/ppc/tcg-target.c b/tcg/ppc/tcg-target.c
index b4e0466..20888e2 100644
--- a/tcg/ppc/tcg-target.c
+++ b/tcg/ppc/tcg-target.c
@@ -244,6 +244,9 @@ static int target_parse_constraint(TCGArgConstraint *ct, const char **pct_str)
         tcg_regset_set32(ct->u.regs, 0, 0xffffffff);
         tcg_regset_reset_reg(ct->u.regs, TCG_REG_R3);
         tcg_regset_reset_reg(ct->u.regs, TCG_REG_R4);
+#if TARGET_LONG_BITS == 64
+        tcg_regset_reset_reg(ct->u.regs, TCG_REG_R5);
+#endif
         break;
     case 'K':                   /* qemu_st[8..32] constraint */
         ct->ct |= TCG_CT_REG;
commit d831fdb0517118e8029316495cb272cbb8910800
Author: Andreas Färber <afaerber at suse.de>
Date:   Wed May 9 19:26:57 2012 +0200

    tcg/ppc: Don't hardcode register numbers
    
    Also assure i64 alignment where necessary.
    
    Alignment code optimization suggested by malc.
    
    Signed-off-by: Andreas Färber <afaerber at suse.de>
    Acked-by: Alexander Graf <agraf at suse.de>
    Signed-off-by: Anthony Liguori <aliguori at us.ibm.com>

diff --git a/tcg/ppc/tcg-target.c b/tcg/ppc/tcg-target.c
index 4b85c89..b4e0466 100644
--- a/tcg/ppc/tcg-target.c
+++ b/tcg/ppc/tcg-target.c
@@ -552,7 +552,7 @@ static void tcg_out_qemu_ld (TCGContext *s, const TCGArg *args, int opc)
 {
     int addr_reg, data_reg, data_reg2, r0, r1, rbase, bswap;
 #ifdef CONFIG_SOFTMMU
-    int mem_index, s_bits, r2;
+    int mem_index, s_bits, r2, ir;
     void *label1_ptr, *label2_ptr;
 #if TARGET_LONG_BITS == 64
     int addr_reg2;
@@ -614,14 +614,17 @@ static void tcg_out_qemu_ld (TCGContext *s, const TCGArg *args, int opc)
 #endif
 
     /* slow path */
+    ir = 3;
 #if TARGET_LONG_BITS == 32
-    tcg_out_mov (s, TCG_TYPE_I32, 3, addr_reg);
-    tcg_out_movi (s, TCG_TYPE_I32, 4, mem_index);
+    tcg_out_mov (s, TCG_TYPE_I32, ir++, addr_reg);
 #else
-    tcg_out_mov (s, TCG_TYPE_I32, 3, addr_reg2);
-    tcg_out_mov (s, TCG_TYPE_I32, 4, addr_reg);
-    tcg_out_movi (s, TCG_TYPE_I32, 5, mem_index);
+#ifdef TCG_TARGET_CALL_ALIGN_ARGS
+    ir |= 1;
+#endif
+    tcg_out_mov (s, TCG_TYPE_I32, ir++, addr_reg2);
+    tcg_out_mov (s, TCG_TYPE_I32, ir++, addr_reg);
 #endif
+    tcg_out_movi (s, TCG_TYPE_I32, ir, mem_index);
 
     tcg_out_call (s, (tcg_target_long) qemu_ld_helpers[s_bits], 1);
     switch (opc) {
@@ -810,13 +813,15 @@ static void tcg_out_qemu_st (TCGContext *s, const TCGArg *args, int opc)
 #endif
 
     /* slow path */
+    ir = 3;
 #if TARGET_LONG_BITS == 32
-    tcg_out_mov (s, TCG_TYPE_I32, 3, addr_reg);
-    ir = 4;
+    tcg_out_mov (s, TCG_TYPE_I32, ir++, addr_reg);
 #else
-    tcg_out_mov (s, TCG_TYPE_I32, 3, addr_reg2);
-    tcg_out_mov (s, TCG_TYPE_I32, 4, addr_reg);
-    ir = 5;
+#ifdef TCG_TARGET_CALL_ALIGN_ARGS
+    ir |= 1;
+#endif
+    tcg_out_mov (s, TCG_TYPE_I32, ir++, addr_reg2);
+    tcg_out_mov (s, TCG_TYPE_I32, ir++, addr_reg);
 #endif
 
     switch (opc) {
@@ -841,7 +846,7 @@ static void tcg_out_qemu_st (TCGContext *s, const TCGArg *args, int opc)
         break;
     case 3:
 #ifdef TCG_TARGET_CALL_ALIGN_ARGS
-        ir = 5;
+        ir |= 1;
 #endif
         tcg_out_mov (s, TCG_TYPE_I32, ir++, data_reg2);
         tcg_out_mov (s, TCG_TYPE_I32, ir, data_reg);
commit c1696d94c17b7fe03a2b103b1ba117fb0726a316
Author: Andreas Färber <andreas.faerber at web.de>
Date:   Wed May 9 19:26:56 2012 +0200

    tcg/ppc: Do not overwrite lower address word on Darwin and AIX
    
    For targets where TARGET_LONG_BITS != 32, i.e. 64-bit guests,
    addr_reg is moved to r4. For hosts without TCG_TARGET_CALL_ALIGN_ARGS
    either data_reg2 or data_reg or a masked version thereof would overwrite
    r4. Place it in r5 instead, matching TCG_TARGET_CALL_ALIGN_ARGS hosts.
    
    This fixes immediate crashes of 64-bit guests observed on Darwin/ppc but
    not on Darwin/ppc64.
    
    Signed-off-by: Andreas Färber <andreas.faerber at web.de>
    Acked-by: malc <av1474 at comtv.ru>
    Acked-by: Alexander Graf <agraf at suse.de>
    Signed-off-by: Anthony Liguori <aliguori at us.ibm.com>

diff --git a/tcg/ppc/tcg-target.c b/tcg/ppc/tcg-target.c
index dc40716..4b85c89 100644
--- a/tcg/ppc/tcg-target.c
+++ b/tcg/ppc/tcg-target.c
@@ -816,11 +816,7 @@ static void tcg_out_qemu_st (TCGContext *s, const TCGArg *args, int opc)
 #else
     tcg_out_mov (s, TCG_TYPE_I32, 3, addr_reg2);
     tcg_out_mov (s, TCG_TYPE_I32, 4, addr_reg);
-#ifdef TCG_TARGET_CALL_ALIGN_ARGS
     ir = 5;
-#else
-    ir = 4;
-#endif
 #endif
 
     switch (opc) {
commit c438b1970b6b751dd403a9ed6a7ef7e078ec2307
Merge: c595481... 9116284...
Author: Anthony Liguori <aliguori at us.ibm.com>
Date:   Tue May 8 13:07:41 2012 -0500

    Merge remote-tracking branch 'qmp/queue/qmp' into staging
    
    * qmp/queue/qmp:
      hmp: fix bad value conversion for M type
      hmp: expr_unary(): check for overflow in strtoul()/strtoull()
      vl: drop is_suspended variable
      runstate: introduce suspended state
      qapi-schema.json: fix RunState enums alphabetical order
      wakeup on migration

commit 911628498cea6617243761babbbacaeb8b3a062a
Author: Luiz Capitulino <lcapitulino at redhat.com>
Date:   Thu Apr 26 17:34:30 2012 -0300

    hmp: fix bad value conversion for M type
    
    The M type converts from megabytes to bytes. However, the value can be
    negative before the conversion, which will lead to a flawed conversion.
    
    For example, this:
    
     (qemu) balloon -1000000000000011
     (qemu)
    
    Just "works", but the value passed by the balloon command will be
    something else.
    
    This patch fixes this problem by requering a positive value before
    converting. There's really no reason to accept a negative value for
    the M type.
    
    Signed-off-by: Luiz Capitulino <lcapitulino at redhat.com>
    Reviewed-by: Eric Blake <eblake at redhat.com>

diff --git a/monitor.c b/monitor.c
index bf60984..12a6fe2 100644
--- a/monitor.c
+++ b/monitor.c
@@ -89,8 +89,8 @@
  *              TODO lift the restriction
  * 'i'          32 bit integer
  * 'l'          target long (32 or 64 bit)
- * 'M'          just like 'l', except in user mode the value is
- *              multiplied by 2^20 (think Mebibyte)
+ * 'M'          Non-negative target long (32 or 64 bit), in user mode the
+ *              value is multiplied by 2^20 (think Mebibyte)
  * 'o'          octets (aka bytes)
  *              user mode accepts an optional T, t, G, g, M, m, K, k
  *              suffix, which multiplies the value by 2^40 for
@@ -3622,6 +3622,10 @@ static const mon_cmd_t *monitor_parse_command(Monitor *mon,
                     monitor_printf(mon, "integer is for 32-bit values\n");
                     goto fail;
                 } else if (c == 'M') {
+                    if (val < 0) {
+                        monitor_printf(mon, "enter a positive value\n");
+                        goto fail;
+                    }
                     val <<= 20;
                 }
                 qdict_put(qdict, key, qint_from_int(val));
commit 6b0e33be88bbccc3bcb987026089aa09f9622de9
Author: Luiz Capitulino <lcapitulino at redhat.com>
Date:   Thu Apr 26 16:48:41 2012 -0300

    hmp: expr_unary(): check for overflow in strtoul()/strtoull()
    
    It's not checked currently, so something like:
    
      (qemu) balloon -100000000000001111114334234
      (qemu)
    
    Will just "work" (in this case the balloon command will get a random
    value).
    
    Fix it by checking if strtoul()/strtoull() overflowed.
    
    Signed-off-by: Luiz Capitulino <lcapitulino at redhat.com>
    Reviewed-by: Eric Blake <eblake at redhat.com>

diff --git a/monitor.c b/monitor.c
index 8946a10..bf60984 100644
--- a/monitor.c
+++ b/monitor.c
@@ -3120,11 +3120,15 @@ static int64_t expr_unary(Monitor *mon)
         n = 0;
         break;
     default:
+        errno = 0;
 #if TARGET_PHYS_ADDR_BITS > 32
         n = strtoull(pch, &p, 0);
 #else
         n = strtoul(pch, &p, 0);
 #endif
+        if (errno == ERANGE) {
+            expr_error(mon, "number too large");
+        }
         if (pch == p) {
             expr_error(mon, "invalid char in expression");
         }
commit 9abc62f6445795522d1bf5bf17f642e44eaf032d
Author: Luiz Capitulino <lcapitulino at redhat.com>
Date:   Fri Apr 27 14:31:12 2012 -0300

    vl: drop is_suspended variable
    
    Check for the RUN_STATE_SUSPENDED state instead.
    
    Signed-off-by: Luiz Capitulino <lcapitulino at redhat.com>

diff --git a/vl.c b/vl.c
index a7afc79..5e0080b 100644
--- a/vl.c
+++ b/vl.c
@@ -1293,7 +1293,6 @@ static pid_t shutdown_pid;
 static int powerdown_requested;
 static int debug_requested;
 static int suspend_requested;
-static bool is_suspended;
 static NotifierList suspend_notifiers =
     NOTIFIER_LIST_INITIALIZER(suspend_notifiers);
 static NotifierList wakeup_notifiers =
@@ -1427,12 +1426,11 @@ static void qemu_system_suspend(void)
     notifier_list_notify(&suspend_notifiers, NULL);
     runstate_set(RUN_STATE_SUSPENDED);
     monitor_protocol_event(QEVENT_SUSPEND, NULL);
-    is_suspended = true;
 }
 
 void qemu_system_suspend_request(void)
 {
-    if (is_suspended) {
+    if (runstate_check(RUN_STATE_SUSPENDED)) {
         return;
     }
     suspend_requested = 1;
@@ -1447,7 +1445,7 @@ void qemu_register_suspend_notifier(Notifier *notifier)
 
 void qemu_system_wakeup_request(WakeupReason reason)
 {
-    if (!is_suspended) {
+    if (!runstate_check(RUN_STATE_SUSPENDED)) {
         return;
     }
     if (!(wakeup_reason_mask & (1 << reason))) {
@@ -1458,7 +1456,6 @@ void qemu_system_wakeup_request(WakeupReason reason)
     notifier_list_notify(&wakeup_notifiers, &reason);
     reset_requested = 1;
     qemu_notify_event();
-    is_suspended = false;
 }
 
 void qemu_system_wakeup_enable(WakeupReason reason, bool enabled)
commit ad02b96ad86baf6dd72a43b04876b2d6ea957112
Author: Luiz Capitulino <lcapitulino at redhat.com>
Date:   Fri Apr 27 13:33:36 2012 -0300

    runstate: introduce suspended state
    
    QEMU enters in this state when the guest suspends to ram (S3).
    
    This is important so that HMP users and QMP clients can know that
    the guest is suspended. QMP also has an event for this, but events
    are not reliable and are limited (ie. a client can connect to QEMU
    after the event has been emitted).
    
    Having a different state for S3 brings a new issue, though. Every
    device that doesn't run when the VM is stopped but wants to run
    when the VM is suspended has to check for RUN_STATE_SUSPENDED
    explicitly. This is the case for the keyboard and mouse devices,
    for example.
    
    Signed-off-by: Luiz Capitulino <lcapitulino at redhat.com>
    Acked-by: Gerd Hoffmann <kraxel at redhat.com>

diff --git a/input.c b/input.c
index 6b5c2c3..6968b31 100644
--- a/input.c
+++ b/input.c
@@ -130,7 +130,7 @@ void qemu_remove_led_event_handler(QEMUPutLEDEntry *entry)
 
 void kbd_put_keycode(int keycode)
 {
-    if (!runstate_is_running()) {
+    if (!runstate_is_running() && !runstate_check(RUN_STATE_SUSPENDED)) {
         return;
     }
     if (qemu_put_kbd_event) {
@@ -154,7 +154,7 @@ void kbd_mouse_event(int dx, int dy, int dz, int buttons_state)
     void *mouse_event_opaque;
     int width, height;
 
-    if (!runstate_is_running()) {
+    if (!runstate_is_running() && !runstate_check(RUN_STATE_SUSPENDED)) {
         return;
     }
     if (QTAILQ_EMPTY(&mouse_handlers)) {
diff --git a/qapi-schema.json b/qapi-schema.json
index 33f2f92..2ca7195 100644
--- a/qapi-schema.json
+++ b/qapi-schema.json
@@ -116,12 +116,14 @@
 #
 # @shutdown: guest is shut down (and -no-shutdown is in use)
 #
+# @suspended: guest is suspended (ACPI S3)
+#
 # @watchdog: the watchdog action is configured to pause and has been triggered
 ##
 { 'enum': 'RunState',
   'data': [ 'debug', 'inmigrate', 'internal-error', 'io-error', 'paused',
             'postmigrate', 'prelaunch', 'finish-migrate', 'restore-vm',
-            'running', 'save-vm', 'shutdown', 'watchdog' ] }
+            'running', 'save-vm', 'shutdown', 'suspended', 'watchdog' ] }
 
 ##
 # @StatusInfo:
diff --git a/qmp.c b/qmp.c
index a182b51..fee9fb2 100644
--- a/qmp.c
+++ b/qmp.c
@@ -151,6 +151,8 @@ void qmp_cont(Error **errp)
                runstate_check(RUN_STATE_SHUTDOWN)) {
         error_set(errp, QERR_RESET_REQUIRED);
         return;
+    } else if (runstate_check(RUN_STATE_SUSPENDED)) {
+        return;
     }
 
     bdrv_iterate(iostatus_bdrv_it, NULL);
diff --git a/vl.c b/vl.c
index ae91a8a..a7afc79 100644
--- a/vl.c
+++ b/vl.c
@@ -366,6 +366,11 @@ static const RunStateTransition runstate_transitions_def[] = {
     { RUN_STATE_SHUTDOWN, RUN_STATE_PAUSED },
     { RUN_STATE_SHUTDOWN, RUN_STATE_FINISH_MIGRATE },
 
+    { RUN_STATE_DEBUG, RUN_STATE_SUSPENDED },
+    { RUN_STATE_RUNNING, RUN_STATE_SUSPENDED },
+    { RUN_STATE_SUSPENDED, RUN_STATE_RUNNING },
+    { RUN_STATE_SUSPENDED, RUN_STATE_FINISH_MIGRATE },
+
     { RUN_STATE_WATCHDOG, RUN_STATE_RUNNING },
     { RUN_STATE_WATCHDOG, RUN_STATE_FINISH_MIGRATE },
 
@@ -1420,6 +1425,7 @@ static void qemu_system_suspend(void)
 {
     pause_all_vcpus();
     notifier_list_notify(&suspend_notifiers, NULL);
+    runstate_set(RUN_STATE_SUSPENDED);
     monitor_protocol_event(QEVENT_SUSPEND, NULL);
     is_suspended = true;
 }
@@ -1447,6 +1453,7 @@ void qemu_system_wakeup_request(WakeupReason reason)
     if (!(wakeup_reason_mask & (1 << reason))) {
         return;
     }
+    runstate_set(RUN_STATE_RUNNING);
     monitor_protocol_event(QEVENT_WAKEUP, NULL);
     notifier_list_notify(&wakeup_notifiers, &reason);
     reset_requested = 1;
commit 0a24c7b18eefcd1138a5c60fc77bc9b653c64082
Author: Luiz Capitulino <lcapitulino at redhat.com>
Date:   Fri Apr 27 13:16:41 2012 -0300

    qapi-schema.json: fix RunState enums alphabetical order
    
    Signed-off-by: Luiz Capitulino <lcapitulino at redhat.com>

diff --git a/qapi-schema.json b/qapi-schema.json
index 4279259..33f2f92 100644
--- a/qapi-schema.json
+++ b/qapi-schema.json
@@ -92,6 +92,8 @@
 #
 # @debug: QEMU is running on a debugger
 #
+# @finish-migrate: guest is paused to finish the migration process
+#
 # @inmigrate: guest is paused waiting for an incoming migration
 #
 # @internal-error: An internal error that prevents further guest execution
@@ -106,8 +108,6 @@
 #
 # @prelaunch: QEMU was started with -S and guest has not started
 #
-# @finish-migrate: guest is paused to finish the migration process
-#
 # @restore-vm: guest is paused to restore VM state
 #
 # @running: guest is actively running
commit 7b5d3aa2ccd886cd50216bc35fe3329e7487502e
Author: Gerd Hoffmann <kraxel at redhat.com>
Date:   Wed Mar 7 08:00:26 2012 +0100

    wakeup on migration
    
    Wakeup the guest when the live part of the migation is finished.
    This avoids being in suspended state on migration, so we don't
    have to save the is_suspended bit.
    
    Signed-off-by: Gerd Hoffmann <kraxel at redhat.com>
    Reviewed-by: Luiz Capitulino <lcapitulino at redhat.com>

diff --git a/migration.c b/migration.c
index 94f7839..f9e968e 100644
--- a/migration.c
+++ b/migration.c
@@ -252,6 +252,7 @@ static void migrate_fd_put_ready(void *opaque)
         int old_vm_running = runstate_is_running();
 
         DPRINTF("done iterating\n");
+        qemu_system_wakeup_request(QEMU_WAKEUP_REASON_OTHER);
         vm_stop_force_state(RUN_STATE_FINISH_MIGRATE);
 
         if (qemu_savevm_state_complete(s->file) < 0) {
commit c5954819b6ee601024c081635be0336ce0cb1115
Author: Peter Maydell <peter.maydell at linaro.org>
Date:   Thu May 3 19:32:15 2012 +0100

    user-exec.c: Don't assert on segfaults for non-valid addresses
    
    h2g() will assert if passed an address that's not a valid guest address,
    so handle_cpu_signal() needs to check before passing "data address
    which caused a segfault" to it, since for a misbehaving guest
    that could be anything. If the address isn't a valid guest address
    then we can simply skip the attempt to unprotect a guest page
    which was made read-only to catch self-modifying code.
    
    This assertion probably fires more readily now than it used to
    do because of recent changes to default to reserving guest address
    space.
    
    Acked-by: Alexander Graf <agraf at suse.de>
    Signed-off-by: Peter Maydell <peter.maydell at linaro.org>
    Signed-off-by: Anthony Liguori <aliguori at us.ibm.com>

diff --git a/user-exec.c b/user-exec.c
index be6bc4f..d8c2ad9 100644
--- a/user-exec.c
+++ b/user-exec.c
@@ -97,7 +97,8 @@ static inline int handle_cpu_signal(uintptr_t pc, unsigned long address,
                 pc, address, is_write, *(unsigned long *)old_set);
 #endif
     /* XXX: locking issue */
-    if (is_write && page_unprotect(h2g(address), pc, puc)) {
+    if (is_write && h2g_valid(address)
+        && page_unprotect(h2g(address), pc, puc)) {
         return 1;
     }
 
commit 90f2cefb17f3e25272143f43cd00f6347e65987b
Author: Andreas Färber <afaerber at suse.de>
Date:   Mon May 7 19:47:37 2012 +0200

    scripts/qemu-binfmt-conf.sh: Fix shell syntax
    
    The script is organized as a sequence of binfmt registrations, with a
    check whether the to be registered architecture matches the host.
    
    Add a missing fi for the SuperH section.
    
    Reported-by: Alexander Graf <agraf at suse.de>
    Reviewed-by: Paolo Bonzini <pbonzini at redhat.com>
    Signed-off-by: Andreas Färber <afaerber at suse.de>
    Signed-off-by: Anthony Liguori <aliguori at us.ibm.com>

diff --git a/scripts/qemu-binfmt-conf.sh b/scripts/qemu-binfmt-conf.sh
index 83a44d8..0da2618 100644
--- a/scripts/qemu-binfmt-conf.sh
+++ b/scripts/qemu-binfmt-conf.sh
@@ -63,6 +63,7 @@ fi
 if [ $cpu != "sh" ] ; then
     echo    ':sh4:M::\x7fELF\x01\x01\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x2a\x00:\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xfe\xff\xff\xff:/usr/local/bin/qemu-sh4:' > /proc/sys/fs/binfmt_misc/register
     echo    ':sh4eb:M::\x7fELF\x01\x02\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x2a:\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xfe\xff\xff:/usr/local/bin/qemu-sh4eb:' > /proc/sys/fs/binfmt_misc/register
+fi
 if [ $cpu != "s390x" ] ; then
     echo   ':s390x:M::\x7fELF\x02\x02\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x16:\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xfe\xff\xff:/usr/local/bin/qemu-s390x:' > /proc/sys/fs/binfmt_misc/register
 fi
commit f5df5baf11a32ae6a669ac945625d1c3e4deb76d
Author: Andreas Färber <afaerber at suse.de>
Date:   Wed May 2 22:28:58 2012 +0200

    cpu: Update documentation and comment
    
    State struct CPU had been renamed to CPUState, former CPUState to
    CPUArchState.
    
    Signed-off-by: Andreas Färber <afaerber at suse.de>
    Signed-off-by: Anthony Liguori <aliguori at us.ibm.com>

diff --git a/include/qemu/cpu.h b/include/qemu/cpu.h
index 4291279..78b65b3 100644
--- a/include/qemu/cpu.h
+++ b/include/qemu/cpu.h
@@ -39,7 +39,7 @@ typedef struct CPUState CPUState;
 
 /**
  * CPUClass:
- * @reset: Callback to reset the #CPU to its initial state.
+ * @reset: Callback to reset the #CPUState to its initial state.
  *
  * Represents a CPU family or model.
  */
@@ -61,7 +61,7 @@ struct CPUState {
     Object parent_obj;
     /*< public >*/
 
-    /* TODO Move common fields from CPUState here. */
+    /* TODO Move common fields from CPUArchState here. */
 };
 
 
commit 175003702a4d9ac6dd58413c348efefd309b778c
Author: Andreas Färber <afaerber at suse.de>
Date:   Tue May 1 01:12:03 2012 +0200

    configure: Assure printing "yes" or "no" for VirtFS support
    
    When auto-detecting VirtFS support, virtfs="". Set it to "no" after
    checking whether it was explicitly requested through --enable-virtfs.
    
    Signed-off-by: Andreas Färber <afaerber at suse.de>
    Cc: Aneesh Kumar K.V <aneesh.kumar at linux.vnet.ibm.com>
    Signed-off-by: Anthony Liguori <aliguori at us.ibm.com>

diff --git a/configure b/configure
index 056293a..491109d 100755
--- a/configure
+++ b/configure
@@ -2902,6 +2902,7 @@ if test "$softmmu" = yes ; then
       if test "$virtfs" = yes; then
         feature_not_found "virtfs"
       fi
+      virtfs=no
     fi
   fi
   if [ "$linux" = "yes" -o "$bsd" = "yes" -o "$solaris" = "yes" ] ; then
commit aabfd88d5e1ec0878aa70076c3de1859614671f4
Author: Andreas Färber <afaerber at suse.de>
Date:   Tue May 1 01:12:02 2012 +0200

    configure: Reindent VirtFS check
    
    Avoid tab-indention and fit in with the surrounding code.
    
    Signed-off-by: Andreas Färber <afaerber at suse.de>
    Cc: Aneesh Kumar K.V <aneesh.kumar at linux.vnet.ibm.com>
    Signed-off-by: Anthony Liguori <aliguori at us.ibm.com>

diff --git a/configure b/configure
index fd424ef..056293a 100755
--- a/configure
+++ b/configure
@@ -2895,14 +2895,14 @@ tools=
 if test "$softmmu" = yes ; then
   tools="qemu-img\$(EXESUF) qemu-io\$(EXESUF) $tools"
   if test "$virtfs" != no ; then
-      if test "$cap" = yes && test "$linux" = yes && test "$attr" = yes ; then
-	  virtfs=yes
-	  tools="$tools fsdev/virtfs-proxy-helper\$(EXESUF)"
-      else
-	  if test "$virtfs" = yes; then
-	      feature_not_found "virtfs"
-	  fi
+    if test "$cap" = yes && test "$linux" = yes && test "$attr" = yes ; then
+      virtfs=yes
+      tools="$tools fsdev/virtfs-proxy-helper\$(EXESUF)"
+    else
+      if test "$virtfs" = yes; then
+        feature_not_found "virtfs"
       fi
+    fi
   fi
   if [ "$linux" = "yes" -o "$bsd" = "yes" -o "$solaris" = "yes" ] ; then
       tools="qemu-nbd\$(EXESUF) $tools"
commit 17904bcfb760bdf6bd462e0396478893555d1edb
Author: Stefan Weil <sw at weilnetz.de>
Date:   Thu May 3 18:09:45 2012 +0200

    tci: Fix wrong macro name for debug code
    
    Code which is compiled with CONFIG_TCG_DEBUG (set by configure option
    --enable-debug-tcg) should not disable the assert macro by
    defining NDEBUG.
    
    With the wrong macro name CONFIG_TCG_DEBUG, all assertions in tci.c
    were completely useless because NDEBUG was always defined.
    
    Reviewed-by: Peter Maydell <peter.maydell at linaro.org>
    Signed-off-by: Stefan Weil <sw at weilnetz.de>
    Signed-off-by: Anthony Liguori <aliguori at us.ibm.com>

diff --git a/tci.c b/tci.c
index 71de66d..a412a4e 100644
--- a/tci.c
+++ b/tci.c
@@ -20,7 +20,7 @@
 #include "config.h"
 
 /* Defining NDEBUG disables assertions (which makes the code faster). */
-#if !defined(CONFIG_TCG_DEBUG) && !defined(NDEBUG)
+#if !defined(CONFIG_DEBUG_TCG) && !defined(NDEBUG)
 # define NDEBUG
 #endif
 
commit 165ceac0950dcfdf7a2676d6189bbab3d67701f1
Author: Andreas Faerber <andreas.faerber at web.de>
Date:   Sat May 5 20:08:40 2012 +0200

    qemu-timer: Move include for __FreeBSD_version to header
    
    sys/param.h is needed for __FreeBSD_version.
    Pointed out by Juergen, thanks.
    
    Signed-off-by: Andreas Faerber <andreas.faerber at web.de>
    Cc: Juergen Lock <nox at jelal.kn-bremen.de>
    Signed-off-by: Anthony Liguori <aliguori at us.ibm.com>

diff --git a/qemu-timer.c b/qemu-timer.c
index b9fd75d..4a6fc98 100644
--- a/qemu-timer.c
+++ b/qemu-timer.c
@@ -31,10 +31,6 @@
 
 #include "qemu-timer.h"
 
-#ifdef __FreeBSD__
-#include <sys/param.h>
-#endif
-
 #ifdef _WIN32
 #include <mmsystem.h>
 #endif
diff --git a/qemu-timer.h b/qemu-timer.h
index 5175419..f8af595 100644
--- a/qemu-timer.h
+++ b/qemu-timer.h
@@ -5,6 +5,10 @@
 #include "main-loop.h"
 #include "notify.h"
 
+#ifdef __FreeBSD__
+#include <sys/param.h>
+#endif
+
 /* timers */
 
 #define SCALE_MS 1000000
commit 4f08129eeb42422655cc946a0a0c3accc2b8e3db
Merge: 7c652c1... bdc62e6...
Author: Anthony Liguori <aliguori at us.ibm.com>
Date:   Tue May 8 09:41:10 2012 -0500

    Merge remote-tracking branch 'mst/tags/for_anthony' into staging
    
    * mst/tags/for_anthony:
      rtl8139: fix regression in TxStatus/TxAddr read

commit 7c652c1eaf20b9271ebcc92b788d1fe656b3a774
Merge: e45bca6... 21fcf36...
Author: Anthony Liguori <aliguori at us.ibm.com>
Date:   Tue May 8 09:38:41 2012 -0500

    Merge remote-tracking branch 'kwolf/for-anthony' into staging
    
    * kwolf/for-anthony:
      fdc: simplify media change handling
      qcow2: lock on prealloc
      block: make bdrv_create adopt coroutine
      qcow2: Limit COW to where it's needed
      sheepdog: switch to writethrough mode if cluster doesn't support flush

commit e45bca682ca1b63cdfba9c8a6b164d1838a2eda4
Merge: 233ffa1... 68bd348...
Author: Anthony Liguori <aliguori at us.ibm.com>
Date:   Tue May 8 09:37:12 2012 -0500

    Merge remote-tracking branch 'bonzini/scsi-next' into staging
    
    * bonzini/scsi-next:
      scsi: Add assertion for use-after-free errors
      scsi: remove useless debug messages
      scsi: set VALID bit to 0 in fixed format sense data
      scsi: do not require a minimum allocation length for REQUEST SENSE
      scsi: do not require a minimum allocation length for INQUIRY
      scsi: parse 16-byte tape CDBs
      scsi: do not report bogus overruns for commands in the 0x00-0x1F range
      scsi-disk: add dpofua property
      scsi: change "removable" field to host many features
      scsi: Specify the xfer direction for UNMAP and ATA_PASSTHROUGH commands
      scsi: fix WRITE SAME transfer length and direction
      scsi: fix refcounting for reads
      scsi: prevent data transfer overflow
      ISCSI: Add support for thin-provisioning via discard/UNMAP and bigger LUNs

commit 233ffa1653b49755e841efdccbd2ac63272ce0c8
Merge: acde837... 1a49ef2...
Author: Anthony Liguori <aliguori at us.ibm.com>
Date:   Tue May 8 09:37:00 2012 -0500

    Merge remote-tracking branch 'riku/linux-user-for-upstream' into staging
    
    * riku/linux-user-for-upstream:
      linux-user: fix emulation of /proc/self/maps
      linux-user: Clean up interim solution for exit syscall

commit acde8376ef638007efdd0b34413ba01b9352171c
Merge: 4b5463b... ddf9f4b...
Author: Anthony Liguori <aliguori at us.ibm.com>
Date:   Tue May 8 09:36:37 2012 -0500

    Merge remote-tracking branch 'spice/spice.v54' into staging
    
    * spice/spice.v54:
      qxl: don't assert on guest create_guest_primary
      qxl: ioport_write: remove guest trigerrable abort
      qxl: qxl_add_memslot: remove guest trigerrable panics
      qxl: interface_notify_update: remove guest trigerrable abort
      qxl: cleanup s/__FUNCTION__/__func__/
      qxl: don't abort on guest trigerrable ring indices mismatch
      qxl: fix > 80 chars line
      qxl: replace panic with guest bug in qxl_track_command
      qxl: check for NULL return from qxl_phys2virt
      hw/qxl.c: qxl_phys2virt: replace panics with guest_bug
      spice_info: add mouse_mode
      spice: require spice-protocol >= 0.8.1

commit 4b5463bfdfc3b0f335af18e0c5b64e5f52e86551
Merge: 847c25d... 40f08e8...
Author: Anthony Liguori <aliguori at us.ibm.com>
Date:   Tue May 8 09:36:18 2012 -0500

    Merge remote-tracking branch 'sweil/fixes' into staging
    
    * sweil/fixes:
      qemu-timer: Fix limits for w32 mmtimer
      qom: Fix memory leak in function container_get
      hw/pc_sysfw: Fix memory leak
      qdev: Fix memory leak in function set_pci_devfn
      arm-semi: Rename SYS_XXX macros to TARGET_SYS_XXX (fixes compiler warning)
      target-mips: Remove unused inline function

commit bdc62e62ead1a6c2a113934bf28cb5abef48618d
Author: Avi Kivity <avi at redhat.com>
Date:   Mon May 7 15:00:45 2012 +0300

    rtl8139: fix regression in TxStatus/TxAddr read
    
    Commit afe0a595356192 added byte reads for TxStatus/TxAddr, but
    broke 32-bit reads; the mask generation
    
       (1 << (8 * size)) - 1
    
    is unspecified in C for size >= sizeof(int), and in fact returns 0
    on x86.
    
    Fix by using a larger type.
    
    Fixes (at least) Fedora 9 i386 with -machine kernel_irqchip=on.  I
    didn't see it with the qemu APIC implementation; may be due to timing
    or (more likely) a tester error.
    
    Signed-off-by: Avi Kivity <avi at redhat.com>
    Signed-off-by: Michael S. Tsirkin <mst at redhat.com>

diff --git a/hw/rtl8139.c b/hw/rtl8139.c
index 4d0f5ba..eb22d04 100644
--- a/hw/rtl8139.c
+++ b/hw/rtl8139.c
@@ -2500,7 +2500,7 @@ static uint32_t rtl8139_TxStatus_TxAddr_read(RTL8139State *s, uint32_t regs[],
     case 1: /* fall through */
     case 2: /* fall through */
     case 4:
-        ret = (regs[reg] >> offset * 8) & ((1 << (size * 8)) - 1);
+        ret = (regs[reg] >> offset * 8) & (((uint64_t)1 << (size * 8)) - 1);
         DPRINTF("TxStatus/TxAddr[%d] read addr=0x%x size=0x%x val=0x%08x\n",
                 reg, addr, size, ret);
         break;
commit 21fcf36095939a97fc3df578e12821c3e6c3ba78
Author: Hervé Poussineau <hpoussin at reactos.org>
Date:   Sat May 5 19:43:28 2012 +0200

    fdc: simplify media change handling
    
    This also (partly) fixes IBM OS/2 Warp 4.0 floppy installation, where
    not all floppies have the same format (2x80x18 for the first ones,
    2x80x23 for the next ones).
    
    Signed-off-by: Hervé Poussineau <hpoussin at reactos.org>
    Signed-off-by: Kevin Wolf <kwolf at redhat.com>

diff --git a/hw/fdc.c b/hw/fdc.c
index 756d4ce..cb4cd25 100644
--- a/hw/fdc.c
+++ b/hw/fdc.c
@@ -705,6 +705,15 @@ static void fdctrl_raise_irq(FDCtrl *fdctrl, uint8_t status0)
         qemu_set_irq(fdctrl->irq, 1);
         fdctrl->sra |= FD_SRA_INTPEND;
     }
+    if (status0 & FD_SR0_SEEK) {
+        FDrive *cur_drv;
+        /* A seek clears the disk change line (if a disk is inserted) */
+        cur_drv = get_cur_drv(fdctrl);
+        if (cur_drv->max_track) {
+            cur_drv->media_changed = 0;
+        }
+    }
+
     fdctrl->reset_sensei = 0;
     fdctrl->status0 = status0;
     FLOPPY_DPRINTF("Set interrupt status to 0x%02x\n", fdctrl->status0);
@@ -936,23 +945,7 @@ static void fdctrl_write_ccr(FDCtrl *fdctrl, uint32_t value)
 
 static int fdctrl_media_changed(FDrive *drv)
 {
-    int ret;
-
-    if (!drv->bs)
-        return 0;
-    if (drv->media_changed) {
-        drv->media_changed = 0;
-        ret = 1;
-    } else {
-        ret = bdrv_media_changed(drv->bs);
-        if (ret < 0) {
-            ret = 0;            /* we don't know, assume no */
-        }
-    }
-    if (ret) {
-        fd_revalidate(drv);
-    }
-    return ret;
+    return drv->media_changed;
 }
 
 /* Digital input register : 0x07 (read-only) */
@@ -1856,6 +1849,7 @@ static void fdctrl_change_cb(void *opaque, bool load)
     FDrive *drive = opaque;
 
     drive->media_changed = 1;
+    fd_revalidate(drive);
 }
 
 static const BlockDevOps fdctrl_block_ops = {
@@ -1886,7 +1880,6 @@ static int fdctrl_connect_drives(FDCtrl *fdctrl)
         fd_init(drive);
         fd_revalidate(drive);
         if (drive->bs) {
-            drive->media_changed = 1;
             bdrv_set_dev_ops(drive->bs, &fdctrl_block_ops, drive);
         }
     }
commit 15552c4ad38b9ec66792b044cf5ae74538c32717
Author: Zhi Yong Wu <wuzhy at linux.vnet.ibm.com>
Date:   Mon May 7 16:51:03 2012 +0800

    qcow2: lock on prealloc
    
    preallocate() will be locked. This is required because
    qcow2_alloc_cluster_link_l2() assumes that it runs under a lock that it
    can drop while COW is being performed.
    
    Signed-off-by: Zhi Yong Wu <wuzhy at linux.vnet.ibm.com>
    Signed-off-by: Kevin Wolf <kwolf at redhat.com>

diff --git a/block/qcow2.c b/block/qcow2.c
index 8c60a6f..ee4678f 100644
--- a/block/qcow2.c
+++ b/block/qcow2.c
@@ -1192,7 +1192,10 @@ static int qcow2_create2(const char *filename, int64_t total_size,
 
     /* And if we're supposed to preallocate metadata, do that now */
     if (prealloc) {
+        BDRVQcowState *s = bs->opaque;
+        qemu_co_mutex_lock(&s->lock);
         ret = preallocate(bs);
+        qemu_co_mutex_unlock(&s->lock);
         if (ret < 0) {
             goto out;
         }
commit 5b7e1542cfa41a281af9629d31cef03704d976e6
Author: Zhi Yong Wu <wuzhy at linux.vnet.ibm.com>
Date:   Mon May 7 16:50:42 2012 +0800

    block: make bdrv_create adopt coroutine
    
    The current qemu.git introduces failure with preallocation and some
    sizes:
    
    qemu-img create -f qcow2 new.img 976563K -o preallocation=metadata
    qemu-img: qemu-coroutine-lock.c:111: qemu_co_mutex_unlock: Assertion
    `mutex->locked == 1' failed.
    
    And lock needs to work in coroutine context. So to fix this issue, we
    need to make bdrv_create adopt coroutine at first.
    
    Signed-off-by: Zhi Yong Wu <wuzhy at linux.vnet.ibm.com>
    Signed-off-by: Kevin Wolf <kwolf at redhat.com>

diff --git a/block.c b/block.c
index 43c794c..ee7d8f2 100644
--- a/block.c
+++ b/block.c
@@ -341,13 +341,53 @@ BlockDriver *bdrv_find_whitelisted_format(const char *format_name)
     return drv && bdrv_is_whitelisted(drv) ? drv : NULL;
 }
 
+typedef struct CreateCo {
+    BlockDriver *drv;
+    char *filename;
+    QEMUOptionParameter *options;
+    int ret;
+} CreateCo;
+
+static void coroutine_fn bdrv_create_co_entry(void *opaque)
+{
+    CreateCo *cco = opaque;
+    assert(cco->drv);
+
+    cco->ret = cco->drv->bdrv_create(cco->filename, cco->options);
+}
+
 int bdrv_create(BlockDriver *drv, const char* filename,
     QEMUOptionParameter *options)
 {
-    if (!drv->bdrv_create)
+    int ret;
+
+    Coroutine *co;
+    CreateCo cco = {
+        .drv = drv,
+        .filename = g_strdup(filename),
+        .options = options,
+        .ret = NOT_DONE,
+    };
+
+    if (!drv->bdrv_create) {
         return -ENOTSUP;
+    }
 
-    return drv->bdrv_create(filename, options);
+    if (qemu_in_coroutine()) {
+        /* Fast-path if already in coroutine context */
+        bdrv_create_co_entry(&cco);
+    } else {
+        co = qemu_coroutine_create(bdrv_create_co_entry);
+        qemu_coroutine_enter(co, &cco);
+        while (cco.ret == NOT_DONE) {
+            qemu_aio_wait();
+        }
+    }
+
+    ret = cco.ret;
+    g_free(cco.filename);
+
+    return ret;
 }
 
 int bdrv_create_file(const char* filename, QEMUOptionParameter *options)
commit 54e6814360ab2110ed3ed07b2b9a3f9907e1202a
Author: Kevin Wolf <kwolf at redhat.com>
Date:   Thu Apr 26 19:41:22 2012 +0200

    qcow2: Limit COW to where it's needed
    
    This fixes a regression introduced in commit 250196f1. The bug leads to
    data corruption, found during an Autotest run with a Fedora 8 guest.
    
    Consider a write request whose first part is covered by an already
    allocated cluster, but additional clusters need to be newly allocated.
    When counting the number of clusters to allocate, the qcow2 code would
    decide to do COW for all remaining clusters of the write request, even
    if some of them are already allocated.
    
    If during this COW operation another write request is issued that touches
    the same cluster, it will still refer to the old cluster. When the COW
    completes, the first request will update the L2 table and the second
    write request will be lost. Note that the requests need not overlap, it's
    enough for them to touch the same cluster.
    
    This patch ensures that only clusters that really require COW are
    considered for allocation. In this case any other request writing to the
    same cluster will be an allocating write and gets serialised.
    
    Reported-by: Marcelo Tosatti <mtosatti at redhat.com>
    Tested-by: Marcelo Tosatti <mtosatti at redhat.com>
    Signed-off-by: Kevin Wolf <kwolf at redhat.com>

diff --git a/block/qcow2-cluster.c b/block/qcow2-cluster.c
index 353889d..10c22fe 100644
--- a/block/qcow2-cluster.c
+++ b/block/qcow2-cluster.c
@@ -883,15 +883,19 @@ again:
         assert(keep_clusters <= nb_clusters);
         nb_clusters -= keep_clusters;
     } else {
+        keep_clusters = 0;
+        cluster_offset = 0;
+    }
+
+    if (nb_clusters > 0) {
         /* For the moment, overwrite compressed clusters one by one */
-        if (cluster_offset & QCOW_OFLAG_COMPRESSED) {
+        uint64_t entry = be64_to_cpu(l2_table[l2_index + keep_clusters]);
+        if (entry & QCOW_OFLAG_COMPRESSED) {
             nb_clusters = 1;
         } else {
-            nb_clusters = count_cow_clusters(s, nb_clusters, l2_table, l2_index);
+            nb_clusters = count_cow_clusters(s, nb_clusters, l2_table,
+                                             l2_index + keep_clusters);
         }
-
-        keep_clusters = 0;
-        cluster_offset = 0;
     }
 
     cluster_offset &= L2E_OFFSET_MASK;
commit 115c2b5a6806615206dfa5518509911bfc7b1d07
Author: MORITA Kazutaka <morita.kazutaka at gmail.com>
Date:   Thu May 3 05:26:07 2012 +0900

    sheepdog: switch to writethrough mode if cluster doesn't support flush
    
    This is necessary for qemu to work with the older version of Sheepdog
    which doesn't support SD_OP_FLUSH_VDI.
    
    Signed-off-by: MORITA Kazutaka <morita.kazutaka at gmail.com>
    Signed-off-by: Kevin Wolf <kwolf at redhat.com>

diff --git a/block/sheepdog.c b/block/sheepdog.c
index 0ed6b19..e01d371 100644
--- a/block/sheepdog.c
+++ b/block/sheepdog.c
@@ -1678,6 +1678,14 @@ static int coroutine_fn sd_co_flush_to_disk(BlockDriverState *bs)
         return ret;
     }
 
+    if (rsp->result == SD_RES_INVALID_PARMS) {
+        dprintf("disable write cache since the server doesn't support it\n");
+
+        s->cache_enabled = 0;
+        closesocket(s->flush_fd);
+        return 0;
+    }
+
     if (rsp->result != SD_RES_SUCCESS) {
         error_report("%s", sd_strerror(rsp->result));
         return -EIO;
commit 847c25d01cbe8e4fe457a7426f82daaaf3287aae
Author: Hans de Goede <hdegoede at redhat.com>
Date:   Mon May 7 09:24:38 2012 +0200

    hw/ac97: Mask out the EAPD bit on Powerdown Ctrl/Stat writes
    
    The Linux AC97 driver tests this bit to decide wether or not to show
    an External amplifier toggle control.
    
    This patch was also tested with a Windows XP guest without any issues.
    
    Signed-off-by: Hans de Goede <hdegoede at redhat.com>
    Signed-off-by: malc <av1474 at comtv.ru>

diff --git a/hw/ac97.c b/hw/ac97.c
index b009257..e791b9d 100644
--- a/hw/ac97.c
+++ b/hw/ac97.c
@@ -603,7 +603,7 @@ static void nam_writew (void *opaque, uint32_t addr, uint32_t val)
         mixer_reset (s);
         break;
     case AC97_Powerdown_Ctrl_Stat:
-        val &= ~0xf;
+        val &= ~0x800f;
         val |= mixer_load (s, index) & 0xf;
         mixer_store (s, index, val);
         break;
commit 7873bfb866c89f9e6eab28b14d0c2007b361150c
Author: Hans de Goede <hdegoede at redhat.com>
Date:   Mon May 7 09:24:37 2012 +0200

    hw/ac97: Mask out unused bits of volume controls
    
    The Linux ac97 drivers does a number of register read/write tests to
    see how much resolution a volume control actually has.
    
    This patch takes this into account by masking out any bits written to
    a volume control reg which should not be there according to the spec.
    
    After this the Linux ac97 driver correctly uses a range of 0 - 0x1f for
    the PCM out volume, as stated in the spec, and we can fix the FIXME
    in update_combined_volume_out().
    
    This patch was also tested with a Windows XP guest without any issues.
    
    Signed-off-by: Hans de Goede <hdegoede at redhat.com>
    Signed-off-by: malc <av1474 at comtv.ru>

diff --git a/hw/ac97.c b/hw/ac97.c
index d175870..b009257 100644
--- a/hw/ac97.c
+++ b/hw/ac97.c
@@ -458,8 +458,7 @@ static void update_combined_volume_out (AC97LinkState *s)
 
     get_volume (mixer_load (s, AC97_Master_Volume_Mute), 0x3f, 1,
                 &mute, &lvol, &rvol);
-    /* FIXME: should be 1f according to spec */
-    get_volume (mixer_load (s, AC97_PCM_Out_Volume_Mute), 0x3f, 1,
+    get_volume (mixer_load (s, AC97_PCM_Out_Volume_Mute), 0x1f, 1,
                 &pmute, &plvol, &prvol);
 
     mute = mute | pmute;
@@ -482,11 +481,22 @@ static void update_volume_in (AC97LinkState *s)
 
 static void set_volume (AC97LinkState *s, int index, uint32_t val)
 {
-    mixer_store (s, index, val);
-    if (index == AC97_Master_Volume_Mute || index == AC97_PCM_Out_Volume_Mute) {
+    switch (index) {
+    case AC97_Master_Volume_Mute:
+        val &= 0xbf3f;
+        mixer_store (s, index, val);
         update_combined_volume_out (s);
-    } else if (index == AC97_Record_Gain_Mute) {
+        break;
+    case AC97_PCM_Out_Volume_Mute:
+        val &= 0x9f1f;
+        mixer_store (s, index, val);
+        update_combined_volume_out (s);
+        break;
+    case AC97_Record_Gain_Mute:
+        val &= 0x8f0f;
+        mixer_store (s, index, val);
         update_volume_in (s);
+        break;
     }
 }
 
commit f94e9b9b3535ea977c5a919f88adf36da95a8292
Author: Hans de Goede <hdegoede at redhat.com>
Date:   Mon May 7 09:24:36 2012 +0200

    hw/ac97: Use AC97_Record_Gain_Mute not AC97_Line_In_Volume_Mute
    
    After commit 19677a380a70348134ed7650b294522617eb03fc:
    "hw/ac97: add support for volume control"
    
    We are (correctly) using AC97_Record_Gain_Mute and not AC97_Line_In_Volume_Mute
    for recording volume, but various places in hw/ac97 were still assumimg that
    we are using AC97_Line_In_Volume_Mute for record volume control, this patch
    fixes this.
    
    Signed-off-by: Hans de Goede <hdegoede at redhat.com>
    Signed-off-by: malc <av1474 at comtv.ru>

diff --git a/hw/ac97.c b/hw/ac97.c
index c5089be..d175870 100644
--- a/hw/ac97.c
+++ b/hw/ac97.c
@@ -511,6 +511,7 @@ static void mixer_reset (AC97LinkState *s)
     mixer_store (s, AC97_PC_BEEP_Volume_Mute     , 0x0000);
     mixer_store (s, AC97_Phone_Volume_Mute       , 0x0000);
     mixer_store (s, AC97_Mic_Volume_Mute         , 0x0000);
+    mixer_store (s, AC97_Line_In_Volume_Mute     , 0x0000);
     mixer_store (s, AC97_CD_Volume_Mute          , 0x0000);
     mixer_store (s, AC97_Video_Volume_Mute       , 0x0000);
     mixer_store (s, AC97_Aux_Volume_Mute         , 0x0000);
@@ -536,7 +537,7 @@ static void mixer_reset (AC97LinkState *s)
     record_select (s, 0);
     set_volume (s, AC97_Master_Volume_Mute, 0x8000);
     set_volume (s, AC97_PCM_Out_Volume_Mute, 0x8808);
-    set_volume (s, AC97_Line_In_Volume_Mute, 0x8808);
+    set_volume (s, AC97_Record_Gain_Mute, 0x8808);
 
     reset_voices (s, active);
 }
@@ -599,7 +600,6 @@ static void nam_writew (void *opaque, uint32_t addr, uint32_t val)
     case AC97_PCM_Out_Volume_Mute:
     case AC97_Master_Volume_Mute:
     case AC97_Record_Gain_Mute:
-    case AC97_Line_In_Volume_Mute:
         set_volume (s, index, val);
         break;
     case AC97_Record_Select:
@@ -667,6 +667,7 @@ static void nam_writew (void *opaque, uint32_t addr, uint32_t val)
     case AC97_PC_BEEP_Volume_Mute:
     case AC97_Phone_Volume_Mute:
     case AC97_Mic_Volume_Mute:
+    case AC97_Line_In_Volume_Mute:
     case AC97_CD_Volume_Mute:
     case AC97_Video_Volume_Mute:
     case AC97_Aux_Volume_Mute:
@@ -1178,8 +1179,8 @@ static int ac97_post_load (void *opaque, int version_id)
                 mixer_load (s, AC97_Master_Volume_Mute));
     set_volume (s, AC97_PCM_Out_Volume_Mute,
                 mixer_load (s, AC97_PCM_Out_Volume_Mute));
-    set_volume (s, AC97_Line_In_Volume_Mute,
-                mixer_load (s, AC97_Line_In_Volume_Mute));
+    set_volume (s, AC97_Record_Gain_Mute,
+                mixer_load (s, AC97_Record_Gain_Mute));
 
     active[PI_INDEX] = !!(s->bm_regs[PI_INDEX].cr & CR_RPBM);
     active[PO_INDEX] = !!(s->bm_regs[PO_INDEX].cr & CR_RPBM);
commit d044be3714db9c3750c430a2bb1be74beee6fd27
Author: Hans de Goede <hdegoede at redhat.com>
Date:   Mon May 7 09:24:35 2012 +0200

    hw/ac97: Make a bunch of mixer registers read only
    
    The Linux ac97 driver tries to see if optional things like video input
    volume control are available in 2 ways:
    1) See if the mute bit is set after reset, if it is no further tests are done
    2) If the mute bit is not set it does a write/read test of the mute bit
    
    This patch changes our ac97 to conform to what the Linux driver expects, it
    initializes registers for things which we don't emulate to 0 (so the mute bit
    is not set) and makes them read only.
    
    This causes Linux to now longer show the following (functionless)
    controls in alsamixer:
    
    Master Mono vol + mute
    3d Control toggle
    PCM out pre / post 3d select
    Surround toggle
    CD vol + mute
    Mic vol + mute
    Mic boost toggle
    Mic mic1 / mic2 select
    Video vol + mute
    Phone vol + mute
    Beep mono vol + mute
    Aux vol + mute
    Mono "output mic" / "mix" select
    Sigmatel 4 speaker stereo toggle
    Sigmatel ADC 6Db att toggle
    Sigmatel DAC 6Db att toggle
    
    This patch was also tested with a Windows XP guest and there it also makes
    a number of functionless mixer controls go away.
    
    Signed-off-by: Hans de Goede <hdegoede at redhat.com>
    Signed-off-by: malc <av1474 at comtv.ru>

diff --git a/hw/ac97.c b/hw/ac97.c
index ceab8b7..c5089be 100644
--- a/hw/ac97.c
+++ b/hw/ac97.c
@@ -54,6 +54,8 @@ enum {
     AC97_6Ch_Vol_C_LFE_Mute        = 0x36,
     AC97_6Ch_Vol_L_R_Surround_Mute = 0x38,
     AC97_Vendor_Reserved           = 0x58,
+    AC97_Sigmatel_Analog           = 0x6c, /* We emulate a Sigmatel codec */
+    AC97_Sigmatel_Dac2Invert       = 0x6e, /* We emulate a Sigmatel codec */
     AC97_Vendor_ID1                = 0x7c,
     AC97_Vendor_ID2                = 0x7e
 };
@@ -503,14 +505,16 @@ static void mixer_reset (AC97LinkState *s)
     memset (s->mixer_data, 0, sizeof (s->mixer_data));
     memset (active, 0, sizeof (active));
     mixer_store (s, AC97_Reset                   , 0x0000); /* 6940 */
-    mixer_store (s, AC97_Master_Volume_Mono_Mute , 0x8000);
+    mixer_store (s, AC97_Headphone_Volume_Mute   , 0x0000);
+    mixer_store (s, AC97_Master_Volume_Mono_Mute , 0x0000);
+    mixer_store (s, AC97_Master_Tone_RL,           0x0000);
     mixer_store (s, AC97_PC_BEEP_Volume_Mute     , 0x0000);
-
-    mixer_store (s, AC97_Phone_Volume_Mute       , 0x8008);
-    mixer_store (s, AC97_Mic_Volume_Mute         , 0x8008);
-    mixer_store (s, AC97_CD_Volume_Mute          , 0x8808);
-    mixer_store (s, AC97_Aux_Volume_Mute         , 0x8808);
-    mixer_store (s, AC97_Record_Gain_Mic_Mute    , 0x8000);
+    mixer_store (s, AC97_Phone_Volume_Mute       , 0x0000);
+    mixer_store (s, AC97_Mic_Volume_Mute         , 0x0000);
+    mixer_store (s, AC97_CD_Volume_Mute          , 0x0000);
+    mixer_store (s, AC97_Video_Volume_Mute       , 0x0000);
+    mixer_store (s, AC97_Aux_Volume_Mute         , 0x0000);
+    mixer_store (s, AC97_Record_Gain_Mic_Mute    , 0x0000);
     mixer_store (s, AC97_General_Purpose         , 0x0000);
     mixer_store (s, AC97_3D_Control              , 0x0000);
     mixer_store (s, AC97_Powerdown_Ctrl_Stat     , 0x000f);
@@ -657,6 +661,22 @@ static void nam_writew (void *opaque, uint32_t addr, uint32_t val)
                     val);
         }
         break;
+    case AC97_Headphone_Volume_Mute:
+    case AC97_Master_Volume_Mono_Mute:
+    case AC97_Master_Tone_RL:
+    case AC97_PC_BEEP_Volume_Mute:
+    case AC97_Phone_Volume_Mute:
+    case AC97_Mic_Volume_Mute:
+    case AC97_CD_Volume_Mute:
+    case AC97_Video_Volume_Mute:
+    case AC97_Aux_Volume_Mute:
+    case AC97_Record_Gain_Mic_Mute:
+    case AC97_General_Purpose:
+    case AC97_3D_Control:
+    case AC97_Sigmatel_Analog:
+    case AC97_Sigmatel_Dac2Invert:
+        /* None of the features in these regs are emulated, so they are RO */
+        break;
     default:
         dolog ("U nam writew %#x <- %#x\n", addr, val);
         mixer_store (s, index, val);
commit a4e652ebc0b2c473f2ded93e8528095da8251c6a
Author: Hans de Goede <hdegoede at redhat.com>
Date:   Mon May 7 09:24:34 2012 +0200

    hw/ac97: Fix log message in mixer_load
    
    Fix a small copy and paste error in logging.
    
    Signed-off-by: Hans de Goede <hdegoede at redhat.com>
    Signed-off-by: malc <av1474 at comtv.ru>

diff --git a/hw/ac97.c b/hw/ac97.c
index 177f729..ceab8b7 100644
--- a/hw/ac97.c
+++ b/hw/ac97.c
@@ -342,7 +342,7 @@ static uint16_t mixer_load (AC97LinkState *s, uint32_t i)
     uint16_t val = 0xffff;
 
     if (i + 2 > sizeof (s->mixer_data)) {
-        dolog ("mixer_store: index %d out of bounds %zd\n",
+        dolog ("mixer_load: index %d out of bounds %zd\n",
                i, sizeof (s->mixer_data));
     }
     else {
commit 68bd348ade453821fd5378479e6718e69bf181f1
Author: Stefan Weil <sw at weilnetz.de>
Date:   Fri May 4 08:51:16 2012 +0200

    scsi: Add assertion for use-after-free errors
    
    The QEMU emulation which is currently used with Raspberry PI images
    (qemu-system-arm -M versatilepb ...) accesses memory which was freed.
    
    Valgrind output (extract):
    
    ==17857== Invalid write of size 4
    ==17857==    at 0x24EB06: scsi_req_unref (scsi-bus.c:1273)
    ==17857==    by 0x24FFAE: scsi_read_complete (scsi-disk.c:277)
    ==17857==    by 0x152ACC: bdrv_co_em_bh (block.c:3363)
    ==17857==    by 0x13D49C: qemu_bh_poll (async.c:71)
    ==17857==    by 0x211A8C: main_loop_wait (main-loop.c:503)
    ==17857==    by 0x207954: main_loop (vl.c:1555)
    ==17857==    by 0x20E9C9: main (vl.c:3653)
    ==17857==  Address 0x1c54383c is 12 bytes inside a block of size 260 free'd
    ==17857==    at 0x4824B3A: free (vg_replace_malloc.c:366)
    ==17857==    by 0x20ADFA: free_and_trace (vl.c:2250)
    ==17857==    by 0x4899FC5: g_free (in /lib/libglib-2.0.so.0.2400.1)
    ==17857==    by 0x24EB3B: scsi_req_unref (scsi-bus.c:1277)
    ==17857==    by 0x24F003: scsi_req_complete (scsi-bus.c:1383)
    ==17857==    by 0x25022A: scsi_read_data (scsi-disk.c:334)
    ==17857==    by 0x24EB9F: scsi_req_continue (scsi-bus.c:1289)
    ==17857==    by 0x1C7787: lsi_do_dma (lsi53c895a.c:575)
    ==17857==    by 0x1C8CDA: lsi_execute_script (lsi53c895a.c:1147)
    ==17857==    by 0x1C74EA: lsi_resume_script (lsi53c895a.c:510)
    ==17857==    by 0x1C7ECD: lsi_transfer_data (lsi53c895a.c:746)
    ==17857==    by 0x24EC90: scsi_req_data (scsi-bus.c:1307)
    
    (There are some more similar messages.)
    
    This patch adds an assertion which also detects those errors:
    
    Calling scsi_req_unref is not allowed when the previous call
    of that function has decremented refcount to 0, because in this
    case req was freed.
    
    Signed-off-by: Stefan Weil <sw at weilnetz.de>
    Signed-off-by: Paolo Bonzini <pbonzini at redhat.com>

diff --git a/hw/scsi-bus.c b/hw/scsi-bus.c
index add1d4f..8ab9bcd 100644
--- a/hw/scsi-bus.c
+++ b/hw/scsi-bus.c
@@ -1291,6 +1291,7 @@ SCSIRequest *scsi_req_ref(SCSIRequest *req)
 
 void scsi_req_unref(SCSIRequest *req)
 {
+    assert(req->refcount > 0);
     if (--req->refcount == 0) {
         if (req->ops->free_req) {
             req->ops->free_req(req);
commit 2a92fbff49a286ddad1686d60532d791f20f4ce1
Author: Paolo Bonzini <pbonzini at redhat.com>
Date:   Thu May 3 18:26:13 2012 +0200

    scsi: remove useless debug messages
    
    Optional inquiry information is declared obsolete in the latest versions
    of the standard; invalid CDBs or unsupported VPD pages are supported
    can be diagnosed with trace_scsi_inquiry.
    
    Signed-off-by: Paolo Bonzini <pbonzini at redhat.com>

diff --git a/hw/scsi-disk.c b/hw/scsi-disk.c
index 4158032..045c764 100644
--- a/hw/scsi-disk.c
+++ b/hw/scsi-disk.c
@@ -28,9 +28,6 @@ do { printf("scsi-disk: " fmt , ## __VA_ARGS__); } while (0)
 #define DPRINTF(fmt, ...) do {} while(0)
 #endif
 
-#define BADF(fmt, ...) \
-do { fprintf(stderr, "scsi-disk: " fmt , ## __VA_ARGS__); } while (0)
-
 #include "qemu-common.h"
 #include "qemu-error.h"
 #include "scsi.h"
@@ -515,12 +512,6 @@ static int scsi_disk_emulate_inquiry(SCSIRequest *req, uint8_t *outbuf)
     SCSIDiskState *s = DO_UPCAST(SCSIDiskState, qdev, req->dev);
     int buflen = 0;
 
-    if (req->cmd.buf[1] & 0x2) {
-        /* Command support data - optional, not implemented */
-        BADF("optional INQUIRY command support request not implemented\n");
-        return -1;
-    }
-
     if (req->cmd.buf[1] & 0x1) {
         /* Vital product data */
         uint8_t page_code = req->cmd.buf[2];
@@ -638,8 +629,6 @@ static int scsi_disk_emulate_inquiry(SCSIRequest *req, uint8_t *outbuf)
             break;
         }
         default:
-            BADF("Error: unsupported Inquiry (EVPD[%02X]) "
-                 "buffer size %zd\n", page_code, req->cmd.xfer);
             return -1;
         }
         /* done with EVPD */
@@ -648,8 +637,6 @@ static int scsi_disk_emulate_inquiry(SCSIRequest *req, uint8_t *outbuf)
 
     /* Standard INQUIRY data */
     if (req->cmd.buf[2] != 0) {
-        BADF("Error: Inquiry (STANDARD) page or code "
-             "is non-zero [%02X]\n", req->cmd.buf[2]);
         return -1;
     }
 
commit 77e4743c94d2a926623e280913e05ad6c840791e
Author: Paolo Bonzini <pbonzini at redhat.com>
Date:   Thu May 3 17:59:27 2012 +0200

    scsi: set VALID bit to 0 in fixed format sense data
    
    The INFORMATION field (bytes 3..6) is never set by QEMU, so the VALID
    bit must be 0.
    
    Signed-off-by: Paolo Bonzini <pbonzini at redhat.com>

diff --git a/hw/scsi-bus.c b/hw/scsi-bus.c
index 925c3ae..add1d4f 100644
--- a/hw/scsi-bus.c
+++ b/hw/scsi-bus.c
@@ -649,7 +649,7 @@ void scsi_req_build_sense(SCSIRequest *req, SCSISense sense)
     trace_scsi_req_build_sense(req->dev->id, req->lun, req->tag,
                                sense.key, sense.asc, sense.ascq);
     memset(req->sense, 0, 18);
-    req->sense[0] = 0xf0;
+    req->sense[0] = 0x70;
     req->sense[2] = sense.key;
     req->sense[7] = 10;
     req->sense[12] = sense.asc;
@@ -1148,7 +1148,7 @@ int scsi_build_sense(uint8_t *in_buf, int in_len,
     memset(buf, 0, len);
     if (fixed) {
         /* Return fixed format sense buffer */
-        buf[0] = 0xf0;
+        buf[0] = 0x70;
         buf[2] = sense.key;
         buf[7] = 10;
         buf[12] = sense.asc;
commit e5f38ff6f530de7f14825fb117de854ed52084fa
Author: Paolo Bonzini <pbonzini at redhat.com>
Date:   Thu May 3 15:57:08 2012 +0200

    scsi: do not require a minimum allocation length for REQUEST SENSE
    
    The requirements on the REQUEST SENSE buffer size are not in my copy of SPC
    (SPC-4 r27) and not observed by LIO.  Rip them out.
    
    Signed-off-by: Paolo Bonzini <pbonzini at redhat.com>

diff --git a/hw/scsi-bus.c b/hw/scsi-bus.c
index 4090b9f..925c3ae 100644
--- a/hw/scsi-bus.c
+++ b/hw/scsi-bus.c
@@ -427,9 +427,6 @@ static int32_t scsi_target_send_command(SCSIRequest *req, uint8_t *buf)
         }
         break;
     case REQUEST_SENSE:
-        if (req->cmd.xfer < 4) {
-            goto illegal_request;
-        }
         r->len = scsi_device_get_sense(r->req.dev, r->buf,
                                        MIN(req->cmd.xfer, sizeof r->buf),
                                        (req->cmd.buf[1] & 1) == 0);
@@ -538,8 +535,8 @@ SCSIRequest *scsi_req_new(SCSIDevice *d, uint32_t tag, uint32_t lun,
             req = scsi_req_alloc(&reqops_unit_attention, d, tag, lun,
                                  hba_private);
         } else if (lun != d->lun ||
-            buf[0] == REPORT_LUNS ||
-            (buf[0] == REQUEST_SENSE && (d->sense_len || cmd.xfer < 4))) {
+                   buf[0] == REPORT_LUNS ||
+                   (buf[0] == REQUEST_SENSE && d->sense_len)) {
             req = scsi_req_alloc(&reqops_target_command, d, tag, lun,
                                  hba_private);
         } else {
commit 3c3d8a95cafb6b38515497688db5a26db67fe6ce
Author: Paolo Bonzini <pbonzini at redhat.com>
Date:   Thu May 3 14:34:45 2012 +0200

    scsi: do not require a minimum allocation length for INQUIRY
    
    The requirements on the INQUIRY buffer size are not in my copy of SPC
    (SPC-4 r27) and not observed by LIO.  Rip them out.
    
    Signed-off-by: Paolo Bonzini <pbonzini at redhat.com>

diff --git a/hw/scsi-bus.c b/hw/scsi-bus.c
index 46cd1f9..4090b9f 100644
--- a/hw/scsi-bus.c
+++ b/hw/scsi-bus.c
@@ -367,10 +367,6 @@ static bool scsi_target_emulate_inquiry(SCSITargetReq *r)
     if (r->req.cmd.buf[1] & 0x1) {
         /* Vital product data */
         uint8_t page_code = r->req.cmd.buf[2];
-        if (r->req.cmd.xfer < 4) {
-            return false;
-        }
-
         r->buf[r->len++] = page_code ; /* this page */
         r->buf[r->len++] = 0x00;
 
@@ -398,10 +394,6 @@ static bool scsi_target_emulate_inquiry(SCSITargetReq *r)
     }
 
     /* PAGE CODE == 0 */
-    if (r->req.cmd.xfer < 5) {
-        return false;
-    }
-
     r->len = MIN(r->req.cmd.xfer, 36);
     memset(r->buf, 0, r->len);
     if (r->req.lun != 0) {
diff --git a/hw/scsi-disk.c b/hw/scsi-disk.c
index 43726ff..4158032 100644
--- a/hw/scsi-disk.c
+++ b/hw/scsi-disk.c
@@ -524,11 +524,6 @@ static int scsi_disk_emulate_inquiry(SCSIRequest *req, uint8_t *outbuf)
     if (req->cmd.buf[1] & 0x1) {
         /* Vital product data */
         uint8_t page_code = req->cmd.buf[2];
-        if (req->cmd.xfer < 4) {
-            BADF("Error: Inquiry (EVPD[%02X]) buffer size %zd is "
-                 "less than 4\n", page_code, req->cmd.xfer);
-            return -1;
-        }
 
         outbuf[buflen++] = s->qdev.type & 0x1f;
         outbuf[buflen++] = page_code ; // this page
@@ -659,12 +654,6 @@ static int scsi_disk_emulate_inquiry(SCSIRequest *req, uint8_t *outbuf)
     }
 
     /* PAGE CODE == 0 */
-    if (req->cmd.xfer < 5) {
-        BADF("Error: Inquiry (STANDARD) buffer size %zd "
-             "is less than 5\n", req->cmd.xfer);
-        return -1;
-    }
-
     buflen = req->cmd.xfer;
     if (buflen > SCSI_MAX_INQUIRY_LEN) {
         buflen = SCSI_MAX_INQUIRY_LEN;
commit 065c25996b6275e306704816c6075d6c0ff66e84
Author: Paolo Bonzini <pbonzini at redhat.com>
Date:   Fri May 4 10:28:55 2012 +0200

    scsi: parse 16-byte tape CDBs
    
    The transfer length for these commands is different from the transfer
    length of the corresponding disk commands, so parse it specially.
    
    Signed-off-by: Paolo Bonzini <pbonzini at redhat.com>

diff --git a/hw/scsi-bus.c b/hw/scsi-bus.c
index 5fbf8db..46cd1f9 100644
--- a/hw/scsi-bus.c
+++ b/hw/scsi-bus.c
@@ -891,6 +891,16 @@ static int scsi_req_stream_length(SCSICommand *cmd, SCSIDevice *dev, uint8_t *bu
             cmd->xfer *= dev->blocksize;
         }
         break;
+    case READ_16:
+    case READ_REVERSE_16:
+    case VERIFY_16:
+    case WRITE_16:
+        cmd->len = 16;
+        cmd->xfer = buf[14] | (buf[13] << 8) | (buf[12] << 16);
+        if (buf[1] & 0x01) { /* fixed */
+            cmd->xfer *= dev->blocksize;
+        }
+        break;
     case REWIND:
     case START_STOP:
         cmd->len = 6;
diff --git a/hw/scsi-defs.h b/hw/scsi-defs.h
index ca24192..219c84d 100644
--- a/hw/scsi-defs.h
+++ b/hw/scsi-defs.h
@@ -92,6 +92,7 @@
 #define PERSISTENT_RESERVE_OUT 0x5f
 #define VARLENGTH_CDB         0x7f
 #define WRITE_FILEMARKS_16    0x80
+#define READ_REVERSE_16       0x81
 #define ALLOW_OVERWRITE       0x82
 #define EXTENDED_COPY         0x83
 #define ATA_PASSTHROUGH       0x85
commit f62d0594604399e89ca8ece730a2a79110de5d77
Author: Paolo Bonzini <pbonzini at redhat.com>
Date:   Thu May 3 15:28:05 2012 +0200

    scsi: do not report bogus overruns for commands in the 0x00-0x1F range
    
    Interpreting cdb[4] == 0 as a request to transfer 256 blocks is only
    needed for READ_6 and WRITE_6.  No other command in that range needs
    that special-casing, and the resulting overrun breaks scsi-testsuite's
    attempt to use command 2 as a known-invalid command.
    
    Signed-off-by: Paolo Bonzini <pbonzini at redhat.com>

diff --git a/hw/scsi-bus.c b/hw/scsi-bus.c
index 08d5088..5fbf8db 100644
--- a/hw/scsi-bus.c
+++ b/hw/scsi-bus.c
@@ -735,10 +735,6 @@ static int scsi_req_length(SCSICommand *cmd, SCSIDevice *dev, uint8_t *buf)
     case 0:
         cmd->xfer = buf[4];
         cmd->len = 6;
-        /* length 0 means 256 blocks */
-        if (cmd->xfer == 0) {
-            cmd->xfer = 256;
-        }
         break;
     case 1:
     case 2:
@@ -808,18 +804,26 @@ static int scsi_req_length(SCSICommand *cmd, SCSIDevice *dev, uint8_t *buf)
             cmd->xfer = buf[9] | (buf[8] << 8);
         }
         break;
+    case WRITE_6:
+        /* length 0 means 256 blocks */
+        if (cmd->xfer == 0) {
+            cmd->xfer = 256;
+        }
     case WRITE_10:
     case WRITE_VERIFY_10:
-    case WRITE_6:
     case WRITE_12:
     case WRITE_VERIFY_12:
     case WRITE_16:
     case WRITE_VERIFY_16:
         cmd->xfer *= dev->blocksize;
         break;
-    case READ_10:
     case READ_6:
     case READ_REVERSE:
+        /* length 0 means 256 blocks */
+        if (cmd->xfer == 0) {
+            cmd->xfer = 256;
+        }
+    case READ_10:
     case RECOVER_BUFFERED_DATA:
     case READ_12:
     case READ_16:
commit da8365dbab51c445832137aa637bb5b990174b24
Author: Paolo Bonzini <pbonzini at redhat.com>
Date:   Tue May 1 10:25:16 2012 +0200

    scsi-disk: add dpofua property
    
    Linux expects REQ_FUA to be advertised only if WRITE+FUA is faster than
    WRITE+SYNCHRONIZE CACHE, so we should not set the DPOFUA bit.  However,
    it is useful to have it for testing purposes, so add a qdev property to
    set it.
    
    Signed-off-by: Paolo Bonzini <pbonzini at redhat.com>

diff --git a/hw/scsi-disk.c b/hw/scsi-disk.c
index b1f5ef0..43726ff 100644
--- a/hw/scsi-disk.c
+++ b/hw/scsi-disk.c
@@ -62,6 +62,7 @@ typedef struct SCSIDiskReq {
 } SCSIDiskReq;
 
 #define SCSI_DISK_F_REMOVABLE   0
+#define SCSI_DISK_F_DPOFUA      1
 
 struct SCSIDiskState
 {
@@ -1103,7 +1104,7 @@ static int scsi_disk_emulate_mode_sense(SCSIDiskReq *r, uint8_t *outbuf)
     p = outbuf;
 
     if (s->qdev.type == TYPE_DISK) {
-        dev_specific_param = 0x10; /* DPOFUA */
+        dev_specific_param = s->features & (1 << SCSI_DISK_F_DPOFUA) ? 0x10 : 0;
         if (bdrv_is_read_only(s->qdev.conf.bs)) {
             dev_specific_param |= 0x80; /* Readonly.  */
         }
@@ -1935,6 +1936,8 @@ static Property scsi_hd_properties[] = {
     DEFINE_SCSI_DISK_PROPERTIES(),
     DEFINE_PROP_BIT("removable", SCSIDiskState, features,
                     SCSI_DISK_F_REMOVABLE, false),
+    DEFINE_PROP_BIT("dpofua", SCSIDiskState, features,
+                    SCSI_DISK_F_DPOFUA, false),
     DEFINE_PROP_END_OF_LIST(),
 };
 
@@ -2038,6 +2041,8 @@ static Property scsi_disk_properties[] = {
     DEFINE_SCSI_DISK_PROPERTIES(),
     DEFINE_PROP_BIT("removable", SCSIDiskState, features,
                     SCSI_DISK_F_REMOVABLE, false),
+    DEFINE_PROP_BIT("dpofua", SCSIDiskState, features,
+                    SCSI_DISK_F_DPOFUA, false),
     DEFINE_PROP_END_OF_LIST(),
 };
 
commit bfe3d7ac6d838b1931678d96d01c45d84c7e3de8
Author: Paolo Bonzini <pbonzini at redhat.com>
Date:   Tue May 1 10:23:54 2012 +0200

    scsi: change "removable" field to host many features
    
    It is pointless to add a uint32_t field for every new feature.
    Since we will need a new feature soon, convert accesses to "removable"
    to look at bit 0 only.
    
    Signed-off-by: Paolo Bonzini <pbonzini at redhat.com>

diff --git a/hw/scsi-disk.c b/hw/scsi-disk.c
index fbb1041..b1f5ef0 100644
--- a/hw/scsi-disk.c
+++ b/hw/scsi-disk.c
@@ -61,10 +61,12 @@ typedef struct SCSIDiskReq {
     BlockAcctCookie acct;
 } SCSIDiskReq;
 
+#define SCSI_DISK_F_REMOVABLE   0
+
 struct SCSIDiskState
 {
     SCSIDevice qdev;
-    uint32_t removable;
+    uint32_t features;
     bool media_changed;
     bool media_event;
     bool eject_request;
@@ -669,7 +671,7 @@ static int scsi_disk_emulate_inquiry(SCSIRequest *req, uint8_t *outbuf)
     memset(outbuf, 0, buflen);
 
     outbuf[0] = s->qdev.type & 0x1f;
-    outbuf[1] = s->removable ? 0x80 : 0;
+    outbuf[1] = (s->features & (1 << SCSI_DISK_F_REMOVABLE)) ? 0x80 : 0;
     if (s->qdev.type == TYPE_ROM) {
         memcpy(&outbuf[16], "QEMU CD-ROM     ", 16);
     } else {
@@ -1710,7 +1712,8 @@ static int scsi_initfn(SCSIDevice *dev)
         return -1;
     }
 
-    if (!s->removable && !bdrv_is_inserted(s->qdev.conf.bs)) {
+    if (!(s->features & (1 << SCSI_DISK_F_REMOVABLE)) &&
+        !bdrv_is_inserted(s->qdev.conf.bs)) {
         error_report("Device needs media, but drive is empty");
         return -1;
     }
@@ -1732,7 +1735,7 @@ static int scsi_initfn(SCSIDevice *dev)
         return -1;
     }
 
-    if (s->removable) {
+    if (s->features & (1 << SCSI_DISK_F_REMOVABLE)) {
         bdrv_set_dev_ops(s->qdev.conf.bs, &scsi_cd_block_ops, s);
     }
     bdrv_set_buffer_alignment(s->qdev.conf.bs, s->qdev.blocksize);
@@ -1755,7 +1758,7 @@ static int scsi_cd_initfn(SCSIDevice *dev)
     SCSIDiskState *s = DO_UPCAST(SCSIDiskState, qdev, dev);
     s->qdev.blocksize = 2048;
     s->qdev.type = TYPE_ROM;
-    s->removable = true;
+    s->features |= 1 << SCSI_DISK_F_REMOVABLE;
     return scsi_initfn(&s->qdev);
 }
 
@@ -1828,7 +1831,9 @@ static int get_device_type(SCSIDiskState *s)
         return -1;
     }
     s->qdev.type = buf[0];
-    s->removable = (buf[1] & 0x80) != 0;
+    if (buf[1] & 0x80) {
+        s->features |= 1 << SCSI_DISK_F_REMOVABLE;
+    }
     return 0;
 }
 
@@ -1928,7 +1933,8 @@ static SCSIRequest *scsi_block_new_request(SCSIDevice *d, uint32_t tag,
 
 static Property scsi_hd_properties[] = {
     DEFINE_SCSI_DISK_PROPERTIES(),
-    DEFINE_PROP_BIT("removable", SCSIDiskState, removable, 0, false),
+    DEFINE_PROP_BIT("removable", SCSIDiskState, features,
+                    SCSI_DISK_F_REMOVABLE, false),
     DEFINE_PROP_END_OF_LIST(),
 };
 
@@ -2030,7 +2036,8 @@ static TypeInfo scsi_block_info = {
 
 static Property scsi_disk_properties[] = {
     DEFINE_SCSI_DISK_PROPERTIES(),
-    DEFINE_PROP_BIT("removable", SCSIDiskState, removable, 0, false),
+    DEFINE_PROP_BIT("removable", SCSIDiskState, features,
+                    SCSI_DISK_F_REMOVABLE, false),
     DEFINE_PROP_END_OF_LIST(),
 };
 
commit 381b634c275ca1a2806e97392527bbfc01bcb333
Author: Ronnie Sahlberg <ronniesahlberg at gmail.com>
Date:   Sat Apr 28 23:49:36 2012 +1000

    scsi: Specify the xfer direction for UNMAP and ATA_PASSTHROUGH commands
    
    scsi_cmd_xfer_mode() is used to specify the xfer direction for SCSI
    commands that come in from the guest.  If the direction is set incorrectly
    this will eventually cause QEMU to kernel-panic the guest.
    
    Add UNMAP and ATAPASSTHROUGH as commands that send data to the device.
    
    Without this change, recent kernels will send both UNMAP as well
    as ATAPASSTHROUGH commands to any /dev/sg* device, which due to the
    incorrect xfer direction very quickly causes the guest kernel to crash.
    
    Example causing a crash without the patch applied:
    
    ./x86_64-softmmu/qemu-system-x86_64 -m 1024 -enable-kvm -cdrom linuxmint-12-gnome-dvd-64bit.iso -drive file=/dev/sg4,if=scsi,bus=0,unit=6
    
    Signed-off-by: Ronnie Sahlberg <ronniesahlberg at gmail.com>
    Signed-off-by: Paolo Bonzini <pbonzini at redhat.com>

diff --git a/hw/scsi-bus.c b/hw/scsi-bus.c
index 5640aae..08d5088 100644
--- a/hw/scsi-bus.c
+++ b/hw/scsi-bus.c
@@ -940,6 +940,7 @@ static void scsi_cmd_xfer_mode(SCSICommand *cmd)
     case WRITE_LONG_10:
     case WRITE_SAME_10:
     case WRITE_SAME_16:
+    case UNMAP:
     case SEARCH_HIGH_12:
     case SEARCH_EQUAL_12:
     case SEARCH_LOW_12:
@@ -949,6 +950,7 @@ static void scsi_cmd_xfer_mode(SCSICommand *cmd)
     case SEND_DVD_STRUCTURE:
     case PERSISTENT_RESERVE_OUT:
     case MAINTENANCE_OUT:
+    case ATA_PASSTHROUGH:
         cmd->mode = SCSI_XFER_TO_DEV;
         break;
     default:
commit a5ee9085627eaeb501db31e3758df4e18500be71
Author: Paolo Bonzini <pbonzini at redhat.com>
Date:   Wed Feb 8 10:40:37 2012 +0100

    scsi: fix WRITE SAME transfer length and direction
    
    Signed-off-by: Paolo Bonzini <pbonzini at redhat.com>

diff --git a/hw/scsi-bus.c b/hw/scsi-bus.c
index c29a4ae..5640aae 100644
--- a/hw/scsi-bus.c
+++ b/hw/scsi-bus.c
@@ -791,7 +791,8 @@ static int scsi_req_length(SCSICommand *cmd, SCSIDevice *dev, uint8_t *buf)
     case MODE_SENSE:
         break;
     case WRITE_SAME_10:
-        cmd->xfer = 1;
+    case WRITE_SAME_16:
+        cmd->xfer = dev->blocksize;
         break;
     case READ_CAPACITY_10:
         cmd->xfer = 8;
@@ -909,6 +910,10 @@ static int scsi_req_stream_length(SCSICommand *cmd, SCSIDevice *dev, uint8_t *bu
 
 static void scsi_cmd_xfer_mode(SCSICommand *cmd)
 {
+    if (!cmd->xfer) {
+        cmd->mode = SCSI_XFER_NONE;
+        return;
+    }
     switch (cmd->buf[0]) {
     case WRITE_6:
     case WRITE_10:
@@ -934,6 +939,7 @@ static void scsi_cmd_xfer_mode(SCSICommand *cmd)
     case UPDATE_BLOCK:
     case WRITE_LONG_10:
     case WRITE_SAME_10:
+    case WRITE_SAME_16:
     case SEARCH_HIGH_12:
     case SEARCH_EQUAL_12:
     case SEARCH_LOW_12:
@@ -946,11 +952,7 @@ static void scsi_cmd_xfer_mode(SCSICommand *cmd)
         cmd->mode = SCSI_XFER_TO_DEV;
         break;
     default:
-        if (cmd->xfer)
-            cmd->mode = SCSI_XFER_FROM_DEV;
-        else {
-            cmd->mode = SCSI_XFER_NONE;
-        }
+        cmd->mode = SCSI_XFER_FROM_DEV;
         break;
     }
 }
diff --git a/hw/scsi-disk.c b/hw/scsi-disk.c
index eca00a6..fbb1041 100644
--- a/hw/scsi-disk.c
+++ b/hw/scsi-disk.c
@@ -1566,8 +1566,11 @@ static int32_t scsi_send_command(SCSIRequest *req, uint8_t *buf)
         }
         break;
     case WRITE_SAME_10:
+        len = lduw_be_p(&buf[7]);
+        goto write_same;
     case WRITE_SAME_16:
-        len = r->req.cmd.xfer / s->qdev.blocksize;
+        len = ldl_be_p(&buf[10]) & 0xffffffffULL;
+    write_same:
 
         DPRINTF("WRITE SAME() (sector %" PRId64 ", count %d)\n",
                 r->req.cmd.lba, len);
commit 31e8fd86f24b4eec8a1708d712bf0532460bb0a5
Author: Paolo Bonzini <pbonzini at redhat.com>
Date:   Tue Apr 24 08:41:04 2012 +0200

    scsi: fix refcounting for reads
    
    Recently introduced FUA support also gave us a use-after-free
    of the BlockAcctCookie within a SCSIDiskReq, due to unbalanced
    reference counting.
    
    The patch fixes this by making scsi_do_read look like a combination
    of scsi_*_complete + scsi_*_data.  It does both a ref (like
    scsi_read_data) and an unref (like scsi_flush_complete).
    
    Reported-by: David Gibson <david at gibson.dropbear.id.au>
    Signed-off-by: Paolo Bonzini <pbonzini at redhat.com>

diff --git a/hw/scsi-disk.c b/hw/scsi-disk.c
index a029ab6..eca00a6 100644
--- a/hw/scsi-disk.c
+++ b/hw/scsi-disk.c
@@ -296,6 +296,13 @@ static void scsi_do_read(void *opaque, int ret)
         }
     }
 
+    if (r->req.io_canceled) {
+        return;
+    }
+
+    /* The request is used as the AIO opaque value, so add a ref.  */
+    scsi_req_ref(&r->req);
+
     if (r->req.sg) {
         dma_acct_start(s->qdev.conf.bs, &r->acct, r->req.sg, BDRV_ACCT_READ);
         r->req.resid -= r->req.sg->size;
commit 12a08998fe4f749af3622385521829a5143e6ff1
Author: Paolo Bonzini <pbonzini at redhat.com>
Date:   Wed Feb 8 11:49:43 2012 +0100

    scsi: prevent data transfer overflow
    
    Avoid sending more than 2GB of data, as that can cause overflows
    in int32_t variables.
    
    Signed-off-by: Paolo Bonzini <pbonzini at redhat.com>

diff --git a/hw/scsi-bus.c b/hw/scsi-bus.c
index dbdb99c..c29a4ae 100644
--- a/hw/scsi-bus.c
+++ b/hw/scsi-bus.c
@@ -239,6 +239,18 @@ int scsi_bus_legacy_handle_cmdline(SCSIBus *bus)
     return res;
 }
 
+static int32_t scsi_invalid_field(SCSIRequest *req, uint8_t *buf)
+{
+    scsi_req_build_sense(req, SENSE_CODE(INVALID_FIELD));
+    scsi_req_complete(req, CHECK_CONDITION);
+    return 0;
+}
+
+static const struct SCSIReqOps reqops_invalid_field = {
+    .size         = sizeof(SCSIRequest),
+    .send_command = scsi_invalid_field
+};
+
 /* SCSIReqOps implementation for invalid commands.  */
 
 static int32_t scsi_invalid_command(SCSIRequest *req, uint8_t *buf)
@@ -517,18 +529,20 @@ SCSIRequest *scsi_req_new(SCSIDevice *d, uint32_t tag, uint32_t lun,
                                       cmd.lba);
         }
 
-        if ((d->unit_attention.key == UNIT_ATTENTION ||
-             bus->unit_attention.key == UNIT_ATTENTION) &&
-            (buf[0] != INQUIRY &&
-             buf[0] != REPORT_LUNS &&
-             buf[0] != GET_CONFIGURATION &&
-             buf[0] != GET_EVENT_STATUS_NOTIFICATION &&
-
-             /*
-              * If we already have a pending unit attention condition,
-              * report this one before triggering another one.
-              */
-             !(buf[0] == REQUEST_SENSE && d->sense_is_ua))) {
+        if (cmd.xfer > INT32_MAX) {
+            req = scsi_req_alloc(&reqops_invalid_field, d, tag, lun, hba_private);
+        } else if ((d->unit_attention.key == UNIT_ATTENTION ||
+                   bus->unit_attention.key == UNIT_ATTENTION) &&
+                  (buf[0] != INQUIRY &&
+                   buf[0] != REPORT_LUNS &&
+                   buf[0] != GET_CONFIGURATION &&
+                   buf[0] != GET_EVENT_STATUS_NOTIFICATION &&
+
+                   /*
+                    * If we already have a pending unit attention condition,
+                    * report this one before triggering another one.
+                    */
+                   !(buf[0] == REQUEST_SENSE && d->sense_is_ua))) {
             req = scsi_req_alloc(&reqops_unit_attention, d, tag, lun,
                                  hba_private);
         } else if (lun != d->lun ||
commit fa6acb0c2ff3f256fb5f2fede4768b27374b03ca
Author: Ronnie Sahlberg <ronniesahlberg at gmail.com>
Date:   Tue Apr 24 16:29:04 2012 +1000

    ISCSI: Add support for thin-provisioning via discard/UNMAP and bigger LUNs
    
    Update the configure test for libiscsi support to detect version 1.3
    or later.  Version 1.3 of libiscsi provides both READCAPACITY16 as well
    as UNMAP commands.
    
    Update the iscsi block layer to use READCAPACITY16 to detect the size of
    the LUN instead of READCAPACITY10. This allows support for LUNs larger
    than 2TB.
    
    Update to implement bdrv_aio_discard() using the UNMAP command.
    This allows us to use thin-provisioned LUNs from TGTD and other iSCSI
    targets that support thin-provisioning.
    
    Signed-off-by: Ronnie Sahlberg <ronniesahlberg at gmail.com>
    [squashed in subsequent patch from Ronnie to fix off-by-one in LBA count]
    Signed-off-by: Paolo Bonzini <pbonzini at redhat.com>

diff --git a/block/iscsi.c b/block/iscsi.c
index 5222726..d37c4ee 100644
--- a/block/iscsi.c
+++ b/block/iscsi.c
@@ -383,6 +383,65 @@ iscsi_aio_flush(BlockDriverState *bs,
     return &acb->common;
 }
 
+static void
+iscsi_unmap_cb(struct iscsi_context *iscsi, int status,
+                     void *command_data, void *opaque)
+{
+    IscsiAIOCB *acb = opaque;
+
+    if (acb->canceled != 0) {
+        qemu_aio_release(acb);
+        scsi_free_scsi_task(acb->task);
+        acb->task = NULL;
+        return;
+    }
+
+    acb->status = 0;
+    if (status < 0) {
+        error_report("Failed to unmap data on iSCSI lun. %s",
+                     iscsi_get_error(iscsi));
+        acb->status = -EIO;
+    }
+
+    iscsi_schedule_bh(iscsi_readv_writev_bh_cb, acb);
+    scsi_free_scsi_task(acb->task);
+    acb->task = NULL;
+}
+
+static BlockDriverAIOCB *
+iscsi_aio_discard(BlockDriverState *bs,
+                  int64_t sector_num, int nb_sectors,
+                  BlockDriverCompletionFunc *cb, void *opaque)
+{
+    IscsiLun *iscsilun = bs->opaque;
+    struct iscsi_context *iscsi = iscsilun->iscsi;
+    IscsiAIOCB *acb;
+    struct unmap_list list[1];
+
+    acb = qemu_aio_get(&iscsi_aio_pool, bs, cb, opaque);
+
+    acb->iscsilun = iscsilun;
+    acb->canceled   = 0;
+
+    list[0].lba = sector_qemu2lun(sector_num, iscsilun);
+    list[0].num = nb_sectors * BDRV_SECTOR_SIZE / iscsilun->block_size;
+
+    acb->task = iscsi_unmap_task(iscsi, iscsilun->lun,
+                                 0, 0, &list[0], 1,
+                                 iscsi_unmap_cb,
+                                 acb);
+    if (acb->task == NULL) {
+        error_report("iSCSI: Failed to send unmap command. %s",
+                     iscsi_get_error(iscsi));
+        qemu_aio_release(acb);
+        return NULL;
+    }
+
+    iscsi_set_events(iscsilun);
+
+    return &acb->common;
+}
+
 static int64_t
 iscsi_getlength(BlockDriverState *bs)
 {
@@ -396,11 +455,11 @@ iscsi_getlength(BlockDriverState *bs)
 }
 
 static void
-iscsi_readcapacity10_cb(struct iscsi_context *iscsi, int status,
+iscsi_readcapacity16_cb(struct iscsi_context *iscsi, int status,
                         void *command_data, void *opaque)
 {
     struct IscsiTask *itask = opaque;
-    struct scsi_readcapacity10 *rc10;
+    struct scsi_readcapacity16 *rc16;
     struct scsi_task *task = command_data;
 
     if (status != 0) {
@@ -412,26 +471,25 @@ iscsi_readcapacity10_cb(struct iscsi_context *iscsi, int status,
         return;
     }
 
-    rc10 = scsi_datain_unmarshall(task);
-    if (rc10 == NULL) {
-        error_report("iSCSI: Failed to unmarshall readcapacity10 data.");
+    rc16 = scsi_datain_unmarshall(task);
+    if (rc16 == NULL) {
+        error_report("iSCSI: Failed to unmarshall readcapacity16 data.");
         itask->status   = 1;
         itask->complete = 1;
         scsi_free_scsi_task(task);
         return;
     }
 
-    itask->iscsilun->block_size = rc10->block_size;
-    itask->iscsilun->num_blocks = rc10->lba;
-    itask->bs->total_sectors = (uint64_t)rc10->lba *
-                               rc10->block_size / BDRV_SECTOR_SIZE ;
+    itask->iscsilun->block_size = rc16->block_length;
+    itask->iscsilun->num_blocks = rc16->returned_lba + 1;
+    itask->bs->total_sectors    = itask->iscsilun->num_blocks *
+                               itask->iscsilun->block_size / BDRV_SECTOR_SIZE ;
 
     itask->status   = 0;
     itask->complete = 1;
     scsi_free_scsi_task(task);
 }
 
-
 static void
 iscsi_connect_cb(struct iscsi_context *iscsi, int status, void *command_data,
                  void *opaque)
@@ -445,10 +503,10 @@ iscsi_connect_cb(struct iscsi_context *iscsi, int status, void *command_data,
         return;
     }
 
-    task = iscsi_readcapacity10_task(iscsi, itask->iscsilun->lun, 0, 0,
-                                   iscsi_readcapacity10_cb, opaque);
+    task = iscsi_readcapacity16_task(iscsi, itask->iscsilun->lun,
+                                   iscsi_readcapacity16_cb, opaque);
     if (task == NULL) {
-        error_report("iSCSI: failed to send readcapacity command.");
+        error_report("iSCSI: failed to send readcapacity16 command.");
         itask->status   = 1;
         itask->complete = 1;
         return;
@@ -700,6 +758,8 @@ static BlockDriver bdrv_iscsi = {
     .bdrv_aio_readv  = iscsi_aio_readv,
     .bdrv_aio_writev = iscsi_aio_writev,
     .bdrv_aio_flush  = iscsi_aio_flush,
+
+    .bdrv_aio_discard = iscsi_aio_discard,
 };
 
 static void iscsi_block_init(void)
diff --git a/configure b/configure
index 0111774..0e3615b 100755
--- a/configure
+++ b/configure
@@ -2546,10 +2546,13 @@ fi
 
 ##########################################
 # Do we have libiscsi
+# We check for iscsi_unmap_sync() to make sure we have a
+# recent enough version of libiscsi.
 if test "$libiscsi" != "no" ; then
   cat > $TMPC << EOF
+#include <stdio.h>
 #include <iscsi/iscsi.h>
-int main(void) { iscsi_create_context(""); return 0; }
+int main(void) { iscsi_unmap_sync(NULL,0,0,0,NULL,0); return 0; }
 EOF
   if compile_prog "-Werror" "-liscsi" ; then
     libiscsi="yes"
commit 8f473dd104f0937ce98523fa6f9de0bd845aebbe
Author: Gerd Hoffmann <kraxel at redhat.com>
Date:   Thu May 3 22:41:28 2012 +0200

    fix build with pulseaudio versions older than 0.9.11
    
    Signed-off-by: Gerd Hoffmann <kraxel at redhat.com>
    Signed-off-by: malc <av1474 at comtv.ru>

diff --git a/audio/paaudio.c b/audio/paaudio.c
index aa15f16..8b69778 100644
--- a/audio/paaudio.c
+++ b/audio/paaudio.c
@@ -56,6 +56,26 @@ static void GCC_FMT_ATTR (2, 3) qpa_logerr (int err, const char *fmt, ...)
     AUD_log (AUDIO_CAP, "Reason: %s\n", pa_strerror (err));
 }
 
+#ifndef PA_CONTEXT_IS_GOOD
+static inline int PA_CONTEXT_IS_GOOD(pa_context_state_t x)
+{
+    return
+        x == PA_CONTEXT_CONNECTING ||
+        x == PA_CONTEXT_AUTHORIZING ||
+        x == PA_CONTEXT_SETTING_NAME ||
+        x == PA_CONTEXT_READY;
+}
+#endif
+
+#ifndef PA_STREAM_IS_GOOD
+static inline int PA_STREAM_IS_GOOD(pa_stream_state_t x)
+{
+    return
+        x == PA_STREAM_CREATING ||
+        x == PA_STREAM_READY;
+}
+#endif
+
 #define CHECK_SUCCESS_GOTO(c, rerror, expression, label)        \
     do {                                                        \
         if (!(expression)) {                                    \
@@ -481,12 +501,16 @@ static pa_stream *qpa_simple_new (
     if (dir == PA_STREAM_PLAYBACK) {
         r = pa_stream_connect_playback (stream, dev, attr,
                                         PA_STREAM_INTERPOLATE_TIMING
+#ifdef PA_STREAM_ADJUST_LATENCY
                                         |PA_STREAM_ADJUST_LATENCY
+#endif
                                         |PA_STREAM_AUTO_TIMING_UPDATE, NULL, NULL);
     } else {
         r = pa_stream_connect_record (stream, dev, attr,
                                       PA_STREAM_INTERPOLATE_TIMING
+#ifdef PA_STREAM_ADJUST_LATENCY
                                       |PA_STREAM_ADJUST_LATENCY
+#endif
                                       |PA_STREAM_AUTO_TIMING_UPDATE);
     }
 
@@ -681,7 +705,9 @@ static int qpa_ctl_out (HWVoiceOut *hw, int cmd, ...)
     pa_cvolume v;
     paaudio *g = &glob_paaudio;
 
-    pa_cvolume_init (&v);
+#ifdef PA_CHECK_VERSION    /* macro is present in 0.9.16+ */
+    pa_cvolume_init (&v);  /* function is present in 0.9.13+ */
+#endif
 
     switch (cmd) {
     case VOICE_VOLUME:
@@ -731,7 +757,9 @@ static int qpa_ctl_in (HWVoiceIn *hw, int cmd, ...)
     pa_cvolume v;
     paaudio *g = &glob_paaudio;
 
+#ifdef PA_CHECK_VERSION
     pa_cvolume_init (&v);
+#endif
 
     switch (cmd) {
     case VOICE_VOLUME:
commit 1a49ef2ad3c1c3c50e6aea348260412f98ea862d
Author: Alexander Graf <agraf at suse.de>
Date:   Tue May 1 16:30:28 2012 +0100

    linux-user: fix emulation of /proc/self/maps
    
    Improve the emulation of /proc/self/maps by reading the underlying
    host maps file and passing lines through with addresses adjusted
    to be guest addresses. This is necessary to avoid false triggers
    of the glibc check that a format string containing '%n' is not in
    writable memory. (For an example see the bug reported in
    https://bugs.launchpad.net/qemu-linaro/+bug/947888 where gpg aborts.)
    
    Signed-off-by: Alexander Graf <agraf at suse.de>
    Signed-off-by: Peter Maydell <peter.maydell at linaro.org>
    Signed-off-by: Riku Voipio <riku.voipio at linaro.org>

diff --git a/linux-user/syscall.c b/linux-user/syscall.c
index 801b8ed..20d2a74 100644
--- a/linux-user/syscall.c
+++ b/linux-user/syscall.c
@@ -4866,13 +4866,53 @@ int get_osversion(void)
 
 static int open_self_maps(void *cpu_env, int fd)
 {
+#if defined(TARGET_ARM) || defined(TARGET_M68K) || defined(TARGET_UNICORE32)
     TaskState *ts = ((CPUArchState *)cpu_env)->opaque;
+#endif
+    FILE *fp;
+    char *line = NULL;
+    size_t len = 0;
+    ssize_t read;
+
+    fp = fopen("/proc/self/maps", "r");
+    if (fp == NULL) {
+        return -EACCES;
+    }
 
+    while ((read = getline(&line, &len, fp)) != -1) {
+        int fields, dev_maj, dev_min, inode;
+        uint64_t min, max, offset;
+        char flag_r, flag_w, flag_x, flag_p;
+        char path[512] = "";
+        fields = sscanf(line, "%"PRIx64"-%"PRIx64" %c%c%c%c %"PRIx64" %x:%x %d"
+                        " %512s", &min, &max, &flag_r, &flag_w, &flag_x,
+                        &flag_p, &offset, &dev_maj, &dev_min, &inode, path);
+
+        if ((fields < 10) || (fields > 11)) {
+            continue;
+        }
+        if (!strncmp(path, "[stack]", 7)) {
+            continue;
+        }
+        if (h2g_valid(min) && h2g_valid(max)) {
+            dprintf(fd, TARGET_ABI_FMT_lx "-" TARGET_ABI_FMT_lx
+                    " %c%c%c%c %08" PRIx64 " %02x:%02x %d%s%s\n",
+                    h2g(min), h2g(max), flag_r, flag_w,
+                    flag_x, flag_p, offset, dev_maj, dev_min, inode,
+                    path[0] ? "          " : "", path);
+        }
+    }
+
+    free(line);
+    fclose(fp);
+
+#if defined(TARGET_ARM) || defined(TARGET_M68K) || defined(TARGET_UNICORE32)
     dprintf(fd, "%08llx-%08llx rw-p %08llx 00:00 0          [stack]\n",
                 (unsigned long long)ts->info->stack_limit,
                 (unsigned long long)(ts->stack_base + (TARGET_PAGE_SIZE - 1))
                                      & TARGET_PAGE_MASK,
-                (unsigned long long)ts->stack_base);
+                (unsigned long long)0);
+#endif
 
     return 0;
 }
commit 209c48491835db84ab728f93209c00954c9e4470
Author: Andreas Färber <afaerber at suse.de>
Date:   Wed May 2 00:10:43 2012 +0200

    linux-user: Clean up interim solution for exit syscall
    
    After all target CPUs have been QOM'ified, we no longer need an #ifdef
    to switch between object_delete() and g_free() in NPTL thread exit.
    
    Signed-off-by: Andreas Färber <afaerber at suse.de>
    Signed-off-by: Riku Voipio <riku.voipio at linaro.org>

diff --git a/linux-user/syscall.c b/linux-user/syscall.c
index 7128618..801b8ed 100644
--- a/linux-user/syscall.c
+++ b/linux-user/syscall.c
@@ -5045,11 +5045,7 @@ abi_long do_syscall(void *cpu_env, int num, abi_long arg1,
                         NULL, NULL, 0);
           }
           thread_env = NULL;
-#ifdef ENV_GET_CPU
           object_delete(OBJECT(ENV_GET_CPU(cpu_env)));
-#else
-          g_free(cpu_env);
-#endif
           g_free(ts);
           pthread_exit(NULL);
       }
commit f05ae5379e40f81a6c8526d891693af8bf6e62da
Author: malc <av1474 at comtv.ru>
Date:   Thu May 3 15:48:49 2012 +0400

    Bail out if CONFIG_TCG_PASS_AREG0 is defined
    
    Signed-off-by: malc <av1474 at comtv.ru>

diff --git a/tcg/ppc/tcg-target.c b/tcg/ppc/tcg-target.c
index b0aa914..dc40716 100644
--- a/tcg/ppc/tcg-target.c
+++ b/tcg/ppc/tcg-target.c
@@ -509,6 +509,7 @@ static void tcg_out_call (TCGContext *s, tcg_target_long arg, int const_arg)
 #include "../../softmmu_defs.h"
 
 #ifdef CONFIG_TCG_PASS_AREG0
+#error CONFIG_TCG_PASS_AREG0 is not supported
 /* helper signature: helper_ld_mmu(CPUState *env, target_ulong addr,
    int mmu_idx) */
 static const void * const qemu_ld_helpers[4] = {
@@ -622,16 +623,6 @@ static void tcg_out_qemu_ld (TCGContext *s, const TCGArg *args, int opc)
     tcg_out_movi (s, TCG_TYPE_I32, 5, mem_index);
 #endif
 
-#ifdef CONFIG_TCG_PASS_AREG0
-    /* XXX/FIXME: suboptimal */
-    tcg_out_mov(s, TCG_TYPE_I32, tcg_target_call_iarg_regs[2],
-                tcg_target_call_iarg_regs[1]);
-    tcg_out_mov(s, TCG_TYPE_TL, tcg_target_call_iarg_regs[1],
-                tcg_target_call_iarg_regs[0]);
-    tcg_out_mov(s, TCG_TYPE_PTR, tcg_target_call_iarg_regs[0],
-                TCG_AREG0);
-#endif
-
     tcg_out_call (s, (tcg_target_long) qemu_ld_helpers[s_bits], 1);
     switch (opc) {
     case 0|4:
@@ -863,17 +854,6 @@ static void tcg_out_qemu_st (TCGContext *s, const TCGArg *args, int opc)
     ir++;
 
     tcg_out_movi (s, TCG_TYPE_I32, ir, mem_index);
-#ifdef CONFIG_TCG_PASS_AREG0
-    /* XXX/FIXME: suboptimal */
-    tcg_out_mov(s, TCG_TYPE_I32, tcg_target_call_iarg_regs[3],
-                tcg_target_call_iarg_regs[2]);
-    tcg_out_mov(s, TCG_TYPE_I64, tcg_target_call_iarg_regs[2],
-                tcg_target_call_iarg_regs[1]);
-    tcg_out_mov(s, TCG_TYPE_TL, tcg_target_call_iarg_regs[1],
-                tcg_target_call_iarg_regs[0]);
-    tcg_out_mov(s, TCG_TYPE_PTR, tcg_target_call_iarg_regs[0],
-                TCG_AREG0);
-#endif
     tcg_out_call (s, (tcg_target_long) qemu_st_helpers[opc], 1);
     label2_ptr = s->code_ptr;
     tcg_out32 (s, B);
commit f6af014e71f7c760db4ff812effd723cc6783c22
Author: malc <av1474 at comtv.ru>
Date:   Thu May 3 15:47:39 2012 +0400

    Restore consistent formatting
    
    Signed-off-by: malc <av1474 at comtv.ru>

diff --git a/tcg/ppc64/tcg-target.c b/tcg/ppc64/tcg-target.c
index f2ad9e3..d0b067b 100644
--- a/tcg/ppc64/tcg-target.c
+++ b/tcg/ppc64/tcg-target.c
@@ -674,12 +674,12 @@ static void tcg_out_qemu_ld (TCGContext *s, const TCGArg *args, int opc)
 
 #ifdef CONFIG_TCG_PASS_AREG0
     /* XXX/FIXME: suboptimal */
-    tcg_out_mov(s, TCG_TYPE_I32, tcg_target_call_iarg_regs[2],
-                tcg_target_call_iarg_regs[1]);
-    tcg_out_mov(s, TCG_TYPE_TL, tcg_target_call_iarg_regs[1],
-                tcg_target_call_iarg_regs[0]);
-    tcg_out_mov(s, TCG_TYPE_PTR, tcg_target_call_iarg_regs[0],
-                TCG_AREG0);
+    tcg_out_mov (s, TCG_TYPE_I32, tcg_target_call_iarg_regs[2],
+                 tcg_target_call_iarg_regs[1]);
+    tcg_out_mov (s, TCG_TYPE_TL, tcg_target_call_iarg_regs[1],
+                 tcg_target_call_iarg_regs[0]);
+    tcg_out_mov (s, TCG_TYPE_PTR, tcg_target_call_iarg_regs[0],
+                 TCG_AREG0);
 #endif
     tcg_out_call (s, (tcg_target_long) qemu_ld_helpers[s_bits], 1);
 
@@ -831,14 +831,14 @@ static void tcg_out_qemu_st (TCGContext *s, const TCGArg *args, int opc)
 
 #ifdef CONFIG_TCG_PASS_AREG0
     /* XXX/FIXME: suboptimal */
-    tcg_out_mov(s, TCG_TYPE_I32, tcg_target_call_iarg_regs[3],
-                tcg_target_call_iarg_regs[2]);
-    tcg_out_mov(s, TCG_TYPE_I64, tcg_target_call_iarg_regs[2],
-                tcg_target_call_iarg_regs[1]);
-    tcg_out_mov(s, TCG_TYPE_TL, tcg_target_call_iarg_regs[1],
-                tcg_target_call_iarg_regs[0]);
-    tcg_out_mov(s, TCG_TYPE_PTR, tcg_target_call_iarg_regs[0],
-                TCG_AREG0);
+    tcg_out_mov (s, TCG_TYPE_I32, tcg_target_call_iarg_regs[3],
+                 tcg_target_call_iarg_regs[2]);
+    tcg_out_mov (s, TCG_TYPE_I64, tcg_target_call_iarg_regs[2],
+                 tcg_target_call_iarg_regs[1]);
+    tcg_out_mov (s, TCG_TYPE_TL, tcg_target_call_iarg_regs[1],
+                 tcg_target_call_iarg_regs[0]);
+    tcg_out_mov (s, TCG_TYPE_PTR, tcg_target_call_iarg_regs[0],
+                 TCG_AREG0);
 #endif
     tcg_out_call (s, (tcg_target_long) qemu_st_helpers[opc], 1);
 
@@ -926,9 +926,9 @@ static void tcg_target_qemu_prologue (TCGContext *s)
         ;
     frame_size = (frame_size + 15) & ~15;
 
-    tcg_set_frame(s, TCG_REG_CALL_STACK, frame_size
-                  - CPU_TEMP_BUF_NLONGS * sizeof(long),
-                  CPU_TEMP_BUF_NLONGS * sizeof(long));
+    tcg_set_frame (s, TCG_REG_CALL_STACK, frame_size
+                   - CPU_TEMP_BUF_NLONGS * sizeof (long),
+                   CPU_TEMP_BUF_NLONGS * sizeof (long));
 
 #ifndef __APPLE__
     /* First emit adhoc function descriptor */
@@ -952,7 +952,7 @@ static void tcg_target_qemu_prologue (TCGContext *s)
 #ifdef CONFIG_USE_GUEST_BASE
     if (GUEST_BASE) {
         tcg_out_movi (s, TCG_TYPE_I64, TCG_GUEST_BASE_REG, GUEST_BASE);
-        tcg_regset_set_reg(s->reserved_regs, TCG_GUEST_BASE_REG);
+        tcg_regset_set_reg (s->reserved_regs, TCG_GUEST_BASE_REG);
     }
 #endif
 
commit ddf9f4b707ca18adec4944a484caad1469c07c23
Author: Alon Levy <alevy at redhat.com>
Date:   Wed Apr 25 12:43:31 2012 +0300

    qxl: don't assert on guest create_guest_primary
    
    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 c614c91..6c11e70 100644
--- a/hw/qxl.c
+++ b/hw/qxl.c
@@ -1191,7 +1191,10 @@ static void qxl_create_guest_primary(PCIQXLDevice *qxl, int loadvm,
     QXLDevSurfaceCreate surface;
     QXLSurfaceCreate *sc = &qxl->guest_primary.surface;
 
-    assert(qxl->mode != QXL_MODE_NATIVE);
+    if (qxl->mode == QXL_MODE_NATIVE) {
+        qxl_guest_bug(qxl, "%s: nop since already in QXL_MODE_NATIVE",
+                      __func__);
+    }
     qxl_exit_vga_mode(qxl);
 
     surface.format     = le32_to_cpu(sc->format);
commit 4763e2cadd3b2ecfc41e83b99b88b8a68d2e6055
Author: Alon Levy <alevy at redhat.com>
Date:   Wed Apr 25 12:13:25 2012 +0300

    qxl: ioport_write: remove guest trigerrable abort
    
    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 44a167a..c614c91 100644
--- a/hw/qxl.c
+++ b/hw/qxl.c
@@ -1464,8 +1464,7 @@ async_common:
         qxl_spice_destroy_surfaces(d, async);
         break;
     default:
-        fprintf(stderr, "%s: ioport=0x%x, abort()\n", __FUNCTION__, io_port);
-        abort();
+        qxl_guest_bug(d, "%s: unexpected ioport=0x%x\n", __func__, io_port);
     }
     return;
 cancel_async:
commit e954ea2873fd6621d199d4a1a012fc0bc0292924
Author: Alon Levy <alevy at redhat.com>
Date:   Wed Apr 25 12:13:24 2012 +0300

    qxl: qxl_add_memslot: remove guest trigerrable panics
    
    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 44ee495..44a167a 100644
--- a/hw/qxl.c
+++ b/hw/qxl.c
@@ -1038,8 +1038,8 @@ static const MemoryRegionPortio qxl_vga_portio_list[] = {
     PORTIO_END_OF_LIST(),
 };
 
-static void qxl_add_memslot(PCIQXLDevice *d, uint32_t slot_id, uint64_t delta,
-                            qxl_async_io async)
+static int qxl_add_memslot(PCIQXLDevice *d, uint32_t slot_id, uint64_t delta,
+                           qxl_async_io async)
 {
     static const int regions[] = {
         QXL_RAM_RANGE_INDEX,
@@ -1060,8 +1060,16 @@ static void qxl_add_memslot(PCIQXLDevice *d, uint32_t slot_id, uint64_t delta,
 
     trace_qxl_memslot_add_guest(d->id, slot_id, guest_start, guest_end);
 
-    PANIC_ON(slot_id >= NUM_MEMSLOTS);
-    PANIC_ON(guest_start > guest_end);
+    if (slot_id >= NUM_MEMSLOTS) {
+        qxl_guest_bug(d, "%s: slot_id >= NUM_MEMSLOTS %d >= %d", __func__,
+                      slot_id, NUM_MEMSLOTS);
+        return 1;
+    }
+    if (guest_start > guest_end) {
+        qxl_guest_bug(d, "%s: guest_start > guest_end 0x%" PRIx64
+                         " > 0x%" PRIx64, __func__, guest_start, guest_end);
+        return 1;
+    }
 
     for (i = 0; i < ARRAY_SIZE(regions); i++) {
         pci_region = regions[i];
@@ -1082,7 +1090,10 @@ static void qxl_add_memslot(PCIQXLDevice *d, uint32_t slot_id, uint64_t delta,
         /* passed */
         break;
     }
-    PANIC_ON(i == ARRAY_SIZE(regions)); /* finished loop without match */
+    if (i == ARRAY_SIZE(regions)) {
+        qxl_guest_bug(d, "%s: finished loop without match", __func__);
+        return 1;
+    }
 
     switch (pci_region) {
     case QXL_RAM_RANGE_INDEX:
@@ -1094,7 +1105,8 @@ static void qxl_add_memslot(PCIQXLDevice *d, uint32_t slot_id, uint64_t delta,
         break;
     default:
         /* should not happen */
-        abort();
+        qxl_guest_bug(d, "%s: pci_region = %d", __func__, pci_region);
+        return 1;
     }
 
     memslot.slot_id = slot_id;
@@ -1110,6 +1122,7 @@ static void qxl_add_memslot(PCIQXLDevice *d, uint32_t slot_id, uint64_t delta,
     d->guest_slots[slot_id].size = memslot.virt_end - memslot.virt_start;
     d->guest_slots[slot_id].delta = delta;
     d->guest_slots[slot_id].active = 1;
+    return 0;
 }
 
 static void qxl_del_memslot(PCIQXLDevice *d, uint32_t slot_id)
@@ -1250,7 +1263,7 @@ static void qxl_set_mode(PCIQXLDevice *d, int modenr, int loadvm)
     }
 
     d->guest_slots[0].slot = slot;
-    qxl_add_memslot(d, 0, devmem, QXL_SYNC);
+    assert(qxl_add_memslot(d, 0, devmem, QXL_SYNC) == 0);
 
     d->guest_primary.surface = surface;
     qxl_create_guest_primary(d, 0, QXL_SYNC);
commit baeae407e6fe38af92eb412f111d5b0c27b54547
Author: Alon Levy <alevy at redhat.com>
Date:   Wed Apr 25 12:13:23 2012 +0300

    qxl: interface_notify_update: remove guest trigerrable abort
    
    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 6e7232c..44ee495 100644
--- a/hw/qxl.c
+++ b/hw/qxl.c
@@ -768,8 +768,13 @@ static int interface_req_cursor_notification(QXLInstance *sin)
 /* called from spice server thread context */
 static void interface_notify_update(QXLInstance *sin, uint32_t update_id)
 {
-    fprintf(stderr, "%s: abort()\n", __FUNCTION__);
-    abort();
+    /*
+     * Called by spice-server as a result of a QXL_CMD_UPDATE which is not in
+     * use by xf86-video-qxl and is defined out in the qxl windows driver.
+     * Probably was at some earlier version that is prior to git start (2009),
+     * and is still guest trigerrable.
+     */
+    fprintf(stderr, "%s: deprecated\n", __func__);
 }
 
 /* called from spice server thread context only */
commit 75fe0d7bf88cc5682de0b4d23e9d7b4ee5951fec
Author: Alon Levy <alevy at redhat.com>
Date:   Wed Apr 25 12:13:22 2012 +0300

    qxl: cleanup s/__FUNCTION__/__func__/
    
    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 44a4c9b..6e7232c 100644
--- a/hw/qxl.c
+++ b/hw/qxl.c
@@ -1503,7 +1503,7 @@ static void qxl_send_events(PCIQXLDevice *d, uint32_t events)
         qxl_update_irq(d);
     } else {
         if (write(d->pipe[1], d, 1) != 1) {
-            dprint(d, 1, "%s: write to pipe failed\n", __FUNCTION__);
+            dprint(d, 1, "%s: write to pipe failed\n", __func__);
         }
     }
 }
commit 0b81c478cff6c2db7ac61b2336eef249e84f0d47
Author: Alon Levy <alevy at redhat.com>
Date:   Wed Apr 25 12:13:21 2012 +0300

    qxl: don't abort on guest trigerrable ring indices mismatch
    
    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 b22f86e..44a4c9b 100644
--- a/hw/qxl.c
+++ b/hw/qxl.c
@@ -27,28 +27,42 @@
 
 #include "qxl.h"
 
+/*
+ * 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
+ * abort we just set qxl_guest_bug and set the return to NULL. Still
+ * it may happen as a result of emulator bug as well.
+ */
 #undef SPICE_RING_PROD_ITEM
-#define SPICE_RING_PROD_ITEM(r, ret) {                                  \
+#define SPICE_RING_PROD_ITEM(qxl, r, ret) {                             \
         typeof(r) start = r;                                            \
         typeof(r) end = r + 1;                                          \
         uint32_t prod = (r)->prod & SPICE_RING_INDEX_MASK(r);           \
         typeof(&(r)->items[prod]) m_item = &(r)->items[prod];           \
         if (!((uint8_t*)m_item >= (uint8_t*)(start) && (uint8_t*)(m_item + 1) <= (uint8_t*)(end))) { \
-            abort();                                                    \
+            qxl_guest_bug(qxl, "SPICE_RING_PROD_ITEM indices mismatch " \
+                          "! %p <= %p < %p", (uint8_t *)start,          \
+                          (uint8_t *)m_item, (uint8_t *)end);           \
+            ret = NULL;                                                 \
+        } else {                                                        \
+            ret = &m_item->el;                                          \
         }                                                               \
-        ret = &m_item->el;                                              \
     }
 
 #undef SPICE_RING_CONS_ITEM
-#define SPICE_RING_CONS_ITEM(r, ret) {                                  \
+#define SPICE_RING_CONS_ITEM(qxl, r, ret) {                             \
         typeof(r) start = r;                                            \
         typeof(r) end = r + 1;                                          \
         uint32_t cons = (r)->cons & SPICE_RING_INDEX_MASK(r);           \
         typeof(&(r)->items[cons]) m_item = &(r)->items[cons];           \
         if (!((uint8_t*)m_item >= (uint8_t*)(start) && (uint8_t*)(m_item + 1) <= (uint8_t*)(end))) { \
-            abort();                                                    \
+            qxl_guest_bug(qxl, "SPICE_RING_CONS_ITEM indices mismatch " \
+                          "! %p <= %p < %p", (uint8_t *)start,          \
+                          (uint8_t *)m_item, (uint8_t *)end);           \
+            ret = NULL;                                                 \
+        } else {                                                        \
+            ret = &m_item->el;                                          \
         }                                                               \
-        ret = &m_item->el;                                              \
     }
 
 #undef ALIGN
@@ -343,7 +357,8 @@ static void init_qxl_ram(PCIQXLDevice *d)
     SPICE_RING_INIT(&d->ram->cmd_ring);
     SPICE_RING_INIT(&d->ram->cursor_ring);
     SPICE_RING_INIT(&d->ram->release_ring);
-    SPICE_RING_PROD_ITEM(&d->ram->release_ring, item);
+    SPICE_RING_PROD_ITEM(d, &d->ram->release_ring, item);
+    assert(item);
     *item = 0;
     qxl_ring_set_dirty(d);
 }
@@ -559,8 +574,10 @@ static int interface_get_command(QXLInstance *sin, struct QXLCommandExt *ext)
         if (SPICE_RING_IS_EMPTY(ring)) {
             return false;
         }
-        trace_qxl_ring_command_get(qxl->id, qxl_mode_to_string(qxl->mode));
-        SPICE_RING_CONS_ITEM(ring, cmd);
+        SPICE_RING_CONS_ITEM(qxl, ring, cmd);
+        if (!cmd) {
+            return false;
+        }
         ext->cmd      = *cmd;
         ext->group_id = MEMSLOT_GROUP_GUEST;
         ext->flags    = qxl->cmdflags;
@@ -572,6 +589,7 @@ static int interface_get_command(QXLInstance *sin, struct QXLCommandExt *ext)
         qxl->guest_primary.commands++;
         qxl_track_command(qxl, ext);
         qxl_log_command(qxl, "cmd", ext);
+        trace_qxl_ring_command_get(qxl->id, qxl_mode_to_string(qxl->mode));
         return true;
     default:
         return false;
@@ -630,7 +648,10 @@ static inline void qxl_push_free_res(PCIQXLDevice *d, int flush)
     if (notify) {
         qxl_send_events(d, QXL_INTERRUPT_DISPLAY);
     }
-    SPICE_RING_PROD_ITEM(ring, item);
+    SPICE_RING_PROD_ITEM(d, ring, item);
+    if (!item) {
+        return;
+    }
     *item = 0;
     d->num_free_res = 0;
     d->last_release = NULL;
@@ -656,7 +677,10 @@ static void interface_release_resource(QXLInstance *sin,
      * pci bar 0, $command.release_info
      */
     ring = &qxl->ram->release_ring;
-    SPICE_RING_PROD_ITEM(ring, item);
+    SPICE_RING_PROD_ITEM(qxl, ring, item);
+    if (!item) {
+        return;
+    }
     if (*item == 0) {
         /* stick head into the ring */
         id = ext.info->id;
@@ -695,7 +719,10 @@ static int interface_get_cursor_command(QXLInstance *sin, struct QXLCommandExt *
         if (SPICE_RING_IS_EMPTY(ring)) {
             return false;
         }
-        SPICE_RING_CONS_ITEM(ring, cmd);
+        SPICE_RING_CONS_ITEM(qxl, ring, cmd);
+        if (!cmd) {
+            return false;
+        }
         ext->cmd      = *cmd;
         ext->group_id = MEMSLOT_GROUP_GUEST;
         ext->flags    = qxl->cmdflags;
commit 2fce7edf46e23f287b7a72b328870f19646261cb
Author: Alon Levy <alevy at redhat.com>
Date:   Wed Apr 25 12:13:20 2012 +0300

    qxl: fix > 80 chars line
    
    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 8b66cbb..b22f86e 100644
--- a/hw/qxl.c
+++ b/hw/qxl.c
@@ -777,8 +777,8 @@ static void interface_async_complete_io(PCIQXLDevice *qxl, QXLCookie *cookie)
     }
     if (cookie && current_async != cookie->io) {
         fprintf(stderr,
-                "qxl: %s: error: current_async = %d != %" PRId64 " = cookie->io\n",
-                __func__, current_async, cookie->io);
+                "qxl: %s: error: current_async = %d != %"
+                PRId64 " = cookie->io\n", __func__, current_async, cookie->io);
     }
     switch (current_async) {
     case QXL_IO_MEMSLOT_ADD_ASYNC:
commit 47eddfbfe061dd18aad525863375028b1ee78d5c
Author: Alon Levy <alevy at redhat.com>
Date:   Wed Apr 25 12:13:19 2012 +0300

    qxl: replace panic with guest bug in qxl_track_command
    
    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 b6a738e..8b66cbb 100644
--- a/hw/qxl.c
+++ b/hw/qxl.c
@@ -394,7 +394,11 @@ static int qxl_track_command(PCIQXLDevice *qxl, struct QXLCommandExt *ext)
             return 1;
         }
         uint32_t id = le32_to_cpu(cmd->surface_id);
-        PANIC_ON(id >= NUM_SURFACES);
+
+        if (id >= NUM_SURFACES) {
+            qxl_guest_bug(qxl, "QXL_CMD_SURFACE id %d >= %d", id, NUM_SURFACES);
+            return 1;
+        }
         qemu_mutex_lock(&qxl->track_lock);
         if (cmd->type == QXL_SURFACE_CMD_CREATE) {
             qxl->guest_surfaces.cmds[id] = ext->cmd.data;
commit fae2afb10e3fdceab612c62a2b1e8b944ff578d9
Author: Alon Levy <alevy at redhat.com>
Date:   Wed Apr 25 12:13:18 2012 +0300

    qxl: check for NULL return from qxl_phys2virt
    
    Signed-off-by: Alon Levy <alevy at redhat.com>
    Signed-off-by: Gerd Hoffmann <kraxel at redhat.com>

diff --git a/hw/qxl-logger.c b/hw/qxl-logger.c
index 367aad1..fe2878c 100644
--- a/hw/qxl-logger.c
+++ b/hw/qxl-logger.c
@@ -100,12 +100,15 @@ static const char *qxl_v2n(const char *n[], size_t l, int v)
 }
 #define qxl_name(_list, _value) qxl_v2n(_list, ARRAY_SIZE(_list), _value)
 
-static void qxl_log_image(PCIQXLDevice *qxl, QXLPHYSICAL addr, int group_id)
+static int qxl_log_image(PCIQXLDevice *qxl, QXLPHYSICAL addr, int group_id)
 {
     QXLImage *image;
     QXLImageDescriptor *desc;
 
     image = qxl_phys2virt(qxl, addr, group_id);
+    if (!image) {
+        return 1;
+    }
     desc = &image->descriptor;
     fprintf(stderr, " (id %" PRIx64 " type %d flags %d width %d height %d",
             desc->id, desc->type, desc->flags, desc->width, desc->height);
@@ -120,6 +123,7 @@ static void qxl_log_image(PCIQXLDevice *qxl, QXLPHYSICAL addr, int group_id)
         break;
     }
     fprintf(stderr, ")");
+    return 0;
 }
 
 static void qxl_log_rect(QXLRect *rect)
@@ -130,17 +134,24 @@ static void qxl_log_rect(QXLRect *rect)
             rect->left, rect->top);
 }
 
-static void qxl_log_cmd_draw_copy(PCIQXLDevice *qxl, QXLCopy *copy, int group_id)
+static int qxl_log_cmd_draw_copy(PCIQXLDevice *qxl, QXLCopy *copy,
+                                 int group_id)
 {
+    int ret;
+
     fprintf(stderr, " src %" PRIx64,
             copy->src_bitmap);
-    qxl_log_image(qxl, copy->src_bitmap, group_id);
+    ret = qxl_log_image(qxl, copy->src_bitmap, group_id);
+    if (ret != 0) {
+        return ret;
+    }
     fprintf(stderr, " area");
     qxl_log_rect(&copy->src_area);
     fprintf(stderr, " rop %d", copy->rop_descriptor);
+    return 0;
 }
 
-static void qxl_log_cmd_draw(PCIQXLDevice *qxl, QXLDrawable *draw, int group_id)
+static int qxl_log_cmd_draw(PCIQXLDevice *qxl, QXLDrawable *draw, int group_id)
 {
     fprintf(stderr, ": surface_id %d type %s effect %s",
             draw->surface_id,
@@ -148,13 +159,14 @@ static void qxl_log_cmd_draw(PCIQXLDevice *qxl, QXLDrawable *draw, int group_id)
             qxl_name(qxl_draw_effect, draw->effect));
     switch (draw->type) {
     case QXL_DRAW_COPY:
-        qxl_log_cmd_draw_copy(qxl, &draw->u.copy, group_id);
+        return qxl_log_cmd_draw_copy(qxl, &draw->u.copy, group_id);
         break;
     }
+    return 0;
 }
 
-static void qxl_log_cmd_draw_compat(PCIQXLDevice *qxl, QXLCompatDrawable *draw,
-                                    int group_id)
+static int qxl_log_cmd_draw_compat(PCIQXLDevice *qxl, QXLCompatDrawable *draw,
+                                   int group_id)
 {
     fprintf(stderr, ": type %s effect %s",
             qxl_name(qxl_draw_type, draw->type),
@@ -166,9 +178,10 @@ static void qxl_log_cmd_draw_compat(PCIQXLDevice *qxl, QXLCompatDrawable *draw,
     }
     switch (draw->type) {
     case QXL_DRAW_COPY:
-        qxl_log_cmd_draw_copy(qxl, &draw->u.copy, group_id);
+        return qxl_log_cmd_draw_copy(qxl, &draw->u.copy, group_id);
         break;
     }
+    return 0;
 }
 
 static void qxl_log_cmd_surface(PCIQXLDevice *qxl, QXLSurfaceCmd *cmd)
@@ -189,7 +202,7 @@ static void qxl_log_cmd_surface(PCIQXLDevice *qxl, QXLSurfaceCmd *cmd)
     }
 }
 
-void qxl_log_cmd_cursor(PCIQXLDevice *qxl, QXLCursorCmd *cmd, int group_id)
+int qxl_log_cmd_cursor(PCIQXLDevice *qxl, QXLCursorCmd *cmd, int group_id)
 {
     QXLCursor *cursor;
 
@@ -203,6 +216,9 @@ void qxl_log_cmd_cursor(PCIQXLDevice *qxl, QXLCursorCmd *cmd, int group_id)
                 cmd->u.set.visible ? "yes" : "no",
                 cmd->u.set.shape);
         cursor = qxl_phys2virt(qxl, cmd->u.set.shape, group_id);
+        if (!cursor) {
+            return 1;
+        }
         fprintf(stderr, " type %s size %dx%d hot-spot +%d+%d"
                 " unique 0x%" PRIx64 " data-size %d",
                 qxl_name(spice_cursor_type, cursor->header.type),
@@ -214,15 +230,17 @@ void qxl_log_cmd_cursor(PCIQXLDevice *qxl, QXLCursorCmd *cmd, int group_id)
         fprintf(stderr, " +%d+%d", cmd->u.position.x, cmd->u.position.y);
         break;
     }
+    return 0;
 }
 
-void qxl_log_command(PCIQXLDevice *qxl, const char *ring, QXLCommandExt *ext)
+int qxl_log_command(PCIQXLDevice *qxl, const char *ring, QXLCommandExt *ext)
 {
     bool compat = ext->flags & QXL_COMMAND_FLAG_COMPAT;
     void *data;
+    int ret;
 
     if (!qxl->cmdlog) {
-        return;
+        return 0;
     }
     fprintf(stderr, "%" PRId64 " qxl-%d/%s:", qemu_get_clock_ns(vm_clock),
             qxl->id, ring);
@@ -231,12 +249,18 @@ void qxl_log_command(PCIQXLDevice *qxl, const char *ring, QXLCommandExt *ext)
             compat ? "(compat)" : "");
 
     data = qxl_phys2virt(qxl, ext->cmd.data, ext->group_id);
+    if (!data) {
+        return 1;
+    }
     switch (ext->cmd.type) {
     case QXL_CMD_DRAW:
         if (!compat) {
-            qxl_log_cmd_draw(qxl, data, ext->group_id);
+            ret = qxl_log_cmd_draw(qxl, data, ext->group_id);
         } else {
-            qxl_log_cmd_draw_compat(qxl, data, ext->group_id);
+            ret = qxl_log_cmd_draw_compat(qxl, data, ext->group_id);
+        }
+        if (ret) {
+            return ret;
         }
         break;
     case QXL_CMD_SURFACE:
@@ -247,4 +271,5 @@ void qxl_log_command(PCIQXLDevice *qxl, const char *ring, QXLCommandExt *ext)
         break;
     }
     fprintf(stderr, "\n");
+    return 0;
 }
diff --git a/hw/qxl-render.c b/hw/qxl-render.c
index f7f1bfd..e2e3fe2 100644
--- a/hw/qxl-render.c
+++ b/hw/qxl-render.c
@@ -228,14 +228,18 @@ fail:
 
 
 /* called from spice server thread context only */
-void qxl_render_cursor(PCIQXLDevice *qxl, QXLCommandExt *ext)
+int qxl_render_cursor(PCIQXLDevice *qxl, QXLCommandExt *ext)
 {
     QXLCursorCmd *cmd = qxl_phys2virt(qxl, ext->cmd.data, ext->group_id);
     QXLCursor *cursor;
     QEMUCursor *c;
 
+    if (!cmd) {
+        return 1;
+    }
+
     if (!qxl->ssd.ds->mouse_set || !qxl->ssd.ds->cursor_define) {
-        return;
+        return 0;
     }
 
     if (qxl->debug > 1 && cmd->type != QXL_CURSOR_MOVE) {
@@ -246,9 +250,12 @@ void qxl_render_cursor(PCIQXLDevice *qxl, QXLCommandExt *ext)
     switch (cmd->type) {
     case QXL_CURSOR_SET:
         cursor = qxl_phys2virt(qxl, cmd->u.set.shape, ext->group_id);
+        if (!cursor) {
+            return 1;
+        }
         if (cursor->chunk.data_size != cursor->data_size) {
             fprintf(stderr, "%s: multiple chunks\n", __FUNCTION__);
-            return;
+            return 1;
         }
         c = qxl_cursor(qxl, cursor);
         if (c == NULL) {
@@ -270,4 +277,5 @@ void qxl_render_cursor(PCIQXLDevice *qxl, QXLCommandExt *ext)
         qemu_mutex_unlock(&qxl->ssd.lock);
         break;
     }
+    return 0;
 }
diff --git a/hw/qxl.c b/hw/qxl.c
index 9e8cdf3..b6a738e 100644
--- a/hw/qxl.c
+++ b/hw/qxl.c
@@ -383,12 +383,16 @@ static void qxl_ring_set_dirty(PCIQXLDevice *qxl)
  * keep track of some command state, for savevm/loadvm.
  * called from spice server thread context only
  */
-static void qxl_track_command(PCIQXLDevice *qxl, struct QXLCommandExt *ext)
+static int qxl_track_command(PCIQXLDevice *qxl, struct QXLCommandExt *ext)
 {
     switch (le32_to_cpu(ext->cmd.type)) {
     case QXL_CMD_SURFACE:
     {
         QXLSurfaceCmd *cmd = qxl_phys2virt(qxl, ext->cmd.data, ext->group_id);
+
+        if (!cmd) {
+            return 1;
+        }
         uint32_t id = le32_to_cpu(cmd->surface_id);
         PANIC_ON(id >= NUM_SURFACES);
         qemu_mutex_lock(&qxl->track_lock);
@@ -408,6 +412,10 @@ static void qxl_track_command(PCIQXLDevice *qxl, struct QXLCommandExt *ext)
     case QXL_CMD_CURSOR:
     {
         QXLCursorCmd *cmd = qxl_phys2virt(qxl, ext->cmd.data, ext->group_id);
+
+        if (!cmd) {
+            return 1;
+        }
         if (cmd->type == QXL_CURSOR_SET) {
             qemu_mutex_lock(&qxl->track_lock);
             qxl->guest_cursor = ext->cmd.data;
@@ -416,6 +424,7 @@ static void qxl_track_command(PCIQXLDevice *qxl, struct QXLCommandExt *ext)
         break;
     }
     }
+    return 0;
 }
 
 /* spice display interface callbacks */
@@ -1568,10 +1577,12 @@ static void qxl_dirty_surfaces(PCIQXLDevice *qxl)
 
         cmd = qxl_phys2virt(qxl, qxl->guest_surfaces.cmds[i],
                             MEMSLOT_GROUP_GUEST);
+        assert(cmd);
         assert(cmd->type == QXL_SURFACE_CMD_CREATE);
         surface_offset = (intptr_t)qxl_phys2virt(qxl,
                                                  cmd->u.surface_create.data,
                                                  MEMSLOT_GROUP_GUEST);
+        assert(surface_offset);
         surface_offset -= vram_start;
         surface_size = cmd->u.surface_create.height *
                        abs(cmd->u.surface_create.stride);
diff --git a/hw/qxl.h b/hw/qxl.h
index cbb1e2d..3102950 100644
--- a/hw/qxl.h
+++ b/hw/qxl.h
@@ -142,12 +142,12 @@ void qxl_spice_reset_image_cache(PCIQXLDevice *qxl);
 void qxl_spice_reset_cursor(PCIQXLDevice *qxl);
 
 /* qxl-logger.c */
-void qxl_log_cmd_cursor(PCIQXLDevice *qxl, QXLCursorCmd *cmd, int group_id);
-void qxl_log_command(PCIQXLDevice *qxl, const char *ring, QXLCommandExt *ext);
+int qxl_log_cmd_cursor(PCIQXLDevice *qxl, QXLCursorCmd *cmd, int group_id);
+int qxl_log_command(PCIQXLDevice *qxl, const char *ring, QXLCommandExt *ext);
 
 /* qxl-render.c */
 void qxl_render_resize(PCIQXLDevice *qxl);
 void qxl_render_update(PCIQXLDevice *qxl);
-void qxl_render_cursor(PCIQXLDevice *qxl, QXLCommandExt *ext);
+int qxl_render_cursor(PCIQXLDevice *qxl, QXLCommandExt *ext);
 void qxl_render_update_area_done(PCIQXLDevice *qxl, QXLCookie *cookie);
 void qxl_render_update_area_bh(void *opaque);
commit 4b635c59b04cae594f49d9aa45d31b3f318def8f
Author: Alon Levy <alevy at redhat.com>
Date:   Wed Apr 25 12:13:17 2012 +0300

    hw/qxl.c: qxl_phys2virt: replace panics with guest_bug
    
    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 c3540c3..9e8cdf3 100644
--- a/hw/qxl.c
+++ b/hw/qxl.c
@@ -1097,15 +1097,28 @@ void *qxl_phys2virt(PCIQXLDevice *qxl, QXLPHYSICAL pqxl, int group_id)
     case MEMSLOT_GROUP_HOST:
         return (void *)(intptr_t)offset;
     case MEMSLOT_GROUP_GUEST:
-        PANIC_ON(slot >= NUM_MEMSLOTS);
-        PANIC_ON(!qxl->guest_slots[slot].active);
-        PANIC_ON(offset < qxl->guest_slots[slot].delta);
+        if (slot >= NUM_MEMSLOTS) {
+            qxl_guest_bug(qxl, "slot too large %d >= %d", slot, NUM_MEMSLOTS);
+            return NULL;
+        }
+        if (!qxl->guest_slots[slot].active) {
+            qxl_guest_bug(qxl, "inactive slot %d\n", slot);
+            return NULL;
+        }
+        if (offset < qxl->guest_slots[slot].delta) {
+            qxl_guest_bug(qxl, "slot %d offset %"PRIu64" < delta %"PRIu64"\n",
+                          slot, offset, qxl->guest_slots[slot].delta);
+            return NULL;
+        }
         offset -= qxl->guest_slots[slot].delta;
-        PANIC_ON(offset > qxl->guest_slots[slot].size)
+        if (offset > qxl->guest_slots[slot].size) {
+            qxl_guest_bug(qxl, "slot %d offset %"PRIu64" > size %"PRIu64"\n",
+                          slot, offset, qxl->guest_slots[slot].size);
+            return NULL;
+        }
         return qxl->guest_slots[slot].ptr + offset;
-    default:
-        PANIC_ON(1);
     }
+    return NULL;
 }
 
 static void qxl_create_guest_primary_complete(PCIQXLDevice *qxl)
commit 4efee029cbd5dc3aaa422edc10447f3659df7754
Author: Alon Levy <alevy at redhat.com>
Date:   Thu Mar 29 23:23:14 2012 +0200

    spice_info: add mouse_mode
    
    Add mouse_mode, either server or mouse, to qmp and hmp commands, based
    on spice_server_is_server_mouse added in spice-server 0.10.3.
    
    Signed-off-by: Alon Levy <alevy at redhat.com>
    Signed-off-by: Gerd Hoffmann <kraxel at redhat.com>

diff --git a/hmp.c b/hmp.c
index eb96618..1f9fe0e 100644
--- a/hmp.c
+++ b/hmp.c
@@ -350,6 +350,8 @@ void hmp_info_spice(Monitor *mon)
     }
     monitor_printf(mon, "        auth: %s\n", info->auth);
     monitor_printf(mon, "    compiled: %s\n", info->compiled_version);
+    monitor_printf(mon, "  mouse-mode: %s\n",
+                   SpiceQueryMouseMode_lookup[info->mouse_mode]);
 
     if (!info->has_channels || info->channels == NULL) {
         monitor_printf(mon, "Channels: none\n");
diff --git a/qapi-schema.json b/qapi-schema.json
index 9193fb9..4279259 100644
--- a/qapi-schema.json
+++ b/qapi-schema.json
@@ -634,6 +634,25 @@
            'tls': 'bool'} }
 
 ##
+# @SpiceQueryMouseMode
+#
+# An enumation of Spice mouse states.
+#
+# @client: Mouse cursor position is determined by the client.
+#
+# @server: Mouse cursor position is determined by the server.
+#
+# @unknown: No information is available about mouse mode used by
+#           the spice server.
+#
+# Note: spice/enums.h has a SpiceMouseMode already, hence the name.
+#
+# Since: 1.1
+##
+{ 'enum': 'SpiceQueryMouseMode',
+  'data': [ 'client', 'server', 'unknown' ] }
+
+##
 # @SpiceInfo
 #
 # Information about the SPICE session.
@@ -654,6 +673,12 @@
 #        'spice' uses SASL or direct TLS authentication, depending on command
 #                line options
 #
+# @mouse-mode: The mode in which the mouse cursor is displayed currently. Can
+#              be determined by the client or the server, or unknown if spice
+#              server doesn't provide this information.
+#
+#              Since: 1.1
+#
 # @channels: a list of @SpiceChannel for each active spice channel
 #
 # Since: 0.14.0
@@ -661,7 +686,7 @@
 { 'type': 'SpiceInfo',
   'data': {'enabled': 'bool', '*host': 'str', '*port': 'int',
            '*tls-port': 'int', '*auth': 'str', '*compiled-version': 'str',
-           '*channels': ['SpiceChannel']} }
+           'mouse-mode': 'SpiceQueryMouseMode', '*channels': ['SpiceChannel']} }
 
 ##
 # @query-spice
diff --git a/ui/spice-core.c b/ui/spice-core.c
index a468524..4fc48f8 100644
--- a/ui/spice-core.c
+++ b/ui/spice-core.c
@@ -462,6 +462,13 @@ 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();
commit 7e3efdac75caca0b283f8e76ad24c924b4718e7b
Author: Alon Levy <alevy at redhat.com>
Date:   Wed Mar 7 16:19:03 2012 +0200

    spice: require spice-protocol >= 0.8.1
    
    Requiring spice-server >= 0.8.2 is not enough since spice-server.pc
    doesn't require spice-protocol (any version). Until that is fixed
    upstream an explicit requirement in qemu fixes compilation broken since
    
    commit 2e1a98c9c1b90ca093278c6b43244dc46604d7b7
    Author: Alon Levy <alevy at redhat.com>
    Date:   Fri Feb 24 23:19:30 2012 +0200
    
        qxl: introduce QXLCookie
    
    Reported-by: Peter Maydell <peter.maydell at linaro.org>
    
    Signed-off-by: Alon Levy <alevy at redhat.com>
    Signed-off-by: Gerd Hoffmann <kraxel at redhat.com>

diff --git a/configure b/configure
index 0111774..62aa760 100755
--- a/configure
+++ b/configure
@@ -2592,6 +2592,7 @@ 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 && \
      compile_prog "$spice_cflags" "$spice_libs" ; then
     spice="yes"
     libs_softmmu="$libs_softmmu $spice_libs"
commit 40f08e87f613273f9dcc8df7d6a0f574b7d28d05
Author: Stefan Weil <sw at weilnetz.de>
Date:   Fri Apr 27 05:34:40 2012 +0000

    qemu-timer: Fix limits for w32 mmtimer
    
    timeSetEvent only accepts delays in the range which is returned by
    timeGetDevCaps.
    
    The lower limit is typically 1 (= 1 ms), so the constant value of 1
    in the old code usually worked.
    
    The upper limit can be as low as 10000 ms, so the latest changes in
    QEMU's timer handling which introduced timeout values above that limit
    could result in failures of timeSetEvent when the timer was re-armed.
    
    Signed-off-by: Stefan Weil <sw at weilnetz.de>

diff --git a/qemu-timer.c b/qemu-timer.c
index 8eadd16..b9fd75d 100644
--- a/qemu-timer.c
+++ b/qemu-timer.c
@@ -611,7 +611,7 @@ static void unix_stop_timer(struct qemu_alarm_timer *t)
 #ifdef _WIN32
 
 static MMRESULT mm_timer;
-static unsigned mm_period;
+static TIMECAPS mm_tc;
 
 static void CALLBACK mm_alarm_handler(UINT uTimerID, UINT uMsg,
                                       DWORD_PTR dwUser, DWORD_PTR dw1,
@@ -628,16 +628,12 @@ static void CALLBACK mm_alarm_handler(UINT uTimerID, UINT uMsg,
 
 static int mm_start_timer(struct qemu_alarm_timer *t)
 {
-    TIMECAPS tc;
+    timeGetDevCaps(&mm_tc, sizeof(mm_tc));
 
-    memset(&tc, 0, sizeof(tc));
-    timeGetDevCaps(&tc, sizeof(tc));
+    timeBeginPeriod(mm_tc.wPeriodMin);
 
-    mm_period = tc.wPeriodMin;
-    timeBeginPeriod(mm_period);
-
-    mm_timer = timeSetEvent(1,                  /* interval (ms) */
-                            mm_period,          /* resolution */
+    mm_timer = timeSetEvent(mm_tc.wPeriodMin,   /* interval (ms) */
+                            mm_tc.wPeriodMin,   /* resolution */
                             mm_alarm_handler,   /* function */
                             (DWORD_PTR)t,       /* parameter */
                             TIME_ONESHOT | TIME_CALLBACK_FUNCTION);
@@ -645,7 +641,7 @@ static int mm_start_timer(struct qemu_alarm_timer *t)
     if (!mm_timer) {
         fprintf(stderr, "Failed to initialize win32 alarm timer: %ld\n",
                 GetLastError());
-        timeEndPeriod(mm_period);
+        timeEndPeriod(mm_tc.wPeriodMin);
         return -1;
     }
 
@@ -655,23 +651,21 @@ static int mm_start_timer(struct qemu_alarm_timer *t)
 static void mm_stop_timer(struct qemu_alarm_timer *t)
 {
     timeKillEvent(mm_timer);
-    timeEndPeriod(mm_period);
+    timeEndPeriod(mm_tc.wPeriodMin);
 }
 
 static void mm_rearm_timer(struct qemu_alarm_timer *t, int64_t delta)
 {
     int64_t nearest_delta_ms = delta / 1000000;
-    if (nearest_delta_ms < 1) {
-        nearest_delta_ms = 1;
-    }
-    /* UINT_MAX can be 32 bit */
-    if (nearest_delta_ms > UINT_MAX) {
-        nearest_delta_ms = UINT_MAX;
+    if (nearest_delta_ms < mm_tc.wPeriodMin) {
+        nearest_delta_ms = mm_tc.wPeriodMin;
+    } else if (nearest_delta_ms > mm_tc.wPeriodMax) {
+        nearest_delta_ms = mm_tc.wPeriodMax;
     }
 
     timeKillEvent(mm_timer);
-    mm_timer = timeSetEvent((unsigned int) nearest_delta_ms,
-                            mm_period,
+    mm_timer = timeSetEvent((UINT)nearest_delta_ms,
+                            mm_tc.wPeriodMin,
                             mm_alarm_handler,
                             (DWORD_PTR)t,
                             TIME_ONESHOT | TIME_CALLBACK_FUNCTION);
@@ -680,7 +674,7 @@ static void mm_rearm_timer(struct qemu_alarm_timer *t, int64_t delta)
         fprintf(stderr, "Failed to re-arm win32 alarm timer %ld\n",
                 GetLastError());
 
-        timeEndPeriod(mm_period);
+        timeEndPeriod(mm_tc.wPeriodMin);
         exit(1);
     }
 }
commit f156f2385ff72e05e35edea6bea270033bf2756a
Author: Stefan Weil <sw at weilnetz.de>
Date:   Sat Apr 28 02:20:19 2012 +0000

    qom: Fix memory leak in function container_get
    
    Valgrind reported this memory leak which occured very often.
    
    Test scenario:
    
    qemu-system-i386 (no arguments), only BIOS started, terminate with
    monitor command (quit).
    
    Signed-off-by: Stefan Weil <sw at weilnetz.de>
    Reviewed-by: Andreas Färber <afaerber at suse.de>

diff --git a/qom/container.c b/qom/container.c
index c9940ab..4ca8b5c 100644
--- a/qom/container.c
+++ b/qom/container.c
@@ -43,6 +43,8 @@ Object *container_get(Object *root, const char *path)
         }
     }
 
+    g_strfreev(parts);
+
     return obj;
 }
 
commit 9cf1f002d7761a1938066379d54a67e8f8b48cc2
Author: Stefan Weil <sw at weilnetz.de>
Date:   Sat Apr 28 02:20:20 2012 +0000

    hw/pc_sysfw: Fix memory leak
    
    Valgrind reported this memory leak which occured a few times.
    
    Test scenario:
    
    qemu-system-i386 (no arguments), only BIOS started, terminate with
    monitor command (quit).
    
    Signed-off-by: Stefan Weil <sw at weilnetz.de>
    Reviewed-by: Andreas Färber <afaerber at suse.de>

diff --git a/hw/pc_sysfw.c b/hw/pc_sysfw.c
index fafdf9b..f0d7c21 100644
--- a/hw/pc_sysfw.c
+++ b/hw/pc_sysfw.c
@@ -85,6 +85,9 @@ static void pc_fw_add_pflash_drv(void)
     filename = qemu_find_file(QEMU_FILE_TYPE_BIOS, bios_name);
 
     opts = drive_add(IF_PFLASH, -1, filename, "readonly=on");
+
+    g_free(filename);
+
     if (opts == NULL) {
       return;
     }
commit 5c878008ddc1fbdb688dee7cdca93e1fd55845dc
Author: Stefan Weil <sw at weilnetz.de>
Date:   Sat Apr 28 02:32:42 2012 +0000

    qdev: Fix memory leak in function set_pci_devfn
    
    Valgrind reported this memory leak which occured very often.
    
    Test scenario:
    
    qemu-system-i386 (no arguments), only BIOS started, terminate with
    monitor command (quit).
    
    v2:
    Use error_free instead of g_free (hint from Andreas Färber, thanks).
    
    Signed-off-by: Stefan Weil <sw at weilnetz.de>
    Acked-by: Andreas Färber <afaerber at suse.de>

diff --git a/hw/qdev-properties.c b/hw/qdev-properties.c
index 98dd06a..c5545dc 100644
--- a/hw/qdev-properties.c
+++ b/hw/qdev-properties.c
@@ -834,6 +834,7 @@ static void set_pci_devfn(Object *obj, Visitor *v, void *opaque,
 
     visit_type_str(v, &str, name, &local_err);
     if (local_err) {
+        error_free(local_err);
         return set_int32(obj, v, opaque, name, errp);
     }
 
commit 3881725cf0c34b366285e2c9ddda941185c9f861
Author: Stefan Weil <sw at weilnetz.de>
Date:   Sat Apr 28 05:07:47 2012 +0000

    arm-semi: Rename SYS_XXX macros to TARGET_SYS_XXX (fixes compiler warning)
    
    SYS_OPEN is already defined in stdio.h of MinGW-w64,
    therefore the compiler complains when building for w64.
    
    Adding the prefix TARGET_ avoids that macro redefinition.
    xtensa-semi.c also uses the same prefix (but mixed case macros
    TARGET_SYS_xxx instead of TARGET_SYS_XXX).
    
    Signed-off-by: Stefan Weil <sw at weilnetz.de>
    Acked-by: Peter Maydell <peter.maydell at linaro.org>

diff --git a/arm-semi.c b/arm-semi.c
index 8debd19..88ca9bb 100644
--- a/arm-semi.c
+++ b/arm-semi.c
@@ -37,26 +37,26 @@
 #include "hw/arm-misc.h"
 #endif
 
-#define SYS_OPEN        0x01
-#define SYS_CLOSE       0x02
-#define SYS_WRITEC      0x03
-#define SYS_WRITE0      0x04
-#define SYS_WRITE       0x05
-#define SYS_READ        0x06
-#define SYS_READC       0x07
-#define SYS_ISTTY       0x09
-#define SYS_SEEK        0x0a
-#define SYS_FLEN        0x0c
-#define SYS_TMPNAM      0x0d
-#define SYS_REMOVE      0x0e
-#define SYS_RENAME      0x0f
-#define SYS_CLOCK       0x10
-#define SYS_TIME        0x11
-#define SYS_SYSTEM      0x12
-#define SYS_ERRNO       0x13
-#define SYS_GET_CMDLINE 0x15
-#define SYS_HEAPINFO    0x16
-#define SYS_EXIT        0x18
+#define TARGET_SYS_OPEN        0x01
+#define TARGET_SYS_CLOSE       0x02
+#define TARGET_SYS_WRITEC      0x03
+#define TARGET_SYS_WRITE0      0x04
+#define TARGET_SYS_WRITE       0x05
+#define TARGET_SYS_READ        0x06
+#define TARGET_SYS_READC       0x07
+#define TARGET_SYS_ISTTY       0x09
+#define TARGET_SYS_SEEK        0x0a
+#define TARGET_SYS_FLEN        0x0c
+#define TARGET_SYS_TMPNAM      0x0d
+#define TARGET_SYS_REMOVE      0x0e
+#define TARGET_SYS_RENAME      0x0f
+#define TARGET_SYS_CLOCK       0x10
+#define TARGET_SYS_TIME        0x11
+#define TARGET_SYS_SYSTEM      0x12
+#define TARGET_SYS_ERRNO       0x13
+#define TARGET_SYS_GET_CMDLINE 0x15
+#define TARGET_SYS_HEAPINFO    0x16
+#define TARGET_SYS_EXIT        0x18
 
 #ifndef O_BINARY
 #define O_BINARY 0
@@ -138,11 +138,11 @@ static void arm_semi_cb(CPUARMState *env, target_ulong ret, target_ulong err)
     } else {
         /* Fixup syscalls that use nonstardard return conventions.  */
         switch (env->regs[0]) {
-        case SYS_WRITE:
-        case SYS_READ:
+        case TARGET_SYS_WRITE:
+        case TARGET_SYS_READ:
             env->regs[0] = arm_semi_syscall_len - ret;
             break;
-        case SYS_SEEK:
+        case TARGET_SYS_SEEK:
             env->regs[0] = 0;
             break;
         default:
@@ -190,7 +190,7 @@ uint32_t do_arm_semihosting(CPUARMState *env)
     nr = env->regs[0];
     args = env->regs[1];
     switch (nr) {
-    case SYS_OPEN:
+    case TARGET_SYS_OPEN:
         if (!(s = lock_user_string(ARG(0))))
             /* FIXME - should this error code be -TARGET_EFAULT ? */
             return (uint32_t)-1;
@@ -211,14 +211,14 @@ uint32_t do_arm_semihosting(CPUARMState *env)
         }
         unlock_user(s, ARG(0), 0);
         return ret;
-    case SYS_CLOSE:
+    case TARGET_SYS_CLOSE:
         if (use_gdb_syscalls()) {
             gdb_do_syscall(arm_semi_cb, "close,%x", ARG(0));
             return env->regs[0];
         } else {
             return set_swi_errno(ts, close(ARG(0)));
         }
-    case SYS_WRITEC:
+    case TARGET_SYS_WRITEC:
         {
           char c;
 
@@ -233,7 +233,7 @@ uint32_t do_arm_semihosting(CPUARMState *env)
                 return write(STDERR_FILENO, &c, 1);
           }
         }
-    case SYS_WRITE0:
+    case TARGET_SYS_WRITE0:
         if (!(s = lock_user_string(args)))
             /* FIXME - should this error code be -TARGET_EFAULT ? */
             return (uint32_t)-1;
@@ -246,7 +246,7 @@ uint32_t do_arm_semihosting(CPUARMState *env)
         }
         unlock_user(s, args, 0);
         return ret;
-    case SYS_WRITE:
+    case TARGET_SYS_WRITE:
         len = ARG(2);
         if (use_gdb_syscalls()) {
             arm_semi_syscall_len = len;
@@ -262,7 +262,7 @@ uint32_t do_arm_semihosting(CPUARMState *env)
                 return -1;
             return len - ret;
         }
-    case SYS_READ:
+    case TARGET_SYS_READ:
         len = ARG(2);
         if (use_gdb_syscalls()) {
             arm_semi_syscall_len = len;
@@ -280,17 +280,17 @@ uint32_t do_arm_semihosting(CPUARMState *env)
                 return -1;
             return len - ret;
         }
-    case SYS_READC:
+    case TARGET_SYS_READC:
        /* XXX: Read from debug cosole. Not implemented.  */
         return 0;
-    case SYS_ISTTY:
+    case TARGET_SYS_ISTTY:
         if (use_gdb_syscalls()) {
             gdb_do_syscall(arm_semi_cb, "isatty,%x", ARG(0));
             return env->regs[0];
         } else {
             return isatty(ARG(0));
         }
-    case SYS_SEEK:
+    case TARGET_SYS_SEEK:
         if (use_gdb_syscalls()) {
             gdb_do_syscall(arm_semi_cb, "lseek,%x,%x,0", ARG(0), ARG(1));
             return env->regs[0];
@@ -300,7 +300,7 @@ uint32_t do_arm_semihosting(CPUARMState *env)
               return -1;
             return 0;
         }
-    case SYS_FLEN:
+    case TARGET_SYS_FLEN:
         if (use_gdb_syscalls()) {
             gdb_do_syscall(arm_semi_flen_cb, "fstat,%x,%x",
 			   ARG(0), env->regs[13]-64);
@@ -312,10 +312,10 @@ uint32_t do_arm_semihosting(CPUARMState *env)
                 return -1;
             return buf.st_size;
         }
-    case SYS_TMPNAM:
+    case TARGET_SYS_TMPNAM:
         /* XXX: Not implemented.  */
         return -1;
-    case SYS_REMOVE:
+    case TARGET_SYS_REMOVE:
         if (use_gdb_syscalls()) {
             gdb_do_syscall(arm_semi_cb, "unlink,%s", ARG(0), (int)ARG(1)+1);
             ret = env->regs[0];
@@ -327,7 +327,7 @@ uint32_t do_arm_semihosting(CPUARMState *env)
             unlock_user(s, ARG(0), 0);
         }
         return ret;
-    case SYS_RENAME:
+    case TARGET_SYS_RENAME:
         if (use_gdb_syscalls()) {
             gdb_do_syscall(arm_semi_cb, "rename,%s,%s",
                            ARG(0), (int)ARG(1)+1, ARG(2), (int)ARG(3)+1);
@@ -347,11 +347,11 @@ uint32_t do_arm_semihosting(CPUARMState *env)
                 unlock_user(s, ARG(0), 0);
             return ret;
         }
-    case SYS_CLOCK:
+    case TARGET_SYS_CLOCK:
         return clock() / (CLOCKS_PER_SEC / 100);
-    case SYS_TIME:
+    case TARGET_SYS_TIME:
         return set_swi_errno(ts, time(NULL));
-    case SYS_SYSTEM:
+    case TARGET_SYS_SYSTEM:
         if (use_gdb_syscalls()) {
             gdb_do_syscall(arm_semi_cb, "system,%s", ARG(0), (int)ARG(1)+1);
             return env->regs[0];
@@ -363,13 +363,13 @@ uint32_t do_arm_semihosting(CPUARMState *env)
             unlock_user(s, ARG(0), 0);
             return ret;
         }
-    case SYS_ERRNO:
+    case TARGET_SYS_ERRNO:
 #ifdef CONFIG_USER_ONLY
         return ts->swi_errno;
 #else
         return syscall_err;
 #endif
-    case SYS_GET_CMDLINE:
+    case TARGET_SYS_GET_CMDLINE:
         {
             /* Build a command-line from the original argv.
              *
@@ -452,7 +452,7 @@ uint32_t do_arm_semihosting(CPUARMState *env)
 
             return status;
         }
-    case SYS_HEAPINFO:
+    case TARGET_SYS_HEAPINFO:
         {
             uint32_t *ptr;
             uint32_t limit;
@@ -498,7 +498,7 @@ uint32_t do_arm_semihosting(CPUARMState *env)
 #endif
             return 0;
         }
-    case SYS_EXIT:
+    case TARGET_SYS_EXIT:
         gdb_exit(env, 0);
         exit(0);
     default:
commit b3412b09e9a437f1e16ca6e63ea78ce97e2dd54c
Author: Stefan Weil <sw at weilnetz.de>
Date:   Sat Mar 17 02:00:51 2012 +0000

    target-mips: Remove unused inline function
    
    Function set_HILO is not needed anywhere.
    
    Signed-off-by: Stefan Weil <sw at weilnetz.de>

diff --git a/target-mips/op_helper.c b/target-mips/op_helper.c
index 5627447..66037ac 100644
--- a/target-mips/op_helper.c
+++ b/target-mips/op_helper.c
@@ -192,12 +192,6 @@ static inline uint64_t get_HILO (void)
     return ((uint64_t)(env->active_tc.HI[0]) << 32) | (uint32_t)env->active_tc.LO[0];
 }
 
-static inline void set_HILO (uint64_t HILO)
-{
-    env->active_tc.LO[0] = (int32_t)HILO;
-    env->active_tc.HI[0] = (int32_t)(HILO >> 32);
-}
-
 static inline void set_HIT0_LO (target_ulong arg1, uint64_t HILO)
 {
     env->active_tc.LO[0] = (int32_t)(HILO & 0xFFFFFFFF);


More information about the Spice-commits mailing list