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
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
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 >
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.
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
© 2016 - 2026 Red Hat, Inc.