16
16
#include <init.h>
17
17
#include <os.h>
18
18
19
+ #include "mconsole_kern.h"
19
20
#include "virt-pci.h"
20
21
#include "vfio_user.h"
21
22
@@ -60,6 +61,7 @@ static LIST_HEAD(uml_vfio_groups);
60
61
static DEFINE_MUTEX (uml_vfio_groups_mtx );
61
62
62
63
static LIST_HEAD (uml_vfio_devices );
64
+ static DEFINE_MUTEX (uml_vfio_devices_mtx );
63
65
64
66
static int uml_vfio_set_container (int group_fd )
65
67
{
@@ -581,32 +583,44 @@ static struct uml_vfio_device *uml_vfio_find_device(const char *device)
581
583
return NULL ;
582
584
}
583
585
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 )
585
587
{
586
588
struct uml_vfio_device * dev ;
587
589
int fd ;
588
590
591
+ guard (mutex )(& uml_vfio_devices_mtx );
592
+
589
593
if (uml_vfio_container .fd < 0 ) {
590
594
fd = uml_vfio_user_open_container ();
591
595
if (fd < 0 )
592
- return fd ;
596
+ return ERR_PTR ( fd ) ;
593
597
uml_vfio_container .fd = fd ;
594
598
}
595
599
596
600
if (uml_vfio_find_device (device ))
597
- return - EEXIST ;
601
+ return ERR_PTR ( - EEXIST ) ;
598
602
599
603
dev = kzalloc (sizeof (* dev ), GFP_KERNEL );
600
604
if (!dev )
601
- return - ENOMEM ;
605
+ return ERR_PTR ( - ENOMEM ) ;
602
606
603
607
dev -> name = kstrdup (device , GFP_KERNEL );
604
608
if (!dev -> name ) {
605
609
kfree (dev );
606
- return - ENOMEM ;
610
+ return ERR_PTR ( - ENOMEM ) ;
607
611
}
608
612
609
613
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 );
610
624
return 0 ;
611
625
}
612
626
@@ -629,6 +643,42 @@ __uml_help(uml_vfio_cmdline_param_ops,
629
643
" through multiple PCI devices to UML.\n\n"
630
644
);
631
645
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
+
632
682
static int __init uml_vfio_init (void )
633
683
{
634
684
struct uml_vfio_device * dev , * n ;
@@ -639,6 +689,8 @@ static int __init uml_vfio_init(void)
639
689
list_for_each_entry_safe (dev , n , & uml_vfio_devices , list )
640
690
uml_vfio_open_device (dev );
641
691
692
+ mconsole_register_dev (& uml_vfio_mc );
693
+
642
694
return 0 ;
643
695
}
644
696
late_initcall (uml_vfio_init );
0 commit comments