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

Signed-off-by: Antonios Motakis <a.mota...@virtualopensystems.com>
---
 drivers/vfio/platform/properties.c | 62 +++++++++++++++++++++++++++++++++++++-
 1 file changed, 61 insertions(+), 1 deletion(-)

diff --git a/drivers/vfio/platform/properties.c 
b/drivers/vfio/platform/properties.c
index 39c6342..645f6e5c 100644
--- a/drivers/vfio/platform/properties.c
+++ b/drivers/vfio/platform/properties.c
@@ -55,7 +55,67 @@ static int dev_property_get_uint(struct device *dev, char 
*name,
                                 uint32_t type, unsigned *lenp,
                                 void __user *datap, unsigned long datasz)
 {
-       return -EINVAL;
+       int ret, n;
+       u8 *out;
+       size_t sz;
+       int (*func)(const struct device *, const char *, void *, size_t)
+               = NULL;
+
+       switch (type) {
+       case VFIO_DEV_PROPERTY_TYPE_U64:
+               sz = sizeof(u64);
+               func = (int (*)(const struct device *,
+                               const char *, void *, size_t))
+                       device_property_read_u64_array;
+               break;
+       case VFIO_DEV_PROPERTY_TYPE_U32:
+               sz = sizeof(u32);
+               func = (int (*)(const struct device *,
+                               const char *, void *, size_t))
+                       device_property_read_u32_array;
+               break;
+       case VFIO_DEV_PROPERTY_TYPE_U16:
+               sz = sizeof(u16);
+               func = (int (*)(const struct device *,
+                               const char *, void *, size_t))
+                       device_property_read_u16_array;
+               break;
+       case VFIO_DEV_PROPERTY_TYPE_U8:
+               sz = sizeof(u8);
+               func = (int (*)(const struct device *,
+                               const char *, void *, size_t))
+                       device_property_read_u8_array;
+               break;
+
+       default:
+               return -EINVAL;
+       }
+
+       /* get size of array */
+       n = func(dev, name, NULL, 0);
+       if (n < 0)
+               return n;
+
+       if (lenp)
+               *lenp = n * sz;
+
+       if (n * sz > datasz)
+               return -EOVERFLOW;
+
+       out = kcalloc(n, sz, GFP_KERNEL);
+       if (!out)
+               return -EFAULT;
+
+       ret = func(dev, name, out, n);
+       if (ret)
+               goto out;
+
+       if (copy_to_user(datap, out, n * sz))
+               ret = -EFAULT;
+
+out:
+       kfree(out);
+       return ret;
 }
 
 int vfio_platform_dev_properties(struct device *dev,
-- 
2.1.3

--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/

Reply via email to