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: Jason Gunthorpe <jgg@nvidia.com>
Tested-by: Nicolin Chen <nicolinc@nvidia.com>
Tested-by: Matthew Rosato <mjrosato@linux.ibm.com>
Tested-by: Yanting Jiang <yanting.jiang@intel.com>
Tested-by: Shameer Kolothum <shameerali.kolothum.thodi@huawei.com>
Tested-by: Terrence Xu <terrence.xu@intel.com>
Tested-by: Zhenzhong Duan <zhenzhong.duan@intel.com>
Signed-off-by: Yi Liu <yi.l.liu@intel.com>
Link: https://lore.kernel.org/r/20230718135551.6592-26-yi.l.liu@intel.com
Signed-off-by: Alex Williamson <alex.williamson@redhat.com>
This commit is contained in:
Yi Liu 2023-07-18 06:55:50 -07:00 committed by Alex Williamson
parent 5398be2564
commit c1cce6d079
5 changed files with 123 additions and 12 deletions

View File

@ -14,8 +14,8 @@ config IOMMUFD
if IOMMUFD if IOMMUFD
config IOMMUFD_VFIO_CONTAINER config IOMMUFD_VFIO_CONTAINER
bool "IOMMUFD provides the VFIO container /dev/vfio/vfio" bool "IOMMUFD provides the VFIO container /dev/vfio/vfio"
depends on VFIO && !VFIO_CONTAINER depends on VFIO_GROUP && !VFIO_CONTAINER
default VFIO && !VFIO_CONTAINER default VFIO_GROUP && !VFIO_CONTAINER
help help
IOMMUFD will provide /dev/vfio/vfio instead of VFIO. This relies on IOMMUFD will provide /dev/vfio/vfio instead of VFIO. This relies on
IOMMUFD providing compatibility emulation to give the same ioctls. IOMMUFD providing compatibility emulation to give the same ioctls.

View File

@ -4,6 +4,8 @@ menuconfig VFIO
select IOMMU_API select IOMMU_API
depends on IOMMUFD || !IOMMUFD depends on IOMMUFD || !IOMMUFD
select INTERVAL_TREE 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 select VFIO_CONTAINER if IOMMUFD=n
help help
VFIO provides a framework for secure userspace device drivers. VFIO provides a framework for secure userspace device drivers.
@ -15,6 +17,7 @@ if VFIO
config VFIO_DEVICE_CDEV config VFIO_DEVICE_CDEV
bool "Support for the VFIO cdev /dev/vfio/devices/vfioX" bool "Support for the VFIO cdev /dev/vfio/devices/vfioX"
depends on IOMMUFD && !SPAPR_TCE_IOMMU depends on IOMMUFD && !SPAPR_TCE_IOMMU
default !VFIO_GROUP
help help
The VFIO device cdev is another way for userspace to get device The VFIO device cdev is another way for userspace to get device
access. Userspace gets device fd by opening device cdev under 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. 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 config VFIO_CONTAINER
bool "Support for the VFIO container /dev/vfio/vfio" bool "Support for the VFIO container /dev/vfio/vfio"
select VFIO_IOMMU_TYPE1 if MMU && (X86 || S390 || ARM || ARM64) select VFIO_IOMMU_TYPE1 if MMU && (X86 || S390 || ARM || ARM64)
depends on VFIO_GROUP
default y default y
help help
The VFIO container is the classic interface to VFIO for establishing The VFIO container is the classic interface to VFIO for establishing
@ -48,6 +62,7 @@ endif
config VFIO_NOIOMMU config VFIO_NOIOMMU
bool "VFIO No-IOMMU support" bool "VFIO No-IOMMU support"
depends on VFIO_GROUP
help help
VFIO is built on the ability to isolate devices using the IOMMU. VFIO is built on the ability to isolate devices using the IOMMU.
Only with an IOMMU can userspace access to DMA capable devices be Only with an IOMMU can userspace access to DMA capable devices be

View File

@ -2,9 +2,9 @@
obj-$(CONFIG_VFIO) += vfio.o obj-$(CONFIG_VFIO) += vfio.o
vfio-y += vfio_main.o \ vfio-y += vfio_main.o \
group.o \
iova_bitmap.o iova_bitmap.o
vfio-$(CONFIG_VFIO_DEVICE_CDEV) += device_cdev.o vfio-$(CONFIG_VFIO_DEVICE_CDEV) += device_cdev.o
vfio-$(CONFIG_VFIO_GROUP) += group.o
vfio-$(CONFIG_IOMMUFD) += iommufd.o vfio-$(CONFIG_IOMMUFD) += iommufd.o
vfio-$(CONFIG_VFIO_CONTAINER) += container.o vfio-$(CONFIG_VFIO_CONTAINER) += container.o
vfio-$(CONFIG_VFIO_VIRQFD) += virqfd.o vfio-$(CONFIG_VFIO_VIRQFD) += virqfd.o

View File

@ -36,6 +36,12 @@ vfio_allocate_device_file(struct vfio_device *device);
extern const struct file_operations vfio_device_fops; 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 { enum vfio_group_type {
/* /*
* Physical device with IOMMU backing. * Physical device with IOMMU backing.
@ -60,6 +66,7 @@ enum vfio_group_type {
VFIO_NO_IOMMU, VFIO_NO_IOMMU,
}; };
#if IS_ENABLED(CONFIG_VFIO_GROUP)
struct vfio_group { struct vfio_group {
struct device dev; struct device dev;
struct cdev cdev; struct cdev cdev;
@ -111,6 +118,82 @@ static inline bool vfio_device_is_noiommu(struct vfio_device *vdev)
return IS_ENABLED(CONFIG_VFIO_NOIOMMU) && return IS_ENABLED(CONFIG_VFIO_NOIOMMU) &&
vdev->group->type == VFIO_NO_IOMMU; 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) #if IS_ENABLED(CONFIG_VFIO_CONTAINER)
/** /**
@ -351,12 +434,6 @@ static inline void vfio_virqfd_exit(void)
} }
#endif #endif
#ifdef CONFIG_VFIO_NOIOMMU
extern bool vfio_noiommu __read_mostly;
#else
enum { vfio_noiommu = false };
#endif
#ifdef CONFIG_HAVE_KVM #ifdef CONFIG_HAVE_KVM
void vfio_device_get_kvm_safe(struct vfio_device *device, struct kvm *kvm); void vfio_device_get_kvm_safe(struct vfio_device *device, struct kvm *kvm);
void vfio_device_put_kvm(struct vfio_device *device); void vfio_device_put_kvm(struct vfio_device *device);

View File

@ -43,7 +43,11 @@ struct vfio_device {
*/ */
const struct vfio_migration_ops *mig_ops; const struct vfio_migration_ops *mig_ops;
const struct vfio_log_ops *log_ops; const struct vfio_log_ops *log_ops;
#if IS_ENABLED(CONFIG_VFIO_GROUP)
struct vfio_group *group; struct vfio_group *group;
struct list_head group_next;
struct list_head iommu_entry;
#endif
struct vfio_device_set *dev_set; struct vfio_device_set *dev_set;
struct list_head dev_set_list; struct list_head dev_set_list;
unsigned int migration_flags; unsigned int migration_flags;
@ -58,8 +62,6 @@ struct vfio_device {
refcount_t refcount; /* user count on registered device*/ refcount_t refcount; /* user count on registered device*/
unsigned int open_count; unsigned int open_count;
struct completion comp; struct completion comp;
struct list_head group_next;
struct list_head iommu_entry;
struct iommufd_access *iommufd_access; struct iommufd_access *iommufd_access;
void (*put_kvm)(struct kvm *kvm); void (*put_kvm)(struct kvm *kvm);
#if IS_ENABLED(CONFIG_IOMMUFD) #if IS_ENABLED(CONFIG_IOMMUFD)
@ -284,12 +286,29 @@ int vfio_mig_get_next_state(struct vfio_device *device,
/* /*
* External user API * External user API
*/ */
#if IS_ENABLED(CONFIG_VFIO_GROUP)
struct iommu_group *vfio_file_iommu_group(struct file *file); struct iommu_group *vfio_file_iommu_group(struct file *file);
bool vfio_file_is_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_is_valid(struct file *file);
bool vfio_file_enforced_coherent(struct file *file); bool vfio_file_enforced_coherent(struct file *file);
void vfio_file_set_kvm(struct file *file, struct kvm *kvm); 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)) #define VFIO_PIN_PAGES_MAX_ENTRIES (PAGE_SIZE/sizeof(unsigned long))