提交 5851d3b0 编写于 作者: E Eric Biggers 提交者: Ulf Hansson

block/keyslot-manager: introduce devm_blk_ksm_init()

Add a resource-managed variant of blk_ksm_init() so that drivers don't
have to worry about calling blk_ksm_destroy().

Note that the implementation uses a custom devres action to call
blk_ksm_destroy() rather than switching the two allocations to be
directly devres-managed, e.g. with devm_kmalloc().  This is because we
need to keep zeroing the memory containing the keyslots when it is
freed, and also because we want to continue using kvmalloc() (and there
is no devm_kvmalloc()).
Signed-off-by: NEric Biggers <ebiggers@google.com>
Reviewed-by: NSatya Tangirala <satyat@google.com>
Acked-by: NJens Axboe <axboe@kernel.dk>
Link: https://lore.kernel.org/r/20210121082155.111333-2-ebiggers@kernel.orgSigned-off-by: NUlf Hansson <ulf.hansson@linaro.org>
上级 4af307f5
...@@ -182,8 +182,9 @@ API presented to device drivers ...@@ -182,8 +182,9 @@ API presented to device drivers
A :c:type:``struct blk_keyslot_manager`` should be set up by device drivers in A :c:type:``struct blk_keyslot_manager`` should be set up by device drivers in
the ``request_queue`` of the device. The device driver needs to call the ``request_queue`` of the device. The device driver needs to call
``blk_ksm_init`` on the ``blk_keyslot_manager``, which specifying the number of ``blk_ksm_init`` (or its resource-managed variant ``devm_blk_ksm_init``) on the
keyslots supported by the hardware. ``blk_keyslot_manager``, while specifying the number of keyslots supported by
the hardware.
The device driver also needs to tell the KSM how to actually manipulate the The device driver also needs to tell the KSM how to actually manipulate the
IE hardware in the device to do things like programming the crypto key into IE hardware in the device to do things like programming the crypto key into
...@@ -202,10 +203,9 @@ needs each and every of its keyslots to be reprogrammed with the key it ...@@ -202,10 +203,9 @@ needs each and every of its keyslots to be reprogrammed with the key it
"should have" at the point in time when the function is called. This is useful "should have" at the point in time when the function is called. This is useful
e.g. if a device loses all its keys on runtime power down/up. e.g. if a device loses all its keys on runtime power down/up.
``blk_ksm_destroy`` should be called to free up all resources used by a keyslot If the driver used ``blk_ksm_init`` instead of ``devm_blk_ksm_init``, then
manager upon ``blk_ksm_init``, once the ``blk_keyslot_manager`` is no longer ``blk_ksm_destroy`` should be called to free up all resources used by a
needed. ``blk_keyslot_manager`` once it is no longer needed.
Layered Devices Layered Devices
=============== ===============
......
...@@ -29,6 +29,7 @@ ...@@ -29,6 +29,7 @@
#define pr_fmt(fmt) "blk-crypto: " fmt #define pr_fmt(fmt) "blk-crypto: " fmt
#include <linux/keyslot-manager.h> #include <linux/keyslot-manager.h>
#include <linux/device.h>
#include <linux/atomic.h> #include <linux/atomic.h>
#include <linux/mutex.h> #include <linux/mutex.h>
#include <linux/pm_runtime.h> #include <linux/pm_runtime.h>
...@@ -127,6 +128,34 @@ int blk_ksm_init(struct blk_keyslot_manager *ksm, unsigned int num_slots) ...@@ -127,6 +128,34 @@ int blk_ksm_init(struct blk_keyslot_manager *ksm, unsigned int num_slots)
} }
EXPORT_SYMBOL_GPL(blk_ksm_init); EXPORT_SYMBOL_GPL(blk_ksm_init);
static void blk_ksm_destroy_callback(void *ksm)
{
blk_ksm_destroy(ksm);
}
/**
* devm_blk_ksm_init() - Resource-managed blk_ksm_init()
* @dev: The device which owns the blk_keyslot_manager.
* @ksm: The blk_keyslot_manager to initialize.
* @num_slots: The number of key slots to manage.
*
* Like blk_ksm_init(), but causes blk_ksm_destroy() to be called automatically
* on driver detach.
*
* Return: 0 on success, or else a negative error code.
*/
int devm_blk_ksm_init(struct device *dev, struct blk_keyslot_manager *ksm,
unsigned int num_slots)
{
int err = blk_ksm_init(ksm, num_slots);
if (err)
return err;
return devm_add_action_or_reset(dev, blk_ksm_destroy_callback, ksm);
}
EXPORT_SYMBOL_GPL(devm_blk_ksm_init);
static inline struct hlist_head * static inline struct hlist_head *
blk_ksm_hash_bucket_for_key(struct blk_keyslot_manager *ksm, blk_ksm_hash_bucket_for_key(struct blk_keyslot_manager *ksm,
const struct blk_crypto_key *key) const struct blk_crypto_key *key)
......
...@@ -85,6 +85,9 @@ struct blk_keyslot_manager { ...@@ -85,6 +85,9 @@ struct blk_keyslot_manager {
int blk_ksm_init(struct blk_keyslot_manager *ksm, unsigned int num_slots); int blk_ksm_init(struct blk_keyslot_manager *ksm, unsigned int num_slots);
int devm_blk_ksm_init(struct device *dev, struct blk_keyslot_manager *ksm,
unsigned int num_slots);
blk_status_t blk_ksm_get_slot_for_key(struct blk_keyslot_manager *ksm, blk_status_t blk_ksm_get_slot_for_key(struct blk_keyslot_manager *ksm,
const struct blk_crypto_key *key, const struct blk_crypto_key *key,
struct blk_ksm_keyslot **slot_ptr); struct blk_ksm_keyslot **slot_ptr);
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册