All of lore.kernel.org
 help / color / mirror / Atom feed
* [Qemu-devel] [RFC PATCH 0/4] VFIO platform: Use device properties API
@ 2015-01-12 13:21 Baptiste Reynal
  2015-01-12 13:21 ` [Qemu-devel] [RFC PATCH 1/4] linux-headers update Baptiste Reynal
                   ` (3 more replies)
  0 siblings, 4 replies; 8+ messages in thread
From: Baptiste Reynal @ 2015-01-12 13:21 UTC (permalink / raw)
  To: qemu-devel, kvmarm; +Cc: tech, Baptiste Reynal, eric.auger

This RFC shows the implementation on QEMU side of the device properties interface
presented in kernel patch series:
[RFC PATCH v3 0/3] vfio: platform: return device properties for a platform device
from branch vfio-device-properties-v3 on the repository:
https://github.com/virtualopensystems/linux-kvm-arm.git

When a VFIO device is bound to the VM, properties are queried to the host 
to fill the device tree.

One issue here is wheter a property may change between the host and the guest.
Currently, interrupt numbers and registers change, other information are kept
(including interrupt type and flags).

Regarding the clock, any primecell device requiring a clock is attached to 
apb-pclk.

DMA pl330 is used as an example. For this reason the last patch 
(3/3, arm,pl330 vfio device property) relies on the following
patch series: [RFC PATCH v2 0/3] VFIO support for AMBA devices.

Baptiste Reynal (4):
  linux-headers update
  hw/vfio/common.c : vfio_get_dev_property
  hw/arm/sysbus-fdt: vfio device property for interrupts
  hw/arm/sysbus-fdt: arm,pl330 vfio device property

 hw/arm/sysbus-fdt.c           | 134 ++++++++++++++++++++++++++++++++++++------
 hw/vfio/common.c              |  33 +++++++++++
 include/hw/vfio/vfio-common.h |   2 +
 linux-headers/linux/vfio.h    |  25 ++++++++
 4 files changed, 175 insertions(+), 19 deletions(-)

-- 
2.2.1

^ permalink raw reply	[flat|nested] 8+ messages in thread

* [Qemu-devel] [RFC PATCH 1/4] linux-headers update
  2015-01-12 13:21 [Qemu-devel] [RFC PATCH 0/4] VFIO platform: Use device properties API Baptiste Reynal
@ 2015-01-12 13:21 ` Baptiste Reynal
  2015-01-12 13:21 ` [Qemu-devel] [RFC PATCH 2/4] hw/vfio/common.c : vfio_get_dev_property Baptiste Reynal
                   ` (2 subsequent siblings)
  3 siblings, 0 replies; 8+ messages in thread
From: Baptiste Reynal @ 2015-01-12 13:21 UTC (permalink / raw)
  To: qemu-devel, kvmarm; +Cc: tech, Baptiste Reynal, eric.auger

Add VFIO device property constants

Signed-off-by: Baptiste Reynal <b.reynal@virtualopensystems.com>
---
 linux-headers/linux/vfio.h | 25 +++++++++++++++++++++++++
 1 file changed, 25 insertions(+)

diff --git a/linux-headers/linux/vfio.h b/linux-headers/linux/vfio.h
index 0f21aa6..0c5f578 100644
--- a/linux-headers/linux/vfio.h
+++ b/linux-headers/linux/vfio.h
@@ -166,6 +166,31 @@ struct vfio_device_info {
 #define VFIO_DEVICE_GET_INFO		_IO(VFIO_TYPE, VFIO_BASE + 7)
 
 /**
+ * VFIO_DEVICE_GET_DEV_PROPERTY - _IOR(VFIO_TYPE, VFIO_BASE + 16,
+ *						struct vfio_devtree_info)
+ *
+ * Retrieve a device property, e.g. from a device tree if available.
+ * Caller will initialize data[] with a single string with the requested
+ * devicetree property name, and type depending on whether a array of strings
+ * or an array of u32 values is expected. On success, data[] will be extended
+ * with the requested information, either as an array of u32, or with a list
+ * of strings separated by the NULL terminating character.
+ * Return: 0 on success, -errno on failure.
+ */
+struct vfio_dev_property {
+	__u32	argsz;
+	__u32	type;
+#define VFIO_DEV_PROPERTY_TYPE_STRINGS	0
+#define VFIO_DEV_PROPERTY_TYPE_U8	1
+#define VFIO_DEV_PROPERTY_TYPE_U16	2
+#define VFIO_DEV_PROPERTY_TYPE_U32	3
+#define VFIO_DEV_PROPERTY_TYPE_U64	4
+	__u32	length;
+	__u8	data[];
+};
+#define VFIO_DEVICE_GET_DEV_PROPERTY	_IO(VFIO_TYPE, VFIO_BASE + 17)
+
+/**
  * VFIO_DEVICE_GET_REGION_INFO - _IOWR(VFIO_TYPE, VFIO_BASE + 8,
  *				       struct vfio_region_info)
  *
-- 
2.2.1

^ permalink raw reply related	[flat|nested] 8+ messages in thread

* [Qemu-devel] [RFC PATCH 2/4] hw/vfio/common.c : vfio_get_dev_property
  2015-01-12 13:21 [Qemu-devel] [RFC PATCH 0/4] VFIO platform: Use device properties API Baptiste Reynal
  2015-01-12 13:21 ` [Qemu-devel] [RFC PATCH 1/4] linux-headers update Baptiste Reynal
@ 2015-01-12 13:21 ` Baptiste Reynal
  2015-01-12 15:36   ` Alex Williamson
  2015-01-12 13:21 ` [Qemu-devel] [RFC PATCH 3/4] hw/arm/sysbus-fdt: vfio device property for interrupts Baptiste Reynal
  2015-01-12 13:21 ` [Qemu-devel] [RFC PATCH 4/4] hw/arm/sysbus-fdt: arm, pl330 vfio device property Baptiste Reynal
  3 siblings, 1 reply; 8+ messages in thread
From: Baptiste Reynal @ 2015-01-12 13:21 UTC (permalink / raw)
  To: qemu-devel, kvmarm; +Cc: Alex Williamson, tech, Baptiste Reynal, eric.auger

Add a function to handle ioctl VFIO_DEVICE_GET_DEV_PROPERTY
to retrieve properties from a VFIO device.

Signed-off-by: Baptiste Reynal <b.reynal@virtualopensystems.com>
---
 hw/vfio/common.c              | 33 +++++++++++++++++++++++++++++++++
 include/hw/vfio/vfio-common.h |  2 ++
 2 files changed, 35 insertions(+)

diff --git a/hw/vfio/common.c b/hw/vfio/common.c
index ba00ec9..698d2c4 100644
--- a/hw/vfio/common.c
+++ b/hw/vfio/common.c
@@ -958,3 +958,36 @@ int vfio_container_ioctl(AddressSpace *as, int32_t groupid,
 
     return vfio_container_do_ioctl(as, groupid, req, param);
 }
+
+struct vfio_dev_property *vfio_get_dev_property(int device, const char *name,
+        unsigned int type)
+{
+    unsigned int length = 0;
+    struct vfio_dev_property *property = NULL;
+    int ret;
+
+    length = strlen(name) + 1;
+
+    while (1) {
+        unsigned int argsz = sizeof(struct vfio_dev_property) + length;
+        property = realloc(property, argsz);
+        property->argsz = argsz;
+        property->type = type;
+        strcpy((char *) property->data, name);
+
+        ret = ioctl(device, VFIO_DEVICE_GET_DEV_PROPERTY, property);
+
+        if (length < property->length) {
+            length = property->length;
+        } else {
+            break;
+        }
+    }
+
+    if (ret) {
+        g_free(property);
+        property = NULL;
+    }
+
+    return property;
+}
diff --git a/include/hw/vfio/vfio-common.h b/include/hw/vfio/vfio-common.h
index 2f1b09c..9c649cd 100644
--- a/include/hw/vfio/vfio-common.h
+++ b/include/hw/vfio/vfio-common.h
@@ -149,6 +149,8 @@ VFIOGroup *vfio_get_group(int groupid, AddressSpace *as);
 void vfio_put_group(VFIOGroup *group);
 int vfio_get_device(VFIOGroup *group, const char *name,
                     VFIODevice *vbasedev);
+struct vfio_dev_property *vfio_get_dev_property(int device, const char *name,
+        unsigned int type);
 
 extern const MemoryRegionOps vfio_region_ops;
 extern const MemoryListener vfio_memory_listener;
-- 
2.2.1

^ permalink raw reply related	[flat|nested] 8+ messages in thread

* [Qemu-devel] [RFC PATCH 3/4] hw/arm/sysbus-fdt: vfio device property for interrupts
  2015-01-12 13:21 [Qemu-devel] [RFC PATCH 0/4] VFIO platform: Use device properties API Baptiste Reynal
  2015-01-12 13:21 ` [Qemu-devel] [RFC PATCH 1/4] linux-headers update Baptiste Reynal
  2015-01-12 13:21 ` [Qemu-devel] [RFC PATCH 2/4] hw/vfio/common.c : vfio_get_dev_property Baptiste Reynal
@ 2015-01-12 13:21 ` Baptiste Reynal
  2015-01-15 15:57   ` Eric Auger
  2015-01-12 13:21 ` [Qemu-devel] [RFC PATCH 4/4] hw/arm/sysbus-fdt: arm, pl330 vfio device property Baptiste Reynal
  3 siblings, 1 reply; 8+ messages in thread
From: Baptiste Reynal @ 2015-01-12 13:21 UTC (permalink / raw)
  To: qemu-devel, kvmarm; +Cc: Peter Maydell, tech, Baptiste Reynal, eric.auger

Use the VFIO device property API to retrieve interrupt
information (type and flags) during device node creation.

Signed-off-by: Baptiste Reynal <b.reynal@virtualopensystems.com>
---
 hw/arm/sysbus-fdt.c | 26 ++++++++++++++++++--------
 1 file changed, 18 insertions(+), 8 deletions(-)

diff --git a/hw/arm/sysbus-fdt.c b/hw/arm/sysbus-fdt.c
index efdeea7..087e788 100644
--- a/hw/arm/sysbus-fdt.c
+++ b/hw/arm/sysbus-fdt.c
@@ -31,6 +31,7 @@
 #include "hw/vfio/vfio-pl330.h"
 
 #include <libfdt.h>
+#include <linux/vfio.h>
 
 /*
  * internal struct that contains the information to create dynamic
@@ -66,7 +67,7 @@ typedef struct NodeCreationPair {
  * Helper function, generate interrupts property for a given node
  */
 static int set_interrupts_fdt_node(char *nodename, SysBusDevice *sbdev,
-        void *opaque, int type, int flags)
+        void *opaque)
 {
     PlatformBusFdtData *data = opaque;
     PlatformBusDevice *pbus = data->pbus;
@@ -76,23 +77,32 @@ static int set_interrupts_fdt_node(char *nodename, SysBusDevice *sbdev,
     int i, ret;
     VFIOPlatformDevice *vdev = VFIO_PLATFORM_DEVICE(sbdev);
     VFIODevice *vbasedev = &vdev->vbasedev;
+    struct vfio_dev_property *irq_prop;
+
+    irq_prop = vfio_get_dev_property(vbasedev->fd, "interrupts",
+            VFIO_DEV_PROPERTY_TYPE_U32);
+
+    if (irq_prop == NULL) {
+        return -1;
+    }
 
     irq_attr = g_new(uint32_t, vbasedev->num_irqs*3);
 
     for (i = 0; i < vbasedev->num_irqs; i++) {
         irq_number = platform_bus_get_irqn(pbus, sbdev , i)
                          + data->irq_start;
-        irq_attr[3*i] = cpu_to_be32(type);
+        irq_attr[3*i] = cpu_to_be32(((__u32 *) irq_prop->data)[3*i]);
         irq_attr[3*i+1] = cpu_to_be32(irq_number);
-        irq_attr[3*i+2] = cpu_to_be32(flags);
+        irq_attr[3*i+2] = cpu_to_be32(((__u32 *) irq_prop->data)[3*i+2]);
     }
 
-   ret = qemu_fdt_setprop(fdt, nodename, "interrupts",
-                     irq_attr, vbasedev->num_irqs*3*sizeof(uint32_t));
+    ret = qemu_fdt_setprop(fdt, nodename, "interrupts",
+            irq_attr, vbasedev->num_irqs*3*sizeof(uint32_t));
 
     g_free(irq_attr);
+    g_free(irq_prop);
 
-   return ret;
+    return ret;
 }
 
 /**
@@ -168,7 +178,7 @@ static int add_calxeda_midway_xgmac_fdt_node(SysBusDevice *sbdev, void *opaque)
         goto fail;
     }
 
-    ret = set_interrupts_fdt_node(nodename, sbdev, opaque, 0, 0x4);
+    ret = set_interrupts_fdt_node(nodename, sbdev, opaque);
 
     if (ret < 0) {
         error_report("could not set interrupts property of node %s",
@@ -248,7 +258,7 @@ static int add_arm_pl330_fdt_node(SysBusDevice *sbdev, void *opaque)
         goto fail;
     }
 
-    ret = set_interrupts_fdt_node(nodename, sbdev, opaque, 0, 0x4);
+    ret = set_interrupts_fdt_node(nodename, sbdev, opaque);
 
     if (ret < 0) {
         error_report("could not set interrupts property of node %s",
-- 
2.2.1

^ permalink raw reply related	[flat|nested] 8+ messages in thread

* [Qemu-devel] [RFC PATCH 4/4] hw/arm/sysbus-fdt: arm, pl330 vfio device property
  2015-01-12 13:21 [Qemu-devel] [RFC PATCH 0/4] VFIO platform: Use device properties API Baptiste Reynal
                   ` (2 preceding siblings ...)
  2015-01-12 13:21 ` [Qemu-devel] [RFC PATCH 3/4] hw/arm/sysbus-fdt: vfio device property for interrupts Baptiste Reynal
@ 2015-01-12 13:21 ` Baptiste Reynal
  2015-01-15 16:16   ` Eric Auger
  3 siblings, 1 reply; 8+ messages in thread
From: Baptiste Reynal @ 2015-01-12 13:21 UTC (permalink / raw)
  To: qemu-devel, kvmarm; +Cc: Peter Maydell, tech, Baptiste Reynal, eric.auger

Adapt arm,pl330 function to use the vfio device property API.

Clock apb-pclk is the default if a clock is needed by the device.

Three optional parameters are taken into account :
- #dma-cells
- #dma-channels
- #dma-requests

Signed-off-by: Baptiste Reynal <b.reynal@virtualopensystems.com>
---
 hw/arm/sysbus-fdt.c | 120 ++++++++++++++++++++++++++++++++++++++++++++--------
 1 file changed, 103 insertions(+), 17 deletions(-)

diff --git a/hw/arm/sysbus-fdt.c b/hw/arm/sysbus-fdt.c
index 087e788..a0adc50 100644
--- a/hw/arm/sysbus-fdt.c
+++ b/hw/arm/sysbus-fdt.c
@@ -96,13 +96,13 @@ static int set_interrupts_fdt_node(char *nodename, SysBusDevice *sbdev,
         irq_attr[3*i+2] = cpu_to_be32(((__u32 *) irq_prop->data)[3*i+2]);
     }
 
-    ret = qemu_fdt_setprop(fdt, nodename, "interrupts",
-            irq_attr, vbasedev->num_irqs*3*sizeof(uint32_t));
+   ret = qemu_fdt_setprop(fdt, nodename, "interrupts",
+                     irq_attr, vbasedev->num_irqs*3*sizeof(uint32_t));
 
     g_free(irq_attr);
     g_free(irq_prop);
 
-    return ret;
+   return ret;
 }
 
 /**
@@ -140,6 +140,54 @@ static int set_regions_fdt_node(char *nodename, SysBusDevice *sbdev,
     return ret;
 }
 
+static int set_arm_primecell_node(char *nodename, SysBusDevice *sbdev, void
+        *opaque)
+{
+    PlatformBusFdtData *data = opaque;
+    void *fdt = data->fdt;
+    int ret;
+    VFIOPlatformDevice *vdev = VFIO_PLATFORM_DEVICE(sbdev);
+    VFIODevice *vbasedev = &vdev->vbasedev;
+    struct vfio_dev_property *property;
+
+    /* Optional properties */
+    property = vfio_get_dev_property(vbasedev->fd, "interrupts",
+            VFIO_DEV_PROPERTY_TYPE_U32);
+    if (property != NULL) {
+        ret = set_interrupts_fdt_node(nodename, sbdev, opaque);
+        if (ret < 0) {
+            error_report("could not set interrupts property of node %s",
+                    nodename);
+            goto fail;
+        }
+        g_free(property);
+    }
+
+    property = vfio_get_dev_property(vbasedev->fd, "clock-names",
+            VFIO_DEV_PROPERTY_TYPE_STRINGS);
+    if (property != NULL) {
+        /* If a clock is attached, we rely on apb-pclk */
+        /* Check clock existence */
+        ret = fdt_path_offset(fdt, "/apb-pclk");
+
+        if (ret < 0) {
+            error_report("could not set clocks property of node %s", nodename);
+            goto fail;
+        } else {
+            qemu_fdt_setprop_cells(fdt, nodename, "clocks",
+                    qemu_fdt_getprop_cell(fdt, "/apb-pclk", "phandle"));
+            char clock_names[] = "apb_pclk";
+            qemu_fdt_setprop(fdt, nodename, "clock-names", clock_names,
+                    sizeof(clock_names));
+        }
+        g_free(property);
+    }
+
+    return 0;
+
+fail:
+    return -1;
+}
 /**
  * add_calxeda_midway_xgmac_fdt_node
  *
@@ -213,6 +261,8 @@ static int add_arm_pl330_fdt_node(SysBusDevice *sbdev, void *opaque)
     VFIOPlatformDevice *vdev = VFIO_PLATFORM_DEVICE(sbdev);
     VFIODevice *vbasedev = &vdev->vbasedev;
     Object *obj = OBJECT(sbdev);
+    struct vfio_dev_property *property;
+    int propint;
 
     mmio_base = object_property_get_int(obj, "mmio[0]", NULL);
 
@@ -222,6 +272,13 @@ static int add_arm_pl330_fdt_node(SysBusDevice *sbdev, void *opaque)
 
     qemu_fdt_add_subnode(fdt, nodename);
 
+    ret = set_arm_primecell_node(nodename, sbdev, opaque);
+    if (ret < 0) {
+        error_report("could not set arm,primecell properties of node %s",
+                nodename);
+        goto fail;
+    }
+
     /*
      * Process compatible string to deal with multiple strings
      * (; is replaced by \0)
@@ -237,20 +294,6 @@ static int add_arm_pl330_fdt_node(SysBusDevice *sbdev, void *opaque)
     qemu_fdt_setprop(fdt, nodename, "compatible",
                           compat, compat_str_len);
 
-    /* Setup clocks for AMBA device */
-    /* Check clock existence */
-    ret = fdt_path_offset(fdt, "/apb-pclk");
-
-    if (ret < 0) {
-        error_report("could not set clocks property of node %s", nodename);
-    } else {
-        qemu_fdt_setprop_cells(fdt, nodename, "clocks",
-                qemu_fdt_getprop_cell(fdt, "/apb-pclk", "phandle"));
-        char clock_names[] = "apb_pclk";
-        qemu_fdt_setprop(fdt, nodename, "clock-names", clock_names,
-                sizeof(clock_names));
-    }
-
     ret = set_regions_fdt_node(nodename, sbdev, opaque);
 
     if (ret < 0) {
@@ -266,6 +309,49 @@ static int add_arm_pl330_fdt_node(SysBusDevice *sbdev, void *opaque)
         goto fail;
     }
 
+    /* Optional properties */
+    property = vfio_get_dev_property(vbasedev->fd, "#dma-cells",
+            VFIO_DEV_PROPERTY_TYPE_U32);
+    if (property != NULL) {
+        propint = cpu_to_be32(((__u32 *) property->data)[0]);
+        ret = qemu_fdt_setprop(fdt, nodename, "#dma-cells", &propint,
+                sizeof(int));
+        if (ret < 0) {
+            error_report("could not set #dma-cells property of node %s",
+                    nodename);
+            goto fail;
+        }
+        g_free(property);
+    }
+
+    property = vfio_get_dev_property(vbasedev->fd, "#dma-channels",
+            VFIO_DEV_PROPERTY_TYPE_U32);
+    if (property != NULL) {
+        propint = cpu_to_be32(((__u32 *) property->data)[0]);
+        ret = qemu_fdt_setprop(fdt, nodename, "#dma-cells", &propint,
+                sizeof(int));
+        if (ret < 0) {
+            error_report("could not set #dma-cells property of node %s",
+                    nodename);
+            goto fail;
+        }
+        g_free(property);
+    }
+
+    property = vfio_get_dev_property(vbasedev->fd, "#dma-requests",
+            VFIO_DEV_PROPERTY_TYPE_U32);
+    if (property != NULL) {
+        propint = cpu_to_be32(((__u32 *) property->data)[0]);
+        ret = qemu_fdt_setprop(fdt, nodename, "#dma-cells", &propint,
+                sizeof(int));
+        if (ret < 0) {
+            error_report("could not set #dma-cells property of node %s",
+                    nodename);
+            goto fail;
+        }
+        g_free(property);
+    }
+
     g_free(nodename);
 
     return 0;
-- 
2.2.1

^ permalink raw reply related	[flat|nested] 8+ messages in thread

* Re: [Qemu-devel] [RFC PATCH 2/4] hw/vfio/common.c : vfio_get_dev_property
  2015-01-12 13:21 ` [Qemu-devel] [RFC PATCH 2/4] hw/vfio/common.c : vfio_get_dev_property Baptiste Reynal
@ 2015-01-12 15:36   ` Alex Williamson
  0 siblings, 0 replies; 8+ messages in thread
From: Alex Williamson @ 2015-01-12 15:36 UTC (permalink / raw)
  To: Baptiste Reynal; +Cc: eric.auger, tech, qemu-devel, kvmarm

On Mon, 2015-01-12 at 14:21 +0100, Baptiste Reynal wrote:
> Add a function to handle ioctl VFIO_DEVICE_GET_DEV_PROPERTY
> to retrieve properties from a VFIO device.
> 
> Signed-off-by: Baptiste Reynal <b.reynal@virtualopensystems.com>
> ---
>  hw/vfio/common.c              | 33 +++++++++++++++++++++++++++++++++
>  include/hw/vfio/vfio-common.h |  2 ++
>  2 files changed, 35 insertions(+)
> 
> diff --git a/hw/vfio/common.c b/hw/vfio/common.c
> index ba00ec9..698d2c4 100644
> --- a/hw/vfio/common.c
> +++ b/hw/vfio/common.c
> @@ -958,3 +958,36 @@ int vfio_container_ioctl(AddressSpace *as, int32_t groupid,
>  
>      return vfio_container_do_ioctl(as, groupid, req, param);
>  }
> +
> +struct vfio_dev_property *vfio_get_dev_property(int device, const char *name,
> +        unsigned int type)
> +{
> +    unsigned int length = 0;
> +    struct vfio_dev_property *property = NULL;
> +    int ret;
> +
> +    length = strlen(name) + 1;
> +
> +    while (1) {
> +        unsigned int argsz = sizeof(struct vfio_dev_property) + length;
> +        property = realloc(property, argsz);

By my read, realloc() doesn't give zero'd memory, so property->length is
uninitialized here.

> +        property->argsz = argsz;
> +        property->type = type;
> +        strcpy((char *) property->data, name);
> +
> +        ret = ioctl(device, VFIO_DEVICE_GET_DEV_PROPERTY, property);

This ioctl might not exit.

> +        if (length < property->length) {

Which means this compares length to random memory and potentially causes
a segfault when trying to realloc.

What types of devices are going to have VFIO_DEVICE_GET_DEV_PROPERTY and
is this appropriate for common?  The error and return here leaves
something to be desired.  Maybe only return for a given error.

> +            length = property->length;
> +        } else {
> +            break;
> +        }
> +    }
> +
> +    if (ret) {
> +        g_free(property);
> +        property = NULL;
> +    }
> +
> +    return property;
> +}
> diff --git a/include/hw/vfio/vfio-common.h b/include/hw/vfio/vfio-common.h
> index 2f1b09c..9c649cd 100644
> --- a/include/hw/vfio/vfio-common.h
> +++ b/include/hw/vfio/vfio-common.h
> @@ -149,6 +149,8 @@ VFIOGroup *vfio_get_group(int groupid, AddressSpace *as);
>  void vfio_put_group(VFIOGroup *group);
>  int vfio_get_device(VFIOGroup *group, const char *name,
>                      VFIODevice *vbasedev);
> +struct vfio_dev_property *vfio_get_dev_property(int device, const char *name,
> +        unsigned int type);
>  
>  extern const MemoryRegionOps vfio_region_ops;
>  extern const MemoryListener vfio_memory_listener;

^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: [Qemu-devel] [RFC PATCH 3/4] hw/arm/sysbus-fdt: vfio device property for interrupts
  2015-01-12 13:21 ` [Qemu-devel] [RFC PATCH 3/4] hw/arm/sysbus-fdt: vfio device property for interrupts Baptiste Reynal
@ 2015-01-15 15:57   ` Eric Auger
  0 siblings, 0 replies; 8+ messages in thread
From: Eric Auger @ 2015-01-15 15:57 UTC (permalink / raw)
  To: Baptiste Reynal, qemu-devel, kvmarm; +Cc: Peter Maydell, tech

Hi Baptiste
On 01/12/2015 02:21 PM, Baptiste Reynal wrote:
> Use the VFIO device property API to retrieve interrupt
> information (type and flags) during device node creation.
> 
> Signed-off-by: Baptiste Reynal <b.reynal@virtualopensystems.com>
> ---
>  hw/arm/sysbus-fdt.c | 26 ++++++++++++++++++--------
>  1 file changed, 18 insertions(+), 8 deletions(-)
> 
> diff --git a/hw/arm/sysbus-fdt.c b/hw/arm/sysbus-fdt.c
> index efdeea7..087e788 100644
> --- a/hw/arm/sysbus-fdt.c
> +++ b/hw/arm/sysbus-fdt.c
> @@ -31,6 +31,7 @@
>  #include "hw/vfio/vfio-pl330.h"
>  
>  #include <libfdt.h>
> +#include <linux/vfio.h>
>  
>  /*
>   * internal struct that contains the information to create dynamic
> @@ -66,7 +67,7 @@ typedef struct NodeCreationPair {
>   * Helper function, generate interrupts property for a given node
might be worth adding something like "based on host device tree node"
>   */
>  static int set_interrupts_fdt_node(char *nodename, SysBusDevice *sbdev,
> -        void *opaque, int type, int flags)
> +        void *opaque)
>  {
>      PlatformBusFdtData *data = opaque;
>      PlatformBusDevice *pbus = data->pbus;
> @@ -76,23 +77,32 @@ static int set_interrupts_fdt_node(char *nodename, SysBusDevice *sbdev,
>      int i, ret;
>      VFIOPlatformDevice *vdev = VFIO_PLATFORM_DEVICE(sbdev);
>      VFIODevice *vbasedev = &vdev->vbasedev;
> +    struct vfio_dev_property *irq_prop;
> +
> +    irq_prop = vfio_get_dev_property(vbasedev->fd, "interrupts",
> +            VFIO_DEV_PROPERTY_TYPE_U32);
> +
> +    if (irq_prop == NULL) {
> +        return -1;
> +    }
>  
>      irq_attr = g_new(uint32_t, vbasedev->num_irqs*3);
>  
>      for (i = 0; i < vbasedev->num_irqs; i++) {
>          irq_number = platform_bus_get_irqn(pbus, sbdev , i)
>                           + data->irq_start;
> -        irq_attr[3*i] = cpu_to_be32(type);
> +        irq_attr[3*i] = cpu_to_be32(((__u32 *) irq_prop->data)[3*i]);
>          irq_attr[3*i+1] = cpu_to_be32(irq_number);
> -        irq_attr[3*i+2] = cpu_to_be32(flags);
> +        irq_attr[3*i+2] = cpu_to_be32(((__u32 *) irq_prop->data)[3*i+2]);
>      }
>  
> -   ret = qemu_fdt_setprop(fdt, nodename, "interrupts",
> -                     irq_attr, vbasedev->num_irqs*3*sizeof(uint32_t));
> +    ret = qemu_fdt_setprop(fdt, nodename, "interrupts",
> +            irq_attr, vbasedev->num_irqs*3*sizeof(uint32_t));
delta may be removed?
>  
>      g_free(irq_attr);
> +    g_free(irq_prop);
>  
> -   return ret;
> +    return ret;
delta may be removed?
Best Regards
Eric
>  }
>  
>  /**
> @@ -168,7 +178,7 @@ static int add_calxeda_midway_xgmac_fdt_node(SysBusDevice *sbdev, void *opaque)
>          goto fail;
>      }
>  
> -    ret = set_interrupts_fdt_node(nodename, sbdev, opaque, 0, 0x4);
> +    ret = set_interrupts_fdt_node(nodename, sbdev, opaque);
>  
>      if (ret < 0) {
>          error_report("could not set interrupts property of node %s",
> @@ -248,7 +258,7 @@ static int add_arm_pl330_fdt_node(SysBusDevice *sbdev, void *opaque)
>          goto fail;
>      }
>  
> -    ret = set_interrupts_fdt_node(nodename, sbdev, opaque, 0, 0x4);
> +    ret = set_interrupts_fdt_node(nodename, sbdev, opaque);
>  
>      if (ret < 0) {
>          error_report("could not set interrupts property of node %s",
> 

^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: [Qemu-devel] [RFC PATCH 4/4] hw/arm/sysbus-fdt: arm, pl330 vfio device property
  2015-01-12 13:21 ` [Qemu-devel] [RFC PATCH 4/4] hw/arm/sysbus-fdt: arm, pl330 vfio device property Baptiste Reynal
@ 2015-01-15 16:16   ` Eric Auger
  0 siblings, 0 replies; 8+ messages in thread
From: Eric Auger @ 2015-01-15 16:16 UTC (permalink / raw)
  To: Baptiste Reynal, qemu-devel, kvmarm; +Cc: Peter Maydell, tech

Hi Baptiste,
On 01/12/2015 02:21 PM, Baptiste Reynal wrote:
> Adapt arm,pl330 function to use the vfio device property API.
> 
> Clock apb-pclk is the default if a clock is needed by the device.
> 
> Three optional parameters are taken into account :
> - #dma-cells
> - #dma-channels
> - #dma-requests
> 
> Signed-off-by: Baptiste Reynal <b.reynal@virtualopensystems.com>
> ---
>  hw/arm/sysbus-fdt.c | 120 ++++++++++++++++++++++++++++++++++++++++++++--------
>  1 file changed, 103 insertions(+), 17 deletions(-)
> 
> diff --git a/hw/arm/sysbus-fdt.c b/hw/arm/sysbus-fdt.c
> index 087e788..a0adc50 100644
> --- a/hw/arm/sysbus-fdt.c
> +++ b/hw/arm/sysbus-fdt.c
> @@ -96,13 +96,13 @@ static int set_interrupts_fdt_node(char *nodename, SysBusDevice *sbdev,
>          irq_attr[3*i+2] = cpu_to_be32(((__u32 *) irq_prop->data)[3*i+2]);
>      }
>  
> -    ret = qemu_fdt_setprop(fdt, nodename, "interrupts",
> -            irq_attr, vbasedev->num_irqs*3*sizeof(uint32_t));
> +   ret = qemu_fdt_setprop(fdt, nodename, "interrupts",
> +                     irq_attr, vbasedev->num_irqs*3*sizeof(uint32_t));
delta may be removed
>  
>      g_free(irq_attr);
>      g_free(irq_prop);
>  
> -    return ret;
> +   return ret;
delta may be removed
>  }
>  
>  /**
> @@ -140,6 +140,54 @@ static int set_regions_fdt_node(char *nodename, SysBusDevice *sbdev,
>      return ret;
>  }
>  
may deserve a comment and/or pointer to
Documentation/devicetree/bindings/arm/primecell.txt; don't know whether
this is the reference doc, sorry.
> +static int set_arm_primecell_node(char *nodename, SysBusDevice *sbdev, void
> +        *opaque)
> +{
> +    PlatformBusFdtData *data = opaque;
> +    void *fdt = data->fdt;
> +    int ret;
> +    VFIOPlatformDevice *vdev = VFIO_PLATFORM_DEVICE(sbdev);
> +    VFIODevice *vbasedev = &vdev->vbasedev;
> +    struct vfio_dev_property *property;
> +
Wouldn't it make sense to handle the required compatible prop here?
> +    /* Optional properties */
> +    property = vfio_get_dev_property(vbasedev->fd, "interrupts",
> +            VFIO_DEV_PROPERTY_TYPE_U32);
> +    if (property != NULL) {
> +        ret = set_interrupts_fdt_node(nodename, sbdev, opaque);
> +        if (ret < 0) {
> +            error_report("could not set interrupts property of node %s",
> +                    nodename);
> +            goto fail;
in case of fail the property is not released.
> +        }
> +        g_free(property);
> +    }
> +
> +    property = vfio_get_dev_property(vbasedev->fd, "clock-names",
> +            VFIO_DEV_PROPERTY_TYPE_STRINGS);
> +    if (property != NULL) {
> +        /* If a clock is attached, we rely on apb-pclk */
> +        /* Check clock existence */
> +        ret = fdt_path_offset(fdt, "/apb-pclk");
> +
> +        if (ret < 0) {
> +            error_report("could not set clocks property of node %s", nodename);
> +            goto fail;
release property
> +        } else {
> +            qemu_fdt_setprop_cells(fdt, nodename, "clocks",
> +                    qemu_fdt_getprop_cell(fdt, "/apb-pclk", "phandle"));
> +            char clock_names[] = "apb_pclk";
> +            qemu_fdt_setprop(fdt, nodename, "clock-names", clock_names,
> +                    sizeof(clock_names));
> +        }
> +        g_free(property);
do you intend to support other optional properties?
> +    }
> +
> +    return 0;
> +
> +fail:
> +    return -1;
> +}
>  /**
>   * add_calxeda_midway_xgmac_fdt_node
>   *
> @@ -213,6 +261,8 @@ static int add_arm_pl330_fdt_node(SysBusDevice *sbdev, void *opaque)
>      VFIOPlatformDevice *vdev = VFIO_PLATFORM_DEVICE(sbdev);
>      VFIODevice *vbasedev = &vdev->vbasedev;
>      Object *obj = OBJECT(sbdev);
> +    struct vfio_dev_property *property;
> +    int propint;
>  
>      mmio_base = object_property_get_int(obj, "mmio[0]", NULL);
>  
> @@ -222,6 +272,13 @@ static int add_arm_pl330_fdt_node(SysBusDevice *sbdev, void *opaque)
>  
>      qemu_fdt_add_subnode(fdt, nodename);
>  
> +    ret = set_arm_primecell_node(nodename, sbdev, opaque);
> +    if (ret < 0) {
> +        error_report("could not set arm,primecell properties of node %s",
> +                nodename);
> +        goto fail;
> +    }
> +
>      /*
>       * Process compatible string to deal with multiple strings
>       * (; is replaced by \0)
> @@ -237,20 +294,6 @@ static int add_arm_pl330_fdt_node(SysBusDevice *sbdev, void *opaque)
>      qemu_fdt_setprop(fdt, nodename, "compatible",
>                            compat, compat_str_len);
>  
> -    /* Setup clocks for AMBA device */
> -    /* Check clock existence */
> -    ret = fdt_path_offset(fdt, "/apb-pclk");
> -
> -    if (ret < 0) {
> -        error_report("could not set clocks property of node %s", nodename);
> -    } else {
> -        qemu_fdt_setprop_cells(fdt, nodename, "clocks",
> -                qemu_fdt_getprop_cell(fdt, "/apb-pclk", "phandle"));
> -        char clock_names[] = "apb_pclk";
> -        qemu_fdt_setprop(fdt, nodename, "clock-names", clock_names,
> -                sizeof(clock_names));
> -    }
> -
>      ret = set_regions_fdt_node(nodename, sbdev, opaque);
>  
>      if (ret < 0) {
> @@ -266,6 +309,49 @@ static int add_arm_pl330_fdt_node(SysBusDevice *sbdev, void *opaque)
>          goto fail;
>      }
>  
> +    /* Optional properties */
> +    property = vfio_get_dev_property(vbasedev->fd, "#dma-cells",
> +            VFIO_DEV_PROPERTY_TYPE_U32);
> +    if (property != NULL) {
> +        propint = cpu_to_be32(((__u32 *) property->data)[0]);
> +        ret = qemu_fdt_setprop(fdt, nodename, "#dma-cells", &propint,
> +                sizeof(int));
> +        if (ret < 0) {
> +            error_report("could not set #dma-cells property of node %s",
> +                    nodename);
> +            goto fail;
property release
> +        }
> +        g_free(property);
> +    }
> +
> +    property = vfio_get_dev_property(vbasedev->fd, "#dma-channels",
> +            VFIO_DEV_PROPERTY_TYPE_U32);
> +    if (property != NULL) {
> +        propint = cpu_to_be32(((__u32 *) property->data)[0]);
> +        ret = qemu_fdt_setprop(fdt, nodename, "#dma-cells", &propint,
> +                sizeof(int));
> +        if (ret < 0) {
> +            error_report("could not set #dma-cells property of node %s",
> +                    nodename);
> +            goto fail;
> +        }
> +        g_free(property);
> +    }
> +
> +    property = vfio_get_dev_property(vbasedev->fd, "#dma-requests",
> +            VFIO_DEV_PROPERTY_TYPE_U32);
> +    if (property != NULL) {
> +        propint = cpu_to_be32(((__u32 *) property->data)[0]);
> +        ret = qemu_fdt_setprop(fdt, nodename, "#dma-cells", &propint,
> +                sizeof(int));
> +        if (ret < 0) {
> +            error_report("could not set #dma-cells property of node %s",
> +                    nodename);
> +            goto fail;
> +        }
> +        g_free(property);
> +    }
> +
>      g_free(nodename);
>  
>      return 0;
to me it looks a good and interesting illustration of the modality

Best Regards

Eric
> 

^ permalink raw reply	[flat|nested] 8+ messages in thread

end of thread, other threads:[~2015-01-15 16:18 UTC | newest]

Thread overview: 8+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2015-01-12 13:21 [Qemu-devel] [RFC PATCH 0/4] VFIO platform: Use device properties API Baptiste Reynal
2015-01-12 13:21 ` [Qemu-devel] [RFC PATCH 1/4] linux-headers update Baptiste Reynal
2015-01-12 13:21 ` [Qemu-devel] [RFC PATCH 2/4] hw/vfio/common.c : vfio_get_dev_property Baptiste Reynal
2015-01-12 15:36   ` Alex Williamson
2015-01-12 13:21 ` [Qemu-devel] [RFC PATCH 3/4] hw/arm/sysbus-fdt: vfio device property for interrupts Baptiste Reynal
2015-01-15 15:57   ` Eric Auger
2015-01-12 13:21 ` [Qemu-devel] [RFC PATCH 4/4] hw/arm/sysbus-fdt: arm, pl330 vfio device property Baptiste Reynal
2015-01-15 16:16   ` Eric Auger

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.