1616#include <init.h>
1717#include <os.h>
1818
19+ #include "mconsole_kern.h"
1920#include "virt-pci.h"
2021#include "vfio_user.h"
2122
@@ -60,6 +61,7 @@ static LIST_HEAD(uml_vfio_groups);
6061static DEFINE_MUTEX (uml_vfio_groups_mtx );
6162
6263static LIST_HEAD (uml_vfio_devices );
64+ static DEFINE_MUTEX (uml_vfio_devices_mtx );
6365
6466static int uml_vfio_set_container (int group_fd )
6567{
@@ -581,32 +583,44 @@ static struct uml_vfio_device *uml_vfio_find_device(const char *device)
581583 return NULL ;
582584}
583585
584- static int uml_vfio_cmdline_set (const char * device , const struct kernel_param * kp )
586+ static struct uml_vfio_device * uml_vfio_add_device (const char * device )
585587{
586588 struct uml_vfio_device * dev ;
587589 int fd ;
588590
591+ guard (mutex )(& uml_vfio_devices_mtx );
592+
589593 if (uml_vfio_container .fd < 0 ) {
590594 fd = uml_vfio_user_open_container ();
591595 if (fd < 0 )
592- return fd ;
596+ return ERR_PTR ( fd ) ;
593597 uml_vfio_container .fd = fd ;
594598 }
595599
596600 if (uml_vfio_find_device (device ))
597- return - EEXIST ;
601+ return ERR_PTR ( - EEXIST ) ;
598602
599603 dev = kzalloc (sizeof (* dev ), GFP_KERNEL );
600604 if (!dev )
601- return - ENOMEM ;
605+ return ERR_PTR ( - ENOMEM ) ;
602606
603607 dev -> name = kstrdup (device , GFP_KERNEL );
604608 if (!dev -> name ) {
605609 kfree (dev );
606- return - ENOMEM ;
610+ return ERR_PTR ( - ENOMEM ) ;
607611 }
608612
609613 list_add_tail (& dev -> list , & uml_vfio_devices );
614+ return dev ;
615+ }
616+
617+ static int uml_vfio_cmdline_set (const char * device , const struct kernel_param * kp )
618+ {
619+ struct uml_vfio_device * dev ;
620+
621+ dev = uml_vfio_add_device (device );
622+ if (IS_ERR (dev ))
623+ return PTR_ERR (dev );
610624 return 0 ;
611625}
612626
@@ -629,6 +643,42 @@ __uml_help(uml_vfio_cmdline_param_ops,
629643" through multiple PCI devices to UML.\n\n"
630644);
631645
646+ static int uml_vfio_mc_config (char * str , char * * error_out )
647+ {
648+ struct uml_vfio_device * dev ;
649+
650+ if (* str != '=' ) {
651+ * error_out = "Invalid config" ;
652+ return - EINVAL ;
653+ }
654+ str += 1 ;
655+
656+ dev = uml_vfio_add_device (str );
657+ if (IS_ERR (dev ))
658+ return PTR_ERR (dev );
659+ uml_vfio_open_device (dev );
660+ return 0 ;
661+ }
662+
663+ static int uml_vfio_mc_id (char * * str , int * start_out , int * end_out )
664+ {
665+ return - EOPNOTSUPP ;
666+ }
667+
668+ static int uml_vfio_mc_remove (int n , char * * error_out )
669+ {
670+ return - EOPNOTSUPP ;
671+ }
672+
673+ static struct mc_device uml_vfio_mc = {
674+ .list = LIST_HEAD_INIT (uml_vfio_mc .list ),
675+ .name = "vfio_uml.device" ,
676+ .config = uml_vfio_mc_config ,
677+ .get_config = NULL ,
678+ .id = uml_vfio_mc_id ,
679+ .remove = uml_vfio_mc_remove ,
680+ };
681+
632682static int __init uml_vfio_init (void )
633683{
634684 struct uml_vfio_device * dev , * n ;
@@ -639,6 +689,8 @@ static int __init uml_vfio_init(void)
639689 list_for_each_entry_safe (dev , n , & uml_vfio_devices , list )
640690 uml_vfio_open_device (dev );
641691
692+ mconsole_register_dev (& uml_vfio_mc );
693+
642694 return 0 ;
643695}
644696late_initcall (uml_vfio_init );
0 commit comments