All of lore.kernel.org
 help / color / mirror / Atom feed
From: "Michael S. Tsirkin" <mst@redhat.com>
To: Linlin Zhang <linlin.zhang@oss.qualcomm.com>
Cc: Max Gurtovoy <mgurtovoy@nvidia.com>,
	Stefan Hajnoczi <stefanha@redhat.com>,
	virtio-dev@lists.linux.dev, ebiggers@kernel.org,
	neeraj.soni@oss.qualcomm.com
Subject: Re: [PATCH v3 0/2] virtio-blk: Add inline encryption support
Date: Tue, 13 Oct 2026 14:08:46 -0400	[thread overview]
Message-ID: <20261013140501-mutt-send-email-mst@kernel.org> (raw)
In-Reply-To: <7a95c6b2-0a7e-4322-ad77-4e3ea13efdbd@oss.qualcomm.com>

On Wed, Oct 14, 2026 at 12:23:16AM +0800, Linlin Zhang wrote:
> 
> 
> On 10/13/2026 6:33 AM, Michael S. Tsirkin wrote:
> > On Sat, Oct 10, 2026 at 06:54:06PM +0800, Linlin Zhang wrote:
> >>
> >>
> >> On 10/9/2026 8:25 PM, Michael S. Tsirkin wrote:
> >>> On Fri, Oct 09, 2026 at 07:21:13PM +0800, Linlin Zhang wrote:
> >>>>
> >>>>
> >>>> On 10/8/2026 6:15 PM, Michael S. Tsirkin wrote:
> >>>>> On Thu, Oct 08, 2026 at 05:17:30PM +0800, Linlin Zhang wrote:
> >>>>>>
> >>>>>>
> >>>>>> On 9/30/2026 6:46 AM, Max Gurtovoy wrote:
> >>>>>>>
> >>>>>>> On 24/09/2026 12:35, Linlin Zhang wrote:
> >>>>>>>>
> >>>>>>>> On 9/22/2026 9:14 PM, Stefan Hajnoczi wrote:
> >>>>>>>>> On Tue, Sep 22, 2026 at 12:29:37PM +0800, Linlin Zhang wrote:
> >>>>>>>>>>
> >>>>>>>>>> On 9/18/2026 5:08 AM, Stefan Hajnoczi wrote:
> >>>>>>>>>>> On Sun, Sep 13, 2026 at 09:16:13AM -0700, Linlin Zhang wrote:
> >>>>>>>>>>>> From: linlzhan <linlin.zhang@oss.qualcomm.com>
> >>>>>>>>>>>>
> >>>>>>>>>>>> This series adds virtio-blk inline encryption support for devices backed
> >>>>>>>>>>>> by storage hardware with an inline crypto engine.
> >>>>>>>>>>>>
> >>>>>>>>>>>> The protocol exposes device capabilities such as keyslot count, maximum
> >>>>>>>>>>>> DUN size, and supported key types. Encrypted requests identify a
> >>>>>>>>>>>> provisioned keyslot and carry a 256-bit DUN. Key management and crypto
> >>>>>>>>>>>> capability discovery use the block device control virtqueue.
> >>>>>>>>>>>>
> >>>>>>>>>>>> The control virtqueue is defined as a generic framework so that its
> >>>>>>>>>>>> buffer layout and queue placement are independent of any particular
> >>>>>>>>>>>> control command. Inline encryption then builds on this framework with
> >>>>>>>>>>>> explicit crypto command formats, capability validation, and keyslot
> >>>>>>>>>>>> state semantics.
> >>>>>>>>>>>>
> >>>>>>>>>>>> All key related operatios are handled in the control virtqueue, and
> >>>>>>>>>>>> the crypto I/O request is handled in the request queue.
> >>>>>>>>>>>>
> >>>>>>>>>>>> For background on inline encryption in UFS and eMMC storage, see:
> >>>>>>>>>>>> https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/tree/Documentation/block/inline-encryption.rst
> >>>>>>>>>>>>
> >>>>>>>>>>>> changes in v3:
> >>>>>>>>>>>>   - Add a control virtqueue
> >>>>>>>>>>>>   - Move key program/evict/derive_sw_secret/generate/prepare/import to
> >>>>>>>>>>>>     the control virtqueue
> >>>>>>>>>>> Thank you. This was a big change, especially if you already have an
> >>>>>>>>>>> implementation. I appreciate it!
> >>>>>>>>>>>
> >>>>>>>>>>> My main feedback is that the new control virtqueue commands are not yet
> >>>>>>>>>>> documented in enough detail so that implementors could implement them.
> >>>>>>>>>>> Once you've decided on the precise semantics, error codes, etc and added
> >>>>>>>>>>> them to the spec, then this will round off the inline encryption
> >>>>>>>>>>> feature. I look forward to reviewing that in the future.
> >>>>>>>>>>>
> >>>>>>>>>> Thanks a lot for your comment!
> >>>>>>>>>>
> >>>>>>>>>> Would you please help clarify what the precise semantics are about? detail
> >>>>>>>>>> introduction of the filed in the inline encryption control command struct?
> >>>>>>>>>> like struct virtio_blk_crypto_key_desc?
> >>>>>>>>> By precise semantics, I mean specifying not just the constants and
> >>>>>>>>> structs, but documenting what each command does and how it can fail.
> >>>>>>>>> Each of the key slot programming commands needs this. There should be at
> >>>>>>>>> least one paragraph for each of VIRTIO_BLK_T_CRYPTO_KEYSLOT_PROGRAM,
> >>>>>>>>> VIRTIO_BLK_T_CRYPTO_KEYSLOT_EVICT, VIRTIO_BLK_T_CRYPTO_DERIVE_SW_SECRET,
> >>>>>>>>> VIRTIO_BLK_T_CRYPTO_GENERATE_KEY, VIRTIO_BLK_T_CRYPTO_IMPORT_KEY, or
> >>>>>>>>> VIRTIO_BLK_T_CRYPTO_PREPARE_KEY.
> >>>>>>>>>
> >>>>>>>>> For example:
> >>>>>>>>>
> >>>>>>>>> The VIRTIO_BLK_T_CRYPTO_KEYSLOT_EVICT command empties a key slot so that
> >>>>>>>>> key information is removed and the key slot cannot be used until it is
> >>>>>>>>> programmed again. The key slot index is specified by struct
> >>>>>>>>> virtio_blk_crypto_key_desc \field{slot} and all other fields in the
> >>>>>>>>> struct are ignored. The command succeeds with VIRTIO_BLK_S_OK if the key
> >>>>>>>>> slot index is valid, including if the slot is already empty. If the key
> >>>>>>>>> slot index is invalid, the command fails with VIRTIO_BLK_S_IOERR.
> >>>>>>>>>
> >>>>>>>>> Stefan
> >>>>>>>> Thanks for the clear example.
> >>>>>>>>
> >>>>>>>> I'll follow the same approach and add explicit normative semantics for
> >>>>>>>> all inline encryption control requests.
> >>>>>>> Can you please explain why we need to introduce yet another VQ type for control?
> >>>>>>>
> >>>>>>> We've added the Admin VQ as a generic VQ for control operations — I'm not sure why it isn't sufficient.
> >>>>>>>
> >>>>>>> Adding control VQ to each device type seems strange to me after adding a generic Admin VQ.
> >>>>>>
> >>>>>> Thanks for your comment! And I agree that the Admin VQ should be considered before
> >>>>>> adding another device-specific control virtqueue.
> >>>>>>
> >>>>>> My understanding is that some of the inline encryption commands(get_crypto_modes/program key
> >>>>>> /derive_sw_secret/evict key) are runtime operations of a specific virtio-blk deivce.
> >>>>>> In particular, different virtio block devices may have different storage hardware sources
> >>>>>> of crypto modes, and keyslot programming and eviction are invoked through the block device's
> >>>>>> keyslot manager, and the programmed virtual keyslots are subsequently referenced by the
> >>>>>> encryption requests submitted on that device's request virtqueues. These commands are
> >>>>>> not about the management operation of device group.
> >>>>>>
> >>>>>> There is also a transport compatibility concern. The current virtio SPEC states that
> >>>>>> 'Devices and drivers utilizing Virtio Over MMIO do not support VIRTIO_F_ADMIN_VQ'.
> >>>>>> virtio MMIO is extensively used, so using the Admin VQ would make the feature unavailable
> >>>>>> for that transport unless the proposal also extended the MMIO transport.
> >>>>>>
> >>>>>> For these reasons, currently I believe that a virtio-blk control virtqueue is the better
> >>>>>> fit: it keeps the complete key lifecycle associated with the block device and remains
> >>>>>> usable across the transports required by the feature.
> >>>>>>
> >>>>>> I would appreciate any feedback or insights from you and Stefan on the V5 patch series
> >>>>>> posted for review before October ASAP.
> >>>>>>
> >>>>>
> >>>>> Fundamentally, it does not make sense to force all vqs to be admin VQs.
> >>>>>
> >>>>> Admin vq would make sense if there is complex resource management going
> >>>>> on - like what is happening with all the flow control things in the
> >>>>> network device, since they have extensive functionality for managing
> >>>>> device resources.
> >>>>>
> >>>>> Random device specific commands - I am not sure we want that.
> >>>>> It remains to be proven.
> >>>>>
> >>>>> But generally why does this go on a special VQ? Is there a reason?
> >>>>>
> >>>>> You define distinct request types seemingly and we are not short on types?
> >>>>>
> >>>>
> >>>> Thanks for your comments!
> >>>>
> >>>> The key programming operation is initiated while preparing a block I/O
> >>>> request and sent to the VQ after the block I/O request has entered the
> >>>> block request queue, before the request is submitted to the device's VQ.
> >>>> see blk_mq_submit_bio(). Using the same virtqueue for both key-program
> >>>> command and normal I/O could lead to bio_queue_enter() called 2 times
> >>>> for the same block queue, which is possible to have deadlock if
> >>>> blk_mq_freeze_queue() is called between above 2 bio_queue_enter() caller.
> >>>>
> >>>> A separate control virtqueue provides an independent execution path for
> >>>> key programming, key eviction, and related operations. It allows these
> >>>> operations to be issued even when the normal request virtqueues are full
> >>>> or unable to make progress. Once the operation completes, the corresponding
> >>>> request can safely reference the programmed virtual keyslot.
> >>>>
> >>>> For such reasons, we believe that a virtio-blk-specific control VQ is a
> >>>> more appropriate mechanism than the standard VQ.
> >>>
> >>> I don't understand. Do these commands go through bio queue?
> >>> Don't they go to VQ directly, just like you would with the control VQ?
> >>>
> >>
> >> Thanks for your comment! my earlier reply conflated two separate concerns.
> >> Let me address them precisely based on Linux kernel code.
> >>
> >> I agree that block-layer queue entry and virtqueue selection are independent
> >> issues.
> >>
> >> Whether key program commands going through bio queue or not depends on the
> >> implementation.
> >>
> >>   - Option A: Reuse the standard block-request helpers (e.g.,
> >>     blk_mq_alloc_request() + blk_execute_rq(), the same pattern virtblk_get_id()
> >>     uses):
> >>     
> >>       - blk_mq_submit_bio()
> >>          -> blk_crypto_submit_bio()   # outer bio_queue_enter() already held
> >>            -> keyslot manager
> >>              -> virtblk_crypto_keyslot_program()
> >>                -> blk_mq_alloc_request()
> >>                  -> blk_queue_enter()    # deadlock: freeze in progress
> >>
> >>     This is not safe at the keyslot-manager call site. Key programming is invoked
> >>     from inside blk_mq_submit_bio(), at a point where the submitting thread already
> >>     holds an unreleased reference from an earlier bio_queue_enter() call on the same
> >>     queue. Calling blk_queue_enter() a second time on the same thread and queue —
> >>     while a concurrent blk_mq_freeze_queue() is in flight — produces a circular wait:
> >>     the freezer blocks waiting for all references (including the outer one) to drop to
> >>     zero, while the submitting thread blocks waiting for the freeze depth to clear.
> >>     Neither can make progress. The problem is not allocation starvation but queue-entry
> >>     reentrancy under freeze. 
> >>
> >>     This is the deadlock concern I mentioned last time.
> >>
> >>   - Option B: Bypass the block layer entirely and raw-submit to a data VQ (i.e.,
> >>     virtqueue_add_sgs() / virtqueue_kick() directly, just targeting a request VQ instead
> >>     of the control VQ):
> >>
> >>     This would indeed sidestep the blk_queue_enter() reentrancy problem. However, it is
> >>     not equivalent to simply adding a new request type — it would require changing the
> >>     data VQ token and completion contract:
> >>
> >>     virtblk_done() — the completion callback registered for every data VQ — unconditionally
> >>     calls blk_mq_rq_from_pdu() and then blk_mq_complete_request() for every buffer it pulls
> >>     off the ring. It assumes every returned token is a struct virtblk_req embedded in a
> >>     blk-mq–allocated struct request. A new specific virtblk_crypto_request injected into a
> >>     data VQ ring is not such an object. The completion path has no way to distinguish it,
> >>     and treating it as one computes a bogus request pointer and corrupts blk-mq tag state.
> >>
> >>     Making this safe would require adding out-of-band type tagging and dispatch logic into
> >>     the hot I/O completion path, making the data-VQ callback polymorphic in a way that
> >>     currently has no precedent.
> >>
> >>     Furthermore, there is a scope mismatch: data VQs are scoped to individual blk-mq hardware
> >>     queues (hctx->queue_num), whereas keyslot management is a per-device operation. On a
> >>     multi-queue device, there is no single canonical data VQ to target. Choosing queue[0]
> >>     arbitrarily concentrates control traffic, causes contention with that hctx's in-flight
> >>     I/O and submission lock (vblk->vqs[i].lock), and can be blocked entirely if that ring
> >>     is saturated.
> >>
> >>     In summary, using a data VQ in this way is implementable in principle, but it would require
> >>     changing the established data-VQ token/completion contract and coupling a device-scoped
> >>     control operation to an arbitrarily chosen hctx-scoped queue.
> > 
> > 
> > Actually even simpler. Option C: spec allows any mix. Linux practically
> > can choose a VQ and dedicates it to the key slot management.
> > It can then submit requests there in any way it wants.
> > No?
> 
> Thanks, this seems a simpler implementation. If I understand correctly, the driver could
> reserve one of the request VQs exclusively for keyslot-management commands and raw-submit
> the commands to that VQ.
> 
> But I see a few issues that may need to be defined:
>   1. This approach depends on VIRTIO_BLK_F_MQ to be negotiated and requires the device to expose
>      at least two request virtqueues. It would therefore provide no usable fallback for a
>      single-queue device.

A control vq is also a vq so ...

>   2. All negotiated queues are exposed through the existing requestq interface, and the
>     spec provides no standardized way to identify one of them as a dedicate queue. Reserving
>     one request VQ for key management would therefore be a driver/backend convention rather
>     than an explicitly negotiated device interface. This also decreasing the code portability.


I don't understand what is code portability.

>   3. The dedicated queue would still use the normal virtio-blk request framing, including
>     struct virtio_blk_outhdr, even though fields such as ioprio and sector have no meaningful
>     semantics for key-management commands.


Not "such as" there are just these two. You can overlay them with different fields, if you prefer.


> This is workable, but it makes the control protocol
>     inherit data-request framing that it does not naturally need.
> 
> If these are acceptable, Option C could avoid adding a new control VQ. But I think the
> queue-selection and feature-dependency rules would still need to be specified explicitly.

FEature dependency, sure. It's a pretty standard thing though.
For queue selection I'd just leave all this to the driver by preference. 


> Could you please help comments about these above concerns? Taking this concern into account,
> I feel a dedicate control queue seems more proper.
> 
> > 
> > 
> >> While the separate control virtqueue provides a direct submission path without entering the
> >> block layer, while also providing a distinct request format, completion callback, lock, and
> >> descriptor pool. This keeps key-management operations separate from blk-mq request/tag
> >> and from the per-hardware-queue I/O completion path.
> >>
> >> Given the above, I prefer to having a new control VQ. I'm appreciated if you have any
> >> insights about it. 
> >>
> >> In addition, the control VQ is currently used for inline encryption. From the virtio
> >> specification perspective, should we state that it is currently used only for inline
> >> encryption, or leave room for future extensions?
> > 


  reply	other threads:[~2026-10-13 18:09 UTC|newest]

Thread overview: 25+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2026-09-13 16:16 [PATCH v3 0/2] virtio-blk: Add inline encryption support Linlin Zhang
2026-09-13 16:16 ` [PATCH v3 1/2] virtio-blk: Add the control virtqueue Linlin Zhang
2026-09-17 20:16   ` Stefan Hajnoczi
2026-09-22 11:10     ` Linlin Zhang
2026-09-13 16:16 ` [PATCH v3 2/2] virtio-blk: Add inline encryption support Linlin Zhang
2026-09-17 21:05   ` Stefan Hajnoczi
2026-09-24  9:32     ` Linlin Zhang
2026-09-17 21:08 ` [PATCH v3 0/2] " Stefan Hajnoczi
2026-09-22  4:29   ` Linlin Zhang
2026-09-22 13:14     ` Stefan Hajnoczi
2026-09-24  9:35       ` Linlin Zhang
2026-09-29 22:46         ` Max Gurtovoy
2026-10-08  9:17           ` Linlin Zhang
2026-10-08 10:15             ` Michael S. Tsirkin
2026-10-09 11:21               ` Linlin Zhang
2026-10-09 12:25                 ` Michael S. Tsirkin
2026-10-10 10:54                   ` Linlin Zhang
2026-10-12 14:51                     ` Linlin Zhang
2026-10-12 22:33                     ` Michael S. Tsirkin
2026-10-13 16:23                       ` Linlin Zhang
2026-10-13 18:08                         ` Michael S. Tsirkin [this message]
2026-10-12 23:12               ` Max Gurtovoy
2026-10-13 16:23                 ` Linlin Zhang
2026-10-13 18:07                   ` Max Gurtovoy
2026-10-13 18:10                     ` Michael S. Tsirkin

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=20261013140501-mutt-send-email-mst@kernel.org \
    --to=mst@redhat.com \
    --cc=ebiggers@kernel.org \
    --cc=linlin.zhang@oss.qualcomm.com \
    --cc=mgurtovoy@nvidia.com \
    --cc=neeraj.soni@oss.qualcomm.com \
    --cc=stefanha@redhat.com \
    --cc=virtio-dev@lists.linux.dev \
    /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 an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.