[Qemu-devel] Re: qemu fail to parse command line with "-pcidevice 00:19.0"
"Hao, Xudong" writes: >>Work-around: -device pci-assign,host=00:19.1 > OK, this new way can work when create guest with static assignment. > But how to hot add a pci device to guest? the old hot add command "pci_add > pci_addr=auto host host=00:19.0" has the same parse error. Command line's -device becomes monitor's device_add: device_add pci-assign,host=00:19.1 > BTW: if we use add "-net none" in qemu command, guest can not be created and > nothing error printed. > > Do you have plan to fix this parse issue? Separate issue. Fix posted: Subject: [Qemu-devel] [PATCH] net: Fix VM start with '-net none' Date: Tue, 15 Jun 2010 13:30:39 +0530 Message-Id: <22a96312232a0458fc04268b79d17828c824df42.1276588830.git.amit.s...@redhat.com> You could have found this yourself :)
[Qemu-devel] [PATCH v2] Makefile: poison TARGET_xxx for compile once.
poison TARGET_xxx for compile once object to prevent those ifdef from creeping in again. didn't poison env which is used as function argument as void *env. Although it would be possible to sort it out, for now just not poison it. qemu-malloc.c didn't compile, so I make it non compile-once for now. It is linked via block-obj-y in Makefile.obj and common-obj-y in Makefile.objs through block-obj-y. So qemu-malloc.o is explicitly added to rules. Signed-off-by: Isaku Yamahata --- Changes v1 -> v2: - tried to poison not only TARGET_ but also TARGET_xxx. - fix link breakage. --- Makefile| 10 +- Makefile.objs | 11 ++- Makefile.target |2 +- poison.h|2 ++ 4 files changed, 18 insertions(+), 7 deletions(-) diff --git a/Makefile b/Makefile index 221fbd8..233b2b1 100644 --- a/Makefile +++ b/Makefile @@ -79,8 +79,8 @@ ifneq ($(wildcard config-host.mak),) include $(SRC_PATH)/Makefile.objs endif -$(common-obj-y): $(GENERATED_HEADERS) -$(filter %-softmmu,$(SUBDIR_RULES)): $(common-obj-y) subdir-libdis +$(common-obj-y) qemu-malloc.o: $(GENERATED_HEADERS) +$(filter %-softmmu,$(SUBDIR_RULES)): $(common-obj-y) qemu-malloc.o subdir-libdis $(filter %-user,$(SUBDIR_RULES)): $(GENERATED_HEADERS) subdir-libdis-user subdir-libuser @@ -137,11 +137,11 @@ iov.o: iov.c iov.h qemu-img.o: qemu-img-cmds.h qemu-img.o qemu-tool.o qemu-nbd.o qemu-io.o: $(GENERATED_HEADERS) -qemu-img$(EXESUF): qemu-img.o qemu-tool.o qemu-error.o $(block-obj-y) $(qobject-obj-y) +qemu-img$(EXESUF): qemu-img.o qemu-tool.o qemu-error.o qemu-malloc.o $(block-obj-y) $(qobject-obj-y) -qemu-nbd$(EXESUF): qemu-nbd.o qemu-tool.o qemu-error.o $(block-obj-y) $(qobject-obj-y) +qemu-nbd$(EXESUF): qemu-nbd.o qemu-tool.o qemu-error.o qemu-malloc.o $(block-obj-y) $(qobject-obj-y) -qemu-io$(EXESUF): qemu-io.o cmd.o qemu-tool.o qemu-error.o $(block-obj-y) $(qobject-obj-y) +qemu-io$(EXESUF): qemu-io.o cmd.o qemu-tool.o qemu-error.o qemu-malloc.o $(block-obj-y) $(qobject-obj-y) qemu-img-cmds.h: $(SRC_PATH)/qemu-img-cmds.hx $(call quiet-command,sh $(SRC_PATH)/hxtool -h < $< > $@," GEN $@") diff --git a/Makefile.objs b/Makefile.objs index 53fb68e..15764c4 100644 --- a/Makefile.objs +++ b/Makefile.objs @@ -7,7 +7,7 @@ qobject-obj-y += qerror.o ### # block-obj-y is code used by both qemu system emulation and qemu-img -block-obj-y = cutils.o cache-utils.o qemu-malloc.o qemu-option.o module.o +block-obj-y = cutils.o cache-utils.o qemu-option.o module.o block-obj-y += nbd.o block.o aio.o aes.o osdep.o qemu-config.o block-obj-$(CONFIG_POSIX) += posix-aio-compat.o block-obj-$(CONFIG_LINUX_AIO) += linux-aio.o @@ -265,3 +265,12 @@ os-win32.o: qemu-options.def qemu-options.def: $(SRC_PATH)/qemu-options.hx $(call quiet-command,sh $(SRC_PATH)/hxtool -h < $< > $@," GEN $(TARGET_DIR)$@") + +## +# poison TARGET_arch to prevent from creeping those defines again. + +POISON_CFLAGS = -include poison.h -DDONT_POISON_ENV +$(qobject-obj-y) $(block-obj-y) $(block-nested-y) $(block-obj-y) \ +$(net-obj-y) $(net-nested-y) $(fsdev-nested-y) $(fsdev-obj-y) \ +$(common-obj-y) $(audio-obj-y) $(slirp-obj-y) $(user-obj-y) \ +$(hw-obj-y) $(sound-obj-y) $(libdis-y) vl.o: QEMU_CFLAGS += $(POISON_CFLAGS) diff --git a/Makefile.target b/Makefile.target index f64702b..91160b6 100644 --- a/Makefile.target +++ b/Makefile.target @@ -295,7 +295,7 @@ monitor.o: qemu-monitor.h $(obj-y) $(obj-$(TARGET_BASE_ARCH)-y): $(GENERATED_HEADERS) -obj-y += $(addprefix ../, $(common-obj-y)) +obj-y += $(addprefix ../, $(common-obj-y) qemu-malloc.o) obj-y += $(addprefix ../libdis/, $(libdis-y)) obj-y += $(libobj-y) obj-y += $(addprefix $(HWDIR)/, $(hw-obj-y)) diff --git a/poison.h b/poison.h index d7db7f4..43af79a 100644 --- a/poison.h +++ b/poison.h @@ -34,7 +34,9 @@ #pragma GCC poison TARGET_PAGE_ALIGN #pragma GCC poison CPUState +#ifndef DONT_POISON_ENV #pragma GCC poison env +#endif #pragma GCC poison CPU_INTERRUPT_HARD #pragma GCC poison CPU_INTERRUPT_EXITTB -- 1.6.6.1
[Qemu-devel] Re: [PATCH 0/2] v2: Add 'serial' attribute to virtio-blk devices
On Thu, 24 Jun 2010 12:49:56 pm Ryan Harper wrote: > Using Rusty's suggestion I've respun the patch removing the special copy > function. I've tested this patch in a guest kernel with and without qemu > supplying serial numbers for the block devices and it's working as expected. > When qemu supplies serial numbers, the correct value is supplied to > /sys/block/vdX/serial and can be used by udev for generating disk/by-id paths > (without separate utility). When running without serial number support the > path > still exists in sysfs but produces no output. > > Signed-off-by: Ryan Harper Great, both applied. BTW, a mail without a patch doesn't need a sign off, does it? Thanks, Ruty.
Re: [Qemu-devel] [PATCH 00/15] Make migration work with hotplug
Alex Williamson wrote: On Thu, 2010-06-24 at 09:04 -0600, Alex Williamson wrote: On Thu, 2010-06-24 at 15:02 +0900, Yoshiaki Tamura wrote: Hi Alex, Is there additional overhead to save rams introduce by this series? If so, how much? Yes, there is overhead, but it's typically quite small. If I migrate a 1G VM immediately after I boot to a login prompt (lots of zero pages), I get an overhead of 0.76%. That's only 226 extra bytes over the 297164995 bytes otherwise transferred. If I build a kernel on the guest and migrate during the compilation, the overhead is 0.19%. The overhead is tiny largely due to patch 12/15, which avoids sending the block name if we're working within the same block as sent previously. If I disable this optimization, the overhead goes up to 0.93% after boot and 0.26% during a kernel compile. Thank your for the detailed numbers and analysis! If the overhead is at this level, I think it's worth introducing to support migration with hot plug devices. Note that an x86 VM does a separate qemu_ram_alloc for memory above 4G, which means in bigger VMs we may end up needing to resend the ramblock name once in a while as we bounce between above and below 4G. Worst case for this could match the 0.26% above, but in my testing during a kernel compile, this seems to increase the overhead to 0.26% on a 6G VM. If we run a program which bounce between the region intentionally, we should get a number close to 0.26%, but the overhead is still low enough, and it shouldn't be a big problem. I don't see any reason why we couldn't allocate all the ram in a single qemu_ram_alloc call, so I'll add another patch to make that change (which will also shorten the name to "pc.ram" for even less overhead ;). Thanks, Hmm. I didn't know about the qemu_ram_alloc over 4G issue. If there isn't any reason, how about submitting a patch to fix it besides this series? FWIW, with this change, my migration during kernel compile on the 6G VM seems to be running just at 0.19%-0.20%, so that eliminates the penalty for bigger memory VMs. Thanks, It make sense:-) Thanks, Yoshi Alex
[Qemu-devel] RE: qemu fail to parse command line with "-pcidevice 00:19.0"
>Work-around: -device pci-assign,host=00:19.1 OK, this new way can work when create guest with static assignment. But how to hot add a pci device to guest? the old hot add command "pci_add pci_addr=auto host host=00:19.0" has the same parse error. BTW: if we use add "-net none" in qemu command, guest can not be created and nothing error printed. Do you have plan to fix this parse issue? Thanks, Xudong -Original Message- From: Markus Armbruster [mailto:arm...@redhat.com] Sent: 2010年6月24日 14:08 To: Hao, Xudong Cc: qemu-devel@nongnu.org; aligu...@us.ibm.com; k...@vger.kernel.org Subject: Re: qemu fail to parse command line with "-pcidevice 00:19.0" Note to qemu-devel: this issue is qemu-kvm only. "Hao, Xudong" writes: > When assign one PCI device, qemu fail to parse the command line: > qemu-system_x86 -smp 2 -m 1024 -hda /path/to/img -pcidevice host=00:19.0 > Error: > qemu-system-x86_64: Parameter 'id' expects an identifier > Identifiers consist of letters, digits, '-', '.', '_', starting with a letter. > pcidevice argument parse error; please check the help text for usage > Could not add assigned device host=00:19.0 > > https://bugs.launchpad.net/qemu/+bug/597932 > > This issue caused by qemu-kvm commit b560a9ab9be06afcbb78b3791ab836dad208a239. The bug is in add_assigned_device(): r = get_param_value(id, sizeof(id), "id", arg); if (!r) r = get_param_value(id, sizeof(id), "name", arg); if (!r) r = get_param_value(id, sizeof(id), "host", arg); We end up with invalid ID "00:19.0". Is there a technical reason why we must have an ID? I doubt it. Work-around: -device pci-assign,host=00:19.1 See the last section of docs/qdev-device-use.txt for details.
[Qemu-devel] [Bug 571432] Re: qemu-system-arm crashed with SIGSEGV in subpage_register()
** Changed in: qemu-kvm (Ubuntu) Status: New => Incomplete -- qemu-system-arm crashed with SIGSEGV in subpage_register() https://bugs.launchpad.net/bugs/571432 You received this bug notification because you are a member of qemu- devel-ml, which is subscribed to QEMU. Status in QEMU: New Status in “qemu-kvm” package in Ubuntu: Incomplete Bug description: Binary package hint: qemu-kvm i think this is the crash behind Bug #570588 not sure why apport did not trigger before ProblemType: Crash DistroRelease: Ubuntu 10.04 Package: qemu-kvm-extras 0.12.3+noroms-0ubuntu9 ProcVersionSignature: Ubuntu 2.6.32-21.32-generic 2.6.32.11+drm33.2 Uname: Linux 2.6.32-21-generic x86_64 NonfreeKernelModules: openafs Architecture: amd64 Date: Wed Apr 28 21:30:13 2010 ExecutablePath: /usr/bin/qemu-system-arm InstallationMedia: Ubuntu 9.10 "Karmic Koala" - Release amd64 (20091027) KvmCmdLine: Error: command ['ps', '-C', 'kvm', '-F'] failed with exit code 1: UIDPID PPID CSZ RSS PSR STIME TTY TIME CMD ProcCmdLine: BOOT_IMAGE=/boot/vmlinuz-2.6.32-21-generic root=UUID=52d7f930-7148-4978-825e-71fcb9243ac6 ro quiet splash ProcCmdline: qemu-system-arm -M versatilepb -cpu cortex-a8 -kernel /tmp/tmp.B2CtSo2g2u/qemu-vmlinuz -no-reboot -nographic -pidfile /tmp/tmp.B2CtSo2g2u/qemu.pid -drive file=/tmp/tmp.B2CtSo2g2u/qemu-armel-201004282122.img,aio=native,cache=none -m 512 -append console=ttyAMA0,115200n8\ root=/dev/sda\ rw\ mem=256M\ devtmpfs.mount=0\ init=/bin/installer\ quiet ProcEnviron: SHELL=/bin/bash LANG=en_GB.UTF-8 SegvAnalysis: Segfault happened at: 0x51058e : cmpq $0x0,(%rdx) PC (0x0051058e) ok source "$0x0" ok destination "(%rdx)" (0x40cc28c0) not located in a known VMA region (needed writable region)! SegvReason: writing unknown VMA Signal: 11 SourcePackage: qemu-kvm StacktraceTop: subpage_register (mmio=0x7f841b26d010, start=, subpage_init (base=268500992, phys=0x1d47400, cpu_register_physical_memory_offset ( smc91c111_init (nd=0xc41b60, base=1087121600, versatile_init (ram_size=, Title: qemu-system-arm crashed with SIGSEGV in subpage_register() UserGroups: dmi.bios.date: 11/07/2007 dmi.bios.vendor: Phoenix Technologies LTD dmi.bios.version: 6.00 dmi.board.name: S2696 dmi.board.vendor: Tyan Computer Corporation dmi.chassis.type: 6 dmi.modalias: dmi:bvnPhoenixTechnologiesLTD:bvr6.00:bd11/07/2007:svn:pn:pvr:rvnTyanComputerCorporation:rnS2696:rvr:cvn:ct6:cvr:
[Qemu-devel] [PATCH 11/14] QError: Introduce QERR_QMP_EXTRA_MEMBER
Signed-off-by: Luiz Capitulino --- qerror.c |4 qerror.h |3 +++ 2 files changed, 7 insertions(+), 0 deletions(-) diff --git a/qerror.c b/qerror.c index cce1e7b..2f6f590 100644 --- a/qerror.c +++ b/qerror.c @@ -177,6 +177,10 @@ static const QErrorStringTable qerror_table[] = { .desc = "QMP input object member '%(member)' expects '%(expected)'", }, { +.error_fmt = QERR_QMP_EXTRA_MEMBER, +.desc = "QMP input object member '%(member)' is unexpected", +}, +{ .error_fmt = QERR_SET_PASSWD_FAILED, .desc = "Could not set password", }, diff --git a/qerror.h b/qerror.h index 77ae574..9ad00b4 100644 --- a/qerror.h +++ b/qerror.h @@ -148,6 +148,9 @@ QError *qobject_to_qerror(const QObject *obj); #define QERR_QMP_BAD_INPUT_OBJECT_MEMBER \ "{ 'class': 'QMPBadInputObjectMember', 'data': { 'member': %s, 'expected': %s } }" +#define QERR_QMP_EXTRA_MEMBER \ +"{ 'class': 'QMPExtraInputObjectMember', 'data': { 'member': %s } }" + #define QERR_SET_PASSWD_FAILED \ "{ 'class': 'SetPasswdFailed', 'data': {} }" -- 1.7.1.359.gd0b8d
[Qemu-devel] Re: Unusual physical address when using 64-bit BAR
On Tue, Jun 15, 2010 at 5:04 AM, Avi Kivity wrote: > On 06/11/2010 08:31 PM, Cam Macdonell wrote: >> >> On Mon, Apr 19, 2010 at 10:41 AM, Cam Macdonell >> wrote: >> >>> >>> Hi, >>> >>> I'm trying to use a 64-bit BAR for my shared memory device. In simply >>> changing the memory type in pci_register_bar() to >>> PCI_BASE_ADDRESS_MEM_TYPE_64 I get an unusual physical address for >>> that BAR (and my driver crashes in pci_ioremap). >>> >>> from lspci: >>> >>> 00:04.0 RAM memory: Qumranet, Inc. Device 1110 >>> Subsystem: Qumranet, Inc. Device 1100 >>> Flags: fast devsel, IRQ 10 >>> Memory at f102 (32-bit, non-prefetchable) [size=1K] >>> Memory at f1021000 (32-bit, non-prefetchable) [size=4K] >>> Memory at c200 (64-bit, non-prefetchable) [size=1024M] >>> Capabilities: >>> 00: f4 1a 10 11 03 00 10 00 00 00 00 05 00 00 00 00 >>> 10: 00 00 02 f1 00 10 02 f1 04 00 00 00 00 c2 00 00 >>> 20: 00 00 00 00 00 00 00 00 00 00 00 00 f4 1a 00 11 >>> 30: 00 00 00 00 40 00 00 00 00 00 00 00 0b 01 00 00 >>> >>> with DEBUG_MEMREG, I see >>> >>> kvm_unregister_memory_area:666 Unregistering memory region >>> c200 (4000) >>> kvm_destroy_phys_mem:649 slot 7 start c200 len 0 flags 0 >>> IVSHMEM: addr = 3221225472 size = 1073741824 >>> kvm_register_phys_mem:605 memory: gpa: c200c000, size: 4000, >>> uaddr: 7f6dd7ffe000, slot: 7, flags: 0 >>> kvm_unregister_memory_area:666 Unregistering memory region >>> c200c000 (4000) >>> kvm_destroy_phys_mem:649 slot 7 start c200c000 len 0 flags 0 >>> IVSHMEM: addr = 0 size = 1073741824 >>> kvm_register_phys_mem:605 memory: gpa: c200, size: 4000, >>> uaddr: 7f6dd7ffe000, slot: 7, flags: 0 >>> kvm_unregister_memory_area:666 Unregistering memory region >>> c200 (4000) >>> kvm_destroy_phys_mem:649 slot 7 start c200 len 0 flags 0 >>> IVSHMEM: addr = 0 size = 1073741824 >>> kvm_register_phys_mem:605 memory: gpa: , size: >>> 4000, uaddr: 7f6dd7ffe000, slot: 7, flags: 0 >>> kvm_unregister_memory_area:666 Unregistering memory region >>> (4000) >>> kvm_destroy_phys_mem:649 slot 7 start len 0 flags 0 >>> IVSHMEM: addr = 0 size = 1073741824 >>> kvm_register_phys_mem:605 memory: gpa: c200, size: 4000, >>> uaddr: 7f6dd7ffe000, slot: 7, flags: 0 >>> >>> (the IVSHMEM lines are my debug statements) >>> >>> address sizes : 40 bits physical, 48 bits virtual (guest) >>> address sizes : 38 bits physical, 48 bits virtual (host) >>> >>> >> >> Hi, I happened to run into this problem again when trying to use a >> 64-bit BAR. I did a bit more digging and the test that is failing is >> called from arch/x86/mm/ioremap.c in the guest and here it is. >> >> static inline int phys_addr_valid(resource_size_t addr) >> { >> #ifdef CONFIG_PHYS_ADDR_T_64BIT >> return !(addr>> boot_cpu_data.x86_phys_bits); >> #else >> return 1; >> #endif >> } >> >> the value of addr (in this case the 48-bit virtual address >> c200) is shifted to the right shift by >> boot_cpu_data.x86_phys_bits (which is 40 bits, the physical address >> size), so a non-zero value is returned which causes the test to fail >> and generates the "invalid physical address" error in the guest. >> >> Any help is appreciated as to whether this is a Qemu or guest kernel >> issue. >> > > The guest kernel should never have generated an address that is bigger than > cpu_phys_bits in the first place. What's the value for cpu_phys_bits in the > guest? (/proc/cpuinfo, 'address sizes :' line). Sorry I missed your reply until now. The guest address sizes are as follows: address sizes : 40 bits physical, 48 bits virtual > > Is this really the address the guest programmed, or is qemu misinterpreting > it? > > -- > error compiling committee.c: too many arguments to function > >
[Qemu-devel] [PATCH 06/14] QDict: Introduce qdict_get_try_bool()
Signed-off-by: Luiz Capitulino --- qdict.c | 18 ++ qdict.h |1 + 2 files changed, 19 insertions(+), 0 deletions(-) diff --git a/qdict.c b/qdict.c index a28a0a9..dee0fb4 100644 --- a/qdict.c +++ b/qdict.c @@ -308,6 +308,24 @@ int64_t qdict_get_try_int(const QDict *qdict, const char *key, } /** + * qdict_get_try_bool(): Try to get a bool mapped by 'key' + * + * Return bool mapped by 'key', if it is not present in the + * dictionary or if the stored object is not of QBool type + * 'def_value' will be returned. + */ +int qdict_get_try_bool(const QDict *qdict, const char *key, int def_value) +{ +QObject *obj; + +obj = qdict_get(qdict, key); +if (!obj || qobject_type(obj) != QTYPE_QBOOL) +return def_value; + +return qbool_get_int(qobject_to_qbool(obj)); +} + +/** * qdict_get_try_str(): Try to get a pointer to the stored string * mapped by 'key' * diff --git a/qdict.h b/qdict.h index 0e7a43f..929d8d2 100644 --- a/qdict.h +++ b/qdict.h @@ -61,6 +61,7 @@ QDict *qdict_get_qdict(const QDict *qdict, const char *key); const char *qdict_get_str(const QDict *qdict, const char *key); int64_t qdict_get_try_int(const QDict *qdict, const char *key, int64_t def_value); +int qdict_get_try_bool(const QDict *qdict, const char *key, int def_value); const char *qdict_get_try_str(const QDict *qdict, const char *key); #endif /* QDICT_H */ -- 1.7.1.359.gd0b8d
Re: [Qemu-devel] [PATCH v3 00/14]: QMP: Replace client argument checker
On Thu, 24 Jun 2010 18:33:26 -0300 Luiz Capitulino wrote: > Current QMP's client argument checker code is more complex than it should be > and has a flaw: it ignores unknown arguments. > > This series solves both problems by introducing a new, simple and > ultra-poweful > argument checker. This wasn't trivial to get right due to the number of errors > combinations, so review is very appreciated. > > changelog > - > > v2 -> v3 > > - Move all input object checking into qmp_check_input_obj() > - Fix remaining problem with the handling of O-type arguments > - Small renames suggested by Markus > - Small cleanup in handle_qmp_command() Forgot to mention that changes from v2 begin in patch 08, and really relevant ones in patch 12. > > v1 -> v2 > > - Introduce new iteration API and use it > - Handle O-type correctly (I hope so) > - Address several small issues found by Markus >
[Qemu-devel] [PATCH 14/14] QMP: handle_qmp_command(): Small cleanup
Drop a unneeded label and QDECREF() call. Signed-off-by: Luiz Capitulino --- monitor.c | 14 ++ 1 files changed, 6 insertions(+), 8 deletions(-) diff --git a/monitor.c b/monitor.c index b68b464..e38a3a4 100644 --- a/monitor.c +++ b/monitor.c @@ -4227,7 +4227,7 @@ static void handle_qmp_command(JSONMessageParser *parser, QList *tokens) Monitor *mon = cur_mon; const char *cmd_name, *info_item; -args = NULL; +args = input = NULL; obj = json_parser_parse(tokens, NULL); if (!obj) { @@ -4248,7 +4248,7 @@ static void handle_qmp_command(JSONMessageParser *parser, QList *tokens) cmd_name = qdict_get_str(input, "execute"); if (invalid_qmp_mode(mon, cmd_name)) { qerror_report(QERR_COMMAND_NOT_FOUND, cmd_name); -goto err_input; +goto err_out; } /* @@ -4257,7 +4257,7 @@ static void handle_qmp_command(JSONMessageParser *parser, QList *tokens) */ if (compare_cmd(cmd_name, "info")) { qerror_report(QERR_COMMAND_NOT_FOUND, cmd_name); -goto err_input; +goto err_out; } else if (strstart(cmd_name, "query-", &info_item)) { cmd = monitor_find_command("info"); qdict_put_obj(input, "arguments", @@ -4266,7 +4266,7 @@ static void handle_qmp_command(JSONMessageParser *parser, QList *tokens) cmd = monitor_find_command(cmd_name); if (!cmd || !monitor_handler_ported(cmd)) { qerror_report(QERR_COMMAND_NOT_FOUND, cmd_name); -goto err_input; +goto err_out; } } @@ -4278,8 +4278,6 @@ static void handle_qmp_command(JSONMessageParser *parser, QList *tokens) QINCREF(args); } -QDECREF(input); - err = qmp_check_client_args(cmd, args); if (err < 0) { goto err_out; @@ -4294,13 +4292,13 @@ static void handle_qmp_command(JSONMessageParser *parser, QList *tokens) } else { monitor_call_handler(mon, cmd, args); } + goto out; -err_input: -QDECREF(input); err_out: monitor_protocol_emitter(mon, NULL); out: +QDECREF(input); QDECREF(args); } -- 1.7.1.359.gd0b8d
[Qemu-devel] [PATCH 12/14] QMP: Introduce qmp_check_input_obj()
This is similar to qmp_check_client_args(), but it checks if the input object follows the specification (QMP/qmp-spec.txt section 2.3). As we're limited to three keys, the work here is quite simple: we iterate over the input object, checking each time if the current argument complies to the specification. Signed-off-by: Luiz Capitulino --- monitor.c | 62 - 1 files changed, 61 insertions(+), 1 deletions(-) diff --git a/monitor.c b/monitor.c index 8d3e788..fab553a 100644 --- a/monitor.c +++ b/monitor.c @@ -4162,6 +4162,62 @@ out: return err; } +/* + * Input object checking rules + * + * 1. Input object must be a dict + * 2. The "execute" key must exist + * 3. The "execute" key must be a string + * 4. If the "arguments" key exists, it must be a dict + * 5. If the "id" key exists, it can be anything (ie. json-value) + * 6. Any argument not listed above is considered invalid + */ +static QDict *qmp_check_input_obj(QObject *input_obj) +{ +const QDictEntry *ent; +int has_exec_key = 0; +QDict *input_dict; + +if (qobject_type(input_obj) != QTYPE_QDICT) { +qerror_report(QERR_QMP_BAD_INPUT_OBJECT, "object"); +return NULL; +} + +input_dict = qobject_to_qdict(input_obj); + +for (ent = qdict_first(input_dict); ent; ent = qdict_next(input_dict, ent)){ +const char *arg_name = qdict_entry_key(ent); +const QObject *arg_obj = qdict_entry_value(ent); + +if (!strcmp(arg_name, "execute")) { +if (qobject_type(arg_obj) != QTYPE_QSTRING) { +qerror_report(QERR_QMP_BAD_INPUT_OBJECT_MEMBER, "execute", + "string"); +return NULL; +} +has_exec_key = 1; +} else if (!strcmp(arg_name, "arguments")) { +if (qobject_type(arg_obj) != QTYPE_QDICT) { +qerror_report(QERR_QMP_BAD_INPUT_OBJECT_MEMBER, "arguments", + "object"); +return NULL; +} +} else if (!strcmp(arg_name, "id")) { +/* FIXME: check duplicated IDs for async commands */ +} else { +qerror_report(QERR_QMP_EXTRA_MEMBER, arg_name); +return NULL; +} +} + +if (!has_exec_key) { +qerror_report(QERR_QMP_BAD_INPUT_OBJECT, "execute"); +return NULL; +} + +return input_dict; +} + static void handle_qmp_command(JSONMessageParser *parser, QList *tokens) { int err; @@ -4184,7 +4240,11 @@ static void handle_qmp_command(JSONMessageParser *parser, QList *tokens) goto err_out; } -input = qobject_to_qdict(obj); +input = qmp_check_input_obj(obj); +if (!input) { +qobject_decref(obj); +goto err_out; +} mon->mc->id = qdict_get(input, "id"); qobject_incref(mon->mc->id); -- 1.7.1.359.gd0b8d
[Qemu-devel] [PATCH 13/14] QMP: Drop old input object checking
Previous commit added qmp_check_input_obj(), it does all the checking we need. Signed-off-by: Luiz Capitulino --- monitor.c | 19 +-- 1 files changed, 1 insertions(+), 18 deletions(-) diff --git a/monitor.c b/monitor.c index fab553a..b68b464 100644 --- a/monitor.c +++ b/monitor.c @@ -4234,10 +4234,6 @@ static void handle_qmp_command(JSONMessageParser *parser, QList *tokens) // FIXME: should be triggered in json_parser_parse() qerror_report(QERR_JSON_PARSING); goto err_out; -} else if (qobject_type(obj) != QTYPE_QDICT) { -qerror_report(QERR_QMP_BAD_INPUT_OBJECT, "object"); -qobject_decref(obj); -goto err_out; } input = qmp_check_input_obj(obj); @@ -4249,17 +4245,7 @@ static void handle_qmp_command(JSONMessageParser *parser, QList *tokens) mon->mc->id = qdict_get(input, "id"); qobject_incref(mon->mc->id); -obj = qdict_get(input, "execute"); -if (!obj) { -qerror_report(QERR_QMP_BAD_INPUT_OBJECT, "execute"); -goto err_input; -} else if (qobject_type(obj) != QTYPE_QSTRING) { -qerror_report(QERR_QMP_BAD_INPUT_OBJECT_MEMBER, "execute", "string"); -goto err_input; -} - -cmd_name = qstring_get_str(qobject_to_qstring(obj)); - +cmd_name = qdict_get_str(input, "execute"); if (invalid_qmp_mode(mon, cmd_name)) { qerror_report(QERR_COMMAND_NOT_FOUND, cmd_name); goto err_input; @@ -4287,9 +4273,6 @@ static void handle_qmp_command(JSONMessageParser *parser, QList *tokens) obj = qdict_get(input, "arguments"); if (!obj) { args = qdict_new(); -} else if (qobject_type(obj) != QTYPE_QDICT) { -qerror_report(QERR_QMP_BAD_INPUT_OBJECT_MEMBER, "arguments", "object"); -goto err_input; } else { args = qobject_to_qdict(obj); QINCREF(args); -- 1.7.1.359.gd0b8d
[Qemu-devel] [PATCH 03/14] QDict: Introduce functions to retrieve QDictEntry values
Next commit will introduce a new QDict iteration API which returns QDictEntry entries, but we don't want users to directly access its members since QDictEntry should be private to QDict. In the near future this kind of data type will be turned into a forward reference. Signed-off-by: Luiz Capitulino --- qdict.c | 21 + qdict.h |2 ++ 2 files changed, 23 insertions(+), 0 deletions(-) diff --git a/qdict.c b/qdict.c index 71be2eb..c467763 100644 --- a/qdict.c +++ b/qdict.c @@ -83,6 +83,27 @@ static QDictEntry *alloc_entry(const char *key, QObject *value) } /** + * qdict_entry_value(): Return qdict entry value + * + * Return weak reference. + */ +QObject *qdict_entry_value(const QDictEntry *entry) +{ +return entry->value; +} + +/** + * qdict_entry_key(): Return qdict entry key + * + * Return a *pointer* to the string, it has to be duplicated before being + * stored. + */ +const char *qdict_entry_key(const QDictEntry *entry) +{ +return entry->key; +} + +/** * qdict_find(): List lookup function */ static QDictEntry *qdict_find(const QDict *qdict, diff --git a/qdict.h b/qdict.h index dcd2b29..0c8de3c 100644 --- a/qdict.h +++ b/qdict.h @@ -34,6 +34,8 @@ typedef struct QDict { /* Object API */ QDict *qdict_new(void); +const char *qdict_entry_key(const QDictEntry *entry); +QObject *qdict_entry_value(const QDictEntry *entry); size_t qdict_size(const QDict *qdict); void qdict_put_obj(QDict *qdict, const char *key, QObject *value); void qdict_del(QDict *qdict, const char *key); -- 1.7.1.359.gd0b8d
[Qemu-devel] [PATCH 04/14] QDict: Introduce new iteration API
It's composed of functions qdict_first() and qdict_next(), plus functions to access QDictEntry values. This API was suggested by Markus Armbruster and it offers full control over the iteration process. The usage is simple, the following example prints all keys in 'qdict' (it's hopefully better than any English description): QDict *qdict; const QDictEntry *ent; [...] for (ent = qdict_first(qdict); ent; ent = qdict_next(qdict, ent)) { printf("%s ", qdict_entry_key(ent)); } Signed-off-by: Luiz Capitulino --- qdict.c | 37 + qdict.h |2 ++ 2 files changed, 39 insertions(+), 0 deletions(-) diff --git a/qdict.c b/qdict.c index c467763..a28a0a9 100644 --- a/qdict.c +++ b/qdict.c @@ -345,6 +345,43 @@ void qdict_iter(const QDict *qdict, } } +static QDictEntry *qdict_next_entry(const QDict *qdict, int first_bucket) +{ +int i; + +for (i = first_bucket; i < QDICT_BUCKET_MAX; i++) { +if (!QLIST_EMPTY(&qdict->table[i])) { +return QLIST_FIRST(&qdict->table[i]); +} +} + +return NULL; +} + +/** + * qdict_first(): Return first qdict entry for iteration. + */ +const QDictEntry *qdict_first(const QDict *qdict) +{ +return qdict_next_entry(qdict, 0); +} + +/** + * qdict_next(): Return next qdict entry in an iteration. + */ +const QDictEntry *qdict_next(const QDict *qdict, const QDictEntry *entry) +{ +QDictEntry *ret; + +ret = QLIST_NEXT(entry, next); +if (!ret) { +unsigned int bucket = tdb_hash(entry->key) % QDICT_BUCKET_MAX; +ret = qdict_next_entry(qdict, bucket + 1); +} + +return ret; +} + /** * qentry_destroy(): Free all the memory allocated by a QDictEntry */ diff --git a/qdict.h b/qdict.h index 0c8de3c..0e7a43f 100644 --- a/qdict.h +++ b/qdict.h @@ -45,6 +45,8 @@ QDict *qobject_to_qdict(const QObject *obj); void qdict_iter(const QDict *qdict, void (*iter)(const char *key, QObject *obj, void *opaque), void *opaque); +const QDictEntry *qdict_first(const QDict *qdict); +const QDictEntry *qdict_next(const QDict *qdict, const QDictEntry *entry); /* Helper to qdict_put_obj(), accepts any object */ #define qdict_put(qdict, key, obj) \ -- 1.7.1.359.gd0b8d
[Qemu-devel] [PATCH 10/14] QMP: Drop old client argument checker
Previous two commits added qmp_check_client_args(), which fully replaces this code and is way better. It's important to note that the new checker doesn't support the '/' arg type. As we don't have any of those handlers converted to QMP, this is just dead code. Signed-off-by: Luiz Capitulino --- monitor.c | 176 - 1 files changed, 0 insertions(+), 176 deletions(-) diff --git a/monitor.c b/monitor.c index 602ccdd..8d3e788 100644 --- a/monitor.c +++ b/monitor.c @@ -3966,177 +3966,6 @@ static int monitor_can_read(void *opaque) return (mon->suspend_cnt == 0) ? 1 : 0; } -typedef struct CmdArgs { -QString *name; -int type; -int flag; -int optional; -} CmdArgs; - -static int check_opt(const CmdArgs *cmd_args, const char *name, QDict *args) -{ -if (!cmd_args->optional) { -qerror_report(QERR_MISSING_PARAMETER, name); -return -1; -} - -return 0; -} - -static int check_arg(const CmdArgs *cmd_args, QDict *args) -{ -QObject *value; -const char *name; - -name = qstring_get_str(cmd_args->name); - -if (!args) { -return check_opt(cmd_args, name, args); -} - -value = qdict_get(args, name); -if (!value) { -return check_opt(cmd_args, name, args); -} - -switch (cmd_args->type) { -case 'F': -case 'B': -case 's': -if (qobject_type(value) != QTYPE_QSTRING) { -qerror_report(QERR_INVALID_PARAMETER_TYPE, name, "string"); -return -1; -} -break; -case '/': { -int i; -const char *keys[] = { "count", "format", "size", NULL }; - -for (i = 0; keys[i]; i++) { -QObject *obj = qdict_get(args, keys[i]); -if (!obj) { -qerror_report(QERR_MISSING_PARAMETER, name); -return -1; -} -if (qobject_type(obj) != QTYPE_QINT) { -qerror_report(QERR_INVALID_PARAMETER_TYPE, name, "int"); -return -1; -} -} -break; -} -case 'i': -case 'l': -case 'M': -if (qobject_type(value) != QTYPE_QINT) { -qerror_report(QERR_INVALID_PARAMETER_TYPE, name, "int"); -return -1; -} -break; -case 'f': -case 'T': -if (qobject_type(value) != QTYPE_QINT && qobject_type(value) != QTYPE_QFLOAT) { -qerror_report(QERR_INVALID_PARAMETER_TYPE, name, "number"); -return -1; -} -break; -case 'b': -if (qobject_type(value) != QTYPE_QBOOL) { -qerror_report(QERR_INVALID_PARAMETER_TYPE, name, "bool"); -return -1; -} -break; -case '-': -if (qobject_type(value) != QTYPE_QINT && -qobject_type(value) != QTYPE_QBOOL) { -qerror_report(QERR_INVALID_PARAMETER_TYPE, name, "bool"); -return -1; -} -break; -case 'O': -default: -/* impossible */ -abort(); -} - -return 0; -} - -static void cmd_args_init(CmdArgs *cmd_args) -{ -cmd_args->name = qstring_new(); -cmd_args->type = cmd_args->flag = cmd_args->optional = 0; -} - -static int check_opts(QemuOptsList *opts_list, QDict *args) -{ -assert(!opts_list->desc->name); -return 0; -} - -/* - * This is not trivial, we have to parse Monitor command's argument - * type syntax to be able to check the arguments provided by clients. - * - * In the near future we will be using an array for that and will be - * able to drop all this parsing... - */ -static int monitor_check_qmp_args(const mon_cmd_t *cmd, QDict *args) -{ -int err; -const char *p; -CmdArgs cmd_args; -QemuOptsList *opts_list; - -if (cmd->args_type == NULL) { -return (qdict_size(args) == 0 ? 0 : -1); -} - -err = 0; -cmd_args_init(&cmd_args); -opts_list = NULL; - -for (p = cmd->args_type;; p++) { -if (*p == ':') { -cmd_args.type = *++p; -p++; -if (cmd_args.type == '-') { -cmd_args.flag = *p++; -cmd_args.optional = 1; -} else if (cmd_args.type == 'O') { -opts_list = qemu_find_opts(qstring_get_str(cmd_args.name)); -assert(opts_list); -} else if (*p == '?') { -cmd_args.optional = 1; -p++; -} - -assert(*p == ',' || *p == '\0'); -if (opts_list) { -err = check_opts(opts_list, args); -opts_list = NULL; -} else { -err = check_arg(&cmd_args, args); -QDECREF(cmd_args.name); -cmd_args_init(&cmd_args)
[Qemu-devel] [PATCH 02/14] QDict: Small terminology change
Let's call a 'hash' only what is returned by our hash function, anything else is a 'bucket'. This helps avoiding confusion with regard to how we traverse our table. Signed-off-by: Luiz Capitulino --- check-qdict.c |2 +- qdict.c | 24 qdict.h |4 ++-- 3 files changed, 15 insertions(+), 15 deletions(-) diff --git a/check-qdict.c b/check-qdict.c index 2c3089f..1b070f4 100644 --- a/check-qdict.c +++ b/check-qdict.c @@ -50,7 +50,7 @@ START_TEST(qdict_put_obj_test) qdict_put_obj(qdict, "", QOBJECT(qint_from_int(num))); fail_unless(qdict_size(qdict) == 1); -ent = QLIST_FIRST(&qdict->table[12345 % QDICT_HASH_SIZE]); +ent = QLIST_FIRST(&qdict->table[12345 % QDICT_BUCKET_MAX]); qi = qobject_to_qint(ent->value); fail_unless(qint_get_int(qi) == num); diff --git a/qdict.c b/qdict.c index c974d6f..71be2eb 100644 --- a/qdict.c +++ b/qdict.c @@ -86,11 +86,11 @@ static QDictEntry *alloc_entry(const char *key, QObject *value) * qdict_find(): List lookup function */ static QDictEntry *qdict_find(const QDict *qdict, - const char *key, unsigned int hash) + const char *key, unsigned int bucket) { QDictEntry *entry; -QLIST_FOREACH(entry, &qdict->table[hash], next) +QLIST_FOREACH(entry, &qdict->table[bucket], next) if (!strcmp(entry->key, key)) return entry; @@ -110,11 +110,11 @@ static QDictEntry *qdict_find(const QDict *qdict, */ void qdict_put_obj(QDict *qdict, const char *key, QObject *value) { -unsigned int hash; +unsigned int bucket; QDictEntry *entry; -hash = tdb_hash(key) % QDICT_HASH_SIZE; -entry = qdict_find(qdict, key, hash); +bucket = tdb_hash(key) % QDICT_BUCKET_MAX; +entry = qdict_find(qdict, key, bucket); if (entry) { /* replace key's value */ qobject_decref(entry->value); @@ -122,7 +122,7 @@ void qdict_put_obj(QDict *qdict, const char *key, QObject *value) } else { /* allocate a new entry */ entry = alloc_entry(key, value); -QLIST_INSERT_HEAD(&qdict->table[hash], entry, next); +QLIST_INSERT_HEAD(&qdict->table[bucket], entry, next); qdict->size++; } } @@ -137,7 +137,7 @@ QObject *qdict_get(const QDict *qdict, const char *key) { QDictEntry *entry; -entry = qdict_find(qdict, key, tdb_hash(key) % QDICT_HASH_SIZE); +entry = qdict_find(qdict, key, tdb_hash(key) % QDICT_BUCKET_MAX); return (entry == NULL ? NULL : entry->value); } @@ -148,8 +148,8 @@ QObject *qdict_get(const QDict *qdict, const char *key) */ int qdict_haskey(const QDict *qdict, const char *key) { -unsigned int hash = tdb_hash(key) % QDICT_HASH_SIZE; -return (qdict_find(qdict, key, hash) == NULL ? 0 : 1); +unsigned int bucket = tdb_hash(key) % QDICT_BUCKET_MAX; +return (qdict_find(qdict, key, bucket) == NULL ? 0 : 1); } /** @@ -318,7 +318,7 @@ void qdict_iter(const QDict *qdict, int i; QDictEntry *entry; -for (i = 0; i < QDICT_HASH_SIZE; i++) { +for (i = 0; i < QDICT_BUCKET_MAX; i++) { QLIST_FOREACH(entry, &qdict->table[i], next) iter(entry->key, entry->value, opaque); } @@ -347,7 +347,7 @@ void qdict_del(QDict *qdict, const char *key) { QDictEntry *entry; -entry = qdict_find(qdict, key, tdb_hash(key) % QDICT_HASH_SIZE); +entry = qdict_find(qdict, key, tdb_hash(key) % QDICT_BUCKET_MAX); if (entry) { QLIST_REMOVE(entry, next); qentry_destroy(entry); @@ -366,7 +366,7 @@ static void qdict_destroy_obj(QObject *obj) assert(obj != NULL); qdict = qobject_to_qdict(obj); -for (i = 0; i < QDICT_HASH_SIZE; i++) { +for (i = 0; i < QDICT_BUCKET_MAX; i++) { QDictEntry *entry = QLIST_FIRST(&qdict->table[i]); while (entry) { QDictEntry *tmp = QLIST_NEXT(entry, next); diff --git a/qdict.h b/qdict.h index 72ea563..dcd2b29 100644 --- a/qdict.h +++ b/qdict.h @@ -18,7 +18,7 @@ #include "qemu-queue.h" #include -#define QDICT_HASH_SIZE 512 +#define QDICT_BUCKET_MAX 512 typedef struct QDictEntry { char *key; @@ -29,7 +29,7 @@ typedef struct QDictEntry { typedef struct QDict { QObject_HEAD; size_t size; -QLIST_HEAD(,QDictEntry) table[QDICT_HASH_SIZE]; +QLIST_HEAD(,QDictEntry) table[QDICT_BUCKET_MAX]; } QDict; /* Object API */ -- 1.7.1.359.gd0b8d
[Qemu-devel] [PATCH 05/14] check-qdict: Introduce test for the new iteration API
Signed-off-by: Luiz Capitulino --- check-qdict.c | 31 +++ 1 files changed, 31 insertions(+), 0 deletions(-) diff --git a/check-qdict.c b/check-qdict.c index 1b070f4..6afce5a 100644 --- a/check-qdict.c +++ b/check-qdict.c @@ -194,6 +194,36 @@ START_TEST(qobject_to_qdict_test) } END_TEST +START_TEST(qdict_iterapi_test) +{ +int count; +const QDictEntry *ent; + +fail_unless(qdict_first(tests_dict) == NULL); + +qdict_put(tests_dict, "key1", qint_from_int(1)); +qdict_put(tests_dict, "key2", qint_from_int(2)); +qdict_put(tests_dict, "key3", qint_from_int(3)); + +count = 0; +for (ent = qdict_first(tests_dict); ent; ent = qdict_next(tests_dict, ent)){ +fail_unless(qdict_haskey(tests_dict, qdict_entry_key(ent)) == 1); +count++; +} + +fail_unless(count == qdict_size(tests_dict)); + +/* Do it again to test restarting */ +count = 0; +for (ent = qdict_first(tests_dict); ent; ent = qdict_next(tests_dict, ent)){ +fail_unless(qdict_haskey(tests_dict, qdict_entry_key(ent)) == 1); +count++; +} + +fail_unless(count == qdict_size(tests_dict)); +} +END_TEST + /* * Errors test-cases */ @@ -338,6 +368,7 @@ static Suite *qdict_suite(void) tcase_add_test(qdict_public2_tcase, qdict_haskey_test); tcase_add_test(qdict_public2_tcase, qdict_del_test); tcase_add_test(qdict_public2_tcase, qobject_to_qdict_test); +tcase_add_test(qdict_public2_tcase, qdict_iterapi_test); qdict_errors_tcase = tcase_create("Errors"); suite_add_tcase(s, qdict_errors_tcase); -- 1.7.1.359.gd0b8d
[Qemu-devel] [PATCH 08/14] QMP: New argument checker (first part)
Current QMP's argument checker is more complex than it should be and has (at least) one serious bug: it ignores unknown arguments. To solve both problems we introduce a new argument checker. It's added on top of the existing one, so that there are no regressions during the transition. This commit introduces the first part of the new checker, which is run by qmp_check_client_args() and does the following: 1. Check if all mandatory arguments were provided 2. Set flags for argument validation In order to do that, we transform the args_type string (from qemu-montor.hx) into a qdict and iterate over it. Next commit adds the new checker's second part: type checking and invalid argument detection. Signed-off-by: Luiz Capitulino --- monitor.c | 106 + 1 files changed, 106 insertions(+), 0 deletions(-) diff --git a/monitor.c b/monitor.c index 5084a6e..edc362f 100644 --- a/monitor.c +++ b/monitor.c @@ -177,6 +177,9 @@ static inline void mon_print_count_init(Monitor *mon) { } static inline int mon_print_count_get(const Monitor *mon) { return 0; } #endif /* CONFIG_DEBUG_MONITOR */ +/* QMP checker flags */ +#define QMP_ACCEPT_UNKNOWNS 1 + static QLIST_HEAD(mon_list, Monitor) mon_list; static const mon_cmd_t mon_cmds[]; @@ -4140,6 +4143,104 @@ static int invalid_qmp_mode(const Monitor *mon, const char *cmd_name) return (qmp_cmd_mode(mon) ? is_cap : !is_cap); } +/* + * - Check if the client has passed all mandatory args + * - Set special flags for argument validation + */ +static int check_mandatory_args(const QDict *cmd_args, +const QDict *client_args, int *flags) +{ +const QDictEntry *ent; + +for (ent = qdict_first(cmd_args); ent; ent = qdict_next(cmd_args, ent)) { +const char *cmd_arg_name = qdict_entry_key(ent); +QString *type = qobject_to_qstring(qdict_entry_value(ent)); +assert(type != NULL); + +if (qstring_get_str(type)[0] == 'O') { +assert((*flags & QMP_ACCEPT_UNKNOWNS) == 0); +*flags |= QMP_ACCEPT_UNKNOWNS; +} else if (qstring_get_str(type)[0] != '-' && + qstring_get_str(type)[1] != '?' && + !qdict_haskey(client_args, cmd_arg_name)) { +qerror_report(QERR_MISSING_PARAMETER, cmd_arg_name); +return -1; +} +} + +return 0; +} + +static QDict *qdict_from_args_type(const char *args_type) +{ +int i; +QDict *qdict; +QString *key, *type, *cur_qs; + +assert(args_type != NULL); + +qdict = qdict_new(); + +if (args_type == NULL || args_type[0] == '\0') { +/* no args, empty qdict */ +goto out; +} + +key = qstring_new(); +type = qstring_new(); + +cur_qs = key; + +for (i = 0;; i++) { +switch (args_type[i]) { +case ',': +case '\0': +qdict_put(qdict, qstring_get_str(key), type); +QDECREF(key); +if (args_type[i] == '\0') { +goto out; +} +type = qstring_new(); /* qdict has ref */ +cur_qs = key = qstring_new(); +break; +case ':': +cur_qs = type; +break; +default: +qstring_append_chr(cur_qs, args_type[i]); +break; +} +} + +out: +return qdict; +} + +/* + * Client argument checking rules: + * + * 1. Client must provide all mandatory arguments + */ +static int qmp_check_client_args(const mon_cmd_t *cmd, QDict *client_args) +{ +int flags, err; +QDict *cmd_args; + +cmd_args = qdict_from_args_type(cmd->args_type); + +flags = 0; +err = check_mandatory_args(cmd_args, client_args, &flags); +if (err) { +goto out; +} + +/* TODO: Check client args type */ + +out: +QDECREF(cmd_args); +return err; +} + static void handle_qmp_command(JSONMessageParser *parser, QList *tokens) { int err; @@ -4215,6 +4316,11 @@ static void handle_qmp_command(JSONMessageParser *parser, QList *tokens) QDECREF(input); +err = qmp_check_client_args(cmd, args); +if (err < 0) { +goto err_out; +} + err = monitor_check_qmp_args(cmd, args); if (err < 0) { goto err_out; -- 1.7.1.359.gd0b8d
[Qemu-devel] [PATCH 07/14] Monitor: handle optional '-' arg as a bool
Historically, user monitor arguments beginning with '-' (eg. '-f') were passed as integers down to handlers. I've maintained this behavior in the new monitor because we didn't have a boolean type at the very beginning of QMP. Today we have it and this behavior is causing trouble to QMP's argument checker. This commit fixes the problem by doing the following changes: 1. User Monitor Before: the optional arg was represented as a QInt, we'd pass 1 down to handlers if the user specified the argument or 0 otherwise This commit: the optional arg is represented as a QBool, we pass true down to handlers if the user specified the argument, otherwise _nothing_ is passed 2. QMP Before: the client was required to pass the arg as QBool, but we'd convert it to QInt internally. If the argument wasn't passed, we'd pass 0 down This commit: still require a QBool, but doesn't do any conversion and doesn't pass any default value 3. Convert existing handlers (do_eject()/do_migrate()) to the new way Before: Both handlers would expect a QInt value, either 0 or 1 This commit: Change the handlers to accept a QBool, they handle the following cases: A) true is passed: the option is enabled B) false is passed: the option is disabled C) nothing is passed: option not specified, use default behavior Signed-off-by: Luiz Capitulino --- blockdev.c |2 +- migration.c | 16 +++- monitor.c | 17 +++-- 3 files changed, 11 insertions(+), 24 deletions(-) diff --git a/blockdev.c b/blockdev.c index 3b8c606..4dcfad8 100644 --- a/blockdev.c +++ b/blockdev.c @@ -521,7 +521,7 @@ static int eject_device(Monitor *mon, BlockDriverState *bs, int force) int do_eject(Monitor *mon, const QDict *qdict, QObject **ret_data) { BlockDriverState *bs; -int force = qdict_get_int(qdict, "force"); +int force = qdict_get_try_bool(qdict, "force", 0); const char *filename = qdict_get_str(qdict, "device"); bs = bdrv_find(filename); diff --git a/migration.c b/migration.c index b49964c..650eb78 100644 --- a/migration.c +++ b/migration.c @@ -75,7 +75,9 @@ int do_migrate(Monitor *mon, const QDict *qdict, QObject **ret_data) { MigrationState *s = NULL; const char *p; -int detach = qdict_get_int(qdict, "detach"); +int detach = qdict_get_try_bool(qdict, "detach", 0); +int blk = qdict_get_try_bool(qdict, "blk", 0); +int inc = qdict_get_try_bool(qdict, "inc", 0); const char *uri = qdict_get_str(qdict, "uri"); if (current_migration && @@ -86,21 +88,17 @@ int do_migrate(Monitor *mon, const QDict *qdict, QObject **ret_data) if (strstart(uri, "tcp:", &p)) { s = tcp_start_outgoing_migration(mon, p, max_throttle, detach, - (int)qdict_get_int(qdict, "blk"), - (int)qdict_get_int(qdict, "inc")); + blk, inc); #if !defined(WIN32) } else if (strstart(uri, "exec:", &p)) { s = exec_start_outgoing_migration(mon, p, max_throttle, detach, - (int)qdict_get_int(qdict, "blk"), - (int)qdict_get_int(qdict, "inc")); + blk, inc); } else if (strstart(uri, "unix:", &p)) { s = unix_start_outgoing_migration(mon, p, max_throttle, detach, - (int)qdict_get_int(qdict, "blk"), - (int)qdict_get_int(qdict, "inc")); + blk, inc); } else if (strstart(uri, "fd:", &p)) { s = fd_start_outgoing_migration(mon, p, max_throttle, detach, -(int)qdict_get_int(qdict, "blk"), -(int)qdict_get_int(qdict, "inc")); +blk, inc); #endif } else { monitor_printf(mon, "unknown migration protocol: %s\n", uri); diff --git a/monitor.c b/monitor.c index ba7d5d9..5084a6e 100644 --- a/monitor.c +++ b/monitor.c @@ -3565,7 +3565,7 @@ static const mon_cmd_t *monitor_parse_command(Monitor *mon, case '-': { const char *tmp = p; -int has_option, skip_key = 0; +int skip_key = 0; /* option */ c = *typestr++; @@ -3573,7 +3573,6 @@ static const mon_cmd_t *monitor_parse_command(Monitor *mon, goto bad_type; while (qemu_isspace(*p)) p++; -has_option = 0; if (*p == '-') { p++; if(c != *p) { @@ -3589,11 +3588,11 @@ static const mon
[Qemu-devel] [PATCH 09/14] QMP: New argument checker (second part)
This commit introduces the second (and last) part of QMP's new argument checker. The job is done by check_client_args_type(), it iterates over the client's argument qdict and for for each argument it checks if it exists and if its type is valid. It's important to observe the following changes from the existing argument checker: - If the handler accepts an O-type argument, unknown arguments are passed down to it. It's up to O-type handlers to validate their arguments - Boolean types (eg. 'b' and '-') don't accept integers anymore, only json-bool - Argument types '/' and '.' are currently unsupported under QMP, thus they're not handled Signed-off-by: Luiz Capitulino --- monitor.c | 94 - 1 files changed, 93 insertions(+), 1 deletions(-) diff --git a/monitor.c b/monitor.c index edc362f..602ccdd 100644 --- a/monitor.c +++ b/monitor.c @@ -4144,6 +4144,95 @@ static int invalid_qmp_mode(const Monitor *mon, const char *cmd_name) } /* + * Argument validation rules: + * + * 1. The argument must exist in cmd_args qdict + * 2. The argument type must be the expected one + * + * Special case: If the argument doesn't exist in cmd_args and + * the QMP_ACCEPT_UNKNOWNS flag is set, then the + * checking is skipped for it. + */ +static int check_client_args_type(const QDict *client_args, + const QDict *cmd_args, int flags) +{ +const QDictEntry *ent; + +for (ent = qdict_first(client_args); ent;ent = qdict_next(client_args,ent)){ +QObject *obj; +QString *arg_type; +const QObject *client_arg = qdict_entry_value(ent); +const char *client_arg_name = qdict_entry_key(ent); + +obj = qdict_get(cmd_args, client_arg_name); +if (!obj) { +if (flags & QMP_ACCEPT_UNKNOWNS) { +/* handler accepts unknowns */ +continue; +} +/* client arg doesn't exist */ +qerror_report(QERR_INVALID_PARAMETER, client_arg_name); +return -1; +} + +arg_type = qobject_to_qstring(obj); +assert(arg_type != NULL); + +/* check if argument's type is correct */ +switch (qstring_get_str(arg_type)[0]) { +case 'F': +case 'B': +case 's': +if (qobject_type(client_arg) != QTYPE_QSTRING) { +qerror_report(QERR_INVALID_PARAMETER_TYPE, client_arg_name, + "string"); +return -1; +} +break; +case 'i': +case 'l': +case 'M': +if (qobject_type(client_arg) != QTYPE_QINT) { +qerror_report(QERR_INVALID_PARAMETER_TYPE, client_arg_name, + "int"); +return -1; +} +break; +case 'f': +case 'T': +if (qobject_type(client_arg) != QTYPE_QINT && +qobject_type(client_arg) != QTYPE_QFLOAT) { +qerror_report(QERR_INVALID_PARAMETER_TYPE, client_arg_name, + "number"); + return -1; +} +break; +case 'b': +case '-': +if (qobject_type(client_arg) != QTYPE_QBOOL) { +qerror_report(QERR_INVALID_PARAMETER_TYPE, client_arg_name, + "bool"); + return -1; +} +break; +case 'O': +assert(flags & QMP_ACCEPT_UNKNOWNS); +break; +case '/': +case '.': +/* + * These types are not supported by QMP and thus are not + * handled here. Fall through. + */ +default: +abort(); +} +} + +return 0; +} + +/* * - Check if the client has passed all mandatory args * - Set special flags for argument validation */ @@ -4220,6 +4309,9 @@ out: * Client argument checking rules: * * 1. Client must provide all mandatory arguments + * 2. Each argument provided by the client must be expected + * 3. Each argument provided by the client must have the type expected + *by the command */ static int qmp_check_client_args(const mon_cmd_t *cmd, QDict *client_args) { @@ -4234,7 +4326,7 @@ static int qmp_check_client_args(const mon_cmd_t *cmd, QDict *client_args) goto out; } -/* TODO: Check client args type */ +err = check_client_args_type(client_args, cmd_args, flags); out: QDECREF(cmd_args); -- 1.7.1.359.gd0b8d
[Qemu-devel] [PATCH v3 00/14]: QMP: Replace client argument checker
Current QMP's client argument checker code is more complex than it should be and has a flaw: it ignores unknown arguments. This series solves both problems by introducing a new, simple and ultra-poweful argument checker. This wasn't trivial to get right due to the number of errors combinations, so review is very appreciated. changelog - v2 -> v3 - Move all input object checking into qmp_check_input_obj() - Fix remaining problem with the handling of O-type arguments - Small renames suggested by Markus - Small cleanup in handle_qmp_command() v1 -> v2 - Introduce new iteration API and use it - Handle O-type correctly (I hope so) - Address several small issues found by Markus
[Qemu-devel] [PATCH 01/14] QDict: Rename 'err_value'
A missing key is not an error. Signed-off-by: Luiz Capitulino --- qdict.c |6 +++--- qdict.h |2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/qdict.c b/qdict.c index 175bc17..c974d6f 100644 --- a/qdict.c +++ b/qdict.c @@ -272,16 +272,16 @@ const char *qdict_get_str(const QDict *qdict, const char *key) * * Return integer mapped by 'key', if it is not present in * the dictionary or if the stored object is not of QInt type - * 'err_value' will be returned. + * 'def_value' will be returned. */ int64_t qdict_get_try_int(const QDict *qdict, const char *key, - int64_t err_value) + int64_t def_value) { QObject *obj; obj = qdict_get(qdict, key); if (!obj || qobject_type(obj) != QTYPE_QINT) -return err_value; +return def_value; return qint_get_int(qobject_to_qint(obj)); } diff --git a/qdict.h b/qdict.h index 5e5902c..72ea563 100644 --- a/qdict.h +++ b/qdict.h @@ -56,7 +56,7 @@ QList *qdict_get_qlist(const QDict *qdict, const char *key); QDict *qdict_get_qdict(const QDict *qdict, const char *key); const char *qdict_get_str(const QDict *qdict, const char *key); int64_t qdict_get_try_int(const QDict *qdict, const char *key, - int64_t err_value); + int64_t def_value); const char *qdict_get_try_str(const QDict *qdict, const char *key); #endif /* QDICT_H */ -- 1.7.1.359.gd0b8d
[Qemu-devel] Re: [PATCH] win32: Add missing function ffs
Am 12.06.2010 16:07, schrieb Stefan Weil: mingw32 does not include function ffs. Commit c6d29ad6e24533cc3762e1d654275607e1d03058 added a declaration for ffs, but an implementation was missing. For compilations with optimization, the compiler creates inline code, so the implementation is not always needed. Without optimization, linking fails without this patch. v2: Use __builtin_ffs as suggested by Richard Henderson Cc: Richard Henderson Signed-off-by: Stefan Weil --- osdep.c |7 +++ 1 files changed, 7 insertions(+), 0 deletions(-) diff --git a/osdep.c b/osdep.c index abbc8a2..dbf872a 100644 --- a/osdep.c +++ b/osdep.c @@ -167,6 +167,13 @@ int qemu_create_pidfile(const char *filename) #ifdef _WIN32 +/* mingw32 needs ffs for compilations without optimization. */ +int ffs(int i) +{ +/* Use gcc's builtin ffs. */ +return __builtin_ffs(i); +} + /* Offset between 1/1/1601 and 1/1/1970 in 100 nanosec units */ #define _W32_FT_OFFSET (1164447360ULL) Ping. The patch should be applied to qemu master. Thanks, Stefan
[Qemu-devel] [PATCH] win32: Add define for missing EPROTONOSUPPORT
mingw32 does not define EPROTONOSUPPORT (which is used by migration.c and maybe future patches), so add a definition which uses a supported errno value. Signed-off-by: Stefan Weil --- qemu-os-win32.h |4 1 files changed, 4 insertions(+), 0 deletions(-) diff --git a/qemu-os-win32.h b/qemu-os-win32.h index 6323f7f..2ff9f45 100644 --- a/qemu-os-win32.h +++ b/qemu-os-win32.h @@ -49,4 +49,8 @@ static inline void os_setup_post(void) {} static inline void os_set_line_buffering(void) {} static inline void os_set_proc_name(const char *dummy) {} +#if !defined(EPROTONOSUPPORT) +# define EPROTONOSUPPORT EINVAL +#endif + #endif -- 1.7.1
[Qemu-devel] [PATCH] .gitignore: Ignore libdis*, qemu-options.def
libdis, libdis-user and qemu-options.def are generated directories / files and should be ignored by git. Signed-off-by: Stefan Weil --- .gitignore |2 ++ 1 files changed, 2 insertions(+), 0 deletions(-) diff --git a/.gitignore b/.gitignore index fdfe2f0..ce66ed5 100644 --- a/.gitignore +++ b/.gitignore @@ -6,6 +6,7 @@ config-target.* *-darwin-user *-linux-user *-bsd-user +libdis* libhw32 libhw64 libuser @@ -21,6 +22,7 @@ qemu-img qemu-nbd qemu-nbd.8 qemu-nbd.pod +qemu-options.def qemu-options.texi qemu-img-cmds.texi qemu-img-cmds.h -- 1.7.1
Re: [Qemu-devel] Guest OS hangs on usb_add
On 06/24/10 02:42, Markus Armbruster wrote: > A botched up patch is often a pretty effective way to get somebody to > fix the thing correctly. OK, I gave it a shot and sent it to the list. Shoulda prolly added a disclaimer in case it blows something up ;) -TJ
Re: [Qemu-devel] [PATCH] poison TARGET_ for compile once.
On 06/24/2010 12:14 AM, Isaku Yamahata wrote: > QEMU_CFLAGS+=-I$(SRC_PATH)/linux-user > -I$(SRC_PATH)/linux-user/$(TARGET_ABI_DIR) > obj-y = main.o syscall.o strace.o mmap.o signal.o thunk.o \ > - elfload.o linuxload.o uaccess.o gdbstub.o cpu-uname.o \ > - qemu-malloc.o > + elfload.o linuxload.o uaccess.o gdbstub.o cpu-uname.o > > obj-$(TARGET_HAS_BFLT) += flatload.o > > @@ -302,6 +301,7 @@ obj-y += $(addprefix $(HWDIR)/, $(hw-obj-y)) > > endif # CONFIG_SOFTMMU > > +obj-y += qemu-malloc.o > obj-$(CONFIG_GDBSTUB_XML) += gdbstub-xml.o > Does this break BSD compile? That host still has qemu_malloc defined in bsd-user/mmap.c. r~
Re: [Qemu-devel] [PATCH 0/5] fbdev display driver + misc bits
On 06/15/2010 11:05 AM, Gerd Hoffmann wrote: > Hi, > > This patch series features the linux fbdev display driver and a few > more patches the fbdev driver depends on. Most of the patches have been > on the list before. If you wondered what they are good for -- here is > the big picture ;) > > As usual the individual patches carry more verbose descriptions. > > cheers, > Gerd > > Gerd Hoffmann (5): > QLIST-ify display change listeners. > add unregister_displaychangelistener > Fix and simplify gui timer logic. > add pflib: PixelFormat conversion library. > linux fbdev display driver. > > Makefile.objs|2 + > console.h| 82 +++-- > fbdev.c | 931 > ++ > hw/xenfb.c |2 +- > linux-keynames.h | 386 ++ > monitor.c| 14 + > pflib.c | 213 + > pflib.h | 20 ++ > qemu-options.hx | 10 + > sysemu.h |1 + > vl.c | 55 ++-- > 11 files changed, 1648 insertions(+), 68 deletions(-) > create mode 100644 fbdev.c > create mode 100644 linux-keynames.h > create mode 100644 pflib.c > create mode 100644 pflib.h > > Have anyone got the time to review this yet ? -- Julian
[Qemu-devel] Fwd: [PATCH] Guest OS hangs on usb_add
This is a small patch to sligtly "intelligentify" usb device and config descriptor parsing and to handle bug with certain usb device reporting device desriptor length as 0x18 (instead of 18) --- hw/usb.h|5 + usb-linux.c | 36 +--- 2 files changed, 26 insertions(+), 15 deletions(-) diff --git a/hw/usb.h b/hw/usb.h index 00d2802..5c3528f 100644 --- a/hw/usb.h +++ b/hw/usb.h @@ -117,6 +117,11 @@ #define USB_DT_INTERFACE 0x04 #define USB_DT_ENDPOINT0x05 +#define USB_DT_DEVICE_LEN 18 +#define USB_DT_CONFIG_LEN 9 +#define USB_DT_INTERFACE_LEN 9 +#define USB_DT_ENDPOINT_LEN7 + #define USB_ENDPOINT_XFER_CONTROL 0 #define USB_ENDPOINT_XFER_ISOC 1 #define USB_ENDPOINT_XFER_BULK 2 diff --git a/usb-linux.c b/usb-linux.c index 88273ff..3ff0856 100644 --- a/usb-linux.c +++ b/usb-linux.c @@ -288,7 +288,7 @@ static void async_cancel(USBPacket *unused, void *opaque) static int usb_host_claim_interfaces(USBHostDevice *dev, int configuration) { -int dev_descr_len, config_descr_len; +int dev_descr_len, config_descr_total_len; int interface, nb_interfaces; int ret, i; @@ -297,32 +297,38 @@ static int usb_host_claim_interfaces(USBHostDevice *dev, int configuration) DPRINTF("husb: claiming interfaces. config %d\n", configuration); -i = 0; dev_descr_len = dev->descr[0]; -if (dev_descr_len > dev->descr_len) { +if (dev_descr_len == 0x18) +dev_descr_len = USB_DT_DEVICE_LEN; /* for buggy device(s) reporting len in hex */ + +if (dev_descr_len > dev->descr_len || dev_descr_len < USB_DT_DEVICE_LEN || dev->descr[1] != USB_DT_DEVICE) { +fprintf(stderr, "husb: invalid device descriptor\n"); goto fail; } -i += dev_descr_len; -while (i < dev->descr_len) { +for (i = dev_descr_len; i < dev->descr_len; ) { DPRINTF("husb: i is %d, descr_len is %d, dl %d, dt %d\n", i, dev->descr_len, dev->descr[i], dev->descr[i+1]); -if (dev->descr[i+1] != USB_DT_CONFIG) { -i += dev->descr[i]; -continue; +if (dev->descr[i] < 2) { +fprintf(stderr, "husb: invalid descriptor\n"); +goto fail; } -config_descr_len = dev->descr[i]; +if (dev->descr[i+1] == USB_DT_CONFIG) { +config_descr_total_len = dev->descr[i+2] + (dev->descr[i+3] << 8); -printf("husb: config #%d need %d\n", dev->descr[i + 5], configuration); +printf("husb: config #%d need %d\n", dev->descr[i + 5], configuration); -if (configuration < 0 || configuration == dev->descr[i + 5]) { -configuration = dev->descr[i + 5]; -break; -} +if (configuration < 0 || configuration == dev->descr[i + 5]) { +configuration = dev->descr[i + 5]; +break; +} -i += config_descr_len; +i += config_descr_total_len; +} +else +i += dev->descr[i]; } if (i >= dev->descr_len) {
Re: [Qemu-devel] Guest OS hangs on usb_add
On 06/24/10 13:59, David S. Ahern wrote: > > > On 06/23/10 22:45, TJ wrote: >> >>> -- Forwarded message -- >>> From: Timothy Jones >>> Date: Wed, Jun 23, 2010 at 9:07 PM >>> Subject: Guest OS hangs on usb_add >>> To: qemu-devel@nongnu.org >>> >>> >>> With some digging around I found out that the qemu hangs in >>> usb_host_claim_interfaces, which is caused by screwed up usb >>> descriptor. The device reports the following: >>> >>> (gdb) p dev->descr_len >>> $21 = 50 >>> (gdb) p /x dev->descr...@50 >>> $23 = {0x18, 0x1, 0x0, 0x1, 0xff, 0xff, 0xff, 0x8, 0x47, 0x46, 0x0, >>> 0x30, 0x0, 0x0, 0x0, 0x0, 0x0, 0x1, 0x9, 0x2, 0x20, >>> 0x0, 0x1, 0x1, 0x0, 0x80, 0x19, 0x9, 0x4, 0x0, 0x0, 0x2, 0xff, 0xff, >>> 0xff, 0x0, 0x7, 0x5, 0x81, 0x2, 0x40, 0x0, 0x0, >>> 0x7, 0x5, 0x3, 0x2, 0x10, 0x0, 0x0} >>> >>> The first 0x18 (Device Descriptor bLength) is supposed to be decimal >>> 18, not hex! According to USB spec, if the device reports size greater >>> than expected, the host is supposed ignore the extra bytes. So qemu >>> behaves correctly here. However, with this length, the following >>> Configuration Descriptor length falls on a 0x0 and so the qemu spins >>> in an endless loop. (This is prolly something that should be detected >>> and reported as error by qemu.) >>> >>> My question is: This 0x18 -- is this something that comes from the >>> device itself (ie, firmware bug)? Or does it come from the USB >>> subsystem? > > What kind of device is this? > > David > Universal Remote Control MX-950 http://www.universalremote.com/product_detail.php?model=35 -TJ
[Qemu-devel] [Bug 571432] Re: qemu-system-arm crashed with SIGSEGV in subpage_register()
Does boot succeed if you add -net nic,model=rtl8139 to your qemu-system-arm arguments? ** Also affects: qemu Importance: Undecided Status: New -- qemu-system-arm crashed with SIGSEGV in subpage_register() https://bugs.launchpad.net/bugs/571432 You received this bug notification because you are a member of qemu- devel-ml, which is subscribed to QEMU. Status in QEMU: New Status in “qemu-kvm” package in Ubuntu: New Bug description: Binary package hint: qemu-kvm i think this is the crash behind Bug #570588 not sure why apport did not trigger before ProblemType: Crash DistroRelease: Ubuntu 10.04 Package: qemu-kvm-extras 0.12.3+noroms-0ubuntu9 ProcVersionSignature: Ubuntu 2.6.32-21.32-generic 2.6.32.11+drm33.2 Uname: Linux 2.6.32-21-generic x86_64 NonfreeKernelModules: openafs Architecture: amd64 Date: Wed Apr 28 21:30:13 2010 ExecutablePath: /usr/bin/qemu-system-arm InstallationMedia: Ubuntu 9.10 "Karmic Koala" - Release amd64 (20091027) KvmCmdLine: Error: command ['ps', '-C', 'kvm', '-F'] failed with exit code 1: UIDPID PPID CSZ RSS PSR STIME TTY TIME CMD ProcCmdLine: BOOT_IMAGE=/boot/vmlinuz-2.6.32-21-generic root=UUID=52d7f930-7148-4978-825e-71fcb9243ac6 ro quiet splash ProcCmdline: qemu-system-arm -M versatilepb -cpu cortex-a8 -kernel /tmp/tmp.B2CtSo2g2u/qemu-vmlinuz -no-reboot -nographic -pidfile /tmp/tmp.B2CtSo2g2u/qemu.pid -drive file=/tmp/tmp.B2CtSo2g2u/qemu-armel-201004282122.img,aio=native,cache=none -m 512 -append console=ttyAMA0,115200n8\ root=/dev/sda\ rw\ mem=256M\ devtmpfs.mount=0\ init=/bin/installer\ quiet ProcEnviron: SHELL=/bin/bash LANG=en_GB.UTF-8 SegvAnalysis: Segfault happened at: 0x51058e : cmpq $0x0,(%rdx) PC (0x0051058e) ok source "$0x0" ok destination "(%rdx)" (0x40cc28c0) not located in a known VMA region (needed writable region)! SegvReason: writing unknown VMA Signal: 11 SourcePackage: qemu-kvm StacktraceTop: subpage_register (mmio=0x7f841b26d010, start=, subpage_init (base=268500992, phys=0x1d47400, cpu_register_physical_memory_offset ( smc91c111_init (nd=0xc41b60, base=1087121600, versatile_init (ram_size=, Title: qemu-system-arm crashed with SIGSEGV in subpage_register() UserGroups: dmi.bios.date: 11/07/2007 dmi.bios.vendor: Phoenix Technologies LTD dmi.bios.version: 6.00 dmi.board.name: S2696 dmi.board.vendor: Tyan Computer Corporation dmi.chassis.type: 6 dmi.modalias: dmi:bvnPhoenixTechnologiesLTD:bvr6.00:bd11/07/2007:svn:pn:pvr:rvnTyanComputerCorporation:rnS2696:rvr:cvn:ct6:cvr:
Re: [Qemu-devel] Guest OS hangs on usb_add
On 06/23/10 22:45, TJ wrote: > >> -- Forwarded message -- >> From: Timothy Jones >> Date: Wed, Jun 23, 2010 at 9:07 PM >> Subject: Guest OS hangs on usb_add >> To: qemu-devel@nongnu.org >> >> >> With some digging around I found out that the qemu hangs in >> usb_host_claim_interfaces, which is caused by screwed up usb >> descriptor. The device reports the following: >> >> (gdb) p dev->descr_len >> $21 = 50 >> (gdb) p /x dev->descr...@50 >> $23 = {0x18, 0x1, 0x0, 0x1, 0xff, 0xff, 0xff, 0x8, 0x47, 0x46, 0x0, >> 0x30, 0x0, 0x0, 0x0, 0x0, 0x0, 0x1, 0x9, 0x2, 0x20, >> 0x0, 0x1, 0x1, 0x0, 0x80, 0x19, 0x9, 0x4, 0x0, 0x0, 0x2, 0xff, 0xff, >> 0xff, 0x0, 0x7, 0x5, 0x81, 0x2, 0x40, 0x0, 0x0, >> 0x7, 0x5, 0x3, 0x2, 0x10, 0x0, 0x0} >> >> The first 0x18 (Device Descriptor bLength) is supposed to be decimal >> 18, not hex! According to USB spec, if the device reports size greater >> than expected, the host is supposed ignore the extra bytes. So qemu >> behaves correctly here. However, with this length, the following >> Configuration Descriptor length falls on a 0x0 and so the qemu spins >> in an endless loop. (This is prolly something that should be detected >> and reported as error by qemu.) >> >> My question is: This 0x18 -- is this something that comes from the >> device itself (ie, firmware bug)? Or does it come from the USB >> subsystem? What kind of device is this? David
[Qemu-devel] [PATCHv3] virtio-net: correct packet length math
We were requesting too much when checking buffer length: size already includes host header length. Further, we should not exit if we get a packet that is too long, since this might not be under control of the guest. Just drop the packet. Red Hat bz 591494 Signed-off-by: Michael S. Tsirkin --- Changes from v2: fixed format warning. Changes from v1: drop packet instead of exit. hw/virtio-net.c | 41 - 1 files changed, 28 insertions(+), 13 deletions(-) diff --git a/hw/virtio-net.c b/hw/virtio-net.c index 06ba481..1018c32 100644 --- a/hw/virtio-net.c +++ b/hw/virtio-net.c @@ -527,17 +527,18 @@ static ssize_t virtio_net_receive(VLANClientState *nc, const uint8_t *buf, size_ { VirtIONet *n = DO_UPCAST(NICState, nc, nc)->opaque; struct virtio_net_hdr_mrg_rxbuf *mhdr = NULL; -size_t hdr_len, offset, i; +size_t guest_hdr_len, offset, i, host_hdr_len; if (!virtio_net_can_receive(&n->nic->nc)) return -1; /* hdr_len refers to the header we supply to the guest */ -hdr_len = n->mergeable_rx_bufs ? +guest_hdr_len = n->mergeable_rx_bufs ? sizeof(struct virtio_net_hdr_mrg_rxbuf) : sizeof(struct virtio_net_hdr); -if (!virtio_net_has_buffers(n, size + hdr_len)) +host_hdr_len = n->has_vnet_hdr ? sizeof(struct virtio_net_hdr) : 0; +if (!virtio_net_has_buffers(n, size + guest_hdr_len - host_hdr_len)) return 0; if (!receive_filter(n, buf, size)) @@ -552,13 +553,14 @@ static ssize_t virtio_net_receive(VLANClientState *nc, const uint8_t *buf, size_ total = 0; -if ((i != 0 && !n->mergeable_rx_bufs) || -virtqueue_pop(n->rx_vq, &elem) == 0) { +if (virtqueue_pop(n->rx_vq, &elem) == 0) { if (i == 0) return -1; -fprintf(stderr, "virtio-net truncating packet: " -"offset %zd, size %zd, hdr_len %zd\n", -offset, size, hdr_len); +fprintf(stderr, "virtio-net unexpected empty queue: " +"i %zd mergeable %d offset %zd, size %zd, " +"guest hdr len %zd, host hdr len %zd guest features 0x%x\n", +i, n->mergeable_rx_bufs, offset, size, +guest_hdr_len, host_hdr_len, n->vdev.guest_features); exit(1); } @@ -567,7 +569,7 @@ static ssize_t virtio_net_receive(VLANClientState *nc, const uint8_t *buf, size_ exit(1); } -if (!n->mergeable_rx_bufs && elem.in_sg[0].iov_len != hdr_len) { +if (!n->mergeable_rx_bufs && elem.in_sg[0].iov_len != guest_hdr_len) { fprintf(stderr, "virtio-net header not in first element\n"); exit(1); } @@ -579,19 +581,32 @@ static ssize_t virtio_net_receive(VLANClientState *nc, const uint8_t *buf, size_ mhdr = (struct virtio_net_hdr_mrg_rxbuf *)sg[0].iov_base; offset += receive_header(n, sg, elem.in_num, - buf + offset, size - offset, hdr_len); -total += hdr_len; + buf + offset, size - offset, guest_hdr_len); +total += guest_hdr_len; } /* copy in packet. ugh */ len = iov_from_buf(sg, elem.in_num, buf + offset, size - offset); total += len; +offset += len; +/* If buffers can't be merged, at this point we + * must have consumed the complete packet. + * Otherwise, drop it. */ +if (!n->mergeable_rx_bufs && offset < size) { +#if 0 +fprintf(stderr, "virtio-net truncated non-mergeable packet: " + +"i %zd mergeable %d offset %zd, size %zd, " +"guest hdr len %zd, host hdr len %zd\n", +i, n->mergeable_rx_bufs, +offset, size, guest_hdr_len, host_hdr_len); +#endif +return size; +} /* signal other side */ virtqueue_fill(n->rx_vq, &elem, total, i++); - -offset += len; } if (mhdr) -- 1.7.1.12.g42b7f
[Qemu-devel] [PATCHv2] virtio-net: correct packet length checks
We were requesting too much when checking buffer length: size already includes host header length. Further, we should not exit if we get a packet that is too long, since this might not be under control of the guest. Just drop the packet. Red Hat bz 591494 Signed-off-by: Michael S. Tsirkin --- This supercedes the patch virtio-net: correct header length checks Changes from v1: address review comments hw/virtio-net.c | 41 - 1 files changed, 28 insertions(+), 13 deletions(-) diff --git a/hw/virtio-net.c b/hw/virtio-net.c index 06ba481..e28d2bd 100644 --- a/hw/virtio-net.c +++ b/hw/virtio-net.c @@ -527,17 +527,18 @@ static ssize_t virtio_net_receive(VLANClientState *nc, const uint8_t *buf, size_ { VirtIONet *n = DO_UPCAST(NICState, nc, nc)->opaque; struct virtio_net_hdr_mrg_rxbuf *mhdr = NULL; -size_t hdr_len, offset, i; +size_t guest_hdr_len, offset, i, host_hdr_len; if (!virtio_net_can_receive(&n->nic->nc)) return -1; /* hdr_len refers to the header we supply to the guest */ -hdr_len = n->mergeable_rx_bufs ? +guest_hdr_len = n->mergeable_rx_bufs ? sizeof(struct virtio_net_hdr_mrg_rxbuf) : sizeof(struct virtio_net_hdr); -if (!virtio_net_has_buffers(n, size + hdr_len)) +host_hdr_len = n->has_vnet_hdr ? sizeof(struct virtio_net_hdr) : 0; +if (!virtio_net_has_buffers(n, size + guest_hdr_len - host_hdr_len)) return 0; if (!receive_filter(n, buf, size)) @@ -552,13 +553,14 @@ static ssize_t virtio_net_receive(VLANClientState *nc, const uint8_t *buf, size_ total = 0; -if ((i != 0 && !n->mergeable_rx_bufs) || -virtqueue_pop(n->rx_vq, &elem) == 0) { +if (virtqueue_pop(n->rx_vq, &elem) == 0) { if (i == 0) return -1; -fprintf(stderr, "virtio-net truncating packet: " -"offset %zd, size %zd, hdr_len %zd\n", -offset, size, hdr_len); +fprintf(stderr, "virtio-net unexpected empty queue: " +"i %d mergeable %d offset %zd, size %zd, " +"guest hdr len %zd, host hdr len %zd guest features 0x%x\n", +i, n->mergeable_rx_bufs, offset, size, +guest_hdr_len, host_hdr_len, n->vdev.guest_features); exit(1); } @@ -567,7 +569,7 @@ static ssize_t virtio_net_receive(VLANClientState *nc, const uint8_t *buf, size_ exit(1); } -if (!n->mergeable_rx_bufs && elem.in_sg[0].iov_len != hdr_len) { +if (!n->mergeable_rx_bufs && elem.in_sg[0].iov_len != guest_hdr_len) { fprintf(stderr, "virtio-net header not in first element\n"); exit(1); } @@ -579,19 +581,32 @@ static ssize_t virtio_net_receive(VLANClientState *nc, const uint8_t *buf, size_ mhdr = (struct virtio_net_hdr_mrg_rxbuf *)sg[0].iov_base; offset += receive_header(n, sg, elem.in_num, - buf + offset, size - offset, hdr_len); -total += hdr_len; + buf + offset, size - offset, guest_hdr_len); +total += guest_hdr_len; } /* copy in packet. ugh */ len = iov_from_buf(sg, elem.in_num, buf + offset, size - offset); total += len; +offset += len; +/* If buffers can't be merged, at this point we + * must have consumed the complete packet. + * Otherwise, drop it. */ +if (!n->mergeable_rx_bufs && offset < size) { +#if 0 +fprintf(stderr, "virtio-net truncated non-mergeable packet: " + +"i %d mergeable %d offset %zd, size %zd, " +"guest hdr len %zd, host hdr len %zd\n", +i, n->mergeable_rx_bufs, +offset, size, guest_hdr_len, host_hdr_len); +#endif +return size; +} /* signal other side */ virtqueue_fill(n->rx_vq, &elem, total, i++); - -offset += len; } if (mhdr) -- 1.7.1.12.g42b7f
Re: [Qemu-devel] [PATCH 00/15] Make migration work with hotplug
On Thu, 2010-06-24 at 09:04 -0600, Alex Williamson wrote: > On Thu, 2010-06-24 at 15:02 +0900, Yoshiaki Tamura wrote: > > > > Hi Alex, > > > > Is there additional overhead to save rams introduce by this series? > > If so, how much? > > Yes, there is overhead, but it's typically quite small. If I migrate a > 1G VM immediately after I boot to a login prompt (lots of zero pages), I > get an overhead of 0.76%. That's only 226 extra bytes over the > 297164995 bytes otherwise transferred. If I build a kernel on the guest > and migrate during the compilation, the overhead is 0.19%. The > overhead is tiny largely due to patch 12/15, which avoids sending the > block name if we're working within the same block as sent previously. > If I disable this optimization, the overhead goes up to 0.93% after boot > and 0.26% during a kernel compile. > > Note that an x86 VM does a separate qemu_ram_alloc for memory above 4G, > which means in bigger VMs we may end up needing to resend the ramblock > name once in a while as we bounce between above and below 4G. Worst > case for this could match the 0.26% above, but in my testing during a > kernel compile, this seems to increase the overhead to 0.26% on a 6G > VM. I don't see any reason why we couldn't allocate all the ram in a > single qemu_ram_alloc call, so I'll add another patch to make that > change (which will also shorten the name to "pc.ram" for even less > overhead ;). Thanks, FWIW, with this change, my migration during kernel compile on the 6G VM seems to be running just at 0.19%-0.20%, so that eliminates the penalty for bigger memory VMs. Thanks, Alex
[Qemu-devel] Re: [RFC v4][PATCH 0/3] Monitor support for Qemu tracing
On Thu, Jun 24, 2010 at 04:49:30PM +0530, Prerna Saxena wrote: > This set of patches enables trace visualization & control > via the QEMU monitor. It is based on trace infrastructure posted > upstream : > ( http://lists.gnu.org/archive/html/qemu-devel/2010-05/msg02407.html ) > > This patchset adds monitor commands : > - info trace : to view current contents of the trace buffer > - info tracepoints : to view all available tracepoints and their state. > - tracepoint NAME on|off : to enable/disable the logging of dataThis is v3 of > a set of patches to enable trace visualization & control > via the QEMU monitor. > > Changelog from v3: > 1. As suggested, it replaces a hash-based search of tracepoints > with a linear search. > 2. Static initialization of trace event array. > 3. Cleanups. > > Changelog from v2: > 1. Clean-ups, particularly relating to export of tdb_hash(). > > Changelog from v1: > 1. Command 'info trace' is used to view current contents of buffer, in > place of 'trace'. > 2. Cleanups Applied, thanks! http://repo.or.cz/w/qemu/stefanha.git/shortlog/refs/heads/tracing I'd like to focus on polishing the current tracing branch into a patchset that can be merged into QEMU. Having this working prototype enables us to try tracing out; we can commit fixes on top and then squish the commits down for QEMU merge when the basic feature set is solid. > Todos : > 1. Integration with QMP > 2. More tracepoints need to be added for instrumenting other qemu components > such as virtio drivers, etc. I am copying these to another email thread so we can discuss what needs to be done to get tracing merged. Stefan
[Qemu-devel] Re: [PATCH 12/15] savevm: Create a new continue flag to avoid resending block name
On Thu, 2010-06-24 at 07:51 +0200, Paolo Bonzini wrote: > > @@ -377,26 +398,11 @@ int ram_load(QEMUFile *f, void *opaque, int > > version_id) > > } else if (flags& RAM_SAVE_FLAG_PAGE) { > > void *host; > > > > -if (version_id == 3) { > > +if (version_id == 3) > > host = qemu_get_ram_ptr(addr); > > -} else { > > -RAMBlock *block; > > -char id[256]; > > -uint8_t len; > > +else > > +host = host_from_stream_offset(f, addr, flags); > > > > -len = qemu_get_byte(f); > > -qemu_get_buffer(f, (uint8_t *)id, len); > > -id[len] = 0; > > - > > -QLIST_FOREACH(block,&ram_list.blocks, next) { > > -if (!strncmp(id, block->idstr, sizeof(id))) > > -break; > > -} > > -if (!block) > > -return -EINVAL; > > - > > -host = block->host + addr; > > -} > > qemu_get_buffer(f, host, TARGET_PAGE_SIZE); > > } > > if (qemu_file_has_error(f)) { > > Gah, sorry. :) > > This also takes care of the code duplication, great. It was certainly a good thought ;) See my reply to Yoshi for the overhead saved. Thanks, Alex
Re: [Qemu-devel] [PATCH 03/15] pci: Implement BusInfo.get_dev_path()
On Thu, 2010-06-24 at 16:39 +0900, Isaku Yamahata wrote: > On Wed, Jun 23, 2010 at 10:41:13PM -0600, Alex Williamson wrote: > > This works great for PCI since a ::. uniquely > > describes a global address. No need to traverse up the qdev tree. > > PCI segment support is a placeholder for compatibility once we > > support multiple segments. > > > > Signed-off-by: Alex Williamson > > --- > > > > hw/pci.c | 14 ++ > > 1 files changed, 14 insertions(+), 0 deletions(-) > > > > diff --git a/hw/pci.c b/hw/pci.c > > index 7787005..5c9d6b4 100644 > > --- a/hw/pci.c > > +++ b/hw/pci.c > > @@ -58,11 +58,13 @@ struct PCIBus { > > }; > > > > static void pcibus_dev_print(Monitor *mon, DeviceState *dev, int indent); > > +static char *pcibus_get_dev_path(DeviceState *dev); > > > > static struct BusInfo pci_bus_info = { > > .name = "PCI", > > .size = sizeof(PCIBus), > > .print_dev = pcibus_dev_print, > > +.get_dev_path = pcibus_get_dev_path, > > .props = (Property[]) { > > DEFINE_PROP_PCI_DEVFN("addr", PCIDevice, devfn, -1), > > DEFINE_PROP_STRING("romfile", PCIDevice, romfile), > > @@ -1853,6 +1855,18 @@ static void pcibus_dev_print(Monitor *mon, > > DeviceState *dev, int indent) > > } > > } > > > > +static char *pcibus_get_dev_path(DeviceState *dev) > > +{ > > +PCIDevice *d = (PCIDevice *)dev; > > +char path[16]; > > + > > +snprintf(path, sizeof(path), "%04x:%02x:%02x.%x", > > + 0 /* FIXME for segment support */, > > d->config[PCI_SECONDARY_BUS], > > pci_find_domain(d->bus) Thank you Isaku, I'll make the change. Alex
Re: [Qemu-devel] [PATCH 00/15] Make migration work with hotplug
On Thu, 2010-06-24 at 15:02 +0900, Yoshiaki Tamura wrote: > > Hi Alex, > > Is there additional overhead to save rams introduce by this series? > If so, how much? Yes, there is overhead, but it's typically quite small. If I migrate a 1G VM immediately after I boot to a login prompt (lots of zero pages), I get an overhead of 0.76%. That's only 226 extra bytes over the 297164995 bytes otherwise transferred. If I build a kernel on the guest and migrate during the compilation, the overhead is 0.19%. The overhead is tiny largely due to patch 12/15, which avoids sending the block name if we're working within the same block as sent previously. If I disable this optimization, the overhead goes up to 0.93% after boot and 0.26% during a kernel compile. Note that an x86 VM does a separate qemu_ram_alloc for memory above 4G, which means in bigger VMs we may end up needing to resend the ramblock name once in a while as we bounce between above and below 4G. Worst case for this could match the 0.26% above, but in my testing during a kernel compile, this seems to increase the overhead to 0.26% on a 6G VM. I don't see any reason why we couldn't allocate all the ram in a single qemu_ram_alloc call, so I'll add another patch to make that change (which will also shorten the name to "pc.ram" for even less overhead ;). Thanks, Alex
[Qemu-devel] [Bug 543478] Re: qemus pmemsave doesn't accept "/" in filename
Muelli: I agree that a help message about quoting pathnames would be useful. Please work with the upstream mailing list to do so. A small patch to qemu-monitor.hx should suffice, but you'll need to interact with the qemu-devel@nongnu.org mailing list. ** Changed in: qemu-kvm (Ubuntu) Status: New => Incomplete -- qemus pmemsave doesn't accept "/" in filename https://bugs.launchpad.net/bugs/543478 You received this bug notification because you are a member of qemu- devel-ml, which is subscribed to QEMU. Status in QEMU: Invalid Status in “qemu-kvm” package in Ubuntu: Incomplete Bug description: Binary package hint: qemu-kvm Please see my conversation with qemu: (qemu) pmemsave unexpected end of expression (qemu) help pmemsave pmemsave addr size file -- save to disk physical memory dump starting at 'addr' of size 'size' (qemu) pmemsave 0 512M /tmp/qemu.mem pmemsave: extraneous characters at the end of line (qemu) pmemsave 0 512 /tmp/qemu.mem invalid char in expression (qemu) pmemsave 0 512 /tmp/qemu invalid char in expression (qemu) pmemsave 0 512 qemu.mem (qemu) pmemsave 0 512M qemu.mem pmemsave: extraneous characters at the end of line Let me comment on each one of those: (qemu) pmemsave unexpected end of expression I expected some sort of hint as to where to get more information. Maybe just a "Type ``help pmemsave'' to get syntax information" would be sufficient. (qemu) help pmemsave pmemsave addr size file -- save to disk physical memory dump starting at 'addr' of size 'size' Nice. But an example would be nice. My proposal: "I.e.: pmemsave 0 1G /tmp/qemu.mem" (qemu) pmemsave 0 512M /tmp/qemu.mem pmemsave: extraneous characters at the end of line eh. Would be nice if it told me *which* character was "extraneous" and what "extraneous" means. My proposal: "Couldn't parse character at position 23, please see help pmemsave for an example". (qemu) pmemsave 0 512 /tmp/qemu.mem invalid char in expression Hm. Interesting. Again, would be nice if it printed me the offending character. My proposal: "Could not parse character at position 23, please see help pmemsave for an example". (qemu) pmemsave 0 512 /tmp/qemu invalid char in expression Now I got rid of almost everything but it still doesn't work. (qemu) pmemsave 0 512 qemu.mem aha! No slashes?! Seriously? (qemu) pmemsave 0 512M qemu.mem pmemsave: extraneous characters at the end of line And no "M" or "G" modifiers? If I want to dump 2GB then I'd have to calculate the number in bytes and paste that long string. I expected qemu to be able to parse the K, M, G suffixes. Also, I'm wondering why it doesn't offer to dump all memory. ProblemType: Bug Architecture: amd64 CurrentDmesg: [150870.676062] kvm_intel: Unknown symbol kvm_vcpu_on_spin [150947.222923] cron[24260]: segfault at 0 ip (null) sp 7fffe865eed8 error 14 in cron[40+9000] [150947.224187] cron[24261]: segfault at 0 ip (null) sp 7fffe865eed8 error 14 in cron[40+9000] Date: Sun Mar 21 15:03:13 2010 DistroRelease: Ubuntu 9.10 KvmCmdLine: UIDPID PPID CSZ RSS PSR STIME TTY TIME CMD muelli 23807 23806 13 239738 228464 0 14:54 pts/800:01:22 /usr/bin/kvm -S -M pc -m 512 -smp 1 -name vanilla_ubuntu -monitor stdio -boot c -drive file=/home/muelli/qemu/ubuntu8.10/ubuntu.img,if=ide,index=0,boot=on -drive file=,if=ide,media=cdrom,index=2 -net nic,model=rtl8139,macaddr=f0:00:BA:12:34:56 -net user,hostfwd=tcp::2223-:22,smb=/tmp/share -serial pty -snapshot MachineType: LENOVO 766636G Package: kvm 1:84+dfsg-0ubuntu16+0.11.0+0ubuntu6.3 PccardctlIdent: Socket 0: no product info available PccardctlStatus: Socket 0: no card ProcCmdLine: root=/dev/mapper/cryptroot source=UUID=9c3d5596-27c6-4fd5-bfcd-fa8eef6f1230 ro vdso32=0 quiet splash crashkernel=384M-2G:64M,2G-:128M ProcVersionSignature: Ubuntu 2.6.32-16.24-generic SourcePackage: qemu-kvm Uname: Linux 2.6.32-16-generic x86_64 dmi.bios.date: 03/12/2009 dmi.bios.vendor: LENOVO dmi.bios.version: 7NETC0WW (2.20 ) dmi.board.name: 766636G dmi.board.vendor: LENOVO dmi.board.version: Not Available dmi.chassis.asset.tag: No Asset Information dmi.chassis.type: 10 dmi.chassis.vendor: LENOVO dmi.chassis.version: Not Available dmi.modalias: dmi:bvnLENOVO:bvr7NETC0WW(2.20):bd03/12/2009:svnLENOVO:pn766636G:pvrThinkPadX61:rvnLENOVO:rn766636G:rvrNotAvailable:cvnLENOVO:ct10:cvrNotAvailable: dmi.product.name: 766636G dmi.product.version: ThinkPad X61 dmi.sys.vendor: LENOVO
Re: [Qemu-devel] [PATCH] net: Fix VM start with '-net none'
On Tue, Jun 15, 2010 at 9:00 AM, Amit Shah wrote: > Commit 50e32ea8f31035877decc10f1075aa0e619e09cb changed the behaviour > for the return type of net_client_init() when a nic type with no init > method was specified. 'none' is one such nic type. Instead of returning > 0, which gets interpreted as an index into the nd_table[] array, we > switched to returning -1, which signifies an error as well. > > That broke VM start with '-net none'. Testing was only done with the > monitor command 'pci_add', which doesn't fail. I stumbled across the broken -net none in qemu.git and qemu-kvm.git. It does a silent exit(1) on startup. It would be nice to merge this patch. Stefan
[Qemu-devel] [RFC v4][PATCH 3/3] Support for dynamically enabling/disabling trace events.
This patch adds support for dynamically enabling/disabling of trace events. This is done by internally maintaining each trace event's state, and permitting logging of data from a trace event only if it is in an 'active' state. Monitor commands added : 1) info trace-events: to view all available trace events and their state. 2) trace-event NAME on|off : to enable/disable data logging from a given trace event. Eg, trace-event paio_submit off disables logging of data when paio_submit is hit. By default, all trace-events are disabled. One can enable desired trace-events via the monitor. Signed-off-by: Prerna Saxena --- monitor.c | 16 qemu-monitor.hx | 18 ++ simpletrace.c | 41 + tracetool | 33 + 4 files changed, 104 insertions(+), 4 deletions(-) diff --git a/monitor.c b/monitor.c index 8b60830..19b1ed7 100644 --- a/monitor.c +++ b/monitor.c @@ -548,6 +548,15 @@ static void do_commit(Monitor *mon, const QDict *qdict) } } +#ifdef CONFIG_SIMPLE_TRACE +static void do_change_trace_event_state(Monitor *mon, const QDict *qdict) +{ +const char *tp_name = qdict_get_str(qdict, "name"); +bool new_state = qdict_get_bool(qdict, "option"); +change_trace_event_state(tp_name, new_state); +} +#endif + static void user_monitor_complete(void *opaque, QObject *ret_data) { MonitorCompletionData *data = (MonitorCompletionData *)opaque; @@ -2791,6 +2800,13 @@ static const mon_cmd_t info_cmds[] = { .help = "show current contents of trace buffer", .mhandler.info = do_info_trace, }, +{ +.name = "trace-events", +.args_type = "", +.params = "", +.help = "show available trace-events & their state", +.mhandler.info = do_info_all_trace_events, +}, #endif { .name = NULL, diff --git a/qemu-monitor.hx b/qemu-monitor.hx index 766c30f..0fedcf9 100644 --- a/qemu-monitor.hx +++ b/qemu-monitor.hx @@ -117,6 +117,8 @@ show device tree #ifdef CONFIG_SIMPLE_TRACE @item info trace show contents of trace buffer +...@item info trace-events +show available trace events and their state #endif @end table ETEXI @@ -225,6 +227,22 @@ STEXI @item logfile @var{filename} @findex logfile Output logs to @var{filename}. +#ifdef CONFIG_SIMPLE_TRACE +ETEXI + +{ +.name = "trace-event", +.args_type = "name:s,option:b", +.params = "name on|off", +.help = "changes status of a specific trace event", +.mhandler.cmd = do_change_trace_event_state, +}, + +STEXI +...@item trace-event +...@findex trace-event +changes status of a trace event +#endif ETEXI { diff --git a/simpletrace.c b/simpletrace.c index 5734d15..57c41fc 100644 --- a/simpletrace.c +++ b/simpletrace.c @@ -24,6 +24,11 @@ static void trace(TraceEventID event, unsigned long x1, unsigned long x2, unsigned long x3, unsigned long x4, unsigned long x5) { TraceRecord *rec = &trace_buf[trace_idx]; + +if (!trace_list[event].state) { +return; +} + rec->event = event; rec->x1 = x1; rec->x2 = x2; @@ -74,3 +79,39 @@ void do_info_trace(Monitor *mon) trace_buf[i].x3, trace_buf[i].x4, trace_buf[i].x5); } } + +void do_info_all_trace_events(Monitor *mon) +{ +unsigned int i; + +for (i = 0; i < NR_TRACE_EVENTS; i++) { +monitor_printf(mon, "%s [Event ID %u] : state %u\n", +trace_list[i].tp_name, i, trace_list[i].state); +} +} + +static TraceEvent* find_trace_event_by_name(const char *tname) +{ +unsigned int i; + +if (!tname) { +return NULL; +} + +for (i = 0; i < NR_TRACE_EVENTS; i++) { +if (!strcmp(trace_list[i].tp_name, tname)) { +return &trace_list[i]; +} +} +return NULL; /* indicates end of list reached without a match */ +} + +void change_trace_event_state(const char *tname, bool tstate) +{ +TraceEvent *tp; + +tp = find_trace_event_by_name(tname); +if (tp) { +tp->state = tstate; +} +} diff --git a/tracetool b/tracetool index 6f8f8a9..9e8dbd8 100755 --- a/tracetool +++ b/tracetool @@ -123,14 +123,23 @@ linetoc_end_nop() linetoh_begin_simple() { cat < + typedef unsigned int TraceEventID; +typedef struct { +const char *tp_name; +bool state; +} TraceEvent; + void trace1(TraceEventID event, unsigned long x1); void trace2(TraceEventID event, unsigned long x1, unsigned long x2); void trace3(TraceEventID event, unsigned long x1, unsigned long x2, unsigned long x3); void trace4(TraceEventID event, unsigned long x1, unsign
[Qemu-devel] [RFC v4][PATCH 2/3] Monitor command 'info trace'
Monitor command 'info trace' to display contents of trace buffer Signed-off-by: Prerna Saxena --- configure |3 +++ monitor.c | 12 qemu-monitor.hx |4 simpletrace.c | 12 tracetool |1 + 5 files changed, 32 insertions(+), 0 deletions(-) diff --git a/configure b/configure index 675d0fc..56af8dd 100755 --- a/configure +++ b/configure @@ -2302,6 +2302,9 @@ bsd) esac echo "TRACE_BACKEND=$trace_backend" >> $config_host_mak +if test "$trace_backend" = "simple"; then + echo "CONFIG_SIMPLE_TRACE=y" >> $config_host_mak +fi if test "$trace_backend" = "ust"; then LIBS="-lust $LIBS" fi diff --git a/monitor.c b/monitor.c index ad50f12..8b60830 100644 --- a/monitor.c +++ b/monitor.c @@ -55,6 +55,9 @@ #include "json-streamer.h" #include "json-parser.h" #include "osdep.h" +#ifdef CONFIG_SIMPLE_TRACE +#include "trace.h" +#endif //#define DEBUG //#define DEBUG_COMPLETION @@ -2780,6 +2783,15 @@ static const mon_cmd_t info_cmds[] = { .help = "show roms", .mhandler.info = do_info_roms, }, +#if defined(CONFIG_SIMPLE_TRACE) +{ +.name = "trace", +.args_type = "", +.params = "", +.help = "show current contents of trace buffer", +.mhandler.info = do_info_trace, +}, +#endif { .name = NULL, }, diff --git a/qemu-monitor.hx b/qemu-monitor.hx index b6e3467..766c30f 100644 --- a/qemu-monitor.hx +++ b/qemu-monitor.hx @@ -114,6 +114,10 @@ show migration status show balloon information @item info qtree show device tree +#ifdef CONFIG_SIMPLE_TRACE +...@item info trace +show contents of trace buffer +#endif @end table ETEXI diff --git a/simpletrace.c b/simpletrace.c index b488380..5734d15 100644 --- a/simpletrace.c +++ b/simpletrace.c @@ -1,5 +1,6 @@ #include #include +#include "monitor.h" #include "trace.h" typedef struct { @@ -62,3 +63,14 @@ void trace4(TraceEventID event, unsigned long x1, unsigned long x2, unsigned lon void trace5(TraceEventID event, unsigned long x1, unsigned long x2, unsigned long x3, unsigned long x4, unsigned long x5) { trace(event, x1, x2, x3, x4, x5); } + +void do_info_trace(Monitor *mon) +{ +unsigned int i; + +for (i = 0; i < trace_idx ; i++) { +monitor_printf(mon, "Event %lu : %lx %lx %lx %lx %lx\n", + trace_buf[i].event, trace_buf[i].x1, trace_buf[i].x2, +trace_buf[i].x3, trace_buf[i].x4, trace_buf[i].x5); +} +} diff --git a/tracetool b/tracetool index 0dc7f1b..6f8f8a9 100755 --- a/tracetool +++ b/tracetool @@ -130,6 +130,7 @@ void trace2(TraceEventID event, unsigned long x1, unsigned long x2); void trace3(TraceEventID event, unsigned long x1, unsigned long x2, unsigned long x3); void trace4(TraceEventID event, unsigned long x1, unsigned long x2, unsigned long x3, unsigned long x4); void trace5(TraceEventID event, unsigned long x1, unsigned long x2, unsigned long x3, unsigned long x4, unsigned long x5); +void do_info_trace(Monitor *mon); EOF simple_event_num=0 -- 1.6.2.5 -- Prerna Saxena Linux Technology Centre, IBM Systems and Technology Lab, Bangalore, India
[Qemu-devel] [RFC v4][PATCH 1/3] Change type declarations
Change type 'TraceEvent' to 'TraceEventID' Signed-off-by: Prerna Saxena --- simpletrace.c | 12 ++-- tracetool | 12 ++-- 2 files changed, 12 insertions(+), 12 deletions(-) diff --git a/simpletrace.c b/simpletrace.c index 2fec4d3..b488380 100644 --- a/simpletrace.c +++ b/simpletrace.c @@ -19,7 +19,7 @@ static TraceRecord trace_buf[TRACE_BUF_LEN]; static unsigned int trace_idx; static FILE *trace_fp; -static void trace(TraceEvent event, unsigned long x1, +static void trace(TraceEventID event, unsigned long x1, unsigned long x2, unsigned long x3, unsigned long x4, unsigned long x5) { TraceRecord *rec = &trace_buf[trace_idx]; @@ -43,22 +43,22 @@ static void trace(TraceEvent event, unsigned long x1, } } -void trace1(TraceEvent event, unsigned long x1) { +void trace1(TraceEventID event, unsigned long x1) { trace(event, x1, 0, 0, 0, 0); } -void trace2(TraceEvent event, unsigned long x1, unsigned long x2) { +void trace2(TraceEventID event, unsigned long x1, unsigned long x2) { trace(event, x1, x2, 0, 0, 0); } -void trace3(TraceEvent event, unsigned long x1, unsigned long x2, unsigned long x3) { +void trace3(TraceEventID event, unsigned long x1, unsigned long x2, unsigned long x3) { trace(event, x1, x2, x3, 0, 0); } -void trace4(TraceEvent event, unsigned long x1, unsigned long x2, unsigned long x3, unsigned long x4) { +void trace4(TraceEventID event, unsigned long x1, unsigned long x2, unsigned long x3, unsigned long x4) { trace(event, x1, x2, x3, x4, 0); } -void trace5(TraceEvent event, unsigned long x1, unsigned long x2, unsigned long x3, unsigned long x4, unsigned long x5) { +void trace5(TraceEventID event, unsigned long x1, unsigned long x2, unsigned long x3, unsigned long x4, unsigned long x5) { trace(event, x1, x2, x3, x4, x5); } diff --git a/tracetool b/tracetool index 9ea9c08..0dc7f1b 100755 --- a/tracetool +++ b/tracetool @@ -123,13 +123,13 @@ linetoc_end_nop() linetoh_begin_simple() { cat <
[Qemu-devel] [RFC v4][PATCH 0/3] Monitor support for Qemu tracing
This set of patches enables trace visualization & control via the QEMU monitor. It is based on trace infrastructure posted upstream : ( http://lists.gnu.org/archive/html/qemu-devel/2010-05/msg02407.html ) This patchset adds monitor commands : - info trace : to view current contents of the trace buffer - info tracepoints : to view all available tracepoints and their state. - tracepoint NAME on|off : to enable/disable the logging of dataThis is v3 of a set of patches to enable trace visualization & control via the QEMU monitor. Changelog from v3: 1. As suggested, it replaces a hash-based search of tracepoints with a linear search. 2. Static initialization of trace event array. 3. Cleanups. Changelog from v2: 1. Clean-ups, particularly relating to export of tdb_hash(). Changelog from v1: 1. Command 'info trace' is used to view current contents of buffer, in place of 'trace'. 2. Cleanups Todos : 1. Integration with QMP 2. More tracepoints need to be added for instrumenting other qemu components such as virtio drivers, etc. -- Prerna Saxena Linux Technology Centre, IBM Systems and Technology Lab, Bangalore, India
Re: [Qemu-devel] [PATCH] poison TARGET_ for compile once.
On 06/24/2010 09:14 AM, Isaku Yamahata wrote: Sorry, I sent out the old patch. Here is the right one. Subject: [PATCH] poison TARGET_arch for compile once. poison TARGET_arch for compile once object to prevent those ifdef from creeping in again. Why do you need to split poison.h? Are there identifiers that are not in your new poison-arch.h and can be legitimately used in target-independent code? Paolo
Re: [Qemu-devel] [PATCH v2] rtc: Remove TARGET_I386 from qemu-config.c, enables driftfix
On 06/23/10 16:44, Amit Shah wrote: > qemu-config.c doesn't contain any target-specific code, and the > TARGET_I386 conditional code didn't get compiled as a result. Removing > this enables the driftfix parameter for rtc. > > Signed-off-by: Amit Shah > --- > qemu-config.c |2 -- > 1 files changed, 0 insertions(+), 2 deletions(-) I really don't like exposing all these options in targets where they are not functional. It would be really nice if we could come up with a better way to handle this without just exposing them globally. Cheers, Jes
[Qemu-devel] Re: [PATCH] virtio-net: correct header length math
On Thu, Jun 24, 2010 at 02:12:13PM +0530, Amit Shah wrote: > On (Wed) Jun 23 2010 [12:51:18], Michael S. Tsirkin wrote: > > We were requesting too much when checking buffer > > length: size already includes host header length. > > > > Signed-off-by: Michael S. Tsirkin > > --- > > hw/virtio-net.c | 20 +++- > > 1 files changed, 11 insertions(+), 9 deletions(-) > > Couple of minor comments. But I'll still provide the > > ACK > > > @@ -556,9 +557,10 @@ static ssize_t virtio_net_receive(VLANClientState *nc, > > const uint8_t *buf, size_ > > virtqueue_pop(n->rx_vq, &elem) == 0) { > > if (i == 0) > > return -1; > > -fprintf(stderr, "virtio-net truncating packet: " > > -"offset %zd, size %zd, hdr_len %zd\n", > > -offset, size, hdr_len); > > +fprintf(stderr, "virtio-net truncating packet: i %d mergeable > > %d " > > +"offset %zd, size %zd, guest hdr %zd, host hdr %zd\n", > > + i, n->mergeable_rx_bufs, > > +offset, size, guest_hdr_len, host_hdr_len); > > Again, tab usage and 'guest hdr len' and 'host hdr len' make better > sense than 'guest hdr' and 'host hdr' > > > exit(1); > > Can we drop the packet(s) instead of exiting? > > Amit This is a guest bug in the same way as moving indexes incorrectly. But since we do have such buggy guests in the field (old virtio), I guess we should. -- MST
[Qemu-devel] Re: [PATCH] virtio-net: correct header length math
On (Wed) Jun 23 2010 [12:51:18], Michael S. Tsirkin wrote: > We were requesting too much when checking buffer > length: size already includes host header length. > > Signed-off-by: Michael S. Tsirkin > --- > hw/virtio-net.c | 20 +++- > 1 files changed, 11 insertions(+), 9 deletions(-) Couple of minor comments. But I'll still provide the ACK > @@ -556,9 +557,10 @@ static ssize_t virtio_net_receive(VLANClientState *nc, > const uint8_t *buf, size_ > virtqueue_pop(n->rx_vq, &elem) == 0) { > if (i == 0) > return -1; > -fprintf(stderr, "virtio-net truncating packet: " > -"offset %zd, size %zd, hdr_len %zd\n", > -offset, size, hdr_len); > +fprintf(stderr, "virtio-net truncating packet: i %d mergeable %d > " > +"offset %zd, size %zd, guest hdr %zd, host hdr %zd\n", > + i, n->mergeable_rx_bufs, > +offset, size, guest_hdr_len, host_hdr_len); Again, tab usage and 'guest hdr len' and 'host hdr len' make better sense than 'guest hdr' and 'host hdr' > exit(1); Can we drop the packet(s) instead of exiting? Amit
[Qemu-devel] [Bug 543478] Re: qemus pmemsave doesn't accept "/" in filename
Eh. Well. I'm a bit surprised that you won't allow forward slashes if you try to parse a path. It's actually a quite common character in the Linux world. Even other Unixes use it for separating components of a path. And since people use it so much, it should be as easy as possible to actually give a path to qemu. The excuse that it "is used to create special expressions" (which, btw?!) doesn't hold. I'm pretty confident that people use the '/' character to separate components of a path rather than doing "special expressions". Especially when a path the a file is expected! So if there are still "special expressions" needed in a path, it'd be better to select a different character. Even if you don't agree on that, I really believe the user deserves some explanation along with the error message that is printed as I've pointed out in comment #0. ** Changed in: qemu-kvm (Ubuntu) Status: Invalid => New -- qemus pmemsave doesn't accept "/" in filename https://bugs.launchpad.net/bugs/543478 You received this bug notification because you are a member of qemu- devel-ml, which is subscribed to QEMU. Status in QEMU: Invalid Status in “qemu-kvm” package in Ubuntu: New Bug description: Binary package hint: qemu-kvm Please see my conversation with qemu: (qemu) pmemsave unexpected end of expression (qemu) help pmemsave pmemsave addr size file -- save to disk physical memory dump starting at 'addr' of size 'size' (qemu) pmemsave 0 512M /tmp/qemu.mem pmemsave: extraneous characters at the end of line (qemu) pmemsave 0 512 /tmp/qemu.mem invalid char in expression (qemu) pmemsave 0 512 /tmp/qemu invalid char in expression (qemu) pmemsave 0 512 qemu.mem (qemu) pmemsave 0 512M qemu.mem pmemsave: extraneous characters at the end of line Let me comment on each one of those: (qemu) pmemsave unexpected end of expression I expected some sort of hint as to where to get more information. Maybe just a "Type ``help pmemsave'' to get syntax information" would be sufficient. (qemu) help pmemsave pmemsave addr size file -- save to disk physical memory dump starting at 'addr' of size 'size' Nice. But an example would be nice. My proposal: "I.e.: pmemsave 0 1G /tmp/qemu.mem" (qemu) pmemsave 0 512M /tmp/qemu.mem pmemsave: extraneous characters at the end of line eh. Would be nice if it told me *which* character was "extraneous" and what "extraneous" means. My proposal: "Couldn't parse character at position 23, please see help pmemsave for an example". (qemu) pmemsave 0 512 /tmp/qemu.mem invalid char in expression Hm. Interesting. Again, would be nice if it printed me the offending character. My proposal: "Could not parse character at position 23, please see help pmemsave for an example". (qemu) pmemsave 0 512 /tmp/qemu invalid char in expression Now I got rid of almost everything but it still doesn't work. (qemu) pmemsave 0 512 qemu.mem aha! No slashes?! Seriously? (qemu) pmemsave 0 512M qemu.mem pmemsave: extraneous characters at the end of line And no "M" or "G" modifiers? If I want to dump 2GB then I'd have to calculate the number in bytes and paste that long string. I expected qemu to be able to parse the K, M, G suffixes. Also, I'm wondering why it doesn't offer to dump all memory. ProblemType: Bug Architecture: amd64 CurrentDmesg: [150870.676062] kvm_intel: Unknown symbol kvm_vcpu_on_spin [150947.222923] cron[24260]: segfault at 0 ip (null) sp 7fffe865eed8 error 14 in cron[40+9000] [150947.224187] cron[24261]: segfault at 0 ip (null) sp 7fffe865eed8 error 14 in cron[40+9000] Date: Sun Mar 21 15:03:13 2010 DistroRelease: Ubuntu 9.10 KvmCmdLine: UIDPID PPID CSZ RSS PSR STIME TTY TIME CMD muelli 23807 23806 13 239738 228464 0 14:54 pts/800:01:22 /usr/bin/kvm -S -M pc -m 512 -smp 1 -name vanilla_ubuntu -monitor stdio -boot c -drive file=/home/muelli/qemu/ubuntu8.10/ubuntu.img,if=ide,index=0,boot=on -drive file=,if=ide,media=cdrom,index=2 -net nic,model=rtl8139,macaddr=f0:00:BA:12:34:56 -net user,hostfwd=tcp::2223-:22,smb=/tmp/share -serial pty -snapshot MachineType: LENOVO 766636G Package: kvm 1:84+dfsg-0ubuntu16+0.11.0+0ubuntu6.3 PccardctlIdent: Socket 0: no product info available PccardctlStatus: Socket 0: no card ProcCmdLine: root=/dev/mapper/cryptroot source=UUID=9c3d5596-27c6-4fd5-bfcd-fa8eef6f1230 ro vdso32=0 quiet splash crashkernel=384M-2G:64M,2G-:128M ProcVersionSignature: Ubuntu 2.6.32-16.24-generic SourcePackage: qemu-kvm Uname: Linux 2.6.32-16-generic x86_64 dmi.bios.date: 03/12/2009 dmi.bios.vendor: LENOVO dmi.bios.version: 7NETC0WW (2.20 ) dmi.board.name: 766636G dmi.board.vendor: LENOVO dmi.board.version: Not Available dmi.chassis.asset.tag: No Asset Information dmi.chassis.type: 10 dmi.chassis.vendor: LENOVO dmi.chassis.version: Not Available dmi.modalias: dmi:bvnLENOVO:bvr7NETC0WW(2.20):bd03/12/2009:svnLENOVO:pn766636G:pvrThinkPadX61:rvnLENOVO:rn766636G:rvrNotAvailable:cvnLENOVO:ct10:cvrNotAvailable: dm
Re: [Qemu-devel] Re: [PATCH v4 3/6] pci: set PCI multi-function bit appropriately.
On Thu, Jun 24, 2010 at 08:48:42AM +0900, Isaku Yamahata wrote: > On Wed, Jun 23, 2010 at 01:41:57PM +0300, Michael S. Tsirkin wrote: > > I will try to find a bit of time to rearrange the code in pci.c a bit, > > but this can come afterwards. > > I'd like to move pci_bridge_xxx into pci_bridge.c because > pci.c has grown. > Are you okay with it? Or should I wait for your rearrange? > I'd like to avoid stepping on each other. I'm looking at rearranging it myself, but doing some API cleanup first. It will be easier if you keep adding to pci.c meanwhile. > -- > yamahata
Re: [Qemu-devel] [PATCH 03/15] pci: Implement BusInfo.get_dev_path()
On Wed, Jun 23, 2010 at 10:41:13PM -0600, Alex Williamson wrote: > This works great for PCI since a ::. uniquely > describes a global address. No need to traverse up the qdev tree. > PCI segment support is a placeholder for compatibility once we > support multiple segments. > > Signed-off-by: Alex Williamson > --- > > hw/pci.c | 14 ++ > 1 files changed, 14 insertions(+), 0 deletions(-) > > diff --git a/hw/pci.c b/hw/pci.c > index 7787005..5c9d6b4 100644 > --- a/hw/pci.c > +++ b/hw/pci.c > @@ -58,11 +58,13 @@ struct PCIBus { > }; > > static void pcibus_dev_print(Monitor *mon, DeviceState *dev, int indent); > +static char *pcibus_get_dev_path(DeviceState *dev); > > static struct BusInfo pci_bus_info = { > .name = "PCI", > .size = sizeof(PCIBus), > .print_dev = pcibus_dev_print, > +.get_dev_path = pcibus_get_dev_path, > .props = (Property[]) { > DEFINE_PROP_PCI_DEVFN("addr", PCIDevice, devfn, -1), > DEFINE_PROP_STRING("romfile", PCIDevice, romfile), > @@ -1853,6 +1855,18 @@ static void pcibus_dev_print(Monitor *mon, DeviceState > *dev, int indent) > } > } > > +static char *pcibus_get_dev_path(DeviceState *dev) > +{ > +PCIDevice *d = (PCIDevice *)dev; > +char path[16]; > + > +snprintf(path, sizeof(path), "%04x:%02x:%02x.%x", > + 0 /* FIXME for segment support */, d->config[PCI_SECONDARY_BUS], pci_find_domain(d->bus) > + PCI_SLOT(d->devfn), PCI_FUNC(d->devfn)); > + > +return strdup(path); > +} > + > static PCIDeviceInfo bridge_info = { > .qdev.name= "pci-bridge", > .qdev.size= sizeof(PCIBridge), > > -- yamahata
Re: [Qemu-devel] [PATCH] poison TARGET_ for compile once.
Sorry, I sent out the old patch. Here is the right one. Subject: [PATCH] poison TARGET_arch for compile once. poison TARGET_arch for compile once object to prevent those ifdef from creeping in again. Signed-off-by: Isaku Yamahata --- Makefile|6 +++--- Makefile.objs | 11 ++- Makefile.target |4 ++-- poison-arch.h | 25 + poison.h| 16 +--- 5 files changed, 41 insertions(+), 21 deletions(-) create mode 100644 poison-arch.h diff --git a/Makefile b/Makefile index 221fbd8..6a55b86 100644 --- a/Makefile +++ b/Makefile @@ -137,11 +137,11 @@ iov.o: iov.c iov.h qemu-img.o: qemu-img-cmds.h qemu-img.o qemu-tool.o qemu-nbd.o qemu-io.o: $(GENERATED_HEADERS) -qemu-img$(EXESUF): qemu-img.o qemu-tool.o qemu-error.o $(block-obj-y) $(qobject-obj-y) +qemu-img$(EXESUF): qemu-img.o qemu-tool.o qemu-error.o qemu-malloc.o $(block-obj-y) $(qobject-obj-y) -qemu-nbd$(EXESUF): qemu-nbd.o qemu-tool.o qemu-error.o $(block-obj-y) $(qobject-obj-y) +qemu-nbd$(EXESUF): qemu-nbd.o qemu-tool.o qemu-error.o qemu-malloc.o $(block-obj-y) $(qobject-obj-y) -qemu-io$(EXESUF): qemu-io.o cmd.o qemu-tool.o qemu-error.o $(block-obj-y) $(qobject-obj-y) +qemu-io$(EXESUF): qemu-io.o cmd.o qemu-tool.o qemu-error.o qemu-malloc.o $(block-obj-y) $(qobject-obj-y) qemu-img-cmds.h: $(SRC_PATH)/qemu-img-cmds.hx $(call quiet-command,sh $(SRC_PATH)/hxtool -h < $< > $@," GEN $@") diff --git a/Makefile.objs b/Makefile.objs index 53fb68e..5674922 100644 --- a/Makefile.objs +++ b/Makefile.objs @@ -7,7 +7,7 @@ qobject-obj-y += qerror.o ### # block-obj-y is code used by both qemu system emulation and qemu-img -block-obj-y = cutils.o cache-utils.o qemu-malloc.o qemu-option.o module.o +block-obj-y = cutils.o cache-utils.o qemu-option.o module.o block-obj-y += nbd.o block.o aio.o aes.o osdep.o qemu-config.o block-obj-$(CONFIG_POSIX) += posix-aio-compat.o block-obj-$(CONFIG_LINUX_AIO) += linux-aio.o @@ -265,3 +265,12 @@ os-win32.o: qemu-options.def qemu-options.def: $(SRC_PATH)/qemu-options.hx $(call quiet-command,sh $(SRC_PATH)/hxtool -h < $< > $@," GEN $(TARGET_DIR)$@") + +## +# poison TARGET_arch to prevent from creeping those defines again. + +POISON_CFLAGS = -include poison-arch.h +$(qobject-obj-y) $(block-obj-y) $(block-nested-y) $(block-obj-y) \ +$(net-obj-y) $(net-nested-y) $(fsdev-nested-y) $(fsdev-obj-y) \ +$(common-obj-y) $(audio-obj-y) $(slirp-obj-y) $(user-obj-y) \ +$(hw-obj-y) $(sound-obj-y) $(libdis-y) vl.o: QEMU_CFLAGS += $(POISON_CFLAGS) diff --git a/Makefile.target b/Makefile.target index f64702b..3475ce5 100644 --- a/Makefile.target +++ b/Makefile.target @@ -85,8 +85,7 @@ $(call set-vpath, $(SRC_PATH)/linux-user:$(SRC_PATH)/linux-user/$(TARGET_ABI_DIR QEMU_CFLAGS+=-I$(SRC_PATH)/linux-user -I$(SRC_PATH)/linux-user/$(TARGET_ABI_DIR) obj-y = main.o syscall.o strace.o mmap.o signal.o thunk.o \ - elfload.o linuxload.o uaccess.o gdbstub.o cpu-uname.o \ - qemu-malloc.o + elfload.o linuxload.o uaccess.o gdbstub.o cpu-uname.o obj-$(TARGET_HAS_BFLT) += flatload.o @@ -302,6 +301,7 @@ obj-y += $(addprefix $(HWDIR)/, $(hw-obj-y)) endif # CONFIG_SOFTMMU +obj-y += qemu-malloc.o obj-$(CONFIG_GDBSTUB_XML) += gdbstub-xml.o $(QEMU_PROG): $(obj-y) $(obj-$(TARGET_BASE_ARCH)-y) diff --git a/poison-arch.h b/poison-arch.h new file mode 100644 index 000..8143c41 --- /dev/null +++ b/poison-arch.h @@ -0,0 +1,25 @@ +/* Poison identifiers that should not be used when building + target independent device code. */ + +#ifndef HW_POISON_ARCH_H +#define HW_POISON_ARCH_H +#ifdef __GNUC__ + +#pragma GCC poison TARGET_I386 +#pragma GCC poison TARGET_X86_64 +#pragma GCC poison TARGET_ALPHA +#pragma GCC poison TARGET_ARM +#pragma GCC poison TARGET_CRIS +#pragma GCC poison TARGET_M68K +#pragma GCC poison TARGET_MIPS +#pragma GCC poison TARGET_MIPS64 +#pragma GCC poison TARGET_PPC +#pragma GCC poison TARGET_PPCEMB +#pragma GCC poison TARGET_PPC64 +#pragma GCC poison TARGET_ABI32 +#pragma GCC poison TARGET_SH4 +#pragma GCC poison TARGET_SPARC +#pragma GCC poison TARGET_SPARC64 + +#endif +#endif diff --git a/poison.h b/poison.h index d7db7f4..f9efae9 100644 --- a/poison.h +++ b/poison.h @@ -5,21 +5,7 @@ #define HW_POISON_H #ifdef __GNUC__ -#pragma GCC poison TARGET_I386 -#pragma GCC poison TARGET_X86_64 -#pragma GCC poison TARGET_ALPHA -#pragma GCC poison TARGET_ARM -#pragma GCC poison TARGET_CRIS -#pragma GCC poison TARGET_M68K -#pragma GCC poison TARGET_MIPS -#pragma GCC poison TARGET_MIPS64 -#pragma GCC poison TARGET_PPC -#pragma GCC poison TARGET_PPCEMB -#pragma GCC poison TARGET_PPC64 -#pragma GCC poison TARGET_ABI32 -#pragma GCC poison TARGET_SH4 -#pragma GCC poison TARGET_SPARC -#pragma GCC poison TARGET_SPARC64 +#include "poison-arch.h" #pragma GCC poison TARGET_WORDS_BIGE