[Spice-commits] 80 commits - MAINTAINERS Makefile arch_init.c block.c block.h block/iscsi.c block/qcow.c block/qcow2.c block/qed.c block/raw-posix.c block/raw-win32.c block/raw.c block/rbd.c block/sheepdog.c block/vdi.c block/vmdk.c block/vpc.c block_int.h blockdev.c compiler.h console.c cpus.c hw/cadence_uart.c hw/ioh3420.c hw/lm4549.c hw/pflash_cfi01.c hw/scsi-bus.c hw/scsi-disk.c hw/scsi.h linux-user/main.c linux-user/syscall.c nbd.c nbd.h net/socket.c os-posix.c qemu-common.h qemu-ga.c qemu-nbd.c qemu-os-posix.h qemu-os-win32.h qemu-sockets.c qemu-timer.c scripts/tracetool sysconfigs/target target-alpha/translate.c target-i386/cpu.c target-i386/cpu.h tcg/README tcg/i386 tcg/mips tcg/tcg-op.h tcg/tcg.c tcg/tcg.h vl.c

Gerd Hoffmann kraxel at kemper.freedesktop.org
Wed Sep 26 00:26:49 PDT 2012


 MAINTAINERS                         |    6 
 Makefile                            |    1 
 arch_init.c                         |    1 
 block.c                             |  299 +++++++++++++++++++++-----
 block.h                             |   18 +
 block/iscsi.c                       |   27 +-
 block/qcow.c                        |   10 
 block/qcow2.c                       |   10 
 block/qed.c                         |    9 
 block/raw-posix.c                   |  225 ++++++++++++++-----
 block/raw-win32.c                   |   40 +--
 block/raw.c                         |   10 
 block/rbd.c                         |    6 
 block/sheepdog.c                    |   14 -
 block/vdi.c                         |    7 
 block/vmdk.c                        |   35 +++
 block/vpc.c                         |    7 
 block_int.h                         |    9 
 blockdev.c                          |    2 
 compiler.h                          |    5 
 console.c                           |    7 
 cpus.c                              |    6 
 hw/cadence_uart.c                   |    2 
 hw/ioh3420.c                        |    1 
 hw/lm4549.c                         |    2 
 hw/pflash_cfi01.c                   |    8 
 hw/scsi-bus.c                       |   23 +-
 hw/scsi-disk.c                      |   44 ++-
 hw/scsi.h                           |    2 
 linux-user/main.c                   |    6 
 linux-user/syscall.c                |    4 
 nbd.c                               |  396 ++++++++++++++++++++++++++++------
 nbd.h                               |   15 +
 net/socket.c                        |    6 
 os-posix.c                          |    5 
 qemu-common.h                       |    5 
 qemu-ga.c                           |    2 
 qemu-nbd.c                          |   36 ++-
 qemu-os-posix.h                     |    2 
 qemu-os-win32.h                     |    5 
 qemu-sockets.c                      |    2 
 qemu-timer.c                        |    7 
 scripts/tracetool/backend/dtrace.py |    2 
 sysconfigs/target/cpus-x86_64.conf  |  128 -----------
 target-alpha/translate.c            |    1 
 target-i386/cpu.c                   |  413 +++++++++++++++++++++---------------
 target-i386/cpu.h                   |   26 ++
 tcg/README                          |   10 
 tcg/i386/tcg-target.c               |    2 
 tcg/mips/tcg-target.c               |   10 
 tcg/mips/tcg-target.h               |    8 
 tcg/tcg-op.h                        |  210 +++++++++++++-----
 tcg/tcg.c                           |    4 
 tcg/tcg.h                           |   10 
 vl.c                                |    4 
 55 files changed, 1503 insertions(+), 652 deletions(-)

New commits:
commit d9b41bcda91ea7285d934a9c2333c49cd32d1ad3
Merge: 444dbc3... f813cb8...
Author: Anthony Liguori <aliguori at us.ibm.com>
Date:   Tue Sep 25 18:12:07 2012 -0500

    Merge remote-tracking branch 'origin/master' into staging
    
    * origin/master:
      tcg/i386: fix build with -march < i686
      tcg: Streamline movcond_i64 using movcond_i32
      tcg: Streamline movcond_i64 using 32-bit arithmetic
      tcg: Sanity check goto_tb input
      tcg: Sanity check deposit inputs
      tcg: Add tcg_debug_assert
      tcg: Implement concat*_i64 with deposit_i64
      tcg: Emit XORI as NOT for appropriate constants
      tcg: Optimize initial inputs for ori_i64
      tcg: Emit ANDI as EXTU for appropriate constants
      tcg: Adjust descriptions of *cond opcodes
      tcg/mips: fix MIPS32(R2) detection

commit f813cb838f19ee8637d3c365659e6a6bb0c9c974
Author: Aurelien Jarno <aurelien at aurel32.net>
Date:   Wed Sep 26 00:30:12 2012 +0200

    tcg/i386: fix build with -march < i686
    
    The movcond_i32 op has to be protected with TCG_TARGET_HAS_movcond_i32
    to fix the build with -march < i686.
    
    Thanks to Richard Henderson for the hint.
    
    Reported-by: Alex Barcelo <abarcelo at ac.upc.edu>
    Signed-off-by: Aurelien Jarno <aurelien at aurel32.net>

diff --git a/tcg/i386/tcg-target.c b/tcg/i386/tcg-target.c
index 122d636..0e218c8 100644
--- a/tcg/i386/tcg-target.c
+++ b/tcg/i386/tcg-target.c
@@ -1893,7 +1893,9 @@ static const TCGTargetOpDef x86_op_defs[] = {
     { INDEX_op_setcond_i32, { "q", "r", "ri" } },
 
     { INDEX_op_deposit_i32, { "Q", "0", "Q" } },
+#if TCG_TARGET_HAS_movcond_i32
     { INDEX_op_movcond_i32, { "r", "r", "ri", "r", "0" } },
+#endif
 
 #if TCG_TARGET_REG_BITS == 32
     { INDEX_op_mulu2_i32, { "a", "d", "a", "r" } },
commit a80a6b63e362cc8eda7aae5b4c3f9e4e49013d62
Author: Richard Henderson <rth at twiddle.net>
Date:   Mon Sep 24 13:45:00 2012 -0700

    tcg: Streamline movcond_i64 using movcond_i32
    
    When movcond_i32 is available we can further reduce the generated
    op count from 12 to 6, and the generated code size on i686 from
    88 to 74 bytes.
    
    Signed-off-by: Richard Henderson <rth at twiddle.net>
    Signed-off-by: Aurelien Jarno <aurelien at aurel32.net>

diff --git a/tcg/tcg-op.h b/tcg/tcg-op.h
index 027270c..bd93fe4 100644
--- a/tcg/tcg-op.h
+++ b/tcg/tcg-op.h
@@ -2218,16 +2218,24 @@ static inline void tcg_gen_movcond_i64(TCGCond cond, TCGv_i64 ret,
     tcg_gen_op6i_i32(INDEX_op_setcond2_i32, t0,
                      TCGV_LOW(c1), TCGV_HIGH(c1),
                      TCGV_LOW(c2), TCGV_HIGH(c2), cond);
-    tcg_gen_neg_i32(t0, t0);
 
-    tcg_gen_and_i32(t1, TCGV_LOW(v1), t0);
-    tcg_gen_andc_i32(TCGV_LOW(ret), TCGV_LOW(v2), t0);
-    tcg_gen_or_i32(TCGV_LOW(ret), TCGV_LOW(ret), t1);
+    if (TCG_TARGET_HAS_movcond_i32) {
+        tcg_gen_movi_i32(t1, 0);
+        tcg_gen_movcond_i32(TCG_COND_NE, TCGV_LOW(ret), t0, t1,
+                            TCGV_LOW(v1), TCGV_LOW(v2));
+        tcg_gen_movcond_i32(TCG_COND_NE, TCGV_HIGH(ret), t0, t1,
+                            TCGV_HIGH(v1), TCGV_HIGH(v2));
+    } else {
+        tcg_gen_neg_i32(t0, t0);
 
-    tcg_gen_and_i32(t1, TCGV_HIGH(v1), t0);
-    tcg_gen_andc_i32(TCGV_HIGH(ret), TCGV_HIGH(v2), t0);
-    tcg_gen_or_i32(TCGV_HIGH(ret), TCGV_HIGH(ret), t1);
+        tcg_gen_and_i32(t1, TCGV_LOW(v1), t0);
+        tcg_gen_andc_i32(TCGV_LOW(ret), TCGV_LOW(v2), t0);
+        tcg_gen_or_i32(TCGV_LOW(ret), TCGV_LOW(ret), t1);
 
+        tcg_gen_and_i32(t1, TCGV_HIGH(v1), t0);
+        tcg_gen_andc_i32(TCGV_HIGH(ret), TCGV_HIGH(v2), t0);
+        tcg_gen_or_i32(TCGV_HIGH(ret), TCGV_HIGH(ret), t1);
+    }
     tcg_temp_free_i32(t0);
     tcg_temp_free_i32(t1);
 #else
commit a463133ee26b9172728476962eb9d411985b480f
Author: Richard Henderson <rth at twiddle.net>
Date:   Mon Sep 24 13:44:59 2012 -0700

    tcg: Streamline movcond_i64 using 32-bit arithmetic
    
    Avoiding 64-bit arithmetic (outside of the compare) reduces the
    generated op count from 15 to 12, and the generated code size on
    i686 from 105 to 88 bytes.
    
    Signed-off-by: Richard Henderson <rth at twiddle.net>
    Signed-off-by: Aurelien Jarno <aurelien at aurel32.net>

diff --git a/tcg/tcg-op.h b/tcg/tcg-op.h
index 9bfed48..027270c 100644
--- a/tcg/tcg-op.h
+++ b/tcg/tcg-op.h
@@ -2212,6 +2212,25 @@ static inline void tcg_gen_movcond_i64(TCGCond cond, TCGv_i64 ret,
                                        TCGv_i64 c1, TCGv_i64 c2,
                                        TCGv_i64 v1, TCGv_i64 v2)
 {
+#if TCG_TARGET_REG_BITS == 32
+    TCGv_i32 t0 = tcg_temp_new_i32();
+    TCGv_i32 t1 = tcg_temp_new_i32();
+    tcg_gen_op6i_i32(INDEX_op_setcond2_i32, t0,
+                     TCGV_LOW(c1), TCGV_HIGH(c1),
+                     TCGV_LOW(c2), TCGV_HIGH(c2), cond);
+    tcg_gen_neg_i32(t0, t0);
+
+    tcg_gen_and_i32(t1, TCGV_LOW(v1), t0);
+    tcg_gen_andc_i32(TCGV_LOW(ret), TCGV_LOW(v2), t0);
+    tcg_gen_or_i32(TCGV_LOW(ret), TCGV_LOW(ret), t1);
+
+    tcg_gen_and_i32(t1, TCGV_HIGH(v1), t0);
+    tcg_gen_andc_i32(TCGV_HIGH(ret), TCGV_HIGH(v2), t0);
+    tcg_gen_or_i32(TCGV_HIGH(ret), TCGV_HIGH(ret), t1);
+
+    tcg_temp_free_i32(t0);
+    tcg_temp_free_i32(t1);
+#else
     if (TCG_TARGET_HAS_movcond_i64) {
         tcg_gen_op6i_i64(INDEX_op_movcond_i64, ret, c1, c2, v1, v2, cond);
     } else {
@@ -2225,6 +2244,7 @@ static inline void tcg_gen_movcond_i64(TCGCond cond, TCGv_i64 ret,
         tcg_temp_free_i64(t0);
         tcg_temp_free_i64(t1);
     }
+#endif
 }
 
 /***************************************/
commit 0a209d4bb119b92eb14b9afab55cef5bc0555554
Author: Richard Henderson <rth at twiddle.net>
Date:   Fri Sep 21 17:18:16 2012 -0700

    tcg: Sanity check goto_tb input
    
    Checking that we don't try for idx != [01] is trivial.  Checking
    that we don't issue more than one of any index requires a tad
    more data and some ifdefs protecting that new variable.
    
    Signed-off-by: Richard Henderson <rth at twiddle.net>
    Cc: Max Filippov <jcmvbkbc at gmail.com>
    Signed-off-by: Aurelien Jarno <aurelien at aurel32.net>

diff --git a/tcg/tcg-op.h b/tcg/tcg-op.h
index ecb1ac3..9bfed48 100644
--- a/tcg/tcg-op.h
+++ b/tcg/tcg-op.h
@@ -2275,8 +2275,15 @@ static inline void tcg_gen_exit_tb(tcg_target_long val)
     tcg_gen_op1i(INDEX_op_exit_tb, val);
 }
 
-static inline void tcg_gen_goto_tb(int idx)
-{
+static inline void tcg_gen_goto_tb(unsigned idx)
+{
+    /* We only support two chained exits.  */
+    tcg_debug_assert(idx <= 1);
+#ifdef CONFIG_DEBUG_TCG
+    /* Verify that we havn't seen this numbered exit before.  */
+    tcg_debug_assert((tcg_ctx.goto_tb_issue_mask & (1 << idx)) == 0);
+    tcg_ctx.goto_tb_issue_mask |= 1 << idx;
+#endif
     tcg_gen_op1i(INDEX_op_goto_tb, idx);
 }
 
diff --git a/tcg/tcg.c b/tcg/tcg.c
index b3c2650..c069e44 100644
--- a/tcg/tcg.c
+++ b/tcg/tcg.c
@@ -298,6 +298,10 @@ void tcg_func_start(TCGContext *s)
     s->nb_labels = 0;
     s->current_frame_offset = s->frame_start;
 
+#ifdef CONFIG_DEBUG_TCG
+    s->goto_tb_issue_mask = 0;
+#endif
+
     gen_opc_ptr = gen_opc_buf;
     gen_opparam_ptr = gen_opparam_buf;
 }
diff --git a/tcg/tcg.h b/tcg/tcg.h
index 4501c15..af7464a 100644
--- a/tcg/tcg.h
+++ b/tcg/tcg.h
@@ -390,6 +390,7 @@ struct TCGContext {
 
 #ifdef CONFIG_DEBUG_TCG
     int temps_in_use;
+    int goto_tb_issue_mask;
 #endif
 };
 
commit 717e70368bdc339d241f84aba00ed72d051e0236
Author: Richard Henderson <rth at twiddle.net>
Date:   Fri Sep 21 17:18:15 2012 -0700

    tcg: Sanity check deposit inputs
    
    Given these are constants, checking once here means everything
    after can assume they're correct.
    
    Signed-off-by: Richard Henderson <rth at twiddle.net>
    Signed-off-by: Aurelien Jarno <aurelien at aurel32.net>

diff --git a/tcg/tcg-op.h b/tcg/tcg-op.h
index d2fb283..ecb1ac3 100644
--- a/tcg/tcg-op.h
+++ b/tcg/tcg-op.h
@@ -2081,6 +2081,10 @@ static inline void tcg_gen_deposit_i32(TCGv_i32 ret, TCGv_i32 arg1,
     uint32_t mask;
     TCGv_i32 t1;
 
+    tcg_debug_assert(ofs < 32);
+    tcg_debug_assert(len <= 32);
+    tcg_debug_assert(ofs + len <= 32);
+
     if (ofs == 0 && len == 32) {
         tcg_gen_mov_i32(ret, arg2);
         return;
@@ -2112,6 +2116,10 @@ static inline void tcg_gen_deposit_i64(TCGv_i64 ret, TCGv_i64 arg1,
     uint64_t mask;
     TCGv_i64 t1;
 
+    tcg_debug_assert(ofs < 64);
+    tcg_debug_assert(len <= 64);
+    tcg_debug_assert(ofs + len <= 64);
+
     if (ofs == 0 && len == 64) {
         tcg_gen_mov_i64(ret, arg2);
         return;
commit c552d6c038f7cf4058d1fd5987118ffd41e0e050
Author: Richard Henderson <rth at twiddle.net>
Date:   Fri Sep 21 17:18:14 2012 -0700

    tcg: Add tcg_debug_assert
    
    Like the C assert macro, except only enabled for CONFIG_DEBUG_TCG,
    and without having to set _NDEBUG and disable all other asserts at
    the same time.
    
    The use of __builtin_unreachable (when available) gives the compiler
    the same information, which may (or may not) help it optimize better.
    
    Signed-off-by: Richard Henderson <rth at twiddle.net>
    Signed-off-by: Aurelien Jarno <aurelien at aurel32.net>

diff --git a/tcg/tcg.h b/tcg/tcg.h
index 48a56f0..4501c15 100644
--- a/tcg/tcg.h
+++ b/tcg/tcg.h
@@ -530,6 +530,15 @@ do {\
     abort();\
 } while (0)
 
+#ifdef CONFIG_DEBUG_TCG
+# define tcg_debug_assert(X) do { assert(X); } while (0)
+#elif QEMU_GNUC_PREREQ(4, 5)
+# define tcg_debug_assert(X) \
+    do { if (!(X)) { __builtin_unreachable(); } } while (0)
+#else
+# define tcg_debug_assert(X) do { (void)(X); } while (0)
+#endif
+
 void tcg_add_target_add_op_defs(const TCGTargetOpDef *tdefs);
 
 #if TCG_TARGET_REG_BITS == 32
commit 77276f6581b660a14bec069ec8d20f1280bddeb6
Author: Richard Henderson <rth at twiddle.net>
Date:   Fri Sep 21 17:18:13 2012 -0700

    tcg: Implement concat*_i64 with deposit_i64
    
    For tcg_gen_concat_i32_i64 we only use deposit if the host supports it.
    For tcg_gen_concat32_i64 even if the host does not, as we get identical
    code before and after.
    
    Note that this relies on the ANDI -> EXTU patch for the identity claim.
    
    Signed-off-by: Richard Henderson <rth at twiddle.net>
    Signed-off-by: Aurelien Jarno <aurelien at aurel32.net>

diff --git a/tcg/tcg-op.h b/tcg/tcg-op.h
index bcfb60b..d2fb283 100644
--- a/tcg/tcg-op.h
+++ b/tcg/tcg-op.h
@@ -1809,36 +1809,6 @@ static inline void tcg_gen_discard_i64(TCGv_i64 arg)
 #endif
 }
 
-static inline void tcg_gen_concat_i32_i64(TCGv_i64 dest, TCGv_i32 low, TCGv_i32 high)
-{
-#if TCG_TARGET_REG_BITS == 32
-    tcg_gen_mov_i32(TCGV_LOW(dest), low);
-    tcg_gen_mov_i32(TCGV_HIGH(dest), high);
-#else
-    TCGv_i64 tmp = tcg_temp_new_i64();
-    /* This extension is only needed for type correctness.
-       We may be able to do better given target specific information.  */
-    tcg_gen_extu_i32_i64(tmp, high);
-    tcg_gen_shli_i64(tmp, tmp, 32);
-    tcg_gen_extu_i32_i64(dest, low);
-    tcg_gen_or_i64(dest, dest, tmp);
-    tcg_temp_free_i64(tmp);
-#endif
-}
-
-static inline void tcg_gen_concat32_i64(TCGv_i64 dest, TCGv_i64 low, TCGv_i64 high)
-{
-#if TCG_TARGET_REG_BITS == 32
-    tcg_gen_concat_i32_i64(dest, TCGV_LOW(low), TCGV_LOW(high));
-#else
-    TCGv_i64 tmp = tcg_temp_new_i64();
-    tcg_gen_ext32u_i64(dest, low);
-    tcg_gen_shli_i64(tmp, high, 32);
-    tcg_gen_or_i64(dest, dest, tmp);
-    tcg_temp_free_i64(tmp);
-#endif
-}
-
 static inline void tcg_gen_andc_i32(TCGv_i32 ret, TCGv_i32 arg1, TCGv_i32 arg2)
 {
     if (TCG_TARGET_HAS_andc_i32) {
@@ -2181,6 +2151,36 @@ static inline void tcg_gen_deposit_i64(TCGv_i64 ret, TCGv_i64 arg1,
     tcg_temp_free_i64(t1);
 }
 
+static inline void tcg_gen_concat_i32_i64(TCGv_i64 dest, TCGv_i32 low,
+                                          TCGv_i32 high)
+{
+#if TCG_TARGET_REG_BITS == 32
+    tcg_gen_mov_i32(TCGV_LOW(dest), low);
+    tcg_gen_mov_i32(TCGV_HIGH(dest), high);
+#else
+    TCGv_i64 tmp = tcg_temp_new_i64();
+    /* These extensions are only needed for type correctness.
+       We may be able to do better given target specific information.  */
+    tcg_gen_extu_i32_i64(tmp, high);
+    tcg_gen_extu_i32_i64(dest, low);
+    /* If deposit is available, use it.  Otherwise use the extra
+       knowledge that we have of the zero-extensions above.  */
+    if (TCG_TARGET_HAS_deposit_i64 && TCG_TARGET_deposit_i64_valid(32, 32)) {
+        tcg_gen_deposit_i64(dest, dest, tmp, 32, 32);
+    } else {
+        tcg_gen_shli_i64(tmp, tmp, 32);
+        tcg_gen_or_i64(dest, dest, tmp);
+    }
+    tcg_temp_free_i64(tmp);
+#endif
+}
+
+static inline void tcg_gen_concat32_i64(TCGv_i64 dest, TCGv_i64 low,
+                                        TCGv_i64 high)
+{
+    tcg_gen_deposit_i64(dest, low, high, 32, 32);
+}
+
 static inline void tcg_gen_movcond_i32(TCGCond cond, TCGv_i32 ret,
                                        TCGv_i32 c1, TCGv_i32 c2,
                                        TCGv_i32 v1, TCGv_i32 v2)
commit 6f3bb33eaa79570b7009f3704ca55c4f8296219f
Author: Richard Henderson <rth at twiddle.net>
Date:   Fri Sep 21 17:18:12 2012 -0700

    tcg: Emit XORI as NOT for appropriate constants
    
    Note that xori_i64 failed to perform even the minimal
    optimizations promised by the README.
    
    Signed-off-by: Richard Henderson <rth at twiddle.net>
    Signed-off-by: Aurelien Jarno <aurelien at aurel32.net>

diff --git a/tcg/tcg-op.h b/tcg/tcg-op.h
index fd16499..bcfb60b 100644
--- a/tcg/tcg-op.h
+++ b/tcg/tcg-op.h
@@ -582,9 +582,12 @@ static inline void tcg_gen_xor_i32(TCGv_i32 ret, TCGv_i32 arg1, TCGv_i32 arg2)
 
 static inline void tcg_gen_xori_i32(TCGv_i32 ret, TCGv_i32 arg1, int32_t arg2)
 {
-    /* some cases can be optimized here */
+    /* Some cases can be optimized here.  */
     if (arg2 == 0) {
         tcg_gen_mov_i32(ret, arg1);
+    } else if (arg2 == -1 && TCG_TARGET_HAS_not_i32) {
+        /* Don't recurse with tcg_gen_not_i32.  */
+        tcg_gen_op2_i32(INDEX_op_not_i32, ret, arg1);
     } else {
         TCGv_i32 t0 = tcg_const_i32(arg2);
         tcg_gen_xor_i32(ret, arg1, t0);
@@ -1206,9 +1209,17 @@ static inline void tcg_gen_xor_i64(TCGv_i64 ret, TCGv_i64 arg1, TCGv_i64 arg2)
 
 static inline void tcg_gen_xori_i64(TCGv_i64 ret, TCGv_i64 arg1, int64_t arg2)
 {
-    TCGv_i64 t0 = tcg_const_i64(arg2);
-    tcg_gen_xor_i64(ret, arg1, t0);
-    tcg_temp_free_i64(t0);
+    /* Some cases can be optimized here.  */
+    if (arg2 == 0) {
+        tcg_gen_mov_i64(ret, arg1);
+    } else if (arg2 == -1 && TCG_TARGET_HAS_not_i64) {
+        /* Don't recurse with tcg_gen_not_i64.  */
+        tcg_gen_op2_i64(INDEX_op_not_i64, ret, arg1);
+    } else {
+        TCGv_i64 t0 = tcg_const_i64(arg2);
+        tcg_gen_xor_i64(ret, arg1, t0);
+        tcg_temp_free_i64(t0);
+    }
 }
 
 static inline void tcg_gen_shl_i64(TCGv_i64 ret, TCGv_i64 arg1, TCGv_i64 arg2)
commit d81ada7fa43e588a24856da4bfcdcac020d8e25b
Author: Richard Henderson <rth at twiddle.net>
Date:   Fri Sep 21 17:18:11 2012 -0700

    tcg: Optimize initial inputs for ori_i64
    
    Copy the same optimizations from ori_i32.
    
    Signed-off-by: Richard Henderson <rth at twiddle.net>
    Signed-off-by: Aurelien Jarno <aurelien at aurel32.net>

diff --git a/tcg/tcg-op.h b/tcg/tcg-op.h
index c8633ff..fd16499 100644
--- a/tcg/tcg-op.h
+++ b/tcg/tcg-op.h
@@ -559,9 +559,9 @@ static inline void tcg_gen_or_i32(TCGv_i32 ret, TCGv_i32 arg1, TCGv_i32 arg2)
 
 static inline void tcg_gen_ori_i32(TCGv_i32 ret, TCGv_i32 arg1, int32_t arg2)
 {
-    /* some cases can be optimized here */
-    if (arg2 == 0xffffffff) {
-        tcg_gen_movi_i32(ret, 0xffffffff);
+    /* Some cases can be optimized here.  */
+    if (arg2 == -1) {
+        tcg_gen_movi_i32(ret, -1);
     } else if (arg2 == 0) {
         tcg_gen_mov_i32(ret, arg1);
     } else {
@@ -1183,9 +1183,16 @@ static inline void tcg_gen_or_i64(TCGv_i64 ret, TCGv_i64 arg1, TCGv_i64 arg2)
 
 static inline void tcg_gen_ori_i64(TCGv_i64 ret, TCGv_i64 arg1, int64_t arg2)
 {
-    TCGv_i64 t0 = tcg_const_i64(arg2);
-    tcg_gen_or_i64(ret, arg1, t0);
-    tcg_temp_free_i64(t0);
+    /* Some cases can be optimized here.  */
+    if (arg2 == -1) {
+        tcg_gen_movi_i64(ret, -1);
+    } else if (arg2 == 0) {
+        tcg_gen_mov_i64(ret, arg1);
+    } else {
+        TCGv_i64 t0 = tcg_const_i64(arg2);
+        tcg_gen_or_i64(ret, arg1, t0);
+        tcg_temp_free_i64(t0);
+    }
 }
 
 static inline void tcg_gen_xor_i64(TCGv_i64 ret, TCGv_i64 arg1, TCGv_i64 arg2)
commit 42ce3e2015b26df591e1d4c5aa1814fb8c45c36c
Author: Richard Henderson <rth at twiddle.net>
Date:   Fri Sep 21 17:18:10 2012 -0700

    tcg: Emit ANDI as EXTU for appropriate constants
    
    Note that andi_i64 failed to perform even the minimal
    optimizations promised by the README.
    
    Signed-off-by: Richard Henderson <rth at twiddle.net>
    Signed-off-by: Aurelien Jarno <aurelien at aurel32.net>

diff --git a/tcg/tcg-op.h b/tcg/tcg-op.h
index 6d28f82..c8633ff 100644
--- a/tcg/tcg-op.h
+++ b/tcg/tcg-op.h
@@ -518,18 +518,34 @@ static inline void tcg_gen_and_i32(TCGv_i32 ret, TCGv_i32 arg1, TCGv_i32 arg2)
     }
 }
 
-static inline void tcg_gen_andi_i32(TCGv_i32 ret, TCGv_i32 arg1, int32_t arg2)
+static inline void tcg_gen_andi_i32(TCGv_i32 ret, TCGv_i32 arg1, uint32_t arg2)
 {
-    /* some cases can be optimized here */
-    if (arg2 == 0) {
+    TCGv_i32 t0;
+    /* Some cases can be optimized here.  */
+    switch (arg2) {
+    case 0:
         tcg_gen_movi_i32(ret, 0);
-    } else if (arg2 == 0xffffffff) {
+        return;
+    case 0xffffffffu:
         tcg_gen_mov_i32(ret, arg1);
-    } else {
-        TCGv_i32 t0 = tcg_const_i32(arg2);
-        tcg_gen_and_i32(ret, arg1, t0);
-        tcg_temp_free_i32(t0);
-    }
+        return;
+    case 0xffu:
+        /* Don't recurse with tcg_gen_ext8u_i32.  */
+        if (TCG_TARGET_HAS_ext8u_i32) {
+            tcg_gen_op2_i32(INDEX_op_ext8u_i32, ret, arg1);
+            return;
+        }
+        break;
+    case 0xffffu:
+        if (TCG_TARGET_HAS_ext16u_i32) {
+            tcg_gen_op2_i32(INDEX_op_ext16u_i32, ret, arg1);
+            return;
+        }
+        break;
+    }
+    t0 = tcg_const_i32(arg2);
+    tcg_gen_and_i32(ret, arg1, t0);
+    tcg_temp_free_i32(t0);
 }
 
 static inline void tcg_gen_or_i32(TCGv_i32 ret, TCGv_i32 arg1, TCGv_i32 arg2)
@@ -1120,9 +1136,38 @@ static inline void tcg_gen_and_i64(TCGv_i64 ret, TCGv_i64 arg1, TCGv_i64 arg2)
     }
 }
 
-static inline void tcg_gen_andi_i64(TCGv_i64 ret, TCGv_i64 arg1, int64_t arg2)
+static inline void tcg_gen_andi_i64(TCGv_i64 ret, TCGv_i64 arg1, uint64_t arg2)
 {
-    TCGv_i64 t0 = tcg_const_i64(arg2);
+    TCGv_i64 t0;
+    /* Some cases can be optimized here.  */
+    switch (arg2) {
+    case 0:
+        tcg_gen_movi_i64(ret, 0);
+        return;
+    case 0xffffffffffffffffull:
+        tcg_gen_mov_i64(ret, arg1);
+        return;
+    case 0xffull:
+        /* Don't recurse with tcg_gen_ext8u_i32.  */
+        if (TCG_TARGET_HAS_ext8u_i64) {
+            tcg_gen_op2_i64(INDEX_op_ext8u_i64, ret, arg1);
+            return;
+        }
+        break;
+    case 0xffffu:
+        if (TCG_TARGET_HAS_ext16u_i64) {
+            tcg_gen_op2_i64(INDEX_op_ext16u_i64, ret, arg1);
+            return;
+        }
+        break;
+    case 0xffffffffull:
+        if (TCG_TARGET_HAS_ext32u_i64) {
+            tcg_gen_op2_i64(INDEX_op_ext32u_i64, ret, arg1);
+            return;
+        }
+        break;
+    }
+    t0 = tcg_const_i64(arg2);
     tcg_gen_and_i64(ret, arg1, t0);
     tcg_temp_free_i64(t0);
 }
commit 5a696f6ac0641f200cdd2dfe7a6fd397d48ea7bd
Author: Richard Henderson <rth at twiddle.net>
Date:   Fri Sep 21 17:18:09 2012 -0700

    tcg: Adjust descriptions of *cond opcodes
    
    The README file documented the operand ordering of the tcg_gen_*
    functions.  Since we're documenting opcodes here, use the true
    operand ordering.
    
    Signed-off-by: Richard Henderson <rth at twiddle.net>
    Cc: malc <av1474 at comtv.ru>
    Signed-off-by: Aurelien Jarno <aurelien at aurel32.net>

diff --git a/tcg/README b/tcg/README
index 33783ee..27846f1 100644
--- a/tcg/README
+++ b/tcg/README
@@ -141,7 +141,7 @@ Define label 'label' at the current program point.
 
 Jump to label.
 
-* brcond_i32/i64 cond, t0, t1, label
+* brcond_i32/i64 t0, t1, cond, label
 
 Conditional jump if t0 cond t1 is true. cond can be:
     TCG_COND_EQ
@@ -301,13 +301,13 @@ This operation would be equivalent to
 
 ********* Conditional moves
 
-* setcond_i32/i64 cond, dest, t1, t2
+* setcond_i32/i64 dest, t1, t2, cond
 
 dest = (t1 cond t2)
 
 Set DEST to 1 if (T1 cond T2) is true, otherwise set to 0.
 
-* movcond_i32/i64 cond, dest, c1, c2, v1, v2
+* movcond_i32/i64 dest, c1, c2, v1, v2, cond
 
 dest = (c1 cond c2 ? v1 : v2)
 
@@ -360,7 +360,7 @@ The following opcodes are internal to TCG.  Thus they are to be implemented by
 32-bit host code generators, but are not to be emitted by guest translators.
 They are emitted as needed by inline functions within "tcg-op.h".
 
-* brcond2_i32 cond, t0_low, t0_high, t1_low, t1_high, label
+* brcond2_i32 t0_low, t0_high, t1_low, t1_high, cond, label
 
 Similar to brcond, except that the 64-bit values T0 and T1
 are formed from two 32-bit arguments.
@@ -377,7 +377,7 @@ is returned in two 32-bit outputs.
 Similar to mul, except two 32-bit (unsigned) inputs T1 and T2 yielding
 the full 64-bit product T0.  The later is returned in two 32-bit outputs.
 
-* setcond2_i32 cond, dest, t1_low, t1_high, t2_low, t2_high
+* setcond2_i32 dest, t1_low, t1_high, t2_low, t2_high, cond
 
 Similar to setcond, except that the 64-bit values T1 and T2 are
 formed from two 32-bit arguments.  The result is a 32-bit value.
commit 8f06bf693dec29642255adcc2828bc6b7daa83d9
Author: Aurelien Jarno <aurelien at aurel32.net>
Date:   Sat Sep 22 23:08:38 2012 +0200

    tcg/mips: fix MIPS32(R2) detection
    
    Fix the MIPS32(R2) cpu detection so that it also works with
    -march=octeon. Thanks to Andrew Pinski for the hint.
    
    Cc: Andrew Pinski <apinski at cavium.com>
    Signed-off-by: Aurelien Jarno <aurelien at aurel32.net>

diff --git a/tcg/mips/tcg-target.c b/tcg/mips/tcg-target.c
index f70910a..34e3e7f 100644
--- a/tcg/mips/tcg-target.c
+++ b/tcg/mips/tcg-target.c
@@ -419,7 +419,7 @@ static inline void tcg_out_movi(TCGContext *s, TCGType type,
 
 static inline void tcg_out_bswap16(TCGContext *s, TCGReg ret, TCGReg arg)
 {
-#ifdef _MIPS_ARCH_MIPS32R2
+#if defined(__mips_isa_rev) && (__mips_isa_rev >= 2)
     tcg_out_opc_reg(s, OPC_WSBH, ret, 0, arg);
 #else
     /* ret and arg can't be register at */
@@ -436,7 +436,7 @@ static inline void tcg_out_bswap16(TCGContext *s, TCGReg ret, TCGReg arg)
 
 static inline void tcg_out_bswap16s(TCGContext *s, TCGReg ret, TCGReg arg)
 {
-#ifdef _MIPS_ARCH_MIPS32R2
+#if defined(__mips_isa_rev) && (__mips_isa_rev >= 2)
     tcg_out_opc_reg(s, OPC_WSBH, ret, 0, arg);
     tcg_out_opc_reg(s, OPC_SEH, ret, 0, ret);
 #else
@@ -454,7 +454,7 @@ static inline void tcg_out_bswap16s(TCGContext *s, TCGReg ret, TCGReg arg)
 
 static inline void tcg_out_bswap32(TCGContext *s, TCGReg ret, TCGReg arg)
 {
-#ifdef _MIPS_ARCH_MIPS32R2
+#if defined(__mips_isa_rev) && (__mips_isa_rev >= 2)
     tcg_out_opc_reg(s, OPC_WSBH, ret, 0, arg);
     tcg_out_opc_sa(s, OPC_ROTR, ret, ret, 16);
 #else
@@ -480,7 +480,7 @@ static inline void tcg_out_bswap32(TCGContext *s, TCGReg ret, TCGReg arg)
 
 static inline void tcg_out_ext8s(TCGContext *s, TCGReg ret, TCGReg arg)
 {
-#ifdef _MIPS_ARCH_MIPS32R2
+#if defined(__mips_isa_rev) && (__mips_isa_rev >= 2)
     tcg_out_opc_reg(s, OPC_SEB, ret, 0, arg);
 #else
     tcg_out_opc_sa(s, OPC_SLL, ret, arg, 24);
@@ -490,7 +490,7 @@ static inline void tcg_out_ext8s(TCGContext *s, TCGReg ret, TCGReg arg)
 
 static inline void tcg_out_ext16s(TCGContext *s, TCGReg ret, TCGReg arg)
 {
-#ifdef _MIPS_ARCH_MIPS32R2
+#if defined(__mips_isa_rev) && (__mips_isa_rev >= 2)
     tcg_out_opc_reg(s, OPC_SEH, ret, 0, arg);
 #else
     tcg_out_opc_sa(s, OPC_SLL, ret, arg, 16);
diff --git a/tcg/mips/tcg-target.h b/tcg/mips/tcg-target.h
index d147e70..7020d65 100644
--- a/tcg/mips/tcg-target.h
+++ b/tcg/mips/tcg-target.h
@@ -88,16 +88,16 @@ typedef enum {
 #define TCG_TARGET_HAS_nand_i32         0
 
 /* optional instructions only implemented on MIPS4, MIPS32 and Loongson 2 */
-#if defined(_MIPS_ARCH_MIPS4) || defined(_MIPS_ARCH_MIPS32) || \
-    defined(_MIPS_ARCH_MIPS32R2) || defined(_MIPS_ARCH_LOONGSON2E) || \
-    defined(_MIPS_ARCH_LOONGSON2F)
+#if (defined(__mips_isa_rev) && (__mips_isa_rev >= 1)) || \
+    defined(_MIPS_ARCH_LOONGSON2E) || defined(_MIPS_ARCH_LOONGSON2F) || \
+    defined(_MIPS_ARCH_MIPS4)
 #define TCG_TARGET_HAS_movcond_i32      1
 #else
 #define TCG_TARGET_HAS_movcond_i32      0
 #endif
 
 /* optional instructions only implemented on MIPS32R2 */
-#ifdef _MIPS_ARCH_MIPS32R2
+#if defined(__mips_isa_rev) && (__mips_isa_rev >= 2)
 #define TCG_TARGET_HAS_bswap16_i32      1
 #define TCG_TARGET_HAS_bswap32_i32      1
 #define TCG_TARGET_HAS_rot_i32          1
commit 444dbc381b94f5b54da521df61e751f28b00ce88
Merge: 3988475... dc1c13d...
Author: Anthony Liguori <aliguori at us.ibm.com>
Date:   Tue Sep 25 16:06:16 2012 -0500

    Merge remote-tracking branch 'kwolf/for-anthony' into staging
    
    * kwolf/for-anthony:
      block: remove keep_read_only flag from BlockDriverState struct
      block: convert bdrv_commit() to use bdrv_reopen()
      block: vpc image file reopen
      block: vdi image file reopen
      block: vmdk image file reopen
      block: qcow image file reopen
      block: qcow2 image file reopen
      block: qed image file reopen
      block: raw image file reopen
      block: raw-posix image file reopen
      block: purge s->aligned_buf and s->aligned_buf_size from raw-posix.c
      block: use BDRV_O_NOCACHE instead of s->aligned_buf in raw-posix.c
      block: do not parse BDRV_O_CACHE_WB in block drivers
      block: move open flag parsing in raw block drivers to helper functions
      block: move aio initialization into a helper function
      block: Framework for reopening files safely
      block: make bdrv_set_enable_write_cache() modify open_flags
      block: correctly set the keep_read_only flag
      blockdev: preserve readonly and snapshot states across media changes

commit 3988475b9b7fa251b00a29b076761d8c1c7e64dc
Merge: 97fe81d... 95df51a...
Author: Anthony Liguori <aliguori at us.ibm.com>
Date:   Tue Sep 25 16:06:16 2012 -0500

    Merge remote-tracking branch 'stefanha/trivial-patches' into staging
    
    * stefanha/trivial-patches:
      w32: Always use standard instead of native format strings
      net/socket: Fix compiler warning (regression for MinGW)
      linux-user: Remove redundant null check and replace free by g_free
      qemu-timer: simplify qemu_run_timers
      TextConsole: saturate escape parameter in TTY_STATE_CSI
      curses: don't initialize curses when qemu is daemonized
      dtrace backend: add function to reserved words
      pflash_cfi01: Fix warning caused by unreachable code
      ioh3420: Remove unreachable code
      lm4549: Fix buffer overflow
      cadence_uart: Fix buffer overflow
      qemu-sockets: Fix potential memory leak
      qemu-ga: Remove unreachable code after g_error
      target-i386: Allow tsc-frequency to be larger then 2.147G

commit 97fe81d3e8613be13754ff096c16b73010fd60ad
Merge: d352210... 2b85cf0...
Author: Anthony Liguori <aliguori at us.ibm.com>
Date:   Tue Sep 25 16:06:16 2012 -0500

    Merge remote-tracking branch 'afaerber/qom-cpu' into staging
    
    * afaerber/qom-cpu:
      target-alpha: Initialize env->cpu_model_str
      target-i386: Drop unused setscalar() macro
      target-i386: Kill cpudef config section support
      target-i386: x86_cpudef_setup() coding style change
      Eliminate cpus-x86_64.conf file
      target-i386: Move CPU models from cpus-x86_64.conf to C
      target-i386: Add missing CPUID_* constants
      Drop cpu_list_id macro
      target-i386: Fold -cpu ?cpuid, ?model output into -cpu help, drop ?dump
      MAINTAINERS: Add entry for QOM CPU

commit d352210aede32743c6e7a8987c99196d84ab5471
Merge: 09d0726... 1109c89...
Author: Anthony Liguori <aliguori at us.ibm.com>
Date:   Tue Sep 25 16:06:16 2012 -0500

    Merge remote-tracking branch 'bonzini/scsi-next' into staging
    
    * bonzini/scsi-next:
      SCSI: Standard INQUIRY data should report HiSup flag as set.
      scsi-disk: use scsi_data_cdb_length
      scsi: introduce scsi_cdb_length and scsi_data_cdb_length
      scsi-disk: fix check for out-of-range LBA
      scsi-disk: introduce check_lba_range
      iSCSI: We dont need to explicitely call qemu_notify_event() any more
      iSCSI: We need to support SG_IO also from iscsi_ioctl()

commit 09d0726c0351cbf71b96b41b9f39cc7857b45ccc
Merge: d3e8f95... 125afda...
Author: Anthony Liguori <aliguori at us.ibm.com>
Date:   Tue Sep 25 16:06:15 2012 -0500

    Merge remote-tracking branch 'bonzini/nbd-next' into staging
    
    * bonzini/nbd-next:
      nbd: add nbd_export_get_blockdev
      nbd: negotiate with named exports
      nbd: register named exports
      qemu-nbd: rewrite termination conditions to use a state machine
      nbd: add notification for closing an NBDExport
      nbd: track clients into NBDExport
      nbd: add reference counting to NBDExport
      nbd: do not leak nbd_trip coroutines when a connection is torn down
      nbd: make refcount interface public
      nbd: do not close BlockDriverState in nbd_export_close
      nbd: pass NBDClient to nbd_send_negotiate
      nbd: add more constants

commit dc1c13d96912731d4c7c7e13d31c93b8735f1203
Author: Jeff Cody <jcody at redhat.com>
Date:   Thu Sep 20 15:13:35 2012 -0400

    block: remove keep_read_only flag from BlockDriverState struct
    
    The keep_read_only flag is no longer used, in favor of the bdrv
    flag BDRV_O_ALLOW_RDWR.
    
    Signed-off-by: Jeff Cody <jcody at redhat.com>
    Signed-off-by: Kevin Wolf <kwolf at redhat.com>

diff --git a/block.c b/block.c
index 84544d2..751ebdc 100644
--- a/block.c
+++ b/block.c
@@ -812,8 +812,6 @@ int bdrv_open(BlockDriverState *bs, const char *filename, int flags,
         flags |= BDRV_O_ALLOW_RDWR;
     }
 
-    bs->keep_read_only = !(flags & BDRV_O_ALLOW_RDWR);
-
     /* Open the image */
     ret = bdrv_open_common(bs, filename, flags, drv);
     if (ret < 0) {
diff --git a/block_int.h b/block_int.h
index 22b3d93..ac4245c 100644
--- a/block_int.h
+++ b/block_int.h
@@ -275,7 +275,6 @@ struct BlockDriverState {
     int64_t total_sectors; /* if we are reading a disk image, give its
                               size in sectors */
     int read_only; /* if true, the media is read only */
-    int keep_read_only; /* if true, the media was requested to stay read only */
     int open_flags; /* flags used to open the file, re-used for re-open */
     int encrypted; /* if true, the media is encrypted */
     int valid_key; /* if true, a valid encryption key has been set */
commit 0bce597d6ec34b2af802799eb53ebc863c704d05
Author: Jeff Cody <jcody at redhat.com>
Date:   Thu Sep 20 15:13:34 2012 -0400

    block: convert bdrv_commit() to use bdrv_reopen()
    
    Currently, bdrv_commit() reopens images r/w itself, via risky
    _delete() and _open() calls. Use the new safe method for drive reopen.
    
    Signed-off-by: Jeff Cody <jcody at redhat.com>
    Signed-off-by: Kevin Wolf <kwolf at redhat.com>

diff --git a/block.c b/block.c
index c7c1a3b..84544d2 100644
--- a/block.c
+++ b/block.c
@@ -1501,13 +1501,11 @@ int bdrv_check(BlockDriverState *bs, BdrvCheckResult *res, BdrvCheckMode fix)
 int bdrv_commit(BlockDriverState *bs)
 {
     BlockDriver *drv = bs->drv;
-    BlockDriver *backing_drv;
     int64_t sector, total_sectors;
     int n, ro, open_flags;
-    int ret = 0, rw_ret = 0;
+    int ret = 0;
     uint8_t *buf;
     char filename[1024];
-    BlockDriverState *bs_rw, *bs_ro;
 
     if (!drv)
         return -ENOMEDIUM;
@@ -1516,42 +1514,18 @@ int bdrv_commit(BlockDriverState *bs)
         return -ENOTSUP;
     }
 
-    if (bs->backing_hd->keep_read_only) {
-        return -EACCES;
-    }
-
     if (bdrv_in_use(bs) || bdrv_in_use(bs->backing_hd)) {
         return -EBUSY;
     }
 
-    backing_drv = bs->backing_hd->drv;
     ro = bs->backing_hd->read_only;
     strncpy(filename, bs->backing_hd->filename, sizeof(filename));
     open_flags =  bs->backing_hd->open_flags;
 
     if (ro) {
-        /* re-open as RW */
-        bdrv_delete(bs->backing_hd);
-        bs->backing_hd = NULL;
-        bs_rw = bdrv_new("");
-        rw_ret = bdrv_open(bs_rw, filename, open_flags | BDRV_O_RDWR,
-            backing_drv);
-        if (rw_ret < 0) {
-            bdrv_delete(bs_rw);
-            /* try to re-open read-only */
-            bs_ro = bdrv_new("");
-            ret = bdrv_open(bs_ro, filename, open_flags & ~BDRV_O_RDWR,
-                backing_drv);
-            if (ret < 0) {
-                bdrv_delete(bs_ro);
-                /* drive not functional anymore */
-                bs->drv = NULL;
-                return ret;
-            }
-            bs->backing_hd = bs_ro;
-            return rw_ret;
+        if (bdrv_reopen(bs->backing_hd, open_flags | BDRV_O_RDWR, NULL)) {
+            return -EACCES;
         }
-        bs->backing_hd = bs_rw;
     }
 
     total_sectors = bdrv_getlength(bs) >> BDRV_SECTOR_BITS;
@@ -1588,20 +1562,8 @@ ro_cleanup:
     g_free(buf);
 
     if (ro) {
-        /* re-open as RO */
-        bdrv_delete(bs->backing_hd);
-        bs->backing_hd = NULL;
-        bs_ro = bdrv_new("");
-        ret = bdrv_open(bs_ro, filename, open_flags & ~BDRV_O_RDWR,
-            backing_drv);
-        if (ret < 0) {
-            bdrv_delete(bs_ro);
-            /* drive not functional anymore */
-            bs->drv = NULL;
-            return ret;
-        }
-        bs->backing_hd = bs_ro;
-        bs->backing_hd->keep_read_only = 0;
+        /* ignoring error return here */
+        bdrv_reopen(bs->backing_hd, open_flags & ~BDRV_O_RDWR, NULL);
     }
 
     return ret;
commit 3fe4b70008f3a0323e1d685becc6a9cff2b71de7
Author: Jeff Cody <jcody at redhat.com>
Date:   Thu Sep 20 15:13:33 2012 -0400

    block: vpc image file reopen
    
    There is currently nothing that needs to be done for VPC image
    file reopen.
    
    Signed-off-by: Jeff Cody <jcody at redhat.com>
    Signed-off-by: Kevin Wolf <kwolf at redhat.com>

diff --git a/block/vpc.c b/block/vpc.c
index c0b82c4..b6bf52f 100644
--- a/block/vpc.c
+++ b/block/vpc.c
@@ -265,6 +265,12 @@ static int vpc_open(BlockDriverState *bs, int flags)
     return err;
 }
 
+static int vpc_reopen_prepare(BDRVReopenState *state,
+                              BlockReopenQueue *queue, Error **errp)
+{
+    return 0;
+}
+
 /*
  * Returns the absolute byte offset of the given sector in the image file.
  * If the sector is not allocated, -1 is returned instead.
@@ -783,6 +789,7 @@ static BlockDriver bdrv_vpc = {
     .bdrv_probe     = vpc_probe,
     .bdrv_open      = vpc_open,
     .bdrv_close     = vpc_close,
+    .bdrv_reopen_prepare = vpc_reopen_prepare,
     .bdrv_create    = vpc_create,
 
     .bdrv_read              = vpc_co_read,
commit ecfe2bbabbc25e08b21ae57d66e484ef64c4aefa
Author: Jeff Cody <jcody at redhat.com>
Date:   Thu Sep 20 15:13:32 2012 -0400

    block: vdi image file reopen
    
    There is currently nothing that needs to be done for VDI reopen.
    
    Signed-off-by: Jeff Cody <jcody at redhat.com>
    Signed-off-by: Kevin Wolf <kwolf at redhat.com>

diff --git a/block/vdi.c b/block/vdi.c
index 550cf58..f35b12e 100644
--- a/block/vdi.c
+++ b/block/vdi.c
@@ -454,6 +454,12 @@ static int vdi_open(BlockDriverState *bs, int flags)
     return -1;
 }
 
+static int vdi_reopen_prepare(BDRVReopenState *state,
+                              BlockReopenQueue *queue, Error **errp)
+{
+    return 0;
+}
+
 static int coroutine_fn vdi_co_is_allocated(BlockDriverState *bs,
         int64_t sector_num, int nb_sectors, int *pnum)
 {
@@ -761,6 +767,7 @@ static BlockDriver bdrv_vdi = {
     .bdrv_probe = vdi_probe,
     .bdrv_open = vdi_open,
     .bdrv_close = vdi_close,
+    .bdrv_reopen_prepare = vdi_reopen_prepare,
     .bdrv_create = vdi_create,
     .bdrv_co_is_allocated = vdi_co_is_allocated,
     .bdrv_make_empty = vdi_make_empty,
commit 3897575f1cd96370a604be8cb5cf1e3fae2be0c1
Author: Jeff Cody <jcody at redhat.com>
Date:   Thu Sep 20 15:13:30 2012 -0400

    block: vmdk image file reopen
    
    This patch supports reopen for VMDK image files.  VMDK extents are added
    to the existing reopen queue, so that the transactional model of reopen
    is maintained with multiple image files.
    
    Signed-off-by: Jeff Cody <jcody at redhat.com>
    Signed-off-by: Kevin Wolf <kwolf at redhat.com>

diff --git a/block/vmdk.c b/block/vmdk.c
index bba4c61..f2e861b 100644
--- a/block/vmdk.c
+++ b/block/vmdk.c
@@ -300,6 +300,40 @@ static int vmdk_is_cid_valid(BlockDriverState *bs)
     return 1;
 }
 
+/* Queue extents, if any, for reopen() */
+static int vmdk_reopen_prepare(BDRVReopenState *state,
+                               BlockReopenQueue *queue, Error **errp)
+{
+    BDRVVmdkState *s;
+    int ret = -1;
+    int i;
+    VmdkExtent *e;
+
+    assert(state != NULL);
+    assert(state->bs != NULL);
+
+    if (queue == NULL) {
+        error_set(errp, ERROR_CLASS_GENERIC_ERROR,
+                 "No reopen queue for VMDK extents");
+        goto exit;
+    }
+
+    s = state->bs->opaque;
+
+    assert(s != NULL);
+
+    for (i = 0; i < s->num_extents; i++) {
+        e = &s->extents[i];
+        if (e->file != state->bs->file) {
+            bdrv_reopen_queue(queue, e->file, state->flags);
+        }
+    }
+    ret = 0;
+
+exit:
+    return ret;
+}
+
 static int vmdk_parent_open(BlockDriverState *bs)
 {
     char *p_name;
@@ -1646,6 +1680,7 @@ static BlockDriver bdrv_vmdk = {
     .instance_size  = sizeof(BDRVVmdkState),
     .bdrv_probe     = vmdk_probe,
     .bdrv_open      = vmdk_open,
+    .bdrv_reopen_prepare = vmdk_reopen_prepare,
     .bdrv_read      = vmdk_co_read,
     .bdrv_write     = vmdk_co_write,
     .bdrv_close     = vmdk_close,
commit d177692ede3129dcb18a6b0f5472577bed2e2688
Author: Jeff Cody <jcody at redhat.com>
Date:   Thu Sep 20 15:13:29 2012 -0400

    block: qcow image file reopen
    
    These are the stubs for the file reopen drivers for the qcow format.
    
    There is currently nothing that needs to be done by the qcow driver
    in reopen.
    
    Signed-off-by: Jeff Cody <jcody at redhat.com>
    Signed-off-by: Kevin Wolf <kwolf at redhat.com>

diff --git a/block/qcow.c b/block/qcow.c
index 7b5ab87..b239c82 100644
--- a/block/qcow.c
+++ b/block/qcow.c
@@ -197,6 +197,15 @@ static int qcow_open(BlockDriverState *bs, int flags)
     return ret;
 }
 
+
+/* We have nothing to do for QCOW reopen, stubs just return
+ * success */
+static int qcow_reopen_prepare(BDRVReopenState *state,
+                               BlockReopenQueue *queue, Error **errp)
+{
+    return 0;
+}
+
 static int qcow_set_key(BlockDriverState *bs, const char *key)
 {
     BDRVQcowState *s = bs->opaque;
@@ -868,6 +877,7 @@ static BlockDriver bdrv_qcow = {
     .bdrv_probe		= qcow_probe,
     .bdrv_open		= qcow_open,
     .bdrv_close		= qcow_close,
+    .bdrv_reopen_prepare = qcow_reopen_prepare,
     .bdrv_create	= qcow_create,
 
     .bdrv_co_readv          = qcow_co_readv,
commit 21d82ac95f67947ebc32ada96184f00831a9b911
Author: Jeff Cody <jcody at redhat.com>
Date:   Thu Sep 20 15:13:28 2012 -0400

    block: qcow2 image file reopen
    
    These are the stubs for the file reopen drivers for the qcow2 format.
    
    There is currently nothing that needs to be done by the qcow2 driver
    in reopen.
    
    Signed-off-by: Jeff Cody <jcody at redhat.com>
    Signed-off-by: Kevin Wolf <kwolf at redhat.com>

diff --git a/block/qcow2.c b/block/qcow2.c
index 8f183f1..aa5e603 100644
--- a/block/qcow2.c
+++ b/block/qcow2.c
@@ -52,6 +52,7 @@ typedef struct {
     uint32_t magic;
     uint32_t len;
 } QCowExtension;
+
 #define  QCOW2_EXT_MAGIC_END 0
 #define  QCOW2_EXT_MAGIC_BACKING_FORMAT 0xE2792ACA
 #define  QCOW2_EXT_MAGIC_FEATURE_TABLE 0x6803f857
@@ -558,6 +559,14 @@ static int qcow2_set_key(BlockDriverState *bs, const char *key)
     return 0;
 }
 
+/* We have nothing to do for QCOW2 reopen, stubs just return
+ * success */
+static int qcow2_reopen_prepare(BDRVReopenState *state,
+                                BlockReopenQueue *queue, Error **errp)
+{
+    return 0;
+}
+
 static int coroutine_fn qcow2_co_is_allocated(BlockDriverState *bs,
         int64_t sector_num, int nb_sectors, int *pnum)
 {
@@ -1679,6 +1688,7 @@ static BlockDriver bdrv_qcow2 = {
     .bdrv_probe         = qcow2_probe,
     .bdrv_open          = qcow2_open,
     .bdrv_close         = qcow2_close,
+    .bdrv_reopen_prepare  = qcow2_reopen_prepare,
     .bdrv_create        = qcow2_create,
     .bdrv_co_is_allocated = qcow2_co_is_allocated,
     .bdrv_set_key       = qcow2_set_key,
commit f9cb20f167ff205e37a895ee6a03d5a183ef8acf
Author: Jeff Cody <jcody at redhat.com>
Date:   Thu Sep 20 15:13:27 2012 -0400

    block: qed image file reopen
    
    These are the stubs for the file reopen drivers for the qed format.
    
    There is currently nothing that needs to be done by the qed driver
    in reopen.
    
    Signed-off-by: Jeff Cody <jcody at redhat.com>
    Signed-off-by: Kevin Wolf <kwolf at redhat.com>

diff --git a/block/qed.c b/block/qed.c
index 21cb239..6c182ca 100644
--- a/block/qed.c
+++ b/block/qed.c
@@ -505,6 +505,14 @@ out:
     return ret;
 }
 
+/* We have nothing to do for QED reopen, stubs just return
+ * success */
+static int bdrv_qed_reopen_prepare(BDRVReopenState *state,
+                                   BlockReopenQueue *queue, Error **errp)
+{
+    return 0;
+}
+
 static void bdrv_qed_close(BlockDriverState *bs)
 {
     BDRVQEDState *s = bs->opaque;
@@ -1564,6 +1572,7 @@ static BlockDriver bdrv_qed = {
     .bdrv_rebind              = bdrv_qed_rebind,
     .bdrv_open                = bdrv_qed_open,
     .bdrv_close               = bdrv_qed_close,
+    .bdrv_reopen_prepare      = bdrv_qed_reopen_prepare,
     .bdrv_create              = bdrv_qed_create,
     .bdrv_co_is_allocated     = bdrv_qed_co_is_allocated,
     .bdrv_make_empty          = bdrv_qed_make_empty,
commit 01bdddb5aaf4f660355cf764874f19271978f74f
Author: Jeff Cody <jcody at redhat.com>
Date:   Thu Sep 20 15:13:26 2012 -0400

    block: raw image file reopen
    
    These are the stubs for the file reopen drivers for the raw format.
    
    There is currently nothing that needs to be done by the raw driver
    in reopen.
    
    Signed-off-by: Jeff Cody <jcody at redhat.com>
    Signed-off-by: Kevin Wolf <kwolf at redhat.com>

diff --git a/block/raw.c b/block/raw.c
index ff34ea4..253e949 100644
--- a/block/raw.c
+++ b/block/raw.c
@@ -9,6 +9,14 @@ static int raw_open(BlockDriverState *bs, int flags)
     return 0;
 }
 
+/* We have nothing to do for raw reopen, stubs just return
+ * success */
+static int raw_reopen_prepare(BDRVReopenState *state,
+                              BlockReopenQueue *queue,  Error **errp)
+{
+    return 0;
+}
+
 static int coroutine_fn raw_co_readv(BlockDriverState *bs, int64_t sector_num,
                                      int nb_sectors, QEMUIOVector *qiov)
 {
@@ -115,6 +123,8 @@ static BlockDriver bdrv_raw = {
     .bdrv_open          = raw_open,
     .bdrv_close         = raw_close,
 
+    .bdrv_reopen_prepare  = raw_reopen_prepare,
+
     .bdrv_co_readv          = raw_co_readv,
     .bdrv_co_writev         = raw_co_writev,
     .bdrv_co_is_allocated   = raw_co_is_allocated,
commit eeb6b45d48800e96f67ef2a5c80332557fd45ddb
Author: Jeff Cody <jcody at redhat.com>
Date:   Thu Sep 20 15:13:25 2012 -0400

    block: raw-posix image file reopen
    
    This is derived from the Supriya Kannery's reopen patches.
    
    This contains the raw-posix driver changes for the bdrv_reopen_*
    functions.  All changes are staged into a temporary scratch buffer
    during the prepare() stage, and copied over to the live structure
    during commit().  Upon abort(), all changes are abandoned, and the
    live structures are unmodified.
    
    The _prepare() will create an extra fd - either by means of a dup,
    if possible, or opening a new fd if not (for instance, access
    control changes).  Upon _commit(), the original fd is closed and
    the new fd is used.  Upon _abort(), the duplicate/new fd is closed.
    
    Signed-off-by: Jeff Cody <jcody at redhat.com>
    Signed-off-by: Kevin Wolf <kwolf at redhat.com>

diff --git a/block/raw-posix.c b/block/raw-posix.c
index 0ffb3d0..28d439f 100644
--- a/block/raw-posix.c
+++ b/block/raw-posix.c
@@ -138,6 +138,14 @@ typedef struct BDRVRawState {
 #endif
 } BDRVRawState;
 
+typedef struct BDRVRawReopenState {
+    int fd;
+    int open_flags;
+#ifdef CONFIG_LINUX_AIO
+    int use_aio;
+#endif
+} BDRVRawReopenState;
+
 static int fd_open(BlockDriverState *bs);
 static int64_t raw_getlength(BlockDriverState *bs);
 
@@ -290,6 +298,109 @@ static int raw_open(BlockDriverState *bs, const char *filename, int flags)
     return raw_open_common(bs, filename, flags, 0);
 }
 
+static int raw_reopen_prepare(BDRVReopenState *state,
+                              BlockReopenQueue *queue, Error **errp)
+{
+    BDRVRawState *s;
+    BDRVRawReopenState *raw_s;
+    int ret = 0;
+
+    assert(state != NULL);
+    assert(state->bs != NULL);
+
+    s = state->bs->opaque;
+
+    state->opaque = g_malloc0(sizeof(BDRVRawReopenState));
+    raw_s = state->opaque;
+
+#ifdef CONFIG_LINUX_AIO
+    raw_s->use_aio = s->use_aio;
+
+    /* we can use s->aio_ctx instead of a copy, because the use_aio flag is
+     * valid in the 'false' condition even if aio_ctx is set, and raw_set_aio()
+     * won't override aio_ctx if aio_ctx is non-NULL */
+    if (raw_set_aio(&s->aio_ctx, &raw_s->use_aio, state->flags)) {
+        return -1;
+    }
+#endif
+
+    raw_parse_flags(state->flags, &raw_s->open_flags);
+
+    raw_s->fd = -1;
+
+    int fcntl_flags = O_APPEND | O_ASYNC | O_NONBLOCK;
+#ifdef O_NOATIME
+    fcntl_flags |= O_NOATIME;
+#endif
+
+    if ((raw_s->open_flags & ~fcntl_flags) == (s->open_flags & ~fcntl_flags)) {
+        /* dup the original fd */
+        /* TODO: use qemu fcntl wrapper */
+#ifdef F_DUPFD_CLOEXEC
+        raw_s->fd = fcntl(s->fd, F_DUPFD_CLOEXEC, 0);
+#else
+        raw_s->fd = dup(s->fd);
+        if (raw_s->fd != -1) {
+            qemu_set_cloexec(raw_s->fd);
+        }
+#endif
+        if (raw_s->fd >= 0) {
+            ret = fcntl_setfl(raw_s->fd, raw_s->open_flags);
+            if (ret) {
+                qemu_close(raw_s->fd);
+                raw_s->fd = -1;
+            }
+        }
+    }
+
+    /* If we cannot use fcntl, or fcntl failed, fall back to qemu_open() */
+    if (raw_s->fd == -1) {
+        assert(!(raw_s->open_flags & O_CREAT));
+        raw_s->fd = qemu_open(state->bs->filename, raw_s->open_flags);
+        if (raw_s->fd == -1) {
+            ret = -1;
+        }
+    }
+    return ret;
+}
+
+
+static void raw_reopen_commit(BDRVReopenState *state)
+{
+    BDRVRawReopenState *raw_s = state->opaque;
+    BDRVRawState *s = state->bs->opaque;
+
+    s->open_flags = raw_s->open_flags;
+
+    qemu_close(s->fd);
+    s->fd = raw_s->fd;
+#ifdef CONFIG_LINUX_AIO
+    s->use_aio = raw_s->use_aio;
+#endif
+
+    g_free(state->opaque);
+    state->opaque = NULL;
+}
+
+
+static void raw_reopen_abort(BDRVReopenState *state)
+{
+    BDRVRawReopenState *raw_s = state->opaque;
+
+     /* nothing to do if NULL, we didn't get far enough */
+    if (raw_s == NULL) {
+        return;
+    }
+
+    if (raw_s->fd >= 0) {
+        qemu_close(raw_s->fd);
+        raw_s->fd = -1;
+    }
+    g_free(state->opaque);
+    state->opaque = NULL;
+}
+
+
 /* XXX: use host sector size if necessary with:
 #ifdef DIOCGSECTORSIZE
         {
@@ -740,6 +851,9 @@ static BlockDriver bdrv_file = {
     .instance_size = sizeof(BDRVRawState),
     .bdrv_probe = NULL, /* no probe for protocols */
     .bdrv_file_open = raw_open,
+    .bdrv_reopen_prepare = raw_reopen_prepare,
+    .bdrv_reopen_commit = raw_reopen_commit,
+    .bdrv_reopen_abort = raw_reopen_abort,
     .bdrv_close = raw_close,
     .bdrv_create = raw_create,
     .bdrv_co_discard = raw_co_discard,
commit 3d1807ac6707773526b193f296e72c6c86969bf7
Author: Jeff Cody <jcody at redhat.com>
Date:   Thu Sep 20 15:13:24 2012 -0400

    block: purge s->aligned_buf and s->aligned_buf_size from raw-posix.c
    
    The aligned_buf pointer and aligned_buf size are no longer used in
    raw_posix.c, so remove all references to them.
    
    Signed-off-by: Jeff Cody <jcody at redhat.com>
    Signed-off-by: Kevin Wolf <kwolf at redhat.com>

diff --git a/block/raw-posix.c b/block/raw-posix.c
index 1e727eb..0ffb3d0 100644
--- a/block/raw-posix.c
+++ b/block/raw-posix.c
@@ -133,8 +133,6 @@ typedef struct BDRVRawState {
     int use_aio;
     void *aio_ctx;
 #endif
-    uint8_t *aligned_buf;
-    unsigned aligned_buf_size;
 #ifdef CONFIG_XFS
     bool is_xfs : 1;
 #endif
@@ -259,23 +257,10 @@ static int raw_open_common(BlockDriverState *bs, const char *filename,
         return ret;
     }
     s->fd = fd;
-    s->aligned_buf = NULL;
-
-    if ((bdrv_flags & BDRV_O_NOCACHE)) {
-        /*
-         * Allocate a buffer for read/modify/write cycles.  Chose the size
-         * pessimistically as we don't know the block size yet.
-         */
-        s->aligned_buf_size = 32 * MAX_BLOCKSIZE;
-        s->aligned_buf = qemu_memalign(MAX_BLOCKSIZE, s->aligned_buf_size);
-        if (s->aligned_buf == NULL) {
-            goto out_close;
-        }
-    }
 
     /* We're falling back to POSIX AIO in some cases so init always */
     if (paio_init() < 0) {
-        goto out_free_buf;
+        goto out_close;
     }
 
 #ifdef CONFIG_LINUX_AIO
@@ -292,8 +277,6 @@ static int raw_open_common(BlockDriverState *bs, const char *filename,
 
     return 0;
 
-out_free_buf:
-    qemu_vfree(s->aligned_buf);
 out_close:
     qemu_close(fd);
     return -errno;
@@ -402,8 +385,6 @@ static void raw_close(BlockDriverState *bs)
     if (s->fd >= 0) {
         qemu_close(s->fd);
         s->fd = -1;
-        if (s->aligned_buf != NULL)
-            qemu_vfree(s->aligned_buf);
     }
 }
 
commit 9acc5a06d41416400dda0ae9495707236911e234
Author: Jeff Cody <jcody at redhat.com>
Date:   Thu Sep 20 15:13:23 2012 -0400

    block: use BDRV_O_NOCACHE instead of s->aligned_buf in raw-posix.c
    
    Rather than check for a non-NULL aligned_buf to determine if
    raw_aio_submit needs to check for alignment, check for the presence
    of BDRV_O_NOCACHE in the bs->open_flags.
    
    Signed-off-by: Jeff Cody <jcody at redhat.com>
    Signed-off-by: Kevin Wolf <kwolf at redhat.com>

diff --git a/block/raw-posix.c b/block/raw-posix.c
index 288e7ff..1e727eb 100644
--- a/block/raw-posix.c
+++ b/block/raw-posix.c
@@ -354,7 +354,7 @@ static BlockDriverAIOCB *raw_aio_submit(BlockDriverState *bs,
      * boundary.  Check if this is the case or tell the low-level
      * driver that it needs to copy the buffer.
      */
-    if (s->aligned_buf) {
+    if ((bs->open_flags & BDRV_O_NOCACHE)) {
         if (!qiov_is_aligned(bs, qiov)) {
             type |= QEMU_AIO_MISALIGNED;
 #ifdef CONFIG_LINUX_AIO
commit 39c9fb9565613a5ca0ae6e83ea115585f91527bb
Author: Jeff Cody <jcody at redhat.com>
Date:   Thu Sep 20 15:13:22 2012 -0400

    block: do not parse BDRV_O_CACHE_WB in block drivers
    
    Block drivers should ignore BDRV_O_CACHE_WB in .bdrv_open flags,
    and in the bs->open_flags.
    
    This patch removes the code, leaving the behaviour behind as if
    BDRV_O_CACHE_WB was set.
    
    Signed-off-by: Jeff Cody <jcody at redhat.com>
    Signed-off-by: Kevin Wolf <kwolf at redhat.com>

diff --git a/block/iscsi.c b/block/iscsi.c
index 0b96165..70cf700 100644
--- a/block/iscsi.c
+++ b/block/iscsi.c
@@ -268,10 +268,6 @@ iscsi_aio_writev(BlockDriverState *bs, int64_t sector_num,
     acb->task->xfer_dir = SCSI_XFER_WRITE;
     acb->task->cdb_size = 16;
     acb->task->cdb[0] = 0x8a;
-    if (!(bs->open_flags & BDRV_O_CACHE_WB)) {
-        /* set FUA on writes when cache mode is write through */
-        acb->task->cdb[1] |= 0x04;
-    }
     lba = sector_qemu2lun(sector_num, iscsilun);
     *(uint32_t *)&acb->task->cdb[2]  = htonl(lba >> 32);
     *(uint32_t *)&acb->task->cdb[6]  = htonl(lba & 0xffffffff);
diff --git a/block/raw-posix.c b/block/raw-posix.c
index 155205f..288e7ff 100644
--- a/block/raw-posix.c
+++ b/block/raw-posix.c
@@ -202,9 +202,6 @@ static void raw_parse_flags(int bdrv_flags, int *open_flags)
     if ((bdrv_flags & BDRV_O_NOCACHE)) {
         *open_flags |= O_DIRECT;
     }
-    if (!(bdrv_flags & BDRV_O_CACHE_WB)) {
-        *open_flags |= O_DSYNC;
-    }
 }
 
 #ifdef CONFIG_LINUX_AIO
diff --git a/block/raw-win32.c b/block/raw-win32.c
index 335c06a..78c8306 100644
--- a/block/raw-win32.c
+++ b/block/raw-win32.c
@@ -92,9 +92,6 @@ static void raw_parse_flags(int flags, int *access_flags, DWORD *overlapped)
     if (flags & BDRV_O_NOCACHE) {
         *overlapped |= FILE_FLAG_NO_BUFFERING;
     }
-    if (!(flags & BDRV_O_CACHE_WB)) {
-        *overlapped |= FILE_FLAG_WRITE_THROUGH;
-    }
 }
 
 static int raw_open(BlockDriverState *bs, const char *filename, int flags)
diff --git a/block/rbd.c b/block/rbd.c
index 5a0f79f..015a9db 100644
--- a/block/rbd.c
+++ b/block/rbd.c
@@ -487,12 +487,6 @@ static int qemu_rbd_open(BlockDriverState *bs, const char *filename, int flags)
         rados_conf_set(s->cluster, "rbd_cache", "false");
     } else {
         rados_conf_set(s->cluster, "rbd_cache", "true");
-        if (!(flags & BDRV_O_CACHE_WB)) {
-            r = rados_conf_set(s->cluster, "rbd_cache_max_dirty", "0");
-            if (r < 0) {
-                rados_conf_set(s->cluster, "rbd_cache", "false");
-            }
-        }
     }
 
     if (strstr(conf, "conf=") == NULL) {
diff --git a/block/sheepdog.c b/block/sheepdog.c
index e0753ee..4742f8a 100644
--- a/block/sheepdog.c
+++ b/block/sheepdog.c
@@ -1114,14 +1114,12 @@ static int sd_open(BlockDriverState *bs, const char *filename, int flags)
         goto out;
     }
 
-    if (flags & BDRV_O_CACHE_WB) {
-        s->cache_enabled = 1;
-        s->flush_fd = connect_to_sdog(s->addr, s->port);
-        if (s->flush_fd < 0) {
-            error_report("failed to connect");
-            ret = s->flush_fd;
-            goto out;
-        }
+    s->cache_enabled = 1;
+    s->flush_fd = connect_to_sdog(s->addr, s->port);
+    if (s->flush_fd < 0) {
+        error_report("failed to connect");
+        ret = s->flush_fd;
+        goto out;
     }
 
     if (snapid || tag[0] != '\0') {
commit 6a8dc0422e508fc85390e55cbca1b93cb242d22d
Author: Jeff Cody <jcody at redhat.com>
Date:   Thu Sep 20 15:13:21 2012 -0400

    block: move open flag parsing in raw block drivers to helper functions
    
    Code motion, to move parsing of open flags into a helper function.
    
    Signed-off-by: Jeff Cody <jcody at redhat.com>
    Signed-off-by: Kevin Wolf <kwolf at redhat.com>

diff --git a/block/raw-posix.c b/block/raw-posix.c
index 5981d04..155205f 100644
--- a/block/raw-posix.c
+++ b/block/raw-posix.c
@@ -185,6 +185,28 @@ static int raw_normalize_devicepath(const char **filename)
 }
 #endif
 
+static void raw_parse_flags(int bdrv_flags, int *open_flags)
+{
+    assert(open_flags != NULL);
+
+    *open_flags |= O_BINARY;
+    *open_flags &= ~O_ACCMODE;
+    if (bdrv_flags & BDRV_O_RDWR) {
+        *open_flags |= O_RDWR;
+    } else {
+        *open_flags |= O_RDONLY;
+    }
+
+    /* Use O_DSYNC for write-through caching, no flags for write-back caching,
+     * and O_DIRECT for no caching. */
+    if ((bdrv_flags & BDRV_O_NOCACHE)) {
+        *open_flags |= O_DIRECT;
+    }
+    if (!(bdrv_flags & BDRV_O_CACHE_WB)) {
+        *open_flags |= O_DSYNC;
+    }
+}
+
 #ifdef CONFIG_LINUX_AIO
 static int raw_set_aio(void **aio_ctx, int *use_aio, int bdrv_flags)
 {
@@ -228,20 +250,8 @@ static int raw_open_common(BlockDriverState *bs, const char *filename,
         return ret;
     }
 
-    s->open_flags = open_flags | O_BINARY;
-    s->open_flags &= ~O_ACCMODE;
-    if (bdrv_flags & BDRV_O_RDWR) {
-        s->open_flags |= O_RDWR;
-    } else {
-        s->open_flags |= O_RDONLY;
-    }
-
-    /* Use O_DSYNC for write-through caching, no flags for write-back caching,
-     * and O_DIRECT for no caching. */
-    if ((bdrv_flags & BDRV_O_NOCACHE))
-        s->open_flags |= O_DIRECT;
-    if (!(bdrv_flags & BDRV_O_CACHE_WB))
-        s->open_flags |= O_DSYNC;
+    s->open_flags = open_flags;
+    raw_parse_flags(bdrv_flags, &s->open_flags);
 
     s->fd = -1;
     fd = qemu_open(filename, s->open_flags, 0644);
diff --git a/block/raw-win32.c b/block/raw-win32.c
index c56bf83..335c06a 100644
--- a/block/raw-win32.c
+++ b/block/raw-win32.c
@@ -77,6 +77,26 @@ static int set_sparse(int fd)
 				 NULL, 0, NULL, 0, &returned, NULL);
 }
 
+static void raw_parse_flags(int flags, int *access_flags, DWORD *overlapped)
+{
+    assert(access_flags != NULL);
+    assert(overlapped != NULL);
+
+    if (flags & BDRV_O_RDWR) {
+        *access_flags = GENERIC_READ | GENERIC_WRITE;
+    } else {
+        *access_flags = GENERIC_READ;
+    }
+
+    *overlapped = FILE_ATTRIBUTE_NORMAL;
+    if (flags & BDRV_O_NOCACHE) {
+        *overlapped |= FILE_FLAG_NO_BUFFERING;
+    }
+    if (!(flags & BDRV_O_CACHE_WB)) {
+        *overlapped |= FILE_FLAG_WRITE_THROUGH;
+    }
+}
+
 static int raw_open(BlockDriverState *bs, const char *filename, int flags)
 {
     BDRVRawState *s = bs->opaque;
@@ -85,17 +105,8 @@ static int raw_open(BlockDriverState *bs, const char *filename, int flags)
 
     s->type = FTYPE_FILE;
 
-    if (flags & BDRV_O_RDWR) {
-        access_flags = GENERIC_READ | GENERIC_WRITE;
-    } else {
-        access_flags = GENERIC_READ;
-    }
+    raw_parse_flags(flags, &access_flags, &overlapped);
 
-    overlapped = FILE_ATTRIBUTE_NORMAL;
-    if (flags & BDRV_O_NOCACHE)
-        overlapped |= FILE_FLAG_NO_BUFFERING;
-    if (!(flags & BDRV_O_CACHE_WB))
-        overlapped |= FILE_FLAG_WRITE_THROUGH;
     s->hfile = CreateFile(filename, access_flags,
                           FILE_SHARE_READ, NULL,
                           OPEN_EXISTING, overlapped, NULL);
@@ -374,18 +385,10 @@ static int hdev_open(BlockDriverState *bs, const char *filename, int flags)
     }
     s->type = find_device_type(bs, filename);
 
-    if (flags & BDRV_O_RDWR) {
-        access_flags = GENERIC_READ | GENERIC_WRITE;
-    } else {
-        access_flags = GENERIC_READ;
-    }
+    raw_parse_flags(flags, &access_flags, &overlapped);
+
     create_flags = OPEN_EXISTING;
 
-    overlapped = FILE_ATTRIBUTE_NORMAL;
-    if (flags & BDRV_O_NOCACHE)
-        overlapped |= FILE_FLAG_NO_BUFFERING;
-    if (!(flags & BDRV_O_CACHE_WB))
-        overlapped |= FILE_FLAG_WRITE_THROUGH;
     s->hfile = CreateFile(filename, access_flags,
                           FILE_SHARE_READ, NULL,
                           create_flags, overlapped, NULL);
commit fc32a72dc19a79f7e16156784b1e76a128d41841
Author: Jeff Cody <jcody at redhat.com>
Date:   Thu Sep 20 15:13:20 2012 -0400

    block: move aio initialization into a helper function
    
    Move AIO initialization for raw-posix block driver into a helper function.
    
    In addition to just code motion, the aio_ctx pointer is checked for NULL,
    prior to calling laio_init(), to make sure laio_init() is only run once.
    
    Signed-off-by: Jeff Cody <jcody at redhat.com>
    Signed-off-by: Kevin Wolf <kwolf at redhat.com>

diff --git a/block/raw-posix.c b/block/raw-posix.c
index 6be20b1..5981d04 100644
--- a/block/raw-posix.c
+++ b/block/raw-posix.c
@@ -185,6 +185,38 @@ static int raw_normalize_devicepath(const char **filename)
 }
 #endif
 
+#ifdef CONFIG_LINUX_AIO
+static int raw_set_aio(void **aio_ctx, int *use_aio, int bdrv_flags)
+{
+    int ret = -1;
+    assert(aio_ctx != NULL);
+    assert(use_aio != NULL);
+    /*
+     * Currently Linux do AIO only for files opened with O_DIRECT
+     * specified so check NOCACHE flag too
+     */
+    if ((bdrv_flags & (BDRV_O_NOCACHE|BDRV_O_NATIVE_AIO)) ==
+                      (BDRV_O_NOCACHE|BDRV_O_NATIVE_AIO)) {
+
+        /* if non-NULL, laio_init() has already been run */
+        if (*aio_ctx == NULL) {
+            *aio_ctx = laio_init();
+            if (!*aio_ctx) {
+                goto error;
+            }
+        }
+        *use_aio = 1;
+    } else {
+        *use_aio = 0;
+    }
+
+    ret = 0;
+
+error:
+    return ret;
+}
+#endif
+
 static int raw_open_common(BlockDriverState *bs, const char *filename,
                            int bdrv_flags, int open_flags)
 {
@@ -240,25 +272,10 @@ static int raw_open_common(BlockDriverState *bs, const char *filename,
     }
 
 #ifdef CONFIG_LINUX_AIO
-    /*
-     * Currently Linux do AIO only for files opened with O_DIRECT
-     * specified so check NOCACHE flag too
-     */
-    if ((bdrv_flags & (BDRV_O_NOCACHE|BDRV_O_NATIVE_AIO)) ==
-                      (BDRV_O_NOCACHE|BDRV_O_NATIVE_AIO)) {
-
-        s->aio_ctx = laio_init();
-        if (!s->aio_ctx) {
-            goto out_free_buf;
-        }
-        s->use_aio = 1;
-    } else
-#endif
-    {
-#ifdef CONFIG_LINUX_AIO
-        s->use_aio = 0;
-#endif
+    if (raw_set_aio(&s->aio_ctx, &s->use_aio, bdrv_flags)) {
+        goto out_close;
     }
+#endif
 
 #ifdef CONFIG_XFS
     if (platform_test_xfs_fd(s->fd)) {
commit e971aa12739f269d6fbfaeabdd4acaeb0f15960b
Author: Jeff Cody <jcody at redhat.com>
Date:   Thu Sep 20 15:13:19 2012 -0400

    block: Framework for reopening files safely
    
    This is based on Supriya Kannery's bdrv_reopen() patch series.
    
    This provides a transactional method to reopen multiple
    images files safely.
    
    Image files are queue for reopen via bdrv_reopen_queue(), and the
    reopen occurs when bdrv_reopen_multiple() is called.  Changes are
    staged in bdrv_reopen_prepare() and in the equivalent driver level
    functions.  If any of the staged images fails a prepare, then all
    of the images left untouched, and the staged changes for each image
    abandoned.
    
    Block drivers are passed a reopen state structure, that contains:
        * BDS to reopen
        * flags for the reopen
        * opaque pointer for any driver-specific data that needs to be
          persistent from _prepare to _commit/_abort
        * reopen queue pointer, if the driver needs to queue additional
          BDS for a reopen
    
    Signed-off-by: Jeff Cody <jcody at redhat.com>
    Signed-off-by: Kevin Wolf <kwolf at redhat.com>

diff --git a/block.c b/block.c
index 458bcc9..c7c1a3b 100644
--- a/block.c
+++ b/block.c
@@ -863,6 +863,238 @@ unlink_and_fail:
     return ret;
 }
 
+typedef struct BlockReopenQueueEntry {
+     bool prepared;
+     BDRVReopenState state;
+     QSIMPLEQ_ENTRY(BlockReopenQueueEntry) entry;
+} BlockReopenQueueEntry;
+
+/*
+ * Adds a BlockDriverState to a simple queue for an atomic, transactional
+ * reopen of multiple devices.
+ *
+ * bs_queue can either be an existing BlockReopenQueue that has had QSIMPLE_INIT
+ * already performed, or alternatively may be NULL a new BlockReopenQueue will
+ * be created and initialized. This newly created BlockReopenQueue should be
+ * passed back in for subsequent calls that are intended to be of the same
+ * atomic 'set'.
+ *
+ * bs is the BlockDriverState to add to the reopen queue.
+ *
+ * flags contains the open flags for the associated bs
+ *
+ * returns a pointer to bs_queue, which is either the newly allocated
+ * bs_queue, or the existing bs_queue being used.
+ *
+ */
+BlockReopenQueue *bdrv_reopen_queue(BlockReopenQueue *bs_queue,
+                                    BlockDriverState *bs, int flags)
+{
+    assert(bs != NULL);
+
+    BlockReopenQueueEntry *bs_entry;
+    if (bs_queue == NULL) {
+        bs_queue = g_new0(BlockReopenQueue, 1);
+        QSIMPLEQ_INIT(bs_queue);
+    }
+
+    if (bs->file) {
+        bdrv_reopen_queue(bs_queue, bs->file, flags);
+    }
+
+    bs_entry = g_new0(BlockReopenQueueEntry, 1);
+    QSIMPLEQ_INSERT_TAIL(bs_queue, bs_entry, entry);
+
+    bs_entry->state.bs = bs;
+    bs_entry->state.flags = flags;
+
+    return bs_queue;
+}
+
+/*
+ * Reopen multiple BlockDriverStates atomically & transactionally.
+ *
+ * The queue passed in (bs_queue) must have been built up previous
+ * via bdrv_reopen_queue().
+ *
+ * Reopens all BDS specified in the queue, with the appropriate
+ * flags.  All devices are prepared for reopen, and failure of any
+ * device will cause all device changes to be abandonded, and intermediate
+ * data cleaned up.
+ *
+ * If all devices prepare successfully, then the changes are committed
+ * to all devices.
+ *
+ */
+int bdrv_reopen_multiple(BlockReopenQueue *bs_queue, Error **errp)
+{
+    int ret = -1;
+    BlockReopenQueueEntry *bs_entry, *next;
+    Error *local_err = NULL;
+
+    assert(bs_queue != NULL);
+
+    bdrv_drain_all();
+
+    QSIMPLEQ_FOREACH(bs_entry, bs_queue, entry) {
+        if (bdrv_reopen_prepare(&bs_entry->state, bs_queue, &local_err)) {
+            error_propagate(errp, local_err);
+            goto cleanup;
+        }
+        bs_entry->prepared = true;
+    }
+
+    /* If we reach this point, we have success and just need to apply the
+     * changes
+     */
+    QSIMPLEQ_FOREACH(bs_entry, bs_queue, entry) {
+        bdrv_reopen_commit(&bs_entry->state);
+    }
+
+    ret = 0;
+
+cleanup:
+    QSIMPLEQ_FOREACH_SAFE(bs_entry, bs_queue, entry, next) {
+        if (ret && bs_entry->prepared) {
+            bdrv_reopen_abort(&bs_entry->state);
+        }
+        g_free(bs_entry);
+    }
+    g_free(bs_queue);
+    return ret;
+}
+
+
+/* Reopen a single BlockDriverState with the specified flags. */
+int bdrv_reopen(BlockDriverState *bs, int bdrv_flags, Error **errp)
+{
+    int ret = -1;
+    Error *local_err = NULL;
+    BlockReopenQueue *queue = bdrv_reopen_queue(NULL, bs, bdrv_flags);
+
+    ret = bdrv_reopen_multiple(queue, &local_err);
+    if (local_err != NULL) {
+        error_propagate(errp, local_err);
+    }
+    return ret;
+}
+
+
+/*
+ * Prepares a BlockDriverState for reopen. All changes are staged in the
+ * 'opaque' field of the BDRVReopenState, which is used and allocated by
+ * the block driver layer .bdrv_reopen_prepare()
+ *
+ * bs is the BlockDriverState to reopen
+ * flags are the new open flags
+ * queue is the reopen queue
+ *
+ * Returns 0 on success, non-zero on error.  On error errp will be set
+ * as well.
+ *
+ * On failure, bdrv_reopen_abort() will be called to clean up any data.
+ * It is the responsibility of the caller to then call the abort() or
+ * commit() for any other BDS that have been left in a prepare() state
+ *
+ */
+int bdrv_reopen_prepare(BDRVReopenState *reopen_state, BlockReopenQueue *queue,
+                        Error **errp)
+{
+    int ret = -1;
+    Error *local_err = NULL;
+    BlockDriver *drv;
+
+    assert(reopen_state != NULL);
+    assert(reopen_state->bs->drv != NULL);
+    drv = reopen_state->bs->drv;
+
+    /* if we are to stay read-only, do not allow permission change
+     * to r/w */
+    if (!(reopen_state->bs->open_flags & BDRV_O_ALLOW_RDWR) &&
+        reopen_state->flags & BDRV_O_RDWR) {
+        error_set(errp, QERR_DEVICE_IS_READ_ONLY,
+                  reopen_state->bs->device_name);
+        goto error;
+    }
+
+
+    ret = bdrv_flush(reopen_state->bs);
+    if (ret) {
+        error_set(errp, ERROR_CLASS_GENERIC_ERROR, "Error (%s) flushing drive",
+                  strerror(-ret));
+        goto error;
+    }
+
+    if (drv->bdrv_reopen_prepare) {
+        ret = drv->bdrv_reopen_prepare(reopen_state, queue, &local_err);
+        if (ret) {
+            if (local_err != NULL) {
+                error_propagate(errp, local_err);
+            } else {
+                error_set(errp, QERR_OPEN_FILE_FAILED,
+                          reopen_state->bs->filename);
+            }
+            goto error;
+        }
+    } else {
+        /* It is currently mandatory to have a bdrv_reopen_prepare()
+         * handler for each supported drv. */
+        error_set(errp, QERR_BLOCK_FORMAT_FEATURE_NOT_SUPPORTED,
+                  drv->format_name, reopen_state->bs->device_name,
+                 "reopening of file");
+        ret = -1;
+        goto error;
+    }
+
+    ret = 0;
+
+error:
+    return ret;
+}
+
+/*
+ * Takes the staged changes for the reopen from bdrv_reopen_prepare(), and
+ * makes them final by swapping the staging BlockDriverState contents into
+ * the active BlockDriverState contents.
+ */
+void bdrv_reopen_commit(BDRVReopenState *reopen_state)
+{
+    BlockDriver *drv;
+
+    assert(reopen_state != NULL);
+    drv = reopen_state->bs->drv;
+    assert(drv != NULL);
+
+    /* If there are any driver level actions to take */
+    if (drv->bdrv_reopen_commit) {
+        drv->bdrv_reopen_commit(reopen_state);
+    }
+
+    /* set BDS specific flags now */
+    reopen_state->bs->open_flags         = reopen_state->flags;
+    reopen_state->bs->enable_write_cache = !!(reopen_state->flags &
+                                              BDRV_O_CACHE_WB);
+    reopen_state->bs->read_only = !(reopen_state->flags & BDRV_O_RDWR);
+}
+
+/*
+ * Abort the reopen, and delete and free the staged changes in
+ * reopen_state
+ */
+void bdrv_reopen_abort(BDRVReopenState *reopen_state)
+{
+    BlockDriver *drv;
+
+    assert(reopen_state != NULL);
+    drv = reopen_state->bs->drv;
+    assert(drv != NULL);
+
+    if (drv->bdrv_reopen_abort) {
+        drv->bdrv_reopen_abort(reopen_state);
+    }
+}
+
+
 void bdrv_close(BlockDriverState *bs)
 {
     bdrv_flush(bs);
diff --git a/block.h b/block.h
index 4d919c2..b1095d8 100644
--- a/block.h
+++ b/block.h
@@ -97,6 +97,15 @@ typedef enum {
     BDRV_ACTION_REPORT, BDRV_ACTION_IGNORE, BDRV_ACTION_STOP
 } BlockQMPEventAction;
 
+typedef QSIMPLEQ_HEAD(BlockReopenQueue, BlockReopenQueueEntry) BlockReopenQueue;
+
+typedef struct BDRVReopenState {
+    BlockDriverState *bs;
+    int flags;
+    void *opaque;
+} BDRVReopenState;
+
+
 void bdrv_iostatus_enable(BlockDriverState *bs);
 void bdrv_iostatus_reset(BlockDriverState *bs);
 void bdrv_iostatus_disable(BlockDriverState *bs);
@@ -131,6 +140,14 @@ int bdrv_parse_cache_flags(const char *mode, int *flags);
 int bdrv_file_open(BlockDriverState **pbs, const char *filename, int flags);
 int bdrv_open(BlockDriverState *bs, const char *filename, int flags,
               BlockDriver *drv);
+BlockReopenQueue *bdrv_reopen_queue(BlockReopenQueue *bs_queue,
+                                    BlockDriverState *bs, int flags);
+int bdrv_reopen_multiple(BlockReopenQueue *bs_queue, Error **errp);
+int bdrv_reopen(BlockDriverState *bs, int bdrv_flags, Error **errp);
+int bdrv_reopen_prepare(BDRVReopenState *reopen_state,
+                        BlockReopenQueue *queue, Error **errp);
+void bdrv_reopen_commit(BDRVReopenState *reopen_state);
+void bdrv_reopen_abort(BDRVReopenState *reopen_state);
 void bdrv_close(BlockDriverState *bs);
 int bdrv_attach_dev(BlockDriverState *bs, void *dev);
 void bdrv_attach_dev_nofail(BlockDriverState *bs, void *dev);
diff --git a/block_int.h b/block_int.h
index 4452f6f..22b3d93 100644
--- a/block_int.h
+++ b/block_int.h
@@ -139,6 +139,13 @@ struct BlockDriver {
     int instance_size;
     int (*bdrv_probe)(const uint8_t *buf, int buf_size, const char *filename);
     int (*bdrv_probe_device)(const char *filename);
+
+    /* For handling image reopen for split or non-split files */
+    int (*bdrv_reopen_prepare)(BDRVReopenState *reopen_state,
+                               BlockReopenQueue *queue, Error **errp);
+    void (*bdrv_reopen_commit)(BDRVReopenState *reopen_state);
+    void (*bdrv_reopen_abort)(BDRVReopenState *reopen_state);
+
     int (*bdrv_open)(BlockDriverState *bs, int flags);
     int (*bdrv_file_open)(BlockDriverState *bs, const char *filename, int flags);
     int (*bdrv_read)(BlockDriverState *bs, int64_t sector_num,
@@ -336,6 +343,7 @@ struct BlockDriverState {
 
     /* long-running background operation */
     BlockJob *job;
+
 };
 
 int get_tmp_filename(char *filename, int size);
commit 55b110f24ec765a09cfb7f4c013fcd90dd807628
Author: Jeff Cody <jcody at redhat.com>
Date:   Thu Sep 20 15:13:18 2012 -0400

    block: make bdrv_set_enable_write_cache() modify open_flags
    
    bdrv_set_enable_write_cache() sets the bs->enable_write_cache flag,
    but without the flag recorded in bs->open_flags, then next time
    a reopen() is performed the enable_write_cache setting may be
    inadvertently lost.
    
    This will set the flag in open_flags, so it is preserved across
    reopens.
    
    Signed-off-by: Jeff Cody <jcody at redhat.com>
    Signed-off-by: Kevin Wolf <kwolf at redhat.com>

diff --git a/block.c b/block.c
index 4c0e7f5..458bcc9 100644
--- a/block.c
+++ b/block.c
@@ -2168,6 +2168,13 @@ int bdrv_enable_write_cache(BlockDriverState *bs)
 void bdrv_set_enable_write_cache(BlockDriverState *bs, bool wce)
 {
     bs->enable_write_cache = wce;
+
+    /* so a reopen() will preserve wce */
+    if (wce) {
+        bs->open_flags |= BDRV_O_CACHE_WB;
+    } else {
+        bs->open_flags &= ~BDRV_O_CACHE_WB;
+    }
 }
 
 int bdrv_is_encrypted(BlockDriverState *bs)
commit be028adcedd68ca4d78fdc43e7e2fa4f1cdbc653
Author: Jeff Cody <jcody at redhat.com>
Date:   Thu Sep 20 15:13:17 2012 -0400

    block: correctly set the keep_read_only flag
    
    I believe the bs->keep_read_only flag is supposed to reflect
    the initial open state of the device. If the device is initially
    opened R/O, then commit operations, or reopen operations changing
    to R/W, are prohibited.
    
    Currently, the keep_read_only flag is only accurate for the active
    layer, and its backing file. Subsequent images end up always having
    the keep_read_only flag set.
    
    For instance, what happens now:
    
    [  base  ]  kro = 1, ro = 1
        |
        v
    [ snap-1 ]  kro = 1, ro = 1
        |
        v
    [ snap-2 ]  kro = 0, ro = 1
        |
        v
    [ active ]  kro = 0, ro = 0
    
    What we want:
    
    [  base  ]  kro = 0, ro = 1
        |
        v
    [ snap-1 ]  kro = 0, ro = 1
        |
        v
    [ snap-2 ]  kro = 0, ro = 1
        |
        v
    [ active ]  kro = 0, ro = 0
    
    Signed-off-by: Jeff Cody <jcody at redhat.com>
    Signed-off-by: Kevin Wolf <kwolf at redhat.com>

diff --git a/block.c b/block.c
index e78039b..4c0e7f5 100644
--- a/block.c
+++ b/block.c
@@ -668,7 +668,7 @@ static int bdrv_open_common(BlockDriverState *bs, const char *filename,
         open_flags |= BDRV_O_RDWR;
     }
 
-    bs->keep_read_only = bs->read_only = !(open_flags & BDRV_O_RDWR);
+    bs->read_only = !(open_flags & BDRV_O_RDWR);
 
     /* Open the image, either directly or using a protocol */
     if (drv->bdrv_file_open) {
@@ -808,6 +808,12 @@ int bdrv_open(BlockDriverState *bs, const char *filename, int flags,
         goto unlink_and_fail;
     }
 
+    if (flags & BDRV_O_RDWR) {
+        flags |= BDRV_O_ALLOW_RDWR;
+    }
+
+    bs->keep_read_only = !(flags & BDRV_O_ALLOW_RDWR);
+
     /* Open the image */
     ret = bdrv_open_common(bs, filename, flags, drv);
     if (ret < 0) {
@@ -837,12 +843,6 @@ int bdrv_open(BlockDriverState *bs, const char *filename, int flags,
             bdrv_close(bs);
             return ret;
         }
-        if (bs->is_temporary) {
-            bs->backing_hd->keep_read_only = !(flags & BDRV_O_RDWR);
-        } else {
-            /* base image inherits from "parent" */
-            bs->backing_hd->keep_read_only = bs->keep_read_only;
-        }
     }
 
     if (!bdrv_key_required(bs)) {
diff --git a/block.h b/block.h
index 2e2be11..4d919c2 100644
--- a/block.h
+++ b/block.h
@@ -80,6 +80,7 @@ typedef struct BlockDevOps {
 #define BDRV_O_COPY_ON_READ 0x0400 /* copy read backing sectors into image */
 #define BDRV_O_INCOMING    0x0800  /* consistency hint for incoming migration */
 #define BDRV_O_CHECK       0x1000  /* open solely for consistency check */
+#define BDRV_O_ALLOW_RDWR  0x2000  /* allow reopen to change from r/o to r/w */
 
 #define BDRV_O_CACHE_MASK  (BDRV_O_NOCACHE | BDRV_O_CACHE_WB | BDRV_O_NO_FLUSH)
 
commit 80dd1aae3657a902d262f5d20a7a3c655b23705e
Author: Kevin Shanahan <kmshanah at disenchant.net>
Date:   Fri Sep 21 08:50:22 2012 +0930

    blockdev: preserve readonly and snapshot states across media changes
    
    If readonly=on is given at device creation time, the ->readonly flag
    needs to be set in the block driver state for this device so that
    readonly-ness is preserved across media changes (qmp change command).
    Similarly, to preserve the snapshot property requires ->open_flags to
    be correct.
    
    Signed-off-by: Kevin Shanahan <kmshanah at disenchant.net>
    Signed-off-by: Kevin Wolf <kwolf at redhat.com>

diff --git a/blockdev.c b/blockdev.c
index 7c83baa..e5d450f 100644
--- a/blockdev.c
+++ b/blockdev.c
@@ -527,6 +527,8 @@ DriveInfo *drive_init(QemuOpts *opts, int default_to_scsi)
                      if_name[type], mediastr, unit_id);
     }
     dinfo->bdrv = bdrv_new(dinfo->id);
+    dinfo->bdrv->open_flags = snapshot ? BDRV_O_SNAPSHOT : 0;
+    dinfo->bdrv->read_only = ro;
     dinfo->devaddr = devaddr;
     dinfo->type = type;
     dinfo->bus = bus_id;
commit 95df51a4a02a853af8828c281bce2d4f2a41d6fd
Author: Stefan Weil <sw at weilnetz.de>
Date:   Wed Aug 22 21:42:32 2012 +0200

    w32: Always use standard instead of native format strings
    
    GLib 2.0 include files use __printf__ for the format attribute
    which resolves to native format strings on w32 hosts.
    
    QEMU wants standard format strings instead of native format
    strings, so we simply change any declaration with __printf__
    to use __gnu_printf__.
    
    This works because all basic printf functions support both
    kinds of format strings.
    
    This fixes a compiler warning:
    
    qapi/string-output-visitor.c: In function ‘print_type_int’:
    qapi/string-output-visitor.c:34:5: warning: unknown conversion type character ‘l’ in format [-Wformat]
    qapi/string-output-visitor.c:34:5: warning: too many arguments for format [-Wformat-extra-args]
    
    Signed-off-by: Stefan Weil <sw at weilnetz.de>
    Signed-off-by: Stefan Hajnoczi <stefanha at gmail.com>

diff --git a/compiler.h b/compiler.h
index 07ba1f8..c734a71 100644
--- a/compiler.h
+++ b/compiler.h
@@ -44,6 +44,11 @@
    /* Use gnu_printf when supported (qemu uses standard format strings). */
 #  define GCC_ATTR __attribute__((__unused__, format(gnu_printf, 1, 2)))
 #  define GCC_FMT_ATTR(n, m) __attribute__((format(gnu_printf, n, m)))
+#  if defined(_WIN32)
+    /* Map __printf__ to __gnu_printf__ because we want standard format strings
+     * even when MinGW or GLib include files use __printf__. */
+#   define __printf__ __gnu_printf__
+#  endif
 # endif
 #if defined(_WIN32)
 #define GCC_WEAK __attribute__((weak))
commit 73062dfe6be0050dbd43ce3516e935ebb2545add
Author: Stefan Weil <sw at weilnetz.de>
Date:   Sat Sep 22 21:13:28 2012 +0200

    net/socket: Fix compiler warning (regression for MinGW)
    
    Commit 213fd5087e2e4e2da10ad266df0ba950cf7618bf removed a type cast
    which is needed for MinGW:
    
    net/socket.c:136: warning:
     pointer targets in passing argument 2 of ‘sendto’ differ in signedness
    /usr/lib/gcc/amd64-mingw32msvc/4.4.4/../../../../amd64-mingw32msvc/include/winsock2.h:1313: note:
     expected ‘const char *’ but argument is of type ‘const uint8_t *’
    
    Add a 'qemu_sendto' macro which provides that type cast where needed
    and use the new macro instead of 'sendto'.
    
    Signed-off-by: Stefan Weil <sw at weilnetz.de>
    Signed-off-by: Stefan Hajnoczi <stefanha at gmail.com>

diff --git a/net/socket.c b/net/socket.c
index 5e0c92e..f3d7878 100644
--- a/net/socket.c
+++ b/net/socket.c
@@ -131,9 +131,9 @@ static ssize_t net_socket_receive_dgram(NetClientState *nc, const uint8_t *buf,
     ssize_t ret;
 
     do {
-        ret = sendto(s->fd, buf, size, 0,
-                     (struct sockaddr *)&s->dgram_dst,
-                     sizeof(s->dgram_dst));
+        ret = qemu_sendto(s->fd, buf, size, 0,
+                          (struct sockaddr *)&s->dgram_dst,
+                          sizeof(s->dgram_dst));
     } while (ret == -1 && errno == EINTR);
 
     if (ret == -1 && errno == EAGAIN) {
diff --git a/qemu-common.h b/qemu-common.h
index e5c2bcd..15d9e4e 100644
--- a/qemu-common.h
+++ b/qemu-common.h
@@ -223,9 +223,14 @@ int qemu_pipe(int pipefd[2]);
 #endif
 
 #ifdef _WIN32
+/* MinGW needs a type cast for the 'buf' argument. */
 #define qemu_recv(sockfd, buf, len, flags) recv(sockfd, (void *)buf, len, flags)
+#define qemu_sendto(sockfd, buf, len, flags, destaddr, addrlen) \
+    sendto(sockfd, (const void *)buf, len, flags, destaddr, addrlen)
 #else
 #define qemu_recv(sockfd, buf, len, flags) recv(sockfd, buf, len, flags)
+#define qemu_sendto(sockfd, buf, len, flags, destaddr, addrlen) \
+    sendto(sockfd, buf, len, flags, destaddr, addrlen)
 #endif
 
 /* Error handling.  */
commit ad11ad77748bdd8016370db210751683dc038dd6
Author: Stefan Weil <sw at weilnetz.de>
Date:   Tue Sep 4 22:14:19 2012 +0200

    linux-user: Remove redundant null check and replace free by g_free
    
    Report from smatch:
    
    linux-user/syscall.c:3632 do_ioctl_dm(220) info:
     redundant null check on big_buf calling free()
    
    'big_buf' was allocated by g_malloc0, therefore free was also
    replaced by g_free.
    
    Signed-off-by: Stefan Weil <sw at weilnetz.de>
    Reviewed-by: Peter Maydell <peter.maydell at linaro.org>
    Signed-off-by: Stefan Hajnoczi <stefanha at gmail.com>

diff --git a/linux-user/syscall.c b/linux-user/syscall.c
index 6257a04..471d060 100644
--- a/linux-user/syscall.c
+++ b/linux-user/syscall.c
@@ -3628,9 +3628,7 @@ static abi_long do_ioctl_dm(const IOCTLEntry *ie, uint8_t *buf_temp, int fd,
         unlock_user(argptr, arg, target_size);
     }
 out:
-    if (big_buf) {
-        free(big_buf);
-    }
+    g_free(big_buf);
     return ret;
 }
 
commit 144b97c26cdef7fecd62dae2db6ce312cd493751
Author: Paolo Bonzini <pbonzini at redhat.com>
Date:   Wed Sep 19 15:52:44 2012 +0200

    qemu-timer: simplify qemu_run_timers
    
    ptimer_head is an invariant pointer to clock->active_timers.
    Remove it, and just reference clock->active_timers directly.
    
    Signed-off-by: Paolo Bonzini <pbonzini at redhat.com>
    Signed-off-by: Stefan Hajnoczi <stefanha at gmail.com>

diff --git a/qemu-timer.c b/qemu-timer.c
index c7a1551..908a103 100644
--- a/qemu-timer.c
+++ b/qemu-timer.c
@@ -372,21 +372,20 @@ bool qemu_timer_expired(QEMUTimer *timer_head, int64_t current_time)
 
 void qemu_run_timers(QEMUClock *clock)
 {
-    QEMUTimer **ptimer_head, *ts;
+    QEMUTimer *ts;
     int64_t current_time;
    
     if (!clock->enabled)
         return;
 
     current_time = qemu_get_clock_ns(clock);
-    ptimer_head = &clock->active_timers;
     for(;;) {
-        ts = *ptimer_head;
+        ts = clock->active_timers;
         if (!qemu_timer_expired_ns(ts, current_time)) {
             break;
         }
         /* remove timer from the list before calling the callback */
-        *ptimer_head = ts->next;
+        clock->active_timers = ts->next;
         ts->next = NULL;
 
         /* run the callback (the timer list can be modified) */
commit c10600af60865ba6c60987be313102ebb5fcee57
Author: Laszlo Ersek <lersek at redhat.com>
Date:   Mon Sep 17 11:10:03 2012 +0200

    TextConsole: saturate escape parameter in TTY_STATE_CSI
    
    Signed-off-by: Laszlo Ersek <lersek at redhat.com>
    Reviewed-by: Markus Armbruster <armbru at redhat.com>
    Signed-off-by: Stefan Hajnoczi <stefanha at gmail.com>

diff --git a/console.c b/console.c
index a8bcc42..3f3d254 100644
--- a/console.c
+++ b/console.c
@@ -938,8 +938,11 @@ static void console_putchar(TextConsole *s, int ch)
     case TTY_STATE_CSI: /* handle escape sequence parameters */
         if (ch >= '0' && ch <= '9') {
             if (s->nb_esc_params < MAX_ESC_PARAMS) {
-                s->esc_params[s->nb_esc_params] =
-                    s->esc_params[s->nb_esc_params] * 10 + ch - '0';
+                int *param = &s->esc_params[s->nb_esc_params];
+                int digit = (ch - '0');
+
+                *param = (*param <= (INT_MAX - digit) / 10) ?
+                         *param * 10 + digit : INT_MAX;
             }
         } else {
             if (s->nb_esc_params < MAX_ESC_PARAMS)
commit 995ee2bf469de6bbe5ce133ec853392b2a4ce34c
Author: Hitoshi Mitake <h.mitake at gmail.com>
Date:   Sat Sep 15 01:15:41 2012 +0900

    curses: don't initialize curses when qemu is daemonized
    
    Current qemu initializes curses even if -daemonize option is
    passed. This cause problem because shell prompt appears without
    calling endwin().
    
    This patch adds new function, is_daemonized(), to OS dependent
    code. With this function, curses_display_init() can check that qemu is
    daemonized or not. If daemonized, curses_display_init() isn't called
    and the problem is avoided.
    
    Of course, -daemonize && -curses doesn't make sense. Users shouldn't
    pass the arguments at the same time. But the problem is very painful
    because Ctrl-C cannot be delivered to the terminal.
    
    Cc: Andrzej Zaborowski  <balrog at zabor.org>
    Cc: Stefan Hajnoczi <stefanha at gmail.com>
    Cc: Anthony Liguori <aliguori at us.ibm.com>
    Cc: Michael Roth <mdroth at linux.vnet.ibm.com>
    Signed-off-by: Hitoshi Mitake <h.mitake at gmail.com>
    Signed-off-by: Stefan Hajnoczi <stefanha at gmail.com>

diff --git a/os-posix.c b/os-posix.c
index 79fa228..eabccb8 100644
--- a/os-posix.c
+++ b/os-posix.c
@@ -360,3 +360,8 @@ int qemu_create_pidfile(const char *filename)
     /* keep pidfile open & locked forever */
     return 0;
 }
+
+bool is_daemonized(void)
+{
+    return daemonize;
+}
diff --git a/qemu-os-posix.h b/qemu-os-posix.h
index 8e1149d..7f198e4 100644
--- a/qemu-os-posix.h
+++ b/qemu-os-posix.h
@@ -46,4 +46,6 @@ typedef struct timeval qemu_timeval;
 typedef struct timespec qemu_timespec;
 int qemu_utimens(const char *path, const qemu_timespec *times);
 
+bool is_daemonized(void);
+
 #endif
diff --git a/qemu-os-win32.h b/qemu-os-win32.h
index 753679b..b3e451b 100644
--- a/qemu-os-win32.h
+++ b/qemu-os-win32.h
@@ -86,4 +86,9 @@ typedef struct {
 } qemu_timeval;
 int qemu_gettimeofday(qemu_timeval *tp);
 
+static inline bool is_daemonized(void)
+{
+    return false;
+}
+
 #endif
diff --git a/vl.c b/vl.c
index 7c577fa..48049ef 100644
--- a/vl.c
+++ b/vl.c
@@ -3657,7 +3657,9 @@ int main(int argc, char **argv, char **envp)
         break;
 #if defined(CONFIG_CURSES)
     case DT_CURSES:
-        curses_display_init(ds, full_screen);
+        if (!is_daemonized()) {
+            curses_display_init(ds, full_screen);
+        }
         break;
 #endif
 #if defined(CONFIG_SDL)
commit d8f8a860f2403533fc73f541122c65a34b21e42f
Author: Alon Levy <alevy at redhat.com>
Date:   Sun Sep 2 02:04:16 2012 +0300

    dtrace backend: add function to reserved words
    
    Signed-off-by: Alon Levy <alevy at redhat.com>
    Signed-off-by: Stefan Hajnoczi <stefanha at gmail.com>

diff --git a/scripts/tracetool/backend/dtrace.py b/scripts/tracetool/backend/dtrace.py
index 9cab75c..6be7047 100644
--- a/scripts/tracetool/backend/dtrace.py
+++ b/scripts/tracetool/backend/dtrace.py
@@ -87,7 +87,7 @@ def stap(events):
         if len(e.args) > 0:
             for name in e.args.names():
                 # Append underscore to reserved keywords
-                if name in ('limit', 'in', 'next', 'self'):
+                if name in ('limit', 'in', 'next', 'self', 'function'):
                     name += '_'
                 out('  %s = $arg%d;' % (name, i))
                 i += 1
commit 12dabc79f976d66755025272f7e2e8e4da31715a
Author: Stefan Weil <sw at weilnetz.de>
Date:   Sat Sep 1 13:00:48 2012 +0200

    pflash_cfi01: Fix warning caused by unreachable code
    
    Report from smatch:
    hw/pflash_cfi01.c:431 pflash_write(180) info: ignoring unreachable code.
    
    Instead of removing the return statement after the switch statement,
    the patch replaces the return statements in the switch statement by
    break statements. Other switch statements in the same code do it also
    like that.
    
    Signed-off-by: Stefan Weil <sw at weilnetz.de>
    Signed-off-by: Stefan Hajnoczi <stefanha at gmail.com>

diff --git a/hw/pflash_cfi01.c b/hw/pflash_cfi01.c
index 9c42d31..855890d 100644
--- a/hw/pflash_cfi01.c
+++ b/hw/pflash_cfi01.c
@@ -321,7 +321,7 @@ static void pflash_write(pflash_t *pfl, target_phys_addr_t offset,
         }
         pfl->wcycle++;
         pfl->cmd = cmd;
-        return;
+        break;
     case 1:
         switch (pfl->cmd) {
         case 0x10: /* Single Byte Program */
@@ -376,7 +376,7 @@ static void pflash_write(pflash_t *pfl, target_phys_addr_t offset,
         default:
             goto error_flash;
         }
-        return;
+        break;
     case 2:
         switch (pfl->cmd) {
         case 0xe8: /* Block write */
@@ -407,7 +407,7 @@ static void pflash_write(pflash_t *pfl, target_phys_addr_t offset,
         default:
             goto error_flash;
         }
-        return;
+        break;
     case 3: /* Confirm mode */
         switch (pfl->cmd) {
         case 0xe8: /* Block write */
@@ -423,7 +423,7 @@ static void pflash_write(pflash_t *pfl, target_phys_addr_t offset,
         default:
             goto error_flash;
         }
-        return;
+        break;
     default:
         /* Should never happen */
         DPRINTF("%s: invalid write state\n",  __func__);
commit 997f15672a5ca7714cf310d92f475d2c5fe40970
Author: Stefan Weil <sw at weilnetz.de>
Date:   Sat Sep 1 12:56:03 2012 +0200

    ioh3420: Remove unreachable code
    
    Report from smatch:
    hw/ioh3420.c:128 ioh3420_initfn(35) info: ignoring unreachable code.
    
    Signed-off-by: Stefan Weil <sw at weilnetz.de>
    Reviewed-by: Juan Quintela <quintela at redhat.com>
    Signed-off-by: Stefan Hajnoczi <stefanha at gmail.com>

diff --git a/hw/ioh3420.c b/hw/ioh3420.c
index 94a537c..4d31473 100644
--- a/hw/ioh3420.c
+++ b/hw/ioh3420.c
@@ -125,7 +125,6 @@ static int ioh3420_initfn(PCIDevice *d)
     rc = pcie_chassis_add_slot(s);
     if (rc < 0) {
         goto err_pcie_cap;
-        return rc;
     }
     pcie_cap_root_init(d);
     rc = pcie_aer_init(d, IOH_EP_AER_OFFSET);
commit 8139626643cbe8dc07bd9acc88057effeedf8064
Author: Stefan Weil <sw at weilnetz.de>
Date:   Sat Sep 1 12:43:41 2012 +0200

    lm4549: Fix buffer overflow
    
    Report from smatch:
    lm4549.c:234 lm4549_write_samples(14) error:
     buffer overflow 's->buffer' 1024 <= 1024
    
    There must be enough space to add two entries starting with index
    s->buffer_level, therefore the old check was wrong.
    
    [Peter Maydell <peter.maydell at linaro.org> clarifies the nature of the
    analyser warning:
    
    I don't object to making the change to placate the analyser,
    but I don't think this is actually a buffer overrun. We always
    add and remove samples from the buffer two at a time, so it's
    not possible to get here with s->buffer_level == BUFFER_SIZE-1
    (which is the only case where the old and new conditions
    give different answers).]
    
    Signed-off-by: Stefan Weil <sw at weilnetz.de>
    Signed-off-by: Stefan Hajnoczi <stefanha at gmail.com>

diff --git a/hw/lm4549.c b/hw/lm4549.c
index 80b3ec4..e0137d5 100644
--- a/hw/lm4549.c
+++ b/hw/lm4549.c
@@ -224,7 +224,7 @@ uint32_t lm4549_write_samples(lm4549_state *s, uint32_t left, uint32_t right)
        This model supports 16-bit playback.
     */
 
-    if (s->buffer_level >= LM4549_BUFFER_SIZE) {
+    if (s->buffer_level > LM4549_BUFFER_SIZE - 2) {
         DPRINTF("write_sample Buffer full\n");
         return 0;
     }
commit 5d40097fc09fe5d34cf316a411dc27d455ac2cd0
Author: Stefan Weil <sw at weilnetz.de>
Date:   Sat Sep 1 11:12:23 2012 +0200

    cadence_uart: Fix buffer overflow
    
    Report from smatch:
    hw/cadence_uart.c:413 uart_read(13) error: buffer overflow 's->r' 18 <= 18
    
    This fixes read access to s->r[R_MAX] which is behind the limits of s->r.
    
    Signed-off-by: Stefan Weil <sw at weilnetz.de>
    Signed-off-by: Stefan Hajnoczi <stefanha at gmail.com>

diff --git a/hw/cadence_uart.c b/hw/cadence_uart.c
index d98e531..f8afc4e 100644
--- a/hw/cadence_uart.c
+++ b/hw/cadence_uart.c
@@ -404,7 +404,7 @@ static uint64_t uart_read(void *opaque, target_phys_addr_t offset,
     uint32_t c = 0;
 
     offset >>= 2;
-    if (offset > R_MAX) {
+    if (offset >= R_MAX) {
         return 0;
     } else if (offset == R_TX_RX) {
         uart_read_rx_fifo(s, &c);
commit 39b384591fda27d6e1213cea0b11b1ebe0ed4b74
Author: Stefan Weil <sw at weilnetz.de>
Date:   Sat Sep 1 09:40:26 2012 +0200

    qemu-sockets: Fix potential memory leak
    
    The old code leaks variable 'peer'.
    
    Signed-off-by: Stefan Weil <sw at weilnetz.de>
    Signed-off-by: Stefan Hajnoczi <stefanha at gmail.com>

diff --git a/qemu-sockets.c b/qemu-sockets.c
index 361d890..037775b 100644
--- a/qemu-sockets.c
+++ b/qemu-sockets.c
@@ -353,7 +353,7 @@ int inet_dgram_opts(QemuOpts *opts)
     if (0 != (rc = getaddrinfo(addr, port, &ai, &local))) {
         fprintf(stderr,"getaddrinfo(%s,%s): %s\n", addr, port,
                 gai_strerror(rc));
-        return -1;
+        goto err;
     }
 
     /* create socket */
commit b548828862d3bf7214b7ef9cb361356b153b89c9
Author: Stefan Weil <sw at weilnetz.de>
Date:   Sat Sep 1 09:34:15 2012 +0200

    qemu-ga: Remove unreachable code after g_error
    
    Report from smatch:
    qemu-ga.c:117 register_signal_handlers(11) info: ignoring unreachable code.
    qemu-ga.c:122 register_signal_handlers(16) info: ignoring unreachable code.
    
    g_error calls abort which terminates the program.
    
    Signed-off-by: Stefan Weil <sw at weilnetz.de>
    Signed-off-by: Stefan Hajnoczi <stefanha at gmail.com>

diff --git a/qemu-ga.c b/qemu-ga.c
index 7623079..b747470 100644
--- a/qemu-ga.c
+++ b/qemu-ga.c
@@ -114,12 +114,10 @@ static gboolean register_signal_handlers(void)
     ret = sigaction(SIGINT, &sigact, NULL);
     if (ret == -1) {
         g_error("error configuring signal handler: %s", strerror(errno));
-        return false;
     }
     ret = sigaction(SIGTERM, &sigact, NULL);
     if (ret == -1) {
         g_error("error configuring signal handler: %s", strerror(errno));
-        return false;
     }
 
     return true;
commit 2e84849aa2cc7f220d3b3668f5f7e3c57bb1b590
Author: Don Slutz <Don at CloudSwitch.com>
Date:   Fri Sep 21 20:13:13 2012 -0400

    target-i386: Allow tsc-frequency to be larger then 2.147G
    
    The check using INT_MAX (2147483647) is wrong in this case.
    
    Signed-off-by: Fred Oliveira <foliveira at cloudswitch.com>
    Signed-off-by: Don Slutz <Don at CloudSwitch.com>
    Signed-off-by: Stefan Hajnoczi <stefanha at gmail.com>

diff --git a/target-i386/cpu.c b/target-i386/cpu.c
index 423e009..cbc172e 100644
--- a/target-i386/cpu.c
+++ b/target-i386/cpu.c
@@ -846,7 +846,7 @@ static void x86_cpuid_set_tsc_freq(Object *obj, Visitor *v, void *opaque,
 {
     X86CPU *cpu = X86_CPU(obj);
     const int64_t min = 0;
-    const int64_t max = INT_MAX;
+    const int64_t max = INT64_MAX;
     int64_t value;
 
     visit_type_int(v, &value, name, errp);
commit 1109c894052751df99962c009fd7dbae397721f5
Author: Ronnie Sahlberg <ronniesahlberg at gmail.com>
Date:   Fri Sep 14 18:13:29 2012 -0700

    SCSI: Standard INQUIRY data should report HiSup flag as set.
    
    QEMU as far as I know only reports LUN numbers using the modes that
    are described in SAM4.
    As such, since all LUN numbers generated by the SCSI emulation in QEMU
    follow SAM4, we should set the HiSup bit in the standard INQUIRY data
    to indicate such.
    
    From SAM4:
      4.6.3 LUNs overview
      All LUN formats described in this standard are hierarchical in
      structure even when only a single level in that hierarchy is used.
      The HISUP bit shall be set to one in the standard INQUIRY data
      (see SPC-4) when any LUN format described in this standard is used.
      Non-hierarchical formats are outside the scope of this standard.
    
    Signed-off-by: Ronnie Sahlberg <ronniesahlberg at gmail.com>

diff --git a/hw/scsi-disk.c b/hw/scsi-disk.c
index 4ffca7a..95e9158 100644
--- a/hw/scsi-disk.c
+++ b/hw/scsi-disk.c
@@ -678,7 +678,7 @@ static int scsi_disk_emulate_inquiry(SCSIRequest *req, uint8_t *outbuf)
      * is actually implemented, but we're good enough.
      */
     outbuf[2] = 5;
-    outbuf[3] = 2; /* Format 2 */
+    outbuf[3] = 2 | 0x10; /* Format 2, HiSup */
 
     if (buflen > 36) {
         outbuf[4] = buflen - 5; /* Additional Length = (Len - 1) - 4 */
commit e93176d55f1eb4be1a366b51afeaf4f4c8c31d75
Author: Paolo Bonzini <pbonzini at redhat.com>
Date:   Wed Sep 5 18:00:57 2012 +0200

    scsi-disk: use scsi_data_cdb_length
    
    This simplifies and unifies the parsing of READ, WRITE and WRITE SAME
    commands.
    
    Signed-off-by: Paolo Bonzini <pbonzini at redhat.com>

diff --git a/hw/scsi-disk.c b/hw/scsi-disk.c
index d621852..4ffca7a 100644
--- a/hw/scsi-disk.c
+++ b/hw/scsi-disk.c
@@ -1808,11 +1808,8 @@ static int32_t scsi_disk_emulate_command(SCSIRequest *req, uint8_t *buf)
         DPRINTF("Unmap (len %lu)\n", (long)r->req.cmd.xfer);
         break;
     case WRITE_SAME_10:
-        nb_sectors = lduw_be_p(&req->cmd.buf[7]);
-        goto write_same;
     case WRITE_SAME_16:
-        nb_sectors = ldl_be_p(&req->cmd.buf[10]) & 0xffffffffULL;
-    write_same:
+        nb_sectors = scsi_data_cdb_length(r->req.cmd.buf);
         if (bdrv_is_read_only(s->qdev.conf.bs)) {
             scsi_check_condition(r, SENSE_CODE(WRITE_PROTECTED));
             return 0;
@@ -1872,7 +1869,7 @@ static int32_t scsi_disk_dma_command(SCSIRequest *req, uint8_t *buf)
 {
     SCSIDiskReq *r = DO_UPCAST(SCSIDiskReq, req, req);
     SCSIDiskState *s = DO_UPCAST(SCSIDiskState, qdev, req->dev);
-    int32_t len;
+    uint32_t len;
     uint8_t command;
 
     command = buf[0];
@@ -1882,13 +1879,13 @@ static int32_t scsi_disk_dma_command(SCSIRequest *req, uint8_t *buf)
         return 0;
     }
 
+    len = scsi_data_cdb_length(r->req.cmd.buf);
     switch (command) {
     case READ_6:
     case READ_10:
     case READ_12:
     case READ_16:
-        len = r->req.cmd.xfer / s->qdev.blocksize;
-        DPRINTF("Read (sector %" PRId64 ", count %d)\n", r->req.cmd.lba, len);
+        DPRINTF("Read (sector %" PRId64 ", count %u)\n", r->req.cmd.lba, len);
         if (r->req.cmd.buf[1] & 0xe0) {
             goto illegal_request;
         }
@@ -1913,8 +1910,7 @@ static int32_t scsi_disk_dma_command(SCSIRequest *req, uint8_t *buf)
     case VERIFY_10:
     case VERIFY_12:
     case VERIFY_16:
-        len = r->req.cmd.xfer / s->qdev.blocksize;
-        DPRINTF("Write %s(sector %" PRId64 ", count %d)\n",
+        DPRINTF("Write %s(sector %" PRId64 ", count %u)\n",
                 (command & 0xe) == 0xe ? "And Verify " : "",
                 r->req.cmd.lba, len);
         if (r->req.cmd.buf[1] & 0xe0) {
commit bb729f758195a36db1dd0d5c01ec983e466729eb
Author: Paolo Bonzini <pbonzini at redhat.com>
Date:   Wed Sep 5 17:57:19 2012 +0200

    scsi: introduce scsi_cdb_length and scsi_data_cdb_length
    
    Signed-off-by: Paolo Bonzini <pbonzini at redhat.com>

diff --git a/hw/scsi-bus.c b/hw/scsi-bus.c
index 4981a02..058d3b2 100644
--- a/hw/scsi-bus.c
+++ b/hw/scsi-bus.c
@@ -801,26 +801,39 @@ static int ata_passthrough_16_xfer_size(SCSIDevice *dev, uint8_t *buf)
     return xfer * unit;
 }
 
-static int scsi_req_length(SCSICommand *cmd, SCSIDevice *dev, uint8_t *buf)
+uint32_t scsi_data_cdb_length(uint8_t *buf)
+{
+    if ((buf[0] >> 5) == 0 && buf[4] == 0) {
+        return 256;
+    } else {
+        return scsi_cdb_length(buf);
+    }
+}
+
+uint32_t scsi_cdb_length(uint8_t *buf)
 {
     switch (buf[0] >> 5) {
     case 0:
-        cmd->xfer = buf[4];
+        return buf[4];
         break;
     case 1:
     case 2:
-        cmd->xfer = lduw_be_p(&buf[7]);
+        return lduw_be_p(&buf[7]);
         break;
     case 4:
-        cmd->xfer = ldl_be_p(&buf[10]) & 0xffffffffULL;
+        return ldl_be_p(&buf[10]) & 0xffffffffULL;
         break;
     case 5:
-        cmd->xfer = ldl_be_p(&buf[6]) & 0xffffffffULL;
+        return ldl_be_p(&buf[6]) & 0xffffffffULL;
         break;
     default:
         return -1;
     }
+}
 
+static int scsi_req_length(SCSICommand *cmd, SCSIDevice *dev, uint8_t *buf)
+{
+    cmd->xfer = scsi_cdb_length(buf);
     switch (buf[0]) {
     case TEST_UNIT_READY:
     case REWIND:
diff --git a/hw/scsi.h b/hw/scsi.h
index 1aeee46..b8f7357 100644
--- a/hw/scsi.h
+++ b/hw/scsi.h
@@ -218,6 +218,8 @@ extern const struct SCSISense sense_code_WRITE_PROTECTED;
 
 #define SENSE_CODE(x) sense_code_ ## x
 
+uint32_t scsi_data_cdb_length(uint8_t *buf);
+uint32_t scsi_cdb_length(uint8_t *buf);
 int scsi_sense_valid(SCSISense sense);
 int scsi_build_sense(uint8_t *in_buf, int in_len,
                      uint8_t *buf, int len, bool fixed);
commit 12ca76fc48081b3a0ad1a70546abfcf198aedfc4
Author: Paolo Bonzini <pbonzini at redhat.com>
Date:   Wed Sep 5 17:54:36 2012 +0200

    scsi-disk: fix check for out-of-range LBA
    
    This fix is needed to correctly handle 0-block read and writes.
    Without it, a 0-block access at LBA 0 would underflow.
    
    Signed-off-by: Paolo Bonzini <pbonzini at redhat.com>

diff --git a/hw/scsi-disk.c b/hw/scsi-disk.c
index 3959603..d621852 100644
--- a/hw/scsi-disk.c
+++ b/hw/scsi-disk.c
@@ -1456,9 +1456,13 @@ static inline bool check_lba_range(SCSIDiskState *s,
      * The first line tests that no overflow happens when computing the last
      * sector.  The second line tests that the last accessed sector is in
      * range.
+     *
+     * Careful, the computations should not underflow for nb_sectors == 0,
+     * and a 0-block read to the first LBA beyond the end of device is
+     * valid.
      */
     return (sector_num <= sector_num + nb_sectors &&
-            sector_num + nb_sectors - 1 <= s->qdev.max_lba);
+            sector_num + nb_sectors <= s->qdev.max_lba + 1);
 }
 
 typedef struct UnmapCBData {
commit 444bc908611ccaf4512dc37c33ac3b54d873a62b
Author: Paolo Bonzini <pbonzini at redhat.com>
Date:   Wed Sep 5 17:46:18 2012 +0200

    scsi-disk: introduce check_lba_range
    
    Abstract the test for an out-of-range (starting block, block count)
    pair.
    
    Signed-off-by: Paolo Bonzini <pbonzini at redhat.com>

diff --git a/hw/scsi-disk.c b/hw/scsi-disk.c
index 1585683..3959603 100644
--- a/hw/scsi-disk.c
+++ b/hw/scsi-disk.c
@@ -1449,6 +1449,18 @@ invalid_field:
     return;
 }
 
+static inline bool check_lba_range(SCSIDiskState *s,
+                                   uint64_t sector_num, uint32_t nb_sectors)
+{
+    /*
+     * The first line tests that no overflow happens when computing the last
+     * sector.  The second line tests that the last accessed sector is in
+     * range.
+     */
+    return (sector_num <= sector_num + nb_sectors &&
+            sector_num + nb_sectors - 1 <= s->qdev.max_lba);
+}
+
 typedef struct UnmapCBData {
     SCSIDiskReq *r;
     uint8_t *inbuf;
@@ -1473,8 +1485,7 @@ static void scsi_unmap_complete(void *opaque, int ret)
     if (data->count > 0 && !r->req.io_canceled) {
         sector_num = ldq_be_p(&data->inbuf[0]);
         nb_sectors = ldl_be_p(&data->inbuf[8]) & 0xffffffffULL;
-        if (sector_num > sector_num + nb_sectors ||
-            sector_num + nb_sectors - 1 > s->qdev.max_lba) {
+        if (!check_lba_range(s, sector_num, nb_sectors)) {
             scsi_check_condition(r, SENSE_CODE(LBA_OUT_OF_RANGE));
             goto done;
         }
@@ -1802,8 +1813,7 @@ static int32_t scsi_disk_emulate_command(SCSIRequest *req, uint8_t *buf)
             scsi_check_condition(r, SENSE_CODE(WRITE_PROTECTED));
             return 0;
         }
-        if (r->req.cmd.lba > r->req.cmd.lba + nb_sectors ||
-            r->req.cmd.lba + nb_sectors - 1 > s->qdev.max_lba) {
+        if (!check_lba_range(s, r->req.cmd.lba, nb_sectors)) {
             goto illegal_lba;
         }
 
@@ -1878,8 +1888,7 @@ static int32_t scsi_disk_dma_command(SCSIRequest *req, uint8_t *buf)
         if (r->req.cmd.buf[1] & 0xe0) {
             goto illegal_request;
         }
-        if (r->req.cmd.lba > r->req.cmd.lba + len ||
-            r->req.cmd.lba + len - 1 > s->qdev.max_lba) {
+        if (!check_lba_range(s, r->req.cmd.lba, len)) {
             goto illegal_lba;
         }
         r->sector = r->req.cmd.lba * (s->qdev.blocksize / 512);
@@ -1907,8 +1916,7 @@ static int32_t scsi_disk_dma_command(SCSIRequest *req, uint8_t *buf)
         if (r->req.cmd.buf[1] & 0xe0) {
             goto illegal_request;
         }
-        if (r->req.cmd.lba > r->req.cmd.lba + len ||
-            r->req.cmd.lba + len - 1 > s->qdev.max_lba) {
+        if (!check_lba_range(s, r->req.cmd.lba, len)) {
             goto illegal_lba;
         }
         r->sector = r->req.cmd.lba * (s->qdev.blocksize / 512);
commit 40a13ca8d28c21062e35b10d9b80e76b92405bdf
Author: Ronnie Sahlberg <ronniesahlberg at gmail.com>
Date:   Thu Aug 30 16:56:36 2012 -0700

    iSCSI: We dont need to explicitely call qemu_notify_event() any more
    
    We no longer need to explicitely call qemu_notify_event() any more
    since this is now done automatically any time the filehandles we listen
    to change.
    
    Signed-off-by: Ronnie Sahlberg <ronniesahlberg at gmail.com>
    Signed-off-by: Paolo Bonzini <pbonzini at redhat.com>

diff --git a/block/iscsi.c b/block/iscsi.c
index ea16609..fb001b9 100644
--- a/block/iscsi.c
+++ b/block/iscsi.c
@@ -167,12 +167,6 @@ iscsi_set_events(IscsiLun *iscsilun)
 
     }
 
-    /* If we just added an event, the callback might be delayed
-     * unless we call qemu_notify_event().
-     */
-    if (ev & ~iscsilun->events) {
-        qemu_notify_event();
-    }
     iscsilun->events = ev;
 }
 
commit f1a12821d7df2e4d21be4f2206f84b4640533e53
Author: Ronnie Sahlberg <ronniesahlberg at gmail.com>
Date:   Thu Aug 30 17:28:40 2012 -0700

    iSCSI: We need to support SG_IO also from iscsi_ioctl()
    
    We need to support SG_IO from the synchronous iscsi_ioctl() since
    scsi-block uses this to do an INQ to the device to discover its properties
    This patch makes scsi-block work with iscsi.
    
    Signed-off-by: Ronnie Sahlberg <ronniesahlberg at gmail.com>
    Signed-off-by: Paolo Bonzini <pbonzini at redhat.com>

diff --git a/block/iscsi.c b/block/iscsi.c
index 0b96165..ea16609 100644
--- a/block/iscsi.c
+++ b/block/iscsi.c
@@ -628,9 +628,17 @@ static BlockDriverAIOCB *iscsi_aio_ioctl(BlockDriverState *bs,
     return &acb->common;
 }
 
+
+static void ioctl_cb(void *opaque, int status)
+{
+    int *p_status = opaque;
+    *p_status = status;
+}
+
 static int iscsi_ioctl(BlockDriverState *bs, unsigned long int req, void *buf)
 {
     IscsiLun *iscsilun = bs->opaque;
+    int status;
 
     switch (req) {
     case SG_GET_VERSION_NUM:
@@ -639,6 +647,15 @@ static int iscsi_ioctl(BlockDriverState *bs, unsigned long int req, void *buf)
     case SG_GET_SCSI_ID:
         ((struct sg_scsi_id *)buf)->scsi_type = iscsilun->type;
         break;
+    case SG_IO:
+        status = -EINPROGRESS;
+        iscsi_aio_ioctl(bs, req, buf, ioctl_cb, &status);
+
+        while (status == -EINPROGRESS) {
+            qemu_aio_wait();
+        }
+
+        return 0;
     default:
         return -1;
     }
commit 2b85cf0efd81a6190320e7b488a0a4bad9743cc3
Author: Richard Henderson <rth at twiddle.net>
Date:   Fri Sep 21 14:15:36 2012 +0200

    target-alpha: Initialize env->cpu_model_str
    
    Save the cpu_model_str so that we have a non-null value when
    creating a new cpu during clone.
    
    Signed-off-by: Richard Henderson <rth at twiddle.net>
    Signed-off-by: Andreas Färber <afaerber at suse.de>

diff --git a/target-alpha/translate.c b/target-alpha/translate.c
index 12de6a3..93063fb 100644
--- a/target-alpha/translate.c
+++ b/target-alpha/translate.c
@@ -3549,6 +3549,7 @@ CPUAlphaState * cpu_alpha_init (const char *cpu_model)
     }
     env->implver = implver;
     env->amask = amask;
+    env->cpu_model_str = cpu_model;
 
     qemu_init_vcpu(env);
     return env;
commit 473955e5c3bce09c007ba3b64937cfca6f18f525
Author: Andreas Färber <afaerber at suse.de>
Date:   Mon Sep 17 19:02:13 2012 +0200

    target-i386: Drop unused setscalar() macro
    
    It was only used by now removed setfeatures() function.
    
    Suggested-by: Igor Mammedov <imammedo at redhat.com>
    Signed-off-by: Andreas Färber <afaerber at suse.de>

diff --git a/target-i386/cpu.c b/target-i386/cpu.c
index 7c0953f..c2e65ea 100644
--- a/target-i386/cpu.c
+++ b/target-i386/cpu.c
@@ -1393,18 +1393,6 @@ int cpu_x86_register(X86CPU *cpu, const char *cpu_model)
 
 #if !defined(CONFIG_USER_ONLY)
 
-/* interpret radix and convert from string to arbitrary scalar,
- * otherwise flag failure
- */
-#define setscalar(pval, str, perr)                      \
-{                                                       \
-    char *pend;                                         \
-    unsigned long ul;                                   \
-                                                        \
-    ul = strtoul(str, &pend, 0);                        \
-    *str && !*pend ? (*pval = ul) : (*perr = 1);        \
-}
-
 void cpu_clear_apic_feature(CPUX86State *env)
 {
     env->cpuid_features &= ~CPUID_APIC;
commit c04321b3685a0b06d737d04146a0f1f2c5950b39
Author: Eduardo Habkost <ehabkost at redhat.com>
Date:   Wed Sep 5 17:41:13 2012 -0300

    target-i386: Kill cpudef config section support
    
    It's nice to have a flexible system to maintain CPU models as data, but
    this is holding us from making improvements in the CPU code because it's
    not using the common infra-structure, and because the machine-type data
    is still inside C code.
    
    Users who want to configure CPU features directly may simply use the
    "-cpu" command-line option (and maybe an equivalent -device option in
    the future) to set CPU features.
    
    Signed-off-by: Eduardo Habkost <ehabkost at redhat.com>
    Signed-off-by: Andreas Färber <afaerber at suse.de>

diff --git a/target-i386/cpu.c b/target-i386/cpu.c
index e13e6d5..7c0953f 100644
--- a/target-i386/cpu.c
+++ b/target-i386/cpu.c
@@ -240,7 +240,6 @@ typedef struct x86_def_t {
     uint32_t xlevel;
     char model_id[48];
     int vendor_override;
-    uint32_t flags;
     /* Store the results of Centaur's CPUID instructions */
     uint32_t ext4_features;
     uint32_t xlevel2;
@@ -1299,7 +1298,7 @@ void x86_cpu_list(FILE *f, fprintf_function cpu_fprintf)
     char buf[256];
 
     for (def = x86_defs; def; def = def->next) {
-        snprintf(buf, sizeof (buf), def->flags ? "[%s]": "%s", def->name);
+        snprintf(buf, sizeof(buf), "%s", def->name);
         (*cpu_fprintf)(f, "x86 %16s  %-48s\n", buf, def->model_id);
     }
     if (kvm_enabled()) {
@@ -1393,16 +1392,6 @@ int cpu_x86_register(X86CPU *cpu, const char *cpu_model)
 }
 
 #if !defined(CONFIG_USER_ONLY)
-/* copy vendor id string to 32 bit register, nul pad as needed
- */
-static void cpyid(const char *s, uint32_t *id)
-{
-    char *d = (char *)id;
-    char i;
-
-    for (i = sizeof (*id); i--; )
-        *d++ = *s ? *s++ : '\0';
-}
 
 /* interpret radix and convert from string to arbitrary scalar,
  * otherwise flag failure
@@ -1416,87 +1405,6 @@ static void cpyid(const char *s, uint32_t *id)
     *str && !*pend ? (*pval = ul) : (*perr = 1);        \
 }
 
-/* map cpuid options to feature bits, otherwise return failure
- * (option tags in *str are delimited by whitespace)
- */
-static void setfeatures(uint32_t *pval, const char *str,
-    const char **featureset, int *perr)
-{
-    const char *p, *q;
-
-    for (q = p = str; *p || *q; q = p) {
-        while (iswhite(*p))
-            q = ++p;
-        while (*p && !iswhite(*p))
-            ++p;
-        if (!*q && !*p)
-            return;
-        if (!lookup_feature(pval, q, p, featureset)) {
-            fprintf(stderr, "error: feature \"%.*s\" not available in set\n",
-                (int)(p - q), q);
-            *perr = 1;
-            return;
-        }
-    }
-}
-
-/* map config file options to x86_def_t form
- */
-static int cpudef_setfield(const char *name, const char *str, void *opaque)
-{
-    x86_def_t *def = opaque;
-    int err = 0;
-
-    if (!strcmp(name, "name")) {
-        g_free((void *)def->name);
-        def->name = g_strdup(str);
-    } else if (!strcmp(name, "model_id")) {
-        strncpy(def->model_id, str, sizeof (def->model_id));
-    } else if (!strcmp(name, "level")) {
-        setscalar(&def->level, str, &err)
-    } else if (!strcmp(name, "vendor")) {
-        cpyid(&str[0], &def->vendor1);
-        cpyid(&str[4], &def->vendor2);
-        cpyid(&str[8], &def->vendor3);
-    } else if (!strcmp(name, "family")) {
-        setscalar(&def->family, str, &err)
-    } else if (!strcmp(name, "model")) {
-        setscalar(&def->model, str, &err)
-    } else if (!strcmp(name, "stepping")) {
-        setscalar(&def->stepping, str, &err)
-    } else if (!strcmp(name, "feature_edx")) {
-        setfeatures(&def->features, str, feature_name, &err);
-    } else if (!strcmp(name, "feature_ecx")) {
-        setfeatures(&def->ext_features, str, ext_feature_name, &err);
-    } else if (!strcmp(name, "extfeature_edx")) {
-        setfeatures(&def->ext2_features, str, ext2_feature_name, &err);
-    } else if (!strcmp(name, "extfeature_ecx")) {
-        setfeatures(&def->ext3_features, str, ext3_feature_name, &err);
-    } else if (!strcmp(name, "xlevel")) {
-        setscalar(&def->xlevel, str, &err)
-    } else {
-        fprintf(stderr, "error: unknown option [%s = %s]\n", name, str);
-        return (1);
-    }
-    if (err) {
-        fprintf(stderr, "error: bad option value [%s = %s]\n", name, str);
-        return (1);
-    }
-    return (0);
-}
-
-/* register config file entry as x86_def_t
- */
-static int cpudef_register(QemuOpts *opts, void *opaque)
-{
-    x86_def_t *def = g_malloc0(sizeof (x86_def_t));
-
-    qemu_opt_foreach(opts, cpudef_setfield, def, 1);
-    def->next = x86_defs;
-    x86_defs = def;
-    return (0);
-}
-
 void cpu_clear_apic_feature(CPUX86State *env)
 {
     env->cpuid_features &= ~CPUID_APIC;
@@ -1504,8 +1412,7 @@ void cpu_clear_apic_feature(CPUX86State *env)
 
 #endif /* !CONFIG_USER_ONLY */
 
-/* register "cpudef" models defined in configuration file.  Here we first
- * preload any built-in definitions
+/* Initialize list of CPU models, filling some non-static fields if necessary
  */
 void x86_cpudef_setup(void)
 {
@@ -1515,7 +1422,6 @@ void x86_cpudef_setup(void)
     for (i = 0; i < ARRAY_SIZE(builtin_x86_defs); ++i) {
         x86_def_t *def = &builtin_x86_defs[i];
         def->next = x86_defs;
-        def->flags = 1;
 
         /* Look for specific "cpudef" models that */
         /* have the QEMU version in .model_id */
@@ -1531,9 +1437,6 @@ void x86_cpudef_setup(void)
 
         x86_defs = def;
     }
-#if !defined(CONFIG_USER_ONLY)
-    qemu_opts_foreach(qemu_find_opts("cpudef"), cpudef_register, NULL, 0);
-#endif
 }
 
 static void get_cpuid_vendor(CPUX86State *env, uint32_t *ebx,
commit bc3e1291ddcbc0f6548886a321c98227fa710173
Author: Eduardo Habkost <ehabkost at redhat.com>
Date:   Wed Sep 5 17:41:12 2012 -0300

    target-i386: x86_cpudef_setup() coding style change
    
    Make source code lines shorter.
    
    Signed-off-by: Eduardo Habkost <ehabkost at redhat.com>
    Reviewed-by: Don Slutz <Don at CloudSwitch.com>
    Signed-off-by: Andreas Färber <afaerber at suse.de>

diff --git a/target-i386/cpu.c b/target-i386/cpu.c
index 73302d8..e13e6d5 100644
--- a/target-i386/cpu.c
+++ b/target-i386/cpu.c
@@ -1513,20 +1513,23 @@ void x86_cpudef_setup(void)
     static const char *model_with_versions[] = { "qemu32", "qemu64", "athlon" };
 
     for (i = 0; i < ARRAY_SIZE(builtin_x86_defs); ++i) {
-        builtin_x86_defs[i].next = x86_defs;
-        builtin_x86_defs[i].flags = 1;
+        x86_def_t *def = &builtin_x86_defs[i];
+        def->next = x86_defs;
+        def->flags = 1;
 
         /* Look for specific "cpudef" models that */
         /* have the QEMU version in .model_id */
         for (j = 0; j < ARRAY_SIZE(model_with_versions); j++) {
-            if (strcmp(model_with_versions[j], builtin_x86_defs[i].name) == 0) {
-                pstrcpy(builtin_x86_defs[i].model_id, sizeof(builtin_x86_defs[i].model_id), "QEMU Virtual CPU version ");
-                pstrcat(builtin_x86_defs[i].model_id, sizeof(builtin_x86_defs[i].model_id), qemu_get_version());
+            if (strcmp(model_with_versions[j], def->name) == 0) {
+                pstrcpy(def->model_id, sizeof(def->model_id),
+                        "QEMU Virtual CPU version ");
+                pstrcat(def->model_id, sizeof(def->model_id),
+                        qemu_get_version());
                 break;
             }
         }
 
-        x86_defs = &builtin_x86_defs[i];
+        x86_defs = def;
     }
 #if !defined(CONFIG_USER_ONLY)
     qemu_opts_foreach(qemu_find_opts("cpudef"), cpudef_register, NULL, 0);
commit ba6212d8a809b89151a9d76b452b814836474029
Author: Eduardo Habkost <ehabkost at redhat.com>
Date:   Wed Sep 5 17:41:11 2012 -0300

    Eliminate cpus-x86_64.conf file
    
    This file is not needed anymore, as QEMU won't ship any config-based
    cpudefs out of the box, relying only on the builtin CPU models.
    
    Signed-off-by: Eduardo Habkost <ehabkost at redhat.com>
    Reviewed-by: Igor Mammedov <imammedo at redhat.com>
    Signed-off-by: Andreas Färber <afaerber at suse.de>

diff --git a/Makefile b/Makefile
index 971e92f..def2ae2 100644
--- a/Makefile
+++ b/Makefile
@@ -298,7 +298,6 @@ install-confdir:
 
 install-sysconfig: install-datadir install-confdir
 	$(INSTALL_DATA) $(SRC_PATH)/sysconfigs/target/target-x86_64.conf "$(DESTDIR)$(qemu_confdir)"
-	$(INSTALL_DATA) $(SRC_PATH)/sysconfigs/target/cpus-x86_64.conf "$(DESTDIR)$(qemu_datadir)"
 
 install: all $(if $(BUILD_DOCS),install-doc) install-sysconfig install-datadir
 	$(INSTALL_DIR) "$(DESTDIR)$(bindir)"
diff --git a/arch_init.c b/arch_init.c
index f849f9b..9904f95 100644
--- a/arch_init.c
+++ b/arch_init.c
@@ -136,7 +136,6 @@ static struct defconfig_file {
     /* Indicates it is an user config file (disabled by -no-user-config) */
     bool userconfig;
 } default_config_files[] = {
-    { CONFIG_QEMU_DATADIR "/cpus-" TARGET_ARCH ".conf",  false },
     { CONFIG_QEMU_CONFDIR "/qemu.conf",                   true },
     { CONFIG_QEMU_CONFDIR "/target-" TARGET_ARCH ".conf", true },
     { NULL }, /* end of list */
diff --git a/sysconfigs/target/cpus-x86_64.conf b/sysconfigs/target/cpus-x86_64.conf
deleted file mode 100644
index 3902189..0000000
--- a/sysconfigs/target/cpus-x86_64.conf
+++ /dev/null
@@ -1 +0,0 @@
-# The CPU models from this file are now built-in in the QEMU source code
commit 3eca46420c9f727ea5c50086d50a610f939affe5
Author: Eduardo Habkost <ehabkost at redhat.com>
Date:   Wed Sep 5 17:41:10 2012 -0300

    target-i386: Move CPU models from cpus-x86_64.conf to C
    
    Those models are maintained by QEMU and may require compatibility code
    to be added when making some changes. Keeping the data in the C source
    code should make it simpler to handle those details.
    
    Signed-off-by: Eduardo Habkost <ehabkost at redhat.com>
    Reviewed-by: Igor Mammedov <imammedo at redhat.com>
    Reviewed-by: Don Slutz <Don at CloudSwitch.com>
    Signed-off-by: Andreas Färber <afaerber at suse.de>

diff --git a/sysconfigs/target/cpus-x86_64.conf b/sysconfigs/target/cpus-x86_64.conf
index cee0ea9..3902189 100644
--- a/sysconfigs/target/cpus-x86_64.conf
+++ b/sysconfigs/target/cpus-x86_64.conf
@@ -1,128 +1 @@
-# x86 CPU MODELS
-
-[cpudef]
-   name = "Conroe"
-   level = "2"
-   vendor = "GenuineIntel"
-   family = "6"
-   model = "2"
-   stepping = "3"
-   feature_edx = "sse2 sse fxsr mmx clflush pse36 pat cmov mca pge mtrr sep apic cx8 mce pae msr tsc pse de fpu"
-   feature_ecx = "ssse3 sse3"
-   extfeature_edx = "i64 xd syscall"
-   extfeature_ecx = "lahf_lm"
-   xlevel = "0x8000000A"
-   model_id = "Intel Celeron_4x0 (Conroe/Merom Class Core 2)"
-
-[cpudef]
-   name = "Penryn"
-   level = "2"
-   vendor = "GenuineIntel"
-   family = "6"
-   model = "2"
-   stepping = "3"
-   feature_edx = "sse2 sse fxsr mmx clflush pse36 pat cmov mca pge mtrr sep apic cx8 mce pae msr tsc pse de fpu"
-   feature_ecx = "sse4.1 cx16 ssse3 sse3"
-   extfeature_edx = "i64 xd syscall"
-   extfeature_ecx = "lahf_lm"
-   xlevel = "0x8000000A"
-   model_id = "Intel Core 2 Duo P9xxx (Penryn Class Core 2)"
-
-[cpudef]
-   name = "Nehalem"
-   level = "2"
-   vendor = "GenuineIntel"
-   family = "6"
-   model = "2"
-   stepping = "3"
-   feature_edx = "sse2 sse fxsr mmx clflush pse36 pat cmov mca pge mtrr sep apic cx8 mce pae msr tsc pse de fpu"
-   feature_ecx = "popcnt sse4.2 sse4.1 cx16 ssse3 sse3"
-   extfeature_edx = "i64 syscall xd"
-   extfeature_ecx = "lahf_lm"
-   xlevel = "0x8000000A"
-   model_id = "Intel Core i7 9xx (Nehalem Class Core i7)"
-
-[cpudef]
-   name = "Westmere"
-   level = "11"
-   vendor = "GenuineIntel"
-   family = "6"
-   model = "44"
-   stepping = "1"
-   feature_edx = "sse2 sse fxsr mmx clflush pse36 pat cmov mca pge mtrr sep apic cx8 mce pae msr tsc pse de fpu"
-   feature_ecx = "aes popcnt sse4.2 sse4.1 cx16 ssse3 sse3"
-   extfeature_edx = "i64 syscall xd"
-   extfeature_ecx = "lahf_lm"
-   xlevel = "0x8000000A"
-   model_id = "Westmere E56xx/L56xx/X56xx (Nehalem-C)"
-
-[cpudef]
-   name = "SandyBridge"
-   level = "0xd"
-   vendor = "GenuineIntel"
-   family = "6"
-   model = "42"
-   stepping = "1"
-   feature_edx = " sse2 sse fxsr mmx clflush pse36 pat cmov mca pge mtrr sep apic cx8 mce pae msr tsc pse de fpu"
-   feature_ecx = "avx xsave aes tsc-deadline popcnt x2apic sse4.2 sse4.1 cx16 ssse3 pclmulqdq sse3"
-   extfeature_edx = "i64 rdtscp nx syscall "
-   extfeature_ecx = "lahf_lm"
-   xlevel = "0x8000000A"
-   model_id = "Intel Xeon E312xx (Sandy Bridge)"
-
-[cpudef]
-   name = "Opteron_G1"
-   level = "5"
-   vendor = "AuthenticAMD"
-   family = "15"
-   model = "6"
-   stepping = "1"
-   feature_edx = "sse2 sse fxsr mmx clflush pse36 pat cmov mca pge mtrr sep apic cx8 mce pae msr tsc pse de fpu"
-   feature_ecx = "sse3"
-   extfeature_edx = "lm fxsr mmx nx pse36 pat cmov mca pge mtrr syscall apic cx8 mce pae msr tsc pse de fpu"
-   extfeature_ecx = " "
-   xlevel = "0x80000008"
-   model_id = "AMD Opteron 240 (Gen 1 Class Opteron)"
-
-[cpudef]
-   name = "Opteron_G2"
-   level = "5"
-   vendor = "AuthenticAMD"
-   family = "15"
-   model = "6"
-   stepping = "1"
-   feature_edx = "sse2 sse fxsr mmx clflush pse36 pat cmov mca pge mtrr sep apic cx8 mce pae msr tsc pse de fpu"
-   feature_ecx = "cx16 sse3"
-   extfeature_edx = "lm rdtscp fxsr mmx nx pse36 pat cmov mca pge mtrr syscall apic cx8 mce pae msr tsc pse de fpu"
-   extfeature_ecx = "svm lahf_lm"
-   xlevel = "0x80000008"
-   model_id = "AMD Opteron 22xx (Gen 2 Class Opteron)"
-
-[cpudef]
-   name = "Opteron_G3"
-   level = "5"
-   vendor = "AuthenticAMD"
-   family = "15"
-   model = "6"
-   stepping = "1"
-   feature_edx = "sse2 sse fxsr mmx clflush pse36 pat cmov mca pge mtrr sep apic cx8 mce pae msr tsc pse de fpu"
-   feature_ecx = "popcnt cx16 monitor sse3"
-   extfeature_edx = "lm rdtscp fxsr mmx nx pse36 pat cmov mca pge mtrr syscall apic cx8 mce pae msr tsc pse de fpu"
-   extfeature_ecx = "misalignsse sse4a abm svm lahf_lm"
-   xlevel = "0x80000008"
-   model_id = "AMD Opteron 23xx (Gen 3 Class Opteron)"
-
-[cpudef]
-   name = "Opteron_G4"
-   level = "0xd"
-   vendor = "AuthenticAMD"
-   family = "21"
-   model = "1"
-   stepping = "2"
-   feature_edx = "sse2 sse fxsr mmx clflush pse36 pat cmov mca pge mtrr sep apic cx8 mce pae msr tsc pse de fpu"
-   feature_ecx = "avx xsave aes popcnt sse4.2 sse4.1 cx16 ssse3 pclmulqdq sse3"
-   extfeature_edx = "lm rdtscp pdpe1gb fxsr mmx nx pse36 pat cmov mca pge mtrr syscall apic cx8 mce pae msr tsc pse de fpu"
-   extfeature_ecx = " fma4 xop 3dnowprefetch misalignsse sse4a abm svm lahf_lm"
-   xlevel = "0x8000001A"
-   model_id = "AMD Opteron 62xx class CPU"
-
+# The CPU models from this file are now built-in in the QEMU source code
diff --git a/target-i386/cpu.c b/target-i386/cpu.c
index d2af0ff..73302d8 100644
--- a/target-i386/cpu.c
+++ b/target-i386/cpu.c
@@ -490,6 +490,225 @@ static x86_def_t builtin_x86_defs[] = {
         .xlevel = 0x8000000A,
         .model_id = "Intel(R) Atom(TM) CPU N270   @ 1.60GHz",
     },
+    {
+        .name = "Conroe",
+        .level = 2,
+        .vendor1 = CPUID_VENDOR_INTEL_1,
+        .vendor2 = CPUID_VENDOR_INTEL_2,
+        .vendor3 = CPUID_VENDOR_INTEL_3,
+        .family = 6,
+        .model = 2,
+        .stepping = 3,
+        .features = CPUID_SSE2 | CPUID_SSE | CPUID_FXSR | CPUID_MMX |
+             CPUID_CLFLUSH | CPUID_PSE36 | CPUID_PAT | CPUID_CMOV | CPUID_MCA |
+             CPUID_PGE | CPUID_MTRR | CPUID_SEP | CPUID_APIC | CPUID_CX8 |
+             CPUID_MCE | CPUID_PAE | CPUID_MSR | CPUID_TSC | CPUID_PSE |
+             CPUID_DE | CPUID_FP87,
+        .ext_features = CPUID_EXT_SSSE3 | CPUID_EXT_SSE3,
+        .ext2_features = CPUID_EXT2_LM | CPUID_EXT2_NX | CPUID_EXT2_SYSCALL,
+        .ext3_features = CPUID_EXT3_LAHF_LM,
+        .xlevel = 0x8000000A,
+        .model_id = "Intel Celeron_4x0 (Conroe/Merom Class Core 2)",
+    },
+    {
+        .name = "Penryn",
+        .level = 2,
+        .vendor1 = CPUID_VENDOR_INTEL_1,
+        .vendor2 = CPUID_VENDOR_INTEL_2,
+        .vendor3 = CPUID_VENDOR_INTEL_3,
+        .family = 6,
+        .model = 2,
+        .stepping = 3,
+        .features = CPUID_SSE2 | CPUID_SSE | CPUID_FXSR | CPUID_MMX |
+             CPUID_CLFLUSH | CPUID_PSE36 | CPUID_PAT | CPUID_CMOV | CPUID_MCA |
+             CPUID_PGE | CPUID_MTRR | CPUID_SEP | CPUID_APIC | CPUID_CX8 |
+             CPUID_MCE | CPUID_PAE | CPUID_MSR | CPUID_TSC | CPUID_PSE |
+             CPUID_DE | CPUID_FP87,
+        .ext_features = CPUID_EXT_SSE41 | CPUID_EXT_CX16 | CPUID_EXT_SSSE3 |
+             CPUID_EXT_SSE3,
+        .ext2_features = CPUID_EXT2_LM | CPUID_EXT2_NX | CPUID_EXT2_SYSCALL,
+        .ext3_features = CPUID_EXT3_LAHF_LM,
+        .xlevel = 0x8000000A,
+        .model_id = "Intel Core 2 Duo P9xxx (Penryn Class Core 2)",
+    },
+    {
+        .name = "Nehalem",
+        .level = 2,
+        .vendor1 = CPUID_VENDOR_INTEL_1,
+        .vendor2 = CPUID_VENDOR_INTEL_2,
+        .vendor3 = CPUID_VENDOR_INTEL_3,
+        .family = 6,
+        .model = 2,
+        .stepping = 3,
+        .features = CPUID_SSE2 | CPUID_SSE | CPUID_FXSR | CPUID_MMX |
+             CPUID_CLFLUSH | CPUID_PSE36 | CPUID_PAT | CPUID_CMOV | CPUID_MCA |
+             CPUID_PGE | CPUID_MTRR | CPUID_SEP | CPUID_APIC | CPUID_CX8 |
+             CPUID_MCE | CPUID_PAE | CPUID_MSR | CPUID_TSC | CPUID_PSE |
+             CPUID_DE | CPUID_FP87,
+        .ext_features = CPUID_EXT_POPCNT | CPUID_EXT_SSE42 | CPUID_EXT_SSE41 |
+             CPUID_EXT_CX16 | CPUID_EXT_SSSE3 | CPUID_EXT_SSE3,
+        .ext2_features = CPUID_EXT2_LM | CPUID_EXT2_SYSCALL | CPUID_EXT2_NX,
+        .ext3_features = CPUID_EXT3_LAHF_LM,
+        .xlevel = 0x8000000A,
+        .model_id = "Intel Core i7 9xx (Nehalem Class Core i7)",
+    },
+    {
+        .name = "Westmere",
+        .level = 11,
+        .vendor1 = CPUID_VENDOR_INTEL_1,
+        .vendor2 = CPUID_VENDOR_INTEL_2,
+        .vendor3 = CPUID_VENDOR_INTEL_3,
+        .family = 6,
+        .model = 44,
+        .stepping = 1,
+        .features = CPUID_SSE2 | CPUID_SSE | CPUID_FXSR | CPUID_MMX |
+             CPUID_CLFLUSH | CPUID_PSE36 | CPUID_PAT | CPUID_CMOV | CPUID_MCA |
+             CPUID_PGE | CPUID_MTRR | CPUID_SEP | CPUID_APIC | CPUID_CX8 |
+             CPUID_MCE | CPUID_PAE | CPUID_MSR | CPUID_TSC | CPUID_PSE |
+             CPUID_DE | CPUID_FP87,
+        .ext_features = CPUID_EXT_AES | CPUID_EXT_POPCNT | CPUID_EXT_SSE42 |
+             CPUID_EXT_SSE41 | CPUID_EXT_CX16 | CPUID_EXT_SSSE3 |
+             CPUID_EXT_SSE3,
+        .ext2_features = CPUID_EXT2_LM | CPUID_EXT2_SYSCALL | CPUID_EXT2_NX,
+        .ext3_features = CPUID_EXT3_LAHF_LM,
+        .xlevel = 0x8000000A,
+        .model_id = "Westmere E56xx/L56xx/X56xx (Nehalem-C)",
+    },
+    {
+        .name = "SandyBridge",
+        .level = 0xd,
+        .vendor1 = CPUID_VENDOR_INTEL_1,
+        .vendor2 = CPUID_VENDOR_INTEL_2,
+        .vendor3 = CPUID_VENDOR_INTEL_3,
+        .family = 6,
+        .model = 42,
+        .stepping = 1,
+        .features = CPUID_SSE2 | CPUID_SSE | CPUID_FXSR | CPUID_MMX |
+             CPUID_CLFLUSH | CPUID_PSE36 | CPUID_PAT | CPUID_CMOV | CPUID_MCA |
+             CPUID_PGE | CPUID_MTRR | CPUID_SEP | CPUID_APIC | CPUID_CX8 |
+             CPUID_MCE | CPUID_PAE | CPUID_MSR | CPUID_TSC | CPUID_PSE |
+             CPUID_DE | CPUID_FP87,
+        .ext_features = CPUID_EXT_AVX | CPUID_EXT_XSAVE | CPUID_EXT_AES |
+             CPUID_EXT_TSC_DEADLINE_TIMER | CPUID_EXT_POPCNT |
+             CPUID_EXT_X2APIC | CPUID_EXT_SSE42 | CPUID_EXT_SSE41 |
+             CPUID_EXT_CX16 | CPUID_EXT_SSSE3 | CPUID_EXT_PCLMULQDQ |
+             CPUID_EXT_SSE3,
+        .ext2_features = CPUID_EXT2_LM | CPUID_EXT2_RDTSCP | CPUID_EXT2_NX |
+             CPUID_EXT2_SYSCALL,
+        .ext3_features = CPUID_EXT3_LAHF_LM,
+        .xlevel = 0x8000000A,
+        .model_id = "Intel Xeon E312xx (Sandy Bridge)",
+    },
+    {
+        .name = "Opteron_G1",
+        .level = 5,
+        .vendor1 = CPUID_VENDOR_AMD_1,
+        .vendor2 = CPUID_VENDOR_AMD_2,
+        .vendor3 = CPUID_VENDOR_AMD_3,
+        .family = 15,
+        .model = 6,
+        .stepping = 1,
+        .features = CPUID_SSE2 | CPUID_SSE | CPUID_FXSR | CPUID_MMX |
+             CPUID_CLFLUSH | CPUID_PSE36 | CPUID_PAT | CPUID_CMOV | CPUID_MCA |
+             CPUID_PGE | CPUID_MTRR | CPUID_SEP | CPUID_APIC | CPUID_CX8 |
+             CPUID_MCE | CPUID_PAE | CPUID_MSR | CPUID_TSC | CPUID_PSE |
+             CPUID_DE | CPUID_FP87,
+        .ext_features = CPUID_EXT_SSE3,
+        .ext2_features = CPUID_EXT2_LM | CPUID_EXT2_FXSR | CPUID_EXT2_MMX |
+             CPUID_EXT2_NX | CPUID_EXT2_PSE36 | CPUID_EXT2_PAT |
+             CPUID_EXT2_CMOV | CPUID_EXT2_MCA | CPUID_EXT2_PGE |
+             CPUID_EXT2_MTRR | CPUID_EXT2_SYSCALL | CPUID_EXT2_APIC |
+             CPUID_EXT2_CX8 | CPUID_EXT2_MCE | CPUID_EXT2_PAE | CPUID_EXT2_MSR |
+             CPUID_EXT2_TSC | CPUID_EXT2_PSE | CPUID_EXT2_DE | CPUID_EXT2_FPU,
+        .xlevel = 0x80000008,
+        .model_id = "AMD Opteron 240 (Gen 1 Class Opteron)",
+    },
+    {
+        .name = "Opteron_G2",
+        .level = 5,
+        .vendor1 = CPUID_VENDOR_AMD_1,
+        .vendor2 = CPUID_VENDOR_AMD_2,
+        .vendor3 = CPUID_VENDOR_AMD_3,
+        .family = 15,
+        .model = 6,
+        .stepping = 1,
+        .features = CPUID_SSE2 | CPUID_SSE | CPUID_FXSR | CPUID_MMX |
+             CPUID_CLFLUSH | CPUID_PSE36 | CPUID_PAT | CPUID_CMOV | CPUID_MCA |
+             CPUID_PGE | CPUID_MTRR | CPUID_SEP | CPUID_APIC | CPUID_CX8 |
+             CPUID_MCE | CPUID_PAE | CPUID_MSR | CPUID_TSC | CPUID_PSE |
+             CPUID_DE | CPUID_FP87,
+        .ext_features = CPUID_EXT_CX16 | CPUID_EXT_SSE3,
+        .ext2_features = CPUID_EXT2_LM | CPUID_EXT2_RDTSCP | CPUID_EXT2_FXSR |
+             CPUID_EXT2_MMX | CPUID_EXT2_NX | CPUID_EXT2_PSE36 |
+             CPUID_EXT2_PAT | CPUID_EXT2_CMOV | CPUID_EXT2_MCA |
+             CPUID_EXT2_PGE | CPUID_EXT2_MTRR | CPUID_EXT2_SYSCALL |
+             CPUID_EXT2_APIC | CPUID_EXT2_CX8 | CPUID_EXT2_MCE |
+             CPUID_EXT2_PAE | CPUID_EXT2_MSR | CPUID_EXT2_TSC | CPUID_EXT2_PSE |
+             CPUID_EXT2_DE | CPUID_EXT2_FPU,
+        .ext3_features = CPUID_EXT3_SVM | CPUID_EXT3_LAHF_LM,
+        .xlevel = 0x80000008,
+        .model_id = "AMD Opteron 22xx (Gen 2 Class Opteron)",
+    },
+    {
+        .name = "Opteron_G3",
+        .level = 5,
+        .vendor1 = CPUID_VENDOR_AMD_1,
+        .vendor2 = CPUID_VENDOR_AMD_2,
+        .vendor3 = CPUID_VENDOR_AMD_3,
+        .family = 15,
+        .model = 6,
+        .stepping = 1,
+        .features = CPUID_SSE2 | CPUID_SSE | CPUID_FXSR | CPUID_MMX |
+             CPUID_CLFLUSH | CPUID_PSE36 | CPUID_PAT | CPUID_CMOV | CPUID_MCA |
+             CPUID_PGE | CPUID_MTRR | CPUID_SEP | CPUID_APIC | CPUID_CX8 |
+             CPUID_MCE | CPUID_PAE | CPUID_MSR | CPUID_TSC | CPUID_PSE |
+             CPUID_DE | CPUID_FP87,
+        .ext_features = CPUID_EXT_POPCNT | CPUID_EXT_CX16 | CPUID_EXT_MONITOR |
+             CPUID_EXT_SSE3,
+        .ext2_features = CPUID_EXT2_LM | CPUID_EXT2_RDTSCP | CPUID_EXT2_FXSR |
+             CPUID_EXT2_MMX | CPUID_EXT2_NX | CPUID_EXT2_PSE36 |
+             CPUID_EXT2_PAT | CPUID_EXT2_CMOV | CPUID_EXT2_MCA |
+             CPUID_EXT2_PGE | CPUID_EXT2_MTRR | CPUID_EXT2_SYSCALL |
+             CPUID_EXT2_APIC | CPUID_EXT2_CX8 | CPUID_EXT2_MCE |
+             CPUID_EXT2_PAE | CPUID_EXT2_MSR | CPUID_EXT2_TSC | CPUID_EXT2_PSE |
+             CPUID_EXT2_DE | CPUID_EXT2_FPU,
+        .ext3_features = CPUID_EXT3_MISALIGNSSE | CPUID_EXT3_SSE4A |
+             CPUID_EXT3_ABM | CPUID_EXT3_SVM | CPUID_EXT3_LAHF_LM,
+        .xlevel = 0x80000008,
+        .model_id = "AMD Opteron 23xx (Gen 3 Class Opteron)",
+    },
+    {
+        .name = "Opteron_G4",
+        .level = 0xd,
+        .vendor1 = CPUID_VENDOR_AMD_1,
+        .vendor2 = CPUID_VENDOR_AMD_2,
+        .vendor3 = CPUID_VENDOR_AMD_3,
+        .family = 21,
+        .model = 1,
+        .stepping = 2,
+        .features = CPUID_SSE2 | CPUID_SSE | CPUID_FXSR | CPUID_MMX |
+             CPUID_CLFLUSH | CPUID_PSE36 | CPUID_PAT | CPUID_CMOV | CPUID_MCA |
+             CPUID_PGE | CPUID_MTRR | CPUID_SEP | CPUID_APIC | CPUID_CX8 |
+             CPUID_MCE | CPUID_PAE | CPUID_MSR | CPUID_TSC | CPUID_PSE |
+             CPUID_DE | CPUID_FP87,
+        .ext_features = CPUID_EXT_AVX | CPUID_EXT_XSAVE | CPUID_EXT_AES |
+             CPUID_EXT_POPCNT | CPUID_EXT_SSE42 | CPUID_EXT_SSE41 |
+             CPUID_EXT_CX16 | CPUID_EXT_SSSE3 | CPUID_EXT_PCLMULQDQ |
+             CPUID_EXT_SSE3,
+        .ext2_features = CPUID_EXT2_LM | CPUID_EXT2_RDTSCP |
+             CPUID_EXT2_PDPE1GB | CPUID_EXT2_FXSR | CPUID_EXT2_MMX |
+             CPUID_EXT2_NX | CPUID_EXT2_PSE36 | CPUID_EXT2_PAT |
+             CPUID_EXT2_CMOV | CPUID_EXT2_MCA | CPUID_EXT2_PGE |
+             CPUID_EXT2_MTRR | CPUID_EXT2_SYSCALL | CPUID_EXT2_APIC |
+             CPUID_EXT2_CX8 | CPUID_EXT2_MCE | CPUID_EXT2_PAE | CPUID_EXT2_MSR |
+             CPUID_EXT2_TSC | CPUID_EXT2_PSE | CPUID_EXT2_DE | CPUID_EXT2_FPU,
+        .ext3_features = CPUID_EXT3_FMA4 | CPUID_EXT3_XOP |
+             CPUID_EXT3_3DNOWPREFETCH | CPUID_EXT3_MISALIGNSSE |
+             CPUID_EXT3_SSE4A | CPUID_EXT3_ABM | CPUID_EXT3_SVM |
+             CPUID_EXT3_LAHF_LM,
+        .xlevel = 0x8000001A,
+        .model_id = "AMD Opteron 62xx class CPU",
+    },
 };
 
 static int cpu_x86_fill_model_id(char *str)
commit a75b081846176b020e5f39b37a0ae197172b7838
Author: Eduardo Habkost <ehabkost at redhat.com>
Date:   Wed Sep 5 17:41:09 2012 -0300

    target-i386: Add missing CPUID_* constants
    
    Those constants will be used by new CPU model definitions.
    
    Signed-off-by: Eduardo Habkost <ehabkost at redhat.com>
    Reviewed-by: Igor Mammedov <imammedo at redhat.com>
    Signed-off-by: Andreas Färber <afaerber at suse.de>

diff --git a/target-i386/cpu.h b/target-i386/cpu.h
index 49e0259..d7ea2f9 100644
--- a/target-i386/cpu.h
+++ b/target-i386/cpu.h
@@ -382,6 +382,7 @@
 #define CPUID_PBE (1 << 31)
 
 #define CPUID_EXT_SSE3     (1 << 0)
+#define CPUID_EXT_PCLMULQDQ (1 << 1)
 #define CPUID_EXT_DTES64   (1 << 2)
 #define CPUID_EXT_MONITOR  (1 << 3)
 #define CPUID_EXT_DSCPL    (1 << 4)
@@ -401,14 +402,33 @@
 #define CPUID_EXT_MOVBE    (1 << 22)
 #define CPUID_EXT_POPCNT   (1 << 23)
 #define CPUID_EXT_TSC_DEADLINE_TIMER (1 << 24)
+#define CPUID_EXT_AES      (1 << 25)
 #define CPUID_EXT_XSAVE    (1 << 26)
 #define CPUID_EXT_OSXSAVE  (1 << 27)
+#define CPUID_EXT_AVX      (1 << 28)
 #define CPUID_EXT_HYPERVISOR  (1 << 31)
 
+#define CPUID_EXT2_FPU     (1 << 0)
+#define CPUID_EXT2_DE      (1 << 2)
+#define CPUID_EXT2_PSE     (1 << 3)
+#define CPUID_EXT2_TSC     (1 << 4)
+#define CPUID_EXT2_MSR     (1 << 5)
+#define CPUID_EXT2_PAE     (1 << 6)
+#define CPUID_EXT2_MCE     (1 << 7)
+#define CPUID_EXT2_CX8     (1 << 8)
+#define CPUID_EXT2_APIC    (1 << 9)
 #define CPUID_EXT2_SYSCALL (1 << 11)
+#define CPUID_EXT2_MTRR    (1 << 12)
+#define CPUID_EXT2_PGE     (1 << 13)
+#define CPUID_EXT2_MCA     (1 << 14)
+#define CPUID_EXT2_CMOV    (1 << 15)
+#define CPUID_EXT2_PAT     (1 << 16)
+#define CPUID_EXT2_PSE36   (1 << 17)
 #define CPUID_EXT2_MP      (1 << 19)
 #define CPUID_EXT2_NX      (1 << 20)
 #define CPUID_EXT2_MMXEXT  (1 << 22)
+#define CPUID_EXT2_MMX     (1 << 23)
+#define CPUID_EXT2_FXSR    (1 << 24)
 #define CPUID_EXT2_FFXSR   (1 << 25)
 #define CPUID_EXT2_PDPE1GB (1 << 26)
 #define CPUID_EXT2_RDTSCP  (1 << 27)
@@ -427,7 +447,9 @@
 #define CPUID_EXT3_3DNOWPREFETCH (1 << 8)
 #define CPUID_EXT3_OSVW    (1 << 9)
 #define CPUID_EXT3_IBS     (1 << 10)
+#define CPUID_EXT3_XOP     (1 << 11)
 #define CPUID_EXT3_SKINIT  (1 << 12)
+#define CPUID_EXT3_FMA4    (1 << 16)
 
 #define CPUID_SVM_NPT          (1 << 0)
 #define CPUID_SVM_LBRV         (1 << 1)
commit e916cbf80328d46b288f6c82a12cb3b8fc4fbd4a
Author: Peter Maydell <peter.maydell at linaro.org>
Date:   Wed Sep 5 17:41:08 2012 -0300

    Drop cpu_list_id macro
    
    Since the only user of the extended cpu_list_id() format
    was the x86 ?model/?dump/?cpuid output, we can drop it
    completely.
    
    Signed-off-by: Peter Maydell <peter.maydell at linaro.org>
    Reviewed-by: Eduardo Habkost <ehabkost at redhat.com>
    Signed-off-by: Eduardo Habkost <ehabkost at redhat.com>
    Reviewed-by: Igor Mammedov <imammedo at redhat.com>
    Signed-off-by: Andreas Färber <afaerber at suse.de>

diff --git a/cpus.c b/cpus.c
index e476a3c..4b726ef 100644
--- a/cpus.c
+++ b/cpus.c
@@ -1192,10 +1192,8 @@ void set_cpu_log_filename(const char *optarg)
 void list_cpus(FILE *f, fprintf_function cpu_fprintf, const char *optarg)
 {
     /* XXX: implement xxx_cpu_list for targets that still miss it */
-#if defined(cpu_list_id)
-    cpu_list_id(f, cpu_fprintf, optarg);
-#elif defined(cpu_list)
-    cpu_list(f, cpu_fprintf); /* deprecated */
+#if defined(cpu_list)
+    cpu_list(f, cpu_fprintf);
 #endif
 }
 
diff --git a/linux-user/main.c b/linux-user/main.c
index e84a18c..9f3476b 100644
--- a/linux-user/main.c
+++ b/linux-user/main.c
@@ -3130,10 +3130,8 @@ static void handle_arg_cpu(const char *arg)
     cpu_model = strdup(arg);
     if (cpu_model == NULL || is_help_option(cpu_model)) {
         /* XXX: implement xxx_cpu_list for targets that still miss it */
-#if defined(cpu_list_id)
-        cpu_list_id(stdout, &fprintf, "");
-#elif defined(cpu_list)
-        cpu_list(stdout, &fprintf); /* deprecated */
+#if defined(cpu_list)
+        cpu_list(stdout, &fprintf);
 #endif
         exit(1);
     }
diff --git a/target-i386/cpu.c b/target-i386/cpu.c
index 5c98064..d2af0ff 100644
--- a/target-i386/cpu.c
+++ b/target-i386/cpu.c
@@ -1073,8 +1073,8 @@ static void listflags(char *buf, int bufsize, uint32_t fbits,
         }
 }
 
-/* generate CPU information */
-void x86_cpu_list(FILE *f, fprintf_function cpu_fprintf, const char *optarg)
+/* generate CPU information. */
+void x86_cpu_list(FILE *f, fprintf_function cpu_fprintf)
 {
     x86_def_t *def;
     char buf[256];
diff --git a/target-i386/cpu.h b/target-i386/cpu.h
index 0677502..49e0259 100644
--- a/target-i386/cpu.h
+++ b/target-i386/cpu.h
@@ -792,7 +792,7 @@ typedef struct CPUX86State {
 
 X86CPU *cpu_x86_init(const char *cpu_model);
 int cpu_x86_exec(CPUX86State *s);
-void x86_cpu_list (FILE *f, fprintf_function cpu_fprintf, const char *optarg);
+void x86_cpu_list(FILE *f, fprintf_function cpu_fprintf);
 void x86_cpudef_setup(void);
 int cpu_x86_support_mca_broadcast(CPUX86State *env);
 
@@ -976,7 +976,7 @@ static inline CPUX86State *cpu_init(const char *cpu_model)
 #define cpu_exec cpu_x86_exec
 #define cpu_gen_code cpu_x86_gen_code
 #define cpu_signal_handler cpu_x86_signal_handler
-#define cpu_list_id x86_cpu_list
+#define cpu_list x86_cpu_list
 #define cpudef_setup	x86_cpudef_setup
 
 #define CPU_SAVE_VERSION 12
commit 6cdf8854203e51a222c9ce94a8c8c568da834cf6
Author: Peter Maydell <peter.maydell at linaro.org>
Date:   Wed Sep 5 17:41:07 2012 -0300

    target-i386: Fold -cpu ?cpuid, ?model output into -cpu help, drop ?dump
    
    Commit c8057f95 (accidentally) disabled the ability to pass
    option strings starting with '?' to the target-specific
    cpu_list function, so the target-i386 specific "-cpu ?dump",
    "-cpu ?cpuid" and "-cpu ?model" stopped working.
    
    Since these options are undocumented and not used by libvirt,
    simply drop them completely rather than reinstating them
    with new style syntax. Instead, we fold the ?model and ?cpuid
    output into the output of the plain "-cpu help" output. The
    detailed output produced by ?dump is dropped.
    
    Signed-off-by: Peter Maydell <peter.maydell at linaro.org>
    Signed-off-by: Eduardo Habkost <ehabkost at redhat.com>
    Reviewed-by: Eduardo Habkost <ehabkost at redhat.com>
    Reviewed-by: Igor Mammedov <imammedo at redhat.com>
    Signed-off-by: Andreas Färber <afaerber at suse.de>

diff --git a/target-i386/cpu.c b/target-i386/cpu.c
index 423e009..5c98064 100644
--- a/target-i386/cpu.c
+++ b/target-i386/cpu.c
@@ -1073,70 +1073,28 @@ static void listflags(char *buf, int bufsize, uint32_t fbits,
         }
 }
 
-/* generate CPU information:
- * -?        list model names
- * -?model   list model names/IDs
- * -?dump    output all model (x86_def_t) data
- * -?cpuid   list all recognized cpuid flag names
- */
+/* generate CPU information */
 void x86_cpu_list(FILE *f, fprintf_function cpu_fprintf, const char *optarg)
 {
-    unsigned char model = !strcmp("?model", optarg);
-    unsigned char dump = !strcmp("?dump", optarg);
-    unsigned char cpuid = !strcmp("?cpuid", optarg);
     x86_def_t *def;
     char buf[256];
 
-    if (cpuid) {
-        (*cpu_fprintf)(f, "Recognized CPUID flags:\n");
-        listflags(buf, sizeof (buf), (uint32_t)~0, feature_name, 1);
-        (*cpu_fprintf)(f, "  f_edx: %s\n", buf);
-        listflags(buf, sizeof (buf), (uint32_t)~0, ext_feature_name, 1);
-        (*cpu_fprintf)(f, "  f_ecx: %s\n", buf);
-        listflags(buf, sizeof (buf), (uint32_t)~0, ext2_feature_name, 1);
-        (*cpu_fprintf)(f, "  extf_edx: %s\n", buf);
-        listflags(buf, sizeof (buf), (uint32_t)~0, ext3_feature_name, 1);
-        (*cpu_fprintf)(f, "  extf_ecx: %s\n", buf);
-        return;
-    }
     for (def = x86_defs; def; def = def->next) {
         snprintf(buf, sizeof (buf), def->flags ? "[%s]": "%s", def->name);
-        if (model || dump) {
-            (*cpu_fprintf)(f, "x86 %16s  %-48s\n", buf, def->model_id);
-        } else {
-            (*cpu_fprintf)(f, "x86 %16s\n", buf);
-        }
-        if (dump) {
-            memcpy(buf, &def->vendor1, sizeof (def->vendor1));
-            memcpy(buf + 4, &def->vendor2, sizeof (def->vendor2));
-            memcpy(buf + 8, &def->vendor3, sizeof (def->vendor3));
-            buf[12] = '\0';
-            (*cpu_fprintf)(f,
-                "  family %d model %d stepping %d level %d xlevel 0x%x"
-                " vendor \"%s\"\n",
-                def->family, def->model, def->stepping, def->level,
-                def->xlevel, buf);
-            listflags(buf, sizeof (buf), def->features, feature_name, 0);
-            (*cpu_fprintf)(f, "  feature_edx %08x (%s)\n", def->features,
-                buf);
-            listflags(buf, sizeof (buf), def->ext_features, ext_feature_name,
-                0);
-            (*cpu_fprintf)(f, "  feature_ecx %08x (%s)\n", def->ext_features,
-                buf);
-            listflags(buf, sizeof (buf), def->ext2_features, ext2_feature_name,
-                0);
-            (*cpu_fprintf)(f, "  extfeature_edx %08x (%s)\n",
-                def->ext2_features, buf);
-            listflags(buf, sizeof (buf), def->ext3_features, ext3_feature_name,
-                0);
-            (*cpu_fprintf)(f, "  extfeature_ecx %08x (%s)\n",
-                def->ext3_features, buf);
-            (*cpu_fprintf)(f, "\n");
-        }
+        (*cpu_fprintf)(f, "x86 %16s  %-48s\n", buf, def->model_id);
     }
     if (kvm_enabled()) {
         (*cpu_fprintf)(f, "x86 %16s\n", "[host]");
     }
+    (*cpu_fprintf)(f, "\nRecognized CPUID flags:\n");
+    listflags(buf, sizeof(buf), (uint32_t)~0, feature_name, 1);
+    (*cpu_fprintf)(f, "  f_edx: %s\n", buf);
+    listflags(buf, sizeof(buf), (uint32_t)~0, ext_feature_name, 1);
+    (*cpu_fprintf)(f, "  f_ecx: %s\n", buf);
+    listflags(buf, sizeof(buf), (uint32_t)~0, ext2_feature_name, 1);
+    (*cpu_fprintf)(f, "  extf_edx: %s\n", buf);
+    listflags(buf, sizeof(buf), (uint32_t)~0, ext3_feature_name, 1);
+    (*cpu_fprintf)(f, "  extf_ecx: %s\n", buf);
 }
 
 CpuDefinitionInfoList *arch_query_cpu_definitions(Error **errp)
commit f2ca052414d7eddc10517e98a5a27ba8099b19b1
Author: Andreas Färber <afaerber at suse.de>
Date:   Mon Sep 17 19:10:32 2012 +0200

    MAINTAINERS: Add entry for QOM CPU
    
    Signed-off-by: Andreas Färber <afaerber at suse.de>

diff --git a/MAINTAINERS b/MAINTAINERS
index 61f8b45..25733fc 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -531,6 +531,12 @@ M: Anthony Liguori <aliguori at us.ibm.com>
 S: Maintained
 F: qemu-char.c
 
+CPU
+M: Andreas Färber <afaerber at suse.de>
+S: Supported
+F: qom/cpu.c
+F: include/qemu/cpu.h
+
 Device Tree
 M: Peter Crosthwaite <peter.crosthwaite at petalogix.com>
 M: Alexander Graf <agraf at suse.de>
commit 125afda8cbd228583c1e7c32c0f86eeb8de39c73
Author: Paolo Bonzini <pbonzini at redhat.com>
Date:   Tue Sep 18 14:31:44 2012 +0200

    nbd: add nbd_export_get_blockdev
    
    Signed-off-by: Paolo Bonzini <pbonzini at redhat.com>

diff --git a/nbd.c b/nbd.c
index 6f60dcf..57edfde 100644
--- a/nbd.c
+++ b/nbd.c
@@ -914,6 +914,7 @@ void nbd_export_close(NBDExport *exp)
     QTAILQ_FOREACH_SAFE(client, &exp->clients, next, next) {
         nbd_client_close(client);
     }
+    nbd_export_set_name(exp, NULL);
     nbd_export_put(exp);
 }
 
@@ -948,13 +949,17 @@ void nbd_export_put(NBDExport *exp)
     }
 }
 
+BlockDriverState *nbd_export_get_blockdev(NBDExport *exp)
+{
+    return exp->bs;
+}
+
 void nbd_export_close_all(void)
 {
     NBDExport *exp, *next;
 
     QTAILQ_FOREACH_SAFE(exp, &exports, next, next) {
         nbd_export_close(exp);
-        nbd_export_set_name(exp, NULL);
     }
 }
 
diff --git a/nbd.h b/nbd.h
index f0edb9c..344f05b 100644
--- a/nbd.h
+++ b/nbd.h
@@ -85,6 +85,8 @@ void nbd_export_close(NBDExport *exp);
 void nbd_export_get(NBDExport *exp);
 void nbd_export_put(NBDExport *exp);
 
+BlockDriverState *nbd_export_get_blockdev(NBDExport *exp);
+
 NBDExport *nbd_export_find(const char *name);
 void nbd_export_set_name(NBDExport *exp, const char *name);
 void nbd_export_close_all(void);
commit 6b8c01e781524ab713faa31a4fb5b20a745f638a
Author: Paolo Bonzini <pbonzini at redhat.com>
Date:   Thu Aug 23 14:57:11 2012 +0200

    nbd: negotiate with named exports
    
    Allow negotiation to receive the name of the requested export from
    the client.  Passing a NULL export to nbd_client_new will cause
    the server to send the extended negotiation header.  The exp field
    is then filled during negotiation.
    
    Signed-off-by: Paolo Bonzini <pbonzini at redhat.com>

diff --git a/nbd.c b/nbd.c
index 2d2221c..6f60dcf 100644
--- a/nbd.c
+++ b/nbd.c
@@ -238,11 +238,23 @@ int unix_socket_outgoing(const char *path)
     return unix_connect(path);
 }
 
-/* Basic flow
+/* Basic flow for negotiation
 
    Server         Client
-
    Negotiate
+
+   or
+
+   Server         Client
+   Negotiate #1
+                  Option
+   Negotiate #2
+
+   ----
+
+   followed by
+
+   Server         Client
                   Request
    Response
                   Request
@@ -250,20 +262,112 @@ int unix_socket_outgoing(const char *path)
                   ...
    ...
                   Request (type == 2)
+
 */
 
+static int nbd_receive_options(NBDClient *client)
+{
+    int csock = client->sock;
+    char name[256];
+    uint32_t tmp, length;
+    uint64_t magic;
+    int rc;
+
+    /* Client sends:
+        [ 0 ..   3]   reserved (0)
+        [ 4 ..  11]   NBD_OPTS_MAGIC
+        [12 ..  15]   NBD_OPT_EXPORT_NAME
+        [16 ..  19]   length
+        [20 ..  xx]   export name (length bytes)
+     */
+
+    rc = -EINVAL;
+    if (read_sync(csock, &tmp, sizeof(tmp)) != sizeof(tmp)) {
+        LOG("read failed");
+        goto fail;
+    }
+    TRACE("Checking reserved");
+    if (tmp != 0) {
+        LOG("Bad reserved received");
+        goto fail;
+    }
+
+    if (read_sync(csock, &magic, sizeof(magic)) != sizeof(magic)) {
+        LOG("read failed");
+        goto fail;
+    }
+    TRACE("Checking reserved");
+    if (magic != be64_to_cpu(NBD_OPTS_MAGIC)) {
+        LOG("Bad magic received");
+        goto fail;
+    }
+
+    if (read_sync(csock, &tmp, sizeof(tmp)) != sizeof(tmp)) {
+        LOG("read failed");
+        goto fail;
+    }
+    TRACE("Checking option");
+    if (tmp != be32_to_cpu(NBD_OPT_EXPORT_NAME)) {
+        LOG("Bad option received");
+        goto fail;
+    }
+
+    if (read_sync(csock, &length, sizeof(length)) != sizeof(length)) {
+        LOG("read failed");
+        goto fail;
+    }
+    TRACE("Checking length");
+    length = be32_to_cpu(length);
+    if (length > 255) {
+        LOG("Bad length received");
+        goto fail;
+    }
+    if (read_sync(csock, name, length) != length) {
+        LOG("read failed");
+        goto fail;
+    }
+    name[length] = '\0';
+
+    client->exp = nbd_export_find(name);
+    if (!client->exp) {
+        LOG("export not found");
+        goto fail;
+    }
+
+    QTAILQ_INSERT_TAIL(&client->exp->clients, client, next);
+    nbd_export_get(client->exp);
+
+    TRACE("Option negotiation succeeded.");
+    rc = 0;
+fail:
+    return rc;
+}
+
 static int nbd_send_negotiate(NBDClient *client)
 {
     int csock = client->sock;
     char buf[8 + 8 + 8 + 128];
     int rc;
+    const int myflags = (NBD_FLAG_HAS_FLAGS | NBD_FLAG_SEND_TRIM |
+                         NBD_FLAG_SEND_FLUSH | NBD_FLAG_SEND_FUA);
 
-    /* Negotiate
-        [ 0 ..   7]   passwd   ("NBDMAGIC")
-        [ 8 ..  15]   magic    (NBD_CLIENT_MAGIC)
+    /* Negotiation header without options:
+        [ 0 ..   7]   passwd       ("NBDMAGIC")
+        [ 8 ..  15]   magic        (NBD_CLIENT_MAGIC)
         [16 ..  23]   size
-        [24 ..  27]   flags
-        [28 .. 151]   reserved (0)
+        [24 ..  25]   server flags (0)
+        [24 ..  27]   export flags
+        [28 .. 151]   reserved     (0)
+
+       Negotiation header with options, part 1:
+        [ 0 ..   7]   passwd       ("NBDMAGIC")
+        [ 8 ..  15]   magic        (NBD_OPTS_MAGIC)
+        [16 ..  17]   server flags (0)
+
+       part 2 (after options are sent):
+        [18 ..  25]   size
+        [26 ..  27]   export flags
+        [28 .. 151]   reserved     (0)
      */
 
     socket_set_block(csock);
@@ -271,16 +375,39 @@ static int nbd_send_negotiate(NBDClient *client)
 
     TRACE("Beginning negotiation.");
     memcpy(buf, "NBDMAGIC", 8);
-    cpu_to_be64w((uint64_t*)(buf + 8), NBD_CLIENT_MAGIC);
-    cpu_to_be64w((uint64_t*)(buf + 16), client->exp->size);
-    cpu_to_be32w((uint32_t*)(buf + 24),
-                 client->exp->nbdflags | NBD_FLAG_HAS_FLAGS | NBD_FLAG_SEND_TRIM |
-                 NBD_FLAG_SEND_FLUSH | NBD_FLAG_SEND_FUA);
+    if (client->exp) {
+        assert ((client->exp->nbdflags & ~65535) == 0);
+        cpu_to_be64w((uint64_t*)(buf + 8), NBD_CLIENT_MAGIC);
+        cpu_to_be64w((uint64_t*)(buf + 16), client->exp->size);
+        cpu_to_be16w((uint16_t*)(buf + 26), client->exp->nbdflags | myflags);
+    } else {
+        cpu_to_be64w((uint64_t*)(buf + 8), NBD_OPTS_MAGIC);
+    }
     memset(buf + 28, 0, 124);
 
-    if (write_sync(csock, buf, sizeof(buf)) != sizeof(buf)) {
-        LOG("write failed");
-        goto fail;
+    if (client->exp) {
+        if (write_sync(csock, buf, sizeof(buf)) != sizeof(buf)) {
+            LOG("write failed");
+            goto fail;
+        }
+    } else {
+        if (write_sync(csock, buf, 18) != 18) {
+            LOG("write failed");
+            goto fail;
+        }
+        rc = nbd_receive_options(client);
+        if (rc < 0) {
+            LOG("option negotiation failed");
+            goto fail;
+        }
+
+        assert ((client->exp->nbdflags & ~65535) == 0);
+        cpu_to_be64w((uint64_t*)(buf + 18), client->exp->size);
+        cpu_to_be16w((uint16_t*)(buf + 26), client->exp->nbdflags | myflags);
+        if (write_sync(csock, buf + 18, sizeof(buf) - 18) != sizeof(buf) - 18) {
+            LOG("write failed");
+            goto fail;
+        }
     }
 
     TRACE("Negotiation succeeded.");
@@ -673,8 +800,10 @@ void nbd_client_put(NBDClient *client)
         qemu_set_fd_handler2(client->sock, NULL, NULL, NULL, NULL);
         close(client->sock);
         client->sock = -1;
-        QTAILQ_REMOVE(&client->exp->clients, client, next);
-        nbd_export_put(client->exp);
+        if (client->exp) {
+            QTAILQ_REMOVE(&client->exp->clients, client, next);
+            nbd_export_put(client->exp);
+        }
         g_free(client);
     }
 }
@@ -1100,7 +1229,9 @@ NBDClient *nbd_client_new(NBDExport *exp, int csock,
     qemu_co_mutex_init(&client->send_lock);
     qemu_set_fd_handler2(csock, nbd_can_read, nbd_read, NULL, client);
 
-    QTAILQ_INSERT_TAIL(&exp->clients, client, next);
-    nbd_export_get(exp);
+    if (exp) {
+        QTAILQ_INSERT_TAIL(&exp->clients, client, next);
+        nbd_export_get(exp);
+    }
     return client;
 }
commit ee0a19ec2a98989ff634857fb203bc2879d96bff
Author: Paolo Bonzini <pbonzini at redhat.com>
Date:   Wed Aug 22 15:59:23 2012 +0200

    nbd: register named exports
    
    Add an API to register and find named exports.
    
    Signed-off-by: Paolo Bonzini <pbonzini at redhat.com>

diff --git a/nbd.c b/nbd.c
index 2e9de70..2d2221c 100644
--- a/nbd.c
+++ b/nbd.c
@@ -93,13 +93,17 @@ struct NBDExport {
     void (*close)(NBDExport *exp);
 
     BlockDriverState *bs;
+    char *name;
     off_t dev_offset;
     off_t size;
     uint32_t nbdflags;
     QTAILQ_HEAD(, NBDClient) clients;
     QSIMPLEQ_HEAD(, NBDRequest) requests;
+    QTAILQ_ENTRY(NBDExport) next;
 };
 
+static QTAILQ_HEAD(, NBDExport) exports = QTAILQ_HEAD_INITIALIZER(exports);
+
 struct NBDClient {
     int refcount;
     void (*close)(NBDClient *client);
@@ -740,6 +744,39 @@ NBDExport *nbd_export_new(BlockDriverState *bs, off_t dev_offset,
     return exp;
 }
 
+NBDExport *nbd_export_find(const char *name)
+{
+    NBDExport *exp;
+    QTAILQ_FOREACH(exp, &exports, next) {
+        if (strcmp(name, exp->name) == 0) {
+            return exp;
+        }
+    }
+
+    return NULL;
+}
+
+void nbd_export_set_name(NBDExport *exp, const char *name)
+{
+    if (exp->name == name) {
+        return;
+    }
+
+    nbd_export_get(exp);
+    if (exp->name != NULL) {
+        g_free(exp->name);
+        exp->name = NULL;
+        QTAILQ_REMOVE(&exports, exp, next);
+        nbd_export_put(exp);
+    }
+    if (name != NULL) {
+        nbd_export_get(exp);
+        exp->name = g_strdup(name);
+        QTAILQ_INSERT_TAIL(&exports, exp, next);
+    }
+    nbd_export_put(exp);
+}
+
 void nbd_export_close(NBDExport *exp)
 {
     NBDClient *client, *next;
@@ -765,6 +802,8 @@ void nbd_export_put(NBDExport *exp)
     }
 
     if (--exp->refcount == 0) {
+        assert(exp->name == NULL);
+
         if (exp->close) {
             exp->close(exp);
         }
@@ -780,6 +819,16 @@ void nbd_export_put(NBDExport *exp)
     }
 }
 
+void nbd_export_close_all(void)
+{
+    NBDExport *exp, *next;
+
+    QTAILQ_FOREACH_SAFE(exp, &exports, next, next) {
+        nbd_export_close(exp);
+        nbd_export_set_name(exp, NULL);
+    }
+}
+
 static int nbd_can_read(void *opaque);
 static void nbd_read(void *opaque);
 static void nbd_restart_write(void *opaque);
diff --git a/nbd.h b/nbd.h
index 895820b..f0edb9c 100644
--- a/nbd.h
+++ b/nbd.h
@@ -85,6 +85,10 @@ void nbd_export_close(NBDExport *exp);
 void nbd_export_get(NBDExport *exp);
 void nbd_export_put(NBDExport *exp);
 
+NBDExport *nbd_export_find(const char *name);
+void nbd_export_set_name(NBDExport *exp, const char *name);
+void nbd_export_close_all(void);
+
 NBDClient *nbd_client_new(NBDExport *exp, int csock,
                           void (*close)(NBDClient *));
 void nbd_client_close(NBDClient *client);
commit 7860a380ac2a9fd09a6e8f31fd9db5318fc91285
Author: Paolo Bonzini <pbonzini at redhat.com>
Date:   Tue Sep 18 13:31:56 2012 +0200

    qemu-nbd: rewrite termination conditions to use a state machine
    
    Use a simple state machine with the following states:
    
    - RUNNING     => accepting connections
    - TERMINATE   => main loop must call nbd_export_close/put, and not accept
      connections anymore
    - TERMINATING => waiting for pending requests to finish
    - TERMINATED  => the NBDExport has been closed
    
    Signed-off-by: Paolo Bonzini <pbonzini at redhat.com>

diff --git a/qemu-nbd.c b/qemu-nbd.c
index 8b87dea..15bcd08 100644
--- a/qemu-nbd.c
+++ b/qemu-nbd.c
@@ -41,8 +41,8 @@ static NBDExport *exp;
 static int verbose;
 static char *srcpath;
 static char *sockpath;
-static bool sigterm_reported;
-static bool nbd_started;
+static int persistent = 0;
+static enum { RUNNING, TERMINATE, TERMINATING, TERMINATED } state;
 static int shared = 1;
 static int nb_fds;
 
@@ -186,7 +186,7 @@ static int find_partition(BlockDriverState *bs, int partition,
 
 static void termsig_handler(int signum)
 {
-    sigterm_reported = true;
+    state = TERMINATE;
     qemu_notify_event();
 }
 
@@ -269,10 +269,20 @@ static int nbd_can_accept(void *opaque)
     return nb_fds < shared;
 }
 
+static void nbd_export_closed(NBDExport *exp)
+{
+    assert(state == TERMINATING);
+    state = TERMINATED;
+}
+
 static void nbd_client_closed(NBDClient *client)
 {
     nb_fds--;
+    if (nb_fds == 0 && !persistent && state == RUNNING) {
+        state = TERMINATE;
+    }
     qemu_notify_event();
+    nbd_client_put(client);
 }
 
 static void nbd_accept(void *opaque)
@@ -282,7 +292,11 @@ static void nbd_accept(void *opaque)
     socklen_t addr_len = sizeof(addr);
 
     int fd = accept(server_fd, (struct sockaddr *)&addr, &addr_len);
-    nbd_started = true;
+    if (state >= TERMINATE) {
+        close(fd);
+        return;
+    }
+
     if (fd >= 0 && nbd_client_new(exp, fd, nbd_client_closed)) {
         nb_fds++;
     }
@@ -329,7 +343,6 @@ int main(int argc, char **argv)
     int partition = -1;
     int ret;
     int fd;
-    int persistent = 0;
     bool seen_cache = false;
 #ifdef CONFIG_LINUX_AIO
     bool seen_aio = false;
@@ -546,7 +559,7 @@ int main(int argc, char **argv)
         }
     }
 
-    exp = nbd_export_new(bs, dev_offset, fd_size, nbdflags, NULL);
+    exp = nbd_export_new(bs, dev_offset, fd_size, nbdflags, nbd_export_closed);
 
     if (sockpath) {
         fd = unix_socket_incoming(sockpath);
@@ -581,14 +594,18 @@ int main(int argc, char **argv)
         err(EXIT_FAILURE, "Could not chdir to root directory");
     }
 
+    state = RUNNING;
     do {
         main_loop_wait(false);
-    } while (!sigterm_reported && (persistent || !nbd_started || nb_fds > 0));
+        if (state == TERMINATE) {
+            state = TERMINATING;
+            nbd_export_close(exp);
+            nbd_export_put(exp);
+            exp = NULL;
+        }
+    } while (state != TERMINATED);
 
-    nbd_export_close(exp);
-    nbd_export_put(exp);
     bdrv_close(bs);
-
     if (sockpath) {
         unlink(sockpath);
     }
commit 0ddf08db22a9ef6b122d8c4cfe5b25d2c2c51962
Author: Paolo Bonzini <pbonzini at redhat.com>
Date:   Tue Sep 18 13:59:03 2012 +0200

    nbd: add notification for closing an NBDExport
    
    In order to exit cleanly from qemu-nbd, add a callback that triggers
    when an NBDExport is closed.  In the case of qemu-nbd it will exit the
    main loop.
    
    Signed-off-by: Paolo Bonzini <pbonzini at redhat.com>

diff --git a/nbd.c b/nbd.c
index c39692b..2e9de70 100644
--- a/nbd.c
+++ b/nbd.c
@@ -90,6 +90,8 @@ struct NBDRequest {
 
 struct NBDExport {
     int refcount;
+    void (*close)(NBDExport *exp);
+
     BlockDriverState *bs;
     off_t dev_offset;
     off_t size;
@@ -723,7 +725,8 @@ static void nbd_request_put(NBDRequest *req)
 }
 
 NBDExport *nbd_export_new(BlockDriverState *bs, off_t dev_offset,
-                          off_t size, uint32_t nbdflags)
+                          off_t size, uint32_t nbdflags,
+                          void (*close)(NBDExport *))
 {
     NBDExport *exp = g_malloc0(sizeof(NBDExport));
     QSIMPLEQ_INIT(&exp->requests);
@@ -733,6 +736,7 @@ NBDExport *nbd_export_new(BlockDriverState *bs, off_t dev_offset,
     exp->dev_offset = dev_offset;
     exp->nbdflags = nbdflags;
     exp->size = size == -1 ? bdrv_getlength(bs) : size;
+    exp->close = close;
     return exp;
 }
 
@@ -761,6 +765,10 @@ void nbd_export_put(NBDExport *exp)
     }
 
     if (--exp->refcount == 0) {
+        if (exp->close) {
+            exp->close(exp);
+        }
+
         while (!QSIMPLEQ_EMPTY(&exp->requests)) {
             NBDRequest *first = QSIMPLEQ_FIRST(&exp->requests);
             QSIMPLEQ_REMOVE_HEAD(&exp->requests, entry);
diff --git a/nbd.h b/nbd.h
index 86921cd..895820b 100644
--- a/nbd.h
+++ b/nbd.h
@@ -79,7 +79,8 @@ typedef struct NBDExport NBDExport;
 typedef struct NBDClient NBDClient;
 
 NBDExport *nbd_export_new(BlockDriverState *bs, off_t dev_offset,
-                          off_t size, uint32_t nbdflags);
+                          off_t size, uint32_t nbdflags,
+                          void (*close)(NBDExport *));
 void nbd_export_close(NBDExport *exp);
 void nbd_export_get(NBDExport *exp);
 void nbd_export_put(NBDExport *exp);
diff --git a/qemu-nbd.c b/qemu-nbd.c
index 2a2cba3..8b87dea 100644
--- a/qemu-nbd.c
+++ b/qemu-nbd.c
@@ -546,7 +546,7 @@ int main(int argc, char **argv)
         }
     }
 
-    exp = nbd_export_new(bs, dev_offset, fd_size, nbdflags);
+    exp = nbd_export_new(bs, dev_offset, fd_size, nbdflags, NULL);
 
     if (sockpath) {
         fd = unix_socket_incoming(sockpath);
commit 4b9441f6b3565ba6affa95141590cd2be4ae0cd9
Author: Paolo Bonzini <pbonzini at redhat.com>
Date:   Tue Sep 18 13:58:25 2012 +0200

    nbd: track clients into NBDExport
    
    Track the NBDClients of each NBDExport, and use it to implement
    nbd_export_close.
    
    Signed-off-by: Paolo Bonzini <pbonzini at redhat.com>

diff --git a/nbd.c b/nbd.c
index 4922d38..c39692b 100644
--- a/nbd.c
+++ b/nbd.c
@@ -94,6 +94,7 @@ struct NBDExport {
     off_t dev_offset;
     off_t size;
     uint32_t nbdflags;
+    QTAILQ_HEAD(, NBDClient) clients;
     QSIMPLEQ_HEAD(, NBDRequest) requests;
 };
 
@@ -109,6 +110,7 @@ struct NBDClient {
     CoMutex send_lock;
     Coroutine *send_coroutine;
 
+    QTAILQ_ENTRY(NBDClient) next;
     int nb_requests;
     bool closing;
 };
@@ -665,6 +667,7 @@ void nbd_client_put(NBDClient *client)
         qemu_set_fd_handler2(client->sock, NULL, NULL, NULL, NULL);
         close(client->sock);
         client->sock = -1;
+        QTAILQ_REMOVE(&client->exp->clients, client, next);
         nbd_export_put(client->exp);
         g_free(client);
     }
@@ -725,6 +728,7 @@ NBDExport *nbd_export_new(BlockDriverState *bs, off_t dev_offset,
     NBDExport *exp = g_malloc0(sizeof(NBDExport));
     QSIMPLEQ_INIT(&exp->requests);
     exp->refcount = 1;
+    QTAILQ_INIT(&exp->clients);
     exp->bs = bs;
     exp->dev_offset = dev_offset;
     exp->nbdflags = nbdflags;
@@ -734,9 +738,13 @@ NBDExport *nbd_export_new(BlockDriverState *bs, off_t dev_offset,
 
 void nbd_export_close(NBDExport *exp)
 {
-    assert(exp->refcount == 1);
+    NBDClient *client, *next;
 
-    /* stub */
+    nbd_export_get(exp);
+    QTAILQ_FOREACH_SAFE(client, &exp->clients, next, next) {
+        nbd_client_close(client);
+    }
+    nbd_export_put(exp);
 }
 
 void nbd_export_get(NBDExport *exp)
@@ -1035,6 +1043,7 @@ NBDClient *nbd_client_new(NBDExport *exp, int csock,
     qemu_co_mutex_init(&client->send_lock);
     qemu_set_fd_handler2(csock, nbd_can_read, nbd_read, NULL, client);
 
+    QTAILQ_INSERT_TAIL(&exp->clients, client, next);
     nbd_export_get(exp);
     return client;
 }
commit 2c8d9f065538a5a0ef2421e90b6076d05148accf
Author: Paolo Bonzini <pbonzini at redhat.com>
Date:   Tue Sep 18 13:26:25 2012 +0200

    nbd: add reference counting to NBDExport
    
    We will use a similar two-phase destruction for NBDExport, so we need
    each NBDClient to add a reference to NBDExport.
    
    Signed-off-by: Paolo Bonzini <pbonzini at redhat.com>

diff --git a/nbd.c b/nbd.c
index eb72f4a..4922d38 100644
--- a/nbd.c
+++ b/nbd.c
@@ -89,6 +89,7 @@ struct NBDRequest {
 };
 
 struct NBDExport {
+    int refcount;
     BlockDriverState *bs;
     off_t dev_offset;
     off_t size;
@@ -664,6 +665,7 @@ void nbd_client_put(NBDClient *client)
         qemu_set_fd_handler2(client->sock, NULL, NULL, NULL, NULL);
         close(client->sock);
         client->sock = -1;
+        nbd_export_put(client->exp);
         g_free(client);
     }
 }
@@ -722,6 +724,7 @@ NBDExport *nbd_export_new(BlockDriverState *bs, off_t dev_offset,
 {
     NBDExport *exp = g_malloc0(sizeof(NBDExport));
     QSIMPLEQ_INIT(&exp->requests);
+    exp->refcount = 1;
     exp->bs = bs;
     exp->dev_offset = dev_offset;
     exp->nbdflags = nbdflags;
@@ -731,14 +734,34 @@ NBDExport *nbd_export_new(BlockDriverState *bs, off_t dev_offset,
 
 void nbd_export_close(NBDExport *exp)
 {
-    while (!QSIMPLEQ_EMPTY(&exp->requests)) {
-        NBDRequest *first = QSIMPLEQ_FIRST(&exp->requests);
-        QSIMPLEQ_REMOVE_HEAD(&exp->requests, entry);
-        qemu_vfree(first->data);
-        g_free(first);
+    assert(exp->refcount == 1);
+
+    /* stub */
+}
+
+void nbd_export_get(NBDExport *exp)
+{
+    assert(exp->refcount > 0);
+    exp->refcount++;
+}
+
+void nbd_export_put(NBDExport *exp)
+{
+    assert(exp->refcount > 0);
+    if (exp->refcount == 1) {
+        nbd_export_close(exp);
     }
 
-    g_free(exp);
+    if (--exp->refcount == 0) {
+        while (!QSIMPLEQ_EMPTY(&exp->requests)) {
+            NBDRequest *first = QSIMPLEQ_FIRST(&exp->requests);
+            QSIMPLEQ_REMOVE_HEAD(&exp->requests, entry);
+            qemu_vfree(first->data);
+            g_free(first);
+        }
+
+        g_free(exp);
+    }
 }
 
 static int nbd_can_read(void *opaque);
@@ -1011,5 +1034,7 @@ NBDClient *nbd_client_new(NBDExport *exp, int csock,
     client->close = close;
     qemu_co_mutex_init(&client->send_lock);
     qemu_set_fd_handler2(csock, nbd_can_read, nbd_read, NULL, client);
+
+    nbd_export_get(exp);
     return client;
 }
diff --git a/nbd.h b/nbd.h
index 8b84a50..86921cd 100644
--- a/nbd.h
+++ b/nbd.h
@@ -81,6 +81,8 @@ typedef struct NBDClient NBDClient;
 NBDExport *nbd_export_new(BlockDriverState *bs, off_t dev_offset,
                           off_t size, uint32_t nbdflags);
 void nbd_export_close(NBDExport *exp);
+void nbd_export_get(NBDExport *exp);
+void nbd_export_put(NBDExport *exp);
 
 NBDClient *nbd_client_new(NBDExport *exp, int csock,
                           void (*close)(NBDClient *));
diff --git a/qemu-nbd.c b/qemu-nbd.c
index 23392e0..2a2cba3 100644
--- a/qemu-nbd.c
+++ b/qemu-nbd.c
@@ -586,7 +586,9 @@ int main(int argc, char **argv)
     } while (!sigterm_reported && (persistent || !nbd_started || nb_fds > 0));
 
     nbd_export_close(exp);
+    nbd_export_put(exp);
     bdrv_close(bs);
+
     if (sockpath) {
         unlink(sockpath);
     }
commit ff2b68aa70d10b7eae813b04e9a23723dbd89ebd
Author: Paolo Bonzini <pbonzini at redhat.com>
Date:   Wed Aug 22 18:45:12 2012 +0200

    nbd: do not leak nbd_trip coroutines when a connection is torn down
    
    Because nbd_client_close removes the I/O handlers for the client
    socket, there is no way that any suspended coroutines are restarted.
    This will be a problem with the QEMU embedded NBD server, because
    we will have a QMP command to forcibly close all connections with
    the clients.
    
    Instead, we can exploit the reference counting of NBDClients; shutdown the
    client socket, which will make it readable and writeable.  Also call the
    close callback, which will release the user's reference.  The coroutines
    then will fail and exit cleanly, and release all remaining references,
    until the last refcount finally triggers the closure of the client.
    
    Signed-off-by: Paolo Bonzini <pbonzini at redhat.com>

diff --git a/nbd.c b/nbd.c
index 4aeb80a..eb72f4a 100644
--- a/nbd.c
+++ b/nbd.c
@@ -109,6 +109,7 @@ struct NBDClient {
     Coroutine *send_coroutine;
 
     int nb_requests;
+    bool closing;
 };
 
 /* That's all folks */
@@ -655,19 +656,35 @@ void nbd_client_get(NBDClient *client)
 void nbd_client_put(NBDClient *client)
 {
     if (--client->refcount == 0) {
+        /* The last reference should be dropped by client->close,
+         * which is called by nbd_client_close.
+         */
+        assert(client->closing);
+
+        qemu_set_fd_handler2(client->sock, NULL, NULL, NULL, NULL);
+        close(client->sock);
+        client->sock = -1;
         g_free(client);
     }
 }
 
-static void nbd_client_close(NBDClient *client)
+void nbd_client_close(NBDClient *client)
 {
-    qemu_set_fd_handler2(client->sock, NULL, NULL, NULL, NULL);
-    close(client->sock);
-    client->sock = -1;
+    if (client->closing) {
+        return;
+    }
+
+    client->closing = true;
+
+    /* Force requests to finish.  They will drop their own references,
+     * then we'll close the socket and free the NBDClient.
+     */
+    shutdown(client->sock, 2);
+
+    /* Also tell the client, so that they release their reference.  */
     if (client->close) {
         client->close(client);
     }
-    nbd_client_put(client);
 }
 
 static NBDRequest *nbd_request_get(NBDClient *client)
@@ -810,14 +827,18 @@ out:
 static void nbd_trip(void *opaque)
 {
     NBDClient *client = opaque;
-    NBDRequest *req = nbd_request_get(client);
     NBDExport *exp = client->exp;
+    NBDRequest *req;
     struct nbd_request request;
     struct nbd_reply reply;
     ssize_t ret;
 
     TRACE("Reading request.");
+    if (client->closing) {
+        return;
+    }
 
+    req = nbd_request_get(client);
     ret = nbd_co_receive_request(req, &request);
     if (ret == -EAGAIN) {
         goto done;
diff --git a/nbd.h b/nbd.h
index a9038dc..8b84a50 100644
--- a/nbd.h
+++ b/nbd.h
@@ -84,6 +84,7 @@ void nbd_export_close(NBDExport *exp);
 
 NBDClient *nbd_client_new(NBDExport *exp, int csock,
                           void (*close)(NBDClient *));
+void nbd_client_close(NBDClient *client);
 void nbd_client_get(NBDClient *client);
 void nbd_client_put(NBDClient *client);
 
commit ce33967af74523685c7f911f6576c689728fcc81
Author: Paolo Bonzini <pbonzini at redhat.com>
Date:   Tue Sep 18 13:17:52 2012 +0200

    nbd: make refcount interface public
    
    After the next patch, the close callback will have to release its
    reference.
    
    Signed-off-by: Paolo Bonzini <pbonzini at redhat.com>

diff --git a/nbd.c b/nbd.c
index 83200bd..4aeb80a 100644
--- a/nbd.c
+++ b/nbd.c
@@ -647,12 +647,12 @@ static ssize_t nbd_send_reply(int csock, struct nbd_reply *reply)
 
 #define MAX_NBD_REQUESTS 16
 
-static void nbd_client_get(NBDClient *client)
+void nbd_client_get(NBDClient *client)
 {
     client->refcount++;
 }
 
-static void nbd_client_put(NBDClient *client)
+void nbd_client_put(NBDClient *client)
 {
     if (--client->refcount == 0) {
         g_free(client);
diff --git a/nbd.h b/nbd.h
index 40d58d3..a9038dc 100644
--- a/nbd.h
+++ b/nbd.h
@@ -81,7 +81,10 @@ typedef struct NBDClient NBDClient;
 NBDExport *nbd_export_new(BlockDriverState *bs, off_t dev_offset,
                           off_t size, uint32_t nbdflags);
 void nbd_export_close(NBDExport *exp);
+
 NBDClient *nbd_client_new(NBDExport *exp, int csock,
                           void (*close)(NBDClient *));
+void nbd_client_get(NBDClient *client);
+void nbd_client_put(NBDClient *client);
 
 #endif
commit a4aab7b4cb2d994e17c987d7d3fb2b6645ea92a2
Author: Paolo Bonzini <pbonzini at redhat.com>
Date:   Wed Aug 22 18:50:30 2012 +0200

    nbd: do not close BlockDriverState in nbd_export_close
    
    This is not desirable when embedding the NBD server inside QEMU.
    Move the bdrv_close to qemu-nbd.
    
    Signed-off-by: Paolo Bonzini <pbonzini at redhat.com>

diff --git a/nbd.c b/nbd.c
index 5a3088d..83200bd 100644
--- a/nbd.c
+++ b/nbd.c
@@ -721,7 +721,6 @@ void nbd_export_close(NBDExport *exp)
         g_free(first);
     }
 
-    bdrv_close(exp->bs);
     g_free(exp);
 }
 
diff --git a/qemu-nbd.c b/qemu-nbd.c
index 1c1cf6a..23392e0 100644
--- a/qemu-nbd.c
+++ b/qemu-nbd.c
@@ -586,6 +586,7 @@ int main(int argc, char **argv)
     } while (!sigterm_reported && (persistent || !nbd_started || nb_fds > 0));
 
     nbd_export_close(exp);
+    bdrv_close(bs);
     if (sockpath) {
         unlink(sockpath);
     }
commit 9a304d29a79a3daeeaf15c68d7439713037405b1
Author: Paolo Bonzini <pbonzini at redhat.com>
Date:   Wed Aug 22 15:30:31 2012 +0200

    nbd: pass NBDClient to nbd_send_negotiate
    
    We will need the NBDClient in nbd_send_negotiate to store the
    export requested by the client.
    
    Signed-off-by: Paolo Bonzini <pbonzini at redhat.com>

diff --git a/nbd.c b/nbd.c
index 8201b7a..5a3088d 100644
--- a/nbd.c
+++ b/nbd.c
@@ -78,6 +78,39 @@
 
 #define NBD_OPT_EXPORT_NAME     (1 << 0)
 
+/* Definitions for opaque data types */
+
+typedef struct NBDRequest NBDRequest;
+
+struct NBDRequest {
+    QSIMPLEQ_ENTRY(NBDRequest) entry;
+    NBDClient *client;
+    uint8_t *data;
+};
+
+struct NBDExport {
+    BlockDriverState *bs;
+    off_t dev_offset;
+    off_t size;
+    uint32_t nbdflags;
+    QSIMPLEQ_HEAD(, NBDRequest) requests;
+};
+
+struct NBDClient {
+    int refcount;
+    void (*close)(NBDClient *client);
+
+    NBDExport *exp;
+    int sock;
+
+    Coroutine *recv_coroutine;
+
+    CoMutex send_lock;
+    Coroutine *send_coroutine;
+
+    int nb_requests;
+};
+
 /* That's all folks */
 
 ssize_t nbd_wr_sync(int fd, void *buffer, size_t size, bool do_read)
@@ -209,8 +242,9 @@ int unix_socket_outgoing(const char *path)
                   Request (type == 2)
 */
 
-static int nbd_send_negotiate(int csock, off_t size, uint32_t flags)
+static int nbd_send_negotiate(NBDClient *client)
 {
+    int csock = client->sock;
     char buf[8 + 8 + 8 + 128];
     int rc;
 
@@ -228,9 +262,9 @@ static int nbd_send_negotiate(int csock, off_t size, uint32_t flags)
     TRACE("Beginning negotiation.");
     memcpy(buf, "NBDMAGIC", 8);
     cpu_to_be64w((uint64_t*)(buf + 8), NBD_CLIENT_MAGIC);
-    cpu_to_be64w((uint64_t*)(buf + 16), size);
+    cpu_to_be64w((uint64_t*)(buf + 16), client->exp->size);
     cpu_to_be32w((uint32_t*)(buf + 24),
-                 flags | NBD_FLAG_HAS_FLAGS | NBD_FLAG_SEND_TRIM |
+                 client->exp->nbdflags | NBD_FLAG_HAS_FLAGS | NBD_FLAG_SEND_TRIM |
                  NBD_FLAG_SEND_FLUSH | NBD_FLAG_SEND_FUA);
     memset(buf + 28, 0, 124);
 
@@ -613,37 +647,6 @@ static ssize_t nbd_send_reply(int csock, struct nbd_reply *reply)
 
 #define MAX_NBD_REQUESTS 16
 
-typedef struct NBDRequest NBDRequest;
-
-struct NBDRequest {
-    QSIMPLEQ_ENTRY(NBDRequest) entry;
-    NBDClient *client;
-    uint8_t *data;
-};
-
-struct NBDExport {
-    BlockDriverState *bs;
-    off_t dev_offset;
-    off_t size;
-    uint32_t nbdflags;
-    QSIMPLEQ_HEAD(, NBDRequest) requests;
-};
-
-struct NBDClient {
-    int refcount;
-    void (*close)(NBDClient *client);
-
-    NBDExport *exp;
-    int sock;
-
-    Coroutine *recv_coroutine;
-
-    CoMutex send_lock;
-    Coroutine *send_coroutine;
-
-    int nb_requests;
-};
-
 static void nbd_client_get(NBDClient *client)
 {
     client->refcount++;
@@ -977,13 +980,14 @@ NBDClient *nbd_client_new(NBDExport *exp, int csock,
                           void (*close)(NBDClient *))
 {
     NBDClient *client;
-    if (nbd_send_negotiate(csock, exp->size, exp->nbdflags) < 0) {
-        return NULL;
-    }
     client = g_malloc0(sizeof(NBDClient));
     client->refcount = 1;
     client->exp = exp;
     client->sock = csock;
+    if (nbd_send_negotiate(client) < 0) {
+        g_free(client);
+        return NULL;
+    }
     client->close = close;
     qemu_co_mutex_init(&client->send_lock);
     qemu_set_fd_handler2(csock, nbd_can_read, nbd_read, NULL, client);
commit fa26c26b078b298a18686adb06a38bea3cdee990
Author: Paolo Bonzini <pbonzini at redhat.com>
Date:   Wed Aug 22 15:13:30 2012 +0200

    nbd: add more constants
    
    Avoid magic numbers and magic size computations; hide them behind
    constants.
    
    Signed-off-by: Paolo Bonzini <pbonzini at redhat.com>

diff --git a/nbd.c b/nbd.c
index 0dd60c5..8201b7a 100644
--- a/nbd.c
+++ b/nbd.c
@@ -57,9 +57,12 @@
 
 /* This is all part of the "official" NBD API */
 
+#define NBD_REQUEST_SIZE        (4 + 4 + 8 + 8 + 4)
 #define NBD_REPLY_SIZE          (4 + 4 + 8)
 #define NBD_REQUEST_MAGIC       0x25609513
 #define NBD_REPLY_MAGIC         0x67446698
+#define NBD_OPTS_MAGIC          0x49484156454F5054LL
+#define NBD_CLIENT_MAGIC        0x0000420281861253LL
 
 #define NBD_SET_SOCK            _IO(0xab, 0)
 #define NBD_SET_BLKSIZE         _IO(0xab, 1)
@@ -213,7 +216,7 @@ static int nbd_send_negotiate(int csock, off_t size, uint32_t flags)
 
     /* Negotiate
         [ 0 ..   7]   passwd   ("NBDMAGIC")
-        [ 8 ..  15]   magic    (0x00420281861253)
+        [ 8 ..  15]   magic    (NBD_CLIENT_MAGIC)
         [16 ..  23]   size
         [24 ..  27]   flags
         [28 .. 151]   reserved (0)
@@ -224,7 +227,7 @@ static int nbd_send_negotiate(int csock, off_t size, uint32_t flags)
 
     TRACE("Beginning negotiation.");
     memcpy(buf, "NBDMAGIC", 8);
-    cpu_to_be64w((uint64_t*)(buf + 8), 0x00420281861253LL);
+    cpu_to_be64w((uint64_t*)(buf + 8), NBD_CLIENT_MAGIC);
     cpu_to_be64w((uint64_t*)(buf + 16), size);
     cpu_to_be32w((uint32_t*)(buf + 24),
                  flags | NBD_FLAG_HAS_FLAGS | NBD_FLAG_SEND_TRIM |
@@ -295,7 +298,7 @@ int nbd_receive_negotiate(int csock, const char *name, uint32_t *flags,
         uint32_t namesize;
 
         TRACE("Checking magic (opts_magic)");
-        if (magic != 0x49484156454F5054LL) {
+        if (magic != NBD_OPTS_MAGIC) {
             LOG("Bad magic received");
             goto fail;
         }
@@ -334,7 +337,7 @@ int nbd_receive_negotiate(int csock, const char *name, uint32_t *flags,
     } else {
         TRACE("Checking magic (cli_magic)");
 
-        if (magic != 0x00420281861253LL) {
+        if (magic != NBD_CLIENT_MAGIC) {
             LOG("Bad magic received");
             goto fail;
         }
@@ -477,7 +480,7 @@ int nbd_client(int fd)
 
 ssize_t nbd_send_request(int csock, struct nbd_request *request)
 {
-    uint8_t buf[4 + 4 + 8 + 8 + 4];
+    uint8_t buf[NBD_REQUEST_SIZE];
     ssize_t ret;
 
     cpu_to_be32w((uint32_t*)buf, NBD_REQUEST_MAGIC);
@@ -504,7 +507,7 @@ ssize_t nbd_send_request(int csock, struct nbd_request *request)
 
 static ssize_t nbd_receive_request(int csock, struct nbd_request *request)
 {
-    uint8_t buf[4 + 4 + 8 + 8 + 4];
+    uint8_t buf[NBD_REQUEST_SIZE];
     uint32_t magic;
     ssize_t ret;
 
@@ -582,7 +585,7 @@ ssize_t nbd_receive_reply(int csock, struct nbd_reply *reply)
 
 static ssize_t nbd_send_reply(int csock, struct nbd_reply *reply)
 {
-    uint8_t buf[4 + 4 + 8];
+    uint8_t buf[NBD_REPLY_SIZE];
     ssize_t ret;
 
     /* Reply


More information about the Spice-commits mailing list