On Wed, Sep 9, 2015 at 10:48 PM, Alex Williamson <[email protected] > wrote:
> On Wed, 2015-09-09 at 11:17 +0200, Baptiste Reynal wrote: > > From: Antonios Motakis <[email protected]> > > > > 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 <[email protected]> > > Signed-off-by: Baptiste Reynal <[email protected]> > > --- > > 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 8bf9c8f..625e2d3 100644 > > --- a/drivers/vfio/platform/properties.c > > +++ b/drivers/vfio/platform/properties.c > > @@ -70,7 +70,67 @@ static int dev_property_get_uint(struct device *dev, > uint32_t *flags, > > 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; > > Why is this conditional? > Same paranoia as before. If lenp is not allocated, the function behaviour is the same. > > > + > > + if (n * sz > datasz) > > + return -EOVERFLOW; > > Ugh, this isn't E2BIG or ENOSPC... > Ok, will be changed to ENOSPC. > > > + > > + out = kcalloc(n, sz, GFP_KERNEL); > > + if (!out) > > + return -ENOMEM; > > + > > + 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, uint32_t *flags, > > > >
_______________________________________________ iommu mailing list [email protected] https://lists.linuxfoundation.org/mailman/listinfo/iommu
