From: Linlin Zhang <linlin.zhang@oss.qualcomm.com>
To: ebiggers@kernel.org, axboe@kernel.dk, mst@redhat.com,
jasowangio@gmail.com, James.Bottomley@HansenPartnership.com,
martin.petersen@oracle.com, robh@kernel.org, krzk+dt@kernel.org,
conor+dt@kernel.org, linux-block@vger.kernel.org,
linux-crypto@vger.kernel.org, linux-scsi@vger.kernel.org,
virtualization@lists.linux.dev, devicetree@vger.kernel.org,
linux-arm-msm@vger.kernel.org
Cc: neeraj.soni@oss.qualcomm.com, gaurav.kashyap@oss.qualcomm.com,
mani@kernel.org, andersson@kernel.org, konradybcio@kernel.org,
bvanassche@acm.org, alim.akhtar@samsung.com,
avri.altman@sandisk.com, stefanha@redhat.com,
pbonzini@redhat.com, eperezma@redhat.com,
xuanzhuo@linux.alibaba.com, linux-kernel@vger.kernel.org
Subject: [PATCH v1 05/11] blk-crypto: add slot-based inline encryption path
Date: Thu, 27 Aug 2026 09:07:14 -0700 [thread overview]
Message-ID: <20260827160806.1295313-6-linlin.zhang@oss.qualcomm.com> (raw)
In-Reply-To: <20260827160806.1295313-1-linlin.zhang@oss.qualcomm.com>
From: linlzhan <linlin.zhang@oss.qualcomm.com>
For the virtio-blk inline encryption use case, the guest kernel goes
through the normal blk_crypto_key programming flow via SMC call in a
virtual slot format before I/O starts. It then requests the host to
handle that I/O with the key programmed into the corresponding physical
keyslot.
Introduce a "slot path" that lets a bio carry a pre-programmed physical
ICE keyslot index rather than a blk_crypto_key pointer. Add struct
blk_crypto_slot, containing the physical slot index (phy_slot) and
data_unit_size_bits, and embed it in struct bio_crypt_ctx alongside the
existing bc_key pointer. A NULL bc_key indicates the slot path.
Provide bio_crypt_set_ctx_by_slot() as the caller-facing API for this
path. Update the internal consumers of bio_crypt_ctx to handle both
paths:
- __bio_crypt_advance() and bio_crypt_dun_is_contiguous() use
bc_slot.data_unit_size_bits to update the DUN when bc_key is NULL.
- bio_crypt_ctx_compatible() compares phy_slot and data_unit_size_bits
when bc_key is NULL, preserving request-merging for slot-based bios.
- __blk_crypto_submit_bio() short-circuits for the slot path: if the
device exposes a crypto_profile the bio is passed through as-is;
otherwise it fails with BLK_STS_NOTSUPP. The software fallback is
not attempted since the guest has no key material.
- blk_crypto_rq_get_keyslot() skips kernel-side keyslot allocation
when bc_key is NULL.
There is no functional change to the existing key-based path.
Signed-off-by: linlzhan <linlin.zhang@oss.qualcomm.com>
---
block/blk-crypto-internal.h | 2 +-
block/blk-crypto.c | 57 ++++++++++++++++++++++++++++++++++---
include/linux/blk-crypto.h | 25 ++++++++++++++++
3 files changed, 79 insertions(+), 5 deletions(-)
diff --git a/block/blk-crypto-internal.h b/block/blk-crypto-internal.h
index 2c7a0446572a..04035d237f03 100644
--- a/block/blk-crypto-internal.h
+++ b/block/blk-crypto-internal.h
@@ -176,7 +176,7 @@ static inline void bio_crypt_do_front_merge(struct request *rq,
blk_status_t __blk_crypto_rq_get_keyslot(struct request *rq);
static inline blk_status_t blk_crypto_rq_get_keyslot(struct request *rq)
{
- if (blk_crypto_rq_is_encrypted(rq))
+ if (blk_crypto_rq_is_encrypted(rq) && rq->crypt_ctx->bc_key)
return __blk_crypto_rq_get_keyslot(rq);
return BLK_STS_OK;
}
diff --git a/block/blk-crypto.c b/block/blk-crypto.c
index bc3a9f59574b..2212d06d3c11 100644
--- a/block/blk-crypto.c
+++ b/block/blk-crypto.c
@@ -113,11 +113,31 @@ void bio_crypt_set_ctx(struct bio *bio, const struct blk_crypto_key *key,
bc->bc_key = key;
memcpy(bc->bc_dun, dun, sizeof(bc->bc_dun));
+ memset(&bc->bc_slot, 0, sizeof(bc->bc_slot));
bio->bi_crypt_context = bc;
}
EXPORT_SYMBOL_GPL(bio_crypt_set_ctx);
+void bio_crypt_set_ctx_by_slot(struct bio *bio,
+ const struct blk_crypto_slot *slot,
+ const u64 dun[BLK_CRYPTO_DUN_ARRAY_SIZE],
+ gfp_t gfp_mask)
+{
+ struct bio_crypt_ctx *bc;
+
+ WARN_ON_ONCE(!(gfp_mask & __GFP_DIRECT_RECLAIM));
+
+ bc = mempool_alloc(bio_crypt_ctx_pool, gfp_mask);
+
+ bc->bc_key = NULL;
+ bc->bc_slot = *slot;
+ memcpy(bc->bc_dun, dun, sizeof(bc->bc_dun));
+
+ bio->bi_crypt_context = bc;
+}
+EXPORT_SYMBOL_GPL(bio_crypt_set_ctx_by_slot);
+
void __bio_crypt_free_ctx(struct bio *bio)
{
mempool_free(bio->bi_crypt_context, bio_crypt_ctx_pool);
@@ -156,8 +176,12 @@ void __bio_crypt_advance(struct bio *bio, unsigned int bytes)
{
struct bio_crypt_ctx *bc = bio->bi_crypt_context;
- bio_crypt_dun_increment(bc->bc_dun,
- bytes >> bc->bc_key->data_unit_size_bits);
+ if (bc->bc_key)
+ bio_crypt_dun_increment(bc->bc_dun,
+ bytes >> bc->bc_key->data_unit_size_bits);
+ else if (bc->bc_slot.data_unit_size_bits)
+ bio_crypt_dun_increment(bc->bc_dun,
+ bytes >> bc->bc_slot.data_unit_size_bits);
}
/*
@@ -169,7 +193,14 @@ bool bio_crypt_dun_is_contiguous(const struct bio_crypt_ctx *bc,
const u64 next_dun[BLK_CRYPTO_DUN_ARRAY_SIZE])
{
int i;
- unsigned int carry = bytes >> bc->bc_key->data_unit_size_bits;
+ unsigned int carry;
+
+ if (bc->bc_key)
+ carry = bytes >> bc->bc_key->data_unit_size_bits;
+ else if (bc->bc_slot.data_unit_size_bits) {
+ carry = bytes >> bc->bc_slot.data_unit_size_bits;
+ } else
+ return false;
for (i = 0; i < BLK_CRYPTO_DUN_ARRAY_SIZE; i++) {
if (bc->bc_dun[i] + carry != next_dun[i])
@@ -198,7 +229,12 @@ static bool bio_crypt_ctx_compatible(struct bio_crypt_ctx *bc1,
if (!bc1)
return !bc2;
- return bc2 && bc1->bc_key == bc2->bc_key;
+ if (bc1->bc_key)
+ return bc2 && bc1->bc_key == bc2->bc_key;
+ else
+ return bc2 && !bc2->bc_key &&
+ bc1->bc_slot.phy_slot == bc2->bc_slot.phy_slot &&
+ bc1->bc_slot.data_unit_size_bits == bc2->bc_slot.data_unit_size_bits;
}
bool bio_crypt_rq_ctx_compatible(struct request *rq, struct bio *bio)
@@ -260,6 +296,19 @@ bool __blk_crypto_submit_bio(struct bio *bio)
return false;
}
+ if (!bc_key) {
+ /*
+ * Slot path: the ICE keyslot was pre-programmed by the
+ * hypervisor. The target device must natively support inline
+ * encryption; there is no fallback for slot-based crypto.
+ */
+ if (!bdev_get_queue(bdev)->crypto_profile) {
+ bio_endio_status(bio, BLK_STS_NOTSUPP);
+ return false;
+ }
+ return true;
+ }
+
/*
* If the device does not natively support the encryption context, try to use
* the fallback if available.
diff --git a/include/linux/blk-crypto.h b/include/linux/blk-crypto.h
index 938ff536838c..33ae52b77522 100644
--- a/include/linux/blk-crypto.h
+++ b/include/linux/blk-crypto.h
@@ -119,9 +119,28 @@ struct blk_crypto_key {
#define BLK_CRYPTO_MAX_IV_SIZE 32
#define BLK_CRYPTO_DUN_ARRAY_SIZE (BLK_CRYPTO_MAX_IV_SIZE / sizeof(u64))
+/**
+ * struct blk_crypto_slot - physical slot context for slot-based inline crypto
+ * @phy_slot: Physical ICE keyslot index (already resolved from virt).
+ * @data_unit_size_bits: log2 of the encryption data unit size; used by
+ * __bio_crypt_advance() to increment the DUN correctly
+ * when a bio is split. 0 means unknown/unset.
+ *
+ * Used when a bio carries inline crypto context by physical slot index rather
+ * than by a blk_crypto_key pointer (i.e. bc_key == NULL in bio_crypt_ctx).
+ * Set by crypto_vblk when building the bio for a GVM VIRTIO_BLK_T_CRYPTO_IN/OUT
+ * request; left zeroed for all other bio types.
+ */
+struct blk_crypto_slot {
+ unsigned int phy_slot;
+ unsigned int data_unit_size_bits;
+};
+
/**
* struct bio_crypt_ctx - an inline encryption context
* @bc_key: the key, algorithm, and data unit size to use
+ * @bc_slot: physical slot + data_unit_size_bits for slot-based crypto
+ * (used when bc_key == NULL)
* @bc_dun: the data unit number (starting IV) to use
*
* A bio_crypt_ctx specifies that the contents of the bio will be encrypted (for
@@ -130,6 +149,7 @@ struct blk_crypto_key {
*/
struct bio_crypt_ctx {
const struct blk_crypto_key *bc_key;
+ struct blk_crypto_slot bc_slot;
u64 bc_dun[BLK_CRYPTO_DUN_ARRAY_SIZE];
};
@@ -152,6 +172,11 @@ void bio_crypt_set_ctx(struct bio *bio, const struct blk_crypto_key *key,
const u64 dun[BLK_CRYPTO_DUN_ARRAY_SIZE],
gfp_t gfp_mask);
+void bio_crypt_set_ctx_by_slot(struct bio *bio,
+ const struct blk_crypto_slot *slot,
+ const u64 dun[BLK_CRYPTO_DUN_ARRAY_SIZE],
+ gfp_t gfp_mask);
+
bool bio_crypt_dun_is_contiguous(const struct bio_crypt_ctx *bc,
unsigned int bytes,
const u64 next_dun[BLK_CRYPTO_DUN_ARRAY_SIZE]);
--
2.34.1
next prev parent reply other threads:[~2026-08-27 16:08 UTC|newest]
Thread overview: 15+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-08-27 16:07 [PATCH v1 00/11] FBE virtualization: inline encryption for virtio-blk guests Linlin Zhang
2026-08-27 16:07 ` [PATCH v1 01/11] virtio_blk: add inline encryption support Linlin Zhang
2026-08-27 16:07 ` [PATCH v1 02/11] soc: qcom: add crypto_virt backend for virtio-blk inline crypto Linlin Zhang
2026-08-27 16:07 ` [PATCH v1 03/11] soc: qcom: crypto_virt: add support for create, prepare and import keys Linlin Zhang
2026-08-27 16:07 ` [PATCH v1 04/11] dt-bindings: soc: qcom: add binding for qcom,crypto-virt Linlin Zhang
2026-08-27 16:07 ` Linlin Zhang [this message]
2026-08-27 16:07 ` [PATCH v1 06/11] scsi: ufs: core: add slot path to ufshcd_prepare_lrbp_crypto Linlin Zhang
2026-08-27 16:07 ` [PATCH v1 07/11] blk-crypto: move bio_crypt_dun_increment() to the public header Linlin Zhang
2026-08-27 16:07 ` [PATCH v1 08/11] block: add /dev/blk-crypto-proxy for host-side virtio-blk inline encryption Linlin Zhang
2026-08-27 16:07 ` [PATCH v1 09/11] soc: qcom: add ICE keyslot partitioning driver for guest VMs Linlin Zhang
2026-08-27 16:07 ` [PATCH v1 10/11] blk-crypto: add slot_offset to blk_crypto_profile Linlin Zhang
2026-08-27 16:07 ` [PATCH v1 11/11] scsi: ufs: ufs-qcom: support ICE keyslot partitioning for guest VMs Linlin Zhang
2026-08-27 18:42 ` [PATCH v1 00/11] FBE virtualization: inline encryption for virtio-blk guests Eric Biggers
2026-08-28 15:37 ` Linlin Zhang
2026-08-28 15:56 ` Linlin Zhang
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=20260827160806.1295313-6-linlin.zhang@oss.qualcomm.com \
--to=linlin.zhang@oss.qualcomm.com \
--cc=James.Bottomley@HansenPartnership.com \
--cc=alim.akhtar@samsung.com \
--cc=andersson@kernel.org \
--cc=avri.altman@sandisk.com \
--cc=axboe@kernel.dk \
--cc=bvanassche@acm.org \
--cc=conor+dt@kernel.org \
--cc=devicetree@vger.kernel.org \
--cc=ebiggers@kernel.org \
--cc=eperezma@redhat.com \
--cc=gaurav.kashyap@oss.qualcomm.com \
--cc=jasowangio@gmail.com \
--cc=konradybcio@kernel.org \
--cc=krzk+dt@kernel.org \
--cc=linux-arm-msm@vger.kernel.org \
--cc=linux-block@vger.kernel.org \
--cc=linux-crypto@vger.kernel.org \
--cc=linux-kernel@vger.kernel.org \
--cc=linux-scsi@vger.kernel.org \
--cc=mani@kernel.org \
--cc=martin.petersen@oracle.com \
--cc=mst@redhat.com \
--cc=neeraj.soni@oss.qualcomm.com \
--cc=pbonzini@redhat.com \
--cc=robh@kernel.org \
--cc=stefanha@redhat.com \
--cc=virtualization@lists.linux.dev \
--cc=xuanzhuo@linux.alibaba.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