> -----Original Message----- > From: Jiri Pirko <jiri@xxxxxxxxxxx> > Sent: Friday, November 8, 2019 5:05 AM > To: Parav Pandit <parav@xxxxxxxxxxxx> > Cc: alex.williamson@xxxxxxxxxx; davem@xxxxxxxxxxxxx; > kvm@xxxxxxxxxxxxxxx; netdev@xxxxxxxxxxxxxxx; Saeed Mahameed > <saeedm@xxxxxxxxxxxx>; kwankhede@xxxxxxxxxx; leon@xxxxxxxxxx; > cohuck@xxxxxxxxxx; Jiri Pirko <jiri@xxxxxxxxxxxx>; linux- > rdma@xxxxxxxxxxxxxxx > Subject: Re: [PATCH net-next 07/19] vfio/mdev: Introduce sha1 based mdev > alias > > Thu, Nov 07, 2019 at 05:08:22PM CET, parav@xxxxxxxxxxxx wrote: > >Some vendor drivers want an identifier for an mdev device that is > >shorter than the UUID, due to length restrictions in the consumers of > >that identifier. > > > >Add a callback that allows a vendor driver to request an alias of a > >specified length to be generated for an mdev device. If generated, that > >alias is checked for collisions. > > > >It is an optional attribute. > >mdev alias is generated using sha1 from the mdev name. > > > >Reviewed-by: Saeed Mahameed <saeedm@xxxxxxxxxxxx> > >Signed-off-by: Parav Pandit <parav@xxxxxxxxxxxx> > >--- > > drivers/vfio/mdev/mdev_core.c | 123 > ++++++++++++++++++++++++++++++- > > drivers/vfio/mdev/mdev_private.h | 5 +- > > drivers/vfio/mdev/mdev_sysfs.c | 13 ++-- > > include/linux/mdev.h | 4 + > > 4 files changed, 135 insertions(+), 10 deletions(-) > > > >diff --git a/drivers/vfio/mdev/mdev_core.c > >b/drivers/vfio/mdev/mdev_core.c index b558d4cfd082..3bdff0469607 > 100644 > >--- a/drivers/vfio/mdev/mdev_core.c > >+++ b/drivers/vfio/mdev/mdev_core.c > >@@ -10,9 +10,11 @@ > > [...] > > > >-int mdev_device_create(struct kobject *kobj, > >- struct device *dev, const guid_t *uuid) > >+static const char * > >+generate_alias(const char *uuid, unsigned int max_alias_len) { > >+ struct shash_desc *hash_desc; > >+ unsigned int digest_size; > >+ unsigned char *digest; > >+ unsigned int alias_len; > >+ char *alias; > >+ int ret; > >+ > >+ /* > >+ * Align to multiple of 2 as bin2hex will generate > >+ * even number of bytes. > >+ */ > >+ alias_len = roundup(max_alias_len, 2); > > This is odd, see below. > > > >+ alias = kzalloc(alias_len + 1, GFP_KERNEL); > >+ if (!alias) > >+ return ERR_PTR(-ENOMEM); > >+ > >+ /* Allocate and init descriptor */ > >+ hash_desc = kvzalloc(sizeof(*hash_desc) + > >+ crypto_shash_descsize(alias_hash), > >+ GFP_KERNEL); > >+ if (!hash_desc) { > >+ ret = -ENOMEM; > >+ goto desc_err; > >+ } > >+ > >+ hash_desc->tfm = alias_hash; > >+ > >+ digest_size = crypto_shash_digestsize(alias_hash); > >+ > >+ digest = kzalloc(digest_size, GFP_KERNEL); > >+ if (!digest) { > >+ ret = -ENOMEM; > >+ goto digest_err; > >+ } > >+ ret = crypto_shash_init(hash_desc); > >+ if (ret) > >+ goto hash_err; > >+ > >+ ret = crypto_shash_update(hash_desc, uuid, UUID_STRING_LEN); > >+ if (ret) > >+ goto hash_err; > >+ > >+ ret = crypto_shash_final(hash_desc, digest); > >+ if (ret) > >+ goto hash_err; > >+ > >+ bin2hex(alias, digest, min_t(unsigned int, digest_size, alias_len / 2)); > >+ /* > >+ * When alias length is odd, zero out an additional last byte > >+ * that bin2hex has copied. > >+ */ > >+ if (max_alias_len % 2) > >+ alias[max_alias_len] = 0; > >+ > >+ kfree(digest); > >+ kvfree(hash_desc); > >+ return alias; > >+ > >+hash_err: > >+ kfree(digest); > >+digest_err: > >+ kvfree(hash_desc); > >+desc_err: > >+ kfree(alias); > >+ return ERR_PTR(ret); > >+} > >+ > >+int mdev_device_create(struct kobject *kobj, struct device *dev, > >+ const char *uuid_str, const guid_t *uuid) > > { > > int ret; > > struct mdev_device *mdev, *tmp; > > struct mdev_parent *parent; > > struct mdev_type *type = to_mdev_type(kobj); > >+ const char *alias = NULL; > > > > parent = mdev_get_parent(type->parent); > > if (!parent) > > return -EINVAL; > > > >+ if (parent->ops->get_alias_length) { > >+ unsigned int alias_len; > >+ > >+ alias_len = parent->ops->get_alias_length(); > >+ if (alias_len) { > > I think this should be with WARN_ON. Driver should not never return such > 0 and if it does, it's a bug. > Ok. will add it. > Also I think this check should be extended by checking value is multiple of 2. Do you mean driver must set alias length as always multiple of 2? Why? > Then you can avoid the roundup() above. No need to allow even len. Did you mean "no need to allow odd"? or? > > [...] > > >diff --git a/drivers/vfio/mdev/mdev_sysfs.c > >b/drivers/vfio/mdev/mdev_sysfs.c index 7570c7602ab4..43afe0e80b76 > >100644 > >--- a/drivers/vfio/mdev/mdev_sysfs.c > >+++ b/drivers/vfio/mdev/mdev_sysfs.c > >@@ -63,15 +63,18 @@ static ssize_t create_store(struct kobject *kobj, > struct device *dev, > > return -ENOMEM; > > > > ret = guid_parse(str, &uuid); > >- kfree(str); > > if (ret) > >- return ret; > >+ goto err; > > > >- ret = mdev_device_create(kobj, dev, &uuid); > >+ ret = mdev_device_create(kobj, dev, str, &uuid); > > Why to pass the same thing twice? Move the guid_parse() call to the > beginning of mdev_device_create() function. > Because alias should be unique and need to hold the lock while searching for duplicate. So it is not done twice, and moving guid_parse() won't help due to need of lock. > > > if (ret) > >- return ret; > >+ goto err; > > > >- return count; > >+ ret = count; > >+ > >+err: > >+ kfree(str); > >+ return ret; > > } > > > > MDEV_TYPE_ATTR_WO(create); > > [...]