Skip to content

libkrun: vhost-user-input support#642

Open
dorindabassey wants to merge 13 commits intocontainers:mainfrom
dorindabassey:vhost-user-input
Open

libkrun: vhost-user-input support#642
dorindabassey wants to merge 13 commits intocontainers:mainfrom
dorindabassey:vhost-user-input

Conversation

@dorindabassey
Copy link
Copy Markdown
Collaborator

@dorindabassey dorindabassey commented Apr 17, 2026

Implement write_config in VhostUserDevice to support dynamic
config space (needed for virtio-input device discovery) and
Add API constants and example for vhost-user input.
depends on rust-vmm/vhost-device#955 and containers/libkrunfw#120

Dorinda Bassey and others added 13 commits April 8, 2026 15:22
Implement vhost-user support for connecting
to external virtio device backends running
in separate processes.
Add vhost-user feature flag, vhost dependency,
and krun_add_vhost_user_device() generalized
API for adding vhost-user devices.

Signed-off-by: Dorinda Bassey <dbassey@redhat.com>
Add memfd-backed memory region creation to enable memory
sharing with vhost-user backends via FD passing. When
vhost-user is enabled, all guest RAM regions are created
with memfd backing instead of anonymous mmap.

This lays the groundwork for vhost-user device support
while maintaining backward compatibility such that the
VM boots normally with standard memory when vhost-user
is not configured.

Signed-off-by: Dorinda Bassey <dbassey@redhat.com>
Implement generic vhost-user device wrapper
with connection, feature negotiation, and
Guest physical address(GPA) to Virtual
address(VA) translation. Supports protocol
feature negotiation (CONFIG, MQ).
Backend interrupts (vring_call_event) are
monitored by the EventManager and forwarded
to the guest without spawning additional threads.

Co-authored-by: Matej Hrica <mhrica@redhat.com>
Signed-off-by: Dorinda Bassey <dbassey@redhat.com>
Add support for attaching vhost-user devices to the VM.
Devices are registered with the EventManager as subscribers
to integrate with the VMM's event loop for interrupt handling.

The VMM now automatically suppresses the implicit RNG
device when a vhost-user RNG is configured via
krun_add_vhost_user_device(), allowing seamless
switching between the standard virtio-rng and external
vhost-user-rng backend for better isolation and flexibility.

Signed-off-by: Dorinda Bassey <dbassey@redhat.com>
Adds --vhost-user-rng command line option to
specify a vhost-user RNG backend socket path.
When provided, the VM uses the external
vhost-user RNG device instead of the built-in
virtio-rng implementation.

Example usage:  ./examples/chroot_vm \
--vhost-user-rng=/tmp/vhost-rng.sock0 \
/ /bin/sh -c "head -c 32 /dev/hwrng | xxd"

Signed-off-by: Dorinda Bassey <dbassey@redhat.com>
Implement read_config() for vhost-user devices using the
VHOST_USER_GET_CONFIG protocol message. This enables vhost-user
devices to expose their configuration space to the guest.

This provides a general mechanism for any vhost-user device that
needs to expose configuration to the guest (e.g., virtio-snd).

Signed-off-by: Dorinda Bassey <dbassey@redhat.com>
Add constants and device-specific configuration for virtio-snd
(vhost-user sound device).

Signed-off-by: Dorinda Bassey <dbassey@redhat.com>
Add --vhost-user-snd option to chroot_vm example,
allowing VMs to use external vhost-user sound backends
for audio playback and capture.

Usage:
  ./chroot_vm --vhost-user-snd=/path/to/sound.sock ...

Note: In the guest, the ALSA default device may not work without
additional configuration. Use explicit device specification:
  aplay -D hw:0,0 /path/to/audio.wav

Or create /etc/asound.conf in the guest:
  defaults.pcm.card 0
  defaults.pcm.device 0
  pcm.!default {
      type hw
      card 0
      device 0
  }

Tested with vhost-device-sound backend using PipeWire.

Signed-off-by: Dorinda Bassey <dbassey@redhat.com>
Add public API constants for vhost-user vsock devices and example
usage in chroot_vm. The underlying support already exists via the
generic VhostUserDevice wrapper.

Example integration:
- Added --vhost-user-vsock option to chroot_vm
- Calls krun_disable_implicit_vsock() to avoid conflict with
  built-in device
- Skips TSI port mapping when vhost-user-vsock is active

Signed-off-by: Dorinda Bassey <dbassey@redhat.com>
Add public API constants for vhost-user CAN devices and
example usage in chroot_vm. The underlying support already
exists via the generic VhostUserDevice wrapper.

Example integration:
- Added --vhost-user-can option to chroot_vm
- Uses 3 queues (TX, RX, control) with 64-entry queue sizes
- Follows same pattern as other vhost-user device integrations

Signed-off-by: Dorinda Bassey <dbassey@redhat.com>
Add public API constants for vhost-user console devices and example
usage in chroot_vm. The underlying support already exists via the
generic VhostUserDevice wrapper.

Console devices require 4 queues for multiport support (receiveq,
transmitq, control receiveq, control transmitq).

Example integration:
- Added --vhost-user-console option to chroot_vm
- Available as /dev/hvc1 in the guest (implicit console uses hvc0)
- Can be used with vhost-device-console for remote console access

Example workflow:
  Terminal 1: Start vhost-device-console backend
  vhost-device-console --socket-path=/tmp/console.sock \
  --socket-count=1 --tcp-port=12346 --backend=network

  Terminal 2: Connect to console (before starting VM)
    nc localhost 12346

  Terminal 3: Start VM with vhost-user console
  chroot_vm --vhost-user-console=/tmp/console.sock0 / /bin/sh
  In guest: Test with echo "hello" > /dev/hvc1

Signed-off-by: Dorinda Bassey <dbassey@redhat.com>
Implement write_config in VhostUserDevice to support
virtio devices that use dynamic configuration space,
such as virtio-input. Some virtio devices like
virtio-input use a request-response pattern for
device discovery. Without write_config support, the
backend never receives the virtio_input config values,
causing device initialization to fail.
This implementation uses VHOST_USER_SET_CONFIG to
forward writes to the backend.

Signed-off-by: Dorinda Bassey <dbassey@redhat.com>
Add public API constants for vhost-user input devices and example
usage in chroot_vm. The underlying support already exists via the
generic VhostUserDevice wrapper.

Console devices require 2 queues (event, status).
Example integration:
  - Added --vhost-user-console option to chroot_vm

Example usage:
On host, start vhost-device-input backend
vhost-device-input --socket-path /tmp/input.sock \
                   --event-list /dev/input/event3

In libkrun
./chroot_vm --vhost-user-input=/tmp/input.sock0 / /bin/sh

The guest will see the input device as /dev/input/event0 and
can read input events from the host device.

Signed-off-by: Dorinda Bassey <dbassey@redhat.com>
Copy link
Copy Markdown
Collaborator

@bilelmoussaoui bilelmoussaoui left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

various comments

Comment thread src/vmm/src/builder.rs
)
}
RegisterVhostUserDevice(ref err) => {
let mut err_msg = format!("{err}");
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Given that mmio::Error likely implements Display, you could use to_string() here instead of going through format! no?

Comment thread src/vmm/src/builder.rs
let kernel_region = unsafe {
MmapRegion::build_raw(kernel_host_addr as *mut u8, kernel_size, 0, 0)
.map_err(StartMicrovmError::InvalidKernelBundle)?
#[cfg(all(feature = "vhost-user", target_os = "linux"))]
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I guess you could have put this cfg above a scope defined with {} so you don't need to repeat it multiple times?

Comment thread src/vmm/src/builder.rs
}

// For vhost-user devices, we need file-backed memory so the backend can mmap it
#[cfg(all(feature = "vhost-user", target_os = "linux"))]
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Same here

Comment thread src/vmm/src/builder.rs
.iter()
.map(|(addr, size)| {
debug!(
" Creating memfd for region: addr=0x{:x}, size=0x{:x}",
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
" Creating memfd for region: addr=0x{:x}, size=0x{:x}",
"Creating memfd for region: addr=0x{:x}, size=0x{:x}",

Comment thread src/vmm/src/builder.rs
// File descriptor ownership is transferred to File::from_raw_fd below.
let memfd = unsafe {
let fd = libc::memfd_create(
b"guest_mem\0".as_ptr() as *const libc::c_char,
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You can use c"" nowadays no?

Comment thread src/vmm/src/builder.rs
libc::close(fd);
return Err(io::Error::last_os_error());
}
debug!(" Created memfd with fd={}", fd);
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
debug!(" Created memfd with fd={}", fd);
debug!("Created memfd with fd={}", fd);

///
/// A new VhostUserDevice or an error if connection fails.
pub fn new(
socket_path: &str,
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

an actual Path maybe?

})
.collect();

Ok(VhostUserDevice {
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
Ok(VhostUserDevice {
Ok(Self {

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants