[Qemu-devel] [Bug 591666] Re: broken pci_add auto storage
** Attachment added: guest write data into vda https://bugs.launchpad.net/qemu/+bug/591666/+attachment/2194879/+files/2-write2virtDisk.png -- You received this bug notification because you are a member of qemu- devel-ml, which is subscribed to QEMU. https://bugs.launchpad.net/bugs/591666 Title: broken pci_add auto storage Status in QEMU: New Bug description: Doing: (qemu) pci_add auto storage file=/dev/ram0,if=virtio Results in: OK domain 0, bus 0, slot 5, function 0 However no device is actually added to the guest. QEMU: Latest git code (June 9) from git://git.kernel.org/pub/scm/virt/kvm/qemu-kvm.git (seems to be broken from 0.12.1.2) KVM: Compiled from git://git.kernel.org/pub/scm/virt/kvm/kvm-kmod.git checked out (refs/remotes/origin/stable-2.6.32) Both guest and host are Ubuntu 9.10 with 2.6.32 kernel. Guest kernel has ACPI enabled (specifically, the PCI slot detection driver) Guest executed with the following parameters: -boot c -drive file=/home/eranr/kvm_images/ubuntu-9.10-2.6.32-perf.img,if=ide,boot=on -m 4096 -net nic,model=virtio -net tap,ifname=qtap0,script=no -vnc :0 -smp 1,cores=1,threads=0 -monitor tcp:localhost:6001,server,nowait To manage notifications about this bug go to: https://bugs.launchpad.net/qemu/+bug/591666/+subscriptions
[Qemu-devel] [Bug 591666] Re: broken pci_add auto storage
** Attachment added: Host get the expect string helloHpervisor https://bugs.launchpad.net/qemu/+bug/591666/+attachment/2194881/+files/3.getStringOnHypervisor.png -- You received this bug notification because you are a member of qemu- devel-ml, which is subscribed to QEMU. https://bugs.launchpad.net/bugs/591666 Title: broken pci_add auto storage Status in QEMU: New Bug description: Doing: (qemu) pci_add auto storage file=/dev/ram0,if=virtio Results in: OK domain 0, bus 0, slot 5, function 0 However no device is actually added to the guest. QEMU: Latest git code (June 9) from git://git.kernel.org/pub/scm/virt/kvm/qemu-kvm.git (seems to be broken from 0.12.1.2) KVM: Compiled from git://git.kernel.org/pub/scm/virt/kvm/kvm-kmod.git checked out (refs/remotes/origin/stable-2.6.32) Both guest and host are Ubuntu 9.10 with 2.6.32 kernel. Guest kernel has ACPI enabled (specifically, the PCI slot detection driver) Guest executed with the following parameters: -boot c -drive file=/home/eranr/kvm_images/ubuntu-9.10-2.6.32-perf.img,if=ide,boot=on -m 4096 -net nic,model=virtio -net tap,ifname=qtap0,script=no -vnc :0 -smp 1,cores=1,threads=0 -monitor tcp:localhost:6001,server,nowait To manage notifications about this bug go to: https://bugs.launchpad.net/qemu/+bug/591666/+subscriptions
[Qemu-devel] [Bug 591666] Re: broken pci_add auto storage
** Attachment added: The disk device on host including virtio block --vda https://bugs.launchpad.net/qemu/+bug/591666/+attachment/2194878/+files/1-vdaOnGuest.png -- You received this bug notification because you are a member of qemu- devel-ml, which is subscribed to QEMU. https://bugs.launchpad.net/bugs/591666 Title: broken pci_add auto storage Status in QEMU: New Bug description: Doing: (qemu) pci_add auto storage file=/dev/ram0,if=virtio Results in: OK domain 0, bus 0, slot 5, function 0 However no device is actually added to the guest. QEMU: Latest git code (June 9) from git://git.kernel.org/pub/scm/virt/kvm/qemu-kvm.git (seems to be broken from 0.12.1.2) KVM: Compiled from git://git.kernel.org/pub/scm/virt/kvm/kvm-kmod.git checked out (refs/remotes/origin/stable-2.6.32) Both guest and host are Ubuntu 9.10 with 2.6.32 kernel. Guest kernel has ACPI enabled (specifically, the PCI slot detection driver) Guest executed with the following parameters: -boot c -drive file=/home/eranr/kvm_images/ubuntu-9.10-2.6.32-perf.img,if=ide,boot=on -m 4096 -net nic,model=virtio -net tap,ifname=qtap0,script=no -vnc :0 -smp 1,cores=1,threads=0 -monitor tcp:localhost:6001,server,nowait To manage notifications about this bug go to: https://bugs.launchpad.net/qemu/+bug/591666/+subscriptions
[Qemu-devel] [Bug 591666] Re: broken pci_add auto storage
If configure guest kernel correctly, it seems that virtio for block is OK! Could you help or send me your configure file to have a second check Thanks version info === QEMU 0.14.50 monitor host kernel: 2.6.39 guest kernel: 2.6.32 config file for kernel info === See attachment =Doing on qemu monitor QEMU 0.14.50 monitor - type 'help' for more information (qemu) pci_add auto storage file=/dev/ram0,if=virtio OK domain 0, bus 0, slot 3, function 0 =Doing on guest console === 1. ---see the disk on guest root@qemux86-64:~# dmesg | grep 'vda' [ 245.440217] vda: unknown partition table root@qemux86-64:~# fdisk -l Disk /dev/sda: 2147 MB, 2147483648 bytes 255 heads, 63 sectors/track, 261 cylinders Units = cylinders of 16065 * 512 = 8225280 bytes Disk /dev/sda doesn't contain a valid partition table Disk /dev/vda: 16 MB, 16777216 bytes 16 heads, 63 sectors/track, 32 cylinders Units = cylinders of 1008 * 512 = 516096 bytes Disk /dev/vda doesn't contain a valid partition table 2. --- write content to virtio disk root@qemux86-64:~# echo 'helloHypervisor' /dev/vda root@qemux86-64:~# head /dev/vda helloHypervisor =Doing on host console = [root@oc8440477808 linux-2.6.39]# head /dev/ram0 helloHypervisor = conclusion Host get the data which is passed through virtio device on guest. The data is helloHpervisor So, the kernel version 2.6.32 can support virtio block device with correct config, especially the following must be choosen: CONFIG_VIRTIO=y CONFIG_VIRTIO_RING=y CONFIG_VIRTIO_PCI=y CONFIG_VIRTIO_BALLOON=y CONFIG_VIRTIO_BLK=y ** Attachment added: guest kernel configure file https://bugs.launchpad.net/qemu/+bug/591666/+attachment/2194876/+files/guest.config -- You received this bug notification because you are a member of qemu- devel-ml, which is subscribed to QEMU. https://bugs.launchpad.net/bugs/591666 Title: broken pci_add auto storage Status in QEMU: New Bug description: Doing: (qemu) pci_add auto storage file=/dev/ram0,if=virtio Results in: OK domain 0, bus 0, slot 5, function 0 However no device is actually added to the guest. QEMU: Latest git code (June 9) from git://git.kernel.org/pub/scm/virt/kvm/qemu-kvm.git (seems to be broken from 0.12.1.2) KVM: Compiled from git://git.kernel.org/pub/scm/virt/kvm/kvm-kmod.git checked out (refs/remotes/origin/stable-2.6.32) Both guest and host are Ubuntu 9.10 with 2.6.32 kernel. Guest kernel has ACPI enabled (specifically, the PCI slot detection driver) Guest executed with the following parameters: -boot c -drive file=/home/eranr/kvm_images/ubuntu-9.10-2.6.32-perf.img,if=ide,boot=on -m 4096 -net nic,model=virtio -net tap,ifname=qtap0,script=no -vnc :0 -smp 1,cores=1,threads=0 -monitor tcp:localhost:6001,server,nowait To manage notifications about this bug go to: https://bugs.launchpad.net/qemu/+bug/591666/+subscriptions
[Qemu-devel] [Bug 591666] Re: broken pci_add auto storage
** Attachment added: Just in case for use, the config for host https://bugs.launchpad.net/qemu/+bug/591666/+attachment/2194877/+files/h-config.gz -- You received this bug notification because you are a member of qemu- devel-ml, which is subscribed to QEMU. https://bugs.launchpad.net/bugs/591666 Title: broken pci_add auto storage Status in QEMU: New Bug description: Doing: (qemu) pci_add auto storage file=/dev/ram0,if=virtio Results in: OK domain 0, bus 0, slot 5, function 0 However no device is actually added to the guest. QEMU: Latest git code (June 9) from git://git.kernel.org/pub/scm/virt/kvm/qemu-kvm.git (seems to be broken from 0.12.1.2) KVM: Compiled from git://git.kernel.org/pub/scm/virt/kvm/kvm-kmod.git checked out (refs/remotes/origin/stable-2.6.32) Both guest and host are Ubuntu 9.10 with 2.6.32 kernel. Guest kernel has ACPI enabled (specifically, the PCI slot detection driver) Guest executed with the following parameters: -boot c -drive file=/home/eranr/kvm_images/ubuntu-9.10-2.6.32-perf.img,if=ide,boot=on -m 4096 -net nic,model=virtio -net tap,ifname=qtap0,script=no -vnc :0 -smp 1,cores=1,threads=0 -monitor tcp:localhost:6001,server,nowait To manage notifications about this bug go to: https://bugs.launchpad.net/qemu/+bug/591666/+subscriptions
Re: [Qemu-devel] migration: new sections and backward compatibility.
Hi, We don't have a hard policy about not merging devices that don't support migration. Since migration must be supported forever, I'd rather see a device get some solid testing before it starts doing live migration. That said, we should probably do this consciously by explicitly marking the device non-migrateable. Can't we just implicitly fail migration whenever there's a device in the tree that doesn't have VMSTATE? There are cases where the device doesn't need to save state, so that alone doesn't cut it. cheers, Gerd
Re: [Qemu-devel] migration: new sections and backward compatibility.
On 07/06/11 19:13, Anthony Liguori wrote: On 07/06/2011 11:04 AM, Gerd Hoffmann wrote: Hi folks, We'll need to figure a sane way to handle migration to older versions with new sections, i.e. devices which used to not save state before do now. We already have one case in tree: usb. qemu 0.14 saves state for usb-hid devices and the usb-hub, whereas qemu 0.13 and older don't. You can't migrate a vm with a usb-tablet from 0.14 to 0.13 because of that even if you use -M pc-0.13. Because if you did migrate, you would actively break the guest during migration. So why is this a problem? Well, in case of usb hid devices breaking the guest isn't that a big issue for at least some guests because they manage to reset the device and continue nevertheless ... I think this is a case-by-case thing. In some cases we want break migration because critical state is missing. In other cases we might want allow it nevertheless. cheers, Gerd
Re: [Qemu-devel] migration: new sections and backward compatibility.
On 07/07/2011 10:14 AM, Gerd Hoffmann wrote: Can't we just implicitly fail migration whenever there's a device in the tree that doesn't have VMSTATE? There are cases where the device doesn't need to save state, so that alone doesn't cut it. It should then say so by having an empty VMSTATE descriptor. -- error compiling committee.c: too many arguments to function
Re: [Qemu-devel] [PATCH] qxl: add defines from latest spice-protocol.
On 07/06/11 14:19, Alon Levy wrote: From: Gerd Hoffmannkra...@redhat.com Allows to build with older spice-protocol versions. Given that we can't get away with changing the protocol only but require a new libspices-server for the new features this is pointless ... cheers, Gerd
Re: [Qemu-devel] [PATCH] qxl: move qemu_spice_add_memslot call out of qxl_add_memslot
Hi, -static void qxl_add_memslot(PCIQXLDevice *d, uint32_t slot_id, uint64_t delta) +static void qxl_add_memslot(PCIQXLDevice *d, uint32_t slot_id, uint64_t delta, +QXLDevMemSlot *memslot) -qxl_add_memslot(d, val, 0); +qxl_add_memslot(d, val, 0,memslot); +qemu_spice_add_memslot(d-ssd,memslot); Do we still need this and the simliar patches? Given that we don't call qemu_spice_add_memslot() from another thread any more we could just pass in a async flag to qxl_add_memslot(). cheers, Gerd
Re: [Qemu-devel] [PATCH] spice: lock spice worker calls
On 07/06/11 14:19, Alon Levy wrote: From: Gerd Hoffmannkra...@redhat.com ... so we can call them from a thread. Still needed? I don't think so. cheers, Gerd
Re: [Qemu-devel] [PATCH] qxl: add defines from latest spice-protocol.
On Thu, Jul 07, 2011 at 09:33:05AM +0200, Gerd Hoffmann wrote: On 07/06/11 14:19, Alon Levy wrote: From: Gerd Hoffmannkra...@redhat.com Allows to build with older spice-protocol versions. Given that we can't get away with changing the protocol only but require a new libspices-server for the new features this is pointless ... right. wasn't thinking. cheers, Gerd
Re: [Qemu-devel] [PATCH] qxl: async I/O
Hi, +void qxl_spice_update_area_async(PCIQXLDevice *qxl, uint32_t surface_id, + struct QXLRect *area, struct QXLRect *dirty_rects, + uint32_t num_dirty_rects, uint32_t clear_dirty_region, + int async) +{ +qemu_mutex_lock(qxl-ssd.wlock); +if (async) { +qxl-ssd.worker-update_area_async(qxl-ssd.worker, surface_id, area, dirty_rects, + num_dirty_rects, clear_dirty_region); +} else { +qxl-ssd.worker-update_area(qxl-ssd.worker, surface_id, area, dirty_rects, + num_dirty_rects, clear_dirty_region); +} +qemu_mutex_unlock(qxl-ssd.wlock); +} We need a plan to handle backward compatibility here. Older libspice-server versions don't have the update_area_async op. Option one is to just not support async mode with older libraries. Option two is to handle the request syncronously even though the guest has asked for async. I'd tend to pick option one, that makes things easier with S3 support because we just can't do that in any way with an older libspice-server. switch (io_port) { +case QXL_IO_UPDATE_AREA_ASYNC: +case QXL_IO_NOTIFY_OOM_ASYNC: +case QXL_IO_MEMSLOT_ADD_ASYNC: +case QXL_IO_CREATE_PRIMARY_ASYNC: +case QXL_IO_DESTROY_PRIMARY_ASYNC: +case QXL_IO_DESTROY_SURFACE_ASYNC: +case QXL_IO_DESTROY_ALL_SURFACES_ASYNC: +async = 1; +if (d-current_async != QXL_UNDEFINED_IO) { +qxl_guest_bug(d, %d async started before last (%d) complete\n, +io_port, d-current_async); Better return here, ignoring the invalid request? cheers, Gerd
Re: [Qemu-devel] [PATCH] spice: lock spice worker calls
On Thu, Jul 07, 2011 at 09:40:15AM +0200, Gerd Hoffmann wrote: On 07/06/11 14:19, Alon Levy wrote: From: Gerd Hoffmannkra...@redhat.com ... so we can call them from a thread. Still needed? I don't think so. Will drop (I wasn't sure we won't want this at a distant future, so I kept it). cheers, Gerd
Re: [Qemu-devel] [PATCH v2] XBRLE page delta compression for live migration of large memory apps
On Wed, Jul 06, 2011 at 02:01:58PM +0200, Shribman, Aidan wrote: XBRLE does not suite all scenarios but has been proven highly beneficial in for VMs running payloads such as: SAP ERP systems; VLC transcoding; LMbench memory write benchmarks. Another way of looking at this patch is as a profiling tool for identifying workloads with poor TLB and cache behavior. The workloads that benefit from this patch are dirtying memory in a sparse fashion, touching many pages but making only small changes. These workloads are using data structures and algorithms that are simply not TLB/cache-efficient. Instead of spending effort in live migration compensating for this poor workload behavior, why not fix the workload? The benefits are much greater: poor TLB/cache usage affects the workload all the time, not just during live migration and not just under virtualization. By fixing the workload you will also get faster live migration. That said, if we can improve live migration then this is a good thing. The challenge is that this optimization is speculative. You need to do a lot of work up-front: copying all pages through the cache and hoping their xor/rle representation will be 1/3 TARGET_PAGE_SIZE. If there is a cache miss or the xor/rle representation is not small enough then it's back to square one. Any thoughts on reducing the overhead and making xbrle on by default? Work is based on research results published VEE 2011: Evaluation of Delta Compression Techniques for Efficient Live Migration of Large Virtual Machines by Benoit, Svard, Tordsson and Elmroth. I will read your paper. Did you try unconditionally applying a cheap compression algorithm like the one Google recently published? That way you just compress everything and don't need to keep the cache around: http://code.google.com/p/snappy/ http://www.hypertable.org/doxygen/bmz_8h.html +static int save_xbrle_page(QEMUFile *f, uint8_t *current_data, +ram_addr_t current_addr, RAMBlock *block, ram_addr_t offset, int cont) +{ +int cache_location = -1, slot = -1, encoded_len = 0, bytes_sent = 0; +XBRLEHeader hdr = {0}; +CacheItem *it; +uint8_t *xor_buf = NULL, *xbrle_buf = NULL; + +/* get location */ +slot = cache_is_cached(current_addr); +if (slot == -1) { +acct_info.xbrle_cache_miss++; +goto done; +} +cache_location = cache_get_cache_pos(current_addr); + +/* abort if page changed too much */ +it = cache_item_get(cache_location, slot); + +/* XOR encoding */ +xor_buf = (uint8_t *) qemu_mallocz(TARGET_PAGE_SIZE); Zeroing unnecessary here. +xor_encode(xor_buf, it-it_data, current_data); + +/* XBRLE (XOR+RLE) encoding (if we can ensure a 1/3 ratio) */ +xbrle_buf = (uint8_t *) qemu_mallocz(TARGET_PAGE_SIZE); Why TARGET_PAGE_SIZE when the actual size is TARGET_PAGE_SIZE/3? Zeroing unnecessary here. +encoded_len = rle_encode(xor_buf, TARGET_PAGE_SIZE, xbrle_buf, +TARGET_PAGE_SIZE/3); + +if (encoded_len 0) { +DPRINTF(XBRLE encoding oeverflow - sending uncompressed\n); s/oeverflow/overflow/ +acct_info.xbrle_overflow++; +goto done; +} + +hdr.xh_len = encoded_len; +hdr.xh_flags |= ENCODING_FLAG_XBRLE; + +/* Send XBRLE compressed page */ +save_block_hdr(f, block, offset, cont, RAM_SAVE_FLAG_XBRLE); +qemu_put_buffer(f, (uint8_t *) hdr, sizeof(hdr)); +qemu_put_buffer(f, xbrle_buf, encoded_len); +acct_info.xbrle_pages++; +bytes_sent = encoded_len + sizeof(hdr); +acct_info.xbrle_bytes += bytes_sent; + +done: +qemu_free(xor_buf); +qemu_free(xbrle_buf); +return bytes_sent; +} static int is_dup_page(uint8_t *page, uint8_t ch) { @@ -107,7 +486,7 @@ static int is_dup_page(uint8_t *page, uint8_t ch) static RAMBlock *last_block; static ram_addr_t last_offset; -static int ram_save_block(QEMUFile *f) +static int ram_save_block(QEMUFile *f, int stage) { RAMBlock *block = last_block; ram_addr_t offset = last_offset; @@ -128,28 +507,27 @@ static int ram_save_block(QEMUFile *f) current_addr + TARGET_PAGE_SIZE, MIGRATION_DIRTY_FLAG); -p = block-host + offset; +p = qemu_mallocz(TARGET_PAGE_SIZE); Where is p freed when use_xbrle is off? You should not introduce overhead in the case where use_xbrle is off. Please make sure the malloc/memcpy only happens if the page is added to the cache. +static int load_xbrle(QEMUFile *f, ram_addr_t addr, void *host) +{ +int ret, rc = -1; +uint8_t *prev_page, *xor_buf, *xbrle_buf; +XBRLEHeader hdr = {0}; + +/* extract RLE header */ +qemu_get_buffer(f, (uint8_t *) hdr, sizeof(hdr)); +if (!(hdr.xh_flags ENCODING_FLAG_XBRLE)) { +fprintf(stderr, Failed to load XBRLE page - wrong compression!\n); +goto done;
Re: [Qemu-devel] SSH console for qemu
Seems no, I think, that the best way is running some kind of ssh daemon, that connects to console (/dev/vcsa1 for example), that listen on port and send to output console events on boot, and allow to work with server with simple ssh client. Also important feature will be saving history of output. On 6 July 2011 19:27, Stefan Hajnoczi stefa...@gmail.com wrote: On Wed, Jul 6, 2011 at 3:08 PM, Nikita A Menkovich menkov...@gmail.com wrote: I'm using qemu with libvirt and I want to create SSH emergency console to linux/unix guests, same way as it is realized in qemu VNC. Maybe someone could help me to determine a place to dive in this question. I think the best way to make it - extend qemu API. But if this could be made with libvirt - this will be also fine. Serial console and the virsh console command? Stefan -- Nikita A Menkovich http://libc6.org/ JID: menkov...@gmail.com Tel: +7 (921) 423-96-48
Re: [Qemu-devel] [PATCH] qxl: move qemu_spice_add_memslot call out of qxl_add_memslot
On Thu, Jul 07, 2011 at 09:39:34AM +0200, Gerd Hoffmann wrote: Hi, -static void qxl_add_memslot(PCIQXLDevice *d, uint32_t slot_id, uint64_t delta) +static void qxl_add_memslot(PCIQXLDevice *d, uint32_t slot_id, uint64_t delta, +QXLDevMemSlot *memslot) -qxl_add_memslot(d, val, 0); +qxl_add_memslot(d, val, 0,memslot); +qemu_spice_add_memslot(d-ssd,memslot); Do we still need this and the simliar patches? Given that we don't call qemu_spice_add_memslot() from another thread any more we could just pass in a async flag to qxl_add_memslot(). I will. The most changes needed are to split the part after calling worker to a complete call, I'm storing the io data inside PCIQXLDevice. cheers, Gerd
Re: [Qemu-devel] migration: new sections and backward compatibility.
Anthony Liguori anth...@codemonkey.ws writes: On 07/06/2011 11:04 AM, Gerd Hoffmann wrote: Hi folks, We'll need to figure a sane way to handle migration to older versions with new sections, i.e. devices which used to not save state before do now. We already have one case in tree: usb. qemu 0.14 saves state for usb-hid devices and the usb-hub, whereas qemu 0.13 and older don't. You can't migrate a vm with a usb-tablet from 0.14 to 0.13 because of that even if you use -M pc-0.13. Because if you did migrate, you would actively break the guest during migration. So why is this a problem? This comes up a lot. We shouldn't enable migration if we know the guest is going to break during migration. That's a feature, not a bug. Not so fast :) I agree that throwing away unrecognized migration data is unsafe, and should not be done. Now let me present my little problem. I'm working on making migration preserve tray status: open/closed, locked/unlocked. For ide-cd, I can stick a subsection ide_drive/tray_state into section ide_drive. Needed only if the tray is open or locked. This gives users a chance to migrate to older versions, and is perfectly safe. scsi-cd doesn't have a section, yet. What now?
Re: [Qemu-devel] migration: new sections and backward compatibility.
On 07.07.2011, at 11:23, Markus Armbruster wrote: Anthony Liguori anth...@codemonkey.ws writes: On 07/06/2011 11:04 AM, Gerd Hoffmann wrote: Hi folks, We'll need to figure a sane way to handle migration to older versions with new sections, i.e. devices which used to not save state before do now. We already have one case in tree: usb. qemu 0.14 saves state for usb-hid devices and the usb-hub, whereas qemu 0.13 and older don't. You can't migrate a vm with a usb-tablet from 0.14 to 0.13 because of that even if you use -M pc-0.13. Because if you did migrate, you would actively break the guest during migration. So why is this a problem? This comes up a lot. We shouldn't enable migration if we know the guest is going to break during migration. That's a feature, not a bug. Not so fast :) I agree that throwing away unrecognized migration data is unsafe, and should not be done. Now let me present my little problem. I'm working on making migration preserve tray status: open/closed, locked/unlocked. For ide-cd, I can stick a subsection ide_drive/tray_state into section ide_drive. Needed only if the tray is open or locked. This gives users a chance to migrate to older versions, and is perfectly safe. scsi-cd doesn't have a section, yet. What now? I guess the obvious answer would be There shouldn't be devices that don't have a section :). Not sure how to not break old -M with this though :(. I'd guess the best would be to have a special VMSTATE that means broken old version doesn't send a section which we can set for special -M? That would of course not help with RHEL :). Alex
Re: [Qemu-devel] [SeaBIOS] [PATCH V5 0/9] Add TPM support to SeaBIOS
On 07/06/2011 06:58 PM, Kevin O'Connor wrote: On Wed, Jul 06, 2011 at 12:31:58PM -0400, Stefan Berger wrote: The following set of patches add TPM and Trusted Computing support to SeaBIOS. In particular the patches add: - a TPM driver for the Qemu's TPM TIS emulation (not yet in Qemu git) - ACPI support for the TPM device (SSDT table) - ACPI support for measurement logging (TCPA table) - Support for initialzation of the TPM - Support for the TCG BIOS extensions (1ah handler [ah = 0xbb]) (used by trusted grub; http://trousers.sourceforge.net/grub.html) - Static Root of Trusted for Measurement (SRTM) support - Support for S3 resume (sends command to TPM upon resume) - TPM-specific menu for controlling aspects of the TPM - [An optional test suite for the TIS interface] All implementations necessarily follow specifications. ... Thanks Stefan. Where does this stand with respect to QEmu integration? Qemu integration is at least 'working' for me - it's just lacking review/attention on the Qemu mailing list. BTW, I don't think patch 7 or 9 really make sense to integrate in the official version of SeaBIOS. Also, in patch 8, I'd prefer to see all new fw_cfg entries use the romfile mechanism. Patch 7 is the menu. This patch is needed in 'some form' since in some cases, like after giving up ownership of the TPM, the TPM becomes disabled and deactivated and one has to interact with the BIOS to activate and enable it again. Other scenarios include someone who has forgotten the owner password for the TPM and now has to go through the BIOS to give up ownership of it -- that's the only way one can do this then. I'll have a look at the 'romfile' mechanism for patch 8. I only post patch 9 for someone who is interested to be able to run the tests. Since the 128kb are slowly filling up, it's not going to be compilable with it for much longer and I don't expect it to go into the repo. Thanks for the feedback. Stefan -Kevin
Re: [Qemu-devel] [PATCH] Add tee option to qemu char device
On Thu, 7 Jul 2011, Chunyan Liu wrote: In previous thread Support logging xen-guest console, it's considered that adding a tee option to char layer is a more generic way and makes more sense. http://lists.nongnu.org/archive/html/qemu-devel/2011-06/msg03011.html Following is an implementation of tee option to char device. It could be used as follows: -chardev pty,id=id,path=path,[mux=on|off],[tee=filepath] -serial tee:filepath,pty With tee option, pty output would be duplicated to filepath. I've ported this patch to qemu-xen and tested with xen guests already. But I'm not very clear how to test the qemu binary directly. Any info? Configure your Xen HVM guest to use the serial. Compile Qemu as emulator: ./configure --disable-xen --target-list=x86_64-softmmu then use qemu directly to boot your guest: ./qemu-system-x86_64 -hda /path/to/file -serial tree:/path/to/log,pty you can connect to the pty using a program like picocom: picocom -b 115200 /dev/pts/$NUM
Re: [Qemu-devel] [PATCH v2 2/6] Add copy and constant propagation.
On Fri, 10 Jun 2011, Richard Henderson wrote: +/* Do copy propagation */ +if (!(def-flags (TCG_OPF_CALL_CLOBBER | TCG_OPF_SIDE_EFFECTS))) { Why are you suppressing copy propagation in this way? I see no reason for it. This was suggested by Aurelien Jarno. I do not know how safe it is to propagate copies through such operations so I decided to be conservative. case INDEX_op_brcond_i64: #endif +memset(temps, 0, nb_temps * sizeof(struct tcg_temp_info)); Perhaps to pedantic, but we can do better in extended basic blocks. A full flush of all temps is only needed at labels. Not much better unfortunately. Globals got spilled at basic block end, temps just die. The only things we can keep are locals but I have not seen much of them in the intermediate representation. Kirill Batuzov
[Qemu-devel] [PATCH v3 0/6] Implement constant folding and copy propagation in TCG
This series implements some basic machine-independent optimizations. They simplify code and allow liveness analysis do it's work better. Suppose we have following ARM code: movwr12, #0xb6db movtr12, #0xdb6d In TCG before optimizations we'll have: movi_i32 tmp8,$0xb6db mov_i32 r12,tmp8 mov_i32 tmp8,r12 ext16u_i32 tmp8,tmp8 movi_i32 tmp9,$0xdb6d or_i32 tmp8,tmp8,tmp9 mov_i32 r12,tmp8 And after optimizations we'll have this: movi_i32 r12,$0xdb6db6db Here are performance evaluation results on SPEC CPU2000 integer tests in user-mode emulation on x86_64 host. There were 5 runs of each test on reference data set. The tables below show runtime in seconds for all these runs. ARM guest without optimizations: Test name #1 #2 #3 #4 #5Median 164.gzip1408.891 1402.323 1407.623 1404.955 1405.396 1405.396 175.vpr 1245.31 1248.758 1247.936 1248.534 1247.534 1247.936 176.gcc 912.561 809.481 847.057 912.636 912.544 912.544 181.mcf 198.384 197.841 199.127 197.976 197.29 197.976 186.crafty 1545.881 1546.051 1546.002 1545.927 1545.945 1545.945 197.parser 3779.954 3779.878 3779.79 3779.94 3779.88 3779.88 252.eon 2563.168 2776.152 2776.395 2776.577 2776.202 2776.202 253.perlbmk 2591.781 2504.078 2507.07 2591.337 2463.401 2507.07 256.bzip2 1306.197 1304.639 1184.853 1305.141 1305.606 1305.141 300.twolf 2918.984 2918.926 2918.93 2918.97 2918.914 2918.93 ARM guest with optimizations: Test name #1 #2 #3 #4 #5MedianGain 164.gzip1401.198 1376.337 1401.117 1401.23 1401.246 1401.198 0.30% 175.vpr 1247.964 1151.468 1247.76 1154.419 1242.017 1242.017 0.47% 176.gcc 896.882 918.546 918.297 851.465 918.39 918.297 -0.63% 181.mcf 198.19 197.399 198.421 198.663 198.312 198.312 -0.17% 186.crafty 1520.425 1520.362 1520.477 1520.445 1520.957 1520.445 1.65% 197.parser 3770.943 3770.927 3770.578 3771.048 3770.904 3770.927 0.24% 252.eon 2752.371 2752.111 2752.005 2752.214 2752.109 2752.111 0.87% 253.perlbmk 2577.462 2578.588 2493.567 2578.571 2578.318 2578.318 -2.84% 256.bzip2 1296.198 1271.128 1296.044 1296.321 1296.147 1296.147 0.69% 300.twolf 2888.984 2889.023 2889.225 2889.039 2889.05 2889.039 1.02% x86_64 guest without optimizations: Test name #1 #2 #3 #4 #5Median 164.gzip 857.654 857.646 857.678 798.119 857.675 857.654 175.vpr 959.265 959.207 959.185 959.461 959.332 959.265 176.gcc 625.722 637.257 646.638 646.614 646.56 646.56 181.mcf 221.666 220.194 220.079 219.868 221.5220.194 186.crafty 1129.531 1129.739 1129.573 1129.588 1129.624 1129.588 197.parser 1809.517 1809.516 1809.386 1809.477 1809.427 1809.477 253.perlbmk 1774.944 1776.046 1769.865 1774.052 1775.236 1774.944 254.gap 1061.033 1061.158 1061.064 1061.047 1061.01 1061.047 255.vortex 1871.261 1914.144 1914.057 1914.086 1914.127 1914.086 256.bzip2918.916 1011.828 1011.819 1012.11 1011.932 1011.828 300.twolf 1332.797 1330.56 1330.687 1330.917 1330.602 1330.687 x86_64 guest with optimizations: Test name #1 #2 #3 #4 #5MedianGain 164.gzip 806.198 854.159 854.184 854.168 854.187 854.168 0.41% 175.vpr 955.905 950.86 955.876 876.397 955.957 955.876 1.82% 176.gcc 641.663 640.189 641.57 641.552 641.514 641.552 0.03% 181.mcf 217.619 218.627 218.699 217.977 216.955 217.977 1.18% 186.crafty 1123.909 1123.852 1123.917 1123.781 1123.805 1123.852 0.51% 197.parser 1813.94 1814.643 1815.286 1814.445 1813.72 1814.445 -0.27% 253.perlbmk 1791.536 1795.642 1793.0 1797.486 1791.401 1793.0-1.02% 254.gap 1070.605 1070.216 1070.637 1070.168 1070.491 1070.491 -0.89% 255.vortex 1918.764 1918.573 1917.411 1918.287 1918.735 1918.573 -0.23% 256.bzip2 1017.179 1017.083 1017.283 1016.913 1017.189 1017.179 -0.53% 300.twolf 1321.072 1321.109 1321.019 1321.072 1321.004 1321.072 0.72% ARM guests for 254.gap and 255.vortex and x86_64 guest for 252.eon does not work under QEMU for some unrelated reason. Changes: v1 - v2 - State and Vals arrays merged to an array of structures. - Added reference counting of temp's copies. This helps to reset temp's state faster in most cases. - Do not make copy propagation through operations with TCG_OPF_CALL_CLOBBER or TCG_OPF_SIDE_EFFECTS flag. - Split some expression simplifications into independent switch. - Let compiler handle signed shifts and sign/zero extends in it's implementation defined way. v2 - v3 - Elements of equiv class are placed in a double-linked circular list so it's easier to choose a new representative. - CASE_OP_32_64 macro is used to reduce amount of ifdefdsi. Checkpatch is not happy about this change but I do not think spaces would be appropriate here. - Some constraints during copy propagation are relaxed. - Functions
[Qemu-devel] [PATCH v3 6/6] Do constant folding for unary operations.
Perform constant folding for NOT and EXT{8,16,32}{S,U} operations. Signed-off-by: Kirill Batuzov batuz...@ispras.ru --- tcg/optimize.c | 59 1 files changed, 59 insertions(+), 0 deletions(-) diff --git a/tcg/optimize.c b/tcg/optimize.c index a1bb287..a324e98 100644 --- a/tcg/optimize.c +++ b/tcg/optimize.c @@ -107,6 +107,11 @@ static int op_bits(int op) case INDEX_op_sar_i32: case INDEX_op_rotl_i32: case INDEX_op_rotr_i32: +case INDEX_op_not_i32: +case INDEX_op_ext8s_i32: +case INDEX_op_ext16s_i32: +case INDEX_op_ext8u_i32: +case INDEX_op_ext16u_i32: return 32; #if TCG_TARGET_REG_BITS == 64 case INDEX_op_mov_i64: @@ -121,6 +126,13 @@ static int op_bits(int op) case INDEX_op_sar_i64: case INDEX_op_rotl_i64: case INDEX_op_rotr_i64: +case INDEX_op_not_i64: +case INDEX_op_ext8s_i64: +case INDEX_op_ext16s_i64: +case INDEX_op_ext32s_i64: +case INDEX_op_ext8u_i64: +case INDEX_op_ext16u_i64: +case INDEX_op_ext32u_i64: return 64; #endif default: @@ -267,6 +279,29 @@ static TCGArg do_constant_folding_2(int op, TCGArg x, TCGArg y) return x; #endif +CASE_OP_32_64(not): +return ~x; + +CASE_OP_32_64(ext8s): +return (int8_t)x; + +CASE_OP_32_64(ext16s): +return (int16_t)x; + +CASE_OP_32_64(ext8u): +return (uint8_t)x; + +CASE_OP_32_64(ext16u): +return (uint16_t)x; + +#if TCG_TARGET_REG_BITS == 64 +case INDEX_op_ext32s_i64: +return (int32_t)x; + +case INDEX_op_ext32u_i64: +return (uint32_t)x; +#endif + default: fprintf(stderr, Unrecognized operation %d in do_constant_folding.\n, op); @@ -424,6 +459,30 @@ static TCGArg *tcg_constant_folding(TCGContext *s, uint16_t *tcg_opc_ptr, gen_args += 2; args += 2; break; +CASE_OP_32_64(not): +CASE_OP_32_64(ext8s): +CASE_OP_32_64(ext16s): +CASE_OP_32_64(ext8u): +CASE_OP_32_64(ext16u): +#if TCG_TARGET_REG_BITS == 64 +case INDEX_op_ext32s_i64: +case INDEX_op_ext32u_i64: +#endif +if (temps[args[1]].state == TCG_TEMP_CONST) { +gen_opc_buf[op_index] = op_to_movi(op); +tmp = do_constant_folding(op, temps[args[1]].val, 0); +tcg_opt_gen_movi(gen_args, args[0], tmp, nb_temps, nb_globals); +gen_args += 2; +args += 2; +break; +} else { +reset_temp(args[0], nb_temps, nb_globals); +gen_args[0] = args[0]; +gen_args[1] = args[1]; +gen_args += 2; +args += 2; +break; +} CASE_OP_32_64(add): CASE_OP_32_64(sub): CASE_OP_32_64(mul): -- 1.7.4.1
[Qemu-devel] [PATCH v3 2/6] Add copy and constant propagation.
Make tcg_constant_folding do copy and constant propagation. It is a preparational work before actual constant folding. Signed-off-by: Kirill Batuzov batuz...@ispras.ru --- tcg/optimize.c | 182 +++- 1 files changed, 180 insertions(+), 2 deletions(-) diff --git a/tcg/optimize.c b/tcg/optimize.c index c7c7da9..f8afe71 100644 --- a/tcg/optimize.c +++ b/tcg/optimize.c @@ -40,24 +40,196 @@ glue(glue(case INDEX_op_, x), _i32) #endif +typedef enum { +TCG_TEMP_UNDEF = 0, +TCG_TEMP_CONST, +TCG_TEMP_COPY, +TCG_TEMP_HAS_COPY, +TCG_TEMP_ANY +} tcg_temp_state; + +struct tcg_temp_info { +tcg_temp_state state; +uint16_t prev_copy; +uint16_t next_copy; +tcg_target_ulong val; +}; + +static struct tcg_temp_info temps[TCG_MAX_TEMPS]; + +/* Reset TEMP's state to TCG_TEMP_ANY. If TEMP was a representative of some + class of equivalent temp's, a new representative should be chosen in this + class. */ +static void reset_temp(TCGArg temp, int nb_temps, int nb_globals) +{ +int i; +TCGArg new_base = (TCGArg)-1; +if (temps[temp].state == TCG_TEMP_HAS_COPY) { +for (i = temps[temp].next_copy; i != temp; i = temps[i].next_copy) { +if (i = nb_globals) { +temps[i].state = TCG_TEMP_HAS_COPY; +new_base = i; +break; +} +} +for (i = temps[temp].next_copy; i != temp; i = temps[i].next_copy) { +if (new_base == (TCGArg)-1) { +temps[i].state = TCG_TEMP_ANY; +} else { +temps[i].val = new_base; +} +} +temps[temps[temp].next_copy].prev_copy = temps[temp].prev_copy; +temps[temps[temp].prev_copy].next_copy = temps[temp].next_copy; +} else if (temps[temp].state == TCG_TEMP_COPY) { +temps[temps[temp].next_copy].prev_copy = temps[temp].prev_copy; +temps[temps[temp].prev_copy].next_copy = temps[temp].next_copy; +new_base = temps[temp].val; +} +temps[temp].state = TCG_TEMP_ANY; +if (new_base != (TCGArg)-1 temps[new_base].next_copy == new_base) { +temps[new_base].state = TCG_TEMP_ANY; +} +} + +static int op_bits(int op) +{ +switch (op) { +case INDEX_op_mov_i32: +return 32; +#if TCG_TARGET_REG_BITS == 64 +case INDEX_op_mov_i64: +return 64; +#endif +default: +fprintf(stderr, Unrecognized operation %d in op_bits.\n, op); +tcg_abort(); +} +} + +static int op_to_movi(int op) +{ +switch (op_bits(op)) { +case 32: +return INDEX_op_movi_i32; +#if TCG_TARGET_REG_BITS == 64 +case 64: +return INDEX_op_movi_i64; +#endif +default: +fprintf(stderr, op_to_movi: unexpected return value of +function op_bits.\n); +tcg_abort(); +} +} + +static void tcg_opt_gen_mov(TCGArg *gen_args, TCGArg dst, TCGArg src, +int nb_temps, int nb_globals) +{ +reset_temp(dst, nb_temps, nb_globals); +assert(temps[src].state != TCG_TEMP_COPY); +if (src = nb_globals) { +assert(temps[src].state != TCG_TEMP_CONST); +if (temps[src].state != TCG_TEMP_HAS_COPY) { +temps[src].state = TCG_TEMP_HAS_COPY; +temps[src].next_copy = src; +temps[src].prev_copy = src; +} +temps[dst].state = TCG_TEMP_COPY; +temps[dst].val = src; +temps[dst].next_copy = temps[src].next_copy; +temps[dst].prev_copy = src; +temps[temps[dst].next_copy].prev_copy = dst; +temps[src].next_copy = dst; +} +gen_args[0] = dst; +gen_args[1] = src; +} + +static void tcg_opt_gen_movi(TCGArg *gen_args, TCGArg dst, TCGArg val, + int nb_temps, int nb_globals) +{ +reset_temp(dst, nb_temps, nb_globals); +temps[dst].state = TCG_TEMP_CONST; +temps[dst].val = val; +gen_args[0] = dst; +gen_args[1] = val; +} + +/* Propagate constants and copies, fold constant expressions. */ static TCGArg *tcg_constant_folding(TCGContext *s, uint16_t *tcg_opc_ptr, TCGArg *args, TCGOpDef *tcg_op_defs) { -int i, nb_ops, op_index, op, nb_temps, nb_globals; +int i, nb_ops, op_index, op, nb_temps, nb_globals, nb_call_args; const TCGOpDef *def; TCGArg *gen_args; +/* Array VALS has an element for each temp. + If this temp holds a constant then its value is kept in VALS' element. + If this temp is a copy of other ones then this equivalence class' + representative is kept in VALS' element. + If this temp is neither copy nor constant then corresponding VALS' + element is unused. */ nb_temps = s-nb_temps; nb_globals = s-nb_globals; +memset(temps, 0, nb_temps * sizeof(struct tcg_temp_info)); nb_ops =
[Qemu-devel] [PATCH v3 4/6] Do constant folding for boolean operations.
Perform constant folding for AND, OR, XOR operations. Signed-off-by: Kirill Batuzov batuz...@ispras.ru --- tcg/optimize.c | 37 + 1 files changed, 37 insertions(+), 0 deletions(-) diff --git a/tcg/optimize.c b/tcg/optimize.c index 42a1bda..c469952 100644 --- a/tcg/optimize.c +++ b/tcg/optimize.c @@ -99,12 +99,18 @@ static int op_bits(int op) case INDEX_op_add_i32: case INDEX_op_sub_i32: case INDEX_op_mul_i32: +case INDEX_op_and_i32: +case INDEX_op_or_i32: +case INDEX_op_xor_i32: return 32; #if TCG_TARGET_REG_BITS == 64 case INDEX_op_mov_i64: case INDEX_op_add_i64: case INDEX_op_sub_i64: case INDEX_op_mul_i64: +case INDEX_op_and_i64: +case INDEX_op_or_i64: +case INDEX_op_xor_i64: return 64; #endif default: @@ -190,6 +196,15 @@ static TCGArg do_constant_folding_2(int op, TCGArg x, TCGArg y) CASE_OP_32_64(mul): return x * y; +CASE_OP_32_64(and): +return x y; + +CASE_OP_32_64(or): +return x | y; + +CASE_OP_32_64(xor): +return x ^ y; + default: fprintf(stderr, Unrecognized operation %d in do_constant_folding.\n, op); @@ -246,6 +261,9 @@ static TCGArg *tcg_constant_folding(TCGContext *s, uint16_t *tcg_opc_ptr, switch (op) { CASE_OP_32_64(add): CASE_OP_32_64(mul): +CASE_OP_32_64(and): +CASE_OP_32_64(or): +CASE_OP_32_64(xor): if (temps[args[1]].state == TCG_TEMP_CONST) { tmp = args[1]; args[1] = args[2]; @@ -291,6 +309,22 @@ static TCGArg *tcg_constant_folding(TCGContext *s, uint16_t *tcg_opc_ptr, continue; } break; +CASE_OP_32_64(or): +CASE_OP_32_64(and): +if (args[1] == args[2]) { +if (args[1] == args[0]) { +args += 3; +gen_opc_buf[op_index] = INDEX_op_nop; +} else { +gen_opc_buf[op_index] = op_to_mov(op); +tcg_opt_gen_mov(gen_args, args[0], args[1], nb_temps, +nb_globals); +gen_args += 2; +args += 3; +} +continue; +} +break; } /* Propagate constants through copy operations and do constant @@ -326,6 +360,9 @@ static TCGArg *tcg_constant_folding(TCGContext *s, uint16_t *tcg_opc_ptr, CASE_OP_32_64(add): CASE_OP_32_64(sub): CASE_OP_32_64(mul): +CASE_OP_32_64(or): +CASE_OP_32_64(and): +CASE_OP_32_64(xor): if (temps[args[1]].state == TCG_TEMP_CONST temps[args[2]].state == TCG_TEMP_CONST) { gen_opc_buf[op_index] = op_to_movi(op); -- 1.7.4.1
[Qemu-devel] [PATCH v3 3/6] Do constant folding for basic arithmetic operations.
Perform actual constant folding for ADD, SUB and MUL operations. Signed-off-by: Kirill Batuzov batuz...@ispras.ru --- tcg/optimize.c | 125 1 files changed, 125 insertions(+), 0 deletions(-) diff --git a/tcg/optimize.c b/tcg/optimize.c index f8afe71..42a1bda 100644 --- a/tcg/optimize.c +++ b/tcg/optimize.c @@ -96,9 +96,15 @@ static int op_bits(int op) { switch (op) { case INDEX_op_mov_i32: +case INDEX_op_add_i32: +case INDEX_op_sub_i32: +case INDEX_op_mul_i32: return 32; #if TCG_TARGET_REG_BITS == 64 case INDEX_op_mov_i64: +case INDEX_op_add_i64: +case INDEX_op_sub_i64: +case INDEX_op_mul_i64: return 64; #endif default: @@ -156,6 +162,52 @@ static void tcg_opt_gen_movi(TCGArg *gen_args, TCGArg dst, TCGArg val, gen_args[1] = val; } +static int op_to_mov(int op) +{ +switch (op_bits(op)) { +case 32: +return INDEX_op_mov_i32; +#if TCG_TARGET_REG_BITS == 64 +case 64: +return INDEX_op_mov_i64; +#endif +default: +fprintf(stderr, op_to_mov: unexpected return value of +function op_bits.\n); +tcg_abort(); +} +} + +static TCGArg do_constant_folding_2(int op, TCGArg x, TCGArg y) +{ +switch (op) { +CASE_OP_32_64(add): +return x + y; + +CASE_OP_32_64(sub): +return x - y; + +CASE_OP_32_64(mul): +return x * y; + +default: +fprintf(stderr, +Unrecognized operation %d in do_constant_folding.\n, op); +tcg_abort(); +} +} + +static TCGArg do_constant_folding(int op, TCGArg x, TCGArg y) +{ +TCGArg res = do_constant_folding_2(op, x, y); +#if TCG_TARGET_REG_BITS == 64 +if (op_bits(op) == 32) { +res = 0x; +} +#endif +return res; +} + /* Propagate constants and copies, fold constant expressions. */ static TCGArg *tcg_constant_folding(TCGContext *s, uint16_t *tcg_opc_ptr, TCGArg *args, TCGOpDef *tcg_op_defs) @@ -163,6 +215,7 @@ static TCGArg *tcg_constant_folding(TCGContext *s, uint16_t *tcg_opc_ptr, int i, nb_ops, op_index, op, nb_temps, nb_globals, nb_call_args; const TCGOpDef *def; TCGArg *gen_args; +TCGArg tmp; /* Array VALS has an element for each temp. If this temp holds a constant then its value is kept in VALS' element. If this temp is a copy of other ones then this equivalence class' @@ -189,6 +242,57 @@ static TCGArg *tcg_constant_folding(TCGContext *s, uint16_t *tcg_opc_ptr, } } +/* For commutative operations make constant second argument */ +switch (op) { +CASE_OP_32_64(add): +CASE_OP_32_64(mul): +if (temps[args[1]].state == TCG_TEMP_CONST) { +tmp = args[1]; +args[1] = args[2]; +args[2] = tmp; +} +break; +default: +break; +} + +/* Simplify expression if possible. */ +switch (op) { +CASE_OP_32_64(add): +CASE_OP_32_64(sub): +if (temps[args[1]].state == TCG_TEMP_CONST) { +/* Proceed with possible constant folding. */ +break; +} +if (temps[args[2]].state == TCG_TEMP_CONST + temps[args[2]].val == 0) { +if ((temps[args[0]].state == TCG_TEMP_COPY + temps[args[0]].val == args[1]) +|| args[0] == args[1]) { +args += 3; +gen_opc_buf[op_index] = INDEX_op_nop; +} else { +gen_opc_buf[op_index] = op_to_mov(op); +tcg_opt_gen_mov(gen_args, args[0], args[1], +nb_temps, nb_globals); +gen_args += 2; +args += 3; +} +continue; +} +break; +CASE_OP_32_64(mul): +if ((temps[args[2]].state == TCG_TEMP_CONST + temps[args[2]].val == 0)) { +gen_opc_buf[op_index] = op_to_movi(op); +tcg_opt_gen_movi(gen_args, args[0], 0, nb_temps, nb_globals); +args += 3; +gen_args += 2; +continue; +} +break; +} + /* Propagate constants through copy operations and do constant folding. Constants will be substituted to arguments by register allocator where needed and possible. Also detect copies. */ @@ -219,6 +323,27 @@ static TCGArg *tcg_constant_folding(TCGContext *s, uint16_t *tcg_opc_ptr, gen_args += 2; args += 2; break; +CASE_OP_32_64(add): +CASE_OP_32_64(sub): +CASE_OP_32_64(mul): +if (temps[args[1]].state == TCG_TEMP_CONST +
[Qemu-devel] [PATCH v3 1/6] Add TCG optimizations stub
Added file tcg/optimize.c to hold TCG optimizations. Function tcg_optimize is called from tcg_gen_code_common. It calls other functions performing specific optimizations. Stub for constant folding was added. Signed-off-by: Kirill Batuzov batuz...@ispras.ru --- Makefile.target |2 +- tcg/optimize.c | 97 +++ tcg/tcg.c |6 +++ tcg/tcg.h |3 ++ 4 files changed, 107 insertions(+), 1 deletions(-) create mode 100644 tcg/optimize.c diff --git a/Makefile.target b/Makefile.target index 2e281a4..0b045ce 100644 --- a/Makefile.target +++ b/Makefile.target @@ -70,7 +70,7 @@ all: $(PROGS) stap # # cpu emulator library libobj-y = exec.o translate-all.o cpu-exec.o translate.o -libobj-y += tcg/tcg.o +libobj-y += tcg/tcg.o tcg/optimize.o libobj-$(CONFIG_SOFTFLOAT) += fpu/softfloat.o libobj-$(CONFIG_NOSOFTFLOAT) += fpu/softfloat-native.o libobj-y += op_helper.o helper.o diff --git a/tcg/optimize.c b/tcg/optimize.c new file mode 100644 index 000..c7c7da9 --- /dev/null +++ b/tcg/optimize.c @@ -0,0 +1,97 @@ +/* + * Optimizations for Tiny Code Generator for QEMU + * + * Copyright (c) 2010 Samsung Electronics. + * Contributed by Kirill Batuzov batuz...@ispras.ru + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the Software), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED AS IS, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +#include config.h + +#include stdlib.h +#include stdio.h + +#include qemu-common.h +#include tcg-op.h + +#if TCG_TARGET_REG_BITS == 64 +#define CASE_OP_32_64(x)\ +glue(glue(case INDEX_op_, x), _i32):\ +glue(glue(case INDEX_op_, x), _i64) +#else +#define CASE_OP_32_64(x)\ +glue(glue(case INDEX_op_, x), _i32) +#endif + +static TCGArg *tcg_constant_folding(TCGContext *s, uint16_t *tcg_opc_ptr, +TCGArg *args, TCGOpDef *tcg_op_defs) +{ +int i, nb_ops, op_index, op, nb_temps, nb_globals; +const TCGOpDef *def; +TCGArg *gen_args; + +nb_temps = s-nb_temps; +nb_globals = s-nb_globals; + +nb_ops = tcg_opc_ptr - gen_opc_buf; +gen_args = args; +for (op_index = 0; op_index nb_ops; op_index++) { +op = gen_opc_buf[op_index]; +def = tcg_op_defs[op]; +switch (op) { +case INDEX_op_call: +i = (args[0] 16) + (args[0] 0x) + 3; +while (i) { +*gen_args = *args; +args++; +gen_args++; +i--; +} +break; +case INDEX_op_set_label: +case INDEX_op_jmp: +case INDEX_op_br: +CASE_OP_32_64(brcond): +for (i = 0; i def-nb_args; i++) { +*gen_args = *args; +args++; +gen_args++; +} +break; +default: +for (i = 0; i def-nb_args; i++) { +gen_args[i] = args[i]; +} +args += def-nb_args; +gen_args += def-nb_args; +break; +} +} + +return gen_args; +} + +TCGArg *tcg_optimize(TCGContext *s, uint16_t *tcg_opc_ptr, +TCGArg *args, TCGOpDef *tcg_op_defs) +{ +TCGArg *res; +res = tcg_constant_folding(s, tcg_opc_ptr, args, tcg_op_defs); +return res; +} diff --git a/tcg/tcg.c b/tcg/tcg.c index fad92f9..6309dce 100644 --- a/tcg/tcg.c +++ b/tcg/tcg.c @@ -24,6 +24,7 @@ /* define it to use liveness analysis (better code) */ #define USE_LIVENESS_ANALYSIS +#define USE_TCG_OPTIMIZATIONS #include config.h @@ -2033,6 +2034,11 @@ static inline int tcg_gen_code_common(TCGContext *s, uint8_t *gen_code_buf, } #endif +#ifdef USE_TCG_OPTIMIZATIONS +gen_opparam_ptr = +tcg_optimize(s, gen_opc_ptr, gen_opparam_buf, tcg_op_defs); +#endif + #ifdef CONFIG_PROFILER s-la_time -= profile_getclock(); #endif diff --git a/tcg/tcg.h b/tcg/tcg.h index 2b985ac..91a3cda
Re: [Qemu-devel] [PATCH v3 0/6] Implement constant folding and copy propagation in TCG
On 7 July 2011 13:37, Kirill Batuzov batuz...@ispras.ru wrote: ARM guests for 254.gap and 255.vortex and x86_64 guest for 252.eon does not work under QEMU for some unrelated reason. If you can provide a binary and a command line for these I can have a look at what's going on with the failing ARM guest binaries... -- PMM
[Qemu-devel] [PATCH v3 5/6] Do constant folding for shift operations.
Perform constant forlding for SHR, SHL, SAR, ROTR, ROTL operations. Signed-off-by: Kirill Batuzov batuz...@ispras.ru --- tcg/optimize.c | 72 1 files changed, 72 insertions(+), 0 deletions(-) diff --git a/tcg/optimize.c b/tcg/optimize.c index c469952..a1bb287 100644 --- a/tcg/optimize.c +++ b/tcg/optimize.c @@ -102,6 +102,11 @@ static int op_bits(int op) case INDEX_op_and_i32: case INDEX_op_or_i32: case INDEX_op_xor_i32: +case INDEX_op_shl_i32: +case INDEX_op_shr_i32: +case INDEX_op_sar_i32: +case INDEX_op_rotl_i32: +case INDEX_op_rotr_i32: return 32; #if TCG_TARGET_REG_BITS == 64 case INDEX_op_mov_i64: @@ -111,6 +116,11 @@ static int op_bits(int op) case INDEX_op_and_i64: case INDEX_op_or_i64: case INDEX_op_xor_i64: +case INDEX_op_shl_i64: +case INDEX_op_shr_i64: +case INDEX_op_sar_i64: +case INDEX_op_rotl_i64: +case INDEX_op_rotr_i64: return 64; #endif default: @@ -205,6 +215,58 @@ static TCGArg do_constant_folding_2(int op, TCGArg x, TCGArg y) CASE_OP_32_64(xor): return x ^ y; +case INDEX_op_shl_i32: +return (uint32_t)x (uint32_t)y; + +#if TCG_TARGET_REG_BITS == 64 +case INDEX_op_shl_i64: +return (uint64_t)x (uint64_t)y; +#endif + +case INDEX_op_shr_i32: +return (uint32_t)x (uint32_t)y; + +#if TCG_TARGET_REG_BITS == 64 +case INDEX_op_shr_i64: +return (uint64_t)x (uint64_t)y; +#endif + +case INDEX_op_sar_i32: +return (int32_t)x (int32_t)y; + +#if TCG_TARGET_REG_BITS == 64 +case INDEX_op_sar_i64: +return (int64_t)x (int64_t)y; +#endif + +case INDEX_op_rotr_i32: +#if TCG_TARGET_REG_BITS == 64 +x = 0x; +y = 0x; +#endif +x = (x (32 - y)) | (x y); +return x; + +#if TCG_TARGET_REG_BITS == 64 +case INDEX_op_rotr_i64: +x = (x (64 - y)) | (x y); +return x; +#endif + +case INDEX_op_rotl_i32: +#if TCG_TARGET_REG_BITS == 64 +x = 0x; +y = 0x; +#endif +x = (x y) | (x (32 - y)); +return x; + +#if TCG_TARGET_REG_BITS == 64 +case INDEX_op_rotl_i64: +x = (x y) | (x (64 - y)); +return x; +#endif + default: fprintf(stderr, Unrecognized operation %d in do_constant_folding.\n, op); @@ -278,6 +340,11 @@ static TCGArg *tcg_constant_folding(TCGContext *s, uint16_t *tcg_opc_ptr, switch (op) { CASE_OP_32_64(add): CASE_OP_32_64(sub): +CASE_OP_32_64(shl): +CASE_OP_32_64(shr): +CASE_OP_32_64(sar): +CASE_OP_32_64(rotl): +CASE_OP_32_64(rotr): if (temps[args[1]].state == TCG_TEMP_CONST) { /* Proceed with possible constant folding. */ break; @@ -363,6 +430,11 @@ static TCGArg *tcg_constant_folding(TCGContext *s, uint16_t *tcg_opc_ptr, CASE_OP_32_64(or): CASE_OP_32_64(and): CASE_OP_32_64(xor): +CASE_OP_32_64(shl): +CASE_OP_32_64(shr): +CASE_OP_32_64(sar): +CASE_OP_32_64(rotl): +CASE_OP_32_64(rotr): if (temps[args[1]].state == TCG_TEMP_CONST temps[args[2]].state == TCG_TEMP_CONST) { gen_opc_buf[op_index] = op_to_movi(op); -- 1.7.4.1
Re: [Qemu-devel] [SeaBIOS] [PATCH V5 0/9] Add TPM support to SeaBIOS
On Thu, Jul 07, 2011 at 07:48:29AM -0400, Stefan Berger wrote: On 07/06/2011 06:58 PM, Kevin O'Connor wrote: BTW, I don't think patch 7 or 9 really make sense to integrate in the official version of SeaBIOS. Also, in patch 8, I'd prefer to see all new fw_cfg entries use the romfile mechanism. Patch 7 is the menu. This patch is needed in 'some form' since in some cases, like after giving up ownership of the TPM, the TPM becomes disabled and deactivated and one has to interact with the BIOS to activate and enable it again. Other scenarios include someone who has forgotten the owner password for the TPM and now has to go through the BIOS to give up ownership of it -- that's the only way one can do this then. Hrmm. I don't recall seeing this menu on the factory BIOS of real machines. How do normal users interact with it? Can the info be passed in from QEmu? I'll have a look at the 'romfile' mechanism for patch 8. I only post patch 9 for someone who is interested to be able to run the tests. Since the 128kb are slowly filling up, it's not going to be compilable with it for much longer and I don't expect it to go into the repo. There is no limit at 128K - if it's exceeded the build will start using a 256K rom. More important than the total size is the fixed size reported at the end of the build - that's how much space is used under 1 Meg after the post phase completes. Ideally it would stay under 64K though that's not a hard limit either. -Kevin
[Qemu-devel] [PATCH 2/3] virtio-console: Add some trace events
Add some trace events for messages passed between the char layer and the virtio-serial bus. Signed-off-by: Amit Shah amit.s...@redhat.com --- hw/virtio-console.c |9 - trace-events|5 + 2 files changed, 13 insertions(+), 1 deletions(-) diff --git a/hw/virtio-console.c b/hw/virtio-console.c index b076331..713a761 100644 --- a/hw/virtio-console.c +++ b/hw/virtio-console.c @@ -12,6 +12,7 @@ #include qemu-char.h #include qemu-error.h +#include trace.h #include virtio-serial.h typedef struct VirtConsole { @@ -24,8 +25,12 @@ typedef struct VirtConsole { static ssize_t flush_buf(VirtIOSerialPort *port, const uint8_t *buf, size_t len) { VirtConsole *vcon = DO_UPCAST(VirtConsole, port, port); +ssize_t ret; -return qemu_chr_write(vcon-chr, buf, len); +ret = qemu_chr_write(vcon-chr, buf, len); + +trace_virtio_console_flush_buf(port-id, len, ret); +return ret; } /* Callback function that's called when the guest opens the port */ @@ -57,6 +62,7 @@ static void chr_read(void *opaque, const uint8_t *buf, int size) { VirtConsole *vcon = opaque; +trace_virtio_console_chr_read(vcon-port.id, size); virtio_serial_write(vcon-port, buf, size); } @@ -64,6 +70,7 @@ static void chr_event(void *opaque, int event) { VirtConsole *vcon = opaque; +trace_virtio_console_chr_event(vcon-port.id, event); switch (event) { case CHR_EVENT_OPENED: virtio_serial_open(vcon-port); diff --git a/trace-events b/trace-events index 59420e8..765a15e 100644 --- a/trace-events +++ b/trace-events @@ -52,6 +52,11 @@ disable virtio_serial_throttle_port(unsigned int port, bool throttle) port %u, disable virtio_serial_handle_control_message(uint16_t event, uint16_t value) event %u, value %u disable virtio_serial_handle_control_message_port(unsigned int port) port %u +# hw/virtio-console.c +disable virtio_console_flush_buf(unsigned int port, size_t len, ssize_t ret) port %u, in_len %zu, out_len %zd +disable virtio_console_chr_read(unsigned int port, int size) port %u, size %d +disable virtio_console_chr_event(unsigned int port, int event) port %u, event %d + # block.c disable multiwrite_cb(void *mcb, int ret) mcb %p ret %d disable bdrv_aio_multiwrite(void *mcb, int num_callbacks, int num_reqs) mcb %p num_callbacks %d num_reqs %d -- 1.7.5.4
[Qemu-devel] [PATCH 1/3] virtio-serial-bus: Add trace events
Add some trace events for messages passed between the guest and host. Signed-off-by: Amit Shah amit.s...@redhat.com --- hw/virtio-serial-bus.c |7 +++ trace-events |6 ++ 2 files changed, 13 insertions(+), 0 deletions(-) diff --git a/hw/virtio-serial-bus.c b/hw/virtio-serial-bus.c index 7f6db7b..9859f9f 100644 --- a/hw/virtio-serial-bus.c +++ b/hw/virtio-serial-bus.c @@ -19,6 +19,7 @@ #include monitor.h #include qemu-queue.h #include sysbus.h +#include trace.h #include virtio-serial.h /* The virtio-serial bus on top of which the ports will ride as devices */ @@ -221,6 +222,7 @@ static size_t send_control_event(VirtIOSerialPort *port, uint16_t event, stw_p(cpkt.event, event); stw_p(cpkt.value, value); +trace_virtio_serial_send_control_event(port-id, event, value); return send_control_msg(port, cpkt, sizeof(cpkt)); } @@ -302,6 +304,7 @@ void virtio_serial_throttle_port(VirtIOSerialPort *port, bool throttle) return; } +trace_virtio_serial_throttle_port(port-id, throttle); port-throttled = throttle; if (throttle) { return; @@ -328,6 +331,8 @@ static void handle_control_message(VirtIOSerial *vser, void *buf, size_t len) cpkt.event = lduw_p(gcpkt-event); cpkt.value = lduw_p(gcpkt-value); +trace_virtio_serial_handle_control_message(cpkt.event, cpkt.value); + if (cpkt.event == VIRTIO_CONSOLE_DEVICE_READY) { if (!cpkt.value) { error_report(virtio-serial-bus: Guest failure in adding device %s, @@ -351,6 +356,8 @@ static void handle_control_message(VirtIOSerial *vser, void *buf, size_t len) return; } +trace_virtio_serial_handle_control_message_port(port-id); + info = DO_UPCAST(VirtIOSerialPortInfo, qdev, port-dev.info); switch(cpkt.event) { diff --git a/trace-events b/trace-events index bebf612..59420e8 100644 --- a/trace-events +++ b/trace-events @@ -46,6 +46,12 @@ disable virtio_queue_notify(void *vdev, int n, void *vq) vdev %p n %d vq %p disable virtio_irq(void *vq) vq %p disable virtio_notify(void *vdev, void *vq) vdev %p vq %p +# hw/virtio-serial-bus.c +disable virtio_serial_send_control_event(unsigned int port, uint16_t event, uint16_t value) port %u, event %u, value %u +disable virtio_serial_throttle_port(unsigned int port, bool throttle) port %u, throttle %d +disable virtio_serial_handle_control_message(uint16_t event, uint16_t value) event %u, value %u +disable virtio_serial_handle_control_message_port(unsigned int port) port %u + # block.c disable multiwrite_cb(void *mcb, int ret) mcb %p ret %d disable bdrv_aio_multiwrite(void *mcb, int num_callbacks, int num_reqs) mcb %p num_callbacks %d num_reqs %d -- 1.7.5.4
[Qemu-devel] [PULL] virtio-serial: trace events, trivial fix
Hello, This series adds some trace events to virtio-serial-bus.c and virtio-console.c. There's also one trivial patch to remove a trailing \n from an error_report() string. Note: some mirrors may not yet have received the update. The following changes since commit 9312805d33e8b106bae356d13a8071fb37d75554: pxa2xx_lcd: add proper rotation support (2011-07-04 22:12:21 +0200) are available in the git repository at: git://git.kernel.org/pub/scm/virt/qemu/amit/virtio-serial.git for-anthony Amit Shah (3): virtio-serial-bus: Add trace events virtio-console: Add some trace events virtio-serial-bus: Fix trailing \n in error_report string hw/virtio-console.c|9 - hw/virtio-serial-bus.c |9 - trace-events | 11 +++ 3 files changed, 27 insertions(+), 2 deletions(-) -- 1.7.5.4
[Qemu-devel] [PATCH 3/3] virtio-serial-bus: Fix trailing \n in error_report string
Markus fixed offenders in the file but one instance sneaked in via another patch. Fix it. Signed-off-by: Amit Shah amit.s...@redhat.com --- hw/virtio-serial-bus.c |2 +- 1 files changed, 1 insertions(+), 1 deletions(-) diff --git a/hw/virtio-serial-bus.c b/hw/virtio-serial-bus.c index 9859f9f..6d73386 100644 --- a/hw/virtio-serial-bus.c +++ b/hw/virtio-serial-bus.c @@ -351,7 +351,7 @@ static void handle_control_message(VirtIOSerial *vser, void *buf, size_t len) port = find_port_by_id(vser, ldl_p(gcpkt-id)); if (!port) { -error_report(virtio-serial-bus: Unexpected port id %u for device %s\n, +error_report(virtio-serial-bus: Unexpected port id %u for device %s, ldl_p(gcpkt-id), vser-bus.qbus.name); return; } -- 1.7.5.4
Re: [Qemu-devel] [PATCH] Add tee option to qemu char device
On 07/07/2011 10:24 AM, Chunyan Liu wrote: In previous thread Support logging xen-guest console, it's considered that adding a tee option to char layer is a more generic way and makes more sense. http://lists.nongnu.org/archive/html/qemu-devel/2011-06/msg03011.html Following is an implementation of tee option to char device. It could be used as follows: -chardev pty,id=id,path=path,[mux=on|off],[tee=filepath] -serial tee:filepath,pty With tee option, pty output would be duplicated to filepath. I've ported this patch to qemu-xen and tested with xen guests already. But I'm not very clear how to test the qemu binary directly. Any info? Please share your comments. Thanks! Signed-off-by: Chunyan Liucy...@novell.com --- qemu-char.c | 159 + qemu-config.c |3 + This is missing documentation in *.hx 2 files changed, 162 insertions(+), 0 deletions(-) diff --git a/qemu-char.c b/qemu-char.c index fb13b28..7281ab4 100644 --- a/qemu-char.c +++ b/qemu-char.c @@ -228,6 +228,135 @@ static CharDriverState *qemu_chr_open_null(QemuOpts *opts) return chr; } +/* Tee driver */ +typedef struct { +CharDriverState *basechr; /* base io*/ +CharDriverState *filechr; /* duplicate output to file */ +} TeeDriver; + +static void tee_init(CharDriverState *chr) +{ +TeeDriver *s = chr-opaque; +if (s-basechr-init) { +s-basechr-init(s-basechr); +} +if (s-filechr-init) { +s-filechr-init(s-filechr); +} +} + +static void tee_chr_update_read_handler(CharDriverState *chr) +{ +TeeDriver *s = chr-opaque; +qemu_chr_add_handlers(s-basechr, chr-chr_can_read, chr-chr_read, + chr-chr_event, chr-handler_opaque); +} + +static int tee_chr_write(CharDriverState *chr, const uint8_t *buf, int len) +{ +TeeDriver *s = chr-opaque; +if (s-filechr-chr_write) { +s-filechr-chr_write(s-filechr, buf, len); What would we do if the file write didn't finish? +} +if (s-basechr-chr_write) { +return s-basechr-chr_write(s-basechr, buf, len); +} +return 0; +} + +static void tee_chr_close(CharDriverState *chr) +{ +TeeDriver *s = chr-opaque; +if (s-basechr-chr_close) { +s-basechr-chr_close(s-basechr); +} +if (s-filechr-chr_close) { +s-filechr-chr_close(s-filechr); +} +qemu_free(s); +} + +static int tee_chr_ioctl(CharDriverState *chr, int cmd, void *arg) +{ +TeeDriver *s = chr-opaque; +if (s-basechr-chr_ioctl) { +return s-basechr-chr_ioctl(s-basechr, cmd, arg); +} +return 0; +} + +static int tee_get_msgfd(CharDriverState *chr) +{ +TeeDriver *s = chr-opaque; +if (s-basechr-get_msgfd) { +return s-basechr-get_msgfd(s-basechr); +} +return -1; +} + +static void tee_chr_send_event(CharDriverState *chr, int event) +{ +TeeDriver *s = chr-opaque; +if (s-basechr-chr_send_event) { +s-basechr-chr_send_event(s-basechr, event); +} +} + +static void tee_chr_accept_input(CharDriverState *chr) +{ +TeeDriver *s = chr-opaque; +if (s-basechr-chr_accept_input) { +s-basechr-chr_accept_input(s-basechr); +} +} +static void tee_chr_set_echo(CharDriverState *chr, bool echo) +{ +TeeDriver *s = chr-opaque; +if (s-basechr-chr_set_echo) { +s-basechr-chr_set_echo(s-basechr, echo); +} +} +static void tee_chr_guest_open(CharDriverState *chr) +{ +TeeDriver *s = chr-opaque; +if (s-basechr-chr_guest_open) { +s-basechr-chr_guest_open(s-basechr); +} +} +static void tee_chr_guest_close(CharDriverState *chr) +{ +TeeDriver *s = chr-opaque; +if (s-basechr-chr_guest_close) { +s-basechr-chr_guest_close(s-basechr); +} +} + +static CharDriverState *qemu_chr_open_tee(CharDriverState *basechr, + CharDriverState *filechr) +{ +CharDriverState *chr; +TeeDriver *d; + +chr = qemu_mallocz(sizeof(CharDriverState)); +d = qemu_mallocz(sizeof(TeeDriver)); Instead of having 2 allocated regions, could you please fold them together and access each other through DO_UPCAST? typedef struct { CharDriverState chr; /* our own driver state */ CharDriverState *basechr; /* base io*/ CharDriverState *filechr; /* duplicate output to file */ } TeeDriver; [...] void foo(CharDriverState *chr) { TeeDriver *d = DO_UPCAST(TeeDriver, chr, chr); [...] } + +d-basechr = basechr; +d-filechr = filechr; +chr-opaque = d; +chr-init = tee_init; +chr-chr_write = tee_chr_write; +chr-chr_close = tee_chr_close; +chr-chr_update_read_handler = tee_chr_update_read_handler; +chr-chr_ioctl = tee_chr_ioctl; +chr-get_msgfd = tee_get_msgfd; +chr-chr_send_event = tee_chr_send_event; +chr-chr_accept_input = tee_chr_accept_input; +chr-chr_set_echo = tee_chr_set_echo; +chr-chr_guest_open = tee_chr_guest_open; +chr-chr_guest_close =
[Qemu-devel] [PATCH v2 1/9] exec: add endian specific phys ld/st functions
Device code some times needs to access physical memory and does that through the ld./st._phys functions. However, these are the exact same functions that the CPU uses to access memory, which means they will be endianness swapped depending on the target CPU. However, devices don't know about the CPU's endianness, but instead access memory directly using their own interface to the memory bus, so they need some way to read data with their native endianness. This patch adds _le and _be functions to ld./st._phys. Signed-off-by: Alexander Graf ag...@suse.de --- v1 - v2: - inline endian detection, so we can use qemu's ld.|st._le|be_p functions --- cpu-common.h | 12 exec.c | 201 +++--- 2 files changed, 203 insertions(+), 10 deletions(-) diff --git a/cpu-common.h b/cpu-common.h index b027e43..c6a2b5f 100644 --- a/cpu-common.h +++ b/cpu-common.h @@ -135,14 +135,26 @@ void qemu_flush_coalesced_mmio_buffer(void); uint32_t ldub_phys(target_phys_addr_t addr); uint32_t lduw_phys(target_phys_addr_t addr); +uint32_t lduw_le_phys(target_phys_addr_t addr); +uint32_t lduw_be_phys(target_phys_addr_t addr); uint32_t ldl_phys(target_phys_addr_t addr); +uint32_t ldl_le_phys(target_phys_addr_t addr); +uint32_t ldl_be_phys(target_phys_addr_t addr); uint64_t ldq_phys(target_phys_addr_t addr); +uint64_t ldq_le_phys(target_phys_addr_t addr); +uint64_t ldq_be_phys(target_phys_addr_t addr); void stl_phys_notdirty(target_phys_addr_t addr, uint32_t val); void stq_phys_notdirty(target_phys_addr_t addr, uint64_t val); void stb_phys(target_phys_addr_t addr, uint32_t val); void stw_phys(target_phys_addr_t addr, uint32_t val); +void stw_le_phys(target_phys_addr_t addr, uint32_t val); +void stw_be_phys(target_phys_addr_t addr, uint32_t val); void stl_phys(target_phys_addr_t addr, uint32_t val); +void stl_le_phys(target_phys_addr_t addr, uint32_t val); +void stl_be_phys(target_phys_addr_t addr, uint32_t val); void stq_phys(target_phys_addr_t addr, uint64_t val); +void stq_le_phys(target_phys_addr_t addr, uint64_t val); +void stq_be_phys(target_phys_addr_t addr, uint64_t val); void cpu_physical_memory_write_rom(target_phys_addr_t addr, const uint8_t *buf, int len); diff --git a/exec.c b/exec.c index 4c45299..9e6913e 100644 --- a/exec.c +++ b/exec.c @@ -4127,7 +4127,8 @@ void cpu_physical_memory_unmap(void *buffer, target_phys_addr_t len, } /* warning: addr must be aligned */ -uint32_t ldl_phys(target_phys_addr_t addr) +static inline uint32_t ldl_phys_internal(target_phys_addr_t addr, + enum device_endian endian) { int io_index; uint8_t *ptr; @@ -4149,17 +4150,52 @@ uint32_t ldl_phys(target_phys_addr_t addr) if (p) addr = (addr ~TARGET_PAGE_MASK) + p-region_offset; val = io_mem_read[io_index][2](io_mem_opaque[io_index], addr); +#if defined(TARGET_WORDS_BIGENDIAN) +if (endian == DEVICE_LITTLE_ENDIAN) { +val = bswap32(val); +} +#else +if (endian == DEVICE_BIG_ENDIAN) { +val = bswap32(val); +} +#endif } else { /* RAM case */ ptr = qemu_get_ram_ptr(pd TARGET_PAGE_MASK) + (addr ~TARGET_PAGE_MASK); -val = ldl_p(ptr); +switch (endian) { +case DEVICE_LITTLE_ENDIAN: +val = ldl_le_p(ptr); +break; +case DEVICE_BIG_ENDIAN: +val = ldl_be_p(ptr); +break; +default: +val = ldl_p(ptr); +break; +} } return val; } +uint32_t ldl_phys(target_phys_addr_t addr) +{ +return ldl_phys_internal(addr, DEVICE_NATIVE_ENDIAN); +} + +uint32_t ldl_le_phys(target_phys_addr_t addr) +{ +return ldl_phys_internal(addr, DEVICE_LITTLE_ENDIAN); +} + +uint32_t ldl_be_phys(target_phys_addr_t addr) +{ +return ldl_phys_internal(addr, DEVICE_BIG_ENDIAN); +} + /* warning: addr must be aligned */ -uint64_t ldq_phys(target_phys_addr_t addr) +static inline uint64_t ldq_phys_internal(target_phys_addr_t addr, + enum device_endian endian) { int io_index; uint8_t *ptr; @@ -4180,6 +4216,9 @@ uint64_t ldq_phys(target_phys_addr_t addr) io_index = (pd IO_MEM_SHIFT) (IO_MEM_NB_ENTRIES - 1); if (p) addr = (addr ~TARGET_PAGE_MASK) + p-region_offset; + +/* XXX This is broken when device endian != cpu endian. + Fix and add endian variable check */ #ifdef TARGET_WORDS_BIGENDIAN val = (uint64_t)io_mem_read[io_index][2](io_mem_opaque[io_index], addr) 32; val |= io_mem_read[io_index][2](io_mem_opaque[io_index], addr + 4); @@ -4191,11 +4230,36 @@ uint64_t ldq_phys(target_phys_addr_t addr) /* RAM case */ ptr = qemu_get_ram_ptr(pd TARGET_PAGE_MASK) + (addr ~TARGET_PAGE_MASK); -val = ldq_p(ptr); +
[Qemu-devel] [PATCH 1/1] virtio-console: Prevent abort()s in case of host chardev close
A host chardev could close just before the guest sends some data to be written. This will cause an -EPIPE error. This shouldn't be propagated to virtio-serial-bus. Ideally we should close the port once -EPIPE is received, but since the chardev interface doesn't return such meaningful values to its users, all we get is -1 for any kind of error. Just return 0 for now and wait for chardevs to return better error messages to act better on the return messages. Signed-off-by: Amit Shah amit.s...@redhat.com --- hw/virtio-console.c | 20 ++-- 1 files changed, 18 insertions(+), 2 deletions(-) diff --git a/hw/virtio-console.c b/hw/virtio-console.c index b076331..a25c29e 100644 --- a/hw/virtio-console.c +++ b/hw/virtio-console.c @@ -24,8 +24,24 @@ typedef struct VirtConsole { static ssize_t flush_buf(VirtIOSerialPort *port, const uint8_t *buf, size_t len) { VirtConsole *vcon = DO_UPCAST(VirtConsole, port, port); - -return qemu_chr_write(vcon-chr, buf, len); +ssize_t ret; + +ret = qemu_chr_write(vcon-chr, buf, len); +if (ret 0 ret != -EAGAIN) { +/* + * Ideally we'd get a better error code than just -1, but + * that's what the chardev interface gives us right now. If + * we had a finer-grained message, like -EPIPE, we could close + * this connection. Absent such error messages, the most we + * can do is to return 0 here. + * + * This will prevent stray -1 values to go to + * virtio-serial-bus.c and cause abort()s in + * do_flush_queued_data(). + */ +ret = 0; +} +return ret; } /* Callback function that's called when the guest opens the port */ -- 1.7.5.4
[Qemu-devel] [PATCH 1/3] qemu: Add strtosz_suffix_unit function
This function does the same as the strtosz_suffix function except that it allows to specify the unit to which the k/M/B/T suffixes apply. This function will be used later to parse the tsc-frequency from the command-line. Signed-off-by: Joerg Roedel joerg.roe...@amd.com --- cutils.c | 16 +++- qemu-common.h |2 ++ 2 files changed, 13 insertions(+), 5 deletions(-) diff --git a/cutils.c b/cutils.c index f9a7e36..28049e0 100644 --- a/cutils.c +++ b/cutils.c @@ -322,7 +322,8 @@ int fcntl_setfl(int fd, int flag) * value must be terminated by whitespace, ',' or '\0'. Return -1 on * error. */ -int64_t strtosz_suffix(const char *nptr, char **end, const char default_suffix) +int64_t strtosz_suffix_unit(const char *nptr, char **end, +const char default_suffix, int64_t unit) { int64_t retval = -1; char *endptr; @@ -362,20 +363,20 @@ int64_t strtosz_suffix(const char *nptr, char **end, const char default_suffix) } break; case STRTOSZ_DEFSUFFIX_KB: -mul = 1 10; +mul = unit; break; case 0: if (mul_required) { goto fail; } case STRTOSZ_DEFSUFFIX_MB: -mul = 1ULL 20; +mul = unit * unit; break; case STRTOSZ_DEFSUFFIX_GB: -mul = 1ULL 30; +mul = unit * unit * unit; break; case STRTOSZ_DEFSUFFIX_TB: -mul = 1ULL 40; +mul = unit * unit * unit * unit; break; default: goto fail; @@ -405,6 +406,11 @@ fail: return retval; } +int64_t strtosz_suffix(const char *nptr, char **end, const char default_suffix) +{ +return strtosz_suffix_unit(nptr, end, default_suffix, 1024); +} + int64_t strtosz(const char *nptr, char **end) { return strtosz_suffix(nptr, end, STRTOSZ_DEFSUFFIX_MB); diff --git a/qemu-common.h b/qemu-common.h index 109498d..854031a 100644 --- a/qemu-common.h +++ b/qemu-common.h @@ -186,6 +186,8 @@ int fcntl_setfl(int fd, int flag); #define STRTOSZ_DEFSUFFIX_B'B' int64_t strtosz(const char *nptr, char **end); int64_t strtosz_suffix(const char *nptr, char **end, const char default_suffix); +int64_t strtosz_suffix_unit(const char *nptr, char **end, +const char default_suffix, int64_t unit); /* path.c */ void init_paths(const char *prefix); -- 1.7.4.1
[Qemu-devel] [PATCH 0/3][uq/master] Basic TSC-Scaling support v2
Hi Avi, Marcelo, here is v2 of the patches to support setting the guests tsc-frequency from the qemu command line. This version addresses the comment from Avi on the first version. To reflect that units can be given to the frequency, the parameter was renamed from tsc_khz to tsc_freq. Thanks, Joerg Diffstat: cutils.c| 16 +++- qemu-common.h |2 ++ target-i386/cpu.h |1 + target-i386/cpuid.c | 13 + target-i386/kvm.c | 18 +- 5 files changed, 44 insertions(+), 6 deletions(-)
Re: [Qemu-devel] [PATCH v3 0/6] Implement constant folding and copy propagation in TCG
On Thu, 7 Jul 2011, Peter Maydell wrote: On 7 July 2011 13:37, Kirill Batuzov batuz...@ispras.ru wrote: ARM guests for 254.gap and 255.vortex and x86_64 guest for 252.eon does not work under QEMU for some unrelated reason. If you can provide a binary and a command line for these I can have a look at what's going on with the failing ARM guest binaries... I've just checked more carefully: these tests fail the same way on hardware. So it is some SPEC or compiler problem not related to QEMU at all. Kirill
Re: [Qemu-devel] [PATCH v2 1/3] spapr: proper qdevification
On 05/26/2011 11:52 AM, Paolo Bonzini wrote: Right now the spapr devices cannot be instantiated with -device, because the IRQs need to be passed to the spapr_*_create functions. Do this instead in the bus's init wrapper. This is particularly important with the conversion from scsi-disk to scsi-{cd,hd} that Markus made. After his patches, if you specify a scsi-cd device attached to an if=none drive, the default VSCSI controller will not be created and, without qdevification, you will not be able to add yours. Signed-off-by: Paolo Bonzinipbonz...@redhat.com Cc: Alexander Grafag...@suse.de Cc: David Gibsonda...@gibson.dropbear.id.au --- hw/spapr.c | 15 +-- hw/spapr.h |6 ++ hw/spapr_llan.c |7 +-- hw/spapr_vio.c |5 + hw/spapr_vio.h | 13 - hw/spapr_vscsi.c |8 +--- hw/spapr_vty.c |8 +--- 7 files changed, 23 insertions(+), 39 deletions(-) diff --git a/hw/spapr.c b/hw/spapr.c index 109b774..07b2165 100644 --- a/hw/spapr.c +++ b/hw/spapr.c @@ -298,7 +298,6 @@ static void ppc_spapr_init(ram_addr_t ram_size, long kernel_size, initrd_size, fw_size; long pteg_shift = 17; char *filename; -int irq = 16; spapr = qemu_malloc(sizeof(*spapr)); cpu_ppc_hypercall = emulate_spapr_hypercall; @@ -360,15 +359,14 @@ static void ppc_spapr_init(ram_addr_t ram_size, /* Set up VIO bus */ spapr-vio_bus = spapr_vio_bus_init(); -for (i = 0; i MAX_SERIAL_PORTS; i++, irq++) { +for (i = 0; i MAX_SERIAL_PORTS; i++) { if (serial_hds[i]) { spapr_vty_create(spapr-vio_bus, SPAPR_VTY_BASE_ADDRESS + i, - serial_hds[i], xics_find_qirq(spapr-icp, irq), - irq); + serial_hds[i]); } } -for (i = 0; i nb_nics; i++, irq++) { +for (i = 0; i nb_nics; i++) { NICInfo *nd =nd_table[i]; if (!nd-model) { @@ -376,8 +374,7 @@ static void ppc_spapr_init(ram_addr_t ram_size, } if (strcmp(nd-model, ibmveth) == 0) { -spapr_vlan_create(spapr-vio_bus, 0x1000 + i, nd, - xics_find_qirq(spapr-icp, irq), irq); +spapr_vlan_create(spapr-vio_bus, 0x1000 + i, nd); } else { fprintf(stderr, pSeries (sPAPR) platform does not support NIC model '%s' (only ibmveth is supported)\n, @@ -387,9 +384,7 @@ static void ppc_spapr_init(ram_addr_t ram_size, } for (i = 0; i= drive_get_max_bus(IF_SCSI); i++) { -spapr_vscsi_create(spapr-vio_bus, 0x2000 + i, - xics_find_qirq(spapr-icp, irq), irq); -irq++; +spapr_vscsi_create(spapr-vio_bus, 0x2000 + i); } if (kernel_filename) { diff --git a/hw/spapr.h b/hw/spapr.h index b52133a..4130c13 100644 --- a/hw/spapr.h +++ b/hw/spapr.h @@ -278,6 +278,12 @@ void spapr_register_hypercall(target_ulong opcode, spapr_hcall_fn fn); target_ulong spapr_hypercall(CPUState *env, target_ulong opcode, target_ulong *args); +static inline qemu_irq *spapr_find_qirq(sPAPREnvironment *spapr, +int irq_num) +{ +return xics_find_qirq(spapr-icp, irq_num); +} + This breaks with current HEAD. I've added a fix to my tree: diff --git a/hw/spapr.h b/hw/spapr.h index 4130c13..a725d4a 100644 --- a/hw/spapr.h +++ b/hw/spapr.h @@ -1,6 +1,8 @@ #if !defined(__HW_SPAPR_H__) #define __HW_SPAPR_H__ +#include hw/xics.h + struct VIOsPAPRBus; struct icp_state; @@ -278,7 +280,7 @@ void spapr_register_hypercall(target_ulong opcode, spapr_hcall_fn fn); target_ulong spapr_hypercall(CPUState *env, target_ulong opcode, target_ulong *args); -static inline qemu_irq *spapr_find_qirq(sPAPREnvironment *spapr, +static inline qemu_irq spapr_find_qirq(sPAPREnvironment *spapr, int irq_num) { return xics_find_qirq(spapr-icp, irq_num); Alex
Re: [Qemu-devel] [PATCH v5 05/18] qapi: add QMP input visitor
On 07/07/2011 09:32 AM, Luiz Capitulino wrote: On Tue, 5 Jul 2011 08:02:32 -0500 Michael Rothmdr...@linux.vnet.ibm.com wrote: A type of Visiter class that is used to walk a qobject's structure and assign each entry to the corresponding native C type. Command marshaling function will use this to pull out QMP command parameters recieved over the wire and pass them as native arguments to the corresponding C functions. Signed-off-by: Michael Rothmdr...@linux.vnet.ibm.com --- Makefile.objs|2 +- qapi/qmp-input-visitor.c | 264 ++ qapi/qmp-input-visitor.h | 27 + qerror.h |3 + 4 files changed, 295 insertions(+), 1 deletions(-) create mode 100644 qapi/qmp-input-visitor.c create mode 100644 qapi/qmp-input-visitor.h diff --git a/Makefile.objs b/Makefile.objs index 0077014..997ecef 100644 --- a/Makefile.objs +++ b/Makefile.objs @@ -375,7 +375,7 @@ libcacard-y = cac.o event.o vcard.o vreader.o vcard_emul_nss.o vcard_emul_type.o ## # qapi -qapi-nested-y = qapi-visit-core.o +qapi-nested-y = qapi-visit-core.o qmp-input-visitor.o qapi-obj-y = $(addprefix qapi/, $(qapi-nested-y)) vl.o: QEMU_CFLAGS+=$(GPROF_CFLAGS) diff --git a/qapi/qmp-input-visitor.c b/qapi/qmp-input-visitor.c new file mode 100644 index 000..80912bb --- /dev/null +++ b/qapi/qmp-input-visitor.c @@ -0,0 +1,264 @@ +/* + * Input Visitor + * + * Copyright IBM, Corp. 2011 + * + * Authors: + * Anthony Liguorialigu...@us.ibm.com + * + * This work is licensed under the terms of the GNU LGPL, version 2.1 or later. + * See the COPYING.LIB file in the top-level directory. + * + */ + +#include qmp-input-visitor.h +#include qemu-queue.h +#include qemu-common.h +#include qemu-objects.h +#include qerror.h + +#define QIV_STACK_SIZE 1024 + +typedef struct StackObject +{ +const QObject *obj; +const QListEntry *entry; +} StackObject; + +struct QmpInputVisitor +{ +Visitor visitor; +const QObject *obj; +StackObject stack[QIV_STACK_SIZE]; +int nb_stack; +}; + +static QmpInputVisitor *to_qiv(Visitor *v) +{ +return container_of(v, QmpInputVisitor, visitor); +} + +static const QObject *qmp_input_get_object(QmpInputVisitor *qiv, const char *name) +{ +const QObject *qobj; + +if (qiv-nb_stack == 0) { +qobj = qiv-obj; +} else { +qobj = qiv-stack[qiv-nb_stack - 1].obj; +} + +if (name qobject_type(qobj) == QTYPE_QDICT) { +return qdict_get(qobject_to_qdict(qobj), name); +} else if (qiv-nb_stack 0 qobject_type(qobj) == QTYPE_QLIST) { +return qlist_entry_obj(qiv-stack[qiv-nb_stack - 1].entry); +} + +return qobj; +} + +static void qmp_input_push(QmpInputVisitor *qiv, const QObject *obj, Error **errp) +{ +qiv-stack[qiv-nb_stack].obj = obj; +if (qobject_type(obj) == QTYPE_QLIST) { +qiv-stack[qiv-nb_stack].entry = qlist_first(qobject_to_qlist(obj)); +} +qiv-nb_stack++; + +if (qiv-nb_stack= QIV_STACK_SIZE) { +error_set(errp, QERR_BUFFER_OVERRUN); +return; +} +} + +static void qmp_input_pop(QmpInputVisitor *qiv, Error **errp) +{ +qiv-nb_stack--; +if (qiv-nb_stack 0) { +error_set(errp, QERR_BUFFER_OVERRUN); +return; +} +} + +static void qmp_input_start_struct(Visitor *v, void **obj, const char *kind, const char *name, size_t size, Error **errp) +{ +QmpInputVisitor *qiv = to_qiv(v); +const QObject *qobj = qmp_input_get_object(qiv, name); + +if (!qobj || qobject_type(qobj) != QTYPE_QDICT) { +error_set(errp, QERR_INVALID_PARAMETER_TYPE, name ? name : null, QDict); +return; +} + +qmp_input_push(qiv, qobj, errp); +if (error_is_set(errp)) { +return; +} + +if (obj) { +*obj = qemu_mallocz(size); +} +} + +static void qmp_input_end_struct(Visitor *v, Error **errp) +{ +QmpInputVisitor *qiv = to_qiv(v); + +qmp_input_pop(qiv, errp); +} + +static void qmp_input_start_list(Visitor *v, const char *name, Error **errp) +{ +QmpInputVisitor *qiv = to_qiv(v); +const QObject *qobj = qmp_input_get_object(qiv, name); + +if (!qobj || qobject_type(qobj) != QTYPE_QLIST) { +error_set(errp, QERR_INVALID_PARAMETER_TYPE, name ? name : null, list); +return; +} + +qmp_input_push(qiv, qobj, errp); +} + +static GenericList *qmp_input_next_list(Visitor *v, GenericList **list, Error **errp) +{ +QmpInputVisitor *qiv = to_qiv(v); +GenericList *entry; +StackObject *so =qiv-stack[qiv-nb_stack - 1]; + +if (so-entry == NULL) { +return NULL; +} + +entry = qemu_mallocz(sizeof(*entry)); +if (*list) { +so-entry = qlist_next(so-entry); +if (so-entry == NULL) { +qemu_free(entry); +return NULL; +} +(*list)-next = entry; +} +*list = entry; + + +return entry; +} + +static
[Qemu-devel] [PATCH 3/3] qemu-x86: Set tsc_khz in kvm when supported
Make use of the KVM_TSC_CONTROL feature if available. Signed-off-by: Joerg Roedel joerg.roe...@amd.com --- target-i386/kvm.c | 18 +- 1 files changed, 17 insertions(+), 1 deletions(-) diff --git a/target-i386/kvm.c b/target-i386/kvm.c index 10fb2c4..923d2d5 100644 --- a/target-i386/kvm.c +++ b/target-i386/kvm.c @@ -354,6 +354,7 @@ int kvm_arch_init_vcpu(CPUState *env) uint32_t unused; struct kvm_cpuid_entry2 *c; uint32_t signature[3]; +int r; env-cpuid_features = kvm_arch_get_supported_cpuid(s, 1, 0, R_EDX); @@ -499,7 +500,22 @@ int kvm_arch_init_vcpu(CPUState *env) qemu_add_vm_change_state_handler(cpu_update_state, env); -return kvm_vcpu_ioctl(env, KVM_SET_CPUID2, cpuid_data); +r = kvm_vcpu_ioctl(env, KVM_SET_CPUID2, cpuid_data); +if (r) + return r; + +#ifdef KVM_CAP_TSC_CONTROL +r = kvm_check_extension(env-kvm_state, KVM_CAP_TSC_CONTROL); +if (r env-tsc_khz) { +r = kvm_vcpu_ioctl(env, KVM_SET_TSC_KHZ, env-tsc_khz); +if (r 0) { +fprintf(stderr, KVM_SET_TSC_KHZ failed\n); +return r; +} +} +#endif + +return 0; } void kvm_arch_reset_vcpu(CPUState *env) -- 1.7.4.1
Re: [Qemu-devel] [QAPI+QGA 2/3] QAPI code generation infrastructure v5
On Tue, 5 Jul 2011 08:02:27 -0500 Michael Roth mdr...@linux.vnet.ibm.com wrote: This is Set 2/3 of the QAPI+QGA patchsets. These patches apply on top of master (set1 merged), and can also be obtained from: git://repo.or.cz/qemu/mdroth.git qapi-backport-set2-v5 This doesn't build due to a bug in error.h. If you didn't get it you're probably testing against a not up to date branch... I have the fix for error.h and will submit it. Only a few small issues remain, I think the next version will be good to go, although I'd only merge it along with the guest agent patches. (Set1+2 are a backport of some of the QAPI-related work from Anthony's glib tree. The main goal is to get the basic code generation infrastructure in place so that it can be used by the guest agent to implement a QMP-like guest interface, and so that future work regarding the QMP conversion to QAPI can be decoupled from the infrastructure bits. Set3 is the Qemu Guest Agent (virtagent), rebased on the new code QAPI code generation infrastructure. This is the first user of QAPI, QMP will follow.) ___ This patchset introduces the following: - Hard dependency on GLib. This has been floating around the list for a while. Currently the only users are the unit tests for this patchset and the guest agent. We can make both of these a configure option, but based on previous discussions a hard dependency will likely be introduced with subsequent QAPI patches. - A couple additional qlist utility functions used by QAPI. - QAPI schema-based code generation for synchronous QMP/QGA commands and types, and Visitor/dispatch infrastructure to handle marshaling/unmarshaling/dispatch between QAPI and the QMP/QGA wire protocols. - Documentation and unit tests for visitor functions and synchronous command/type generation. CHANGES SINCE V4: - Fix segfault in output visitor when dealing with QAPI-defined C structs with NULL pointers CHANGES SINCE V3: - Added copyright headers for generated code and remaining files - Added checking for required/extra parameters in top-level of QMP QObject - Made QDict arg to input visitor constructor a const - Renamed qmp_dispatch_err() - do_qmp_dispatch() - Changed QERR_QAPI_STACK_OVERRUN to QERR_BUFFER_OVERRUN - Moved configure changes to create QAPI directory when using a different build root to first patch which uses it. - Squashed Makefile changes for test-visitor/test-qmp-commands into single commits - Removed redundant NULL checks for qemu_free() in dealloc visitor CHANGES SINCE V2: - Added cleanup functions for input/output visitor types and fixed a leak in dispatch path. - Corrected spelling from visiter-visitor and updated filenames accordingly. - Re-organized patches so that each new C file can be built as part of the introducting commit (for instances where there were no users of the qapi-obj-y target yet a test build was done by adding the target as a superficial dependency on other tools), and moved code generator patches after the required dependencies. - Made qlist_first/qlist_next accept/return const types. - Moved Visitor interface inline wrapper functions to real ones. - Fixed error-reporting for invalid parameters when parameter name is null. - Removed hard-coded size for QAPI-type allocations done by the input visitor, using generated code to pass in a sizeof() now. - Replaced assert()'s on visitor stack overruns, replaced with an error indication. - Fixed build issue when using a separate build directory. - Added missing copyright headers for scripts, moved external code in ordereddict.py to a seperate patch. - Many thanks to Luiz, Anthony, and everyone else for the excellent review/testing. CHANGES SINCE V1: - Fixed build issue that was missed due to deprecated files being present in source tree. Thanks to Matsuda Daiki for sending fixes. - Fixed grammatical errors in documentation pointed out by Luiz. - Added generated code to the make clean target. CHANGES SINCE V0 (QAPI Infrastructure Round 1): - Fixed known memory leaks in generated code - Stricter error-handling in generated code - Removed currently unused code (generators for events and async/proxied QMP/QGA commands and definition used by the not-yet-introduced QMP server replacement) - Added documentation for code generation scripts/schemas/usage - Addressed review comments from Luiz and Stefan Makefile| 24 +++- Makefile.objs |9 + Makefile.target |1 + configure | 14 ++ docs/qapi-code-gen.txt | 316 +++ module.h|2 + qapi-schema-test.json | 22 +++ qapi/qapi-dealloc-visitor.c | 138 qapi/qapi-dealloc-visitor.h | 26 +++ qapi/qapi-types-core.h | 21 +++
Re: [Qemu-devel] [PATCH v5 05/18] qapi: add QMP input visitor
On Tue, 5 Jul 2011 08:02:32 -0500 Michael Roth mdr...@linux.vnet.ibm.com wrote: A type of Visiter class that is used to walk a qobject's structure and assign each entry to the corresponding native C type. Command marshaling function will use this to pull out QMP command parameters recieved over the wire and pass them as native arguments to the corresponding C functions. Signed-off-by: Michael Roth mdr...@linux.vnet.ibm.com --- Makefile.objs|2 +- qapi/qmp-input-visitor.c | 264 ++ qapi/qmp-input-visitor.h | 27 + qerror.h |3 + 4 files changed, 295 insertions(+), 1 deletions(-) create mode 100644 qapi/qmp-input-visitor.c create mode 100644 qapi/qmp-input-visitor.h diff --git a/Makefile.objs b/Makefile.objs index 0077014..997ecef 100644 --- a/Makefile.objs +++ b/Makefile.objs @@ -375,7 +375,7 @@ libcacard-y = cac.o event.o vcard.o vreader.o vcard_emul_nss.o vcard_emul_type.o ## # qapi -qapi-nested-y = qapi-visit-core.o +qapi-nested-y = qapi-visit-core.o qmp-input-visitor.o qapi-obj-y = $(addprefix qapi/, $(qapi-nested-y)) vl.o: QEMU_CFLAGS+=$(GPROF_CFLAGS) diff --git a/qapi/qmp-input-visitor.c b/qapi/qmp-input-visitor.c new file mode 100644 index 000..80912bb --- /dev/null +++ b/qapi/qmp-input-visitor.c @@ -0,0 +1,264 @@ +/* + * Input Visitor + * + * Copyright IBM, Corp. 2011 + * + * Authors: + * Anthony Liguori aligu...@us.ibm.com + * + * This work is licensed under the terms of the GNU LGPL, version 2.1 or later. + * See the COPYING.LIB file in the top-level directory. + * + */ + +#include qmp-input-visitor.h +#include qemu-queue.h +#include qemu-common.h +#include qemu-objects.h +#include qerror.h + +#define QIV_STACK_SIZE 1024 + +typedef struct StackObject +{ +const QObject *obj; +const QListEntry *entry; +} StackObject; + +struct QmpInputVisitor +{ +Visitor visitor; +const QObject *obj; +StackObject stack[QIV_STACK_SIZE]; +int nb_stack; +}; + +static QmpInputVisitor *to_qiv(Visitor *v) +{ +return container_of(v, QmpInputVisitor, visitor); +} + +static const QObject *qmp_input_get_object(QmpInputVisitor *qiv, const char *name) +{ +const QObject *qobj; + +if (qiv-nb_stack == 0) { +qobj = qiv-obj; +} else { +qobj = qiv-stack[qiv-nb_stack - 1].obj; +} + +if (name qobject_type(qobj) == QTYPE_QDICT) { +return qdict_get(qobject_to_qdict(qobj), name); +} else if (qiv-nb_stack 0 qobject_type(qobj) == QTYPE_QLIST) { +return qlist_entry_obj(qiv-stack[qiv-nb_stack - 1].entry); +} + +return qobj; +} + +static void qmp_input_push(QmpInputVisitor *qiv, const QObject *obj, Error **errp) +{ +qiv-stack[qiv-nb_stack].obj = obj; +if (qobject_type(obj) == QTYPE_QLIST) { +qiv-stack[qiv-nb_stack].entry = qlist_first(qobject_to_qlist(obj)); +} +qiv-nb_stack++; + +if (qiv-nb_stack = QIV_STACK_SIZE) { +error_set(errp, QERR_BUFFER_OVERRUN); +return; +} +} + +static void qmp_input_pop(QmpInputVisitor *qiv, Error **errp) +{ +qiv-nb_stack--; +if (qiv-nb_stack 0) { +error_set(errp, QERR_BUFFER_OVERRUN); +return; +} +} + +static void qmp_input_start_struct(Visitor *v, void **obj, const char *kind, const char *name, size_t size, Error **errp) +{ +QmpInputVisitor *qiv = to_qiv(v); +const QObject *qobj = qmp_input_get_object(qiv, name); + +if (!qobj || qobject_type(qobj) != QTYPE_QDICT) { +error_set(errp, QERR_INVALID_PARAMETER_TYPE, name ? name : null, QDict); +return; +} + +qmp_input_push(qiv, qobj, errp); +if (error_is_set(errp)) { +return; +} + +if (obj) { +*obj = qemu_mallocz(size); +} +} + +static void qmp_input_end_struct(Visitor *v, Error **errp) +{ +QmpInputVisitor *qiv = to_qiv(v); + +qmp_input_pop(qiv, errp); +} + +static void qmp_input_start_list(Visitor *v, const char *name, Error **errp) +{ +QmpInputVisitor *qiv = to_qiv(v); +const QObject *qobj = qmp_input_get_object(qiv, name); + +if (!qobj || qobject_type(qobj) != QTYPE_QLIST) { +error_set(errp, QERR_INVALID_PARAMETER_TYPE, name ? name : null, list); +return; +} + +qmp_input_push(qiv, qobj, errp); +} + +static GenericList *qmp_input_next_list(Visitor *v, GenericList **list, Error **errp) +{ +QmpInputVisitor *qiv = to_qiv(v); +GenericList *entry; +StackObject *so = qiv-stack[qiv-nb_stack - 1]; + +if (so-entry == NULL) { +return NULL; +} + +entry = qemu_mallocz(sizeof(*entry)); +if (*list) { +so-entry = qlist_next(so-entry); +if (so-entry == NULL) { +qemu_free(entry);
Re: [Qemu-devel] [PATCH v3 0/3] spapr qdevification
On 07/06/2011 01:32 PM, Paolo Bonzini wrote: On 06/06/2011 04:16 PM, Paolo Bonzini wrote: This series fixes some problems with spapr's qdev interface. Patch 1 is the important one, which makes it possible to use -device to create vio devices. The other two are cosmetic. v1-v2: abstracted the call to xics_find_qirq behind spapr_find_qirq v2-v3: undid v1-v2 change, introduced spapr_allocate_irq Ping? Thanks, applied to ppc-next :) Alex
Re: [Qemu-devel] [PATCH v5 04/18] qapi: add QAPI visitor core
On Tue, 5 Jul 2011 08:02:31 -0500 Michael Roth mdr...@linux.vnet.ibm.com wrote: Base definitions/includes for Visiter interface used by generated visiter/marshalling code. Includes a GenericList type. Our lists require an embedded element. Since these types are generated, if you want to use them in a different type of data structure, there's no easy way to add another embedded element. The solution is to have non-embedded lists and that what this is. Signed-off-by: Michael Roth mdr...@linux.vnet.ibm.com --- Makefile.objs |6 +++ configure |1 + qapi/qapi-types-core.h | 21 + qapi/qapi-visit-core.c | 114 qapi/qapi-visit-core.h | 68 5 files changed, 210 insertions(+), 0 deletions(-) create mode 100644 qapi/qapi-types-core.h create mode 100644 qapi/qapi-visit-core.c create mode 100644 qapi/qapi-visit-core.h diff --git a/Makefile.objs b/Makefile.objs index 493c988..0077014 100644 --- a/Makefile.objs +++ b/Makefile.objs @@ -372,6 +372,12 @@ endif libcacard-y = cac.o event.o vcard.o vreader.o vcard_emul_nss.o vcard_emul_type.o card_7816.o +## +# qapi + +qapi-nested-y = qapi-visit-core.o +qapi-obj-y = $(addprefix qapi/, $(qapi-nested-y)) qapi-obj-y has to included in common-obj-y, no? I'd also move this up in this file (where others modulename-obj-y are located). + vl.o: QEMU_CFLAGS+=$(GPROF_CFLAGS) vl.o: QEMU_CFLAGS+=$(SDL_CFLAGS) diff --git a/configure b/configure index 63156a2..02c552e 100755 --- a/configure +++ b/configure @@ -3486,6 +3486,7 @@ DIRS=tests tests/cris slirp audio block net pc-bios/optionrom DIRS=$DIRS pc-bios/spapr-rtas DIRS=$DIRS roms/seabios roms/vgabios DIRS=$DIRS fsdev ui +DIRS=$DIRS qapi FILES=Makefile tests/Makefile FILES=$FILES tests/cris/Makefile tests/cris/.gdbinit FILES=$FILES pc-bios/optionrom/Makefile pc-bios/keymaps diff --git a/qapi/qapi-types-core.h b/qapi/qapi-types-core.h new file mode 100644 index 000..de733ab --- /dev/null +++ b/qapi/qapi-types-core.h @@ -0,0 +1,21 @@ +/* + * Core Definitions for QAPI-generated Types + * + * Copyright IBM, Corp. 2011 + * + * Authors: + * Anthony Liguori aligu...@us.ibm.com + * + * This work is licensed under the terms of the GNU LGPL, version 2.1 or later. + * See the COPYING.LIB file in the top-level directory. + * + */ + +#ifndef QAPI_TYPES_CORE_H +#define QAPI_TYPES_CORE_H + +#include stdbool.h +#include stdint.h +#include error.h + +#endif diff --git a/qapi/qapi-visit-core.c b/qapi/qapi-visit-core.c new file mode 100644 index 000..c8a7805 --- /dev/null +++ b/qapi/qapi-visit-core.c @@ -0,0 +1,114 @@ +/* + * Core Definitions for QAPI Visitor Classes + * + * Copyright IBM, Corp. 2011 + * + * Authors: + * Anthony Liguori aligu...@us.ibm.com + * + * This work is licensed under the terms of the GNU LGPL, version 2.1 or later. + * See the COPYING.LIB file in the top-level directory. + * + */ + +#include qapi/qapi-visit-core.h + +void visit_start_handle(Visitor *v, void **obj, const char *kind, const char *name, Error **errp) +{ +if (!error_is_set(errp) v-start_handle) { +v-start_handle(v, obj, kind, name, errp); +} +} + +void visit_end_handle(Visitor *v, Error **errp) +{ +if (!error_is_set(errp) v-end_handle) { +v-end_handle(v, errp); +} +} + +void visit_start_struct(Visitor *v, void **obj, const char *kind, const char *name, size_t size, Error **errp) +{ +if (!error_is_set(errp)) { +v-start_struct(v, obj, kind, name, size, errp); +} +} + +void visit_end_struct(Visitor *v, Error **errp) +{ +if (!error_is_set(errp)) { +v-end_struct(v, errp); +} +} + +void visit_start_list(Visitor *v, const char *name, Error **errp) +{ +if (!error_is_set(errp)) { +v-start_list(v, name, errp); +} +} + +GenericList *visit_next_list(Visitor *v, GenericList **list, Error **errp) +{ +if (!error_is_set(errp)) { +return v-next_list(v, list, errp); +} + +return 0; +} + +void visit_end_list(Visitor *v, Error **errp) +{ +if (!error_is_set(errp)) { +v-end_list(v, errp); +} +} + +void visit_start_optional(Visitor *v, bool *present, const char *name, Error **errp) +{ +if (!error_is_set(errp) v-start_optional) { +v-start_optional(v, present, name, errp); +} +} + +void visit_end_optional(Visitor *v, Error **errp) +{ +if (!error_is_set(errp) v-end_optional) { +v-end_optional(v, errp); +} +} + +void visit_type_enum(Visitor *v, int *obj, const char *kind, const char *name, Error **errp) +{ +if (!error_is_set(errp)) { +v-type_enum(v, obj, kind, name, errp); +} +} + +void visit_type_int(Visitor *v, int64_t
Re: [Qemu-devel] [QAPI+QGA 2/3] QAPI code generation infrastructure v5
On 07/07/2011 09:37 AM, Luiz Capitulino wrote: On Tue, 5 Jul 2011 08:02:27 -0500 Michael Rothmdr...@linux.vnet.ibm.com wrote: This is Set 2/3 of the QAPI+QGA patchsets. These patches apply on top of master (set1 merged), and can also be obtained from: git://repo.or.cz/qemu/mdroth.git qapi-backport-set2-v5 This doesn't build due to a bug in error.h. If you didn't get it you're probably testing against a not up to date branch... I have the fix for error.h and will submit it. Only a few small issues remain, I think the next version will be good to go, although I'd only merge it along with the guest agent patches. Doh, I see it too. I must've missed a build test after rebasing on master. I'll keep an eye out for your patch, thanks! (Set1+2 are a backport of some of the QAPI-related work from Anthony's glib tree. The main goal is to get the basic code generation infrastructure in place so that it can be used by the guest agent to implement a QMP-like guest interface, and so that future work regarding the QMP conversion to QAPI can be decoupled from the infrastructure bits. Set3 is the Qemu Guest Agent (virtagent), rebased on the new code QAPI code generation infrastructure. This is the first user of QAPI, QMP will follow.) ___ This patchset introduces the following: - Hard dependency on GLib. This has been floating around the list for a while. Currently the only users are the unit tests for this patchset and the guest agent. We can make both of these a configure option, but based on previous discussions a hard dependency will likely be introduced with subsequent QAPI patches. - A couple additional qlist utility functions used by QAPI. - QAPI schema-based code generation for synchronous QMP/QGA commands and types, and Visitor/dispatch infrastructure to handle marshaling/unmarshaling/dispatch between QAPI and the QMP/QGA wire protocols. - Documentation and unit tests for visitor functions and synchronous command/type generation. CHANGES SINCE V4: - Fix segfault in output visitor when dealing with QAPI-defined C structs with NULL pointers CHANGES SINCE V3: - Added copyright headers for generated code and remaining files - Added checking for required/extra parameters in top-level of QMP QObject - Made QDict arg to input visitor constructor a const - Renamed qmp_dispatch_err() - do_qmp_dispatch() - Changed QERR_QAPI_STACK_OVERRUN to QERR_BUFFER_OVERRUN - Moved configure changes to create QAPI directory when using a different build root to first patch which uses it. - Squashed Makefile changes for test-visitor/test-qmp-commands into single commits - Removed redundant NULL checks for qemu_free() in dealloc visitor CHANGES SINCE V2: - Added cleanup functions for input/output visitor types and fixed a leak in dispatch path. - Corrected spelling from visiter-visitor and updated filenames accordingly. - Re-organized patches so that each new C file can be built as part of the introducting commit (for instances where there were no users of the qapi-obj-y target yet a test build was done by adding the target as a superficial dependency on other tools), and moved code generator patches after the required dependencies. - Made qlist_first/qlist_next accept/return const types. - Moved Visitor interface inline wrapper functions to real ones. - Fixed error-reporting for invalid parameters when parameter name is null. - Removed hard-coded size for QAPI-type allocations done by the input visitor, using generated code to pass in a sizeof() now. - Replaced assert()'s on visitor stack overruns, replaced with an error indication. - Fixed build issue when using a separate build directory. - Added missing copyright headers for scripts, moved external code in ordereddict.py to a seperate patch. - Many thanks to Luiz, Anthony, and everyone else for the excellent review/testing. CHANGES SINCE V1: - Fixed build issue that was missed due to deprecated files being present in source tree. Thanks to Matsuda Daiki for sending fixes. - Fixed grammatical errors in documentation pointed out by Luiz. - Added generated code to the make clean target. CHANGES SINCE V0 (QAPI Infrastructure Round 1): - Fixed known memory leaks in generated code - Stricter error-handling in generated code - Removed currently unused code (generators for events and async/proxied QMP/QGA commands and definition used by the not-yet-introduced QMP server replacement) - Added documentation for code generation scripts/schemas/usage - Addressed review comments from Luiz and Stefan Makefile| 24 +++- Makefile.objs |9 + Makefile.target |1 + configure | 14 ++ docs/qapi-code-gen.txt | 316 +++ module.h|2 + qapi-schema-test.json | 22 +++
Re: [Qemu-devel] [SeaBIOS] [PATCH V5 0/9] Add TPM support to SeaBIOS
On 07/07/2011 08:43 AM, Kevin O'Connor wrote: On Thu, Jul 07, 2011 at 07:48:29AM -0400, Stefan Berger wrote: On 07/06/2011 06:58 PM, Kevin O'Connor wrote: BTW, I don't think patch 7 or 9 really make sense to integrate in the official version of SeaBIOS. Also, in patch 8, I'd prefer to see all new fw_cfg entries use the romfile mechanism. Patch 7 is the menu. This patch is needed in 'some form' since in some cases, like after giving up ownership of the TPM, the TPM becomes disabled and deactivated and one has to interact with the BIOS to activate and enable it again. Other scenarios include someone who has forgotten the owner password for the TPM and now has to go through the BIOS to give up ownership of it -- that's the only way one can do this then. Hrmm. I don't recall seeing this menu on the factory BIOS of real machines. How do normal users interact with it? Everyone has to go through the BIOS menu to maybe even enable and activate the TPM before first use. It's typically under 'security'. Can the info be passed in from QEmu? To a certain limit, yes. I have an experimental patch that allows one to pass in a parameter via command line to Qemu which then passes this parameter on to the BIOS via the firmware interface. It tells the BIOS what it should do with the TPM upon VM startup / reboot. I can for example tell it to always enable and activate the TPM so that the user doesn't have to go through the BIOS once he gave up ownership of the device. However, I cannot tell the BIOS to give up ownership every time there is a startup/reboot since otherwise all keys that the TPM owner generated will be lost. So the case where the user forgot his password is problematic and in that case he would have to get to the BIOS menu, give up ownership and then boot the machine again. The reason is that only during an early bootup the TPM is in a state that would allow certain commands to be sent that among other things allow giving up ownership. I'll have a look at the 'romfile' mechanism for patch 8. I only post patch 9 for someone who is interested to be able to run the tests. Since the 128kb are slowly filling up, it's not going to be compilable with it for much longer and I don't expect it to go into the repo. So regarding the romfile mechanism for patch 8: In patch 8 I (expect Qemu to) hash for example files passed via -kernel, -initrd and data provided via -append or modules in case of multiboot, write them into concatenated data structures and pass the byte array to the firmware interface for SeaBIOS to pick up. Now with the romfile mechanism I have the impression that these are more or less static data, whereas what is happening in patch 8 depends on the parameters pass to qemu. Here an example for such a command line when Qemu starts in this type of paravirtualized mode: qemu -kernel /boot/vmlinuz-2.6.36 -initrd /boot/initrd-2.6.36 -append ro [...] [...] In effect Qemu does a sha1sum /boot/vmlinuz-2.6.36 sha1sum /boot/initrd-2.6.36 echo -n ro [...] | sha1sum and logs what it measured, i.e., kernel, initrd, or command line. And here's the corresponding patch for Qemu: http://www.mail-archive.com/qemu-devel@nongnu.org/msg69677.html There is no limit at 128K - if it's exceeded the build will start using a 256K rom. Good to know. Stefan More important than the total size is the fixed size reported at the end of the build - that's how much space is used under 1 Meg after the post phase completes. Ideally it would stay under 64K though that's not a hard limit either. -Kevin
Re: [Qemu-devel] migration: new sections and backward compatibility.
On 07/07/2011 04:23 AM, Markus Armbruster wrote: Anthony Liguorianth...@codemonkey.ws writes: On 07/06/2011 11:04 AM, Gerd Hoffmann wrote: Hi folks, We'll need to figure a sane way to handle migration to older versions with new sections, i.e. devices which used to not save state before do now. We already have one case in tree: usb. qemu 0.14 saves state for usb-hid devices and the usb-hub, whereas qemu 0.13 and older don't. You can't migrate a vm with a usb-tablet from 0.14 to 0.13 because of that even if you use -M pc-0.13. Because if you did migrate, you would actively break the guest during migration. So why is this a problem? This comes up a lot. We shouldn't enable migration if we know the guest is going to break during migration. That's a feature, not a bug. Not so fast :) I agree that throwing away unrecognized migration data is unsafe, and should not be done. Now let me present my little problem. I'm working on making migration preserve tray status: open/closed, locked/unlocked. For ide-cd, I can stick a subsection ide_drive/tray_state into section ide_drive. Needed only if the tray is open or locked. This gives users a chance to migrate to older versions, and is perfectly safe. scsi-cd doesn't have a section, yet. What now? Is that because 'scsi-cd' doesn't need a section or because it hasn't been implemented yet? Regards, Anthony Liguori
Re: [Qemu-devel] [PATCH v5 04/18] qapi: add QAPI visitor core
On 07/07/2011 09:32 AM, Luiz Capitulino wrote: On Tue, 5 Jul 2011 08:02:31 -0500 Michael Rothmdr...@linux.vnet.ibm.com wrote: Base definitions/includes for Visiter interface used by generated visiter/marshalling code. Includes a GenericList type. Our lists require an embedded element. Since these types are generated, if you want to use them in a different type of data structure, there's no easy way to add another embedded element. The solution is to have non-embedded lists and that what this is. Signed-off-by: Michael Rothmdr...@linux.vnet.ibm.com --- Makefile.objs |6 +++ configure |1 + qapi/qapi-types-core.h | 21 + qapi/qapi-visit-core.c | 114 qapi/qapi-visit-core.h | 68 5 files changed, 210 insertions(+), 0 deletions(-) create mode 100644 qapi/qapi-types-core.h create mode 100644 qapi/qapi-visit-core.c create mode 100644 qapi/qapi-visit-core.h diff --git a/Makefile.objs b/Makefile.objs index 493c988..0077014 100644 --- a/Makefile.objs +++ b/Makefile.objs @@ -372,6 +372,12 @@ endif libcacard-y = cac.o event.o vcard.o vreader.o vcard_emul_nss.o vcard_emul_type.o card_7816.o +## +# qapi + +qapi-nested-y = qapi-visit-core.o +qapi-obj-y = $(addprefix qapi/, $(qapi-nested-y)) qapi-obj-y has to included in common-obj-y, no? I'd also move this up in this file (where others modulename-obj-y are located). Eventually, when we do the full QMP conversion. But for now, only the guest agent pulls these in. I'll move the block up. + vl.o: QEMU_CFLAGS+=$(GPROF_CFLAGS) vl.o: QEMU_CFLAGS+=$(SDL_CFLAGS) diff --git a/configure b/configure index 63156a2..02c552e 100755 --- a/configure +++ b/configure @@ -3486,6 +3486,7 @@ DIRS=tests tests/cris slirp audio block net pc-bios/optionrom DIRS=$DIRS pc-bios/spapr-rtas DIRS=$DIRS roms/seabios roms/vgabios DIRS=$DIRS fsdev ui +DIRS=$DIRS qapi FILES=Makefile tests/Makefile FILES=$FILES tests/cris/Makefile tests/cris/.gdbinit FILES=$FILES pc-bios/optionrom/Makefile pc-bios/keymaps diff --git a/qapi/qapi-types-core.h b/qapi/qapi-types-core.h new file mode 100644 index 000..de733ab --- /dev/null +++ b/qapi/qapi-types-core.h @@ -0,0 +1,21 @@ +/* + * Core Definitions for QAPI-generated Types + * + * Copyright IBM, Corp. 2011 + * + * Authors: + * Anthony Liguorialigu...@us.ibm.com + * + * This work is licensed under the terms of the GNU LGPL, version 2.1 or later. + * See the COPYING.LIB file in the top-level directory. + * + */ + +#ifndef QAPI_TYPES_CORE_H +#define QAPI_TYPES_CORE_H + +#includestdbool.h +#includestdint.h +#include error.h + +#endif diff --git a/qapi/qapi-visit-core.c b/qapi/qapi-visit-core.c new file mode 100644 index 000..c8a7805 --- /dev/null +++ b/qapi/qapi-visit-core.c @@ -0,0 +1,114 @@ +/* + * Core Definitions for QAPI Visitor Classes + * + * Copyright IBM, Corp. 2011 + * + * Authors: + * Anthony Liguorialigu...@us.ibm.com + * + * This work is licensed under the terms of the GNU LGPL, version 2.1 or later. + * See the COPYING.LIB file in the top-level directory. + * + */ + +#include qapi/qapi-visit-core.h + +void visit_start_handle(Visitor *v, void **obj, const char *kind, const char *name, Error **errp) +{ +if (!error_is_set(errp) v-start_handle) { +v-start_handle(v, obj, kind, name, errp); +} +} + +void visit_end_handle(Visitor *v, Error **errp) +{ +if (!error_is_set(errp) v-end_handle) { +v-end_handle(v, errp); +} +} + +void visit_start_struct(Visitor *v, void **obj, const char *kind, const char *name, size_t size, Error **errp) +{ +if (!error_is_set(errp)) { +v-start_struct(v, obj, kind, name, size, errp); +} +} + +void visit_end_struct(Visitor *v, Error **errp) +{ +if (!error_is_set(errp)) { +v-end_struct(v, errp); +} +} + +void visit_start_list(Visitor *v, const char *name, Error **errp) +{ +if (!error_is_set(errp)) { +v-start_list(v, name, errp); +} +} + +GenericList *visit_next_list(Visitor *v, GenericList **list, Error **errp) +{ +if (!error_is_set(errp)) { +return v-next_list(v, list, errp); +} + +return 0; +} + +void visit_end_list(Visitor *v, Error **errp) +{ +if (!error_is_set(errp)) { +v-end_list(v, errp); +} +} + +void visit_start_optional(Visitor *v, bool *present, const char *name, Error **errp) +{ +if (!error_is_set(errp) v-start_optional) { +v-start_optional(v, present, name, errp); +} +} + +void visit_end_optional(Visitor *v, Error **errp) +{ +if (!error_is_set(errp) v-end_optional) { +v-end_optional(v, errp); +} +} + +void visit_type_enum(Visitor *v, int *obj, const char *kind, const char *name, Error **errp) +{ +if (!error_is_set(errp)) { +v-type_enum(v, obj, kind, name, errp); +} +} + +void visit_type_int(Visitor *v,
Re: [Qemu-devel] migration: new sections and backward compatibility.
Hi, Not so fast :) I agree that throwing away unrecognized migration data is unsafe, and should not be done. Now let me present my little problem. I'm working on making migration preserve tray status: open/closed, locked/unlocked. For ide-cd, I can stick a subsection ide_drive/tray_state into section ide_drive. Needed only if the tray is open or locked. This gives users a chance to migrate to older versions, and is perfectly safe. scsi-cd doesn't have a section, yet. What now? Experimental patch for usb attached (actually two, the first is pure code motion though so the second with the actual changes becomes more readable). That makes migration support switchable using a property, so we can use compatibility properties to disable sending the section to an older version. That requires usb-hid.c call vmstate_register manually. Not that nice. We could move the needed() callback from VMStateSubsection to VMStateDescription, so it is possible to send complete sections conditionally. Comments? cheers, Gerd From adf3fd9f870c5ce5566223e1edfb033c81bd01e4 Mon Sep 17 00:00:00 2001 From: Gerd Hoffmann kra...@redhat.com Date: Thu, 7 Jul 2011 15:49:54 +0200 Subject: [PATCH 1/2] move code --- hw/usb-hid.c | 86 +- 1 files changed, 43 insertions(+), 43 deletions(-) diff --git a/hw/usb-hid.c b/hw/usb-hid.c index d711b5c..f30c96b 100644 --- a/hw/usb-hid.c +++ b/hw/usb-hid.c @@ -854,49 +854,6 @@ static void usb_hid_handle_destroy(USBDevice *dev) } } -static int usb_hid_initfn(USBDevice *dev, int kind) -{ -USBHIDState *s = DO_UPCAST(USBHIDState, dev, dev); - -usb_desc_init(dev); -s-kind = kind; - -if (s-kind == USB_MOUSE) { -s-ptr.eh_entry = qemu_add_mouse_event_handler(usb_pointer_event, s, - 0, QEMU USB Mouse); -} else if (s-kind == USB_TABLET) { -s-ptr.eh_entry = qemu_add_mouse_event_handler(usb_pointer_event, s, - 1, QEMU USB Tablet); -} - -/* Force poll routine to be run and grab input the first time. */ -s-changed = 1; -return 0; -} - -static int usb_tablet_initfn(USBDevice *dev) -{ -return usb_hid_initfn(dev, USB_TABLET); -} - -static int usb_mouse_initfn(USBDevice *dev) -{ -return usb_hid_initfn(dev, USB_MOUSE); -} - -static int usb_keyboard_initfn(USBDevice *dev) -{ -return usb_hid_initfn(dev, USB_KEYBOARD); -} - -void usb_hid_datain_cb(USBDevice *dev, void *opaque, void (*datain)(void *)) -{ -USBHIDState *s = (USBHIDState *)dev; - -s-datain_opaque = opaque; -s-datain = datain; -} - static int usb_hid_post_load(void *opaque, int version_id) { USBHIDState *s = opaque; @@ -956,6 +913,49 @@ static const VMStateDescription vmstate_usb_kbd = { } }; +static int usb_hid_initfn(USBDevice *dev, int kind) +{ +USBHIDState *s = DO_UPCAST(USBHIDState, dev, dev); + +usb_desc_init(dev); +s-kind = kind; + +if (s-kind == USB_MOUSE) { +s-ptr.eh_entry = qemu_add_mouse_event_handler(usb_pointer_event, s, + 0, QEMU USB Mouse); +} else if (s-kind == USB_TABLET) { +s-ptr.eh_entry = qemu_add_mouse_event_handler(usb_pointer_event, s, + 1, QEMU USB Tablet); +} + +/* Force poll routine to be run and grab input the first time. */ +s-changed = 1; +return 0; +} + +static int usb_tablet_initfn(USBDevice *dev) +{ +return usb_hid_initfn(dev, USB_TABLET); +} + +static int usb_mouse_initfn(USBDevice *dev) +{ +return usb_hid_initfn(dev, USB_MOUSE); +} + +static int usb_keyboard_initfn(USBDevice *dev) +{ +return usb_hid_initfn(dev, USB_KEYBOARD); +} + +void usb_hid_datain_cb(USBDevice *dev, void *opaque, void (*datain)(void *)) +{ +USBHIDState *s = (USBHIDState *)dev; + +s-datain_opaque = opaque; +s-datain = datain; +} + static struct USBDeviceInfo hid_info[] = { { .product_desc = QEMU USB Tablet, -- 1.7.1 From 8d918be8c56adc099fe4a12e01c5fdfa735df349 Mon Sep 17 00:00:00 2001 From: Gerd Hoffmann kra...@redhat.com Date: Thu, 7 Jul 2011 15:51:40 +0200 Subject: [PATCH 2/2] usb-hid: make migration support conditional --- hw/usb-hid.c | 23 --- 1 files changed, 20 insertions(+), 3 deletions(-) diff --git a/hw/usb-hid.c b/hw/usb-hid.c index f30c96b..81dff27 100644 --- a/hw/usb-hid.c +++ b/hw/usb-hid.c @@ -80,6 +80,7 @@ typedef struct USBHIDState { int32_t protocol; uint8_t idle; int64_t next_idle_clock; +uint32_t migration; int changed; void *datain_opaque; void (*datain)(void *); @@ -928,6 +929,17 @@ static int usb_hid_initfn(USBDevice *dev, int kind) 1, QEMU USB Tablet); } +if (s-migration) { +if (s-kind == USB_KEYBOARD) { +
[Qemu-devel] [Bug 568614] Re: x86_64 host curses interface: spacing/garbling
This is probably the source of the problem. As you say it'd be best to use chtype directly if it can be done cleanly, unfortunately it looks like it'll add a curses specific snippet in console.h, but so be it. The only other option is to add a conversion step in curses.c and give up zero-copy passing screen data to curses, which I'd like to avoid. -- You received this bug notification because you are a member of qemu- devel-ml, which is subscribed to QEMU. https://bugs.launchpad.net/bugs/568614 Title: x86_64 host curses interface: spacing/garbling Status in QEMU: In Progress Bug description: Environment: Arch Linux x86_64, kernel 2.6.33, qemu 0.12.3 Steps to reproduce: 1. Have a host system running 64-bit Linux. 2. Start a qemu VM with the -curses flag. Expected results: Text displayed looks as it would on a real text-mode display, and VM is therefore usable. Actual results: Text displayed contains an extra space between characters, causing text to flow off the right and bottom sides of the screen. This makes the curses interface unintelligible. The attached patch fixes this problem on 0.12.3 on my installation without changing behavior on a 32-bit machine. I don't know enough of the semantics of console_ch_t to know if this is the correct fix or if there should be, say, an extra cast somewhere instead. To manage notifications about this bug go to: https://bugs.launchpad.net/qemu/+bug/568614/+subscriptions
[Qemu-devel] [PATCH] Error: Fix build when qemu-common.h is not included
Commit e4ea5e2d0e0e4c5188ab45b66f3195062ae059dc added the use of the macro GCC_FMT_ATTR to error.h, however qemu-common.h is not included by error.h This will cause a build error when files including error.h don't include qemu-common.h. Not an issue today because the only file including it is json-parser.h and it does include qemu-common.h, but let's fix it. Signed-off-by: Luiz Capitulino lcapitul...@redhat.com --- error.h |2 +- 1 files changed, 1 insertions(+), 1 deletions(-) diff --git a/error.h b/error.h index 0f92a6f..6e3bd98 100644 --- a/error.h +++ b/error.h @@ -12,7 +12,7 @@ #ifndef ERROR_H #define ERROR_H -#include stdbool.h +#include qemu-common.h /** * A class representing internal errors within QEMU. An error has a string -- 1.7.6.134.gcf13f
[Qemu-devel] [PATCH] qemu-options.hx: Document werror and rerror -drive options
Signed-off-by: Luiz Capitulino lcapitul...@redhat.com --- qemu-options.hx |5 + 1 files changed, 5 insertions(+), 0 deletions(-) diff --git a/qemu-options.hx b/qemu-options.hx index e6d7adc..5f16a78 100644 --- a/qemu-options.hx +++ b/qemu-options.hx @@ -160,6 +160,11 @@ an untrusted format header. This option specifies the serial number to assign to the device. @item addr=@var{addr} Specify the controller's PCI address (if=virtio only). +@item werror=@var{action},rerror=@var{action} +Specify which @var{action} to take on write and read errors. Valid actions are: +ignore (ignore the error and try to continue), stop (pause QEMU), +enospc (pause QEMU, but only on no space conditions), +report (report the error to the guest). @end table By default, writethrough caching is used for all block device. This means that -- 1.7.6.134.gcf13f
Re: [Qemu-devel] migration: new sections and backward compatibility.
On 07/07/2011 01:02 PM, Alexander Graf wrote: I'd guess the best would be to have a special VMSTATE that means broken old version doesn't send a section which we can set for special -M? No, the best would be to have a serious migration format, based for example on ASN.1 which Michael Tsirkin was playing with. We cannot keep bolting more and more stuff on top of the current protocol, especially since adding a new protocol is not that hard (old machine types can keep the old protocol). That would of course not help with RHEL:). At least for RHEL6 we can live with adding a few hacks here and there. Paolo
Re: [Qemu-devel] [PATCH] Error: Fix build when qemu-common.h is not included
On 07/07/2011 11:02 AM, Luiz Capitulino wrote: Commit e4ea5e2d0e0e4c5188ab45b66f3195062ae059dc added the use of the macro GCC_FMT_ATTR to error.h, however qemu-common.h is not included by error.h This will cause a build error when files including error.h don't include qemu-common.h. Not an issue today because the only file including it is json-parser.h and it does include qemu-common.h, but let's fix it. Signed-off-by: Luiz Capitulinolcapitul...@redhat.com --- error.h |2 +- 1 files changed, 1 insertions(+), 1 deletions(-) diff --git a/error.h b/error.h index 0f92a6f..6e3bd98 100644 --- a/error.h +++ b/error.h @@ -12,7 +12,7 @@ #ifndef ERROR_H #define ERROR_H -#includestdbool.h +#include qemu-common.h /** * A class representing internal errors within QEMU. An error has a string Tested-by: Michael Roth mdr...@linux.vnet.ibm.com
Re: [Qemu-devel] KVM call agenda for June 28
On Tue, Jul 5, 2011 at 7:18 PM, Marcelo Tosatti mtosa...@redhat.com wrote: On Tue, Jul 05, 2011 at 04:37:08PM +0100, Stefan Hajnoczi wrote: On Tue, Jul 5, 2011 at 3:32 PM, Marcelo Tosatti mtosa...@redhat.com wrote: On Tue, Jul 05, 2011 at 04:39:06PM +0300, Dor Laor wrote: On 07/05/2011 03:58 PM, Marcelo Tosatti wrote: On Tue, Jul 05, 2011 at 01:40:08PM +0100, Stefan Hajnoczi wrote: On Tue, Jul 5, 2011 at 9:01 AM, Dor Laordl...@redhat.com wrote: I tried to re-arrange all of the requirements and use cases using this wiki page: http://wiki.qemu.org/Features/LiveBlockMigration It would be the best to agree upon the most interesting use cases (while we make sure we cover future ones) and agree to them. The next step is to set the interface for all the various verbs since the implementation seems to be converging. Live block copy was supposed to support snapshot merge. I think the current favored approach is to make the source image a backing file to the destination image and essentially do image streaming. Using this mechanism for snapshot merge is tricky. The COW file already uses the read-only snapshot base image. So now we cannot trivally copy the COW file contents back into the snapshot base image using live block copy. It never did. Live copy creates a new image were both snapshot and current are copied to. This is similar with image streaming. Not sure I realize what's bad to do in-place merge: Let's suppose we have this COW chain: base -- s1 -- s2 Now a live snapshot is created over s2, s2 becomes RO and s3 is RW: base -- s1 -- s2 -- s3 Now we've done with s2 (post backup) and like to merge s3 into s2. With your approach we use live copy of s3 into newSnap: base -- s1 -- s2 -- s3 base -- s1 -- newSnap When it is over s2 and s3 can be erased. The down side is the IOs for copying s2 data and the temporary storage. I guess temp storage is cheap but excessive IO are expensive. My approach was to collapse s3 into s2 and erase s3 eventually: before: base -- s1 -- s2 -- s3 after: base -- s1 -- s2 If we use live block copy using mirror driver it should be safe as long as we keep the ordering of new writes into s3 during the execution. Even a failure in the the middle won't cause harm since the management will keep using s3 until it gets success event. Well, it is more complicated than simply streaming into a new image. I'm not entirely sure it is necessary. The common case is: base - sn-1 - sn-2 - ... - sn-n When n reaches a limit, you do: base - merge-1 You're potentially copying similar amount of data when merging back into a single image (and you can't easily merge multiple snapshots). If the amount of data thats not in 'base' is large, you create leave a new external file around: base - merge-1 - sn-1 - sn-2 ... - sn-n to base - merge-1 - merge-2 It seems like snapshot merge will require dedicated code that reads the allocated clusters from the COW file and writes them back into the base image. A very inefficient alternative would be to create a third image, the merge image file, which has the COW file as its backing file: snapshot (base) - cow - merge Remember there is a 'base' before snapshot, you don't copy the entire image. One use case I have in mind is the Live Backup approach that Jagane has been developing. Here the backup solution only creates a snapshot for the period of time needed to read out the dirty blocks. Then the snapshot is deleted again and probably contains very little new data relative to the base image. The backup solution does this operation every day. This is the pathalogical case for any approach that copies the entire base into a new file. We could have avoided a lot of I/O by doing an in-place update. I want to make sure this works well. This use case does not fit the streaming scheme that has come up. Its a completly different operation. IMO it should be implemented separately. Okay, not everything can fit into this one grand unified block copy/image streaming mechanism :). Stefan
Re: [Qemu-devel] [PATCH 3/3] hw/omap_gpio.c: Convert to qdev
Hi, On 5 July 2011 15:19, Peter Maydell peter.mayd...@linaro.org wrote: On 4 July 2011 23:39, andrzej zaborowski balr...@gmail.com wrote: I'd also prefer that omap2_gpio_init remains a function that does all the qdev magic in omap_gpio.c and with the current signature I'm not convinced about this. Implementing the GPIO module as a sysbus device seems like the right thing, and it's the job of omap2.c to know how to map and wire the resources the sysbus device provides. Hiding that in a helper function in omap_gpio.c doesn't seem quite right. Good point. (so for example clocks usage can be kept track of). You're right, we probably should do something with the clocks (even though omap_gpio doesn't use them). We'd probably wind up with a 'wire up clocks' function per device type though, unless we want to try to make all omap devices inherit from a common thing that knows about clocks (so we could have an omap_connect_clk() function like sysbus_connect_irq()). [This is about the only thing inclining me in favour of an _init routine. I guess you touch on the idea of an omap-specific bus below.] PS: on the subject of clocks, this is how a later qdevification patch in my stack does the wiring up of the uart: s-uart[0] = qdev_create(NULL, omap_uart); s-uart[0]-id = uart1; qdev_prop_set_uint32(s-uart[0], mmio_size, 0x1000); qdev_prop_set_uint32(s-uart[0], baudrate, omap_clk_getrate(omap_findclk(s, uart1_fclk)) / 16); qdev_prop_set_chr(s-uart[0], chardev, serial_hds[0]); qdev_init_nofail(s-uart[0]); busdev = sysbus_from_qdev(s-uart[0]); sysbus_connect_irq(busdev, 0, s-irq[0][OMAP_INT_24XX_UART1_IRQ]); sysbus_connect_irq(busdev, 1, s-drq[OMAP24XX_DMA_UART1_TX]); sysbus_connect_irq(busdev, 2, s-drq[OMAP24XX_DMA_UART1_RX]); sysbus_mmio_map(busdev, 0, omap_l4_base(omap_l4ta(s-l4, 19), 0)); ...it would be useful to know if you're going to object to how it's dealing with the clock there so I can fix it in advance and avoid a round of review. Other than the clock and the address passing it looks ok. Optimally we should pass the clock as a pointer or name, not only the baudrate (clocks can be stopped, reparented, or have frequency changed dynamically -- in fact the OS will most likely manipulate the uart source clock frequency during init) and the TA region as such instead of only the base. Maybe let's have a short omap_dev_connect_clock function that would use or alias prop_set_ptr or something like that (and a similar thing for the target agent). Would it make more sense to pass the ta structures instead of base adresses to the qdev? Have you considered how difficult l4 would be to convert to a QBus? Hmm. I hadn't thought about that. Does it buy us anything useful? Probably not if we can pass the resources to qdev in a nice way. Cheers
Re: [Qemu-devel] migration: new sections and backward compatibility.
On 07/06/2011 06:32 PM, Alexander Graf wrote: On 06.07.2011, at 22:01, Anthony Liguori wrote: On 07/06/2011 12:28 PM, Avi Kivity wrote: On 07/06/2011 07:04 PM, Gerd Hoffmann wrote: Hi folks, We'll need to figure a sane way to handle migration to older versions with new sections, i.e. devices which used to not save state before do now. We already have one case in tree: usb. qemu 0.14 saves state for usb-hid devices and the usb-hub, whereas qemu 0.13 and older don't. You can't migrate a vm with a usb-tablet from 0.14 to 0.13 because of that even if you use -M pc-0.13. More cases are lurking. AHCI doesn't support migration today but probably will some day. Markus mentioned that scsi-disk will face that issue too. And that list probably isn't complete. Subsections don't help here as there is no toplevel section in the first place. Ideas anyone? Maybe allow test functions like we have for subsections for toplevel sections too, so we have a way to skip the section altogether on savevm? We probably also want a way to fail the migration in case the target machine doesn't support migration for $device, especially for $device == ahci to avoid data loss. For the usb-tablet it isn't that problematic, in the best case the guest just resets the device and goes on, in the worst case the mouse is dead. How did AHCI get in without migration? It's relatively new, is it not? We don't have a hard policy about not merging devices that don't support migration. Since migration must be supported forever, I'd rather see a device get some solid testing before it starts doing live migration. That said, we should probably do this consciously by explicitly marking the device non-migrateable. Can't we just implicitly fail migration whenever there's a device in the tree that doesn't have VMSTATE? Not all devices currently implement VMSTATE. Regards, Anthony Liguori Alex
[Qemu-devel] [PATCH v2] qxl: use update_area_async in qxl-render
--- hw/qxl-render.c |4 ++-- hw/qxl.c| 14 +- hw/qxl.h|3 --- 3 files changed, 7 insertions(+), 14 deletions(-) diff --git a/hw/qxl-render.c b/hw/qxl-render.c index 60b822d..8d847d0 100644 --- a/hw/qxl-render.c +++ b/hw/qxl-render.c @@ -124,8 +124,8 @@ void qxl_render_update(PCIQXLDevice *qxl) update.bottom = qxl-guest_primary.surface.height; memset(dirty, 0, sizeof(dirty)); -qxl_spice_update_area(qxl, 0, update, - dirty, ARRAY_SIZE(dirty), 1); +qxl_spice_update_area_async(qxl, 0, update, + dirty, ARRAY_SIZE(dirty), 1, 1); for (i = 0; i ARRAY_SIZE(dirty); i++) { if (qemu_spice_rect_is_empty(dirty+i)) { diff --git a/hw/qxl.c b/hw/qxl.c index 54ee5f5..c447e89 100644 --- a/hw/qxl.c +++ b/hw/qxl.c @@ -150,14 +150,6 @@ void qxl_spice_update_area_async(PCIQXLDevice *qxl, uint32_t surface_id, } } -void qxl_spice_update_area(PCIQXLDevice *qxl, uint32_t surface_id, - struct QXLRect *area, struct QXLRect *dirty_rects, - uint32_t num_dirty_rects, uint32_t clear_dirty_region) -{ -qxl_spice_update_area_async(qxl, surface_id, area, dirty_rects, -num_dirty_rects, clear_dirty_region, 0); -} - static void qxl_spice_destroy_surface_wait_complete(PCIQXLDevice *qxl) { qemu_mutex_lock(qxl-track_lock); @@ -776,7 +768,11 @@ static void interface_async_complete(QXLInstance *sin, uint64_t cookie) qxl_spice_destroy_surface_wait_complete(qxl); break; } -qxl_send_events(qxl, QXL_INTERRUPT_IO_CMD); +if (current_async != QXL_IO_UPDATE_AREA_ASYNC || qxl-mode != QXL_MODE_VGA) { +qxl_send_events(qxl, QXL_INTERRUPT_IO_CMD); +} else { +dprint(qxl, 1, in vga mode; update_area_async interrupt not sent\n); +} } static const QXLInterface qxl_interface = { diff --git a/hw/qxl.h b/hw/qxl.h index 23d6215..f02c28f 100644 --- a/hw/qxl.h +++ b/hw/qxl.h @@ -115,9 +115,6 @@ typedef struct PCIQXLDevice { void *qxl_phys2virt(PCIQXLDevice *qxl, QXLPHYSICAL phys, int group_id); void qxl_guest_bug(PCIQXLDevice *qxl, const char *msg, ...); -void qxl_spice_update_area(PCIQXLDevice *qxl, uint32_t surface_id, - struct QXLRect *area, struct QXLRect *dirty_rects, - uint32_t num_dirty_rects, uint32_t clear_dirty_region); void qxl_spice_update_area_async(PCIQXLDevice *qxl, uint32_t surface_id, struct QXLRect *area, struct QXLRect *dirty_rects, uint32_t num_dirty_rects, uint32_t clear_dirty_region, -- 1.7.5.4
[Qemu-devel] [PATCH v2] qxl: only disallow specific io's in vga mode
Since the driver is still in operation even after moving to UNDEFINED, i.e. by destroying primary in any way. --- hw/qxl.c |3 ++- 1 files changed, 2 insertions(+), 1 deletions(-) diff --git a/hw/qxl.c b/hw/qxl.c index 395d994..e57ccf2 100644 --- a/hw/qxl.c +++ b/hw/qxl.c @@ -1167,8 +1167,9 @@ static void ioport_write(void *opaque, uint32_t addr, uint32_t val) case QXL_IO_LOG: break; default: -if (d-mode == QXL_MODE_NATIVE || d-mode == QXL_MODE_COMPAT) +if (d-mode != QXL_MODE_VGA) { break; +} dprint(d, 1, %s: unexpected port 0x%x (%s) in vga mode\n, __FUNCTION__, io_port, io_port_to_string(io_port)); /* be nice to buggy guest drivers */ -- 1.7.5.4
[Qemu-devel] [PATCH v2] qxl: bump pci rev
From: Gerd Hoffmann kra...@redhat.com Inform guest drivers about the new features I/O commands we have now (async commands, S3 support). Signed-off-by: Gerd Hoffmann kra...@redhat.com --- hw/qxl.c |9 ++--- 1 files changed, 6 insertions(+), 3 deletions(-) diff --git a/hw/qxl.c b/hw/qxl.c index f72d5b8..395d994 100644 --- a/hw/qxl.c +++ b/hw/qxl.c @@ -1541,9 +1541,12 @@ static int qxl_init_common(PCIQXLDevice *qxl) pci_device_rev = QXL_REVISION_STABLE_V04; break; case 2: /* spice 0.6 -- qxl-2 */ -default: pci_device_rev = QXL_REVISION_STABLE_V06; break; +case 3: /* qxl-3 */ +default: +pci_device_rev = 3; +break; } pci_set_byte(config[PCI_REVISION_ID], pci_device_rev); @@ -1807,7 +1810,7 @@ static PCIDeviceInfo qxl_info_primary = { .qdev.props = (Property[]) { DEFINE_PROP_UINT32(ram_size, PCIQXLDevice, vga.vram_size, 64 * 1024 * 1024), DEFINE_PROP_UINT32(vram_size, PCIQXLDevice, vram_size, 64 * 1024 * 1024), -DEFINE_PROP_UINT32(revision, PCIQXLDevice, revision, 2), +DEFINE_PROP_UINT32(revision, PCIQXLDevice, revision, 3), DEFINE_PROP_UINT32(debug, PCIQXLDevice, debug, 0), DEFINE_PROP_UINT32(guestdebug, PCIQXLDevice, guestdebug, 0), DEFINE_PROP_UINT32(cmdlog, PCIQXLDevice, cmdlog, 0), @@ -1828,7 +1831,7 @@ static PCIDeviceInfo qxl_info_secondary = { .qdev.props = (Property[]) { DEFINE_PROP_UINT32(ram_size, PCIQXLDevice, vga.vram_size, 64 * 1024 * 1024), DEFINE_PROP_UINT32(vram_size, PCIQXLDevice, vram_size, 64 * 1024 * 1024), -DEFINE_PROP_UINT32(revision, PCIQXLDevice, revision, 2), +DEFINE_PROP_UINT32(revision, PCIQXLDevice, revision, 3), DEFINE_PROP_UINT32(debug, PCIQXLDevice, debug, 0), DEFINE_PROP_UINT32(guestdebug, PCIQXLDevice, guestdebug, 0), DEFINE_PROP_UINT32(cmdlog, PCIQXLDevice, cmdlog, 0), -- 1.7.5.4
[Qemu-devel] [PATCH v2] qxl: make qxl_guest_bug take variable arguments
--- hw/qxl.c | 18 +++--- hw/qxl.h |2 +- 2 files changed, 12 insertions(+), 8 deletions(-) diff --git a/hw/qxl.c b/hw/qxl.c index 0d62036..935bac0 100644 --- a/hw/qxl.c +++ b/hw/qxl.c @@ -124,11 +124,15 @@ static void qxl_reset_memslots(PCIQXLDevice *d); static void qxl_reset_surfaces(PCIQXLDevice *d); static void qxl_ring_set_dirty(PCIQXLDevice *qxl); -void qxl_guest_bug(PCIQXLDevice *qxl, const char *msg) +void qxl_guest_bug(PCIQXLDevice *qxl, const char *msg, ...) { qxl_send_events(qxl, QXL_INTERRUPT_ERROR); if (qxl-guestdebug) { -fprintf(stderr, qxl-%d: guest bug: %s\n, qxl-id, msg); +va_list ap; +va_start(ap, msg); +fprintf(stderr, qxl-%d: guest bug: , qxl-id); +vfprintf(stderr, msg, ap); +va_end(ap); } } @@ -1114,11 +1118,11 @@ static void ioport_write(void *opaque, uint32_t addr, uint32_t val) break; case QXL_IO_MEMSLOT_ADD: if (val = NUM_MEMSLOTS) { -qxl_guest_bug(d, QXL_IO_MEMSLOT_ADD: val out of range); +qxl_guest_bug(d, QXL_IO_MEMSLOT_ADD: val out of range\n); break; } if (d-guest_slots[val].active) { -qxl_guest_bug(d, QXL_IO_MEMSLOT_ADD: memory slot already active); +qxl_guest_bug(d, QXL_IO_MEMSLOT_ADD: memory slot already active\n); break; } d-guest_slots[val].slot = d-ram-mem_slot; @@ -1126,14 +1130,14 @@ static void ioport_write(void *opaque, uint32_t addr, uint32_t val) break; case QXL_IO_MEMSLOT_DEL: if (val = NUM_MEMSLOTS) { -qxl_guest_bug(d, QXL_IO_MEMSLOT_DEL: val out of range); +qxl_guest_bug(d, QXL_IO_MEMSLOT_DEL: val out of range\n); break; } qxl_del_memslot(d, val); break; case QXL_IO_CREATE_PRIMARY: if (val != 0) { -qxl_guest_bug(d, QXL_IO_CREATE_PRIMARY: val != 0); +qxl_guest_bug(d, QXL_IO_CREATE_PRIMARY: val != 0\n); break; } dprint(d, 1, QXL_IO_CREATE_PRIMARY\n); @@ -1142,7 +1146,7 @@ static void ioport_write(void *opaque, uint32_t addr, uint32_t val) break; case QXL_IO_DESTROY_PRIMARY: if (val != 0) { -qxl_guest_bug(d, QXL_IO_DESTROY_PRIMARY: val != 0); +qxl_guest_bug(d, QXL_IO_DESTROY_PRIMARY: val != 0\n); break; } dprint(d, 1, QXL_IO_DESTROY_PRIMARY (%s)\n, qxl_mode_to_string(d-mode)); diff --git a/hw/qxl.h b/hw/qxl.h index 88393c2..e361bc6 100644 --- a/hw/qxl.h +++ b/hw/qxl.h @@ -99,7 +99,7 @@ typedef struct PCIQXLDevice { /* qxl.c */ void *qxl_phys2virt(PCIQXLDevice *qxl, QXLPHYSICAL phys, int group_id); -void qxl_guest_bug(PCIQXLDevice *qxl, const char *msg); +void qxl_guest_bug(PCIQXLDevice *qxl, const char *msg, ...); void qxl_spice_update_area(PCIQXLDevice *qxl, uint32_t surface_id, struct QXLRect *area, struct QXLRect *dirty_rects, -- 1.7.5.4
Re: [Qemu-devel] migration: new sections and backward compatibility.
On 07/07/2011 02:19 AM, Gerd Hoffmann wrote: On 07/06/11 19:13, Anthony Liguori wrote: On 07/06/2011 11:04 AM, Gerd Hoffmann wrote: Hi folks, We'll need to figure a sane way to handle migration to older versions with new sections, i.e. devices which used to not save state before do now. We already have one case in tree: usb. qemu 0.14 saves state for usb-hid devices and the usb-hub, whereas qemu 0.13 and older don't. You can't migrate a vm with a usb-tablet from 0.14 to 0.13 because of that even if you use -M pc-0.13. Because if you did migrate, you would actively break the guest during migration. So why is this a problem? Well, in case of usb hid devices breaking the guest isn't that a big issue for at least some guests because they manage to reset the device and continue nevertheless ... In a situation like this, I think our responsibility is to let the user know that there could be a problem, and provide the ability to the user to force the migration. So for instance, you could have a (qemu) migrate_ignore_section usb command or something like that. But we shouldn't enable things that may sometimes work by default. Regards, Anthony Liguori I think this is a case-by-case thing. In some cases we want break migration because critical state is missing. In other cases we might want allow it nevertheless. cheers, Gerd
[Qemu-devel] [PATCH v2] qxl: add QXL_IO_FLUSH_{SURFACES, RELEASE} for guest S3S4 support
Add two new IOs. QXL_IO_FLUSH_SURFACES - equivalent to update area for all surfaces, used to reduce vmexits from NumSurfaces to 1 on guest S3, S4 and resolution change (windows driver implementation is such that this is done on each of those occasions). QXL_IO_FLUSH_RELEASE - used to ensure anything on last_release is put on the release ring for the client to free. Cc: Yonit Halperin yhalp...@redhat.com --- hw/qxl.c | 25 + hw/qxl.h |1 + 2 files changed, 26 insertions(+), 0 deletions(-) diff --git a/hw/qxl.c b/hw/qxl.c index e57ccf2..4007847 100644 --- a/hw/qxl.c +++ b/hw/qxl.c @@ -177,6 +177,11 @@ static void qxl_spice_destroy_surface_wait_async(PCIQXLDevice *qxl, uint32_t id, } } +void qxl_spice_flush_surfaces_async(PCIQXLDevice *qxl) +{ +qxl-ssd.worker-flush_surfaces_async(qxl-ssd.worker, 0); +} + void qxl_spice_loadvm_commands(PCIQXLDevice *qxl, struct QXLCommandExt *ext, uint32_t count) { @@ -1187,6 +1192,7 @@ static void ioport_write(void *opaque, uint32_t addr, uint32_t val) case QXL_IO_DESTROY_PRIMARY_ASYNC: case QXL_IO_DESTROY_SURFACE_ASYNC: case QXL_IO_DESTROY_ALL_SURFACES_ASYNC: +case QXL_IO_FLUSH_SURFACES_ASYNC: if (!qemu_spice_supports_async(d-ssd)) { fprintf(stderr, qxl: error: async not supported by libspice but guest driver used it\n); return; @@ -1306,6 +1312,25 @@ static void ioport_write(void *opaque, uint32_t addr, uint32_t val) } qxl_spice_destroy_surface_wait_async(d, val, async); break; +case QXL_IO_FLUSH_RELEASE: { +QXLReleaseRing *ring = d-ram-release_ring; +if (ring-prod - ring-cons + 1 == ring-num_items) { +fprintf(stderr, +ERROR: no flush, full release ring [p%d,%dc]\n, +ring-prod, ring-cons); +} +qxl_push_free_res(d, 1 /* flush */); +dprint(d, 1, QXL_IO_FLUSH_RELEASE exit (%s, s#=%d, res#=%d,%p)\n, +qxl_mode_to_string(d-mode), d-guest_surfaces.count, +d-num_free_res, d-last_release); +break; +} +case QXL_IO_FLUSH_SURFACES_ASYNC: +dprint(d, 1, QXL_IO_FLUSH_SURFACES_ASYNC (%d) (%s, s#=%d, res#=%d)\n, + val, qxl_mode_to_string(d-mode), d-guest_surfaces.count, + d-num_free_res); +qxl_spice_flush_surfaces_async(d); +break; case QXL_IO_DESTROY_ALL_SURFACES_ASYNC: case QXL_IO_DESTROY_ALL_SURFACES: d-mode = QXL_MODE_UNDEFINED; diff --git a/hw/qxl.h b/hw/qxl.h index 16639ce..23d6215 100644 --- a/hw/qxl.h +++ b/hw/qxl.h @@ -129,6 +129,7 @@ void qxl_spice_oom_async(PCIQXLDevice *qxl, int async); void qxl_spice_reset_memslots(PCIQXLDevice *qxl); void qxl_spice_reset_image_cache(PCIQXLDevice *qxl); void qxl_spice_reset_cursor(PCIQXLDevice *qxl); +void qxl_spice_flush_surfaces_async(PCIQXLDevice *qxl); /* qxl-logger.c */ void qxl_log_cmd_cursor(PCIQXLDevice *qxl, QXLCursorCmd *cmd, int group_id); -- 1.7.5.4
Re: [Qemu-devel] migration: new sections and backward compatibility.
Anthony Liguori anth...@codemonkey.ws writes: On 07/07/2011 04:23 AM, Markus Armbruster wrote: Anthony Liguorianth...@codemonkey.ws writes: On 07/06/2011 11:04 AM, Gerd Hoffmann wrote: Hi folks, We'll need to figure a sane way to handle migration to older versions with new sections, i.e. devices which used to not save state before do now. We already have one case in tree: usb. qemu 0.14 saves state for usb-hid devices and the usb-hub, whereas qemu 0.13 and older don't. You can't migrate a vm with a usb-tablet from 0.14 to 0.13 because of that even if you use -M pc-0.13. Because if you did migrate, you would actively break the guest during migration. So why is this a problem? This comes up a lot. We shouldn't enable migration if we know the guest is going to break during migration. That's a feature, not a bug. Not so fast :) I agree that throwing away unrecognized migration data is unsafe, and should not be done. Now let me present my little problem. I'm working on making migration preserve tray status: open/closed, locked/unlocked. For ide-cd, I can stick a subsection ide_drive/tray_state into section ide_drive. Needed only if the tray is open or locked. This gives users a chance to migrate to older versions, and is perfectly safe. scsi-cd doesn't have a section, yet. What now? Is that because 'scsi-cd' doesn't need a section or because it hasn't been implemented yet? According to Juan, because it was assumed that qemu_aio_flush() gets us into a clean, resumable state.
[Qemu-devel] [PATCH v2] qxl: error handling fixes and cleanups.
From: Gerd Hoffmann kra...@redhat.com Add qxl_guest_bug() function which is supposed to be called in case sanity checks of guest requests fail. It raises an error IRQ and logs a message in case guest debugging is enabled. Make PANIC_ON() abort instead of exit. That macro should be used for qemu bugs only, any guest-triggerable stuff should use the new qxl_guest_bug() function instead. Convert a few easy cases from PANIC_ON() to qxl_guest_bug() to show intended usage. Signed-off-by: Gerd Hoffmann kra...@redhat.com --- hw/qxl.c | 32 hw/qxl.h |3 ++- 2 files changed, 30 insertions(+), 5 deletions(-) diff --git a/hw/qxl.c b/hw/qxl.c index f3312f0..0d62036 100644 --- a/hw/qxl.c +++ b/hw/qxl.c @@ -124,6 +124,14 @@ static void qxl_reset_memslots(PCIQXLDevice *d); static void qxl_reset_surfaces(PCIQXLDevice *d); static void qxl_ring_set_dirty(PCIQXLDevice *qxl); +void qxl_guest_bug(PCIQXLDevice *qxl, const char *msg) +{ +qxl_send_events(qxl, QXL_INTERRUPT_ERROR); +if (qxl-guestdebug) { +fprintf(stderr, qxl-%d: guest bug: %s\n, qxl-id, msg); +} +} + void qxl_spice_update_area(PCIQXLDevice *qxl, uint32_t surface_id, struct QXLRect *area, struct QXLRect *dirty_rects, @@ -1105,22 +1113,38 @@ static void ioport_write(void *opaque, uint32_t addr, uint32_t val) qxl_hard_reset(d, 0); break; case QXL_IO_MEMSLOT_ADD: -PANIC_ON(val = NUM_MEMSLOTS); -PANIC_ON(d-guest_slots[val].active); +if (val = NUM_MEMSLOTS) { +qxl_guest_bug(d, QXL_IO_MEMSLOT_ADD: val out of range); +break; +} +if (d-guest_slots[val].active) { +qxl_guest_bug(d, QXL_IO_MEMSLOT_ADD: memory slot already active); +break; +} d-guest_slots[val].slot = d-ram-mem_slot; qxl_add_memslot(d, val, 0); break; case QXL_IO_MEMSLOT_DEL: +if (val = NUM_MEMSLOTS) { +qxl_guest_bug(d, QXL_IO_MEMSLOT_DEL: val out of range); +break; +} qxl_del_memslot(d, val); break; case QXL_IO_CREATE_PRIMARY: -PANIC_ON(val != 0); +if (val != 0) { +qxl_guest_bug(d, QXL_IO_CREATE_PRIMARY: val != 0); +break; +} dprint(d, 1, QXL_IO_CREATE_PRIMARY\n); d-guest_primary.surface = d-ram-create_surface; qxl_create_guest_primary(d, 0); break; case QXL_IO_DESTROY_PRIMARY: -PANIC_ON(val != 0); +if (val != 0) { +qxl_guest_bug(d, QXL_IO_DESTROY_PRIMARY: val != 0); +break; +} dprint(d, 1, QXL_IO_DESTROY_PRIMARY (%s)\n, qxl_mode_to_string(d-mode)); if (d-mode != QXL_MODE_UNDEFINED) { d-mode = QXL_MODE_UNDEFINED; diff --git a/hw/qxl.h b/hw/qxl.h index 087ef6b..88393c2 100644 --- a/hw/qxl.h +++ b/hw/qxl.h @@ -86,7 +86,7 @@ typedef struct PCIQXLDevice { #define PANIC_ON(x) if ((x)) { \ printf(%s: PANIC %s failed\n, __FUNCTION__, #x); \ -exit(-1); \ +abort(); \ } #define dprint(_qxl, _level, _fmt, ...) \ @@ -99,6 +99,7 @@ typedef struct PCIQXLDevice { /* qxl.c */ void *qxl_phys2virt(PCIQXLDevice *qxl, QXLPHYSICAL phys, int group_id); +void qxl_guest_bug(PCIQXLDevice *qxl, const char *msg); void qxl_spice_update_area(PCIQXLDevice *qxl, uint32_t surface_id, struct QXLRect *area, struct QXLRect *dirty_rects, -- 1.7.5.4
[Qemu-devel] [PATCH v2] spice: add worker wrapper functions.
From: Gerd Hoffmann kra...@redhat.com Add wrapper functions for all spice worker calls. Signed-off-by: Gerd Hoffmann kra...@redhat.com --- hw/qxl-render.c|4 +- hw/qxl.c | 32 +- ui/spice-display.c | 94 --- ui/spice-display.h | 20 +++ 4 files changed, 126 insertions(+), 24 deletions(-) diff --git a/hw/qxl-render.c b/hw/qxl-render.c index 1316066..bef5f14 100644 --- a/hw/qxl-render.c +++ b/hw/qxl-render.c @@ -124,8 +124,8 @@ void qxl_render_update(PCIQXLDevice *qxl) update.bottom = qxl-guest_primary.surface.height; memset(dirty, 0, sizeof(dirty)); -qxl-ssd.worker-update_area(qxl-ssd.worker, 0, update, - dirty, ARRAY_SIZE(dirty), 1); +qemu_spice_update_area(qxl-ssd, 0, update, + dirty, ARRAY_SIZE(dirty), 1); for (i = 0; i ARRAY_SIZE(dirty); i++) { if (qemu_spice_rect_is_empty(dirty+i)) { diff --git a/hw/qxl.c b/hw/qxl.c index 0b9a4c7..19240da 100644 --- a/hw/qxl.c +++ b/hw/qxl.c @@ -684,8 +684,8 @@ static void qxl_hard_reset(PCIQXLDevice *d, int loadvm) dprint(d, 1, %s: start%s\n, __FUNCTION__, loadvm ? (loadvm) : ); -d-ssd.worker-reset_cursor(d-ssd.worker); -d-ssd.worker-reset_image_cache(d-ssd.worker); +qemu_spice_reset_cursor(d-ssd); +qemu_spice_reset_image_cache(d-ssd); qxl_reset_surfaces(d); qxl_reset_memslots(d); @@ -790,7 +790,7 @@ static void qxl_add_memslot(PCIQXLDevice *d, uint32_t slot_id, uint64_t delta) __FUNCTION__, memslot.slot_id, memslot.virt_start, memslot.virt_end); -d-ssd.worker-add_memslot(d-ssd.worker, memslot); +qemu_spice_add_memslot(d-ssd, memslot); d-guest_slots[slot_id].ptr = (void*)memslot.virt_start; d-guest_slots[slot_id].size = memslot.virt_end - memslot.virt_start; d-guest_slots[slot_id].delta = delta; @@ -800,14 +800,14 @@ static void qxl_add_memslot(PCIQXLDevice *d, uint32_t slot_id, uint64_t delta) static void qxl_del_memslot(PCIQXLDevice *d, uint32_t slot_id) { dprint(d, 1, %s: slot %d\n, __FUNCTION__, slot_id); -d-ssd.worker-del_memslot(d-ssd.worker, MEMSLOT_GROUP_HOST, slot_id); +qemu_spice_del_memslot(d-ssd, MEMSLOT_GROUP_HOST, slot_id); d-guest_slots[slot_id].active = 0; } static void qxl_reset_memslots(PCIQXLDevice *d) { dprint(d, 1, %s:\n, __FUNCTION__); -d-ssd.worker-reset_memslots(d-ssd.worker); +qemu_spice_reset_memslots(d-ssd); memset(d-guest_slots, 0, sizeof(d-guest_slots)); } @@ -815,7 +815,7 @@ static void qxl_reset_surfaces(PCIQXLDevice *d) { dprint(d, 1, %s:\n, __FUNCTION__); d-mode = QXL_MODE_UNDEFINED; -d-ssd.worker-destroy_surfaces(d-ssd.worker); +qemu_spice_destroy_surfaces(d-ssd); memset(d-guest_surfaces.cmds, 0, sizeof(d-guest_surfaces.cmds)); } @@ -869,7 +869,7 @@ static void qxl_create_guest_primary(PCIQXLDevice *qxl, int loadvm) qxl-mode = QXL_MODE_NATIVE; qxl-cmdflags = 0; -qxl-ssd.worker-create_primary_surface(qxl-ssd.worker, 0, surface); +qemu_spice_create_primary_surface(qxl-ssd, 0, surface); /* for local rendering */ qxl_render_resize(qxl); @@ -884,7 +884,7 @@ static void qxl_destroy_primary(PCIQXLDevice *d) dprint(d, 1, %s\n, __FUNCTION__); d-mode = QXL_MODE_UNDEFINED; -d-ssd.worker-destroy_primary_surface(d-ssd.worker, 0); +qemu_spice_destroy_primary_surface(d-ssd, 0); } static void qxl_set_mode(PCIQXLDevice *d, int modenr, int loadvm) @@ -956,15 +956,15 @@ static void ioport_write(void *opaque, uint32_t addr, uint32_t val) case QXL_IO_UPDATE_AREA: { QXLRect update = d-ram-update_area; -d-ssd.worker-update_area(d-ssd.worker, d-ram-update_surface, - update, NULL, 0, 0); +qemu_spice_update_area(d-ssd, d-ram-update_surface, + update, NULL, 0, 0); break; } case QXL_IO_NOTIFY_CMD: -d-ssd.worker-wakeup(d-ssd.worker); +qemu_spice_wakeup(d-ssd); break; case QXL_IO_NOTIFY_CURSOR: -d-ssd.worker-wakeup(d-ssd.worker); +qemu_spice_wakeup(d-ssd); break; case QXL_IO_UPDATE_IRQ: qxl_set_irq(d); @@ -978,7 +978,7 @@ static void ioport_write(void *opaque, uint32_t addr, uint32_t val) break; } d-oom_running = 1; -d-ssd.worker-oom(d-ssd.worker); +qemu_spice_oom(d-ssd); d-oom_running = 0; break; case QXL_IO_SET_MODE: @@ -1016,10 +1016,10 @@ static void ioport_write(void *opaque, uint32_t addr, uint32_t val) qxl_destroy_primary(d); break; case QXL_IO_DESTROY_SURFACE_WAIT: -d-ssd.worker-destroy_surface_wait(d-ssd.worker, val); +qemu_spice_destroy_surface_wait(d-ssd, val); break; case QXL_IO_DESTROY_ALL_SURFACES: -
[Qemu-devel] [PATCH v2] qxl: fix surface tracking locking
From: Gerd Hoffmann kra...@redhat.com Surface tracking needs proper locking since it is used from vcpu and spice worker threads, add it. Also reset the surface counter when zapping all surfaces. Signed-off-by: Gerd Hoffmann kra...@redhat.com --- hw/qxl.c | 13 - hw/qxl.h |2 ++ 2 files changed, 14 insertions(+), 1 deletions(-) diff --git a/hw/qxl.c b/hw/qxl.c index def128d..9116c99 100644 --- a/hw/qxl.c +++ b/hw/qxl.c @@ -135,7 +135,12 @@ void qxl_spice_update_area(PCIQXLDevice *qxl, uint32_t surface_id, void qxl_spice_destroy_surface_wait(PCIQXLDevice *qxl, uint32_t id) { +qemu_mutex_lock(qxl-track_lock); +PANIC_ON(id = NUM_SURFACES); qxl-ssd.worker-destroy_surface_wait(qxl-ssd.worker, id); +qxl-guest_surfaces.cmds[id] = 0; +qxl-guest_surfaces.count--; +qemu_mutex_unlock(qxl-track_lock); } void qxl_spice_loadvm_commands(PCIQXLDevice *qxl, struct QXLCommandExt *ext, @@ -156,7 +161,11 @@ void qxl_spice_reset_memslots(PCIQXLDevice *qxl) void qxl_spice_destroy_surfaces(PCIQXLDevice *qxl) { +qemu_mutex_lock(qxl-track_lock); qxl-ssd.worker-destroy_surfaces(qxl-ssd.worker); +memset(qxl-guest_surfaces.cmds, 0, sizeof(qxl-guest_surfaces.cmds)); +qxl-guest_surfaces.count = 0; +qemu_mutex_unlock(qxl-track_lock); } void qxl_spice_reset_image_cache(PCIQXLDevice *qxl) @@ -315,6 +324,7 @@ static void qxl_track_command(PCIQXLDevice *qxl, struct QXLCommandExt *ext) QXLSurfaceCmd *cmd = qxl_phys2virt(qxl, ext-cmd.data, ext-group_id); uint32_t id = le32_to_cpu(cmd-surface_id); PANIC_ON(id = NUM_SURFACES); +qemu_mutex_lock(qxl-track_lock); if (cmd-type == QXL_SURFACE_CMD_CREATE) { qxl-guest_surfaces.cmds[id] = ext-cmd.data; qxl-guest_surfaces.count++; @@ -325,6 +335,7 @@ static void qxl_track_command(PCIQXLDevice *qxl, struct QXLCommandExt *ext) qxl-guest_surfaces.cmds[id] = 0; qxl-guest_surfaces.count--; } +qemu_mutex_unlock(qxl-track_lock); break; } case QXL_CMD_CURSOR: @@ -867,7 +878,6 @@ static void qxl_reset_surfaces(PCIQXLDevice *d) dprint(d, 1, %s:\n, __FUNCTION__); d-mode = QXL_MODE_UNDEFINED; qxl_spice_destroy_surfaces(d); -memset(d-guest_surfaces.cmds, 0, sizeof(d-guest_surfaces.cmds)); } /* called from spice server thread context only */ @@ -1278,6 +1288,7 @@ static int qxl_init_common(PCIQXLDevice *qxl) qxl-generation = 1; qxl-num_memslots = NUM_MEMSLOTS; qxl-num_surfaces = NUM_SURFACES; +qemu_mutex_init(qxl-track_lock); switch (qxl-revision) { case 1: /* spice 0.4 -- qxl-1 */ diff --git a/hw/qxl.h b/hw/qxl.h index 489d518..087ef6b 100644 --- a/hw/qxl.h +++ b/hw/qxl.h @@ -55,6 +55,8 @@ typedef struct PCIQXLDevice { } guest_surfaces; QXLPHYSICALguest_cursor; +QemuMutex track_lock; + /* thread signaling */ pthread_t main; intpipe[2]; -- 1.7.5.4
[Qemu-devel] [PATCH v2] qxl: add io_port_to_string
--- hw/qxl.c | 62 +- 1 files changed, 61 insertions(+), 1 deletions(-) diff --git a/hw/qxl.c b/hw/qxl.c index 9116c99..f3312f0 100644 --- a/hw/qxl.c +++ b/hw/qxl.c @@ -407,6 +407,65 @@ static const char *qxl_mode_to_string(int mode) return INVALID; } +static const char *io_port_to_string(uint32_t io_port) +{ +if (io_port = QXL_IO_RANGE_SIZE) { +return out of range; +} +switch(io_port) { +case QXL_IO_NOTIFY_CMD: +return QXL_IO_NOTIFY_CMD; +case QXL_IO_NOTIFY_CURSOR: +return QXL_IO_NOTIFY_CURSOR; +case QXL_IO_UPDATE_AREA: +return QXL_IO_UPDATE_AREA; +case QXL_IO_UPDATE_IRQ: +return QXL_IO_UPDATE_IRQ; +case QXL_IO_NOTIFY_OOM: +return QXL_IO_NOTIFY_OOM; +case QXL_IO_RESET: +return QXL_IO_RESET; +case QXL_IO_SET_MODE: +return QXL_IO_SET_MODE; +case QXL_IO_LOG: +return QXL_IO_LOG; +case QXL_IO_MEMSLOT_ADD: +return QXL_IO_MEMSLOT_ADD; +case QXL_IO_MEMSLOT_DEL: +return QXL_IO_MEMSLOT_DEL; +case QXL_IO_DETACH_PRIMARY: +return QXL_IO_DETACH_PRIMARY; +case QXL_IO_ATTACH_PRIMARY: +return QXL_IO_ATTACH_PRIMARY; +case QXL_IO_CREATE_PRIMARY: +return QXL_IO_CREATE_PRIMARY; +case QXL_IO_DESTROY_PRIMARY: +return QXL_IO_DESTROY_PRIMARY; +case QXL_IO_DESTROY_SURFACE_WAIT: +return QXL_IO_DESTROY_SURFACE_WAIT; +case QXL_IO_DESTROY_ALL_SURFACES: +return QXL_IO_DESTROY_ALL_SURFACES; +case QXL_IO_UPDATE_AREA_ASYNC: +return QXL_IO_UPDATE_AREA_ASYNC; +case QXL_IO_MEMSLOT_ADD_ASYNC: +return QXL_IO_MEMSLOT_ADD_ASYNC; +case QXL_IO_CREATE_PRIMARY_ASYNC: +return QXL_IO_CREATE_PRIMARY_ASYNC; +case QXL_IO_DESTROY_PRIMARY_ASYNC: +return QXL_IO_DESTROY_PRIMARY_ASYNC; +case QXL_IO_DESTROY_SURFACE_ASYNC: +return QXL_IO_DESTROY_SURFACE_ASYNC; +case QXL_IO_DESTROY_ALL_SURFACES_ASYNC: +return QXL_IO_DESTROY_ALL_SURFACES_ASYNC; +case QXL_IO_FLUSH_SURFACES_ASYNC: +return QXL_IO_FLUSH_SURFACES_ASYNC; +case QXL_IO_FLUSH_RELEASE: +return QXL_IO_FLUSH_RELEASE; +} +// not reached? +return error in io_port_to_string; +} + /* called from spice server thread context only */ static int interface_get_command(QXLInstance *sin, struct QXLCommandExt *ext) { @@ -997,7 +1056,8 @@ static void ioport_write(void *opaque, uint32_t addr, uint32_t val) default: if (d-mode == QXL_MODE_NATIVE || d-mode == QXL_MODE_COMPAT) break; -dprint(d, 1, %s: unexpected port 0x%x in vga mode\n, __FUNCTION__, io_port); +dprint(d, 1, %s: unexpected port 0x%x (%s) in vga mode\n, +__FUNCTION__, io_port, io_port_to_string(io_port)); return; } -- 1.7.5.4
Re: [Qemu-devel] [PATCH 3/3] hw/omap_gpio.c: Convert to qdev
On 7 July 2011 16:29, andrzej zaborowski balr...@gmail.com wrote: Optimally we should pass the clock as a pointer or name, not only the baudrate (clocks can be stopped, reparented, or have frequency changed dynamically -- in fact the OS will most likely manipulate the uart source clock frequency during init) and the TA region as such instead of only the base. Maybe let's have a short omap_dev_connect_clock function that would use or alias prop_set_ptr or something like that (and a similar thing for the target agent). How about we just have the devices define string properties for the clocks? (and then the device initfn would look the clock up with omap_findclk()). That seems more useful as a user-visible property than a raw pointer. Something like: s-uart[0] = qdev_create(NULL, omap_uart); s-uart[0]-id = uart1; qdev_prop_set_uint32(s-uart[0], mmio_size, 0x1000); qdev_prop_set_string(s-uart[0], clock, uart1_fclk)); qdev_prop_set_chr(s-uart[0], chardev, serial_hds[0]); qdev_init_nofail(s-uart[0]); -- PMM
[Qemu-devel] [PATCH v2] spice: add qemu_spice_display_init_common
From: Gerd Hoffmann kra...@redhat.com Factor out SimpleSpiceDisplay initialization into qemu_spice_display_init_common() and call it from both qxl.c (for vga mode) and spice-display.c Signed-off-by: Gerd Hoffmann kra...@redhat.com --- hw/qxl.c |7 +-- ui/spice-display.c | 17 +++-- ui/spice-display.h |1 + 3 files changed, 13 insertions(+), 12 deletions(-) diff --git a/hw/qxl.c b/hw/qxl.c index 19240da..d92d5b2 100644 --- a/hw/qxl.c +++ b/hw/qxl.c @@ -1315,12 +1315,7 @@ static int qxl_init_primary(PCIDevice *dev) vga-ds = graphic_console_init(qxl_hw_update, qxl_hw_invalidate, qxl_hw_screen_dump, qxl_hw_text_update, qxl); -qxl-ssd.ds = vga-ds; -qemu_mutex_init(qxl-ssd.lock); -qxl-ssd.mouse_x = -1; -qxl-ssd.mouse_y = -1; -qxl-ssd.bufsize = (16 * 1024 * 1024); -qxl-ssd.buf = qemu_malloc(qxl-ssd.bufsize); +qemu_spice_display_init_common(qxl-ssd, vga-ds); qxl0 = qxl; register_displaychangelistener(vga-ds, display_listener); diff --git a/ui/spice-display.c b/ui/spice-display.c index 0433ea8..fef1758 100644 --- a/ui/spice-display.c +++ b/ui/spice-display.c @@ -285,6 +285,16 @@ void qemu_spice_vm_change_state_handler(void *opaque, int running, int reason) ssd-running = running; } +void qemu_spice_display_init_common(SimpleSpiceDisplay *ssd, DisplayState *ds) +{ +ssd-ds = ds; +qemu_mutex_init(ssd-lock); +ssd-mouse_x = -1; +ssd-mouse_y = -1; +ssd-bufsize = (16 * 1024 * 1024); +ssd-buf = qemu_malloc(ssd-bufsize); +} + /* display listener callbacks */ void qemu_spice_display_update(SimpleSpiceDisplay *ssd, @@ -498,12 +508,7 @@ static DisplayChangeListener display_listener = { void qemu_spice_display_init(DisplayState *ds) { assert(sdpy.ds == NULL); -sdpy.ds = ds; -qemu_mutex_init(sdpy.lock); -sdpy.mouse_x = -1; -sdpy.mouse_y = -1; -sdpy.bufsize = (16 * 1024 * 1024); -sdpy.buf = qemu_malloc(sdpy.bufsize); +qemu_spice_display_init_common(sdpy, ds); register_displaychangelistener(ds, display_listener); sdpy.qxl.base.sif = dpy_interface.base; diff --git a/ui/spice-display.h b/ui/spice-display.h index 0effdfa..a39b19d 100644 --- a/ui/spice-display.h +++ b/ui/spice-display.h @@ -75,6 +75,7 @@ void qemu_spice_create_host_memslot(SimpleSpiceDisplay *ssd); void qemu_spice_create_host_primary(SimpleSpiceDisplay *ssd); void qemu_spice_destroy_host_primary(SimpleSpiceDisplay *ssd); void qemu_spice_vm_change_state_handler(void *opaque, int running, int reason); +void qemu_spice_display_init_common(SimpleSpiceDisplay *ssd, DisplayState *ds); void qemu_spice_display_update(SimpleSpiceDisplay *ssd, int x, int y, int w, int h); -- 1.7.5.4
[Qemu-devel] [PATCH v2] qxl: async I/O
Some of the QXL port i/o commands are waiting for the spice server to complete certain actions. Add async versions for these commands, so we don't block the vcpu while the spice server processses the command. Instead the qxl device will raise an IRQ when done. The async command processing relies on an added QXLInterface::async_complete and added QXLWorker::*_async additions, in spice server qxl = 3.1 Signed-off-by: Gerd Hoffmann kra...@redhat.com Signed-off-by: Alon Levy al...@redhat.com --- hw/qxl.c | 244 ++- hw/qxl.h | 21 - ui/spice-display.c | 33 +++ ui/spice-display.h |8 ++ 4 files changed, 261 insertions(+), 45 deletions(-) diff --git a/hw/qxl.c b/hw/qxl.c index 935bac0..f72d5b8 100644 --- a/hw/qxl.c +++ b/hw/qxl.c @@ -136,25 +136,47 @@ void qxl_guest_bug(PCIQXLDevice *qxl, const char *msg, ...) } } +void qxl_spice_update_area_async(PCIQXLDevice *qxl, uint32_t surface_id, + struct QXLRect *area, struct QXLRect *dirty_rects, + uint32_t num_dirty_rects, uint32_t clear_dirty_region, + int async) +{ +if (async) { +qxl-ssd.worker-update_area_async(qxl-ssd.worker, surface_id, area, dirty_rects, + num_dirty_rects, clear_dirty_region, 0); +} else { +qxl-ssd.worker-update_area(qxl-ssd.worker, surface_id, area, dirty_rects, + num_dirty_rects, clear_dirty_region); +} +} void qxl_spice_update_area(PCIQXLDevice *qxl, uint32_t surface_id, struct QXLRect *area, struct QXLRect *dirty_rects, uint32_t num_dirty_rects, uint32_t clear_dirty_region) { -qxl-ssd.worker-update_area(qxl-ssd.worker, surface_id, area, dirty_rects, - num_dirty_rects, clear_dirty_region); +qxl_spice_update_area_async(qxl, surface_id, area, dirty_rects, +num_dirty_rects, clear_dirty_region, 0); } -void qxl_spice_destroy_surface_wait(PCIQXLDevice *qxl, uint32_t id) +static void qxl_spice_destroy_surface_wait_complete(PCIQXLDevice *qxl) { qemu_mutex_lock(qxl-track_lock); -PANIC_ON(id = NUM_SURFACES); -qxl-ssd.worker-destroy_surface_wait(qxl-ssd.worker, id); -qxl-guest_surfaces.cmds[id] = 0; +qxl-guest_surfaces.cmds[qxl-io_data.surface_id] = 0; qxl-guest_surfaces.count--; qemu_mutex_unlock(qxl-track_lock); } +static void qxl_spice_destroy_surface_wait_async(PCIQXLDevice *qxl, uint32_t id, int async) +{ +qxl-io_data.surface_id = id; +if (async) { +qxl-ssd.worker-destroy_surface_wait_async(qxl-ssd.worker, id, 0); +} else { +qxl-ssd.worker-destroy_surface_wait(qxl-ssd.worker, id); +qxl_spice_destroy_surface_wait_complete(qxl); +} +} + void qxl_spice_loadvm_commands(PCIQXLDevice *qxl, struct QXLCommandExt *ext, uint32_t count) { @@ -171,15 +193,29 @@ void qxl_spice_reset_memslots(PCIQXLDevice *qxl) qxl-ssd.worker-reset_memslots(qxl-ssd.worker); } -void qxl_spice_destroy_surfaces(PCIQXLDevice *qxl) +static void qxl_spice_destroy_surfaces_complete(PCIQXLDevice *qxl) { qemu_mutex_lock(qxl-track_lock); -qxl-ssd.worker-destroy_surfaces(qxl-ssd.worker); memset(qxl-guest_surfaces.cmds, 0, sizeof(qxl-guest_surfaces.cmds)); qxl-guest_surfaces.count = 0; qemu_mutex_unlock(qxl-track_lock); } +static void qxl_spice_destroy_surfaces(PCIQXLDevice *qxl) +{ +qxl-ssd.worker-destroy_surfaces(qxl-ssd.worker); +qxl_spice_destroy_surfaces_complete(qxl); +} + +static void qxl_spice_destroy_surfaces_async(PCIQXLDevice *qxl, int async) +{ +if (async) { +qxl-ssd.worker-destroy_surfaces_async(qxl-ssd.worker, 0); +} else { +qxl_spice_destroy_surfaces(qxl); +} +} + void qxl_spice_reset_image_cache(PCIQXLDevice *qxl) { qxl-ssd.worker-reset_image_cache(qxl-ssd.worker); @@ -706,6 +742,38 @@ static int interface_flush_resources(QXLInstance *sin) return ret; } +static void qxl_add_memslot_complete(PCIQXLDevice *d); +static void qxl_create_guest_primary_complete(PCIQXLDevice *d); + +/* called from spice server thread context only */ +static void interface_async_complete(QXLInstance *sin, uint64_t cookie) +{ +PCIQXLDevice *qxl = container_of(sin, PCIQXLDevice, ssd.qxl); +uint32_t current_async; + +qemu_mutex_lock(qxl-async_lock); +current_async = qxl-current_async; +qxl-current_async = QXL_UNDEFINED_IO; +qemu_mutex_unlock(qxl-async_lock); + +dprint(qxl, 1, async_complete: %d (%ld) done\n, current_async, cookie); +switch (current_async) { +case QXL_IO_MEMSLOT_ADD_ASYNC: +qxl_add_memslot_complete(qxl); +break; +case QXL_IO_CREATE_PRIMARY_ASYNC: +qxl_create_guest_primary_complete(qxl); +break; +case
Re: [Qemu-devel] [PATCH] Error: Fix build when qemu-common.h is not included
Am 07.07.2011 18:17, schrieb Michael Roth: On 07/07/2011 11:02 AM, Luiz Capitulino wrote: Commit e4ea5e2d0e0e4c5188ab45b66f3195062ae059dc added the use of the macro GCC_FMT_ATTR to error.h, however qemu-common.h is not included by error.h This will cause a build error when files including error.h don't include qemu-common.h. Not an issue today because the only file including it is json-parser.h and it does include qemu-common.h, but let's fix it. Signed-off-by: Luiz Capitulinolcapitul...@redhat.com --- error.h |2 +- 1 files changed, 1 insertions(+), 1 deletions(-) The same argument could be applied to more QEMU *.h files which also work only after qemu-common.h. Otherwise, including qemu-common.h in *.c files would rarely be needed. As far as I remember, the *.h files used to be more self-contained some years ago, but then the strategy changed and central files like qemu-common.h were introduced. I personally prefer self-contained include files like error.h (before my patch and after your patch), but I'm afraid that the QEMU way is different. Cheers, Stefan W.
Re: [Qemu-devel] [PATCH] Implement the global timer present in ARM MPCore chips.
On Wed, Jul 06, 2011 at 10:58:09PM +0100, Peter Maydell wrote: On 6 July 2011 21:04, Christopher Harvey char...@matrox.com wrote: Below are some random comments noticed on a first-pass. +/* Global timer data */ +static uint64_t global_timer_count = 0; +static uint64_t global_timer_this_inc = 0; + ??/* Only for prescale and enable bits */ +static uint32_t global_timer_control = 0; Static globals look like the wrong thing to me. My C code design is pretty bad. I generally just try to copy the style around what I'm editing. These variables are to be used exclusively inside hw/mpcore.c and are referenced in many of the functions. How would you change this code? thanks, -Chris
[Qemu-devel] [PATCH v2] spice/qxl: move worker wrappers
From: Gerd Hoffmann kra...@redhat.com Move the wrapper functions which are used by qxl only to qxl.c. Rename them from qemu_spice_* to qxl_spice_*. Also pass in a qxl state pointer instead of a SimpleSpiceDisplay pointer. Signed-off-by: Gerd Hoffmann kra...@redhat.com --- hw/qxl-render.c|4 +- hw/qxl.c | 66 hw/qxl.h | 12 + ui/spice-display.c | 45 --- ui/spice-display.h | 11 5 files changed, 70 insertions(+), 68 deletions(-) diff --git a/hw/qxl-render.c b/hw/qxl-render.c index bef5f14..60b822d 100644 --- a/hw/qxl-render.c +++ b/hw/qxl-render.c @@ -124,8 +124,8 @@ void qxl_render_update(PCIQXLDevice *qxl) update.bottom = qxl-guest_primary.surface.height; memset(dirty, 0, sizeof(dirty)); -qemu_spice_update_area(qxl-ssd, 0, update, - dirty, ARRAY_SIZE(dirty), 1); +qxl_spice_update_area(qxl, 0, update, + dirty, ARRAY_SIZE(dirty), 1); for (i = 0; i ARRAY_SIZE(dirty); i++) { if (qemu_spice_rect_is_empty(dirty+i)) { diff --git a/hw/qxl.c b/hw/qxl.c index a405e50..def128d 100644 --- a/hw/qxl.c +++ b/hw/qxl.c @@ -124,6 +124,52 @@ static void qxl_reset_memslots(PCIQXLDevice *d); static void qxl_reset_surfaces(PCIQXLDevice *d); static void qxl_ring_set_dirty(PCIQXLDevice *qxl); + +void qxl_spice_update_area(PCIQXLDevice *qxl, uint32_t surface_id, + struct QXLRect *area, struct QXLRect *dirty_rects, + uint32_t num_dirty_rects, uint32_t clear_dirty_region) +{ +qxl-ssd.worker-update_area(qxl-ssd.worker, surface_id, area, dirty_rects, + num_dirty_rects, clear_dirty_region); +} + +void qxl_spice_destroy_surface_wait(PCIQXLDevice *qxl, uint32_t id) +{ +qxl-ssd.worker-destroy_surface_wait(qxl-ssd.worker, id); +} + +void qxl_spice_loadvm_commands(PCIQXLDevice *qxl, struct QXLCommandExt *ext, + uint32_t count) +{ +qxl-ssd.worker-loadvm_commands(qxl-ssd.worker, ext, count); +} + +void qxl_spice_oom(PCIQXLDevice *qxl) +{ +qxl-ssd.worker-oom(qxl-ssd.worker); +} + +void qxl_spice_reset_memslots(PCIQXLDevice *qxl) +{ +qxl-ssd.worker-reset_memslots(qxl-ssd.worker); +} + +void qxl_spice_destroy_surfaces(PCIQXLDevice *qxl) +{ +qxl-ssd.worker-destroy_surfaces(qxl-ssd.worker); +} + +void qxl_spice_reset_image_cache(PCIQXLDevice *qxl) +{ +qxl-ssd.worker-reset_image_cache(qxl-ssd.worker); +} + +void qxl_spice_reset_cursor(PCIQXLDevice *qxl) +{ +qxl-ssd.worker-reset_cursor(qxl-ssd.worker); +} + + static inline uint32_t msb_mask(uint32_t val) { uint32_t mask; @@ -686,8 +732,8 @@ static void qxl_hard_reset(PCIQXLDevice *d, int loadvm) dprint(d, 1, %s: start%s\n, __FUNCTION__, loadvm ? (loadvm) : ); -qemu_spice_reset_cursor(d-ssd); -qemu_spice_reset_image_cache(d-ssd); +qxl_spice_reset_cursor(d); +qxl_spice_reset_image_cache(d); qxl_reset_surfaces(d); qxl_reset_memslots(d); @@ -812,7 +858,7 @@ static void qxl_del_memslot(PCIQXLDevice *d, uint32_t slot_id) static void qxl_reset_memslots(PCIQXLDevice *d) { dprint(d, 1, %s:\n, __FUNCTION__); -qemu_spice_reset_memslots(d-ssd); +qxl_spice_reset_memslots(d); memset(d-guest_slots, 0, sizeof(d-guest_slots)); } @@ -820,7 +866,7 @@ static void qxl_reset_surfaces(PCIQXLDevice *d) { dprint(d, 1, %s:\n, __FUNCTION__); d-mode = QXL_MODE_UNDEFINED; -qemu_spice_destroy_surfaces(d-ssd); +qxl_spice_destroy_surfaces(d); memset(d-guest_surfaces.cmds, 0, sizeof(d-guest_surfaces.cmds)); } @@ -949,8 +995,8 @@ static void ioport_write(void *opaque, uint32_t addr, uint32_t val) case QXL_IO_UPDATE_AREA: { QXLRect update = d-ram-update_area; -qemu_spice_update_area(d-ssd, d-ram-update_surface, - update, NULL, 0, 0); +qxl_spice_update_area(d, d-ram-update_surface, + update, NULL, 0, 0); break; } case QXL_IO_NOTIFY_CMD: @@ -971,7 +1017,7 @@ static void ioport_write(void *opaque, uint32_t addr, uint32_t val) break; } d-oom_running = 1; -qemu_spice_oom(d-ssd); +qxl_spice_oom(d); d-oom_running = 0; break; case QXL_IO_SET_MODE: @@ -1012,10 +1058,10 @@ static void ioport_write(void *opaque, uint32_t addr, uint32_t val) } break; case QXL_IO_DESTROY_SURFACE_WAIT: -qemu_spice_destroy_surface_wait(d-ssd, val); +qxl_spice_destroy_surface_wait(d, val); break; case QXL_IO_DESTROY_ALL_SURFACES: -qemu_spice_destroy_surfaces(d-ssd); +qxl_spice_destroy_surfaces(d); break; default: fprintf(stderr, %s: ioport=0x%x, abort()\n, __FUNCTION__, io_port); @@ -1415,7 +1461,7 @@ static int
[Qemu-devel] Upstream Qemu With Xen configuration problem
Greetings, I am trying to configure Xen4.2 unstable with upstream qemu. I am running on a small problem when running the configuration of qemu, Qemu Config can not find Xen. I have debugged the Configuration script and the temp c file that qemu uses to detect xen version are returning empty string, hence the config script can tell xen version. Xen with staging branch works fine. My configure call is as follows: ./configure --enable-xen --target-list=i386-softmmu --extra-cflags=-I/usr/src/xen-unstable.hg/dist/install/usr/include --extra-ldflags=-L/usr/src/xen-unstable.hg/dist/install/usr/lib --enable-debug The contents of /usr/src/xen-unstable.hg/dist/install/usr/include are: blktaplib.h libxl.h temp.c xenguest.hxs_lib.h fsimage_grub.h_libxl_types.h xen xenstat.h fsimage.h libxl_utils.h xenctrl.h xentoollog.h fsimage_plugin.h libxl_uuid.hxenctrlosdep.h xs.h The contents of /usr/src/xen-unstable.hg/dist/install/usr/lib are: python2.7 xen Qemu is on master branch 744d3644181ddb16ef5944a0f9217e46961c8c84 pxa2xx_lcd: add proper rotation support Xen is on unstable branch 23608:2f63562df1c4 libxl: Do not SEGV when no 'removable' disk parameter in xenstore I can change xen changeset freely, but I can not change qemu changeset since I need some features present in qemu. Any help, or pointers are greatly appreciated. Thanks for your time, Daniel -- +-=---+ | +-+ | This space intentionally blank for notetaking. | | | Daniel Castro, | | | | Consultant/Programmer.| | | | U Andes | +-+
[Qemu-devel] [PATCH v2] async + suspend reworked
Everything is based on spice.v38 from git://anongit.freedesktop.org/spice/qemu v1-v2 changes: dropped wlock dropped oom_async update_area_async used in qxl-render added async_lock async_complete handles completion of io, not at dispatcher call time Git trees: git://anongit.freedesktop.org/~alon/qemus3.v4.async.api.v2 git://anongit.freedesktop.org/~alon/spice s3.v3.async.v3 git://anongit.freedesktop.org/~alon/spice-protocol s3.v2 git://anongit.freedesktop.org/~alon/qxl s3.v3.async.v3 Alon Levy (7): qxl: add io_port_to_string qxl: make qxl_guest_bug take variable arguments qxl: async I/O qxl: only disallow specific io's in vga mode qxl: add QXL_IO_FLUSH_{SURFACES,RELEASE} for guest S3S4 support qxl: use QXL_REVISION_* qxl: use update_area_async in qxl-render Gerd Hoffmann (7): spice: add worker wrapper functions. spice: add qemu_spice_display_init_common qxl: remove qxl_destroy_primary() spice/qxl: move worker wrappers qxl: fix surface tracking locking qxl: error handling fixes and cleanups. qxl: bump pci rev hw/qxl-render.c|4 +- hw/qxl.c | 467 +++- hw/qxl.h | 32 - ui/spice-display.c | 99 ++-- ui/spice-display.h | 18 ++ 5 files changed, 530 insertions(+), 90 deletions(-) -- 1.7.5.4
[Qemu-devel] [PATCH v2] qxl: use QXL_REVISION_*
--- hw/qxl.c | 24 +++- 1 files changed, 11 insertions(+), 13 deletions(-) diff --git a/hw/qxl.c b/hw/qxl.c index 4007847..54ee5f5 100644 --- a/hw/qxl.c +++ b/hw/qxl.c @@ -1551,7 +1551,6 @@ static DisplayChangeListener display_listener = { static int qxl_init_common(PCIQXLDevice *qxl) { uint8_t* config = qxl-pci.config; -uint32_t pci_device_rev; uint32_t io_size; qxl-mode = QXL_MODE_UNDEFINED; @@ -1563,19 +1562,18 @@ static int qxl_init_common(PCIQXLDevice *qxl) qxl-current_async = QXL_UNDEFINED_IO; switch (qxl-revision) { -case 1: /* spice 0.4 -- qxl-1 */ -pci_device_rev = QXL_REVISION_STABLE_V04; +case QXL_REVISION_STABLE_V04: /* spice 0.4 -- qxl-1 */ +case QXL_REVISION_STABLE_V06: /* spice 0.6 -- qxl-2 */ +case QXL_REVISION_STABLE_V10: /* spice 0.10? -- qxl-3 */ break; -case 2: /* spice 0.6 -- qxl-2 */ -pci_device_rev = QXL_REVISION_STABLE_V06; -break; -case 3: /* qxl-3 */ default: -pci_device_rev = 3; +fprintf(stderr, invalid revision %d, resetting to %d\n, qxl-revision, +QXL_REVISION_STABLE_V10); +qxl-revision = QXL_REVISION_STABLE_V10; break; } -pci_set_byte(config[PCI_REVISION_ID], pci_device_rev); +pci_set_byte(config[PCI_REVISION_ID], qxl-revision); pci_set_byte(config[PCI_INTERRUPT_PIN], 1); qxl-rom_size = qxl_rom_size(); @@ -1586,14 +1584,14 @@ static int qxl_init_common(PCIQXLDevice *qxl) if (qxl-vram_size 16 * 1024 * 1024) { qxl-vram_size = 16 * 1024 * 1024; } -if (qxl-revision == 1) { +if (qxl-revision == QXL_REVISION_STABLE_V04) { qxl-vram_size = 4096; } qxl-vram_size = msb_mask(qxl-vram_size * 2 - 1); qxl-vram_offset = qemu_ram_alloc(qxl-pci.qdev, qxl.vram, qxl-vram_size); io_size = msb_mask(QXL_IO_RANGE_SIZE * 2 - 1); -if (qxl-revision == 1) { +if (qxl-revision == QXL_REVISION_STABLE_V04) { io_size = 8; } @@ -1836,7 +1834,7 @@ static PCIDeviceInfo qxl_info_primary = { .qdev.props = (Property[]) { DEFINE_PROP_UINT32(ram_size, PCIQXLDevice, vga.vram_size, 64 * 1024 * 1024), DEFINE_PROP_UINT32(vram_size, PCIQXLDevice, vram_size, 64 * 1024 * 1024), -DEFINE_PROP_UINT32(revision, PCIQXLDevice, revision, 3), +DEFINE_PROP_UINT32(revision, PCIQXLDevice, revision, QXL_REVISION_STABLE_V10), DEFINE_PROP_UINT32(debug, PCIQXLDevice, debug, 0), DEFINE_PROP_UINT32(guestdebug, PCIQXLDevice, guestdebug, 0), DEFINE_PROP_UINT32(cmdlog, PCIQXLDevice, cmdlog, 0), @@ -1857,7 +1855,7 @@ static PCIDeviceInfo qxl_info_secondary = { .qdev.props = (Property[]) { DEFINE_PROP_UINT32(ram_size, PCIQXLDevice, vga.vram_size, 64 * 1024 * 1024), DEFINE_PROP_UINT32(vram_size, PCIQXLDevice, vram_size, 64 * 1024 * 1024), -DEFINE_PROP_UINT32(revision, PCIQXLDevice, revision, 3), +DEFINE_PROP_UINT32(revision, PCIQXLDevice, revision, QXL_REVISION_STABLE_V10), DEFINE_PROP_UINT32(debug, PCIQXLDevice, debug, 0), DEFINE_PROP_UINT32(guestdebug, PCIQXLDevice, guestdebug, 0), DEFINE_PROP_UINT32(cmdlog, PCIQXLDevice, cmdlog, 0), -- 1.7.5.4
[Qemu-devel] [PATCH v2] qxl: remove qxl_destroy_primary()
From: Gerd Hoffmann kra...@redhat.com We'll have to move qemu_spice_destroy_primary_surface() out of qxl_destroy_primary(). That makes the function pretty pointless, so zap it and open code the two lines instead. Signed-off-by: Gerd Hoffmann kra...@redhat.com --- hw/qxl.c | 28 1 files changed, 12 insertions(+), 16 deletions(-) diff --git a/hw/qxl.c b/hw/qxl.c index d92d5b2..a405e50 100644 --- a/hw/qxl.c +++ b/hw/qxl.c @@ -120,7 +120,6 @@ static QXLMode qxl_modes[] = { static PCIQXLDevice *qxl0; static void qxl_send_events(PCIQXLDevice *d, uint32_t events); -static void qxl_destroy_primary(PCIQXLDevice *d); static void qxl_reset_memslots(PCIQXLDevice *d); static void qxl_reset_surfaces(PCIQXLDevice *d); static void qxl_ring_set_dirty(PCIQXLDevice *qxl); @@ -617,7 +616,10 @@ static void qxl_exit_vga_mode(PCIQXLDevice *d) return; } dprint(d, 1, %s\n, __FUNCTION__); -qxl_destroy_primary(d); +if (d-mode != QXL_MODE_UNDEFINED) { +d-mode = QXL_MODE_UNDEFINED; +qemu_spice_destroy_primary_surface(d-ssd, 0); +} } static void qxl_set_irq(PCIQXLDevice *d) @@ -714,7 +716,10 @@ static void qxl_vga_ioport_write(void *opaque, uint32_t addr, uint32_t val) if (qxl-mode != QXL_MODE_VGA) { dprint(qxl, 1, %s\n, __FUNCTION__); -qxl_destroy_primary(qxl); +if (qxl-mode != QXL_MODE_UNDEFINED) { +qxl-mode = QXL_MODE_UNDEFINED; +qemu_spice_destroy_primary_surface(qxl-ssd, 0); +} qxl_soft_reset(qxl); } vga_ioport_write(opaque, addr, val); @@ -875,18 +880,6 @@ static void qxl_create_guest_primary(PCIQXLDevice *qxl, int loadvm) qxl_render_resize(qxl); } -static void qxl_destroy_primary(PCIQXLDevice *d) -{ -if (d-mode == QXL_MODE_UNDEFINED) { -return; -} - -dprint(d, 1, %s\n, __FUNCTION__); - -d-mode = QXL_MODE_UNDEFINED; -qemu_spice_destroy_primary_surface(d-ssd, 0); -} - static void qxl_set_mode(PCIQXLDevice *d, int modenr, int loadvm) { pcibus_t start = d-pci.io_regions[QXL_RAM_RANGE_INDEX].addr; @@ -1013,7 +1006,10 @@ static void ioport_write(void *opaque, uint32_t addr, uint32_t val) case QXL_IO_DESTROY_PRIMARY: PANIC_ON(val != 0); dprint(d, 1, QXL_IO_DESTROY_PRIMARY (%s)\n, qxl_mode_to_string(d-mode)); -qxl_destroy_primary(d); +if (d-mode != QXL_MODE_UNDEFINED) { +d-mode = QXL_MODE_UNDEFINED; +qemu_spice_destroy_primary_surface(d-ssd, 0); +} break; case QXL_IO_DESTROY_SURFACE_WAIT: qemu_spice_destroy_surface_wait(d-ssd, val); -- 1.7.5.4
Re: [Qemu-devel] [PATCH] Error: Fix build when qemu-common.h is not included
On Thu, 07 Jul 2011 18:50:28 +0200 Stefan Weil w...@mail.berlios.de wrote: Am 07.07.2011 18:17, schrieb Michael Roth: On 07/07/2011 11:02 AM, Luiz Capitulino wrote: Commit e4ea5e2d0e0e4c5188ab45b66f3195062ae059dc added the use of the macro GCC_FMT_ATTR to error.h, however qemu-common.h is not included by error.h This will cause a build error when files including error.h don't include qemu-common.h. Not an issue today because the only file including it is json-parser.h and it does include qemu-common.h, but let's fix it. Signed-off-by: Luiz Capitulinolcapitul...@redhat.com --- error.h |2 +- 1 files changed, 1 insertions(+), 1 deletions(-) The same argument could be applied to more QEMU *.h files which also work only after qemu-common.h. Otherwise, including qemu-common.h in *.c files would rarely be needed. As far as I remember, the *.h files used to be more self-contained some years ago, but then the strategy changed and central files like qemu-common.h were introduced. I personally prefer self-contained include files like error.h (before my patch and after your patch), but I'm afraid that the QEMU way is different. The current way is broken. Some qemu header files are a complete mess. qemu-common.h and sysemu.h are good examples. They include too many things, if you change them a lot of code will be recompiled. I could make the problem less worse by moving all compiler related macros to a compiler.h header and then include it in qemu-common.h and error.h. This way error.h won't be affected, although the real problem will remain unsolved.
Re: [Qemu-devel] [libvirt-users] SSH console for qemu
On 07/07/2011 02:36 AM, Nikita A Menkovich wrote: Seems no, I think, that the best way is running some kind of ssh daemon, that connects to console (/dev/vcsa1 for example), that listen on port and send to output console events on boot, and allow to work with server with simple ssh client. Also important feature will be saving history of output. If you're trying to capture boot events, then you have to have an SGA (serial graphics adaptor) capable BIOS that can output boot events on the serial console. There's recent work underway to add that feature to qemu, and to expose that feature from libvirt: https://www.redhat.com/archives/libvir-list/2011-July/msg00174.html Setting up an ssh daemon in the guest is too late - the daemon won't be set up until the guest has already booted, so there's no way to have that daemon forward boot messages back to the host in a timely manner. I think you're trying too hard - 'virsh console' really is the way to read all messages output to the guest's console, and your only missing piece is that you also appear to want BIOS to output to the console. -- Eric Blake ebl...@redhat.com+1-801-349-2682 Libvirt virtualization library http://libvirt.org signature.asc Description: OpenPGP digital signature
[Qemu-devel] [Bug 568614] Re: x86_64 host curses interface: spacing/garbling
How about using CONFIG_CURSES? If we --enable-curses, then we know we have curses.h and chtype. If we --disable-curses, then we don't care. Patch attached. It's a no-op if curses is disabled, and it fixes the issue on my machine with curses enabled. I had to undef the color constants from curses.h so we didn't conflict with enum color_names in console.c. ** Patch added: ifdef CONFIG_CURSES, use chtype https://bugs.launchpad.net/qemu/+bug/568614/+attachment/2195896/+files/chtype.diff -- You received this bug notification because you are a member of qemu- devel-ml, which is subscribed to QEMU. https://bugs.launchpad.net/bugs/568614 Title: x86_64 host curses interface: spacing/garbling Status in QEMU: In Progress Bug description: Environment: Arch Linux x86_64, kernel 2.6.33, qemu 0.12.3 Steps to reproduce: 1. Have a host system running 64-bit Linux. 2. Start a qemu VM with the -curses flag. Expected results: Text displayed looks as it would on a real text-mode display, and VM is therefore usable. Actual results: Text displayed contains an extra space between characters, causing text to flow off the right and bottom sides of the screen. This makes the curses interface unintelligible. The attached patch fixes this problem on 0.12.3 on my installation without changing behavior on a 32-bit machine. I don't know enough of the semantics of console_ch_t to know if this is the correct fix or if there should be, say, an extra cast somewhere instead. To manage notifications about this bug go to: https://bugs.launchpad.net/qemu/+bug/568614/+subscriptions
Re: [Qemu-devel] Upstream Qemu With Xen configuration problem
I find I have to point at the src directories, and not the dist directory. My extra-cflags looks something like this: --extra-cflags=-I /path/to/xen/tools/include -L /path/to/xen/tools/libxc -I /path/to/xen/tools/libxc -L /path/to/xen/tools/xenstore -I /path/to/xen/tools/xenstore' -John On 07/07/2011 01:17 PM, Daniel Castro wrote: Greetings, I am trying to configure Xen4.2 unstable with upstream qemu. I am running on a small problem when running the configuration of qemu, Qemu Config can not find Xen. I have debugged the Configuration script and the temp c file that qemu uses to detect xen version are returning empty string, hence the config script can tell xen version. Xen with staging branch works fine. My configure call is as follows: ./configure --enable-xen --target-list=i386-softmmu --extra-cflags=-I/usr/src/xen-unstable.hg/dist/install/usr/include --extra-ldflags=-L/usr/src/xen-unstable.hg/dist/install/usr/lib --enable-debug The contents of /usr/src/xen-unstable.hg/dist/install/usr/include are: blktaplib.h libxl.h temp.c xenguest.hxs_lib.h fsimage_grub.h_libxl_types.h xen xenstat.h fsimage.h libxl_utils.h xenctrl.h xentoollog.h fsimage_plugin.h libxl_uuid.hxenctrlosdep.h xs.h The contents of /usr/src/xen-unstable.hg/dist/install/usr/lib are: python2.7 xen Qemu is on master branch 744d3644181ddb16ef5944a0f9217e46961c8c84 pxa2xx_lcd: add proper rotation support Xen is on unstable branch 23608:2f63562df1c4 libxl: Do not SEGV when no 'removable' disk parameter in xenstore I can change xen changeset freely, but I can not change qemu changeset since I need some features present in qemu. Any help, or pointers are greatly appreciated. Thanks for your time, Daniel
Re: [Qemu-devel] SSH console for qemu
On Thu, Jul 7, 2011 at 9:36 AM, Nikita A Menkovich menkov...@gmail.com wrote: Seems no, I think, that the best way is running some kind of ssh daemon, that connects to console (/dev/vcsa1 for example), that listen on port and send to output console events on boot, and allow to work with server with simple ssh client. Also important feature will be saving history of output. If you configure an ssh daemon properly you can have it invoke virsh console domain as the shell. Remember to lock down port forwarding and sftp. Stefan
Re: [Qemu-devel] [libvirt-users] SSH console for qemu
I want to launch very minimal ssh daemon (that listen on selected port and allows only input commands and read output from console) that launch when guest started, and this not run inside a guest. Thanks to the link for patch On 7 July 2011 22:19, Eric Blake ebl...@redhat.com wrote: On 07/07/2011 02:36 AM, Nikita A Menkovich wrote: Seems no, I think, that the best way is running some kind of ssh daemon, that connects to console (/dev/vcsa1 for example), that listen on port and send to output console events on boot, and allow to work with server with simple ssh client. Also important feature will be saving history of output. If you're trying to capture boot events, then you have to have an SGA (serial graphics adaptor) capable BIOS that can output boot events on the serial console. There's recent work underway to add that feature to qemu, and to expose that feature from libvirt: https://www.redhat.com/archives/libvir-list/2011-July/msg00174.html Setting up an ssh daemon in the guest is too late - the daemon won't be set up until the guest has already booted, so there's no way to have that daemon forward boot messages back to the host in a timely manner. I think you're trying too hard - 'virsh console' really is the way to read all messages output to the guest's console, and your only missing piece is that you also appear to want BIOS to output to the console. -- Eric Blake ebl...@redhat.com +1-801-349-2682 Libvirt virtualization library http://libvirt.org -- Nikita A Menkovich http://libc6.org/ JID: menkov...@gmail.com Tel: +7 (921) 423-96-48
Re: [Qemu-devel] [PATCH v2] XBRLE page delta compression for live migration of large memory apps
On Wed, Jul 6, 2011 at 1:01 PM, Shribman, Aidan aidan.shrib...@sap.com wrote: Subject: [PATCH v2] XBRLE page delta compression for live migration of large memory apps From: Aidan Shribman aidan.shrib...@sap.com Work is based on research results published VEE 2011: Evaluation of Delta Compression Techniques for Efficient Live Migration of Large Virtual Machines by Benoit, Svard, Tordsson and Elmroth. Out of interest, why did ARC not work well as the caching algorithm? Did you try it out and measure its performance? Stefan
Re: [Qemu-devel] [PATCH 2/3] Add fno-strict-overflow
* On Tue, Jul 05, 2011 at 09:30:44PM +0100, Stefan Hajnoczi stefa...@gmail.com wrote: On Tue, Jul 5, 2011 at 4:36 PM, Raghavendra D Prabhu raghu.prabh...@gmail.com wrote: * On Mon, Jul 04, 2011 at 11:38:30PM +0100, Peter Maydell peter.mayd...@linaro.org wrote: On 4 July 2011 23:00, Raghavendra D Prabhu raghu.prabh...@gmail.com wrote: This is to avoid gcc optimizating out the comparison in assert, due to assumption of signed overflow being undefined by default (-Werror=strict-overflow). --- a/Makefile.hw +++ b/Makefile.hw @@ -9,7 +9,7 @@ include $(SRC_PATH)/rules.mak $(call set-vpath, $(SRC_PATH):$(SRC_PATH)/hw) -QEMU_CFLAGS+=-I.. -I$(SRC_PATH)/fpu +QEMU_CFLAGS+=-I.. -I$(SRC_PATH)/fpu -fno-strict-overflow Can you give a more detailed description of the problem this is trying to solve? I think it would be nicer if we could remove the assumptions about signed overflows instead, if that's practical. Following line in pcie.c:pcie_add_capability:505 assert(offset offset + size); is what the compiler was warning about. The compiler optimizes out that comparison without fno-strict-overflow flag. More information about it is here - http://www.airs.com/blog/archives/120 -- as already mentioned by Stefan. (Also, if we do want to add this compiler flag then it ought to be done in configure I think, as we do for -fno-strict-aliasing.) Globally adding that flag can limits the optimizations of gcc since in other places (loops) the undefined behavior can be advantageous, hence added only to Makefile.hw. Doing this on a per-subsystem or per-file basis does not make sense to me. This is a general C coding issue that needs to be settled for the entire codebase. We will not catch instances of overflow slipping in during patch review, so limiting the scope of -fno-strict-overflow is not feasible. I suggest we cover all of QEMU with -fwrapv instead of worrying about -fno-strict-overflow. That way we can get some optimizations and it reflects the model that we are all assuming: This option instructs the compiler to assume that signed arithmetic overflow of addition, subtraction and multiplication wraps around using twos-complement representation. This flag enables some optimizations and disables others. This option is enabled by default for the Java front-end, as required by the Java language specification. http://gcc.gnu.org/onlinedocs/gcc-4.4.2/gcc/Code-Gen-Options.html Stefan I have removed that option from Makefile; instead replaced it with another assert which shouldn't be affected by overflow. === diff --git a/Makefile.hw b/Makefile.hw index 23dac45..b9181ab 100644 --- a/Makefile.hw +++ b/Makefile.hw @@ -9,7 +9,7 @@ include $(SRC_PATH)/rules.mak $(call set-vpath, $(SRC_PATH):$(SRC_PATH)/hw) -QEMU_CFLAGS+=-I.. -I$(SRC_PATH)/fpu -fno-strict-overflow +QEMU_CFLAGS+=-I.. -I$(SRC_PATH)/fpu include $(SRC_PATH)/Makefile.objs diff --git a/hw/pcie.c b/hw/pcie.c index 39607bf..cfb11fe 100644 --- a/hw/pcie.c +++ b/hw/pcie.c @@ -502,7 +502,7 @@ void pcie_add_capability(PCIDevice *dev, uint16_t next; assert(offset = PCI_CONFIG_SPACE_SIZE); -assert(offset offset + size); +assert(UINT_MAX - size offset); assert(offset + size PCIE_CONFIG_SPACE_SIZE); assert(size = 8); assert(pci_is_express(dev)); -- Raghavendra Prabhu GPG Id : 0xD72BE977 Fingerprint: B93F EBCB 8E05 7039 CD3C A4B8 A616 DCA1 D72B E977 www: wnohang.net pgpWBEVNiNbuF.pgp Description: PGP signature
[Qemu-devel] [PATCH v2 0/4] ppc: booke206: KVM MMU API and info tlb
Scott Wood (4): kvm: ppc: Update KVM headers for MMU API kvm: ppc: booke206: use MMU API ppc: booke206: use MAV=2.0 TSIZE definition, fix 4G pages ppc: booke206: add info tlb support hmp-commands.hx |2 +- hw/ppce500_mpc8544ds.c |4 +- linux-headers/asm-powerpc/kvm.h | 39 +++- linux-headers/linux/kvm.h | 27 --- monitor.c |5 +- target-ppc/cpu.h|8 +++- target-ppc/helper.c | 93 ++- target-ppc/kvm.c| 83 ++ 8 files changed, 244 insertions(+), 17 deletions(-) -- 1.7.4.1
[Qemu-devel] [PATCH 1/4] kvm: ppc: Update KVM headers for MMU API
Signed-off-by: Scott Wood scottw...@freescale.com --- linux-headers/asm-powerpc/kvm.h | 39 +-- linux-headers/linux/kvm.h | 27 --- 2 files changed, 57 insertions(+), 9 deletions(-) diff --git a/linux-headers/asm-powerpc/kvm.h b/linux-headers/asm-powerpc/kvm.h index 777d307..1a6dedf 100644 --- a/linux-headers/asm-powerpc/kvm.h +++ b/linux-headers/asm-powerpc/kvm.h @@ -166,8 +166,8 @@ struct kvm_sregs { } ppc64; struct { __u32 sr[16]; - __u64 ibat[8]; - __u64 dbat[8]; + __u64 ibat[8]; + __u64 dbat[8]; } ppc32; } s; struct { @@ -272,4 +272,39 @@ struct kvm_guest_debug_arch { #define KVM_INTERRUPT_UNSET-2U #define KVM_INTERRUPT_SET_LEVEL-3U +struct kvm_book3e_206_tlb_entry { + __u32 mas8; + __u32 mas1; + __u64 mas2; + __u64 mas7_3; +}; + +struct kvm_book3e_206_tlb_params { + /* +* For mmu types KVM_MMU_FSL_BOOKE_NOHV and KVM_MMU_FSL_BOOKE_HV: +* +* - The number of ways of TLB0 must be a power of two between 2 and +* 16. +* - TLB1 must be fully associative. +* - The size of TLB0 must be a multiple of the number of ways, and +* the number of sets must be a power of two. +* - The size of TLB1 may not exceed 64 entries. +* - TLB0 supports 4 KiB pages. +* - The page sizes supported by TLB1 are as indicated by +* TLB1CFG (if MMUCFG[MAVN] = 0) or TLB1PS (if MMUCFG[MAVN] = 1) +* as returned by KVM_GET_SREGS. +* - TLB2 and TLB3 are reserved, and their entries in tlb_sizes[] +* and tlb_ways[] must be zero. +* +* tlb_ways[n] = tlb_sizes[n] means the array is fully associative. +* +* KVM will adjust TLBnCFG based on the sizes configured here, +* though arrays greater than 2048 entries will have TLBnCFG[NENTRY] +* set to zero. +*/ + __u32 tlb_sizes[4]; + __u32 tlb_ways[4]; + __u32 reserved[8]; +}; + #endif /* __LINUX_KVM_POWERPC_H */ diff --git a/linux-headers/linux/kvm.h b/linux-headers/linux/kvm.h index fc63b73..2228642 100644 --- a/linux-headers/linux/kvm.h +++ b/linux-headers/linux/kvm.h @@ -544,6 +544,7 @@ struct kvm_ppc_pvinfo { #define KVM_CAP_TSC_CONTROL 60 #define KVM_CAP_GET_TSC_KHZ 61 #define KVM_CAP_PPC_BOOKE_SREGS 62 +#define KVM_CAP_SW_TLB 63 #ifdef KVM_CAP_IRQ_ROUTING @@ -623,6 +624,21 @@ struct kvm_clock_data { __u32 pad[9]; }; +#define KVM_MMU_FSL_BOOKE_NOHV 0 +#define KVM_MMU_FSL_BOOKE_HV 1 + +struct kvm_config_tlb { + __u64 params; + __u64 array; + __u32 mmu_type; + __u32 array_len; +}; + +struct kvm_dirty_tlb { + __u64 bitmap; + __u32 num_dirty; +}; + /* * ioctls for VM fds */ @@ -746,6 +762,9 @@ struct kvm_clock_data { /* Available with KVM_CAP_XCRS */ #define KVM_GET_XCRS _IOR(KVMIO, 0xa6, struct kvm_xcrs) #define KVM_SET_XCRS _IOW(KVMIO, 0xa7, struct kvm_xcrs) +/* Available with KVM_CAP_SW_TLB */ +#define KVM_CONFIG_TLB _IOW(KVMIO, 0xa8, struct kvm_config_tlb) +#define KVM_DIRTY_TLB_IOW(KVMIO, 0xa9, struct kvm_dirty_tlb) #define KVM_DEV_ASSIGN_ENABLE_IOMMU(1 0) @@ -773,20 +792,14 @@ struct kvm_assigned_pci_dev { struct kvm_assigned_irq { __u32 assigned_dev_id; - __u32 host_irq; + __u32 host_irq; /* ignored (legacy field) */ __u32 guest_irq; __u32 flags; union { - struct { - __u32 addr_lo; - __u32 addr_hi; - __u32 data; - } guest_msi; __u32 reserved[12]; }; }; - struct kvm_assigned_msix_nr { __u32 assigned_dev_id; __u16 entry_nr; -- 1.7.4.1
Re: [Qemu-devel] SeaBIOS error with Juniper FreeBSD kernel
On Thu, Jul 07, 2011 at 05:45:02PM +0200, Bjørn Mork wrote: It's been a while with little work and little progress on my side... But I looked at this again today, and found that it may be related to the SMBIOS table being allocated with malloc_high(). Does that make sense? Anyway, the problematic OS boots without problems with current seabios from git if I make this change: diff --git a/src/smbios.c b/src/smbios.c index 8df0f2d..c96deb5 100644 --- a/src/smbios.c +++ b/src/smbios.c @@ -17,7 +17,7 @@ smbios_entry_point_init(u16 max_structure_size, u16 number_of_structures) { struct smbios_entry_point *ep = malloc_fseg(sizeof(*ep)); -void *finaltable = malloc_high(structure_table_length); +void *finaltable = malloc_fseg(structure_table_length); if (!ep || !finaltable) { warn_noalloc(); free(ep); Thanks. It's possible that the OS has an error in handling the SMBIOS when it is in high-memory (located above 1meg). (For example, older versions of Linux crash when the mptable is in high memory.) However, it would be really odd for the OS to work some times with the SMBIOS in high memory and sometimes fail. I tried malloc_low() too, and that works as well. But malloc_fseg() seems appropriate, unless I've misunderstood something here. Which very well can be. I am not going to claim any understanding at all. malloc_low and malloc_fseg would both put the table in the first megabyte of physical ram. Of the two, malloc_fseg would be preferable. Does the above make any sense, or is this just another example of tickling the underlying bug? I have to wonder if the reorganization of memory just caused the bug to not pop up. If you disable SMBIOS, can you confirm the problem reliably goes away on multiple versions of SeaBIOS? -Kevin
[Qemu-devel] [PATCH v2 2/4] kvm: ppc: booke206: use MMU API
Share the TLB array with KVM. This allows us to set the initial TLB both on initial boot and reset, is useful for debugging, and could eventually be used to support migration. Signed-off-by: Scott Wood scottw...@freescale.com --- v2: - rebase on top of current tree, remove now-unneeded ifdefs - add some asserts and comments as requested hw/ppce500_mpc8544ds.c |2 + target-ppc/cpu.h |2 + target-ppc/kvm.c | 83 3 files changed, 87 insertions(+), 0 deletions(-) diff --git a/hw/ppce500_mpc8544ds.c b/hw/ppce500_mpc8544ds.c index b739ce2..3626e26 100644 --- a/hw/ppce500_mpc8544ds.c +++ b/hw/ppce500_mpc8544ds.c @@ -202,6 +202,8 @@ static void mmubooke_create_initial_mapping(CPUState *env, tlb-mas2 = va TARGET_PAGE_MASK; tlb-mas7_3 = pa TARGET_PAGE_MASK; tlb-mas7_3 |= MAS3_UR | MAS3_UW | MAS3_UX | MAS3_SR | MAS3_SW | MAS3_SX; + +env-tlb_dirty = true; } static void mpc8544ds_cpu_reset(void *opaque) diff --git a/target-ppc/cpu.h b/target-ppc/cpu.h index 84f8ff6..f8bf2b1 100644 --- a/target-ppc/cpu.h +++ b/target-ppc/cpu.h @@ -921,6 +921,8 @@ struct CPUPPCState { ppc_tlb_t tlb; /* TLB is optional. Allocate them only if needed*/ /* 403 dedicated access protection registers */ target_ulong pb[4]; +bool tlb_dirty; /* Set to non-zero when modifying TLB */ +bool kvm_sw_tlb; /* non-zero if KVM SW TLB API is active*/ #endif /* Other registers */ diff --git a/target-ppc/kvm.c b/target-ppc/kvm.c index 21f35af7..e18c931 100644 --- a/target-ppc/kvm.c +++ b/target-ppc/kvm.c @@ -105,6 +105,50 @@ static int kvm_arch_sync_sregs(CPUState *cenv) return kvm_vcpu_ioctl(cenv, KVM_SET_SREGS, sregs); } +/* Set up a shared TLB array with KVM */ +static int kvm_booke206_tlb_init(CPUState *env) +{ +struct kvm_book3e_206_tlb_params params = {}; +struct kvm_config_tlb cfg = {}; +size_t array_len; +unsigned int entries = 0; +int ret, i; + +if (!kvm_enabled() || +!kvm_check_extension(env-kvm_state, KVM_CAP_SW_TLB)) { +return 0; +} + +assert(ARRAY_SIZE(params.tlb_sizes) == BOOKE206_MAX_TLBN); + +for (i = 0; i BOOKE206_MAX_TLBN; i++) { +params.tlb_sizes[i] = booke206_tlb_size(env, i); +params.tlb_ways[i] = booke206_tlb_ways(env, i); +entries += params.tlb_sizes[i]; +} + +assert(entries == env-nb_tlb); +assert(sizeof(struct kvm_book3e_206_tlb_entry) == sizeof(ppcmas_tlb_t)); + +array_len = sizeof(ppcmas_tlb_t) * entries; +env-tlb_dirty = true; + +cfg.array = (uintptr_t)env-tlb.tlbm; +cfg.array_len = sizeof(ppcmas_tlb_t) * entries; +cfg.params = (uintptr_t)params; +cfg.mmu_type = KVM_MMU_FSL_BOOKE_NOHV; + +ret = kvm_vcpu_ioctl(env, KVM_CONFIG_TLB, cfg); +if (ret 0) { +fprintf(stderr, %s: couldn't KVM_CONFIG_TLB: %s\n, +__func__, strerror(-ret)); +return ret; +} + +env-kvm_sw_tlb = true; +return 0; +} + int kvm_arch_init_vcpu(CPUState *cenv) { int ret; @@ -116,6 +160,15 @@ int kvm_arch_init_vcpu(CPUState *cenv) idle_timer = qemu_new_timer_ns(vm_clock, kvm_kick_env, cenv); +/* Some targets support access to KVM's guest TLB. */ +switch (cenv-mmu_model) { +case POWERPC_MMU_BOOKE206: +ret = kvm_booke206_tlb_init(cenv); +break; +default: +break; +} + return ret; } @@ -123,6 +176,31 @@ void kvm_arch_reset_vcpu(CPUState *env) { } +static void kvm_sw_tlb_put(CPUState *env) +{ +struct kvm_dirty_tlb dirty_tlb; +unsigned char *bitmap; +int ret; + +if (!env-kvm_sw_tlb) { +return; +} + +bitmap = qemu_malloc((env-nb_tlb + 7) / 8); +memset(bitmap, 0xFF, (env-nb_tlb + 7) / 8); + +dirty_tlb.bitmap = (uintptr_t)bitmap; +dirty_tlb.num_dirty = env-nb_tlb; + +ret = kvm_vcpu_ioctl(env, KVM_DIRTY_TLB, dirty_tlb); +if (ret) { +fprintf(stderr, %s: KVM_DIRTY_TLB: %s\n, +__func__, strerror(-ret)); +} + +qemu_free(bitmap); +} + int kvm_arch_put_registers(CPUState *env, int level) { struct kvm_regs regs; @@ -160,6 +238,11 @@ int kvm_arch_put_registers(CPUState *env, int level) if (ret 0) return ret; +if (env-tlb_dirty) { +kvm_sw_tlb_put(env); +env-tlb_dirty = false; +} + return ret; } -- 1.7.4.1
[Qemu-devel] [PATCH 3/4] ppc: booke206: use MAV=2.0 TSIZE definition, fix 4G pages
This definition is backward compatible with MAV=1.0 as long as the guest does not set reserved bits in MAS1/MAS4. Also, fix the shift in booke206_tlb_to_page_size -- it's the base that should be able to hold a 4G page size, not the shift count. Signed-off-by: Scott Wood scottw...@freescale.com --- Unchanged in patchset v2 hw/ppce500_mpc8544ds.c |2 +- target-ppc/cpu.h |4 ++-- target-ppc/helper.c|5 +++-- 3 files changed, 6 insertions(+), 5 deletions(-) diff --git a/hw/ppce500_mpc8544ds.c b/hw/ppce500_mpc8544ds.c index 3626e26..1aed612 100644 --- a/hw/ppce500_mpc8544ds.c +++ b/hw/ppce500_mpc8544ds.c @@ -187,7 +187,7 @@ out: /* Create -kernel TLB entries for BookE, linearly spanning 256MB. */ static inline target_phys_addr_t booke206_page_size_to_tlb(uint64_t size) { -return (ffs(size 10) - 1) 1; +return ffs(size 10) - 1; } static void mmubooke_create_initial_mapping(CPUState *env, diff --git a/target-ppc/cpu.h b/target-ppc/cpu.h index f8bf2b1..9cf8327 100644 --- a/target-ppc/cpu.h +++ b/target-ppc/cpu.h @@ -654,8 +654,8 @@ enum { #define MAS0_ATSEL_TLB 0 #define MAS0_ATSEL_LRATMAS0_ATSEL -#define MAS1_TSIZE_SHIFT 8 -#define MAS1_TSIZE_MASK(0xf MAS1_TSIZE_SHIFT) +#define MAS1_TSIZE_SHIFT 7 +#define MAS1_TSIZE_MASK(0x1f MAS1_TSIZE_SHIFT) #define MAS1_TS_SHIFT 12 #define MAS1_TS(1 MAS1_TS_SHIFT) diff --git a/target-ppc/helper.c b/target-ppc/helper.c index 176128a..892c6e3 100644 --- a/target-ppc/helper.c +++ b/target-ppc/helper.c @@ -1293,7 +1293,7 @@ target_phys_addr_t booke206_tlb_to_page_size(CPUState *env, ppcmas_tlb_t *tlb) { uint32_t tlbncfg; int tlbn = booke206_tlbm_to_tlbn(env, tlb); -target_phys_addr_t tlbm_size; +int tlbm_size; tlbncfg = env-spr[SPR_BOOKE_TLB0CFG + tlbn]; @@ -1301,9 +1301,10 @@ target_phys_addr_t booke206_tlb_to_page_size(CPUState *env, ppcmas_tlb_t *tlb) tlbm_size = (tlb-mas1 MAS1_TSIZE_MASK) MAS1_TSIZE_SHIFT; } else { tlbm_size = (tlbncfg TLBnCFG_MINSIZE) TLBnCFG_MINSIZE_SHIFT; +tlbm_size = 1; } -return (1 (tlbm_size 1)) 10; +return 1024ULL tlbm_size; } /* TLB check function for MAS based SoftTLBs */ -- 1.7.4.1
[Qemu-devel] [PATCH v2 4/4] ppc: booke206: add info tlb support
Signed-off-by: Scott Wood scottw...@freescale.com --- v2: Remove redundant valid? comment hmp-commands.hx |2 +- monitor.c |5 ++- target-ppc/cpu.h|2 + target-ppc/helper.c | 88 +++ 4 files changed, 94 insertions(+), 3 deletions(-) diff --git a/hmp-commands.hx b/hmp-commands.hx index 6ad8806..014a4fb 100644 --- a/hmp-commands.hx +++ b/hmp-commands.hx @@ -1306,7 +1306,7 @@ show i8259 (PIC) state @item info pci show emulated PCI device info @item info tlb -show virtual to physical memory mappings (i386, SH4 and SPARC only) +show virtual to physical memory mappings (i386, SH4, SPARC, and PPC only) @item info mem show the active virtual memory mappings (i386 only) @item info jit diff --git a/monitor.c b/monitor.c index 67ceb46..7b9c2b1 100644 --- a/monitor.c +++ b/monitor.c @@ -2408,7 +2408,7 @@ static void tlb_info(Monitor *mon) #endif -#if defined(TARGET_SPARC) +#if defined(TARGET_SPARC) || defined(TARGET_PPC) static void tlb_info(Monitor *mon) { CPUState *env1 = mon_get_cpu(); @@ -2901,7 +2901,8 @@ static const mon_cmd_t info_cmds[] = { .user_print = do_pci_info_print, .mhandler.info_new = do_pci_info, }, -#if defined(TARGET_I386) || defined(TARGET_SH4) || defined(TARGET_SPARC) +#if defined(TARGET_I386) || defined(TARGET_SH4) || defined(TARGET_SPARC) || \ +defined(TARGET_PPC) { .name = tlb, .args_type = , diff --git a/target-ppc/cpu.h b/target-ppc/cpu.h index 9cf8327..0d04779 100644 --- a/target-ppc/cpu.h +++ b/target-ppc/cpu.h @@ -2032,4 +2032,6 @@ static inline void cpu_pc_from_tb(CPUState *env, TranslationBlock *tb) env-nip = tb-pc; } +void dump_mmu(FILE *f, fprintf_function cpu_fprintf, CPUState *env); + #endif /* !defined (__CPU_PPC_H__) */ diff --git a/target-ppc/helper.c b/target-ppc/helper.c index 892c6e3..a3b7283 100644 --- a/target-ppc/helper.c +++ b/target-ppc/helper.c @@ -1466,6 +1466,94 @@ found_tlb: return ret; } +static const char *book3e_tsize_to_str[32] = { +1K, 2K, 4K, 8K, 16K, 32K, 64K, 128K, 256K, 512K, +1M, 2M, 4M, 8M, 16M, 32M, 64M, 128M, 256M, 512M, +1G, 2G, 4G, 8G, 16G, 32G, 64G, 128G, 256G, 512G, +1T, 2T +}; + +static void mmubooke206_dump_one_tlb(FILE *f, fprintf_function cpu_fprintf, + CPUState *env, int tlbn, int offset, + int tlbsize) +{ +ppcmas_tlb_t *entry; +int i; + +cpu_fprintf(f, \nTLB%d:\n, tlbn); +cpu_fprintf(f, Effective Physical Size TID TS SRWX URWX WIMGE U0123\n); + +entry = env-tlb.tlbm[offset]; +for (i = 0; i tlbsize; i++, entry++) { +target_phys_addr_t ea, pa, size; +int tsize; + +if (!(entry-mas1 MAS1_VALID)) { +continue; +} + +tsize = (entry-mas1 MAS1_TSIZE_MASK) MAS1_TSIZE_SHIFT; +size = 1024ULL tsize; +ea = entry-mas2 ~(size - 1); +pa = entry-mas7_3 ~(size - 1); + +cpu_fprintf(f, 0x%016 PRIx64 0x%016 PRIx64 %4s %-5u %1u S%c%c%c U%c%c%c %c%c%c%c%c U%c%c%c%c\n, +(uint64_t)ea, (uint64_t)pa, +book3e_tsize_to_str[tsize], +(entry-mas1 MAS1_TID_MASK) MAS1_TID_SHIFT, +(entry-mas1 MAS1_TS) MAS1_TS_SHIFT, +entry-mas7_3 MAS3_SR ? 'R' : '-', +entry-mas7_3 MAS3_SW ? 'W' : '-', +entry-mas7_3 MAS3_SX ? 'X' : '-', +entry-mas7_3 MAS3_UR ? 'R' : '-', +entry-mas7_3 MAS3_UW ? 'W' : '-', +entry-mas7_3 MAS3_UX ? 'X' : '-', +entry-mas2 MAS2_W ? 'W' : '-', +entry-mas2 MAS2_I ? 'I' : '-', +entry-mas2 MAS2_M ? 'M' : '-', +entry-mas2 MAS2_G ? 'G' : '-', +entry-mas2 MAS2_E ? 'E' : '-', +entry-mas7_3 MAS3_U0 ? '0' : '-', +entry-mas7_3 MAS3_U1 ? '1' : '-', +entry-mas7_3 MAS3_U2 ? '2' : '-', +entry-mas7_3 MAS3_U3 ? '3' : '-'); +} +} + +static void mmubooke206_dump_mmu(FILE *f, fprintf_function cpu_fprintf, + CPUState *env) +{ +int offset = 0; +int i; + +if (kvm_enabled() !env-kvm_sw_tlb) { +cpu_fprintf(f, Cannot access KVM TLB\n); +return; +} + +for (i = 0; i BOOKE206_MAX_TLBN; i++) { +int size = booke206_tlb_size(env, i); + +if (size == 0) { +continue; +} + +mmubooke206_dump_one_tlb(f, cpu_fprintf, env, i, offset, size); +offset += size; +} +} + +void dump_mmu(FILE *f, fprintf_function cpu_fprintf, CPUState *env) +{ +switch (env-mmu_model) { +case POWERPC_MMU_BOOKE206: +mmubooke206_dump_mmu(f, cpu_fprintf, env); +break; +default: +
Re: [Qemu-devel] KVM call agenda for June 28
On Tue, Jul 05, 2011 at 04:39:06PM +0300, Dor Laor wrote: On 07/05/2011 03:58 PM, Marcelo Tosatti wrote: On Tue, Jul 05, 2011 at 01:40:08PM +0100, Stefan Hajnoczi wrote: On Tue, Jul 5, 2011 at 9:01 AM, Dor Laordl...@redhat.com wrote: I tried to re-arrange all of the requirements and use cases using this wiki page: http://wiki.qemu.org/Features/LiveBlockMigration It would be the best to agree upon the most interesting use cases (while we make sure we cover future ones) and agree to them. The next step is to set the interface for all the various verbs since the implementation seems to be converging. Live block copy was supposed to support snapshot merge. I think the current favored approach is to make the source image a backing file to the destination image and essentially do image streaming. Using this mechanism for snapshot merge is tricky. The COW file already uses the read-only snapshot base image. So now we cannot trivally copy the COW file contents back into the snapshot base image using live block copy. It never did. Live copy creates a new image were both snapshot and current are copied to. This is similar with image streaming. Not sure I realize what's bad to do in-place merge: Let's suppose we have this COW chain: base -- s1 -- s2 Now a live snapshot is created over s2, s2 becomes RO and s3 is RW: base -- s1 -- s2 -- s3 Now we've done with s2 (post backup) and like to merge s3 into s2. With your approach we use live copy of s3 into newSnap: base -- s1 -- s2 -- s3 base -- s1 -- newSnap When it is over s2 and s3 can be erased. The down side is the IOs for copying s2 data and the temporary storage. I guess temp storage is cheap but excessive IO are expensive. My approach was to collapse s3 into s2 and erase s3 eventually: before: base -- s1 -- s2 -- s3 after: base -- s1 -- s2 If we use live block copy using mirror driver it should be safe as long as we keep the ordering of new writes into s3 during the execution. Even a failure in the the middle won't cause harm since the management will keep using s3 until it gets success event. Well, it is more complicated than simply streaming into a new image. I'm not entirely sure it is necessary. The common case is: base - sn-1 - sn-2 - ... - sn-n When n reaches a limit, you do: base - merge-1 You're potentially copying similar amount of data when merging back into a single image (and worst, you can't easily merge multiple snapshots). If the amount of data thats not in 'base' is large, you create leave a new external file around: base - merge-1 - sn-1 - sn-2 ... - sn-n to base - merge-1 - merge-2 It seems like snapshot merge will require dedicated code that reads the allocated clusters from the COW file and writes them back into the base image. A very inefficient alternative would be to create a third image, the merge image file, which has the COW file as its backing file: snapshot (base) - cow - merge All data from snapshot and cow is copied into merge and then snapshot and cow can be deleted. But this approach is results in full data copying and uses potentially 3x space if cow is close to the size of snapshot. Remember there is a 'base' before snapshot, you don't copy the entire OS installation. Management can set a higher limit on the size of data that is merged, and create a new base once exceeded. This avoids copying excessive amounts of data. Any other ideas that reuse live block copy for snapshot merge? Stefan
Re: [Qemu-devel] Qemu performance
On 30.06.2011, at 15:24, Alexander Graf ag...@suse.de wrote: On 30.06.2011, at 04:11, Lê Đức Tài letai_d...@yahoo.com.vn wrote: Thank for your answer. Beside nbench, I'm also using Dhrystone to measure the guest cpu performance. The performance does not much diffetence too. Is the emulated guest performance not depend on guest processor clock? Please don't top-post. Qemu doesn't emulate cycle-accurately. Instead, it converts guest code to host code and executes it as fast as it can. So whatever you tell the guest on the cpu speed doesn't really matter. Except for the timebase of course :). Mind if I ask what exactly you're trying to do with ppc emulation? I'm interested in use cases people have. Alex Thank you, Exactly I want to emulate my ppc custom board (ppc440) with many features supporting as Ethernet, HDD, VGA, .. for my test environment (I have a software that running on ppc440). And I wan to get the best performance of Qemu. Tai