* [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, 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 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 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