]>
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; | |
0bfc6a4e JG |
36 | |
37 | /* Members below here are private, not for driver use */ | |
38 | refcount_t refcount; | |
2fd585f4 | 39 | unsigned int open_count; |
0bfc6a4e JG |
40 | struct completion comp; |
41 | struct list_head group_next; | |
0bfc6a4e JG |
42 | }; |
43 | ||
cba3345c AW |
44 | /** |
45 | * struct vfio_device_ops - VFIO bus driver device callbacks | |
46 | * | |
2fd585f4 JG |
47 | * @open_device: Called when the first file descriptor is opened for this device |
48 | * @close_device: Opposite of open_device | |
cba3345c AW |
49 | * @read: Perform read(2) on device file descriptor |
50 | * @write: Perform write(2) on device file descriptor | |
51 | * @ioctl: Perform ioctl(2) on device file descriptor, supporting VFIO_DEVICE_* | |
52 | * operations documented below | |
53 | * @mmap: Perform mmap(2) on a region of the device file descriptor | |
13060b64 | 54 | * @request: Request for the bus driver to release the device |
5f3874c2 AW |
55 | * @match: Optional device name match callback (return: 0 for no-match, >0 for |
56 | * match, -errno for abort (ex. match with insufficient or incorrect | |
57 | * additional args) | |
cba3345c AW |
58 | */ |
59 | struct vfio_device_ops { | |
60 | char *name; | |
2fd585f4 JG |
61 | int (*open_device)(struct vfio_device *vdev); |
62 | void (*close_device)(struct vfio_device *vdev); | |
6df62c5b | 63 | ssize_t (*read)(struct vfio_device *vdev, char __user *buf, |
cba3345c | 64 | size_t count, loff_t *ppos); |
6df62c5b | 65 | ssize_t (*write)(struct vfio_device *vdev, const char __user *buf, |
cba3345c | 66 | size_t count, loff_t *size); |
6df62c5b | 67 | long (*ioctl)(struct vfio_device *vdev, unsigned int cmd, |
cba3345c | 68 | unsigned long arg); |
6df62c5b JG |
69 | int (*mmap)(struct vfio_device *vdev, struct vm_area_struct *vma); |
70 | void (*request)(struct vfio_device *vdev, unsigned int count); | |
71 | int (*match)(struct vfio_device *vdev, char *buf); | |
cba3345c AW |
72 | }; |
73 | ||
03a76b60 AW |
74 | extern struct iommu_group *vfio_iommu_group_get(struct device *dev); |
75 | extern void vfio_iommu_group_put(struct iommu_group *group, struct device *dev); | |
76 | ||
0bfc6a4e | 77 | void vfio_init_group_dev(struct vfio_device *device, struct device *dev, |
1e04ec14 | 78 | const struct vfio_device_ops *ops); |
ae03c377 | 79 | void vfio_uninit_group_dev(struct vfio_device *device); |
0bfc6a4e | 80 | int vfio_register_group_dev(struct vfio_device *device); |
0bfc6a4e | 81 | void vfio_unregister_group_dev(struct vfio_device *device); |
44f50716 VMP |
82 | extern struct vfio_device *vfio_device_get_from_dev(struct device *dev); |
83 | extern void vfio_device_put(struct vfio_device *device); | |
cba3345c | 84 | |
2fd585f4 JG |
85 | int vfio_assign_device_set(struct vfio_device *device, void *set_id); |
86 | ||
ec5e3294 SS |
87 | /* events for the backend driver notify callback */ |
88 | enum vfio_iommu_notify_type { | |
89 | VFIO_IOMMU_CONTAINER_CLOSE = 0, | |
90 | }; | |
91 | ||
cba3345c AW |
92 | /** |
93 | * struct vfio_iommu_driver_ops - VFIO IOMMU driver callbacks | |
94 | */ | |
95 | struct vfio_iommu_driver_ops { | |
96 | char *name; | |
97 | struct module *owner; | |
98 | void *(*open)(unsigned long arg); | |
99 | void (*release)(void *iommu_data); | |
100 | ssize_t (*read)(void *iommu_data, char __user *buf, | |
101 | size_t count, loff_t *ppos); | |
102 | ssize_t (*write)(void *iommu_data, const char __user *buf, | |
103 | size_t count, loff_t *size); | |
104 | long (*ioctl)(void *iommu_data, unsigned int cmd, | |
105 | unsigned long arg); | |
106 | int (*mmap)(void *iommu_data, struct vm_area_struct *vma); | |
107 | int (*attach_group)(void *iommu_data, | |
108 | struct iommu_group *group); | |
109 | void (*detach_group)(void *iommu_data, | |
110 | struct iommu_group *group); | |
95fc87b4 KW |
111 | int (*pin_pages)(void *iommu_data, |
112 | struct iommu_group *group, | |
113 | unsigned long *user_pfn, | |
2169037d KW |
114 | int npage, int prot, |
115 | unsigned long *phys_pfn); | |
116 | int (*unpin_pages)(void *iommu_data, | |
117 | unsigned long *user_pfn, int npage); | |
c086de81 | 118 | int (*register_notifier)(void *iommu_data, |
22195cbd | 119 | unsigned long *events, |
c086de81 KW |
120 | struct notifier_block *nb); |
121 | int (*unregister_notifier)(void *iommu_data, | |
122 | struct notifier_block *nb); | |
8d46c0cc YZ |
123 | int (*dma_rw)(void *iommu_data, dma_addr_t user_iova, |
124 | void *data, size_t count, bool write); | |
bdfae1c9 LB |
125 | struct iommu_domain *(*group_iommu_domain)(void *iommu_data, |
126 | struct iommu_group *group); | |
ec5e3294 SS |
127 | void (*notify)(void *iommu_data, |
128 | enum vfio_iommu_notify_type event); | |
cba3345c AW |
129 | }; |
130 | ||
131 | extern int vfio_register_iommu_driver(const struct vfio_iommu_driver_ops *ops); | |
132 | ||
133 | extern void vfio_unregister_iommu_driver( | |
134 | const struct vfio_iommu_driver_ops *ops); | |
135 | ||
6cdd9782 AK |
136 | /* |
137 | * External user API | |
138 | */ | |
139 | extern struct vfio_group *vfio_group_get_external_user(struct file *filep); | |
140 | extern void vfio_group_put_external_user(struct vfio_group *group); | |
c0560f51 YZ |
141 | extern struct vfio_group *vfio_group_get_external_user_from_dev(struct device |
142 | *dev); | |
5d6dee80 AW |
143 | extern bool vfio_external_group_match_file(struct vfio_group *group, |
144 | struct file *filep); | |
6cdd9782 | 145 | extern int vfio_external_user_iommu_id(struct vfio_group *group); |
88d7ab89 AW |
146 | extern long vfio_external_check_extension(struct vfio_group *group, |
147 | unsigned long arg); | |
6cdd9782 | 148 | |
2169037d KW |
149 | #define VFIO_PIN_PAGES_MAX_ENTRIES (PAGE_SIZE/sizeof(unsigned long)) |
150 | ||
151 | extern int vfio_pin_pages(struct device *dev, unsigned long *user_pfn, | |
152 | int npage, int prot, unsigned long *phys_pfn); | |
153 | extern int vfio_unpin_pages(struct device *dev, unsigned long *user_pfn, | |
154 | int npage); | |
155 | ||
40280cf7 YZ |
156 | extern int vfio_group_pin_pages(struct vfio_group *group, |
157 | unsigned long *user_iova_pfn, int npage, | |
158 | int prot, unsigned long *phys_pfn); | |
159 | extern int vfio_group_unpin_pages(struct vfio_group *group, | |
160 | unsigned long *user_iova_pfn, int npage); | |
161 | ||
8d46c0cc YZ |
162 | extern int vfio_dma_rw(struct vfio_group *group, dma_addr_t user_iova, |
163 | void *data, size_t len, bool write); | |
164 | ||
bdfae1c9 LB |
165 | extern struct iommu_domain *vfio_group_iommu_domain(struct vfio_group *group); |
166 | ||
22195cbd JS |
167 | /* each type has independent events */ |
168 | enum vfio_notify_type { | |
169 | VFIO_IOMMU_NOTIFY = 0, | |
ccd46dba | 170 | VFIO_GROUP_NOTIFY = 1, |
22195cbd JS |
171 | }; |
172 | ||
173 | /* events for VFIO_IOMMU_NOTIFY */ | |
174 | #define VFIO_IOMMU_NOTIFY_DMA_UNMAP BIT(0) | |
c086de81 | 175 | |
ccd46dba JS |
176 | /* events for VFIO_GROUP_NOTIFY */ |
177 | #define VFIO_GROUP_NOTIFY_SET_KVM BIT(0) | |
178 | ||
c086de81 | 179 | extern int vfio_register_notifier(struct device *dev, |
22195cbd JS |
180 | enum vfio_notify_type type, |
181 | unsigned long *required_events, | |
c086de81 | 182 | struct notifier_block *nb); |
c086de81 | 183 | extern int vfio_unregister_notifier(struct device *dev, |
22195cbd | 184 | enum vfio_notify_type type, |
c086de81 KW |
185 | struct notifier_block *nb); |
186 | ||
ccd46dba JS |
187 | struct kvm; |
188 | extern void vfio_group_set_kvm(struct vfio_group *group, struct kvm *kvm); | |
189 | ||
d7a8d5ed AW |
190 | /* |
191 | * Sub-module helpers | |
192 | */ | |
193 | struct vfio_info_cap { | |
194 | struct vfio_info_cap_header *buf; | |
195 | size_t size; | |
196 | }; | |
197 | extern struct vfio_info_cap_header *vfio_info_cap_add( | |
198 | struct vfio_info_cap *caps, size_t size, u16 id, u16 version); | |
199 | extern void vfio_info_cap_shift(struct vfio_info_cap *caps, size_t offset); | |
200 | ||
b3c0a866 | 201 | extern int vfio_info_add_capability(struct vfio_info_cap *caps, |
dda01f78 AW |
202 | struct vfio_info_cap_header *cap, |
203 | size_t size); | |
b3c0a866 | 204 | |
c747f08a KW |
205 | extern int vfio_set_irqs_validate_and_prepare(struct vfio_irq_set *hdr, |
206 | int num_irqs, int max_irq_type, | |
207 | size_t *data_size); | |
208 | ||
92d18a68 | 209 | struct pci_dev; |
bb67b496 | 210 | #if IS_ENABLED(CONFIG_VFIO_SPAPR_EEH) |
9b936c96 | 211 | extern void vfio_spapr_pci_eeh_open(struct pci_dev *pdev); |
1b69be5e GS |
212 | extern void vfio_spapr_pci_eeh_release(struct pci_dev *pdev); |
213 | extern long vfio_spapr_iommu_eeh_ioctl(struct iommu_group *group, | |
214 | unsigned int cmd, | |
215 | unsigned long arg); | |
216 | #else | |
9b936c96 | 217 | static inline void vfio_spapr_pci_eeh_open(struct pci_dev *pdev) |
1b69be5e | 218 | { |
1b69be5e GS |
219 | } |
220 | ||
221 | static inline void vfio_spapr_pci_eeh_release(struct pci_dev *pdev) | |
222 | { | |
223 | } | |
224 | ||
225 | static inline long vfio_spapr_iommu_eeh_ioctl(struct iommu_group *group, | |
226 | unsigned int cmd, | |
227 | unsigned long arg) | |
228 | { | |
229 | return -ENOTTY; | |
230 | } | |
bb67b496 | 231 | #endif /* CONFIG_VFIO_SPAPR_EEH */ |
7e992d69 AM |
232 | |
233 | /* | |
234 | * IRQfd - generic | |
235 | */ | |
236 | struct virqfd { | |
237 | void *opaque; | |
238 | struct eventfd_ctx *eventfd; | |
239 | int (*handler)(void *, void *); | |
240 | void (*thread)(void *, void *); | |
241 | void *data; | |
242 | struct work_struct inject; | |
ac6424b9 | 243 | wait_queue_entry_t wait; |
7e992d69 AM |
244 | poll_table pt; |
245 | struct work_struct shutdown; | |
246 | struct virqfd **pvirqfd; | |
247 | }; | |
248 | ||
7e992d69 AM |
249 | extern int vfio_virqfd_enable(void *opaque, |
250 | int (*handler)(void *, void *), | |
251 | void (*thread)(void *, void *), | |
252 | void *data, struct virqfd **pvirqfd, int fd); | |
253 | extern void vfio_virqfd_disable(struct virqfd **pvirqfd); | |
254 | ||
cba3345c | 255 | #endif /* VFIO_H */ |