Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
16 changes: 16 additions & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

3 changes: 3 additions & 0 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,9 @@ endif
ifeq ($(INPUT),1)
FEATURE_FLAGS += --features input
endif
ifeq ($(VHOST_USER),1)
FEATURE_FLAGS += --features vhost-user
endif
ifeq ($(AWS_NITRO),1)
VARIANT = -awsnitro
FEATURE_FLAGS := --features aws-nitro,net
Expand Down
23 changes: 22 additions & 1 deletion examples/chroot_vm.c
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,8 @@ static void print_help(char *const name)
" --log=PATH Write libkrun log to file or named pipe at PATH\n"
" --color-log=PATH Write libkrun log to file or named pipe at PATH, use color\n"
" --net=NET_MODE Set network mode\n"
" --passt-socket=PATH Instead of starting passt, connect to passt socket at PATH"
" --passt-socket=PATH Instead of starting passt, connect to passt socket at PATH\n"
" --vhost-user-rng=PATH Use vhost-user RNG backend at socket PATH\n"
"NET_MODE can be either TSI (default) or PASST\n"
"\n"
"NEWROOT: the root directory of the vm\n"
Expand All @@ -54,6 +55,7 @@ static const struct option long_options[] = {
{ "color-log", required_argument, NULL, 'C' },
{ "net_mode", required_argument, NULL, 'N' },
{ "passt-socket", required_argument, NULL, 'P' },
{ "vhost-user-rng", required_argument, NULL, 'V' },
{ NULL, 0, NULL, 0 }
};

Expand All @@ -63,6 +65,7 @@ struct cmdline {
uint32_t log_style;
enum net_mode net_mode;
char const *passt_socket_path;
char const *vhost_user_rng_socket;
char const *new_root;
char *const *guest_argv;
};
Expand All @@ -89,6 +92,7 @@ bool parse_cmdline(int argc, char *const argv[], struct cmdline *cmdline)
.show_help = false,
.net_mode = NET_MODE_TSI,
.passt_socket_path = NULL,
.vhost_user_rng_socket = NULL,
.new_root = NULL,
.guest_argv = NULL,
.log_target = KRUN_LOG_TARGET_DEFAULT,
Expand Down Expand Up @@ -124,6 +128,9 @@ bool parse_cmdline(int argc, char *const argv[], struct cmdline *cmdline)
case 'P':
cmdline->passt_socket_path = optarg;
break;
case 'V':
cmdline->vhost_user_rng_socket = optarg;
break;
case '?':
return false;
default:
Expand Down Expand Up @@ -249,6 +256,20 @@ int main(int argc, char *const argv[])
return -1;
}

// Configure vhost-user RNG if requested
if (cmdline.vhost_user_rng_socket != NULL) {
// Test sentinel-terminated array: auto-detect queue count, use custom size
uint16_t custom_sizes[] = {512, 0}; // 0 = sentinel terminator

if (err = krun_add_vhost_user_device(ctx_id, KRUN_VIRTIO_DEVICE_RNG,
cmdline.vhost_user_rng_socket, NULL, 0, custom_sizes)) {
errno = -err;
perror("Error adding vhost-user RNG device");
return -1;
}
printf("Using vhost-user RNG backend at %s (custom queue size: 512)\n", cmdline.vhost_user_rng_socket);
}

// Raise RLIMIT_NOFILE to the maximum allowed to create some room for virtio-fs
getrlimit(RLIMIT_NOFILE, &rlim);
rlim.rlim_cur = rlim.rlim_max;
Expand Down
70 changes: 70 additions & 0 deletions include/libkrun.h
Original file line number Diff line number Diff line change
Expand Up @@ -717,6 +717,76 @@ int krun_add_input_device_fd(uint32_t ctx_id, int input_fd);
*/
int32_t krun_set_snd_device(uint32_t ctx_id, bool enable);

/**
* Vhost-user device types.
* These correspond to virtio device type IDs for devices.
*/
#define KRUN_VIRTIO_DEVICE_RNG 4
#define KRUN_VIRTIO_DEVICE_SND 25
#define KRUN_VIRTIO_DEVICE_CAN 36

/**
* Vhost-user RNG device default queue configuration.
* Use these when you want explicit defaults instead of auto-detection.
*/
#define KRUN_VHOST_USER_RNG_NUM_QUEUES 1
#define KRUN_VHOST_USER_RNG_QUEUE_SIZES ((uint16_t[]){256})

/**
* Add a vhost-user device to the VM.
*
* This function adds a vhost-user device by connecting to an external
* backend process (e.g., vhost-device-rng, vhost-device-snd). The backend
* must be running and listening on the specified socket before starting the VM.
*
* This API is designed for devices like RNG, sound, and CAN.
*
* Arguments:
* "ctx_id" - the configuration context ID.
* "device_type" - type of vhost-user device (e.g., KRUN_VHOST_USER_DEVICE_RNG).
* "socket_path" - path to the vhost-user Unix domain socket (e.g., "/tmp/vhost-rng.sock").
* "name" - device name for logging/debugging (e.g., "vhost-rng", "vhost-snd").
* NULL = auto-generate from device_type ("vhost-user-4", "vhost-user-25", etc.)
* "num_queues" - number of virtqueues.
* 0 = auto-detect from backend (requires backend MQ support).
* >0 = explicit queue count.
* Or use device-specific constants like KRUN_VHOST_USER_RNG_NUM_QUEUES.
* "queue_sizes" - array of queue sizes for each queue.
* NULL = use default size (256) for all queues.
* When num_queues=0 (auto-detect): array must be 0-terminated (sentinel).
* When num_queues>0 (explicit): array must have exactly num_queues elements.
* Use device-specific constants like KRUN_VHOST_USER_RNG_QUEUE_SIZES for defaults.
*
* Examples:
* // Auto-detect queue count, use default size (256)
* krun_add_vhost_user_device(ctx, KRUN_VHOST_USER_DEVICE_RNG, "/tmp/rng.sock", NULL, 0, NULL);
*
* // Auto-detect queue count, use custom size (512) for all queues
* uint16_t custom_size[] = {512, 0}; // 0 = sentinel terminator
* krun_add_vhost_user_device(ctx, KRUN_VHOST_USER_DEVICE_RNG, "/tmp/rng.sock", NULL, 0, custom_size);
*
* // Explicit defaults using #define constants
* krun_add_vhost_user_device(ctx, KRUN_VHOST_USER_DEVICE_RNG, "/tmp/rng.sock", "vhost-rng",
* KRUN_VHOST_USER_RNG_NUM_QUEUES,
* KRUN_VHOST_USER_RNG_QUEUE_SIZES);
*
* // Explicit queue count with custom sizes
* uint16_t sizes[] = {256, 512};
* krun_add_vhost_user_device(ctx, KRUN_VHOST_USER_DEVICE_SND, "/tmp/snd.sock", "vhost-snd", 2, sizes);
*
* Returns:
* Zero on success or a negative error number on failure.
* -EINVAL - Invalid parameters (device_type, socket_path, etc.)
* -ENOENT - Context doesn't exist
* -ENOTSUP - vhost-user support not compiled in
*/
int32_t krun_add_vhost_user_device(uint32_t ctx_id,
uint32_t device_type,
const char *socket_path,
const char *name,
uint16_t num_queues,
const uint16_t *queue_sizes);

/**
* Configures a map of rlimits to be set in the guest before starting the isolated binary.
*
Expand Down
2 changes: 2 additions & 0 deletions src/devices/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ input = ["zerocopy", "krun_input"]
virgl_resource_map2 = []
aws-nitro = []
test_utils = []
vhost-user = ["vhost"]

[dependencies]
bitflags = "1.2.0"
Expand All @@ -29,6 +30,7 @@ nix = { version = "0.30.1", features = ["ioctl", "net", "poll", "socket", "fs"]
pw = { package = "pipewire", version = "0.8.0", optional = true }
rand = "0.9.2"
thiserror = { version = "2.0", optional = true }
vhost = { version = "0.14", optional = true, features = ["vhost-user-frontend"] }
virtio-bindings = "0.2.0"
vm-memory = { version = ">=0.13", features = ["backend-mmap"] }
zerocopy = { version = "0.8.26", optional = true, features = ["derive"] }
Expand Down
4 changes: 4 additions & 0 deletions src/devices/src/virtio/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,8 @@ mod queue;
pub mod rng;
#[cfg(feature = "snd")]
pub mod snd;
#[cfg(feature = "vhost-user")]
pub mod vhost_user;
pub mod vsock;

#[cfg(not(feature = "tee"))]
Expand All @@ -56,6 +58,8 @@ pub use self::queue::{Descriptor, DescriptorChain, Queue};
pub use self::rng::*;
#[cfg(feature = "snd")]
pub use self::snd::Snd;
#[cfg(feature = "vhost-user")]
pub use self::vhost_user::VhostUserDevice;
pub use self::vsock::*;

/// When the driver initializes the device, it lets the device know about the
Expand Down
Loading
Loading