[Qemu-devel] [PATCH] the calculation of bytes_xfer in qemu_put_buffer() is wrong
In qemu_put_buffer(), bytes_xfer += size is wrong, it will be more than expected, and should be bytes_xfer += l. Signed-off-by: zhangmin zhangm...@huawei.commailto:zhangm...@huawei.com --- savevm.c |2 +- 1 files changed, 1 insertions(+), 1 deletions(-) diff --git a/savevm.c b/savevm.c index 2f631d4..3f912dd 100644 --- a/savevm.c +++ b/savevm.c @@ -794,7 +794,7 @@ void qemu_put_buffer(QEMUFile *f, const uint8_t *buf, int size) if (l size) l = size; memcpy(f-buf + f-buf_index, buf, l); -f-bytes_xfer += size; +f-bytes_xfer += l; if (f-ops-writev_buffer) { add_to_iovec(f, f-buf + f-buf_index, l); } -- 1.7.3.1.msysgit.0
Re: [Qemu-devel] console muti-head some more design input
Hi, So I felt I had a choice here for sharing a single output surface amongst outputs: a) have multiple QemuConsole reference multiple DisplaySurface wihch reference a single pixman image, This one. In either case we need to store, width/height of the console and x/y offset into the output surface somewhere, as the output dimensions will not correspond to surface dimensions or the surface dimensions won't correspond to the pixman image dimensions Not needed (well, internal to virtio-gpu probably). Just use qemu_create_displaysurface_from(). That creates a new DisplaySurface (and pixman image) using existing backing storage. Typically backing storage is the guests video memory. In your case it probably is the dma-buf the gpu rendered into (at least in the 3d case, not sure you are there already). You can also use normal guest ram as backing storage (for 2d maybe?). The framebuffer must be linear in guest physical memory (so it is linear in host virtual too) for this to work. Dimensions not matching is no problem, you'll pass the scanline length of the backing storage as linesize parameter. Adjust the data pointer according to x+y offset. So I picked (b) in my current codebase, once I untangled a few lifetimes issues (replace_surface - frees the displaysurface == bad, this is bad in general), Why is this bad? Some background on the design (/me feels like it would be a good idea to brew up a docs/ui.txt from our email discussions ...): There are basically two ways to manage the surfaces. Case one: You don't have the data in a format the qemu ui code can handle. Such as vga text mode, or those funky planar 16 color modes. You'll go create a DisplaySurface for it (using qemu_create_displaysurface, allocating backing storage too). You keep it until the guest switches the video mode. You render into it and you notify qemu about updates using dpy_gfx_update(). Case two: You have the data in a format qemu ui can handle directly. You'll go create a DisplaySurface using qemu_create_displaysurface_from, backing the DisplaySurface using your existing backing storage. If the viewpoint changes (panning, page flipping) just create a new DisplaySurface and replace the old one. As the backing storage doesn't change this is cheap, so it is perfectly fine to do it frequently if needed. Another issue I had is I feel the console layer could do with some sort of subclassing of objects or the ability to store ui layer info in the console objects, You can do that by embedding the DisplayChangeListener into your ui state struct. Spice does it this way: State struct for one display channel: struct SimpleSpiceDisplay { [ ... ] DisplayChangeListener dcl; [ ... ] }; When registering it binds the spice channel / display listener to a console (i.e. don't follow active_console): ssd-dcl.ops = display_listener_ops; ssd-dcl.con = con; register_displaychangelistener(ssd-dcl); Then in the callbacks go find the spice display channel state: SimpleSpiceDisplay *ssd = container_of(dcl, SimpleSpiceDisplay, dcl); As there is a fixed relationship between QemuConsole and DisplayChangeListener you can store all the data you need to manage the QemuConsole there. cheers, Gerd
Re: [Qemu-devel] [PATCH] the calculation of bytes_xfer in qemu_put_buffer() is wrong
Il 19/11/2013 06:53, Wangting (Kathy) ha scritto: In qemu_put_buffer(), bytes_xfer += size is wrong,it will be more than expected,and should be bytes_xfer += l. Signed-off-by: zhangmin zhangm...@huawei.com --- savevm.c |2 +- 1 files changed, 1 insertions(+), 1 deletions(-) diff --git a/savevm.c b/savevm.c index 2f631d4..3f912dd 100644 --- a/savevm.c +++ b/savevm.c @@ -794,7 +794,7 @@ void qemu_put_buffer(QEMUFile *f, const uint8_t *buf, int size) if (l size) l = size; memcpy(f-buf + f-buf_index, buf, l); -f-bytes_xfer += size; +f-bytes_xfer += l; if (f-ops-writev_buffer) { add_to_iovec(f, f-buf + f-buf_index, l); } -- 1.7.3.1.msysgit.0 Reviewed-by: Paolo Bonzini pbonz...@redhat.com
Re: [Qemu-devel] [PULL 47/58] qdev-monitor: Unref device when device_add fails
On Mon, Nov 18, 2013 at 03:35:20PM +0100, Andreas Färber wrote: Am 18.11.2013 13:29, schrieb Amos Kong: On Tue, Oct 08, 2013 at 07:44:45PM +0200, Andreas Färber wrote: From: Stefan Hajnoczi stefa...@redhat.com qdev_device_add() leaks the created device upon failure. I suspect this problem crept in because qdev_free() unparents the device but does not drop a reference - confusing name. Cc: qemu-sta...@nongnu.org Signed-off-by: Stefan Hajnoczi stefa...@redhat.com Signed-off-by: Andreas Färber afaer...@suse.de Hi Stefan, This commit caused a regression bug: hotplug more than 32 disks to vm, qemu crash --- [amos@amosk qemu]$ cat radd.sh for i in `seq 3 9` a b c d e f 11 12 13 14 15 16 17 18 19 1a 1b 1c 1d 1e 1f;do for j in `seq 1 7` 0;do /bin/cp /images/none.qcow2 /tmp/resize$i$j.qcow2 echo drive_add $i.$j id=drv$i$j,file=/tmp/resize$i$j.qcow2,if=none echo drive_add $i.$j id=drv$i$j,file=/tmp/resize$i$j.qcow2,if=none | nc -U /tmp/m echo device_add virtio-blk-pci,id=dev$i$j,drive=drv$i$j,addr=0x$i.$j,multifunction=on echo device_add virtio-blk-pci,id=dev$i$j,drive=drv$i$j,addr=0x$i.$j,multifunction=on | nc -U /tmp/m done done Hi, thanks for catching this. Is this only with virtio-blk-pci or with any PCI card or only when drives are involved? I can reproduce by hotplugging virtio-net-pci NIC for i in `seq 3 9` a b c d e f 11 12 13 14 15 16 17 18 19 1a 1b 1c 1d 1e 1f;do for j in `seq 1 7` 0;do echo netdev_add tap,id=dev$i$j | nc -U /tmp/m echo device_add virtio-net-pci,netdev=dev$i$j,id=nic$i$j,addr=0x$i.$j,multifunction=on | nc -U /tmp/m done done Either way it would be really great if you could add such tests to Stefan's qtest using QMP, so that it can easily be run by everyone. I will do it. The stacktrace below is not really telling to me. I wonder if we forget to clean up some MemoryRegion in the device that still has a back reference or whether the Memory API still references MemoryRegions that have been destroyed by the device or forgets the reference devices it still needs... Paolo? I had reviewed the call paths and believe the patch to be 100% good, so the fault will very likely be elsewhere. Regards, Andreas #0 0x558b7f95 in flatview_ref (view=0x0) at /home/devel/qemu/memory.c:300 #1 0x558b9689 in address_space_get_flatview (as=0x5645d660) at /home/devel/qemu/memory.c:656 #2 0x558ba416 in address_space_update_topology (as=0x5645d660) at /home/devel/qemu/memory.c:760 #3 0x558ba5cf in memory_region_transaction_commit () at /home/devel/qemu/memory.c:799 #4 0x558bcfcc in memory_region_set_enabled (mr=0x5647af08, enabled=false) at /home/devel/qemu/memory.c:1503 #5 0x5571a0af in do_pci_register_device (pci_dev=0x5647ac10, bus=0x564132b0, name=0x56261100 virtio-blk-pci, devfn=26) at hw/pci/pci.c:846 #6 0x5571c6cc in pci_qdev_init (qdev=0x5647ac10) at hw/pci/pci.c:1751 #7 0x55694d70 in device_realize (dev=0x5647ac10, err=0x7fffc8e8) at hw/core/qdev.c:178 #8 0x556966fc in device_set_realized (obj=0x5647ac10, value=true, err=0x7fffca60) at hw/core/qdev.c:699 #9 0x557e7b57 in property_set_bool (obj=0x5647ac10, v=0x5679a830, opaque=0x56461b10, name=0x559922ae realized, errp=0x7fffca60) at qom/object.c:1315 #10 0x557e665b in object_property_set (obj=0x5647ac10, v=0x5679a830, name=0x559922ae realized, errp=0x7fffca60) at qom/object.c:803 #11 0x557e816e in object_property_set_qobject (obj=0x5647ac10, value=0x56678880, name=0x559922ae realized, errp=0x7fffca60) at qom/qom-qobject.c:24 #12 0x557e6950 in object_property_set_bool (obj=0x5647ac10, value=true, name=0x559922ae realized, errp=0x7fffca60) at qom/object.c:866 #13 0x55694ca7 in qdev_init (dev=0x5647ac10) at hw/core/qdev.c:163 #14 0x557c60ee in qdev_device_add (opts=0x56525370) at qdev-monitor.c:543 #15 0x557c6730 in do_device_add (mon=0x562fb760, qdict=0x5645d440, ret_data=0x7fffcb80) at qdev-monitor.c:656 #16 0x558c8892 in handle_user_command (mon=0x562fb760, cmdline=0x563f0f60 device_add virtio-blk-pci,id=dev32,drive=drv32,addr=0x3.2,multifunction=on) at /home/devel/qemu/monitor.c:4137 #17 0x558ca10f in monitor_command_cb (mon=0x562fb760, cmdline=0x563f0f60 device_add virtio-blk-pci,id=dev32,drive=drv32,addr=0x3.2,multifunction=on, opaque=0x0) at /home/devel/qemu/monitor.c:4757 #18 0x557e9491 in readline_handle_byte (rs=0x563f0f60, ch=10) at readline.c:373 #19 0x558ca045 in monitor_read (opaque=0x562fb760, buf=0x7fffccf0 \n\315\377\377\377\177, size=1) at
Re: [Qemu-devel] [PATCH] qemu-iotests: Add -c cache-mode to check
On Mon, Nov 18, 2013 at 04:40:39PM +0100, Kevin Wolf wrote: Am 18.11.2013 um 16:32 hat Stefan Hajnoczi geschrieben: On Thu, Nov 14, 2013 at 10:24:04AM +0800, Fam Zheng wrote: The default cache mode for drive options is changed to writethrough, and overridable with ./check -c mode. Signed-off-by: Fam Zheng f...@redhat.com --- tests/qemu-iotests/common | 13 - tests/qemu-iotests/iotests.py | 3 ++- 2 files changed, 14 insertions(+), 2 deletions(-) BTW, I looked back at Kevin's reply to your earlier patch and saw he suggested making the default writethrough. Kevin: Any reason not to use writeback by default? I'm not opposed to changing the default in a second step. It's just that writethrough is the default today and tests not respecting this are buggy. So the incremental fix is to make them obey the global setting, and then that setting can be tweaked in a second step. Makes sense. Stefan
Re: [Qemu-devel] [PATCH] virtio-net: fix the memory leak in rxfilter_notify()
On Mon, Nov 18, 2013 at 05:20:41PM +0200, Michael S. Tsirkin wrote: On Mon, Nov 18, 2013 at 04:14:08PM +0100, Stefan Hajnoczi wrote: On Mon, Nov 18, 2013 at 09:47:25PM +0800, Amos Kong wrote: object_get_canonical_path() returns a gchar*, it should be freeed by the caller. Signed-off-by: Amos Kong ak...@redhat.com --- hw/net/virtio-net.c | 8 1 file changed, 4 insertions(+), 4 deletions(-) Thanks, applied to my net tree (will send pull request for QEMU 1.7): https://github.com/stefanha/qemu/commits/net Stefan I'd prefer it for my comment to be addressed first ... I folded your suggestion into the commit. Stefan
Re: [Qemu-devel] [PATCH v2] virtio-net: fix the memory leak in rxfilter_notify()
On Mon, Nov 18, 2013 at 11:32:17PM +0800, Amos Kong wrote: object_get_canonical_path() returns a gchar*, it should be freeed by the caller. Signed-off-by: Amos Kong ak...@redhat.com --- v2: put gchar *path inside rxfilter_notify_enabled block --- hw/net/virtio-net.c | 8 1 file changed, 4 insertions(+), 4 deletions(-) Thanks, applied to my net tree: https://github.com/stefanha/qemu/commits/net Stefan
Re: [Qemu-devel] [PATCH v2 for-1.7] qom: Fix memory leak in object_property_set_link()
On Mon, Nov 18, 2013 at 04:52:02PM +0100, Andreas Färber wrote: Am 15.11.2013 18:09, schrieb Vlad Yasevich: Save the result of the call to object_get_cannonical_path() so we can free it. Signed-off-by: Vlad Yasevich vyase...@redhat.com Cc: qemu-sta...@nongnu.org Reviewed-by: Andreas Färber afaer...@suse.de in case Anthony wants to pick it up himself, and queued on qom-next: https://github.com/afaerber/qemu-cpu/commits/qom-next It looks as if Stefan posted an identical patch with for-1.7 tag but with his From. Please merge Vlad's patch. I wrote mine independently because I hadn't read Vlad's email yet. Stefan
Re: [Qemu-devel] [PATCH for-1.7] qom: fix object_property_set_link() memory leak
On Mon, Nov 18, 2013 at 04:11:43PM +0100, Andreas Färber wrote: Am 18.11.2013 16:10, schrieb Stefan Hajnoczi: object_get_canonical_path() returns a string that the caller is responsible for freeing. Signed-off-by: Stefan Hajnoczi stefa...@redhat.com What's the difference to Vlad's v2? Please ignore this patch, Vlad has already submitted an equivalent patch which I hadn't seen. NACK
Re: [Qemu-devel] [edk2] [edk2 PATCH 0/1] OvmfPkg: grab ACPI tables from QEMU
Hi, ACPI PciWindow32: Base=0xA000 End=0xFEEF Length=0x5EF0 begin32=c000 end32=fec0 begin64=0 end64=0 qemu seabios pick a 32bit window size which allows to cover it with a single mtrr entry. Size must be a power of two for that to work. [root@fedora ~]# cat /proc/mtrr reg00: base=0x08000 ( 2048MB), size= 2048MB, count=1: uncachable So we have three cases for piix (as you've figured in the source code already). Start at 0x8000 (2G window), 0xc000 (1G window) and 0xe000 (512M window). btw: q35 has a fixed 1G window, max low ram addr is 0xb00, the remaining address space (0xb000 - 0xc000) is used for mmconfig. I guess the range starting at 0xc000 is somehow incompatible with the EFI memory map. (I can't actually explain this idea because, again, this second range is a proper subset of the former, and its size is still 1004MB.) Probably efi places the gfx memory bar somewhere between 0xa000 and 0xc000. Sets up efifb accordingly. Then the linux kernel loads and figures Oh, that bar is outside the 0xc000+ window and goes remap it - efifb writes go into nowhere. cheers, Gerd
Re: [Qemu-devel] [PATCH] qtest: Use -display none by default
On Mon, Nov 18, 2013 at 05:54:33PM +0100, Andreas Färber wrote: Am 18.11.2013 17:48, schrieb Stefan Hajnoczi: On Mon, Nov 18, 2013 at 05:36:34PM +0100, Andreas Färber wrote: This avoids each test needing to add it to suppress windows popping up. Signed-off-by: Andreas Färber afaer...@suse.de --- tests/boot-order-test.c | 2 +- tests/endianness-test.c | 6 +++--- tests/fw_cfg-test.c | 3 +-- tests/hd-geo-test.c | 2 +- tests/i440fx-test.c | 2 +- tests/libqtest.c| 1 + tests/m48t59-test.c | 2 +- tests/qom-test.c| 2 +- tests/rtc-test.c| 2 +- tests/tmp105-test.c | 2 +- 10 files changed, 12 insertions(+), 12 deletions(-) I avoided making -display none common because tests may wish to have a display. But at the moment no test needs a display so I guess this is fine. I was under the assumption that -display none -display sdl would work just like mst's overriding the default -machine accel=qtest with -machine accel=tcg? Good point. I checked the code and it works. Let's take your patch since it also prevents future problems. Stefan
Re: [Qemu-devel] [PATCH] qtest: Use -display none by default
On Mon, Nov 18, 2013 at 05:36:34PM +0100, Andreas Färber wrote: This avoids each test needing to add it to suppress windows popping up. Signed-off-by: Andreas Färber afaer...@suse.de --- tests/boot-order-test.c | 2 +- tests/endianness-test.c | 6 +++--- tests/fw_cfg-test.c | 3 +-- tests/hd-geo-test.c | 2 +- tests/i440fx-test.c | 2 +- tests/libqtest.c| 1 + tests/m48t59-test.c | 2 +- tests/qom-test.c| 2 +- tests/rtc-test.c| 2 +- tests/tmp105-test.c | 2 +- 10 files changed, 12 insertions(+), 12 deletions(-) Tested with: DISPLAY=foo make check Thanks, applied to my block tree: https://github.com/stefanha/qemu/commits/block Stefan
Re: [Qemu-devel] [Bug 603872] Re: [Feature request] qemu-img image conversion does not show percentage
On Mon, Nov 18, 2013 at 03:55:45PM -, Varad wrote: Incomplete patch. Usecase: `qemu-img convert` with -p now shows the write speed. 1. I'm calculating the speed using the time taken to run the for(;;) at qemu-img.c:1477. I figured that every time this loop runs, n1 sectors are converted, and so I calculate the write_speed accordingly. Is this correct? 2. I have changed qemu-progress.c:qemu_progress_print() to take in a speed parameter, thinking that it would be the best option. Should I do it some other way instead (maybe write another function to print just speed)? ** Patch added: [PATCH/RFC] https://bugs.launchpad.net/qemu/+bug/603872/+attachment/3911803/+files/0001-qemu-img-show-image-conversion-speed.patch Patches attached on the bug tracker are not reviewed, they should be sent to the qemu-devel mailing list instead. If you want to link to a submitted patch from launchpad, please post a mailing list archive link. For example: http://article.gmane.org/gmane.comp.emulators.qemu/242109
Re: [Qemu-devel] Are there any IOMMU emulation in QEMU for x86 platform
Il 19/11/2013 07:34, Jiang, Yunhong ha scritto: Hi, all I noticed there are several patchset has been sent out about IOMMU emulation like http://lists.gnu.org/archive/html/qemu-devel/2011-10/msg03764.html, http://lists.gnu.org/archive/html/qemu-devel/2011-01/msg03196.html . Also I noticed that PPC platform has IOMMU emulation support in QEMU already. Are there any plan to support IOMMU emulation in QEMU for x86 now? Not that I know of. Of course, patches are welcome. And also, does it requires the real host platform have the IOMMU to support the QEMU IOMMU emulation? Or it will be a purely software emulation? For emulated devices it could be purely software. Nested device assignment would require a host IOMMU, and would require the host IOMMU driver to do some kind of shadow-paging. Paolo
[Qemu-devel] [Bug 1252009] Re: slow boot on USB drives
This is due to changes in the architecture of QEMU that do not fit very well with Windows. In the long term things should get better, but it may take a while and no one is working specifically on Windows performance. ** Changed in: qemu Status: New = Won't Fix -- You received this bug notification because you are a member of qemu- devel-ml, which is subscribed to QEMU. https://bugs.launchpad.net/bugs/1252009 Title: slow boot on USB drives Status in QEMU: Won't Fix Bug description: QEMU version: 1.6.90.0 from 2013 11 16 Host OS: Windows XP SP3 x86 Host machine: 3.2 GHz AMD Athlon 64 dual core processor, 4 GB DDR II (3.2 seen by the OS) memory Guest OS: Grub4Dos boot manager menu Problem: when I use qemu-system-i386.exe -drive file=\\.\PhysicalDrive1,if=ide,index=0,media=disk,snapshot=off -m 512 it boots twice as slow than the 0.15.1.0 version. To manage notifications about this bug go to: https://bugs.launchpad.net/qemu/+bug/1252009/+subscriptions
Re: [Qemu-devel] [PATCH 0/2] COW: Speed up writes
On Fri, Nov 15, 2013 at 07:47:00PM +0100, Charlie Shepherd wrote: v4: - Rebase onto master - Fix compilation error v3: - Refix cow_update_bitmap and squash patches 1 3 together to ensuring that we only flush if necessary, patch 1 on its own would change this causing a regression. v2: - Fix bit position calculations in cow_update_bitmap - Add necessary check in cow_set_bits Following on from Paolo's commits 26ae980 and 276cbc7, this patchset implements some changes he recommended earlier which I didn't previously have time to do while on GSoC. Charlie Shepherd (2): COW: Speed up writes COW: Extend checking allocated bits to beyond one sector block/cow.c | 124 +--- 1 file changed, 76 insertions(+), 48 deletions(-) Please remember the include the revision in the subject line: [PATCH v4] Thanks, applied to my block-next tree: https://github.com/stefanha/qemu/commits/block-next Stefan
[Qemu-devel] vl.c: question on cpu core calculation in smp_parse
Hi, if I specify just e.g. -smp 4 then smp_parse computes the following values: cpus 4, cores 1, threads 1, sockets 1 shouldn't the number of cores in this case not be 4? Peter
[Qemu-devel] [PULL for-1.7 1/1] qom: Fix memory leak in object_property_set_link()
From: Vlad Yasevich vyase...@redhat.com Save the result of the call to object_get_canonical_path() so we can free it. Cc: qemu-sta...@nongnu.org Signed-off-by: Vlad Yasevich vyase...@redhat.com Reviewed-by: Amos Kong ak...@redhat.com Reviewed-by: Stefan Hajnoczi stefa...@redhat.com Signed-off-by: Andreas Färber afaer...@suse.de --- qom/object.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/qom/object.c b/qom/object.c index b617f26..fc19cf6 100644 --- a/qom/object.c +++ b/qom/object.c @@ -838,8 +838,9 @@ char *object_property_get_str(Object *obj, const char *name, void object_property_set_link(Object *obj, Object *value, const char *name, Error **errp) { -object_property_set_str(obj, object_get_canonical_path(value), -name, errp); +gchar *path = object_get_canonical_path(value); +object_property_set_str(obj, path, name, errp); +g_free(path); } Object *object_property_get_link(Object *obj, const char *name, -- 1.8.1.4
[Qemu-devel] [PULL for-1.7 0/1] QOM devices patch queue 2013-11-19
Hello Anthony, This is my QOM (devices) patch queue for 1.7. Please pull. Thanks, Andreas Cc: Anthony Liguori anth...@codemonkey.ws Cc: Vlad Yasevich vyase...@redhat.com Cc: Stefan Hajnoczi stefa...@redhat.com The following changes since commit 5c5432e7d630592ddcc1876ac8a1505f8f14ef15: Merge remote-tracking branch 'luiz/queue/qmp' into staging (2013-11-13 11:49:27 -0800) are available in the git repository at: git://github.com/afaerber/qemu-cpu.git tags/qom-devices-for-anthony for you to fetch changes up to 2d3aa28cc2cf382aa04cd577e0be542175eea9bd: qom: Fix memory leak in object_property_set_link() (2013-11-19 10:58:21 +0100) QOM infrastructure fixes for 1.7 * QOM memory leak fix Vlad Yasevich (1): qom: Fix memory leak in object_property_set_link() qom/object.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-)
Re: [Qemu-devel] [PATCH v2 0/2] Add cache mode option to qemu-iotests
Am 19.11.2013 um 07:45 hat Fam Zheng geschrieben: The first patch adds -c mode option to ./check and convert -nocache to an alias to -c none. The mode is used in qemu-io. The second patch modifies iotests.py to use the cache mode option in qemu drive command line. Fam Zheng (2): qemu-iotests: Add -c cache-mode option qemu-iotests: Honour cache mode in iotests.py tests/qemu-iotests/common | 18 -- tests/qemu-iotests/iotests.py | 3 ++- 2 files changed, 18 insertions(+), 3 deletions(-) Reviewed-by: Kevin Wolf kw...@redhat.com
[Qemu-devel] [RFC] Architecture to connect a userspace ethernet switch to QEMU guests via Virtio
Hello, There have been discussions before on these lists on the topic of connecting a QEMU guest running a virtio_net driver, with an external userspace ethernet switch (Snabbswitch in particular). The essential requirement in this is to put the virtio backend in the external userspace process. The preferred direction should be similar to vhost, with the main difference of the control mechanism being a unix domain socket instead of an ioctl interface, and of course placing the backend in an userspace process instead the kernel. Since we are pursuing this direction,we would like to share a more detailed description of the architecture we are working on. Any feedback is most welcome. It is available here: http://www.virtualopensystems.com/media/snabbswitch/rfc_snabbswitch_qemu.pdf Best regards, Antonios Motakis Virtual Open Systems
Re: [Qemu-devel] [PATCH v2 0/2] Add cache mode option to qemu-iotests
Am 19.11.2013 um 07:45 hat Fam Zheng geschrieben: The first patch adds -c mode option to ./check and convert -nocache to an alias to -c none. The mode is used in qemu-io. The second patch modifies iotests.py to use the cache mode option in qemu drive command line. Okay, I gave it some testing, too, and it looks like we need some additional changes. There are some test cases that use: _unsupported_qemu_io_options --nocache Which obviously doesn't work any more. We need to replace it by a check against $CACHEMODE (or, perhaps preferably, even override it automatically, so that test cases aren't left out just because of the cache mode) Test case 026 uses the option of having a 026.out.nocache, which differs from the normal output. I suspect the correct differentiation is here between writethrough and writeback modes. And of course, grepping for '--nocache' to detect the condition doesn't work any more. Kevin
Re: [Qemu-devel] [PULL 11/13] target-i386: forward CPUID cache leaves when -cpu host is used
On 18.11.2013 17:11, Paolo Bonzini wrote: Il 18/11/2013 16:37, Peter Lieven ha scritto: If I specify: -smp 2,sockets=1,cores=2,threads=1 to a Windows 2012 R2 Server it crashes at boot time. -smp 2 works. for Linux /proc/cpuinfo reveals no cpu layout information (sibliings, cores, threads etc.) with this patch applied and a manual socket,core,thread configuration. What's the full command line? ~/git/qemu$ x86_64-softmmu/qemu-system-x86_64 -m 2048 -drive if=virtio,file=iscsi://172.21.200.45/iqn.2001-05.com.equallogic:0-8a0906-9d95c510a-344001d54795289f-2012-r2-1-7-0/0,format=raw,cache=writeback,aio=native -smp 2,cores=2,threads=1,sockets=1 -cpu host -monitor stdio -vnc :1 -enable-kvm -usb -usbdevice tablet -vga cirrus -global virtio-blk-pci.scsi=off -serial null -parallel null -boot c With just -smp 2 it works. However, have a look at my other email I think there is a bug in smp_parse, because -smp 2 yields cpus=2,cores=1,threads=1,sockets=1 whereas I think cores should be 2. Peter
Re: [Qemu-devel] [PULL 47/58] qdev-monitor: Unref device when device_add fails
Il 19/11/2013 09:31, Amos Kong ha scritto: I can reproduce by hotplugging virtio-net-pci NIC for i in `seq 3 9` a b c d e f 11 12 13 14 15 16 17 18 19 1a 1b 1c 1d 1e 1f;do for j in `seq 1 7` 0;do echo netdev_add tap,id=dev$i$j | nc -U /tmp/m echo device_add virtio-net-pci,netdev=dev$i$j,id=nic$i$j,addr=0x$i.$j,multifunction=on | nc -U /tmp/m done done Do you have the full command line? Also, why/where is device_add failing? Can you add a puts(driver); before the unrefs? I tried something very similar to the above, with commands like netdev_add bridge,helper=/usr/libexec/qemu-bridge-helper,br=virbr0,id=dev1f0 device_add virtio-net-pci,netdev=dev1f0,id=nic1f0,addr=0x1f.0,multifunction=on and it hotplugged all 224 devices this way without any failure. Did you try running with MALLOC_PERTURB_=42
Re: [Qemu-devel] [PATCH v2] spapr: add ibm, (get|set)-system-parameter
On 19.11.2013, at 02:23, Alexey Kardashevskiy a...@ozlabs.ru wrote: On 11/19/2013 07:58 AM, Alexander Graf wrote: On 17.11.2013, at 22:09, Alexey Kardashevskiy a...@ozlabs.ru wrote: This adds very basic handlers for ibm,get-system-parameter and ibm,set-system-parameter RTAS calls. The only parameter handled at the moment is platform-processor-diagnostics-run-mode which is always disabled and does not support changing. This is expected to make ppc64_cpu --run-mode=1 happy. Signed-off-by: Alexey Kardashevskiy a...@ozlabs.ru --- Changes: v2: * addressed comments from Alex Graf --- hw/ppc/spapr_rtas.c | 48 1 file changed, 48 insertions(+) diff --git a/hw/ppc/spapr_rtas.c b/hw/ppc/spapr_rtas.c index eb542f2..8053a67 100644 --- a/hw/ppc/spapr_rtas.c +++ b/hw/ppc/spapr_rtas.c @@ -224,6 +224,50 @@ static void rtas_stop_self(PowerPCCPU *cpu, sPAPREnvironment *spapr, env-msr = 0; } +#define DIAGNOSTICS_RUN_MODE42 + +static void rtas_ibm_get_system_parameter(PowerPCCPU *cpu, + sPAPREnvironment *spapr, + uint32_t token, uint32_t nargs, + target_ulong args, + uint32_t nret, target_ulong rets) +{ +target_ulong papameter = rtas_ld(args, 0); +target_ulong buffer = rtas_ld(args, 1); +target_ulong length = rtas_ld(args, 2); +target_ulong ret = -3; /* System parameter is not supported */ Is this an RTAS function defined return value or a global RTAS return value? Sorry for my ignorance, I do not understand the question. So far every RTAS call I looked at defined all return codes right in the description of the call. It's just a prelude to the suggestion further down. Like this (sorry, cut-n-paste from PDF killed formatting but the point is still valid): 7.3.16.2 ibm,set-system-parameter Table 96. ibm,set-system-parameter Argument Call Buffer Parameter Type Name Token Values Token for ibm,set-system-parameter Number Inputs In 2 Number Outputs 1 Parameter Token number of the target system parameter buffer Out Real address of data buffer Status 0: Success -1: Hardware Error -2: Busy, Try again later -3: System parameter not supported -9002: Setting not allowed/authorized -: Parameter Error 990x:Extended delay where x is a number 0-5 (see text below) + +switch (papameter) { +case DIAGNOSTICS_RUN_MODE: +if (length == 1) { +rtas_st(buffer, 0, 0); +ret = 0; /* Success */ I assume this one is RTAS global? +} +break; +} + +rtas_st(rets, 0, ret); +} + +static void rtas_ibm_set_system_parameter(PowerPCCPU *cpu, + sPAPREnvironment *spapr, + uint32_t token, uint32_t nargs, + target_ulong args, + uint32_t nret, target_ulong rets) +{ +target_ulong papameter = rtas_ld(args, 0); +/* target_ulong buffer = rtas_ld(args, 1); */ Not addressed. Just remove this line until it gets used. What is bad in having such a comment? I thought by having one return per function we help other people from the future to add functionality easier and such comment would help them too. One return per function makes the code flow easier. It's only partly about future functionality. I do see your point and I've usually written code the same way, until I had it rejected upstream. I'm honestly not sure which way is better. We have 3 choices here: 1) Keep it as comment 2) Add __attribute__((unused)) 3) Remove the line I like option 1 the least. But if you insist on it I won't nack the patch because of it. +target_ulong ret = -3; /* System parameter is not supported */ + +switch (papameter) { +case DIAGNOSTICS_RUN_MODE: +ret = -9002; /* Setting not allowed/authorized */ -9002 seems to always mean Not Authorized. In fact, reading through the PAPR spec it seems as if we can easily give return values reasonable names: #define RTAS_OUT_SUCCESS 0 #define RTAS_OUT_ERROR -1 #define RTAS_OUT_BUSY -2 #define RTAS_OUT_NOT_SUPPORTED -3 #define RTAS_OUT_NOMEM -5 #define RTAS_OUT_NOT_AUTHORIZED -9002 #define RTAS_OUT_PARAM_ERROR - These are RTAS local, noone else really cares about them. The kernel uses numbers too (arch/powerpc/kernel/rtas.c). Why should I replace easy understandable (look at spec - look at gdb - everything is clear) numbers with definitions? For the same reason that you use -ENOINT or -EINVAL in kernel code. For the same reason that you use H_SUCCESS rather than 0 as return value for hypercalls. In general it makes the code easier to read for people who don't have the
Re: [Qemu-devel] [PATCH v3] target-ppc: move POWER7+ to a separate family
On 19.11.2013, at 02:39, Alexey Kardashevskiy a...@ozlabs.ru wrote: So far POWER7+ was a part of POWER7 family. However it has a different PVR base value so in order to support PVR masks, it needs a separate family class. This adds a new family class, PVR base and mask values and moves Power7+ v2.1 CPU to a new family. The class init function is copied from the POWER7 family. This defines a firmware name for the new family as PowerPC,POWER7+ instead of previously used PowerPC,POWER7 from the POWER7 family. The reason for that is that the Sapphire firmware (a h0st firmware) uses PowerPC,POWER7+ already and since no specification defines exactly the CPU nodes naming in the device tree, we better stay in sync with the host firmware. Signed-off-by: Alexey Kardashevskiy a...@ozlabs.ru Thanks, applied to ppc-next. Alex
Re: [Qemu-devel] [PATCH v3 2/2] spapr-rtas: add ibm, (get|set)-system-parameter
On 19.11.2013, at 05:28, Alexey Kardashevskiy a...@ozlabs.ru wrote: This adds very basic handlers for ibm,get-system-parameter and ibm,set-system-parameter RTAS calls. The only parameter handled at the moment is platform-processor-diagnostics-run-mode which is always disabled and does not support changing. This is expected to make ppc64_cpu --run-mode=1 happy. Signed-off-by: Alexey Kardashevskiy a...@ozlabs.ru --- Changes: v3: * reworked all return codes (in a separate patch) v2: * addressed comments from Alex Graf --- hw/ppc/spapr_rtas.c| 47 +++ include/hw/ppc/spapr.h | 2 ++ 2 files changed, 49 insertions(+) diff --git a/hw/ppc/spapr_rtas.c b/hw/ppc/spapr_rtas.c index f9897a5..d7b1f1d 100644 --- a/hw/ppc/spapr_rtas.c +++ b/hw/ppc/spapr_rtas.c @@ -224,6 +224,49 @@ static void rtas_stop_self(PowerPCCPU *cpu, sPAPREnvironment *spapr, env-msr = 0; } +#define DIAGNOSTICS_RUN_MODE42 + +static void rtas_ibm_get_system_parameter(PowerPCCPU *cpu, + sPAPREnvironment *spapr, + uint32_t token, uint32_t nargs, + target_ulong args, + uint32_t nret, target_ulong rets) +{ +target_ulong papameter = rtas_ld(args, 0); Sorry, saw that one too late. What is a papameter? Is it related to the pope? :) +target_ulong buffer = rtas_ld(args, 1); +target_ulong length = rtas_ld(args, 2); +target_ulong ret = RTAS_OUT_NOT_SUPPORTED; + +switch (papameter) { +case DIAGNOSTICS_RUN_MODE: +if (length == 1) { +rtas_st(buffer, 0, 0); +ret = RTAS_OUT_SUCCESS; +} +break; +} + +rtas_st(rets, 0, ret); +} + +static void rtas_ibm_set_system_parameter(PowerPCCPU *cpu, + sPAPREnvironment *spapr, + uint32_t token, uint32_t nargs, + target_ulong args, + uint32_t nret, target_ulong rets) +{ +target_ulong papameter = rtas_ld(args, 0); Here too Alex +target_ulong ret = RTAS_OUT_NOT_SUPPORTED; + +switch (papameter) { +case DIAGNOSTICS_RUN_MODE: +ret = RTAS_OUT_NOT_AUTHORIZED; +break; +} + +rtas_st(rets, 0, ret); +} + static struct rtas_call { const char *name; spapr_rtas_fn fn; @@ -345,6 +388,10 @@ static void core_rtas_register_types(void) rtas_query_cpu_stopped_state); spapr_rtas_register(start-cpu, rtas_start_cpu); spapr_rtas_register(stop-self, rtas_stop_self); +spapr_rtas_register(ibm,get-system-parameter, +rtas_ibm_get_system_parameter); +spapr_rtas_register(ibm,set-system-parameter, +rtas_ibm_set_system_parameter); } type_init(core_rtas_register_types) diff --git a/include/hw/ppc/spapr.h b/include/hw/ppc/spapr.h index 085cfa7..b2f11e9 100644 --- a/include/hw/ppc/spapr.h +++ b/include/hw/ppc/spapr.h @@ -338,6 +338,8 @@ static inline int spapr_allocate_lsi(int hint) #define RTAS_OUT_HW_ERROR -1 #define RTAS_OUT_BUSY -2 #define RTAS_OUT_PARAM_ERROR-3 +#define RTAS_OUT_NOT_SUPPORTED -3 +#define RTAS_OUT_NOT_AUTHORIZED -9002 static inline uint64_t ppc64_phys_to_real(uint64_t addr) { -- 1.8.4.rc4
Re: [Qemu-devel] [PATCH v3 1/2] spapr-rtas: replace return code constants with macros
On 19.11.2013, at 05:28, Alexey Kardashevskiy a...@ozlabs.ru wrote: Signed-off-by: Alexey Kardashevskiy a...@ozlabs.ru Thanks, applied to ppc-next. Alex
Re: [Qemu-devel] [PATCH v3 2/2] spapr-rtas: add ibm, (get|set)-system-parameter
On 19.11.2013, at 05:28, Alexey Kardashevskiy a...@ozlabs.ru wrote: This adds very basic handlers for ibm,get-system-parameter and ibm,set-system-parameter RTAS calls. The only parameter handled at the moment is platform-processor-diagnostics-run-mode which is always disabled and does not support changing. This is expected to make ppc64_cpu --run-mode=1 happy. Signed-off-by: Alexey Kardashevskiy a...@ozlabs.ru --- Changes: v3: * reworked all return codes (in a separate patch) v2: * addressed comments from Alex Graf --- hw/ppc/spapr_rtas.c| 47 +++ include/hw/ppc/spapr.h | 2 ++ 2 files changed, 49 insertions(+) diff --git a/hw/ppc/spapr_rtas.c b/hw/ppc/spapr_rtas.c index f9897a5..d7b1f1d 100644 --- a/hw/ppc/spapr_rtas.c +++ b/hw/ppc/spapr_rtas.c @@ -224,6 +224,49 @@ static void rtas_stop_self(PowerPCCPU *cpu, sPAPREnvironment *spapr, env-msr = 0; } +#define DIAGNOSTICS_RUN_MODE42 + +static void rtas_ibm_get_system_parameter(PowerPCCPU *cpu, + sPAPREnvironment *spapr, + uint32_t token, uint32_t nargs, + target_ulong args, + uint32_t nret, target_ulong rets) +{ +target_ulong papameter = rtas_ld(args, 0); Sorry, saw that one too late. What is a papameter? Is it related to the pope? :) +target_ulong buffer = rtas_ld(args, 1); +target_ulong length = rtas_ld(args, 2); +target_ulong ret = RTAS_OUT_NOT_SUPPORTED; + +switch (papameter) { +case DIAGNOSTICS_RUN_MODE: +if (length == 1) { +rtas_st(buffer, 0, 0); +ret = RTAS_OUT_SUCCESS; +} +break; +} + +rtas_st(rets, 0, ret); +} + +static void rtas_ibm_set_system_parameter(PowerPCCPU *cpu, + sPAPREnvironment *spapr, + uint32_t token, uint32_t nargs, + target_ulong args, + uint32_t nret, target_ulong rets) +{ +target_ulong papameter = rtas_ld(args, 0); Here too Alex +target_ulong ret = RTAS_OUT_NOT_SUPPORTED; + +switch (papameter) { +case DIAGNOSTICS_RUN_MODE: +ret = RTAS_OUT_NOT_AUTHORIZED; +break; +} + +rtas_st(rets, 0, ret); +} + static struct rtas_call { const char *name; spapr_rtas_fn fn; @@ -345,6 +388,10 @@ static void core_rtas_register_types(void) rtas_query_cpu_stopped_state); spapr_rtas_register(start-cpu, rtas_start_cpu); spapr_rtas_register(stop-self, rtas_stop_self); +spapr_rtas_register(ibm,get-system-parameter, +rtas_ibm_get_system_parameter); +spapr_rtas_register(ibm,set-system-parameter, +rtas_ibm_set_system_parameter); } type_init(core_rtas_register_types) diff --git a/include/hw/ppc/spapr.h b/include/hw/ppc/spapr.h index 085cfa7..b2f11e9 100644 --- a/include/hw/ppc/spapr.h +++ b/include/hw/ppc/spapr.h @@ -338,6 +338,8 @@ static inline int spapr_allocate_lsi(int hint) #define RTAS_OUT_HW_ERROR -1 #define RTAS_OUT_BUSY -2 #define RTAS_OUT_PARAM_ERROR-3 +#define RTAS_OUT_NOT_SUPPORTED -3 +#define RTAS_OUT_NOT_AUTHORIZED -9002 static inline uint64_t ppc64_phys_to_real(uint64_t addr) { -- 1.8.4.rc4
Re: [Qemu-devel] [Qemu-ppc] [PATCH v3 2/2] spapr-rtas: add ibm, (get|set)-system-parameter
On 19.11.2013, at 11:36, Alexander Graf ag...@suse.de wrote: On 19.11.2013, at 05:28, Alexey Kardashevskiy a...@ozlabs.ru wrote: This adds very basic handlers for ibm,get-system-parameter and ibm,set-system-parameter RTAS calls. The only parameter handled at the moment is platform-processor-diagnostics-run-mode which is always disabled and does not support changing. This is expected to make ppc64_cpu --run-mode=1 happy. Signed-off-by: Alexey Kardashevskiy a...@ozlabs.ru --- Changes: v3: * reworked all return codes (in a separate patch) v2: * addressed comments from Alex Graf --- hw/ppc/spapr_rtas.c| 47 +++ include/hw/ppc/spapr.h | 2 ++ 2 files changed, 49 insertions(+) diff --git a/hw/ppc/spapr_rtas.c b/hw/ppc/spapr_rtas.c index f9897a5..d7b1f1d 100644 --- a/hw/ppc/spapr_rtas.c +++ b/hw/ppc/spapr_rtas.c @@ -224,6 +224,49 @@ static void rtas_stop_self(PowerPCCPU *cpu, sPAPREnvironment *spapr, env-msr = 0; } +#define DIAGNOSTICS_RUN_MODE42 + +static void rtas_ibm_get_system_parameter(PowerPCCPU *cpu, + sPAPREnvironment *spapr, + uint32_t token, uint32_t nargs, + target_ulong args, + uint32_t nret, target_ulong rets) +{ +target_ulong papameter = rtas_ld(args, 0); Sorry, saw that one too late. What is a papameter? Is it related to the pope? :) I changed it locally to parameter and applied the patch to ppc-next. Thanks a lot. Alex
Re: [Qemu-devel] [PULL 11/13] target-i386: forward CPUID cache leaves when -cpu host is used
Il 19/11/2013 11:25, Peter Lieven ha scritto: ~/git/qemu$ x86_64-softmmu/qemu-system-x86_64 -m 2048 -drive if=virtio,file=iscsi://172.21.200.45/iqn.2001-05.com.equallogic:0-8a0906-9d95c510a-344001d54795289f-2012-r2-1-7-0/0,format=raw,cache=writeback,aio=native -smp 2,cores=2,threads=1,sockets=1 -cpu host -monitor stdio -vnc :1 -enable-kvm -usb -usbdevice tablet -vga cirrus -global virtio-blk-pci.scsi=off -serial null -parallel null -boot c What is your host CPU's topology With just -smp 2 it works. However, have a look at my other email I think there is a bug in smp_parse, because -smp 2 yields cpus=2,cores=1,threads=1,sockets=1 whereas I think cores should be 2. The code matching the comment in vl.c (compute missing values, prefer sockets over cores over threads) would be like -smp cpu=2,cores=1,threads=1,sockets=2, giving this code: if (cpus == 0) { sockets = sockets 0 ? sockets : 1; cores = cores 0 ? cores : 1; threads = threads 0 ? threads : 1; cpus = cores * threads * sockets; } else if (sockets == 0) { cores = cores 0 ? cores : 1; threads = threads 0 ? threads : 1; sockets = cpus / (cores * threads); } else if (cores == 0) { threads = threads 0 ? threads : 1; cores = cpus / (sockets * threads); } else { threads = cpus / (sockets * cores); } What you suggest is cores over threads over sockets: if (cpus == 0) { cores = cores 0 ? cores : 1; threads = threads 0 ? threads : 1; sockets = sockets 0 ? sockets : 1; cpus = cores * threads * sockets; } else if (cores == 0) { threads = threads 0 ? threads : 1; sockets = sockets 0 ? sockets : 1; cores = cpus / (threads * sockets); } else if (threads == 0) { sockets = sockets 0 ? sockets : 1; threads = cpus / (cores * sockets); } else { sockets = cpus / (cores * threads); } Can you test which of these two work? But I agree it's best to disable cache-leaf forwarding. Paolo
Re: [Qemu-devel] [PULL 11/13] target-i386: forward CPUID cache leaves when -cpu host is used
Il 18/11/2013 20:53, Peter Lieven ha scritto: The essential part is -enable-kvm -smp 2,sockets=1,cores=2,threads=1 -cpu host. I believe the corect fix could be to disabled the cache leave forwarding as soon as the user specifies his own socket/core/thread layout. Please test this: diff --git a/include/sysemu/cpus.h b/include/sysemu/cpus.h index 6502488..170fd70 100644 --- a/include/sysemu/cpus.h +++ b/include/sysemu/cpus.h @@ -17,6 +17,7 @@ void qtest_clock_warp(int64_t dest); /* vl.c */ extern int smp_cores; extern int smp_threads; +extern bool smp_manual_topology; #else /* *-user doesn't have configurable SMP topology */ #define smp_cores 1 diff --git a/target-i386/cpu.c b/target-i386/cpu.c index 864c80e..49b5d45 100644 --- a/target-i386/cpu.c +++ b/target-i386/cpu.c @@ -1149,7 +1149,7 @@ static void kvm_cpu_fill_host(x86_def_t *x86_cpu_def) assert(kvm_enabled()); x86_cpu_def-name = host; -x86_cpu_def-cache_info_passthrough = true; +x86_cpu_def-cache_info_passthrough = !smp_manual_topology; host_cpuid(0x0, 0, eax, ebx, ecx, edx); x86_cpu_vendor_words2str(x86_cpu_def-vendor, ebx, edx, ecx); diff --git a/vl.c b/vl.c index 4ad15b8..f319976 100644 --- a/vl.c +++ b/vl.c @@ -207,6 +207,7 @@ CharDriverState *virtcon_hds[MAX_VIRTIO_CONSOLES]; CharDriverState *sclp_hds[MAX_SCLP_CONSOLES]; int win2k_install_hack = 0; int singlestep = 0; +bool smp_manual_topology = false; int smp_cpus = 1; int max_cpus = 0; int smp_cores = 1; @@ -1391,6 +1392,8 @@ static void smp_parse(QemuOpts *opts) unsigned cores = qemu_opt_get_number(opts, cores, 0); unsigned threads = qemu_opt_get_number(opts, threads, 0); +smp_manual_topology = sockets || threads || cores; + /* compute missing values, prefer sockets over cores over threads */ if (cpus == 0 || sockets == 0) { sockets = sockets 0 ? sockets : 1;
Re: [Qemu-devel] [PULL 11/13] target-i386: forward CPUID cache leaves when -cpu host is used
On 19.11.2013 11:47, Paolo Bonzini wrote: Il 19/11/2013 11:25, Peter Lieven ha scritto: ~/git/qemu$ x86_64-softmmu/qemu-system-x86_64 -m 2048 -drive if=virtio,file=iscsi://172.21.200.45/iqn.2001-05.com.equallogic:0-8a0906-9d95c510a-344001d54795289f-2012-r2-1-7-0/0,format=raw,cache=writeback,aio=native -smp 2,cores=2,threads=1,sockets=1 -cpu host -monitor stdio -vnc :1 -enable-kvm -usb -usbdevice tablet -vga cirrus -global virtio-blk-pci.scsi=off -serial null -parallel null -boot c What is your host CPU's topology I tested it with 1 socket, 2 cores, 2 threads per core (my workstation) and 2 sockets, 8 cores per socket, 2 threads per thread. Both crash. With just -smp 2 it works. However, have a look at my other email I think there is a bug in smp_parse, because -smp 2 yields cpus=2,cores=1,threads=1,sockets=1 whereas I think cores should be 2. The code matching the comment in vl.c (compute missing values, prefer sockets over cores over threads) would be like -smp cpu=2,cores=1,threads=1,sockets=2, giving this code: if (cpus == 0) { sockets = sockets 0 ? sockets : 1; cores = cores 0 ? cores : 1; threads = threads 0 ? threads : 1; cpus = cores * threads * sockets; } else if (sockets == 0) { cores = cores 0 ? cores : 1; threads = threads 0 ? threads : 1; sockets = cpus / (cores * threads); } else if (cores == 0) { threads = threads 0 ? threads : 1; cores = cpus / (sockets * threads); } else { threads = cpus / (sockets * cores); } I am fine with either of the both variants, it should just be consistent ;-) What you suggest is cores over threads over sockets: if (cpus == 0) { cores = cores 0 ? cores : 1; threads = threads 0 ? threads : 1; sockets = sockets 0 ? sockets : 1; cpus = cores * threads * sockets; } else if (cores == 0) { threads = threads 0 ? threads : 1; sockets = sockets 0 ? sockets : 1; cores = cpus / (threads * sockets); } else if (threads == 0) { sockets = sockets 0 ? sockets : 1; threads = cpus / (cores * sockets); } else { sockets = cpus / (cores * threads); } Can you test which of these two work? But I agree it's best to disable cache-leaf forwarding. The problem is, its broken because at least cpuid index 4 includes a hint to the number of cores and threads. I think we have to disable the cache leaf forwarding if the qemu cpu topology does not match the host topology. I also tried to fix index 4, but this alone seems to be not enough. at least in index 2 seems also to be some info about cores and threads (which is currently not there).
Re: [Qemu-devel] [PATCH] extend limit of physical sections number
On Sat, Sep 28, 2013 at 12:49:20AM +0800, Amos Kong wrote: # qemu -drive file=/disk0,if=none,id=v0,format=qcow2 \ -device virtio-blk-pci,drive=v0,id=v00,multifunction=on,addr=0x04.0 Launching guest with more than 32 virtio-blk disks, qemu will crash, because there are too many BARs. This patch brings the limit of non-tcg up by a factor of 8 (32767 / 4096), i.e. 32*8 = 256. I re-tested with latest guest kernel (3.10.0-rc5), crash still occurred after applied this patch. 1. phys_section_add: assert(next_map.sections_nb TARGET_PAGE_SIZE); crash 2. phys_section_add: assert(next_map.sections_nb SHRT_MAX); crash 3. without this assert of next_map.sections_nb in phys_section_add crash occurred at register_subpage(): assert(existing-mr-subpage || existing-mr == io_mem_unassigned); Signed-off-by: Paolo Bonzini pbonz...@redhat.com Signed-off-by: Amos Kong ak...@redhat.com --- exec.c | 17 - 1 file changed, 12 insertions(+), 5 deletions(-) diff --git a/exec.c b/exec.c index 5aef833..f639c01 100644 --- a/exec.c +++ b/exec.c @@ -763,11 +763,18 @@ void phys_mem_set_alloc(void *(*alloc)(ram_addr_t)) static uint16_t phys_section_add(MemoryRegionSection *section) { -/* The physical section number is ORed with a page-aligned - * pointer to produce the iotlb entries. Thus it should - * never overflow into the page-aligned value. - */ -assert(next_map.sections_nb TARGET_PAGE_SIZE); +if (tcg_enabled()) { +/* The physical section number is ORed with a page-aligned + * pointer to produce the iotlb entries. Thus it should + * never overflow into the page-aligned value. + */ +assert(next_map.sections_nb TARGET_PAGE_SIZE); +} else { +/* For KVM or Xen we can use the full range of the ptr field + * in PhysPageEntry. + */ +assert(next_map.sections_nb SHRT_MAX); +} if (next_map.sections_nb == next_map.sections_nb_alloc) { next_map.sections_nb_alloc = MAX(next_map.sections_nb_alloc * 2, -- 1.8.3.1 -- Amos.
Re: [Qemu-devel] [PATCH V5 1/5] snapshot: distinguish id and name in load_tmp
Am 10.11.2013 um 23:03 hat Wenchao Xia geschrieben: Since later this function will be used so improve it. The only caller of it now is qemu-img, and it is not impacted by introduce function bdrv_snapshot_load_tmp_by_id_or_name() that call bdrv_snapshot_load_tmp() twice to keep old search logic. bdrv_snapshot_load_tmp_by_id_or_name() return int to let caller know the errno, and errno will be used later. Also fix a typo in comments of bdrv_snapshot_delete(). Signed-off-by: Wenchao Xia xiaw...@linux.vnet.ibm.com --- block/qcow2-snapshot.c| 16 ++- block/qcow2.h |5 +++- block/snapshot.c | 60 ++-- include/block/block_int.h |4 ++- include/block/snapshot.h |7 - qemu-img.c|8 - 6 files changed, 90 insertions(+), 10 deletions(-) diff --git a/block/qcow2-snapshot.c b/block/qcow2-snapshot.c index 3529c68..aeb5efd 100644 --- a/block/qcow2-snapshot.c +++ b/block/qcow2-snapshot.c @@ -675,7 +675,10 @@ int qcow2_snapshot_list(BlockDriverState *bs, QEMUSnapshotInfo **psn_tab) return s-nb_snapshots; } -int qcow2_snapshot_load_tmp(BlockDriverState *bs, const char *snapshot_name) +int qcow2_snapshot_load_tmp(BlockDriverState *bs, +const char *snapshot_id, +const char *name, +Error **errp) { int i, snapshot_index; BDRVQcowState *s = bs-opaque; @@ -683,12 +686,17 @@ int qcow2_snapshot_load_tmp(BlockDriverState *bs, const char *snapshot_name) uint64_t *new_l1_table; int new_l1_bytes; int ret; +const char *device = bdrv_get_device_name(bs); This is wrong, low-level functions shouldn't need the device name for anything. assert(bs-read_only); /* Search the snapshot */ -snapshot_index = find_snapshot_by_id_or_name(bs, snapshot_name); +snapshot_index = find_snapshot_by_id_and_name(bs, snapshot_id, name); if (snapshot_index 0) { +error_setg(errp, + Can't find a snapshot with ID '%s' and name '%s' + on device '%s', + STR_OR_NULL(snapshot_id), STR_OR_NULL(name), device); return -ENOENT; } sn = s-snapshots[snapshot_index]; I think we already discussed the same thing in the context of a different series: The caller knows which device and which snapshot name or ID he used. The only information he really needs is: error_setg(errp, Can't find snapshot); If in the context of the caller's caller this isn't enough, the caller can add this information. I doubt that it's even necessary in this case. @@ -699,6 +707,10 @@ int qcow2_snapshot_load_tmp(BlockDriverState *bs, const char *snapshot_name) ret = bdrv_pread(bs-file, sn-l1_table_offset, new_l1_table, new_l1_bytes); if (ret 0) { +error_setg(errp, + Failed to read l1 table for snapshot with ID '%s' and name + '%s' on device '%s', + sn-id_str, sn-name, device); g_free(new_l1_table); return ret; } diff --git a/block/qcow2.h b/block/qcow2.h index 922e190..303eb26 100644 --- a/block/qcow2.h +++ b/block/qcow2.h @@ -488,7 +488,10 @@ int qcow2_snapshot_delete(BlockDriverState *bs, const char *name, Error **errp); int qcow2_snapshot_list(BlockDriverState *bs, QEMUSnapshotInfo **psn_tab); -int qcow2_snapshot_load_tmp(BlockDriverState *bs, const char *snapshot_name); +int qcow2_snapshot_load_tmp(BlockDriverState *bs, +const char *snapshot_id, +const char *name, +Error **errp); void qcow2_free_snapshots(BlockDriverState *bs); int qcow2_read_snapshots(BlockDriverState *bs); diff --git a/block/snapshot.c b/block/snapshot.c index a05c0c0..e51a7db 100644 --- a/block/snapshot.c +++ b/block/snapshot.c @@ -194,7 +194,7 @@ int bdrv_snapshot_goto(BlockDriverState *bs, * If only @snapshot_id is specified, delete the first one with id * @snapshot_id. * If only @name is specified, delete the first one with name @name. - * if none is specified, return -ENINVAL. + * if none is specified, return -EINVAL. * * Returns: 0 on success, -errno on failure. If @bs is not inserted, return * -ENOMEDIUM. If @snapshot_id and @name are both NULL, return -EINVAL. If @bs @@ -265,18 +265,72 @@ int bdrv_snapshot_list(BlockDriverState *bs, return -ENOTSUP; } +/** + * Temporarily load an internal snapshot by @snapshot_id and @name. + * @bs: block device used in the operation + * @snapshot_id: unique snapshot ID, or NULL + * @name: snapshot name, or NULL + * @errp: location to store error + * + * If both @snapshot_id and @name are specified, load the first one with + * id @snapshot_id and name @name. + * If
Re: [Qemu-devel] [PATCH V5 2/5] qemu-nbd: support internal snapshot export
Am 10.11.2013 um 23:03 hat Wenchao Xia geschrieben: Now it is possible to directly export an internal snapshot, which can be used to probe the snapshot's contents without qemu-img convert. Signed-off-by: Wenchao Xia xiaw...@linux.vnet.ibm.com --- block/snapshot.c | 18 + include/block/snapshot.h |8 +++ qemu-nbd.c | 47 - qemu-nbd.texi|8 ++- 4 files changed, 78 insertions(+), 3 deletions(-) diff --git a/block/snapshot.c b/block/snapshot.c index e51a7db..7cc45fa 100644 --- a/block/snapshot.c +++ b/block/snapshot.c @@ -25,6 +25,24 @@ #include block/snapshot.h #include block/block_int.h +QemuOptsList internal_snapshot_opts = { +.name = snapshot, +.head = QTAILQ_HEAD_INITIALIZER(internal_snapshot_opts.head), +.desc = { +{ +.name = SNAPSHOT_OPT_ID, +.type = QEMU_OPT_STRING, +.help = snapshot id +},{ +.name = SNAPSHOT_OPT_NAME, +.type = QEMU_OPT_STRING, +.help = snapshot name +},{ +/* end of list */ +} +}, +}; + int bdrv_snapshot_find(BlockDriverState *bs, QEMUSnapshotInfo *sn_info, const char *name) { diff --git a/include/block/snapshot.h b/include/block/snapshot.h index d05bea7..770d9bb 100644 --- a/include/block/snapshot.h +++ b/include/block/snapshot.h @@ -27,6 +27,14 @@ #include qemu-common.h #include qapi/error.h +#include qemu/option.h + + +#define SNAPSHOT_OPT_BASE snapshot. +#define SNAPSHOT_OPT_ID snapshot.id +#define SNAPSHOT_OPT_NAME snapshot.name + +extern QemuOptsList internal_snapshot_opts; typedef struct QEMUSnapshotInfo { char id_str[128]; /* unique snapshot id */ diff --git a/qemu-nbd.c b/qemu-nbd.c index c26c98e..f934eaa 100644 --- a/qemu-nbd.c +++ b/qemu-nbd.c @@ -20,6 +20,7 @@ #include block/block.h #include block/nbd.h #include qemu/main-loop.h +#include block/snapshot.h #include stdarg.h #include stdio.h @@ -79,7 +80,14 @@ static void usage(const char *name) \n Block device options:\n -r, --read-only export read-only\n - -s, --snapshot use snapshot file\n + -s, --snapshot use FILE as an external snapshot, create a temporary\n + file with backing_file=FILE, redirect the write to\n + the temporary one\n + -l, --load-snapshot=SNAPSHOT_PARAM\n + load an internal snapshot inside FILE and export it\n + as an read-only device, SNAPSHOT_PARAM format is\n + 'snapshot.id=[ID],snapshot.name=[NAME]', or\n + '[ID_OR_NAME]'\n -n, --nocachedisable host cache\n --cache=MODE set cache mode (none, writeback, ...)\n #ifdef CONFIG_LINUX_AIO @@ -315,7 +323,9 @@ int main(int argc, char **argv) char *device = NULL; int port = NBD_DEFAULT_PORT; off_t fd_size; -const char *sopt = hVb:o:p:rsnP:c:dvk:e:f:t; +QemuOpts *sn_opts = NULL; +const char *sn_id_or_name = NULL; +const char *sopt = hVb:o:p:rsnP:c:dvk:e:f:tl:; struct option lopt[] = { { help, 0, NULL, 'h' }, { version, 0, NULL, 'V' }, @@ -328,6 +338,7 @@ int main(int argc, char **argv) { connect, 1, NULL, 'c' }, { disconnect, 0, NULL, 'd' }, { snapshot, 0, NULL, 's' }, +{ load-snapshot, 1, NULL, 'l' }, { nocache, 0, NULL, 'n' }, { cache, 1, NULL, QEMU_NBD_OPT_CACHE }, #ifdef CONFIG_LINUX_AIO @@ -428,6 +439,18 @@ int main(int argc, char **argv) errx(EXIT_FAILURE, Offset must be positive `%s', optarg); } break; +case 'l': +if (strncmp(optarg, SNAPSHOT_OPT_BASE, strlen(SNAPSHOT_OPT_BASE)) +== 0) { You can avoid this ugly line break by using strstart(): if (strstart(optarg, SNAPSHOT_OPT_BASE, NULL)) { ... Kevin
Re: [Qemu-devel] [PULL 11/13] target-i386: forward CPUID cache leaves when -cpu host is used
next question: is cache leaf forwarding a migration blocker?
Re: [Qemu-devel] [PULL 11/13] target-i386: forward CPUID cache leaves when -cpu host is used
Il 19/11/2013 12:35, Peter Lieven ha scritto: next question: is cache leaf forwarding a migration blocker? -cpu host in general is interesting at migration time, so I would say no. Paolo
Re: [Qemu-devel] [PULL 11/13] target-i386: forward CPUID cache leaves when -cpu host is used
On 19.11.2013 12:37, Paolo Bonzini wrote: Il 19/11/2013 12:35, Peter Lieven ha scritto: next question: is cache leaf forwarding a migration blocker? -cpu host in general is interesting at migration time, so I would say no. It works for for a long time as long as all cpu features that are supported on the source are also supported on the destination. As for the cache leaves feature I would go for making it a optional parameter. If we woudl want to support it, we need to adjust several cpuid indexes to reflect the emulated cpu topology. Question would be to what extend the cache information would then make sense. Or with other words if one wants to use cache leaf pass-thru the topology must match the physical one? Peter
Re: [Qemu-devel] [PATCH for-1.7 v2 7/8] pc: s/INT64_MAX/UINT64_MAX/
Il 07/11/2013 11:41, Marcel Apfelbaum ha scritto: From: Paolo Bonzini pbonz...@redhat.com It doesn't make sense for a region to be INT64_MAX in size: memory core uses UINT64_MAX as a special value meaning all 64 bit this is what was meant here. While this should never affect the PC system which at the moment always has 63 bit size, this makes us hit all kind of corner case bugs with sub-pages, so users are probably better off if we just use UINT64_MAX instead. Reported-by: Luiz Capitulino lcapitul...@redhat.com Tested-by: Luiz Capitulino lcapitul...@redhat.com Reviewed-by: Michael S. Tsirkin m...@redhat.com Signed-off-by: Michael S. Tsirkin m...@redhat.com Michael, is this patch (and 8/8: spapr_pci: s/INT64_MAX/UINT64_MAX/) queued for 1.7 and/or 1.8? Paolo --- hw/i386/pc_piix.c | 2 +- hw/i386/pc_q35.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/hw/i386/pc_piix.c b/hw/i386/pc_piix.c index 4fdb7b6..8e8d354 100644 --- a/hw/i386/pc_piix.c +++ b/hw/i386/pc_piix.c @@ -115,7 +115,7 @@ static void pc_init1(QEMUMachineInitArgs *args, if (pci_enabled) { pci_memory = g_new(MemoryRegion, 1); -memory_region_init(pci_memory, NULL, pci, INT64_MAX); +memory_region_init(pci_memory, NULL, pci, UINT64_MAX); rom_memory = pci_memory; } else { pci_memory = NULL; diff --git a/hw/i386/pc_q35.c b/hw/i386/pc_q35.c index 4c191d3..ca44e05 100644 --- a/hw/i386/pc_q35.c +++ b/hw/i386/pc_q35.c @@ -102,7 +102,7 @@ static void pc_q35_init(QEMUMachineInitArgs *args) /* pci enabled */ if (pci_enabled) { pci_memory = g_new(MemoryRegion, 1); -memory_region_init(pci_memory, NULL, pci, INT64_MAX); +memory_region_init(pci_memory, NULL, pci, UINT64_MAX); rom_memory = pci_memory; } else { pci_memory = NULL;
Re: [Qemu-devel] [PATCH for-1.7 v2 7/8] pc: s/INT64_MAX/UINT64_MAX/
On Tue, Nov 19, 2013 at 12:44:42PM +0100, Paolo Bonzini wrote: Il 07/11/2013 11:41, Marcel Apfelbaum ha scritto: From: Paolo Bonzini pbonz...@redhat.com It doesn't make sense for a region to be INT64_MAX in size: memory core uses UINT64_MAX as a special value meaning all 64 bit this is what was meant here. While this should never affect the PC system which at the moment always has 63 bit size, this makes us hit all kind of corner case bugs with sub-pages, so users are probably better off if we just use UINT64_MAX instead. Reported-by: Luiz Capitulino lcapitul...@redhat.com Tested-by: Luiz Capitulino lcapitul...@redhat.com Reviewed-by: Michael S. Tsirkin m...@redhat.com Signed-off-by: Michael S. Tsirkin m...@redhat.com Michael, is this patch (and 8/8: spapr_pci: s/INT64_MAX/UINT64_MAX/) queued for 1.7 and/or 1.8? Paolo I queued this for 1.8 - I don't think it fixes any known specific bugs. You can see my queue at git://git.kernel.org/pub/scm/virt/kvm/mst/qemu.git pci --- hw/i386/pc_piix.c | 2 +- hw/i386/pc_q35.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/hw/i386/pc_piix.c b/hw/i386/pc_piix.c index 4fdb7b6..8e8d354 100644 --- a/hw/i386/pc_piix.c +++ b/hw/i386/pc_piix.c @@ -115,7 +115,7 @@ static void pc_init1(QEMUMachineInitArgs *args, if (pci_enabled) { pci_memory = g_new(MemoryRegion, 1); -memory_region_init(pci_memory, NULL, pci, INT64_MAX); +memory_region_init(pci_memory, NULL, pci, UINT64_MAX); rom_memory = pci_memory; } else { pci_memory = NULL; diff --git a/hw/i386/pc_q35.c b/hw/i386/pc_q35.c index 4c191d3..ca44e05 100644 --- a/hw/i386/pc_q35.c +++ b/hw/i386/pc_q35.c @@ -102,7 +102,7 @@ static void pc_q35_init(QEMUMachineInitArgs *args) /* pci enabled */ if (pci_enabled) { pci_memory = g_new(MemoryRegion, 1); -memory_region_init(pci_memory, NULL, pci, INT64_MAX); +memory_region_init(pci_memory, NULL, pci, UINT64_MAX); rom_memory = pci_memory; } else { pci_memory = NULL;
Re: [Qemu-devel] [PULL 11/13] target-i386: forward CPUID cache leaves when -cpu host is used
On 19.11.2013 11:47, Paolo Bonzini wrote: Il 19/11/2013 11:25, Peter Lieven ha scritto: ~/git/qemu$ x86_64-softmmu/qemu-system-x86_64 -m 2048 -drive if=virtio,file=iscsi://172.21.200.45/iqn.2001-05.com.equallogic:0-8a0906-9d95c510a-344001d54795289f-2012-r2-1-7-0/0,format=raw,cache=writeback,aio=native -smp 2,cores=2,threads=1,sockets=1 -cpu host -monitor stdio -vnc :1 -enable-kvm -usb -usbdevice tablet -vga cirrus -global virtio-blk-pci.scsi=off -serial null -parallel null -boot c What is your host CPU's topology With just -smp 2 it works. However, have a look at my other email I think there is a bug in smp_parse, because -smp 2 yields cpus=2,cores=1,threads=1,sockets=1 whereas I think cores should be 2. The code matching the comment in vl.c (compute missing values, prefer sockets over cores over threads) would be like -smp cpu=2,cores=1,threads=1,sockets=2, giving this code: if (cpus == 0) { sockets = sockets 0 ? sockets : 1; cores = cores 0 ? cores : 1; threads = threads 0 ? threads : 1; cpus = cores * threads * sockets; } else if (sockets == 0) { cores = cores 0 ? cores : 1; threads = threads 0 ? threads : 1; sockets = cpus / (cores * threads); } else if (cores == 0) { threads = threads 0 ? threads : 1; cores = cpus / (sockets * threads); } else { threads = cpus / (sockets * cores); } What you suggest is cores over threads over sockets: if (cpus == 0) { cores = cores 0 ? cores : 1; threads = threads 0 ? threads : 1; sockets = sockets 0 ? sockets : 1; cpus = cores * threads * sockets; } else if (cores == 0) { threads = threads 0 ? threads : 1; sockets = sockets 0 ? sockets : 1; cores = cpus / (threads * sockets); } else if (threads == 0) { sockets = sockets 0 ? sockets : 1; threads = cpus / (cores * sockets); } else { sockets = cpus / (cores * threads); } Can you test which of these two work? But I agree it's best to disable cache-leaf forwarding. The first does make windows boot again and it calculates a correct combination of cpus, threads, cores and sockets. But I think the reason it boots is because cores=threads=1. As its more intuitive (I think) I would prefer your cores over threads over socket . The last thing I would think of is emulating more than 1 socket. -smp N would then mean, N cores, no hyper-threading, 1 socket.
Re: [Qemu-devel] [Qemu-ppc] [PATCH v3 2/2] spapr-rtas: add ibm, (get|set)-system-parameter
On 11/19/2013 09:43 PM, Alexander Graf wrote: On 19.11.2013, at 11:36, Alexander Graf ag...@suse.de wrote: On 19.11.2013, at 05:28, Alexey Kardashevskiy a...@ozlabs.ru wrote: This adds very basic handlers for ibm,get-system-parameter and ibm,set-system-parameter RTAS calls. The only parameter handled at the moment is platform-processor-diagnostics-run-mode which is always disabled and does not support changing. This is expected to make ppc64_cpu --run-mode=1 happy. Signed-off-by: Alexey Kardashevskiy a...@ozlabs.ru --- Changes: v3: * reworked all return codes (in a separate patch) v2: * addressed comments from Alex Graf --- hw/ppc/spapr_rtas.c| 47 +++ include/hw/ppc/spapr.h | 2 ++ 2 files changed, 49 insertions(+) diff --git a/hw/ppc/spapr_rtas.c b/hw/ppc/spapr_rtas.c index f9897a5..d7b1f1d 100644 --- a/hw/ppc/spapr_rtas.c +++ b/hw/ppc/spapr_rtas.c @@ -224,6 +224,49 @@ static void rtas_stop_self(PowerPCCPU *cpu, sPAPREnvironment *spapr, env-msr = 0; } +#define DIAGNOSTICS_RUN_MODE42 + +static void rtas_ibm_get_system_parameter(PowerPCCPU *cpu, + sPAPREnvironment *spapr, + uint32_t token, uint32_t nargs, + target_ulong args, + uint32_t nret, target_ulong rets) +{ +target_ulong papameter = rtas_ld(args, 0); Sorry, saw that one too late. What is a papameter? Is it related to the pope? :) I changed it locally to parameter and applied the patch to ppc-next. Thanks a lot. Oh. git citool does not spell check the code :) Thanks! -- Alexey
Re: [Qemu-devel] [PULL 11/13] target-i386: forward CPUID cache leaves when -cpu host is used
On 19.11.2013 13:03, Peter Lieven wrote: On 19.11.2013 11:47, Paolo Bonzini wrote: Il 19/11/2013 11:25, Peter Lieven ha scritto: ~/git/qemu$ x86_64-softmmu/qemu-system-x86_64 -m 2048 -drive if=virtio,file=iscsi://172.21.200.45/iqn.2001-05.com.equallogic:0-8a0906-9d95c510a-344001d54795289f-2012-r2-1-7-0/0,format=raw,cache=writeback,aio=native -smp 2,cores=2,threads=1,sockets=1 -cpu host -monitor stdio -vnc :1 -enable-kvm -usb -usbdevice tablet -vga cirrus -global virtio-blk-pci.scsi=off -serial null -parallel null -boot c What is your host CPU's topology With just -smp 2 it works. However, have a look at my other email I think there is a bug in smp_parse, because -smp 2 yields cpus=2,cores=1,threads=1,sockets=1 whereas I think cores should be 2. The code matching the comment in vl.c (compute missing values, prefer sockets over cores over threads) would be like -smp cpu=2,cores=1,threads=1,sockets=2, giving this code: if (cpus == 0) { sockets = sockets 0 ? sockets : 1; cores = cores 0 ? cores : 1; threads = threads 0 ? threads : 1; cpus = cores * threads * sockets; } else if (sockets == 0) { cores = cores 0 ? cores : 1; threads = threads 0 ? threads : 1; sockets = cpus / (cores * threads); } else if (cores == 0) { threads = threads 0 ? threads : 1; cores = cpus / (sockets * threads); } else { threads = cpus / (sockets * cores); } What you suggest is cores over threads over sockets: if (cpus == 0) { cores = cores 0 ? cores : 1; threads = threads 0 ? threads : 1; sockets = sockets 0 ? sockets : 1; cpus = cores * threads * sockets; } else if (cores == 0) { threads = threads 0 ? threads : 1; sockets = sockets 0 ? sockets : 1; cores = cpus / (threads * sockets); } else if (threads == 0) { sockets = sockets 0 ? sockets : 1; threads = cpus / (cores * sockets); } else { sockets = cpus / (cores * threads); } Can you test which of these two work? But I agree it's best to disable cache-leaf forwarding. The first does make windows boot again and it calculates a correct combination of cpus, threads, cores and sockets. But I think the reason it boots is because cores=threads=1. Forgot to mention: In this case the information about cores and threads is not retreived from additional indexes. bits 16..23 in ebx in index 0x0001 are zero. So bottom line, the whole cache leaf passthru thing only worked because of a bug in smp_parse yielding threads and cores 1 by default.
Re: [Qemu-devel] [PULL 11/13] target-i386: forward CPUID cache leaves when -cpu host is used
Il 19/11/2013 13:03, Peter Lieven ha scritto: Can you test which of these two work? But I agree it's best to disable cache-leaf forwarding. The first does make windows boot again and it calculates a correct combination of cpus, threads, cores and sockets. But I think the reason it boots is because cores=threads=1. As its more intuitive (I think) I would prefer your cores over threads over socket . The last thing I would think of is emulating more than 1 socket. -smp N would then mean, N cores, no hyper-threading, 1 socket. After looking more at the docs, I think I found the bug. Can you test this? diff --git a/target-i386/cpu.c b/target-i386/cpu.c index 864c80e..16d4db1 100644 --- a/target-i386/cpu.c +++ b/target-i386/cpu.c @@ -2086,14 +2086,10 @@ void cpu_x86_cpuid(CPUX86State *env, uint32_t index, uint32_t count, /* cache info: needed for Core compatibility */ if (cpu-cache_info_passthrough) { host_cpuid(index, count, eax, ebx, ecx, edx); -break; -} -if (cs-nr_cores 1) { -*eax = (cs-nr_cores - 1) 26; +*eax = ~0xFC00; } else { *eax = 0; -} -switch (count) { +switch (count) { case 0: /* L1 dcache info */ *eax |= CPUID_4_TYPE_DCACHE | \ CPUID_4_LEVEL(1) | \ @@ -2118,9 +2114,6 @@ void cpu_x86_cpuid(CPUX86State *env, uint32_t index, uint32_t count, *eax |= CPUID_4_TYPE_UNIFIED | \ CPUID_4_LEVEL(2) | \ CPUID_4_SELF_INIT_LEVEL; -if (cs-nr_threads 1) { -*eax |= (cs-nr_threads - 1) 14; -} *ebx = (L2_LINE_SIZE - 1) | \ ((L2_PARTITIONS - 1) 12) | \ ((L2_ASSOCIATIVITY - 1) 22); @@ -2133,6 +2126,12 @@ void cpu_x86_cpuid(CPUX86State *env, uint32_t index, uint32_t count, *ecx = 0; *edx = 0; break; +} +} + +/* We give out APIC IDs ourselves, so force bits 31..26 even for -cpu host. */ +if (cs-nr_cores 1) { +*eax |= (cs-nr_cores - 1) 26; } break; case 5: Paolo
Re: [Qemu-devel] [edk2] [edk2 PATCH 0/1] OvmfPkg: grab ACPI tables from QEMU
On 11/19/13 09:54, Gerd Hoffmann wrote: Hi, ACPI PciWindow32: Base=0xA000 End=0xFEEF Length=0x5EF0 begin32=c000 end32=fec0 begin64=0 end64=0 qemu seabios pick a 32bit window size which allows to cover it with a single mtrr entry. Size must be a power of two for that to work. [root@fedora ~]# cat /proc/mtrr reg00: base=0x08000 ( 2048MB), size= 2048MB, count=1: uncachable So we have three cases for piix (as you've figured in the source code already). Start at 0x8000 (2G window), 0xc000 (1G window) and 0xe000 (512M window). btw: q35 has a fixed 1G window, max low ram addr is 0xb00, the remaining address space (0xb000 - 0xc000) is used for mmconfig. I guess the range starting at 0xc000 is somehow incompatible with the EFI memory map. (I can't actually explain this idea because, again, this second range is a proper subset of the former, and its size is still 1004MB.) Probably efi places the gfx memory bar somewhere between 0xa000 and 0xc000. Sets up efifb accordingly. Then the linux kernel loads and figures Oh, that bar is outside the 0xc000+ window and goes remap it - efifb writes go into nowhere. Thank you for the explanation. How do I fix it though? :) I could change the MMIO HOBs in PEI (OvmfPkg/PlatformPei/Platform.c): // // Video memory + Legacy BIOS region // AddIoMemoryRangeHob (0x0A, BASE_1MB); // // address purpose size // - // max(top, 2g) PCI MMIO 0xFC00 - max(top, 2g) // 0xFC00gap 44 MB // 0xFEC0IO-APIC4 KB // 0xFEC01000gap 1020 KB // 0xFED0HPET 1 KB // 0xFED00400gap 1023 KB // 0xFEE0LAPIC 1 MB // AddIoMemoryRangeHob (TopOfMemory BASE_2GB ? BASE_2GB : TopOfMemory, 0xFC00); AddIoMemoryBaseSizeHob (0xFEC0, SIZE_4KB); AddIoMemoryBaseSizeHob (0xFED0, SIZE_1KB); AddIoMemoryBaseSizeHob (PcdGet32(PcdCpuLocalApicBaseAddress), SIZE_1MB); to imitate the same three cases. The HOB with the lowest address produced here would affect the BAR placement as well. ... Yes, I tested the attached patch, and it makes the display work in both 2560MB guests. However, I don't like the idea of hardwiring those boundaries here. (The current values are also hardwired, but they are better: they are not the consequence of SeaBIOS has done it like this forever -- inter-firmware dependency, especially when they aren't each other's payloads, is bad IMHO.) We'd need something dynamic here, like a memory map from qemu. ... Which puts us in the same boat with Wei :) Thanks Laszlo From 9cf2af82399d7d7a9717ff6ac17860b66c705a64 Mon Sep 17 00:00:00 2001 From: Laszlo Ersek ler...@redhat.com Date: Tue, 19 Nov 2013 13:07:41 +0100 Subject: [PATCH] OvmfPkg/PlatformPei: follow SeaBIOS tradition with 32-bit PCI hole placement Contributed-under: TianoCore Contribution Agreement 1.0 Signed-off-by: Laszlo Ersek ler...@redhat.com --- OvmfPkg/PlatformPei/Platform.c | 6 -- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/OvmfPkg/PlatformPei/Platform.c b/OvmfPkg/PlatformPei/Platform.c index fb56e99..5bc0d74 100644 --- a/OvmfPkg/PlatformPei/Platform.c +++ b/OvmfPkg/PlatformPei/Platform.c @@ -197,7 +197,7 @@ MemMapInitialization ( // // address purpose size // - - // max(top, 2g) PCI MMIO 0xFC00 - max(top, 2g) + // 2G/3G/3.5GPCI MMIO0xFC00 - 2G/3G/3.5G // 0xFC00gap 44 MB // 0xFEC0IO-APIC4 KB // 0xFEC01000gap 1020 KB @@ -205,7 +205,9 @@ MemMapInitialization ( // 0xFED00400gap 1023 KB // 0xFEE0LAPIC 1 MB // - AddIoMemoryRangeHob (TopOfMemory BASE_2GB ? BASE_2GB : TopOfMemory, 0xFC00); + AddIoMemoryRangeHob (TopOfMemory = 0x8000 ? 0x8000 : + TopOfMemory = 0xC000 ? 0xC000 : + 0xE000, 0xFC00); AddIoMemoryBaseSizeHob (0xFEC0, SIZE_4KB); AddIoMemoryBaseSizeHob (0xFED0, SIZE_1KB); AddIoMemoryBaseSizeHob (PcdGet32(PcdCpuLocalApicBaseAddress), SIZE_1MB); -- 1.8.3.1
Re: [Qemu-devel] [PULL 11/13] target-i386: forward CPUID cache leaves when -cpu host is used
On 19.11.2013 13:14, Paolo Bonzini wrote: Il 19/11/2013 13:03, Peter Lieven ha scritto: Can you test which of these two work? But I agree it's best to disable cache-leaf forwarding. The first does make windows boot again and it calculates a correct combination of cpus, threads, cores and sockets. But I think the reason it boots is because cores=threads=1. As its more intuitive (I think) I would prefer your cores over threads over socket . The last thing I would think of is emulating more than 1 socket. -smp N would then mean, N cores, no hyper-threading, 1 socket. After looking more at the docs, I think I found the bug. Can you test this? diff --git a/target-i386/cpu.c b/target-i386/cpu.c index 864c80e..16d4db1 100644 --- a/target-i386/cpu.c +++ b/target-i386/cpu.c @@ -2086,14 +2086,10 @@ void cpu_x86_cpuid(CPUX86State *env, uint32_t index, uint32_t count, /* cache info: needed for Core compatibility */ if (cpu-cache_info_passthrough) { host_cpuid(index, count, eax, ebx, ecx, edx); -break; -} -if (cs-nr_cores 1) { -*eax = (cs-nr_cores - 1) 26; +*eax = ~0xFC00; } else { *eax = 0; -} -switch (count) { +switch (count) { case 0: /* L1 dcache info */ *eax |= CPUID_4_TYPE_DCACHE | \ CPUID_4_LEVEL(1) | \ @@ -2118,9 +2114,6 @@ void cpu_x86_cpuid(CPUX86State *env, uint32_t index, uint32_t count, *eax |= CPUID_4_TYPE_UNIFIED | \ CPUID_4_LEVEL(2) | \ CPUID_4_SELF_INIT_LEVEL; -if (cs-nr_threads 1) { -*eax |= (cs-nr_threads - 1) 14; -} *ebx = (L2_LINE_SIZE - 1) | \ ((L2_PARTITIONS - 1) 12) | \ ((L2_ASSOCIATIVITY - 1) 22); @@ -2133,6 +2126,12 @@ void cpu_x86_cpuid(CPUX86State *env, uint32_t index, uint32_t count, *ecx = 0; *edx = 0; break; +} +} + +/* We give out APIC IDs ourselves, so force bits 31..26 even for -cpu host. */ +if (cs-nr_cores 1) { +*eax |= (cs-nr_cores - 1) 26; } break; case 5: Paolo I already tried exactly this fix. Its reading index 0x004 for increasing indexes until qemu aborts: ~/git/qemu$ x86_64-softmmu/qemu-system-x86_64 -m 2048 -drive if=virtio,file=iscsi://172.21.200.45/iqn.2001-05.com.equallogic:0-8a0906-9d95c510a-344001d54795289f-2012-r2-1-7-0/0,format=raw,cache=writeback,aio=native -cpu host -monitor stdio -vnc :1 -enable-kvm -usb -usbdevice tablet -vga cirrus -global virtio-blk-pci.scsi=off -smp 4,cores=4,threads=1,sockets=1 -serial null -parallel null -boot c (qemu) cpuid_data is full, no space for cpuid(eax:0x4,ecx:0x5d) Abgebrochen (Speicherabzug geschrieben) If you really want to have this feature: a) fix smp_parse and leave it at prefer sockets over cores over threads, but use your new code: if (cpus == 0) { sockets = sockets 0 ? sockets : 1; cores = cores 0 ? cores : 1; threads = threads 0 ? threads : 1; cpus = cores * threads * sockets; } else if (sockets == 0) { cores = cores 0 ? cores : 1; threads = threads 0 ? threads : 1; sockets = cpus / (cores * threads); } else if (cores == 0) { threads = threads 0 ? threads : 1; cores = cpus / (sockets * threads); } else { threads = cpus / (sockets * cores); } b) disable cache leaf pass-thru as soon as threads*cores 1. It seems to work as long as there is only one core with one thread per socket. Peter
[Qemu-devel] [PULL for-1.7 0/1] Block patches
Fix for block qtest buildbot failure from Andreas. The following changes since commit 06d22aa36706a3d6051b74c8a183ab554a0cb808: block: Fail if requested driver is not available (2013-11-15 13:37:48 +0100) are available in the git repository at: git://github.com/stefanha/qemu.git block for you to fetch changes up to 2ad645d2854746b55ddfd1d8e951f689cca5d78f: qtest: Use -display none by default (2013-11-19 10:28:14 +0100) Andreas Färber (1): qtest: Use -display none by default tests/boot-order-test.c | 2 +- tests/endianness-test.c | 6 +++--- tests/fw_cfg-test.c | 3 +-- tests/hd-geo-test.c | 2 +- tests/i440fx-test.c | 2 +- tests/libqtest.c| 1 + tests/m48t59-test.c | 2 +- tests/qom-test.c| 2 +- tests/rtc-test.c| 2 +- tests/tmp105-test.c | 2 +- 10 files changed, 12 insertions(+), 12 deletions(-) -- 1.8.4.2
[Qemu-devel] [PULL for-1.7 1/1] qtest: Use -display none by default
From: Andreas Färber afaer...@suse.de This avoids each test needing to add it to suppress windows popping up. [Commit 7ceeedd016facf8d58e14a0d1417fa7225d71072 (blockdev-test: add test case for drive_add duplicate IDs) and commit 43cd209803d6cffb1e1a028c9ff2fd0ff4fce954 (qdev-monitor-test: add device_add leak test cases) added qtest tests without specifying -display none. As a result, make check now tries to use graphics (GTK or SDL). Since graphics are not used by the test and inappropriate for headless make check runs, add the missing -display none. This fixes make check in the QEMU buildbot. -- Stefan] Signed-off-by: Andreas Färber afaer...@suse.de Signed-off-by: Stefan Hajnoczi stefa...@redhat.com --- tests/boot-order-test.c | 2 +- tests/endianness-test.c | 6 +++--- tests/fw_cfg-test.c | 3 +-- tests/hd-geo-test.c | 2 +- tests/i440fx-test.c | 2 +- tests/libqtest.c| 1 + tests/m48t59-test.c | 2 +- tests/qom-test.c| 2 +- tests/rtc-test.c| 2 +- tests/tmp105-test.c | 2 +- 10 files changed, 12 insertions(+), 12 deletions(-) diff --git a/tests/boot-order-test.c b/tests/boot-order-test.c index da158c3..360a691 100644 --- a/tests/boot-order-test.c +++ b/tests/boot-order-test.c @@ -34,7 +34,7 @@ static void test_a_boot_order(const char *machine, char *args; uint64_t actual; -args = g_strdup_printf(-nodefaults -display none%s%s %s, +args = g_strdup_printf(-nodefaults%s%s %s, machine ? -M : , machine ?: , test_args); diff --git a/tests/endianness-test.c b/tests/endianness-test.c index 8719c09..646df7d 100644 --- a/tests/endianness-test.c +++ b/tests/endianness-test.c @@ -121,7 +121,7 @@ static void test_endianness(gconstpointer data) const TestCase *test = data; char *args; -args = g_strdup_printf(-display none -M %s%s%s -device pc-testdev, +args = g_strdup_printf(-M %s%s%s -device pc-testdev, test-machine, test-superio ? -device : , test-superio ?: ); @@ -196,7 +196,7 @@ static void test_endianness_split(gconstpointer data) const TestCase *test = data; char *args; -args = g_strdup_printf(-display none -M %s%s%s -device pc-testdev, +args = g_strdup_printf(-M %s%s%s -device pc-testdev, test-machine, test-superio ? -device : , test-superio ?: ); @@ -243,7 +243,7 @@ static void test_endianness_combine(gconstpointer data) const TestCase *test = data; char *args; -args = g_strdup_printf(-display none -M %s%s%s -device pc-testdev, +args = g_strdup_printf(-M %s%s%s -device pc-testdev, test-machine, test-superio ? -device : , test-superio ?: ); diff --git a/tests/fw_cfg-test.c b/tests/fw_cfg-test.c index b86e49a..e4f355c 100644 --- a/tests/fw_cfg-test.c +++ b/tests/fw_cfg-test.c @@ -126,8 +126,7 @@ int main(int argc, char **argv) g_test_add_func(/fw_cfg/numa, test_fw_cfg_numa); g_test_add_func(/fw_cfg/boot_menu, test_fw_cfg_boot_menu); -cmdline = g_strdup_printf(-display none - -uuid 4600cb32-38ec-4b2f-8acb-81c6ea54f2d8 ); +cmdline = g_strdup_printf(-uuid 4600cb32-38ec-4b2f-8acb-81c6ea54f2d8 ); s = qtest_start(cmdline); g_free(cmdline); diff --git a/tests/hd-geo-test.c b/tests/hd-geo-test.c index b72042e..c84d1e7 100644 --- a/tests/hd-geo-test.c +++ b/tests/hd-geo-test.c @@ -171,7 +171,7 @@ static int setup_common(char *argv[], int argv_sz) { memset(cur_ide, 0, sizeof(cur_ide)); return append_arg(0, argv, argv_sz, - g_strdup(-nodefaults -display none)); + g_strdup(-nodefaults)); } static void setup_mbr(int img_idx, MBRcontents mbr) diff --git a/tests/i440fx-test.c b/tests/i440fx-test.c index 08ce820..65c786c 100644 --- a/tests/i440fx-test.c +++ b/tests/i440fx-test.c @@ -265,7 +265,7 @@ int main(int argc, char **argv) data.num_cpus = 1; -cmdline = g_strdup_printf(-display none -smp %d, data.num_cpus); +cmdline = g_strdup_printf(-smp %d, data.num_cpus); s = qtest_start(cmdline); g_free(cmdline); diff --git a/tests/libqtest.c b/tests/libqtest.c index 83424c3..359d571 100644 --- a/tests/libqtest.c +++ b/tests/libqtest.c @@ -135,6 +135,7 @@ QTestState *qtest_init(const char *extra_args) -qmp unix:%s,nowait -pidfile %s -machine accel=qtest + -display none %s, qemu_binary, s-socket_path, s-qmp_socket_path, pid_file, extra_args ?: ); diff --git a/tests/m48t59-test.c
[Qemu-devel] [PULL for-1.7 0/2] Net patches
Bug fixes for QEMU 1.7. The following changes since commit 5c5432e7d630592ddcc1876ac8a1505f8f14ef15: Merge remote-tracking branch 'luiz/queue/qmp' into staging (2013-11-13 11:49:27 -0800) are available in the git repository at: git://github.com/stefanha/qemu.git net for you to fetch changes up to 96e35046e4a97df5b4e1e24e217eb1e1701c7c71: virtio-net: fix the memory leak in rxfilter_notify() (2013-11-19 10:26:55 +0100) Amos Kong (1): virtio-net: fix the memory leak in rxfilter_notify() Sebastian Huber (1): smc91c111: Fix receive starvation hw/net/smc91c111.c | 1 + hw/net/virtio-net.c | 8 2 files changed, 5 insertions(+), 4 deletions(-) -- 1.8.4.2
[Qemu-devel] [PULL for-1.7 2/2] virtio-net: fix the memory leak in rxfilter_notify()
From: Amos Kong ak...@redhat.com object_get_canonical_path() returns a gchar*, it should be freed by the caller. Signed-off-by: Amos Kong ak...@redhat.com Reviewed-by: Michael S. Tsirkin m...@redhat.com Reviewed-by: Vlad Yasevich vyase...@redhat.com Reviewed-by: Andreas Färber afaer...@suse.de Signed-off-by: Stefan Hajnoczi stefa...@redhat.com --- hw/net/virtio-net.c | 8 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/hw/net/virtio-net.c b/hw/net/virtio-net.c index 613f144..b75c753 100644 --- a/hw/net/virtio-net.c +++ b/hw/net/virtio-net.c @@ -200,16 +200,16 @@ static void rxfilter_notify(NetClientState *nc) VirtIONet *n = qemu_get_nic_opaque(nc); if (nc-rxfilter_notify_enabled) { +gchar *path = object_get_canonical_path(OBJECT(n-qdev)); if (n-netclient_name) { event_data = qobject_from_jsonf({ 'name': %s, 'path': %s }, -n-netclient_name, - object_get_canonical_path(OBJECT(n-qdev))); +n-netclient_name, path); } else { -event_data = qobject_from_jsonf({ 'path': %s }, - object_get_canonical_path(OBJECT(n-qdev))); +event_data = qobject_from_jsonf({ 'path': %s }, path); } monitor_protocol_event(QEVENT_NIC_RX_FILTER_CHANGED, event_data); qobject_decref(event_data); +g_free(path); /* disable event notification to avoid events flooding */ nc-rxfilter_notify_enabled = 0; -- 1.8.4.2
[Qemu-devel] [PULL for-1.7 1/2] smc91c111: Fix receive starvation
From: Sebastian Huber sebastian.hu...@embedded-brains.de In case the smc91c111 interface signals that it cannot receive more packets the packets are queued and further reception will be disabled. In case the interface is again ready to receive packets notify the upper layer. Signed-off-by: Sebastian Huber sebastian.hu...@embedded-brains.de Signed-off-by: Stefan Hajnoczi stefa...@redhat.com --- hw/net/smc91c111.c | 1 + 1 file changed, 1 insertion(+) diff --git a/hw/net/smc91c111.c b/hw/net/smc91c111.c index f5963e2..a8e29b3 100644 --- a/hw/net/smc91c111.c +++ b/hw/net/smc91c111.c @@ -185,6 +185,7 @@ static void smc91c111_release_packet(smc91c111_state *s, int packet) s-allocated = ~(1 packet); if (s-tx_alloc == 0x80) smc91c111_tx_alloc(s); +qemu_flush_queued_packets(qemu_get_queue(s-nic)); } /* Flush the TX FIFO. */ -- 1.8.4.2
Re: [Qemu-devel] [PATCH for-1.7] pci: unregister vmstate_pcibus on unplug
Am 06.11.2013 23:52, schrieb Bandan Das: PCIBus registers a vmstate during init. Unregister it upon removal/unplug. Signed-off-by: Bandan Das b...@redhat.com Michael, this patch looks good for 1.7 to me, are you planning to still pick it up? Only one small comment below. Cc: qemu-sta...@nongnu.org --- Note that I didn't add a instance_init to register vmstate (yet) due to concerns expressed by Andreas that we shouldn't be registering global state there. What's happening here is the following: instance_init does in fact not register anything, but vmstate_unregister() becomes a no-op loop if the vmsd+opaque combo is not registered, so it is safe. The registration happens in pci_bus_new() / pci_bus_new_inplace(), which I believe all PCI buses to date inside QEMU use, i.e. after instance_init, so in practice unregistering will not be no-op. hw/pci/pci.c | 8 1 file changed, 8 insertions(+) diff --git a/hw/pci/pci.c b/hw/pci/pci.c index a98c8a0..63ef7ce 100644 --- a/hw/pci/pci.c +++ b/hw/pci/pci.c @@ -47,6 +47,7 @@ static void pcibus_dev_print(Monitor *mon, DeviceState *dev, int indent); static char *pcibus_get_dev_path(DeviceState *dev); static char *pcibus_get_fw_dev_path(DeviceState *dev); static int pcibus_reset(BusState *qbus); +static void pci_bus_finalize(Object *obj); It may be nicer to avoid the prototype by moving the new pci_bus_finalize() above pci_bus_info. But since what counts is the fix to avoid segfaults during migration on access to a dangling opaque pointer after hot-unplug of a PCI-PCI bridge, Reviewed-by: Andreas Färber afaer...@suse.de Thanks, Andreas static Property pci_props[] = { DEFINE_PROP_PCI_DEVFN(addr, PCIDevice, devfn, -1), @@ -73,6 +74,7 @@ static const TypeInfo pci_bus_info = { .name = TYPE_PCI_BUS, .parent = TYPE_BUS, .instance_size = sizeof(PCIBus), +.instance_finalize = pci_bus_finalize, .class_init = pci_bus_class_init, }; @@ -401,6 +403,12 @@ int pci_bus_num(PCIBus *s) return s-parent_dev-config[PCI_SECONDARY_BUS]; } +static void pci_bus_finalize(Object *obj) +{ +PCIBus *bus = PCI_BUS(obj); +vmstate_unregister(NULL, vmstate_pcibus, bus); +} + static int get_pci_config_device(QEMUFile *f, void *pv, size_t size) { PCIDevice *s = container_of(pv, PCIDevice, config); -- SUSE LINUX Products GmbH, Maxfeldstr. 5, 90409 Nürnberg, Germany GF: Jeff Hawn, Jennifer Guild, Felix Imendörffer; HRB 16746 AG Nürnberg
Re: [Qemu-devel] [PATCH 0/2] qemu-iotests: Filter out qemu-io in all tests
On 11/18/2013 11:50 PM, Fam Zheng wrote: The second patch is too big in size (over 10M), and rejected by list moderator. You can PULL from git branch: https://github.com/famz/qemu.git 035-filter-qemu-io I'm guessing the second patch consists of a tiny amount of code to turn on the filter, while the majority of the patch was automated. It would be helpful to amend your commit message to show how you automated the conversion (was it something like find tests/qemu-iotests -name *.out | \ xargs -L1 sed -i s/qemu-io //g ' ?) Given such a formula in the commit message itself, it would be much easier to review the patch - check that both the non-automatic small modification and the conversion formula make sense, then repeat the conversion formula locally and compare it to your git tree to see that the two results match, and that the testsuite still passes. [Or in other words, I don't plan on reading 10M of mindlessly repetitive changes :) ] tests/qemu-iotests/common.filter | 3 +- 20 files changed, 75546 insertions(+), 75545 deletions(-) Looks like that's the one file with the nontrivial change. diff --git a/tests/qemu-iotests/common.filter b/tests/qemu-iotests/common.filter index 8e7b1a4..0dd82e1 100644 --- a/tests/qemu-iotests/common.filter +++ b/tests/qemu-iotests/common.filter @@ -149,7 +149,8 @@ _filter_win32() # sanitize qemu-io output _filter_qemu_io() { -_filter_win32 | sed -e s/[0-9]* ops\; [0-9/:. sec]* ([0-9/.inf]* [EPTGMKiBbytes]*\/sec and [0-9/.inf]* ops\/sec)/X ops\; XX:XX:XX.X (XXX YYY\/sec and XXX ops\/sec)/ +_filter_win32 | sed -e s/[0-9]* ops\; [0-9/:. sec]* ([0-9/.inf]* [EPTGMKiBbytes]*\/sec and [0-9/.inf]* ops\/sec)/X ops\; XX:XX:XX.X (XXX YYY\/sec and XXX ops\/sec)/ |\ +sed -e s/qemu-io //g } # replace occurrences of QEMU_PROG with qemu Question - why do you pipeline 'sed | sed'? It should be sufficient to just add the s/qemu-io //g instruction into the existing sed pipeline, for one fewer process per filter run. -- Eric Blake eblake redhat com+1-919-301-3266 Libvirt virtualization library http://libvirt.org signature.asc Description: OpenPGP digital signature
Re: [Qemu-devel] [PATCH V5 3/5] qemu-iotests: add 058 internal snapshot export with qemu-nbd case
Am 10.11.2013 um 23:03 hat Wenchao Xia geschrieben: Signed-off-by: Wenchao Xia xiaw...@linux.vnet.ibm.com --- tests/qemu-iotests/058 | 102 tests/qemu-iotests/058.out | 32 ++ tests/qemu-iotests/check |1 + tests/qemu-iotests/group |1 + 4 files changed, 136 insertions(+), 0 deletions(-) create mode 100755 tests/qemu-iotests/058 create mode 100644 tests/qemu-iotests/058.out I think this should have: _supported_proto nbd Or otherwise the check in common needs to be changed. At least for me the test failed without an error message because I didn't have a qemu-nbd symlink in place. Kevin
Re: [Qemu-devel] [PATCH 1/2] qemu-iotests: Filter qemu-io output in 025
On 11/18/2013 12:21 AM, Fam Zheng wrote: Signed-off-by: Fam Zheng f...@redhat.com --- tests/qemu-iotests/025 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) Reviewed-by: Eric Blake ebl...@redhat.com diff --git a/tests/qemu-iotests/025 b/tests/qemu-iotests/025 index a7241cc..9426c93 100755 --- a/tests/qemu-iotests/025 +++ b/tests/qemu-iotests/025 @@ -56,7 +56,7 @@ _check_test_img echo echo === Resizing image -$QEMU_IO $TEST_IMG EOF +$QEMU_IO $TEST_IMG EOF | _filter_qemu_io length truncate $big_size length -- Eric Blake eblake redhat com+1-919-301-3266 Libvirt virtualization library http://libvirt.org signature.asc Description: OpenPGP digital signature
Re: [Qemu-devel] [PULL 11/13] target-i386: forward CPUID cache leaves when -cpu host is used
Il 19/11/2013 13:32, Peter Lieven ha scritto: + +/* We give out APIC IDs ourselves, so force bits 31..26 even for -cpu host. */ +if (cs-nr_cores 1) { +*eax |= (cs-nr_cores - 1) 26; } break; case 5: I already tried exactly this fix. Its reading index 0x004 for increasing indexes until qemu aborts: Oops, it should be I guess if ((*eax 31) cs-nr_cores 1). Paolo ~/git/qemu$ x86_64-softmmu/qemu-system-x86_64 -m 2048 -drive if=virtio,file=iscsi://172.21.200.45/iqn.2001-05.com.equallogic:0-8a0906-9d95c510a-344001d54795289f-2012-r2-1-7-0/0,format=raw,cache=writeback,aio=native -cpu host -monitor stdio -vnc :1 -enable-kvm -usb -usbdevice tablet -vga cirrus -global virtio-blk-pci.scsi=off -smp 4,cores=4,threads=1,sockets=1 -serial null -parallel null -boot c
Re: [Qemu-devel] [PATCH/RFC] qemu-img: show image conversion speed
On Mon, Nov 18, 2013 at 07:25:09PM +0530, Varad Gautam wrote: Calculate and display write speed when converting image with the -p parameter. qemu-progress:qemu_progress_print() now takes speed parameter to print. How well does this approach work in your testing? Calculating a new speed for every I/O request could lead to very volatile output. If the value jumps around too much it becomes unusable; moving averages solve this problem. Adding speed with hardcoded 'kB/s' units in qemu-progress.c is unfortunate. qemu-progress.c does not know about units. Perhaps the speed units should be passed in when providing speed values. @@ -945,7 +945,7 @@ static int img_compare(int argc, char **argv) filename2 = argv[optind++]; /* Initialize before goto out */ -qemu_progress_init(progress, 2.0); +qemu_progress_init(progress, 2.0, 0); Perhaps compare should report read speed. @@ -1127,7 +1127,7 @@ static int img_convert(int argc, char **argv) const char *fmt, *out_fmt, *cache, *out_baseimg, *out_filename; BlockDriver *drv, *proto_drv; BlockDriverState **bs = NULL, *out_bs = NULL; -int64_t total_sectors, nb_sectors, sector_num, bs_offset; +int64_t total_sectors, nb_sectors, sector_num, bs_offset, time; uint64_t bs_sectors; uint8_t * buf = NULL; const uint8_t *buf1; @@ -1136,7 +1136,7 @@ static int img_convert(int argc, char **argv) QEMUOptionParameter *out_baseimg_param; char *options = NULL; const char *snapshot_name = NULL; -float local_progress = 0; +float local_progress = 0, write_speed = 0; int min_sparse = 8; /* Need at least 4k of zeros for sparse detection */ bool quiet = false; Error *local_err = NULL; @@ -1223,7 +1223,7 @@ static int img_convert(int argc, char **argv) out_filename = argv[argc - 1]; /* Initialize before goto out */ -qemu_progress_init(progress, 2.0); +qemu_progress_init(progress, 2.0, write_speed); if (options is_help_option(options)) { ret = print_block_option_help(out_filename, out_fmt); @@ -1237,7 +1237,7 @@ static int img_convert(int argc, char **argv) goto out; } -qemu_progress_print(0, 100); +qemu_progress_print(0, 100, write_speed); bs = g_malloc0(bs_n * sizeof(BlockDriverState *)); @@ -1460,7 +1460,7 @@ static int img_convert(int argc, char **argv) } } sector_num += n; -qemu_progress_print(local_progress, 100); +qemu_progress_print(local_progress, 100, write_speed); } Write speed is not calculated for compressed writes. -qemu_progress_print(local_progress, 100); +time = qemu_clock_get_ns(QEMU_CLOCK_REALTIME) - time; +write_speed = (sectors_to_bytes(n1) * 10 / (double) time ) / 1048576 ; Please use constants for these magic numbers (e.g. NANOSECONDS_PER_SECOND and MEGABYTE). By the way, shouldn't the speed be in KB/s? @@ -2174,8 +2177,8 @@ static int img_rebase(int argc, char **argv) } filename = argv[optind++]; -qemu_progress_init(progress, 2.0); -qemu_progress_print(0, 100); +qemu_progress_init(progress, 2.0, 0); +qemu_progress_print(0, 100, 0); Perhaps we should provide the write speed?
[Qemu-devel] [PATCH 0/9] usb: redirection streams support + small fixes
Hi Gerd, Here are my outstanding qemu usb patches. Most of them have been send before and are just rebases. As before these depend on kernel / libusb streams support, which will hopefully go upstream for 3.14 . New this time around are: [PATCH 4/9] xhci: Add a few missing checks for disconnected devices This one fixes a bunch of bugs in xhci wrt disconnect handling and should go upstream ASAP [PATCH 8/9] usb-redir: Add support for bulk streams usb-redir now supports streams too [PATCH 9/9] uas: s/ui/iu/ This one is self explanatory, and can go upstream at the earliest convenient moment. Thanks Regards, Hans
[Qemu-devel] [PATCH 1/9] usb: Add max_streams attribute to endpoint info
Signed-off-by: Hans de Goede hdego...@redhat.com --- hw/usb/core.c| 22 ++ hw/usb/desc.c| 2 ++ include/hw/usb.h | 3 +++ 3 files changed, 27 insertions(+) diff --git a/hw/usb/core.c b/hw/usb/core.c index cf59a1a..67ba7d6 100644 --- a/hw/usb/core.c +++ b/hw/usb/core.c @@ -623,6 +623,7 @@ void usb_ep_reset(USBDevice *dev) dev-ep_ctl.type = USB_ENDPOINT_XFER_CONTROL; dev-ep_ctl.ifnum = 0; dev-ep_ctl.max_packet_size = 64; +dev-ep_ctl.max_streams = 0; dev-ep_ctl.dev = dev; dev-ep_ctl.pipeline = false; for (ep = 0; ep USB_MAX_ENDPOINTS; ep++) { @@ -636,6 +637,8 @@ void usb_ep_reset(USBDevice *dev) dev-ep_out[ep].ifnum = USB_INTERFACE_INVALID; dev-ep_in[ep].max_packet_size = 0; dev-ep_out[ep].max_packet_size = 0; +dev-ep_in[ep].max_streams = 0; +dev-ep_out[ep].max_streams = 0; dev-ep_in[ep].dev = dev; dev-ep_out[ep].dev = dev; dev-ep_in[ep].pipeline = false; @@ -764,6 +767,25 @@ int usb_ep_get_max_packet_size(USBDevice *dev, int pid, int ep) return uep-max_packet_size; } +void usb_ep_set_max_streams(USBDevice *dev, int pid, int ep, uint8_t raw) +{ +struct USBEndpoint *uep = usb_ep_get(dev, pid, ep); +int MaxStreams; + +MaxStreams = raw 0x1f; +if (MaxStreams) { +uep-max_streams = 1 MaxStreams; +} else { +uep-max_streams = 0; +} +} + +int usb_ep_get_max_streams(USBDevice *dev, int pid, int ep) +{ +struct USBEndpoint *uep = usb_ep_get(dev, pid, ep); +return uep-max_streams; +} + void usb_ep_set_pipeline(USBDevice *dev, int pid, int ep, bool enabled) { struct USBEndpoint *uep = usb_ep_get(dev, pid, ep); diff --git a/hw/usb/desc.c b/hw/usb/desc.c index bf6c522..5dbe754 100644 --- a/hw/usb/desc.c +++ b/hw/usb/desc.c @@ -385,6 +385,8 @@ static void usb_desc_ep_init(USBDevice *dev) usb_ep_set_ifnum(dev, pid, ep, iface-bInterfaceNumber); usb_ep_set_max_packet_size(dev, pid, ep, iface-eps[e].wMaxPacketSize); +usb_ep_set_max_streams(dev, pid, ep, + iface-eps[e].bmAttributes_super); } } } diff --git a/include/hw/usb.h b/include/hw/usb.h index a7680d4..e9d96ba 100644 --- a/include/hw/usb.h +++ b/include/hw/usb.h @@ -189,6 +189,7 @@ struct USBEndpoint { uint8_t type; uint8_t ifnum; int max_packet_size; +int max_streams; bool pipeline; bool halted; USBDevice *dev; @@ -421,6 +422,8 @@ void usb_ep_set_ifnum(USBDevice *dev, int pid, int ep, uint8_t ifnum); void usb_ep_set_max_packet_size(USBDevice *dev, int pid, int ep, uint16_t raw); int usb_ep_get_max_packet_size(USBDevice *dev, int pid, int ep); +void usb_ep_set_max_streams(USBDevice *dev, int pid, int ep, uint8_t raw); +int usb_ep_get_max_streams(USBDevice *dev, int pid, int ep); void usb_ep_set_pipeline(USBDevice *dev, int pid, int ep, bool enabled); void usb_ep_set_halted(USBDevice *dev, int pid, int ep, bool halted); USBPacket *usb_ep_find_packet_by_id(USBDevice *dev, int pid, int ep, -- 1.8.4.2
[Qemu-devel] [PATCH 2/9] usb: Add usb_device_alloc/free_streams
Signed-off-by: Hans de Goede hdego...@redhat.com --- hw/usb/bus.c | 18 ++ include/hw/usb.h | 12 2 files changed, 30 insertions(+) diff --git a/hw/usb/bus.c b/hw/usb/bus.c index ca329be..09848c6 100644 --- a/hw/usb/bus.c +++ b/hw/usb/bus.c @@ -203,6 +203,24 @@ void usb_device_ep_stopped(USBDevice *dev, USBEndpoint *ep) } } +int usb_device_alloc_streams(USBDevice *dev, USBEndpoint **eps, int nr_eps, + int streams) +{ +USBDeviceClass *klass = USB_DEVICE_GET_CLASS(dev); +if (klass-alloc_streams) { +return klass-alloc_streams(dev, eps, nr_eps, streams); +} +return 0; +} + +void usb_device_free_streams(USBDevice *dev, USBEndpoint **eps, int nr_eps) +{ +USBDeviceClass *klass = USB_DEVICE_GET_CLASS(dev); +if (klass-free_streams) { +klass-free_streams(dev, eps, nr_eps); +} +} + static int usb_qdev_init(DeviceState *qdev) { USBDevice *dev = USB_DEVICE(qdev); diff --git a/include/hw/usb.h b/include/hw/usb.h index e9d96ba..0a6ef4a 100644 --- a/include/hw/usb.h +++ b/include/hw/usb.h @@ -315,6 +315,14 @@ typedef struct USBDeviceClass { */ void (*ep_stopped)(USBDevice *dev, USBEndpoint *ep); +/* + * Called by the hcd to alloc / free streams on a bulk endpoint. + * Optional may be NULL. + */ +int (*alloc_streams)(USBDevice *dev, USBEndpoint **eps, int nr_eps, + int streams); +void (*free_streams)(USBDevice *dev, USBEndpoint **eps, int nr_eps); + const char *product_desc; const USBDesc *usb_desc; } USBDeviceClass; @@ -553,6 +561,10 @@ void usb_device_flush_ep_queue(USBDevice *dev, USBEndpoint *ep); void usb_device_ep_stopped(USBDevice *dev, USBEndpoint *ep); +int usb_device_alloc_streams(USBDevice *dev, USBEndpoint **eps, int nr_eps, + int streams); +void usb_device_free_streams(USBDevice *dev, USBEndpoint **eps, int nr_eps); + const char *usb_device_get_product_desc(USBDevice *dev); const USBDesc *usb_device_get_usb_desc(USBDevice *dev); -- 1.8.4.2
[Qemu-devel] [PATCH 4/9] xhci: Add a few missing checks for disconnected devices
One of the reworks of qemu's usb core made changes to usb-port's disconnect handling. Now ports with a device will always have a non 0 dev member, but if the device is not attached (which is possible with usb redirection), dev-attached will be 0. So supplement all checks for dev to also check dev-attached, and add an extra check in a path where a device check was completely missing. This fixes various crashes (asserts triggering) I've been seeing when xhci attached usb devices get disconnected at the wrong time. Signed-off-by: Hans de Goede hdego...@redhat.com --- hw/usb/hcd-xhci.c | 13 +++-- 1 file changed, 11 insertions(+), 2 deletions(-) diff --git a/hw/usb/hcd-xhci.c b/hw/usb/hcd-xhci.c index 9368348..bafe085 100644 --- a/hw/usb/hcd-xhci.c +++ b/hw/usb/hcd-xhci.c @@ -1600,7 +1600,8 @@ static TRBCCode xhci_reset_ep(XHCIState *xhci, unsigned int slotid, } if (!xhci-slots[slotid-1].uport || -!xhci-slots[slotid-1].uport-dev) { +!xhci-slots[slotid-1].uport-dev || +!xhci-slots[slotid-1].uport-dev-attached) { return CC_USB_TRANSACTION_ERROR; } @@ -2087,6 +2088,14 @@ static void xhci_kick_ep(XHCIState *xhci, unsigned int slotid, return; } +/* If the device has been detached, but the guest has not noticed this + yet the 2 above checks will succeed, but we must NOT continue */ +if (!xhci-slots[slotid - 1].uport || +!xhci-slots[slotid - 1].uport-dev || +!xhci-slots[slotid - 1].uport-dev-attached) { +return; +} + if (epctx-retry) { XHCITransfer *xfer = epctx-retry; @@ -2311,7 +2320,7 @@ static TRBCCode xhci_address_slot(XHCIState *xhci, unsigned int slotid, trace_usb_xhci_slot_address(slotid, uport-path); dev = uport-dev; -if (!dev) { +if (!dev || !dev-attached) { fprintf(stderr, xhci: port %s not connected\n, uport-path); return CC_USB_TRANSACTION_ERROR; } -- 1.8.4.2
[Qemu-devel] [PATCH 5/9] usb-host-libusb: Fill in endpoint max_streams when available
Signed-off-by: Hans de Goede hdego...@redhat.com --- hw/usb/host-libusb.c | 12 1 file changed, 12 insertions(+) diff --git a/hw/usb/host-libusb.c b/hw/usb/host-libusb.c index fd320cd..0dd60b2 100644 --- a/hw/usb/host-libusb.c +++ b/hw/usb/host-libusb.c @@ -720,6 +720,9 @@ static void usb_host_ep_update(USBHostDevice *s) struct libusb_config_descriptor *conf; const struct libusb_interface_descriptor *intf; const struct libusb_endpoint_descriptor *endp; +#if LIBUSBX_API_VERSION = 0x01000102 +struct libusb_ss_endpoint_companion_descriptor *endp_ss_comp; +#endif uint8_t devep, type; int pid, ep; int rc, i, e; @@ -765,6 +768,15 @@ static void usb_host_ep_update(USBHostDevice *s) usb_ep_set_type(udev, pid, ep, type); usb_ep_set_ifnum(udev, pid, ep, i); usb_ep_set_halted(udev, pid, ep, 0); +#if LIBUSBX_API_VERSION = 0x01000102 +if (type == LIBUSB_TRANSFER_TYPE_BULK +libusb_get_ss_endpoint_companion_descriptor(ctx, endp, +endp_ss_comp) == LIBUSB_SUCCESS) { +usb_ep_set_max_streams(udev, pid, ep, + endp_ss_comp-bmAttributes); +libusb_free_ss_endpoint_companion_descriptor(endp_ss_comp); +} +#endif } } -- 1.8.4.2
[Qemu-devel] [PATCH 3/9] xhci: Call usb_device_alloc/free_streams
Note this code is not as KISS as I would like, the reason for this is that the Linux kernel interface wants streams on eps belonging to one interface to be allocated in one call. Things will also work if we do this one ep at a time (as long as all eps support the same amount of streams), but lets stick to the kernel API. Signed-off-by: Hans de Goede hdego...@redhat.com --- hw/usb/hcd-xhci.c | 117 ++ 1 file changed, 117 insertions(+) diff --git a/hw/usb/hcd-xhci.c b/hw/usb/hcd-xhci.c index d84d510..9368348 100644 --- a/hw/usb/hcd-xhci.c +++ b/hw/usb/hcd-xhci.c @@ -1150,6 +1150,111 @@ static void xhci_free_streams(XHCIEPContext *epctx) epctx-nr_pstreams = 0; } +static int xhci_epmask_to_eps_with_streams(XHCIState *xhci, + unsigned int slotid, + uint32_t epmask, + XHCIEPContext **epctxs, + USBEndpoint **eps) +{ +XHCISlot *slot; +XHCIEPContext *epctx; +USBEndpoint *ep; +int i, j; + +assert(slotid = 1 slotid = xhci-numslots); + +slot = xhci-slots[slotid - 1]; + +for (i = 2, j = 0; i = 31; i++) { +if (!(epmask (1 i))) { +continue; +} + +epctx = slot-eps[i - 1]; +ep = xhci_epid_to_usbep(xhci, slotid, i); +if (!epctx || !epctx-nr_pstreams || !ep) { +continue; +} + +if (epctxs) { +epctxs[j] = epctx; +} +eps[j++] = ep; +} +return j; +} + +static void xhci_free_device_streams(XHCIState *xhci, unsigned int slotid, + uint32_t epmask) +{ +USBEndpoint *eps[30]; +int nr_eps; + +nr_eps = xhci_epmask_to_eps_with_streams(xhci, slotid, epmask, NULL, eps); +if (nr_eps) { +usb_device_free_streams(eps[0]-dev, eps, nr_eps); +} +} + +static TRBCCode xhci_alloc_device_streams(XHCIState *xhci, unsigned int slotid, + uint32_t epmask) +{ +XHCIEPContext *epctxs[30]; +USBEndpoint *eps[30]; +int i, r, nr_eps, req_nr_streams, dev_max_streams; + +nr_eps = xhci_epmask_to_eps_with_streams(xhci, slotid, epmask, epctxs, + eps); +if (nr_eps == 0) { +return CC_SUCCESS; +} + +req_nr_streams = epctxs[0]-nr_pstreams; +dev_max_streams = eps[0]-max_streams; + +for (i = 1; i nr_eps; i++) { +/* + * HdG: I don't expect these to ever trigger, but if they do we need + * to come up with another solution, ie group identical endpoints + * together and make an usb_device_alloc_streams call per group. + */ +if (epctxs[i]-nr_pstreams != req_nr_streams) { +FIXME(guest streams config not identical for all eps); +return CC_RESOURCE_ERROR; +} +if (eps[i]-max_streams != dev_max_streams) { +FIXME(device streams config not identical for all eps); +return CC_RESOURCE_ERROR; +} +} + +/* + * max-streams in both the device descriptor and in the controller is a + * power of 2. But stream id 0 is reserved, so if a device can do up to 4 + * streams the guest will ask for 5 rounded up to the next power of 2 which + * becomes 8. For emulated devices usb_device_alloc_streams is a nop. + * + * For redirected devices however this is an issue, as there we must ask + * the real xhci controller to alloc streams, and the host driver for the + * real xhci controller will likely disallow allocating more streams then + * the device can handle. + * + * So we limit the requested nr_streams to the maximum number the device + * can handle. + */ +if (req_nr_streams dev_max_streams) { +req_nr_streams = dev_max_streams; +} + +r = usb_device_alloc_streams(eps[0]-dev, eps, nr_eps, req_nr_streams); +if (r != 0) { +fprintf(stderr, xhci: alloc streams failed\n); +return CC_RESOURCE_ERROR; +} + +return CC_SUCCESS; +} + static XHCIStreamContext *xhci_find_stream(XHCIEPContext *epctx, unsigned int streamid, uint32_t *cc_error) @@ -2313,6 +2418,8 @@ static TRBCCode xhci_configure_slot(XHCIState *xhci, unsigned int slotid, return CC_CONTEXT_STATE_ERROR; } +xhci_free_device_streams(xhci, slotid, ictl_ctx[0] | ictl_ctx[1]); + for (i = 2; i = 31; i++) { if (ictl_ctx[0] (1i)) { xhci_disable_ep(xhci, slotid, i); @@ -2334,6 +2441,16 @@ static TRBCCode xhci_configure_slot(XHCIState *xhci, unsigned int slotid, } } +res = xhci_alloc_device_streams(xhci, slotid, ictl_ctx[1]); +if (res != CC_SUCCESS) { +for (i = 2; i = 31; i++) { +if (ictl_ctx[1]
[Qemu-devel] [PATCH 7/9] usb-host-libusb: Set stream id when submitting bulk-stream transfers
Signed-off-by: Hans de Goede hdego...@redhat.com --- hw/usb/host-libusb.c | 20 1 file changed, 16 insertions(+), 4 deletions(-) diff --git a/hw/usb/host-libusb.c b/hw/usb/host-libusb.c index 894875b..3376b96 100644 --- a/hw/usb/host-libusb.c +++ b/hw/usb/host-libusb.c @@ -1214,10 +1214,22 @@ static void usb_host_handle_data(USBDevice *udev, USBPacket *p) usb_packet_copy(p, r-buffer, size); } ep = p-ep-nr | (r-in ? USB_DIR_IN : 0); -libusb_fill_bulk_transfer(r-xfer, s-dh, ep, - r-buffer, size, - usb_host_req_complete_data, r, - BULK_TIMEOUT); +if (p-stream) { +#if LIBUSBX_API_VERSION = 0x01000103 +libusb_fill_bulk_stream_transfer(r-xfer, s-dh, ep, p-stream, + r-buffer, size, + usb_host_req_complete_data, r, + BULK_TIMEOUT); +#else +usb_host_req_free(r); +return USB_RET_STALL; +#endif +} else { +libusb_fill_bulk_transfer(r-xfer, s-dh, ep, + r-buffer, size, + usb_host_req_complete_data, r, + BULK_TIMEOUT); +} break; case USB_ENDPOINT_XFER_INT: r = usb_host_req_alloc(s, p, p-pid == USB_TOKEN_IN, p-iov.size); -- 1.8.4.2
[Qemu-devel] [PATCH 6/9] usb-host-libusb: Add alloc / free streams ops
Signed-off-by: Hans de Goede hdego...@redhat.com --- hw/usb/host-libusb.c | 50 ++ 1 file changed, 50 insertions(+) diff --git a/hw/usb/host-libusb.c b/hw/usb/host-libusb.c index 0dd60b2..894875b 100644 --- a/hw/usb/host-libusb.c +++ b/hw/usb/host-libusb.c @@ -1280,6 +1280,54 @@ static void usb_host_handle_reset(USBDevice *udev) } } +static int usb_host_alloc_streams(USBDevice *udev, USBEndpoint **eps, + int nr_eps, int streams) +{ +#if LIBUSBX_API_VERSION = 0x01000103 +USBHostDevice *s = USB_HOST_DEVICE(udev); +unsigned char endpoints[30]; +int i, rc; + +for (i = 0; i nr_eps; i++) { +endpoints[i] = eps[i]-nr; +if (eps[i]-pid == USB_TOKEN_IN) { +endpoints[i] |= 0x80; +} +} +rc = libusb_alloc_streams(s-dh, streams, endpoints, nr_eps); +if (rc 0) { +usb_host_libusb_error(libusb_alloc_streams, rc); +} else if (rc != streams) { +fprintf(stderr, +libusb_alloc_streams: got less streams then requested %d %d\n, +rc, streams); +} + +return (rc == streams) ? 0 : -1; +#else +fprintf(stderr, libusb_alloc_streams: error not implemented\n); +return -1; +#endif +} + +static void usb_host_free_streams(USBDevice *udev, USBEndpoint **eps, + int nr_eps) +{ +#if LIBUSBX_API_VERSION = 0x01000103 +USBHostDevice *s = USB_HOST_DEVICE(udev); +unsigned char endpoints[30]; +int i; + +for (i = 0; i nr_eps; i++) { +endpoints[i] = eps[i]-nr; +if (eps[i]-pid == USB_TOKEN_IN) { +endpoints[i] |= 0x80; +} +} +libusb_free_streams(s-dh, endpoints, nr_eps); +#endif +} + /* * This is *NOT* about restoring state. We have absolutely no idea * what state the host device is in at the moment and whenever it is @@ -1361,6 +1409,8 @@ static void usb_host_class_initfn(ObjectClass *klass, void *data) uc-handle_reset = usb_host_handle_reset; uc-handle_destroy = usb_host_handle_destroy; uc-flush_ep_queue = usb_host_flush_ep_queue; +uc-alloc_streams = usb_host_alloc_streams; +uc-free_streams = usb_host_free_streams; dc-vmsd = vmstate_usb_host; dc-props = usb_host_dev_properties; set_bit(DEVICE_CATEGORY_BRIDGE, dc-categories); -- 1.8.4.2
[Qemu-devel] [V2 PATCH 00/14] target-ppc: VSX Stage 4
This is the fourth and final series of patches that add emulation support to QEMU for the PowerPC Vector Scalar Extension (VSX). This series adds the instructions that were newly introduced with Power ISA V2.07. This includes 3 scalar load instructions, 2 scalar store instructions, 7 standard single precision scalar arithmetic instructions, 8 scalar single precision fused multiply/add instructions, two integer-to-single-precision conversion instructions and 3 vector logical instructions. The single-precision scalar arithmetic instructions all interpret the most significant 64 bits of a VSR as a single precision floating point number stored in double precision format (similar to the standard PowerPC floating point single precision instructions). Thus a common theme in the supporting code is rounding of an intermediate double-precision number to single precision. V2: (a) Changed the rounding to single precision to reuse the existing helper_frsp() routine. (b) Re-implemented the fused multiply/add instructions to use float32_muladd instead of float64_muladd, which avoids subtle rounding errors. Tom Musta (14): target-ppc: VSX Stage 4: Add VSX 2.07 Flag target-ppc: VSX Stage 4: Refactor lxsdx target-ppc: VSX Stage 4: Add lxsiwax, lxsiwzx and lxsspx target-ppc: VSX Stage 4: Refactor stxsdx target-ppc: VSX Stage 4: Add stxsiwx and stxsspx target-ppc: VSX Stage 4: Add xsaddsp and xssubsp target-ppc: VSX Stage 4: Add xsmulsp target-ppc: VSX Stage 4: Add xsdivsp target-ppc: VSX Stage 4: Add xsresp target-ppc: VSX Stage 4: Add xssqrtsp target-ppc: VSX Stage 4: add xsrsqrtesp target-ppc: VSX Stage 4: Add Scalar SP Fused Multiply-Adds target-ppc: VSX Stage 4: Add xscvsxdsp and xscvuxdsp target-ppc: VSX Stage 4: Add xxleqv, xxlnand and xxlorc target-ppc/cpu.h|4 +- target-ppc/fpu_helper.c | 190 ++- target-ppc/helper.h | 18 target-ppc/translate.c | 110 +++-- target-ppc/translate_init.c |2 +- 5 files changed, 258 insertions(+), 66 deletions(-)
[Qemu-devel] [V2 PATCH 01/14] target-ppc: VSX Stage 4: Add VSX 2.07 Flag
This patch adds a flag to identify those VSX instructions that are new to Power ISA V2.07. The flag is added to the Power 8 processor initialization so that the P8 models understand how to decode and emulate instructions in this category. Signed-off-by: Tom Musta tommu...@gmail.com --- target-ppc/cpu.h|4 +++- target-ppc/translate_init.c |2 +- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/target-ppc/cpu.h b/target-ppc/cpu.h index bb84767..0abc848 100644 --- a/target-ppc/cpu.h +++ b/target-ppc/cpu.h @@ -1875,9 +1875,11 @@ enum { PPC2_DBRX = 0x0010ULL, /* Book I 2.05 PowerPC specification */ PPC2_ISA205= 0x0020ULL, +/* VSX additions in ISA 2.07 */ +PPC2_VSX207= 0x0040ULL, #define PPC_TCG_INSNS2 (PPC2_BOOKE206 | PPC2_VSX | PPC2_PRCNTL | PPC2_DBRX | \ - PPC2_ISA205) +PPC2_ISA205 | PPC2_VSX207) }; /*/ diff --git a/target-ppc/translate_init.c b/target-ppc/translate_init.c index 13457ec..e14ab63 100644 --- a/target-ppc/translate_init.c +++ b/target-ppc/translate_init.c @@ -7270,7 +7270,7 @@ POWERPC_FAMILY(POWER8)(ObjectClass *oc, void *data) PPC_64B | PPC_ALTIVEC | PPC_SEGMENT_64B | PPC_SLBI | PPC_POPCNTB | PPC_POPCNTWD; -pcc-insns_flags2 = PPC2_VSX | PPC2_DFP | PPC2_DBRX; +pcc-insns_flags2 = PPC2_VSX | PPC2_VSX207 | PPC2_DFP | PPC2_DBRX; pcc-msr_mask = 0x8284FF36ULL; pcc-mmu_model = POWERPC_MMU_2_06; #if defined(CONFIG_SOFTMMU) -- 1.7.1
[Qemu-devel] [PATCH 9/9] uas: s/ui/iu/
The various uas data structures are called IU-s, which is short for Information Unit, rather then UI-s. Signed-off-by: Hans de Goede hdego...@redhat.com --- hw/usb/dev-uas.c | 76 1 file changed, 38 insertions(+), 38 deletions(-) diff --git a/hw/usb/dev-uas.c b/hw/usb/dev-uas.c index 82a47be..997b715 100644 --- a/hw/usb/dev-uas.c +++ b/hw/usb/dev-uas.c @@ -55,7 +55,7 @@ typedef struct { uint8_tid; uint8_treserved; uint16_t tag; -} QEMU_PACKED uas_ui_header; +} QEMU_PACKED uas_iu_header; typedef struct { uint8_tprio_taskattr; /* 6:3 priority, 2:0 task attribute */ @@ -65,7 +65,7 @@ typedef struct { uint64_t lun; uint8_tcdb[16]; uint8_tadd_cdb[]; -} QEMU_PACKED uas_ui_command; +} QEMU_PACKED uas_iu_command; typedef struct { uint16_t status_qualifier; @@ -73,29 +73,29 @@ typedef struct { uint8_treserved[7]; uint16_t sense_length; uint8_tsense_data[18]; -} QEMU_PACKED uas_ui_sense; +} QEMU_PACKED uas_iu_sense; typedef struct { uint8_tadd_response_info[3]; uint8_tresponse_code; -} QEMU_PACKED uas_ui_response; +} QEMU_PACKED uas_iu_response; typedef struct { uint8_tfunction; uint8_treserved; uint16_t task_tag; uint64_t lun; -} QEMU_PACKED uas_ui_task_mgmt; +} QEMU_PACKED uas_iu_task_mgmt; typedef struct { -uas_ui_header hdr; +uas_iu_header hdr; union { -uas_ui_command command; -uas_ui_sense sense; -uas_ui_task_mgmt task; -uas_ui_response response; +uas_iu_command command; +uas_iu_sense sense; +uas_iu_task_mgmt task; +uas_iu_response response; }; -} QEMU_PACKED uas_ui; +} QEMU_PACKED uas_iu; /* - */ @@ -145,7 +145,7 @@ struct UASRequest { struct UASStatus { uint32_t stream; -uas_uistatus; +uas_iustatus; uint32_t length; QTAILQ_ENTRY(UASStatus) next; }; @@ -338,7 +338,7 @@ static UASStatus *usb_uas_alloc_status(UASDevice *uas, uint8_t id, uint16_t tag) st-status.hdr.id = id; st-status.hdr.tag = cpu_to_be16(tag); -st-length = sizeof(uas_ui_header); +st-length = sizeof(uas_iu_header); if (uas_using_streams(uas)) { st-stream = tag; } @@ -398,7 +398,7 @@ static void usb_uas_queue_response(UASDevice *uas, uint16_t tag, uint8_t code) trace_usb_uas_response(uas-dev.addr, tag, code); st-status.response.response_code = code; -usb_uas_queue_status(uas, st, sizeof(uas_ui_response)); +usb_uas_queue_status(uas, st, sizeof(uas_iu_response)); } static void usb_uas_queue_sense(UASRequest *req, uint8_t status) @@ -414,7 +414,7 @@ static void usb_uas_queue_sense(UASRequest *req, uint8_t status) sizeof(st-status.sense.sense_data)); st-status.sense.sense_length = cpu_to_be16(slen); } -len = sizeof(uas_ui_sense) - sizeof(st-status.sense.sense_data) + slen; +len = sizeof(uas_iu_sense) - sizeof(st-status.sense.sense_data) + slen; usb_uas_queue_status(req-uas, st, len); } @@ -432,7 +432,7 @@ static void usb_uas_queue_fake_sense(UASDevice *uas, uint16_t tag, st-status.sense.sense_data[12] = sense.asc; st-status.sense.sense_data[13] = sense.ascq; slen = 18; -len = sizeof(uas_ui_sense) - sizeof(st-status.sense.sense_data) + slen; +len = sizeof(uas_iu_sense) - sizeof(st-status.sense.sense_data) + slen; usb_uas_queue_status(uas, st, len); } @@ -534,14 +534,14 @@ static void usb_uas_start_next_transfer(UASDevice *uas) } } -static UASRequest *usb_uas_alloc_request(UASDevice *uas, uas_ui *ui) +static UASRequest *usb_uas_alloc_request(UASDevice *uas, uas_iu *iu) { UASRequest *req; req = g_new0(UASRequest, 1); req-uas = uas; -req-tag = be16_to_cpu(ui-hdr.tag); -req-lun = be64_to_cpu(ui-command.lun); +req-tag = be16_to_cpu(iu-hdr.tag); +req-lun = be64_to_cpu(iu-command.lun); req-dev = usb_uas_get_dev(req-uas, req-lun); return req; } @@ -684,11 +684,11 @@ static void usb_uas_cancel_io(USBDevice *dev, USBPacket *p) assert(!canceled usb packet not found); } -static void usb_uas_command(UASDevice *uas, uas_ui *ui) +static void usb_uas_command(UASDevice *uas, uas_iu *iu) { UASRequest *req; uint32_t len; -uint16_t tag = be16_to_cpu(ui-hdr.tag); +uint16_t tag = be16_to_cpu(iu-hdr.tag); if (uas_using_streams(uas) tag UAS_MAX_STREAMS) { goto invalid_tag; @@ -697,7 +697,7 @@ static void usb_uas_command(UASDevice *uas, uas_ui *ui) if (req) { goto overlapped_tag; } -req = usb_uas_alloc_request(uas, ui); +req = usb_uas_alloc_request(uas, iu); if (req-dev == NULL) {
[Qemu-devel] [PATCH 8/9] usb-redir: Add support for bulk streams
Signed-off-by: Hans de Goede hdego...@redhat.com --- hw/usb/redirect.c | 137 -- 1 file changed, 132 insertions(+), 5 deletions(-) diff --git a/hw/usb/redirect.c b/hw/usb/redirect.c index 287a505..4c6187b 100644 --- a/hw/usb/redirect.c +++ b/hw/usb/redirect.c @@ -50,6 +50,10 @@ ((i) 0x10) ? USB_TOKEN_IN : USB_TOKEN_OUT, \ (i) 0x0f)) +#ifndef USBREDIR_VERSION /* This is not defined in older usbredir versions */ +#define USBREDIR_VERSION 0 +#endif + typedef struct USBRedirDevice USBRedirDevice; /* Struct to hold buffered packets */ @@ -68,6 +72,7 @@ struct endp_data { uint8_t interval; uint8_t interface; /* bInterfaceNumber this ep belongs to */ uint16_t max_packet_size; /* In bytes, not wMaxPacketSize format !! */ +uint32_t max_streams; uint8_t iso_started; uint8_t iso_error; /* For reporting iso errors to the HC */ uint8_t interrupt_started; @@ -106,8 +111,9 @@ struct USBRedirDevice { int read_buf_size; /* Active chardev-watch-tag */ guint watch; -/* For async handling of close */ +/* For async handling of close / reject */ QEMUBH *chardev_close_bh; +QEMUBH *device_reject_bh; /* To delay the usb attach in case of quick chardev close + open */ QEMUTimer *attach_timer; int64_t next_attach_time; @@ -780,11 +786,12 @@ static void usbredir_handle_bulk_data(USBRedirDevice *dev, USBPacket *p, dev-endpoint[EP2I(ep)].bulk_receiving_enabled = 0; } -DPRINTF(bulk-out ep %02X len %zd id %PRIu64\n, ep, size, p-id); +DPRINTF(bulk-out ep %02X stream %u len %zd id %PRIu64\n, +ep, p-stream, size, p-id); bulk_packet.endpoint = ep; bulk_packet.length= size; -bulk_packet.stream_id = 0; +bulk_packet.stream_id = p-stream; bulk_packet.length_high = size 16; assert(bulk_packet.length_high == 0 || usbredirparser_peer_has_cap(dev-parser, @@ -1091,6 +1098,66 @@ static void usbredir_handle_control(USBDevice *udev, USBPacket *p, p-status = USB_RET_ASYNC; } +static int usbredir_alloc_streams(USBDevice *udev, USBEndpoint **eps, + int nr_eps, int streams) +{ +USBRedirDevice *dev = DO_UPCAST(USBRedirDevice, dev, udev); +#if USBREDIR_VERSION = 0x000700 +struct usb_redir_alloc_bulk_streams_header alloc_streams; +int i; + +if (!usbredirparser_peer_has_cap(dev-parser, + usb_redir_cap_bulk_streams)) { +ERROR(peer does not support streams\n); +goto reject; +} + +if (streams == 0) { +ERROR(request to allocate 0 streams\n); +return -1; +} + +alloc_streams.no_streams = streams; +alloc_streams.endpoints = 0; +for (i = 0; i nr_eps; i++) { +alloc_streams.endpoints |= 1 USBEP2I(eps[i]); +} +usbredirparser_send_alloc_bulk_streams(dev-parser, 0, alloc_streams); +usbredirparser_do_write(dev-parser); + +return 0; +#else +ERROR(usbredir_alloc_streams not implemented\n); +goto reject; +#endif +reject: +ERROR(streams are not available, disconnecting\n); +qemu_bh_schedule(dev-device_reject_bh); +return -1; +} + +static void usbredir_free_streams(USBDevice *udev, USBEndpoint **eps, + int nr_eps) +{ +#if USBREDIR_VERSION = 0x000700 +USBRedirDevice *dev = DO_UPCAST(USBRedirDevice, dev, udev); +struct usb_redir_free_bulk_streams_header free_streams; +int i; + +if (!usbredirparser_peer_has_cap(dev-parser, + usb_redir_cap_bulk_streams)) { +return; +} + +free_streams.endpoints = 0; +for (i = 0; i nr_eps; i++) { +free_streams.endpoints |= 1 USBEP2I(eps[i]); +} +usbredirparser_send_free_bulk_streams(dev-parser, 0, free_streams); +usbredirparser_do_write(dev-parser); +#endif +} + /* * Close events can be triggered by usbredirparser_do_write which gets called * from within the USBDevice data / control packet callbacks and doing a @@ -1102,6 +1169,7 @@ static void usbredir_chardev_close_bh(void *opaque) { USBRedirDevice *dev = opaque; +qemu_bh_cancel(dev-device_reject_bh); usbredir_device_disconnect(dev); if (dev-parser) { @@ -1153,6 +1221,9 @@ static void usbredir_create_parser(USBRedirDevice *dev) usbredirparser_caps_set_cap(caps, usb_redir_cap_64bits_ids); usbredirparser_caps_set_cap(caps, usb_redir_cap_32bits_bulk_length); usbredirparser_caps_set_cap(caps, usb_redir_cap_bulk_receiving); +#if USBREDIR_VERSION = 0x000700 +usbredirparser_caps_set_cap(caps, usb_redir_cap_bulk_streams); +#endif if (runstate_check(RUN_STATE_INMIGRATE)) { flags |= usbredirparser_fl_no_hello; @@ -1171,6 +1242,17 @@ static void usbredir_reject_device(USBRedirDevice *dev) } } +/* + * We may need to reject the device when the hcd calls
[Qemu-devel] [V2 PATCH 03/14] target-ppc: VSX Stage 4: Add lxsiwax, lxsiwzx and lxsspx
This patch adds the scalar load instructions introduced in ISA V2.07: - Load VSX Scalar as Integer Word Algebraic Indexd (lxsiwax) - Load VSX Scalar as Integer Word and Zero Indexed (lxsiwzx) - Load VSX Scalar Single-Precision Indexed (lxsspx) Signed-off-by: Tom Musta tommu...@gmail.com --- target-ppc/translate.c |6 ++ 1 files changed, 6 insertions(+), 0 deletions(-) diff --git a/target-ppc/translate.c b/target-ppc/translate.c index 2541b5f..ad40d27 100644 --- a/target-ppc/translate.c +++ b/target-ppc/translate.c @@ -7023,6 +7023,9 @@ static void gen_##name(DisasContext *ctx) \ } VSX_LOAD_SCALAR(lxsdx, ld64) +VSX_LOAD_SCALAR(lxsiwax, ld32s) +VSX_LOAD_SCALAR(lxsiwzx, ld32u) +VSX_LOAD_SCALAR(lxsspx, ld32fs) static void gen_lxvd2x(DisasContext *ctx) { @@ -10036,6 +10039,9 @@ GEN_VAFORM_PAIRED(vsel, vperm, 21), GEN_VAFORM_PAIRED(vmaddfp, vnmsubfp, 23), GEN_HANDLER_E(lxsdx, 0x1F, 0x0C, 0x12, 0, PPC_NONE, PPC2_VSX), +GEN_HANDLER_E(lxsiwax, 0x1F, 0x0C, 0x02, 0, PPC_NONE, PPC2_VSX207), +GEN_HANDLER_E(lxsiwzx, 0x1F, 0x0C, 0x00, 0, PPC_NONE, PPC2_VSX207), +GEN_HANDLER_E(lxsspx, 0x1F, 0x0C, 0x10, 0, PPC_NONE, PPC2_VSX207), GEN_HANDLER_E(lxvd2x, 0x1F, 0x0C, 0x1A, 0, PPC_NONE, PPC2_VSX), GEN_HANDLER_E(lxvdsx, 0x1F, 0x0C, 0x0A, 0, PPC_NONE, PPC2_VSX), GEN_HANDLER_E(lxvw4x, 0x1F, 0x0C, 0x18, 0, PPC_NONE, PPC2_VSX), -- 1.7.1
[Qemu-devel] [V2 PATCH 04/14] target-ppc: VSX Stage 4: Refactor stxsdx
This patch refactors the stxsdx instruction. Reusable code is extracted into a macro which will be used in subsequent patches in this series. Signed-off-by: Tom Musta tommu...@gmail.com --- target-ppc/translate.c | 27 +++ 1 files changed, 15 insertions(+), 12 deletions(-) diff --git a/target-ppc/translate.c b/target-ppc/translate.c index ad40d27..52e487d 100644 --- a/target-ppc/translate.c +++ b/target-ppc/translate.c @@ -7086,20 +7086,23 @@ static void gen_lxvw4x(DisasContext *ctx) tcg_temp_free(tmp); } -static void gen_stxsdx(DisasContext *ctx) -{ -TCGv EA; -if (unlikely(!ctx-vsx_enabled)) { -gen_exception(ctx, POWERPC_EXCP_VSXU); -return; -} -gen_set_access_type(ctx, ACCESS_INT); -EA = tcg_temp_new(); -gen_addr_reg_index(ctx, EA); -gen_qemu_st64(ctx, cpu_vsrh(xS(ctx-opcode)), EA); -tcg_temp_free(EA); +#define VSX_STORE_SCALAR(name, operation) \ +static void gen_##name(DisasContext *ctx) \ +{ \ +TCGv EA; \ +if (unlikely(!ctx-vsx_enabled)) {\ +gen_exception(ctx, POWERPC_EXCP_VSXU);\ +return; \ +} \ +gen_set_access_type(ctx, ACCESS_INT); \ +EA = tcg_temp_new(); \ +gen_addr_reg_index(ctx, EA); \ +gen_qemu_##operation(ctx, cpu_vsrh(xS(ctx-opcode)), EA); \ +tcg_temp_free(EA);\ } +VSX_STORE_SCALAR(stxsdx, st64) + static void gen_stxvd2x(DisasContext *ctx) { TCGv EA; -- 1.7.1
[Qemu-devel] [V2 PATCH 09/14] target-ppc: VSX Stage 4: Add xsresp
This patch adds the VSX Scalar Reciprocal Estimate Single Precision (xsresp) instruction. The existing VSX_RE macro is modified to support rounding of the intermediate double precision result to single precision. V2: Updated conversion to single precision range. Signed-off-by: Tom Musta tommu...@gmail.com --- target-ppc/fpu_helper.c | 14 ++ target-ppc/helper.h |1 + target-ppc/translate.c |2 ++ 3 files changed, 13 insertions(+), 4 deletions(-) diff --git a/target-ppc/fpu_helper.c b/target-ppc/fpu_helper.c index da31964..b633547 100644 --- a/target-ppc/fpu_helper.c +++ b/target-ppc/fpu_helper.c @@ -1928,7 +1928,7 @@ VSX_DIV(xvdivsp, 4, float32, f32, 0, 0) * fld - vsr_t field (f32 or f64) * sfprf - set FPRF */ -#define VSX_RE(op, nels, tp, fld, sfprf) \ +#define VSX_RE(op, nels, tp, fld, sfprf, r2sp)\ void helper_##op(CPUPPCState *env, uint32_t opcode) \ { \ ppc_vsr_t xt, xb; \ @@ -1943,6 +1943,11 @@ void helper_##op(CPUPPCState *env, uint32_t opcode) \ fload_invalid_op_excp(env, POWERPC_EXCP_FP_VXSNAN, sfprf);\ } \ xt.fld[i] = tp##_div(tp##_one, xb.fld[i], env-fp_status); \ + \ +if (r2sp) { \ +xt.fld[i] = helper_frsp(env, xt.fld[i]); \ +} \ + \ if (sfprf) { \ helper_compute_fprf(env, xt.fld[0], sfprf); \ } \ @@ -1952,9 +1957,10 @@ void helper_##op(CPUPPCState *env, uint32_t opcode) \ helper_float_check_status(env); \ } -VSX_RE(xsredp, 1, float64, f64, 1) -VSX_RE(xvredp, 2, float64, f64, 0) -VSX_RE(xvresp, 4, float32, f32, 0) +VSX_RE(xsredp, 1, float64, f64, 1, 0) +VSX_RE(xsresp, 1, float64, f64, 1, 1) +VSX_RE(xvredp, 2, float64, f64, 0, 0) +VSX_RE(xvresp, 4, float32, f32, 0, 0) /* VSX_SQRT - VSX floating point square root * op- instruction mnemonic diff --git a/target-ppc/helper.h b/target-ppc/helper.h index 308f97c..b1cf3c0 100644 --- a/target-ppc/helper.h +++ b/target-ppc/helper.h @@ -290,6 +290,7 @@ DEF_HELPER_2(xsaddsp, void, env, i32) DEF_HELPER_2(xssubsp, void, env, i32) DEF_HELPER_2(xsmulsp, void, env, i32) DEF_HELPER_2(xsdivsp, void, env, i32) +DEF_HELPER_2(xsresp, void, env, i32) DEF_HELPER_2(xvadddp, void, env, i32) DEF_HELPER_2(xvsubdp, void, env, i32) diff --git a/target-ppc/translate.c b/target-ppc/translate.c index 896dbc2..c4c57a1 100644 --- a/target-ppc/translate.c +++ b/target-ppc/translate.c @@ -7345,6 +7345,7 @@ GEN_VSX_HELPER_2(xsaddsp, 0x00, 0x00, 0, PPC2_VSX207) GEN_VSX_HELPER_2(xssubsp, 0x00, 0x01, 0, PPC2_VSX207) GEN_VSX_HELPER_2(xsmulsp, 0x00, 0x02, 0, PPC2_VSX207) GEN_VSX_HELPER_2(xsdivsp, 0x00, 0x03, 0, PPC2_VSX207) +GEN_VSX_HELPER_2(xsresp, 0x14, 0x01, 0, PPC2_VSX207) GEN_VSX_HELPER_2(xvadddp, 0x00, 0x0C, 0, PPC2_VSX) GEN_VSX_HELPER_2(xvsubdp, 0x00, 0x0D, 0, PPC2_VSX) @@ -10157,6 +10158,7 @@ GEN_XX3FORM(xsaddsp, 0x00, 0x00, PPC2_VSX207), GEN_XX3FORM(xssubsp, 0x00, 0x01, PPC2_VSX207), GEN_XX3FORM(xsmulsp, 0x00, 0x02, PPC2_VSX207), GEN_XX3FORM(xsdivsp, 0x00, 0x03, PPC2_VSX207), +GEN_XX2FORM(xsresp, 0x14, 0x01, PPC2_VSX207), GEN_XX3FORM(xvadddp, 0x00, 0x0C, PPC2_VSX), GEN_XX3FORM(xvsubdp, 0x00, 0x0D, PPC2_VSX), -- 1.7.1
[Qemu-devel] [V2 PATCH 05/14] target-ppc: VSX Stage 4: Add stxsiwx and stxsspx
This patch adds two store scalar instructions: - Store VSX Scalar as Integer Word Indexed (stxsiwx) - Store VSX Scalar Single-Precision Indexed (stxsspx) Signed-off-by: Tom Musta tommu...@gmail.com --- target-ppc/translate.c |4 1 files changed, 4 insertions(+), 0 deletions(-) diff --git a/target-ppc/translate.c b/target-ppc/translate.c index 52e487d..62604fd 100644 --- a/target-ppc/translate.c +++ b/target-ppc/translate.c @@ -7102,6 +7102,8 @@ static void gen_##name(DisasContext *ctx) \ } VSX_STORE_SCALAR(stxsdx, st64) +VSX_STORE_SCALAR(stxsiwx, st32) +VSX_STORE_SCALAR(stxsspx, st32fs) static void gen_stxvd2x(DisasContext *ctx) { @@ -10050,6 +10052,8 @@ GEN_HANDLER_E(lxvdsx, 0x1F, 0x0C, 0x0A, 0, PPC_NONE, PPC2_VSX), GEN_HANDLER_E(lxvw4x, 0x1F, 0x0C, 0x18, 0, PPC_NONE, PPC2_VSX), GEN_HANDLER_E(stxsdx, 0x1F, 0xC, 0x16, 0, PPC_NONE, PPC2_VSX), +GEN_HANDLER_E(stxsiwx, 0x1F, 0xC, 0x04, 0, PPC_NONE, PPC2_VSX207), +GEN_HANDLER_E(stxsspx, 0x1F, 0xC, 0x14, 0, PPC_NONE, PPC2_VSX207), GEN_HANDLER_E(stxvd2x, 0x1F, 0xC, 0x1E, 0, PPC_NONE, PPC2_VSX), GEN_HANDLER_E(stxvw4x, 0x1F, 0xC, 0x1C, 0, PPC_NONE, PPC2_VSX), -- 1.7.1
[Qemu-devel] [V2 PATCH 11/14] target-ppc: VSX Stage 4: add xsrsqrtesp
This patch adds the VSX Scalar Reciprocal Square Root Estimate Single Precision (xsrsqrtesp) instruction. The existing VSX_RSQRTE() macro is modified to support rounding of the intermediate double-precision result to single precision. V2: Updated conversion to single precision range. Signed-off-by: Tom Musta tommu...@gmail.com --- target-ppc/fpu_helper.c | 13 + target-ppc/helper.h |1 + target-ppc/translate.c |2 ++ 3 files changed, 12 insertions(+), 4 deletions(-) diff --git a/target-ppc/fpu_helper.c b/target-ppc/fpu_helper.c index 34a8b66..8825db2 100644 --- a/target-ppc/fpu_helper.c +++ b/target-ppc/fpu_helper.c @@ -2018,7 +2018,7 @@ VSX_SQRT(xvsqrtsp, 4, float32, f32, 0, 0) * fld - vsr_t field (f32 or f64) * sfprf - set FPRF */ -#define VSX_RSQRTE(op, nels, tp, fld, sfprf) \ +#define VSX_RSQRTE(op, nels, tp, fld, sfprf, r2sp) \ void helper_##op(CPUPPCState *env, uint32_t opcode) \ {\ ppc_vsr_t xt, xb;\ @@ -2043,6 +2043,10 @@ void helper_##op(CPUPPCState *env, uint32_t opcode) \ }\ }\ \ +if (r2sp) { \ +xt.fld[i] = helper_frsp(env, xt.fld[i]); \ +}\ + \ if (sfprf) { \ helper_compute_fprf(env, xt.fld[i], sfprf); \ }\ @@ -2052,9 +2056,10 @@ void helper_##op(CPUPPCState *env, uint32_t opcode) \ helper_float_check_status(env); \ } -VSX_RSQRTE(xsrsqrtedp, 1, float64, f64, 1) -VSX_RSQRTE(xvrsqrtedp, 2, float64, f64, 0) -VSX_RSQRTE(xvrsqrtesp, 4, float32, f32, 0) +VSX_RSQRTE(xsrsqrtedp, 1, float64, f64, 1, 0) +VSX_RSQRTE(xsrsqrtesp, 1, float64, f64, 1, 1) +VSX_RSQRTE(xvrsqrtedp, 2, float64, f64, 0, 0) +VSX_RSQRTE(xvrsqrtesp, 4, float32, f32, 0, 0) static inline int ppc_float32_get_unbiased_exp(float32 f) { diff --git a/target-ppc/helper.h b/target-ppc/helper.h index 0192043..84c6ee1 100644 --- a/target-ppc/helper.h +++ b/target-ppc/helper.h @@ -292,6 +292,7 @@ DEF_HELPER_2(xsmulsp, void, env, i32) DEF_HELPER_2(xsdivsp, void, env, i32) DEF_HELPER_2(xsresp, void, env, i32) DEF_HELPER_2(xssqrtsp, void, env, i32) +DEF_HELPER_2(xsrsqrtesp, void, env, i32) DEF_HELPER_2(xvadddp, void, env, i32) DEF_HELPER_2(xvsubdp, void, env, i32) diff --git a/target-ppc/translate.c b/target-ppc/translate.c index b9cd35b..ae80289 100644 --- a/target-ppc/translate.c +++ b/target-ppc/translate.c @@ -7347,6 +7347,7 @@ GEN_VSX_HELPER_2(xsmulsp, 0x00, 0x02, 0, PPC2_VSX207) GEN_VSX_HELPER_2(xsdivsp, 0x00, 0x03, 0, PPC2_VSX207) GEN_VSX_HELPER_2(xsresp, 0x14, 0x01, 0, PPC2_VSX207) GEN_VSX_HELPER_2(xssqrtsp, 0x16, 0x00, 0, PPC2_VSX207) +GEN_VSX_HELPER_2(xsrsqrtesp, 0x14, 0x00, 0, PPC2_VSX207) GEN_VSX_HELPER_2(xvadddp, 0x00, 0x0C, 0, PPC2_VSX) GEN_VSX_HELPER_2(xvsubdp, 0x00, 0x0D, 0, PPC2_VSX) @@ -10161,6 +10162,7 @@ GEN_XX3FORM(xsmulsp, 0x00, 0x02, PPC2_VSX207), GEN_XX3FORM(xsdivsp, 0x00, 0x03, PPC2_VSX207), GEN_XX2FORM(xsresp, 0x14, 0x01, PPC2_VSX207), GEN_XX2FORM(xssqrtsp, 0x16, 0x00, PPC2_VSX207), +GEN_XX2FORM(xsrsqrtesp, 0x14, 0x00, PPC2_VSX207), GEN_XX3FORM(xvadddp, 0x00, 0x0C, PPC2_VSX), GEN_XX3FORM(xvsubdp, 0x00, 0x0D, PPC2_VSX), -- 1.7.1
[Qemu-devel] [V2 PATCH 07/14] target-ppc: VSX Stage 4: Add xsmulsp
This patch adds the VSX Scalar Multiply Single-Precision (xsmulsp) instruction. The existing VSX_MUL macro is modified to support rounding of the intermediate result to single precision. V2: Updated conversion to single precision. Signed-off-by: Tom Musta tommu...@gmail.com --- target-ppc/fpu_helper.c | 13 + target-ppc/helper.h |1 + target-ppc/translate.c |2 ++ 3 files changed, 12 insertions(+), 4 deletions(-) diff --git a/target-ppc/fpu_helper.c b/target-ppc/fpu_helper.c index 1256ad0..b3a5261 100644 --- a/target-ppc/fpu_helper.c +++ b/target-ppc/fpu_helper.c @@ -1822,7 +1822,7 @@ VSX_ADD_SUB(xvsubsp, sub, 4, float32, f32, 0, 0) * fld - vsr_t field (f32 or f64) * sfprf - set FPRF */ -#define VSX_MUL(op, nels, tp, fld, sfprf)\ +#define VSX_MUL(op, nels, tp, fld, sfprf, r2sp) \ void helper_##op(CPUPPCState *env, uint32_t opcode) \ {\ ppc_vsr_t xt, xa, xb;\ @@ -1849,6 +1849,10 @@ void helper_##op(CPUPPCState *env, uint32_t opcode) \ }\ }\ \ +if (r2sp) { \ +xt.fld[i] = helper_frsp(env, xt.fld[i]); \ +}\ + \ if (sfprf) { \ helper_compute_fprf(env, xt.fld[i], sfprf); \ }\ @@ -1858,9 +1862,10 @@ void helper_##op(CPUPPCState *env, uint32_t opcode) \ helper_float_check_status(env); \ } -VSX_MUL(xsmuldp, 1, float64, f64, 1) -VSX_MUL(xvmuldp, 2, float64, f64, 0) -VSX_MUL(xvmulsp, 4, float32, f32, 0) +VSX_MUL(xsmuldp, 1, float64, f64, 1, 0) +VSX_MUL(xsmulsp, 1, float64, f64, 1, 1) +VSX_MUL(xvmuldp, 2, float64, f64, 0, 0) +VSX_MUL(xvmulsp, 4, float32, f32, 0, 0) /* VSX_DIV - VSX floating point divide * op- instruction mnemonic diff --git a/target-ppc/helper.h b/target-ppc/helper.h index 696b9d3..0ccdc96 100644 --- a/target-ppc/helper.h +++ b/target-ppc/helper.h @@ -288,6 +288,7 @@ DEF_HELPER_2(xsrdpiz, void, env, i32) DEF_HELPER_2(xsaddsp, void, env, i32) DEF_HELPER_2(xssubsp, void, env, i32) +DEF_HELPER_2(xsmulsp, void, env, i32) DEF_HELPER_2(xvadddp, void, env, i32) DEF_HELPER_2(xvsubdp, void, env, i32) diff --git a/target-ppc/translate.c b/target-ppc/translate.c index bd639cc..450ab88 100644 --- a/target-ppc/translate.c +++ b/target-ppc/translate.c @@ -7343,6 +7343,7 @@ GEN_VSX_HELPER_2(xsrdpiz, 0x12, 0x05, 0, PPC2_VSX) GEN_VSX_HELPER_2(xsaddsp, 0x00, 0x00, 0, PPC2_VSX207) GEN_VSX_HELPER_2(xssubsp, 0x00, 0x01, 0, PPC2_VSX207) +GEN_VSX_HELPER_2(xsmulsp, 0x00, 0x02, 0, PPC2_VSX207) GEN_VSX_HELPER_2(xvadddp, 0x00, 0x0C, 0, PPC2_VSX) GEN_VSX_HELPER_2(xvsubdp, 0x00, 0x0D, 0, PPC2_VSX) @@ -10153,6 +10154,7 @@ GEN_XX2FORM(xsrdpiz, 0x12, 0x05, PPC2_VSX), GEN_XX3FORM(xsaddsp, 0x00, 0x00, PPC2_VSX207), GEN_XX3FORM(xssubsp, 0x00, 0x01, PPC2_VSX207), +GEN_XX3FORM(xsmulsp, 0x00, 0x02, PPC2_VSX207), GEN_XX3FORM(xvadddp, 0x00, 0x0C, PPC2_VSX), GEN_XX3FORM(xvsubdp, 0x00, 0x0D, PPC2_VSX), -- 1.7.1
[Qemu-devel] [V2 PATCH 13/14] target-ppc: VSX Stage 4: Add xscvsxdsp and xscvuxdsp
This patch adds the VSX Scalar Convert Unsigned Integer Doubleword to Floating Point Format and Round to Single Precision (xscvuxdsp) and VSX Scalar Convert Signed Integer Douglbeword to Floating Point Format and Round to Single Precision (xscvsxdsp) instructions. The existing integer to floating point conversion macro (VSX_CVT_INT_TO_FP) is modified to support the rounding of the intermediate floating point result to single precision. V2: updated conversion to single precision range. Signed-off-by: Tom Musta tommu...@gmail.com --- target-ppc/fpu_helper.c | 27 --- target-ppc/helper.h |2 ++ target-ppc/translate.c |4 3 files changed, 22 insertions(+), 11 deletions(-) diff --git a/target-ppc/fpu_helper.c b/target-ppc/fpu_helper.c index 6428c54..eba6c0a 100644 --- a/target-ppc/fpu_helper.c +++ b/target-ppc/fpu_helper.c @@ -2622,7 +2622,7 @@ VSX_CVT_FP_TO_INT(xvcvspuxws, 4, float32, uint32, f32[j], u32[i], i, 0) * jdef - definition of the j index (i or 2*i) * sfprf - set FPRF */ -#define VSX_CVT_INT_TO_FP(op, nels, stp, ttp, sfld, tfld, jdef, sfprf) \ +#define VSX_CVT_INT_TO_FP(op, nels, stp, ttp, sfld, tfld, jdef, sfprf, r2sp) \ void helper_##op(CPUPPCState *env, uint32_t opcode) \ { \ ppc_vsr_t xt, xb; \ @@ -2634,6 +2634,9 @@ void helper_##op(CPUPPCState *env, uint32_t opcode) \ for (i = 0; i nels; i++) {\ int j = jdef; \ xt.tfld = stp##_to_##ttp(xb.sfld, env-fp_status); \ +if (r2sp) { \ +xt.tfld = helper_frsp(env, xt.tfld);\ +} \ if (sfprf) {\ helper_compute_fprf(env, xt.tfld, sfprf); \ } \ @@ -2643,20 +2646,22 @@ void helper_##op(CPUPPCState *env, uint32_t opcode) \ helper_float_check_status(env); \ } -VSX_CVT_INT_TO_FP(xscvsxddp, 1, int64, float64, u64[j], f64[i], i, 1) -VSX_CVT_INT_TO_FP(xscvuxddp, 1, uint64, float64, u64[j], f64[i], i, 1) -VSX_CVT_INT_TO_FP(xvcvsxddp, 2, int64, float64, u64[j], f64[i], i, 0) -VSX_CVT_INT_TO_FP(xvcvuxddp, 2, uint64, float64, u64[j], f64[i], i, 0) +VSX_CVT_INT_TO_FP(xscvsxddp, 1, int64, float64, u64[j], f64[i], i, 1, 0) +VSX_CVT_INT_TO_FP(xscvuxddp, 1, uint64, float64, u64[j], f64[i], i, 1, 0) +VSX_CVT_INT_TO_FP(xscvsxdsp, 1, int64, float64, u64[j], f64[i], i, 1, 1) +VSX_CVT_INT_TO_FP(xscvuxdsp, 1, uint64, float64, u64[j], f64[i], i, 1, 1) +VSX_CVT_INT_TO_FP(xvcvsxddp, 2, int64, float64, u64[j], f64[i], i, 0, 0) +VSX_CVT_INT_TO_FP(xvcvuxddp, 2, uint64, float64, u64[j], f64[i], i, 0, 0) VSX_CVT_INT_TO_FP(xvcvsxwdp, 2, int32, float64, u32[j], f64[i], \ - 2*i + JOFFSET, 0) + 2*i + JOFFSET, 0, 0) VSX_CVT_INT_TO_FP(xvcvuxwdp, 2, uint64, float64, u32[j], f64[i], \ - 2*i + JOFFSET, 0) + 2*i + JOFFSET, 0, 0) VSX_CVT_INT_TO_FP(xvcvsxdsp, 2, int64, float32, u64[i], f32[j], \ - 2*i + JOFFSET, 0) + 2*i + JOFFSET, 0, 0) VSX_CVT_INT_TO_FP(xvcvuxdsp, 2, uint64, float32, u64[i], f32[j], \ - 2*i + JOFFSET, 0) -VSX_CVT_INT_TO_FP(xvcvsxwsp, 4, int32, float32, u32[j], f32[i], i, 0) -VSX_CVT_INT_TO_FP(xvcvuxwsp, 4, uint32, float32, u32[j], f32[i], i, 0) + 2*i + JOFFSET, 0, 0) +VSX_CVT_INT_TO_FP(xvcvsxwsp, 4, int32, float32, u32[j], f32[i], i, 0, 0) +VSX_CVT_INT_TO_FP(xvcvuxwsp, 4, uint32, float32, u32[j], f32[i], i, 0, 0) /* For use current rounding mode, define a value that will not be one of * the existing rounding model enums. diff --git a/target-ppc/helper.h b/target-ppc/helper.h index 655b670..6250eba 100644 --- a/target-ppc/helper.h +++ b/target-ppc/helper.h @@ -279,6 +279,8 @@ DEF_HELPER_2(xscvdpsxws, void, env, i32) DEF_HELPER_2(xscvdpuxds, void, env, i32) DEF_HELPER_2(xscvdpuxws, void, env, i32) DEF_HELPER_2(xscvsxddp, void, env, i32) +DEF_HELPER_2(xscvuxdsp, void, env, i32) +DEF_HELPER_2(xscvsxdsp, void, env, i32) DEF_HELPER_2(xscvuxddp, void, env, i32) DEF_HELPER_2(xsrdpi, void, env, i32) DEF_HELPER_2(xsrdpic, void, env, i32) diff --git a/target-ppc/translate.c b/target-ppc/translate.c index 672cf0a..e13bb8f 100644 --- a/target-ppc/translate.c +++ b/target-ppc/translate.c @@ -7356,6 +7356,8 @@ GEN_VSX_HELPER_2(xsnmaddasp, 0x04, 0x10, 0, PPC2_VSX207) GEN_VSX_HELPER_2(xsnmaddmsp, 0x04, 0x11, 0, PPC2_VSX207) GEN_VSX_HELPER_2(xsnmsubasp, 0x04, 0x12, 0, PPC2_VSX207) GEN_VSX_HELPER_2(xsnmsubmsp,
[Qemu-devel] [V2 PATCH 08/14] target-ppc: VSX Stage 4: Add xsdivsp
This patch adds the VSX Scalar Divide Single Precision (xsdivsp) instruction. The existing VSX_DIV macro is modified to support rounding of the intermediate double precision result to single precision. V2: Updated conversion to single precision. Signed-off-by: Tom Musta tommu...@gmail.com --- target-ppc/fpu_helper.c | 13 + target-ppc/helper.h |1 + target-ppc/translate.c |2 ++ 3 files changed, 12 insertions(+), 4 deletions(-) diff --git a/target-ppc/fpu_helper.c b/target-ppc/fpu_helper.c index b3a5261..da31964 100644 --- a/target-ppc/fpu_helper.c +++ b/target-ppc/fpu_helper.c @@ -1874,7 +1874,7 @@ VSX_MUL(xvmulsp, 4, float32, f32, 0, 0) * fld - vsr_t field (f32 or f64) * sfprf - set FPRF */ -#define VSX_DIV(op, nels, tp, fld, sfprf) \ +#define VSX_DIV(op, nels, tp, fld, sfprf, r2sp) \ void helper_##op(CPUPPCState *env, uint32_t opcode) \ { \ ppc_vsr_t xt, xa, xb; \ @@ -1903,6 +1903,10 @@ void helper_##op(CPUPPCState *env, uint32_t opcode) \ } \ } \ \ +if (r2sp) { \ +xt.fld[i] = helper_frsp(env, xt.fld[i]); \ +} \ + \ if (sfprf) { \ helper_compute_fprf(env, xt.fld[i], sfprf); \ } \ @@ -1912,9 +1916,10 @@ void helper_##op(CPUPPCState *env, uint32_t opcode) \ helper_float_check_status(env); \ } -VSX_DIV(xsdivdp, 1, float64, f64, 1) -VSX_DIV(xvdivdp, 2, float64, f64, 0) -VSX_DIV(xvdivsp, 4, float32, f32, 0) +VSX_DIV(xsdivdp, 1, float64, f64, 1, 0) +VSX_DIV(xsdivsp, 1, float64, f64, 1, 1) +VSX_DIV(xvdivdp, 2, float64, f64, 0, 0) +VSX_DIV(xvdivsp, 4, float32, f32, 0, 0) /* VSX_RE - VSX floating point reciprocal estimate * op- instruction mnemonic diff --git a/target-ppc/helper.h b/target-ppc/helper.h index 0ccdc96..308f97c 100644 --- a/target-ppc/helper.h +++ b/target-ppc/helper.h @@ -289,6 +289,7 @@ DEF_HELPER_2(xsrdpiz, void, env, i32) DEF_HELPER_2(xsaddsp, void, env, i32) DEF_HELPER_2(xssubsp, void, env, i32) DEF_HELPER_2(xsmulsp, void, env, i32) +DEF_HELPER_2(xsdivsp, void, env, i32) DEF_HELPER_2(xvadddp, void, env, i32) DEF_HELPER_2(xvsubdp, void, env, i32) diff --git a/target-ppc/translate.c b/target-ppc/translate.c index 450ab88..896dbc2 100644 --- a/target-ppc/translate.c +++ b/target-ppc/translate.c @@ -7344,6 +7344,7 @@ GEN_VSX_HELPER_2(xsrdpiz, 0x12, 0x05, 0, PPC2_VSX) GEN_VSX_HELPER_2(xsaddsp, 0x00, 0x00, 0, PPC2_VSX207) GEN_VSX_HELPER_2(xssubsp, 0x00, 0x01, 0, PPC2_VSX207) GEN_VSX_HELPER_2(xsmulsp, 0x00, 0x02, 0, PPC2_VSX207) +GEN_VSX_HELPER_2(xsdivsp, 0x00, 0x03, 0, PPC2_VSX207) GEN_VSX_HELPER_2(xvadddp, 0x00, 0x0C, 0, PPC2_VSX) GEN_VSX_HELPER_2(xvsubdp, 0x00, 0x0D, 0, PPC2_VSX) @@ -10155,6 +10156,7 @@ GEN_XX2FORM(xsrdpiz, 0x12, 0x05, PPC2_VSX), GEN_XX3FORM(xsaddsp, 0x00, 0x00, PPC2_VSX207), GEN_XX3FORM(xssubsp, 0x00, 0x01, PPC2_VSX207), GEN_XX3FORM(xsmulsp, 0x00, 0x02, PPC2_VSX207), +GEN_XX3FORM(xsdivsp, 0x00, 0x03, PPC2_VSX207), GEN_XX3FORM(xvadddp, 0x00, 0x0C, PPC2_VSX), GEN_XX3FORM(xvsubdp, 0x00, 0x0D, PPC2_VSX), -- 1.7.1
[Qemu-devel] [V2 PATCH 14/14] target-ppc: VSX Stage 4: Add xxleqv, xxlnand and xxlorc
This patchs adds the VSX Logical instructions that are new with ISA V2.07: - VSX Logical Equivalence (xxleqv) - VSX Logical NAND (xxlnand) - VSX Logical ORC (xxlorc) Signed-off-by: Tom Musta tommu...@gmail.com --- target-ppc/translate.c |6 ++ 1 files changed, 6 insertions(+), 0 deletions(-) diff --git a/target-ppc/translate.c b/target-ppc/translate.c index e13bb8f..1f7e499 100644 --- a/target-ppc/translate.c +++ b/target-ppc/translate.c @@ -7451,6 +7451,9 @@ VSX_LOGICAL(xxlandc, tcg_gen_andc_tl) VSX_LOGICAL(xxlor, tcg_gen_or_tl) VSX_LOGICAL(xxlxor, tcg_gen_xor_tl) VSX_LOGICAL(xxlnor, tcg_gen_nor_tl) +VSX_LOGICAL(xxleqv, tcg_gen_eqv_tl) +VSX_LOGICAL(xxlnand, tcg_gen_nand_tl) +VSX_LOGICAL(xxlorc, tcg_gen_orc_tl) #define VSX_XXMRG(name, high) \ static void glue(gen_, name)(DisasContext * ctx)\ @@ -10267,6 +10270,9 @@ VSX_LOGICAL(xxlandc, 0x8, 0x11, PPC2_VSX), VSX_LOGICAL(xxlor, 0x8, 0x12, PPC2_VSX), VSX_LOGICAL(xxlxor, 0x8, 0x13, PPC2_VSX), VSX_LOGICAL(xxlnor, 0x8, 0x14, PPC2_VSX), +VSX_LOGICAL(xxleqv, 0x8, 0x17, PPC2_VSX207), +VSX_LOGICAL(xxlnand, 0x8, 0x16, PPC2_VSX207), +VSX_LOGICAL(xxlorc, 0x8, 0x15, PPC2_VSX207), GEN_XX3FORM(xxmrghw, 0x08, 0x02, PPC2_VSX), GEN_XX3FORM(xxmrglw, 0x08, 0x06, PPC2_VSX), GEN_XX2FORM(xxspltw, 0x08, 0x0A, PPC2_VSX), -- 1.7.1
Re: [Qemu-devel] [PATCH 2/3] ui/vnc: optimize dirty bitmap tracking
On 18.11.2013 17:27, Anthony Liguori wrote: On Nov 18, 2013 12:20 AM, Peter Lieven p...@kamp.de mailto:p...@kamp.de wrote: vnc_update_client currently scans the dirty bitmap of each client bitwise which is a very costly operation if only few bits are dirty. vnc_refresh_server_surface does almost the same. this patch optimizes both by utilizing the heavily optimized function find_next_bit to find the offset of the next dirty bit in the dirty bitmaps. Signed-off-by: Peter Lieven p...@kamp.de mailto:p...@kamp.de Can you include performance data? I made some aritificial analysis of vnc_update_client with the attached test code. $ gcc -O2 -o vnc_perf vnc_perf.c $ ./vnc_perf All bits clean - vnc_update_client_new: 0.07 secs vnc_update_client_old: 10.82 secs All bits dirty - vnc_update_client_new: 9.81 secs vnc_update_client_old: 20.00 secs Few bits dirty - vnc_update_client_new: 0.08 secs vnc_update_client_old: 10.62 secs find_and_clear_dirty_height() is still very slow, but I will look at this separately. Peter --- #define ITERATIONS 16*1024 #define VNC_MAX_WIDTH 2560 #define VNC_MAX_HEIGHT 2048 #define VNC_DIRTY_PIXELS_PER_BIT 16 /* VNC_DIRTY_BITS is the number of bits in the dirty bitmap. */ #define VNC_DIRTY_BITS (VNC_MAX_WIDTH / VNC_DIRTY_PIXELS_PER_BIT) /* VNC_DIRTY_BITS_PER_LINE might be greater than VNC_DIRTY_BITS due to alignment */ #define VNC_DIRTY_BITS_PER_LINE(x) (sizeof(x) / VNC_MAX_HEIGHT * BITS_PER_BYTE) #define BITS_PER_BYTE 8 #define BITS_PER_LONG (sizeof (unsigned long) * BITS_PER_BYTE) #define BITOP_WORD(nr)((nr) / BITS_PER_LONG) #define DIV_ROUND_UP(n,d) (((n) + (d) - 1) / (d)) #define BIT(nr)(1UL (nr)) #define BIT_MASK(nr)(1UL ((nr) % BITS_PER_LONG)) #define BIT_WORD(nr)((nr) / BITS_PER_LONG) #define BITS_TO_LONGS(nr)DIV_ROUND_UP(nr, BITS_PER_BYTE * sizeof(long)) #define DECLARE_BITMAP(name,bits) \ unsigned long name[BITS_TO_LONGS(bits)] #define ctzl ctz64 #include stdio.h #include stdint.h #include string.h #include time.h static inline int ctz64(uint64_t val) { return val ? __builtin_ctzll(val) : 64; } DECLARE_BITMAP(dirty[VNC_MAX_HEIGHT], VNC_DIRTY_BITS); unsigned long find_next_bit(const unsigned long *addr, unsigned long size, unsigned long offset) { const unsigned long *p = addr + BITOP_WORD(offset); unsigned long result = offset ~(BITS_PER_LONG-1); unsigned long tmp; if (offset = size) { return size; } size -= result; offset %= BITS_PER_LONG; if (offset) { tmp = *(p++); tmp = (~0UL offset); if (size BITS_PER_LONG) { goto found_first; } if (tmp) { goto found_middle; } size -= BITS_PER_LONG; result += BITS_PER_LONG; } while (size = 4*BITS_PER_LONG) { unsigned long d1, d2, d3; tmp = *p; d1 = *(p+1); d2 = *(p+2); d3 = *(p+3); if (tmp) { goto found_middle; } if (d1 | d2 | d3) { break; } p += 4; result += 4*BITS_PER_LONG; size -= 4*BITS_PER_LONG; } while (size = BITS_PER_LONG) { if ((tmp = *(p++))) { goto found_middle; } result += BITS_PER_LONG; size -= BITS_PER_LONG; } if (!size) { return result; } tmp = *p; found_first: tmp = (~0UL (BITS_PER_LONG - size)); if (tmp == 0UL) {/* Are any bits set? */ return result + size;/* Nope. */ } found_middle: return result + ctzl(tmp); } static inline int test_bit(int nr, const unsigned long *addr) { return 1UL (addr[BIT_WORD(nr)] (nr (BITS_PER_LONG-1))); } static inline void clear_bit(int nr, unsigned long *addr) { unsigned long mask = BIT_MASK(nr); unsigned long *p = addr + BIT_WORD(nr); *p = ~mask; } static inline void set_bit(int nr, unsigned long *addr) { unsigned long mask = BIT_MASK(nr); unsigned long *p = addr + BIT_WORD(nr); *p |= mask; } static inline int test_and_clear_bit(int nr, unsigned long *addr) { unsigned long mask = BIT_MASK(nr); unsigned long *p = addr + BIT_WORD(nr); unsigned long old = *p; *p = old ~mask; return (old mask) != 0; } static int find_and_clear_dirty_height(int y, int last_x, int x, int height) { int h; for (h = 1; h (height - y); h++) { int tmp_x; if (!test_bit(last_x, dirty[y + h])) { break; } for (tmp_x = last_x; tmp_x x; tmp_x++) { clear_bit(tmp_x, dirty[y + h]); } } return h; } #define VNC_CLIENT_UPDATE_RECT() \ if (last_x != -1) {\ int h = find_and_clear_dirty_height(y, last_x, x, height);\ } void vnc_update_client_new() { int width = VNC_MAX_WIDTH; int height =
Re: [Qemu-devel] [PATCH for-1.7] pci: unregister vmstate_pcibus on unplug
On Tue, Nov 19, 2013 at 01:51:58PM +0100, Andreas Färber wrote: Am 06.11.2013 23:52, schrieb Bandan Das: PCIBus registers a vmstate during init. Unregister it upon removal/unplug. Signed-off-by: Bandan Das b...@redhat.com Michael, this patch looks good for 1.7 to me, are you planning to still pick it up? Only one small comment below. Cc: qemu-sta...@nongnu.org --- Note that I didn't add a instance_init to register vmstate (yet) due to concerns expressed by Andreas that we shouldn't be registering global state there. What's happening here is the following: instance_init does in fact not register anything, but vmstate_unregister() becomes a no-op loop if the vmsd+opaque combo is not registered, so it is safe. The registration happens in pci_bus_new() / pci_bus_new_inplace(), which I believe all PCI buses to date inside QEMU use, i.e. after instance_init, so in practice unregistering will not be no-op. hw/pci/pci.c | 8 1 file changed, 8 insertions(+) diff --git a/hw/pci/pci.c b/hw/pci/pci.c index a98c8a0..63ef7ce 100644 --- a/hw/pci/pci.c +++ b/hw/pci/pci.c @@ -47,6 +47,7 @@ static void pcibus_dev_print(Monitor *mon, DeviceState *dev, int indent); static char *pcibus_get_dev_path(DeviceState *dev); static char *pcibus_get_fw_dev_path(DeviceState *dev); static int pcibus_reset(BusState *qbus); +static void pci_bus_finalize(Object *obj); It may be nicer to avoid the prototype by moving the new pci_bus_finalize() above pci_bus_info. But since what counts is the fix to avoid segfaults during migration on access to a dangling opaque pointer after hot-unplug of a PCI-PCI bridge, Reviewed-by: Andreas Färber afaer...@suse.de Thanks, Andreas Thanks for the review, I'll review and hopefully merge later today. static Property pci_props[] = { DEFINE_PROP_PCI_DEVFN(addr, PCIDevice, devfn, -1), @@ -73,6 +74,7 @@ static const TypeInfo pci_bus_info = { .name = TYPE_PCI_BUS, .parent = TYPE_BUS, .instance_size = sizeof(PCIBus), +.instance_finalize = pci_bus_finalize, .class_init = pci_bus_class_init, }; @@ -401,6 +403,12 @@ int pci_bus_num(PCIBus *s) return s-parent_dev-config[PCI_SECONDARY_BUS]; } +static void pci_bus_finalize(Object *obj) +{ +PCIBus *bus = PCI_BUS(obj); +vmstate_unregister(NULL, vmstate_pcibus, bus); +} + static int get_pci_config_device(QEMUFile *f, void *pv, size_t size) { PCIDevice *s = container_of(pv, PCIDevice, config); -- SUSE LINUX Products GmbH, Maxfeldstr. 5, 90409 Nürnberg, Germany GF: Jeff Hawn, Jennifer Guild, Felix Imendörffer; HRB 16746 AG Nürnberg
Re: [Qemu-devel] [PATCH 2/3] ui/vnc: optimize dirty bitmap tracking
On 19.11.2013 14:48, Peter Lieven wrote: On 18.11.2013 17:27, Anthony Liguori wrote: On Nov 18, 2013 12:20 AM, Peter Lieven p...@kamp.de mailto:p...@kamp.de wrote: vnc_update_client currently scans the dirty bitmap of each client bitwise which is a very costly operation if only few bits are dirty. vnc_refresh_server_surface does almost the same. this patch optimizes both by utilizing the heavily optimized function find_next_bit to find the offset of the next dirty bit in the dirty bitmaps. Signed-off-by: Peter Lieven p...@kamp.de mailto:p...@kamp.de Can you include performance data? I made some aritificial analysis of vnc_update_client with the attached test code. $ gcc -O2 -o vnc_perf vnc_perf.c $ ./vnc_perf All bits clean - vnc_update_client_new: 0.07 secs vnc_update_client_old: 10.82 secs All bits dirty - vnc_update_client_new: 9.81 secs vnc_update_client_old: 20.00 secs Few bits dirty - vnc_update_client_new: 0.08 secs vnc_update_client_old: 10.62 secs find_and_clear_dirty_height() is still very slow, but I will look at this separately. quite easy, but great effect: replacing: for (tmp_x = last_x; tmp_x x; tmp_x++) { clear_bit(tmp_x, dirty[y + h]); } with: bitmap_clear(dirty[y + h], last_x, x - last_x); in find_and_clear_dirty_height(), yields the following performance ;-) All bits clean - vnc_update_client_new: 0.07 secs vnc_update_client_old: 10.65 secs All bits dirty - vnc_update_client_new: 0.69 secs vnc_update_client_old: 19.86 secs Few bits dirty - vnc_update_client_new: 0.07 secs vnc_update_client_old: 10.69 secs Peter --- #define ITERATIONS 16*1024 #define VNC_MAX_WIDTH 2560 #define VNC_MAX_HEIGHT 2048 #define VNC_DIRTY_PIXELS_PER_BIT 16 /* VNC_DIRTY_BITS is the number of bits in the dirty bitmap. */ #define VNC_DIRTY_BITS (VNC_MAX_WIDTH / VNC_DIRTY_PIXELS_PER_BIT) /* VNC_DIRTY_BITS_PER_LINE might be greater than VNC_DIRTY_BITS due to alignment */ #define VNC_DIRTY_BITS_PER_LINE(x) (sizeof(x) / VNC_MAX_HEIGHT * BITS_PER_BYTE) #define BITS_PER_BYTE 8 #define BITS_PER_LONG (sizeof (unsigned long) * BITS_PER_BYTE) #define BITOP_WORD(nr)((nr) / BITS_PER_LONG) #define DIV_ROUND_UP(n,d) (((n) + (d) - 1) / (d)) #define BIT(nr)(1UL (nr)) #define BIT_MASK(nr)(1UL ((nr) % BITS_PER_LONG)) #define BIT_WORD(nr)((nr) / BITS_PER_LONG) #define BITS_TO_LONGS(nr)DIV_ROUND_UP(nr, BITS_PER_BYTE * sizeof(long)) #define DECLARE_BITMAP(name,bits) \ unsigned long name[BITS_TO_LONGS(bits)] #define ctzl ctz64 #include stdio.h #include stdint.h #include string.h #include time.h static inline int ctz64(uint64_t val) { return val ? __builtin_ctzll(val) : 64; } DECLARE_BITMAP(dirty[VNC_MAX_HEIGHT], VNC_DIRTY_BITS); unsigned long find_next_bit(const unsigned long *addr, unsigned long size, unsigned long offset) { const unsigned long *p = addr + BITOP_WORD(offset); unsigned long result = offset ~(BITS_PER_LONG-1); unsigned long tmp; if (offset = size) { return size; } size -= result; offset %= BITS_PER_LONG; if (offset) { tmp = *(p++); tmp = (~0UL offset); if (size BITS_PER_LONG) { goto found_first; } if (tmp) { goto found_middle; } size -= BITS_PER_LONG; result += BITS_PER_LONG; } while (size = 4*BITS_PER_LONG) { unsigned long d1, d2, d3; tmp = *p; d1 = *(p+1); d2 = *(p+2); d3 = *(p+3); if (tmp) { goto found_middle; } if (d1 | d2 | d3) { break; } p += 4; result += 4*BITS_PER_LONG; size -= 4*BITS_PER_LONG; } while (size = BITS_PER_LONG) { if ((tmp = *(p++))) { goto found_middle; } result += BITS_PER_LONG; size -= BITS_PER_LONG; } if (!size) { return result; } tmp = *p; found_first: tmp = (~0UL (BITS_PER_LONG - size)); if (tmp == 0UL) {/* Are any bits set? */ return result + size;/* Nope. */ } found_middle: return result + ctzl(tmp); } static inline int test_bit(int nr, const unsigned long *addr) { return 1UL (addr[BIT_WORD(nr)] (nr (BITS_PER_LONG-1))); } static inline void clear_bit(int nr, unsigned long *addr) { unsigned long mask = BIT_MASK(nr); unsigned long *p = addr + BIT_WORD(nr); *p = ~mask; } static inline void set_bit(int nr, unsigned long *addr) { unsigned long mask = BIT_MASK(nr); unsigned long *p = addr + BIT_WORD(nr); *p |= mask; } static inline int test_and_clear_bit(int nr, unsigned long *addr) { unsigned long mask = BIT_MASK(nr); unsigned long *p = addr + BIT_WORD(nr); unsigned long old
[Qemu-devel] [V2 PATCH 02/14] target-ppc: VSX Stage 4: Refactor lxsdx
This patch refactors the lxsdx generator. Resuable code is isolated into a macro. The macro will be used in subsequent patches in this series to implement other scalar load instructions. Signed-off-by: Tom Musta tommu...@gmail.com --- target-ppc/translate.c | 31 +-- 1 files changed, 17 insertions(+), 14 deletions(-) diff --git a/target-ppc/translate.c b/target-ppc/translate.c index 52d7165..2541b5f 100644 --- a/target-ppc/translate.c +++ b/target-ppc/translate.c @@ -7006,20 +7006,23 @@ static inline TCGv_i64 cpu_vsrl(int n) } } -static void gen_lxsdx(DisasContext *ctx) -{ -TCGv EA; -if (unlikely(!ctx-vsx_enabled)) { -gen_exception(ctx, POWERPC_EXCP_VSXU); -return; -} -gen_set_access_type(ctx, ACCESS_INT); -EA = tcg_temp_new(); -gen_addr_reg_index(ctx, EA); -gen_qemu_ld64(ctx, cpu_vsrh(xT(ctx-opcode)), EA); -/* NOTE: cpu_vsrl is undefined */ -tcg_temp_free(EA); -} +#define VSX_LOAD_SCALAR(name, operation) \ +static void gen_##name(DisasContext *ctx) \ +{ \ +TCGv EA; \ +if (unlikely(!ctx-vsx_enabled)) {\ +gen_exception(ctx, POWERPC_EXCP_VSXU);\ +return; \ +} \ +gen_set_access_type(ctx, ACCESS_INT); \ +EA = tcg_temp_new(); \ +gen_addr_reg_index(ctx, EA); \ +gen_qemu_##operation(ctx, cpu_vsrh(xT(ctx-opcode)), EA); \ +/* NOTE: cpu_vsrl is undefined */ \ +tcg_temp_free(EA);\ +} + +VSX_LOAD_SCALAR(lxsdx, ld64) static void gen_lxvd2x(DisasContext *ctx) { -- 1.7.1
Re: [Qemu-devel] [PULL 11/13] target-i386: forward CPUID cache leaves when -cpu host is used
On 19.11.2013 14:21, Paolo Bonzini wrote: Il 19/11/2013 13:32, Peter Lieven ha scritto: + +/* We give out APIC IDs ourselves, so force bits 31..26 even for -cpu host. */ +if (cs-nr_cores 1) { +*eax |= (cs-nr_cores - 1) 26; } break; case 5: I already tried exactly this fix. Its reading index 0x004 for increasing indexes until qemu aborts: Oops, it should be I guess if ((*eax 31) cs-nr_cores 1). Maybe, how should we continue. This should be fixed before 1.7 comes out. Peter
Re: [Qemu-devel] [PULL 11/13] target-i386: forward CPUID cache leaves when -cpu host is used
Il 19/11/2013 15:11, Peter Lieven ha scritto: I already tried exactly this fix. Its reading index 0x004 for increasing indexes until qemu aborts: Oops, it should be I guess if ((*eax 31) cs-nr_cores 1). Maybe, how should we continue. This should be fixed before 1.7 comes out. If this works, I'll post a patch. Paolo
Re: [Qemu-devel] [PATCH] virtio-net: don't update mac_table in error state
On Mon, Nov 11, 2013 at 11:48:36AM +0800, Amos Kong wrote: mac_table was always cleaned up first in handling VIRTIO_NET_CTRL_MAC_TABLE_SET command, and we din't recover mac_table content in error state, it's not correct. This patch makes all the changes in temporal variables, only update the real mac_table if everything is ok. We won't change mac_table in error state, so rxfilter notification isn't needed. This patch also fixed same problame in http://lists.nongnu.org/archive/html/qemu-devel/2013-11/msg01188.html (not merge) I will send patch for virtio spec to clarifying this change. Signed-off-by: Amos Kong ak...@redhat.com --- hw/net/virtio-net.c | 34 -- 1 file changed, 20 insertions(+), 14 deletions(-) Thanks, applied to my net-next tree: https://github.com/stefanha/qemu/commits/net-next Stefan
Re: [Qemu-devel] [PULL 11/13] target-i386: forward CPUID cache leaves when -cpu host is used
On 19.11.2013 15:14, Paolo Bonzini wrote: if ((*eax 31) cs-nr_cores 1) at which position exactly do you want to put this condition and take which action? Peter
[Qemu-devel] [V2 PATCH 10/14] target-ppc: VSX Stage 4: Add xssqrtsp
This patch adds the VSX Scalar Square Root Single Precision (xssqrtsp) instruction. The existing VSX_SQRT() macro is modified to support rounding of the intermediate double-precision result to single-precision. V2: Updated conversion to single precision range. Signed-off-by: Tom Musta tommu...@gmail.com --- target-ppc/fpu_helper.c | 13 + target-ppc/helper.h |1 + target-ppc/translate.c |2 ++ 3 files changed, 12 insertions(+), 4 deletions(-) diff --git a/target-ppc/fpu_helper.c b/target-ppc/fpu_helper.c index b633547..34a8b66 100644 --- a/target-ppc/fpu_helper.c +++ b/target-ppc/fpu_helper.c @@ -1969,7 +1969,7 @@ VSX_RE(xvresp, 4, float32, f32, 0, 0) * fld - vsr_t field (f32 or f64) * sfprf - set FPRF */ -#define VSX_SQRT(op, nels, tp, fld, sfprf) \ +#define VSX_SQRT(op, nels, tp, fld, sfprf, r2sp) \ void helper_##op(CPUPPCState *env, uint32_t opcode) \ {\ ppc_vsr_t xt, xb;\ @@ -1993,6 +1993,10 @@ void helper_##op(CPUPPCState *env, uint32_t opcode) \ }\ }\ \ +if (r2sp) { \ +xt.fld[i] = helper_frsp(env, xt.fld[i]); \ +}\ + \ if (sfprf) { \ helper_compute_fprf(env, xt.fld[i], sfprf); \ }\ @@ -2002,9 +2006,10 @@ void helper_##op(CPUPPCState *env, uint32_t opcode) \ helper_float_check_status(env); \ } -VSX_SQRT(xssqrtdp, 1, float64, f64, 1) -VSX_SQRT(xvsqrtdp, 2, float64, f64, 0) -VSX_SQRT(xvsqrtsp, 4, float32, f32, 0) +VSX_SQRT(xssqrtdp, 1, float64, f64, 1, 0) +VSX_SQRT(xssqrtsp, 1, float64, f64, 1, 1) +VSX_SQRT(xvsqrtdp, 2, float64, f64, 0, 0) +VSX_SQRT(xvsqrtsp, 4, float32, f32, 0, 0) /* VSX_RSQRTE - VSX floating point reciprocal square root estimate * op- instruction mnemonic diff --git a/target-ppc/helper.h b/target-ppc/helper.h index b1cf3c0..0192043 100644 --- a/target-ppc/helper.h +++ b/target-ppc/helper.h @@ -291,6 +291,7 @@ DEF_HELPER_2(xssubsp, void, env, i32) DEF_HELPER_2(xsmulsp, void, env, i32) DEF_HELPER_2(xsdivsp, void, env, i32) DEF_HELPER_2(xsresp, void, env, i32) +DEF_HELPER_2(xssqrtsp, void, env, i32) DEF_HELPER_2(xvadddp, void, env, i32) DEF_HELPER_2(xvsubdp, void, env, i32) diff --git a/target-ppc/translate.c b/target-ppc/translate.c index c4c57a1..b9cd35b 100644 --- a/target-ppc/translate.c +++ b/target-ppc/translate.c @@ -7346,6 +7346,7 @@ GEN_VSX_HELPER_2(xssubsp, 0x00, 0x01, 0, PPC2_VSX207) GEN_VSX_HELPER_2(xsmulsp, 0x00, 0x02, 0, PPC2_VSX207) GEN_VSX_HELPER_2(xsdivsp, 0x00, 0x03, 0, PPC2_VSX207) GEN_VSX_HELPER_2(xsresp, 0x14, 0x01, 0, PPC2_VSX207) +GEN_VSX_HELPER_2(xssqrtsp, 0x16, 0x00, 0, PPC2_VSX207) GEN_VSX_HELPER_2(xvadddp, 0x00, 0x0C, 0, PPC2_VSX) GEN_VSX_HELPER_2(xvsubdp, 0x00, 0x0D, 0, PPC2_VSX) @@ -10159,6 +10160,7 @@ GEN_XX3FORM(xssubsp, 0x00, 0x01, PPC2_VSX207), GEN_XX3FORM(xsmulsp, 0x00, 0x02, PPC2_VSX207), GEN_XX3FORM(xsdivsp, 0x00, 0x03, PPC2_VSX207), GEN_XX2FORM(xsresp, 0x14, 0x01, PPC2_VSX207), +GEN_XX2FORM(xssqrtsp, 0x16, 0x00, PPC2_VSX207), GEN_XX3FORM(xvadddp, 0x00, 0x0C, PPC2_VSX), GEN_XX3FORM(xvsubdp, 0x00, 0x0D, PPC2_VSX), -- 1.7.1
Re: [Qemu-devel] [PULL 11/13] target-i386: forward CPUID cache leaves when -cpu host is used
Il 19/11/2013 15:17, Peter Lieven ha scritto: if ((*eax 31) cs-nr_cores 1) at which position exactly do you want to put this condition and take which action? Just replace if (cs-nr_cores 1) in the patch I posted, i.e. after the switch. Paolo -- 8 - From 781ff96e9d1eeacbd4ff588d4d3773351f14320b Mon Sep 17 00:00:00 2001 From: Paolo Bonzini pbonz...@redhat.com Date: Tue, 19 Nov 2013 13:19:17 +0100 Subject: [PATCH] target-i386: do not override nr_cores for -cpu host Commit 787aaf5 (target-i386: forward CPUID cache leaves when -cpu host is used, 2013-09-02) brings bits 31..26 of CPUID leaf 04h out of sync with the APIC IDs that QEMU reserves for each package. This number must come from -smp options rather than from the host CPUID. It also turns out that this unsyncing makes Windows Server 2012R2 fail to boot. Signed-off-by: Paolo Bonzini pbonz...@redhat.com --- target-i386/cpu.c | 14 -- 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/target-i386/cpu.c b/target-i386/cpu.c index 864c80e..8df6747 100644 --- a/target-i386/cpu.c +++ b/target-i386/cpu.c @@ -2086,14 +2086,10 @@ void cpu_x86_cpuid(CPUX86State *env, uint32_t index, uint32_t count, /* cache info: needed for Core compatibility */ if (cpu-cache_info_passthrough) { host_cpuid(index, count, eax, ebx, ecx, edx); -break; -} -if (cs-nr_cores 1) { -*eax = (cs-nr_cores - 1) 26; +*eax = ~0xFC00; } else { *eax = 0; -} -switch (count) { +switch (count) { case 0: /* L1 dcache info */ *eax |= CPUID_4_TYPE_DCACHE | \ CPUID_4_LEVEL(1) | \ @@ -2133,6 +2129,12 @@ void cpu_x86_cpuid(CPUX86State *env, uint32_t index, uint32_t count, *ecx = 0; *edx = 0; break; +} +} + +/* We give out APIC IDs ourselves, so force bits 31..26 even for -cpu host. */ +if ((*eax 31) cs-nr_cores 1) { +*eax |= (cs-nr_cores - 1) 26; } break; case 5: -- 1.8.4.2
Re: [Qemu-devel] dataplane, thread and gpu stuff
On Mon, Nov 18, 2013 at 08:18:47AM -0800, Anthony Liguori wrote: On Nov 18, 2013 7:05 AM, Stefan Hajnoczi stefa...@gmail.com wrote: On Mon, Nov 18, 2013 at 02:52:53PM +1000, Dave Airlie wrote: So after talking to a few people at kvm forum I think the GPU code should probably use the dataplane stuff from the outset, The main advantages I think this gives me is being able to dequeue objects from the vq from a thread and send irq vectors from there as well. Though since it appears the dataplane stuff is kvm specific (at least the irq handling), I was wondering how I should deal with fallbacks for non-kvm operation, and quite how much falling back I need to do. Can I still use the dataplane/vring code from the normal bottom half handlers or do I have to write separate code for both situations. As of today, there are still two vring implementations in hw/virtio/virtio.c and hw/virtio/dataplane/vring.c. This means it isn't clean and easy to integrate into a new device yet. Existing dataplane devices basically take advantage of the fact that the non-dataplane version sets up the device before I/O. I think we also need some form of mdroth's GContext prior to introducing more dataplane devices. Sticking every device in a seperate thread with no way to control who is where can actually hurt performance. I think we really need to have a M-N device thread model too. Yes, I agree. We need the concept of multiple event loops (QContext). Stefan
Re: [Qemu-devel] dataplane, thread and gpu stuff
On Mon, Nov 18, 2013 at 05:37:20PM +0100, Paolo Bonzini wrote: Il 18/11/2013 16:03, Stefan Hajnoczi ha scritto: As of today, there are still two vring implementations in hw/virtio/virtio.c and hw/virtio/dataplane/vring.c. This means it isn't clean and easy to integrate into a new device yet. Existing dataplane devices basically take advantage of the fact that the non-dataplane version sets up the device before I/O. Paolo can give you details on the latest thread-safe memory API stuff and whether it's already usable for virtio. vring and virtio are still separate even in my latest patches. I have patches to convert vring to use memory_region_find instead of hostmem. Regarding irqfd, we could emulate it in TCG using an EventNotifier (eventfd). At that point I think it's no longer kvm-specific. I think he's talking about ioeventfd though. ioeventfd can be emulated using EventNotifier too, although it depends on the handler function whether or not it's worth deferring it to another thread. Stefan
Re: [Qemu-devel] Multi-head support RFC
On 11/19/2013 1:57 AM, Gerd Hoffmann wrote: Hi, I think it would be better if the HwOps calls all took a QemuConsole instead of the opaque structure. The hw implementations can dig their opaque structure out from there. QemuConsole is private to ui/console.c though (and I prefer to keep it this way). So we need either a helper function to query con-hw or we keep the opaque and pass QemuConsole as additional parameter. When going this route. Alternative approach: struct my_gfx_card_state { PCIDevice pci; [ ... ] struct my_head_state { QemuConsole *con; [ ... ] } heads[MAX_HEADS]; } Then instead of graphic_console_init(..., state); call graphic_console_init(..., state-heads[i]); so you can figure the head in the callbacks. What I had prototyped (I got impatient) was to add a helper: qemu_console_hw_opaque() to console.c so the HwOps could query the opaque pointer. I don't like it because it requires an additional function call at the top of frequently called operations... However I'm not a huge fan of the head state array either, since it will require either pointer duplication, or pointer acrobatics, or the same helper function to get the card state. A third option would be to use the console index as a parameter to each HwOp. graphic_console_init and QemuConsole could remain unchanged, as could all the graphic_hw_*() helpers. If the HwOp needs the QemuConsole for any given operation, it could then use qemu_console_lookup_by_index(). Many operations would only need the index though. cheers, Gerd
[Qemu-devel] [V2 PATCH 12/14] target-ppc: VSX Stage 4: Add Scalar SP Fused Multiply-Adds
This patch adds the Single Precision VSX Scalar Fused Multiply-Add instructions: xsmaddasp, xsmaddmsp, xssubasp, xssubmsp, xsnmaddasp, xsnmaddmsp, xsnmsubasp, xsnmsubmsp. The existing VSX_MADD() macro is modified to support rounding of the intermediate double precision result to single precision. V2: Re-implemented per feedback from Richard Henderson. In order to avoid double rounding and incorrect results, the operands must be converted to true single precision values and use the single precision fused multiply/add routine. Signed-off-by: Tom Musta tommu...@gmail.com --- target-ppc/fpu_helper.c | 77 +++ target-ppc/helper.h |8 + target-ppc/translate.c | 16 ++ 3 files changed, 101 insertions(+), 0 deletions(-) diff --git a/target-ppc/fpu_helper.c b/target-ppc/fpu_helper.c index 8825db2..6428c54 100644 --- a/target-ppc/fpu_helper.c +++ b/target-ppc/fpu_helper.c @@ -2250,6 +2250,74 @@ void helper_##op(CPUPPCState *env, uint32_t opcode) \ helper_float_check_status(env); \ } +/* VSX_XSMADDSP - VSX scalar muliply/add single precision variations + * op- instruction mnemonic + * maddflgs - flags for the float*muladd routine that control the + * various forms (madd, msub, nmadd, nmsub) + * afrm - A form (1=A, 0=M) + */ +#define VSX_XSMADDSP(op, maddflgs, afrm) \ +void helper_##op(CPUPPCState *env, uint32_t opcode) \ +{ \ +ppc_vsr_t xt_in, xa, xb, xt_out; \ +ppc_vsr_t *b, *c; \ + \ +if (afrm) { /* AxB + T */ \ +b = xb; \ +c = xt_in; \ +} else { /* AxT + B */\ +b = xt_in; \ +c = xb; \ +} \ + \ +getVSR(xA(opcode), xa, env); \ +getVSR(xB(opcode), xb, env); \ +getVSR(xT(opcode), xt_in, env); \ + \ +xt_out = xt_in; \ + \ +helper_reset_fpstatus(env); \ + \ +/* NOTE: in order to get accurate results, we must first round back */\ +/* to single precision and use the fused multiply add routine */\ +/* for 32-bit floats. */\ +float_status tstat = env-fp_status; \ +float32 a32 = float64_to_float32(xa.f64[0], tstat); \ +float32 b32 = float64_to_float32(b-f64[0], tstat); \ +float32 c32 = float64_to_float32(c-f64[0], tstat); \ + \ +set_float_exception_flags(0, tstat); \ +float32 t32 = float32_muladd(a32, b32, c32, maddflgs, tstat);\ + \ +env-fp_status.float_exception_flags |= tstat.float_exception_flags; \ + \ +if (unlikely(tstat.float_exception_flags float_flag_invalid)) { \ +if (float64_is_signaling_nan(xa.f64[0]) ||\ +float64_is_signaling_nan(b-f64[0]) ||\ +float64_is_signaling_nan(c-f64[0])) {\ +fload_invalid_op_excp(env, POWERPC_EXCP_FP_VXSNAN, 1);\ +tstat.float_exception_flags = ~float_flag_invalid; \ +} \ +if ((float64_is_infinity(xa.f64[0]) float64_is_zero(b-f64[0])) || \ +(float64_is_zero(xa.f64[0]) float64_is_infinity(b-f64[0]))) { \ +xt_out.f64[0] =
[Qemu-devel] [V2 PATCH 06/14] target-ppc: VSX Stage 4: Add xsaddsp and xssubsp
This patch adds the VSX Scalar Add Single-Precision (xsaddsp) and VSX Scalar Subtract Single-Precision (xssubsp) instructions. The existing VSX_ADD_SUB macro is modified to support the rounding of the (intermediate) result to single-precision. V2: updated conversion of result to single precision. Signed-off-by: Tom Musta tommu...@gmail.com --- target-ppc/fpu_helper.c | 20 +--- target-ppc/helper.h |3 +++ target-ppc/translate.c |6 ++ 3 files changed, 22 insertions(+), 7 deletions(-) diff --git a/target-ppc/fpu_helper.c b/target-ppc/fpu_helper.c index f3d02cc..1256ad0 100644 --- a/target-ppc/fpu_helper.c +++ b/target-ppc/fpu_helper.c @@ -1768,7 +1768,7 @@ static void putVSR(int n, ppc_vsr_t *vsr, CPUPPCState *env) * fld - vsr_t field (f32 or f64) * sfprf - set FPRF */ -#define VSX_ADD_SUB(name, op, nels, tp, fld, sfprf) \ +#define VSX_ADD_SUB(name, op, nels, tp, fld, sfprf, r2sp)\ void helper_##name(CPUPPCState *env, uint32_t opcode)\ {\ ppc_vsr_t xt, xa, xb;\ @@ -1794,6 +1794,10 @@ void helper_##name(CPUPPCState *env, uint32_t opcode) \ }\ }\ \ +if (r2sp) { \ +xt.fld[i] = helper_frsp(env, xt.fld[i]); \ +}\ + \ if (sfprf) { \ helper_compute_fprf(env, xt.fld[i], sfprf); \ }\ @@ -1802,12 +1806,14 @@ void helper_##name(CPUPPCState *env, uint32_t opcode) \ helper_float_check_status(env); \ } -VSX_ADD_SUB(xsadddp, add, 1, float64, f64, 1) -VSX_ADD_SUB(xvadddp, add, 2, float64, f64, 0) -VSX_ADD_SUB(xvaddsp, add, 4, float32, f32, 0) -VSX_ADD_SUB(xssubdp, sub, 1, float64, f64, 1) -VSX_ADD_SUB(xvsubdp, sub, 2, float64, f64, 0) -VSX_ADD_SUB(xvsubsp, sub, 4, float32, f32, 0) +VSX_ADD_SUB(xsadddp, add, 1, float64, f64, 1, 0) +VSX_ADD_SUB(xsaddsp, add, 1, float64, f64, 1, 1) +VSX_ADD_SUB(xvadddp, add, 2, float64, f64, 0, 0) +VSX_ADD_SUB(xvaddsp, add, 4, float32, f32, 0, 0) +VSX_ADD_SUB(xssubdp, sub, 1, float64, f64, 1, 0) +VSX_ADD_SUB(xssubsp, sub, 1, float64, f64, 1, 1) +VSX_ADD_SUB(xvsubdp, sub, 2, float64, f64, 0, 0) +VSX_ADD_SUB(xvsubsp, sub, 4, float32, f32, 0, 0) /* VSX_MUL - VSX floating point multiply * op- instruction mnemonic diff --git a/target-ppc/helper.h b/target-ppc/helper.h index 0276b02..696b9d3 100644 --- a/target-ppc/helper.h +++ b/target-ppc/helper.h @@ -286,6 +286,9 @@ DEF_HELPER_2(xsrdpim, void, env, i32) DEF_HELPER_2(xsrdpip, void, env, i32) DEF_HELPER_2(xsrdpiz, void, env, i32) +DEF_HELPER_2(xsaddsp, void, env, i32) +DEF_HELPER_2(xssubsp, void, env, i32) + DEF_HELPER_2(xvadddp, void, env, i32) DEF_HELPER_2(xvsubdp, void, env, i32) DEF_HELPER_2(xvmuldp, void, env, i32) diff --git a/target-ppc/translate.c b/target-ppc/translate.c index 62604fd..bd639cc 100644 --- a/target-ppc/translate.c +++ b/target-ppc/translate.c @@ -7341,6 +7341,9 @@ GEN_VSX_HELPER_2(xsrdpim, 0x12, 0x07, 0, PPC2_VSX) GEN_VSX_HELPER_2(xsrdpip, 0x12, 0x06, 0, PPC2_VSX) GEN_VSX_HELPER_2(xsrdpiz, 0x12, 0x05, 0, PPC2_VSX) +GEN_VSX_HELPER_2(xsaddsp, 0x00, 0x00, 0, PPC2_VSX207) +GEN_VSX_HELPER_2(xssubsp, 0x00, 0x01, 0, PPC2_VSX207) + GEN_VSX_HELPER_2(xvadddp, 0x00, 0x0C, 0, PPC2_VSX) GEN_VSX_HELPER_2(xvsubdp, 0x00, 0x0D, 0, PPC2_VSX) GEN_VSX_HELPER_2(xvmuldp, 0x00, 0x0E, 0, PPC2_VSX) @@ -10148,6 +10151,9 @@ GEN_XX2FORM(xsrdpim, 0x12, 0x07, PPC2_VSX), GEN_XX2FORM(xsrdpip, 0x12, 0x06, PPC2_VSX), GEN_XX2FORM(xsrdpiz, 0x12, 0x05, PPC2_VSX), +GEN_XX3FORM(xsaddsp, 0x00, 0x00, PPC2_VSX207), +GEN_XX3FORM(xssubsp, 0x00, 0x01, PPC2_VSX207), + GEN_XX3FORM(xvadddp, 0x00, 0x0C, PPC2_VSX), GEN_XX3FORM(xvsubdp, 0x00, 0x0D, PPC2_VSX), GEN_XX3FORM(xvmuldp, 0x00, 0x0E, PPC2_VSX), -- 1.7.1
Re: [Qemu-devel] [PULL 11/13] target-i386: forward CPUID cache leaves when -cpu host is used
On 19.11.2013 15:19, Paolo Bonzini wrote: Il 19/11/2013 15:17, Peter Lieven ha scritto: if ((*eax 31) cs-nr_cores 1) at which position exactly do you want to put this condition and take which action? Just replace if (cs-nr_cores 1) in the patch I posted, i.e. after the switch. This seems to work. What is in bits 0..5 of eax? What about the number of threads in count == 2? I would still like to have at least an option to disable the passthru without recompiling if other issues occur. Paolo -- 8 - From 781ff96e9d1eeacbd4ff588d4d3773351f14320b Mon Sep 17 00:00:00 2001 From: Paolo Bonzini pbonz...@redhat.com Date: Tue, 19 Nov 2013 13:19:17 +0100 Subject: [PATCH] target-i386: do not override nr_cores for -cpu host Commit 787aaf5 (target-i386: forward CPUID cache leaves when -cpu host is used, 2013-09-02) brings bits 31..26 of CPUID leaf 04h out of sync with the APIC IDs that QEMU reserves for each package. This number must come from -smp options rather than from the host CPUID. It also turns out that this unsyncing makes Windows Server 2012R2 fail to boot. Signed-off-by: Paolo Bonzini pbonz...@redhat.com --- target-i386/cpu.c | 14 -- 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/target-i386/cpu.c b/target-i386/cpu.c index 864c80e..8df6747 100644 --- a/target-i386/cpu.c +++ b/target-i386/cpu.c @@ -2086,14 +2086,10 @@ void cpu_x86_cpuid(CPUX86State *env, uint32_t index, uint32_t count, /* cache info: needed for Core compatibility */ if (cpu-cache_info_passthrough) { host_cpuid(index, count, eax, ebx, ecx, edx); -break; -} -if (cs-nr_cores 1) { -*eax = (cs-nr_cores - 1) 26; +*eax = ~0xFC00; } else { *eax = 0; -} -switch (count) { +switch (count) { case 0: /* L1 dcache info */ *eax |= CPUID_4_TYPE_DCACHE | \ CPUID_4_LEVEL(1) | \ @@ -2133,6 +2129,12 @@ void cpu_x86_cpuid(CPUX86State *env, uint32_t index, uint32_t count, *ecx = 0; *edx = 0; break; +} +} + +/* We give out APIC IDs ourselves, so force bits 31..26 even for -cpu host. */ +if ((*eax 31) cs-nr_cores 1) { +*eax |= (cs-nr_cores - 1) 26; } break; case 5: Tested-by: Peter Lieven p...@kamp.de Peter
Re: [Qemu-devel] [PULL 11/13] target-i386: forward CPUID cache leaves when -cpu host is used
Il 19/11/2013 15:46, Peter Lieven ha scritto: Just replace if (cs-nr_cores 1) in the patch I posted, i.e. after the switch. This seems to work. What is in bits 0..5 of eax? It's the kind of cache. 0 means that there is no cache and the returned data is not valid. In theory, Intel says you should only check whether those bits are 0, and stop iterating when they are, but apparently something is expecting eax=0. What about the number of threads in count == 2? That's a property of the L2 cache. It's not related to APIC IDs. I would still like to have at least an option to disable the passthru without recompiling if other issues occur. I think of -cpu host in general as a hit-or-miss option. I'm not sure whether it makes sense to have such fine grain. Paolo
Re: [Qemu-devel] [PULL 11/13] target-i386: forward CPUID cache leaves when -cpu host is used
On 19.11.2013 15:57, Paolo Bonzini wrote: Il 19/11/2013 15:46, Peter Lieven ha scritto: Just replace if (cs-nr_cores 1) in the patch I posted, i.e. after the switch. This seems to work. What is in bits 0..5 of eax? It's the kind of cache. 0 means that there is no cache and the returned data is not valid. In theory, Intel says you should only check whether those bits are 0, and stop iterating when they are, but apparently something is expecting eax=0. What about the number of threads in count == 2? That's a property of the L2 cache. It's not related to APIC IDs. okay, but the contents could be wrong if the physical system has threads while the emulated vserver has not. does this matter? I would still like to have at least an option to disable the passthru without recompiling if other issues occur. I think of -cpu host in general as a hit-or-miss option. I'm not sure whether it makes sense to have such fine grain. As I explained, I have no trouble with -cpu host for ages when I ensure that I do not live migrate to a processor that misses a feature that was there when the vserver was created. With the caching option this could become a problem or do you think wrong assumption about the cache are just a performance penalty? Peter
Re: [Qemu-devel] [PULL 11/13] target-i386: forward CPUID cache leaves when -cpu host is used
Il 19/11/2013 16:05, Peter Lieven ha scritto: What about the number of threads in count == 2? That's a property of the L2 cache. It's not related to APIC IDs. okay, but the contents could be wrong if the physical system has threads while the emulated vserver has not. does this matter? If you care about passing cache leaves, you probably can be expected to pass a number of threads that matches the host, making the vCPUs a multiple of the number of threads, and pinning the virtual cores to the physical cores. But in general, I'd say that the cache _is_ shared with another thread. It may be that the thread is not part of the VM---that depends on things such as the pinning of vCPUs to physical CPUs. Paolo
Re: [Qemu-devel] [PATCH v5 0/4] Use blkdebug to make test deterministic
On Mon, Nov 18, 2013 at 03:01:47PM +0800, Fam Zheng wrote: This adds remove_break command to block, which removes a break point defined with break. It is used in iotests.py to pause and resume drive in block job cases to make the test deterministic. v5: Addressing Max's comments (thanks for reviewing) [02] Resume all the requests. [03] Fix event= case. Change default value to None. Change resume to bool. [04] Change resume to bool v4: [01] Added. [03] Add common method pair pause_drive and resume_drive. [04] Also fix 040, 055. Fam Zheng (4): qemu-iotests: Drop local version of cancel_and_wait from 040 blkdebug: add remove_break command qemu-iotest: Add pause_drive and resume_drive methods qemu-iotests: Make test case 030, 040 and 055 deterministic block.c | 13 + block/blkdebug.c | 27 +++ include/block/block.h | 1 + include/block/block_int.h | 2 ++ qemu-io-cmds.c| 22 ++ tests/qemu-iotests/030| 16 +++- tests/qemu-iotests/040| 19 +++ tests/qemu-iotests/055| 15 +++ tests/qemu-iotests/iotests.py | 18 +- 9 files changed, 107 insertions(+), 26 deletions(-) I get this failure after applying the patches onto my block-next tree: $ ./check -qcow2 055 QEMU -- /home/stefanha/qemu/tests/qemu-iotests/qemu QEMU_IMG -- /home/stefanha/qemu/tests/qemu-iotests/qemu-img QEMU_IO -- /home/stefanha/qemu/tests/qemu-iotests/qemu-io IMGFMT-- qcow2 (compat=1.1) IMGPROTO -- file PLATFORM -- Linux/x86_64 stefanha-thinkpad 3.11.8-300.fc20.x86_64 SOCKET_SCM_HELPER -- 055 9s ... [failed, exit status 1] - output mismatch (see 055.out.bad) --- 055.out 2013-10-08 13:23:38.412934858 +0200 +++ 055.out.bad 2013-11-19 16:30:31.100351135 +0100 @@ -1,5 +1,15 @@ -.. +...F.. +== +FAIL: test_pause (__main__.TestSingleDrive) +-- +Traceback (most recent call last): + File ./055, line 80, in test_pause +self.assert_qmp(result, 'return[0]/offset', offset) + File /home/stefanha/qemu/tests/qemu-iotests/iotests.py, line 232, in assert_qmp +self.assertEqual(result, value, 'values not equal %s and %s' % (str(result), str(value))) +AssertionError: values not equal 65536 and 0 + -- Ran 14 tests -OK +FAILED (failures=1) Failures: 055 Failed 1 of 1 tests
[Qemu-devel] [PATCH 1/2] block: Enable BDRV_O_SNAPSHOT with driver-specific options
In the case of snapshot=on, don't rely on the backing file path in the temporary image any more, but override the backing file with the given set of options. This way, block drivers that don't use a file name can be accessed with snapshot=on, for example: -drive file.driver=nbd,file.host=localhost,snapshot=on Which becomes internally something like: file.filename=/tmp/vl.AWQZCu,backing.file.driver=nbd,backing.file.host=localhost Signed-off-by: Kevin Wolf kw...@redhat.com --- block.c | 49 +++-- 1 file changed, 23 insertions(+), 26 deletions(-) diff --git a/block.c b/block.c index 382ea71..51fcb59 100644 --- a/block.c +++ b/block.c @@ -1052,21 +1052,15 @@ int bdrv_open(BlockDriverState *bs, const char *filename, QDict *options, int64_t total_size; BlockDriver *bdrv_qcow2; QEMUOptionParameter *create_options; -char backing_filename[PATH_MAX]; - -if (qdict_size(options) != 0) { -error_setg(errp, Can't use snapshot=on with driver-specific options); -ret = -EINVAL; -goto fail; -} -assert(filename != NULL); +QDict *snapshot_options; /* if snapshot, we create a temporary backing file and open it instead of opening 'filename' directly */ -/* if there is a backing file, use it */ +/* Get the required size from the image */ bs1 = bdrv_new(); -ret = bdrv_open(bs1, filename, NULL, 0, drv, local_err); +QINCREF(options); +ret = bdrv_open(bs1, filename, options, 0, drv, local_err); if (ret 0) { bdrv_unref(bs1); goto fail; @@ -1075,33 +1069,18 @@ int bdrv_open(BlockDriverState *bs, const char *filename, QDict *options, bdrv_unref(bs1); +/* Create the temporary image */ ret = get_tmp_filename(tmp_filename, sizeof(tmp_filename)); if (ret 0) { error_setg_errno(errp, -ret, Could not get temporary filename); goto fail; } -/* Real path is meaningless for protocols */ -if (path_has_protocol(filename)) { -snprintf(backing_filename, sizeof(backing_filename), - %s, filename); -} else if (!realpath(filename, backing_filename)) { -ret = -errno; -error_setg_errno(errp, errno, Could not resolve path '%s', filename); -goto fail; -} - bdrv_qcow2 = bdrv_find_format(qcow2); create_options = parse_option_parameters(, bdrv_qcow2-create_options, NULL); set_option_parameter_int(create_options, BLOCK_OPT_SIZE, total_size); -set_option_parameter(create_options, BLOCK_OPT_BACKING_FILE, - backing_filename); -if (drv) { -set_option_parameter(create_options, BLOCK_OPT_BACKING_FMT, -drv-format_name); -} ret = bdrv_create(bdrv_qcow2, tmp_filename, create_options, local_err); free_option_parameters(create_options); @@ -1114,6 +1093,24 @@ int bdrv_open(BlockDriverState *bs, const char *filename, QDict *options, goto fail; } +/* Prepare a new options QDict for the temporary file, where user + * options refer to the backing file */ +if (!options) { +options = qdict_new(); +} +if (filename) { +qdict_put(options, file.filename, qstring_from_str(filename)); +} +if (drv) { +qdict_put(options, driver, qstring_from_str(drv-format_name)); +} + +snapshot_options = qdict_new(); +qdict_put(snapshot_options, backing, options); +qdict_flatten(snapshot_options); + +options = snapshot_options; + filename = tmp_filename; drv = bdrv_qcow2; bs-is_temporary = 1; -- 1.8.1.4