[Qemu-devel] Hello Would You Like To Earn
Hello qemu-devel Would you like to earn an extra $200 everyday?, for just 45 minutes work? You could quit your job and make double the money at home working for yourself. visit->http:tinyurl.com/3brnlpx Regards, Sharon Burns Survey Human Resources Dept.
Re: [Qemu-devel] QEMU for ppc440 on i386 host
On 31.05.2011, at 23:52, Alexander Graf wrote: >On 31.05.2011, at 18:05, Lê Đức Tài wrote: > >> Hi! >> My name is Tai. >> Sorry for bother you! >> >> I have a question about QEMU for powerpc. >> Can QEMU emulate the ppc440 on a i386 host? >> I mean it is full-system emulation. >> Because when I'm trying to run linux ppc440 with qemu on my i386 PC >> I alway get the error like that: >> >> $ qemu-system-ppc -M bamboo -kernel vmlinux >> qemu: fatal: Trying to execute code outside RAM or ROM at 0xc000 >> >> NIP c000 LR CTR XER >> MSR HID0 0300 HF idx 0 >> Segmentation fault >> >> $ qemu-system-ppc -M bamboo -kernel arch/powerpc/boot/uImage >> Trying to read privileged spr 947 3b3 at 1014 >> Trying to read invalid spr 62 03e at 0778 >> >> I using QEMU that configured and built with device tree support (enable >>libfdt). >> QEMU version 0.14.1 >> The kernel image is built for bamboo using powerpc-440 toolchain. >> kernel-version 2.6.38.2 > >PPC440 emulation support has only been added to Qemu very recently (0.14). So >far, the only board that is somewhat known to work is the virtex5 ml507 one >with >a 440x5 xilinx cpu. Please see http://wiki.qemu.org/ChangeLog/0.14#PPC for >details. > >The bamboo board was added to enable KVM support for 440, it hasn't been used >with the emulation target yet. > >What exactly are you trying to emulate? > > >Alex Thank for your answer. I'm trying to emulate the ppc440 on a i386 host. My final target: Linux for PPC440 can run on Qemu and drop a shell prompt. When I try to run this command: $ qemu-system-ppc -M ? Supported machines are: virtex-ml507 Xilinx Virtex ML507 reference design mpc8544ds mpc8544ds bamboo bamboo (alias of bamboo-0.13) bamboo-0.13 bamboo bamboo-0.12 bamboo ref405ep ref405ep taihu taihu mac99 Mac99 based PowerMAC g3beigeHeathrow based PowerMAC (default) prep PowerPC PREP platform I find two boards that have a PPC440 cpu: virtex-ml507 and bamboo. I have checked the bamboo board fist, then I get the result as above. Hower, the ml507 board seems not working too. I have built kernel image for Virtex ML507 using powerpc-440 toolchain. kernel-version: linux-2.6.39 config: 44x/virtex5_defconfig When I'm trying to run: $ qemu-system-ppc -M virtex-ml507 -kernel arch/powerpc/boot/simpleImage.virtex440-ml507.elf I get the following output: Unable to get size of device tree file 'ppc.dtb' Warning: vlan 0 with no nics Qemu just display a monitor console, it seems not to be loading the kernel. Could you help me some ideas? Could you help me the guide to emulate virtex-ml507 on i368 host? Thank you very much. Tai
[Qemu-devel] Hello Would You Like To Earn
Hello qemu-devel Would you like to earn an extra $200 everyday?, for just 45 minutes work? You could quit your job and make double the money at home working for yourself. visit->http:tinyurl.com/3brnlpx Regards, Sharon Burns Survey Human Resources Dept.
[Qemu-devel] Hello Would You Like To Earn
Hello qemu-devel Would you like to earn an extra $200 everyday?, for just 45 minutes work? You could quit your job and make double the money at home working for yourself. visit->http:tinyurl.com/3brnlpx Regards, Sharon Burns Survey Human Resources Dept.
[Qemu-devel] Reminder about your invitation from Paulo Cezar
LinkedIn This invitation is awaiting your response: From Paulo Cezar -- (c) 2011, LinkedIn Corporation
Re: [Qemu-devel] QEMU for ppc440 on i386 host
On Wed, Jun 01, 2011 at 03:03:18PM +0800, Lê ?c Tài wrote: >On 31.05.2011, at 23:52, Alexander Graf wrote: >>On 31.05.2011, at 18:05, Lê Äức Tà i wrote: >> >>> Hi! >>> My name is Tai. >>> Sorry for bother you! >>> >>> I have a question about QEMU for powerpc. >>> Can QEMU emulate the ppc440 on a i386 host? >>> I mean it is full-system emulation. >>> Because when I'm trying to run linux ppc440 with qemu on my i386 PC >>> I alway get the error like that: >>> >>> $ qemu-system-ppc -M bamboo -kernel vmlinux >>> qemu: fatal: Trying to execute code outside RAM or ROM at 0xc000 >>> >>> NIP c000 LR CTR XER >>> MSR HID0 0300 HF idx 0 >>> Segmentation fault >>> >>> $ qemu-system-ppc -M bamboo -kernel arch/powerpc/boot/uImage >>> Trying to read privileged spr 947 3b3 at 1014 >>> Trying to read invalid spr 62 03e at 0778 >>> >>> I using QEMU that configured and built with device tree support >(enable libfdt). >>> QEMU version 0.14.1 >>> The kernel image is built for bamboo using powerpc-440 toolchain. >>> kernel-version 2.6.38.2 >> >>PPC440 emulation support has only been added to Qemu very recently >(0.14). So far, the only board that is somewhat known to work is the >virtex5 ml507 one with a 440x5 xilinx cpu. Please see >[1]http://wiki.qemu.org/ChangeLog/0.14#PPC for details. >> >>The bamboo board was added to enable KVM support for 440, it hasn't >been used with the emulation target yet. >> >>What exactly are you trying to emulate? >> >> >>Alex >Thank for your answer. >I'm trying to emulate the ppc440 on a i386 host. >My final target: Linux for PPC440 can run on Qemu and drop a shell >prompt. >When I try to run this command: >$ qemu-system-ppc -M ? >Supported machines are: >virtex-ml507 Xilinx Virtex ML507 reference design >mpc8544ds mpc8544ds >bamboo bamboo (alias of bamboo-0.13) >bamboo-0.13 bamboo >bamboo-0.12 bamboo >ref405ep ref405ep >taihu taihu >mac99 Mac99 based PowerMAC >g3beigeHeathrow based PowerMAC (default) >prep PowerPC PREP platform >I find two boards that have a PPC440 cpu: virtex-ml507 and bamboo. >I have checked the bamboo board fist, then I get the result as above. >Hower, the ml507 board seems not working too. >I have built kernel image for Virtex ML507 using powerpc-440 toolchain. >kernel-version: linux-2.6.39 >config: 44x/virtex5_defconfig >When I'm trying to run: >$ qemu-system-ppc -M virtex-ml507 -kernel >arch/powerpc/boot/simpleImage.virtex440-ml507.elf >I get the following output: >Unable to get size of device tree file 'ppc.dtb' >Warning: vlan 0 with no nics >Qemu just display a monitor console, it seems not to be loading the >kernel. >Could you help me some ideas? >Could you help me the guide to emulate virtex-ml507 on i368 host? Hi, I've just uploaded a test image to the wiki's download pages. See http://wiki.qemu.org/Download. You'll need a recent qemu, built with libfdt support. I threw in the linux kernelconfig used to build the image. I used a rather old version (2.6.34) of the kernel provided by Xilinx at: git://git.xilinx.com/linux-2.6-xlnx.git commit: 91e2c43452914a789a4bebea7c199695bbf888f2 My guess is that you should be able to build a kernel directly from upstream, but I haven't tried. One thing to note is that qemu still lacks support for the ll-temac (ethernet nic) and the kernel hangs when probing for it. The workaround is to remove it from the device tree file (ppc.dtb). Already done in the archive with my test image, but good to know if you start rolling your own stuff. Regarding the ll-temac, we've got it running and plan to submit, I just need to get some time to clean it up etc.. sorry. Good luck
Re: [Qemu-devel] virtio scsi host draft specification, v2
On Fri, May 20, 2011 at 10:21:03AM +0200, Paolo Bonzini wrote: > Hi all, > > here is the second version of the spec. In the end I took the > advice of merging all requestq's into one. The reason for this is > that I took a look at the vSCSI device and liked its approach of > using SAM 8-byte LUNs directly. While it _is_ complex (and not yet > done right by QEMU---will send a patch for that), the scheme is > actually quite natural to implement and use, and supporting generic > bus/target/LUN topologies is good to have for passthrough, as well. > > I also added a few more features from SAM to avoid redefining the > structs in the future. > > Of course it may be that I'm completely wrong. :) Please comment on > the spec! > > Paolo > Virtio SCSI Host Device Spec > > > The virtio SCSI host device groups together one or more simple virtual > devices (ie. disk), and allows communicating to these devices using the > SCSI protocol. An instance of the device represents a SCSI host with > possibly many buses, targets and LUN attached. > > The virtio SCSI device services two kinds of requests: > > - command requests for a logical unit; > > - task management functions related to a logical unit, target or > command. > > The device is also able to send out notifications about added > and removed logical units. > > v4: > First public version > > v5: > Merged all virtqueues into one, removed separate TARGET fields Document still seems to refer to multiple VQs - maybe I misunderstand? > Configuration > - > > Subsystem Device ID > TBD > > Virtqueues > 0:control transmitq > 1:control receiveq > 2:requestq > > Feature bits > VIRTIO_SCSI_F_INOUT - Whether a single request can include both > read-only and write-only data buffers. > > Device configuration layout > struct virtio_scsi_config { > } > > (Still empty) > > Device initialization > - > > The initialization routine should first of all discover the device's > control virtqueues. > > The driver should then place at least a buffer in the control receiveq. Size of the buffer? > Buffers returned by the device on the control receiveq may be referred > to as "events" in the rest of the document. > > The driver can immediately issue requests (for example, INQUIRY or > REPORT LUNS) or task management functions (for example, I_T RESET). > > Device operation: request queue > --- > > The driver queues requests to the virtqueue, and they are used by the device > (not necessarily in order). > > Requests have the following format: > > struct virtio_scsi_req_cmd { > u8 lun[8]; > u64 id; > u8 task_attr; > u8 prio; > u8 crn; > u32 num_dataout, num_datain; > char cdb[]; > char data[][num_dataout+num_datain]; > u8 sense[]; > u32 sense_len; > u32 residual; > u16 status_qualifier; > u8 status; > u8 response; > }; > > /* command-specific response values */ > #define VIRTIO_SCSI_S_OK 0 > #define VIRTIO_SCSI_S_UNDERRUN1 > #define VIRTIO_SCSI_S_ABORTED 2 > #define VIRTIO_SCSI_S_FAILURE 3 > > The lun field addresses a bus, target and logical unit in the SCSI > host. The id field is the command identifier as defined in SAM. > > The task_attr, prio field should always be zero, as task > attributes other than SIMPLE, as well as command priority, are > explicitly not supported by this version of the device. > CRN is also as defined in SAM; while it is generally expected to > be 0, clients can provide it. The maximum CRN value defined by > the protocol is 255, since CRN is stored in an 8-bit integer. > > All of these fields are always read-only. > > The cdb, data and sense fields must reside in separate buffers. > The cdb field is always read-only. The data buffers may be either > read-only or write-only, depending on the request, with the read-only > buffers coming first. The sense buffer is always write-only. > > The request shall have num_dataout read-only data buffers and > num_datain write-only data buffers. One of these two values must be > zero if the VIRTIO_SCSI_F_INOUT has not been negotiated. Why do num_datain/num_dataout need to be there? We can just look at the number of io/out bufs in virtio descriptors, no? Also, from experience, it's better not to have any layout assumptions - let the guest stick everything in a single in + single out buffer if it desires. > Remaining fields are filled in by the device. The sense_len field > indicates the number of bytes actually written to the sense buffer, > while the residual field indicates the residual size, calculated as > data_length - number_of_transferred_bytes. Again virtio gives you total number of written
Re: [Qemu-devel] VMDK development plan for Summer of Code 2011
On 01.06.2011, at 06:29, Stefan Hajnoczi wrote: > On Sun, May 29, 2011 at 2:19 PM, Fam Zheng wrote: >> As a project of Google Summer of Code 2011, I'm now working on >> improving VMDK image support. There are many subformats of VMDK >> virtual disk, some of which have separate descriptor file and others >> don't, some allocate space at once and some others grow dynamically, >> some have optional data compression. The current support of VMDK >> format is very limited, i.e. qemu now supports single file images, but >> couldn't recognize the widely used multi-file types. We have planned >> to add such support to VMDK block driver and enable more image types, >> and the working timeline is set in weeks (#1 to #7) as: >> >> [#1] Monolithic flat layout support >> [#2] Implement compression and Stream-Optimized Compressed Sparse >> Extents support. >> [#3] Improve ESX Server Sparse Extents support. >> [#4] Debug and test. Collect virtual disks with various versions and >> options, test qemu-img with them. By now some patches may be ready to >> deliver. >> [#5, 6] Add multi-file support (2GB extent formats) >> [#7] Clean up and midterm evaluation. > > Thanks to Fam's work, we'll hopefully support the latest real-world > VMDK files in qemu-img convert within the next few months. > > If anyone has had particular VMDK "problem files" which qemu-img > cannot handle, please reply, they would make interesting test cases. There is one very useful use-case of VMDK files that we currently don't support: remapping. A vmdk file can specify that it really is backed by a raw block device, but only for certain chunks, while other chunks of it can be mapped read-only or zero. That is very useful when passing in a host disk to the guest and you want to be sure that you don't break other partitions than the one you're playing with. It can also shadow map those chunks. For example on the case above, the MBR is COW (IIRC) for the image, so you can install a bootloader in there. Alex
[Qemu-devel] [PATCH] qcow2: Fix memory leaks in error cases
This fixes memory leaks that may be caused by I/O errors during L1 table growth (can happen during save_vm) and in qemu-img check. Signed-off-by: Kevin Wolf --- block/qcow2-cluster.c |2 +- block/qcow2-refcount.c |9 ++--- 2 files changed, 7 insertions(+), 4 deletions(-) diff --git a/block/qcow2-cluster.c b/block/qcow2-cluster.c index c56651c..67230fc 100644 --- a/block/qcow2-cluster.c +++ b/block/qcow2-cluster.c @@ -70,7 +70,7 @@ int qcow2_grow_l1_table(BlockDriverState *bs, int min_size, bool exact_size) ret = qcow2_cache_flush(bs, s->refcount_block_cache); if (ret < 0) { -return ret; +goto fail; } BLKDBG_EVENT(bs->file, BLKDBG_L1_GROW_WRITE_TABLE); diff --git a/block/qcow2-refcount.c b/block/qcow2-refcount.c index d62dc1c..ac95b88 100644 --- a/block/qcow2-refcount.c +++ b/block/qcow2-refcount.c @@ -1086,7 +1086,7 @@ int qcow2_check_refcounts(BlockDriverState *bs, BdrvCheckResult *res) ret = check_refcounts_l1(bs, res, refcount_table, nb_clusters, s->l1_table_offset, s->l1_size, 1); if (ret < 0) { -return ret; +goto fail; } /* snapshots */ @@ -1095,7 +1095,7 @@ int qcow2_check_refcounts(BlockDriverState *bs, BdrvCheckResult *res) ret = check_refcounts_l1(bs, res, refcount_table, nb_clusters, sn->l1_table_offset, sn->l1_size, 0); if (ret < 0) { -return ret; +goto fail; } } inc_refcounts(bs, res, refcount_table, nb_clusters, @@ -1159,8 +1159,11 @@ int qcow2_check_refcounts(BlockDriverState *bs, BdrvCheckResult *res) } } +ret = 0; + +fail: qemu_free(refcount_table); -return 0; +return ret; } -- 1.7.5.2
Re: [Qemu-devel] VMDK development plan for Summer of Code 2011
Am 01.06.2011 10:49, schrieb Alexander Graf: > > On 01.06.2011, at 06:29, Stefan Hajnoczi wrote: > >> On Sun, May 29, 2011 at 2:19 PM, Fam Zheng wrote: >>> As a project of Google Summer of Code 2011, I'm now working on >>> improving VMDK image support. There are many subformats of VMDK >>> virtual disk, some of which have separate descriptor file and others >>> don't, some allocate space at once and some others grow dynamically, >>> some have optional data compression. The current support of VMDK >>> format is very limited, i.e. qemu now supports single file images, but >>> couldn't recognize the widely used multi-file types. We have planned >>> to add such support to VMDK block driver and enable more image types, >>> and the working timeline is set in weeks (#1 to #7) as: >>> >>> [#1] Monolithic flat layout support >>> [#2] Implement compression and Stream-Optimized Compressed Sparse >>> Extents support. >>> [#3] Improve ESX Server Sparse Extents support. >>> [#4] Debug and test. Collect virtual disks with various versions and >>> options, test qemu-img with them. By now some patches may be ready to >>> deliver. >>> [#5, 6] Add multi-file support (2GB extent formats) >>> [#7] Clean up and midterm evaluation. >> >> Thanks to Fam's work, we'll hopefully support the latest real-world >> VMDK files in qemu-img convert within the next few months. >> >> If anyone has had particular VMDK "problem files" which qemu-img >> cannot handle, please reply, they would make interesting test cases. > > There is one very useful use-case of VMDK files that we currently don't > support: remapping. > > A vmdk file can specify that it really is backed by a raw block device, but > only for certain chunks, while other chunks of it can be mapped read-only or > zero. That is very useful when passing in a host disk to the guest and you > want to be sure that you don't break other partitions than the one you're > playing with. > > It can also shadow map those chunks. For example on the case above, the MBR > is COW (IIRC) for the image, so you can install a bootloader in there. Hm, wondering if that's something to consider for qcow2v3, too... Do you think it's still useful when doing this on a cluster granularity? It would only work for well-aligned partitions then, but I think that shouldn't be a problem for current OSes. Basically, additionally to the three cluster types "read from this image", "COW from backing file" and "zero cluster" we could introduce a fourth one "read/write to backing file". Kevin
Re: [Qemu-devel] VMDK development plan for Summer of Code 2011
On 01.06.2011, at 11:11, Kevin Wolf wrote: > Am 01.06.2011 10:49, schrieb Alexander Graf: >> >> On 01.06.2011, at 06:29, Stefan Hajnoczi wrote: >> >>> On Sun, May 29, 2011 at 2:19 PM, Fam Zheng wrote: As a project of Google Summer of Code 2011, I'm now working on improving VMDK image support. There are many subformats of VMDK virtual disk, some of which have separate descriptor file and others don't, some allocate space at once and some others grow dynamically, some have optional data compression. The current support of VMDK format is very limited, i.e. qemu now supports single file images, but couldn't recognize the widely used multi-file types. We have planned to add such support to VMDK block driver and enable more image types, and the working timeline is set in weeks (#1 to #7) as: [#1] Monolithic flat layout support [#2] Implement compression and Stream-Optimized Compressed Sparse Extents support. [#3] Improve ESX Server Sparse Extents support. [#4] Debug and test. Collect virtual disks with various versions and options, test qemu-img with them. By now some patches may be ready to deliver. [#5, 6] Add multi-file support (2GB extent formats) [#7] Clean up and midterm evaluation. >>> >>> Thanks to Fam's work, we'll hopefully support the latest real-world >>> VMDK files in qemu-img convert within the next few months. >>> >>> If anyone has had particular VMDK "problem files" which qemu-img >>> cannot handle, please reply, they would make interesting test cases. >> >> There is one very useful use-case of VMDK files that we currently don't >> support: remapping. >> >> A vmdk file can specify that it really is backed by a raw block device, but >> only for certain chunks, while other chunks of it can be mapped read-only or >> zero. That is very useful when passing in a host disk to the guest and you >> want to be sure that you don't break other partitions than the one you're >> playing with. >> >> It can also shadow map those chunks. For example on the case above, the MBR >> is COW (IIRC) for the image, so you can install a bootloader in there. > > Hm, wondering if that's something to consider for qcow2v3, too... Do you > think it's still useful when doing this on a cluster granularity? It > would only work for well-aligned partitions then, but I think that > shouldn't be a problem for current OSes. Well, we could always just hack around for bits where it overlaps. When passing in a differently aligned partition for example, we could just declare the odd sector as COW sector and copy the contents over :). Though that might not be what the user really wants. Hrm. > Basically, additionally to the three cluster types "read from this > image", "COW from backing file" and "zero cluster" we could introduce a > fourth one "read/write to backing file". Yup, sounds very much straight forward! Then all we need is some tool to create such a qcow file :) Alex
[Qemu-devel] [PATCH v2 2/2] Add support for Zipit Z2 machine
Zipit Z2 is small PXA270 based handheld. Signed-off-by: Vasily Khoruzhick --- v2: codestyle fixes, added VMStateDescription for LCD device and AER915, traces clean up. Makefile.target |1 + hw/z2.c | 352 +++ 2 files changed, 353 insertions(+), 0 deletions(-) create mode 100644 hw/z2.c diff --git a/Makefile.target b/Makefile.target index 602d50d..5750499 100644 --- a/Makefile.target +++ b/Makefile.target @@ -358,6 +358,7 @@ obj-arm-y += omap2.o omap_dss.o soc_dma.o omap_gptimer.o omap_synctimer.o \ obj-arm-y += omap_sx1.o palm.o tsc210x.o obj-arm-y += nseries.o blizzard.o onenand.o vga.o cbus.o tusb6010.o usb-musb.o obj-arm-y += mst_fpga.o mainstone.o +obj-arm-y += z2.o obj-arm-y += musicpal.o bitbang_i2c.o marvell_88w8618_audio.o obj-arm-y += framebuffer.o obj-arm-y += syborg.o syborg_fb.o syborg_interrupt.o syborg_keyboard.o diff --git a/hw/z2.c b/hw/z2.c new file mode 100644 index 000..3e3591a --- /dev/null +++ b/hw/z2.c @@ -0,0 +1,352 @@ +/* + * PXA270-based Zipit Z2 device + * + * Copyright (c) 2011 by Vasily Khoruzhick + * + * Code is based on mainstone platform. + * + * This code is licensed under the GNU GPL v2. + */ + +#include "hw.h" +#include "pxa.h" +#include "arm-misc.h" +#include "devices.h" +#include "i2c.h" +#include "ssi.h" +#include "boards.h" +#include "sysemu.h" +#include "flash.h" +#include "blockdev.h" +#include "console.h" +#include "audio/audio.h" + +#if 0 +#define DPRINTF(fmt, ...) \ +printf(fmt, ## __VA_ARGS__) +#else +#define DPRINTF(fmt, ...) +#endif + +static struct keymap map[0x100] = { +[0 ... 0xff] = { -1, -1 }, +[0x3b] = {0, 0}, /* Option = F1 */ +[0xc8] = {0, 1}, /* Up */ +[0xd0] = {0, 2}, /* Down */ +[0xcb] = {0, 3}, /* Left */ +[0xcd] = {0, 4}, /* Right */ +[0xcf] = {0, 5}, /* End */ +[0x0d] = {0, 6}, /* KPPLUS */ +[0xc7] = {1, 0}, /* Home */ +[0x10] = {1, 1}, /* Q */ +[0x17] = {1, 2}, /* I */ +[0x22] = {1, 3}, /* G */ +[0x2d] = {1, 4}, /* X */ +[0x1c] = {1, 5}, /* Enter */ +[0x0c] = {1, 6}, /* KPMINUS */ +[0xc9] = {2, 0}, /* PageUp */ +[0x11] = {2, 1}, /* W */ +[0x18] = {2, 2}, /* O */ +[0x23] = {2, 3}, /* H */ +[0x2e] = {2, 4}, /* C */ +[0x38] = {2, 5}, /* LeftAlt */ +[0xd1] = {3, 0}, /* PageDown */ +[0x12] = {3, 1}, /* E */ +[0x19] = {3, 2}, /* P */ +[0x24] = {3, 3}, /* J */ +[0x2f] = {3, 4}, /* V */ +[0x2a] = {3, 5}, /* LeftShift */ +[0x01] = {4, 0}, /* Esc */ +[0x13] = {4, 1}, /* R */ +[0x1e] = {4, 2}, /* A */ +[0x25] = {4, 3}, /* K */ +[0x30] = {4, 4}, /* B */ +[0x1d] = {4, 5}, /* LeftCtrl */ +[0x0f] = {5, 0}, /* Tab */ +[0x14] = {5, 1}, /* T */ +[0x1f] = {5, 2}, /* S */ +[0x26] = {5, 3}, /* L */ +[0x31] = {5, 4}, /* N */ +[0x39] = {5, 5}, /* Space */ +[0x3c] = {6, 0}, /* Stop = F2 */ +[0x15] = {6, 1}, /* Y */ +[0x20] = {6, 2}, /* D */ +[0x0e] = {6, 3}, /* Backspace */ +[0x32] = {6, 4}, /* M */ +[0x33] = {6, 5}, /* Comma */ +[0x3d] = {7, 0}, /* Play = F3 */ +[0x16] = {7, 1}, /* U */ +[0x21] = {7, 2}, /* F */ +[0x2c] = {7, 3}, /* Z */ +[0x27] = {7, 4}, /* Semicolon */ +[0x34] = {7, 5}, /* Dot */ +}; + +#define Z2_RAM_SIZE 0x0200 +#define Z2_FLASH_BASE 0x +#define Z2_FLASH_SIZE 0x0080 + +static struct arm_boot_info z2_binfo = { +.loader_start = PXA2XX_SDRAM_BASE, +.ram_size = Z2_RAM_SIZE, +}; + +#define Z2_GPIO_SD_DETECT 96 +#define Z2_GPIO_AC_IN 0 +#define Z2_GPIO_KEY_ON 1 +#define Z2_GPIO_LCD_CS 88 + +typedef struct { +SSISlave ssidev; +int32_t selected; +int32_t enabled; +uint8_t buf[3]; +uint32_t cur_reg; +int pos; +} ZipitLCD; + +static uint32_t zipit_lcd_transfer(SSISlave *dev, uint32_t value) +{ +ZipitLCD *z = FROM_SSI_SLAVE(ZipitLCD, dev); +uint16_t val; +if (z->selected) { +z->buf[z->pos] = value & 0xff; +z->pos++; +} +if (z->pos == 3) { +switch (z->buf[0]) { +case 0x74: +DPRINTF("%s: reg: 0x%.2x\n", __func__, z->buf[2]); +z->cur_reg = z->buf[2]; +break; +case 0x76: +val = z->buf[1] << 8 | z->buf[2]; +DPRINTF("%s: value: 0x%.4x\n", __func__, val); +if (z->cur_reg == 0x22 && val == 0x) { +z->enabled = 1; +printf("%s: LCD enabled\n", __func__); +} else if (z->cur_reg == 0x10 && val == 0x) { +z->enabled = 0; +printf("%s: LCD disabled\n", __func__); +} +break; +default: +fprintf(stderr, "%s: unknown command!\n", __func__); +break; +} +z->pos = 0; +} +return 0; +} + +static void z2_lcd_cs(void *opaque, int line, int level) +{ +ZipitLCD *z2_lcd = opaque; +z2_lcd->selected = !level; +} + +stat
[Qemu-devel] [PATCH v2 1/2] pxa2xx_lcd: add proper rotation support
Until now, pxa2xx_lcd only supported 90deg rotation, but some machines (for example Zipit Z2) needs 270deg rotation. Signed-off-by: Vasily Khoruzhick --- v2: codestyle fixes hw/framebuffer.c |2 + hw/pxa2xx_lcd.c | 86 +++-- input.c | 34 +++- qemu-options.hx |9 + vl.c | 11 ++- 5 files changed, 122 insertions(+), 20 deletions(-) diff --git a/hw/framebuffer.c b/hw/framebuffer.c index 24cdf25..5e9ab5e 100644 --- a/hw/framebuffer.c +++ b/hw/framebuffer.c @@ -78,6 +78,8 @@ void framebuffer_update_display( dest = ds_get_data(ds); if (dest_col_pitch < 0) dest -= dest_col_pitch * (cols - 1); +if (dest_row_pitch < 0) +dest -= dest_row_pitch * (rows - 1); first = -1; addr = pd; diff --git a/hw/pxa2xx_lcd.c b/hw/pxa2xx_lcd.c index e524802..a560bb0 100644 --- a/hw/pxa2xx_lcd.c +++ b/hw/pxa2xx_lcd.c @@ -665,7 +665,7 @@ static void pxa2xx_palette_parse(PXA2xxLCDState *s, int ch, int bpp) } } -static void pxa2xx_lcdc_dma0_redraw_horiz(PXA2xxLCDState *s, +static void pxa2xx_lcdc_dma0_redraw_rot0(PXA2xxLCDState *s, target_phys_addr_t addr, int *miny, int *maxy) { int src_width, dest_width; @@ -692,7 +692,7 @@ static void pxa2xx_lcdc_dma0_redraw_horiz(PXA2xxLCDState *s, fn, s->dma_ch[0].palette, miny, maxy); } -static void pxa2xx_lcdc_dma0_redraw_vert(PXA2xxLCDState *s, +static void pxa2xx_lcdc_dma0_redraw_rot90(PXA2xxLCDState *s, target_phys_addr_t addr, int *miny, int *maxy) { int src_width, dest_width; @@ -720,6 +720,61 @@ static void pxa2xx_lcdc_dma0_redraw_vert(PXA2xxLCDState *s, miny, maxy); } +static void pxa2xx_lcdc_dma0_redraw_rot180(PXA2xxLCDState *s, +target_phys_addr_t addr, int *miny, int *maxy) +{ +int src_width, dest_width; +drawfn fn = NULL; +if (s->dest_width) +fn = s->line_fn[s->transp][s->bpp]; +if (!fn) +return; + +src_width = (s->xres + 3) & ~3; /* Pad to a 4 pixels multiple */ +if (s->bpp == pxa_lcdc_19pbpp || s->bpp == pxa_lcdc_18pbpp) +src_width *= 3; +else if (s->bpp > pxa_lcdc_16bpp) +src_width *= 4; +else if (s->bpp > pxa_lcdc_8bpp) +src_width *= 2; + +dest_width = s->xres * s->dest_width; +*miny = 0; +framebuffer_update_display(s->ds, + addr, s->xres, s->yres, + src_width, -dest_width, -s->dest_width, + s->invalidated, + fn, s->dma_ch[0].palette, miny, maxy); +} + +static void pxa2xx_lcdc_dma0_redraw_rot270(PXA2xxLCDState *s, + target_phys_addr_t addr, int *miny, int *maxy) +{ +int src_width, dest_width; +drawfn fn = NULL; +if (s->dest_width) +fn = s->line_fn[s->transp][s->bpp]; +if (!fn) +return; + +src_width = (s->xres + 3) & ~3; /* Pad to a 4 pixels multiple */ +if (s->bpp == pxa_lcdc_19pbpp || s->bpp == pxa_lcdc_18pbpp) +src_width *= 3; +else if (s->bpp > pxa_lcdc_16bpp) +src_width *= 4; +else if (s->bpp > pxa_lcdc_8bpp) +src_width *= 2; + +dest_width = s->yres * s->dest_width; +*miny = 0; +framebuffer_update_display(s->ds, + addr, s->xres, s->yres, + src_width, -s->dest_width, dest_width, + s->invalidated, + fn, s->dma_ch[0].palette, + miny, maxy); +} + static void pxa2xx_lcdc_resize(PXA2xxLCDState *s) { int width, height; @@ -730,10 +785,11 @@ static void pxa2xx_lcdc_resize(PXA2xxLCDState *s) height = LCCR2_LPP(s->control[2]) + 1; if (width != s->xres || height != s->yres) { -if (s->orientation) +if (s->orientation == 90 || s->orientation == 270) { qemu_console_resize(s->ds, height, width); -else +} else { qemu_console_resize(s->ds, width, height); +} s->invalidated = 1; s->xres = width; s->yres = height; @@ -797,10 +853,11 @@ static void pxa2xx_update_display(void *opaque) } if (miny >= 0) { -if (s->orientation) +if (s->orientation == 90 || s->orientation == 270) { dpy_update(s->ds, miny, 0, maxy - miny, s->xres); -else +} else { dpy_update(s->ds, 0, miny, s->xres, maxy - miny); +} } pxa2xx_lcdc_int_update(s); @@ -822,10 +879,19 @@ static void pxa2xx_lcdc_orientation(void *opaque, int angle) { PXA2xxLCDState *s = (PXA2xxLCDState *) opaque; -if (angle) { -s->dma_ch[0].redraw = pxa2xx_lcdc_dma0_redraw_vert; -} else { -s->dma_ch[0].redraw = pxa2xx_lcdc_dma0_redraw_horiz; +switch (angle) { +case 0: +s-
[Qemu-devel] [PATCH] linux-user: Fix the computation of the requested heap size
Hi Peter & Martin, On 2011-04-21 14:04:40, Peter Maydell wrote: > > I've had a report from Martin Mohring that this patch breaks some > programs which previously worked in linux-user mode (one wonders if > they were overwriting some chunk of memory that they happened not > to be using for anything important...) Peter, actually your patch exposes two old bugs more explicitly (since the error code is now correctly reported). To complete your patchset, just consider this contribution as "PATCH 4/3" ;) Martin, I suppose you have encountered a problem with the memory allocator used in Bash and Emacs. I reduced the problem to the test-case embedded in the commit message below. Also, I wonder how this whole new implementation of the target brk could help ScratchBox2? [1] Regards, Cédric [1] http://lists.gnu.org/archive/html/qemu-devel/2011-04/msg01817.html PS: feel free to ask me for a separated patch if you don't [like to] use "git am --scissors" 8<8<8<8<8<8<8<8<8<8<8<8< There were two remaining bugs in the previous implementation of do_brk(): 1. the value of "new_alloc_size" was one page too large when the requested brk was aligned on a host page boundary. 2. no new pages should be (re-)allocated when the requested brk is in the range of the pages that were already allocated previsouly (for the same purpose). Technically these pages are never unmapped in the current implementation. The problem/fix can be reproduced/validated with the following test case: #include/* syscall(2), */ #include /* SYS_brk, */ #include /* puts(3), */ #include/* exit(3), EXIT_*, */ int main() { int current_brk = 0; int new_brk; int failure = 0; void test(int increment) { static int test_number = 0; test_number++; new_brk = syscall(SYS_brk, current_brk + increment); if (new_brk == current_brk) { printf("test %d fails\n", test_number); failure++; } current_brk = new_brk; } /* Initialization. */ test(0); /* Does QEMU overlap host pages? */ test(HOST_PAGE_SIZE); test(HOST_PAGE_SIZE); /* Does QEMU allocate the same host page twice? */ test(-HOST_PAGE_SIZE); test(HOST_PAGE_SIZE); if (!failure) { printf("success\n"); exit(EXIT_SUCCESS); } else { exit(EXIT_FAILURE); } } Signed-off-by: Cédric VINCENT Reviewed-by: Christophe Guillon Cc: Riku Voipio --- linux-user/syscall.c | 11 ++- 1 files changed, 6 insertions(+), 5 deletions(-) diff --git a/linux-user/syscall.c b/linux-user/syscall.c index b975730..be27f53 100644 --- a/linux-user/syscall.c +++ b/linux-user/syscall.c @@ -709,16 +709,17 @@ char *target_strerror(int err) static abi_ulong target_brk; static abi_ulong target_original_brk; +static abi_ulong brk_page; void target_set_brk(abi_ulong new_brk) { target_original_brk = target_brk = HOST_PAGE_ALIGN(new_brk); +brk_page = HOST_PAGE_ALIGN(target_brk); } /* do_brk() must return target values and target errnos. */ abi_long do_brk(abi_ulong new_brk) { -abi_ulong brk_page; abi_long mapped_addr; intnew_alloc_size; @@ -727,9 +728,8 @@ abi_long do_brk(abi_ulong new_brk) if (new_brk < target_original_brk) return target_brk; -brk_page = HOST_PAGE_ALIGN(target_brk); - -/* If the new brk is less than this, set it and we're done... */ +/* If the new brk is less than the highest page reserved to the + * target heap allocation, set it and we're done... */ if (new_brk < brk_page) { target_brk = new_brk; return target_brk; @@ -741,13 +741,14 @@ abi_long do_brk(abi_ulong new_brk) * itself); instead we treat "mapped but at wrong address" as * a failure and unmap again. */ -new_alloc_size = HOST_PAGE_ALIGN(new_brk - brk_page + 1); +new_alloc_size = HOST_PAGE_ALIGN(new_brk - brk_page); mapped_addr = get_errno(target_mmap(brk_page, new_alloc_size, PROT_READ|PROT_WRITE, MAP_ANON|MAP_PRIVATE, 0, 0)); if (mapped_addr == brk_page) { target_brk = new_brk; +brk_page = HOST_PAGE_ALIGN(target_brk); return target_brk; } else if (mapped_addr != -1) { /* Mapped but at wrong address, meaning there wasn't actually -- 1.7.5.1
Re: [Qemu-devel] [PATCH] virtio: correctly initialize vm_running
On Wed, May 18, 2011 at 01:57:37PM +0800, Jason Wang wrote: > Current vm_running was not explicitly initialized and its value was changed by > vm state notifier, this may confuse the virtio device being hotplugged such as > virtio-net with vhost backend as it may think the vm was not running. Solve > this > by initialize this value explicitly in virtio_common_init(). > > Signed-off-by: Jason Wang Applied, thanks > --- > 0 files changed, 0 insertions(+), 0 deletions(-) > > diff --git a/hw/virtio.c b/hw/virtio.c > index 6e8814c..27d7e50 100644 > --- a/hw/virtio.c > +++ b/hw/virtio.c > @@ -789,6 +789,7 @@ VirtIODevice *virtio_common_init(const char *name, > uint16_t device_id, > vdev->queue_sel = 0; > vdev->config_vector = VIRTIO_NO_VECTOR; > vdev->vq = qemu_mallocz(sizeof(VirtQueue) * VIRTIO_PCI_QUEUE_MAX); > +vdev->vm_running = vm_running; > for(i = 0; i < VIRTIO_PCI_QUEUE_MAX; i++) { > vdev->vq[i].vector = VIRTIO_NO_VECTOR; > vdev->vq[i].vdev = vdev;
Re: [Qemu-devel] [SeaBIOS] Graphics card pass-through working with two pass pci-initialization
On 01.06.2011, at 09:30, Gerd Hoffmann wrote: > Hi, > >> 0xE000 is hard-coded in the DSDT for both piix and q35 as below. >> If the range is determined dynamically, the area also needs to be >> updated somehow dynamically. >> >> ... >> Name (_CRS, ResourceTemplate () >> ... >> DWordMemory (ResourceProducer, PosDecode, MinFixed, >> MaxFixed, NonCacheable, ReadWrite, >> 0x, // Address Space Granularity >> 0xE000, // Address Range Minimum >> 0xFEBF, // Address Range Maximum >> 0x, // Address Translation Offset >> 0x1EC0, // Address Length >> ,, , AddressRangeMemory, TypeStatic) > > Uhm, indeed. I know next to nothing about ACPI though. Ideas anyone how > this could be done? We're facing similar issues on PPC. The equivalent of the DSDT there is the device tree, which is currently passed in as binary blob and slightly appended for dynamic configuration. I'd much rather like to see it fully generated inside of Qemu from all the information we have available there, so we don't run into consistency issues. This will be even more required when we pass through SoC devices to the guest, which are not on a PCI bus. Without specifying them in the DT, the guest doesn't know about them. X86 has a similar issue. Take a look at the HPET for example. If you don't want an HPET inside the guest, the DSDT needs to be modified. So you need to change things at 2 places - the DSDT and Qemu. I don't know how much work it would be to generate the DSDT dynamically from Qemu, but IMHO that's the sanest way to make things flexible. We could probably even extract most information from the Qdev tree. Alex
[Qemu-devel] Hello Would You Like To Earn
Hello qemu-devel Would you like to earn an extra $200 everyday?, for just 45 minutes work? You could quit your job and make double the money at home working for yourself. visit->http:tinyurl.com/3brnlpx Regards, Sharon Burns Survey Human Resources Dept.
Re: [Qemu-devel] Question on virtio disk maximum index and maximum partition
On Wed, 1 Jun 2011, Wei Liu wrote: > That's exactly what I'm seeing... > > Maybe I should modify the checking and make a exception for virtio > disk? Stefano, what would you say? That is not a check, it is just the upper limit to decode "vda1" or "vde2" in a disk number and partition number. I would just use the same as scsi.
Re: [Qemu-devel] [SeaBIOS] Graphics card pass-through working with two pass pci-initialization
Sorry I forgot to include all addresses. I don't know how much work it would be to generate the DSDT dynamically from Qemu, but IMHO that's the sanest way to make things flexible. We could probably even extract most information from the Qdev tree. Well I have written for coreboot a ACPI bytecode generator (check acpigen.c). Maybe moving to SeaBIOS+Coreboot would make sense? It has the PCI resource allocator and all already done. Thanks, Rudolf
Re: [Qemu-devel] QEMU for ppc440 on i386 host
On Wed, Jun 01, 2011 at 15:36, Edgar E. Iglesias wrote: > On Wed, Jun 01, 2011 at 03:03:18PM +0800, Lê Đức Tài wrote: > > On 31.05.2011, at 23:52, Alexander Graf wrote: > > > On 31.05.2011, at 18:05, Lê Đức Tài wrote: > > > > > > > > Hi! > > > > My name is Tai. > > > > Sorry for bother you! > > > > > > > > I have a question about QEMU for powerpc. > > > > Can QEMU emulate the ppc440 on a i386 host? > > > > I mean it is full-system emulation. > > > > Because when I'm trying to run linux ppc440 with qemu on my i386 PC > > > > I alway get the error like that: > > > > > > > > $ qemu-system-ppc -M bamboo -kernel vmlinux > > > > qemu: fatal: Trying to execute code outside RAM or ROM at 0xc000 > > > > > > > > NIP c000 LR CTR XER > > > > MSR HID0 0300 HF idx 0 > > > > Segmentation fault > > > > > > > > $ qemu-system-ppc -M bamboo -kernel arch/powerpc/boot/uImage > > > > Trying to read privileged spr 947 3b3 at 1014 > > > > Trying to read invalid spr 62 03e at 0778 > > > > > > > > I using QEMU that configured and built with device tree support > > > > (enable libfdt). > > > > QEMU version 0.14.1 > > > > The kernel image is built for bamboo using powerpc-440 toolchain. > > > > kernel-version 2.6.38.2 > > > > > > PPC440 emulation support has only been added to Qemu very recently > > > (0.14). So far, the only board that is somewhat known to work is the > > > virtex5 ml507 one with a 440x5 xilinx cpu. Please see > > > [1]http://wiki.qemu.org/ChangeLog/0.14#PPC for details. > > > > > > The bamboo board was added to enable KVM support for 440, it hasn't > > > been used with the emulation target yet. > > > > > > What exactly are you trying to emulate? > > > > > > > > > Alex > > > > Thank for your answer. > > I'm trying to emulate the ppc440 on a i386 host. > > My final target: Linux for PPC440 can run on Qemu and drop a shell > > prompt. > > When I try to run this command: > > $ qemu-system-ppc -M ? > > Supported machines are: > > virtex-ml507 Xilinx Virtex ML507 reference design > > mpc8544ds mpc8544ds > > bamboobamboo (alias of bamboo-0.13) > > bamboo-0.13 bamboo > > bamboo-0.12 bamboo > > ref405ep ref405ep > > taihu taihu > > mac99 Mac99 based PowerMAC > > g3beigeHeathrow based PowerMAC (default) > > prep PowerPC PREP platform > > I find two boards that have a PPC440 cpu: virtex-ml507 and bamboo. > > I have checked the bamboo board fist, then I get the result as above. > > Hower, the ml507 board seems not working too. > > I have built kernel image for Virtex ML507 using powerpc-440 toolchain. > > kernel-version: linux-2.6.39 > > config: 44x/virtex5_defconfig > > When I'm trying to run: > > $ qemu-system-ppc -M virtex-ml507 -kernel > > arch/powerpc/boot/simpleImage.virtex440-ml507.elf > > I get the following output: > > Unable to get size of device tree file 'ppc.dtb' > > Warning: vlan 0 with no nics > > Qemu just display a monitor console, it seems not to be loading the > > kernel. > > Could you help me some ideas? > > Could you help me the guide to emulate virtex-ml507 on i368 host? > > Hi, > > I've just uploaded a test image to the wiki's download pages. > See http://wiki.qemu.org/Download. > > You'll need a recent qemu, built with libfdt support. > > I threw in the linux kernelconfig used to build the image. I > used a rather old version (2.6.34) of the kernel provided by > Xilinx at: > git://git.xilinx.com/linux-2.6-xlnx.git > commit: > 91e2c43452914a789a4bebea7c199695bbf888f2 > > My guess is that you should be able to build a kernel directly > from upstream, but I haven't tried. > > One thing to note is that qemu still lacks support for the ll-temac > (ethernet nic) and the kernel hangs when probing for it. The workaround > is to remove it from the device tree file (ppc.dtb). Already done in > the archive with my test image, but good to know if you start rolling > your own stuff. > > Regarding the ll-temac, we've got it running and plan to submit, I just > need to get some time to clean it up etc.. sorry. > > Good luck > Thank you. I've just downloaded the test image from QEMU site. Then I run the qemu-run.sh script, it boot succesful. I get a nice shell. # cat /proc/cpuinfo processor : 0 cpu : 440 in Virtex-5 FXT revision: 25.16 (pvr 7ff2 1910) bogomips: 800.00 timebase: 4 platform: Xilinx Virtex440 model : testing Memory : 256 MB Thank for your support one more. I will get the Xilinx kernel and try to build it. Tai
[Qemu-devel] Hello Would You Like To Earn
Hello qemu-devel Would you like to earn an extra $200 everyday?, for just 45 minutes work? You could quit your job and make double the money at home working for yourself. visit->http:tinyurl.com/3brnlpx Regards, Sharon Burns Survey Human Resources Dept.
Re: [Qemu-devel] [PATCH 01/14] usb-linux: Set usb_auto_timer to NULL after deleting it
On 05/31/11 11:35, Hans de Goede wrote: We might check for it being NULL later, if the device gets unplugged. --- usb-linux.c |1 + 1 files changed, 1 insertions(+), 0 deletions(-) diff --git a/usb-linux.c b/usb-linux.c index 4d7a31a..ea3ab5f 100644 --- a/usb-linux.c +++ b/usb-linux.c @@ -1675,6 +1675,7 @@ static void usb_host_auto_check(void *unused) /* nothing to watch */ if (usb_auto_timer) { qemu_del_timer(usb_auto_timer); +usb_auto_timer = NULL; This is wrong. qemu_del_timer just removes the scheduled timer event, not the timer structure itself. qemu_free_timer does the later. cheers, Gerd
Re: [Qemu-devel] [SeaBIOS] Graphics card pass-through working with two pass pci-initialization
On 06/01/2011 12:56 PM, Alexander Graf wrote: On 01.06.2011, at 09:30, Gerd Hoffmann wrote: > Hi, > >> 0xE000 is hard-coded in the DSDT for both piix and q35 as below. >> If the range is determined dynamically, the area also needs to be >> updated somehow dynamically. >> >> ... >> Name (_CRS, ResourceTemplate () >> ... >> DWordMemory (ResourceProducer, PosDecode, MinFixed, MaxFixed, NonCacheable, ReadWrite, >> 0x, // Address Space Granularity >> 0xE000, // Address Range Minimum >> 0xFEBF, // Address Range Maximum >> 0x, // Address Translation Offset >> 0x1EC0, // Address Length >> ,, , AddressRangeMemory, TypeStatic) > > Uhm, indeed. I know next to nothing about ACPI though. Ideas anyone how this could be done? We're facing similar issues on PPC. The equivalent of the DSDT there is the device tree, which is currently passed in as binary blob and slightly appended for dynamic configuration. I'd much rather like to see it fully generated inside of Qemu from all the information we have available there, so we don't run into consistency issues. This will be even more required when we pass through SoC devices to the guest, which are not on a PCI bus. Without specifying them in the DT, the guest doesn't know about them. X86 has a similar issue. Take a look at the HPET for example. If you don't want an HPET inside the guest, the DSDT needs to be modified. So you need to change things at 2 places - the DSDT and Qemu. I don't know how much work it would be to generate the DSDT dynamically from Qemu, but IMHO that's the sanest way to make things flexible. We could probably even extract most information from the Qdev tree. Generating the DSDT dynamically is hard, but the DSDT itself is dynamic. You can make any function talk to the firmware configuration interface and return results that depend on the information there. -- error compiling committee.c: too many arguments to function
Re: [Qemu-devel] [SeaBIOS] Graphics card pass-through working with two pass pci-initialization
On 01.06.2011, at 13:13, Avi Kivity wrote: > On 06/01/2011 12:56 PM, Alexander Graf wrote: >> On 01.06.2011, at 09:30, Gerd Hoffmann wrote: >> >> > Hi, >> > >> >> 0xE000 is hard-coded in the DSDT for both piix and q35 as below. >> >> If the range is determined dynamically, the area also needs to be >> >> updated somehow dynamically. >> >> >> >> ... >> >> Name (_CRS, ResourceTemplate () >> >> ... >> >> DWordMemory (ResourceProducer, PosDecode, MinFixed, >> >> MaxFixed, NonCacheable, ReadWrite, >> >> 0x, // Address Space Granularity >> >> 0xE000, // Address Range Minimum >> >> 0xFEBF, // Address Range Maximum >> >> 0x, // Address Translation Offset >> >> 0x1EC0, // Address Length >> >> ,, , AddressRangeMemory, TypeStatic) >> > >> > Uhm, indeed. I know next to nothing about ACPI though. Ideas anyone how >> > this could be done? >> >> We're facing similar issues on PPC. The equivalent of the DSDT there is the >> device tree, which is currently passed in as binary blob and slightly >> appended for dynamic configuration. I'd much rather like to see it fully >> generated inside of Qemu from all the information we have available there, >> so we don't run into consistency issues. >> >> This will be even more required when we pass through SoC devices to the >> guest, which are not on a PCI bus. Without specifying them in the DT, the >> guest doesn't know about them. X86 has a similar issue. Take a look at the >> HPET for example. If you don't want an HPET inside the guest, the DSDT needs >> to be modified. So you need to change things at 2 places - the DSDT and Qemu. >> >> I don't know how much work it would be to generate the DSDT dynamically from >> Qemu, but IMHO that's the sanest way to make things flexible. We could >> probably even extract most information from the Qdev tree. >> > > Generating the DSDT dynamically is hard, but the DSDT itself is dynamic. You > can make any function talk to the firmware configuration interface and return > results that depend on the information there. Does that hold true for nodes as well? I thought you can only use 'functions' for specific elements? Alex
Re: [Qemu-devel] [SeaBIOS] Graphics card pass-through working with two pass pci-initialization
On 06/01/2011 02:16 PM, Alexander Graf wrote: >> > > Generating the DSDT dynamically is hard, but the DSDT itself is dynamic. You can make any function talk to the firmware configuration interface and return results that depend on the information there. Does that hold true for nodes as well? I thought you can only use 'functions' for specific elements? I believe that if you declare _CRS as a method, it should work (there are both "Name" and "Method" _CRSs in the DSDT currently). -- error compiling committee.c: too many arguments to function
Re: [Qemu-devel] [PATCH 03/14] usb-linux: Teach about super speed
On 05/31/11 11:35, Hans de Goede wrote: +if (!strcmp(buf, "5000")) { +speed = USB_SPEED_SUPER; +} else if (!strcmp(buf, "480")) { Patch applied. thanks, Gerd
[Qemu-devel] [PATCH] qemu-char: Print strerror message on failure
The only way for chardev drivers to communicate an error was to return a NULL pointer, which resulted in an error message that said _that_ something went wrong, but not _why_. This patch changes the interface to return 0/-errno and updates qemu_chr_open_opts to use strerror to display a more helpful error message. Signed-off-by: Kevin Wolf --- console.c |8 ++- console.h |2 +- hw/baum.c |7 +- hw/msmouse.c |5 +- hw/msmouse.h |2 +- qemu-char.c | 165 +++-- spice-qemu-char.c |9 ++- ui/qemu-spice.h |2 +- 8 files changed, 117 insertions(+), 83 deletions(-) diff --git a/console.c b/console.c index 871c1d4..314d625 100644 --- a/console.c +++ b/console.c @@ -1507,7 +1507,7 @@ static void text_console_do_init(CharDriverState *chr, DisplayState *ds) chr->init(chr); } -CharDriverState *text_console_init(QemuOpts *opts) +int text_console_init(QemuOpts *opts, CharDriverState **_chr) { CharDriverState *chr; TextConsole *s; @@ -1539,7 +1539,7 @@ CharDriverState *text_console_init(QemuOpts *opts) if (!s) { free(chr); -return NULL; +return -EBUSY; } s->chr = chr; @@ -1547,7 +1547,9 @@ CharDriverState *text_console_init(QemuOpts *opts) s->g_height = height; chr->opaque = s; chr->chr_set_echo = text_console_set_echo; -return chr; + +*_chr = chr; +return 0; } void text_consoles_set_display(DisplayState *ds) diff --git a/console.h b/console.h index 64d1f09..c09537b 100644 --- a/console.h +++ b/console.h @@ -354,7 +354,7 @@ void vga_hw_text_update(console_ch_t *chardata); int is_graphic_console(void); int is_fixedsize_console(void); -CharDriverState *text_console_init(QemuOpts *opts); +int text_console_init(QemuOpts *opts, CharDriverState **_chr); void text_consoles_set_display(DisplayState *ds); void console_select(unsigned int index); void console_color_init(DisplayState *ds); diff --git a/hw/baum.c b/hw/baum.c index 2aaf5ff..33a22a7 100644 --- a/hw/baum.c +++ b/hw/baum.c @@ -576,7 +576,7 @@ static void baum_close(struct CharDriverState *chr) qemu_free(baum); } -CharDriverState *chr_baum_init(QemuOpts *opts) +int chr_baum_init(QemuOpts *opts, CharDriverState **_chr) { BaumDriverState *baum; CharDriverState *chr; @@ -629,7 +629,8 @@ CharDriverState *chr_baum_init(QemuOpts *opts) qemu_chr_generic_open(chr); -return chr; +*_chr = chr; +return 0; fail: qemu_free_timer(baum->cellCount_timer); @@ -638,5 +639,5 @@ fail_handle: qemu_free(handle); qemu_free(chr); qemu_free(baum); -return NULL; +return -EIO; } diff --git a/hw/msmouse.c b/hw/msmouse.c index 05f893c..67c6cd4 100644 --- a/hw/msmouse.c +++ b/hw/msmouse.c @@ -64,7 +64,7 @@ static void msmouse_chr_close (struct CharDriverState *chr) qemu_free (chr); } -CharDriverState *qemu_chr_open_msmouse(QemuOpts *opts) +int qemu_chr_open_msmouse(QemuOpts *opts, CharDriverState **_chr) { CharDriverState *chr; @@ -74,5 +74,6 @@ CharDriverState *qemu_chr_open_msmouse(QemuOpts *opts) qemu_add_mouse_event_handler(msmouse_event, chr, 0, "QEMU Microsoft Mouse"); -return chr; +*_chr = chr; +return 0; } diff --git a/hw/msmouse.h b/hw/msmouse.h index 456cb21..8b853b3 100644 --- a/hw/msmouse.h +++ b/hw/msmouse.h @@ -1,2 +1,2 @@ /* msmouse.c */ -CharDriverState *qemu_chr_open_msmouse(QemuOpts *opts); +int qemu_chr_open_msmouse(QemuOpts *opts, CharDriverState **_chr); diff --git a/qemu-char.c b/qemu-char.c index 5e04a20..a8e4094 100644 --- a/qemu-char.c +++ b/qemu-char.c @@ -220,13 +220,15 @@ static int null_chr_write(CharDriverState *chr, const uint8_t *buf, int len) return len; } -static CharDriverState *qemu_chr_open_null(QemuOpts *opts) +static int qemu_chr_open_null(QemuOpts *opts, CharDriverState **_chr) { CharDriverState *chr; chr = qemu_mallocz(sizeof(CharDriverState)); chr->chr_write = null_chr_write; -return chr; + +*_chr= chr; +return 0; } /* MUX driver for serial I/O splitting */ @@ -635,18 +637,21 @@ static CharDriverState *qemu_chr_open_fd(int fd_in, int fd_out) return chr; } -static CharDriverState *qemu_chr_open_file_out(QemuOpts *opts) +static int qemu_chr_open_file_out(QemuOpts *opts, CharDriverState **_chr) { int fd_out; TFR(fd_out = qemu_open(qemu_opt_get(opts, "path"), O_WRONLY | O_TRUNC | O_CREAT | O_BINARY, 0666)); -if (fd_out < 0) -return NULL; -return qemu_chr_open_fd(-1, fd_out); +if (fd_out < 0) { +return -errno; +} + +*_chr = qemu_chr_open_fd(-1, fd_out); +return 0; } -static CharDriverState *qemu_chr_open_pipe(QemuOpts *opts) +static int qemu_chr_open_pipe(QemuOpts *opts, CharDriverState **_chr) { int fd_in, fd_out; char filename_in[256], filename_out[256]; @@ -654,7 +659,7 @@ static CharDri
Re: [Qemu-devel] [PATCH 02/14] usb-linux: Get speed from sysfs rather then from the connectinfo ioctl
On 05/31/11 11:35, Hans de Goede wrote: The connectinfo ioctl only differentiates between lo speed devices, and all other speeds, where as we would like to know the real speed. The real speed is available in sysfs so use that when available. Applied. thanks, Gerd
Re: [Qemu-devel] [PATCH 04/14] usb-linux: Don't do perror when errno is not set
On 05/31/11 11:35, Hans de Goede wrote: Note that "op" also is not set, so before this change these error paths would feed NULL to perror. Patch applied. thanks, Gerd
Re: [Qemu-devel] [PATCH 04/14] usb-linux: Don't do perror when errno is not set
On 05/31/11 11:35, Hans de Goede wrote: Note that "op" also is not set, so before this change these error paths would feed NULL to perror. Patch applied. thanks, Gerd
[Qemu-devel] [PATCH] linux-user: Define AT_RANDOM to support target dynamic linkers that do ASLR
From: Laurent ALFONSI The dynamic linker of the GNU C library v2.10+ uses the ELF auxialiary vector AT_RANDOM as a pointer to a 16-bit random value. Prior this patch the value of AT_RANDOM was not defined by the ELF loader of QEMU so the GNU dynamic linker de-referenced the NULL pointer instead. As a consequence any target program linked to the GNU C library v2.10+ crashed due to a SEGFAULT. Note AT_RANDOM now points to the start of the text segment thus the 16-bit value is not random at all, however it is definitively readable. This "dummy" behavior could be improved later. Signed-off-by: Laurent ALFONSI Signed-off-by: Cédric VINCENT --- You can easily test this patch with ARMedSlack-13+: ftp://ftp.armedslack.org/armedslack/armedslack-devtools/minirootfs/roots/ linux-user/elfload.c |9 - 1 files changed, 8 insertions(+), 1 deletions(-) diff --git a/linux-user/elfload.c b/linux-user/elfload.c index dcfeb7a..6f67286 100644 --- a/linux-user/elfload.c +++ b/linux-user/elfload.c @@ -927,7 +927,7 @@ struct exec #define TARGET_ELF_PAGESTART(_v) ((_v) & ~(unsigned long)(TARGET_ELF_EXEC_PAGESIZE-1)) #define TARGET_ELF_PAGEOFFSET(_v) ((_v) & (TARGET_ELF_EXEC_PAGESIZE-1)) -#define DLINFO_ITEMS 12 +#define DLINFO_ITEMS 13 static inline void memcpy_fromfs(void * to, const void * from, unsigned long n) { @@ -1271,6 +1271,13 @@ static abi_ulong create_elf_tables(abi_ulong p, int argc, int envc, NEW_AUX_ENT(AT_EGID, (abi_ulong) getegid()); NEW_AUX_ENT(AT_HWCAP, (abi_ulong) ELF_HWCAP); NEW_AUX_ENT(AT_CLKTCK, (abi_ulong) sysconf(_SC_CLK_TCK)); + +/* The dynamic linker of the GNU C library v2.10+ uses the ELF + * auxialiary vector AT_RANDOM as a pointer to a 16-bit random + * value. Note the start of the text segment is not random at + * all, however it is definitively readeable. */ +NEW_AUX_ENT(AT_RANDOM, (abi_ulong) info->start_code); + if (k_platform) NEW_AUX_ENT(AT_PLATFORM, u_platform); #ifdef ARCH_DLINFO -- 1.7.5.1
Re: [Qemu-devel] virtio scsi host draft specification, v2
Device initialization - The initialization routine should first of all discover the device's control virtqueues. The driver should then place at least a buffer in the control receiveq. Size of the buffer? Good catch. I'll add this to the configuration information. The cdb, data and sense fields must reside in separate buffers. The cdb field is always read-only. The data buffers may be either read-only or write-only, depending on the request, with the read-only buffers coming first. The sense buffer is always write-only. The request shall have num_dataout read-only data buffers and num_datain write-only data buffers. One of these two values must be zero if the VIRTIO_SCSI_F_INOUT has not been negotiated. Why do num_datain/num_dataout need to be there? We can just look at the number of io/out bufs in virtio descriptors, no? This depends on having a single variable-sized datum per direction. I'd rather avoid this assumption. Also, from experience, it's better not to have any layout assumptions - let the guest stick everything in a single in + single out buffer if it desires. Ok, changed. Remaining fields are filled in by the device. The sense_len field indicates the number of bytes actually written to the sense buffer, while the residual field indicates the residual size, calculated as data_length - number_of_transferred_bytes. Again virtio gives you total number of written bytes in the used len field. So just one of these fields will be enough. The two fields give completely different information (sense vs. real data), and the math has to be done anyway in either the driver or the device. The device is going to be written just once and actually it already has the separate information, so I put it in the struct and spared some annoyance to driver writers. The control receiveq is used by the device to report information on logical units that are attached to it. The driver should always leave a few (?) buffers ready in the control receiveq. The device may end up dropping events if it finds no buffer ready. [...] It looks like there's a finite number of possible events. If you keep opening and closing the tray from the guest, you could fire a possibly unbounded number of events. If this mechanism is unreliable, how is it useful? Events alone are unreliable, but the combination of events+sense is reliable. And events+sense are still useful because: 1) sense codes only provide information when the driver next accesses the unit or, at best, the target. Until then, the driver has no clue that the event happened. Events can be reported at the time they happen. This is important for example when the host requests a clean hot-unplug of a disk: if the disk is idle in the guest, the driver may never see the event and acknowledge the hot-unplug! 2) for this reason, unit attention has no way to signal events on a target that is unknown to the driver (because it has just been hotplugged). Events and sense codes together are reliable because the driver is aware of dropped events. The driver can react to it by rescanning the bus (which will let the driver see the unit attention conditions) and polling CD-ROM units for events it had subscribed to. I'll add a short version of the above text to the spec, and I'll also add the following dummy event: - No event #define VIRTIO_SCSI_T_NO_EVENT 0 This event is fired in the following cases: 1) When the device detects in the eventq a buffer that is shorter than what is indicated in the configuration field, it will use it immediately and put this dummy value in the event field. A well-written driver will never observe this situation. 2) When events are dropped, the device may signal this event as soon as the drivers makes a buffer available, in order to request action from the driver. In this case, of course, this event will be reported with the VIRTIO_SCSI_T_EVENTS_MISSED flag. This will make it even clearer that no queuing is needed. - Asynchronous notification #define VIRTIO_SCSI_T_ASYNC_NOTIFY 1 struct virtio_scsi_an_event { u8 lun[8]; u32 event; } #define VIRTIO_SCSI_EVT_ASYNC_MEDIA_CHANGE16 By sending this event, the device signals that an event was fired from a physical interface. The device only sends events that the driver has subscribed to via the "Asynchronous notification subscription" command. All fields are written by the device. The event field is set to VIRTIO_SCSI_T_ASYNC_NOTIFY. We'll have to define events, right? They are defined in terms of annex A of the MMC spec (see the "Asynchronous notification query" command). Media change is the only supported event for now, but others are already defined by the MMC spec. Paolo
[Qemu-devel] [PATCH] bdrv_img_create: Fix segfault
Block drivers that don't support creating images don't have a size option. Fail gracefully instead of segfaulting when trying to access the option's value. Signed-off-by: Kevin Wolf --- block.c |5 +++-- 1 files changed, 3 insertions(+), 2 deletions(-) diff --git a/block.c b/block.c index ebd1501..8df2a5f 100644 --- a/block.c +++ b/block.c @@ -2900,7 +2900,7 @@ int bdrv_img_create(const char *filename, const char *fmt, char *options, uint64_t img_size, int flags) { QEMUOptionParameter *param = NULL, *create_options = NULL; -QEMUOptionParameter *backing_fmt, *backing_file; +QEMUOptionParameter *backing_fmt, *backing_file, *size; BlockDriverState *bs = NULL; BlockDriver *drv, *proto_drv; BlockDriver *backing_drv = NULL; @@ -2983,7 +2983,8 @@ int bdrv_img_create(const char *filename, const char *fmt, // The size for the image must always be specified, with one exception: // If we are using a backing file, we can obtain the size from there -if (get_option_parameter(param, BLOCK_OPT_SIZE)->value.n == -1) { +size = get_option_parameter(param, BLOCK_OPT_SIZE); +if (size && size->value.n == -1) { if (backing_file && backing_file->value.s) { uint64_t size; char buf[32]; -- 1.7.5.2
[Qemu-devel] Hello Would You Like To Earn
Hello qemu-devel Would you like to earn an extra $200 everyday?, for just 45 minutes work? You could quit your job and make double the money at home working for yourself. visit->http:tinyurl.com/3brnlpx Regards, Sharon Burns Survey Human Resources Dept.
Re: [Qemu-devel] [PATCH 06/14] usb-linux: Ensure devep != 0
On 05/31/11 11:35, Hans de Goede wrote: So that we don't index endp_table with a negative index. Patch applied. thanks, Gerd
Re: [Qemu-devel] [PATCH 05/14] usb-linux: Don't call usb_host_close when usb_host_open fails
What bug you are trying to fix here? cheers, Gerd
Re: [Qemu-devel] [PATCH 07/14] usb-linux: If opening a device fails remove it from our filter list
On 05/31/11 11:35, Hans de Goede wrote: So that we don't retry to open it every 2 seconds flooding stderr with error messages. The polling here is done intentionally, so the devices catched by the filter show up in the guest automagically as soon as they are plugged in. Just zapping the filter on failure isn't the right thing to do here. We could try to do something more clever than polling sysfs every two seconds though, such using inotify to watch /sys/bus/usb/devices for new devices poping up. cheers, Gerd
Re: [Qemu-devel] [PATCH 08/14] usb-linux: Don't try to open the same device twice
On 05/31/11 11:35, Hans de Goede wrote: If a user wants to redirect 2 identical usb sticks, in theory this is possible by doing: usb_add host:1234:5678 usb_add host:1234:5678 But this will lead to us trying to open the first stick twice, since we don't break the loop after having found a match in our filter list, so the next' filter list entry will result in us trying to open the same device again. Fix Good catch. Patch applied. thanks, Gerd
[Qemu-devel] [PATCH] linux-user: Fix the load of ELF files that have no "useful" symbol
This patch fixes a "double free()" due to "realloc(syms, 0)" in the loader when the ELF file has no "useful" symbol, as with the following example (compiled with "sh4-linux-gcc -nostdlib"): .text .align 1 .global _start _start: mov #1, r3 trapa #40 // syscall(__NR_exit) nop The bug appears when the log (option "-d") is enabled. Signed-off-by: Cédric VINCENT Signed-off-by: Yves JANIN --- linux-user/elfload.c | 34 +++--- 1 files changed, 19 insertions(+), 15 deletions(-) diff --git a/linux-user/elfload.c b/linux-user/elfload.c index 6f67286..4e77c89 100644 --- a/linux-user/elfload.c +++ b/linux-user/elfload.c @@ -1650,9 +1650,9 @@ static void load_symbols(struct elfhdr *hdr, int fd, abi_ulong load_bias) { int i, shnum, nsyms, sym_idx = 0, str_idx = 0; struct elf_shdr *shdr; -char *strings; -struct syminfo *s; -struct elf_sym *syms, *new_syms; +char *strings = NULL; +struct syminfo *s = NULL; +struct elf_sym *new_syms, *syms = NULL; shnum = hdr->e_shnum; i = shnum * sizeof(struct elf_shdr); @@ -1677,24 +1677,19 @@ static void load_symbols(struct elfhdr *hdr, int fd, abi_ulong load_bias) /* Now know where the strtab and symtab are. Snarf them. */ s = malloc(sizeof(*s)); if (!s) { -return; +goto give_up; } i = shdr[str_idx].sh_size; s->disas_strtab = strings = malloc(i); if (!strings || pread(fd, strings, i, shdr[str_idx].sh_offset) != i) { -free(s); -free(strings); -return; +goto give_up; } i = shdr[sym_idx].sh_size; syms = malloc(i); if (!syms || pread(fd, syms, i, shdr[sym_idx].sh_offset) != i) { -free(s); -free(strings); -free(syms); -return; +goto give_up; } nsyms = i / sizeof(struct elf_sym); @@ -1717,16 +1712,18 @@ static void load_symbols(struct elfhdr *hdr, int fd, abi_ulong load_bias) } } +/* No "useful" symbol. */ +if (nsyms == 0) { +goto give_up; +} + /* Attempt to free the storage associated with the local symbols that we threw away. Whether or not this has any effect on the memory allocation depends on the malloc implementation and how many symbols we managed to discard. */ new_syms = realloc(syms, nsyms * sizeof(*syms)); if (new_syms == NULL) { -free(s); -free(syms); -free(strings); -return; +goto give_up; } syms = new_syms; @@ -1741,6 +1738,13 @@ static void load_symbols(struct elfhdr *hdr, int fd, abi_ulong load_bias) s->lookup_symbol = lookup_symbolxx; s->next = syminfos; syminfos = s; + +return; + +give_up: +free(s); +free(strings); +free(syms); } int load_elf_binary(struct linux_binprm * bprm, struct target_pt_regs * regs, -- 1.7.5.1
Re: [Qemu-devel] [PATCH 09/14] usb-linux: Don't declare a usbdevice_name
On 05/31/11 11:35, Hans de Goede wrote: Declaring a usbdevice_name while we still have an explicit call to usb_host_device_open in vl.c causes usb_host_device_open to get called twice if the initial call fails. Wrong way around, the vl.c call should be zapped instead. Just did. cheers, Gerd
[Qemu-devel] Hello Would You Like To Earn
Hello qemu-devel Would you like to earn an extra $200 everyday?, for just 45 minutes work? You could quit your job and make double the money at home working for yourself. visit->http:tinyurl.com/3brnlpx Regards, Sharon Burns Survey Human Resources Dept.
Re: [Qemu-devel] [PATCH 13/14] usb-bus: Don't detach non attached devices on device exit
On 05/31/11 11:35, Hans de Goede wrote: This causes an "Error: tried to detach unattached usb device " to be printed, this can happen when deleting ie a usb host qdev, which did not get attached (because a device matching the filter never got plugged in). Patch applied. thanks, Gerd
Re: [Qemu-devel] [PATCH 10/14] usb-linux: Enlarge buffer for descriptors to 8192 bytes
On 05/31/11 11:35, Hans de Goede wrote: 1024 bytes is way to small, one hd UVC webcam I have over here has so many resolutions its descriptors take op close to 4k. Hopefully 8k will be enough for all devices. Patch applied. thanks, Gerd
Re: [Qemu-devel] [PATCH 14/14] usb: Proper error propagation for usb_device_attach errors
Hi, I'll wait a bit for more feedback and then change [PATCH 14/14] usb: Proper error propagation for usb_device_attach errors I'll wait for new revisions of patches 12+14 then. cheers, Gerd
[Qemu-devel] [PATCH 1/3] lsi: Fix unused-but-set-variable warning
This warning is new in gcc 4.6. Signed-off-by: Christophe Fergeau --- hw/lsi53c895a.c |2 -- 1 files changed, 0 insertions(+), 2 deletions(-) diff --git a/hw/lsi53c895a.c b/hw/lsi53c895a.c index 83084b6..90c6cbc 100644 --- a/hw/lsi53c895a.c +++ b/hw/lsi53c895a.c @@ -889,7 +889,6 @@ static void lsi_do_msgout(LSIState *s) uint8_t msg; int len; uint32_t current_tag; -SCSIDevice *current_dev; lsi_request *current_req, *p, *p_next; int id; @@ -901,7 +900,6 @@ static void lsi_do_msgout(LSIState *s) current_req = lsi_find_by_tag(s, current_tag); } id = (current_tag >> 8) & 0xf; -current_dev = s->bus.devs[id]; DPRINTF("MSG out len=%d\n", s->dbc); while (s->dbc) { -- 1.7.5.2
Re: [Qemu-devel] [PATCH 11/14] usb-bus: Add knowledge of USB_SPEED_SUPER to usb_speed helper
On 05/31/11 11:35, Hans de Goede wrote: +[ USB_SPEED_SUPER ] = "5000", Patch applied. thanks, Gerd
Re: [Qemu-devel] virtio scsi host draft specification, v2
On Wed, Jun 01, 2011 at 01:59:14PM +0200, Paolo Bonzini wrote: > >>Device initialization > >>- > >> > >>The initialization routine should first of all discover the device's > >>control virtqueues. > >> > >>The driver should then place at least a buffer in the control receiveq. > > > >Size of the buffer? > > Good catch. I'll add this to the configuration information. > > >> The cdb, data and sense fields must reside in separate buffers. > >> The cdb field is always read-only. The data buffers may be either > >> read-only or write-only, depending on the request, with the read-only > >> buffers coming first. The sense buffer is always write-only. > >> > >> The request shall have num_dataout read-only data buffers and > >> num_datain write-only data buffers. One of these two values must be > >> zero if the VIRTIO_SCSI_F_INOUT has not been negotiated. > > > >Why do num_datain/num_dataout need to be there? > >We can just look at the number of io/out bufs in > >virtio descriptors, no? > > This depends on having a single variable-sized datum per direction. > I'd rather avoid this assumption. I think it's a sane assumption: does scsi ever give you more? If you have many how do you know the size of each? > >Also, from experience, it's better not to have any layout > >assumptions - let the guest stick everything in a single > >in + single out buffer if it desires. > > Ok, changed. > > >> Remaining fields are filled in by the device. The sense_len field > >> indicates the number of bytes actually written to the sense buffer, > >> while the residual field indicates the residual size, calculated as > >> data_length - number_of_transferred_bytes. > > > >Again virtio gives you total number of written bytes in the used len > >field. So just one of these fields will be enough. > > The two fields give completely different information (sense vs. real > data), and the math has to be done anyway in either the driver or > the device. The device is going to be written just once and > actually it already has the separate information, so I put it in the > struct and spared some annoyance to driver writers. Yes but this way you get duplicate information which means it can get out of sync. Go figure who's right then ... Further less data->less cache pressure ... > >>The control receiveq is used by the device to report information on > >>logical units that are attached to it. The driver should always > >>leave a few (?) buffers ready in the control receiveq. The device may > >>end up dropping events if it finds no buffer ready. > > > >[...] It looks like there's a finite number of possible events. > > If you keep opening and closing the tray from the guest, you could > fire a possibly unbounded number of events. In that case only the last one is really interesting. > >If this mechanism is unreliable, how is it useful? > > Events alone are unreliable, but the combination of events+sense is > reliable. And events+sense are still useful because: > > 1) sense codes only provide information when the driver next > accesses the unit or, at best, the target. Until then, the driver > has no clue that the event happened. Events can be reported at the > time they happen. This is important for example when the host > requests a clean hot-unplug of a disk: if the disk is idle in the > guest, the driver may never see the event and acknowledge the > hot-unplug! right. But if you then drop this because you don't have a buffer, you get the same problem. > 2) for this reason, unit attention has no way to signal events on a > target that is unknown to the driver (because it has just been > hotplugged). > > Events and sense codes together are reliable because the driver is > aware of dropped events. It is? How is it notified of dropped events? > The driver can react to it by rescanning > the bus (which will let the driver see the unit attention > conditions) and polling CD-ROM units for events it had subscribed > to. > > I'll add a short version of the above text to the spec, and I'll > also add the following dummy event: > > - No event > > #define VIRTIO_SCSI_T_NO_EVENT 0 > > This event is fired in the following cases: > > 1) When the device detects in the eventq a buffer that is shorter > than what is indicated in the configuration field, it will use > it immediately and put this dummy value in the event field. > A well-written driver will never observe this situation. > > 2) When events are dropped, the device may signal this event as > soon as the drivers makes a buffer available, in order to request > action from the driver. In this case, of course, this event will > be reported with the VIRTIO_SCSI_T_EVENTS_MISSED flag. For 2, you don't have a buffer - so how is this event reported? > This will make it even clearer that no queuing is needed. > > >>- Asynchronous notification > >> > >> #def
[Qemu-devel] [PATCH 0/3] Fix unused-but-set-variable warnings
Hi, Here are a few more "unused-but-set-variable" warning fixes which I got when rebuilding qemu. I can fold the other 2 patches that were already sent to this list in this series if needed. The 3rd hunk of the ehci patch needs a review from someone who knows the code, different values are assigned to the "pid" variable which the patch deletes, and further down in the function, ehci->pid is used, so maybe an "ehci->pid = pid;" line is missing in this function, in which case the patch would hide a bug instead of solving it. Similarly, the variable removed from the linux-user patch is assigned different values depending on some conditions, maybe it's not right to remove it but it should be used for "something". Christophe Christophe Fergeau (3): lsi: Fix unused-but-set-variable warning ehci: Fix unused-but-set-variable warning linux-user: Fix unused-but-set-variable warning hw/lsi53c895a.c|2 -- hw/usb-ehci.c | 11 +-- linux-user/linuxload.c |9 + 3 files changed, 2 insertions(+), 20 deletions(-) -- 1.7.5.2
[Qemu-devel] [PATCH 2/3] ehci: Fix unused-but-set-variable warning
This warning is new in gcc 4.6. Signed-off-by: Christophe Fergeau --- hw/usb-ehci.c | 11 +-- 1 files changed, 1 insertions(+), 10 deletions(-) diff --git a/hw/usb-ehci.c b/hw/usb-ehci.c index f63519e..8a7b1bb 100644 --- a/hw/usb-ehci.c +++ b/hw/usb-ehci.c @@ -523,11 +523,8 @@ static void ehci_detach(USBPort *port) static void ehci_reset(void *opaque) { EHCIState *s = opaque; -uint8_t *pci_conf; int i; -pci_conf = s->dev.config; - memset(&s->mmio[OPREGBASE], 0x00, MMIO_SIZE - OPREGBASE); s->usbcmd = NB_MAXINTRATE << USBCMD_ITC_SH; @@ -1105,18 +1102,15 @@ static int ehci_process_itd(EHCIState *ehci, int ret; int i, j; int ptr; -int pid; int pg; int len; int dir; int devadr; int endp; -int maxpkt; dir =(itd->bufptr[1] & ITD_BUFPTR_DIRECTION); devadr = get_field(itd->bufptr[0], ITD_BUFPTR_DEVADDR); endp = get_field(itd->bufptr[0], ITD_BUFPTR_EP); -maxpkt = get_field(itd->bufptr[1], ITD_BUFPTR_MAXPKT); for(i = 0; i < 8; i++) { if (itd->transact[i] & ITD_XACT_ACTIVE) { @@ -1134,11 +1128,8 @@ static int ehci_process_itd(EHCIState *ehci, DPRINTF("ISOCH: buffer %08X len %d\n", ptr, len); -if (!dir) { +if (!dir) cpu_physical_memory_rw(ptr, &ehci->buffer[0], len, 0); -pid = USB_TOKEN_OUT; -} else -pid = USB_TOKEN_IN; ret = USB_RET_NODEV; -- 1.7.5.2
Re: [Qemu-devel] [PATCH] linux-user: Fix the load of ELF files that have no "useful" symbol
On 06/01/2011 05:36 AM, Cédric VINCENT wrote: > This patch fixes a "double free()" due to "realloc(syms, 0)" in the > loader when the ELF file has no "useful" symbol, as with the following > example (compiled with "sh4-linux-gcc -nostdlib"): > > .text > .align 1 > .global _start > _start: > mov #1, r3 > trapa #40 // syscall(__NR_exit) > nop > > The bug appears when the log (option "-d") is enabled. > > Signed-off-by: Cédric VINCENT > Signed-off-by: Yves JANIN Reviewed-by: Richard Henderson r~
[Qemu-devel] Hello Would You Like To Earn
Hello qemu-devel Would you like to earn an extra $200 everyday?, for just 45 minutes work? You could quit your job and make double the money at home working for yourself. visit->http:tinyurl.com/3brnlpx Regards, Sharon Burns Survey Human Resources Dept.
[Qemu-devel] [PATCH 3/3] linux-user: Fix unused-but-set-variable warning
This warning is new in gcc 4.6. Signed-off-by: Christophe Fergeau --- linux-user/linuxload.c |9 + 1 files changed, 1 insertions(+), 8 deletions(-) diff --git a/linux-user/linuxload.c b/linux-user/linuxload.c index ac8c486..e66a4ea 100644 --- a/linux-user/linuxload.c +++ b/linux-user/linuxload.c @@ -57,7 +57,7 @@ static int prepare_binprm(struct linux_binprm *bprm) { struct statst; int mode; -int retval, id_change; +int retval; if(fstat(bprm->fd, &st) < 0) { return(-errno); @@ -73,14 +73,10 @@ static int prepare_binprm(struct linux_binprm *bprm) bprm->e_uid = geteuid(); bprm->e_gid = getegid(); -id_change = 0; /* Set-uid? */ if(mode & S_ISUID) { bprm->e_uid = st.st_uid; - if(bprm->e_uid != geteuid()) { - id_change = 1; - } } /* Set-gid? */ @@ -91,9 +87,6 @@ static int prepare_binprm(struct linux_binprm *bprm) */ if ((mode & (S_ISGID | S_IXGRP)) == (S_ISGID | S_IXGRP)) { bprm->e_gid = st.st_gid; - if (!in_group_p(bprm->e_gid)) { - id_change = 1; - } } retval = read(bprm->fd, bprm->buf, BPRM_BUF_SIZE); -- 1.7.5.2
Re: [Qemu-devel] virtio scsi host draft specification, v2
On 06/01/2011 02:51 PM, Michael S. Tsirkin wrote: The cdb, data and sense fields must reside in separate buffers. The cdb field is always read-only. The data buffers may be either read-only or write-only, depending on the request, with the read-only buffers coming first. The sense buffer is always write-only. The request shall have num_dataout read-only data buffers and num_datain write-only data buffers. One of these two values must be zero if the VIRTIO_SCSI_F_INOUT has not been negotiated. Why do num_datain/num_dataout need to be there? We can just look at the number of io/out bufs in virtio descriptors, no? This depends on having a single variable-sized datum per direction. I'd rather avoid this assumption. I think it's a sane assumption: does scsi ever give you more? Sense data, and data from the device, are both variable-length. With your suggestion that they may be in a single buffer, we do need size information for them. If you have many how do you know the size of each? That's up to the transport protocol to devise. However, I'll make a few changes: 1) num_dataout/num_datain will become byte counts rather than buffer counts. This fits better if the driver has the liberty has to use single buffers. 2) I'll add a sense_size field to give the size of the sense buffer, since now it won't necessarily be in a separate buffer (which gave this knowledge to the . The sense_len will tell the driver how many bytes were actually written (usually 0). Remaining fields are filled in by the device. The sense_len field indicates the number of bytes actually written to the sense buffer, while the residual field indicates the residual size, calculated as data_length - number_of_transferred_bytes. Again virtio gives you total number of written bytes in the used len field. So just one of these fields will be enough. The two fields give completely different information (sense vs. real data), and the math has to be done anyway in either the driver or the device. The device is going to be written just once and actually it already has the separate information, so I put it in the struct and spared some annoyance to driver writers. Yes but this way you get duplicate information which means it can get out of sync. Go figure who's right then ... But is it duplicate actually? The write-only buffer(s) start with datain_size bytes of data, and sense_size bytes of sense. If everything is placed in a single buffer, the used len field cannot capture how many bytes were written in the data and how many were written in the sense. In addition, if everything is placed in a single buffer, the device will have to report that it has written the full buffer because other parts of the response come after datain and sense. So, if I am going to give this liberty with buffers to the driver, I _have_ to keep the size information. Otherwise, I agree that it is redundant and I will remove it. What poison do you prefer? [...] It looks like there's a finite number of possible events. If you keep opening and closing the tray from the guest, you could fire a possibly unbounded number of events. In that case only the last one is really interesting. That's true. But events are rare enough that you should not have any problems feeding enough buffers to the device, and even in that case there is a way out in case of dropped events (see below). Assuming I am going to implement the device, requiring the device to queue events seems a bit masochistic. :) If this mechanism is unreliable, how is it useful? Events alone are unreliable, but the combination of events+sense is reliable. And events+sense are still useful because: 1) sense codes only provide information when the driver next accesses the unit or, at best, the target. Until then, the driver has no clue that the event happened. Events can be reported at the time they happen. This is important for example when the host requests a clean hot-unplug of a disk: if the disk is idle in the guest, the driver may never see the event and acknowledge the hot-unplug! right. But if you then drop this because you don't have a buffer, you get the same problem. First of all, it should be clear that while lack of buffers may happen, it is expected to be an exceptional case. If the driver keeps on not providing buffers, so goes life. PCI hot-unplug requires a cooperating operating system too, after all. So, it may happen that the driver misses an event because it doesn't provide a buffer at the right time. But if the driver works correctly, it will provide event buffers regularly to the device, and the device will tell the driver that events were dropped through the VIRTIO_SCSI_T_EVENTS_MISSED flag. The driver will then ask the SCSI subsystem to rescan the bus, and will see the unit attention condition during the rescan. I guess this answered your next questio
Re: [Qemu-devel] [RFC]QEMU disk I/O limits
On Wed, Jun 01, 2011 at 11:19:58AM +0800, Zhi Yong Wu wrote: > On Tue, May 31, 2011 at 03:55:49PM -0400, Vivek Goyal wrote: > >Date: Tue, 31 May 2011 15:55:49 -0400 > >From: Vivek Goyal > >To: Zhi Yong Wu > >Cc: kw...@redhat.com, aligu...@us.ibm.com, stefa...@linux.vnet.ibm.com, > > k...@vger.kernel.org, guijianf...@cn.fujitsu.com, > > qemu-devel@nongnu.org, wu...@cn.ibm.com, > > herb...@gondor.hengli.com.au, luow...@cn.ibm.com, zh...@cn.ibm.com, > > zhaoy...@cn.ibm.com, l...@redhat.com, rahar...@us.ibm.com > >Subject: Re: [Qemu-devel] [RFC]QEMU disk I/O limits > >User-Agent: Mutt/1.5.21 (2010-09-15) > > > >On Mon, May 30, 2011 at 01:09:23PM +0800, Zhi Yong Wu wrote: > > > >[..] > >> 3.) How the users enable and play with it > >> QEMU -drive option will be extended so that disk I/O limits can be > >> specified on its command line, such as -drive [iops=xxx,][throughput=xxx] > >> or -drive [iops_rd=xxx,][iops_wr=xxx,][throughput=xxx] etc. When this > >> argument is specified, it means that "disk I/O limits" feature is enabled > >> for this drive disk. > > > >How does throughput interface look like? is it bytes per second or something > >else? > Given your suggestion, its form will look like below: > > -drive [iops=xxx][,bps=xxx] or -drive > [iops_rd=xxx][,iops_wr=xxx][,bps_rd=xxx][,bps_wr=xxx] Can one specify both iops and bps rule for the same drive? Thanks Vivek
Re: [Qemu-devel] [PATCH uq/master V3] kvm: Add CPUID support for VIA CPU
On Wed, Jun 01, 2011 at 09:59:52AM +0800, BrillyWu wrote: > From: brill...@viatech.com.cn > > When KVM is running on VIA CPU with host cpu's model, the > feautures of VIA CPU will be passed into kvm guest by calling > the CPUID instruction for Centaur. > > Signed-off-by: BrillyWu > Signed-off-by: KaryJin > --- > target-i386/cpu.h |7 > target-i386/cpuid.c | 53 -- > target-i386/kvm.c | 15 + > 3 files changed, 73 insertions(+), 2 deletions(-) Applied to uq/master, thanks.
Re: [Qemu-devel] [RFC]QEMU disk I/O limits
On Tue, May 31, 2011 at 06:30:09PM -0500, Anthony Liguori wrote: [..] > The level of consistency will then depend on whether you overcommit > your hardware and how you have it configured. Agreed. > > Consistency is very hard because at the end of the day, you still > have shared resources. Even with blkio, I presume one guest can > still impact another guest by forcing the disk to do excessive > seeking or something of that nature. > > So absolutely consistency can't be the requirement for the use-case. > The use-cases we are interested really are more about providing caps > than anything else. I think both qemu and kenrel can do the job. The only thing which seriously favors throttling implementation in qemu is the ability to handle wide variety of backend files (NFS, qcow, libcurl based devices etc). So what I am arguing is that your previous reason that qemu can do a better job because it knows effective IOPS of guest, is not necessarily a very good reason. To me simplicity of being able to handle everything as file and do the throttling is the most compelling reason to do this implementation in qemu. Thanks Vivek
Re: [Qemu-devel] [PATCH 05/18] ide: Turn debug messages into assertions
Am 01.06.2011 15:44, schrieb Luiz Capitulino: > On Thu, 26 May 2011 18:12:08 -0300 > Luiz Capitulino wrote: > >> On Thu, 19 May 2011 14:33:19 +0200 >> Kevin Wolf wrote: >> >>> These printfs aren't really debug messages, but clearly indicate a bug if >>> they >>> ever become effective. >> >> Then we have a bug somewhere, starting a VM with: >> >> # qemu -hda disks/test.img -enable-kvm -m 1G -cdrom /dev/sr0 >> >> Where the host's CDROM is empty, triggers one of these asserts: >> >> qmp-unstable/hw/ide/pci.c:299: bmdma_cmd_writeb: Assertion >> `bm->bus->dma->aiocb == ((void *)0)' > > I found out why this is happening. I'm passing '-snapshot' to the > command-line, > sorry for not mentioning it (I forgot I was using my devel alias). And suddenly it's reproducible. :-) I'll have a look. > I also found out that /usr/bin/eject in the guest won't work when > -snapshot is used. Shouldn't qemu ignore this flag when using cdrom > passthrough? "Won't work" means that it works like with a CD-ROM image? That would be what I expect, as you end up having a qcow2 image with -snapshot. Not sure what's the best way of fixing this. Maybe just ignoring -snapshot for read-only block devices? Or we could try and forward the eject request to the backing file if the format driver doesn't handle it. Kevin
Re: [Qemu-devel] [PATCH] linux-user: Define AT_RANDOM to support target dynamic linkers that do ASLR
On 06/01/2011 04:42 AM, Cédric VINCENT wrote: > +/* The dynamic linker of the GNU C library v2.10+ uses the ELF > + * auxialiary vector AT_RANDOM as a pointer to a 16-bit random > + * value. Note the start of the text segment is not random at > + * all, however it is definitively readeable. */ > +NEW_AUX_ENT(AT_RANDOM, (abi_ulong) info->start_code); 16 bytes, not 16 bits. Typos for auxiliary and readable. r~
Re: [Qemu-devel] [RFC PATCH 01/13] Generic DMA memory access interface
On 05/31/2011 06:38 PM, Eduard - Gabriel Munteanu wrote: > +static inline void dma_memory_rw(DMADevice *dev, > + dma_addr_t addr, > + void *buf, > + dma_addr_t len, > + int is_write) I don't think this needs to be inline... > +{ > +/* > + * Fast-path non-iommu. > + * More importantly, makes it obvious what this function does. > + */ > +if (!dev || !dev->mmu) { > +cpu_physical_memory_rw(addr, buf, len, is_write); > +return; > +} ... because you'll never be able to eliminate the if or the calls. You might as well make the overall code smaller by taking the entire function out of line. > +#define DEFINE_DMA_LD(prefix, suffix, devtype, dmafield, size)\ > +static inline uint##size##_t \ > +dma_ld##suffix(DMADevice *dev, dma_addr_t addr) \ > +{ \ > +int err; \ > +dma_addr_t paddr, plen; \ > + \ > +if (!dev || !dev->mmu) { \ > +return ld##suffix##_phys(addr); \ > +} \ Similarly for all the ld/st functions. > +#define DEFINE_DMA_MEMORY_RW(prefix, devtype, dmafield) > +#define DEFINE_DMA_MEMORY_READ(prefix, devtype, dmafield) > +#define DEFINE_DMA_MEMORY_WRITE(prefix, devtype, dmafield) > + > +#define DEFINE_DMA_OPS(prefix, devtype, dmafield) \ I think this is a bit over the top, really. > +err = dev->mmu->translate(dev, addr, &paddr, &plen, is_write); I see you didn't take my suggestion for using an opaque callback pointer. Really and truly, I won't be able to use this as-is for Alpha. r~
Re: [Qemu-devel] [PATCH 05/18] ide: Turn debug messages into assertions
On Wed, 01 Jun 2011 16:02:56 +0200 Kevin Wolf wrote: > Am 01.06.2011 15:44, schrieb Luiz Capitulino: > > On Thu, 26 May 2011 18:12:08 -0300 > > Luiz Capitulino wrote: > > > >> On Thu, 19 May 2011 14:33:19 +0200 > >> Kevin Wolf wrote: > >> > >>> These printfs aren't really debug messages, but clearly indicate a bug if > >>> they > >>> ever become effective. > >> > >> Then we have a bug somewhere, starting a VM with: > >> > >> # qemu -hda disks/test.img -enable-kvm -m 1G -cdrom /dev/sr0 > >> > >> Where the host's CDROM is empty, triggers one of these asserts: > >> > >> qmp-unstable/hw/ide/pci.c:299: bmdma_cmd_writeb: Assertion > >> `bm->bus->dma->aiocb == ((void *)0)' > > > > I found out why this is happening. I'm passing '-snapshot' to the > > command-line, > > sorry for not mentioning it (I forgot I was using my devel alias). > > And suddenly it's reproducible. :-) > > I'll have a look. Thanks. > > I also found out that /usr/bin/eject in the guest won't work when > > -snapshot is used. Shouldn't qemu ignore this flag when using cdrom > > passthrough? > > "Won't work" means that it works like with a CD-ROM image? I guess so. > That would be > what I expect, as you end up having a qcow2 image with -snapshot. > > Not sure what's the best way of fixing this. Maybe just ignoring > -snapshot for read-only block devices? I think that makes sense as the reason to use -snapshot is to avoid writing to the image/device. > Or we could try and forward the > eject request to the backing file if the format driver doesn't handle it. > > Kevin >
Re: [Qemu-devel] [PATCH] linux-user: Define AT_RANDOM to support target dynamic linkers that do ASLR
On Wed, Jun 01, 2011 at 03:26:09PM +0200, Richard Henderson wrote: > > 16 bytes, not 16 bits. You're right it's not 16 bits, it's "sizeof(uintptr_t)" actually: http://repo.or.cz/w/glibc.git/blob/glibc-2.10:/sysdeps/unix/sysv/linux/dl-osinfo.h#l89 > Typos for auxiliary and readable. Thanks.
Re: [Qemu-devel] [RFC PATCH 01/13] Generic DMA memory access interface
On 06/01/2011 05:01 PM, Richard Henderson wrote: > +err = dev->mmu->translate(dev, addr,&paddr,&plen, is_write); I see you didn't take my suggestion for using an opaque callback pointer. Really and truly, I won't be able to use this as-is for Alpha. Rather than opaques, please pass the DMA engine itself and use container_of(). We should be removing opaques, not adding them. -- error compiling committee.c: too many arguments to function
Re: [Qemu-devel] virtio scsi host draft specification, v2
On Wed, Jun 01, 2011 at 03:31:42PM +0200, Paolo Bonzini wrote: > On 06/01/2011 02:51 PM, Michael S. Tsirkin wrote: > The cdb, data and sense fields must reside in separate buffers. > The cdb field is always read-only. The data buffers may be either > read-only or write-only, depending on the request, with the read-only > buffers coming first. The sense buffer is always write-only. > > The request shall have num_dataout read-only data buffers and > num_datain write-only data buffers. One of these two values must be > zero if the VIRTIO_SCSI_F_INOUT has not been negotiated. > >>> > >>>Why do num_datain/num_dataout need to be there? > >>>We can just look at the number of io/out bufs in > >>>virtio descriptors, no? > >> > >>This depends on having a single variable-sized datum per direction. > >>I'd rather avoid this assumption. > > > >I think it's a sane assumption: does scsi ever give you more? > > Sense data, and data from the device, are both variable-length. > With your suggestion that they may be in a single buffer, we do need > size information for them. > > >If you have many how do you know the size of each? > > That's up to the transport protocol to devise. > > However, I'll make a few changes: > > 1) num_dataout/num_datain will become byte counts rather than buffer > counts. This fits better if the driver has the liberty has to use > single buffers. > 2) I'll add a sense_size field to give the size of the sense buffer, > since now it won't necessarily be in a separate buffer (which gave > this knowledge to the . The sense_len will tell the driver how many > bytes were actually written (usually 0). > Remaining fields are filled in by the device. The sense_len field > indicates the number of bytes actually written to the sense buffer, > while the residual field indicates the residual size, calculated as > data_length - number_of_transferred_bytes. > >>> > >>>Again virtio gives you total number of written bytes in the used len > >>>field. So just one of these fields will be enough. > >> > >>The two fields give completely different information (sense vs. real > >>data), and the math has to be done anyway in either the driver or > >>the device. The device is going to be written just once and > >>actually it already has the separate information, so I put it in the > >>struct and spared some annoyance to driver writers. > > > >Yes but this way you get duplicate information which means > >it can get out of sync. Go figure who's right then ... > > But is it duplicate actually? The write-only buffer(s) start with > datain_size bytes of data, and sense_size bytes of sense. If > everything is placed in a single buffer, the used len field cannot > capture how many bytes were written in the data and how many were > written in the sense. In addition, if everything is placed in a > single buffer, the device will have to report that it has written > the full buffer because other parts of the response come after > datain and sense. > > So, if I am going to give this liberty with buffers to the driver, I > _have_ to keep the size information. Otherwise, I agree that it is > redundant and I will remove it. What poison do you prefer? > Ah, I think I understand now. Both sense and data have in fields that might only be used partially? In that case I think I agree: it's best to require the use of separate buffers for them, in this way used len will give you useful information and you won't need sense_len and data_len: just a flag to mark the fact that there *is* a sense buffer following. And the num field does that. virtio-net does something vaguely similar with mergeable buffers. However some questions: 1. I think you don't need numdatain/numdataout: each buffer can include in and out segments. Just tell device how many buffers are there. 2. Put first out then in for data, then out then in for sense, so that you can get away with less descriptors as all of data can be in a single indirect descriptor. 2. Is it true that device really expects optional data + optional sense? Then an explicit two bit field 'have data','have sense' might be better than 'number'. What do you think? > >>>[...] It looks like there's a finite number of possible events. > >> > >>If you keep opening and closing the tray from the guest, you could > >>fire a possibly unbounded number of events. > > > >In that case only the last one is really interesting. > > That's true. But events are rare enough that you should not have > any problems feeding enough buffers to the device, and even in that > case there is a way out in case of dropped events (see below). > Assuming I am going to implement the device, requiring the device to > queue events seems a bit masochistic. :) > > >>>If this mechanism is unreliable, how is it useful? > >> > >>Events alone are unreliable, but the combination of events+sense is > >>reliable. And event
Re: [Qemu-devel] [SeaBIOS] Graphics card pass-through working with two pass pci-initialization
Having a brief look at the coreboot code it seems static stuff (compiled by iasl) and dynamic bits are combined into the final dsdt table, is that correct? Yes the dsdt is static, it has just external references to ssdt which is dynamically generated using the acpigen. Acpigen can generate the packages, names and sometimes even bits of methods. Thanks Rudolf
Re: [Qemu-devel] [PATCH 14/14] usb: Proper error propagation for usb_device_attach errors
Hi, On 06/01/2011 02:50 PM, Gerd Hoffmann wrote: Hi, I'll wait a bit for more feedback and then change [PATCH 14/14] usb: Proper error propagation for usb_device_attach errors I'll wait for new revisions of patches 12+14 then. I already fixed this yeterday, I opted to leave patch 12 unmodified and replace all fprintf(stderr, ... calls with error_report calls in one go in a new patch 14. You can find the new version here: http://cgit.freedesktop.org/~jwrdegoede/qemu/commit/?h=usb-patches&id=3c0be7730ff74a5cdac6aa100179b15c9392ab5f Let me know if you'd rather have me resend 12 + 14 to the list. Regards, Hans
[Qemu-devel] [PATCH v2] linux-user: Define AT_RANDOM to support target dynamic linkers that do ASLR
From: Laurent ALFONSI The dynamic linker of the GNU C library v2.10+ uses the ELF auxialiary vector AT_RANDOM as a pointer to a word with random value. Prior this patch the value of AT_RANDOM was not defined by the ELF loader of QEMU so the GNU dynamic linker de-referenced the NULL pointer instead. As a consequence any target program linked to the GNU C library v2.10+ crashed due to a SEGFAULT. Note AT_RANDOM now points to the start of the text segment thus the value is not random at all, however it is definitively readable. This "dummy" behavior could be improved later. Signed-off-by: Laurent ALFONSI Signed-off-by: Cédric VINCENT --- linux-user/elfload.c |9 - 1 files changed, 8 insertions(+), 1 deletions(-) diff --git a/linux-user/elfload.c b/linux-user/elfload.c index dcfeb7a..28c 100644 --- a/linux-user/elfload.c +++ b/linux-user/elfload.c @@ -927,7 +927,7 @@ struct exec #define TARGET_ELF_PAGESTART(_v) ((_v) & ~(unsigned long)(TARGET_ELF_EXEC_PAGESIZE-1)) #define TARGET_ELF_PAGEOFFSET(_v) ((_v) & (TARGET_ELF_EXEC_PAGESIZE-1)) -#define DLINFO_ITEMS 12 +#define DLINFO_ITEMS 13 static inline void memcpy_fromfs(void * to, const void * from, unsigned long n) { @@ -1271,6 +1271,13 @@ static abi_ulong create_elf_tables(abi_ulong p, int argc, int envc, NEW_AUX_ENT(AT_EGID, (abi_ulong) getegid()); NEW_AUX_ENT(AT_HWCAP, (abi_ulong) ELF_HWCAP); NEW_AUX_ENT(AT_CLKTCK, (abi_ulong) sysconf(_SC_CLK_TCK)); + +/* The dynamic linker of the GNU C library v2.10+ uses the ELF + * auxiliary vector AT_RANDOM as a pointer to a word with random + * value. Note the start of the text segment is not random at + * all, however it is definitively readable. */ +NEW_AUX_ENT(AT_RANDOM, (abi_ulong) info->start_code); + if (k_platform) NEW_AUX_ENT(AT_PLATFORM, u_platform); #ifdef ARCH_DLINFO -- 1.7.5.1
Re: [Qemu-devel] [PATCH 07/14] usb-linux: If opening a device fails remove it from our filter list
Hi, On 06/01/2011 02:32 PM, Gerd Hoffmann wrote: On 05/31/11 11:35, Hans de Goede wrote: So that we don't retry to open it every 2 seconds flooding stderr with error messages. The polling here is done intentionally, so the devices catched by the filter show up in the guest automagically as soon as they are plugged in. Just zapping the filter on failure isn't the right thing to do here. Note I'm zapping the filter when we fail to open the device, not when it is not present. This can happen for example when the qemu user does not have rights on the usbfs device node. It seems better to me to print the relevant error once, and then require the user to redo the usb_add / device_add if necessary, then to flood the monitor with repeating the same error every 2 seconds. Note that something like a permission problem (which is the most likely case for opening a device failing once we've found it) won't go away by itself. We could try to do something more clever than polling sysfs every two seconds though, such using inotify to watch /sys/bus/usb/devices for new devices poping up. That would also result in trying to open the device ones, and if that fails give up, I don't see the difference. Actually the user experience would be worse, because the proper sequence in case of a permission problem would go from: usb_add see error fix permission usb_add to: usb_add see error fix permission usb_del usb_add Regards, Hans
Re: [Qemu-devel] [PATCH 05/14] usb-linux: Don't call usb_host_close when usb_host_open fails
Hi, On 06/01/2011 02:22 PM, Gerd Hoffmann wrote: What bug you are trying to fix here? Nothing in particular, while looking at some other stuff I noticed that we have the following sequence, which is wrong: usb_host_open called usb_host_open calls usb_host_claim_interfaces usb_host_claim_interfaces calls do_disconnect because of failure do_disconnect calls usb_host_close usb_host_close iterates over endpoints, but usb_linux_update_endp_table has not been called to initialize the endpoints at this points usb_host_close calls usb_device_detach, but not attached yet usb_host_close does an not needed ioctl(dev->fd, USBDEVFS_RESET); usb_host_closes the fd usb_host_open jumps to fail, closes the fd *again* All of this is does not lead to any real user visible bugs, but from a code flow pov it is wrong. Regards, Hans
Re: [Qemu-devel] virtio scsi host draft specification, v2
On 06/01/2011 05:36 PM, Michael S. Tsirkin wrote: > > So, if I am going to give this liberty with buffers to the driver, I > _have_ to keep the size information. Otherwise, I agree that it is > redundant and I will remove it. What poison do you prefer? > Ah, I think I understand now. Both sense and data have in fields that might only be used partially? In that case I think I agree: it's best to require the use of separate buffers for them, in this way used len will give you useful information and you won't need sense_len and data_len: just a flag to mark the fact that there *is* a sense buffer following. And the num field does that. Do you mean to use the virtio iovec length to determine information about the message (like splitting it into buffers)? I think that's a bad idea. Splitting into buffers is a function of memory management. For example, a driver in userspace (or a nested guest) will have additional fragmentation into 4K pages after it passes through the iommu. Let's not mix layers here. -- error compiling committee.c: too many arguments to function
Re: [Qemu-devel] [PATCH 09/14] usb-linux: Don't declare a usbdevice_name
Hi, On 06/01/2011 02:44 PM, Gerd Hoffmann wrote: On 05/31/11 11:35, Hans de Goede wrote: Declaring a usbdevice_name while we still have an explicit call to usb_host_device_open in vl.c causes usb_host_device_open to get called twice if the initial call fails. Wrong way around, the vl.c call should be zapped instead. Just did. Sounds good to me, but you will also need to fix usb-bsd to declare a usbdevice_name and initfn then. Regards, Hans
Re: [Qemu-devel] [RFC PATCH 01/13] Generic DMA memory access interface
On Wed, Jun 01, 2011 at 07:01:42AM -0700, Richard Henderson wrote: > On 05/31/2011 06:38 PM, Eduard - Gabriel Munteanu wrote: > > +static inline void dma_memory_rw(DMADevice *dev, > > + dma_addr_t addr, > > + void *buf, > > + dma_addr_t len, > > + int is_write) > > I don't think this needs to be inline... > > > +{ > > +/* > > + * Fast-path non-iommu. > > + * More importantly, makes it obvious what this function does. > > + */ > > +if (!dev || !dev->mmu) { > > +cpu_physical_memory_rw(addr, buf, len, is_write); > > +return; > > +} > > ... because you'll never be able to eliminate the if or the calls. > You might as well make the overall code smaller by taking the > entire function out of line. > > > +#define DEFINE_DMA_LD(prefix, suffix, devtype, dmafield, size)\ > > +static inline uint##size##_t \ > > +dma_ld##suffix(DMADevice *dev, dma_addr_t addr) \ > > +{ \ > > +int err; \ > > +dma_addr_t paddr, plen; \ > > + \ > > +if (!dev || !dev->mmu) { \ > > +return ld##suffix##_phys(addr); \ > > +} \ > > Similarly for all the ld/st functions. > The idea was to get to the fastpath as soon as possible. I'm not really concerned about the case where there's an IOMMU present, since translation/checking does a lot more work. But other people might be worried about that additional function call when there's no IOMMU. And these functions are quite small anyway. Thoughts, anybody else? > > +#define DEFINE_DMA_MEMORY_RW(prefix, devtype, dmafield) > > +#define DEFINE_DMA_MEMORY_READ(prefix, devtype, dmafield) > > +#define DEFINE_DMA_MEMORY_WRITE(prefix, devtype, dmafield) > > + > > +#define DEFINE_DMA_OPS(prefix, devtype, dmafield) \ > > I think this is a bit over the top, really. > Yeah, it's a bit unconventional, but why do you think that? The main selling point is there are more chances to screw up if every bus layer implements these manually. And it's really convenient, especially if we get to add another ld/st. I do have one concern about it, though: it might increase compile time due to additional preprocessing work. I haven't done any benchmarks on that. But apart from this, are there any other objections? > > +err = dev->mmu->translate(dev, addr, &paddr, &plen, is_write); > > I see you didn't take my suggestion for using an opaque callback pointer. > Really and truly, I won't be able to use this as-is for Alpha. > If I understand correctly you need some sort of shared state between IOMMUs or units residing on different buses. Then you should be able to get to it even with this API, just like I do with my AMD IOMMU state by upcasting. It doesn't seem to matter whether you've got an opaque, that opaque could very well be reachable by upcasting. Did I get this wrong? Eduard > > r~
Re: [Qemu-devel] virtio scsi host draft specification, v2
On 05/20/2011 11:21 AM, Paolo Bonzini wrote: Hi all, here is the second version of the spec. In the end I took the advice of merging all requestq's into one. The reason for this is that I took a look at the vSCSI device and liked its approach of using SAM 8-byte LUNs directly. While it _is_ complex (and not yet done right by QEMU---will send a patch for that), the scheme is actually quite natural to implement and use, and supporting generic bus/target/LUN topologies is good to have for passthrough, as well. I also added a few more features from SAM to avoid redefining the structs in the future. Of course it may be that I'm completely wrong. :) Please comment on the spec! Virtqueues 0:control transmitq 1:control receiveq 2:requestq Shouldn't we plan multiqueue for this from day 1? Requests have the following format: struct virtio_scsi_req_cmd { u8 lun[8]; u64 id; u8 task_attr; u8 prio; u8 crn; u32 num_dataout, num_datain; char cdb[]; char data[][num_dataout+num_datain]; u8 sense[]; u32 sense_len; u32 residual; u16 status_qualifier; u8 status; u8 response; }; flags? room for growth? -- error compiling committee.c: too many arguments to function
Re: [Qemu-devel] [RFC PATCH 01/13] Generic DMA memory access interface
On 06/01/2011 07:52 AM, Eduard - Gabriel Munteanu wrote: > The main selling point is there are more chances to screw up if every > bus layer implements these manually. And it's really convenient, > especially if we get to add another ld/st. If we drop the ld/st, we're talking about 5 lines for every bus layer. If I recall, there was just the one driver that actually uses the ld/st interface; most used the read/write interface. > If I understand correctly you need some sort of shared state between > IOMMUs or units residing on different buses. Then you should be able to > get to it even with this API, just like I do with my AMD IOMMU state by > upcasting. It doesn't seem to matter whether you've got an opaque, that > opaque could very well be reachable by upcasting. > > Did I get this wrong? Can you honestly tell me that > +static int amd_iommu_translate(DMADevice *dev, > + dma_addr_t addr, > + dma_addr_t *paddr, > + dma_addr_t *len, > + int is_write) > +{ > +PCIDevice *pci_dev = container_of(dev, PCIDevice, dma); > +PCIDevice *iommu_dev = DO_UPCAST(PCIDevice, qdev, dev->mmu->iommu); > +AMDIOMMUState *s = DO_UPCAST(AMDIOMMUState, dev, iommu_dev); THREE (3) upcasts is a sane to write maintainable software? The margin for error here is absolutely enormous. If you had just passed in that AMDIOMMUState* as the opaque value, it would be trivial to look at the initialization statement and the callback function to verify that the right value is being passed. r~
Re: [Qemu-devel] [PATCH] linux-user: Define AT_RANDOM to support target dynamic linkers that do ASLR
On 06/01/2011 06:47 AM, cedric.vinc...@st.com wrote: > On Wed, Jun 01, 2011 at 03:26:09PM +0200, Richard Henderson wrote: >> >> 16 bytes, not 16 bits. > > You're right it's not 16 bits, it's "sizeof(uintptr_t)" actually: No, it's not. unsigned char k_rand_bytes[16]; elf_addr_t __user *u_rand_bytes; ... /* * Generate 16 random bytes for userspace PRNG seeding. */ get_random_bytes(k_rand_bytes, sizeof(k_rand_bytes)); u_rand_bytes = (elf_addr_t __user *) STACK_ALLOC(p, sizeof(k_rand_bytes)); if (__copy_to_user(u_rand_bytes, k_rand_bytes, sizeof(k_rand_bytes))) return -EFAULT; ... NEW_AUX_ENT(AT_RANDOM, (elf_addr_t)(unsigned long)u_rand_bytes); Frankly, it's trivial to do this right in create_elf_tables. Grab 16 bytes at SP right at the beginning of the function, fill it with whatever random values seem good. I suggest at minimum a command-line argument to force a particular AT_RANDOM value, for repeatability. r~
[Qemu-devel] Hello Would You Like To Earn
Hello qemu-devel Would you like to earn an extra $200 everyday?, for just 45 minutes work? You could quit your job and make double the money at home working for yourself. visit->http:tinyurl.com/3brnlpx Regards, Sharon Burns Survey Human Resources Dept.
Re: [Qemu-devel] [RFC PATCH 01/13] Generic DMA memory access interface
On Wed, Jun 01, 2011 at 08:09:29AM -0700, Richard Henderson wrote: > On 06/01/2011 07:52 AM, Eduard - Gabriel Munteanu wrote: > > The main selling point is there are more chances to screw up if every > > bus layer implements these manually. And it's really convenient, > > especially if we get to add another ld/st. > > If we drop the ld/st, we're talking about 5 lines for every bus layer. > > If I recall, there was just the one driver that actually uses the ld/st > interface; most used the read/write interface. Hm, indeed there seem to be far fewer uses of those now, actually my patches don't seem to be using those. What do you guys think? Will these go away completely? > > If I understand correctly you need some sort of shared state between > > IOMMUs or units residing on different buses. Then you should be able to > > get to it even with this API, just like I do with my AMD IOMMU state by > > upcasting. It doesn't seem to matter whether you've got an opaque, that > > opaque could very well be reachable by upcasting. > > > > Did I get this wrong? > > Can you honestly tell me that > > > +static int amd_iommu_translate(DMADevice *dev, > > + dma_addr_t addr, > > + dma_addr_t *paddr, > > + dma_addr_t *len, > > + int is_write) > > +{ > > +PCIDevice *pci_dev = container_of(dev, PCIDevice, dma); > > +PCIDevice *iommu_dev = DO_UPCAST(PCIDevice, qdev, dev->mmu->iommu); > > +AMDIOMMUState *s = DO_UPCAST(AMDIOMMUState, dev, iommu_dev); > > THREE (3) upcasts is a sane to write maintainable software? > The margin for error here is absolutely enormous. > > If you had just passed in that AMDIOMMUState* as the opaque > value, it would be trivial to look at the initialization > statement and the callback function to verify that the right > value is being passed. Maybe it's not nice, but you're missing the fact upcasting gives you some type safety. With opaques you have none. Plus you also get the PCI device that made the call while you're at it. Eduard > r~
[Qemu-devel] [PATCH v1][ 03/14] Introduce the new error framework
From: Luiz Capitulino New error-handling framework that allows for exception-like error propagation. Signed-off-by: Luiz Capitulino Signed-off-by: Michael Roth --- Makefile.objs |2 +- error.c | 140 + error.h | 70 error_int.h | 29 4 files changed, 240 insertions(+), 1 deletions(-) create mode 100644 error.c create mode 100644 error.h create mode 100644 error_int.h diff --git a/Makefile.objs b/Makefile.objs index 90838f6..0f7bb52 100644 --- a/Makefile.objs +++ b/Makefile.objs @@ -59,7 +59,7 @@ fsdev-obj-$(CONFIG_VIRTFS) += $(addprefix fsdev/, $(fsdev-nested-y)) # system emulation, i.e. a single QEMU executable should support all # CPUs and machines. -common-obj-y = $(block-obj-y) blockdev.o +common-obj-y = $(block-obj-y) blockdev.o error.o common-obj-y += $(net-obj-y) common-obj-y += $(qobject-obj-y) common-obj-$(CONFIG_LINUX) += $(fsdev-obj-$(CONFIG_LINUX)) diff --git a/error.c b/error.c new file mode 100644 index 000..867eec2 --- /dev/null +++ b/error.c @@ -0,0 +1,140 @@ +/* + * QEMU Error Objects + * + * Copyright IBM, Corp. 2011 + * + * Authors: + * Anthony Liguori + * + * This work is licensed under the terms of the GNU LGPL, version 2. See + * the COPYING.LIB file in the top-level directory. + */ +#include "error.h" +#include "error_int.h" +#include "qemu-objects.h" +#include "qerror.h" +#include + +struct Error +{ +QDict *obj; +const char *fmt; +char *msg; +}; + +void error_set(Error **errp, const char *fmt, ...) +{ +Error *err; +va_list ap; + +if (errp == NULL) { +return; +} + +err = qemu_mallocz(sizeof(*err)); + +va_start(ap, fmt); +err->obj = qobject_to_qdict(qobject_from_jsonv(fmt, &ap)); +va_end(ap); +err->fmt = fmt; + +*errp = err; +} + +bool error_is_set(Error **errp) +{ +return (errp && *errp); +} + +const char *error_get_pretty(Error *err) +{ +if (err->msg == NULL) { +QString *str; +str = qerror_format(err->fmt, err->obj); +err->msg = qemu_strdup(qstring_get_str(str)); +QDECREF(str); +} + +return err->msg; +} + +const char *error_get_field(Error *err, const char *field) +{ +if (strcmp(field, "class") == 0) { +return qdict_get_str(err->obj, field); +} else { +QDict *dict = qdict_get_qdict(err->obj, "data"); +return qdict_get_str(dict, field); +} +} + +QDict *error_get_data(Error *err) +{ +QDict *data = qdict_get_qdict(err->obj, "data"); +QINCREF(data); +return data; +} + +void error_set_field(Error *err, const char *field, const char *value) +{ +QDict *dict = qdict_get_qdict(err->obj, "data"); +return qdict_put(dict, field, qstring_from_str(value)); +} + +void error_free(Error *err) +{ +if (err) { +QDECREF(err->obj); +qemu_free(err->msg); +qemu_free(err); +} +} + +bool error_is_type(Error *err, const char *fmt) +{ +const char *error_class; +char *ptr; +char *end; + +ptr = strstr(fmt, "'class': '"); +assert(ptr != NULL); +ptr += strlen("'class': '"); + +end = strchr(ptr, '\''); +assert(end != NULL); + +error_class = error_get_field(err, "class"); +if (strlen(error_class) != end - ptr) { +return false; +} + +return strncmp(ptr, error_class, end - ptr) == 0; +} + +void error_propagate(Error **dst_err, Error *local_err) +{ +if (dst_err) { +*dst_err = local_err; +} else if (local_err) { +error_free(local_err); +} +} + +QObject *error_get_qobject(Error *err) +{ +QINCREF(err->obj); +return QOBJECT(err->obj); +} + +void error_set_qobject(Error **errp, QObject *obj) +{ +Error *err; +if (errp == NULL) { +return; +} +err = qemu_mallocz(sizeof(*err)); +err->obj = qobject_to_qdict(obj); +qobject_incref(obj); + +*errp = err; +} diff --git a/error.h b/error.h new file mode 100644 index 000..003c855 --- /dev/null +++ b/error.h @@ -0,0 +1,70 @@ +/* + * QEMU Error Objects + * + * Copyright IBM, Corp. 2011 + * + * Authors: + * Anthony Liguori + * + * This work is licensed under the terms of the GNU LGPL, version 2. See + * the COPYING.LIB file in the top-level directory. + */ +#ifndef ERROR_H +#define ERROR_H + +#include + +/** + * A class representing internal errors within QEMU. An error has a string + * typename and optionally a set of named string parameters. + */ +typedef struct Error Error; + +/** + * Set an indirect pointer to an error given a printf-style format parameter. + * Currently, qerror.h defines these error formats. This function is not + * meant to be used outside of QEMU. + */ +void error_set(Error **err, const char *fmt, ...) +__attribute__((format(printf, 2, 3))); + +/** + * Returns true if an indirect pointer to an error is pointing to a valid + * error object. + */ +bool error_is_set(Error **err); + +/** +
[Qemu-devel] [QAPI+QGA 2/3] QAPI code generation infrastructure
This is Set 2/3 of the QAPI+QGA patchsets. These patches apply on top of qapi-backport-set1-v1, and can also be obtained from: git://repo.or.cz/qemu/mdroth.git qapi-backport-set2-v1 (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 Visiter/dispatch infrastructure to handle marshaling/unmarshaling/dispatch between QAPI and the QMP/QGA wire protocols. - Documentation and unit tests for visiter functions and synchronous command/type generation. 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| 21 ++ Makefile.objs |9 + Makefile.target |1 + configure | 13 ++ docs/qapi-code-gen.txt | 315 + module.h|2 + qapi-schema-test.json | 16 ++ qapi/qapi-dealloc-visiter.c | 127 qapi/qapi-dealloc-visiter.h | 26 +++ qapi/qapi-types-core.h | 21 ++ qapi/qapi-visit-core.h | 187 + qapi/qmp-core.h | 43 qapi/qmp-dispatch.c | 73 +++ qapi/qmp-input-visiter.c| 239 ++ qapi/qmp-input-visiter.h| 26 +++ qapi/qmp-output-visiter.c | 180 + qapi/qmp-output-visiter.h | 27 +++ qapi/qmp-registry.c | 27 +++ qlist.h | 11 + scripts/ordereddict.py | 128 scripts/qapi-commands.py| 464 +++ scripts/qapi-types.py | 217 scripts/qapi-visit.py | 219 scripts/qapi.py | 181 + test-qmp-commands.c | 113 +++ test-visiter.c | 214 26 files changed, 2900 insertions(+), 0 deletions(-)
[Qemu-devel] [PATCH v1][ 05/21] qapi: add qapi-types.py code generator
This is the code generator for qapi types. It will generation the following files: $(prefix)qapi-types.h - C types corresponding to types defined in the schema you pass in $(prefix)qapi-types.c - Cleanup functions for the above C types The $(prefix) is used to as a namespace to keep the generated code from one schema/code-generation separated from others so code and be generated from multiple schemas with clobbering previously created code. Signed-off-by: Michael Roth --- scripts/qapi-types.py | 217 + 1 files changed, 217 insertions(+), 0 deletions(-) create mode 100644 scripts/qapi-types.py diff --git a/scripts/qapi-types.py b/scripts/qapi-types.py new file mode 100644 index 000..617166a --- /dev/null +++ b/scripts/qapi-types.py @@ -0,0 +1,217 @@ +from ordereddict import OrderedDict +from qapi import * +import sys +import getopt + +def generate_fwd_struct(name, members): +return mcgen(''' +typedef struct %(name)s %(name)s; + +typedef struct %(name)sList +{ +%(name)s *value; +struct %(name)sList *next; +} %(name)sList; +''', + name=name) + +def generate_struct(structname, fieldname, members): +ret = mcgen(''' +struct %(name)s +{ +''', + name=structname) + +for argname, argentry, optional, structured in parse_args(members): +if optional: +ret += mcgen(''' +bool has_%(c_name)s; +''', + c_name=c_var(argname)) +if structured: +push_indent() +ret += generate_struct("", argname, argentry) +pop_indent() +else: +ret += mcgen(''' +%(c_type)s %(c_name)s; +''', + c_type=c_type(argentry), c_name=c_var(argname)) + +if len(fieldname): +fieldname = " " + fieldname +ret += mcgen(''' +}%(field)s; +''', +field=fieldname) + +return ret + +def generate_handle(name, typeinfo): +return mcgen(''' +typedef struct %(name)s +{ +%(c_type)s handle; +} %(name)s; + +typedef struct %(name)sList +{ +%(name)s *value; +struct %(name)sList *next; +} %(name)sList; +''', + name=name, c_type=c_type(typeinfo)) + +def generate_enum(name, values): +ret = mcgen(''' +typedef enum %(name)s +{ +''', +name=name) + +i = 1 +for value in values: +ret += mcgen(''' +%(abbrev)s_%(value)s = %(i)d, +''', + abbrev=de_camel_case(name).upper(), + value=c_var(value).upper(), + i=i) +i += 1 + +ret += mcgen(''' +} %(name)s; +''', + name=name) + +return ret + +def generate_union(name, typeinfo): +ret = mcgen(''' +struct %(name)s +{ +%(name)sKind kind; +union { +''', +name=name) + +for key in typeinfo: +ret += mcgen(''' +%(c_type)s %(c_name)s; +''', + c_type=c_type(typeinfo[key]), + c_name=c_var(key)) + +ret += mcgen(''' +}; +}; +''') + +return ret + +def generate_type_cleanup_decl(name): +ret = mcgen(''' +void qapi_free_%(type)s(%(c_type)s obj); +''', +c_type=c_type(name),type=name) +return ret + +def generate_type_cleanup(name): +ret = mcgen(''' +void qapi_free_%(type)s(%(c_type)s obj) +{ +QapiDeallocVisiter *md; +Visiter *v; + +if (!obj) { +return; +} + +md = qapi_dealloc_visiter_new(); +v = qapi_dealloc_get_visiter(md); +visit_type_%(type)s(v, &obj, NULL, NULL); +qapi_dealloc_visiter_cleanup(md); +} +''', +c_type=c_type(name),type=name) +return ret + + +try: +opts, args = getopt.gnu_getopt(sys.argv[1:], "p:o:", ["prefix=", "output-dir="]) +except getopt.GetoptError, err: +print str(err) +sys.exit(1) + +output_dir = "" +prefix = "" +c_file = 'qapi-types.c' +h_file = 'qapi-types.h' + +for o, a in opts: +if o in ("-p", "--prefix"): +prefix = a +elif o in ("-o", "--output-dir"): +output_dir = a + "/" + +c_file = output_dir + prefix + c_file +h_file = output_dir + prefix + h_file + +fdef = open(c_file, 'w') +fdecl = open(h_file, 'w') + +fdef.write(mcgen(''' +/* AUTOMATICALLY GENERATED, DO NOT MODIFY */ + +#include "qapi/qapi-dealloc-visiter.h" +#include "%(prefix)sqapi-types.h" +#include "%(prefix)sqapi-visit.h" + +''', prefix=prefix)) + +fdecl.write(mcgen(''' +/* AUTOMATICALLY GENERATED, DO NOT MODIFY */ +#ifndef %(guard)s +#define %(guard)s + +#include "qapi/qapi-types-core.h" +''', + guard=guardname(h_file))) + +exprs = parse_schema(sys.stdin) + +for expr in exprs: +ret = "\n" +if expr.has_key('type'): +ret += generate_fwd_struct(expr['type'], expr['data']) +elif expr.has_key('enum'): +add_enum(expr['enum']) +ret += generate_enum(expr['enum'], expr['data']) +elif expr.has_key('union'): +add_enum('%sKind' % exp
[Qemu-devel] [PATCH v1][ 06/21] qapi: add qapi-visit.py code generator
This is the code generator for qapi visiter functions used to marshal/unmarshal/dealloc qapi types. It generates the following 2 files: $(prefix)qapi-visit.c: visiter function for a particular c type, used to automagically convert qobjects into the corresponding C type and vice-versa, and well as for deallocation memory for an existing C type $(prefix)qapi-visit.h: declarations for previously mentioned visiter functions $(prefix) is used as decribed for qapi-types.py Signed-off-by: Michael Roth --- scripts/qapi-visit.py | 219 + 1 files changed, 219 insertions(+), 0 deletions(-) create mode 100644 scripts/qapi-visit.py diff --git a/scripts/qapi-visit.py b/scripts/qapi-visit.py new file mode 100644 index 000..defb9bf --- /dev/null +++ b/scripts/qapi-visit.py @@ -0,0 +1,219 @@ +from ordereddict import OrderedDict +from qapi import * +import sys +import getopt + +def generate_visit_struct_body(field_prefix, members): +ret = "" +if len(field_prefix): +field_prefix = field_prefix + "." +for argname, argentry, optional, structured in parse_args(members): +if optional: +ret += mcgen(''' +visit_start_optional(m, (obj && *obj) ? &(*obj)->%(c_prefix)shas_%(c_name)s : NULL, "%(name)s", errp); +if ((*obj)->%(prefix)shas_%(c_name)s) { +''', + c_prefix=c_var(field_prefix), prefix=field_prefix, + c_name=c_var(argname), name=argname) +push_indent() + +if structured: +ret += mcgen(''' +visit_start_struct(m, NULL, "", "%(name)s", errp); +''', + name=argname) +ret += generate_visit_struct_body(field_prefix + argname, argentry) +ret += mcgen(''' +visit_end_struct(m, errp); +''') +else: +ret += mcgen(''' +visit_type_%(type)s(m, (obj && *obj) ? &(*obj)->%(c_prefix)s%(c_name)s : NULL, "%(name)s", errp); +''', + c_prefix=c_var(field_prefix), prefix=field_prefix, + type=type_name(argentry), c_name=c_var(argname), + name=argname) + +if optional: +pop_indent() +ret += mcgen(''' +} +visit_end_optional(m, errp); +''') +return ret + +def generate_visit_struct(name, members): +ret = mcgen(''' + +void visit_type_%(name)s(Visiter *m, %(name)s ** obj, const char *name, Error **errp) +{ +visit_start_struct(m, (void **)obj, "%(name)s", name, errp); +''', +name=name) +push_indent() +ret += generate_visit_struct_body("", members) +pop_indent() + +ret += mcgen(''' +visit_end_struct(m, errp); +} +''') +return ret + +def generate_visit_list(name, members): +return mcgen(''' + +void visit_type_%(name)sList(Visiter *m, %(name)sList ** obj, const char *name, Error **errp) +{ +GenericList *i; + +visit_start_list(m, name, errp); + +for (i = visit_next_list(m, (GenericList **)obj, errp); i; i = visit_next_list(m, &i, errp)) { +%(name)sList *native_i = (%(name)sList *)i; +visit_type_%(name)s(m, &native_i->value, NULL, errp); +} + +visit_end_list(m, errp); +} +''', +name=name) + +def generate_visit_handle(name, typeinfo): +return mcgen(''' + +void visit_type_%(name)s(Visiter *m, %(name)s ** obj, const char *name, Error **errp) +{ +visit_start_handle(m, (void **)obj, "%(name)s", name, errp); +visit_type_%(type_name)s(m, &(*obj)->handle, "handle", errp); +visit_end_handle(m, errp); +} +''', +name=name, type_name=type_name(typeinfo)) + +def generate_visit_enum(name, members): +return mcgen(''' + +void visit_type_%(name)s(Visiter *m, %(name)s * obj, const char *name, Error **errp) +{ +visit_type_enum(m, (int *)obj, "%(name)s", name, errp); +} +''', + name=name) + +def generate_visit_union(name, members): +ret = generate_visit_enum('%sKind' % name, members.keys()) + +ret += mcgen(''' + +void visit_type_%(name)s(Visiter *m, %(name)s ** obj, const char *name, Error **errp) +{ +} +''', + name=name) + +return ret + +def generate_declaration(name, members, genlist=True): +ret = mcgen(''' + +void visit_type_%(name)s(Visiter *m, %(name)s ** obj, const char *name, Error **errp); +''', +name=name) + +if genlist: +ret += mcgen(''' +void visit_type_%(name)sList(Visiter *m, %(name)sList ** obj, const char *name, Error **errp); +''', + name=name) + +return ret + +def generate_decl_enum(name, members, genlist=True): +return mcgen(''' + +void visit_type_%(name)s(Visiter *m, %(name)s * obj, const char *name, Error **errp); +''', +name=name) + +try: +opts, args = getopt.gnu_getopt(sys.argv[1:], "p:o:", ["prefix=", "output-dir="]
[Qemu-devel] [PATCH v1][ 15/21] qapi: add base declaration/types for QMP
Signed-off-by: Michael Roth --- qapi/qmp-core.h | 43 +++ 1 files changed, 43 insertions(+), 0 deletions(-) create mode 100644 qapi/qmp-core.h diff --git a/qapi/qmp-core.h b/qapi/qmp-core.h new file mode 100644 index 000..34b2e6a --- /dev/null +++ b/qapi/qmp-core.h @@ -0,0 +1,43 @@ +/* + * Core Definitions for QAPI/QMP Dispatch + * + * Copyright IBM, Corp. 2011 + * + * Authors: + * Anthony Liguori + * + * 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 QMP_CORE_H +#define QMP_CORE_H + +#include "monitor.h" +#include "error_int.h" +#include "qapi/qapi-types-core.h" + +typedef void (QmpCommandFunc)(QDict *, QObject **, Error **); + +typedef enum QmpCommandType +{ +QCT_NORMAL, +} QmpCommandType; + +typedef struct QmpCommand +{ +const char *name; +QmpCommandType type; +QmpCommandFunc *fn; +QTAILQ_ENTRY(QmpCommand) node; +} QmpCommand; + +void qmp_register_command(const char *name, QmpCommandFunc *fn); +QmpCommand *qmp_find_command(const char *name); + +QObject *qmp_dispatch(QObject *request); +void qmp_proxy_dispatch(const char *name, QDict *args, Error **errp); + +#endif + -- 1.7.0.4
Re: [Qemu-devel] [RFC PATCH 00/13] AMD IOMMU emulation patches, another try
On 05/31/2011 06:38 PM, Eduard - Gabriel Munteanu wrote: > Hi, > > Again, sorry for taking so long, but I just don't send stuff without looking > through it. This is meant to go into Michael's PCI branch, if it does. > > Some of the changes include: > - some fixes (one thanks to David Gibson) and cleanups > - macro magic for exporting clones of the DMA interface (e.g. > pci_memory_read()); I hope it isn't too much a stretch > - we use pci_memory_*() in most places where PCI devices are involved now > - luckily we don't need unaligned accesses anymore > - some attempt at signaling target aborts, but it doesn't seem like that > stuff is completely implemented in the PCI layer / devices > - PCI ids are defined in hw/amd_iommu.c until they get merged into Linux > > Also, I can't answer every request that the API is extended for doing this and > that more comfortably. I understand there may be corner cases, but may I > suggest merging it (maybe into a separate branch related to mst's pci) so that > everybody can deal with it? This is still labeled RFC, but if you think it's > ready it can be merged. > > I hope most of the important issues have been dealt with. I'll post the > SeaBIOS > patches soon (though I think you can give it a spin with the old ones, if you > need). I'll also take care of submitting PCI ids to be merged into Linux. > > In any case, let me know what you think. I hope I didn't forget to Cc someone. In order to move the discussion along productively, please have a look at git://repo.or.cz/qemu/rth.git axp-iommu-1 which is based on your previous patch set. There's stuff in there that's not 100% relevant to the discussion, but these two commits: 0652a74 target-alpha: Implement iommu translation for Typhoon. db50b11 DMA: Use an void* opaque value, rather than upcasting from qdev. are exactly what I'm interested in discussing. r~
[Qemu-devel] [PATCH v3][ 4/7] guest agent: add error class for QERR_QGA_LOGGING_FAILED
Signed-off-by: Michael Roth --- qerror.c |4 qerror.h |3 +++ 2 files changed, 7 insertions(+), 0 deletions(-) diff --git a/qerror.c b/qerror.c index c18641f..059981b 100644 --- a/qerror.c +++ b/qerror.c @@ -209,6 +209,10 @@ static const QErrorStringTable qerror_table[] = { .error_fmt = QERR_VNC_SERVER_FAILED, .desc = "Could not start VNC server on %(target)", }, +{ +.error_fmt = QERR_QGA_LOGGING_FAILED, +.desc = "failed to write log statement due to logging being disabled", +}, {} }; diff --git a/qerror.h b/qerror.h index 8b971fd..22e1b09 100644 --- a/qerror.h +++ b/qerror.h @@ -178,4 +178,7 @@ QError *qobject_to_qerror(const QObject *obj); #define QERR_FEATURE_DISABLED \ "{ 'class': 'FeatureDisabled', 'data': { 'name': %s } }" +#define QERR_QGA_LOGGING_FAILED \ +"{ 'class': 'QgaLoggingFailed', 'data': {} }" + #endif /* QERROR_H */ -- 1.7.0.4
[Qemu-devel] [PATCH v1][ 09/14] json-parser: detect premature EOI
From: Anthony Liguori Signed-off-by: Michael Roth --- json-parser.c | 58 - 1 files changed, 57 insertions(+), 1 deletions(-) diff --git a/json-parser.c b/json-parser.c index ac4063a..58e973b 100644 --- a/json-parser.c +++ b/json-parser.c @@ -275,10 +275,15 @@ out: */ static int parse_pair(JSONParserContext *ctxt, QDict *dict, QList **tokens, va_list *ap) { -QObject *key, *token = NULL, *value, *peek; +QObject *key = NULL, *token = NULL, *value, *peek; QList *working = qlist_copy(*tokens); peek = qlist_peek(working); +if (peek == NULL) { +parse_error(ctxt, NULL, "premature EOI"); +goto out; +} + key = parse_value(ctxt, &working, ap); if (!key || qobject_type(key) != QTYPE_QSTRING) { parse_error(ctxt, peek, "key is not a string in object"); @@ -286,6 +291,11 @@ static int parse_pair(JSONParserContext *ctxt, QDict *dict, QList **tokens, va_l } token = qlist_pop(working); +if (token == NULL) { +parse_error(ctxt, NULL, "premature EOI"); +goto out; +} + if (!token_is_operator(token, ':')) { parse_error(ctxt, token, "missing : in object pair"); goto out; @@ -321,6 +331,10 @@ static QObject *parse_object(JSONParserContext *ctxt, QList **tokens, va_list *a QList *working = qlist_copy(*tokens); token = qlist_pop(working); +if (token == NULL) { +goto out; +} + if (!token_is_operator(token, '{')) { goto out; } @@ -330,12 +344,22 @@ static QObject *parse_object(JSONParserContext *ctxt, QList **tokens, va_list *a dict = qdict_new(); peek = qlist_peek(working); +if (peek == NULL) { +parse_error(ctxt, NULL, "premature EOI"); +goto out; +} + if (!token_is_operator(peek, '}')) { if (parse_pair(ctxt, dict, &working, ap) == -1) { goto out; } token = qlist_pop(working); +if (token == NULL) { +parse_error(ctxt, NULL, "premature EOI"); +goto out; +} + while (!token_is_operator(token, '}')) { if (!token_is_operator(token, ',')) { parse_error(ctxt, token, "expected separator in dict"); @@ -349,6 +373,10 @@ static QObject *parse_object(JSONParserContext *ctxt, QList **tokens, va_list *a } token = qlist_pop(working); +if (token == NULL) { +parse_error(ctxt, NULL, "premature EOI"); +goto out; +} } qobject_decref(token); token = NULL; @@ -377,6 +405,10 @@ static QObject *parse_array(JSONParserContext *ctxt, QList **tokens, va_list *ap QList *working = qlist_copy(*tokens); token = qlist_pop(working); +if (token == NULL) { +goto out; +} + if (!token_is_operator(token, '[')) { goto out; } @@ -386,6 +418,11 @@ static QObject *parse_array(JSONParserContext *ctxt, QList **tokens, va_list *ap list = qlist_new(); peek = qlist_peek(working); +if (peek == NULL) { +parse_error(ctxt, NULL, "premature EOI"); +goto out; +} + if (!token_is_operator(peek, ']')) { QObject *obj; @@ -398,6 +435,11 @@ static QObject *parse_array(JSONParserContext *ctxt, QList **tokens, va_list *ap qlist_append_obj(list, obj); token = qlist_pop(working); +if (token == NULL) { +parse_error(ctxt, NULL, "premature EOI"); +goto out; +} + while (!token_is_operator(token, ']')) { if (!token_is_operator(token, ',')) { parse_error(ctxt, token, "expected separator in list"); @@ -416,6 +458,10 @@ static QObject *parse_array(JSONParserContext *ctxt, QList **tokens, va_list *ap qlist_append_obj(list, obj); token = qlist_pop(working); +if (token == NULL) { +parse_error(ctxt, NULL, "premature EOI"); +goto out; +} } qobject_decref(token); @@ -444,6 +490,9 @@ static QObject *parse_keyword(JSONParserContext *ctxt, QList **tokens) QList *working = qlist_copy(*tokens); token = qlist_pop(working); +if (token == NULL) { +goto out; +} if (token_get_type(token) != JSON_KEYWORD) { goto out; @@ -481,6 +530,9 @@ static QObject *parse_escape(JSONParserContext *ctxt, QList **tokens, va_list *a } token = qlist_pop(working); +if (token == NULL) { +goto out; +} if (token_is_escape(token, "%p")) { obj = va_arg(*ap, QObject *); @@ -520,6 +572,10 @@ static QObject *parse_literal(JSONParserContext *ctxt, QList **tokens) QList *working = qlist_copy(*tokens); token = qlist_pop(working); +if (token == NULL) { +goto out; +} + switch (token_get_type(token)) { case JSON_STRING:
[Qemu-devel] [PATCH v1][ 16/21] qapi: test schema used for unit tests
This is how QMP commands/parameters/types would be defined. We use a subset of that functionality here to implement functions/types for unit testing. Signed-off-by: Michael Roth --- qapi-schema-test.json | 16 1 files changed, 16 insertions(+), 0 deletions(-) create mode 100644 qapi-schema-test.json diff --git a/qapi-schema-test.json b/qapi-schema-test.json new file mode 100644 index 000..3c8d56b --- /dev/null +++ b/qapi-schema-test.json @@ -0,0 +1,16 @@ +# *-*- Mode: Python -*-* + +# for testing nested structs +{ 'type': 'UserDefOne', + 'data': { 'integer': 'int', 'string': 'str' } } + +{ 'type': 'UserDefTwo', + 'data': { 'string': 'str', +'dict': { 'string': 'str', + 'dict': { 'userdef': 'UserDefOne', 'string': 'str' }, + '*dict2': { 'userdef': 'UserDefOne', 'string': 'str' } } } } + +# testing commands +{ 'command': 'user_def_cmd', 'data': {} } +{ 'command': 'user_def_cmd1', 'data': {'ud1a': 'UserDefOne'} } +{ 'command': 'user_def_cmd2', 'data': {'ud1a': 'UserDefOne', 'ud1b': 'UserDefOne'}, 'returns': 'UserDefTwo' } -- 1.7.0.4
[Qemu-devel] [PATCH v1][ 17/21] qapi: add test-visiter, tests for gen. visiter code
Signed-off-by: Michael Roth --- test-visiter.c | 214 1 files changed, 214 insertions(+), 0 deletions(-) create mode 100644 test-visiter.c diff --git a/test-visiter.c b/test-visiter.c new file mode 100644 index 000..31596a0 --- /dev/null +++ b/test-visiter.c @@ -0,0 +1,214 @@ +#include +#include "qapi/qmp-output-visiter.h" +#include "qapi/qmp-input-visiter.h" +#include "test-qapi-types.h" +#include "test-qapi-visit.h" +#include "qemu-objects.h" + +typedef struct TestStruct +{ +int64_t x; +int64_t y; +} TestStruct; + +typedef struct TestStructList +{ +TestStruct *value; +struct TestStructList *next; +} TestStructList; + +static void visit_type_TestStruct(Visiter *v, TestStruct **obj, const char *name, Error **errp) +{ +visit_start_struct(v, (void **)obj, "TestStruct", name, errp); +visit_type_int(v, &(*obj)->x, "x", errp); +visit_type_int(v, &(*obj)->y, "y", errp); +visit_end_struct(v, errp); +} + +static void visit_type_TestStructList(Visiter *m, TestStructList ** obj, const char *name, Error **errp) +{ +GenericList *i; + +visit_start_list(m, name, errp); + +for (i = visit_next_list(m, (GenericList **)obj, errp); i; i = visit_next_list(m, &i, errp)) { +TestStructList *native_i = (TestStructList *)i; +visit_type_TestStruct(m, &native_i->value, NULL, errp); +} + +visit_end_list(m, errp); +} + +/* test deep nesting with refs to other user-defined types */ +static void test_nested_structs(void) +{ +QmpOutputVisiter *mo; +QmpInputVisiter *mi; +Visiter *v; +UserDefOne ud1; +UserDefOne *ud1_p = &ud1, *ud1c_p = NULL; +UserDefTwo ud2; +UserDefTwo *ud2_p = &ud2, *ud2c_p = NULL; +Error *err = NULL; +QObject *obj; +QString *str; + +ud1.integer = 42; +ud1.string = strdup("fourty two"); + +/* sanity check */ +mo = qmp_output_visiter_new(); +v = qmp_output_get_visiter(mo); +visit_type_UserDefOne(v, &ud1_p, "o_O", &err); +if (err) { +g_error("%s", error_get_pretty(err)); +} +obj = qmp_output_get_qobject(mo); +g_assert(obj); +qobject_decref(obj); + +ud2.string = strdup("fourty three"); +ud2.dict.string = strdup("fourty four"); +ud2.dict.dict.userdef = ud1_p; +ud2.dict.dict.string = strdup("fourty five"); +ud2.dict.has_dict2 = true; +ud2.dict.dict2.userdef = ud1_p; +ud2.dict.dict2.string = strdup("fourty six"); + +/* c type -> qobject */ +mo = qmp_output_visiter_new(); +v = qmp_output_get_visiter(mo); +visit_type_UserDefTwo(v, &ud2_p, "unused", &err); +if (err) { +g_error("%s", error_get_pretty(err)); +} +obj = qmp_output_get_qobject(mo); +g_assert(obj); +str = qobject_to_json_pretty(obj); +g_print("%s\n", qstring_get_str(str)); +QDECREF(str); + +/* qobject -> c type, should match original struct */ +mi = qmp_input_visiter_new(obj); +v = qmp_input_get_visiter(mi); +visit_type_UserDefTwo(v, &ud2c_p, NULL, &err); +if (err) { +g_error("%s", error_get_pretty(err)); +} + +g_assert(!g_strcmp0(ud2c_p->string, ud2.string)); +g_assert(!g_strcmp0(ud2c_p->dict.string, ud2.dict.string)); + +ud1c_p = ud2c_p->dict.dict.userdef; +g_assert(ud1c_p->integer == ud1_p->integer); +g_assert(!g_strcmp0(ud1c_p->string, ud1_p->string)); + +g_assert(!g_strcmp0(ud2c_p->dict.dict.string, ud2.dict.dict.string)); + +ud1c_p = ud2c_p->dict.dict2.userdef; +g_assert(ud1c_p->integer == ud1_p->integer); +g_assert(!g_strcmp0(ud1c_p->string, ud1_p->string)); + +g_assert(!g_strcmp0(ud2c_p->dict.dict2.string, ud2.dict.dict2.string)); +qemu_free(ud1.string); +qemu_free(ud2.string); +qemu_free(ud2.dict.string); +qemu_free(ud2.dict.dict.string); +qemu_free(ud2.dict.dict2.string); + +qapi_free_UserDefTwo(ud2c_p); + +qobject_decref(obj); +} + +int main(int argc, char **argv) +{ +QmpOutputVisiter *mo; +QmpInputVisiter *mi; +Visiter *v; +TestStruct ts = { 42, 82 }; +TestStruct *pts = &ts; +TestStructList *lts = NULL; +Error *err = NULL; +QObject *obj; +QString *str; + +g_test_init(&argc, &argv, NULL); + +mo = qmp_output_visiter_new(); +v = qmp_output_get_visiter(mo); + +visit_type_TestStruct(v, &pts, NULL, &err); + +obj = qmp_output_get_qobject(mo); + +str = qobject_to_json(obj); + +printf("%s\n", qstring_get_str(str)); + +QDECREF(str); + +obj = QOBJECT(qint_from_int(0x42)); + +mi = qmp_input_visiter_new(obj); +v = qmp_input_get_visiter(mi); + +int64_t value = 0; + +visit_type_int(v, &value, NULL, &err); +if (err) { +printf("%s\n", error_get_pretty(err)); +return 1; +} + +g_assert(value == 0x42); + +qobject_decref(obj); + +obj = qobject_from_json("{'x': 42, 'y': 84}"); +mi = qmp_input_visiter_new(obj); +v = qmp_input_get_visiter(mi);
[Qemu-devel] [QAPI+QGA 1/3] Error propagation and JSON parser fix-ups
This is Set 1/3 of the QAPI+QGA patchsets. These patches apply on top of master (5-31), and can also be obtained from: git://repo.or.cz/qemu/mdroth.git qapi-backport-set1-v1 (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: - a new error-handling framework with support for exception-like error propagation. This error-handling will be used by QAPI and the guest agent, initially, and other users will be converted over time. - various hardening of QEMU's json parsing routines, mainly: limits on max token size and token count, immediately propagating lexer errors to the parser (inducing a NULL qobject to be output) to avoid churning on tokens after a lexer error, stricter handling of invalid UTF-8 characters, and some minor bug fixes. CHANGES SINCE V0 ("QAPI Infrastructure Round 1"): - Rebased on Luiz's backport of the error-handling patches - Added JSON-related patches Makefile|4 +- Makefile.objs |2 +- error.c | 140 +++ error.h | 70 +++ error_int.h | 29 +++ json-lexer.c| 47 --- json-lexer.h|1 + json-parser.c | 83 ++-- json-parser.h |2 + json-streamer.c | 42 +++-- json-streamer.h |1 + qerror.c| 59 --- qerror.h|4 ++ 13 files changed, 446 insertions(+), 38 deletions(-)
[Qemu-devel] [PATCH v1][ 18/21] qapi: Makefile changes to build test-visiter
Signed-off-by: Michael Roth --- Makefile | 13 + Makefile.objs |7 +++ 2 files changed, 20 insertions(+), 0 deletions(-) diff --git a/Makefile b/Makefile index cf318c8..6636d2a 100644 --- a/Makefile +++ b/Makefile @@ -145,6 +145,19 @@ check-qlist: check-qlist.o qlist.o qint.o $(CHECK_PROG_DEPS) check-qfloat: check-qfloat.o qfloat.o $(CHECK_PROG_DEPS) check-qjson: check-qjson.o qfloat.o qint.o qdict.o qstring.o qlist.o qbool.o qjson.o json-streamer.o json-lexer.o json-parser.o error.o qerror.o qemu-error.o $(CHECK_PROG_DEPS) +qapi-dir := qapi-generated +$(qapi-obj-y) test-visiter.o: QEMU_CFLAGS += -I $(qapi-dir) + +$(qapi-dir)/test-qapi-types.c: $(qapi-dir)/test-qapi-types.h +$(qapi-dir)/test-qapi-types.h: $(SRC_PATH)/qapi-schema-test.json $(SRC_PATH)/scripts/qapi-types.py + $(call quiet-command,python $(SRC_PATH)/scripts/qapi-types.py -o "$(qapi-dir)" -p "test-" < $<, " GEN $@") +$(qapi-dir)/test-qapi-visit.c: $(qapi-dir)/test-qapi-visit.h +$(qapi-dir)/test-qapi-visit.h: $(SRC_PATH)/qapi-schema-test.json $(SRC_PATH)/scripts/qapi-visit.py + $(call quiet-command,python $(SRC_PATH)/scripts/qapi-visit.py -o "$(qapi-dir)" -p "test-" < $<, " GEN $@") + +test-visiter.o: $(addprefix $(qapi-dir)/, test-qapi-types.c test-qapi-types.h test-qapi-visit.c test-qapi-visit.h) +test-visiter: test-visiter.o qfloat.o qint.o qdict.o qstring.o qlist.o qbool.o $(qapi-obj-y) error.o osdep.o qemu-malloc.o $(oslib-obj-y) qjson.o json-streamer.o json-lexer.o json-parser.o qerror.o qemu-error.o qemu-tool.o $(qapi-dir)/test-qapi-visit.o $(qapi-dir)/test-qapi-types.o + QEMULIBS=libhw32 libhw64 libuser libdis libdis-user clean: diff --git a/Makefile.objs b/Makefile.objs index eb264d9..9b77d10 100644 --- a/Makefile.objs +++ b/Makefile.objs @@ -362,6 +362,13 @@ 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 = qmp-input-visiter.o qmp-output-visiter.o qapi-dealloc-visiter.o +qapi-nested-y += qmp-registry.o qmp-dispatch.o +qapi-obj-y = $(addprefix qapi/, $(qapi-nested-y)) + vl.o: QEMU_CFLAGS+=$(GPROF_CFLAGS) vl.o: QEMU_CFLAGS+=$(SDL_CFLAGS) -- 1.7.0.4
[Qemu-devel] [PATCH v1][ 05/14] json-streamer: allow recovery after bad input
From: Anthony Liguori Once we detect a malformed message, make sure to reset our state. Signed-off-by: Michael Roth --- json-streamer.c |8 ++-- 1 files changed, 6 insertions(+), 2 deletions(-) diff --git a/json-streamer.c b/json-streamer.c index f7e7a68..549e9b7 100644 --- a/json-streamer.c +++ b/json-streamer.c @@ -51,8 +51,12 @@ static void json_message_process_token(JSONLexer *lexer, QString *token, JSONTok qlist_append(parser->tokens, dict); -if (parser->brace_count == 0 && -parser->bracket_count == 0) { +if (parser->brace_count < 0 || +parser->bracket_count < 0 || +(parser->brace_count == 0 && + parser->bracket_count == 0)) { +parser->brace_count = 0; +parser->bracket_count = 0; parser->emit(parser, parser->tokens); QDECREF(parser->tokens); parser->tokens = qlist_new(); -- 1.7.0.4
[Qemu-devel] [PATCH v3][ 2/7] guest agent: command state class
Signed-off-by: Michael Roth --- qga/guest-agent-command-state.c | 73 +++ 1 files changed, 73 insertions(+), 0 deletions(-) create mode 100644 qga/guest-agent-command-state.c diff --git a/qga/guest-agent-command-state.c b/qga/guest-agent-command-state.c new file mode 100644 index 000..997355e --- /dev/null +++ b/qga/guest-agent-command-state.c @@ -0,0 +1,73 @@ +/* + * QEMU Guest Agent command state interfaces + * + * Copyright IBM Corp. 2011 + * + * Authors: + * Michael Roth + * + * This work is licensed under the terms of the GNU GPL, version 2 or later. + * See the COPYING file in the top-level directory. + */ +#include +#include "guest-agent.h" + +struct GACommandState { +GSList *groups; +}; + +typedef struct GACommandGroup { +void (*init)(void); +void (*cleanup)(void); +} GACommandGroup; + +/* handle init/cleanup for stateful guest commands */ + +void ga_command_state_add(GACommandState *cs, + void (*init)(void), + void (*cleanup)(void)) +{ +GACommandGroup *cg = g_malloc0(sizeof(GACommandGroup)); +cg->init = init; +cg->cleanup = cleanup; +cs->groups = g_slist_append(cs->groups, cg); +} + +static void ga_command_group_init(gpointer opaque, gpointer unused) +{ +GACommandGroup *cg = opaque; + +g_assert(cg); +if (cg->init) { +cg->init(); +} +} + +void ga_command_state_init_all(GACommandState *cs) +{ +g_assert(cs); +g_slist_foreach(cs->groups, ga_command_group_init, NULL); +} + +static void ga_command_group_cleanup(gpointer opaque, gpointer unused) +{ +GACommandGroup *cg = opaque; + +g_assert(cg); +if (cg->cleanup) { +cg->cleanup(); +} +} + +void ga_command_state_cleanup_all(GACommandState *cs) +{ +g_assert(cs); +g_slist_foreach(cs->groups, ga_command_group_cleanup, NULL); +} + +GACommandState *ga_command_state_new(void) +{ +GACommandState *cs = g_malloc0(sizeof(GACommandState)); +cs->groups = NULL; +return cs; +} -- 1.7.0.4
[Qemu-devel] [PATCH v1][ 10/21] qapi: add QMP input visiter
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 --- qapi/qmp-input-visiter.c | 239 ++ qapi/qmp-input-visiter.h | 26 + 2 files changed, 265 insertions(+), 0 deletions(-) create mode 100644 qapi/qmp-input-visiter.c create mode 100644 qapi/qmp-input-visiter.h diff --git a/qapi/qmp-input-visiter.c b/qapi/qmp-input-visiter.c new file mode 100644 index 000..6767e39 --- /dev/null +++ b/qapi/qmp-input-visiter.c @@ -0,0 +1,239 @@ +#include "qmp-input-visiter.h" +#include "qemu-queue.h" +#include "qemu-common.h" +#include "qemu-objects.h" +#include "qerror.h" + +#define QAPI_OBJECT_SIZE 512 + +#define QIV_STACK_SIZE 1024 + +typedef struct StackObject +{ +QObject *obj; +QListEntry *entry; +} StackObject; + +struct QmpInputVisiter +{ +Visiter visiter; +QObject *obj; +StackObject stack[QIV_STACK_SIZE]; +int nb_stack; +}; + +static QmpInputVisiter *to_qiv(Visiter *v) +{ +return container_of(v, QmpInputVisiter, visiter); +} + +static QObject *qmp_input_get_object(QmpInputVisiter *qiv, const char *name) +{ +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(QmpInputVisiter *qiv, QObject *obj) +{ +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++; + +assert(qiv->nb_stack < QIV_STACK_SIZE); // FIXME +} + +static void qmp_input_pop(QmpInputVisiter *qiv) +{ +qiv->nb_stack--; +assert(qiv->nb_stack >= 0); // FIXME +} + +static void qmp_input_start_struct(Visiter *v, void **obj, const char *kind, const char *name, Error **errp) +{ +QmpInputVisiter *qiv = to_qiv(v); +QObject *qobj = qmp_input_get_object(qiv, name); + +if (!qobj || qobject_type(qobj) != QTYPE_QDICT) { +error_set(errp, QERR_INVALID_PARAMETER_TYPE, name, "object"); +return; +} + +qmp_input_push(qiv, qobj); + +if (obj) { +*obj = qemu_mallocz(QAPI_OBJECT_SIZE); +} +} + +static void qmp_input_end_struct(Visiter *v, Error **errp) +{ +QmpInputVisiter *qiv = to_qiv(v); + +qmp_input_pop(qiv); +} + +static void qmp_input_start_list(Visiter *v, const char *name, Error **errp) +{ +QmpInputVisiter *qiv = to_qiv(v); +QObject *qobj = qmp_input_get_object(qiv, name); + +if (!qobj || qobject_type(qobj) != QTYPE_QLIST) { +error_set(errp, QERR_INVALID_PARAMETER_TYPE, name, "list"); +return; +} + +qmp_input_push(qiv, qobj); +} + +static GenericList *qmp_input_next_list(Visiter *v, GenericList **list, Error **errp) +{ +QmpInputVisiter *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 void qmp_input_end_list(Visiter *v, Error **errp) +{ +QmpInputVisiter *qiv = to_qiv(v); + +qmp_input_pop(qiv); +} + +static void qmp_input_type_int(Visiter *v, int64_t *obj, const char *name, Error **errp) +{ +QmpInputVisiter *qiv = to_qiv(v); +QObject *qobj = qmp_input_get_object(qiv, name); + +if (!qobj || qobject_type(qobj) != QTYPE_QINT) { +error_set(errp, QERR_INVALID_PARAMETER_TYPE, name, "integer"); +return; +} + +*obj = qint_get_int(qobject_to_qint(qobj)); +} + +static void qmp_input_type_bool(Visiter *v, bool *obj, const char *name, Error **errp) +{ +QmpInputVisiter *qiv = to_qiv(v); +QObject *qobj = qmp_input_get_object(qiv, name); + +if (!qobj || qobject_type(qobj) != QTYPE_QBOOL) { +error_set(errp, QERR_INVALID_PARAMETER_TYPE, name, "boolean"); +return; +} + +*obj = qbool_get_int(qobject_to_qbool(qobj)); +} + +static void qmp_input_type_str(Visiter *v, char **obj, const char *name, Error **errp) +{ +QmpInputVisiter *qiv = to_qiv(v); +QObject *qobj = qmp_input_get_object(qiv, name); + +if (!qobj || qobject_type(qobj) != QTYPE_QSTRING) { +error_set(errp, QERR_INVALID_P
Re: [Qemu-devel] virtio scsi host draft specification, v2
On 06/01/2011 03:46 PM, Avi Kivity wrote: Virtqueues 0:control transmitq 1:control receiveq 2:requestq Shouldn't we plan multiqueue for this from day 1? How would you do multiqueue? Just provide N queues, and the device can place requests for any LUN on any queue? If that's correct, it doesn't sound too hard to do, but also doesn't sound problematic to fit it later. So I'm quite ambivalent Requests have the following format: struct virtio_scsi_req_cmd { u8 lun[8]; u64 id; u8 task_attr; u8 prio; u8 crn; u32 num_dataout, num_datain; char cdb[]; char data[][num_dataout+num_datain]; u8 sense[]; u32 sense_len; u32 residual; u16 status_qualifier; u8 status; u8 response; }; flags? room for growth? Feature bits can be used to negotiate the exact format of the request. I don't expect many changes, since we're closely mimicking the SCSI requests. Paolo
Re: [Qemu-devel] virtio scsi host draft specification, v2
On 06/01/2011 07:25 PM, Paolo Bonzini wrote: On 06/01/2011 03:46 PM, Avi Kivity wrote: Virtqueues 0:control transmitq 1:control receiveq 2:requestq Shouldn't we plan multiqueue for this from day 1? How would you do multiqueue? Just provide N queues, and the device can place requests for any LUN on any queue? Yes. If that's correct, it doesn't sound too hard to do, but also doesn't sound problematic to fit it later. So I'm quite ambivalent Since it's easy, why not? Reducing feature bit proliferation means easier testing. flags? room for growth? Feature bits can be used to negotiate the exact format of the request. I don't expect many changes, since we're closely mimicking the SCSI requests. Ok. If we're following a standard we should be safe. -- error compiling committee.c: too many arguments to function
[Qemu-devel] QMP: RFC: I/O error info & query-stop-reason
Hi there, There are people who want to use QMP for thin provisioning. That's, the VM is started with a small storage and when a no space error is triggered, more space is allocated and the VM is put to run again. QMP has two limitations that prevent people from doing this today: 1. The BLOCK_IO_ERROR doesn't contain error information 2. Considering we solve item 1, we still have to provide a way for clients to query why a VM stopped. This is needed because clients may miss the BLOCK_IO_ERROR event or may connect to the VM while it's already stopped A proposal to solve both problems follow. A. BLOCK_IO_ERROR information - We already have discussed this a lot, but didn't reach a consensus. My solution is quite simple: to add a stringfied errno name to the BLOCK_IO_ERROR event, for example (see the "reason" key): { "event": "BLOCK_IO_ERROR", "data": { "device": "ide0-hd1", "operation": "write", "action": "stop", "reason": "enospc", } "timestamp": { "seconds": 1265044230, "microseconds": 450486 } } Valid error reasons could be: "enospc", "eio", etc. B. query-stop-reason I also have a simple solution for item 2. The vm_stop() accepts a reason argument, so we could store it somewhere and return it as a string, like: -> { "execute": "query-stop-reason" } <- { "return": { "reason": "user" } } Valid reasons could be: "user", "debug", "shutdown", "diskfull" (hey, this should be "ioerror", no?), "watchdog", "panic", "savevm", "loadvm", "migrate". Also note that we have a STOP event. It should be extended with the stop reason too, for completeness.
[Qemu-devel] [PATCH v1][ 12/14] json-lexer: make lexer error-recovery more deterministic
Currently when we reach an error state we effectively flush everything fed to the lexer, which can put us in a state where we keep feeding tokens into the parser at arbitrary offsets in the stream. This makes it difficult for the lexer/tokenizer/parser to get back in sync when bad input is made by the client. With these changes we emit an error state/token up to the tokenizer as soon as we reach an error state, and continue processing any data passed in rather than bailing out. The reset token will be used to reset the tokenizer and parser, such that they'll recover state as soon as the lexer begins generating valid token sequences again. We also map chr(192,193,245-255) to an error state here, since they are invalid UTF-8 characters. QMP guest proxy/agent will use chr(255) to force a flush/reset of previous input for reliable delivery of certain events, so also we document that thoroughly here. Signed-off-by: Michael Roth --- json-lexer.c | 25 + json-lexer.h |1 + 2 files changed, 22 insertions(+), 4 deletions(-) diff --git a/json-lexer.c b/json-lexer.c index 6b49047..c21338f 100644 --- a/json-lexer.c +++ b/json-lexer.c @@ -105,7 +105,8 @@ static const uint8_t json_lexer[][256] = { ['u'] = IN_DQ_UCODE0, }, [IN_DQ_STRING] = { -[1 ... 0xFF] = IN_DQ_STRING, +[1 ... 0xBF] = IN_DQ_STRING, +[0xC2 ... 0xF4] = IN_DQ_STRING, ['\\'] = IN_DQ_STRING_ESCAPE, ['"'] = JSON_STRING, }, @@ -144,7 +145,8 @@ static const uint8_t json_lexer[][256] = { ['u'] = IN_SQ_UCODE0, }, [IN_SQ_STRING] = { -[1 ... 0xFF] = IN_SQ_STRING, +[1 ... 0xBF] = IN_SQ_STRING, +[0xC2 ... 0xF4] = IN_SQ_STRING, ['\\'] = IN_SQ_STRING_ESCAPE, ['\''] = JSON_STRING, }, @@ -305,10 +307,25 @@ static int json_lexer_feed_char(JSONLexer *lexer, char ch, bool flush) new_state = IN_START; break; case IN_ERROR: +/* XXX: To avoid having previous bad input leaving the parser in an + * unresponsive state where we consume unpredictable amounts of + * subsequent "good" input, percolate this error state up to the + * tokenizer/parser by forcing a NULL object to be emitted, then + * reset state. + * + * Also note that this handling is required for reliable channel + * negotiation between QMP and the guest agent, since chr(0xFF) + * is placed at the beginning of certain events to ensure proper + * delivery when the channel is in an unknown state. chr(0xFF) is + * never a valid ASCII/UTF-8 sequence, so this should reliably + * induce an error/flush state. + */ +lexer->emit(lexer, lexer->token, JSON_ERROR, lexer->x, lexer->y); QDECREF(lexer->token); lexer->token = qstring_new(); new_state = IN_START; -return -EINVAL; +lexer->state = new_state; +return 0; default: break; } @@ -346,7 +363,7 @@ int json_lexer_feed(JSONLexer *lexer, const char *buffer, size_t size) int json_lexer_flush(JSONLexer *lexer) { -return lexer->state == IN_START ? 0 : json_lexer_feed_char(lexer, 0); +return lexer->state == IN_START ? 0 : json_lexer_feed_char(lexer, 0, true); } void json_lexer_destroy(JSONLexer *lexer) diff --git a/json-lexer.h b/json-lexer.h index 3b50c46..10bc0a7 100644 --- a/json-lexer.h +++ b/json-lexer.h @@ -25,6 +25,7 @@ typedef enum json_token_type { JSON_STRING, JSON_ESCAPE, JSON_SKIP, +JSON_ERROR, } JSONTokenType; typedef struct JSONLexer JSONLexer; -- 1.7.0.4
Re: [Qemu-devel] [PATCH V2 3/3] Remove warning in printf due to type mismatch
Markus, Stefan, Am 30.05.2011 um 00:22 schrieb Alexandre Raymond: 8< qemu/target-lm32/translate.c: In function ‘gen_intermediate_code_internal’: qemu/target-lm32/translate.c:1135: warning: format ‘%zd’ expects type ‘signed size_t’, but argument 4 has type ‘int’ 8< Both gen_opc_ptr and gen_opc_buf are "uint16_t *". The difference between pointers is a ptrdiff_t so printf needs '%td'. Signed-off-by: Alexandre Raymond You suggested the use of t, are you planning to ack it? Andreas --- target-lm32/translate.c |2 +- 1 files changed, 1 insertions(+), 1 deletions(-) diff --git a/target-lm32/translate.c b/target-lm32/translate.c index eb21158..5e19725 100644 --- a/target-lm32/translate.c +++ b/target-lm32/translate.c @@ -1132,7 +1132,7 @@ static void gen_intermediate_code_internal(CPUState *env, if (qemu_loglevel_mask(CPU_LOG_TB_IN_ASM)) { qemu_log("\n"); log_target_disas(pc_start, dc->pc - pc_start, 0); -qemu_log("\nisize=%d osize=%zd\n", +qemu_log("\nisize=%d osize=%td\n", dc->pc - pc_start, gen_opc_ptr - gen_opc_buf); } #endif -- 1.7.5
Re: [Qemu-devel] [RFC]QEMU disk I/O limits
On Wed, Jun 1, 2011 at 2:20 PM, Vivek Goyal wrote: > On Tue, May 31, 2011 at 06:30:09PM -0500, Anthony Liguori wrote: > > [..] >> The level of consistency will then depend on whether you overcommit >> your hardware and how you have it configured. > > Agreed. > >> >> Consistency is very hard because at the end of the day, you still >> have shared resources. Even with blkio, I presume one guest can >> still impact another guest by forcing the disk to do excessive >> seeking or something of that nature. >> >> So absolutely consistency can't be the requirement for the use-case. >> The use-cases we are interested really are more about providing caps >> than anything else. > > I think both qemu and kenrel can do the job. The only thing which > seriously favors throttling implementation in qemu is the ability > to handle wide variety of backend files (NFS, qcow, libcurl based > devices etc). > > So what I am arguing is that your previous reason that qemu can do > a better job because it knows effective IOPS of guest, is not > necessarily a very good reason. To me simplicity of being able to handle > everything as file and do the throttling is the most compelling reason > to do this implementation in qemu. The variety of backends is the reason to go for a QEMU-based approach. If there were kernel mechanisms to handle non-block backends that would be great. cgroups NFS? Of course for something like Sheepdog or Ceph it becomes quite hard to do it in the kernel at all since they are userspace libraries that speak their protocol over sockets, and you really don't have sinight into what I/O operations they are doing from the kernel. One issue that concerns me is how effective iops and throughput are as capping mechanisms. If you cap throughput then you're likely to affect sequential I/O but do little against random I/O which can hog the disk with a seeky I/O pattern. If you limit iops you can cap random I/O but artifically limit sequential I/O, which may be able to perform a high number of iops without hogging the disk due to seek times at all. One proposed solution here (I think Christoph Hellwig suggested it) is to do something like merging sequential I/O counting so that multiple sequential I/Os only count as 1 iop. I like the idea of a proportional share of disk utilization but doing that from QEMU is problematic since we only know when we issued an I/O to the kernel, not when it's actually being serviced by the disk - there could be queue wait times in the block layer that we don't know about - so we end up with a magic number for disk utilization which may not be a very meaningful number. So given the constraints and the backends we need to support, disk I/O limits in QEMU with iops and throughput limits seem like the approach we need. Stefan
[Qemu-devel] [PATCH v1][ 11/21] qapi: add QMP output visiter
Type of Visiter class that serves as the inverse of the input visiter: it takes a series of native C types and uses their values to construct a corresponding QObject. The command marshaling/dispatcher functions will use this to convert the output of QMP functions into a QObject that can be sent over the wire. Signed-off-by: Michael Roth --- qapi/qmp-output-visiter.c | 180 + qapi/qmp-output-visiter.h | 27 +++ 2 files changed, 207 insertions(+), 0 deletions(-) create mode 100644 qapi/qmp-output-visiter.c create mode 100644 qapi/qmp-output-visiter.h diff --git a/qapi/qmp-output-visiter.c b/qapi/qmp-output-visiter.c new file mode 100644 index 000..4a7cb36 --- /dev/null +++ b/qapi/qmp-output-visiter.c @@ -0,0 +1,180 @@ +#include "qmp-output-visiter.h" +#include "qemu-queue.h" +#include "qemu-common.h" +#include "qemu-objects.h" + +typedef struct QStackEntry +{ +QObject *value; +QTAILQ_ENTRY(QStackEntry) node; +} QStackEntry; + +typedef QTAILQ_HEAD(QStack, QStackEntry) QStack; + +struct QmpOutputVisiter +{ +Visiter visiter; +QStack stack; +}; + +#define qmp_output_add(qov, name, value) qmp_output_add_obj(qov, name, QOBJECT(value)) +#define qmp_output_push(qov, value) qmp_output_push_obj(qov, QOBJECT(value)) + +static QmpOutputVisiter *to_qov(Visiter *v) +{ +return container_of(v, QmpOutputVisiter, visiter); +} + +static void qmp_output_push_obj(QmpOutputVisiter *qov, QObject *value) +{ +QStackEntry *e = qemu_mallocz(sizeof(*e)); + +e->value = value; +QTAILQ_INSERT_HEAD(&qov->stack, e, node); +} + +static QObject *qmp_output_pop(QmpOutputVisiter *qov) +{ +QStackEntry *e = QTAILQ_FIRST(&qov->stack); +QObject *value; +QTAILQ_REMOVE(&qov->stack, e, node); +value = e->value; +qemu_free(e); +return value; +} + +static QObject *qmp_output_first(QmpOutputVisiter *qov) +{ +QStackEntry *e = QTAILQ_LAST(&qov->stack, QStack); +return e->value; +} + +static QObject *qmp_output_last(QmpOutputVisiter *qov) +{ +QStackEntry *e = QTAILQ_FIRST(&qov->stack); +return e->value; +} + +static void qmp_output_add_obj(QmpOutputVisiter *qov, const char *name, QObject *value) +{ +QObject *cur; + +if (QTAILQ_EMPTY(&qov->stack)) { +qmp_output_push_obj(qov, value); +return; +} + +cur = qmp_output_last(qov); + +switch (qobject_type(cur)) { +case QTYPE_QDICT: +qdict_put_obj(qobject_to_qdict(cur), name, value); +break; +case QTYPE_QLIST: +qlist_append_obj(qobject_to_qlist(cur), value); +break; +default: +qobject_decref(qmp_output_pop(qov)); +qmp_output_push_obj(qov, value); +break; +} +} + +static void qmp_output_start_struct(Visiter *v, void **obj, const char *kind, const char *name, Error **errp) +{ +QmpOutputVisiter *qov = to_qov(v); +QDict *dict = qdict_new(); + +qmp_output_add(qov, name, dict); +qmp_output_push(qov, dict); +} + +static void qmp_output_end_struct(Visiter *v, Error **errp) +{ +QmpOutputVisiter *qov = to_qov(v); +qmp_output_pop(qov); +} + +static void qmp_output_start_list(Visiter *v, const char *name, Error **errp) +{ +QmpOutputVisiter *qov = to_qov(v); +QList *list = qlist_new(); + +qmp_output_add(qov, name, list); +qmp_output_push(qov, list); +} + +static GenericList *qmp_output_next_list(Visiter *v, GenericList **list, Error **errp) +{ +GenericList *retval = *list; +*list = retval->next; +return retval; +} + +static void qmp_output_end_list(Visiter *v, Error **errp) +{ +QmpOutputVisiter *qov = to_qov(v); +qmp_output_pop(qov); +} + +static void qmp_output_type_int(Visiter *v, int64_t *obj, const char *name, Error **errp) +{ +QmpOutputVisiter *qov = to_qov(v); +qmp_output_add(qov, name, qint_from_int(*obj)); +} + +static void qmp_output_type_bool(Visiter *v, bool *obj, const char *name, Error **errp) +{ +QmpOutputVisiter *qov = to_qov(v); +qmp_output_add(qov, name, qbool_from_int(*obj)); +} + +static void qmp_output_type_str(Visiter *v, char **obj, const char *name, Error **errp) +{ +QmpOutputVisiter *qov = to_qov(v); +qmp_output_add(qov, name, qstring_from_str(*obj)); +} + +static void qmp_output_type_number(Visiter *v, double *obj, const char *name, Error **errp) +{ +QmpOutputVisiter *qov = to_qov(v); +qmp_output_add(qov, name, qfloat_from_double(*obj)); +} + +static void qmp_output_type_enum(Visiter *v, int *obj, const char *kind, const char *name, Error **errp) +{ +int64_t value = *obj; +qmp_output_type_int(v, &value, name, errp); +} + +QObject *qmp_output_get_qobject(QmpOutputVisiter *qov) +{ +return qmp_output_first(qov); +} + +Visiter *qmp_output_get_visiter(QmpOutputVisiter *v) +{ +return &v->visiter; +} + +QmpOutputVisiter *qmp_output_visiter_new(void) +{ +QmpOutputVisiter *v; + +v = qemu_mallocz(sizeof(*v)); + +v->visiter.start_struct = qmp_output_st
[Qemu-devel] [PATCH 2/2] kvm: Enable CPU SMEP feature
From: "Yang, Wei Y" This patchset enables a new CPU feature SMEP (Supervisor Mode Execution Protection) in QEMU-KVM. SMEP prevents kernel from executing code in application. Updated Intel SDM describes this CPU feature. The document will be published soon. SMEP is identified by CPUID leaf 7 EBX[7], which is 0 before. Get the right value by query KVM kernel module, so that guest can get SMEP through CPUID. Signed-off-by: Yang, Wei Singed-off-by: Shan, Haitao Singed-off-by: Li, Xin Signed-off-by: Marcelo Tosatti --- target-i386/cpuid.c | 13 + 1 files changed, 13 insertions(+), 0 deletions(-) diff --git a/target-i386/cpuid.c b/target-i386/cpuid.c index 40a73c7..79e7580 100644 --- a/target-i386/cpuid.c +++ b/target-i386/cpuid.c @@ -1142,6 +1142,19 @@ void cpu_x86_cpuid(CPUX86State *env, uint32_t index, uint32_t count, *ecx = 0; *edx = 0; break; +case 7: +if (kvm_enabled()) { +*eax = kvm_arch_get_supported_cpuid(env, 0x7, count, R_EAX); +*ebx = kvm_arch_get_supported_cpuid(env, 0x7, count, R_EBX); +*ecx = kvm_arch_get_supported_cpuid(env, 0x7, count, R_ECX); +*edx = kvm_arch_get_supported_cpuid(env, 0x7, count, R_EDX); +} else { +*eax = 0; +*ebx = 0; +*ecx = 0; +*edx = 0; +} +break; case 9: /* Direct Cache Access Information Leaf */ *eax = 0; /* Bits 0-31 in DCA_CAP MSR */ -- 1.7.5.2
Re: [Qemu-devel] [RFC]QEMU disk I/O limits
On Wed, Jun 01, 2011 at 10:15:30PM +0100, Stefan Hajnoczi wrote: > On Wed, Jun 1, 2011 at 2:20 PM, Vivek Goyal wrote: > > On Tue, May 31, 2011 at 06:30:09PM -0500, Anthony Liguori wrote: > > > > [..] > >> The level of consistency will then depend on whether you overcommit > >> your hardware and how you have it configured. > > > > Agreed. > > > >> > >> Consistency is very hard because at the end of the day, you still > >> have shared resources. Even with blkio, I presume one guest can > >> still impact another guest by forcing the disk to do excessive > >> seeking or something of that nature. > >> > >> So absolutely consistency can't be the requirement for the use-case. > >> The use-cases we are interested really are more about providing caps > >> than anything else. > > > > I think both qemu and kenrel can do the job. The only thing which > > seriously favors throttling implementation in qemu is the ability > > to handle wide variety of backend files (NFS, qcow, libcurl based > > devices etc). > > > > So what I am arguing is that your previous reason that qemu can do > > a better job because it knows effective IOPS of guest, is not > > necessarily a very good reason. To me simplicity of being able to handle > > everything as file and do the throttling is the most compelling reason > > to do this implementation in qemu. > > The variety of backends is the reason to go for a QEMU-based approach. > If there were kernel mechanisms to handle non-block backends that > would be great. cgroups NFS? I agree that because qemu can handle variety of backends it becomes a very good reason to do throttling in qemu. Kernel currently does not handle files over NFS. There were some suggestions of using a loop or device mapper loop device on top of NFS images and then implement block device policies like throttling. But I am not convinced that it is a good idea. To cover the case of NFS we probably shall have to implement something in NFS or something more generic in VFS. But I am not sure if file system guys will like it or is it even worth at this point of time given the fact that primary use case is qemu and qemu can easily implement this funcitonality. > > Of course for something like Sheepdog or Ceph it becomes quite hard to > do it in the kernel at all since they are userspace libraries that > speak their protocol over sockets, and you really don't have sinight > into what I/O operations they are doing from the kernel. Agreed. This is another reason that why doing it in qemu makes sense. > > One issue that concerns me is how effective iops and throughput are as > capping mechanisms. If you cap throughput then you're likely to > affect sequential I/O but do little against random I/O which can hog > the disk with a seeky I/O pattern. If you limit iops you can cap > random I/O but artifically limit sequential I/O, which may be able to > perform a high number of iops without hogging the disk due to seek > times at all. One proposed solution here (I think Christoph Hellwig > suggested it) is to do something like merging sequential I/O counting > so that multiple sequential I/Os only count as 1 iop. One of the things we atleast need to do is allow specifying both bps and iops rule together so that random IO with high iops does not create havoc and seqential or large size IO with low iops and high bps does not overload the system. I am not sure how IO shows up in qemu but will elevator in guest make sure that lot of sequential IO is merged together? For dependent READS, I think counting multiple sequential reads as 1 iops might help. I think this is one optimization one can do once throttling starts working in qemu and see if it is a real concern. > > I like the idea of a proportional share of disk utilization but doing > that from QEMU is problematic since we only know when we issued an I/O > to the kernel, not when it's actually being serviced by the disk - > there could be queue wait times in the block layer that we don't know > about - so we end up with a magic number for disk utilization which > may not be a very meaningful number. To be able to implement proportional IO one should be able to see all IO from all clients at one place. Qemu knows about IO of only its guest and not other guests running on the system. So I think qemu can't implement proportion IO. > > So given the constraints and the backends we need to support, disk I/O > limits in QEMU with iops and throughput limits seem like the approach > we need. For qemu yes. For other non-qemu usages we will still require a kernel mechanism of throttling. Thanks Vivek