(This is something I am also interested in because I'm working on a
different kind of network device)
You can definitely play with the sample driver included in this series
however!
Manos
>
>Thanks!
>
>> On Sun, 10 May 2026 16:38, Manos Pitsidianakis <[email protected]> wrote:
>> >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=virt,virtualization=off,acpi=on \
>> > -cpu host \
>> > -smp 8 \
>> > -accel kvm \
>> > -drive
if=virtio,format=qcow2,file=./debian-13-nocloud-arm64-daily.qcow2 \
>> > -device virtio-net-pci,netdev=unet \
>> > -device virtio-scsi-pci \
>> > -serial mon:stdio \
>> > -m 8192 \
>> > -object memory-backend-memfd,id=mem,size=8G,share=on \
>> > -numa node,memdev=mem \
>> > -display none \
>> > -vga none \
>> > -kernel /path/to/linux/build/arch/arm64/boot/Image \
>> > -device
vhost-user-test-device,chardev=rtc,id=rtc,virtio-id=17,num_vqs=2,vq_size=1024 \
>> > -chardev socket,path=/tmp/rtc.sock,id=rtc \
>> > ...
>> >
>> > 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 = 1777890485031060388
>> > [ 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 = 1777890485032086075
>> > [ 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 = 338567896865557
>> >
>> >Concerns - Notes - TODOs
>> >========================
>> >
>> >- 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/[email protected]
>> >
>> >Changes in v2:
>> >- Move helper ifdefs to helper file (thanks Alice)
>> >- Changed CONFIG checks to IS_ENABLED to allow for CONFIG_VIRTIO=m
>> >- 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/[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]>
>> >