Skip to content

Commit 8129b9e

Browse files
btw616jmberg-intel
authored andcommitted
um: vfio: Support adding devices via mconsole
It can be used when we want to pass through PCI devices to UML while it's up and running. PCI devices can be passed through to UML using the same syntax as the command line option: (mconsole) config vfio_uml.device=<domain:bus:slot.function> Signed-off-by: Tiwei Bie <[email protected]> Link: https://patch.msgid.link/[email protected] Signed-off-by: Johannes Berg <[email protected]>
1 parent 4c916e3 commit 8129b9e

File tree

1 file changed

+57
-5
lines changed

1 file changed

+57
-5
lines changed

arch/um/drivers/vfio_kern.c

Lines changed: 57 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@
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);
6061
static DEFINE_MUTEX(uml_vfio_groups_mtx);
6162

6263
static LIST_HEAD(uml_vfio_devices);
64+
static DEFINE_MUTEX(uml_vfio_devices_mtx);
6365

6466
static 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+
632682
static 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
}
644696
late_initcall(uml_vfio_init);

0 commit comments

Comments
 (0)