Re: [Qemu-devel] [PATCH v3 0/4] fix debug macro pattern for vmxnet3

2015-12-07 Thread Dmitry Fleytman

Reviewed-by: Dmitry Fleytman mailto:dmi...@daynix.com>>

> On 8 Dec 2015, at 07:28 AM, Miao Yan  wrote:
> 
> This patchset fixes debug macro pattern for vmxnet3. The old style uses
> #ifdef...#else...#endif to define debug macros, as a result
> the format string inside the macro will never be checked
> (debug not turned on by default) and is likely to cause build
> errors in the future when enabled.
> 
> Changes in v3:
> - fix a build error on 32 bit platforms
> 
> Changes in v2:
> - fix grammar errors in commit log
> 
> Miao Yan (4):
>  net/vmxnet3: fix a build error when enabling debug output
>  net/vmxnet3: use %zu for size_t in printf
>  net/vmxnet3: fix debug macro pattern for vmxnet3
>  net/vmxnet3: remove redundant VMW_SHPRN(...) definition
> 
> hw/net/vmware_utils.h |   5 +-
> hw/net/vmxnet3.c  |   8 +--
> hw/net/vmxnet_debug.h | 139 +++---
> 3 files changed, 91 insertions(+), 61 deletions(-)
> 
> -- 
> 1.9.1
> 



[Qemu-devel] [PATCH v3 4/4] net/vmxnet3: remove redundant VMW_SHPRN(...) definition

2015-12-07 Thread Miao Yan
Macro VMW_SHPRN(...) is already defined vmxnet3_debug.h,
so remove the duplication

Signed-off-by: Miao Yan 
Reviewed-by: Eric Blake 
---
 hw/net/vmware_utils.h | 5 +
 1 file changed, 1 insertion(+), 4 deletions(-)

diff --git a/hw/net/vmware_utils.h b/hw/net/vmware_utils.h
index 1099df6..c2c2f90 100644
--- a/hw/net/vmware_utils.h
+++ b/hw/net/vmware_utils.h
@@ -18,10 +18,7 @@
 #define VMWARE_UTILS_H
 
 #include "qemu/range.h"
-
-#ifndef VMW_SHPRN
-#define VMW_SHPRN(fmt, ...) do {} while (0)
-#endif
+#include "vmxnet_debug.h"
 
 /*
  * Shared memory access functions with byte swap support
-- 
1.9.1




[Qemu-devel] [PATCH v3 1/4] net/vmxnet3: fix a build error when enabling debug output

2015-12-07 Thread Miao Yan
Macro MAC_FMT and MAC_ARG are not defined, but used in vmxnet3_net_init().
This will cause build error when debug level is raised in
vmxnet3_debug.h (enable all VMXNET3_DEBUG_xxx).

Use VMXNET_MF and VXMNET_MA instead.

Signed-off-by: Miao Yan 
Reviewed-by: Eric Blake 
---
Changes in v3:
  - add Reviewed-by tag
  - align subject line with others

 hw/net/vmxnet3.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/hw/net/vmxnet3.c b/hw/net/vmxnet3.c
index 5e3a233..ea3d9b7 100644
--- a/hw/net/vmxnet3.c
+++ b/hw/net/vmxnet3.c
@@ -2044,7 +2044,7 @@ static void vmxnet3_net_init(VMXNET3State *s)
 
 s->link_status_and_speed = VMXNET3_LINK_SPEED | VMXNET3_LINK_STATUS_UP;
 
-VMW_CFPRN("Permanent MAC: " MAC_FMT, MAC_ARG(s->perm_mac.a));
+VMW_CFPRN("Permanent MAC: " VMXNET_MF, VMXNET_MA(s->perm_mac.a));
 
 s->nic = qemu_new_nic(&net_vmxnet3_info, &s->conf,
   object_get_typename(OBJECT(s)),
-- 
1.9.1




[Qemu-devel] [PATCH v3 3/4] net/vmxnet3: fix debug macro pattern for vmxnet3

2015-12-07 Thread Miao Yan
Vmxnet3 uses the following debug macro style:

 #ifdef SOME_DEBUG
 #  define debug(...) do{ printf(...); } while (0)
 # else
 #  define debug(...) do{ } while (0)
 #endif

If SOME_DEBUG is undefined, then format string inside the
debug macro will never be checked by compiler. Code is
likely to break in the future when SOME_DEBUG is enabled
 because of lack of testing. This patch changes this
to the following:

 #define debug(...) \
  do { if (SOME_DEBUG_ENABLED) printf(...); } while (0)

Signed-off-by: Miao Yan 
Reviewed-by: Eric Blake 
---
 hw/net/vmxnet_debug.h | 139 +++---
 1 file changed, 86 insertions(+), 53 deletions(-)

diff --git a/hw/net/vmxnet_debug.h b/hw/net/vmxnet_debug.h
index 96dae0f..96495db 100644
--- a/hw/net/vmxnet_debug.h
+++ b/hw/net/vmxnet_debug.h
@@ -20,94 +20,127 @@
 
 #define VMXNET_DEVICE_NAME "vmxnet3"
 
-/* #define VMXNET_DEBUG_CB */
 #define VMXNET_DEBUG_WARNINGS
 #define VMXNET_DEBUG_ERRORS
-/* #define VMXNET_DEBUG_INTERRUPTS */
-/* #define VMXNET_DEBUG_CONFIG */
-/* #define VMXNET_DEBUG_RINGS */
-/* #define VMXNET_DEBUG_PACKETS */
-/* #define VMXNET_DEBUG_SHMEM_ACCESS */
+
+#undef VMXNET_DEBUG_CB
+#undef VMXNET_DEBUG_INTERRUPTS
+#undef VMXNET_DEBUG_CONFIG
+#undef VMXNET_DEBUG_RINGS
+#undef VMXNET_DEBUG_PACKETS
+#undef VMXNET_DEBUG_SHMEM_ACCESS
+
+#ifdef VMXNET_DEBUG_CB
+#  define VMXNET_DEBUG_CB_ENABLED 1
+#else
+#  define VMXNET_DEBUG_CB_ENABLED 0
+#endif
+
+#ifdef VMXNET_DEBUG_WARNINGS
+#  define VMXNET_DEBUG_WARNINGS_ENABLED 1
+#else
+#  define VMXNET_DEBUG_WARNINGS_ENABLED 0
+#endif
+
+#ifdef VMXNET_DEBUG_ERRORS
+#  define VMXNET_DEBUG_ERRORS_ENABLED 1
+#else
+#  define VMXNET_DEBUG_ERRORS_ENABLED 0
+#endif
+
+#ifdef VMXNET_DEBUG_CONFIG
+#  define VMXNET_DEBUG_CONFIG_ENABLED 1
+#else
+#  define VMXNET_DEBUG_CONFIG_ENABLED 0
+#endif
+
+#ifdef VMXNET_DEBUG_RINGS
+#  define VMXNET_DEBUG_RINGS_ENABLED 1
+#else
+#  define VMXNET_DEBUG_RINGS_ENABLED 0
+#endif
+
+#ifdef VMXNET_DEBUG_PACKETS
+#  define VMXNET_DEBUG_PACKETS_ENABLED 1
+#else
+#  define VMXNET_DEBUG_PACKETS_ENABLED 0
+#endif
+
+#ifdef VMXNET_DEBUG_INTERRUPTS
+#  define VMXNET_DEBUG_INTERRUPTS_ENABLED 1
+#else
+#  define VMXNET_DEBUG_INTERRUPTS_ENABLED 0
+#endif
 
 #ifdef VMXNET_DEBUG_SHMEM_ACCESS
+#  define VMXNET_DEBUG_SHMEM_ACCESS_ENABLED 1
+#else
+#  define VMXNET_DEBUG_SHMEM_ACCESS_ENABLED 0
+#endif
+
 #define VMW_SHPRN(fmt, ...)   \
 do {  \
-printf("[%s][SH][%s]: " fmt "\n", VMXNET_DEVICE_NAME, __func__,   \
-## __VA_ARGS__);  \
+if (VMXNET_DEBUG_SHMEM_ACCESS_ENABLED) {  \
+printf("[%s][SH][%s]: " fmt "\n", VMXNET_DEVICE_NAME, __func__,   \
+## __VA_ARGS__);  \
+   }  \
 } while (0)
-#else
-#define VMW_SHPRN(fmt, ...) do {} while (0)
-#endif
 
-#ifdef VMXNET_DEBUG_CB
 #define VMW_CBPRN(fmt, ...)   \
 do {  \
-printf("[%s][CB][%s]: " fmt "\n", VMXNET_DEVICE_NAME, __func__,   \
-## __VA_ARGS__);  \
+if (VMXNET_DEBUG_CB_ENABLED) {\
+printf("[%s][CB][%s]: " fmt "\n", VMXNET_DEVICE_NAME, __func__,   \
+## __VA_ARGS__);  \
+} \
 } while (0)
-#else
-#define VMW_CBPRN(fmt, ...) do {} while (0)
-#endif
 
-#ifdef VMXNET_DEBUG_PACKETS
 #define VMW_PKPRN(fmt, ...)   \
 do {  \
-printf("[%s][PK][%s]: " fmt "\n", VMXNET_DEVICE_NAME, __func__,   \
-## __VA_ARGS__);  \
+if (VMXNET_DEBUG_PACKETS_ENABLED) {   \
+printf("[%s][PK][%s]: " fmt "\n", VMXNET_DEVICE_NAME, __func__,   \
+## __VA_ARGS__);  \
+} \
 } while (0)
-#else
-#define VMW_PKPRN(fmt, ...) do {} while (0)
-#endif
 
-#ifdef VMXNET_DEBUG_WARNINGS
 #define VMW_WRPRN(fmt, ...)   \
 do {  \
-printf("[%s][WR][%s]: " fmt "\n", VMXNET_DEVICE_NAME, __func__,   \
-## __VA_ARGS__);  \
+if (VMXNET_DEBUG_WARN

[Qemu-devel] [PATCH v3 2/4] net/vmxnet3: use %zu for size_t in printf

2015-12-07 Thread Miao Yan
Use %zu specifier for size_t in printf, otherwise build would fail
on platforms where size_t is not unsigned long

Signed-off-by: Miao Yan 
---
 hw/net/vmxnet3.c | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)

diff --git a/hw/net/vmxnet3.c b/hw/net/vmxnet3.c
index ea3d9b7..e168285 100644
--- a/hw/net/vmxnet3.c
+++ b/hw/net/vmxnet3.c
@@ -138,7 +138,7 @@ static inline void vmxnet3_ring_init(Vmxnet3Ring *ring,
 }
 
 #define VMXNET3_RING_DUMP(macro, ring_name, ridx, r) \
-macro("%s#%d: base %" PRIx64 " size %lu cell_size %lu gen %d next %lu",  \
+macro("%s#%d: base %" PRIx64 " size %zu cell_size %zu gen %d next %zu",  \
   (ring_name), (ridx),   \
   (r)->pa, (r)->size, (r)->cell_size, (r)->gen, (r)->next)
 
@@ -925,7 +925,7 @@ static void vmxnet3_rx_need_csum_calculate(struct 
VmxnetRxPkt *pkt,
 
 /* Validate packet len: csum_start + scum_offset + length of csum field */
 if (pkt_len < (vhdr->csum_start + vhdr->csum_offset + 2)) {
-VMW_PKPRN("packet len:%lu < csum_start(%d) + csum_offset(%d) + 2, "
+VMW_PKPRN("packet len:%zu < csum_start(%d) + csum_offset(%d) + 2, "
   "cannot calculate checksum",
   pkt_len, vhdr->csum_start, vhdr->csum_offset);
 return;
@@ -1974,7 +1974,7 @@ vmxnet3_receive(NetClientState *nc, const uint8_t *buf, 
size_t size)
 vmxnet_rx_pkt_attach_data(s->rx_pkt, buf, size, s->rx_vlan_stripping);
 bytes_indicated = vmxnet3_indicate_packet(s) ? size : -1;
 if (bytes_indicated < size) {
-VMW_PKPRN("RX: %lu of %lu bytes indicated", bytes_indicated, size);
+VMW_PKPRN("RX: %zu of %zu bytes indicated", bytes_indicated, size);
 }
 } else {
 VMW_PKPRN("Packet dropped by RX filter");
-- 
1.9.1




[Qemu-devel] [PATCH v3 0/4] fix debug macro pattern for vmxnet3

2015-12-07 Thread Miao Yan
This patchset fixes debug macro pattern for vmxnet3. The old style uses
 #ifdef...#else...#endif to define debug macros, as a result
the format string inside the macro will never be checked
(debug not turned on by default) and is likely to cause build
errors in the future when enabled.

Changes in v3:
 - fix a build error on 32 bit platforms

Changes in v2:
 - fix grammar errors in commit log

Miao Yan (4):
  net/vmxnet3: fix a build error when enabling debug output
  net/vmxnet3: use %zu for size_t in printf
  net/vmxnet3: fix debug macro pattern for vmxnet3
  net/vmxnet3: remove redundant VMW_SHPRN(...) definition

 hw/net/vmware_utils.h |   5 +-
 hw/net/vmxnet3.c  |   8 +--
 hw/net/vmxnet_debug.h | 139 +++---
 3 files changed, 91 insertions(+), 61 deletions(-)

-- 
1.9.1




[Qemu-devel] qemu 2.2 stuck on condition mutex locks on all threads

2015-12-07 Thread Neil McGill


Has anyone seen anything like this ? all 4 qemu threads are stuck on a
pthread condition

QEMU emulator version 2.2.0 (Debian 1:2.2+dfsg-5expubuntu9.3~cloud0), Copyright 
(c) 2003-2008 Fabrice Bellard

I'll try and get the qemu source built on this machine to debug and get
some useful symbols out of gdb, but just wondering if there is a known
issue like this on:

Linux virl 3.19.0-33-generic #38~14.04.1-Ubuntu SMP Fri Nov 6 18:17:28 UTC 2015 
x86_64 x86_64 x86_64 GNU/Linux

tx

neil

(gdb) where
#0  __lll_lock_wait () at 
../nptl/sysdeps/unix/sysv/linux/x86_64/lowlevellock.S:135
#1  0x7f7a17524657 in _L_lock_909 () from 
/lib/x86_64-linux-gnu/libpthread.so.0
#2  0x7f7a17524480 in __GI___pthread_mutex_lock (mutex=0x7f7a2150f9a0) at 
../nptl/pthread_mutex_lock.c:79
#3  0x7f7a21036909 in ?? ()
#4  0x7f7a20fc1fdb in ?? ()
#5  0x7f7a20d153fe in ?? ()
#6  0x7f7a17176ec5 in __libc_start_main (main=0x7f7a20d13eb0, argc=94, 
argv=0x7ffcb0b0b948, init=,
fini=, rtld_fini=, stack_end=0x7ffcb0b0b938) 
at libc-start.c:287
#7  0x7f7a20d1b96c in ?? ()

(gdb) thread 2
[Switching to thread 2 (Thread 0x7f793e3ff700 (LWP 65315))]
#0  pthread_cond_wait@@GLIBC_2.3.2 () at 
../nptl/sysdeps/unix/sysv/linux/x86_64/pthread_cond_wait.S:185
185 ../nptl/sysdeps/unix/sysv/linux/x86_64/pthread_cond_wait.S: No such 
file or directory.
(gdb) where
#0  pthread_cond_wait@@GLIBC_2.3.2 () at 
../nptl/sysdeps/unix/sysv/linux/x86_64/pthread_cond_wait.S:185
#1  0x7f7a21036b29 in ?? ()
#2  0x7f7a20fb10c3 in ?? ()
#3  0x7f7a20fb14c0 in ?? ()
#4  0x7f7a17522182 in start_thread (arg=0x7f793e3ff700) at 
pthread_create.c:312
#5  0x7f7a1724f47d in clone () at 
../sysdeps/unix/sysv/linux/x86_64/clone.S:111

(gdb) thread 3
[Switching to thread 3 (Thread 0x7f7a0cbf8700 (LWP 65311))]
#0  __lll_lock_wait () at 
../nptl/sysdeps/unix/sysv/linux/x86_64/lowlevellock.S:135
135 ../nptl/sysdeps/unix/sysv/linux/x86_64/lowlevellock.S: No such file or 
directory.
(gdb) where
#0  __lll_lock_wait () at 
../nptl/sysdeps/unix/sysv/linux/x86_64/lowlevellock.S:135
#1  0x7f7a17524657 in _L_lock_909 () from 
/lib/x86_64-linux-gnu/libpthread.so.0
#2  0x7f7a17524480 in __GI___pthread_mutex_lock (mutex=0x7f7a2150f9a0) at 
../nptl/pthread_mutex_lock.c:79
#3  0x7f7a21036909 in ?? ()
#4  0x7f7a20d57d3c in ?? ()
#5  0x7f7a20d42db2 in ?? ()
#6  0x7f7a17522182 in start_thread (arg=0x7f7a0cbf8700) at 
pthread_create.c:312
#7  0x7f7a1724f47d in clone () at 
../sysdeps/unix/sysv/linux/x86_64/clone.S:111

(gdb) thread 4
[Switching to thread 4 (Thread 0x7f7a0d3f9700 (LWP 65310))]
#0  0x7f7a172421ef in __GI_ppoll (fds=0x7f7a234db150, nfds=1, 
timeout=, sigmask=0x0)
at ../sysdeps/unix/sysv/linux/ppoll.c:56
56  ../sysdeps/unix/sysv/linux/ppoll.c: No such file or directory.
(gdb) where
#0  0x7f7a172421ef in __GI_ppoll (fds=0x7f7a234db150, nfds=1, 
timeout=, sigmask=0x0)
at ../sysdeps/unix/sysv/linux/ppoll.c:56
#1  0x7f7a20fc2b2b in ?? ()
#2  0x7f7a20fc3d04 in ?? ()
#3  0x7f7a20fb5e5f in ?? ()
#4  0x7f7a20fb78f4 in ?? ()
#5  0x7f7a20ef1732 in ?? ()
#6  0x7f7a20d58e81 in ?? ()
#7  0x7f7a20d5e947 in ?? ()
#8  0x7f7a20d1f933 in ?? ()
#9  0x7f7a20d57fa1 in ?? ()
#10 0x7f7a20d42db2 in ?? ()
#11 0x7f7a17522182 in start_thread (arg=0x7f7a0d3f9700) at 
pthread_create.c:312
#12 0x7f7a1724f47d in clone () at 
../sysdeps/unix/sysv/linux/x86_64/clone.S:111
(gdb)





[Qemu-devel] [PATCH v7 30/31] qapi: Change visit_type_FOO() to no longer return partial objects

2015-12-07 Thread Eric Blake
Returning a partial object on error is an invitation for a careless
caller to leak memory.  As no one outside the testsuite was actually
relying on these semantics, it is cleaner to just document and
guarantee that ALL pointer-based visit_type_FOO() functions always
leave a safe value in *obj during an input visitor (either the new
object on success, or NULL if an error is encountered).

Since input visitors have blind assignment semantics, we have to
track the result of whether an assignment is made all the way down
to each visitor callback implementation, to avoid making decisions
based on potentially uninitialized storage.

Note that we still leave *obj unchanged after a scalar-based
visit_type_FOO(); I did not feel like auditing all uses of
visit_type_Enum() to see if the callers would tolerate a specific
sentinel value (not to mention having to decide whether it would
be better to use 0 or ENUM__MAX as that sentinel).

Signed-off-by: Eric Blake 

---
v7: rebase to earlier changes, enhance commit message, also fix
visit_type_str() and visit_type_any()
v6: rebase on top of earlier doc and formatting improvements, mention
that *obj can be uninitialized on entry to an input visitor, rework
semantics to keep valgrind happy on uninitialized input, break some
long lines
---
 include/qapi/visitor-impl.h|  6 ++---
 include/qapi/visitor.h | 53 --
 qapi/opts-visitor.c| 11 ++---
 qapi/qapi-dealloc-visitor.c|  9 ---
 qapi/qapi-visit-core.c | 43 +++---
 qapi/qmp-input-visitor.c   | 18 +-
 qapi/qmp-output-visitor.c  |  6 +++--
 qapi/string-input-visitor.c|  6 +++--
 qapi/string-output-visitor.c   |  3 ++-
 scripts/qapi-visit.py  | 40 +++
 tests/test-qmp-commands.c  | 13 +--
 tests/test-qmp-input-strict.c  | 19 +++
 tests/test-qmp-input-visitor.c | 10 ++--
 13 files changed, 156 insertions(+), 81 deletions(-)

diff --git a/include/qapi/visitor-impl.h b/include/qapi/visitor-impl.h
index 9654be6..ccb8b19 100644
--- a/include/qapi/visitor-impl.h
+++ b/include/qapi/visitor-impl.h
@@ -26,7 +26,7 @@ struct Visitor
 {
 /* Must be provided to visit structs (the string visitors do not
  * currently visit structs). */
-void (*start_struct)(Visitor *v, void **obj, size_t size,
+bool (*start_struct)(Visitor *v, void **obj, size_t size,
  const char *name, Error **errp);
 /* May be NULL; most useful for input visitors. */
 void (*check_struct)(Visitor *v, Error **errp);
@@ -34,13 +34,13 @@ struct Visitor
 void (*end_struct)(Visitor *v);

 /* May be NULL; most useful for input visitors. */
-void (*start_implicit_struct)(Visitor *v, void **obj, size_t size,
+bool (*start_implicit_struct)(Visitor *v, void **obj, size_t size,
   Error **errp);
 /* May be NULL */
 void (*end_implicit_struct)(Visitor *v);

 /* Must be set */
-void (*start_list)(Visitor *v, const char *name, GenericList **list,
+bool (*start_list)(Visitor *v, const char *name, GenericList **list,
Error **errp);
 /* Must be set */
 GenericList *(*next_list)(Visitor *v, GenericList *element, Error **errp);
diff --git a/include/qapi/visitor.h b/include/qapi/visitor.h
index 3b9f429..e9bb811 100644
--- a/include/qapi/visitor.h
+++ b/include/qapi/visitor.h
@@ -30,6 +30,27 @@
  * visitor-impl.h.
  */

+/* All qapi types have a corresponding function with a signature
+ * roughly compatible with this:
+ *
+ * void visit_type_FOO(Visitor *v, void *obj, const char *name, Error **errp);
+ *
+ * where *@obj is itself a pointer or a scalar.  The visit functions for
+ * built-in types are declared here, while the functions for qapi-defined
+ * struct, union, enum, and list types are generated (see qapi-visit.h).
+ * Input visitors may receive an uninitialized *@obj, and guarantee a
+ * safe value is assigned (a new object on success, or NULL on failure).
+ * Output visitors expect *@obj to be properly initialized on entry.
+ *
+ * Additionally, all qapi structs have a generated function compatible
+ * with this:
+ *
+ * void qapi_free_FOO(void *obj);
+ *
+ * which behaves like free(), even if @obj is NULL or was only partially
+ * allocated before encountering an error.
+ */
+
 /* This struct is layout-compatible with all other *List structs
  * created by the qapi generator. */
 typedef struct GenericList
@@ -61,11 +82,12 @@ typedef struct GenericList
  * Set *@errp on failure; for example, if the input stream does not
  * have a member @name or if the member is not an object.
  *
- * FIXME: For input visitors, *@obj can be assigned here even if later
- * visits will fail; this can lead to memory leaks if clients aren't
- * careful.
+ * Returns true if *@obj was allocated; if that happens, and an error
+ * occurs any time before the matching 

[Qemu-devel] [PATCH v7 31/31] RFC: qapi: Adjust layout of FooList types

2015-12-07 Thread Eric Blake
By sticking the next pointer first, we don't need a union with
64-bit padding for smaller types.  On 32-bit platforms, this
can reduce the size of uint8List from 16 bytes (or 12, depending
on whether 64-bit ints can tolerate 4-byte alignment) down to 8.
It has no effect on 64-bit platforms (where alignment still
dictates a 16-byte struct); but fewer anonymous unions is still
a win in my book.

However, this requires visit_start_list() and visit_next_list()
to gain a size parameter, to know what size element to allocate.

I debated about going one step further, to allow for fewer casts,
by doing:
typedef GenericList GenericList;
struct GenericList {
GenericList *next;
};
struct FooList {
GenericList base;
Foo value;
};
so that you convert to 'GenericList *' by '&foolist->base', and
back by 'container_of(generic, GenericList, base)' (as opposed to
the existing '(GenericList *)foolist' and '(FooList *)generic').
But doing that would require hoisting the declaration of
GenericList prior to inclusion of qapi-types.h, rather than its
current spot in visitor.h; it also makes iteration a bit more
verbose through 'foolist->base.next' instead of 'foolist->next'.

Signed-off-by: Eric Blake 

---
v7: new patch; probably too invasive to be worth it, especially if
we can't prove that our current size for uint8List is a bottleneck
---
 hw/ppc/spapr_drc.c   |  2 +-
 include/qapi/visitor-impl.h  |  5 +++--
 include/qapi/visitor.h   | 39 +++
 qapi/opts-visitor.c  |  9 +
 qapi/qapi-dealloc-visitor.c  |  5 +++--
 qapi/qapi-visit-core.c   | 14 +-
 qapi/qmp-input-visitor.c |  8 
 qapi/qmp-output-visitor.c|  5 +++--
 qapi/string-input-visitor.c  |  9 +
 qapi/string-output-visitor.c |  5 +++--
 scripts/qapi-types.py|  5 +
 scripts/qapi-visit.py|  4 ++--
 12 files changed, 58 insertions(+), 52 deletions(-)

diff --git a/hw/ppc/spapr_drc.c b/hw/ppc/spapr_drc.c
index f5ea3e0..6d07393 100644
--- a/hw/ppc/spapr_drc.c
+++ b/hw/ppc/spapr_drc.c
@@ -299,7 +299,7 @@ static void prop_get_fdt(Object *obj, Visitor *v, void 
*opaque,
 int i;
 prop = fdt_get_property_by_offset(fdt, fdt_offset, &prop_len);
 name = fdt_string(fdt, fdt32_to_cpu(prop->nameoff));
-visit_start_list(v, name, NULL, &err);
+visit_start_list(v, name, NULL, 0, &err);
 if (err) {
 error_propagate(errp, err);
 return;
diff --git a/include/qapi/visitor-impl.h b/include/qapi/visitor-impl.h
index ccb8b19..71313a9 100644
--- a/include/qapi/visitor-impl.h
+++ b/include/qapi/visitor-impl.h
@@ -41,9 +41,10 @@ struct Visitor

 /* Must be set */
 bool (*start_list)(Visitor *v, const char *name, GenericList **list,
-   Error **errp);
+   size_t size, Error **errp);
 /* Must be set */
-GenericList *(*next_list)(Visitor *v, GenericList *element, Error **errp);
+GenericList *(*next_list)(Visitor *v, GenericList *element, size_t size,
+  Error **errp);
 /* Must be set */
 void (*end_list)(Visitor *v);

diff --git a/include/qapi/visitor.h b/include/qapi/visitor.h
index e9bb811..febe5da 100644
--- a/include/qapi/visitor.h
+++ b/include/qapi/visitor.h
@@ -55,11 +55,8 @@
  * created by the qapi generator. */
 typedef struct GenericList
 {
-union {
-void *value;
-uint64_t padding;
-};
 struct GenericList *next;
+char padding[];
 } GenericList;

 /**
@@ -129,19 +126,19 @@ void visit_end_implicit_struct(Visitor *v);
 /**
  * Prepare to visit a list tied to an object key @name.
  * @name will be NULL if this is visited as part of another list.
- * Input visitors malloc a qapi List struct into *@list, or set it to
- * NULL if there are no elements in the list; and output visitors
- * expect *@list to point to the start of the list, if any.  On
- * return, if *@list is non-NULL, the caller should enter a loop
+ * Input visitors malloc a qapi List struct into *@list of size @size,
+ * or set it to NULL if there are no elements in the list; and output
+ * visitors expect *@list to point to the start of the list, if any.
+ * On return, if *@list is non-NULL, the caller should enter a loop
  * visiting the current element, then using visit_next_list() to
  * advance to the next element, until that returns NULL; then
  * visit_end_list() must be used to complete the visit.
  *
- * If supported by a visitor, @list can be NULL to indicate that there
- * is no qapi List struct, and that the upcoming visit calls are
- * parsing input to or creating output from some other representation;
- * in this case, visit_next_list() will not be needed, but
- * visit_end_list() is still mandatory.
+ * If supported by a visitor, @list can be NULL (and @size 0) to
+ * indicate that there is no qapi List struct, and that the upc

[Qemu-devel] [PATCH v7 29/31] qapi: Simplify semantics of visit_next_list()

2015-12-07 Thread Eric Blake
We have two uses of list visits in the entire code base: one in
spapr_drc (which completely avoids visit_next_list(), feeding in
integers from a different source than uint8List), and one in
qapi-visit.py (that is, all other list visitors are generated
in qapi-visit.c, and share the same paradigm based on a qapi
FooList type).  What's more, the semantics of the list visit are
somewhat baroque, with the following pseudocode when FooList is
used:

start()
prev = head
while (cur = next(prev)) {
visit(cur)
prev = &cur
}

Note that these semantics (advance before visit) requires that
the first call to next() return the list head, while all other
calls return the next element of the list; that is, every visitor
implementation is required to track extra state to decide whether
to return the input as-is, or to advance.  It also requires an
argument of 'GenericList **' to next(), solely because the first
iteration might need to modify the caller's GenericList head, so
that all other calls have to do a layer of dereferencing.

We can greatly simplify things by hoisting the special case
into the start() routine, and flipping the order in the loop
to visit before advance:

start(head)
element = *head
while (element) {
visit(element)
element = next(element)
}

With the simpler semantics, visitors have less state to track,
the argument to next() is reduced to 'GenericList *', and it
also becomes obvious whether an input visitor is allocating a
FooList during visit_start_list() (rather than the old way of
not knowing if an allocation happened until the first
visit_next_list()).

The spapr_drc case requires that visit_start_list() has to pay
attention to whether visit_next_list() will even be used to
visit a FooList qapi struct; this is done by passing NULL for
list, similarly to how NULL is passed to visit_start_struct()
when a qapi type is not used in those visits.  It was easy to
provide these semantics for qmp-output and dealloc visitors,
and a bit harder for qmp-input (it required hoisting the
advance of the current qlist entry out of qmp_input_next_list()
into qmp_input_get_object()).  But it turned out that the
string and opts visitors munge enough state during
visit_next_list() to make those conversions simpler if they
require a GenericList visit for now; an assertion will remind
us to adjust things if we need the semantics in the future.

Signed-off-by: Eric Blake 

---
v7: new patch
---
 hw/ppc/spapr_drc.c   |  2 +-
 include/qapi/visitor-impl.h  |  5 ++--
 include/qapi/visitor.h   | 44 +--
 qapi/opts-visitor.c  | 32 ++-
 qapi/qapi-dealloc-visitor.c  | 29 +
 qapi/qapi-visit-core.c   |  7 ++---
 qapi/qmp-input-visitor.c | 62 +---
 qapi/qmp-output-visitor.c| 21 +++
 qapi/string-input-visitor.c  | 34 
 qapi/string-output-visitor.c | 36 -
 scripts/qapi-visit.py| 21 ---
 11 files changed, 123 insertions(+), 170 deletions(-)

diff --git a/hw/ppc/spapr_drc.c b/hw/ppc/spapr_drc.c
index 65764bc..f5ea3e0 100644
--- a/hw/ppc/spapr_drc.c
+++ b/hw/ppc/spapr_drc.c
@@ -299,7 +299,7 @@ static void prop_get_fdt(Object *obj, Visitor *v, void 
*opaque,
 int i;
 prop = fdt_get_property_by_offset(fdt, fdt_offset, &prop_len);
 name = fdt_string(fdt, fdt32_to_cpu(prop->nameoff));
-visit_start_list(v, name, &err);
+visit_start_list(v, name, NULL, &err);
 if (err) {
 error_propagate(errp, err);
 return;
diff --git a/include/qapi/visitor-impl.h b/include/qapi/visitor-impl.h
index d1f4f78..9654be6 100644
--- a/include/qapi/visitor-impl.h
+++ b/include/qapi/visitor-impl.h
@@ -40,9 +40,10 @@ struct Visitor
 void (*end_implicit_struct)(Visitor *v);

 /* Must be set */
-void (*start_list)(Visitor *v, const char *name, Error **errp);
+void (*start_list)(Visitor *v, const char *name, GenericList **list,
+   Error **errp);
 /* Must be set */
-GenericList *(*next_list)(Visitor *v, GenericList **list, Error **errp);
+GenericList *(*next_list)(Visitor *v, GenericList *element, Error **errp);
 /* Must be set */
 void (*end_list)(Visitor *v);

diff --git a/include/qapi/visitor.h b/include/qapi/visitor.h
index f83707a..3b9f429 100644
--- a/include/qapi/visitor.h
+++ b/include/qapi/visitor.h
@@ -111,32 +111,36 @@ void visit_end_implicit_struct(Visitor *v);
 /**
  * Prepare to visit a list tied to an object key @name.
  * @name will be NULL if this is visited as part of another list.
- * After calling this, the elements must be collected until
- * visit_next_list() returns NULL, then visit_end_list() must be
- * used to complete the visit.
- */
-void visit_start_list(Visitor *v, const char *name, Error **errp);
-/**
- * Iterate over a GenericList during a list visit.

[Qemu-devel] [PATCH v7 23/31] qapi: Fix command with named empty argument type

2015-12-07 Thread Eric Blake
The generator special-cased
 { 'command':'foo', 'data': {} }
to avoid emitting a visitor variable, but failed to see that
 { 'struct':'NamedEmptyType, 'data': {} }
 { 'command':'foo', 'data':'NamedEmptyType' }
needs the same treatment.  Without a fix to the generator, the
change to qapi-schema-test.json fails to compile with:

tests/test-qmp-marshal.c: In function ‘qmp_marshal_user_def_cmd0’:
tests/test-qmp-marshal.c:264:14: error: variable ‘v’ set but not used 
[-Werror=unused-but-set-variable]
 Visitor *v;
  ^

Signed-off-by: Eric Blake 

---
v7: no change
v6: new patch
---
 scripts/qapi-commands.py| 6 +++---
 tests/qapi-schema/qapi-schema-test.json | 2 ++
 tests/qapi-schema/qapi-schema-test.out  | 2 ++
 tests/test-qmp-commands.c   | 5 +
 4 files changed, 12 insertions(+), 3 deletions(-)

diff --git a/scripts/qapi-commands.py b/scripts/qapi-commands.py
index 561e47a..38cbffc 100644
--- a/scripts/qapi-commands.py
+++ b/scripts/qapi-commands.py
@@ -65,7 +65,7 @@ def gen_marshal_vars(arg_type, ret_type):
 ''',
  c_type=ret_type.c_type())

-if arg_type:
+if arg_type and not arg_type.is_empty():
 ret += mcgen('''
 QmpInputVisitor *qiv = qmp_input_visitor_new_strict(QOBJECT(args));
 QapiDeallocVisitor *qdv;
@@ -97,7 +97,7 @@ def gen_marshal_vars(arg_type, ret_type):
 def gen_marshal_input_visit(arg_type, dealloc=False):
 ret = ''

-if not arg_type:
+if not arg_type or arg_type.is_empty():
 return ret

 if dealloc:
@@ -177,7 +177,7 @@ def gen_marshal(name, arg_type, ret_type):

 # 'goto out' produced by gen_marshal_input_visit->gen_visit_fields()
 # for each arg_type member, and by gen_call() for ret_type
-if (arg_type and arg_type.members) or ret_type:
+if (arg_type and not arg_type.is_empty()) or ret_type:
 ret += mcgen('''

 out:
diff --git a/tests/qapi-schema/qapi-schema-test.json 
b/tests/qapi-schema/qapi-schema-test.json
index 4b89527..a0fdb88 100644
--- a/tests/qapi-schema/qapi-schema-test.json
+++ b/tests/qapi-schema/qapi-schema-test.json
@@ -18,6 +18,8 @@
 { 'struct': 'Empty1', 'data': { } }
 { 'struct': 'Empty2', 'base': 'Empty1', 'data': { } }

+{ 'command': 'user_def_cmd0', 'data': 'Empty2', 'returns': 'Empty2' }
+
 # for testing override of default naming heuristic
 { 'enum': 'QEnumTwo',
   'prefix': 'QENUM_TWO',
diff --git a/tests/qapi-schema/qapi-schema-test.out 
b/tests/qapi-schema/qapi-schema-test.out
index 2c546b7..d8f9108 100644
--- a/tests/qapi-schema/qapi-schema-test.out
+++ b/tests/qapi-schema/qapi-schema-test.out
@@ -198,6 +198,8 @@ command guest-sync :obj-guest-sync-arg -> any
gen=True success_response=True
 command user_def_cmd None -> None
gen=True success_response=True
+command user_def_cmd0 Empty2 -> Empty2
+   gen=True success_response=True
 command user_def_cmd1 :obj-user_def_cmd1-arg -> None
gen=True success_response=True
 command user_def_cmd2 :obj-user_def_cmd2-arg -> UserDefTwo
diff --git a/tests/test-qmp-commands.c b/tests/test-qmp-commands.c
index 9f35b80..b132775 100644
--- a/tests/test-qmp-commands.c
+++ b/tests/test-qmp-commands.c
@@ -12,6 +12,11 @@ void qmp_user_def_cmd(Error **errp)
 {
 }

+Empty2 *qmp_user_def_cmd0(Error **errp)
+{
+return g_new0(Empty2, 1);
+}
+
 void qmp_user_def_cmd1(UserDefOne * ud1, Error **errp)
 {
 }
-- 
2.4.3




[Qemu-devel] [PATCH v7 20/31] spapr_drc: Expose 'null' in qom-get when there is no fdt

2015-12-07 Thread Eric Blake
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.

(Note that this reverts the behavior of commit ab8bf1d, taking
us back to the behavior of commit 1d10b44; but that this time,
the change is intentional and not an accidental side-effect.)

Signed-off-by: Eric Blake 
Cc: David Gibson 

---
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 dcce563..0c675ff 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, void 
*opaque,
 void *fdt;

 if (!drc->fdt) {
-visit_start_struct(v, NULL, 0, name, &err);
-if (!err) {
-visit_end_struct(v, &err);
-}
-error_propagate(errp, err);
+visit_type_null(v, NULL, errp);
 return;
 }

-- 
2.4.3




[Qemu-devel] [PATCH v7 25/31] qapi: Canonicalize missing object to :empty

2015-12-07 Thread Eric Blake
Now that we elide unnecessary visits of empty types, we can
start using the special ':empty' type in more places.  By using
the empty type as the base class of every explicit struct or
union, and as the default data for any command or event, we can
simplify later logic in qapi-{visit,commands,event} by merely
checking whether the type is empty, without also having to worry
whether a type was even supplied.

Note that gen_object() in qapi-types still has to check for a
base, because it is also called for alternates (which have no
base).

No change to generated code.

Signed-off-by: Eric Blake 

---
v7: rebase to earlier changes
v6: new patch
---
 scripts/qapi-commands.py|  7 ++---
 scripts/qapi-event.py   |  5 ++--
 scripts/qapi-types.py   |  4 +--
 scripts/qapi-visit.py   | 12 +
 scripts/qapi.py | 22 
 tests/qapi-schema/event-case.out|  2 +-
 tests/qapi-schema/flat-union-empty.out  |  1 +
 tests/qapi-schema/ident-with-escape.out |  1 +
 tests/qapi-schema/indented-expr.out |  4 +--
 tests/qapi-schema/qapi-schema-test.out  | 45 ++---
 tests/qapi-schema/union-clash-data.out  |  2 ++
 tests/qapi-schema/union-empty.out   |  1 +
 12 files changed, 77 insertions(+), 29 deletions(-)

diff --git a/scripts/qapi-commands.py b/scripts/qapi-commands.py
index 38cbffc..0f3cc57 100644
--- a/scripts/qapi-commands.py
+++ b/scripts/qapi-commands.py
@@ -65,7 +65,8 @@ def gen_marshal_vars(arg_type, ret_type):
 ''',
  c_type=ret_type.c_type())

-if arg_type and not arg_type.is_empty():
+assert arg_type
+if not arg_type.is_empty():
 ret += mcgen('''
 QmpInputVisitor *qiv = qmp_input_visitor_new_strict(QOBJECT(args));
 QapiDeallocVisitor *qdv;
@@ -97,7 +98,7 @@ def gen_marshal_vars(arg_type, ret_type):
 def gen_marshal_input_visit(arg_type, dealloc=False):
 ret = ''

-if not arg_type or arg_type.is_empty():
+if arg_type.is_empty():
 return ret

 if dealloc:
@@ -177,7 +178,7 @@ def gen_marshal(name, arg_type, ret_type):

 # 'goto out' produced by gen_marshal_input_visit->gen_visit_fields()
 # for each arg_type member, and by gen_call() for ret_type
-if (arg_type and not arg_type.is_empty()) or ret_type:
+if not arg_type.is_empty() or ret_type:
 ret += mcgen('''

 out:
diff --git a/scripts/qapi-event.py b/scripts/qapi-event.py
index f2feaaf..6a29b6c 100644
--- a/scripts/qapi-event.py
+++ b/scripts/qapi-event.py
@@ -39,7 +39,8 @@ def gen_event_send(name, arg_type):
 ''',
 proto=gen_event_send_proto(name, arg_type))

-if arg_type and not arg_type.is_empty():
+assert arg_type
+if not arg_type.is_empty():
 ret += mcgen('''
 QObject *obj;
 QmpOutputVisitor *qov;
@@ -88,7 +89,7 @@ out_obj:
 ''',
  c_enum=c_enum_const(event_enum_name, name))

-if arg_type and not arg_type.is_empty():
+if not arg_type.is_empty():
 ret += mcgen('''
 out:
 qmp_output_visitor_cleanup(qov);
diff --git a/scripts/qapi-types.py b/scripts/qapi-types.py
index 8f57200..91c5ae0 100644
--- a/scripts/qapi-types.py
+++ b/scripts/qapi-types.py
@@ -58,7 +58,7 @@ struct %(c_name)s {
 ''',
 c_name=c_name(name))

-if base:
+if base and not base.is_empty():
 ret += mcgen('''
 /* Members inherited from %(c_name)s: */
 ''',
@@ -222,7 +222,7 @@ class QAPISchemaGenTypeVisitor(QAPISchemaVisitor):
 def visit_object_type(self, name, info, base, members, variants):
 self._fwdecl += gen_fwd_object_or_array(name)
 self.decl += gen_object(name, base, members, variants)
-if base:
+if not base.is_implicit():
 self.decl += gen_upcast(name, base)
 self._gen_type_cleanup(name)

diff --git a/scripts/qapi-visit.py b/scripts/qapi-visit.py
index 4ec0d22..2f71dac 100644
--- a/scripts/qapi-visit.py
+++ b/scripts/qapi-visit.py
@@ -74,10 +74,11 @@ static void visit_type_implicit_%(c_type)s(Visitor *v, 
%(c_type)s **obj, Error *
 def gen_visit_struct_fields(name, base, members):
 ret = ''

-if (not base or base.is_empty()) and not members:
+assert base
+if base.is_empty() and not members:
 return ret

-if base and not base.is_empty():
+if not base.is_empty():
 ret += gen_visit_fields_decl(base)

 struct_fields_seen.add(name)
@@ -90,7 +91,7 @@ static void visit_type_%(c_name)s_fields(Visitor *v, 
%(c_name)s **obj, Error **e
 ''',
  c_name=c_name(name))

-if base and not base.is_empty():
+if not base.is_empty():
 ret += mcgen('''
 visit_type_%(c_type)s_fields(v, (%(c_type)s **)obj, &err);
 ''',
@@ -246,7 +247,8 @@ out:
 def gen_visit_union(name, base, variants):
 ret = ''

-if base:
+assert base
+if not base.is_empty():
 ret += gen_visit_fields_decl(base)

 for var in variants.var

[Qemu-devel] [PATCH v7 28/31] qapi: Split visit_end_struct() into pieces

2015-12-07 Thread Eric Blake
As mentioned in previous patches, we want to call visit_end_struct()
functions unconditionally, so that visitors can release resources
tied up since the matching visit_start_struct() without also having
to worry about error priority if more than one error occurs.

Even though error_propagate() can be safely used to ignore a second
error during cleanup caused by a first error, it is simpler if the
cleanup cannot set an error, and we instead split the task of
checking that an input visitor has no unvisited input as a new
function visit_check_struct(), called only if all prior steps are
successful.

Generated code has diffs resembling:

|@@ -59,10 +59,12 @@ void visit_type_ACPIOSTInfo(Visitor *v,
| goto out_obj;
| }
| visit_type_ACPIOSTInfo_fields(v, obj, &err);
|+if (err) {
|+goto out_obj;
|+}
|+visit_check_struct(v, &err);
| out_obj:
|-error_propagate(errp, err);
|-err = NULL;
|-visit_end_struct(v, &err);
|+visit_end_struct(v);
| out:

Signed-off-by: Eric Blake 

---
v7: rebase to earlier changes
v6: new patch, revised version of RFC based on discussion of v5 7/46
---
 hmp.c   |  7 ---
 hw/ppc/spapr_drc.c  |  3 ++-
 hw/virtio/virtio-balloon.c  | 12 ++--
 include/qapi/visitor-impl.h |  4 +++-
 include/qapi/visitor.h  | 13 ++---
 qapi/opts-visitor.c | 17 +++--
 qapi/qapi-dealloc-visitor.c |  2 +-
 qapi/qapi-visit-core.c  | 11 +--
 qapi/qmp-input-visitor.c| 34 +++---
 qapi/qmp-output-visitor.c   |  2 +-
 qom/object.c|  5 ++---
 scripts/qapi-event.py   |  3 ++-
 scripts/qapi-visit.py   |  9 -
 vl.c| 11 +--
 14 files changed, 83 insertions(+), 50 deletions(-)

diff --git a/hmp.c b/hmp.c
index f81f332..35cd625 100644
--- a/hmp.c
+++ b/hmp.c
@@ -1698,13 +1698,14 @@ void hmp_object_add(Monitor *mon, const QDict *qdict)
 }

 object_add(type, id, pdict, v, &err);
-
-out_end:
-visit_end_struct(v, &err_end);
+visit_check_struct(v, &err_end);
 if (!err && err_end) {
 qmp_object_del(id, NULL);
 }
 error_propagate(&err, err_end);
+
+out_end:
+visit_end_struct(v);
 out_clean:
 opts_visitor_cleanup(ov);

diff --git a/hw/ppc/spapr_drc.c b/hw/ppc/spapr_drc.c
index 0c675ff..65764bc 100644
--- a/hw/ppc/spapr_drc.c
+++ b/hw/ppc/spapr_drc.c
@@ -287,11 +287,12 @@ static void prop_get_fdt(Object *obj, Visitor *v, void 
*opaque,
 case FDT_END_NODE:
 /* shouldn't ever see an FDT_END_NODE before FDT_BEGIN_NODE */
 g_assert(fdt_depth > 0);
-visit_end_struct(v, &err);
+visit_check_struct(v, &err);
 if (err) {
 error_propagate(errp, err);
 return;
 }
+visit_end_struct(v);
 fdt_depth--;
 break;
 case FDT_PROP: {
diff --git a/hw/virtio/virtio-balloon.c b/hw/virtio/virtio-balloon.c
index cb8237f..fc3bced 100644
--- a/hw/virtio/virtio-balloon.c
+++ b/hw/virtio/virtio-balloon.c
@@ -136,15 +136,15 @@ static void balloon_stats_get_all(Object *obj, struct 
Visitor *v,
 goto out_nested;
 }
 }
+visit_check_struct(v, &err);
 out_nested:
-error_propagate(errp, err);
-err = NULL;
-visit_end_struct(v, &err);
+visit_end_struct(v);

+if (!err) {
+visit_check_struct(v, &err);
+}
 out_end:
-error_propagate(errp, err);
-err = NULL;
-visit_end_struct(v, &err);
+visit_end_struct(v);
 out:
 error_propagate(errp, err);
 }
diff --git a/include/qapi/visitor-impl.h b/include/qapi/visitor-impl.h
index 3b67dc7..d1f4f78 100644
--- a/include/qapi/visitor-impl.h
+++ b/include/qapi/visitor-impl.h
@@ -28,8 +28,10 @@ struct Visitor
  * currently visit structs). */
 void (*start_struct)(Visitor *v, void **obj, size_t size,
  const char *name, Error **errp);
+/* May be NULL; most useful for input visitors. */
+void (*check_struct)(Visitor *v, Error **errp);
 /* Must be provided if start_struct is present. */
-void (*end_struct)(Visitor *v, Error **errp);
+void (*end_struct)(Visitor *v);

 /* May be NULL; most useful for input visitors. */
 void (*start_implicit_struct)(Visitor *v, void **obj, size_t size,
diff --git a/include/qapi/visitor.h b/include/qapi/visitor.h
index b8146d7..f83707a 100644
--- a/include/qapi/visitor.h
+++ b/include/qapi/visitor.h
@@ -68,12 +68,19 @@ typedef struct GenericList
 void visit_start_struct(Visitor *v, void **obj, size_t size,
 const char *name, Error **errp);
 /**
+ * Prepare for completing a struct visit.
+ * Should be called prior to visit_end_struct() if all other intermediate
+ * visit steps were successful, to allow the caller one last chance to
+ * report errors such as remaining data that was not consumed by the visit.
+ */
+void visit_check_struct(

[Qemu-devel] [PATCH v7 21/31] qapi: Simplify excess input reporting in input visitors

2015-12-07 Thread Eric Blake
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.

Suggested-by: Markus Armbruster 
Signed-off-by: Eric Blake 

---
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 e8c7517..a767391 100644
--- a/qapi/opts-visitor.c
+++ b/qapi/opts-visitor.c
@@ -156,17 +156,11 @@ opts_start_struct(Visitor *v, void **obj, size_t size,
 }


-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, &ghr_true, NULL);
-if (any) {
+g_hash_table_iter_init(&iter, ov->unprocessed_opts);
+if (g_hash_table_iter_next(&iter, NULL, (void **)&any)) {
 const QemuOpt *first;

 first = g_queue_peek_head(any);
diff --git a/qapi/qmp-input-visitor.c b/qapi/qmp-input-visitor.c
index a7ebbb6..0587b8e 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, &key);
+GHashTableIter iter;
+const char *key;
+
+g_hash_table_iter_init(&iter, top_ht);
+if (g_hash_table_iter_next(&iter, (void **)&key, NULL)) {
 error_setg(errp, QERR_QMP_EXTRA_MEMBER, key);
 }
 g_hash_table_unref(top_ht);
-- 
2.4.3




[Qemu-devel] [PATCH v7 22/31] qapi: Add type.is_empty() helper

2015-12-07 Thread Eric Blake
And use it in qapi-types and qapi-event.  Down the road, we may
want to lift our artificial restriction of no variants at the
top level of an event, at which point, inlining our check for
whether members is empty will no longer be sufficient.  More
immediately, the new .is_empty() helper will help fix a bug in
qapi-visit.

Signed-off-by: Eric Blake 

---
v7: rebase to context change
v6: new patch
---
 scripts/qapi-event.py | 6 +++---
 scripts/qapi-types.py | 2 +-
 scripts/qapi.py   | 3 +++
 3 files changed, 7 insertions(+), 4 deletions(-)

diff --git a/scripts/qapi-event.py b/scripts/qapi-event.py
index 111958d..f2feaaf 100644
--- a/scripts/qapi-event.py
+++ b/scripts/qapi-event.py
@@ -39,7 +39,7 @@ def gen_event_send(name, arg_type):
 ''',
 proto=gen_event_send_proto(name, arg_type))

-if arg_type and arg_type.members:
+if arg_type and not arg_type.is_empty():
 ret += mcgen('''
 QObject *obj;
 QmpOutputVisitor *qov;
@@ -58,7 +58,7 @@ def gen_event_send(name, arg_type):
 ''',
  name=name)

-if arg_type and arg_type.members:
+if arg_type and not arg_type.is_empty():
 ret += mcgen('''
 qov = qmp_output_visitor_new();
 v = qmp_output_get_visitor(qov);
@@ -88,7 +88,7 @@ out_obj:
 ''',
  c_enum=c_enum_const(event_enum_name, name))

-if arg_type and arg_type.members:
+if arg_type and not arg_type.is_empty():
 ret += mcgen('''
 out:
 qmp_output_visitor_cleanup(qov);
diff --git a/scripts/qapi-types.py b/scripts/qapi-types.py
index 0d86269..8f57200 100644
--- a/scripts/qapi-types.py
+++ b/scripts/qapi-types.py
@@ -76,7 +76,7 @@ struct %(c_name)s {
 # potential issues with attempting to malloc space for zero-length
 # structs in C, and also incompatibility with C++ (where an empty
 # struct is size 1).
-if not (base and base.members) and not members and not variants:
+if (not base or base.is_empty()) and not members and not variants:
 ret += mcgen('''
 char qapi_dummy_field_for_empty_struct;
 ''')
diff --git a/scripts/qapi.py b/scripts/qapi.py
index 497eaba..8b388ee 100644
--- a/scripts/qapi.py
+++ b/scripts/qapi.py
@@ -973,6 +973,9 @@ class QAPISchemaObjectType(QAPISchemaType):
 # See QAPISchema._make_implicit_object_type()
 return self.name[0] == ':'

+def is_empty(self):
+return not self.members and not self.variants
+
 def c_name(self):
 assert not self.is_implicit()
 return QAPISchemaType.c_name(self)
-- 
2.4.3




[Qemu-devel] [PATCH v7 26/31] qapi-visit: Unify struct and union visit

2015-12-07 Thread Eric Blake
We are finally at the point where gen_visit_struct() and
gen_visit_union() can be unified to a generic gen_visit_object().

The generated code for structs and for flat unions is unchanged.
For simple unions, a new visit_type_FOO_fields() is created,
wrapping the visit of the non-variant tag field:

|+static void visit_type_ChardevBackend_fields(Visitor *v, ChardevBackend 
**obj, Error **errp)
|+{
|+Error *err = NULL;
|+
|+visit_type_ChardevBackendKind(v, &(*obj)->type, "type", &err);
|+if (err) {
|+goto out;
|+}
|+
|+out:
|+error_propagate(errp, err);
|+}
|+
| void visit_type_ChardevBackend(Visitor *v, ChardevBackend **obj, const char 
*name, Error **errp)
| {
| Error *err = NULL;
|@@ -2319,7 +2332,7 @@ void visit_type_ChardevBackend(Visitor *
| if (!*obj) {
| goto out_obj;
| }
|-visit_type_ChardevBackendKind(v, &(*obj)->type, "type", &err);
|+visit_type_ChardevBackend_fields(v, obj, &err);
| if (err) {

Signed-off-by: Eric Blake 

---
v7: rebase to earlier changes
v6: new patch
---
 scripts/qapi-visit.py | 133 +++---
 1 file changed, 51 insertions(+), 82 deletions(-)

diff --git a/scripts/qapi-visit.py b/scripts/qapi-visit.py
index 2f71dac..e045017 100644
--- a/scripts/qapi-visit.py
+++ b/scripts/qapi-visit.py
@@ -109,46 +109,6 @@ out:
 return ret


-def gen_visit_struct(name, base, members):
-ret = gen_visit_struct_fields(name, base, members)
-
-# FIXME: if *obj is NULL on entry, and visit_start_struct() assigns to
-# *obj, but then visit_type_FOO_fields() fails, we should clean up *obj
-# rather than leaving it non-NULL. As currently written, the caller must
-# call qapi_free_FOO() to avoid a memory leak of the partial FOO.
-ret += mcgen('''
-
-void visit_type_%(c_name)s(Visitor *v, %(c_name)s **obj, const char *name, 
Error **errp)
-{
-Error *err = NULL;
-
-visit_start_struct(v, (void **)obj, sizeof(%(c_name)s), name, &err);
-if (err) {
-goto out;
-}
-if (!*obj) {
-goto out_obj;
-}
-''',
- name=name, c_name=c_name(name))
-if (base and not base.is_empty()) or members:
-ret += mcgen('''
-visit_type_%(c_name)s_fields(v, obj, &err);
-''',
- c_name=c_name(name))
-ret += mcgen('''
-out_obj:
-error_propagate(errp, err);
-err = NULL;
-visit_end_struct(v, &err);
-out:
-error_propagate(errp, err);
-}
-''')
-
-return ret
-
-
 def gen_visit_list(name, element_type):
 # FIXME: if *obj is NULL on entry, and the first visit_next_list()
 # assigns to *obj, while a later one fails, we should clean up *obj
@@ -244,18 +204,24 @@ out:
 return ret


-def gen_visit_union(name, base, variants):
+def gen_visit_object(name, base, members, variants):
 ret = ''

 assert base
 if not base.is_empty():
 ret += gen_visit_fields_decl(base)
+if members:
+ret += gen_visit_struct_fields(name, base, members)
+if variants:
+for var in variants.variants:
+# Ugly special case for simple union TODO get rid of it
+if not var.simple_union_type():
+ret += gen_visit_implicit_struct(var.type)

-for var in variants.variants:
-# Ugly special case for simple union TODO get rid of it
-if not var.simple_union_type():
-ret += gen_visit_implicit_struct(var.type)
-
+# FIXME: if *obj is NULL on entry, and visit_start_struct() assigns to
+# *obj, but then visit_type_FOO_fields() fails, we should clean up *obj
+# rather than leaving it non-NULL. As currently written, the caller must
+# call qapi_free_FOO() to avoid a memory leak of the partial FOO.
 ret += mcgen('''

 void visit_type_%(c_name)s(Visitor *v, %(c_name)s **obj, const char *name, 
Error **errp)
@@ -272,61 +238,71 @@ void visit_type_%(c_name)s(Visitor *v, %(c_name)s **obj, 
const char *name, Error
 ''',
  c_name=c_name(name))

-if not base.is_empty():
+if not base.is_empty() or members:
+if members:
+type_name = c_name(name)
+cast = ''
+else:
+type_name = base.c_name()
+cast = '(%s **)' % type_name
 ret += mcgen('''
-visit_type_%(c_name)s_fields(v, (%(c_name)s **)obj, &err);
+visit_type_%(c_name)s_fields(v, %(cast)sobj, &err);
 ''',
- c_name=base.c_name())
-else:
+ c_name=type_name, cast=cast)
+if variants:
+ret += gen_err_check(label='out_obj')
+
+if variants:
 ret += mcgen('''
-visit_type_%(c_type)s(v, &(*obj)->%(c_name)s, "%(name)s", &err);
-''',
- c_type=variants.tag_member.type.c_name(),
- c_name=c_name(variants.tag_member.name),
- name=variants.tag_member.name)
-ret += gen_err_check(label='out_obj')
-ret += mcgen('''
 if (!visit_start_union(v, !!(*obj

[Qemu-devel] [PATCH v7 17/31] qapi: Document visitor interfaces, add assertions

2015-12-07 Thread Eric Blake
The visitor interface for mapping between QObject/QemuOpts/string
and qapi has formerly been documented only by reading source code,
making it difficult to propose changes to either scripts/qapi*.py
or to clients without knowing whether those changes would be safe.
This adds documentation, including mentioning when parameters can
be NULL, and where there are still some interface warts that would
be nice to remove.  In particular, I have plans to remove
visit_start_union() in a future patch.

Add some asserts to strengthen the claims of the assertions; some
of these were only made possible by recent cleanup commits.  These
were made easier with the addition of a new visit_is_output()
helper (since all 2 output visitors of our 6 overall visitors use
the same .type_enum() callback).

Signed-off-by: Eric Blake 

---
v7: retitle; more wording changes, add asserts to enforce the
wording, place later in series to rebase on fixes that would
otherwise trip the new assertions
v6: mention that input visitors blindly assign over *obj; wording
improvements
---
 include/qapi/visitor-impl.h |  31 +-
 include/qapi/visitor.h  | 223 ++--
 qapi/qapi-visit-core.c  |  39 +++-
 3 files changed, 280 insertions(+), 13 deletions(-)

diff --git a/include/qapi/visitor-impl.h b/include/qapi/visitor-impl.h
index c3c6323..27f776f 100644
--- a/include/qapi/visitor-impl.h
+++ b/include/qapi/visitor-impl.h
@@ -15,23 +15,37 @@
 #include "qapi/error.h"
 #include "qapi/visitor.h"

+/* This file describes the callback interface for implementing a
+ * QObject visitor.  For the client interface, see visitor.h.  When
+ * implementing the callbacks, it is easiest to declare a struct with
+ * 'Visitor visitor;' as the first member.  Semantics for the
+ * callbacks are generally similar to the counterpart public
+ * interface.  */
+
 struct Visitor
 {
-/* Must be set */
+/* Must be provided to visit structs (the string visitors do not
+ * currently visit structs). */
 void (*start_struct)(Visitor *v, void **obj, size_t size,
  const char *name, Error **errp);
+/* Must be provided if start_struct is present. */
 void (*end_struct)(Visitor *v, Error **errp);

+/* May be NULL; most useful for input visitors. */
 void (*start_implicit_struct)(Visitor *v, void **obj, size_t size,
   Error **errp);
 /* May be NULL */
 void (*end_implicit_struct)(Visitor *v);

+/* Must be set */
 void (*start_list)(Visitor *v, const char *name, Error **errp);
+/* Must be set */
 GenericList *(*next_list)(Visitor *v, GenericList **list, Error **errp);
 /* Must be set */
 void (*end_list)(Visitor *v);

+/* Must be set, although the helpers input_type_enum() and
+ * output_type_enum() should be used if appropriate.  */
 void (*type_enum)(Visitor *v, int *obj, const char *const strings[],
   const char *name, Error **errp);
 /* May be NULL; only needed for input visitors. */
@@ -47,23 +61,38 @@ struct Visitor
 /* Optional; fallback is type_uint64().  */
 void (*type_size)(Visitor *v, uint64_t *obj, const char *name,
   Error **errp);
+
 /* Must be set. */
 void (*type_bool)(Visitor *v, bool *obj, const char *name, Error **errp);
+/* Must be set */
 void (*type_str)(Visitor *v, char **obj, const char *name, Error **errp);
+
+/* Must be provided to visit numbers (the opts visitor does not
+ * currently visit non-integers). */
 void (*type_number)(Visitor *v, double *obj, const char *name,
 Error **errp);
+/* Must be provided to visit arbitrary QTypes (the opts and string
+ * visitors do not currently visit arbitrary types).  */
 void (*type_any)(Visitor *v, QObject **obj, const char *name,
  Error **errp);

 /* May be NULL; most useful for input visitors. */
 void (*optional)(Visitor *v, bool *present, const char *name);

+/* FIXME - needs to be removed */
 bool (*start_union)(Visitor *v, bool data_present, Error **errp);
+/* FIXME - needs to be removed */
 void (*end_union)(Visitor *v, bool data_present, Error **errp);
 };

+/**
+ * A generic visitor.type_enum suitable for input visitors.
+ */
 void input_type_enum(Visitor *v, int *obj, const char *const strings[],
  const char *name, Error **errp);
+/**
+ * A generic visitor.type_enum suitable for output visitors.
+ */
 void output_type_enum(Visitor *v, int *obj, const char *const strings[],
   const char *name, Error **errp);

diff --git a/include/qapi/visitor.h b/include/qapi/visitor.h
index 21c09b4..96a9535 100644
--- a/include/qapi/visitor.h
+++ b/include/qapi/visitor.h
@@ -18,6 +18,20 @@
 #include "qapi/error.h"
 #include 

+/* This file describes the client view for visiting a map between
+ * generated QAPI C structs and another representa

[Qemu-devel] [PATCH v7 27/31] qapi: Rework deallocation of partial struct

2015-12-07 Thread Eric Blake
Commit cee2dedb noticed that if you have a partial flat union
(such as if an input parse failed due to a missing
discriminator), calling the dealloc visitor could result in
trying to dereference the NULL pointer. But the fix it proposed
requires the use of a 'data' member in the union, which may or
may not be the same size as other branches of the union
(consider a 32-bit platform where one of the branches is an
int64), so it feels fairly dirty.  A better fix is to tweak all
of the generated visit_type_implicit_FOO() functions to avoid
dereferencing NULL in the first place, by not visiting the
fields if the struct pointer itself is not present, at which
point we no longer even need visit_start_union().  And no one
was implementing visit_end_union() callbacks.

While rewriting the code, use patterns that are closer to what
is used elsewhere in the generated visitors, by using 'goto'
to cleanup labels rather than putting followup code under 'if'
conditions.  The change keeps the contract that any successful
use of visit_start_implicit_struct() will be paired with a
matching visit_end_implicit_struct(), even if intermediate
processing is skipped.  We are safe in checking *obj alone, as
as the contract of visit_start_implicit_struct() requires a
non-NULL obj.

As an example of the changes to generated code:
|@@ -1331,10 +1331,16 @@ static void visit_type_implicit_Blockdev
| Error *err = NULL;
|
| visit_start_implicit_struct(v, (void **)obj, 
sizeof(BlockdevOptionsArchipelago), &err);
|-if (!err) {
|-visit_type_BlockdevOptionsArchipelago_fields(v, obj, errp);
|-visit_end_implicit_struct(v);
|+if (err) {
|+goto out;
|+}
|+if (!*obj) {
|+goto out_obj;
| }
|+visit_type_BlockdevOptionsArchipelago_fields(v, obj, &err);
|+out_obj:
|+visit_end_implicit_struct(v);
|+out:
| error_propagate(errp, err);
| }
...
|@@ -1479,9 +1539,6 @@ void visit_type_BlockdevOptions(Visitor
| if (err) {
| goto out_obj;
| }
|-if (!visit_start_union(v, !!(*obj)->u.data, &err) || err) {
|-goto out_obj;
|-}
| switch ((*obj)->driver) {
| case BLOCKDEV_DRIVER_ARCHIPELAGO:
| visit_type_implicit_BlockdevOptionsArchipelago(v, 
&(*obj)->u.archipelago, &err);
|@@ -1570,11 +1627,6 @@ void visit_type_BlockdevOptions(Visitor
| out_obj:
| error_propagate(errp, err);
| err = NULL;
|-if (*obj) {
|-visit_end_union(v, !!(*obj)->u.data, &err);
|-}
|-error_propagate(errp, err);
|-err = NULL;
| visit_end_struct(v, &err);

Signed-off-by: Eric Blake 

---
v7: rebase to earlier context changes, simplify 'obj && !*obj'
condition based on contract
v6: rebase due to deferring 7/46, and gen_err_check() improvements;
rewrite gen_visit_implicit_struct() more like other patterns
---
 include/qapi/visitor-impl.h |  5 -
 include/qapi/visitor.h  | 12 
 qapi/qapi-dealloc-visitor.c | 26 --
 qapi/qapi-visit-core.c  | 15 ---
 scripts/qapi-visit.py   | 25 +
 5 files changed, 9 insertions(+), 74 deletions(-)

diff --git a/include/qapi/visitor-impl.h b/include/qapi/visitor-impl.h
index 628cab7..3b67dc7 100644
--- a/include/qapi/visitor-impl.h
+++ b/include/qapi/visitor-impl.h
@@ -81,11 +81,6 @@ struct Visitor

 /* May be NULL; most useful for input visitors. */
 void (*optional)(Visitor *v, bool *present, const char *name);
-
-/* FIXME - needs to be removed */
-bool (*start_union)(Visitor *v, bool data_present, Error **errp);
-/* FIXME - needs to be removed */
-void (*end_union)(Visitor *v, bool data_present, Error **errp);
 };

 /**
diff --git a/include/qapi/visitor.h b/include/qapi/visitor.h
index 2592dd1..b8146d7 100644
--- a/include/qapi/visitor.h
+++ b/include/qapi/visitor.h
@@ -274,16 +274,4 @@ void visit_type_any(Visitor *v, QObject **obj, const char 
*name, Error **errp);
  */
 void visit_type_null(Visitor *v, const char *name, Error **errp);

-/**
- * Mark the start of visiting the branches of a union. Return true if
- * @data_present.
- * FIXME: Should not be needed
- */
-bool visit_start_union(Visitor *v, bool data_present, Error **errp);
-/**
- * Mark the end of union branches, after visit_start_union().
- * FIXME: Should not be needed
- */
-void visit_end_union(Visitor *v, bool data_present, Error **errp);
-
 #endif
diff --git a/qapi/qapi-dealloc-visitor.c b/qapi/qapi-dealloc-visitor.c
index e3a4493..92345aa 100644
--- a/qapi/qapi-dealloc-visitor.c
+++ b/qapi/qapi-dealloc-visitor.c
@@ -172,31 +172,6 @@ static void qapi_dealloc_type_enum(Visitor *v, int *obj,
 {
 }

-/* If there's no data present, the dealloc visitor has nothing to free.
- * Thus, indicate to visitor code that the subsequent union fields can
- * be skipped. This is not an error condition, since the cleanup of the
- * rest of an object can continue unhindered, so leave errp unset in
- * these cases.
- *
- * NOTE: In cases where we're attemp

[Qemu-devel] [PATCH v7 24/31] qapi: Eliminate empty visit_type_FOO_fields

2015-12-07 Thread Eric Blake
For empty structs, such as the 'Abort' helper type used as part
of the 'transaction' command, we were emitting a no-op
visit_type_FOO_fields().  Optimize things to instead omit calls
for empty structs.  Generated code changes resemble:

|-static void visit_type_Abort_fields(Visitor *v, Abort **obj, Error **errp)
|-{
|-Error *err = NULL;
|-
|-error_propagate(errp, err);
|-}
|-
| void visit_type_Abort(Visitor *v, Abort **obj, const char *name, Error **errp)
| {
| Error *err = NULL;
|@@ -112,7 +105,6 @@ void visit_type_Abort(Visitor *v, Abort
| if (!*obj) {
| goto out_obj;
| }
|-visit_type_Abort_fields(v, obj, &err);
| out_obj:
| error_propagate(errp, err);

Another reason for doing this optimization is that it gets us
closer to merging the code for visiting structs and unions:
since flat unions have no local members, they do not need to
have a visit_type_UNION_fields() emitted, even when they start
sharing the code used to visit structs.

Signed-off-by: Eric Blake 

---
v7: rebase to earlier changes
v6: new patch
---
 scripts/qapi-visit.py | 41 +++--
 1 file changed, 23 insertions(+), 18 deletions(-)

diff --git a/scripts/qapi-visit.py b/scripts/qapi-visit.py
index acb237b..4ec0d22 100644
--- a/scripts/qapi-visit.py
+++ b/scripts/qapi-visit.py
@@ -35,22 +35,22 @@ void visit_type_%(c_name)s(Visitor *v, %(c_type)sobj, const 
char *name, Error **


 def gen_visit_fields_decl(typ):
-ret = ''
-if typ.name not in struct_fields_seen:
-ret += mcgen('''
+if typ.is_empty() or typ.name in struct_fields_seen:
+return ''
+
+struct_fields_seen.add(typ.name)
+return mcgen('''

 static void visit_type_%(c_type)s_fields(Visitor *v, %(c_type)s **obj, Error 
**errp);
 ''',
- c_type=typ.c_name())
-struct_fields_seen.add(typ.name)
-return ret
+ c_type=typ.c_name())


 def gen_visit_implicit_struct(typ):
-if typ in implicit_structs_seen:
+if typ.is_empty() or typ in implicit_structs_seen:
 return ''
+
 implicit_structs_seen.add(typ)
-
 ret = gen_visit_fields_decl(typ)

 ret += mcgen('''
@@ -74,7 +74,10 @@ static void visit_type_implicit_%(c_type)s(Visitor *v, 
%(c_type)s **obj, Error *
 def gen_visit_struct_fields(name, base, members):
 ret = ''

-if base:
+if (not base or base.is_empty()) and not members:
+return ret
+
+if base and not base.is_empty():
 ret += gen_visit_fields_decl(base)

 struct_fields_seen.add(name)
@@ -87,7 +90,7 @@ static void visit_type_%(c_name)s_fields(Visitor *v, 
%(c_name)s **obj, Error **e
 ''',
  c_name=c_name(name))

-if base:
+if base and not base.is_empty():
 ret += mcgen('''
 visit_type_%(c_type)s_fields(v, (%(c_type)s **)obj, &err);
 ''',
@@ -96,13 +99,9 @@ static void visit_type_%(c_name)s_fields(Visitor *v, 
%(c_name)s **obj, Error **e

 ret += gen_visit_fields(members, prefix='(*obj)->')

-# 'goto out' produced for base, and by gen_visit_fields() for each member
-if base or members:
-ret += mcgen('''
+ret += mcgen('''

 out:
-''')
-ret += mcgen('''
 error_propagate(errp, err);
 }
 ''')
@@ -129,7 +128,14 @@ void visit_type_%(c_name)s(Visitor *v, %(c_name)s **obj, 
const char *name, Error
 if (!*obj) {
 goto out_obj;
 }
+''',
+ name=name, c_name=c_name(name))
+if (base and not base.is_empty()) or members:
+ret += mcgen('''
 visit_type_%(c_name)s_fields(v, obj, &err);
+''',
+ c_name=c_name(name))
+ret += mcgen('''
 out_obj:
 error_propagate(errp, err);
 err = NULL;
@@ -137,8 +143,7 @@ out_obj:
 out:
 error_propagate(errp, err);
 }
-''',
- c_name=c_name(name))
+''')

 return ret

@@ -300,7 +305,7 @@ void visit_type_%(c_name)s(Visitor *v, %(c_name)s **obj, 
const char *name, Error
 ''',
  c_type=simple_union_type.c_name(),
  c_name=c_name(var.name))
-else:
+elif not var.type.is_empty():
 ret += mcgen('''
 visit_type_implicit_%(c_type)s(v, &(*obj)->u.%(c_name)s, &err);
 ''',
-- 
2.4.3




[Qemu-devel] [PATCH v7 19/31] qmp: Tighten output visitor rules

2015-12-07 Thread Eric Blake
Add a new qmp_output_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 (so
that the accidental return of NULL fixed by commit ab8bf1d7 will
be much easier to diagnose), and that it may only be called once
per visit.

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.

Signed-off-by: Eric Blake 

---
v7: new patch, based on discussion about spapr_drc.c
---
 include/qapi/qmp-output-visitor.h |  1 +
 include/qapi/visitor-impl.h   |  2 +-
 qapi/qmp-output-visitor.c | 37 -
 tests/test-qmp-output-visitor.c   |  2 ++
 4 files changed, 28 insertions(+), 14 deletions(-)

diff --git a/include/qapi/qmp-output-visitor.h 
b/include/qapi/qmp-output-visitor.h
index 2266770..184195b 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_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 78a5ab1..628cab7 100644
--- a/include/qapi/visitor-impl.h
+++ b/include/qapi/visitor-impl.h
@@ -76,7 +76,7 @@ struct Visitor
 void (*type_any)(Visitor *v, QObject **obj, const char *name,
  Error **errp);
 /* Must be provided to visit explicit null values (right now, only the
- * dealloc visitor supports this).  */
+ * dealloc and qmp-output visitors support this).  */
 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 06ee19b..28f9854 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 Red Hat, Inc.
  * Copyright IBM, Corp. 2011
  *
  * Authors:
@@ -88,9 +89,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)) {
@@ -202,18 +202,22 @@ static void qmp_output_type_any(Visitor *v, QObject 
**obj, const char *name,
 qmp_output_add_obj(qov, name, *obj);
 }

+static void qmp_output_type_null(Visitor *v, const char *name, Error **errp)
+{
+QmpOutputVisitor *qov = to_qov(v);
+qmp_output_add_obj(qov, name, qnull());
+}
+
 /* Finish building, and return the root object. Will not be NULL. */
 QObject *qmp_output_get_qobject(QmpOutputVisitor *qov)
 {
-/* FIXME: we should require that a visit occurred, and that it is
- * complete (no starts without a matching end) */
-QObject *obj = qov->root;
-if (obj) {
-qobject_incref(obj);
-} else {
-obj = qnull();
-}
-return obj;
+QObject *root;
+
+assert(qov->root);  /* A visit must have occurred...  */
+assert(!qmp_output_last(qov));  /* ...with each start paired with end.  */
+root = qov->root;
+qov->root = NULL;
+return root;
 }

 Visitor *qmp_output_get_visitor(QmpOutputVisitor *v)
@@ -221,7 +225,7 @@ Visitor *qmp_output_get_visitor(QmpOutputVisitor *v)
 return &v->visitor;
 }

-void qmp_output_visitor_cleanup(QmpOutputVisitor *v)
+void qmp_output_reset(QmpOutputVisitor *v)
 {
 QStackEntry *e, *tmp;

@@ -231,6 +235,12 @@ void qmp_output_visitor_cleanup(QmpOutputVisitor *v)
 }

 qobject_decref(v->root);
+v->root = NULL;
+}
+
+void qmp_output_visitor_cleanup(QmpOutputVisitor *v)
+{
+qmp_output_reset(v);
 g_free(v);
 }

@@ -252,6 +262,7 @@ QmpOutputVisitor *qmp_output_visitor_new(void)
 v->visitor.type_str = qmp_output_type_str;
 v->visitor.type_number = qmp_output_type_number;
 v->visitor.type_any = qmp_output_type_any;
+v->visitor.type_null = qmp_output_type_null;

 QTAILQ_INIT(&v->stack);

diff --git a/tests/test-qmp-output-visitor.c b/tests/test-qmp-output-visitor.c
index 8e6fc33..53d1372 100644
--- a/tests/test-qmp-output-visitor.c
+++ b/tests/test-qmp-output-visi

[Qemu-devel] [PATCH v7 13/31] qapi: Drop unused 'kind' for struct/enum visit

2015-12-07 Thread Eric Blake
visit_start_struct() and visit_type_enum() had a 'kind' argument
that was usually set to either the stringized version of the
corresponding qapi type name, or to NULL (although some clients
didn't even get that right).  But nothing ever used the argument.
It's even hard to argue that it would be useful in a debugger,
as a stack backtrace also tells which type is being visited.

Therefore, drop the 'kind' argument as dead.  While at it, change
the signature of visit_start_struct() to place the 'name'
argument at the end (other than 'errp'), and the 'size' argument
next to 'obj'; this placement of 'name' matches matches how all
other functions in visit.h do it (visit_type_enum() places
'strings' between 'obj' and 'name'; visit_get_next_type() places
'promote_int' between 'type' and 'name').  This also avoids the
confusion caused by splitting related pieces of information,
where the old signature an unrelated parameter in between the
"typename" and sizeof(typename) arguments.

Signed-off-by: Eric Blake 

---
v7: new patch
---
 hmp.c   |  2 +-
 hw/core/qdev-properties.c   |  6 ++
 hw/ppc/spapr_drc.c  |  4 ++--
 hw/virtio/virtio-balloon.c  |  4 ++--
 include/qapi/visitor-impl.h | 16 
 include/qapi/visitor.h  |  8 
 qapi/opts-visitor.c |  4 ++--
 qapi/qapi-dealloc-visitor.c | 10 --
 qapi/qapi-visit-core.c  | 23 +++
 qapi/qmp-input-visitor.c|  4 ++--
 qapi/qmp-output-visitor.c   |  5 ++---
 qom/object.c|  8 
 scripts/qapi-event.py   |  2 +-
 scripts/qapi-visit.py   | 12 ++--
 vl.c|  2 +-
 15 files changed, 52 insertions(+), 58 deletions(-)

diff --git a/hmp.c b/hmp.c
index 0d21f1d..f81f332 100644
--- a/hmp.c
+++ b/hmp.c
@@ -1680,7 +1680,7 @@ void hmp_object_add(Monitor *mon, const QDict *qdict)
 pdict = qdict_clone_shallow(qdict);
 v = opts_get_visitor(ov);

-visit_start_struct(v, NULL, NULL, NULL, 0, &err);
+visit_start_struct(v, NULL, 0, NULL, &err);
 if (err) {
 goto out_clean;
 }
diff --git a/hw/core/qdev-properties.c b/hw/core/qdev-properties.c
index 33e245e..d81d689 100644
--- a/hw/core/qdev-properties.c
+++ b/hw/core/qdev-properties.c
@@ -48,8 +48,7 @@ static void get_enum(Object *obj, Visitor *v, void *opaque,
 Property *prop = opaque;
 int *ptr = qdev_get_prop_ptr(dev, prop);

-visit_type_enum(v, ptr, prop->info->enum_table,
-prop->info->name, prop->name, errp);
+visit_type_enum(v, ptr, prop->info->enum_table, prop->name, errp);
 }

 static void set_enum(Object *obj, Visitor *v, void *opaque,
@@ -64,8 +63,7 @@ static void set_enum(Object *obj, Visitor *v, void *opaque,
 return;
 }

-visit_type_enum(v, ptr, prop->info->enum_table,
-prop->info->name, prop->name, errp);
+visit_type_enum(v, ptr, prop->info->enum_table, prop->name, errp);
 }

 /* Bit */
diff --git a/hw/ppc/spapr_drc.c b/hw/ppc/spapr_drc.c
index 8be62c3..96d06f5 100644
--- a/hw/ppc/spapr_drc.c
+++ b/hw/ppc/spapr_drc.c
@@ -259,7 +259,7 @@ static void prop_get_fdt(Object *obj, Visitor *v, void 
*opaque,
 void *fdt;

 if (!drc->fdt) {
-visit_start_struct(v, NULL, NULL, name, 0, &err);
+visit_start_struct(v, NULL, 0, name, &err);
 if (!err) {
 visit_end_struct(v, &err);
 }
@@ -282,7 +282,7 @@ static void prop_get_fdt(Object *obj, Visitor *v, void 
*opaque,
 case FDT_BEGIN_NODE:
 fdt_depth++;
 name = fdt_get_name(fdt, fdt_offset, &name_len);
-visit_start_struct(v, NULL, NULL, name, 0, &err);
+visit_start_struct(v, NULL, 0, name, &err);
 if (err) {
 error_propagate(errp, err);
 return;
diff --git a/hw/virtio/virtio-balloon.c b/hw/virtio/virtio-balloon.c
index 1ce987a..cb8237f 100644
--- a/hw/virtio/virtio-balloon.c
+++ b/hw/virtio/virtio-balloon.c
@@ -117,7 +117,7 @@ static void balloon_stats_get_all(Object *obj, struct 
Visitor *v,
 VirtIOBalloon *s = opaque;
 int i;

-visit_start_struct(v, NULL, "guest-stats", name, 0, &err);
+visit_start_struct(v, NULL, 0, name, &err);
 if (err) {
 goto out;
 }
@@ -126,7 +126,7 @@ static void balloon_stats_get_all(Object *obj, struct 
Visitor *v,
 goto out_end;
 }

-visit_start_struct(v, NULL, NULL, "stats", 0, &err);
+visit_start_struct(v, NULL, 0, "stats", &err);
 if (err) {
 goto out_end;
 }
diff --git a/include/qapi/visitor-impl.h b/include/qapi/visitor-impl.h
index 5ee2974..6737005 100644
--- a/include/qapi/visitor-impl.h
+++ b/include/qapi/visitor-impl.h
@@ -18,8 +18,8 @@
 struct Visitor
 {
 /* Must be set */
-void (*start_struct)(Visitor *v, void **obj, const char *kind,
- const char *name, size_t size, Error **errp);
+void (*start_struct)(Visitor *v, void **obj, size_t size,
+   

[Qemu-devel] [PATCH v7 15/31] qmp: Fix reference-counting of qnull on empty output visit

2015-12-07 Thread Eric Blake
Commit 6c2f9a15 ensured that we would not return NULL when the
caller used an output visitor but had nothing to visit. But
in doing so, it added a FIXME about a reference count leak
that could abort qemu in the (unlikely) case of SIZE_MAX such
visits (more plausible on 32-bit).  (Although that commit
suggested we might fix it in time for 2.5, we ran out of time;
fortunately, it is unlikely enough to bite that it was not
worth worrying about during the 2.5 release.)

This fixes things by documenting the internal contracts, and
explaining why the internal function can return NULL and only
the public facing interface needs to worry about qnull(),
thus avoiding over-referencing the qnull_ global object.

It does not, however, fix the stupidity of the stack mixing
up two separate pieces of information; add a FIXME to explain
that issue.

Signed-off-by: Eric Blake 
Cc: qemu-sta...@nongnu.org

---
v7: cc qemu-stable, tweak some asserts, drop stale comment, add more
comments
v6: no change
---
 qapi/qmp-output-visitor.c   | 39 ---
 tests/test-qmp-output-visitor.c |  2 ++
 2 files changed, 34 insertions(+), 7 deletions(-)

diff --git a/qapi/qmp-output-visitor.c b/qapi/qmp-output-visitor.c
index 4bd2ad0..77097b7 100644
--- a/qapi/qmp-output-visitor.c
+++ b/qapi/qmp-output-visitor.c
@@ -29,6 +29,15 @@ typedef QTAILQ_HEAD(QStack, QStackEntry) QStack;
 struct QmpOutputVisitor
 {
 Visitor visitor;
+/* FIXME: we are abusing stack to hold two separate pieces of
+ * information: the current root object in slot 0, and the stack
+ * of N objects still being built in slots 1 through N (for N+1
+ * slots in use).  Worse, our behavior is inconsistent:
+ * qmp_output_add_obj() visiting two top-level scalars in a row
+ * discards the first in favor of the second, but visiting two
+ * top-level objects in a row tries to append the second object
+ * into the first (since the first object was placed in the stack
+ * in both slot 0 and 1, but only popped from slot 1).  */
 QStack stack;
 };

@@ -41,10 +50,12 @@ static QmpOutputVisitor *to_qov(Visitor *v)
 return container_of(v, QmpOutputVisitor, visitor);
 }

+/* Push @value onto the stack of current QObjects being built */
 static void qmp_output_push_obj(QmpOutputVisitor *qov, QObject *value)
 {
 QStackEntry *e = g_malloc0(sizeof(*e));

+assert(value);
 e->value = value;
 if (qobject_type(e->value) == QTYPE_QLIST) {
 e->is_list_head = true;
@@ -52,44 +63,51 @@ static void qmp_output_push_obj(QmpOutputVisitor *qov, 
QObject *value)
 QTAILQ_INSERT_HEAD(&qov->stack, e, node);
 }

+/* Grab and remove the most recent QObject from the stack */
 static QObject *qmp_output_pop(QmpOutputVisitor *qov)
 {
 QStackEntry *e = QTAILQ_FIRST(&qov->stack);
 QObject *value;
+
+assert(e);
 QTAILQ_REMOVE(&qov->stack, e, node);
 value = e->value;
 g_free(e);
 return value;
 }

+/* Grab the root QObject, if any, in preparation to empty the stack */
 static QObject *qmp_output_first(QmpOutputVisitor *qov)
 {
 QStackEntry *e = QTAILQ_LAST(&qov->stack, QStack);

-/*
- * FIXME Wrong, because qmp_output_get_qobject() will increment
- * the refcnt *again*.  We need to think through how visitors
- * handle null.
- */
 if (!e) {
-return qnull();
+/* No root */
+return NULL;
 }
-
+assert(e->value);
 return e->value;
 }

+/* Grab the most recent QObject from the stack, which must exist */
 static QObject *qmp_output_last(QmpOutputVisitor *qov)
 {
 QStackEntry *e = QTAILQ_FIRST(&qov->stack);
+
+assert(e && e->value);
 return e->value;
 }

+/* Add @value to the current QObject being built.
+ * If the stack is visiting a dictionary or list, @value is now owned
+ * by that container. Otherwise, @value is now the root.  */
 static void qmp_output_add_obj(QmpOutputVisitor *qov, const char *name,
QObject *value)
 {
 QObject *cur;

 if (QTAILQ_EMPTY(&qov->stack)) {
+/* Stack was empty, track this object as root */
 qmp_output_push_obj(qov, value);
 return;
 }
@@ -98,13 +116,17 @@ static void qmp_output_add_obj(QmpOutputVisitor *qov, 
const char *name,

 switch (qobject_type(cur)) {
 case QTYPE_QDICT:
+assert(name);
 qdict_put_obj(qobject_to_qdict(cur), name, value);
 break;
 case QTYPE_QLIST:
 qlist_append_obj(qobject_to_qlist(cur), value);
 break;
 default:
+/* The previous root was a scalar, replace it with a new root */
+/* FIXME this is abusing the stack; see comment above */
 qobject_decref(qmp_output_pop(qov));
+assert(QTAILQ_EMPTY(&qov->stack));
 qmp_output_push_obj(qov, value);
 break;
 }
@@ -205,11 +227,14 @@ static void qmp_output_type_any(Visitor *v, QObject 
**obj, const char *name,
 qmp_output_add_obj(qov, name, *obj)

[Qemu-devel] [PATCH v7 16/31] qmp: Don't abuse stack to track qmp-output root

2015-12-07 Thread Eric Blake
The previous commit documented an inconsistency in how we are
using the stack of qmp-output-visitor.  Normally, pushing a
single top-level object puts the object on the stack twice:
once as the root, and once as the current container being
appended to; but popping that struct only pops once.  However,
qmp_ouput_add() was trying to either set up the added object
as the new root (works if you parse two top-level scalars in a
row: the second replaces the first as the root) or as a member
of the current container (works as long as you have an open
container on the stack; but if you have popped the first
top-level container, it then resolves to the root and still
tries to add into that existing container).

Fix the stupidity by not tracking two separate things in the
stack.  Drop the now-useless qmp_output_first() while at it.

Saved for a later patch: we still are rather sloppy in that
qmp_output_get_object() can be called in the middle of a parse,
rather than requiring that a visit is complete.

Signed-off-by: Eric Blake 

---
v7: retitle; rebase to earlier changes, drop qmp_output_first()
v6: no change
---
 qapi/qmp-output-visitor.c | 79 ---
 1 file changed, 26 insertions(+), 53 deletions(-)

diff --git a/qapi/qmp-output-visitor.c b/qapi/qmp-output-visitor.c
index 77097b7..06ee19b 100644
--- a/qapi/qmp-output-visitor.c
+++ b/qapi/qmp-output-visitor.c
@@ -29,16 +29,8 @@ typedef QTAILQ_HEAD(QStack, QStackEntry) QStack;
 struct QmpOutputVisitor
 {
 Visitor visitor;
-/* FIXME: we are abusing stack to hold two separate pieces of
- * information: the current root object in slot 0, and the stack
- * of N objects still being built in slots 1 through N (for N+1
- * slots in use).  Worse, our behavior is inconsistent:
- * qmp_output_add_obj() visiting two top-level scalars in a row
- * discards the first in favor of the second, but visiting two
- * top-level objects in a row tries to append the second object
- * into the first (since the first object was placed in the stack
- * in both slot 0 and 1, but only popped from slot 1).  */
-QStack stack;
+QStack stack; /* Stack of containers that haven't yet been finished */
+QObject *root; /* Root of the output visit */
 };

 #define qmp_output_add(qov, name, value) \
@@ -55,6 +47,7 @@ static void qmp_output_push_obj(QmpOutputVisitor *qov, 
QObject *value)
 {
 QStackEntry *e = g_malloc0(sizeof(*e));

+assert(qov->root);
 assert(value);
 e->value = value;
 if (qobject_type(e->value) == QTYPE_QLIST) {
@@ -76,26 +69,12 @@ static QObject *qmp_output_pop(QmpOutputVisitor *qov)
 return value;
 }

-/* Grab the root QObject, if any, in preparation to empty the stack */
-static QObject *qmp_output_first(QmpOutputVisitor *qov)
-{
-QStackEntry *e = QTAILQ_LAST(&qov->stack, QStack);
-
-if (!e) {
-/* No root */
-return NULL;
-}
-assert(e->value);
-return e->value;
-}
-
-/* Grab the most recent QObject from the stack, which must exist */
+/* Grab the most recent QObject from the stack, if any */
 static QObject *qmp_output_last(QmpOutputVisitor *qov)
 {
 QStackEntry *e = QTAILQ_FIRST(&qov->stack);

-assert(e && e->value);
-return e->value;
+return e ? e->value : NULL;
 }

 /* Add @value to the current QObject being built.
@@ -106,29 +85,25 @@ static void qmp_output_add_obj(QmpOutputVisitor *qov, 
const char *name,
 {
 QObject *cur;

-if (QTAILQ_EMPTY(&qov->stack)) {
-/* Stack was empty, track this object as root */
-qmp_output_push_obj(qov, value);
-return;
-}
-
 cur = qmp_output_last(qov);

-switch (qobject_type(cur)) {
-case QTYPE_QDICT:
-assert(name);
-qdict_put_obj(qobject_to_qdict(cur), name, value);
-break;
-case QTYPE_QLIST:
-qlist_append_obj(qobject_to_qlist(cur), value);
-break;
-default:
-/* The previous root was a scalar, replace it with a new root */
-/* FIXME this is abusing the stack; see comment above */
-qobject_decref(qmp_output_pop(qov));
-assert(QTAILQ_EMPTY(&qov->stack));
-qmp_output_push_obj(qov, value);
-break;
+if (!cur) {
+/* FIXME we should require the user to reset the visitor, rather
+ * than throwing away the previous root */
+qobject_decref(qov->root);
+qov->root = value;
+} else {
+switch (qobject_type(cur)) {
+case QTYPE_QDICT:
+assert(name);
+qdict_put_obj(qobject_to_qdict(cur), name, value);
+break;
+case QTYPE_QLIST:
+qlist_append_obj(qobject_to_qlist(cur), value);
+break;
+default:
+g_assert_not_reached();
+}
 }
 }

@@ -230,7 +205,9 @@ static void qmp_output_type_any(Visitor *v, QObject **obj, 
const char *name,
 /* Finish building, and return the root object. Will not be NULL. */
 QObject 

[Qemu-devel] [PATCH v7 09/31] qapi: Prefer type_int64 over type_int in visitors

2015-12-07 Thread Eric Blake
The qapi builtin type 'int' is basically shorthand for the type
'int64'.  In fact, since no visitor was providing the optional
type_int64() callback, visit_type_int64() was just always falling
back to type_int(), cementing the equivalence between the types.

However, some visitors are providing a type_uint64() callback.
For purposes of code consistency, it is nicer if all visitors
use the paired type_int64/type_uint64 names rather than the
mismatched type_int/type_uint64.  So this patch just renames
the signed int callbacks in place, dropping the type_int()
callback as redundant, and a later patch will focus on the
unsigned int callbacks.

Add some FIXMEs to questionable reuse of errp in code touched
by the rename, while at it (the reuse works as long as the
callbacks don't modify value when setting an error, but it's not
a good example to set).

No change in functionality here, although further cleanups are
in the pipeline.

Signed-off-by: Eric Blake 

---
v7: split off of 1/23 and 2/23 for easier-to-read diffs
---
 include/qapi/visitor-impl.h  |  1 -
 qapi/opts-visitor.c  |  4 ++--
 qapi/qapi-dealloc-visitor.c  |  6 +++---
 qapi/qapi-visit-core.c   | 36 ++--
 qapi/qmp-input-visitor.c |  6 +++---
 qapi/qmp-output-visitor.c|  6 +++---
 qapi/string-input-visitor.c  |  6 +++---
 qapi/string-output-visitor.c |  6 +++---
 8 files changed, 39 insertions(+), 32 deletions(-)

diff --git a/include/qapi/visitor-impl.h b/include/qapi/visitor-impl.h
index 44a21b7..70326e0 100644
--- a/include/qapi/visitor-impl.h
+++ b/include/qapi/visitor-impl.h
@@ -36,7 +36,6 @@ struct Visitor
 void (*get_next_type)(Visitor *v, QType *type, bool promote_int,
   const char *name, Error **errp);

-void (*type_int)(Visitor *v, int64_t *obj, const char *name, Error **errp);
 void (*type_bool)(Visitor *v, bool *obj, const char *name, Error **errp);
 void (*type_str)(Visitor *v, char **obj, const char *name, Error **errp);
 void (*type_number)(Visitor *v, double *obj, const char *name,
diff --git a/qapi/opts-visitor.c b/qapi/opts-visitor.c
index dd4094c..56c798f 100644
--- a/qapi/opts-visitor.c
+++ b/qapi/opts-visitor.c
@@ -360,7 +360,7 @@ opts_type_bool(Visitor *v, bool *obj, const char *name, 
Error **errp)


 static void
-opts_type_int(Visitor *v, int64_t *obj, const char *name, Error **errp)
+opts_type_int64(Visitor *v, int64_t *obj, const char *name, Error **errp)
 {
 OptsVisitor *ov = to_ov(v);
 const QemuOpt *opt;
@@ -528,7 +528,7 @@ opts_visitor_new(const QemuOpts *opts)
  */
 ov->visitor.type_enum = &input_type_enum;

-ov->visitor.type_int= &opts_type_int;
+ov->visitor.type_int64  = &opts_type_int64;
 ov->visitor.type_uint64 = &opts_type_uint64;
 ov->visitor.type_size   = &opts_type_size;
 ov->visitor.type_bool   = &opts_type_bool;
diff --git a/qapi/qapi-dealloc-visitor.c b/qapi/qapi-dealloc-visitor.c
index 204de8f..e9b9f3f 100644
--- a/qapi/qapi-dealloc-visitor.c
+++ b/qapi/qapi-dealloc-visitor.c
@@ -135,8 +135,8 @@ static void qapi_dealloc_type_str(Visitor *v, char **obj, 
const char *name,
 }
 }

-static void qapi_dealloc_type_int(Visitor *v, int64_t *obj, const char *name,
-  Error **errp)
+static void qapi_dealloc_type_int64(Visitor *v, int64_t *obj, const char *name,
+Error **errp)
 {
 }

@@ -219,7 +219,7 @@ QapiDeallocVisitor *qapi_dealloc_visitor_new(void)
 v->visitor.next_list = qapi_dealloc_next_list;
 v->visitor.end_list = qapi_dealloc_end_list;
 v->visitor.type_enum = qapi_dealloc_type_enum;
-v->visitor.type_int = qapi_dealloc_type_int;
+v->visitor.type_int64 = qapi_dealloc_type_int64;
 v->visitor.type_bool = qapi_dealloc_type_bool;
 v->visitor.type_str = qapi_dealloc_type_str;
 v->visitor.type_number = qapi_dealloc_type_number;
diff --git a/qapi/qapi-visit-core.c b/qapi/qapi-visit-core.c
index 6d63e40..6295fa8 100644
--- a/qapi/qapi-visit-core.c
+++ b/qapi/qapi-visit-core.c
@@ -97,7 +97,7 @@ void visit_type_enum(Visitor *v, int *obj, const char * const 
strings[],

 void visit_type_int(Visitor *v, int64_t *obj, const char *name, Error **errp)
 {
-v->type_int(v, obj, name, errp);
+v->type_int64(v, obj, name, errp);
 }

 void visit_type_uint8(Visitor *v, uint8_t *obj, const char *name, Error **errp)
@@ -108,8 +108,10 @@ void visit_type_uint8(Visitor *v, uint8_t *obj, const char 
*name, Error **errp)
 v->type_uint8(v, obj, name, errp);
 } else {
 value = *obj;
-v->type_int(v, &value, name, errp);
+v->type_int64(v, &value, name, errp);
 if (value < 0 || value > UINT8_MAX) {
+/* FIXME questionable reuse of errp if type_int64() changes
+   value on error */
 error_setg(errp, QERR_INVALID_PARAMETER_VALUE,
name ? name : "null", "uint8_t");
 return;
@@ -126,8 +128,10 @

[Qemu-devel] [PATCH v7 11/31] qapi: Consolidate visitor small integer callbacks

2015-12-07 Thread Eric Blake
Commit 4e27e819 introduced optional visitor callbacks for all
sorts of int types, but no visitor has supplied any of the
callbacks for sizes less than 64 bits.  In other words, the
generic implementation based on using type_[u]int64() followed
by bounds-checking works just fine. In the interest of
simplicity, it's easier to make the visitor callback interface
not have to worry about the other sizes.

Adding some helper functions minimizes the boilerplate required
to correct FIXMEs added earlier with regards to questionable
reuse of errp, particularly now that we can guarantee from a
single file audit that value is unchanged if an error is set.

Signed-off-by: Eric Blake 

---
v7: further factor out helper functions that eliminate the
questionable errp reuse
v6: split off from v5 23/46
original version also appeared in v6-v9 of subset D
---
 include/qapi/visitor-impl.h |  22 +++---
 qapi/qapi-visit-core.c  | 158 +---
 2 files changed, 70 insertions(+), 110 deletions(-)

diff --git a/include/qapi/visitor-impl.h b/include/qapi/visitor-impl.h
index 70326e0..5ee2974 100644
--- a/include/qapi/visitor-impl.h
+++ b/include/qapi/visitor-impl.h
@@ -1,7 +1,7 @@
 /*
  * Core Definitions for QAPI Visitor implementations
  *
- * Copyright (C) 2012 Red Hat, Inc.
+ * Copyright (C) 2012, 2015 Red Hat, Inc.
  *
  * Author: Paolo Bonizni 
  *
@@ -36,6 +36,16 @@ struct Visitor
 void (*get_next_type)(Visitor *v, QType *type, bool promote_int,
   const char *name, Error **errp);

+/* Must be set. */
+void (*type_int64)(Visitor *v, int64_t *obj, const char *name,
+   Error **errp);
+/* Must be set. */
+void (*type_uint64)(Visitor *v, uint64_t *obj, const char *name,
+Error **errp);
+/* Optional; fallback is type_uint64().  */
+void (*type_size)(Visitor *v, uint64_t *obj, const char *name,
+  Error **errp);
+/* Must be set. */
 void (*type_bool)(Visitor *v, bool *obj, const char *name, Error **errp);
 void (*type_str)(Visitor *v, char **obj, const char *name, Error **errp);
 void (*type_number)(Visitor *v, double *obj, const char *name,
@@ -46,16 +56,6 @@ struct Visitor
 /* May be NULL; most useful for input visitors. */
 void (*optional)(Visitor *v, bool *present, const char *name);

-void (*type_uint8)(Visitor *v, uint8_t *obj, const char *name, Error 
**errp);
-void (*type_uint16)(Visitor *v, uint16_t *obj, const char *name, Error 
**errp);
-void (*type_uint32)(Visitor *v, uint32_t *obj, const char *name, Error 
**errp);
-void (*type_uint64)(Visitor *v, uint64_t *obj, const char *name, Error 
**errp);
-void (*type_int8)(Visitor *v, int8_t *obj, const char *name, Error **errp);
-void (*type_int16)(Visitor *v, int16_t *obj, const char *name, Error 
**errp);
-void (*type_int32)(Visitor *v, int32_t *obj, const char *name, Error 
**errp);
-void (*type_int64)(Visitor *v, int64_t *obj, const char *name, Error 
**errp);
-/* visit_type_size() falls back to (*type_uint64)() if type_size is unset 
*/
-void (*type_size)(Visitor *v, uint64_t *obj, const char *name, Error 
**errp);
 bool (*start_union)(Visitor *v, bool data_present, Error **errp);
 void (*end_union)(Visitor *v, bool data_present, Error **errp);
 };
diff --git a/qapi/qapi-visit-core.c b/qapi/qapi-visit-core.c
index 4a8ad43..a48fd4e 100644
--- a/qapi/qapi-visit-core.c
+++ b/qapi/qapi-visit-core.c
@@ -100,129 +100,89 @@ void visit_type_int(Visitor *v, int64_t *obj, const char 
*name, Error **errp)
 v->type_int64(v, obj, name, errp);
 }

+static void visit_type_uintN(Visitor *v, uint64_t *obj, const char *name,
+ uint64_t max, const char *type, Error **errp)
+{
+Error *err = NULL;
+uint64_t value = *obj;
+
+v->type_uint64(v, &value, name, &err);
+if (err) {
+error_propagate(errp, err);
+} else if (value > max) {
+error_setg(errp, QERR_INVALID_PARAMETER_VALUE,
+   name ? name : "null", type);
+} else {
+*obj = value;
+}
+}
+
 void visit_type_uint8(Visitor *v, uint8_t *obj, const char *name, Error **errp)
 {
-uint64_t value;
-
-if (v->type_uint8) {
-v->type_uint8(v, obj, name, errp);
-} else {
-value = *obj;
-v->type_uint64(v, &value, name, errp);
-if (value > UINT8_MAX) {
-/* FIXME questionable reuse of errp if type_uint64() changes
-   value on error */
-error_setg(errp, QERR_INVALID_PARAMETER_VALUE,
-   name ? name : "null", "uint8_t");
-return;
-}
-*obj = value;
-}
+uint64_t value = *obj;
+visit_type_uintN(v, &value, name, UINT8_MAX, "uint8_t", errp);
+*obj = value;
 }

-void visit_type_uint16(Visitor *v, uint16_t *obj, const char *name, Error 
**errp)
+void visit_type_uint16(Visitor *v, uint16_t *obj, const 

[Qemu-devel] [PATCH v7 14/31] qapi: Drop unused error argument for list and implicit struct

2015-12-07 Thread Eric Blake
No backend was setting an error when ending the visit of a list
or implicit struct.  Make the callers a bit easier to follow by
making this a part of the contract, and removing the errp
argument - callers can then unconditionally end an object as
part of cleanup without having to think about whether a second
error is dominated by a first, because there is no second error.

A later patch will then tackle the larger task of splitting
visit_end_struct(), which can indeed set an error.

Signed-off-by: Eric Blake 

---
v7: place earlier in series, rebase to earlier changes
v6: new patch, split from RFC on v5 7/46
---
 hw/ppc/spapr_drc.c   |  6 +-
 include/qapi/visitor-impl.h  |  6 --
 include/qapi/visitor.h   |  5 +++--
 qapi/opts-visitor.c  |  2 +-
 qapi/qapi-dealloc-visitor.c  |  4 ++--
 qapi/qapi-visit-core.c   |  8 
 qapi/qmp-input-visitor.c |  9 ++---
 qapi/qmp-output-visitor.c|  2 +-
 qapi/string-input-visitor.c  |  2 +-
 qapi/string-output-visitor.c |  2 +-
 scripts/qapi-visit.py| 10 +++---
 11 files changed, 23 insertions(+), 33 deletions(-)

diff --git a/hw/ppc/spapr_drc.c b/hw/ppc/spapr_drc.c
index 96d06f5..dcce563 100644
--- a/hw/ppc/spapr_drc.c
+++ b/hw/ppc/spapr_drc.c
@@ -314,11 +314,7 @@ static void prop_get_fdt(Object *obj, Visitor *v, void 
*opaque,
 return;
 }
 }
-visit_end_list(v, &err);
-if (err) {
-error_propagate(errp, err);
-return;
-}
+visit_end_list(v);
 break;
 }
 default:
diff --git a/include/qapi/visitor-impl.h b/include/qapi/visitor-impl.h
index 6737005..c3c6323 100644
--- a/include/qapi/visitor-impl.h
+++ b/include/qapi/visitor-impl.h
@@ -24,11 +24,13 @@ struct Visitor

 void (*start_implicit_struct)(Visitor *v, void **obj, size_t size,
   Error **errp);
-void (*end_implicit_struct)(Visitor *v, Error **errp);
+/* May be NULL */
+void (*end_implicit_struct)(Visitor *v);

 void (*start_list)(Visitor *v, const char *name, Error **errp);
 GenericList *(*next_list)(Visitor *v, GenericList **list, Error **errp);
-void (*end_list)(Visitor *v, Error **errp);
+/* Must be set */
+void (*end_list)(Visitor *v);

 void (*type_enum)(Visitor *v, int *obj, const char *const strings[],
   const char *name, Error **errp);
diff --git a/include/qapi/visitor.h b/include/qapi/visitor.h
index 21891ca..21c09b4 100644
--- a/include/qapi/visitor.h
+++ b/include/qapi/visitor.h
@@ -32,10 +32,11 @@ void visit_start_struct(Visitor *v, void **obj, size_t size,
 void visit_end_struct(Visitor *v, Error **errp);
 void visit_start_implicit_struct(Visitor *v, void **obj, size_t size,
  Error **errp);
-void visit_end_implicit_struct(Visitor *v, Error **errp);
+void visit_end_implicit_struct(Visitor *v);
+
 void visit_start_list(Visitor *v, const char *name, Error **errp);
 GenericList *visit_next_list(Visitor *v, GenericList **list, Error **errp);
-void visit_end_list(Visitor *v, Error **errp);
+void visit_end_list(Visitor *v);

 /**
  * Check if an optional member @name of an object needs visiting.
diff --git a/qapi/opts-visitor.c b/qapi/opts-visitor.c
index df5b537..e8c7517 100644
--- a/qapi/opts-visitor.c
+++ b/qapi/opts-visitor.c
@@ -269,7 +269,7 @@ opts_next_list(Visitor *v, GenericList **list, Error **errp)


 static void
-opts_end_list(Visitor *v, Error **errp)
+opts_end_list(Visitor *v)
 {
 OptsVisitor *ov = to_ov(v);

diff --git a/qapi/qapi-dealloc-visitor.c b/qapi/qapi-dealloc-visitor.c
index f4c0a67..e280d9f 100644
--- a/qapi/qapi-dealloc-visitor.c
+++ b/qapi/qapi-dealloc-visitor.c
@@ -83,7 +83,7 @@ static void qapi_dealloc_start_implicit_struct(Visitor *v,
 qapi_dealloc_push(qov, obj);
 }

-static void qapi_dealloc_end_implicit_struct(Visitor *v, Error **errp)
+static void qapi_dealloc_end_implicit_struct(Visitor *v)
 {
 QapiDeallocVisitor *qov = to_qov(v);
 void **obj = qapi_dealloc_pop(qov);
@@ -119,7 +119,7 @@ static GenericList *qapi_dealloc_next_list(Visitor *v, 
GenericList **listp,
 return NULL;
 }

-static void qapi_dealloc_end_list(Visitor *v, Error **errp)
+static void qapi_dealloc_end_list(Visitor *v)
 {
 QapiDeallocVisitor *qov = to_qov(v);
 void *obj = qapi_dealloc_pop(qov);
diff --git a/qapi/qapi-visit-core.c b/qapi/qapi-visit-core.c
index d9ec1cc..3bd5cae 100644
--- a/qapi/qapi-visit-core.c
+++ b/qapi/qapi-visit-core.c
@@ -37,10 +37,10 @@ void visit_start_implicit_struct(Visitor *v, void **obj, 
size_t size,
 }
 }

-void visit_end_implicit_struct(Visitor *v, Error **errp)
+void visit_end_implicit_struct(Visitor *v)
 {
 if (v->end_implicit_struct) {
-v->end_implicit_struct(v, errp);
+v->end_implicit_struct(v);
 }
 }

@@ -54,9 +54,9 @@ GenericList *visit_next_list(Visitor *v, GenericList **list, 
Error

[Qemu-devel] [PATCH v7 08/31] qapi: Track all failures between visit_start/stop

2015-12-07 Thread Eric Blake
Inside the generated code between visit_start_struct() and
visit_end_struct(), we were blindly setting the error into
the caller's errp parameter.  But a future patch to split
visit_end_struct() will require that we take action based
on whether an error has occurred, which requires us to track
all actions through a local err.  Rewrite the visits to be
more in line with the other generated calls.

Signed-off-by: Eric Blake 

---
v7: place earlier in series
v6: based loosely on v5 7/46, but mostly a rewrite to get the last
generated code in the same form as all the others, so that the
later conversion to split visit_check_struct() will be easier
---
 scripts/qapi-visit.py | 16 +++-
 1 file changed, 11 insertions(+), 5 deletions(-)

diff --git a/scripts/qapi-visit.py b/scripts/qapi-visit.py
index b93690b..4a4f67d 100644
--- a/scripts/qapi-visit.py
+++ b/scripts/qapi-visit.py
@@ -123,12 +123,18 @@ void visit_type_%(c_name)s(Visitor *v, %(c_name)s **obj, 
const char *name, Error
 Error *err = NULL;

 visit_start_struct(v, (void **)obj, "%(name)s", name, sizeof(%(c_name)s), 
&err);
-if (!err) {
-if (*obj) {
-visit_type_%(c_name)s_fields(v, obj, errp);
-}
-visit_end_struct(v, &err);
+if (err) {
+goto out;
 }
+if (!*obj) {
+goto out_obj;
+}
+visit_type_%(c_name)s_fields(v, obj, &err);
+out_obj:
+error_propagate(errp, err);
+err = NULL;
+visit_end_struct(v, &err);
+out:
 error_propagate(errp, err);
 }
 ''',
-- 
2.4.3




[Qemu-devel] [PATCH v7 07/31] qapi: Improve generated event use of qapi visitor

2015-12-07 Thread Eric Blake
All other successful clients of visit_start_struct() were paired
with an unconditional visit_end_struct(); but the generated
code for events was relying on qmp_output_visitor_cleanup() to
work on an incomplete visit.  Alter the code to guarantee that
the struct is completed, which will make a future patch to
split visit_end_struct() easier to reason about.  While at it,
drop some assertions and comments that are not present in other
uses of the qmp output visitor, rearrange the declaration to
make it easier for a future patch to introduce the notion of
a boxed event visit, and pass NULL rather than "" as the 'kind'
parameter (matching most other uses where obj is NULL).

Signed-off-by: Eric Blake 

---
v7: place earlier in series, adjust handling of 'kind'
v6: new patch

If desired, I can defer the hunk re-ordering the declaration of
obj to later in the series where it actually comes in handy.
---
 scripts/qapi-event.py | 14 ++
 scripts/qapi.py   |  5 +++--
 2 files changed, 9 insertions(+), 10 deletions(-)

diff --git a/scripts/qapi-event.py b/scripts/qapi-event.py
index 720486f..e37c07a 100644
--- a/scripts/qapi-event.py
+++ b/scripts/qapi-event.py
@@ -41,9 +41,9 @@ def gen_event_send(name, arg_type):

 if arg_type and arg_type.members:
 ret += mcgen('''
+QObject *obj;
 QmpOutputVisitor *qov;
 Visitor *v;
-QObject *obj;

 ''')

@@ -61,25 +61,23 @@ def gen_event_send(name, arg_type):
 if arg_type and arg_type.members:
 ret += mcgen('''
 qov = qmp_output_visitor_new();
-g_assert(qov);
-
 v = qmp_output_get_visitor(qov);
-g_assert(v);

-/* Fake visit, as if all members are under a structure */
-visit_start_struct(v, NULL, "", "%(name)s", 0, &err);
+visit_start_struct(v, NULL, NULL, "%(name)s", 0, &err);
 ''',
  name=name)
 ret += gen_err_check()
-ret += gen_visit_fields(arg_type.members, need_cast=True)
+ret += gen_visit_fields(arg_type.members, need_cast=True,
+label='out_obj')
 ret += mcgen('''
+out_obj:
 visit_end_struct(v, &err);
 if (err) {
 goto out;
 }

 obj = qmp_output_get_qobject(qov);
-g_assert(obj != NULL);
+g_assert(obj);

 qdict_put_obj(qmp, "data", obj);
 ''')
diff --git a/scripts/qapi.py b/scripts/qapi.py
index 7dec611..497eaba 100644
--- a/scripts/qapi.py
+++ b/scripts/qapi.py
@@ -1636,7 +1636,8 @@ def gen_err_check(label='out', skiperr=False):
  label=label)


-def gen_visit_fields(members, prefix='', need_cast=False, skiperr=False):
+def gen_visit_fields(members, prefix='', need_cast=False, skiperr=False,
+ label='out'):
 ret = ''
 if skiperr:
 errparg = 'NULL'
@@ -1664,7 +1665,7 @@ def gen_visit_fields(members, prefix='', need_cast=False, 
skiperr=False):
  c_type=memb.type.c_name(), prefix=prefix, cast=cast,
  c_name=c_name(memb.name), name=memb.name,
  errp=errparg)
-ret += gen_err_check(skiperr=skiperr)
+ret += gen_err_check(skiperr=skiperr, label=label)

 if memb.optional:
 pop_indent()
-- 
2.4.3




[Qemu-devel] [PATCH v7 18/31] qapi: Add visit_type_null() visitor

2015-12-07 Thread Eric Blake
Right now, qmp-output-visitor happens to produce a QNull result
if nothing is actually visited between the creation of the visitor
and the request for the resulting QObject.  A stronger protocol
would require that a QMP output visit MUST visit something.  But
to still be able to produce a JSON 'null' output, we need a new
visitor function that states our intentions.

This patch introduces the new visit_type_null() interface, and
a later patch will then wire it up into the qmp output visitor.

Signed-off-by: Eric Blake 

---
v7: new patch, based on discussion about spapr_drc.c
---
 include/qapi/visitor-impl.h | 3 +++
 include/qapi/visitor.h  | 8 
 qapi/qapi-dealloc-visitor.c | 5 +
 qapi/qapi-visit-core.c  | 5 +
 4 files changed, 21 insertions(+)

diff --git a/include/qapi/visitor-impl.h b/include/qapi/visitor-impl.h
index 27f776f..78a5ab1 100644
--- a/include/qapi/visitor-impl.h
+++ b/include/qapi/visitor-impl.h
@@ -75,6 +75,9 @@ struct Visitor
  * visitors do not currently visit arbitrary types).  */
 void (*type_any)(Visitor *v, QObject **obj, const char *name,
  Error **errp);
+/* Must be provided to visit explicit null values (right now, only the
+ * dealloc visitor supports this).  */
+void (*type_null)(Visitor *v, const char *name, Error **errp);

 /* May be NULL; most useful for input visitors. */
 void (*optional)(Visitor *v, bool *present, const char *name);
diff --git a/include/qapi/visitor.h b/include/qapi/visitor.h
index 96a9535..2592dd1 100644
--- a/include/qapi/visitor.h
+++ b/include/qapi/visitor.h
@@ -267,6 +267,14 @@ void visit_type_number(Visitor *v, double *obj, const char 
*name,
 void visit_type_any(Visitor *v, QObject **obj, const char *name, Error **errp);

 /**
+ * Visit a JSON null value tied to @name in the current object visit.
+ * @name will be NULL if this is visited as part of a list.
+ * No obj parameter is needed; rather, this is a witness that an
+ * explicit null value is expected rather than any other type.
+ */
+void visit_type_null(Visitor *v, const char *name, Error **errp);
+
+/**
  * Mark the start of visiting the branches of a union. Return true if
  * @data_present.
  * FIXME: Should not be needed
diff --git a/qapi/qapi-dealloc-visitor.c b/qapi/qapi-dealloc-visitor.c
index e280d9f..e3a4493 100644
--- a/qapi/qapi-dealloc-visitor.c
+++ b/qapi/qapi-dealloc-visitor.c
@@ -162,6 +162,10 @@ static void qapi_dealloc_type_anything(Visitor *v, QObject 
**obj,
 }
 }

+static void qapi_dealloc_type_null(Visitor *v, const char *name, Error **errp)
+{
+}
+
 static void qapi_dealloc_type_enum(Visitor *v, int *obj,
const char *const strings[],
const char *name, Error **errp)
@@ -223,6 +227,7 @@ QapiDeallocVisitor *qapi_dealloc_visitor_new(void)
 v->visitor.type_str = qapi_dealloc_type_str;
 v->visitor.type_number = qapi_dealloc_type_number;
 v->visitor.type_any = qapi_dealloc_type_anything;
+v->visitor.type_null = qapi_dealloc_type_null;
 v->visitor.start_union = qapi_dealloc_start_union;

 QTAILQ_INIT(&v->stack);
diff --git a/qapi/qapi-visit-core.c b/qapi/qapi-visit-core.c
index 042ef07..36917f3 100644
--- a/qapi/qapi-visit-core.c
+++ b/qapi/qapi-visit-core.c
@@ -257,6 +257,11 @@ void visit_type_any(Visitor *v, QObject **obj, const char 
*name,
 v->type_any(v, obj, name, errp);
 }

+void visit_type_null(Visitor *v, const char *name, Error **errp)
+{
+v->type_null(v, name, errp);
+}
+
 void output_type_enum(Visitor *v, int *obj, const char *const strings[],
   const char *name, Error **errp)
 {
-- 
2.4.3




[Qemu-devel] [PATCH v7 12/31] qapi: Don't cast Enum* to int*

2015-12-07 Thread Eric Blake
C compilers are allowed to represent enums as a smaller type
than int, if all enum values fit in the smaller type.  There
are even compiler flags that force the use of this smaller
representation, and using them changes the ABI of a binary.
Therefore, our generated code for visit_type_ENUM() (for all
qapi enums) was wrong for casting Enum* to int* when calling
visit_type_enum().

It appears that no one has been doing this for qemu, because
if they had, we are potentially dereferencing beyond bounds
or even risking a SIGBUS on platforms where unaligned pointer
dereferencing is fatal.  Better is to avoid the practice
entirely, and just use the correct types.

This matches the fix for alternate qapi types, done earlier in
"qapi: Simplify visiting of alternate types".

Signed-off-by: Eric Blake 

---
v7: rebase on typo fix
v6: new patch
---
 scripts/qapi-visit.py | 5 +++--
 1 file changed, 3 insertions(+), 2 deletions(-)

diff --git a/scripts/qapi-visit.py b/scripts/qapi-visit.py
index 4a4f67d..6bd188b 100644
--- a/scripts/qapi-visit.py
+++ b/scripts/qapi-visit.py
@@ -178,12 +178,13 @@ out:


 def gen_visit_enum(name):
-# FIXME cast from enum *obj to int * invalidly assumes enum is int
 return mcgen('''

 void visit_type_%(c_name)s(Visitor *v, %(c_name)s *obj, const char *name, 
Error **errp)
 {
-visit_type_enum(v, (int *)obj, %(c_name)s_lookup, "%(name)s", name, errp);
+int tmp = *obj;
+visit_type_enum(v, &tmp, %(c_name)s_lookup, "%(name)s", name, errp);
+*obj = tmp;
 }
 ''',
  c_name=c_name(name), name=name)
-- 
2.4.3




[Qemu-devel] [PATCH v7 00/31] qapi visitor cleanups (post-introspection cleanups subset E)

2015-12-07 Thread Eric Blake
Pending prerequisites:
+ Markus' qapi-not-next branch (including my subset D patches)
http://repo.or.cz/qemu/armbru.git/shortlog/refs/heads/qapi-not-next
https://lists.gnu.org/archive/html/qemu-devel/2015-12/msg00463.html

Also available as a tag at this location:
git fetch git://repo.or.cz/qemu/ericb.git qapi-cleanupv7e

and will soon be part of my branch with the rest of the v5 series, at:
http://repo.or.cz/qemu/ericb.git/shortlog/refs/heads/qapi

v7 notes:
Rearrange several patches (trying to float the obvious ones up
front, moving hunks between patches to make review easier), and
add several new patches.  In particular, I'm quite pleased with
how 29/31 turned out as a new patch for simplifying visitor
semantics; and 18-20 address an issue that caused some last-minute
flurry before 2.5-rc3.

Patch 31 is marked RFC because it might be overkill; when I first
conceived it, I thought a simple change to qapi-types.py and
GenericList in visitor.h would be enough to save memory; until
valgrind reminded me that if sizeof(GenericList) shrinks and
becomes variably-sized, I have to start passing sizes around.  The
additional changes to visit_start_list() and visit_next_list()
didn't turn out as lean as I had hoped, so I'm okay if we ditch
that patch.

I'm very seriously considering writing a new JSON output visitor,
so that we can go straight from qapi to JSON without having to go
through an intermediate QObject tree, and as proof that the visitor
interface is starting to be better documented.  But I guess I should
first focus on getting my subset F patches ready to go (we still
want to get netdev_add introspectible), since those have at least
been on list before.

Some patch retitling makes the backport-diff claim more new patches
than there actually are.

001/31:[down] 'qobject: Document more shortcomings in our number handling'
002/31:[down] 'qapi: Avoid use of misnamed DO_UPCAST()'
003/31:[down] 'qapi: Drop dead dealloc visitor variable'
004/31:[0008] [FC] 'hmp: Improve use of qapi visitor'
005/31:[0012] [FC] 'vl: Improve use of qapi visitor'
006/31:[] [--] 'balloon: Improve use of qapi visitor'
007/31:[0007] [FC] 'qapi: Improve generated event use of qapi visitor'
008/31:[] [--] 'qapi: Track all failures between visit_start/stop'
009/31:[down] 'qapi: Prefer type_int64 over type_int in visitors'
010/31:[down] 'qapi: Make all visitors supply uint64 callbacks'
011/31:[down] 'qapi: Consolidate visitor small integer callbacks'
012/31:[0002] [FC] 'qapi: Don't cast Enum* to int*'
013/31:[down] 'qapi: Drop unused 'kind' for struct/enum visit'
014/31:[0013] [FC] 'qapi: Drop unused error argument for list and implicit 
struct'
015/31:[0021] [FC] 'qmp: Fix reference-counting of qnull on empty output visit'
016/31:[down] 'qmp: Don't abuse stack to track qmp-output root'
017/31:[down] 'qapi: Document visitor interfaces, add assertions'
018/31:[down] 'qapi: Add visit_type_null() visitor'
019/31:[down] 'qmp: Tighten output visitor rules'
020/31:[down] 'spapr_drc: Expose 'null' in qom-get when there is no fdt'
021/31:[down] 'qapi: Simplify excess input reporting in input visitors'
022/31:[] [-C] 'qapi: Add type.is_empty() helper'
023/31:[] [--] 'qapi: Fix command with named empty argument type'
024/31:[0020] [FC] 'qapi: Eliminate empty visit_type_FOO_fields'
025/31:[0002] [FC] 'qapi: Canonicalize missing object to :empty'
026/31:[0002] [FC] 'qapi-visit: Unify struct and union visit'
027/31:[0002] [FC] 'qapi: Rework deallocation of partial struct'
028/31:[0030] [FC] 'qapi: Split visit_end_struct() into pieces'
029/31:[down] 'qapi: Simplify semantics of visit_next_list()'
030/31:[0154] [FC] 'qapi: Change visit_type_FOO() to no longer return partial 
objects'
031/31:[down] 'RFC: qapi: Adjust layout of FooList types

v6 notes:
https://lists.gnu.org/archive/html/qemu-devel/2015-11/msg05793.html
My set of patches related to qapi visitors has grown, and it's time
that I post it on list again.  Of course, since this is all 2.6
material, and there's already lots of patches earlier in the queue,
I may need a v7 to pick up rebase changes.

A lot of the new patches in this series are based on fallout from
implementing an early RFC posted against a v5 review:
https://lists.gnu.org/archive/html/qemu-devel/2015-09/msg06878.html

v5 and earlier - look in the mail archives :)

Eric Blake (31):
  qobject: Document more shortcomings in our number handling
  qapi: Avoid use of misnamed DO_UPCAST()
  qapi: Drop dead dealloc visitor variable
  hmp: Improve use of qapi visitor
  vl: Improve use of qapi visitor
  balloon: Improve use of qapi visitor
  qapi: Improve generated event use of qapi visitor
  qapi: Track all failures between visit_start/stop
  qapi: Prefer type_int64 over type_int in visitors
  qapi: Make all visitors supply uint64 callbacks
  qapi: Consolidate visitor small integer callbacks
  qapi: Don't cast Enum* to int*
  qapi: Drop unused 'kind' for struct/enum visit
  qapi: Drop unused error argument for list and im

[Qemu-devel] [PATCH v7 10/31] qapi: Make all visitors supply uint64 callbacks

2015-12-07 Thread Eric Blake
Our qapi visitor contract supports multiple integer visitors,
but left the type_uint64 visitor as optional (falling back on
type_int64); it also marks the type_size visitor as optional
(falling back on type_uint64 or even type_int64).

Note that the default of falling back on type_int for unsigned
visitors can cause confusing results for values larger than
INT64_MAX (such as having to pass in a negative 2s complement
value on input, and getting a negative result on output).

This patch does not fully address the disparity in handling
large values as negatives, but does move towards a cleaner
situation where EVERY visitor provides both type_int64 and
type_uint64 variants as entry points; then each client can
either implement sane differences between the two, or document
in place with a FIXME that there is munging going on.

The dealloc visitor no longer needs a type_size callback,
since that now safely falls back to the type_uint64 callback.

Then, in qapi-visit-core.c, we can now use the guaranteed
type_uint64 callback as the fallback for all smaller unsigned
int visits.

Signed-off-by: Eric Blake 

---
v7: split off int64 callbacks and retitle, add more FIXMEs in the
code, hoist use of type_uint64 here from 3/23, improved commit
message
v6: new patch, but stems from v5 23/46
---
 qapi/qapi-dealloc-visitor.c  | 12 ++--
 qapi/qapi-visit-core.c   | 42 ++
 qapi/qmp-input-visitor.c | 17 +
 qapi/qmp-output-visitor.c|  9 +
 qapi/string-input-visitor.c  | 15 +++
 qapi/string-output-visitor.c |  9 +
 6 files changed, 70 insertions(+), 34 deletions(-)

diff --git a/qapi/qapi-dealloc-visitor.c b/qapi/qapi-dealloc-visitor.c
index e9b9f3f..11eb828 100644
--- a/qapi/qapi-dealloc-visitor.c
+++ b/qapi/qapi-dealloc-visitor.c
@@ -140,6 +140,11 @@ static void qapi_dealloc_type_int64(Visitor *v, int64_t 
*obj, const char *name,
 {
 }

+static void qapi_dealloc_type_uint64(Visitor *v, uint64_t *obj,
+ const char *name, Error **errp)
+{
+}
+
 static void qapi_dealloc_type_bool(Visitor *v, bool *obj, const char *name,
Error **errp)
 {
@@ -158,11 +163,6 @@ static void qapi_dealloc_type_anything(Visitor *v, QObject 
**obj,
 }
 }

-static void qapi_dealloc_type_size(Visitor *v, uint64_t *obj, const char *name,
-   Error **errp)
-{
-}
-
 static void qapi_dealloc_type_enum(Visitor *v, int *obj,
const char * const strings[],
const char *kind, const char *name,
@@ -220,11 +220,11 @@ QapiDeallocVisitor *qapi_dealloc_visitor_new(void)
 v->visitor.end_list = qapi_dealloc_end_list;
 v->visitor.type_enum = qapi_dealloc_type_enum;
 v->visitor.type_int64 = qapi_dealloc_type_int64;
+v->visitor.type_uint64 = qapi_dealloc_type_uint64;
 v->visitor.type_bool = qapi_dealloc_type_bool;
 v->visitor.type_str = qapi_dealloc_type_str;
 v->visitor.type_number = qapi_dealloc_type_number;
 v->visitor.type_any = qapi_dealloc_type_anything;
-v->visitor.type_size = qapi_dealloc_type_size;
 v->visitor.start_union = qapi_dealloc_start_union;

 QTAILQ_INIT(&v->stack);
diff --git a/qapi/qapi-visit-core.c b/qapi/qapi-visit-core.c
index 6295fa8..4a8ad43 100644
--- a/qapi/qapi-visit-core.c
+++ b/qapi/qapi-visit-core.c
@@ -102,15 +102,15 @@ void visit_type_int(Visitor *v, int64_t *obj, const char 
*name, Error **errp)

 void visit_type_uint8(Visitor *v, uint8_t *obj, const char *name, Error **errp)
 {
-int64_t value;
+uint64_t value;

 if (v->type_uint8) {
 v->type_uint8(v, obj, name, errp);
 } else {
 value = *obj;
-v->type_int64(v, &value, name, errp);
-if (value < 0 || value > UINT8_MAX) {
-/* FIXME questionable reuse of errp if type_int64() changes
+v->type_uint64(v, &value, name, errp);
+if (value > UINT8_MAX) {
+/* FIXME questionable reuse of errp if type_uint64() changes
value on error */
 error_setg(errp, QERR_INVALID_PARAMETER_VALUE,
name ? name : "null", "uint8_t");
@@ -122,15 +122,15 @@ void visit_type_uint8(Visitor *v, uint8_t *obj, const 
char *name, Error **errp)

 void visit_type_uint16(Visitor *v, uint16_t *obj, const char *name, Error 
**errp)
 {
-int64_t value;
+uint64_t value;

 if (v->type_uint16) {
 v->type_uint16(v, obj, name, errp);
 } else {
 value = *obj;
-v->type_int64(v, &value, name, errp);
-if (value < 0 || value > UINT16_MAX) {
-/* FIXME questionable reuse of errp if type_int64() changes
+v->type_uint64(v, &value, name, errp);
+if (value > UINT16_MAX) {
+/* FIXME questionable reuse of errp if type_uint64() changes
value on error */
 error_setg(errp, QERR_INVALID_P

[Qemu-devel] [PATCH v7 02/31] qapi: Avoid use of misnamed DO_UPCAST()

2015-12-07 Thread Eric Blake
The macro DO_UPCAST() is incorrectly named: it converts from a
parent class to a derived class (which is a downcast).  Better,
and more consistent with some of the other qapi visitors, is
to use the container_of() macro through a to_FOO() helper.

Our current definition of container_of() is weaker than
DO_UPCAST(), in that it does not require the derived class to
have Visitor * as its first member, but this does not hurt our
usage patterns in qapi visitors.

Signed-off-by: Eric Blake 

---
v7: new patch
---
 qapi/opts-visitor.c  | 28 +---
 qapi/string-input-visitor.c  | 23 ++-
 qapi/string-output-visitor.c | 21 +
 3 files changed, 44 insertions(+), 28 deletions(-)

diff --git a/qapi/opts-visitor.c b/qapi/opts-visitor.c
index ef5fb8b..dd4094c 100644
--- a/qapi/opts-visitor.c
+++ b/qapi/opts-visitor.c
@@ -89,6 +89,12 @@ struct OptsVisitor
 };


+static OptsVisitor *to_ov(Visitor *v)
+{
+return container_of(v, OptsVisitor, visitor);
+}
+
+
 static void
 destroy_list(gpointer list)
 {
@@ -121,7 +127,7 @@ static void
 opts_start_struct(Visitor *v, void **obj, const char *kind,
   const char *name, size_t size, Error **errp)
 {
-OptsVisitor *ov = DO_UPCAST(OptsVisitor, visitor, v);
+OptsVisitor *ov = to_ov(v);
 const QemuOpt *opt;

 if (obj) {
@@ -160,7 +166,7 @@ ghr_true(gpointer ign_key, gpointer ign_value, gpointer 
ign_user_data)
 static void
 opts_end_struct(Visitor *v, Error **errp)
 {
-OptsVisitor *ov = DO_UPCAST(OptsVisitor, visitor, v);
+OptsVisitor *ov = to_ov(v);
 GQueue *any;

 if (--ov->depth > 0) {
@@ -202,7 +208,7 @@ lookup_distinct(const OptsVisitor *ov, const char *name, 
Error **errp)
 static void
 opts_start_list(Visitor *v, const char *name, Error **errp)
 {
-OptsVisitor *ov = DO_UPCAST(OptsVisitor, visitor, v);
+OptsVisitor *ov = to_ov(v);

 /* we can't traverse a list in a list */
 assert(ov->list_mode == LM_NONE);
@@ -216,7 +222,7 @@ opts_start_list(Visitor *v, const char *name, Error **errp)
 static GenericList *
 opts_next_list(Visitor *v, GenericList **list, Error **errp)
 {
-OptsVisitor *ov = DO_UPCAST(OptsVisitor, visitor, v);
+OptsVisitor *ov = to_ov(v);
 GenericList **link;

 switch (ov->list_mode) {
@@ -265,7 +271,7 @@ opts_next_list(Visitor *v, GenericList **list, Error **errp)
 static void
 opts_end_list(Visitor *v, Error **errp)
 {
-OptsVisitor *ov = DO_UPCAST(OptsVisitor, visitor, v);
+OptsVisitor *ov = to_ov(v);

 assert(ov->list_mode == LM_STARTED ||
ov->list_mode == LM_IN_PROGRESS ||
@@ -307,7 +313,7 @@ processed(OptsVisitor *ov, const char *name)
 static void
 opts_type_str(Visitor *v, char **obj, const char *name, Error **errp)
 {
-OptsVisitor *ov = DO_UPCAST(OptsVisitor, visitor, v);
+OptsVisitor *ov = to_ov(v);
 const QemuOpt *opt;

 opt = lookup_scalar(ov, name, errp);
@@ -323,7 +329,7 @@ opts_type_str(Visitor *v, char **obj, const char *name, 
Error **errp)
 static void
 opts_type_bool(Visitor *v, bool *obj, const char *name, Error **errp)
 {
-OptsVisitor *ov = DO_UPCAST(OptsVisitor, visitor, v);
+OptsVisitor *ov = to_ov(v);
 const QemuOpt *opt;

 opt = lookup_scalar(ov, name, errp);
@@ -356,7 +362,7 @@ opts_type_bool(Visitor *v, bool *obj, const char *name, 
Error **errp)
 static void
 opts_type_int(Visitor *v, int64_t *obj, const char *name, Error **errp)
 {
-OptsVisitor *ov = DO_UPCAST(OptsVisitor, visitor, v);
+OptsVisitor *ov = to_ov(v);
 const QemuOpt *opt;
 const char *str;
 long long val;
@@ -412,7 +418,7 @@ opts_type_int(Visitor *v, int64_t *obj, const char *name, 
Error **errp)
 static void
 opts_type_uint64(Visitor *v, uint64_t *obj, const char *name, Error **errp)
 {
-OptsVisitor *ov = DO_UPCAST(OptsVisitor, visitor, v);
+OptsVisitor *ov = to_ov(v);
 const QemuOpt *opt;
 const char *str;
 unsigned long long val;
@@ -464,7 +470,7 @@ opts_type_uint64(Visitor *v, uint64_t *obj, const char 
*name, Error **errp)
 static void
 opts_type_size(Visitor *v, uint64_t *obj, const char *name, Error **errp)
 {
-OptsVisitor *ov = DO_UPCAST(OptsVisitor, visitor, v);
+OptsVisitor *ov = to_ov(v);
 const QemuOpt *opt;
 int64_t val;
 char *endptr;
@@ -490,7 +496,7 @@ opts_type_size(Visitor *v, uint64_t *obj, const char *name, 
Error **errp)
 static void
 opts_optional(Visitor *v, bool *present, const char *name)
 {
-OptsVisitor *ov = DO_UPCAST(OptsVisitor, visitor, v);
+OptsVisitor *ov = to_ov(v);

 /* we only support a single mandatory scalar field in a list node */
 assert(ov->list_mode == LM_NONE);
diff --git a/qapi/string-input-visitor.c b/qapi/string-input-visitor.c
index dee780a..7f5645b 100644
--- a/qapi/string-input-visitor.c
+++ b/qapi/string-input-visitor.c
@@ -32,6 +32,11 @@ struct StringInputVisitor
 const char *string;
 };

+static StringInputVisitor *to_siv(Visitor *v)
+{
+   

[Qemu-devel] [PATCH v7 01/31] qobject: Document more shortcomings in our number handling

2015-12-07 Thread Eric Blake
We've already documented that our JSON parsing is locale dependent;
but we should also document that our JSON output has the same
problem.  Additionally, JSON requires finite values (you have to
upgrade to JSON5 to get support for Inf or NaN), and our output
risks truncating floating point numbers to the point of losing
significant precision.

Sadly, this series is not going to be the one that addresses these
problems.

Fix some trailing whitespace I noticed in the vicinity.

Signed-off-by: Eric Blake 

---
v7: new patch
---
 qobject/json-parser.c | 4 +++-
 qobject/qjson.c   | 8 +++-
 2 files changed, 10 insertions(+), 2 deletions(-)

diff --git a/qobject/json-parser.c b/qobject/json-parser.c
index 3c5d35d..6ab98a7 100644
--- a/qobject/json-parser.c
+++ b/qobject/json-parser.c
@@ -1,5 +1,5 @@
 /*
- * JSON Parser 
+ * JSON Parser
  *
  * Copyright IBM, Corp. 2009
  *
@@ -519,6 +519,8 @@ static QObject *parse_literal(JSONParserContext *ctxt)
 }
 case JSON_FLOAT:
 /* FIXME dependent on locale */
+/* FIXME our lexer matches RFC7159 in forbidding Inf or NaN,
+ * but those might be useful extensions beyond JSON */
 return QOBJECT(qfloat_from_double(strtod(token->str, NULL)));
 default:
 abort();
diff --git a/qobject/qjson.c b/qobject/qjson.c
index a3e6a7c..41d9d65 100644
--- a/qobject/qjson.c
+++ b/qobject/qjson.c
@@ -237,6 +237,12 @@ static void to_json(const QObject *obj, QString *str, int 
pretty, int indent)
 char buffer[1024];
 int len;

+/* FIXME: snprintf() is locale dependent; but JSON requires
+ * numbers to be formatted as if in the C locale. */
+/* FIXME: This risks printing Inf or NaN, which are not valid
+ * JSON values. */
+/* FIXME: the default precision of %f may be insufficient to
+ * tell this number apart from others. */
 len = snprintf(buffer, sizeof(buffer), "%f", qfloat_get_double(val));
 while (len > 0 && buffer[len - 1] == '0') {
 len--;
@@ -247,7 +253,7 @@ static void to_json(const QObject *obj, QString *str, int 
pretty, int indent)
 } else {
 buffer[len] = 0;
 }
-
+
 qstring_append(str, buffer);
 break;
 }
-- 
2.4.3




[Qemu-devel] [PATCH v7 04/31] hmp: Improve use of qapi visitor

2015-12-07 Thread Eric Blake
Cache the visitor in a local variable instead of repeatedly
calling the accessor.  Pass NULL for the visit_start_struct()
object (which matches the fact that we were already passing 0
for the size argument, because we aren't using the visit to
allocate a qapi struct).

Signed-off-by: Eric Blake 

---
v7: place earlier in series, drop attempts to provide a 'kind' string,
drop bogus avoidance of qmp_object_del() on error
v6: new patch, split from RFC on v5 7/46
---
 hmp.c | 14 +++---
 1 file changed, 7 insertions(+), 7 deletions(-)

diff --git a/hmp.c b/hmp.c
index c2b2c16..0d21f1d 100644
--- a/hmp.c
+++ b/hmp.c
@@ -1667,9 +1667,9 @@ void hmp_object_add(Monitor *mon, const QDict *qdict)
 QemuOpts *opts;
 char *type = NULL;
 char *id = NULL;
-void *dummy = NULL;
 OptsVisitor *ov;
 QDict *pdict;
+Visitor *v;

 opts = qemu_opts_from_qdict(qemu_find_opts("object"), qdict, &err);
 if (err) {
@@ -1678,28 +1678,29 @@ void hmp_object_add(Monitor *mon, const QDict *qdict)

 ov = opts_visitor_new(opts);
 pdict = qdict_clone_shallow(qdict);
+v = opts_get_visitor(ov);

-visit_start_struct(opts_get_visitor(ov), &dummy, NULL, NULL, 0, &err);
+visit_start_struct(v, NULL, NULL, NULL, 0, &err);
 if (err) {
 goto out_clean;
 }

 qdict_del(pdict, "qom-type");
-visit_type_str(opts_get_visitor(ov), &type, "qom-type", &err);
+visit_type_str(v, &type, "qom-type", &err);
 if (err) {
 goto out_end;
 }

 qdict_del(pdict, "id");
-visit_type_str(opts_get_visitor(ov), &id, "id", &err);
+visit_type_str(v, &id, "id", &err);
 if (err) {
 goto out_end;
 }

-object_add(type, id, pdict, opts_get_visitor(ov), &err);
+object_add(type, id, pdict, v, &err);

 out_end:
-visit_end_struct(opts_get_visitor(ov), &err_end);
+visit_end_struct(v, &err_end);
 if (!err && err_end) {
 qmp_object_del(id, NULL);
 }
@@ -1711,7 +1712,6 @@ out_clean:
 qemu_opts_del(opts);
 g_free(id);
 g_free(type);
-g_free(dummy);

 out:
 hmp_handle_error(mon, &err);
-- 
2.4.3




[Qemu-devel] [PATCH v7 06/31] balloon: Improve use of qapi visitor

2015-12-07 Thread Eric Blake
Rework the control flow of balloon_stats_get_all() to make it
easier for a later patch to split visit_end_struct().  Also
switch to the uint64 visitor to match the data type.

Signed-off-by: Eric Blake 

---
v7: place earlier in series
v6: new patch, split from RFC on v5 7/46
---
 hw/virtio/virtio-balloon.c | 9 ++---
 1 file changed, 6 insertions(+), 3 deletions(-)

diff --git a/hw/virtio/virtio-balloon.c b/hw/virtio/virtio-balloon.c
index 9671635..1ce987a 100644
--- a/hw/virtio/virtio-balloon.c
+++ b/hw/virtio/virtio-balloon.c
@@ -130,10 +130,13 @@ static void balloon_stats_get_all(Object *obj, struct 
Visitor *v,
 if (err) {
 goto out_end;
 }
-for (i = 0; !err && i < VIRTIO_BALLOON_S_NR; i++) {
-visit_type_int64(v, (int64_t *) &s->stats[i], balloon_stat_names[i],
- &err);
+for (i = 0; i < VIRTIO_BALLOON_S_NR; i++) {
+visit_type_uint64(v, &s->stats[i], balloon_stat_names[i], &err);
+if (err) {
+goto out_nested;
+}
 }
+out_nested:
 error_propagate(errp, err);
 err = NULL;
 visit_end_struct(v, &err);
-- 
2.4.3




[Qemu-devel] [PATCH v7 03/31] qapi: Drop dead dealloc visitor variable

2015-12-07 Thread Eric Blake
Commit 0b9d8542 added StackEntry.is_list_head, but forgot to
delete the now-unused QapiDeallocVisitor.is_list_head.

Signed-off-by: Eric Blake 

---
v7: new patch
---
 qapi/qapi-dealloc-visitor.c | 1 -
 1 file changed, 1 deletion(-)

diff --git a/qapi/qapi-dealloc-visitor.c b/qapi/qapi-dealloc-visitor.c
index 737deab..204de8f 100644
--- a/qapi/qapi-dealloc-visitor.c
+++ b/qapi/qapi-dealloc-visitor.c
@@ -28,7 +28,6 @@ struct QapiDeallocVisitor
 {
 Visitor visitor;
 QTAILQ_HEAD(, StackEntry) stack;
-bool is_list_head;
 };

 static QapiDeallocVisitor *to_qov(Visitor *v)
-- 
2.4.3




[Qemu-devel] [PATCH v7 05/31] vl: Improve use of qapi visitor

2015-12-07 Thread Eric Blake
Cache the visitor in a local variable instead of repeatedly
calling the accessor.  Pass NULL for the visit_start_struct()
object (which matches the fact that we were already passing 0
for the size argument, because we aren't using the visit to
allocate a qapi struct).  Guarantee that visit_end_struct()
is called if visit_start_struct() succeeded.

Signed-off-by: Eric Blake 

---
v7: place earlier in series, drop attempts to provide a 'kind' string,
drop bogus avoidance of qmp_object_del() on error
v6: new patch, split from RFC on v5 7/46
---
 vl.c | 26 ++
 1 file changed, 14 insertions(+), 12 deletions(-)

diff --git a/vl.c b/vl.c
index 5aaea77..11555ac 100644
--- a/vl.c
+++ b/vl.c
@@ -2828,44 +2828,47 @@ static bool object_create_delayed(const char *type)
 static int object_create(void *opaque, QemuOpts *opts, Error **errp)
 {
 Error *err = NULL;
+Error *err_end = NULL;
 char *type = NULL;
 char *id = NULL;
-void *dummy = NULL;
 OptsVisitor *ov;
 QDict *pdict;
 bool (*type_predicate)(const char *) = opaque;
+Visitor *v;

 ov = opts_visitor_new(opts);
 pdict = qemu_opts_to_qdict(opts, NULL);
+v = opts_get_visitor(ov);

-visit_start_struct(opts_get_visitor(ov), &dummy, NULL, NULL, 0, &err);
+visit_start_struct(v, NULL, NULL, NULL, 0, &err);
 if (err) {
 goto out;
 }

 qdict_del(pdict, "qom-type");
-visit_type_str(opts_get_visitor(ov), &type, "qom-type", &err);
+visit_type_str(v, &type, "qom-type", &err);
 if (err) {
 goto out;
 }
 if (!type_predicate(type)) {
+visit_end_struct(v, NULL);
 goto out;
 }

 qdict_del(pdict, "id");
-visit_type_str(opts_get_visitor(ov), &id, "id", &err);
+visit_type_str(v, &id, "id", &err);
 if (err) {
-goto out;
+goto out_end;
 }

-object_add(type, id, pdict, opts_get_visitor(ov), &err);
-if (err) {
-goto out;
-}
-visit_end_struct(opts_get_visitor(ov), &err);
-if (err) {
+object_add(type, id, pdict, v, &err);
+
+out_end:
+visit_end_struct(v, &err_end);
+if (!err && err_end) {
 qmp_object_del(id, NULL);
 }
+error_propagate(&err, err_end);

 out:
 opts_visitor_cleanup(ov);
@@ -2873,7 +2876,6 @@ out:
 QDECREF(pdict);
 g_free(id);
 g_free(type);
-g_free(dummy);
 if (err) {
 error_report_err(err);
 return -1;
-- 
2.4.3




Re: [Qemu-devel] [PATCH v2 2/3] net/vmxnet3: fix debug macro pattern for vmxnet3

2015-12-07 Thread Miao Yan
2015-12-08 6:04 GMT+08:00 Eric Blake :
> On 12/06/2015 07:47 PM, Jason Wang wrote:
>>
>>
>> On 12/05/2015 04:55 PM, Miao Yan wrote:
>>> Vmxnet3 uses the following debug macro style:
>>>
>>>  #ifdef SOME_DEBUG
>>>  #  define debug(...) do{ printf(...); } while (0)
>>>  # else
>>>  #  define debug(...) do{ } while (0)
>>>  #endif
>>>
>>> If SOME_DEBUG is undefined, then format string inside the
>>> debug macro will never be checked by compiler. Code is
>>> likely to break in the future when SOME_DEBUG is enabled
>>>  because of lack of testing. This patch changes this
>>> to the following:
>>>
>>>  #define debug(...) \
>>>   do { if (SOME_DEBUG_ENABLED) printf(...); } while (0)
>>>
>>> Signed-off-by: Miao Yan 
>>> Reviewed-by: Eric Blake 
>>> ---
>>> Changes in v2:
>>>   - Fix grammar error in commit log
>>
>> Applied in my -net for 2.5. Thanks
>
> I don't know if Miao saw Peter's reaction to the pull request, but just
> as I guessed on v1, exposing more format strings turned up more latent
> bugs in the format strings, with failures such as:

Very sorry about this.

>
>> I'm afraid this doesn't build on 32-bit due to format string errors:
>>
>> /home/petmay01/qemu/hw/net/vmxnet3.c: In function 'vmxnet3_complete_packet':
>> /home/petmay01/qemu/hw/net/vmxnet3.c:500:5: error: format '%lu'
>> expects argument of type 'long unsigned int', but argument 7 has type
>> 'size_t' [-Werror=format=]
>> VMXNET3_RING_DUMP(VMW_RIPRN, "TXC", qidx, &s->txq_descr[qidx].comp_ring);


I don't have a 32 bit machine for a long time, I'll create a VM to test this.

>
> Looks like it will need a v3; and sorry that I didn't catch the problems
> in my review (I was just going off of whether the macro conversion was
> correct, and not an actual compile test to see if all the now-live
> format strings were always valid).


I guess %zu should fix this.  I'll send v3. Thanks.


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



[Qemu-devel] tcg: improve MAX_CODE_GEN_BUFFER_SIZE for arm

2015-12-07 Thread TeLeMan
I know MAX_CODE_GEN_BUFFER_SIZE is limited by the host direct branch
instructions.But the arm's MAX_CODE_GEN_BUFFER_SIZE is so small.I
tried improving MAX_CODE_GEN_BUFFER_SIZE.I wrote some check codes for
the overflow offset in tcg_out_b(), tcg_out_bl(),
tcg_out_blx_imm(),reloc_pc24(). But I didn't catch any overflow case
when tb_size and MAX_CODE_GEN_BUFFER_SIZE were larger than 32MB. After
the generated code size was larger than 32MB, qemu crashed.

Any suggest for this issue?

--
SUN OF A BEACH



Re: [Qemu-devel] [Qemu-ppc] [PATCHv2 07/10] pseries: DEFINE_SPAPR_MACHINE

2015-12-07 Thread Sam Bobroff
On Mon, Dec 07, 2015 at 02:34:37PM +1100, David Gibson wrote:
> At the moment all the class_init functions and TypeInfo structures for the
> various versioned pseries machine types are open-coded.  As more versions
> are created this is getting increasingly clumsy.
> 
> This patch borrows the approach used in PC, using a DEFINE_SPAPR_MACHINE()
> macro to construct most of the boilerplate from simpler 'class_options' and
> 'instance_options' functions.
> 
> This patch makes a small semantic change - the versioned machine types are
> now registered through machine_init() instead of type_init().  Since the
> new way is how PC already did it, I'm assuming that's correct.
> 
> Signed-off-by: David Gibson 
> ---
>  hw/ppc/spapr.c | 119 
> -
>  1 file changed, 49 insertions(+), 70 deletions(-)
> 
> diff --git a/hw/ppc/spapr.c b/hw/ppc/spapr.c
> index 3078e60..4f645f3 100644
> --- a/hw/ppc/spapr.c
> +++ b/hw/ppc/spapr.c
> @@ -2302,24 +2302,47 @@ static const TypeInfo spapr_machine_info = {
>  },
>  };
>  
> +#define DEFINE_SPAPR_MACHINE(suffix, verstr) \
> +static void spapr_machine_##suffix##_class_init(ObjectClass *oc, \
> +void *data)  \
> +{\
> +MachineClass *mc = MACHINE_CLASS(oc);\
> +spapr_machine_##suffix##_class_options(mc);  \
> +}\
> +static void spapr_machine_##suffix##_instance_init(Object *obj)  \
> +{\
> +MachineState *machine = MACHINE(obj);\
> +spapr_machine_##suffix##_instance_options(machine);  \
> +}\
> +static const TypeInfo spapr_machine_##suffix##_info = {  \
> +.name = MACHINE_TYPE_NAME("pseries-" verstr),\
> +.parent = TYPE_SPAPR_MACHINE,\
> +.class_init = spapr_machine_##suffix##_class_init,   \
> +.instance_init = spapr_machine_##suffix##_instance_init, \
> +};   \
> +static void spapr_machine_register_##suffix(void)\
> +{\
> +type_register(&spapr_machine_##suffix##_info);   \
> +}\
> +machine_init(spapr_machine_register_##suffix)
> +
>  /*
>   * pseries-2.5
>   */
> -static void spapr_machine_2_5_class_init(ObjectClass *oc, void *data)
> +static void spapr_machine_2_5_instance_options(MachineState *machine)
>  {
> -MachineClass *mc = MACHINE_CLASS(oc);
> -sPAPRMachineClass *smc = SPAPR_MACHINE_CLASS(oc);
> +}
> +
> +static void spapr_machine_2_5_class_options(MachineClass *mc)
> +{
> +sPAPRMachineClass *smc = SPAPR_MACHINE_CLASS(mc);
>  
>  mc->alias = "pseries";
>  mc->is_default = 1;
>  smc->dr_lmb_enabled = true;
>  }
>  
> -static const TypeInfo spapr_machine_2_5_info = {
> -.name  = MACHINE_TYPE_NAME("pseries-2.5"),
> -.parent= TYPE_SPAPR_MACHINE,
> -.class_init= spapr_machine_2_5_class_init,
> -};
> +DEFINE_SPAPR_MACHINE(2_5, "2.5");
>  
>  /*
>   * pseries-2.4
> @@ -2327,18 +2350,17 @@ static const TypeInfo spapr_machine_2_5_info = {
>  #define SPAPR_COMPAT_2_4 \
>  HW_COMPAT_2_4
>  
> -static void spapr_machine_2_4_class_init(ObjectClass *oc, void *data)
> +static void spapr_machine_2_4_instance_options(MachineState *machine)
>  {
> -MachineClass *mc = MACHINE_CLASS(oc);
> +spapr_machine_2_5_instance_options(machine);
> +}
>  
> +static void spapr_machine_2_4_class_options(MachineClass *mc)
> +{
>  SET_MACHINE_COMPAT(mc, SPAPR_COMPAT_2_4);
>  }
>  
> -static const TypeInfo spapr_machine_2_4_info = {
> -.name  = MACHINE_TYPE_NAME("pseries-2.4"),
> -.parent= TYPE_SPAPR_MACHINE,
> -.class_init= spapr_machine_2_4_class_init,
> -};
> +DEFINE_SPAPR_MACHINE(2_4, "2.4");
>  
>  /*
>   * pseries-2.3
> @@ -2352,30 +2374,18 @@ static const TypeInfo spapr_machine_2_4_info = {
>  .value= "off",\
>  },
>  
> -static void spapr_compat_2_3(Object *obj)
> +static void spapr_machine_2_3_instance_options(MachineState *machine)
>  {
> +spapr_machine_2_4_instance_options(machine);
>  savevm_skip_section_footers();
>  global_state_set_optional();
>  }
>  
> -static void spapr_machine_2_3_instance_init(Object *obj)
> -{
> -spapr_compat_2_3(obj);
> -}
> -
> -static void spapr_machine_2_3_class_init(ObjectClass *oc, void *data)
> +static void spapr_machine_2_3_class_options(MachineClass *mc)
>  {
> -   

Re: [Qemu-devel] [PATCH v5 00/11] Add basic "detach" support for dump-guest-memory

2015-12-07 Thread Peter Xu
On Mon, Dec 07, 2015 at 03:13:02PM -0700, Eric Blake wrote:
> On 12/06/2015 10:56 PM, Peter Xu wrote:
> > - patch 8
> >   - add "DumpQueryResult" in DUMP_COMPLETED event [Eric]
> > (since DumpQueryResult is introduced in patch 10, so doing it in
> > patch 10 for convenience. Please let me know if I should not do
> > this, e.g., if patch re-ordering is required)
> 
> All patches should build in isolation.  It looks like you met that goal
> (you introduce 'DUMP_COMPLETED' event in 8 without a 'result' member,
> then modify it in 10), so that it at least builds.  But it results in
> churn, in that you have multiple different definitions of
> 'DUMP_COMPLETED' over the life of the series.
> 
> It's not a requirement to rework things since each step builds, but if I
> were writing the series, I do find it conceptually easier to supply
> patches in an order that minimizes churn (the first patch that
> introduces a type uses its final form, rather than going through several
> iterations of that type).  So on that grounds, introducing
> DumpQueryResult as a separate patch, before either DUMP_COMPLETED or
> query-dump, might be easier to review, if there is a reason for a v6 spin.

Yes, it's harder for review. Sorry for that.

I think there should have a v6 spin, I will put DUMP_COMPLETE patch
to the end of the patch set.

Thanks.
Peter



Re: [Qemu-devel] [PULL for-2.5 2/4] block: Don't wait serialising for non-COR read requests

2015-12-07 Thread Fam Zheng
On Mon, 12/07 17:42, Cornelia Huck wrote:
> On Mon, 7 Dec 2015 11:02:51 +0100
> Cornelia Huck  wrote:
> 
> > On Thu,  3 Dec 2015 13:00:00 +0800
> > Stefan Hajnoczi  wrote:
> > 
> > > From: Fam Zheng 
> > > 
> > > The assertion problem was noticed in 06c3916b35a, but it wasn't
> > > completely fixed, because even though the req is not marked as
> > > serialising, it still gets serialised by wait_serialising_requests
> > > against other serialising requests, which could lead to the same
> > > assertion failure.
> > > 
> > > Fix it by even more explicitly skipping the serialising for this
> > > specific case.
> > > 
> > > Signed-off-by: Fam Zheng 
> > > Message-id: 1448962590-2842-2-git-send-email-f...@redhat.com
> > > Signed-off-by: Stefan Hajnoczi 
> > > ---
> > >  block/backup.c|  2 +-
> > >  block/io.c| 12 +++-
> > >  include/block/block.h |  4 ++--
> > >  trace-events  |  2 +-
> > >  4 files changed, 11 insertions(+), 9 deletions(-)
> > 
> > This one causes segfaults for me:
> > 
> > Program received signal SIGSEGV, Segmentation fault.
> > bdrv_is_inserted (bs=0x8000) at /data/git/yyy/qemu/block.c:3071
> > 3071if (!drv) {
> > 
> > (gdb) bt
> > #0  bdrv_is_inserted (bs=0x8000) at /data/git/yyy/qemu/block.c:3071
> > #1  0x80216974 in blk_is_inserted (blk=)
> > at /data/git/yyy/qemu/block/block-backend.c:986
> > #2  0x802169c6 in blk_is_available (blk=blk@entry=0x3ffb17e7960)
> > at /data/git/yyy/qemu/block/block-backend.c:991
> > #3  0x80216d12 in blk_check_byte_request 
> > (blk=blk@entry=0x3ffb17e7960, 
> > offset=offset@entry=4928966656, size=16384)
> > at /data/git/yyy/qemu/block/block-backend.c:558
> > #4  0x80216df2 in blk_check_request (blk=blk@entry=0x3ffb17e7960, 
> > sector_num=sector_num@entry=9626888, nb_sectors=nb_sectors@entry=32)
> > at /data/git/yyy/qemu/block/block-backend.c:589
> > #5  0x80217ee8 in blk_aio_readv (blk=0x3ffb17e7960, sector_num=
> > 9626888, iov=0x8098c658, nb_sectors=, cb=
> > 0x80081150 , opaque=0x80980620)
> > at /data/git/yyy/qemu/block/block-backend.c:727
> > #6  0x8008186e in submit_requests (niov=, 
> > num_reqs=, start=, mrb=, 
> > blk=) at /data/git/yyy/qemu/hw/block/virtio-blk.c:366
> > #7  virtio_blk_submit_multireq (mrb=, blk=)
> > at /data/git/yyy/qemu/hw/block/virtio-blk.c:444
> > #8  virtio_blk_submit_multireq (blk=0x3ffb17e7960, mrb=0x3ffeb58)
> > at /data/git/yyy/qemu/hw/block/virtio-blk.c:389

I can't parse these lines in the backtrace, what is #8 -> #7 ?

But other than that, this looks like a normal read request. Can you dump "blk"
fields?

> > #9  0x800823ee in virtio_blk_handle_output (vdev=, 
> > vq=) at /data/git/yyy/qemu/hw/block/virtio-blk.c:615
> > #10 0x801e367e in aio_dispatch (ctx=0x80918520)
> > at /data/git/yyy/qemu/aio-posix.c:326
> > #11 0x801d28b0 in aio_ctx_dispatch (source=, 
> > callback=, user_data=)
> > at /data/git/yyy/qemu/async.c:231
> > #12 0x03fffd36a05a in g_main_context_dispatch ()
> >from /lib64/libglib-2.0.so.0
> > #13 0x801e0ffa in glib_pollfds_poll ()
> > at /data/git/yyy/qemu/main-loop.c:211
> > #14 os_host_main_loop_wait (timeout=)
> > at /data/git/yyy/qemu/main-loop.c:256
> > #15 main_loop_wait (nonblocking=)
> > at /data/git/yyy/qemu/main-loop.c:504
> > #16 0x800148a6 in main_loop () at /data/git/yyy/qemu/vl.c:1923
> > #17 main (argc=, argv=, envp=)
> > at /data/git/yyy/qemu/vl.c:4684
> > 
> > Relevant part of command line:
> > 
> > -drive 
> > file=/dev/sda,if=none,id=drive-virtio-disk0,format=raw,serial=ccwzfcp1,cache=none
> >  -device 
> > virtio-blk-ccw,devno=fe.0.0001,drive=drive-virtio-disk0,id=virtio-disk0,bootindex=1,scsi=off
> 
> I played around a bit. The main part of this change seems to be calling
> wait_serialising_requests() conditionally; reverting this makes the
> guest boot again.
> 
> I then tried to find out when wait_serialising_requests() was NOT
> called and added fprintfs: well, it was _always_ called. I then added a
> fprintf for flags at the beginning of the function: this produced a
> segfault no matter whether wait_serialising_requests() was called
> conditionally or unconditionally. Weird race?

It looks like a race, any other operations happening at the time?  What jobs
are in the guest?

It would be nice if you can advise the reproducing approach? Apparently my
attempt failed..

Fam

> 
> Anything further I can do? I guess this patch fixes a bug for someone,
> but it means insta-death for my setup...
> 



Re: [Qemu-devel] [PATCH] virtio-blk: Drop x-data-plane option

2015-12-07 Thread Fam Zheng
On Mon, 12/07 21:02, Fam Zheng wrote:
> On Mon, 12/07 12:29, Cornelia Huck wrote:
> > No general objection to removing x-data-plane; but this probably wants
> > a mention on the changelog as x-data-plane has been described in
> > various howtos etc. over the years.

Add a changelog line,

http://wiki.qemu.org/ChangeLog/2.5#Block_devices_and_tools

please review.

Fam



Re: [Qemu-devel] [PATCH COLO-Frame v11 34/39] net/filter-buffer: Add default filter-buffer for each netdev

2015-12-07 Thread Yang Hongyang

On 2015年12月07日 15:38, Hailiang Zhang wrote:

On 2015/12/3 15:21, Yang Hongyang wrote:



On 2015年12月03日 14:48, Hailiang Zhang wrote:

On 2015/12/3 14:25, Wen Congyang wrote:

On 12/03/2015 11:53 AM, Hailiang Zhang wrote:

On 2015/12/3 9:17, Wen Congyang wrote:

On 11/24/2015 05:25 PM, zhanghailiang wrote:

We add each netdev a default filter-buffer, which will be used for
COLO
or Micro-checkpoint to buffer VM's packets. The name of default
filter-buffer
is 'nop'.
For the default filter-buffer, it will not buffer any packets in
default.
So it has no side effect for the netdev.


No, filter-buffer doesn't support vhost, so if you add default
filter-buffer
for each netdev, you can't use vhost.



Have you tested it ? Did the default filter-buffer break vhost ?
It's not supposed to break vhost, I will look into it. Thanks.


Yes, I have tested it. When I want to start a normal vm with vhost,
I get
the following error messages:

qemu-system-x86_64: -netdev tap,id=hn0,queues=1,vhost=on: Vhost is not
supported



Hmm, that is reported by filter in nextfilter_complete(), i will
investigate it.
We hope the default buffer filter has no side effect on netdev.


I think you'd better add an option to netdev to turn on/off default
filter, that will solve the problem.



Hi Hongyang,

I have fix this problem in another way, just skip add filter for vhost-user
netdev. And by the way, I didn't add any option to netdev to control
the default filter's on/off, since i'd like to control the default filter
just in filter layer, i add an 'enabled' and an 'is-default' flag in
struct NetFilterState, and for the default filter buffer, its status is
'off' (disabled),
so it will not buffer any packets, we will skip it in
filter_receive_iov() to ensure
the packets will not go through the process of filter.

Besides, for hmp command 'info network', we will show the on/off status
for filter, just
like: (Or, maybe we don't show the filter that is disabled ?)
(qemu) info network
net-pci0: index=0,type=nic,model=virtio-net-pci,macaddr=52:54:00:12:34:56
  \ bn0:
index=0,type=tap,ifname=tap0,script=/etc/qemu-ifup,downscript=/etc/qemu-ifdown

filters:
   - nop: type=filter-buffer,interval=0,netdev=bn0,queue=rx,status=off
   - f0: type=filter-buffer,interval=1000,netdev=bn0,queue=rx,status=on

Is this acceptable?


Hi Hailiang, thanks for the explanation.
It's up to Jason though, cause he's the network Maintainer :)



Thanks.
Hailiang



Thanks,
Hailiang




Thanks
Wen Congyang



Signed-off-by: zhanghailiang 
Cc: Jason Wang 
Cc: Yang Hongyang 
---
v11:
- New patch
---
   include/net/filter.h |  3 +++
   net/filter-buffer.c  | 74

   net/net.c|  8 ++
   3 files changed, 85 insertions(+)

diff --git a/include/net/filter.h b/include/net/filter.h
index 2deda36..01a7e90 100644
--- a/include/net/filter.h
+++ b/include/net/filter.h
@@ -74,4 +74,7 @@ ssize_t
qemu_netfilter_pass_to_next(NetClientState *sender,
   int iovcnt,
   void *opaque);

+void netdev_add_default_filter_buffer(const char *netdev_id,
+  NetFilterDirection direction,
+  Error **errp);
   #endif /* QEMU_NET_FILTER_H */
diff --git a/net/filter-buffer.c b/net/filter-buffer.c
index 57be149..195af68 100644
--- a/net/filter-buffer.c
+++ b/net/filter-buffer.c
@@ -14,6 +14,12 @@
   #include "qapi/qmp/qerror.h"
   #include "qapi-visit.h"
   #include "qom/object.h"
+#include "net/net.h"
+#include "qapi/qmp/qdict.h"
+#include "qapi/qmp-output-visitor.h"
+#include "qapi/qmp-input-visitor.h"
+#include "monitor/monitor.h"
+#include "qmp-commands.h"

   #define TYPE_FILTER_BUFFER "filter-buffer"

@@ -26,6 +32,8 @@ typedef struct FilterBufferState {
   NetQueue *incoming_queue;
   uint32_t interval;
   QEMUTimer release_timer;
+bool is_default;
+bool enable_buffer;
   } FilterBufferState;

   static void filter_buffer_flush(NetFilterState *nf)
@@ -65,6 +73,10 @@ static ssize_t
filter_buffer_receive_iov(NetFilterState *nf,
   {
   FilterBufferState *s = FILTER_BUFFER(nf);

+/* Don't buffer any packets if the filter is not enabled */
+if (!s->enable_buffer) {
+return 0;
+}
   /*
* We return size when buffer a packet, the sender will take
it as
* a already sent packet, so sent_cb should not be called
later.
@@ -102,6 +114,7 @@ static void
filter_buffer_cleanup(NetFilterState *nf)
   static void filter_buffer_setup(NetFilterState *nf, Error **errp)
   {
   FilterBufferState *s = FILTER_BUFFER(nf);
+char *path = object_get_canonical_path_component(OBJECT(nf));

   /*
* We may want to accept zero interval when VM FT solutions
like MC
@@ -114,6 +127,7 @@ static void filter_buffer_setup(NetFilterState
*nf, Error **errp)
   }

   s->incoming_queue =
qemu_new_net_queue(qemu_netfilter_pass_to_next, nf);
+   

Re: [Qemu-devel] [PATCH RFC for-2.6 0/3] block: Add meta dirty bitmap for migration/persistence

2015-12-07 Thread Fam Zheng
On Mon, 12/07 17:19, Vladimir Sementsov-Ogievskiy wrote:
> On 07.12.2015 08:59, Fam Zheng wrote:
> >Vladimir,
> >
> >This is what I propose to implement meta bitmap. It's implemented in the
> >HBitmap level to be more efficient, and the interface slightly varies too.
> 
> What is the benefit?
> 
> Hbitmap usage:
> 
> 1) BdrvDirtyBitmap - need meta
> 2) BackupBlockJob - doesn't need meta
> 3) BlockDirtyBitmapState - doesn't need meta
> 4) now I'm working on series for parallels format and I use HBitmap
> to mark allocated/free clusters.. - doesn't need meta
> 5) your meta hbitmap =) - doesn't need meta..

6) persistence dirty bitmap. - need meta

> 
> So, what is the benefit of moving this functionality to parent
> class? (Which is complicated without it)..

See my reply to John's comment on the cover letter. This is more efficient than
doing it in BdrvDirtyBitmap.

> 
> However, I'm not really against, except my comment to the first patch.
> 
> PS:
> Actually I don't like HBitmap - BdrvDirtyBitmap..
> - No implementation without granularity
>I need HBitmap without granularity for my needs and have to
> use granularity=0. If there was HBitmap without granularity some
> operations can be faster - for example, finding next/previous/last
> zeros, jumping by words not by bits..
> - It is not sparse. Empty bitmap occupies lots of ram.
> - different granularity units for HBitmap and BdrvDirtyBitmap
> - different layers with/without granularity in hbitmap.c
> - HBitmap with non-zero granularity doesn't know its size (only
> rounded up to granularity)
> - necessity of writing wrappers like
>bdrv_dirty_bitmap_do_something(...)
>{
> hbitmap_do_something(...)
>}
>-- Yes, I understand that this is inevitably, but I just don't like it..
> - BdrvDirtyBitmap is defined in block.c.. I think, it should have
> its own .c file.

Yes, I agree we should cut it out during 2.6, with a separate header.




Re: [Qemu-devel] [PATCH RFC for-2.6 0/3] block: Add meta dirty bitmap for migration/persistence

2015-12-07 Thread Fam Zheng
On Mon, 12/07 18:47, John Snow wrote:
> 
> 
> On 12/07/2015 12:59 AM, Fam Zheng wrote:
> > Vladimir,
> > 
> > This is what I propose to implement meta bitmap. It's implemented in the
> > HBitmap level to be more efficient, and the interface slightly varies too.
> > 
> 
> I missed it: What was wrong with Vladimir's approach / what are the
> benefits of this approach?

The only real difference with this series is, only actual bit toggling will
mark meta dirty. Vladimir's approach was in BdrvDirtyBitmap level which can't
tell bit toggling from repetitive bit set/unset. This is from his patch:

@@ -3390,6 +3428,9 @@ void bdrv_set_dirty_bitmap(BdrvDirtyBitmap *bitmap,
 {
 assert(bdrv_dirty_bitmap_enabled(bitmap));
 hbitmap_set(bitmap->bitmap, cur_sector, nr_sectors);
+if (bitmap->meta_bitmap) {
+hbitmap_set(bitmap->meta_bitmap, cur_sector, nr_sectors);
+}
 }

 void bdrv_reset_dirty_bitmap(BdrvDirtyBitmap *bitmap,
@@ -3397,6 +3438,9 @@ void bdrv_reset_dirty_bitmap(BdrvDirtyBitmap *bitmap,
 {
 assert(bdrv_dirty_bitmap_enabled(bitmap));
 hbitmap_reset(bitmap->bitmap, cur_sector, nr_sectors);
+if (bitmap->meta_bitmap) {
+hbitmap_set(bitmap->meta_bitmap, cur_sector, nr_sectors);
+}
 }

 void bdrv_clear_dirty_bitmap(BdrvDirtyBitmap *bitmap)

> 
> > I'd like to use these operations to make dirty bitmap persistence more
> > efficient too: unchanged dirty bits don't need to be flushed to disk. So I'm
> > posting this as a separate series for a common base for both sides.
> > 
> 
> This is a reasonable use of the meta-bitmap strategy in general.
> 
> Keep in mind Vladimir's approach to Meta bitmaps used a different
> granularity such that 1 physical bit implied 1 sector needed to be
> re-transmitted.

Yes, I can fix the meta bitmap granularity.

> 
> A meta-bitmap that keeps track of disk flushes may require a different
> granularity than one used for migration.
> 
> > Posting as RFC as 2.6 dev phase is just starting, we can still tweak the
> > interface and/or implementation to fit the need.
> > 
> > Fam Zheng (3):
> >   HBitmap: Introduce "meta" bitmap to track bit changes
> >   tests: Add test code for meta bitmap
> >   block: Support meta dirty bitmap
> > 
> >  block.c| 46 ++-
> >  block/mirror.c |  3 +-
> >  blockdev.c |  3 +-
> >  include/block/block.h  | 11 
> >  include/qemu/hbitmap.h |  7 +
> >  migration/block.c  |  2 +-
> >  tests/test-hbitmap.c   | 74 
> > ++
> >  util/hbitmap.c | 22 +++
> >  8 files changed, 164 insertions(+), 4 deletions(-)
> > 



Re: [Qemu-devel] [PATCH RFC for-2.6 1/3] HBitmap: Introduce "meta" bitmap to track bit changes

2015-12-07 Thread Fam Zheng
On Mon, 12/07 16:32, Vladimir Sementsov-Ogievskiy wrote:
> On 07.12.2015 08:59, Fam Zheng wrote:
> >The meta bitmap will have the same size and granularity as the tracked
> >bitmap, and upon each bit toggle, the corresponding bit in the meta
> >bitmap, at an identical position, will be set.
> 
> No, meta bitmap should not have same granularity. If we have 16tb
> storage, then 16kb granulated bitmap will occupy more then 128 mb.
> And additional meta bitmap of the same size and granularity is
> redundant 128+ mb of RAM, when actually we need meta bitmap for
> blocks for example of 1mb and it should occupy about 128 bits.

Makes sense, do you prefer a parameterized granularity, or a fixed scaling like
one bit for 1 word?

Fam

> 
> 
> >
> >Signed-off-by: Fam Zheng 
> >---
> >  include/qemu/hbitmap.h |  7 +++
> >  util/hbitmap.c | 22 ++
> >  2 files changed, 29 insertions(+)
> >
> >diff --git a/include/qemu/hbitmap.h b/include/qemu/hbitmap.h
> >index bb94a00..09a6b06 100644
> >--- a/include/qemu/hbitmap.h
> >+++ b/include/qemu/hbitmap.h
> >@@ -181,6 +181,13 @@ void hbitmap_iter_init(HBitmapIter *hbi, const HBitmap 
> >*hb, uint64_t first);
> >   */
> >  unsigned long hbitmap_iter_skip_words(HBitmapIter *hbi);
> >+/* hbitmap_create_meta
> >+ * @hb: The HBitmap to operate on.
> >+ *
> >+ * Create a "meta" hbitmap to track dirtiness of the bits in this HBitmap.
> >+ */
> >+HBitmap *hbitmap_create_meta(HBitmap *hb);
> >+
> >  /**
> >   * hbitmap_iter_next:
> >   * @hbi: HBitmapIter to operate on.
> >diff --git a/util/hbitmap.c b/util/hbitmap.c
> >index 50b888f..3ad406e 100644
> >--- a/util/hbitmap.c
> >+++ b/util/hbitmap.c
> >@@ -81,6 +81,9 @@ struct HBitmap {
> >   */
> >  int granularity;
> >+/* A meta dirty bitmap to track the dirtiness of bits in this HBitmap. 
> >*/
> >+HBitmap *meta;
> >+
> >  /* A number of progressively less coarse bitmaps (i.e. level 0 is the
> >   * coarsest).  Each bit in level N represents a word in level N+1 that
> >   * has a set bit, except the last level where each bit represents the
> >@@ -232,6 +235,7 @@ static inline bool hb_set_elem(unsigned long *elem, 
> >uint64_t start, uint64_t las
> >  /* The recursive workhorse (the depth is limited to HBITMAP_LEVELS)... */
> >  static void hb_set_between(HBitmap *hb, int level, uint64_t start, 
> > uint64_t last)
> >  {
> >+uint64_t save_start = start;
> >  size_t pos = start >> BITS_PER_LEVEL;
> >  size_t lastpos = last >> BITS_PER_LEVEL;
> >  bool changed = false;
> >@@ -252,6 +256,9 @@ static void hb_set_between(HBitmap *hb, int level, 
> >uint64_t start, uint64_t last
> >  }
> >  }
> >  changed |= hb_set_elem(&hb->levels[level][i], start, last);
> >+if (hb->meta && level == HBITMAP_LEVELS - 1 && changed) {
> >+hbitmap_set(hb->meta, save_start, last - save_start + 1);
> >+}
> >  /* If there was any change in this layer, we may have to update
> >   * the one above.
> >@@ -298,6 +305,7 @@ static inline bool hb_reset_elem(unsigned long *elem, 
> >uint64_t start, uint64_t l
> >  /* The recursive workhorse (the depth is limited to HBITMAP_LEVELS)... */
> >  static void hb_reset_between(HBitmap *hb, int level, uint64_t start, 
> > uint64_t last)
> >  {
> >+uint64_t save_start = start;
> >  size_t pos = start >> BITS_PER_LEVEL;
> >  size_t lastpos = last >> BITS_PER_LEVEL;
> >  bool changed = false;
> >@@ -336,6 +344,10 @@ static void hb_reset_between(HBitmap *hb, int level, 
> >uint64_t start, uint64_t la
> >  lastpos--;
> >  }
> >+if (hb->meta && level == HBITMAP_LEVELS - 1 && changed) {
> >+hbitmap_set(hb->meta, save_start, last - save_start + 1);
> >+}
> >+
> >  if (level > 0 && changed) {
> >  hb_reset_between(hb, level - 1, pos, lastpos);
> >  }
> >@@ -384,6 +396,9 @@ void hbitmap_free(HBitmap *hb)
> >  for (i = HBITMAP_LEVELS; i-- > 0; ) {
> >  g_free(hb->levels[i]);
> >  }
> >+if (hb->meta) {
> >+hbitmap_free(hb->meta);
> >+}
> >  g_free(hb);
> >  }
> >@@ -493,3 +508,10 @@ bool hbitmap_merge(HBitmap *a, const HBitmap *b)
> >  return true;
> >  }
> >+
> >+HBitmap *hbitmap_create_meta(HBitmap *hb)
> >+{
> >+assert(!hb->meta);
> >+hb->meta = hbitmap_alloc(hb->size, hb->granularity);
> >+return hb->meta;
> >+}
> 
> 
> -- 
> Best regards,
> Vladimir
> * now, @virtuozzo.com instead of @parallels.com. Sorry for this inconvenience.
> 



Re: [Qemu-devel] [PATCH 0/2] Preparation for PCI devices convert to realize()

2015-12-07 Thread Cao jin

Hi, Marcel

On 12/07/2015 09:42 PM, Marcel Apfelbaum wrote:

On 12/07/2015 10:08 AM, Cao jin wrote:

There are many PCI devices still using .init() as its initialization
function,
I am planning to do the "convert to realize()" work, and PCI bridge
devices are
chosen first. The supporting functions should be modified
first.msi_init() &
msix_init() are supporting functions for PCI devices.

Because this patchset is much different from the previous one, so, didn`t
add "V2" in the subject


Hi,

Even if the patches are different is worth mentioning V2, otherwise
the maintainer would not know which to take.



I see. Thanks for your suggestion:)


Thanks,
Marcel



--
Yours Sincerely,

Cao Jin





Re: [Qemu-devel] Posible regressions around spapr-dr-connector property drc-connector[]

2015-12-07 Thread Eric Blake
On 12/07/2015 05:18 PM, David Gibson wrote:
> On Fri, Dec 04, 2015 at 11:11:31AM +0100, Markus Armbruster wrote:
>> David Gibson  writes:
>>

 It was {} in 2.4.  Changing it to null so we can distingish "nothing"
 from "empty" is an incompatible change.  May make sense anyway, but I
 can't judge it.
>>>
>>> Strictly speaking it's an incompatible change, yes.  But I find it
>>> hard to imagine anything would be relying on the {} behaviour.  This
>>> property is essentially a debugging interface to start with, and the
>>> missing / empty case is examining it in a state that's unlikely to be
>>> interesting.
>>
>> I'm not against changing it, I just want it changed intentionally rather
>> than by accidental side effect :)
>>
>> If you tell me you want null here going forward, I'll make sure it gets
>> changed to null in the next development cycle, with a nice commit
>> message.
> 
> I would like it to be null (or simply missing) in future.

Okay, I'm about to post the patch for just that, for the 2.6 timeframe.

> But leaving it as is for 2.5 is fine.

Good.

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



signature.asc
Description: OpenPGP digital signature


Re: [Qemu-devel] Posible regressions around spapr-dr-connector property drc-connector[]

2015-12-07 Thread David Gibson
On Fri, Dec 04, 2015 at 11:11:31AM +0100, Markus Armbruster wrote:
> David Gibson  writes:
> 
> > On Fri, Dec 04, 2015 at 09:05:51AM +0100, Markus Armbruster wrote:
> >> David Gibson  writes:
> >> 
> >> > On Thu, Dec 03, 2015 at 04:30:31PM +0100, Markus Armbruster wrote:
> >> >> 1. Before commit 94649d4 "spapr: Don't use QOM [*] syntax for DR
> >> >>connectors", the indexes were small integers:
> >> >> 
> >> >>(qemu) info qom-tree
> >> >>/machine (pseries-2.4-machine)
> >> >>  /unattached (container)
> >> >>[...]
> >> >>/device[5] (spapr-pci-host-bridge)
> >> >>  /p...@8002000.mmio[0] (qemu:memory-region)
> >> >>  /p...@8002000.mmio-alias[0] (qemu:memory-region)
> >> >>  /p...@8002000.io[0] (qemu:memory-region)
> >> >>  /p...@8002000.io-alias[0] (qemu:memory-region)
> >> >>  /pci.0 (PCI)
> >> >>  /pci@8002000.iommu-root[0] (qemu:memory-region)
> >> >>  /dr-connector[0] (spapr-dr-connector)
> >> >>  /dr-connector[1] (spapr-dr-connector)
> >> >>  /dr-connector[2] (spapr-dr-connector)
> >> >>  [...]
> >> >> 
> >> >>Since then, they're big ones:
> >> >> 
> >> >>  /dr-connector[1073741824] (spapr-dr-connector)
> >> >>  /dr-connector[1073741825] (spapr-dr-connector)
> >> >>  /dr-connector[1073741826] (spapr-dr-connector)
> >> >> 
> >> >>The commit message doesn't quite spell out this change, and I'm
> >> >>therefore double-checkint it's intentional.  Is it?
> >> >
> >> > Yes, it's intentional.  The small integers were arbitrarily allocated
> >> > by the QOM magic [*] code, whereas the big integers are actually
> >> > meaningful values (essentially the DRC's global ID for the dynamic
> >> > reconfiguration hypervisor interfaces).
> >> 
> >> Good.
> >> 
> >> >> 2. Before commit 6c2f9a1 "qapi: Make output visitor return qnull()
> >> >>instead of NULL", qom-get returned {}:
> >> >> 
> >> >>Since then, it returns null:
> >> >> 
> >> >>QMP> { "execute": "qom-get", "arguments": { "path": 
> >> >> "/machine/unattached/device[5]/dr-connector[1073741950]", "property": 
> >> >> "fdt" } }
> >> >>{"return": null}
> >> >> 
> >> >>Does anyone care?
> >> >
> >> > Hm, I'm guessing this is a case where fdt is NULL internally.  Which I
> >> 
> >> Yes.
> >> 
> >> > think will happen before a device gets hotplugged into the DRC.  In
> >> > that case null seems more correct to me than {}, since {} would also
> >> > be what's shown for a present-but-empty device tree.
> >> 
> >> It was {} in 2.4.  Changing it to null so we can distingish "nothing"
> >> from "empty" is an incompatible change.  May make sense anyway, but I
> >> can't judge it.
> >
> > Strictly speaking it's an incompatible change, yes.  But I find it
> > hard to imagine anything would be relying on the {} behaviour.  This
> > property is essentially a debugging interface to start with, and the
> > missing / empty case is examining it in a state that's unlikely to be
> > interesting.
> 
> I'm not against changing it, I just want it changed intentionally rather
> than by accidental side effect :)
> 
> If you tell me you want null here going forward, I'll make sure it gets
> changed to null in the next development cycle, with a nice commit
> message.

I would like it to be null (or simply missing) in future.

> If you want it to be null in 2.5, NAK "[PATCH for-2.5 2/3] spapr_drc:
> Change value of property "fdt" from null back to {}".  It'll remain an
> implicit change then, not documented in commit messages.  I expect we'll
> eventually get a patch similar to the NAKed one regardless, because
> we'll tighten up the visitor contracts, and returning without visiting
> anything should become a programming error then.

But leaving it as is for 2.5 is fine.


-- 
David Gibson| I'll have my music baroque, and my code
david AT gibson.dropbear.id.au  | minimalist, thank you.  NOT _the_ _other_
| _way_ _around_!
http://www.ozlabs.org/~dgibson


signature.asc
Description: PGP signature


[Qemu-devel] [ANNOUNCE] QEMU 2.5.0-rc3 is now available

2015-12-07 Thread Michael Roth
Hello,

On behalf of the QEMU Team, I'd like to announce the availability of the
fourth release candidate for the QEMU 2.5 release.  This release is meant
for testing purposes and should not be used in a production environment.

  http://wiki.qemu.org/download/qemu-2.5.0-rc3.tar.bz2

You can help improve the quality of the QEMU 2.5 release by testing this
release and reporting bugs on Launchpad:

  https://bugs.launchpad.net/qemu/

The release plan for the 2.5 release is available at:

  http://wiki.qemu.org/Planning/2.5

Please add entries to the ChangeLog for the 2.5 release below:

  http://wiki.qemu.org/ChangeLog/2.5

Major issues fixed in this latest RC can be viewed here:

  http://wiki.qemu.org/Planning/2.5#Fixed_in_rc3

This is the last planned RC before the official 2.5.0 release.

Changes since rc2:

c3626ca: Update version for v2.5.0-rc3 release (Peter Maydell)
ba306c7: sd: Mark brittle abuse of blk_attach_dev() FIXME (Markus Armbruster)
79f2170: sdhci: Sanitize "sdhci-pci" properties for future qomification (Markus 
Armbruster)
a616fb7: virtio-blk: Drop x-data-plane option (Fam Zheng)
52b4bb7: lan9118: log and ignore access to invalid registers, rather than 
aborting (Andrew Baumann)
12fdd92: lan9118: fix emulation of MAC address loaded bit in E2P_CMD register 
(Andrew Baumann)
6a9c647: vmxnet3: silence warning (Michael S. Tsirkin)
8b98a2f: pcnet: fix rx buffer overflow(CVE-2015-7512) (Jason Wang)
837f21a: net: pcnet: add check to validate receive data size(CVE-2015-7504) 
(Prasad J Pandit)
9596ef7: e1000: fix hang of win2k12 shutdown with flood ping (Denis V. Lunev)
0d2cd78: qom-test: Fix qmp() leaks (Marc-André Lureau)
041088c: tests: Use proper functions types instead of void (*fn) (Markus 
Armbruster)
9847574: bt: check struct sizes (Paolo Bonzini)
2988cbe: typedefs: Put them back into alphabetical order (Markus Armbruster)
8ea9900: scsi: remove scsi_req_free prototype (Hervé Poussineau)
63fc737: gt64xxx: fix decoding of ISD register (Paolo Bonzini)
fccd35a: configure: use appropriate code fragment for -fstack-protector checks 
(Rodrigo Rebello)
0e1d024: crypto: avoid two coverity false positive error reports (Daniel P. 
Berrange)
0ef74c7: configure: Diagnose broken linkers directly (Peter Maydell)
e0df8f1: bt: avoid unintended sign extension (Paolo Bonzini)
624533e: util/id: fully allocate names table (John Snow)
ab8bf1d: spapr_drc: Change value of property "fdt" from null back to {} (Markus 
Armbruster)
c401ae8: spapr_drc: Make device "spapr-dr-connector" unavailable with -device 
(Markus Armbruster)
c75304a: spapr_drc: Handle visitor errors properly (Markus Armbruster)
70ae0b6: qom: Update documentation comment of struct Object (Cao jin)
b5e62af: tests: Fix check-report-qtest-% target (Andreas Färber)
4c65fed: ui: vnc: avoid floating point exception (Prasad J Pandit)
9cc0f19: iotests: Add regresion test case for write notifier assertion failure 
(Fam Zheng)
78b666f: iotests: Add "add_drive_raw" method (Fam Zheng)
61408b2: block: Don't wait serialising for non-COR read requests (Fam Zheng)
d21e877: iothread: include id in thread name (Paolo Bonzini)
a694ee3: migration: do floating-point division (Paolo Bonzini)
4e39f57: migration: Clean up use of g_poll() in socket_writev_buffer() (Markus 
Armbruster)
7197fb4: util/mmap-alloc: fix hugetlb support on ppc64 (Michael S. Tsirkin)
0560b0e: virtio-pci: Set the QEMU_PCI_CAP_EXPRESS capability early in its 
DeviceClass realize method (Shmulik Ladkani)
11380b3: virtio: handle non-virtio-1-capable backend for ccw (Cornelia Huck)
6d0b908: tests/vhost-user-bridge.c: fix fd leakage (Victor Kaplansky)
b0ae153: vhost: drop dead code (Michael S. Tsirkin)
176c369: mirror: Quiesce source during "mirror_exit" (Fam Zheng)
2087352: blkdebug: silence warning under qtest (Michael S. Tsirkin)
6f6f951: vhost-user: verify that number of queues is non-zero (Victor Kaplansky)
45ce512: vhost-user-test: fix crash with glib < 2.36 (Marc-André Lureau)
a899b1e: vhost-user-test: use unix port for migration (Marc-André Lureau)
9732baf: vhost-user-test: fix chardriver race (Marc-André Lureau)
c2551b4: qcow2: Fix potential qemu-img check crash on 32 bit hosts (Kevin Wolf)
0c2d70c: translate-all: ensure host page mask is always extended with 1's 
(Paolo Bonzini)
21a2430: main-loop: suppress warnings under qtest (Michael S. Tsirkin)
c1f2448: qemu-char: retry g_poll on EINTR (Paolo Bonzini)
55b4e80: exec: Stop using memory after free (Don Slutz)
b17a6d3: tcg: Increase the highwater reservation (Richard Henderson)
8d3a5d9: ui/cocoa.m: Prevent activation clicks from going to guest (Peter 
Maydell)
f0a399d: s390x/pci: fix up IOMMU size (Yi Min Zhao)
567c88c: s390x: no deprecation warning while testing (Cornelia Huck)
07af4c5: pc-bios/s390-ccw: rebuild image (Cornelia Huck)
7619562: pc-bios/s390-ccw: build for z900 (Christian Borntraeger)
ebac120: virtio-9p: use QEMU thread pool (Paolo Bonzini)
49f817c: fsdev-proxy-helper: avoid TOC/TOU race (Paolo Bonzini)
7624789: target-ppc/fpu_

Re: [Qemu-devel] [PATCH for-2.6 v2 04/10] fdc: add default drive type option

2015-12-07 Thread Eric Blake
On 12/07/2015 04:34 PM, John Snow wrote:
> 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 explicit
> behaviors: 120, 144, 288, auto, and none. The new "auto" behavior
> is intended to mimick current behavior, while the other types pick

s/mimick/mimic/ (one of those weird 'ic' verbs where the 'k' is
necessary in past tense but not present tense)

> one explicitly.
> 
> In a future patch, the goal is to change the FDC's default drive type
> from auto (falling back to 1.44MB) to auto (falling back to 2.88MB).
> 
> In order to allow users to obtain the old behaviors, though, a mechanism
> for specifying the exact type of drive we want is needed.
> 
> This patch adds the properties, but it is not acted on yet in favor of
> making those changes a little more explicitly clear in standalone patches
> later in this patch set.
> 
> Signed-off-by: John Snow 
> ---

> +++ b/qapi/block.json
> @@ -40,6 +40,22 @@
>'data': ['auto', 'none', 'lba', 'large', 'rechs']}
>  
>  ##
> +# @FloppyDriveType
> +#
> +# Type of Floppy drive to be emulated by the Floppy Disk Controller.
> +#
> +# @144:  1.44MB 3.5" drive
> +# @288:  2.88MB 3.5" drive
> +# @120:  1.5MB 5.25" drive

Names start with a digit - not the prettiest, but also not the first
instance, so qapi handles it just fine.  And I don't have any
suggestions for a better yet still concise name.

> +# @none: No drive connected
> +# @auto: Automatically determined by inserted media at boot
> +#
> +# Since: 2.6
> +##
> +{ 'enum': 'FloppyDriveType',
> +  'data': ['144', '288', '120', 'none', 'auto']}

Reviewed-by: Eric Blake 

-- 
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 RFC for-2.6 0/3] block: Add meta dirty bitmap for migration/persistence

2015-12-07 Thread John Snow


On 12/07/2015 12:59 AM, Fam Zheng wrote:
> Vladimir,
> 
> This is what I propose to implement meta bitmap. It's implemented in the
> HBitmap level to be more efficient, and the interface slightly varies too.
> 

I missed it: What was wrong with Vladimir's approach / what are the
benefits of this approach?

> I'd like to use these operations to make dirty bitmap persistence more
> efficient too: unchanged dirty bits don't need to be flushed to disk. So I'm
> posting this as a separate series for a common base for both sides.
> 

This is a reasonable use of the meta-bitmap strategy in general.

Keep in mind Vladimir's approach to Meta bitmaps used a different
granularity such that 1 physical bit implied 1 sector needed to be
re-transmitted.

A meta-bitmap that keeps track of disk flushes may require a different
granularity than one used for migration.

> Posting as RFC as 2.6 dev phase is just starting, we can still tweak the
> interface and/or implementation to fit the need.
> 
> Fam Zheng (3):
>   HBitmap: Introduce "meta" bitmap to track bit changes
>   tests: Add test code for meta bitmap
>   block: Support meta dirty bitmap
> 
>  block.c| 46 ++-
>  block/mirror.c |  3 +-
>  blockdev.c |  3 +-
>  include/block/block.h  | 11 
>  include/qemu/hbitmap.h |  7 +
>  migration/block.c  |  2 +-
>  tests/test-hbitmap.c   | 74 
> ++
>  util/hbitmap.c | 22 +++
>  8 files changed, 164 insertions(+), 4 deletions(-)
> 



Re: [Qemu-devel] [PATCH V5 8/8] arm: xlnx-zynqmp: Add xlnx-dp and xlnx-dpdma

2015-12-07 Thread Alistair Francis
On Mon, Nov 30, 2015 at 2:57 PM, Frederic Konrad
 wrote:
> On 24/11/2015 04:42, Alistair Francis wrote:
>> On Mon, Nov 23, 2015 at 6:53 PM, KONRAD Frederic
>>  wrote:
>>>
>>> Le 20/11/2015 13:21, Alistair Francis a écrit :
 On Fri, Oct 16, 2015 at 7:11 PM,   wrote:
> From: KONRAD Frederic 
>
> This adds the DP and the DPDMA to the Zynq MP platform.
>
> Signed-off-by: KONRAD Frederic 
> Reviewed-by: Peter Crosthwaite 
> Tested-By: Hyun Kwon 
> ---
>   hw/arm/xlnx-zynqmp.c | 20 
>   include/hw/arm/xlnx-zynqmp.h |  5 +
>   2 files changed, 25 insertions(+)
>
> diff --git a/hw/arm/xlnx-zynqmp.c b/hw/arm/xlnx-zynqmp.c
> index b36ca3d..dfed5cd 100644
> --- a/hw/arm/xlnx-zynqmp.c
> +++ b/hw/arm/xlnx-zynqmp.c
> @@ -32,6 +32,12 @@
>   #define SATA_ADDR   0xFD0C
>   #define SATA_NUM_PORTS  2
>
> +#define DP_ADDR 0xfd4a
> +#define DP_IRQ  113
> +
> +#define DPDMA_ADDR  0xfd4c
> +#define DPDMA_IRQ   116
> +
>   static const uint64_t gem_addr[XLNX_ZYNQMP_NUM_GEMS] = {
>   0xFF0B, 0xFF0C, 0xFF0D, 0xFF0E,
>   };
> @@ -97,6 +103,11 @@ static void xlnx_zynqmp_init(Object *obj)
>
>   object_initialize(&s->sata, sizeof(s->sata), TYPE_SYSBUS_AHCI);
>   qdev_set_parent_bus(DEVICE(&s->sata), sysbus_get_default());
> +
> +object_initialize(&s->dp, sizeof(s->dp), TYPE_XLNX_DP);
> +qdev_set_parent_bus(DEVICE(&s->dp), sysbus_get_default());
 New line

> +object_initialize(&s->dpdma, sizeof(s->dpdma), TYPE_XLNX_DPDMA);
> +qdev_set_parent_bus(DEVICE(&s->dpdma), sysbus_get_default());
>   }
>
>   static void xlnx_zynqmp_realize(DeviceState *dev, Error **errp)
> @@ -258,6 +269,15 @@ static void xlnx_zynqmp_realize(DeviceState *dev,
> Error **errp)
>
>   sysbus_mmio_map(SYS_BUS_DEVICE(&s->sata), 0, SATA_ADDR);
>   sysbus_connect_irq(SYS_BUS_DEVICE(&s->sata), 0,
> gic_spi[SATA_INTR]);
> +
> +sysbus_mmio_map(SYS_BUS_DEVICE(&s->dp), 0, DP_ADDR);
> +sysbus_connect_irq(SYS_BUS_DEVICE(&s->dp), 0, gic_spi[DP_IRQ]);
 New line

> +sysbus_mmio_map(SYS_BUS_DEVICE(&s->dpdma), 0, DPDMA_ADDR);
> +sysbus_connect_irq(SYS_BUS_DEVICE(&s->dpdma), 0,
> gic_spi[DPDMA_IRQ]);
> +object_property_set_bool(OBJECT(&s->dp), true, "realized", &err);
> +object_property_set_bool(OBJECT(&s->dpdma), true, "realized", &err);
 Can you add something to check these errors?
>>>
>>> Ok.
>> Thanks
>>
>>> BTW I'll move the I2C and AUX device out of xlnx-dp and put that here.
>>> Is that ok with you?
>> That should be fine. Is there a reason you are doing that? Does
>> anything else need to access them?
> No I don't thing anything else is accessing that. It's just a screen
> specific stuff.
> If it's fine like this then I don't bother changing that.

I think it is fine as is.

Thanks,

Alistair

>
> Fred
>
>>
>> Thanks,
>>
>> Alistair
>>
>>> Thanks,
>>> Fred
>>>
 Thanks,

 Alistair

> +object_property_set_link(OBJECT(&s->dp), OBJECT(&s->dpdma), "dpdma",
> + &error_abort);
>   }
>
>   static Property xlnx_zynqmp_props[] = {
> diff --git a/include/hw/arm/xlnx-zynqmp.h b/include/hw/arm/xlnx-zynqmp.h
> index 4005a99..5a4d6cc 100644
> --- a/include/hw/arm/xlnx-zynqmp.h
> +++ b/include/hw/arm/xlnx-zynqmp.h
> @@ -24,6 +24,8 @@
>   #include "hw/char/cadence_uart.h"
>   #include "hw/ide/pci.h"
>   #include "hw/ide/ahci.h"
> +#include "hw/dma/xlnx_dpdma.h"
> +#include "hw/display/xlnx_dp.h"
>
>   #define TYPE_XLNX_ZYNQMP "xlnx,zynqmp"
>   #define XLNX_ZYNQMP(obj) OBJECT_CHECK(XlnxZynqMPState, (obj), \
> @@ -66,6 +68,9 @@ typedef struct XlnxZynqMPState {
>
>   char *boot_cpu;
>   ARMCPU *boot_cpu_ptr;
> +
> +XlnxDPState dp;
> +XlnxDPDMAState dpdma;
>   }  XlnxZynqMPState;
>
>   #define XLNX_ZYNQMP_H
> --
> 1.9.0
>
>
>>>
>
>



[Qemu-devel] [PATCH for-2.6 v2 07/10] fdc: add physical disk sizes

2015-12-07 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.

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 9bb3021..12a2595 100644
--- a/hw/block/fdc.c
+++ b/hw/block/fdc.c
@@ -59,6 +59,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;
@@ -75,11 +81,15 @@ typedef struct FDFormat {
 #define FDRIVE_DEFAULT FLOPPY_DRIVE_TYPE_AUTO
 #define FDRIVE_AUTO_FALLBACK FLOPPY_DRIVE_TYPE_144
 
+/* 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, },
@@ -93,7 +103,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" 1400 */
 { 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, },
@@ -101,15 +111,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, },
@@ -117,11 +127,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




[Qemu-devel] [PATCH for-2.6 v2 06/10] fdc: implement new drive type property

2015-12-07 Thread John Snow
Respect the drive type as given via the CLI.

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.)

The pick_geometry algorithm is modified to only allow matches outside
of the existing drive type for the new auto behavior. If a user specifies
the "none" type, QEMU will not report this drive to the CMOS.

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

diff --git a/hw/block/fdc.c b/hw/block/fdc.c
index 39e680b..9bb3021 100644
--- a/hw/block/fdc.c
+++ b/hw/block/fdc.c
@@ -161,10 +161,12 @@ typedef struct FDrive {
 bool media_inserted;  /* Is there a medium in the tray */
 } FDrive;
 
+static FloppyDriveType get_default_drive_type(FDrive *drv);
+
 static void fd_init(FDrive *drv)
 {
 /* Drive */
-drv->drive = FLOPPY_DRIVE_TYPE_NONE;
+drv->drive = get_default_drive_type(drv);
 drv->perpendicular = 0;
 /* Disk */
 drv->disk = FLOPPY_DRIVE_TYPE_NONE;
@@ -277,7 +279,7 @@ static bool 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) {
@@ -291,13 +293,17 @@ static bool pick_geometry(FDrive *drv)
 }
 if (match == -1) {
 if (first_match == -1) {
-match = 1;
+/* No entry found: drive_type was NONE or we neglected to add any
+ * candidate geometries for our drive type into the fd_formats 
table
+ */
+match = ARRAY_SIZE(fd_formats) - 1;
 } else {
 match = first_match;
 }
 parse = &fd_formats[match];
 }
 
+ out:
 if (parse->max_head == 0) {
 drv->flags &= ~FDISK_DBL_SIDES;
 } else {
@@ -319,8 +325,16 @@ static bool pick_geometry(FDrive *drv)
 
 static void pick_drive_type(FDrive *drv)
 {
-if (pick_geometry(drv)) {
-drv->drive = drv->disk;
+if (drv->drive != FLOPPY_DRIVE_TYPE_AUTO) {
+return;
+}
+
+if (!drv->media_inserted) {
+drv->drive = FDRIVE_AUTO_FALLBACK;
+} else {
+if (pick_geometry(drv)) {
+drv->drive = drv->disk;
+}
 }
 }
 
@@ -623,6 +637,27 @@ typedef struct FDCtrlISABus {
 int32_t bootindexB;
 } FDCtrlISABus;
 
+static FloppyDriveType get_default_drive_type(FDrive *drv)
+{
+FDCtrl *fdctrl = drv->fdctrl;
+
+g_assert_cmpint(MAX_FD, ==, 2);
+
+if (!drv->blk) {
+return FLOPPY_DRIVE_TYPE_NONE;
+}
+
+if (drv == &fdctrl->drives[0]) {
+return fdctrl->typeA;
+}
+
+if (drv == &fdctrl->drives[1]) {
+return fdctrl->typeB;
+}
+
+return FDRIVE_DEFAULT;
+}
+
 static uint32_t fdctrl_read (void *opaque, uint32_t reg)
 {
 FDCtrl *fdctrl = opaque;
-- 
2.4.3




[Qemu-devel] [PATCH for-2.6 v2 04/10] fdc: add default drive type option

2015-12-07 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 explicit
behaviors: 120, 144, 288, auto, and none. The new "auto" behavior
is intended to mimick current behavior, while the other types pick
one explicitly.

In a future patch, the goal is to change the FDC's default drive type
from auto (falling back to 1.44MB) to auto (falling back to 2.88MB).

In order to allow users to obtain the old behaviors, though, a mechanism
for specifying the exact type of drive we want is needed.

This patch adds the properties, but it is not acted on yet in favor of
making those changes a little more explicitly clear in standalone patches
later in this patch set.

Signed-off-by: John Snow 
---
 hw/block/fdc.c   | 108 ++-
 hw/core/qdev-properties.c|  11 +
 hw/i386/pc.c |  17 +++
 include/hw/block/fdc.h   |   9 +---
 include/hw/qdev-properties.h |   1 +
 qapi/block.json  |  16 +++
 6 files changed, 103 insertions(+), 59 deletions(-)

diff --git a/hw/block/fdc.c b/hw/block/fdc.c
index 13fef23..498eb9c 100644
--- a/hw/block/fdc.c
+++ b/hw/block/fdc.c
@@ -60,58 +60,66 @@ typedef enum FDriveRate {
 } FDriveRate;
 
 typedef struct FDFormat {
-FDriveType drive;
+FloppyDriveType drive;
 uint8_t last_sect;
 uint8_t max_track;
 uint8_t max_head;
 FDriveRate rate;
 } FDFormat;
 
+/**
+ * FDRIVE_DEFAULT: The default drive type if none specified.
+ * FDRIVE_AUTO_FALLBACK: The default drive type to assume if
+ *   no media is inserted.
+ */
+#define FDRIVE_DEFAULT FLOPPY_DRIVE_TYPE_AUTO
+#define FDRIVE_AUTO_FALLBACK FLOPPY_DRIVE_TYPE_144
+
 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_25

[Qemu-devel] [PATCH for-2.6 v2 10/10] fdc: change auto fallback drive to 288

2015-12-07 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.

Signed-off-by: John Snow 
---
 hw/block/fdc.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/hw/block/fdc.c b/hw/block/fdc.c
index 246bd83..a82ddd0 100644
--- a/hw/block/fdc.c
+++ b/hw/block/fdc.c
@@ -79,7 +79,7 @@ typedef struct FDFormat {
  *   no media is inserted.
  */
 #define FDRIVE_DEFAULT FLOPPY_DRIVE_TYPE_AUTO
-#define FDRIVE_AUTO_FALLBACK FLOPPY_DRIVE_TYPE_144
+#define FDRIVE_AUTO_FALLBACK FLOPPY_DRIVE_TYPE_288
 
 /* In many cases, the total sector size of a format is enough to uniquely
  * identify it. However, there are some total sector collisions between
-- 
2.4.3




[Qemu-devel] [PATCH for-2.6 v2 08/10] fdc: rework pick_geometry

2015-12-07 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 and type matches, choose it.
 - Fall back to the first geometry that matched our type.

The new one is:
 - If the size 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 | 63 +-
 1 file changed, 40 insertions(+), 23 deletions(-)

diff --git a/hw/block/fdc.c b/hw/block/fdc.c
index 12a2595..246bd83 100644
--- a/hw/block/fdc.c
+++ b/hw/block/fdc.c
@@ -132,7 +132,6 @@ static const FDFormat fd_formats[] = {
 { FLOPPY_DRIVE_TYPE_NONE, -1, -1, 0, 0, },
 };
 
-__attribute__((__unused__))
 static FDriveSize drive_size(FloppyDriveType drive)
 {
 switch (drive) {
@@ -287,45 +286,63 @@ static bool 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) {
 return false;
 }
 
+/* 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 number of sectors,
+ * (4) 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, &nb_sectors);
-match = -1;
-first_match = -1;
+match = size_match = type_match = -1;
 for (i = 0; ; i++) {
 parse = &fd_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;
-}
-if (first_match == -1) {
-first_match = i;
+size = (parse->max_head + 1) * parse->max_track * parse->last_sect;
+if (nb_sectors == size) {
+if (magic || parse->drive == drv->drive) {
+/* (1) perfect match */
+goto out;
+} else if (drive_size(parse->drive) == drive_size(drv->drive)) {
+/* (2) physical size match */
+match = (match == -1) ? i : match;
+} else {
+/* (3) nsectors match only */
+size_match = (size_match == -1) ? i : size_match;
 }
+} else if ((type_match == -1) &&
+   ((parse->drive == drv->drive) ||
+(magic && (parse->drive == FDRIVE_AUTO_FALLBACK {
+/* (4) type matches, or type matches the autodetect default if we
+ * are using the autodetect mechanism. */
+type_match = i;
 }
 }
+
 if (match == -1) {
-if (first_match == -1) {
-/* No entry found: drive_type was NONE or we neglected to add any
- * candidate geometries for our drive type into the fd_formats 
table
- */
-match = ARRAY_SIZE(fd_formats) - 1;
-} else {
-match = first_match;
-}
-parse = &fd_formats[match];
+match = (size_match != -1) ? size_match : type_match;
+}
+
+if (match == -1) {
+/* No entry found: drive_type was NONE or we neglected to add any
+ * candidate geometries for our drive type into the fd_formats table. 
*/
+match = ARRAY_SIZE(fd_formats) - 1;
 }
+parse = &(fd_formats[match]);
 
  out:
 if (parse->max_head == 0) {
-- 
2.4.3




[Qemu-devel] [PATCH for-2.6 v2 05/10] fdc: do not call revalidate on eject

2015-12-07 Thread John Snow
Currently, fd_revalidate is called in two different places, with two
different expectations of behavior:

(1) On initialization, as a routine to help pick the drive type and
initial geometries as a side-effect of the pick_geometry routine

(2) On insert/eject, which either sets the geometries to a default value
or chooses new geometries based on the inserted diskette.

Break this nonsense apart by creating a new function dedicated towards
picking the drive type on initialization.

This has a few results:

(1) fd_revalidate does not get called on boot anymore for drives with no
diskette.

(2) pick_geometry will actually get called twice if we have a diskette
inserted, but this is harmless. (Once for the drive type, and once
as part of the media callback.)

Signed-off-by: John Snow 
---
 hw/block/fdc.c | 36 +---
 1 file changed, 29 insertions(+), 7 deletions(-)

diff --git a/hw/block/fdc.c b/hw/block/fdc.c
index 498eb9c..39e680b 100644
--- a/hw/block/fdc.c
+++ b/hw/block/fdc.c
@@ -170,6 +170,7 @@ static void fd_init(FDrive *drv)
 drv->disk = FLOPPY_DRIVE_TYPE_NONE;
 drv->last_sect = 0;
 drv->max_track = 0;
+drv->ro = true;
 }
 
 #define NUM_SIDES(drv) ((drv)->flags & FDISK_DBL_SIDES ? 2 : 1)
@@ -252,13 +253,21 @@ 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.
+ */
+static bool 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 false;
+}
+
 blk_get_geometry(blk, &nb_sectors);
 match = -1;
 first_match = -1;
@@ -296,8 +305,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->disk = parse->drive;
 drv->media_rate = parse->rate;
 
 if (drv->media_inserted) {
@@ -306,6 +314,14 @@ static void pick_geometry(FDrive *drv)
drv->max_track, drv->last_sect,
drv->ro ? "ro" : "rw");
 }
+return true;
+}
+
+static void pick_drive_type(FDrive *drv)
+{
+if (pick_geometry(drv)) {
+drv->drive = drv->disk;
+}
 }
 
 /* Revalidate a disk drive after a disk change */
@@ -314,15 +330,18 @@ static void fd_revalidate(FDrive *drv)
 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");
+drv->disk = FLOPPY_DRIVE_TYPE_NONE;
+} else {
+pick_geometry(drv);
 }
 } else {
 FLOPPY_DPRINTF("No drive connected\n");
 drv->last_sect = 0;
 drv->max_track = 0;
 drv->flags &= ~FDISK_DBL_SIDES;
+drv->disk = FLOPPY_DRIVE_TYPE_NONE;
 }
 }
 
@@ -2194,9 +2213,11 @@ 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);
+
+if (load) {
+fd_revalidate(drive);
+}
 }
 
 static bool fdctrl_is_tray_open(void *opaque)
@@ -2232,11 +2253,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, &fdctrl_block_ops, drive);
 drive->media_inserted = blk_is_inserted(drive->blk);
+pick_drive_type(drive);
 }
+fdctrl_change_cb(drive, drive->media_inserted);
 }
 }
 
-- 
2.4.3




[Qemu-devel] [PATCH for-2.6 v2 00/10] fdc: fix 2.88mb floppy diskette support

2015-12-07 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.

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

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

(4) Change the automatic fallback type for the automatic guessing
heuristic from 1.44MB to 2.88MB as it is a more diverse drive.

(5) 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.

If any guests are discovered to be unable to cope with this default,
they are free to choose a 1.44MB drive type at boot, or insert an
appropriate diskette. By and large, this appears to improve the
diskette compatibility for most guests.



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-v2:
https://github.com/jnsnow/qemu/releases/tag/fdc-default-v2

John Snow (10):
  fdc: move pick_geometry
  fdc: refactor pick_geometry
  fdc: add disk field
  fdc: add default drive type option
  fdc: do not call revalidate on eject
  fdc: implement new drive type property
  fdc: add physical disk sizes
  fdc: rework pick_geometry
  qtest/fdc: Support for 2.88MB drives
  fdc: change auto fallback drive to 288

 hw/block/fdc.c   | 317 +--
 hw/core/qdev-properties.c|  11 ++
 hw/i386/pc.c |  17 +--
 include/hw/block/fdc.h   |   9 +-
 include/hw/qdev-properties.h |   1 +
 qapi/block.json  |  16 +++
 tests/fdc-test.c |   2 +-
 7 files changed, 255 insertions(+), 118 deletions(-)

-- 
2.4.3




[Qemu-devel] [PATCH for-2.6 v2 09/10] qtest/fdc: Support for 2.88MB drives

2015-12-07 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.

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 for-2.6 v2 01/10] fdc: move pick_geometry

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

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 4292ece..246b631 100644
--- a/hw/block/fdc.c
+++ b/hw/block/fdc.c
@@ -114,51 +114,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, &nb_sectors);
-match = -1;
-first_match = -1;
-for (i = 0; ; i++) {
-parse = &fd_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 = &fd_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))
 
@@ -286,6 +241,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, &nb_sectors);
+match = -1;
+first_match = -1;
+for (i = 0; ; i++) {
+parse = &fd_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 = &fd_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 for-2.6 v2 02/10] fdc: refactor pick_geometry

2015-12-07 Thread John Snow
Modify this function to operate directly on FDrive objects instead of
unpacking and passing all of those parameters manually.

Helps reduce complexity in each caller, and reduces the number of args.

Signed-off-by: John Snow 
---
 hw/block/fdc.c | 54 +++---
 1 file changed, 23 insertions(+), 31 deletions(-)

diff --git a/hw/block/fdc.c b/hw/block/fdc.c
index 246b631..09bb63d 100644
--- a/hw/block/fdc.c
+++ b/hw/block/fdc.c
@@ -241,11 +241,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;
@@ -258,8 +256,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) {
@@ -279,41 +277,35 @@ static void pick_geometry(BlockBackend *blk, int 
*nb_heads,
 }
 parse = &fd_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;
+
+if (drv->media_inserted) {
+FLOPPY_DPRINTF("Floppy disk (%d h %d t %d s) %s\n",
+   parse->max_head + 1,
+   drv->max_track, drv->last_sect,
+   drv->ro ? "ro" : "rw");
+}
 }
 
 /* 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, &nb_heads, &max_track,
-  &last_sect, drv->drive, &drive, &rate);
+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");
 }
-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 for-2.6 v2 03/10] fdc: add disk field

2015-12-07 Thread John Snow
This allows us to distinguish between the current disk type and the
current drive type. The drive is what's reported to CMOS, the disk is
whatever the pick_geometry function suspects has been inserted.

The drive field maintains the exact same meaning as it did previously,
however pick_geometry/fd_revalidate will be refactored to *never* update
the drive field, considering it frozen in-place during an earlier
initialization call.

Before this patch, pick_geometry/fd_revalidate could only change the
drive field when it was FDRIVE_DRV_NONE, which indicated that we had
not yet reported our drive type to CMOS. After we "pick one," even
though pick_geometry/fd_revalidate re-set drv->drive, it should always
be the same as the value going into these calls, so it is effectively
already static.

As of this patch, disk and drive will always be the same, but that may
not be true by the end of this series.

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.

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

diff --git a/hw/block/fdc.c b/hw/block/fdc.c
index 09bb63d..13fef23 100644
--- a/hw/block/fdc.c
+++ b/hw/block/fdc.c
@@ -133,7 +133,8 @@ typedef struct FDrive {
 FDCtrl *fdctrl;
 BlockBackend *blk;
 /* Drive status */
-FDriveType drive;
+FDriveType drive; /* CMOS drive type */
+FDriveType disk;  /* Current disk type */
 uint8_t perpendicular;/* 2.88 MB access mode*/
 /* Position */
 uint8_t head;
@@ -157,6 +158,7 @@ static void fd_init(FDrive *drv)
 drv->drive = FDRIVE_DRV_NONE;
 drv->perpendicular = 0;
 /* Disk */
+drv->disk = FDRIVE_DRV_NONE;
 drv->last_sect = 0;
 drv->max_track = 0;
 }
@@ -286,6 +288,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 : FDRIVE_DRV_NONE;
 drv->media_rate = parse->rate;
 
 if (drv->media_inserted) {
-- 
2.4.3




[Qemu-devel] [PATCH v6 5/5] i.MX: move i.MX31 CCM object to register array.

2015-12-07 Thread Jean-Christophe Dubois
With this i.MX25 and i.MX31 to have close implementation.

Moreover all i.MX31 CCM registers are now present

Signed-off-by: Jean-Christophe Dubois 
---

Changes since v1:
 * Not present

Changes since v2:
 * Not present

Changes since v3:
 * Not present

Changes since v4:
 * Not present

Changes since v5:
 * Not present

 hw/misc/imx31_ccm.c | 188 
 include/hw/misc/imx31_ccm.h |  38 +++--
 2 files changed, 115 insertions(+), 111 deletions(-)

diff --git a/hw/misc/imx31_ccm.c b/hw/misc/imx31_ccm.c
index b92d2e0..47d6ead 100644
--- a/hw/misc/imx31_ccm.c
+++ b/hw/misc/imx31_ccm.c
@@ -29,77 +29,73 @@
 
 static char const *imx31_ccm_reg_name(uint32_t reg)
 {
+static char unknown[20];
+
 switch (reg) {
-case 0:
+case IMX31_CCM_CCMR_REG:
 return "CCMR";
-case 1:
+case IMX31_CCM_PDR0_REG:
 return "PDR0";
-case 2:
+case IMX31_CCM_PDR1_REG:
 return "PDR1";
-case 3:
+case IMX31_CCM_RCSR_REG:
 return "RCSR";
-case 4:
+case IMX31_CCM_MPCTL_REG:
 return "MPCTL";
-case 5:
+case IMX31_CCM_UPCTL_REG:
 return "UPCTL";
-case 6:
+case IMX31_CCM_SPCTL_REG:
 return "SPCTL";
-case 7:
+case IMX31_CCM_COSR_REG:
 return "COSR";
-case 8:
+case IMX31_CCM_CGR0_REG:
 return "CGR0";
-case 9:
+case IMX31_CCM_CGR1_REG:
 return "CGR1";
-case 10:
+case IMX31_CCM_CGR2_REG:
 return "CGR2";
-case 11:
+case IMX31_CCM_WIMR_REG:
 return "WIMR";
-case 12:
+case IMX31_CCM_LDC_REG:
 return "LDC";
-case 13:
+case IMX31_CCM_DCVR0_REG:
 return "DCVR0";
-case 14:
+case IMX31_CCM_DCVR1_REG:
 return "DCVR1";
-case 15:
+case IMX31_CCM_DCVR2_REG:
 return "DCVR2";
-case 16:
+case IMX31_CCM_DCVR3_REG:
 return "DCVR3";
-case 17:
+case IMX31_CCM_LTR0_REG:
 return "LTR0";
-case 18:
+case IMX31_CCM_LTR1_REG:
 return "LTR1";
-case 19:
+case IMX31_CCM_LTR2_REG:
 return "LTR2";
-case 20:
+case IMX31_CCM_LTR3_REG:
 return "LTR3";
-case 21:
+case IMX31_CCM_LTBR0_REG:
 return "LTBR0";
-case 22:
+case IMX31_CCM_LTBR1_REG:
 return "LTBR1";
-case 23:
+case IMX31_CCM_PMCR0_REG:
 return "PMCR0";
-case 24:
+case IMX31_CCM_PMCR1_REG:
 return "PMCR1";
-case 25:
+case IMX31_CCM_PDR2_REG:
 return "PDR2";
 default:
-return "???";
+sprintf(unknown, "[%d ?]", reg);
+return unknown;
 }
 }
 
 static const VMStateDescription vmstate_imx31_ccm = {
 .name = TYPE_IMX31_CCM,
-.version_id = 1,
-.minimum_version_id = 1,
+.version_id = 2,
+.minimum_version_id = 2,
 .fields = (VMStateField[]) {
-VMSTATE_UINT32(ccmr, IMX31CCMState),
-VMSTATE_UINT32(pdr0, IMX31CCMState),
-VMSTATE_UINT32(pdr1, IMX31CCMState),
-VMSTATE_UINT32(mpctl, IMX31CCMState),
-VMSTATE_UINT32(spctl, IMX31CCMState),
-VMSTATE_UINT32_ARRAY(cgr, IMX31CCMState, 3),
-VMSTATE_UINT32(pmcr0, IMX31CCMState),
-VMSTATE_UINT32(pmcr1, IMX31CCMState),
+VMSTATE_UINT32_ARRAY(reg, IMX31CCMState, IMX31_CCM_MAX_REG),
 VMSTATE_END_OF_LIST()
 },
 };
@@ -109,10 +105,10 @@ static uint32_t imx31_ccm_get_pll_ref_clk(IMXCCMState 
*dev)
 uint32_t freq = 0;
 IMX31CCMState *s = IMX31_CCM(dev);
 
-if ((s->ccmr & CCMR_PRCS) == 2) {
-if (s->ccmr & CCMR_FPME) {
+if ((s->reg[IMX31_CCM_CCMR_REG] & CCMR_PRCS) == 2) {
+if (s->reg[IMX31_CCM_CCMR_REG] & CCMR_FPME) {
 freq = CKIL_FREQ;
-if (s->ccmr & CCMR_FPMF) {
+if (s->reg[IMX31_CCM_CCMR_REG] & CCMR_FPMF) {
 freq *= 1024;
 }
 } 
@@ -130,7 +126,8 @@ static uint32_t imx31_ccm_get_mpll_clk(IMXCCMState *dev)
 uint32_t freq;
 IMX31CCMState *s = IMX31_CCM(dev);
 
-freq = imx_ccm_calc_pll(s->mpctl, imx31_ccm_get_pll_ref_clk(dev));
+freq = imx_ccm_calc_pll(s->reg[IMX31_CCM_MPCTL_REG],
+imx31_ccm_get_pll_ref_clk(dev));
 
 DPRINTF("freq = %d\n", freq);
 
@@ -142,7 +139,8 @@ static uint32_t imx31_ccm_get_mcu_main_clk(IMXCCMState *dev)
 uint32_t freq;
 IMX31CCMState *s = IMX31_CCM(dev);
 
-if ((s->ccmr & CCMR_MDS) || !(s->ccmr & CCMR_MPE)) {
+if ((s->reg[IMX31_CCM_CCMR_REG] & CCMR_MDS) ||
+!(s->reg[IMX31_CCM_CCMR_REG] & CCMR_MPE)) {
 freq = imx31_ccm_get_pll_ref_clk(dev);
 } else {
 freq = imx31_ccm_get_mpll_clk(dev);
@@ -158,7 +156,8 @@ static uint32_t imx31_ccm_get_mcu_clk(IMXCCMState *dev)
 uint32_t freq;
 IMX31CCMState *s = IMX31_CCM(dev);
 
-freq = imx31_ccm_get_mcu_main_clk(dev) / (1 + EXTRACT(s->pdr0, MCU));
+freq = imx31_ccm_get_mcu_main_clk(dev)
+   / (1 + EXTRACT(s->reg[IMX31_CCM_PDR0_REG],

[Qemu-devel] [PATCH v6 3/5] i.MX: Split the CCM class into an abstact base class and a concrete class.

2015-12-07 Thread Jean-Christophe Dubois
The IMX_CCM class is now the base abstract class that is used by EPIT and GPT
timer implementation.

IMX31_CCM class is the concrete class implementing CCM for i.MX31 SOC.

For now the i.MX25 continues to use the i.MX31 CCM implementation.

An i.MX25 specific CCM will be introduced in a later patch.

We also rework initialization to stop using deprecated sysbus device init

Signed-off-by: Jean-Christophe Dubois 
Reviewed-by: Peter Crosthwaite 
---

Changes since v1:
 * None 
 
Changes since v2:
 * We moved to an inheritance QOM scheme
 
Changes since v3:
 * Rework logging based on comment on i.MX25 CCM patch.
 * Change abstract class function parameter to abstract class type instead
   of DEVICE type.
 * EPIT and GPT timers use abstract class instead of DEVICE class.

Changes sinve v4:
 * improve debug logging.
 * make IPG clk dependent on HCLK clk.

Changes since v5:
 * None

 hw/arm/fsl-imx25.c  |   6 +-
 hw/arm/fsl-imx31.c  |   6 +-
 hw/misc/Makefile.objs   |   1 +
 hw/misc/imx31_ccm.c | 392 
 hw/misc/imx_ccm.c   | 231 +++---
 include/hw/arm/fsl-imx25.h  |   4 +-
 include/hw/arm/fsl-imx31.h  |   4 +-
 include/hw/misc/imx31_ccm.h |  66 
 include/hw/misc/imx_ccm.h   |  69 +++-
 include/hw/timer/imx_epit.h |   5 +-
 include/hw/timer/imx_gpt.h  |   5 +-
 11 files changed, 521 insertions(+), 268 deletions(-)
 create mode 100644 hw/misc/imx31_ccm.c
 create mode 100644 include/hw/misc/imx31_ccm.h

diff --git a/hw/arm/fsl-imx25.c b/hw/arm/fsl-imx25.c
index e1cadac..9f302ed 100644
--- a/hw/arm/fsl-imx25.c
+++ b/hw/arm/fsl-imx25.c
@@ -38,7 +38,7 @@ static void fsl_imx25_init(Object *obj)
 object_initialize(&s->avic, sizeof(s->avic), TYPE_IMX_AVIC);
 qdev_set_parent_bus(DEVICE(&s->avic), sysbus_get_default());
 
-object_initialize(&s->ccm, sizeof(s->ccm), TYPE_IMX_CCM);
+object_initialize(&s->ccm, sizeof(s->ccm), TYPE_IMX31_CCM);
 qdev_set_parent_bus(DEVICE(&s->ccm), sysbus_get_default());
 
 for (i = 0; i < FSL_IMX25_NUM_UARTS; i++) {
@@ -150,7 +150,7 @@ static void fsl_imx25_realize(DeviceState *dev, Error 
**errp)
 { FSL_IMX25_GPT4_ADDR, FSL_IMX25_GPT4_IRQ }
 };
 
-s->gpt[i].ccm = DEVICE(&s->ccm);
+s->gpt[i].ccm = IMX_CCM(&s->ccm);
 
 object_property_set_bool(OBJECT(&s->gpt[i]), true, "realized", &err);
 if (err) {
@@ -173,7 +173,7 @@ static void fsl_imx25_realize(DeviceState *dev, Error 
**errp)
 { FSL_IMX25_EPIT2_ADDR, FSL_IMX25_EPIT2_IRQ }
 };
 
-s->epit[i].ccm = DEVICE(&s->ccm);
+s->epit[i].ccm = IMX_CCM(&s->ccm);
 
 object_property_set_bool(OBJECT(&s->epit[i]), true, "realized", &err);
 if (err) {
diff --git a/hw/arm/fsl-imx31.c b/hw/arm/fsl-imx31.c
index 53d4473..abdea06 100644
--- a/hw/arm/fsl-imx31.c
+++ b/hw/arm/fsl-imx31.c
@@ -35,7 +35,7 @@ static void fsl_imx31_init(Object *obj)
 object_initialize(&s->avic, sizeof(s->avic), TYPE_IMX_AVIC);
 qdev_set_parent_bus(DEVICE(&s->avic), sysbus_get_default());
 
-object_initialize(&s->ccm, sizeof(s->ccm), TYPE_IMX_CCM);
+object_initialize(&s->ccm, sizeof(s->ccm), TYPE_IMX31_CCM);
 qdev_set_parent_bus(DEVICE(&s->ccm), sysbus_get_default());
 
 for (i = 0; i < FSL_IMX31_NUM_UARTS; i++) {
@@ -128,7 +128,7 @@ static void fsl_imx31_realize(DeviceState *dev, Error 
**errp)
 serial_table[i].irq));
 }
 
-s->gpt.ccm = DEVICE(&s->ccm);
+s->gpt.ccm = IMX_CCM(&s->ccm);
 
 object_property_set_bool(OBJECT(&s->gpt), true, "realized", &err);
 if (err) {
@@ -150,7 +150,7 @@ static void fsl_imx31_realize(DeviceState *dev, Error 
**errp)
 { FSL_IMX31_EPIT2_ADDR, FSL_IMX31_EPIT2_IRQ },
 };
 
-s->epit[i].ccm = DEVICE(&s->ccm);
+s->epit[i].ccm = IMX_CCM(&s->ccm);
 
 object_property_set_bool(OBJECT(&s->epit[i]), true, "realized", &err);
 if (err) {
diff --git a/hw/misc/Makefile.objs b/hw/misc/Makefile.objs
index aeb6b7d..c77f3e3 100644
--- a/hw/misc/Makefile.objs
+++ b/hw/misc/Makefile.objs
@@ -26,6 +26,7 @@ obj-$(CONFIG_NSERIES) += cbus.o
 obj-$(CONFIG_ECCMEMCTL) += eccmemctl.o
 obj-$(CONFIG_EXYNOS4) += exynos4210_pmu.o
 obj-$(CONFIG_IMX) += imx_ccm.o
+obj-$(CONFIG_IMX) += imx31_ccm.o
 obj-$(CONFIG_MILKYMIST) += milkymist-hpdmc.o
 obj-$(CONFIG_MILKYMIST) += milkymist-pfpu.o
 obj-$(CONFIG_MAINSTONE) += mst_fpga.o
diff --git a/hw/misc/imx31_ccm.c b/hw/misc/imx31_ccm.c
new file mode 100644
index 000..b92d2e0
--- /dev/null
+++ b/hw/misc/imx31_ccm.c
@@ -0,0 +1,392 @@
+/*
+ * IMX31 Clock Control Module
+ *
+ * Copyright (C) 2012 NICTA
+ * Updated by Jean-Christophe Dubois 
+ *
+ * This work is licensed under the terms of the GNU GPL, version 2 or later.
+ * See the COPYING file in the top-level directory.
+ *
+ * To get the timer frequencies right, we need to emulate at least part of
+ * the i.MX31 CCM.
+ */
+

[Qemu-devel] [PATCH v6 4/5] i.MX: Add an i.MX25 specific CCM class/instance.

2015-12-07 Thread Jean-Christophe Dubois
With this CCM, i.MX25 timer is accurate with "real world time".

Signed-off-by: Jean-Christophe Dubois 
Reviewed-by Peter Crosthwaite 
---

Changes since v1:
 * rework loging to match other i.MX drivers

Changes since v2:
 * We moved to an inheritance QOM scheme

Changes since v3:
 * Rework logging based on comments.

Changes since v4:
 * Improve debug logging.

Changes since v5:
 * move object state to uint32 array.

 hw/arm/fsl-imx25.c  |   2 +-
 hw/misc/Makefile.objs   |   1 +
 hw/misc/imx25_ccm.c | 341 
 include/hw/arm/fsl-imx25.h  |   4 +-
 include/hw/misc/imx25_ccm.h |  79 ++
 5 files changed, 424 insertions(+), 3 deletions(-)
 create mode 100644 hw/misc/imx25_ccm.c
 create mode 100644 include/hw/misc/imx25_ccm.h

diff --git a/hw/arm/fsl-imx25.c b/hw/arm/fsl-imx25.c
index 9f302ed..36818ee 100644
--- a/hw/arm/fsl-imx25.c
+++ b/hw/arm/fsl-imx25.c
@@ -38,7 +38,7 @@ static void fsl_imx25_init(Object *obj)
 object_initialize(&s->avic, sizeof(s->avic), TYPE_IMX_AVIC);
 qdev_set_parent_bus(DEVICE(&s->avic), sysbus_get_default());
 
-object_initialize(&s->ccm, sizeof(s->ccm), TYPE_IMX31_CCM);
+object_initialize(&s->ccm, sizeof(s->ccm), TYPE_IMX25_CCM);
 qdev_set_parent_bus(DEVICE(&s->ccm), sysbus_get_default());
 
 for (i = 0; i < FSL_IMX25_NUM_UARTS; i++) {
diff --git a/hw/misc/Makefile.objs b/hw/misc/Makefile.objs
index c77f3e3..8a235df 100644
--- a/hw/misc/Makefile.objs
+++ b/hw/misc/Makefile.objs
@@ -27,6 +27,7 @@ obj-$(CONFIG_ECCMEMCTL) += eccmemctl.o
 obj-$(CONFIG_EXYNOS4) += exynos4210_pmu.o
 obj-$(CONFIG_IMX) += imx_ccm.o
 obj-$(CONFIG_IMX) += imx31_ccm.o
+obj-$(CONFIG_IMX) += imx25_ccm.o
 obj-$(CONFIG_MILKYMIST) += milkymist-hpdmc.o
 obj-$(CONFIG_MILKYMIST) += milkymist-pfpu.o
 obj-$(CONFIG_MAINSTONE) += mst_fpga.o
diff --git a/hw/misc/imx25_ccm.c b/hw/misc/imx25_ccm.c
new file mode 100644
index 000..23759ca
--- /dev/null
+++ b/hw/misc/imx25_ccm.c
@@ -0,0 +1,341 @@
+/*
+ * IMX25 Clock Control Module
+ *
+ * Copyright (C) 2012 NICTA
+ * Updated by Jean-Christophe Dubois 
+ *
+ * This work is licensed under the terms of the GNU GPL, version 2 or later.
+ * See the COPYING file in the top-level directory.
+ *
+ * To get the timer frequencies right, we need to emulate at least part of
+ * the CCM.
+ */
+
+#include "hw/misc/imx25_ccm.h"
+
+#ifndef DEBUG_IMX25_CCM
+#define DEBUG_IMX25_CCM 0
+#endif
+
+#define DPRINTF(fmt, args...) \
+do { \
+if (DEBUG_IMX25_CCM) { \
+fprintf(stderr, "[%s]%s: " fmt , TYPE_IMX25_CCM, \
+ __func__, ##args); \
+} \
+} while (0)
+
+static char const *imx25_ccm_reg_name(uint32_t reg)
+{
+static char unknown[20];
+
+switch (reg) {
+case IMX25_CCM_MPCTL_REG:
+return "mpctl";
+case IMX25_CCM_UPCTL_REG:
+return "upctl";
+case IMX25_CCM_CCTL_REG:
+return "cctl";
+case IMX25_CCM_CGCR0_REG:
+return "cgcr0";
+case IMX25_CCM_CGCR1_REG:
+return "cgcr1";
+case IMX25_CCM_CGCR2_REG:
+return "cgcr2";
+case IMX25_CCM_PCDR0_REG:
+return "pcdr0";
+case IMX25_CCM_PCDR1_REG:
+return "pcdr1";
+case IMX25_CCM_PCDR2_REG:
+return "pcdr2";
+case IMX25_CCM_PCDR3_REG:
+return "pcdr3";
+case IMX25_CCM_RCSR_REG:
+return "rcsr";
+case IMX25_CCM_CRDR_REG:
+return "crdr";
+case IMX25_CCM_DCVR0_REG:
+return "dcvr0";
+case IMX25_CCM_DCVR1_REG:
+return "dcvr1";
+case IMX25_CCM_DCVR2_REG:
+return "dcvr2";
+case IMX25_CCM_DCVR3_REG:
+return "dcvr3";
+case IMX25_CCM_LTR0_REG:
+return "ltr0";
+case IMX25_CCM_LTR1_REG:
+return "ltr1";
+case IMX25_CCM_LTR2_REG:
+return "ltr2";
+case IMX25_CCM_LTR3_REG:
+return "ltr3";
+case IMX25_CCM_LTBR0_REG:
+return "ltbr0";
+case IMX25_CCM_LTBR1_REG:
+return "ltbr1";
+case IMX25_CCM_PMCR0_REG:
+return "pmcr0";
+case IMX25_CCM_PMCR1_REG:
+return "pmcr1";
+case IMX25_CCM_PMCR2_REG:
+return "pmcr2";
+case IMX25_CCM_MCR_REG:
+return "mcr";
+case IMX25_CCM_LPIMR0_REG:
+return "lpimr0";
+case IMX25_CCM_LPIMR1_REG:
+return "lpimr1";
+default:
+sprintf(unknown, "[%d ?]", reg);
+return unknown;
+}
+}
+#define CKIH_FREQ 2400 /* 24MHz crystal input */
+
+static const VMStateDescription vmstate_imx25_ccm = {
+.name = TYPE_IMX25_CCM,
+.version_id = 1,
+.minimum_version_id = 1,
+.fields = (VMStateField[]) {
+VMSTATE_UINT32_ARRAY(reg, IMX25CCMState, IMX25_CCM_MAX_REG),
+VMSTATE_END_OF_LIST()
+},
+};
+
+static uint32_t imx25_ccm_get_mpll_clk(IMXCCMState *dev)
+{
+uint32_t freq;
+IMX25CCMState *s = IMX25_CCM(dev);
+
+if (EXTRACT(s->reg[IMX25_CCM_CCTL_REG], MPLL_BYPASS)) {
+freq = CKIH_FREQ;
+} el

[Qemu-devel] [PATCH v6 1/5] i.MX: Fix i.MX31 default/reset configuration.

2015-12-07 Thread Jean-Christophe Dubois
Linux on i.MX31/KZM is expecting the CCM to use the CKIH ref clock instead
of the CKIL plus the FPM multiplier.

We change the CCMR reg reset value to match linux expected config.

This allow the CCM to provide a 39MHz clk (as expected by linux) instead of
the actual 50MHz.

With this change the "sleep 60" command on linux is time accurate with
"real world time".

Signed-off-by: Jean-Christophe Dubois 
Reviewed-by: Peter Crosthwaite 
---
  
Changes since v1:
 * Not present 
 
Changes since v2:
 * Not present 
 
Changes since v3:
 * Not present
 
Changes since v4:
 * Not present
 
Changes since v4:
 * No change

 hw/misc/imx_ccm.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/hw/misc/imx_ccm.c b/hw/misc/imx_ccm.c
index 4cc2bbc..500dda5 100644
--- a/hw/misc/imx_ccm.c
+++ b/hw/misc/imx_ccm.c
@@ -123,7 +123,7 @@ static void imx_ccm_reset(DeviceState *dev)
 {
 IMXCCMState *s = IMX_CCM(dev);
 
-s->ccmr = 0x074b0b7b;
+s->ccmr = 0x074b0b7d;
 s->pdr0 = 0xff870b48;
 s->pdr1 = 0x49fcfe7f;
 s->mpctl = PLL_PD(1) | PLL_MFD(0) | PLL_MFI(6) | PLL_MFN(0);
-- 
2.5.0




[Qemu-devel] [PATCH v6 0/5] Add an i.MX25 specific CCM driver

2015-12-07 Thread Jean-Christophe Dubois
i.MX25 SOC has a different CCM device than i.MX31.

Qemu i.MX25 emulation was built with i.MX31 CCM driver. This allows
Linux to work on top of the i.MX25 emultion but this is not correct.

Furthermore, other SOC we could emulate like i.MX6 have yet a different
implementation of the CCM device.

So we split the i.MX31 into a generic base class and a specific i.MX31
class.

We then add an i.MX25 specific CCM Device and have the i.MX25 SOC use it.

Jean-Christophe Dubois (5):
  i.MX: Fix i.MX31 default/reset configuration.
  i.MX: rename i.MX CCM get_clock() function and CLK ID enum names
  i.MX: Split the CCM class into an abstact base class and a concrete
class.
  i.MX: Add an i.MX25 specific CCM class/instance.
  i.MX: move i.MX31 CCM object to register array.

 hw/arm/fsl-imx25.c  |   6 +-
 hw/arm/fsl-imx31.c  |   6 +-
 hw/misc/Makefile.objs   |   2 +
 hw/misc/imx25_ccm.c | 341 
 hw/misc/imx31_ccm.c | 374 
 hw/misc/imx_ccm.c   | 231 +++
 hw/timer/imx_epit.c |  20 ++-
 hw/timer/imx_gpt.c  |  16 +-
 include/hw/arm/fsl-imx25.h  |   4 +-
 include/hw/arm/fsl-imx31.h  |   4 +-
 include/hw/misc/imx25_ccm.h |  79 ++
 include/hw/misc/imx31_ccm.h |  88 +++
 include/hw/misc/imx_ccm.h   |  75 -
 include/hw/timer/imx_epit.h |   5 +-
 include/hw/timer/imx_gpt.h  |   5 +-
 15 files changed, 966 insertions(+), 290 deletions(-)
 create mode 100644 hw/misc/imx25_ccm.c
 create mode 100644 hw/misc/imx31_ccm.c
 create mode 100644 include/hw/misc/imx25_ccm.h
 create mode 100644 include/hw/misc/imx31_ccm.h

-- 
2.5.0




[Qemu-devel] [PATCH v6 2/5] i.MX: rename i.MX CCM get_clock() function and CLK ID enum names

2015-12-07 Thread Jean-Christophe Dubois
This is to prepare for CCM code refactoring.

This is just a bit of function and enum values renaming.

We also remove some useless intermediate variables.

Signed-off-by: Jean-Christophe Dubois 
Reviewed-by: Peter Crosthwaite 
---

Changes since v1:
 * Not present 
  
Changes since v2:
 * Not present 
 
Changes since v3:
 * None 
 
Changes since v4:
 * None 

Changes since v5:
 * None 

 hw/misc/imx_ccm.c |  8 
 hw/timer/imx_epit.c   | 20 +---
 hw/timer/imx_gpt.c| 16 
 include/hw/misc/imx_ccm.h |  8 
 4 files changed, 25 insertions(+), 27 deletions(-)

diff --git a/hw/misc/imx_ccm.c b/hw/misc/imx_ccm.c
index 500dda5..1ac697a 100644
--- a/hw/misc/imx_ccm.c
+++ b/hw/misc/imx_ccm.c
@@ -49,18 +49,18 @@ static const VMStateDescription vmstate_imx_ccm = {
 .post_load = imx_ccm_post_load,
 };
 
-uint32_t imx_clock_frequency(DeviceState *dev, IMXClk clock)
+uint32_t imx_ccm_get_clock_frequency(DeviceState *dev, IMXClk clock)
 {
 IMXCCMState *s = IMX_CCM(dev);
 
 switch (clock) {
 case NOCLK:
 return 0;
-case MCU:
+case CLK_MCU:
 return s->mcu_clk_freq;
-case HSP:
+case CLK_HSP:
 return s->hsp_clk_freq;
-case IPG:
+case CLK_IPG:
 return s->ipg_clk_freq;
 case CLK_32k:
 return CKIL_FREQ;
diff --git a/hw/timer/imx_epit.c b/hw/timer/imx_epit.c
index 967be4a..50bf83c 100644
--- a/hw/timer/imx_epit.c
+++ b/hw/timer/imx_epit.c
@@ -51,9 +51,9 @@ static char const *imx_epit_reg_name(uint32_t reg)
  * These are typical.
  */
 static const IMXClk imx_epit_clocks[] =  {
-0,/* 00 disabled */
-IPG,  /* 01 ipg_clk, ~532MHz */
-IPG,  /* 10 ipg_clk_highfreq */
+NOCLK,/* 00 disabled */
+CLK_IPG,  /* 01 ipg_clk, ~532MHz */
+CLK_IPG,  /* 10 ipg_clk_highfreq */
 CLK_32k,  /* 11 ipg_clk_32k -- ~32kHz */
 };
 
@@ -73,20 +73,18 @@ static void imx_epit_set_freq(IMXEPITState *s)
 {
 uint32_t clksrc;
 uint32_t prescaler;
-uint32_t freq;
 
 clksrc = extract32(s->cr, CR_CLKSRC_SHIFT, 2);
 prescaler = 1 + extract32(s->cr, CR_PRESCALE_SHIFT, 12);
 
-freq = imx_clock_frequency(s->ccm, imx_epit_clocks[clksrc]) / prescaler;
+s->freq = imx_ccm_get_clock_frequency(s->ccm,
+imx_epit_clocks[clksrc]) / prescaler;
 
-s->freq = freq;
+DPRINTF("Setting ptimer frequency to %u\n", s->freq);
 
-DPRINTF("Setting ptimer frequency to %u\n", freq);
-
-if (freq) {
-ptimer_set_freq(s->timer_reload, freq);
-ptimer_set_freq(s->timer_cmp, freq);
+if (s->freq) {
+ptimer_set_freq(s->timer_reload, s->freq);
+ptimer_set_freq(s->timer_cmp, s->freq);
 }
 }
 
diff --git a/hw/timer/imx_gpt.c b/hw/timer/imx_gpt.c
index 7257f42..b1893b8 100644
--- a/hw/timer/imx_gpt.c
+++ b/hw/timer/imx_gpt.c
@@ -81,8 +81,8 @@ static const VMStateDescription vmstate_imx_timer_gpt = {
 
 static const IMXClk imx_gpt_clocks[] = {
 NOCLK,/* 000 No clock source */
-IPG,  /* 001 ipg_clk, 532MHz*/
-IPG,  /* 010 ipg_clk_highfreq */
+CLK_IPG,  /* 001 ipg_clk, 532MHz*/
+CLK_IPG,  /* 010 ipg_clk_highfreq */
 NOCLK,/* 011 not defined */
 CLK_32k,  /* 100 ipg_clk_32k */
 NOCLK,/* 101 not defined */
@@ -93,14 +93,14 @@ static const IMXClk imx_gpt_clocks[] = {
 static void imx_gpt_set_freq(IMXGPTState *s)
 {
 uint32_t clksrc = extract32(s->cr, GPT_CR_CLKSRC_SHIFT, 3);
-uint32_t freq = imx_clock_frequency(s->ccm, imx_gpt_clocks[clksrc])
-/ (1 + s->pr);
-s->freq = freq;
 
-DPRINTF("Setting clksrc %d to frequency %d\n", clksrc, freq);
+s->freq = imx_ccm_get_clock_frequency(s->ccm,
+imx_gpt_clocks[clksrc]) / (1 + s->pr);
 
-if (freq) {
-ptimer_set_freq(s->timer, freq);
+DPRINTF("Setting clksrc %d to frequency %d\n", clksrc, s->freq);
+
+if (s->freq) {
+ptimer_set_freq(s->timer, s->freq);
 }
 }
 
diff --git a/include/hw/misc/imx_ccm.h b/include/hw/misc/imx_ccm.h
index 0f2e469..09f6248 100644
--- a/include/hw/misc/imx_ccm.h
+++ b/include/hw/misc/imx_ccm.h
@@ -80,12 +80,12 @@ typedef struct IMXCCMState {
 
 typedef enum  {
 NOCLK,
-MCU,
-HSP,
-IPG,
+CLK_MCU,
+CLK_HSP,
+CLK_IPG,
 CLK_32k
 } IMXClk;
 
-uint32_t imx_clock_frequency(DeviceState *s, IMXClk clock);
+uint32_t imx_ccm_get_clock_frequency(DeviceState *s, IMXClk clock);
 
 #endif /* IMX_CCM_H */
-- 
2.5.0




Re: [Qemu-devel] [Qemu-ppc] [PATCH 00/77] ppc: Add "native" POWER8 platform

2015-12-07 Thread Cédric Le Goater
On 12/07/2015 02:25 AM, Stewart Smith wrote:
> Cédric Le Goater  writes:
>> On 11/28/2015 08:59 AM, Benjamin Herrenschmidt wrote:
>>> On Fri, 2015-11-27 at 11:21 +0100, Alexander Graf wrote:

 How does real hardware store petitboot? If it's flash, you could pass it
 in using -pflash and thus model things even more closely and allow users
 to just take the ROM image as is.
>>>
>>> It is a flash image, we could use an Open Power machine flash image "as-is"
>>> provided we taught qemu to extract skiboot (aka OPAL) from it.
>>
>> Couldn't we add an offset argument to load_image_targphys() or make that 
>> an extra routine ? If so, we could then load directly from an openpower 
>> pnor file. 
>>
>> I gave it a quick (and dirty) try and a powernv guest runs fine up to 
>> petitboot with just :
>>
>>  qemu-system-ppc64 -m 2G -M powernv -bios  
>> ~/work/open-power/images/palmetto.pnor -nographic -nodefaults -serial stdio
>>
>> The pnor file is compiled from github. The patch is below (without the dirty
>> cut and paste I did in loader.c). The offset for the PAYLOAD and BOOTKERNEL
>> partitions are hard coded but I guess we don't need to read the flash 
>> partition
>> table in qemu, not yet.
> 
> One downside to this is that if we don't fall back to being able to load
> skiboot.lid it becomes more annoying to boot a gcov enabled skiboot as
> typical PNOR layout only gives 1MB for skiboot, and gcov builds bloat
> that a *lot*.

I guess that what we can imagine having a bigger partition for skiboot 
in the case of gcov ?  This will require a custom pnor build. Might be 
too complex. Or we could use a -pflash option to load the pnor and an
optional -bios for skiboot if we want a custom one.

> We probably don't want NVRAM writes going back to a single system wide
> PNOR image too, so while using pnor file is great for simulating what
> hardware does, may not work as the solution for long term model.

we can use a memory backend to start with, which is also much simpler 
than having to handle the block backend like the cfi pflash is doing. 
a guest could use its own private pnor if a block backend is needed.

C. 




Re: [Qemu-devel] [PATCH v5 00/11] Add basic "detach" support for dump-guest-memory

2015-12-07 Thread Eric Blake
On 12/06/2015 10:56 PM, Peter Xu wrote:
> v5 changes:
> - patch 1
>   - comment English fix [Fam]
> - patch 2
>   - pass has_detach=true always in hmp_dump_guest_memory [Paolo]
> - patch 3
>   - always use local_err and error_propagate() when need to check
> the result [Fam]
> - patch 8
>   - add "DumpQueryResult" in DUMP_COMPLETED event [Eric]
> (since DumpQueryResult is introduced in patch 10, so doing it in
> patch 10 for convenience. Please let me know if I should not do
> this, e.g., if patch re-ordering is required)

All patches should build in isolation.  It looks like you met that goal
(you introduce 'DUMP_COMPLETED' event in 8 without a 'result' member,
then modify it in 10), so that it at least builds.  But it results in
churn, in that you have multiple different definitions of
'DUMP_COMPLETED' over the life of the series.

It's not a requirement to rework things since each step builds, but if I
were writing the series, I do find it conceptually easier to supply
patches in an order that minimizes churn (the first patch that
introduces a type uses its final form, rather than going through several
iterations of that type).  So on that grounds, introducing
DumpQueryResult as a separate patch, before either DUMP_COMPLETED or
query-dump, might be easier to review, if there is a reason for a v6 spin.

-- 
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 0/2] add support for KVM_CAP_SPLIT_IRQCHIP

2015-12-07 Thread Matt Gingell
Will do.

Thanks,
Matt


> On Dec 5, 2015, at 2:00 AM, Jan Kiszka  wrote:
> 
> On 2015-11-14 00:25, Matt Gingell wrote:
>> Hi,
>> 
>> The following patches adds support for the new KVM split irqchip
>> interface discussed on the KVM mailing list.
>> 
>> [kvm] KVM: x86: Split the APIC from the rest of IRQCHIP.
>> http://thread.gmane.org/gmane.comp.emulators.kvm.devel/135918
>> 
>> Our testing found some issues with the implementation of split IRQ
>> chip in the kernel and fixes for those have been submitted to the 
>> KVM mailing list:
>> 
>> [kvm] KVM: x86: bug fixes for split IRQ chip
>> http://thread.gmane.org/gmane.comp.emulators.kvm.devel/143109
>> 
>> With those patches, I’m able to pass KVM unit tests and boot Linux
>> and Windows. 
>> 
>> Any feedback is appreciated. 
> 
> Please choose more telling (and differentiating) subjects for the
> individual patches.
> 
> Thanks,
> Jan




Re: [Qemu-devel] [PATCH v2 2/3] net/vmxnet3: fix debug macro pattern for vmxnet3

2015-12-07 Thread Eric Blake
On 12/06/2015 07:47 PM, Jason Wang wrote:
> 
> 
> On 12/05/2015 04:55 PM, Miao Yan wrote:
>> Vmxnet3 uses the following debug macro style:
>>
>>  #ifdef SOME_DEBUG
>>  #  define debug(...) do{ printf(...); } while (0)
>>  # else
>>  #  define debug(...) do{ } while (0)
>>  #endif
>>
>> If SOME_DEBUG is undefined, then format string inside the
>> debug macro will never be checked by compiler. Code is
>> likely to break in the future when SOME_DEBUG is enabled
>>  because of lack of testing. This patch changes this
>> to the following:
>>
>>  #define debug(...) \
>>   do { if (SOME_DEBUG_ENABLED) printf(...); } while (0)
>>
>> Signed-off-by: Miao Yan 
>> Reviewed-by: Eric Blake 
>> ---
>> Changes in v2:
>>   - Fix grammar error in commit log
> 
> Applied in my -net for 2.5. Thanks

I don't know if Miao saw Peter's reaction to the pull request, but just
as I guessed on v1, exposing more format strings turned up more latent
bugs in the format strings, with failures such as:

> I'm afraid this doesn't build on 32-bit due to format string errors:
> 
> /home/petmay01/qemu/hw/net/vmxnet3.c: In function 'vmxnet3_complete_packet':
> /home/petmay01/qemu/hw/net/vmxnet3.c:500:5: error: format '%lu'
> expects argument of type 'long unsigned int', but argument 7 has type
> 'size_t' [-Werror=format=]
> VMXNET3_RING_DUMP(VMW_RIPRN, "TXC", qidx, &s->txq_descr[qidx].comp_ring);

Looks like it will need a v3; and sorry that I didn't catch the problems
in my review (I was just going off of whether the macro conversion was
correct, and not an actual compile test to see if all the now-live
format strings were always valid).

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



signature.asc
Description: OpenPGP digital signature


[Qemu-devel] [PATCH] qemu-img / curl: When fetching Content-Size use GET instead of HEAD.

2015-12-07 Thread Boris Schrijver
Hi all,

I was testing out the "qemu-img info/convert" options in combination with
"http/https" when I stumbled upon this issue. When "qemu-img info/convert" tries
to collect the file info it will first try to fetch the Content-Size of the
remote file. It does a HEAD request and after a GET request for the correct
range.

The HEAD request is an issue. Because when you've got a pre-signed url, for
example from S3, which INCLUDES the REQUEST METHOD in it's signature, you'll get
a 403 Forbidden.

It's is therefore better to use only the GET request method, and discard the
body at the first call.

Please review! I'll be ready for answers!

[PATCH] qemu-img / curl: When fetching Content-Size use GET instead of HEAD.

A server can respond different to both methods, or can block one of the two.
---
 block/curl.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/block/curl.c b/block/curl.c
index 8994182..2e74c32 100644
--- a/block/curl.c
+++ b/block/curl.c
@@ -594,11 +594,11 @@ static int curl_open(BlockDriverState *bs, QDict *options,
int flags,
 // Get file size
 
 s->accept_range = false;
-curl_easy_setopt(state->curl, CURLOPT_NOBODY, 1);
+curl_easy_setopt(state->curl, CURLOPT_HTTPGET, 1);
 curl_easy_setopt(state->curl, CURLOPT_HEADERFUNCTION,
  curl_header_cb);
 curl_easy_setopt(state->curl, CURLOPT_HEADERDATA, s);
-if (curl_easy_perform(state->curl))
+if (curl_easy_perform(state->curl) != 23)
 goto out;
 curl_easy_getinfo(state->curl, CURLINFO_CONTENT_LENGTH_DOWNLOAD, &d);
 if (d)
-- 
2.1.4

-- 

Met vriendelijke groet / Kind regards,

Boris Schrijver

PCextreme B.V.

http://www.pcextreme.nl/contact
Tel direct: +31 (0) 118 700 215



Re: [Qemu-devel] [PATCH 2/2] lan9118: log and ignore access to invalid registers, rather than aborting

2015-12-07 Thread Andrew Baumann
> From: Paolo Bonzini [mailto:paolo.bonz...@gmail.com] On Behalf Of Paolo
> Bonzini
> Sent: Monday, 7 December 2015 01:53
> On 07/12/2015 06:20, Andrew Baumann wrote:
> > Yeah, I considered doing that, but figured that those cases
> > (incorrectly-sized register writes in 16-bit mode) are indicative of
> > a pretty badly screwed-up guest, and was going for a minimal patch.
> > It probably makes sense to change them for consistency, though.
> 
> I think those should be fixed by modifying lan9118_*_mem_ops and adding
> .valid.{min,max}_access_size.  Not for 2.5, however.  (Probably these
> patches should also be 2.6 + qemu-stable rather than 2.5).

Just to clarify: would you guys like me to prepare such a patch? I'm not 
familiar with the memory op APIs, and don't have a good setup for testing this 
device emulation any more (and certainly not in 16-bit mode!), so would prefer 
to defer to someone else.

BTW, I also see no great urgency for these patches. They're minor fixes, and it 
would be good to have them in, but it's certainly not a regression as the code 
has been that way for ages.

Andrew



Re: [Qemu-devel] [Qemu-block] [PATCH for-2.5?] qcow2: always initialize specific image info

2015-12-07 Thread Max Reitz
On 07.12.2015 19:11, Denis V. Lunev wrote:
> On 12/07/2015 08:54 PM, Eric Blake wrote:
>> On 12/07/2015 10:51 AM, Eric Blake wrote:
>>> [adding qemu-devel - ALL patches should go to qemu-devel, even if they
>>> are also going to a sub-list like qemu-block]
>>>
>>> On 12/07/2015 10:07 AM, Roman Kagan wrote:
 qcow2_get_specific_info() used to have a code path which would leave
 pointer to ImageInfoSpecificQCow2 uninitialized.

 We guess that it caused sporadic crashes on freeing an invalid pointer
 in response to "query-block" QMP command in
 visit_type_ImageInfoSpecificQCow2 with QapiDeallocVisitor.

 Although we have neither a solid proof nor a reproduction scenario,
 making sure the field is initialized appears a reasonable thing to do.

 Signed-off-by: Roman Kagan 
 ---
   block/qcow2.c | 2 +-
   1 file changed, 1 insertion(+), 1 deletion(-)
>> Oops; hit send too soon.  I added for-2.5? to the subject line,
>> because...
>>
 diff --git a/block/qcow2.c b/block/qcow2.c
 index 88f56c8..67c9d3d 100644
 --- a/block/qcow2.c
 +++ b/block/qcow2.c
 @@ -2739,7 +2739,7 @@ static ImageInfoSpecific
 *qcow2_get_specific_info(BlockDriverState *bs)
 *spec_info = (ImageInfoSpecific){
   .type  = IMAGE_INFO_SPECIFIC_KIND_QCOW2,
 -.u.qcow2 = g_new(ImageInfoSpecificQCow2, 1),
 +.u.qcow2 = g_new0(ImageInfoSpecificQCow2, 1),
>>> NACK.  This makes no difference, except when s->qcow_version is out
>>> of spec.
>>>
   };
   if (s->qcow_version == 2) {
   *spec_info->u.qcow2 = (ImageInfoSpecificQCow2){

>>> If s->qcow_version is exactly 2, then we end up initializing all fields
>>> due to the assignment here; same if qcow_version is exactly 3.  The only
>>> time qcow2 remains uninitialized is if qcow_version is 0, 1, or > 3; but
>>> we refuse to handle qcow files with out-of-range versions.  So I don't
>>> see how you are plugging any uninitialized values; and therefore, I
>>> don't see how this is patching any crashes.
>> ...if you can prove that we aren't gracefully handling an out-of-spec
>> qcow_version, such that the uninitialized memory in that scenario is
>> indeed causing a crash, then it is worth respinning a v2 of this patch
>> with that proof, and worth considering it for 2.5 if it really is a
>> crash fixer.

More or less unfortunately, Eric is right. I chose a g_new() over
g_new0() because I was using compound literals anyway (and members not
explicitly initialized in the initializer list given for a compound
literal are initialized implicitly like object with static storage
duration, i.e. 0, generally).

s->qcow_version is always set to 2 or 3. It is only set in:
(1) qcow2_open(): Directly before it is set, we check that the version
is either 2 or 3.
(2) qcow2_downgrade(): We make sure that target_version (the value
s->qcow_version is set to) is equal to 2.
(3) qcow2_downgrade(): On error, s->qcow_version may be reset to
current_version, which is the old value of s->qcow_version which we
can inductively assume to be either 2 or 3.
(4) qcow2_amend_options(): On version upgrade, s->qcow_version is
overwritten by new_version, which is either 2, 3, or the old value
of s->qcow_version (in practice it is always 3 because it needs to
be greater than s->qcow_version in order to get here).
(5) qcow2_amend_options(): On version upgrade error, s->qcow_version is
reset to the old value of s->qcow_version, which we can again assume
to be 2 or 3.

I'd be completely fine with adding an "else { abort(); }" branch to
qcow2_get_specific_info(). But I fear that the issue you encountered is
caused by something different than the ImageInfoSpecificQCow2 object not
being fully initialized, and therefore I'm against this patch even if it
should not change anything (because it might make as feel as if we found
the issue even though there (most probably) is none here).

Also...

> Here is an info about our crash.
> 
> we have this crash under unknown conditions on RHEV version of QEMU.
> 
> Sorry, there is no much additional info. For the 

[...]

> which looks like
> 
> More specifically (expanding inlines along the stack trace):
> 
> (gdb) l *(visit_type_ImageInfoSpecificQCow2+169)
> 0x1a71e9 is in visit_type_ImageInfoSpecificQCow2 (qapi-visit.c:552).
> 548 static void visit_type_ImageInfoSpecificQCow2_fields(Visitor *m,
> ImageInfoSpecificQCow2 **obj, Error **errp)
> 549 {
> 550 Error *err = NULL;
> 551 ==> visit_type_str(m, &(*obj)->compat, "compat", &err);

...the compat field is always set, in either code path (both for version
2 and 3). Therefore, if this pointer is wrong, it definitely is not due
to the field not being initialized.

Without any way of reproducing, it is difficult to find the true cause
of the issue, though. valgrind would probably tell us something, but for
that we'd need something it could find first.

M

Re: [Qemu-devel] [PATCH 00/16] pc: Eliminate struct PcGuestInfo

2015-12-07 Thread Marcel Apfelbaum

On 12/02/2015 03:46 AM, Eduardo Habkost wrote:

This moves all data from PcGuestInfo to either PCMachineState or
PCMachineClass.

This series depends on other two series:
* [PATCH v3 0/6] pc: Initialization and compat function cleanup
* [PATCH V3 0/3]  hw/pcie: Multi-root support for Q35

For reference, there's a git tree containing this series plus all
the dependencies, at:
   git://github.com/ehabkost/qemu-hacks.git work/pcguestinfo-eliminate

Eduardo Habkost (16):
   pc: Move PcGuestInfo declaration to top of file
   pc: Eliminate struct PcGuestInfoState
   pc: Remove guest_info parameter from pc_memory_init()
   acpi: Make acpi_setup() get PCMachineState as argument
   acpi: Remove unused build_facs() PcGuestInfo paramter
   acpi: Save PCMachineState on AcpiBuildState
   acpi: Make acpi_build() get PCMachineState as argument
   acpi: Make build_srat() get PCMachineState as argument
   acpi: Remove ram size fields fron PcGuestInfo
   pc: Move PcGuestInfo.fw_cfg field to PCMachineState
   pc: Simplify signature of xen_load_linux()
   pc: Remove PcGuestInfo.isapc_ram_fw field
   q35: Remove MCHPCIState.guest_info field
   acpi: Use PCMachineClass fields directly
   pc: Move PcGuestInfo.apic_xrupt_override field to PCMachineState
   pc: Move APIC and NUMA data from PcGuestInfo to PCMachineState


Hi,

I mainly agree with the removal of PcGuestInfo , I commented on some patches.

I do have a minor reservation, we kind of loose some information about the 
fields.
Until now it was pretty clear that the fields were related to guest because
they were part of PcGuestInfo. Now this information is lost and the fields
appear as yet other machine attributes.

I suppose this can be addressed by:
- a prefix for guest fields (e.g numa_nodes-> guest_numa_nodes),
- a comment in the class /* guest fields */,
- keeping the fields in PcGuestInfo struct but make the machine field short: guest 
so we can call machine->guest.numa_nodes
- or not be addressed at all :)


Thanks,
Marcel





  hw/i386/acpi-build.c  | 75 ---
  hw/i386/acpi-build.h  |  2 +-
  hw/i386/pc.c  | 71 ++--
  hw/i386/pc_piix.c | 14 ++---
  hw/i386/pc_q35.c  | 15 ++
  include/hw/i386/pc.h  | 30 +++
  include/hw/pci-host/q35.h |  1 -
  7 files changed, 82 insertions(+), 126 deletions(-)






Re: [Qemu-devel] [RFC PATCH V2 0/3] IXGBE/VFIO: Add live migration support for SRIOV NIC

2015-12-07 Thread Alexander Duyck
On Mon, Dec 7, 2015 at 9:39 AM, Michael S. Tsirkin  wrote:
> On Mon, Dec 07, 2015 at 09:12:08AM -0800, Alexander Duyck wrote:
>> On Mon, Dec 7, 2015 at 7:40 AM, Lan, Tianyu  wrote:
>> > On 12/5/2015 1:07 AM, Alexander Duyck wrote:

>> > If can't do that, we have to stop DMA in a short time to mark all dma
>> > pages dirty and then reenable it. I am not sure how much we can get by
>> > this way to track all DMA memory with device running during migration. I
>> > need to do some tests and compare results with stop DMA diretly at last
>> > stage during migration.
>>
>> We have to halt the DMA before we can complete the migration.  So
>> please feel free to test this.
>>
>> In addition I still feel you would be better off taking this in
>> smaller steps.  I still say your first step would be to come up with a
>> generic solution for the dirty page tracking like the dma_mark_clean()
>> approach I had mentioned earlier.  If I get time I might try to take
>> care of it myself later this week since you don't seem to agree with
>> that approach.
>
> Or even try to look at the dirty bit in the VT-D PTEs
> on the host. See the mail I have just sent.
> Might be slower, or might be faster, but is completely
> transparent.

I just saw it and I am looking over the VTd spec now.  It looks like
there might be some performance impacts if software is changing the
PTEs since then the VTd harwdare cannot cache them.  I still have to
do some more reading though so I can fully understand the impacts.

>> >>
>> >> The question is how we would go about triggering it.  I really don't
>> >> think the PCI configuration space approach is the right idea.
>> >>  I wonder
>> >> if we couldn't get away with some sort of ACPI event instead.  We
>> >> already require ACPI support in order to shut down the system
>> >> gracefully, I wonder if we couldn't get away with something similar in
>> >> order to suspend/resume the direct assigned devices gracefully.
>> >>
>> >
>> > I don't think there is such events in the current spec.
>> > Otherwise, There are two kinds of suspend/resume callbacks.
>> > 1) System suspend/resume called during S2RAM and S2DISK.
>> > 2) Runtime suspend/resume called by pm core when device is idle.
>> > If you want to do what you mentioned, you have to change PM core and
>> > ACPI spec.
>>
>> The thought I had was to somehow try to move the direct assigned
>> devices into their own power domain and then simulate a AC power event
>> where that domain is switched off.  However I don't know if there are
>> ACPI events to support that since the power domain code currently only
>> appears to be in use for runtime power management.
>>
>> That had also given me the thought to look at something like runtime
>> power management for the VFs.  We would need to do a runtime
>> suspend/resume.  The only problem is I don't know if there is any way
>> to get the VFs to do a quick wakeup.  It might be worthwhile looking
>> at trying to check with the ACPI experts out there to see if there is
>> anything we can do as bypassing having to use the configuration space
>> mechanism to signal this would definitely be worth it.
>
> I don't much like this idea because it relies on the
> device being exactly the same across source/destination.
> After all, this is always true for suspend/resume.
> Most users do not have control over this, and you would
> often get sightly different versions of firmware,
> etc without noticing.

The original code was operating on that assumption as well.  That is
kind of why I suggested suspend/resume rather than reinventing the
wheel.

> I think we should first see how far along we can get
> by doing a full device reset, and only carrying over
> high level state such as IP, MAC, ARP cache etc.

One advantage of the suspend/resume approach is that it is compatible
with a full reset.  The suspend/resume approach assumes the device
goes through a D0->D3->D0 reset as a part of transitioning between the
system states.

I do admit though that the PCI spec says you aren't supposed to be
hot-swapping devices while the system is in a sleep state so odds are
you would encounter issues if the device changed in any significant
way.

>> >>> The dma page allocated by VF driver also needs to reserve space
>> >>> to do dummy write.
>> >>
>> >>
>> >> No, this will not work.  If for example you have a VF driver allocating
>> >> memory for a 9K receive how will that work?  It isn't as if you can poke
>> >> a hole in the contiguous memory.
>>
>> This is the bit that makes your "poke a hole" solution not portable to
>> other drivers.  I don't know if you overlooked it but for many NICs
>> jumbo frames means using large memory allocations to receive the data.
>> That is the way ixgbevf was up until about a year ago so you cannot
>> expect all the drivers that will want migration support to allow a
>> space for you to write to.  In addition some storage drivers have to
>> map an entire page, that means there is no room for a hole the

Re: [Qemu-devel] [Qemu-block] [PATCH for-2.5?] qcow2: always initialize specific image info

2015-12-07 Thread Denis V. Lunev

On 12/07/2015 08:54 PM, Eric Blake wrote:

On 12/07/2015 10:51 AM, Eric Blake wrote:

[adding qemu-devel - ALL patches should go to qemu-devel, even if they
are also going to a sub-list like qemu-block]

On 12/07/2015 10:07 AM, Roman Kagan wrote:

qcow2_get_specific_info() used to have a code path which would leave
pointer to ImageInfoSpecificQCow2 uninitialized.

We guess that it caused sporadic crashes on freeing an invalid pointer
in response to "query-block" QMP command in
visit_type_ImageInfoSpecificQCow2 with QapiDeallocVisitor.

Although we have neither a solid proof nor a reproduction scenario,
making sure the field is initialized appears a reasonable thing to do.

Signed-off-by: Roman Kagan 
---
  block/qcow2.c | 2 +-
  1 file changed, 1 insertion(+), 1 deletion(-)

Oops; hit send too soon.  I added for-2.5? to the subject line, because...


diff --git a/block/qcow2.c b/block/qcow2.c
index 88f56c8..67c9d3d 100644
--- a/block/qcow2.c
+++ b/block/qcow2.c
@@ -2739,7 +2739,7 @@ static ImageInfoSpecific 
*qcow2_get_specific_info(BlockDriverState *bs)
  
  *spec_info = (ImageInfoSpecific){

  .type  = IMAGE_INFO_SPECIFIC_KIND_QCOW2,
-.u.qcow2 = g_new(ImageInfoSpecificQCow2, 1),
+.u.qcow2 = g_new0(ImageInfoSpecificQCow2, 1),

NACK.  This makes no difference, except when s->qcow_version is out of spec.


  };
  if (s->qcow_version == 2) {
  *spec_info->u.qcow2 = (ImageInfoSpecificQCow2){


If s->qcow_version is exactly 2, then we end up initializing all fields
due to the assignment here; same if qcow_version is exactly 3.  The only
time qcow2 remains uninitialized is if qcow_version is 0, 1, or > 3; but
we refuse to handle qcow files with out-of-range versions.  So I don't
see how you are plugging any uninitialized values; and therefore, I
don't see how this is patching any crashes.

...if you can prove that we aren't gracefully handling an out-of-spec
qcow_version, such that the uninitialized memory in that scenario is
indeed causing a crash, then it is worth respinning a v2 of this patch
with that proof, and worth considering it for 2.5 if it really is a
crash fixer.


Here is an info about our crash.

we have this crash under unknown conditions on RHEV version of QEMU.

Sorry, there is no much additional info. For the time being it
has happen only once.


*** Error in `/usr/libexec/qemu-kvm': free(): invalid pointer: 
0x7f1c453757b8 ***
=== Backtrace: =
/lib64/libc.so.6(+0x7d1fd)[0x7f1c450381fd]
/lib64/libglib-2.0.so.0(g_free+0xf)[0x7f1c49b5236f]
/usr/libexec/qemu-kvm(+0x1a71e9)[0x7f1c4ca0d1e9]
/usr/libexec/qemu-kvm(+0x1a779e)[0x7f1c4ca0d79e]
/usr/libexec/qemu-kvm(+0x1a7bf3)[0x7f1c4ca0dbf3]
/usr/libexec/qemu-kvm(+0x1a8664)[0x7f1c4ca0e664]
/usr/libexec/qemu-kvm(+0x1a92dd)[0x7f1c4ca0f2dd]
/usr/libexec/qemu-kvm(+0x1a9380)[0x7f1c4ca0f380]
/usr/libexec/qemu-kvm(+0x194eb8)[0x7f1c4c9faeb8]
/usr/libexec/qemu-kvm(+0xb35d8)[0x7f1c4c9195d8]
/usr/libexec/qemu-kvm(+0x301f02)[0x7f1c4cb67f02]
/usr/libexec/qemu-kvm(+0x31483f)[0x7f1c4cb7a83f]
/usr/libexec/qemu-kvm(+0x31490e)[0x7f1c4cb7a90e]
/usr/libexec/qemu-kvm(+0xb112f)[0x7f1c4c91712f]
/usr/libexec/qemu-kvm(+0x18a460)[0x7f1c4c9f0460]
/lib64/libglib-2.0.so.0(g_main_context_dispatch+0x15a)[0x7f1c49b4c79a]
/usr/libexec/qemu-kvm(+0x2b96b8)[0x7f1c4cb1f6b8]
/usr/libexec/qemu-kvm(+0x87a4e)[0x7f1c4c8eda4e]
/lib64/libc.so.6(__libc_start_main+0xf5)[0x7f1c44fdcaf5]
/usr/libexec/qemu-kvm(+0x8c2bd)[0x7f1c4c8f22bd]
=== Memory map: 

which we have decoded as

Decoded stacktrace:

g_free+0xf
visit_type_ImageInfoSpecificQCow2+169
visit_type_ImageInfoSpecific+302
visit_type_ImageInfo+867
visit_type_BlockDeviceInfo+820
visit_type_BlockInfo+685
visit_type_BlockInfoList+128
qmp_marshal_input_query_block+232
handle_qmp_command+1992
json_message_process_token+242
json_lexer_feed_char+383
json_lexer_feed+46
monitor_control_read+31
tcp_chr_read+144
g_main_context_dispatch+0x15a
main_loop_wait+440
main+5502
__libc_start_main+0xf5
_start+41

which looks like

More specifically (expanding inlines along the stack trace):

(gdb) l *(visit_type_ImageInfoSpecificQCow2+169)
0x1a71e9 is in visit_type_ImageInfoSpecificQCow2 (qapi-visit.c:552).
548 static void visit_type_ImageInfoSpecificQCow2_fields(Visitor *m, 
ImageInfoSpecificQCow2 **obj, Error **errp)
549 {
550 Error *err = NULL;
551 ==> visit_type_str(m, &(*obj)->compat, "compat", &err);
552 if (err) {
553 goto out;
554 }


(gdb) l visit_type_str
238 void visit_type_str(Visitor *v, char **obj, const char *name, Error 
**errp)
239 {
240 ==> v->type_str(v, obj, name, errp);
241 }


(gdb) l qapi_dealloc_visitor_new
175 QapiDeallocVisitor *qapi_dealloc_visitor_new(void)
176 {
177 QapiDeallocVisitor *v;
178
179 v = g_malloc0(sizeof(*v));
[...]
191 v->visitor.type_str = qapi_dealloc_type_str;
192 v->visitor.type_number = qapi_dealloc_type_number;
193 v->visitor.type_size

Re: [Qemu-devel] [Qemu-block] [PATCH for-2.5?] qcow2: always initialize specific image info

2015-12-07 Thread Eric Blake
On 12/07/2015 10:51 AM, Eric Blake wrote:
> [adding qemu-devel - ALL patches should go to qemu-devel, even if they
> are also going to a sub-list like qemu-block]
> 
> On 12/07/2015 10:07 AM, Roman Kagan wrote:
>> qcow2_get_specific_info() used to have a code path which would leave
>> pointer to ImageInfoSpecificQCow2 uninitialized.
>>
>> We guess that it caused sporadic crashes on freeing an invalid pointer
>> in response to "query-block" QMP command in
>> visit_type_ImageInfoSpecificQCow2 with QapiDeallocVisitor.
>>
>> Although we have neither a solid proof nor a reproduction scenario,
>> making sure the field is initialized appears a reasonable thing to do.
>>
>> Signed-off-by: Roman Kagan 
>> ---
>>  block/qcow2.c | 2 +-
>>  1 file changed, 1 insertion(+), 1 deletion(-)
> 

Oops; hit send too soon.  I added for-2.5? to the subject line, because...

> 
>>
>> diff --git a/block/qcow2.c b/block/qcow2.c
>> index 88f56c8..67c9d3d 100644
>> --- a/block/qcow2.c
>> +++ b/block/qcow2.c
>> @@ -2739,7 +2739,7 @@ static ImageInfoSpecific 
>> *qcow2_get_specific_info(BlockDriverState *bs)
>>  
>>  *spec_info = (ImageInfoSpecific){
>>  .type  = IMAGE_INFO_SPECIFIC_KIND_QCOW2,
>> -.u.qcow2 = g_new(ImageInfoSpecificQCow2, 1),
>> +.u.qcow2 = g_new0(ImageInfoSpecificQCow2, 1),
> 
> NACK.  This makes no difference, except when s->qcow_version is out of spec.
> 
>>  };
>>  if (s->qcow_version == 2) {
>>  *spec_info->u.qcow2 = (ImageInfoSpecificQCow2){
>>
> 
> If s->qcow_version is exactly 2, then we end up initializing all fields
> due to the assignment here; same if qcow_version is exactly 3.  The only
> time qcow2 remains uninitialized is if qcow_version is 0, 1, or > 3; but
> we refuse to handle qcow files with out-of-range versions.  So I don't
> see how you are plugging any uninitialized values; and therefore, I
> don't see how this is patching any crashes.

...if you can prove that we aren't gracefully handling an out-of-spec
qcow_version, such that the uninitialized memory in that scenario is
indeed causing a crash, then it is worth respinning a v2 of this patch
with that proof, and worth considering it for 2.5 if it really is a
crash fixer.

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



signature.asc
Description: OpenPGP digital signature


Re: [Qemu-devel] [Qemu-block] [PATCH for-2.5] qcow2: always initialize specific image info

2015-12-07 Thread Eric Blake
[adding qemu-devel - ALL patches should go to qemu-devel, even if they
are also going to a sub-list like qemu-block]

On 12/07/2015 10:07 AM, Roman Kagan wrote:
> qcow2_get_specific_info() used to have a code path which would leave
> pointer to ImageInfoSpecificQCow2 uninitialized.
> 
> We guess that it caused sporadic crashes on freeing an invalid pointer
> in response to "query-block" QMP command in
> visit_type_ImageInfoSpecificQCow2 with QapiDeallocVisitor.
> 
> Although we have neither a solid proof nor a reproduction scenario,
> making sure the field is initialized appears a reasonable thing to do.
> 
> Signed-off-by: Roman Kagan 
> ---
>  block/qcow2.c | 2 +-
>  1 file changed, 1 insertion(+), 1 deletion(-)


> 
> diff --git a/block/qcow2.c b/block/qcow2.c
> index 88f56c8..67c9d3d 100644
> --- a/block/qcow2.c
> +++ b/block/qcow2.c
> @@ -2739,7 +2739,7 @@ static ImageInfoSpecific 
> *qcow2_get_specific_info(BlockDriverState *bs)
>  
>  *spec_info = (ImageInfoSpecific){
>  .type  = IMAGE_INFO_SPECIFIC_KIND_QCOW2,
> -.u.qcow2 = g_new(ImageInfoSpecificQCow2, 1),
> +.u.qcow2 = g_new0(ImageInfoSpecificQCow2, 1),

NACK.  This makes no difference, except when s->qcow_version is out of spec.

>  };
>  if (s->qcow_version == 2) {
>  *spec_info->u.qcow2 = (ImageInfoSpecificQCow2){
> 

If s->qcow_version is exactly 2, then we end up initializing all fields
due to the assignment here; same if qcow_version is exactly 3.  The only
time qcow2 remains uninitialized is if qcow_version is 0, 1, or > 3; but
we refuse to handle qcow files with out-of-range versions.  So I don't
see how you are plugging any uninitialized values; and therefore, I
don't see how this is patching any crashes.

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



signature.asc
Description: OpenPGP digital signature


Re: [Qemu-devel] [RFC PATCH V2 0/3] IXGBE/VFIO: Add live migration support for SRIOV NIC

2015-12-07 Thread Michael S. Tsirkin
On Mon, Dec 07, 2015 at 09:12:08AM -0800, Alexander Duyck wrote:
> On Mon, Dec 7, 2015 at 7:40 AM, Lan, Tianyu  wrote:
> > On 12/5/2015 1:07 AM, Alexander Duyck wrote:
> >>>
> >>>
> >>> We still need to support Windows guest for migration and this is why our
> >>> patches keep all changes in the driver since it's impossible to change
> >>> Windows kernel.
> >>
> >>
> >> That is a poor argument.  I highly doubt Microsoft is interested in
> >> having to modify all of the drivers that will support direct assignment
> >> in order to support migration.  They would likely request something
> >> similar to what I have in that they will want a way to do DMA tracking
> >> with minimal modification required to the drivers.
> >
> >
> > This totally depends on the NIC or other devices' vendors and they
> > should make decision to support migration or not. If yes, they would
> > modify driver.
> 
> Having to modify every driver that wants to support live migration is
> a bit much.  In addition I don't see this being limited only to NIC
> devices.  You can direct assign a number of different devices, your
> solution cannot be specific to NICs.
> 
> > If just target to call suspend/resume during migration, the feature will
> > be meaningless. Most cases don't want to affect user during migration
> > a lot and so the service down time is vital. Our target is to apply
> > SRIOV NIC passthough to cloud service and NFV(network functions
> > virtualization) projects which are sensitive to network performance
> > and stability. From my opinion, We should give a change for device
> > driver to implement itself migration job. Call suspend and resume
> > callback in the driver if it doesn't care the performance during migration.
> 
> The suspend/resume callback should be efficient in terms of time.
> After all we don't want the system to stall for a long period of time
> when it should be either running or asleep.  Having it burn cycles in
> a power state limbo doesn't do anyone any good.  If nothing else maybe
> it will help to push the vendors to speed up those functions which
> then benefit migration and the system sleep states.
> 
> Also you keep assuming you can keep the device running while you do
> the migration and you can't.  You are going to corrupt the memory if
> you do, and you have yet to provide any means to explain how you are
> going to solve that.
> 
> 
> >
> >>
> >>> Following is my idea to do DMA tracking.
> >>>
> >>> Inject event to VF driver after memory iterate stage
> >>> and before stop VCPU and then VF driver marks dirty all
> >>> using DMA memory. The new allocated pages also need to
> >>> be marked dirty before stopping VCPU. All dirty memory
> >>> in this time slot will be migrated until stop-and-copy
> >>> stage. We also need to make sure to disable VF via clearing the
> >>> bus master enable bit for VF before migrating these memory.
> >>
> >>
> >> The ordering of your explanation here doesn't quite work.  What needs to
> >> happen is that you have to disable DMA and then mark the pages as dirty.
> >>   What the disabling of the BME does is signal to the hypervisor that
> >> the device is now stopped.  The ixgbevf_suspend call already supported
> >> by the driver is almost exactly what is needed to take care of something
> >> like this.
> >
> >
> > This is why I hope to reserve a piece of space in the dma page to do dummy
> > write. This can help to mark page dirty while not require to stop DMA and
> > not race with DMA data.
> 
> You can't and it will still race.  What concerns me is that your
> patches and the document you referenced earlier show a considerable
> lack of understanding about how DMA and device drivers work.  There is
> a reason why device drivers have so many memory barriers and the like
> in them.  The fact is when you have CPU and a device both accessing
> memory things have to be done in a very specific order and you cannot
> violate that.
> 
> If you have a contiguous block of memory you expect the device to
> write into you cannot just poke a hole in it.  Such a situation is not
> supported by any hardware that I am aware of.
> 
> As far as writing to dirty the pages it only works so long as you halt
> the DMA and then mark the pages dirty.  It has to be in that order.
> Any other order will result in data corruption and I am sure the NFV
> customers definitely don't want that.
> 
> > If can't do that, we have to stop DMA in a short time to mark all dma
> > pages dirty and then reenable it. I am not sure how much we can get by
> > this way to track all DMA memory with device running during migration. I
> > need to do some tests and compare results with stop DMA diretly at last
> > stage during migration.
> 
> We have to halt the DMA before we can complete the migration.  So
> please feel free to test this.
> 
> In addition I still feel you would be better off taking this in
> smaller steps.  I still say your first step would be to come up with a
> generic solution for the dirty

Re: [Qemu-devel] [PATCH 1/8] bcm2835_sbm: add BCM2835 mailboxes

2015-12-07 Thread Andrew Baumann
> From: Peter Crosthwaite [mailto:crosthwaitepe...@gmail.com]
> Sent: Sunday, 6 December 2015 22:37
> On Thu, Dec 3, 2015 at 10:01 PM, Andrew Baumann
>  wrote:
> > This adds the system mailboxes which are used to communicate with a
> > number of GPU peripherals on Pi/Pi2.
> >
> 
> Are there any publically available specs for this? I found the
> peripheral manual which documents the interrupts controller but I
> couldnt easily find a doc to cover this. I can review without docs,
> but it is a little harder. A few top level sentances about how it
> works and what it does would help in commit message if we can't get a
> doc.

The only docs I could find are:
https://github.com/raspberrypi/firmware/wiki/Mailboxes
https://github.com/raspberrypi/firmware/wiki/Accessing-mailboxes

It probably doesn't hurt to add these links to either a header comment or 
commit message. I'll do that in v2.

Andrew


Re: [Qemu-devel] [RFC PATCH V2 0/3] IXGBE/VFIO: Add live migration support for SRIOV NIC

2015-12-07 Thread Alexander Duyck
On Mon, Dec 7, 2015 at 7:40 AM, Lan, Tianyu  wrote:
> On 12/5/2015 1:07 AM, Alexander Duyck wrote:
>>>
>>>
>>> We still need to support Windows guest for migration and this is why our
>>> patches keep all changes in the driver since it's impossible to change
>>> Windows kernel.
>>
>>
>> That is a poor argument.  I highly doubt Microsoft is interested in
>> having to modify all of the drivers that will support direct assignment
>> in order to support migration.  They would likely request something
>> similar to what I have in that they will want a way to do DMA tracking
>> with minimal modification required to the drivers.
>
>
> This totally depends on the NIC or other devices' vendors and they
> should make decision to support migration or not. If yes, they would
> modify driver.

Having to modify every driver that wants to support live migration is
a bit much.  In addition I don't see this being limited only to NIC
devices.  You can direct assign a number of different devices, your
solution cannot be specific to NICs.

> If just target to call suspend/resume during migration, the feature will
> be meaningless. Most cases don't want to affect user during migration
> a lot and so the service down time is vital. Our target is to apply
> SRIOV NIC passthough to cloud service and NFV(network functions
> virtualization) projects which are sensitive to network performance
> and stability. From my opinion, We should give a change for device
> driver to implement itself migration job. Call suspend and resume
> callback in the driver if it doesn't care the performance during migration.

The suspend/resume callback should be efficient in terms of time.
After all we don't want the system to stall for a long period of time
when it should be either running or asleep.  Having it burn cycles in
a power state limbo doesn't do anyone any good.  If nothing else maybe
it will help to push the vendors to speed up those functions which
then benefit migration and the system sleep states.

Also you keep assuming you can keep the device running while you do
the migration and you can't.  You are going to corrupt the memory if
you do, and you have yet to provide any means to explain how you are
going to solve that.


>
>>
>>> Following is my idea to do DMA tracking.
>>>
>>> Inject event to VF driver after memory iterate stage
>>> and before stop VCPU and then VF driver marks dirty all
>>> using DMA memory. The new allocated pages also need to
>>> be marked dirty before stopping VCPU. All dirty memory
>>> in this time slot will be migrated until stop-and-copy
>>> stage. We also need to make sure to disable VF via clearing the
>>> bus master enable bit for VF before migrating these memory.
>>
>>
>> The ordering of your explanation here doesn't quite work.  What needs to
>> happen is that you have to disable DMA and then mark the pages as dirty.
>>   What the disabling of the BME does is signal to the hypervisor that
>> the device is now stopped.  The ixgbevf_suspend call already supported
>> by the driver is almost exactly what is needed to take care of something
>> like this.
>
>
> This is why I hope to reserve a piece of space in the dma page to do dummy
> write. This can help to mark page dirty while not require to stop DMA and
> not race with DMA data.

You can't and it will still race.  What concerns me is that your
patches and the document you referenced earlier show a considerable
lack of understanding about how DMA and device drivers work.  There is
a reason why device drivers have so many memory barriers and the like
in them.  The fact is when you have CPU and a device both accessing
memory things have to be done in a very specific order and you cannot
violate that.

If you have a contiguous block of memory you expect the device to
write into you cannot just poke a hole in it.  Such a situation is not
supported by any hardware that I am aware of.

As far as writing to dirty the pages it only works so long as you halt
the DMA and then mark the pages dirty.  It has to be in that order.
Any other order will result in data corruption and I am sure the NFV
customers definitely don't want that.

> If can't do that, we have to stop DMA in a short time to mark all dma
> pages dirty and then reenable it. I am not sure how much we can get by
> this way to track all DMA memory with device running during migration. I
> need to do some tests and compare results with stop DMA diretly at last
> stage during migration.

We have to halt the DMA before we can complete the migration.  So
please feel free to test this.

In addition I still feel you would be better off taking this in
smaller steps.  I still say your first step would be to come up with a
generic solution for the dirty page tracking like the dma_mark_clean()
approach I had mentioned earlier.  If I get time I might try to take
care of it myself later this week since you don't seem to agree with
that approach.

>>
>> The question is how we would go about triggering it.  I really don

Re: [Qemu-devel] [PATCH] virtio-blk: Drop x-data-plane option

2015-12-07 Thread Peter Maydell
On 7 December 2015 at 15:19, Paolo Bonzini  wrote:
>
>
> On 07/12/2015 14:02, Fam Zheng wrote:
>> On Mon, 12/07 12:29, Cornelia Huck wrote:
>>> On Mon,  7 Dec 2015 18:59:27 +0800
>>> Fam Zheng  wrote:
>>>
 The official way of enabling dataplane is through the "iothread"
 property that references an iothread object created by "-object
 iothread".  Since the old "x-data-plane=on" way now even crashes, it's
 probably easier to just drop it:

 $ qemu-system-x86_64 -drive file=null-co://,id=d0,if=none \
 -device virtio-blk-pci,drive=d0,x-data-plane=on

 ERROR:/home/fam/work/qemu/qom/object.c:1515:
 object_get_canonical_path_component: assertion failed: (obj->parent != 
 NULL)
 Aborted
>>>
>>> Do we understand yet why this crashes, btw?
>>
>> I think it's because with x-data-plane=on, virtio-blk initialize an object 
>> that
>> doesn't have a parent, therefore it doesn't have a valid "canonical path
>> component" thing, which is different from objects created with "-object" CLI.
>> I'm not very familiar with the QOM semantics here.
>>
>>>

 Signed-off-by: Fam Zheng 
 ---
  hw/block/dataplane/virtio-blk.c | 15 ++-
  hw/block/virtio-blk.c   |  1 -
  include/hw/virtio/virtio-blk.h  |  1 -
  3 files changed, 2 insertions(+), 15 deletions(-)

>>>
>>> No general objection to removing x-data-plane; but this probably wants
>>> a mention on the changelog as x-data-plane has been described in
>>> various howtos etc. over the years.
>>
>> Yes, that is a good point.  I don't know if it's too rushing in removing it 
>> for
>> 2.5 (this is just posted as one option) and we'll have to count on QOM 
>> experts
>> for the fix, if it is.
>
> The solution would be to add object_property_add_child to
> virtio_blk_data_plane_create, between object_initialize and
> user_creatable_complete.  But I think this patch is ok for 2.5.

Paolo asked me to apply this to master, so I have done so.

thanks
-- PMM



[Qemu-devel] live migration vs device assignment (was Re: [RFC PATCH V2 00/10] Qemu: Add live migration support for SRIOV NIC)

2015-12-07 Thread Michael S. Tsirkin
On Tue, Nov 24, 2015 at 09:35:17PM +0800, Lan Tianyu wrote:
> This patchset is to propose a solution of adding live migration
> support for SRIOV NIC.

I thought about what this is doing at the high level, and I do have some
value in what you are trying to do, but I also think we need to clarify
the motivation a bit more.  What you are saying is not really what the
patches are doing.

And with that clearer understanding of the motivation in mind (assuming
it actually captures a real need), I would also like to suggest some
changes.

TLDR:
- split this into 3 unrelated efforts/patchsets
- try implementing this host-side only using VT-d dirty tracking
- if making guest changes, make them in a way that makes many devices benefit
- measure speed before trying to improve it

---

First, this does not help to actually do migration with an
active assigned device. Guest needs to deactivate the device
before VM is moved around.

What they are actually able to do, instead, is three things.
My suggestion is to split them up, and work on them
separately.  There's really no need to have them all.

I discuss all 3 things below, but if we do need to have some discussion,
please snip and  let's have separate threads for each item please.


1. Starting live migration with device running.
This might help speed up networking during pre-copy where there is a
long warm-up phase.

Note: To complete migration, one also has to do something to stop
the device, but that's a separate item, since existing hot-unplug
request will do that just as well.


Proposed changes of approach:
One option is to write into the dma memory to make it dirty.  Your
patches do this within the driver, but doing this in the generic dma
unmap code seems more elegant as it will help all devices.  An
interesting note: on unplug, driver unmaps all memory for DMA, so this
works out fine.


Some benchmarking will be needed to show the performance overhead.
It is likely non zero, so an interface would be needed
to enable this tracking before starting migration.


According to the VT-d spec, I note that bit 6 in the PTE is the dirty
bit.  Why don't we use this to detect memory changes by the device?
Specifically, periodically scan pages that we have already
sent, test and clear atomically the dirty bit in the PTE of
the IOMMU, and if set, resend the page.
The interface could be simply an ioctl for VFIO giving
it a range of memory, and have VFIO do the scan and set
bits for userspace.

This might be slower than writing into DMA page,
since e.g. PML does not work here.

We could go for a mixed approach, where we negotiate with the
guest: if guest can write into memory on unmap, then
skip the scanning, otherwise do scanning of IOMMU PTEs
as described above.

I would suggest starting with clean IOMMU PTE polling
on host. If you see that there is a performance problem,
optimize later by enabling the updates within guest
if required.

2.  (Presumably) faster device stop.
After the warmup phase, we need to enter the stop and
copy phase. At that point, device needs to be stopped.
One way to do this is to send request to guest while
we continue to track and send memory changes.
I am not sure whether this is what you are doing,
but I'm assuming it is.

I don't know what do you do on the host,
I guesss you could send removal request to guest, and
keep sending page updates meanwhile.
After guest eject/stop acknowledge is received on the host,
you can enter stop and copy.

Your patches seem to stop device with a custom device specific
register, but using more generic interfaces, such as
e.g. device removal, could also work, even if
it's less optimal.

The way you defined the interfaces, they don't
seem device specific at all.
A new PCI capability ID reserved by the PCI SIG
could be one way to add the new interface
if it's needed.


We also need a way to know what does guest support.
With hotplug we know all modern guests support
it, but with any custom code we need negotiation,
and then fall back on either hot unplug
or blocking migration.

Additionally, hot-unplug will unmap all dma
memory so if all dma unmap callbacks do
a write, you get that memory dirtied for free.

At the moment, device removal destroys state such as IP address and arp
cache, but we could have guest move these around
if necessary. Possibly this can be done in userspace with
the guest agent. We could discuss guest kernel or firmware solutions
if we need to address corner cases such as network boot.

You might run into hotplug behaviour such as
a 5 second timeout until device is actually
detected. It always seemed silly to me.
A simple if (!kvm) in that code might be justified.

The fact that guest cooperation is needed
to complete migration is a big problem IMHO.
This practically means you need to give a lot of
CPU to a guest on an overcommitted host
in order to be able to move it out to another host.
Meanwhile, guest can abuse the extra CPU it got.

Can not surprise removal be emulated instead?
Remo

Re: [Qemu-devel] [PATCH for-2.5] virtio-blk/dataplane: parentize compat iothread

2015-12-07 Thread Cornelia Huck
On Mon, 7 Dec 2015 16:33:11 +
Peter Maydell  wrote:

> On 7 December 2015 at 16:27, Cornelia Huck  wrote:
> > On Mon,  7 Dec 2015 16:50:01 +0100
> > Cornelia Huck  wrote:
> >
> >> For x-data-plane=true, we create an iothread automatically for
> >> compatibility. Commit d21e877 ("iothread: include id in thread name")
> >> exposed that this iothread missed correct parenthood: fix this.
> >>
> >> Signed-off-by: Cornelia Huck 
> >> ---
> >>  hw/block/dataplane/virtio-blk.c | 3 +++
> >>  1 file changed, 3 insertions(+)
> >>
> >> diff --git a/hw/block/dataplane/virtio-blk.c 
> >> b/hw/block/dataplane/virtio-blk.c
> >> index c42ddeb..c7e5668 100644
> >> --- a/hw/block/dataplane/virtio-blk.c
> >> +++ b/hw/block/dataplane/virtio-blk.c
> >> @@ -187,6 +187,9 @@ void virtio_blk_data_plane_create(VirtIODevice *vdev, 
> >> VirtIOBlkConf *conf,
> >>  object_initialize(&s->internal_iothread_obj,
> >>sizeof(s->internal_iothread_obj),
> >>TYPE_IOTHREAD);
> >> +object_property_add_child(OBJECT(conf), TYPE_IOTHREAD,
> >> +  OBJECT(&s->internal_iothread_obj),
> >> +  &error_abort);
> >>  user_creatable_complete(OBJECT(&s->internal_iothread_obj), 
> >> &error_abort);
> >>  s->iothread = &s->internal_iothread_obj;
> >>  }
> >
> > Scratch that, does not work... (I thought I was hitting the other
> > segfault in the block backend processing...)
> 
> Should I go ahead and apply Fam's "remove x-data-plane" patch then?

That's probably the quickest solution, as the iothread name patch is
useful and I haven't been able to come up with a correct patch.




Re: [Qemu-devel] [PATCH v2 1/4] xen/MSI-X: latch MSI-X table writes

2015-12-07 Thread Jan Beulich
>>> On 07.12.15 at 13:41,  wrote:
> I know that in your opinion is superfluous, nonetheless could you please
> add 2-3 lines of in-code comment right here, to explain what you are
> doing with the check?  Something like:
> 
> /*
>  * Update the entry addr and data to the latest values only when the
>  * entry is masked or they are all masked, as required by the spec.
>  * Addr and data changes while the MSI-X entry is unmasked will be
>  * delayed until the next masking->unmasking.
>  */

Btw, will it be okay to just resend this one patch as v3, or do I need
to resend the whole series (the rest of which didn't change)?

Jan




Re: [Qemu-devel] [PULL for-2.5 2/4] block: Don't wait serialising for non-COR read requests

2015-12-07 Thread Cornelia Huck
On Mon, 7 Dec 2015 11:02:51 +0100
Cornelia Huck  wrote:

> On Thu,  3 Dec 2015 13:00:00 +0800
> Stefan Hajnoczi  wrote:
> 
> > From: Fam Zheng 
> > 
> > The assertion problem was noticed in 06c3916b35a, but it wasn't
> > completely fixed, because even though the req is not marked as
> > serialising, it still gets serialised by wait_serialising_requests
> > against other serialising requests, which could lead to the same
> > assertion failure.
> > 
> > Fix it by even more explicitly skipping the serialising for this
> > specific case.
> > 
> > Signed-off-by: Fam Zheng 
> > Message-id: 1448962590-2842-2-git-send-email-f...@redhat.com
> > Signed-off-by: Stefan Hajnoczi 
> > ---
> >  block/backup.c|  2 +-
> >  block/io.c| 12 +++-
> >  include/block/block.h |  4 ++--
> >  trace-events  |  2 +-
> >  4 files changed, 11 insertions(+), 9 deletions(-)
> 
> This one causes segfaults for me:
> 
> Program received signal SIGSEGV, Segmentation fault.
> bdrv_is_inserted (bs=0x8000) at /data/git/yyy/qemu/block.c:3071
> 3071  if (!drv) {
> 
> (gdb) bt
> #0  bdrv_is_inserted (bs=0x8000) at /data/git/yyy/qemu/block.c:3071
> #1  0x80216974 in blk_is_inserted (blk=)
> at /data/git/yyy/qemu/block/block-backend.c:986
> #2  0x802169c6 in blk_is_available (blk=blk@entry=0x3ffb17e7960)
> at /data/git/yyy/qemu/block/block-backend.c:991
> #3  0x80216d12 in blk_check_byte_request 
> (blk=blk@entry=0x3ffb17e7960, 
> offset=offset@entry=4928966656, size=16384)
> at /data/git/yyy/qemu/block/block-backend.c:558
> #4  0x80216df2 in blk_check_request (blk=blk@entry=0x3ffb17e7960, 
> sector_num=sector_num@entry=9626888, nb_sectors=nb_sectors@entry=32)
> at /data/git/yyy/qemu/block/block-backend.c:589
> #5  0x80217ee8 in blk_aio_readv (blk=0x3ffb17e7960, sector_num=
> 9626888, iov=0x8098c658, nb_sectors=, cb=
> 0x80081150 , opaque=0x80980620)
> at /data/git/yyy/qemu/block/block-backend.c:727
> #6  0x8008186e in submit_requests (niov=, 
> num_reqs=, start=, mrb=, 
> blk=) at /data/git/yyy/qemu/hw/block/virtio-blk.c:366
> #7  virtio_blk_submit_multireq (mrb=, blk=)
> at /data/git/yyy/qemu/hw/block/virtio-blk.c:444
> #8  virtio_blk_submit_multireq (blk=0x3ffb17e7960, mrb=0x3ffeb58)
> at /data/git/yyy/qemu/hw/block/virtio-blk.c:389
> #9  0x800823ee in virtio_blk_handle_output (vdev=, 
> vq=) at /data/git/yyy/qemu/hw/block/virtio-blk.c:615
> #10 0x801e367e in aio_dispatch (ctx=0x80918520)
> at /data/git/yyy/qemu/aio-posix.c:326
> #11 0x801d28b0 in aio_ctx_dispatch (source=, 
> callback=, user_data=)
> at /data/git/yyy/qemu/async.c:231
> #12 0x03fffd36a05a in g_main_context_dispatch ()
>from /lib64/libglib-2.0.so.0
> #13 0x801e0ffa in glib_pollfds_poll ()
> at /data/git/yyy/qemu/main-loop.c:211
> #14 os_host_main_loop_wait (timeout=)
> at /data/git/yyy/qemu/main-loop.c:256
> #15 main_loop_wait (nonblocking=)
> at /data/git/yyy/qemu/main-loop.c:504
> #16 0x800148a6 in main_loop () at /data/git/yyy/qemu/vl.c:1923
> #17 main (argc=, argv=, envp=)
> at /data/git/yyy/qemu/vl.c:4684
> 
> Relevant part of command line:
> 
> -drive 
> file=/dev/sda,if=none,id=drive-virtio-disk0,format=raw,serial=ccwzfcp1,cache=none
>  -device 
> virtio-blk-ccw,devno=fe.0.0001,drive=drive-virtio-disk0,id=virtio-disk0,bootindex=1,scsi=off

I played around a bit. The main part of this change seems to be calling
wait_serialising_requests() conditionally; reverting this makes the
guest boot again.

I then tried to find out when wait_serialising_requests() was NOT
called and added fprintfs: well, it was _always_ called. I then added a
fprintf for flags at the beginning of the function: this produced a
segfault no matter whether wait_serialising_requests() was called
conditionally or unconditionally. Weird race?

Anything further I can do? I guess this patch fixes a bug for someone,
but it means insta-death for my setup...




Re: [Qemu-devel] [PATCH for-2.5] virtio-blk/dataplane: parentize compat iothread

2015-12-07 Thread Peter Maydell
On 7 December 2015 at 16:27, Cornelia Huck  wrote:
> On Mon,  7 Dec 2015 16:50:01 +0100
> Cornelia Huck  wrote:
>
>> For x-data-plane=true, we create an iothread automatically for
>> compatibility. Commit d21e877 ("iothread: include id in thread name")
>> exposed that this iothread missed correct parenthood: fix this.
>>
>> Signed-off-by: Cornelia Huck 
>> ---
>>  hw/block/dataplane/virtio-blk.c | 3 +++
>>  1 file changed, 3 insertions(+)
>>
>> diff --git a/hw/block/dataplane/virtio-blk.c 
>> b/hw/block/dataplane/virtio-blk.c
>> index c42ddeb..c7e5668 100644
>> --- a/hw/block/dataplane/virtio-blk.c
>> +++ b/hw/block/dataplane/virtio-blk.c
>> @@ -187,6 +187,9 @@ void virtio_blk_data_plane_create(VirtIODevice *vdev, 
>> VirtIOBlkConf *conf,
>>  object_initialize(&s->internal_iothread_obj,
>>sizeof(s->internal_iothread_obj),
>>TYPE_IOTHREAD);
>> +object_property_add_child(OBJECT(conf), TYPE_IOTHREAD,
>> +  OBJECT(&s->internal_iothread_obj),
>> +  &error_abort);
>>  user_creatable_complete(OBJECT(&s->internal_iothread_obj), 
>> &error_abort);
>>  s->iothread = &s->internal_iothread_obj;
>>  }
>
> Scratch that, does not work... (I thought I was hitting the other
> segfault in the block backend processing...)

Should I go ahead and apply Fam's "remove x-data-plane" patch then?

thanks
-- PMM



Re: [Qemu-devel] [PATCH for-2.5 0/2] sd: Avoid ABI mistake, add a FIXME

2015-12-07 Thread Peter Maydell
On 7 December 2015 at 15:55, Markus Armbruster  wrote:
> Markus Armbruster (2):
>   sdhci: Sanitize "sdhci-pci" properties for future qomification
>   sd: Mark brittle abuse of blk_attach_dev() FIXME
>
>  hw/sd/sd.c| 1 +
>  hw/sd/sdhci.c | 9 +++--
>  include/hw/sd/sdhci.h | 2 +-
>  3 files changed, 9 insertions(+), 3 deletions(-)

Reviewed-by: Peter Maydell 

These patches look good to me and like the best compromise we
have for 2.5.

thanks
-- PMM



Re: [Qemu-devel] [PATCH for-2.5] virtio-blk/dataplane: parentize compat iothread

2015-12-07 Thread Cornelia Huck
On Mon,  7 Dec 2015 16:50:01 +0100
Cornelia Huck  wrote:

> For x-data-plane=true, we create an iothread automatically for
> compatibility. Commit d21e877 ("iothread: include id in thread name")
> exposed that this iothread missed correct parenthood: fix this.
> 
> Signed-off-by: Cornelia Huck 
> ---
>  hw/block/dataplane/virtio-blk.c | 3 +++
>  1 file changed, 3 insertions(+)
> 
> diff --git a/hw/block/dataplane/virtio-blk.c b/hw/block/dataplane/virtio-blk.c
> index c42ddeb..c7e5668 100644
> --- a/hw/block/dataplane/virtio-blk.c
> +++ b/hw/block/dataplane/virtio-blk.c
> @@ -187,6 +187,9 @@ void virtio_blk_data_plane_create(VirtIODevice *vdev, 
> VirtIOBlkConf *conf,
>  object_initialize(&s->internal_iothread_obj,
>sizeof(s->internal_iothread_obj),
>TYPE_IOTHREAD);
> +object_property_add_child(OBJECT(conf), TYPE_IOTHREAD,
> +  OBJECT(&s->internal_iothread_obj),
> +  &error_abort);
>  user_creatable_complete(OBJECT(&s->internal_iothread_obj), 
> &error_abort);
>  s->iothread = &s->internal_iothread_obj;
>  }

Scratch that, does not work... (I thought I was hitting the other
segfault in the block backend processing...)




[Qemu-devel] [PATCH 1/3] scripts: Add new clean-includes script to fix C include directives

2015-12-07 Thread Peter Maydell
Add a new scripts/clean-includes, which can be used to automatically
ensure that a C source file includes qemu/osdep.h first and doesn't
then include any headers which osdep.h provides already.

Signed-off-by: Peter Maydell 
---
 scripts/clean-includes | 109 +
 1 file changed, 109 insertions(+)
 create mode 100755 scripts/clean-includes

diff --git a/scripts/clean-includes b/scripts/clean-includes
new file mode 100755
index 000..1af1f82
--- /dev/null
+++ b/scripts/clean-includes
@@ -0,0 +1,109 @@
+#!/bin/sh -e
+#
+# Clean up QEMU #include lines by ensuring that qemu/osdep.h
+# is the first include listed.
+#
+# Copyright (c) 2015 Linaro Limited
+#
+# Authors:
+#  Peter Maydell 
+#
+# This work is licensed under the terms of the GNU GPL, version 2
+# or (at your option) any later version. See the COPYING file in
+# the top-level directory.
+
+# Usage:
+#   clean-includes [--git subjectprefix] file ...
+#
+# If the --git subjectprefix option is given, then after making
+# the changes to the files this script will create a git commit
+# with the subject line "subjectprefix: Clean up includes"
+# and a boilerplate commit message.
+
+# This script requires Coccinelle to be installed.
+
+
+# The following one-liner may be handy for finding files to run this on.
+# However some caution is required regarding files that might be part
+# of the guest agent or standalone tests.
+
+# for i in `git ls-tree --name-only HEAD`  ; do test -f $i && \
+#   grep -E '^# *include' $i | head -1 | grep 'osdep.h' ; test $? != 0 && \
+#   echo $i ; done
+
+
+GIT=no
+
+if [ $# -ne 0 ] && [ "$1" = "--git" ]; then
+if [ $# -eq 1 ]; then
+echo "--git option requires an argument"
+exit 1
+fi
+GITSUBJ="$2"
+GIT=yes
+shift
+shift
+fi
+
+if [ $# -eq 0 ]; then
+echo "Usage: clean-includes [--git subjectprefix] foo.c ..."
+echo "(modifies the files in place)"
+exit 1
+fi
+
+# Annoyingly coccinelle won't read a scriptfile unless its
+# name ends '.cocci', so write it out to a tempfile with the
+# right kind of name.
+COCCIFILE="$(mktemp --suffix=.cocci)"
+
+trap 'rm -f -- "$COCCIFILE"' INT TERM HUP EXIT
+
+cat >"$COCCIFILE" <
+)
+EOT
+
+
+for f in "$@"; do
+  # First, use coccinelle to add qemu/osdep.h before the first existing include
+  # (this will add two lines if the file uses both "..." and <...> #includes,
+  # but we will remove the extras in the next step)
+  spatch  --in-place --no-show-diff --cocci-file "$COCCIFILE" "$f"
+
+  # Now remove any duplicate osdep.h includes
+  perl -n -i  -e 'print if !/#include "qemu\/osdep.h"/ || !$n++;' "$f"
+
+  # Remove includes that osdep.h already provides
+  perl -n -i -e 'print if !/\s*#\s*include\s*(["<][^>"]*[">])/ ||
+  ! (grep { $_ eq $1 } qw (
+   "config-host.h" "qemu/compiler.h" "config.h"
+   
+   
+
+  
+   "glib-compat.h" "qapi/error.h"
+))' "$f"
+
+done
+
+if [ "$GIT" = "yes" ]; then
+git add -- "$@"
+git commit --signoff -F - <

[Qemu-devel] [PATCH 3/3] hw/arm: Clean up includes

2015-12-07 Thread Peter Maydell
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 
---
 hw/arm/allwinner-a10.c   | 1 +
 hw/arm/armv7m.c  | 1 +
 hw/arm/boot.c| 2 +-
 hw/arm/collie.c  | 1 +
 hw/arm/cubieboard.c  | 1 +
 hw/arm/digic.c   | 1 +
 hw/arm/digic_boards.c| 1 +
 hw/arm/exynos4210.c  | 1 +
 hw/arm/exynos4_boards.c  | 1 +
 hw/arm/fsl-imx25.c   | 1 +
 hw/arm/fsl-imx31.c   | 1 +
 hw/arm/gumstix.c | 1 +
 hw/arm/highbank.c| 1 +
 hw/arm/imx25_pdk.c   | 1 +
 hw/arm/integratorcp.c| 1 +
 hw/arm/kzm.c | 1 +
 hw/arm/mainstone.c   | 1 +
 hw/arm/musicpal.c| 1 +
 hw/arm/netduino2.c   | 1 +
 hw/arm/nseries.c | 1 +
 hw/arm/omap1.c   | 1 +
 hw/arm/omap2.c   | 1 +
 hw/arm/omap_sx1.c| 1 +
 hw/arm/palm.c| 1 +
 hw/arm/pxa2xx.c  | 1 +
 hw/arm/pxa2xx_gpio.c | 1 +
 hw/arm/pxa2xx_pic.c  | 1 +
 hw/arm/realview.c| 1 +
 hw/arm/spitz.c   | 1 +
 hw/arm/stellaris.c   | 1 +
 hw/arm/stm32f205_soc.c   | 1 +
 hw/arm/strongarm.c   | 1 +
 hw/arm/sysbus-fdt.c  | 1 +
 hw/arm/tosa.c| 1 +
 hw/arm/versatilepb.c | 1 +
 hw/arm/vexpress.c| 1 +
 hw/arm/virt-acpi-build.c | 1 +
 hw/arm/virt.c| 1 +
 hw/arm/xilinx_zynq.c | 1 +
 hw/arm/xlnx-ep108.c  | 1 +
 hw/arm/xlnx-zynqmp.c | 1 +
 hw/arm/z2.c  | 1 +
 42 files changed, 42 insertions(+), 1 deletion(-)

diff --git a/hw/arm/allwinner-a10.c b/hw/arm/allwinner-a10.c
index b0ca81c..02c8caa 100644
--- a/hw/arm/allwinner-a10.c
+++ b/hw/arm/allwinner-a10.c
@@ -15,6 +15,7 @@
  * for more details.
  */
 
+#include "qemu/osdep.h"
 #include "hw/sysbus.h"
 #include "hw/devices.h"
 #include "hw/arm/allwinner-a10.h"
diff --git a/hw/arm/armv7m.c b/hw/arm/armv7m.c
index a80d2ad..f3973f7 100644
--- a/hw/arm/armv7m.c
+++ b/hw/arm/armv7m.c
@@ -7,6 +7,7 @@
  * This code is licensed under the GPL.
  */
 
+#include "qemu/osdep.h"
 #include "hw/sysbus.h"
 #include "hw/arm/arm.h"
 #include "hw/loader.h"
diff --git a/hw/arm/boot.c b/hw/arm/boot.c
index 75f69bf..7742dd3 100644
--- a/hw/arm/boot.c
+++ b/hw/arm/boot.c
@@ -7,7 +7,7 @@
  * This code is licensed under the GPL.
  */
 
-#include "config.h"
+#include "qemu/osdep.h"
 #include "hw/hw.h"
 #include "hw/arm/arm.h"
 #include "hw/arm/linux-boot-if.h"
diff --git a/hw/arm/collie.c b/hw/arm/collie.c
index 9991c0c..8bb308a 100644
--- a/hw/arm/collie.c
+++ b/hw/arm/collie.c
@@ -8,6 +8,7 @@
  * Contributions after 2012-01-13 are licensed under the terms of the
  * GNU GPL, version 2 or (at your option) any later version.
  */
+#include "qemu/osdep.h"
 #include "hw/hw.h"
 #include "hw/sysbus.h"
 #include "hw/boards.h"
diff --git a/hw/arm/cubieboard.c b/hw/arm/cubieboard.c
index bf068cd..9fcbaf4 100644
--- a/hw/arm/cubieboard.c
+++ b/hw/arm/cubieboard.c
@@ -15,6 +15,7 @@
  * for more details.
  */
 
+#include "qemu/osdep.h"
 #include "hw/sysbus.h"
 #include "hw/devices.h"
 #include "hw/boards.h"
diff --git a/hw/arm/digic.c b/hw/arm/digic.c
index 90f8190..82087ba 100644
--- a/hw/arm/digic.c
+++ b/hw/arm/digic.c
@@ -20,6 +20,7 @@
  *
  */
 
+#include "qemu/osdep.h"
 #include "hw/arm/digic.h"
 
 #define DIGIC4_TIMER_BASE(n)(0xc021 + (n) * 0x100)
diff --git a/hw/arm/digic_boards.c b/hw/arm/digic_boards.c
index 710045a..ef52fafb 100644
--- a/hw/arm/digic_boards.c
+++ b/hw/arm/digic_boards.c
@@ -23,6 +23,7 @@
  *
  */
 
+#include "qemu/osdep.h"
 #include "hw/boards.h"
 #include "exec/address-spaces.h"
 #include "qemu/error-report.h"
diff --git a/hw/arm/exynos4210.c b/hw/arm/exynos4210.c
index d934980..0d5a22f 100644
--- a/hw/arm/exynos4210.c
+++ b/hw/arm/exynos4210.c
@@ -21,6 +21,7 @@
  *
  */
 
+#include "qemu/osdep.h"
 #include "hw/boards.h"
 #include "sysemu/sysemu.h"
 #include "hw/sysbus.h"
diff --git a/hw/arm/exynos4_boards.c b/hw/arm/exynos4_boards.c
index da82b27..42faa8c 100644
--- a/hw/arm/exynos4_boards.c
+++ b/hw/arm/exynos4_boards.c
@@ -21,6 +21,7 @@
  *
  */
 
+#include "qemu/osdep.h"
 #include "sysemu/sysemu.h"
 #include "sysemu/qtest.h"
 #include "hw/sysbus.h"
diff --git a/hw/arm/fsl-imx25.c b/hw/arm/fsl-imx25.c
index e1cadac..8507cf0 100644
--- a/hw/arm/fsl-imx25.c
+++ b/hw/arm/fsl-imx25.c
@@ -22,6 +22,7 @@
  *  with this program; if not, see .
  */
 
+#include "qemu/osdep.h"
 #include "hw/arm/fsl-imx25.h"
 #include "sysemu/sysemu.h"
 #include "exec/address-spaces.h"
diff --git a/hw/arm/fsl-imx31.c b/hw/arm/fsl-imx31.c
index 53d4473..331a5b1 100644
--- a/hw/arm/fsl-imx31.c
+++ b/hw/arm/fsl-imx31.c
@@ -19,6 +19,7 @@
  *  with this program; if not, see .
  */
 
+#include "qemu/osdep.h"
 #include "hw/arm/fsl-imx31.h"
 #include "sysemu/sysemu.h"
 #include "exec/address-spaces.h"
diff --git a/hw/arm/gumstix.c b/hw/arm/gumstix.c
index 32ad041..626d338 1

[Qemu-devel] [PATCH 0/3] clean-includes script to add osdep.h to everything

2015-12-07 Thread Peter Maydell
We've had some discussion previously (on list and IRC) about adding an
include of "qemu/osdep.h" to everything. The basic idea is that every
.c file should include "qemu/osdep.h" as its first include; then every
other header (and the .c file itself) can rely on the facilities that
osdep.h provides.

This patchset is mostly here to get comment and review on the script
I've written to do the job of automatically updating the source files.

To quote the usage comment from the script:

# Usage:
#   clean-includes [--git subjectprefix] file ...
#
# If the --git subjectprefix option is given, then after making
# the changes to the files this script will create a git commit
# with the subject line "subjectprefix: Clean up includes"
# and a boilerplate commit message.

The script requires Perl and Coccinelle.

Patches 2 and 3 are examples of its output, produced via
 scripts/clean-includes --git target-arm target-arm/*.c
 scripts/clean-includes --git hw/arm hw/arm/*.c

NB: the script assumes my patch to make osdep.h include
glib-compat.h has already been applied:
  http://patchwork.ozlabs.org/patch/552828/

Once we're happy with the set of transformations it produces the
next question is how we want to apply it to the tree. The good
news is that the changes to the .c files are idempotent and don't
depend on each other, so we could send things via different
submaintainer trees. Or we could have a single patchseries which we
apply all at once on the theory that this minimises the pain overall.

(The part that will depend on these having gone in is where we
update .h files to not include headers that osdep.h gives us.)


A question I had about including osdep.h everywhere:
are there any files in the tree where we *can't* include it?
(Obvious possible candidates would be standalone test programs
and the guest-agent code.)


Peter Maydell (3):
  scripts: Add new clean-includes script to fix C include directives
  target-arm: Clean up includes
  hw/arm: Clean up includes

 hw/arm/allwinner-a10.c |   1 +
 hw/arm/armv7m.c|   1 +
 hw/arm/boot.c  |   2 +-
 hw/arm/collie.c|   1 +
 hw/arm/cubieboard.c|   1 +
 hw/arm/digic.c |   1 +
 hw/arm/digic_boards.c  |   1 +
 hw/arm/exynos4210.c|   1 +
 hw/arm/exynos4_boards.c|   1 +
 hw/arm/fsl-imx25.c |   1 +
 hw/arm/fsl-imx31.c |   1 +
 hw/arm/gumstix.c   |   1 +
 hw/arm/highbank.c  |   1 +
 hw/arm/imx25_pdk.c |   1 +
 hw/arm/integratorcp.c  |   1 +
 hw/arm/kzm.c   |   1 +
 hw/arm/mainstone.c |   1 +
 hw/arm/musicpal.c  |   1 +
 hw/arm/netduino2.c |   1 +
 hw/arm/nseries.c   |   1 +
 hw/arm/omap1.c |   1 +
 hw/arm/omap2.c |   1 +
 hw/arm/omap_sx1.c  |   1 +
 hw/arm/palm.c  |   1 +
 hw/arm/pxa2xx.c|   1 +
 hw/arm/pxa2xx_gpio.c   |   1 +
 hw/arm/pxa2xx_pic.c|   1 +
 hw/arm/realview.c  |   1 +
 hw/arm/spitz.c |   1 +
 hw/arm/stellaris.c |   1 +
 hw/arm/stm32f205_soc.c |   1 +
 hw/arm/strongarm.c |   1 +
 hw/arm/sysbus-fdt.c|   1 +
 hw/arm/tosa.c  |   1 +
 hw/arm/versatilepb.c   |   1 +
 hw/arm/vexpress.c  |   1 +
 hw/arm/virt-acpi-build.c   |   1 +
 hw/arm/virt.c  |   1 +
 hw/arm/xilinx_zynq.c   |   1 +
 hw/arm/xlnx-ep108.c|   1 +
 hw/arm/xlnx-zynqmp.c   |   1 +
 hw/arm/z2.c|   1 +
 scripts/clean-includes | 109 +
 target-arm/arm-semi.c  |   8 +---
 target-arm/cpu.c   |   1 +
 target-arm/cpu64.c |   1 +
 target-arm/crypto_helper.c |   2 +-
 target-arm/gdbstub.c   |   2 +-
 target-arm/gdbstub64.c |   2 +-
 target-arm/helper-a64.c|   1 +
 target-arm/helper.c|   1 +
 target-arm/iwmmxt_helper.c |   3 +-
 target-arm/kvm-stub.c  |   1 +
 target-arm/kvm.c   |   3 +-
 target-arm/kvm32.c |   3 +-
 target-arm/kvm64.c |   4 +-
 target-arm/machine.c   |   1 +
 target-arm/neon_helper.c   |   3 +-
 target-arm/op_helper.c |   1 +
 target-arm/psci.c  |   1 +
 target-arm/translate-a64.c |   6 +--
 target-arm/translate.c |   6 +--
 62 files changed, 170 insertions(+), 32 deletions(-)
 create mode 100755 scripts/clean-includes

-- 
1.9.1




[Qemu-devel] [PATCH 2/3] target-arm: Clean up includes

2015-12-07 Thread Peter Maydell
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 
---
 target-arm/arm-semi.c  | 8 +---
 target-arm/cpu.c   | 1 +
 target-arm/cpu64.c | 1 +
 target-arm/crypto_helper.c | 2 +-
 target-arm/gdbstub.c   | 2 +-
 target-arm/gdbstub64.c | 2 +-
 target-arm/helper-a64.c| 1 +
 target-arm/helper.c| 1 +
 target-arm/iwmmxt_helper.c | 3 +--
 target-arm/kvm-stub.c  | 1 +
 target-arm/kvm.c   | 3 +--
 target-arm/kvm32.c | 3 +--
 target-arm/kvm64.c | 4 +---
 target-arm/machine.c   | 1 +
 target-arm/neon_helper.c   | 3 +--
 target-arm/op_helper.c | 1 +
 target-arm/psci.c  | 1 +
 target-arm/translate-a64.c | 6 +-
 target-arm/translate.c | 6 +-
 19 files changed, 19 insertions(+), 31 deletions(-)

diff --git a/target-arm/arm-semi.c b/target-arm/arm-semi.c
index d7cff3d..76c33b9 100644
--- a/target-arm/arm-semi.c
+++ b/target-arm/arm-semi.c
@@ -18,13 +18,7 @@
  *  along with this program; if not, see .
  */
 
-#include 
-#include 
-#include 
-#include 
-#include 
-#include 
-#include 
+#include "qemu/osdep.h"
 
 #include "cpu.h"
 #include "exec/semihost.h"
diff --git a/target-arm/cpu.c b/target-arm/cpu.c
index 30739fc..72cb65f 100644
--- a/target-arm/cpu.c
+++ b/target-arm/cpu.c
@@ -18,6 +18,7 @@
  * 
  */
 
+#include "qemu/osdep.h"
 #include "cpu.h"
 #include "internals.h"
 #include "qemu-common.h"
diff --git a/target-arm/cpu64.c b/target-arm/cpu64.c
index 63c8b1c..5f8a177 100644
--- a/target-arm/cpu64.c
+++ b/target-arm/cpu64.c
@@ -18,6 +18,7 @@
  * 
  */
 
+#include "qemu/osdep.h"
 #include "cpu.h"
 #include "qemu-common.h"
 #if !defined(CONFIG_USER_ONLY)
diff --git a/target-arm/crypto_helper.c b/target-arm/crypto_helper.c
index 5d22838..3b6df3f 100644
--- a/target-arm/crypto_helper.c
+++ b/target-arm/crypto_helper.c
@@ -9,7 +9,7 @@
  * version 2 of the License, or (at your option) any later version.
  */
 
-#include 
+#include "qemu/osdep.h"
 
 #include "cpu.h"
 #include "exec/exec-all.h"
diff --git a/target-arm/gdbstub.c b/target-arm/gdbstub.c
index 1c34396..08b91a4 100644
--- a/target-arm/gdbstub.c
+++ b/target-arm/gdbstub.c
@@ -17,7 +17,7 @@
  * You should have received a copy of the GNU Lesser General Public
  * License along with this library; if not, see .
  */
-#include "config.h"
+#include "qemu/osdep.h"
 #include "qemu-common.h"
 #include "exec/gdbstub.h"
 
diff --git a/target-arm/gdbstub64.c b/target-arm/gdbstub64.c
index 8f3b8d1..634c6bc 100644
--- a/target-arm/gdbstub64.c
+++ b/target-arm/gdbstub64.c
@@ -16,7 +16,7 @@
  * You should have received a copy of the GNU Lesser General Public
  * License along with this library; if not, see .
  */
-#include "config.h"
+#include "qemu/osdep.h"
 #include "qemu-common.h"
 #include "exec/gdbstub.h"
 
diff --git a/target-arm/helper-a64.c b/target-arm/helper-a64.c
index deb8dbe..c46af93 100644
--- a/target-arm/helper-a64.c
+++ b/target-arm/helper-a64.c
@@ -17,6 +17,7 @@
  * License along with this library; if not, see .
  */
 
+#include "qemu/osdep.h"
 #include "cpu.h"
 #include "exec/gdbstub.h"
 #include "exec/helper-proto.h"
diff --git a/target-arm/helper.c b/target-arm/helper.c
index afc4163..18d60ff 100644
--- a/target-arm/helper.c
+++ b/target-arm/helper.c
@@ -1,3 +1,4 @@
+#include "qemu/osdep.h"
 #include "cpu.h"
 #include "internals.h"
 #include "exec/gdbstub.h"
diff --git a/target-arm/iwmmxt_helper.c b/target-arm/iwmmxt_helper.c
index a506914..7d87e1a 100644
--- a/target-arm/iwmmxt_helper.c
+++ b/target-arm/iwmmxt_helper.c
@@ -19,8 +19,7 @@
  * License along with this library; if not, see .
  */
 
-#include 
-#include 
+#include "qemu/osdep.h"
 
 #include "cpu.h"
 #include "exec/exec-all.h"
diff --git a/target-arm/kvm-stub.c b/target-arm/kvm-stub.c
index db2edc2..38bf433 100644
--- a/target-arm/kvm-stub.c
+++ b/target-arm/kvm-stub.c
@@ -9,6 +9,7 @@
  * See the COPYING file in the top-level directory.
  *
  */
+#include "qemu/osdep.h"
 #include "qemu-common.h"
 #include "kvm_arm.h"
 
diff --git a/target-arm/kvm.c b/target-arm/kvm.c
index 79ef4c6..c1c5584 100644
--- a/target-arm/kvm.c
+++ b/target-arm/kvm.c
@@ -8,8 +8,7 @@
  *
  */
 
-#include 
-#include 
+#include "qemu/osdep.h"
 #include 
 #include 
 
diff --git a/target-arm/kvm32.c b/target-arm/kvm32.c
index df1e2b0..646ba41 100644
--- a/target-arm/kvm32.c
+++ b/target-arm/kvm32.c
@@ -8,8 +8,7 @@
  *
  */
 
-#include 
-#include 
+#include "qemu/osdep.h"
 #include 
 #include 
 
diff --git a/target-arm/kvm64.c b/target-arm/kvm64.c
index ceebfeb..d409259 100644
--- a/target-arm/kvm64.c
+++ b/target-arm/kvm64.c
@@ -8,14 +8,12 @@
  *
  */
 
-#include 
-#

  1   2   >