Skip to content

Commit

Permalink
vfio: Compile vfio_group infrastructure optionally
Browse files Browse the repository at this point in the history
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>
  • Loading branch information
Yi Liu authored and Alex Williamson committed Jul 25, 2023
1 parent 5398be2 commit c1cce6d
Show file tree
Hide file tree
Showing 5 changed files with 123 additions and 12 deletions.
4 changes: 2 additions & 2 deletions drivers/iommu/iommufd/Kconfig
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Expand Down
15 changes: 15 additions & 0 deletions drivers/vfio/Kconfig
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Expand All @@ -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
Expand All @@ -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
Expand All @@ -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
Expand Down
2 changes: 1 addition & 1 deletion drivers/vfio/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
89 changes: 83 additions & 6 deletions drivers/vfio/vfio.h
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Expand All @@ -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;
Expand Down Expand Up @@ -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)
/**
Expand Down Expand Up @@ -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);
Expand Down
25 changes: 22 additions & 3 deletions include/linux/vfio.h
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand All @@ -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)
Expand Down Expand Up @@ -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))

Expand Down

0 comments on commit c1cce6d

Please sign in to comment.