466 lines · c
1/* SPDX-License-Identifier: GPL-2.0-only */2/*3 * Copyright (C) 2012 Red Hat, Inc. All rights reserved.4 * Author: Alex Williamson <alex.williamson@redhat.com>5 */6#ifndef __VFIO_VFIO_H__7#define __VFIO_VFIO_H__8 9#include <linux/file.h>10#include <linux/device.h>11#include <linux/cdev.h>12#include <linux/module.h>13#include <linux/vfio.h>14 15struct iommufd_ctx;16struct iommu_group;17struct vfio_container;18 19struct vfio_device_file {20 struct vfio_device *device;21 struct vfio_group *group;22 23 u8 access_granted;24 u32 devid; /* only valid when iommufd is valid */25 spinlock_t kvm_ref_lock; /* protect kvm field */26 struct kvm *kvm;27 struct iommufd_ctx *iommufd; /* protected by struct vfio_device_set::lock */28};29 30void vfio_device_put_registration(struct vfio_device *device);31bool vfio_device_try_get_registration(struct vfio_device *device);32int vfio_df_open(struct vfio_device_file *df);33void vfio_df_close(struct vfio_device_file *df);34struct vfio_device_file *35vfio_allocate_device_file(struct vfio_device *device);36 37extern const struct file_operations vfio_device_fops;38 39#ifdef CONFIG_VFIO_NOIOMMU40extern bool vfio_noiommu __read_mostly;41#else42enum { vfio_noiommu = false };43#endif44 45enum vfio_group_type {46 /*47 * Physical device with IOMMU backing.48 */49 VFIO_IOMMU,50 51 /*52 * Virtual device without IOMMU backing. The VFIO core fakes up an53 * iommu_group as the iommu_group sysfs interface is part of the54 * userspace ABI. The user of these devices must not be able to55 * directly trigger unmediated DMA.56 */57 VFIO_EMULATED_IOMMU,58 59 /*60 * Physical device without IOMMU backing. The VFIO core fakes up an61 * iommu_group as the iommu_group sysfs interface is part of the62 * userspace ABI. Users can trigger unmediated DMA by the device,63 * usage is highly dangerous, requires an explicit opt-in and will64 * taint the kernel.65 */66 VFIO_NO_IOMMU,67};68 69#if IS_ENABLED(CONFIG_VFIO_GROUP)70struct vfio_group {71 struct device dev;72 struct cdev cdev;73 /*74 * When drivers is non-zero a driver is attached to the struct device75 * that provided the iommu_group and thus the iommu_group is a valid76 * pointer. When drivers is 0 the driver is being detached. Once users77 * reaches 0 then the iommu_group is invalid.78 */79 refcount_t drivers;80 unsigned int container_users;81 struct iommu_group *iommu_group;82 struct vfio_container *container;83 struct list_head device_list;84 struct mutex device_lock;85 struct list_head vfio_next;86#if IS_ENABLED(CONFIG_VFIO_CONTAINER)87 struct list_head container_next;88#endif89 enum vfio_group_type type;90 struct mutex group_lock;91 struct kvm *kvm;92 struct file *opened_file;93 struct blocking_notifier_head notifier;94 struct iommufd_ctx *iommufd;95 spinlock_t kvm_ref_lock;96 unsigned int cdev_device_open_cnt;97};98 99int vfio_device_block_group(struct vfio_device *device);100void vfio_device_unblock_group(struct vfio_device *device);101int vfio_device_set_group(struct vfio_device *device,102 enum vfio_group_type type);103void vfio_device_remove_group(struct vfio_device *device);104void vfio_device_group_register(struct vfio_device *device);105void vfio_device_group_unregister(struct vfio_device *device);106int vfio_device_group_use_iommu(struct vfio_device *device);107void vfio_device_group_unuse_iommu(struct vfio_device *device);108void vfio_df_group_close(struct vfio_device_file *df);109struct vfio_group *vfio_group_from_file(struct file *file);110bool vfio_group_enforced_coherent(struct vfio_group *group);111void vfio_group_set_kvm(struct vfio_group *group, struct kvm *kvm);112bool vfio_device_has_container(struct vfio_device *device);113int __init vfio_group_init(void);114void vfio_group_cleanup(void);115 116static inline bool vfio_device_is_noiommu(struct vfio_device *vdev)117{118 return IS_ENABLED(CONFIG_VFIO_NOIOMMU) &&119 vdev->group->type == VFIO_NO_IOMMU;120}121#else122struct vfio_group;123 124static inline int vfio_device_block_group(struct vfio_device *device)125{126 return 0;127}128 129static inline void vfio_device_unblock_group(struct vfio_device *device)130{131}132 133static inline int vfio_device_set_group(struct vfio_device *device,134 enum vfio_group_type type)135{136 return 0;137}138 139static inline void vfio_device_remove_group(struct vfio_device *device)140{141}142 143static inline void vfio_device_group_register(struct vfio_device *device)144{145}146 147static inline void vfio_device_group_unregister(struct vfio_device *device)148{149}150 151static inline int vfio_device_group_use_iommu(struct vfio_device *device)152{153 return -EOPNOTSUPP;154}155 156static inline void vfio_device_group_unuse_iommu(struct vfio_device *device)157{158}159 160static inline void vfio_df_group_close(struct vfio_device_file *df)161{162}163 164static inline struct vfio_group *vfio_group_from_file(struct file *file)165{166 return NULL;167}168 169static inline bool vfio_group_enforced_coherent(struct vfio_group *group)170{171 return true;172}173 174static inline void vfio_group_set_kvm(struct vfio_group *group, struct kvm *kvm)175{176}177 178static inline bool vfio_device_has_container(struct vfio_device *device)179{180 return false;181}182 183static inline int __init vfio_group_init(void)184{185 return 0;186}187 188static inline void vfio_group_cleanup(void)189{190}191 192static inline bool vfio_device_is_noiommu(struct vfio_device *vdev)193{194 return false;195}196#endif /* CONFIG_VFIO_GROUP */197 198#if IS_ENABLED(CONFIG_VFIO_CONTAINER)199/**200 * struct vfio_iommu_driver_ops - VFIO IOMMU driver callbacks201 */202struct vfio_iommu_driver_ops {203 char *name;204 struct module *owner;205 void *(*open)(unsigned long arg);206 void (*release)(void *iommu_data);207 long (*ioctl)(void *iommu_data, unsigned int cmd,208 unsigned long arg);209 int (*attach_group)(void *iommu_data,210 struct iommu_group *group,211 enum vfio_group_type);212 void (*detach_group)(void *iommu_data,213 struct iommu_group *group);214 int (*pin_pages)(void *iommu_data,215 struct iommu_group *group,216 dma_addr_t user_iova,217 int npage, int prot,218 struct page **pages);219 void (*unpin_pages)(void *iommu_data,220 dma_addr_t user_iova, int npage);221 void (*register_device)(void *iommu_data,222 struct vfio_device *vdev);223 void (*unregister_device)(void *iommu_data,224 struct vfio_device *vdev);225 int (*dma_rw)(void *iommu_data, dma_addr_t user_iova,226 void *data, size_t count, bool write);227 struct iommu_domain *(*group_iommu_domain)(void *iommu_data,228 struct iommu_group *group);229};230 231struct vfio_iommu_driver {232 const struct vfio_iommu_driver_ops *ops;233 struct list_head vfio_next;234};235 236int vfio_register_iommu_driver(const struct vfio_iommu_driver_ops *ops);237void vfio_unregister_iommu_driver(const struct vfio_iommu_driver_ops *ops);238 239struct vfio_container *vfio_container_from_file(struct file *filep);240int vfio_group_use_container(struct vfio_group *group);241void vfio_group_unuse_container(struct vfio_group *group);242int vfio_container_attach_group(struct vfio_container *container,243 struct vfio_group *group);244void vfio_group_detach_container(struct vfio_group *group);245void vfio_device_container_register(struct vfio_device *device);246void vfio_device_container_unregister(struct vfio_device *device);247int vfio_device_container_pin_pages(struct vfio_device *device,248 dma_addr_t iova, int npage,249 int prot, struct page **pages);250void vfio_device_container_unpin_pages(struct vfio_device *device,251 dma_addr_t iova, int npage);252int vfio_device_container_dma_rw(struct vfio_device *device,253 dma_addr_t iova, void *data,254 size_t len, bool write);255 256int __init vfio_container_init(void);257void vfio_container_cleanup(void);258#else259static inline struct vfio_container *260vfio_container_from_file(struct file *filep)261{262 return NULL;263}264 265static inline int vfio_group_use_container(struct vfio_group *group)266{267 return -EOPNOTSUPP;268}269 270static inline void vfio_group_unuse_container(struct vfio_group *group)271{272}273 274static inline int vfio_container_attach_group(struct vfio_container *container,275 struct vfio_group *group)276{277 return -EOPNOTSUPP;278}279 280static inline void vfio_group_detach_container(struct vfio_group *group)281{282}283 284static inline void vfio_device_container_register(struct vfio_device *device)285{286}287 288static inline void vfio_device_container_unregister(struct vfio_device *device)289{290}291 292static inline int vfio_device_container_pin_pages(struct vfio_device *device,293 dma_addr_t iova, int npage,294 int prot, struct page **pages)295{296 return -EOPNOTSUPP;297}298 299static inline void vfio_device_container_unpin_pages(struct vfio_device *device,300 dma_addr_t iova, int npage)301{302}303 304static inline int vfio_device_container_dma_rw(struct vfio_device *device,305 dma_addr_t iova, void *data,306 size_t len, bool write)307{308 return -EOPNOTSUPP;309}310 311static inline int vfio_container_init(void)312{313 return 0;314}315static inline void vfio_container_cleanup(void)316{317}318#endif319 320#if IS_ENABLED(CONFIG_IOMMUFD)321bool vfio_iommufd_device_has_compat_ioas(struct vfio_device *vdev,322 struct iommufd_ctx *ictx);323int vfio_df_iommufd_bind(struct vfio_device_file *df);324void vfio_df_iommufd_unbind(struct vfio_device_file *df);325int vfio_iommufd_compat_attach_ioas(struct vfio_device *device,326 struct iommufd_ctx *ictx);327#else328static inline bool329vfio_iommufd_device_has_compat_ioas(struct vfio_device *vdev,330 struct iommufd_ctx *ictx)331{332 return false;333}334 335static inline int vfio_df_iommufd_bind(struct vfio_device_file *fd)336{337 return -EOPNOTSUPP;338}339 340static inline void vfio_df_iommufd_unbind(struct vfio_device_file *df)341{342}343 344static inline int345vfio_iommufd_compat_attach_ioas(struct vfio_device *device,346 struct iommufd_ctx *ictx)347{348 return -EOPNOTSUPP;349}350#endif351 352int vfio_df_ioctl_attach_pt(struct vfio_device_file *df,353 struct vfio_device_attach_iommufd_pt __user *arg);354int vfio_df_ioctl_detach_pt(struct vfio_device_file *df,355 struct vfio_device_detach_iommufd_pt __user *arg);356 357#if IS_ENABLED(CONFIG_VFIO_DEVICE_CDEV)358void vfio_init_device_cdev(struct vfio_device *device);359 360static inline int vfio_device_add(struct vfio_device *device)361{362 /* cdev does not support noiommu device */363 if (vfio_device_is_noiommu(device))364 return device_add(&device->device);365 vfio_init_device_cdev(device);366 return cdev_device_add(&device->cdev, &device->device);367}368 369static inline void vfio_device_del(struct vfio_device *device)370{371 if (vfio_device_is_noiommu(device))372 device_del(&device->device);373 else374 cdev_device_del(&device->cdev, &device->device);375}376 377int vfio_device_fops_cdev_open(struct inode *inode, struct file *filep);378long vfio_df_ioctl_bind_iommufd(struct vfio_device_file *df,379 struct vfio_device_bind_iommufd __user *arg);380void vfio_df_unbind_iommufd(struct vfio_device_file *df);381int vfio_cdev_init(struct class *device_class);382void vfio_cdev_cleanup(void);383#else384static inline void vfio_init_device_cdev(struct vfio_device *device)385{386}387 388static inline int vfio_device_add(struct vfio_device *device)389{390 return device_add(&device->device);391}392 393static inline void vfio_device_del(struct vfio_device *device)394{395 device_del(&device->device);396}397 398static inline int vfio_device_fops_cdev_open(struct inode *inode,399 struct file *filep)400{401 return 0;402}403 404static inline long vfio_df_ioctl_bind_iommufd(struct vfio_device_file *df,405 struct vfio_device_bind_iommufd __user *arg)406{407 return -ENOTTY;408}409 410static inline void vfio_df_unbind_iommufd(struct vfio_device_file *df)411{412}413 414static inline int vfio_cdev_init(struct class *device_class)415{416 return 0;417}418 419static inline void vfio_cdev_cleanup(void)420{421}422#endif /* CONFIG_VFIO_DEVICE_CDEV */423 424#if IS_ENABLED(CONFIG_VFIO_VIRQFD)425int __init vfio_virqfd_init(void);426void vfio_virqfd_exit(void);427#else428static inline int __init vfio_virqfd_init(void)429{430 return 0;431}432static inline void vfio_virqfd_exit(void)433{434}435#endif436 437#if IS_ENABLED(CONFIG_KVM)438void vfio_device_get_kvm_safe(struct vfio_device *device, struct kvm *kvm);439void vfio_device_put_kvm(struct vfio_device *device);440#else441static inline void vfio_device_get_kvm_safe(struct vfio_device *device,442 struct kvm *kvm)443{444}445 446static inline void vfio_device_put_kvm(struct vfio_device *device)447{448}449#endif450 451#ifdef CONFIG_VFIO_DEBUGFS452void vfio_debugfs_create_root(void);453void vfio_debugfs_remove_root(void);454 455void vfio_device_debugfs_init(struct vfio_device *vdev);456void vfio_device_debugfs_exit(struct vfio_device *vdev);457#else458static inline void vfio_debugfs_create_root(void) { }459static inline void vfio_debugfs_remove_root(void) { }460 461static inline void vfio_device_debugfs_init(struct vfio_device *vdev) { }462static inline void vfio_device_debugfs_exit(struct vfio_device *vdev) { }463#endif /* CONFIG_VFIO_DEBUGFS */464 465#endif466