Rust virtio drivers in Linux
Manos Pitsidianakis <[email protected]> Mon, 18 May 2026 11:12:06 +0300
| Newsgroups | dev.linux.lists.virtio-dev |
|---|---|
| Message-ID | <CAAjaMXaOm=sOjO4ksM-PcOf4wqez9+ePBdv9U7prHiVaCx7-+Q@mail.gmail.com> |
Hello all, I have a new device type proposal for the virtio spec I hope to publish to virtio-comment soon and I have a reference C driver implementation for Linux. However I would prefer to implement the driver in Rust, and should it be accepted upstream, abandon the C driver out-of-tree. In preparation for that, I wrote bindings for the virtio subsystem and sent them to LKML. I had forgotten to CC virtio-dev. The RFC I sent 2 weeks ago has a sample virtio-rtc driver that doesn't register itself to the rtc subsystem. Since then I wrote a virtio-rng driver instead that is fully equivalent to the C driver. I haven't sent it yet because my last revision did not receive any comments yet. My WIP tree is https://github.com/epilys/linux/tree/rust-virtio I'd like to hear any feedback and suggestions, especially from the kernel virtio and Rust maintainers. Note: An issue with virtio drivers is that they require bindings both for virtio and the device subsystem. For example I had to write hwrng bindings for the virtio-rng driver. Does this require more co-operation from kernel maintainers in order to get things merged? Miguel: WDYT? Thanks in advance! ---------- Forwarded message --------- From: Manos Pitsidianakis <[email protected]> Date: Sun, May 10, 2026 at 4:38=E2=80=AFPM Subject: [PATCH RFC v3 0/6] Add Rust virtio bindings and sample device To: Miguel Ojeda <[email protected]> Cc: Manos Pitsidianakis <[email protected]>, Peter Hilber <[email protected]>, Stefano Garzarella <[email protected]>, Stefan Hajnoczi <[email protected]>, Viresh Kumar <[email protected]>, Michael S. Tsirkin <[email protected]>, Boqun Feng <[email protected]>, Gary Guo <[email protected]>, Bj=C3=B6rn Roy Baron <[email protected]>, Benno Lossin <[email protected]>, Andreas Hindborg <[email protected]>, Alice Ryhl <[email protected]>, Trevor Gross <[email protected]>, Danilo Krummrich <[email protected]>, Daniel Almeida <[email protected]>, <[email protected]>, Jason Wang <[email protected]>, Xuan Zhuo <[email protected]>, Eugenio P=C3=A9rez <[email protected]>, <[email protected]>, <[email protected]>, Manos Pitsidianakis <[email protected]> Hi all, this RFC series adds Rust bindings for Virtio drivers (frontends in virtio parlance). As a PoC, it also adds a sample virtio-rtc driver which performs capability discovery through the virtqueue without registering any clock. Before I send a cleaned-up non-RFC I would like some initial feedback (i.e. is it something the upstream wants?) This was tested with the rust-vmm vhost-device-rtc device backend that I wrote[^0]: [^0]: https://github.com/rust-vmm/vhost-device/tree/main/vhost-device-rtc Instructions: Run the daemon in a separate terminal: $ cargo run --bin vhost-device-rtc -- -s /tmp/rtc.sock Then run the VM: $ qemu-system-aarch64 \ -machine type=3Dvirt,virtualization=3Doff,acpi=3Don \ -cpu host \ -smp 8 \ -accel kvm \ -drive if=3Dvirtio,format=3Dqcow2,file=3D./debian-13-nocloud-arm64-dail= y.qcow2 \ -device virtio-net-pci,netdev=3Dunet \ -device virtio-scsi-pci \ -serial mon:stdio \ -m 8192 \ -object memory-backend-memfd,id=3Dmem,size=3D8G,share=3Don \ -numa node,memdev=3Dmem \ -display none \ -vga none \ -kernel /path/to/linux/build/arch/arm64/boot/Image \ -device vhost-user-test-device,chardev=3Drtc,id=3Drtc,virtio-id=3D17,nu= m_vqs=3D2,vq_size=3D1024 \ -chardev socket,path=3D/tmp/rtc.sock,id=3Drtc \ ... Example output: [ 1.105238] rust_virtio_rtc: Probe Rust virtio driver sample. [ 1.105645] rust_virtio_rtc: Found 1 vqs. [ 1.136050] rust_virtio_rtc: process_requestq got buf 16 bytes [ 1.136125] rust_virtio_rtc: Got response! Ok(RespCfg { head: ReqHead { msg_type: Le16(0), reserved: [0, 0, 0, 0, 0, 0] }, num_clocks: Le16(3), reserved: [0, 0, 0, 0, 0, 0] }) [ 1.136701] rust_virtio_rtc: Got response! Ok(RespClockCap { head: ReqHead { msg_type: Le16(0), reserved: [0, 0, 0, 0, 0, 0] }, clock_type: 3, leap_second_smearing: 0, flags: 0, reserved: [0, 0, 0, 0, 0] }) [ 1.136724] rust_virtio_rtc virtio0: cannot expose clock 0 (type 3, variant 0, flags 0) to userspace [ 1.137259] rust_virtio_rtc: Got response! Ok(RespRead { head: ReqHead { msg_type: Le16(0), reserved: [0, 0, 0, 0, 0, 0] }, clock_reading: Le64(1777890485031060388) }) [ 1.137277] rust_virtio_rtc: #0 clock reading =3D 177789048503106038= 8 [ 1.137749] rust_virtio_rtc: Got response! Ok(RespClockCap { head: ReqHead { msg_type: Le16(0), reserved: [0, 0, 0, 0, 0, 0] }, clock_type: 1, leap_second_smearing: 0, flags: 0, reserved: [0, 0, 0, 0, 0] }) [ 1.137769] rust_virtio_rtc virtio0: cannot expose clock 1 (type 1, variant 0, flags 0) to userspace [ 1.138247] rust_virtio_rtc: Got response! Ok(RespRead { head: ReqHead { msg_type: Le16(0), reserved: [0, 0, 0, 0, 0, 0] }, clock_reading: Le64(1777890485032086075) }) [ 1.138264] rust_virtio_rtc: #1 clock reading =3D 177789048503208607= 5 [ 1.138730] rust_virtio_rtc: Got response! Ok(RespClockCap { head: ReqHead { msg_type: Le16(0), reserved: [0, 0, 0, 0, 0, 0] }, clock_type: 2, leap_second_smearing: 0, flags: 0, reserved: [0, 0, 0, 0, 0] }) [ 1.138751] rust_virtio_rtc virtio0: cannot expose clock 2 (type 2, variant 0, flags 0) to userspace [ 1.139253] rust_virtio_rtc: Got response! Ok(RespRead { head: ReqHead { msg_type: Le16(0), reserved: [0, 0, 0, 0, 0, 0] }, clock_reading: Le64(338567896865557) }) [ 1.139270] rust_virtio_rtc: #2 clock reading =3D 338567896865557 Concerns - Notes - TODOs =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D - Virtqueue lifetimes don't neatly apply to Rust as expected, so a lot of times we have to go through unsafe pointer dereferences (though which are guaranteed by Virtio subsystem to be valid, for example when a callback is called with the vq argument). There's a potential for misuse and definitely could use better thinking. - `struct virtio_device` is not reference-counted like other implemented device types in rust/kernel. Maybe we need to change C API first to make them reference counted, assuming this doesn't break anything? - The sample driver obviously conflicts with the C implementation, so this would either need to move out of samples/ or figure out some way to handle this in kbuild. - kernel::virtio module and its types need a few rustdoc examples that I will add in followup series - Note that the registration of RTC clocks etc in the sample driver is not done, I'm putting it off until I receive some feedback first. The sample driver otherwise does send and receive data from the virtqueue as a PoC. PS: No LLMs used so any mistakes and goofs are solely written by me. Signed-off-by: Manos Pitsidianakis <[email protected]> --- Changes in v3: - Removed unused methods from virtio API - Clean up how scattergather lists are added to virtqueues by using owned SGTables only, and make the API safe(r) - Add RAII cleanup for find_vqs return value that calls del_vqs - Reset device after remove callback - Significantly clean up sample driver as a result of the other cleanups - Link to v2: https://lore.kernel.org/r/20260509-rust-virtio-v2-0-c1e30ec2b= [email protected] Changes in v2: - Move helper ifdefs to helper file (thanks Alice) - Changed CONFIG checks to IS_ENABLED to allow for CONFIG_VIRTIO=3Dm - Split all use imports to one item per line according to style guide - Fixed wait_for_completion_interruptible*() rustdocs - Use Jiffy type alias in wait_for_completion_interruptible_timeout() - Pepper and salt #[inline]s wherever appropriate as per style guide - Split probe() into probe() and init() to allow cleaning up if init fails - Remove unnecessary Send and Sync unsafe impls for kernel::virtio::Device - Remove unnecessary LeSize and BeSize - Accept Option<_> for virtqueue callback when creating a VirtqueueInfo - Made all vq buffer adding operations unsafe - Use AtomicU16 instead of Cell<u16> for sample virtio driver - Fix RespHead field types in sample virtio driver - Fix response error checking in sample virtio driver - Change some device contexts in method signatures - Link to v1: https://lore.kernel.org/r/20260505-rust-virtio-v1-0-956338390= [email protected] --- Manos Pitsidianakis (6): rust/bindings: generate virtio bindings rust/helpers: add virtio.c rust/kernel/device: return parent at same context rust: add virtio module rust: impl interruptible waits for Completion samples/rust: Add sample virtio-rtc driver [WIP] MAINTAINERS | 9 + rust/bindings/bindings_helper.h | 5 + rust/helpers/helpers.c | 1 + rust/helpers/virtio.c | 37 ++++ rust/kernel/device.rs | 2 +- rust/kernel/lib.rs | 2 + rust/kernel/sync/completion.rs | 42 +++- rust/kernel/virtio.rs | 423 ++++++++++++++++++++++++++++++++++++= ++++ rust/kernel/virtio/utils.rs | 57 ++++++ rust/kernel/virtio/virtqueue.rs | 314 +++++++++++++++++++++++++++++ samples/rust/Kconfig | 15 ++ samples/rust/Makefile | 1 + samples/rust/rust_virtio_rtc.rs | 403 ++++++++++++++++++++++++++++++++++++= ++ 13 files changed, 1309 insertions(+), 2 deletions(-) --- base-commit: 028ef9c96e96197026887c0f092424679298aae8 change-id: 20260504-rust-virtio-8523b01dfdc2 Best regards, -- Manos Pitsidianakis <[email protected]> --=20 Manos Pitsidianakis Emulation and Virtualization Engineer at Linaro Ltd