[Qemu-devel] [PATCH v4] This patch adds support for a new block device type called "vxhs".
Source code for the qnio library that this code loads can be downloaded from: https://github.com/MittalAshish/libqnio.git Sample command line using the JSON syntax: ./qemu-system-x86_64 -name instance-0008 -S -vnc 0.0.0.0:0 -k en-us -vga cirrus -device virtio-balloon-pci,id=balloon0,bus=pci.0,addr=0x5 -msg timestamp=on 'json:{"driver":"vxhs","vdisk_id":"c3e9095a-a5ee-4dce-afeb-2a59fb387410", "server":{"host":"172.172.17.4","port":""}}' Sample command line using the URI syntax: qemu-img convert -f raw -O raw -n /var/lib/nova/instances/_base/0c5eacd5ebea5ed914b6a3e7b18f1ce734c386ad vxhs://192.168.0.1:/c6718f6b-0401-441d-a8c3-1f0064d75ee0 Signed-off-by: Ashish Mittal --- v4 changelog: (1) Incorporated v3 review comments on QAPI changes. (2) Added refcounting for device open/close. Free library resources on last device close. v3 changelog: (1) Added QAPI schema for the VxHS driver. v2 changelog: (1) Changes done in response to v1 comments. TODO: (1) Add qemu-iotest block/Makefile.objs | 2 + block/trace-events | 21 ++ block/vxhs.c | 703 +++ configure| 41 +++ qapi/block-core.json | 20 +- 5 files changed, 785 insertions(+), 2 deletions(-) create mode 100644 block/vxhs.c diff --git a/block/Makefile.objs b/block/Makefile.objs index 67a036a..58313a2 100644 --- a/block/Makefile.objs +++ b/block/Makefile.objs @@ -18,6 +18,7 @@ block-obj-$(CONFIG_LIBNFS) += nfs.o block-obj-$(CONFIG_CURL) += curl.o block-obj-$(CONFIG_RBD) += rbd.o block-obj-$(CONFIG_GLUSTERFS) += gluster.o +block-obj-$(CONFIG_VXHS) += vxhs.o block-obj-$(CONFIG_ARCHIPELAGO) += archipelago.o block-obj-$(CONFIG_LIBSSH2) += ssh.o block-obj-y += accounting.o dirty-bitmap.o @@ -38,6 +39,7 @@ rbd.o-cflags := $(RBD_CFLAGS) rbd.o-libs := $(RBD_LIBS) gluster.o-cflags := $(GLUSTERFS_CFLAGS) gluster.o-libs := $(GLUSTERFS_LIBS) +vxhs.o-libs:= $(VXHS_LIBS) ssh.o-cflags := $(LIBSSH2_CFLAGS) ssh.o-libs := $(LIBSSH2_LIBS) archipelago.o-libs := $(ARCHIPELAGO_LIBS) diff --git a/block/trace-events b/block/trace-events index aff8a96..5cb8089 100644 --- a/block/trace-events +++ b/block/trace-events @@ -113,3 +113,24 @@ qed_aio_write_data(void *s, void *acb, int ret, uint64_t offset, size_t len) "s qed_aio_write_prefill(void *s, void *acb, uint64_t start, size_t len, uint64_t offset) "s %p acb %p start %"PRIu64" len %zu offset %"PRIu64 qed_aio_write_postfill(void *s, void *acb, uint64_t start, size_t len, uint64_t offset) "s %p acb %p start %"PRIu64" len %zu offset %"PRIu64 qed_aio_write_main(void *s, void *acb, int ret, uint64_t offset, size_t len) "s %p acb %p ret %d offset %"PRIu64" len %zu" + +# block/vxhs.c +vxhs_iio_callback(int error, int reason) "ctx is NULL: error %d, reason %d" +vxhs_setup_qnio(void *s) "Context to HyperScale IO manager = %p" +vxhs_iio_callback_chnfail(int err, int error) "QNIO channel failed, no i/o %d, %d" +vxhs_iio_callback_unknwn(int opcode, int err) "unexpected opcode %d, errno %d" +vxhs_open_fail(int ret) "Could not open the device. Error = %d" +vxhs_open_epipe(int ret) "Could not create a pipe for device. Bailing out. Error=%d" +vxhs_aio_rw_invalid(int req) "Invalid I/O request iodir %d" +vxhs_aio_rw_ioerr(char *guid, int iodir, uint64_t size, uint64_t off, void *acb, int ret, int err) "IO ERROR (vDisk %s) FOR : Read/Write = %d size = %lu offset = %lu ACB = %p. Error = %d, errno = %d" +vxhs_get_vdisk_stat_err(char *guid, int ret, int err) "vDisk (%s) stat ioctl failed, ret = %d, errno = %d" +vxhs_get_vdisk_stat(char *vdisk_guid, uint64_t vdisk_size) "vDisk %s stat ioctl returned size %lu" +vxhs_qnio_iio_open(const char *ip) "Failed to connect to storage agent on host-ip %s" +vxhs_qnio_iio_devopen(const char *fname) "Failed to open vdisk device: %s" +vxhs_complete_aio(void *acb, uint64_t ret) "aio failed acb %p ret %ld" +vxhs_parse_uri_filename(const char *filename) "URI passed via bdrv_parse_filename %s" +vxhs_qemu_init_vdisk(const char *vdisk_id) "vdisk-id from json %s" +vxhs_parse_uri_hostinfo(int num, char *host, int port) "Host %d: IP %s, Port %d" +vxhs_qemu_init(char *of_vsa_addr, int port) "Adding host %s:%d to BDRVVXHSState" +vxhs_qemu_init_filename(const char *filename) "Filename passed as %s" +vxhs_close(char *vdisk_guid) "Closing vdisk %s" diff --git a/block/vxhs.c b/block/vxhs.c new file mode 100644 index 000..d95be11 --- /dev/null +++ b/block/vxhs.c @@ -0,0 +1,703 @@ +/* + * QEMU Block driver for Veritas HyperScale (VxHS) + * + * 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 "qemu/osdep.h" +#include "block/block_int.h" +#include +#include "qapi/qmp/qerror.h" +#include "qapi/qmp/qdict.h" +#include "qapi/qmp/qstring.h" +#include "trace.h" +#include "qemu/uri.h" +#include "qapi/error.h" +#include "qemu/error-report.h" + +#define VDISK_FD_READ
Re: [Qemu-devel] [PATCH v10 01/19] vfio: Mediated device Core driver
On 10/27/2016 05:29 AM, Kirti Wankhede wrote: > +int mdev_register_device(struct device *dev, const struct parent_ops *ops) > +{ > + int ret; > + struct parent_device *parent; > + > + /* check for mandatory ops */ > + if (!ops || !ops->create || !ops->remove || !ops->supported_type_groups) > + return -EINVAL; > + > + dev = get_device(dev); > + if (!dev) > + return -EINVAL; > + > + mutex_lock(&parent_list_lock); > + > + /* Check for duplicate */ > + parent = __find_parent_device(dev); > + if (parent) { > + ret = -EEXIST; > + goto add_dev_err; > + } > + > + parent = kzalloc(sizeof(*parent), GFP_KERNEL); > + if (!parent) { > + ret = -ENOMEM; > + goto add_dev_err; > + } > + > + kref_init(&parent->ref); > + mutex_init(&parent->lock); > + > + parent->dev = dev; > + parent->ops = ops; > + > + ret = parent_create_sysfs_files(parent); > + if (ret) { > + mutex_unlock(&parent_list_lock); > + mdev_put_parent(parent); > + return ret; > + } > + > + ret = class_compat_create_link(mdev_bus_compat_class, dev, NULL); > + if (ret) > + dev_warn(dev, "Failed to create compatibility class link\n"); > + Hi Kirti, Like I replied to previous version: http://www.spinics.net/lists/kvm/msg139331.html You can always check if mdev_bus_compat_class already registered here, and register it if not yet. Same logic should be adopted to mdev_init. Current implementation will simply panic if configured as builtin, which is rare but far from impossible. -- Thanks, Jike > + list_add(&parent->next, &parent_list); > + mutex_unlock(&parent_list_lock); > + > + dev_info(dev, "MDEV: Registered\n"); > + return 0; > + > +add_dev_err: > + mutex_unlock(&parent_list_lock); > + put_device(dev); > + return ret; > +} > +EXPORT_SYMBOL(mdev_register_device); > + > +/* > + * mdev_unregister_device : Unregister a parent device > + * @dev: device structure representing parent device. > + * > + * Remove device from list of registered parent devices. Give a chance to > free > + * existing mediated devices for given device. > + */ > + > +void mdev_unregister_device(struct device *dev) > +{ > + struct parent_device *parent; > + bool force_remove = true; > + > + mutex_lock(&parent_list_lock); > + parent = __find_parent_device(dev); > + > + if (!parent) { > + mutex_unlock(&parent_list_lock); > + return; > + } > + dev_info(dev, "MDEV: Unregistering\n"); > + > + list_del(&parent->next); > + class_compat_remove_link(mdev_bus_compat_class, dev, NULL); > + > + device_for_each_child(dev, (void *)&force_remove, > + mdev_device_remove_cb); > + > + parent_remove_sysfs_files(parent); > + > + mutex_unlock(&parent_list_lock); > + mdev_put_parent(parent); > +} > +EXPORT_SYMBOL(mdev_unregister_device); > + > +static void mdev_device_release(struct device *dev) > +{ > + struct mdev_device *mdev = to_mdev_device(dev); > + > + dev_dbg(&mdev->dev, "MDEV: destroying\n"); > + kfree(mdev); > +} > + > +int mdev_device_create(struct kobject *kobj, struct device *dev, uuid_le > uuid) > +{ > + int ret; > + struct mdev_device *mdev; > + struct parent_device *parent; > + struct mdev_type *type = to_mdev_type(kobj); > + > + parent = mdev_get_parent(type->parent); > + if (!parent) > + return -EINVAL; > + > + mutex_lock(&parent->lock); > + > + /* Check for duplicate */ > + if (mdev_device_exist(parent, uuid)) { > + ret = -EEXIST; > + goto create_err; > + } > + > + mdev = kzalloc(sizeof(*mdev), GFP_KERNEL); > + if (!mdev) { > + ret = -ENOMEM; > + goto create_err; > + } > + > + memcpy(&mdev->uuid, &uuid, sizeof(uuid_le)); > + mdev->parent = parent; > + kref_init(&mdev->ref); > + > + mdev->dev.parent = dev; > + mdev->dev.bus = &mdev_bus_type; > + mdev->dev.release = mdev_device_release; > + dev_set_name(&mdev->dev, "%pUl", uuid.b); > + > + ret = device_register(&mdev->dev); > + if (ret) { > + put_device(&mdev->dev); > + goto create_err; > + } > + > + ret = mdev_device_create_ops(kobj, mdev); > + if (ret) > + goto create_failed; > + > + ret = mdev_create_sysfs_files(&mdev->dev, type); > + if (ret) { > + mdev_device_remove_ops(mdev, true); > + goto create_failed; > + } > + > + mdev->type_kobj = kobj; > + dev_dbg(&mdev->dev, "MDEV: created\n"); > + > + mutex_unlock(&parent->lock); > + return ret; > + > +create_failed: > + device_unregister(&mdev->dev); > + > +create_err: > + mutex_unlock(&parent->lock); > + mdev_put_parent(parent); > + return ret; > +} > + > +int mdev_device_
[Qemu-devel] [Bug 1637693] [NEW] QEMU not able to create vm with pflash and UEFI bios
Public bug reported: Running Fedora 24 with the virt-preview repo on QEMU Version 2.7.0 and libvirt version 2.2.0. Tried to install a windows 10 vm with the OVMF bios and this error happens every time, it didnt happen when using the stable version of qemu for fedora 24. libvirtError: internal error: qemu unexpectedly closed the monitor: 2016-10-29T04:07:29.678518Z qemu-system-x86_64: -drive file=/usr/share/edk2/aarch64/QEMU_EFI- pflash.raw,if=pflash,format=raw,unit=0,readonly=on: oversized backing file, pflash segments cannot be mapped under ff80 Any ideas? ** Affects: qemu Importance: Undecided Status: New ** Tags: pflash uefi -- You received this bug notification because you are a member of qemu- devel-ml, which is subscribed to QEMU. https://bugs.launchpad.net/bugs/1637693 Title: QEMU not able to create vm with pflash and UEFI bios Status in QEMU: New Bug description: Running Fedora 24 with the virt-preview repo on QEMU Version 2.7.0 and libvirt version 2.2.0. Tried to install a windows 10 vm with the OVMF bios and this error happens every time, it didnt happen when using the stable version of qemu for fedora 24. libvirtError: internal error: qemu unexpectedly closed the monitor: 2016-10-29T04:07:29.678518Z qemu-system-x86_64: -drive file=/usr/share/edk2/aarch64/QEMU_EFI- pflash.raw,if=pflash,format=raw,unit=0,readonly=on: oversized backing file, pflash segments cannot be mapped under ff80 Any ideas? To manage notifications about this bug go to: https://bugs.launchpad.net/qemu/+bug/1637693/+subscriptions
Re: [Qemu-devel] [PATCH 1/2] KVM: page track: add a new notifier type: track_flush_slot
On 10/26/2016 10:45 PM, Paolo Bonzini wrote: > On 26/10/2016 15:44, Jike Song wrote: >> On 10/21/2016 01:06 AM, Paolo Bonzini wrote: >>> On 20/10/2016 03:48, Xiao Guangrong wrote: I understood that KVM side is safe, however, vfio side is independent with kvm and the user of usrdata can fetch kvm struct at any time, consider this scenario: CPU 0 CPU 1 KVM: VFIO/userdata user kvm_ioctl_create_device get_kvm() vfio_group_get_usrdata(vfio_group) kvm_device_release put_kvm() !!! kvm refcount has gone use KVM struct Then, the user of userdata have fetched kvm struct but the refcount has already gone. >>> >>> vfio_group_set_usrdata (actually) kvm_vfio_group_set_kvm has called >>> kvm_get_kvm too, however. What you need is a mutex that is taken by >>> vfio_group_set_usrdata and by the callers of vfio_group_get_usrdata. >> >> Hi Paolo & Guangrong, >> >> I walked the whole thread and became a little nervous: I don't want >> to introduce a global mutex. >> >> The problem is, as I understand, vfio_group_get_usrdata() returns a >> KVM pointer but it may be stale. To make the pointer always valid, >> it can call kvm_get_kvm() *before* return the pointer. > > That doesn't work, you still have to protect get against concurrent set. > But the mutex need not be global, it is specific to the vfio device. > You probably have such a mutex anyway... Thanks Paolo, I agree whatsoever a mutex is necessary. I cooked a patch sent to you and Alex, please kindly have a look :-) -- Thanks, Jike >> I would apologize in advance if this idea turns out totally >> nonsense, but hey, please kindly help fix my whim :-) >> >> >> [vfio.h] >> >> struct vfio_usrdata { >> void *data; >> void (*get)(void *data); >> void (*put)(void *data) >> }; >> >> vfio_group { >> ... >> vfio_usrdata *usrdata; >> >> [kvm.ko] >> >> struvt vfio_usrdata kvmdata = { >> .data = kvm, >> .get = kvm_get_kvm, >> .put = kvm_put_kvm, >> }; >> >> fn = symbol_get(vfio_group_set_usrdata) >> fn(vfio_group, &kvmdata) >> >> >> [vfio.ko] >> >> vfio_group_set_usrdata >> lock >> vfio_group->d = kvmdata >> unlock >> >> void *vfio_group_get_usrdata >> lock >> struct vfio_usrdata *d = vfio_group->usrdata; >> d->get(d->data); >> unlock >> return d->data; >> >> void vfio_group_put_usrdata >> lock >> struct vfio_usrdata *d = vfio_group->usrdata; >> d->put(d->data) >> unlock >> >> [kvmgt.ko] >> >> call vfio_group_get_usrdata to get kvm, >> call vfio_group_put_usrdata to release it >> *never* call kvm_get_kvm/kvm_put_kvm
[Qemu-devel] [PATCH v4 4/8] qdev: Extract property-default code to qdev_property_set_to_default()
The code that registers qdev properties will be split from the code that initializes default values on instance_init, so move it to a separate function. Reviewed-by: Igor Mammedov Signed-off-by: Eduardo Habkost --- Changes series v1 -> v4: * (none) --- hw/core/qdev.c | 41 + 1 file changed, 29 insertions(+), 12 deletions(-) diff --git a/hw/core/qdev.c b/hw/core/qdev.c index 36ca5e7..85952e8 100644 --- a/hw/core/qdev.c +++ b/hw/core/qdev.c @@ -775,6 +775,34 @@ static void qdev_property_add_legacy(DeviceState *dev, Property *prop, } /** + * qdev_property_set_to_default: + * @dev: Device where the property will be reset + * @prop: The qdev property definition + * @errp: location to store error information + * + * Reset the value of property @prop in @dev to its default value. + * On error, store error in @errp. + */ +static void qdev_property_set_to_default(DeviceState *dev, Property *prop, + Error **errp) +{ +Object *obj = OBJECT(dev); + +if (prop->qtype == QTYPE_NONE) { +return; +} + +if (prop->qtype == QTYPE_QBOOL) { +object_property_set_bool(obj, prop->defval, prop->name, errp); +} else if (prop->info->enum_table) { +object_property_set_str(obj, prop->info->enum_table[prop->defval], +prop->name, errp); +} else if (prop->qtype == QTYPE_QINT) { +object_property_set_int(obj, prop->defval, prop->name, errp); +} +} + +/** * qdev_property_add_static: * @dev: Device to add the property to. * @prop: The qdev property definition. @@ -813,18 +841,7 @@ void qdev_property_add_static(DeviceState *dev, Property *prop, prop->info->description, &error_abort); -if (prop->qtype == QTYPE_NONE) { -return; -} - -if (prop->qtype == QTYPE_QBOOL) { -object_property_set_bool(obj, prop->defval, prop->name, &error_abort); -} else if (prop->info->enum_table) { -object_property_set_str(obj, prop->info->enum_table[prop->defval], -prop->name, &error_abort); -} else if (prop->qtype == QTYPE_QINT) { -object_property_set_int(obj, prop->defval, prop->name, &error_abort); -} +qdev_property_set_to_default(dev, prop, &error_abort); } /* @qdev_alias_all_properties - Add alias properties to the source object for -- 2.7.4
[Qemu-devel] [PATCH v4 8/8] qdev: Warning about using qdev_property_add_static() in new code
The only remaining user of qdev_property_add_static() is arm_cpu_post_init(), but removing it may take some work. While we don't change it, warn people to not use the function in new code. Cc: Peter Maydell Cc: qemu-...@nongnu.org Signed-off-by: Eduardo Habkost --- Changes series v1 -> v3: * (none) Changes series v3 -> v4: * Rewrote commit message to refer to correct function name * s/qdev_class_set_props/device_class_set_props/ (function had been renamed in series v3) --- hw/core/qdev.c | 4 1 file changed, 4 insertions(+) diff --git a/hw/core/qdev.c b/hw/core/qdev.c index e695fa8..ae772fc 100644 --- a/hw/core/qdev.c +++ b/hw/core/qdev.c @@ -812,6 +812,10 @@ static void qdev_property_set_to_default(DeviceState *dev, Property *prop, * Add a static QOM property to @dev for qdev property @prop. * On error, store error in @errp. Static properties access data in a struct. * The type of the QOM property is derived from prop->info. + * + * Do not use this in new code. Either use device_class_set_props(), + * or register regular QOM properties using object_property_add() or + * object_class_property_add(). */ void qdev_property_add_static(DeviceState *dev, Property *prop, Error **errp) -- 2.7.4
[Qemu-devel] [PATCH v4 7/8] qmp: Support abstract classes on device-list-properties
When an abstract class is used on device-list-properties, we can simply return the class properties registered for the class. This will be useful if management software needs to query for supported options that apply to all devices of a given type (e.g. options supported by all CPU models, options supported by all PCI devices). Signed-off-by: Eduardo Habkost --- Changes series v1 -> v2: * (none) Changes series v2 -> v3: * Reworded commit message Changes series v3 -> v4: * (none) --- qmp.c | 21 + 1 file changed, 9 insertions(+), 12 deletions(-) diff --git a/qmp.c b/qmp.c index a06cb7b..1e7e60d 100644 --- a/qmp.c +++ b/qmp.c @@ -518,7 +518,7 @@ DevicePropertyInfoList *qmp_device_list_properties(const char *typename, Error **errp) { ObjectClass *klass; -Object *obj; +Object *obj = NULL; ObjectProperty *prop; ObjectPropertyIterator iter; DevicePropertyInfoList *prop_list = NULL; @@ -537,19 +537,16 @@ DevicePropertyInfoList *qmp_device_list_properties(const char *typename, } if (object_class_is_abstract(klass)) { -error_setg(errp, QERR_INVALID_PARAMETER_VALUE, "name", - "non-abstract device type"); -return NULL; -} - -if (DEVICE_CLASS(klass)->cannot_destroy_with_object_finalize_yet) { -error_setg(errp, "Can't list properties of device '%s'", typename); -return NULL; +object_class_property_iter_init(&iter, klass); +} else { +if (DEVICE_CLASS(klass)->cannot_destroy_with_object_finalize_yet) { +error_setg(errp, "Can't list properties of device '%s'", typename); +return NULL; +} +obj = object_new(typename); +object_property_iter_init(&iter, obj); } -obj = object_new(typename); - -object_property_iter_init(&iter, obj); while ((prop = object_property_iter_next(&iter))) { DevicePropertyInfo *info; DevicePropertyInfoList *entry; -- 2.7.4
[Qemu-devel] [PATCH v4 0/8] qdev class properties + abstract class support on device-list-properties
Changes v3 -> v4: * FIx "make check" failures: * Fix e1000e initialization ordering (fixes tests/device-introspect-test failure) * Reported-by: Igor Mammedov * Call prop->info->release on instance_finalize (fixes tests/drive_del-test failure) * See individual patches for other minor/style changes Changes v2 -> v3: * Small alignment fix in patch 3/6 * Included patches from "tests: A few check-qom-proplist fixes" in the series * Rebased to latest qemu.git master Changes v1 -> v2: * s/qdev_class_set_props/device_class_set_props/ * Suggested-by: Andreas Färber A git branch containing this series can be seen at: https://github.com/ehabkost/qemu-hacks.git work/device-list-abstract-properties Eduardo Habkost (8): tests: check-qom-proplist: Remove duplicate "bv" property tests: check-qom-proplist: Use &error_abort to catch errors qdev: device_class_set_props() function qdev: Extract property-default code to qdev_property_set_to_default() qdev: Register static properties as class properties qom: object_class_property_iter_init() function qmp: Support abstract classes on device-list-properties qdev: Warning about using qdev_property_add_static() in new code hw/9pfs/virtio-9p-device.c | 2 +- hw/acpi/piix4.c | 2 +- hw/arm/armv7m.c | 2 +- hw/arm/bcm2836.c| 2 +- hw/arm/integratorcp.c | 2 +- hw/arm/musicpal.c | 2 +- hw/arm/pxa2xx.c | 4 +- hw/arm/pxa2xx_gpio.c| 2 +- hw/arm/spitz.c | 2 +- hw/arm/stm32f205_soc.c | 2 +- hw/arm/strongarm.c | 2 +- hw/arm/xlnx-zynqmp.c| 2 +- hw/audio/ac97.c | 2 +- hw/audio/adlib.c| 2 +- hw/audio/cs4231.c | 2 +- hw/audio/cs4231a.c | 2 +- hw/audio/gus.c | 2 +- hw/audio/hda-codec.c| 2 +- hw/audio/intel-hda.c| 4 +- hw/audio/marvell_88w8618.c | 2 +- hw/audio/pcspk.c| 2 +- hw/audio/pl041.c| 2 +- hw/audio/sb16.c | 2 +- hw/block/fdc.c | 8 +-- hw/block/m25p80.c | 2 +- hw/block/nand.c | 2 +- hw/block/nvme.c | 2 +- hw/block/onenand.c | 2 +- hw/block/pflash_cfi01.c | 2 +- hw/block/pflash_cfi02.c | 2 +- hw/block/virtio-blk.c | 2 +- hw/char/bcm2835_aux.c | 2 +- hw/char/cadence_uart.c | 2 +- hw/char/debugcon.c | 2 +- hw/char/digic-uart.c| 2 +- hw/char/escc.c | 2 +- hw/char/etraxfs_ser.c | 2 +- hw/char/exynos4210_uart.c | 2 +- hw/char/grlib_apbuart.c | 2 +- hw/char/imx_serial.c| 2 +- hw/char/ipoctal232.c| 2 +- hw/char/lm32_juart.c| 2 +- hw/char/lm32_uart.c | 2 +- hw/char/milkymist-uart.c| 2 +- hw/char/parallel.c | 2 +- hw/char/pl011.c | 2 +- hw/char/sclpconsole-lm.c| 2 +- hw/char/sclpconsole.c | 2 +- hw/char/serial-isa.c| 2 +- hw/char/serial-pci.c| 6 +- hw/char/spapr_vty.c | 2 +- hw/char/stm32f2xx_usart.c | 2 +- hw/char/virtio-console.c| 2 +- hw/char/virtio-serial-bus.c | 4 +- hw/char/xilinx_uartlite.c | 2 +- hw/core/generic-loader.c| 2 +- hw/core/or-irq.c| 2 +- hw/core/platform-bus.c | 2 +- hw/core/qdev.c | 125 ++-- hw/cpu/a15mpcore.c | 2 +- hw/cpu/a9mpcore.c | 2 +- hw/cpu/arm11mpcore.c| 2 +- hw/cpu/realview_mpcore.c| 2 +- hw/display/bcm2835_fb.c | 2 +- hw/display/cg3.c| 2 +- hw/display/cirrus_vga.c | 4 +- hw/display/g364fb.c | 2 +- hw/display/milkymist-vgafb.c| 2 +- hw/display/qxl.c| 2 +- hw/display/tcx.c| 2 +- hw/display/vga-isa.c| 2 +- hw/display/vga-pci.c| 4 +- hw/display/virtio-gpu-pci.c | 2 +- hw/display/virtio-gpu.c | 2 +- hw/display/virtio-vga.c | 2 +- hw/display/vmware_vga.c | 2 +- hw/dma/i82374.c | 2 +- hw/dma/i8257.c | 2 +- hw/dma/pl330.c | 2 +- hw/dma/pxa2xx_dma.c | 2 +- hw/dma/sparc32_dma.c| 2 +- hw/dma/sun4m_iommu.c
[Qemu-devel] [PATCH v4 6/8] qom: object_class_property_iter_init() function
The new function will allow us to iterate over class properties using the same logic we use for object properties. Unit test included. Signed-off-by: Eduardo Habkost --- Changes series v1 -> v3: * (none) Changes series v3 -> v4: * Trivial whitespace change (removed extra newline) --- include/qom/object.h | 14 ++ qom/object.c | 10 -- tests/check-qom-proplist.c | 28 3 files changed, 50 insertions(+), 2 deletions(-) diff --git a/include/qom/object.h b/include/qom/object.h index 5ecc2d1..6e3646e 100644 --- a/include/qom/object.h +++ b/include/qom/object.h @@ -995,6 +995,20 @@ void object_property_iter_init(ObjectPropertyIterator *iter, Object *obj); /** + * object_class_property_iter_init: + * @klass: the class + * + * Initializes an iterator for traversing all properties + * registered against an object class and all parent classes. + * + * It is forbidden to modify the property list while iterating, + * whether removing or adding properties. + */ +void object_class_property_iter_init(ObjectPropertyIterator *iter, + ObjectClass *klass); + + +/** * object_property_iter_next: * @iter: the iterator instance * diff --git a/qom/object.c b/qom/object.c index 7a05e35..0cbe228 100644 --- a/qom/object.c +++ b/qom/object.c @@ -1010,6 +1010,13 @@ void object_property_iter_init(ObjectPropertyIterator *iter, iter->nextclass = object_get_class(obj); } +void object_class_property_iter_init(ObjectPropertyIterator *iter, + ObjectClass *klass) +{ +g_hash_table_iter_init(&iter->iter, klass->properties); +iter->nextclass = object_class_get_parent(klass); +} + ObjectProperty *object_property_iter_next(ObjectPropertyIterator *iter) { gpointer key, val; @@ -1017,8 +1024,7 @@ ObjectProperty *object_property_iter_next(ObjectPropertyIterator *iter) if (!iter->nextclass) { return NULL; } -g_hash_table_iter_init(&iter->iter, iter->nextclass->properties); -iter->nextclass = object_class_get_parent(iter->nextclass); +object_class_property_iter_init(iter, iter->nextclass); } return val; } diff --git a/tests/check-qom-proplist.c b/tests/check-qom-proplist.c index 766a4a1..9536415 100644 --- a/tests/check-qom-proplist.c +++ b/tests/check-qom-proplist.c @@ -496,6 +496,33 @@ static void test_dummy_iterator(void) } +static void test_dummy_class_iterator(void) +{ +ObjectClass *klass = object_class_by_name(TYPE_DUMMY); +ObjectProperty *prop; +ObjectPropertyIterator iter; +bool seensv = false, seenav = false, seentype; + +object_class_property_iter_init(&iter, klass); +while ((prop = object_property_iter_next(&iter))) { +if (g_str_equal(prop->name, "sv")) { +seensv = true; +} else if (g_str_equal(prop->name, "av")) { +seenav = true; +} else if (g_str_equal(prop->name, "type")) { +/* This prop comes from the base Object class */ +seentype = true; +} else { +g_printerr("Found prop '%s'\n", prop->name); +g_assert_not_reached(); +} +} +g_assert(seenav); +g_assert(seensv); +g_assert(seentype); +} + + static void test_dummy_delchild(void) { Object *parent = object_get_objects_root(); @@ -524,6 +551,7 @@ int main(int argc, char **argv) g_test_add_func("/qom/proplist/badenum", test_dummy_badenum); g_test_add_func("/qom/proplist/getenum", test_dummy_getenum); g_test_add_func("/qom/proplist/iterator", test_dummy_iterator); +g_test_add_func("/qom/proplist/class_iterator", test_dummy_class_iterator); g_test_add_func("/qom/proplist/delchild", test_dummy_delchild); return g_test_run(); -- 2.7.4
[Qemu-devel] [PATCH v4 5/8] qdev: Register static properties as class properties
Instead of registering qdev static properties on instance_init, register them as class properties, at qdev_class_set_props(). qdev_property_add_legacy() was replaced by an equivalent qdev_class_property_add_legacy() function. qdev_property_add_static(), on the other hand, can't be eliminated yet because it is used by arm_cpu_post_init(). As class properties don't have a release function called when an object instance is destroyed, the release functions for properties are called manually from device_finalize(). Signed-off-by: Eduardo Habkost --- Changes series v1 -> v2: * (none) Changes v2 -> v3: * Fix code alignemnt * Reported-by: Igor Mammedov Changes series v3 -> v4: * s/Device/Class/ on qdev_class_property_add_legacy() doc comment * Reported-by: Igor Mammedov * Call prop->info->release on instance_finalize (fix tests/drive_del-test failure) --- hw/core/qdev.c | 82 -- 1 file changed, 69 insertions(+), 13 deletions(-) diff --git a/hw/core/qdev.c b/hw/core/qdev.c index 85952e8..e695fa8 100644 --- a/hw/core/qdev.c +++ b/hw/core/qdev.c @@ -739,12 +739,12 @@ static void qdev_get_legacy_property(Object *obj, Visitor *v, } /** - * qdev_property_add_legacy: - * @dev: Device to add the property to. + * qdev_class_property_add_legacy: + * @oc: Class to add the property to. * @prop: The qdev property definition. * @errp: location to store error information. * - * Add a legacy QOM property to @dev for qdev property @prop. + * Add a legacy QOM property to @oc for qdev property @prop. * On error, store error in @errp. * * Legacy properties are string versions of QOM properties. The format of @@ -754,8 +754,8 @@ static void qdev_get_legacy_property(Object *obj, Visitor *v, * Do not use this is new code! QOM Properties added through this interface * will be given names in the "legacy" namespace. */ -static void qdev_property_add_legacy(DeviceState *dev, Property *prop, - Error **errp) +static void qdev_class_property_add_legacy(ObjectClass *oc, Property *prop, + Error **errp) { gchar *name; @@ -765,11 +765,12 @@ static void qdev_property_add_legacy(DeviceState *dev, Property *prop, } name = g_strdup_printf("legacy-%s", prop->name); -object_property_add(OBJECT(dev), name, "str", -prop->info->print ? qdev_get_legacy_property : prop->info->get, -NULL, -NULL, -prop, errp); +object_class_property_add(oc, name, "str", + prop->info->print ? + qdev_get_legacy_property : + prop->info->get, + NULL, NULL, + prop, errp); g_free(name); } @@ -844,6 +845,48 @@ void qdev_property_add_static(DeviceState *dev, Property *prop, qdev_property_set_to_default(dev, prop, &error_abort); } +/** + * qdev_class_property_add_static: + * @oc: Class to add the property to. + * @prop: The qdev property definition. + * @errp: location to store error information. + * + * Add a static QOM property to @oc for qdev property @prop. + * On error, store error in @errp. Static properties access data in a struct. + * The type of the QOM property is derived from prop->info. + */ +static void qdev_class_property_add_static(ObjectClass *oc, Property *prop, + Error **errp) +{ +Error *local_err = NULL; + +/* + * TODO qdev_prop_ptr does not have getters or setters. It must + * go now that it can be replaced with links. The test should be + * removed along with it: all static properties are read/write. + */ +if (!prop->info->get && !prop->info->set) { +return; +} + +/* Note: prop->info->release is called on device_finalize(), + * because it needs to be called on instaqnce destruction, not on + * class property removal. + */ +object_class_property_add(oc, prop->name, prop->info->name, + prop->info->get, prop->info->set, + NULL, prop, &local_err); + +if (local_err) { +error_propagate(errp, local_err); +return; +} + +object_class_property_set_description(oc, prop->name, + prop->info->description, + &error_abort); +} + /* @qdev_alias_all_properties - Add alias properties to the source object for * all qdev properties on the target DeviceState. */ @@ -867,8 +910,15 @@ void qdev_alias_all_properties(DeviceState *target, Object *source) void device_class_set_props(DeviceClass *dc, Property *props) { +Property *prop; +ObjectClass *oc = OBJECT_CLASS(dc); + assert(!dc->props); dc->props = props; +for (prop = dc->pr
[Qemu-devel] [PATCH v4 1/8] tests: check-qom-proplist: Remove duplicate "bv" property
The object_property_add_bool() call in dummy_init() is always failing because there is an existing "bv" class property. We need to remove either the "bv" class property or the "bv" instance property. Remove the class property so both object properties and class properties are covered by the test code. Reviewed-by: Igor Mammedov Signed-off-by: Eduardo Habkost --- Changes series v2 -> v3: * Patch imported from "tests: A few check-qom-proplist fixes" series * Reworded commit message for clarity Changes series v3 -> v4: * (none) --- tests/check-qom-proplist.c | 4 1 file changed, 4 deletions(-) diff --git a/tests/check-qom-proplist.c b/tests/check-qom-proplist.c index a16cefc..693dc4c 100644 --- a/tests/check-qom-proplist.c +++ b/tests/check-qom-proplist.c @@ -129,10 +129,6 @@ static void dummy_init(Object *obj) static void dummy_class_init(ObjectClass *cls, void *data) { -object_class_property_add_bool(cls, "bv", - dummy_get_bv, - dummy_set_bv, - NULL); object_class_property_add_str(cls, "sv", dummy_get_sv, dummy_set_sv, -- 2.7.4
[Qemu-devel] [PATCH v4 2/8] tests: check-qom-proplist: Use &error_abort to catch errors
Use &error_abort so we don't ignore any errors on the property registration calls. Signed-off-by: Eduardo Habkost --- Changes series v2 -> v3: * Patch imported from "tests: A few check-qom-proplist fixes" series Changes series v3 -> v4: * Added &error_abort to more object_property_{add,del}_*() calls * Suggested-by: Igor Mammedov --- tests/check-qom-proplist.c | 14 +++--- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/tests/check-qom-proplist.c b/tests/check-qom-proplist.c index 693dc4c..766a4a1 100644 --- a/tests/check-qom-proplist.c +++ b/tests/check-qom-proplist.c @@ -123,7 +123,7 @@ static void dummy_init(Object *obj) object_property_add_bool(obj, "bv", dummy_get_bv, dummy_set_bv, - NULL); + &error_abort); } @@ -132,13 +132,13 @@ static void dummy_class_init(ObjectClass *cls, void *data) object_class_property_add_str(cls, "sv", dummy_get_sv, dummy_set_sv, - NULL); + &error_abort); object_class_property_add_enum(cls, "av", "DummyAnimal", dummy_animal_map, dummy_get_av, dummy_set_av, - NULL); + &error_abort); } @@ -239,13 +239,13 @@ static void dummy_dev_init(Object *obj) DummyBus *bus = DUMMY_BUS(object_new(TYPE_DUMMY_BUS)); DummyBackend *backend = DUMMY_BACKEND(object_new(TYPE_DUMMY_BACKEND)); -object_property_add_child(obj, "bus", OBJECT(bus), NULL); +object_property_add_child(obj, "bus", OBJECT(bus), &error_abort); dev->bus = bus; -object_property_add_child(OBJECT(bus), "backend", OBJECT(backend), NULL); +object_property_add_child(OBJECT(bus), "backend", OBJECT(backend), &error_abort); bus->backend = backend; object_property_add_link(obj, "backend", TYPE_DUMMY_BACKEND, - (Object **)&bus->backend, NULL, 0, NULL); + (Object **)&bus->backend, NULL, 0, &error_abort); } static void dummy_dev_unparent(Object *obj) @@ -274,7 +274,7 @@ static void dummy_bus_init(Object *obj) static void dummy_bus_unparent(Object *obj) { DummyBus *bus = DUMMY_BUS(obj); -object_property_del(obj->parent, "backend", NULL); +object_property_del(obj->parent, "backend", &error_abort); object_unparent(OBJECT(bus->backend)); } -- 2.7.4
[Qemu-devel] [PULL 12/13] xen: Rename xen_be_find_xendev
From: Emil Condrea Prepare xen_be_find_xendev to be shared with frontends: * xen_be_find_xendev -> xen_pv_find_xendev Signed-off-by: Emil Condrea Signed-off-by: Stefano Stabellini Signed-off-by: Quan Xu Acked-by: Anthony PERARD --- hw/display/xenfb.c | 4 ++-- hw/xen/xen_backend.c | 2 +- hw/xen/xen_pvdev.c | 2 +- include/hw/xen/xen_pvdev.h | 2 +- 4 files changed, 5 insertions(+), 5 deletions(-) diff --git a/hw/display/xenfb.c b/hw/display/xenfb.c index 184e735..7a8727a 100644 --- a/hw/display/xenfb.c +++ b/hw/display/xenfb.c @@ -988,8 +988,8 @@ void xen_init_display(int domid) wait_more: i++; main_loop_wait(true); -xfb = xen_be_find_xendev("vfb", domid, 0); -xin = xen_be_find_xendev("vkbd", domid, 0); +xfb = xen_pv_find_xendev("vfb", domid, 0); +xin = xen_pv_find_xendev("vkbd", domid, 0); if (!xfb || !xin) { if (i < 256) { usleep(1); diff --git a/hw/xen/xen_backend.c b/hw/xen/xen_backend.c index f594dba..98fcb77 100644 --- a/hw/xen/xen_backend.c +++ b/hw/xen/xen_backend.c @@ -114,7 +114,7 @@ static struct XenDevice *xen_be_get_xendev(const char *type, int dom, int dev, { struct XenDevice *xendev; -xendev = xen_be_find_xendev(type, dom, dev); +xendev = xen_pv_find_xendev(type, dom, dev); if (xendev) { return xendev; } diff --git a/hw/xen/xen_pvdev.c b/hw/xen/xen_pvdev.c index 28acf61..af29150 100644 --- a/hw/xen/xen_pvdev.c +++ b/hw/xen/xen_pvdev.c @@ -264,7 +264,7 @@ int xen_pv_send_notify(struct XenDevice *xendev) /* - */ -struct XenDevice *xen_be_find_xendev(const char *type, int dom, int dev) +struct XenDevice *xen_pv_find_xendev(const char *type, int dom, int dev) { struct XenDevice *xendev; diff --git a/include/hw/xen/xen_pvdev.h b/include/hw/xen/xen_pvdev.h index caf1edc..4b1cc60 100644 --- a/include/hw/xen/xen_pvdev.h +++ b/include/hw/xen/xen_pvdev.h @@ -67,7 +67,7 @@ const char *xenbus_strstate(enum xenbus_state state); void xen_pv_evtchn_event(void *opaque); void xen_pv_insert_xendev(struct XenDevice *xendev); void xen_be_del_xendev(struct XenDevice *xendev); -struct XenDevice *xen_be_find_xendev(const char *type, int dom, int dev); +struct XenDevice *xen_pv_find_xendev(const char *type, int dom, int dev); void xen_pv_unbind_evtchn(struct XenDevice *xendev); int xen_pv_send_notify(struct XenDevice *xendev); -- 1.9.1
[Qemu-devel] [PULL 08/13] xen: Rename xen_be_printf to xen_pv_printf
From: Emil Condrea Prepare xen_be_printf to be used by both backend and frontends: * xen_be_printf -> xen_pv_printf Signed-off-by: Emil Condrea Signed-off-by: Stefano Stabellini Signed-off-by: Quan Xu Acked-by: Anthony PERARD --- hw/block/xen_disk.c| 58 +++--- hw/char/xen_console.c | 8 +++ hw/display/xenfb.c | 42 - hw/net/xen_nic.c | 22 +- hw/usb/xen-usb.c | 38 +++--- hw/xen/xen_backend.c | 46 ++-- hw/xen/xen_devconfig.c | 4 ++-- hw/xen/xen_pvdev.c | 10 include/hw/xen/xen_pvdev.h | 2 +- xen-common.c | 4 ++-- 10 files changed, 117 insertions(+), 117 deletions(-) diff --git a/hw/block/xen_disk.c b/hw/block/xen_disk.c index 5b037e7..6145567 100644 --- a/hw/block/xen_disk.c +++ b/hw/block/xen_disk.c @@ -167,12 +167,12 @@ static void destroy_grant(gpointer pgnt) xengnttab_handle *gnt = grant->blkdev->xendev.gnttabdev; if (xengnttab_unmap(gnt, grant->page, 1) != 0) { -xen_be_printf(&grant->blkdev->xendev, 0, +xen_pv_printf(&grant->blkdev->xendev, 0, "xengnttab_unmap failed: %s\n", strerror(errno)); } grant->blkdev->persistent_gnt_count--; -xen_be_printf(&grant->blkdev->xendev, 3, +xen_pv_printf(&grant->blkdev->xendev, 3, "unmapped grant %p\n", grant->page); g_free(grant); } @@ -184,11 +184,11 @@ static void remove_persistent_region(gpointer data, gpointer dev) xengnttab_handle *gnt = blkdev->xendev.gnttabdev; if (xengnttab_unmap(gnt, region->addr, region->num) != 0) { -xen_be_printf(&blkdev->xendev, 0, +xen_pv_printf(&blkdev->xendev, 0, "xengnttab_unmap region %p failed: %s\n", region->addr, strerror(errno)); } -xen_be_printf(&blkdev->xendev, 3, +xen_pv_printf(&blkdev->xendev, 3, "unmapped grant region %p with %d pages\n", region->addr, region->num); g_free(region); @@ -255,7 +255,7 @@ static int ioreq_parse(struct ioreq *ioreq) size_t len; int i; -xen_be_printf(&blkdev->xendev, 3, +xen_pv_printf(&blkdev->xendev, 3, "op %d, nr %d, handle %d, id %" PRId64 ", sector %" PRId64 "\n", ioreq->req.operation, ioreq->req.nr_segments, ioreq->req.handle, ioreq->req.id, ioreq->req.sector_number); @@ -275,28 +275,28 @@ static int ioreq_parse(struct ioreq *ioreq) case BLKIF_OP_DISCARD: return 0; default: -xen_be_printf(&blkdev->xendev, 0, "error: unknown operation (%d)\n", +xen_pv_printf(&blkdev->xendev, 0, "error: unknown operation (%d)\n", ioreq->req.operation); goto err; }; if (ioreq->req.operation != BLKIF_OP_READ && blkdev->mode[0] != 'w') { -xen_be_printf(&blkdev->xendev, 0, "error: write req for ro device\n"); +xen_pv_printf(&blkdev->xendev, 0, "error: write req for ro device\n"); goto err; } ioreq->start = ioreq->req.sector_number * blkdev->file_blk; for (i = 0; i < ioreq->req.nr_segments; i++) { if (i == BLKIF_MAX_SEGMENTS_PER_REQUEST) { -xen_be_printf(&blkdev->xendev, 0, "error: nr_segments too big\n"); +xen_pv_printf(&blkdev->xendev, 0, "error: nr_segments too big\n"); goto err; } if (ioreq->req.seg[i].first_sect > ioreq->req.seg[i].last_sect) { -xen_be_printf(&blkdev->xendev, 0, "error: first > last sector\n"); +xen_pv_printf(&blkdev->xendev, 0, "error: first > last sector\n"); goto err; } if (ioreq->req.seg[i].last_sect * BLOCK_SIZE >= XC_PAGE_SIZE) { -xen_be_printf(&blkdev->xendev, 0, "error: page crossing\n"); +xen_pv_printf(&blkdev->xendev, 0, "error: page crossing\n"); goto err; } @@ -308,7 +308,7 @@ static int ioreq_parse(struct ioreq *ioreq) qemu_iovec_add(&ioreq->v, (void*)mem, len); } if (ioreq->start + ioreq->v.size > blkdev->file_size) { -xen_be_printf(&blkdev->xendev, 0, "error: access beyond end of file\n"); +xen_pv_printf(&blkdev->xendev, 0, "error: access beyond end of file\n"); goto err; } return 0; @@ -331,7 +331,7 @@ static void ioreq_unmap(struct ioreq *ioreq) return; } if (xengnttab_unmap(gnt, ioreq->pages, ioreq->num_unmap) != 0) { -xen_be_printf(&ioreq->blkdev->xendev, 0, +xen_pv_printf(&ioreq->blkdev->xendev, 0, "xengnttab_unmap failed: %s\n", strerror(errno)); } @@ -343,7 +343,7 @@ static void ioreq_unmap(struct ioreq *ioreq) continue; }
[Qemu-devel] [PULL 13/13] xen: Rename xen_be_del_xendev
From: Emil Condrea Prepare xen_be_del_xendev to be shared with frontends: * xen_be_del_xendev -> xen_pv_del_xendev Signed-off-by: Emil Condrea Signed-off-by: Stefano Stabellini Signed-off-by: Quan Xu Acked-by: Anthony PERARD --- hw/xen/xen_backend.c | 2 +- hw/xen/xen_pvdev.c | 2 +- include/hw/xen/xen_pvdev.h | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/hw/xen/xen_backend.c b/hw/xen/xen_backend.c index 98fcb77..41ba5c5 100644 --- a/hw/xen/xen_backend.c +++ b/hw/xen/xen_backend.c @@ -483,7 +483,7 @@ void xenstore_update_be(char *watch, char *type, int dom, if (xendev != NULL) { bepath = xs_read(xenstore, 0, xendev->be, &len); if (bepath == NULL) { -xen_be_del_xendev(xendev); +xen_pv_del_xendev(xendev); } else { free(bepath); xen_be_backend_changed(xendev, path); diff --git a/hw/xen/xen_pvdev.c b/hw/xen/xen_pvdev.c index af29150..405e154 100644 --- a/hw/xen/xen_pvdev.c +++ b/hw/xen/xen_pvdev.c @@ -286,7 +286,7 @@ struct XenDevice *xen_pv_find_xendev(const char *type, int dom, int dev) /* * release xen backend device. */ -void xen_be_del_xendev(struct XenDevice *xendev) +void xen_pv_del_xendev(struct XenDevice *xendev) { if (xendev->ops->free) { xendev->ops->free(xendev); diff --git a/include/hw/xen/xen_pvdev.h b/include/hw/xen/xen_pvdev.h index 4b1cc60..083f0a9 100644 --- a/include/hw/xen/xen_pvdev.h +++ b/include/hw/xen/xen_pvdev.h @@ -66,7 +66,7 @@ const char *xenbus_strstate(enum xenbus_state state); void xen_pv_evtchn_event(void *opaque); void xen_pv_insert_xendev(struct XenDevice *xendev); -void xen_be_del_xendev(struct XenDevice *xendev); +void xen_pv_del_xendev(struct XenDevice *xendev); struct XenDevice *xen_pv_find_xendev(const char *type, int dom, int dev); void xen_pv_unbind_evtchn(struct XenDevice *xendev); -- 1.9.1
[Qemu-devel] [PULL 10/13] xen: Rename xen_be_send_notify
From: Emil Condrea Prepare xen_be_send_notify to be shared with frontends: * xen_be_send_notify -> xen_pv_send_notify Signed-off-by: Emil Condrea Signed-off-by: Stefano Stabellini Signed-off-by: Quan Xu Acked-by: Anthony PERARD --- hw/block/xen_disk.c| 4 ++-- hw/char/xen_console.c | 4 ++-- hw/display/xenfb.c | 8 hw/net/xen_nic.c | 4 ++-- hw/usb/xen-usb.c | 6 +++--- hw/xen/xen_pvdev.c | 2 +- include/hw/xen/xen_pvdev.h | 2 +- 7 files changed, 15 insertions(+), 15 deletions(-) diff --git a/hw/block/xen_disk.c b/hw/block/xen_disk.c index 8f7fe41..3a7dc19 100644 --- a/hw/block/xen_disk.c +++ b/hw/block/xen_disk.c @@ -796,7 +796,7 @@ static void blk_send_response_all(struct XenBlkDev *blkdev) ioreq_release(ioreq, true); } if (send_notify) { -xen_be_send_notify(&blkdev->xendev); +xen_pv_send_notify(&blkdev->xendev); } } @@ -866,7 +866,7 @@ static void blk_handle_requests(struct XenBlkDev *blkdev) }; if (blk_send_response_one(ioreq)) { -xen_be_send_notify(&blkdev->xendev); +xen_pv_send_notify(&blkdev->xendev); } ioreq_release(ioreq, false); continue; diff --git a/hw/char/xen_console.c b/hw/char/xen_console.c index 15463dc..c01f410 100644 --- a/hw/char/xen_console.c +++ b/hw/char/xen_console.c @@ -74,7 +74,7 @@ static void buffer_append(struct XenConsole *con) xen_mb(); intf->out_cons = cons; -xen_be_send_notify(&con->xendev); +xen_pv_send_notify(&con->xendev); if (buffer->max_capacity && buffer->size > buffer->max_capacity) { @@ -142,7 +142,7 @@ static void xencons_receive(void *opaque, const uint8_t *buf, int len) } xen_wmb(); intf->in_prod = prod; -xen_be_send_notify(&con->xendev); +xen_pv_send_notify(&con->xendev); } static void xencons_send(struct XenConsole *con) diff --git a/hw/display/xenfb.c b/hw/display/xenfb.c index 1077575..184e735 100644 --- a/hw/display/xenfb.c +++ b/hw/display/xenfb.c @@ -215,7 +215,7 @@ static int xenfb_kbd_event(struct XenInput *xenfb, XENKBD_IN_RING_REF(page, prod) = *event; xen_wmb(); /* ensure ring contents visible */ page->in_prod = prod + 1; -return xen_be_send_notify(&xenfb->c.xendev); +return xen_pv_send_notify(&xenfb->c.xendev); } /* Send a keyboard (or mouse button) event */ @@ -397,7 +397,7 @@ static void input_event(struct XenDevice *xendev) if (page->out_prod == page->out_cons) return; page->out_cons = page->out_prod; -xen_be_send_notify(&xenfb->c.xendev); +xen_pv_send_notify(&xenfb->c.xendev); } /* */ @@ -672,7 +672,7 @@ static void xenfb_send_event(struct XenFB *xenfb, union xenfb_in_event *event) xen_wmb(); /* ensure ring contents visible */ page->in_prod = prod + 1; -xen_be_send_notify(&xenfb->c.xendev); +xen_pv_send_notify(&xenfb->c.xendev); } static void xenfb_send_refresh_period(struct XenFB *xenfb, int period) @@ -945,7 +945,7 @@ static void fb_event(struct XenDevice *xendev) struct XenFB *xenfb = container_of(xendev, struct XenFB, c.xendev); xenfb_handle_events(xenfb); -xen_be_send_notify(&xenfb->c.xendev); +xen_pv_send_notify(&xenfb->c.xendev); } /* */ diff --git a/hw/net/xen_nic.c b/hw/net/xen_nic.c index c996684..20c43a6 100644 --- a/hw/net/xen_nic.c +++ b/hw/net/xen_nic.c @@ -69,7 +69,7 @@ static void net_tx_response(struct XenNetDev *netdev, netif_tx_request_t *txp, i netdev->tx_ring.rsp_prod_pvt = ++i; RING_PUSH_RESPONSES_AND_CHECK_NOTIFY(&netdev->tx_ring, notify); if (notify) { -xen_be_send_notify(&netdev->xendev); +xen_pv_send_notify(&netdev->xendev); } if (i == netdev->tx_ring.req_cons) { @@ -221,7 +221,7 @@ static void net_rx_response(struct XenNetDev *netdev, netdev->rx_ring.rsp_prod_pvt = ++i; RING_PUSH_RESPONSES_AND_CHECK_NOTIFY(&netdev->rx_ring, notify); if (notify) { -xen_be_send_notify(&netdev->xendev); +xen_pv_send_notify(&netdev->xendev); } } diff --git a/hw/usb/xen-usb.c b/hw/usb/xen-usb.c index 4ae9b6a..1b3c2fb 100644 --- a/hw/usb/xen-usb.c +++ b/hw/usb/xen-usb.c @@ -314,7 +314,7 @@ static void usbback_do_response(struct usbback_req *usbback_req, int32_t status, RING_PUSH_RESPONSES_AND_CHECK_NOTIFY(&usbif->urb_ring, notify); if (notify) { -xen_be_send_notify(xendev); +xen_pv_send_notify(xendev); } } @@ -590,7 +590,7 @@ static void usbback_hotplug_notify(struct usbback_info *usbif) /* Check for full ring. */ if ((RING_SIZE(ring) - ring->rsp_prod_pvt - ring->req_cons) == 0) { -xen_be_send_notify(&usbif->xendev); +xen_pv_send_notify(&us
[Qemu-devel] [PULL 11/13] xen: Rename xen_be_evtchn_event
From: Emil Condrea Prepare xen_be_evtchn_event to be shared with frontends: * xen_be_evtchn_event -> xen_pv_evtchn_event Signed-off-by: Emil Condrea Signed-off-by: Stefano Stabellini Signed-off-by: Quan Xu Acked-by: Anthony PERARD --- hw/xen/xen_backend.c | 2 +- hw/xen/xen_pvdev.c | 2 +- include/hw/xen/xen_pvdev.h | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/hw/xen/xen_backend.c b/hw/xen/xen_backend.c index e960dad..f594dba 100644 --- a/hw/xen/xen_backend.c +++ b/hw/xen/xen_backend.c @@ -581,7 +581,7 @@ int xen_be_bind_evtchn(struct XenDevice *xendev) } xen_pv_printf(xendev, 2, "bind evtchn port %d\n", xendev->local_port); qemu_set_fd_handler(xenevtchn_fd(xendev->evtchndev), -xen_be_evtchn_event, NULL, xendev); +xen_pv_evtchn_event, NULL, xendev); return 0; } diff --git a/hw/xen/xen_pvdev.c b/hw/xen/xen_pvdev.c index 8c7e3f5..28acf61 100644 --- a/hw/xen/xen_pvdev.c +++ b/hw/xen/xen_pvdev.c @@ -227,7 +227,7 @@ void xen_pv_printf(struct XenDevice *xendev, int msg_level, qemu_log_flush(); } -void xen_be_evtchn_event(void *opaque) +void xen_pv_evtchn_event(void *opaque) { struct XenDevice *xendev = opaque; evtchn_port_t port; diff --git a/include/hw/xen/xen_pvdev.h b/include/hw/xen/xen_pvdev.h index 2e5d6e1..caf1edc 100644 --- a/include/hw/xen/xen_pvdev.h +++ b/include/hw/xen/xen_pvdev.h @@ -64,7 +64,7 @@ void xenstore_update(void *unused); const char *xenbus_strstate(enum xenbus_state state); -void xen_be_evtchn_event(void *opaque); +void xen_pv_evtchn_event(void *opaque); void xen_pv_insert_xendev(struct XenDevice *xendev); void xen_be_del_xendev(struct XenDevice *xendev); struct XenDevice *xen_be_find_xendev(const char *type, int dom, int dev); -- 1.9.1
[Qemu-devel] [PULL 05/13] xen: Move evtchn functions to xen_pvdev.c
From: Emil Condrea The name of the functions moved: * xen_be_evtchn_event * xen_be_unbind_evtchn * xen_be_send_notify Signed-off-by: Emil Condrea Signed-off-by: Stefano Stabellini Signed-off-by: Quan Xu Acked-by: Anthony PERARD --- hw/xen/xen_backend.c | 35 --- hw/xen/xen_pvdev.c | 35 +++ include/hw/xen/xen_backend.h | 2 -- include/hw/xen/xen_pvdev.h | 4 4 files changed, 39 insertions(+), 37 deletions(-) diff --git a/hw/xen/xen_backend.c b/hw/xen/xen_backend.c index e3a7d95..1487db2 100644 --- a/hw/xen/xen_backend.c +++ b/hw/xen/xen_backend.c @@ -607,25 +607,6 @@ void xenstore_update_fe(char *watch, struct XenDevice *xendev) xen_be_frontend_changed(xendev, node); xen_be_check_state(xendev); } -static void xen_be_evtchn_event(void *opaque) -{ -struct XenDevice *xendev = opaque; -evtchn_port_t port; - -port = xenevtchn_pending(xendev->evtchndev); -if (port != xendev->local_port) { -xen_be_printf(xendev, 0, - "xenevtchn_pending returned %d (expected %d)\n", - port, xendev->local_port); -return; -} -xenevtchn_unmask(xendev->evtchndev, port); - -if (xendev->ops->event) { -xendev->ops->event(xendev); -} -} - /* */ int xen_be_init(void) @@ -702,22 +683,6 @@ int xen_be_bind_evtchn(struct XenDevice *xendev) return 0; } -void xen_be_unbind_evtchn(struct XenDevice *xendev) -{ -if (xendev->local_port == -1) { -return; -} -qemu_set_fd_handler(xenevtchn_fd(xendev->evtchndev), NULL, NULL, NULL); -xenevtchn_unbind(xendev->evtchndev, xendev->local_port); -xen_be_printf(xendev, 2, "unbind evtchn port %d\n", xendev->local_port); -xendev->local_port = -1; -} - -int xen_be_send_notify(struct XenDevice *xendev) -{ -return xenevtchn_notify(xendev->evtchndev, xendev->local_port); -} - static int xen_sysdev_init(SysBusDevice *dev) { diff --git a/hw/xen/xen_pvdev.c b/hw/xen/xen_pvdev.c index 22a1abe..7607e44 100644 --- a/hw/xen/xen_pvdev.c +++ b/hw/xen/xen_pvdev.c @@ -171,3 +171,38 @@ void xen_be_printf(struct XenDevice *xendev, int msg_level, } qemu_log_flush(); } + +void xen_be_evtchn_event(void *opaque) +{ +struct XenDevice *xendev = opaque; +evtchn_port_t port; + +port = xenevtchn_pending(xendev->evtchndev); +if (port != xendev->local_port) { +xen_be_printf(xendev, 0, + "xenevtchn_pending returned %d (expected %d)\n", + port, xendev->local_port); +return; +} +xenevtchn_unmask(xendev->evtchndev, port); + +if (xendev->ops->event) { +xendev->ops->event(xendev); +} +} + +void xen_be_unbind_evtchn(struct XenDevice *xendev) +{ +if (xendev->local_port == -1) { +return; +} +qemu_set_fd_handler(xenevtchn_fd(xendev->evtchndev), NULL, NULL, NULL); +xenevtchn_unbind(xendev->evtchndev, xendev->local_port); +xen_be_printf(xendev, 2, "unbind evtchn port %d\n", xendev->local_port); +xendev->local_port = -1; +} + +int xen_be_send_notify(struct XenDevice *xendev) +{ +return xenevtchn_notify(xendev->evtchndev, xendev->local_port); +} diff --git a/include/hw/xen/xen_backend.h b/include/hw/xen/xen_backend.h index 2e54150..6c617d9 100644 --- a/include/hw/xen/xen_backend.h +++ b/include/hw/xen/xen_backend.h @@ -36,8 +36,6 @@ void xen_be_register_common(void); int xen_be_register(const char *type, struct XenDevOps *ops); int xen_be_set_state(struct XenDevice *xendev, enum xenbus_state state); int xen_be_bind_evtchn(struct XenDevice *xendev); -void xen_be_unbind_evtchn(struct XenDevice *xendev); -int xen_be_send_notify(struct XenDevice *xendev); /* actual backend drivers */ extern struct XenDevOps xen_console_ops; /* xen_console.c */ diff --git a/include/hw/xen/xen_pvdev.h b/include/hw/xen/xen_pvdev.h index 3c4cc01..a8da3da 100644 --- a/include/hw/xen/xen_pvdev.h +++ b/include/hw/xen/xen_pvdev.h @@ -64,6 +64,10 @@ void xenstore_update(void *unused); const char *xenbus_strstate(enum xenbus_state state); +void xen_be_evtchn_event(void *opaque); +void xen_be_unbind_evtchn(struct XenDevice *xendev); +int xen_be_send_notify(struct XenDevice *xendev); + void xen_be_printf(struct XenDevice *xendev, int msg_level, const char *fmt, ...) GCC_FMT_ATTR(3, 4); -- 1.9.1
[Qemu-devel] [PULL 06/13] xen: Prepare xendev qtail to be shared with frontends
From: Emil Condrea * move xendevs qtail to xen_pvdev.c * change xen_be_get_xendev to use a new function: xen_pv_insert_xendev Signed-off-by: Emil Condrea Signed-off-by: Stefano Stabellini Signed-off-by: Quan Xu Acked-by: Anthony PERARD --- hw/xen/xen_backend.c | 51 +-- hw/xen/xen_pvdev.c | 57 include/hw/xen/xen_backend.h | 1 - include/hw/xen/xen_pvdev.h | 4 4 files changed, 62 insertions(+), 51 deletions(-) diff --git a/hw/xen/xen_backend.c b/hw/xen/xen_backend.c index 1487db2..2875e7c 100644 --- a/hw/xen/xen_backend.c +++ b/hw/xen/xen_backend.c @@ -54,8 +54,6 @@ struct xs_dirs { static QTAILQ_HEAD(xs_dirs_head, xs_dirs) xs_cleanup = QTAILQ_HEAD_INITIALIZER(xs_cleanup); -static QTAILQ_HEAD(XenDeviceHead, XenDevice) xendevs = -QTAILQ_HEAD_INITIALIZER(xendevs); static int debug; static void xenstore_cleanup_dir(char *dir) @@ -157,27 +155,6 @@ int xen_be_set_state(struct XenDevice *xendev, enum xenbus_state state) return 0; } -/* - */ - -struct XenDevice *xen_be_find_xendev(const char *type, int dom, int dev) -{ -struct XenDevice *xendev; - -QTAILQ_FOREACH(xendev, &xendevs, next) { -if (xendev->dom != dom) { -continue; -} -if (xendev->dev != dev) { -continue; -} -if (strcmp(xendev->type, type) != 0) { -continue; -} -return xendev; -} -return NULL; -} - /* * get xen backend device, allocate a new one if it doesn't exist. */ @@ -226,7 +203,7 @@ static struct XenDevice *xen_be_get_xendev(const char *type, int dom, int dev, xendev->gnttabdev = NULL; } -QTAILQ_INSERT_TAIL(&xendevs, xendev, next); +xen_pv_insert_xendev(xendev); if (xendev->ops->alloc) { xendev->ops->alloc(xendev); @@ -235,32 +212,6 @@ static struct XenDevice *xen_be_get_xendev(const char *type, int dom, int dev, return xendev; } -/* - * release xen backend device. - */ -static void xen_be_del_xendev(struct XenDevice *xendev) -{ -if (xendev->ops->free) { -xendev->ops->free(xendev); -} - -if (xendev->fe) { -char token[XEN_BUFSIZE]; -snprintf(token, sizeof(token), "fe:%p", xendev); -xs_unwatch(xenstore, xendev->fe, token); -g_free(xendev->fe); -} - -if (xendev->evtchndev != NULL) { -xenevtchn_close(xendev->evtchndev); -} -if (xendev->gnttabdev != NULL) { -xengnttab_close(xendev->gnttabdev); -} - -QTAILQ_REMOVE(&xendevs, xendev, next); -g_free(xendev); -} /* * Sync internal data structures on xenstore updates. diff --git a/hw/xen/xen_pvdev.c b/hw/xen/xen_pvdev.c index 7607e44..96ed2a3 100644 --- a/hw/xen/xen_pvdev.c +++ b/hw/xen/xen_pvdev.c @@ -22,7 +22,11 @@ #include "hw/xen/xen_backend.h" #include "hw/xen/xen_pvdev.h" +/* private */ static int debug; +static QTAILQ_HEAD(XenDeviceHead, XenDevice) xendevs = +QTAILQ_HEAD_INITIALIZER(xendevs); + /* - */ int xenstore_write_str(const char *base, const char *node, const char *val) @@ -206,3 +210,56 @@ int xen_be_send_notify(struct XenDevice *xendev) { return xenevtchn_notify(xendev->evtchndev, xendev->local_port); } + +/* - */ + +struct XenDevice *xen_be_find_xendev(const char *type, int dom, int dev) +{ +struct XenDevice *xendev; + +QTAILQ_FOREACH(xendev, &xendevs, next) { +if (xendev->dom != dom) { +continue; +} +if (xendev->dev != dev) { +continue; +} +if (strcmp(xendev->type, type) != 0) { +continue; +} +return xendev; +} +return NULL; +} + +/* + * release xen backend device. + */ +void xen_be_del_xendev(struct XenDevice *xendev) +{ +if (xendev->ops->free) { +xendev->ops->free(xendev); +} + +if (xendev->fe) { +char token[XEN_BUFSIZE]; +snprintf(token, sizeof(token), "fe:%p", xendev); +xs_unwatch(xenstore, xendev->fe, token); +g_free(xendev->fe); +} + +if (xendev->evtchndev != NULL) { +xenevtchn_close(xendev->evtchndev); +} +if (xendev->gnttabdev != NULL) { +xengnttab_close(xendev->gnttabdev); +} + +QTAILQ_REMOVE(&xendevs, xendev, next); +g_free(xendev); +} + +void xen_pv_insert_xendev(struct XenDevice *xendev) +{ +QTAILQ_INSERT_TAIL(&xendevs, xendev, next); +} diff --git a/include/hw/xen/xen_backend.h b/include/hw/xen/xen_backend.h index 6c617d9..cbda40e 100644 --- a/include/hw/xen/xen_backend.h +++ b/include/hw/xen/xen_backend.h @@ -27,7 +27,6 @@ int xenstore_read_fe_int(struct XenDevice *xendev, const char *node, int *ival); int xenstore_read_fe_uint64(struct XenDevice *xendev, const char *node,
[Qemu-devel] [PULL 07/13] xen: Move xenstore cleanup and mkdir functions
From: Emil Condrea The name of the functions moved to xen_pvdev.c: * xenstore_cleanup_dir * xen_config_cleanup * xenstore_mkdir Signed-off-by: Emil Condrea Signed-off-by: Stefano Stabellini Signed-off-by: Quan Xu Acked-by: Anthony PERARD --- hw/xen/xen_backend.c | 49 - hw/xen/xen_pvdev.c | 51 +++ 2 files changed, 51 insertions(+), 49 deletions(-) diff --git a/hw/xen/xen_backend.c b/hw/xen/xen_backend.c index 2875e7c..216072d 100644 --- a/hw/xen/xen_backend.c +++ b/hw/xen/xen_backend.c @@ -47,57 +47,8 @@ struct xs_handle *xenstore = NULL; const char *xen_protocol; /* private */ -struct xs_dirs { -char *xs_dir; -QTAILQ_ENTRY(xs_dirs) list; -}; -static QTAILQ_HEAD(xs_dirs_head, xs_dirs) xs_cleanup = -QTAILQ_HEAD_INITIALIZER(xs_cleanup); - static int debug; -static void xenstore_cleanup_dir(char *dir) -{ -struct xs_dirs *d; - -d = g_malloc(sizeof(*d)); -d->xs_dir = dir; -QTAILQ_INSERT_TAIL(&xs_cleanup, d, list); -} - -void xen_config_cleanup(void) -{ -struct xs_dirs *d; - -QTAILQ_FOREACH(d, &xs_cleanup, list) { -xs_rm(xenstore, 0, d->xs_dir); -} -} - -int xenstore_mkdir(char *path, int p) -{ -struct xs_permissions perms[2] = { -{ -.id= 0, /* set owner: dom0 */ -}, { -.id= xen_domid, -.perms = p, -} -}; - -if (!xs_mkdir(xenstore, 0, path)) { -xen_be_printf(NULL, 0, "xs_mkdir %s: failed\n", path); -return -1; -} -xenstore_cleanup_dir(g_strdup(path)); - -if (!xs_set_permissions(xenstore, 0, path, perms, 2)) { -xen_be_printf(NULL, 0, "xs_set_permissions %s: failed\n", path); -return -1; -} -return 0; -} - int xenstore_write_be_str(struct XenDevice *xendev, const char *node, const char *val) { return xenstore_write_str(xendev->be, node, val); diff --git a/hw/xen/xen_pvdev.c b/hw/xen/xen_pvdev.c index 96ed2a3..e432d30 100644 --- a/hw/xen/xen_pvdev.c +++ b/hw/xen/xen_pvdev.c @@ -24,11 +24,62 @@ /* private */ static int debug; + +struct xs_dirs { +char *xs_dir; +QTAILQ_ENTRY(xs_dirs) list; +}; + +static QTAILQ_HEAD(xs_dirs_head, xs_dirs) xs_cleanup = +QTAILQ_HEAD_INITIALIZER(xs_cleanup); + static QTAILQ_HEAD(XenDeviceHead, XenDevice) xendevs = QTAILQ_HEAD_INITIALIZER(xendevs); /* - */ +static void xenstore_cleanup_dir(char *dir) +{ +struct xs_dirs *d; + +d = g_malloc(sizeof(*d)); +d->xs_dir = dir; +QTAILQ_INSERT_TAIL(&xs_cleanup, d, list); +} + +void xen_config_cleanup(void) +{ +struct xs_dirs *d; + +QTAILQ_FOREACH(d, &xs_cleanup, list) { +xs_rm(xenstore, 0, d->xs_dir); +} +} + +int xenstore_mkdir(char *path, int p) +{ +struct xs_permissions perms[2] = { +{ +.id= 0, /* set owner: dom0 */ +}, { +.id= xen_domid, +.perms = p, +} +}; + +if (!xs_mkdir(xenstore, 0, path)) { +xen_be_printf(NULL, 0, "xs_mkdir %s: failed\n", path); +return -1; +} +xenstore_cleanup_dir(g_strdup(path)); + +if (!xs_set_permissions(xenstore, 0, path, perms, 2)) { +xen_be_printf(NULL, 0, "xs_set_permissions %s: failed\n", path); +return -1; +} +return 0; +} + int xenstore_write_str(const char *base, const char *node, const char *val) { char abspath[XEN_BUFSIZE]; -- 1.9.1
[Qemu-devel] [PULL 09/13] xen: Rename xen_be_unbind_evtchn
From: Emil Condrea Prepare xen_be_unbind_evtchn to be shared with frontends: * xen_be_unbind_evtchn -> xen_pv_unbind_evtchn Signed-off-by: Emil Condrea Signed-off-by: Stefano Stabellini Signed-off-by: Quan Xu Acked-by: Anthony PERARD --- hw/block/xen_disk.c| 2 +- hw/char/xen_console.c | 2 +- hw/display/xenfb.c | 2 +- hw/net/xen_nic.c | 2 +- hw/usb/xen-usb.c | 2 +- hw/xen/xen_pvdev.c | 2 +- include/hw/xen/xen_pvdev.h | 2 +- 7 files changed, 7 insertions(+), 7 deletions(-) diff --git a/hw/block/xen_disk.c b/hw/block/xen_disk.c index 6145567..8f7fe41 100644 --- a/hw/block/xen_disk.c +++ b/hw/block/xen_disk.c @@ -1194,7 +1194,7 @@ static void blk_disconnect(struct XenDevice *xendev) blk_unref(blkdev->blk); blkdev->blk = NULL; } -xen_be_unbind_evtchn(&blkdev->xendev); +xen_pv_unbind_evtchn(&blkdev->xendev); if (blkdev->sring) { xengnttab_unmap(blkdev->xendev.gnttabdev, blkdev->sring, 1); diff --git a/hw/char/xen_console.c b/hw/char/xen_console.c index aa7a27e..15463dc 100644 --- a/hw/char/xen_console.c +++ b/hw/char/xen_console.c @@ -262,7 +262,7 @@ static void con_disconnect(struct XenDevice *xendev) struct XenConsole *con = container_of(xendev, struct XenConsole, xendev); qemu_chr_fe_deinit(&con->chr); -xen_be_unbind_evtchn(&con->xendev); +xen_pv_unbind_evtchn(&con->xendev); if (con->sring) { if (!xendev->dev) { diff --git a/hw/display/xenfb.c b/hw/display/xenfb.c index d7b94b0..1077575 100644 --- a/hw/display/xenfb.c +++ b/hw/display/xenfb.c @@ -112,7 +112,7 @@ static int common_bind(struct common *c) static void common_unbind(struct common *c) { -xen_be_unbind_evtchn(&c->xendev); +xen_pv_unbind_evtchn(&c->xendev); if (c->page) { xenforeignmemory_unmap(xen_fmem, c->page, 1); c->page = NULL; diff --git a/hw/net/xen_nic.c b/hw/net/xen_nic.c index 2d6e033..c996684 100644 --- a/hw/net/xen_nic.c +++ b/hw/net/xen_nic.c @@ -372,7 +372,7 @@ static void net_disconnect(struct XenDevice *xendev) { struct XenNetDev *netdev = container_of(xendev, struct XenNetDev, xendev); -xen_be_unbind_evtchn(&netdev->xendev); +xen_pv_unbind_evtchn(&netdev->xendev); if (netdev->txs) { xengnttab_unmap(netdev->xendev.gnttabdev, netdev->txs, 1); diff --git a/hw/usb/xen-usb.c b/hw/usb/xen-usb.c index 6b06fd8..4ae9b6a 100644 --- a/hw/usb/xen-usb.c +++ b/hw/usb/xen-usb.c @@ -834,7 +834,7 @@ static void usbback_disconnect(struct XenDevice *xendev) usbif = container_of(xendev, struct usbback_info, xendev); -xen_be_unbind_evtchn(xendev); +xen_pv_unbind_evtchn(xendev); if (usbif->urb_sring) { xengnttab_unmap(xendev->gnttabdev, usbif->urb_sring, 1); diff --git a/hw/xen/xen_pvdev.c b/hw/xen/xen_pvdev.c index 6938c09..b362eb7 100644 --- a/hw/xen/xen_pvdev.c +++ b/hw/xen/xen_pvdev.c @@ -246,7 +246,7 @@ void xen_be_evtchn_event(void *opaque) } } -void xen_be_unbind_evtchn(struct XenDevice *xendev) +void xen_pv_unbind_evtchn(struct XenDevice *xendev) { if (xendev->local_port == -1) { return; diff --git a/include/hw/xen/xen_pvdev.h b/include/hw/xen/xen_pvdev.h index 7aedc91..1aff68c 100644 --- a/include/hw/xen/xen_pvdev.h +++ b/include/hw/xen/xen_pvdev.h @@ -69,7 +69,7 @@ void xen_pv_insert_xendev(struct XenDevice *xendev); void xen_be_del_xendev(struct XenDevice *xendev); struct XenDevice *xen_be_find_xendev(const char *type, int dom, int dev); -void xen_be_unbind_evtchn(struct XenDevice *xendev); +void xen_pv_unbind_evtchn(struct XenDevice *xendev); int xen_be_send_notify(struct XenDevice *xendev); void xen_pv_printf(struct XenDevice *xendev, int msg_level, -- 1.9.1
[Qemu-devel] [PULL 01/13] xen: Fix coding style errors
From: Emil Condrea Fixes the following errors: * ERROR: line over 90 characters * ERROR: code indent should never use tabs * ERROR: space prohibited after that open square bracket '[' * ERROR: do not initialise statics to 0 or NULL * ERROR: "(foo*)" should be "(foo *)" Signed-off-by: Emil Condrea Signed-off-by: Stefano Stabellini Signed-off-by: Quan Xu Acked-by: Anthony PERARD --- hw/char/xen_console.c | 21 ++-- hw/display/xenfb.c| 91 --- hw/net/xen_nic.c | 8 +++-- hw/xen/xen_backend.c | 20 +-- 4 files changed, 76 insertions(+), 64 deletions(-) diff --git a/hw/char/xen_console.c b/hw/char/xen_console.c index 86cdc52..d236a46 100644 --- a/hw/char/xen_console.c +++ b/hw/char/xen_console.c @@ -158,16 +158,17 @@ static void xencons_send(struct XenConsole *con) len = size; } if (len < 1) { - if (!con->backlog) { - con->backlog = 1; - xen_be_printf(&con->xendev, 1, "backlog piling up, nobody listening?\n"); - } +if (!con->backlog) { +con->backlog = 1; +xen_be_printf(&con->xendev, 1, + "backlog piling up, nobody listening?\n"); +} } else { - buffer_advance(&con->buffer, len); - if (con->backlog && len == size) { - con->backlog = 0; - xen_be_printf(&con->xendev, 1, "backlog is gone\n"); - } +buffer_advance(&con->buffer, len); +if (con->backlog && len == size) { +con->backlog = 0; +xen_be_printf(&con->xendev, 1, "backlog is gone\n"); +} } } @@ -191,7 +192,7 @@ static int con_init(struct XenDevice *xendev) type = xenstore_read_str(con->console, "type"); if (!type || strcmp(type, "ioemu") != 0) { - xen_be_printf(xendev, 1, "not for me (type=%s)\n", type); +xen_be_printf(xendev, 1, "not for me (type=%s)\n", type); ret = -1; goto out; } diff --git a/hw/display/xenfb.c b/hw/display/xenfb.c index 46b7d5e..eaa1fce 100644 --- a/hw/display/xenfb.c +++ b/hw/display/xenfb.c @@ -90,21 +90,22 @@ static int common_bind(struct common *c) xen_pfn_t mfn; if (xenstore_read_fe_uint64(&c->xendev, "page-ref", &val) == -1) - return -1; +return -1; mfn = (xen_pfn_t)val; assert(val == mfn); if (xenstore_read_fe_int(&c->xendev, "event-channel", &c->xendev.remote_port) == -1) - return -1; +return -1; c->page = xenforeignmemory_map(xen_fmem, c->xendev.dom, PROT_READ | PROT_WRITE, 1, &mfn, NULL); if (c->page == NULL) - return -1; +return -1; xen_be_bind_evtchn(&c->xendev); -xen_be_printf(&c->xendev, 1, "ring mfn %"PRI_xen_pfn", remote-port %d, local-port %d\n", - mfn, c->xendev.remote_port, c->xendev.local_port); +xen_be_printf(&c->xendev, 1, + "ring mfn %"PRI_xen_pfn", remote-port %d, local-port %d\n", + mfn, c->xendev.remote_port, c->xendev.local_port); return 0; } @@ -500,8 +501,8 @@ out: } static int xenfb_configure_fb(struct XenFB *xenfb, size_t fb_len_lim, - int width, int height, int depth, - size_t fb_len, int offset, int row_stride) + int width, int height, int depth, + size_t fb_len, int offset, int row_stride) { size_t mfn_sz = sizeof(*((struct xenfb_page *)0)->pd); size_t pd_len = sizeof(((struct xenfb_page *)0)->pd) / mfn_sz; @@ -510,40 +511,47 @@ static int xenfb_configure_fb(struct XenFB *xenfb, size_t fb_len_lim, int max_width, max_height; if (fb_len_lim > fb_len_max) { - xen_be_printf(&xenfb->c.xendev, 0, "fb size limit %zu exceeds %zu, corrected\n", - fb_len_lim, fb_len_max); - fb_len_lim = fb_len_max; +xen_be_printf(&xenfb->c.xendev, 0, + "fb size limit %zu exceeds %zu, corrected\n", + fb_len_lim, fb_len_max); +fb_len_lim = fb_len_max; } if (fb_len_lim && fb_len > fb_len_lim) { - xen_be_printf(&xenfb->c.xendev, 0, "frontend fb size %zu limited to %zu\n", - fb_len, fb_len_lim); - fb_len = fb_len_lim; +xen_be_printf(&xenfb->c.xendev, 0, + "frontend fb size %zu limited to %zu\n", + fb_len, fb_len_lim); +fb_len = fb_len_lim; } if (depth != 8 && depth != 16 && depth != 24 && depth != 32) { - xen_be_printf(&xenfb->c.xendev, 0, "can't handle frontend fb depth %d\n", - depth); - return -1; +xen_be_printf(&xenfb->c.xendev, 0, + "can't handle frontend fb depth %d\n", + depth); +return -1; } if (row_stride <= 0 || row_stride > fb_len) { - xen_be_print
[Qemu-devel] [PULL 03/13] xen: Create a new file xen_pvdev.c
From: Emil Condrea The purpose of the new file is to store generic functions shared by frontend and backends such as xenstore operations, xendevs. Signed-off-by: Quan Xu Signed-off-by: Emil Condrea Signed-off-by: Stefano Stabellini Signed-off-by: Quan Xu Acked-by: Anthony PERARD --- hw/xen/Makefile.objs | 2 +- hw/xen/xen_backend.c | 126 +--- hw/xen/xen_pvdev.c | 150 +++ include/hw/xen/xen_backend.h | 64 +- include/hw/xen/xen_pvdev.h | 69 5 files changed, 222 insertions(+), 189 deletions(-) create mode 100644 hw/xen/xen_pvdev.c create mode 100644 include/hw/xen/xen_pvdev.h diff --git a/hw/xen/Makefile.objs b/hw/xen/Makefile.objs index d367094..591cdc2 100644 --- a/hw/xen/Makefile.objs +++ b/hw/xen/Makefile.objs @@ -1,5 +1,5 @@ # xen backend driver support -common-obj-$(CONFIG_XEN_BACKEND) += xen_backend.o xen_devconfig.o +common-obj-$(CONFIG_XEN_BACKEND) += xen_backend.o xen_devconfig.o xen_pvdev.o obj-$(CONFIG_XEN_PCI_PASSTHROUGH) += xen-host-pci-device.o obj-$(CONFIG_XEN_PCI_PASSTHROUGH) += xen_pt.o xen_pt_config_init.o xen_pt_graphics.o xen_pt_msi.o diff --git a/hw/xen/xen_backend.c b/hw/xen/xen_backend.c index 0e95880..b32b0dd 100644 --- a/hw/xen/xen_backend.c +++ b/hw/xen/xen_backend.c @@ -30,6 +30,7 @@ #include "sysemu/char.h" #include "qemu/log.h" #include "hw/xen/xen_backend.h" +#include "hw/xen/xen_pvdev.h" #include @@ -57,8 +58,6 @@ static QTAILQ_HEAD(XenDeviceHead, XenDevice) xendevs = QTAILQ_HEAD_INITIALIZER(xendevs); static int debug; -/* - */ - static void xenstore_cleanup_dir(char *dir) { struct xs_dirs *d; @@ -77,34 +76,6 @@ void xen_config_cleanup(void) } } -int xenstore_write_str(const char *base, const char *node, const char *val) -{ -char abspath[XEN_BUFSIZE]; - -snprintf(abspath, sizeof(abspath), "%s/%s", base, node); -if (!xs_write(xenstore, 0, abspath, val, strlen(val))) { -return -1; -} -return 0; -} - -char *xenstore_read_str(const char *base, const char *node) -{ -char abspath[XEN_BUFSIZE]; -unsigned int len; -char *str, *ret = NULL; - -snprintf(abspath, sizeof(abspath), "%s/%s", base, node); -str = xs_read(xenstore, 0, abspath, &len); -if (str != NULL) { -/* move to qemu-allocated memory to make sure - * callers can savely g_free() stuff. */ -ret = g_strdup(str); -free(str); -} -return ret; -} - int xenstore_mkdir(char *path, int p) { struct xs_permissions perms[2] = { @@ -129,48 +100,6 @@ int xenstore_mkdir(char *path, int p) return 0; } -int xenstore_write_int(const char *base, const char *node, int ival) -{ -char val[12]; - -snprintf(val, sizeof(val), "%d", ival); -return xenstore_write_str(base, node, val); -} - -int xenstore_write_int64(const char *base, const char *node, int64_t ival) -{ -char val[21]; - -snprintf(val, sizeof(val), "%"PRId64, ival); -return xenstore_write_str(base, node, val); -} - -int xenstore_read_int(const char *base, const char *node, int *ival) -{ -char *val; -int rc = -1; - -val = xenstore_read_str(base, node); -if (val && 1 == sscanf(val, "%d", ival)) { -rc = 0; -} -g_free(val); -return rc; -} - -int xenstore_read_uint64(const char *base, const char *node, uint64_t *uval) -{ -char *val; -int rc = -1; - -val = xenstore_read_str(base, node); -if (val && 1 == sscanf(val, "%"SCNu64, uval)) { -rc = 0; -} -g_free(val); -return rc; -} - int xenstore_write_be_str(struct XenDevice *xendev, const char *node, const char *val) { return xenstore_write_str(xendev->be, node, val); @@ -214,20 +143,6 @@ int xenstore_read_fe_uint64(struct XenDevice *xendev, const char *node, /* - */ -const char *xenbus_strstate(enum xenbus_state state) -{ -static const char *const name[] = { -[XenbusStateUnknown] = "Unknown", -[XenbusStateInitialising] = "Initialising", -[XenbusStateInitWait] = "InitWait", -[XenbusStateInitialised] = "Initialised", -[XenbusStateConnected] = "Connected", -[XenbusStateClosing] = "Closing", -[XenbusStateClosed]= "Closed", -}; -return (state < ARRAY_SIZE(name)) ? name[state] : "INVALID"; -} - int xen_be_set_state(struct XenDevice *xendev, enum xenbus_state state) { int rc; @@ -827,45 +742,6 @@ int xen_be_send_notify(struct XenDevice *xendev) return xenevtchn_notify(xendev->evtchndev, xendev->local_port); } -/* - * msg_level: - * 0 == errors (stderr + logfile). - * 1 == informative debug messages (logfile only). - * 2 == noisy debug messages (logfile only). - * 3 == will flood your log (logfile only). - */ -void xen_
[Qemu-devel] [PULL 04/13] xen: Move xenstore_update to xen_pvdev.c
From: Emil Condrea * xenstore_update -> xen_pvdev.c Signed-off-by: Emil Condrea Signed-off-by: Stefano Stabellini Signed-off-by: Quan Xu Acked-by: Anthony PERARD --- hw/xen/xen_backend.c | 30 +++--- hw/xen/xen_pvdev.c | 23 +++ include/hw/xen/xen_backend.h | 3 +++ include/hw/xen/xen_pvdev.h | 1 + 4 files changed, 30 insertions(+), 27 deletions(-) diff --git a/hw/xen/xen_backend.c b/hw/xen/xen_backend.c index b32b0dd..e3a7d95 100644 --- a/hw/xen/xen_backend.c +++ b/hw/xen/xen_backend.c @@ -556,8 +556,8 @@ static int xenstore_scan(const char *type, int dom, struct XenDevOps *ops) return 0; } -static void xenstore_update_be(char *watch, char *type, int dom, - struct XenDevOps *ops) +void xenstore_update_be(char *watch, char *type, int dom, +struct XenDevOps *ops) { struct XenDevice *xendev; char path[XEN_BUFSIZE], *bepath; @@ -590,7 +590,7 @@ static void xenstore_update_be(char *watch, char *type, int dom, } } -static void xenstore_update_fe(char *watch, struct XenDevice *xendev) +void xenstore_update_fe(char *watch, struct XenDevice *xendev) { char *node; unsigned int len; @@ -607,30 +607,6 @@ static void xenstore_update_fe(char *watch, struct XenDevice *xendev) xen_be_frontend_changed(xendev, node); xen_be_check_state(xendev); } - -static void xenstore_update(void *unused) -{ -char **vec = NULL; -intptr_t type, ops, ptr; -unsigned int dom, count; - -vec = xs_read_watch(xenstore, &count); -if (vec == NULL) { -goto cleanup; -} - -if (sscanf(vec[XS_WATCH_TOKEN], "be:%" PRIxPTR ":%d:%" PRIxPTR, - &type, &dom, &ops) == 3) { -xenstore_update_be(vec[XS_WATCH_PATH], (void *)type, dom, (void*)ops); -} -if (sscanf(vec[XS_WATCH_TOKEN], "fe:%" PRIxPTR, &ptr) == 1) { -xenstore_update_fe(vec[XS_WATCH_PATH], (void *)ptr); -} - -cleanup: -free(vec); -} - static void xen_be_evtchn_event(void *opaque) { struct XenDevice *xendev = opaque; diff --git a/hw/xen/xen_pvdev.c b/hw/xen/xen_pvdev.c index a1dc2be..22a1abe 100644 --- a/hw/xen/xen_pvdev.c +++ b/hw/xen/xen_pvdev.c @@ -95,6 +95,29 @@ int xenstore_read_uint64(const char *base, const char *node, uint64_t *uval) return rc; } +void xenstore_update(void *unused) +{ +char **vec = NULL; +intptr_t type, ops, ptr; +unsigned int dom, count; + +vec = xs_read_watch(xenstore, &count); +if (vec == NULL) { +goto cleanup; +} + +if (sscanf(vec[XS_WATCH_TOKEN], "be:%" PRIxPTR ":%d:%" PRIxPTR, + &type, &dom, &ops) == 3) { +xenstore_update_be(vec[XS_WATCH_PATH], (void *)type, dom, (void*)ops); +} +if (sscanf(vec[XS_WATCH_TOKEN], "fe:%" PRIxPTR, &ptr) == 1) { +xenstore_update_fe(vec[XS_WATCH_PATH], (void *)ptr); +} + +cleanup: +free(vec); +} + const char *xenbus_strstate(enum xenbus_state state) { static const char *const name[] = { diff --git a/include/hw/xen/xen_backend.h b/include/hw/xen/xen_backend.h index 973cb4b..2e54150 100644 --- a/include/hw/xen/xen_backend.h +++ b/include/hw/xen/xen_backend.h @@ -19,6 +19,9 @@ int xenstore_write_be_int(struct XenDevice *xendev, const char *node, int ival); int xenstore_write_be_int64(struct XenDevice *xendev, const char *node, int64_t ival); char *xenstore_read_be_str(struct XenDevice *xendev, const char *node); int xenstore_read_be_int(struct XenDevice *xendev, const char *node, int *ival); +void xenstore_update_fe(char *watch, struct XenDevice *xendev); +void xenstore_update_be(char *watch, char *type, int dom, +struct XenDevOps *ops); char *xenstore_read_fe_str(struct XenDevice *xendev, const char *node); int xenstore_read_fe_int(struct XenDevice *xendev, const char *node, int *ival); int xenstore_read_fe_uint64(struct XenDevice *xendev, const char *node, diff --git a/include/hw/xen/xen_pvdev.h b/include/hw/xen/xen_pvdev.h index cd3d6bc..3c4cc01 100644 --- a/include/hw/xen/xen_pvdev.h +++ b/include/hw/xen/xen_pvdev.h @@ -60,6 +60,7 @@ int xenstore_write_int64(const char *base, const char *node, int64_t ival); char *xenstore_read_str(const char *base, const char *node); int xenstore_read_int(const char *base, const char *node, int *ival); int xenstore_read_uint64(const char *base, const char *node, uint64_t *uval); +void xenstore_update(void *unused); const char *xenbus_strstate(enum xenbus_state state); -- 1.9.1
[Qemu-devel] [PULL 02/13] xen: Fix coding style warnings
From: Emil Condrea Fixes: * WARNING: line over 80 characters Signed-off-by: Emil Condrea Signed-off-by: Stefano Stabellini Signed-off-by: Quan Xu Acked-by: Anthony PERARD --- hw/block/xen_disk.c | 3 ++- hw/char/xen_console.c| 3 ++- hw/display/xenfb.c | 6 -- hw/net/xen_nic.c | 12 hw/xen/xen_backend.c | 15 ++- include/hw/xen/xen_backend.h | 8 +--- 6 files changed, 31 insertions(+), 16 deletions(-) diff --git a/hw/block/xen_disk.c b/hw/block/xen_disk.c index 1292a4b..5b037e7 100644 --- a/hw/block/xen_disk.c +++ b/hw/block/xen_disk.c @@ -1068,7 +1068,8 @@ static int blk_connect(struct XenDevice *xendev) blk_set_enable_write_cache(blkdev->blk, !writethrough); } else { /* setup via qemu cmdline -> already setup for us */ -xen_be_printf(&blkdev->xendev, 2, "get configured bdrv (cmdline setup)\n"); +xen_be_printf(&blkdev->xendev, 2, + "get configured bdrv (cmdline setup)\n"); blkdev->blk = blk_by_legacy_dinfo(blkdev->dinfo); if (blk_is_read_only(blkdev->blk) && !readonly) { xen_be_printf(&blkdev->xendev, 0, "Unexpected read-only drive"); diff --git a/hw/char/xen_console.c b/hw/char/xen_console.c index d236a46..9ae9558 100644 --- a/hw/char/xen_console.c +++ b/hw/char/xen_console.c @@ -248,7 +248,8 @@ static int con_initialise(struct XenDevice *xendev) qemu_chr_fe_set_handlers(&con->chr, xencons_can_receive, xencons_receive, NULL, con, NULL, true); -xen_be_printf(xendev, 1, "ring mfn %d, remote port %d, local port %d, limit %zd\n", +xen_be_printf(xendev, 1, + "ring mfn %d, remote port %d, local port %d, limit %zd\n", con->ring_ref, con->xendev.remote_port, con->xendev.local_port, diff --git a/hw/display/xenfb.c b/hw/display/xenfb.c index eaa1fce..d458fc1 100644 --- a/hw/display/xenfb.c +++ b/hw/display/xenfb.c @@ -561,7 +561,8 @@ static int xenfb_configure_fb(struct XenFB *xenfb, size_t fb_len_lim, xenfb->offset = offset; xenfb->up_fullscreen = 1; xenfb->do_resize = 1; -xen_be_printf(&xenfb->c.xendev, 1, "framebuffer %dx%dx%d offset %d stride %d\n", +xen_be_printf(&xenfb->c.xendev, 1, + "framebuffer %dx%dx%d offset %d stride %d\n", width, height, depth, offset, row_stride); return 0; } @@ -729,7 +730,8 @@ static void xenfb_update(void *opaque) break; } dpy_gfx_replace_surface(xenfb->c.con, surface); -xen_be_printf(&xenfb->c.xendev, 1, "update: resizing: %dx%d @ %d bpp%s\n", +xen_be_printf(&xenfb->c.xendev, 1, + "update: resizing: %dx%d @ %d bpp%s\n", xenfb->width, xenfb->height, xenfb->depth, is_buffer_shared(surface) ? " (shared)" : ""); xenfb->up_fullscreen = 1; diff --git a/hw/net/xen_nic.c b/hw/net/xen_nic.c index 9d93466..dbf3a89 100644 --- a/hw/net/xen_nic.c +++ b/hw/net/xen_nic.c @@ -140,7 +140,8 @@ static void net_tx_packets(struct XenNetDev *netdev) #endif if (txreq.size < 14) { -xen_be_printf(&netdev->xendev, 0, "bad packet size: %d\n", txreq.size); +xen_be_printf(&netdev->xendev, 0, "bad packet size: %d\n", + txreq.size); net_tx_error(netdev, &txreq, rc); continue; } @@ -213,7 +214,8 @@ static void net_rx_response(struct XenNetDev *netdev, resp->status = (int16_t)st; } -xen_be_printf(&netdev->xendev, 3, "rx response: idx %d, status %d, flags 0x%x\n", +xen_be_printf(&netdev->xendev, 3, + "rx response: idx %d, status %d, flags 0x%x\n", i, resp->status, resp->flags); netdev->rx_ring.rsp_prod_pvt = ++i; @@ -256,7 +258,8 @@ static ssize_t net_rx_packet(NetClientState *nc, const uint8_t *buf, size_t size netdev->xendev.dom, rxreq.gref, PROT_WRITE); if (page == NULL) { -xen_be_printf(&netdev->xendev, 0, "error: rx gref dereference failed (%d)\n", +xen_be_printf(&netdev->xendev, 0, + "error: rx gref dereference failed (%d)\n", rxreq.gref); net_rx_response(netdev, &rxreq, NETIF_RSP_ERROR, 0, 0, 0); return -1; @@ -330,7 +333,8 @@ static int net_connect(struct XenDevice *xendev) rx_copy = 0; } if (rx_copy == 0) { -xen_be_printf(&netdev->xendev, 0, "frontend doesn't support rx-copy.\n"); +xen_be_printf(&netdev->xendev, 0, + "frontend doesn't support rx-copy.\n"); return -1; } diff --git a/hw/xen/xen_backend.c b/hw/xen/xen_backend.c index 545ee47..0e95880 100644 --- a/hw/xen/xen_backend.c +++ b/hw/xen/xen_backend
[Qemu-devel] [PULL 00/13] xen-20161028-tag
The following changes since commit 5b2ecabaeabc17f032197246c4846b9ba95ba8a6: Merge remote-tracking branch 'remotes/kraxel/tags/pull-ui-20161028-1' into staging (2016-10-28 17:59:04 +0100) are available in the git repository at: git://xenbits.xen.org/people/sstabellini/qemu-dm.git tags/xen-20161028-tag for you to fetch changes up to 71981364b6152e63d0f3098fcdf8b884fa9ffa50: xen: Rename xen_be_del_xendev (2016-10-28 17:54:49 -0700) Xen 2016/10/28 Emil Condrea (13): xen: Fix coding style errors xen: Fix coding style warnings xen: Create a new file xen_pvdev.c xen: Move xenstore_update to xen_pvdev.c xen: Move evtchn functions to xen_pvdev.c xen: Prepare xendev qtail to be shared with frontends xen: Move xenstore cleanup and mkdir functions xen: Rename xen_be_printf to xen_pv_printf xen: Rename xen_be_unbind_evtchn xen: Rename xen_be_send_notify xen: Rename xen_be_evtchn_event xen: Rename xen_be_find_xendev xen: Rename xen_be_del_xendev hw/block/xen_disk.c | 65 hw/char/xen_console.c| 30 ++-- hw/display/xenfb.c | 127 hw/net/xen_nic.c | 36 +++-- hw/usb/xen-usb.c | 46 +++--- hw/xen/Makefile.objs | 2 +- hw/xen/xen_backend.c | 348 +-- hw/xen/xen_devconfig.c | 4 +- hw/xen/xen_pvdev.c | 316 +++ include/hw/xen/xen_backend.h | 72 + include/hw/xen/xen_pvdev.h | 78 ++ xen-common.c | 4 +- 12 files changed, 603 insertions(+), 525 deletions(-) create mode 100644 hw/xen/xen_pvdev.c create mode 100644 include/hw/xen/xen_pvdev.h
Re: [Qemu-devel] [PATCH 1/2] target-m68k: add 64bit mull
On 10/28/2016 03:39 PM, Laurent Vivier wrote: +tcg_gen_movi_i32(QREG_CC_V, 0); +tcg_gen_mov_i32(QREG_CC_C, QREG_CC_V); movi CC, 0 Otherwise, Reviewed-by: Richard Henderson r~
[Qemu-devel] [PATCH v2 2/2] target-m68k: add 680x0 divu/divs variants
Update helper to set the throwing location in case of div-by-0. Cleanup divX.w and add quad word variants of divX.l. Signed-off-by: Laurent Vivier --- linux-user/main.c | 7 +++ target-m68k/cpu.h | 4 -- target-m68k/helper.h| 6 +- target-m68k/op_helper.c | 102 target-m68k/qregs.def | 2 - target-m68k/translate.c | 154 ++-- 6 files changed, 211 insertions(+), 64 deletions(-) diff --git a/linux-user/main.c b/linux-user/main.c index 75b199f..c1d5eb4 100644 --- a/linux-user/main.c +++ b/linux-user/main.c @@ -2864,6 +2864,13 @@ void cpu_loop(CPUM68KState *env) info._sifields._sigfault._addr = env->pc; queue_signal(env, info.si_signo, QEMU_SI_FAULT, &info); break; +case EXCP_DIV0: +info.si_signo = TARGET_SIGFPE; +info.si_errno = 0; +info.si_code = TARGET_FPE_INTDIV; +info._sifields._sigfault._addr = env->pc; +queue_signal(env, info.si_signo, QEMU_SI_FAULT, &info); +break; case EXCP_TRAP0: { abi_long ret; diff --git a/target-m68k/cpu.h b/target-m68k/cpu.h index 6dfb54e..0b4ed7b 100644 --- a/target-m68k/cpu.h +++ b/target-m68k/cpu.h @@ -95,10 +95,6 @@ typedef struct CPUM68KState { uint32_t macsr; uint32_t mac_mask; -/* Temporary storage for DIV helpers. */ -uint32_t div1; -uint32_t div2; - /* MMU status. */ struct { uint32_t ar; diff --git a/target-m68k/helper.h b/target-m68k/helper.h index aae01f9..566094a 100644 --- a/target-m68k/helper.h +++ b/target-m68k/helper.h @@ -1,8 +1,10 @@ DEF_HELPER_1(bitrev, i32, i32) DEF_HELPER_1(ff1, i32, i32) DEF_HELPER_FLAGS_2(sats, TCG_CALL_NO_RWG_SE, i32, i32, i32) -DEF_HELPER_2(divu, void, env, i32) -DEF_HELPER_2(divs, void, env, i32) +DEF_HELPER_4(divu, i64, env, i32, i32, i32) +DEF_HELPER_4(divs, i64, env, i32, i32, i32) +DEF_HELPER_3(divu64, i64, env, i64, i32) +DEF_HELPER_3(divs64, i64, env, i64, i32) DEF_HELPER_2(set_sr, void, env, i32) DEF_HELPER_3(movec, void, env, i32, i32) diff --git a/target-m68k/op_helper.c b/target-m68k/op_helper.c index 48e02e4..cdeeb10 100644 --- a/target-m68k/op_helper.c +++ b/target-m68k/op_helper.c @@ -166,12 +166,17 @@ bool m68k_cpu_exec_interrupt(CPUState *cs, int interrupt_request) return false; } -static void raise_exception(CPUM68KState *env, int tt) +static void raise_exception_ra(CPUM68KState *env, int tt, uintptr_t raddr) { CPUState *cs = CPU(m68k_env_get_cpu(env)); cs->exception_index = tt; -cpu_loop_exit(cs); +cpu_loop_exit_restore(cs, raddr); +} + +static void raise_exception(CPUM68KState *env, int tt) +{ +raise_exception_ra(env, tt, 0); } void HELPER(raise_exception)(CPUM68KState *env, uint32_t tt) @@ -179,51 +184,100 @@ void HELPER(raise_exception)(CPUM68KState *env, uint32_t tt) raise_exception(env, tt); } -void HELPER(divu)(CPUM68KState *env, uint32_t word) +uint64_t HELPER(divu)(CPUM68KState *env, uint32_t num, uint32_t den, + uint32_t word) { -uint32_t num; -uint32_t den; uint32_t quot; uint32_t rem; -num = env->div1; -den = env->div2; -/* ??? This needs to make sure the throwing location is accurate. */ if (den == 0) { -raise_exception(env, EXCP_DIV0); +raise_exception_ra(env, EXCP_DIV0, GETPC()); } quot = num / den; rem = num % den; env->cc_v = (word && quot > 0x ? -1 : 0); -env->cc_z = quot; -env->cc_n = quot; +/* real 68040 keep Z and N on overflow, + * whereas documentation says "undefined" + */ +if (!env->cc_v) { +env->cc_z = quot; +env->cc_n = quot; +} env->cc_c = 0; -env->div1 = quot; -env->div2 = rem; +return quot | ((uint64_t)rem << 32); } -void HELPER(divs)(CPUM68KState *env, uint32_t word) +uint64_t HELPER(divs)(CPUM68KState *env, uint32_t num, uint32_t den, + uint32_t word) { -int32_t num; -int32_t den; int32_t quot; int32_t rem; -num = env->div1; -den = env->div2; if (den == 0) { -raise_exception(env, EXCP_DIV0); +raise_exception_ra(env, EXCP_DIV0, GETPC()); +} +quot = (int32_t)num / (int32_t)den; +rem = (int32_t)num % (int32_t)den; + +env->cc_v = (word && quot != (int16_t)quot ? -1 : 0); +/* real 68040 keep Z and N on overflow, + * whereas documentation says "undefined" + */ +if (!env->cc_v) { +env->cc_z = quot; +env->cc_n = quot; +} +env->cc_c = 0; + +return quot | ((uint64_t)rem << 32); +} + +uint64_t HELPER(divu64)(CPUM68KState *env, uint64_t num, uint32_t den) +{ +uint64_t quot; +uint32_t rem; + +if (den == 0) { +raise_exception_ra(env, EXCP_DIV0, GETPC()); } quot = num / den; rem = num % den; -env->cc_v = (word &&
[Qemu-devel] [PATCH v2 1/2] target-m68k: add 64bit mull
Signed-off-by: Laurent Vivier --- target-m68k/translate.c | 60 +++-- 1 file changed, 48 insertions(+), 12 deletions(-) diff --git a/target-m68k/translate.c b/target-m68k/translate.c index c00978d..d612a82 100644 --- a/target-m68k/translate.c +++ b/target-m68k/translate.c @@ -1812,24 +1812,60 @@ DISAS_INSN(tas) DISAS_INSN(mull) { uint16_t ext; -TCGv reg; TCGv src1; -TCGv dest; +int sign; -/* The upper 32 bits of the product are discarded, so - muls.l and mulu.l are functionally equivalent. */ ext = read_im16(env, s); -if (ext & 0x87ff) { -gen_exception(s, s->pc - 4, EXCP_UNSUPPORTED); + +sign = ext & 0x800; + +if (ext & 0x400) { +if (!m68k_feature(s->env, M68K_FEATURE_QUAD_MULDIV)) { +gen_exception(s, s->pc - 4, EXCP_UNSUPPORTED); +return; +} + +SRC_EA(env, src1, OS_LONG, 0, NULL); + +if (sign) { +tcg_gen_muls2_i32(DREG(ext, 12), DREG(ext, 0), src1, DREG(ext, 12)); +} else { +tcg_gen_mulu2_i32(DREG(ext, 12), DREG(ext, 0), src1, DREG(ext, 12)); +} + +tcg_gen_movi_i32(QREG_CC_V, 0); +tcg_gen_mov_i32(QREG_CC_C, QREG_CC_V); +tcg_gen_mov_i32(QREG_CC_N, DREG(ext, 0)); +tcg_gen_or_i32(QREG_CC_Z, DREG(ext, 12), DREG(ext, 0)); + +set_cc_op(s, CC_OP_FLAGS); return; } -reg = DREG(ext, 12); SRC_EA(env, src1, OS_LONG, 0, NULL); -dest = tcg_temp_new(); -tcg_gen_mul_i32(dest, src1, reg); -tcg_gen_mov_i32(reg, dest); -/* Unlike m68k, coldfire always clears the overflow bit. */ -gen_logic_cc(s, dest, OS_LONG); +if (m68k_feature(s->env, M68K_FEATURE_M68000)) { +tcg_gen_movi_i32(QREG_CC_C, 0); +if (sign) { +tcg_gen_muls2_i32(QREG_CC_N, QREG_CC_V, src1, DREG(ext, 12)); +/* QREG_CC_V is -(QREG_CC_V != (QREG_CC_N >> 31)) */ +tcg_gen_sari_i32(QREG_CC_Z, QREG_CC_N, 31); +tcg_gen_setcond_i32(TCG_COND_NE, QREG_CC_V, QREG_CC_V, QREG_CC_Z); +} else { +tcg_gen_mulu2_i32(QREG_CC_N, QREG_CC_V, src1, DREG(ext, 12)); +/* QREG_CC_V is -(QREG_CC_V != 0), use QREG_CC_C as 0 */ +tcg_gen_setcond_i32(TCG_COND_NE, QREG_CC_V, QREG_CC_V, QREG_CC_C); +} +tcg_gen_neg_i32(QREG_CC_V, QREG_CC_V); +tcg_gen_mov_i32(DREG(ext, 12), QREG_CC_N); + +tcg_gen_mov_i32(QREG_CC_Z, QREG_CC_N); + +set_cc_op(s, CC_OP_FLAGS); +} else { +/* The upper 32 bits of the product are discarded, so + muls.l and mulu.l are functionally equivalent. */ +tcg_gen_mul_i32(DREG(ext, 12), src1, DREG(ext, 12)); +gen_logic_cc(s, DREG(ext, 12), OS_LONG); +} } static void gen_link(DisasContext *s, uint16_t insn, int32_t offset) -- 2.7.4
[Qemu-devel] [PATCH v2 0/2] 680x0 mul and div instructions
This series is another subset of the series I sent in May: https://lists.gnu.org/archive/html/qemu-devel/2016-05/msg00501.html It must be applied on top of series: "target-m68k: 680x0 instruction set, part 2" This subset contains reworked patches of mul and div instructions: - "add 64bit mull": correctly set QREG_CC_V, - "inline divu/divs": don't inline divu/divs, but update existing functions to manage 680x0 div instructions I've checked it doesn't break coldfire support: http://wiki.qemu.org/download/coldfire-test-0.1.tar.bz2 but it can't boot a 680x0 processor kernel. v2: - Free "rem" and "quot" in "divl". Laurent Vivier (2): target-m68k: add 64bit mull target-m68k: add 680x0 divu/divs variants linux-user/main.c | 7 ++ target-m68k/cpu.h | 4 - target-m68k/helper.h| 6 +- target-m68k/op_helper.c | 102 +-- target-m68k/qregs.def | 2 - target-m68k/translate.c | 214 ++-- 6 files changed, 259 insertions(+), 76 deletions(-) -- 2.7.4
Re: [Qemu-devel] [PATCH 2/2] target-m68k: add 680x0 divu/divs variants
Le 29/10/2016 à 00:39, Laurent Vivier a écrit : > Update helper to set the throwing location in case of div-by-0. > Cleanup divX.w and add quad word variants of divX.l. > > Signed-off-by: Laurent Vivier > --- > linux-user/main.c | 7 +++ > target-m68k/cpu.h | 4 -- > target-m68k/helper.h| 6 +- > target-m68k/op_helper.c | 102 > target-m68k/qregs.def | 2 - > target-m68k/translate.c | 150 > ++-- > 6 files changed, 208 insertions(+), 63 deletions(-) > ... > +quot = tcg_temp_new(); > +rem = tcg_temp_new(); > +tcg_gen_extr_i64_i32(quot, rem, t64); > +tcg_temp_free_i64(t64); > + > +/* on overflow, operands are unaffected, > + * Z and N flags are undefined, C is always 0 > + * If Dq and Dr are the same, the quotient is returned. > + * therefore we set Dq last. > + */ > +if (m68k_feature(s->env, M68K_FEATURE_CF_ISA_A)) { > +/* divs.l , Dq32/32 -> 32q */ > +if (REG(ext, 0) == REG(ext, 12)) { > +tcg_gen_movcond_i32(TCG_COND_EQ, DREG(ext, 12), > +QREG_CC_V, QREG_CC_C /* zero */, > +quot, DREG(ext, 12)); /* quot */ > +} else { > +tcg_gen_movcond_i32(TCG_COND_EQ, DREG(ext, 0), > +QREG_CC_V, QREG_CC_C /* zero */, > +rem, DREG(ext, 0)); /* rem */ > +} > } else { > -/* rem */ > -tcg_gen_mov_i32 (reg, QREG_DIV2); > +/* divs.l , Dq32/32 -> 32q */ > +/* divsl.l , Dr:Dq32/32 -> 32r:32q */ > +tcg_gen_movcond_i32(TCG_COND_EQ, DREG(ext, 0), > +QREG_CC_V, QREG_CC_C /* zero */, > +rem, DREG(ext, 0)); /* rem */ > +tcg_gen_movcond_i32(TCG_COND_EQ, DREG(ext, 12), > +QREG_CC_V, QREG_CC_C /* zero */, > +quot, DREG(ext, 12)); /* quot */ > } > + I forget to free "rem" and "quot" here: send a v2... Laurent
[Qemu-devel] [PATCH 2/2] target-m68k: add 680x0 divu/divs variants
Update helper to set the throwing location in case of div-by-0. Cleanup divX.w and add quad word variants of divX.l. Signed-off-by: Laurent Vivier --- linux-user/main.c | 7 +++ target-m68k/cpu.h | 4 -- target-m68k/helper.h| 6 +- target-m68k/op_helper.c | 102 target-m68k/qregs.def | 2 - target-m68k/translate.c | 150 ++-- 6 files changed, 208 insertions(+), 63 deletions(-) diff --git a/linux-user/main.c b/linux-user/main.c index 75b199f..c1d5eb4 100644 --- a/linux-user/main.c +++ b/linux-user/main.c @@ -2864,6 +2864,13 @@ void cpu_loop(CPUM68KState *env) info._sifields._sigfault._addr = env->pc; queue_signal(env, info.si_signo, QEMU_SI_FAULT, &info); break; +case EXCP_DIV0: +info.si_signo = TARGET_SIGFPE; +info.si_errno = 0; +info.si_code = TARGET_FPE_INTDIV; +info._sifields._sigfault._addr = env->pc; +queue_signal(env, info.si_signo, QEMU_SI_FAULT, &info); +break; case EXCP_TRAP0: { abi_long ret; diff --git a/target-m68k/cpu.h b/target-m68k/cpu.h index 6dfb54e..0b4ed7b 100644 --- a/target-m68k/cpu.h +++ b/target-m68k/cpu.h @@ -95,10 +95,6 @@ typedef struct CPUM68KState { uint32_t macsr; uint32_t mac_mask; -/* Temporary storage for DIV helpers. */ -uint32_t div1; -uint32_t div2; - /* MMU status. */ struct { uint32_t ar; diff --git a/target-m68k/helper.h b/target-m68k/helper.h index aae01f9..566094a 100644 --- a/target-m68k/helper.h +++ b/target-m68k/helper.h @@ -1,8 +1,10 @@ DEF_HELPER_1(bitrev, i32, i32) DEF_HELPER_1(ff1, i32, i32) DEF_HELPER_FLAGS_2(sats, TCG_CALL_NO_RWG_SE, i32, i32, i32) -DEF_HELPER_2(divu, void, env, i32) -DEF_HELPER_2(divs, void, env, i32) +DEF_HELPER_4(divu, i64, env, i32, i32, i32) +DEF_HELPER_4(divs, i64, env, i32, i32, i32) +DEF_HELPER_3(divu64, i64, env, i64, i32) +DEF_HELPER_3(divs64, i64, env, i64, i32) DEF_HELPER_2(set_sr, void, env, i32) DEF_HELPER_3(movec, void, env, i32, i32) diff --git a/target-m68k/op_helper.c b/target-m68k/op_helper.c index 48e02e4..cdeeb10 100644 --- a/target-m68k/op_helper.c +++ b/target-m68k/op_helper.c @@ -166,12 +166,17 @@ bool m68k_cpu_exec_interrupt(CPUState *cs, int interrupt_request) return false; } -static void raise_exception(CPUM68KState *env, int tt) +static void raise_exception_ra(CPUM68KState *env, int tt, uintptr_t raddr) { CPUState *cs = CPU(m68k_env_get_cpu(env)); cs->exception_index = tt; -cpu_loop_exit(cs); +cpu_loop_exit_restore(cs, raddr); +} + +static void raise_exception(CPUM68KState *env, int tt) +{ +raise_exception_ra(env, tt, 0); } void HELPER(raise_exception)(CPUM68KState *env, uint32_t tt) @@ -179,51 +184,100 @@ void HELPER(raise_exception)(CPUM68KState *env, uint32_t tt) raise_exception(env, tt); } -void HELPER(divu)(CPUM68KState *env, uint32_t word) +uint64_t HELPER(divu)(CPUM68KState *env, uint32_t num, uint32_t den, + uint32_t word) { -uint32_t num; -uint32_t den; uint32_t quot; uint32_t rem; -num = env->div1; -den = env->div2; -/* ??? This needs to make sure the throwing location is accurate. */ if (den == 0) { -raise_exception(env, EXCP_DIV0); +raise_exception_ra(env, EXCP_DIV0, GETPC()); } quot = num / den; rem = num % den; env->cc_v = (word && quot > 0x ? -1 : 0); -env->cc_z = quot; -env->cc_n = quot; +/* real 68040 keep Z and N on overflow, + * whereas documentation says "undefined" + */ +if (!env->cc_v) { +env->cc_z = quot; +env->cc_n = quot; +} env->cc_c = 0; -env->div1 = quot; -env->div2 = rem; +return quot | ((uint64_t)rem << 32); } -void HELPER(divs)(CPUM68KState *env, uint32_t word) +uint64_t HELPER(divs)(CPUM68KState *env, uint32_t num, uint32_t den, + uint32_t word) { -int32_t num; -int32_t den; int32_t quot; int32_t rem; -num = env->div1; -den = env->div2; if (den == 0) { -raise_exception(env, EXCP_DIV0); +raise_exception_ra(env, EXCP_DIV0, GETPC()); +} +quot = (int32_t)num / (int32_t)den; +rem = (int32_t)num % (int32_t)den; + +env->cc_v = (word && quot != (int16_t)quot ? -1 : 0); +/* real 68040 keep Z and N on overflow, + * whereas documentation says "undefined" + */ +if (!env->cc_v) { +env->cc_z = quot; +env->cc_n = quot; +} +env->cc_c = 0; + +return quot | ((uint64_t)rem << 32); +} + +uint64_t HELPER(divu64)(CPUM68KState *env, uint64_t num, uint32_t den) +{ +uint64_t quot; +uint32_t rem; + +if (den == 0) { +raise_exception_ra(env, EXCP_DIV0, GETPC()); } quot = num / den; rem = num % den; -env->cc_v = (word &&
[Qemu-devel] [PATCH 0/2] 680x0 mul and div instructions
This series is another subset of the series I sent in May: https://lists.gnu.org/archive/html/qemu-devel/2016-05/msg00501.html It must be applied on top of series: "target-m68k: 680x0 instruction set, part 2" This subset contains reworked patches of mul and div instructions: - "add 64bit mull": correctly set QREG_CC_V, - "inline divu/divs": don't inline divu/divs, but update existing functions to manage 680x0 div instructions I've checked it doesn't break coldfire support: http://wiki.qemu.org/download/coldfire-test-0.1.tar.bz2 but it can't boot a 680x0 processor kernel. Laurent Vivier (2): target-m68k: add 64bit mull target-m68k: add 680x0 divu/divs variants linux-user/main.c | 7 ++ target-m68k/cpu.h | 4 - target-m68k/helper.h| 6 +- target-m68k/op_helper.c | 102 +-- target-m68k/qregs.def | 2 - target-m68k/translate.c | 210 ++-- 6 files changed, 256 insertions(+), 75 deletions(-) -- 2.7.4
[Qemu-devel] [PATCH 1/2] target-m68k: add 64bit mull
Signed-off-by: Laurent Vivier --- target-m68k/translate.c | 60 +++-- 1 file changed, 48 insertions(+), 12 deletions(-) diff --git a/target-m68k/translate.c b/target-m68k/translate.c index c00978d..d612a82 100644 --- a/target-m68k/translate.c +++ b/target-m68k/translate.c @@ -1812,24 +1812,60 @@ DISAS_INSN(tas) DISAS_INSN(mull) { uint16_t ext; -TCGv reg; TCGv src1; -TCGv dest; +int sign; -/* The upper 32 bits of the product are discarded, so - muls.l and mulu.l are functionally equivalent. */ ext = read_im16(env, s); -if (ext & 0x87ff) { -gen_exception(s, s->pc - 4, EXCP_UNSUPPORTED); + +sign = ext & 0x800; + +if (ext & 0x400) { +if (!m68k_feature(s->env, M68K_FEATURE_QUAD_MULDIV)) { +gen_exception(s, s->pc - 4, EXCP_UNSUPPORTED); +return; +} + +SRC_EA(env, src1, OS_LONG, 0, NULL); + +if (sign) { +tcg_gen_muls2_i32(DREG(ext, 12), DREG(ext, 0), src1, DREG(ext, 12)); +} else { +tcg_gen_mulu2_i32(DREG(ext, 12), DREG(ext, 0), src1, DREG(ext, 12)); +} + +tcg_gen_movi_i32(QREG_CC_V, 0); +tcg_gen_mov_i32(QREG_CC_C, QREG_CC_V); +tcg_gen_mov_i32(QREG_CC_N, DREG(ext, 0)); +tcg_gen_or_i32(QREG_CC_Z, DREG(ext, 12), DREG(ext, 0)); + +set_cc_op(s, CC_OP_FLAGS); return; } -reg = DREG(ext, 12); SRC_EA(env, src1, OS_LONG, 0, NULL); -dest = tcg_temp_new(); -tcg_gen_mul_i32(dest, src1, reg); -tcg_gen_mov_i32(reg, dest); -/* Unlike m68k, coldfire always clears the overflow bit. */ -gen_logic_cc(s, dest, OS_LONG); +if (m68k_feature(s->env, M68K_FEATURE_M68000)) { +tcg_gen_movi_i32(QREG_CC_C, 0); +if (sign) { +tcg_gen_muls2_i32(QREG_CC_N, QREG_CC_V, src1, DREG(ext, 12)); +/* QREG_CC_V is -(QREG_CC_V != (QREG_CC_N >> 31)) */ +tcg_gen_sari_i32(QREG_CC_Z, QREG_CC_N, 31); +tcg_gen_setcond_i32(TCG_COND_NE, QREG_CC_V, QREG_CC_V, QREG_CC_Z); +} else { +tcg_gen_mulu2_i32(QREG_CC_N, QREG_CC_V, src1, DREG(ext, 12)); +/* QREG_CC_V is -(QREG_CC_V != 0), use QREG_CC_C as 0 */ +tcg_gen_setcond_i32(TCG_COND_NE, QREG_CC_V, QREG_CC_V, QREG_CC_C); +} +tcg_gen_neg_i32(QREG_CC_V, QREG_CC_V); +tcg_gen_mov_i32(DREG(ext, 12), QREG_CC_N); + +tcg_gen_mov_i32(QREG_CC_Z, QREG_CC_N); + +set_cc_op(s, CC_OP_FLAGS); +} else { +/* The upper 32 bits of the product are discarded, so + muls.l and mulu.l are functionally equivalent. */ +tcg_gen_mul_i32(DREG(ext, 12), src1, DREG(ext, 12)); +gen_logic_cc(s, DREG(ext, 12), OS_LONG); +} } static void gen_link(DisasContext *s, uint16_t insn, int32_t offset) -- 2.7.4
[Qemu-devel] [PATCH] atapi: classify read_cd as conditionally returning data
For the purposes of byte_count_limit verification, add a new flag that identifies read_cd as sometimes returning data, then check the BCL in its command handler after we know that it will indeed return data. Reported-by: Hervé Poussineau Signed-off-by: John Snow --- hw/ide/atapi.c | 49 +++-- 1 file changed, 39 insertions(+), 10 deletions(-) diff --git a/hw/ide/atapi.c b/hw/ide/atapi.c index 6189675..f26e3f4 100644 --- a/hw/ide/atapi.c +++ b/hw/ide/atapi.c @@ -637,6 +637,23 @@ static unsigned int event_status_media(IDEState *s, return 8; /* We wrote to 4 extra bytes from the header */ } +/* + * Before transferring data or otherwise signalling acceptance of a command + * marked CONDDATA, we must check the validity of the byte_count_limit. + */ +static bool validate_bcl(IDEState *s) +{ +/* TODO: Check IDENTIFY data word 125 for defacult BCL (currently 0) */ +if (s->atapi_dma || atapi_byte_count_limit(s)) { +return true; +} + +/* TODO: Move abort back into core.c and introduce proper error flow between + * ATAPI layer and IDE core layer */ +ide_abort_command(s); +return false; +} + static void cmd_get_event_status_notification(IDEState *s, uint8_t *buf) { @@ -1028,12 +1045,19 @@ static void cmd_read_cd(IDEState *s, uint8_t* buf) return; } -transfer_request = buf[9]; -switch(transfer_request & 0xf8) { -case 0x00: +transfer_request = buf[9] & 0xf8; +if (transfer_request == 0x00) { /* nothing */ ide_atapi_cmd_ok(s); -break; +return; +} + +/* Check validity of BCL before transferring data */ +if (!validate_bcl(s)) { +return; +} + +switch(transfer_request) { case 0x10: /* normal read */ ide_atapi_cmd_read(s, lba, nb_sectors, 2048); @@ -1266,6 +1290,14 @@ enum { * See ATA8-ACS3 "7.21.5 Byte Count Limit" */ NONDATA = 0x04, + +/* + * CONDDATA implies a command that transfers data only conditionally based + * on the presence of suboptions. It should be exempt from the BCL check at + * command validation time, but it needs to be checked at the command + * handler level instead. + */ +CONDDATA = 0x08, }; static const struct AtapiCmd { @@ -1348,15 +1380,12 @@ void ide_atapi_cmd(IDEState *s) return; } -/* Nondata commands permit the byte_count_limit to be 0. +/* Commands that don't transfer DATA permit the byte_count_limit to be 0. * If this is a data-transferring PIO command and BCL is 0, * we abort at the /ATA/ level, not the ATAPI level. * See ATA8 ACS3 section 7.17.6.49 and 7.21.5 */ -if (cmd->handler && !(cmd->flags & NONDATA)) { -/* TODO: Check IDENTIFY data word 125 for default BCL (currently 0) */ -if (!(atapi_byte_count_limit(s) || s->atapi_dma)) { -/* TODO: Move abort back into core.c and make static inline again */ -ide_abort_command(s); +if (cmd->handler && !(cmd->flags & (NONDATA | CONDDATA))) { +if (!validate_bcl(s)) { return; } } -- 2.7.4
[Qemu-devel] [PATCH] 9pfs: drop abusive error message from virtfs_reset()
The virtfs_reset() function is called either when the virtio-9p device gets reset, or when the client starts a new 9P session. In both cases, if it finds fids from a previous session, the following is printed in the monitor: 9pfs:virtfs_reset: One or more uncluncked fids found during reset For example, if a linux guest with a mounted 9P share is reset from the monitor with system_reset, the message will be printed. This is abusive since these fids are now clunked and the state is clean. Signed-off-by: Greg Kurz --- hw/9pfs/9p.c |7 +-- 1 file changed, 1 insertion(+), 6 deletions(-) diff --git a/hw/9pfs/9p.c b/hw/9pfs/9p.c index 1050b89ec720..aea7e9d39206 100644 --- a/hw/9pfs/9p.c +++ b/hw/9pfs/9p.c @@ -535,7 +535,7 @@ static int coroutine_fn v9fs_mark_fids_unreclaim(V9fsPDU *pdu, V9fsPath *path) static void coroutine_fn virtfs_reset(V9fsPDU *pdu) { V9fsState *s = pdu->s; -V9fsFidState *fidp = NULL; +V9fsFidState *fidp; /* Free all fids */ while (s->fid_list) { @@ -548,11 +548,6 @@ static void coroutine_fn virtfs_reset(V9fsPDU *pdu) free_fid(pdu, fidp); } } -if (fidp) { -/* One or more unclunked fids found... */ -error_report("9pfs:%s: One or more uncluncked fids " - "found during reset", __func__); -} } #define P9_QID_TYPE_DIR 0x80
Re: [Qemu-devel] [PATCH v3] block/vxhs: Add Veritas HyperScale VxHS block device support
On 10/28/16, 12:03 PM, "Jeff Cody" wrote: >On Fri, Oct 28, 2016 at 12:44:27AM -0700, Ashish Mittal wrote: >> This patch adds support for a new block device type called "vxhs". >> Source code for the qnio library that this code loads can be downloaded >>from: >> https://github.com/MittalAshish/libqnio.git >> >> Sample command line using the JSON syntax: >> ./qemu-system-x86_64 -name instance-0008 -S -vnc 0.0.0.0:0 -k en-us >> -vga cirrus -device virtio-balloon-pci,id=balloon0,bus=pci.0,addr=0x5 >> -msg timestamp=on >> >>'json:{"driver":"vxhs","vdisk_id":"{c3e9095a-a5ee-4dce-afeb-2a59fb387410} >>", >> "server":{"host":"172.172.17.4","port":""}}' >> >> Sample command line using the URI syntax: >> qemu-img convert -f raw -O raw -n >> /var/lib/nova/instances/_base/0c5eacd5ebea5ed914b6a3e7b18f1ce734c386ad >> vxhs://192.168.0.1:/%7Bc6718f6b-0401-441d-a8c3-1f0064d75ee0%7D >> >> Signed-off-by: Ashish Mittal >> --- >> v3 changelog: >> (1) Added QAPI schema for the VxHS driver. >> >> v2 changelog: >> (1) Changes done in response to v1 comments. >> >> TODO: >> (1) Add qemu-iotest >> (2) We need to be able to free all resources once we close the last >>vxhs drive. >> >> block/Makefile.objs | 2 + >> block/trace-events | 21 ++ >> block/vxhs.c | 669 >>+++ >> configure| 41 >> qapi/block-core.json | 20 +- >> 5 files changed, 751 insertions(+), 2 deletions(-) >> create mode 100644 block/vxhs.c >> >> diff --git a/block/Makefile.objs b/block/Makefile.objs >> index 67a036a..58313a2 100644 >> --- a/block/Makefile.objs >> +++ b/block/Makefile.objs >> @@ -18,6 +18,7 @@ block-obj-$(CONFIG_LIBNFS) += nfs.o >> block-obj-$(CONFIG_CURL) += curl.o >> block-obj-$(CONFIG_RBD) += rbd.o >> block-obj-$(CONFIG_GLUSTERFS) += gluster.o >> +block-obj-$(CONFIG_VXHS) += vxhs.o >> block-obj-$(CONFIG_ARCHIPELAGO) += archipelago.o >> block-obj-$(CONFIG_LIBSSH2) += ssh.o >> block-obj-y += accounting.o dirty-bitmap.o >> @@ -38,6 +39,7 @@ rbd.o-cflags := $(RBD_CFLAGS) >> rbd.o-libs := $(RBD_LIBS) >> gluster.o-cflags := $(GLUSTERFS_CFLAGS) >> gluster.o-libs := $(GLUSTERFS_LIBS) >> +vxhs.o-libs:= $(VXHS_LIBS) >> ssh.o-cflags := $(LIBSSH2_CFLAGS) >> ssh.o-libs := $(LIBSSH2_LIBS) >> archipelago.o-libs := $(ARCHIPELAGO_LIBS) >> diff --git a/block/trace-events b/block/trace-events >> index 05fa13c..94249ee 100644 >> --- a/block/trace-events >> +++ b/block/trace-events >> @@ -114,3 +114,24 @@ qed_aio_write_data(void *s, void *acb, int ret, >>uint64_t offset, size_t len) "s >> qed_aio_write_prefill(void *s, void *acb, uint64_t start, size_t len, >>uint64_t offset) "s %p acb %p start %"PRIu64" len %zu offset %"PRIu64 >> qed_aio_write_postfill(void *s, void *acb, uint64_t start, size_t len, >>uint64_t offset) "s %p acb %p start %"PRIu64" len %zu offset %"PRIu64 >> qed_aio_write_main(void *s, void *acb, int ret, uint64_t offset, >>size_t len) "s %p acb %p ret %d offset %"PRIu64" len %zu" >> + >> +# block/vxhs.c >> +vxhs_iio_callback(int error, int reason) "ctx is NULL: error %d, >>reason %d" >> +vxhs_setup_qnio(void *s) "Context to HyperScale IO manager = %p" >> +vxhs_iio_callback_chnfail(int err, int error) "QNIO channel failed, no >>i/o %d, %d" >> +vxhs_iio_callback_unknwn(int opcode, int err) "unexpected opcode %d, >>errno %d" >> +vxhs_open_fail(int ret) "Could not open the device. Error = %d" >> +vxhs_open_epipe(int ret) "Could not create a pipe for device. Bailing >>out. Error=%d" >> +vxhs_aio_rw_invalid(int req) "Invalid I/O request iodir %d" >> +vxhs_aio_rw_ioerr(char *guid, int iodir, uint64_t size, uint64_t off, >>void *acb, int ret, int err) "IO ERROR (vDisk %s) FOR : Read/Write = %d >>size = %lu offset = %lu ACB = %p. Error = %d, errno = %d" >> +vxhs_get_vdisk_stat_err(char *guid, int ret, int err) "vDisk (%s) stat >>ioctl failed, ret = %d, errno = %d" >> +vxhs_get_vdisk_stat(char *vdisk_guid, uint64_t vdisk_size) "vDisk %s >>stat ioctl returned size %lu" >> +vxhs_qnio_iio_open(const char *ip) "Failed to connect to storage agent >>on host-ip %s" >> +vxhs_qnio_iio_devopen(const char *fname) "Failed to open vdisk device: >>%s" >> +vxhs_complete_aio(void *acb, uint64_t ret) "aio failed acb %p ret %ld" >> +vxhs_parse_uri_filename(const char *filename) "URI passed via >>bdrv_parse_filename %s" >> +vxhs_qemu_init_vdisk(const char *vdisk_id) "vdisk_id from json %s" >> +vxhs_parse_uri_hostinfo(int num, char *host, int port) "Host %d: IP >>%s, Port %d" >> +vxhs_qemu_init(char *of_vsa_addr, int port) "Adding host %s:%d to >>BDRVVXHSState" >> +vxhs_qemu_init_filename(const char *filename) "Filename passed as %s" >> +vxhs_close(char *vdisk_guid) "Closing vdisk %s" >> diff --git a/block/vxhs.c b/block/vxhs.c >> new file mode 100644 >> index 000..08ad681 >> --- /dev/null >> +++ b/block/vxhs.c >> @@ -0,0 +1,669 @@ >> +/* >> + * QEMU Block driver for Veritas HyperScale (VxHS) >> + * >> + * This wor
Re: [Qemu-devel] [PATCH v2] block/vxhs: Add Veritas HyperScale VxHS block device support
On Fri, Oct 28, 2016 at 01:26:41AM +, Rakesh Ranjan wrote: > Hi Jeff etc al, > > Thanks a lot for your due diligence to review the code changes throughly > and providing comments, suggestions to improve. We are completely on top > of this and have already started to expedite the overall development. > > We would like to get you help regarding the applicability of qemu-iotests > test harness against a QEMU block driver which doesn¹t support create > operation. Where we can find the detailed document regarding qemu-iotests > test harness and and it¹s dependency on a particular block driver? > > We have enhanced the test server utility (qnio_server) a bit and conducted > manual tests, which mainly includes qemu-img convert and qemu-io read and > write operations. > > # libqnio/src/test/ > > @ Create vDisk file of size 10G > > # ./create_vdisk.sh > Usage: create_vdisk > > > # ./create_vdisk.sh /qemublk_test/vDisk1 10240 > > > # ls -lhs /qemublk_test/vDisk1 > 1.1M -rw-r--r-- 1 root root 10G Oct 27 17:02 /qemublk_test/vDisk1 > > > > @ Start qnio_server > > # ./qnio_server -h > Usage: qnio_server [-d ] [-p] [-v] [-h] > d -> Vdisk directory > p -> Run commands in separate thread > h -> Help > v -> Verbose > > > # ./qnio_server -d /qemublk_test/ > > > > @ Convert qcow2 image to vxhs raw format > > # ./qemu-img convert -f qcow2 -O raw -n /qemublk_test/centos-64.qcow2 > vxhs://127.0.0.1:/vDisk1 > Hi Rakesh, The qemu-iotests are located in the qemu tree, under 'tests/qemu-iotests'. I don't know of any formal documenation out here, but here are the basics: To run an individual iotest, you can run the test from within the tests/qemu-iotests directory, e.g.: # cd tests/qemu-iotests # ./check -qcow2 002 What this will do is run the test case 002 with the format qcow2. The output of that test is checked against 002.out, and if there are differences, an error is reported. What is implicit in the above check command is the protocol type of 'file'. If you wanted to run that test using a different protocol (for instance, 'nfs'), you can do: # ./check -qcow2 -nfs 002 You need to extend qemu-iotests to be aware of the vxhs:// protocol. To do this, you'll need to modify these files: tests/qemu-iotests/common.rc tests/qemu-iotests/common If you search for some of the other protocol drivers, you should see what you need to change; for instance, 'sheepdog', 'nfs', 'ssh', etc.. are all protocol drivers. One difference is, as you noted, that you cannot create an image using your protocol. This means you will need to either: A) Let the test framework create the test image like normal, and then have the test script launch the test QNIO server, B) Do the image creation, and server launch, manually outside the script. This isn't optimal because then the testers (e.g. me, and other block maintainers) need to remember what steps to perform. For the basis of a simple test, you can look at test 002. It should be a good starting point. You'll need to create a new test as a file named after the existing tests (you need the ??? and ???.out files), and then modify the 'group' file to include the test). Generally, it is best if the test if a separate patch in the series. Jeff
Re: [Qemu-devel] [PATCH v3] block/vxhs: Add Veritas HyperScale VxHS block device support
Hi Eric, On Fri, Oct 28, 2016 at 7:44 AM, Eric Blake wrote: > On 10/28/2016 02:44 AM, Ashish Mittal wrote: >> This patch adds support for a new block device type called "vxhs". >> Source code for the qnio library that this code loads can be downloaded from: >> https://github.com/MittalAshish/libqnio.git >> >> Sample command line using the JSON syntax: >> ./qemu-system-x86_64 -name instance-0008 -S -vnc 0.0.0.0:0 -k en-us >> -vga cirrus -device virtio-balloon-pci,id=balloon0,bus=pci.0,addr=0x5 >> -msg timestamp=on >> 'json:{"driver":"vxhs","vdisk_id":"{c3e9095a-a5ee-4dce-afeb-2a59fb387410}", >> "server":{"host":"172.172.17.4","port":""}}' > > Are the {} really part of vdisk_id? That's not a usual portion of a > UUID. And it should probably be spelled vdisk-id. > The {} are not required for qemu/libqnio or the test server. It is just some artifact that our openstack components need. Then test server does not need {} at all. I will remove it from the sample command syntax in v4. > It's a shame that port is a string and not an int, but it matches > existing practice, so that part is correct. > >> >> Sample command line using the URI syntax: >> qemu-img convert -f raw -O raw -n >> /var/lib/nova/instances/_base/0c5eacd5ebea5ed914b6a3e7b18f1ce734c386ad >> vxhs://192.168.0.1:/%7Bc6718f6b-0401-441d-a8c3-1f0064d75ee0%7D >> > > The URI syntax is potentially harder to use when compared to structured > usage (Kevin's work to add -blockdev, which depends on the QAPI definition). > We decided to keep both after discussion with other reviewers. Do qemu-img and qemu-io binaries support json syntax similar to qemu-system-x86_64? >> Signed-off-by: Ashish Mittal >> --- >> v3 changelog: >> (1) Added QAPI schema for the VxHS driver. >> > > For this email, I'm focusing just on the QAPI. > >> +++ b/qapi/block-core.json >> @@ -1708,7 +1708,7 @@ >> ## >> { 'enum': 'BlockdevDriver', >>'data': [ 'archipelago', 'blkdebug', 'blkverify', 'bochs', 'cloop', >> -'dmg', 'file', 'ftp', 'ftps', 'gluster', 'host_cdrom', >> +'dmg', 'file', 'ftp', 'ftps', 'gluster', 'host_cdrom', 'vxhs', >> 'host_device', 'http', 'https', 'luks', 'null-aio', 'null-co', > > Missing mention of the new enum value in the comments above. > Will fix in v4. >> 'parallels', 'qcow', 'qcow2', 'qed', 'quorum', 'raw', >> 'replication', 'tftp', 'vdi', 'vhdx', 'vmdk', 'vpc', 'vvfat' ] } >> @@ -2220,6 +2220,21 @@ >>'data': { 'filename': 'str' } } >> >> ## >> +# @BlockdevOptionsVxHS >> +# >> +# Driver specific block device options for VxHS >> +# >> +# @vdisk_id:UUID of VxHS volume > > Again, this should be vdisk-id. > Will fix in v4. >> +# >> +# @server: vxhs server IP, port >> +# >> +# Since: 2.7 > > You missed 2.7; this should be 2.8 (if you make soft freeze) or even 2.9. > Will fix in v4. >> +## >> +{ 'struct': 'BlockdevOptionsVxHS', >> + 'data': { 'vdisk_id': 'str', >> +'server': 'InetSocketAddress' } } > > Is there any way to use a Unix socket, or is this server ONLY accessible > over IPv4/IPv6? > Right now we support IPv4 only. > >> + >> +## >> # @BlockdevOptions >> # >> # Options for creating a block device. Many options are available for all >> @@ -2283,7 +2298,8 @@ >>'vhdx': 'BlockdevOptionsGenericFormat', >>'vmdk': 'BlockdevOptionsGenericCOWFormat', >>'vpc':'BlockdevOptionsGenericFormat', >> - 'vvfat': 'BlockdevOptionsVVFAT' >> + 'vvfat': 'BlockdevOptionsVVFAT', >> + 'vxhs': 'BlockdevOptionsVxHS' >>} } >> >> ## >> > > -- > Eric Blake eblake redhat com+1-919-301-3266 > Libvirt virtualization library http://libvirt.org >
Re: [Qemu-devel] [PATCH] block-backend: Always notify on blk_eject
On 10/28/2016 05:23 PM, John Snow wrote: blk_eject is only used by scsi-disk and atapi, and in both cases we only attempt to invoke blk_eject if we have a bona-fide change in tray state. The "issue" here is that the tray state does not generate a QMP event unless there is a medium/BDS attached to the device, so if libvirt et al are waiting for a tray event to occur from an empty-but-closed drive, software opening that drive will not emit an event and libvirt will wait forever. Change this by modifying blk_eject to always emit an event, instead of conditionally on a "real" backend eject. Fixes: https://bugzilla.redhat.com/show_bug.cgi?id=1373264 Reported-by: Peter Krempa Signed-off-by: John Snow --- block/block-backend.c | 13 +++-- 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/block/block-backend.c b/block/block-backend.c index c53ca30..2044f20 100644 --- a/block/block-backend.c +++ b/block/block-backend.c @@ -1381,15 +1381,16 @@ void blk_eject(BlockBackend *blk, bool eject_flag) /* blk_eject is only called by qdevified devices */ assert(!blk->legacy_dev); +id = blk_get_attached_dev_id(blk); Uhh, whoops, I left a change in my local branch that kept this right before the tray event. Sorry about that. if (bs) { bdrv_eject(bs, eject_flag); - -id = blk_get_attached_dev_id(blk); -qapi_event_send_device_tray_moved(blk_name(blk), id, - eject_flag, &error_abort); -g_free(id); - } + +/* Whether or not we ejected on the backend, + * the frontend experienced a tray event. */ +qapi_event_send_device_tray_moved(blk_name(blk), id, + eject_flag, &error_abort); +g_free(id); } int blk_get_flags(BlockBackend *blk)
[Qemu-devel] [PATCH] block-backend: Always notify on blk_eject
blk_eject is only used by scsi-disk and atapi, and in both cases we only attempt to invoke blk_eject if we have a bona-fide change in tray state. The "issue" here is that the tray state does not generate a QMP event unless there is a medium/BDS attached to the device, so if libvirt et al are waiting for a tray event to occur from an empty-but-closed drive, software opening that drive will not emit an event and libvirt will wait forever. Change this by modifying blk_eject to always emit an event, instead of conditionally on a "real" backend eject. Fixes: https://bugzilla.redhat.com/show_bug.cgi?id=1373264 Reported-by: Peter Krempa Signed-off-by: John Snow --- block/block-backend.c | 13 +++-- 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/block/block-backend.c b/block/block-backend.c index c53ca30..2044f20 100644 --- a/block/block-backend.c +++ b/block/block-backend.c @@ -1381,15 +1381,16 @@ void blk_eject(BlockBackend *blk, bool eject_flag) /* blk_eject is only called by qdevified devices */ assert(!blk->legacy_dev); +id = blk_get_attached_dev_id(blk); if (bs) { bdrv_eject(bs, eject_flag); - -id = blk_get_attached_dev_id(blk); -qapi_event_send_device_tray_moved(blk_name(blk), id, - eject_flag, &error_abort); -g_free(id); - } + +/* Whether or not we ejected on the backend, + * the frontend experienced a tray event. */ +qapi_event_send_device_tray_moved(blk_name(blk), id, + eject_flag, &error_abort); +g_free(id); } int blk_get_flags(BlockBackend *blk) -- 2.7.4
[Qemu-devel] Periodically print the number of dirty pages in KVM-QEMU
Greetings! I am trying to let qemu periodically print how many memory pages get dirtied since the last call. I added some code in qemu in the following way. I first of all create a thread right before main_loop (vl.c). Below is what this this thread does: void* report_dirty_pages(void* arg) { memory_global_dirty_log_start(); // To turn on the KVM_MEM_LOG_DIRTY_PAGES flags for all the memory pages while(1) { memory_global_sync_dirty_bitmap(get_system_memory()); sleep(5); // Report every 5 minutes //TODO Question: how do I know how many pages get dirtied? } } I got two questions here. The first question is am I doing correct? If I am right, how do I know how many pages get dirtied so that I can print this number? Many thanks for your patience and time. -- Regards, Wang Cheng
Re: [Qemu-devel] [PATCH v10 10/19] vfio iommu: Add blocking notifier to notify DMA_UNMAP
On Sat, 29 Oct 2016 01:32:35 +0530 Kirti Wankhede wrote: > On 10/28/2016 6:10 PM, Alex Williamson wrote: > > On Fri, 28 Oct 2016 15:33:58 +0800 > > Jike Song wrote: > > > >> On 10/27/2016 05:29 AM, Kirti Wankhede wrote: > >>> Added blocking notifier to IOMMU TYPE1 driver to notify vendor drivers > >>> about DMA_UNMAP. > >>> Exported two APIs vfio_register_notifier() and vfio_unregister_notifier(). > >>> Vendor driver should register notifer using these APIs. > >>> Vendor driver should use VFIO_IOMMU_NOTIFY_DMA_UNMAP action to invalidate > >>> mappings. > >>> > >>> Signed-off-by: Kirti Wankhede > >>> Signed-off-by: Neo Jia > >>> Change-Id: I5910d0024d6be87f3e8d3e0ca0eaeaaa0b17f271 > >>> --- > >>> drivers/vfio/vfio.c | 73 + > >>> drivers/vfio/vfio_iommu_type1.c | 89 > >>> - > >>> include/linux/vfio.h| 11 + > >>> 3 files changed, 163 insertions(+), 10 deletions(-) > >>> > >>> diff --git a/drivers/vfio/vfio.c b/drivers/vfio/vfio.c > >>> index 28b50ca14c52..ff05ac6b1e90 100644 > >>> --- a/drivers/vfio/vfio.c > >>> +++ b/drivers/vfio/vfio.c > >>> @@ -1891,6 +1891,79 @@ err_unpin_pages: > >>> } > >>> EXPORT_SYMBOL(vfio_unpin_pages); > >>> > >>> +int vfio_register_notifier(struct device *dev, struct notifier_block *nb) > >>> +{ > >>> + struct vfio_container *container; > >>> + struct vfio_group *group; > >>> + struct vfio_iommu_driver *driver; > >>> + ssize_t ret; > >>> + > >>> + if (!dev || !nb) > >>> + return -EINVAL; > >>> + > >>> + group = vfio_group_get_from_dev(dev); > >>> + if (IS_ERR(group)) > >>> + return PTR_ERR(group); > >>> + > >>> + ret = vfio_group_add_container_user(group); > >>> + if (ret) > >>> + goto err_register_nb; > >>> + > >>> + container = group->container; > >>> + down_read(&container->group_lock); > >>> + > >>> + driver = container->iommu_driver; > >>> + if (likely(driver && driver->ops->register_notifier)) > >>> + ret = driver->ops->register_notifier(container->iommu_data, nb); > >>> + else > >>> + ret = -EINVAL; > >>> + > >>> + up_read(&container->group_lock); > >>> + vfio_group_try_dissolve_container(group); > >>> + > >>> +err_register_nb: > >>> + vfio_group_put(group); > >>> + return ret; > >>> +} > >>> +EXPORT_SYMBOL(vfio_register_notifier); > >>> + > >>> +int vfio_unregister_notifier(struct device *dev, struct notifier_block > >>> *nb) > >>> +{ > >>> + struct vfio_container *container; > >>> + struct vfio_group *group; > >>> + struct vfio_iommu_driver *driver; > >>> + ssize_t ret; > >>> + > >>> + if (!dev || !nb) > >>> + return -EINVAL; > >>> + > >>> + group = vfio_group_get_from_dev(dev); > >>> + if (IS_ERR(group)) > >>> + return PTR_ERR(group); > >>> + > >>> + ret = vfio_group_add_container_user(group); > >>> + if (ret) > >>> + goto err_unregister_nb; > >>> + > >>> + container = group->container; > >>> + down_read(&container->group_lock); > >>> + > >>> + driver = container->iommu_driver; > >>> + if (likely(driver && driver->ops->unregister_notifier)) > >>> + ret = driver->ops->unregister_notifier(container->iommu_data, > >>> +nb); > >>> + else > >>> + ret = -EINVAL; > >>> + > >>> + up_read(&container->group_lock); > >>> + vfio_group_try_dissolve_container(group); > >>> + > >>> +err_unregister_nb: > >>> + vfio_group_put(group); > >>> + return ret; > >>> +} > >>> +EXPORT_SYMBOL(vfio_unregister_notifier); > >>> + > >>> /** > >>> * Module/class support > >>> */ > >>> diff --git a/drivers/vfio/vfio_iommu_type1.c > >>> b/drivers/vfio/vfio_iommu_type1.c > >>> index 5add11a147e1..a4bd331ac0fd 100644 > >>> --- a/drivers/vfio/vfio_iommu_type1.c > >>> +++ b/drivers/vfio/vfio_iommu_type1.c > >>> @@ -37,6 +37,7 @@ > >>> #include > >>> #include > >>> #include > >>> +#include > >>> > >>> #define DRIVER_VERSION "0.2" > >>> #define DRIVER_AUTHOR "Alex Williamson " > >>> @@ -59,6 +60,7 @@ struct vfio_iommu { > >>> struct vfio_domain *external_domain; /* domain for external user */ > >>> struct mutexlock; > >>> struct rb_root dma_list; > >>> + struct blocking_notifier_head notifier; > >>> boolv2; > >>> boolnesting; > >>> }; > >>> @@ -549,7 +551,8 @@ static long vfio_iommu_type1_pin_pages(void > >>> *iommu_data, > >>> > >>> mutex_lock(&iommu->lock); > >>> > >>> - if (!iommu->external_domain) { > >>> + /* Fail if notifier list is empty */ > >>> + if ((!iommu->external_domain) || (!iommu->notifier.head)) { > >>> ret = -EINVAL; > >>> goto pin_done; > >>> } > >>> @@ -768,6 +771,50 @@ static unsigned long vfio_pgsize_bitmap(struct > >>> vfio_iommu *iommu) > >>> return bitmap; > >>> } > >>> > >>> +/* > >>> + * This function finds pfn in domain->external_addr_space->pfn_list for > >>> given > >>> + * iova range. If pfn exist, notify p
Re: [Qemu-devel] [PATCH v5 2/2] qapi: allow blockdev-add for NFS
On 10/28/2016 12:09 PM, Ashijeet Acharya wrote: > Introduce new object 'BlockdevOptionsNFS' in qapi/block-core.json to > support blockdev-add for NFS network protocol driver. Also make a new > struct NFSServer to support tcp connection. > > Signed-off-by: Ashijeet Acharya > --- > qapi/block-core.json | 74 > +--- > 1 file changed, 71 insertions(+), 3 deletions(-) > > diff --git a/qapi/block-core.json b/qapi/block-core.json > index 3592a9d..c0c9b48 100644 > --- a/qapi/block-core.json > +++ b/qapi/block-core.json > @@ -1714,14 +1714,14 @@ > # > # @host_device, @host_cdrom: Since 2.1 > # @gluster: Since 2.7 > -# @nbd, @ssh: Since 2.8 > +# @nbd, @ssh, @nfs: Since 2.8 Might be nice to keep the list alphabetical per release (nfs before ssh). Also minor conflict with a patch to mention 'replication' in this list. > > ## > +# @NFSTransport > +# > +# An enumeration of NFS transport types > +# > +# @inet:TCP transport > +# > +# Since 2.8 > +## > +{ 'enum': 'NFSTransport', > + 'data': [ 'inet' ] } > + > +## > +# @NFSServer > +# > +# Captures the address of the socket Might be worth a mention that this type is explicitly modeled to be a subset of SocketAddress and/or GlusterServer (except see below - I'm not sure it is a subset of either). > +# > +# @type:transport type used for NFS (only TCP supported) > +# > +# @host:host address for NFS server > +# > +# Since 2.8 > +## > +{ 'struct': 'NFSServer', > + 'data': { 'type': 'NFSTransport', > +'host': 'str' } } Uggh. We used 'type':'inet' in SocketAddress, but 'type':'tcp' for GlusterServer. Compared to SocketAddress (the 'inet' branch), we have no 'port' or 'to' parameter, and no optional 'ipv4' or 'ipv6' bools. Do we NEED to be able to distinguish between ipv4 and ipv6 addresses? Did we really botch GlusterServer in the 2.7 release? > + > +## > +# @BlockdevOptionsNfs > +# > +# Driver specific block device option for NFS > +# > +# @server: host address > +# > +# @path:path of the image on the host > +# > +# @user:#optional UID value to use when talking to the > +# server (defaults to 65534 on Windows and getuid() > +# on unix) > +# > +# @group: #optional GID value to use when talking to the > +# server (defaults to 65534 on Windows and getgid() > +# in unix) > +# > +# @tcp-syn-count: #optional number of SYNs during the session > +# establishment (defaults to libnfs default) > +# > +# @readahead-size: #optional set the readahead size in bytes > (defaults > +# to libnfs default) > +# > +# @page-cache-size: #optional set the pagecache size in bytes > (defaults > +# to libnfs default) > +# > +# @debug-level: #optional set the NFS debug level (max 2) > (defaults > +# to libnfs default) > +# > +# Since 2.8 > +## > +{ 'struct': 'BlockdevOptionsNfs', > + 'data': { 'server': 'NFSServer', > +'path': 'str', > +'*user': 'int', > +'*group': 'int', > +'*tcp-syn-count': 'int', > +'*readahead-size': 'int', > +'*page-cache-size': 'int', > +'*debug-level': 'int' } } This looks good. > + > +## > # @BlockdevOptionsCurl > # > # Driver specific block device options for the curl backend. > @@ -2315,7 +2383,7 @@ > # TODO iscsi: Wait for structured options >'luks': 'BlockdevOptionsLUKS', >'nbd':'BlockdevOptionsNbd', > -# TODO nfs: Wait for structured options > + 'nfs':'BlockdevOptionsNfs', >'null-aio': 'BlockdevOptionsNull', >'null-co':'BlockdevOptionsNull', >'parallels': 'BlockdevOptionsGenericFormat', > -- Eric Blake eblake redhat com+1-919-301-3266 Libvirt virtualization library http://libvirt.org signature.asc Description: OpenPGP digital signature
Re: [Qemu-devel] [PATCH v10 10/19] vfio iommu: Add blocking notifier to notify DMA_UNMAP
On 10/28/2016 6:10 PM, Alex Williamson wrote: > On Fri, 28 Oct 2016 15:33:58 +0800 > Jike Song wrote: > >> On 10/27/2016 05:29 AM, Kirti Wankhede wrote: >>> Added blocking notifier to IOMMU TYPE1 driver to notify vendor drivers >>> about DMA_UNMAP. >>> Exported two APIs vfio_register_notifier() and vfio_unregister_notifier(). >>> Vendor driver should register notifer using these APIs. >>> Vendor driver should use VFIO_IOMMU_NOTIFY_DMA_UNMAP action to invalidate >>> mappings. >>> >>> Signed-off-by: Kirti Wankhede >>> Signed-off-by: Neo Jia >>> Change-Id: I5910d0024d6be87f3e8d3e0ca0eaeaaa0b17f271 >>> --- >>> drivers/vfio/vfio.c | 73 + >>> drivers/vfio/vfio_iommu_type1.c | 89 >>> - >>> include/linux/vfio.h| 11 + >>> 3 files changed, 163 insertions(+), 10 deletions(-) >>> >>> diff --git a/drivers/vfio/vfio.c b/drivers/vfio/vfio.c >>> index 28b50ca14c52..ff05ac6b1e90 100644 >>> --- a/drivers/vfio/vfio.c >>> +++ b/drivers/vfio/vfio.c >>> @@ -1891,6 +1891,79 @@ err_unpin_pages: >>> } >>> EXPORT_SYMBOL(vfio_unpin_pages); >>> >>> +int vfio_register_notifier(struct device *dev, struct notifier_block *nb) >>> +{ >>> + struct vfio_container *container; >>> + struct vfio_group *group; >>> + struct vfio_iommu_driver *driver; >>> + ssize_t ret; >>> + >>> + if (!dev || !nb) >>> + return -EINVAL; >>> + >>> + group = vfio_group_get_from_dev(dev); >>> + if (IS_ERR(group)) >>> + return PTR_ERR(group); >>> + >>> + ret = vfio_group_add_container_user(group); >>> + if (ret) >>> + goto err_register_nb; >>> + >>> + container = group->container; >>> + down_read(&container->group_lock); >>> + >>> + driver = container->iommu_driver; >>> + if (likely(driver && driver->ops->register_notifier)) >>> + ret = driver->ops->register_notifier(container->iommu_data, nb); >>> + else >>> + ret = -EINVAL; >>> + >>> + up_read(&container->group_lock); >>> + vfio_group_try_dissolve_container(group); >>> + >>> +err_register_nb: >>> + vfio_group_put(group); >>> + return ret; >>> +} >>> +EXPORT_SYMBOL(vfio_register_notifier); >>> + >>> +int vfio_unregister_notifier(struct device *dev, struct notifier_block *nb) >>> +{ >>> + struct vfio_container *container; >>> + struct vfio_group *group; >>> + struct vfio_iommu_driver *driver; >>> + ssize_t ret; >>> + >>> + if (!dev || !nb) >>> + return -EINVAL; >>> + >>> + group = vfio_group_get_from_dev(dev); >>> + if (IS_ERR(group)) >>> + return PTR_ERR(group); >>> + >>> + ret = vfio_group_add_container_user(group); >>> + if (ret) >>> + goto err_unregister_nb; >>> + >>> + container = group->container; >>> + down_read(&container->group_lock); >>> + >>> + driver = container->iommu_driver; >>> + if (likely(driver && driver->ops->unregister_notifier)) >>> + ret = driver->ops->unregister_notifier(container->iommu_data, >>> + nb); >>> + else >>> + ret = -EINVAL; >>> + >>> + up_read(&container->group_lock); >>> + vfio_group_try_dissolve_container(group); >>> + >>> +err_unregister_nb: >>> + vfio_group_put(group); >>> + return ret; >>> +} >>> +EXPORT_SYMBOL(vfio_unregister_notifier); >>> + >>> /** >>> * Module/class support >>> */ >>> diff --git a/drivers/vfio/vfio_iommu_type1.c >>> b/drivers/vfio/vfio_iommu_type1.c >>> index 5add11a147e1..a4bd331ac0fd 100644 >>> --- a/drivers/vfio/vfio_iommu_type1.c >>> +++ b/drivers/vfio/vfio_iommu_type1.c >>> @@ -37,6 +37,7 @@ >>> #include >>> #include >>> #include >>> +#include >>> >>> #define DRIVER_VERSION "0.2" >>> #define DRIVER_AUTHOR "Alex Williamson " >>> @@ -59,6 +60,7 @@ struct vfio_iommu { >>> struct vfio_domain *external_domain; /* domain for external user */ >>> struct mutexlock; >>> struct rb_root dma_list; >>> + struct blocking_notifier_head notifier; >>> boolv2; >>> boolnesting; >>> }; >>> @@ -549,7 +551,8 @@ static long vfio_iommu_type1_pin_pages(void *iommu_data, >>> >>> mutex_lock(&iommu->lock); >>> >>> - if (!iommu->external_domain) { >>> + /* Fail if notifier list is empty */ >>> + if ((!iommu->external_domain) || (!iommu->notifier.head)) { >>> ret = -EINVAL; >>> goto pin_done; >>> } >>> @@ -768,6 +771,50 @@ static unsigned long vfio_pgsize_bitmap(struct >>> vfio_iommu *iommu) >>> return bitmap; >>> } >>> >>> +/* >>> + * This function finds pfn in domain->external_addr_space->pfn_list for >>> given >>> + * iova range. If pfn exist, notify pfn to registered notifier list. On >>> + * receiving notifier callback, vendor driver should invalidate the >>> mapping and >>> + * call vfio_unpin_pages() to unpin this pfn. With that vfio_pfn for this >>> pfn >>> + * gets removed from rb tre
Re: [Qemu-devel] [PATCH v2 01/11] qapi: add qapi2texi script
On 10/28/2016 11:44 AM, Markus Armbruster wrote: > Marc-André Lureau writes: > >> As the name suggests, the qapi2texi script converts JSON QAPI >> description into a standalone texi file suitable for different target >> formats. >> >> It parses the following kind of blocks with some little variations: >> >> ## >> # = Section >> # == Subsection >> # >> # Some text foo with *emphasis* >> # 1. with a list >> # 2. like that >> # >> # And some code: >> # | $ echo foo >> # | <- do this >> # | -> get that Backwards. Pre-patch, qmp-commands.txt states: > Also, the following notation is used to denote data flow: > > -> data issued by the Client > <- Server data response so you want -> do this <- get that >> # >> ## How much effort is it to get rid of the "little variations" and flag documentation that does not match consistent patterns? A tighter parser that requires specific format, but also diagnoses where comments don't meet that format, is probably going to be easier to maintain in the long run (fewer special cases) even if it is more painful up front (more tweaks to bring things into a consistent layout). >> >> ## >> # @symbol >> # >> # Symbol body ditto ergo sum. Foo bar >> # baz ding. >> # >> # @arg: foo >> # @arg: #optional foo >> # >> # Returns: returns bla bla >> # >> # Or bla blah >> # >> # Since: version >> # Notes: notes, comments can have >> #- itemized list >> #- like this >> # >> #and continue... >> # >> # Example: >> # >> # <- { "execute": "quit" } >> # -> { "return": {} } Again, backwards. >> # >> ## >> >> Thanks to the json declaration, it's able to give extra information >> about the type of arguments and return value expected. >> >> Signed-off-by: Marc-André Lureau >> --- >> scripts/qapi.py| 100 +++- >> scripts/qapi2texi.py | 314 >> + >> docs/qapi-code-gen.txt | 44 +-- >> 3 files changed, 446 insertions(+), 12 deletions(-) >> create mode 100755 scripts/qapi2texi.py > > My review will be easier to follow if you skip ahead qapi-code-gen.txt, > then go to class QAPISchemaParser, then come back here. Commenting on just a few points: >> +if key.startswith("@"): >> +key = key[1:].rstrip(':') > > Treats the colon as optional. I understand you're trying to be > unintrusive, but since we're parsing comments already, we can make the > parser do double duty and enforce consistent comment formatting. But > this isn't the place to discuss the format we want, review of > qapi-code-gen.txt is. Makes sense - since we are writing a parser, we can make it be strict and pick one approved format, rather than allowing two separate formats; the parser will point out what needs to be fixed, and we actually make those fixes then rearrange the series so the fixes come first. > > Taken together: > > * The QAPI parser is hacked to accumulate and exfiltrate some comments > to the QAPIDoc parser. I haven't closely looked at the code yet, just the review comments at this point. During the QAPI parse of the .json file, are we passing the entire ##...## comment (of which there should be at most one per top-level element of the .json file), and then letting QAPIDoc further parse that comment block? Or are you trying to combine both levels of parsing into the same parser object? > General remarks: > > * I feel the only way to keep the API documentation in order as we > develop is to have the parser reject malformed API comments. Agreed. Forcing docs to be well-written up front will pay benefits in ease of maintenance and uniformity of style (it's a lot easier to copy-and-paste a working style if that is the only style to copy from), once we have converted existing documentation to be well-formed. > > * The only way to create a robust and maintainable parser is to specify > the language *first* and *rigorously*. > > * Stacking parsers is not a good idea. Figuring out one parser's > accepted language is hard enough. We do have the nice aspect that there is (should be) at most one ##...## comment body per QAPI (pseudo-JSON) object, so the QAPI parse just needs to find that comment block and associate it with everything else it parsed. Further parsing the documentation comment into sections for output, as well as double-checking sanity aspects (such as no missing or extra parameters) may require more coordination between the parsed QAPI object and the code that parses the comments. >> +++ b/docs/qapi-code-gen.txt >> @@ -45,16 +45,13 @@ QAPI parser does not). At present, there is no place >> where a QAPI >> schema requires the use of JSON numbers or null. >> >> Comments are allowed; anything between an unquoted # and the following >> -newline is ignored. Although there is not yet a documentation >> -generator, a form of stylized comments has developed for cons
Re: [Qemu-devel] [QEMU PATCH v9 2/3] migration: migrate QTAILQ
On 10/28/2016 12:06 PM, Dr. David Alan Gilbert wrote: > * Jianjun Duan (du...@linux.vnet.ibm.com) wrote: >> Currently we cannot directly transfer a QTAILQ instance because of the >> limitation in the migration code. Here we introduce an approach to >> transfer such structures. We created VMStateInfo vmstate_info_qtailq >> for QTAILQ. Similar VMStateInfo can be created for other data structures >> such as list. >> >> This approach will be used to transfer pending_events and ccs_list in spapr >> state. >> >> We also create some macros in qemu/queue.h to access a QTAILQ using pointer >> arithmetic. This ensures that we do not depend on the implementation >> details about QTAILQ in the migration code. >> >> Signed-off-by: Jianjun Duan >> --- >> include/migration/vmstate.h | 20 ++ >> include/qemu/queue.h| 61 + >> migration/trace-events | 4 +++ >> migration/vmstate.c | 67 >> + >> 4 files changed, 152 insertions(+) >> >> diff --git a/include/migration/vmstate.h b/include/migration/vmstate.h >> index d0e37b5..318a6f1 100644 >> --- a/include/migration/vmstate.h >> +++ b/include/migration/vmstate.h >> @@ -251,6 +251,7 @@ extern const VMStateInfo vmstate_info_timer; >> extern const VMStateInfo vmstate_info_buffer; >> extern const VMStateInfo vmstate_info_unused_buffer; >> extern const VMStateInfo vmstate_info_bitmap; >> +extern const VMStateInfo vmstate_info_qtailq; >> >> #define type_check_2darray(t1,t2,n,m) ((t1(*)[n][m])0 - (t2*)0) >> #define type_check_array(t1,t2,n) ((t1(*)[n])0 - (t2*)0) >> @@ -662,6 +663,25 @@ extern const VMStateInfo vmstate_info_bitmap; >> .offset = offsetof(_state, _field),\ >> } >> >> +/* For QTAILQ that need customized handling. >> + * Target QTAILQ needs be properly initialized. >> + * _type: type of QTAILQ element >> + * _next: name of QTAILQ entry field in QTAILQ element >> + * _vmsd: VMSD for QTAILQ element >> + * size: size of QTAILQ element >> + * start: offset of QTAILQ entry in QTAILQ element >> + */ >> +#define VMSTATE_QTAILQ_V(_field, _state, _version, _vmsd, _type, _next) \ >> +{\ >> +.name = (stringify(_field)), \ >> +.version_id = (_version), \ >> +.vmsd = &(_vmsd),\ >> +.size = sizeof(_type), \ >> +.info = &vmstate_info_qtailq,\ >> +.offset = offsetof(_state, _field),\ >> +.start= offsetof(_type, _next), \ >> +} >> + >> /* _f : field name >> _f_n : num of elements field_name >> _n : num of elements >> diff --git a/include/qemu/queue.h b/include/qemu/queue.h >> index 342073f..16af127 100644 >> --- a/include/qemu/queue.h >> +++ b/include/qemu/queue.h >> @@ -438,4 +438,65 @@ struct { >> \ >> #define QTAILQ_PREV(elm, headname, field) \ >> (*(((struct headname *)((elm)->field.tqe_prev))->tqh_last)) >> >> +#define field_at_offset(base, offset, type) >>\ >> +((type) (((char *) (base)) + (offset))) >> + >> +typedef struct DUMB_Q_ENTRY DUMB_Q_ENTRY; >> +typedef struct DUMB_Q DUMB_Q; >> + >> +struct DUMB_Q_ENTRY { >> +QTAILQ_ENTRY(DUMB_Q_ENTRY) next; >> +}; >> + >> +struct DUMB_Q { >> +QTAILQ_HEAD(DUMB_Q_HEAD, DUMB_Q_ENTRY) head; >> +}; > > OK, good we've got rid of the hard coded offsets; thanks! > >> +#define dumb_q ((DUMB_Q *) 0) >> +#define dumb_qh ((typeof(dumb_q->head) *) 0) >> +#define dumb_qe ((DUMB_Q_ENTRY *) 0) > > Note that 'dumb' and 'dummy' are completely different words; > this is a dummy not a dumb. > OK. >> +/* >> + * Offsets of layout of a tail queue head. >> + */ >> +#define QTAILQ_FIRST_OFFSET ((size_t) &(QTAILQ_FIRST(dumb_qh))) > > Isn't that just offsetof(dumb_qh, tqh_first) ? Yes. But I don't want to depend on the inside of the type if it is possible. QTAILQ_FIRST is a defined access macro. > >> +#define QTAILQ_LAST_OFFSET (offsetof(typeof(dumb_q->head), tqh_last)) > > Similarly isnt't that just offsetof(DUMB_Q_HEAD, tqh_last) ? > Similarly, DUMB_Q_HEAD may not be a type name in the future. Thanks, Jianjun >> +/* >> + * Raw access of elements of a tail queue >> + */ >> +#define QTAILQ_RAW_FIRST(head) >>\ >> +(*field_at_offset(head, QTAILQ_FIRST_OFFSET, void **)) >> +#define QTAILQ_RAW_LAST(head) >>\ >> +(*field_at_offset(head, QTAILQ_LAST_OFFSET, void ***)) >> + >> +/* >> + * Offsets of layout of a tail queue element. >> + */ >> +#define
Re: [Qemu-devel] [QEMU PATCH v9 2/3] migration: migrate QTAILQ
* Jianjun Duan (du...@linux.vnet.ibm.com) wrote: > Currently we cannot directly transfer a QTAILQ instance because of the > limitation in the migration code. Here we introduce an approach to > transfer such structures. We created VMStateInfo vmstate_info_qtailq > for QTAILQ. Similar VMStateInfo can be created for other data structures > such as list. > > This approach will be used to transfer pending_events and ccs_list in spapr > state. > > We also create some macros in qemu/queue.h to access a QTAILQ using pointer > arithmetic. This ensures that we do not depend on the implementation > details about QTAILQ in the migration code. > > Signed-off-by: Jianjun Duan > --- > include/migration/vmstate.h | 20 ++ > include/qemu/queue.h| 61 + > migration/trace-events | 4 +++ > migration/vmstate.c | 67 > + > 4 files changed, 152 insertions(+) > > diff --git a/include/migration/vmstate.h b/include/migration/vmstate.h > index d0e37b5..318a6f1 100644 > --- a/include/migration/vmstate.h > +++ b/include/migration/vmstate.h > @@ -251,6 +251,7 @@ extern const VMStateInfo vmstate_info_timer; > extern const VMStateInfo vmstate_info_buffer; > extern const VMStateInfo vmstate_info_unused_buffer; > extern const VMStateInfo vmstate_info_bitmap; > +extern const VMStateInfo vmstate_info_qtailq; > > #define type_check_2darray(t1,t2,n,m) ((t1(*)[n][m])0 - (t2*)0) > #define type_check_array(t1,t2,n) ((t1(*)[n])0 - (t2*)0) > @@ -662,6 +663,25 @@ extern const VMStateInfo vmstate_info_bitmap; > .offset = offsetof(_state, _field),\ > } > > +/* For QTAILQ that need customized handling. > + * Target QTAILQ needs be properly initialized. > + * _type: type of QTAILQ element > + * _next: name of QTAILQ entry field in QTAILQ element > + * _vmsd: VMSD for QTAILQ element > + * size: size of QTAILQ element > + * start: offset of QTAILQ entry in QTAILQ element > + */ > +#define VMSTATE_QTAILQ_V(_field, _state, _version, _vmsd, _type, _next) \ > +{\ > +.name = (stringify(_field)), \ > +.version_id = (_version), \ > +.vmsd = &(_vmsd),\ > +.size = sizeof(_type), \ > +.info = &vmstate_info_qtailq,\ > +.offset = offsetof(_state, _field),\ > +.start= offsetof(_type, _next), \ > +} > + > /* _f : field name > _f_n : num of elements field_name > _n : num of elements > diff --git a/include/qemu/queue.h b/include/qemu/queue.h > index 342073f..16af127 100644 > --- a/include/qemu/queue.h > +++ b/include/qemu/queue.h > @@ -438,4 +438,65 @@ struct { >\ > #define QTAILQ_PREV(elm, headname, field) \ > (*(((struct headname *)((elm)->field.tqe_prev))->tqh_last)) > > +#define field_at_offset(base, offset, type) > \ > +((type) (((char *) (base)) + (offset))) > + > +typedef struct DUMB_Q_ENTRY DUMB_Q_ENTRY; > +typedef struct DUMB_Q DUMB_Q; > + > +struct DUMB_Q_ENTRY { > +QTAILQ_ENTRY(DUMB_Q_ENTRY) next; > +}; > + > +struct DUMB_Q { > +QTAILQ_HEAD(DUMB_Q_HEAD, DUMB_Q_ENTRY) head; > +}; OK, good we've got rid of the hard coded offsets; thanks! > +#define dumb_q ((DUMB_Q *) 0) > +#define dumb_qh ((typeof(dumb_q->head) *) 0) > +#define dumb_qe ((DUMB_Q_ENTRY *) 0) Note that 'dumb' and 'dummy' are completely different words; this is a dummy not a dumb. > +/* > + * Offsets of layout of a tail queue head. > + */ > +#define QTAILQ_FIRST_OFFSET ((size_t) &(QTAILQ_FIRST(dumb_qh))) Isn't that just offsetof(dumb_qh, tqh_first) ? > +#define QTAILQ_LAST_OFFSET (offsetof(typeof(dumb_q->head), tqh_last)) Similarly isnt't that just offsetof(DUMB_Q_HEAD, tqh_last) ? > +/* > + * Raw access of elements of a tail queue > + */ > +#define QTAILQ_RAW_FIRST(head) > \ > +(*field_at_offset(head, QTAILQ_FIRST_OFFSET, void **)) > +#define QTAILQ_RAW_LAST(head) > \ > +(*field_at_offset(head, QTAILQ_LAST_OFFSET, void ***)) > + > +/* > + * Offsets of layout of a tail queue element. > + */ > +#define QTAILQ_NEXT_OFFSET ((size_t) (&QTAILQ_NEXT(dumb_qe, next))) > +#define QTAILQ_PREV_OFFSET (offsetof(typeof(dumb_qe->next), tqe_prev)) Similar comments to the pair above. Dave P.S. I'm out next week, so please someone else jump in. > +/* > + * Raw access of elements of a tail entry > + */ > +#define QTAILQ_RAW_NEXT(elm, entry) > \ > +
Re: [Qemu-devel] [PATCH v3] block/vxhs: Add Veritas HyperScale VxHS block device support
On Fri, Oct 28, 2016 at 12:44:27AM -0700, Ashish Mittal wrote: > This patch adds support for a new block device type called "vxhs". > Source code for the qnio library that this code loads can be downloaded from: > https://github.com/MittalAshish/libqnio.git > > Sample command line using the JSON syntax: > ./qemu-system-x86_64 -name instance-0008 -S -vnc 0.0.0.0:0 -k en-us > -vga cirrus -device virtio-balloon-pci,id=balloon0,bus=pci.0,addr=0x5 > -msg timestamp=on > 'json:{"driver":"vxhs","vdisk_id":"{c3e9095a-a5ee-4dce-afeb-2a59fb387410}", > "server":{"host":"172.172.17.4","port":""}}' > > Sample command line using the URI syntax: > qemu-img convert -f raw -O raw -n > /var/lib/nova/instances/_base/0c5eacd5ebea5ed914b6a3e7b18f1ce734c386ad > vxhs://192.168.0.1:/%7Bc6718f6b-0401-441d-a8c3-1f0064d75ee0%7D > > Signed-off-by: Ashish Mittal > --- > v3 changelog: > (1) Added QAPI schema for the VxHS driver. > > v2 changelog: > (1) Changes done in response to v1 comments. > > TODO: > (1) Add qemu-iotest > (2) We need to be able to free all resources once we close the last vxhs > drive. > > block/Makefile.objs | 2 + > block/trace-events | 21 ++ > block/vxhs.c | 669 > +++ > configure| 41 > qapi/block-core.json | 20 +- > 5 files changed, 751 insertions(+), 2 deletions(-) > create mode 100644 block/vxhs.c > > diff --git a/block/Makefile.objs b/block/Makefile.objs > index 67a036a..58313a2 100644 > --- a/block/Makefile.objs > +++ b/block/Makefile.objs > @@ -18,6 +18,7 @@ block-obj-$(CONFIG_LIBNFS) += nfs.o > block-obj-$(CONFIG_CURL) += curl.o > block-obj-$(CONFIG_RBD) += rbd.o > block-obj-$(CONFIG_GLUSTERFS) += gluster.o > +block-obj-$(CONFIG_VXHS) += vxhs.o > block-obj-$(CONFIG_ARCHIPELAGO) += archipelago.o > block-obj-$(CONFIG_LIBSSH2) += ssh.o > block-obj-y += accounting.o dirty-bitmap.o > @@ -38,6 +39,7 @@ rbd.o-cflags := $(RBD_CFLAGS) > rbd.o-libs := $(RBD_LIBS) > gluster.o-cflags := $(GLUSTERFS_CFLAGS) > gluster.o-libs := $(GLUSTERFS_LIBS) > +vxhs.o-libs:= $(VXHS_LIBS) > ssh.o-cflags := $(LIBSSH2_CFLAGS) > ssh.o-libs := $(LIBSSH2_LIBS) > archipelago.o-libs := $(ARCHIPELAGO_LIBS) > diff --git a/block/trace-events b/block/trace-events > index 05fa13c..94249ee 100644 > --- a/block/trace-events > +++ b/block/trace-events > @@ -114,3 +114,24 @@ qed_aio_write_data(void *s, void *acb, int ret, uint64_t > offset, size_t len) "s > qed_aio_write_prefill(void *s, void *acb, uint64_t start, size_t len, > uint64_t offset) "s %p acb %p start %"PRIu64" len %zu offset %"PRIu64 > qed_aio_write_postfill(void *s, void *acb, uint64_t start, size_t len, > uint64_t offset) "s %p acb %p start %"PRIu64" len %zu offset %"PRIu64 > qed_aio_write_main(void *s, void *acb, int ret, uint64_t offset, size_t len) > "s %p acb %p ret %d offset %"PRIu64" len %zu" > + > +# block/vxhs.c > +vxhs_iio_callback(int error, int reason) "ctx is NULL: error %d, reason %d" > +vxhs_setup_qnio(void *s) "Context to HyperScale IO manager = %p" > +vxhs_iio_callback_chnfail(int err, int error) "QNIO channel failed, no i/o > %d, %d" > +vxhs_iio_callback_unknwn(int opcode, int err) "unexpected opcode %d, errno > %d" > +vxhs_open_fail(int ret) "Could not open the device. Error = %d" > +vxhs_open_epipe(int ret) "Could not create a pipe for device. Bailing out. > Error=%d" > +vxhs_aio_rw_invalid(int req) "Invalid I/O request iodir %d" > +vxhs_aio_rw_ioerr(char *guid, int iodir, uint64_t size, uint64_t off, void > *acb, int ret, int err) "IO ERROR (vDisk %s) FOR : Read/Write = %d size = %lu > offset = %lu ACB = %p. Error = %d, errno = %d" > +vxhs_get_vdisk_stat_err(char *guid, int ret, int err) "vDisk (%s) stat ioctl > failed, ret = %d, errno = %d" > +vxhs_get_vdisk_stat(char *vdisk_guid, uint64_t vdisk_size) "vDisk %s stat > ioctl returned size %lu" > +vxhs_qnio_iio_open(const char *ip) "Failed to connect to storage agent on > host-ip %s" > +vxhs_qnio_iio_devopen(const char *fname) "Failed to open vdisk device: %s" > +vxhs_complete_aio(void *acb, uint64_t ret) "aio failed acb %p ret %ld" > +vxhs_parse_uri_filename(const char *filename) "URI passed via > bdrv_parse_filename %s" > +vxhs_qemu_init_vdisk(const char *vdisk_id) "vdisk_id from json %s" > +vxhs_parse_uri_hostinfo(int num, char *host, int port) "Host %d: IP %s, Port > %d" > +vxhs_qemu_init(char *of_vsa_addr, int port) "Adding host %s:%d to > BDRVVXHSState" > +vxhs_qemu_init_filename(const char *filename) "Filename passed as %s" > +vxhs_close(char *vdisk_guid) "Closing vdisk %s" > diff --git a/block/vxhs.c b/block/vxhs.c > new file mode 100644 > index 000..08ad681 > --- /dev/null > +++ b/block/vxhs.c > @@ -0,0 +1,669 @@ > +/* > + * QEMU Block driver for Veritas HyperScale (VxHS) > + * > + * This work is licensed under the terms of the GNU GPL, version 2 or later. > + * See the COPYING file in the top-level directory. > + * > + */ > +
Re: [Qemu-devel] [PATCH v2 0/7] blockjobs: preliminary refactoring work, Pt 1
On Thu, Oct 27, 2016 at 12:06:54PM -0400, John Snow wrote: > This is a follow-up to patches 2-6 of: > [PATCH v2 00/11] blockjobs: Fix transactional race condition > > That series started trying to refactor blockjobs with the goal of > internalizing BlockJob state as a side effect of having gone through > the effort of figuring out which commands were "safe" to call on > a Job that has no coroutine object. > > I've split out the less contentious bits so I can move forward with my > original work of focusing on the transactional race condition in a > different series. > > Functionally the biggest difference here is the presence of "internal" > block jobs, which do not emit QMP events or show up in block query > requests. This is done for the sake of replication jobs, which should > not be interfering with the public jobs namespace. > > === > v2 > === > > 01:Cleaned up error message, fixed strcmp oversight, added assert() > 02-07: Added R-Bs. (Does everyone else pronounce this as "Arby's" too?) Well, now I will! > > > > For convenience, this branch is available at: > https://github.com/jnsnow/qemu.git branch job-refactor-pt1 > https://github.com/jnsnow/qemu/tree/job-refactor-pt1 > > This version is tagged job-refactor-pt1-v2: > https://github.com/jnsnow/qemu/releases/tag/job-refactor-pt1-v2 > > John Snow (7): > blockjobs: hide internal jobs from management API > blockjobs: Allow creating internal jobs > Replication/Blockjobs: Create replication jobs as internal > blockjob: centralize QMP event emissions > Blockjobs: Internalize user_pause logic > blockjobs: split interface into public/private, Part 1 > blockjobs: fix documentation > > block/backup.c | 5 +- > block/commit.c | 10 +- > block/mirror.c | 28 +++-- > block/replication.c | 14 +-- > block/stream.c | 9 +- > block/trace-events | 5 +- > blockdev.c | 74 + > blockjob.c | 113 +++ > include/block/block.h| 3 +- > include/block/block_int.h| 26 ++--- > include/block/blockjob.h | 257 > +++ > include/block/blockjob_int.h | 232 ++ > qemu-img.c | 5 +- > tests/test-blockjob-txn.c| 5 +- > tests/test-blockjob.c| 4 +- > 15 files changed, 446 insertions(+), 344 deletions(-) > create mode 100644 include/block/blockjob_int.h > > -- > 2.7.4 > Thanks, Applied to my block branch: git://github.com/codyprime/qemu-kvm-jtc.git block -Jeff
Re: [Qemu-devel] [PULL 0/6] ui patch queue.
On 28 October 2016 at 13:11, Gerd Hoffmann wrote: > Hi, > > Here comes the UI patch queue with bugfixes for gtk and curses UIs and > the baum braille support. > > I've cherry-picked from Samuel's patches the ones which are ready to > merge. There is more in the pipeline for better unicode support in > curses, but those will probably not make the 2.8 freeze deadline. > > please pull, > Gerd > > The following changes since commit db4df20de86c6e8ecd6c9f042c029ffb9f9cddac: > > trace: Fix 'char **' compilation error in simple backend (2016-10-27 > 19:24:15 +0100) > > are available in the git repository at: > > git://git.kraxel.org/qemu tags/pull-ui-20161028-1 > > for you to fetch changes up to 8ddc5bf9e5de51c2a4842c01dd3a97f5591776fd: > > curses: Use cursesw instead of curses (2016-10-28 11:19:38 +0200) > > > braille fixes and improvements. > curses fix, switch to cursesw. > gtk bugfixes. Applied, thanks. -- PMM
[Qemu-devel] [PATCH Risu 3/3] Initial implemention for ppc64le
From: Jose Ricardo Ziviani - This commit adds the initial implementation of ppc64le support (client and server) for Risu. Signed-off-by: Jose Ricardo Ziviani --- configure | 6 ++ risu_ppc64le.c | 92 ++ risu_reginfo_ppc64le.c | 175 + risu_reginfo_ppc64le.h | 36 ++ test_ppc64le.s | 52 +++ 5 files changed, 361 insertions(+) create mode 100644 risu_ppc64le.c create mode 100644 risu_reginfo_ppc64le.c create mode 100644 risu_reginfo_ppc64le.h create mode 100644 test_ppc64le.s diff --git a/configure b/configure index 748b48a..3e239f3 100755 --- a/configure +++ b/configure @@ -22,6 +22,12 @@ guess_arch() { ARCH="arm" elif check_define __aarch64__ ; then ARCH="aarch64" +elif check_define __powerpc64__ ; then +if check_define __BIG_ENDIAN__; then +ARCH="ppc64" +else +ARCH="ppc64le" +fi else echo "This cpu is not supported by risu. Try -h. " >&2 exit 1 diff --git a/risu_ppc64le.c b/risu_ppc64le.c new file mode 100644 index 000..811dd77 --- /dev/null +++ b/risu_ppc64le.c @@ -0,0 +1,92 @@ +/** + * Copyright (c) 2013 Linaro Limited + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Jose Ricardo Ziviani - initial implementation + * based on Claudio Fontana's risu_aarch64.c + * based on Peter Maydell's risu_arm.c + */ + +#include +#include +#include + +#include "risu.h" +#include "risu_reginfo_ppc64le.h" + +struct reginfo master_ri, apprentice_ri; + +void advance_pc(void *vuc) +{ +ucontext_t *uc = (ucontext_t*)vuc; +uc->uc_mcontext.regs->nip += 4; +} + +int send_register_info(int sock, void *uc) +{ +struct reginfo ri; +reginfo_init(&ri, uc); +return send_data_pkt(sock, &ri, sizeof(ri)); +} + +/* Read register info from the socket and compare it with that from the + * ucontext. Return 0 for match, 1 for end-of-test, 2 for mismatch. + * NB: called from a signal handler. + */ +int recv_and_compare_register_info(int sock, void *uc) +{ +int resp = 0; +reginfo_init(&master_ri, uc); +if (recv_data_pkt(sock, &apprentice_ri, sizeof(apprentice_ri))) { +printf("Packed mismatch\n"); +resp = 2; + +} else if (!reginfo_is_eq(&master_ri, &apprentice_ri, uc)) +{ +/* mismatch */ +resp = 2; +} +else if (master_ri.faulting_insn == 0x5af1) +{ +/* end of test */ +resp = 1; +} +else +{ +/* either successful match or expected undef */ +resp = 0; +} +send_response_byte(sock, resp); + +return resp; +} + +/* Print a useful report on the status of the last comparison + * done in recv_and_compare_register_info(). This is called on + * exit, so need not restrict itself to signal-safe functions. + * Should return 0 if it was a good match (ie end of test) + * and 1 for a mismatch. + */ +int report_match_status(void) +{ +fprintf(stderr, "match status...\n"); +int resp = reginfo_is_eq(&master_ri, &apprentice_ri, NULL); +if (resp) { +fprintf(stderr, "\e[1;34mTest passed successfuly\e[0m\n"); +return 0; +} + +fprintf(stderr, "\n [master reginfo]\n"); +reginfo_dump(&master_ri, 1); + +fprintf(stderr, "\n*** [apprentice reginfo]\n"); +reginfo_dump(&apprentice_ri, 0); + +fprintf(stderr, "\e[1;31mmismatch!\e[0m\n"); + +return resp; +} diff --git a/risu_reginfo_ppc64le.c b/risu_reginfo_ppc64le.c new file mode 100644 index 000..b79ecfc --- /dev/null +++ b/risu_reginfo_ppc64le.c @@ -0,0 +1,175 @@ +/** + * Copyright (c) 2013 Linaro Limited + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Jose Ricardo Ziviani - initial implementation + * based on Claudio Fontana's risu_aarch64.c + * based on Peter Maydell's risu_arm.c + */ + +#include +#include +#include +#include + +#include "risu.h" +#include "risu_reginfo_ppc64le.h" + +#define XER 37 +#define CCR 38 + +/* reginfo_init: initialize with a ucontext */ +void reginfo_init(struct reginfo *ri, ucontext_t *uc) +{ +ri->faulting_insn = *((uint32_t *)uc->uc_mcontext.regs->nip
Re: [Qemu-devel] [PATCH] tcg: correct 32-bit tcg_gen_ld8s_i64 sign-extension
On 10/28/2016 05:42 AM, Peter Maydell wrote: On 28 October 2016 at 00:35, Joseph Myers wrote: The version of tcg_gen_ld8s_i64 for 32-bit systems does a load into the low part of the return value - then attempts a sign extension into the high part, but wrongly sets the high part to a sign extension of itself rather than of the low part. This results in TCG internal errors from the use of the uninitialized high part (in some GCC tests of AArch64 NEON shift intrinsics, in particular). This patch corrects the sign-extension logic, making it match other functions such as tcg_gen_ld16s_i64. Signed-off-by: Joseph Myers --- diff --git a/tcg/tcg-op.c b/tcg/tcg-op.c index bb2bfee..43d34ea 100644 --- a/tcg/tcg-op.c +++ b/tcg/tcg-op.c @@ -790,7 +790,7 @@ void tcg_gen_ld8u_i64(TCGv_i64 ret, TCGv_ptr arg2, tcg_target_long offset) void tcg_gen_ld8s_i64(TCGv_i64 ret, TCGv_ptr arg2, tcg_target_long offset) { tcg_gen_ld8s_i32(TCGV_LOW(ret), arg2, offset); -tcg_gen_sari_i32(TCGV_HIGH(ret), TCGV_HIGH(ret), 31); +tcg_gen_sari_i32(TCGV_HIGH(ret), TCGV_LOW(ret), 31); } void tcg_gen_ld16u_i64(TCGv_i64 ret, TCGv_ptr arg2, tcg_target_long offset) Reviewed-by: Peter Maydell As far as I can tell this bug was introduced in commit a7812ae4123 in 2008, which is a remarkably long time for a basic bug like this to persist... Indeed, but the function is used exactly once in the entire source tree, as a part of target-arm's read_vec_element for aarch64. And I suspect that virtually all of the aarch64 testing we've ever done has been with a 64-bit host. r~
[Qemu-devel] [PATCH Risu 2/3] Isolates Arm specific subroutines out from risugen main file
- In order to make risugen more agnostic to different archs, a new module is created to handle Arm instrunctions. This module, as well as the Power module, is dinamically called based on the .mode directive defined in each risu file. Signed-off-by: Jose Ricardo Ziviani --- risugen| 1018 ++--- risugen_arm.pm | 1075 2 files changed, 1105 insertions(+), 988 deletions(-) create mode 100644 risugen_arm.pm diff --git a/risugen b/risugen index 892a6dc..3c88c9b 100755 --- a/risugen +++ b/risugen @@ -9,6 +9,7 @@ # Contributors: # Peter Maydell (Linaro) - initial implementation # Claudio Fontana (Linaro) - initial aarch64 support +# Jose Ricardo Ziviani (IBM) - initial ppc64 support and arch isolation ### # risugen -- generate a test binary file for use with risu @@ -17,12 +18,9 @@ use strict; use Getopt::Long; use Data::Dumper; +use Module::Load; use Text::Balanced qw { extract_bracketed extract_multiple }; -my $periodic_reg_random = 1; -my $enable_aarch64_ld1 = 0; - -my @insns; my %insn_details; # Note that we always start in ARM mode even if the C code was compiled for @@ -31,941 +29,21 @@ my %insn_details; # an arm or thumb insn?); test_thumb tells us which mode we need to switch # to to emit the insns under test. # Use .mode aarch64 to start in Aarch64 mode. - my $is_aarch64 = 0; # are we in aarch64 mode? # For aarch64 it only makes sense to put the mode directive at the # beginning, and there is no switching away from aarch64 to arm/thumb. -my $is_thumb = 0; # are we currently in Thumb mode? +# Use .mode ppc64 to start in PowerPC64 mode. +my $is_ppc64 = 0; # are we in ppc64 mode? + my $test_thumb = 0; # should test code be Thumb mode? my @pattern_re = ();# include pattern my @not_pattern_re = ();# exclude pattern -my $bytecount; - -# Maximum alignment restriction permitted for a memory op. -my $MAXALIGN = 64; - -# An instruction pattern as parsed from the config file turns into -# a record like this: -# name # name of the pattern -# width # 16 or 32 -# fixedbits # values of the fixed bits -# fixedbitmask # 1s indicate locations of the fixed bits -# blocks# hash of blockname->contents (for constraints etc) -# fields# array of arrays, each element is [ varname, bitpos, bitmask ] -# -# We store these in the insn_details hash. - # Valid block names (keys in blocks hash) my %valid_blockname = ( constraints => 1, memory => 1 ); -sub open_bin -{ -my ($fname) = @_; -open(BIN, ">", $fname) or die "can't open %fname: $!"; -$bytecount = 0; -} - -sub close_bin -{ -close(BIN) or die "can't close output file: $!"; -} - -sub insn32($) -{ -my ($insn) = @_; -print BIN pack("V", $insn); -$bytecount += 4; -} - -sub insn16($) -{ -my ($insn) = @_; -print BIN pack("v", $insn); -$bytecount += 2; -} - -# for thumb only -sub thumb_align4() -{ -if ($bytecount & 3) { -insn16(0xbf00); # NOP -} -} - -# used for aarch64 only for now -sub data_barrier() -{ -if ($is_aarch64) { -insn32(0xd5033f9f); # DSB SYS -} -} - -# The space 0xE7F___F_ is guaranteed to always UNDEF -# and not to be allocated for insns in future architecture -# revisions. So we use it for our 'do comparison' and -# 'end of test' instructions. -# We fill in the middle bit with a randomly selected -# 'e5a' just in case the space is being used by somebody -# else too. - -# For Thumb the equivalent space is 0xDExx -# and we use 0xDEEx. - -# So the last nibble indicates the desired operation: -my $OP_COMPARE = 0;# compare registers -my $OP_TESTEND = 1;# end of test, stop -my $OP_SETMEMBLOCK = 2;# r0 is address of memory block (8192 bytes) -my $OP_GETMEMBLOCK = 3;# add the address of memory block to r0 -my $OP_COMPAREMEM = 4; # compare memory block - -sub write_thumb_risuop($) -{ -my ($op) = @_; -insn16(0xdee0 | $op); -} - -sub write_arm_risuop($) -{ -my ($op) = @_; -insn32(0xe7fe5af0 | $op); -} - -sub write_aarch64_risuop($) -{ -# instr with bits (28:27) == 0 0 are UNALLOCATED -my ($op) = @_; -insn32(0x5af0 | $op); -} - -sub write_risuop($) -{ -my ($op) = @_; -if ($is_thumb) { -write_thumb_risuop($op); -} elsif ($is_aarch64) { -write_aarch64_risuop($op); -} else { -write_arm_risuop($op); -} -} - -sub write_switch_to_thumb() -{ -# Switch to thumb if we're not already there -if (!$is_thumb) { -# Note that we have to clean up r0 afterwards -# so it isn't tainted with a value which depends -# on PC (and which might differ between hw and -# qemu/valgrind/etc) -insn32(0xe28f0001); # add r0, pc, #1 -insn32(0xe12fff10); # bx r0
[Qemu-devel] [PATCH Risu 0/3] Risu support for PPC64LE
From: Jose Ricardo Ziviani This is an initial effort to have RISU working for PPC64LE. I also made some changes to isolate risugen, creating two modules (risugen_arm.pm and risugen_ppc64le.pm) to implement specific instructions in it. Suggestions are welcome! :) TODOS: - improve load/store instruction generation - improve initial random values for FP and Vector regs. Jose Ricardo Ziviani (3): Implementation of ppc64le module for risugen and risufile Isolates Arm specific subroutines out from risugen main file Initial implemention for ppc64le configure |6 + ppc64le.risu | 3459 risu_ppc64le.c | 92 ++ risu_reginfo_ppc64le.c | 175 +++ risu_reginfo_ppc64le.h | 36 + risugen| 1018 +- risugen_arm.pm | 1075 +++ risugen_ppc64le.pm | 460 +++ test_ppc64le.s | 52 + 9 files changed, 5385 insertions(+), 988 deletions(-) create mode 100644 ppc64le.risu create mode 100644 risu_ppc64le.c create mode 100644 risu_reginfo_ppc64le.c create mode 100644 risu_reginfo_ppc64le.h create mode 100644 risugen_arm.pm create mode 100644 risugen_ppc64le.pm create mode 100644 test_ppc64le.s -- 2.7.4
Re: [Qemu-devel] [Xen-devel] [PATCH v2] xenfv: set has_acpi_build to false
On Fri, 28 Oct 2016, Wei Liu wrote: > On Thu, Oct 27, 2016 at 11:58:29AM -0700, Stefano Stabellini wrote: > > On Thu, 27 Oct 2016, Sander Eikelenboom wrote: > > > Thursday, October 27, 2016, 3:51:09 PM, you wrote: > > > > > > > Xen's toolstack is in charge of building ACPI tables. Skip ACPI table > > > > building and loading in QEMU by setting has_acpi_build to false for > > > > xenfv machine. > > > > > > > This issue is discovered due to direct kernel boot on Xen doesn't boot > > > > anymore, because the new ACPI tables cause the guest to exceed its > > > > memory allocation limit. > > > > > > > Reported-by: Sander Eikelenboom > > > > Signed-off-by: Wei Liu > > > > > > Just given this patch a spin and you may add a: > > > Tested-by: Sander Eikelenboom > > > > The problem with this patch is that it only covers the xenfv machine > > case, which is default, but QEMU can also be invoked with -M > > pc,accel=xen. That case wouldn't be fixed by this patch. Wei, you can > > test it by adding "xen_platform_pci=0" to the VM config file. > > That's why we probably need a new option, similar to has_acpi_build, but > > that can be changed at accelerator init time. > > > > Do you mean we should add a new field to AccelClass? I mean that this patch is insufficient unfortunately. I am not sure about what is the best way to solve this problem, but Eduardo suggested to add a new PCMachineState field: http://marc.info/?l=qemu-devel&m=147749203112422&w=2
Re: [Qemu-devel] [PATCH v2 3/3] target-m68k: shift ops manage word and byte operands
On 10/27/2016 02:43 PM, Laurent Vivier wrote: +static inline void shift_reg(DisasContext *s, uint16_t insn, int opsize) { -TCGv reg, s32; -TCGv_i64 t64, s64; int logical = insn & 8; +int left = insn & 0x100; +int bits = opsize_bytes(opsize) * 8; +TCGv reg = gen_extend(DREG(insn, 0), opsize, !logical); +TCGv s32; +TCGv_i64 t64, s64; +TCGv zero; -reg = DREG(insn, 0); t64 = tcg_temp_new_i64(); s64 = tcg_temp_new_i64(); s32 = tcg_temp_new(); @@ -2402,44 +2420,144 @@ DISAS_INSN(shift_reg) tcg_gen_andi_i32(s32, DREG(insn, 9), 63); tcg_gen_extu_i32_i64(s64, s32); -/* Non-arithmetic shift clears V. Use it as a source zero here. */ -tcg_gen_movi_i32(QREG_CC_V, 0); +zero = tcg_const_i32(0); +tcg_gen_mov_i32(QREG_CC_V, zero); -if (insn & 0x100) { -tcg_gen_extu_i32_i64(t64, reg); +tcg_gen_extu_i32_i64(t64, reg); +if (left) { +tcg_gen_shli_i64(t64, t64, 32 - bits); tcg_gen_shl_i64(t64, t64, s64); tcg_temp_free_i64(s64); tcg_gen_extr_i64_i32(QREG_CC_N, QREG_CC_C, t64); tcg_temp_free_i64(t64); +tcg_gen_sari_i32(QREG_CC_N, QREG_CC_N, 32 - bits); tcg_gen_andi_i32(QREG_CC_C, QREG_CC_C, 1); + +/* Note that ColdFire always clears V, + while M68000 sets if the most significant bit is changed at + any time during the shift operation */ +if (!logical && m68k_feature(s->env, M68K_FEATURE_M68000)) { +TCGv t0 = tcg_temp_new(); +TCGv t1 = tcg_temp_new(); +TCGv t2 = tcg_const_i32(bits); + +tcg_gen_sub_i32(t2, t2, s32); /* t2 = bits - count */ + +tcg_gen_sari_i32(t0, reg, 31); +tcg_gen_sar_i32(t1, reg, t2); +tcg_temp_free(t2); +tcg_gen_setcond_i32(TCG_COND_NE, QREG_CC_V, t0, t1); +tcg_temp_free(t1); + +/* if shift count >= bits, V is (reg != 0) */ +tcg_gen_setcond_i32(TCG_COND_NE, t0, reg, zero); +tcg_gen_movcond_i32(TCG_COND_GE, QREG_CC_V, s32, t2, t0, QREG_CC_V); + +tcg_temp_free(t0); + +tcg_gen_neg_i32(QREG_CC_V, QREG_CC_V); + +/* if shift count is zero, V is 0 */ +tcg_gen_movcond_i32(TCG_COND_NE, QREG_CC_V, s32, zero, +QREG_CC_V, zero); This computation is not quite right, in that you compute bits - count and don't bound that against 0..31 for the sar_i32. I think we can also to better for the two things you're special-casing: count >= bits and count == 0. I need to think about that some more. r~
Re: [Qemu-devel] [PATCH v3] block: Turn on "unmap" in active commit
On Tue, Sep 27, 2016 at 07:14:52PM +0800, Fam Zheng wrote: > We already specified BDRV_O_UNMAP when opening images in 'qemu-img > commit', but didn't turn on the "unmap" in the active commit job. This > patch fixes that so that zeroed clusters in top image can be discarded > which is desired in the virt-sparsify use case, where a temporary > overlay is created and fstrim'ed before commiting back, to free space in > the original image. > > This also enables it for block-commit. > > Signed-off-by: Fam Zheng > --- > v3: Change the right parameter. > v2: Add "unmap" to block-commit as well. [Kevin] > --- > block/mirror.c | 2 +- > 1 file changed, 1 insertion(+), 1 deletion(-) > > diff --git a/block/mirror.c b/block/mirror.c > index f9d1fec..8847ec5 100644 > --- a/block/mirror.c > +++ b/block/mirror.c > @@ -1042,7 +1042,7 @@ void commit_active_start(const char *job_id, > BlockDriverState *bs, > > mirror_start_job(job_id, bs, base, NULL, speed, 0, 0, > MIRROR_LEAVE_BACKING_CHAIN, > - on_error, on_error, false, cb, opaque, &local_err, > + on_error, on_error, true, cb, opaque, &local_err, > &commit_active_job_driver, false, base, auto_complete); > if (local_err) { > error_propagate(errp, local_err); > -- > 2.7.4 > Thanks, Applied to my block branch: git://github.com/codyprime/qemu-kvm-jtc.git block -Jeff
Re: [Qemu-devel] [PATCH v2 1/1] block/gluster: memory usage: use one glfs instance per volume
On Thu, Oct 27, 2016 at 08:54:50PM +0530, Prasanna Kumar Kalever wrote: > Currently, for every drive accessed via gfapi we create a new glfs > instance (call glfs_new() followed by glfs_init()) which could consume > memory in few 100 MB's, from the table below it looks like for each > instance ~300 MB VSZ was consumed > > Before: > --- > Disks VSZ RSS > 1 1098728 187756 > 2 1430808 198656 > 3 1764932 199704 > 4 2084728 202684 > > This patch maintains a list of pre-opened glfs objects. On adding > a new drive belonging to the same gluster volume, we just reuse the > existing glfs object by updating its refcount. > > With this approch we shrink up the unwanted memory consumption and > glfs_new/glfs_init calls for accessing a disk (file) if belongs to > same volume. > > From below table notice that the memory usage after adding a disk > (which will reuse the existing glfs object hence) is in negligible > compared to before. > > After: > -- > Disks VSZ RSS > 1 1101964 185768 > 2 1109604 194920 > 3 1114012 196036 > 4 1114496 199868 > > Disks: number of -drive > VSZ: virtual memory size of the process in KiB > RSS: resident set size, the non-swapped physical memory (in kiloBytes) > > VSZ and RSS are analyzed using 'ps aux' utility. > > Signed-off-by: Prasanna Kumar Kalever > --- > v2: Address comments from Jeff Cody on v1 > v1: Initial patch > --- > block/gluster.c | 94 > - > 1 file changed, 80 insertions(+), 14 deletions(-) > > diff --git a/block/gluster.c b/block/gluster.c > index 01b479f..7e39201 100644 > --- a/block/gluster.c > +++ b/block/gluster.c > @@ -54,6 +54,19 @@ typedef struct BDRVGlusterReopenState { > } BDRVGlusterReopenState; > > > +typedef struct GlfsPreopened { > +char *volume; > +glfs_t *fs; > +int ref; > +} GlfsPreopened; > + > +typedef struct ListElement { > +QLIST_ENTRY(ListElement) list; > +GlfsPreopened saved; > +} ListElement; > + > +static QLIST_HEAD(glfs_list, ListElement) glfs_list; > + > static QemuOptsList qemu_gluster_create_opts = { > .name = "qemu-gluster-create-opts", > .head = QTAILQ_HEAD_INITIALIZER(qemu_gluster_create_opts.head), > @@ -182,6 +195,57 @@ static QemuOptsList runtime_tcp_opts = { > }, > }; > > +static void glfs_set_preopened(const char *volume, glfs_t *fs) > +{ > +ListElement *entry = NULL; > + > +entry = g_new(ListElement, 1); > + > +entry->saved.volume = g_strdup(volume); > + > +entry->saved.fs = fs; > +entry->saved.ref = 1; > + > +QLIST_INSERT_HEAD(&glfs_list, entry, list); > +} > + > +static glfs_t *glfs_find_preopened(const char *volume) > +{ > +ListElement *entry = NULL; > + > + QLIST_FOREACH(entry, &glfs_list, list) { > +if (strcmp(entry->saved.volume, volume) == 0) { > +entry->saved.ref++; > +return entry->saved.fs; > +} > + } > + > +return NULL; > +} > + > +static void glfs_clear_preopened(glfs_t *fs) > +{ > +ListElement *entry = NULL; > + > +if (fs == NULL) { > +return; > +} > + > +QLIST_FOREACH(entry, &glfs_list, list) { > +if (entry->saved.fs == fs) { > +if (--entry->saved.ref) { > +return; > +} > + > +QLIST_REMOVE(entry, list); > + > +glfs_fini(entry->saved.fs); > +g_free(entry->saved.volume); > +g_free(entry); > +} > +} > +} > + > static int parse_volume_options(BlockdevOptionsGluster *gconf, char *path) > { > char *p, *q; > @@ -319,11 +383,18 @@ static struct glfs > *qemu_gluster_glfs_init(BlockdevOptionsGluster *gconf, > int old_errno; > GlusterServerList *server; > > +glfs = glfs_find_preopened(gconf->volume); > +if (glfs) { > +return glfs; > +} > + > glfs = glfs_new(gconf->volume); > if (!glfs) { > goto out; > } > > +glfs_set_preopened(gconf->volume, glfs); > + > for (server = gconf->server; server; server = server->next) { > if (server->value->type == GLUSTER_TRANSPORT_UNIX) { > ret = glfs_set_volfile_server(glfs, > @@ -375,7 +446,7 @@ static struct glfs > *qemu_gluster_glfs_init(BlockdevOptionsGluster *gconf, > out: > if (glfs) { > old_errno = errno; > -glfs_fini(glfs); > +glfs_clear_preopened(glfs); > errno = old_errno; > } > return NULL; > @@ -741,9 +812,9 @@ out: > if (s->fd) { > glfs_close(s->fd); > } > -if (s->glfs) { > -glfs_fini(s->glfs); > -} > + > +glfs_clear_preopened(s->glfs); > + > return ret; > } > > @@ -808,9 +879,8 @@ static void qemu_gluster_reopen_commit(BDRVReopenState > *state) > if (s->fd) { > glfs_close(s->fd); > } > -if (s->glfs) { > -glfs_fini(s->glfs); > -} > + > +glfs_clear_preopened(s->glfs); > >
[Qemu-devel] [PATCH v2 1/4] target-ppc: Implement bcdcfn. instruction
bcdcfn. converts from National numeric format to BCD. National format uses a byte to represent a digit where the most significant nibble is always 0x3 and the least sign. nibbles is the digit itself. Signed-off-by: Jose Ricardo Ziviani --- target-ppc/helper.h | 1 + target-ppc/int_helper.c | 54 ++ target-ppc/translate/vmx-impl.inc.c | 75 + target-ppc/translate/vmx-ops.inc.c | 4 +- 4 files changed, 132 insertions(+), 2 deletions(-) diff --git a/target-ppc/helper.h b/target-ppc/helper.h index 3916b2e..3b23eed 100644 --- a/target-ppc/helper.h +++ b/target-ppc/helper.h @@ -371,6 +371,7 @@ DEF_HELPER_4(vpermxor, void, avr, avr, avr, avr) DEF_HELPER_4(bcdadd, i32, avr, avr, avr, i32) DEF_HELPER_4(bcdsub, i32, avr, avr, avr, i32) +DEF_HELPER_3(bcdcfn, i32, avr, avr, i32) DEF_HELPER_2(xsadddp, void, env, i32) DEF_HELPER_2(xssubdp, void, env, i32) diff --git a/target-ppc/int_helper.c b/target-ppc/int_helper.c index dca4798..9d620a6 100644 --- a/target-ppc/int_helper.c +++ b/target-ppc/int_helper.c @@ -2429,6 +2429,8 @@ void helper_vsubecuq(ppc_avr_t *r, ppc_avr_t *a, ppc_avr_t *b, ppc_avr_t *c) #define BCD_NEG_PREF0xD #define BCD_NEG_ALT 0xB #define BCD_PLUS_ALT_2 0xE +#define NATIONAL_PLUS 0x2B +#define NATIONAL_NEG0x2D #if defined(HOST_WORDS_BIGENDIAN) #define BCD_DIG_BYTE(n) (15 - (n/2)) @@ -2495,6 +2497,15 @@ static void bcd_put_digit(ppc_avr_t *bcd, uint8_t digit, int n) } } +static uint8_t get_national_digit(ppc_avr_t *reg, int n) +{ +#if defined(HOST_WORDS_BIGENDIAN) +return reg->u16[8 - n]; +#else +return reg->u16[n]; +#endif +} + static int bcd_cmp_mag(ppc_avr_t *a, ppc_avr_t *b) { int i; @@ -2625,6 +2636,49 @@ uint32_t helper_bcdsub(ppc_avr_t *r, ppc_avr_t *a, ppc_avr_t *b, uint32_t ps) return helper_bcdadd(r, a, &bcopy, ps); } +uint32_t helper_bcdcfn(ppc_avr_t *r, ppc_avr_t *b, uint32_t ps) +{ +int i; +int neq_flag = 0; +int cr = 0; +int national = 0; +ppc_avr_t ret = { .u64 = { 0, 0 } }; +uint16_t sgnb = get_national_digit(b, 0); +int invalid = (sgnb != NATIONAL_PLUS && sgnb != NATIONAL_NEG); + +for (i = 1; i < 8; i++) { +national = get_national_digit(b, i); + +neq_flag += (national != 0x30); +if (unlikely(national < 0x30 || national > 0x39)) { +invalid = 1; +break; +} + +bcd_put_digit(&ret, national & 0xf, i); +} + +if (sgnb == NATIONAL_PLUS) { +bcd_put_digit(&ret, (ps == 0) ? BCD_PLUS_PREF_1 : BCD_PLUS_PREF_2, 0); +} else { +bcd_put_digit(&ret, BCD_NEG_PREF, 0); +} + +if (neq_flag) { +cr = (sgnb == NATIONAL_PLUS) ? 1 << CRF_GT : 1 << CRF_LT; +} else { +cr = 1 << CRF_EQ; +} + +if (unlikely(invalid)) { +cr = 1 << CRF_SO; +} + +*r = ret; + +return cr; +} + void helper_vsbox(ppc_avr_t *r, ppc_avr_t *a) { int i; diff --git a/target-ppc/translate/vmx-impl.inc.c b/target-ppc/translate/vmx-impl.inc.c index fc612d9..06d28f2 100644 --- a/target-ppc/translate/vmx-impl.inc.c +++ b/target-ppc/translate/vmx-impl.inc.c @@ -945,8 +945,81 @@ static void gen_##op(DisasContext *ctx) \ tcg_temp_free_i32(ps); \ } +#define GEN_BCD2(op)\ +static void gen_##op(DisasContext *ctx) \ +{ \ +TCGv_ptr rd, rb;\ +TCGv_i32 ps;\ +\ +if (unlikely(!ctx->altivec_enabled)) { \ +gen_exception(ctx, POWERPC_EXCP_VPU); \ +return; \ +} \ +\ +rb = gen_avr_ptr(rB(ctx->opcode)); \ +rd = gen_avr_ptr(rD(ctx->opcode)); \ +\ +ps = tcg_const_i32((ctx->opcode & 0x200) != 0); \ +\ +gen_helper_##op(cpu_crf[6], rd, rb, ps);\ +\ +tcg_temp_free_ptr(rb); \ +tcg_temp_free_ptr(rd); \ +tcg_temp_free_i32(ps); \ +} + GEN_BCD(bcdadd) GEN_BCD(bcdsub) +GEN_BCD2(bcdcfn) + +static void gen_xpnd04_1(DisasContext *ctx) +{ +switch (opc4(ctx->opcode)) { +case 0: +break; /* bcdctsq. */ +case 2: +break; /* bcdcfsq. */ +case 4: +break; /* bcdctz. */ +case 5: +break; /* bcdctn. */ +case 6: +break; /* bcdcfz. */ +case 7: +gen_bcdcfn(ctx); +break; +case 31: +break; /* bcdsetsgn. */ +default: +break; +}
[Qemu-devel] [PATCH v2 0/4] POWER9 TCG enablements - BCD functions part I
v2: - implements all fixes and suggestions This serie contains 4 new instructions for POWER9 ISA3.0 bcdcfn.: Decimal Convert From National bcdctn.: Decimal Convert To National bcdcfz.: Decimal Convert From Zoned bcdctz.: Decimal Convert to Zoned Jose Ricardo Ziviani (4): target-ppc: Implement bcdcfn. instruction target-ppc: Implement bcdctn. instruction target-ppc: Implement bcdcfz. instruction target-ppc: Implement bcdctz. instruction target-ppc/helper.h | 4 + target-ppc/int_helper.c | 200 target-ppc/translate/vmx-impl.inc.c | 103 +++ target-ppc/translate/vmx-ops.inc.c | 4 +- 4 files changed, 309 insertions(+), 2 deletions(-) -- 2.7.4
[Qemu-devel] [PATCH v2 3/4] target-ppc: Implement bcdcfz. instruction
bcdcfz. converts from Zoned numeric format to BCD. Zoned format uses a byte to represent a digit where the most significant nibble is 0x3 or 0xf, depending on the preferred signal. Signed-off-by: Jose Ricardo Ziviani --- target-ppc/helper.h | 1 + target-ppc/int_helper.c | 47 + target-ppc/translate/vmx-impl.inc.c | 7 -- 3 files changed, 53 insertions(+), 2 deletions(-) diff --git a/target-ppc/helper.h b/target-ppc/helper.h index 53d1e7a..a9ac28b 100644 --- a/target-ppc/helper.h +++ b/target-ppc/helper.h @@ -373,6 +373,7 @@ DEF_HELPER_4(bcdadd, i32, avr, avr, avr, i32) DEF_HELPER_4(bcdsub, i32, avr, avr, avr, i32) DEF_HELPER_3(bcdcfn, i32, avr, avr, i32) DEF_HELPER_2(bcdctn, i32, avr, avr) +DEF_HELPER_3(bcdcfz, i32, avr, avr, i32) DEF_HELPER_2(xsadddp, void, env, i32) DEF_HELPER_2(xssubdp, void, env, i32) diff --git a/target-ppc/int_helper.c b/target-ppc/int_helper.c index a58ed30..19e6a3a 100644 --- a/target-ppc/int_helper.c +++ b/target-ppc/int_helper.c @@ -2727,6 +2727,53 @@ uint32_t helper_bcdctn(ppc_avr_t *r, ppc_avr_t *b) return cr; } +uint32_t helper_bcdcfz(ppc_avr_t *r, ppc_avr_t *b, uint32_t ps) +{ +int i; +int j; +int cr = 0; +int invalid = 0; +int neq_flag = 0; +int zone_digit = 0; +int zone_lead = (ps) ? 0xF : 0x3; +int digit = 0; +ppc_avr_t ret = { .u64 = { 0, 0 } }; +int sgnb = b->u8[BCD_DIG_BYTE(0)] >> 4; + +if (unlikely((sgnb < 0xA) && ps)) { +invalid = 1; +} + +for (i = 0, j = 1; i < 31; i += 2, j++) { +zone_digit = (i) ? b->u8[BCD_DIG_BYTE(i)] >> 4 : zone_lead; +digit = b->u8[BCD_DIG_BYTE(i)] & 0xF; + +if (unlikely(zone_digit != zone_lead || digit > 0x9)) { +invalid = 1; +break; +} + +neq_flag += (digit != 0); +bcd_put_digit(&ret, digit, j); +} + +if ((ps && (sgnb == 0xB || sgnb == 0xD)) || +(!ps && (sgnb & 0x4))) { +bcd_put_digit(&ret, BCD_NEG_PREF, 0); +cr = (neq_flag) ? 1 << CRF_LT : 1 << CRF_EQ; +} else { +bcd_put_digit(&ret, BCD_PLUS_PREF_1, 0); +cr = (neq_flag) ? 1 << CRF_GT : 1 << CRF_EQ; +} + +if (unlikely(invalid)) { +cr = 1 << CRF_SO; +} + +*r = ret; + +return cr; +} void helper_vsbox(ppc_avr_t *r, ppc_avr_t *a) { int i; diff --git a/target-ppc/translate/vmx-impl.inc.c b/target-ppc/translate/vmx-impl.inc.c index e37fc11..6e54437 100644 --- a/target-ppc/translate/vmx-impl.inc.c +++ b/target-ppc/translate/vmx-impl.inc.c @@ -991,6 +991,7 @@ GEN_BCD(bcdadd) GEN_BCD(bcdsub) GEN_BCD2(bcdcfn) GEN_BCD3(bcdctn) +GEN_BCD2(bcdcfz) static void gen_xpnd04_1(DisasContext *ctx) { @@ -1005,7 +1006,8 @@ static void gen_xpnd04_1(DisasContext *ctx) gen_bcdctn(ctx); break; case 6: -break; /* bcdcfz. */ +gen_bcdcfz(ctx); +break; case 7: gen_bcdcfn(ctx); break; @@ -1026,7 +1028,8 @@ static void gen_xpnd04_2(DisasContext *ctx) case 4: break; /* bcdctz. */ case 6: -break; /* bcdcfz. */ +gen_bcdcfz(ctx); +break; case 7: gen_bcdcfn(ctx); break; -- 2.7.4
[Qemu-devel] [PATCH v3 0/2] Qemu: gdbstub: fix vCont
This small patchset fixes the incorrect behaviour of the vCont command in the gdb stub. The first patch, as suggested be Paolo, refactors some code. The most visible change is that it moves vm_start to cpus.c The second one fixes the incorrect behaviour of the vCont command. Previously, continuing or stepping a single thread (CPU) caused all other CPUs to be started too, whereas the GDB specification clearly states that without a default action all threads not explicitly mentioned in the command should stay stopped. So if the Qemu gdbstub receives a vCont;c:1 packet, no other CPU should be restarted except the first, and when a vCont;s:1 is received, the first CPU should be stepped without restarting the others. With this patchset Qemu now behaves as expected. See here for reference material about the packets: https://sourceware.org/gdb/current/onlinedocs/gdb/Packets.html https://sourceware.org/gdb/onlinedocs/gdb/Packets.html v2 -> v3 * removed resume_some_vcpus * cleared up the code and simplified the implementation in light of the clarification in the specification of the vCont packet Claudio Imbrenda (2): move vm_start to cpus.c gdbstub: Fix vCont behaviour cpus.c | 44 ++- gdbstub.c | 189 ++--- hw/i386/kvmvapic.c | 2 + include/sysemu/cpus.h | 1 + include/sysemu/sysemu.h| 2 + target-s390x/misc_helper.c | 2 + vl.c | 32 +--- 7 files changed, 195 insertions(+), 77 deletions(-) -- 1.9.1
[Qemu-devel] [PATCH v2 2/4] target-ppc: Implement bcdctn. instruction
bcdctn. converts from BCD to National numeric format. National format uses a byte to represent a digit where the most significant nibble is always 0x3 and the least sign. nibbles is the digit itself. Signed-off-by: Jose Ricardo Ziviani --- target-ppc/helper.h | 1 + target-ppc/int_helper.c | 48 + target-ppc/translate/vmx-impl.inc.c | 24 ++- 3 files changed, 72 insertions(+), 1 deletion(-) diff --git a/target-ppc/helper.h b/target-ppc/helper.h index 3b23eed..53d1e7a 100644 --- a/target-ppc/helper.h +++ b/target-ppc/helper.h @@ -372,6 +372,7 @@ DEF_HELPER_4(vpermxor, void, avr, avr, avr, avr) DEF_HELPER_4(bcdadd, i32, avr, avr, avr, i32) DEF_HELPER_4(bcdsub, i32, avr, avr, avr, i32) DEF_HELPER_3(bcdcfn, i32, avr, avr, i32) +DEF_HELPER_2(bcdctn, i32, avr, avr) DEF_HELPER_2(xsadddp, void, env, i32) DEF_HELPER_2(xssubdp, void, env, i32) diff --git a/target-ppc/int_helper.c b/target-ppc/int_helper.c index 9d620a6..a58ed30 100644 --- a/target-ppc/int_helper.c +++ b/target-ppc/int_helper.c @@ -2506,6 +2506,15 @@ static uint8_t get_national_digit(ppc_avr_t *reg, int n) #endif } +static void set_national_digit(ppc_avr_t *reg, uint8_t val, int n) +{ +#if defined(HOST_WORDS_BIGENDIAN) +reg->u16[8 - n] = val; +#else +reg->u16[n] = val; +#endif +} + static int bcd_cmp_mag(ppc_avr_t *a, ppc_avr_t *b) { int i; @@ -2679,6 +2688,45 @@ uint32_t helper_bcdcfn(ppc_avr_t *r, ppc_avr_t *b, uint32_t ps) return cr; } +uint32_t helper_bcdctn(ppc_avr_t *r, ppc_avr_t *b) +{ +int i; +int cr = 0; +int sgnb = bcd_get_sgn(b); +int invalid = (sgnb == 0); +ppc_avr_t ret = { .u64 = { 0, 0 } }; + +int eq_flag = (b->u64[HI_IDX] == 0) && ((b->u64[LO_IDX] >> 4) == 0); +int ox_flag = (b->u64[HI_IDX] != 0) || ((b->u64[LO_IDX] >> 32) != 0); + +for (i = 1; i < 8; i++) { +set_national_digit(&ret, 0x30 + bcd_get_digit(b, i, &invalid), i); + +if (unlikely(invalid)) { +break; +} +} +set_national_digit(&ret, (sgnb == -1) ? NATIONAL_NEG : NATIONAL_PLUS, 0); + +if (!eq_flag) { +cr = (sgnb == -1) ? 1 << CRF_LT : 1 << CRF_GT; +} else { +cr = 1 << CRF_EQ; +} + +if (ox_flag) { +cr |= 1 << CRF_SO; +} + +if (unlikely(invalid)) { +cr = 1 << CRF_SO; +} + +*r = ret; + +return cr; +} + void helper_vsbox(ppc_avr_t *r, ppc_avr_t *a) { int i; diff --git a/target-ppc/translate/vmx-impl.inc.c b/target-ppc/translate/vmx-impl.inc.c index 06d28f2..e37fc11 100644 --- a/target-ppc/translate/vmx-impl.inc.c +++ b/target-ppc/translate/vmx-impl.inc.c @@ -968,9 +968,29 @@ static void gen_##op(DisasContext *ctx) \ tcg_temp_free_i32(ps); \ } +#define GEN_BCD3(op)\ +static void gen_##op(DisasContext *ctx) \ +{ \ +TCGv_ptr rb, rd;\ +\ +if (unlikely(!ctx->altivec_enabled)) { \ +gen_exception(ctx, POWERPC_EXCP_VPU); \ +return; \ +} \ +\ +rb = gen_avr_ptr(rB(ctx->opcode)); \ +rd = gen_avr_ptr(rD(ctx->opcode)); \ +\ +gen_helper_##op(cpu_crf[6], rd, rb);\ +\ +tcg_temp_free_ptr(rb); \ +tcg_temp_free_ptr(rd); \ +} + GEN_BCD(bcdadd) GEN_BCD(bcdsub) GEN_BCD2(bcdcfn) +GEN_BCD3(bcdctn) static void gen_xpnd04_1(DisasContext *ctx) { @@ -982,7 +1002,8 @@ static void gen_xpnd04_1(DisasContext *ctx) case 4: break; /* bcdctz. */ case 5: -break; /* bcdctn. */ +gen_bcdctn(ctx); +break; case 6: break; /* bcdcfz. */ case 7: @@ -1098,3 +1119,4 @@ GEN_VXFORM_DUAL(vsldoi, PPC_ALTIVEC, PPC_NONE, #undef GEN_VAFORM_PAIRED #undef GEN_BCD2 +#undef GEN_BCD3 -- 2.7.4
[Qemu-devel] [PATCH v2 4/4] target-ppc: Implement bcdctz. instruction
bcdctz. converts from BCD to Zoned numeric format. Zoned format uses a byte to represent a digit where the most significant nibble is 0x3 or 0xf, depending on the preferred signal. Signed-off-by: Jose Ricardo Ziviani --- target-ppc/helper.h | 1 + target-ppc/int_helper.c | 51 + target-ppc/translate/vmx-impl.inc.c | 7 +++-- 3 files changed, 57 insertions(+), 2 deletions(-) diff --git a/target-ppc/helper.h b/target-ppc/helper.h index a9ac28b..489a405 100644 --- a/target-ppc/helper.h +++ b/target-ppc/helper.h @@ -374,6 +374,7 @@ DEF_HELPER_4(bcdsub, i32, avr, avr, avr, i32) DEF_HELPER_3(bcdcfn, i32, avr, avr, i32) DEF_HELPER_2(bcdctn, i32, avr, avr) DEF_HELPER_3(bcdcfz, i32, avr, avr, i32) +DEF_HELPER_3(bcdctz, i32, avr, avr, i32) DEF_HELPER_2(xsadddp, void, env, i32) DEF_HELPER_2(xssubdp, void, env, i32) diff --git a/target-ppc/int_helper.c b/target-ppc/int_helper.c index 19e6a3a..518824e 100644 --- a/target-ppc/int_helper.c +++ b/target-ppc/int_helper.c @@ -2774,6 +2774,57 @@ uint32_t helper_bcdcfz(ppc_avr_t *r, ppc_avr_t *b, uint32_t ps) return cr; } + +uint32_t helper_bcdctz(ppc_avr_t *r, ppc_avr_t *b, uint32_t ps) +{ +int i; +int j; +int cr = 0; +uint8_t digit = 0; +int sgnb = bcd_get_sgn(b); +int zone_lead = (ps) ? 0xF0 : 0x30; +int invalid = (sgnb == 0); +ppc_avr_t ret = { .u64 = { 0, 0 } }; + +int eq_flag = (b->u64[HI_IDX] == 0) && ((b->u64[LO_IDX] >> 4) == 0); +int ox_flag = ((b->u64[HI_IDX] >> 4) != 0); + +for (i = 0, j = 1; i < 32; i += 2, j++) { +digit = bcd_get_digit(b, j, &invalid); + +if (unlikely(invalid)) { +break; +} + +ret.u8[BCD_DIG_BYTE(i)] = zone_lead + digit; +} + +if (ps) { +bcd_put_digit(&ret, (sgnb == 1) ? 0xC : 0xD, 1); +} else { +bcd_put_digit(&ret, (sgnb == 1) ? 0x3 : 0x7, 1); +} +bcd_put_digit(&ret, b->u8[BCD_DIG_BYTE(0)] >> 4, 0); + +if (!eq_flag) { +cr = (sgnb == 1) ? 1 << CRF_GT : 1 << CRF_LT; +} else { +cr = 1 << CRF_EQ; +} + +if (ox_flag) { +cr |= 1 << CRF_SO; +} + +if (unlikely(invalid)) { +cr = 1 << CRF_SO; +} + +*r = ret; + +return cr; +} + void helper_vsbox(ppc_avr_t *r, ppc_avr_t *a) { int i; diff --git a/target-ppc/translate/vmx-impl.inc.c b/target-ppc/translate/vmx-impl.inc.c index 6e54437..a868740 100644 --- a/target-ppc/translate/vmx-impl.inc.c +++ b/target-ppc/translate/vmx-impl.inc.c @@ -992,6 +992,7 @@ GEN_BCD(bcdsub) GEN_BCD2(bcdcfn) GEN_BCD3(bcdctn) GEN_BCD2(bcdcfz) +GEN_BCD2(bcdctz) static void gen_xpnd04_1(DisasContext *ctx) { @@ -1001,7 +1002,8 @@ static void gen_xpnd04_1(DisasContext *ctx) case 2: break; /* bcdcfsq. */ case 4: -break; /* bcdctz. */ +gen_bcdctz(ctx); +break; case 5: gen_bcdctn(ctx); break; @@ -1026,7 +1028,8 @@ static void gen_xpnd04_2(DisasContext *ctx) case 2: break; /* bcdcfsq. */ case 4: -break; /* bcdctz. */ +gen_bcdctz(ctx); +break; case 6: gen_bcdcfz(ctx); break; -- 2.7.4
[Qemu-devel] [PATCH v3 1/2] move vm_start to cpus.c
This patch: * moves vm_start to cpus.c . * exports qemu_vmstop_requested, since it's needed by vm_start . * extracts vm_prepare_start from vm_start; it does what vm_start did, except restarting the cpus. vm_start now calls vm_prepare_start. * moves the call to qemu_clock_enable away from resume_all_vcpus, and add an explicit call to it before each instance of resume_all_vcpus in the code. Signed-off-by: Claudio Imbrenda --- cpus.c | 44 +++- hw/i386/kvmvapic.c | 2 ++ include/sysemu/cpus.h | 1 + include/sysemu/sysemu.h| 2 ++ target-s390x/misc_helper.c | 2 ++ vl.c | 32 +++- 6 files changed, 53 insertions(+), 30 deletions(-) diff --git a/cpus.c b/cpus.c index cfd5cdc..34667fa 100644 --- a/cpus.c +++ b/cpus.c @@ -1260,7 +1260,6 @@ void resume_all_vcpus(void) { CPUState *cpu; -qemu_clock_enable(QEMU_CLOCK_VIRTUAL, true); CPU_FOREACH(cpu) { cpu_resume(cpu); } @@ -1396,6 +1395,49 @@ int vm_stop(RunState state) return do_vm_stop(state); } +/** + * Prepare for (re)starting the VM. + * Returns -1 if the vCPUs are not to be restarted (e.g. if they are already + * running or in case of an error condition), 0 otherwise. + */ +int vm_prepare_start(void) +{ +RunState requested; +int res = 0; + +qemu_vmstop_requested(&requested); +if (runstate_is_running() && requested == RUN_STATE__MAX) { +return -1; +} + +/* Ensure that a STOP/RESUME pair of events is emitted if a + * vmstop request was pending. The BLOCK_IO_ERROR event, for + * example, according to documentation is always followed by + * the STOP event. + */ +if (runstate_is_running()) { +qapi_event_send_stop(&error_abort); +res = -1; +} else { +replay_enable_events(); +cpu_enable_ticks(); +runstate_set(RUN_STATE_RUNNING); +vm_state_notify(1, RUN_STATE_RUNNING); +} + +/* XXX: is it ok to send this even before actually resuming the CPUs? */ +qapi_event_send_resume(&error_abort); +return res; +} + +void vm_start(void) +{ +if (!vm_prepare_start()) { +qemu_clock_enable(QEMU_CLOCK_VIRTUAL, true); +resume_all_vcpus(); +} +} + /* does a state transition even if the VM is already stopped, current state is forgotten forever */ int vm_stop_force_state(RunState state) diff --git a/hw/i386/kvmvapic.c b/hw/i386/kvmvapic.c index 74a549b..3101860 100644 --- a/hw/i386/kvmvapic.c +++ b/hw/i386/kvmvapic.c @@ -446,6 +446,7 @@ static void patch_instruction(VAPICROMState *s, X86CPU *cpu, target_ulong ip) abort(); } +qemu_clock_enable(QEMU_CLOCK_VIRTUAL, true); resume_all_vcpus(); if (!kvm_enabled()) { @@ -686,6 +687,7 @@ static void vapic_write(void *opaque, hwaddr addr, uint64_t data, pause_all_vcpus(); patch_byte(cpu, env->eip - 2, 0x66); patch_byte(cpu, env->eip - 1, 0x90); +qemu_clock_enable(QEMU_CLOCK_VIRTUAL, true); resume_all_vcpus(); } diff --git a/include/sysemu/cpus.h b/include/sysemu/cpus.h index 3728a1e..5fa074b 100644 --- a/include/sysemu/cpus.h +++ b/include/sysemu/cpus.h @@ -5,6 +5,7 @@ bool qemu_in_vcpu_thread(void); void qemu_init_cpu_loop(void); void resume_all_vcpus(void); +void resume_some_vcpus(CPUState **cpus); void pause_all_vcpus(void); void cpu_stop_current(void); void cpu_ticks_init(void); diff --git a/include/sysemu/sysemu.h b/include/sysemu/sysemu.h index 66c6f15..ebe8b76 100644 --- a/include/sysemu/sysemu.h +++ b/include/sysemu/sysemu.h @@ -37,6 +37,7 @@ void vm_state_notify(int running, RunState state); #define VMRESET_REPORT true void vm_start(void); +int vm_prepare_start(void); int vm_stop(RunState state); int vm_stop_force_state(RunState state); @@ -60,6 +61,7 @@ void qemu_register_powerdown_notifier(Notifier *notifier); void qemu_system_debug_request(void); void qemu_system_vmstop_request(RunState reason); void qemu_system_vmstop_request_prepare(void); +bool qemu_vmstop_requested(RunState *r); int qemu_shutdown_requested_get(void); int qemu_reset_requested_get(void); void qemu_system_killed(int signal, pid_t pid); diff --git a/target-s390x/misc_helper.c b/target-s390x/misc_helper.c index 4df2ec6..2b74710 100644 --- a/target-s390x/misc_helper.c +++ b/target-s390x/misc_helper.c @@ -133,6 +133,7 @@ static int modified_clear_reset(S390CPU *cpu) s390_crypto_reset(); scc->load_normal(CPU(cpu)); cpu_synchronize_all_post_reset(); +qemu_clock_enable(QEMU_CLOCK_VIRTUAL, true); resume_all_vcpus(); return 0; } @@ -152,6 +153,7 @@ static int load_normal_reset(S390CPU *cpu) scc->initial_cpu_reset(CPU(cpu)); scc->load_normal(CPU(cpu)); cpu_synchronize_all_post_reset(); +qemu_clock_enable(QEMU_CLOCK_VIRTUAL, true); resume_all_vcpus(); return 0; } diff -
[Qemu-devel] [PATCH v3 2/2] gdbstub: Fix vCont behaviour
When GDB issues a "vCont", QEMU was not handling it correctly when multiple VCPUs are active. For vCont, for each thread (VCPU), it can be specified whether to single step, continue or stop that thread. The default is to stop a thread. However, when (for example) "vCont;s:2" is issued, all VCPUs continue to run, although all but VCPU nr 2 are to be stopped. This patch completely rewrites the vCont parsing code. Please note that this improvement only works in system emulation mode, when in userspace emulation mode the old behaviour is preserved. Signed-off-by: Claudio Imbrenda --- gdbstub.c | 189 ++ 1 file changed, 142 insertions(+), 47 deletions(-) diff --git a/gdbstub.c b/gdbstub.c index b2e1b79..9bb548f 100644 --- a/gdbstub.c +++ b/gdbstub.c @@ -386,6 +386,45 @@ static inline void gdb_continue(GDBState *s) #endif } +/* + * Resume execution, per CPU actions. For user-more emulation it's + * equivalent to gdb_continue . + */ +static int gdb_continue_partial(GDBState *s, char *newstates) +{ +int res = 0; +#ifdef CONFIG_USER_ONLY +s->running_state = 1; +#else +CPUState *cpu; + +if (!runstate_needs_reset()) { +if (vm_prepare_start()) { +return 0; +} + +CPU_FOREACH(cpu) { +switch (newstates[cpu_index(cpu) - 1]) { +case 0: +case 1: +break; /* nothing to do here */ +case 's': +cpu_single_step(cpu, sstep_flags); +cpu_resume(cpu); +break; +case 'c': +cpu_resume(cpu); +break; +default: +res = -1; +break; +} +} +} +#endif +return res; +} + static void put_buffer(GDBState *s, const uint8_t *buf, int len) { #ifdef CONFIG_USER_ONLY @@ -784,6 +823,102 @@ static int is_query_packet(const char *p, const char *query, char separator) (p[query_len] == '\0' || p[query_len] == separator); } +/** + * gdb_handle_vcont - Parses and handles a vCont packet. + * returns -1 if a command is unsupported, -22 if there is a format error, + * 0 on success. + */ +static int gdb_handle_vcont(GDBState *s, const char *p) +{ +int res, idx, signal = 0; +char cur_action; +char *newstates; +unsigned long tmp; +CPUState *cpu; + +/* uninitialised CPUs stay 0 */ +newstates = g_new0(char, max_cpus); + +/* mark valid CPUs with 1 */ +CPU_FOREACH(cpu) { +newstates[cpu_index(cpu) - 1] = 1; +} + +/* + * res keeps track of what error we are returning, with -1 meaning + * that the command is unknown or unsupported, and thus returning + * an empty packet, while -22 returns an E22 packet due to + * invalid or incorrect parameters passed. + */ +res = 0; +while (*p) { +if (*p != ';') { +res = -1; +break; +} +p++; /* skip the ; */ + +/* unknown/invalid/unsupported command */ +if (*p != 'C' && *p != 'S' && *p != 'c' && *p != 's') { +res = -1; +break; +} +cur_action = tolower(*p); +if (*p == 'C' || *p == 'S') { +if (qemu_strtoul(p + 1, &p, 16, &tmp)) { +res = -22; +break; +} +signal = gdb_signal_to_target(tmp); +} else { +p++; +} +/* thread specification. special values: (none), -1 = all; 0 = any */ +if ((p[0] == ':' && p[1] == '-' && p[2] == '1') || (p[0] != ':')) { +for (idx = 0; idx < max_cpus; idx++) { +if (newstates[idx] == 1) { +newstates[idx] = cur_action; +} +} +if (*p == ':') { +p += 3; +} +} else if (*p == ':') { +p++; +if (qemu_strtoul(p, &p, 16, &tmp)) { +res = -22; +break; +} +idx = tmp; +/* 0 means any thread, so we pick the first valid CPU */ +if (!idx) { +CPU_FOREACH(cpu) { +idx = cpu_index(cpu); +break; +} +} + +/* invalid CPU specified */ +if (!idx || idx > max_cpus || !newstates[idx - 1]) { +res = -22; +break; +} +/* only use if no previous match occourred */ +if (newstates[idx - 1] == 1) { +newstates[idx - 1] = cur_action; +} +} +} +if (!res) { +s->signal = signal; +gdb_continue_partial(s, newstates); +} + +g_free(newstates); + +return res; +} + static int gdb_handle_packet(GDBState *s, const char *line_buf) { CPUState *cpu; @@ -829,60 +964,20 @@ static int gdb_handle_packet(GDBState *s, const char *line
[Qemu-devel] [PATCH v5 2/2] qapi: allow blockdev-add for NFS
Introduce new object 'BlockdevOptionsNFS' in qapi/block-core.json to support blockdev-add for NFS network protocol driver. Also make a new struct NFSServer to support tcp connection. Signed-off-by: Ashijeet Acharya --- qapi/block-core.json | 74 +--- 1 file changed, 71 insertions(+), 3 deletions(-) diff --git a/qapi/block-core.json b/qapi/block-core.json index 3592a9d..c0c9b48 100644 --- a/qapi/block-core.json +++ b/qapi/block-core.json @@ -1714,14 +1714,14 @@ # # @host_device, @host_cdrom: Since 2.1 # @gluster: Since 2.7 -# @nbd, @ssh: Since 2.8 +# @nbd, @ssh, @nfs: Since 2.8 # # Since: 2.0 ## { 'enum': 'BlockdevDriver', 'data': [ 'archipelago', 'blkdebug', 'blkverify', 'bochs', 'cloop', 'dmg', 'file', 'ftp', 'ftps', 'gluster', 'host_cdrom', -'host_device', 'http', 'https', 'luks', 'nbd', 'null-aio', +'host_device', 'http', 'https', 'luks', 'nbd', 'nfs', 'null-aio', 'null-co', 'parallels', 'qcow', 'qcow2', 'qed', 'quorum', 'raw', 'replication', 'ssh', 'tftp', 'vdi', 'vhdx', 'vmdk', 'vpc', 'vvfat' ] } @@ -2240,6 +2240,74 @@ '*top-id': 'str' } } ## +# @NFSTransport +# +# An enumeration of NFS transport types +# +# @inet:TCP transport +# +# Since 2.8 +## +{ 'enum': 'NFSTransport', + 'data': [ 'inet' ] } + +## +# @NFSServer +# +# Captures the address of the socket +# +# @type:transport type used for NFS (only TCP supported) +# +# @host:host address for NFS server +# +# Since 2.8 +## +{ 'struct': 'NFSServer', + 'data': { 'type': 'NFSTransport', +'host': 'str' } } + +## +# @BlockdevOptionsNfs +# +# Driver specific block device option for NFS +# +# @server: host address +# +# @path:path of the image on the host +# +# @user:#optional UID value to use when talking to the +# server (defaults to 65534 on Windows and getuid() +# on unix) +# +# @group: #optional GID value to use when talking to the +# server (defaults to 65534 on Windows and getgid() +# in unix) +# +# @tcp-syn-count: #optional number of SYNs during the session +# establishment (defaults to libnfs default) +# +# @readahead-size: #optional set the readahead size in bytes (defaults +# to libnfs default) +# +# @page-cache-size: #optional set the pagecache size in bytes (defaults +# to libnfs default) +# +# @debug-level: #optional set the NFS debug level (max 2) (defaults +# to libnfs default) +# +# Since 2.8 +## +{ 'struct': 'BlockdevOptionsNfs', + 'data': { 'server': 'NFSServer', +'path': 'str', +'*user': 'int', +'*group': 'int', +'*tcp-syn-count': 'int', +'*readahead-size': 'int', +'*page-cache-size': 'int', +'*debug-level': 'int' } } + +## # @BlockdevOptionsCurl # # Driver specific block device options for the curl backend. @@ -2315,7 +2383,7 @@ # TODO iscsi: Wait for structured options 'luks': 'BlockdevOptionsLUKS', 'nbd':'BlockdevOptionsNbd', -# TODO nfs: Wait for structured options + 'nfs':'BlockdevOptionsNfs', 'null-aio': 'BlockdevOptionsNull', 'null-co':'BlockdevOptionsNull', 'parallels': 'BlockdevOptionsGenericFormat', -- 2.6.2
[Qemu-devel] [PATCH v5 1/2] block/nfs: Introduce runtime_opts in NFS
Make NFS block driver use various fine grained runtime_opts. Set .bdrv_parse_filename() to nfs_parse_filename() and introduce two new functions nfs_parse_filename() and nfs_parse_uri() to help parsing the URI. Add a new option "server" which then accepts a new struct NFSServer. "host" is supported as a legacy option and is mapped to its NFSServer representation. Signed-off-by: Ashijeet Acharya --- block/nfs.c | 430 +++- 1 file changed, 337 insertions(+), 93 deletions(-) diff --git a/block/nfs.c b/block/nfs.c index c3db2ec..5b66602 100644 --- a/block/nfs.c +++ b/block/nfs.c @@ -35,8 +35,15 @@ #include "qemu/uri.h" #include "qemu/cutils.h" #include "sysemu/sysemu.h" +#include "qapi/qmp/qdict.h" +#include "qapi/qmp/qint.h" +#include "qapi/qmp/qstring.h" +#include "qapi-visit.h" +#include "qapi/qobject-input-visitor.h" +#include "qapi/qobject-output-visitor.h" #include + #define QEMU_NFS_MAX_READAHEAD_SIZE 1048576 #define QEMU_NFS_MAX_PAGECACHE_SIZE (8388608 / NFS_BLKSIZE) #define QEMU_NFS_MAX_DEBUG_LEVEL 2 @@ -49,6 +56,9 @@ typedef struct NFSClient { AioContext *aio_context; blkcnt_t st_blocks; bool cache_used; +NFSServer *server; +char *path; +int64_t uid, gid, tcp_syncnt, readahead, pagecache, debug; } NFSClient; typedef struct NFSRPC { @@ -60,6 +70,122 @@ typedef struct NFSRPC { NFSClient *client; } NFSRPC; +static int nfs_parse_uri(const char *filename, QDict *options, Error **errp) +{ +URI *uri = NULL; +QueryParams *qp = NULL; +int ret = -EINVAL, i; + +uri = uri_parse(filename); +if (!uri) { +error_setg(errp, "Invalid URI specified"); +goto out; +} +if (strcmp(uri->scheme, "nfs") != 0) { +error_setg(errp, "URI scheme must be 'nfs'"); +goto out; +} + +if (!uri->server) { +error_setg(errp, "missing hostname in URI"); +goto out; +} + +if (!uri->path) { +error_setg(errp, "missing file path in URI"); +goto out; +} + +qp = query_params_parse(uri->query); +if (!qp) { +error_setg(errp, "could not parse query parameters"); +goto out; +} + +qdict_put(options, "server.host", qstring_from_str(uri->server)); +qdict_put(options, "server.type", qstring_from_str("inet")); +qdict_put(options, "path", qstring_from_str(uri->path)); + +for (i = 0; i < qp->n; i++) { +if (!qp->p[i].value) { +error_setg(errp, "Value for NFS parameter expected: %s", + qp->p[i].name); +goto out; +} +if (parse_uint_full(qp->p[i].value, NULL, 0)) { +error_setg(errp, "Illegal value for NFS parameter: %s", + qp->p[i].name); +goto out; +} +if (!strcmp(qp->p[i].name, "uid")) { +qdict_put(options, "user", + qstring_from_str(qp->p[i].value)); +} else if (!strcmp(qp->p[i].name, "gid")) { +qdict_put(options, "group", + qstring_from_str(qp->p[i].value)); +} else if (!strcmp(qp->p[i].name, "tcp-syncnt")) { +qdict_put(options, "tcp-syn-count", + qstring_from_str(qp->p[i].value)); +} else if (!strcmp(qp->p[i].name, "readahead")) { +qdict_put(options, "readahead-size", + qstring_from_str(qp->p[i].value)); +} else if (!strcmp(qp->p[i].name, "pagecache")) { +qdict_put(options, "page-cache-size", + qstring_from_str(qp->p[i].value)); +} else if (!strcmp(qp->p[i].name, "debug")) { +qdict_put(options, "debug-level", + qstring_from_str(qp->p[i].value)); +} else { +error_setg(errp, "Unknown NFS parameter name: %s", + qp->p[i].name); +goto out; +} +} +ret = 0; +out: +if (qp) { +query_params_free(qp); +} +if (uri) { +uri_free(uri); +} +return ret; +} + +static bool nfs_has_filename_options_conflict(QDict *options, Error **errp) +{ +const QDictEntry *qe; + +for (qe = qdict_first(options); qe; qe = qdict_next(options, qe)) { +if (!strcmp(qe->key, "host") || +!strcmp(qe->key, "path") || +!strcmp(qe->key, "user") || +!strcmp(qe->key, "group") || +!strcmp(qe->key, "tcp-syn-count") || +!strcmp(qe->key, "readahead-size") || +!strcmp(qe->key, "page-cache-size") || +!strcmp(qe->key, "debug-level") || +strstart(qe->key, "server.", NULL)) +{ +error_setg(errp, "Option %s cannot be used with a filename", + qe->key); +return true; +} +} + +return false; +} + +static void nfs_parse_filename(const char *filename, QDict *options, + Error **errp) +{ +
[Qemu-devel] [PATCH v5 0/2] allow blockdev-add for NFS
Previously posted series patches: v4: https://lists.gnu.org/archive/html/qemu-devel/2016-10/msg07449.html v3: https://lists.gnu.org/archive/html/qemu-devel/2016-10/msg06903.html v2: https://lists.gnu.org/archive/html/qemu-devel/2016-10/msg05844.html v1: https://lists.gnu.org/archive/html/qemu-devel/2016-10/msg04487.html This series adds blockdev-add support for NFS block driver. Patch 1 helps to prepare NFS driver to make use of several runtime_opts as they appear in the URI. This will make NFS to do things similar to the way other drivers available in the block layer do. It also adds support to handle new option "server". Patch 2 helps to allow blockdev-add support for the NFS block driver by making the NFS option available. *** This series depends on the following patch: *** "qdict: implement a qdict_crumple method for un-flattening a dict" from Daniel's "QAPI/QOM work for non-scalar object properties" series. Changes in v5: - drop use of legacy options - set bs->exact_filename in bdrv_refresh_filename - change client->inet to client->server - fix qdict_crumple() bug Changes in v4: - add support for option "server" in nfs driver - add bdrv_refresh_filename fix - fix the comments in json Changes in v3: - minor coding style fix - set ret=-EINVAL in nfs_parse_uri() - fix the bug of setting errp twice - make all error paths 'goto fail' - pass 0 as a default value in qemu_opt_get_number() - drop nfs_set_pagecache_ttl() - introduce new enum NFSTransport and set 'type' to use it NFSServer - mention default values of query parameters - change the names of query parameters in JSON Changes in v2: - drop strcmp() condition check for host and path in nfs_parse_uri() - drop "export" completely - initialize client->context bedore setting query parameters - fix the QDict options being passed to nfs_client_open() and make use of url Ashijeet Acharya (2): block/nfs: Introduce runtime_opts in NFS qapi: allow blockdev-add for NFS block/nfs.c | 430 --- qapi/block-core.json | 74 - 2 files changed, 408 insertions(+), 96 deletions(-) -- 2.6.2
Re: [Qemu-devel] [libvirt-users] pci-assign fails with read error on config-space file
On Fri, 28 Oct 2016 11:25:55 -0400 Laine Stump wrote: > On 10/28/2016 07:28 AM, Henning Schild wrote: > > Hey, > > > > i am running an unusual setup where i assign pci devices behind the > > back of libvirt. I have two options to do that: > > 1. a wrapper script for qemu that takes care of suid-root and appends > > arguments for pci-assign > > 2. virsh qemu-monitor-command ... 'device_add pci-assign...' > > With any reasonably modern version of Linux/qemu/libvirt, you should not > be using pci-assign, but should use vfio-pci instead. pci-assign is old, > unmaintained, and deprecated (and any other bad words you can think of). > > Also, have you done anything to lock the guest's memory in host RAM? > This is necessary so that the source/destination of DMA reads/writes is > always present. It is done automatically by libvirt as required *when > libvirt knows that a device is being assigned to the guest*, but if > you're going behind libvirt's back, you need to take care of that > yourself (or alternately, don't go behind libvirt's back, which is the > greatly preferred alternative!) Note that pci-assign doesn't care about user locked memory limits, so that much is not required for this deprecated use case, but I fully agree that going behind libvirt's back is completely unadvised and pci-assign is deprecated and likely broken. Maybe we should even consider removing it in the QEMU2.8 release cycle. Use vfio-pci and use the mechanisms provided in libvirt to attach the device to the VM, if these don't work, file bugs and improve the environment to meet your needs rather than working around it. I can't figure out from the original report what specifically about the environment prevents use of libvirt entries. Thanks, Alex > > > > I know i should probably not be doing this, > > > Yes, that is a serious understatement :-) And I suspect that it isn't > necessary. > > > > it is a workaround to > > introduce fine-grained pci-assignment in an openstack setup, where > > vendor and device id are not enough to pick the right device for a vm. > > libvirt selects the device according to its PCI address, not vendor and > device id. Is that not "fine-grained" enough? (And does OpenStack not > let you select devices based on their PCI address?) > > > > > In both cases qemu will crash with the following output: > > > >> qemu: hardware error: pci read failed, ret = 0 errno = 22 > > followed by the usual machine state dump. With strace i found it to be > > a failing read on the config space file of my device. > > /sys/bus/pci/devices/:xx:xx.x/config > > A few reads out of that file succeeded, as well as accesses on vendor > > etc. > > > > Manually launching a qemu with the pci-assign works without a problem, > > so i "blame" libvirt and the cgroup environment the qemu ends up in. > > So i put a bash into the exact same cgroup setup - next to a running > > qemu, expecting a dd or hexdump on the config-space file to fail. But > > from that bash i can read the file without a problem. > > > > Has anyone seen that problem before? > > No, because nobody else (that I've ever heard) is doing what you are > doing. You're going around behind the back of libvirt (and OpenStack) > to do device assignment with a method that was replaced with something > newer/better/etc about 3 years ago, and in the process are likely > missing a lot of the details that would otherwise be automatically > handled by libvirt. > > > > Right now i do not know what i > > am missing, maybe qemu is hitting some limits configured for the > > cgroups or whatever. I can not use pci-assign from libvirt, but if i > > did would it configure cgroups in a different way or relax some limits? > > > > What would be a good next step to debug that? Right now i am looking at > > kernel event traces, but the machine is pretty big and so is the trace. > > > My recommendation would be this: > > 1) look at OpenStack to see if it allows selecting the device to assign > by PCI address. If so, use that (it will just tell libvirt "assign this > device", and libvirt will automatically use VFIO for the device > assignment if it's available (which it will be)) > > 2) if (1) is a deadend (i.e. OpenStack doesn't allow you to select based > on PCI address), use your "sneaky backdoor method" to do "virsh > attach-device somexmlfile.xml", where somexmlfile.xml has a proper > element to select and assign the host device you want. Again, > libvirt will automatically figure out if VFIO can be used, and will > properly setup everything necessary related to cgroups, locked memory, etc. > > > > > > That assignment used to work and i do not know how it broke, i have > > tried combinations of several kernels, versions of libvirt and qemu. > > (kernel 3.18 and 4.4, libvirt 1.3.2 and 2.0.0, and qemu 2.2.1 and 2.7) > > All combinations show the same problem, even the ones that work on > > other machines. So when it comes to softwar
[Qemu-devel] [PATCH v3 4/4] pc: memhp: enable nvdimm device hotplug
_GPE.E04 is dedicated for nvdimm device hotplug Signed-off-by: Xiao Guangrong --- docs/specs/acpi_mem_hotplug.txt | 3 +++ hw/acpi/memory_hotplug.c | 31 +++ hw/i386/acpi-build.c | 7 +++ hw/i386/pc.c | 12 hw/mem/nvdimm.c | 4 include/hw/acpi/acpi_dev_interface.h | 1 + 6 files changed, 46 insertions(+), 12 deletions(-) diff --git a/docs/specs/acpi_mem_hotplug.txt b/docs/specs/acpi_mem_hotplug.txt index 3df3620..cb26dd2 100644 --- a/docs/specs/acpi_mem_hotplug.txt +++ b/docs/specs/acpi_mem_hotplug.txt @@ -4,6 +4,9 @@ QEMU<->ACPI BIOS memory hotplug interface ACPI BIOS GPE.3 handler is dedicated for notifying OS about memory hot-add and hot-remove events. +ACPI BIOS GPE.4 handler is dedicated for notifying OS about nvdimm device +hot-add and hot-remove events. + Memory hot-plug interface (IO port 0xa00-0xa17, 1-4 byte access): --- 0xa00: diff --git a/hw/acpi/memory_hotplug.c b/hw/acpi/memory_hotplug.c index ec4e64b..70f6451 100644 --- a/hw/acpi/memory_hotplug.c +++ b/hw/acpi/memory_hotplug.c @@ -2,6 +2,7 @@ #include "hw/acpi/memory_hotplug.h" #include "hw/acpi/pc-hotplug.h" #include "hw/mem/pc-dimm.h" +#include "hw/mem/nvdimm.h" #include "hw/boards.h" #include "hw/qdev-core.h" #include "trace.h" @@ -232,11 +233,8 @@ void acpi_memory_plug_cb(HotplugHandler *hotplug_dev, MemHotplugState *mem_st, DeviceState *dev, Error **errp) { MemStatus *mdev; -DeviceClass *dc = DEVICE_GET_CLASS(dev); - -if (!dc->hotpluggable) { -return; -} +AcpiEventStatusBits event; +bool is_nvdimm = object_dynamic_cast(OBJECT(dev), TYPE_NVDIMM); mdev = acpi_memory_slot_status(mem_st, dev, errp); if (!mdev) { @@ -244,10 +242,23 @@ void acpi_memory_plug_cb(HotplugHandler *hotplug_dev, MemHotplugState *mem_st, } mdev->dimm = dev; -mdev->is_enabled = true; + +/* + * do not set is_enabled and is_inserting if the slot is plugged with + * a nvdimm device to stop OSPM inquires memory region from the slot. + */ +if (is_nvdimm) { +event = ACPI_NVDIMM_HOTPLUG_STATUS; +} else { +mdev->is_enabled = true; +event = ACPI_MEMORY_HOTPLUG_STATUS; +} + if (dev->hotplugged) { -mdev->is_inserting = true; -acpi_send_event(DEVICE(hotplug_dev), ACPI_MEMORY_HOTPLUG_STATUS); +if (!is_nvdimm) { +mdev->is_inserting = true; +} +acpi_send_event(DEVICE(hotplug_dev), event); } } @@ -262,6 +273,8 @@ void acpi_memory_unplug_request_cb(HotplugHandler *hotplug_dev, return; } +/* nvdimm device hot unplug is not supported yet. */ +assert(!object_dynamic_cast(OBJECT(dev), TYPE_NVDIMM)); mdev->is_removing = true; acpi_send_event(DEVICE(hotplug_dev), ACPI_MEMORY_HOTPLUG_STATUS); } @@ -276,6 +289,8 @@ void acpi_memory_unplug_cb(MemHotplugState *mem_st, return; } +/* nvdimm device hot unplug is not supported yet. */ +assert(!object_dynamic_cast(OBJECT(dev), TYPE_NVDIMM)); mdev->is_enabled = false; mdev->dimm = NULL; } diff --git a/hw/i386/acpi-build.c b/hw/i386/acpi-build.c index bc49958..32270c3 100644 --- a/hw/i386/acpi-build.c +++ b/hw/i386/acpi-build.c @@ -2039,6 +2039,13 @@ build_dsdt(GArray *table_data, BIOSLinker *linker, method = aml_method("_E03", 0, AML_NOTSERIALIZED); aml_append(method, aml_call0(MEMORY_HOTPLUG_HANDLER_PATH)); aml_append(scope, method); + +if (pcms->acpi_nvdimm_state.is_enabled) { +method = aml_method("_E04", 0, AML_NOTSERIALIZED); +aml_append(method, aml_notify(aml_name("\\_SB.NVDR"), + aml_int(0x80))); +aml_append(scope, method); +} } aml_append(dsdt, scope); diff --git a/hw/i386/pc.c b/hw/i386/pc.c index 3be6304..200963f 100644 --- a/hw/i386/pc.c +++ b/hw/i386/pc.c @@ -1729,6 +1729,12 @@ static void pc_dimm_unplug_request(HotplugHandler *hotplug_dev, goto out; } +if (object_dynamic_cast(OBJECT(dev), TYPE_NVDIMM)) { +error_setg(&local_err, + "nvdimm device hot unplug is not supported yet."); +goto out; +} + hhc = HOTPLUG_HANDLER_GET_CLASS(pcms->acpi_dev); hhc->unplug_request(HOTPLUG_HANDLER(pcms->acpi_dev), dev, &local_err); @@ -1746,6 +1752,12 @@ static void pc_dimm_unplug(HotplugHandler *hotplug_dev, HotplugHandlerClass *hhc; Error *local_err = NULL; +if (object_dynamic_cast(OBJECT(dev), TYPE_NVDIMM)) { +error_setg(&local_err, + "nvdimm device hot unplug is not supported yet."); +goto out; +} + hhc = HOTPLUG_HANDLER_GET_CLASS(pcms->acpi_dev); hhc->unplug(HOTPLUG_HANDLER(pcms->acpi_dev), dev, &local_err); di
[Qemu-devel] [PATCH v3 3/4] nvdimm acpi: introduce _FIT
_FIT is required for hotplug support, guest will inquire the updated device info from it if a hotplug event is received As FIT buffer is not completely mapped into guest address space, so a new function, Read FIT whose UUID is UUID 648B9CF2-CDA1-4312-8AD9-49C4AF32BD62, handle 0x1, function index is 0x1, is reserved by QEMU to read the piece of FIT buffer. The buffer is concatenated before _FIT return Refer to docs/specs/acpi-nvdimm.txt for detailed design Signed-off-by: Xiao Guangrong --- docs/specs/acpi_nvdimm.txt | 58 - hw/acpi/nvdimm.c | 204 - 2 files changed, 257 insertions(+), 5 deletions(-) diff --git a/docs/specs/acpi_nvdimm.txt b/docs/specs/acpi_nvdimm.txt index 0fdd251..4aa5e3d 100644 --- a/docs/specs/acpi_nvdimm.txt +++ b/docs/specs/acpi_nvdimm.txt @@ -127,6 +127,58 @@ _DSM process diagram: | result from the page | | | +--+ +--+ - _FIT implementation - --- - TODO (will fill it when nvdimm hotplug is introduced) +Device Handle Reservation +- +As we mentioned above, byte 0 ~ byte 3 in the DSM memory save NVDIMM device +handle. The handle is completely QEMU internal thing, the values in range +[0, 0x] indicate nvdimm device (O means nvdimm root device named NVDR), +other values are reserved by other purpose. + +Current reserved handle: +0x1 is reserved for QEMU internal DSM function called on the root +device. + +QEMU internal use only _DSM function + +UUID, 648B9CF2-CDA1-4312-8AD9-49C4AF32BD62, is reserved for QEMU internal +DSM function. + +There is the function introduced by QEMU and only used by QEMU internal. + +1) Read FIT + As we only reserved one page for NVDIMM ACPI it is impossible to map the + whole FIT data to guest's address space. This function is used by _FIT + method to read a piece of FIT data from QEMU. + + Input parameters: + Arg0 – UUID {set to 648B9CF2-CDA1-4312-8AD9-49C4AF32BD62} + Arg1 – Revision ID (set to 1) + Arg2 - Function Index, 0x1 + Arg3 - A package containing a buffer whose layout is as follows: + + +--+-+-+---+ + | Filed | Byte Length | Byte Offset | Description | + +--+-+-+---+ + | offset | 4 |0| the offset of FIT buffer | + +--+-+-+---+ + + Output: + +--+-+-+---+ + | Filed | Byte Length | Byte Offset | Description | + +--+-+-+---+ + | | | | return status codes | + | | | | 0x100 indicates fit has been| + | status | 4 |0| updated | + | | | | other follows Chapter 3 in DSM| + | | | | Spec Rev1 | + +--+-+-+---+ + | fit data | Varies |4| FIT data | + | | | | | + +--+-+-+---+ + + The FIT offset is maintained by the caller itself, current offset plugs + the length returned by the function is the next offset we should read. + When all the FIT data has been read out, zero length is returned. + + If it returns 0x100, OSPM should restart to read FIT (read from offset 0 + again). diff --git a/hw/acpi/nvdimm.c b/hw/acpi/nvdimm.c index 5f728a6..fc1a012 100644 --- a/hw/acpi/nvdimm.c +++ b/hw/acpi/nvdimm.c @@ -496,6 +496,22 @@ typedef struct NvdimmFuncSetLabelDataIn NvdimmFuncSetLabelDataIn; QEMU_BUILD_BUG_ON(sizeof(NvdimmFuncSetLabelDataIn) + offsetof(NvdimmDsmIn, arg3) > 4096); +struct NvdimmFuncReadFITIn { +uint32_t offset; /* the offset of FIT buffer. */ +} QEMU_PACKED; +typedef struct NvdimmFuncReadFITIn NvdimmFuncReadFITIn; +QEMU_BUILD_BUG_ON(sizeof(NvdimmFuncReadFITIn) + + offsetof(NvdimmDsmIn, arg3) > 4096); + +struct NvdimmFuncReadFITOut { +/* the size of buffer filled by QEMU. */ +uint32_t len; +uint32_t func_ret_status; /* return status code. */ +uint8_t fit[0]; /* the FIT data. */ +} QEMU_PACKED; +typedef struct NvdimmFuncReadFITOut NvdimmFuncReadFITOut; +QEMU_BUILD_BUG_ON(sizeof(NvdimmFuncReadFITOut) > 4096); + static void nvdimm_dsm_function0(uint32_t supported_func, hwaddr dsm_mem_addr) { @@ -516,6 +532,74 @@ nvdimm_dsm_no_payload(uint32_t func_ret_status, hwaddr
[Qemu-devel] [PATCH v3 2/4] nvdimm acpi: introduce fit buffer
The buffer is used to save the FIT info for all the presented nvdimm devices which is updated after the nvdimm device is plugged or unplugged. In the later patch, it will be used to construct NVDIMM ACPI _FIT method which reflects the presented nvdimm devices after nvdimm hotplug As FIT buffer can not completely mapped into guest address space, OSPM will exit to QEMU multiple times, however, there is the race condition - FIT may be changed during these multiple exits, so that some rules are introduced: 1) the user should hold the @lock to access the buffer and 2) mark @dirty whenever the buffer is updated. @dirty is cleared for the first time OSPM gets fit buffer, if dirty is detected in the later access, OSPM will restart the access As fit should be updated after nvdimm device is successfully realized so that a new hotplug callback, post_hotplug, is introduced Signed-off-by: Xiao Guangrong --- hw/acpi/nvdimm.c| 59 +++-- hw/core/hotplug.c | 11 + hw/core/qdev.c | 20 + hw/i386/acpi-build.c| 2 +- hw/i386/pc.c| 19 include/hw/hotplug.h| 10 + include/hw/mem/nvdimm.h | 26 +- 7 files changed, 124 insertions(+), 23 deletions(-) diff --git a/hw/acpi/nvdimm.c b/hw/acpi/nvdimm.c index b8a2e62..5f728a6 100644 --- a/hw/acpi/nvdimm.c +++ b/hw/acpi/nvdimm.c @@ -348,8 +348,9 @@ static void nvdimm_build_structure_dcr(GArray *structures, DeviceState *dev) (DSM) in DSM Spec Rev1.*/); } -static GArray *nvdimm_build_device_structure(GSList *device_list) +static GArray *nvdimm_build_device_structure(void) { +GSList *device_list = nvdimm_get_plugged_device_list(); GArray *structures = g_array_new(false, true /* clear */, 1); for (; device_list; device_list = device_list->next) { @@ -367,28 +368,58 @@ static GArray *nvdimm_build_device_structure(GSList *device_list) /* build NVDIMM Control Region Structure. */ nvdimm_build_structure_dcr(structures, dev); } +g_slist_free(device_list); return structures; } -static void nvdimm_build_nfit(GSList *device_list, GArray *table_offsets, +static void nvdimm_init_fit_buffer(NvdimmFitBuffer *fit_buf) +{ +qemu_mutex_init(&fit_buf->lock); +fit_buf->fit = g_array_new(false, true /* clear */, 1); +} + +static void nvdimm_build_fit_buffer(NvdimmFitBuffer *fit_buf) +{ +qemu_mutex_lock(&fit_buf->lock); +g_array_free(fit_buf->fit, true); +fit_buf->fit = nvdimm_build_device_structure(); +fit_buf->dirty = true; +qemu_mutex_unlock(&fit_buf->lock); +} + +void nvdimm_acpi_hotplug(AcpiNVDIMMState *state) +{ +nvdimm_build_fit_buffer(&state->fit_buf); +} + +static void nvdimm_build_nfit(AcpiNVDIMMState *state, GArray *table_offsets, GArray *table_data, BIOSLinker *linker) { -GArray *structures = nvdimm_build_device_structure(device_list); +NvdimmFitBuffer *fit_buf = &state->fit_buf; unsigned int header; +qemu_mutex_lock(&fit_buf->lock); + +/* NVDIMM device is not plugged? */ +if (!fit_buf->fit->len) { +goto exit; +} + acpi_add_table(table_offsets, table_data); /* NFIT header. */ header = table_data->len; acpi_data_push(table_data, sizeof(NvdimmNfitHeader)); /* NVDIMM device structures. */ -g_array_append_vals(table_data, structures->data, structures->len); +g_array_append_vals(table_data, fit_buf->fit->data, fit_buf->fit->len); build_header(linker, table_data, (void *)(table_data->data + header), "NFIT", - sizeof(NvdimmNfitHeader) + structures->len, 1, NULL, NULL); -g_array_free(structures, true); + sizeof(NvdimmNfitHeader) + fit_buf->fit->len, 1, NULL, NULL); + +exit: +qemu_mutex_unlock(&fit_buf->lock); } struct NvdimmDsmIn { @@ -771,6 +802,8 @@ void nvdimm_init_acpi_state(AcpiNVDIMMState *state, MemoryRegion *io, acpi_data_push(state->dsm_mem, sizeof(NvdimmDsmIn)); fw_cfg_add_file(fw_cfg, NVDIMM_DSM_MEM_FILE, state->dsm_mem->data, state->dsm_mem->len); + +nvdimm_init_fit_buffer(&state->fit_buf); } #define NVDIMM_COMMON_DSM "NCAL" @@ -1045,25 +1078,17 @@ static void nvdimm_build_ssdt(GArray *table_offsets, GArray *table_data, } void nvdimm_build_acpi(GArray *table_offsets, GArray *table_data, - BIOSLinker *linker, GArray *dsm_dma_arrea, + BIOSLinker *linker, AcpiNVDIMMState *state, uint32_t ram_slots) { -GSList *device_list; - -device_list = nvdimm_get_plugged_device_list(); - -/* NVDIMM device is plugged. */ -if (device_list) { -nvdimm_build_nfit(device_list, table_offsets, table_data, linker); -g_slist_free(device_list); -} +nvdimm_build_nfit(state, table_offsets, table_data, li
Re: [Qemu-devel] [PATCH v2 1/1] block/gluster: memory usage: use one glfs instance per volume
On Fri, Oct 28, 2016 at 12:44:24PM +0200, Niels de Vos wrote: > On Thu, Oct 27, 2016 at 08:54:50PM +0530, Prasanna Kumar Kalever wrote: > > Currently, for every drive accessed via gfapi we create a new glfs > > instance (call glfs_new() followed by glfs_init()) which could consume > > memory in few 100 MB's, from the table below it looks like for each > > instance ~300 MB VSZ was consumed > > > > Before: > > --- > > Disks VSZ RSS > > 1 1098728 187756 > > 2 1430808 198656 > > 3 1764932 199704 > > 4 2084728 202684 > > > > This patch maintains a list of pre-opened glfs objects. On adding > > a new drive belonging to the same gluster volume, we just reuse the > > existing glfs object by updating its refcount. > > > > With this approch we shrink up the unwanted memory consumption and > > glfs_new/glfs_init calls for accessing a disk (file) if belongs to > > same volume. > > > > From below table notice that the memory usage after adding a disk > > (which will reuse the existing glfs object hence) is in negligible > > compared to before. > > > > After: > > -- > > Disks VSZ RSS > > 1 1101964 185768 > > 2 1109604 194920 > > 3 1114012 196036 > > 4 1114496 199868 > > > > Disks: number of -drive > > VSZ: virtual memory size of the process in KiB > > RSS: resident set size, the non-swapped physical memory (in kiloBytes) > > > > VSZ and RSS are analyzed using 'ps aux' utility. > > > > Signed-off-by: Prasanna Kumar Kalever > > --- > > v2: Address comments from Jeff Cody on v1 > > v1: Initial patch > > --- > > block/gluster.c | 94 > > - > > 1 file changed, 80 insertions(+), 14 deletions(-) > > > > diff --git a/block/gluster.c b/block/gluster.c > > index 01b479f..7e39201 100644 > > --- a/block/gluster.c > > +++ b/block/gluster.c > > @@ -54,6 +54,19 @@ typedef struct BDRVGlusterReopenState { > > } BDRVGlusterReopenState; > > > > > > +typedef struct GlfsPreopened { > > +char *volume; > > +glfs_t *fs; > > +int ref; > > +} GlfsPreopened; > > + > > +typedef struct ListElement { > > +QLIST_ENTRY(ListElement) list; > > +GlfsPreopened saved; > > +} ListElement; > > + > > +static QLIST_HEAD(glfs_list, ListElement) glfs_list; > > + > > static QemuOptsList qemu_gluster_create_opts = { > > .name = "qemu-gluster-create-opts", > > .head = QTAILQ_HEAD_INITIALIZER(qemu_gluster_create_opts.head), > > @@ -182,6 +195,57 @@ static QemuOptsList runtime_tcp_opts = { > > }, > > }; > > > > +static void glfs_set_preopened(const char *volume, glfs_t *fs) > > +{ > > +ListElement *entry = NULL; > > + > > +entry = g_new(ListElement, 1); > > + > > +entry->saved.volume = g_strdup(volume); > > + > > +entry->saved.fs = fs; > > +entry->saved.ref = 1; > > + > > +QLIST_INSERT_HEAD(&glfs_list, entry, list); > > +} > > + > > +static glfs_t *glfs_find_preopened(const char *volume) > > +{ > > +ListElement *entry = NULL; > > + > > + QLIST_FOREACH(entry, &glfs_list, list) { > > Indention seems off a space. > > Does QLIST_FOREACH do locking? If not, it looks possible that > glfs_find_preopened() and glfs_clear_preopened() race for accessing > 'entry' and it may get g_free()'d before this dereference. Maybe the > block layer prevents this from happening? > > If others confirm that there is no explicit locking needed here, you can > add my Reviewed-by line. > There should be no issue with locking - it will all be running in the same thread. I'll add your R-b when I pull it in, and adding my own: Reviewed-by: Jeff Cody > > > > +if (strcmp(entry->saved.volume, volume) == 0) { > > +entry->saved.ref++; > > +return entry->saved.fs; > > +} > > + } > > + > > +return NULL; > > +} > > + > > +static void glfs_clear_preopened(glfs_t *fs) > > +{ > > +ListElement *entry = NULL; > > + > > +if (fs == NULL) { > > +return; > > +} > > + > > +QLIST_FOREACH(entry, &glfs_list, list) { > > +if (entry->saved.fs == fs) { > > +if (--entry->saved.ref) { > > +return; > > +} > > + > > +QLIST_REMOVE(entry, list); > > + > > +glfs_fini(entry->saved.fs); > > +g_free(entry->saved.volume); > > +g_free(entry); > > +} > > +} > > +} > > + > > static int parse_volume_options(BlockdevOptionsGluster *gconf, char *path) > > { > > char *p, *q; > > @@ -319,11 +383,18 @@ static struct glfs > > *qemu_gluster_glfs_init(BlockdevOptionsGluster *gconf, > > int old_errno; > > GlusterServerList *server; > > > > +glfs = glfs_find_preopened(gconf->volume); > > +if (glfs) { > > +return glfs; > > +} > > + > > glfs = glfs_new(gconf->volume); > > if (!glfs) { > > goto out; > > } > > > > +glfs_set_preopened(gconf->volume, glfs); > > + > > for (server = gc
[Qemu-devel] [PATCH v3 1/4] nvdimm acpi: prebuild nvdimm devices for available slots
For each NVDIMM present or intended to be supported by platform, platform firmware also exposes an ACPI Namespace Device under the root device So it builds nvdimm devices for all slots to support vNVDIMM hotplug Reviewed-by: Stefan Hajnoczi Signed-off-by: Xiao Guangrong --- hw/acpi/nvdimm.c| 41 - hw/i386/acpi-build.c| 2 +- include/hw/mem/nvdimm.h | 3 ++- 3 files changed, 27 insertions(+), 19 deletions(-) diff --git a/hw/acpi/nvdimm.c b/hw/acpi/nvdimm.c index bb896c9..b8a2e62 100644 --- a/hw/acpi/nvdimm.c +++ b/hw/acpi/nvdimm.c @@ -961,12 +961,11 @@ static void nvdimm_build_device_dsm(Aml *dev, uint32_t handle) aml_append(dev, method); } -static void nvdimm_build_nvdimm_devices(GSList *device_list, Aml *root_dev) +static void nvdimm_build_nvdimm_devices(Aml *root_dev, uint32_t ram_slots) { -for (; device_list; device_list = device_list->next) { -DeviceState *dev = device_list->data; -int slot = object_property_get_int(OBJECT(dev), PC_DIMM_SLOT_PROP, - NULL); +uint32_t slot; + +for (slot = 0; slot < ram_slots; slot++) { uint32_t handle = nvdimm_slot_to_handle(slot); Aml *nvdimm_dev; @@ -987,9 +986,9 @@ static void nvdimm_build_nvdimm_devices(GSList *device_list, Aml *root_dev) } } -static void nvdimm_build_ssdt(GSList *device_list, GArray *table_offsets, - GArray *table_data, BIOSLinker *linker, - GArray *dsm_dma_arrea) +static void nvdimm_build_ssdt(GArray *table_offsets, GArray *table_data, + BIOSLinker *linker, GArray *dsm_dma_arrea, + uint32_t ram_slots) { Aml *ssdt, *sb_scope, *dev; int mem_addr_offset, nvdimm_ssdt; @@ -1021,7 +1020,7 @@ static void nvdimm_build_ssdt(GSList *device_list, GArray *table_offsets, /* 0 is reserved for root device. */ nvdimm_build_device_dsm(dev, 0); -nvdimm_build_nvdimm_devices(device_list, dev); +nvdimm_build_nvdimm_devices(dev, ram_slots); aml_append(sb_scope, dev); aml_append(ssdt, sb_scope); @@ -1046,17 +1045,25 @@ static void nvdimm_build_ssdt(GSList *device_list, GArray *table_offsets, } void nvdimm_build_acpi(GArray *table_offsets, GArray *table_data, - BIOSLinker *linker, GArray *dsm_dma_arrea) + BIOSLinker *linker, GArray *dsm_dma_arrea, + uint32_t ram_slots) { GSList *device_list; -/* no NVDIMM device is plugged. */ device_list = nvdimm_get_plugged_device_list(); -if (!device_list) { -return; + +/* NVDIMM device is plugged. */ +if (device_list) { +nvdimm_build_nfit(device_list, table_offsets, table_data, linker); +g_slist_free(device_list); +} + +/* + * NVDIMM device is allowed to be plugged only if there is available + * slot. + */ +if (ram_slots) { +nvdimm_build_ssdt(table_offsets, table_data, linker, dsm_dma_arrea, + ram_slots); } -nvdimm_build_nfit(device_list, table_offsets, table_data, linker); -nvdimm_build_ssdt(device_list, table_offsets, table_data, linker, - dsm_dma_arrea); -g_slist_free(device_list); } diff --git a/hw/i386/acpi-build.c b/hw/i386/acpi-build.c index e999654..6ae4769 100644 --- a/hw/i386/acpi-build.c +++ b/hw/i386/acpi-build.c @@ -2767,7 +2767,7 @@ void acpi_build(AcpiBuildTables *tables, MachineState *machine) } if (pcms->acpi_nvdimm_state.is_enabled) { nvdimm_build_acpi(table_offsets, tables_blob, tables->linker, - pcms->acpi_nvdimm_state.dsm_mem); + pcms->acpi_nvdimm_state.dsm_mem, machine->ram_slots); } /* Add tables supplied by user (if any) */ diff --git a/include/hw/mem/nvdimm.h b/include/hw/mem/nvdimm.h index 1cfe9e0..63a2b20 100644 --- a/include/hw/mem/nvdimm.h +++ b/include/hw/mem/nvdimm.h @@ -112,5 +112,6 @@ typedef struct AcpiNVDIMMState AcpiNVDIMMState; void nvdimm_init_acpi_state(AcpiNVDIMMState *state, MemoryRegion *io, FWCfgState *fw_cfg, Object *owner); void nvdimm_build_acpi(GArray *table_offsets, GArray *table_data, - BIOSLinker *linker, GArray *dsm_dma_arrea); + BIOSLinker *linker, GArray *dsm_dma_arrea, + uint32_t ram_slots); #endif -- 1.8.3.1
[Qemu-devel] [PATCH v3 0/4] nvdimm: hotplug support
It is based on my previous patchset, "[PATCH 0/8] nvdimm acpi: bug fix and cleanup", these two patchset are against commit dea651a95af6dad099 (intel-iommu: Check IOAPIC's Trigger Mode against the one in IRTE) on pci branch of Michael's git tree and can be found at: https://github.com/xiaogr/qemu.git nvdimm-hotplug-v3 Changelog in v3: 1) use a dedicated interrupt for nvdimm device hotplug 2) stop nvdimm device hot unplug 3) reserve UUID and handle for QEMU internally used QEMU 5) redesign fit buffer to avoid OSPM reading incomplete fit info 6) bug fixes and cleanups Changelog in v2: Fixed signed integer overflow pointed out by Stefan Hajnoczi This patchset enables nvdimm hotplug support, it is used as pc-dimm hotplug, for example, a new nvdimm device can be plugged as follows: object_add memory-backend-file,id=mem3,size=10G,mem-path=/home/eric/nvdimm3 device_add nvdimm,id=nvdimm3,memdev=mem3 and unplug it as follows: device_del nvdimm3 object_del mem3 Xiao Guangrong (4): nvdimm acpi: prebuild nvdimm devices for available slots nvdimm acpi: introduce fit buffer nvdimm acpi: introduce _FIT pc: memhp: enable nvdimm device hotplug docs/specs/acpi_mem_hotplug.txt | 3 + docs/specs/acpi_nvdimm.txt | 58 ++- hw/acpi/memory_hotplug.c | 31 +++- hw/acpi/nvdimm.c | 286 +++ hw/core/hotplug.c| 11 ++ hw/core/qdev.c | 20 ++- hw/i386/acpi-build.c | 9 +- hw/i386/pc.c | 31 hw/mem/nvdimm.c | 4 - include/hw/acpi/acpi_dev_interface.h | 1 + include/hw/hotplug.h | 10 ++ include/hw/mem/nvdimm.h | 27 +++- 12 files changed, 443 insertions(+), 48 deletions(-) -- 1.8.3.1
Re: [Qemu-devel] [PULL 00/18] M68k part2 patches
On 28 October 2016 at 09:48, Laurent Vivier wrote: > The following changes since commit 835f3d24b42fcbeca5c49048994a4e5d0fe905c5: > > Merge remote-tracking branch 'remotes/kraxel/tags/pull-audio-20161027-1' > into staging (2016-10-27 17:24:29 +0100) > > are available in the git repository at: > > g...@github.com:vivier/qemu-m68k.git tags/m68k-part2-pull-request > > for you to fetch changes up to 595a926de9ba10d5839894454525264c8c401f82: > > MAINTAINERS: update M68K entry (2016-10-28 10:38:48 +0200) > > > This is the second part of the changes needed to enable 680x0 > processor emulation. > Applied, thanks. -- PMM
[Qemu-devel] [PATCH 5/6] tests/docker/docker.py: expand images command
Modern docker cli commands can filter by repository but as we want to work on all instances do this by hand in python: /tests/docker/docker.py images --repo qemu Will return a space delimited list for the benefit of our Makefile recipes. Signed-off-by: Alex Bennée --- tests/docker/docker.py | 27 ++- 1 file changed, 22 insertions(+), 5 deletions(-) diff --git a/tests/docker/docker.py b/tests/docker/docker.py index 37d8319..03c0238 100755 --- a/tests/docker/docker.py +++ b/tests/docker/docker.py @@ -105,12 +105,15 @@ class Docker(object): signal.signal(signal.SIGTERM, self._kill_instances) signal.signal(signal.SIGHUP, self._kill_instances) -def _do(self, cmd, quiet=True, infile=None, **kwargs): +def _do(self, cmd, quiet=True, infile=None, output=False, **kwargs): if quiet: kwargs["stdout"] = DEVNULL if infile: kwargs["stdin"] = infile -return subprocess.call(self._command + cmd, **kwargs) +if output: +return subprocess.check_output(self._command + cmd, **kwargs) +else: +return subprocess.call(self._command + cmd, **kwargs) def _do_kill_instances(self, only_known, only_active=True): cmd = ["ps", "-q"] @@ -188,8 +191,8 @@ class Docker(object): self._instances.remove(label) return ret -def command(self, cmd, argv, quiet): -return self._do([cmd] + argv, quiet=quiet) +def command(self, cmd, argv, quiet, output=False): +return self._do([cmd] + argv, quiet=quiet, output=output) class SubCommand(object): """A SubCommand template base class""" @@ -325,8 +328,22 @@ class CleanCommand(SubCommand): class ImagesCommand(SubCommand): """Run "docker images" command""" name = "images" +def args(self, parser): +parser.add_argument("--repo", +help="List images in the given repository") + def run(self, args, argv): -return Docker().command("images", argv, args.quiet) +if args.repo: +images=[] +image_re = re.compile(r"^"+re.escape(args.repo)+r"\s+(\S*)") +output = Docker().command("images", argv, args.quiet, output=True) +for line in output.split("\n"): +search = image_re.search(line) +if search: +images.append(search.group(1)) +print ' '.join(map(str,images)) +else: +return Docker().command("images", argv, args.quiet) def main(): parser = argparse.ArgumentParser(description="A Docker helper", -- 2.10.1
[Qemu-devel] [PULL 22/23] clean-up: removed duplicate #includes
From: Anand J Some files contain multiple #includes of the same header file. Removed most of those unnecessary duplicate entries using scripts/clean-includes. Reviewed-by: Thomas Huth Signed-off-by: Anand J Signed-off-by: Michael Tokarev --- accel.c | 1 - cputlb.c| 1 - gdbstub.c | 1 - hw/i386/acpi-build.c| 1 - hw/microblaze/boot.c| 1 - hw/mips/mips_malta.c| 1 - hw/nvram/fw_cfg.c | 1 - hw/pci-bridge/pci_expander_bridge.c | 1 - hw/ppc/ppc405_boards.c | 1 - hw/ppc/spapr.c | 1 - hw/timer/grlib_gptimer.c| 1 - hw/tpm/tpm_tis.c| 1 - hw/unicore32/puv3.c | 1 - hw/usb/dev-mtp.c| 1 - include/hw/i386/pc.h| 1 - monitor.c | 2 -- qemu-io-cmds.c | 1 - qmp.c | 1 - target-i386/machine.c | 3 --- target-mips/machine.c | 1 - target-ppc/machine.c| 1 - target-ppc/mem_helper.c | 1 - target-sparc/machine.c | 3 --- target-xtensa/translate.c | 1 - tests/crypto-tls-x509-helpers.h | 3 --- tests/vhost-user-test.c | 2 -- util/oslib-posix.c | 1 - vl.c| 1 - 28 files changed, 36 deletions(-) diff --git a/accel.c b/accel.c index 403eb5e..664bb88 100644 --- a/accel.c +++ b/accel.c @@ -33,7 +33,6 @@ #include "sysemu/qtest.h" #include "hw/xen/xen.h" #include "qom/object.h" -#include "hw/boards.h" int tcg_tb_size; static bool tcg_allowed = true; diff --git a/cputlb.c b/cputlb.c index cc4da4d..813279f 100644 --- a/cputlb.c +++ b/cputlb.c @@ -26,7 +26,6 @@ #include "exec/cputlb.h" #include "exec/memory-internal.h" #include "exec/ram_addr.h" -#include "exec/exec-all.h" #include "tcg/tcg.h" #include "qemu/error-report.h" #include "exec/log.h" diff --git a/gdbstub.c b/gdbstub.c index b2e1b79..de62d26 100644 --- a/gdbstub.c +++ b/gdbstub.c @@ -31,7 +31,6 @@ #define MAX_PACKET_LENGTH 4096 -#include "cpu.h" #include "qemu/sockets.h" #include "sysemu/kvm.h" #include "exec/semihost.h" diff --git a/hw/i386/acpi-build.c b/hw/i386/acpi-build.c index 93be96f..5cd1da9 100644 --- a/hw/i386/acpi-build.c +++ b/hw/i386/acpi-build.c @@ -53,7 +53,6 @@ #include "hw/pci/pci_bus.h" #include "hw/pci-host/q35.h" #include "hw/i386/x86-iommu.h" -#include "hw/timer/hpet.h" #include "hw/acpi/aml-build.h" diff --git a/hw/microblaze/boot.c b/hw/microblaze/boot.c index 9eebb1a..1834d22 100644 --- a/hw/microblaze/boot.c +++ b/hw/microblaze/boot.c @@ -30,7 +30,6 @@ #include "qemu/option.h" #include "qemu/config-file.h" #include "qemu/error-report.h" -#include "qemu-common.h" #include "sysemu/device_tree.h" #include "sysemu/sysemu.h" #include "hw/loader.h" diff --git a/hw/mips/mips_malta.c b/hw/mips/mips_malta.c index cf9bd3e..cf48f42 100644 --- a/hw/mips/mips_malta.c +++ b/hw/mips/mips_malta.c @@ -47,7 +47,6 @@ #include "elf.h" #include "hw/timer/mc146818rtc.h" #include "hw/timer/i8254.h" -#include "sysemu/block-backend.h" #include "sysemu/blockdev.h" #include "exec/address-spaces.h" #include "hw/sysbus.h" /* SysBusDevice */ diff --git a/hw/nvram/fw_cfg.c b/hw/nvram/fw_cfg.c index 92aa563..1f0c3e9 100644 --- a/hw/nvram/fw_cfg.c +++ b/hw/nvram/fw_cfg.c @@ -29,7 +29,6 @@ #include "hw/isa/isa.h" #include "hw/nvram/fw_cfg.h" #include "hw/sysbus.h" -#include "hw/boards.h" #include "trace.h" #include "qemu/error-report.h" #include "qemu/config-file.h" diff --git a/hw/pci-bridge/pci_expander_bridge.c b/hw/pci-bridge/pci_expander_bridge.c index 1cc598f..6ac187f 100644 --- a/hw/pci-bridge/pci_expander_bridge.c +++ b/hw/pci-bridge/pci_expander_bridge.c @@ -15,7 +15,6 @@ #include "hw/pci/pci.h" #include "hw/pci/pci_bus.h" #include "hw/pci/pci_host.h" -#include "hw/pci/pci_bus.h" #include "hw/pci/pci_bridge.h" #include "hw/i386/pc.h" #include "qemu/range.h" diff --git a/hw/ppc/ppc405_boards.c b/hw/ppc/ppc405_boards.c index 4b2f07a..d01798f 100644 --- a/hw/ppc/ppc405_boards.c +++ b/hw/ppc/ppc405_boards.c @@ -37,7 +37,6 @@ #include "qemu/log.h" #include "qemu/error-report.h" #include "hw/loader.h" -#include "sysemu/block-backend.h" #include "sysemu/blockdev.h" #include "exec/address-spaces.h" diff --git a/hw/ppc/spapr.c b/hw/ppc/spapr.c index 486f57d..17d5d6d 100644 --- a/hw/ppc/spapr.c +++ b/hw/ppc/spapr.c @@ -37,7 +37,6 @@ #include "sysemu/block-backend.h" #include "sysemu/cpus.h" #include "sysemu/kvm.h" -#include "sysemu/device_tree.h" #include "kvm_ppc.h" #include "migration/migration.h" #include "mmu-hash64.h" diff --git a/hw/timer/grlib_gptimer.c b/hw/timer/grlib_gptimer.c index 712d1ae..4ed96e9 100644 --- a/hw/timer/grlib_gptimer.c +++ b/hw/timer/grlib_gptimer.c @@ -26,7 +26,6 @@ #include "hw/s
Re: [Qemu-devel] [RFC] powernv: CPU compatibility modes don't make sense for powernv
On Fri, 2016-10-28 at 18:40 +0200, Cédric Le Goater wrote: > > It makes perfect sense. The "cpu-version" property is for PAPR, not > for OPAL. > hostboot and skiboot put SPR_PVR in this property. > > I will be careful using 'CPU_CORE(pc)->nr_threads' in the ICP patches > also. No, the cpu-version is part of the old OF bindings afaik, at least it exists under OPAL, so it should be there but yes, it should just contain the PVR. Cheers, Ben. > Reviewed-by: Cédric Le Goater > > Thanks, > > C. > > > > > > > > diff --git a/hw/ppc/pnv.c b/hw/ppc/pnv.c > > index 82276e0..6af3424 100644 > > --- a/hw/ppc/pnv.c > > +++ b/hw/ppc/pnv.c > > @@ -110,7 +110,7 @@ static void powernv_create_core_node(PnvChip > > *chip, PnvCore *pc, void *fdt) > > CPUState *cs = CPU(DEVICE(pc->threads)); > > DeviceClass *dc = DEVICE_GET_CLASS(cs); > > PowerPCCPU *cpu = POWERPC_CPU(cs); > > -int smt_threads = ppc_get_compat_smt_threads(cpu); > > +int smt_threads = CPU_CORE(pc)->nr_threads; > > CPUPPCState *env = &cpu->env; > > PowerPCCPUClass *pcc = POWERPC_CPU_GET_CLASS(cs); > > uint32_t servers_prop[smt_threads]; > > @@ -206,10 +206,6 @@ static void powernv_create_core_node(PnvChip > > *chip, PnvCore *pc, void *fdt) > > _FDT((fdt_setprop(fdt, offset, "ibm,pa-features", > > pa_features, sizeof(pa_features; > > > > -if (cpu->cpu_version) { > > -_FDT((fdt_setprop_cell(fdt, offset, "cpu-version", cpu- > > >cpu_version))); > > -} > > - > > /* Build interrupt servers properties */ > > for (i = 0; i < smt_threads; i++) { > > servers_prop[i] = cpu_to_be32(pc->pir + i); > >
Re: [Qemu-devel] [PATCH v2 3/6] target-ppc: add vrldnmi and vrlwmi instructions
On 10/27/2016 06:30 PM, David Gibson wrote: How about something like this in target-ppc/cpu.h #define FUNC_MASK(name, ret_type, size, max_val) \ static inline ret_type name (uint##size##_t start,\ uint##size##_t end) \ Consider introducing an internals.h, for stuff that needs to be shared within target-ppc/, but is not required by any other user of cpu.h. r~
Re: [Qemu-devel] [RFC] powernv: CPU compatibility modes don't make sense for powernv
On 10/28/2016 06:46 PM, Benjamin Herrenschmidt wrote: > On Fri, 2016-10-28 at 18:40 +0200, Cédric Le Goater wrote: >> >> It makes perfect sense. The "cpu-version" property is for PAPR, not >> for OPAL. >> hostboot and skiboot put SPR_PVR in this property. >> >> I will be careful using 'CPU_CORE(pc)->nr_threads' in the ICP patches >> also. > > No, the cpu-version is part of the old OF bindings afaik, at least it > exists under OPAL, so it should be there but yes, it should just > contain the PVR. powernv_create_core_node() sets "cpu-version" twice : _FDT((fdt_setprop_cell(fdt, offset, "cpu-version", env->spr[SPR_PVR]))); and then : if (cpu->cpu_version) { _FDT((fdt_setprop_cell(fdt, offset, "cpu-version", cpu->cpu_version))); } but the patch only removes the second one but you don't really see the first ... I should have said that. Cheers, C. > Cheers, > Ben. > >> Reviewed-by: Cédric Le Goater >> >> Thanks, >> >> C. >> >> >>> >>> >>> diff --git a/hw/ppc/pnv.c b/hw/ppc/pnv.c >>> index 82276e0..6af3424 100644 >>> --- a/hw/ppc/pnv.c >>> +++ b/hw/ppc/pnv.c >>> @@ -110,7 +110,7 @@ static void powernv_create_core_node(PnvChip >>> *chip, PnvCore *pc, void *fdt) >>> CPUState *cs = CPU(DEVICE(pc->threads)); >>> DeviceClass *dc = DEVICE_GET_CLASS(cs); >>> PowerPCCPU *cpu = POWERPC_CPU(cs); >>> -int smt_threads = ppc_get_compat_smt_threads(cpu); >>> +int smt_threads = CPU_CORE(pc)->nr_threads; >>> CPUPPCState *env = &cpu->env; >>> PowerPCCPUClass *pcc = POWERPC_CPU_GET_CLASS(cs); >>> uint32_t servers_prop[smt_threads]; >>> @@ -206,10 +206,6 @@ static void powernv_create_core_node(PnvChip >>> *chip, PnvCore *pc, void *fdt) >>> _FDT((fdt_setprop(fdt, offset, "ibm,pa-features", >>> pa_features, sizeof(pa_features; >>> >>> -if (cpu->cpu_version) { >>> -_FDT((fdt_setprop_cell(fdt, offset, "cpu-version", cpu- cpu_version))); >>> -} >>> - >>> /* Build interrupt servers properties */ >>> for (i = 0; i < smt_threads; i++) { >>> servers_prop[i] = cpu_to_be32(pc->pir + i); >>>
[Qemu-devel] [PATCH 1/6] tests/docker/Makefile.include: fix diff-index call
The whole thing is wrapped inside a call quiet-command as well as being the actual call taking a --quiet argument so the redirect is superfluous. For reasons I have yet to determine this also seems to be causing the source preparation step to skip stashing work tree stuff. Signed-off-by: Alex Bennée --- TODO: - properly understand the failure --- tests/docker/Makefile.include | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/docker/Makefile.include b/tests/docker/Makefile.include index 3f15d5a..d91e28b 100644 --- a/tests/docker/Makefile.include +++ b/tests/docker/Makefile.include @@ -20,7 +20,7 @@ IMAGES ?= % # Make archive from git repo $1 to tar.gz $2 make-archive-maybe = $(if $(wildcard $1/*), \ $(call quiet-command, \ - (cd $1; if git diff-index --quiet HEAD -- &>/dev/null; then \ + (cd $1; if git diff-index --quiet HEAD; then \ git archive -1 HEAD --format=tar.gz; \ else \ git archive -1 $$(git stash create) --format=tar.gz; \ -- 2.10.1
Re: [Qemu-devel] [RFC] powernv: CPU compatibility modes don't make sense for powernv
On 10/28/2016 04:05 AM, David Gibson wrote: > powernv has some code (derived from the spapr equivalent) used in device > tree generation which depends on the CPU's compatibility mode / logical > PVR. However, compatibility modes don't make sense on powernv - at least > not as a property controlled by the host - because the guest in powernv > has full hypervisor level access to the virtual system, and so owns the > PCR (Processor Compatibility Register) which implements compatiblity modes. > > Signed-off-by: David Gibson > --- > hw/ppc/pnv.c | 6 +- > 1 file changed, 1 insertion(+), 5 deletions(-) > > Hi Cédric, I'd appreciate it if you can double check my reasoning > here. This patch gets powernv out of the way of a bunch of > compatibility mode cleanups I have in the works. It makes perfect sense. The "cpu-version" property is for PAPR, not for OPAL. hostboot and skiboot put SPR_PVR in this property. I will be careful using 'CPU_CORE(pc)->nr_threads' in the ICP patches also. Reviewed-by: Cédric Le Goater Thanks, C. > > diff --git a/hw/ppc/pnv.c b/hw/ppc/pnv.c > index 82276e0..6af3424 100644 > --- a/hw/ppc/pnv.c > +++ b/hw/ppc/pnv.c > @@ -110,7 +110,7 @@ static void powernv_create_core_node(PnvChip *chip, > PnvCore *pc, void *fdt) > CPUState *cs = CPU(DEVICE(pc->threads)); > DeviceClass *dc = DEVICE_GET_CLASS(cs); > PowerPCCPU *cpu = POWERPC_CPU(cs); > -int smt_threads = ppc_get_compat_smt_threads(cpu); > +int smt_threads = CPU_CORE(pc)->nr_threads; > CPUPPCState *env = &cpu->env; > PowerPCCPUClass *pcc = POWERPC_CPU_GET_CLASS(cs); > uint32_t servers_prop[smt_threads]; > @@ -206,10 +206,6 @@ static void powernv_create_core_node(PnvChip *chip, > PnvCore *pc, void *fdt) > _FDT((fdt_setprop(fdt, offset, "ibm,pa-features", > pa_features, sizeof(pa_features; > > -if (cpu->cpu_version) { > -_FDT((fdt_setprop_cell(fdt, offset, "cpu-version", > cpu->cpu_version))); > -} > - > /* Build interrupt servers properties */ > for (i = 0; i < smt_threads; i++) { > servers_prop[i] = cpu_to_be32(pc->pir + i); >
[Qemu-devel] [PATCH 7/8] acpi nvdimm: rename result_size to dsm_out_buf_siz
Rename it as dsm_out_buf_siz is more descriptive Suggested-by: Igor Mammedov Signed-off-by: Xiao Guangrong --- hw/acpi/nvdimm.c | 15 --- 1 file changed, 8 insertions(+), 7 deletions(-) diff --git a/hw/acpi/nvdimm.c b/hw/acpi/nvdimm.c index cc958a4..12126d1 100644 --- a/hw/acpi/nvdimm.c +++ b/hw/acpi/nvdimm.c @@ -778,9 +778,9 @@ void nvdimm_init_acpi_state(AcpiNVDIMMState *state, MemoryRegion *io, static void nvdimm_build_common_dsm(Aml *dev) { -Aml *method, *ifctx, *function, *handle, *uuid, *dsm_mem, *result_size; +Aml *method, *ifctx, *function, *handle, *uuid, *dsm_mem; Aml *elsectx, *unsupport, *unpatched, *expected_uuid, *uuid_invalid; -Aml *pckg, *pckg_index, *pckg_buf, *field, *dsm_out_buf; +Aml *pckg, *pckg_index, *pckg_buf, *field, *dsm_out_buf, *dsm_out_buf_size; uint8_t byte_list[1]; method = aml_method(NVDIMM_COMMON_DSM, 5, AML_SERIALIZED); @@ -921,13 +921,14 @@ static void nvdimm_build_common_dsm(Aml *dev) */ aml_append(method, aml_store(dsm_mem, aml_name("NTFI"))); -result_size = aml_local(1); +dsm_out_buf_size = aml_local(1); /* RLEN is not included in the payload returned to guest. */ -aml_append(method, aml_subtract(aml_name("RLEN"), aml_int(4), result_size)); -aml_append(method, aml_store(aml_shiftleft(result_size, aml_int(3)), - result_size)); +aml_append(method, aml_subtract(aml_name("RLEN"), aml_int(4), +dsm_out_buf_size)); +aml_append(method, aml_store(aml_shiftleft(dsm_out_buf_size, aml_int(3)), + dsm_out_buf_size)); aml_append(method, aml_create_field(aml_name("ODAT"), aml_int(0), -result_size, "OBUF")); +dsm_out_buf_size, "OBUF")); aml_append(method, aml_concatenate(aml_buffer(0, NULL), aml_name("OBUF"), dsm_out_buf)); aml_append(method, aml_return(dsm_out_buf)); -- 1.8.3.1
[Qemu-devel] [PATCH 4/6] tests/docker/Makefile: Add a rule for Debian user images
This allows you to create Debian images powered by a qemu linux-user binary. Later patches will list these in the help file but for now: make docker-image-debian-stable-arm64 Signed-off-by: Alex Bennée --- tests/docker/Makefile.include | 16 1 file changed, 16 insertions(+) diff --git a/tests/docker/Makefile.include b/tests/docker/Makefile.include index d91e28b..bb9e078 100644 --- a/tests/docker/Makefile.include +++ b/tests/docker/Makefile.include @@ -64,6 +64,22 @@ $(foreach i,$(DOCKER_IMAGES), \ ) \ ) +# Additional Debian qemu-user images +# +# These images are built using the generic debian-bootstrap image and a qemu-user binary +# +docker-image-debian-%: DEB_TYPE = $(shell echo '$@' | sed -e 's/docker-image-debian-\([^@]*\)-\(.*\)/\1/') +docker-image-debian-%: DEB_ARCH = $(shell echo '$@' | sed -e 's/docker-image-debian-\([^@]*\)-\(.*\)/\2/') +docker-image-debian-%: QEMU_ARCH = $(subst arm64,aarch64,$(subst armhf,arm,$(DEB_ARCH))) +docker-image-debian-%: QEMU_EXEC=$(BUILD_DIR)/$(QEMU_ARCH)-linux-user/qemu-$(QEMU_ARCH) +docker-image-debian-%: $(DOCKER_FILES_DIR)/debian-bootstrap.docker + $(call quiet-command,\ + DEB_ARCH=$(DEB_ARCH) DEB_TYPE=$(DEB_TYPE) \ + $(SRC_PATH)/tests/docker/docker.py build qemu:debian-$* $< \ + $(if $V,,--quiet) $(if $(NOCACHE),--no-cache) \ + --include-executable=$(QEMU_EXEC),\ + "BUILD USER","$*") + docker: @echo 'Build QEMU and run tests inside Docker containers' @echo -- 2.10.1
[Qemu-devel] [PATCH 6/6] tests/docker/Makefile.include: expand docker help text
No we can query what has and hasn't been built we can make this list available in the help text. This is useful as some of the bootstrapped builds can take some time to build. Signed-off-by: Alex Bennée --- tests/docker/Makefile.include | 11 +-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/tests/docker/Makefile.include b/tests/docker/Makefile.include index bb9e078..a19991b 100644 --- a/tests/docker/Makefile.include +++ b/tests/docker/Makefile.include @@ -80,6 +80,10 @@ docker-image-debian-%: $(DOCKER_FILES_DIR)/debian-bootstrap.docker --include-executable=$(QEMU_EXEC),\ "BUILD USER","$*") +DOCKER_USER_IMAGES := debian-stable-armhf debian-stable-arm64 +DOCKER_BUILT_IMAGES := $(shell $(SRC_PATH)/tests/docker/docker.py images --repo qemu) +DOCKER_UNBUILT_IMAGES := $(filter-out debian-bootstrap, $(filter-out $(DOCKER_BUILT_IMAGES), $(DOCKER_USER_IMAGES) $(DOCKER_IMAGES))) + docker: @echo 'Build QEMU and run tests inside Docker containers' @echo @@ -96,8 +100,11 @@ docker: @echo 'docker-image-IMAGE: Build image "IMAGE".' @echo 'docker-run: For manually running a "TEST" with "IMAGE"' @echo - @echo 'Available container images:' - @echo '$(DOCKER_IMAGES)' + @echo 'Available built container images:' + @echo '$(DOCKER_BUILT_IMAGES)' + @echo + @echo 'Available (but unbuilt) container images:' + @echo '$(DOCKER_UNBUILT_IMAGES)' @echo @echo 'Available tests:' @echo '$(DOCKER_TESTS)' -- 2.10.1
Re: [Qemu-devel] [PATCH v2 01/11] qapi: add qapi2texi script
Marc-André Lureau writes: > As the name suggests, the qapi2texi script converts JSON QAPI > description into a standalone texi file suitable for different target > formats. > > It parses the following kind of blocks with some little variations: > > ## > # = Section > # == Subsection > # > # Some text foo with *emphasis* > # 1. with a list > # 2. like that > # > # And some code: > # | $ echo foo > # | <- do this > # | -> get that > # > ## > > ## > # @symbol > # > # Symbol body ditto ergo sum. Foo bar > # baz ding. > # > # @arg: foo > # @arg: #optional foo > # > # Returns: returns bla bla > # > # Or bla blah > # > # Since: version > # Notes: notes, comments can have > #- itemized list > #- like this > # > #and continue... > # > # Example: > # > # <- { "execute": "quit" } > # -> { "return": {} } > # > ## > > Thanks to the json declaration, it's able to give extra information > about the type of arguments and return value expected. > > Signed-off-by: Marc-André Lureau > --- > scripts/qapi.py| 100 +++- > scripts/qapi2texi.py | 314 > + > docs/qapi-code-gen.txt | 44 +-- > 3 files changed, 446 insertions(+), 12 deletions(-) > create mode 100755 scripts/qapi2texi.py My review will be easier to follow if you skip ahead qapi-code-gen.txt, then go to class QAPISchemaParser, then come back here. > diff --git a/scripts/qapi.py b/scripts/qapi.py > index 21bc32f..4efc7e7 100644 > --- a/scripts/qapi.py > +++ b/scripts/qapi.py > @@ -122,6 +122,79 @@ class QAPIExprError(Exception): > "%s:%d: %s" % (self.info['file'], self.info['line'], self.msg) > > > +class QAPIDoc: Old-style class. Make this class QAPIDoc(object): > +def __init__(self, comment): > +self.symbol = None > +self.comment = "" # the main symbol comment PEP8 wants at least two spaces before #, and I prefer the # in colum 32. > +self.args = OrderedDict() > +# meta is for Since:, Notes:, Examples:, Returns:... > +self.meta = OrderedDict() > +# the current section to populate, array of [dict, key, comment...] > +self.section = None > + > +for line in comment.split('\n'): Makes me wonder whether the caller should pass a list of lines instead of a string that needs to be split into lines. > +# remove multiple spaces > +sline = ' '.join(line.split()) Actually, this doesn't "remove multiple spaces", it squeezes sequences of whitespace into a single space character. Rather inefficiently, I suspect, but let's not worry about that now. > +# take the first word out > +split = sline.split(' ', 1) > +key = split[0] > + > +if key.startswith("@"): > +key = key[1:].rstrip(':') Treats the colon as optional. I understand you're trying to be unintrusive, but since we're parsing comments already, we can make the parser do double duty and enforce consistent comment formatting. But this isn't the place to discuss the format we want, review of qapi-code-gen.txt is. > +sline = split[1] if len(split) > 1 else "" > +if self.symbol is None: > +# the first is the section symbol > +self.symbol = key Let's not say "the section symbol". It's the symbol this APIDoc object documents. The APIDoc object has sections. > +else: > +# else an arg > +self.start_section(self.args, key) > +elif self.symbol and \ > +key in ("Returns:", > +# special case for Since often used without: > +"Since:", "Since", > +# those are often singular or plural > +"Note:", "Notes:", > +"Example:", "Examples:"): > +sline = split[1] if len(split) > 1 else "" > +line = None > +# new "meta" section > +self.start_section(self.meta, key.rstrip(':')) > + > +if self.section and self.section[1].startswith("Example"): > +# example is verbatim > +self.append_comment(line) > +else: > +self.append_comment(sline) Sections other than "Example" and "Examples" have whitespace squeezed. I believe this is the true reason for the squeezing. There are a few other places that rely on it, but they could do just as well without. > + > +self.end_section() > + > +def append_comment(self, line): > +"""Adds a comment to the current section, or the symbol comment""" > +if line is None: > +return > +if self.section is not None: > +if self.section[-1] == "" and line == "": > +
[Qemu-devel] [PATCH 4/8] acpi nvdimm: fix ARG3 conflict
As ARG3 is a reserved name, we rename it to FARG Suggested-by: Igor Mammedov Signed-off-by: Xiao Guangrong --- hw/acpi/nvdimm.c | 7 --- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/hw/acpi/nvdimm.c b/hw/acpi/nvdimm.c index c2f5caa..0b8c275 100644 --- a/hw/acpi/nvdimm.c +++ b/hw/acpi/nvdimm.c @@ -816,7 +816,8 @@ static void nvdimm_build_common_dsm(Aml *dev) * on NVDIMM Root Device. * REVS: store the Arg1 of _DSM call. * FUNC: store the Arg2 of _DSM call. - * ARG3: store the Arg3 of _DSM call. + * FARG: store the Arg3 of _DSM call which is a Package containing + * function-specific arguments. * * They are RAM mapping on host so that these accesses never cause * VM-EXIT. @@ -828,7 +829,7 @@ static void nvdimm_build_common_dsm(Aml *dev) sizeof(typeof_field(NvdimmDsmIn, revision)) * BITS_PER_BYTE)); aml_append(field, aml_named_field("FUNC", sizeof(typeof_field(NvdimmDsmIn, function)) * BITS_PER_BYTE)); -aml_append(field, aml_named_field("ARG3", +aml_append(field, aml_named_field("FARG", (sizeof(NvdimmDsmIn) - offsetof(NvdimmDsmIn, arg3)) * BITS_PER_BYTE)); aml_append(method, field); @@ -910,7 +911,7 @@ static void nvdimm_build_common_dsm(Aml *dev) pckg_buf = aml_local(3); aml_append(ifctx, aml_store(aml_index(pckg, aml_int(0)), pckg_index)); aml_append(ifctx, aml_store(aml_derefof(pckg_index), pckg_buf)); -aml_append(ifctx, aml_store(pckg_buf, aml_name("ARG3"))); +aml_append(ifctx, aml_store(pckg_buf, aml_name("FARG"))); aml_append(method, ifctx); /* -- 1.8.3.1
[Qemu-devel] [PATCH 0/6] Expand the building of qemu-user docker images
Hi Fam, These are a little bit of a work in progress so maybe not all ready to be taken yet although review would be welcome. This adds some tweaks to allow us to build the cross-arch debian images with direct make invocations and then see which images we can test against from the "make docker" help text. Now: make docker-image-debian-stable-arm64 Will do exactly as you expect. I can't get: make docker-test-quick@debian-stable-arm64 To work but I suspect this needs some fixing to the generated rules. Comments? Alex Bennée (6): tests/docker/Makefile.include: fix diff-index call tests/docker/test-user: a simple linux-user test tests/docker: add optional libs to travis.docker tests/docker/Makefile: Add a rule for Debian user images tests/docker/docker.py: expand images command tests/docker/Makefile.include: expand docker help text tests/docker/Makefile.include | 29 ++--- tests/docker/docker.py | 27 ++- tests/docker/dockerfiles/travis.docker | 9 - tests/docker/test-user | 18 ++ 4 files changed, 74 insertions(+), 9 deletions(-) create mode 100755 tests/docker/test-user -- 2.10.1
[Qemu-devel] [PATCH 2/6] tests/docker/test-user: a simple linux-user test
This is useful for checking an appropriately updated cross-arch docker actually starts without having to do a full build. Signed-off-by: Alex Bennée --- tests/docker/test-user | 18 ++ 1 file changed, 18 insertions(+) create mode 100755 tests/docker/test-user diff --git a/tests/docker/test-user b/tests/docker/test-user new file mode 100755 index 000..4871de7 --- /dev/null +++ b/tests/docker/test-user @@ -0,0 +1,18 @@ +#!/bin/bash -e +# +# A very simple test that checks qemu-linux-user binaries work +# correctly in a cross-arch docker container. +# +# Copyright (c) 2016 Linaro. +# +# Authors: +# Alex Bennée +# +# This work is licensed under the terms of the GNU GPL, version 2 +# or (at your option) any later version. See the COPYING file in +# the top-level directory. + +. common.rc + +uname -a +exit 0 -- 2.10.1
[Qemu-devel] [PATCH 2/8] acpi nvdimm: fix device physical address base
According to ACPI 6.0 spec, "Memory Device Physical Address Region Base" in memdev is defined as "This field provides the Device Physical Address base of the region". This field should be zero in our case Signed-off-by: Xiao Guangrong --- hw/acpi/nvdimm.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/hw/acpi/nvdimm.c b/hw/acpi/nvdimm.c index 24a2b3b..05fdf9c 100644 --- a/hw/acpi/nvdimm.c +++ b/hw/acpi/nvdimm.c @@ -289,8 +289,6 @@ static void nvdimm_build_structure_memdev(GArray *structures, DeviceState *dev) { NvdimmNfitMemDev *nfit_memdev; -uint64_t addr = object_property_get_int(OBJECT(dev), PC_DIMM_ADDR_PROP, -NULL); uint64_t size = object_property_get_int(OBJECT(dev), PC_DIMM_SIZE_PROP, NULL); int slot = object_property_get_int(OBJECT(dev), PC_DIMM_SLOT_PROP, @@ -314,7 +312,8 @@ nvdimm_build_structure_memdev(GArray *structures, DeviceState *dev) /* The memory region on the device. */ nfit_memdev->region_len = cpu_to_le64(size); -nfit_memdev->region_dpa = cpu_to_le64(addr); +/* The device address starts from 0. */ +nfit_memdev->region_dpa = cpu_to_le64(0); /* Only one interleave for PMEM. */ nfit_memdev->interleave_ways = cpu_to_le16(1); -- 1.8.3.1
[Qemu-devel] [PATCH 3/6] tests/docker: add optional libs to travis.docker
In our .travis.yml we install a bunch of extra libraries which are not part of the packaged QEMU's builddeps. We include them here to make our docker container more closely match the state of the system after docker has installed the rest of the build dependencies. Signed-off-by: Alex Bennée --- tests/docker/dockerfiles/travis.docker | 9 - 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/tests/docker/dockerfiles/travis.docker b/tests/docker/dockerfiles/travis.docker index e4983ae..6bef722 100644 --- a/tests/docker/dockerfiles/travis.docker +++ b/tests/docker/dockerfiles/travis.docker @@ -2,5 +2,12 @@ FROM quay.io/travisci/travis-ruby RUN apt-get update RUN apt-get -y build-dep qemu RUN apt-get -y build-dep device-tree-compiler -RUN apt-get -y install python2.7 dh-autoreconf +# Additional optional libs not in QEMU's builddep +RUN apt-get -y install libbrlapi-dev liblttng-ust-dev libcap-ng-dev \ + libnfs-dev libnss3-dev libpixman-1-dev \ + libpng12-dev librados-dev libseccomp-dev \ + libspice-protocol-dev libspice-server-dev \ + libssh2-1-dev liburcu-dev libusb-1.0-0-dev \ + libvte-2.90-dev +RUN apt-get -y install python2.7 dh-autoreconf sparse ENV FEATURES pyyaml -- 2.10.1
[Qemu-devel] [PATCH 6/8] nvdimm acpi: compile nvdimm acpi code arch-independently
As the arch dependent info, TARGET_PAGE_SIZE, has been dropped from nvdimm acpi code, it can be compiled arch-independently Signed-off-by: Xiao Guangrong --- hw/acpi/Makefile.objs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/hw/acpi/Makefile.objs b/hw/acpi/Makefile.objs index 4b7da66..489e63b 100644 --- a/hw/acpi/Makefile.objs +++ b/hw/acpi/Makefile.objs @@ -3,7 +3,7 @@ common-obj-$(CONFIG_ACPI_X86_ICH) += ich9.o tco.o common-obj-$(CONFIG_ACPI_CPU_HOTPLUG) += cpu_hotplug.o common-obj-$(CONFIG_ACPI_MEMORY_HOTPLUG) += memory_hotplug.o memory_hotplug_acpi_table.o common-obj-$(CONFIG_ACPI_CPU_HOTPLUG) += cpu.o -obj-$(CONFIG_ACPI_NVDIMM) += nvdimm.o +common-obj-$(CONFIG_ACPI_NVDIMM) += nvdimm.o common-obj-$(CONFIG_ACPI) += acpi_interface.o common-obj-$(CONFIG_ACPI) += bios-linker-loader.o common-obj-$(CONFIG_ACPI) += aml-build.o -- 1.8.3.1
[Qemu-devel] [PATCH 8/8] nvdimm acpi: use common macros instead of magic names
There are some names repeatedly used in acpi code, define them as macros to refine the code Suggested-by: Igor Mammedov Signed-off-by: Xiao Guangrong --- hw/acpi/nvdimm.c | 83 +--- 1 file changed, 49 insertions(+), 34 deletions(-) diff --git a/hw/acpi/nvdimm.c b/hw/acpi/nvdimm.c index 12126d1..bb896c9 100644 --- a/hw/acpi/nvdimm.c +++ b/hw/acpi/nvdimm.c @@ -773,8 +773,20 @@ void nvdimm_init_acpi_state(AcpiNVDIMMState *state, MemoryRegion *io, state->dsm_mem->len); } -#define NVDIMM_COMMON_DSM "NCAL" -#define NVDIMM_ACPI_MEM_ADDR "MEMA" +#define NVDIMM_COMMON_DSM "NCAL" +#define NVDIMM_ACPI_MEM_ADDR"MEMA" + +#define NVDIMM_DSM_MEMORY "NRAM" +#define NVDIMM_DSM_IOPORT "NPIO" + +#define NVDIMM_DSM_NOTIFY "NTFI" +#define NVDIMM_DSM_HANDLE "HDLE" +#define NVDIMM_DSM_REVISION "REVS" +#define NVDIMM_DSM_FUNCTION "FUNC" +#define NVDIMM_DSM_ARG3 "FARG" + +#define NVDIMM_DSM_OUT_BUF_SIZE "RLEN" +#define NVDIMM_DSM_OUT_BUF "ODAT" static void nvdimm_build_common_dsm(Aml *dev) { @@ -793,60 +805,63 @@ static void nvdimm_build_common_dsm(Aml *dev) aml_append(method, aml_store(aml_name(NVDIMM_ACPI_MEM_ADDR), dsm_mem)); /* map DSM memory and IO into ACPI namespace. */ -aml_append(method, aml_operation_region("NPIO", AML_SYSTEM_IO, +aml_append(method, aml_operation_region(NVDIMM_DSM_IOPORT, AML_SYSTEM_IO, aml_int(NVDIMM_ACPI_IO_BASE), NVDIMM_ACPI_IO_LEN)); -aml_append(method, aml_operation_region("NRAM", AML_SYSTEM_MEMORY, - dsm_mem, sizeof(NvdimmDsmIn))); +aml_append(method, aml_operation_region(NVDIMM_DSM_MEMORY, + AML_SYSTEM_MEMORY, dsm_mem, sizeof(NvdimmDsmIn))); /* * DSM notifier: - * NTFI: write the address of DSM memory and notify QEMU to emulate - * the access. + * NVDIMM_DSM_NOTIFY: write the address of DSM memory and notify QEMU to + *emulate the access. * * It is the IO port so that accessing them will cause VM-exit, the * control will be transferred to QEMU. */ -field = aml_field("NPIO", AML_DWORD_ACC, AML_NOLOCK, AML_PRESERVE); -aml_append(field, aml_named_field("NTFI", +field = aml_field(NVDIMM_DSM_IOPORT, AML_DWORD_ACC, AML_NOLOCK, + AML_PRESERVE); +aml_append(field, aml_named_field(NVDIMM_DSM_NOTIFY, sizeof(uint32_t) * BITS_PER_BYTE)); aml_append(method, field); /* * DSM input: - * HDLE: store device's handle, it's zero if the _DSM call happens - * on NVDIMM Root Device. - * REVS: store the Arg1 of _DSM call. - * FUNC: store the Arg2 of _DSM call. - * FARG: store the Arg3 of _DSM call which is a Package containing - * function-specific arguments. + * NVDIMM_DSM_HANDLE: store device's handle, it's zero if the _DSM call + *happens on NVDIMM Root Device. + * NVDIMM_DSM_REVISION: store the Arg1 of _DSM call. + * NVDIMM_DSM_FUNCTION: store the Arg2 of _DSM call. + * NVDIMM_DSM_ARG3: store the Arg3 of _DSM call which is a Package + * containing function-specific arguments. * * They are RAM mapping on host so that these accesses never cause * VM-EXIT. */ -field = aml_field("NRAM", AML_DWORD_ACC, AML_NOLOCK, AML_PRESERVE); -aml_append(field, aml_named_field("HDLE", +field = aml_field(NVDIMM_DSM_MEMORY, AML_DWORD_ACC, AML_NOLOCK, + AML_PRESERVE); +aml_append(field, aml_named_field(NVDIMM_DSM_HANDLE, sizeof(typeof_field(NvdimmDsmIn, handle)) * BITS_PER_BYTE)); -aml_append(field, aml_named_field("REVS", +aml_append(field, aml_named_field(NVDIMM_DSM_REVISION, sizeof(typeof_field(NvdimmDsmIn, revision)) * BITS_PER_BYTE)); -aml_append(field, aml_named_field("FUNC", +aml_append(field, aml_named_field(NVDIMM_DSM_FUNCTION, sizeof(typeof_field(NvdimmDsmIn, function)) * BITS_PER_BYTE)); -aml_append(field, aml_named_field("FARG", +aml_append(field, aml_named_field(NVDIMM_DSM_ARG3, (sizeof(NvdimmDsmIn) - offsetof(NvdimmDsmIn, arg3)) * BITS_PER_BYTE)); aml_append(method, field); /* * DSM output: - * RLEN: the size of the buffer filled by QEMU. - * ODAT: the buffer QEMU uses to store the result. + * NVDIMM_DSM_OUT_BUF_SIZE: the size of the buffer filled by QEMU. + * NVDIMM_DSM_OUT_BUF: the buffer QEMU uses to store the result. * * Since the page is reused by both input and out, the input data * will be lost after storing new result into ODAT so we should fetch * all the input data before writing the result. */ -field = aml_field("NRAM", AML_DWORD_ACC, AML_NOLOCK, AML_PRESERVE); -aml_append(field, aml_named_field("RLEN", +field = aml_field(NVDIMM_DSM_MEMORY,
[Qemu-devel] [PATCH 3/8] acpi nvdimm: fix OperationRegion definition
Based on ACPI spec: RegionOffset := TermArg => Integer However, Named object is not a TermArg. This patch moves OperationRegion to NCAL() and uses localX as its RegionOffset Suggested-by: Igor Mammedov Signed-off-by: Xiao Guangrong --- hw/acpi/nvdimm.c | 122 --- 1 file changed, 62 insertions(+), 60 deletions(-) diff --git a/hw/acpi/nvdimm.c b/hw/acpi/nvdimm.c index 05fdf9c..c2f5caa 100644 --- a/hw/acpi/nvdimm.c +++ b/hw/acpi/nvdimm.c @@ -780,14 +780,73 @@ static void nvdimm_build_common_dsm(Aml *dev) { Aml *method, *ifctx, *function, *handle, *uuid, *dsm_mem, *result_size; Aml *elsectx, *unsupport, *unpatched, *expected_uuid, *uuid_invalid; -Aml *pckg, *pckg_index, *pckg_buf; +Aml *pckg, *pckg_index, *pckg_buf, *field; uint8_t byte_list[1]; method = aml_method(NVDIMM_COMMON_DSM, 5, AML_SERIALIZED); uuid = aml_arg(0); function = aml_arg(2); handle = aml_arg(4); -dsm_mem = aml_name(NVDIMM_ACPI_MEM_ADDR); +dsm_mem = aml_local(6); + +aml_append(method, aml_store(aml_name(NVDIMM_ACPI_MEM_ADDR), dsm_mem)); + +/* map DSM memory and IO into ACPI namespace. */ +aml_append(method, aml_operation_region("NPIO", AML_SYSTEM_IO, + aml_int(NVDIMM_ACPI_IO_BASE), NVDIMM_ACPI_IO_LEN)); +aml_append(method, aml_operation_region("NRAM", AML_SYSTEM_MEMORY, + dsm_mem, sizeof(NvdimmDsmIn))); + +/* + * DSM notifier: + * NTFI: write the address of DSM memory and notify QEMU to emulate + * the access. + * + * It is the IO port so that accessing them will cause VM-exit, the + * control will be transferred to QEMU. + */ +field = aml_field("NPIO", AML_DWORD_ACC, AML_NOLOCK, AML_PRESERVE); +aml_append(field, aml_named_field("NTFI", + sizeof(uint32_t) * BITS_PER_BYTE)); +aml_append(method, field); + +/* + * DSM input: + * HDLE: store device's handle, it's zero if the _DSM call happens + * on NVDIMM Root Device. + * REVS: store the Arg1 of _DSM call. + * FUNC: store the Arg2 of _DSM call. + * ARG3: store the Arg3 of _DSM call. + * + * They are RAM mapping on host so that these accesses never cause + * VM-EXIT. + */ +field = aml_field("NRAM", AML_DWORD_ACC, AML_NOLOCK, AML_PRESERVE); +aml_append(field, aml_named_field("HDLE", + sizeof(typeof_field(NvdimmDsmIn, handle)) * BITS_PER_BYTE)); +aml_append(field, aml_named_field("REVS", + sizeof(typeof_field(NvdimmDsmIn, revision)) * BITS_PER_BYTE)); +aml_append(field, aml_named_field("FUNC", + sizeof(typeof_field(NvdimmDsmIn, function)) * BITS_PER_BYTE)); +aml_append(field, aml_named_field("ARG3", + (sizeof(NvdimmDsmIn) - offsetof(NvdimmDsmIn, arg3)) * BITS_PER_BYTE)); +aml_append(method, field); + +/* + * DSM output: + * RLEN: the size of the buffer filled by QEMU. + * ODAT: the buffer QEMU uses to store the result. + * + * Since the page is reused by both input and out, the input data + * will be lost after storing new result into ODAT so we should fetch + * all the input data before writing the result. + */ +field = aml_field("NRAM", AML_DWORD_ACC, AML_NOLOCK, AML_PRESERVE); +aml_append(field, aml_named_field("RLEN", + sizeof(typeof_field(NvdimmDsmOut, len)) * BITS_PER_BYTE)); +aml_append(field, aml_named_field("ODAT", + (sizeof(NvdimmDsmOut) - offsetof(NvdimmDsmOut, data)) * BITS_PER_BYTE)); +aml_append(method, field); /* * do not support any method if DSM memory address has not been @@ -914,7 +973,7 @@ static void nvdimm_build_ssdt(GSList *device_list, GArray *table_offsets, GArray *table_data, BIOSLinker *linker, GArray *dsm_dma_arrea) { -Aml *ssdt, *sb_scope, *dev, *field; +Aml *ssdt, *sb_scope, *dev; int mem_addr_offset, nvdimm_ssdt; acpi_add_table(table_offsets, table_data); @@ -939,63 +998,6 @@ static void nvdimm_build_ssdt(GSList *device_list, GArray *table_offsets, */ aml_append(dev, aml_name_decl("_HID", aml_string("ACPI0012"))); -/* map DSM memory and IO into ACPI namespace. */ -aml_append(dev, aml_operation_region("NPIO", AML_SYSTEM_IO, - aml_int(NVDIMM_ACPI_IO_BASE), NVDIMM_ACPI_IO_LEN)); -aml_append(dev, aml_operation_region("NRAM", AML_SYSTEM_MEMORY, - aml_name(NVDIMM_ACPI_MEM_ADDR), sizeof(NvdimmDsmIn))); - -/* - * DSM notifier: - * NTFI: write the address of DSM memory and notify QEMU to emulate - * the access. - * - * It is the IO port so that accessing them will cause VM-exit, the - * control will be transferred to QEMU. - */ -field = aml_field("NPIO", AML_DWORD_ACC, AML_NOLOCK, AML_PRESERVE); -aml_append(field, aml_named_field("NTFI", - sizeof(uint32_t) *
[Qemu-devel] [PATCH 5/8] acpi nvdimm: fix Arg6 usage
As the function only has 5 args, we use local7 instead of it Suggested-by: Igor Mammedov Signed-off-by: Xiao Guangrong --- hw/acpi/nvdimm.c | 7 --- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/hw/acpi/nvdimm.c b/hw/acpi/nvdimm.c index 0b8c275..cc958a4 100644 --- a/hw/acpi/nvdimm.c +++ b/hw/acpi/nvdimm.c @@ -780,7 +780,7 @@ static void nvdimm_build_common_dsm(Aml *dev) { Aml *method, *ifctx, *function, *handle, *uuid, *dsm_mem, *result_size; Aml *elsectx, *unsupport, *unpatched, *expected_uuid, *uuid_invalid; -Aml *pckg, *pckg_index, *pckg_buf, *field; +Aml *pckg, *pckg_index, *pckg_buf, *field, *dsm_out_buf; uint8_t byte_list[1]; method = aml_method(NVDIMM_COMMON_DSM, 5, AML_SERIALIZED); @@ -788,6 +788,7 @@ static void nvdimm_build_common_dsm(Aml *dev) function = aml_arg(2); handle = aml_arg(4); dsm_mem = aml_local(6); +dsm_out_buf = aml_local(7); aml_append(method, aml_store(aml_name(NVDIMM_ACPI_MEM_ADDR), dsm_mem)); @@ -928,8 +929,8 @@ static void nvdimm_build_common_dsm(Aml *dev) aml_append(method, aml_create_field(aml_name("ODAT"), aml_int(0), result_size, "OBUF")); aml_append(method, aml_concatenate(aml_buffer(0, NULL), aml_name("OBUF"), - aml_arg(6))); -aml_append(method, aml_return(aml_arg(6))); + dsm_out_buf)); +aml_append(method, aml_return(dsm_out_buf)); aml_append(dev, method); } -- 1.8.3.1
[Qemu-devel] [PATCH 1/8] acpi nvdimm: fix wrong buffer size returned by DSM method
Currently, 'RLEN' is the totally buffer size written by QEMU and it is ACPI internally used only. The buffer size returned to guest should not include 'RLEN' itself Signed-off-by: Xiao Guangrong --- hw/acpi/nvdimm.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/hw/acpi/nvdimm.c b/hw/acpi/nvdimm.c index e486128..24a2b3b 100644 --- a/hw/acpi/nvdimm.c +++ b/hw/acpi/nvdimm.c @@ -862,7 +862,8 @@ static void nvdimm_build_common_dsm(Aml *dev) aml_append(method, aml_store(dsm_mem, aml_name("NTFI"))); result_size = aml_local(1); -aml_append(method, aml_store(aml_name("RLEN"), result_size)); +/* RLEN is not included in the payload returned to guest. */ +aml_append(method, aml_subtract(aml_name("RLEN"), aml_int(4), result_size)); aml_append(method, aml_store(aml_shiftleft(result_size, aml_int(3)), result_size)); aml_append(method, aml_create_field(aml_name("ODAT"), aml_int(0), -- 1.8.3.1
[Qemu-devel] [PULL 21/23] scripts/clean-includes: added duplicate #include check
From: Anand J Enhance the clean-includes script to optionally check for duplicate #include entries. Script might output false positive entries as well. Such entries should not be removed. So if it finds any duplicate entries script will terminate with an exit status 1. Then each and every file should be checked manually and corrected if necessary. In order to enable the check use --check-dup-head option with scripts/clean-includes. Reviewed-by: Thomas Huth Signed-off-by: Anand J Signed-off-by: Michael Tokarev --- scripts/clean-includes | 56 +- 1 file changed, 42 insertions(+), 14 deletions(-) diff --git a/scripts/clean-includes b/scripts/clean-includes index 4412a55..dd938da 100755 --- a/scripts/clean-includes +++ b/scripts/clean-includes @@ -14,15 +14,18 @@ # the top-level directory. # Usage: -# clean-includes [--git subjectprefix] file ... +# clean-includes [--git subjectprefix] [--check-dup-head] file ... # or -# clean-includes [--git subjectprefix] --all +# clean-includes [--git subjectprefix] [--check-dup-head] --all # # If the --git subjectprefix option is given, then after making # the changes to the files this script will create a git commit # with the subject line "subjectprefix: Clean up includes" # and a boilerplate commit message. # +# If --check-dup-head is specified, additionally check for duplicate +# header includes. +# # Using --all will cause clean-includes to run on the whole source # tree (excluding certain directories which are known not to need # handling). @@ -45,23 +48,40 @@ GIT=no +DUPHEAD=no # Extended regular expression defining files to ignore when using --all XDIRREGEX='^(tests/tcg|tests/multiboot|pc-bios|disas/libvixl)' -if [ $# -ne 0 ] && [ "$1" = "--git" ]; then -if [ $# -eq 1 ]; then -echo "--git option requires an argument" -exit 1 -fi -GITSUBJ="$2" -GIT=yes -shift -shift -fi +while true +do +case $1 in +"--git") + if [ $# -eq 1 ]; then + echo "--git option requires an argument" + exit 1 + fi + GITSUBJ="$2" + GIT=yes + shift + shift + ;; +"--check-dup-head") +DUPHEAD=yes +shift +;; +"--") +shift +break +;; +*) +break +;; + esac +done if [ $# -eq 0 ]; then -echo "Usage: clean-includes [--git subjectprefix] [--all | foo.c ...]" +echo "Usage: clean-includes [--git subjectprefix] [--check-dup-head] [--all | foo.c ...]" echo "(modifies the files in place)" exit 1 fi @@ -91,7 +111,6 @@ cat >"$COCCIFILE" < 1) print $0}' +if [ $? -eq 0 ]; then +echo "Found duplicate header file includes. Please check the above files manually." +exit 1 +fi +fi + if [ "$GIT" = "yes" ]; then git add -- "$@" git commit --signoff -F - <