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@xxxxxxxxxxxxxxxxxxxxxx> --- 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 -- To unsubscribe from this list: send the line "unsubscribe kvm" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html