vfio.h 9.7 KB
Newer Older
1
/* SPDX-License-Identifier: GPL-2.0-only */
A
Alex Williamson 已提交
2 3 4 5 6 7 8 9 10 11 12 13
/*
 * VFIO API definition
 *
 * Copyright (C) 2012 Red Hat, Inc.  All rights reserved.
 *     Author: Alex Williamson <alex.williamson@redhat.com>
 */
#ifndef VFIO_H
#define VFIO_H


#include <linux/iommu.h>
#include <linux/mm.h>
14 15
#include <linux/workqueue.h>
#include <linux/poll.h>
16
#include <uapi/linux/vfio.h>
A
Alex Williamson 已提交
17

18 19 20 21 22 23 24 25 26 27 28 29
struct vfio_device {
	struct device *dev;
	const struct vfio_device_ops *ops;
	struct vfio_group *group;

	/* Members below here are private, not for driver use */
	refcount_t refcount;
	struct completion comp;
	struct list_head group_next;
	void *device_data;
};

A
Alex Williamson 已提交
30 31 32 33 34 35 36 37 38 39
/**
 * struct vfio_device_ops - VFIO bus driver device callbacks
 *
 * @open: Called when userspace creates new file descriptor for device
 * @release: Called when userspace releases file descriptor for device
 * @read: Perform read(2) on device file descriptor
 * @write: Perform write(2) on device file descriptor
 * @ioctl: Perform ioctl(2) on device file descriptor, supporting VFIO_DEVICE_*
 *         operations documented below
 * @mmap: Perform mmap(2) on a region of the device file descriptor
40
 * @request: Request for the bus driver to release the device
41 42 43
 * @match: Optional device name match callback (return: 0 for no-match, >0 for
 *         match, -errno for abort (ex. match with insufficient or incorrect
 *         additional args)
A
Alex Williamson 已提交
44 45 46 47 48 49 50 51 52 53 54 55
 */
struct vfio_device_ops {
	char	*name;
	int	(*open)(void *device_data);
	void	(*release)(void *device_data);
	ssize_t	(*read)(void *device_data, char __user *buf,
			size_t count, loff_t *ppos);
	ssize_t	(*write)(void *device_data, const char __user *buf,
			 size_t count, loff_t *size);
	long	(*ioctl)(void *device_data, unsigned int cmd,
			 unsigned long arg);
	int	(*mmap)(void *device_data, struct vm_area_struct *vma);
56
	void	(*request)(void *device_data, unsigned int count);
57
	int	(*match)(void *device_data, char *buf);
A
Alex Williamson 已提交
58 59
};

A
Alex Williamson 已提交
60 61 62
extern struct iommu_group *vfio_iommu_group_get(struct device *dev);
extern void vfio_iommu_group_put(struct iommu_group *group, struct device *dev);

63 64 65
void vfio_init_group_dev(struct vfio_device *device, struct device *dev,
			 const struct vfio_device_ops *ops, void *device_data);
int vfio_register_group_dev(struct vfio_device *device);
A
Alex Williamson 已提交
66 67 68 69 70
extern int vfio_add_group_dev(struct device *dev,
			      const struct vfio_device_ops *ops,
			      void *device_data);

extern void *vfio_del_group_dev(struct device *dev);
71
void vfio_unregister_group_dev(struct vfio_device *device);
72 73 74
extern struct vfio_device *vfio_device_get_from_dev(struct device *dev);
extern void vfio_device_put(struct vfio_device *device);
extern void *vfio_device_data(struct vfio_device *device);
A
Alex Williamson 已提交
75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94

/**
 * struct vfio_iommu_driver_ops - VFIO IOMMU driver callbacks
 */
struct vfio_iommu_driver_ops {
	char		*name;
	struct module	*owner;
	void		*(*open)(unsigned long arg);
	void		(*release)(void *iommu_data);
	ssize_t		(*read)(void *iommu_data, char __user *buf,
				size_t count, loff_t *ppos);
	ssize_t		(*write)(void *iommu_data, const char __user *buf,
				 size_t count, loff_t *size);
	long		(*ioctl)(void *iommu_data, unsigned int cmd,
				 unsigned long arg);
	int		(*mmap)(void *iommu_data, struct vm_area_struct *vma);
	int		(*attach_group)(void *iommu_data,
					struct iommu_group *group);
	void		(*detach_group)(void *iommu_data,
					struct iommu_group *group);
95 96 97
	int		(*pin_pages)(void *iommu_data,
				     struct iommu_group *group,
				     unsigned long *user_pfn,
98 99 100 101
				     int npage, int prot,
				     unsigned long *phys_pfn);
	int		(*unpin_pages)(void *iommu_data,
				       unsigned long *user_pfn, int npage);
102
	int		(*register_notifier)(void *iommu_data,
103
					     unsigned long *events,
104 105 106
					     struct notifier_block *nb);
	int		(*unregister_notifier)(void *iommu_data,
					       struct notifier_block *nb);
107 108
	int		(*dma_rw)(void *iommu_data, dma_addr_t user_iova,
				  void *data, size_t count, bool write);
109 110
	KABI_EXTEND(struct iommu_domain *(*group_iommu_domain)(void *iommu_data,
						               struct iommu_group *group))
A
Alex Williamson 已提交
111 112 113 114 115 116 117
};

extern int vfio_register_iommu_driver(const struct vfio_iommu_driver_ops *ops);

extern void vfio_unregister_iommu_driver(
				const struct vfio_iommu_driver_ops *ops);

118 119 120 121 122
/*
 * External user API
 */
extern struct vfio_group *vfio_group_get_external_user(struct file *filep);
extern void vfio_group_put_external_user(struct vfio_group *group);
123 124
extern struct vfio_group *vfio_group_get_external_user_from_dev(struct device
								*dev);
125 126
extern bool vfio_external_group_match_file(struct vfio_group *group,
					   struct file *filep);
127
extern int vfio_external_user_iommu_id(struct vfio_group *group);
128 129
extern long vfio_external_check_extension(struct vfio_group *group,
					  unsigned long arg);
130

131 132 133 134 135 136 137
#define VFIO_PIN_PAGES_MAX_ENTRIES	(PAGE_SIZE/sizeof(unsigned long))

extern int vfio_pin_pages(struct device *dev, unsigned long *user_pfn,
			  int npage, int prot, unsigned long *phys_pfn);
extern int vfio_unpin_pages(struct device *dev, unsigned long *user_pfn,
			    int npage);

138 139 140 141 142 143
extern int vfio_group_pin_pages(struct vfio_group *group,
				unsigned long *user_iova_pfn, int npage,
				int prot, unsigned long *phys_pfn);
extern int vfio_group_unpin_pages(struct vfio_group *group,
				  unsigned long *user_iova_pfn, int npage);

144 145 146
extern int vfio_dma_rw(struct vfio_group *group, dma_addr_t user_iova,
		       void *data, size_t len, bool write);

147 148
extern struct iommu_domain *vfio_group_iommu_domain(struct vfio_group *group);

149 150 151
/* each type has independent events */
enum vfio_notify_type {
	VFIO_IOMMU_NOTIFY = 0,
152
	VFIO_GROUP_NOTIFY = 1,
153 154 155 156
};

/* events for VFIO_IOMMU_NOTIFY */
#define VFIO_IOMMU_NOTIFY_DMA_UNMAP	BIT(0)
157

158 159 160
/* events for VFIO_GROUP_NOTIFY */
#define VFIO_GROUP_NOTIFY_SET_KVM	BIT(0)

161
extern int vfio_register_notifier(struct device *dev,
162 163
				  enum vfio_notify_type type,
				  unsigned long *required_events,
164 165
				  struct notifier_block *nb);
extern int vfio_unregister_notifier(struct device *dev,
166
				    enum vfio_notify_type type,
167 168
				    struct notifier_block *nb);

169 170 171
struct kvm;
extern void vfio_group_set_kvm(struct vfio_group *group, struct kvm *kvm);

172 173 174 175 176 177 178 179 180 181 182
/*
 * Sub-module helpers
 */
struct vfio_info_cap {
	struct vfio_info_cap_header *buf;
	size_t size;
};
extern struct vfio_info_cap_header *vfio_info_cap_add(
		struct vfio_info_cap *caps, size_t size, u16 id, u16 version);
extern void vfio_info_cap_shift(struct vfio_info_cap *caps, size_t offset);

183
extern int vfio_info_add_capability(struct vfio_info_cap *caps,
A
Alex Williamson 已提交
184 185
				    struct vfio_info_cap_header *cap,
				    size_t size);
186

187 188 189 190
extern int vfio_set_irqs_validate_and_prepare(struct vfio_irq_set *hdr,
					      int num_irqs, int max_irq_type,
					      size_t *data_size);

G
Gavin Shan 已提交
191
struct pci_dev;
192
#if IS_ENABLED(CONFIG_VFIO_SPAPR_EEH)
193
extern void vfio_spapr_pci_eeh_open(struct pci_dev *pdev);
194 195 196 197 198
extern void vfio_spapr_pci_eeh_release(struct pci_dev *pdev);
extern long vfio_spapr_iommu_eeh_ioctl(struct iommu_group *group,
				       unsigned int cmd,
				       unsigned long arg);
#else
199
static inline void vfio_spapr_pci_eeh_open(struct pci_dev *pdev)
200 201 202 203 204 205 206 207 208 209 210 211 212
{
}

static inline void vfio_spapr_pci_eeh_release(struct pci_dev *pdev)
{
}

static inline long vfio_spapr_iommu_eeh_ioctl(struct iommu_group *group,
					      unsigned int cmd,
					      unsigned long arg)
{
	return -ENOTTY;
}
213
#endif /* CONFIG_VFIO_SPAPR_EEH */
214 215 216 217 218 219 220 221 222 223 224

/*
 * IRQfd - generic
 */
struct virqfd {
	void			*opaque;
	struct eventfd_ctx	*eventfd;
	int			(*handler)(void *, void *);
	void			(*thread)(void *, void *);
	void			*data;
	struct work_struct	inject;
225
	wait_queue_entry_t		wait;
226 227 228 229 230 231 232 233 234 235 236
	poll_table		pt;
	struct work_struct	shutdown;
	struct virqfd		**pvirqfd;
};

extern int vfio_virqfd_enable(void *opaque,
			      int (*handler)(void *, void *),
			      void (*thread)(void *, void *),
			      void *data, struct virqfd **pvirqfd, int fd);
extern void vfio_virqfd_disable(struct virqfd **pvirqfd);

237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288
extern int vfio_pci_num_regions(void *device_data);
extern struct pci_dev *vfio_pci_pdev(void *device_data);
extern long vfio_pci_ioctl(void *device_data,
			  unsigned int cmd, unsigned long arg);
extern ssize_t vfio_pci_read(void *device_data, char __user *buf,
			     size_t count, loff_t *ppos);
extern ssize_t vfio_pci_write(void *device_data, const char __user *buf,
			      size_t count, loff_t *ppos);
extern int vfio_pci_mmap(void *device_data, struct vm_area_struct *vma);
extern void vfio_pci_request(void *device_data, unsigned int count);
extern int vfio_pci_open(void *device_data);
extern void vfio_pci_release(void *device_data);
extern void *vfio_pci_vendor_data(void *device_data);
extern int vfio_pci_set_vendor_regions(void *device_data,
					int num_vendor_regions);

struct vfio_pci_vendor_driver_ops {
	char			*name;
	struct module		*owner;
	void			*(*probe)(struct pci_dev *pdev);
	void			(*remove)(void *vendor_data);
	struct vfio_device_ops *device_ops;
};
int __vfio_pci_register_vendor_driver(struct vfio_pci_vendor_driver_ops *ops);
void vfio_pci_unregister_vendor_driver(struct vfio_device_ops *device_ops);

#define vfio_pci_register_vendor_driver(__name, __probe, __remove,	\
					__device_ops)			\
static struct vfio_pci_vendor_driver_ops  __ops ## _node = {		\
	.owner		= THIS_MODULE,					\
	.name		= __name,					\
	.probe		= __probe,					\
	.remove		= __remove,					\
	.device_ops	= __device_ops,					\
};									\
__vfio_pci_register_vendor_driver(&__ops ## _node)

#define module_vfio_pci_register_vendor_handler(name, probe, remove,	\
						device_ops)		\
static int __init device_ops ## _module_init(void)			\
{									\
	vfio_pci_register_vendor_driver(name, probe, remove,		\
					device_ops);			\
	return 0;							\
};									\
static void __exit device_ops ## _module_exit(void)			\
{									\
	vfio_pci_unregister_vendor_driver(device_ops);			\
};									\
module_init(device_ops ## _module_init);				\
module_exit(device_ops ## _module_exit)

A
Alex Williamson 已提交
289
#endif /* VFIO_H */