arch/um/drivers/vfio_kern.c

Source file repositories/reference/linux-study-clean/arch/um/drivers/vfio_kern.c

File Facts

System
Linux kernel
Corpus path
arch/um/drivers/vfio_kern.c
Extension
.c
Size
15379 bytes
Lines
708
Domain
Architecture Layer
Bucket
arch/um
Inferred role
Architecture Layer: implementation source
Status
source implementation candidate

Why This File Exists

CPU and platform-specific kernel glue: boot entry, traps, syscall entry, interrupts, page tables, context switch, and low-level barriers.

Dependency Surface

Detected Declarations

Annotated Snippet

struct uml_vfio_intr_ctx {
	struct uml_vfio_device *dev;
	int irq;
};

struct uml_vfio_device {
	const char *name;
	int group;

	struct um_pci_device pdev;
	struct uml_vfio_user_device udev;
	struct uml_vfio_intr_ctx *intr_ctx;

	int msix_cap;
	int msix_bar;
	int msix_offset;
	int msix_size;
	u32 *msix_data;

	struct list_head list;
};

struct uml_vfio_group {
	int id;
	int fd;
	int users;
	struct list_head list;
};

static struct {
	int fd;
	int users;
} uml_vfio_container = { .fd = -1 };
static DEFINE_MUTEX(uml_vfio_container_mtx);

static LIST_HEAD(uml_vfio_groups);
static DEFINE_MUTEX(uml_vfio_groups_mtx);

static LIST_HEAD(uml_vfio_devices);
static DEFINE_MUTEX(uml_vfio_devices_mtx);

static int uml_vfio_set_container(int group_fd)
{
	int err;

	guard(mutex)(&uml_vfio_container_mtx);

	err = uml_vfio_user_set_container(uml_vfio_container.fd, group_fd);
	if (err)
		return err;

	uml_vfio_container.users++;
	if (uml_vfio_container.users > 1)
		return 0;

	err = uml_vfio_user_setup_iommu(uml_vfio_container.fd);
	if (err) {
		uml_vfio_user_unset_container(uml_vfio_container.fd, group_fd);
		uml_vfio_container.users--;
	}
	return err;
}

static void uml_vfio_unset_container(int group_fd)
{
	guard(mutex)(&uml_vfio_container_mtx);

	uml_vfio_user_unset_container(uml_vfio_container.fd, group_fd);
	uml_vfio_container.users--;
}

static int uml_vfio_open_group(int group_id)
{
	struct uml_vfio_group *group;
	int err;

	guard(mutex)(&uml_vfio_groups_mtx);

	list_for_each_entry(group, &uml_vfio_groups, list) {
		if (group->id == group_id) {
			group->users++;
			return group->fd;
		}
	}

	group = kzalloc_obj(*group);
	if (!group)
		return -ENOMEM;

	group->fd = uml_vfio_user_open_group(group_id);

Annotation

Implementation Notes