On Wed, 20 Apr 2022 at 08:48, Christoph Hellwig <hch@xxxxxx> 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@xxxxxx> 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@xxxxxxxxxx> 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 >