Re: [Qemu-devel] [PATCH v5 00/10] trace-state: make the behaviour of disable consistent across all backends
On Tue, Jun 28, 2011 at 5:52 PM, Lluís xscr...@gmx.net wrote: This patch defines the disable trace event state to always use the nop backend. Apologies for not reviewing sooner. I have begun and will send feedback tomorrow. Stefan
Re: [Qemu-devel] Loading ELF binaries with very high base addresses
On 07/12/2011 09:43 AM, Alexander Graf wrote: For now, just force the mapping to somewhere mappable :) Unfortunately, I can tell you that there is no such place. The text segment is mapped by default at 0x4000 and the data segment is by default mapped at 0x6000. If you set guest_base = 0xc000, which remaps the text segment to 0, then the data segment will still be at 0x2000, which x86_64 still cannot represent. If you hack the address mapping routines to simply drop the high bits, then the text and data segments will map on top of one another. You can well imagine how well that will work. The *only* way to solve this is with softmmu. r~
Re: [Qemu-devel] [PATCH v5] Add support for Zipit Z2 machine
On 6 July 2011 14:52, Vasily Khoruzhick anars...@gmail.com wrote: Zipit Z2 is small PXA270 based handheld. Signed-off-by: Vasily Khoruzhick anars...@gmail.com --- v2: codestyle fixes, added VMStateDescription for LCD device and AER915, traces clean up. v3: no changes v4: no changes v5: use DPRINTF for debug-related traces, add missing fields to VMStateDescription for LCD device and AER915 Reviewed-by: Peter Maydell peter.mayd...@linaro.org (Tested with master + cherry-pick of http://patchwork.ozlabs.org/patch/103356/ since we're still waiting for the xen pullreq to be merged.) -- PMM
[Qemu-devel] [PATCH 1/2] Introduce compiler.h header file
From: Luiz Capitulino lcapitul...@gmail.com This moves compiler related macros from qemu-common.h to compiler.h. The reason for this change is that there are simple header files that depend only on the compiler macros, so including qemu-common.h is overkill. Besides, qemu-common.h is bloated and will benefit from some splitting. Signed-off-by: Luiz Capitulino lcapitul...@gmail.com --- compiler.h| 38 ++ qemu-common.h | 25 + 2 files changed, 39 insertions(+), 24 deletions(-) create mode 100644 compiler.h diff --git a/compiler.h b/compiler.h new file mode 100644 index 000..864f8ff --- /dev/null +++ b/compiler.h @@ -0,0 +1,38 @@ +/* + * Compiler related definition + * + * This work is licensed under the terms of the GNU GPL, version 2. See + * the COPYING file in the top-level directory. + * + */ +#ifndef COMPILER_H +#define COMPILER_H + +#include config-host.h + +#define QEMU_NORETURN __attribute__ ((__noreturn__)) +#ifdef CONFIG_GCC_ATTRIBUTE_WARN_UNUSED_RESULT +#define QEMU_WARN_UNUSED_RESULT __attribute__((warn_unused_result)) +#else +#define QEMU_WARN_UNUSED_RESULT +#endif + +#define QEMU_BUILD_BUG_ON(x) typedef char __build_bug_on__##__LINE__[(x)?-1:1]; + +#if defined __GNUC__ +# if (__GNUC__ 4) || \ + defined(__GNUC_MINOR__) (__GNUC__ == 4) (__GNUC_MINOR__ 4) + /* gcc versions before 4.4.x don't support gnu_printf, so use printf. */ +# define GCC_ATTR __attribute__((__unused__, format(printf, 1, 2))) +# define GCC_FMT_ATTR(n, m) __attribute__((format(printf, n, m))) +# else + /* Use gnu_printf when supported (qemu uses standard format strings). */ +# define GCC_ATTR __attribute__((__unused__, format(gnu_printf, 1, 2))) +# define GCC_FMT_ATTR(n, m) __attribute__((format(gnu_printf, n, m))) +# endif +#else +#define GCC_ATTR /**/ +#define GCC_FMT_ATTR(n, m) +#endif + +#endif /* COMPILER_H */ diff --git a/qemu-common.h b/qemu-common.h index abd7a75..1e72931 100644 --- a/qemu-common.h +++ b/qemu-common.h @@ -2,16 +2,9 @@ #ifndef QEMU_COMMON_H #define QEMU_COMMON_H +#include compiler.h #include config-host.h -#define QEMU_NORETURN __attribute__ ((__noreturn__)) -#ifdef CONFIG_GCC_ATTRIBUTE_WARN_UNUSED_RESULT -#define QEMU_WARN_UNUSED_RESULT __attribute__((warn_unused_result)) -#else -#define QEMU_WARN_UNUSED_RESULT -#endif - -#define QEMU_BUILD_BUG_ON(x) typedef char __build_bug_on__##__LINE__[(x)?-1:1]; #define TFR(expr) do { if ((expr) != -1) break; } while (errno == EINTR) typedef struct QEMUTimer QEMUTimer; @@ -82,22 +75,6 @@ struct iovec { #include sys/uio.h #endif -#if defined __GNUC__ -# if (__GNUC__ 4) || \ - defined(__GNUC_MINOR__) (__GNUC__ == 4) (__GNUC_MINOR__ 4) - /* gcc versions before 4.4.x don't support gnu_printf, so use printf. */ -# define GCC_ATTR __attribute__((__unused__, format(printf, 1, 2))) -# define GCC_FMT_ATTR(n, m) __attribute__((format(printf, n, m))) -# else - /* Use gnu_printf when supported (qemu uses standard format strings). */ -# define GCC_ATTR __attribute__((__unused__, format(gnu_printf, 1, 2))) -# define GCC_FMT_ATTR(n, m) __attribute__((format(gnu_printf, n, m))) -# endif -#else -#define GCC_ATTR /**/ -#define GCC_FMT_ATTR(n, m) -#endif - typedef int (*fprintf_function)(FILE *f, const char *fmt, ...) GCC_FMT_ATTR(2, 3); -- 1.7.6.134.gcf13f
[Qemu-devel] [PATCH v2 0/2]: Fix build issue with error.h
A .c file including error.h and not including qemu-common.h will break the build, because error.h uses a macro defined in qemu-common.h. The simple and obvious fix would be to change error.h to include qemu-common.h. But this is overkill, so this series does some splitting in qemu-common.h and changes error.h to include only what it really needs. Please, refer to the patches for more details. v2 o move compiler related macros from qemu-common.h to compiler.h compiler.h| 38 ++ error.h |1 + qemu-common.h | 25 + 3 files changed, 40 insertions(+), 24 deletions(-)
Re: [Qemu-devel] Loading ELF binaries with very high base addresses
On 12 July 2011 17:43, Alexander Graf ag...@suse.de wrote: I guess the long-term solution here really is to use the softmmu for linux-user as well - unless we're running 32-on-64. Even for 32-on-64 we need to control the guest's address space properly (so we don't do things like gratuitously failing mmap); in theory you could do that if you could guarantee to mmap 4GB contiguous at startup to parcel out to the guest, but it would be simpler and more consistent to just use softmmu in all cases. -- PMM
Re: [Qemu-devel] [PATCH] os-posix: set groups properly for -runas
* Chris Wright (chr...@sous-sol.org) wrote: * Stefan Hajnoczi (stefa...@linux.vnet.ibm.com) wrote: @@ -199,6 +200,11 @@ static void change_process_uid(void) fprintf(stderr, Failed to setgid(%d)\n, user_pwd-pw_gid); exit(1); } +if (initgroups(user_pwd-pw_name, user_pwd-pw_gid) 0) { +fprintf(stderr, Failed to initgroups(\%s\, %d)\n, +user_pwd-pw_name, user_pwd-pw_gid); +exit(1); +} Does initgroups need access to /etc/group? How does this combine w/ -chroot? Tested this on Linux, and w/out /etc/group it simply fails to add any supplementary groups (doesn't fail completely, just fails safely). Appears similar from solaris manpages. Given that... Acked-by: Chris Wright chr...@sous-sol.org
[Qemu-devel] [PATCH 2/2] Error: Fix build when qemu-common.h is not included
From: Luiz Capitulino lcapitul...@gmail.com Commit e4ea5e2d0e0e4c5188ab45b66f3195062ae059dc added the use of the macro GCC_FMT_ATTR to error.h, however compiler.h is not included by error.h This will cause a build error when files including error.h don't include qemu-common.h (or compiler.h). Not an issue today because the only file including it is json-parser.h and it does include qemu-common.h, but let's get it fixed. Signed-off-by: Luiz Capitulino lcapitul...@gmail.com --- error.h |1 + 1 files changed, 1 insertions(+), 0 deletions(-) diff --git a/error.h b/error.h index 0f92a6f..6361f40 100644 --- a/error.h +++ b/error.h @@ -12,6 +12,7 @@ #ifndef ERROR_H #define ERROR_H +#include compiler.h #include stdbool.h /** -- 1.7.6.134.gcf13f
Re: [Qemu-devel] [PATCH v2 1/9] exec: add endian specific phys ld/st functions
Thanks, applied all. On Tue, Jul 12, 2011 at 10:52 AM, Alexander Graf ag...@suse.de wrote: Am 06.07.2011 um 09:09 schrieb Alexander Graf ag...@suse.de: Device code some times needs to access physical memory and does that through the ld./st._phys functions. However, these are the exact same functions that the CPU uses to access memory, which means they will be endianness swapped depending on the target CPU. However, devices don't know about the CPU's endianness, but instead access memory directly using their own interface to the memory bus, so they need some way to read data with their native endianness. This patch adds _le and _be functions to ld./st._phys. Blue, mind to apply at least this one if there are no concerns? The API it adds makes sense IMHO and I don't want to hold up the megasas patch due to it ;). Alex
[Qemu-devel] [PATCH] linux-user/signal.c: Rename s390 target_ucontext fields to fix ia64
The ia64 sys/ucontext.h defines macros 'uc_link', 'uc_sigmask' and 'uc_stack'. Rename the s390 target_ucontext struct members to tuc_*, bringing them into line with the other targets and fixing a compile failure on ia64 hosts caused by this clash. Signed-off-by: Peter Maydell peter.mayd...@linaro.org --- linux-user/signal.c | 30 +++--- 1 files changed, 15 insertions(+), 15 deletions(-) diff --git a/linux-user/signal.c b/linux-user/signal.c index 7d168e1..07ad07a 100644 --- a/linux-user/signal.c +++ b/linux-user/signal.c @@ -3662,11 +3662,11 @@ typedef struct { } sigframe; struct target_ucontext { -target_ulong uc_flags; -struct target_ucontext *uc_link; -target_stack_t uc_stack; -target_sigregs uc_mcontext; -target_sigset_t uc_sigmask; /* mask last for extensibility */ +target_ulong tuc_flags; +struct target_ucontext *tuc_link; +target_stack_t tuc_stack; +target_sigregs tuc_mcontext; +target_sigset_t tuc_sigmask; /* mask last for extensibility */ }; typedef struct { @@ -3814,16 +3814,16 @@ static void setup_rt_frame(int sig, struct target_sigaction *ka, } /* Create the ucontext. */ -__put_user(0, frame-uc.uc_flags); -__put_user((abi_ulong)0, (abi_ulong *)frame-uc.uc_link); -__put_user(target_sigaltstack_used.ss_sp, frame-uc.uc_stack.ss_sp); +__put_user(0, frame-uc.tuc_flags); +__put_user((abi_ulong)0, (abi_ulong *)frame-uc.tuc_link); +__put_user(target_sigaltstack_used.ss_sp, frame-uc.tuc_stack.ss_sp); __put_user(sas_ss_flags(get_sp_from_cpustate(env)), - frame-uc.uc_stack.ss_flags); -__put_user(target_sigaltstack_used.ss_size, frame-uc.uc_stack.ss_size); -save_sigregs(env, frame-uc.uc_mcontext); + frame-uc.tuc_stack.ss_flags); +__put_user(target_sigaltstack_used.ss_size, frame-uc.tuc_stack.ss_size); +save_sigregs(env, frame-uc.tuc_mcontext); for (i = 0; i TARGET_NSIG_WORDS; i++) { __put_user((abi_ulong)set-sig[i], -(abi_ulong *)frame-uc.uc_sigmask.sig[i]); +(abi_ulong *)frame-uc.tuc_sigmask.sig[i]); } /* Set up to return from userspace. If provided, use a stub @@ -3928,15 +3928,15 @@ long do_rt_sigreturn(CPUState *env) if (!lock_user_struct(VERIFY_READ, frame, frame_addr, 1)) { goto badframe; } -target_to_host_sigset(set, frame-uc.uc_sigmask); +target_to_host_sigset(set, frame-uc.tuc_sigmask); sigprocmask(SIG_SETMASK, set, NULL); /* ~_BLOCKABLE? */ -if (restore_sigregs(env, frame-uc.uc_mcontext)) { +if (restore_sigregs(env, frame-uc.tuc_mcontext)) { goto badframe; } -if (do_sigaltstack(frame_addr + offsetof(rt_sigframe, uc.uc_stack), 0, +if (do_sigaltstack(frame_addr + offsetof(rt_sigframe, uc.tuc_stack), 0, get_sp_from_cpustate(env)) == -EFAULT) { goto badframe; } -- 1.7.4.1
[Qemu-devel] [PATCH 1/2] qemu-options.hx: Document missing -drive options
They are 'werror', 'rerror' and 'readonly'. Signed-off-by: Luiz Capitulino lcapitul...@redhat.com --- qemu-options.hx |8 1 files changed, 8 insertions(+), 0 deletions(-) diff --git a/qemu-options.hx b/qemu-options.hx index e6d7adc..64114dd 100644 --- a/qemu-options.hx +++ b/qemu-options.hx @@ -160,6 +160,14 @@ an untrusted format header. This option specifies the serial number to assign to the device. @item addr=@var{addr} Specify the controller's PCI address (if=virtio only). +@item werror=@var{action},rerror=@var{action} +Specify which @var{action} to take on write and read errors. Valid actions are: +ignore (ignore the error and try to continue), stop (pause QEMU), +report (report the error to the guest), enospc (pause QEMU only if the +host disk is full; report the error to the guest otherwise). +The default setting is @option{werror=enospc} and @option{rerror=report}. +@item readonly +Open drive @option{file} as read-only. Guest write attempts will fail. @end table By default, writethrough caching is used for all block device. This means that -- 1.7.6.134.gcf13f
[Qemu-devel] [PATCH v2 0/2]: block: Document -drive options
Please, see individual patches for details. v2 o Correct man-page text o Document -drive options in qemu-config.c qemu-config.c |6 ++ qemu-options.hx |8 2 files changed, 14 insertions(+), 0 deletions(-)
Re: [Qemu-devel] [PATCH 1/2] Introduce compiler.h header file
On Tue, 12 Jul 2011, Luiz Capitulino wrote: From: Luiz Capitulino lcapitul...@gmail.com This moves compiler related macros from qemu-common.h to compiler.h. The reason for this change is that there are simple header files that depend only on the compiler macros, so including qemu-common.h is overkill. Besides, qemu-common.h is bloated and will benefit from some splitting. Signed-off-by: Luiz Capitulino lcapitul...@gmail.com --- compiler.h| 38 ++ qemu-common.h | 25 + 2 files changed, 39 insertions(+), 24 deletions(-) create mode 100644 compiler.h diff --git a/compiler.h b/compiler.h new file mode 100644 index 000..864f8ff --- /dev/null +++ b/compiler.h @@ -0,0 +1,38 @@ +/* + * Compiler related definition + * + * This work is licensed under the terms of the GNU GPL, version 2. See + * the COPYING file in the top-level directory. + * + */ +#ifndef COMPILER_H +#define COMPILER_H + +#include config-host.h + +#define QEMU_NORETURN __attribute__ ((__noreturn__)) +#ifdef CONFIG_GCC_ATTRIBUTE_WARN_UNUSED_RESULT +#define QEMU_WARN_UNUSED_RESULT __attribute__((warn_unused_result)) +#else +#define QEMU_WARN_UNUSED_RESULT +#endif + +#define QEMU_BUILD_BUG_ON(x) typedef char __build_bug_on__##__LINE__[(x)?-1:1]; + +#if defined __GNUC__ +# if (__GNUC__ 4) || \ + defined(__GNUC_MINOR__) (__GNUC__ == 4) (__GNUC_MINOR__ 4) + /* gcc versions before 4.4.x don't support gnu_printf, so use printf. */ +# define GCC_ATTR __attribute__((__unused__, format(printf, 1, 2))) +# define GCC_FMT_ATTR(n, m) __attribute__((format(printf, n, m))) I wrote the above and certainly didn't license it under GPL, please drop the bogus copyright notice at the top. +# else + /* Use gnu_printf when supported (qemu uses standard format strings). */ +# define GCC_ATTR __attribute__((__unused__, format(gnu_printf, 1, 2))) +# define GCC_FMT_ATTR(n, m) __attribute__((format(gnu_printf, n, m))) +# endif +#else +#define GCC_ATTR /**/ +#define GCC_FMT_ATTR(n, m) +#endif + +#endif /* COMPILER_H */ diff --git a/qemu-common.h b/qemu-common.h index abd7a75..1e72931 100644 --- a/qemu-common.h +++ b/qemu-common.h @@ -2,16 +2,9 @@ #ifndef QEMU_COMMON_H #define QEMU_COMMON_H +#include compiler.h #include config-host.h -#define QEMU_NORETURN __attribute__ ((__noreturn__)) -#ifdef CONFIG_GCC_ATTRIBUTE_WARN_UNUSED_RESULT -#define QEMU_WARN_UNUSED_RESULT __attribute__((warn_unused_result)) -#else -#define QEMU_WARN_UNUSED_RESULT -#endif - -#define QEMU_BUILD_BUG_ON(x) typedef char __build_bug_on__##__LINE__[(x)?-1:1]; #define TFR(expr) do { if ((expr) != -1) break; } while (errno == EINTR) typedef struct QEMUTimer QEMUTimer; @@ -82,22 +75,6 @@ struct iovec { #include sys/uio.h #endif -#if defined __GNUC__ -# if (__GNUC__ 4) || \ - defined(__GNUC_MINOR__) (__GNUC__ == 4) (__GNUC_MINOR__ 4) - /* gcc versions before 4.4.x don't support gnu_printf, so use printf. */ -# define GCC_ATTR __attribute__((__unused__, format(printf, 1, 2))) -# define GCC_FMT_ATTR(n, m) __attribute__((format(printf, n, m))) -# else - /* Use gnu_printf when supported (qemu uses standard format strings). */ -# define GCC_ATTR __attribute__((__unused__, format(gnu_printf, 1, 2))) -# define GCC_FMT_ATTR(n, m) __attribute__((format(gnu_printf, n, m))) -# endif -#else -#define GCC_ATTR /**/ -#define GCC_FMT_ATTR(n, m) -#endif - typedef int (*fprintf_function)(FILE *f, const char *fmt, ...) GCC_FMT_ATTR(2, 3); -- mailto:av1...@comtv.ru
Re: [Qemu-devel] [PATCH 1/2] Introduce compiler.h header file
On Wed, 13 Jul 2011 00:31:56 +0400 (MSD) malc av1...@comtv.ru wrote: On Tue, 12 Jul 2011, Luiz Capitulino wrote: From: Luiz Capitulino lcapitul...@gmail.com This moves compiler related macros from qemu-common.h to compiler.h. The reason for this change is that there are simple header files that depend only on the compiler macros, so including qemu-common.h is overkill. Besides, qemu-common.h is bloated and will benefit from some splitting. Signed-off-by: Luiz Capitulino lcapitul...@gmail.com --- compiler.h| 38 ++ qemu-common.h | 25 + 2 files changed, 39 insertions(+), 24 deletions(-) create mode 100644 compiler.h diff --git a/compiler.h b/compiler.h new file mode 100644 index 000..864f8ff --- /dev/null +++ b/compiler.h @@ -0,0 +1,38 @@ +/* + * Compiler related definition + * + * This work is licensed under the terms of the GNU GPL, version 2. See + * the COPYING file in the top-level directory. + * + */ +#ifndef COMPILER_H +#define COMPILER_H + +#include config-host.h + +#define QEMU_NORETURN __attribute__ ((__noreturn__)) +#ifdef CONFIG_GCC_ATTRIBUTE_WARN_UNUSED_RESULT +#define QEMU_WARN_UNUSED_RESULT __attribute__((warn_unused_result)) +#else +#define QEMU_WARN_UNUSED_RESULT +#endif + +#define QEMU_BUILD_BUG_ON(x) typedef char __build_bug_on__##__LINE__[(x)?-1:1]; + +#if defined __GNUC__ +# if (__GNUC__ 4) || \ + defined(__GNUC_MINOR__) (__GNUC__ == 4) (__GNUC_MINOR__ 4) + /* gcc versions before 4.4.x don't support gnu_printf, so use printf. */ +# define GCC_ATTR __attribute__((__unused__, format(printf, 1, 2))) +# define GCC_FMT_ATTR(n, m) __attribute__((format(printf, n, m))) I wrote the above and certainly didn't license it under GPL, please drop the bogus copyright notice at the top. Which one should I use? +# else + /* Use gnu_printf when supported (qemu uses standard format strings). */ +# define GCC_ATTR __attribute__((__unused__, format(gnu_printf, 1, 2))) +# define GCC_FMT_ATTR(n, m) __attribute__((format(gnu_printf, n, m))) +# endif +#else +#define GCC_ATTR /**/ +#define GCC_FMT_ATTR(n, m) +#endif + +#endif /* COMPILER_H */ diff --git a/qemu-common.h b/qemu-common.h index abd7a75..1e72931 100644 --- a/qemu-common.h +++ b/qemu-common.h @@ -2,16 +2,9 @@ #ifndef QEMU_COMMON_H #define QEMU_COMMON_H +#include compiler.h #include config-host.h -#define QEMU_NORETURN __attribute__ ((__noreturn__)) -#ifdef CONFIG_GCC_ATTRIBUTE_WARN_UNUSED_RESULT -#define QEMU_WARN_UNUSED_RESULT __attribute__((warn_unused_result)) -#else -#define QEMU_WARN_UNUSED_RESULT -#endif - -#define QEMU_BUILD_BUG_ON(x) typedef char __build_bug_on__##__LINE__[(x)?-1:1]; #define TFR(expr) do { if ((expr) != -1) break; } while (errno == EINTR) typedef struct QEMUTimer QEMUTimer; @@ -82,22 +75,6 @@ struct iovec { #include sys/uio.h #endif -#if defined __GNUC__ -# if (__GNUC__ 4) || \ - defined(__GNUC_MINOR__) (__GNUC__ == 4) (__GNUC_MINOR__ 4) - /* gcc versions before 4.4.x don't support gnu_printf, so use printf. */ -# define GCC_ATTR __attribute__((__unused__, format(printf, 1, 2))) -# define GCC_FMT_ATTR(n, m) __attribute__((format(printf, n, m))) -# else - /* Use gnu_printf when supported (qemu uses standard format strings). */ -# define GCC_ATTR __attribute__((__unused__, format(gnu_printf, 1, 2))) -# define GCC_FMT_ATTR(n, m) __attribute__((format(gnu_printf, n, m))) -# endif -#else -#define GCC_ATTR /**/ -#define GCC_FMT_ATTR(n, m) -#endif - typedef int (*fprintf_function)(FILE *f, const char *fmt, ...) GCC_FMT_ATTR(2, 3);
Re: [Qemu-devel] [PATCH 6/9] pl080: use specific endian ld/st_phys
On 5 July 2011 17:28, Alexander Graf ag...@suse.de wrote: --- a/hw/pl080.c +++ b/hw/pl080.c @@ -199,10 +199,10 @@ again: if (size == 0) { /* Transfer complete. */ if (ch-lli) { - ch-src = ldl_phys(ch-lli); - ch-dest = ldl_phys(ch-lli + 4); - ch-ctrl = ldl_phys(ch-lli + 12); - ch-lli = ldl_phys(ch-lli + 8); + ch-src = ldl_le_phys(ch-lli); + ch-dest = ldl_le_phys(ch-lli + 4); + ch-ctrl = ldl_le_phys(ch-lli + 12); + ch-lli = ldl_le_phys(ch-lli + 8); } else { ch-conf = ~PL080_CCONF_E; } (Mostly this email is to get this info into the archive before I forget; we talked about it on IRC. It's not intended to be a nak, which is just as well given the patch is already committed :-)) This is no worse than the existing code, but it's not actually the right behaviour. Bit 0 of ch-lli indicates which AHB master we make the request on; you use that to identify which of bits 1 and 2 in the DMACConfiguration Register to test to determine whether to be little endian or big endian for each master: if (ch-conf (PL080_CONF_M1 (ch-lli 1))) { bigendian; } else { littleendian; } However since that function pl080_run() has this early on: hw_error(DMA active\n); we'll never reach this code, so it's all a bit moot :-) (There are no doubt other bits of that code which would need fixing to properly support bigendian DMA too, which is a bit much effort for functionality that isn't used.) -- PMM
Re: [Qemu-devel] [PATCH 1/2] Introduce compiler.h header file
On Tue, 12 Jul 2011, Luiz Capitulino wrote: On Wed, 13 Jul 2011 00:31:56 +0400 (MSD) malc av1...@comtv.ru wrote: On Tue, 12 Jul 2011, Luiz Capitulino wrote: From: Luiz Capitulino lcapitul...@gmail.com This moves compiler related macros from qemu-common.h to compiler.h. The reason for this change is that there are simple header files that depend only on the compiler macros, so including qemu-common.h is overkill. Besides, qemu-common.h is bloated and will benefit from some splitting. Signed-off-by: Luiz Capitulino lcapitul...@gmail.com --- compiler.h| 38 ++ qemu-common.h | 25 + 2 files changed, 39 insertions(+), 24 deletions(-) create mode 100644 compiler.h diff --git a/compiler.h b/compiler.h new file mode 100644 index 000..864f8ff --- /dev/null +++ b/compiler.h @@ -0,0 +1,38 @@ +/* + * Compiler related definition + * + * This work is licensed under the terms of the GNU GPL, version 2. See + * the COPYING file in the top-level directory. + * + */ +#ifndef COMPILER_H +#define COMPILER_H + +#include config-host.h + +#define QEMU_NORETURN __attribute__ ((__noreturn__)) +#ifdef CONFIG_GCC_ATTRIBUTE_WARN_UNUSED_RESULT +#define QEMU_WARN_UNUSED_RESULT __attribute__((warn_unused_result)) +#else +#define QEMU_WARN_UNUSED_RESULT +#endif + +#define QEMU_BUILD_BUG_ON(x) typedef char __build_bug_on__##__LINE__[(x)?-1:1]; + +#if defined __GNUC__ +# if (__GNUC__ 4) || \ + defined(__GNUC_MINOR__) (__GNUC__ == 4) (__GNUC_MINOR__ 4) + /* gcc versions before 4.4.x don't support gnu_printf, so use printf. */ +# define GCC_ATTR __attribute__((__unused__, format(printf, 1, 2))) +# define GCC_FMT_ATTR(n, m) __attribute__((format(printf, n, m))) I wrote the above and certainly didn't license it under GPL, please drop the bogus copyright notice at the top. Which one should I use? None, it's a bloody header with definitions it's not copyrightable. +# else + /* Use gnu_printf when supported (qemu uses standard format strings). */ +# define GCC_ATTR __attribute__((__unused__, format(gnu_printf, 1, 2))) +# define GCC_FMT_ATTR(n, m) __attribute__((format(gnu_printf, n, m))) +# endif +#else +#define GCC_ATTR /**/ +#define GCC_FMT_ATTR(n, m) +#endif + +#endif /* COMPILER_H */ diff --git a/qemu-common.h b/qemu-common.h index abd7a75..1e72931 100644 --- a/qemu-common.h +++ b/qemu-common.h @@ -2,16 +2,9 @@ #ifndef QEMU_COMMON_H #define QEMU_COMMON_H +#include compiler.h #include config-host.h -#define QEMU_NORETURN __attribute__ ((__noreturn__)) -#ifdef CONFIG_GCC_ATTRIBUTE_WARN_UNUSED_RESULT -#define QEMU_WARN_UNUSED_RESULT __attribute__((warn_unused_result)) -#else -#define QEMU_WARN_UNUSED_RESULT -#endif - -#define QEMU_BUILD_BUG_ON(x) typedef char __build_bug_on__##__LINE__[(x)?-1:1]; #define TFR(expr) do { if ((expr) != -1) break; } while (errno == EINTR) typedef struct QEMUTimer QEMUTimer; @@ -82,22 +75,6 @@ struct iovec { #include sys/uio.h #endif -#if defined __GNUC__ -# if (__GNUC__ 4) || \ - defined(__GNUC_MINOR__) (__GNUC__ == 4) (__GNUC_MINOR__ 4) - /* gcc versions before 4.4.x don't support gnu_printf, so use printf. */ -# define GCC_ATTR __attribute__((__unused__, format(printf, 1, 2))) -# define GCC_FMT_ATTR(n, m) __attribute__((format(printf, n, m))) -# else - /* Use gnu_printf when supported (qemu uses standard format strings). */ -# define GCC_ATTR __attribute__((__unused__, format(gnu_printf, 1, 2))) -# define GCC_FMT_ATTR(n, m) __attribute__((format(gnu_printf, n, m))) -# endif -#else -#define GCC_ATTR /**/ -#define GCC_FMT_ATTR(n, m) -#endif - typedef int (*fprintf_function)(FILE *f, const char *fmt, ...) GCC_FMT_ATTR(2, 3); -- mailto:av1...@comtv.ru
Re: [Qemu-devel] [PATCH] tcg: Reload local variables after return from longjmp
Thanks, applied. On Sat, Jul 2, 2011 at 10:50 AM, Jan Kiszka jan.kis...@web.de wrote: From: Jan Kiszka jan.kis...@siemens.com Recent compilers look deep into cpu_exec, find longjmp as a noreturn function and decide to smash some stack variables as they won't be used again. This may lead to env becoming invalid after return from setjmp, causing crashes. Fix it by reloading env from cpu_single_env in that case. Signed-off-by: Jan Kiszka jan.kis...@siemens.com --- cpu-exec.c | 4 1 files changed, 4 insertions(+), 0 deletions(-) diff --git a/cpu-exec.c b/cpu-exec.c index 20e3ec4..de0d716 100644 --- a/cpu-exec.c +++ b/cpu-exec.c @@ -587,6 +587,10 @@ int cpu_exec(CPUState *env) /* reset soft MMU for next block (it can currently only be set by a memory fault) */ } /* for(;;) */ + } else { + /* Reload env after longjmp - the compiler may have smashed all + * local variables as longjmp is marked 'noreturn'. */ + env = cpu_single_env; } } /* for(;;) */
Re: [Qemu-devel] [PATCH] exec.c: Fix calculation of code_gen_buffer_max_size
Thanks, applied. On Wed, Jul 6, 2011 at 2:07 PM, Peter Maydell peter.mayd...@linaro.org wrote: Ping? On 22 June 2011 11:58, Peter Maydell peter.mayd...@linaro.org wrote: When calculating the point at which we should not try to put another TB into the code gen buffer, we have to allow not just for OPC_MAX_SIZE but OPC_BUF_SIZE. This is because the target translate.c will only stop when an instruction has put it past the OPC_MAX_SIZE limit, so we have to include the MAX_OP_PER_INSTR margin which that final insn might have used. Signed-off-by: Peter Maydell peter.mayd...@linaro.org --- exec.c | 4 ++-- 1 files changed, 2 insertions(+), 2 deletions(-) diff --git a/exec.c b/exec.c index 09928a3..c910840 100644 --- a/exec.c +++ b/exec.c @@ -555,8 +555,8 @@ static void code_gen_alloc(unsigned long tb_size) #endif #endif /* !USE_STATIC_CODE_GEN_BUFFER */ map_exec(code_gen_prologue, sizeof(code_gen_prologue)); - code_gen_buffer_max_size = code_gen_buffer_size - - (TCG_MAX_OP_SIZE * OPC_MAX_SIZE); + code_gen_buffer_max_size = code_gen_buffer_size - + (TCG_MAX_OP_SIZE * OPC_BUF_SIZE); code_gen_max_blocks = code_gen_buffer_size / CODE_GEN_AVG_BLOCK_SIZE; tbs = qemu_malloc(code_gen_max_blocks * sizeof(TranslationBlock)); } -- 1.7.1
Re: [Qemu-devel] Loading ELF binaries with very high base addresses
Yes, exactly what happened when loading a non-trivial binary. :-( Oh well. On Wed, Jul 13, 2011 at 12:04 AM, Richard Henderson r...@twiddle.net wrote: On 07/12/2011 09:43 AM, Alexander Graf wrote: For now, just force the mapping to somewhere mappable :) Unfortunately, I can tell you that there is no such place. The text segment is mapped by default at 0x4000 and the data segment is by default mapped at 0x6000. If you set guest_base = 0xc000, which remaps the text segment to 0, then the data segment will still be at 0x2000, which x86_64 still cannot represent. If you hack the address mapping routines to simply drop the high bits, then the text and data segments will map on top of one another. You can well imagine how well that will work. The *only* way to solve this is with softmmu. r~
Re: [Qemu-devel] [PATCH] exec-all.h: Make MAX_OP_PER_INSTR large enough for target-arm's uses
Thanks, applied. On Wed, Jul 6, 2011 at 2:15 PM, Peter Maydell peter.mayd...@linaro.org wrote: Ping? On 22 June 2011 15:16, Peter Maydell peter.mayd...@linaro.org wrote: The target-arm frontend's worst-case TCG ops per instr is 194 (and in general many of the load multiple registers ARM instructions generate more than 100 TCG ops). Raise MAX_OP_PER_INSTR accordingly to avoid possible buffer overruns. Since it doesn't make any sense for the 64 bit guest on 32 bit host case to have a smaller limit than the normal case, we collapse the two cases back into each other again. (This increase costs us about 14K in extra static buffer space and 21K of extra margin at the end of a 32MB codegen buffer.) Signed-off-by: Peter Maydell peter.mayd...@linaro.org --- You might recall the patchset which moves the Neon load/store multiple instructions to helper functions, and which turns out to slow them down rather a lot. This is the other approach, which is just to raise the limit so that the existing implementations don't risk buffer overruns. The extra memory costs are tiny IMHO. (The Neon instructions are the worst offenders but the VFP load/store multiple insns also breach the previous limit. I think we should consider an implementation of an instruction that's been basically the same since VFP support was added to QEMU in 2005 to be an acceptable one, and make sure our buffer sizes cope with it :-)) exec-all.h | 6 +- 1 files changed, 1 insertions(+), 5 deletions(-) diff --git a/exec-all.h b/exec-all.h index 2a13a95..ef5f5b6 100644 --- a/exec-all.h +++ b/exec-all.h @@ -43,11 +43,7 @@ typedef ram_addr_t tb_page_addr_t; typedef struct TranslationBlock TranslationBlock; /* XXX: make safe guess about sizes */ -#if (HOST_LONG_BITS == 32) (TARGET_LONG_BITS == 64) -#define MAX_OP_PER_INSTR 128 -#else -#define MAX_OP_PER_INSTR 96 -#endif +#define MAX_OP_PER_INSTR 208 #if HOST_LONG_BITS == 32 #define MAX_OPC_PARAM_PER_ARG 2 -- 1.7.1
Re: [Qemu-devel] [PATCH] target-alpha, target-ppc: Remove unnecessary setjmp.h include
Thanks, applied. On Tue, Jul 5, 2011 at 12:02 AM, Peter Maydell peter.mayd...@linaro.org wrote: Remove the include of setjmp.h from the cpu.h of target-alpha and target-ppc. This is unnecessary because cpu-defs.h already includes this header; this change brings these two targets into line with all the rest. Signed-off-by: Peter Maydell peter.mayd...@linaro.org --- target-alpha/cpu.h | 2 -- target-ppc/cpu.h | 2 -- 2 files changed, 0 insertions(+), 4 deletions(-) diff --git a/target-alpha/cpu.h b/target-alpha/cpu.h index 411bd55..78caa79 100644 --- a/target-alpha/cpu.h +++ b/target-alpha/cpu.h @@ -28,8 +28,6 @@ #include cpu-defs.h -#include setjmp.h - #include softfloat.h #define TARGET_HAS_ICE 1 diff --git a/target-ppc/cpu.h b/target-ppc/cpu.h index 84f8ff6..d903366 100644 --- a/target-ppc/cpu.h +++ b/target-ppc/cpu.h @@ -75,8 +75,6 @@ #include cpu-defs.h -#include setjmp.h - #include softfloat.h #define TARGET_HAS_ICE 1 -- 1.7.4.1
Re: [Qemu-devel] [PATCH 1/2] Introduce compiler.h header file
On Wed, 13 Jul 2011 00:43:42 +0400 (MSD) malc av1...@comtv.ru wrote: On Tue, 12 Jul 2011, Luiz Capitulino wrote: On Wed, 13 Jul 2011 00:31:56 +0400 (MSD) malc av1...@comtv.ru wrote: On Tue, 12 Jul 2011, Luiz Capitulino wrote: From: Luiz Capitulino lcapitul...@gmail.com This moves compiler related macros from qemu-common.h to compiler.h. The reason for this change is that there are simple header files that depend only on the compiler macros, so including qemu-common.h is overkill. Besides, qemu-common.h is bloated and will benefit from some splitting. Signed-off-by: Luiz Capitulino lcapitul...@gmail.com --- compiler.h| 38 ++ qemu-common.h | 25 + 2 files changed, 39 insertions(+), 24 deletions(-) create mode 100644 compiler.h diff --git a/compiler.h b/compiler.h new file mode 100644 index 000..864f8ff --- /dev/null +++ b/compiler.h @@ -0,0 +1,38 @@ +/* + * Compiler related definition + * + * This work is licensed under the terms of the GNU GPL, version 2. See + * the COPYING file in the top-level directory. + * + */ +#ifndef COMPILER_H +#define COMPILER_H + +#include config-host.h + +#define QEMU_NORETURN __attribute__ ((__noreturn__)) +#ifdef CONFIG_GCC_ATTRIBUTE_WARN_UNUSED_RESULT +#define QEMU_WARN_UNUSED_RESULT __attribute__((warn_unused_result)) +#else +#define QEMU_WARN_UNUSED_RESULT +#endif + +#define QEMU_BUILD_BUG_ON(x) typedef char __build_bug_on__##__LINE__[(x)?-1:1]; + +#if defined __GNUC__ +# if (__GNUC__ 4) || \ + defined(__GNUC_MINOR__) (__GNUC__ == 4) (__GNUC_MINOR__ 4) + /* gcc versions before 4.4.x don't support gnu_printf, so use printf. */ +# define GCC_ATTR __attribute__((__unused__, format(printf, 1, 2))) +# define GCC_FMT_ATTR(n, m) __attribute__((format(printf, n, m))) I wrote the above and certainly didn't license it under GPL, please drop the bogus copyright notice at the top. Which one should I use? None, it's a bloody header with definitions it's not copyrightable. It's, but you're choosing not to do so. +# else + /* Use gnu_printf when supported (qemu uses standard format strings). */ +# define GCC_ATTR __attribute__((__unused__, format(gnu_printf, 1, 2))) +# define GCC_FMT_ATTR(n, m) __attribute__((format(gnu_printf, n, m))) +# endif +#else +#define GCC_ATTR /**/ +#define GCC_FMT_ATTR(n, m) +#endif + +#endif /* COMPILER_H */ diff --git a/qemu-common.h b/qemu-common.h index abd7a75..1e72931 100644 --- a/qemu-common.h +++ b/qemu-common.h @@ -2,16 +2,9 @@ #ifndef QEMU_COMMON_H #define QEMU_COMMON_H +#include compiler.h #include config-host.h -#define QEMU_NORETURN __attribute__ ((__noreturn__)) -#ifdef CONFIG_GCC_ATTRIBUTE_WARN_UNUSED_RESULT -#define QEMU_WARN_UNUSED_RESULT __attribute__((warn_unused_result)) -#else -#define QEMU_WARN_UNUSED_RESULT -#endif - -#define QEMU_BUILD_BUG_ON(x) typedef char __build_bug_on__##__LINE__[(x)?-1:1]; #define TFR(expr) do { if ((expr) != -1) break; } while (errno == EINTR) typedef struct QEMUTimer QEMUTimer; @@ -82,22 +75,6 @@ struct iovec { #include sys/uio.h #endif -#if defined __GNUC__ -# if (__GNUC__ 4) || \ - defined(__GNUC_MINOR__) (__GNUC__ == 4) (__GNUC_MINOR__ 4) - /* gcc versions before 4.4.x don't support gnu_printf, so use printf. */ -# define GCC_ATTR __attribute__((__unused__, format(printf, 1, 2))) -# define GCC_FMT_ATTR(n, m) __attribute__((format(printf, n, m))) -# else - /* Use gnu_printf when supported (qemu uses standard format strings). */ -# define GCC_ATTR __attribute__((__unused__, format(gnu_printf, 1, 2))) -# define GCC_FMT_ATTR(n, m) __attribute__((format(gnu_printf, n, m))) -# endif -#else -#define GCC_ATTR /**/ -#define GCC_FMT_ATTR(n, m) -#endif - typedef int (*fprintf_function)(FILE *f, const char *fmt, ...) GCC_FMT_ATTR(2, 3);
Re: [Qemu-devel] [PATCH v2] Remove unneeded setjmp.h (fix compilation on Debian lenny)
Thanks, applied. On Mon, Jul 4, 2011 at 9:52 PM, Stefan Weil w...@mail.berlios.de wrote: Some versions of png.h cannot be included after setjmp.h, even when PNG_SKIP_SETJMP_CHECK was defined. setjmp.h was included from qemu-common.h and is not needed there. Removing the include statement fixes compilation of ui/vnc-enc-tight.c with CONFIG_VNC_PNG defined. Signed-off-by: Stefan Weil w...@mail.berlios.de --- qemu-common.h | 1 - 1 files changed, 0 insertions(+), 1 deletions(-) diff --git a/qemu-common.h b/qemu-common.h index abd7a75..c2b79bd 100644 --- a/qemu-common.h +++ b/qemu-common.h @@ -117,7 +117,6 @@ static inline char *realpath(const char *path, char *resolved_path) /* FIXME: Remove NEED_CPU_H. */ #ifndef NEED_CPU_H -#include setjmp.h #include osdep.h #include bswap.h -- 1.7.2.5
Re: [Qemu-devel] Loading ELF binaries with very high base addresses
On 07/12/2011 01:58 PM, Prashant Vaibhav wrote: Yes, exactly what happened when loading a non-trivial binary. :-( Oh well. If you've got an ia64 cross-compiler, you could still make progress on qemu by building your own binaries and linking them somewhere convenient in the low 64 TB. r~
Re: [Qemu-devel] [PATCH v2] esp: cancel current request only if some request is in flight
Thanks, applied. 2011/7/9 Hervé Poussineau hpous...@reactos.org: This bug was introduced in 94d3f98a3f3caddd7875f9a11776daeb84962a7b: scsi_cancel_io was checking if some request was pending before trying to cancel it, while scsi_req_cancel always cancels the request. This may lead to a crash of Qemu due to dereferencing a NULL pointer, as exhibited by NetBSD 5.1 installer on MIPS Magnum emulation. Signed-off-by: Hervé Poussineau hpous...@reactos.org --- Changes since v1: - better commit message hw/esp.c | 2 +- 1 files changed, 1 insertions(+), 1 deletions(-) diff --git a/hw/esp.c b/hw/esp.c index 8e95672..aa50800 100644 --- a/hw/esp.c +++ b/hw/esp.c @@ -219,7 +219,7 @@ static uint32_t get_cmd(ESPState *s, uint8_t *buf) s-ti_rptr = 0; s-ti_wptr = 0; - if (s-current_dev) { + if (s-current_req) { /* Started a new command before the old one finished. Cancel it. */ scsi_req_cancel(s-current_req); s-async_len = 0; -- 1.7.5.4
Re: [Qemu-devel] [PATCH] os-posix: set groups properly for -runas
Thanks, applied. On Sat, Jul 9, 2011 at 12:22 PM, Stefan Hajnoczi stefa...@linux.vnet.ibm.com wrote: Andrew Griffiths reports that -runas does not set supplementary group IDs. This means that gid 0 (root) is not dropped when switching to an unprivileged user. Add an initgroups(3) call to use the -runas user's /etc/groups membership to update the supplementary group IDs. Signed-off-by: Stefan Hajnoczi stefa...@linux.vnet.ibm.com --- Note this needs compile testing on various POSIX host platforms. Tested on Linux. Should work on BSD and Solaris. initgroups(3) is SVr4/BSD but not in POSIX. os-posix.c | 6 ++ 1 files changed, 6 insertions(+), 0 deletions(-) diff --git a/os-posix.c b/os-posix.c index 7dfb278..6f8d488 100644 --- a/os-posix.c +++ b/os-posix.c @@ -31,6 +31,7 @@ /*needed for MAP_POPULATE before including qemu-options.h */ #include sys/mman.h #include pwd.h +#include grp.h #include libgen.h /* Needed early for CONFIG_BSD etc. */ @@ -199,6 +200,11 @@ static void change_process_uid(void) fprintf(stderr, Failed to setgid(%d)\n, user_pwd-pw_gid); exit(1); } + if (initgroups(user_pwd-pw_name, user_pwd-pw_gid) 0) { + fprintf(stderr, Failed to initgroups(\%s\, %d)\n, + user_pwd-pw_name, user_pwd-pw_gid); + exit(1); + } if (setuid(user_pwd-pw_uid) 0) { fprintf(stderr, Failed to setuid(%d)\n, user_pwd-pw_uid); exit(1); -- 1.7.5.4
Re: [Qemu-devel] [RFC v3 30/56] rtl8139: convert to memory API
On Sun, 2011-07-10 at 21:14 +0300, Avi Kivity wrote: Signed-off-by: Avi Kivity a...@redhat.com --- hw/rtl8139.c | 172 +- 1 files changed, 51 insertions(+), 121 deletions(-) diff --git a/hw/rtl8139.c b/hw/rtl8139.c index 5214b8c..fa661fc 100644 --- a/hw/rtl8139.c +++ b/hw/rtl8139.c @@ -474,7 +474,6 @@ typedef struct RTL8139State { NICState *nic; NICConf conf; -int rtl8139_mmio_io_addr; /* C ring mode */ uint32_t currTxDesc; @@ -506,6 +505,9 @@ typedef struct RTL8139State { QEMUTimer *timer; int64_t TimerExpire; +MemoryRegion bar_io; +MemoryRegion bar_mem; + /* Support migration to/from old versions */ int rtl8139_mmio_io_addr_dummy; } RTL8139State; @@ -2705,12 +2707,8 @@ static uint32_t rtl8139_MultiIntr_read(RTL8139State *s) return ret; } -static void rtl8139_io_writeb(void *opaque, uint8_t addr, uint32_t val) +static void rtl8139_io_writeb(RTL8139State *s, uint8_t addr, uint32_t val) { -RTL8139State *s = opaque; - -addr = 0xff; - switch (addr) { case MAC0 ... MAC0+5: @@ -2792,10 +2790,8 @@ static void rtl8139_io_writeb(void *opaque, uint8_t addr, uint32_t val) } } -static void rtl8139_io_writew(void *opaque, uint8_t addr, uint32_t val) +static void rtl8139_io_writew(RTL8139State *s, uint8_t addr, uint32_t val) { -RTL8139State *s = opaque; - addr = 0xfe; switch (addr) @@ -2846,8 +2842,8 @@ static void rtl8139_io_writew(void *opaque, uint8_t addr, uint32_t val) DPRINTF(ioport write(w) addr=0x%x val=0x%04x via write(b)\n, addr, val); -rtl8139_io_writeb(opaque, addr, val 0xff); -rtl8139_io_writeb(opaque, addr + 1, (val 8) 0xff); +rtl8139_io_writeb(s, addr, val 0xff); +rtl8139_io_writeb(s, addr + 1, (val 8) 0xff); break; } } @@ -2892,10 +2888,8 @@ static void rtl8139_set_next_tctr_time(RTL8139State *s, int64_t current_time) } } -static void rtl8139_io_writel(void *opaque, uint8_t addr, uint32_t val) +static void rtl8139_io_writel(RTL8139State *s, uint8_t addr, uint32_t val) { -RTL8139State *s = opaque; - addr = 0xfc; switch (addr) @@ -2952,21 +2946,18 @@ static void rtl8139_io_writel(void *opaque, uint8_t addr, uint32_t val) default: DPRINTF(ioport write(l) addr=0x%x val=0x%08x via write(b)\n, addr, val); -rtl8139_io_writeb(opaque, addr, val 0xff); -rtl8139_io_writeb(opaque, addr + 1, (val 8) 0xff); -rtl8139_io_writeb(opaque, addr + 2, (val 16) 0xff); -rtl8139_io_writeb(opaque, addr + 3, (val 24) 0xff); +rtl8139_io_writeb(s, addr, val 0xff); +rtl8139_io_writeb(s, addr + 1, (val 8) 0xff); +rtl8139_io_writeb(s, addr + 2, (val 16) 0xff); +rtl8139_io_writeb(s, addr + 3, (val 24) 0xff); break; } } -static uint32_t rtl8139_io_readb(void *opaque, uint8_t addr) +static uint32_t rtl8139_io_readb(RTL8139State *s, uint8_t addr) { -RTL8139State *s = opaque; int ret; -addr = 0xff; - switch (addr) { case MAC0 ... MAC0+5: @@ -3034,9 +3025,8 @@ static uint32_t rtl8139_io_readb(void *opaque, uint8_t addr) return ret; } -static uint32_t rtl8139_io_readw(void *opaque, uint8_t addr) +static uint32_t rtl8139_io_readw(RTL8139State *s, uint8_t addr) { -RTL8139State *s = opaque; uint32_t ret; addr = 0xfe; /* mask lower bit */ @@ -3101,8 +3091,8 @@ static uint32_t rtl8139_io_readw(void *opaque, uint8_t addr) default: DPRINTF(ioport read(w) addr=0x%x via read(b)\n, addr); -ret = rtl8139_io_readb(opaque, addr); -ret |= rtl8139_io_readb(opaque, addr + 1) 8; +ret = rtl8139_io_readb(s, addr); +ret |= rtl8139_io_readb(s, addr + 1) 8; DPRINTF(ioport read(w) addr=0x%x val=0x%04x\n, addr, ret); break; @@ -3182,71 +3172,40 @@ static uint32_t rtl8139_io_readl(void *opaque, uint8_t addr) return ret; } -/* */ - -static void rtl8139_ioport_writeb(void *opaque, uint32_t addr, uint32_t val) -{ -rtl8139_io_writeb(opaque, addr 0xFF, val); -} - -static void rtl8139_ioport_writew(void *opaque, uint32_t addr, uint32_t val) -{ -rtl8139_io_writew(opaque, addr 0xFF, val); -} - -static void rtl8139_ioport_writel(void *opaque, uint32_t addr, uint32_t val) -{ -rtl8139_io_writel(opaque, addr 0xFF, val); -} - -static uint32_t rtl8139_ioport_readb(void *opaque, uint32_t addr) +static uint64_t rtl8139_io_read(void *opaque, +target_phys_addr_t addr, +unsigned size) { -return
Re: [Qemu-devel] [RFC v3 30/56] rtl8139: convert to memory API
On Tue, 2011-07-12 at 16:41 -0600, Alex Williamson wrote: On Sun, 2011-07-10 at 21:14 +0300, Avi Kivity wrote: Signed-off-by: Avi Kivity a...@redhat.com --- hw/rtl8139.c | 172 +- 1 files changed, 51 insertions(+), 121 deletions(-) diff --git a/hw/rtl8139.c b/hw/rtl8139.c index 5214b8c..fa661fc 100644 --- a/hw/rtl8139.c +++ b/hw/rtl8139.c @@ -474,7 +474,6 @@ typedef struct RTL8139State { NICState *nic; NICConf conf; -int rtl8139_mmio_io_addr; /* C ring mode */ uint32_t currTxDesc; @@ -506,6 +505,9 @@ typedef struct RTL8139State { QEMUTimer *timer; int64_t TimerExpire; +MemoryRegion bar_io; +MemoryRegion bar_mem; + /* Support migration to/from old versions */ int rtl8139_mmio_io_addr_dummy; } RTL8139State; @@ -2705,12 +2707,8 @@ static uint32_t rtl8139_MultiIntr_read(RTL8139State *s) return ret; } -static void rtl8139_io_writeb(void *opaque, uint8_t addr, uint32_t val) +static void rtl8139_io_writeb(RTL8139State *s, uint8_t addr, uint32_t val) { -RTL8139State *s = opaque; - -addr = 0xff; - switch (addr) { case MAC0 ... MAC0+5: @@ -2792,10 +2790,8 @@ static void rtl8139_io_writeb(void *opaque, uint8_t addr, uint32_t val) } } -static void rtl8139_io_writew(void *opaque, uint8_t addr, uint32_t val) +static void rtl8139_io_writew(RTL8139State *s, uint8_t addr, uint32_t val) { -RTL8139State *s = opaque; - addr = 0xfe; switch (addr) @@ -2846,8 +2842,8 @@ static void rtl8139_io_writew(void *opaque, uint8_t addr, uint32_t val) DPRINTF(ioport write(w) addr=0x%x val=0x%04x via write(b)\n, addr, val); -rtl8139_io_writeb(opaque, addr, val 0xff); -rtl8139_io_writeb(opaque, addr + 1, (val 8) 0xff); +rtl8139_io_writeb(s, addr, val 0xff); +rtl8139_io_writeb(s, addr + 1, (val 8) 0xff); break; } } @@ -2892,10 +2888,8 @@ static void rtl8139_set_next_tctr_time(RTL8139State *s, int64_t current_time) } } -static void rtl8139_io_writel(void *opaque, uint8_t addr, uint32_t val) +static void rtl8139_io_writel(RTL8139State *s, uint8_t addr, uint32_t val) { -RTL8139State *s = opaque; - addr = 0xfc; switch (addr) @@ -2952,21 +2946,18 @@ static void rtl8139_io_writel(void *opaque, uint8_t addr, uint32_t val) default: DPRINTF(ioport write(l) addr=0x%x val=0x%08x via write(b)\n, addr, val); -rtl8139_io_writeb(opaque, addr, val 0xff); -rtl8139_io_writeb(opaque, addr + 1, (val 8) 0xff); -rtl8139_io_writeb(opaque, addr + 2, (val 16) 0xff); -rtl8139_io_writeb(opaque, addr + 3, (val 24) 0xff); +rtl8139_io_writeb(s, addr, val 0xff); +rtl8139_io_writeb(s, addr + 1, (val 8) 0xff); +rtl8139_io_writeb(s, addr + 2, (val 16) 0xff); +rtl8139_io_writeb(s, addr + 3, (val 24) 0xff); break; } } -static uint32_t rtl8139_io_readb(void *opaque, uint8_t addr) +static uint32_t rtl8139_io_readb(RTL8139State *s, uint8_t addr) { -RTL8139State *s = opaque; int ret; -addr = 0xff; - switch (addr) { case MAC0 ... MAC0+5: @@ -3034,9 +3025,8 @@ static uint32_t rtl8139_io_readb(void *opaque, uint8_t addr) return ret; } -static uint32_t rtl8139_io_readw(void *opaque, uint8_t addr) +static uint32_t rtl8139_io_readw(RTL8139State *s, uint8_t addr) { -RTL8139State *s = opaque; uint32_t ret; addr = 0xfe; /* mask lower bit */ @@ -3101,8 +3091,8 @@ static uint32_t rtl8139_io_readw(void *opaque, uint8_t addr) default: DPRINTF(ioport read(w) addr=0x%x via read(b)\n, addr); -ret = rtl8139_io_readb(opaque, addr); -ret |= rtl8139_io_readb(opaque, addr + 1) 8; +ret = rtl8139_io_readb(s, addr); +ret |= rtl8139_io_readb(s, addr + 1) 8; DPRINTF(ioport read(w) addr=0x%x val=0x%04x\n, addr, ret); break; @@ -3182,71 +3172,40 @@ static uint32_t rtl8139_io_readl(void *opaque, uint8_t addr) return ret; } -/* */ - -static void rtl8139_ioport_writeb(void *opaque, uint32_t addr, uint32_t val) -{ -rtl8139_io_writeb(opaque, addr 0xFF, val); -} - -static void rtl8139_ioport_writew(void *opaque, uint32_t addr, uint32_t val) -{ -rtl8139_io_writew(opaque, addr 0xFF, val); -} - -static void rtl8139_ioport_writel(void *opaque, uint32_t addr, uint32_t val) -{ -rtl8139_io_writel(opaque, addr 0xFF, val); -} - -static
[Qemu-devel] [PATCH v6 01/18] Add hard build dependency on glib
From: Anthony Liguori aligu...@us.ibm.com GLib is an extremely common library that has a portable thread implementation along with tons of other goodies. GLib and GObject have a fantastic amount of infrastructure we can leverage in QEMU including an object oriented programming infrastructure. Short term, it has a very nice thread pool implementation that we could leverage in something like virtio-9p. It also has a test harness implementation that this series will use. Signed-off-by: Anthony Liguori aligu...@us.ibm.com Signed-off-by: Michael Roth mdr...@linux.vnet.ibm.com --- Makefile|2 ++ Makefile.objs |2 ++ Makefile.target |1 + configure | 13 + 4 files changed, 18 insertions(+), 0 deletions(-) diff --git a/Makefile b/Makefile index b3ffbe2..42ae4e5 100644 --- a/Makefile +++ b/Makefile @@ -106,6 +106,8 @@ audio/audio.o audio/fmodaudio.o: QEMU_CFLAGS += $(FMOD_CFLAGS) QEMU_CFLAGS+=$(CURL_CFLAGS) +QEMU_CFLAGS+=$(GLIB_CFLAGS) + ui/cocoa.o: ui/cocoa.m ui/sdl.o audio/sdlaudio.o ui/sdl_zoom.o baum.o: QEMU_CFLAGS += $(SDL_CFLAGS) diff --git a/Makefile.objs b/Makefile.objs index cea15e4..493c988 100644 --- a/Makefile.objs +++ b/Makefile.objs @@ -376,3 +376,5 @@ vl.o: QEMU_CFLAGS+=$(GPROF_CFLAGS) vl.o: QEMU_CFLAGS+=$(SDL_CFLAGS) +vl.o: QEMU_CFLAGS+=$(GLIB_CFLAGS) + diff --git a/Makefile.target b/Makefile.target index a53a2ff..b8256ae 100644 --- a/Makefile.target +++ b/Makefile.target @@ -203,6 +203,7 @@ QEMU_CFLAGS += $(VNC_TLS_CFLAGS) QEMU_CFLAGS += $(VNC_SASL_CFLAGS) QEMU_CFLAGS += $(VNC_JPEG_CFLAGS) QEMU_CFLAGS += $(VNC_PNG_CFLAGS) +QEMU_CFLAGS += $(GLIB_CFLAGS) # xen backend driver support obj-i386-$(CONFIG_XEN) += xen_machine_pv.o xen_domainbuild.o diff --git a/configure b/configure index 88159ac..63156a2 100755 --- a/configure +++ b/configure @@ -1803,6 +1803,18 @@ EOF fi ## +# glib support probe +if $pkg_config --modversion gthread-2.0 gio-2.0 /dev/null 21 ; then +glib_cflags=`$pkg_config --cflags gthread-2.0 gio-2.0 2/dev/null` +glib_libs=`$pkg_config --libs gthread-2.0 gio-2.0 2/dev/null` +libs_softmmu=$glib_libs $libs_softmmu +libs_tools=$glib_libs $libs_tools +else +echo glib-2.0 required to compile QEMU +exit 1 +fi + +## # pthread probe PTHREADLIBS_LIST=-lpthread -lpthreadGC2 @@ -2849,6 +2861,7 @@ if test $bluez = yes ; then echo CONFIG_BLUEZ=y $config_host_mak echo BLUEZ_CFLAGS=$bluez_cflags $config_host_mak fi +echo GLIB_CFLAGS=$glib_cflags $config_host_mak if test $xen = yes ; then echo CONFIG_XEN=y $config_host_mak echo CONFIG_XEN_CTRL_INTERFACE_VERSION=$xen_ctrl_version $config_host_mak -- 1.7.0.4
[Qemu-devel] [PATCH v6 03/18] qapi: add module init types for qapi
Signed-off-by: Michael Roth mdr...@linux.vnet.ibm.com --- module.h |2 ++ 1 files changed, 2 insertions(+), 0 deletions(-) diff --git a/module.h b/module.h index 9263f1c..ef66730 100644 --- a/module.h +++ b/module.h @@ -24,12 +24,14 @@ typedef enum { MODULE_INIT_BLOCK, MODULE_INIT_DEVICE, MODULE_INIT_MACHINE, +MODULE_INIT_QAPI, MODULE_INIT_MAX } module_init_type; #define block_init(function) module_init(function, MODULE_INIT_BLOCK) #define device_init(function) module_init(function, MODULE_INIT_DEVICE) #define machine_init(function) module_init(function, MODULE_INIT_MACHINE) +#define qapi_init(function) module_init(function, MODULE_INIT_QAPI) void register_module_init(void (*fn)(void), module_init_type type); -- 1.7.0.4
[Qemu-devel] [PATCH v6 07/18] qapi: add QAPI dealloc visitor
Type of Visitor class that can be passed into a qapi-generated C type's visitor function to free() any heap-allocated data types. Signed-off-by: Michael Roth mdr...@linux.vnet.ibm.com --- Makefile.objs |2 +- qapi/qapi-dealloc-visitor.c | 147 +++ qapi/qapi-dealloc-visitor.h | 26 3 files changed, 174 insertions(+), 1 deletions(-) create mode 100644 qapi/qapi-dealloc-visitor.c create mode 100644 qapi/qapi-dealloc-visitor.h diff --git a/Makefile.objs b/Makefile.objs index 7f9cba5..08f69e5 100644 --- a/Makefile.objs +++ b/Makefile.objs @@ -375,7 +375,7 @@ libcacard-y = cac.o event.o vcard.o vreader.o vcard_emul_nss.o vcard_emul_type.o ## # qapi -qapi-nested-y = qapi-visit-core.o qmp-input-visitor.o qmp-output-visitor.o +qapi-nested-y = qapi-visit-core.o qmp-input-visitor.o qmp-output-visitor.o qapi-dealloc-visitor.o qapi-obj-y = $(addprefix qapi/, $(qapi-nested-y)) vl.o: QEMU_CFLAGS+=$(GPROF_CFLAGS) diff --git a/qapi/qapi-dealloc-visitor.c b/qapi/qapi-dealloc-visitor.c new file mode 100644 index 000..8cde4dd --- /dev/null +++ b/qapi/qapi-dealloc-visitor.c @@ -0,0 +1,147 @@ +/* + * Dealloc Visitor + * + * Copyright IBM, Corp. 2011 + * + * Authors: + * Michael Roth mdr...@linux.vnet.ibm.com + * + * This work is licensed under the terms of the GNU LGPL, version 2.1 or later. + * See the COPYING.LIB file in the top-level directory. + * + */ + +#include qapi-dealloc-visitor.h +#include qemu-queue.h +#include qemu-common.h +#include qemu-objects.h + +typedef struct StackEntry +{ +void *value; +QTAILQ_ENTRY(StackEntry) node; +} StackEntry; + +struct QapiDeallocVisitor +{ +Visitor visitor; +QTAILQ_HEAD(, StackEntry) stack; +}; + +static QapiDeallocVisitor *to_qov(Visitor *v) +{ +return container_of(v, QapiDeallocVisitor, visitor); +} + +static void qapi_dealloc_push(QapiDeallocVisitor *qov, void *value) +{ +StackEntry *e = qemu_mallocz(sizeof(*e)); + +e-value = value; +QTAILQ_INSERT_HEAD(qov-stack, e, node); +} + +static void *qapi_dealloc_pop(QapiDeallocVisitor *qov) +{ +StackEntry *e = QTAILQ_FIRST(qov-stack); +QObject *value; +QTAILQ_REMOVE(qov-stack, e, node); +value = e-value; +qemu_free(e); +return value; +} + +static void qapi_dealloc_start_struct(Visitor *v, void **obj, const char *kind, + const char *name, size_t unused, + Error **errp) +{ +QapiDeallocVisitor *qov = to_qov(v); +qapi_dealloc_push(qov, obj); +} + +static void qapi_dealloc_end_struct(Visitor *v, Error **errp) +{ +QapiDeallocVisitor *qov = to_qov(v); +void **obj = qapi_dealloc_pop(qov); +if (obj) { +qemu_free(*obj); +} +} + +static void qapi_dealloc_start_list(Visitor *v, const char *name, Error **errp) +{ +} + +static GenericList *qapi_dealloc_next_list(Visitor *v, GenericList **list, + Error **errp) +{ +GenericList *retval = *list; +qemu_free(retval-value); +*list = retval-next; +return retval; +} + +static void qapi_dealloc_end_list(Visitor *v, Error **errp) +{ +} + +static void qapi_dealloc_type_str(Visitor *v, char **obj, const char *name, + Error **errp) +{ +if (obj) { +qemu_free(*obj); +} +} + +static void qapi_dealloc_type_int(Visitor *v, int64_t *obj, const char *name, + Error **errp) +{ +} + +static void qapi_dealloc_type_bool(Visitor *v, bool *obj, const char *name, + Error **errp) +{ +} + +static void qapi_dealloc_type_number(Visitor *v, double *obj, const char *name, + Error **errp) +{ +} + +static void qapi_dealloc_type_enum(Visitor *v, int *obj, const char *strings[], + const char *kind, const char *name, + Error **errp) +{ +} + +Visitor *qapi_dealloc_get_visitor(QapiDeallocVisitor *v) +{ +return v-visitor; +} + +void qapi_dealloc_visitor_cleanup(QapiDeallocVisitor *v) +{ +qemu_free(v); +} + +QapiDeallocVisitor *qapi_dealloc_visitor_new(void) +{ +QapiDeallocVisitor *v; + +v = qemu_mallocz(sizeof(*v)); + +v-visitor.start_struct = qapi_dealloc_start_struct; +v-visitor.end_struct = qapi_dealloc_end_struct; +v-visitor.start_list = qapi_dealloc_start_list; +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_bool = qapi_dealloc_type_bool; +v-visitor.type_str = qapi_dealloc_type_str; +v-visitor.type_number = qapi_dealloc_type_number; + +QTAILQ_INIT(v-stack); + +return v; +} diff --git a/qapi/qapi-dealloc-visitor.h
[Qemu-devel] [PATCH v6 02/18] qlist: add qlist_first()/qlist_next()
Signed-off-by: Michael Roth mdr...@linux.vnet.ibm.com --- qlist.h | 11 +++ 1 files changed, 11 insertions(+), 0 deletions(-) diff --git a/qlist.h b/qlist.h index dbe7b92..d426bd4 100644 --- a/qlist.h +++ b/qlist.h @@ -16,6 +16,7 @@ #include qobject.h #include qemu-queue.h #include qemu-common.h +#include qemu-queue.h typedef struct QListEntry { QObject *value; @@ -50,4 +51,14 @@ QObject *qlist_peek(QList *qlist); int qlist_empty(const QList *qlist); QList *qobject_to_qlist(const QObject *obj); +static inline const QListEntry *qlist_first(const QList *qlist) +{ +return QTAILQ_FIRST(qlist-head); +} + +static inline const QListEntry *qlist_next(const QListEntry *entry) +{ +return QTAILQ_NEXT(entry, next); +} + #endif /* QLIST_H */ -- 1.7.0.4
[Qemu-devel] [PATCH v6 04/18] qapi: add QAPI visitor core
Base definitions/includes for Visiter interface used by generated visiter/marshalling code. Includes a GenericList type. Our lists require an embedded element. Since these types are generated, if you want to use them in a different type of data structure, there's no easy way to add another embedded element. The solution is to have non-embedded lists and that what this is. Signed-off-by: Michael Roth mdr...@linux.vnet.ibm.com --- Makefile.objs |6 +++ configure |1 + qapi/qapi-types-core.h | 20 qapi/qapi-visit-core.c | 118 qapi/qapi-visit-core.h | 76 +++ 5 files changed, 221 insertions(+), 0 deletions(-) create mode 100644 qapi/qapi-types-core.h create mode 100644 qapi/qapi-visit-core.c create mode 100644 qapi/qapi-visit-core.h diff --git a/Makefile.objs b/Makefile.objs index 493c988..0077014 100644 --- a/Makefile.objs +++ b/Makefile.objs @@ -372,6 +372,12 @@ endif libcacard-y = cac.o event.o vcard.o vreader.o vcard_emul_nss.o vcard_emul_type.o card_7816.o +## +# qapi + +qapi-nested-y = qapi-visit-core.o +qapi-obj-y = $(addprefix qapi/, $(qapi-nested-y)) + vl.o: QEMU_CFLAGS+=$(GPROF_CFLAGS) vl.o: QEMU_CFLAGS+=$(SDL_CFLAGS) diff --git a/configure b/configure index 63156a2..02c552e 100755 --- a/configure +++ b/configure @@ -3486,6 +3486,7 @@ DIRS=tests tests/cris slirp audio block net pc-bios/optionrom DIRS=$DIRS pc-bios/spapr-rtas DIRS=$DIRS roms/seabios roms/vgabios DIRS=$DIRS fsdev ui +DIRS=$DIRS qapi FILES=Makefile tests/Makefile FILES=$FILES tests/cris/Makefile tests/cris/.gdbinit FILES=$FILES pc-bios/optionrom/Makefile pc-bios/keymaps diff --git a/qapi/qapi-types-core.h b/qapi/qapi-types-core.h new file mode 100644 index 000..a79bc2b --- /dev/null +++ b/qapi/qapi-types-core.h @@ -0,0 +1,20 @@ +/* + * Core Definitions for QAPI-generated Types + * + * Copyright IBM, Corp. 2011 + * + * Authors: + * Anthony Liguori aligu...@us.ibm.com + * + * This work is licensed under the terms of the GNU LGPL, version 2.1 or later. + * See the COPYING.LIB file in the top-level directory. + * + */ + +#ifndef QAPI_TYPES_CORE_H +#define QAPI_TYPES_CORE_H + +#include qemu-common.h +#include error.h + +#endif diff --git a/qapi/qapi-visit-core.c b/qapi/qapi-visit-core.c new file mode 100644 index 000..ddef3ed --- /dev/null +++ b/qapi/qapi-visit-core.c @@ -0,0 +1,118 @@ +/* + * Core Definitions for QAPI Visitor Classes + * + * Copyright IBM, Corp. 2011 + * + * Authors: + * Anthony Liguori aligu...@us.ibm.com + * + * This work is licensed under the terms of the GNU LGPL, version 2.1 or later. + * See the COPYING.LIB file in the top-level directory. + * + */ + +#include qapi/qapi-visit-core.h + +void visit_start_handle(Visitor *v, void **obj, const char *kind, +const char *name, Error **errp) +{ +if (!error_is_set(errp) v-start_handle) { +v-start_handle(v, obj, kind, name, errp); +} +} + +void visit_end_handle(Visitor *v, Error **errp) +{ +if (!error_is_set(errp) v-end_handle) { +v-end_handle(v, errp); +} +} + +void visit_start_struct(Visitor *v, void **obj, const char *kind, +const char *name, size_t size, Error **errp) +{ +if (!error_is_set(errp)) { +v-start_struct(v, obj, kind, name, size, errp); +} +} + +void visit_end_struct(Visitor *v, Error **errp) +{ +if (!error_is_set(errp)) { +v-end_struct(v, errp); +} +} + +void visit_start_list(Visitor *v, const char *name, Error **errp) +{ +if (!error_is_set(errp)) { +v-start_list(v, name, errp); +} +} + +GenericList *visit_next_list(Visitor *v, GenericList **list, Error **errp) +{ +if (!error_is_set(errp)) { +return v-next_list(v, list, errp); +} + +return 0; +} + +void visit_end_list(Visitor *v, Error **errp) +{ +if (!error_is_set(errp)) { +v-end_list(v, errp); +} +} + +void visit_start_optional(Visitor *v, bool *present, const char *name, + Error **errp) +{ +if (!error_is_set(errp) v-start_optional) { +v-start_optional(v, present, name, errp); +} +} + +void visit_end_optional(Visitor *v, Error **errp) +{ +if (!error_is_set(errp) v-end_optional) { +v-end_optional(v, errp); +} +} + +void visit_type_enum(Visitor *v, int *obj, const char *strings[], + const char *kind, const char *name, Error **errp) +{ +if (!error_is_set(errp)) { +v-type_enum(v, obj, strings, kind, name, errp); +} +} + +void visit_type_int(Visitor *v, int64_t *obj, const char *name, Error **errp) +{ +if (!error_is_set(errp)) { +v-type_int(v, obj, name, errp); +} +} + +void visit_type_bool(Visitor *v, bool *obj, const char *name, Error **errp) +{ +if (!error_is_set(errp)) { +v-type_bool(v, obj, name, errp);
[Qemu-devel] [PATCH v6 05/18] qapi: add QMP input visitor
A type of Visiter class that is used to walk a qobject's structure and assign each entry to the corresponding native C type. Command marshaling function will use this to pull out QMP command parameters recieved over the wire and pass them as native arguments to the corresponding C functions. Signed-off-by: Michael Roth mdr...@linux.vnet.ibm.com --- Makefile.objs|2 +- qapi/qmp-input-visitor.c | 301 ++ qapi/qmp-input-visitor.h | 27 qerror.h |3 + 4 files changed, 332 insertions(+), 1 deletions(-) create mode 100644 qapi/qmp-input-visitor.c create mode 100644 qapi/qmp-input-visitor.h diff --git a/Makefile.objs b/Makefile.objs index 0077014..997ecef 100644 --- a/Makefile.objs +++ b/Makefile.objs @@ -375,7 +375,7 @@ libcacard-y = cac.o event.o vcard.o vreader.o vcard_emul_nss.o vcard_emul_type.o ## # qapi -qapi-nested-y = qapi-visit-core.o +qapi-nested-y = qapi-visit-core.o qmp-input-visitor.o qapi-obj-y = $(addprefix qapi/, $(qapi-nested-y)) vl.o: QEMU_CFLAGS+=$(GPROF_CFLAGS) diff --git a/qapi/qmp-input-visitor.c b/qapi/qmp-input-visitor.c new file mode 100644 index 000..6a1adc9 --- /dev/null +++ b/qapi/qmp-input-visitor.c @@ -0,0 +1,301 @@ +/* + * Input Visitor + * + * Copyright IBM, Corp. 2011 + * + * Authors: + * Anthony Liguori aligu...@us.ibm.com + * + * This work is licensed under the terms of the GNU LGPL, version 2.1 or later. + * See the COPYING.LIB file in the top-level directory. + * + */ + +#include qmp-input-visitor.h +#include qemu-queue.h +#include qemu-common.h +#include qemu-objects.h +#include qerror.h + +#define QIV_STACK_SIZE 1024 + +typedef struct StackObject +{ +const QObject *obj; +const QListEntry *entry; +} StackObject; + +struct QmpInputVisitor +{ +Visitor visitor; +QObject *obj; +StackObject stack[QIV_STACK_SIZE]; +int nb_stack; +}; + +static QmpInputVisitor *to_qiv(Visitor *v) +{ +return container_of(v, QmpInputVisitor, visitor); +} + +static const QObject *qmp_input_get_object(QmpInputVisitor *qiv, + const char *name) +{ +const QObject *qobj; + +if (qiv-nb_stack == 0) { +qobj = qiv-obj; +} else { +qobj = qiv-stack[qiv-nb_stack - 1].obj; +} + +if (name qobject_type(qobj) == QTYPE_QDICT) { +return qdict_get(qobject_to_qdict(qobj), name); +} else if (qiv-nb_stack 0 qobject_type(qobj) == QTYPE_QLIST) { +return qlist_entry_obj(qiv-stack[qiv-nb_stack - 1].entry); +} + +return qobj; +} + +static void qmp_input_push(QmpInputVisitor *qiv, const QObject *obj, Error **errp) +{ +qiv-stack[qiv-nb_stack].obj = obj; +if (qobject_type(obj) == QTYPE_QLIST) { +qiv-stack[qiv-nb_stack].entry = qlist_first(qobject_to_qlist(obj)); +} +qiv-nb_stack++; + +if (qiv-nb_stack = QIV_STACK_SIZE) { +error_set(errp, QERR_BUFFER_OVERRUN); +return; +} +} + +static void qmp_input_pop(QmpInputVisitor *qiv, Error **errp) +{ +qiv-nb_stack--; +if (qiv-nb_stack 0) { +error_set(errp, QERR_BUFFER_OVERRUN); +return; +} +} + +static void qmp_input_start_struct(Visitor *v, void **obj, const char *kind, + const char *name, size_t size, Error **errp) +{ +QmpInputVisitor *qiv = to_qiv(v); +const QObject *qobj = qmp_input_get_object(qiv, name); + +if (!qobj || qobject_type(qobj) != QTYPE_QDICT) { +error_set(errp, QERR_INVALID_PARAMETER_TYPE, name ? name : null, + QDict); +return; +} + +qmp_input_push(qiv, qobj, errp); +if (error_is_set(errp)) { +return; +} + +if (obj) { +*obj = qemu_mallocz(size); +} +} + +static void qmp_input_end_struct(Visitor *v, Error **errp) +{ +QmpInputVisitor *qiv = to_qiv(v); + +qmp_input_pop(qiv, errp); +} + +static void qmp_input_start_list(Visitor *v, const char *name, Error **errp) +{ +QmpInputVisitor *qiv = to_qiv(v); +const QObject *qobj = qmp_input_get_object(qiv, name); + +if (!qobj || qobject_type(qobj) != QTYPE_QLIST) { +error_set(errp, QERR_INVALID_PARAMETER_TYPE, name ? name : null, + list); +return; +} + +qmp_input_push(qiv, qobj, errp); +} + +static GenericList *qmp_input_next_list(Visitor *v, GenericList **list, +Error **errp) +{ +QmpInputVisitor *qiv = to_qiv(v); +GenericList *entry; +StackObject *so = qiv-stack[qiv-nb_stack - 1]; + +if (so-entry == NULL) { +return NULL; +} + +entry = qemu_mallocz(sizeof(*entry)); +if (*list) { +so-entry = qlist_next(so-entry); +if (so-entry == NULL) { +qemu_free(entry); +return NULL; +} +(*list)-next = entry; +} +*list = entry; + + +return entry;
[Qemu-devel] [PATCH v6 13/18] qapi: add qapi-visit.py code generator
This is the code generator for qapi visiter functions used to marshal/unmarshal/dealloc qapi types. It generates the following 2 files: $(prefix)qapi-visit.c: visiter function for a particular c type, used to automagically convert qobjects into the corresponding C type and vice-versa, and well as for deallocation memory for an existing C type $(prefix)qapi-visit.h: declarations for previously mentioned visiter functions $(prefix) is used as decribed for qapi-types.py Signed-off-by: Michael Roth mdr...@linux.vnet.ibm.com --- scripts/qapi-visit.py | 243 + 1 files changed, 243 insertions(+), 0 deletions(-) create mode 100644 scripts/qapi-visit.py diff --git a/scripts/qapi-visit.py b/scripts/qapi-visit.py new file mode 100644 index 000..0ef6602 --- /dev/null +++ b/scripts/qapi-visit.py @@ -0,0 +1,243 @@ +# +# QAPI visitor generator +# +# Copyright IBM, Corp. 2011 +# +# Authors: +# Anthony Liguori aligu...@us.ibm.com +# Michael Rothmdr...@linux.vnet.ibm.com +# +# This work is licensed under the terms of the GNU GPLv2. +# See the COPYING.LIB file in the top-level directory. + +from ordereddict import OrderedDict +from qapi import * +import sys +import os +import getopt + +def generate_visit_struct_body(field_prefix, members): +ret = +if len(field_prefix): +field_prefix = field_prefix + . +for argname, argentry, optional, structured in parse_args(members): +if optional: +ret += mcgen(''' +visit_start_optional(m, (obj *obj) ? (*obj)-%(c_prefix)shas_%(c_name)s : NULL, %(name)s, errp); +if ((*obj)-%(prefix)shas_%(c_name)s) { +''', + c_prefix=c_var(field_prefix), prefix=field_prefix, + c_name=c_var(argname), name=argname) +push_indent() + +if structured: +ret += mcgen(''' +visit_start_struct(m, NULL, , %(name)s, 0, errp); +''', + name=argname) +ret += generate_visit_struct_body(field_prefix + argname, argentry) +ret += mcgen(''' +visit_end_struct(m, errp); +''') +else: +ret += mcgen(''' +visit_type_%(type)s(m, (obj *obj) ? (*obj)-%(c_prefix)s%(c_name)s : NULL, %(name)s, errp); +''', + c_prefix=c_var(field_prefix), prefix=field_prefix, + type=type_name(argentry), c_name=c_var(argname), + name=argname) + +if optional: +pop_indent() +ret += mcgen(''' +} +visit_end_optional(m, errp); +''') +return ret + +def generate_visit_struct(name, members): +ret = mcgen(''' + +void visit_type_%(name)s(Visitor *m, %(name)s ** obj, const char *name, Error **errp) +{ +visit_start_struct(m, (void **)obj, %(name)s, name, sizeof(%(name)s), errp); +''', +name=name) +push_indent() +ret += generate_visit_struct_body(, members) +pop_indent() + +ret += mcgen(''' +visit_end_struct(m, errp); +} +''') +return ret + +def generate_visit_list(name, members): +return mcgen(''' + +void visit_type_%(name)sList(Visitor *m, %(name)sList ** obj, const char *name, Error **errp) +{ +GenericList *i; + +visit_start_list(m, name, errp); + +for (i = visit_next_list(m, (GenericList **)obj, errp); i; i = visit_next_list(m, i, errp)) { +%(name)sList *native_i = (%(name)sList *)i; +visit_type_%(name)s(m, native_i-value, NULL, errp); +} + +visit_end_list(m, errp); +} +''', +name=name) + +def generate_visit_enum(name, members): +return mcgen(''' + +void visit_type_%(name)s(Visitor *m, %(name)s * obj, const char *name, Error **errp) +{ +visit_type_enum(m, (int *)obj, %(name)s_lookup, %(name)s, name, errp); +} +''', + name=name) + +def generate_visit_union(name, members): +ret = generate_visit_enum('%sKind' % name, members.keys()) + +ret += mcgen(''' + +void visit_type_%(name)s(Visitor *m, %(name)s ** obj, const char *name, Error **errp) +{ +} +''', + name=name) + +return ret + +def generate_declaration(name, members, genlist=True): +ret = mcgen(''' + +void visit_type_%(name)s(Visitor *m, %(name)s ** obj, const char *name, Error **errp); +''', +name=name) + +if genlist: +ret += mcgen(''' +void visit_type_%(name)sList(Visitor *m, %(name)sList ** obj, const char *name, Error **errp); +''', + name=name) + +return ret + +def generate_decl_enum(name, members, genlist=True): +return mcgen(''' + +void visit_type_%(name)s(Visitor *m, %(name)s * obj, const char *name, Error **errp); +''', +name=name) + +try: +opts, args = getopt.gnu_getopt(sys.argv[1:], p:o:, [prefix=, output-dir=]) +except getopt.GetoptError, err: +print str(err) +sys.exit(1)
[Qemu-devel] [QAPI+QGA 2/3] QAPI code generation infrastructure v6
This is Set 2/3 of the QAPI+QGA patchsets. These patches apply on top of master (set1 merged), and can also be obtained from: git://repo.or.cz/qemu/mdroth.git qapi-backport-set2-v6 (Set1+2 are a backport of some of the QAPI-related work from Anthony's glib tree. The main goal is to get the basic code generation infrastructure in place so that it can be used by the guest agent to implement a QMP-like guest interface, and so that future work regarding the QMP conversion to QAPI can be decoupled from the infrastructure bits. Set3 is the Qemu Guest Agent (virtagent), rebased on the new code QAPI code generation infrastructure. This is the first user of QAPI, QMP will follow.) ___ This patchset introduces the following: - Hard dependency on GLib. This has been floating around the list for a while. Currently the only users are the unit tests for this patchset and the guest agent. We can make both of these a configure option, but based on previous discussions a hard dependency will likely be introduced with subsequent QAPI patches. - A couple additional qlist utility functions used by QAPI. - QAPI schema-based code generation for synchronous QMP/QGA commands and types, and Visitor/dispatch infrastructure to handle marshaling/unmarshaling/dispatch between QAPI and the QMP/QGA wire protocols. - Documentation and unit tests for visitor functions and synchronous command/type generation. CHANGES SINCE V5: - Enums are now represented as stringified constants on the wire instead of integers - QObjects passed in to qmp_input_visitor_new() are now qobject_incref()'d, and qobject_decref()'d in qmp_input_visitor_cleanup() - Whitespace fixes - Fixed incorrect email addr in generated copyright headers CHANGES SINCE V4: - Fix segfault in output visitor when dealing with QAPI-defined C structures with NULL pointers CHANGES SINCE V3: - Added copyright headers for generated code and remaining files - Added checking for required/extra parameters in top-level of QMP QObject - Made QDict arg to input visitor constructor a const - Renamed qmp_dispatch_err() - do_qmp_dispatch() - Changed QERR_QAPI_STACK_OVERRUN to QERR_BUFFER_OVERRUN - Moved configure changes to create QAPI directory when using a different build root to first patch which uses it. - Squashed Makefile changes for test-visitor/test-qmp-commands into single commits - Removed redundant NULL checks for qemu_free() in dealloc visitor CHANGES SINCE V2: - Added cleanup functions for input/output visitor types and fixed a leak in dispatch path. - Corrected spelling from visiter-visitor and updated filenames accordingly. - Re-organized patches so that each new C file can be built as part of the introducting commit (for instances where there were no users of the qapi-obj-y target yet a test build was done by adding the target as a superficial dependency on other tools), and moved code generator patches after the required dependencies. - Made qlist_first/qlist_next accept/return const types. - Moved Visitor interface inline wrapper functions to real ones. - Fixed error-reporting for invalid parameters when parameter name is null. - Removed hard-coded size for QAPI-type allocations done by the input visitor, using generated code to pass in a sizeof() now. - Replaced assert()'s on visitor stack overruns, replaced with an error indication. - Fixed build issue when using a separate build directory. - Added missing copyright headers for scripts, moved external code in ordereddict.py to a seperate patch. - Many thanks to Luiz, Anthony, and everyone else for the excellent review/testing. CHANGES SINCE V1: - Fixed build issue that was missed due to deprecated files being present in source tree. Thanks to Matsuda Daiki for sending fixes. - Fixed grammatical errors in documentation pointed out by Luiz. - Added generated code to the make clean target. CHANGES SINCE V0 (QAPI Infrastructure Round 1): - Fixed known memory leaks in generated code - Stricter error-handling in generated code - Removed currently unused code (generators for events and async/proxied QMP/QGA commands and definition used by the not-yet-introduced QMP server replacement) - Added documentation for code generation scripts/schemas/usage - Addressed review comments from Luiz and Stefan Makefile| 26 +++- Makefile.objs |9 + Makefile.target |1 + configure | 14 ++ docs/qapi-code-gen.txt | 316 +++ module.h|2 + qapi-schema-test.json | 22 +++ qapi/qapi-dealloc-visitor.c | 147 + qapi/qapi-dealloc-visitor.h | 26 +++ qapi/qapi-types-core.h | 20 +++ qapi/qapi-visit-core.c | 118 + qapi/qapi-visit-core.h | 76 + qapi/qmp-core.h | 41 + qapi/qmp-dispatch.c | 124 ++
[Qemu-devel] [PATCH v6 15/18] qapi: test schema used for unit tests
This is how QMP commands/parameters/types would be defined. We use a subset of that functionality here to implement functions/types for unit testing. Signed-off-by: Michael Roth mdr...@linux.vnet.ibm.com --- qapi-schema-test.json | 22 ++ 1 files changed, 22 insertions(+), 0 deletions(-) create mode 100644 qapi-schema-test.json diff --git a/qapi-schema-test.json b/qapi-schema-test.json new file mode 100644 index 000..3acedad --- /dev/null +++ b/qapi-schema-test.json @@ -0,0 +1,22 @@ +# *-*- Mode: Python -*-* + +# for testing enums +{ 'enum': 'EnumOne', + 'data': [ 'value1', 'value2', 'value3' ] } +{ 'type': 'NestedEnumsOne', + 'data': { 'enum1': 'EnumOne', '*enum2': 'EnumOne', 'enum3': 'EnumOne', '*enum4': 'EnumOne' } } + +# for testing nested structs +{ 'type': 'UserDefOne', + 'data': { 'integer': 'int', 'string': 'str' } } + +{ 'type': 'UserDefTwo', + 'data': { 'string': 'str', +'dict': { 'string': 'str', + 'dict': { 'userdef': 'UserDefOne', 'string': 'str' }, + '*dict2': { 'userdef': 'UserDefOne', 'string': 'str' } } } } + +# testing commands +{ 'command': 'user_def_cmd', 'data': {} } +{ 'command': 'user_def_cmd1', 'data': {'ud1a': 'UserDefOne'} } +{ 'command': 'user_def_cmd2', 'data': {'ud1a': 'UserDefOne', 'ud1b': 'UserDefOne'}, 'returns': 'UserDefTwo' } -- 1.7.0.4
[Qemu-devel] [PATCH v6 09/18] qapi: add QMP dispatch functions
Given an object recieved via QMP, this code uses the dispatch table provided by qmp_registry.c to call the corresponding marshalling/dispatch function and format return values/errors for delivery to the QMP. Currently only synchronous QMP functions are supported, but this will also be used for async QMP functions and QMP guest proxy dispatch as well. Signed-off-by: Michael Roth mdr...@linux.vnet.ibm.com --- Makefile.objs |2 +- qapi/qmp-core.h |1 + qapi/qmp-dispatch.c | 124 +++ 3 files changed, 126 insertions(+), 1 deletions(-) create mode 100644 qapi/qmp-dispatch.c diff --git a/Makefile.objs b/Makefile.objs index 55a94e4..d7c4cec 100644 --- a/Makefile.objs +++ b/Makefile.objs @@ -376,7 +376,7 @@ libcacard-y = cac.o event.o vcard.o vreader.o vcard_emul_nss.o vcard_emul_type.o # qapi qapi-nested-y = qapi-visit-core.o qmp-input-visitor.o qmp-output-visitor.o qapi-dealloc-visitor.o -qapi-nested-y += qmp-registry.o +qapi-nested-y += qmp-registry.o qmp-dispatch.o qapi-obj-y = $(addprefix qapi/, $(qapi-nested-y)) vl.o: QEMU_CFLAGS+=$(GPROF_CFLAGS) diff --git a/qapi/qmp-core.h b/qapi/qmp-core.h index 99e929f..f1c26e4 100644 --- a/qapi/qmp-core.h +++ b/qapi/qmp-core.h @@ -35,6 +35,7 @@ typedef struct QmpCommand void qmp_register_command(const char *name, QmpCommandFunc *fn); QmpCommand *qmp_find_command(const char *name); +QObject *qmp_dispatch(QObject *request); #endif diff --git a/qapi/qmp-dispatch.c b/qapi/qmp-dispatch.c new file mode 100644 index 000..5584693 --- /dev/null +++ b/qapi/qmp-dispatch.c @@ -0,0 +1,124 @@ +/* + * Core Definitions for QAPI/QMP Dispatch + * + * Copyright IBM, Corp. 2011 + * + * Authors: + * Anthony Liguori aligu...@us.ibm.com + * + * This work is licensed under the terms of the GNU LGPL, version 2.1 or later. + * See the COPYING.LIB file in the top-level directory. + * + */ + +#include qemu-objects.h +#include qapi/qmp-core.h +#include json-parser.h +#include error.h +#include error_int.h +#include qerror.h + +static QDict *qmp_dispatch_check_obj(const QObject *request, Error **errp) +{ +const QDictEntry *ent; +const char *arg_name; +const QObject *arg_obj; +bool has_exec_key = false; +QDict *dict = NULL; + +if (qobject_type(request) != QTYPE_QDICT) { +error_set(errp, QERR_QMP_BAD_INPUT_OBJECT, + request is not a dictionary); +return NULL; +} + +dict = qobject_to_qdict(request); + +for (ent = qdict_first(dict); ent; + ent = qdict_next(dict, ent)) { +arg_name = qdict_entry_key(ent); +arg_obj = qdict_entry_value(ent); + +if (!strcmp(arg_name, execute)) { +if (qobject_type(arg_obj) != QTYPE_QSTRING) { +error_set(errp, QERR_QMP_BAD_INPUT_OBJECT_MEMBER, execute, + string); +return NULL; +} +has_exec_key = true; +} else if (strcmp(arg_name, arguments)) { +error_set(errp, QERR_QMP_EXTRA_MEMBER, arg_name); +return NULL; +} +} + +if (!has_exec_key) { +error_set(errp, QERR_QMP_BAD_INPUT_OBJECT, execute); +return NULL; +} + +return dict; +} + +static QObject *do_qmp_dispatch(QObject *request, Error **errp) +{ +const char *command; +QDict *args, *dict; +QmpCommand *cmd; +QObject *ret = NULL; + + +dict = qmp_dispatch_check_obj(request, errp); +if (!dict || error_is_set(errp)) { +return NULL; +} + +command = qdict_get_str(dict, execute); +cmd = qmp_find_command(command); +if (cmd == NULL) { +error_set(errp, QERR_COMMAND_NOT_FOUND, command); +return NULL; +} + +if (!qdict_haskey(dict, arguments)) { +args = qdict_new(); +} else { +args = qdict_get_qdict(dict, arguments); +QINCREF(args); +} + +switch (cmd-type) { +case QCT_NORMAL: +cmd-fn(args, ret, errp); +if (!error_is_set(errp) ret == NULL) { +ret = QOBJECT(qdict_new()); +} +break; +} + +QDECREF(args); + +return ret; +} + +QObject *qmp_dispatch(QObject *request) +{ +Error *err = NULL; +QObject *ret; +QDict *rsp; + +ret = do_qmp_dispatch(request, err); + +rsp = qdict_new(); +if (err) { +qdict_put_obj(rsp, error, error_get_qobject(err)); +error_free(err); +} else if (ret) { +qdict_put_obj(rsp, return, ret); +} else { +QDECREF(rsp); +return NULL; +} + +return QOBJECT(rsp); +} -- 1.7.0.4
[Qemu-devel] [PATCH v6 12/18] qapi: add qapi-types.py code generator
This is the code generator for qapi types. It will generation the following files: $(prefix)qapi-types.h - C types corresponding to types defined in the schema you pass in $(prefix)qapi-types.c - Cleanup functions for the above C types The $(prefix) is used to as a namespace to keep the generated code from one schema/code-generation separated from others so code and be generated from multiple schemas with clobbering previously created code. Signed-off-by: Michael Roth mdr...@linux.vnet.ibm.com --- scripts/qapi-types.py | 267 + 1 files changed, 267 insertions(+), 0 deletions(-) create mode 100644 scripts/qapi-types.py diff --git a/scripts/qapi-types.py b/scripts/qapi-types.py new file mode 100644 index 000..ab47286 --- /dev/null +++ b/scripts/qapi-types.py @@ -0,0 +1,267 @@ +# +# QAPI types generator +# +# Copyright IBM, Corp. 2011 +# +# Authors: +# Anthony Liguori aligu...@us.ibm.com +# +# This work is licensed under the terms of the GNU GPLv2. +# See the COPYING.LIB file in the top-level directory. + +from ordereddict import OrderedDict +from qapi import * +import sys +import os +import getopt + +def generate_fwd_struct(name, members): +return mcgen(''' +typedef struct %(name)s %(name)s; + +typedef struct %(name)sList +{ +%(name)s *value; +struct %(name)sList *next; +} %(name)sList; +''', + name=name) + +def generate_struct(structname, fieldname, members): +ret = mcgen(''' +struct %(name)s +{ +''', + name=structname) + +for argname, argentry, optional, structured in parse_args(members): +if optional: +ret += mcgen(''' +bool has_%(c_name)s; +''', + c_name=c_var(argname)) +if structured: +push_indent() +ret += generate_struct(, argname, argentry) +pop_indent() +else: +ret += mcgen(''' +%(c_type)s %(c_name)s; +''', + c_type=c_type(argentry), c_name=c_var(argname)) + +if len(fieldname): +fieldname = + fieldname +ret += mcgen(''' +}%(field)s; +''', +field=fieldname) + +return ret + +def generate_enum_lookup(name, values): +ret = mcgen(''' +const char *%(name)s_lookup[] = { +''', + name=name) +i = 0 +for value in values: +ret += mcgen(''' +%(abbrev)s_%(value)s, +''', + abbrev=de_camel_case(name).upper(), + value=c_var(value).upper()) + +ret += mcgen(''' +NULL, +}; + +''') +return ret + +def generate_enum(name, values): +lookup_decl = mcgen(''' +extern const char *%(name)s_lookup[]; +''', +name=name) + +enum_decl = mcgen(''' +typedef enum %(name)s +{ +''', +name=name) + +i = 0 +for value in values: +enum_decl += mcgen(''' +%(abbrev)s_%(value)s = %(i)d, +''', + abbrev=de_camel_case(name).upper(), + value=c_var(value).upper(), + i=i) +i += 1 + +enum_decl += mcgen(''' +} %(name)s; +''', + name=name) + +return lookup_decl + enum_decl + +def generate_union(name, typeinfo): +ret = mcgen(''' +struct %(name)s +{ +%(name)sKind kind; +union { +''', +name=name) + +for key in typeinfo: +ret += mcgen(''' +%(c_type)s %(c_name)s; +''', + c_type=c_type(typeinfo[key]), + c_name=c_var(key)) + +ret += mcgen(''' +}; +}; +''') + +return ret + +def generate_type_cleanup_decl(name): +ret = mcgen(''' +void qapi_free_%(type)s(%(c_type)s obj); +''', +c_type=c_type(name),type=name) +return ret + +def generate_type_cleanup(name): +ret = mcgen(''' +void qapi_free_%(type)s(%(c_type)s obj) +{ +QapiDeallocVisitor *md; +Visitor *v; + +if (!obj) { +return; +} + +md = qapi_dealloc_visitor_new(); +v = qapi_dealloc_get_visitor(md); +visit_type_%(type)s(v, obj, NULL, NULL); +qapi_dealloc_visitor_cleanup(md); +} +''', +c_type=c_type(name),type=name) +return ret + + +try: +opts, args = getopt.gnu_getopt(sys.argv[1:], p:o:, [prefix=, output-dir=]) +except getopt.GetoptError, err: +print str(err) +sys.exit(1) + +output_dir = +prefix = +c_file = 'qapi-types.c' +h_file = 'qapi-types.h' + +for o, a in opts: +if o in (-p, --prefix): +prefix = a +elif o in (-o, --output-dir): +output_dir = a + / + +c_file = output_dir + prefix + c_file +h_file = output_dir + prefix + h_file + +if os.path.isdir(output_dir) == False: +os.makedirs(output_dir) + +fdef = open(c_file, 'w') +fdecl = open(h_file, 'w') + +fdef.write(mcgen(''' +/* AUTOMATICALLY GENERATED, DO NOT MODIFY */ + +/* + * deallocation functions for schema-defined QAPI types + * + * Copyright IBM, Corp. 2011 + * + * Authors: + *
[Qemu-devel] [PATCH v6 16/18] qapi: add test-visitor, tests for gen. visitor code
Signed-off-by: Michael Roth mdr...@linux.vnet.ibm.com --- Makefile | 18 +++- test-visitor.c | 306 2 files changed, 322 insertions(+), 2 deletions(-) create mode 100644 test-visitor.c diff --git a/Makefile b/Makefile index 42ae4e5..a243c24 100644 --- a/Makefile +++ b/Makefile @@ -162,6 +162,19 @@ check-qlist: check-qlist.o qlist.o qint.o $(CHECK_PROG_DEPS) check-qfloat: check-qfloat.o qfloat.o $(CHECK_PROG_DEPS) check-qjson: check-qjson.o qfloat.o qint.o qdict.o qstring.o qlist.o qbool.o qjson.o json-streamer.o json-lexer.o json-parser.o error.o qerror.o qemu-error.o $(CHECK_PROG_DEPS) +qapi-dir := qapi-generated +$(qapi-obj-y) test-visitor.o: QEMU_CFLAGS += -I $(qapi-dir) + +$(qapi-dir)/test-qapi-types.c: $(qapi-dir)/test-qapi-types.h +$(qapi-dir)/test-qapi-types.h: $(SRC_PATH)/qapi-schema-test.json $(SRC_PATH)/scripts/qapi-types.py + $(call quiet-command,python $(SRC_PATH)/scripts/qapi-types.py -o $(qapi-dir) -p test- $, GEN $@) +$(qapi-dir)/test-qapi-visit.c: $(qapi-dir)/test-qapi-visit.h +$(qapi-dir)/test-qapi-visit.h: $(SRC_PATH)/qapi-schema-test.json $(SRC_PATH)/scripts/qapi-visit.py + $(call quiet-command,python $(SRC_PATH)/scripts/qapi-visit.py -o $(qapi-dir) -p test- $, GEN $@) + +test-visitor.o: $(addprefix $(qapi-dir)/, test-qapi-types.c test-qapi-types.h test-qapi-visit.c test-qapi-visit.h) +test-visitor: test-visitor.o qfloat.o qint.o qdict.o qstring.o qlist.o qbool.o $(qapi-obj-y) error.o osdep.o qemu-malloc.o $(oslib-obj-y) qjson.o json-streamer.o json-lexer.o json-parser.o qerror.o qemu-error.o qemu-tool.o $(qapi-dir)/test-qapi-visit.o $(qapi-dir)/test-qapi-types.o + QEMULIBS=libhw32 libhw64 libuser libdis libdis-user clean: @@ -170,11 +183,12 @@ clean: rm -f qemu-options.def rm -f *.o *.d *.a *.lo $(TOOLS) TAGS cscope.* *.pod *~ */*~ rm -Rf .libs - rm -f slirp/*.o slirp/*.d audio/*.o audio/*.d block/*.o block/*.d net/*.o net/*.d fsdev/*.o fsdev/*.d ui/*.o ui/*.d + rm -f slirp/*.o slirp/*.d audio/*.o audio/*.d block/*.o block/*.d net/*.o net/*.d fsdev/*.o fsdev/*.d ui/*.o ui/*.d qapi/*.o qapi/*.d rm -f qemu-img-cmds.h rm -f trace.c trace.h trace.c-timestamp trace.h-timestamp rm -f trace-dtrace.dtrace trace-dtrace.dtrace-timestamp rm -f trace-dtrace.h trace-dtrace.h-timestamp + rm -rf $(qapi-dir) $(MAKE) -C tests clean for d in $(ALL_SUBDIRS) $(QEMULIBS) libcacard; do \ if test -d $$d; then $(MAKE) -C $$d $@ || exit 1; fi; \ @@ -363,4 +377,4 @@ tarbin: $(mandir)/man8/qemu-nbd.8 # Include automatically generated dependency files --include $(wildcard *.d audio/*.d slirp/*.d block/*.d net/*.d ui/*.d) +-include $(wildcard *.d audio/*.d slirp/*.d block/*.d net/*.d ui/*.d qapi/*.d) diff --git a/test-visitor.c b/test-visitor.c new file mode 100644 index 000..787a100 --- /dev/null +++ b/test-visitor.c @@ -0,0 +1,306 @@ +#include glib.h +#include qapi/qmp-output-visitor.h +#include qapi/qmp-input-visitor.h +#include test-qapi-types.h +#include test-qapi-visit.h +#include qemu-objects.h + +typedef struct TestStruct +{ +int64_t x; +int64_t y; +} TestStruct; + +typedef struct TestStructList +{ +TestStruct *value; +struct TestStructList *next; +} TestStructList; + +static void visit_type_TestStruct(Visitor *v, TestStruct **obj, const char *name, Error **errp) +{ +visit_start_struct(v, (void **)obj, TestStruct, name, sizeof(TestStruct), errp); +visit_type_int(v, (*obj)-x, x, errp); +visit_type_int(v, (*obj)-y, y, errp); +visit_end_struct(v, errp); +} + +static void visit_type_TestStructList(Visitor *m, TestStructList ** obj, const char *name, Error **errp) +{ +GenericList *i; + +visit_start_list(m, name, errp); + +for (i = visit_next_list(m, (GenericList **)obj, errp); i; i = visit_next_list(m, i, errp)) { +TestStructList *native_i = (TestStructList *)i; +visit_type_TestStruct(m, native_i-value, NULL, errp); +} + +visit_end_list(m, errp); +} + +/* test core visitor methods */ +static void test_visitor_core(void) +{ +QmpOutputVisitor *mo; +QmpInputVisitor *mi; +Visitor *v; +TestStruct ts = { 42, 82 }; +TestStruct *pts = ts; +TestStructList *lts = NULL; +Error *err = NULL; +QObject *obj; +QString *str; +int64_t value = 0; + +mo = qmp_output_visitor_new(); +v = qmp_output_get_visitor(mo); + +visit_type_TestStruct(v, pts, NULL, err); + +obj = qmp_output_get_qobject(mo); + +str = qobject_to_json(obj); + +printf(%s\n, qstring_get_str(str)); + +QDECREF(str); + +obj = QOBJECT(qint_from_int(0x42)); + +mi = qmp_input_visitor_new(obj); +v = qmp_input_get_visitor(mi); + +visit_type_int(v, value, NULL, err); +if (err) { +g_error(%s, error_get_pretty(err)); +} + +g_assert(value == 0x42); + +qobject_decref(obj); + +
[Qemu-devel] [PATCH v6 11/18] qapi: add qapi.py helper libraries
Signed-off-by: Michael Roth mdr...@linux.vnet.ibm.com --- scripts/qapi.py | 203 +++ 1 files changed, 203 insertions(+), 0 deletions(-) create mode 100644 scripts/qapi.py diff --git a/scripts/qapi.py b/scripts/qapi.py new file mode 100644 index 000..56af232 --- /dev/null +++ b/scripts/qapi.py @@ -0,0 +1,203 @@ +# +# QAPI helper library +# +# Copyright IBM, Corp. 2011 +# +# Authors: +# Anthony Liguori aligu...@us.ibm.com +# +# This work is licensed under the terms of the GNU GPLv2. +# See the COPYING.LIB file in the top-level directory. + +from ordereddict import OrderedDict + +def tokenize(data): +while len(data): +if data[0] in ['{', '}', ':', ',', '[', ']']: +yield data[0] +data = data[1:] +elif data[0] in ' \n': +data = data[1:] +elif data[0] == ': +data = data[1:] +string = '' +while data[0] != ': +string += data[0] +data = data[1:] +data = data[1:] +yield string + +def parse(tokens): +if tokens[0] == '{': +ret = OrderedDict() +tokens = tokens[1:] +while tokens[0] != '}': +key = tokens[0] +tokens = tokens[1:] + +tokens = tokens[1:] # : + +value, tokens = parse(tokens) + +if tokens[0] == ',': +tokens = tokens[1:] + +ret[key] = value +tokens = tokens[1:] +return ret, tokens +elif tokens[0] == '[': +ret = [] +tokens = tokens[1:] +while tokens[0] != ']': +value, tokens = parse(tokens) +if tokens[0] == ',': +tokens = tokens[1:] +ret.append(value) +tokens = tokens[1:] +return ret, tokens +else: +return tokens[0], tokens[1:] + +def evaluate(string): +return parse(map(lambda x: x, tokenize(string)))[0] + +def parse_schema(fp): +exprs = [] +expr = '' +expr_eval = None + +for line in fp: +if line.startswith('#') or line == '\n': +continue + +if line.startswith(' '): +expr += line +elif expr: +expr_eval = evaluate(expr) +if expr_eval.has_key('enum'): +add_enum(expr_eval['enum']) +elif expr_eval.has_key('union'): +add_enum('%sKind' % expr_eval['union']) +exprs.append(expr_eval) +expr = line +else: +expr += line + +if expr: +expr_eval = evaluate(expr) +if expr_eval.has_key('enum'): +add_enum(expr_eval['enum']) +elif expr_eval.has_key('union'): +add_enum('%sKind' % expr_eval['union']) +exprs.append(expr_eval) + +return exprs + +def parse_args(typeinfo): +for member in typeinfo: +argname = member +argentry = typeinfo[member] +optional = False +structured = False +if member.startswith('*'): +argname = member[1:] +optional = True +if isinstance(argentry, OrderedDict): +structured = True +yield (argname, argentry, optional, structured) + +def de_camel_case(name): +new_name = '' +for ch in name: +if ch.isupper() and new_name: +new_name += '_' +if ch == '-': +new_name += '_' +else: +new_name += ch.lower() +return new_name + +def camel_case(name): +new_name = '' +first = True +for ch in name: +if ch in ['_', '-']: +first = True +elif first: +new_name += ch.upper() +first = False +else: +new_name += ch.lower() +return new_name + +def c_var(name): +return '_'.join(name.split('-')).lstrip(*) + +def c_list_type(name): +return '%sList' % name + +def type_name(name): +if type(name) == list: +return c_list_type(name[0]) +return name + +enum_types = [] + +def add_enum(name): +global enum_types +enum_types.append(name) + +def is_enum(name): +global enum_types +return (name in enum_types) + +def c_type(name): +if name == 'str': +return 'char *' +elif name == 'int': +return 'int64_t' +elif name == 'bool': +return 'bool' +elif name == 'number': +return 'double' +elif type(name) == list: +return '%s *' % c_list_type(name[0]) +elif is_enum(name): +return name +elif name == None or len(name) == 0: +return 'void' +elif name == name.upper(): +return '%sEvent *' % camel_case(name) +else: +return '%s *' % name + +def genindent(count): +ret = +for i in range(count): +ret += +return ret + +indent_level = 0 + +def push_indent(indent_amount=4): +global indent_level +indent_level += indent_amount + +def
[Qemu-devel] [PATCH v6 14/18] qapi: add qapi-commands.py code generator
This is the code generator for qapi command marshaling/dispatch. Currently only generators for synchronous qapi/qmp functions are supported. This script generates the following files: $(prefix)qmp-marshal.c: command marshal/dispatch functions for each QMP command defined in the schema. Functions generated by qapi-visit.py are used to convert qobjects recieved from the wire into function parameters, and uses the same visiter functions to convert native C return values to qobjects from transmission back over the wire. $(prefix)qmp-commands.h: Function prototypes for the QMP commands specified in the schema. $(prefix) is used in the same manner as with qapi-types.py Signed-off-by: Michael Roth mdr...@linux.vnet.ibm.com --- scripts/qapi-commands.py | 381 ++ 1 files changed, 381 insertions(+), 0 deletions(-) create mode 100644 scripts/qapi-commands.py diff --git a/scripts/qapi-commands.py b/scripts/qapi-commands.py new file mode 100644 index 000..5c06bfa --- /dev/null +++ b/scripts/qapi-commands.py @@ -0,0 +1,381 @@ +# +# QAPI command marshaller generator +# +# Copyright IBM, Corp. 2011 +# +# Authors: +# Anthony Liguori aligu...@us.ibm.com +# Michael Rothmdr...@linux.vnet.ibm.com +# +# This work is licensed under the terms of the GNU GPLv2. +# See the COPYING.LIB file in the top-level directory. + +from ordereddict import OrderedDict +from qapi import * +import sys +import os +import getopt + +def generate_decl_enum(name, members, genlist=True): +return mcgen(''' + +void visit_type_%(name)s(Visitor *m, %(name)s * obj, const char *name, Error **errp); +''', +name=name) + +def generate_command_decl(name, args, ret_type): +arglist= +for argname, argtype, optional, structured in parse_args(args): +argtype = c_type(argtype) +if argtype == char *: +argtype = const char * +if optional: +arglist += bool has_%s, % c_var(argname) +arglist += %s %s, % (argtype, c_var(argname)) +return mcgen(''' +%(ret_type)s qmp_%(name)s(%(args)sError **errp); +''', + ret_type=c_type(ret_type), name=c_var(name), args=arglist).strip() + +def gen_sync_call(name, args, ret_type, indent=0): +ret = +arglist= +retval= +if ret_type: +retval = retval = +for argname, argtype, optional, structured in parse_args(args): +if optional: +arglist += has_%s, % c_var(argname) +arglist += %s, % (c_var(argname)) +push_indent(indent) +ret = mcgen(''' +%(retval)sqmp_%(name)s(%(args)serrp); + +''', +name=c_var(name), args=arglist, retval=retval).rstrip() +if ret_type: +ret += \n + mcgen( +%(marshal_output_call)s +''', +marshal_output_call=gen_marshal_output_call(name, ret_type)).rstrip() +pop_indent(indent) +return ret.rstrip() + + +def gen_marshal_output_call(name, ret_type): +if not ret_type: +return +return qmp_marshal_output_%s(retval, ret, errp); % c_var(name) + +def gen_visitor_output_containers_decl(ret_type): +ret = +push_indent() +if ret_type: +ret += mcgen(''' +QmpOutputVisitor *mo; +QapiDeallocVisitor *md; +Visitor *v; +''') +pop_indent() + +return ret + +def gen_visitor_input_containers_decl(args): +ret = + +push_indent() +if len(args) 0: +ret += mcgen(''' +QmpInputVisitor *mi; +QapiDeallocVisitor *md; +Visitor *v; +''') +pop_indent() + +return ret.rstrip() + +def gen_visitor_input_vars_decl(args): +ret = +push_indent() +for argname, argtype, optional, structured in parse_args(args): +if optional: +ret += mcgen(''' +bool has_%(argname)s = false; +''', + argname=c_var(argname)) +if c_type(argtype).endswith(*): +ret += mcgen(''' +%(argtype)s %(argname)s = NULL; +''', + argname=c_var(argname), argtype=c_type(argtype)) +else: +ret += mcgen(''' +%(argtype)s %(argname)s; +''', + argname=c_var(argname), argtype=c_type(argtype)) + +pop_indent() +return ret.rstrip() + +def gen_visitor_input_block(args, obj, dealloc=False): +ret = +if len(args) == 0: +return ret + +push_indent() + +if dealloc: +ret += mcgen(''' +md = qapi_dealloc_visitor_new(); +v = qapi_dealloc_get_visitor(md); +''') +else: +ret += mcgen(''' +mi = qmp_input_visitor_new(%(obj)s); +v = qmp_input_get_visitor(mi); +''', + obj=obj) + +for argname, argtype, optional, structured in parse_args(args): +if optional: +ret += mcgen(''' +visit_start_optional(v, has_%(c_name)s,
[Qemu-devel] [PATCH v6 17/18] qapi: add test-qmp-commands, tests for gen. marshalling/dispatch code
Signed-off-by: Michael Roth mdr...@linux.vnet.ibm.com --- Makefile|8 +++- test-qmp-commands.c | 113 +++ 2 files changed, 120 insertions(+), 1 deletions(-) create mode 100644 test-qmp-commands.c diff --git a/Makefile b/Makefile index a243c24..cbd2d77 100644 --- a/Makefile +++ b/Makefile @@ -163,7 +163,7 @@ check-qfloat: check-qfloat.o qfloat.o $(CHECK_PROG_DEPS) check-qjson: check-qjson.o qfloat.o qint.o qdict.o qstring.o qlist.o qbool.o qjson.o json-streamer.o json-lexer.o json-parser.o error.o qerror.o qemu-error.o $(CHECK_PROG_DEPS) qapi-dir := qapi-generated -$(qapi-obj-y) test-visitor.o: QEMU_CFLAGS += -I $(qapi-dir) +$(qapi-obj-y) test-visitor.o test-qmp-commands.o: QEMU_CFLAGS += -I $(qapi-dir) $(qapi-dir)/test-qapi-types.c: $(qapi-dir)/test-qapi-types.h $(qapi-dir)/test-qapi-types.h: $(SRC_PATH)/qapi-schema-test.json $(SRC_PATH)/scripts/qapi-types.py @@ -171,10 +171,16 @@ $(qapi-dir)/test-qapi-types.h: $(SRC_PATH)/qapi-schema-test.json $(SRC_PATH)/scr $(qapi-dir)/test-qapi-visit.c: $(qapi-dir)/test-qapi-visit.h $(qapi-dir)/test-qapi-visit.h: $(SRC_PATH)/qapi-schema-test.json $(SRC_PATH)/scripts/qapi-visit.py $(call quiet-command,python $(SRC_PATH)/scripts/qapi-visit.py -o $(qapi-dir) -p test- $, GEN $@) +$(qapi-dir)/test-qmp-commands.h: $(qapi-dir)/test-qmp-marshal.c +$(qapi-dir)/test-qmp-marshal.c: $(SRC_PATH)/qapi-schema-test.json $(SRC_PATH)/scripts/qapi-commands.py + $(call quiet-command,python $(SRC_PATH)/scripts/qapi-commands.py -o $(qapi-dir) -p test- $, GEN $@) test-visitor.o: $(addprefix $(qapi-dir)/, test-qapi-types.c test-qapi-types.h test-qapi-visit.c test-qapi-visit.h) test-visitor: test-visitor.o qfloat.o qint.o qdict.o qstring.o qlist.o qbool.o $(qapi-obj-y) error.o osdep.o qemu-malloc.o $(oslib-obj-y) qjson.o json-streamer.o json-lexer.o json-parser.o qerror.o qemu-error.o qemu-tool.o $(qapi-dir)/test-qapi-visit.o $(qapi-dir)/test-qapi-types.o +test-qmp-commands.o: $(addprefix $(qapi-dir)/, test-qapi-types.c test-qapi-types.h test-qapi-visit.c test-qapi-visit.h test-qmp-marshal.c test-qmp-commands.h) +test-qmp-commands: test-qmp-commands.o qfloat.o qint.o qdict.o qstring.o qlist.o qbool.o $(qapi-obj-y) error.o osdep.o qemu-malloc.o $(oslib-obj-y) qjson.o json-streamer.o json-lexer.o json-parser.o qerror.o qemu-error.o qemu-tool.o $(qapi-dir)/test-qapi-visit.o $(qapi-dir)/test-qapi-types.o $(qapi-dir)/test-qmp-marshal.o module.o + QEMULIBS=libhw32 libhw64 libuser libdis libdis-user clean: diff --git a/test-qmp-commands.c b/test-qmp-commands.c new file mode 100644 index 000..7752904 --- /dev/null +++ b/test-qmp-commands.c @@ -0,0 +1,113 @@ +#include glib.h +#include qemu-objects.h +#include test-qmp-commands.h +#include qapi/qmp-core.h +#include module.h + +void qmp_user_def_cmd(Error **errp) +{ +} + +void qmp_user_def_cmd1(UserDefOne * ud1, Error **errp) +{ +} + +UserDefTwo * qmp_user_def_cmd2(UserDefOne * ud1a, UserDefOne * ud1b, Error **errp) +{ +UserDefTwo *ret; +UserDefOne *ud1c = qemu_mallocz(sizeof(UserDefOne)); +UserDefOne *ud1d = qemu_mallocz(sizeof(UserDefOne)); + +ud1c-string = strdup(ud1a-string); +ud1c-integer = ud1a-integer; +ud1d-string = strdup(ud1b-string); +ud1d-integer = ud1b-integer; + +ret = qemu_mallocz(sizeof(UserDefTwo)); +ret-string = strdup(blah1); +ret-dict.string = strdup(blah2); +ret-dict.dict.userdef = ud1c; +ret-dict.dict.string = strdup(blah3); +ret-dict.has_dict2 = true; +ret-dict.dict2.userdef = ud1d; +ret-dict.dict2.string = strdup(blah4); + +return ret; +} + +/* test commands with no input and no return value */ +static void test_dispatch_cmd(void) +{ +QDict *req = qdict_new(); +QObject *resp; + +qdict_put_obj(req, execute, QOBJECT(qstring_from_str(user_def_cmd))); + +resp = qmp_dispatch(QOBJECT(req)); +assert(resp != NULL); +assert(!qdict_haskey(qobject_to_qdict(resp), error)); +g_print(\nresp: %s\n, qstring_get_str(qobject_to_json(resp))); + +qobject_decref(resp); +QDECREF(req); +} + +/* test commands that return an error due to invalid parameters */ +static void test_dispatch_cmd_error(void) +{ +QDict *req = qdict_new(); +QObject *resp; + +qdict_put_obj(req, execute, QOBJECT(qstring_from_str(user_def_cmd2))); + +resp = qmp_dispatch(QOBJECT(req)); +assert(resp != NULL); +assert(qdict_haskey(qobject_to_qdict(resp), error)); +g_print(\nresp: %s\n, qstring_get_str(qobject_to_json_pretty(resp))); + +qobject_decref(resp); +QDECREF(req); +} + +/* test commands that involve both input parameters and return values */ +static void test_dispatch_cmd_io(void) +{ +QDict *req = qdict_new(); +QDict *args = qdict_new(); +QDict *ud1a = qdict_new(); +QDict *ud1b = qdict_new(); +QObject *resp; + +qdict_put_obj(ud1a, integer, QOBJECT(qint_from_int(42))); +
[Qemu-devel] [PATCH v6 18/18] qapi: add QAPI code generation documentation
Signed-off-by: Michael Roth mdr...@linux.vnet.ibm.com --- docs/qapi-code-gen.txt | 316 1 files changed, 316 insertions(+), 0 deletions(-) create mode 100644 docs/qapi-code-gen.txt diff --git a/docs/qapi-code-gen.txt b/docs/qapi-code-gen.txt new file mode 100644 index 000..b7befb5 --- /dev/null +++ b/docs/qapi-code-gen.txt @@ -0,0 +1,316 @@ += How to use the QAPI code generator = + +* Note: as of this writing, QMP does not use QAPI. Eventually QMP +commands will be converted to use QAPI internally. The following +information describes QMP/QAPI as it will exist after the +conversion. + +QAPI is a native C API within QEMU which provides management-level +functionality to internal/external users. For external +users/processes, this interface is made available by a JSON-based +QEMU Monitor protocol that is provided by the QMP server. + +To map QMP-defined interfaces to the native C QAPI implementations, +a JSON-based schema is used to define types and function +signatures, and a set of scripts is used to generate types/signatures, +and marshaling/dispatch code. The QEMU Guest Agent also uses these +scripts, paired with a seperate schema, to generate +marshaling/dispatch code for the guest agent server running in the +guest. + +This document will describe how the schemas, scripts, and resulting +code is used. + + +== QMP/Guest agent schema == + +This file defines the types, commands, and events used by QMP. It should +fully describe the interface used by QMP. + +This file is designed to be loosely based on JSON although it's technically +executable Python. While dictionaries are used, they are parsed as +OrderedDicts so that ordering is preserved. + +There are two basic syntaxes used, type definitions and command definitions. + +The first syntax defines a type and is represented by a dictionary. There are +two kinds of types that are supported: complex user-defined types, and enums. + +A complex type is a dictionary containing a single key who's value is a +dictionary. This corresponds to a struct in C or an Object in JSON. An +example of a complex type is: + + { 'type': 'MyType', + 'data' { 'member1': 'str', 'member2': 'int', '*member3': 'str } } + +The use of '*' as a prefix to the name means the member is optional. Optional +members should always be added to the end of the dictionary to preserve +backwards compatibility. + +An enumeration type is a dictionary containing a single key who's value is a +list of strings. An example enumeration is: + + { 'enum': 'MyEnum', 'data': [ 'value1', 'value2', 'value3' ] } + +Generally speaking, complex types and enums should always use CamelCase for +the type names. + +Commands are defined by using a list containing three members. The first +member is the command name, the second member is a dictionary containing +arguments, and the third member is the return type. + +An example command is: + + { 'command': 'my-command', + 'data': { 'arg1': 'str', '*arg2': 'str' }, + 'returns': 'str' ] + +Command names should be all lower case with words separated by a hyphen. + + +== Code generation == + +Schemas are fed into 3 scripts to generate all the code/files that, paired +with the core QAPI libraries, comprise everything required to take JSON +commands read in by a QMP/guest agent server, unmarshal the arguments into +the underlying C types, call into the corresponding C function, and map the +response back to a QMP/guest agent response to be returned to the user. + +As an example, we'll use the following schema, which describes a single +complex user-defined type (which will produce a C struct, along with a list +node structure that can be used to chain together a list of such types in +case we want to accept/return a list of this type with a command), and a +command which takes that type as a parameter and returns the same type: + +mdroth@illuin:~/w/qemu2.git$ cat example-schema.json +{ 'type': 'UserDefOne', + 'data': { 'integer': 'int', 'string': 'str' } } + +{ 'command': 'my-command', + 'data':{'arg1': 'UserDefOne'}, + 'returns': 'UserDefOne' } +mdroth@illuin:~/w/qemu2.git$ + +=== scripts/qapi-types.py === + +Used to generate the C types defined by a schema. The following files are +created: + +$(prefix)qapi-types.h - C types corresponding to types defined in +the schema you pass in +$(prefix)qapi-types.c - Cleanup functions for the above C types + +The $(prefix) is an optional parameter used as a namespace to keep the +generated code from one schema/code-generation separated from others so code +can be generated/used from multiple schemas without clobbering previously +created code. + +Example: + +mdroth@illuin:~/w/qemu2.git$ python scripts/qapi-types.py \ + --output-dir=qapi-generated --prefix=example- example-schema.json +mdroth@illuin:~/w/qemu2.git$ cat qapi-generated/example-qapi-types.c +/* AUTOMATICALLY GENERATED, DO NOT
Re: [Qemu-devel] Loading ELF binaries with very high base addresses
That is what I am doing except that my binaries also don't have any data section and don't link against any libraries. The text section does start at 0x4000 but they get mapped at 0x1000 or similar location. I can also build binaries with low base addresses. When these basic ones are working I'll move on to figuring out softmmu for more complex (read: real world) binaries. Thanks for all the suggestions btw, really appreciate it. On Wed, Jul 13, 2011 at 3:02 AM, Richard Henderson r...@twiddle.net wrote: On 07/12/2011 01:58 PM, Prashant Vaibhav wrote: Yes, exactly what happened when loading a non-trivial binary. :-( Oh well. If you've got an ia64 cross-compiler, you could still make progress on qemu by building your own binaries and linking them somewhere convenient in the low 64 TB. r~
[Qemu-devel] buildbot failure in qemu on qmp_i386_debian_5_0
The Buildbot has detected a new failure on builder qmp_i386_debian_5_0 while building qemu. Full details are available at: http://buildbot.b1-systems.de/qemu/builders/qmp_i386_debian_5_0/builds/32 Buildbot URL: http://buildbot.b1-systems.de/qemu/ Buildslave for this Build: yuzuki Build Reason: The Nightly scheduler named 'nightly_qmp' triggered this build Build Source Stamp: [branch master] HEAD Blamelist: BUILD FAILED: failed git sincerely, -The Buildbot
Re: [Qemu-devel] PCI with Xilinx virtex-ml507 board
On Jul 11, 2011 15:31, Edgar E. Iglesias edgar.igles...@gmail.com wrote: Hi, The emulated board and fpga config doesnt have pci. It does have a xilinx ll-temac ethernet mac though. I have patches for that, its on my todo list to post them. Right now im on the road with little access to my stuff. It'll have to wait, sorry. If you dont need a particular mac, you could try to change the dtb and qemu to instantiate a xilinx ethlite mac which qemu upstream does emulate. I suggest looking at the microblaze boards as reference. Good luck, Edgar Hi Edgar, I'm trying to create Xilinx Ethernet Lite MAC. So, I have two question :d. What is the kernel driver that use for xilinx-ethlite nic? And what should I change the dts file? (Does remove Hard Ethernet Mac?) Please help me. Thank you. Tai
[Qemu-devel] [PATCH 0/4] SPARC64: Implement sparcv9 ldfa/stfa instructions
Hi, This patch series implements sparcv9 stfa/ldfa instructions with non block-transfer ASIs that implementations seem to be left unfinished. This patch also adds fp_disabled exception checks on stfa/ldfa as they are FP instructions. target-sparc/op_helper.c | 31 ++- target-sparc/translate.c | 14 -- 2 files changed, 34 insertions(+), 11 deletions(-)
[Qemu-devel] [PATCH 2/4] SPARC64: fp_disabled checks on ldfa/lddfa/ldqfa
ldfa/lddfa/ldqfa instructions should raise fp_disabled exceptions if %pstate.PEF==0 or %fprs.FEF==0. Signed-off-by: Tsuneo Saito tsnsa...@gmail.com --- target-sparc/translate.c |6 ++ 1 files changed, 6 insertions(+), 0 deletions(-) diff --git a/target-sparc/translate.c b/target-sparc/translate.c index f32a674..d07eb25 100644 --- a/target-sparc/translate.c +++ b/target-sparc/translate.c @@ -4484,10 +4484,14 @@ static void disas_sparc_insn(DisasContext * dc) case 0x2d: /* V9 prefetch, no effect */ goto skip_move; case 0x30: /* V9 ldfa */ +if (gen_trap_ifnofpu(dc, cpu_cond)) +goto jmp_insn; save_state(dc, cpu_cond); gen_ldf_asi(cpu_addr, insn, 4, rd); goto skip_move; case 0x33: /* V9 lddfa */ +if (gen_trap_ifnofpu(dc, cpu_cond)) +goto jmp_insn; save_state(dc, cpu_cond); gen_ldf_asi(cpu_addr, insn, 8, DFPREG(rd)); goto skip_move; @@ -4495,6 +4499,8 @@ static void disas_sparc_insn(DisasContext * dc) goto skip_move; case 0x32: /* V9 ldqfa */ CHECK_FPU_FEATURE(dc, FLOAT128); +if (gen_trap_ifnofpu(dc, cpu_cond)) +goto jmp_insn; save_state(dc, cpu_cond); gen_ldf_asi(cpu_addr, insn, 16, QFPREG(rd)); goto skip_move; -- 1.7.5.4
[Qemu-devel] [PATCH 1/4] SPARC64: Implement ldfa/lddfa/ldqfa instructions properly
This patch implements sparcv9 ldfa/lddfa/ldqfa instructions with non block-load ASIs. Signed-off-by: Tsuneo Saito tsnsa...@gmail.com --- target-sparc/op_helper.c | 16 +++- 1 files changed, 11 insertions(+), 5 deletions(-) diff --git a/target-sparc/op_helper.c b/target-sparc/op_helper.c index fd0cfbd..a75ac4f 100644 --- a/target-sparc/op_helper.c +++ b/target-sparc/op_helper.c @@ -3331,7 +3331,7 @@ void helper_ldda_asi(target_ulong addr, int asi, int rd) void helper_ldf_asi(target_ulong addr, int asi, int size, int rd) { unsigned int i; -target_ulong val; +CPU_DoubleU u; helper_check_align(addr, 3); addr = asi_address_mask(env, asi, addr); @@ -3371,17 +3371,23 @@ void helper_ldf_asi(target_ulong addr, int asi, int size, int rd) break; } -val = helper_ld_asi(addr, asi, size, 0); switch(size) { default: case 4: -*((uint32_t *)env-fpr[rd]) = val; +*((uint32_t *)env-fpr[rd]) = helper_ld_asi(addr, asi, size, 0); break; case 8: -*((int64_t *)DT0) = val; +u.ll = helper_ld_asi(addr, asi, size, 0); +*((uint32_t *)env-fpr[rd++]) = u.l.upper; +*((uint32_t *)env-fpr[rd++]) = u.l.lower; break; case 16: -// XXX +u.ll = helper_ld_asi(addr, asi, 8, 0); +*((uint32_t *)env-fpr[rd++]) = u.l.upper; +*((uint32_t *)env-fpr[rd++]) = u.l.lower; +u.ll = helper_ld_asi(addr + 8, asi, 8, 0); +*((uint32_t *)env-fpr[rd++]) = u.l.upper; +*((uint32_t *)env-fpr[rd++]) = u.l.lower; break; } } -- 1.7.5.4
[Qemu-devel] [PATCH 3/4] SPARC64: Implement stfa/stdfa/stqfa instrcutions properly
This patch implements sparcv9 stfa/stdfa/stqfa instructions with non block-store ASIs. Signed-off-by: Tsuneo Saito tsnsa...@gmail.com --- target-sparc/op_helper.c | 15 +++ target-sparc/translate.c |2 -- 2 files changed, 11 insertions(+), 6 deletions(-) diff --git a/target-sparc/op_helper.c b/target-sparc/op_helper.c index a75ac4f..fe71829 100644 --- a/target-sparc/op_helper.c +++ b/target-sparc/op_helper.c @@ -3396,6 +3396,7 @@ void helper_stf_asi(target_ulong addr, int asi, int size, int rd) { unsigned int i; target_ulong val = 0; +CPU_DoubleU u; helper_check_align(addr, 3); addr = asi_address_mask(env, asi, addr); @@ -3440,16 +3441,22 @@ void helper_stf_asi(target_ulong addr, int asi, int size, int rd) switch(size) { default: case 4: -val = *((uint32_t *)env-fpr[rd]); +helper_st_asi(addr, *(uint32_t *)env-fpr[rd], asi, size); break; case 8: -val = *((int64_t *)DT0); +u.l.upper = *(uint32_t *)env-fpr[rd++]; +u.l.lower = *(uint32_t *)env-fpr[rd++]; +helper_st_asi(addr, u.ll, asi, size); break; case 16: -// XXX +u.l.upper = *(uint32_t *)env-fpr[rd++]; +u.l.lower = *(uint32_t *)env-fpr[rd++]; +helper_st_asi(addr, u.ll, asi, 8); +u.l.upper = *(uint32_t *)env-fpr[rd++]; +u.l.lower = *(uint32_t *)env-fpr[rd++]; +helper_st_asi(addr + 8, u.ll, asi, 8); break; } -helper_st_asi(addr, val, asi, size); } target_ulong helper_cas_asi(target_ulong addr, target_ulong val1, diff --git a/target-sparc/translate.c b/target-sparc/translate.c index d07eb25..95e78a3 100644 --- a/target-sparc/translate.c +++ b/target-sparc/translate.c @@ -4739,12 +4739,10 @@ static void disas_sparc_insn(DisasContext * dc) r_const = tcg_const_i32(7); gen_helper_check_align(cpu_addr, r_const); tcg_temp_free_i32(r_const); -gen_op_load_fpr_QT0(QFPREG(rd)); gen_stf_asi(cpu_addr, insn, 16, QFPREG(rd)); } break; case 0x37: /* V9 stdfa */ -gen_op_load_fpr_DT0(DFPREG(rd)); gen_stf_asi(cpu_addr, insn, 8, DFPREG(rd)); break; case 0x3c: /* V9 casa */ -- 1.7.5.4
[Qemu-devel] [PATCH 4/4] SPARC64: fp_disabled checks on stfa/stdfa/stqfa
stfa/stdfa/stqfa instructions should raise fp_disabled exceptions if %pstate.PEF==0 or %fprs.FEF==0. Signed-off-by: Tsuneo Saito tsnsa...@gmail.com --- target-sparc/translate.c |6 ++ 1 files changed, 6 insertions(+), 0 deletions(-) diff --git a/target-sparc/translate.c b/target-sparc/translate.c index 95e78a3..94c1000 100644 --- a/target-sparc/translate.c +++ b/target-sparc/translate.c @@ -4729,6 +4729,8 @@ static void disas_sparc_insn(DisasContext * dc) switch (xop) { #ifdef TARGET_SPARC64 case 0x34: /* V9 stfa */ +if (gen_trap_ifnofpu(dc, cpu_cond)) +goto jmp_insn; gen_stf_asi(cpu_addr, insn, 4, rd); break; case 0x36: /* V9 stqfa */ @@ -4736,6 +4738,8 @@ static void disas_sparc_insn(DisasContext * dc) TCGv_i32 r_const; CHECK_FPU_FEATURE(dc, FLOAT128); +if (gen_trap_ifnofpu(dc, cpu_cond)) +goto jmp_insn; r_const = tcg_const_i32(7); gen_helper_check_align(cpu_addr, r_const); tcg_temp_free_i32(r_const); @@ -4743,6 +4747,8 @@ static void disas_sparc_insn(DisasContext * dc) } break; case 0x37: /* V9 stdfa */ +if (gen_trap_ifnofpu(dc, cpu_cond)) +goto jmp_insn; gen_stf_asi(cpu_addr, insn, 8, DFPREG(rd)); break; case 0x3c: /* V9 casa */ -- 1.7.5.4
Re: [Qemu-devel] Fwd: [PATCH] Introduce info migrate-times monitor command
Michal Novotny minov...@redhat.com writes: This accidentally didn't go to the list although it's been sent there (using git send-email)... Please resend cleanly, so that git-am commits with a reasonable commit message, not some crap like this: commit 1f5de40943d4ce9c18d7f9d8b0070a755d7babb5 Author: Michal Novotny minov...@redhat.com Date: Tue Jul 12 16:17:59 2011 +0200 Fwd: [PATCH] Introduce info migrate-times monitor command This accidentally didn't go to the list although it's been sent there (using git send-email)... Michal Original Message Subject:[PATCH] Introduce info migrate-times monitor command Date: Tue, 12 Jul 2011 15:28:27 +0200 From: Michal Novotny mig...@gmail.com To: qemu-devel@nongnu.org CC: Michal Novotny minov...@redhat.com, Michal Novotny mig...@gmail.com From: Michal Novotny minov...@redhat.com Hi, this is the implementation of the info migrate-times command [...]