History

block: Make blk-integrity preclude hardware inline encryption

Whenever a device supports blk-integrity, make the kernel pretend that the device doesn't support inline encryption (essentially by setting the keyslot manager in the request queue to NULL). There's no hardware currently that supports both integrity and inline encryption. However, it seems possible that there will be such hardware in the near future (like the NVMe key per I/O support that might support both inline encryption and PI). But properly integrating both features is not trivial, and without real hardware that implements both, it is difficult to tell if it will be done correctly by the majority of hardware that support both. So it seems best not to support both features together right now, and to decide what to do at probe time.

Satya Tangirala committed 6 years ago

Commit d145dc21 parent a892c8d4 files · +59 −0Browse files

Unified · Split

4 files
  1. block/bio-integrity.c +3 −0
  2. block/blk-integrity.c +7 −0
  3. block/keyslot-manager.c +19 −0
  4. include/linux/blkdev.h +30 −0
block/bio-integrity.c+3−0
@@ -42,6 +42,9 @@ struct bio_integrity_payload *bio_integrity_alloc(struct bio *bio, · 41 unmodified lines
42 struct bio_set *bs = bio->bi_pool;42 struct bio_set *bs = bio->bi_pool;
43 unsigned inline_vecs;43 unsigned inline_vecs;
44 44
45 if (WARN_ON_ONCE(bio_has_crypt_ctx(bio)))
46 return ERR_PTR(-EOPNOTSUPP);
47
45 if (!bs || !mempool_initialized(&bs->bio_integrity_pool)) {48 if (!bs || !mempool_initialized(&bs->bio_integrity_pool)) {
46 bip = kmalloc(struct_size(bip, bip_inline_vecs, nr_vecs), gfp_mask);49 bip = kmalloc(struct_size(bip, bip_inline_vecs, nr_vecs), gfp_mask);
47 inline_vecs = nr_vecs;50 inline_vecs = nr_vecs;
block/blk-integrity.c+7−0
@@ -409,6 +409,13 @@ void blk_integrity_register(struct gendisk *disk, struct blk_integrity *template · 408 unmodified lines
409 bi->tag_size = template->tag_size;409 bi->tag_size = template->tag_size;
410 410
411 disk->queue->backing_dev_info->capabilities |= BDI_CAP_STABLE_WRITES;411 disk->queue->backing_dev_info->capabilities |= BDI_CAP_STABLE_WRITES;
412
413#ifdef CONFIG_BLK_INLINE_ENCRYPTION
414 if (disk->queue->ksm) {
415 pr_warn("blk-integrity: Integrity and hardware inline encryption are not supported together. Disabling hardware inline encryption.\n");
416 blk_ksm_unregister(disk->queue);
417 }
418#endif
412}419}
413EXPORT_SYMBOL(blk_integrity_register);420EXPORT_SYMBOL(blk_integrity_register);
414 421
block/keyslot-manager.c+19−0
@@ -25,6 +25,9 @@ · 24 unmodified lines
25 * Upper layers will call blk_ksm_get_slot_for_key() to program a25 * Upper layers will call blk_ksm_get_slot_for_key() to program a
26 * key into some slot in the inline encryption hardware.26 * key into some slot in the inline encryption hardware.
27 */27 */
28
29#define pr_fmt(fmt) "blk-crypto: " fmt
30
28#include <linux/keyslot-manager.h>31#include <linux/keyslot-manager.h>
29#include <linux/atomic.h>32#include <linux/atomic.h>
30#include <linux/mutex.h>33#include <linux/mutex.h>
@@ -376,3 +379,19 @@ void blk_ksm_destroy(struct blk_keyslot_manager *ksm) · 345 unmodified lines
376 memzero_explicit(ksm, sizeof(*ksm));379 memzero_explicit(ksm, sizeof(*ksm));
377}380}
378EXPORT_SYMBOL_GPL(blk_ksm_destroy);381EXPORT_SYMBOL_GPL(blk_ksm_destroy);
382
383bool blk_ksm_register(struct blk_keyslot_manager *ksm, struct request_queue *q)
384{
385 if (blk_integrity_queue_supports_integrity(q)) {
386 pr_warn("Integrity and hardware inline encryption are not supported together. Disabling hardware inline encryption.\n");
387 return false;
388 }
389 q->ksm = ksm;
390 return true;
391}
392EXPORT_SYMBOL_GPL(blk_ksm_register);
393
394void blk_ksm_unregister(struct request_queue *q)
395{
396 q->ksm = NULL;
397}
include/linux/blkdev.h+30−0
@@ -1583,6 +1583,12 @@ struct blk_integrity *bdev_get_integrity(struct block_device *bdev) · 1582 unmodified lines
1583 return blk_get_integrity(bdev->bd_disk);1583 return blk_get_integrity(bdev->bd_disk);
1584}1584}
1585 1585
1586static inline bool
1587blk_integrity_queue_supports_integrity(struct request_queue *q)
1588{
1589 return q->integrity.profile;
1590}
1591
1586static inline bool blk_integrity_rq(struct request *rq)1592static inline bool blk_integrity_rq(struct request *rq)
1587{1593{
1588 return rq->cmd_flags & REQ_INTEGRITY;1594 return rq->cmd_flags & REQ_INTEGRITY;
@@ -1663,6 +1669,11 @@ static inline struct blk_integrity *blk_get_integrity(struct gendisk *disk) · 74 unmodified lines
1663{1669{
1664 return NULL;1670 return NULL;
1665}1671}
1672static inline bool
1673blk_integrity_queue_supports_integrity(struct request_queue *q)
1674{
1675 return false;
1676}
1666static inline int blk_integrity_compare(struct gendisk *a, struct gendisk *b)1677static inline int blk_integrity_compare(struct gendisk *a, struct gendisk *b)
1667{1678{
1668 return 0;1679 return 0;
@@ -1714,6 +1725,25 @@ static inline struct bio_vec *rq_integrity_vec(struct request *rq) · 45 unmodified lines
1714 1725
1715#endif /* CONFIG_BLK_DEV_INTEGRITY */1726#endif /* CONFIG_BLK_DEV_INTEGRITY */
1716 1727
1728#ifdef CONFIG_BLK_INLINE_ENCRYPTION
1729
1730bool blk_ksm_register(struct blk_keyslot_manager *ksm, struct request_queue *q);
1731
1732void blk_ksm_unregister(struct request_queue *q);
1733
1734#else /* CONFIG_BLK_INLINE_ENCRYPTION */
1735
1736static inline bool blk_ksm_register(struct blk_keyslot_manager *ksm,
1737 struct request_queue *q)
1738{
1739 return true;
1740}
1741
1742static inline void blk_ksm_unregister(struct request_queue *q) { }
1743
1744#endif /* CONFIG_BLK_INLINE_ENCRYPTION */
1745
1746
1717struct block_device_operations {1747struct block_device_operations {
1718 int (*open) (struct block_device *, fmode_t);1748 int (*open) (struct block_device *, fmode_t);
1719 void (*release) (struct gendisk *, fmode_t);1749 void (*release) (struct gendisk *, fmode_t);