Commit c1cce6d0 authored by Yi Liu's avatar Yi Liu Committed by Alex Williamson
Browse files

vfio: Compile vfio_group infrastructure optionally



vfio_group is not needed for vfio device cdev, so with vfio device cdev
introduced, the vfio_group infrastructures can be compiled out if only
cdev is needed.

Reviewed-by: default avatarJason Gunthorpe <jgg@nvidia.com>
Tested-by: default avatarNicolin Chen <nicolinc@nvidia.com>
Tested-by: default avatarMatthew Rosato <mjrosato@linux.ibm.com>
Tested-by: default avatarYanting Jiang <yanting.jiang@intel.com>
Tested-by: default avatarShameer Kolothum <shameerali.kolothum.thodi@huawei.com>
Tested-by: default avatarTerrence Xu <terrence.xu@intel.com>
Tested-by: default avatarZhenzhong Duan <zhenzhong.duan@intel.com>
Signed-off-by: default avatarYi Liu <yi.l.liu@intel.com>
Link: https://lore.kernel.org/r/20230718135551.6592-26-yi.l.liu@intel.com


Signed-off-by: default avatarAlex Williamson <alex.williamson@redhat.com>
parent 5398be25
Loading
Loading
Loading
Loading
+2 −2
Original line number Diff line number Diff line
@@ -14,8 +14,8 @@ config IOMMUFD
if IOMMUFD
config IOMMUFD_VFIO_CONTAINER
	bool "IOMMUFD provides the VFIO container /dev/vfio/vfio"
	depends on VFIO && !VFIO_CONTAINER
	default VFIO && !VFIO_CONTAINER
	depends on VFIO_GROUP && !VFIO_CONTAINER
	default VFIO_GROUP && !VFIO_CONTAINER
	help
	  IOMMUFD will provide /dev/vfio/vfio instead of VFIO. This relies on
	  IOMMUFD providing compatibility emulation to give the same ioctls.
+15 −0
Original line number Diff line number Diff line
@@ -4,6 +4,8 @@ menuconfig VFIO
	select IOMMU_API
	depends on IOMMUFD || !IOMMUFD
	select INTERVAL_TREE
	select VFIO_GROUP if SPAPR_TCE_IOMMU || IOMMUFD=n
	select VFIO_DEVICE_CDEV if !VFIO_GROUP
	select VFIO_CONTAINER if IOMMUFD=n
	help
	  VFIO provides a framework for secure userspace device drivers.
@@ -15,6 +17,7 @@ if VFIO
config VFIO_DEVICE_CDEV
	bool "Support for the VFIO cdev /dev/vfio/devices/vfioX"
	depends on IOMMUFD && !SPAPR_TCE_IOMMU
	default !VFIO_GROUP
	help
	  The VFIO device cdev is another way for userspace to get device
	  access. Userspace gets device fd by opening device cdev under
@@ -24,9 +27,20 @@ config VFIO_DEVICE_CDEV

	  If you don't know what to do here, say N.

config VFIO_GROUP
	bool "Support for the VFIO group /dev/vfio/$group_id"
	default y
	help
	   VFIO group support provides the traditional model for accessing
	   devices through VFIO and is used by the majority of userspace
	   applications and drivers making use of VFIO.

	   If you don't know what to do here, say Y.

config VFIO_CONTAINER
	bool "Support for the VFIO container /dev/vfio/vfio"
	select VFIO_IOMMU_TYPE1 if MMU && (X86 || S390 || ARM || ARM64)
	depends on VFIO_GROUP
	default y
	help
	  The VFIO container is the classic interface to VFIO for establishing
@@ -48,6 +62,7 @@ endif

config VFIO_NOIOMMU
	bool "VFIO No-IOMMU support"
	depends on VFIO_GROUP
	help
	  VFIO is built on the ability to isolate devices using the IOMMU.
	  Only with an IOMMU can userspace access to DMA capable devices be
+1 −1
Original line number Diff line number Diff line
@@ -2,9 +2,9 @@
obj-$(CONFIG_VFIO) += vfio.o

vfio-y += vfio_main.o \
	  group.o \
	  iova_bitmap.o
vfio-$(CONFIG_VFIO_DEVICE_CDEV) += device_cdev.o
vfio-$(CONFIG_VFIO_GROUP) += group.o
vfio-$(CONFIG_IOMMUFD) += iommufd.o
vfio-$(CONFIG_VFIO_CONTAINER) += container.o
vfio-$(CONFIG_VFIO_VIRQFD) += virqfd.o
+83 −6
Original line number Diff line number Diff line
@@ -36,6 +36,12 @@ vfio_allocate_device_file(struct vfio_device *device);

extern const struct file_operations vfio_device_fops;

#ifdef CONFIG_VFIO_NOIOMMU
extern bool vfio_noiommu __read_mostly;
#else
enum { vfio_noiommu = false };
#endif

enum vfio_group_type {
	/*
	 * Physical device with IOMMU backing.
@@ -60,6 +66,7 @@ enum vfio_group_type {
	VFIO_NO_IOMMU,
};

#if IS_ENABLED(CONFIG_VFIO_GROUP)
struct vfio_group {
	struct device 			dev;
	struct cdev			cdev;
@@ -111,6 +118,82 @@ static inline bool vfio_device_is_noiommu(struct vfio_device *vdev)
	return IS_ENABLED(CONFIG_VFIO_NOIOMMU) &&
	       vdev->group->type == VFIO_NO_IOMMU;
}
#else
struct vfio_group;

static inline int vfio_device_block_group(struct vfio_device *device)
{
	return 0;
}

static inline void vfio_device_unblock_group(struct vfio_device *device)
{
}

static inline int vfio_device_set_group(struct vfio_device *device,
					enum vfio_group_type type)
{
	return 0;
}

static inline void vfio_device_remove_group(struct vfio_device *device)
{
}

static inline void vfio_device_group_register(struct vfio_device *device)
{
}

static inline void vfio_device_group_unregister(struct vfio_device *device)
{
}

static inline int vfio_device_group_use_iommu(struct vfio_device *device)
{
	return -EOPNOTSUPP;
}

static inline void vfio_device_group_unuse_iommu(struct vfio_device *device)
{
}

static inline void vfio_df_group_close(struct vfio_device_file *df)
{
}

static inline struct vfio_group *vfio_group_from_file(struct file *file)
{
	return NULL;
}

static inline bool vfio_group_enforced_coherent(struct vfio_group *group)
{
	return true;
}

static inline void vfio_group_set_kvm(struct vfio_group *group, struct kvm *kvm)
{
}

static inline bool vfio_device_has_container(struct vfio_device *device)
{
	return false;
}

static inline int __init vfio_group_init(void)
{
	return 0;
}

static inline void vfio_group_cleanup(void)
{
}

static inline bool vfio_device_is_noiommu(struct vfio_device *vdev)
{
	return false;
}
#endif /* CONFIG_VFIO_GROUP */

#if IS_ENABLED(CONFIG_VFIO_CONTAINER)
/**
@@ -351,12 +434,6 @@ static inline void vfio_virqfd_exit(void)
}
#endif

#ifdef CONFIG_VFIO_NOIOMMU
extern bool vfio_noiommu __read_mostly;
#else
enum { vfio_noiommu = false };
#endif

#ifdef CONFIG_HAVE_KVM
void vfio_device_get_kvm_safe(struct vfio_device *device, struct kvm *kvm);
void vfio_device_put_kvm(struct vfio_device *device);
+22 −3
Original line number Diff line number Diff line
@@ -43,7 +43,11 @@ struct vfio_device {
	 */
	const struct vfio_migration_ops *mig_ops;
	const struct vfio_log_ops *log_ops;
#if IS_ENABLED(CONFIG_VFIO_GROUP)
	struct vfio_group *group;
	struct list_head group_next;
	struct list_head iommu_entry;
#endif
	struct vfio_device_set *dev_set;
	struct list_head dev_set_list;
	unsigned int migration_flags;
@@ -58,8 +62,6 @@ struct vfio_device {
	refcount_t refcount;	/* user count on registered device*/
	unsigned int open_count;
	struct completion comp;
	struct list_head group_next;
	struct list_head iommu_entry;
	struct iommufd_access *iommufd_access;
	void (*put_kvm)(struct kvm *kvm);
#if IS_ENABLED(CONFIG_IOMMUFD)
@@ -284,12 +286,29 @@ int vfio_mig_get_next_state(struct vfio_device *device,
/*
 * External user API
 */
#if IS_ENABLED(CONFIG_VFIO_GROUP)
struct iommu_group *vfio_file_iommu_group(struct file *file);
bool vfio_file_is_group(struct file *file);
bool vfio_file_has_dev(struct file *file, struct vfio_device *device);
#else
static inline struct iommu_group *vfio_file_iommu_group(struct file *file)
{
	return NULL;
}

static inline bool vfio_file_is_group(struct file *file)
{
	return false;
}

static inline bool vfio_file_has_dev(struct file *file, struct vfio_device *device)
{
	return false;
}
#endif
bool vfio_file_is_valid(struct file *file);
bool vfio_file_enforced_coherent(struct file *file);
void vfio_file_set_kvm(struct file *file, struct kvm *kvm);
bool vfio_file_has_dev(struct file *file, struct vfio_device *device);

#define VFIO_PIN_PAGES_MAX_ENTRIES	(PAGE_SIZE/sizeof(unsigned long))