@@ -213,6 +213,8 @@ pub enum StartMicrovmError {
213213 RegisterRngDevice ( device_manager:: mmio:: Error ) ,
214214 /// Cannot initialize a MMIO Snd device or add a device to the MMIO Bus.
215215 RegisterSndDevice ( device_manager:: mmio:: Error ) ,
216+ /// Cannot initialize a vhost-user device or add a device to the MMIO Bus.
217+ RegisterVhostUserDevice ( device_manager:: mmio:: Error ) ,
216218 /// Cannot initialize a MMIO Vsock Device or add a device to the MMIO Bus.
217219 RegisterVsockDevice ( device_manager:: mmio:: Error ) ,
218220 /// Cannot attest the VM in the Secure Virtualization context.
@@ -465,6 +467,14 @@ impl Display for StartMicrovmError {
465467 "Cannot initialize a MMIO Snd Device or add a device to the MMIO Bus. {err_msg}"
466468 )
467469 }
470+ RegisterVhostUserDevice ( ref err) => {
471+ let mut err_msg = format ! ( "{err}" ) ;
472+ err_msg = err_msg. replace ( '\"' , "" ) ;
473+ write ! (
474+ f,
475+ "Cannot initialize a vhost-user device or add a device to the MMIO Bus. {err_msg}"
476+ )
477+ }
468478 RegisterVsockDevice ( ref err) => {
469479 let mut err_msg = format ! ( "{err}" ) ;
470480 err_msg = err_msg. replace ( '\"' , "" ) ;
@@ -976,7 +986,29 @@ pub fn build_microvm(
976986 #[ cfg( not( feature = "tee" ) ) ]
977987 attach_balloon_device ( & mut vmm, event_manager, intc. clone ( ) ) ?;
978988 #[ cfg( not( feature = "tee" ) ) ]
979- attach_rng_device ( & mut vmm, event_manager, intc. clone ( ) ) ?;
989+ {
990+ #[ cfg( feature = "vhost-user" ) ]
991+ {
992+ const VIRTIO_ID_RNG : u32 = 4 ;
993+ for device_config in & vm_resources. vhost_user_devices {
994+ attach_vhost_user_device ( & mut vmm, intc. clone ( ) , device_config) ?;
995+ }
996+
997+ let has_vhost_user_rng = vm_resources
998+ . vhost_user_devices
999+ . iter ( )
1000+ . any ( |dev| dev. device_type == VIRTIO_ID_RNG ) ;
1001+
1002+ if !has_vhost_user_rng {
1003+ attach_rng_device ( & mut vmm, event_manager, intc. clone ( ) ) ?;
1004+ }
1005+ }
1006+
1007+ #[ cfg( not( feature = "vhost-user" ) ) ]
1008+ {
1009+ attach_rng_device ( & mut vmm, event_manager, intc. clone ( ) ) ?;
1010+ }
1011+ }
9801012 let mut console_id = 0 ;
9811013 if !vm_resources. disable_implicit_console {
9821014 attach_console_devices (
@@ -2389,6 +2421,36 @@ fn attach_rng_device(
23892421 Ok ( ( ) )
23902422}
23912423
2424+ #[ cfg( not( feature = "tee" ) ) ]
2425+ #[ cfg( feature = "vhost-user" ) ]
2426+ fn attach_vhost_user_device (
2427+ vmm : & mut Vmm ,
2428+ intc : IrqChip ,
2429+ device_config : & VhostUserDeviceConfig ,
2430+ ) -> std:: result:: Result < ( ) , StartMicrovmError > {
2431+ use self :: StartMicrovmError :: * ;
2432+
2433+ let device_name = device_config
2434+ . name
2435+ . clone ( )
2436+ . unwrap_or_else ( || format ! ( "vhost-user-{}" , device_config. device_type) ) ;
2437+
2438+ let device = Arc :: new ( Mutex :: new (
2439+ devices:: virtio:: VhostUserDevice :: new (
2440+ & device_config. socket_path ,
2441+ device_config. device_type ,
2442+ device_name. clone ( ) ,
2443+ device_config. num_queues ,
2444+ & device_config. queue_sizes ,
2445+ )
2446+ . map_err ( |e| RegisterVhostUserDevice ( device_manager:: mmio:: Error :: VhostUserDevice ( e) ) ) ?,
2447+ ) ) ;
2448+
2449+ attach_mmio_device ( vmm, device_name, intc. clone ( ) , device) . map_err ( RegisterVhostUserDevice ) ?;
2450+
2451+ Ok ( ( ) )
2452+ }
2453+
23922454#[ cfg( feature = "gpu" ) ]
23932455#[ allow( clippy:: too_many_arguments) ]
23942456fn attach_gpu_device (
0 commit comments