Commit | Line | Data |
---|---|---|
d2912cb1 | 1 | /* SPDX-License-Identifier: GPL-2.0-only */ |
cba3345c AW |
2 | /* |
3 | * VFIO API definition | |
4 | * | |
5 | * Copyright (C) 2012 Red Hat, Inc. All rights reserved. | |
6 | * Author: Alex Williamson <alex.williamson@redhat.com> | |
cba3345c AW |
7 | */ |
8 | #ifndef VFIO_H | |
9 | #define VFIO_H | |
10 | ||
cba3345c AW |
11 | |
12 | #include <linux/iommu.h> | |
13 | #include <linux/mm.h> | |
7e992d69 AM |
14 | #include <linux/workqueue.h> |
15 | #include <linux/poll.h> | |
607ca46e | 16 | #include <uapi/linux/vfio.h> |
cba3345c | 17 | |
2fd585f4 JG |
18 | /* |
19 | * VFIO devices can be placed in a set, this allows all devices to share this | |
20 | * structure and the VFIO core will provide a lock that is held around | |
21 | * open_device()/close_device() for all devices in the set. | |
22 | */ | |
23 | struct vfio_device_set { | |
24 | void *set_id; | |
25 | struct mutex lock; | |
26 | struct list_head device_list; | |
27 | unsigned int device_count; | |
28 | }; | |
29 | ||
0bfc6a4e JG |
30 | struct vfio_device { |
31 | struct device *dev; | |
32 | const struct vfio_device_ops *ops; | |
33 | struct vfio_group *group; | |
2fd585f4 JG |
34 | struct vfio_device_set *dev_set; |
35 | struct list_head dev_set_list; | |
8cb3d83b | 36 | unsigned int migration_flags; |
0bfc6a4e JG |
37 | |
38 | /* Members below here are private, not for driver use */ | |
39 | refcount_t refcount; | |
2fd585f4 | 40 | unsigned int open_count; |
0bfc6a4e JG |
41 | struct completion comp; |
42 | struct list_head group_next; | |
0bfc6a4e JG |
43 | }; |
44 | ||
cba3345c AW |
45 | /** |
46 | * struct vfio_device_ops - VFIO bus driver device callbacks | |
47 | * | |
2fd585f4 JG |
48 | * @open_device: Called when the first file descriptor is opened for this device |
49 | * @close_device: Opposite of open_device | |
cba3345c AW |
50 | * @read: Perform read(2) on device file descriptor |
51 | * @write: Perform write(2) on device file descriptor | |
52 | * @ioctl: Perform ioctl(2) on device file descriptor, supporting VFIO_DEVICE_* | |
53 | * operations documented below | |
54 | * @mmap: Perform mmap(2) on a region of the device file descriptor | |
13060b64 | 55 | * @request: Request for the bus driver to release the device |
5f3874c2 AW |
56 | * @match: Optional device name match callback (return: 0 for no-match, >0 for |
57 | * match, -errno for abort (ex. match with insufficient or incorrect | |
58 | * additional args) | |
445ad495 | 59 | * @device_feature: Optional, fill in the VFIO_DEVICE_FEATURE ioctl |
115dcec6 JG |
60 | * @migration_set_state: Optional callback to change the migration state for |
61 | * devices that support migration. It's mandatory for | |
62 | * VFIO_DEVICE_FEATURE_MIGRATION migration support. | |
63 | * The returned FD is used for data transfer according to the FSM | |
64 | * definition. The driver is responsible to ensure that FD reaches end | |
65 | * of stream or error whenever the migration FSM leaves a data transfer | |
66 | * state or before close_device() returns. | |
67 | * @migration_get_state: Optional callback to get the migration state for | |
68 | * devices that support migration. It's mandatory for | |
69 | * VFIO_DEVICE_FEATURE_MIGRATION migration support. | |
cba3345c AW |
70 | */ |
71 | struct vfio_device_ops { | |
72 | char *name; | |
2fd585f4 JG |
73 | int (*open_device)(struct vfio_device *vdev); |
74 | void (*close_device)(struct vfio_device *vdev); | |
6df62c5b | 75 | ssize_t (*read)(struct vfio_device *vdev, char __user *buf, |
cba3345c | 76 | size_t count, loff_t *ppos); |
6df62c5b | 77 | ssize_t (*write)(struct vfio_device *vdev, const char __user *buf, |
cba3345c | 78 | size_t count, loff_t *size); |
6df62c5b | 79 | long (*ioctl)(struct vfio_device *vdev, unsigned int cmd, |
cba3345c | 80 | unsigned long arg); |
6df62c5b JG |
81 | int (*mmap)(struct vfio_device *vdev, struct vm_area_struct *vma); |
82 | void (*request)(struct vfio_device *vdev, unsigned int count); | |
83 | int (*match)(struct vfio_device *vdev, char *buf); | |
445ad495 JG |
84 | int (*device_feature)(struct vfio_device *device, u32 flags, |
85 | void __user *arg, size_t argsz); | |
115dcec6 JG |
86 | struct file *(*migration_set_state)( |
87 | struct vfio_device *device, | |
88 | enum vfio_device_mig_state new_state); | |
89 | int (*migration_get_state)(struct vfio_device *device, | |
90 | enum vfio_device_mig_state *curr_state); | |
cba3345c AW |
91 | }; |
92 | ||
445ad495 JG |
93 | /** |
94 | * vfio_check_feature - Validate user input for the VFIO_DEVICE_FEATURE ioctl | |
95 | * @flags: Arg from the device_feature op | |
96 | * @argsz: Arg from the device_feature op | |
97 | * @supported_ops: Combination of VFIO_DEVICE_FEATURE_GET and SET the driver | |
98 | * supports | |
99 | * @minsz: Minimum data size the driver accepts | |
100 | * | |
101 | * For use in a driver's device_feature op. Checks that the inputs to the | |
102 | * VFIO_DEVICE_FEATURE ioctl are correct for the driver's feature. Returns 1 if | |
103 | * the driver should execute the get or set, otherwise the relevant | |
104 | * value should be returned. | |
105 | */ | |
106 | static inline int vfio_check_feature(u32 flags, size_t argsz, u32 supported_ops, | |
107 | size_t minsz) | |
108 | { | |
109 | if ((flags & (VFIO_DEVICE_FEATURE_GET | VFIO_DEVICE_FEATURE_SET)) & | |
110 | ~supported_ops) | |
111 | return -EINVAL; | |
112 | if (flags & VFIO_DEVICE_FEATURE_PROBE) | |
113 | return 0; | |
114 | /* Without PROBE one of GET or SET must be requested */ | |
115 | if (!(flags & (VFIO_DEVICE_FEATURE_GET | VFIO_DEVICE_FEATURE_SET))) | |
116 | return -EINVAL; | |
117 | if (argsz < minsz) | |
118 | return -EINVAL; | |
119 | return 1; | |
120 | } | |
121 | ||
0bfc6a4e | 122 | void vfio_init_group_dev(struct vfio_device *device, struct device *dev, |
1e04ec14 | 123 | const struct vfio_device_ops *ops); |
ae03c377 | 124 | void vfio_uninit_group_dev(struct vfio_device *device); |
0bfc6a4e | 125 | int vfio_register_group_dev(struct vfio_device *device); |
c68ea0d0 | 126 | int vfio_register_emulated_iommu_dev(struct vfio_device *device); |
0bfc6a4e | 127 | void vfio_unregister_group_dev(struct vfio_device *device); |
44f50716 VMP |
128 | extern struct vfio_device *vfio_device_get_from_dev(struct device *dev); |
129 | extern void vfio_device_put(struct vfio_device *device); | |
cba3345c | 130 | |
2fd585f4 JG |
131 | int vfio_assign_device_set(struct vfio_device *device, void *set_id); |
132 | ||
115dcec6 JG |
133 | int vfio_mig_get_next_state(struct vfio_device *device, |
134 | enum vfio_device_mig_state cur_fsm, | |
135 | enum vfio_device_mig_state new_fsm, | |
136 | enum vfio_device_mig_state *next_fsm); | |
137 | ||
6cdd9782 AK |
138 | /* |
139 | * External user API | |
140 | */ | |
141 | extern struct vfio_group *vfio_group_get_external_user(struct file *filep); | |
142 | extern void vfio_group_put_external_user(struct vfio_group *group); | |
c0560f51 YZ |
143 | extern struct vfio_group *vfio_group_get_external_user_from_dev(struct device |
144 | *dev); | |
5d6dee80 AW |
145 | extern bool vfio_external_group_match_file(struct vfio_group *group, |
146 | struct file *filep); | |
6cdd9782 | 147 | extern int vfio_external_user_iommu_id(struct vfio_group *group); |
88d7ab89 AW |
148 | extern long vfio_external_check_extension(struct vfio_group *group, |
149 | unsigned long arg); | |
6cdd9782 | 150 | |
2169037d KW |
151 | #define VFIO_PIN_PAGES_MAX_ENTRIES (PAGE_SIZE/sizeof(unsigned long)) |
152 | ||
153 | extern int vfio_pin_pages(struct device *dev, unsigned long *user_pfn, | |
154 | int npage, int prot, unsigned long *phys_pfn); | |
155 | extern int vfio_unpin_pages(struct device *dev, unsigned long *user_pfn, | |
156 | int npage); | |
157 | ||
40280cf7 YZ |
158 | extern int vfio_group_pin_pages(struct vfio_group *group, |
159 | unsigned long *user_iova_pfn, int npage, | |
160 | int prot, unsigned long *phys_pfn); | |
161 | extern int vfio_group_unpin_pages(struct vfio_group *group, | |
162 | unsigned long *user_iova_pfn, int npage); | |
163 | ||
8d46c0cc YZ |
164 | extern int vfio_dma_rw(struct vfio_group *group, dma_addr_t user_iova, |
165 | void *data, size_t len, bool write); | |
166 | ||
bdfae1c9 LB |
167 | extern struct iommu_domain *vfio_group_iommu_domain(struct vfio_group *group); |
168 | ||
22195cbd JS |
169 | /* each type has independent events */ |
170 | enum vfio_notify_type { | |
171 | VFIO_IOMMU_NOTIFY = 0, | |
ccd46dba | 172 | VFIO_GROUP_NOTIFY = 1, |
22195cbd JS |
173 | }; |
174 | ||
175 | /* events for VFIO_IOMMU_NOTIFY */ | |
176 | #define VFIO_IOMMU_NOTIFY_DMA_UNMAP BIT(0) | |
c086de81 | 177 | |
ccd46dba JS |
178 | /* events for VFIO_GROUP_NOTIFY */ |
179 | #define VFIO_GROUP_NOTIFY_SET_KVM BIT(0) | |
180 | ||
c086de81 | 181 | extern int vfio_register_notifier(struct device *dev, |
22195cbd JS |
182 | enum vfio_notify_type type, |
183 | unsigned long *required_events, | |
c086de81 | 184 | struct notifier_block *nb); |
c086de81 | 185 | extern int vfio_unregister_notifier(struct device *dev, |
22195cbd | 186 | enum vfio_notify_type type, |
c086de81 KW |
187 | struct notifier_block *nb); |
188 | ||
ccd46dba JS |
189 | struct kvm; |
190 | extern void vfio_group_set_kvm(struct vfio_group *group, struct kvm *kvm); | |
191 | ||
d7a8d5ed AW |
192 | /* |
193 | * Sub-module helpers | |
194 | */ | |
195 | struct vfio_info_cap { | |
196 | struct vfio_info_cap_header *buf; | |
197 | size_t size; | |
198 | }; | |
199 | extern struct vfio_info_cap_header *vfio_info_cap_add( | |
200 | struct vfio_info_cap *caps, size_t size, u16 id, u16 version); | |
201 | extern void vfio_info_cap_shift(struct vfio_info_cap *caps, size_t offset); | |
202 | ||
b3c0a866 | 203 | extern int vfio_info_add_capability(struct vfio_info_cap *caps, |
dda01f78 AW |
204 | struct vfio_info_cap_header *cap, |
205 | size_t size); | |
b3c0a866 | 206 | |
c747f08a KW |
207 | extern int vfio_set_irqs_validate_and_prepare(struct vfio_irq_set *hdr, |
208 | int num_irqs, int max_irq_type, | |
209 | size_t *data_size); | |
210 | ||
92d18a68 | 211 | struct pci_dev; |
bb67b496 | 212 | #if IS_ENABLED(CONFIG_VFIO_SPAPR_EEH) |
9b936c96 | 213 | extern void vfio_spapr_pci_eeh_open(struct pci_dev *pdev); |
1b69be5e GS |
214 | extern void vfio_spapr_pci_eeh_release(struct pci_dev *pdev); |
215 | extern long vfio_spapr_iommu_eeh_ioctl(struct iommu_group *group, | |
216 | unsigned int cmd, | |
217 | unsigned long arg); | |
218 | #else | |
9b936c96 | 219 | static inline void vfio_spapr_pci_eeh_open(struct pci_dev *pdev) |
1b69be5e | 220 | { |
1b69be5e GS |
221 | } |
222 | ||
223 | static inline void vfio_spapr_pci_eeh_release(struct pci_dev *pdev) | |
224 | { | |
225 | } | |
226 | ||
227 | static inline long vfio_spapr_iommu_eeh_ioctl(struct iommu_group *group, | |
228 | unsigned int cmd, | |
229 | unsigned long arg) | |
230 | { | |
231 | return -ENOTTY; | |
232 | } | |
bb67b496 | 233 | #endif /* CONFIG_VFIO_SPAPR_EEH */ |
7e992d69 AM |
234 | |
235 | /* | |
236 | * IRQfd - generic | |
237 | */ | |
238 | struct virqfd { | |
239 | void *opaque; | |
240 | struct eventfd_ctx *eventfd; | |
241 | int (*handler)(void *, void *); | |
242 | void (*thread)(void *, void *); | |
243 | void *data; | |
244 | struct work_struct inject; | |
ac6424b9 | 245 | wait_queue_entry_t wait; |
7e992d69 AM |
246 | poll_table pt; |
247 | struct work_struct shutdown; | |
248 | struct virqfd **pvirqfd; | |
249 | }; | |
250 | ||
7e992d69 AM |
251 | extern int vfio_virqfd_enable(void *opaque, |
252 | int (*handler)(void *, void *), | |
253 | void (*thread)(void *, void *), | |
254 | void *data, struct virqfd **pvirqfd, int fd); | |
255 | extern void vfio_virqfd_disable(struct virqfd **pvirqfd); | |
256 | ||
cba3345c | 257 | #endif /* VFIO_H */ |