[Qemu-devel] [PULL 7/7] softfloat: fix return type of roundAndPackFloat16

2016-01-22 Thread Peter Maydell
From: Aurelien Jarno 

The roundAndPackFloat16 function should return a float16 value, not a
float32 one. Fix that.

Cc: Peter Maydell 
Signed-off-by: Aurelien Jarno 
Reviewed-by: Peter Maydell 
Message-id: 1452700993-6570-1-git-send-email-aurel...@aurel32.net
Signed-off-by: Peter Maydell 
---
 fpu/softfloat.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/fpu/softfloat.c b/fpu/softfloat.c
index 850d08f..162c211 100644
--- a/fpu/softfloat.c
+++ b/fpu/softfloat.c
@@ -3368,7 +3368,7 @@ static float16 packFloat16(flag zSign, int_fast16_t zExp, 
uint16_t zSig)
 | Binary Floating-Point Arithmetic.
 **/
 
-static float32 roundAndPackFloat16(flag zSign, int_fast16_t zExp,
+static float16 roundAndPackFloat16(flag zSign, int_fast16_t zExp,
uint32_t zSig, flag ieee,
float_status *status)
 {
-- 
1.9.1




Re: [Qemu-devel] [PATCH v13 00/10] Block replication for continuous checkpoints

2016-01-22 Thread Dr. David Alan Gilbert
Hi,
  I can trigger a segfault if I wire in the block replication together with
a quorum instance; it only triggers with both of them present but,
it looks like the problem is a disagreement about the number of quorum
members;  I'm triggering this on the 'colo-v2.4-periodic-mode' branch
that is posted in the colo-framework set that I think includes this set
(from https://github.com/coloft/qemu.git).

To trigger:
./git/colo/jan-16/try/x86_64-softmmu/qemu-system-x86_64 -nographic -S

(qemu) drive_add 0 
if=none,id=colo-disk0,file.filename=/home/localvms/bugzilla.raw,driver=raw,node-name=node0
(qemu) drive_add 1 
if=none,id=active-disk0,throttling.bps-total=7000,driver=replication,mode=secondary,file.driver=qcow2,file.file.filename=/run/colo-active-disk.qcow2,file.backing.driver=qcow2,file.backing.file.filename=/run/colo-hidden-disk.qcow2,file.backing.backing=colo-disk0
(qemu) drive_add 2 
if=none,id=top-quorum,driver=quorum,read-pattern=fifo,vote-threshold=1,children.0=active-disk0
(qemu) device_add virtio-blk-pci,drive=top-quorum,addr=9

*** Error in `/root/colo/jan-2016/./try/x86_64-softmmu/qemu-system-x86_64': 
free(): invalid pointer: 0x55a8fdf0 ***
=== Backtrace: =
/lib64/libc.so.6(+0x7cfe1)[0x7110ffe1]
/lib64/libglib-2.0.so.0(g_free+0xf)[0x71ecc36f]
/root/colo/jan-2016/./try/x86_64-softmmu/qemu-system-x86_64
Program received signal SIGABRT, Aborted.
0x710c85f7 in raise () from /lib64/libc.so.6
(gdb) where
#0  0x710c85f7 in raise () from /lib64/libc.so.6
#1  0x710c9ce8 in abort () from /lib64/libc.so.6
#2  0x71108317 in __libc_message () from /lib64/libc.so.6
#3  0x7110ffe1 in _int_free () from /lib64/libc.so.6
#4  0x71ecc36f in g_free () from /lib64/libglib-2.0.so.0
#5  0x559dfdd7 in qemu_iovec_destroy (qiov=0x57815410) at 
/root/colo/jan-2016/qemu/util/iov.c:378
#6  0x55989cce in quorum_aio_finalize (acb=0x57815350) at 
/root/colo/jan-2016/qemu/block/quorum.c:171
171 qemu_iovec_destroy(>qcrs[i].qiov);
(gdb) list
166 
167 if (acb->is_read) {
168 /* on the quorum case acb->child_iter == s->num_children - 1 */
169 for (i = 0; i <= acb->child_iter; i++) {
170 qemu_vfree(acb->qcrs[i].buf);
171 qemu_iovec_destroy(>qcrs[i].qiov);
172 }
173 }
174 
175 g_free(acb->qcrs);
(gdb) p acb->child_iter
$1 = 1
(gdb) p i
$3 = 1

#7  0x5598afca in quorum_aio_cb (opaque=, ret=-5)
at /root/colo/jan-2016/qemu/block/quorum.c:302
#8  0x559990ee in bdrv_co_complete (acb=0x57815410) at 
/root/colo/jan-2016/qemu/block/io.c:2122
.

So I guess acb->child_iter is wrong, since we only have one child on that 
quorum?
and we're trying to do a destroy on the second child.

Dave
--
Dr. David Alan Gilbert / dgilb...@redhat.com / Manchester, UK



[Qemu-devel] [PULL 0/7] softfloat queue

2016-01-22 Thread Peter Maydell
Pullreq with some pending softfloat patches: mine to get rid of the
confusing softfloat specific int types, and Aurelien's to fix the
roundAndPackFloat16 return type.

thanks
-- PMM


The following changes since commit 3c2c85ec4b112e3e2b899472314d5da6880fdf0e:

  Merge remote-tracking branch 'remotes/gkurz/tags/for-upstream' into staging 
(2016-01-22 14:44:12 +)

are available in the git repository at:


  git://git.linaro.org/people/pmaydell/qemu-arm.git tags/pull-softfloat-20160122

for you to fetch changes up to 7ceac86f49b564954f5bde477c4281f407be1399:

  softfloat: fix return type of roundAndPackFloat16 (2016-01-22 15:09:21 +)


softfloat:
 * drop confusing softfloat-only types
 * fix return type of roundAndPackFloat16


Aurelien Jarno (1):
  softfloat: fix return type of roundAndPackFloat16

Peter Maydell (6):
  fpu: Replace int64 typedef with int64_t
  fpu: Replace uint64 typedef with uint64_t
  fpu: Replace int32 typedef with int32_t
  fpu: Replace uint32 typedef with uint32_t
  fpu: Replace int8 typedef with int8_t
  fpu: Replace uint8 typedef with uint8_t

 crypto/secret.c|   2 +-
 fpu/softfloat-macros.h |  26 +++---
 fpu/softfloat-specialize.h |   2 +-
 fpu/softfloat.c| 220 ++---
 hw/i386/pc.c   |   2 +-
 hw/ipmi/isa_ipmi_bt.c  |   2 +-
 hw/ipmi/isa_ipmi_kcs.c |   2 +-
 hw/misc/imx25_ccm.c|   2 +-
 hw/misc/imx31_ccm.c|   2 +-
 hw/net/vmware_utils.h  |   2 +-
 hw/net/vmxnet3.c   |   2 +-
 hw/ppc/spapr_events.c  |   4 +-
 include/fpu/softfloat.h|  68 ++
 include/hw/i386/pc.h   |   2 +-
 migration/ram.c|   2 +-
 target-alpha/fpu_helper.c  |   2 +-
 target-mips/kvm.c  |   4 +-
 target-mips/msa_helper.c   |  36 
 target-s390x/kvm.c |   2 +-
 tests/vhost-user-test.c|   2 +-
 20 files changed, 188 insertions(+), 198 deletions(-)



[Qemu-devel] [PULL 3/7] fpu: Replace int32 typedef with int32_t

2016-01-22 Thread Peter Maydell
Replace the int32 softfloat-specific typedef with int32_t.
This change was made with

find hw include fpu target-* -name '*.[ch]' | xargs sed -i -e 
's/\bint32\b/int32_t/g'

together with manual removal of the typedef definition, and
manual undoing of some mis-hits where macro arguments were
being used for token pasting rather than as a type.

The uses in hw/ipmi/ should not have been using this type at all.

Signed-off-by: Peter Maydell 
Reviewed-by: Richard Henderson 
Reviewed-by: Aurelien Jarno 
Acked-by: Leon Alrae 
Acked-by: James Hogan 
Message-id: 1452603315-27030-4-git-send-email-peter.mayd...@linaro.org
---
 fpu/softfloat.c  | 106 +++
 hw/ipmi/isa_ipmi_bt.c|   2 +-
 hw/ipmi/isa_ipmi_kcs.c   |   2 +-
 include/fpu/softfloat.h  |  18 
 target-mips/msa_helper.c |  24 +--
 5 files changed, 76 insertions(+), 76 deletions(-)

diff --git a/fpu/softfloat.c b/fpu/softfloat.c
index c72eb5b..af3f82e 100644
--- a/fpu/softfloat.c
+++ b/fpu/softfloat.c
@@ -144,7 +144,7 @@ static inline flag extractFloat16Sign(float16 a)
 | positive or negative integer is returned.
 **/
 
-static int32 roundAndPackInt32(flag zSign, uint64_t absZ, float_status *status)
+static int32_t roundAndPackInt32(flag zSign, uint64_t absZ, float_status 
*status)
 {
 int8 roundingMode;
 flag roundNearestEven;
@@ -702,7 +702,7 @@ static inline uint64_t extractFloatx80Frac( floatx80 a )
 | value `a'.
 **/
 
-static inline int32 extractFloatx80Exp( floatx80 a )
+static inline int32_t extractFloatx80Exp( floatx80 a )
 {
 
 return a.high & 0x7FFF;
@@ -729,7 +729,7 @@ static inline flag extractFloatx80Sign( floatx80 a )
 **/
 
 static void
- normalizeFloatx80Subnormal( uint64_t aSig, int32 *zExpPtr, uint64_t *zSigPtr )
+ normalizeFloatx80Subnormal( uint64_t aSig, int32_t *zExpPtr, uint64_t 
*zSigPtr )
 {
 int8 shiftCount;
 
@@ -744,7 +744,7 @@ static void
 | extended double-precision floating-point value, returning the result.
 **/
 
-static inline floatx80 packFloatx80( flag zSign, int32 zExp, uint64_t zSig )
+static inline floatx80 packFloatx80( flag zSign, int32_t zExp, uint64_t zSig )
 {
 floatx80 z;
 
@@ -779,7 +779,7 @@ static inline floatx80 packFloatx80( flag zSign, int32 
zExp, uint64_t zSig )
 **/
 
 static floatx80 roundAndPackFloatx80(int8 roundingPrecision, flag zSign,
- int32 zExp, uint64_t zSig0, uint64_t 
zSig1,
+ int32_t zExp, uint64_t zSig0, uint64_t 
zSig1,
  float_status *status)
 {
 int8 roundingMode;
@@ -975,7 +975,7 @@ static floatx80 roundAndPackFloatx80(int8 
roundingPrecision, flag zSign,
 **/
 
 static floatx80 normalizeRoundAndPackFloatx80(int8 roundingPrecision,
-  flag zSign, int32 zExp,
+  flag zSign, int32_t zExp,
   uint64_t zSig0, uint64_t zSig1,
   float_status *status)
 {
@@ -1023,7 +1023,7 @@ static inline uint64_t extractFloat128Frac0( float128 a )
 | `a'.
 **/
 
-static inline int32 extractFloat128Exp( float128 a )
+static inline int32_t extractFloat128Exp( float128 a )
 {
 
 return ( a.high>>48 ) & 0x7FFF;
@@ -1055,7 +1055,7 @@ static void
  normalizeFloat128Subnormal(
  uint64_t aSig0,
  uint64_t aSig1,
- int32 *zExpPtr,
+ int32_t *zExpPtr,
  uint64_t *zSig0Ptr,
  uint64_t *zSig1Ptr
  )
@@ -1096,7 +1096,7 @@ static void
 **/
 
 static inline float128
- packFloat128( flag zSign, int32 zExp, uint64_t zSig0, uint64_t zSig1 )
+ packFloat128( flag zSign, int32_t zExp, uint64_t zSig0, uint64_t zSig1 )
 {
 float128 z;
 
@@ -1127,7 +1127,7 @@ static inline float128
 | overflow follows the IEC/IEEE Standard for Binary Floating-Point Arithmetic.
 **/
 
-static float128 roundAndPackFloat128(flag zSign, int32 zExp,
+static float128 roundAndPackFloat128(flag zSign, int32_t zExp,
  uint64_t zSig0, uint64_t zSig1,
  uint64_t zSig2, float_status *status)
 {
@@ 

[Qemu-devel] [PULL 2/7] fpu: Replace uint64 typedef with uint64_t

2016-01-22 Thread Peter Maydell
Replace the uint64 softfloat-specific typedef with uint64_t.
This change was made with

find include fpu target-* -name '*.[ch]' | xargs sed -i -e 
's/\buint64\b/uint64_t/g'

together with manual removal of the typedef definition, and
manual undoing of some mis-hits where macro arguments were
being used for token pasting rather than as a type.

Note that the target-mips/kvm.c and target-s390x/kvm.c changes are fixing
code that should not have been using the uint64 type in the first place.

Signed-off-by: Peter Maydell 
Reviewed-by: Richard Henderson 
Reviewed-by: Aurelien Jarno 
Acked-by: Leon Alrae 
Acked-by: James Hogan 
Message-id: 1452603315-27030-3-git-send-email-peter.mayd...@linaro.org
---
 fpu/softfloat.c   | 10 +-
 include/fpu/softfloat.h   |  9 -
 target-alpha/fpu_helper.c |  2 +-
 target-mips/kvm.c |  4 ++--
 target-s390x/kvm.c|  2 +-
 5 files changed, 13 insertions(+), 14 deletions(-)

diff --git a/fpu/softfloat.c b/fpu/softfloat.c
index 967da1c..c72eb5b 100644
--- a/fpu/softfloat.c
+++ b/fpu/softfloat.c
@@ -1363,7 +1363,7 @@ float128 int32_to_float128(int32_t a, float_status 
*status)
 float32 int64_to_float32(int64_t a, float_status *status)
 {
 flag zSign;
-uint64 absA;
+uint64_t absA;
 int8 shiftCount;
 
 if ( a == 0 ) return float32_zero;
@@ -1414,7 +1414,7 @@ float64 int64_to_float64(int64_t a, float_status *status)
 floatx80 int64_to_floatx80(int64_t a, float_status *status)
 {
 flag zSign;
-uint64 absA;
+uint64_t absA;
 int8 shiftCount;
 
 if ( a == 0 ) return packFloatx80( 0, 0, 0 );
@@ -1434,7 +1434,7 @@ floatx80 int64_to_floatx80(int64_t a, float_status 
*status)
 float128 int64_to_float128(int64_t a, float_status *status)
 {
 flag zSign;
-uint64 absA;
+uint64_t absA;
 int8 shiftCount;
 int32 zExp;
 uint64_t zSig0, zSig1;
@@ -1705,7 +1705,7 @@ int64_t float32_to_int64(float32 a, float_status *status)
 | raise the inexact exception flag.
 **/
 
-uint64 float32_to_uint64(float32 a, float_status *status)
+uint64_t float32_to_uint64(float32 a, float_status *status)
 {
 flag aSign;
 int_fast16_t aExp, shiftCount;
@@ -1750,7 +1750,7 @@ uint64 float32_to_uint64(float32 a, float_status *status)
 | not round to zero will raise the inexact flag.
 **/
 
-uint64 float32_to_uint64_round_to_zero(float32 a, float_status *status)
+uint64_t float32_to_uint64_round_to_zero(float32 a, float_status *status)
 {
 signed char current_rounding_mode = status->float_rounding_mode;
 set_float_rounding_mode(float_round_to_zero, status);
diff --git a/include/fpu/softfloat.h b/include/fpu/softfloat.h
index b49d5fb..438804e 100644
--- a/include/fpu/softfloat.h
+++ b/include/fpu/softfloat.h
@@ -103,7 +103,6 @@ typedef uint8_t uint8;
 typedef int8_t int8;
 typedef unsigned int uint32;
 typedef signed int int32;
-typedef uint64_t uint64;
 
 #define LIT64( a ) a##LL
 
@@ -380,8 +379,8 @@ int32 float32_to_int32_round_to_zero(float32, float_status 
*status);
 uint32 float32_to_uint32(float32, float_status *status);
 uint32 float32_to_uint32_round_to_zero(float32, float_status *status);
 int64_t float32_to_int64(float32, float_status *status);
-uint64 float32_to_uint64(float32, float_status *status);
-uint64 float32_to_uint64_round_to_zero(float32, float_status *status);
+uint64_t float32_to_uint64(float32, float_status *status);
+uint64_t float32_to_uint64_round_to_zero(float32, float_status *status);
 int64_t float32_to_int64_round_to_zero(float32, float_status *status);
 float64 float32_to_float64(float32, float_status *status);
 floatx80 float32_to_floatx80(float32, float_status *status);
@@ -493,8 +492,8 @@ uint32 float64_to_uint32(float64, float_status *status);
 uint32 float64_to_uint32_round_to_zero(float64, float_status *status);
 int64_t float64_to_int64(float64, float_status *status);
 int64_t float64_to_int64_round_to_zero(float64, float_status *status);
-uint64 float64_to_uint64(float64 a, float_status *status);
-uint64 float64_to_uint64_round_to_zero(float64 a, float_status *status);
+uint64_t float64_to_uint64(float64 a, float_status *status);
+uint64_t float64_to_uint64_round_to_zero(float64 a, float_status *status);
 float32 float64_to_float32(float64, float_status *status);
 floatx80 float64_to_floatx80(float64, float_status *status);
 float128 float64_to_float128(float64, float_status *status);
diff --git a/target-alpha/fpu_helper.c b/target-alpha/fpu_helper.c
index b091aa8..0c65e1f 100644
--- a/target-alpha/fpu_helper.c
+++ b/target-alpha/fpu_helper.c
@@ -437,7 +437,7 @@ uint64_t helper_cvtqs(CPUAlphaState *env, uint64_t a)
 return float32_to_s(fr);
 }
 
-/* Implement float64 to uint64 conversion without saturation -- 

[Qemu-devel] [PULL 6/7] fpu: Replace uint8 typedef with uint8_t

2016-01-22 Thread Peter Maydell
Replace the uint8 softfloat-specific typedef with uint8_t.
This change was made with

find include hw fpu target-* -name '*.[ch]' | xargs sed -i -e 
's/\buint8\b/uint8_t/g'

together with manual removal of the typedef definition and
manual fixing of more erroneous uses found via test compilation.

It turns out that the only code using this type is an accidental
use where uint8_t was intended anyway...

Signed-off-by: Peter Maydell 
Reviewed-by: Richard Henderson 
Reviewed-by: Aurelien Jarno 
Acked-by: Leon Alrae 
Acked-by: James Hogan 
Message-id: 1452603315-27030-7-git-send-email-peter.mayd...@linaro.org
---
 crypto/secret.c |  2 +-
 hw/net/vmware_utils.h   |  2 +-
 include/fpu/softfloat.h | 13 -
 migration/ram.c |  2 +-
 4 files changed, 7 insertions(+), 12 deletions(-)

diff --git a/crypto/secret.c b/crypto/secret.c
index 9a9257a..a799da1 100644
--- a/crypto/secret.c
+++ b/crypto/secret.c
@@ -434,7 +434,7 @@ int qcrypto_secret_lookup(const char *secretid,
 return -1;
 }
 
-*data = g_new0(uint8, secret->rawlen + 1);
+*data = g_new0(uint8_t, secret->rawlen + 1);
 memcpy(*data, secret->rawdata, secret->rawlen);
 (*data)[secret->rawlen] = '\0';
 *datalen = secret->rawlen;
diff --git a/hw/net/vmware_utils.h b/hw/net/vmware_utils.h
index c2c2f90..c0dbb2f 100644
--- a/hw/net/vmware_utils.h
+++ b/hw/net/vmware_utils.h
@@ -49,7 +49,7 @@ vmw_shmem_rw(hwaddr addr, void *buf, int len, int is_write)
 }
 
 static inline void
-vmw_shmem_set(hwaddr addr, uint8 val, int len)
+vmw_shmem_set(hwaddr addr, uint8_t val, int len)
 {
 int i;
 VMW_SHPRN("SHMEM set: %" PRIx64 ", len: %d (value 0x%X)", addr, len, val);
diff --git a/include/fpu/softfloat.h b/include/fpu/softfloat.h
index a6842ad..575a739 100644
--- a/include/fpu/softfloat.h
+++ b/include/fpu/softfloat.h
@@ -90,16 +90,11 @@ this code that are retained.
 #include "config-host.h"
 #include "qemu/osdep.h"
 
-/*
-| Each of the following `typedef's defines the most convenient type that holds
-| integers of at least as many bits as specified.  For example, `uint8' should
-| be the most convenient type that can hold unsigned integers of as many as
-| 8 bits.  The `flag' type must be able to hold either a 0 or 1.  For most
-| implementations of C, `flag', `uint8', and `int8' should all be `typedef'ed
-| to the same as `int'.
-**/
+/* This 'flag' type must be able to hold at least 0 and 1. It should
+ * probably be replaced with 'bool' but the uses would need to be audited
+ * to check that they weren't accidentally relying on it being a larger type.
+ */
 typedef uint8_t flag;
-typedef uint8_t uint8;
 
 #define LIT64( a ) a##LL
 
diff --git a/migration/ram.c b/migration/ram.c
index 4e606ab..e49749d 100644
--- a/migration/ram.c
+++ b/migration/ram.c
@@ -265,7 +265,7 @@ struct DecompressParam {
 QemuMutex mutex;
 QemuCond cond;
 void *des;
-uint8 *compbuf;
+uint8_t *compbuf;
 int len;
 };
 typedef struct DecompressParam DecompressParam;
-- 
1.9.1




[Qemu-devel] [PULL 5/7] fpu: Replace int8 typedef with int8_t

2016-01-22 Thread Peter Maydell
Replace the int8 softfloat-specific typedef with int8_t.
This change was made with

find include hw fpu target-* -name '*.[ch]' | xargs sed -i -e 
's/\bint8\b/int8_t/g'

together with manual removal of the typedef definition, and
manual undoing of various mis-hits.

Signed-off-by: Peter Maydell 
Reviewed-by: Richard Henderson 
Reviewed-by: Aurelien Jarno 
Acked-by: Leon Alrae 
Acked-by: James Hogan 
Message-id: 1452603315-27030-6-git-send-email-peter.mayd...@linaro.org
---
 fpu/softfloat-macros.h | 26 
 fpu/softfloat-specialize.h |  2 +-
 fpu/softfloat.c| 50 +++---
 include/fpu/softfloat.h|  3 +--
 4 files changed, 40 insertions(+), 41 deletions(-)

diff --git a/fpu/softfloat-macros.h b/fpu/softfloat-macros.h
index 5e030cd..e95b445 100644
--- a/fpu/softfloat-macros.h
+++ b/fpu/softfloat-macros.h
@@ -164,7 +164,7 @@ static inline void
  uint64_t a0, uint64_t a1, int_fast16_t count, uint64_t *z0Ptr, uint64_t 
*z1Ptr)
 {
 uint64_t z0, z1;
-int8 negCount = ( - count ) & 63;
+int8_t negCount = ( - count ) & 63;
 
 if ( count == 0 ) {
 z1 = a1;
@@ -201,7 +201,7 @@ static inline void
  uint64_t a0, uint64_t a1, int_fast16_t count, uint64_t *z0Ptr, uint64_t 
*z1Ptr)
 {
 uint64_t z0, z1;
-int8 negCount = ( - count ) & 63;
+int8_t negCount = ( - count ) & 63;
 
 if ( count == 0 ) {
 z1 = a1;
@@ -236,7 +236,7 @@ static inline void
  uint64_t a0, uint64_t a1, int_fast16_t count, uint64_t *z0Ptr, uint64_t 
*z1Ptr)
 {
 uint64_t z0, z1;
-int8 negCount = ( - count ) & 63;
+int8_t negCount = ( - count ) & 63;
 
 if ( count == 0 ) {
 z1 = a1;
@@ -294,7 +294,7 @@ static inline void
  )
 {
 uint64_t z0, z1, z2;
-int8 negCount = ( - count ) & 63;
+int8_t negCount = ( - count ) & 63;
 
 if ( count == 0 ) {
 z2 = a2;
@@ -371,7 +371,7 @@ static inline void
  )
 {
 uint64_t z0, z1, z2;
-int8 negCount;
+int8_t negCount;
 
 z2 = a2<>27 ) & 15;
@@ -669,7 +669,7 @@ static uint32_t estimateSqrt32(int_fast16_t aExp, uint32_t 
a)
 | `a'.  If `a' is zero, 32 is returned.
 **/
 
-static int8 countLeadingZeros32( uint32_t a )
+static int8_t countLeadingZeros32( uint32_t a )
 {
 #if SOFTFLOAT_GNUC_PREREQ(3, 4)
 if (a) {
@@ -678,7 +678,7 @@ static int8 countLeadingZeros32( uint32_t a )
 return 32;
 }
 #else
-static const int8 countLeadingZerosHigh[] = {
+static const int8_t countLeadingZerosHigh[] = {
 8, 7, 6, 6, 5, 5, 5, 5, 4, 4, 4, 4, 4, 4, 4, 4,
 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
@@ -696,7 +696,7 @@ static int8 countLeadingZeros32( uint32_t a )
 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
 };
-int8 shiftCount;
+int8_t shiftCount;
 
 shiftCount = 0;
 if ( a < 0x1 ) {
@@ -717,7 +717,7 @@ static int8 countLeadingZeros32( uint32_t a )
 | `a'.  If `a' is zero, 64 is returned.
 **/
 
-static int8 countLeadingZeros64( uint64_t a )
+static int8_t countLeadingZeros64( uint64_t a )
 {
 #if SOFTFLOAT_GNUC_PREREQ(3, 4)
 if (a) {
@@ -726,7 +726,7 @@ static int8 countLeadingZeros64( uint64_t a )
 return 64;
 }
 #else
-int8 shiftCount;
+int8_t shiftCount;
 
 shiftCount = 0;
 if ( a < ( (uint64_t) 1 )<<32 ) {
diff --git a/fpu/softfloat-specialize.h b/fpu/softfloat-specialize.h
index 6dd41d8..0875436 100644
--- a/fpu/softfloat-specialize.h
+++ b/fpu/softfloat-specialize.h
@@ -174,7 +174,7 @@ const float128 float128_default_nan
 | should be simply `float_exception_flags |= flags;'.
 **/
 
-void float_raise(int8 flags, float_status *status)
+void float_raise(int8_t flags, float_status *status)
 {
 status->float_exception_flags |= flags;
 }
diff --git a/fpu/softfloat.c b/fpu/softfloat.c
index 

[Qemu-devel] [PULL 1/7] fpu: Replace int64 typedef with int64_t

2016-01-22 Thread Peter Maydell
Replace the int64 softfloat-specific typedef with int64_t.
This change was made with

find include fpu target-* -name '*.[ch]' | xargs sed -i -e 
's/\bint64\b/int64_t/g'

together with manual removal of the typedef definition, and
manual undoing of some mis-hits where macro arguments were
being used for token pasting rather than as a type.

Signed-off-by: Peter Maydell 
Reviewed-by: Richard Henderson 
Reviewed-by: Aurelien Jarno 
Acked-by: Leon Alrae 
Message-id: 1452603315-27030-2-git-send-email-peter.mayd...@linaro.org
---
 fpu/softfloat.c  | 30 +++---
 include/fpu/softfloat.h  | 17 -
 target-mips/msa_helper.c | 12 ++--
 3 files changed, 29 insertions(+), 30 deletions(-)

diff --git a/fpu/softfloat.c b/fpu/softfloat.c
index f1170fe..967da1c 100644
--- a/fpu/softfloat.c
+++ b/fpu/softfloat.c
@@ -198,7 +198,7 @@ static int32 roundAndPackInt32(flag zSign, uint64_t absZ, 
float_status *status)
 | returned.
 **/
 
-static int64 roundAndPackInt64(flag zSign, uint64_t absZ0, uint64_t absZ1,
+static int64_t roundAndPackInt64(flag zSign, uint64_t absZ0, uint64_t absZ1,
float_status *status)
 {
 int8 roundingMode;
@@ -255,7 +255,7 @@ static int64 roundAndPackInt64(flag zSign, uint64_t absZ0, 
uint64_t absZ1,
 | exception is raised and the largest unsigned integer is returned.
 **/
 
-static int64 roundAndPackUint64(flag zSign, uint64_t absZ0,
+static int64_t roundAndPackUint64(flag zSign, uint64_t absZ0,
 uint64_t absZ1, float_status *status)
 {
 int8 roundingMode;
@@ -784,7 +784,7 @@ static floatx80 roundAndPackFloatx80(int8 
roundingPrecision, flag zSign,
 {
 int8 roundingMode;
 flag roundNearestEven, increment, isTiny;
-int64 roundIncrement, roundMask, roundBits;
+int64_t roundIncrement, roundMask, roundBits;
 
 roundingMode = status->float_rounding_mode;
 roundNearestEven = ( roundingMode == float_round_nearest_even );
@@ -1666,7 +1666,7 @@ int_fast16_t float32_to_int16_round_to_zero(float32 a, 
float_status *status)
 | largest integer with the same sign as `a' is returned.
 **/
 
-int64 float32_to_int64(float32 a, float_status *status)
+int64_t float32_to_int64(float32 a, float_status *status)
 {
 flag aSign;
 int_fast16_t aExp, shiftCount;
@@ -1769,13 +1769,13 @@ uint64 float32_to_uint64_round_to_zero(float32 a, 
float_status *status)
 | returned.
 **/
 
-int64 float32_to_int64_round_to_zero(float32 a, float_status *status)
+int64_t float32_to_int64_round_to_zero(float32 a, float_status *status)
 {
 flag aSign;
 int_fast16_t aExp, shiftCount;
 uint32_t aSig;
 uint64_t aSig64;
-int64 z;
+int64_t z;
 a = float32_squash_input_denormal(a, status);
 
 aSig = extractFloat32Frac( a );
@@ -3201,7 +3201,7 @@ int_fast16_t float64_to_int16_round_to_zero(float64 a, 
float_status *status)
 | largest integer with the same sign as `a' is returned.
 **/
 
-int64 float64_to_int64(float64 a, float_status *status)
+int64_t float64_to_int64(float64 a, float_status *status)
 {
 flag aSign;
 int_fast16_t aExp, shiftCount;
@@ -3244,12 +3244,12 @@ int64 float64_to_int64(float64 a, float_status *status)
 | returned.
 **/
 
-int64 float64_to_int64_round_to_zero(float64 a, float_status *status)
+int64_t float64_to_int64_round_to_zero(float64 a, float_status *status)
 {
 flag aSign;
 int_fast16_t aExp, shiftCount;
 uint64_t aSig;
-int64 z;
+int64_t z;
 a = float64_squash_input_denormal(a, status);
 
 aSig = extractFloat64Frac( a );
@@ -4864,7 +4864,7 @@ int32 floatx80_to_int32_round_to_zero(floatx80 a, 
float_status *status)
 | overflows, the largest integer with the same sign as `a' is returned.
 **/
 
-int64 floatx80_to_int64(floatx80 a, float_status *status)
+int64_t floatx80_to_int64(floatx80 a, float_status *status)
 {
 flag aSign;
 int32 aExp, shiftCount;
@@ -4904,12 +4904,12 @@ int64 floatx80_to_int64(floatx80 a, float_status 
*status)
 | sign as `a' is returned.
 **/
 
-int64 floatx80_to_int64_round_to_zero(floatx80 a, float_status *status)
+int64_t floatx80_to_int64_round_to_zero(floatx80 a, float_status *status)
 {
 flag aSign;
 int32 aExp, shiftCount;
 uint64_t aSig;
-int64 z;
+int64_t z;
 

Re: [Qemu-devel] [PATCH] mips: Clean up includes

2016-01-22 Thread Leon Alrae
On 18/01/16 17:35, Peter Maydell wrote:
> Clean up includes so that osdep.h is included first and headers
> which it implies are not included manually.
> 
> This commit was created with scripts/clean-includes.
> 
> Signed-off-by: Peter Maydell 
> ---
>  disas/mips.c | 1 +
>  hw/mips/addr.c   | 1 +
>  hw/mips/cputimer.c   | 1 +
>  hw/mips/gt64xxx_pci.c| 1 +
>  hw/mips/mips_fulong2e.c  | 1 +
>  hw/mips/mips_int.c   | 1 +
>  hw/mips/mips_jazz.c  | 1 +
>  hw/mips/mips_malta.c | 1 +
>  hw/mips/mips_mipssim.c   | 1 +
>  hw/mips/mips_r4k.c   | 1 +
>  target-mips/cpu.c| 1 +
>  target-mips/dsp_helper.c | 1 +
>  target-mips/gdbstub.c| 2 +-
>  target-mips/helper.c | 6 +-
>  target-mips/kvm.c| 2 +-
>  target-mips/lmi_helper.c | 1 +
>  target-mips/machine.c| 1 +
>  target-mips/mips-semi.c  | 2 +-
>  target-mips/msa_helper.c | 1 +
>  target-mips/op_helper.c  | 2 +-
>  target-mips/translate.c  | 1 +
>  21 files changed, 21 insertions(+), 9 deletions(-)

Applied to target-mips tree, thanks.

Regards,
Leon




[Qemu-devel] [PATCH v5] i2c-tiny-usb is a small usb to i2c bridge

2016-01-22 Thread Tim Sander
i2c-tiny-usb is a small usb to i2c bridge:
 http://www.harbaum.org/till/i2c_tiny_usb/index.shtml

It is pretty simple and has no usb endpoints just a control.
Reasons for adding this device:
* Linux device driver available
* adding an additional i2c bus via command line e.g.
  -device usb-i2c-tiny,id=i2c-0 -device tmp105,bus=i2c,address=0x50
---
Signed-off-by: Tim Sander 
 default-configs/usb.mak |   1 +
 hw/usb/Makefile.objs|   1 +
 hw/usb/dev-i2c-tiny.c   | 314 
 trace-events|  11 ++
 4 files changed, 327 insertions(+)
 create mode 100644 hw/usb/dev-i2c-tiny.c

diff --git a/default-configs/usb.mak b/default-configs/usb.mak
index f4b8568..01d2c9f 100644
--- a/default-configs/usb.mak
+++ b/default-configs/usb.mak
@@ -8,3 +8,4 @@ CONFIG_USB_AUDIO=y
 CONFIG_USB_SERIAL=y
 CONFIG_USB_NETWORK=y
 CONFIG_USB_BLUETOOTH=y
+CONFIG_USB_I2C_TINY=y
diff --git a/hw/usb/Makefile.objs b/hw/usb/Makefile.objs
index 8f00fbd..3a4c337 100644
--- a/hw/usb/Makefile.objs
+++ b/hw/usb/Makefile.objs
@@ -20,6 +20,7 @@ common-obj-$(CONFIG_USB_AUDIO)+= dev-audio.o
 common-obj-$(CONFIG_USB_SERIAL)   += dev-serial.o
 common-obj-$(CONFIG_USB_NETWORK)  += dev-network.o
 common-obj-$(CONFIG_USB_BLUETOOTH)+= dev-bluetooth.o
+common-obj-$(CONFIG_USB_I2C_TINY) += dev-i2c-tiny.o
 
 ifeq ($(CONFIG_USB_SMARTCARD),y)
 common-obj-y  += dev-smartcard-reader.o
diff --git a/hw/usb/dev-i2c-tiny.c b/hw/usb/dev-i2c-tiny.c
new file mode 100644
index 000..7abb9df
--- /dev/null
+++ b/hw/usb/dev-i2c-tiny.c
@@ -0,0 +1,314 @@
+/*
+ * I2C tiny usb device emulation
+ *
+ * i2c-tiny-usb is a small usb to i2c bridge:
+ *
+ * http://www.harbaum.org/till/i2c_tiny_usb/index.shtml
+ *
+ * The simulated device is pretty simple and has no usb endpoints.
+ * There is a Linux device driver available named i2c-tiny-usb.
+ *
+ * Below is an example how to use this device from command line:
+ *  -device usb-i2c-tiny,id=i2c-0 -device tmp105,bus=i2c,address=0x50
+ *
+ * Copyright (c) 2015 Tim Sander 
+ *
+ * Loosly based on usb dev-serial.c:
+ * Copyright (c) 2006 CodeSourcery.
+ * Copyright (c) 2008 Samuel Thibault 
+ * Written by Paul Brook, reused for FTDI by Samuel Thibault
+ *
+ * This code is licensed under the LGPL.
+ *
+ */
+
+#include "trace.h"
+#include "qemu-common.h"
+#include "qemu/error-report.h"
+#include "hw/usb.h"
+#include "hw/usb/desc.h"
+#include "hw/i2c/i2c.h"
+#include "hw/i2c/smbus.h"
+#include "sysemu/char.h"
+#include "endian.h"
+
+/* commands from USB, must e.g. match command ids in kernel driver */
+#define CMD_ECHO   0
+#define CMD_GET_FUNC   1
+#define CMD_SET_DELAY  2
+#define CMD_GET_STATUS 3
+
+/* To determine what functionality is present */
+#define I2C_FUNC_I2C0x0001
+#define I2C_FUNC_10BIT_ADDR 0x0002
+#define I2C_FUNC_PROTOCOL_MANGLING  0x0004
+#define I2C_FUNC_SMBUS_HWPEC_CALC   0x0008 /* SMBus 2.0 */
+#define I2C_FUNC_SMBUS_READ_WORD_DATA_PEC   0x0800 /* SMBus 2.0 */
+#define I2C_FUNC_SMBUS_WRITE_WORD_DATA_PEC  0x1000 /* SMBus 2.0 */
+#define I2C_FUNC_SMBUS_PROC_CALL_PEC0x2000 /* SMBus 2.0 */
+#define I2C_FUNC_SMBUS_BLOCK_PROC_CALL_PEC  0x4000 /* SMBus 2.0 */
+#define I2C_FUNC_SMBUS_BLOCK_PROC_CALL  0x8000 /* SMBus 2.0 */
+#define I2C_FUNC_SMBUS_QUICK0x0001
+#define I2C_FUNC_SMBUS_READ_BYTE0x0002
+#define I2C_FUNC_SMBUS_WRITE_BYTE   0x0004
+#define I2C_FUNC_SMBUS_READ_BYTE_DATA   0x0008
+#define I2C_FUNC_SMBUS_WRITE_BYTE_DATA  0x0010
+#define I2C_FUNC_SMBUS_READ_WORD_DATA   0x0020
+#define I2C_FUNC_SMBUS_WRITE_WORD_DATA  0x0040
+#define I2C_FUNC_SMBUS_PROC_CALL0x0080
+#define I2C_FUNC_SMBUS_READ_BLOCK_DATA  0x0100
+#define I2C_FUNC_SMBUS_WRITE_BLOCK_DATA 0x0200
+#define I2C_FUNC_SMBUS_READ_I2C_BLOCK   0x0400 /*I2C-like blk-xfr 
*/
+#define I2C_FUNC_SMBUS_WRITE_I2C_BLOCK  0x0800 /*1-byte reg. 
addr.*/
+#define I2C_FUNC_SMBUS_READ_I2C_BLOCK_2 0x1000 /*I2C-like 
blk-xfer*/
+#define I2C_FUNC_SMBUS_WRITE_I2C_BLOCK_20x2000 /* w/ 2-byte 
regadr*/
+#define I2C_FUNC_SMBUS_READ_BLOCK_DATA_PEC  0x4000 /* SMBus 2.0 */
+#define I2C_FUNC_SMBUS_WRITE_BLOCK_DATA_PEC 0x8000 /* SMBus 2.0 */
+
+#define I2C_FUNC_SMBUS_BYTE (I2C_FUNC_SMBUS_READ_BYTE | \
+I2C_FUNC_SMBUS_WRITE_BYTE)
+#define I2C_FUNC_SMBUS_BYTE_DATA (I2C_FUNC_SMBUS_READ_BYTE_DATA | \
+I2C_FUNC_SMBUS_WRITE_BYTE_DATA)
+#define I2C_FUNC_SMBUS_WORD_DATA (I2C_FUNC_SMBUS_READ_WORD_DATA | \
+I2C_FUNC_SMBUS_WRITE_WORD_DATA)
+#define I2C_FUNC_SMBUS_BLOCK_DATA (I2C_FUNC_SMBUS_READ_BLOCK_DATA | \
+I2C_FUNC_SMBUS_WRITE_BLOCK_DATA)
+#define 

[Qemu-devel] [PULL 4/7] fpu: Replace uint32 typedef with uint32_t

2016-01-22 Thread Peter Maydell
Replace the uint32 softfloat-specific typedef with uint32_t.
This change was made with

find include hw fpu target-* -name '*.[ch]' | xargs sed -i -e 
's/\buint32\b/uint32_t/g'

together with manual removal of the typedef definition,
manual undoing of various mis-hits, and another couple of
fixes found via test compilation.

All the uses in hw/ were using the wrong type by mistake.

Signed-off-by: Peter Maydell 
Reviewed-by: Richard Henderson 
Reviewed-by: Aurelien Jarno 
Acked-by: Leon Alrae 
Acked-by: James Hogan 
Message-id: 1452603315-27030-5-git-send-email-peter.mayd...@linaro.org
---
 fpu/softfloat.c | 22 +++---
 hw/i386/pc.c|  2 +-
 hw/misc/imx25_ccm.c |  2 +-
 hw/misc/imx31_ccm.c |  2 +-
 hw/net/vmxnet3.c|  2 +-
 hw/ppc/spapr_events.c   |  4 ++--
 include/fpu/softfloat.h | 10 --
 include/hw/i386/pc.h|  2 +-
 tests/vhost-user-test.c |  2 +-
 9 files changed, 23 insertions(+), 25 deletions(-)

diff --git a/fpu/softfloat.c b/fpu/softfloat.c
index af3f82e..4ee98c4 100644
--- a/fpu/softfloat.c
+++ b/fpu/softfloat.c
@@ -1296,7 +1296,7 @@ float32 int32_to_float32(int32_t a, float_status *status)
 float64 int32_to_float64(int32_t a, float_status *status)
 {
 flag zSign;
-uint32 absA;
+uint32_t absA;
 int8 shiftCount;
 uint64_t zSig;
 
@@ -1319,7 +1319,7 @@ float64 int32_to_float64(int32_t a, float_status *status)
 floatx80 int32_to_floatx80(int32_t a, float_status *status)
 {
 flag zSign;
-uint32 absA;
+uint32_t absA;
 int8 shiftCount;
 uint64_t zSig;
 
@@ -1341,7 +1341,7 @@ floatx80 int32_to_floatx80(int32_t a, float_status 
*status)
 float128 int32_to_float128(int32_t a, float_status *status)
 {
 flag zSign;
-uint32 absA;
+uint32_t absA;
 int8 shiftCount;
 uint64_t zSig0;
 
@@ -7080,10 +7080,10 @@ float64 uint32_to_float64(uint32_t a, float_status 
*status)
 return int64_to_float64(a, status);
 }
 
-uint32 float32_to_uint32(float32 a, float_status *status)
+uint32_t float32_to_uint32(float32 a, float_status *status)
 {
 int64_t v;
-uint32 res;
+uint32_t res;
 int old_exc_flags = get_float_exception_flags(status);
 
 v = float32_to_int64(a, status);
@@ -7099,10 +7099,10 @@ uint32 float32_to_uint32(float32 a, float_status 
*status)
 return res;
 }
 
-uint32 float32_to_uint32_round_to_zero(float32 a, float_status *status)
+uint32_t float32_to_uint32_round_to_zero(float32 a, float_status *status)
 {
 int64_t v;
-uint32 res;
+uint32_t res;
 int old_exc_flags = get_float_exception_flags(status);
 
 v = float32_to_int64_round_to_zero(a, status);
@@ -7177,10 +7177,10 @@ uint_fast16_t float32_to_uint16_round_to_zero(float32 
a, float_status *status)
 return res;
 }
 
-uint32 float64_to_uint32(float64 a, float_status *status)
+uint32_t float64_to_uint32(float64 a, float_status *status)
 {
 uint64_t v;
-uint32 res;
+uint32_t res;
 int old_exc_flags = get_float_exception_flags(status);
 
 v = float64_to_uint64(a, status);
@@ -7194,10 +7194,10 @@ uint32 float64_to_uint32(float64 a, float_status 
*status)
 return res;
 }
 
-uint32 float64_to_uint32_round_to_zero(float64 a, float_status *status)
+uint32_t float64_to_uint32_round_to_zero(float64 a, float_status *status)
 {
 uint64_t v;
-uint32 res;
+uint32_t res;
 int old_exc_flags = get_float_exception_flags(status);
 
 v = float64_to_uint64_round_to_zero(a, status);
diff --git a/hw/i386/pc.c b/hw/i386/pc.c
index 293e22a..838636c 100644
--- a/hw/i386/pc.c
+++ b/hw/i386/pc.c
@@ -1454,7 +1454,7 @@ void pc_basic_device_init(ISABus *isa_bus, qemu_irq *gsi,
   ISADevice **rtc_state,
   bool create_fdctrl,
   bool no_vmport,
-  uint32 hpet_irqs)
+  uint32_t hpet_irqs)
 {
 int i;
 DriveInfo *fd[MAX_FD];
diff --git a/hw/misc/imx25_ccm.c b/hw/misc/imx25_ccm.c
index 23759ca..90752fd 100644
--- a/hw/misc/imx25_ccm.c
+++ b/hw/misc/imx25_ccm.c
@@ -249,7 +249,7 @@ static void imx25_ccm_reset(DeviceState *dev)
 
 static uint64_t imx25_ccm_read(void *opaque, hwaddr offset, unsigned size)
 {
-uint32 value = 0;
+uint32_t value = 0;
 IMX25CCMState *s = (IMX25CCMState *)opaque;
 
 if (offset < 0x70) {
diff --git a/hw/misc/imx31_ccm.c b/hw/misc/imx31_ccm.c
index 47d6ead..c47b96f 100644
--- a/hw/misc/imx31_ccm.c
+++ b/hw/misc/imx31_ccm.c
@@ -261,7 +261,7 @@ static void imx31_ccm_reset(DeviceState *dev)
 
 static uint64_t imx31_ccm_read(void *opaque, hwaddr offset, unsigned size)
 {
-uint32 value = 0;
+uint32_t value = 0;
 IMX31CCMState *s = (IMX31CCMState *)opaque;
 
 if ((offset >> 2) < IMX31_CCM_MAX_REG) {
diff --git a/hw/net/vmxnet3.c b/hw/net/vmxnet3.c
index 67abad3..5147f05 100644
--- 

[Qemu-devel] [PATCH v5 00/12] fdc: fix 2.88mb floppy diskette support

2016-01-22 Thread John Snow
Yes, it's been broken for ten years.
No, it's not a CVE.

The problem is that QEMU doesn't have a configuration option for the type
of floppy drive you want. It determines that based on the type of
diskette inserted at boot time.

If you don't insert one, it always chooses a 1.44MB type.

If you want to insert a 2.88MB floppy after boot, you simply cannot.

"Wow, who cares?"

Good question -- Unfortunately, the virtio-win floppy disk images that
Red Hat/Fedora ship require a 2.88MB drive, so if you forgot to insert
them at boot, you'd have to change your VM configuration and try again.

For a one-shot operation, that's kind of obnoxious -- it'd be nice to
allow one to just insert the diskette on-demand.

"OK, What are you changing in this decades-old device?"

(1) Add a new property to allow users to specify what kind of drive they
want without relying on magical guessing behavior.
Choices are: 120, 144, 288, auto, and none.

120, 144 and 288 refer to 1.20MB, 1.44MB, and 2.88MB drives.
auto refers to the auto-detect behavior QEMU currently has.
none ... hides the drive. You probably don't want to use this,
but it's there if you feel like creating a drive you can't use.

(2) Add a new "fallback" property for use with the "auto" drive type
that allows us to specify the backup behavior, too. In most cases
this property won't be needed, but it is provided for allowing
QEMU to be fully backwards compatible.

(3) Add the concept of physical diskette size to QEMU, classifying
120-style diskettes as fundamentally different from 144 and 288 ones.

(4) Revamp the automatic guessing heuristic to understand that
2.88MB style drives can accept 1.44MB diskettes.

(5) Change the automatic fallback type for the automatic guessing
heuristic from 1.44MB to 2.88MB for 2.6 machines and beyond,
leaving 2.5- machines set to default to auto/144.

(6) A lot of code cleanup in general.

"Won't this break everything, you madman?"

No: I tested this in MS-DOS 6.22, Fedora 23 and Windows 8.1. All
seemed perfectly happy with 2.88MB drives as the default for 1.44
or 2.88MB floppy diskette images.

And: Older machine types will happily still default to the 1.44
 type just like they used to, so really nothing should change
 at all for most guests.

If there ARE any guests affected in 2.6+ machine types, you are
urged to use an explicit drive type that matches your application
if the automatic behavior is unsuitable.

===
v5:
===

Nearly identical to v4.

Key:
[] : patches are identical
[] : number of functional differences between upstream/downstream patch
[down] : patch is downstream-only
The flags [FC] indicate (F)unctional and (C)ontextual differences, respectively

001/12:[] [--] 'fdc: move pick_geometry'
002/12:[] [--] 'fdc: reduce number of pick_geometry arguments'
003/12:[0002] [FC] 'fdc: add drive type qapi enum'
004/12:[] [--] 'fdc: add disk field'
005/12:[] [--] 'fdc: Throw an assertion on misconfigured fd_formats table'
006/12:[] [--] 'fdc: add pick_drive'
007/12:[] [--] 'fdc: Add fallback option'
008/12:[0002] [FC] 'fdc: add drive type option'
009/12:[0002] [FC] 'fdc: add physical disk sizes'
010/12:[0031] [FC] 'fdc: rework pick_geometry'
011/12:[] [--] 'qtest/fdc: Support for 2.88MB drives'
012/12:[] [--] 'fdc: change auto fallback drive for ISA FDC to 288'

03: Fixed 1.5MB typo to say 1.2MB.
08: Removed extraneous parentheses.
09: Fixed sector count comment to be 1440 instead of 1400.
10: Removed what was match type #3 and replaced it with a warning.
Updated some comments.

===
v4:
===

Hopefully a more logical patch order with smaller changes.

02: Kept both debug printfs in fd_revalidate.
03: New patch, QAPI enumeration change only.
04: Re-ordered FDrive fields
Fallout from 03.
05: New patch.
06: Almost completely re-done.
07: Added media_validated property
Fallout from patch re-ordering.
08: Re-ordered.
10: Changed return type of pick_geometry to int.
Changed one error pathway to abort, as it's not a run-time problem.
12: Rebased on top of current master.

===
v3:
===

04: Remove typeA/typeB members of FDCtrl. Store e.g. -fdtypeA options
   directly into FDCtrl.drives[x].drive instead.
05: Add a new fallback= option that controls fdtype{A,B}=auto behavior.
07: replace get_default_drive_type which is no longer needed
add get_fallback_drive_type.
09: Reworked the auto/fallback section of pick_geometry.



For convenience, this branch is available at:
https://github.com/jnsnow/qemu.git branch fdc-default
https://github.com/jnsnow/qemu/tree/fdc-default

This version is tagged fdc-default-v5:
https://github.com/jnsnow/qemu/releases/tag/fdc-default-v5

John Snow (12):
  fdc: move pick_geometry
  fdc: reduce number of pick_geometry arguments
  fdc: add drive type qapi enum
  fdc: add disk field
  fdc: Throw an assertion on 

[Qemu-devel] [PATCH v5 02/12] fdc: reduce number of pick_geometry arguments

2016-01-22 Thread John Snow
Modify this function to operate directly on FDrive objects instead of
unpacking and passing all of those parameters manually. Reduces the
complexity in the caller and reduces the number of args to just one.

Reviewed-by: Eric Blake 
Signed-off-by: John Snow 
---
 hw/block/fdc.c | 50 --
 1 file changed, 20 insertions(+), 30 deletions(-)

diff --git a/hw/block/fdc.c b/hw/block/fdc.c
index 71d931e..5505219 100644
--- a/hw/block/fdc.c
+++ b/hw/block/fdc.c
@@ -242,11 +242,9 @@ static void fd_recalibrate(FDrive *drv)
 fd_seek(drv, 0, 0, 1, 1);
 }
 
-static void pick_geometry(BlockBackend *blk, int *nb_heads,
-  int *max_track, int *last_sect,
-  FDriveType drive_in, FDriveType *drive,
-  FDriveRate *rate)
+static void pick_geometry(FDrive *drv)
 {
+BlockBackend *blk = drv->blk;
 const FDFormat *parse;
 uint64_t nb_sectors, size;
 int i, first_match, match;
@@ -259,8 +257,8 @@ static void pick_geometry(BlockBackend *blk, int *nb_heads,
 if (parse->drive == FDRIVE_DRV_NONE) {
 break;
 }
-if (drive_in == parse->drive ||
-drive_in == FDRIVE_DRV_NONE) {
+if (drv->drive == parse->drive ||
+drv->drive == FDRIVE_DRV_NONE) {
 size = (parse->max_head + 1) * parse->max_track *
 parse->last_sect;
 if (nb_sectors == size) {
@@ -280,41 +278,33 @@ static void pick_geometry(BlockBackend *blk, int 
*nb_heads,
 }
 parse = _formats[match];
 }
-*nb_heads = parse->max_head + 1;
-*max_track = parse->max_track;
-*last_sect = parse->last_sect;
-*drive = parse->drive;
-*rate = parse->rate;
+
+if (parse->max_head == 0) {
+drv->flags &= ~FDISK_DBL_SIDES;
+} else {
+drv->flags |= FDISK_DBL_SIDES;
+}
+drv->max_track = parse->max_track;
+drv->last_sect = parse->last_sect;
+drv->drive = parse->drive;
+drv->media_rate = parse->rate;
 }
 
 /* Revalidate a disk drive after a disk change */
 static void fd_revalidate(FDrive *drv)
 {
-int nb_heads, max_track, last_sect, ro;
-FDriveType drive;
-FDriveRate rate;
-
 FLOPPY_DPRINTF("revalidate\n");
 if (drv->blk != NULL) {
-ro = blk_is_read_only(drv->blk);
-pick_geometry(drv->blk, _heads, _track,
-  _sect, drv->drive, , );
+drv->ro = blk_is_read_only(drv->blk);
+pick_geometry(drv);
 if (!drv->media_inserted) {
 FLOPPY_DPRINTF("No disk in drive\n");
 } else {
-FLOPPY_DPRINTF("Floppy disk (%d h %d t %d s) %s\n", nb_heads,
-   max_track, last_sect, ro ? "ro" : "rw");
+FLOPPY_DPRINTF("Floppy disk (%d h %d t %d s) %s\n",
+   (drv->flags & FDISK_DBL_SIDES) ? 2 : 1,
+   drv->max_track, drv->last_sect,
+   drv->ro ? "ro" : "rw");
 }
-if (nb_heads == 1) {
-drv->flags &= ~FDISK_DBL_SIDES;
-} else {
-drv->flags |= FDISK_DBL_SIDES;
-}
-drv->max_track = max_track;
-drv->last_sect = last_sect;
-drv->ro = ro;
-drv->drive = drive;
-drv->media_rate = rate;
 } else {
 FLOPPY_DPRINTF("No drive connected\n");
 drv->last_sect = 0;
-- 
2.4.3




[Qemu-devel] [PATCH v5 09/12] fdc: add physical disk sizes

2016-01-22 Thread John Snow
2.88MB capable drives can accept 1.44MB floppies,
for instance. To rework the pick_geometry function,
we need to know if our current drive can even accept
the type of disks we're considering.

NB: This allows us to distinguish between all of the
"total sectors" collisions between 1.20MB and 1.44MB
diskette types, by using the physical drive size as a
differentiator.

Reviewed-by: Eric Blake 
Signed-off-by: John Snow 
---
 hw/block/fdc.c | 40 
 1 file changed, 32 insertions(+), 8 deletions(-)

diff --git a/hw/block/fdc.c b/hw/block/fdc.c
index e89ce2d..e51154b 100644
--- a/hw/block/fdc.c
+++ b/hw/block/fdc.c
@@ -60,6 +60,12 @@ typedef enum FDriveRate {
 FDRIVE_RATE_1M   = 0x03,  /*   1 Mbps */
 } FDriveRate;
 
+typedef enum FDriveSize {
+FDRIVE_SIZE_UNKNOWN,
+FDRIVE_SIZE_350,
+FDRIVE_SIZE_525,
+} FDriveSize;
+
 typedef struct FDFormat {
 FloppyDriveType drive;
 uint8_t last_sect;
@@ -68,11 +74,15 @@ typedef struct FDFormat {
 FDriveRate rate;
 } FDFormat;
 
+/* In many cases, the total sector size of a format is enough to uniquely
+ * identify it. However, there are some total sector collisions between
+ * formats of different physical size, and these are noted below by
+ * highlighting the total sector size for entries with collisions. */
 static const FDFormat fd_formats[] = {
 /* First entry is default format */
 /* 1.44 MB 3"1/2 floppy disks */
-{ FLOPPY_DRIVE_TYPE_144, 18, 80, 1, FDRIVE_RATE_500K, },
-{ FLOPPY_DRIVE_TYPE_144, 20, 80, 1, FDRIVE_RATE_500K, },
+{ FLOPPY_DRIVE_TYPE_144, 18, 80, 1, FDRIVE_RATE_500K, }, /* 3.5" 2880 */
+{ FLOPPY_DRIVE_TYPE_144, 20, 80, 1, FDRIVE_RATE_500K, }, /* 3.5" 3200 */
 { FLOPPY_DRIVE_TYPE_144, 21, 80, 1, FDRIVE_RATE_500K, },
 { FLOPPY_DRIVE_TYPE_144, 21, 82, 1, FDRIVE_RATE_500K, },
 { FLOPPY_DRIVE_TYPE_144, 21, 83, 1, FDRIVE_RATE_500K, },
@@ -86,7 +96,7 @@ static const FDFormat fd_formats[] = {
 { FLOPPY_DRIVE_TYPE_288, 44, 80, 1, FDRIVE_RATE_1M, },
 { FLOPPY_DRIVE_TYPE_288, 48, 80, 1, FDRIVE_RATE_1M, },
 /* 720 kB 3"1/2 floppy disks */
-{ FLOPPY_DRIVE_TYPE_144,  9, 80, 1, FDRIVE_RATE_250K, },
+{ FLOPPY_DRIVE_TYPE_144,  9, 80, 1, FDRIVE_RATE_250K, }, /* 3.5" 1440 */
 { FLOPPY_DRIVE_TYPE_144, 10, 80, 1, FDRIVE_RATE_250K, },
 { FLOPPY_DRIVE_TYPE_144, 10, 82, 1, FDRIVE_RATE_250K, },
 { FLOPPY_DRIVE_TYPE_144, 10, 83, 1, FDRIVE_RATE_250K, },
@@ -94,15 +104,15 @@ static const FDFormat fd_formats[] = {
 { FLOPPY_DRIVE_TYPE_144, 14, 80, 1, FDRIVE_RATE_250K, },
 /* 1.2 MB 5"1/4 floppy disks */
 { FLOPPY_DRIVE_TYPE_120, 15, 80, 1, FDRIVE_RATE_500K, },
-{ FLOPPY_DRIVE_TYPE_120, 18, 80, 1, FDRIVE_RATE_500K, },
+{ FLOPPY_DRIVE_TYPE_120, 18, 80, 1, FDRIVE_RATE_500K, }, /* 5.25" 2880 */
 { FLOPPY_DRIVE_TYPE_120, 18, 82, 1, FDRIVE_RATE_500K, },
 { FLOPPY_DRIVE_TYPE_120, 18, 83, 1, FDRIVE_RATE_500K, },
-{ FLOPPY_DRIVE_TYPE_120, 20, 80, 1, FDRIVE_RATE_500K, },
+{ FLOPPY_DRIVE_TYPE_120, 20, 80, 1, FDRIVE_RATE_500K, }, /* 5.25" 3200 */
 /* 720 kB 5"1/4 floppy disks */
-{ FLOPPY_DRIVE_TYPE_120,  9, 80, 1, FDRIVE_RATE_250K, },
+{ FLOPPY_DRIVE_TYPE_120,  9, 80, 1, FDRIVE_RATE_250K, }, /* 5.25" 1440 */
 { FLOPPY_DRIVE_TYPE_120, 11, 80, 1, FDRIVE_RATE_250K, },
 /* 360 kB 5"1/4 floppy disks */
-{ FLOPPY_DRIVE_TYPE_120,  9, 40, 1, FDRIVE_RATE_300K, },
+{ FLOPPY_DRIVE_TYPE_120,  9, 40, 1, FDRIVE_RATE_300K, }, /* 5.25" 720 */
 { FLOPPY_DRIVE_TYPE_120,  9, 40, 0, FDRIVE_RATE_300K, },
 { FLOPPY_DRIVE_TYPE_120, 10, 41, 1, FDRIVE_RATE_300K, },
 { FLOPPY_DRIVE_TYPE_120, 10, 42, 1, FDRIVE_RATE_300K, },
@@ -110,11 +120,25 @@ static const FDFormat fd_formats[] = {
 { FLOPPY_DRIVE_TYPE_120,  8, 40, 1, FDRIVE_RATE_250K, },
 { FLOPPY_DRIVE_TYPE_120,  8, 40, 0, FDRIVE_RATE_250K, },
 /* 360 kB must match 5"1/4 better than 3"1/2... */
-{ FLOPPY_DRIVE_TYPE_144,  9, 80, 0, FDRIVE_RATE_250K, },
+{ FLOPPY_DRIVE_TYPE_144,  9, 80, 0, FDRIVE_RATE_250K, }, /* 3.5" 720 */
 /* end */
 { FLOPPY_DRIVE_TYPE_NONE, -1, -1, 0, 0, },
 };
 
+__attribute__((__unused__))
+static FDriveSize drive_size(FloppyDriveType drive)
+{
+switch (drive) {
+case FLOPPY_DRIVE_TYPE_120:
+return FDRIVE_SIZE_525;
+case FLOPPY_DRIVE_TYPE_144:
+case FLOPPY_DRIVE_TYPE_288:
+return FDRIVE_SIZE_350;
+default:
+return FDRIVE_SIZE_UNKNOWN;
+}
+}
+
 #define GET_CUR_DRV(fdctrl) ((fdctrl)->cur_drv)
 #define SET_CUR_DRV(fdctrl, drive) ((fdctrl)->cur_drv = (drive))
 
-- 
2.4.3




Re: [Qemu-devel] [PATCH v5 10/12] fdc: rework pick_geometry

2016-01-22 Thread John Snow


On 01/22/2016 03:51 PM, John Snow wrote:
> This one is the crazy one.
> 
> fd_revalidate currently uses pick_geometry to tell if the diskette
> geometry has changed upon an eject/insert event, but it won't allow us
> to insert a 1.44MB diskette into a 2.88MB drive. This is inflexible.
> 
> The new algorithm applies a new heuristic to guessing disk geometries
> that allows us to switch diskette types as long as the physical size
> matches before falling back to the old heuristic.
> 
> The old one is roughly:
>  - If the size (sectors) and type matches, choose it.
>  - Fall back to the first geometry that matched our type.
> 
> The new one is:
>  - If the size (sectors) and type matches, choose it.
>  - If the size (sectors) and physical size match, choose it.
>  - If the size (sectors) matches at all, choose it begrudgingly.
>  - Fall back to the first geometry that matched our type.
> 

Goofed and didn't update commit. Will change on PULL to omit the third
line if the patch is otherwise OK.

> Signed-off-by: John Snow 
> ---
>  hw/block/fdc.c | 72 
> ++
>  1 file changed, 52 insertions(+), 20 deletions(-)
> 
> diff --git a/hw/block/fdc.c b/hw/block/fdc.c
> index e51154b..6e0c5fc 100644
> --- a/hw/block/fdc.c
> +++ b/hw/block/fdc.c
> @@ -125,7 +125,6 @@ static const FDFormat fd_formats[] = {
>  { FLOPPY_DRIVE_TYPE_NONE, -1, -1, 0, 0, },
>  };
>  
> -__attribute__((__unused__))
>  static FDriveSize drive_size(FloppyDriveType drive)
>  {
>  switch (drive) {
> @@ -284,45 +283,78 @@ static int pick_geometry(FDrive *drv)
>  BlockBackend *blk = drv->blk;
>  const FDFormat *parse;
>  uint64_t nb_sectors, size;
> -int i, first_match, match;
> +int i;
> +int match, size_match, type_match;
> +bool magic = drv->drive == FLOPPY_DRIVE_TYPE_AUTO;
>  
>  /* We can only pick a geometry if we have a diskette. */
>  if (!drv->media_inserted || drv->drive == FLOPPY_DRIVE_TYPE_NONE) {
>  return -1;
>  }
>  
> +/* We need to determine the likely geometry of the inserted medium.
> + * In order of preference, we look for:
> + * (1) The same drive type and number of sectors,
> + * (2) The same diskette size and number of sectors,
> + * (3) The same drive type.
> + *
> + * In all cases, matches that occur higher in the drive table will take
> + * precedence over matches that occur later in the table.
> + */
>  blk_get_geometry(blk, _sectors);
> -match = -1;
> -first_match = -1;
> +match = size_match = type_match = -1;
>  for (i = 0; ; i++) {
>  parse = _formats[i];
>  if (parse->drive == FLOPPY_DRIVE_TYPE_NONE) {
>  break;
>  }
> -if (drv->drive == parse->drive ||
> -drv->drive == FLOPPY_DRIVE_TYPE_AUTO) {
> -size = (parse->max_head + 1) * parse->max_track *
> -parse->last_sect;
> -if (nb_sectors == size) {
> -match = i;
> -break;
> +size = (parse->max_head + 1) * parse->max_track * parse->last_sect;
> +if (nb_sectors == size) {
> +if (magic || parse->drive == drv->drive) {
> +/* (1) perfect match -- nb_sectors and drive type */
> +goto out;
> +} else if (drive_size(parse->drive) == drive_size(drv->drive)) {
> +/* (2) size match -- nb_sectors and physical medium size */
> +match = (match == -1) ? i : match;
> +} else {
> +/* This is suspicious -- Did the user misconfigure? */
> +size_match = (size_match == -1) ? i : size_match;
>  }
> -if (first_match == -1) {
> -first_match = i;
> +} else if (type_match == -1) {
> +if ((parse->drive == drv->drive) ||
> +(magic && (parse->drive == get_fallback_drive_type(drv {
> +/* (3) type match -- nb_sectors mismatch, but matches the 
> type
> + * specified explicitly by the user, or matches the 
> fallback
> + * default type when using the drive autodetect 
> mechanism */
> +type_match = i;
>  }
>  }
>  }
> +
> +/* No exact match found */
>  if (match == -1) {
> -if (first_match == -1) {
> -error_setg(_abort, "No candidate geometries present in 
> table "
> -   " for floppy drive type '%s'",
> -   FloppyDriveType_lookup[drv->drive]);
> -} else {
> -match = first_match;
> +if (size_match != -1) {
> +parse = _formats[size_match];
> +FLOPPY_DPRINTF("User requested floppy drive type '%s', "
> +   "but inserted medium appears to be a "
> +   "%d sector '%s' type\n",
> +   

Re: [Qemu-devel] [PATCH v4] qom, qmp, hmp, qapi: create qom-type-prop-list for class properties

2016-01-22 Thread Valentin Rakush
Hi Eric, hi Daniel,

Re dashes in the command name

AFAICC, the QOM related command in HMP use dash "-". For example, qom-list
and qom-set. If we will change dash "-" to underscore "_" then
qom_type_prop_list will be consistent with old HMP commands (created before
year 2013), but will _not_ be consistent with QOM commands created after
2013. Which is not nice and may be misleading.

If we want to have consistent naming of all HMP commands, then we should
rename all QOM commands to replace "-" to "_". But in this case we can
brake compatibility in possible scripts that already use these commands.
For example, scripts/qmp/qom-fuse

I would leave name qom-type-prop-list with dashes, so it will be consistent
with other two QOM commands and would refactor all QOM commands names if
possible.

Re subcommand of the info command

Also from hmp-command.hx I can see that info command shows various
information about the _system_state_ The qom-type-prop-list shows
properties of the class type. They can be changed during runtime, but I am
not sure if they can be referred as a system state. From another side
command like "info class x86_64-cpu" could take less typing, but this will
be inconsistent with QMP version of the command.

For this reasons I would leave qom-type-prop-list as it is right now.

Daniel have reviewed this patch already but found my error in the
parameters of the HMP command. I have fixed this error and tested command
with monitor.  But would it be ok to add QMP and HMP tests to this patch?
Or may be submit tests with another patch, because this one is already
reviewed? I do not see much QMP/HMP tests so I am hesitating if this is a
good idea.

Thank you,
Valentin






On Fri, Jan 22, 2016 at 10:02 PM, Eric Blake  wrote:

> On 01/22/2016 05:15 AM, Valentin Rakush wrote:
> > This patch adds support for qom-type-prop-list command to list object
> > class properties. A later patch will use this functionality to
> > implement x86_64-cpu properties.
> >
> > Signed-off-by: Valentin Rakush 
> > Cc: Luiz Capitulino 
> > Cc: Eric Blake 
> > Cc: Markus Armbruster 
> > Cc: Andreas Färber 
> > Cc: Daniel P. Berrange 
> > ---
>
> > +++ b/hmp-commands.hx
> > @@ -1734,6 +1734,19 @@ Print QOM properties of object at location
> @var{path}
> >  ETEXI
> >
> >  {
> > +.name   = "qom-type-prop-list",
>
> To be consistent with most existing HMP commands, this should use
> qmp_type_prop_list (only the QMP version should use '-').
>
> For that matter, should this really be a new top-level command, or
> should it be a subcommand of the 'info' command?
>
> The QMP command looks fine, though.
>
> --
> Eric Blake   eblake redhat com+1-919-301-3266
> Libvirt virtualization library http://libvirt.org
>
>


-- 
Best Regards,
Valentin Rakush.


[Qemu-devel] [PATCH v5 01/12] fdc: move pick_geometry

2016-01-22 Thread John Snow
Code motion: I want to refactor this function to work with FDrive
directly, so shuffle it below that definition.

Reviewed-by: Eric Blake 
Signed-off-by: John Snow 
---
 hw/block/fdc.c | 90 +-
 1 file changed, 45 insertions(+), 45 deletions(-)

diff --git a/hw/block/fdc.c b/hw/block/fdc.c
index 6711c6a..71d931e 100644
--- a/hw/block/fdc.c
+++ b/hw/block/fdc.c
@@ -115,51 +115,6 @@ static const FDFormat fd_formats[] = {
 { FDRIVE_DRV_NONE, -1, -1, 0, 0, },
 };
 
-static void pick_geometry(BlockBackend *blk, int *nb_heads,
-  int *max_track, int *last_sect,
-  FDriveType drive_in, FDriveType *drive,
-  FDriveRate *rate)
-{
-const FDFormat *parse;
-uint64_t nb_sectors, size;
-int i, first_match, match;
-
-blk_get_geometry(blk, _sectors);
-match = -1;
-first_match = -1;
-for (i = 0; ; i++) {
-parse = _formats[i];
-if (parse->drive == FDRIVE_DRV_NONE) {
-break;
-}
-if (drive_in == parse->drive ||
-drive_in == FDRIVE_DRV_NONE) {
-size = (parse->max_head + 1) * parse->max_track *
-parse->last_sect;
-if (nb_sectors == size) {
-match = i;
-break;
-}
-if (first_match == -1) {
-first_match = i;
-}
-}
-}
-if (match == -1) {
-if (first_match == -1) {
-match = 1;
-} else {
-match = first_match;
-}
-parse = _formats[match];
-}
-*nb_heads = parse->max_head + 1;
-*max_track = parse->max_track;
-*last_sect = parse->last_sect;
-*drive = parse->drive;
-*rate = parse->rate;
-}
-
 #define GET_CUR_DRV(fdctrl) ((fdctrl)->cur_drv)
 #define SET_CUR_DRV(fdctrl, drive) ((fdctrl)->cur_drv = (drive))
 
@@ -287,6 +242,51 @@ static void fd_recalibrate(FDrive *drv)
 fd_seek(drv, 0, 0, 1, 1);
 }
 
+static void pick_geometry(BlockBackend *blk, int *nb_heads,
+  int *max_track, int *last_sect,
+  FDriveType drive_in, FDriveType *drive,
+  FDriveRate *rate)
+{
+const FDFormat *parse;
+uint64_t nb_sectors, size;
+int i, first_match, match;
+
+blk_get_geometry(blk, _sectors);
+match = -1;
+first_match = -1;
+for (i = 0; ; i++) {
+parse = _formats[i];
+if (parse->drive == FDRIVE_DRV_NONE) {
+break;
+}
+if (drive_in == parse->drive ||
+drive_in == FDRIVE_DRV_NONE) {
+size = (parse->max_head + 1) * parse->max_track *
+parse->last_sect;
+if (nb_sectors == size) {
+match = i;
+break;
+}
+if (first_match == -1) {
+first_match = i;
+}
+}
+}
+if (match == -1) {
+if (first_match == -1) {
+match = 1;
+} else {
+match = first_match;
+}
+parse = _formats[match];
+}
+*nb_heads = parse->max_head + 1;
+*max_track = parse->max_track;
+*last_sect = parse->last_sect;
+*drive = parse->drive;
+*rate = parse->rate;
+}
+
 /* Revalidate a disk drive after a disk change */
 static void fd_revalidate(FDrive *drv)
 {
-- 
2.4.3




[Qemu-devel] [PATCH v5 05/12] fdc: Throw an assertion on misconfigured fd_formats table

2016-01-22 Thread John Snow
pick_geometry is a convoluted function that makes it difficult to tell
at a glance what QEMU's current behavior for choosing a floppy drive
type is when it can't quite identify the diskette.

The code iterates over all entries in the candidate geometry table
("fd_formats") and if our specific drive type matches a row in the table,
then either "match" is set to that entry (an exact match) and the loop
exits, or "first_match" will be non-negative (the first such entry that
shares the same drive type), and the loop continues. If our specific
drive type is NONE, then all drive types in the candidate geometry table
are considered. After iteration, if "match" was not set, we fall back to
"first match".

This means that either "match" was set, or we exited the loop without an
exact match, in which case:

- If drive type is NONE, the default is truly fd_formats[0], a 1.44MB
  type, because "first_match" will always get set to the first item.

- If drive type is not NONE, pick_geometry's iteration was fussier and
  only looked at rows that matched our drive type. However, since all
  possible drive types are represented in the table, we still know that
  "first match" was set.

- If drive type is not NONE and the fd_formats table lists no options for
  our drive type, we choose fd_formats[1], an incomprehensibly bizarre
  choice that can never happen anyway.

Correct this: If first_match is -1, it can ONLY mean we didn't edit our
fd_formats table correctly. Throw an assertion instead.

Reviewed-by: Eric Blake 
Signed-off-by: John Snow 
---
 hw/block/fdc.c | 4 +++-
 1 file changed, 3 insertions(+), 1 deletion(-)

diff --git a/hw/block/fdc.c b/hw/block/fdc.c
index 18e363b..a8f0cf2 100644
--- a/hw/block/fdc.c
+++ b/hw/block/fdc.c
@@ -274,7 +274,9 @@ static void pick_geometry(FDrive *drv)
 }
 if (match == -1) {
 if (first_match == -1) {
-match = 1;
+error_setg(_abort, "No candidate geometries present in table 
"
+   " for floppy drive type '%s'",
+   FloppyDriveType_lookup[drv->drive]);
 } else {
 match = first_match;
 }
-- 
2.4.3




[Qemu-devel] [PATCH v5 12/12] fdc: change auto fallback drive for ISA FDC to 288

2016-01-22 Thread John Snow
The 2.88 drive is more suitable as a default because
it can still read 1.44 images correctly, but the reverse
is not true.

Since there exist virtio-win drivers that are shipped on
2.88 floppy images, this patch will allow VMs booted without
a floppy disk inserted to later insert a 2.88MB floppy and
have that work.

This patch has been tested with msdos, freedos, fedora,
windows 8 and windows 10 without issue: if problems do
arise for certain guests being unable to cope with 2.88MB
drives as the default, they are in the minority and can use
type=144 as needed (or insert a proper boot medium and omit
type=144/288 or use type=auto) to obtain different drive types.

As icing, the default will remain auto/144 for any pre-2.6
machine types, hopefully minimizing the impact of this change
in legacy hw to basically zero.

Reviewed-by: Eric Blake 
Signed-off-by: John Snow 
---
 hw/block/fdc.c  | 2 +-
 include/hw/compat.h | 4 
 2 files changed, 5 insertions(+), 1 deletion(-)

diff --git a/hw/block/fdc.c b/hw/block/fdc.c
index 6e0c5fc..e3b0e1e 100644
--- a/hw/block/fdc.c
+++ b/hw/block/fdc.c
@@ -2543,7 +2543,7 @@ static Property isa_fdc_properties[] = {
 FLOPPY_DRIVE_TYPE_AUTO, qdev_prop_fdc_drive_type,
 FloppyDriveType),
 DEFINE_PROP_DEFAULT("fallback", FDCtrlISABus, state.fallback,
-FLOPPY_DRIVE_TYPE_144, qdev_prop_fdc_drive_type,
+FLOPPY_DRIVE_TYPE_288, qdev_prop_fdc_drive_type,
 FloppyDriveType),
 DEFINE_PROP_END_OF_LIST(),
 };
diff --git a/include/hw/compat.h b/include/hw/compat.h
index 491884b..2ebe739 100644
--- a/include/hw/compat.h
+++ b/include/hw/compat.h
@@ -3,6 +3,10 @@
 
 #define HW_COMPAT_2_5 \
 {\
+.driver   = "isa-fdc",\
+.property = "fallback",\
+.value= "144",\
+},{\
 .driver   = "pvscsi",\
 .property = "x-old-pci-configuration",\
 .value= "on",\
-- 
2.4.3




[Qemu-devel] [PATCH v5 11/12] qtest/fdc: Support for 2.88MB drives

2016-01-22 Thread John Snow
The old test assumes a 1.44MB drive.
Assert that the QEMU default drive is now either 1.44 or 2.88.

Reviewed-by: Eric Blake 
Signed-off-by: John Snow 
---
 tests/fdc-test.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/tests/fdc-test.c b/tests/fdc-test.c
index b5a4696..526d459 100644
--- a/tests/fdc-test.c
+++ b/tests/fdc-test.c
@@ -267,7 +267,7 @@ static void test_cmos(void)
 uint8_t cmos;
 
 cmos = cmos_read(CMOS_FLOPPY);
-g_assert(cmos == 0x40);
+g_assert(cmos == 0x40 || cmos == 0x50);
 }
 
 static void test_no_media_on_start(void)
-- 
2.4.3




[Qemu-devel] [PATCH v5 06/12] fdc: add pick_drive

2016-01-22 Thread John Snow
Split apart pick_geometry by creating a pick_drive routine that will only
ever called during device bring-up instead of relying on pick_geometry to
be used in both cases.

With this change, the drive field is changed to be 'write once'. It is
not altered after the initialization routines exit.

media_validated does not need to be migrated. The target VM
will just revalidate the media on post_load anyway.

Reviewed-by: Eric Blake 
Signed-off-by: John Snow 
---
 hw/block/fdc.c | 56 ++--
 1 file changed, 46 insertions(+), 10 deletions(-)

diff --git a/hw/block/fdc.c b/hw/block/fdc.c
index a8f0cf2..f8e070e 100644
--- a/hw/block/fdc.c
+++ b/hw/block/fdc.c
@@ -151,6 +151,7 @@ typedef struct FDrive {
 uint8_t media_rate;   /* Data rate of medium*/
 
 bool media_inserted;  /* Is there a medium in the tray */
+bool media_validated; /* Have we validated the media? */
 } FDrive;
 
 static void fd_init(FDrive *drv)
@@ -162,6 +163,8 @@ static void fd_init(FDrive *drv)
 drv->disk = FLOPPY_DRIVE_TYPE_NONE;
 drv->last_sect = 0;
 drv->max_track = 0;
+drv->ro = true;
+drv->media_changed = 1;
 }
 
 #define NUM_SIDES(drv) ((drv)->flags & FDISK_DBL_SIDES ? 2 : 1)
@@ -244,13 +247,24 @@ static void fd_recalibrate(FDrive *drv)
 fd_seek(drv, 0, 0, 1, 1);
 }
 
-static void pick_geometry(FDrive *drv)
+/**
+ * Determine geometry based on inserted diskette.
+ * Will not operate on an empty drive.
+ *
+ * @return: 0 on success, -1 if the drive is empty.
+ */
+static int pick_geometry(FDrive *drv)
 {
 BlockBackend *blk = drv->blk;
 const FDFormat *parse;
 uint64_t nb_sectors, size;
 int i, first_match, match;
 
+/* We can only pick a geometry if we have a diskette. */
+if (!drv->media_inserted) {
+return -1;
+}
+
 blk_get_geometry(blk, _sectors);
 match = -1;
 first_match = -1;
@@ -290,31 +304,51 @@ static void pick_geometry(FDrive *drv)
 }
 drv->max_track = parse->max_track;
 drv->last_sect = parse->last_sect;
-drv->drive = parse->drive;
-drv->disk = drv->media_inserted ? parse->drive : FLOPPY_DRIVE_TYPE_NONE;
+drv->disk = parse->drive;
 drv->media_rate = parse->rate;
+return 0;
+}
+
+static void pick_drive_type(FDrive *drv)
+{
+if (pick_geometry(drv) == 0) {
+drv->drive = drv->disk;
+} else {
+/* Legacy behavior: default to 1.44MB floppy */
+drv->drive = FLOPPY_DRIVE_TYPE_144;
+}
 }
 
 /* Revalidate a disk drive after a disk change */
 static void fd_revalidate(FDrive *drv)
 {
+int rc;
+
 FLOPPY_DPRINTF("revalidate\n");
 if (drv->blk != NULL) {
 drv->ro = blk_is_read_only(drv->blk);
-pick_geometry(drv);
 if (!drv->media_inserted) {
 FLOPPY_DPRINTF("No disk in drive\n");
-} else {
-FLOPPY_DPRINTF("Floppy disk (%d h %d t %d s) %s\n",
-   (drv->flags & FDISK_DBL_SIDES) ? 2 : 1,
-   drv->max_track, drv->last_sect,
-   drv->ro ? "ro" : "rw");
+drv->disk = FLOPPY_DRIVE_TYPE_NONE;
+} else if (!drv->media_validated) {
+rc = pick_geometry(drv);
+if (rc) {
+FLOPPY_DPRINTF("Could not validate floppy drive media");
+} else {
+drv->media_validated = true;
+FLOPPY_DPRINTF("Floppy disk (%d h %d t %d s) %s\n",
+   (drv->flags & FDISK_DBL_SIDES) ? 2 : 1,
+   drv->max_track, drv->last_sect,
+   drv->ro ? "ro" : "rw");
+}
 }
 } else {
 FLOPPY_DPRINTF("No drive connected\n");
 drv->last_sect = 0;
 drv->max_track = 0;
 drv->flags &= ~FDISK_DBL_SIDES;
+drv->drive = FLOPPY_DRIVE_TYPE_NONE;
+drv->disk = FLOPPY_DRIVE_TYPE_NONE;
 }
 }
 
@@ -2185,6 +2219,7 @@ static void fdctrl_change_cb(void *opaque, bool load)
 drive->media_inserted = load && drive->blk && blk_is_inserted(drive->blk);
 
 drive->media_changed = 1;
+drive->media_validated = false;
 fd_revalidate(drive);
 }
 
@@ -2221,11 +2256,12 @@ static void fdctrl_connect_drives(FDCtrl *fdctrl, Error 
**errp)
 }
 
 fd_init(drive);
-fdctrl_change_cb(drive, 0);
 if (drive->blk) {
 blk_set_dev_ops(drive->blk, _block_ops, drive);
 drive->media_inserted = blk_is_inserted(drive->blk);
+pick_drive_type(drive);
 }
+fd_revalidate(drive);
 }
 }
 
-- 
2.4.3




[Qemu-devel] [PATCH v5 07/12] fdc: Add fallback option

2016-01-22 Thread John Snow
Currently, QEMU chooses a drive type automatically based on the inserted
media. If there is no disk inserted, it chooses a 1.44MB drive type.

Change this behavior to be configurable, but leave it defaulted to 1.44.

This is not earnestly intended to be used by a user or a management
library, but rather exists so that pre-2.6 board types can configure it
to be a legacy value.

Reviewed-by: Eric Blake 
Signed-off-by: John Snow 
---
 hw/block/fdc.c   | 25 +++--
 hw/core/qdev-properties.c| 11 +++
 include/hw/qdev-properties.h |  1 +
 3 files changed, 35 insertions(+), 2 deletions(-)

diff --git a/hw/block/fdc.c b/hw/block/fdc.c
index f8e070e..4caed9b 100644
--- a/hw/block/fdc.c
+++ b/hw/block/fdc.c
@@ -154,6 +154,9 @@ typedef struct FDrive {
 bool media_validated; /* Have we validated the media? */
 } FDrive;
 
+
+static FloppyDriveType get_fallback_drive_type(FDrive *drv);
+
 static void fd_init(FDrive *drv)
 {
 /* Drive */
@@ -314,8 +317,7 @@ static void pick_drive_type(FDrive *drv)
 if (pick_geometry(drv) == 0) {
 drv->drive = drv->disk;
 } else {
-/* Legacy behavior: default to 1.44MB floppy */
-drv->drive = FLOPPY_DRIVE_TYPE_144;
+drv->drive = get_fallback_drive_type(drv);
 }
 }
 
@@ -598,11 +600,17 @@ struct FDCtrl {
 FDrive drives[MAX_FD];
 int reset_sensei;
 uint32_t check_media_rate;
+FloppyDriveType fallback; /* type=auto failure fallback */
 /* Timers state */
 uint8_t timer0;
 uint8_t timer1;
 };
 
+static FloppyDriveType get_fallback_drive_type(FDrive *drv)
+{
+return drv->fdctrl->fallback;
+}
+
 #define TYPE_SYSBUS_FDC "base-sysbus-fdc"
 #define SYSBUS_FDC(obj) OBJECT_CHECK(FDCtrlSysBus, (obj), TYPE_SYSBUS_FDC)
 
@@ -2338,6 +2346,10 @@ static void fdctrl_realize_common(FDCtrl *fdctrl, Error 
**errp)
 int i, j;
 static int command_tables_inited = 0;
 
+if (fdctrl->fallback == FLOPPY_DRIVE_TYPE_AUTO) {
+error_setg(errp, "Cannot choose a fallback FDrive type of 'auto'");
+}
+
 /* Fill 'command_to_handler' lookup table */
 if (!command_tables_inited) {
 command_tables_inited = 1;
@@ -2463,6 +2475,9 @@ static Property isa_fdc_properties[] = {
 DEFINE_PROP_DRIVE("driveB", FDCtrlISABus, state.drives[1].blk),
 DEFINE_PROP_BIT("check_media_rate", FDCtrlISABus, state.check_media_rate,
 0, true),
+DEFINE_PROP_DEFAULT("fallback", FDCtrlISABus, state.fallback,
+FLOPPY_DRIVE_TYPE_144, qdev_prop_fdc_drive_type,
+FloppyDriveType),
 DEFINE_PROP_END_OF_LIST(),
 };
 
@@ -2511,6 +2526,9 @@ static const VMStateDescription vmstate_sysbus_fdc ={
 static Property sysbus_fdc_properties[] = {
 DEFINE_PROP_DRIVE("driveA", FDCtrlSysBus, state.drives[0].blk),
 DEFINE_PROP_DRIVE("driveB", FDCtrlSysBus, state.drives[1].blk),
+DEFINE_PROP_DEFAULT("fallback", FDCtrlISABus, state.fallback,
+FLOPPY_DRIVE_TYPE_144, qdev_prop_fdc_drive_type,
+FloppyDriveType),
 DEFINE_PROP_END_OF_LIST(),
 };
 
@@ -2531,6 +2549,9 @@ static const TypeInfo sysbus_fdc_info = {
 
 static Property sun4m_fdc_properties[] = {
 DEFINE_PROP_DRIVE("drive", FDCtrlSysBus, state.drives[0].blk),
+DEFINE_PROP_DEFAULT("fallback", FDCtrlISABus, state.fallback,
+FLOPPY_DRIVE_TYPE_144, qdev_prop_fdc_drive_type,
+FloppyDriveType),
 DEFINE_PROP_END_OF_LIST(),
 };
 
diff --git a/hw/core/qdev-properties.c b/hw/core/qdev-properties.c
index 3572810..aacad66 100644
--- a/hw/core/qdev-properties.c
+++ b/hw/core/qdev-properties.c
@@ -541,6 +541,17 @@ PropertyInfo qdev_prop_bios_chs_trans = {
 .set = set_enum,
 };
 
+/* --- FDC default drive types */
+
+PropertyInfo qdev_prop_fdc_drive_type = {
+.name = "FdcDriveType",
+.description = "FDC drive type, "
+   "144/288/120/none/auto",
+.enum_table = FloppyDriveType_lookup,
+.get = get_enum,
+.set = set_enum
+};
+
 /* --- pci address --- */
 
 /*
diff --git a/include/hw/qdev-properties.h b/include/hw/qdev-properties.h
index 254afd8..03a1b91 100644
--- a/include/hw/qdev-properties.h
+++ b/include/hw/qdev-properties.h
@@ -20,6 +20,7 @@ extern PropertyInfo qdev_prop_ptr;
 extern PropertyInfo qdev_prop_macaddr;
 extern PropertyInfo qdev_prop_losttickpolicy;
 extern PropertyInfo qdev_prop_bios_chs_trans;
+extern PropertyInfo qdev_prop_fdc_drive_type;
 extern PropertyInfo qdev_prop_drive;
 extern PropertyInfo qdev_prop_netdev;
 extern PropertyInfo qdev_prop_vlan;
-- 
2.4.3




Re: [Qemu-devel] [PATCH v9 2/3] quorum: implement bdrv_add_child() and bdrv_del_child()

2016-01-22 Thread Dr. David Alan Gilbert
* Alberto Garcia (be...@igalia.com) wrote:
> On Thu 21 Jan 2016 05:58:42 PM CET, Eric Blake  wrote:
>  In general, what do you do to make sure that the data in a new Quorum
>  child is consistent with that of the rest of the array?
> >>>
> >>> Quorum can have more than one child when it starts. But we don't do
> >>> the similar check. So I don't think we should do such check here.
> >> 
> >> Yes, but when you start a VM you can verify in advance that all
> >> members of the Quorum have the same data. If you do that on a running
> >> VM how can you know if the new disk is consistent with the others?
> >
> > User error if it is not.  Just the same as it is user error if you
> > request a shallow drive-mirror but the destination is not the same
> > contents as the backing file.  I don't think qemu has to protect us
> > from user error in this case.
> 
> But the backing file is read-only so the user can guarantee that the
> destination has the same data before the shallow mirror. How do you do
> that in this case?

I think in the colo case they're relying on doing a block migrate
to synchronise the remote disk prior to switching into colo mode.

Dave

> Berto
--
Dr. David Alan Gilbert / dgilb...@redhat.com / Manchester, UK



[Qemu-devel] [PATCH v5 03/12] fdc: add drive type qapi enum

2016-01-22 Thread John Snow
Change the floppy drive type to a QAPI enum type, to allow us to
specify the floppy drive type from the CLI in a forthcoming patch.

Reviewed-by: Eric Blake 
Signed-off-by: John Snow 
---
 hw/block/fdc.c | 80 +-
 hw/i386/pc.c   | 17 ++-
 include/hw/block/fdc.h |  9 +-
 qapi/block.json| 16 ++
 4 files changed, 66 insertions(+), 56 deletions(-)

diff --git a/hw/block/fdc.c b/hw/block/fdc.c
index 5505219..e37934d 100644
--- a/hw/block/fdc.c
+++ b/hw/block/fdc.c
@@ -61,7 +61,7 @@ typedef enum FDriveRate {
 } FDriveRate;
 
 typedef struct FDFormat {
-FDriveType drive;
+FloppyDriveType drive;
 uint8_t last_sect;
 uint8_t max_track;
 uint8_t max_head;
@@ -71,48 +71,48 @@ typedef struct FDFormat {
 static const FDFormat fd_formats[] = {
 /* First entry is default format */
 /* 1.44 MB 3"1/2 floppy disks */
-{ FDRIVE_DRV_144, 18, 80, 1, FDRIVE_RATE_500K, },
-{ FDRIVE_DRV_144, 20, 80, 1, FDRIVE_RATE_500K, },
-{ FDRIVE_DRV_144, 21, 80, 1, FDRIVE_RATE_500K, },
-{ FDRIVE_DRV_144, 21, 82, 1, FDRIVE_RATE_500K, },
-{ FDRIVE_DRV_144, 21, 83, 1, FDRIVE_RATE_500K, },
-{ FDRIVE_DRV_144, 22, 80, 1, FDRIVE_RATE_500K, },
-{ FDRIVE_DRV_144, 23, 80, 1, FDRIVE_RATE_500K, },
-{ FDRIVE_DRV_144, 24, 80, 1, FDRIVE_RATE_500K, },
+{ FLOPPY_DRIVE_TYPE_144, 18, 80, 1, FDRIVE_RATE_500K, },
+{ FLOPPY_DRIVE_TYPE_144, 20, 80, 1, FDRIVE_RATE_500K, },
+{ FLOPPY_DRIVE_TYPE_144, 21, 80, 1, FDRIVE_RATE_500K, },
+{ FLOPPY_DRIVE_TYPE_144, 21, 82, 1, FDRIVE_RATE_500K, },
+{ FLOPPY_DRIVE_TYPE_144, 21, 83, 1, FDRIVE_RATE_500K, },
+{ FLOPPY_DRIVE_TYPE_144, 22, 80, 1, FDRIVE_RATE_500K, },
+{ FLOPPY_DRIVE_TYPE_144, 23, 80, 1, FDRIVE_RATE_500K, },
+{ FLOPPY_DRIVE_TYPE_144, 24, 80, 1, FDRIVE_RATE_500K, },
 /* 2.88 MB 3"1/2 floppy disks */
-{ FDRIVE_DRV_288, 36, 80, 1, FDRIVE_RATE_1M, },
-{ FDRIVE_DRV_288, 39, 80, 1, FDRIVE_RATE_1M, },
-{ FDRIVE_DRV_288, 40, 80, 1, FDRIVE_RATE_1M, },
-{ FDRIVE_DRV_288, 44, 80, 1, FDRIVE_RATE_1M, },
-{ FDRIVE_DRV_288, 48, 80, 1, FDRIVE_RATE_1M, },
+{ FLOPPY_DRIVE_TYPE_288, 36, 80, 1, FDRIVE_RATE_1M, },
+{ FLOPPY_DRIVE_TYPE_288, 39, 80, 1, FDRIVE_RATE_1M, },
+{ FLOPPY_DRIVE_TYPE_288, 40, 80, 1, FDRIVE_RATE_1M, },
+{ FLOPPY_DRIVE_TYPE_288, 44, 80, 1, FDRIVE_RATE_1M, },
+{ FLOPPY_DRIVE_TYPE_288, 48, 80, 1, FDRIVE_RATE_1M, },
 /* 720 kB 3"1/2 floppy disks */
-{ FDRIVE_DRV_144,  9, 80, 1, FDRIVE_RATE_250K, },
-{ FDRIVE_DRV_144, 10, 80, 1, FDRIVE_RATE_250K, },
-{ FDRIVE_DRV_144, 10, 82, 1, FDRIVE_RATE_250K, },
-{ FDRIVE_DRV_144, 10, 83, 1, FDRIVE_RATE_250K, },
-{ FDRIVE_DRV_144, 13, 80, 1, FDRIVE_RATE_250K, },
-{ FDRIVE_DRV_144, 14, 80, 1, FDRIVE_RATE_250K, },
+{ FLOPPY_DRIVE_TYPE_144,  9, 80, 1, FDRIVE_RATE_250K, },
+{ FLOPPY_DRIVE_TYPE_144, 10, 80, 1, FDRIVE_RATE_250K, },
+{ FLOPPY_DRIVE_TYPE_144, 10, 82, 1, FDRIVE_RATE_250K, },
+{ FLOPPY_DRIVE_TYPE_144, 10, 83, 1, FDRIVE_RATE_250K, },
+{ FLOPPY_DRIVE_TYPE_144, 13, 80, 1, FDRIVE_RATE_250K, },
+{ FLOPPY_DRIVE_TYPE_144, 14, 80, 1, FDRIVE_RATE_250K, },
 /* 1.2 MB 5"1/4 floppy disks */
-{ FDRIVE_DRV_120, 15, 80, 1, FDRIVE_RATE_500K, },
-{ FDRIVE_DRV_120, 18, 80, 1, FDRIVE_RATE_500K, },
-{ FDRIVE_DRV_120, 18, 82, 1, FDRIVE_RATE_500K, },
-{ FDRIVE_DRV_120, 18, 83, 1, FDRIVE_RATE_500K, },
-{ FDRIVE_DRV_120, 20, 80, 1, FDRIVE_RATE_500K, },
+{ FLOPPY_DRIVE_TYPE_120, 15, 80, 1, FDRIVE_RATE_500K, },
+{ FLOPPY_DRIVE_TYPE_120, 18, 80, 1, FDRIVE_RATE_500K, },
+{ FLOPPY_DRIVE_TYPE_120, 18, 82, 1, FDRIVE_RATE_500K, },
+{ FLOPPY_DRIVE_TYPE_120, 18, 83, 1, FDRIVE_RATE_500K, },
+{ FLOPPY_DRIVE_TYPE_120, 20, 80, 1, FDRIVE_RATE_500K, },
 /* 720 kB 5"1/4 floppy disks */
-{ FDRIVE_DRV_120,  9, 80, 1, FDRIVE_RATE_250K, },
-{ FDRIVE_DRV_120, 11, 80, 1, FDRIVE_RATE_250K, },
+{ FLOPPY_DRIVE_TYPE_120,  9, 80, 1, FDRIVE_RATE_250K, },
+{ FLOPPY_DRIVE_TYPE_120, 11, 80, 1, FDRIVE_RATE_250K, },
 /* 360 kB 5"1/4 floppy disks */
-{ FDRIVE_DRV_120,  9, 40, 1, FDRIVE_RATE_300K, },
-{ FDRIVE_DRV_120,  9, 40, 0, FDRIVE_RATE_300K, },
-{ FDRIVE_DRV_120, 10, 41, 1, FDRIVE_RATE_300K, },
-{ FDRIVE_DRV_120, 10, 42, 1, FDRIVE_RATE_300K, },
+{ FLOPPY_DRIVE_TYPE_120,  9, 40, 1, FDRIVE_RATE_300K, },
+{ FLOPPY_DRIVE_TYPE_120,  9, 40, 0, FDRIVE_RATE_300K, },
+{ FLOPPY_DRIVE_TYPE_120, 10, 41, 1, FDRIVE_RATE_300K, },
+{ FLOPPY_DRIVE_TYPE_120, 10, 42, 1, FDRIVE_RATE_300K, },
 /* 320 kB 5"1/4 floppy disks */
-{ FDRIVE_DRV_120,  8, 40, 1, FDRIVE_RATE_250K, },
-{ FDRIVE_DRV_120,  8, 40, 0, FDRIVE_RATE_250K, },
+{ FLOPPY_DRIVE_TYPE_120,  8, 40, 1, FDRIVE_RATE_250K, },
+{ FLOPPY_DRIVE_TYPE_120,  8, 40, 0, FDRIVE_RATE_250K, },
 /* 360 kB must match 5"1/4 better than 3"1/2... */
-{ FDRIVE_DRV_144,  9, 

[Qemu-devel] [PATCH v5 04/12] fdc: add disk field

2016-01-22 Thread John Snow
Currently, 'drive' is used both to represent the current diskette
type as well as the current drive type.

This patch adds a 'disk' field that is updated explicitly to match
the type of the disk.

As of this patch, disk and drive are always the same, but forthcoming
patches to change the behavior of pick_geometry will invalidate this
assumption.

disk does not need to be migrated because it is not user-visible state
nor is it currently used for any calculations. It is purely informative,
and will be rebuilt automatically via fd_revalidate on the new host.

Reviewed-by: Eric Blake 
Signed-off-by: John Snow 
---
 hw/block/fdc.c | 3 +++
 1 file changed, 3 insertions(+)

diff --git a/hw/block/fdc.c b/hw/block/fdc.c
index e37934d..18e363b 100644
--- a/hw/block/fdc.c
+++ b/hw/block/fdc.c
@@ -141,6 +141,7 @@ typedef struct FDrive {
 uint8_t track;
 uint8_t sect;
 /* Media */
+FloppyDriveType disk; /* Current disk type  */
 FDiskFlags flags;
 uint8_t last_sect;/* Nb sector per track*/
 uint8_t max_track;/* Nb of tracks   */
@@ -158,6 +159,7 @@ static void fd_init(FDrive *drv)
 drv->drive = FLOPPY_DRIVE_TYPE_NONE;
 drv->perpendicular = 0;
 /* Disk */
+drv->disk = FLOPPY_DRIVE_TYPE_NONE;
 drv->last_sect = 0;
 drv->max_track = 0;
 }
@@ -287,6 +289,7 @@ static void pick_geometry(FDrive *drv)
 drv->max_track = parse->max_track;
 drv->last_sect = parse->last_sect;
 drv->drive = parse->drive;
+drv->disk = drv->media_inserted ? parse->drive : FLOPPY_DRIVE_TYPE_NONE;
 drv->media_rate = parse->rate;
 }
 
-- 
2.4.3




[Qemu-devel] [PATCH v5 08/12] fdc: add drive type option

2016-01-22 Thread John Snow
This patch adds a new explicit Floppy Drive Type option. The existing
behavior in QEMU is to automatically guess a drive type based on the
media inserted, or if a diskette is not present, arbitrarily assign one.

This behavior can be described as "auto." This patch adds the option
to pick an explicit behavior: 120, 144, 288 or none. The new "auto"
option is intended to mimic current behavior, while the other types
pick one explicitly.

Set the type given by the CLI during fd_init. If the type remains the
default (auto), we'll attempt to scan an inserted diskette if present
to determine a type. If auto is selected but no diskette is present,
we fall back to a predetermined default (currently 1.44MB to match
legacy QEMU behavior.)

Reviewed-by: Eric Blake 
Signed-off-by: John Snow 
---
 hw/block/fdc.c | 26 +++---
 1 file changed, 23 insertions(+), 3 deletions(-)

diff --git a/hw/block/fdc.c b/hw/block/fdc.c
index 4caed9b..e89ce2d 100644
--- a/hw/block/fdc.c
+++ b/hw/block/fdc.c
@@ -160,7 +160,6 @@ static FloppyDriveType get_fallback_drive_type(FDrive *drv);
 static void fd_init(FDrive *drv)
 {
 /* Drive */
-drv->drive = FLOPPY_DRIVE_TYPE_NONE;
 drv->perpendicular = 0;
 /* Disk */
 drv->disk = FLOPPY_DRIVE_TYPE_NONE;
@@ -264,7 +263,7 @@ static int pick_geometry(FDrive *drv)
 int i, first_match, match;
 
 /* We can only pick a geometry if we have a diskette. */
-if (!drv->media_inserted) {
+if (!drv->media_inserted || drv->drive == FLOPPY_DRIVE_TYPE_NONE) {
 return -1;
 }
 
@@ -277,7 +276,7 @@ static int pick_geometry(FDrive *drv)
 break;
 }
 if (drv->drive == parse->drive ||
-drv->drive == FLOPPY_DRIVE_TYPE_NONE) {
+drv->drive == FLOPPY_DRIVE_TYPE_AUTO) {
 size = (parse->max_head + 1) * parse->max_track *
 parse->last_sect;
 if (nb_sectors == size) {
@@ -314,11 +313,17 @@ static int pick_geometry(FDrive *drv)
 
 static void pick_drive_type(FDrive *drv)
 {
+if (drv->drive != FLOPPY_DRIVE_TYPE_AUTO) {
+return;
+}
+
 if (pick_geometry(drv) == 0) {
 drv->drive = drv->disk;
 } else {
 drv->drive = get_fallback_drive_type(drv);
 }
+
+g_assert(drv->drive != FLOPPY_DRIVE_TYPE_AUTO);
 }
 
 /* Revalidate a disk drive after a disk change */
@@ -2475,6 +2480,12 @@ static Property isa_fdc_properties[] = {
 DEFINE_PROP_DRIVE("driveB", FDCtrlISABus, state.drives[1].blk),
 DEFINE_PROP_BIT("check_media_rate", FDCtrlISABus, state.check_media_rate,
 0, true),
+DEFINE_PROP_DEFAULT("fdtypeA", FDCtrlISABus, state.drives[0].drive,
+FLOPPY_DRIVE_TYPE_AUTO, qdev_prop_fdc_drive_type,
+FloppyDriveType),
+DEFINE_PROP_DEFAULT("fdtypeB", FDCtrlISABus, state.drives[1].drive,
+FLOPPY_DRIVE_TYPE_AUTO, qdev_prop_fdc_drive_type,
+FloppyDriveType),
 DEFINE_PROP_DEFAULT("fallback", FDCtrlISABus, state.fallback,
 FLOPPY_DRIVE_TYPE_144, qdev_prop_fdc_drive_type,
 FloppyDriveType),
@@ -2526,6 +2537,12 @@ static const VMStateDescription vmstate_sysbus_fdc ={
 static Property sysbus_fdc_properties[] = {
 DEFINE_PROP_DRIVE("driveA", FDCtrlSysBus, state.drives[0].blk),
 DEFINE_PROP_DRIVE("driveB", FDCtrlSysBus, state.drives[1].blk),
+DEFINE_PROP_DEFAULT("fdtypeA", FDCtrlSysBus, state.drives[0].drive,
+FLOPPY_DRIVE_TYPE_AUTO, qdev_prop_fdc_drive_type,
+FloppyDriveType),
+DEFINE_PROP_DEFAULT("fdtypeB", FDCtrlSysBus, state.drives[1].drive,
+FLOPPY_DRIVE_TYPE_AUTO, qdev_prop_fdc_drive_type,
+FloppyDriveType),
 DEFINE_PROP_DEFAULT("fallback", FDCtrlISABus, state.fallback,
 FLOPPY_DRIVE_TYPE_144, qdev_prop_fdc_drive_type,
 FloppyDriveType),
@@ -2549,6 +2566,9 @@ static const TypeInfo sysbus_fdc_info = {
 
 static Property sun4m_fdc_properties[] = {
 DEFINE_PROP_DRIVE("drive", FDCtrlSysBus, state.drives[0].blk),
+DEFINE_PROP_DEFAULT("fdtype", FDCtrlSysBus, state.drives[0].drive,
+FLOPPY_DRIVE_TYPE_AUTO, qdev_prop_fdc_drive_type,
+FloppyDriveType),
 DEFINE_PROP_DEFAULT("fallback", FDCtrlISABus, state.fallback,
 FLOPPY_DRIVE_TYPE_144, qdev_prop_fdc_drive_type,
 FloppyDriveType),
-- 
2.4.3




[Qemu-devel] [PATCH v5 10/12] fdc: rework pick_geometry

2016-01-22 Thread John Snow
This one is the crazy one.

fd_revalidate currently uses pick_geometry to tell if the diskette
geometry has changed upon an eject/insert event, but it won't allow us
to insert a 1.44MB diskette into a 2.88MB drive. This is inflexible.

The new algorithm applies a new heuristic to guessing disk geometries
that allows us to switch diskette types as long as the physical size
matches before falling back to the old heuristic.

The old one is roughly:
 - If the size (sectors) and type matches, choose it.
 - Fall back to the first geometry that matched our type.

The new one is:
 - If the size (sectors) and type matches, choose it.
 - If the size (sectors) and physical size match, choose it.
 - If the size (sectors) matches at all, choose it begrudgingly.
 - Fall back to the first geometry that matched our type.

Signed-off-by: John Snow 
---
 hw/block/fdc.c | 72 ++
 1 file changed, 52 insertions(+), 20 deletions(-)

diff --git a/hw/block/fdc.c b/hw/block/fdc.c
index e51154b..6e0c5fc 100644
--- a/hw/block/fdc.c
+++ b/hw/block/fdc.c
@@ -125,7 +125,6 @@ static const FDFormat fd_formats[] = {
 { FLOPPY_DRIVE_TYPE_NONE, -1, -1, 0, 0, },
 };
 
-__attribute__((__unused__))
 static FDriveSize drive_size(FloppyDriveType drive)
 {
 switch (drive) {
@@ -284,45 +283,78 @@ static int pick_geometry(FDrive *drv)
 BlockBackend *blk = drv->blk;
 const FDFormat *parse;
 uint64_t nb_sectors, size;
-int i, first_match, match;
+int i;
+int match, size_match, type_match;
+bool magic = drv->drive == FLOPPY_DRIVE_TYPE_AUTO;
 
 /* We can only pick a geometry if we have a diskette. */
 if (!drv->media_inserted || drv->drive == FLOPPY_DRIVE_TYPE_NONE) {
 return -1;
 }
 
+/* We need to determine the likely geometry of the inserted medium.
+ * In order of preference, we look for:
+ * (1) The same drive type and number of sectors,
+ * (2) The same diskette size and number of sectors,
+ * (3) The same drive type.
+ *
+ * In all cases, matches that occur higher in the drive table will take
+ * precedence over matches that occur later in the table.
+ */
 blk_get_geometry(blk, _sectors);
-match = -1;
-first_match = -1;
+match = size_match = type_match = -1;
 for (i = 0; ; i++) {
 parse = _formats[i];
 if (parse->drive == FLOPPY_DRIVE_TYPE_NONE) {
 break;
 }
-if (drv->drive == parse->drive ||
-drv->drive == FLOPPY_DRIVE_TYPE_AUTO) {
-size = (parse->max_head + 1) * parse->max_track *
-parse->last_sect;
-if (nb_sectors == size) {
-match = i;
-break;
+size = (parse->max_head + 1) * parse->max_track * parse->last_sect;
+if (nb_sectors == size) {
+if (magic || parse->drive == drv->drive) {
+/* (1) perfect match -- nb_sectors and drive type */
+goto out;
+} else if (drive_size(parse->drive) == drive_size(drv->drive)) {
+/* (2) size match -- nb_sectors and physical medium size */
+match = (match == -1) ? i : match;
+} else {
+/* This is suspicious -- Did the user misconfigure? */
+size_match = (size_match == -1) ? i : size_match;
 }
-if (first_match == -1) {
-first_match = i;
+} else if (type_match == -1) {
+if ((parse->drive == drv->drive) ||
+(magic && (parse->drive == get_fallback_drive_type(drv {
+/* (3) type match -- nb_sectors mismatch, but matches the type
+ * specified explicitly by the user, or matches the 
fallback
+ * default type when using the drive autodetect mechanism 
*/
+type_match = i;
 }
 }
 }
+
+/* No exact match found */
 if (match == -1) {
-if (first_match == -1) {
-error_setg(_abort, "No candidate geometries present in table 
"
-   " for floppy drive type '%s'",
-   FloppyDriveType_lookup[drv->drive]);
-} else {
-match = first_match;
+if (size_match != -1) {
+parse = _formats[size_match];
+FLOPPY_DPRINTF("User requested floppy drive type '%s', "
+   "but inserted medium appears to be a "
+   "%d sector '%s' type\n",
+   FloppyDriveType_lookup[drv->drive],
+   nb_sectors,
+   FloppyDriveType_lookup[parse->drive]);
 }
-parse = _formats[match];
+match = type_match;
 }
 
+/* No match of any kind found -- fd_format is misconfigured, abort. */
+if (match == -1) {
+error_setg(_abort, "No candidate geometries present in table "
+ 

Re: [Qemu-devel] [PATCH] qmp: add query-block-dirty-bitmap

2016-01-22 Thread Denis V. Lunev

On 01/22/2016 08:07 PM, Vladimir Sementsov-Ogievskiy wrote:

Add qmp command to query dirty bitmap. This is needed for external
backup.

Signed-off-by: Vladimir Sementsov-Ogievskiy 
---
  block.c   | 41 
  blockdev.c| 21 +
  include/block/block.h |  2 ++
  qapi/block-core.json  | 52 +++
  qmp-commands.hx   | 22 ++
  5 files changed, 138 insertions(+)

diff --git a/block.c b/block.c
index 5709d3d..9a28589 100644
--- a/block.c
+++ b/block.c
@@ -3717,6 +3717,47 @@ void bdrv_set_dirty(BlockDriverState *bs, int64_t 
cur_sector,
  }
  }
  
+BlockDirtyBitmapInfo *bdrv_query_dirty_bitmap(BlockDriverState *bs,

+  BdrvDirtyBitmap *bitmap)
+{
+BlockDirtyBitmapInfo *info = g_new0(BlockDirtyBitmapInfo, 1);
+BlockDirtyRegionList **plist = >dirty_regions;
+uint64_t begin = 0, end = 0, size = bitmap->size;
+HBitmap *hb = bitmap->bitmap;
+
+info->dirty_count = bdrv_get_dirty_count(bitmap);
+info->granularity = bdrv_dirty_bitmap_granularity(bitmap);
+info->size = bitmap->size;
+info->name = g_strdup(bitmap->name);
+info->disabled = bitmap->disabled;
+info->dirty_regions = NULL;
+
+for (; begin < size; ++begin) {
+BlockDirtyRegion *region;
+BlockDirtyRegionList *entry;
+
+if (!hbitmap_get(hb, begin)) {
+continue;
+}
+
+for (end = begin + 1; end < size && hbitmap_get(hb, end); ++end) {
+;
+}
let us implemented faster finder. This would be useful in other places. 
It could be

100 times faster!


+
+region = g_new0(BlockDirtyRegion, 1);
+entry = g_new0(BlockDirtyRegionList, 1);
+region->start = begin;
+region->count = end - begin;
+entry->value = region;
+*plist = entry;
+plist = >next;
+
+begin = end;
+}
+
+return info;
+}
+
  /**
   * Advance an HBitmapIter to an arbitrary offset.
   */
diff --git a/blockdev.c b/blockdev.c
index 07cfe25..d2bc453 100644
--- a/blockdev.c
+++ b/blockdev.c
@@ -2734,6 +2734,27 @@ void qmp_block_dirty_bitmap_clear(const char *node, 
const char *name,
  aio_context_release(aio_context);
  }
  
+BlockDirtyBitmapInfo *qmp_query_block_dirty_bitmap(const char *node,

+   const char *name,
+   Error **errp)
+{
+AioContext *aio_context;
+BdrvDirtyBitmap *bitmap;
+BlockDriverState *bs;
+BlockDirtyBitmapInfo *ret = NULL;
+
+bitmap = block_dirty_bitmap_lookup(node, name, , _context, errp);
+if (!bitmap) {
+return NULL;
+}
+
+ret = bdrv_query_dirty_bitmap(bs, bitmap);
+
+aio_context_release(aio_context);
+
+return ret;
+}
+
  void hmp_drive_del(Monitor *mon, const QDict *qdict)
  {
  const char *id = qdict_get_str(qdict, "id");
diff --git a/include/block/block.h b/include/block/block.h
index 25f36dc..9d6bd33 100644
--- a/include/block/block.h
+++ b/include/block/block.h
@@ -505,6 +505,8 @@ void bdrv_set_dirty_bitmap(BdrvDirtyBitmap *bitmap,
 int64_t cur_sector, int nr_sectors);
  void bdrv_reset_dirty_bitmap(BdrvDirtyBitmap *bitmap,
   int64_t cur_sector, int nr_sectors);
+BlockDirtyBitmapInfo *bdrv_query_dirty_bitmap(BlockDriverState *bs,
+  BdrvDirtyBitmap *bitmap);
  void bdrv_dirty_iter_init(BdrvDirtyBitmap *bitmap, struct HBitmapIter *hbi);
  void bdrv_set_dirty_iter(struct HBitmapIter *hbi, int64_t offset);
  int64_t bdrv_get_dirty_count(BdrvDirtyBitmap *bitmap);
diff --git a/qapi/block-core.json b/qapi/block-core.json
index 0a915ed..12ed759 100644
--- a/qapi/block-core.json
+++ b/qapi/block-core.json
@@ -414,6 +414,58 @@
  ##
  { 'command': 'query-block', 'returns': ['BlockInfo'] }
  
+##

+# @BlockDirtyRegion:
+#
+# Region in bytes.
+#
+# @start: first byte
+#
+# @count: number of bytes in the region
+#
+# Since: 2.3
+##
+{ 'struct': 'BlockDirtyRegion',
+  'data': { 'start': 'int', 'count': 'int' } }
+
+##
+# @BlockDirtyBitmapInfo
+#
+# @name: the name of the dirty bitmap
+#
+# @size: size of the dirty bitmap in sectors
+#
+# @granularity: granularity of the dirty bitmap in bytes
+#
+# @disabled: whether the dirty bitmap is disabled
+#
+# @dirty-count: number of dirty bytes according to the dirty bitmap
+#
+# @dirty-regions: dirty regions of the bitmap
+#
+# Since 2.3
+##
+{ 'struct': 'BlockDirtyBitmapInfo',
+  'data': { 'name': 'str',
+'size': 'int',
+'granularity': 'int',
+'disabled': 'bool',
+'dirty-count': 'int',
+'dirty-regions': ['BlockDirtyRegion'] } }
+
+##
+# @query-block-dirty-bitmap
+#
+# Get a description for specified dirty bitmap including it's dirty regions.
+# This 

Re: [Qemu-devel] [PATCH] qmp: add query-block-dirty-bitmap

2016-01-22 Thread Denis V. Lunev

On 01/22/2016 08:28 PM, Vladimir Sementsov-Ogievskiy wrote:

On 22.01.2016 20:22, Denis V. Lunev wrote:

On 01/22/2016 08:07 PM, Vladimir Sementsov-Ogievskiy wrote:
  { 'command': 'query-block', 'returns': ['BlockInfo'] }
  +##
+# @BlockDirtyRegion:
+#
+# Region in bytes.
+#
+# @start: first byte
+#
+# @count: number of bytes in the region
+#
+# Since: 2.3
+##
+{ 'struct': 'BlockDirtyRegion',
+  'data': { 'start': 'int', 'count': 'int' } }
+
+##
+# @BlockDirtyBitmapInfo
+#
+# @name: the name of the dirty bitmap
+#
+# @size: size of the dirty bitmap in sectors
+#
+# @granularity: granularity of the dirty bitmap in bytes
+#
+# @disabled: whether the dirty bitmap is disabled
+#
+# @dirty-count: number of dirty bytes according to the dirty bitmap
+#
+# @dirty-regions: dirty regions of the bitmap
+#
+# Since 2.3
+##
+{ 'struct': 'BlockDirtyBitmapInfo',
+  'data': { 'name': 'str',
+'size': 'int',
+'granularity': 'int',
+'disabled': 'bool',
+'dirty-count': 'int',
+'dirty-regions': ['BlockDirtyRegion'] } }
+
+##
+# @query-block-dirty-bitmap
+#
+# Get a description for specified dirty bitmap including it's dirty 
regions.

+# This command is in general for testing purposes.
+#
+# Returns: @BlockDirtyBitmapInfo
+#
+# Since: 2.3
+##
+{ 'command': 'query-block-dirty-bitmap',
+  'data': 'BlockDirtyBitmap',
+  'returns': 'BlockDirtyBitmapInfo' }
1) should we consider part-by-part retrieval? This could be useful 
for large discs.

2) Change to since 2.6
3) Do you think that content should be retrieved separately than data?


3 - what do you mean?



sorry, I mean bitmap description separately from bitmap bits aka data



Re: [Qemu-devel] [PATCH v4] qom, qmp, hmp, qapi: create qom-type-prop-list for class properties

2016-01-22 Thread Eric Blake
On 01/22/2016 05:15 AM, Valentin Rakush wrote:
> This patch adds support for qom-type-prop-list command to list object
> class properties. A later patch will use this functionality to
> implement x86_64-cpu properties.
> 
> Signed-off-by: Valentin Rakush 
> Cc: Luiz Capitulino 
> Cc: Eric Blake 
> Cc: Markus Armbruster 
> Cc: Andreas Färber 
> Cc: Daniel P. Berrange 
> ---

> +++ b/hmp-commands.hx
> @@ -1734,6 +1734,19 @@ Print QOM properties of object at location @var{path}
>  ETEXI
>  
>  {
> +.name   = "qom-type-prop-list",

To be consistent with most existing HMP commands, this should use
qmp_type_prop_list (only the QMP version should use '-').

For that matter, should this really be a new top-level command, or
should it be a subcommand of the 'info' command?

The QMP command looks fine, though.

-- 
Eric Blake   eblake redhat com+1-919-301-3266
Libvirt virtualization library http://libvirt.org



signature.asc
Description: OpenPGP digital signature


Re: [Qemu-devel] [PATCH] hw/pci-host/uninorth.c: Add support for Apple's PCI bridge register 0x48

2016-01-22 Thread Mark Cave-Ayland
On 22/01/16 18:26, Programmingkid wrote:

> On Jan 22, 2016, at 11:46 AM, Mark Cave-Ayland wrote:
> 
>> On 22/01/16 16:09, Programmingkid wrote:
>>
>>> Apple has custom PCI bridge registers that are not a part of any known 
>>> standard. This patch implements register 0x48. With this patch the 
>>> AppleMacRiscPCI kernel extension no longer prints these error messages for 
>>> the mac99 target:
>>> AppleMacRiscPCI: bad range 2(8000:0100)
>>> AppleMacRiscPCI: bad range 2(8100:1000)
>>> AppleMacRiscPCI: bad range 2(8108:0008)
>>>
>>> Signed-off-by: John Arbuckle 
>>>
>>> ---
>>> hw/pci-host/uninorth.c |4 
>>> 1 files changed, 4 insertions(+), 0 deletions(-)
>>>
>>> diff --git a/hw/pci-host/uninorth.c b/hw/pci-host/uninorth.c
>>> index 215b64f..6541b10 100644
>>> --- a/hw/pci-host/uninorth.c
>>> +++ b/hw/pci-host/uninorth.c
>>> @@ -330,6 +330,10 @@ static void unin_agp_pci_host_realize(PCIDevice *d, 
>>> Error **errp)
>>> d->config[0x0C] = 0x08; // cache_line_size
>>> d->config[0x0D] = 0x10; // latency_timer
>>> //d->config[0x34] = 0x80; // capabilities_pointer
>>> +d->config[0x48] = 0x0;
>>> +d->config[0x49] = 0x0;
>>> +d->config[0x4a] = 0x0;
>>> +d->config[0x4b] = 0x1;
>>> }
>>>
>>> static void u3_agp_pci_host_realize(PCIDevice *d, Error **errp)
>>
>> Tested-by: Mark Cave-Ayland 
>>
>> As this config space register is seemingly an Apple custom option (or at
>> least I can't find a mention of it in the PCI-PCI bridge spec) I think
>> this should have a comment explaining exactly what it does, and should
>> reference both AppleMacRiscPCI.cpp filename and the enum for the
>> register value (0x48 == kMacRISCPCIAddressSelect).
> 
> Is this what you want:
> 
> Apple has custom PCI bridge registers that are not a part of any known 
> standard. This patch implements register 0x48. With this patch the 
> AppleMacRiscPCI kernel extension no longer prints these error messages for 
> the mac99 target:
> AppleMacRiscPCI: bad range 2(8000:0100)
> AppleMacRiscPCI: bad range 2(8100:1000)
> AppleMacRiscPCI: bad range 2(8108:0008)
> 
> In Apple's AppleMacRiscPCI.h source code, the register is defined as 
> kMacRISCPCIAddressSelect. It is accessed in the AppleMacRiscPCI.cpp file. 
> What this register is used for is determining the address a pci bridge range 
> that is kept track of by the operating system. 
> 
>> I'd also like to see a note explaining that this sets up the register to
>> match the PCI memory region base/size currently used in QEMU/OpenBIOS
>> too in order to provide a hint that if one changes, so must the other.
> 
> Note: OpenBIOS in the arch/ppc/qemu/init.c file has a structure with an index 
> of [ARCH_MAC99]. It keeps track of the PCI MMIO range for the mac99 target. 
> If a change happens to either this file or the AppleMacRiscPCI kernel 
> extension, the other would have to be changed as well.

It's mostly down to Alex/David (so please wait for some initial
feedback) but I'd prefer to see something along these lines:


Subject: uninorth.c: add support for UniNorth kMacRISCPCIAddressSelect
(0x48) register

Darwin/OS X use the undocumented kMacRISCPCIAddressSelect (0x48) to
configure PCI memory space size for mac99 machines. Without this
register, warnings similar to below are emitted to the console during boot:

AppleMacRiscPCI: bad range 2(8000:0100)
AppleMacRiscPCI: bad range 2(8100:1000)
AppleMacRiscPCI: bad range 2(8108:0008)

Based upon the algorithm in Darwin's AppleMacRiscPCI.cpp driver, set the
kMacRISCPCIAddressSelect register so that Darwin considers the PCI
memory space to be at 0x8000 (size 0x1000) which matches that
currently used by QEMU and OpenBIOS.


Similarly I think a 2-line comment should be added in the actual code
itself e.g.

/* Set kMacRISCPCIAddressSelect (0x48) register to indicate PCI memory
space with base 0x8000, size 0x1000 for Apple's AppleMacRiscPCI
driver */

>> BTW is the register required for any of the other uni-north realize
>> functions? Alex?
> 
> 
> My guess is no. Only the AppleMacRiscPCI kernel extension needs to know those 
> details.

I was thinking more about AGP and non-AGP uninorth bridges, but there is
definitely some overlap as you can see that the AppleMacRiscPCI driver
is also used to configure AGP.

> Since this is only a change to the patch's comment, do I still need to use v2 
> in the "[PATCH]" text?

Yeah, it's best to do this regardless of the changes so that it's clear
to the maintainers which version of the patch to use.


ATB,

Mark.




Re: [Qemu-devel] [PATCH v9 24/37] qmp: Tighten output visitor rules

2016-01-22 Thread Markus Armbruster
Eric Blake  writes:

> Add a new qmp_output_visitor_reset(), which must be called before
> reusing an exising QmpOutputVisitor on a new root object.  Tighten
> assertions to require that qmp_output_get_qobject() can only be
> called after pairing a visit_end_* for every visit_start_* (rather
> than allowing it to return a partially built object), that it must
> not be called unless at least one visit_type_* or visit_start/
> visit_end pair has occurred since creation/reset (the accidental
> return of NULL fixed by commit ab8bf1d7 would have been much
> easier to diagnose),

Makes sense.

>  and that it may only be called once per visit.

Why?

Does it have a side effect?

> Meanwhile, nothing was using the return value of qmp_output_pop().

Well, pop returns the value popped, otherwise it's not a pop.

> Also, adding a parameter will let us diagnose any programming bugs
> due to mismatched push(struct)/pop(list) or push(list)/pop(struct).

Hmm.

> To keep the semantics of test_visitor_out_empty, we now have to
> explicitly request a top-level visit of a NULL object, by
> implementing the just-added visitor type_null() callback.

The fact that we implement type_null() in the QMP output visitor is
mentioned only in passing, and not clearly.

Could the previous patch implement it for both QMP input and output?

> Signed-off-by: Eric Blake 
>
> ---
> v9: rebase to added patch, squash in more sanity checks, drop
> Marc-Andre's R-b
> v8: rename qmp_output_reset to qmp_output_visitor_reset
> v7: new patch, based on discussion about spapr_drc.c
> ---
>  include/qapi/qmp-output-visitor.h |  1 +
>  include/qapi/visitor-impl.h   |  4 ++--
>  qapi/qmp-output-visitor.c | 50 
> +++
>  tests/test-qmp-output-visitor.c   |  2 ++
>  4 files changed, 35 insertions(+), 22 deletions(-)
>
> diff --git a/include/qapi/qmp-output-visitor.h 
> b/include/qapi/qmp-output-visitor.h
> index 2266770..5093f0d 100644
> --- a/include/qapi/qmp-output-visitor.h
> +++ b/include/qapi/qmp-output-visitor.h
> @@ -21,6 +21,7 @@ typedef struct QmpOutputVisitor QmpOutputVisitor;
>
>  QmpOutputVisitor *qmp_output_visitor_new(void);
>  void qmp_output_visitor_cleanup(QmpOutputVisitor *v);
> +void qmp_output_visitor_reset(QmpOutputVisitor *v);
>
>  QObject *qmp_output_get_qobject(QmpOutputVisitor *v);
>  Visitor *qmp_output_get_visitor(QmpOutputVisitor *v);
> diff --git a/include/qapi/visitor-impl.h b/include/qapi/visitor-impl.h
> index 95408a5..913f1b0 100644
> --- a/include/qapi/visitor-impl.h
> +++ b/include/qapi/visitor-impl.h
> @@ -75,8 +75,8 @@ struct Visitor
>   * visitors do not currently visit arbitrary types).  */
>  void (*type_any)(Visitor *v, const char *name, QObject **obj,
>   Error **errp);
> -/* Must be provided to visit explicit null values (right now, only the
> - * dealloc and qmp-input visitors support this).  */
> +/* Must be provided to visit explicit null values (the opts and string
> + * visitors do not currently visit an explicit null).  */

Will need updating.

>  void (*type_null)(Visitor *v, const char *name, Error **errp);
>
>  /* May be NULL; most useful for input visitors. */
> diff --git a/qapi/qmp-output-visitor.c b/qapi/qmp-output-visitor.c
> index df22999..2eb200d 100644
> --- a/qapi/qmp-output-visitor.c
> +++ b/qapi/qmp-output-visitor.c
> @@ -1,6 +1,7 @@
>  /*
>   * Core Definitions for QAPI/QMP Command Registry
>   *
> + * Copyright (C) 2015-2016 Red Hat, Inc.
>   * Copyright IBM, Corp. 2011
>   *
>   * Authors:
> @@ -56,17 +57,15 @@ static void qmp_output_push_obj(QmpOutputVisitor *qov, 
> QObject *value)
>  QTAILQ_INSERT_HEAD(>stack, e, node);
>  }
>
> -/* Grab and remove the most recent QObject from the stack */
> -static QObject *qmp_output_pop(QmpOutputVisitor *qov)
> +/* Remove the most recent QObject with given type from the stack */
> +static void qmp_output_pop(QmpOutputVisitor *qov, QType type)
>  {
>  QStackEntry *e = QTAILQ_FIRST(>stack);
> -QObject *value;
>
>  assert(e);
>  QTAILQ_REMOVE(>stack, e, node);
> -value = e->value;
> +assert(qobject_type(e->value) == type);
>  g_free(e);
> -return value;
>  }
>
>
>  /* Grab the most recent QObject from the stack, if any */
> @@ -88,9 +87,8 @@ static void qmp_output_add_obj(QmpOutputVisitor *qov, const 
> char *name,
>  cur = qmp_output_last(qov);
>
>  if (!cur) {
> -/* FIXME we should require the user to reset the visitor, rather
> - * than throwing away the previous root */
> -qobject_decref(qov->root);
> +/* Don't allow reuse of visitor on more than one root */
> +assert(!qov->root);
>  qov->root = value;
>  } else {
>  switch (qobject_type(cur)) {
> @@ -99,6 +97,7 @@ static void qmp_output_add_obj(QmpOutputVisitor *qov, const 
> char *name,
>  qdict_put_obj(qobject_to_qdict(cur), 

Re: [Qemu-devel] [PATCH] char: fix parameter name / type in BSD codepath

2016-01-22 Thread Peter Maydell
You typoed the qemu-devel address...

thanks
-- PMM

On 22 January 2016 at 17:35, Daniel P. Berrange  wrote:
> The BSD impl of qemu_chr_open_pp_fd had mis-declared
> its parameter type as ChardevBackend instead of
> ChardevCommon. It had also mistakenly used the variable
> name 'common' instead of 'backend'.
>
> Tested-by: Sean Bruno 
> Signed-off-by: Daniel P. Berrange 
> ---
>  qemu-char.c | 4 ++--
>  1 file changed, 2 insertions(+), 2 deletions(-)
>
> diff --git a/qemu-char.c b/qemu-char.c
> index e133f4f..aa2e660 100644
> --- a/qemu-char.c
> +++ b/qemu-char.c
> @@ -1835,12 +1835,12 @@ static int pp_ioctl(CharDriverState *chr, int cmd, 
> void *arg)
>  }
>
>  static CharDriverState *qemu_chr_open_pp_fd(int fd,
> -ChardevBackend *backend,
> +ChardevCommon *backend,
>  Error **errp)
>  {
>  CharDriverState *chr;
>
> -chr = qemu_chr_alloc(common, errp);
> +chr = qemu_chr_alloc(backend, errp);
>  if (!chr) {
>  return NULL;
>  }
> --
> 2.5.0
>



Re: [Qemu-devel] [PATCH] hw/pci-host/uninorth.c: Add support for Apple's PCI bridge register 0x48

2016-01-22 Thread Programmingkid

On Jan 22, 2016, at 11:46 AM, Mark Cave-Ayland wrote:

> On 22/01/16 16:09, Programmingkid wrote:
> 
>> Apple has custom PCI bridge registers that are not a part of any known 
>> standard. This patch implements register 0x48. With this patch the 
>> AppleMacRiscPCI kernel extension no longer prints these error messages for 
>> the mac99 target:
>> AppleMacRiscPCI: bad range 2(8000:0100)
>> AppleMacRiscPCI: bad range 2(8100:1000)
>> AppleMacRiscPCI: bad range 2(8108:0008)
>> 
>> Signed-off-by: John Arbuckle 
>> 
>> ---
>> hw/pci-host/uninorth.c |4 
>> 1 files changed, 4 insertions(+), 0 deletions(-)
>> 
>> diff --git a/hw/pci-host/uninorth.c b/hw/pci-host/uninorth.c
>> index 215b64f..6541b10 100644
>> --- a/hw/pci-host/uninorth.c
>> +++ b/hw/pci-host/uninorth.c
>> @@ -330,6 +330,10 @@ static void unin_agp_pci_host_realize(PCIDevice *d, 
>> Error **errp)
>> d->config[0x0C] = 0x08; // cache_line_size
>> d->config[0x0D] = 0x10; // latency_timer
>> //d->config[0x34] = 0x80; // capabilities_pointer
>> +d->config[0x48] = 0x0;
>> +d->config[0x49] = 0x0;
>> +d->config[0x4a] = 0x0;
>> +d->config[0x4b] = 0x1;
>> }
>> 
>> static void u3_agp_pci_host_realize(PCIDevice *d, Error **errp)
> 
> Tested-by: Mark Cave-Ayland 
> 
> As this config space register is seemingly an Apple custom option (or at
> least I can't find a mention of it in the PCI-PCI bridge spec) I think
> this should have a comment explaining exactly what it does, and should
> reference both AppleMacRiscPCI.cpp filename and the enum for the
> register value (0x48 == kMacRISCPCIAddressSelect).

Is this what you want:

Apple has custom PCI bridge registers that are not a part of any known 
standard. This patch implements register 0x48. With this patch the 
AppleMacRiscPCI kernel extension no longer prints these error messages for the 
mac99 target:
AppleMacRiscPCI: bad range 2(8000:0100)
AppleMacRiscPCI: bad range 2(8100:1000)
AppleMacRiscPCI: bad range 2(8108:0008)

In Apple's AppleMacRiscPCI.h source code, the register is defined as 
kMacRISCPCIAddressSelect. It is accessed in the AppleMacRiscPCI.cpp file. What 
this register is used for is determining the address a pci bridge range that is 
kept track of by the operating system. 

> I'd also like to see a note explaining that this sets up the register to
> match the PCI memory region base/size currently used in QEMU/OpenBIOS
> too in order to provide a hint that if one changes, so must the other.

Note: OpenBIOS in the arch/ppc/qemu/init.c file has a structure with an index 
of [ARCH_MAC99]. It keeps track of the PCI MMIO range for the mac99 target. If 
a change happens to either this file or the AppleMacRiscPCI kernel extension, 
the other would have to be changed as well.

> 
> BTW is the register required for any of the other uni-north realize
> functions? Alex?


My guess is no. Only the AppleMacRiscPCI kernel extension needs to know those 
details.

Since this is only a change to the patch's comment, do I still need to use v2 
in the "[PATCH]" text?



Re: [Qemu-devel] [PATCH] qmp: add query-block-dirty-bitmap

2016-01-22 Thread Eric Blake
On 01/22/2016 10:07 AM, Vladimir Sementsov-Ogievskiy wrote:
> Add qmp command to query dirty bitmap. This is needed for external
> backup.
> 
> Signed-off-by: Vladimir Sementsov-Ogievskiy 
> ---
>  block.c   | 41 
>  blockdev.c| 21 +
>  include/block/block.h |  2 ++
>  qapi/block-core.json  | 52 
> +++
>  qmp-commands.hx   | 22 ++
>  5 files changed, 138 insertions(+)

Just an interface review at this time:

> +++ b/qapi/block-core.json
> @@ -414,6 +414,58 @@
>  ##
>  { 'command': 'query-block', 'returns': ['BlockInfo'] }
>  
> +##
> +# @BlockDirtyRegion:
> +#
> +# Region in bytes.
> +#
> +# @start: first byte
> +#
> +# @count: number of bytes in the region
> +#
> +# Since: 2.3

Don't you mean 2.6?

> +##
> +{ 'struct': 'BlockDirtyRegion',
> +  'data': { 'start': 'int', 'count': 'int' } }
> +
> +##
> +# @BlockDirtyBitmapInfo
> +#
> +# @name: the name of the dirty bitmap
> +#
> +# @size: size of the dirty bitmap in sectors
> +#
> +# @granularity: granularity of the dirty bitmap in bytes
> +#
> +# @disabled: whether the dirty bitmap is disabled
> +#
> +# @dirty-count: number of dirty bytes according to the dirty bitmap
> +#
> +# @dirty-regions: dirty regions of the bitmap
> +#
> +# Since 2.3

and again

> +##
> +{ 'struct': 'BlockDirtyBitmapInfo',
> +  'data': { 'name': 'str',
> +'size': 'int',
> +'granularity': 'int',
> +'disabled': 'bool',
> +'dirty-count': 'int',
> +'dirty-regions': ['BlockDirtyRegion'] } }
> +
> +##
> +# @query-block-dirty-bitmap
> +#
> +# Get a description for specified dirty bitmap including it's dirty regions.
> +# This command is in general for testing purposes.
> +#
> +# Returns: @BlockDirtyBitmapInfo
> +#
> +# Since: 2.3

and again

> +##
> +{ 'command': 'query-block-dirty-bitmap',
> +  'data': 'BlockDirtyBitmap',
> +  'returns': 'BlockDirtyBitmapInfo' }

Seems reasonable for getting at the information for one bitmap.  But
would it be smarter to have:

{ 'command': 'query-block-dirty-bitmap',
  'data': { 'node':'str', '*name':'str' },
  'returns': [ 'BlockDirtyBitmapInfo' ] }

so that you could get ALL the dirty bitmaps for a single node (with
optional filtering to get an array of just one, if 'name' was provided)?
 Or, should BlockDirtyBitmapInfo also include a node name, then you
could query all dirty bitmaps for all nodes at once?  Is that too much
data for one QMP command?


> +
> +query-block-dirty-bitmap
> +
> +Since 2.6
> +
> +Get dirty bitmap info, including contents. Bitmap data are returned as array 
> of
> +dirty regions
> +
> +Arguments:
> +
> +- "node": device/node on which to remove dirty bitmap (json-string)

Too much copy-and-paste; you aren't removing the bitmap.

> +- "name": name of the dirty bitmap to remove (json-string)
> +
> +EQMP

Worth showing example output?


-- 
Eric Blake   eblake redhat com+1-919-301-3266
Libvirt virtualization library http://libvirt.org



signature.asc
Description: OpenPGP digital signature


Re: [Qemu-devel] [PATCH v9 26/37] qapi: Simplify excess input reporting in input visitors

2016-01-22 Thread Markus Armbruster
Eric Blake  writes:

> When reporting that an unvisited member remains at the end of an
> input visit for a struct, we were using g_hash_table_find()
> coupled with a callback function that always returns true, to
> locate an arbitrary member of the hash table.  But if all we
> need is an arbitrary entry, we can get that from a single-use
> iterator, without needing a tautological callback function.

Good idea.

> Suggested-by: Markus Armbruster 

Whoops, it's even mine!  I forgot... %-)

> Signed-off-by: Eric Blake 
> Reviewed-by: Marc-André Lureau 
>
> ---
> v9: no change
> v8: rebase to earlier changes
> v7: retitle, rebase to earlier context changes
> v6: new patch, based on comments on RFC against v5 7/46
> ---
>  qapi/opts-visitor.c  | 12 +++-
>  qapi/qmp-input-visitor.c | 14 +-
>  2 files changed, 8 insertions(+), 18 deletions(-)
>
> diff --git a/qapi/opts-visitor.c b/qapi/opts-visitor.c
> index 62ffdd4..df312e6 100644
> --- a/qapi/opts-visitor.c
> +++ b/qapi/opts-visitor.c
> @@ -156,17 +156,11 @@ opts_start_struct(Visitor *v, const char *name, void 
> **obj,
>  }
>
>
> -static gboolean
> -ghr_true(gpointer ign_key, gpointer ign_value, gpointer ign_user_data)
> -{
> -return TRUE;
> -}
> -
> -
>  static void
>  opts_end_struct(Visitor *v, Error **errp)
>  {
>  OptsVisitor *ov = to_ov(v);
> +GHashTableIter iter;
>  GQueue *any;
>
>  if (--ov->depth > 0) {
> @@ -174,8 +168,8 @@ opts_end_struct(Visitor *v, Error **errp)
>  }
>
>  /* we should have processed all (distinct) QemuOpt instances */
> -any = g_hash_table_find(ov->unprocessed_opts, _true, NULL);
> -if (any) {
> +g_hash_table_iter_init(, ov->unprocessed_opts);
> +if (g_hash_table_iter_next(, NULL, (void **))) {

Is this cast kosher?

>  const QemuOpt *first;
>
>  first = g_queue_peek_head(any);
> diff --git a/qapi/qmp-input-visitor.c b/qapi/qmp-input-visitor.c
> index ad23bec..91ef945 100644
> --- a/qapi/qmp-input-visitor.c
> +++ b/qapi/qmp-input-visitor.c
> @@ -88,12 +88,6 @@ static void qmp_input_push(QmpInputVisitor *qiv, QObject 
> *obj, Error **errp)
>  qiv->nb_stack++;
>  }
>
> -/** Only for qmp_input_pop. */
> -static gboolean always_true(gpointer key, gpointer val, gpointer user_pkey)
> -{
> -*(const char **)user_pkey = (const char *)key;
> -return TRUE;
> -}
>
>  static void qmp_input_pop(QmpInputVisitor *qiv, Error **errp)
>  {
> @@ -102,9 +96,11 @@ static void qmp_input_pop(QmpInputVisitor *qiv, Error 
> **errp)
>  if (qiv->strict) {
>  GHashTable * const top_ht = qiv->stack[qiv->nb_stack - 1].h;
>  if (top_ht) {
> -if (g_hash_table_size(top_ht)) {
> -const char *key;
> -g_hash_table_find(top_ht, always_true, );
> +GHashTableIter iter;
> +const char *key;
> +
> +g_hash_table_iter_init(, top_ht);
> +if (g_hash_table_iter_next(, (void **), NULL)) {

Is this cast kosher?

>  error_setg(errp, QERR_QMP_EXTRA_MEMBER, key);
>  }
>  g_hash_table_unref(top_ht);



Re: [Qemu-devel] [PATCH v9 25/37] spapr_drc: Expose 'null' in qom-get when there is no fdt

2016-01-22 Thread Markus Armbruster
Eric Blake  writes:

> Now that the QMP output visitor supports an explicit null
> output, we should utilize it to make it easier to diagnose
> the difference between a missing fdt vs. a present-but-empty
> one.

Please spell out that we change the value from {} to null.

>
> (Note that this reverts the behavior of commit ab8bf1d, taking
> us back to the behavior of commit 6c2f9a1 [which in turn
> stemmed from a crash fix in 1d10b44]; but that this time,
> the change is intentional and not an accidental side-effect.)
>
> Signed-off-by: Eric Blake 
> Acked-by: David Gibson 
>
> ---
> v9: improved commit message
> v8: rebase to 'name' motion
> v7: new patch, based on discussion about spapr_drc.c
> ---
>  hw/ppc/spapr_drc.c | 6 +-
>  1 file changed, 1 insertion(+), 5 deletions(-)
>
> diff --git a/hw/ppc/spapr_drc.c b/hw/ppc/spapr_drc.c
> index ffc2cd9..831ce23 100644
> --- a/hw/ppc/spapr_drc.c
> +++ b/hw/ppc/spapr_drc.c
> @@ -259,11 +259,7 @@ static void prop_get_fdt(Object *obj, Visitor *v, const 
> char *name,
>  void *fdt;
>
>  if (!drc->fdt) {
> -visit_start_struct(v, name, NULL, 0, );
> -if (!err) {
> -visit_end_struct(v, );
> -}
> -error_propagate(errp, err);
> +visit_type_null(v, NULL, errp);
>  return;
>  }

Easier to read, always welcome :)



[Qemu-devel] COLO: how to flip a secondary to a primary?

2016-01-22 Thread Dr. David Alan Gilbert
Hi,
  I've been looking at what's needed to add a new secondary after
a primary failed; from the block side it doesn't look as hard
as I'd expected, perhaps you can tell me if I'm missing something!

The normal primary setup is:

   quorum
  Real disk
  nbd client

The normal secondary setup is:
   replication
  active-disk
  hidden-disk
  Real-disk

With a couple of minor code hacks; I changed the secondary to be:

   quorum
  replication
active-disk
hidden-disk
Real-disk
  dummy-disk

and then after the primary fails, I start a new secondary
on another host and then on the old secondary do:

  nbd_server_stop
  stop
  x_block_change top-quorum -d children.0 # deletes use of real disk, 
leaves dummy
  drive_del active-disk0
  x_block_change top-quorum -a node-real-disk
  x_block_change top-quorum -d children.1 # Seems to have deleted the 
dummy?!, the disk is now child 0
  drive_add buddy 
driver=replication,mode=primary,file.driver=nbd,file.host=ibpair,file.port=8889,file.export=colo-disk0,node-name=nbd-client,if=none,cache=none
  x_block_change top-quorum -a nbd-client
  c
  migrate_set_capability x-colo on
  migrate -d -b tcp:ibpair:

and I think that means what was the secondary, has the same disk
structure as a normal primary.
That's not quite happy yet, and I've not figured out why - but the
order/structure of the block devices looks right?

Notes:
   a) The dummy serves two purposes, 1) it works around the segfault
  I reported in the other mail, 2) when I delete the real disk in the
  first x_block_change it means the quorum still has 1 disk so doesn't
  get upset.
   b) I had to remove the restriction in quorum_start_replication
  on which mode it would run in. 
   c) I'm not really sure everything knows it's in secondary mode yet, and
  I'm not convinced whether the replication is doing the right thing.
   d) The migrate -d -b   eventually fails on the destination, not worked out 
why
  yet.
   e) Adding/deleting children on quorum is hard having to use the children.0/1
  notation when you've added children using node names - it's worrying
  which number is which; is there a way to give them a name?
   f) I've not thought about the colo-proxy that much yet - I guess that
  existing connections need to keep their sequence number offset but
  new connections made by what is now the primary dont need to do anything
  special.

Dave
--
Dr. David Alan Gilbert / dgilb...@redhat.com / Manchester, UK



Re: [Qemu-devel] [PATCH v9 26/37] qapi: Simplify excess input reporting in input visitors

2016-01-22 Thread Eric Blake
On 01/22/2016 12:24 PM, Markus Armbruster wrote:
> Eric Blake  writes:
> 
>> When reporting that an unvisited member remains at the end of an
>> input visit for a struct, we were using g_hash_table_find()
>> coupled with a callback function that always returns true, to
>> locate an arbitrary member of the hash table.  But if all we
>> need is an arbitrary entry, we can get that from a single-use
>> iterator, without needing a tautological callback function.
> 
> Good idea.
> 
>> Suggested-by: Markus Armbruster 
> 
> Whoops, it's even mine!  I forgot... %-)
> 
>> Signed-off-by: Eric Blake 
>> Reviewed-by: Marc-André Lureau 
>>
>> ---

>>  GQueue *any;
>>
>>  if (--ov->depth > 0) {
>> @@ -174,8 +168,8 @@ opts_end_struct(Visitor *v, Error **errp)
>>  }
>>
>>  /* we should have processed all (distinct) QemuOpt instances */
>> -any = g_hash_table_find(ov->unprocessed_opts, _true, NULL);
>> -if (any) {
>> +g_hash_table_iter_init(, ov->unprocessed_opts);
>> +if (g_hash_table_iter_next(, NULL, (void **))) {
> 
> Is this cast kosher?

You may have a point that it violates some corner of C99, but I'm not
the first such user:

hw/i386/intel_iommu.c:while (g_hash_table_iter_next (_it, NULL,
(void**)_bus)) {
qom/object.c:while (g_hash_table_iter_next(, NULL, (gpointer
*))) {

Conceptually, it seems fine - void* can be assigned to any pointer, and
'any' qualifies as such a pointer.  We are then taking the address of
that (or void**) to pass by reference.

I suppose a stricter version would be:

void *wrap;
GQueue *any;
if (g_hash_table_iter_next(, NULL, )) {
any = wrap;
...

but is it worth the bother?  Put another way, will a compiler ever do
the wrong thing to us because C99 might have some corner case?  Laszlo,
what's your take?

>>  if (top_ht) {
>> -if (g_hash_table_size(top_ht)) {
>> -const char *key;
>> -g_hash_table_find(top_ht, always_true, );
>> +GHashTableIter iter;
>> +const char *key;
>> +
>> +g_hash_table_iter_init(, top_ht);
>> +if (g_hash_table_iter_next(, (void **), NULL)) {
> 
> Is this cast kosher?

Here, in addition to the above argument, we also needed to cast away const.

-- 
Eric Blake   eblake redhat com+1-919-301-3266
Libvirt virtualization library http://libvirt.org



signature.asc
Description: OpenPGP digital signature


[Qemu-devel] [PATCH v3 1/3] target-arm: Apply S2 MMU startlevel table size check to AArch64

2016-01-22 Thread Edgar E. Iglesias
From: "Edgar E. Iglesias" 

The S2 starting level table size check applies to both AArch32
and AArch64. Move it to common code.

Reviewed-by: Alex Bennée 
Signed-off-by: Edgar E. Iglesias 
---
 target-arm/helper.c | 16 
 1 file changed, 8 insertions(+), 8 deletions(-)

diff --git a/target-arm/helper.c b/target-arm/helper.c
index f956b67..8aedce9 100644
--- a/target-arm/helper.c
+++ b/target-arm/helper.c
@@ -6581,11 +6581,19 @@ typedef enum {
 static bool check_s2_startlevel(ARMCPU *cpu, bool is_aa64, int level,
 int inputsize, int stride)
 {
+const int grainsize = stride + 3;
+int startsizecheck;
+
 /* Negative levels are never allowed.  */
 if (level < 0) {
 return false;
 }
 
+startsizecheck = inputsize - ((3 - level) * stride + grainsize);
+if (startsizecheck < 1 || startsizecheck > stride + 4) {
+return false;
+}
+
 if (is_aa64) {
 unsigned int pamax = arm_pamax(cpu);
 
@@ -6609,20 +6617,12 @@ static bool check_s2_startlevel(ARMCPU *cpu, bool 
is_aa64, int level,
 g_assert_not_reached();
 }
 } else {
-const int grainsize = stride + 3;
-int startsizecheck;
-
 /* AArch32 only supports 4KB pages. Assert on that.  */
 assert(stride == 9);
 
 if (level == 0) {
 return false;
 }
-
-startsizecheck = inputsize - ((3 - level) * stride + grainsize);
-if (startsizecheck < 1 || startsizecheck > stride + 4) {
-return false;
-}
 }
 return true;
 }
-- 
1.9.1




[Qemu-devel] [PATCH v3 2/3] target-arm: Make pamax an argument to check_s2_startlevel

2016-01-22 Thread Edgar E. Iglesias
From: "Edgar E. Iglesias" 

Make pamax an argument to check_s2_startlevel in preparation
for future reuse.

No functional change.

Reviewed-by: Alex Bennée 
Signed-off-by: Edgar E. Iglesias 
---
 target-arm/helper.c | 9 +
 1 file changed, 5 insertions(+), 4 deletions(-)

diff --git a/target-arm/helper.c b/target-arm/helper.c
index 8aedce9..2a6fa94 100644
--- a/target-arm/helper.c
+++ b/target-arm/helper.c
@@ -6575,11 +6575,13 @@ typedef enum {
  * @startlevel: Suggested starting level
  * @inputsize:  Bitsize of IPAs
  * @stride: Page-table stride (See the ARM ARM)
+ * @pamax:  Implementation defined bit-width of physical addresses
  *
  * Returns true if the suggested starting level is OK and false otherwise.
  */
 static bool check_s2_startlevel(ARMCPU *cpu, bool is_aa64, int level,
-int inputsize, int stride)
+int inputsize, int stride,
+unsigned int pamax)
 {
 const int grainsize = stride + 3;
 int startsizecheck;
@@ -6595,8 +6597,6 @@ static bool check_s2_startlevel(ARMCPU *cpu, bool 
is_aa64, int level,
 }
 
 if (is_aa64) {
-unsigned int pamax = arm_pamax(cpu);
-
 switch (stride) {
 case 13: /* 64KB Pages.  */
 if (level == 0 || (level == 1 && pamax <= 42)) {
@@ -6808,6 +6808,7 @@ static bool get_phys_addr_lpae(CPUARMState *env, 
target_ulong address,
  * VTCR_EL2.SL0 field (whose interpretation depends on the page size)
  */
 int startlevel = extract32(tcr->raw_tcr, 6, 2);
+unsigned int pamax = arm_pamax(cpu);
 bool ok;
 
 if (va_size == 32 || stride == 9) {
@@ -6820,7 +6821,7 @@ static bool get_phys_addr_lpae(CPUARMState *env, 
target_ulong address,
 
 /* Check that the starting level is valid. */
 ok = check_s2_startlevel(cpu, va_size == 64, level,
- inputsize, stride);
+ inputsize, stride, pamax);
 if (!ok) {
 /* AArch64 reports these as level 0 faults.
  * AArch32 reports these as level 1 faults.
-- 
1.9.1




[Qemu-devel] [PATCH v3 3/3] target-arm: Implement the S2 MMU inputsize > pamax check

2016-01-22 Thread Edgar E. Iglesias
From: "Edgar E. Iglesias" 

Implement the inputsize > pamax check for Stage 2 translations.
We have multiple choices for how to respond to errors and
choose to fault.

Signed-off-by: Edgar E. Iglesias 
---
 target-arm/helper.c | 16 
 1 file changed, 12 insertions(+), 4 deletions(-)

diff --git a/target-arm/helper.c b/target-arm/helper.c
index 2a6fa94..8901762 100644
--- a/target-arm/helper.c
+++ b/target-arm/helper.c
@@ -6809,7 +6809,7 @@ static bool get_phys_addr_lpae(CPUARMState *env, 
target_ulong address,
  */
 int startlevel = extract32(tcr->raw_tcr, 6, 2);
 unsigned int pamax = arm_pamax(cpu);
-bool ok;
+bool ok = true;
 
 if (va_size == 32 || stride == 9) {
 /* AArch32 or 4KB pages */
@@ -6819,9 +6819,17 @@ static bool get_phys_addr_lpae(CPUARMState *env, 
target_ulong address,
 level = 3 - startlevel;
 }
 
-/* Check that the starting level is valid. */
-ok = check_s2_startlevel(cpu, va_size == 64, level,
- inputsize, stride, pamax);
+if (va_size == 64 &&
+inputsize > pamax &&
+(arm_el_is_aa64(env, 1) || inputsize > 40)) {
+/* We have multiple choices but choose to fault.  */
+ok = false;
+}
+if (ok) {
+/* Check that the starting level is valid. */
+ok = check_s2_startlevel(cpu, va_size == 64, level,
+ inputsize, stride, pamax);
+}
 if (!ok) {
 /* AArch64 reports these as level 0 faults.
  * AArch32 reports these as level 1 faults.
-- 
1.9.1




Re: [Qemu-devel] [PATCH v2 2/4] blockdev: Fix 'change' for slot devices

2016-01-22 Thread Alberto Garcia
On Wed 20 Jan 2016 07:29:19 PM CET, Max Reitz wrote:
> @@ -2424,6 +2442,15 @@ static void qmp_blockdev_insert_anon_medium(const char 
> *device,
>  
>  blk_insert_bs(blk, bs);
>  
> +if (!blk_dev_has_tray(blk)) {
> +/* For tray-less devices, blockdev-close-tray is a no-op (or may not 
> be
> + * called at all); therefore, the medium needs to be pushed into the
> + * slot here.
> + * Do it after blk_insert_bs() so blk_is_inserted(blk) returns the 
> @load
> + * value passed here (i.e. true). */
> +blk_dev_change_media_cb(blk, true);
> +}
> +
>  QTAILQ_INSERT_TAIL(_states, bs, device_list);
>  }

Any reason why you do this before updating bdrv_states ?

If the device has a tray this would happen afterwards, in
qmp_blockdev_close_tray().

Berto



Re: [Qemu-devel] [PATCH] dimm: Correct type of MemoryHotplugState->base

2016-01-22 Thread Igor Mammedov
On Thu, 21 Jan 2016 12:37:51 +1100
David Gibson  wrote:

> The 'base' field of MemoryHotplugState is ram_addr_t, which indicates that
> it exists in the abstract address space of RAM regions.
> 
> However, the actual usage of this field indicates that it is a concrete
> physical address (it's passed as an offset to memory_region_add_subgregion
> for example).
> 
> So, correct its type to 'hwaddr'.
> 
> Signed-off-by: David Gibson 
> ---
>  include/hw/mem/pc-dimm.h | 2 +-
>  1 file changed, 1 insertion(+), 1 deletion(-)
> 
> diff --git a/include/hw/mem/pc-dimm.h b/include/hw/mem/pc-dimm.h
> index d83bf30..218dfb0 100644
> --- a/include/hw/mem/pc-dimm.h
> +++ b/include/hw/mem/pc-dimm.h
> @@ -77,7 +77,7 @@ typedef struct PCDIMMDeviceClass {
>   * @mr: hotplug memory address space container
>   */
>  typedef struct MemoryHotplugState {
> -ram_addr_t base;
> +hwaddr base;
>  MemoryRegion mr;
>  } MemoryHotplugState;
>  

I agree with this fix but that's not the only place where
ram_addr_t needs to be replaced with hwaddr.
For example type of MachineState.[max]ram_size fields needs
to be changed as well. Because QEMU builds without CONFIG_XEN_BACKEND
on 32-bit hosts are broken since ram_addr_t is 32-bits there
while some targets assume and use it as 64-bit one.





Re: [Qemu-devel] [PATCH RFC 0/7] Netfilter: Add each netdev a default filter

2016-01-22 Thread Daniel P. Berrange
On Fri, Jan 22, 2016 at 04:36:44PM +0800, zhanghailiang wrote:
> This series is a prerequisite for COLO, here we add each netdev
> a default buffer filter, it is disabled by default, and has
> no side effect for delivering packets in net layer.

Why can't whatever is launching QEMU just setup filters explicitly
if they want to use COLO ? I'm not seeing an obvious compelling
reason to add this by default and then add extra code to deal
with special casing its behaviour.

> 
> Besides, patch 1 fixes the ouput information of 'info network' command
> for filter.
> 
> zhanghailiang (7):
>   net/filter: Fix the output information for command 'info network'
>   net/filter: Add a 'status' property for filter object
>   net/filter: Skip the disabled filter when delivering packets
>   net/filter: Introduce a helper to add a filter to the netdev
>   filter-buffer: Accept zero interval
>   net/filter: Add a default filter to each netdev
>   net/filter: prevent the default filter to be deleted
> 
>  include/net/filter.h |  25 +++-
>  net/dump.c   |   2 -
>  net/filter-buffer.c  |  10 
>  net/filter.c | 163 
> +--
>  net/net.c|  27 -
>  5 files changed, 194 insertions(+), 33 deletions(-)

Regards,
Daniel
-- 
|: http://berrange.com  -o-http://www.flickr.com/photos/dberrange/ :|
|: http://libvirt.org  -o- http://virt-manager.org :|
|: http://autobuild.org   -o- http://search.cpan.org/~danberr/ :|
|: http://entangle-photo.org   -o-   http://live.gnome.org/gtk-vnc :|



Re: [Qemu-devel] [PATCH RFC 0/7] Netfilter: Add each netdev a default filter

2016-01-22 Thread Daniel P. Berrange
On Fri, Jan 22, 2016 at 06:35:48PM +0800, Hailiang Zhang wrote:
> On 2016/1/22 18:07, Daniel P. Berrange wrote:
> >On Fri, Jan 22, 2016 at 04:36:44PM +0800, zhanghailiang wrote:
> >>This series is a prerequisite for COLO, here we add each netdev
> >>a default buffer filter, it is disabled by default, and has
> >>no side effect for delivering packets in net layer.
> >
> >Why can't whatever is launching QEMU just setup filters explicitly
> >if they want to use COLO ? I'm not seeing an obvious compelling
> >reason to add this by default and then add extra code to deal
> >with special casing its behaviour.
> >
> 
> The main reason is, we hope to support hot add network during VM's COLO
> lifetime in the future. (I'm not quite sure if this usage case is really 
> exist,
> but we don't want the VM in COLO state has too many limitations.)
> 
> Maybe add an option that users can control if they want to use COLO or not is 
> more
> acceptable ? With this option, we can decide whether to add the default 
> filter or not.
> Or, we could dynamically add filter while users ask to go into COLO state for 
> VM.
> (We have discussed this before in community, and Jason suggested me to add 
> default
> filter for each netdev to support hot-add network during COLO state).
> 
> What's your suggestion ?

Why can't the app hot-adding the network interface also configure a
filter at that time if they're using COLO ?

Regards,
Daniel
-- 
|: http://berrange.com  -o-http://www.flickr.com/photos/dberrange/ :|
|: http://libvirt.org  -o- http://virt-manager.org :|
|: http://autobuild.org   -o- http://search.cpan.org/~danberr/ :|
|: http://entangle-photo.org   -o-   http://live.gnome.org/gtk-vnc :|



Re: [Qemu-devel] [PATCH] linux-user: add option to intercept execve() syscalls

2016-01-22 Thread Peter Maydell
On 22 January 2016 at 10:33, Laurent Vivier  wrote:
> Le 22/01/2016 11:01, Petros Angelatos a écrit :
>> This was my initial approach too, but argv[0] can be just the filename
>> like "qemu-arm-static". And while I could add extra logic to look this
>> up in the PATH, someone could run it from a completely different
>> location. Then I looked for a way to get the path of the current
>> executable but every platform has its own way of doing that and I
>> didn't want to add all these cases.
>>
>> https://stackoverflow.com/questions/1023306/finding-current-executables-path-without-proc-self-exe
>
> linux-user works only on linux.
> qemu uses glib-2.0, so you can use g_find_program_in_path().

If QEMU was started via execle() to set the environment of the
executed process and that specified environment has a different
PATH, then g_find_program_in_path() will give the wrong answer.
Using AT_EXECFN (perhaps with a fallback to /proc/self/exe) seems
like a better approach to me.

>> questions. Is it ok that I deleted part of the patch for my reply to
>> code review, or should I have replied inline without deleting
>
> Generally, it's better to not delete parts. So, someone tacking the mail
> thread at a moment can read the whole history in the last mail.

I tend to happily delete parts and assume that readers have
access to the thread (via the archive or in their mail readers).
Not deleting bits makes it hard to read replies if there's
a conversation about a small part of a large patch.

thanks
-- PMM



[Qemu-devel] [PATCH] seabios: fix submodule

2016-01-22 Thread Gerd Hoffmann
Commit "36f96c4 target-i386: Add support to migrate vcpu's TSC rate"
updates roms/seabios, appearently by mistake.  Revert this.

Signed-off-by: Gerd Hoffmann 
---
 roms/seabios | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/roms/seabios b/roms/seabios
index 33fbe13..01a84be 16
--- a/roms/seabios
+++ b/roms/seabios
@@ -1 +1 @@
-Subproject commit 33fbe13a3e2a01e0ba1087a8feed801a0451db21
+Subproject commit 01a84bea2d28a19d2405c1ecac4bdef17683cc0c
-- 
1.8.3.1




Re: [Qemu-devel] [PATCH 2/2] net: netmap: avoid mmap() when ports use the same shared memory area

2016-01-22 Thread Vincenzo Maffione
No, you're right, nm_mmap() is not defined for all netmap versions.

It will take a while for us to decide how to manage this. Would it be
possible to go ahead with patch 1/2 only (I will reissue the patch
series)?

Cheers,
  Vincenzo

2016-01-14 4:25 GMT+01:00 Jason Wang :
>
>
> On 01/08/2016 09:15 PM, Vincenzo Maffione wrote:
>> With this patch, nm_open() does not mmap() the netmap device. This
>> operation is performed separately only if the memory area of the
>> port just opened was not known before.
>> A global list of netmap clients is kept to check when matches
>> occur.
>>
>> Signed-off-by: Vincenzo Maffione 
>> ---
>>  net/netmap.c | 38 +-
>>  1 file changed, 37 insertions(+), 1 deletion(-)
>>
>> diff --git a/net/netmap.c b/net/netmap.c
>> index 27295ab..6a4c01c 100644
>> --- a/net/netmap.c
>> +++ b/net/netmap.c
>> @@ -49,8 +49,12 @@ typedef struct NetmapState {
>>  boolwrite_poll;
>>  struct ioveciov[IOV_MAX];
>>  int vnet_hdr_len;  /* Current virtio-net header length. 
>> */
>> +QTAILQ_ENTRY(NetmapState) next;
>>  } NetmapState;
>>
>> +static QTAILQ_HEAD(, NetmapState) netmap_clients =
>> +   QTAILQ_HEAD_INITIALIZER(netmap_clients);
>> +
>>  #ifndef __FreeBSD__
>>  #define pkt_copy bcopy
>>  #else
>> @@ -78,6 +82,23 @@ pkt_copy(const void *_src, void *_dst, int l)
>>  #endif /* __FreeBSD__ */
>>
>>  /*
>> + * find nm_desc parent with same allocator
>> + */
>> +static struct nm_desc *
>> +netmap_find_memory(struct nm_desc *nmd)
>> +{
>> +NetmapState *s;
>> +
>> +QTAILQ_FOREACH(s, _clients, next) {
>> +if (nmd->req.nr_arg2 == s->nmd->req.nr_arg2) {
>> +return s->nmd;
>> +}
>> +}
>> +
>> +return NULL;
>> +}
>> +
>> +/*
>>   * Open a netmap device. We assume there is only one queue
>>   * (which is the case for the VALE bridge).
>>   */
>> @@ -86,10 +107,11 @@ static struct nm_desc *netmap_open(const 
>> NetdevNetmapOptions *nm_opts,
>>  {
>>  struct nm_desc *nmd;
>>  struct nmreq req;
>> +int ret;
>>
>>  memset(, 0, sizeof(req));
>>
>> -nmd = nm_open(nm_opts->ifname, , NETMAP_NO_TX_POLL,
>> +nmd = nm_open(nm_opts->ifname, , NETMAP_NO_TX_POLL | 
>> NM_OPEN_NO_MMAP,
>>NULL);
>>  if (nmd == NULL) {
>>  error_setg_errno(errp, errno, "Failed to nm_open() %s",
>> @@ -97,6 +119,17 @@ static struct nm_desc *netmap_open(const 
>> NetdevNetmapOptions *nm_opts,
>>  return NULL;
>>  }
>>
>> +/* Check if we already have a nm_desc that uses the same memory as the 
>> one
>> + * just opened, so that nm_mmap() can skip mmap() and inherit from 
>> parent.
>> + */
>> +ret = nm_mmap(nmd, netmap_find_memory(nmd));
>
> Looks like I could not find nm_mmap() definition in neither qemu or
> freebsd source. Is there anything missed?
>
>> +if (ret) {
>> +error_setg_errno(errp, errno, "Failed to nm_mmap() %s",
>> + nm_opts->ifname);
>> +nm_close(nmd);
>> +return NULL;
>> +}
>> +
>>  return nmd;
>>  }
>>
>> @@ -321,6 +354,8 @@ static void netmap_cleanup(NetClientState *nc)
>>  netmap_poll(nc, false);
>>  nm_close(s->nmd);
>>  s->nmd = NULL;
>> +
>> +QTAILQ_REMOVE(_clients, s, next);
>>  }
>>
>>  /* Offloading manipulation support callbacks. */
>> @@ -423,6 +458,7 @@ int net_init_netmap(const NetClientOptions *opts,
>>  s->rx = NETMAP_RXRING(nmd->nifp, 0);
>>  s->vnet_hdr_len = 0;
>>  pstrcpy(s->ifname, sizeof(s->ifname), netmap_opts->ifname);
>> +QTAILQ_INSERT_TAIL(_clients, s, next);
>>  netmap_read_poll(s, true); /* Initially only poll for reads. */
>>
>>  return 0;
>



-- 
Vincenzo Maffione



Re: [Qemu-devel] [PATCH] e1000: eliminate infinite loops on out-of-bounds transfer start

2016-01-22 Thread Laszlo Ersek
On 01/22/16 07:15, Jason Wang wrote:
> 
> 
> On 01/22/2016 02:11 PM, Michael Tokarev wrote:
>> 22.01.2016 06:09, Jason Wang wrote:
>>> On 01/19/2016 09:17 PM, Laszlo Ersek wrote:
 The start_xmit() and e1000_receive_iov() functions implement DMA transfers
 iterating over a set of descriptors that the guest's e1000 driver
 prepares:
>> ...
>>> Applied in my -net.
>> This is CVE-2016-1981, btw.
>>
>> /mjt
>>
> 
> Add this into commit log.

Thanks guys!
Laszlo




[Qemu-devel] [PATCH v2] qom, qmp, hmp, qapi: create qom-type-list for class properties

2016-01-22 Thread Valentin Rakush
This patch adds support for qom-type-prop-list command to list object 
class properties. A later patch will use this functionality to 
implement x86_64-cpu properties.

Signed-off-by: Valentin Rakush 
Cc: Luiz Capitulino 
Cc: Eric Blake 
Cc: Markus Armbruster 
Cc: Andreas Färber 
Cc: Daniel P. Berrange 
---
V2: Fixes after first review
 - changed command name from qom-type-list to qom-type-prop-list
 - changed memory allocation from g_malloc0 to g_new0
 - changed parameter name from path to typename
 - fixed wordings and comments
 - fixed source code formatting
 - registered the command in monitor
   
 hmp-commands.hx  | 13 +
 hmp.c| 26 ++
 hmp.h|  1 +
 include/qom/object.h | 31 +++
 qapi-schema.json | 19 +++
 qmp-commands.hx  |  6 ++
 qmp.c| 32 
 qom/object.c |  7 +++
 8 files changed, 135 insertions(+)

diff --git a/hmp-commands.hx b/hmp-commands.hx
index bb52e4d..0aca653 100644
--- a/hmp-commands.hx
+++ b/hmp-commands.hx
@@ -1734,6 +1734,19 @@ Print QOM properties of object at location @var{path}
 ETEXI
 
 {
+.name   = "qom-type-prop-list",
+.args_type  = "typename:s?",
+.params = "typename",
+.help   = "list QOM class properties",
+.mhandler.cmd  = hmp_qom_type_prop_list,
+},
+
+STEXI
+@item qom-type-prop-list [@var{typename}]
+Print QOM properties of the type @var{typename}
+ETEXI
+
+{
 .name   = "qom-set",
 .args_type  = "path:s,property:s,value:s",
 .params = "path property value",
diff --git a/hmp.c b/hmp.c
index 54f2620..4bad6a1 100644
--- a/hmp.c
+++ b/hmp.c
@@ -2052,6 +2052,32 @@ void hmp_qom_list(Monitor *mon, const QDict *qdict)
 hmp_handle_error(mon, );
 }
 
+void hmp_qom_type_prop_list(Monitor *mon, const QDict *qdict)
+{
+const char *path = qdict_get_try_str(qdict, "path");
+ObjectPropertyInfoList *list;
+Error *err = NULL;
+
+if (!path) {
+monitor_printf(mon, "/\n");
+return;
+}
+
+list = qmp_qom_type_prop_list(path, );
+if (!err) {
+ObjectPropertyInfoList *start = list;
+while (list) {
+ObjectPropertyInfo *value = list->value;
+
+monitor_printf(mon, "%s (%s)\n",
+   value->name, value->type);
+list = list->next;
+}
+qapi_free_ObjectPropertyInfoList(start);
+}
+hmp_handle_error(mon, );
+}
+
 void hmp_qom_set(Monitor *mon, const QDict *qdict)
 {
 const char *path = qdict_get_str(qdict, "path");
diff --git a/hmp.h b/hmp.h
index a8c5b5a..8c12ebe 100644
--- a/hmp.h
+++ b/hmp.h
@@ -103,6 +103,7 @@ void hmp_object_del(Monitor *mon, const QDict *qdict);
 void hmp_info_memdev(Monitor *mon, const QDict *qdict);
 void hmp_info_memory_devices(Monitor *mon, const QDict *qdict);
 void hmp_qom_list(Monitor *mon, const QDict *qdict);
+void hmp_qom_type_prop_list(Monitor *mon, const QDict *qdict);
 void hmp_qom_set(Monitor *mon, const QDict *qdict);
 void object_add_completion(ReadLineState *rs, int nb_args, const char *str);
 void object_del_completion(ReadLineState *rs, int nb_args, const char *str);
diff --git a/include/qom/object.h b/include/qom/object.h
index d0dafe9..0c8379d 100644
--- a/include/qom/object.h
+++ b/include/qom/object.h
@@ -1013,6 +1013,37 @@ void object_property_iter_init(ObjectPropertyIterator 
*iter,
  */
 ObjectProperty *object_property_iter_next(ObjectPropertyIterator *iter);
 
+/**
+ * object_class_property_iter_init:
+ * @klass: the class owning the properties to be iterated over
+ *
+ * Initializes an iterator for traversing all properties
+ * registered against a class type and all parent classes.
+ *
+ * It is forbidden to modify the property list while iterating,
+ * whether removing or adding properties.
+ *
+ * NB For getting next property in the list the object related
+ * function object_property_iter_next is still used.
+ *
+ * Typical usage pattern would be
+ *
+ * 
+ *   Using object class property iterators
+ *   
+ *   ObjectProperty *prop;
+ *   ObjectPropertyIterator iter;
+ *
+ *   object_class property_iter_init(, obj);
+ *   while ((prop = object_property_iter_next())) {
+ * ... do something with prop ...
+ *   }
+ *   
+ * 
+ */
+void object_class_property_iter_init(ObjectPropertyIterator *iter,
+ ObjectClass *klass);
+
 void object_unparent(Object *obj);
 
 /**
diff --git a/qapi-schema.json b/qapi-schema.json
index b3038b2..2e960db 100644
--- a/qapi-schema.json
+++ b/qapi-schema.json
@@ -4081,3 +4081,22 @@
 ##
 { 'enum': 'ReplayMode',
   'data': [ 'none', 'record', 'play' ] }
+
+##
+# @qom-type-prop-list:
+#
+# This command will list any properties of an object 

[Qemu-devel] [PATCH v3] qom, qmp, hmp, qapi: create qom-type-prop-list for class properties

2016-01-22 Thread Valentin Rakush
This patch adds support for qom-type-prop-list command to list object
class properties. A later patch will use this functionality to
implement x86_64-cpu properties.

Signed-off-by: Valentin Rakush 
Cc: Luiz Capitulino 
Cc: Eric Blake 
Cc: Markus Armbruster 
Cc: Andreas Färber 
Cc: Daniel P. Berrange 
---
V2: Fixes after first review
 - changed command name from qom-type-list to qom-type-prop-list
 - changed memory allocation from g_malloc0 to g_new0
 - changed parameter name from path to typename
 - fixed wordings and comments
 - fixed source code formatting
 - registered the command in monitor
V3: commit message fix 
 - commit message changed to reflect actual command name


 hmp-commands.hx  | 13 +
 hmp.c| 26 ++
 hmp.h|  1 +
 include/qom/object.h | 31 +++
 qapi-schema.json | 19 +++
 qmp-commands.hx  |  6 ++
 qmp.c| 32 
 qom/object.c |  7 +++
 8 files changed, 135 insertions(+)

diff --git a/hmp-commands.hx b/hmp-commands.hx
index bb52e4d..0aca653 100644
--- a/hmp-commands.hx
+++ b/hmp-commands.hx
@@ -1734,6 +1734,19 @@ Print QOM properties of object at location @var{path}
 ETEXI
 
 {
+.name   = "qom-type-prop-list",
+.args_type  = "typename:s?",
+.params = "typename",
+.help   = "list QOM class properties",
+.mhandler.cmd  = hmp_qom_type_prop_list,
+},
+
+STEXI
+@item qom-type-prop-list [@var{typename}]
+Print QOM properties of the type @var{typename}
+ETEXI
+
+{
 .name   = "qom-set",
 .args_type  = "path:s,property:s,value:s",
 .params = "path property value",
diff --git a/hmp.c b/hmp.c
index 54f2620..4bad6a1 100644
--- a/hmp.c
+++ b/hmp.c
@@ -2052,6 +2052,32 @@ void hmp_qom_list(Monitor *mon, const QDict *qdict)
 hmp_handle_error(mon, );
 }
 
+void hmp_qom_type_prop_list(Monitor *mon, const QDict *qdict)
+{
+const char *path = qdict_get_try_str(qdict, "path");
+ObjectPropertyInfoList *list;
+Error *err = NULL;
+
+if (!path) {
+monitor_printf(mon, "/\n");
+return;
+}
+
+list = qmp_qom_type_prop_list(path, );
+if (!err) {
+ObjectPropertyInfoList *start = list;
+while (list) {
+ObjectPropertyInfo *value = list->value;
+
+monitor_printf(mon, "%s (%s)\n",
+   value->name, value->type);
+list = list->next;
+}
+qapi_free_ObjectPropertyInfoList(start);
+}
+hmp_handle_error(mon, );
+}
+
 void hmp_qom_set(Monitor *mon, const QDict *qdict)
 {
 const char *path = qdict_get_str(qdict, "path");
diff --git a/hmp.h b/hmp.h
index a8c5b5a..8c12ebe 100644
--- a/hmp.h
+++ b/hmp.h
@@ -103,6 +103,7 @@ void hmp_object_del(Monitor *mon, const QDict *qdict);
 void hmp_info_memdev(Monitor *mon, const QDict *qdict);
 void hmp_info_memory_devices(Monitor *mon, const QDict *qdict);
 void hmp_qom_list(Monitor *mon, const QDict *qdict);
+void hmp_qom_type_prop_list(Monitor *mon, const QDict *qdict);
 void hmp_qom_set(Monitor *mon, const QDict *qdict);
 void object_add_completion(ReadLineState *rs, int nb_args, const char *str);
 void object_del_completion(ReadLineState *rs, int nb_args, const char *str);
diff --git a/include/qom/object.h b/include/qom/object.h
index d0dafe9..0c8379d 100644
--- a/include/qom/object.h
+++ b/include/qom/object.h
@@ -1013,6 +1013,37 @@ void object_property_iter_init(ObjectPropertyIterator 
*iter,
  */
 ObjectProperty *object_property_iter_next(ObjectPropertyIterator *iter);
 
+/**
+ * object_class_property_iter_init:
+ * @klass: the class owning the properties to be iterated over
+ *
+ * Initializes an iterator for traversing all properties
+ * registered against a class type and all parent classes.
+ *
+ * It is forbidden to modify the property list while iterating,
+ * whether removing or adding properties.
+ *
+ * NB For getting next property in the list the object related
+ * function object_property_iter_next is still used.
+ *
+ * Typical usage pattern would be
+ *
+ * 
+ *   Using object class property iterators
+ *   
+ *   ObjectProperty *prop;
+ *   ObjectPropertyIterator iter;
+ *
+ *   object_class property_iter_init(, obj);
+ *   while ((prop = object_property_iter_next())) {
+ * ... do something with prop ...
+ *   }
+ *   
+ * 
+ */
+void object_class_property_iter_init(ObjectPropertyIterator *iter,
+ ObjectClass *klass);
+
 void object_unparent(Object *obj);
 
 /**
diff --git a/qapi-schema.json b/qapi-schema.json
index b3038b2..2e960db 100644
--- a/qapi-schema.json
+++ b/qapi-schema.json
@@ -4081,3 +4081,22 @@
 ##
 { 'enum': 'ReplayMode',
   'data': [ 'none', 'record', 'play' ] }
+
+##
+# 

Re: [Qemu-devel] [PATCH v2 4/4] block/qapi: Emit tray_open only if there is a tray

2016-01-22 Thread Alberto Garcia
On Wed 20 Jan 2016 07:29:21 PM CET, Max Reitz wrote:
> Signed-off-by: Max Reitz 
> ---
>  block/qapi.c   | 2 +-
>  qapi/block-core.json   | 4 ++--
>  tests/qemu-iotests/067.out | 4 
>  3 files changed, 3 insertions(+), 7 deletions(-)

Reviewed-by: Alberto Garcia 

Berto



Re: [Qemu-devel] [PATCH v3] qom, qmp, hmp, qapi: create qom-type-prop-list for class properties

2016-01-22 Thread Daniel P. Berrange
On Fri, Jan 22, 2016 at 12:26:52PM +0300, Valentin Rakush wrote:
> This patch adds support for qom-type-prop-list command to list object
> class properties. A later patch will use this functionality to
> implement x86_64-cpu properties.
> 
> Signed-off-by: Valentin Rakush 
> Cc: Luiz Capitulino 
> Cc: Eric Blake 
> Cc: Markus Armbruster 
> Cc: Andreas Färber 
> Cc: Daniel P. Berrange 
> ---
> V2: Fixes after first review
>  - changed command name from qom-type-list to qom-type-prop-list
>  - changed memory allocation from g_malloc0 to g_new0
>  - changed parameter name from path to typename
>  - fixed wordings and comments
>  - fixed source code formatting
>  - registered the command in monitor
> V3: commit message fix 
>  - commit message changed to reflect actual command name
> 
> 
>  hmp-commands.hx  | 13 +
>  hmp.c| 26 ++
>  hmp.h|  1 +
>  include/qom/object.h | 31 +++
>  qapi-schema.json | 19 +++
>  qmp-commands.hx  |  6 ++
>  qmp.c| 32 
>  qom/object.c |  7 +++
>  8 files changed, 135 insertions(+)
> 
> diff --git a/hmp-commands.hx b/hmp-commands.hx
> index bb52e4d..0aca653 100644
> --- a/hmp-commands.hx
> +++ b/hmp-commands.hx
> @@ -1734,6 +1734,19 @@ Print QOM properties of object at location @var{path}
>  ETEXI
>  
>  {
> +.name   = "qom-type-prop-list",
> +.args_type  = "typename:s?",

The typename should be mandatory so remove the '?' here, then.

> +.params = "typename",
> +.help   = "list QOM class properties",
> +.mhandler.cmd  = hmp_qom_type_prop_list,
> +},
> +
> +STEXI
> +@item qom-type-prop-list [@var{typename}]
> +Print QOM properties of the type @var{typename}
> +ETEXI
> +
> +{
>  .name   = "qom-set",
>  .args_type  = "path:s,property:s,value:s",
>  .params = "path property value",
> diff --git a/hmp.c b/hmp.c
> index 54f2620..4bad6a1 100644
> --- a/hmp.c
> +++ b/hmp.c
> @@ -2052,6 +2052,32 @@ void hmp_qom_list(Monitor *mon, const QDict *qdict)
>  hmp_handle_error(mon, );
>  }
>  
> +void hmp_qom_type_prop_list(Monitor *mon, const QDict *qdict)
> +{
> +const char *path = qdict_get_try_str(qdict, "path");
> +ObjectPropertyInfoList *list;
> +Error *err = NULL;
> +
> +if (!path) {
> +monitor_printf(mon, "/\n");
> +return;
> +}

...you don't need this check for path being NULL, you can assume
it is non-NULL

> +
> +list = qmp_qom_type_prop_list(path, );
> +if (!err) {
> +ObjectPropertyInfoList *start = list;
> +while (list) {
> +ObjectPropertyInfo *value = list->value;
> +
> +monitor_printf(mon, "%s (%s)\n",
> +   value->name, value->type);
> +list = list->next;
> +}
> +qapi_free_ObjectPropertyInfoList(start);
> +}
> +hmp_handle_error(mon, );
> +}
> +

Aside from that I think this change looks good.

Regards,
Daniel
-- 
|: http://berrange.com  -o-http://www.flickr.com/photos/dberrange/ :|
|: http://libvirt.org  -o- http://virt-manager.org :|
|: http://autobuild.org   -o- http://search.cpan.org/~danberr/ :|
|: http://entangle-photo.org   -o-   http://live.gnome.org/gtk-vnc :|



Re: [Qemu-devel] [PATCH v1] kvm/x86: Hyper-V tsc page setup

2016-01-22 Thread Paolo Bonzini


On 24/12/2015 10:33, Andrey Smetanin wrote:
> Lately tsc page was implemented but filled with empty
> values. This patch setup tsc page scale and offset based
> on vcpu tsc, tsc_khz and  HV_X64_MSR_TIME_REF_COUNT value.
> 
> The valid tsc page drops HV_X64_MSR_TIME_REF_COUNT msr
> reads count to zero which potentially improves performance.
> 
> The patch applies on top of
> 'kvm: Make vcpu->requests as 64 bit bitmap'
> previously sent.
> 
> Signed-off-by: Andrey Smetanin 
> CC: Paolo Bonzini 
> CC: Gleb Natapov 
> CC: Roman Kagan 
> CC: Denis V. Lunev 
> CC: qemu-devel@nongnu.org

Actually there are some more issues:

- unless KVM can use a master clock, it is incorrect to set up the TSC
page this way; the sequence needs to be 0x in that case

- writing the TSC page must be done while all VCPUs are stopped, because
the TSC page doesn't provide the possibility for the guest to retry in
the middle of an update (like seqcount in Linux doess)

In the end, the TSC page is actually pretty similar to the kvmclock
master clock and it makes sense to build it on the master clock too.
I'll post a patch next week.

Paolo

> ---
>  arch/x86/kvm/hyperv.c| 117 
> +--
>  arch/x86/kvm/hyperv.h|   2 +
>  arch/x86/kvm/x86.c   |  12 +
>  include/linux/kvm_host.h |   1 +
>  4 files changed, 117 insertions(+), 15 deletions(-)
> 
> diff --git a/arch/x86/kvm/hyperv.c b/arch/x86/kvm/hyperv.c
> index d50675a..504fdc7 100644
> --- a/arch/x86/kvm/hyperv.c
> +++ b/arch/x86/kvm/hyperv.c
> @@ -753,6 +753,105 @@ static int kvm_hv_msr_set_crash_data(struct kvm_vcpu 
> *vcpu,
>   return 0;
>  }
>  
> +static u64 calc_tsc_page_scale(u32 tsc_khz)
> +{
> + /*
> +  * reftime (in 100ns) = tsc * tsc_scale / 2^64 + tsc_offset
> +  * so reftime_delta = (tsc_delta * tsc_scale) / 2^64
> +  * so tsc_scale = (2^64 * reftime_delta)/tsc_delta
> +  * so tsc_scale = (2^64 * 10 * 10^6) / tsc_hz = (2^64 * 1) / tsc_khz
> +  * so tsc_scale = (2^63 * 2 * 1) / tsc_khz
> +  */
> + return mul_u64_u32_div(1ULL << 63, 2 * 1, tsc_khz);
> +}
> +
> +static int write_tsc_page(struct kvm *kvm, u64 gfn,
> +   PHV_REFERENCE_TSC_PAGE tsc_ref)
> +{
> + if (kvm_write_guest(kvm, gfn_to_gpa(gfn),
> + tsc_ref, sizeof(*tsc_ref)))
> + return 1;
> + mark_page_dirty(kvm, gfn);
> + return 0;
> +}
> +
> +static int read_tsc_page(struct kvm *kvm, u64 gfn,
> +  PHV_REFERENCE_TSC_PAGE tsc_ref)
> +{
> + if (kvm_read_guest(kvm, gfn_to_gpa(gfn),
> +tsc_ref, sizeof(*tsc_ref)))
> + return 1;
> + return 0;
> +}
> +
> +static u64 calc_tsc_page_time(struct kvm_vcpu *vcpu,
> +   PHV_REFERENCE_TSC_PAGE tsc_ref)
> +{
> +
> + u64 tsc = kvm_read_l1_tsc(vcpu, rdtsc());
> +
> + return mul_u64_u64_shr(tsc, tsc_ref->tsc_scale, 64)
> + + tsc_ref->tsc_offset;
> +}
> +
> +static int setup_blank_tsc_page(struct kvm_vcpu *vcpu, u64 gfn)
> +{
> + HV_REFERENCE_TSC_PAGE tsc_ref;
> +
> + memset(_ref, 0, sizeof(tsc_ref));
> + return write_tsc_page(vcpu->kvm, gfn, _ref);
> +}
> +
> +int kvm_hv_setup_tsc_page(struct kvm_vcpu *vcpu)
> +{
> + struct kvm *kvm = vcpu->kvm;
> + struct kvm_hv *hv = >arch.hyperv;
> + HV_REFERENCE_TSC_PAGE tsc_ref;
> + u32 tsc_khz;
> + int r;
> + u64 gfn, ref_time, tsc_scale, tsc_offset, tsc;
> +
> + if (WARN_ON_ONCE(!(hv->hv_tsc_page & HV_X64_MSR_TSC_REFERENCE_ENABLE)))
> + return -EINVAL;
> +
> + gfn = hv->hv_tsc_page >> HV_X64_MSR_TSC_REFERENCE_ADDRESS_SHIFT;
> + vcpu_debug(vcpu, "tsc page gfn 0x%llx\n", gfn);
> +
> + tsc_khz = vcpu->arch.virtual_tsc_khz;
> + if (!tsc_khz) {
> + vcpu_unimpl(vcpu, "no tsc khz\n");
> + return setup_blank_tsc_page(vcpu, gfn);
> + }
> +
> + r = read_tsc_page(kvm, gfn, _ref);
> + if (r) {
> + vcpu_err(vcpu, "can't access tsc page gfn 0x%llx\n", gfn);
> + return r;
> + }
> +
> + tsc_scale = calc_tsc_page_scale(tsc_khz);
> + ref_time = get_time_ref_counter(kvm);
> + tsc = kvm_read_l1_tsc(vcpu, rdtsc());
> +
> + /* tsc_offset = reftime - tsc * tsc_scale / 2^64 */
> + tsc_offset = ref_time - mul_u64_u64_shr(tsc, tsc_scale, 64);
> + vcpu_debug(vcpu, "tsc khz %u tsc %llu scale %llu offset %llu\n",
> +tsc_khz, tsc, tsc_scale, tsc_offset);
> +
> + tsc_ref.tsc_sequence++;
> + if (tsc_ref.tsc_sequence == 0)
> + tsc_ref.tsc_sequence = 1;
> +
> + tsc_ref.tsc_scale = tsc_scale;
> + tsc_ref.tsc_offset = tsc_offset;
> +
> + vcpu_debug(vcpu, "tsc page calibration time %llu vs. reftime %llu\n",
> +calc_tsc_page_time(vcpu, _ref),
> +

Re: [Qemu-devel] [PATCH v1] kvm/x86: Hyper-V tsc page setup

2016-01-22 Thread Andrey Smetanin



On 01/22/2016 01:08 PM, Paolo Bonzini wrote:



On 24/12/2015 10:33, Andrey Smetanin wrote:

Lately tsc page was implemented but filled with empty
values. This patch setup tsc page scale and offset based
on vcpu tsc, tsc_khz and  HV_X64_MSR_TIME_REF_COUNT value.

The valid tsc page drops HV_X64_MSR_TIME_REF_COUNT msr
reads count to zero which potentially improves performance.

The patch applies on top of
'kvm: Make vcpu->requests as 64 bit bitmap'
previously sent.

Signed-off-by: Andrey Smetanin 
CC: Paolo Bonzini 
CC: Gleb Natapov 
CC: Roman Kagan 
CC: Denis V. Lunev 
CC: qemu-devel@nongnu.org


Actually there are some more issues:

- unless KVM can use a master clock, it is incorrect to set up the TSC
page this way; the sequence needs to be 0x in that case

0x is not an invalid value for tsc page,
see https://lkml.org/lkml/2015/11/2/655


- writing the TSC page must be done while all VCPUs are stopped, because
the TSC page doesn't provide the possibility for the guest to retry in
the middle of an update (like seqcount in Linux doess)
I think Windows guest gives tsc page address at boot time and protects 
against other vcpu's tsc page access.


In the end, the TSC page is actually pretty similar to the kvmclock
master clock and it makes sense to build it on the master clock too.
I'll post a patch next week.

Paolo


---
  arch/x86/kvm/hyperv.c| 117 +--
  arch/x86/kvm/hyperv.h|   2 +
  arch/x86/kvm/x86.c   |  12 +
  include/linux/kvm_host.h |   1 +
  4 files changed, 117 insertions(+), 15 deletions(-)

diff --git a/arch/x86/kvm/hyperv.c b/arch/x86/kvm/hyperv.c
index d50675a..504fdc7 100644
--- a/arch/x86/kvm/hyperv.c
+++ b/arch/x86/kvm/hyperv.c
@@ -753,6 +753,105 @@ static int kvm_hv_msr_set_crash_data(struct kvm_vcpu 
*vcpu,
return 0;
  }

+static u64 calc_tsc_page_scale(u32 tsc_khz)
+{
+   /*
+* reftime (in 100ns) = tsc * tsc_scale / 2^64 + tsc_offset
+* so reftime_delta = (tsc_delta * tsc_scale) / 2^64
+* so tsc_scale = (2^64 * reftime_delta)/tsc_delta
+* so tsc_scale = (2^64 * 10 * 10^6) / tsc_hz = (2^64 * 1) / tsc_khz
+* so tsc_scale = (2^63 * 2 * 1) / tsc_khz
+*/
+   return mul_u64_u32_div(1ULL << 63, 2 * 1, tsc_khz);
+}
+
+static int write_tsc_page(struct kvm *kvm, u64 gfn,
+ PHV_REFERENCE_TSC_PAGE tsc_ref)
+{
+   if (kvm_write_guest(kvm, gfn_to_gpa(gfn),
+   tsc_ref, sizeof(*tsc_ref)))
+   return 1;
+   mark_page_dirty(kvm, gfn);
+   return 0;
+}
+
+static int read_tsc_page(struct kvm *kvm, u64 gfn,
+PHV_REFERENCE_TSC_PAGE tsc_ref)
+{
+   if (kvm_read_guest(kvm, gfn_to_gpa(gfn),
+  tsc_ref, sizeof(*tsc_ref)))
+   return 1;
+   return 0;
+}
+
+static u64 calc_tsc_page_time(struct kvm_vcpu *vcpu,
+ PHV_REFERENCE_TSC_PAGE tsc_ref)
+{
+
+   u64 tsc = kvm_read_l1_tsc(vcpu, rdtsc());
+
+   return mul_u64_u64_shr(tsc, tsc_ref->tsc_scale, 64)
+   + tsc_ref->tsc_offset;
+}
+
+static int setup_blank_tsc_page(struct kvm_vcpu *vcpu, u64 gfn)
+{
+   HV_REFERENCE_TSC_PAGE tsc_ref;
+
+   memset(_ref, 0, sizeof(tsc_ref));
+   return write_tsc_page(vcpu->kvm, gfn, _ref);
+}
+
+int kvm_hv_setup_tsc_page(struct kvm_vcpu *vcpu)
+{
+   struct kvm *kvm = vcpu->kvm;
+   struct kvm_hv *hv = >arch.hyperv;
+   HV_REFERENCE_TSC_PAGE tsc_ref;
+   u32 tsc_khz;
+   int r;
+   u64 gfn, ref_time, tsc_scale, tsc_offset, tsc;
+
+   if (WARN_ON_ONCE(!(hv->hv_tsc_page & HV_X64_MSR_TSC_REFERENCE_ENABLE)))
+   return -EINVAL;
+
+   gfn = hv->hv_tsc_page >> HV_X64_MSR_TSC_REFERENCE_ADDRESS_SHIFT;
+   vcpu_debug(vcpu, "tsc page gfn 0x%llx\n", gfn);
+
+   tsc_khz = vcpu->arch.virtual_tsc_khz;
+   if (!tsc_khz) {
+   vcpu_unimpl(vcpu, "no tsc khz\n");
+   return setup_blank_tsc_page(vcpu, gfn);
+   }
+
+   r = read_tsc_page(kvm, gfn, _ref);
+   if (r) {
+   vcpu_err(vcpu, "can't access tsc page gfn 0x%llx\n", gfn);
+   return r;
+   }
+
+   tsc_scale = calc_tsc_page_scale(tsc_khz);
+   ref_time = get_time_ref_counter(kvm);
+   tsc = kvm_read_l1_tsc(vcpu, rdtsc());
+
+   /* tsc_offset = reftime - tsc * tsc_scale / 2^64 */
+   tsc_offset = ref_time - mul_u64_u64_shr(tsc, tsc_scale, 64);
+   vcpu_debug(vcpu, "tsc khz %u tsc %llu scale %llu offset %llu\n",
+  tsc_khz, tsc, tsc_scale, tsc_offset);
+
+   tsc_ref.tsc_sequence++;
+   if (tsc_ref.tsc_sequence == 0)
+   tsc_ref.tsc_sequence = 1;
+
+   tsc_ref.tsc_scale = tsc_scale;
+   tsc_ref.tsc_offset = tsc_offset;
+
+   vcpu_debug(vcpu, "tsc page calibration 

Re: [Qemu-devel] [Minios-devel] [PATCH v8 0/] Begin to disentangle libxenctrl and provide some stable libraries

2016-01-22 Thread Ian Campbell
On Tue, 2016-01-19 at 15:44 +, Ian Campbell wrote:
> On Fri, 2016-01-15 at 13:22 +, Ian Campbell wrote:
> >  
> > Therefore needing attention from Ian and/or Wei are:
> > 
> > tools/libs/foreignmemory: Mention restrictions on fork in docs.
> > N   tools/libs/evtchn: Use uint32_t for domid arguments
> > D   tools/libs/gnttab: Extensive updates to API documentation.
> >       tools/libs/call: linux: touch newly allocated pages after madvise
> > l
> > tools/libs/{call,evtchn}: Document requirements around forking.
> >    Rtools/libs/*: Use O_CLOEXEC on Linux and FreeBSD
> 
> Thanks to Wei for acking all of these. This set of series is now ready to
> go in, but we've not had a push for a little while and this is
> potentially
> disruptive so I'm going to hold off for now until we get a push.

We've now had a push in 78610 so I'm going to go ahead with applying this
mass of patches today.

> There are one or two patches which will require rebasing over Jeurgens
> introduction of tools/helpers, I'll resend just those ones though (or at
> least only the Xen part of this series).

Ian.



Re: [Qemu-devel] [PATCH v2 4/9] ipmi: introduce a struct ipmi_sdr_compact

2016-01-22 Thread Greg Kurz
On Thu, 21 Jan 2016 18:18:49 +0100
Cédric Le Goater  wrote:

> Currently, sdr attributes are identified using byte offsets and this
> can be a bit confusing.
> 
> This patch adds a struct ipmi_sdr_compact conforming to the IPMI specs
> and replaces byte offsets with names. It also introduces and uses a
> struct ipmi_sdr_header in sections of the code where no assumption is
> made on the type of SDR. This leave rooms to potential usage of other
> types in the future.
> 

Turning all these magic numbers into understandable names is definitely a
great idea !

See comments below.

> Signed-off-by: Cédric Le Goater 
> ---
>  hw/ipmi/ipmi_bmc_sim.c | 65 
> +++---
>  include/hw/ipmi/ipmi.h | 44 ++
>  2 files changed, 84 insertions(+), 25 deletions(-)
> 
> diff --git a/hw/ipmi/ipmi_bmc_sim.c b/hw/ipmi/ipmi_bmc_sim.c
> index fc596a548df7..31f990199154 100644
> --- a/hw/ipmi/ipmi_bmc_sim.c
> +++ b/hw/ipmi/ipmi_bmc_sim.c
> @@ -323,11 +323,15 @@ static void sdr_inc_reservation(IPMISdr *sdr)
>  static int sdr_add_entry(IPMIBmcSim *ibs, const uint8_t *entry,
>   unsigned int len, uint16_t *recid)
>  {
> +struct ipmi_sdr_header *sdrh_entry = (struct ipmi_sdr_header *) entry;

This looks like the entry argument should be struct ipmi_sdr_header * and
you would not need sdrh_entry.

> +struct ipmi_sdr_header *sdrh =
> +(struct ipmi_sdr_header *) >sdr.sdr[ibs->sdr.next_free];
> +
>  if ((len < 5) || (len > 255)) {
>  return 1;
>  }
> 
> -if (entry[4] != len - 5) {
> +if (sdrh_entry->rec_length != len - 5) {
>  return 1;
>  }
> 
> @@ -336,10 +340,10 @@ static int sdr_add_entry(IPMIBmcSim *ibs, const uint8_t 
> *entry,
>  return 1;
>  }
> 
> -memcpy(ibs->sdr.sdr + ibs->sdr.next_free, entry, len);
> -ibs->sdr.sdr[ibs->sdr.next_free] = ibs->sdr.next_rec_id & 0xff;
> -ibs->sdr.sdr[ibs->sdr.next_free+1] = (ibs->sdr.next_rec_id >> 8) & 0xff;
> -ibs->sdr.sdr[ibs->sdr.next_free+2] = 0x51; /* Conform to IPMI 1.5 spec */
> +memcpy(sdrh, entry, len);
> +sdrh->rec_id[0] = ibs->sdr.next_rec_id & 0xff;
> +sdrh->rec_id[1] = (ibs->sdr.next_rec_id >> 8) & 0xff;
> +sdrh->sdr_version = 0x51; /* Conform to IPMI 1.5 spec */
> 
>  if (recid) {
>  *recid = ibs->sdr.next_rec_id;
> @@ -357,8 +361,10 @@ static int sdr_find_entry(IPMISdr *sdr, uint16_t recid,
>  unsigned int pos = *retpos;
> 
>  while (pos < sdr->next_free) {
> -uint16_t trec = sdr->sdr[pos] | (sdr->sdr[pos + 1] << 8);
> -unsigned int nextpos = pos + sdr->sdr[pos + 4];
> +struct ipmi_sdr_header *sdrh =
> +(struct ipmi_sdr_header *) >sdr[pos];
> +uint16_t trec = ipmi_sdr_recid(sdrh);
> +unsigned int nextpos = pos + sdrh->rec_length;
> 
>  if (trec == recid) {
>  if (nextrec) {
> @@ -507,29 +513,32 @@ static void ipmi_init_sensors_from_sdrs(IPMIBmcSim *s)
> 
>  pos = 0;
>  for (i = 0; !sdr_find_entry(>sdr, i, , NULL); i++) {
> -uint8_t *sdr = s->sdr.sdr + pos;
> -unsigned int len = sdr[4];
> +struct ipmi_sdr_compact *sdr =
> +(struct ipmi_sdr_compact *) >sdr.sdr[pos];
> +unsigned int len = sdr->header.rec_length;
> 
>  if (len < 20) {
>  continue;
>  }
> -if ((sdr[3] < 1) || (sdr[3] > 2)) {
> +if (sdr->header.rec_type != IPMI_SDR_COMPACT_TYPE) {
>  continue; /* Not a sensor SDR we set from */
>  }
> 
> -if (sdr[7] > MAX_SENSORS) {
> +if (sdr->sensor_owner_number > MAX_SENSORS) {
>  continue;
>  }
> -sens = s->sensors + sdr[7];
> +sens = s->sensors + sdr->sensor_owner_number;
> 
>  IPMI_SENSOR_SET_PRESENT(sens, 1);
> -IPMI_SENSOR_SET_SCAN_ON(sens, (sdr[10] >> 6) & 1);
> -IPMI_SENSOR_SET_EVENTS_ON(sens, (sdr[10] >> 5) & 1);
> -sens->assert_suppt = sdr[14] | (sdr[15] << 8);
> -sens->deassert_suppt = sdr[16] | (sdr[17] << 8);
> -sens->states_suppt = sdr[18] | (sdr[19] << 8);
> -sens->sensor_type = sdr[12];
> -sens->evt_reading_type_code = sdr[13] & 0x7f;
> +IPMI_SENSOR_SET_SCAN_ON(sens, (sdr->sensor_init >> 6) & 1);
> +IPMI_SENSOR_SET_EVENTS_ON(sens, (sdr->sensor_init >> 5) & 1);
> +sens->assert_suppt = sdr->assert_mask[0] | (sdr->assert_mask[1] << 
> 8);
> +sens->deassert_suppt =
> +sdr->deassert_mask[0] | (sdr->deassert_mask[1] << 8);
> +sens->states_suppt =
> +sdr->discrete_mask[0] | (sdr->discrete_mask[1] << 8);
> +sens->sensor_type = sdr->sensor_type;
> +sens->evt_reading_type_code = sdr->reading_type & 0x7f;
> 
>  /* Enable all the events that are supported. */
>  sens->assert_enable = sens->assert_suppt;
> @@ -1155,6 +1164,7 @@ static void 

Re: [Qemu-devel] [PATCH v2 5/9] ipmi: fix SDR length value

2016-01-22 Thread Greg Kurz
On Thu, 21 Jan 2016 18:18:50 +0100
Cédric Le Goater  wrote:
> The IPMI BMC simulator populates the SDR table with a set of initial
> SDRs. The length of each SDR is taken from the record itself (byte 4)
> which does not include the size of the header. But, the full length
> (header + data) is required by the sdr_add_entry() routine.
> 
> Signed-off-by: Cédric Le Goater 

The patch is good but IMHO it should come before patch 4 because this is bugfix
that could be applied right away, while patch 4 is code cleanup that may need
some more discussion.

> ---
>  hw/ipmi/ipmi_bmc_sim.c | 18 +-
>  include/hw/ipmi/ipmi.h |  1 +
>  2 files changed, 10 insertions(+), 9 deletions(-)
> 
> diff --git a/hw/ipmi/ipmi_bmc_sim.c b/hw/ipmi/ipmi_bmc_sim.c
> index 31f990199154..803c7e5130c0 100644
> --- a/hw/ipmi/ipmi_bmc_sim.c
> +++ b/hw/ipmi/ipmi_bmc_sim.c
> @@ -327,11 +327,11 @@ static int sdr_add_entry(IPMIBmcSim *ibs, const uint8_t 
> *entry,
>  struct ipmi_sdr_header *sdrh =
>  (struct ipmi_sdr_header *) >sdr.sdr[ibs->sdr.next_free];
> 
> -if ((len < 5) || (len > 255)) {
> +if ((len < IPMI_SDR_HEADER_SIZE) || (len > 255)) {
>  return 1;
>  }
> 
> -if (sdrh_entry->rec_length != len - 5) {
> +if (ipmi_sdr_length(sdrh_entry) != len) {
>  return 1;
>  }
> 
> @@ -364,7 +364,7 @@ static int sdr_find_entry(IPMISdr *sdr, uint16_t recid,
>  struct ipmi_sdr_header *sdrh =
>  (struct ipmi_sdr_header *) >sdr[pos];
>  uint16_t trec = ipmi_sdr_recid(sdrh);
> -unsigned int nextpos = pos + sdrh->rec_length;
> +unsigned int nextpos = pos + ipmi_sdr_length(sdrh);
> 
>  if (trec == recid) {
>  if (nextrec) {
> @@ -1179,7 +1179,7 @@ static void get_sdr(IPMIBmcSim *ibs,
> 
>  sdrh = (struct ipmi_sdr_header *) >sdr.sdr[pos];
> 
> -if (cmd[6] > sdrh->rec_length) {
> +if (cmd[6] > ipmi_sdr_length(sdrh)) {
>  rsp[2] = IPMI_CC_PARM_OUT_OF_RANGE;
>  return;
>  }
> @@ -1188,7 +1188,7 @@ static void get_sdr(IPMIBmcSim *ibs,
>  IPMI_ADD_RSP_DATA((nextrec >> 8) & 0xff);
> 
>  if (cmd[7] == 0xff) {
> -cmd[7] = sdrh->rec_length - cmd[6];
> +cmd[7] = ipmi_sdr_length(sdrh) - cmd[6];
>  }
> 
>  if ((cmd[7] + *rsp_len) > max_rsp_len) {
> @@ -1659,22 +1659,22 @@ static void ipmi_sim_init(Object *obj)
>  for (i = 0;;) {
>  struct ipmi_sdr_header *sdrh;
>  int len;
> -if ((i + 5) > sizeof(init_sdrs)) {
> +if ((i + IPMI_SDR_HEADER_SIZE) > sizeof(init_sdrs)) {
>  error_report("Problem with recid 0x%4.4x", i);
>  return;
>  }
>  sdrh = (struct ipmi_sdr_header *) _sdrs[i];
> -len = sdrh->rec_length;
> +len = ipmi_sdr_length(sdrh);
>  recid = ipmi_sdr_recid(sdrh);
>  if (recid == 0x) {
>  break;
>  }
> -if ((i + len + 5) > sizeof(init_sdrs)) {
> +if ((i + len) > sizeof(init_sdrs)) {
>  error_report("Problem with recid 0x%4.4x", i);
>  return;
>  }
>  sdr_add_entry(ibs, init_sdrs + i, len, NULL);
> -i += len + 5;
> +i += len;
>  }
> 
>  ipmi_init_sensors_from_sdrs(ibs);
> diff --git a/include/hw/ipmi/ipmi.h b/include/hw/ipmi/ipmi.h
> index 7e142e241dcb..74a2b5af9613 100644
> --- a/include/hw/ipmi/ipmi.h
> +++ b/include/hw/ipmi/ipmi.h
> @@ -219,6 +219,7 @@ struct ipmi_sdr_header {
>  #define IPMI_SDR_HEADER_SIZE sizeof(struct ipmi_sdr_header)
> 
>  #define ipmi_sdr_recid(sdr) ((sdr)->rec_id[0] | ((sdr)->rec_id[1] << 8))
> +#define ipmi_sdr_length(sdr) ((sdr)->rec_length + IPMI_SDR_HEADER_SIZE)
> 
>  /*
>   * 43.2 SDR Type 02h. Compact Sensor Record




Re: [Qemu-devel] [PATCH v9 2/3] quorum: implement bdrv_add_child() and bdrv_del_child()

2016-01-22 Thread Alberto Garcia
On Thu 21 Jan 2016 05:58:42 PM CET, Eric Blake  wrote:
 In general, what do you do to make sure that the data in a new Quorum
 child is consistent with that of the rest of the array?
>>>
>>> Quorum can have more than one child when it starts. But we don't do
>>> the similar check. So I don't think we should do such check here.
>> 
>> Yes, but when you start a VM you can verify in advance that all
>> members of the Quorum have the same data. If you do that on a running
>> VM how can you know if the new disk is consistent with the others?
>
> User error if it is not.  Just the same as it is user error if you
> request a shallow drive-mirror but the destination is not the same
> contents as the backing file.  I don't think qemu has to protect us
> from user error in this case.

But the backing file is read-only so the user can guarantee that the
destination has the same data before the shallow mirror. How do you do
that in this case?

Berto



[Qemu-devel] [PATCH v3 0/3] target-arm: Add a few more S2 MMU input checks

2016-01-22 Thread Edgar E. Iglesias
From: "Edgar E. Iglesias" 

This adds the inputsize > pamax check and also fixes the
startlevel checks to apply to the 64bit translations.

Comments welcome!

Cheers,
Edgar

ChangeLog:
v2 -> v3:
* Document pamax arg to check_s2_startlevel

v1 -> v2:
* inputsize > pmax check only applies to AArch64
* Fix commit message typo < should be >

Edgar E. Iglesias (3):
  target-arm: Apply S2 MMU startlevel table size check to AArch64
  target-arm: Make pamax an argument to check_s2_startlevel
  target-arm: Implement the S2 MMU inputsize > pamax check

 target-arm/helper.c | 39 ---
 1 file changed, 24 insertions(+), 15 deletions(-)

-- 
1.9.1




Re: [Qemu-devel] [PATCH] linux-user: add option to intercept execve() syscalls

2016-01-22 Thread Petros Angelatos
>> diff --git a/linux-user/main.c b/linux-user/main.c
>> index ee12035..5951279 100644
>> --- a/linux-user/main.c
>> +++ b/linux-user/main.c
>> @@ -79,6 +79,7 @@ static void usage(int exitcode);
>>
>>  static const char *interp_prefix = CONFIG_QEMU_INTERP_PREFIX;
>>  const char *qemu_uname_release;
>> +const char *qemu_execve_path;
>>
>>  /* XXX: on x86 MAP_GROWSDOWN only works if ESP <= address + 32, so
>> we allocate a bigger stack. Need a better solution, for example
>> @@ -3828,6 +3829,11 @@ static void handle_arg_guest_base(const char *arg)
>>  have_guest_base = 1;
>>  }
>>
>> +static void handle_arg_execve(const char *arg)
>> +{
>> +qemu_execve_path = strdup(arg);
>
> I think you can use the parameter just as an on/off switch and
> realpath(argv[0]) as qemu_execve_path.
>
> I don't see any reason to use other binary than the one in use.

This was my initial approach too, but argv[0] can be just the filename
like "qemu-arm-static". And while I could add extra logic to look this
up in the PATH, someone could run it from a completely different
location. Then I looked for a way to get the path of the current
executable but every platform has its own way of doing that and I
didn't want to add all these cases.

https://stackoverflow.com/questions/1023306/finding-current-executables-path-without-proc-self-exe

>> diff --git a/linux-user/syscall.c b/linux-user/syscall.c
>> index 0cbace4..d0b5442 100644
>> --- a/linux-user/syscall.c
>> +++ b/linux-user/syscall.c
>> @@ -5854,6 +5854,109 @@ static target_timer_t get_timer_id(abi_long arg)
>>  return timerid;
>>  }
>>
>> +#define BINPRM_BUF_SIZE 128
>
> This is defined in 

Got it, I'll add this header and remove the definition.

>
>> +/* qemu_execve() Must return target values and target errnos. */
>> +static abi_long qemu_execve(char *filename, char *argv[],
>> +  char *envp[])
>> +{
>> +char *i_arg = NULL, *i_name = NULL;
>> +char **new_argp;
>> +int argc, fd, ret, i, offset = 3;
>> +char *cp;
>> +char buf[BINPRM_BUF_SIZE];
>> +
>> +for (argc = 0; argv[argc] != NULL; argc++) {
>> +/* nothing */ ;
>> +}
>> +
>> +fd = open(filename, O_RDONLY);
>> +if (fd == -1) {
>> +return -ENOENT;
>
> return -errno; ?

Will fix in v2

>> +ret = read(fd, buf, BINPRM_BUF_SIZE);
>> +if (ret == -1) {
>> +close(fd);
>> +return -ENOENT;
>
> return -errno; ?

Will fix in v2

>> +}
>> +
>> +close(fd);
>> +
>> +/* adapted from the kernel
>> + * 
>> https://git.kernel.org/cgit/linux/kernel/git/torvalds/linux.git/tree/fs/binfmt_script.c
>> + */
>> +if ((buf[0] == '#') && (buf[1] == '!')) {
>
> what happens if read() < 2 ?

Hm, the easy option is for qemu_execve to return ENOEXEC or EIO.
Otherwise I could retry the read N times? I'm not sure how to handle
this if we don't want to return an error.

>> +/* Copy the original arguments with offset */
>> +for (i = 0; i < argc; i++) {
>> +new_argp[i + offset] = argv[i];
>> +}
>> +
>> +new_argp[0] = strdup(qemu_execve_path);
>> +new_argp[1] = strdup("-0");
>> +new_argp[offset] = filename;
>> +new_argp[argc + offset] = NULL;
>> +
>> +if (i_name) {
>> +new_argp[2] = i_name;
>> +new_argp[3] = i_name;
>> +
>> +if (i_arg) {
>> +new_argp[4] = i_arg;
>> +}
>> +} else {
>> +new_argp[2] = argv[0];
>> +}
>> +
>> +return get_errno(execve(qemu_execve_path, new_argp, envp));
>
> duplicate get_errno() with the caller.

I'll add the logic proposed bellow in this function and remove the
duplicate get_errno() from the caller.

>>  /* do_syscall() should always have a single exit point at the end so
>> that actions, such as logging of syscall results, can be performed.
>> All errnos that do_syscall() returns must be -TARGET_. */
>> @@ -6113,7 +6216,13 @@ abi_long do_syscall(void *cpu_env, int num, abi_long 
>> arg1,
>>
>>  if (!(p = lock_user_string(arg1)))
>>  goto execve_efault;
>> -ret = get_errno(execve(p, argp, envp));
>> +
>> +if (qemu_execve_path && *qemu_execve_path) {
>> +ret = get_errno(qemu_execve(p, argp, envp));
>> +} else {
>> +ret = get_errno(execve(p, argp, envp));
>> +}
>> +
>
> what do you think of:
>
> ret = qemu_execve(p, argp, envp);
>
> and in qemu_execve():
>
> if (qemu_execve_path == NULL || *qemu_execve_path == 0) {
> return get_errno(execve(p, argp, envp));
> }
>
> so all the logic is in the function.

Sounds good, I'll include this in v2

Since I'm new to this style of contribution I have a couple of
questions. Is it ok that I deleted part of the patch for my reply to
code review, or should I have replied inline without deleting
anything? Should I send v2 after we resolve all the issues here or
should I send a v2 with proposed fixes but lacking the ones pending
replies?

Re: [Qemu-devel] [PATCH] linux-user: add option to intercept execve() syscalls

2016-01-22 Thread Laurent Vivier


Le 22/01/2016 11:01, Petros Angelatos a écrit :
>>> diff --git a/linux-user/main.c b/linux-user/main.c
>>> index ee12035..5951279 100644
>>> --- a/linux-user/main.c
>>> +++ b/linux-user/main.c
>>> @@ -79,6 +79,7 @@ static void usage(int exitcode);
>>>
>>>  static const char *interp_prefix = CONFIG_QEMU_INTERP_PREFIX;
>>>  const char *qemu_uname_release;
>>> +const char *qemu_execve_path;
>>>
>>>  /* XXX: on x86 MAP_GROWSDOWN only works if ESP <= address + 32, so
>>> we allocate a bigger stack. Need a better solution, for example
>>> @@ -3828,6 +3829,11 @@ static void handle_arg_guest_base(const char *arg)
>>>  have_guest_base = 1;
>>>  }
>>>
>>> +static void handle_arg_execve(const char *arg)
>>> +{
>>> +qemu_execve_path = strdup(arg);
>>
>> I think you can use the parameter just as an on/off switch and
>> realpath(argv[0]) as qemu_execve_path.
>>
>> I don't see any reason to use other binary than the one in use.
> 
> This was my initial approach too, but argv[0] can be just the filename
> like "qemu-arm-static". And while I could add extra logic to look this
> up in the PATH, someone could run it from a completely different
> location. Then I looked for a way to get the path of the current
> executable but every platform has its own way of doing that and I
> didn't want to add all these cases.
> 
> https://stackoverflow.com/questions/1023306/finding-current-executables-path-without-proc-self-exe

linux-user works only on linux.
qemu uses glib-2.0, so you can use g_find_program_in_path().

>>> diff --git a/linux-user/syscall.c b/linux-user/syscall.c
>>> index 0cbace4..d0b5442 100644
>>> --- a/linux-user/syscall.c
>>> +++ b/linux-user/syscall.c
>>> @@ -5854,6 +5854,109 @@ static target_timer_t get_timer_id(abi_long arg)
>>>  return timerid;
>>>  }
>>>
>>> +#define BINPRM_BUF_SIZE 128
>>
>> This is defined in 
> 
> Got it, I'll add this header and remove the definition.
> 
>>
>>> +/* qemu_execve() Must return target values and target errnos. */
>>> +static abi_long qemu_execve(char *filename, char *argv[],
>>> +  char *envp[])
>>> +{
>>> +char *i_arg = NULL, *i_name = NULL;
>>> +char **new_argp;
>>> +int argc, fd, ret, i, offset = 3;
>>> +char *cp;
>>> +char buf[BINPRM_BUF_SIZE];
>>> +
>>> +for (argc = 0; argv[argc] != NULL; argc++) {
>>> +/* nothing */ ;
>>> +}
>>> +
>>> +fd = open(filename, O_RDONLY);
>>> +if (fd == -1) {
>>> +return -ENOENT;
>>
>> return -errno; ?
> 
> Will fix in v2
> 
>>> +ret = read(fd, buf, BINPRM_BUF_SIZE);
>>> +if (ret == -1) {
>>> +close(fd);
>>> +return -ENOENT;
>>
>> return -errno; ?
> 
> Will fix in v2
> 
>>> +}
>>> +
>>> +close(fd);
>>> +
>>> +/* adapted from the kernel
>>> + * 
>>> https://git.kernel.org/cgit/linux/kernel/git/torvalds/linux.git/tree/fs/binfmt_script.c
>>> + */
>>> +if ((buf[0] == '#') && (buf[1] == '!')) {
>>
>> what happens if read() < 2 ?
> 
> Hm, the easy option is for qemu_execve to return ENOEXEC or EIO.
> Otherwise I could retry the read N times? I'm not sure how to handle
> this if we don't want to return an error.

if we have less than 2 bytes, we can guess it is not executable...

>>> +/* Copy the original arguments with offset */
>>> +for (i = 0; i < argc; i++) {
>>> +new_argp[i + offset] = argv[i];
>>> +}
>>> +
>>> +new_argp[0] = strdup(qemu_execve_path);
>>> +new_argp[1] = strdup("-0");
>>> +new_argp[offset] = filename;
>>> +new_argp[argc + offset] = NULL;
>>> +
>>> +if (i_name) {
>>> +new_argp[2] = i_name;
>>> +new_argp[3] = i_name;
>>> +
>>> +if (i_arg) {
>>> +new_argp[4] = i_arg;
>>> +}
>>> +} else {
>>> +new_argp[2] = argv[0];
>>> +}
>>> +
>>> +return get_errno(execve(qemu_execve_path, new_argp, envp));
>>
>> duplicate get_errno() with the caller.
> 
> I'll add the logic proposed bellow in this function and remove the
> duplicate get_errno() from the caller.
> 
>>>  /* do_syscall() should always have a single exit point at the end so
>>> that actions, such as logging of syscall results, can be performed.
>>> All errnos that do_syscall() returns must be -TARGET_. */
>>> @@ -6113,7 +6216,13 @@ abi_long do_syscall(void *cpu_env, int num, abi_long 
>>> arg1,
>>>
>>>  if (!(p = lock_user_string(arg1)))
>>>  goto execve_efault;
>>> -ret = get_errno(execve(p, argp, envp));
>>> +
>>> +if (qemu_execve_path && *qemu_execve_path) {
>>> +ret = get_errno(qemu_execve(p, argp, envp));
>>> +} else {
>>> +ret = get_errno(execve(p, argp, envp));
>>> +}
>>> +
>>
>> what do you think of:
>>
>> ret = qemu_execve(p, argp, envp);
>>
>> and in qemu_execve():
>>
>> if (qemu_execve_path == NULL || *qemu_execve_path == 0) {
>> return get_errno(execve(p, argp, envp));
>> }
>>
>> so all the logic is in 

Re: [Qemu-devel] [PATCH] linux-user: add option to intercept execve() syscalls

2016-01-22 Thread Laurent Vivier


Le 22/01/2016 11:47, Peter Maydell a écrit :
> On 22 January 2016 at 10:33, Laurent Vivier  wrote:
>> Le 22/01/2016 11:01, Petros Angelatos a écrit :
>>> This was my initial approach too, but argv[0] can be just the filename
>>> like "qemu-arm-static". And while I could add extra logic to look this
>>> up in the PATH, someone could run it from a completely different
>>> location. Then I looked for a way to get the path of the current
>>> executable but every platform has its own way of doing that and I
>>> didn't want to add all these cases.
>>>
>>> https://stackoverflow.com/questions/1023306/finding-current-executables-path-without-proc-self-exe
>>
>> linux-user works only on linux.
>> qemu uses glib-2.0, so you can use g_find_program_in_path().
> 
> If QEMU was started via execle() to set the environment of the
> executed process and that specified environment has a different
> PATH, then g_find_program_in_path() will give the wrong answer.
> Using AT_EXECFN (perhaps with a fallback to /proc/self/exe) seems
> like a better approach to me.

I agree, you can use getauxval(AT_EXECFN).

>>> questions. Is it ok that I deleted part of the patch for my reply to
>>> code review, or should I have replied inline without deleting
>>
>> Generally, it's better to not delete parts. So, someone tacking the mail
>> thread at a moment can read the whole history in the last mail.
> 
> I tend to happily delete parts and assume that readers have
> access to the thread (via the archive or in their mail readers).
> Not deleting bits makes it hard to read replies if there's
> a conversation about a small part of a large patch.

Yes, I do that also... :)

Laurent



Re: [Qemu-devel] [PATCH v1] kvm/x86: Hyper-V tsc page setup

2016-01-22 Thread Paolo Bonzini


On 22/01/2016 11:15, Andrey Smetanin wrote:
>>
>> - unless KVM can use a master clock, it is incorrect to set up the TSC
>> page this way; the sequence needs to be 0x in that case
> 0x is not an invalid value for tsc page,
> see https://lkml.org/lkml/2015/11/2/655

oh, I see now.

>> - writing the TSC page must be done while all VCPUs are stopped, because
>> the TSC page doesn't provide the possibility for the guest to retry in
>> the middle of an update (like seqcount in Linux doess)
> I think Windows guest gives tsc page address at boot time and protects
> against other vcpu's tsc page access.

Sometimes the TSC is detected to be unstable and Linux switches to
another clocksource.  At least in that case you can get a write to the
TSC page while the guest is running.

In that case it would be enough to write a zero to tsc_sequence, which
_can_ be done atomically while the guest is running.  However, KVM
already has a mechanism to stop all VCPUs (KVM_REQ_MASTERCLOCK_UPDATE)
so we might as well use it.

Paolo



Re: [Qemu-devel] [PATCH v2 6/9] ipmi: add get and set SENSOR_TYPE commands

2016-01-22 Thread Greg Kurz
On Thu, 21 Jan 2016 18:18:51 +0100
Cédric Le Goater  wrote:

> Signed-off-by: Cédric Le Goater 
> Acked-by: Corey Minyard 
> ---

Reviewed-by: Greg Kurz 

Just two nits below.

>  hw/ipmi/ipmi_bmc_sim.c | 45 -
>  1 file changed, 44 insertions(+), 1 deletion(-)
> 
> diff --git a/hw/ipmi/ipmi_bmc_sim.c b/hw/ipmi/ipmi_bmc_sim.c
> index 803c7e5130c0..7c0f2a1d9799 100644
> --- a/hw/ipmi/ipmi_bmc_sim.c
> +++ b/hw/ipmi/ipmi_bmc_sim.c
> @@ -42,6 +42,8 @@
>  #define IPMI_CMD_REARM_SENSOR_EVTS0x2a
>  #define IPMI_CMD_GET_SENSOR_EVT_STATUS0x2b
>  #define IPMI_CMD_GET_SENSOR_READING   0x2d
> +#define IPMI_CMD_SET_SENSOR_TYPE  0x2e
> +#define IPMI_CMD_GET_SENSOR_TYPE  0x2f
> 
>  /* #define IPMI_NETFN_APP 0x06 In ipmi.h */
> 
> @@ -1527,6 +1529,45 @@ static void get_sensor_reading(IPMIBmcSim *ibs,
>  }
>  }
> 
> +static void set_sensor_type(IPMIBmcSim *ibs,
> +   uint8_t *cmd, unsigned int cmd_len,
> +   uint8_t *rsp, unsigned int *rsp_len,
> +   unsigned int max_rsp_len)
> +{
> +IPMISensor *sens;
> +
> +
> +IPMI_CHECK_CMD_LEN(5);
> +if ((cmd[2] > MAX_SENSORS) ||

This has been a recurring remark on many patches lately, and all the people
don't necessarily agree but the extra parenthesis are not needed here...

> +!IPMI_SENSOR_GET_PRESENT(ibs->sensors + cmd[2])) {
> +rsp[2] = IPMI_CC_REQ_ENTRY_NOT_PRESENT;
> +return;
> +}
> +sens = ibs->sensors + cmd[2];
> +sens->sensor_type = cmd[3];
> +sens->evt_reading_type_code = cmd[4] & 0x7f;
> +}
> +
> +static void get_sensor_type(IPMIBmcSim *ibs,
> +   uint8_t *cmd, unsigned int cmd_len,
> +   uint8_t *rsp, unsigned int *rsp_len,
> +   unsigned int max_rsp_len)
> +{
> +IPMISensor *sens;
> +
> +
> +IPMI_CHECK_CMD_LEN(3);
> +if ((cmd[2] > MAX_SENSORS) ||

and here.

> +!IPMI_SENSOR_GET_PRESENT(ibs->sensors + cmd[2])) {
> +rsp[2] = IPMI_CC_REQ_ENTRY_NOT_PRESENT;
> +return;
> +}
> +sens = ibs->sensors + cmd[2];
> +IPMI_ADD_RSP_DATA(sens->sensor_type);
> +IPMI_ADD_RSP_DATA(sens->evt_reading_type_code);
> +}
> +
> +
>  static const IPMICmdHandler chassis_cmds[] = {
>  [IPMI_CMD_GET_CHASSIS_CAPABILITIES] = chassis_capabilities,
>  [IPMI_CMD_GET_CHASSIS_STATUS] = chassis_status,
> @@ -1542,7 +1583,9 @@ static const IPMICmdHandler sensor_event_cmds[] = {
>  [IPMI_CMD_GET_SENSOR_EVT_ENABLE] = get_sensor_evt_enable,
>  [IPMI_CMD_REARM_SENSOR_EVTS] = rearm_sensor_evts,
>  [IPMI_CMD_GET_SENSOR_EVT_STATUS] = get_sensor_evt_status,
> -[IPMI_CMD_GET_SENSOR_READING] = get_sensor_reading
> +[IPMI_CMD_GET_SENSOR_READING] = get_sensor_reading,
> +[IPMI_CMD_SET_SENSOR_TYPE] = set_sensor_type,
> +[IPMI_CMD_GET_SENSOR_TYPE] = get_sensor_type,
>  };
>  static const IPMINetfn sensor_event_netfn = {
>  .cmd_nums = ARRAY_SIZE(sensor_event_cmds),




Re: [Qemu-devel] [PATCH v2 03/13] block: Move block dirty bitmap code to separate files

2016-01-22 Thread Vladimir Sementsov-Ogievskiy

On 20.01.2016 09:11, Fam Zheng wrote:

The only change is making bdrv_dirty_bitmap_truncate public. It is used in
block.c.

Signed-off-by: Fam Zheng 
Reviewed-by: John Snow 
---
  block.c  | 339 ---
  block/Makefile.objs  |   2 +-
  block/dirty-bitmap.c | 366 +++
  include/block/block.h|  35 +
  include/block/dirty-bitmap.h |  43 +
  5 files changed, 411 insertions(+), 374 deletions(-)
  create mode 100644 block/dirty-bitmap.c
  create mode 100644 include/block/dirty-bitmap.h

diff --git a/block.c b/block.c
index 54c37f9..ab79bfe 100644
--- a/block.c
+++ b/block.c
@@ -55,23 +55,6 @@
  #include 
  #endif
  
-/**

- * A BdrvDirtyBitmap can be in three possible states:
- * (1) successor is NULL and disabled is false: full r/w mode
- * (2) successor is NULL and disabled is true: read only mode ("disabled")
- * (3) successor is set: frozen mode.
- * A frozen bitmap cannot be renamed, deleted, anonymized, cleared, set,
- * or enabled. A frozen bitmap can only abdicate() or reclaim().
- */
-struct BdrvDirtyBitmap {
-HBitmap *bitmap;/* Dirty sector bitmap implementation */
-BdrvDirtyBitmap *successor; /* Anonymous child; implies frozen status */
-char *name; /* Optional non-empty unique ID */
-int64_t size;   /* Size of the bitmap (Number of sectors) */
-bool disabled;  /* Bitmap is read-only */
-QLIST_ENTRY(BdrvDirtyBitmap) list;
-};
-
  #define NOT_DONE 0x7fff /* used while emulated sync operation in progress 
*/
  
  struct BdrvStates bdrv_states = QTAILQ_HEAD_INITIALIZER(bdrv_states);

@@ -87,7 +70,6 @@ static int bdrv_open_inherit(BlockDriverState **pbs, const 
char *filename,
   BlockDriverState *parent,
   const BdrvChildRole *child_role, Error **errp);
  
-static void bdrv_dirty_bitmap_truncate(BlockDriverState *bs);

  /* If non-zero, use only whitelisted block drivers */
  static int use_bdrv_whitelist;
  
@@ -3373,327 +3355,6 @@ void bdrv_lock_medium(BlockDriverState *bs, bool locked)

  }
  }
  
-BdrvDirtyBitmap *bdrv_find_dirty_bitmap(BlockDriverState *bs, const char *name)

-{
-BdrvDirtyBitmap *bm;
-
-assert(name);
-QLIST_FOREACH(bm, >dirty_bitmaps, list) {
-if (bm->name && !strcmp(name, bm->name)) {
-return bm;
-}
-}
-return NULL;
-}
-
-void bdrv_dirty_bitmap_make_anon(BdrvDirtyBitmap *bitmap)
-{
-assert(!bdrv_dirty_bitmap_frozen(bitmap));
-g_free(bitmap->name);
-bitmap->name = NULL;
-}
-
-BdrvDirtyBitmap *bdrv_create_dirty_bitmap(BlockDriverState *bs,
-  uint32_t granularity,
-  const char *name,
-  Error **errp)
-{
-int64_t bitmap_size;
-BdrvDirtyBitmap *bitmap;
-uint32_t sector_granularity;
-
-assert((granularity & (granularity - 1)) == 0);
-
-if (name && bdrv_find_dirty_bitmap(bs, name)) {
-error_setg(errp, "Bitmap already exists: %s", name);
-return NULL;
-}
-sector_granularity = granularity >> BDRV_SECTOR_BITS;
-assert(sector_granularity);
-bitmap_size = bdrv_nb_sectors(bs);
-if (bitmap_size < 0) {
-error_setg_errno(errp, -bitmap_size, "could not get length of device");
-errno = -bitmap_size;
-return NULL;
-}
-bitmap = g_new0(BdrvDirtyBitmap, 1);
-bitmap->bitmap = hbitmap_alloc(bitmap_size, ctz32(sector_granularity));
-bitmap->size = bitmap_size;
-bitmap->name = g_strdup(name);
-bitmap->disabled = false;
-QLIST_INSERT_HEAD(>dirty_bitmaps, bitmap, list);
-return bitmap;
-}
-
-bool bdrv_dirty_bitmap_frozen(BdrvDirtyBitmap *bitmap)
-{
-return bitmap->successor;
-}
-
-bool bdrv_dirty_bitmap_enabled(BdrvDirtyBitmap *bitmap)
-{
-return !(bitmap->disabled || bitmap->successor);
-}
-
-DirtyBitmapStatus bdrv_dirty_bitmap_status(BdrvDirtyBitmap *bitmap)
-{
-if (bdrv_dirty_bitmap_frozen(bitmap)) {
-return DIRTY_BITMAP_STATUS_FROZEN;
-} else if (!bdrv_dirty_bitmap_enabled(bitmap)) {
-return DIRTY_BITMAP_STATUS_DISABLED;
-} else {
-return DIRTY_BITMAP_STATUS_ACTIVE;
-}
-}
-
-/**
- * Create a successor bitmap destined to replace this bitmap after an 
operation.
- * Requires that the bitmap is not frozen and has no successor.
- */
-int bdrv_dirty_bitmap_create_successor(BlockDriverState *bs,
-   BdrvDirtyBitmap *bitmap, Error **errp)
-{
-uint64_t granularity;
-BdrvDirtyBitmap *child;
-
-if (bdrv_dirty_bitmap_frozen(bitmap)) {
-error_setg(errp, "Cannot create a successor for a bitmap that is "
-   "currently frozen");
-return -1;
-}
-assert(!bitmap->successor);
-
-/* Create an 

Re: [Qemu-devel] [PATCH RFC 3/7] net/filter: Skip the disabled filter when delivering packets

2016-01-22 Thread Wen Congyang
On 01/22/2016 04:36 PM, zhanghailiang wrote:
> If the filter is disabled, don't go through it.
> 
> Signed-off-by: zhanghailiang 
> ---
>  include/net/filter.h | 5 +
>  net/net.c| 4 
>  2 files changed, 9 insertions(+)
> 
> diff --git a/include/net/filter.h b/include/net/filter.h
> index 9ed5ec6..d797ee4 100644
> --- a/include/net/filter.h
> +++ b/include/net/filter.h
> @@ -74,6 +74,11 @@ ssize_t qemu_netfilter_pass_to_next(NetClientState *sender,
>  int iovcnt,
>  void *opaque);
>  
> +static inline bool qemu_need_skip_netfilter(NetFilterState *nf)
> +{
> +return nf->enabled ? false : true;
> +}
> +
>  void netfilter_print_info(NetFilterState *nf, char *output_str, int size);
>  
>  #endif /* QEMU_NET_FILTER_H */
> diff --git a/net/net.c b/net/net.c
> index 87de7c0..ec43105 100644
> --- a/net/net.c
> +++ b/net/net.c
> @@ -581,6 +581,10 @@ static ssize_t filter_receive_iov(NetClientState *nc,
>  NetFilterState *nf = NULL;
>  
>  QTAILQ_FOREACH(nf, >filters, next) {
> +/* Don't go through filter if it is off */
> +if (qemu_need_skip_netfilter(nf)) {
> +continue;
> +}
>  ret = qemu_netfilter_receive(nf, direction, sender, flags, iov,
>   iovcnt, sent_cb);
>  if (ret) {
> 

qemu_netfilter_pass_to_next() shoule also be updated.

Thanks
Wen Congyang






Re: [Qemu-devel] [PATCH v2 3/3] target-arm: Implement the S2 MMU inputsize > pamax check

2016-01-22 Thread Alex Bennée

Edgar E. Iglesias  writes:

> From: "Edgar E. Iglesias" 
>
> Implement the inputsize > pamax check for Stage 2 translations.
> We have multiple choices for how to respond to errors and
> choose to fault.
>
> Signed-off-by: Edgar E. Iglesias 
> ---
>  target-arm/helper.c | 16 
>  1 file changed, 12 insertions(+), 4 deletions(-)
>
> diff --git a/target-arm/helper.c b/target-arm/helper.c
> index 4abeb4d..9a7ff5e 100644
> --- a/target-arm/helper.c
> +++ b/target-arm/helper.c
> @@ -6808,7 +6808,7 @@ static bool get_phys_addr_lpae(CPUARMState *env, 
> target_ulong address,
>   */
>  int startlevel = extract32(tcr->raw_tcr, 6, 2);
>  unsigned int pamax = arm_pamax(cpu);
> -bool ok;
> +bool ok = true;
>
>  if (va_size == 32 || stride == 9) {
>  /* AArch32 or 4KB pages */
> @@ -6818,9 +6818,17 @@ static bool get_phys_addr_lpae(CPUARMState *env, 
> target_ulong address,
>  level = 3 - startlevel;
>  }
>
> -/* Check that the starting level is valid. */
> -ok = check_s2_startlevel(cpu, va_size == 64, level,
> - inputsize, stride, pamax);
> +if (va_size == 64 &&
> +inputsize > pamax &&
> +(arm_el_is_aa64(env, 1) || inputsize > 40)) {

If va_size == 64 doesn't that imply arm_el_is_aa64(env, 1)? Looking
further up the function it seems that is what sets va_size in the first
place. I think that makes the inputsize > 40 check redundant.

> +/* We have multiple choices but choose to fault.  */
> +ok = false;
> +}
> +if (ok) {
> +/* Check that the starting level is valid. */
> +ok = check_s2_startlevel(cpu, va_size == 64, level,
> + inputsize, stride, pamax);
> +}
>  if (!ok) {
>  /* AArch64 reports these as level 0 faults.
>   * AArch32 reports these as level 1 faults.

I'm not a fan of the ok = true / ok = false / ok =
check_s2_start_level() / if (!ok) ping-pong here as it is hard to
follow. I'm not sure how you could make it cleaner to follow though.
Maybe something like:

/* For stage 2 translations the starting level is specified by the
 * VTCR_EL2.SL0 field (whose interpretation depends on the page size)
 */
int startlevel = extract32(tcr->raw_tcr, 6, 2);
unsigned int pamax = arm_pamax(cpu);
bool is_aarch64_regime = (va_size == 64);
bool ok;

if (va_size == 32 || stride == 9) {
/* AArch32 or 4KB pages */
level = 2 - startlevel;
} else {
/* 16KB or 64KB pages */
level = 3 - startlevel;
}

if (is_aarch64_regime &&
inputsize > pamax) {
/* We have multiple choices but choose to fault.  */
ok = false;
} else {
/* Check that the starting level is valid. */
ok = check_s2_startlevel(cpu, is_aarch64_regime, level,
 inputsize, stride, pamax);
}
if (!ok) {
/* AArch64 reports these as level 0 faults.
 * AArch32 reports these as level 1 faults.
 */
level = is_aarch64_regime ? 0 : 1;
fault_type = translation_fault;
goto do_fault;
}

But I'm wondering if it just makes more sense to push the:

is_aarch64_regime && inputsize > pamax

Check into check_s2_startlevel? Then you could just have a simple call
which succeeds or falls through to a fault?

/* Check that the starting level is valid. */
if (!check_s2_startlevel(cpu, is_aarch64_regime, level,
 inputsize, stride, pamax) ){
/* AArch64 reports these as level 0 faults.
 * AArch32 reports these as level 1 faults.
 */
level = is_aarch64_regime ? 0 : 1;
fault_type = translation_fault;
goto do_fault;
}

--
Alex Bennée



Re: [Qemu-devel] [PATCH RFC 0/7] Netfilter: Add each netdev a default filter

2016-01-22 Thread Hailiang Zhang

On 2016/1/22 18:07, Daniel P. Berrange wrote:

On Fri, Jan 22, 2016 at 04:36:44PM +0800, zhanghailiang wrote:

This series is a prerequisite for COLO, here we add each netdev
a default buffer filter, it is disabled by default, and has
no side effect for delivering packets in net layer.


Why can't whatever is launching QEMU just setup filters explicitly
if they want to use COLO ? I'm not seeing an obvious compelling
reason to add this by default and then add extra code to deal
with special casing its behaviour.



The main reason is, we hope to support hot add network during VM's COLO
lifetime in the future. (I'm not quite sure if this usage case is really exist,
but we don't want the VM in COLO state has too many limitations.)

Maybe add an option that users can control if they want to use COLO or not is 
more
acceptable ? With this option, we can decide whether to add the default filter 
or not.
Or, we could dynamically add filter while users ask to go into COLO state for 
VM.
(We have discussed this before in community, and Jason suggested me to add 
default
filter for each netdev to support hot-add network during COLO state).

What's your suggestion ?

Thanks,
Hailiang



Besides, patch 1 fixes the ouput information of 'info network' command
for filter.

zhanghailiang (7):
   net/filter: Fix the output information for command 'info network'
   net/filter: Add a 'status' property for filter object
   net/filter: Skip the disabled filter when delivering packets
   net/filter: Introduce a helper to add a filter to the netdev
   filter-buffer: Accept zero interval
   net/filter: Add a default filter to each netdev
   net/filter: prevent the default filter to be deleted

  include/net/filter.h |  25 +++-
  net/dump.c   |   2 -
  net/filter-buffer.c  |  10 
  net/filter.c | 163 +--
  net/net.c|  27 -
  5 files changed, 194 insertions(+), 33 deletions(-)


Regards,
Daniel







Re: [Qemu-devel] [PATCH v2] pc: allow raising low memory via max-ram-below-4g option

2016-01-22 Thread Gerd Hoffmann
  Hi,

> > > I wonder whether we should just bite the bullet and ask management to
> > > maintain the physical memory map for us, instead of trying to give us
> > > hints.
> > 
> > I doubt this simplified things, given the backward compatibility
> > constrains we have.
> > 
> > cheers,
> >   Gerd
> 
> That's exactly what would become simple.
> For backwards compatibility we would leave things alone
> if the new flags for the memory map aren't specified.

But we'll add a bunch of new code for the new config mode which allows
management to maintain the physical memory map.  And we'll expect
management know about a bunch of machine type internals.  That isn't a
simplification.

> This would allow people to e.g. allocate phy address
> ranges for things like nvdimm which has been
> problematic in the past.

Didn't follow nvdimm discussions.  If you think we really need that
anyway to solve certain issues, sure, go ahead and I happily adjust this
patch to use the new infrastructure.

cheers,
  Gerd




Re: [Qemu-devel] [PATCH v2 7/9] ipmi: add GET_SYS_RESTART_CAUSE chassis command

2016-01-22 Thread Greg Kurz
On Thu, 21 Jan 2016 18:18:52 +0100
Cédric Le Goater  wrote:

> This is a simulator. Just return an unknown cause (0).
> 
> Signed-off-by: Cédric Le Goater 
> Acked-by: Corey Minyard 
> ---

Reviewed-by: Greg Kurz 

>  hw/ipmi/ipmi_bmc_sim.c | 16 +++-
>  1 file changed, 15 insertions(+), 1 deletion(-)
> 
> diff --git a/hw/ipmi/ipmi_bmc_sim.c b/hw/ipmi/ipmi_bmc_sim.c
> index 7c0f2a1d9799..e882af3f1b40 100644
> --- a/hw/ipmi/ipmi_bmc_sim.c
> +++ b/hw/ipmi/ipmi_bmc_sim.c
> @@ -34,6 +34,7 @@
>  #define IPMI_CMD_GET_CHASSIS_CAPABILITIES 0x00
>  #define IPMI_CMD_GET_CHASSIS_STATUS   0x01
>  #define IPMI_CMD_CHASSIS_CONTROL  0x02
> +#define IPMI_CMD_GET_SYS_RESTART_CAUSE0x09
> 
>  #define IPMI_NETFN_SENSOR_EVENT   0x04
> 
> @@ -197,6 +198,8 @@ struct IPMIBmcSim {
>  uint8_t mfg_id[3];
>  uint8_t product_id[2];
> 
> +uint8_t restart_cause;
> +
>  IPMISel sel;
>  IPMISdr sdr;
>  IPMISensor sensors[MAX_SENSORS];
> @@ -756,6 +759,15 @@ static void chassis_control(IPMIBmcSim *ibs,
>  }
>  }
> 
> +static void chassis_get_sys_restart_cause(IPMIBmcSim *ibs,
> +   uint8_t *cmd, unsigned int cmd_len,
> +   uint8_t *rsp, unsigned int *rsp_len,
> +   unsigned int max_rsp_len)
> +{
> +IPMI_ADD_RSP_DATA(ibs->restart_cause & 0xf); /* Restart Cause */
> +IPMI_ADD_RSP_DATA(0);  /* Channel 0 */
> +}
> +
>  static void get_device_id(IPMIBmcSim *ibs,
>uint8_t *cmd, unsigned int cmd_len,
>uint8_t *rsp, unsigned int *rsp_len,
> @@ -1571,7 +1583,8 @@ static void get_sensor_type(IPMIBmcSim *ibs,
>  static const IPMICmdHandler chassis_cmds[] = {
>  [IPMI_CMD_GET_CHASSIS_CAPABILITIES] = chassis_capabilities,
>  [IPMI_CMD_GET_CHASSIS_STATUS] = chassis_status,
> -[IPMI_CMD_CHASSIS_CONTROL] = chassis_control
> +[IPMI_CMD_CHASSIS_CONTROL] = chassis_control,
> +[IPMI_CMD_GET_SYS_RESTART_CAUSE] = chassis_get_sys_restart_cause
>  };
>  static const IPMINetfn chassis_netfn = {
>  .cmd_nums = ARRAY_SIZE(chassis_cmds),
> @@ -1692,6 +1705,7 @@ static void ipmi_sim_init(Object *obj)
>  ibs->bmc_global_enables = (1 << IPMI_BMC_EVENT_LOG_BIT);
>  ibs->device_id = 0x20;
>  ibs->ipmi_version = 0x02; /* IPMI 2.0 */
> +ibs->restart_cause = 0;
>  for (i = 0; i < 4; i++) {
>  ibs->sel.last_addition[i] = 0xff;
>  ibs->sel.last_clear[i] = 0xff;




Re: [Qemu-devel] [RFC PATCH 0/2] Early release of -drive QemuOpts

2016-01-22 Thread Max Reitz
On 22.01.2016 15:01, Paolo Bonzini wrote:
> 
> 
> On 08/01/2016 18:37, Paolo Bonzini wrote:
>> In short, this patch gets rid of blockdev_mark_auto_del and
>> blockdev_auto_del.
>>
>> With these patches, it is possible to create a new -drive with the same
>> id as soon as the DEVICE_DELETED event is delivered (which equals to
>> unrealize).
>>
>> I'm sorry I'm not able to explain the history (and probably do not
>> understand the full ramifications) of this.  That's why this is just
>> an RFC.
>>
>> The idea here is that reference counting the BlockBackend is enough to
>> defer the deletion of the block device as much as necessary; anticipating
>> the demise of the DriveInfo is not a problem, and has the desired effect
>> of freeing the QemuOpts.
>>
>> Paolo
>>
>> Paolo Bonzini (2):
>>   block: detach devices from DriveInfo at unrealize time
>>   block: remove legacy_dinfo at blk_detach_dev time
>>
>>  block/block-backend.c| 14 
>>  blockdev.c   | 26 --
>>  hw/block/virtio-blk.c|  4 +++-
>>  hw/block/xen_disk.c  |  1 +
>>  hw/core/qdev-properties-system.c |  2 +-
>>  hw/ide/piix.c|  3 +++
>>  hw/scsi/scsi-bus.c   |  4 +++-
>>  hw/usb/dev-storage.c |  3 ++-
>>  include/sysemu/blockdev.h|  5 ++---
>>  9 files changed, 33 insertions(+), 29 deletions(-)
>>
> 
> Ping?  Any comments or other kinds of review? :)

I skimmed it last week and I remember that I found the idea sound and
didn't have any objections; but that I didn't feel confident for a R-b
or explicit comment, because I don't think I understand the full
ramifications of it either. ;-)

Max



signature.asc
Description: OpenPGP digital signature


[Qemu-devel] [PATCH v3 3/4] Revert "hw/block/fdc: Implement tray status"

2016-01-22 Thread Max Reitz
This reverts the changes that commit
2e1280e8ff95b3145bc6262accc9d447718e5318 applied to hw/block/fdc.c.

That commit changed tests/fdc-test.c, too, because after it, one less
TRAY_MOVED event would be emitted when executing 'change' on an empty
drive. However, now, no TRAY_MOVED events will be emitted at all, and
the tray_open status returned by query-block will always be false,
necessitating (different) changes to tests/fdc-test.c and iotest 118,
which is why this patch is not a pure revert of said commit.

Signed-off-by: Max Reitz 
Reviewed-by: Eric Blake 
---
 hw/block/fdc.c |  20 ++---
 tests/fdc-test.c   |   2 -
 tests/qemu-iotests/118 | 117 +++--
 3 files changed, 40 insertions(+), 99 deletions(-)

diff --git a/hw/block/fdc.c b/hw/block/fdc.c
index 6711c6a..d2df218 100644
--- a/hw/block/fdc.c
+++ b/hw/block/fdc.c
@@ -193,8 +193,6 @@ typedef struct FDrive {
 uint8_t ro;   /* Is read-only   */
 uint8_t media_changed;/* Is media changed   */
 uint8_t media_rate;   /* Data rate of medium*/
-
-bool media_inserted;  /* Is there a medium in the tray */
 } FDrive;
 
 static void fd_init(FDrive *drv)
@@ -264,7 +262,7 @@ static int fd_seek(FDrive *drv, uint8_t head, uint8_t 
track, uint8_t sect,
 #endif
 drv->head = head;
 if (drv->track != track) {
-if (drv->media_inserted) {
+if (drv->blk != NULL && blk_is_inserted(drv->blk)) {
 drv->media_changed = 0;
 }
 ret = 1;
@@ -273,7 +271,7 @@ static int fd_seek(FDrive *drv, uint8_t head, uint8_t 
track, uint8_t sect,
 drv->sect = sect;
 }
 
-if (!drv->media_inserted) {
+if (drv->blk == NULL || !blk_is_inserted(drv->blk)) {
 ret = 2;
 }
 
@@ -299,7 +297,7 @@ static void fd_revalidate(FDrive *drv)
 ro = blk_is_read_only(drv->blk);
 pick_geometry(drv->blk, _heads, _track,
   _sect, drv->drive, , );
-if (!drv->media_inserted) {
+if (!blk_is_inserted(drv->blk)) {
 FLOPPY_DPRINTF("No disk in drive\n");
 } else {
 FLOPPY_DPRINTF("Floppy disk (%d h %d t %d s) %s\n", nb_heads,
@@ -695,7 +693,7 @@ static bool fdrive_media_changed_needed(void *opaque)
 {
 FDrive *drive = opaque;
 
-return (drive->media_inserted && drive->media_changed != 1);
+return (drive->blk != NULL && drive->media_changed != 1);
 }
 
 static const VMStateDescription vmstate_fdrive_media_changed = {
@@ -2187,21 +2185,12 @@ static void fdctrl_change_cb(void *opaque, bool load)
 {
 FDrive *drive = opaque;
 
-drive->media_inserted = load && drive->blk && blk_is_inserted(drive->blk);
-
 drive->media_changed = 1;
 fd_revalidate(drive);
 }
 
-static bool fdctrl_is_tray_open(void *opaque)
-{
-FDrive *drive = opaque;
-return !drive->media_inserted;
-}
-
 static const BlockDevOps fdctrl_block_ops = {
 .change_media_cb = fdctrl_change_cb,
-.is_tray_open = fdctrl_is_tray_open,
 };
 
 /* Init functions */
@@ -2229,7 +2218,6 @@ static void fdctrl_connect_drives(FDCtrl *fdctrl, Error 
**errp)
 fdctrl_change_cb(drive, 0);
 if (drive->blk) {
 blk_set_dev_ops(drive->blk, _block_ops, drive);
-drive->media_inserted = blk_is_inserted(drive->blk);
 }
 }
 }
diff --git a/tests/fdc-test.c b/tests/fdc-test.c
index b5a4696..7f0e215 100644
--- a/tests/fdc-test.c
+++ b/tests/fdc-test.c
@@ -304,7 +304,6 @@ static void test_media_insert(void)
 qmp_discard_response("{'execute':'change', 'arguments':{"
  " 'device':'floppy0', 'target': %s, 'arg': 'raw' }}",
  test_image);
-qmp_discard_response(""); /* ignore event (open -> close) */
 
 dir = inb(FLOPPY_BASE + reg_dir);
 assert_bit_set(dir, DSKCHG);
@@ -335,7 +334,6 @@ static void test_media_change(void)
  * reset the bit. */
 qmp_discard_response("{'execute':'eject', 'arguments':{"
  " 'device':'floppy0' }}");
-qmp_discard_response(""); /* ignore event */
 
 dir = inb(FLOPPY_BASE + reg_dir);
 assert_bit_set(dir, DSKCHG);
diff --git a/tests/qemu-iotests/118 b/tests/qemu-iotests/118
index 114d0e2..7caa38c 100755
--- a/tests/qemu-iotests/118
+++ b/tests/qemu-iotests/118
@@ -42,6 +42,9 @@ class ChangeBaseClass(iotests.QMPTestCase):
 self.has_opened = True
 
 def wait_for_open(self):
+if not self.has_real_tray:
+return
+
 timeout = time.clock() + 3
 while not self.has_opened and time.clock() < timeout:
 self.process_events()
@@ -49,6 +52,9 @@ class ChangeBaseClass(iotests.QMPTestCase):
 self.fail('Timeout while waiting for the tray to open')
 
 def wait_for_close(self):
+if not self.has_real_tray:
+return
+
 timeout = time.clock() + 3

[Qemu-devel] [PATCH v3 2/4] blockdev: Fix 'change' for slot devices

2016-01-22 Thread Max Reitz
'change' and related operations did not work when used on guest devices
featuring removable media but no actual tray, because
blk_dev_is_tray_open() always returned false for them and the
blockdev-{insert,remove}-medium commands required it to return true.

Fix this by making blockdev-{insert,remove}-medium work on tray-less
devices. Also, blockdev-{open,close}-tray are now explicitly no-ops when
invoked on such devices, and blk_dev_change_media_cb() is instead
called by blockdev-{insert,remove}-medium (for tray-less devices only).

Reported-by: Peter Maydell 
Cc: qemu-stable 
Signed-off-by: Max Reitz 
---
 blockdev.c   | 31 +--
 qapi/block-core.json |  3 +--
 2 files changed, 30 insertions(+), 4 deletions(-)

diff --git a/blockdev.c b/blockdev.c
index 07cfe25..1044a6a 100644
--- a/blockdev.c
+++ b/blockdev.c
@@ -2304,6 +2304,11 @@ void qmp_blockdev_open_tray(const char *device, bool 
has_force, bool force,
 return;
 }
 
+if (!blk_dev_has_tray(blk)) {
+/* Ignore this command on tray-less devices */
+return;
+}
+
 if (blk_dev_is_tray_open(blk)) {
 return;
 }
@@ -2334,6 +2339,11 @@ void qmp_blockdev_close_tray(const char *device, Error 
**errp)
 return;
 }
 
+if (!blk_dev_has_tray(blk)) {
+/* Ignore this command on tray-less devices */
+return;
+}
+
 if (!blk_dev_is_tray_open(blk)) {
 return;
 }
@@ -2363,7 +2373,7 @@ void qmp_x_blockdev_remove_medium(const char *device, 
Error **errp)
 return;
 }
 
-if (has_device && !blk_dev_is_tray_open(blk)) {
+if (has_device && blk_dev_has_tray(blk) && !blk_dev_is_tray_open(blk)) {
 error_setg(errp, "Tray of device '%s' is not open", device);
 return;
 }
@@ -2388,6 +2398,14 @@ void qmp_x_blockdev_remove_medium(const char *device, 
Error **errp)
 
 blk_remove_bs(blk);
 
+if (!blk_dev_has_tray(blk)) {
+/* For tray-less devices, blockdev-open-tray is a no-op (or may not be
+ * called at all); therefore, the medium needs to be ejected here.
+ * Do it after blk_remove_bs() so blk_is_inserted(blk) returns the 
@load
+ * value passed here (i.e. false). */
+blk_dev_change_media_cb(blk, false);
+}
+
 out:
 aio_context_release(aio_context);
 }
@@ -2413,7 +2431,7 @@ static void qmp_blockdev_insert_anon_medium(const char 
*device,
 return;
 }
 
-if (has_device && !blk_dev_is_tray_open(blk)) {
+if (has_device && blk_dev_has_tray(blk) && !blk_dev_is_tray_open(blk)) {
 error_setg(errp, "Tray of device '%s' is not open", device);
 return;
 }
@@ -2426,6 +2444,15 @@ static void qmp_blockdev_insert_anon_medium(const char 
*device,
 blk_insert_bs(blk, bs);
 
 QTAILQ_INSERT_TAIL(_states, bs, device_list);
+
+if (!blk_dev_has_tray(blk)) {
+/* For tray-less devices, blockdev-close-tray is a no-op (or may not be
+ * called at all); therefore, the medium needs to be pushed into the
+ * slot here.
+ * Do it after blk_insert_bs() so blk_is_inserted(blk) returns the 
@load
+ * value passed here (i.e. true). */
+blk_dev_change_media_cb(blk, true);
+}
 }
 
 void qmp_x_blockdev_insert_medium(const char *device, const char *node_name,
diff --git a/qapi/block-core.json b/qapi/block-core.json
index 0a915ed..40239bf 100644
--- a/qapi/block-core.json
+++ b/qapi/block-core.json
@@ -2098,8 +2098,7 @@
 #   respond to the eject request
 # - if the BlockBackend denoted by @device does not have a guest device 
attached
 #   to it
-# - if the guest device does not have an actual tray and is empty, for instance
-#   for floppy disk drives
+# - if the guest device does not have an actual tray
 #
 # @device: block device name
 #
-- 
2.7.0




Re: [Qemu-devel] [PATCH v3] vfio/common: Check iova with limit not with size

2016-01-22 Thread Alex Williamson
On Thu, 2016-01-21 at 14:15 +0100, Pierre Morel wrote:
> 
> On 01/20/2016 04:46 PM, Alex Williamson wrote:
> > On Wed, 2016-01-20 at 16:14 +0100, Pierre Morel wrote:
> > > On 01/12/2016 07:16 PM, Alex Williamson wrote:
> > > > On Tue, 2016-01-12 at 16:11 +0100, Pierre Morel wrote:
> > > > > In vfio_listener_region_add(), we try to validate that the region
> > > > > is
> > > > > not
> > > > > zero sized and hasn't overflowed the addresses space.
> > > > > 
> > > > > But the calculation uses the size of the region instead of
> > > > > using the region's limit (size - 1).
> > > > > 
> > > > > This leads to Int128 overflow when the region has
> > > > > been initialized to UINT64_MAX because in this case
> > > > > memory_region_init() transform the size from UINT64_MAX
> > > > > to int128_2_64().
> > > > > 
> > > > > Let's really use the limit by sustracting one to the size
> > > > > and take care to use the limit for functions using limit
> > > > > and size to call functions which need size.
> > > > > 
> > > > > Signed-off-by: Pierre Morel 
> > > > > ---
> > > > > 
> > > > > Changes from v2:
> > > > >   - all, just ignore v2, sorry about this,
> > > > > this is build after v1
> > > > > 
> > > > > Changes from v1:
> > > > >   - adjust the tests by knowing we already substracted one to
> > > > > end.
> > > > > 
> > > > >    hw/vfio/common.c |   14 +++---
> > > > >    1 files changed, 7 insertions(+), 7 deletions(-)
> > > > > 
> > > > > diff --git a/hw/vfio/common.c b/hw/vfio/common.c
> > > > > index 6797208..a5f6643 100644
> > > > > --- a/hw/vfio/common.c
> > > > > +++ b/hw/vfio/common.c
> > > > > @@ -348,12 +348,12 @@ static void
> > > > > vfio_listener_region_add(MemoryListener *listener,
> > > > >    if (int128_ge(int128_make64(iova), llend)) {
> > > > >    return;
> > > > >    }
> > > > > -end = int128_get64(llend);
> > > > > +end = int128_get64(int128_sub(llend, int128_one()));
> > > > >    
> > > > > -if ((iova < container->min_iova) || ((end - 1) > container-
> > > > > > max_iova)) {
> > > > > +if ((iova < container->min_iova) || (end  > container-
> > > > > > max_iova)) {
> > > > >    error_report("vfio: IOMMU container %p can't map guest
> > > > > IOVA
> > > > > region"
> > > > > " 0x%"HWADDR_PRIx"..0x%"HWADDR_PRIx,
> > > > > - container, iova, end - 1);
> > > > > + container, iova, end);
> > > > >    ret = -EFAULT;
> > > > >    goto fail;
> > > > >    }
> > > > > @@ -363,7 +363,7 @@ static void
> > > > > vfio_listener_region_add(MemoryListener *listener,
> > > > >    if (memory_region_is_iommu(section->mr)) {
> > > > >    VFIOGuestIOMMU *giommu;
> > > > >    
> > > > > -trace_vfio_listener_region_add_iommu(iova, end - 1);
> > > > > +trace_vfio_listener_region_add_iommu(iova, end);
> > > > >    /*
> > > > > * FIXME: We should do some checking to see if the
> > > > > * capabilities of the host VFIO IOMMU are adequate to
> > > > > model
> > > > > @@ -394,13 +394,13 @@ static void
> > > > > vfio_listener_region_add(MemoryListener *listener,
> > > > >    section->offset_within_region +
> > > > >    (iova - section->offset_within_address_space);
> > > > >    
> > > > > -trace_vfio_listener_region_add_ram(iova, end - 1, vaddr);
> > > > > +trace_vfio_listener_region_add_ram(iova, end, vaddr);
> > > > >    
> > > > > -ret = vfio_dma_map(container, iova, end - iova, vaddr,
> > > > > section-
> > > > > > readonly);
> > > > > +ret = vfio_dma_map(container, iova, end - iova + 1, vaddr,
> > > > > section->readonly);
> > > > >    if (ret) {
> > > > >    error_report("vfio_dma_map(%p, 0x%"HWADDR_PRIx", "
> > > > > "0x%"HWADDR_PRIx", %p) = %d (%m)",
> > > > > - container, iova, end - iova, vaddr, ret);
> > > > > + container, iova, end - iova + 1, vaddr,
> > > > > ret);
> > > > >    goto fail;
> > > > >    }
> > > > >    
> > > > Hmm, did we just push the overflow from one place to another?  If
> > > > we're
> > > > mapping a full region of size int128_2_64() starting at iova zero,
> > > > then
> > > > this becomes (0x___ - 0 + 1) = 0.  So I think we
> > > > need
> > > > to calculate size with 128bit arithmetic too and let it assert if
> > > > we
> > > > overflow, ie:
> > > > 
> > > > diff --git a/hw/vfio/common.c b/hw/vfio/common.c
> > > > index a5f6643..13ad90b 100644
> > > > --- a/hw/vfio/common.c
> > > > +++ b/hw/vfio/common.c
> > > > @@ -321,7 +321,7 @@ static void
> > > > vfio_listener_region_add(MemoryListener *listener,
> > > > MemoryRegionSection
> > > > *section)
> > > >    {
> > > >    VFIOContainer *container = container_of(listener,
> > > > VFIOContainer, listener);
> > > > -hwaddr iova, 

Re: [Qemu-devel] [PATCH v3] vfio/common: Check iova with limit not with size

2016-01-22 Thread Alex Williamson
On Fri, 2016-01-22 at 15:14 -0700, Alex Williamson wrote:
> On Thu, 2016-01-21 at 14:15 +0100, Pierre Morel wrote:
> > 
> > On 01/20/2016 04:46 PM, Alex Williamson wrote:
> > > On Wed, 2016-01-20 at 16:14 +0100, Pierre Morel wrote:
> > > > On 01/12/2016 07:16 PM, Alex Williamson wrote:
> > > > > On Tue, 2016-01-12 at 16:11 +0100, Pierre Morel wrote:
> > > > > > In vfio_listener_region_add(), we try to validate that the region
> > > > > > is
> > > > > > not
> > > > > > zero sized and hasn't overflowed the addresses space.
> > > > > > 
> > > > > > But the calculation uses the size of the region instead of
> > > > > > using the region's limit (size - 1).
> > > > > > 
> > > > > > This leads to Int128 overflow when the region has
> > > > > > been initialized to UINT64_MAX because in this case
> > > > > > memory_region_init() transform the size from UINT64_MAX
> > > > > > to int128_2_64().
> > > > > > 
> > > > > > Let's really use the limit by sustracting one to the size
> > > > > > and take care to use the limit for functions using limit
> > > > > > and size to call functions which need size.
> > > > > > 
> > > > > > Signed-off-by: Pierre Morel 
> > > > > > ---
> > > > > > 
> > > > > > Changes from v2:
> > > > > >   - all, just ignore v2, sorry about this,
> > > > > > this is build after v1
> > > > > > 
> > > > > > Changes from v1:
> > > > > >   - adjust the tests by knowing we already substracted one to
> > > > > > end.
> > > > > > 
> > > > > >    hw/vfio/common.c |   14 +++---
> > > > > >    1 files changed, 7 insertions(+), 7 deletions(-)
> > > > > > 
> > > > > > diff --git a/hw/vfio/common.c b/hw/vfio/common.c
> > > > > > index 6797208..a5f6643 100644
> > > > > > --- a/hw/vfio/common.c
> > > > > > +++ b/hw/vfio/common.c
> > > > > > @@ -348,12 +348,12 @@ static void
> > > > > > vfio_listener_region_add(MemoryListener *listener,
> > > > > >    if (int128_ge(int128_make64(iova), llend)) {
> > > > > >    return;
> > > > > >    }
> > > > > > -end = int128_get64(llend);
> > > > > > +end = int128_get64(int128_sub(llend, int128_one()));
> > > > > >    
> > > > > > -if ((iova < container->min_iova) || ((end - 1) > container-
> > > > > > > max_iova)) {
> > > > > > +if ((iova < container->min_iova) || (end  > container-
> > > > > > > max_iova)) {
> > > > > >    error_report("vfio: IOMMU container %p can't map guest
> > > > > > IOVA
> > > > > > region"
> > > > > > " 0x%"HWADDR_PRIx"..0x%"HWADDR_PRIx,
> > > > > > - container, iova, end - 1);
> > > > > > + container, iova, end);
> > > > > >    ret = -EFAULT;
> > > > > >    goto fail;
> > > > > >    }
> > > > > > @@ -363,7 +363,7 @@ static void
> > > > > > vfio_listener_region_add(MemoryListener *listener,
> > > > > >    if (memory_region_is_iommu(section->mr)) {
> > > > > >    VFIOGuestIOMMU *giommu;
> > > > > >    
> > > > > > -trace_vfio_listener_region_add_iommu(iova, end - 1);
> > > > > > +trace_vfio_listener_region_add_iommu(iova, end);
> > > > > >    /*
> > > > > > * FIXME: We should do some checking to see if the
> > > > > > * capabilities of the host VFIO IOMMU are adequate to
> > > > > > model
> > > > > > @@ -394,13 +394,13 @@ static void
> > > > > > vfio_listener_region_add(MemoryListener *listener,
> > > > > >    section->offset_within_region +
> > > > > >    (iova - section->offset_within_address_space);
> > > > > >    
> > > > > > -trace_vfio_listener_region_add_ram(iova, end - 1, vaddr);
> > > > > > +trace_vfio_listener_region_add_ram(iova, end, vaddr);
> > > > > >    
> > > > > > -ret = vfio_dma_map(container, iova, end - iova, vaddr,
> > > > > > section-
> > > > > > > readonly);
> > > > > > +ret = vfio_dma_map(container, iova, end - iova + 1, vaddr,
> > > > > > section->readonly);
> > > > > >    if (ret) {
> > > > > >    error_report("vfio_dma_map(%p, 0x%"HWADDR_PRIx", "
> > > > > > "0x%"HWADDR_PRIx", %p) = %d (%m)",
> > > > > > - container, iova, end - iova, vaddr, ret);
> > > > > > + container, iova, end - iova + 1, vaddr,
> > > > > > ret);
> > > > > >    goto fail;
> > > > > >    }
> > > > > >    
> > > > > Hmm, did we just push the overflow from one place to another?  If
> > > > > we're
> > > > > mapping a full region of size int128_2_64() starting at iova zero,
> > > > > then
> > > > > this becomes (0x___ - 0 + 1) = 0.  So I think we
> > > > > need
> > > > > to calculate size with 128bit arithmetic too and let it assert if
> > > > > we
> > > > > overflow, ie:
> > > > > 
> > > > > diff --git a/hw/vfio/common.c b/hw/vfio/common.c
> > > > > index a5f6643..13ad90b 100644
> > > > > --- a/hw/vfio/common.c
> > > > > +++ b/hw/vfio/common.c
> > > > > @@ -321,7 +321,7 @@ static void
> > 

[Qemu-devel] [PATCH v3 1/4] block: Add blk_dev_has_tray()

2016-01-22 Thread Max Reitz
Pull out the check whether a block device has a tray from
blk_dev_is_tray_open() into its own function so both attributes (whether
there is a tray vs. whether that tray is open) can be queried
independently.

Cc: qemu-stable 
Signed-off-by: Max Reitz 
Reviewed-by: Eric Blake 
Reviewed-by: Alberto Garcia 
---
 block/block-backend.c | 10 +-
 include/block/block_int.h |  1 +
 2 files changed, 10 insertions(+), 1 deletion(-)

diff --git a/block/block-backend.c b/block/block-backend.c
index efd6146..a4208f1 100644
--- a/block/block-backend.c
+++ b/block/block-backend.c
@@ -459,6 +459,14 @@ bool blk_dev_has_removable_media(BlockBackend *blk)
 }
 
 /*
+ * Does @blk's attached device model have a tray?
+ */
+bool blk_dev_has_tray(BlockBackend *blk)
+{
+return blk->dev_ops && blk->dev_ops->is_tray_open;
+}
+
+/*
  * Notify @blk's attached device model of a media eject request.
  * If @force is true, the medium is about to be yanked out forcefully.
  */
@@ -474,7 +482,7 @@ void blk_dev_eject_request(BlockBackend *blk, bool force)
  */
 bool blk_dev_is_tray_open(BlockBackend *blk)
 {
-if (blk->dev_ops && blk->dev_ops->is_tray_open) {
+if (blk_dev_has_tray(blk)) {
 return blk->dev_ops->is_tray_open(blk->dev_opaque);
 }
 return false;
diff --git a/include/block/block_int.h b/include/block/block_int.h
index 428fa33..ec31df1 100644
--- a/include/block/block_int.h
+++ b/include/block/block_int.h
@@ -695,6 +695,7 @@ void blk_set_bs(BlockBackend *blk, BlockDriverState *bs);
 
 void blk_dev_change_media_cb(BlockBackend *blk, bool load);
 bool blk_dev_has_removable_media(BlockBackend *blk);
+bool blk_dev_has_tray(BlockBackend *blk);
 void blk_dev_eject_request(BlockBackend *blk, bool force);
 bool blk_dev_is_tray_open(BlockBackend *blk);
 bool blk_dev_is_medium_locked(BlockBackend *blk);
-- 
2.7.0




[Qemu-devel] [PATCH v3 0/4] blockdev: Fix 'change' for slot devices

2016-01-22 Thread Max Reitz
The series "BlockBackend and media" intended all block devices with
removable media to implement a tray model; if the devices does not have
a tray, it should emulate one.

While this may make sense from a technical perspective (blockdev-*-tray
are guest device controlling operations, invoking
blk_dev_change_media_cb(); blockdev-*-medium are operations concerning
the block layer, controlling the BB-BDS link), it is (probably)
unintuitive to users, and it requires said implementation of an emulated
tray for each of the slot devices (floppy disk drives and SD card
readers).

We can get rid of those virtual trays by special-casing tray-less
devices in blockdev-*-tray (those operations are no-ops there) and in
blockdev-*-medium (those operations then have to invoke
blk_dev_change_media_cb()). With this change, changing the medium
inserted into a slot device will no longer emit TRAY_MOVED events (which
seems like a bugfix to me, because slot devices actually do not have
trays).


Patches 1 and 2 are CC'd to qemu-stable because they fix 'change' for SD
card readers. Patch 3 does not fix it for floppy disk drives, it just
changes the behavior when used on them (no TRAY_MOVED events, no
tray_open status, and blockdev-{open,close}-tray are optional), which is
why it is not CC'd to qemu-stable; and patch 4 is more of a change in
behavior than a stable-worthy fix.


v3:
- Patch 2: Keep blk_insert_bs(...) and
  QTAILQ_INSERT_TAIL(_states, ...) paired [Berto]


git-backport-diff against v2:

Key:
[] : patches are identical
[] : number of functional differences between upstream/downstream patch
[down] : patch is downstream-only
The flags [FC] indicate (F)unctional and (C)ontextual differences, respectively

001/4:[] [--] 'block: Add blk_dev_has_tray()'
002/4:[0002] [FC] 'blockdev: Fix 'change' for slot devices'
003/4:[] [--] 'Revert "hw/block/fdc: Implement tray status"'
004/4:[] [--] 'block/qapi: Emit tray_open only if there is a tray'


Max Reitz (4):
  block: Add blk_dev_has_tray()
  blockdev: Fix 'change' for slot devices
  Revert "hw/block/fdc: Implement tray status"
  block/qapi: Emit tray_open only if there is a tray

 block/block-backend.c  |  10 +++-
 block/qapi.c   |   2 +-
 blockdev.c |  31 +++-
 hw/block/fdc.c |  20 ++--
 include/block/block_int.h  |   1 +
 qapi/block-core.json   |   7 ++-
 tests/fdc-test.c   |   2 -
 tests/qemu-iotests/067.out |   4 --
 tests/qemu-iotests/118 | 117 ++---
 9 files changed, 83 insertions(+), 111 deletions(-)

-- 
2.7.0




[Qemu-devel] [PATCH v3 4/4] block/qapi: Emit tray_open only if there is a tray

2016-01-22 Thread Max Reitz
Signed-off-by: Max Reitz 
Reviewed-by: Eric Blake 
Reviewed-by: Alberto Garcia 
---
 block/qapi.c   | 2 +-
 qapi/block-core.json   | 4 ++--
 tests/qemu-iotests/067.out | 4 
 3 files changed, 3 insertions(+), 7 deletions(-)

diff --git a/block/qapi.c b/block/qapi.c
index a49c118..bbe0c9d 100644
--- a/block/qapi.c
+++ b/block/qapi.c
@@ -300,7 +300,7 @@ static void bdrv_query_info(BlockBackend *blk, BlockInfo 
**p_info,
 info->locked = blk_dev_is_medium_locked(blk);
 info->removable = blk_dev_has_removable_media(blk);
 
-if (blk_dev_has_removable_media(blk)) {
+if (blk_dev_has_tray(blk)) {
 info->has_tray_open = true;
 info->tray_open = blk_dev_is_tray_open(blk);
 }
diff --git a/qapi/block-core.json b/qapi/block-core.json
index 40239bf..628a41d 100644
--- a/qapi/block-core.json
+++ b/qapi/block-core.json
@@ -382,8 +382,8 @@
 # @locked: True if the guest has locked this device from having its media
 #  removed
 #
-# @tray_open: #optional True if the device has a tray and it is open
-# (only present if removable is true)
+# @tray_open: #optional True if the device's tray is open
+# (only present if it has a tray)
 #
 # @dirty-bitmaps: #optional dirty bitmaps information (only present if the
 # driver has one or more dirty bitmaps) (Since 2.0)
diff --git a/tests/qemu-iotests/067.out b/tests/qemu-iotests/067.out
index 27ad56f..ae3fccb 100644
--- a/tests/qemu-iotests/067.out
+++ b/tests/qemu-iotests/067.out
@@ -169,7 +169,6 @@ Testing: -drive 
file=TEST_DIR/t.qcow2,format=qcow2,if=none,id=disk
 "file": "TEST_DIR/t.qcow2",
 "encryption_key_missing": false
 },
-"tray_open": false,
 "type": "unknown"
 }
 ]
@@ -289,7 +288,6 @@ Testing:
 "file": "TEST_DIR/t.qcow2",
 "encryption_key_missing": false
 },
-"tray_open": false,
 "type": "unknown"
 }
 ]
@@ -410,7 +408,6 @@ Testing:
 "file": "TEST_DIR/t.qcow2",
 "encryption_key_missing": false
 },
-"tray_open": false,
 "type": "unknown"
 }
 ]
@@ -501,7 +498,6 @@ Testing:
 "file": "TEST_DIR/t.qcow2",
 "encryption_key_missing": false
 },
-"tray_open": false,
 "type": "unknown"
 }
 ]
-- 
2.7.0




Re: [Qemu-devel] [PATCH v2 2/4] blockdev: Fix 'change' for slot devices

2016-01-22 Thread Max Reitz
On 22.01.2016 10:58, Alberto Garcia wrote:
> On Wed 20 Jan 2016 07:29:19 PM CET, Max Reitz wrote:
>> @@ -2424,6 +2442,15 @@ static void qmp_blockdev_insert_anon_medium(const 
>> char *device,
>>  
>>  blk_insert_bs(blk, bs);
>>  
>> +if (!blk_dev_has_tray(blk)) {
>> +/* For tray-less devices, blockdev-close-tray is a no-op (or may 
>> not be
>> + * called at all); therefore, the medium needs to be pushed into the
>> + * slot here.
>> + * Do it after blk_insert_bs() so blk_is_inserted(blk) returns the 
>> @load
>> + * value passed here (i.e. true). */
>> +blk_dev_change_media_cb(blk, true);
>> +}
>> +
>>  QTAILQ_INSERT_TAIL(_states, bs, device_list);
>>  }
> 
> Any reason why you do this before updating bdrv_states ?

The reason is that I just moved it after blk_insert_bs(). But that's
wrong, QTAILQ_INSERT_TAIL() should be paired with blk_insert_bs()
without anything in between, thanks!

(I don't think it changes anything in practice, but it still is wrong.)

> If the device has a tray this would happen afterwards, in
> qmp_blockdev_close_tray().

Well, tray devices are no longer really a good comparison, because in
the opposite case (ejecting a medium), for them we open the tray and
then eject the medium; however, for trayless devices we now eject the
medium and only then "open the tray" (invoke blk_dev_change_media_cb()).

Anyway, will fix, thanks.

Max



signature.asc
Description: OpenPGP digital signature


Re: [Qemu-devel] [PATCH v7 01/15] block: Add "file" output parameter to block status query functions

2016-01-22 Thread Max Reitz
On 22.01.2016 04:06, Fam Zheng wrote:
> The added parameter can be used to return the BDS pointer which the
> valid offset is referring to. Its value should be ignored unless
> BDRV_BLOCK_OFFSET_VALID in ret is set.
> 
> Until block drivers fill in the right value, let's clear it explicitly
> right before calling .bdrv_get_block_status.
> 
> The "bs->file" condition in bdrv_co_get_block_status is kept now to keep 
> iotest
> case 102 passing, and will be fixed once all drivers return the right file
> pointer.
> 
> Signed-off-by: Fam Zheng 
> ---
>  block/io.c| 38 ++
>  block/iscsi.c |  6 --
>  block/mirror.c|  3 ++-
>  block/parallels.c |  2 +-
>  block/qcow.c  |  2 +-
>  block/qcow2.c |  2 +-
>  block/qed.c   |  3 ++-
>  block/raw-posix.c |  3 ++-
>  block/raw_bsd.c   |  3 ++-
>  block/sheepdog.c  |  2 +-
>  block/vdi.c   |  2 +-
>  block/vmdk.c  |  2 +-
>  block/vpc.c   |  2 +-
>  block/vvfat.c |  2 +-
>  include/block/block.h | 11 +++
>  include/block/block_int.h |  3 ++-
>  qemu-img.c| 13 +
>  17 files changed, 64 insertions(+), 35 deletions(-)

Reviewed-by: Max Reitz 



signature.asc
Description: OpenPGP digital signature


Re: [Qemu-devel] [PATCH v2 3/9] ipmi: replace *_MAXCMD defines

2016-01-22 Thread Greg Kurz
On Thu, 21 Jan 2016 18:18:48 +0100
Cédric Le Goater  wrote:

> ARRAY_SIZE() is simple to use and removes the need to pre-define
> the size of the command arrays.
> 
> Signed-off-by: Cédric Le Goater 
> ---

Much nicer !

Reviewed-by: Greg Kurz 

>  hw/ipmi/ipmi_bmc_sim.c | 21 -
>  1 file changed, 8 insertions(+), 13 deletions(-)
> 
> diff --git a/hw/ipmi/ipmi_bmc_sim.c b/hw/ipmi/ipmi_bmc_sim.c
> index e42c7e86c344..fc596a548df7 100644
> --- a/hw/ipmi/ipmi_bmc_sim.c
> +++ b/hw/ipmi/ipmi_bmc_sim.c
> @@ -30,14 +30,12 @@
>  #include "qemu/error-report.h"
> 
>  #define IPMI_NETFN_CHASSIS0x00
> -#define IPMI_NETFN_CHASSIS_MAXCMD 0x03
> 
>  #define IPMI_CMD_GET_CHASSIS_CAPABILITIES 0x00
>  #define IPMI_CMD_GET_CHASSIS_STATUS   0x01
>  #define IPMI_CMD_CHASSIS_CONTROL  0x02
> 
>  #define IPMI_NETFN_SENSOR_EVENT   0x04
> -#define IPMI_NETFN_SENSOR_EVENT_MAXCMD0x2e
> 
>  #define IPMI_CMD_SET_SENSOR_EVT_ENABLE0x28
>  #define IPMI_CMD_GET_SENSOR_EVT_ENABLE0x29
> @@ -46,7 +44,6 @@
>  #define IPMI_CMD_GET_SENSOR_READING   0x2d
> 
>  /* #define IPMI_NETFN_APP 0x06 In ipmi.h */
> -#define IPMI_NETFN_APP_MAXCMD 0x36
> 
>  #define IPMI_CMD_GET_DEVICE_ID0x01
>  #define IPMI_CMD_COLD_RESET   0x02
> @@ -63,7 +60,6 @@
>  #define IPMI_CMD_READ_EVT_MSG_BUF 0x35
> 
>  #define IPMI_NETFN_STORAGE0x0a
> -#define IPMI_NETFN_STORAGE_MAXCMD 0x4a
> 
>  #define IPMI_CMD_GET_SDR_REP_INFO 0x20
>  #define IPMI_CMD_GET_SDR_REP_ALLOC_INFO   0x21
> @@ -1518,18 +1514,17 @@ static void get_sensor_reading(IPMIBmcSim *ibs,
>  }
>  }
> 
> -static const IPMICmdHandler chassis_cmds[IPMI_NETFN_CHASSIS_MAXCMD] = {
> +static const IPMICmdHandler chassis_cmds[] = {
>  [IPMI_CMD_GET_CHASSIS_CAPABILITIES] = chassis_capabilities,
>  [IPMI_CMD_GET_CHASSIS_STATUS] = chassis_status,
>  [IPMI_CMD_CHASSIS_CONTROL] = chassis_control
>  };
>  static const IPMINetfn chassis_netfn = {
> -.cmd_nums = IPMI_NETFN_CHASSIS_MAXCMD,
> +.cmd_nums = ARRAY_SIZE(chassis_cmds),
>  .cmd_handlers = chassis_cmds
>  };
> 
> -static const IPMICmdHandler
> -sensor_event_cmds[IPMI_NETFN_SENSOR_EVENT_MAXCMD] = {
> +static const IPMICmdHandler sensor_event_cmds[] = {
>  [IPMI_CMD_SET_SENSOR_EVT_ENABLE] = set_sensor_evt_enable,
>  [IPMI_CMD_GET_SENSOR_EVT_ENABLE] = get_sensor_evt_enable,
>  [IPMI_CMD_REARM_SENSOR_EVTS] = rearm_sensor_evts,
> @@ -1537,11 +1532,11 @@ sensor_event_cmds[IPMI_NETFN_SENSOR_EVENT_MAXCMD] = {
>  [IPMI_CMD_GET_SENSOR_READING] = get_sensor_reading
>  };
>  static const IPMINetfn sensor_event_netfn = {
> -.cmd_nums = IPMI_NETFN_SENSOR_EVENT_MAXCMD,
> +.cmd_nums = ARRAY_SIZE(sensor_event_cmds),
>  .cmd_handlers = sensor_event_cmds
>  };
> 
> -static const IPMICmdHandler app_cmds[IPMI_NETFN_APP_MAXCMD] = {
> +static const IPMICmdHandler app_cmds[] = {
>  [IPMI_CMD_GET_DEVICE_ID] = get_device_id,
>  [IPMI_CMD_COLD_RESET] = cold_reset,
>  [IPMI_CMD_WARM_RESET] = warm_reset,
> @@ -1557,11 +1552,11 @@ static const IPMICmdHandler 
> app_cmds[IPMI_NETFN_APP_MAXCMD] = {
>  [IPMI_CMD_GET_WATCHDOG_TIMER] = get_watchdog_timer,
>  };
>  static const IPMINetfn app_netfn = {
> -.cmd_nums = IPMI_NETFN_APP_MAXCMD,
> +.cmd_nums = ARRAY_SIZE(app_cmds),
>  .cmd_handlers = app_cmds
>  };
> 
> -static const IPMICmdHandler storage_cmds[IPMI_NETFN_STORAGE_MAXCMD] = {
> +static const IPMICmdHandler storage_cmds[] = {
>  [IPMI_CMD_GET_SDR_REP_INFO] = get_sdr_rep_info,
>  [IPMI_CMD_RESERVE_SDR_REP] = reserve_sdr_rep,
>  [IPMI_CMD_GET_SDR] = get_sdr,
> @@ -1577,7 +1572,7 @@ static const IPMICmdHandler 
> storage_cmds[IPMI_NETFN_STORAGE_MAXCMD] = {
>  };
> 
>  static const IPMINetfn storage_netfn = {
> -.cmd_nums = IPMI_NETFN_STORAGE_MAXCMD,
> +.cmd_nums = ARRAY_SIZE(storage_cmds),
>  .cmd_handlers = storage_cmds
>  };
> 




[Qemu-devel] [PATCH RFC 4/7] net/filter: Introduce a helper to add a filter to the netdev

2016-01-22 Thread zhanghailiang
Signed-off-by: zhanghailiang 
---
 include/net/filter.h |  5 +
 net/filter.c | 63 
 2 files changed, 68 insertions(+)

diff --git a/include/net/filter.h b/include/net/filter.h
index d797ee4..c7bd8f9 100644
--- a/include/net/filter.h
+++ b/include/net/filter.h
@@ -81,4 +81,9 @@ static inline bool qemu_need_skip_netfilter(NetFilterState 
*nf)
 
 void netfilter_print_info(NetFilterState *nf, char *output_str, int size);
 
+void netdev_add_filter(const char *netdev_id,
+   const char *filter_type,
+   const char *id,
+   Error **errp);
+
 #endif /* QEMU_NET_FILTER_H */
diff --git a/net/filter.c b/net/filter.c
index f4933cc..4d96301 100644
--- a/net/filter.c
+++ b/net/filter.c
@@ -16,6 +16,10 @@
 #include "qom/object_interfaces.h"
 #include "qemu/iov.h"
 #include "qapi/string-output-visitor.h"
+#include "qapi/qmp/qdict.h"
+#include "qapi/qmp-output-visitor.h"
+#include "qapi/qmp-input-visitor.h"
+#include "monitor/monitor.h"
 
 ssize_t qemu_netfilter_receive(NetFilterState *nf,
NetFilterDirection direction,
@@ -232,6 +236,65 @@ static void netfilter_complete(UserCreatable *uc, Error 
**errp)
 QTAILQ_INSERT_TAIL(>netdev->filters, nf, next);
 }
 
+/*
+* This will be used by COLO or MC FT, for which they will need
+* to buffer the packets of VM's net devices, Here we add a default
+* buffer filter for each netdev. The name of default buffer filter is
+* 'nop'
+*/
+void netdev_add_filter(const char *netdev_id,
+   const char *filter_type,
+   const char *id,
+   Error **errp)
+{
+QmpOutputVisitor *qov;
+QmpInputVisitor *qiv;
+Visitor *ov, *iv;
+QObject *obj = NULL;
+QDict *qdict;
+void *dummy = NULL;
+NetClientState *nc = qemu_find_netdev(netdev_id);
+Error *err = NULL;
+
+/* FIXME: Not support multiple queues */
+if (!nc || nc->queue_index > 1) {
+return;
+}
+/* Not support vhost-net */
+if (get_vhost_net(nc)) {
+return;
+}
+
+qov = qmp_output_visitor_new();
+ov = qmp_output_get_visitor(qov);
+visit_start_struct(ov,  , NULL, NULL, 0, );
+if (err) {
+goto out;
+}
+visit_type_str(ov, >name, "netdev", );
+if (err) {
+goto out;
+}
+visit_end_struct(ov, );
+if (err) {
+goto out;
+}
+obj = qmp_output_get_qobject(qov);
+g_assert(obj != NULL);
+qdict = qobject_to_qdict(obj);
+qmp_output_visitor_cleanup(qov);
+
+qiv = qmp_input_visitor_new(obj);
+iv = qmp_input_get_visitor(qiv);
+object_add(filter_type, id, qdict, iv, );
+qmp_input_visitor_cleanup(qiv);
+qobject_decref(obj);
+out:
+if (err) {
+error_propagate(errp, err);
+}
+}
+
 static void netfilter_finalize(Object *obj)
 {
 NetFilterState *nf = NETFILTER(obj);
-- 
1.8.3.1





[Qemu-devel] [PATCH RFC 5/7] filter-buffer: Accept zero interval

2016-01-22 Thread zhanghailiang
We may want to accept zero interval when VM FT solutions like MC
or COLO use this filter to release packets on demand.

Signed-off-by: zhanghailiang 
Reviewed-by: Yang Hongyang 
---
 net/filter-buffer.c | 10 --
 1 file changed, 10 deletions(-)

diff --git a/net/filter-buffer.c b/net/filter-buffer.c
index 57be149..12e0c87 100644
--- a/net/filter-buffer.c
+++ b/net/filter-buffer.c
@@ -103,16 +103,6 @@ static void filter_buffer_setup(NetFilterState *nf, Error 
**errp)
 {
 FilterBufferState *s = FILTER_BUFFER(nf);
 
-/*
- * We may want to accept zero interval when VM FT solutions like MC
- * or COLO use this filter to release packets on demand.
- */
-if (!s->interval) {
-error_setg(errp, QERR_INVALID_PARAMETER_VALUE, "interval",
-   "a non-zero interval");
-return;
-}
-
 s->incoming_queue = qemu_new_net_queue(qemu_netfilter_pass_to_next, nf);
 if (s->interval) {
 timer_init_us(>release_timer, QEMU_CLOCK_VIRTUAL,
-- 
1.8.3.1





[Qemu-devel] [PATCH RFC 3/7] net/filter: Skip the disabled filter when delivering packets

2016-01-22 Thread zhanghailiang
If the filter is disabled, don't go through it.

Signed-off-by: zhanghailiang 
---
 include/net/filter.h | 5 +
 net/net.c| 4 
 2 files changed, 9 insertions(+)

diff --git a/include/net/filter.h b/include/net/filter.h
index 9ed5ec6..d797ee4 100644
--- a/include/net/filter.h
+++ b/include/net/filter.h
@@ -74,6 +74,11 @@ ssize_t qemu_netfilter_pass_to_next(NetClientState *sender,
 int iovcnt,
 void *opaque);
 
+static inline bool qemu_need_skip_netfilter(NetFilterState *nf)
+{
+return nf->enabled ? false : true;
+}
+
 void netfilter_print_info(NetFilterState *nf, char *output_str, int size);
 
 #endif /* QEMU_NET_FILTER_H */
diff --git a/net/net.c b/net/net.c
index 87de7c0..ec43105 100644
--- a/net/net.c
+++ b/net/net.c
@@ -581,6 +581,10 @@ static ssize_t filter_receive_iov(NetClientState *nc,
 NetFilterState *nf = NULL;
 
 QTAILQ_FOREACH(nf, >filters, next) {
+/* Don't go through filter if it is off */
+if (qemu_need_skip_netfilter(nf)) {
+continue;
+}
 ret = qemu_netfilter_receive(nf, direction, sender, flags, iov,
  iovcnt, sent_cb);
 if (ret) {
-- 
1.8.3.1





[Qemu-devel] [PATCH RFC 6/7] net/filter: Add a default filter to each netdev

2016-01-22 Thread zhanghailiang
We add each netdev a default buffer filter, which the name is
'nop', and the default buffer filter is disabled, so it has
no side effect for packets delivering in qemu net layer.

The default buffer filter can be used by COLO or Micro-checkpoint,
The reason we add the default filter is we hope to support
hot add network during COLO state in future.

Signed-off-by: zhanghailiang 
---
 include/net/filter.h | 11 +++
 net/dump.c   |  2 --
 net/filter.c | 15 ++-
 net/net.c| 18 ++
 4 files changed, 43 insertions(+), 3 deletions(-)

diff --git a/include/net/filter.h b/include/net/filter.h
index c7bd8f9..2043609 100644
--- a/include/net/filter.h
+++ b/include/net/filter.h
@@ -22,6 +22,16 @@
 #define NETFILTER_CLASS(klass) \
 OBJECT_CLASS_CHECK(NetFilterClass, (klass), TYPE_NETFILTER)
 
+#define DEFAULT_FILTER_NAME "nop"
+
+#define TYPE_FILTER_BUFFER "filter-buffer"
+#define TYPE_FILTER_DUMP "filter-dump"
+
+#define NETFILTER_ID_BUFFER 1
+#define NETFILTER_ID_DUMP 2
+
+extern const char *const netfilter_type_lookup[];
+
 typedef void (FilterSetup) (NetFilterState *nf, Error **errp);
 typedef void (FilterCleanup) (NetFilterState *nf);
 /*
@@ -55,6 +65,7 @@ struct NetFilterState {
 char *netdev_id;
 NetClientState *netdev;
 NetFilterDirection direction;
+bool is_default;
 bool enabled;
 QTAILQ_ENTRY(NetFilterState) next;
 };
diff --git a/net/dump.c b/net/dump.c
index 88d9582..82727a6 100644
--- a/net/dump.c
+++ b/net/dump.c
@@ -229,8 +229,6 @@ int net_init_dump(const NetClientOptions *opts, const char 
*name,
 
 /* Dumping via filter */
 
-#define TYPE_FILTER_DUMP "filter-dump"
-
 #define FILTER_DUMP(obj) \
 OBJECT_CHECK(NetFilterDumpState, (obj), TYPE_FILTER_DUMP)
 
diff --git a/net/filter.c b/net/filter.c
index 4d96301..a126a3b 100644
--- a/net/filter.c
+++ b/net/filter.c
@@ -21,6 +21,11 @@
 #include "qapi/qmp-input-visitor.h"
 #include "monitor/monitor.h"
 
+const char *const netfilter_type_lookup[] = {
+[NETFILTER_ID_BUFFER] = TYPE_FILTER_BUFFER,
+[NETFILTER_ID_DUMP] = TYPE_FILTER_DUMP,
+};
+
 ssize_t qemu_netfilter_receive(NetFilterState *nf,
NetFilterDirection direction,
NetClientState *sender,
@@ -200,7 +205,7 @@ static void netfilter_complete(UserCreatable *uc, Error 
**errp)
 NetFilterClass *nfc = NETFILTER_GET_CLASS(uc);
 int queues;
 Error *local_err = NULL;
-
+char *path = object_get_canonical_path_component(OBJECT(nf));
 
 if (!nf->netdev_id) {
 error_setg(errp, "Parameter 'netdev' is required");
@@ -225,6 +230,14 @@ static void netfilter_complete(UserCreatable *uc, Error 
**errp)
 }
 
 nf->netdev = ncs[0];
+nf->is_default = !strcmp(path, DEFAULT_FILTER_NAME);
+/*
+* For the default buffer filter, it will be disabled by default,
+* So it will not buffer any packets.
+*/
+if (nf->is_default) {
+nf->enabled = false;
+}
 
 if (nfc->setup) {
 nfc->setup(nf, _err);
diff --git a/net/net.c b/net/net.c
index ec43105..9630234 100644
--- a/net/net.c
+++ b/net/net.c
@@ -76,6 +76,12 @@ const char *host_net_devices[] = {
 
 int default_net = 1;
 
+/*
+ * FIXME: Export this with an option for users to control
+ * this with comand line ?
+ */
+int default_netfilter = NETFILTER_ID_BUFFER;
+
 /***/
 /* network device redirectors */
 
@@ -1032,6 +1038,18 @@ static int net_client_init1(const void *object, int 
is_netdev, Error **errp)
 }
 return -1;
 }
+
+if (is_netdev) {
+const Netdev *netdev = object;
+/*
+* Here we add each netdev a default filter whose name is 'nop',
+* it will disabled by default, Users can enable it when necessary.
+*/
+netdev_add_filter(netdev->id,
+  netfilter_type_lookup[default_netfilter],
+  DEFAULT_FILTER_NAME,
+  errp);
+}
 return 0;
 }
 
-- 
1.8.3.1





Re: [Qemu-devel] [PATCH RFC 0/7] Netfilter: Add each netdev a default filter

2016-01-22 Thread Hailiang Zhang

Cc: Dr. David Alan Gilbert 

On 2016/1/22 16:36, zhanghailiang wrote:

This series is a prerequisite for COLO, here we add each netdev
a default buffer filter, it is disabled by default, and has
no side effect for delivering packets in net layer.

Besides, patch 1 fixes the ouput information of 'info network' command
for filter.

zhanghailiang (7):
   net/filter: Fix the output information for command 'info network'
   net/filter: Add a 'status' property for filter object
   net/filter: Skip the disabled filter when delivering packets
   net/filter: Introduce a helper to add a filter to the netdev
   filter-buffer: Accept zero interval
   net/filter: Add a default filter to each netdev
   net/filter: prevent the default filter to be deleted

  include/net/filter.h |  25 +++-
  net/dump.c   |   2 -
  net/filter-buffer.c  |  10 
  net/filter.c | 163 +--
  net/net.c|  27 -
  5 files changed, 194 insertions(+), 33 deletions(-)







Re: [Qemu-devel] [PATCH 2/8] qmp: create qmp_savevm command

2016-01-22 Thread Denis V. Lunev

On 01/19/2016 09:11 PM, Markus Armbruster wrote:

"Denis V. Lunev"  writes:


On 01/18/2016 06:58 PM, Markus Armbruster wrote:

"Denis V. Lunev"  writes:


'name' attribute is made mandatory in distinction with HMP command.

The patch also moves hmp_savevm implementation into hmp.c. This function
is just a simple wrapper now and does not have knowledge about
migration internals.

[...]

diff --git a/qapi-schema.json b/qapi-schema.json
index 2e31733..09d1a1a 100644
--- a/qapi-schema.json
+++ b/qapi-schema.json
@@ -4054,3 +4054,16 @@
   ##
   { 'enum': 'ReplayMode',
 'data': [ 'none', 'record', 'play' ] }
+
+##
+# @savevm
+#
+# Save a VM snapshot. Old snapshot with the same name will be deleted if 
exists.
+#
+# @name: identifier of a snapshot to be created
+#
+# Returns: Nothing on success
+#
+# Since 2.6
+##
+{ 'command': 'savevm', 'data': {'name': 'str'} }
diff --git a/qmp-commands.hx b/qmp-commands.hx
index db072a6..b7851e1 100644
--- a/qmp-commands.hx
+++ b/qmp-commands.hx
@@ -4795,3 +4795,28 @@ Example:
{"type": 0, "out-pport": 0, "pport": 0, "vlan-id": 3840,
 "pop-vlan": 1, "id": 251658240}
  ]}
+
+EQMP
+
+SQMP
+savevm
+--
+
+Save a VM snapshot. Old snapshot with the same name will be deleted if exists.
+
+Arguments:
+
+- "name": snapshot name
+
+Example:
+
+-> { "execute": "savevm", "arguments": { "name": "snapshot1" } }
+<- { "return": {} }
+
+EQMP
+
+{
+.name   = "savevm",
+.args_type  = "name:s",
+.mhandler.cmd_new = qmp_marshal_savevm,
+},

A snapshot has a tag (QEMUSnapshotInfo member name) and an ID
(QEMUSnapshotInfo member id_str).

HMP's name arguments are overloaded: they're matched both against tag
and ID.  Unwisely chosen tags can create ambiguity.  Example:

  (qemu) savevm 2
  (qemu) savevm
  (qemu) info snapshots
  IDTAG VM SIZEDATE   VM CLOCK
  1 2  1.7M 2016-01-18 16:56:31   00:00:00.000
  2 vm-20160118165641  1.7M 2016-01-18 16:56:41   00:00:00.000

Care to guess which one we get when we ask for "2"?

I think we want separate, unoverloaded arguments for QMP.

I think there is no need to. Name is now absolutely mandatory.
Thus for new snapshots we will have 'name' specified and we
will be bound to name only.

'id' will be used for old VMs and this is convenience
layer to make old 'id' only snaphosts accessible
through new interface in the same way as old.

The overloaded interface you propose is more complex than it seems.  You
hide the complexity by not documenting its workings.  Not even to the
(insufficient!) degree the HMP interface documents how its overloaded
name parameters work.

Merely copying over the HMP documentation won't cut it.  The bar for new
QMP interfaces is a fair bit higher than "no worse than HMP".  The new
interface must reasonably sane for *QMP*, and sufficiently documented.

If we can't make a sane QMP interface, I'd rather have no QMP interface.
However, I believe we *can* make a sane QMP interface if we put in the
design work.

The design work must start with a review of what we're trying to
accomplish, and how to fit it into the rest of the system.  Here's my
attempt.  Since my knowledge on snapshots is rather superficial, I'm
cc'ing Kevin for additional snapshot expertise.  Kevin, please correct
me when I talk nonsense.  I'm further cc'ing Eric and Peter for the
management layer perspective.

A point-in-time snapshot of a system consists of a snapshot of its
machine state and snapshots of its storage.  All the snapshots need to
be made at the same point in time for the result to be consistent.

Snapshots of read-only storage carry no information and are commonly
omitted.

Isolated storage snapshots can make sense, but snapshotting the machine
state without also snapshotting the machine's storage doesn't sound
useful to me.

Both storage and machine state snapshots come in two flavours: internal
and external.

External ones can be made with any block backend, but internal storage
snapshots work only with certain formats, notably qcow2.  QMP supports
both kinds of storage snapshots.

Both kinds of storage snapshots need exclusive access while they work.
They're relatively quick, but the delay could be noticable for large
internal snapshots, and perhaps for external snapshots on really slow
storage.

Internal machine state snapshots are currently only available via HMP's
savevm, which integrates internal machine state and storage snapshots.
This is non-live, i.e. the guest is stopped while the snapshot gets
saved.  I figure we could make it live if we really wanted to.  Another
instance of the emerging background job concept.

On the implementation level, QCOW2 can't currently store a machine state
snapshot without also storing a storage snapshot.  I guess we could
change this if we really wanted to.

External machine state 

[Qemu-devel] [PATCH] net: walk through filters reversely if traffic is outgress

2016-01-22 Thread Li Zhijian
Previously, if the netdev has more than one filters, the ingress
or outgress traffic pass the filter in the same order. this patch
is to make the outgress pass the filter in a reverse order

Signed-off-by: Wen Congyang 
Signed-off-by: Li Zhijian 
---
 include/net/net.h |  4 +++-
 net/filter.c  | 21 +++--
 net/net.c | 23 ++-
 3 files changed, 40 insertions(+), 8 deletions(-)

diff --git a/include/net/net.h b/include/net/net.h
index 7af3e15..1d807cc 100644
--- a/include/net/net.h
+++ b/include/net/net.h
@@ -79,6 +79,8 @@ typedef struct NetClientInfo {
 SetVnetBE *set_vnet_be;
 } NetClientInfo;
 
+QTAILQ_HEAD(NetFilterHead, NetFilterState);
+
 struct NetClientState {
 NetClientInfo *info;
 int link_down;
@@ -92,7 +94,7 @@ struct NetClientState {
 NetClientDestructor *destructor;
 unsigned int queue_index;
 unsigned rxfilter_notify_enabled:1;
-QTAILQ_HEAD(, NetFilterState) filters;
+struct NetFilterHead filters;
 };
 
 typedef struct NICState {
diff --git a/net/filter.c b/net/filter.c
index 5d90f83..17a8398 100644
--- a/net/filter.c
+++ b/net/filter.c
@@ -34,6 +34,22 @@ ssize_t qemu_netfilter_receive(NetFilterState *nf,
 return 0;
 }
 
+static NetFilterState *netfilter_next(NetFilterState *nf,
+  NetFilterDirection dir)
+{
+NetFilterState *next;
+
+if (dir == NET_FILTER_DIRECTION_TX) {
+/* forward walk through filters */
+next = QTAILQ_NEXT(nf, next);
+} else {
+/* reverse order */
+next = QTAILQ_PREV(nf, NetFilterHead, next);
+}
+
+return next;
+}
+
 ssize_t qemu_netfilter_pass_to_next(NetClientState *sender,
 unsigned flags,
 const struct iovec *iov,
@@ -43,7 +59,7 @@ ssize_t qemu_netfilter_pass_to_next(NetClientState *sender,
 int ret = 0;
 int direction;
 NetFilterState *nf = opaque;
-NetFilterState *next = QTAILQ_NEXT(nf, next);
+NetFilterState *next = NULL;
 
 if (!sender || !sender->peer) {
 /* no receiver, or sender been deleted, no need to pass it further */
@@ -61,6 +77,7 @@ ssize_t qemu_netfilter_pass_to_next(NetClientState *sender,
 direction = nf->direction;
 }
 
+next = netfilter_next(nf, direction);
 while (next) {
 /*
  * if qemu_netfilter_pass_to_next been called, means that
@@ -73,7 +90,7 @@ ssize_t qemu_netfilter_pass_to_next(NetClientState *sender,
 if (ret) {
 return ret;
 }
-next = QTAILQ_NEXT(next, next);
+next = netfilter_next(next, direction);
 }
 
 /*
diff --git a/net/net.c b/net/net.c
index 87dd356..05ec996 100644
--- a/net/net.c
+++ b/net/net.c
@@ -580,11 +580,24 @@ static ssize_t filter_receive_iov(NetClientState *nc,
 ssize_t ret = 0;
 NetFilterState *nf = NULL;
 
-QTAILQ_FOREACH(nf, >filters, next) {
-ret = qemu_netfilter_receive(nf, direction, sender, flags, iov,
- iovcnt, sent_cb);
-if (ret) {
-return ret;
+assert(direction == NET_FILTER_DIRECTION_TX ||
+   direction == NET_FILTER_DIRECTION_RX);
+
+if (direction == NET_FILTER_DIRECTION_TX) {
+QTAILQ_FOREACH(nf, >filters, next) {
+ret = qemu_netfilter_receive(nf, direction, sender, flags, iov,
+ iovcnt, sent_cb);
+if (ret) {
+return ret;
+}
+}
+} else {
+QTAILQ_FOREACH_REVERSE(nf, >filters, NetFilterHead, next) {
+ret = qemu_netfilter_receive(nf, direction, sender, flags, iov,
+ iovcnt, sent_cb);
+if (ret) {
+return ret;
+}
 }
 }
 
-- 
2.5.0






[Qemu-devel] [PATCH RFC 2/7] net/filter: Add a 'status' property for filter object

2016-01-22 Thread zhanghailiang
With this property, users can control if this filter is 'enable'
or 'disable'. The default behavior for filter is enabled.

Signed-off-by: zhanghailiang 
---
 include/net/filter.h |  1 +
 net/filter.c | 36 
 2 files changed, 37 insertions(+)

diff --git a/include/net/filter.h b/include/net/filter.h
index 8a20138..9ed5ec6 100644
--- a/include/net/filter.h
+++ b/include/net/filter.h
@@ -55,6 +55,7 @@ struct NetFilterState {
 char *netdev_id;
 NetClientState *netdev;
 NetFilterDirection direction;
+bool enabled;
 QTAILQ_ENTRY(NetFilterState) next;
 };
 
diff --git a/net/filter.c b/net/filter.c
index 40254bd..f4933cc 100644
--- a/net/filter.c
+++ b/net/filter.c
@@ -117,8 +117,41 @@ static void netfilter_set_direction(Object *obj, int 
direction, Error **errp)
 nf->direction = direction;
 }
 
+static char *netfilter_get_status(Object *obj, Error **errp)
+{
+NetFilterState *nf = NETFILTER(obj);
+
+if (nf->enabled) {
+return g_strdup("enable");
+} else {
+return g_strdup("disable");
+}
+}
+
+static void netfilter_set_status(Object *obj, const char *str, Error **errp)
+{
+NetFilterState *nf = NETFILTER(obj);
+
+if (!strcmp(str, "enable")) {
+nf->enabled = true;
+} else if (!strcmp(str, "disable")) {
+nf->enabled = false;
+} else {
+error_setg(errp, "Invalid value for netfilter status, "
+ "should be 'enable' or 'disable'");
+}
+}
+
 static void netfilter_init(Object *obj)
 {
+NetFilterState *nf = NETFILTER(obj);
+
+/*
+* If not configured with 'status' property, the default status
+* for netfilter will be enabled.
+*/
+nf->enabled = true;
+
 object_property_add_str(obj, "netdev",
 netfilter_get_netdev_id, netfilter_set_netdev_id,
 NULL);
@@ -126,6 +159,9 @@ static void netfilter_init(Object *obj)
  NetFilterDirection_lookup,
  netfilter_get_direction, netfilter_set_direction,
  NULL);
+object_property_add_str(obj, "status",
+netfilter_get_status, netfilter_set_status,
+NULL);
 }
 
 void netfilter_print_info(NetFilterState *nf, char *output_str, int size)
-- 
1.8.3.1





[Qemu-devel] [PATCH RFC 1/7] net/filter: Fix the output information for command 'info network'

2016-01-22 Thread zhanghailiang
The properties of netfilter object could be changed by 'qom-set'
command, but the output of 'info network' command is not updated,
because it got the old information through nf->info_str, it will
not be updated while we change the value of netfilter's property.

Here we split a the helper function that could colletct the output
information for filter, and also remove the useless member
'info_str' from struct NetFilterState.

Signed-off-by: zhanghailiang 
---
 include/net/filter.h |  3 ++-
 net/filter.c | 47 ++-
 net/net.c|  5 -
 3 files changed, 32 insertions(+), 23 deletions(-)

diff --git a/include/net/filter.h b/include/net/filter.h
index 2deda36..8a20138 100644
--- a/include/net/filter.h
+++ b/include/net/filter.h
@@ -55,7 +55,6 @@ struct NetFilterState {
 char *netdev_id;
 NetClientState *netdev;
 NetFilterDirection direction;
-char info_str[256];
 QTAILQ_ENTRY(NetFilterState) next;
 };
 
@@ -74,4 +73,6 @@ ssize_t qemu_netfilter_pass_to_next(NetClientState *sender,
 int iovcnt,
 void *opaque);
 
+void netfilter_print_info(NetFilterState *nf, char *output_str, int size);
+
 #endif /* QEMU_NET_FILTER_H */
diff --git a/net/filter.c b/net/filter.c
index 5d90f83..40254bd 100644
--- a/net/filter.c
+++ b/net/filter.c
@@ -128,6 +128,31 @@ static void netfilter_init(Object *obj)
  NULL);
 }
 
+void netfilter_print_info(NetFilterState *nf, char *output_str, int size)
+{
+char *str, *info;
+ObjectProperty *prop;
+ObjectPropertyIterator iter;
+StringOutputVisitor *ov;
+
+/* generate info str */
+object_property_iter_init(, OBJECT(nf));
+while ((prop = object_property_iter_next())) {
+if (!strcmp(prop->name, "type")) {
+continue;
+}
+ov = string_output_visitor_new(false);
+object_property_get(OBJECT(nf), string_output_get_visitor(ov),
+prop->name, NULL);
+str = string_output_get_string(ov);
+string_output_visitor_cleanup(ov);
+info = g_strdup_printf(",%s=%s", prop->name, str);
+g_strlcat(output_str, info, size);
+g_free(str);
+g_free(info);
+}
+}
+
 static void netfilter_complete(UserCreatable *uc, Error **errp)
 {
 NetFilterState *nf = NETFILTER(uc);
@@ -135,10 +160,7 @@ static void netfilter_complete(UserCreatable *uc, Error 
**errp)
 NetFilterClass *nfc = NETFILTER_GET_CLASS(uc);
 int queues;
 Error *local_err = NULL;
-char *str, *info;
-ObjectProperty *prop;
-ObjectPropertyIterator iter;
-StringOutputVisitor *ov;
+
 
 if (!nf->netdev_id) {
 error_setg(errp, "Parameter 'netdev' is required");
@@ -172,23 +194,6 @@ static void netfilter_complete(UserCreatable *uc, Error 
**errp)
 }
 }
 QTAILQ_INSERT_TAIL(>netdev->filters, nf, next);
-
-/* generate info str */
-object_property_iter_init(, OBJECT(nf));
-while ((prop = object_property_iter_next())) {
-if (!strcmp(prop->name, "type")) {
-continue;
-}
-ov = string_output_visitor_new(false);
-object_property_get(OBJECT(nf), string_output_get_visitor(ov),
-prop->name, errp);
-str = string_output_get_string(ov);
-string_output_visitor_cleanup(ov);
-info = g_strdup_printf(",%s=%s", prop->name, str);
-g_strlcat(nf->info_str, info, sizeof(nf->info_str));
-g_free(str);
-g_free(info);
-}
 }
 
 static void netfilter_finalize(Object *obj)
diff --git a/net/net.c b/net/net.c
index 87dd356..87de7c0 100644
--- a/net/net.c
+++ b/net/net.c
@@ -1198,9 +1198,12 @@ void print_net_client(Monitor *mon, NetClientState *nc)
 }
 QTAILQ_FOREACH(nf, >filters, next) {
 char *path = object_get_canonical_path_component(OBJECT(nf));
+char info[256] = { 0 };
+
+netfilter_print_info(nf, info, sizeof(info));
 monitor_printf(mon, "  - %s: type=%s%s\n", path,
object_get_typename(OBJECT(nf)),
-   nf->info_str);
+   info);
 g_free(path);
 }
 }
-- 
1.8.3.1





[Qemu-devel] [PATCH RFC 7/7] net/filter: prevent the default filter to be deleted

2016-01-22 Thread zhanghailiang
Signed-off-by: zhanghailiang 
---
 net/filter.c | 8 
 1 file changed, 8 insertions(+)

diff --git a/net/filter.c b/net/filter.c
index a126a3b..4aafff0 100644
--- a/net/filter.c
+++ b/net/filter.c
@@ -323,11 +323,19 @@ static void netfilter_finalize(Object *obj)
 g_free(nf->netdev_id);
 }
 
+static bool netfilter_can_be_deleted(UserCreatable *uc, Error **errp)
+{
+NetFilterState *nf = NETFILTER(uc);
+/* Forbid the default filter to be deleted */
+return !nf->is_default;
+}
+
 static void netfilter_class_init(ObjectClass *oc, void *data)
 {
 UserCreatableClass *ucc = USER_CREATABLE_CLASS(oc);
 
 ucc->complete = netfilter_complete;
+ucc->can_be_deleted = netfilter_can_be_deleted;
 }
 
 static const TypeInfo netfilter_info = {
-- 
1.8.3.1





[Qemu-devel] [PATCH RFC 0/7] Netfilter: Add each netdev a default filter

2016-01-22 Thread zhanghailiang
This series is a prerequisite for COLO, here we add each netdev
a default buffer filter, it is disabled by default, and has
no side effect for delivering packets in net layer.

Besides, patch 1 fixes the ouput information of 'info network' command
for filter.

zhanghailiang (7):
  net/filter: Fix the output information for command 'info network'
  net/filter: Add a 'status' property for filter object
  net/filter: Skip the disabled filter when delivering packets
  net/filter: Introduce a helper to add a filter to the netdev
  filter-buffer: Accept zero interval
  net/filter: Add a default filter to each netdev
  net/filter: prevent the default filter to be deleted

 include/net/filter.h |  25 +++-
 net/dump.c   |   2 -
 net/filter-buffer.c  |  10 
 net/filter.c | 163 +--
 net/net.c|  27 -
 5 files changed, 194 insertions(+), 33 deletions(-)

-- 
1.8.3.1





Re: [Qemu-devel] [PATCH 0/6] Some improvements and small fixes for migration

2016-01-22 Thread Hailiang Zhang

ping ?

On 2016/1/15 11:37, zhanghailiang wrote:

Patch 1 ~ patch 4 are picked from COLO and live memory snapshot series,
They are just small improvements for migration codes and have been reviewed
by Dave.

Patch 5, 6 are small fixes for migration releated documention.

Please review.

zhanghailiang (6):
   ram: Split host_from_stream_offset() into two helper functions
   migration: Rename the'file' member of MigrationState
   savevm: Split load vm state function qemu_loadvm_state
   migration/ram: Fix some helper functions' parameter to use
 PageSearchStatus
   qmp-commands.hx: Fix the missing options for migration parameters
 commands
   qmp-commands.hx: Document the missing options for migration capability
 commands

  include/exec/ram_addr.h   |   8 ++-
  include/migration/migration.h |   2 +-
  migration/exec.c  |   4 +-
  migration/fd.c|   4 +-
  migration/migration.c |  72 +--
  migration/postcopy-ram.c  |   6 +-
  migration/ram.c   |  73 +++
  migration/rdma.c  |   2 +-
  migration/savevm.c| 158 +-
  migration/tcp.c   |   4 +-
  migration/unix.c  |   4 +-
  qmp-commands.hx   |  33 +++--
  12 files changed, 222 insertions(+), 148 deletions(-)







Re: [Qemu-devel] [PULL 10/11] Add Error **errp for xen_pt_config_init()

2016-01-22 Thread Paolo Bonzini


On 21/01/2016 18:01, Stefano Stabellini wrote:
> -XEN_PT_LOG(>dev, "Failed to initialize %d/%ld reg 
> 0x%x in grp_type=0x%x (%d/%ld), rc=%d\n",
> -   j, 
> ARRAY_SIZE(xen_pt_emu_reg_grps[i].emu_regs),
> -   regs->offset, 
> xen_pt_emu_reg_grps[i].grp_type,
> -   i, ARRAY_SIZE(xen_pt_emu_reg_grps), rc);
> +xen_pt_config_reg_init(s, reg_grp_entry, regs, );
> +if (err) {
> +error_append_hint(, "Failed to initialize %d/%zu"
> +" reg 0x%x in grp_type = 0x%x (%d/%zu)",
> +j, 
> ARRAY_SIZE(xen_pt_emu_reg_grps[i].emu_regs),

Coverity noticed a preexisting problem here.  emu_regs is a pointer,
thus ARRAY_SIZE doesn't return what you expect.

Paolo

> +regs->offset, 
> xen_pt_emu_reg_grps[i].grp_type,
> +i, ARRAY_SIZE(xen_pt_emu_reg_grps));
> +error_propagate(errp, err);



Re: [Qemu-devel] [PATCH v2 9/9] ipmi: add SET_SENSOR_READING command (tentative try)

2016-01-22 Thread Greg Kurz
On Thu, 21 Jan 2016 18:18:54 +0100
Cédric Le Goater  wrote:

> SET_SENSOR_READING is a complex IPMI command (IPMI spec : "35.17 Set
> Sensor Reading And Event Status Command"). Here is a very minimum
> framework fitting the Open PowerNV platform needs. This command is
> used on this platform to set the "System Firmware Progress" sensor and
> the "Boot Count" sensor.
> 
> Signed-off-by: Cédric Le Goater 
> Acked-by: Corey Minyard 
> ---

Reviewed-by: Greg Kurz 

Just one "parenthesitis" attack...

>  hw/ipmi/ipmi_bmc_sim.c | 135 
> +
>  1 file changed, 135 insertions(+)
> 
> diff --git a/hw/ipmi/ipmi_bmc_sim.c b/hw/ipmi/ipmi_bmc_sim.c
> index 53c75cb21c1a..0aa7e67ae217 100644
> --- a/hw/ipmi/ipmi_bmc_sim.c
> +++ b/hw/ipmi/ipmi_bmc_sim.c
> @@ -46,6 +46,7 @@
>  #define IPMI_CMD_GET_SENSOR_READING   0x2d
>  #define IPMI_CMD_SET_SENSOR_TYPE  0x2e
>  #define IPMI_CMD_GET_SENSOR_TYPE  0x2f
> +#define IPMI_CMD_SET_SENSOR_READING   0x30
> 
>  /* #define IPMI_NETFN_APP 0x06 In ipmi.h */
> 
> @@ -1616,6 +1617,139 @@ static void get_sensor_type(IPMIBmcSim *ibs,
>  IPMI_ADD_RSP_DATA(sens->evt_reading_type_code);
>  }
> 
> +static void set_sensor_reading(IPMIBmcSim *ibs,
> +   uint8_t *cmd, unsigned int cmd_len,
> +   uint8_t *rsp, unsigned int *rsp_len,
> +   unsigned int max_rsp_len)
> +{
> +IPMISensor *sens;
> +uint8_t evd1;
> +uint8_t evd2;
> +uint8_t evd3;
> +
> +IPMI_CHECK_CMD_LEN(5);
> +if ((cmd[2] > MAX_SENSORS) ||

Here ! :)

> +!IPMI_SENSOR_GET_PRESENT(ibs->sensors + cmd[2])) {
> +rsp[2] = IPMI_CC_REQ_ENTRY_NOT_PRESENT;
> +return;
> +}
> +
> +sens = ibs->sensors + cmd[2];
> +
> +/* Sensor Reading operation */
> +switch ((cmd[3]) & 0x3) {
> +case 0: /* Do not change */
> +break;
> +case 1: /* write given value to sensor reading byte */
> +sens->reading = cmd[4];
> +break;
> +case 2:
> +case 3:
> +rsp[2] = IPMI_CC_INVALID_DATA_FIELD;
> +return;
> +}
> +
> +/* Deassertion bits operation */
> +switch ((cmd[3] >> 2) & 0x3) {
> +case 0: /* Do not change */
> +break;
> +case 1: /* write given value */
> +if (cmd_len > 7) {
> +sens->deassert_states = cmd[7];
> +}
> +if (cmd_len > 8) {
> +sens->deassert_states = cmd[8] << 8;
> +}
> +
> +case 2: /* mask on */
> +if (cmd_len > 7) {
> +sens->deassert_states |= cmd[7];
> +}
> +if (cmd_len > 8) {
> +sens->deassert_states |= cmd[8] << 8;
> +}
> +break;
> +case 3: /* mask off */
> +if (cmd_len > 7) {
> +sens->deassert_states &= cmd[7];
> +}
> +if (cmd_len > 8) {
> +sens->deassert_states &= (cmd[8] << 8);
> +}
> +break;
> +}
> +
> +/* Assertion bits operation */
> +switch ((cmd[3] >> 4) & 0x3) {
> +case 0: /* Do not change */
> +break;
> +case 1: /* write given value */
> +if (cmd_len > 5) {
> +sens->assert_states = cmd[5];
> +}
> +if (cmd_len > 6) {
> +sens->assert_states = cmd[6] << 8;
> +}
> +
> +case 2: /* mask on */
> +if (cmd_len > 5) {
> +sens->assert_states |= cmd[5];
> +}
> +if (cmd_len > 6) {
> +sens->assert_states |= cmd[6] << 8;
> +}
> +break;
> +case 3: /* mask off */
> +if (cmd_len > 5) {
> +sens->assert_states &= cmd[5];
> +}
> +if (cmd_len > 6) {
> +sens->assert_states &= (cmd[6] << 8);
> +}
> +break;
> +}
> +
> +evd1 = evd2 = evd3 = 0x0;
> +if (cmd_len > 9) {
> +evd1 = cmd[9];
> +}
> +if (cmd_len > 10) {
> +evd2 = cmd[10];
> +}
> +if (cmd_len > 11) {
> +evd3 = cmd[11];
> +}
> +
> +/* Event Data Bytes operation */
> +switch ((cmd[3] >> 6) & 0x3) {
> +case 0: /* Do not use the event data in message */
> +evd1 = evd2 = evd3 = 0x0;
> +break;
> +case 1: /* Write given values to event data bytes excluding bits
> + * [3:0] Event Data 1. */
> +evd1 &= 0xf0;
> +break;
> +case 2: /* Write given values to event data bytes including bits
> + * [3:0] Event Data 1. */
> +break;
> +case 3:
> +rsp[2] = IPMI_CC_INVALID_DATA_FIELD;
> +return;
> +}
> +
> +if (IPMI_SENSOR_IS_DISCRETE(sens)) {
> +unsigned int bit = evd1 & 0xf;
> +uint16_t mask = (1 << bit);
> +
> +if (sens->assert_states & mask & sens->assert_enable) {
> +gen_event(ibs, cmd[2], 0, evd1, evd2, evd3);
> +}

Re: [Qemu-devel] [PATCH v2 08/13] block: Support meta dirty bitmap

2016-01-22 Thread Vladimir Sementsov-Ogievskiy

On 20.01.2016 09:11, Fam Zheng wrote:

The added group of operations enables tracking of the changed bits in
the dirty bitmap.

Signed-off-by: Fam Zheng 
---
  block/dirty-bitmap.c | 51 
  include/block/dirty-bitmap.h |  9 
  2 files changed, 60 insertions(+)

diff --git a/block/dirty-bitmap.c b/block/dirty-bitmap.c
index bd7758b..d75dcf7 100644
--- a/block/dirty-bitmap.c
+++ b/block/dirty-bitmap.c
@@ -37,6 +37,7 @@
   */
  struct BdrvDirtyBitmap {
  HBitmap *bitmap;/* Dirty sector bitmap implementation */
+HBitmap *meta;  /* Meta dirty bitmap */
  BdrvDirtyBitmap *successor; /* Anonymous child; implies frozen status */
  char *name; /* Optional non-empty unique ID */
  int64_t size;   /* Size of the bitmap (Number of sectors) */
@@ -102,6 +103,56 @@ BdrvDirtyBitmap *bdrv_create_dirty_bitmap(BlockDriverState 
*bs,
  return bitmap;
  }
  
+/* bdrv_create_meta_dirty_bitmap

+ *
+ * Create a meta dirty bitmap that tracks the changes of bits in @bitmap. I.e.
+ * when a dirty status bit in @bitmap is changed (either from reset to set or
+ * the other way around), its respective meta dirty bitmap bit will be marked
+ * dirty as well.
+ *
+ * @bitmap: the block dirty bitmap for which to create a meta dirty bitmap.
+ * @granularity: how many bytes of bitmap data does each bit in the meta bitmap
+ * track.
+ */
+void bdrv_create_meta_dirty_bitmap(BdrvDirtyBitmap *bitmap,
+   int granularity)
+{
+assert(!bitmap->meta);
+bitmap->meta = hbitmap_create_meta(bitmap->bitmap,
+   BDRV_SECTOR_SIZE * BITS_PER_BYTE);
+}
+
+void bdrv_release_meta_dirty_bitmap(BdrvDirtyBitmap *bitmap)
+{
+assert(bitmap->meta);
+hbitmap_free_meta(bitmap->bitmap);
+bitmap->meta = NULL;
+}
+
+int bdrv_dirty_bitmap_get_meta(BlockDriverState *bs,
+   BdrvDirtyBitmap *bitmap, int64_t sector,
+   int nb_sectors)
+{
+uint64_t i;
+int gran = bdrv_dirty_bitmap_granularity(bitmap) >> BDRV_SECTOR_BITS;
+
+/* To optimize: we can make hbitmap to internally check the range in a
+ * coarse level, or at least do it word by word. */
+for (i = sector; i < sector + nb_sectors; i += gran) {
+if (hbitmap_get(bitmap->meta, i)) {
+return true;
+}
+}
+return false;
+}
+
+void bdrv_dirty_bitmap_reset_meta(BlockDriverState *bs,
+  BdrvDirtyBitmap *bitmap, int64_t sector,
+  int nb_sectors)
+{
+hbitmap_reset(bitmap->meta, sector, nb_sectors);
+}
+
  bool bdrv_dirty_bitmap_frozen(BdrvDirtyBitmap *bitmap)
  {
  return bitmap->successor;
diff --git a/include/block/dirty-bitmap.h b/include/block/dirty-bitmap.h
index 120bac6..d9b281a 100644
--- a/include/block/dirty-bitmap.h
+++ b/include/block/dirty-bitmap.h
@@ -9,6 +9,9 @@ BdrvDirtyBitmap *bdrv_create_dirty_bitmap(BlockDriverState *bs,
uint32_t granularity,
const char *name,
Error **errp);
+void bdrv_create_meta_dirty_bitmap(BdrvDirtyBitmap *bitmap,
+   int granularity);
+void bdrv_release_meta_dirty_bitmap(BdrvDirtyBitmap *bitmap);
  int bdrv_dirty_bitmap_create_successor(BlockDriverState *bs,
 BdrvDirtyBitmap *bitmap,
 Error **errp);
@@ -35,6 +38,12 @@ void bdrv_set_dirty_bitmap(BdrvDirtyBitmap *bitmap,
 int64_t cur_sector, int nr_sectors);
  void bdrv_reset_dirty_bitmap(BdrvDirtyBitmap *bitmap,
   int64_t cur_sector, int nr_sectors);
+int bdrv_dirty_bitmap_get_meta(BlockDriverState *bs,
+   BdrvDirtyBitmap *bitmap, int64_t sector,
+   int nb_sectors);
+void bdrv_dirty_bitmap_reset_meta(BlockDriverState *bs,
+  BdrvDirtyBitmap *bitmap, int64_t sector,
+  int nb_sectors);
  BdrvDirtyBitmapIter *bdrv_dirty_iter_new(BdrvDirtyBitmap *bitmap,
   uint64_t first_sector);
  void bdrv_dirty_iter_free(BdrvDirtyBitmapIter *iter);


In my migration series I need iterators, get granularity, and something 
like hbitmap_count  for meta bitmaps. You can add them here if you want, 
or I can add them in my series.


--
Best regards,
Vladimir
* now, @virtuozzo.com instead of @parallels.com. Sorry for this inconvenience.




[Qemu-devel] [PATCH 2/6] scripts/dump-guest-memory.py: Make methods functions

2016-01-22 Thread Janosch Frank
The functions dealing with qemu components rarely used parts of the
class, so they were moved out of the class.

As the uintptr_t variable is needed both within and outside the class,
it was made a constant and moved to the top.

Reviewed-by: Laszlo Ersek 
Signed-off-by: Janosch Frank 
---
 scripts/dump-guest-memory.py | 184 ++-
 1 file changed, 93 insertions(+), 91 deletions(-)

diff --git a/scripts/dump-guest-memory.py b/scripts/dump-guest-memory.py
index e49c835..d0b927a 100644
--- a/scripts/dump-guest-memory.py
+++ b/scripts/dump-guest-memory.py
@@ -17,6 +17,8 @@
 
 import struct
 
+UINTPTR_T = gdb.lookup_type("uintptr_t")
+
 TARGET_PAGE_SIZE = 0x1000
 TARGET_PAGE_MASK = 0xF000
 
@@ -66,6 +68,94 @@ ELF64_PHDR = ("I"  # p_type
   "Q"  # p_align
   )
 
+def int128_get64(val):
+assert (val["hi"] == 0)
+return val["lo"]
+
+def qlist_foreach(head, field_str):
+var_p = head["lh_first"]
+while (var_p != 0):
+var = var_p.dereference()
+yield var
+var_p = var[field_str]["le_next"]
+
+def qemu_get_ram_block(ram_addr):
+ram_blocks = gdb.parse_and_eval("ram_list.blocks")
+for block in qlist_foreach(ram_blocks, "next"):
+if (ram_addr - block["offset"] < block["used_length"]):
+return block
+raise gdb.GdbError("Bad ram offset %x" % ram_addr)
+
+def qemu_get_ram_ptr(ram_addr):
+block = qemu_get_ram_block(ram_addr)
+return block["host"] + (ram_addr - block["offset"])
+
+def memory_region_get_ram_ptr(mr):
+if (mr["alias"] != 0):
+return (memory_region_get_ram_ptr(mr["alias"].dereference()) +
+mr["alias_offset"])
+return qemu_get_ram_ptr(mr["ram_addr"] & TARGET_PAGE_MASK)
+
+def get_guest_phys_blocks():
+guest_phys_blocks = []
+print "guest RAM blocks:"
+print ("target_start target_end   host_addrmessage "
+   "count")
+print ("   --- "
+   "-")
+
+current_map_p = gdb.parse_and_eval("address_space_memory.current_map")
+current_map = current_map_p.dereference()
+for cur in range(current_map["nr"]):
+flat_range   = (current_map["ranges"] + cur).dereference()
+mr   = flat_range["mr"].dereference()
+
+# we only care about RAM
+if (not mr["ram"]):
+continue
+
+section_size = int128_get64(flat_range["addr"]["size"])
+target_start = int128_get64(flat_range["addr"]["start"])
+target_end   = target_start + section_size
+host_addr= (memory_region_get_ram_ptr(mr) +
+flat_range["offset_in_region"])
+predecessor = None
+
+# find continuity in guest physical address space
+if (len(guest_phys_blocks) > 0):
+predecessor = guest_phys_blocks[-1]
+predecessor_size = (predecessor["target_end"] -
+predecessor["target_start"])
+
+# the memory API guarantees monotonically increasing
+# traversal
+assert (predecessor["target_end"] <= target_start)
+
+# we want continuity in both guest-physical and
+# host-virtual memory
+if (predecessor["target_end"] < target_start or
+predecessor["host_addr"] + predecessor_size != host_addr):
+predecessor = None
+
+if (predecessor is None):
+# isolated mapping, add it to the list
+guest_phys_blocks.append({"target_start": target_start,
+  "target_end"  : target_end,
+  "host_addr"   : host_addr})
+message = "added"
+else:
+# expand predecessor until @target_end; predecessor's
+# start doesn't change
+predecessor["target_end"] = target_end
+message = "joined"
+
+print ("%016x %016x %016x %-7s %5u" %
+   (target_start, target_end, host_addr.cast(UINTPTR_T),
+message, len(guest_phys_blocks)))
+
+return guest_phys_blocks
+
+
 class DumpGuestMemory(gdb.Command):
 """Extract guest vmcore from qemu process coredump.
 
@@ -100,96 +190,9 @@ shape and this command should mostly work."""
 super(DumpGuestMemory, self).__init__("dump-guest-memory",
   gdb.COMMAND_DATA,
   gdb.COMPLETE_FILENAME)
-self.uintptr_t = gdb.lookup_type("uintptr_t")
 self.elf64_ehdr_le = struct.Struct("<%s" % ELF64_EHDR)
 self.elf64_phdr_le = struct.Struct("<%s" % ELF64_PHDR)
-
-def int128_get64(self, val):
-assert (val["hi"] == 0)
-return val["lo"]
-
-def qlist_foreach(self, head, field_str):
-var_p = head["lh_first"]
-while (var_p != 0):
-   

[Qemu-devel] [PATCH v4] qom, qmp, hmp, qapi: create qom-type-prop-list for class properties

2016-01-22 Thread Valentin Rakush
This patch adds support for qom-type-prop-list command to list object
class properties. A later patch will use this functionality to
implement x86_64-cpu properties.

Signed-off-by: Valentin Rakush 
Cc: Luiz Capitulino 
Cc: Eric Blake 
Cc: Markus Armbruster 
Cc: Andreas Färber 
Cc: Daniel P. Berrange 
---
V4: review fixes
 - the typename argument in the hmp command changed to be mandatory
V3: commit message fix
 - commit message changed to reflect actual command name
V2: Fixes after first review
 - changed command name from qom-type-list to qom-type-prop-list
 - changed memory allocation from g_malloc0 to g_new0
 - changed parameter name from path to typename
 - fixed wordings and comments
 - fixed source code formatting
 - registered the command in monitor

 hmp-commands.hx  | 13 +
 hmp.c| 21 +
 hmp.h|  1 +
 include/qom/object.h | 31 +++
 qapi-schema.json | 19 +++
 qmp-commands.hx  |  6 ++
 qmp.c| 32 
 qom/object.c |  7 +++
 8 files changed, 130 insertions(+)

diff --git a/hmp-commands.hx b/hmp-commands.hx
index bb52e4d..ee4d1e2 100644
--- a/hmp-commands.hx
+++ b/hmp-commands.hx
@@ -1734,6 +1734,19 @@ Print QOM properties of object at location @var{path}
 ETEXI
 
 {
+.name   = "qom-type-prop-list",
+.args_type  = "typename:s",
+.params = "typename",
+.help   = "list QOM class properties",
+.mhandler.cmd  = hmp_qom_type_prop_list,
+},
+
+STEXI
+@item qom-type-prop-list [@var{typename}]
+Print QOM properties of the type @var{typename}
+ETEXI
+
+{
 .name   = "qom-set",
 .args_type  = "path:s,property:s,value:s",
 .params = "path property value",
diff --git a/hmp.c b/hmp.c
index 54f2620..6de9bf0 100644
--- a/hmp.c
+++ b/hmp.c
@@ -2052,6 +2052,27 @@ void hmp_qom_list(Monitor *mon, const QDict *qdict)
 hmp_handle_error(mon, );
 }
 
+void hmp_qom_type_prop_list(Monitor *mon, const QDict *qdict)
+{
+const char *typename = qdict_get_try_str(qdict, "typename");
+ObjectPropertyInfoList *list;
+Error *err = NULL;
+
+list = qmp_qom_type_prop_list(typename, );
+if (!err) {
+ObjectPropertyInfoList *start = list;
+while (list) {
+ObjectPropertyInfo *value = list->value;
+
+monitor_printf(mon, "%s (%s)\n",
+   value->name, value->type);
+list = list->next;
+}
+qapi_free_ObjectPropertyInfoList(start);
+}
+hmp_handle_error(mon, );
+}
+
 void hmp_qom_set(Monitor *mon, const QDict *qdict)
 {
 const char *path = qdict_get_str(qdict, "path");
diff --git a/hmp.h b/hmp.h
index a8c5b5a..8c12ebe 100644
--- a/hmp.h
+++ b/hmp.h
@@ -103,6 +103,7 @@ void hmp_object_del(Monitor *mon, const QDict *qdict);
 void hmp_info_memdev(Monitor *mon, const QDict *qdict);
 void hmp_info_memory_devices(Monitor *mon, const QDict *qdict);
 void hmp_qom_list(Monitor *mon, const QDict *qdict);
+void hmp_qom_type_prop_list(Monitor *mon, const QDict *qdict);
 void hmp_qom_set(Monitor *mon, const QDict *qdict);
 void object_add_completion(ReadLineState *rs, int nb_args, const char *str);
 void object_del_completion(ReadLineState *rs, int nb_args, const char *str);
diff --git a/include/qom/object.h b/include/qom/object.h
index d0dafe9..0c8379d 100644
--- a/include/qom/object.h
+++ b/include/qom/object.h
@@ -1013,6 +1013,37 @@ void object_property_iter_init(ObjectPropertyIterator 
*iter,
  */
 ObjectProperty *object_property_iter_next(ObjectPropertyIterator *iter);
 
+/**
+ * object_class_property_iter_init:
+ * @klass: the class owning the properties to be iterated over
+ *
+ * Initializes an iterator for traversing all properties
+ * registered against a class type and all parent classes.
+ *
+ * It is forbidden to modify the property list while iterating,
+ * whether removing or adding properties.
+ *
+ * NB For getting next property in the list the object related
+ * function object_property_iter_next is still used.
+ *
+ * Typical usage pattern would be
+ *
+ * 
+ *   Using object class property iterators
+ *   
+ *   ObjectProperty *prop;
+ *   ObjectPropertyIterator iter;
+ *
+ *   object_class property_iter_init(, obj);
+ *   while ((prop = object_property_iter_next())) {
+ * ... do something with prop ...
+ *   }
+ *   
+ * 
+ */
+void object_class_property_iter_init(ObjectPropertyIterator *iter,
+ ObjectClass *klass);
+
 void object_unparent(Object *obj);
 
 /**
diff --git a/qapi-schema.json b/qapi-schema.json
index b3038b2..2e960db 100644
--- a/qapi-schema.json
+++ b/qapi-schema.json
@@ -4081,3 +4081,22 @@
 ##
 { 'enum': 'ReplayMode',
   'data': [ 'none', 'record', 'play' ] }
+
+##

  1   2   3   >