linux-block.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
From: Satya Tangirala <satyaprateek2357@gmail.com>
To: linux-block@vger.kernel.org, linux-kernel@vger.kernel.org
Cc: Jens Axboe <axboe@kernel.dk>, Eric Biggers <ebiggers@google.com>,
	Satya Tangirala <satyaprateek2357@gmail.com>,
	Satya Tangirala <satyat@google.com>
Subject: [PATCH v4 4/9] block: keyslot-manager: introduce blk_ksm_restrict_dus_to_queue_limits()
Date: Tue,  6 Jul 2021 22:29:38 -0700	[thread overview]
Message-ID: <20210707052943.3960-5-satyaprateek2357@gmail.com> (raw)
In-Reply-To: <20210707052943.3960-1-satyaprateek2357@gmail.com>

From: Satya Tangirala <satyat@google.com>

Not all crypto data unit sizes might be supported by the block layer due to
certain queue limits. This new function checks the queue limits and
appropriately modifies the keyslot manager to reflect only the supported
crypto data unit sizes. blk_ksm_register() runs any given ksm through this
function before actually registering the ksm with a queue.

Signed-off-by: Satya Tangirala <satyat@google.com>
---
 block/keyslot-manager.c | 89 +++++++++++++++++++++++++++++++++++++++++
 1 file changed, 89 insertions(+)

diff --git a/block/keyslot-manager.c b/block/keyslot-manager.c
index 4d0794506d43..01358df66e41 100644
--- a/block/keyslot-manager.c
+++ b/block/keyslot-manager.c
@@ -468,12 +468,101 @@ bool blk_ksm_is_empty(struct blk_keyslot_manager *ksm)
 }
 EXPORT_SYMBOL_GPL(blk_ksm_is_empty);
 
+/*
+ * Restrict the supported data unit sizes of the ksm based on the request queue
+ * limits
+ */
+static unsigned long
+blk_ksm_largest_dus_for_queue_limits(struct blk_keyslot_manager *ksm,
+				     struct request_queue *q)
+{
+	/* The largest possible data unit size we support is PAGE_SIZE. */
+	unsigned long largest_dus = PAGE_SIZE;
+	struct queue_limits *limits = &q->limits;
+
+	/*
+	 * If the queue doesn't support SG gaps, then a bio may have to be split
+	 * between any two bio_vecs.  Since the size of each bio_vec is only
+	 * guaranteed to be a multiple of logical_block_size, logical_block_size
+	 * is also the maximum crypto data unit size that can be supported in
+	 * this case, as bios must not be split in the middle of a data unit.
+	 */
+	if (limits->virt_boundary_mask)
+		largest_dus = queue_logical_block_size(q);
+
+	/*
+	 * Similarly, if chunk_sectors is set and a bio is submitted that
+	 * crosses a chunk boundary, then that bio may have to be split at a
+	 * boundary that is only logical_block_size aligned.  So that limits the
+	 * crypto data unit size to logical_block_size as well.
+	 */
+	if (limits->chunk_sectors)
+		largest_dus = queue_logical_block_size(q);
+
+	/*
+	 * Each bio_vec can be as small as logical_block_size.  Therefore the
+	 * crypto data unit size can't be greater than 'max_segments *
+	 * logical_block_size', as otherwise in the worst case there would be no
+	 * way to process the first data unit without exceeding max_segments.
+	 */
+	largest_dus = min(largest_dus,
+			  rounddown_pow_of_two(limits->max_segments) *
+			  queue_logical_block_size(q));
+
+	return largest_dus;
+}
+
+/**
+ * blk_ksm_register() - Sets the queue's keyslot manager to the provided ksm, if
+ *			compatible
+ * @ksm: The ksm to register
+ * @q: The request_queue to register the ksm to
+ *
+ * Checks if the keyslot manager provided is compatible with the request queue
+ * (i.e. the queue shouldn't also support integrity). After that, the crypto
+ * capabilities of the given keyslot manager are restricted to what the queue
+ * can support based on it's limits. Note that if @ksm won't support any
+ * crypto capabilities if its capabilities are restricted, the queue's ksm is
+ * set to NULL, instead of being set to a pointer to an "empty" @ksm, and @ksm
+ * is *not* modified.
+ *
+ * Return: true if @q's ksm is set to the provided @ksm, false otherwise
+ *	   (in which case @ksm will not have been modified)
+ */
 bool blk_ksm_register(struct blk_keyslot_manager *ksm, struct request_queue *q)
 {
+	unsigned long largest_dus_allowed;
+	unsigned int dus_allowed_mask;
+	bool dus_was_restricted = false;
+	int i;
+
 	if (blk_integrity_queue_supports_integrity(q)) {
 		pr_warn("Integrity and hardware inline encryption are not supported together. Disabling hardware inline encryption.\n");
 		return false;
 	}
+
+	largest_dus_allowed = blk_ksm_largest_dus_for_queue_limits(ksm, q);
+	dus_allowed_mask = (largest_dus_allowed << 1) - 1;
+
+	/*
+	 * Check if ksm will become empty if we clear disallowed data unit
+	 * sizes (in which case, don't modify the ksm)
+	 */
+	if (blk_ksm_is_empty_mask(ksm, dus_allowed_mask))
+		return false;
+
+	/* Clear all unsupported data unit sizes. */
+	for (i = 0; i < ARRAY_SIZE(ksm->crypto_modes_supported); i++) {
+		if (ksm->crypto_modes_supported[i] & (~dus_allowed_mask))
+			dus_was_restricted = true;
+		ksm->crypto_modes_supported[i] &= dus_allowed_mask;
+	}
+
+	if (dus_was_restricted) {
+		pr_warn("Device: %s - Disallowed use of encryption data unit sizes above %lu bytes with inline encryption hardware because of device request queue limits.\n",
+			q->backing_dev_info->dev_name, largest_dus_allowed);
+	}
+
 	q->ksm = ksm;
 	return true;
 }
-- 
2.25.1


  parent reply	other threads:[~2021-07-07  5:30 UTC|newest]

Thread overview: 21+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2021-07-07  5:29 [PATCH v4 0/9] ensure bios aren't split in middle of crypto data unit Satya Tangirala
2021-07-07  5:29 ` [PATCH v4 1/9] block: introduce blk_ksm_is_empty() Satya Tangirala
2021-07-23 16:45   ` Eric Biggers
2021-07-07  5:29 ` [PATCH v4 2/9] block: blk-crypto: introduce blk_crypto_bio_sectors_alignment() Satya Tangirala
2021-07-23 16:45   ` Eric Biggers
2021-07-07  5:29 ` [PATCH v4 3/9] block: introduce bio_required_sector_alignment() Satya Tangirala
2021-07-23 16:46   ` Eric Biggers
2021-07-07  5:29 ` Satya Tangirala [this message]
2021-07-23 17:08   ` [PATCH v4 4/9] block: keyslot-manager: introduce blk_ksm_restrict_dus_to_queue_limits() Eric Biggers
2021-07-07  5:29 ` [PATCH v4 5/9] ufshcd: handle error from blk_ksm_register() Satya Tangirala
2021-07-23 17:13   ` Eric Biggers
2021-07-07  5:29 ` [PATCH v4 6/9] mmc: " Satya Tangirala
2021-07-07  5:29 ` [PATCH v4 7/9] dm: " Satya Tangirala
2021-07-23 17:26   ` Eric Biggers
2021-07-07  5:29 ` [PATCH v4 8/9] blk-merge: Ensure bios aren't split in middle of a crypto data unit Satya Tangirala
2021-07-23 18:11   ` Eric Biggers
2021-07-07  5:29 ` [PATCH v4 9/9] block: add WARN_ON_ONCE() to bio_split() for sector alignment Satya Tangirala
2021-07-23 17:30   ` Eric Biggers
2021-07-23 16:49 ` [PATCH v4 0/9] ensure bios aren't split in middle of crypto data unit Eric Biggers
2021-07-23 17:52   ` Eric Biggers
2021-07-24  7:36 ` Christoph Hellwig

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20210707052943.3960-5-satyaprateek2357@gmail.com \
    --to=satyaprateek2357@gmail.com \
    --cc=axboe@kernel.dk \
    --cc=ebiggers@google.com \
    --cc=linux-block@vger.kernel.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=satyat@google.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).