1212// See the License for the specific language governing permissions and
1313// limitations under the License.
1414
15+ mod config;
16+
1517use std:: collections:: HashMap ;
1618use std:: ffi:: CString ;
1719use std:: mem;
@@ -25,23 +27,28 @@ use alioth::errors::{DebugTrace, trace_error};
2527use alioth:: hv:: Hvf ;
2628#[ cfg( target_os = "linux" ) ]
2729use alioth:: hv:: Kvm ;
28- use alioth:: hv:: { Coco , HvConfig } ;
30+ use alioth:: hv:: { Coco , HvConfig , Hypervisor } ;
2931use alioth:: loader:: { Executable , Payload } ;
3032use alioth:: mem:: { MemBackend , MemConfig } ;
3133#[ cfg( target_os = "linux" ) ]
3234use alioth:: vfio:: { CdevParam , ContainerParam , GroupParam , IoasParam } ;
35+ #[ cfg( target_os = "linux" ) ]
36+ use alioth:: virtio:: DeviceId ;
3337use alioth:: virtio:: dev:: balloon:: BalloonParam ;
3438use alioth:: virtio:: dev:: blk:: BlkFileParam ;
3539use alioth:: virtio:: dev:: entropy:: EntropyParam ;
40+ #[ cfg( target_os = "linux" ) ]
41+ use alioth:: virtio:: vu:: frontend:: VuFrontendParam ;
3642use alioth:: virtio:: worker:: WorkerApi ;
3743use alioth:: vm:: Machine ;
38- use alioth:: vm:: config:: { BlkParam , Config , FsParam , NetParam , VsockParam } ;
3944use clap:: Args ;
4045use serde_aco:: help_text;
4146use snafu:: { ResultExt , Snafu } ;
4247
4348use crate :: objects:: { DOC_OBJECTS , parse_objects} ;
4449
50+ use self :: config:: { BlkParam , Config , FsParam , NetParam , VsockParam } ;
51+
4552#[ trace_error]
4653#[ derive( Snafu , DebugTrace ) ]
4754#[ snafu( module, context( suffix( false ) ) ) ]
@@ -338,6 +345,111 @@ fn parse_args(mut args: BootArgs, objects: HashMap<&str, &str>) -> Result<Config
338345 Ok ( config)
339346}
340347
348+ fn create < H : Hypervisor > ( hypervisor : & H , config : Config ) -> Result < Machine < H > , alioth:: vm:: Error > {
349+ let vm = Machine :: new ( hypervisor, config. board ) ?;
350+
351+ #[ cfg( target_arch = "x86_64" ) ]
352+ vm. add_com1 ( ) ?;
353+ #[ cfg( target_arch = "aarch64" ) ]
354+ vm. add_pl011 ( ) ?;
355+ #[ cfg( target_arch = "aarch64" ) ]
356+ vm. add_pl031 ( ) ;
357+
358+ if config. pvpanic {
359+ vm. add_pvpanic ( ) ?;
360+ }
361+
362+ #[ cfg( target_arch = "x86_64" ) ]
363+ if config. payload . firmware . is_some ( ) || !config. fw_cfg . is_empty ( ) {
364+ vm. add_fw_cfg ( config. fw_cfg . into_iter ( ) ) ?;
365+ } ;
366+
367+ if let Some ( param) = config. entropy {
368+ vm. add_virtio_dev ( "virtio-entropy" , param) ?;
369+ }
370+
371+ for ( index, param) in config. net . into_iter ( ) . enumerate ( ) {
372+ match param {
373+ #[ cfg( target_os = "linux" ) ]
374+ NetParam :: Tap ( tap_param) => vm. add_virtio_dev ( format ! ( "virtio-net-{index}" ) , tap_param) ,
375+ #[ cfg( target_os = "linux" ) ]
376+ NetParam :: Vu ( sock) => {
377+ let param = VuFrontendParam {
378+ id : DeviceId :: Net ,
379+ socket : sock. socket ,
380+ } ;
381+ vm. add_virtio_dev ( format ! ( "vu-net-{index}" ) , param)
382+ }
383+ #[ cfg( target_os = "macos" ) ]
384+ NetParam :: Vmnet ( p) => vm. add_virtio_dev ( format ! ( "virtio-net-{index}" ) , p) ,
385+ } ?;
386+ }
387+
388+ for ( index, param) in config. blk . into_iter ( ) . enumerate ( ) {
389+ match param {
390+ BlkParam :: File ( p) => vm. add_virtio_dev ( format ! ( "virtio-blk-{index}" ) , p) ,
391+ #[ cfg( target_os = "linux" ) ]
392+ BlkParam :: Vu ( s) => {
393+ let p = VuFrontendParam {
394+ id : DeviceId :: Block ,
395+ socket : s. socket ,
396+ } ;
397+ vm. add_virtio_dev ( format ! ( "vu-net-{index}" ) , p)
398+ }
399+ } ?;
400+ }
401+
402+ for ( index, param) in config. fs . into_iter ( ) . enumerate ( ) {
403+ match param {
404+ FsParam :: Dir ( p) => vm. add_virtio_dev ( format ! ( "virtio-fs-{index}" ) , p) ,
405+ #[ cfg( target_os = "linux" ) ]
406+ FsParam :: Vu ( p) => vm. add_virtio_dev ( format ! ( "vu-fs-{index}" ) , p) ,
407+ } ?;
408+ }
409+
410+ if let Some ( param) = config. vsock {
411+ match param {
412+ #[ cfg( target_os = "linux" ) ]
413+ VsockParam :: Vhost ( p) => vm. add_virtio_dev ( "vhost-vsock" , p) ,
414+ VsockParam :: Uds ( p) => vm. add_virtio_dev ( "uds-vsock" , p) ,
415+ #[ cfg( target_os = "linux" ) ]
416+ VsockParam :: Vu ( s) => {
417+ let p = VuFrontendParam {
418+ id : DeviceId :: Socket ,
419+ socket : s. socket ,
420+ } ;
421+ vm. add_virtio_dev ( "vu-vsock" , p)
422+ }
423+ } ?;
424+ }
425+
426+ if let Some ( param) = config. balloon {
427+ vm. add_virtio_dev ( "virtio-balloon" , param) ?;
428+ }
429+
430+ #[ cfg( target_os = "linux" ) ]
431+ for param in config. vfio_ioas . into_iter ( ) {
432+ vm. add_vfio_ioas ( param) ?;
433+ }
434+ #[ cfg( target_os = "linux" ) ]
435+ for ( index, param) in config. vfio_cdev . into_iter ( ) . enumerate ( ) {
436+ vm. add_vfio_cdev ( format ! ( "vfio-{index}" ) . into ( ) , param) ?;
437+ }
438+
439+ #[ cfg( target_os = "linux" ) ]
440+ for param in config. vfio_container . into_iter ( ) {
441+ vm. add_vfio_container ( param) ?;
442+ }
443+ #[ cfg( target_os = "linux" ) ]
444+ for ( index, param) in config. vfio_group . into_iter ( ) . enumerate ( ) {
445+ vm. add_vfio_devs_in_group ( & index. to_string ( ) , param) ?;
446+ }
447+
448+ vm. add_payload ( config. payload ) ;
449+
450+ Ok ( vm)
451+ }
452+
341453pub fn boot ( mut args : BootArgs ) -> Result < ( ) , Error > {
342454 let object_args = mem:: take ( & mut args. objects ) ;
343455 let objects = parse_objects ( & object_args) ?;
@@ -356,7 +468,7 @@ pub fn boot(mut args: BootArgs) -> Result<(), Error> {
356468
357469 let config = parse_args ( args, objects) ?;
358470
359- let vm = Machine :: new ( hypervisor, config) . context ( error:: CreateVm ) ?;
471+ let vm = create ( & hypervisor, config) . context ( error:: CreateVm ) ?;
360472
361473 vm. boot ( ) . context ( error:: BootVm ) ?;
362474 vm. wait ( ) . context ( error:: WaitVm ) ?;
0 commit comments