All of lore.kernel.org
 help / color / mirror / Atom feed
* [RFC 0/4] VFIO: PLATFORM: Return device tree info for a platform device node
@ 2014-08-13 11:02 Antonios Motakis
       [not found] ` <1407927740-14993-1-git-send-email-a.motakis-lrHrjnjw1UfHK3s98zE1ajGjJy/sRE9J@public.gmane.org>
  2014-08-19 20:27   ` Joel Schopp
  0 siblings, 2 replies; 13+ messages in thread
From: Antonios Motakis @ 2014-08-13 11:02 UTC (permalink / raw)
  To: alex.williamson-H+wXaHxf7aLQT0dZR+AlfA,
	kvmarm-FPEHb7Xf0XXUo1n7N8X6UoWGPAHP3yOg,
	iommu-cunTk1MwBs9QetFLy7KEm3xJsTq8ys+cHZ5vskTnxNA
  Cc: kvm-u79uwXL29TY76Z2rM5mHXA, eric.auger-QSEj5FYQhm4dnm+yROfE0A,
	marc.zyngier-5wv7dgnIgG8, will.deacon-5wv7dgnIgG8,
	a.rigo-lrHrjnjw1UfHK3s98zE1ajGjJy/sRE9J,
	stuart.yoder-KZfg59tc24xl57MIdRCFDg, Antonios Motakis,
	tech-lrHrjnjw1UfHK3s98zE1ajGjJy/sRE9J,
	christoffer.dall-QSEj5FYQhm4dnm+yROfE0A

This RFC's intention is to show what an interface to access device node
properties for VFIO_PLATFORM can look like.

If a device tree node corresponding to a platform device bound by VFIO_PLATFORM
is available, this patch series will allow the user to query the properties
associated with this device node. This can be useful for userspace drivers
to automatically query parameters related to the device.

An API to return data from a device's device tree has been proposed before on
these lists. The API proposed here is slightly different.

Properties to parse from the device tree are not indexed by a numerical id.
The host system doesn't guarantee any specific ordering for the available
properties, or that those will remain the same; while this does not happen in
practice, there is nothing from the host changing the device nodes during
operation. So properties are accessed by property name.

The type of the property accessed must also be known by the user. Properties
types implemented in this RFC:
- VFIO_DEVTREE_ARR_TYPE_STRING (strings sepparated by the null character)
- VFIO_DEVTREE_ARR_TYPE_U32
- VFIO_DEVTREE_ARR_TYPE_U16
- VFIO_DEVTREE_ARR_TYPE_U8

These can all be access by the ioctl VFIO_DEVICE_GET_DEVTREE_INFO. A new ioctl
was preferred instead of shoehorning the functionality in VFIO_DEVICE_GET_INFO.
The structure exchanged looks like this:

/**
 * VFIO_DEVICE_GET_DEVTREE_INFO - _IOR(VFIO_TYPE, VFIO_BASE + 16,
 *						struct vfio_devtree_info)
 *
 * Retrieve information from the device's 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 sepparated by the NULL terminating character.
 * Return: 0 on success, -errno on failure.
 */
struct vfio_devtree_info {
	__u32	argsz;
	__u32	type;
#define VFIO_DEVTREE_PROP_NAMES		0
#define VFIO_DEVTREE_ARR_TYPE_STRING	1
#define VFIO_DEVTREE_ARR_TYPE_U8	2
#define VFIO_DEVTREE_ARR_TYPE_U16	3
#define VFIO_DEVTREE_ARR_TYPE_U32	4
	__u32	length;
	__u8	data[];
};
#define VFIO_DEVICE_GET_DEVTREE_INFO	_IO(VFIO_TYPE, VFIO_BASE + 17)

The length of the property will be reported in length, so the user can reallocate
the structure if the data does not fit the first time the call is used.

Specifically for QEMU, reading the "compatible" property of the device tree
node coul be of use to find out what device is being assigned to the guest and
handle appropriately a wider range of devices in the future, and to generate an
appropriate device tree for the guest.

Antonios Motakis (4):
  VFIO: PLATFORM: Add device tree info API and skeleton
  VFIO: PLATFORM: DEVTREE: Return available property names
  VFIO: PLATFORM: DEVTREE: Access property as a list of strings
  VFIO: PLATFORM: DEVTREE: Return arrays of u32, u16, or u8

 drivers/vfio/platform/Makefile                |   2 +-
 drivers/vfio/platform/devtree.c               | 252 ++++++++++++++++++++++++++
 drivers/vfio/platform/vfio_platform.c         |  11 ++
 drivers/vfio/platform/vfio_platform_private.h |   7 +
 include/uapi/linux/vfio.h                     |  32 +++-
 5 files changed, 300 insertions(+), 4 deletions(-)
 create mode 100644 drivers/vfio/platform/devtree.c

-- 
1.8.3.2

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

* [PATCH 1/4] VFIO: PLATFORM: Add device tree info API and skeleton
       [not found] ` <1407927740-14993-1-git-send-email-a.motakis-lrHrjnjw1UfHK3s98zE1ajGjJy/sRE9J@public.gmane.org>
  2014-08-13 11:02     ` Antonios Motakis
@ 2014-08-13 11:02     ` Antonios Motakis
  2014-08-13 11:02     ` Antonios Motakis
  2014-08-13 11:02     ` Antonios Motakis
  3 siblings, 0 replies; 13+ messages in thread
From: Antonios Motakis @ 2014-08-13 11:02 UTC (permalink / raw)
  To: alex.williamson-H+wXaHxf7aLQT0dZR+AlfA,
	kvmarm-FPEHb7Xf0XXUo1n7N8X6UoWGPAHP3yOg,
	iommu-cunTk1MwBs9QetFLy7KEm3xJsTq8ys+cHZ5vskTnxNA
  Cc: tech-lrHrjnjw1UfHK3s98zE1ajGjJy/sRE9J,
	a.rigo-lrHrjnjw1UfHK3s98zE1ajGjJy/sRE9J,
	kvm-u79uwXL29TY76Z2rM5mHXA,
	christoffer.dall-QSEj5FYQhm4dnm+yROfE0A, will.deacon-5wv7dgnIgG8,
	kim.phillips-KZfg59tc24xl57MIdRCFDg,
	stuart.yoder-KZfg59tc24xl57MIdRCFDg,
	eric.auger-QSEj5FYQhm4dnm+yROfE0A, marc.zyngier-5wv7dgnIgG8,
	Antonios Motakis, Catalin Marinas, Mark Rutland, Vladimir Murzin,
	Rob Herring, Ashwin Chaugule, open list, open list:ABI/API

This patch introduced the API to return device tree info about
a PLATFORM device (if described by a device tree) and the skeleton
of the implementation for VFIO_PLATFORM. Information about any device
node bound by VFIO_PLATFORM should be queried via the introduced ioctl
VFIO_DEVICE_GET_DEVTREE_INFO.

Signed-off-by: Antonios Motakis <a.motakis-lrHrjnjw1UfHK3s98zE1ajGjJy/sRE9J@public.gmane.org>
---
 drivers/vfio/platform/Makefile                |  2 +-
 drivers/vfio/platform/devtree.c               | 27 ++++++++++++++++++++++
 drivers/vfio/platform/vfio_platform.c         | 11 +++++++++
 drivers/vfio/platform/vfio_platform_private.h |  7 ++++++
 include/uapi/linux/vfio.h                     | 32 ++++++++++++++++++++++++---
 5 files changed, 75 insertions(+), 4 deletions(-)
 create mode 100644 drivers/vfio/platform/devtree.c

diff --git a/drivers/vfio/platform/Makefile b/drivers/vfio/platform/Makefile
index 2c53327..4313fd7 100644
--- a/drivers/vfio/platform/Makefile
+++ b/drivers/vfio/platform/Makefile
@@ -1,4 +1,4 @@
 
-vfio-platform-y := vfio_platform.o vfio_platform_irq.o
+vfio-platform-y := vfio_platform.o vfio_platform_irq.o devtree.o
 
 obj-$(CONFIG_VFIO_PLATFORM) += vfio-platform.o
diff --git a/drivers/vfio/platform/devtree.c b/drivers/vfio/platform/devtree.c
new file mode 100644
index 0000000..91cab88
--- /dev/null
+++ b/drivers/vfio/platform/devtree.c
@@ -0,0 +1,27 @@
+#include <linux/slab.h>
+#include <linux/vfio.h>
+#include <linux/of.h>
+#include <linux/platform_device.h>
+#include "vfio_platform_private.h"
+
+void vfio_platform_devtree_get(struct vfio_platform_device *vdev)
+{
+	vdev->of_node = of_node_get(vdev->pdev->dev.of_node);
+}
+
+void vfio_platform_devtree_put(struct vfio_platform_device *vdev)
+{
+	of_node_put(vdev->of_node);
+	vdev->of_node = NULL;
+}
+
+bool vfio_platform_has_devtree(struct vfio_platform_device *vdev)
+{
+	return !!vdev->of_node;
+}
+
+long vfio_platform_devtree_ioctl(struct vfio_platform_device *vdev,
+				 unsigned long arg)
+{
+	return -EINVAL; /* not implemented yet */
+}
diff --git a/drivers/vfio/platform/vfio_platform.c b/drivers/vfio/platform/vfio_platform.c
index f4c06c6..e6fe05a 100644
--- a/drivers/vfio/platform/vfio_platform.c
+++ b/drivers/vfio/platform/vfio_platform.c
@@ -26,6 +26,7 @@
 #include <linux/vfio.h>
 #include <linux/io.h>
 #include <linux/platform_device.h>
+#include <linux/of.h>
 #include <linux/irq.h>
 
 #include "vfio_platform_private.h"
@@ -66,6 +67,9 @@ static int vfio_platform_regions_init(struct vfio_platform_device *vdev)
 
 	vdev->num_regions = cnt;
 
+	/* get device tree node for info if available */
+	vfio_platform_devtree_get(vdev);
+
 	return 0;
 err:
 	kfree(vdev->region);
@@ -74,6 +78,7 @@ err:
 
 static void vfio_platform_regions_cleanup(struct vfio_platform_device *vdev)
 {
+	vfio_platform_devtree_put(vdev);
 	vdev->num_regions = 0;
 	kfree(vdev->region);
 }
@@ -132,6 +137,9 @@ static long vfio_platform_ioctl(void *device_data,
 			return -EINVAL;
 
 		info.flags = VFIO_DEVICE_FLAGS_PLATFORM;
+		if (vfio_platform_has_devtree(vdev))
+			info.flags |= VFIO_DEVICE_FLAGS_DEVTREE;
+
 		info.num_regions = vdev->num_regions;
 		info.num_irqs = vdev->num_irqs;
 
@@ -210,6 +218,9 @@ static long vfio_platform_ioctl(void *device_data,
 
 		return ret;
 
+	} else if (cmd == VFIO_DEVICE_GET_DEVTREE_INFO) {
+		return vfio_platform_devtree_ioctl(vdev, arg);
+
 	} else if (cmd == VFIO_DEVICE_RESET)
 		return -EINVAL;
 
diff --git a/drivers/vfio/platform/vfio_platform_private.h b/drivers/vfio/platform/vfio_platform_private.h
index 86a9201..1c42ba0 100644
--- a/drivers/vfio/platform/vfio_platform_private.h
+++ b/drivers/vfio/platform/vfio_platform_private.h
@@ -49,6 +49,7 @@ struct vfio_platform_device {
 	u32				num_regions;
 	struct vfio_platform_irq	*irq;
 	u32				num_irqs;
+	struct device_node		*of_node;
 };
 
 extern int vfio_platform_irq_init(struct vfio_platform_device *vdev);
@@ -59,4 +60,10 @@ extern int vfio_platform_set_irqs_ioctl(struct vfio_platform_device *vdev,
 			uint32_t flags, unsigned index, unsigned start,
 			unsigned count, void *data);
 
+/* device tree info support in devtree.c */
+extern void vfio_platform_devtree_get(struct vfio_platform_device *vdev);
+extern void vfio_platform_devtree_put(struct vfio_platform_device *vdev);
+extern bool vfio_platform_has_devtree(struct vfio_platform_device *vdev);
+extern long vfio_platform_devtree_ioctl(struct vfio_platform_device *vdev,
+					unsigned long arg);
 #endif /* VFIO_PLATFORM_PRIVATE_H */
diff --git a/include/uapi/linux/vfio.h b/include/uapi/linux/vfio.h
index d381107..60f66ec 100644
--- a/include/uapi/linux/vfio.h
+++ b/include/uapi/linux/vfio.h
@@ -153,15 +153,41 @@ struct vfio_group_status {
 struct vfio_device_info {
 	__u32	argsz;
 	__u32	flags;
-#define VFIO_DEVICE_FLAGS_RESET	(1 << 0)	/* Device supports reset */
-#define VFIO_DEVICE_FLAGS_PCI	(1 << 1)	/* vfio-pci device */
-#define VFIO_DEVICE_FLAGS_PLATFORM (1 << 2)	/* vfio-platform device */
+#define VFIO_DEVICE_FLAGS_RESET		(1 << 0) /* Device supports reset */
+#define VFIO_DEVICE_FLAGS_PCI		(1 << 1) /* vfio-pci device */
+#define VFIO_DEVICE_FLAGS_PLATFORM	(1 << 2) /* vfio-platform device */
+#define VFIO_DEVICE_FLAGS_DEVTREE	(1 << 3) /* device tree metadata */
 	__u32	num_regions;	/* Max region index + 1 */
 	__u32	num_irqs;	/* Max IRQ index + 1 */
 };
 #define VFIO_DEVICE_GET_INFO		_IO(VFIO_TYPE, VFIO_BASE + 7)
 
 /**
+ * VFIO_DEVICE_GET_DEVTREE_INFO - _IOR(VFIO_TYPE, VFIO_BASE + 16,
+ *						struct vfio_devtree_info)
+ *
+ * Retrieve information from the device's 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 sepparated by the NULL terminating character.
+ * Return: 0 on success, -errno on failure.
+ */
+struct vfio_devtree_info {
+	__u32	argsz;
+	__u32	type;
+#define VFIO_DEVTREE_PROP_NAMES		0
+#define VFIO_DEVTREE_ARR_TYPE_STRING	1
+#define VFIO_DEVTREE_ARR_TYPE_U8	2
+#define VFIO_DEVTREE_ARR_TYPE_U16	3
+#define VFIO_DEVTREE_ARR_TYPE_U32	4
+	__u32	length;
+	__u8	data[];
+};
+#define VFIO_DEVICE_GET_DEVTREE_INFO	_IO(VFIO_TYPE, VFIO_BASE + 17)
+
+/**
  * VFIO_DEVICE_GET_REGION_INFO - _IOWR(VFIO_TYPE, VFIO_BASE + 8,
  *				       struct vfio_region_info)
  *
-- 
1.8.3.2

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

* [PATCH 1/4] VFIO: PLATFORM: Add device tree info API and skeleton
@ 2014-08-13 11:02     ` Antonios Motakis
  0 siblings, 0 replies; 13+ messages in thread
From: Antonios Motakis @ 2014-08-13 11:02 UTC (permalink / raw)
  To: alex.williamson-H+wXaHxf7aLQT0dZR+AlfA,
	kvmarm-FPEHb7Xf0XXUo1n7N8X6UoWGPAHP3yOg,
	iommu-cunTk1MwBs9QetFLy7KEm3xJsTq8ys+cHZ5vskTnxNA
  Cc: tech-lrHrjnjw1UfHK3s98zE1ajGjJy/sRE9J,
	a.rigo-lrHrjnjw1UfHK3s98zE1ajGjJy/sRE9J,
	kvm-u79uwXL29TY76Z2rM5mHXA,
	christoffer.dall-QSEj5FYQhm4dnm+yROfE0A, will.deacon-5wv7dgnIgG8,
	kim.phillips-KZfg59tc24xl57MIdRCFDg,
	stuart.yoder-KZfg59tc24xl57MIdRCFDg,
	eric.auger-QSEj5FYQhm4dnm+yROfE0A, marc.zyngier-5wv7dgnIgG8,
	Antonios Motakis, Catalin Marinas, Mark Rutland, Vladimir Murzin,
	Rob Herring, Ashwin Chaugule, open list, open list:ABI/API

This patch introduced the API to return device tree info about
a PLATFORM device (if described by a device tree) and the skeleton
of the implementation for VFIO_PLATFORM. Information about any device
node bound by VFIO_PLATFORM should be queried via the introduced ioctl
VFIO_DEVICE_GET_DEVTREE_INFO.

Signed-off-by: Antonios Motakis <a.motakis-lrHrjnjw1UfHK3s98zE1ajGjJy/sRE9J@public.gmane.org>
---
 drivers/vfio/platform/Makefile                |  2 +-
 drivers/vfio/platform/devtree.c               | 27 ++++++++++++++++++++++
 drivers/vfio/platform/vfio_platform.c         | 11 +++++++++
 drivers/vfio/platform/vfio_platform_private.h |  7 ++++++
 include/uapi/linux/vfio.h                     | 32 ++++++++++++++++++++++++---
 5 files changed, 75 insertions(+), 4 deletions(-)
 create mode 100644 drivers/vfio/platform/devtree.c

diff --git a/drivers/vfio/platform/Makefile b/drivers/vfio/platform/Makefile
index 2c53327..4313fd7 100644
--- a/drivers/vfio/platform/Makefile
+++ b/drivers/vfio/platform/Makefile
@@ -1,4 +1,4 @@
 
-vfio-platform-y := vfio_platform.o vfio_platform_irq.o
+vfio-platform-y := vfio_platform.o vfio_platform_irq.o devtree.o
 
 obj-$(CONFIG_VFIO_PLATFORM) += vfio-platform.o
diff --git a/drivers/vfio/platform/devtree.c b/drivers/vfio/platform/devtree.c
new file mode 100644
index 0000000..91cab88
--- /dev/null
+++ b/drivers/vfio/platform/devtree.c
@@ -0,0 +1,27 @@
+#include <linux/slab.h>
+#include <linux/vfio.h>
+#include <linux/of.h>
+#include <linux/platform_device.h>
+#include "vfio_platform_private.h"
+
+void vfio_platform_devtree_get(struct vfio_platform_device *vdev)
+{
+	vdev->of_node = of_node_get(vdev->pdev->dev.of_node);
+}
+
+void vfio_platform_devtree_put(struct vfio_platform_device *vdev)
+{
+	of_node_put(vdev->of_node);
+	vdev->of_node = NULL;
+}
+
+bool vfio_platform_has_devtree(struct vfio_platform_device *vdev)
+{
+	return !!vdev->of_node;
+}
+
+long vfio_platform_devtree_ioctl(struct vfio_platform_device *vdev,
+				 unsigned long arg)
+{
+	return -EINVAL; /* not implemented yet */
+}
diff --git a/drivers/vfio/platform/vfio_platform.c b/drivers/vfio/platform/vfio_platform.c
index f4c06c6..e6fe05a 100644
--- a/drivers/vfio/platform/vfio_platform.c
+++ b/drivers/vfio/platform/vfio_platform.c
@@ -26,6 +26,7 @@
 #include <linux/vfio.h>
 #include <linux/io.h>
 #include <linux/platform_device.h>
+#include <linux/of.h>
 #include <linux/irq.h>
 
 #include "vfio_platform_private.h"
@@ -66,6 +67,9 @@ static int vfio_platform_regions_init(struct vfio_platform_device *vdev)
 
 	vdev->num_regions = cnt;
 
+	/* get device tree node for info if available */
+	vfio_platform_devtree_get(vdev);
+
 	return 0;
 err:
 	kfree(vdev->region);
@@ -74,6 +78,7 @@ err:
 
 static void vfio_platform_regions_cleanup(struct vfio_platform_device *vdev)
 {
+	vfio_platform_devtree_put(vdev);
 	vdev->num_regions = 0;
 	kfree(vdev->region);
 }
@@ -132,6 +137,9 @@ static long vfio_platform_ioctl(void *device_data,
 			return -EINVAL;
 
 		info.flags = VFIO_DEVICE_FLAGS_PLATFORM;
+		if (vfio_platform_has_devtree(vdev))
+			info.flags |= VFIO_DEVICE_FLAGS_DEVTREE;
+
 		info.num_regions = vdev->num_regions;
 		info.num_irqs = vdev->num_irqs;
 
@@ -210,6 +218,9 @@ static long vfio_platform_ioctl(void *device_data,
 
 		return ret;
 
+	} else if (cmd == VFIO_DEVICE_GET_DEVTREE_INFO) {
+		return vfio_platform_devtree_ioctl(vdev, arg);
+
 	} else if (cmd == VFIO_DEVICE_RESET)
 		return -EINVAL;
 
diff --git a/drivers/vfio/platform/vfio_platform_private.h b/drivers/vfio/platform/vfio_platform_private.h
index 86a9201..1c42ba0 100644
--- a/drivers/vfio/platform/vfio_platform_private.h
+++ b/drivers/vfio/platform/vfio_platform_private.h
@@ -49,6 +49,7 @@ struct vfio_platform_device {
 	u32				num_regions;
 	struct vfio_platform_irq	*irq;
 	u32				num_irqs;
+	struct device_node		*of_node;
 };
 
 extern int vfio_platform_irq_init(struct vfio_platform_device *vdev);
@@ -59,4 +60,10 @@ extern int vfio_platform_set_irqs_ioctl(struct vfio_platform_device *vdev,
 			uint32_t flags, unsigned index, unsigned start,
 			unsigned count, void *data);
 
+/* device tree info support in devtree.c */
+extern void vfio_platform_devtree_get(struct vfio_platform_device *vdev);
+extern void vfio_platform_devtree_put(struct vfio_platform_device *vdev);
+extern bool vfio_platform_has_devtree(struct vfio_platform_device *vdev);
+extern long vfio_platform_devtree_ioctl(struct vfio_platform_device *vdev,
+					unsigned long arg);
 #endif /* VFIO_PLATFORM_PRIVATE_H */
diff --git a/include/uapi/linux/vfio.h b/include/uapi/linux/vfio.h
index d381107..60f66ec 100644
--- a/include/uapi/linux/vfio.h
+++ b/include/uapi/linux/vfio.h
@@ -153,15 +153,41 @@ struct vfio_group_status {
 struct vfio_device_info {
 	__u32	argsz;
 	__u32	flags;
-#define VFIO_DEVICE_FLAGS_RESET	(1 << 0)	/* Device supports reset */
-#define VFIO_DEVICE_FLAGS_PCI	(1 << 1)	/* vfio-pci device */
-#define VFIO_DEVICE_FLAGS_PLATFORM (1 << 2)	/* vfio-platform device */
+#define VFIO_DEVICE_FLAGS_RESET		(1 << 0) /* Device supports reset */
+#define VFIO_DEVICE_FLAGS_PCI		(1 << 1) /* vfio-pci device */
+#define VFIO_DEVICE_FLAGS_PLATFORM	(1 << 2) /* vfio-platform device */
+#define VFIO_DEVICE_FLAGS_DEVTREE	(1 << 3) /* device tree metadata */
 	__u32	num_regions;	/* Max region index + 1 */
 	__u32	num_irqs;	/* Max IRQ index + 1 */
 };
 #define VFIO_DEVICE_GET_INFO		_IO(VFIO_TYPE, VFIO_BASE + 7)
 
 /**
+ * VFIO_DEVICE_GET_DEVTREE_INFO - _IOR(VFIO_TYPE, VFIO_BASE + 16,
+ *						struct vfio_devtree_info)
+ *
+ * Retrieve information from the device's 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 sepparated by the NULL terminating character.
+ * Return: 0 on success, -errno on failure.
+ */
+struct vfio_devtree_info {
+	__u32	argsz;
+	__u32	type;
+#define VFIO_DEVTREE_PROP_NAMES		0
+#define VFIO_DEVTREE_ARR_TYPE_STRING	1
+#define VFIO_DEVTREE_ARR_TYPE_U8	2
+#define VFIO_DEVTREE_ARR_TYPE_U16	3
+#define VFIO_DEVTREE_ARR_TYPE_U32	4
+	__u32	length;
+	__u8	data[];
+};
+#define VFIO_DEVICE_GET_DEVTREE_INFO	_IO(VFIO_TYPE, VFIO_BASE + 17)
+
+/**
  * VFIO_DEVICE_GET_REGION_INFO - _IOWR(VFIO_TYPE, VFIO_BASE + 8,
  *				       struct vfio_region_info)
  *
-- 
1.8.3.2

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

* [PATCH 1/4] VFIO: PLATFORM: Add device tree info API and skeleton
@ 2014-08-13 11:02     ` Antonios Motakis
  0 siblings, 0 replies; 13+ messages in thread
From: Antonios Motakis @ 2014-08-13 11:02 UTC (permalink / raw)
  To: alex.williamson, kvmarm, iommu
  Cc: tech, a.rigo, kvm, christoffer.dall, will.deacon, kim.phillips,
	stuart.yoder, eric.auger, marc.zyngier, Antonios Motakis,
	Catalin Marinas, Mark Rutland, Vladimir Murzin, Rob Herring,
	Ashwin Chaugule, open list, open list:ABI/API

This patch introduced the API to return device tree info about
a PLATFORM device (if described by a device tree) and the skeleton
of the implementation for VFIO_PLATFORM. Information about any device
node bound by VFIO_PLATFORM should be queried via the introduced ioctl
VFIO_DEVICE_GET_DEVTREE_INFO.

Signed-off-by: Antonios Motakis <a.motakis@virtualopensystems.com>
---
 drivers/vfio/platform/Makefile                |  2 +-
 drivers/vfio/platform/devtree.c               | 27 ++++++++++++++++++++++
 drivers/vfio/platform/vfio_platform.c         | 11 +++++++++
 drivers/vfio/platform/vfio_platform_private.h |  7 ++++++
 include/uapi/linux/vfio.h                     | 32 ++++++++++++++++++++++++---
 5 files changed, 75 insertions(+), 4 deletions(-)
 create mode 100644 drivers/vfio/platform/devtree.c

diff --git a/drivers/vfio/platform/Makefile b/drivers/vfio/platform/Makefile
index 2c53327..4313fd7 100644
--- a/drivers/vfio/platform/Makefile
+++ b/drivers/vfio/platform/Makefile
@@ -1,4 +1,4 @@
 
-vfio-platform-y := vfio_platform.o vfio_platform_irq.o
+vfio-platform-y := vfio_platform.o vfio_platform_irq.o devtree.o
 
 obj-$(CONFIG_VFIO_PLATFORM) += vfio-platform.o
diff --git a/drivers/vfio/platform/devtree.c b/drivers/vfio/platform/devtree.c
new file mode 100644
index 0000000..91cab88
--- /dev/null
+++ b/drivers/vfio/platform/devtree.c
@@ -0,0 +1,27 @@
+#include <linux/slab.h>
+#include <linux/vfio.h>
+#include <linux/of.h>
+#include <linux/platform_device.h>
+#include "vfio_platform_private.h"
+
+void vfio_platform_devtree_get(struct vfio_platform_device *vdev)
+{
+	vdev->of_node = of_node_get(vdev->pdev->dev.of_node);
+}
+
+void vfio_platform_devtree_put(struct vfio_platform_device *vdev)
+{
+	of_node_put(vdev->of_node);
+	vdev->of_node = NULL;
+}
+
+bool vfio_platform_has_devtree(struct vfio_platform_device *vdev)
+{
+	return !!vdev->of_node;
+}
+
+long vfio_platform_devtree_ioctl(struct vfio_platform_device *vdev,
+				 unsigned long arg)
+{
+	return -EINVAL; /* not implemented yet */
+}
diff --git a/drivers/vfio/platform/vfio_platform.c b/drivers/vfio/platform/vfio_platform.c
index f4c06c6..e6fe05a 100644
--- a/drivers/vfio/platform/vfio_platform.c
+++ b/drivers/vfio/platform/vfio_platform.c
@@ -26,6 +26,7 @@
 #include <linux/vfio.h>
 #include <linux/io.h>
 #include <linux/platform_device.h>
+#include <linux/of.h>
 #include <linux/irq.h>
 
 #include "vfio_platform_private.h"
@@ -66,6 +67,9 @@ static int vfio_platform_regions_init(struct vfio_platform_device *vdev)
 
 	vdev->num_regions = cnt;
 
+	/* get device tree node for info if available */
+	vfio_platform_devtree_get(vdev);
+
 	return 0;
 err:
 	kfree(vdev->region);
@@ -74,6 +78,7 @@ err:
 
 static void vfio_platform_regions_cleanup(struct vfio_platform_device *vdev)
 {
+	vfio_platform_devtree_put(vdev);
 	vdev->num_regions = 0;
 	kfree(vdev->region);
 }
@@ -132,6 +137,9 @@ static long vfio_platform_ioctl(void *device_data,
 			return -EINVAL;
 
 		info.flags = VFIO_DEVICE_FLAGS_PLATFORM;
+		if (vfio_platform_has_devtree(vdev))
+			info.flags |= VFIO_DEVICE_FLAGS_DEVTREE;
+
 		info.num_regions = vdev->num_regions;
 		info.num_irqs = vdev->num_irqs;
 
@@ -210,6 +218,9 @@ static long vfio_platform_ioctl(void *device_data,
 
 		return ret;
 
+	} else if (cmd == VFIO_DEVICE_GET_DEVTREE_INFO) {
+		return vfio_platform_devtree_ioctl(vdev, arg);
+
 	} else if (cmd == VFIO_DEVICE_RESET)
 		return -EINVAL;
 
diff --git a/drivers/vfio/platform/vfio_platform_private.h b/drivers/vfio/platform/vfio_platform_private.h
index 86a9201..1c42ba0 100644
--- a/drivers/vfio/platform/vfio_platform_private.h
+++ b/drivers/vfio/platform/vfio_platform_private.h
@@ -49,6 +49,7 @@ struct vfio_platform_device {
 	u32				num_regions;
 	struct vfio_platform_irq	*irq;
 	u32				num_irqs;
+	struct device_node		*of_node;
 };
 
 extern int vfio_platform_irq_init(struct vfio_platform_device *vdev);
@@ -59,4 +60,10 @@ extern int vfio_platform_set_irqs_ioctl(struct vfio_platform_device *vdev,
 			uint32_t flags, unsigned index, unsigned start,
 			unsigned count, void *data);
 
+/* device tree info support in devtree.c */
+extern void vfio_platform_devtree_get(struct vfio_platform_device *vdev);
+extern void vfio_platform_devtree_put(struct vfio_platform_device *vdev);
+extern bool vfio_platform_has_devtree(struct vfio_platform_device *vdev);
+extern long vfio_platform_devtree_ioctl(struct vfio_platform_device *vdev,
+					unsigned long arg);
 #endif /* VFIO_PLATFORM_PRIVATE_H */
diff --git a/include/uapi/linux/vfio.h b/include/uapi/linux/vfio.h
index d381107..60f66ec 100644
--- a/include/uapi/linux/vfio.h
+++ b/include/uapi/linux/vfio.h
@@ -153,15 +153,41 @@ struct vfio_group_status {
 struct vfio_device_info {
 	__u32	argsz;
 	__u32	flags;
-#define VFIO_DEVICE_FLAGS_RESET	(1 << 0)	/* Device supports reset */
-#define VFIO_DEVICE_FLAGS_PCI	(1 << 1)	/* vfio-pci device */
-#define VFIO_DEVICE_FLAGS_PLATFORM (1 << 2)	/* vfio-platform device */
+#define VFIO_DEVICE_FLAGS_RESET		(1 << 0) /* Device supports reset */
+#define VFIO_DEVICE_FLAGS_PCI		(1 << 1) /* vfio-pci device */
+#define VFIO_DEVICE_FLAGS_PLATFORM	(1 << 2) /* vfio-platform device */
+#define VFIO_DEVICE_FLAGS_DEVTREE	(1 << 3) /* device tree metadata */
 	__u32	num_regions;	/* Max region index + 1 */
 	__u32	num_irqs;	/* Max IRQ index + 1 */
 };
 #define VFIO_DEVICE_GET_INFO		_IO(VFIO_TYPE, VFIO_BASE + 7)
 
 /**
+ * VFIO_DEVICE_GET_DEVTREE_INFO - _IOR(VFIO_TYPE, VFIO_BASE + 16,
+ *						struct vfio_devtree_info)
+ *
+ * Retrieve information from the device's 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 sepparated by the NULL terminating character.
+ * Return: 0 on success, -errno on failure.
+ */
+struct vfio_devtree_info {
+	__u32	argsz;
+	__u32	type;
+#define VFIO_DEVTREE_PROP_NAMES		0
+#define VFIO_DEVTREE_ARR_TYPE_STRING	1
+#define VFIO_DEVTREE_ARR_TYPE_U8	2
+#define VFIO_DEVTREE_ARR_TYPE_U16	3
+#define VFIO_DEVTREE_ARR_TYPE_U32	4
+	__u32	length;
+	__u8	data[];
+};
+#define VFIO_DEVICE_GET_DEVTREE_INFO	_IO(VFIO_TYPE, VFIO_BASE + 17)
+
+/**
  * VFIO_DEVICE_GET_REGION_INFO - _IOWR(VFIO_TYPE, VFIO_BASE + 8,
  *				       struct vfio_region_info)
  *
-- 
1.8.3.2


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

* [PATCH 2/4] VFIO: PLATFORM: DEVTREE: Return available property names
  2014-08-13 11:02 [RFC 0/4] VFIO: PLATFORM: Return device tree info for a platform device node Antonios Motakis
@ 2014-08-13 11:02     ` Antonios Motakis
  2014-08-19 20:27   ` Joel Schopp
  1 sibling, 0 replies; 13+ messages in thread
From: Antonios Motakis @ 2014-08-13 11:02 UTC (permalink / raw)
  To: alex.williamson-H+wXaHxf7aLQT0dZR+AlfA,
	kvmarm-FPEHb7Xf0XXUo1n7N8X6UoWGPAHP3yOg,
	iommu-cunTk1MwBs9QetFLy7KEm3xJsTq8ys+cHZ5vskTnxNA
  Cc: kvm-u79uwXL29TY76Z2rM5mHXA, eric.auger-QSEj5FYQhm4dnm+yROfE0A,
	marc.zyngier-5wv7dgnIgG8, open list, will.deacon-5wv7dgnIgG8,
	a.rigo-lrHrjnjw1UfHK3s98zE1ajGjJy/sRE9J,
	stuart.yoder-KZfg59tc24xl57MIdRCFDg, Antonios Motakis,
	tech-lrHrjnjw1UfHK3s98zE1ajGjJy/sRE9J,
	christoffer.dall-QSEj5FYQhm4dnm+yROfE0A

For various reasons, the available properties of the platform device
node in the device tree node should be referred to by the property name.
Passing type = VFIO_DEVTREE_PROP_NAMES to VFIO_DEVICE_GET_DEVTREE_INFO,
returns a list of strings with the available properties that the VFIO
user can access.

Signed-off-by: Antonios Motakis <a.motakis-lrHrjnjw1UfHK3s98zE1ajGjJy/sRE9J@public.gmane.org>
---
 drivers/vfio/platform/devtree.c | 68 ++++++++++++++++++++++++++++++++++++++++-
 1 file changed, 67 insertions(+), 1 deletion(-)

diff --git a/drivers/vfio/platform/devtree.c b/drivers/vfio/platform/devtree.c
index 91cab88..b8fd4138 100644
--- a/drivers/vfio/platform/devtree.c
+++ b/drivers/vfio/platform/devtree.c
@@ -20,8 +20,74 @@ bool vfio_platform_has_devtree(struct vfio_platform_device *vdev)
 	return !!vdev->of_node;
 }
 
+static int devtree_get_prop_names(struct device_node *np, void __user *datap,
+				  unsigned long datasz, int *lenp)
+{
+	struct property *prop;
+	int len = 0, sz;
+	int ret = 0;
+
+	for_each_property_of_node(np, prop) {
+		sz = strlen(prop->name) + 1;
+
+		if (datasz < sz) {
+			ret = -EAGAIN;
+			break;
+		}
+
+		if (copy_to_user(datap, prop->name, sz))
+			return -EFAULT;
+
+		datap += sz;
+		datasz -= sz;
+		len += sz;
+	}
+
+	/* if overflow occurs, calculate remaining length */
+	while (prop) {
+		len += strlen(prop->name) + 1;
+		prop = prop->next;
+	}
+
+	/* we expose the full_name in addition to the usual properties */
+	len += sz = strlen("full_name") + 1;
+	if (datasz < sz) {
+		ret = -EAGAIN;
+	} else if (copy_to_user(datap, "full_name", sz))
+		return -EFAULT;
+
+	*lenp = len;
+
+	return ret;
+}
+
 long vfio_platform_devtree_ioctl(struct vfio_platform_device *vdev,
 				 unsigned long arg)
 {
-	return -EINVAL; /* not implemented yet */
+	struct vfio_devtree_info info;
+	unsigned long minsz = offsetofend(struct vfio_devtree_info, length);
+	void __user *datap = (void __user *) arg + minsz;
+	unsigned long int datasz;
+	int ret = -EINVAL;
+
+	if (!vfio_platform_has_devtree(vdev))
+		return -EINVAL;
+
+	if (copy_from_user(&info, (void __user *)arg, minsz))
+		return -EFAULT;
+
+	if (info.argsz < minsz)
+		return -EINVAL;
+
+	datasz = info.argsz - minsz;
+
+	if (info.type == VFIO_DEVTREE_PROP_NAMES) {
+		ret = devtree_get_prop_names(vdev->of_node, datap, datasz,
+								&info.length);
+	}
+
+	if (copy_to_user((void __user *)arg, &info, minsz))
+		ret = -EFAULT;
+
+	return ret;
 }
-- 
1.8.3.2

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

* [PATCH 2/4] VFIO: PLATFORM: DEVTREE: Return available property names
@ 2014-08-13 11:02     ` Antonios Motakis
  0 siblings, 0 replies; 13+ messages in thread
From: Antonios Motakis @ 2014-08-13 11:02 UTC (permalink / raw)
  To: alex.williamson, kvmarm, iommu
  Cc: tech, a.rigo, kvm, christoffer.dall, will.deacon, kim.phillips,
	stuart.yoder, eric.auger, marc.zyngier, Antonios Motakis,
	open list

For various reasons, the available properties of the platform device
node in the device tree node should be referred to by the property name.
Passing type = VFIO_DEVTREE_PROP_NAMES to VFIO_DEVICE_GET_DEVTREE_INFO,
returns a list of strings with the available properties that the VFIO
user can access.

Signed-off-by: Antonios Motakis <a.motakis@virtualopensystems.com>
---
 drivers/vfio/platform/devtree.c | 68 ++++++++++++++++++++++++++++++++++++++++-
 1 file changed, 67 insertions(+), 1 deletion(-)

diff --git a/drivers/vfio/platform/devtree.c b/drivers/vfio/platform/devtree.c
index 91cab88..b8fd4138 100644
--- a/drivers/vfio/platform/devtree.c
+++ b/drivers/vfio/platform/devtree.c
@@ -20,8 +20,74 @@ bool vfio_platform_has_devtree(struct vfio_platform_device *vdev)
 	return !!vdev->of_node;
 }
 
+static int devtree_get_prop_names(struct device_node *np, void __user *datap,
+				  unsigned long datasz, int *lenp)
+{
+	struct property *prop;
+	int len = 0, sz;
+	int ret = 0;
+
+	for_each_property_of_node(np, prop) {
+		sz = strlen(prop->name) + 1;
+
+		if (datasz < sz) {
+			ret = -EAGAIN;
+			break;
+		}
+
+		if (copy_to_user(datap, prop->name, sz))
+			return -EFAULT;
+
+		datap += sz;
+		datasz -= sz;
+		len += sz;
+	}
+
+	/* if overflow occurs, calculate remaining length */
+	while (prop) {
+		len += strlen(prop->name) + 1;
+		prop = prop->next;
+	}
+
+	/* we expose the full_name in addition to the usual properties */
+	len += sz = strlen("full_name") + 1;
+	if (datasz < sz) {
+		ret = -EAGAIN;
+	} else if (copy_to_user(datap, "full_name", sz))
+		return -EFAULT;
+
+	*lenp = len;
+
+	return ret;
+}
+
 long vfio_platform_devtree_ioctl(struct vfio_platform_device *vdev,
 				 unsigned long arg)
 {
-	return -EINVAL; /* not implemented yet */
+	struct vfio_devtree_info info;
+	unsigned long minsz = offsetofend(struct vfio_devtree_info, length);
+	void __user *datap = (void __user *) arg + minsz;
+	unsigned long int datasz;
+	int ret = -EINVAL;
+
+	if (!vfio_platform_has_devtree(vdev))
+		return -EINVAL;
+
+	if (copy_from_user(&info, (void __user *)arg, minsz))
+		return -EFAULT;
+
+	if (info.argsz < minsz)
+		return -EINVAL;
+
+	datasz = info.argsz - minsz;
+
+	if (info.type == VFIO_DEVTREE_PROP_NAMES) {
+		ret = devtree_get_prop_names(vdev->of_node, datap, datasz,
+								&info.length);
+	}
+
+	if (copy_to_user((void __user *)arg, &info, minsz))
+		ret = -EFAULT;
+
+	return ret;
 }
-- 
1.8.3.2


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

* [PATCH 3/4] VFIO: PLATFORM: DEVTREE: Access property as a list of strings
  2014-08-13 11:02 [RFC 0/4] VFIO: PLATFORM: Return device tree info for a platform device node Antonios Motakis
@ 2014-08-13 11:02     ` Antonios Motakis
  2014-08-19 20:27   ` Joel Schopp
  1 sibling, 0 replies; 13+ messages in thread
From: Antonios Motakis @ 2014-08-13 11:02 UTC (permalink / raw)
  To: alex.williamson-H+wXaHxf7aLQT0dZR+AlfA,
	kvmarm-FPEHb7Xf0XXUo1n7N8X6UoWGPAHP3yOg,
	iommu-cunTk1MwBs9QetFLy7KEm3xJsTq8ys+cHZ5vskTnxNA
  Cc: kvm-u79uwXL29TY76Z2rM5mHXA, eric.auger-QSEj5FYQhm4dnm+yROfE0A,
	marc.zyngier-5wv7dgnIgG8, open list, will.deacon-5wv7dgnIgG8,
	a.rigo-lrHrjnjw1UfHK3s98zE1ajGjJy/sRE9J,
	stuart.yoder-KZfg59tc24xl57MIdRCFDg, Antonios Motakis,
	tech-lrHrjnjw1UfHK3s98zE1ajGjJy/sRE9J,
	christoffer.dall-QSEj5FYQhm4dnm+yROfE0A

Certain device tree properties (e.g. the device node name, the compatible
string), are available as a list of strings (separated by the null
terminating character). Let the VFIO user query this type of properties.

Signed-off-by: Antonios Motakis <a.motakis-lrHrjnjw1UfHK3s98zE1ajGjJy/sRE9J@public.gmane.org>
---
 drivers/vfio/platform/devtree.c | 60 +++++++++++++++++++++++++++++++++++++++++
 1 file changed, 60 insertions(+)

diff --git a/drivers/vfio/platform/devtree.c b/drivers/vfio/platform/devtree.c
index b8fd4138..80c60d4 100644
--- a/drivers/vfio/platform/devtree.c
+++ b/drivers/vfio/platform/devtree.c
@@ -61,6 +61,43 @@ static int devtree_get_prop_names(struct device_node *np, void __user *datap,
 	return ret;
 }
 
+static int devtree_get_strings(struct device_node *np, char *name,
+			       void __user *datap, unsigned long datasz)
+{
+	struct property *prop;
+	int len;
+
+	prop = of_find_property(np, name, &len);
+
+	if (!prop)
+		return -EINVAL;
+
+	if (len > datasz)
+		return -EAGAIN;
+
+	if (copy_to_user(datap, prop->value, len))
+		return -EFAULT;
+	else
+		return 0;
+}
+
+static int devtree_get_full_name(struct device_node *np, void __user *datap,
+				 unsigned long datasz, int *lenp)
+{
+	int len = strlen(np->full_name) + 1;
+
+	if (lenp)
+		*lenp = len;
+
+	if (len > datasz)
+		return -EAGAIN;
+
+	if (copy_to_user(datap, np->full_name, len))
+		return -EFAULT;
+
+	return 0;
+}
+
 long vfio_platform_devtree_ioctl(struct vfio_platform_device *vdev,
 				 unsigned long arg)
 {
@@ -68,6 +105,7 @@ long vfio_platform_devtree_ioctl(struct vfio_platform_device *vdev,
 	unsigned long minsz = offsetofend(struct vfio_devtree_info, length);
 	void __user *datap = (void __user *) arg + minsz;
 	unsigned long int datasz;
+	char *name;
 	int ret = -EINVAL;
 
 	if (!vfio_platform_has_devtree(vdev))
@@ -84,8 +122,30 @@ long vfio_platform_devtree_ioctl(struct vfio_platform_device *vdev,
 	if (info.type == VFIO_DEVTREE_PROP_NAMES) {
 		ret = devtree_get_prop_names(vdev->of_node, datap, datasz,
 								&info.length);
+		goto out;
 	}
 
+	name = kzalloc(datasz, GFP_KERNEL);
+	if (!name)
+		return -ENOMEM;
+	if (copy_from_user(name, datap, datasz))
+		return -EFAULT;
+
+	if (!of_find_property(vdev->of_node, name, &info.length)) {
+		/* special case full_name as a property that is not on the fdt,
+		 * but we wish to return to the user as it includes the full
+		 * path of the device */
+		if (!strcmp(name, "full_name") &&
+				(info.type == VFIO_DEVTREE_ARR_TYPE_STRING))
+			ret = devtree_get_full_name(vdev->of_node, datap,
+						    datasz, &info.length);
+
+	} else if (info.type == VFIO_DEVTREE_ARR_TYPE_STRING)
+		ret = devtree_get_strings(vdev->of_node, name, datap, datasz);
+
+	kfree(name);
+
+out:
 	if (copy_to_user((void __user *)arg, &info, minsz))
 		ret = -EFAULT;
 
-- 
1.8.3.2

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

* [PATCH 3/4] VFIO: PLATFORM: DEVTREE: Access property as a list of strings
@ 2014-08-13 11:02     ` Antonios Motakis
  0 siblings, 0 replies; 13+ messages in thread
From: Antonios Motakis @ 2014-08-13 11:02 UTC (permalink / raw)
  To: alex.williamson, kvmarm, iommu
  Cc: tech, a.rigo, kvm, christoffer.dall, will.deacon, kim.phillips,
	stuart.yoder, eric.auger, marc.zyngier, Antonios Motakis,
	open list

Certain device tree properties (e.g. the device node name, the compatible
string), are available as a list of strings (separated by the null
terminating character). Let the VFIO user query this type of properties.

Signed-off-by: Antonios Motakis <a.motakis@virtualopensystems.com>
---
 drivers/vfio/platform/devtree.c | 60 +++++++++++++++++++++++++++++++++++++++++
 1 file changed, 60 insertions(+)

diff --git a/drivers/vfio/platform/devtree.c b/drivers/vfio/platform/devtree.c
index b8fd4138..80c60d4 100644
--- a/drivers/vfio/platform/devtree.c
+++ b/drivers/vfio/platform/devtree.c
@@ -61,6 +61,43 @@ static int devtree_get_prop_names(struct device_node *np, void __user *datap,
 	return ret;
 }
 
+static int devtree_get_strings(struct device_node *np, char *name,
+			       void __user *datap, unsigned long datasz)
+{
+	struct property *prop;
+	int len;
+
+	prop = of_find_property(np, name, &len);
+
+	if (!prop)
+		return -EINVAL;
+
+	if (len > datasz)
+		return -EAGAIN;
+
+	if (copy_to_user(datap, prop->value, len))
+		return -EFAULT;
+	else
+		return 0;
+}
+
+static int devtree_get_full_name(struct device_node *np, void __user *datap,
+				 unsigned long datasz, int *lenp)
+{
+	int len = strlen(np->full_name) + 1;
+
+	if (lenp)
+		*lenp = len;
+
+	if (len > datasz)
+		return -EAGAIN;
+
+	if (copy_to_user(datap, np->full_name, len))
+		return -EFAULT;
+
+	return 0;
+}
+
 long vfio_platform_devtree_ioctl(struct vfio_platform_device *vdev,
 				 unsigned long arg)
 {
@@ -68,6 +105,7 @@ long vfio_platform_devtree_ioctl(struct vfio_platform_device *vdev,
 	unsigned long minsz = offsetofend(struct vfio_devtree_info, length);
 	void __user *datap = (void __user *) arg + minsz;
 	unsigned long int datasz;
+	char *name;
 	int ret = -EINVAL;
 
 	if (!vfio_platform_has_devtree(vdev))
@@ -84,8 +122,30 @@ long vfio_platform_devtree_ioctl(struct vfio_platform_device *vdev,
 	if (info.type == VFIO_DEVTREE_PROP_NAMES) {
 		ret = devtree_get_prop_names(vdev->of_node, datap, datasz,
 								&info.length);
+		goto out;
 	}
 
+	name = kzalloc(datasz, GFP_KERNEL);
+	if (!name)
+		return -ENOMEM;
+	if (copy_from_user(name, datap, datasz))
+		return -EFAULT;
+
+	if (!of_find_property(vdev->of_node, name, &info.length)) {
+		/* special case full_name as a property that is not on the fdt,
+		 * but we wish to return to the user as it includes the full
+		 * path of the device */
+		if (!strcmp(name, "full_name") &&
+				(info.type == VFIO_DEVTREE_ARR_TYPE_STRING))
+			ret = devtree_get_full_name(vdev->of_node, datap,
+						    datasz, &info.length);
+
+	} else if (info.type == VFIO_DEVTREE_ARR_TYPE_STRING)
+		ret = devtree_get_strings(vdev->of_node, name, datap, datasz);
+
+	kfree(name);
+
+out:
 	if (copy_to_user((void __user *)arg, &info, minsz))
 		ret = -EFAULT;
 
-- 
1.8.3.2


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

* [PATCH 4/4] VFIO: PLATFORM: DEVTREE: Return arrays of u32, u16, or u8
  2014-08-13 11:02 [RFC 0/4] VFIO: PLATFORM: Return device tree info for a platform device node Antonios Motakis
@ 2014-08-13 11:02     ` Antonios Motakis
  2014-08-19 20:27   ` Joel Schopp
  1 sibling, 0 replies; 13+ messages in thread
From: Antonios Motakis @ 2014-08-13 11:02 UTC (permalink / raw)
  To: alex.williamson-H+wXaHxf7aLQT0dZR+AlfA,
	kvmarm-FPEHb7Xf0XXUo1n7N8X6UoWGPAHP3yOg,
	iommu-cunTk1MwBs9QetFLy7KEm3xJsTq8ys+cHZ5vskTnxNA
  Cc: kvm-u79uwXL29TY76Z2rM5mHXA, eric.auger-QSEj5FYQhm4dnm+yROfE0A,
	marc.zyngier-5wv7dgnIgG8, open list, will.deacon-5wv7dgnIgG8,
	a.rigo-lrHrjnjw1UfHK3s98zE1ajGjJy/sRE9J,
	stuart.yoder-KZfg59tc24xl57MIdRCFDg, Antonios Motakis,
	tech-lrHrjnjw1UfHK3s98zE1ajGjJy/sRE9J,
	christoffer.dall-QSEj5FYQhm4dnm+yROfE0A

Certain properties of a device tree node are accessible as an array
of unsigned integers, either u32, u16, or u8. Let the VFIO user query
this type of device node properties.

Signed-off-by: Antonios Motakis <a.motakis-lrHrjnjw1UfHK3s98zE1ajGjJy/sRE9J@public.gmane.org>
---
 drivers/vfio/platform/devtree.c | 99 +++++++++++++++++++++++++++++++++++++++++
 1 file changed, 99 insertions(+)

diff --git a/drivers/vfio/platform/devtree.c b/drivers/vfio/platform/devtree.c
index 80c60d4..331cc34 100644
--- a/drivers/vfio/platform/devtree.c
+++ b/drivers/vfio/platform/devtree.c
@@ -98,6 +98,96 @@ static int devtree_get_full_name(struct device_node *np, void __user *datap,
 	return 0;
 }
 
+static int devtree_get_u32_arr(const struct device_node *np, const char *name,
+			       void __user *datap, unsigned long datasz)
+{
+	int ret;
+	int n;
+	u32 *out;
+
+	n = of_property_count_elems_of_size(np, name, sizeof(u32));
+	if (n < 0)
+		return n;
+
+	if (n * sizeof(u32) > datasz)
+		return -EAGAIN;
+
+	out = kcalloc(n, sizeof(u32), GFP_KERNEL);
+	if (!out)
+		return -EFAULT;
+
+	ret = of_property_read_u32_array(np, name, out, n);
+	if (ret)
+		goto out;
+
+	if (copy_to_user(datap, out, n * sizeof(u32)))
+		ret = -EFAULT;
+
+out:
+	kfree(out);
+	return ret;
+}
+
+static int devtree_get_u16_arr(const struct device_node *np, const char *name,
+			       void __user *datap, unsigned long datasz)
+{
+	int ret;
+	int n;
+	u16 *out;
+
+	n = of_property_count_elems_of_size(np, name, sizeof(u16));
+	if (n < 0)
+		return n;
+
+	if (n * sizeof(u16) > datasz)
+		return -EAGAIN;
+
+	out = kcalloc(n, sizeof(u16), GFP_KERNEL);
+	if (!out)
+		return -EFAULT;
+
+	ret = of_property_read_u16_array(np, name, out, n);
+	if (ret)
+		goto out;
+
+	if (copy_to_user(datap, out, n * sizeof(u16)))
+		ret = -EFAULT;
+
+out:
+	kfree(out);
+	return ret;
+}
+
+static int devtree_get_u8_arr(const struct device_node *np, const char *name,
+			       void __user *datap, unsigned long datasz)
+{
+	int ret;
+	int n;
+	u8 *out;
+
+	n = of_property_count_elems_of_size(np, name, sizeof(u8));
+	if (n < 0)
+		return n;
+
+	if (n * sizeof(u8) > datasz)
+		return -EAGAIN;
+
+	out = kcalloc(n, sizeof(u8), GFP_KERNEL);
+	if (!out)
+		return -EFAULT;
+
+	ret = of_property_read_u8_array(np, name, out, n);
+	if (ret)
+		goto out;
+
+	if (copy_to_user(datap, out, n * sizeof(u8)))
+		ret = -EFAULT;
+
+out:
+	kfree(out);
+	return ret;
+}
+
 long vfio_platform_devtree_ioctl(struct vfio_platform_device *vdev,
 				 unsigned long arg)
 {
@@ -143,6 +233,15 @@ long vfio_platform_devtree_ioctl(struct vfio_platform_device *vdev,
 	} else if (info.type == VFIO_DEVTREE_ARR_TYPE_STRING)
 		ret = devtree_get_strings(vdev->of_node, name, datap, datasz);
 
+	else if (info.type == VFIO_DEVTREE_ARR_TYPE_U32)
+		ret = devtree_get_u32_arr(vdev->of_node, name, datap, datasz);
+
+	else if (info.type == VFIO_DEVTREE_ARR_TYPE_U16)
+		ret = devtree_get_u16_arr(vdev->of_node, name, datap, datasz);
+
+	else if (info.type == VFIO_DEVTREE_ARR_TYPE_U8)
+		ret = devtree_get_u8_arr(vdev->of_node, name, datap, datasz);
+
 	kfree(name);
 
 out:
-- 
1.8.3.2

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

* [PATCH 4/4] VFIO: PLATFORM: DEVTREE: Return arrays of u32, u16, or u8
@ 2014-08-13 11:02     ` Antonios Motakis
  0 siblings, 0 replies; 13+ messages in thread
From: Antonios Motakis @ 2014-08-13 11:02 UTC (permalink / raw)
  To: alex.williamson, kvmarm, iommu
  Cc: tech, a.rigo, kvm, christoffer.dall, will.deacon, kim.phillips,
	stuart.yoder, eric.auger, marc.zyngier, Antonios Motakis,
	open list

Certain properties of a device tree node are accessible as an array
of unsigned integers, either u32, u16, or u8. Let the VFIO user query
this type of device node properties.

Signed-off-by: Antonios Motakis <a.motakis@virtualopensystems.com>
---
 drivers/vfio/platform/devtree.c | 99 +++++++++++++++++++++++++++++++++++++++++
 1 file changed, 99 insertions(+)

diff --git a/drivers/vfio/platform/devtree.c b/drivers/vfio/platform/devtree.c
index 80c60d4..331cc34 100644
--- a/drivers/vfio/platform/devtree.c
+++ b/drivers/vfio/platform/devtree.c
@@ -98,6 +98,96 @@ static int devtree_get_full_name(struct device_node *np, void __user *datap,
 	return 0;
 }
 
+static int devtree_get_u32_arr(const struct device_node *np, const char *name,
+			       void __user *datap, unsigned long datasz)
+{
+	int ret;
+	int n;
+	u32 *out;
+
+	n = of_property_count_elems_of_size(np, name, sizeof(u32));
+	if (n < 0)
+		return n;
+
+	if (n * sizeof(u32) > datasz)
+		return -EAGAIN;
+
+	out = kcalloc(n, sizeof(u32), GFP_KERNEL);
+	if (!out)
+		return -EFAULT;
+
+	ret = of_property_read_u32_array(np, name, out, n);
+	if (ret)
+		goto out;
+
+	if (copy_to_user(datap, out, n * sizeof(u32)))
+		ret = -EFAULT;
+
+out:
+	kfree(out);
+	return ret;
+}
+
+static int devtree_get_u16_arr(const struct device_node *np, const char *name,
+			       void __user *datap, unsigned long datasz)
+{
+	int ret;
+	int n;
+	u16 *out;
+
+	n = of_property_count_elems_of_size(np, name, sizeof(u16));
+	if (n < 0)
+		return n;
+
+	if (n * sizeof(u16) > datasz)
+		return -EAGAIN;
+
+	out = kcalloc(n, sizeof(u16), GFP_KERNEL);
+	if (!out)
+		return -EFAULT;
+
+	ret = of_property_read_u16_array(np, name, out, n);
+	if (ret)
+		goto out;
+
+	if (copy_to_user(datap, out, n * sizeof(u16)))
+		ret = -EFAULT;
+
+out:
+	kfree(out);
+	return ret;
+}
+
+static int devtree_get_u8_arr(const struct device_node *np, const char *name,
+			       void __user *datap, unsigned long datasz)
+{
+	int ret;
+	int n;
+	u8 *out;
+
+	n = of_property_count_elems_of_size(np, name, sizeof(u8));
+	if (n < 0)
+		return n;
+
+	if (n * sizeof(u8) > datasz)
+		return -EAGAIN;
+
+	out = kcalloc(n, sizeof(u8), GFP_KERNEL);
+	if (!out)
+		return -EFAULT;
+
+	ret = of_property_read_u8_array(np, name, out, n);
+	if (ret)
+		goto out;
+
+	if (copy_to_user(datap, out, n * sizeof(u8)))
+		ret = -EFAULT;
+
+out:
+	kfree(out);
+	return ret;
+}
+
 long vfio_platform_devtree_ioctl(struct vfio_platform_device *vdev,
 				 unsigned long arg)
 {
@@ -143,6 +233,15 @@ long vfio_platform_devtree_ioctl(struct vfio_platform_device *vdev,
 	} else if (info.type == VFIO_DEVTREE_ARR_TYPE_STRING)
 		ret = devtree_get_strings(vdev->of_node, name, datap, datasz);
 
+	else if (info.type == VFIO_DEVTREE_ARR_TYPE_U32)
+		ret = devtree_get_u32_arr(vdev->of_node, name, datap, datasz);
+
+	else if (info.type == VFIO_DEVTREE_ARR_TYPE_U16)
+		ret = devtree_get_u16_arr(vdev->of_node, name, datap, datasz);
+
+	else if (info.type == VFIO_DEVTREE_ARR_TYPE_U8)
+		ret = devtree_get_u8_arr(vdev->of_node, name, datap, datasz);
+
 	kfree(name);
 
 out:
-- 
1.8.3.2


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

* Re: [RFC 0/4] VFIO: PLATFORM: Return device tree info for a platform device node
  2014-08-13 11:02 [RFC 0/4] VFIO: PLATFORM: Return device tree info for a platform device node Antonios Motakis
@ 2014-08-19 20:27   ` Joel Schopp
  2014-08-19 20:27   ` Joel Schopp
  1 sibling, 0 replies; 13+ messages in thread
From: Joel Schopp @ 2014-08-19 20:27 UTC (permalink / raw)
  To: Antonios Motakis, alex.williamson, kvmarm, iommu
  Cc: tech, a.rigo, kvm, christoffer.dall, will.deacon, kim.phillips,
	stuart.yoder, eric.auger, marc.zyngier


> This RFC's intention is to show what an interface to access device node
> properties for VFIO_PLATFORM can look like.
>
> If a device tree node corresponding to a platform device bound by VFIO_PLATFORM
> is available, this patch series will allow the user to query the properties
> associated with this device node. This can be useful for userspace drivers
> to automatically query parameters related to the device.
>
> An API to return data from a device's device tree has been proposed before on
> these lists. The API proposed here is slightly different.
>
> Properties to parse from the device tree are not indexed by a numerical id.
> The host system doesn't guarantee any specific ordering for the available
> properties, or that those will remain the same; while this does not happen in
> practice, there is nothing from the host changing the device nodes during
> operation. So properties are accessed by property name.
>
> The type of the property accessed must also be known by the user. Properties
> types implemented in this RFC:
> - VFIO_DEVTREE_ARR_TYPE_STRING (strings sepparated by the null character)
> - VFIO_DEVTREE_ARR_TYPE_U32
> - VFIO_DEVTREE_ARR_TYPE_U16
> - VFIO_DEVTREE_ARR_TYPE_U8
>
> These can all be access by the ioctl VFIO_DEVICE_GET_DEVTREE_INFO. A new ioctl
> was preferred instead of shoehorning the functionality in VFIO_DEVICE_GET_INFO.
> The structure exchanged looks like this:

You'll have to forgive my ignorance on the history.  But with the dtc
tool already supporting a filesystem representation (--in-format=fs),
with the dtc tool source already built into qemu, and having an example
implementation of such an interface in /proc/device-tree/ why is an
ioctl interface preferred over a filesystem interface? 


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

* Re: [RFC 0/4] VFIO: PLATFORM: Return device tree info for a platform device node
@ 2014-08-19 20:27   ` Joel Schopp
  0 siblings, 0 replies; 13+ messages in thread
From: Joel Schopp @ 2014-08-19 20:27 UTC (permalink / raw)
  To: Antonios Motakis, alex.williamson, kvmarm, iommu
  Cc: tech, a.rigo, kvm, christoffer.dall, will.deacon, kim.phillips,
	stuart.yoder, eric.auger, marc.zyngier


> This RFC's intention is to show what an interface to access device node
> properties for VFIO_PLATFORM can look like.
>
> If a device tree node corresponding to a platform device bound by VFIO_PLATFORM
> is available, this patch series will allow the user to query the properties
> associated with this device node. This can be useful for userspace drivers
> to automatically query parameters related to the device.
>
> An API to return data from a device's device tree has been proposed before on
> these lists. The API proposed here is slightly different.
>
> Properties to parse from the device tree are not indexed by a numerical id.
> The host system doesn't guarantee any specific ordering for the available
> properties, or that those will remain the same; while this does not happen in
> practice, there is nothing from the host changing the device nodes during
> operation. So properties are accessed by property name.
>
> The type of the property accessed must also be known by the user. Properties
> types implemented in this RFC:
> - VFIO_DEVTREE_ARR_TYPE_STRING (strings sepparated by the null character)
> - VFIO_DEVTREE_ARR_TYPE_U32
> - VFIO_DEVTREE_ARR_TYPE_U16
> - VFIO_DEVTREE_ARR_TYPE_U8
>
> These can all be access by the ioctl VFIO_DEVICE_GET_DEVTREE_INFO. A new ioctl
> was preferred instead of shoehorning the functionality in VFIO_DEVICE_GET_INFO.
> The structure exchanged looks like this:

You'll have to forgive my ignorance on the history.  But with the dtc
tool already supporting a filesystem representation (--in-format=fs),
with the dtc tool source already built into qemu, and having an example
implementation of such an interface in /proc/device-tree/ why is an
ioctl interface preferred over a filesystem interface? 


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

* Re: [RFC 0/4] VFIO: PLATFORM: Return device tree info for a platform device node
       [not found]   ` <53F3B32C.6080101-5C7GfCeVMHo@public.gmane.org>
@ 2014-08-21 12:19     ` Antonios Motakis
  0 siblings, 0 replies; 13+ messages in thread
From: Antonios Motakis @ 2014-08-21 12:19 UTC (permalink / raw)
  To: Joel Schopp
  Cc: Stuart Yoder, KVM devel mailing list, Eric Auger, Marc Zyngier,
	Will Deacon, Linux IOMMU, alvise rigo,
	VirtualOpenSystems Technical Team, kvm-arm, Christoffer Dall

On Tue, Aug 19, 2014 at 10:27 PM, Joel Schopp <joel.schopp-5C7GfCeVMHo@public.gmane.org> wrote:
>
>
> > This RFC's intention is to show what an interface to access device node
> > properties for VFIO_PLATFORM can look like.
> >
> > If a device tree node corresponding to a platform device bound by VFIO_PLATFORM
> > is available, this patch series will allow the user to query the properties
> > associated with this device node. This can be useful for userspace drivers
> > to automatically query parameters related to the device.
> >
> > An API to return data from a device's device tree has been proposed before on
> > these lists. The API proposed here is slightly different.
> >
> > Properties to parse from the device tree are not indexed by a numerical id.
> > The host system doesn't guarantee any specific ordering for the available
> > properties, or that those will remain the same; while this does not happen in
> > practice, there is nothing from the host changing the device nodes during
> > operation. So properties are accessed by property name.
> >
> > The type of the property accessed must also be known by the user. Properties
> > types implemented in this RFC:
> > - VFIO_DEVTREE_ARR_TYPE_STRING (strings sepparated by the null character)
> > - VFIO_DEVTREE_ARR_TYPE_U32
> > - VFIO_DEVTREE_ARR_TYPE_U16
> > - VFIO_DEVTREE_ARR_TYPE_U8
> >
> > These can all be access by the ioctl VFIO_DEVICE_GET_DEVTREE_INFO. A new ioctl
> > was preferred instead of shoehorning the functionality in VFIO_DEVICE_GET_INFO.
> > The structure exchanged looks like this:
>
> You'll have to forgive my ignorance on the history.  But with the dtc
> tool already supporting a filesystem representation (--in-format=fs),
> with the dtc tool source already built into qemu, and having an example
> implementation of such an interface in /proc/device-tree/ why is an
> ioctl interface preferred over a filesystem interface?
>

Hello Joel,

VFIO already exposes an ioctl interface, so from the side of VFIO I
think it wouldn't make sense to add another interface just for the
device node data of the target device. I don't think the existing
/proc interface would be appropriate to use since (1) you would have
to give to the VFIO user (e.g. QEMU) access to the whole hierarchy (2)
the VFIO user would have to implement logic to figure out which node
it needs to get data from.

One thing to keep in mind is that VFIO is not designed to be used only
by QEMU. Taking as an example a hypothetical user space driver for the
PL330 DMAC, I think it makes sense to be able to directly get from
VFIO the right values for #dma-cells, #dma-channels, #dma-requests,
etc.

Of course QEMU could let the user override any values via any format
QEMU supports, but IMHO out of the box it would make sense to use an
interface such as the proposed one.

-- 
Antonios Motakis
Virtual Open Systems

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

end of thread, other threads:[~2014-08-21 12:19 UTC | newest]

Thread overview: 13+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2014-08-13 11:02 [RFC 0/4] VFIO: PLATFORM: Return device tree info for a platform device node Antonios Motakis
     [not found] ` <1407927740-14993-1-git-send-email-a.motakis-lrHrjnjw1UfHK3s98zE1ajGjJy/sRE9J@public.gmane.org>
2014-08-13 11:02   ` [PATCH 1/4] VFIO: PLATFORM: Add device tree info API and skeleton Antonios Motakis
2014-08-13 11:02     ` Antonios Motakis
2014-08-13 11:02     ` Antonios Motakis
2014-08-13 11:02   ` [PATCH 2/4] VFIO: PLATFORM: DEVTREE: Return available property names Antonios Motakis
2014-08-13 11:02     ` Antonios Motakis
2014-08-13 11:02   ` [PATCH 3/4] VFIO: PLATFORM: DEVTREE: Access property as a list of strings Antonios Motakis
2014-08-13 11:02     ` Antonios Motakis
2014-08-13 11:02   ` [PATCH 4/4] VFIO: PLATFORM: DEVTREE: Return arrays of u32, u16, or u8 Antonios Motakis
2014-08-13 11:02     ` Antonios Motakis
2014-08-19 20:27 ` [RFC 0/4] VFIO: PLATFORM: Return device tree info for a platform device node Joel Schopp
2014-08-19 20:27   ` Joel Schopp
     [not found]   ` <53F3B32C.6080101-5C7GfCeVMHo@public.gmane.org>
2014-08-21 12:19     ` Antonios Motakis

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.