From: "Alexandre Courbot" <acourbot@nvidia.com>
To: "Alistair Francis" <alistair23@gmail.com>
Cc: <lukas@wunner.de>, <linux-cxl@vger.kernel.org>,
<akpm@linux-foundation.org>, <Jonathan.Cameron@huawei.com>,
<rust-for-linux@vger.kernel.org>, <linux-kernel@vger.kernel.org>,
<jic23@kernel.org>, <bhelgaas@google.com>,
<alistair@alistair23.me>, <djbw@kernel.org>,
<linux-pci@vger.kernel.org>, <wilfred.mallawa@wdc.com>,
<a.hindborg@kernel.org>, <gregkh@linuxfoundation.org>,
<alex.gaynor@gmail.com>, <aliceryhl@google.com>,
<benno.lossin@proton.me>, <boqun.feng@gmail.com>,
<bjorn3_gh@protonmail.com>, <tmgross@umich.edu>,
<gary@garyguo.net>, <ojeda@kernel.org>,
"Jonathan Cameron" <jonathan.cameron@oss.qualcomm.com>
Subject: Re: [PATCH v4 10/22] lib: rspdm: Initial commit of Rust SPDM
Date: Thu, 15 Oct 2026 16:29:55 +0900 [thread overview]
Message-ID: <DM58HRC3DHSS.1YC0E53ZXANT4@nvidia.com> (raw)
In-Reply-To: <CAKmqyKNEup=x+bwmPD_8x0s4ssPkqFnQtSGqJ_82z9oDP=A6cA@mail.gmail.com>
On Thu Oct 15, 2026 at 12:06 PM JST, Alistair Francis wrote:
<...>
>> > +/// The current SPDM session state for a device.
>> > +///
>> > +/// Concurrent access is serialised by wrapping the whole struct in a
>> > +/// `Mutex<SpdmState>` at the FFI boundary, so `spdm_authenticate()` callers
>> > +/// run one at a time and the locked `&mut SpdmState` is the only way to
>> > +/// reach the inner fields.
>> > +///
>> > +/// `dev`: Responder device. Used for error reporting and passed to @transport.
>> > +/// `transport`: Transport function to perform one message exchange.
>> > +/// `transport_priv`: Transport private data.
>> > +/// `transport_sz`: Maximum message size the transport is capable of (in bytes).
>> > +/// Used as DataTransferSize in GET_CAPABILITIES exchange.
>> > +/// `validate`: Function to validate additional leaf certificate requirements.
>> > +///
>> > +/// `version`: Maximum common supported version of requester and responder.
>> > +/// Negotiated during GET_VERSION exchange.
>>
>> Field documentation should be their own doccomments before each
>> individual field (see [1] for an example and general good practices when
>> writing Rust doccomments).
>>
>> [1] https://doc.rust-lang.org/rust-by-example/meta/doc.html
>>
>> > +#[expect(dead_code)]
>> > +pub(crate) struct SpdmState {
>> > + pub(crate) dev: *mut bindings::device,
>>
>> This makes me very nervous. I see this is passed to C callbacks. We need
>> to maintain the guarantee that the device still exists, so an
>> `ARef<Device>`, from which you obtain a pointer to pass to the C
>> callbacks, should be the minimum here. Does the device also need to be
>> bound? Looking at `drivers/pci/cma.c` it seems to be. Then this needs to
>> be a `&Device<Bound>`, with a lifetime to `SpdmState` so callers only
>> use it while the device is bound.
>
> Good point, I have converted this to use a `&Device<Bound>`
Another related point of feedback is that this code seems to be
designed to interact with C drivers exclusively - i.e. I don't see a
publicly exported Rust API.
That's probably what has guided the current design of storing pointers,
as that's what the C functions expect; and the C side is also
responsible for taking care of lifetime and bound device status, so in
that context using a `&Device<Bound>` will be of little help as it will
need to be forged by trusting that the calling C code knows what it is
doing.
I think it would be helpful on the contrary to design things around a
Rust API, on top of which the C FFI is built. That way you would have to
work with properly bound references, and have a proof that the model is
viable before exposing it to C. Also I guess Rust drivers will want to
use this at some point, so better design with that in mind from the
get-go.
Also related, what is the reason for having this code in `lib`? Why not
make this a regular kernel module?
>
>>
>> Just storing a C pointer and passing it whenever a function needs it
>> cancels the purpose of using Rust and make the safety requirements of
>> the callback you pass it to impossible to guarantee, as nothing enforces
>> that the device still exists or is in a valid state when they are
>> invoked.
>>
>> > + pub(crate) transport: bindings::spdm_transport,
>> > + pub(crate) transport_priv: *mut c_void,
>>
>> Here I also suspect we want to define some kind of ownership model for
>> the private data instead of hoping that the pointer is still valid when
>> we use it.
>
> Any ideas here? It's just a pointer that we pass back to C when
> calling the `transport_function()`, I'm not clear on what we could do
> to ensure it's still valid.
I suspect something close to what `fwctl` does? Basically `SpdmState`
would store a reference to a generic type, which outlives the SPDM
driver bound time. That's also why having the Rust API first is helpful,
as it will provide the lifetime that needs to be outlived.
Looking at the example in `cma.c`, the private data appears to be
`host.doe_mb`, which exists before `spdm_create` is called and is still
there after `spdm_destroy`, so that seems to be the correct model, i.e.
there should be no need to transfer full ownership of the private data
to the SPDM driver - a reference should be sufficient.
Actually thinking some more about it seems like the `fwctl` Rust
bindings could be a good model to follow. They are simple and adopt a
similar pattern of a sub-component of a larger driver that never
outlives its parent.
<...>
>>
>> > +impl<'a, 'c> Validate<'c, Untrusted<&'a [u8]>> for SpdmHeader {
>> > + type Err = Error;
>> > +
>> > + type Context = &'c SpdmState;
>> > +
>> > + fn validate(unvalidated: &[u8], _context: &'c SpdmState) -> Result<Self, Self::Err> {
>> > + Ok(SpdmHeader {
>> > + version: *unvalidated.get(0).ok_or(EIO)?,
>> > + code: *unvalidated.get(1).ok_or(EIO)?,
>> > + param1: *unvalidated.get(2).ok_or(EIO)?,
>> > + param2: *unvalidated.get(3).ok_or(EIO)?,
>> > + })
>>
>> Here you will definitely want to leverage zerocopy's `FromBytes` trait.
>
> I was hoping not too actually.
>
> The SPDM responses are a bit complex. For example NegotiateAlgsRsp has
> multiple dynamically sized arrays, and the fields change based on the
> version.
>
> Using zerocopy means we need packed structs and even then I'm not
> clear on how we can handle the KVec<u32> or even the
> KVec<RespAlgStruct> nicley.
>
> The current approach has the obvious downside of copying the data, but
> as the data is pretty small in the scheme of things and not part of a
> hot path, I think the tradeoff of copying the data with much cleaner
> and easier to understand code is worth it.
>
> Maybe in the future zerocopy could be a performance improvement, but I
> think right now it's a large complexity overhead in this case.
>
> Note that obviously SpdmHeader is not complex, but I think they should
> all follow the same pattern.
For more complex structures sure, but in the case of `SpdmHeader`
zerocopy looks like it would work nicely? It also supports performing a
copy (see `read_from_bytes` and `read_from_prefix`).
next prev parent reply other threads:[~2026-10-15 7:30 UTC|newest]
Thread overview: 56+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-09-28 1:11 [PATCH v4 00/22] lib: Rust implementation of SPDM alistair23
2026-09-28 1:11 ` [PATCH v4 01/22] virt: coco: change tsm_register() to use a const struct alistair23
2026-09-28 1:41 ` sashiko-bot
2026-09-28 1:11 ` [PATCH v4 02/22] rust: transmute: add `cast_slice[_mut]` functions alistair23
2026-09-28 1:35 ` sashiko-bot
2026-10-14 15:16 ` Alexandre Courbot
2026-09-28 1:11 ` [PATCH v4 03/22] rust: create basic untrusted data API alistair23
2026-09-28 1:41 ` sashiko-bot
2026-10-14 15:17 ` Alexandre Courbot
2026-09-28 1:11 ` [PATCH v4 04/22] rust: validate: add `Validate` trait alistair23
2026-09-28 1:41 ` sashiko-bot
2026-09-28 1:11 ` [PATCH v4 05/22] X.509: Make certificate parser public alistair23
2026-09-28 1:39 ` sashiko-bot
2026-09-28 1:11 ` [PATCH v4 06/22] X.509: Parse Subject Alternative Name in certificates alistair23
2026-09-28 1:39 ` sashiko-bot
2026-09-28 1:11 ` [PATCH v4 07/22] X.509: Move certificate length retrieval into new helper alistair23
2026-09-28 1:36 ` sashiko-bot
2026-09-28 1:11 ` [PATCH v4 08/22] rust: add bindings for hash.h alistair23
2026-09-28 1:43 ` sashiko-bot
2026-09-28 1:11 ` [PATCH v4 09/22] rust: error: impl From<FromBytesWithNulError> for Kernel Error alistair23
2026-09-28 1:36 ` sashiko-bot
2026-09-28 1:11 ` [PATCH v4 10/22] lib: rspdm: Initial commit of Rust SPDM alistair23
2026-09-28 1:45 ` sashiko-bot
2026-10-14 15:17 ` Alexandre Courbot
2026-10-15 3:06 ` Alistair Francis
2026-10-15 7:29 ` Alexandre Courbot [this message]
2026-09-28 1:11 ` [PATCH v4 11/22] PCI/TSM: Rename pf0 to host alistair23
2026-09-28 1:41 ` sashiko-bot
2026-09-28 1:11 ` [PATCH v4 12/22] PCI/TSM: Support connecting to PCIe CMA devices alistair23
2026-09-28 1:43 ` sashiko-bot
2026-09-28 1:11 ` [PATCH v4 13/22] PCI/CMA: Add a PCI TSM CMA driver using SPDM alistair23
2026-09-28 1:43 ` sashiko-bot
2026-09-28 1:11 ` [PATCH v4 14/22] PCI/CMA: Validate Subject Alternative Name in certificates alistair23
2026-09-28 1:44 ` sashiko-bot
2026-09-28 1:11 ` [PATCH v4 15/22] lib: rspdm: Support SPDM get_version alistair23
2026-09-28 1:39 ` sashiko-bot
2026-09-28 1:11 ` [PATCH v4 16/22] lib: rspdm: Support SPDM get_capabilities alistair23
2026-09-28 1:41 ` sashiko-bot
2026-09-28 1:11 ` [PATCH v4 17/22] lib: rspdm: Support SPDM negotiate_algorithms alistair23
2026-09-28 1:45 ` sashiko-bot
2026-09-28 1:11 ` [PATCH v4 18/22] lib: rspdm: Support SPDM get_digests alistair23
2026-09-28 1:45 ` sashiko-bot
2026-09-28 1:31 ` [PATCH v4 19/22] lib: rspdm: Support SPDM get_certificate alistair23
2026-09-28 1:31 ` [PATCH v4 20/22] lib: rspdm: Support SPDM certificate validation alistair23
2026-09-28 1:47 ` sashiko-bot
2026-09-28 1:31 ` [PATCH v4 21/22] rust: allow extracting the buffer from a CString alistair23
2026-09-28 1:41 ` sashiko-bot
2026-09-28 1:31 ` [PATCH v4 22/22] lib: rspdm: Support SPDM challenge alistair23
2026-09-28 1:46 ` sashiko-bot
2026-09-28 1:43 ` [PATCH v4 19/22] lib: rspdm: Support SPDM get_certificate sashiko-bot
2026-10-14 15:16 ` [PATCH v4 00/22] lib: Rust implementation of SPDM Alexandre Courbot
2026-10-15 4:17 ` Alistair Francis
2026-10-14 20:54 ` Alice Ryhl
2026-10-15 5:23 ` Alistair Francis
2026-10-15 5:54 ` Miguel Ojeda
2026-10-15 8:02 ` Alexandre Courbot
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=DM58HRC3DHSS.1YC0E53ZXANT4@nvidia.com \
--to=acourbot@nvidia.com \
--cc=Jonathan.Cameron@huawei.com \
--cc=a.hindborg@kernel.org \
--cc=akpm@linux-foundation.org \
--cc=alex.gaynor@gmail.com \
--cc=aliceryhl@google.com \
--cc=alistair23@gmail.com \
--cc=alistair@alistair23.me \
--cc=benno.lossin@proton.me \
--cc=bhelgaas@google.com \
--cc=bjorn3_gh@protonmail.com \
--cc=boqun.feng@gmail.com \
--cc=djbw@kernel.org \
--cc=gary@garyguo.net \
--cc=gregkh@linuxfoundation.org \
--cc=jic23@kernel.org \
--cc=jonathan.cameron@oss.qualcomm.com \
--cc=linux-cxl@vger.kernel.org \
--cc=linux-kernel@vger.kernel.org \
--cc=linux-pci@vger.kernel.org \
--cc=lukas@wunner.de \
--cc=ojeda@kernel.org \
--cc=rust-for-linux@vger.kernel.org \
--cc=tmgross@umich.edu \
--cc=wilfred.mallawa@wdc.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 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.