[dm-devel] [PATCH 2/2] blk-crypto: fix the blk_crypto_profile liftime

Ulf Hansson ulf.hansson at linaro.org
Wed Apr 20 09:49:19 UTC 2022


On Wed, 20 Apr 2022 at 08:48, Christoph Hellwig <hch at lst.de> wrote:
>
> Once the blk_crypto_profile is exposed in sysfs it needs to stay alive
> as long as sysfs accesses are possibly pending.  Ensure that by removing
> the blk_crypto_kobj wrapper and just embedding the kobject into the
> actual blk_crypto_profile.  This requires the blk_crypto_profile
> structure to be dynamically allocated, which in turn requires a private
> data pointer for driver use.
>
> Fixes: 20f01f163203 ("blk-crypto: show crypto capabilities in sysfs")
> Signed-off-by: Christoph Hellwig <hch at lst.de>

I am not surprised that you seem to have found lifecycle issues, as
it's a rather complex path of how to deal with the resources
correctly. Just for mmc internally, we have three layers of code that
gets involved.

That said, I think the code in the $subject patch looks good to me,
but I have to admit that it's not a full in-depth review - and I
haven't done any tests.

Nevertheless, feel free to add:
Reviewed-by: Ulf Hansson <ulf.hansson at linaro.org>

Kind regards
Uffe

> ---
>  Documentation/block/inline-encryption.rst |  10 +-
>  block/blk-crypto-fallback.c               |  20 +--
>  block/blk-crypto-profile.c                | 143 ++++++++++------------
>  drivers/md/dm-table.c                     |  28 +----
>  drivers/mmc/core/crypto.c                 |   4 +-
>  drivers/mmc/host/cqhci-crypto.c           |  16 ++-
>  drivers/scsi/ufs/ufshcd-crypto.c          |  31 ++---
>  drivers/scsi/ufs/ufshcd.h                 |   2 +-
>  include/linux/blk-crypto-profile.h        |  19 +--
>  include/linux/blkdev.h                    |   1 -
>  include/linux/mmc/host.h                  |   2 +-
>  11 files changed, 123 insertions(+), 153 deletions(-)
>
> diff --git a/Documentation/block/inline-encryption.rst b/Documentation/block/inline-encryption.rst
> index 4d151fbe20583..0d740b0f9faf3 100644
> --- a/Documentation/block/inline-encryption.rst
> +++ b/Documentation/block/inline-encryption.rst
> @@ -230,8 +230,8 @@ API presented to device drivers
>
>  A device driver that wants to support inline encryption must set up a
>  blk_crypto_profile in the request_queue of its device.  To do this, it first
> -must call ``blk_crypto_profile_init()`` (or its resource-managed variant
> -``devm_blk_crypto_profile_init()``), providing the number of keyslots.
> +must call ``blk_crypto_profile_alloc()`` (or its resource-managed variant
> +``devm_blk_crypto_profile_alloc()``), providing the number of keyslots.
>
>  Next, it must advertise its crypto capabilities by setting fields in the
>  blk_crypto_profile, e.g. ``modes_supported`` and ``max_dun_bytes_supported``.
> @@ -259,9 +259,9 @@ If there are situations where the inline encryption hardware loses the contents
>  of its keyslots, e.g. device resets, the driver must handle reprogramming the
>  keyslots.  To do this, the driver may call ``blk_crypto_reprogram_all_keys()``.
>
> -Finally, if the driver used ``blk_crypto_profile_init()`` instead of
> -``devm_blk_crypto_profile_init()``, then it is responsible for calling
> -``blk_crypto_profile_destroy()`` when the crypto profile is no longer needed.
> +Finally, if the driver used ``blk_crypto_profile_alloc()`` instead of
> +``devm_blk_crypto_profile_alloc()``, then it is responsible for calling
> +``blk_crypto_profile_put()`` when the crypto profile is no longer needed.
>
>  Layered Devices
>  ===============
> diff --git a/block/blk-crypto-fallback.c b/block/blk-crypto-fallback.c
> index 5d1aa5b1d30a1..729974028e448 100644
> --- a/block/blk-crypto-fallback.c
> +++ b/block/blk-crypto-fallback.c
> @@ -78,7 +78,7 @@ static struct blk_crypto_fallback_keyslot {
>         struct crypto_skcipher *tfms[BLK_ENCRYPTION_MODE_MAX];
>  } *blk_crypto_keyslots;
>
> -static struct blk_crypto_profile blk_crypto_fallback_profile;
> +static struct blk_crypto_profile *blk_crypto_fallback_profile;
>  static struct workqueue_struct *blk_crypto_wq;
>  static mempool_t *blk_crypto_bounce_page_pool;
>  static struct bio_set crypto_bio_split;
> @@ -293,7 +293,7 @@ static bool blk_crypto_fallback_encrypt_bio(struct bio **bio_ptr)
>          * Get a blk-crypto-fallback keyslot that contains a crypto_skcipher for
>          * this bio's algorithm and key.
>          */
> -       blk_st = blk_crypto_get_keyslot(&blk_crypto_fallback_profile,
> +       blk_st = blk_crypto_get_keyslot(blk_crypto_fallback_profile,
>                                         bc->bc_key, &slot);
>         if (blk_st != BLK_STS_OK) {
>                 src_bio->bi_status = blk_st;
> @@ -396,7 +396,7 @@ static void blk_crypto_fallback_decrypt_bio(struct work_struct *work)
>          * Get a blk-crypto-fallback keyslot that contains a crypto_skcipher for
>          * this bio's algorithm and key.
>          */
> -       blk_st = blk_crypto_get_keyslot(&blk_crypto_fallback_profile,
> +       blk_st = blk_crypto_get_keyslot(blk_crypto_fallback_profile,
>                                         bc->bc_key, &slot);
>         if (blk_st != BLK_STS_OK) {
>                 bio->bi_status = blk_st;
> @@ -500,7 +500,7 @@ bool blk_crypto_fallback_bio_prep(struct bio **bio_ptr)
>                 return false;
>         }
>
> -       if (!__blk_crypto_cfg_supported(&blk_crypto_fallback_profile,
> +       if (!__blk_crypto_cfg_supported(blk_crypto_fallback_profile,
>                                         &bc->bc_key->crypto_cfg)) {
>                 bio->bi_status = BLK_STS_NOTSUPP;
>                 return false;
> @@ -527,7 +527,7 @@ bool blk_crypto_fallback_bio_prep(struct bio **bio_ptr)
>
>  int blk_crypto_fallback_evict_key(const struct blk_crypto_key *key)
>  {
> -       return __blk_crypto_evict_key(&blk_crypto_fallback_profile, key);
> +       return __blk_crypto_evict_key(blk_crypto_fallback_profile, key);
>  }
>
>  static bool blk_crypto_fallback_inited;
> @@ -535,7 +535,7 @@ static int blk_crypto_fallback_init(void)
>  {
>         int i;
>         int err;
> -       struct blk_crypto_profile *profile = &blk_crypto_fallback_profile;
> +       struct blk_crypto_profile *profile;
>
>         if (blk_crypto_fallback_inited)
>                 return 0;
> @@ -546,10 +546,10 @@ static int blk_crypto_fallback_init(void)
>         if (err)
>                 goto out;
>
> -       err = blk_crypto_profile_init(profile, blk_crypto_num_keyslots);
> -       if (err)
> -               goto fail_free_bioset;
>         err = -ENOMEM;
> +       profile = blk_crypto_profile_alloc(blk_crypto_num_keyslots);
> +       if (!profile)
> +               goto fail_free_bioset;
>
>         profile->ll_ops = blk_crypto_fallback_ll_ops;
>         profile->max_dun_bytes_supported = BLK_CRYPTO_MAX_IV_SIZE;
> @@ -598,7 +598,7 @@ static int blk_crypto_fallback_init(void)
>  fail_free_wq:
>         destroy_workqueue(blk_crypto_wq);
>  fail_destroy_profile:
> -       blk_crypto_profile_destroy(profile);
> +       blk_crypto_profile_put(profile);
>  fail_free_bioset:
>         bioset_exit(&crypto_bio_split);
>  out:
> diff --git a/block/blk-crypto-profile.c b/block/blk-crypto-profile.c
> index 4f444323cb491..e4e14322d2f2e 100644
> --- a/block/blk-crypto-profile.c
> +++ b/block/blk-crypto-profile.c
> @@ -42,11 +42,6 @@ struct blk_crypto_keyslot {
>         struct blk_crypto_profile *profile;
>  };
>
> -struct blk_crypto_kobj {
> -       struct kobject kobj;
> -       struct blk_crypto_profile *profile;
> -};
> -
>  struct blk_crypto_attr {
>         struct attribute attr;
>         ssize_t (*show)(struct blk_crypto_profile *profile,
> @@ -55,7 +50,7 @@ struct blk_crypto_attr {
>
>  static struct blk_crypto_profile *kobj_to_crypto_profile(struct kobject *kobj)
>  {
> -       return container_of(kobj, struct blk_crypto_kobj, kobj)->profile;
> +       return container_of(kobj, struct blk_crypto_profile, kobj);
>  }
>
>  static struct blk_crypto_attr *attr_to_crypto_attr(struct attribute *attr)
> @@ -145,7 +140,14 @@ static const struct sysfs_ops blk_crypto_attr_ops = {
>
>  static void blk_crypto_release(struct kobject *kobj)
>  {
> -       kfree(container_of(kobj, struct blk_crypto_kobj, kobj));
> +       struct blk_crypto_profile *profile =
> +               container_of(kobj, struct blk_crypto_profile, kobj);
> +
> +       kvfree(profile->slot_hashtable);
> +       kvfree_sensitive(profile->slots,
> +                        sizeof(profile->slots[0]) * profile->num_slots);
> +       memzero_explicit(profile, sizeof(*profile));
> +       kfree(profile);
>  }
>
>  static struct kobj_type blk_crypto_ktype = {
> @@ -160,30 +162,20 @@ static struct kobj_type blk_crypto_ktype = {
>   */
>  int blk_crypto_sysfs_register(struct request_queue *q)
>  {
> -       struct blk_crypto_kobj *obj;
>         int err;
>
>         if (!q->crypto_profile)
>                 return 0;
>
> -       obj = kzalloc(sizeof(*obj), GFP_KERNEL);
> -       if (!obj)
> -               return -ENOMEM;
> -       obj->profile = q->crypto_profile;
> -
> -       err = kobject_init_and_add(&obj->kobj, &blk_crypto_ktype, &q->kobj,
> -                                  "crypto");
> -       if (err) {
> -               kobject_put(&obj->kobj);
> -               return err;
> -       }
> -       q->crypto_kobject = &obj->kobj;
> -       return 0;
> +       err = kobject_add(&q->crypto_profile->kobj, &q->kobj, "crypto");
> +       if (err)
> +               kobject_put(&q->crypto_profile->kobj);
> +       return err;
>  }
>
>  void blk_crypto_sysfs_unregister(struct request_queue *q)
>  {
> -       kobject_put(q->crypto_kobject);
> +       kobject_del(&q->crypto_profile->kobj);
>  }
>
>  static inline void blk_crypto_hw_enter(struct blk_crypto_profile *profile)
> @@ -205,30 +197,13 @@ static inline void blk_crypto_hw_exit(struct blk_crypto_profile *profile)
>                 pm_runtime_put_sync(profile->dev);
>  }
>
> -/**
> - * blk_crypto_profile_init() - Initialize a blk_crypto_profile
> - * @profile: the blk_crypto_profile to initialize
> - * @num_slots: the number of keyslots
> - *
> - * Storage drivers must call this when starting to set up a blk_crypto_profile,
> - * before filling in additional fields.
> - *
> - * Return: 0 on success, or else a negative error code.
> - */
> -int blk_crypto_profile_init(struct blk_crypto_profile *profile,
> -                           unsigned int num_slots)
> +/* Initialize keyslot management data. */
> +static int blk_crypto_profile_init_slots(struct blk_crypto_profile *profile,
> +               unsigned int num_slots)
>  {
> +       unsigned int slot_hashtable_size;
>         unsigned int slot;
>         unsigned int i;
> -       unsigned int slot_hashtable_size;
> -
> -       memset(profile, 0, sizeof(*profile));
> -       init_rwsem(&profile->lock);
> -
> -       if (num_slots == 0)
> -               return 0;
> -
> -       /* Initialize keyslot management data. */
>
>         profile->slots = kvcalloc(num_slots, sizeof(profile->slots[0]),
>                                   GFP_KERNEL);
> @@ -261,48 +236,75 @@ int blk_crypto_profile_init(struct blk_crypto_profile *profile,
>                 kvmalloc_array(slot_hashtable_size,
>                                sizeof(profile->slot_hashtable[0]), GFP_KERNEL);
>         if (!profile->slot_hashtable)
> -               goto err_destroy;
> +               return -ENOMEM;
>         for (i = 0; i < slot_hashtable_size; i++)
>                 INIT_HLIST_HEAD(&profile->slot_hashtable[i]);
> -
>         return 0;
> +}
> +
> +/**
> + * blk_crypto_profile_alloc() - Allocate a blk_crypto_profile
> + * @num_slots: the number of keyslots
> + *
> + * Storage drivers must call this when starting to set up a blk_crypto_profile,
> + * before filling in additional fields.
> + *
> + * Return: pointer to the profile on success, or ele %NULL.
> + */
> +struct blk_crypto_profile *blk_crypto_profile_alloc(unsigned int num_slots)
> +{
> +       struct blk_crypto_profile *profile;
>
> -err_destroy:
> -       blk_crypto_profile_destroy(profile);
> -       return -ENOMEM;
> +       profile = kzalloc(sizeof(*profile), GFP_KERNEL);
> +       if (!profile)
> +               return NULL;
> +       kobject_init(&profile->kobj, &blk_crypto_ktype);
> +       init_rwsem(&profile->lock);
> +       if (num_slots && blk_crypto_profile_init_slots(profile, num_slots)) {
> +               blk_crypto_profile_put(profile);
> +               return NULL;
> +       }
> +
> +       return profile;
>  }
> -EXPORT_SYMBOL_GPL(blk_crypto_profile_init);
> +EXPORT_SYMBOL_GPL(blk_crypto_profile_alloc);
>
> -static void blk_crypto_profile_destroy_callback(void *profile)
> +void blk_crypto_profile_put(struct blk_crypto_profile *profile)
>  {
> -       blk_crypto_profile_destroy(profile);
> +       if (profile)
> +               kobject_put(&profile->kobj);
> +}
> +EXPORT_SYMBOL_GPL(blk_crypto_profile_put);
> +
> +static void blk_crypto_profile_put_callback(void *profile)
> +{
> +       blk_crypto_profile_put(profile);
>  }
>
>  /**
> - * devm_blk_crypto_profile_init() - Resource-managed blk_crypto_profile_init()
> + * devm_blk_crypto_profile_alloc() - Resource-managed blk_crypto_profile_alloc()
>   * @dev: the device which owns the blk_crypto_profile
> - * @profile: the blk_crypto_profile to initialize
>   * @num_slots: the number of keyslots
>   *
> - * Like blk_crypto_profile_init(), but causes blk_crypto_profile_destroy() to be
> + * Like blk_crypto_profile_alloc(), but causes blk_crypto_profile_put() to be
>   * called automatically on driver detach.
>   *
> - * Return: 0 on success, or else a negative error code.
> + * Return: profile on success, or else %NULL.
>   */
> -int devm_blk_crypto_profile_init(struct device *dev,
> -                                struct blk_crypto_profile *profile,
> +struct blk_crypto_profile *devm_blk_crypto_profile_alloc(struct device *dev,
>                                  unsigned int num_slots)
>  {
> -       int err = blk_crypto_profile_init(profile, num_slots);
> -
> -       if (err)
> -               return err;
> +       struct blk_crypto_profile *profile;
>
> -       return devm_add_action_or_reset(dev,
> -                                       blk_crypto_profile_destroy_callback,
> -                                       profile);
> +       profile = blk_crypto_profile_alloc(num_slots);
> +       if (!profile)
> +               return NULL;
> +       if (devm_add_action_or_reset(dev, blk_crypto_profile_put_callback,
> +                       profile))
> +               return NULL;
> +       return profile;
>  }
> -EXPORT_SYMBOL_GPL(devm_blk_crypto_profile_init);
> +EXPORT_SYMBOL_GPL(devm_blk_crypto_profile_alloc);
>
>  static inline struct hlist_head *
>  blk_crypto_hash_bucket_for_key(struct blk_crypto_profile *profile,
> @@ -585,17 +587,6 @@ void blk_crypto_reprogram_all_keys(struct blk_crypto_profile *profile)
>  }
>  EXPORT_SYMBOL_GPL(blk_crypto_reprogram_all_keys);
>
> -void blk_crypto_profile_destroy(struct blk_crypto_profile *profile)
> -{
> -       if (!profile)
> -               return;
> -       kvfree(profile->slot_hashtable);
> -       kvfree_sensitive(profile->slots,
> -                        sizeof(profile->slots[0]) * profile->num_slots);
> -       memzero_explicit(profile, sizeof(*profile));
> -}
> -EXPORT_SYMBOL_GPL(blk_crypto_profile_destroy);
> -
>  bool blk_crypto_register(struct blk_crypto_profile *profile,
>                          struct request_queue *q)
>  {
> diff --git a/drivers/md/dm-table.c b/drivers/md/dm-table.c
> index e7d42f6335a2a..0d40f9e9eefbc 100644
> --- a/drivers/md/dm-table.c
> +++ b/drivers/md/dm-table.c
> @@ -1185,11 +1185,6 @@ static int dm_table_register_integrity(struct dm_table *t)
>
>  #ifdef CONFIG_BLK_INLINE_ENCRYPTION
>
> -struct dm_crypto_profile {
> -       struct blk_crypto_profile profile;
> -       struct mapped_device *md;
> -};
> -
>  struct dm_keyslot_evict_args {
>         const struct blk_crypto_key *key;
>         int err;
> @@ -1215,8 +1210,7 @@ static int dm_keyslot_evict_callback(struct dm_target *ti, struct dm_dev *dev,
>  static int dm_keyslot_evict(struct blk_crypto_profile *profile,
>                             const struct blk_crypto_key *key, unsigned int slot)
>  {
> -       struct mapped_device *md =
> -               container_of(profile, struct dm_crypto_profile, profile)->md;
> +       struct mapped_device *md = profile->private;
>         struct dm_keyslot_evict_args args = { key };
>         struct dm_table *t;
>         int srcu_idx;
> @@ -1250,15 +1244,7 @@ device_intersect_crypto_capabilities(struct dm_target *ti, struct dm_dev *dev,
>
>  void dm_destroy_crypto_profile(struct blk_crypto_profile *profile)
>  {
> -       struct dm_crypto_profile *dmcp = container_of(profile,
> -                                                     struct dm_crypto_profile,
> -                                                     profile);
> -
> -       if (!profile)
> -               return;
> -
> -       blk_crypto_profile_destroy(profile);
> -       kfree(dmcp);
> +       blk_crypto_profile_put(profile);
>  }
>
>  static void dm_table_destroy_crypto_profile(struct dm_table *t)
> @@ -1278,19 +1264,15 @@ static void dm_table_destroy_crypto_profile(struct dm_table *t)
>   */
>  static int dm_table_construct_crypto_profile(struct dm_table *t)
>  {
> -       struct dm_crypto_profile *dmcp;
>         struct blk_crypto_profile *profile;
>         struct dm_target *ti;
>         unsigned int i;
>         bool empty_profile = true;
>
> -       dmcp = kmalloc(sizeof(*dmcp), GFP_KERNEL);
> -       if (!dmcp)
> +       profile = blk_crypto_profile_alloc(0);
> +       if (!profile)
>                 return -ENOMEM;
> -       dmcp->md = t->md;
> -
> -       profile = &dmcp->profile;
> -       blk_crypto_profile_init(profile, 0);
> +       profile->private = t->md;
>         profile->ll_ops.keyslot_evict = dm_keyslot_evict;
>         profile->max_dun_bytes_supported = UINT_MAX;
>         memset(profile->modes_supported, 0xFF,
> diff --git a/drivers/mmc/core/crypto.c b/drivers/mmc/core/crypto.c
> index fec4fbf16a5b6..df3c002526cc7 100644
> --- a/drivers/mmc/core/crypto.c
> +++ b/drivers/mmc/core/crypto.c
> @@ -16,13 +16,13 @@ void mmc_crypto_set_initial_state(struct mmc_host *host)
>  {
>         /* Reset might clear all keys, so reprogram all the keys. */
>         if (host->caps2 & MMC_CAP2_CRYPTO)
> -               blk_crypto_reprogram_all_keys(&host->crypto_profile);
> +               blk_crypto_reprogram_all_keys(host->crypto_profile);
>  }
>
>  void mmc_crypto_setup_queue(struct request_queue *q, struct mmc_host *host)
>  {
>         if (host->caps2 & MMC_CAP2_CRYPTO)
> -               blk_crypto_register(&host->crypto_profile, q);
> +               blk_crypto_register(host->crypto_profile, q);
>  }
>  EXPORT_SYMBOL_GPL(mmc_crypto_setup_queue);
>
> diff --git a/drivers/mmc/host/cqhci-crypto.c b/drivers/mmc/host/cqhci-crypto.c
> index d5f4b6972f63e..6b1c111e9e4b2 100644
> --- a/drivers/mmc/host/cqhci-crypto.c
> +++ b/drivers/mmc/host/cqhci-crypto.c
> @@ -25,8 +25,7 @@ static const struct cqhci_crypto_alg_entry {
>  static inline struct cqhci_host *
>  cqhci_host_from_crypto_profile(struct blk_crypto_profile *profile)
>  {
> -       struct mmc_host *mmc =
> -               container_of(profile, struct mmc_host, crypto_profile);
> +       struct mmc_host *mmc = profile->private;
>
>         return mmc->cqe_private;
>  }
> @@ -169,7 +168,7 @@ int cqhci_crypto_init(struct cqhci_host *cq_host)
>  {
>         struct mmc_host *mmc = cq_host->mmc;
>         struct device *dev = mmc_dev(mmc);
> -       struct blk_crypto_profile *profile = &mmc->crypto_profile;
> +       struct blk_crypto_profile *profile;
>         unsigned int num_keyslots;
>         unsigned int cap_idx;
>         enum blk_crypto_mode_num blk_mode_num;
> @@ -180,6 +179,7 @@ int cqhci_crypto_init(struct cqhci_host *cq_host)
>             !(cqhci_readl(cq_host, CQHCI_CAP) & CQHCI_CAP_CS))
>                 goto out;
>
> +       err = -ENOMEM;
>         cq_host->crypto_capabilities.reg_val =
>                         cpu_to_le32(cqhci_readl(cq_host, CQHCI_CCAP));
>
> @@ -189,10 +189,8 @@ int cqhci_crypto_init(struct cqhci_host *cq_host)
>         cq_host->crypto_cap_array =
>                 devm_kcalloc(dev, cq_host->crypto_capabilities.num_crypto_cap,
>                              sizeof(cq_host->crypto_cap_array[0]), GFP_KERNEL);
> -       if (!cq_host->crypto_cap_array) {
> -               err = -ENOMEM;
> +       if (!cq_host->crypto_cap_array)
>                 goto out;
> -       }
>
>         /*
>          * CCAP.CFGC is off by one, so the actual number of crypto
> @@ -200,10 +198,10 @@ int cqhci_crypto_init(struct cqhci_host *cq_host)
>          */
>         num_keyslots = cq_host->crypto_capabilities.config_count + 1;
>
> -       err = devm_blk_crypto_profile_init(dev, profile, num_keyslots);
> -       if (err)
> +       profile = devm_blk_crypto_profile_alloc(dev, num_keyslots);
> +       if (!profile)
>                 goto out;
> -
> +       profile->private = mmc;
>         profile->ll_ops = cqhci_crypto_ops;
>         profile->dev = dev;
>
> diff --git a/drivers/scsi/ufs/ufshcd-crypto.c b/drivers/scsi/ufs/ufshcd-crypto.c
> index 67402baf6faee..b48ff6046bdc8 100644
> --- a/drivers/scsi/ufs/ufshcd-crypto.c
> +++ b/drivers/scsi/ufs/ufshcd-crypto.c
> @@ -52,8 +52,7 @@ static int ufshcd_crypto_keyslot_program(struct blk_crypto_profile *profile,
>                                          const struct blk_crypto_key *key,
>                                          unsigned int slot)
>  {
> -       struct ufs_hba *hba =
> -               container_of(profile, struct ufs_hba, crypto_profile);
> +       struct ufs_hba *hba = profile->private;
>         const union ufs_crypto_cap_entry *ccap_array = hba->crypto_cap_array;
>         const struct ufs_crypto_alg_entry *alg =
>                         &ufs_crypto_algs[key->crypto_cfg.crypto_mode];
> @@ -110,10 +109,7 @@ static int ufshcd_crypto_keyslot_evict(struct blk_crypto_profile *profile,
>                                        const struct blk_crypto_key *key,
>                                        unsigned int slot)
>  {
> -       struct ufs_hba *hba =
> -               container_of(profile, struct ufs_hba, crypto_profile);
> -
> -       return ufshcd_clear_keyslot(hba, slot);
> +       return ufshcd_clear_keyslot(profile->private, slot);
>  }
>
>  bool ufshcd_crypto_enable(struct ufs_hba *hba)
> @@ -122,7 +118,7 @@ bool ufshcd_crypto_enable(struct ufs_hba *hba)
>                 return false;
>
>         /* Reset might clear all keys, so reprogram all the keys. */
> -       blk_crypto_reprogram_all_keys(&hba->crypto_profile);
> +       blk_crypto_reprogram_all_keys(hba->crypto_profile);
>         return true;
>  }
>
> @@ -168,6 +164,7 @@ int ufshcd_hba_init_crypto_capabilities(struct ufs_hba *hba)
>             !(hba->caps & UFSHCD_CAP_CRYPTO))
>                 goto out;
>
> +       err = -ENOMEM;
>         hba->crypto_capabilities.reg_val =
>                         cpu_to_le32(ufshcd_readl(hba, REG_UFS_CCAP));
>         hba->crypto_cfg_register =
> @@ -175,22 +172,20 @@ int ufshcd_hba_init_crypto_capabilities(struct ufs_hba *hba)
>         hba->crypto_cap_array =
>                 devm_kcalloc(hba->dev, hba->crypto_capabilities.num_crypto_cap,
>                              sizeof(hba->crypto_cap_array[0]), GFP_KERNEL);
> -       if (!hba->crypto_cap_array) {
> -               err = -ENOMEM;
> +       if (!hba->crypto_cap_array)
>                 goto out;
> -       }
>
>         /* The actual number of configurations supported is (CFGC+1) */
> -       err = devm_blk_crypto_profile_init(
> -                       hba->dev, &hba->crypto_profile,
> +       hba->crypto_profile = devm_blk_crypto_profile_alloc(hba->dev,
>                         hba->crypto_capabilities.config_count + 1);
> -       if (err)
> +       if (!hba->crypto_profile)
>                 goto out;
>
> -       hba->crypto_profile.ll_ops = ufshcd_crypto_ops;
> +       hba->crypto_profile->private = hba;
> +       hba->crypto_profile->ll_ops = ufshcd_crypto_ops;
>         /* UFS only supports 8 bytes for any DUN */
> -       hba->crypto_profile.max_dun_bytes_supported = 8;
> -       hba->crypto_profile.dev = hba->dev;
> +       hba->crypto_profile->max_dun_bytes_supported = 8;
> +       hba->crypto_profile->dev = hba->dev;
>
>         /*
>          * Cache all the UFS crypto capabilities and advertise the supported
> @@ -205,7 +200,7 @@ int ufshcd_hba_init_crypto_capabilities(struct ufs_hba *hba)
>                 blk_mode_num = ufshcd_find_blk_crypto_mode(
>                                                 hba->crypto_cap_array[cap_idx]);
>                 if (blk_mode_num != BLK_ENCRYPTION_MODE_INVALID)
> -                       hba->crypto_profile.modes_supported[blk_mode_num] |=
> +                       hba->crypto_profile->modes_supported[blk_mode_num] |=
>                                 hba->crypto_cap_array[cap_idx].sdus_mask * 512;
>         }
>
> @@ -236,5 +231,5 @@ void ufshcd_init_crypto(struct ufs_hba *hba)
>  void ufshcd_crypto_register(struct ufs_hba *hba, struct request_queue *q)
>  {
>         if (hba->caps & UFSHCD_CAP_CRYPTO)
> -               blk_crypto_register(&hba->crypto_profile, q);
> +               blk_crypto_register(hba->crypto_profile, q);
>  }
> diff --git a/drivers/scsi/ufs/ufshcd.h b/drivers/scsi/ufs/ufshcd.h
> index 94f545be183aa..94edbe3721890 100644
> --- a/drivers/scsi/ufs/ufshcd.h
> +++ b/drivers/scsi/ufs/ufshcd.h
> @@ -930,7 +930,7 @@ struct ufs_hba {
>         union ufs_crypto_capabilities crypto_capabilities;
>         union ufs_crypto_cap_entry *crypto_cap_array;
>         u32 crypto_cfg_register;
> -       struct blk_crypto_profile crypto_profile;
> +       struct blk_crypto_profile *crypto_profile;
>  #endif
>  #ifdef CONFIG_DEBUG_FS
>         struct dentry *debugfs_root;
> diff --git a/include/linux/blk-crypto-profile.h b/include/linux/blk-crypto-profile.h
> index bbab65bd54288..07745a4675f25 100644
> --- a/include/linux/blk-crypto-profile.h
> +++ b/include/linux/blk-crypto-profile.h
> @@ -8,6 +8,7 @@
>
>  #include <linux/bio.h>
>  #include <linux/blk-crypto.h>
> +#include <linux/kobject.h>
>
>  struct blk_crypto_profile;
>
> @@ -100,6 +101,11 @@ struct blk_crypto_profile {
>          */
>         struct device *dev;
>
> +       /**
> +        * @private: Optional private data for driver use.
> +        */
> +       void *private;
> +
>         /* private: The following fields shouldn't be accessed by drivers. */
>
>         /* Number of keyslots, or 0 if not applicable */
> @@ -127,14 +133,13 @@ struct blk_crypto_profile {
>
>         /* Per-keyslot data */
>         struct blk_crypto_keyslot *slots;
> -};
>
> -int blk_crypto_profile_init(struct blk_crypto_profile *profile,
> -                           unsigned int num_slots);
> +       struct kobject kobj;
> +};
>
> -int devm_blk_crypto_profile_init(struct device *dev,
> -                                struct blk_crypto_profile *profile,
> -                                unsigned int num_slots);
> +struct blk_crypto_profile *blk_crypto_profile_alloc(unsigned int num_slots);
> +struct blk_crypto_profile *devm_blk_crypto_profile_alloc(struct device *dev,
> +               unsigned int num_slots);
>
>  unsigned int blk_crypto_keyslot_index(struct blk_crypto_keyslot *slot);
>
> @@ -152,7 +157,7 @@ int __blk_crypto_evict_key(struct blk_crypto_profile *profile,
>
>  void blk_crypto_reprogram_all_keys(struct blk_crypto_profile *profile);
>
> -void blk_crypto_profile_destroy(struct blk_crypto_profile *profile);
> +void blk_crypto_profile_put(struct blk_crypto_profile *profile);
>
>  void blk_crypto_intersect_capabilities(struct blk_crypto_profile *parent,
>                                        const struct blk_crypto_profile *child);
> diff --git a/include/linux/blkdev.h b/include/linux/blkdev.h
> index 34724b15813b7..390e3c4ad64b6 100644
> --- a/include/linux/blkdev.h
> +++ b/include/linux/blkdev.h
> @@ -413,7 +413,6 @@ struct request_queue {
>
>  #ifdef CONFIG_BLK_INLINE_ENCRYPTION
>         struct blk_crypto_profile *crypto_profile;
> -       struct kobject *crypto_kobject;
>  #endif
>
>         unsigned int            rq_timeout;
> diff --git a/include/linux/mmc/host.h b/include/linux/mmc/host.h
> index 7afb57cab00b7..8d6069503c0dc 100644
> --- a/include/linux/mmc/host.h
> +++ b/include/linux/mmc/host.h
> @@ -495,7 +495,7 @@ struct mmc_host {
>
>         /* Inline encryption support */
>  #ifdef CONFIG_MMC_CRYPTO
> -       struct blk_crypto_profile crypto_profile;
> +       struct blk_crypto_profile *crypto_profile;
>  #endif
>
>         /* Host Software Queue support */
> --
> 2.30.2
>



More information about the dm-devel mailing list