Re: [Qemu-devel] [PATCH v3 1/6] RFC: Efficient VM backup for qemu

2013-02-20 Thread Markus Armbruster
Dietmar Maurer diet...@proxmox.com writes:

  * Backup to a single archive file
  * Backup contain all data to restore VM (full backup)
  * Do not depend on storage type or image format
  * Avoid use of temporary storage
  * store sparse images efficiently
 
 It is customary to send a 0/6 cover letter for details like this, rather than
 slamming it into the first patch (git send-email --cover-letter).

 But how do I maintain the content of that cover-letter when it is not
 part of the git tree?

Nothing stops you from committing it to your branch.  The extra commit
isn't sent out, of course.

I guess people usually archive it in e-mail instead.



[Qemu-devel] [PATCH 28/38] target-ppc: Compute addition carry with setcond

2013-02-20 Thread Richard Henderson
Cc: Alexander Graf ag...@suse.de
Signed-off-by: Richard Henderson r...@twiddle.net
---
 target-ppc/translate.c | 42 --
 1 file changed, 16 insertions(+), 26 deletions(-)

diff --git a/target-ppc/translate.c b/target-ppc/translate.c
index 116cf12..fce261b 100644
--- a/target-ppc/translate.c
+++ b/target-ppc/translate.c
@@ -768,36 +768,26 @@ static inline void gen_op_arith_compute_ov(DisasContext 
*ctx, TCGv arg0,
 static inline void gen_op_arith_compute_ca(DisasContext *ctx, TCGv arg1,
TCGv arg2, int sub)
 {
-int l1 = gen_new_label();
+TCGv t0 = tcg_temp_new(), t1 = arg1, t2 = arg2;
 
 #if defined(TARGET_PPC64)
 if (!(ctx-sf_mode)) {
-TCGv t0, t1;
-t0 = tcg_temp_new();
-t1 = tcg_temp_new();
-
-tcg_gen_ext32u_tl(t0, arg1);
-tcg_gen_ext32u_tl(t1, arg2);
-if (sub) {
-tcg_gen_brcond_tl(TCG_COND_GTU, t0, t1, l1);
-} else {
-tcg_gen_brcond_tl(TCG_COND_GEU, t0, t1, l1);
-}
-tcg_gen_movi_tl(cpu_ca, 1);
-gen_set_label(l1);
-tcg_temp_free(t0);
-tcg_temp_free(t1);
-} else
+t1 = t0;
+tcg_gen_ext32u_tl(t1, arg1);
+t2 = tcg_temp_new();
+tcg_gen_ext32u_tl(t2, arg2);
+}
 #endif
-{
-if (sub) {
-tcg_gen_brcond_tl(TCG_COND_GTU, arg1, arg2, l1);
-} else {
-tcg_gen_brcond_tl(TCG_COND_GEU, arg1, arg2, l1);
-}
-tcg_gen_movi_tl(cpu_ca, 1);
-gen_set_label(l1);
+
+tcg_gen_setcond_tl(sub ? TCG_COND_LEU : TCG_COND_LTU, t0, t1, t2);
+tcg_gen_or_tl(cpu_ca, cpu_ca, t0);
+
+tcg_temp_free(t0);
+#if defined(TARGET_PPC64)
+if (!(ctx-sf_mode)) {
+tcg_temp_free(t2);
 }
+#endif
 }
 
 /* Common add function */
@@ -811,7 +801,7 @@ static inline void gen_op_arith_add(DisasContext *ctx, TCGv 
ret, TCGv arg1,
 (!TCGV_EQUAL(ret,arg1)  !TCGV_EQUAL(ret, arg2)))  {
 t0 = ret;
 } else {
-t0 = tcg_temp_local_new();
+t0 = tcg_temp_new();
 }
 
 if (add_ca) {
-- 
1.8.1.2




[Qemu-devel] [PATCH 32/38] target-ppc: Compute mullwo without branches

2013-02-20 Thread Richard Henderson
Cc: Alexander Graf ag...@suse.de
Signed-off-by: Richard Henderson r...@twiddle.net
---
 target-ppc/translate.c | 42 ++
 1 file changed, 14 insertions(+), 28 deletions(-)

diff --git a/target-ppc/translate.c b/target-ppc/translate.c
index 439..f886441 100644
--- a/target-ppc/translate.c
+++ b/target-ppc/translate.c
@@ -1036,35 +1036,21 @@ static void gen_mullw(DisasContext *ctx)
 /* mullwo  mullwo. */
 static void gen_mullwo(DisasContext *ctx)
 {
-int l1;
-TCGv_i64 t0, t1;
+TCGv_i32 t0 = tcg_temp_new_i32();
+TCGv_i32 t1 = tcg_temp_new_i32();
 
-t0 = tcg_temp_new_i64();
-t1 = tcg_temp_new_i64();
-l1 = gen_new_label();
-/* Start with XER OV disabled, the most likely case */
-tcg_gen_movi_tl(cpu_ov, 0);
-#if defined(TARGET_PPC64)
-tcg_gen_ext32s_i64(t0, cpu_gpr[rA(ctx-opcode)]);
-tcg_gen_ext32s_i64(t1, cpu_gpr[rB(ctx-opcode)]);
-#else
-tcg_gen_ext_tl_i64(t0, cpu_gpr[rA(ctx-opcode)]);
-tcg_gen_ext_tl_i64(t1, cpu_gpr[rB(ctx-opcode)]);
-#endif
-tcg_gen_mul_i64(t0, t0, t1);
-#if defined(TARGET_PPC64)
-tcg_gen_ext32s_i64(cpu_gpr[rD(ctx-opcode)], t0);
-tcg_gen_brcond_i64(TCG_COND_EQ, t0, cpu_gpr[rD(ctx-opcode)], l1);
-#else
-tcg_gen_trunc_i64_tl(cpu_gpr[rD(ctx-opcode)], t0);
-tcg_gen_ext32s_i64(t1, t0);
-tcg_gen_brcond_i64(TCG_COND_EQ, t0, t1, l1);
-#endif
-tcg_gen_movi_tl(cpu_ov, 1);
-tcg_gen_movi_tl(cpu_so, 1);
-gen_set_label(l1);
-tcg_temp_free_i64(t0);
-tcg_temp_free_i64(t1);
+tcg_gen_trunc_tl_i32(t0, cpu_gpr[rA(ctx-opcode)]);
+tcg_gen_trunc_tl_i32(t1, cpu_gpr[rB(ctx-opcode)]);
+tcg_gen_muls2_i32(t0, t1, t0, t1);
+tcg_gen_ext_i32_tl(cpu_gpr[rD(ctx-opcode)], t0);
+
+tcg_gen_sari_i32(t0, t0, 31);
+tcg_gen_setcond_i32(TCG_COND_NE, t0, t0, t1);
+tcg_gen_extu_i32_tl(cpu_ov, t0);
+tcg_gen_or_tl(cpu_so, cpu_so, cpu_ov);
+
+tcg_temp_free_i32(t0);
+tcg_temp_free_i32(t1);
 if (unlikely(Rc(ctx-opcode) != 0))
 gen_set_Rc0(ctx, cpu_gpr[rD(ctx-opcode)]);
 }
-- 
1.8.1.2




Re: [Qemu-devel] [PATCH v12 rebased 2/8] start vm after resetting it

2013-02-20 Thread Hu Tao
On Thu, Feb 07, 2013 at 11:50:28PM -0200, Marcelo Tosatti wrote:
 On Wed, Jan 23, 2013 at 03:19:23PM +0800, Hu Tao wrote:
  From: Wen Congyang we...@cn.fujitsu.com
  
  The guest should run after resetting it, but it does not run if its
  old state is RUN_STATE_INTERNAL_ERROR or RUN_STATE_PAUSED.
  
  We don't set runstate to RUN_STATE_PAUSED when resetting the guest,
  so the runstate will be changed from RUN_STATE_INTERNAL_ERROR or
  RUN_STATE_PAUSED to RUN_STATE_RUNNING(not RUN_STATE_PAUSED).
 
 It appears the last hunk will automatically reset state from 
 RUN_STATE_INTERNAL_ERROR to RUN_STATE_RUNNING ?

Yes.

 
 I suppose the transition table allows, from RUN_STATE_INTERNAL_ERROR:
 
 monitor system_reset
 monitor cont
 
 To resume the machine?

True.

I think the purpose of this patch is to always reset and _run_ the guest
by `system_reset', avoiding an additional `cont' following `system_reset'.

 
  
  Signed-off-by: Wen Congyang we...@cn.fujitsu.com
  ---
   include/block/block.h | 2 ++
   qmp.c | 2 +-
   vl.c  | 7 ---
   3 files changed, 7 insertions(+), 4 deletions(-)
  
  diff --git a/include/block/block.h b/include/block/block.h
  index ffd1936..5e82ccb 100644
  --- a/include/block/block.h
  +++ b/include/block/block.h
  @@ -366,6 +366,8 @@ void bdrv_disable_copy_on_read(BlockDriverState *bs);
   void bdrv_set_in_use(BlockDriverState *bs, int in_use);
   int bdrv_in_use(BlockDriverState *bs);
   
  +void iostatus_bdrv_it(void *opaque, BlockDriverState *bs);
  +
   #ifdef CONFIG_LINUX_AIO
   int raw_get_aio_fd(BlockDriverState *bs);
   #else
  diff --git a/qmp.c b/qmp.c
  index 55b056b..5f1bed1 100644
  --- a/qmp.c
  +++ b/qmp.c
  @@ -130,7 +130,7 @@ SpiceInfo *qmp_query_spice(Error **errp)
   };
   #endif
   
  -static void iostatus_bdrv_it(void *opaque, BlockDriverState *bs)
  +void iostatus_bdrv_it(void *opaque, BlockDriverState *bs)
   {
   bdrv_iostatus_reset(bs);
   }
  diff --git a/vl.c b/vl.c
  index b0bcf1e..1d2edaa 100644
  --- a/vl.c
  +++ b/vl.c
  @@ -534,7 +534,7 @@ static const RunStateTransition 
  runstate_transitions_def[] = {
   { RUN_STATE_INMIGRATE, RUN_STATE_RUNNING },
   { RUN_STATE_INMIGRATE, RUN_STATE_PAUSED },
   
  -{ RUN_STATE_INTERNAL_ERROR, RUN_STATE_PAUSED },
  +{ RUN_STATE_INTERNAL_ERROR, RUN_STATE_RUNNING },
   { RUN_STATE_INTERNAL_ERROR, RUN_STATE_FINISH_MIGRATE },
   
   { RUN_STATE_IO_ERROR, RUN_STATE_RUNNING },
  @@ -569,7 +569,7 @@ static const RunStateTransition 
  runstate_transitions_def[] = {
   
   { RUN_STATE_SAVE_VM, RUN_STATE_RUNNING },
   
  -{ RUN_STATE_SHUTDOWN, RUN_STATE_PAUSED },
  +{ RUN_STATE_SHUTDOWN, RUN_STATE_RUNNING },
   { RUN_STATE_SHUTDOWN, RUN_STATE_FINISH_MIGRATE },
   
   { RUN_STATE_DEBUG, RUN_STATE_SUSPENDED },
  @@ -1951,7 +1951,8 @@ static bool main_loop_should_exit(void)
   resume_all_vcpus();
   if (runstate_check(RUN_STATE_INTERNAL_ERROR) ||
   runstate_check(RUN_STATE_SHUTDOWN)) {
  -runstate_set(RUN_STATE_PAUSED);
  +bdrv_iterate(iostatus_bdrv_it, NULL);
  +vm_start();
   }
   }
   if (qemu_wakeup_requested()) {
  -- 
  1.8.0.1.240.ge8a1f5a
  
  --
  To unsubscribe from this list: send the line unsubscribe kvm in
  the body of a message to majord...@vger.kernel.org
  More majordomo info at  http://vger.kernel.org/majordomo-info.html

-- 
Regards,
Hu Tao



Re: [Qemu-devel] [RFC PATCH 03/10] qemu-ga: Add an configure option to specify path to Windows VSS SDK

2013-02-20 Thread Tomoki Sekiyama
On 2013/02/19 9:15, mdroth wrote:
 On Fri, Feb 15, 2013 at 12:55:49PM +0900, Tomoki Sekiyama wrote:
 On 2013/02/15 9:47, mdroth wrote:
 [...]

 Hi Tomoki,

 Hi,

 Did you happen to run into this issue compiling the test program?

 [mdroth@vm qemu-build]$ ls ~/w/vsssdk/inc/win2003/
 vdslun.hvsbackup.hvscoordint.idl  vsmgmt.idl  vsprov.idl
 vss.idlvsswprv.idl
 vdslun.idl  vscoordint.h  vsmgmt.hvsprov.hvss.h
 vsswprv.h  vswriter.h
 [mdroth@vm qemu-build]$ cat test.c
 #define __MIDL_user_allocate_free_DEFINED__
 #include inc/win2003/vss.h
 int main(void) { return VSS_CTX_BACKUP; }
 [mdroth@vm qemu-build]$ gcc -I ~/w/vsssdk/ -o test test.c
 In file included from test.c:2:0:
 /home/mdroth/w/vsssdk/inc/win2003/vss.h:25:17: fatal error: rpc.h: No
 such file or directory
 compilation terminated.

 I can't seem to locate any mingw or microsoft package that provides that.
 It's also not present anywhere on the Wine filesystem I installed the
 VSS SDK to.


 Hmm, I haven't seen this yet.
 I am testing this on Fedora 18 x86_64 host, and it provides package
 mingw32-headers.noarch or mingw64-headers.noarch which contains
 the rpc.h
 (filepath is /usr/x86_64-w64-mingw32/sys-root/mingw/include/rpc.h )
 
 Thanks. I actually did have that header, but I was doing something silly
 (forgot to use cross-compiler for the test program). The configure issue
 I was hitting was also an error on my part (options with ~ weren't
 resolving to my home dir). I did end up missing ntverp.h however in
 vss-win32.h using Fedora 15. I made some progress trying the build
 without it however. Can you confirm all the headers in vss-win32.h are
 needed? 

Some of headers in vss-win32.h (nterp,h, rpc.h, rpcndr.h, etc) seems
needed to build qemu-ga.exe in a native build environment(mingw on Windows).
In my Fedora 18 environment, these don't cause errors, but it also
succeeded to build even without the headers.

 I went ahead and put together an FC18 environment, but would be
 nice if we can get this building for older environments (if possible).

I will try this with some of my old VMs and investigate which headers
are really needed.

Thanks,
-- 
Tomoki Sekiyama




[Qemu-devel] [PATCH 08/38] tcg: Implement multiword addition helpers

2013-02-20 Thread Richard Henderson
Signed-off-by: Richard Henderson r...@twiddle.net
---
 tcg/tcg-op.h | 82 
 1 file changed, 82 insertions(+)

diff --git a/tcg/tcg-op.h b/tcg/tcg-op.h
index 97e0795..dac3b4e 100644
--- a/tcg/tcg-op.h
+++ b/tcg/tcg-op.h
@@ -2332,6 +2332,44 @@ static inline void tcg_gen_movcond_i64(TCGCond cond, 
TCGv_i64 ret,
 #endif
 }
 
+static inline void tcg_gen_add2_i32(TCGv_i32 rl, TCGv_i32 rh, TCGv_i32 al,
+TCGv_i32 ah, TCGv_i32 bl, TCGv_i32 bh)
+{
+if (TCG_TARGET_HAS_add2_i32) {
+tcg_gen_op6_i32(INDEX_op_add2_i32, rl, rh, al, ah, bl, bh);
+/* Allow the optimizer room to replace add2 with two moves.  */
+tcg_gen_op0(INDEX_op_nop);
+} else {
+TCGv_i64 t0 = tcg_temp_new_i64();
+TCGv_i64 t1 = tcg_temp_new_i64();
+tcg_gen_concat_i32_i64(t0, al, ah);
+tcg_gen_concat_i32_i64(t1, bl, bh);
+tcg_gen_add_i64(t0, t0, t1);
+tcg_gen_extr_i64_i32(rl, rh, t0);
+tcg_temp_free_i64(t0);
+tcg_temp_free_i64(t1);
+}
+}
+
+static inline void tcg_gen_sub2_i32(TCGv_i32 rl, TCGv_i32 rh, TCGv_i32 al,
+TCGv_i32 ah, TCGv_i32 bl, TCGv_i32 bh)
+{
+if (TCG_TARGET_HAS_sub2_i32) {
+tcg_gen_op6_i32(INDEX_op_sub2_i32, rl, rh, al, ah, bl, bh);
+/* Allow the optimizer room to replace sub2 with two moves.  */
+tcg_gen_op0(INDEX_op_nop);
+} else {
+TCGv_i64 t0 = tcg_temp_new_i64();
+TCGv_i64 t1 = tcg_temp_new_i64();
+tcg_gen_concat_i32_i64(t0, al, ah);
+tcg_gen_concat_i32_i64(t1, bl, bh);
+tcg_gen_sub_i64(t0, t0, t1);
+tcg_gen_extr_i64_i32(rl, rh, t0);
+tcg_temp_free_i64(t0);
+tcg_temp_free_i64(t1);
+}
+}
+
 static inline void tcg_gen_mulu2_i32(TCGv_i32 rl, TCGv_i32 rh,
  TCGv_i32 arg1, TCGv_i32 arg2)
 {
@@ -2370,6 +2408,46 @@ static inline void tcg_gen_muls2_i32(TCGv_i32 rl, 
TCGv_i32 rh,
 }
 }
 
+static inline void tcg_gen_add2_i64(TCGv_i64 rl, TCGv_i64 rh, TCGv_i64 al,
+TCGv_i64 ah, TCGv_i64 bl, TCGv_i64 bh)
+{
+if (TCG_TARGET_HAS_add2_i64) {
+tcg_gen_op6_i64(INDEX_op_add2_i64, rl, rh, al, ah, bl, bh);
+/* Allow the optimizer room to replace add2 with two moves.  */
+tcg_gen_op0(INDEX_op_nop);
+} else {
+TCGv_i64 t0 = tcg_temp_new_i64();
+TCGv_i64 t1 = tcg_temp_new_i64();
+tcg_gen_add_i64(t0, al, bl);
+tcg_gen_setcond_i64(TCG_COND_LTU, t1, t0, al);
+tcg_gen_add_i64(rh, ah, bh);
+tcg_gen_add_i64(rh, rh, t1);
+tcg_gen_mov_i64(rl, t0);
+tcg_temp_free_i64(t0);
+tcg_temp_free_i64(t1);
+}
+}
+
+static inline void tcg_gen_sub2_i64(TCGv_i64 rl, TCGv_i64 rh, TCGv_i64 al,
+TCGv_i64 ah, TCGv_i64 bl, TCGv_i64 bh)
+{
+if (TCG_TARGET_HAS_sub2_i64) {
+tcg_gen_op6_i64(INDEX_op_sub2_i64, rl, rh, al, ah, bl, bh);
+/* Allow the optimizer room to replace sub2 with two moves.  */
+tcg_gen_op0(INDEX_op_nop);
+} else {
+TCGv_i64 t0 = tcg_temp_new_i64();
+TCGv_i64 t1 = tcg_temp_new_i64();
+tcg_gen_sub_i64(t0, al, bl);
+tcg_gen_setcond_i64(TCG_COND_LTU, t1, al, bl);
+tcg_gen_sub_i64(rh, ah, bh);
+tcg_gen_sub_i64(rh, rh, t1);
+tcg_gen_mov_i64(rl, t0);
+tcg_temp_free_i64(t0);
+tcg_temp_free_i64(t1);
+}
+}
+
 static inline void tcg_gen_mulu2_i64(TCGv_i64 rl, TCGv_i64 rh,
  TCGv_i64 arg1, TCGv_i64 arg2)
 {
@@ -2739,6 +2817,8 @@ static inline void tcg_gen_qemu_st64(TCGv_i64 arg, TCGv 
addr, int mem_index)
 #define tcg_const_tl tcg_const_i64
 #define tcg_const_local_tl tcg_const_local_i64
 #define tcg_gen_movcond_tl tcg_gen_movcond_i64
+#define tcg_gen_add2_tl tcg_gen_add2_i64
+#define tcg_gen_sub2_tl tcg_gen_sub2_i64
 #define tcg_gen_mulu2_tl tcg_gen_mulu2_i64
 #define tcg_gen_muls2_tl tcg_gen_muls2_i64
 #else
@@ -2814,6 +2894,8 @@ static inline void tcg_gen_qemu_st64(TCGv_i64 arg, TCGv 
addr, int mem_index)
 #define tcg_const_tl tcg_const_i32
 #define tcg_const_local_tl tcg_const_local_i32
 #define tcg_gen_movcond_tl tcg_gen_movcond_i32
+#define tcg_gen_add2_tl tcg_gen_add2_i32
+#define tcg_gen_sub2_tl tcg_gen_sub2_i32
 #define tcg_gen_mulu2_tl tcg_gen_mulu2_i32
 #define tcg_gen_muls2_tl tcg_gen_muls2_i32
 #endif
-- 
1.8.1.2




Re: [Qemu-devel] [PATCH] machine: correct macro name for default boot_order

2013-02-20 Thread Markus Armbruster
liguang lig.f...@cn.fujitsu.com writes:

 DEFAULT_MACHINE_OPTIONS is setting default boot_order,
 while QEMUMachine already has default_machine_opts
 to encapsulate some default options, so change it to
 DEFAULT_MACHINE_BOOT_ORDER.

Right now, DEFAULT_MACHINE_OPTIONS contains just a .boot_order
initializer.  But that's not necessarily so; it could contain anything.
Avik, Anthony, you wrote or reviewed the patch that added it, what do
you think?



Re: [Qemu-devel] [PATCH 1/4] configure: Add --enable-migration-from-qemu-kvm

2013-02-20 Thread Michael Tokarev
20.02.2013 02:39, Cole Robinson wrote:
 This switch will turn on all the migration compat bits needed to
 perform migration from qemu-kvm to qemu. It's just a stub for now.
 
 This compat will break incoming migration from qemu  1.3, but for
 distros where qemu-kvm was the only shipped package for years it's
 not a big loss (and I don't know any way to avoid it).

Actually I think it is relatively easy to support migration from BOTH
qemu and qemu-kvm.  By adding a _runtime_ command-line switch (such as
--qemu-kvm-compat, which has been already mentioned in other context),
which modifies that migration stuff (machine definitions) in a reasonable
way.  It can be done based on this patchset I guess (when it will be
polished and proven to work well).  And after that is done, this
configure option can go away.

How do you guys think?

Thanks!

/mjt



[Qemu-devel] [PATCH v2] vga: fix byteswapping.

2013-02-20 Thread Gerd Hoffmann
In case host and guest endianness differ the vga code first creates
a shared surface (using qemu_create_displaysurface_from), then goes
patch the surface format to indicate that the bytes must be swapped.

The switch to pixman broke that hack as the format patching isn't
propagated into the pixman image, so ui code using the pixman image
directly (such as vnc) uses the wrong format.

Fix that by adding a byteswap parameter to
qemu_create_displaysurface_from, so we'll use the correct format
when creating the surface (and the pixman image) and don't have
to patch the format afterwards.

[ v2: unbreak xen build ]

Cc: qemu-sta...@nongnu.org
Cc: mark.cave-ayl...@ilande.co.uk
Cc: ag...@suse.de
Signed-off-by: Gerd Hoffmann kra...@redhat.com
---
 hw/qxl-render.c  |3 ++-
 hw/vga.c |   18 --
 hw/vmware_vga.c  |2 +-
 hw/xenfb.c   |3 ++-
 include/ui/console.h |3 ++-
 ui/console.c |9 +++--
 6 files changed, 22 insertions(+), 16 deletions(-)

diff --git a/hw/qxl-render.c b/hw/qxl-render.c
index 88e63f8..455fb91 100644
--- a/hw/qxl-render.c
+++ b/hw/qxl-render.c
@@ -118,7 +118,8 @@ static void qxl_render_update_area_unlocked(PCIQXLDevice 
*qxl)
  qxl-guest_primary.surface.height,
  qxl-guest_primary.bits_pp,
  qxl-guest_primary.abs_stride,
- qxl-guest_primary.data);
+ qxl-guest_primary.data,
+ false);
 } else {
 qemu_resize_displaysurface(vga-ds,
 qxl-guest_primary.surface.width,
diff --git a/hw/vga.c b/hw/vga.c
index e2ba7f2..1caf23d 100644
--- a/hw/vga.c
+++ b/hw/vga.c
@@ -1643,6 +1643,11 @@ static void vga_draw_graphic(VGACommonState *s, int 
full_update)
 uint8_t *d;
 uint32_t v, addr1, addr;
 vga_draw_line_func *vga_draw_line;
+#if defined(HOST_WORDS_BIGENDIAN) == defined(TARGET_WORDS_BIGENDIAN)
+static const bool byteswap = false;
+#else
+static const bool byteswap = true;
+#endif
 
 full_update |= update_basic_params(s);
 
@@ -1685,18 +1690,11 @@ static void vga_draw_graphic(VGACommonState *s, int 
full_update)
 disp_width != s-last_width ||
 height != s-last_height ||
 s-last_depth != depth) {
-#if defined(HOST_WORDS_BIGENDIAN) == defined(TARGET_WORDS_BIGENDIAN)
-if (depth == 16 || depth == 32) {
-#else
-if (depth == 32) {
-#endif
+if (depth == 32 || (depth == 16  !byteswap)) {
 qemu_free_displaysurface(s-ds);
 s-ds-surface = qemu_create_displaysurface_from(disp_width, 
height, depth,
 s-line_offset,
-s-vram_ptr + (s-start_addr * 4));
-#if defined(HOST_WORDS_BIGENDIAN) != defined(TARGET_WORDS_BIGENDIAN)
-s-ds-surface-pf = qemu_different_endianness_pixelformat(depth);
-#endif
+s-vram_ptr + (s-start_addr * 4), byteswap);
 dpy_gfx_resize(s-ds);
 } else {
 qemu_console_resize(s-ds, disp_width, height);
@@ -1715,7 +1713,7 @@ static void vga_draw_graphic(VGACommonState *s, int 
full_update)
 s-ds-surface = qemu_create_displaysurface_from(disp_width,
 height, depth,
 s-line_offset,
-s-vram_ptr + (s-start_addr * 4));
+s-vram_ptr + (s-start_addr * 4), byteswap);
 dpy_gfx_setdata(s-ds);
 }
 
diff --git a/hw/vmware_vga.c b/hw/vmware_vga.c
index cd15ee4..8fc201b 100644
--- a/hw/vmware_vga.c
+++ b/hw/vmware_vga.c
@@ -1074,7 +1074,7 @@ static void vmsvga_screen_dump(void *opaque, const char 
*filename, bool cswitch,
  ds_get_height(s-vga.ds),
  32,
  ds_get_linesize(s-vga.ds),
- s-vga.vram_ptr);
+ s-vga.vram_ptr, false);
 ppm_save(filename, ds, errp);
 g_free(ds);
 }
diff --git a/hw/xenfb.c b/hw/xenfb.c
index 903efd3..7f1f6b4 100644
--- a/hw/xenfb.c
+++ b/hw/xenfb.c
@@ -756,7 +756,8 @@ static void xenfb_update(void *opaque)
 qemu_free_displaysurface(xenfb-c.ds);
 xenfb-c.ds-surface = qemu_create_displaysurface_from
 (xenfb-width, xenfb-height, xenfb-depth,
- xenfb-row_stride, xenfb-pixels + xenfb-offset);
+ xenfb-row_stride, xenfb-pixels + xenfb-offset,
+ false);
 break;
 default:
 /* we must convert stuff */
diff --git a/include/ui/console.h b/include/ui/console.h
index fc23baa..18012f1 100644
--- a/include/ui/console.h
+++ b/include/ui/console.h
@@ -184,7 +184,8 @@ struct DisplayState {
 void register_displaystate(DisplayState *ds);
 DisplayState *get_displaystate(void);
 DisplaySurface* qemu_create_displaysurface_from(int width, int height, int bpp,
-int linesize, uint8_t *data);
+  

Re: [Qemu-devel] using -net dump with tap networking

2013-02-20 Thread Stefan Hajnoczi
On Tue, Feb 19, 2013 at 09:16:56PM +0100, Laszlo Ersek wrote:
 On 02/19/13 18:50, Markus Armbruster wrote:
 
  Your example uses -net to connect additional backends to the hubport.
  If I understand you correctly, you can't use -netdev to do that.
  Ignorant question: fundamental reason or just not implemented?
 In order to take a stab at your question at last:
 - the two (parallel, opposing) links created in (3) connect two backends,
 - -netdev does not set the peer link in the backend, so you cannot use
 that,
 - -device *would* set the links in both directions, but it's for
 creating frontends.
 
 IOW (3) is unique because it links backend to backend.

Right.  -netdev doesn't allow you to specify a peer, only NICs (-device)
do that.

This means there is no way to hook up -netdev dump with -netdev hubport,
they are both -netdevs :(.

This is why I said it's just playing games with syntax.  I don't think
it buys us anything in the end.

Stefan



Re: [Qemu-devel] using -net dump with tap networking

2013-02-20 Thread Stefan Hajnoczi
On Tue, Feb 19, 2013 at 06:50:22PM +0100, Markus Armbruster wrote:
 Stefan Hajnoczi stefa...@gmail.com writes:
 
  On Tue, Feb 19, 2013 at 09:53:07AM +0100, Markus Armbruster wrote:
  Stefan Hajnoczi stefa...@redhat.com writes:
  
   On Tue, Feb 19, 2013 at 12:37:28PM +1100, Alexey Kardashevskiy wrote:
   On 14/02/13 21:26, Stefan Hajnoczi wrote:
   
   Now I want to enable network dump. With the old -net syntax
I could do
   that with -net dump but I cannot with the new syntax, tried many
   variants, none works. What would the correct syntax be for
the case above?
   
   The question was about new -netdev interface.
   
   I would do:
   
   qemu-system-ppc64 ...
  -net tap,ifname=tap0,script=qemu-ifup.sh
  -net nic,model=virtio
  -net dump,file=./dump.lan.qemu.virtio
   
   
   The answer is about old -net interface which I know how to use.
   
   Does this mean that there is no way to use dump with -netdev tap?
  
   It is not possible using just -netdev/-device.  The closest you can get
   is:
  
 $ qemu -netdev hubport,hubid=1,id=hubport0 \
-device virtio-net-pci,netdev=hubport0,... \
 -net tap,vlan=1,... \
 -net dump,vlan=1,...
  
  Care to explain briefly how hubport works, and how it's connected to the
  legacy vlan feature?
 
  -netdev hubport instantiates a new port on a hub with vlan number
  hubid=number.
 
  hubport is a -netdev, so it allows you to hook up a NIC to a hub using
  -netdev/-device syntax.
 
  This is just playing games with syntax, we still have a hub in between
  the virtio-net-pci, tap, and dump devices.  I didn't check if the
  offload features get plumbed through, but I wouldn't count on it.
 
 Thanks.
 
 Would you mind documenting net backend hubport in qemu-options.hx?  Was
 forgotten in commit f6c874e3.

Sure.

Stefan



[Qemu-devel] [PATCH 12/38] target-i386: Use add2 to implement the ADX extension

2013-02-20 Thread Richard Henderson
Signed-off-by: Richard Henderson r...@twiddle.net
---
 target-i386/translate.c | 20 +---
 1 file changed, 9 insertions(+), 11 deletions(-)

diff --git a/target-i386/translate.c b/target-i386/translate.c
index 1545e3f..3b92f3b 100644
--- a/target-i386/translate.c
+++ b/target-i386/translate.c
@@ -4169,7 +4169,7 @@ static void gen_sse(CPUX86State *env, DisasContext *s, 
int b,
 if (!(s-cpuid_7_0_ebx_features  CPUID_7_0_EBX_ADX)) {
 goto illegal_op;
 } else {
-TCGv carry_in, carry_out;
+TCGv carry_in, carry_out, zero;
 int end_op;
 
 ot = (s-dflag == 2 ? OT_QUAD : OT_LONG);
@@ -4229,18 +4229,16 @@ static void gen_sse(CPUX86State *env, DisasContext *s, 
int b,
 #endif
 default:
 /* Otherwise compute the carry-out in two steps.  */
-tcg_gen_add_tl(cpu_T[0], cpu_T[0], cpu_regs[reg]);
-tcg_gen_setcond_tl(TCG_COND_LTU, cpu_tmp4,
-   cpu_T[0], cpu_regs[reg]);
-tcg_gen_add_tl(cpu_regs[reg], cpu_T[0], carry_in);
-tcg_gen_setcond_tl(TCG_COND_LTU, carry_out,
-   cpu_regs[reg], cpu_T[0]);
-tcg_gen_or_tl(carry_out, carry_out, cpu_tmp4);
+zero = tcg_const_tl(0);
+tcg_gen_add2_tl(cpu_T[0], carry_out,
+cpu_T[0], zero,
+carry_in, zero);
+tcg_gen_add2_tl(cpu_regs[reg], carry_out,
+cpu_regs[reg], carry_out,
+cpu_T[0], zero);
+tcg_temp_free(zero);
 break;
 }
-/* We began with all flags computed to CC_SRC, and we
-   have now placed the carry-out in CC_DST.  All that
-   is left is to record the CC_OP.  */
 set_cc_op(s, end_op);
 }
 break;
-- 
1.8.1.2




[Qemu-devel] [PATCH 33/38] target-sparc: Use official add2/sub2 interfaces for addx/subx

2013-02-20 Thread Richard Henderson
Cc: Blue Swirl blauwir...@gmail.com
Signed-off-by: Richard Henderson r...@twiddle.net
---
 target-sparc/translate.c | 42 --
 1 file changed, 16 insertions(+), 26 deletions(-)

diff --git a/target-sparc/translate.c b/target-sparc/translate.c
index ca75e1a..d3e2acf 100644
--- a/target-sparc/translate.c
+++ b/target-sparc/translate.c
@@ -448,19 +448,16 @@ static void gen_op_addx_int(DisasContext *dc, TCGv dst, 
TCGv src1,
 case CC_OP_ADD:
 case CC_OP_TADD:
 case CC_OP_TADDTV:
-#if TCG_TARGET_REG_BITS == 32  TARGET_LONG_BITS == 32
-{
-/* For 32-bit hosts, we can re-use the host's hardware carry
-   generation by using an ADD2 opcode.  We discard the low
-   part of the output.  Ideally we'd combine this operation
-   with the add that generated the carry in the first place.  */
-TCGv dst_low = tcg_temp_new();
-tcg_gen_op6_i32(INDEX_op_add2_i32, dst_low, dst,
-cpu_cc_src, src1, cpu_cc_src2, src2);
-tcg_temp_free(dst_low);
+if (TARGET_LONG_BITS == 32) {
+/* We can re-use the host's hardware carry generation by using
+   an ADD2 opcode.  We discard the low part of the output.
+   Ideally we'd combine this operation with the add that
+   generated the carry in the first place.  */
+carry = tcg_temp_new();
+tcg_gen_add2_tl(carry, dst, cpu_cc_src, src1, cpu_cc_src2, src2);
+tcg_temp_free(carry);
 goto add_done;
 }
-#endif
 carry_32 = gen_add32_carry32();
 break;
 
@@ -492,9 +489,7 @@ static void gen_op_addx_int(DisasContext *dc, TCGv dst, 
TCGv src1,
 tcg_temp_free(carry);
 #endif
 
-#if TCG_TARGET_REG_BITS == 32  TARGET_LONG_BITS == 32
  add_done:
-#endif
 if (update_cc) {
 tcg_gen_mov_tl(cpu_cc_src, src1);
 tcg_gen_mov_tl(cpu_cc_src2, src2);
@@ -554,19 +549,16 @@ static void gen_op_subx_int(DisasContext *dc, TCGv dst, 
TCGv src1,
 case CC_OP_SUB:
 case CC_OP_TSUB:
 case CC_OP_TSUBTV:
-#if TCG_TARGET_REG_BITS == 32  TARGET_LONG_BITS == 32
-{
-/* For 32-bit hosts, we can re-use the host's hardware carry
-   generation by using a SUB2 opcode.  We discard the low
-   part of the output.  Ideally we'd combine this operation
-   with the add that generated the carry in the first place.  */
-TCGv dst_low = tcg_temp_new();
-tcg_gen_op6_i32(INDEX_op_sub2_i32, dst_low, dst,
-cpu_cc_src, src1, cpu_cc_src2, src2);
-tcg_temp_free(dst_low);
+if (TARGET_LONG_BITS == 32) {
+/* We can re-use the host's hardware carry generation by using
+   a SUB2 opcode.  We discard the low part of the output.
+   Ideally we'd combine this operation with the add that
+   generated the carry in the first place.  */
+carry = tcg_temp_new();
+tcg_gen_sub2_tl(carry, dst, cpu_cc_src, src1, cpu_cc_src2, src2);
+tcg_temp_free(carry);
 goto sub_done;
 }
-#endif
 carry_32 = gen_sub32_carry32();
 break;
 
@@ -592,9 +584,7 @@ static void gen_op_subx_int(DisasContext *dc, TCGv dst, 
TCGv src1,
 tcg_temp_free(carry);
 #endif
 
-#if TCG_TARGET_REG_BITS == 32  TARGET_LONG_BITS == 32
  sub_done:
-#endif
 if (update_cc) {
 tcg_gen_mov_tl(cpu_cc_src, src1);
 tcg_gen_mov_tl(cpu_cc_src2, src2);
-- 
1.8.1.2




Re: [Qemu-devel] High memory usage by multiqueue

2013-02-20 Thread Jason Wang
On 02/20/2013 02:59 AM, Edivaldo de Araujo Pereira wrote:
 Dear Jason,

 In the last 2 weeks, I noticed a significant increase in the memory usage of 
 qemu. Just to assess the stability of my system, I usually run a kind of 
 stress test, every time I install a new kernel in my host or in a custom VM 
 that I use in my classes, or when I compile a new snapshot of qemu. 

 The test is quite simple, but somewhat brutal: 200 qemu guests (1 cpu, 256MB, 
 no hd) running on a single host (4 core, 8 threads, 8GB). It's obvious that 
 such thing doesn't serve any purpose other than to say it runs... 80% of all 
 memory and 35% of all processing just to make 200 guests little more than 
 idle... But the point is, when everything is ok, it runs very well, and I can 
 even put some 240Mbits of traffic in the virtual net.

 In my tests, each VM uses ~180MB (thanks to ksm, 200*180MB8GB); but in 
 recent weeks, the memory footprint of the MVs jumped to ~230MB, along whith 
 some change in its behaviour that rends completely broken the magic of ksm 
 (at least in my test); in other words, I can no more run 200 guests in my 
 machine.

 So I did a git bisect, as Stefan told some time ago, and I found the 
 problem is related to multiqueue support. More precisely, the constant 
 MAX_QUEUE_NUM 1024 in include/net/net.h.

 As long as I understand, such a high number of queues is at least a little 
 bit out of reality... Wouldn't it imply having possibly that number of 
 threads runing network traffic? Problem is, I can not imagine the total 
 number of logical processors a guest would need to have, just to take 
 advantage of such a number of network traffic thhreads. By the way, that 
 number is many times higher than supported by any physical network adapter I 
 have read about.

 So I've tampered a little with that number, and found that setting it to 4 or 
 8 reduces drastically the memory usage, without disrupting any network 
 function (in my test...); yet this is twice the numbers of some examples I've 
 seen in wmware related texts. The good news: my stress test runs smoothly 
 again... well, almost, for I'm not using multiqueue yet...

 So, I think it would be good to find a better approach; dynamic allocation 
 would be nice, in accordance with command line parameters, wouldn't it?

Yes, it's a bug. The dynamic allocation is better(1.5). For 1.4, I think
we can simply limit the number to 8. Will post the patch.

Thanks

 Thank you, very much

 Edivaldo de Araújo Pereira





[Qemu-devel] [PATCH 30/38] target-ppc: Implement neg in terms of subf

2013-02-20 Thread Richard Henderson
Cc: Alexander Graf ag...@suse.de
Signed-off-by: Richard Henderson r...@twiddle.net
---
 target-ppc/translate.c | 63 +++---
 1 file changed, 19 insertions(+), 44 deletions(-)

diff --git a/target-ppc/translate.c b/target-ppc/translate.c
index abc75e2..05f93f6 100644
--- a/target-ppc/translate.c
+++ b/target-ppc/translate.c
@@ -1121,50 +1121,6 @@ static void gen_mulldo(DisasContext *ctx)
 }
 #endif
 
-/* neg neg. nego nego. */
-static inline void gen_op_arith_neg(DisasContext *ctx, TCGv ret, TCGv arg1,
-int ov_check)
-{
-int l1 = gen_new_label();
-int l2 = gen_new_label();
-TCGv t0 = tcg_temp_local_new();
-#if defined(TARGET_PPC64)
-if (ctx-sf_mode) {
-tcg_gen_mov_tl(t0, arg1);
-tcg_gen_brcondi_tl(TCG_COND_EQ, t0, INT64_MIN, l1);
-} else
-#endif
-{
-tcg_gen_ext32s_tl(t0, arg1);
-tcg_gen_brcondi_tl(TCG_COND_EQ, t0, INT32_MIN, l1);
-}
-tcg_gen_neg_tl(ret, arg1);
-if (ov_check) {
-tcg_gen_movi_tl(cpu_ov, 0);
-}
-tcg_gen_br(l2);
-gen_set_label(l1);
-tcg_gen_mov_tl(ret, t0);
-if (ov_check) {
-tcg_gen_movi_tl(cpu_ov, 1);
-tcg_gen_movi_tl(cpu_so, 1);
-}
-gen_set_label(l2);
-tcg_temp_free(t0);
-if (unlikely(Rc(ctx-opcode) != 0))
-gen_set_Rc0(ctx, ret);
-}
-
-static void gen_neg(DisasContext *ctx)
-{
-gen_op_arith_neg(ctx, cpu_gpr[rD(ctx-opcode)], cpu_gpr[rA(ctx-opcode)], 
0);
-}
-
-static void gen_nego(DisasContext *ctx)
-{
-gen_op_arith_neg(ctx, cpu_gpr[rD(ctx-opcode)], cpu_gpr[rA(ctx-opcode)], 
1);
-}
-
 /* Common subf function */
 static inline void gen_op_arith_subf(DisasContext *ctx, TCGv ret, TCGv arg1,
  TCGv arg2, bool add_ca, bool compute_ca,
@@ -1254,6 +1210,25 @@ static void gen_subfic(DisasContext *ctx)
 tcg_temp_free(c);
 }
 
+/* neg neg. nego nego. */
+static inline void gen_op_arith_neg(DisasContext *ctx, bool compute_ov)
+{
+TCGv zero = tcg_const_tl(0);
+gen_op_arith_subf(ctx, cpu_gpr[rD(ctx-opcode)], cpu_gpr[rA(ctx-opcode)],
+  zero, 0, 0, compute_ov, Rc(ctx-opcode));
+tcg_temp_free(zero);
+}
+
+static void gen_neg(DisasContext *ctx)
+{
+gen_op_arith_neg(ctx, 0);
+}
+
+static void gen_nego(DisasContext *ctx)
+{
+gen_op_arith_neg(ctx, 1);
+}
+
 /***Integer logical***/
 #define GEN_LOGICAL2(name, tcg_op, opc, type) \
 static void glue(gen_, name)(DisasContext *ctx)
   \
-- 
1.8.1.2




[Qemu-devel] [PATCH 36/38] target-unicore32: Use mul*2 for do_mult

2013-02-20 Thread Richard Henderson
Cc: Guan Xuetao g...@mprc.pku.edu.cn
Signed-off-by: Richard Henderson r...@twiddle.net
---
 target-unicore32/translate.c | 83 ++--
 1 file changed, 11 insertions(+), 72 deletions(-)

diff --git a/target-unicore32/translate.c b/target-unicore32/translate.c
index f4498bc..d5039e2 100644
--- a/target-unicore32/translate.c
+++ b/target-unicore32/translate.c
@@ -267,37 +267,6 @@ static void gen_exception(int excp)
 dead_tmp(tmp);
 }
 
-/* FIXME: Most targets have native widening multiplication.
-   It would be good to use that instead of a full wide multiply.  */
-/* 32x32-64 multiply.  Marks inputs as dead.  */
-static TCGv_i64 gen_mulu_i64_i32(TCGv a, TCGv b)
-{
-TCGv_i64 tmp1 = tcg_temp_new_i64();
-TCGv_i64 tmp2 = tcg_temp_new_i64();
-
-tcg_gen_extu_i32_i64(tmp1, a);
-dead_tmp(a);
-tcg_gen_extu_i32_i64(tmp2, b);
-dead_tmp(b);
-tcg_gen_mul_i64(tmp1, tmp1, tmp2);
-tcg_temp_free_i64(tmp2);
-return tmp1;
-}
-
-static TCGv_i64 gen_muls_i64_i32(TCGv a, TCGv b)
-{
-TCGv_i64 tmp1 = tcg_temp_new_i64();
-TCGv_i64 tmp2 = tcg_temp_new_i64();
-
-tcg_gen_ext_i32_i64(tmp1, a);
-dead_tmp(a);
-tcg_gen_ext_i32_i64(tmp2, b);
-dead_tmp(b);
-tcg_gen_mul_i64(tmp1, tmp1, tmp2);
-tcg_temp_free_i64(tmp2);
-return tmp1;
-}
-
 #define gen_set_CF(var) tcg_gen_st_i32(var, cpu_env, 
offsetof(CPUUniCore32State, CF))
 
 /* Set CF to the top bit of var.  */
@@ -1219,38 +1188,6 @@ static void disas_coproc_insn(CPUUniCore32State *env, 
DisasContext *s,
 }
 }
 
-
-/* Store a 64-bit value to a register pair.  Clobbers val.  */
-static void gen_storeq_reg(DisasContext *s, int rlow, int rhigh, TCGv_i64 val)
-{
-TCGv tmp;
-tmp = new_tmp();
-tcg_gen_trunc_i64_i32(tmp, val);
-store_reg(s, rlow, tmp);
-tmp = new_tmp();
-tcg_gen_shri_i64(val, val, 32);
-tcg_gen_trunc_i64_i32(tmp, val);
-store_reg(s, rhigh, tmp);
-}
-
-/* load and add a 64-bit value from a register pair.  */
-static void gen_addq(DisasContext *s, TCGv_i64 val, int rlow, int rhigh)
-{
-TCGv_i64 tmp;
-TCGv tmpl;
-TCGv tmph;
-
-/* Load 64-bit value rd:rn.  */
-tmpl = load_reg(s, rlow);
-tmph = load_reg(s, rhigh);
-tmp = tcg_temp_new_i64();
-tcg_gen_concat_i32_i64(tmp, tmpl, tmph);
-dead_tmp(tmpl);
-dead_tmp(tmph);
-tcg_gen_add_i64(val, val, tmp);
-tcg_temp_free_i64(tmp);
-}
-
 /* data processing instructions */
 static void do_datap(CPUUniCore32State *env, DisasContext *s, uint32_t insn)
 {
@@ -1445,24 +1382,26 @@ static void do_datap(CPUUniCore32State *env, 
DisasContext *s, uint32_t insn)
 /* multiply */
 static void do_mult(CPUUniCore32State *env, DisasContext *s, uint32_t insn)
 {
-TCGv tmp;
-TCGv tmp2;
-TCGv_i64 tmp64;
+TCGv tmp, tmp2, tmp3, tmp4;
 
 if (UCOP_SET(27)) {
 /* 64 bit mul */
 tmp = load_reg(s, UCOP_REG_M);
 tmp2 = load_reg(s, UCOP_REG_N);
 if (UCOP_SET(26)) {
-tmp64 = gen_muls_i64_i32(tmp, tmp2);
+tcg_gen_muls2_i32(tmp, tmp2, tmp, tmp2);
 } else {
-tmp64 = gen_mulu_i64_i32(tmp, tmp2);
+tcg_gen_mulu2_i32(tmp, tmp2, tmp, tmp2);
 }
 if (UCOP_SET(25)) { /* mult accumulate */
-gen_addq(s, tmp64, UCOP_REG_LO, UCOP_REG_HI);
-}
-gen_storeq_reg(s, UCOP_REG_LO, UCOP_REG_HI, tmp64);
-tcg_temp_free_i64(tmp64);
+tmp3 = load_reg(s, UCOP_REG_LO);
+tmp4 = load_reg(s, UCOP_REG_HI);
+tcg_gen_add2_i32(tmp, tmp2, tmp, tmp2, tmp3, tmp4);
+dead_tmp(tmp3);
+dead_tmp(tmp4);
+}
+store_reg(s, UCOP_REG_LO, tmp);
+store_reg(s, UCOP_REG_HI, tmp2);
 } else {
 /* 32 bit mul */
 tmp = load_reg(s, UCOP_REG_M);
-- 
1.8.1.2




Re: [Qemu-devel] [PATCH v3 3/6] add backup related monitor commands

2013-02-20 Thread Dietmar Maurer
  +++ b/qapi-schema.json
  @@ -425,6 +425,39 @@
   { 'type': 'EventInfo', 'data': {'name': 'str'} }
 
   ##
  +# @BackupStatus:
  +#
  +# Detailed backup status.
  +#
  +# @status: #optional string describing the current backup status.
  +#  This can be 'active', 'done', 'error'. If this field is not
  +#  returned, no backup process has been initiated
 
 This should be an enum type, not an open-coded 'str'.

@MigrationInfo also use a string for @status. I try to use the same
style as existing code.

  +#
  +# @errmsg: #optional error message (only returned if status is
  +'error') # # @total: #optional total amount of bytes involved in the
  +backup process # # @transferred: #optional amount of bytes already
  +backed up.
  +#
  +# @zero-bytes: #optional amount of 'zero' bytes detected.
  +#
  +# @start-time: #optional time (epoch) when backup job started.
  +#
  +# @end-time: #optional time (epoch) when backup job finished.
 
 Is 1-second resolution good enough, or should we be accounting for sub-
 second information?

IMHO second is good enough.

  +#
  +# @backupfile: #optional backup file name # # @uuid: #optional uuid
  +for this backup job # # Since: 1.5.0 ## { 'type': 'BackupStatus',
  +  'data': {'*status': 'str', '*errmsg': 'str', '*total': 'int',
  +   '*transferred': 'int', '*zero-bytes': 'int',
  +   '*start-time': 'int', '*end-time': 'int',
  +   '*backupfile': 'str', '*uuid': 'str' } }
 
 You can optional set the speed when starting a backup job, but can you later
 change the job speed on the fly, and if so, with what command?

no, you can't change the speed later (currently).

 Also, shouldn't the current speed be displayed as part of BackupStatus?

You can compute the actual speed from those value. 

  +
  +##
   # @query-events:
   #
   # Return a list of supported QMP events by this server @@ -1824,6
  +1857,64 @@
 'data': { 'path': 'str' },
 'returns': [ 'ObjectPropertyInfo' ] }
 
  +
  +##
  +# @BackupFormat
  +#
  +# An enumeration of supported backup formats.
  +#
  +# @vma: Proxmox vma backup format
  +##
  +{ 'enum': 'BackupFormat',
  +  'data': [ 'vma' ] }
  +
  +##
  +# @backup:
  +#
  +# Starts a VM backup.
  +#
  +# @backupfile: the backup file name
  +#
  +# @format: format of the backup file
  +#
  +# @config-filename: #optional name of a configuration file to include
  +into # the backup archive.
 
 'backupfile' vs. 'config-filename' feels inconsistent; better might be 
 'backup-
 file' and 'config-file'.

will change that.
 
  +#
  +# @speed: #optional the maximum speed, in bytes per second #
 
 @devlist is missing.
 
  +# Returns: the uuid of the backup job # # Since: 1.5.0 ## {
  +'command': 'backup', 'data': { 'backupfile': 'str', '*format': 
  'BackupFormat',
  + '*config-filename': 'str',
  + '*devlist': 'str', '*speed': 'int'
  +},
  +  'returns': 'str' }
  +
  +##
  +# @query-backup
  +#
  +# Returns information about current/last backup task.
  +#
  +# Returns: @BackupStatus
  +#
  +# Since: 1.5.0
  +##
  +{ 'command': 'query-backup', 'returns': 'BackupStatus' }
  +
  +##
  +# @backup-cancel
  +#
  +# Cancel the current executing backup process.
  +#
  +# Returns: nothing on success
  +#
  +# Notes: This command succeeds even if there is no backup process
 running.
  +#
  +# Since: 1.5.0
  +##
  +{ 'command': 'backup-cancel' }
  +
 
  +++ b/qmp-commands.hx
  @@ -889,6 +889,18 @@ EQMP
   },
 
   {
  +.name   = backup,
  +.args_type  = backupfile:s,format:s?,config-
 filename:F?,speed:o?,devlist:s?,
  +.mhandler.cmd_new = qmp_marshal_input_backup,
  +},
  +
  +{
  +.name   = backup_cancel,
 
 This doesn't match the spelling in the .json file.

will fix that.


[Qemu-devel] [PATCH 24/38] target-ppc: Use mul*2 in mulh* insns

2013-02-20 Thread Richard Henderson
Cc: Alexander Graf ag...@suse.de
Signed-off-by: Richard Henderson r...@twiddle.net
---
 target-ppc/helper.h |  2 --
 target-ppc/int_helper.c | 18 ---
 target-ppc/translate.c  | 82 +++--
 3 files changed, 38 insertions(+), 64 deletions(-)

diff --git a/target-ppc/helper.h b/target-ppc/helper.h
index 18e0394..fcf372a 100644
--- a/target-ppc/helper.h
+++ b/target-ppc/helper.h
@@ -30,8 +30,6 @@ DEF_HELPER_2(icbi, void, env, tl)
 DEF_HELPER_5(lscbx, tl, env, tl, i32, i32, i32)
 
 #if defined(TARGET_PPC64)
-DEF_HELPER_FLAGS_2(mulhd, TCG_CALL_NO_RWG_SE, i64, i64, i64)
-DEF_HELPER_FLAGS_2(mulhdu, TCG_CALL_NO_RWG_SE, i64, i64, i64)
 DEF_HELPER_3(mulldo, i64, env, i64, i64)
 #endif
 
diff --git a/target-ppc/int_helper.c b/target-ppc/int_helper.c
index 783079d..8653151 100644
--- a/target-ppc/int_helper.c
+++ b/target-ppc/int_helper.c
@@ -25,24 +25,6 @@
 /* Fixed point operations helpers */
 #if defined(TARGET_PPC64)
 
-/* multiply high word */
-uint64_t helper_mulhd(uint64_t arg1, uint64_t arg2)
-{
-uint64_t tl, th;
-
-muls64(tl, th, arg1, arg2);
-return th;
-}
-
-/* multiply high word unsigned */
-uint64_t helper_mulhdu(uint64_t arg1, uint64_t arg2)
-{
-uint64_t tl, th;
-
-mulu64(tl, th, arg1, arg2);
-return th;
-}
-
 uint64_t helper_mulldo(CPUPPCState *env, uint64_t arg1, uint64_t arg2)
 {
 int64_t th;
diff --git a/target-ppc/translate.c b/target-ppc/translate.c
index 2ac5794..2673a89 100644
--- a/target-ppc/translate.c
+++ b/target-ppc/translate.c
@@ -1061,24 +1061,15 @@ GEN_INT_ARITH_DIVD(divdo, 0x1F, 1, 1);
 /* mulhw  mulhw. */
 static void gen_mulhw(DisasContext *ctx)
 {
-TCGv_i64 t0, t1;
+TCGv_i32 t0 = tcg_temp_new_i32();
+TCGv_i32 t1 = tcg_temp_new_i32();
 
-t0 = tcg_temp_new_i64();
-t1 = tcg_temp_new_i64();
-#if defined(TARGET_PPC64)
-tcg_gen_ext32s_tl(t0, cpu_gpr[rA(ctx-opcode)]);
-tcg_gen_ext32s_tl(t1, cpu_gpr[rB(ctx-opcode)]);
-tcg_gen_mul_i64(t0, t0, t1);
-tcg_gen_shri_i64(cpu_gpr[rD(ctx-opcode)], t0, 32);
-#else
-tcg_gen_ext_tl_i64(t0, cpu_gpr[rA(ctx-opcode)]);
-tcg_gen_ext_tl_i64(t1, cpu_gpr[rB(ctx-opcode)]);
-tcg_gen_mul_i64(t0, t0, t1);
-tcg_gen_shri_i64(t0, t0, 32);
-tcg_gen_trunc_i64_tl(cpu_gpr[rD(ctx-opcode)], t0);
-#endif
-tcg_temp_free_i64(t0);
-tcg_temp_free_i64(t1);
+tcg_gen_trunc_tl_i32(t0, cpu_gpr[rA(ctx-opcode)]);
+tcg_gen_trunc_tl_i32(t1, cpu_gpr[rB(ctx-opcode)]);
+tcg_gen_muls2_i32(t0, t1, t0, t1);
+tcg_gen_extu_i32_tl(cpu_gpr[rD(ctx-opcode)], t1);
+tcg_temp_free_i32(t0);
+tcg_temp_free_i32(t1);
 if (unlikely(Rc(ctx-opcode) != 0))
 gen_set_Rc0(ctx, cpu_gpr[rD(ctx-opcode)]);
 }
@@ -1086,24 +1077,15 @@ static void gen_mulhw(DisasContext *ctx)
 /* mulhwu  mulhwu.  */
 static void gen_mulhwu(DisasContext *ctx)
 {
-TCGv_i64 t0, t1;
+TCGv_i32 t0 = tcg_temp_new_i32();
+TCGv_i32 t1 = tcg_temp_new_i32();
 
-t0 = tcg_temp_new_i64();
-t1 = tcg_temp_new_i64();
-#if defined(TARGET_PPC64)
-tcg_gen_ext32u_i64(t0, cpu_gpr[rA(ctx-opcode)]);
-tcg_gen_ext32u_i64(t1, cpu_gpr[rB(ctx-opcode)]);
-tcg_gen_mul_i64(t0, t0, t1);
-tcg_gen_shri_i64(cpu_gpr[rD(ctx-opcode)], t0, 32);
-#else
-tcg_gen_extu_tl_i64(t0, cpu_gpr[rA(ctx-opcode)]);
-tcg_gen_extu_tl_i64(t1, cpu_gpr[rB(ctx-opcode)]);
-tcg_gen_mul_i64(t0, t0, t1);
-tcg_gen_shri_i64(t0, t0, 32);
-tcg_gen_trunc_i64_tl(cpu_gpr[rD(ctx-opcode)], t0);
-#endif
-tcg_temp_free_i64(t0);
-tcg_temp_free_i64(t1);
+tcg_gen_trunc_tl_i32(t0, cpu_gpr[rA(ctx-opcode)]);
+tcg_gen_trunc_tl_i32(t1, cpu_gpr[rB(ctx-opcode)]);
+tcg_gen_mulu2_i32(t0, t1, t0, t1);
+tcg_gen_extu_i32_tl(cpu_gpr[rD(ctx-opcode)], t1);
+tcg_temp_free_i32(t0);
+tcg_temp_free_i32(t1);
 if (unlikely(Rc(ctx-opcode) != 0))
 gen_set_Rc0(ctx, cpu_gpr[rD(ctx-opcode)]);
 }
@@ -1159,19 +1141,31 @@ static void gen_mulli(DisasContext *ctx)
 tcg_gen_muli_tl(cpu_gpr[rD(ctx-opcode)], cpu_gpr[rA(ctx-opcode)],
 SIMM(ctx-opcode));
 }
+
 #if defined(TARGET_PPC64)
-#define GEN_INT_ARITH_MUL_HELPER(name, opc3)  \
-static void glue(gen_, name)(DisasContext *ctx)
   \
-{ \
-gen_helper_##name (cpu_gpr[rD(ctx-opcode)],  \
-   cpu_gpr[rA(ctx-opcode)], cpu_gpr[rB(ctx-opcode)]);   \
-if (unlikely(Rc(ctx-opcode) != 0))   \
-gen_set_Rc0(ctx, cpu_gpr[rD(ctx-opcode)]);   \
-}
 /* mulhd  mulhd. */
-GEN_INT_ARITH_MUL_HELPER(mulhdu, 0x00);
+static void gen_mulhd(DisasContext *ctx)
+{
+TCGv lo = tcg_temp_new();
+tcg_gen_muls2_tl(lo, cpu_gpr[rD(ctx-opcode)],
+ cpu_gpr[rA(ctx-opcode)], cpu_gpr[rB(ctx-opcode)]);
+tcg_temp_free(lo);
+if 

Re: [Qemu-devel] 3 new x86 instructions

2013-02-20 Thread Torbjorn Granlund
Richard Henderson r...@twiddle.net writes:

  On 2013-02-19 13:52, Torbjorn Granlund wrote:
   Execute.  I believe correct behaviour is to print:
  
000d 000d 040b 000a
  
   The program under your special qemu instead prints:
  
000e 000d 040b 000a
  
   Perhaps I am being silly and the program is behaving correctly.
  
  Nope, you found a typo in the comparison.  Annoyingly, not in the i686
  version, which is what I'd tested by hand before.
  
  I've pushed an update to my x86-next branch, and updated the eflags3
  branch against which I posted patches for review this afternoon.
  
I cloned a fresh repo, and compiled it exactly like yesterday on the
same system (I used bash's history list):

  [srcpath]/configure  make -j8

Now my disk image fails to boot.

No bootable device.  Retrying in 60 seconds.

My boot command is (and was):

qemu-system-x86_64 -m 512 -cpu Haswell,+adx \
   -net nic,macaddr=52:54:00:f2:81:c7,model=e1000 -net tap \
  -cdrom /u/FreeBSD/FreeBSD-9.1-RELEASE-amd64-dvd1.iso -boot c -hda disk.img

I went back to the old qemu-system-x86_64 and that still works, so I
don't think the disk.img file is corrupt.

I then tried something that you might consider more plain:

qemu-system-x86_64 -m 512 -cpu Haswell,+adx \
 -net nic,macaddr=52:54:00:f2:18:b7,model=e1000 -net tap \
 -cdrom /u/GNU/Debian/debian-6.0.6-amd64-netinst.iso -boot d --hda disk.img

It fails similarly.  (Here disk.img is pristine from a qemu-img create
command, but I am attemtping to boot from the iso img.)

-- 
Torbjörn



Re: [Qemu-devel] [PATCH 4/9] target-i386: convert 'hv_relaxed' to static property

2013-02-20 Thread Igor Mammedov
On Tue, 19 Feb 2013 15:45:16 -0300
Eduardo Habkost ehabk...@redhat.com wrote:

 On Mon, Feb 11, 2013 at 05:35:06PM +0100, Igor Mammedov wrote:
  Signed-off-by: Igor Mammedov imamm...@redhat.com
  ---
   target-i386/cpu.c |   35 ++-
   1 files changed, 34 insertions(+), 1 deletions(-)
  
  diff --git a/target-i386/cpu.c b/target-i386/cpu.c
  index 1f14b65..b804031 100644
  --- a/target-i386/cpu.c
  +++ b/target-i386/cpu.c
  @@ -528,6 +528,38 @@ PropertyInfo qdev_prop_spinlocks = {
   .defval =
  _defval  \ }
   
  +static void x86_get_hv_relaxed(Object *obj, Visitor *v, void *opaque,
  + const char *name, Error **errp)
  +{
  +bool value = hyperv_relaxed_timing_enabled();
  +
  +visit_type_bool(v, value, name, errp);
  +}
  +
  +static void x86_set_hv_relaxed(Object *obj, Visitor *v, void *opaque,
  + const char *name, Error **errp)
  +{
  +bool value;
  +
  +visit_type_bool(v, value, name, errp);
  +if (error_is_set(errp)) {
  +return;
  +}
  +hyperv_enable_relaxed_timing(value);
  +}
  +
  +PropertyInfo qdev_prop_hv_relaxed = {
  +.name  = boolean,
  +.get   = x86_get_hv_relaxed,
  +.set   = x86_set_hv_relaxed,
  +};
  +#define DEFINE_PROP_HV_RELAXED(_n, _defval)
  {  \
  +.name  =
  _n,   \
  +.info  =
  qdev_prop_hv_relaxed,\
  +.qtype =
  QTYPE_QBOOL,  \
  +.defval =
  _defval  \ +}
  +
   static Property cpu_x86_properties[] = {
   DEFINE_PROP_FAMILY(family),
   DEFINE_PROP_MODEL(model),
  @@ -538,6 +570,7 @@ static Property cpu_x86_properties[] = {
   DEFINE_PROP_MODEL_ID(model-id),
   DEFINE_PROP_TSC_FREQ(tsc-frequency),
   DEFINE_PROP_HV_SPINLOCKS(hv-spinlocks,
  HYPERV_SPINLOCK_NEVER_RETRY),
  +DEFINE_PROP_HV_RELAXED(hv-relaxed, false),
 
 Why not simply make it a X86CPU struct field, so we don't need a special
 PropertyInfo?
 
 The whole contents of target-i386/hyperv.c are getters/setters for three
 static variables that should have been X86CPU fields in the first place.
I went via less intrusive approach to avoid breaking anything during
conversion. Can we proceed with conversion first and than decide whether to
move hv_* into CPU or not?

 
 
   DEFINE_PROP_END_OF_LIST(),
};
   
  @@ -1468,7 +1501,7 @@ static void cpu_x86_parse_featurestr(X86CPU *cpu,
  char *features, Error **errp) } else if (!strcmp(featurestr, enforce)) {
   check_cpuid = enforce_cpuid = 1;
   } else if (!strcmp(featurestr, hv_relaxed)) {
  -hyperv_enable_relaxed_timing(true);
  +object_property_parse(OBJECT(cpu), on, hv-relaxed, errp);
   } else if (!strcmp(featurestr, hv_vapic)) {
   hyperv_enable_vapic_recommended(true);
   } else {
  -- 
  1.7.1
  
  
 




[Qemu-devel] [PATCH 20/38] target-arm: Implement adc_cc inline

2013-02-20 Thread Richard Henderson
Use add2 if available, otherwise use 64-bit arithmetic.

Cc: Peter Maydell peter.mayd...@linaro.org
Signed-off-by: Richard Henderson r...@twiddle.net
---
 target-arm/helper.h|  1 -
 target-arm/op_helper.c | 15 ---
 target-arm/translate.c | 39 ++-
 3 files changed, 34 insertions(+), 21 deletions(-)

diff --git a/target-arm/helper.h b/target-arm/helper.h
index bca5a5b..507bb9c 100644
--- a/target-arm/helper.h
+++ b/target-arm/helper.h
@@ -140,7 +140,6 @@ DEF_HELPER_2(recpe_u32, i32, i32, env)
 DEF_HELPER_2(rsqrte_u32, i32, i32, env)
 DEF_HELPER_5(neon_tbl, i32, env, i32, i32, i32, i32)
 
-DEF_HELPER_3(adc_cc, i32, env, i32, i32)
 DEF_HELPER_3(sbc_cc, i32, env, i32, i32)
 
 DEF_HELPER_3(shl_cc, i32, env, i32, i32)
diff --git a/target-arm/op_helper.c b/target-arm/op_helper.c
index 99610d7..49fc036 100644
--- a/target-arm/op_helper.c
+++ b/target-arm/op_helper.c
@@ -315,21 +315,6 @@ uint64_t HELPER(get_cp_reg64)(CPUARMState *env, void *rip)
The only way to do that in TCG is a conditional branch, which clobbers
all our temporaries.  For now implement these as helper functions.  */
 
-uint32_t HELPER(adc_cc)(CPUARMState *env, uint32_t a, uint32_t b)
-{
-uint32_t result;
-if (!env-CF) {
-result = a + b;
-env-CF = result  a;
-} else {
-result = a + b + 1;
-env-CF = result = a;
-}
-env-VF = (a ^ b ^ -1)  (a ^ result);
-env-NF = env-ZF = result;
-return result;
-}
-
 uint32_t HELPER(sbc_cc)(CPUARMState *env, uint32_t a, uint32_t b)
 {
 uint32_t result;
diff --git a/target-arm/translate.c b/target-arm/translate.c
index ca6f0af..493448a 100644
--- a/target-arm/translate.c
+++ b/target-arm/translate.c
@@ -421,6 +421,34 @@ static void gen_add_CC(TCGv dest, TCGv t0, TCGv t1)
 tcg_gen_mov_i32(dest, cpu_NF);
 }
 
+/* dest = T0 + T1 + CF.  Compute C, N, V and Z flags */
+static void gen_adc_CC(TCGv dest, TCGv t0, TCGv t1)
+{
+TCGv tmp = tcg_temp_new_i32();
+if (TCG_TARGET_HAS_add2_i32) {
+tcg_gen_movi_i32(tmp, 0);
+tcg_gen_add2_i32(cpu_NF, cpu_CF, t0, tmp, cpu_CF, tmp);
+tcg_gen_add2_i32(cpu_NF, cpu_CF, t0, cpu_CF, t1, tmp);
+} else {
+TCGv_i64 q0 = tcg_temp_new_i64();
+TCGv_i64 q1 = tcg_temp_new_i64();
+tcg_gen_extu_i32_i64(q0, t0);
+tcg_gen_extu_i32_i64(q1, t1);
+tcg_gen_add_i64(q0, q0, q1);
+tcg_gen_extu_i32_i64(q1, cpu_CF);
+tcg_gen_add_i64(q0, q0, q1);
+tcg_gen_extr_i64_i32(cpu_NF, cpu_CF, q0);
+tcg_temp_free_i64(q0);
+tcg_temp_free_i64(q1);
+}
+tcg_gen_mov_i32(cpu_ZF, cpu_NF);
+tcg_gen_xor_i32(cpu_VF, cpu_NF, t0);
+tcg_gen_xor_i32(tmp, t0, t1);
+tcg_gen_andc_i32(cpu_VF, cpu_VF, tmp);
+tcg_temp_free_i32(tmp);
+tcg_gen_mov_i32(dest, cpu_NF);
+}
+
 /* dest = T0 - T1. Compute C, N, V and Z flags */
 static void gen_sub_CC(TCGv dest, TCGv t0, TCGv t1)
 {
@@ -7073,7 +7101,7 @@ static void disas_arm_insn(CPUARMState * env, 
DisasContext *s)
 break;
 case 0x05:
 if (set_cc) {
-gen_helper_adc_cc(tmp, cpu_env, tmp, tmp2);
+gen_adc_CC(tmp, tmp, tmp2);
 } else {
 gen_add_carry(tmp, tmp, tmp2);
 }
@@ -7914,7 +7942,7 @@ gen_thumb2_data_op(DisasContext *s, int op, int conds, 
uint32_t shifter_out, TCG
 break;
 case 10: /* adc */
 if (conds)
-gen_helper_adc_cc(t0, cpu_env, t0, t1);
+gen_adc_CC(t0, t0, t1);
 else
 gen_adc(t0, t1);
 break;
@@ -9232,10 +9260,11 @@ static void disas_thumb_insn(CPUARMState *env, 
DisasContext *s)
 }
 break;
 case 0x5: /* adc */
-if (s-condexec_mask)
+if (s-condexec_mask) {
 gen_adc(tmp, tmp2);
-else
-gen_helper_adc_cc(tmp, cpu_env, tmp, tmp2);
+} else {
+gen_adc_CC(tmp, tmp, tmp2);
+}
 break;
 case 0x6: /* sbc */
 if (s-condexec_mask)
-- 
1.8.1.2




[Qemu-devel] [PATCH 37/38] target-xtensa: Use mul*2 for mul*hi

2013-02-20 Thread Richard Henderson
Cc: Max Filippov jcmvb...@gmail.com
Signed-off-by: Richard Henderson r...@twiddle.net
---
 target-xtensa/translate.c | 20 ++--
 1 file changed, 6 insertions(+), 14 deletions(-)

diff --git a/target-xtensa/translate.c b/target-xtensa/translate.c
index 7029ac4..b41d12c 100644
--- a/target-xtensa/translate.c
+++ b/target-xtensa/translate.c
@@ -1652,24 +1652,16 @@ static void disas_xtensa_insn(CPUXtensaState *env, 
DisasContext *dc)
 case 11: /*MULSHi*/
 HAS_OPTION(XTENSA_OPTION_32_BIT_IMUL_HIGH);
 {
-TCGv_i64 r = tcg_temp_new_i64();
-TCGv_i64 s = tcg_temp_new_i64();
-TCGv_i64 t = tcg_temp_new_i64();
+TCGv lo = tcg_temp_new();
 
 if (OP2 == 10) {
-tcg_gen_extu_i32_i64(s, cpu_R[RRR_S]);
-tcg_gen_extu_i32_i64(t, cpu_R[RRR_T]);
+tcg_gen_mulu2_i32(lo, cpu_R[RRR_R],
+  cpu_R[RRR_S], cpu_R[RRR_T]);
 } else {
-tcg_gen_ext_i32_i64(s, cpu_R[RRR_S]);
-tcg_gen_ext_i32_i64(t, cpu_R[RRR_T]);
+tcg_gen_muls2_i32(lo, cpu_R[RRR_R],
+  cpu_R[RRR_S], cpu_R[RRR_T]);
 }
-tcg_gen_mul_i64(r, s, t);
-tcg_gen_shri_i64(r, r, 32);
-tcg_gen_trunc_i64_i32(cpu_R[RRR_R], r);
-
-tcg_temp_free_i64(r);
-tcg_temp_free_i64(s);
-tcg_temp_free_i64(t);
+tcg_temp_free(lo);
 }
 break;
 
-- 
1.8.1.2




[Qemu-devel] [PATCH 35/38] target-sh4: Use mul*2 for dmul*

2013-02-20 Thread Richard Henderson
Cc: Aurelien Jarno aurel...@aurel32.net
Signed-off-by: Richard Henderson r...@twiddle.net
---
 target-sh4/translate.c | 30 ++
 1 file changed, 2 insertions(+), 28 deletions(-)

diff --git a/target-sh4/translate.c b/target-sh4/translate.c
index c58d79a..d255066 100644
--- a/target-sh4/translate.c
+++ b/target-sh4/translate.c
@@ -833,36 +833,10 @@ static void _decode_opc(DisasContext * ctx)
 gen_helper_div1(REG(B11_8), cpu_env, REG(B7_4), REG(B11_8));
return;
 case 0x300d:   /* dmuls.l Rm,Rn */
-   {
-   TCGv_i64 tmp1 = tcg_temp_new_i64();
-   TCGv_i64 tmp2 = tcg_temp_new_i64();
-
-   tcg_gen_ext_i32_i64(tmp1, REG(B7_4));
-   tcg_gen_ext_i32_i64(tmp2, REG(B11_8));
-   tcg_gen_mul_i64(tmp1, tmp1, tmp2);
-   tcg_gen_trunc_i64_i32(cpu_macl, tmp1);
-   tcg_gen_shri_i64(tmp1, tmp1, 32);
-   tcg_gen_trunc_i64_i32(cpu_mach, tmp1);
-
-   tcg_temp_free_i64(tmp2);
-   tcg_temp_free_i64(tmp1);
-   }
+tcg_gen_muls2_i32(cpu_macl, cpu_mach, REG(B7_4), REG(B11_8));
return;
 case 0x3005:   /* dmulu.l Rm,Rn */
-   {
-   TCGv_i64 tmp1 = tcg_temp_new_i64();
-   TCGv_i64 tmp2 = tcg_temp_new_i64();
-
-   tcg_gen_extu_i32_i64(tmp1, REG(B7_4));
-   tcg_gen_extu_i32_i64(tmp2, REG(B11_8));
-   tcg_gen_mul_i64(tmp1, tmp1, tmp2);
-   tcg_gen_trunc_i64_i32(cpu_macl, tmp1);
-   tcg_gen_shri_i64(tmp1, tmp1, 32);
-   tcg_gen_trunc_i64_i32(cpu_mach, tmp1);
-
-   tcg_temp_free_i64(tmp2);
-   tcg_temp_free_i64(tmp1);
-   }
+tcg_gen_mulu2_i32(cpu_macl, cpu_mach, REG(B7_4), REG(B11_8));
return;
 case 0x600e:   /* exts.b Rm,Rn */
tcg_gen_ext8s_i32(REG(B11_8), REG(B7_4));
-- 
1.8.1.2




Re: [Qemu-devel] [PATCH 2/2] coroutine: trim down nesting level in perf_nesting test

2013-02-20 Thread Stefan Hajnoczi
On Tue, Feb 19, 2013 at 11:59:10AM +0100, Paolo Bonzini wrote:
 2 nested coroutines require 20 GB of virtual address space.
 Only nest 1000 of them so that the test (only enabled with
 -m perf on the command line) runs on 32-bit machines too.
 
 Cc: qemu-sta...@nongnu.org
 Signed-off-by: Paolo Bonzini pbonz...@redhat.com
 ---
  tests/test-coroutine.c | 2 +-
  1 file changed, 1 insertion(+), 1 deletion(-)

Okay, 2 nesting level was unrealistic and QEMU will never approach
that in reality.  1000 is fine.

Reviewed-by: Stefan Hajnoczi stefa...@redhat.com



Re: [Qemu-devel] [PATCH 1/2] coroutine: move pooling to common code

2013-02-20 Thread Stefan Hajnoczi
On Tue, Feb 19, 2013 at 11:59:09AM +0100, Paolo Bonzini wrote:
 The coroutine pool code is duplicated between the ucontext and
 sigaltstack backends, and absent from the win32 backend.  But the
 code can be shared easily by moving it to qemu-coroutine.c.
 
 Signed-off-by: Paolo Bonzini pbonz...@redhat.com
 ---
  coroutine-sigaltstack.c | 43 +--
  coroutine-ucontext.c| 43 +--
  qemu-coroutine.c| 45 +++--
  3 files changed, 45 insertions(+), 86 deletions(-)

Reviewed-by: Stefan Hajnoczi stefa...@redhat.com



[Qemu-devel] [PATCH 31/38] target-ppc: Compute arithmetic shift carry without branches

2013-02-20 Thread Richard Henderson
Cc: Alexander Graf ag...@suse.de
Signed-off-by: Richard Henderson r...@twiddle.net
---
 target-ppc/translate.c | 71 ++
 1 file changed, 31 insertions(+), 40 deletions(-)

diff --git a/target-ppc/translate.c b/target-ppc/translate.c
index 05f93f6..439 100644
--- a/target-ppc/translate.c
+++ b/target-ppc/translate.c
@@ -1773,30 +1773,25 @@ static void gen_sraw(DisasContext *ctx)
 static void gen_srawi(DisasContext *ctx)
 {
 int sh = SH(ctx-opcode);
-if (sh != 0) {
-int l1, l2;
-TCGv t0;
-l1 = gen_new_label();
-l2 = gen_new_label();
-t0 = tcg_temp_local_new();
-tcg_gen_ext32s_tl(t0, cpu_gpr[rS(ctx-opcode)]);
-tcg_gen_brcondi_tl(TCG_COND_GE, t0, 0, l1);
-tcg_gen_andi_tl(t0, cpu_gpr[rS(ctx-opcode)], (1ULL  sh) - 1);
-tcg_gen_brcondi_tl(TCG_COND_EQ, t0, 0, l1);
-tcg_gen_movi_tl(cpu_ca, 1);
-tcg_gen_br(l2);
-gen_set_label(l1);
+TCGv dst = cpu_gpr[rA(ctx-opcode)];
+TCGv src = cpu_gpr[rS(ctx-opcode)];
+if (sh == 0) {
+tcg_gen_mov_tl(dst, src);
 tcg_gen_movi_tl(cpu_ca, 0);
-gen_set_label(l2);
-tcg_gen_ext32s_tl(t0, cpu_gpr[rS(ctx-opcode)]);
-tcg_gen_sari_tl(cpu_gpr[rA(ctx-opcode)], t0, sh);
-tcg_temp_free(t0);
 } else {
-tcg_gen_mov_tl(cpu_gpr[rA(ctx-opcode)], cpu_gpr[rS(ctx-opcode)]);
-tcg_gen_movi_tl(cpu_ca, 0);
+TCGv t0;
+tcg_gen_ext32s_tl(dst, src);
+tcg_gen_andi_tl(cpu_ca, dst, (1ULL  sh) - 1);
+t0 = tcg_temp_new();
+tcg_gen_sari_tl(t0, dst, TARGET_LONG_BITS - 1);
+tcg_gen_and_tl(cpu_ca, cpu_ca, t0);
+tcg_temp_free(t0);
+tcg_gen_setcondi_tl(TCG_COND_NE, cpu_ca, cpu_ca, 0);
+tcg_gen_sari_tl(dst, dst, sh);
+}
+if (unlikely(Rc(ctx-opcode) != 0)) {
+gen_set_Rc0(ctx, dst);
 }
-if (unlikely(Rc(ctx-opcode) != 0))
-gen_set_Rc0(ctx, cpu_gpr[rA(ctx-opcode)]);
 }
 
 /* srw  srw. */
@@ -1856,28 +1851,24 @@ static void gen_srad(DisasContext *ctx)
 static inline void gen_sradi(DisasContext *ctx, int n)
 {
 int sh = SH(ctx-opcode) + (n  5);
-if (sh != 0) {
-int l1, l2;
-TCGv t0;
-l1 = gen_new_label();
-l2 = gen_new_label();
-t0 = tcg_temp_local_new();
-tcg_gen_brcondi_tl(TCG_COND_GE, cpu_gpr[rS(ctx-opcode)], 0, l1);
-tcg_gen_andi_tl(t0, cpu_gpr[rS(ctx-opcode)], (1ULL  sh) - 1);
-tcg_gen_brcondi_tl(TCG_COND_EQ, t0, 0, l1);
-tcg_gen_movi_tl(cpu_ca, 1);
-tcg_gen_br(l2);
-gen_set_label(l1);
+TCGv dst = cpu_gpr[rA(ctx-opcode)];
+TCGv src = cpu_gpr[rS(ctx-opcode)];
+if (sh == 0) {
+tcg_gen_mov_tl(dst, src);
 tcg_gen_movi_tl(cpu_ca, 0);
-gen_set_label(l2);
-tcg_temp_free(t0);
-tcg_gen_sari_tl(cpu_gpr[rA(ctx-opcode)], cpu_gpr[rS(ctx-opcode)], 
sh);
 } else {
-tcg_gen_mov_tl(cpu_gpr[rA(ctx-opcode)], cpu_gpr[rS(ctx-opcode)]);
-tcg_gen_movi_tl(cpu_ca, 0);
+TCGv t0;
+tcg_gen_andi_tl(cpu_ca, src, (1ULL  sh) - 1);
+t0 = tcg_temp_new();
+tcg_gen_sari_tl(t0, src, TARGET_LONG_BITS - 1);
+tcg_gen_and_tl(cpu_ca, cpu_ca, t0);
+tcg_temp_free(t0);
+tcg_gen_setcondi_tl(TCG_COND_NE, cpu_ca, cpu_ca, 0);
+tcg_gen_sari_tl(dst, src, sh);
+}
+if (unlikely(Rc(ctx-opcode) != 0)) {
+gen_set_Rc0(ctx, dst);
 }
-if (unlikely(Rc(ctx-opcode) != 0))
-gen_set_Rc0(ctx, cpu_gpr[rA(ctx-opcode)]);
 }
 
 static void gen_sradi0(DisasContext *ctx)
-- 
1.8.1.2




[Qemu-devel] [PATCH 29/38] target-ppc: Use add2 for carry generation

2013-02-20 Thread Richard Henderson
Cc: Alexander Graf ag...@suse.de
Signed-off-by: Richard Henderson r...@twiddle.net
---
 target-ppc/translate.c | 194 ++---
 1 file changed, 69 insertions(+), 125 deletions(-)

diff --git a/target-ppc/translate.c b/target-ppc/translate.c
index fce261b..abc75e2 100644
--- a/target-ppc/translate.c
+++ b/target-ppc/translate.c
@@ -765,73 +765,40 @@ static inline void gen_op_arith_compute_ov(DisasContext 
*ctx, TCGv arg0,
 tcg_gen_or_tl(cpu_so, cpu_so, cpu_ov);
 }
 
-static inline void gen_op_arith_compute_ca(DisasContext *ctx, TCGv arg1,
-   TCGv arg2, int sub)
-{
-TCGv t0 = tcg_temp_new(), t1 = arg1, t2 = arg2;
-
-#if defined(TARGET_PPC64)
-if (!(ctx-sf_mode)) {
-t1 = t0;
-tcg_gen_ext32u_tl(t1, arg1);
-t2 = tcg_temp_new();
-tcg_gen_ext32u_tl(t2, arg2);
-}
-#endif
-
-tcg_gen_setcond_tl(sub ? TCG_COND_LEU : TCG_COND_LTU, t0, t1, t2);
-tcg_gen_or_tl(cpu_ca, cpu_ca, t0);
-
-tcg_temp_free(t0);
-#if defined(TARGET_PPC64)
-if (!(ctx-sf_mode)) {
-tcg_temp_free(t2);
-}
-#endif
-}
-
 /* Common add function */
 static inline void gen_op_arith_add(DisasContext *ctx, TCGv ret, TCGv arg1,
-TCGv arg2, int add_ca, int compute_ca,
-int compute_ov)
+TCGv arg2, bool add_ca, bool compute_ca,
+bool compute_ov, bool compute_rc0)
 {
-TCGv t0, t1;
+TCGv t0 = ret;
 
-if ((!compute_ca  !compute_ov) ||
-(!TCGV_EQUAL(ret,arg1)  !TCGV_EQUAL(ret, arg2)))  {
-t0 = ret;
-} else {
+if (((compute_ca  add_ca) || compute_ov)
+ (TCGV_EQUAL(ret, arg1) || TCGV_EQUAL(ret, arg2)))  {
 t0 = tcg_temp_new();
 }
 
-if (add_ca) {
-t1 = tcg_temp_local_new();
-tcg_gen_mov_tl(t1, cpu_ca);
-} else {
-TCGV_UNUSED(t1);
-}
-
 if (compute_ca) {
-/* Start with XER CA disabled, the most likely case */
-tcg_gen_movi_tl(cpu_ca, 0);
+TCGv zero = tcg_const_tl(0);
+if (add_ca) {
+tcg_gen_add2_tl(t0, cpu_ca, arg1, zero, cpu_ca, zero);
+tcg_gen_add2_tl(t0, cpu_ca, t0, cpu_ca, arg2, zero);
+} else {
+tcg_gen_add2_tl(t0, cpu_ca, arg1, zero, arg2, zero);
+}
+tcg_temp_free(zero);
+} else {
+tcg_gen_add_tl(t0, arg1, arg2);
+if (add_ca) {
+tcg_gen_add_tl(t0, t0, cpu_ca);
+}
 }
 
-tcg_gen_add_tl(t0, arg1, arg2);
-
-if (compute_ca) {
-gen_op_arith_compute_ca(ctx, t0, arg1, 0);
-}
-if (add_ca) {
-tcg_gen_add_tl(t0, t0, t1);
-gen_op_arith_compute_ca(ctx, t0, t1, 0);
-tcg_temp_free(t1);
-}
 if (compute_ov) {
 gen_op_arith_compute_ov(ctx, t0, arg1, arg2, 0);
 }
-
-if (unlikely(Rc(ctx-opcode) != 0))
+if (unlikely(compute_rc0)) {
 gen_set_Rc0(ctx, t0);
+}
 
 if (!TCGV_EQUAL(t0, ret)) {
 tcg_gen_mov_tl(ret, t0);
@@ -840,21 +807,21 @@ static inline void gen_op_arith_add(DisasContext *ctx, 
TCGv ret, TCGv arg1,
 }
 /* Add functions with two operands */
 #define GEN_INT_ARITH_ADD(name, opc3, add_ca, compute_ca, compute_ov) \
-static void glue(gen_, name)(DisasContext *ctx)
   \
+static void glue(gen_, name)(DisasContext *ctx)   \
 { \
 gen_op_arith_add(ctx, cpu_gpr[rD(ctx-opcode)],   \
  cpu_gpr[rA(ctx-opcode)], cpu_gpr[rB(ctx-opcode)],  \
- add_ca, compute_ca, compute_ov); \
+ add_ca, compute_ca, compute_ov, Rc(ctx-opcode));\
 }
 /* Add functions with one operand and one immediate */
 #define GEN_INT_ARITH_ADD_CONST(name, opc3, const_val,\
 add_ca, compute_ca, compute_ov)   \
-static void glue(gen_, name)(DisasContext *ctx)
   \
+static void glue(gen_, name)(DisasContext *ctx)   \
 { \
-TCGv t0 = tcg_const_local_tl(const_val);  \
+TCGv t0 = tcg_const_tl(const_val);\
 gen_op_arith_add(ctx, cpu_gpr[rD(ctx-opcode)],   \
  cpu_gpr[rA(ctx-opcode)], t0,\
- add_ca, compute_ca, compute_ov); \
+ add_ca, compute_ca, compute_ov, Rc(ctx-opcode));\
 tcg_temp_free(t0);\
 }
 
@@ -882,40 +849,27 @@ static void 

[Qemu-devel] [PATCH 19/38] target-arm: Use add2 in gen_add_CC

2013-02-20 Thread Richard Henderson
Cc: Peter Maydell peter.mayd...@linaro.org
Signed-off-by: Richard Henderson r...@twiddle.net
---
 target-arm/translate.c | 7 +++
 1 file changed, 3 insertions(+), 4 deletions(-)

diff --git a/target-arm/translate.c b/target-arm/translate.c
index efe76d0..ca6f0af 100644
--- a/target-arm/translate.c
+++ b/target-arm/translate.c
@@ -410,12 +410,11 @@ static void gen_sub_carry(TCGv dest, TCGv t0, TCGv t1)
 /* dest = T0 + T1. Compute C, N, V and Z flags */
 static void gen_add_CC(TCGv dest, TCGv t0, TCGv t1)
 {
-TCGv tmp;
-tcg_gen_add_i32(cpu_NF, t0, t1);
+TCGv tmp = tcg_temp_new_i32();
+tcg_gen_movi_i32(tmp, 0);
+tcg_gen_add2_i32(cpu_NF, cpu_CF, t0, tmp, t1, tmp);
 tcg_gen_mov_i32(cpu_ZF, cpu_NF);
-tcg_gen_setcond_i32(TCG_COND_LTU, cpu_CF, cpu_NF, t0);
 tcg_gen_xor_i32(cpu_VF, cpu_NF, t0);
-tmp = tcg_temp_new_i32();
 tcg_gen_xor_i32(tmp, t0, t1);
 tcg_gen_andc_i32(cpu_VF, cpu_VF, tmp);
 tcg_temp_free_i32(tmp);
-- 
1.8.1.2




[Qemu-devel] [PATCH 27/38] target-ppc: Compute addition overflow without branches

2013-02-20 Thread Richard Henderson
Cc: Alexander Graf ag...@suse.de
Signed-off-by: Richard Henderson r...@twiddle.net
---
 target-ppc/translate.c | 46 +-
 1 file changed, 13 insertions(+), 33 deletions(-)

diff --git a/target-ppc/translate.c b/target-ppc/translate.c
index 7aab6ae..116cf12 100644
--- a/target-ppc/translate.c
+++ b/target-ppc/translate.c
@@ -746,35 +746,23 @@ static void gen_isel(DisasContext *ctx)
 static inline void gen_op_arith_compute_ov(DisasContext *ctx, TCGv arg0,
TCGv arg1, TCGv arg2, int sub)
 {
-int l1;
-TCGv t0;
+TCGv t0 = tcg_temp_new();
 
-l1 = gen_new_label();
-/* Start with XER OV disabled, the most likely case */
-tcg_gen_movi_tl(cpu_ov, 0);
-t0 = tcg_temp_local_new();
-tcg_gen_xor_tl(t0, arg0, arg1);
-#if defined(TARGET_PPC64)
-if (!ctx-sf_mode)
-tcg_gen_ext32s_tl(t0, t0);
-#endif
-if (sub)
-tcg_gen_brcondi_tl(TCG_COND_LT, t0, 0, l1);
-else
-tcg_gen_brcondi_tl(TCG_COND_GE, t0, 0, l1);
+tcg_gen_xor_tl(cpu_ov, arg0, arg1);
 tcg_gen_xor_tl(t0, arg1, arg2);
+if (sub) {
+tcg_gen_and_tl(cpu_ov, cpu_ov, t0);
+} else {
+tcg_gen_andc_tl(cpu_ov, cpu_ov, t0);
+}
+tcg_temp_free(t0);
 #if defined(TARGET_PPC64)
-if (!ctx-sf_mode)
-tcg_gen_ext32s_tl(t0, t0);
+if (!ctx-sf_mode) {
+tcg_gen_ext32s_tl(cpu_ov, cpu_ov);
+}
 #endif
-if (sub)
-tcg_gen_brcondi_tl(TCG_COND_GE, t0, 0, l1);
-else
-tcg_gen_brcondi_tl(TCG_COND_LT, t0, 0, l1);
-tcg_gen_movi_tl(cpu_ov, 1);
-tcg_gen_movi_tl(cpu_so, 1);
-gen_set_label(l1);
-tcg_temp_free(t0);
+tcg_gen_shri_tl(cpu_ov, cpu_ov, TARGET_LONG_BITS - 1);
+tcg_gen_or_tl(cpu_so, cpu_so, cpu_ov);
 }
 
 static inline void gen_op_arith_compute_ca(DisasContext *ctx, TCGv arg1,
@@ -837,10 +825,6 @@ static inline void gen_op_arith_add(DisasContext *ctx, 
TCGv ret, TCGv arg1,
 /* Start with XER CA disabled, the most likely case */
 tcg_gen_movi_tl(cpu_ca, 0);
 }
-if (compute_ov) {
-/* Start with XER OV disabled, the most likely case */
-tcg_gen_movi_tl(cpu_ov, 0);
-}
 
 tcg_gen_add_tl(t0, arg1, arg2);
 
@@ -1261,10 +1245,6 @@ static inline void gen_op_arith_subf(DisasContext *ctx, 
TCGv ret, TCGv arg1,
 /* Start with XER CA disabled, the most likely case */
 tcg_gen_movi_tl(cpu_ca, 0);
 }
-if (compute_ov) {
-/* Start with XER OV disabled, the most likely case */
-tcg_gen_movi_tl(cpu_ov, 0);
-}
 
 if (add_ca) {
 tcg_gen_not_tl(t0, arg1);
-- 
1.8.1.2




[Qemu-devel] [PATCH] tap: forbid creating multiqueue tap when hub is used

2013-02-20 Thread Jason Wang
Obviously, hub does not support multiqueue tap. So this patch forbids creating
multiple queue tap when hub is used to prevent the crash when command line such
as -net tap,queues=2 is used.

Signed-off-by: Jason Wang jasow...@redhat.com
---
This patch is needed for 1.4 stable also.
---
 net/tap.c |6 ++
 1 files changed, 6 insertions(+), 0 deletions(-)

diff --git a/net/tap.c b/net/tap.c
index 48c254e..1e14f59 100644
--- a/net/tap.c
+++ b/net/tap.c
@@ -693,6 +693,12 @@ int net_init_tap(const NetClientOptions *opts, const char 
*name,
 queues = tap-has_queues ? tap-queues : 1;
 vhostfdname = tap-has_vhostfd ? tap-vhostfd : NULL;
 
+if (peer  (tap-has_queues || tap-has_fds || tap-has_vhostfds)) {
+error_report(This configuration is not compatiable with multiqueue
+  tap);
+return -1;
+}
+
 if (tap-has_fd) {
 if (tap-has_ifname || tap-has_script || tap-has_downscript ||
 tap-has_vnet_hdr || tap-has_helper || tap-has_queues ||
-- 
1.7.1




Re: [Qemu-devel] [PATCH v9 1/3] iov: Factor out hexdumper

2013-02-20 Thread Gerd Hoffmann
  Hi,

 Done, thanks for the correction. Do you have a lightweight test vector
 that exercises this? The iovec stuff in my areas is all limited to
 single iovec element.  Interdiff below.

hw/usb/dev-network.c (with TRAFFC_DEBUG) calls this on usb packets which
could trigger this in theory.  Depends on how the guest allocates the
usb packet buffers though, so I'm not fully sure whenever that actually
triggers in practice.

 @@ -202,11 +202,16 @@ void iov_hexdump(const struct iovec *iov, const
 unsigned int iov_cnt,
   FILE *fp, const char *prefix, size_t limit)
  {
  int v;
 -for (v = 0; v  iov_cnt  limit; v++) {
 -int size = limit  iov[v].iov_len ? limit : iov[v].iov_len;
 -hexdump(iov[v].iov_base, fp, prefix, size);
 -limit -= size;
 +size_t size = 0;
 +char *buf;
 +
 +for (v = 0; v  iov_cnt; v++) {
 +size += iov[v].iov_len;
  }
 +size = size  limit ? limit : size;
 +buf = g_malloc(size);
 +iov_to_buf(iov, iov_cnt, 0, buf, size);

You've lost the actual hexdump() call here ;)

 +g_free(buf);

Otherwise it looks fine.

cheers,
  Gerd




Re: [Qemu-devel] [PATCH V4 RESEND 15/22] tap: multiqueue support

2013-02-20 Thread Jason Wang
On 02/11/2013 06:28 PM, Markus Armbruster wrote:
 Commit 264986e2 extended NetdevTapOptions without updating the
 documentation.  Hasn't been addressed since.  Must fix for 1.4, in my
 opinion.

Will send a patch to fix this.

Thanks

 This is the offending patch:

 Jason Wang jasow...@redhat.com writes:

 Recently, linux support multiqueue tap which could let userspace call 
 TUNSETIFF
 for a signle device many times to create multiple file descriptors as
 independent queues. User could also enable/disabe a specific queue through
 TUNSETQUEUE.

 The patch adds the generic infrastructure to create multiqueue taps. To 
 achieve
 this a new parameter queues were introduced to specify how many queues were
 expected to be created for tap by qemu itself. Alternatively, management 
 could
 also pass multiple pre-created tap file descriptors separated with ':' 
 through a
 new parameter fds like -netdev tap,id=hn0,fds=X:Y:..:Z. Multiple vhost file
 descriptors could also be passed in this way.

 Each TAPState were still associated to a tap fd, which mean multiple 
 TAPStates
 were created when user needs multiqueue taps. Since each TAPState contains 
 one
 NetClientState, with the multiqueue nic support, an N peers of NetClientState
 were built up.

 A new parameter, mq_required were introduce in tap_open() to create 
 multiqueue
 tap fds.
 [...]
 diff --git a/qapi-schema.json b/qapi-schema.json
 index 3a4817b..cdd8384 100644
 --- a/qapi-schema.json
 +++ b/qapi-schema.json
 @@ -2533,6 +2533,7 @@
'data': {
  '*ifname': 'str',
  '*fd': 'str',
 +'*fds':'str',
  '*script': 'str',
  '*downscript': 'str',
  '*helper': 'str',
 @@ -2540,7 +2541,9 @@
  '*vnet_hdr':   'bool',
  '*vhost':  'bool',
  '*vhostfd':'str',
 -'*vhostforce': 'bool' } }
 +'*vhostfds':   'str',
 +'*vhostforce': 'bool',
 +'*queues': 'uint32'} }
  
  ##
  # @NetdevSocketOptions




[Qemu-devel] [PATCH 01/38] tcg: Make 32-bit multiword operations optional for 64-bit hosts

2013-02-20 Thread Richard Henderson
Signed-off-by: Richard Henderson r...@twiddle.net
---
 tcg/i386/tcg-target.h  | 4 
 tcg/ia64/tcg-target.h  | 3 +++
 tcg/ppc64/tcg-target.h | 3 +++
 tcg/s390/tcg-target.h  | 3 +++
 tcg/sparc/tcg-target.h | 4 
 tcg/tcg-opc.h  | 6 +++---
 tcg/tcg.h  | 6 +-
 tcg/tci/tcg-target.h   | 4 
 8 files changed, 29 insertions(+), 4 deletions(-)

diff --git a/tcg/i386/tcg-target.h b/tcg/i386/tcg-target.h
index e63db9c..43ad2c4 100644
--- a/tcg/i386/tcg-target.h
+++ b/tcg/i386/tcg-target.h
@@ -114,6 +114,10 @@ typedef enum {
 #define TCG_TARGET_HAS_nor_i64  0
 #define TCG_TARGET_HAS_deposit_i64  1
 #define TCG_TARGET_HAS_movcond_i64  1
+
+#define TCG_TARGET_HAS_add2_i32 0
+#define TCG_TARGET_HAS_sub2_i32 0
+#define TCG_TARGET_HAS_mulu2_i320
 #endif
 
 #define TCG_TARGET_deposit_i32_valid(ofs, len) \
diff --git a/tcg/ia64/tcg-target.h b/tcg/ia64/tcg-target.h
index 7f3401e..b4ff7c3 100644
--- a/tcg/ia64/tcg-target.h
+++ b/tcg/ia64/tcg-target.h
@@ -136,6 +136,9 @@ typedef enum {
 #define TCG_TARGET_HAS_movcond_i64  1
 #define TCG_TARGET_HAS_deposit_i32  1
 #define TCG_TARGET_HAS_deposit_i64  1
+#define TCG_TARGET_HAS_add2_i32 0
+#define TCG_TARGET_HAS_sub2_i32 0
+#define TCG_TARGET_HAS_mulu2_i320
 
 #define TCG_TARGET_deposit_i32_valid(ofs, len) ((len) = 16)
 #define TCG_TARGET_deposit_i64_valid(ofs, len) ((len) = 16)
diff --git a/tcg/ppc64/tcg-target.h b/tcg/ppc64/tcg-target.h
index 9b8e9a0..ea976ad 100644
--- a/tcg/ppc64/tcg-target.h
+++ b/tcg/ppc64/tcg-target.h
@@ -85,6 +85,9 @@ typedef enum {
 #define TCG_TARGET_HAS_nor_i32  0
 #define TCG_TARGET_HAS_deposit_i32  0
 #define TCG_TARGET_HAS_movcond_i32  0
+#define TCG_TARGET_HAS_add2_i32 0
+#define TCG_TARGET_HAS_sub2_i32 0
+#define TCG_TARGET_HAS_mulu2_i320
 
 #define TCG_TARGET_HAS_div_i64  1
 #define TCG_TARGET_HAS_rot_i64  0
diff --git a/tcg/s390/tcg-target.h b/tcg/s390/tcg-target.h
index c87b413..7772c35 100644
--- a/tcg/s390/tcg-target.h
+++ b/tcg/s390/tcg-target.h
@@ -65,6 +65,9 @@ typedef enum TCGReg {
 #define TCG_TARGET_HAS_nor_i32  0
 #define TCG_TARGET_HAS_deposit_i32  0
 #define TCG_TARGET_HAS_movcond_i32  0
+#define TCG_TARGET_HAS_add2_i32 0
+#define TCG_TARGET_HAS_sub2_i32 0
+#define TCG_TARGET_HAS_mulu2_i320
 
 #if TCG_TARGET_REG_BITS == 64
 #define TCG_TARGET_HAS_div2_i64 1
diff --git a/tcg/sparc/tcg-target.h b/tcg/sparc/tcg-target.h
index 256f973..6c62e45 100644
--- a/tcg/sparc/tcg-target.h
+++ b/tcg/sparc/tcg-target.h
@@ -124,6 +124,10 @@ typedef enum {
 #define TCG_TARGET_HAS_nor_i64  0
 #define TCG_TARGET_HAS_deposit_i64  0
 #define TCG_TARGET_HAS_movcond_i64  1
+
+#define TCG_TARGET_HAS_add2_i32 0
+#define TCG_TARGET_HAS_sub2_i32 0
+#define TCG_TARGET_HAS_mulu2_i320
 #endif
 
 #define TCG_AREG0 TCG_REG_I0
diff --git a/tcg/tcg-opc.h b/tcg/tcg-opc.h
index 9651063..1d9a9a2 100644
--- a/tcg/tcg-opc.h
+++ b/tcg/tcg-opc.h
@@ -83,10 +83,10 @@ DEF(deposit_i32, 1, 2, 2, IMPL(TCG_TARGET_HAS_deposit_i32))
 
 DEF(brcond_i32, 0, 2, 2, TCG_OPF_BB_END)
 
-DEF(add2_i32, 2, 4, 0, IMPL(TCG_TARGET_REG_BITS == 32))
-DEF(sub2_i32, 2, 4, 0, IMPL(TCG_TARGET_REG_BITS == 32))
+DEF(add2_i32, 2, 4, 0, IMPL(TCG_TARGET_HAS_add2_i32))
+DEF(sub2_i32, 2, 4, 0, IMPL(TCG_TARGET_HAS_sub2_i32))
+DEF(mulu2_i32, 2, 2, 0, IMPL(TCG_TARGET_HAS_mulu2_i32))
 DEF(brcond2_i32, 0, 4, 2, TCG_OPF_BB_END | IMPL(TCG_TARGET_REG_BITS == 32))
-DEF(mulu2_i32, 2, 2, 0, IMPL(TCG_TARGET_REG_BITS == 32))
 DEF(setcond2_i32, 1, 4, 1, IMPL(TCG_TARGET_REG_BITS == 32))
 
 DEF(ext8s_i32, 1, 1, 0, IMPL(TCG_TARGET_HAS_ext8s_i32))
diff --git a/tcg/tcg.h b/tcg/tcg.h
index 51c8176..e5c7ce4 100644
--- a/tcg/tcg.h
+++ b/tcg/tcg.h
@@ -57,8 +57,8 @@ typedef uint64_t TCGRegSet;
 #error unsupported
 #endif
 
-/* Turn some undef macros into false macros.  */
 #if TCG_TARGET_REG_BITS == 32
+/* Turn some undef macros into false macros.  */
 #define TCG_TARGET_HAS_div_i64  0
 #define TCG_TARGET_HAS_div2_i64 0
 #define TCG_TARGET_HAS_rot_i64  0
@@ -80,6 +80,10 @@ typedef uint64_t TCGRegSet;
 #define TCG_TARGET_HAS_nor_i64  0
 #define TCG_TARGET_HAS_deposit_i64  0
 #define TCG_TARGET_HAS_movcond_i64  0
+/* Turn some undef macros into true macros.  */
+#define TCG_TARGET_HAS_add2_i32 1
+#define TCG_TARGET_HAS_sub2_i32 1
+#define TCG_TARGET_HAS_mulu2_i321
 #endif
 
 #ifndef TCG_TARGET_deposit_i32_valid
diff --git a/tcg/tci/tcg-target.h b/tcg/tci/tcg-target.h
index a832f5c..3e235bd 100644
--- a/tcg/tci/tcg-target.h
+++ b/tcg/tci/tcg-target.h
@@ -100,6 +100,10 @@
 #define TCG_TARGET_HAS_orc_i64  0
 #define TCG_TARGET_HAS_rot_i64  1
 #define TCG_TARGET_HAS_movcond_i64  0
+
+#define TCG_TARGET_HAS_add2_i32 0
+#define TCG_TARGET_HAS_sub2_i32 0
+#define TCG_TARGET_HAS_mulu2_i320
 

[Qemu-devel] [PATCH 22/38] target-mips: Use mul[us]2 in [D]MULT[U] insns

2013-02-20 Thread Richard Henderson
Cc: Aurelien Jarno aurel...@aurel32.net
Signed-off-by: Richard Henderson r...@twiddle.net
---
 target-mips/helper.h|  2 --
 target-mips/op_helper.c | 12 
 target-mips/translate.c | 48 
 3 files changed, 20 insertions(+), 42 deletions(-)

diff --git a/target-mips/helper.h b/target-mips/helper.h
index cd48738..ed75e2c 100644
--- a/target-mips/helper.h
+++ b/target-mips/helper.h
@@ -24,8 +24,6 @@ DEF_HELPER_FLAGS_1(clz, TCG_CALL_NO_RWG_SE, tl, tl)
 #ifdef TARGET_MIPS64
 DEF_HELPER_FLAGS_1(dclo, TCG_CALL_NO_RWG_SE, tl, tl)
 DEF_HELPER_FLAGS_1(dclz, TCG_CALL_NO_RWG_SE, tl, tl)
-DEF_HELPER_3(dmult, void, env, tl, tl)
-DEF_HELPER_3(dmultu, void, env, tl, tl)
 #endif
 
 DEF_HELPER_3(muls, tl, env, tl, tl)
diff --git a/target-mips/op_helper.c b/target-mips/op_helper.c
index 526f84f..45cbb2f 100644
--- a/target-mips/op_helper.c
+++ b/target-mips/op_helper.c
@@ -267,18 +267,6 @@ target_ulong helper_mulshiu(CPUMIPSState *env, 
target_ulong arg1,
(uint64_t)(uint32_t)arg2);
 }
 
-#ifdef TARGET_MIPS64
-void helper_dmult(CPUMIPSState *env, target_ulong arg1, target_ulong arg2)
-{
-muls64((env-active_tc.LO[0]), (env-active_tc.HI[0]), arg1, arg2);
-}
-
-void helper_dmultu(CPUMIPSState *env, target_ulong arg1, target_ulong arg2)
-{
-mulu64((env-active_tc.LO[0]), (env-active_tc.HI[0]), arg1, arg2);
-}
-#endif
-
 #ifndef CONFIG_USER_ONLY
 
 static inline hwaddr do_translate_address(CPUMIPSState *env,
diff --git a/target-mips/translate.c b/target-mips/translate.c
index 4ee9615..f10a533 100644
--- a/target-mips/translate.c
+++ b/target-mips/translate.c
@@ -2715,47 +2715,39 @@ static void gen_muldiv (DisasContext *ctx, uint32_t opc,
 break;
 case OPC_MULT:
 {
-TCGv_i64 t2 = tcg_temp_new_i64();
-TCGv_i64 t3 = tcg_temp_new_i64();
+TCGv_i32 t2 = tcg_temp_new_i32();
+TCGv_i32 t3 = tcg_temp_new_i32();
 acc = ((ctx-opcode)  11)  0x03;
 if (acc != 0) {
 check_dsp(ctx);
 }
 
-tcg_gen_ext_tl_i64(t2, t0);
-tcg_gen_ext_tl_i64(t3, t1);
-tcg_gen_mul_i64(t2, t2, t3);
-tcg_temp_free_i64(t3);
-tcg_gen_trunc_i64_tl(t0, t2);
-tcg_gen_shri_i64(t2, t2, 32);
-tcg_gen_trunc_i64_tl(t1, t2);
-tcg_temp_free_i64(t2);
-tcg_gen_ext32s_tl(cpu_LO[acc], t0);
-tcg_gen_ext32s_tl(cpu_HI[acc], t1);
+tcg_gen_trunc_tl_i32(t2, t0);
+tcg_gen_trunc_tl_i32(t3, t1);
+tcg_gen_muls2_i32(t2, t3, t2, t3);
+tcg_gen_ext_i32_tl(cpu_LO[acc], t2);
+tcg_gen_ext_i32_tl(cpu_HI[acc], t3);
+tcg_temp_free_i32(t2);
+tcg_temp_free_i32(t3);
 }
 opn = mult;
 break;
 case OPC_MULTU:
 {
-TCGv_i64 t2 = tcg_temp_new_i64();
-TCGv_i64 t3 = tcg_temp_new_i64();
+TCGv_i32 t2 = tcg_temp_new_i32();
+TCGv_i32 t3 = tcg_temp_new_i32();
 acc = ((ctx-opcode)  11)  0x03;
 if (acc != 0) {
 check_dsp(ctx);
 }
 
-tcg_gen_ext32u_tl(t0, t0);
-tcg_gen_ext32u_tl(t1, t1);
-tcg_gen_extu_tl_i64(t2, t0);
-tcg_gen_extu_tl_i64(t3, t1);
-tcg_gen_mul_i64(t2, t2, t3);
-tcg_temp_free_i64(t3);
-tcg_gen_trunc_i64_tl(t0, t2);
-tcg_gen_shri_i64(t2, t2, 32);
-tcg_gen_trunc_i64_tl(t1, t2);
-tcg_temp_free_i64(t2);
-tcg_gen_ext32s_tl(cpu_LO[acc], t0);
-tcg_gen_ext32s_tl(cpu_HI[acc], t1);
+tcg_gen_trunc_tl_i32(t2, t0);
+tcg_gen_trunc_tl_i32(t3, t1);
+tcg_gen_mulu2_i32(t2, t3, t2, t3);
+tcg_gen_ext_i32_tl(cpu_LO[acc], t2);
+tcg_gen_ext_i32_tl(cpu_HI[acc], t3);
+tcg_temp_free_i32(t2);
+tcg_temp_free_i32(t3);
 }
 opn = multu;
 break;
@@ -2791,11 +2783,11 @@ static void gen_muldiv (DisasContext *ctx, uint32_t opc,
 opn = ddivu;
 break;
 case OPC_DMULT:
-gen_helper_dmult(cpu_env, t0, t1);
+tcg_gen_muls2_i64(cpu_LO[0], cpu_HI[0], t0, t1);
 opn = dmult;
 break;
 case OPC_DMULTU:
-gen_helper_dmultu(cpu_env, t0, t1);
+tcg_gen_mulu2_i64(cpu_LO[0], cpu_HI[0], t0, t1);
 opn = dmultu;
 break;
 #endif
-- 
1.8.1.2




[Qemu-devel] [PATCH 18/38] target-arm: Use mul[us]2 and add2 in umlal et al

2013-02-20 Thread Richard Henderson
Cc: Peter Maydell peter.mayd...@linaro.org
Signed-off-by: Richard Henderson r...@twiddle.net
---
 target-arm/helper.c|  5 -
 target-arm/helper.h|  2 --
 target-arm/translate.c | 26 ++
 3 files changed, 14 insertions(+), 19 deletions(-)

diff --git a/target-arm/helper.c b/target-arm/helper.c
index e63da57..e97e1a5 100644
--- a/target-arm/helper.c
+++ b/target-arm/helper.c
@@ -2893,11 +2893,6 @@ uint32_t HELPER(sel_flags)(uint32_t flags, uint32_t a, 
uint32_t b)
 return (a  mask) | (b  ~mask);
 }
 
-uint32_t HELPER(logicq_cc)(uint64_t val)
-{
-return (val  32) | (val != 0);
-}
-
 /* VFP support.  We follow the convention used for VFP instructions:
Single precision routines have a s suffix, double precision a
d suffix.  */
diff --git a/target-arm/helper.h b/target-arm/helper.h
index 8544f82..bca5a5b 100644
--- a/target-arm/helper.h
+++ b/target-arm/helper.h
@@ -46,8 +46,6 @@ DEF_HELPER_3(usat16, i32, env, i32, i32)
 
 DEF_HELPER_FLAGS_2(usad8, TCG_CALL_NO_RWG_SE, i32, i32, i32)
 
-DEF_HELPER_1(logicq_cc, i32, i64)
-
 DEF_HELPER_FLAGS_3(sel_flags, TCG_CALL_NO_RWG_SE,
i32, i32, i32, i32)
 DEF_HELPER_2(exception, void, env, i32)
diff --git a/target-arm/translate.c b/target-arm/translate.c
index 129f674..efe76d0 100644
--- a/target-arm/translate.c
+++ b/target-arm/translate.c
@@ -6433,13 +6433,11 @@ static void gen_addq(DisasContext *s, TCGv_i64 val, int 
rlow, int rhigh)
 tcg_temp_free_i64(tmp);
 }
 
-/* Set N and Z flags from a 64-bit value.  */
-static void gen_logicq_cc(TCGv_i64 val)
+/* Set N and Z flags from hi|lo.  */
+static void gen_logicq_cc(TCGv lo, TCGv hi)
 {
-TCGv tmp = tcg_temp_new_i32();
-gen_helper_logicq_cc(tmp, val);
-gen_logic_CC(tmp);
-tcg_temp_free_i32(tmp);
+tcg_gen_mov_i32(cpu_NF, hi);
+tcg_gen_or_i32(cpu_ZF, lo, hi);
 }
 
 /* Load/Store exclusive instructions are implemented by remembering
@@ -7219,18 +7217,22 @@ static void disas_arm_insn(CPUARMState * env, 
DisasContext *s)
 tmp = load_reg(s, rs);
 tmp2 = load_reg(s, rm);
 if (insn  (1  22)) {
-tmp64 = gen_muls_i64_i32(tmp, tmp2);
+tcg_gen_muls2_i32(tmp, tmp2, tmp, tmp2);
 } else {
-tmp64 = gen_mulu_i64_i32(tmp, tmp2);
+tcg_gen_mulu2_i32(tmp, tmp2, tmp, tmp2);
 }
 if (insn  (1  21)) { /* mult accumulate */
-gen_addq(s, tmp64, rn, rd);
+TCGv al = load_reg(s, rn);
+TCGv ah = load_reg(s, rd);
+tcg_gen_add2_i32(tmp, tmp2, tmp, tmp2, al, ah);
+tcg_temp_free(al);
+tcg_temp_free(ah);
 }
 if (insn  (1  20)) {
-gen_logicq_cc(tmp64);
+gen_logicq_cc(tmp, tmp2);
 }
-gen_storeq_reg(s, rn, rd, tmp64);
-tcg_temp_free_i64(tmp64);
+store_reg(s, rn, tmp);
+store_reg(s, rd, tmp2);
 break;
 default:
 goto illegal_op;
-- 
1.8.1.2




[Qemu-devel] [PATCH 23/38] target-cris: Use mul*2 in mul* insns

2013-02-20 Thread Richard Henderson
Cc: Edgar E. Iglesias edgar.igles...@gmail.com
Signed-off-by: Richard Henderson r...@twiddle.net
---
 target-cris/translate.c | 44 ++--
 1 file changed, 2 insertions(+), 42 deletions(-)

diff --git a/target-cris/translate.c b/target-cris/translate.c
index 04a5379..df4dbd3 100644
--- a/target-cris/translate.c
+++ b/target-cris/translate.c
@@ -340,46 +340,6 @@ static void t_gen_asr(TCGv d, TCGv a, TCGv b)
 tcg_temp_free(t_31);
 }
 
-/* 64-bit signed mul, lower result in d and upper in d2.  */
-static void t_gen_muls(TCGv d, TCGv d2, TCGv a, TCGv b)
-{
-TCGv_i64 t0, t1;
-
-t0 = tcg_temp_new_i64();
-t1 = tcg_temp_new_i64();
-
-tcg_gen_ext_i32_i64(t0, a);
-tcg_gen_ext_i32_i64(t1, b);
-tcg_gen_mul_i64(t0, t0, t1);
-
-tcg_gen_trunc_i64_i32(d, t0);
-tcg_gen_shri_i64(t0, t0, 32);
-tcg_gen_trunc_i64_i32(d2, t0);
-
-tcg_temp_free_i64(t0);
-tcg_temp_free_i64(t1);
-}
-
-/* 64-bit unsigned muls, lower result in d and upper in d2.  */
-static void t_gen_mulu(TCGv d, TCGv d2, TCGv a, TCGv b)
-{
-TCGv_i64 t0, t1;
-
-t0 = tcg_temp_new_i64();
-t1 = tcg_temp_new_i64();
-
-tcg_gen_extu_i32_i64(t0, a);
-tcg_gen_extu_i32_i64(t1, b);
-tcg_gen_mul_i64(t0, t0, t1);
-
-tcg_gen_trunc_i64_i32(d, t0);
-tcg_gen_shri_i64(t0, t0, 32);
-tcg_gen_trunc_i64_i32(d2, t0);
-
-tcg_temp_free_i64(t0);
-tcg_temp_free_i64(t1);
-}
-
 static void t_gen_cris_dstep(TCGv d, TCGv a, TCGv b)
 {
 int l1;
@@ -832,10 +792,10 @@ static void cris_alu_op_exec(DisasContext *dc, int op,
 gen_helper_lz(dst, b);
 break;
 case CC_OP_MULS:
-t_gen_muls(dst, cpu_PR[PR_MOF], a, b);
+tcg_gen_muls2_tl(dst, cpu_PR[PR_MOF], a, b);
 break;
 case CC_OP_MULU:
-t_gen_mulu(dst, cpu_PR[PR_MOF], a, b);
+tcg_gen_mulu2_tl(dst, cpu_PR[PR_MOF], a, b);
 break;
 case CC_OP_DSTEP:
 t_gen_cris_dstep(dst, a, b);
-- 
1.8.1.2




[Qemu-devel] [PATCH 11/38] target-i386: Use mulu2 and muls2

2013-02-20 Thread Richard Henderson
These correspond very closely to the insns that we're emulating.

Signed-off-by: Richard Henderson r...@twiddle.net
---
 target-i386/helper.h |   4 --
 target-i386/int_helper.c |  40 
 target-i386/translate.c  | 167 ---
 3 files changed, 56 insertions(+), 155 deletions(-)

diff --git a/target-i386/helper.h b/target-i386/helper.h
index 26a0cc8..d6974df 100644
--- a/target-i386/helper.h
+++ b/target-i386/helper.h
@@ -14,12 +14,8 @@ DEF_HELPER_2(idivw_AX, void, env, tl)
 DEF_HELPER_2(divl_EAX, void, env, tl)
 DEF_HELPER_2(idivl_EAX, void, env, tl)
 #ifdef TARGET_X86_64
-DEF_HELPER_2(mulq_EAX_T0, void, env, tl)
-DEF_HELPER_2(imulq_EAX_T0, void, env, tl)
-DEF_HELPER_3(imulq_T0_T1, tl, env, tl, tl)
 DEF_HELPER_2(divq_EAX, void, env, tl)
 DEF_HELPER_2(idivq_EAX, void, env, tl)
-DEF_HELPER_FLAGS_2(umulh, TCG_CALL_NO_RWG_SE, tl, tl, tl)
 #endif
 
 DEF_HELPER_2(aam, void, env, int)
diff --git a/target-i386/int_helper.c b/target-i386/int_helper.c
index 3b56075..74c7c36 100644
--- a/target-i386/int_helper.c
+++ b/target-i386/int_helper.c
@@ -374,46 +374,6 @@ static int idiv64(uint64_t *plow, uint64_t *phigh, int64_t 
b)
 return 0;
 }
 
-void helper_mulq_EAX_T0(CPUX86State *env, target_ulong t0)
-{
-uint64_t r0, r1;
-
-mulu64(r0, r1, EAX, t0);
-EAX = r0;
-EDX = r1;
-CC_DST = r0;
-CC_SRC = r1;
-}
-
-target_ulong helper_umulh(target_ulong t0, target_ulong t1)
-{
-uint64_t h, l;
-mulu64(l, h, t0, t1);
-return h;
-}
-
-void helper_imulq_EAX_T0(CPUX86State *env, target_ulong t0)
-{
-uint64_t r0, r1;
-
-muls64(r0, r1, EAX, t0);
-EAX = r0;
-EDX = r1;
-CC_DST = r0;
-CC_SRC = ((int64_t)r1 != ((int64_t)r0  63));
-}
-
-target_ulong helper_imulq_T0_T1(CPUX86State *env, target_ulong t0,
-target_ulong t1)
-{
-uint64_t r0, r1;
-
-muls64(r0, r1, t0, t1);
-CC_DST = r0;
-CC_SRC = ((int64_t)r1 != ((int64_t)r0  63));
-return r0;
-}
-
 void helper_divq_EAX(CPUX86State *env, target_ulong t0)
 {
 uint64_t r0, r1;
diff --git a/target-i386/translate.c b/target-i386/translate.c
index 439d19e..1545e3f 100644
--- a/target-i386/translate.c
+++ b/target-i386/translate.c
@@ -4111,31 +4111,18 @@ static void gen_sse(CPUX86State *env, DisasContext *s, 
int b,
 ot = s-dflag == 2 ? OT_QUAD : OT_LONG;
 gen_ldst_modrm(env, s, modrm, ot, OR_TMP0, 0);
 switch (ot) {
-TCGv_i64 t0, t1;
 default:
-t0 = tcg_temp_new_i64();
-t1 = tcg_temp_new_i64();
-#ifdef TARGET_X86_64
-tcg_gen_ext32u_i64(t0, cpu_T[0]);
-tcg_gen_ext32u_i64(t1, cpu_regs[R_EDX]);
-#else
-tcg_gen_extu_i32_i64(t0, cpu_T[0]);
-tcg_gen_extu_i32_i64(t0, cpu_regs[R_EDX]);
-#endif
-tcg_gen_mul_i64(t0, t0, t1);
-tcg_gen_trunc_i64_tl(cpu_T[0], t0);
-tcg_gen_shri_i64(t0, t0, 32);
-tcg_gen_trunc_i64_tl(cpu_T[1], t0);
-tcg_temp_free_i64(t0);
-tcg_temp_free_i64(t1);
-gen_op_mov_reg_T0(OT_LONG, s-vex_v);
-gen_op_mov_reg_T1(OT_LONG, reg);
+tcg_gen_trunc_tl_i32(cpu_tmp2_i32, cpu_T[0]);
+tcg_gen_trunc_tl_i32(cpu_tmp3_i32, cpu_regs[R_EDX]);
+tcg_gen_mulu2_i32(cpu_tmp2_i32, cpu_tmp3_i32,
+  cpu_tmp2_i32, cpu_tmp3_i32);
+tcg_gen_extu_i32_tl(cpu_regs[s-vex_v], cpu_tmp2_i32);
+tcg_gen_extu_i32_tl(cpu_regs[reg], cpu_tmp3_i32);
 break;
 #ifdef TARGET_X86_64
 case OT_QUAD:
-tcg_gen_mov_tl(cpu_T[1], cpu_regs[R_EDX]);
-tcg_gen_mul_tl(cpu_regs[s-vex_v], cpu_T[0], cpu_T[1]);
-gen_helper_umulh(cpu_regs[reg], cpu_T[0], cpu_T[1]);
+tcg_gen_mulu2_i64(cpu_regs[s-vex_v], cpu_regs[reg],
+  cpu_T[0], cpu_regs[R_EDX]);
 break;
 #endif
 }
@@ -5034,39 +5021,22 @@ static target_ulong disas_insn(CPUX86State *env, 
DisasContext *s,
 break;
 default:
 case OT_LONG:
-#ifdef TARGET_X86_64
-gen_op_mov_TN_reg(OT_LONG, 1, R_EAX);
-tcg_gen_ext32u_tl(cpu_T[0], cpu_T[0]);
-tcg_gen_ext32u_tl(cpu_T[1], cpu_T[1]);
-tcg_gen_mul_tl(cpu_T[0], cpu_T[0], cpu_T[1]);
-gen_op_mov_reg_T0(OT_LONG, R_EAX);
-tcg_gen_mov_tl(cpu_cc_dst, cpu_T[0]);
-tcg_gen_shri_tl(cpu_T[0], cpu_T[0], 32);
-gen_op_mov_reg_T0(OT_LONG, R_EDX);
-tcg_gen_mov_tl(cpu_cc_src, cpu_T[0]);
-#else
-{
-TCGv_i64 t0, t1;
-  

[Qemu-devel] [PATCH 25/38] target-ppc: Split out SO, OV, CA fields from XER

2013-02-20 Thread Richard Henderson
In preparation for more efficient setting of these fields.

Cc: Alexander Graf ag...@suse.de
Signed-off-by: Richard Henderson r...@twiddle.net
---
 target-ppc/cpu.h|  24 +-
 target-ppc/int_helper.c |  38 -
 target-ppc/kvm.c|   4 +-
 target-ppc/machine.c|   8 +-
 target-ppc/translate.c  | 188 +++-
 target-ppc/translate_init.c |   4 +-
 6 files changed, 160 insertions(+), 106 deletions(-)

diff --git a/target-ppc/cpu.h b/target-ppc/cpu.h
index 8c081db..20f4565 100644
--- a/target-ppc/cpu.h
+++ b/target-ppc/cpu.h
@@ -941,8 +941,11 @@ struct CPUPPCState {
 /* CFAR */
 target_ulong cfar;
 #endif
-/* XER */
+/* XER (with SO, OV, CA split out) */
 target_ulong xer;
+target_ulong so;
+target_ulong ov;
+target_ulong ca;
 /* Reservation address */
 target_ulong reserve_addr;
 /* Reservation value */
@@ -1268,9 +1271,9 @@ static inline void cpu_clone_regs(CPUPPCState *env, 
target_ulong newsp)
 #define XER_CA  29
 #define XER_CMP  8
 #define XER_BC   0
-#define xer_so  ((env-xer  XER_SO)  1)
-#define xer_ov  ((env-xer  XER_OV)  1)
-#define xer_ca  ((env-xer  XER_CA)  1)
+#define xer_so  (env-so)
+#define xer_ov  (env-ov)
+#define xer_ca  (env-ca)
 #define xer_cmp ((env-xer  XER_CMP)  0xFF)
 #define xer_bc  ((env-xer  XER_BC)   0x7F)
 
@@ -2087,6 +2090,19 @@ enum {
 
 /*/
 
+static inline target_ulong cpu_read_xer(CPUPPCState *env)
+{
+return env-xer | (env-so  XER_SO) | (env-ov  XER_OV) | (env-ca  
XER_CA);
+}
+
+static inline void cpu_write_xer(CPUPPCState *env, target_ulong xer)
+{
+env-so = (xer  XER_SO)  1;
+env-ov = (xer  XER_OV)  1;
+env-ca = (xer  XER_CA)  1;
+env-xer = xer  ~((1u  XER_SO) | (1u  XER_OV) | (1u  XER_CA));
+}
+
 static inline void cpu_get_tb_cpu_state(CPUPPCState *env, target_ulong *pc,
 target_ulong *cs_base, int *flags)
 {
diff --git a/target-ppc/int_helper.c b/target-ppc/int_helper.c
index 8653151..54eca9b 100644
--- a/target-ppc/int_helper.c
+++ b/target-ppc/int_helper.c
@@ -33,9 +33,9 @@ uint64_t helper_mulldo(CPUPPCState *env, uint64_t arg1, 
uint64_t arg2)
 muls64(tl, (uint64_t *)th, arg1, arg2);
 /* If th != 0  th != -1, then we had an overflow */
 if (likely((uint64_t)(th + 1) = 1)) {
-env-xer = ~(1  XER_OV);
+env-ov = 0;
 } else {
-env-xer |= (1  XER_OV) | (1  XER_SO);
+env-so = env-ov = 1;
 }
 return (int64_t)tl;
 }
@@ -64,21 +64,17 @@ target_ulong helper_sraw(CPUPPCState *env, target_ulong 
value,
 shift = 0x1f;
 ret = (int32_t)value  shift;
 if (likely(ret = 0 || (value  ((1  shift) - 1)) == 0)) {
-env-xer = ~(1  XER_CA);
+env-ca = 0;
 } else {
-env-xer |= (1  XER_CA);
+env-ca = 1;
 }
 } else {
 ret = (int32_t)value;
-env-xer = ~(1  XER_CA);
+env-ca = 0;
 }
 } else {
 ret = (int32_t)value  31;
-if (ret) {
-env-xer |= (1  XER_CA);
-} else {
-env-xer = ~(1  XER_CA);
-}
+env-ca = (ret != 0);
 }
 return (target_long)ret;
 }
@@ -94,21 +90,17 @@ target_ulong helper_srad(CPUPPCState *env, target_ulong 
value,
 shift = 0x3f;
 ret = (int64_t)value  shift;
 if (likely(ret = 0 || (value  ((1  shift) - 1)) == 0)) {
-env-xer = ~(1  XER_CA);
+env-ca = 0;
 } else {
-env-xer |= (1  XER_CA);
+env-ca = 1;
 }
 } else {
 ret = (int64_t)value;
-env-xer = ~(1  XER_CA);
+env-ca = 0;
 }
 } else {
 ret = (int64_t)value  63;
-if (ret) {
-env-xer |= (1  XER_CA);
-} else {
-env-xer = ~(1  XER_CA);
-}
+env-ca = (ret != 0);
 }
 return ret;
 }
@@ -188,16 +180,16 @@ target_ulong helper_divo(CPUPPCState *env, target_ulong 
arg1,
 
 if (((int32_t)tmp == INT32_MIN  (int32_t)arg2 == (int32_t)-1) ||
 (int32_t)arg2 == 0) {
-env-xer |= (1  XER_OV) | (1  XER_SO);
+env-so = env-ov = 1;
 env-spr[SPR_MQ] = 0;
 return INT32_MIN;
 } else {
 env-spr[SPR_MQ] = tmp % arg2;
 tmp /= (int32_t)arg2;
 if ((int32_t)tmp != tmp) {
-env-xer |= (1  XER_OV) | (1  XER_SO);
+env-so = env-ov = 1;
 } else {
-env-xer = ~(1  XER_OV);
+env-ov = 0;
 }
 return tmp;
 }
@@ -221,11 +213,11 @@ target_ulong helper_divso(CPUPPCState *env, target_ulong 
arg1,
 {
 if (((int32_t)arg1 == INT32_MIN  (int32_t)arg2 == (int32_t)-1) ||
 (int32_t)arg2 == 0) {
-env-xer |= 

[Qemu-devel] [PATCH 17/38] target-arm: Use mul[us]2 in gen_mul[us]_i64_i32

2013-02-20 Thread Richard Henderson
Cc: Peter Maydell peter.mayd...@linaro.org
Signed-off-by: Richard Henderson r...@twiddle.net
---
 target-arm/translate.c | 38 ++
 1 file changed, 22 insertions(+), 16 deletions(-)

diff --git a/target-arm/translate.c b/target-arm/translate.c
index a8893f7..129f674 100644
--- a/target-arm/translate.c
+++ b/target-arm/translate.c
@@ -305,35 +305,41 @@ static TCGv_i64 gen_subq_msw(TCGv_i64 a, TCGv b)
 return a;
 }
 
-/* FIXME: Most targets have native widening multiplication.
-   It would be good to use that instead of a full wide multiply.  */
 /* 32x32-64 multiply.  Marks inputs as dead.  */
 static TCGv_i64 gen_mulu_i64_i32(TCGv a, TCGv b)
 {
-TCGv_i64 tmp1 = tcg_temp_new_i64();
-TCGv_i64 tmp2 = tcg_temp_new_i64();
+TCGv lo = tcg_temp_new_i32();
+TCGv hi = tcg_temp_new_i32();
+TCGv_i64 ret;
 
-tcg_gen_extu_i32_i64(tmp1, a);
+tcg_gen_mulu2_i32(lo, hi, a, b);
 tcg_temp_free_i32(a);
-tcg_gen_extu_i32_i64(tmp2, b);
 tcg_temp_free_i32(b);
-tcg_gen_mul_i64(tmp1, tmp1, tmp2);
-tcg_temp_free_i64(tmp2);
-return tmp1;
+
+ret = tcg_temp_new_i64();
+tcg_gen_concat_i32_i64(ret, lo, hi);
+tcg_temp_free(lo);
+tcg_temp_free(hi);
+
+return ret;
 }
 
 static TCGv_i64 gen_muls_i64_i32(TCGv a, TCGv b)
 {
-TCGv_i64 tmp1 = tcg_temp_new_i64();
-TCGv_i64 tmp2 = tcg_temp_new_i64();
+TCGv lo = tcg_temp_new_i32();
+TCGv hi = tcg_temp_new_i32();
+TCGv_i64 ret;
 
-tcg_gen_ext_i32_i64(tmp1, a);
+tcg_gen_muls2_i32(lo, hi, a, b);
 tcg_temp_free_i32(a);
-tcg_gen_ext_i32_i64(tmp2, b);
 tcg_temp_free_i32(b);
-tcg_gen_mul_i64(tmp1, tmp1, tmp2);
-tcg_temp_free_i64(tmp2);
-return tmp1;
+
+ret = tcg_temp_new_i64();
+tcg_gen_concat_i32_i64(ret, lo, hi);
+tcg_temp_free(lo);
+tcg_temp_free(hi);
+
+return ret;
 }
 
 /* Swap low and high halfwords.  */
-- 
1.8.1.2




[Qemu-devel] [PATCH 13/38] tcg: Implement muls2 with mulu2

2013-02-20 Thread Richard Henderson
Signed-off-by: Richard Henderson r...@twiddle.net
---
 tcg/tcg-op.h | 40 
 1 file changed, 40 insertions(+)

diff --git a/tcg/tcg-op.h b/tcg/tcg-op.h
index dac3b4e..d70b2eb 100644
--- a/tcg/tcg-op.h
+++ b/tcg/tcg-op.h
@@ -2396,6 +2396,26 @@ static inline void tcg_gen_muls2_i32(TCGv_i32 rl, 
TCGv_i32 rh,
 tcg_gen_op4_i32(INDEX_op_muls2_i32, rl, rh, arg1, arg2);
 /* Allow the optimizer room to replace muls2 with two moves.  */
 tcg_gen_op0(INDEX_op_nop);
+} else if (TCG_TARGET_REG_BITS == 32  TCG_TARGET_HAS_mulu2_i32) {
+TCGv_i32 t0 = tcg_temp_new_i32();
+TCGv_i32 t1 = tcg_temp_new_i32();
+TCGv_i32 t2 = tcg_temp_new_i32();
+TCGv_i32 t3 = tcg_temp_new_i32();
+tcg_gen_op4_i32(INDEX_op_mulu2_i32, t0, t1, arg1, arg2);
+/* Allow the optimizer room to replace mulu2 with two moves.  */
+tcg_gen_op0(INDEX_op_nop);
+/* Adjust for negative inputs.  */
+tcg_gen_sari_i32(t2, arg1, 31);
+tcg_gen_sari_i32(t3, arg2, 31);
+tcg_gen_and_i32(t2, t2, arg2);
+tcg_gen_and_i32(t3, t3, arg1);
+tcg_gen_sub_i32(rh, t1, t2);
+tcg_gen_sub_i32(rh, rh, t3);
+tcg_gen_mov_i32(rl, t0);
+tcg_temp_free_i32(t0);
+tcg_temp_free_i32(t1);
+tcg_temp_free_i32(t2);
+tcg_temp_free_i32(t3);
 } else {
 TCGv_i64 t0 = tcg_temp_new_i64();
 TCGv_i64 t1 = tcg_temp_new_i64();
@@ -2455,6 +2475,26 @@ static inline void tcg_gen_mulu2_i64(TCGv_i64 rl, 
TCGv_i64 rh,
 tcg_gen_op4_i64(INDEX_op_mulu2_i64, rl, rh, arg1, arg2);
 /* Allow the optimizer room to replace mulu2 with two moves.  */
 tcg_gen_op0(INDEX_op_nop);
+} else if (TCG_TARGET_HAS_mulu2_i64) {
+TCGv_i64 t0 = tcg_temp_new_i64();
+TCGv_i64 t1 = tcg_temp_new_i64();
+TCGv_i64 t2 = tcg_temp_new_i64();
+TCGv_i64 t3 = tcg_temp_new_i64();
+tcg_gen_op4_i64(INDEX_op_mulu2_i64, t0, t1, arg1, arg2);
+/* Allow the optimizer room to replace mulu2 with two moves.  */
+tcg_gen_op0(INDEX_op_nop);
+/* Adjust for negative inputs.  */
+tcg_gen_sari_i64(t2, arg1, 63);
+tcg_gen_sari_i64(t3, arg2, 63);
+tcg_gen_and_i64(t2, t2, arg2);
+tcg_gen_and_i64(t3, t3, arg1);
+tcg_gen_sub_i64(rh, t1, t2);
+tcg_gen_sub_i64(rh, rh, t3);
+tcg_gen_mov_i64(rl, t0);
+tcg_temp_free_i64(t0);
+tcg_temp_free_i64(t1);
+tcg_temp_free_i64(t2);
+tcg_temp_free_i64(t3);
 } else {
 TCGv_i64 t0 = tcg_temp_new_i64();
 int sizemask = 0;
-- 
1.8.1.2




[Qemu-devel] [PATCH v4 2/6] add basic backup support to block driver

2013-02-20 Thread Dietmar Maurer
Function backup_job_create() creates a block job to backup a block device.
The coroutine is started with backup_job_start().

We call backup_do_cow() for each write during backup. That function
reads the original data and pass it to backup_dump_cb().

The tracked_request infrastructure is used to serialize access.

Currently backup cluster size is hardcoded to 65536 bytes.

Signed-off-by: Dietmar Maurer diet...@proxmox.com
---
 Makefile.objs|1 +
 backup.c |  338 ++
 backup.h |   32 +
 block.c  |   71 +-
 include/block/block.h|2 +
 include/block/blockjob.h |   10 ++
 6 files changed, 448 insertions(+), 6 deletions(-)
 create mode 100644 backup.c
 create mode 100644 backup.h

diff --git a/Makefile.objs b/Makefile.objs
index a68cdac..df64f70 100644
--- a/Makefile.objs
+++ b/Makefile.objs
@@ -13,6 +13,7 @@ block-obj-$(CONFIG_POSIX) += aio-posix.o
 block-obj-$(CONFIG_WIN32) += aio-win32.o
 block-obj-y += block/
 block-obj-y += qapi-types.o qapi-visit.o
+block-obj-y += backup.o
 
 block-obj-y += qemu-coroutine.o qemu-coroutine-lock.o qemu-coroutine-io.o
 block-obj-y += qemu-coroutine-sleep.o
diff --git a/backup.c b/backup.c
new file mode 100644
index 000..c9576d5
--- /dev/null
+++ b/backup.c
@@ -0,0 +1,338 @@
+/*
+ * QEMU backup
+ *
+ * Copyright (C) 2013 Proxmox Server Solutions
+ *
+ * Authors:
+ *  Dietmar Maurer (diet...@proxmox.com)
+ *
+ * This work is licensed under the terms of the GNU GPL, version 2 or later.
+ * See the COPYING file in the top-level directory.
+ *
+ */
+
+#include stdio.h
+#include errno.h
+#include unistd.h
+
+#include block/block.h
+#include block/block_int.h
+#include block/blockjob.h
+#include qemu/ratelimit.h
+#include backup.h
+
+#define DEBUG_BACKUP 0
+
+#define DPRINTF(fmt, ...) \
+do { if (DEBUG_BACKUP) { printf(backup:  fmt, ## __VA_ARGS__); } } \
+while (0)
+
+
+#define SLICE_TIME 1ULL /* ns */
+
+typedef struct BackupBlockJob {
+BlockJob common;
+RateLimit limit;
+uint64_t sectors_read;
+unsigned long *bitmap;
+int bitmap_size;
+BackupDumpFunc *backup_dump_cb;
+BlockDriverCompletionFunc *backup_complete_cb;
+void *opaque;
+} BackupBlockJob;
+
+static int backup_get_bitmap(BackupBlockJob *job, int64_t cluster_num)
+{
+assert(job);
+assert(job-bitmap);
+
+unsigned long val, idx, bit;
+
+idx = cluster_num / BITS_PER_LONG;
+
+assert(job-bitmap_size  idx);
+
+bit = cluster_num % BITS_PER_LONG;
+val = job-bitmap[idx];
+
+return !!(val  (1UL  bit));
+}
+
+static void backup_set_bitmap(BackupBlockJob *job, int64_t cluster_num,
+  int dirty)
+{
+assert(job);
+assert(job-bitmap);
+
+unsigned long val, idx, bit;
+
+idx = cluster_num / BITS_PER_LONG;
+
+assert(job-bitmap_size  idx);
+
+bit = cluster_num % BITS_PER_LONG;
+val = job-bitmap[idx];
+if (dirty) {
+if (!(val  (1UL  bit))) {
+val |= 1UL  bit;
+}
+} else {
+if (val  (1UL  bit)) {
+val = ~(1UL  bit);
+}
+}
+job-bitmap[idx] = val;
+}
+
+static int backup_in_progress_count;
+
+static int coroutine_fn backup_do_cow(BlockDriverState *bs,
+  int64_t sector_num, int nb_sectors)
+{
+assert(bs);
+BackupBlockJob *job = (BackupBlockJob *)bs-job;
+assert(job);
+
+BlockDriver *drv = bs-drv;
+struct iovec iov;
+QEMUIOVector bounce_qiov;
+void *bounce_buffer = NULL;
+int ret = 0;
+
+backup_in_progress_count++;
+
+int64_t start, end;
+
+start = sector_num / BACKUP_BLOCKS_PER_CLUSTER;
+end = (sector_num + nb_sectors + BACKUP_BLOCKS_PER_CLUSTER - 1) /
+BACKUP_BLOCKS_PER_CLUSTER;
+
+DPRINTF(brdv_co_backup_cow enter %s C%zd %zd %d\n,
+bdrv_get_device_name(bs), start, sector_num, nb_sectors);
+
+for (; start  end; start++) {
+if (backup_get_bitmap(job, start)) {
+DPRINTF(brdv_co_backup_cow skip C%zd\n, start);
+continue; /* already copied */
+}
+
+/* immediately set bitmap (avoid coroutine race) */
+backup_set_bitmap(job, start, 1);
+
+DPRINTF(brdv_co_backup_cow C%zd\n, start);
+
+if (!bounce_buffer) {
+iov.iov_len = BACKUP_CLUSTER_SIZE;
+iov.iov_base = bounce_buffer = qemu_blockalign(bs, iov.iov_len);
+qemu_iovec_init_external(bounce_qiov, iov, 1);
+}
+
+ret = drv-bdrv_co_readv(bs, start * BACKUP_BLOCKS_PER_CLUSTER,
+ BACKUP_BLOCKS_PER_CLUSTER,
+ bounce_qiov);
+
+job-sectors_read += BACKUP_BLOCKS_PER_CLUSTER;
+
+if (ret  0) {
+DPRINTF(brdv_co_backup_cow bdrv_read C%zd failed\n, start);
+goto out;
+}
+
+ret = job-backup_dump_cb(job-opaque, bs, start, 

[Qemu-devel] [PATCH v4 6/6] add vm state to backups

2013-02-20 Thread Dietmar Maurer

Signed-off-by: Dietmar Maurer diet...@proxmox.com
---
 blockdev.c   |  196 +-
 hmp.c|3 +-
 qapi-schema.json |5 +-
 3 files changed, 200 insertions(+), 4 deletions(-)

diff --git a/blockdev.c b/blockdev.c
index 1cfc780..1b81824 100644
--- a/blockdev.c
+++ b/blockdev.c
@@ -22,6 +22,8 @@
 #include sysemu/arch_init.h
 #include backup.h
 #include vma.h
+#include migration/qemu-file.h
+#include migration/migration.h
 
 static QTAILQ_HEAD(drivelist, DriveInfo) drives = 
QTAILQ_HEAD_INITIALIZER(drives);
 
@@ -1355,6 +1357,10 @@ static struct GenericBackupState {
 size_t total;
 size_t transferred;
 size_t zero_bytes;
+unsigned char buf[BACKUP_CLUSTER_SIZE];
+int buf_index;
+size_t buf_cluster_num;
+guint8 vmstate_dev_id;
 } backup_state;
 
 typedef struct BackupCB {
@@ -1510,10 +1516,170 @@ static void backup_start_jobs(void)
 backup_run_next_job();
 }
 
+static int backup_state_close(void *opaque)
+{
+if (!backup_state.buf_index) {
+return 0;
+}
+
+size_t zero_bytes = 0;
+if (backup_state.buf_index  BACKUP_CLUSTER_SIZE) {
+memset(backup_state.buf + backup_state.buf_index, 0,
+   BACKUP_CLUSTER_SIZE - backup_state.buf_index);
+}
+int bytes = backup_state.driver-dump_cb(
+backup_state.writer, backup_state.vmstate_dev_id,
+backup_state.buf_cluster_num,
+backup_state.buf, zero_bytes);
+backup_state.buf_index = 0;
+
+return bytes  0 ? -1 : 0;
+}
+
+static int backup_state_put_buffer(void *opaque, const uint8_t *buf,
+   int64_t pos, int size)
+{
+assert(backup_state.driver);
+assert(backup_state.writer);
+assert(backup_state.driver-dump_cb);
+
+/* Note: our backup driver expects to get whole clusters (64KB) */
+
+int ret = size;
+
+while (size  0) {
+int l = BACKUP_CLUSTER_SIZE - backup_state.buf_index;
+l = l  size ? size : l;
+memcpy(backup_state.buf + backup_state.buf_index, buf, l);
+backup_state.buf_index += l;
+buf += l;
+size -= l;
+if (backup_state.buf_index == BACKUP_CLUSTER_SIZE) {
+size_t zero_bytes = 0;
+int bytes = backup_state.driver-dump_cb(
+backup_state.writer, backup_state.vmstate_dev_id,
+backup_state.buf_cluster_num++,
+backup_state.buf, zero_bytes);
+backup_state.buf_index = 0;
+if (bytes  0) {
+return -1;
+}
+}
+}
+
+return ret;
+}
+
+static const QEMUFileOps backup_file_ops = {
+.put_buffer = backup_state_put_buffer,
+.close = backup_state_close,
+};
+
+static void coroutine_fn backup_start_savevm(void *opaque)
+{
+assert(backup_state.driver);
+assert(backup_state.writer);
+int ret;
+char *err = NULL;
+uint64_t remaining;
+int64_t maxlen;
+MigrationParams params = {
+.blk = 0,
+.shared = 0
+};
+
+int restart = 0;
+
+QEMUFile *file = qemu_fopen_ops(NULL, backup_file_ops);
+
+ret = qemu_savevm_state_begin(file, params);
+if (ret  0) {
+qemu_fclose(file);
+err = g_strdup(qemu_savevm_state_begin failed);
+goto abort;
+}
+
+while (1) {
+ret = qemu_savevm_state_iterate(file);
+remaining = ram_bytes_remaining();
+
+if (ret  0) {
+qemu_fclose(file);
+err = g_strdup_printf(qemu_savevm_state_iterate error %d, ret);
+goto abort;
+}
+
+/* stop the VM if we use too much space,
+ * or if remaining is just a few MB
+ */
+maxlen = ram_bytes_total();
+size_t cpos = backup_state.buf_cluster_num * BACKUP_CLUSTER_SIZE;
+if ((remaining  10) || ((cpos + remaining) = maxlen)) {
+if (runstate_is_running()) {
+restart = 1;
+vm_stop(RUN_STATE_SAVE_VM);
+   }
+}
+
+if (ret == 1) { /* finished */
+if (runstate_is_running()) {
+restart = 1;
+vm_stop(RUN_STATE_SAVE_VM);
+}
+
+ret = qemu_savevm_state_complete(file);
+if (ret  0) {
+qemu_fclose(file);
+err = g_strdup(qemu_savevm_state_complete error);
+goto abort;
+
+} else {
+if (qemu_fclose(file)  0) {
+error_setg(backup_state.error,
+   backup_start_savevm: qemu_fclose failed);
+goto abort;
+}
+if (backup_state.driver-complete_cb(backup_state.writer,
+backup_state.vmstate_dev_id, 0)  0) {
+err = g_strdup(backup_start_savevm: complete_cb failed);
+goto abort;
+}
+backup_run_next_job();
+goto 

Re: [Qemu-devel] [PATCH 1/2] coroutine: move pooling to common code

2013-02-20 Thread Kevin Wolf
On Tue, Feb 19, 2013 at 11:59:09AM +0100, Paolo Bonzini wrote:
 The coroutine pool code is duplicated between the ucontext and
 sigaltstack backends, and absent from the win32 backend.  But the
 code can be shared easily by moving it to qemu-coroutine.c.
 
 Signed-off-by: Paolo Bonzini pbonz...@redhat.com

Thanks, applied both to the block branch.

Kevin



Re: [Qemu-devel] [PATCH] tap: forbid creating multiqueue tap when hub is used

2013-02-20 Thread Paolo Bonzini
Il 20/02/2013 10:18, Jason Wang ha scritto:
 Obviously, hub does not support multiqueue tap. So this patch forbids creating
 multiple queue tap when hub is used to prevent the crash when command line 
 such
 as -net tap,queues=2 is used.
 
 Signed-off-by: Jason Wang jasow...@redhat.com
 ---
 This patch is needed for 1.4 stable also.

Stefan, please add Cc when committing to the net branch.

Jason, next time please add the Cc yourself to the body.

Paolo

 ---
  net/tap.c |6 ++
  1 files changed, 6 insertions(+), 0 deletions(-)
 
 diff --git a/net/tap.c b/net/tap.c
 index 48c254e..1e14f59 100644
 --- a/net/tap.c
 +++ b/net/tap.c
 @@ -693,6 +693,12 @@ int net_init_tap(const NetClientOptions *opts, const 
 char *name,
  queues = tap-has_queues ? tap-queues : 1;
  vhostfdname = tap-has_vhostfd ? tap-vhostfd : NULL;
  
 +if (peer  (tap-has_queues || tap-has_fds || tap-has_vhostfds)) {
 +error_report(This configuration is not compatiable with multiqueue
 +  tap);
 +return -1;
 +}
 +
  if (tap-has_fd) {
  if (tap-has_ifname || tap-has_script || tap-has_downscript ||
  tap-has_vnet_hdr || tap-has_helper || tap-has_queues ||
 




Re: [Qemu-devel] Online resize of virtio-blk device does not emit udev event

2013-02-20 Thread Stefan Hajnoczi
On Tue, Feb 19, 2013 at 10:15:32PM +0100, Milos Vyletel wrote:
 I was looking at the virtblk_config_changed_work function in RHEL6.3 kernel's
 drivers/block/virtio_blk.c which I believe is the function handling 
 blockresize
 and it does not look like it tries to emit any kobject uevent.
 
 Before I jump into patching kernel my question is whether it makes sense to 
 have
 such uevent? I surely can use a way how to detect capacity change from 
 userspace.

I suggest checking how other block drivers (including the device-mapper
and scsi layers) handle resize.  Perhaps virtio_blk.c can follow an
existing approach.

Stefan



[Qemu-devel] [PATCH 10/38] tcg-arm: Implement muls2_i32

2013-02-20 Thread Richard Henderson
We even had the encoding of smull already handy...

Cc: Andrzej Zaborowski balr...@gmail.com
Signed-off-by: Richard Henderson r...@twiddle.net
---
 tcg/arm/tcg-target.c | 4 
 tcg/arm/tcg-target.h | 2 +-
 2 files changed, 5 insertions(+), 1 deletion(-)

diff --git a/tcg/arm/tcg-target.c b/tcg/arm/tcg-target.c
index d9c33d8..94c6ca4 100644
--- a/tcg/arm/tcg-target.c
+++ b/tcg/arm/tcg-target.c
@@ -1647,6 +1647,9 @@ static inline void tcg_out_op(TCGContext *s, TCGOpcode 
opc,
 case INDEX_op_mulu2_i32:
 tcg_out_umull32(s, COND_AL, args[0], args[1], args[2], args[3]);
 break;
+case INDEX_op_muls2_i32:
+tcg_out_smull32(s, COND_AL, args[0], args[1], args[2], args[3]);
+break;
 /* XXX: Perhaps args[2]  0x1f is wrong */
 case INDEX_op_shl_i32:
 c = const_args[2] ?
@@ -1798,6 +1801,7 @@ static const TCGTargetOpDef arm_op_defs[] = {
 { INDEX_op_sub_i32, { r, r, rI } },
 { INDEX_op_mul_i32, { r, r, r } },
 { INDEX_op_mulu2_i32, { r, r, r, r } },
+{ INDEX_op_muls2_i32, { r, r, r, r } },
 { INDEX_op_and_i32, { r, r, rI } },
 { INDEX_op_andc_i32, { r, r, rI } },
 { INDEX_op_or_i32, { r, r, rI } },
diff --git a/tcg/arm/tcg-target.h b/tcg/arm/tcg-target.h
index f9599bd..b6eed1f 100644
--- a/tcg/arm/tcg-target.h
+++ b/tcg/arm/tcg-target.h
@@ -75,7 +75,7 @@ typedef enum {
 #define TCG_TARGET_HAS_nor_i32  0
 #define TCG_TARGET_HAS_deposit_i32  0
 #define TCG_TARGET_HAS_movcond_i32  1
-#define TCG_TARGET_HAS_muls2_i320
+#define TCG_TARGET_HAS_muls2_i321
 
 enum {
 TCG_AREG0 = TCG_REG_R6,
-- 
1.8.1.2




[Qemu-devel] [PATCH] doc: document -netdev hubport

2013-02-20 Thread Stefan Hajnoczi
Signed-off-by: Stefan Hajnoczi stefa...@redhat.com
---
 qemu-options.hx | 11 ++-
 1 file changed, 10 insertions(+), 1 deletion(-)

diff --git a/qemu-options.hx b/qemu-options.hx
index 4bc9c85..c77c43e 100644
--- a/qemu-options.hx
+++ b/qemu-options.hx
@@ -1404,7 +1404,8 @@ DEF(netdev, HAS_ARG, QEMU_OPTION_netdev,
 #ifdef CONFIG_VDE
 vde|
 #endif
-socket],id=str[,option][,option][,...]\n, QEMU_ARCH_ALL)
+socket|
+hubport],id=str[,option][,option][,...]\n, QEMU_ARCH_ALL)
 STEXI
 @item -net nic[,vlan=@var{n}][,macaddr=@var{mac}][,model=@var{type}] 
[,name=@var{name}][,addr=@var{addr}][,vectors=@var{v}]
 @findex -net
@@ -1726,6 +1727,14 @@ vde_switch -F -sock /tmp/myswitch
 qemu-system-i386 linux.img -net nic -net vde,sock=/tmp/myswitch
 @end example
 
+@item -netdev hubport,id=@var{id},hubid=@var{hubid}
+
+Create a hub port on QEMU vlan @var{hubid}.  This syntax is an alterative to
+the -net @option{vlan} argument and can be used to connect a NIC specified with
+-device to a QEMU vlan.
+
+Note that only NICs can be connected to a hubport, other -netdevs cannot.
+
 @item -net dump[,vlan=@var{n}][,file=@var{file}][,len=@var{len}]
 Dump network traffic on VLAN @var{n} to file @var{file} 
(@file{qemu-vlan0.pcap} by default).
 At most @var{len} bytes (64k by default) per packet are stored. The file 
format is
-- 
1.8.1.2




[Qemu-devel] [PATCH 06/38] tcg: Implement a 64-bit to 32-bit extraction helper

2013-02-20 Thread Richard Henderson
We're going to have use for this shortly in implementing other helpers.

Signed-off-by: Richard Henderson r...@twiddle.net
---
 tcg/tcg-op.h | 22 ++
 1 file changed, 22 insertions(+)

diff --git a/tcg/tcg-op.h b/tcg/tcg-op.h
index 91c9d80..4ded249 100644
--- a/tcg/tcg-op.h
+++ b/tcg/tcg-op.h
@@ -2246,6 +2246,26 @@ static inline void tcg_gen_concat32_i64(TCGv_i64 dest, 
TCGv_i64 low,
 tcg_gen_deposit_i64(dest, low, high, 32, 32);
 }
 
+static inline void tcg_gen_extr_i64_i32(TCGv_i32 lo, TCGv_i32 hi, TCGv_i64 arg)
+{
+#if TCG_TARGET_REG_BITS == 32
+tcg_gen_mov_i32(lo, TCGV_LOW(arg));
+tcg_gen_mov_i32(hi, TCGV_HIGH(arg));
+#else
+TCGv_i64 t0 = tcg_temp_new_i64();
+tcg_gen_trunc_i64_i32(lo, arg);
+tcg_gen_shri_i64(t0, arg, 32);
+tcg_gen_trunc_i64_i32(hi, t0);
+tcg_temp_free_i64(t0);
+#endif
+}
+
+static inline void tcg_gen_extr32_i64(TCGv_i64 lo, TCGv_i64 hi, TCGv_i64 arg)
+{
+tcg_gen_ext32u_i64(lo, arg);
+tcg_gen_shri_i64(hi, arg, 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)
@@ -2625,6 +2645,7 @@ static inline void tcg_gen_qemu_st64(TCGv_i64 arg, TCGv 
addr, int mem_index)
 #define tcg_gen_bswap32_tl tcg_gen_bswap32_i64
 #define tcg_gen_bswap64_tl tcg_gen_bswap64_i64
 #define tcg_gen_concat_tl_i64 tcg_gen_concat32_i64
+#define tcg_gen_extr_i64_tl tcg_gen_extr32_i64
 #define tcg_gen_andc_tl tcg_gen_andc_i64
 #define tcg_gen_eqv_tl tcg_gen_eqv_i64
 #define tcg_gen_nand_tl tcg_gen_nand_i64
@@ -2697,6 +2718,7 @@ static inline void tcg_gen_qemu_st64(TCGv_i64 arg, TCGv 
addr, int mem_index)
 #define tcg_gen_bswap16_tl tcg_gen_bswap16_i32
 #define tcg_gen_bswap32_tl tcg_gen_bswap32_i32
 #define tcg_gen_concat_tl_i64 tcg_gen_concat_i32_i64
+#define tcg_gen_extr_tl_i64 tcg_gen_extr_i32_i64
 #define tcg_gen_andc_tl tcg_gen_andc_i32
 #define tcg_gen_eqv_tl tcg_gen_eqv_i32
 #define tcg_gen_nand_tl tcg_gen_nand_i32
-- 
1.8.1.2




[Qemu-devel] [PATCH 04/38] tcg: Add 64-bit multiword arithmetic operations

2013-02-20 Thread Richard Henderson
Matching the 32-bit multiword arithmetic that we already have.
---
 tcg/README | 26 ++
 tcg/i386/tcg-target.h  |  3 +++
 tcg/ia64/tcg-target.h  |  3 +++
 tcg/optimize.c |  4 ++--
 tcg/ppc64/tcg-target.h |  3 +++
 tcg/s390/tcg-target.h  |  3 +++
 tcg/sparc/tcg-target.h |  3 +++
 tcg/tcg-opc.h  |  4 
 tcg/tcg.h  |  3 +++
 tcg/tci/tcg-target.h   |  3 +++
 10 files changed, 41 insertions(+), 14 deletions(-)

diff --git a/tcg/README b/tcg/README
index ec1ac79..89f0cdd 100644
--- a/tcg/README
+++ b/tcg/README
@@ -361,6 +361,20 @@ Write 8, 16, 32 or 64 bits to host memory.
 All this opcodes assume that the pointed host memory doesn't correspond
 to a global. In the latter case the behaviour is unpredictable.
 
+* Multiword arithmetic support
+
+* add2_i32/i64 t0_low, t0_high, t1_low, t1_high, t2_low, t2_high
+* sub2_i32/i64 t0_low, t0_high, t1_low, t1_high, t2_low, t2_high
+
+Similar to add/sub, except that the double-word inputs T1 and T2 are
+formed from two single-word arguments, and the double-word output T0
+is returned in two single-word outputs.
+
+* mulu2_i32/i64 t0_low, t0_high, t1, t2
+
+Similar to mul, except two unsigned inputs T1 and T2 yielding the full
+double-word product T0.  The later is returned in two single-word outputs.
+
 * 64-bit target on 32-bit host support
 
 The following opcodes are internal to TCG.  Thus they are to be implemented by
@@ -372,18 +386,6 @@ They are emitted as needed by inline functions within 
tcg-op.h.
 Similar to brcond, except that the 64-bit values T0 and T1
 are formed from two 32-bit arguments.
 
-* add2_i32 t0_low, t0_high, t1_low, t1_high, t2_low, t2_high
-* sub2_i32 t0_low, t0_high, t1_low, t1_high, t2_low, t2_high
-
-Similar to add/sub, except that the 64-bit inputs T1 and T2 are
-formed from two 32-bit arguments, and the 64-bit output T0
-is returned in two 32-bit outputs.
-
-* mulu2_i32 t0_low, t0_high, t1, t2
-
-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 dest, t1_low, t1_high, t2_low, t2_high, cond
 
 Similar to setcond, except that the 64-bit values T1 and T2 are
diff --git a/tcg/i386/tcg-target.h b/tcg/i386/tcg-target.h
index 487dc23..4f00171 100644
--- a/tcg/i386/tcg-target.h
+++ b/tcg/i386/tcg-target.h
@@ -117,6 +117,9 @@ typedef enum {
 #define TCG_TARGET_HAS_nor_i64  0
 #define TCG_TARGET_HAS_deposit_i64  1
 #define TCG_TARGET_HAS_movcond_i64  1
+#define TCG_TARGET_HAS_add2_i64 0
+#define TCG_TARGET_HAS_sub2_i64 0
+#define TCG_TARGET_HAS_mulu2_i640
 #endif
 
 #define TCG_TARGET_deposit_i32_valid(ofs, len) \
diff --git a/tcg/ia64/tcg-target.h b/tcg/ia64/tcg-target.h
index b4ff7c3..40f442e 100644
--- a/tcg/ia64/tcg-target.h
+++ b/tcg/ia64/tcg-target.h
@@ -137,8 +137,11 @@ typedef enum {
 #define TCG_TARGET_HAS_deposit_i32  1
 #define TCG_TARGET_HAS_deposit_i64  1
 #define TCG_TARGET_HAS_add2_i32 0
+#define TCG_TARGET_HAS_add2_i64 0
 #define TCG_TARGET_HAS_sub2_i32 0
+#define TCG_TARGET_HAS_sub2_i64 0
 #define TCG_TARGET_HAS_mulu2_i320
+#define TCG_TARGET_HAS_mulu2_i640
 
 #define TCG_TARGET_deposit_i32_valid(ofs, len) ((len) = 16)
 #define TCG_TARGET_deposit_i64_valid(ofs, len) ((len) = 16)
diff --git a/tcg/optimize.c b/tcg/optimize.c
index 973d2d6..027b3a5 100644
--- a/tcg/optimize.c
+++ b/tcg/optimize.c
@@ -554,11 +554,11 @@ static TCGArg *tcg_constant_folding(TCGContext *s, 
uint16_t *tcg_opc_ptr,
 args[5] = tcg_invert_cond(args[5]);
 }
 break;
-case INDEX_op_add2_i32:
+CASE_OP_32_64(add2):
 swap_commutative(args[0], args[2], args[4]);
 swap_commutative(args[1], args[3], args[5]);
 break;
-case INDEX_op_mulu2_i32:
+CASE_OP_32_64(mulu2):
 swap_commutative(args[0], args[2], args[3]);
 break;
 case INDEX_op_brcond2_i32:
diff --git a/tcg/ppc64/tcg-target.h b/tcg/ppc64/tcg-target.h
index ea976ad..86929c1 100644
--- a/tcg/ppc64/tcg-target.h
+++ b/tcg/ppc64/tcg-target.h
@@ -109,6 +109,9 @@ typedef enum {
 #define TCG_TARGET_HAS_nor_i64  0
 #define TCG_TARGET_HAS_deposit_i64  0
 #define TCG_TARGET_HAS_movcond_i64  0
+#define TCG_TARGET_HAS_add2_i64 0
+#define TCG_TARGET_HAS_sub2_i64 0
+#define TCG_TARGET_HAS_mulu2_i640
 
 #define TCG_AREG0 TCG_REG_R27
 
diff --git a/tcg/s390/tcg-target.h b/tcg/s390/tcg-target.h
index 7772c35..ee31c37 100644
--- a/tcg/s390/tcg-target.h
+++ b/tcg/s390/tcg-target.h
@@ -90,6 +90,9 @@ typedef enum TCGReg {
 #define TCG_TARGET_HAS_nor_i64  0
 #define TCG_TARGET_HAS_deposit_i64  0
 #define TCG_TARGET_HAS_movcond_i64  0
+#define TCG_TARGET_HAS_add2_i64 0
+#define TCG_TARGET_HAS_sub2_i64 0
+#define TCG_TARGET_HAS_mulu2_i64   

Re: [Qemu-devel] [PATCH 3/6] qcow2: flush caches in qcow2_alloc_bytes()

2013-02-20 Thread Kevin Wolf
On Tue, Feb 19, 2013 at 04:45:03PM +0100, Stefan Hajnoczi wrote:
 It is not completely clear to me what is being flushed in
 qcow2_alloc_bytes() but bdrv_flush(bs-file) is probably wrong.  At
 least the refcount cache should be flushed since this function calls
 update_cluster_refcount().
 
 To be on the safe side, call the full bdrv_flush(bs).  This flushes all
 caches and the underlying file itself.
 
 Signed-off-by: Stefan Hajnoczi stefa...@redhat.com

To me it looks as if qcow2_alloc_compressed_cluster_offset() would need
a call to qcow2_cache_set_dependency() like there is already for the
uncompressed case in qcow2_alloc_cluster_link_l2(). Once we have that,
the unconditional flush can be removed. I guess this will be a major
performance improvement for converting to compressed qcow2.

The bdrv_flush() ended up here only because I pushed the flush from
qcow2_alloc_clusters() to its callers so I could remove it from the
common fast path. All surviving instances from this still need review.

Kevin



Re: [Qemu-devel] [PATCH] tap: forbid creating multiqueue tap when hub is used

2013-02-20 Thread Jason Wang
On 02/20/2013 05:45 PM, Paolo Bonzini wrote:
 Il 20/02/2013 10:18, Jason Wang ha scritto:
 Obviously, hub does not support multiqueue tap. So this patch forbids 
 creating
 multiple queue tap when hub is used to prevent the crash when command line 
 such
 as -net tap,queues=2 is used.

 Signed-off-by: Jason Wang jasow...@redhat.com
 ---
 This patch is needed for 1.4 stable also.
 Stefan, please add Cc when committing to the net branch.

 Jason, next time please add the Cc yourself to the body.

Sure.
 Paolo

 ---
  net/tap.c |6 ++
  1 files changed, 6 insertions(+), 0 deletions(-)

 diff --git a/net/tap.c b/net/tap.c
 index 48c254e..1e14f59 100644
 --- a/net/tap.c
 +++ b/net/tap.c
 @@ -693,6 +693,12 @@ int net_init_tap(const NetClientOptions *opts, const 
 char *name,
  queues = tap-has_queues ? tap-queues : 1;
  vhostfdname = tap-has_vhostfd ? tap-vhostfd : NULL;
  
 +if (peer  (tap-has_queues || tap-has_fds || tap-has_vhostfds)) {
 +error_report(This configuration is not compatiable with multiqueue
 +  tap);
 +return -1;
 +}
 +
  if (tap-has_fd) {
  if (tap-has_ifname || tap-has_script || tap-has_downscript ||
  tap-has_vnet_hdr || tap-has_helper || tap-has_queues ||






Re: [Qemu-devel] [PATCH 0/6] qcow2: cache flush fixes and performance improvements

2013-02-20 Thread Kevin Wolf
On Tue, Feb 19, 2013 at 04:45:00PM +0100, Stefan Hajnoczi wrote:
 Users have reported that qcow2 internal snapshot creation is slow.  I filed a
 bug report at https://bugs.launchpad.net/qemu/+bug/1126369.
 
 This patch series reduces the time for qcow2 internal snapshot creation
 significantly, from more than 3 minutes to under 1 second.
 
 In the process of removing unnecessary cache flushes, I also stumbled upon
 instances of bdrv_flush(bs-file) where we really want to flush metadata
 updates.  Since qcow2 caches metadata this actually does not write out the
 metadata updates to disk!  The fix is either bdrv_flush(bs) or a more specific
 cache flush (e.g. refcount block cache).
 
 This series passes qemu-iotests.
 
 Stefan Hajnoczi (6):
   qcow2: flush refcount cache correctly in alloc_refcount_block()
   qcow2: flush refcount cache correctly in qcow2_write_snapshots()
   qcow2: flush caches in qcow2_alloc_bytes()
   qcow2: flush in qcow2_update_snapshot_refcount()
   qcow2: drop flush in update_cluster_refcount()
   qcow2: drop unnecessary flush in qcow2_update_snapshot_refcount()
 
  block/qcow2-refcount.c | 12 +++-
  block/qcow2-snapshot.c |  7 +--
  2 files changed, 4 insertions(+), 15 deletions(-)

You touch a few bdrv_flush() callers that don't check the return value.
Could you use the opportunity to fix that as well?

Kevin



[Qemu-devel] [PATCH RESEND for 1.4-stable] net: reduce memory allocation when multiqueue is not used

2013-02-20 Thread Jason Wang
Edivaldo reports a problem that the array of NetClientState in NICState is too
large - MAX_QUEUE_NUM(1024) which will waste memory even if multiqueue is not
used.

For 1.4 we can just solve this by reduce the MAX_QUEUE_NUM to 8 which is the
same as the current kernel (3.8+) tap queue limit. For 1.5, we will use dynamic
allocation instead.

Cc: Edivaldo de Araujo Pereira edivaldoapere...@yahoo.com.br
Signed-off-by: Jason Wang jasow...@redhat.com
---
RESEND since the previous mail misses the list.
---
 include/net/net.h |2 +-
 1 files changed, 1 insertions(+), 1 deletions(-)

diff --git a/include/net/net.h b/include/net/net.h
index 43a045e..cdffc34 100644
--- a/include/net/net.h
+++ b/include/net/net.h
@@ -9,7 +9,7 @@
 #include migration/vmstate.h
 #include qapi-types.h
 
-#define MAX_QUEUE_NUM 1024
+#define MAX_QUEUE_NUM 8
 
 struct MACAddr {
 uint8_t a[6];
-- 
1.7.1




[Qemu-devel] [PATCH v4 00/10] main-loop: switch to g_poll(3) on POSIX hosts

2013-02-20 Thread Stefan Hajnoczi
Amos Kong ak...@redhat.com reported that file descriptors numbered higher
than 1024 could crash QEMU.  This is due to the fixed size of the fd_set type
used for select(2) event polling.

This series converts the main-loop.c and aio-posix.c select(2) calls to
g_poll(3).  This eliminates the fd_set type and allows QEMU to scale to high
numbers of file descriptors.

The g_poll(3) interface is a portable version of the poll(2) system call.  The
difference to select(2) is that fine-grained events (G_IO_IN, G_IO_OUT,
G_IO_HUP, G_IO_ERR, G_IO_PRI) can be monitored instead of just
read/write/exception.  Also, there is no limit to the file descriptor numbers
that may be used, allowing applications to scale to many file descriptors.  See
the documentation for details:

  http://developer.gnome.org/glib/2.28/glib-The-Main-Event-Loop.html#g-poll

The QEMU main loop works as follows today:

1. Call out to slirp, iohandlers, and glib sources to fill rfds/wfds/xfds with
   the file descriptors to select(2).
2. Perform the select(2) call.
3. Call out to slirp, iohandlers, and glib sources to handle events polled in
   rfds/wfds/xfds.

The plan of attack is as follows:

1. Replace select(2) with g_poll(3).  Use glue that converts between
   rfds/wfds/xfds and GPollFD so that the unconverted QEMU components still
   work.

2. Convert slirp, iohandlers, and glib source fill/poll functions to use
   GPollFD directly instead of rfds/wfds/xfds.

3. Drop the glue since all components now natively use GPollFD.

4. Convert aio-posix.c to g_poll(3) by reusing GPollFD.

I have tested that the series builds and is bisectable on Linux and Windows
hosts.  But I have not done extensive testing on other host platforms or with
long-term guests to check for performance regressions.

v4:
 * Assign revents instead of bitwise OR to make code clearer [Laszlo]
 * Invoke pollfds_poll() only when select(2) succeeds [Laszlo]
 * Fix gpollfds_to_select(select_ret || g_poll_ret) call [Laszlo]

v3:
 * Convert slirp/slirp.c to tabs to spaces [Blue Swirl]

v2:
 * Replace custom Poller type with GArray [aliguori]

Stefan Hajnoczi (10):
  main-loop: fix select_ret uninitialized variable warning
  main-loop: switch to g_poll() on POSIX hosts
  main-loop: switch POSIX glib integration to GPollFD
  slirp: slirp/slirp.c coding style cleanup
  slirp: switch to GPollFD
  iohandler: switch to GPollFD
  main-loop: drop rfds/wfds/xfds for good
  aio: extract aio_dispatch() from aio_poll()
  aio: convert aio_poll() to g_poll(3)
  aio: support G_IO_HUP and G_IO_ERR

 aio-posix.c  | 130 -
 async.c  |   2 +
 include/block/aio.h  |   3 +
 include/qemu/main-loop.h |   4 +-
 iohandler.c  |  40 ++-
 main-loop.c  | 158 ++-
 slirp/libslirp.h |   6 +-
 slirp/main.h |   1 -
 slirp/slirp.c| 673 +--
 slirp/socket.c   |   9 -
 slirp/socket.h   |   2 +
 stubs/slirp.c|   6 +-
 12 files changed, 547 insertions(+), 487 deletions(-)

-- 
1.8.1.2




[Qemu-devel] [PATCH v4 01/10] main-loop: fix select_ret uninitialized variable warning

2013-02-20 Thread Stefan Hajnoczi
Signed-off-by: Stefan Hajnoczi stefa...@redhat.com
---
 main-loop.c | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/main-loop.c b/main-loop.c
index 6f52ac3..d0d8fe4 100644
--- a/main-loop.c
+++ b/main-loop.c
@@ -330,7 +330,8 @@ void qemu_fd_register(int fd)
 static int os_host_main_loop_wait(uint32_t timeout)
 {
 GMainContext *context = g_main_context_default();
-int select_ret, g_poll_ret, ret, i;
+int select_ret = 0;
+int g_poll_ret, ret, i;
 PollingEntry *pe;
 WaitObjects *w = wait_objects;
 gint poll_timeout;
-- 
1.8.1.2




[Qemu-devel] [PATCH v4 08/10] aio: extract aio_dispatch() from aio_poll()

2013-02-20 Thread Stefan Hajnoczi
We will need to loop over AioHandlers calling -io_read()/-io_write()
when aio_poll() is converted from select(2) to g_poll(2).

Luckily the code for this already exists, extract it into the new
aio_dispatch() function.

Two small changes:

 * aio_poll() checks !node-deleted to avoid calling handlers that have
   been deleted.

 * Fix typo 'then' - 'them' in aio_poll() comment.

Signed-off-by: Stefan Hajnoczi stefa...@redhat.com
---
 aio-posix.c | 57 +++--
 1 file changed, 35 insertions(+), 22 deletions(-)

diff --git a/aio-posix.c b/aio-posix.c
index fe4dbb4..35131a3 100644
--- a/aio-posix.c
+++ b/aio-posix.c
@@ -129,30 +129,12 @@ bool aio_pending(AioContext *ctx)
 return false;
 }
 
-bool aio_poll(AioContext *ctx, bool blocking)
+static bool aio_dispatch(AioContext *ctx)
 {
-static struct timeval tv0;
 AioHandler *node;
-fd_set rdfds, wrfds;
-int max_fd = -1;
-int ret;
-bool busy, progress;
-
-progress = false;
-
-/*
- * If there are callbacks left that have been queued, we need to call then.
- * Do not call select in this case, because it is possible that the caller
- * does not need a complete flush (as is the case for qemu_aio_wait loops).
- */
-if (aio_bh_poll(ctx)) {
-blocking = false;
-progress = true;
-}
+bool progress = false;
 
 /*
- * Then dispatch any pending callbacks from the GSource.
- *
  * We have to walk very carefully in case qemu_aio_set_fd_handler is
  * called while we're walking.
  */
@@ -167,11 +149,15 @@ bool aio_poll(AioContext *ctx, bool blocking)
 node-pfd.revents = 0;
 
 /* See comment in aio_pending.  */
-if (revents  (G_IO_IN | G_IO_HUP | G_IO_ERR)  node-io_read) {
+if (!node-deleted 
+(revents  (G_IO_IN | G_IO_HUP | G_IO_ERR)) 
+node-io_read) {
 node-io_read(node-opaque);
 progress = true;
 }
-if (revents  (G_IO_OUT | G_IO_ERR)  node-io_write) {
+if (!node-deleted 
+(revents  (G_IO_OUT | G_IO_ERR)) 
+node-io_write) {
 node-io_write(node-opaque);
 progress = true;
 }
@@ -186,6 +172,33 @@ bool aio_poll(AioContext *ctx, bool blocking)
 g_free(tmp);
 }
 }
+return progress;
+}
+
+bool aio_poll(AioContext *ctx, bool blocking)
+{
+static struct timeval tv0;
+AioHandler *node;
+fd_set rdfds, wrfds;
+int max_fd = -1;
+int ret;
+bool busy, progress;
+
+progress = false;
+
+/*
+ * If there are callbacks left that have been queued, we need to call them.
+ * Do not call select in this case, because it is possible that the caller
+ * does not need a complete flush (as is the case for qemu_aio_wait loops).
+ */
+if (aio_bh_poll(ctx)) {
+blocking = false;
+progress = true;
+}
+
+if (aio_dispatch(ctx)) {
+progress = true;
+}
 
 if (progress  !blocking) {
 return true;
-- 
1.8.1.2




[Qemu-devel] [PATCH v4 06/10] iohandler: switch to GPollFD

2013-02-20 Thread Stefan Hajnoczi
Convert iohandler_select_fill() and iohandler_select_poll() to use
GPollFD instead of rfds/wfds/xfds.

Signed-off-by: Stefan Hajnoczi stefa...@redhat.com
---
 include/qemu/main-loop.h |  4 ++--
 iohandler.c  | 40 ++--
 main-loop.c  |  4 ++--
 3 files changed, 34 insertions(+), 14 deletions(-)

diff --git a/include/qemu/main-loop.h b/include/qemu/main-loop.h
index e8059c3..0995288 100644
--- a/include/qemu/main-loop.h
+++ b/include/qemu/main-loop.h
@@ -297,8 +297,8 @@ void qemu_mutex_unlock_iothread(void);
 /* internal interfaces */
 
 void qemu_fd_register(int fd);
-void qemu_iohandler_fill(int *pnfds, fd_set *readfds, fd_set *writefds, fd_set 
*xfds);
-void qemu_iohandler_poll(fd_set *readfds, fd_set *writefds, fd_set *xfds, int 
rc);
+void qemu_iohandler_fill(GArray *pollfds);
+void qemu_iohandler_poll(GArray *pollfds, int rc);
 
 QEMUBH *qemu_bh_new(QEMUBHFunc *cb, void *opaque);
 void qemu_bh_schedule_idle(QEMUBH *bh);
diff --git a/iohandler.c b/iohandler.c
index 2523adc..ae2ef8f 100644
--- a/iohandler.c
+++ b/iohandler.c
@@ -39,6 +39,7 @@ typedef struct IOHandlerRecord {
 void *opaque;
 QLIST_ENTRY(IOHandlerRecord) next;
 int fd;
+int pollfds_idx;
 bool deleted;
 } IOHandlerRecord;
 
@@ -78,6 +79,7 @@ int qemu_set_fd_handler2(int fd,
 ioh-fd_read = fd_read;
 ioh-fd_write = fd_write;
 ioh-opaque = opaque;
+ioh-pollfds_idx = -1;
 ioh-deleted = 0;
 qemu_notify_event();
 }
@@ -92,38 +94,56 @@ int qemu_set_fd_handler(int fd,
 return qemu_set_fd_handler2(fd, NULL, fd_read, fd_write, opaque);
 }
 
-void qemu_iohandler_fill(int *pnfds, fd_set *readfds, fd_set *writefds, fd_set 
*xfds)
+void qemu_iohandler_fill(GArray *pollfds)
 {
 IOHandlerRecord *ioh;
 
 QLIST_FOREACH(ioh, io_handlers, next) {
+int events = 0;
+
 if (ioh-deleted)
 continue;
 if (ioh-fd_read 
 (!ioh-fd_read_poll ||
  ioh-fd_read_poll(ioh-opaque) != 0)) {
-FD_SET(ioh-fd, readfds);
-if (ioh-fd  *pnfds)
-*pnfds = ioh-fd;
+events |= G_IO_IN | G_IO_HUP | G_IO_ERR;
 }
 if (ioh-fd_write) {
-FD_SET(ioh-fd, writefds);
-if (ioh-fd  *pnfds)
-*pnfds = ioh-fd;
+events |= G_IO_OUT | G_IO_ERR;
+}
+if (events) {
+GPollFD pfd = {
+.fd = ioh-fd,
+.events = events,
+};
+ioh-pollfds_idx = pollfds-len;
+g_array_append_val(pollfds, pfd);
+} else {
+ioh-pollfds_idx = -1;
 }
 }
 }
 
-void qemu_iohandler_poll(fd_set *readfds, fd_set *writefds, fd_set *xfds, int 
ret)
+void qemu_iohandler_poll(GArray *pollfds, int ret)
 {
 if (ret  0) {
 IOHandlerRecord *pioh, *ioh;
 
 QLIST_FOREACH_SAFE(ioh, io_handlers, next, pioh) {
-if (!ioh-deleted  ioh-fd_read  FD_ISSET(ioh-fd, readfds)) {
+int revents = 0;
+
+if (!ioh-deleted  ioh-pollfds_idx != -1) {
+GPollFD *pfd = g_array_index(pollfds, GPollFD,
+  ioh-pollfds_idx);
+revents = pfd-revents;
+}
+
+if (!ioh-deleted  ioh-fd_read 
+(revents  (G_IO_IN | G_IO_HUP | G_IO_ERR))) {
 ioh-fd_read(ioh-opaque);
 }
-if (!ioh-deleted  ioh-fd_write  FD_ISSET(ioh-fd, writefds)) 
{
+if (!ioh-deleted  ioh-fd_write 
+(revents  (G_IO_OUT | G_IO_ERR))) {
 ioh-fd_write(ioh-opaque);
 }
 
diff --git a/main-loop.c b/main-loop.c
index 839e98f..800868a 100644
--- a/main-loop.c
+++ b/main-loop.c
@@ -507,9 +507,9 @@ int main_loop_wait(int nonblocking)
 slirp_update_timeout(timeout);
 slirp_pollfds_fill(gpollfds);
 #endif
-qemu_iohandler_fill(nfds, rfds, wfds, xfds);
+qemu_iohandler_fill(gpollfds);
 ret = os_host_main_loop_wait(timeout);
-qemu_iohandler_poll(rfds, wfds, xfds, ret);
+qemu_iohandler_poll(gpollfds, ret);
 #ifdef CONFIG_SLIRP
 slirp_pollfds_poll(gpollfds, (ret  0));
 #endif
-- 
1.8.1.2




[Qemu-devel] [PATCH v4 05/10] slirp: switch to GPollFD

2013-02-20 Thread Stefan Hajnoczi
Slirp uses rfds/wfds/xfds more extensively than other QEMU components.

The rarely-used out-of-band TCP data feature is used.  That means we
need the full table of select(2) to g_poll(3) events:

  rfds - G_IO_IN | G_IO_HUP | G_IO_ERR
  wfds - G_IO_OUT | G_IO_ERR
  xfds - G_IO_PRI

I came up with this table by looking at Linux fs/select.c which maps
select(2) to poll(2) internally.

Another detail to watch out for are the global variables that reference
rfds/wfds/xfds during slirp_select_poll().  sofcantrcvmore() and
sofcantsendmore() use these globals to clear fd_set bits.  When
sofcantrcvmore() is called, the wfds bit is cleared so that the write
handler will no longer be run for this iteration of the event loop.

This actually seems buggy to me since TCP connections can be half-closed
and we'd still want to handle data in half-duplex fashion.  I think the
real intention is to avoid running the read/write handler when the
socket has been fully closed.  This is indicated with the SS_NOFDREF
state bit so we now check for it before invoking the TCP write handler.
Note that UDP/ICMP code paths don't care because they are
connectionless.

Note that slirp/ has a lot of tabs and sometimes mixed tabs with spaces.
I followed the style of the surrounding code.

Signed-off-by: Stefan Hajnoczi stefa...@redhat.com
---
 main-loop.c  |   4 +-
 slirp/libslirp.h |   6 +--
 slirp/main.h |   1 -
 slirp/slirp.c| 133 +--
 slirp/socket.c   |   9 
 slirp/socket.h   |   2 +
 stubs/slirp.c|   6 +--
 7 files changed, 87 insertions(+), 74 deletions(-)

diff --git a/main-loop.c b/main-loop.c
index c2ede99..839e98f 100644
--- a/main-loop.c
+++ b/main-loop.c
@@ -505,13 +505,13 @@ int main_loop_wait(int nonblocking)
 
 #ifdef CONFIG_SLIRP
 slirp_update_timeout(timeout);
-slirp_select_fill(nfds, rfds, wfds, xfds);
+slirp_pollfds_fill(gpollfds);
 #endif
 qemu_iohandler_fill(nfds, rfds, wfds, xfds);
 ret = os_host_main_loop_wait(timeout);
 qemu_iohandler_poll(rfds, wfds, xfds, ret);
 #ifdef CONFIG_SLIRP
-slirp_select_poll(rfds, wfds, xfds, (ret  0));
+slirp_pollfds_poll(gpollfds, (ret  0));
 #endif
 
 qemu_run_all_timers();
diff --git a/slirp/libslirp.h b/slirp/libslirp.h
index 49609c2..ceabff8 100644
--- a/slirp/libslirp.h
+++ b/slirp/libslirp.h
@@ -17,11 +17,9 @@ Slirp *slirp_init(int restricted, struct in_addr vnetwork,
 void slirp_cleanup(Slirp *slirp);
 
 void slirp_update_timeout(uint32_t *timeout);
-void slirp_select_fill(int *pnfds,
-   fd_set *readfds, fd_set *writefds, fd_set *xfds);
+void slirp_pollfds_fill(GArray *pollfds);
 
-void slirp_select_poll(fd_set *readfds, fd_set *writefds, fd_set *xfds,
-   int select_error);
+void slirp_pollfds_poll(GArray *pollfds, int select_error);
 
 void slirp_input(Slirp *slirp, const uint8_t *pkt, int pkt_len);
 
diff --git a/slirp/main.h b/slirp/main.h
index 66e4f92..f2e58cf 100644
--- a/slirp/main.h
+++ b/slirp/main.h
@@ -31,7 +31,6 @@ extern int ctty_closed;
 extern char *slirp_tty;
 extern char *exec_shell;
 extern u_int curtime;
-extern fd_set *global_readfds, *global_writefds, *global_xfds;
 extern struct in_addr loopback_addr;
 extern unsigned long loopback_mask;
 extern char *username;
diff --git a/slirp/slirp.c b/slirp/slirp.c
index 5d14e7f..bd9b7cb 100644
--- a/slirp/slirp.c
+++ b/slirp/slirp.c
@@ -39,9 +39,6 @@ static const uint8_t special_ethaddr[ETH_ALEN] = {
 
 static const uint8_t zero_ethaddr[ETH_ALEN] = { 0, 0, 0, 0, 0, 0 };
 
-/* XXX: suppress those select globals */
-fd_set *global_readfds, *global_writefds, *global_xfds;
-
 u_int curtime;
 static u_int time_fasttimo, last_slowtimo;
 static int do_slowtimo;
@@ -261,7 +258,6 @@ void slirp_cleanup(Slirp *slirp)
 
 #define CONN_CANFSEND(so) (((so)-so_state  
(SS_FCANTSENDMORE|SS_ISFCONNECTED)) == SS_ISFCONNECTED)
 #define CONN_CANFRCV(so) (((so)-so_state  (SS_FCANTRCVMORE|SS_ISFCONNECTED)) 
== SS_ISFCONNECTED)
-#define UPD_NFDS(x) if (nfds  (x)) nfds = (x)
 
 void slirp_update_timeout(uint32_t *timeout)
 {
@@ -270,23 +266,15 @@ void slirp_update_timeout(uint32_t *timeout)
 }
 }
 
-void slirp_select_fill(int *pnfds,
-   fd_set *readfds, fd_set *writefds, fd_set *xfds)
+void slirp_pollfds_fill(GArray *pollfds)
 {
 Slirp *slirp;
 struct socket *so, *so_next;
-int nfds;
 
 if (QTAILQ_EMPTY(slirp_instances)) {
 return;
 }
 
-/* fail safe */
-global_readfds = NULL;
-global_writefds = NULL;
-global_xfds = NULL;
-
-nfds = *pnfds;
 /*
  * First, TCP sockets
  */
@@ -302,8 +290,12 @@ void slirp_select_fill(int *pnfds,
 
 for (so = slirp-tcb.so_next; so != slirp-tcb;
 so = so_next) {
+int events = 0;
+
 so_next = so-so_next;
 
+so-pollfds_idx = -1;
+
 /*
  * See if we need a tcp_fasttimo
  */
@@ -323,8 +315,12 @@ 

[Qemu-devel] [PATCH v4 07/10] main-loop: drop rfds/wfds/xfds for good

2013-02-20 Thread Stefan Hajnoczi
Now that all *_fill() and *_poll() functions use GPollFD we no longer
need rfds/wfds/xfds or pollfds_from_select()/pollfds_to_select().

From now on everything uses GPollFD.

Signed-off-by: Stefan Hajnoczi stefa...@redhat.com
---
 main-loop.c | 77 ++---
 1 file changed, 2 insertions(+), 75 deletions(-)

diff --git a/main-loop.c b/main-loop.c
index 800868a..8c9b58c 100644
--- a/main-loop.c
+++ b/main-loop.c
@@ -143,66 +143,8 @@ int qemu_init_main_loop(void)
 return 0;
 }
 
-static fd_set rfds, wfds, xfds;
-static int nfds;
 static int max_priority;
 
-/* Load rfds/wfds/xfds into gpollfds.  Will be removed a few commits later. */
-static void gpollfds_from_select(void)
-{
-int fd;
-for (fd = 0; fd = nfds; fd++) {
-int events = 0;
-if (FD_ISSET(fd, rfds)) {
-events |= G_IO_IN | G_IO_HUP | G_IO_ERR;
-}
-if (FD_ISSET(fd, wfds)) {
-events |= G_IO_OUT | G_IO_ERR;
-}
-if (FD_ISSET(fd, xfds)) {
-events |= G_IO_PRI;
-}
-if (events) {
-GPollFD pfd = {
-.fd = fd,
-.events = events,
-};
-g_array_append_val(gpollfds, pfd);
-}
-}
-}
-
-/* Store gpollfds revents into rfds/wfds/xfds.  Will be removed a few commits
- * later.
- */
-static void gpollfds_to_select(int ret)
-{
-int i;
-
-FD_ZERO(rfds);
-FD_ZERO(wfds);
-FD_ZERO(xfds);
-
-if (ret = 0) {
-return;
-}
-
-for (i = 0; i  gpollfds-len; i++) {
-int fd = g_array_index(gpollfds, GPollFD, i).fd;
-int revents = g_array_index(gpollfds, GPollFD, i).revents;
-
-if (revents  (G_IO_IN | G_IO_HUP | G_IO_ERR)) {
-FD_SET(fd, rfds);
-}
-if (revents  (G_IO_OUT | G_IO_ERR)) {
-FD_SET(fd, wfds);
-}
-if (revents  G_IO_PRI) {
-FD_SET(fd, xfds);
-}
-}
-}
-
 #ifndef _WIN32
 static int glib_pollfds_idx;
 static int glib_n_poll_fds;
@@ -251,15 +193,8 @@ static int os_host_main_loop_wait(uint32_t timeout)
 qemu_mutex_unlock_iothread();
 }
 
-/* We'll eventually drop fd_set completely.  But for now we still have
- * *_fill() and *_poll() functions that use rfds/wfds/xfds.
- */
-gpollfds_from_select();
-
 ret = g_poll((GPollFD *)gpollfds-data, gpollfds-len, timeout);
 
-gpollfds_to_select(ret);
-
 if (timeout  0) {
 qemu_mutex_lock_iothread();
 }
@@ -417,6 +352,8 @@ static int os_host_main_loop_wait(uint32_t timeout)
 WaitObjects *w = wait_objects;
 gint poll_timeout;
 static struct timeval tv0;
+fd_set rfds, wfds, xfds;
+int nfds;
 
 /* XXX: need to suppress polling by better using win32 events */
 ret = 0;
@@ -463,10 +400,6 @@ static int os_host_main_loop_wait(uint32_t timeout)
  * improve socket latency.
  */
 
-/* This back-and-forth between GPollFDs and select(2) is temporary.  We'll
- * drop it in a couple of patches, I promise :).
- */
-gpollfds_from_select();
 FD_ZERO(rfds);
 FD_ZERO(wfds);
 FD_ZERO(xfds);
@@ -480,7 +413,6 @@ static int os_host_main_loop_wait(uint32_t timeout)
 pollfds_poll(gpollfds, nfds, rfds, wfds, xfds);
 }
 }
-gpollfds_to_select(select_ret);
 
 return select_ret || g_poll_ret;
 }
@@ -498,11 +430,6 @@ int main_loop_wait(int nonblocking)
 /* poll any events */
 g_array_set_size(gpollfds, 0); /* reset for new iteration */
 /* XXX: separate device handlers from system ones */
-nfds = -1;
-FD_ZERO(rfds);
-FD_ZERO(wfds);
-FD_ZERO(xfds);
-
 #ifdef CONFIG_SLIRP
 slirp_update_timeout(timeout);
 slirp_pollfds_fill(gpollfds);
-- 
1.8.1.2




[Qemu-devel] [PATCH 14/38] tcg: Apply life analysis to 64-bit multiword arithmetic ops

2013-02-20 Thread Richard Henderson
Signed-off-by: Richard Henderson r...@twiddle.net
---
 tcg/tcg.c | 28 
 1 file changed, 20 insertions(+), 8 deletions(-)

diff --git a/tcg/tcg.c b/tcg/tcg.c
index c8a843e..1d8265e 100644
--- a/tcg/tcg.c
+++ b/tcg/tcg.c
@@ -1217,7 +1217,7 @@ static inline void tcg_la_bb_end(TCGContext *s, uint8_t 
*dead_temps,
 static void tcg_liveness_analysis(TCGContext *s)
 {
 int i, op_index, nb_args, nb_iargs, nb_oargs, arg, nb_ops;
-TCGOpcode op;
+TCGOpcode op, op_new;
 TCGArg *args;
 const TCGOpDef *def;
 uint8_t *dead_temps, *mem_temps;
@@ -1324,7 +1324,17 @@ static void tcg_liveness_analysis(TCGContext *s)
 break;
 
 case INDEX_op_add2_i32:
+op_new = INDEX_op_add_i32;
+goto do_addsub2;
 case INDEX_op_sub2_i32:
+op_new = INDEX_op_sub_i32;
+goto do_addsub2;
+case INDEX_op_add2_i64:
+op_new = INDEX_op_add_i64;
+goto do_addsub2;
+case INDEX_op_sub2_i64:
+op_new = INDEX_op_sub_i64;
+do_addsub2:
 args -= 6;
 nb_iargs = 4;
 nb_oargs = 2;
@@ -1337,12 +1347,7 @@ static void tcg_liveness_analysis(TCGContext *s)
 goto do_remove;
 }
 /* Create the single operation plus nop.  */
-if (op == INDEX_op_add2_i32) {
-op = INDEX_op_add_i32;
-} else {
-op = INDEX_op_sub_i32;
-}
-s-gen_opc_buf[op_index] = op;
+s-gen_opc_buf[op_index] = op = op_new;
 args[1] = args[2];
 args[2] = args[4];
 assert(s-gen_opc_buf[op_index + 1] == INDEX_op_nop);
@@ -1354,6 +1359,13 @@ static void tcg_liveness_analysis(TCGContext *s)
 goto do_not_remove;
 
 case INDEX_op_mulu2_i32:
+case INDEX_op_muls2_i32:
+op_new = INDEX_op_mul_i32;
+goto do_mul2;
+case INDEX_op_mulu2_i64:
+case INDEX_op_muls2_i64:
+op_new = INDEX_op_mul_i64;
+do_mul2:
 args -= 4;
 nb_iargs = 2;
 nb_oargs = 2;
@@ -1362,7 +1374,7 @@ static void tcg_liveness_analysis(TCGContext *s)
 if (dead_temps[args[0]]  !mem_temps[args[0]]) {
 goto do_remove;
 }
-s-gen_opc_buf[op_index] = op = INDEX_op_mul_i32;
+s-gen_opc_buf[op_index] = op = op_new;
 args[1] = args[2];
 args[2] = args[3];
 assert(s-gen_opc_buf[op_index + 1] == INDEX_op_nop);
-- 
1.8.1.2




[Qemu-devel] [PATCH 38/38] target-xtensa: Use add2/sub2 for mac

2013-02-20 Thread Richard Henderson
Cc: Max Filippov jcmvb...@gmail.com
Signed-off-by: Richard Henderson r...@twiddle.net
---
 target-xtensa/translate.c | 29 +
 1 file changed, 13 insertions(+), 16 deletions(-)

diff --git a/target-xtensa/translate.c b/target-xtensa/translate.c
index b41d12c..11e06a3 100644
--- a/target-xtensa/translate.c
+++ b/target-xtensa/translate.c
@@ -2487,27 +2487,24 @@ static void disas_xtensa_insn(CPUXtensaState *env, 
DisasContext *dc)
 tcg_gen_sari_i32(cpu_SR[ACCHI], cpu_SR[ACCLO], 31);
 }
 } else {
-TCGv_i32 res = tcg_temp_new_i32();
-TCGv_i64 res64 = tcg_temp_new_i64();
-TCGv_i64 tmp = tcg_temp_new_i64();
-
-tcg_gen_mul_i32(res, m1, m2);
-tcg_gen_ext_i32_i64(res64, res);
-tcg_gen_concat_i32_i64(tmp,
-cpu_SR[ACCLO], cpu_SR[ACCHI]);
+TCGv_i32 lo = tcg_temp_new_i32();
+TCGv_i32 hi = tcg_temp_new_i32();
+
+tcg_gen_mul_i32(lo, m1, m2);
+tcg_gen_sari_i32(hi, lo, 31);
 if (op == MAC16_MULA) {
-tcg_gen_add_i64(tmp, tmp, res64);
+tcg_gen_add2_i32(cpu_SR[ACCLO], cpu_SR[ACCHI],
+ cpu_SR[ACCLO], cpu_SR[ACCHI],
+ lo, hi);
 } else {
-tcg_gen_sub_i64(tmp, tmp, res64);
+tcg_gen_sub2_i32(cpu_SR[ACCLO], cpu_SR[ACCHI],
+ cpu_SR[ACCLO], cpu_SR[ACCHI],
+ lo, hi);
 }
-tcg_gen_trunc_i64_i32(cpu_SR[ACCLO], tmp);
-tcg_gen_shri_i64(tmp, tmp, 32);
-tcg_gen_trunc_i64_i32(cpu_SR[ACCHI], tmp);
 tcg_gen_ext8s_i32(cpu_SR[ACCHI], cpu_SR[ACCHI]);
 
-tcg_temp_free(res);
-tcg_temp_free_i64(res64);
-tcg_temp_free_i64(tmp);
+tcg_temp_free_i32(lo);
+tcg_temp_free_i32(hi);
 }
 tcg_temp_free(m1);
 tcg_temp_free(m2);
-- 
1.8.1.2




[Qemu-devel] [PATCH v4 1/6] add documenation for new backup framework

2013-02-20 Thread Dietmar Maurer

Signed-off-by: Dietmar Maurer diet...@proxmox.com
---
 docs/backup.txt |  116 +++
 1 files changed, 116 insertions(+), 0 deletions(-)
 create mode 100644 docs/backup.txt

diff --git a/docs/backup.txt b/docs/backup.txt
new file mode 100644
index 000..927d787
--- /dev/null
+++ b/docs/backup.txt
@@ -0,0 +1,116 @@
+Efficient VM backup for qemu
+
+=Requirements=
+
+* Backup to a single archive file
+* Backup needs to contain all data to restore VM (full backup)
+* Do not depend on storage type or image format
+* Avoid use of temporary storage
+* store sparse images efficiently
+
+=Introduction=
+
+Most VM backup solutions use some kind of snapshot to get a consistent
+VM view at a specific point in time. For example, we previously used
+LVM to create a snapshot of all used VM images, which are then copied
+into a tar file.
+
+That basically means that any data written during backup involve
+considerable overhead. For LVM we get the following steps:
+
+1.) read original data (VM write)
+2.) write original data into snapshot (VM write)
+3.) write new data (VM write)
+4.) read data from snapshot (backup)
+5.) write data from snapshot into tar file (backup)
+
+Another approach to backup VM images is to create a new qcow2 image
+which use the old image as base. During backup, writes are redirected
+to the new image, so the old image represents a 'snapshot'. After
+backup, data need to be copied back from new image into the old
+one (commit). So a simple write during backup triggers the following
+steps:
+
+1.) write new data to new image (VM write)
+2.) read data from old image (backup)
+3.) write data from old image into tar file (backup)
+
+4.) read data from new image (commit)
+5.) write data to old image (commit)
+
+This is in fact the same overhead as before. Other tools like qemu
+livebackup produces similar overhead (2 reads, 3 writes).
+
+Some storage types/formats supports internal snapshots using some kind
+of reference counting (rados, sheepdog, dm-thin, qcow2). It would be possible
+to use that for backups, but for now we want to be storage-independent.
+
+=Make it more efficient=
+
+The be more efficient, we simply need to avoid unnecessary steps. The
+following steps are always required:
+
+1.) read old data before it gets overwritten
+2.) write that data into the backup archive
+3.) write new data (VM write)
+
+As you can see, this involves only one read, and two writes.
+
+To make that work, our backup archive need to be able to store image
+data 'out of order'. It is important to notice that this will not work
+with traditional archive formats like tar.
+
+During backup we simply intercept writes, then read existing data and
+store that directly into the archive. After that we can continue the
+write.
+
+==Advantages==
+
+* very good performance (1 read, 2 writes)
+* works on any storage type and image format.
+* avoid usage of temporary storage
+* we can define a new and simple archive format, which is able to
+  store sparse files efficiently.
+
+Note: Storing sparse files is a mess with existing archive
+formats. For example, tar requires information about holes at the
+beginning of the archive.
+
+==Disadvantages==
+
+* we need to define a new archive format
+
+Note: Most existing archive formats are optimized to store small files
+including file attributes. We simply do not need that for VM archives.
+
+* archive contains data 'out of order'
+
+If you want to access image data in sequential order, you need to
+re-order archive data. It would be possible to to that on the fly,
+using temporary files.
+
+Fortunately, a normal restore/extract works perfectly with 'out of
+order' data, because the target files are seekable.
+
+* slow backup storage can slow down VM during backup
+
+It is important to note that we only do sequential writes to the
+backup storage. Furthermore one can compress the backup stream. IMHO,
+it is better to slow down the VM a bit. All other solutions creates
+large amounts of temporary data during backup.
+
+=Archive format requirements=
+
+The basic requirement for such new format is that we can store image
+date 'out of order'. It is also very likely that we have less than 256
+drives/images per VM, and we want to be able to store VM configuration
+files.
+
+We have defined a very simply format with those properties, see:
+
+docs/specs/vma_spec.txt
+
+Please let us know if you know an existing format which provides the
+same functionality.
+
+
-- 
1.7.2.5




Re: [Qemu-devel] [PATCH v1 1/6] i2c: support address ranges

2013-02-20 Thread Paolo Bonzini
Il 20/02/2013 06:29, Peter Crosthwaite ha scritto:
 @@ -192,12 +197,13 @@ static int i2c_slave_post_load(void *opaque, int 
 version_id)
  
  const VMStateDescription vmstate_i2c_slave = {
  .name = I2CSlave,
 -.version_id = 1,
 -.minimum_version_id = 1,
 -.minimum_version_id_old = 1,
 +.version_id = 2,
 +.minimum_version_id = 2,
 +.minimum_version_id_old = 2,
  .post_load = i2c_slave_post_load,
  .fields  = (VMStateField []) {
  VMSTATE_UINT8(address, I2CSlave),
 +VMSTATE_UINT8(address_range, I2CSlave),
  VMSTATE_END_OF_LIST()

Properties do not need to be serialized.

Paolo



[Qemu-devel] Live migration using qcow2

2013-02-20 Thread Tiziano Müller
Hi everyone

According to http://wiki.qemu.org/Migration/Storage section Image
Formats qemu can't do live migration without data corruption when using
qcow2 or qed due to the metadata caches.
Wasn't that fixed by commit 06d9260 ?

Also, Clustered File Systems does not seem to be up-to-date since
libvirt considers only OCFS and GFS2 to be safe for migration with
cache!=none. Since FUSE supports O_DIRECT officially, adding GlusterFS
to this list may be appropriate as well?

Thanks in advance,
Tiziano

[1]
http://git.qemu.org/?p=qemu.git;a=commit;h=06d9260ffa9dfa0e96e015501e43480ab66f96f6


-- 
stepping stone GmbH
Neufeldstrasse 9
CH-3012 Bern
Telefon: +41 31 332 53 63
www.stepping-stone.ch
tiziano.muel...@stepping-stone.ch




Re: [Qemu-devel] [PATCH v3 1/6] RFC: Efficient VM backup for qemu

2013-02-20 Thread Kevin Wolf
On Wed, Feb 20, 2013 at 09:01:16AM +0100, Markus Armbruster wrote:
 Dietmar Maurer diet...@proxmox.com writes:
 
   * Backup to a single archive file
   * Backup contain all data to restore VM (full backup)
   * Do not depend on storage type or image format
   * Avoid use of temporary storage
   * store sparse images efficiently
  
  It is customary to send a 0/6 cover letter for details like this, rather 
  than
  slamming it into the first patch (git send-email --cover-letter).
 
  But how do I maintain the content of that cover-letter when it is not
  part of the git tree?
 
 Nothing stops you from committing it to your branch.  The extra commit
 isn't sent out, of course.
 
 I guess people usually archive it in e-mail instead.

I use separate format-patch and send-email steps, so I'll still have the
cover letter file around when I send the next version.

Kevin



Re: [Qemu-devel] Live migration using qcow2

2013-02-20 Thread Kevin Wolf
On Wed, Feb 20, 2013 at 11:47:56AM +0100, Tiziano Müller wrote:
 Hi everyone
 
 According to http://wiki.qemu.org/Migration/Storage section Image
 Formats qemu can't do live migration without data corruption when using
 qcow2 or qed due to the metadata caches.
 Wasn't that fixed by commit 06d9260 ?

Yes, it is fixed. Depending on your backend, you still need
cache=none/directsync, of course.

Kevin



[Qemu-devel] [PATCH 26/38] target-ppc: Use setcond in gen_op_cmp

2013-02-20 Thread Richard Henderson
Which means that callers need not copy data into local tmps.

Cc: Alexander Graf ag...@suse.de
Signed-off-by: Richard Henderson r...@twiddle.net
---
 target-ppc/translate.c | 46 +++---
 1 file changed, 23 insertions(+), 23 deletions(-)

diff --git a/target-ppc/translate.c b/target-ppc/translate.c
index 0ac072c..7aab6ae 100644
--- a/target-ppc/translate.c
+++ b/target-ppc/translate.c
@@ -596,33 +596,33 @@ static opc_handler_t invalid_handler = {
 
 static inline void gen_op_cmp(TCGv arg0, TCGv arg1, int s, int crf)
 {
-int l1, l2, l3;
+TCGv t0 = tcg_temp_new();
+TCGv_i32 t1 = tcg_temp_new_i32();
 
 tcg_gen_trunc_tl_i32(cpu_crf[crf], cpu_so);
 
-l1 = gen_new_label();
-l2 = gen_new_label();
-l3 = gen_new_label();
-if (s) {
-tcg_gen_brcond_tl(TCG_COND_LT, arg0, arg1, l1);
-tcg_gen_brcond_tl(TCG_COND_GT, arg0, arg1, l2);
-} else {
-tcg_gen_brcond_tl(TCG_COND_LTU, arg0, arg1, l1);
-tcg_gen_brcond_tl(TCG_COND_GTU, arg0, arg1, l2);
-}
-tcg_gen_ori_i32(cpu_crf[crf], cpu_crf[crf], 1  CRF_EQ);
-tcg_gen_br(l3);
-gen_set_label(l1);
-tcg_gen_ori_i32(cpu_crf[crf], cpu_crf[crf], 1  CRF_LT);
-tcg_gen_br(l3);
-gen_set_label(l2);
-tcg_gen_ori_i32(cpu_crf[crf], cpu_crf[crf], 1  CRF_GT);
-gen_set_label(l3);
+tcg_gen_setcond_tl((s ? TCG_COND_LT: TCG_COND_LTU), t0, arg0, arg1);
+tcg_gen_trunc_tl_i32(t1, t0);
+tcg_gen_shli_i32(t1, t1, CRF_LT);
+tcg_gen_or_i32(cpu_crf[crf], cpu_crf[crf], t1);
+
+tcg_gen_setcond_tl((s ? TCG_COND_GT: TCG_COND_GTU), t0, arg0, arg1);
+tcg_gen_trunc_tl_i32(t1, t0);
+tcg_gen_shli_i32(t1, t1, CRF_GT);
+tcg_gen_or_i32(cpu_crf[crf], cpu_crf[crf], t1);
+
+tcg_gen_setcond_tl(TCG_COND_EQ, t0, arg0, arg1);
+tcg_gen_trunc_tl_i32(t1, t0);
+tcg_gen_shli_i32(t1, t1, CRF_EQ);
+tcg_gen_or_i32(cpu_crf[crf], cpu_crf[crf], t1);
+
+tcg_temp_free(t0);
+tcg_temp_free_i32(t1);
 }
 
 static inline void gen_op_cmpi(TCGv arg0, target_ulong arg1, int s, int crf)
 {
-TCGv t0 = tcg_const_local_tl(arg1);
+TCGv t0 = tcg_const_tl(arg1);
 gen_op_cmp(arg0, t0, s, crf);
 tcg_temp_free(t0);
 }
@@ -631,8 +631,8 @@ static inline void gen_op_cmpi(TCGv arg0, target_ulong 
arg1, int s, int crf)
 static inline void gen_op_cmp32(TCGv arg0, TCGv arg1, int s, int crf)
 {
 TCGv t0, t1;
-t0 = tcg_temp_local_new();
-t1 = tcg_temp_local_new();
+t0 = tcg_temp_new();
+t1 = tcg_temp_new();
 if (s) {
 tcg_gen_ext32s_tl(t0, arg0);
 tcg_gen_ext32s_tl(t1, arg1);
@@ -647,7 +647,7 @@ static inline void gen_op_cmp32(TCGv arg0, TCGv arg1, int 
s, int crf)
 
 static inline void gen_op_cmpi32(TCGv arg0, target_ulong arg1, int s, int crf)
 {
-TCGv t0 = tcg_const_local_tl(arg1);
+TCGv t0 = tcg_const_tl(arg1);
 gen_op_cmp32(arg0, t0, s, crf);
 tcg_temp_free(t0);
 }
-- 
1.8.1.2




[Qemu-devel] [PATCH v4 10/10] aio: support G_IO_HUP and G_IO_ERR

2013-02-20 Thread Stefan Hajnoczi
aio-posix.c could not take advantage of G_IO_HUP and G_IO_ERR because
select(2) does not have equivalent events.  Now that g_poll(3) is used
we can support G_IO_HUP and G_IO_ERR.

Signed-off-by: Stefan Hajnoczi stefa...@redhat.com
---
 aio-posix.c | 12 ++--
 1 file changed, 2 insertions(+), 10 deletions(-)

diff --git a/aio-posix.c b/aio-posix.c
index d755e16..b68eccd 100644
--- a/aio-posix.c
+++ b/aio-posix.c
@@ -88,8 +88,8 @@ void aio_set_fd_handler(AioContext *ctx,
 node-opaque = opaque;
 node-pollfds_idx = -1;
 
-node-pfd.events = (io_read ? G_IO_IN | G_IO_HUP : 0);
-node-pfd.events |= (io_write ? G_IO_OUT : 0);
+node-pfd.events = (io_read ? G_IO_IN | G_IO_HUP | G_IO_ERR : 0);
+node-pfd.events |= (io_write ? G_IO_OUT | G_IO_ERR : 0);
 }
 
 aio_notify(ctx);
@@ -112,13 +112,6 @@ bool aio_pending(AioContext *ctx)
 QLIST_FOREACH(node, ctx-aio_handlers, node) {
 int revents;
 
-/*
- * FIXME: right now we cannot get G_IO_HUP and G_IO_ERR because
- * main-loop.c is still select based (due to the slirp legacy).
- * If main-loop.c ever switches to poll, G_IO_ERR should be
- * tested too.  Dispatching G_IO_ERR to both handlers should be
- * okay, since handlers need to be ready for spurious wakeups.
- */
 revents = node-pfd.revents  node-pfd.events;
 if (revents  (G_IO_IN | G_IO_HUP | G_IO_ERR)  node-io_read) {
 return true;
@@ -150,7 +143,6 @@ static bool aio_dispatch(AioContext *ctx)
 revents = node-pfd.revents  node-pfd.events;
 node-pfd.revents = 0;
 
-/* See comment in aio_pending.  */
 if (!node-deleted 
 (revents  (G_IO_IN | G_IO_HUP | G_IO_ERR)) 
 node-io_read) {
-- 
1.8.1.2




Re: [Qemu-devel] [PATCH 1/9] build: disable Wstrict-prototypes

2013-02-20 Thread Kevin Wolf
On Mon, Feb 18, 2013 at 05:56:57PM -0600, Anthony Liguori wrote:
 GTK won't build with strict-prototypes due to gtkitemfactory.h:
 
 /* We use () here to mean unspecified arguments. This is deprecated
  * as of C99, but we can't change it without breaking compatibility.
  * (Note that if we are included from a C++ program () will mean
  * (void) so an explicit cast will be needed.)
  */
 typedef   void(*GtkItemFactoryCallback)  ();
 
 Signed-off-by: Anthony Liguori aligu...@us.ibm.com
 ---
  configure | 2 +-
  1 file changed, 1 insertion(+), 1 deletion(-)
 
 diff --git a/configure b/configure
 index bf5970f..74d5878 100755
 --- a/configure
 +++ b/configure
 @@ -283,7 +283,7 @@ sdl_config=${SDL_CONFIG-${cross_prefix}sdl-config}
  # default flags for all hosts
  QEMU_CFLAGS=-fno-strict-aliasing $QEMU_CFLAGS
  QEMU_CFLAGS=-Wall -Wundef -Wwrite-strings -Wmissing-prototypes $QEMU_CFLAGS
 -QEMU_CFLAGS=-Wstrict-prototypes -Wredundant-decls $QEMU_CFLAGS
 +QEMU_CFLAGS=-Wredundant-decls $QEMU_CFLAGS
  QEMU_CFLAGS=-D_GNU_SOURCE -D_FILE_OFFSET_BITS=64 -D_LARGEFILE_SOURCE 
 $QEMU_CFLAGS
  QEMU_INCLUDES=-I. -I\$(SRC_PATH) -I\$(SRC_PATH)/include
  if test $debug_info = yes; then

Other places wrap the inclusion of problematic headers in '#pragma GCC
diagnostic ...' instead of globally disabling warnings.

Kevin



[Qemu-devel] [PATCH 16/38] target-s390x: Use mulu2 for mlgr insn

2013-02-20 Thread Richard Henderson
Signed-off-by: Richard Henderson r...@twiddle.net
---
 target-s390x/helper.h | 1 -
 target-s390x/int_helper.c | 8 
 target-s390x/translate.c  | 3 +--
 3 files changed, 1 insertion(+), 11 deletions(-)

diff --git a/target-s390x/helper.h b/target-s390x/helper.h
index dd90d93..0d80aa0 100644
--- a/target-s390x/helper.h
+++ b/target-s390x/helper.h
@@ -8,7 +8,6 @@ DEF_HELPER_FLAGS_4(mvc, TCG_CALL_NO_WG, void, env, i32, i64, 
i64)
 DEF_HELPER_FLAGS_4(clc, TCG_CALL_NO_WG, i32, env, i32, i64, i64)
 DEF_HELPER_3(mvcl, i32, env, i32, i32)
 DEF_HELPER_FLAGS_4(clm, TCG_CALL_NO_WG, i32, env, i32, i32, i64)
-DEF_HELPER_FLAGS_3(mul128, TCG_CALL_NO_RWG, i64, env, i64, i64)
 DEF_HELPER_FLAGS_3(divs32, TCG_CALL_NO_WG, s64, env, s64, s64)
 DEF_HELPER_FLAGS_3(divu32, TCG_CALL_NO_WG, i64, env, i64, i64)
 DEF_HELPER_FLAGS_3(divs64, TCG_CALL_NO_WG, s64, env, s64, s64)
diff --git a/target-s390x/int_helper.c b/target-s390x/int_helper.c
index 6858301..af16b21 100644
--- a/target-s390x/int_helper.c
+++ b/target-s390x/int_helper.c
@@ -29,14 +29,6 @@
 #define HELPER_LOG(x...)
 #endif
 
-/* 64/64 - 128 unsigned multiplication */
-uint64_t HELPER(mul128)(CPUS390XState *env, uint64_t v1, uint64_t v2)
-{
-uint64_t reth;
-mulu64(env-retxl, reth, v1, v2);
-return reth;
-}
-
 /* 64/32 - 32 signed division */
 int64_t HELPER(divs32)(CPUS390XState *env, int64_t a, int64_t b64)
 {
diff --git a/target-s390x/translate.c b/target-s390x/translate.c
index a57296c..bdf69a3 100644
--- a/target-s390x/translate.c
+++ b/target-s390x/translate.c
@@ -2566,8 +2566,7 @@ static ExitStatus op_mul(DisasContext *s, DisasOps *o)
 
 static ExitStatus op_mul128(DisasContext *s, DisasOps *o)
 {
-gen_helper_mul128(o-out, cpu_env, o-in1, o-in2);
-return_low128(o-out2);
+tcg_gen_mulu2_i64(o-out2, o-out, o-in1, o-in2);
 return NO_EXIT;
 }
 
-- 
1.8.1.2




Re: [Qemu-devel] [PATCH 0/6] qcow2: cache flush fixes and performance improvements

2013-02-20 Thread Stefan Hajnoczi
On Wed, Feb 20, 2013 at 11:27:47AM +0100, Kevin Wolf wrote:
 On Tue, Feb 19, 2013 at 04:45:00PM +0100, Stefan Hajnoczi wrote:
  Users have reported that qcow2 internal snapshot creation is slow.  I filed 
  a
  bug report at https://bugs.launchpad.net/qemu/+bug/1126369.
  
  This patch series reduces the time for qcow2 internal snapshot creation
  significantly, from more than 3 minutes to under 1 second.
  
  In the process of removing unnecessary cache flushes, I also stumbled upon
  instances of bdrv_flush(bs-file) where we really want to flush metadata
  updates.  Since qcow2 caches metadata this actually does not write out the
  metadata updates to disk!  The fix is either bdrv_flush(bs) or a more 
  specific
  cache flush (e.g. refcount block cache).
  
  This series passes qemu-iotests.
  
  Stefan Hajnoczi (6):
qcow2: flush refcount cache correctly in alloc_refcount_block()
qcow2: flush refcount cache correctly in qcow2_write_snapshots()
qcow2: flush caches in qcow2_alloc_bytes()
qcow2: flush in qcow2_update_snapshot_refcount()
qcow2: drop flush in update_cluster_refcount()
qcow2: drop unnecessary flush in qcow2_update_snapshot_refcount()
  
   block/qcow2-refcount.c | 12 +++-
   block/qcow2-snapshot.c |  7 +--
   2 files changed, 4 insertions(+), 15 deletions(-)
 
 You touch a few bdrv_flush() callers that don't check the return value.
 Could you use the opportunity to fix that as well?

Sure, will send a v2.

Stefan



[Qemu-devel] [PATCH v4 02/10] main-loop: switch to g_poll() on POSIX hosts

2013-02-20 Thread Stefan Hajnoczi
Use g_poll(3) instead of select(2).  Well, this is kind of a cheat.
It's true that we're now using g_poll(3) on POSIX hosts but the *_fill()
and *_poll() functions are still using rfds/wfds/xfds.

We've set the scene to start converting *_fill() and *_poll() functions
step-by-step until no more rfds/wfds/xfds users remain.  Then we'll drop
the temporary gpollfds_from_select() and gpollfds_to_select() functions
and be left with native g_poll(2).

On Windows things are a little crazy: convert from rfds/wfds/xfds to
GPollFDs, back to rfds/wfds/xfds, call select(2), rfds/wfds/xfds back to
GPollFDs, and finally back to rfds/wfds/xfds again.  This is only
temporary and keeps the Windows build working through the following
patches.  We'll drop this excessive conversion later and be left with a
single GPollFDs - select(2) - GPollFDs sequence that allows Windows to
use select(2) while the rest of QEMU only knows about GPollFD.

Signed-off-by: Stefan Hajnoczi stefa...@redhat.com
---
 main-loop.c | 137 
 1 file changed, 129 insertions(+), 8 deletions(-)

diff --git a/main-loop.c b/main-loop.c
index d0d8fe4..489b27c 100644
--- a/main-loop.c
+++ b/main-loop.c
@@ -117,6 +117,8 @@ void qemu_notify_event(void)
 aio_notify(qemu_aio_context);
 }
 
+static GArray *gpollfds;
+
 int qemu_init_main_loop(void)
 {
 int ret;
@@ -133,6 +135,7 @@ int qemu_init_main_loop(void)
 return ret;
 }
 
+gpollfds = g_array_new(FALSE, FALSE, sizeof(GPollFD));
 qemu_aio_context = aio_context_new();
 src = aio_get_g_source(qemu_aio_context);
 g_source_attach(src, NULL);
@@ -146,6 +149,62 @@ static GPollFD poll_fds[1024 * 2]; /* this is probably 
overkill */
 static int n_poll_fds;
 static int max_priority;
 
+/* Load rfds/wfds/xfds into gpollfds.  Will be removed a few commits later. */
+static void gpollfds_from_select(void)
+{
+int fd;
+for (fd = 0; fd = nfds; fd++) {
+int events = 0;
+if (FD_ISSET(fd, rfds)) {
+events |= G_IO_IN | G_IO_HUP | G_IO_ERR;
+}
+if (FD_ISSET(fd, wfds)) {
+events |= G_IO_OUT | G_IO_ERR;
+}
+if (FD_ISSET(fd, xfds)) {
+events |= G_IO_PRI;
+}
+if (events) {
+GPollFD pfd = {
+.fd = fd,
+.events = events,
+};
+g_array_append_val(gpollfds, pfd);
+}
+}
+}
+
+/* Store gpollfds revents into rfds/wfds/xfds.  Will be removed a few commits
+ * later.
+ */
+static void gpollfds_to_select(int ret)
+{
+int i;
+
+FD_ZERO(rfds);
+FD_ZERO(wfds);
+FD_ZERO(xfds);
+
+if (ret = 0) {
+return;
+}
+
+for (i = 0; i  gpollfds-len; i++) {
+int fd = g_array_index(gpollfds, GPollFD, i).fd;
+int revents = g_array_index(gpollfds, GPollFD, i).revents;
+
+if (revents  (G_IO_IN | G_IO_HUP | G_IO_ERR)) {
+FD_SET(fd, rfds);
+}
+if (revents  (G_IO_OUT | G_IO_ERR)) {
+FD_SET(fd, wfds);
+}
+if (revents  G_IO_PRI) {
+FD_SET(fd, xfds);
+}
+}
+}
+
 #ifndef _WIN32
 static void glib_select_fill(int *max_fd, fd_set *rfds, fd_set *wfds,
  fd_set *xfds, uint32_t *cur_timeout)
@@ -212,22 +271,22 @@ static void glib_select_poll(fd_set *rfds, fd_set *wfds, 
fd_set *xfds,
 
 static int os_host_main_loop_wait(uint32_t timeout)
 {
-struct timeval tv, *tvarg = NULL;
 int ret;
 
 glib_select_fill(nfds, rfds, wfds, xfds, timeout);
 
-if (timeout  UINT32_MAX) {
-tvarg = tv;
-tv.tv_sec = timeout / 1000;
-tv.tv_usec = (timeout % 1000) * 1000;
-}
-
 if (timeout  0) {
 qemu_mutex_unlock_iothread();
 }
 
-ret = select(nfds + 1, rfds, wfds, xfds, tvarg);
+/* We'll eventually drop fd_set completely.  But for now we still have
+ * *_fill() and *_poll() functions that use rfds/wfds/xfds.
+ */
+gpollfds_from_select();
+
+ret = g_poll((GPollFD *)gpollfds-data, gpollfds-len, timeout);
+
+gpollfds_to_select(ret);
 
 if (timeout  0) {
 qemu_mutex_lock_iothread();
@@ -327,6 +386,55 @@ void qemu_fd_register(int fd)
FD_CONNECT | FD_WRITE | FD_OOB);
 }
 
+static int pollfds_fill(GArray *pollfds, fd_set *rfds, fd_set *wfds,
+fd_set *xfds)
+{
+int nfds = -1;
+int i;
+
+for (i = 0; i  pollfds-len; i++) {
+GPollFD *pfd = g_array_index(pollfds, GPollFD, i);
+int fd = pfd-fd;
+int events = pfd-events;
+if (events  (G_IO_IN | G_IO_HUP | G_IO_ERR)) {
+FD_SET(fd, rfds);
+nfds = MAX(nfds, fd);
+}
+if (events  (G_IO_OUT | G_IO_ERR)) {
+FD_SET(fd, wfds);
+nfds = MAX(nfds, fd);
+}
+if (events  G_IO_PRI) {
+FD_SET(fd, xfds);
+nfds = MAX(nfds, fd);
+}
+}
+

Re: [Qemu-devel] how to ues qemu -sd option?

2013-02-20 Thread Markus Armbruster
Weng Fan wengfan-f...@cn.fujitsu.com writes:

 Hi all:
 I want to use the qemu's -sd option to  emulate a sd card, so that I
 can get more free space.
 When I use the command qemu-system-ppc -M mpc8544ds -kernel uImage
 -initrd initrd.img
 -append root=/dev/ram rdinit=/linuxrc -nographic -sd sd.img to
 start the kernel image, I can't
 find any device like mmcblk in the /dev .

 Any ideas how to get this work?

-sd sd.img is shorthand for -drive if=sd,index=0,file=sd.img.  Like
all -drive (except for if=none), it requests the board to create a
suitable device.  Boards act on some requests, and ignore others.
mpc8544ds ignores if=sd.

To add devices beyond what the board code can do, use -device, like
this:

-drive if=none,id=sd0,file=sd.img -device DEV-MODEL,drive=sd0

with a suitable sd card DEV-MODEL.  However, I'm not aware of an sd card
device model that can be plugged that way.  Perhaps Andreas (cc'ed)
knows more.

See also docs/qdev-device-use.txt section Block Devices.



[Qemu-devel] [PATCH] help: add docs for multiqueue tap options

2013-02-20 Thread Jason Wang
Cc: Markus Armbruster arm...@redhat.com
Cc: Jason Wang jasow...@redhat.com
Signed-off-by: Jason Wang jasow...@redhat.com
---
This patch is neede for 1.4 stable also.
---
 qapi-schema.json |6 ++
 qemu-options.hx  |4 +++-
 2 files changed, 9 insertions(+), 1 deletions(-)

diff --git a/qapi-schema.json b/qapi-schema.json
index 7275b5d..cd7ea25 100644
--- a/qapi-schema.json
+++ b/qapi-schema.json
@@ -2504,6 +2504,9 @@
 #
 # @fd: #optional file descriptor of an already opened tap
 #
+# @fds: #optional multiple file descriptors of already opened multiqueue 
capable
+# tap
+#
 # @script: #optional script to initialize the interface
 #
 # @downscript: #optional script to shut down the interface
@@ -2518,6 +2521,9 @@
 #
 # @vhostfd: #optional file descriptor of an already opened vhost net device
 #
+# @vhostfds: #optional file descriptors of multiple already opened vhost net
+# devices
+#
 # @vhostforce: #optional vhost on for non-MSIX virtio guests
 #
 # Since 1.2
diff --git a/qemu-options.hx b/qemu-options.hx
index 4bc9c85..2832d82 100644
--- a/qemu-options.hx
+++ b/qemu-options.hx
@@ -1354,7 +1354,7 @@ DEF(net, HAS_ARG, QEMU_OPTION_net,
 -net tap[,vlan=n][,name=str],ifname=name\n
 connect the host TAP network interface to VLAN 'n'\n
 #else
--net 
tap[,vlan=n][,name=str][,fd=h][,ifname=name][,script=file][,downscript=dfile][,helper=helper][,sndbuf=nbytes][,vnet_hdr=on|off][,vhost=on|off][,vhostfd=h][,vhostforce=on|off]\n
+-net 
tap[,vlan=n][,name=str][,fd=h][,fds=x:y:...:z][,ifname=name][,script=file][,downscript=dfile][,helper=helper][,sndbuf=nbytes][,vnet_hdr=on|off][,vhost=on|off][,vhostfd=h][,vhostfds=x:y:...:z][,vhostforce=on|off]\n
 connect the host TAP network interface to VLAN 'n'\n
 use network scripts 'file' (default= 
DEFAULT_NETWORK_SCRIPT )\n
 to configure it and 'dfile' (default= 
DEFAULT_NETWORK_DOWN_SCRIPT )\n
@@ -1363,6 +1363,7 @@ DEF(net, HAS_ARG, QEMU_OPTION_net,
 use network helper 'helper' (default= 
DEFAULT_BRIDGE_HELPER ) to\n
 configure it\n
 use 'fd=h' to connect to an already opened TAP 
interface\n
+use 'fds=x:y:...:z' to connect to already opened 
multiqueue capable TAP interfaces\n
 use 'sndbuf=nbytes' to limit the size of the send buffer 
(the\n
 default is disabled 'sndbuf=0' to enable flow control set 
'sndbuf=1048576')\n
 use vnet_hdr=off to avoid enabling the IFF_VNET_HDR tap 
flag\n
@@ -1371,6 +1372,7 @@ DEF(net, HAS_ARG, QEMU_OPTION_net,
 (only has effect for virtio guests which use MSIX)\n
 use vhostforce=on to force vhost on for non-MSIX virtio 
guests\n
 use 'vhostfd=h' to connect to an already opened vhost net 
device\n
+use 'vhostfds=x:y:...:z to connect to multiple already 
opened vhost net devices\n
 -net bridge[,vlan=n][,name=str][,br=bridge][,helper=helper]\n
 connects a host TAP network interface to a host bridge 
device 'br'\n
 (default= DEFAULT_BRIDGE_INTERFACE ) using the program 
'helper'\n
-- 
1.7.1




Re: [Qemu-devel] how to ues qemu -sd option?

2013-02-20 Thread Peter Crosthwaite
Hi Weng Fan,

On Wed, Feb 20, 2013 at 6:18 PM, Markus Armbruster arm...@redhat.com wrote:
 Weng Fan wengfan-f...@cn.fujitsu.com writes:

 Hi all:
 I want to use the qemu's -sd option to  emulate a sd card, so that I
 can get more free space.
 When I use the command qemu-system-ppc -M mpc8544ds -kernel uImage
 -initrd initrd.img
 -append root=/dev/ram rdinit=/linuxrc -nographic -sd sd.img to
 start the kernel image, I can't
 find any device like mmcblk in the /dev .

 Any ideas how to get this work?

 -sd sd.img is shorthand for -drive if=sd,index=0,file=sd.img.  Like
 all -drive (except for if=none), it requests the board to create a
 suitable device.  Boards act on some requests, and ignore others.
 mpc8544ds ignores if=sd.

 To add devices beyond what the board code can do, use -device, like
 this:

 -drive if=none,id=sd0,file=sd.img -device DEV-MODEL,drive=sd0


With minimal effort you may be able to mock something up with SDHCI,
at least in its PIO mode.The SDHCI patches are currently doing review
cycles on list.

Regards,
Peter

 with a suitable sd card DEV-MODEL.  However, I'm not aware of an sd card
 device model that can be plugged that way.  Perhaps Andreas (cc'ed)
 knows more.

 See also docs/qdev-device-use.txt section Block Devices.




[Qemu-devel] emulate powerpc(mpc8544ds) on x86 architecture

2013-02-20 Thread Shi Rong

Hi all:
I want to emulate powerpc(mpc8544ds) on x86 architecture, is anybody 
succeed in it?


My working step:
about qemu:
./configure --cpu=ppc --target-list=ppc-softmmu --enable-fdt 
--enable-kvm --enable-tcg-interpreter --enable-linux-user 
--prefix=/home/shir/install/qemu/

make
make install

but everytime I start my qemu-system-ppc,
qemu-system-ppc -M mpc8544ds -kernel uImage -append root=/dev/ram 
rdinit=/linuxrc -initrd initrd -nographic

I get this error :
KVM: Couldn't find level irq capability. Expect the VM to stall at times
kvm_init_vcpu failed: Cannot allocate memory

fedora project reference below( 
https://fedoraproject.org/wiki/Features/KVM_and_QEMU_merge ):
KVM provides kernel support for running guests of *the same 
architecture* as the host. Guests run directly on the hardware with out 
any translation needed by the host, allowing much higher levels of 
performance to be attained. QEMU can now use the KVM kernel support for 
higher performance virtualization.

is that true?

--
--
Best regards!
--
Shi Rong
Nanjing Fujitsu Nanda Software Tech. Co., Ltd.(FNST)
No. 6 Wenzhu Road, Nanjing, 210012, China
TEL:+86+25-86630566-8222
MOBILE: 15996209501
EMail:shir.f...@cn.fujitsu.com
--
This communication is for use by the intended recipient(s) only and may
contain information that is privileged, confidential and exempt from
disclosure under applicable law. If you are not an intended recipient of
this communication, you are hereby notified that any dissemination,
distribution or copying hereof is strictly prohibited.  If you have received
this communication in error, please notify me by reply e-mail, permanently
delete this communication from your system, and destroy any hard copies you
may have printed.





Re: [Qemu-devel] [PATCH 4/9] target-i386: convert 'hv_relaxed' to static property

2013-02-20 Thread Eduardo Habkost
On Wed, Feb 20, 2013 at 10:03:37AM +0100, Igor Mammedov wrote:
 On Tue, 19 Feb 2013 15:45:16 -0300
 Eduardo Habkost ehabk...@redhat.com wrote:
 
  On Mon, Feb 11, 2013 at 05:35:06PM +0100, Igor Mammedov wrote:
   Signed-off-by: Igor Mammedov imamm...@redhat.com
   ---
target-i386/cpu.c |   35 ++-
1 files changed, 34 insertions(+), 1 deletions(-)
   
   diff --git a/target-i386/cpu.c b/target-i386/cpu.c
   index 1f14b65..b804031 100644
   --- a/target-i386/cpu.c
   +++ b/target-i386/cpu.c
   @@ -528,6 +528,38 @@ PropertyInfo qdev_prop_spinlocks = {
.defval =
   _defval  \ }

   +static void x86_get_hv_relaxed(Object *obj, Visitor *v, void *opaque,
   + const char *name, Error **errp)
   +{
   +bool value = hyperv_relaxed_timing_enabled();
   +
   +visit_type_bool(v, value, name, errp);
   +}
   +
   +static void x86_set_hv_relaxed(Object *obj, Visitor *v, void *opaque,
   + const char *name, Error **errp)
   +{
   +bool value;
   +
   +visit_type_bool(v, value, name, errp);
   +if (error_is_set(errp)) {
   +return;
   +}
   +hyperv_enable_relaxed_timing(value);
   +}
   +
   +PropertyInfo qdev_prop_hv_relaxed = {
   +.name  = boolean,
   +.get   = x86_get_hv_relaxed,
   +.set   = x86_set_hv_relaxed,
   +};
   +#define DEFINE_PROP_HV_RELAXED(_n, _defval)
   {  \
   +.name  =
   _n,   \
   +.info  =
   qdev_prop_hv_relaxed,\
   +.qtype =
   QTYPE_QBOOL,  \
   +.defval =
   _defval  \ +}
   +
static Property cpu_x86_properties[] = {
DEFINE_PROP_FAMILY(family),
DEFINE_PROP_MODEL(model),
   @@ -538,6 +570,7 @@ static Property cpu_x86_properties[] = {
DEFINE_PROP_MODEL_ID(model-id),
DEFINE_PROP_TSC_FREQ(tsc-frequency),
DEFINE_PROP_HV_SPINLOCKS(hv-spinlocks,
   HYPERV_SPINLOCK_NEVER_RETRY),
   +DEFINE_PROP_HV_RELAXED(hv-relaxed, false),
  
  Why not simply make it a X86CPU struct field, so we don't need a special
  PropertyInfo?
  
  The whole contents of target-i386/hyperv.c are getters/setters for three
  static variables that should have been X86CPU fields in the first place.
 I went via less intrusive approach to avoid breaking anything during
 conversion. Can we proceed with conversion first and than decide whether to
 move hv_* into CPU or not?

Personally, I find the complex getter+setter+PropertyInfo+DEFINE_PROP_*
code above more complex and harder to review (thus harder to make me
confident it won't break anything) than simply moving a static variable
to a X86CPU field.

Also, it doesn't even make sense to have a X86CPU property available for
a static variable that is not per-CPU. What do we gain by making it look
like a per-X86CPU property if it is not?


 
  
  
DEFINE_PROP_END_OF_LIST(),
 };

   @@ -1468,7 +1501,7 @@ static void cpu_x86_parse_featurestr(X86CPU *cpu,
   char *features, Error **errp) } else if (!strcmp(featurestr, enforce)) {
check_cpuid = enforce_cpuid = 1;
} else if (!strcmp(featurestr, hv_relaxed)) {
   -hyperv_enable_relaxed_timing(true);
   +object_property_parse(OBJECT(cpu), on, hv-relaxed, errp);
} else if (!strcmp(featurestr, hv_vapic)) {
hyperv_enable_vapic_recommended(true);
} else {
   -- 
   1.7.1
   
   
  
 

-- 
Eduardo



[Qemu-devel] [PATCH v4 3/6] add backup related monitor commands

2013-02-20 Thread Dietmar Maurer
We use a generic BackupDriver struct to encapsulate all archive format
related function.

Another option would be to simply dump devid,cluster_num,cluster_data to
the output fh (pipe), and an external binary saves the data. That way we
could move the whole archive format related code out of qemu.

Signed-off-by: Dietmar Maurer diet...@proxmox.com
---
 backup.h |   12 ++
 blockdev.c   |  423 ++
 hmp-commands.hx  |   31 
 hmp.c|   63 
 hmp.h|3 +
 monitor.c|7 +
 qapi-schema.json |   95 
 qmp-commands.hx  |   27 
 8 files changed, 661 insertions(+), 0 deletions(-)

diff --git a/backup.h b/backup.h
index d9395bc..c8ba153 100644
--- a/backup.h
+++ b/backup.h
@@ -29,4 +29,16 @@ int backup_job_create(BlockDriverState *bs, BackupDumpFunc 
*backup_dump_cb,
   BlockDriverCompletionFunc *backup_complete_cb,
   void *opaque, int64_t speed);
 
+typedef struct BackupDriver {
+const char *format;
+void *(*open_cb)(const char *filename, uuid_t uuid, Error **errp);
+int (*close_cb)(void *opaque, Error **errp);
+int (*register_config_cb)(void *opaque, const char *name, gpointer data,
+  size_t data_len);
+int (*register_stream_cb)(void *opaque, const char *devname, size_t size);
+int (*dump_cb)(void *opaque, uint8_t dev_id, int64_t cluster_num,
+   unsigned char *buf, size_t *zero_bytes);
+int (*complete_cb)(void *opaque, uint8_t dev_id, int ret);
+} BackupDriver;
+
 #endif /* QEMU_BACKUP_H */
diff --git a/blockdev.c b/blockdev.c
index 63e6f1e..c340fde 100644
--- a/blockdev.c
+++ b/blockdev.c
@@ -20,6 +20,7 @@
 #include qmp-commands.h
 #include trace.h
 #include sysemu/arch_init.h
+#include backup.h
 
 static QTAILQ_HEAD(drivelist, DriveInfo) drives = 
QTAILQ_HEAD_INITIALIZER(drives);
 
@@ -1334,6 +1335,428 @@ void qmp_drive_mirror(const char *device, const char 
*target,
 drive_get_ref(drive_get_by_blockdev(bs));
 }
 
+/* Backup related function */
+
+static void backup_run_next_job(void);
+
+static struct GenericBackupState {
+Error *error;
+bool cancel;
+uuid_t uuid;
+char uuid_str[37];
+int64_t speed;
+time_t start_time;
+time_t end_time;
+char *backup_file;
+const BackupDriver *driver;
+void *writer;
+GList *bcb_list;
+size_t total;
+size_t transferred;
+size_t zero_bytes;
+} backup_state;
+
+typedef struct BackupCB {
+BlockDriverState *bs;
+uint8_t dev_id;
+bool started;
+bool completed;
+size_t size;
+size_t transferred;
+size_t zero_bytes;
+} BackupCB;
+
+static int backup_dump_cb(void *opaque, BlockDriverState *bs,
+  int64_t cluster_num, unsigned char *buf)
+{
+BackupCB *bcb = opaque;
+
+assert(backup_state.driver);
+assert(backup_state.writer);
+assert(backup_state.driver-dump_cb);
+
+size_t zero_bytes = 0;
+int bytes = backup_state.driver-dump_cb(backup_state.writer,
+ bcb-dev_id, cluster_num,
+ buf, zero_bytes);
+
+if (bytes  0) {
+bcb-transferred += bytes;
+backup_state.transferred += bytes;
+if (zero_bytes) {
+bcb-zero_bytes += bytes;
+backup_state.zero_bytes += zero_bytes;
+}
+}
+
+return bytes;
+}
+
+static void backup_cleanup(void)
+{
+if (backup_state.writer  backup_state.driver) {
+backup_state.end_time = time(NULL);
+Error *local_err = NULL;
+backup_state.driver-close_cb(backup_state.writer, local_err);
+error_propagate(backup_state.error, local_err);
+backup_state.writer = NULL;
+}
+
+if (backup_state.bcb_list) {
+GList *l = backup_state.bcb_list;
+while (l) {
+BackupCB *bcb = l-data;
+l = g_list_next(l);
+drive_put_ref_bh_schedule(drive_get_by_blockdev(bcb-bs));
+g_free(bcb);
+}
+g_list_free(backup_state.bcb_list);
+backup_state.bcb_list = NULL;
+}
+}
+
+static void backup_complete_cb(void *opaque, int ret)
+{
+BackupCB *bcb = opaque;
+
+assert(backup_state.driver);
+assert(backup_state.writer);
+assert(backup_state.driver-complete_cb);
+assert(backup_state.driver-close_cb);
+
+bcb-completed = true;
+
+backup_state.driver-complete_cb(backup_state.writer, bcb-dev_id, ret);
+
+if (!backup_state.cancel) {
+backup_run_next_job();
+}
+}
+
+static void backup_cancel(void)
+{
+backup_state.cancel = true;
+
+if (!backup_state.error) {
+error_setg(backup_state.error, backup cancelled);
+}
+
+/* drain all i/o (awake jobs waiting for aio) */
+bdrv_drain_all();
+
+int job_count = 0;
+GList *l = backup_state.bcb_list;
+while (l) {
+BackupCB *bcb = l-data;
+ 

[Qemu-devel] [PATCH v4 5/6] add regression tests for backup

2013-02-20 Thread Dietmar Maurer
Simple regression tests using vma-reader and vma-writer.

Note: the call to g_thread_init() solves problems with g_slice_alloc() - 
without that call we get arbitrary crashes.

Signed-off-by: Dietmar Maurer diet...@proxmox.com
---
 tests/Makefile  |   11 +-
 tests/backup-test.c |  517 +++
 2 files changed, 526 insertions(+), 2 deletions(-)
 create mode 100644 tests/backup-test.c

diff --git a/tests/Makefile b/tests/Makefile
index 567e36e..136be84 100644
--- a/tests/Makefile
+++ b/tests/Makefile
@@ -59,6 +59,8 @@ gcov-files-test-mul64-y = util/host-utils.c
 
 check-block-$(CONFIG_POSIX) += tests/qemu-iotests-quick.sh
 
+check-backup-y = tests/backup-test$(EXESUF)
+
 # All QTests for now are POSIX-only, but the dependencies are
 # really in libqtest, not in the testcases themselves.
 check-qtest-i386-y = tests/fdc-test$(EXESUF)
@@ -102,6 +104,7 @@ tests/test-coroutine$(EXESUF): tests/test-coroutine.o 
$(block-obj-y) libqemuutil
 tests/test-aio$(EXESUF): tests/test-aio.o $(block-obj-y) libqemuutil.a 
libqemustub.a
 tests/test-thread-pool$(EXESUF): tests/test-thread-pool.o $(block-obj-y) 
libqemuutil.a libqemustub.a
 tests/test-iov$(EXESUF): tests/test-iov.o libqemuutil.a
+tests/backup-test$(EXESUF): tests/backup-test.o vma-reader.o $(block-obj-y) 
libqemuutil.a libqemustub.a
 tests/test-hbitmap$(EXESUF): tests/test-hbitmap.o libqemuutil.a libqemustub.a
 tests/test-x86-cpuid$(EXESUF): tests/test-x86-cpuid.o
 tests/test-xbzrle$(EXESUF): tests/test-xbzrle.o xbzrle.o page_cache.o 
libqemuutil.a
@@ -213,10 +216,14 @@ check-tests/qemu-iotests-quick.sh: 
tests/qemu-iotests-quick.sh qemu-img$(EXESUF)
 
 # Consolidated targets
 
-.PHONY: check-qtest check-unit check
+.PHONY: check-backup check-qtest check-unit check
 check-qtest: $(patsubst %,check-qtest-%, $(QTEST_TARGETS))
 check-unit: $(patsubst %,check-%, $(check-unit-y))
 check-block: $(patsubst %,check-%, $(check-block-y))
-check: check-unit check-qtest
+
+check-backup: tests/backup-test$(EXESUF)
+   $
+
+check: check-unit check-qtest check-backup
 
 -include $(wildcard tests/*.d)
diff --git a/tests/backup-test.c b/tests/backup-test.c
new file mode 100644
index 000..5ff6f1d
--- /dev/null
+++ b/tests/backup-test.c
@@ -0,0 +1,517 @@
+/*
+ * QEMU backup test suit
+ *
+ * Copyright (C) Proxmox Server Solutions
+ *
+ * Authors:
+ *  Dietmar Maurer (diet...@proxmox.com)
+ *
+ * This work is licensed under the terms of the GNU GPL, version 2.  See
+ * the COPYING file in the top-level directory.
+ *
+ * Fixme: running 'backup-test -l' trigger a bug in g_slice_alloc()
+ * Note: 'G_SLICE=always-malloc ./tests/backup-test -l' works
+ *
+ */
+
+#include sys/time.h
+#include sys/types.h
+#include stdarg.h
+#include stdio.h
+#include getopt.h
+#include libgen.h
+
+#include qemu-common.h
+#include block/block.h
+
+#include vma.h
+
+static int opt_debug;
+static int opt_loop;
+
+#define DPRINTF(fmt, ...) \
+do { if (opt_debug) { printf(fmt, ## __VA_ARGS__); } } while (0)
+
+#define CLUSTER(x) (x*BACKUP_CLUSTER_SIZE)
+
+#define RUN_TEST(testfunc, speed) \
+backup_test(#testfunc  speed  #speed, speed, testfunc);
+
+
+static unsigned char buf_sec_pattern_cd[BDRV_SECTOR_SIZE];
+static unsigned char buf_sec_pattern_32[BDRV_SECTOR_SIZE];
+
+#define TEST_IMG_SIZE (6*1024*1024+BDRV_SECTOR_SIZE)
+#define TEST_IMG_NAME backuptest.raw
+#define TEST_IMG_RESTORE_NAME backuptest.raw.restore
+#define TEST_VMA_NAME backuptest.vma
+
+typedef struct BackupCB {
+VmaWriter *vmaw;
+uint8_t dev_id;
+} BackupCB;
+
+static int backup_dump_cb(void *opaque, BlockDriverState *bs,
+  int64_t cluster_num, unsigned char *buf)
+{
+BackupCB *bcb = opaque;
+
+DPRINTF(backup_dump_cb C%zd %d\n, cluster_num, bcb-dev_id);
+
+size_t zb = 0;
+if (vma_writer_write(bcb-vmaw, bcb-dev_id, cluster_num, buf, zb)  0) {
+printf(backup_dump_cb vma_writer_write failed\n);
+return -1;
+}
+
+return 0;
+}
+
+static void backup_complete_cb(void *opaque, int ret)
+{
+BackupCB *bcb = opaque;
+
+DPRINTF(backup_complete_cb %d %d\n, bcb-dev_id, ret);
+
+if (ret  0) {
+vma_writer_set_error(bcb-vmaw, backup_complete_cb %d, ret);
+}
+
+if (vma_writer_close_stream(bcb-vmaw, bcb-dev_id) = 0) {
+Error *err = NULL;
+if (vma_writer_close(bcb-vmaw, err) != 0) {
+g_error(vma_writer_close failed %s, error_get_pretty(err));
+}
+}
+DPRINTF(backup_complete_cb finish\n);
+}
+
+static void write_sec_pattern_cd(BlockDriverState *bs, int64_t offset)
+{
+int ret;
+
+DPRINTF(write_sec_pattern_cd %zd\n, offset);
+
+if (offset  0x1ff) {
+g_error(write_sec_pattern_cd offset %zd is not sector aligned\n,
+offset);
+}
+
+ret = bdrv_write(bs, offset  9, buf_sec_pattern_cd, 1);
+if (ret  0) {
+g_error(write_sec_pattern_cd %zd failed, offset);
+}
+
+}
+
+static void read_sec(BlockDriverState 

[Qemu-devel] [PATCH 05/38] tcg: Add signed multiword multiplication operations

2013-02-20 Thread Richard Henderson
Signed-off-by: Richard Henderson r...@twiddle.net
---
 tcg/README | 4 
 tcg/arm/tcg-target.h   | 1 +
 tcg/hppa/tcg-target.h  | 1 +
 tcg/i386/tcg-target.h  | 2 ++
 tcg/ia64/tcg-target.h  | 2 ++
 tcg/mips/tcg-target.h  | 1 +
 tcg/optimize.c | 1 +
 tcg/ppc/tcg-target.h   | 1 +
 tcg/ppc64/tcg-target.h | 2 ++
 tcg/s390/tcg-target.h  | 2 ++
 tcg/sparc/tcg-target.h | 2 ++
 tcg/tcg-opc.h  | 2 ++
 tcg/tcg.h  | 1 +
 tcg/tci/tcg-target.h   | 2 ++
 14 files changed, 24 insertions(+)

diff --git a/tcg/README b/tcg/README
index 89f0cdd..934e7af 100644
--- a/tcg/README
+++ b/tcg/README
@@ -375,6 +375,10 @@ is returned in two single-word outputs.
 Similar to mul, except two unsigned inputs T1 and T2 yielding the full
 double-word product T0.  The later is returned in two single-word outputs.
 
+* muls2_i32/i64 t0_low, t0_high, t1, t2
+
+Similar to mulu2, except the two inputs T1 and T2 are signed.
+
 * 64-bit target on 32-bit host support
 
 The following opcodes are internal to TCG.  Thus they are to be implemented by
diff --git a/tcg/arm/tcg-target.h b/tcg/arm/tcg-target.h
index 7083f3a..f9599bd 100644
--- a/tcg/arm/tcg-target.h
+++ b/tcg/arm/tcg-target.h
@@ -75,6 +75,7 @@ typedef enum {
 #define TCG_TARGET_HAS_nor_i32  0
 #define TCG_TARGET_HAS_deposit_i32  0
 #define TCG_TARGET_HAS_movcond_i32  1
+#define TCG_TARGET_HAS_muls2_i320
 
 enum {
 TCG_AREG0 = TCG_REG_R6,
diff --git a/tcg/hppa/tcg-target.h b/tcg/hppa/tcg-target.h
index e2754fe..ebd53d9 100644
--- a/tcg/hppa/tcg-target.h
+++ b/tcg/hppa/tcg-target.h
@@ -98,6 +98,7 @@ typedef enum {
 #define TCG_TARGET_HAS_nor_i32  0
 #define TCG_TARGET_HAS_deposit_i32  1
 #define TCG_TARGET_HAS_movcond_i32  1
+#define TCG_TARGET_HAS_muls2_i320
 
 /* optional instructions automatically implemented */
 #define TCG_TARGET_HAS_neg_i32  0 /* sub rd, 0, rs */
diff --git a/tcg/i386/tcg-target.h b/tcg/i386/tcg-target.h
index 4f00171..2b08ef7 100644
--- a/tcg/i386/tcg-target.h
+++ b/tcg/i386/tcg-target.h
@@ -95,6 +95,7 @@ typedef enum {
 #define TCG_TARGET_HAS_add2_i32 1
 #define TCG_TARGET_HAS_sub2_i32 1
 #define TCG_TARGET_HAS_mulu2_i321
+#define TCG_TARGET_HAS_muls2_i320
 
 #if TCG_TARGET_REG_BITS == 64
 #define TCG_TARGET_HAS_div2_i64 1
@@ -120,6 +121,7 @@ typedef enum {
 #define TCG_TARGET_HAS_add2_i64 0
 #define TCG_TARGET_HAS_sub2_i64 0
 #define TCG_TARGET_HAS_mulu2_i640
+#define TCG_TARGET_HAS_muls2_i640
 #endif
 
 #define TCG_TARGET_deposit_i32_valid(ofs, len) \
diff --git a/tcg/ia64/tcg-target.h b/tcg/ia64/tcg-target.h
index 40f442e..e3d72ea 100644
--- a/tcg/ia64/tcg-target.h
+++ b/tcg/ia64/tcg-target.h
@@ -142,6 +142,8 @@ typedef enum {
 #define TCG_TARGET_HAS_sub2_i64 0
 #define TCG_TARGET_HAS_mulu2_i320
 #define TCG_TARGET_HAS_mulu2_i640
+#define TCG_TARGET_HAS_muls2_i320
+#define TCG_TARGET_HAS_muls2_i640
 
 #define TCG_TARGET_deposit_i32_valid(ofs, len) ((len) = 16)
 #define TCG_TARGET_deposit_i64_valid(ofs, len) ((len) = 16)
diff --git a/tcg/mips/tcg-target.h b/tcg/mips/tcg-target.h
index 78af664..0384bd3 100644
--- a/tcg/mips/tcg-target.h
+++ b/tcg/mips/tcg-target.h
@@ -87,6 +87,7 @@ typedef enum {
 #define TCG_TARGET_HAS_orc_i32  0
 #define TCG_TARGET_HAS_eqv_i32  0
 #define TCG_TARGET_HAS_nand_i32 0
+#define TCG_TARGET_HAS_muls2_i320
 
 /* optional instructions only implemented on MIPS4, MIPS32 and Loongson 2 */
 #if (defined(__mips_isa_rev)  (__mips_isa_rev = 1)) || \
diff --git a/tcg/optimize.c b/tcg/optimize.c
index 027b3a5..bc6e5c1 100644
--- a/tcg/optimize.c
+++ b/tcg/optimize.c
@@ -559,6 +559,7 @@ static TCGArg *tcg_constant_folding(TCGContext *s, uint16_t 
*tcg_opc_ptr,
 swap_commutative(args[1], args[3], args[5]);
 break;
 CASE_OP_32_64(mulu2):
+CASE_OP_32_64(muls2):
 swap_commutative(args[0], args[2], args[3]);
 break;
 case INDEX_op_brcond2_i32:
diff --git a/tcg/ppc/tcg-target.h b/tcg/ppc/tcg-target.h
index 0fdad04..17a6bb3 100644
--- a/tcg/ppc/tcg-target.h
+++ b/tcg/ppc/tcg-target.h
@@ -94,6 +94,7 @@ typedef enum {
 #define TCG_TARGET_HAS_nor_i32  1
 #define TCG_TARGET_HAS_deposit_i32  1
 #define TCG_TARGET_HAS_movcond_i32  1
+#define TCG_TARGET_HAS_muls2_i320
 
 #define TCG_AREG0 TCG_REG_R27
 
diff --git a/tcg/ppc64/tcg-target.h b/tcg/ppc64/tcg-target.h
index 86929c1..aa6a0f0 100644
--- a/tcg/ppc64/tcg-target.h
+++ b/tcg/ppc64/tcg-target.h
@@ -88,6 +88,7 @@ typedef enum {
 #define TCG_TARGET_HAS_add2_i32 0
 #define TCG_TARGET_HAS_sub2_i32 0
 #define TCG_TARGET_HAS_mulu2_i320
+#define TCG_TARGET_HAS_muls2_i320
 
 #define TCG_TARGET_HAS_div_i64  1
 #define TCG_TARGET_HAS_rot_i64  0
@@ -112,6 +113,7 @@ typedef enum {
 #define TCG_TARGET_HAS_add2_i64 0
 

[Qemu-devel] [PATCH v1 3/5] xilinx_spips: Add missing dual-bus snoop commands

2013-02-20 Thread Peter Crosthwaite
From: Nathan Rossi nathan.ro...@xilinx.com

Added additional commands to the switch to check for when snooping commands in
dual bus mode setups. Cleaned up code to use an enum.

Signed-off-by: Nathan Rossi nathan.ro...@xilinx.com
Signed-off-by: Peter Crosthwaite peter.crosthwa...@xilinx.com
---

 hw/xilinx_spips.c |   29 +++--
 1 files changed, 23 insertions(+), 6 deletions(-)

diff --git a/hw/xilinx_spips.c b/hw/xilinx_spips.c
index 03797c3..45a1c51 100644
--- a/hw/xilinx_spips.c
+++ b/hw/xilinx_spips.c
@@ -115,6 +115,19 @@
 #define SNOOP_NONE 0xFE
 #define SNOOP_STRIPING 0
 
+typedef enum {
+READ = 0x3,
+FAST_READ = 0xb,
+DOR = 0x3b,
+QOR = 0x6b,
+DIOR = 0xbb,
+QIOR = 0xeb,
+
+PP = 0x2,
+DPP = 0xa2,
+QPP = 0x32,
+} FlashCMD;
+
 typedef struct {
 SysBusDevice busdev;
 MemoryRegion iomem;
@@ -251,15 +264,19 @@ static void xilinx_spips_flush_txfifo(XilinxSPIPS *s)
 switch (s-snoop_state) {
 case (SNOOP_CHECKING):
 switch (tx) { /* new instruction code */
-case 0x0b: /* dual/quad output read DOR/QOR */
-case 0x6b:
-s-snoop_state = 4;
+case READ: /* 3 address bytes, no dummy bytes/cycles */
+case PP:
+case DPP:
+case QPP:
+s-snoop_state = 3;
 break;
-/* FIXME: these vary between vendor - set to spansion */
-case 0xbb: /* high performance dual read DIOR */
+case FAST_READ: /* 3 address bytes, 1 dummy byte */
+case DOR:
+case QOR:
+case DIOR: /* FIXME: these vary between vendor - set to spansion */
 s-snoop_state = 4;
 break;
-case 0xeb: /* high performance quad read QIOR */
+case QIOR: /* 3 address bytes, 2 dummy bytes */
 s-snoop_state = 6;
 break;
 default:
-- 
1.7.0.4




Re: [Qemu-devel] [PATCH v2] vga: fix byteswapping.

2013-02-20 Thread Stefano Stabellini
On Wed, 20 Feb 2013, Gerd Hoffmann wrote:
 In case host and guest endianness differ the vga code first creates
 a shared surface (using qemu_create_displaysurface_from), then goes
 patch the surface format to indicate that the bytes must be swapped.
 
 The switch to pixman broke that hack as the format patching isn't
 propagated into the pixman image, so ui code using the pixman image
 directly (such as vnc) uses the wrong format.
 
 Fix that by adding a byteswap parameter to
 qemu_create_displaysurface_from, so we'll use the correct format
 when creating the surface (and the pixman image) and don't have
 to patch the format afterwards.
 
 [ v2: unbreak xen build ]
 
 Cc: qemu-sta...@nongnu.org
 Cc: mark.cave-ayl...@ilande.co.uk
 Cc: ag...@suse.de
 Signed-off-by: Gerd Hoffmann kra...@redhat.com

the patch looks good to me


  hw/qxl-render.c  |3 ++-
  hw/vga.c |   18 --
  hw/vmware_vga.c  |2 +-
  hw/xenfb.c   |3 ++-
  include/ui/console.h |3 ++-
  ui/console.c |9 +++--
  6 files changed, 22 insertions(+), 16 deletions(-)
 
 diff --git a/hw/qxl-render.c b/hw/qxl-render.c
 index 88e63f8..455fb91 100644
 --- a/hw/qxl-render.c
 +++ b/hw/qxl-render.c
 @@ -118,7 +118,8 @@ static void qxl_render_update_area_unlocked(PCIQXLDevice 
 *qxl)
   qxl-guest_primary.surface.height,
   qxl-guest_primary.bits_pp,
   qxl-guest_primary.abs_stride,
 - qxl-guest_primary.data);
 + qxl-guest_primary.data,
 + false);
  } else {
  qemu_resize_displaysurface(vga-ds,
  qxl-guest_primary.surface.width,
 diff --git a/hw/vga.c b/hw/vga.c
 index e2ba7f2..1caf23d 100644
 --- a/hw/vga.c
 +++ b/hw/vga.c
 @@ -1643,6 +1643,11 @@ static void vga_draw_graphic(VGACommonState *s, int 
 full_update)
  uint8_t *d;
  uint32_t v, addr1, addr;
  vga_draw_line_func *vga_draw_line;
 +#if defined(HOST_WORDS_BIGENDIAN) == defined(TARGET_WORDS_BIGENDIAN)
 +static const bool byteswap = false;
 +#else
 +static const bool byteswap = true;
 +#endif
  
  full_update |= update_basic_params(s);
  
 @@ -1685,18 +1690,11 @@ static void vga_draw_graphic(VGACommonState *s, int 
 full_update)
  disp_width != s-last_width ||
  height != s-last_height ||
  s-last_depth != depth) {
 -#if defined(HOST_WORDS_BIGENDIAN) == defined(TARGET_WORDS_BIGENDIAN)
 -if (depth == 16 || depth == 32) {
 -#else
 -if (depth == 32) {
 -#endif
 +if (depth == 32 || (depth == 16  !byteswap)) {
  qemu_free_displaysurface(s-ds);
  s-ds-surface = qemu_create_displaysurface_from(disp_width, 
 height, depth,
  s-line_offset,
 -s-vram_ptr + (s-start_addr * 4));
 -#if defined(HOST_WORDS_BIGENDIAN) != defined(TARGET_WORDS_BIGENDIAN)
 -s-ds-surface-pf = 
 qemu_different_endianness_pixelformat(depth);
 -#endif
 +s-vram_ptr + (s-start_addr * 4), byteswap);
  dpy_gfx_resize(s-ds);
  } else {
  qemu_console_resize(s-ds, disp_width, height);
 @@ -1715,7 +1713,7 @@ static void vga_draw_graphic(VGACommonState *s, int 
 full_update)
  s-ds-surface = qemu_create_displaysurface_from(disp_width,
  height, depth,
  s-line_offset,
 -s-vram_ptr + (s-start_addr * 4));
 +s-vram_ptr + (s-start_addr * 4), byteswap);
  dpy_gfx_setdata(s-ds);
  }
  
 diff --git a/hw/vmware_vga.c b/hw/vmware_vga.c
 index cd15ee4..8fc201b 100644
 --- a/hw/vmware_vga.c
 +++ b/hw/vmware_vga.c
 @@ -1074,7 +1074,7 @@ static void vmsvga_screen_dump(void *opaque, const char 
 *filename, bool cswitch,
   ds_get_height(s-vga.ds),
   32,
   ds_get_linesize(s-vga.ds),
 - s-vga.vram_ptr);
 + s-vga.vram_ptr, false);
  ppm_save(filename, ds, errp);
  g_free(ds);
  }
 diff --git a/hw/xenfb.c b/hw/xenfb.c
 index 903efd3..7f1f6b4 100644
 --- a/hw/xenfb.c
 +++ b/hw/xenfb.c
 @@ -756,7 +756,8 @@ static void xenfb_update(void *opaque)
  qemu_free_displaysurface(xenfb-c.ds);
  xenfb-c.ds-surface = qemu_create_displaysurface_from
  (xenfb-width, xenfb-height, xenfb-depth,
 - xenfb-row_stride, xenfb-pixels + xenfb-offset);
 + xenfb-row_stride, xenfb-pixels + xenfb-offset,
 + false);
  break;
  default:
  /* we must convert stuff */
 diff --git a/include/ui/console.h b/include/ui/console.h
 index fc23baa..18012f1 100644
 --- a/include/ui/console.h
 +++ b/include/ui/console.h
 @@ -184,7 +184,8 @@ struct DisplayState {
  void register_displaystate(DisplayState *ds);
  DisplayState 

[Qemu-devel] [PATCH 03/38] tcg-sparc: Always implement 32-bit multiword ops

2013-02-20 Thread Richard Henderson
Cc: Blue Swirl blauwir...@gmail.com
Signed-off-by: Richard Henderson r...@twiddle.net
---
 tcg/sparc/tcg-target.c | 6 --
 tcg/sparc/tcg-target.h | 7 +++
 2 files changed, 7 insertions(+), 6 deletions(-)

diff --git a/tcg/sparc/tcg-target.c b/tcg/sparc/tcg-target.c
index 03db514..6d489fc 100644
--- a/tcg/sparc/tcg-target.c
+++ b/tcg/sparc/tcg-target.c
@@ -1327,6 +1327,8 @@ static inline void tcg_out_op(TCGContext *s, TCGOpcode 
opc, const TCGArg *args,
  args[3], const_args[3],
  args[4], const_args[4]);
 break;
+#endif
+
 case INDEX_op_add2_i32:
 tcg_out_addsub2(s, args[0], args[1], args[2], args[3],
 args[4], const_args[4], args[5], const_args[5],
@@ -1342,7 +1344,6 @@ static inline void tcg_out_op(TCGContext *s, TCGOpcode 
opc, const TCGArg *args,
ARITH_UMUL);
 tcg_out_rdy(s, args[1]);
 break;
-#endif
 
 case INDEX_op_qemu_ld8u:
 tcg_out_qemu_ld(s, args, 0);
@@ -1511,10 +1512,11 @@ static const TCGTargetOpDef sparc_op_defs[] = {
 #if TCG_TARGET_REG_BITS == 32
 { INDEX_op_brcond2_i32, { rZ, rZ, rJ, rJ } },
 { INDEX_op_setcond2_i32, { r, rZ, rZ, rJ, rJ } },
+#endif
+
 { INDEX_op_add2_i32, { r, r, rZ, rZ, rJ, rJ } },
 { INDEX_op_sub2_i32, { r, r, rZ, rZ, rJ, rJ } },
 { INDEX_op_mulu2_i32, { r, r, rZ, rJ } },
-#endif
 
 #if TCG_TARGET_REG_BITS == 64
 { INDEX_op_mov_i64, { r, r } },
diff --git a/tcg/sparc/tcg-target.h b/tcg/sparc/tcg-target.h
index 6c62e45..8446721 100644
--- a/tcg/sparc/tcg-target.h
+++ b/tcg/sparc/tcg-target.h
@@ -102,6 +102,9 @@ typedef enum {
 #define TCG_TARGET_HAS_nor_i32  0
 #define TCG_TARGET_HAS_deposit_i32  0
 #define TCG_TARGET_HAS_movcond_i32  1
+#define TCG_TARGET_HAS_add2_i32 1
+#define TCG_TARGET_HAS_sub2_i32 1
+#define TCG_TARGET_HAS_mulu2_i321
 
 #if TCG_TARGET_REG_BITS == 64
 #define TCG_TARGET_HAS_div_i64  1
@@ -124,10 +127,6 @@ typedef enum {
 #define TCG_TARGET_HAS_nor_i64  0
 #define TCG_TARGET_HAS_deposit_i64  0
 #define TCG_TARGET_HAS_movcond_i64  1
-
-#define TCG_TARGET_HAS_add2_i32 0
-#define TCG_TARGET_HAS_sub2_i32 0
-#define TCG_TARGET_HAS_mulu2_i320
 #endif
 
 #define TCG_AREG0 TCG_REG_I0
-- 
1.8.1.2




[Qemu-devel] [PATCH v4 03/10] main-loop: switch POSIX glib integration to GPollFD

2013-02-20 Thread Stefan Hajnoczi
Convert glib file descriptor polling from rfds/wfds/xfds to GPollFD.

The Windows code still needs poll_fds[] and n_poll_fds but they can now
become local variables.

Signed-off-by: Stefan Hajnoczi stefa...@redhat.com
---
 main-loop.c | 71 +++--
 1 file changed, 22 insertions(+), 49 deletions(-)

diff --git a/main-loop.c b/main-loop.c
index 489b27c..c2ede99 100644
--- a/main-loop.c
+++ b/main-loop.c
@@ -145,8 +145,6 @@ int qemu_init_main_loop(void)
 
 static fd_set rfds, wfds, xfds;
 static int nfds;
-static GPollFD poll_fds[1024 * 2]; /* this is probably overkill */
-static int n_poll_fds;
 static int max_priority;
 
 /* Load rfds/wfds/xfds into gpollfds.  Will be removed a few commits later. */
@@ -206,65 +204,39 @@ static void gpollfds_to_select(int ret)
 }
 
 #ifndef _WIN32
-static void glib_select_fill(int *max_fd, fd_set *rfds, fd_set *wfds,
- fd_set *xfds, uint32_t *cur_timeout)
+static int glib_pollfds_idx;
+static int glib_n_poll_fds;
+
+static void glib_pollfds_fill(uint32_t *cur_timeout)
 {
 GMainContext *context = g_main_context_default();
-int i;
 int timeout = 0;
+int n;
 
 g_main_context_prepare(context, max_priority);
 
-n_poll_fds = g_main_context_query(context, max_priority, timeout,
-  poll_fds, ARRAY_SIZE(poll_fds));
-g_assert(n_poll_fds = ARRAY_SIZE(poll_fds));
-
-for (i = 0; i  n_poll_fds; i++) {
-GPollFD *p = poll_fds[i];
-
-if ((p-events  G_IO_IN)) {
-FD_SET(p-fd, rfds);
-*max_fd = MAX(*max_fd, p-fd);
-}
-if ((p-events  G_IO_OUT)) {
-FD_SET(p-fd, wfds);
-*max_fd = MAX(*max_fd, p-fd);
-}
-if ((p-events  G_IO_ERR)) {
-FD_SET(p-fd, xfds);
-*max_fd = MAX(*max_fd, p-fd);
-}
-}
+glib_pollfds_idx = gpollfds-len;
+n = glib_n_poll_fds;
+do {
+GPollFD *pfds;
+glib_n_poll_fds = n;
+g_array_set_size(gpollfds, glib_pollfds_idx + glib_n_poll_fds);
+pfds = g_array_index(gpollfds, GPollFD, glib_pollfds_idx);
+n = g_main_context_query(context, max_priority, timeout, pfds,
+ glib_n_poll_fds);
+} while (n != glib_n_poll_fds);
 
 if (timeout = 0  timeout  *cur_timeout) {
 *cur_timeout = timeout;
 }
 }
 
-static void glib_select_poll(fd_set *rfds, fd_set *wfds, fd_set *xfds,
- bool err)
+static void glib_pollfds_poll(void)
 {
 GMainContext *context = g_main_context_default();
+GPollFD *pfds = g_array_index(gpollfds, GPollFD, glib_pollfds_idx);
 
-if (!err) {
-int i;
-
-for (i = 0; i  n_poll_fds; i++) {
-GPollFD *p = poll_fds[i];
-
-if ((p-events  G_IO_IN)  FD_ISSET(p-fd, rfds)) {
-p-revents |= G_IO_IN;
-}
-if ((p-events  G_IO_OUT)  FD_ISSET(p-fd, wfds)) {
-p-revents |= G_IO_OUT;
-}
-if ((p-events  G_IO_ERR)  FD_ISSET(p-fd, xfds)) {
-p-revents |= G_IO_ERR;
-}
-}
-}
-
-if (g_main_context_check(context, max_priority, poll_fds, n_poll_fds)) {
+if (g_main_context_check(context, max_priority, pfds, glib_n_poll_fds)) {
 g_main_context_dispatch(context);
 }
 }
@@ -273,7 +245,7 @@ static int os_host_main_loop_wait(uint32_t timeout)
 {
 int ret;
 
-glib_select_fill(nfds, rfds, wfds, xfds, timeout);
+glib_pollfds_fill(timeout);
 
 if (timeout  0) {
 qemu_mutex_unlock_iothread();
@@ -292,7 +264,7 @@ static int os_host_main_loop_wait(uint32_t timeout)
 qemu_mutex_lock_iothread();
 }
 
-glib_select_poll(rfds, wfds, xfds, (ret  0));
+glib_pollfds_poll();
 return ret;
 }
 #else
@@ -438,8 +410,9 @@ static void pollfds_poll(GArray *pollfds, int nfds, fd_set 
*rfds,
 static int os_host_main_loop_wait(uint32_t timeout)
 {
 GMainContext *context = g_main_context_default();
+GPollFD poll_fds[1024 * 2]; /* this is probably overkill */
 int select_ret = 0;
-int g_poll_ret, ret, i;
+int g_poll_ret, ret, i, n_poll_fds;
 PollingEntry *pe;
 WaitObjects *w = wait_objects;
 gint poll_timeout;
-- 
1.8.1.2




[Qemu-devel] [PATCH] tcg: Document tcg_qemu_tb_exec() and provide constants for low bit uses

2013-02-20 Thread Peter Maydell
Document tcg_qemu_tb_exec(). In particular, its return value is a
combination of a pointer to the next translation block and some
extra information in the low two bits. Provide some #defines for
the values passed in these bits to improve code clarity.

Signed-off-by: Peter Maydell peter.mayd...@linaro.org
---
I have a patch cooking which uses the final remaining bottom-two-bits
combo to indicate exited TB due to pending interrupt so I thought it
would be nice to document what was going on here and get rid of some
of the magic numbers in the code.

 cpu-exec.c|9 +
 include/exec/gen-icount.h |2 +-
 tcg/tcg.h |   36 +++-
 3 files changed, 41 insertions(+), 6 deletions(-)

diff --git a/cpu-exec.c b/cpu-exec.c
index 9fcfe9e0..ea63e7d 100644
--- a/cpu-exec.c
+++ b/cpu-exec.c
@@ -72,7 +72,7 @@ static void cpu_exec_nocache(CPUArchState *env, int 
max_cycles,
 next_tb = tcg_qemu_tb_exec(env, tb-tc_ptr);
 cpu-current_tb = NULL;
 
-if ((next_tb  3) == 2) {
+if ((next_tb  TB_EXIT_MASK) == TB_EXIT_ICOUNT_EXPIRED) {
 /* Restore PC.  This may happen if async event occurs before
the TB starts executing.  */
 cpu_pc_from_tb(env, tb);
@@ -584,7 +584,8 @@ int cpu_exec(CPUArchState *env)
spans two pages, we cannot safely do a direct
jump. */
 if (next_tb != 0  tb-page_addr[1] == -1) {
-tb_add_jump((TranslationBlock *)(next_tb  ~3), next_tb  
3, tb);
+tb_add_jump((TranslationBlock *)(next_tb  ~TB_EXIT_MASK),
+next_tb  TB_EXIT_MASK, tb);
 }
 spin_unlock(tcg_ctx.tb_ctx.tb_lock);
 
@@ -598,10 +599,10 @@ int cpu_exec(CPUArchState *env)
 tc_ptr = tb-tc_ptr;
 /* execute the generated code */
 next_tb = tcg_qemu_tb_exec(env, tc_ptr);
-if ((next_tb  3) == 2) {
+if ((next_tb  TB_EXIT_MASK) == TB_EXIT_ICOUNT_EXPIRED) {
 /* Instruction counter expired.  */
 int insns_left;
-tb = (TranslationBlock *)(next_tb  ~3);
+tb = (TranslationBlock *)(next_tb  ~TB_EXIT_MASK);
 /* Restore PC.  */
 cpu_pc_from_tb(env, tb);
 insns_left = env-icount_decr.u32;
diff --git a/include/exec/gen-icount.h b/include/exec/gen-icount.h
index 8043b3b..c858a73 100644
--- a/include/exec/gen-icount.h
+++ b/include/exec/gen-icount.h
@@ -32,7 +32,7 @@ static void gen_icount_end(TranslationBlock *tb, int 
num_insns)
 if (use_icount) {
 *icount_arg = num_insns;
 gen_set_label(icount_label);
-tcg_gen_exit_tb((tcg_target_long)tb + 2);
+tcg_gen_exit_tb((tcg_target_long)tb + TB_EXIT_ICOUNT_EXPIRED);
 }
 }
 
diff --git a/tcg/tcg.h b/tcg/tcg.h
index 51c8176..7cf4c15 100644
--- a/tcg/tcg.h
+++ b/tcg/tcg.h
@@ -669,7 +669,41 @@ TCGv_i64 tcg_const_i64(int64_t val);
 TCGv_i32 tcg_const_local_i32(int32_t val);
 TCGv_i64 tcg_const_local_i64(int64_t val);
 
-/* TCG targets may use a different definition of tcg_qemu_tb_exec. */
+/**
+ * tcg_qemu_tb_exec:
+ * @env: CPUArchState * for the CPU
+ * @tb_ptr: address of generated code for the TB to execute
+ *
+ * Start executing code from a given translation block.
+ * Where translation blocks have been linked, execution
+ * may proceed from the given TB into successive ones.
+ * Control eventually returns only when some action is needed
+ * from the top-level loop: either control must pass to a TB
+ * which has not yet been directly linked, or an asynchronous
+ * event such as an interrupt needs handling.
+ *
+ * The return value is a pointer to the next TB to execute
+ * (if known; otherwise zero). This pointer is assumed to be
+ * 4-aligned, and the bottom two bits are used to return further
+ * information:
+ *  0, 1: the link between this TB and the next is via the specified
+ *TB index (0 or 1). That is, we left the TB via (the equivalent
+ *of) goto_tb index. The main loop uses this to determine
+ *how to link the TB just executed to the next.
+ *  2:we are using instruction counting code generation, and we
+ *stopped executing this TB because the instruction counter
+ *hit zero. In this case the next-TB pointer returned is the
+ *TB we were partway through.
+ *
+ * Note that TCG targets may use a different definition of tcg_qemu_tb_exec
+ * to this default (which just calls the prologue code emitted by
+ * tcg_target_qemu_prologue()).
+ */
+#define TB_EXIT_MASK 3
+#define TB_EXIT_IDX0 0
+#define TB_EXIT_IDX1 1
+#define TB_EXIT_ICOUNT_EXPIRED 2
+
 #if !defined(tcg_qemu_tb_exec)
 # define tcg_qemu_tb_exec(env, tb_ptr) \
 ((tcg_target_ulong (*)(void *, void *))tcg_ctx.code_gen_prologue)(env, \
-- 

Re: [Qemu-devel] [RFC PATCH] Distinguish between reset types

2013-02-20 Thread Peter Crosthwaite
Hi Peter,

On Wed, Feb 20, 2013 at 8:50 AM, Peter Maydell peter.mayd...@linaro.org wrote:
 On 19 February 2013 22:17, Anthony Liguori anth...@codemonkey.ws wrote:
 David Woodhouse dw...@infradead.org writes:
 On Tue, 2013-02-19 at 14:29 -0600, Anthony Liguori wrote:
 So should we even be resetting anything other than the CPU during soft
 reset?

 I suspect not. A soft reset triggered by the RCR, keyboard controller,
 port 92 etc. should all just reset the CPU and nothing else.

 I suspect what we need to do is convert qemu_system_reset_request() into
 a qemu_system_cpu_reset() that takes a callback.  Once the VCPUs have
 been reset, the callback can then be used to reset all or some of the
 device model.

 If we're just solving a PC problem here and it really is just
 only reset the CPU, nothing else, why don't we give the
 x86 CPU a qemu_irq input for reset this CPU core and wire it
 up to the relevant bit of hardware on the PC board? I don't
 see the need for a specific 'qemu_system_cpu_reset()' here
 (and not having one avoids the swamp of trying to define its
 semantics...)


Could we be more general and implement this on the TYPE_DEVICE level
(rather than X86_CPU)? I want this GPIO-as-reset feature for all Zynq
devices cpus and preihperals alike. The Zynq power controller has
software controllable individual reset for every device in the system
and my plan-A was to do it as GPIOs. To implement the reset gpio-ins
however I was thinking do it in one swift stroke by adding the single
GPIO on the TYPE_DEVICE layer that backs onto DeviceClass-.reset.
With recent QOM efforts (making CPUs DEVICEs) this catchall will also
implment the feature for all CPUs. Power controllers define gpio_outs
and then machine model just play connect the dots.

RFC! I was planning at some stage to formally RFC this but yet to get
around to it. I bring it up because the topic is hot here.

 How far down this road do we go? Do we end up wiring up the full reset
 topology and abandoning the special-case qemu_system_reset()
 altogether?

 Long term, yes.  Short term, whatever we need that's reasonable to get
 the CSM happy without making things worse.

 I definitely think we should be modelling reset lines, yes.
 It would be nice if we could sketch a path for how we get from
 here to there. Here's a strawman proposal that's probably full
 of holes:

 (1) we retain the existing 'reset' Device method as meaning full
 power-cycle style reset and qemu_system_reset_request() as
 meaning power cycle entire machine. (Eventually the latter
 might go away as I doubt much real hardware has a power
 cycle the world wiring.)

 (2) we recommend that for new devices etc, where the device has
 one or more physical reset pins those should be modeled as
 qdev_gpio input lines, with the behaviour the hardware has
 when those are asserted. [Q: what do we do about logic-low-is-assert
 vs logic-high-is-assert hardware?] This reset can obviously share
 code with the DeviceState::reset in many cases, but it's
 conceptually separate.

 (3) when we need to implement a particular effect on a particular
 board (as here with the PC) we do that by:
  a. making sure all affected devices implement reset
  b. wiring up reset on the board model
  c. having the implementation of the 'reset' register or whatever
 assert the irq line

 (4) as and when we have time, convert existing code (ho ho)

The TYPE_DEVICE level implementation would give a reset pin to every
device that implements DeviceClass-reset which should minimise the
pain here. The hard part is devices that dont implement reset at all
which are a lost cause WRT this discussion.

 This obviously works best when the not actually a full power
 cycle reset you want in (3) is a very limited focus one,
 like just reset the CPU...

 It also exposes some not there yet features like the fact
 we can't have named gpio input lines so you have to have a
 numbering convention for smooshing all your inputs into a
 single array. Pins, anybody? :-)


Yes my idea requires this so would have to bite the bullet and get
this one through.

Regards,
Peter

 -- PMM




Re: [Qemu-devel] [RFC PATCH] Distinguish between reset types

2013-02-20 Thread Peter Maydell
On 20 February 2013 12:21, Peter Crosthwaite
peter.crosthwa...@xilinx.com wrote:
 On Wed, Feb 20, 2013 at 8:50 AM, Peter Maydell peter.mayd...@linaro.org 
 wrote:
 If we're just solving a PC problem here and it really is just
 only reset the CPU, nothing else, why don't we give the
 x86 CPU a qemu_irq input for reset this CPU core and wire it
 up to the relevant bit of hardware on the PC board? I don't
 see the need for a specific 'qemu_system_cpu_reset()' here
 (and not having one avoids the swamp of trying to define its
 semantics...)

 Could we be more general and implement this on the TYPE_DEVICE level
 (rather than X86_CPU)? I want this GPIO-as-reset feature for all Zynq
 devices cpus and preihperals alike. The Zynq power controller has
 software controllable individual reset for every device in the system
 and my plan-A was to do it as GPIOs. To implement the reset gpio-ins
 however I was thinking do it in one swift stroke by adding the single
 GPIO on the TYPE_DEVICE layer that backs onto DeviceClass-.reset.

The trouble is that:
 * some devices have no reset GPIO line
 * some devices have more than one (eg a Cortex-A9MPx4 has 18 different
   reset input lines)
 * the reset line doesn't always match up with the DeviceClass::reset
   semantics

I guess maybe if there was a way to say 'this device suppresses
the default reset input implementation'.

(Plus as you note we'd have to actually support named GPIO inputs
to have the base class provide an input pin that didn't get
tangled up with the device's own inputs.)

-- PMM



Re: [Qemu-devel] [PATCH v1 1/6] i2c: support address ranges

2013-02-20 Thread Peter Crosthwaite
On Wed, Feb 20, 2013 at 5:27 PM, Paolo Bonzini pbonz...@redhat.com wrote:
 Il 20/02/2013 06:29, Peter Crosthwaite ha scritto:
 @@ -192,12 +197,13 @@ static int i2c_slave_post_load(void *opaque, int 
 version_id)

  const VMStateDescription vmstate_i2c_slave = {
  .name = I2CSlave,
 -.version_id = 1,
 -.minimum_version_id = 1,
 -.minimum_version_id_old = 1,
 +.version_id = 2,
 +.minimum_version_id = 2,
 +.minimum_version_id_old = 2,
  .post_load = i2c_slave_post_load,
  .fields  = (VMStateField []) {
  VMSTATE_UINT8(address, I2CSlave),
 +VMSTATE_UINT8(address_range, I2CSlave),
  VMSTATE_END_OF_LIST()

 Properties do not need to be serialized.


Ok,

I do wonder why the address itselt in VMSDs however and my best guess
is the intention is that devices can modify their address at runtime
(phyiscally very possible and valid with I2C). So what happens if a
device changes the value of one of its props at runtime? E.G. in this
case what happens if my device decides to change its I2CSlave-address
in response to some arbitrary event? Will that play foul with VMSD or
can i just save the prop in my VMSD with the rest of my device state
to implement restoration of the modified prop?

Regards,
Peter

 Paolo




[Qemu-devel] [PATCH v4 04/10] slirp: slirp/slirp.c coding style cleanup

2013-02-20 Thread Stefan Hajnoczi
The slirp glue code uses tabs in some places.  Since the next patch will
modify the file, convert tabs to spaces and fix checkpatch.pl issues.

Signed-off-by: Stefan Hajnoczi stefa...@redhat.com
---
 slirp/slirp.c | 608 ++
 1 file changed, 311 insertions(+), 297 deletions(-)

diff --git a/slirp/slirp.c b/slirp/slirp.c
index 0e6e232..5d14e7f 100644
--- a/slirp/slirp.c
+++ b/slirp/slirp.c
@@ -287,135 +287,139 @@ void slirp_select_fill(int *pnfds,
 global_xfds = NULL;
 
 nfds = *pnfds;
-   /*
-* First, TCP sockets
-*/
-   do_slowtimo = 0;
-
-   QTAILQ_FOREACH(slirp, slirp_instances, entry) {
-   /*
-* *_slowtimo needs calling if there are IP fragments
-* in the fragment queue, or there are TCP connections active
-*/
-   do_slowtimo |= ((slirp-tcb.so_next != slirp-tcb) ||
-   (slirp-ipq.ip_link != slirp-ipq.ip_link.next));
-
-   for (so = slirp-tcb.so_next; so != slirp-tcb;
-so = so_next) {
-   so_next = so-so_next;
-
-   /*
-* See if we need a tcp_fasttimo
-*/
-   if (time_fasttimo == 0  so-so_tcpcb-t_flags  
TF_DELACK)
-  time_fasttimo = curtime; /* Flag when we want a 
fasttimo */
-
-   /*
-* NOFDREF can include still connecting to local-host,
-* newly socreated() sockets etc. Don't want to select 
these.
-*/
-   if (so-so_state  SS_NOFDREF || so-s == -1)
-  continue;
-
-   /*
-* Set for reading sockets which are accepting
-*/
-   if (so-so_state  SS_FACCEPTCONN) {
-FD_SET(so-s, readfds);
-   UPD_NFDS(so-s);
-   continue;
-   }
-
-   /*
-* Set for writing sockets which are connecting
-*/
-   if (so-so_state  SS_ISFCONNECTING) {
-   FD_SET(so-s, writefds);
-   UPD_NFDS(so-s);
-   continue;
-   }
-
-   /*
-* Set for writing if we are connected, can send more, 
and
-* we have something to send
-*/
-   if (CONN_CANFSEND(so)  so-so_rcv.sb_cc) {
-   FD_SET(so-s, writefds);
-   UPD_NFDS(so-s);
-   }
-
-   /*
-* Set for reading (and urgent data) if we are 
connected, can
-* receive more, and we have room for it XXX /2 ?
-*/
-   if (CONN_CANFRCV(so)  (so-so_snd.sb_cc  
(so-so_snd.sb_datalen/2))) {
-   FD_SET(so-s, readfds);
-   FD_SET(so-s, xfds);
-   UPD_NFDS(so-s);
-   }
-   }
-
-   /*
-* UDP sockets
-*/
-   for (so = slirp-udb.so_next; so != slirp-udb;
-so = so_next) {
-   so_next = so-so_next;
-
-   /*
-* See if it's timed out
-*/
-   if (so-so_expire) {
-   if (so-so_expire = curtime) {
-   udp_detach(so);
-   continue;
-   } else
-   do_slowtimo = 1; /* Let socket expire */
-   }
-
-   /*
-* When UDP packets are received from over the
-* link, they're sendto()'d straight away, so
-* no need for setting for writing
-* Limit the number of packets queued by this session
-* to 4.  Note that even though we try and limit this
-* to 4 packets, the session could have more queued
-* if the packets needed to be fragmented
-* (XXX = 4 ?)
-*/
-   if ((so-so_state  SS_ISFCONNECTED)  so-so_queued 
= 4) {
-   FD_SET(so-s, readfds);
-   UPD_NFDS(so-s);
-   }
-   }
+/*
+ * First, TCP sockets
+ */
+do_slowtimo = 0;
 
-/*
- 

Re: [Qemu-devel] [RFC PATCH] Distinguish between reset types

2013-02-20 Thread Peter Crosthwaite
On Wed, Feb 20, 2013 at 10:29 PM, Peter Maydell
peter.mayd...@linaro.org wrote:
 On 20 February 2013 12:21, Peter Crosthwaite
 peter.crosthwa...@xilinx.com wrote:
 On Wed, Feb 20, 2013 at 8:50 AM, Peter Maydell peter.mayd...@linaro.org 
 wrote:
 If we're just solving a PC problem here and it really is just
 only reset the CPU, nothing else, why don't we give the
 x86 CPU a qemu_irq input for reset this CPU core and wire it
 up to the relevant bit of hardware on the PC board? I don't
 see the need for a specific 'qemu_system_cpu_reset()' here
 (and not having one avoids the swamp of trying to define its
 semantics...)

 Could we be more general and implement this on the TYPE_DEVICE level
 (rather than X86_CPU)? I want this GPIO-as-reset feature for all Zynq
 devices cpus and preihperals alike. The Zynq power controller has
 software controllable individual reset for every device in the system
 and my plan-A was to do it as GPIOs. To implement the reset gpio-ins
 however I was thinking do it in one swift stroke by adding the single
 GPIO on the TYPE_DEVICE layer that backs onto DeviceClass-.reset.

 The trouble is that:
  * some devices have no reset GPIO line

Is there any harm in just not connecting the default reset GPIO? Or if
you are pedantic allow the class definition to opt-out and inhibit
generation of the GPIO.

  * some devices have more than one (eg a Cortex-A9MPx4 has 18 different
reset input lines)

Yeh you are lost in this case. But my intended semantics for the
TYPE_DEVICE reset GPIO is it is a power on reset (PoR) with equivalent
function to DeviceClass-reset

  * the reset line doesn't always match up with the DeviceClass::reset
semantics


Then its not a PoR equivalent (and thus from QEMUs perspective not a
reset at all). Its a device specific GPIO. The same applies to 18
lines of A9MPx4, althought that is a container object so im guessing
some of those 18 resets will pass through as PoR equivalents to the
subdevices?

So working on that case, suppose GIC (a subcomponent of Cortex-A9MPx4)
has a PoR equivalent wired directly as one of the 18 resets. The
container will have to explicitly define all 18 resets, however, it
can pass GICs through to the TYPE_DEVICE reset for the GIC instance,
saving on having to hack up GIC to explicitly have a reset GPIO.

It just strikes me as a workable solution for the 90% case then we can
go you full custom GPIO solution for the harder ones.

Regards,
Peter


 I guess maybe if there was a way to say 'this device suppresses
 the default reset input implementation'.

 (Plus as you note we'd have to actually support named GPIO inputs
 to have the base class provide an input pin that didn't get
 tangled up with the device's own inputs.)

 -- PMM




[Qemu-devel] [PATCH 02/38] tcg-i386: Always implement 32-bit multiword ops

2013-02-20 Thread Richard Henderson
Signed-off-by: Richard Henderson r...@twiddle.net
---
 tcg/i386/tcg-target.c | 18 ++
 tcg/i386/tcg-target.h |  7 +++
 2 files changed, 13 insertions(+), 12 deletions(-)

diff --git a/tcg/i386/tcg-target.c b/tcg/i386/tcg-target.c
index 7aec304..f645529 100644
--- a/tcg/i386/tcg-target.c
+++ b/tcg/i386/tcg-target.c
@@ -1922,13 +1922,6 @@ static inline void tcg_out_op(TCGContext *s, TCGOpcode 
opc,
 tcg_out_qemu_st(s, args, 3);
 break;
 
-#if TCG_TARGET_REG_BITS == 32
-case INDEX_op_brcond2_i32:
-tcg_out_brcond2(s, args, const_args, 0);
-break;
-case INDEX_op_setcond2_i32:
-tcg_out_setcond2(s, args, const_args);
-break;
 case INDEX_op_mulu2_i32:
 tcg_out_modrm(s, OPC_GRP3_Ev, EXT3_MUL, args[3]);
 break;
@@ -1956,6 +1949,14 @@ static inline void tcg_out_op(TCGContext *s, TCGOpcode 
opc,
 tgen_arithr(s, ARITH_SBB, args[1], args[5]);
 }
 break;
+
+#if TCG_TARGET_REG_BITS == 32
+case INDEX_op_brcond2_i32:
+tcg_out_brcond2(s, args, const_args, 0);
+break;
+case INDEX_op_setcond2_i32:
+tcg_out_setcond2(s, args, const_args);
+break;
 #else /* TCG_TARGET_REG_BITS == 64 */
 case INDEX_op_movi_i64:
 tcg_out_movi(s, TCG_TYPE_I64, args[0], args[1]);
@@ -2078,10 +2079,11 @@ static const TCGTargetOpDef x86_op_defs[] = {
 { INDEX_op_movcond_i32, { r, r, ri, r, 0 } },
 #endif
 
-#if TCG_TARGET_REG_BITS == 32
 { INDEX_op_mulu2_i32, { a, d, a, r } },
 { INDEX_op_add2_i32, { r, r, 0, 1, ri, ri } },
 { INDEX_op_sub2_i32, { r, r, 0, 1, ri, ri } },
+
+#if TCG_TARGET_REG_BITS == 32
 { INDEX_op_brcond2_i32, { r, r, ri, ri } },
 { INDEX_op_setcond2_i32, { r, r, r, ri, ri } },
 #else
diff --git a/tcg/i386/tcg-target.h b/tcg/i386/tcg-target.h
index 43ad2c4..487dc23 100644
--- a/tcg/i386/tcg-target.h
+++ b/tcg/i386/tcg-target.h
@@ -92,6 +92,9 @@ typedef enum {
 #define TCG_TARGET_HAS_nor_i32  0
 #define TCG_TARGET_HAS_deposit_i32  1
 #define TCG_TARGET_HAS_movcond_i32  1
+#define TCG_TARGET_HAS_add2_i32 1
+#define TCG_TARGET_HAS_sub2_i32 1
+#define TCG_TARGET_HAS_mulu2_i321
 
 #if TCG_TARGET_REG_BITS == 64
 #define TCG_TARGET_HAS_div2_i64 1
@@ -114,10 +117,6 @@ typedef enum {
 #define TCG_TARGET_HAS_nor_i64  0
 #define TCG_TARGET_HAS_deposit_i64  1
 #define TCG_TARGET_HAS_movcond_i64  1
-
-#define TCG_TARGET_HAS_add2_i32 0
-#define TCG_TARGET_HAS_sub2_i32 0
-#define TCG_TARGET_HAS_mulu2_i320
 #endif
 
 #define TCG_TARGET_deposit_i32_valid(ofs, len) \
-- 
1.8.1.2




[Qemu-devel] qemu 1.4 : ubuntu 12.10 : ehci + companion + usb-tablet - vmmouse not loaded + usb-tablet not working

2013-02-20 Thread Alexandre DERUMIER
Hi List,

I'm testing qemu 1.4, without ubuntu desktop 12.10 with graphical installer

I found 2 bugs:

1) vmmouse is not loaded  if an usb-tablet is plugged on an ehci controller 
with companion
-

4 cases with mixed options:


a)ehci +companion +tablet:  vmmouse is not loaded

qemu command line : -readconfig /usr/share/qemu-server/pve-usb-companion.cfg 
-device usb-tablet,id=tablet,bus=ehci.0,port=6

# info mice
  Mouse #0: QEMU PS/2 Mouse
* Mouse #1: QEMU HID Tablet (absolute)


b)ehci +companion -tablet: vmmouse is loaded

qemu command line :  -readconfig /usr/share/qemu-server/pve-usb-companion.cfg

# info mice
  Mouse #0: QEMU PS/2 Mouse
* Mouse #1: vmmouse (absolute)


c)ehci -companion + tablet : vmmouse is loaded

qemu command line :  -readconfig /usr/share/qemu-server/pve-usb-nocompanion.cfg 
-device usb-tablet,id=tablet,bus=ehci.0,port=6

# info mice
  Mouse #1: QEMU HID Tablet (absolute)
  Mouse #0: QEMU PS/2 Mouse
* Mouse #2: vmmouse (absolute)



d)ehci -companion -tablet : vmmouse is loaded

qemu command line :  -readconfig /usr/share/qemu-server/pve-usb-nocompanion.cfg

# info mice
  Mouse #0: QEMU PS/2 Mouse
* Mouse #1: vmmouse (absolute)


pve-usb-companion.cfg:

[device ehci]
  driver = ich9-usb-ehci1
  addr = 1d.7
  multifunction = on

[device uhci-1]
  driver = ich9-usb-uhci1
  addr = 1d.0
  multifunction = on
  masterbus = ehci.0
  firstport = 0

[device uhci-2]
  driver = ich9-usb-uhci2
  addr = 1d.1
  multifunction = on
  masterbus = ehci.0
  firstport = 2

[device uhci-3]
  driver = ich9-usb-uhci3
  addr = 1d.2
  multifunction = on
  masterbus = ehci.0
  firstport = 4



pve-usb-nocompanion.cfg:

[device ehci]
  driver = ich9-usb-ehci1
  addr = 1d.7
  multifunction = off


2) -usb-tablet don't work on ehci with ubuntu
--
- don't work (mouse not moving) with or without companion
- device is correctly displayed with #lsusb,so maybe it's an xorg driver 
problem.
- It's working fine on windows guest. 




Both bugs result to don't have a working mouse in ubuntu installer.
(vmmouse is not available, and usb-tablet is selected but it's not working).




Any idea ? 

Regards,

Alexandre Derumier




[Qemu-devel] [PATCH 21/38] target-arm: Implement sbc_cc inline

2013-02-20 Thread Richard Henderson
Use sub2 if available, otherwise use 64-bit arithmetic.

Cc: Peter Maydell peter.mayd...@linaro.org
Signed-off-by: Richard Henderson r...@twiddle.net
---
 target-arm/helper.h|  2 --
 target-arm/op_helper.c | 15 ---
 target-arm/translate.c | 47 +++
 3 files changed, 39 insertions(+), 25 deletions(-)

diff --git a/target-arm/helper.h b/target-arm/helper.h
index 507bb9c..63ae13a 100644
--- a/target-arm/helper.h
+++ b/target-arm/helper.h
@@ -140,8 +140,6 @@ DEF_HELPER_2(recpe_u32, i32, i32, env)
 DEF_HELPER_2(rsqrte_u32, i32, i32, env)
 DEF_HELPER_5(neon_tbl, i32, env, i32, i32, i32, i32)
 
-DEF_HELPER_3(sbc_cc, i32, env, i32, i32)
-
 DEF_HELPER_3(shl_cc, i32, env, i32, i32)
 DEF_HELPER_3(shr_cc, i32, env, i32, i32)
 DEF_HELPER_3(sar_cc, i32, env, i32, i32)
diff --git a/target-arm/op_helper.c b/target-arm/op_helper.c
index 49fc036..a522313 100644
--- a/target-arm/op_helper.c
+++ b/target-arm/op_helper.c
@@ -315,21 +315,6 @@ uint64_t HELPER(get_cp_reg64)(CPUARMState *env, void *rip)
The only way to do that in TCG is a conditional branch, which clobbers
all our temporaries.  For now implement these as helper functions.  */
 
-uint32_t HELPER(sbc_cc)(CPUARMState *env, uint32_t a, uint32_t b)
-{
-uint32_t result;
-if (!env-CF) {
-result = a - b - 1;
-env-CF = a  b;
-} else {
-result = a - b;
-env-CF = a = b;
-}
-env-VF = (a ^ b)  (a ^ result);
-env-NF = env-ZF = result;
-return result;
-}
-
 /* Similarly for variable shift instructions.  */
 
 uint32_t HELPER(shl_cc)(CPUARMState *env, uint32_t x, uint32_t i)
diff --git a/target-arm/translate.c b/target-arm/translate.c
index 493448a..9993aea 100644
--- a/target-arm/translate.c
+++ b/target-arm/translate.c
@@ -464,6 +464,35 @@ static void gen_sub_CC(TCGv dest, TCGv t0, TCGv t1)
 tcg_gen_mov_i32(dest, cpu_NF);
 }
 
+/* dest = T0 + ~T1 + CF = T0 - T1 + CF - 1.  Compute C, N, V and Z flags */
+static void gen_sbc_CC(TCGv dest, TCGv t0, TCGv t1)
+{
+TCGv tmp = tcg_temp_new_i32();
+tcg_gen_subi_i32(cpu_CF, cpu_CF, 1);
+if (TCG_TARGET_HAS_add2_i32) {
+tcg_gen_movi_i32(tmp, 0);
+tcg_gen_add2_i32(cpu_NF, cpu_CF, t0, tmp, cpu_CF, tmp);
+tcg_gen_sub2_i32(cpu_NF, cpu_CF, t0, cpu_CF, t1, tmp);
+} else {
+TCGv_i64 q0 = tcg_temp_new_i64();
+TCGv_i64 q1 = tcg_temp_new_i64();
+tcg_gen_extu_i32_i64(q0, t0);
+tcg_gen_extu_i32_i64(q1, t1);
+tcg_gen_sub_i64(q0, q0, q1);
+tcg_gen_extu_i32_i64(q1, cpu_CF);
+tcg_gen_add_i64(q0, q0, q1);
+tcg_gen_extr_i64_i32(cpu_NF, cpu_CF, q0);
+tcg_temp_free_i64(q0);
+tcg_temp_free_i64(q1);
+}
+tcg_gen_mov_i32(cpu_ZF, cpu_NF);
+tcg_gen_xor_i32(cpu_VF, cpu_NF, t0);
+tcg_gen_xor_i32(tmp, t0, t1);
+tcg_gen_and_i32(cpu_VF, cpu_VF, tmp);
+tcg_temp_free_i32(tmp);
+tcg_gen_mov_i32(dest, cpu_NF);
+}
+
 #define GEN_SHIFT(name)   \
 static void gen_##name(TCGv dest, TCGv t0, TCGv t1)   \
 { \
@@ -7109,7 +7138,7 @@ static void disas_arm_insn(CPUARMState * env, 
DisasContext *s)
 break;
 case 0x06:
 if (set_cc) {
-gen_helper_sbc_cc(tmp, cpu_env, tmp, tmp2);
+gen_sbc_CC(tmp, tmp, tmp2);
 } else {
 gen_sub_carry(tmp, tmp, tmp2);
 }
@@ -7117,7 +7146,7 @@ static void disas_arm_insn(CPUARMState * env, 
DisasContext *s)
 break;
 case 0x07:
 if (set_cc) {
-gen_helper_sbc_cc(tmp, cpu_env, tmp2, tmp);
+gen_sbc_CC(tmp, tmp2, tmp);
 } else {
 gen_sub_carry(tmp, tmp2, tmp);
 }
@@ -7947,10 +7976,11 @@ gen_thumb2_data_op(DisasContext *s, int op, int conds, 
uint32_t shifter_out, TCG
 gen_adc(t0, t1);
 break;
 case 11: /* sbc */
-if (conds)
-gen_helper_sbc_cc(t0, cpu_env, t0, t1);
-else
+if (conds) {
+gen_sbc_CC(t0, t0, t1);
+} else {
 gen_sub_carry(t0, t0, t1);
+}
 break;
 case 13: /* sub */
 if (conds)
@@ -9267,10 +9297,11 @@ static void disas_thumb_insn(CPUARMState *env, 
DisasContext *s)
 }
 break;
 case 0x6: /* sbc */
-if (s-condexec_mask)
+if (s-condexec_mask) {
 gen_sub_carry(tmp, tmp, tmp2);
-else
-gen_helper_sbc_cc(tmp, cpu_env, tmp, tmp2);
+} else {
+gen_sbc_CC(tmp, tmp, tmp2);
+}
 break;
 case 0x7: /* ror */
 if (s-condexec_mask) {
-- 
1.8.1.2




[Qemu-devel] [PATCH 34/38] target-sparc: Use mul*2 for multiply

2013-02-20 Thread Richard Henderson
Cc: Blue Swirl blauwir...@gmail.com
Signed-off-by: Richard Henderson r...@twiddle.net
---
 target-sparc/translate.c | 45 ++---
 1 file changed, 18 insertions(+), 27 deletions(-)

diff --git a/target-sparc/translate.c b/target-sparc/translate.c
index d3e2acf..f99b82a 100644
--- a/target-sparc/translate.c
+++ b/target-sparc/translate.c
@@ -642,39 +642,30 @@ static inline void gen_op_mulscc(TCGv dst, TCGv src1, 
TCGv src2)
 
 static inline void gen_op_multiply(TCGv dst, TCGv src1, TCGv src2, int 
sign_ext)
 {
-TCGv_i32 r_src1, r_src2;
-TCGv_i64 r_temp, r_temp2;
-
-r_src1 = tcg_temp_new_i32();
-r_src2 = tcg_temp_new_i32();
-
-tcg_gen_trunc_tl_i32(r_src1, src1);
-tcg_gen_trunc_tl_i32(r_src2, src2);
-
-r_temp = tcg_temp_new_i64();
-r_temp2 = tcg_temp_new_i64();
-
+#if TARGET_LONG_BITS == 32
 if (sign_ext) {
-tcg_gen_ext_i32_i64(r_temp, r_src2);
-tcg_gen_ext_i32_i64(r_temp2, r_src1);
+tcg_gen_muls2_tl(dst, cpu_y, src1, src2);
 } else {
-tcg_gen_extu_i32_i64(r_temp, r_src2);
-tcg_gen_extu_i32_i64(r_temp2, r_src1);
+tcg_gen_mulu2_tl(dst, cpu_y, src1, src2);
 }
+#else
+TCGv t0 = tcg_temp_new_i64();
+TCGv t1 = tcg_temp_new_i64();
 
-tcg_gen_mul_i64(r_temp2, r_temp, r_temp2);
-
-tcg_gen_shri_i64(r_temp, r_temp2, 32);
-tcg_gen_trunc_i64_tl(cpu_y, r_temp);
-tcg_temp_free_i64(r_temp);
-tcg_gen_andi_tl(cpu_y, cpu_y, 0x);
-
-tcg_gen_trunc_i64_tl(dst, r_temp2);
+if (sign_ext) {
+tcg_gen_ext32s_i64(t0, src1);
+tcg_gen_ext32s_i64(t1, src2);
+} else {
+tcg_gen_ext32u_i64(t0, src1);
+tcg_gen_ext32u_i64(t1, src2);
+}
 
-tcg_temp_free_i64(r_temp2);
+tcg_gen_mul_i64(dst, t0, t1);
+tcg_temp_free(t0);
+tcg_temp_free(t1);
 
-tcg_temp_free_i32(r_src1);
-tcg_temp_free_i32(r_src2);
+tcg_gen_shri_i64(cpu_y, dst, 32);
+#endif
 }
 
 static inline void gen_op_umul(TCGv dst, TCGv src1, TCGv src2)
-- 
1.8.1.2




[Qemu-devel] [PATCH 07/38] tcg: Implement multiword multiply helpers

2013-02-20 Thread Richard Henderson
Signed-off-by: Richard Henderson r...@twiddle.net
---
 tcg-runtime.c | 16 ++-
 tcg/tcg-op.h  | 84 +++
 tcg/tcg-runtime.h |  2 ++
 3 files changed, 101 insertions(+), 1 deletion(-)

diff --git a/tcg-runtime.c b/tcg-runtime.c
index abfc364..4b66e51 100644
--- a/tcg-runtime.c
+++ b/tcg-runtime.c
@@ -22,7 +22,7 @@
  * THE SOFTWARE.
  */
 #include stdint.h
-
+#include qemu/host-utils.h
 #include tcg/tcg-runtime.h
 
 /* 32-bit helpers */
@@ -83,3 +83,17 @@ uint64_t tcg_helper_remu_i64(uint64_t arg1, uint64_t arg2)
 {
 return arg1 % arg2;
 }
+
+uint64_t tcg_helper_muluh_i64(uint64_t arg1, uint64_t arg2)
+{
+uint64_t l, h;
+mulu64(l, h, arg1, arg2);
+return h;
+}
+
+int64_t tcg_helper_mulsh_i64(int64_t arg1, int64_t arg2)
+{
+uint64_t l, h;
+muls64(l, h, arg1, arg2);
+return h;
+}
diff --git a/tcg/tcg-op.h b/tcg/tcg-op.h
index 4ded249..97e0795 100644
--- a/tcg/tcg-op.h
+++ b/tcg/tcg-op.h
@@ -2332,6 +2332,86 @@ static inline void tcg_gen_movcond_i64(TCGCond cond, 
TCGv_i64 ret,
 #endif
 }
 
+static inline void tcg_gen_mulu2_i32(TCGv_i32 rl, TCGv_i32 rh,
+ TCGv_i32 arg1, TCGv_i32 arg2)
+{
+if (TCG_TARGET_HAS_mulu2_i32) {
+tcg_gen_op4_i32(INDEX_op_mulu2_i32, rl, rh, arg1, arg2);
+/* Allow the optimizer room to replace mulu2 with two moves.  */
+tcg_gen_op0(INDEX_op_nop);
+} else {
+TCGv_i64 t0 = tcg_temp_new_i64();
+TCGv_i64 t1 = tcg_temp_new_i64();
+tcg_gen_extu_i32_i64(t0, arg1);
+tcg_gen_extu_i32_i64(t1, arg2);
+tcg_gen_mul_i64(t0, t0, t1);
+tcg_gen_extr_i64_i32(rl, rh, t0);
+tcg_temp_free_i64(t0);
+tcg_temp_free_i64(t1);
+}
+}
+
+static inline void tcg_gen_muls2_i32(TCGv_i32 rl, TCGv_i32 rh,
+ TCGv_i32 arg1, TCGv_i32 arg2)
+{
+if (TCG_TARGET_HAS_muls2_i32) {
+tcg_gen_op4_i32(INDEX_op_muls2_i32, rl, rh, arg1, arg2);
+/* Allow the optimizer room to replace muls2 with two moves.  */
+tcg_gen_op0(INDEX_op_nop);
+} else {
+TCGv_i64 t0 = tcg_temp_new_i64();
+TCGv_i64 t1 = tcg_temp_new_i64();
+tcg_gen_ext_i32_i64(t0, arg1);
+tcg_gen_ext_i32_i64(t1, arg2);
+tcg_gen_mul_i64(t0, t0, t1);
+tcg_gen_extr_i64_i32(rl, rh, t0);
+tcg_temp_free_i64(t0);
+tcg_temp_free_i64(t1);
+}
+}
+
+static inline void tcg_gen_mulu2_i64(TCGv_i64 rl, TCGv_i64 rh,
+ TCGv_i64 arg1, TCGv_i64 arg2)
+{
+if (TCG_TARGET_HAS_mulu2_i64) {
+tcg_gen_op4_i64(INDEX_op_mulu2_i64, rl, rh, arg1, arg2);
+/* Allow the optimizer room to replace mulu2 with two moves.  */
+tcg_gen_op0(INDEX_op_nop);
+} else {
+TCGv_i64 t0 = tcg_temp_new_i64();
+int sizemask = 0;
+/* Return value and both arguments are 64-bit and unsigned.  */
+sizemask |= tcg_gen_sizemask(0, 1, 0);
+sizemask |= tcg_gen_sizemask(1, 1, 0);
+sizemask |= tcg_gen_sizemask(2, 1, 0);
+tcg_gen_mul_i64(t0, arg1, arg2);
+tcg_gen_helper64(tcg_helper_muluh_i64, sizemask, rh, arg1, arg2);
+tcg_gen_mov_i64(rl, t0);
+tcg_temp_free_i64(t0);
+}
+}
+
+static inline void tcg_gen_muls2_i64(TCGv_i64 rl, TCGv_i64 rh,
+ TCGv_i64 arg1, TCGv_i64 arg2)
+{
+if (TCG_TARGET_HAS_muls2_i64) {
+tcg_gen_op4_i64(INDEX_op_muls2_i64, rl, rh, arg1, arg2);
+/* Allow the optimizer room to replace muls2 with two moves.  */
+tcg_gen_op0(INDEX_op_nop);
+} else {
+TCGv_i64 t0 = tcg_temp_new_i64();
+int sizemask = 0;
+/* Return value and both arguments are 64-bit and signed.  */
+sizemask |= tcg_gen_sizemask(0, 1, 1);
+sizemask |= tcg_gen_sizemask(1, 1, 1);
+sizemask |= tcg_gen_sizemask(2, 1, 1);
+tcg_gen_mul_i64(t0, arg1, arg2);
+tcg_gen_helper64(tcg_helper_mulsh_i64, sizemask, rh, arg1, arg2);
+tcg_gen_mov_i64(rl, t0);
+tcg_temp_free_i64(t0);
+}
+}
+
 /***/
 /* QEMU specific operations. Their type depend on the QEMU CPU
type. */
@@ -2659,6 +2739,8 @@ static inline void tcg_gen_qemu_st64(TCGv_i64 arg, TCGv 
addr, int mem_index)
 #define tcg_const_tl tcg_const_i64
 #define tcg_const_local_tl tcg_const_local_i64
 #define tcg_gen_movcond_tl tcg_gen_movcond_i64
+#define tcg_gen_mulu2_tl tcg_gen_mulu2_i64
+#define tcg_gen_muls2_tl tcg_gen_muls2_i64
 #else
 #define tcg_gen_movi_tl tcg_gen_movi_i32
 #define tcg_gen_mov_tl tcg_gen_mov_i32
@@ -2732,6 +2814,8 @@ static inline void tcg_gen_qemu_st64(TCGv_i64 arg, TCGv 
addr, int mem_index)
 #define tcg_const_tl tcg_const_i32
 #define tcg_const_local_tl tcg_const_local_i32
 #define tcg_gen_movcond_tl tcg_gen_movcond_i32
+#define tcg_gen_mulu2_tl tcg_gen_mulu2_i32
+#define tcg_gen_muls2_tl 

Re: [Qemu-devel] [PATCH v1 1/6] i2c: support address ranges

2013-02-20 Thread Paolo Bonzini
Il 20/02/2013 13:30, Peter Crosthwaite ha scritto:
 Ok,
 
 I do wonder why the address itselt in VMSDs however and my best guess
 is the intention is that devices can modify their address at runtime
 (phyiscally very possible and valid with I2C). So what happens if a
 device changes the value of one of its props at runtime? E.G. in this
 case what happens if my device decides to change its I2CSlave-address
 in response to some arbitrary event? Will that play foul with VMSD or
 can i just save the prop in my VMSD with the rest of my device state
 to implement restoration of the modified prop?

Ok, in this case this would be valid, but the implementation is still a
bit weird.  What is the behavior on reset?  Should it go back to the
original value of the address?

If so, you need to use a separate variable to store the initial value of
the address and the current value.  Then the initial value is immutable
and thus not serialized; the current value instead is part of the
VMState.  More importantly, the reset callback can then reset the
current address back to the initial value.

Paolo



Re: [Qemu-devel] [PATCH] tap: forbid creating multiqueue tap when hub is used

2013-02-20 Thread Stefan Hajnoczi
On Wed, Feb 20, 2013 at 05:18:08PM +0800, Jason Wang wrote:
 diff --git a/net/tap.c b/net/tap.c
 index 48c254e..1e14f59 100644
 --- a/net/tap.c
 +++ b/net/tap.c
 @@ -693,6 +693,12 @@ int net_init_tap(const NetClientOptions *opts, const 
 char *name,
  queues = tap-has_queues ? tap-queues : 1;
  vhostfdname = tap-has_vhostfd ? tap-vhostfd : NULL;
  
 +if (peer  (tap-has_queues || tap-has_fds || tap-has_vhostfds)) {
 +error_report(This configuration is not compatiable with multiqueue
 +  tap);

s/compatiable/compatible/

The error message should be specific, for example, multiqueue tap
cannot be used with QEMU vlans.

A comment would be nice too to remind readers that peer is only set when
QEMU vlans are in use.  peer is always NULL for -netdev.

Stefan



Re: [Qemu-devel] qemu 1.4 : ubuntu 12.10 : ehci + companion + usb-tablet - vmmouse not loaded + usb-tablet not working

2013-02-20 Thread Tiziano Müller
Hi Alexandre

No solution yet, but I can reproduce bug 2) with Fedora 18 64bit as
guest.

Regards,
Tiziano

Am Mittwoch, den 20.02.2013, 13:56 +0100 schrieb Alexandre DERUMIER:
 Hi List,
 
 I'm testing qemu 1.4, without ubuntu desktop 12.10 with graphical installer
 
 I found 2 bugs:
 
 1) vmmouse is not loaded  if an usb-tablet is plugged on an ehci controller 
 with companion
 -
 
 4 cases with mixed options:
 
 
 a)ehci +companion +tablet:  vmmouse is not loaded
 
 qemu command line : -readconfig /usr/share/qemu-server/pve-usb-companion.cfg 
 -device usb-tablet,id=tablet,bus=ehci.0,port=6
 
 # info mice
   Mouse #0: QEMU PS/2 Mouse
 * Mouse #1: QEMU HID Tablet (absolute)
 
 
 b)ehci +companion -tablet: vmmouse is loaded
 
 qemu command line :  -readconfig /usr/share/qemu-server/pve-usb-companion.cfg
 
 # info mice
   Mouse #0: QEMU PS/2 Mouse
 * Mouse #1: vmmouse (absolute)
 
 
 c)ehci -companion + tablet : vmmouse is loaded
 
 qemu command line :  -readconfig 
 /usr/share/qemu-server/pve-usb-nocompanion.cfg -device 
 usb-tablet,id=tablet,bus=ehci.0,port=6
 
 # info mice
   Mouse #1: QEMU HID Tablet (absolute)
   Mouse #0: QEMU PS/2 Mouse
 * Mouse #2: vmmouse (absolute)
 
 
 
 d)ehci -companion -tablet : vmmouse is loaded
 
 qemu command line :  -readconfig 
 /usr/share/qemu-server/pve-usb-nocompanion.cfg
 
 # info mice
   Mouse #0: QEMU PS/2 Mouse
 * Mouse #1: vmmouse (absolute)
 
 
 pve-usb-companion.cfg:
 
 [device ehci]
   driver = ich9-usb-ehci1
   addr = 1d.7
   multifunction = on
 
 [device uhci-1]
   driver = ich9-usb-uhci1
   addr = 1d.0
   multifunction = on
   masterbus = ehci.0
   firstport = 0
 
 [device uhci-2]
   driver = ich9-usb-uhci2
   addr = 1d.1
   multifunction = on
   masterbus = ehci.0
   firstport = 2
 
 [device uhci-3]
   driver = ich9-usb-uhci3
   addr = 1d.2
   multifunction = on
   masterbus = ehci.0
   firstport = 4
 
 
 
 pve-usb-nocompanion.cfg:
 
 [device ehci]
   driver = ich9-usb-ehci1
   addr = 1d.7
   multifunction = off
 
 
 2) -usb-tablet don't work on ehci with ubuntu
 --
 - don't work (mouse not moving) with or without companion
 - device is correctly displayed with #lsusb,so maybe it's an xorg driver 
 problem.
 - It's working fine on windows guest. 
 
 
 
 
 Both bugs result to don't have a working mouse in ubuntu installer.
 (vmmouse is not available, and usb-tablet is selected but it's not working).
 
 
 
 
 Any idea ? 
 
 Regards,
 
 Alexandre Derumier
 
 

-- 
stepping stone GmbH
Neufeldstrasse 9
CH-3012 Bern
Telefon: +41 31 332 53 63
www.stepping-stone.ch
tiziano.muel...@stepping-stone.ch




Re: [Qemu-devel] Live migration using qcow2

2013-02-20 Thread Tiziano Müller
Am Mittwoch, den 20.02.2013, 12:20 +0100 schrieb Kevin Wolf:
 On Wed, Feb 20, 2013 at 11:47:56AM +0100, Tiziano Müller wrote:
  Hi everyone
  
  According to http://wiki.qemu.org/Migration/Storage section Image
  Formats qemu can't do live migration without data corruption when using
  qcow2 or qed due to the metadata caches.
  Wasn't that fixed by commit 06d9260 ?
 
 Yes, it is fixed. Depending on your backend, you still need
 cache=none/directsync, of course.

Thanks for the fast reply. Can you please elaborate on that (or post a
link to an explanation): What exactly does the backend have to provide
that for example cache=writeback can be used? Is there a way to test for
it?

Regards,
Tiziano

-- 
stepping stone GmbH
Neufeldstrasse 9
CH-3012 Bern
Telefon: +41 31 332 53 63
www.stepping-stone.ch
tiziano.muel...@stepping-stone.ch




[Qemu-devel] [Bug 1130533] [NEW] Documentation cannot be build since commit c70a01e449536c616c85ab820c6fbad7d7e9cf39

2013-02-20 Thread FredBezies
Public bug reported:

I tried to build git -based qemu and when documentation is processed I
got this error :

./qemu-options.texi:1526: unknown command `list'
./qemu-options.texi:1526: table requires an argument: the formatter for @item
./qemu-options.texi:1526: warning: @table has text but no @item

Looks like commit c70a01e449536c616c85ab820c6fbad7d7e9cf39 is guilty ?!

Or any modification related to documentation, I think.

** Affects: qemu
 Importance: Undecided
 Status: New

-- 
You received this bug notification because you are a member of qemu-
devel-ml, which is subscribed to QEMU.
https://bugs.launchpad.net/bugs/1130533

Title:
  Documentation cannot be build since commit
  c70a01e449536c616c85ab820c6fbad7d7e9cf39

Status in QEMU:
  New

Bug description:
  I tried to build git -based qemu and when documentation is processed I
  got this error :

  ./qemu-options.texi:1526: unknown command `list'
  ./qemu-options.texi:1526: table requires an argument: the formatter for @item
  ./qemu-options.texi:1526: warning: @table has text but no @item

  Looks like commit c70a01e449536c616c85ab820c6fbad7d7e9cf39 is guilty
  ?!

  Or any modification related to documentation, I think.

To manage notifications about this bug go to:
https://bugs.launchpad.net/qemu/+bug/1130533/+subscriptions



  1   2   3   4   >