[RFC 0/2] rust: introduce abstractions for fwctl

Zhi Wang posted 2 patches 3 months, 1 week ago
There is a newer version of this series
include/uapi/fwctl/fwctl.h        |   1 +
rust/bindings/bindings_helper.h   |   1 +
rust/kernel/fwctl.rs              | 254 ++++++++++++++++++++++++++++++
rust/kernel/lib.rs                |   2 +
samples/rust/Kconfig              |  11 ++
samples/rust/Makefile             |   1 +
samples/rust/rust_driver_fwctl.rs | 123 +++++++++++++++
7 files changed, 393 insertions(+)
create mode 100644 rust/kernel/fwctl.rs
create mode 100644 samples/rust/rust_driver_fwctl.rs
[RFC 0/2] rust: introduce abstractions for fwctl
Posted by Zhi Wang 3 months, 1 week ago
In the NVIDIA vGPU RFC [1], the vGPU type blobs must be provided to the GSP
before userspace can enumerate available vGPU types and create vGPU
instances. The original design relied on the firmware loading interface,
but fwctl is a more natural fit for this use case, as it is designed for
uploading configuration or firmware data required before the device becomes
operational.

This patch introduces a Rust abstraction over the fwctl subsystem,
providing safe and idiomatic bindings.

The new `fwctl` module allows Rust drivers to integrate with the existing
C-side fwctl core through a typed trait interface. It provides:

  - `FwCtlOps` trait — defines driver-specific operations such as
    `open_uctx()`, `close_uctx()`, `info()`, and `fw_rpc()`.  
    Each Rust driver implements this trait to describe its own per-FD
    user-context behavior and RPC handling.

  - `FwCtlUCtx<T>` — a generic wrapper around `struct fwctl_uctx`
    embedding driver-specific context data, providing safe conversion
    from raw C pointers and access to the parent device.

  - `Registration<T>` — safe registration and automatic unregistration
    of `struct fwctl_device` objects using the kernel’s device model.

  - `FwCtlVTable<T>` — a static vtable bridging C callbacks and Rust
    trait methods, ensuring type safety across the FFI boundary.

`rust/kernel/lib.rs` is updated to conditionally include this module
under `CONFIG_FWCTL`.

[1] https://lore.kernel.org/all/20250903221111.3866249-1-zhiw@nvidia.com/

Zhi Wang (2):
  rust: introduce abstractions for fwctl
  samples: rust: fwctl: add sample code for FwCtl

 include/uapi/fwctl/fwctl.h        |   1 +
 rust/bindings/bindings_helper.h   |   1 +
 rust/kernel/fwctl.rs              | 254 ++++++++++++++++++++++++++++++
 rust/kernel/lib.rs                |   2 +
 samples/rust/Kconfig              |  11 ++
 samples/rust/Makefile             |   1 +
 samples/rust/rust_driver_fwctl.rs | 123 +++++++++++++++
 7 files changed, 393 insertions(+)
 create mode 100644 rust/kernel/fwctl.rs
 create mode 100644 samples/rust/rust_driver_fwctl.rs

-- 
2.47.3

Re: [RFC 0/2] rust: introduce abstractions for fwctl
Posted by Zhi Wang 3 months, 1 week ago
On 30.10.2025 18.03, Zhi Wang wrote:
> In the NVIDIA vGPU RFC [1], the vGPU type blobs must be provided to the GSP
> before userspace can enumerate available vGPU types and create vGPU
> instances. The original design relied on the firmware loading interface,
> but fwctl is a more natural fit for this use case, as it is designed for
> uploading configuration or firmware data required before the device becomes
> operational.
> 

Hi Jason and Danilo:

Thanks for the comments. I had one more open to discuss, handling the buffer
allocation/free between rust and C world.

Two fwctl ioctls:

FWCTL_CMD_INFO: The driver allocates the info memory (kmalloc) and the fwctl
subsystem frees it.

FWCTL_RPC:

Case 1: The driver can choose to re-use the input buffer and write the *out_len
for actual length of data.

Case 2: The driver can allocate a new buffer (kmalloc) and the fwctl subsystem
frees it.

----
Now with the Rust driver:

FWCTL_CMD_INFO: The rust side returns a new KVec, the rust fwctl abstraction
consumes it, get void *buf and pass it to fwctl subsystem (C). The memory
will be freed by C side.

FWCTL_RPC:

The input buffer will be wrapped in a mutable slice.

Case 1: Re-use the input buffer. The rust side writes the mut slice and the
* mut out_len.

Case 2: Allocate the new output buffer. The same approach as FWCTL_CMD_INFO.

----

We know KVec is backed by kmalloc. If C side changes the requirements of
the driver memory allocation someday, E.g. from kfree() to kvfree() or vfree().

Drivers in C will be updated surely at that time.

Is possible that we can have some approaches to catch that change from the rust
side via rust compiler for rust drivers?

Z.

> This patch introduces a Rust abstraction over the fwctl subsystem,
> providing safe and idiomatic bindings.
> 
> The new `fwctl` module allows Rust drivers to integrate with the existing
> C-side fwctl core through a typed trait interface. It provides:
> 
>   - `FwCtlOps` trait — defines driver-specific operations such as
>     `open_uctx()`, `close_uctx()`, `info()`, and `fw_rpc()`.  
>     Each Rust driver implements this trait to describe its own per-FD
>     user-context behavior and RPC handling.
> 
>   - `FwCtlUCtx<T>` — a generic wrapper around `struct fwctl_uctx`
>     embedding driver-specific context data, providing safe conversion
>     from raw C pointers and access to the parent device.
> 
>   - `Registration<T>` — safe registration and automatic unregistration
>     of `struct fwctl_device` objects using the kernel’s device model.
> 
>   - `FwCtlVTable<T>` — a static vtable bridging C callbacks and Rust
>     trait methods, ensuring type safety across the FFI boundary.
> 
> `rust/kernel/lib.rs` is updated to conditionally include this module
> under `CONFIG_FWCTL`.
> 
> [1] https://lore.kernel.org/all/20250903221111.3866249-1-zhiw@nvidia.com/
> 
> Zhi Wang (2):
>   rust: introduce abstractions for fwctl
>   samples: rust: fwctl: add sample code for FwCtl
> 
>  include/uapi/fwctl/fwctl.h        |   1 +
>  rust/bindings/bindings_helper.h   |   1 +
>  rust/kernel/fwctl.rs              | 254 ++++++++++++++++++++++++++++++
>  rust/kernel/lib.rs                |   2 +
>  samples/rust/Kconfig              |  11 ++
>  samples/rust/Makefile             |   1 +
>  samples/rust/rust_driver_fwctl.rs | 123 +++++++++++++++
>  7 files changed, 393 insertions(+)
>  create mode 100644 rust/kernel/fwctl.rs
>  create mode 100644 samples/rust/rust_driver_fwctl.rs
> 

Re: [RFC 0/2] rust: introduce abstractions for fwctl
Posted by Danilo Krummrich 3 months, 1 week ago
On Thu Oct 30, 2025 at 6:29 PM CET, Zhi Wang wrote:
> On 30.10.2025 18.03, Zhi Wang wrote:
>> In the NVIDIA vGPU RFC [1], the vGPU type blobs must be provided to the GSP
>> before userspace can enumerate available vGPU types and create vGPU
>> instances. The original design relied on the firmware loading interface,
>> but fwctl is a more natural fit for this use case, as it is designed for
>> uploading configuration or firmware data required before the device becomes
>> operational.
>> 
>
> Hi Jason and Danilo:
>
> Thanks for the comments. I had one more open to discuss, handling the buffer
> allocation/free between rust and C world.
>
> Two fwctl ioctls:
>
> FWCTL_CMD_INFO: The driver allocates the info memory (kmalloc) and the fwctl
> subsystem frees it.
>
> FWCTL_RPC:
>
> Case 1: The driver can choose to re-use the input buffer and write the *out_len
> for actual length of data.
>
> Case 2: The driver can allocate a new buffer (kmalloc) and the fwctl subsystem
> frees it.
>
> ----
> Now with the Rust driver:
>
> FWCTL_CMD_INFO: The rust side returns a new KVec, the rust fwctl abstraction
> consumes it, get void *buf and pass it to fwctl subsystem (C). The memory
> will be freed by C side.
>
> FWCTL_RPC:
>
> The input buffer will be wrapped in a mutable slice.
>
> Case 1: Re-use the input buffer. The rust side writes the mut slice and the
> * mut out_len.
>
> Case 2: Allocate the new output buffer. The same approach as FWCTL_CMD_INFO.
>
> ----
>
> We know KVec is backed by kmalloc. If C side changes the requirements of
> the driver memory allocation someday, E.g. from kfree() to kvfree() or vfree().
>
> Drivers in C will be updated surely at that time.
>
> Is possible that we can have some approaches to catch that change from the rust
> side via rust compiler for rust drivers?

I don't think we have the possibility of doing any compile time check here,
since on the C side the type is always void * for any memory allocation.

However, I think the only broken case would be if C switches to vmalloc() (and
hence vfree()), but the Rust code doesn't. That sounds unlikely to me for three
reasons.

  (1) I think if there'd be a change it would be to kvmalloc() and calling
      kvfree() on a kmalloc() buffer should be fine.

  (2) A breaking change would also affect all C drivers, so it'd not only be the
      Rust code being affected.
Re: [RFC 0/2] rust: introduce abstractions for fwctl
Posted by Jason Gunthorpe 3 months, 1 week ago
On Thu, Oct 30, 2025 at 06:52:31PM +0100, Danilo Krummrich wrote:
>   (1) I think if there'd be a change it would be to kvmalloc() and calling
>       kvfree() on a kmalloc() buffer should be fine.

Yes

>   (2) A breaking change would also affect all C drivers, so it'd not only be the
>       Rust code being affected.

Yes

Jason