[Qemu-devel] [PATCH v4] This patch adds support for a new block device type called "vxhs".

2016-10-28 Thread Ashish Mittal
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

2016-10-28 Thread Jike Song
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

2016-10-28 Thread Zach
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

2016-10-28 Thread Jike Song
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()

2016-10-28 Thread Eduardo Habkost
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

2016-10-28 Thread Eduardo Habkost
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

2016-10-28 Thread Eduardo Habkost
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

2016-10-28 Thread Eduardo Habkost
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

2016-10-28 Thread Eduardo Habkost
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

2016-10-28 Thread Eduardo Habkost
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

2016-10-28 Thread Eduardo Habkost
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

2016-10-28 Thread Eduardo Habkost
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

2016-10-28 Thread Stefano Stabellini
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

2016-10-28 Thread Stefano Stabellini
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

2016-10-28 Thread Stefano Stabellini
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

2016-10-28 Thread Stefano Stabellini
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

2016-10-28 Thread Stefano Stabellini
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

2016-10-28 Thread Stefano Stabellini
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

2016-10-28 Thread Stefano Stabellini
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

2016-10-28 Thread Stefano Stabellini
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

2016-10-28 Thread Stefano Stabellini
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

2016-10-28 Thread Stefano Stabellini
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

2016-10-28 Thread Stefano Stabellini
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

2016-10-28 Thread Stefano Stabellini
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

2016-10-28 Thread Stefano Stabellini
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

2016-10-28 Thread Stefano Stabellini
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

2016-10-28 Thread Richard Henderson

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

2016-10-28 Thread Laurent Vivier
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

2016-10-28 Thread Laurent Vivier
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

2016-10-28 Thread Laurent Vivier
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

2016-10-28 Thread Laurent Vivier


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

2016-10-28 Thread Laurent Vivier
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

2016-10-28 Thread Laurent Vivier
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

2016-10-28 Thread Laurent Vivier
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

2016-10-28 Thread John Snow
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()

2016-10-28 Thread Greg Kurz
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

2016-10-28 Thread Buddhi Madhav


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

2016-10-28 Thread Jeff Cody
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

2016-10-28 Thread ashish mittal
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

2016-10-28 Thread John Snow



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

2016-10-28 Thread John Snow
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

2016-10-28 Thread Wang Cheng
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

2016-10-28 Thread Alex Williamson
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

2016-10-28 Thread Eric Blake
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

2016-10-28 Thread Kirti Wankhede


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

2016-10-28 Thread Eric Blake
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

2016-10-28 Thread Jianjun Duan


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

2016-10-28 Thread Dr. David Alan Gilbert
* 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

2016-10-28 Thread Jeff Cody
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

2016-10-28 Thread Jeff Cody
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.

2016-10-28 Thread Peter Maydell
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

2016-10-28 Thread Jose Ricardo Ziviani
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

2016-10-28 Thread Richard Henderson

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

2016-10-28 Thread Jose Ricardo Ziviani
 - 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

2016-10-28 Thread Jose Ricardo Ziviani
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

2016-10-28 Thread Stefano Stabellini
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

2016-10-28 Thread Richard Henderson

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

2016-10-28 Thread Jeff Cody
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

2016-10-28 Thread Jeff Cody
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

2016-10-28 Thread Jose Ricardo Ziviani
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

2016-10-28 Thread Jose Ricardo Ziviani
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

2016-10-28 Thread Jose Ricardo Ziviani
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

2016-10-28 Thread Claudio Imbrenda
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

2016-10-28 Thread Jose Ricardo Ziviani
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

2016-10-28 Thread Jose Ricardo Ziviani
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

2016-10-28 Thread Claudio Imbrenda
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

2016-10-28 Thread Claudio Imbrenda
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

2016-10-28 Thread Ashijeet Acharya
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

2016-10-28 Thread Ashijeet Acharya
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

2016-10-28 Thread Ashijeet Acharya
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

2016-10-28 Thread Alex Williamson
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

2016-10-28 Thread Xiao Guangrong
_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

2016-10-28 Thread Xiao Guangrong
_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

2016-10-28 Thread Xiao Guangrong
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

2016-10-28 Thread Jeff Cody
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

2016-10-28 Thread Xiao Guangrong
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

2016-10-28 Thread Xiao Guangrong
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

2016-10-28 Thread Peter Maydell
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

2016-10-28 Thread Alex Bennée
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

2016-10-28 Thread Michael Tokarev
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

2016-10-28 Thread Benjamin Herrenschmidt
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

2016-10-28 Thread Richard Henderson

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

2016-10-28 Thread Cédric Le Goater
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

2016-10-28 Thread Alex Bennée
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

2016-10-28 Thread Cédric Le Goater
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

2016-10-28 Thread Xiao Guangrong
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

2016-10-28 Thread Alex Bennée
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

2016-10-28 Thread Alex Bennée
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

2016-10-28 Thread Markus Armbruster
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

2016-10-28 Thread Xiao Guangrong
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

2016-10-28 Thread Alex Bennée
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

2016-10-28 Thread Alex Bennée
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

2016-10-28 Thread Xiao Guangrong
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

2016-10-28 Thread Alex Bennée
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

2016-10-28 Thread Xiao Guangrong
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

2016-10-28 Thread Xiao Guangrong
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

2016-10-28 Thread Xiao Guangrong
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

2016-10-28 Thread Xiao Guangrong
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

2016-10-28 Thread Xiao Guangrong
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

2016-10-28 Thread Michael Tokarev
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 - <

  1   2   3   >