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 | ||
0bfc6a4e | 74 | void vfio_init_group_dev(struct vfio_device *device, struct device *dev, |
1e04ec14 | 75 | const struct vfio_device_ops *ops); |
ae03c377 | 76 | void vfio_uninit_group_dev(struct vfio_device *device); |
0bfc6a4e | 77 | int vfio_register_group_dev(struct vfio_device *device); |
c68ea0d0 | 78 | int vfio_register_emulated_iommu_dev(struct vfio_device *device); |
0bfc6a4e | 79 | void vfio_unregister_group_dev(struct vfio_device *device); |
44f50716 VMP |
80 | extern struct vfio_device *vfio_device_get_from_dev(struct device *dev); |
81 | extern void vfio_device_put(struct vfio_device *device); | |
cba3345c | 82 | |
2fd585f4 JG |
83 | int vfio_assign_device_set(struct vfio_device *device, void *set_id); |
84 | ||
6cdd9782 AK |
85 | /* |
86 | * External user API | |
87 | */ | |
88 | extern struct vfio_group *vfio_group_get_external_user(struct file *filep); | |
89 | extern void vfio_group_put_external_user(struct vfio_group *group); | |
c0560f51 YZ |
90 | extern struct vfio_group *vfio_group_get_external_user_from_dev(struct device |
91 | *dev); | |
5d6dee80 AW |
92 | extern bool vfio_external_group_match_file(struct vfio_group *group, |
93 | struct file *filep); | |
6cdd9782 | 94 | extern int vfio_external_user_iommu_id(struct vfio_group *group); |
88d7ab89 AW |
95 | extern long vfio_external_check_extension(struct vfio_group *group, |
96 | unsigned long arg); | |
6cdd9782 | 97 | |
2169037d KW |
98 | #define VFIO_PIN_PAGES_MAX_ENTRIES (PAGE_SIZE/sizeof(unsigned long)) |
99 | ||
100 | extern int vfio_pin_pages(struct device *dev, unsigned long *user_pfn, | |
101 | int npage, int prot, unsigned long *phys_pfn); | |
102 | extern int vfio_unpin_pages(struct device *dev, unsigned long *user_pfn, | |
103 | int npage); | |
104 | ||
40280cf7 YZ |
105 | extern int vfio_group_pin_pages(struct vfio_group *group, |
106 | unsigned long *user_iova_pfn, int npage, | |
107 | int prot, unsigned long *phys_pfn); | |
108 | extern int vfio_group_unpin_pages(struct vfio_group *group, | |
109 | unsigned long *user_iova_pfn, int npage); | |
110 | ||
8d46c0cc YZ |
111 | extern int vfio_dma_rw(struct vfio_group *group, dma_addr_t user_iova, |
112 | void *data, size_t len, bool write); | |
113 | ||
bdfae1c9 LB |
114 | extern struct iommu_domain *vfio_group_iommu_domain(struct vfio_group *group); |
115 | ||
22195cbd JS |
116 | /* each type has independent events */ |
117 | enum vfio_notify_type { | |
118 | VFIO_IOMMU_NOTIFY = 0, | |
ccd46dba | 119 | VFIO_GROUP_NOTIFY = 1, |
22195cbd JS |
120 | }; |
121 | ||
122 | /* events for VFIO_IOMMU_NOTIFY */ | |
123 | #define VFIO_IOMMU_NOTIFY_DMA_UNMAP BIT(0) | |
c086de81 | 124 | |
ccd46dba JS |
125 | /* events for VFIO_GROUP_NOTIFY */ |
126 | #define VFIO_GROUP_NOTIFY_SET_KVM BIT(0) | |
127 | ||
c086de81 | 128 | extern int vfio_register_notifier(struct device *dev, |
22195cbd JS |
129 | enum vfio_notify_type type, |
130 | unsigned long *required_events, | |
c086de81 | 131 | struct notifier_block *nb); |
c086de81 | 132 | extern int vfio_unregister_notifier(struct device *dev, |
22195cbd | 133 | enum vfio_notify_type type, |
c086de81 KW |
134 | struct notifier_block *nb); |
135 | ||
ccd46dba JS |
136 | struct kvm; |
137 | extern void vfio_group_set_kvm(struct vfio_group *group, struct kvm *kvm); | |
138 | ||
d7a8d5ed AW |
139 | /* |
140 | * Sub-module helpers | |
141 | */ | |
142 | struct vfio_info_cap { | |
143 | struct vfio_info_cap_header *buf; | |
144 | size_t size; | |
145 | }; | |
146 | extern struct vfio_info_cap_header *vfio_info_cap_add( | |
147 | struct vfio_info_cap *caps, size_t size, u16 id, u16 version); | |
148 | extern void vfio_info_cap_shift(struct vfio_info_cap *caps, size_t offset); | |
149 | ||
b3c0a866 | 150 | extern int vfio_info_add_capability(struct vfio_info_cap *caps, |
dda01f78 AW |
151 | struct vfio_info_cap_header *cap, |
152 | size_t size); | |
b3c0a866 | 153 | |
c747f08a KW |
154 | extern int vfio_set_irqs_validate_and_prepare(struct vfio_irq_set *hdr, |
155 | int num_irqs, int max_irq_type, | |
156 | size_t *data_size); | |
157 | ||
92d18a68 | 158 | struct pci_dev; |
bb67b496 | 159 | #if IS_ENABLED(CONFIG_VFIO_SPAPR_EEH) |
9b936c96 | 160 | extern void vfio_spapr_pci_eeh_open(struct pci_dev *pdev); |
1b69be5e GS |
161 | extern void vfio_spapr_pci_eeh_release(struct pci_dev *pdev); |
162 | extern long vfio_spapr_iommu_eeh_ioctl(struct iommu_group *group, | |
163 | unsigned int cmd, | |
164 | unsigned long arg); | |
165 | #else | |
9b936c96 | 166 | static inline void vfio_spapr_pci_eeh_open(struct pci_dev *pdev) |
1b69be5e | 167 | { |
1b69be5e GS |
168 | } |
169 | ||
170 | static inline void vfio_spapr_pci_eeh_release(struct pci_dev *pdev) | |
171 | { | |
172 | } | |
173 | ||
174 | static inline long vfio_spapr_iommu_eeh_ioctl(struct iommu_group *group, | |
175 | unsigned int cmd, | |
176 | unsigned long arg) | |
177 | { | |
178 | return -ENOTTY; | |
179 | } | |
bb67b496 | 180 | #endif /* CONFIG_VFIO_SPAPR_EEH */ |
7e992d69 AM |
181 | |
182 | /* | |
183 | * IRQfd - generic | |
184 | */ | |
185 | struct virqfd { | |
186 | void *opaque; | |
187 | struct eventfd_ctx *eventfd; | |
188 | int (*handler)(void *, void *); | |
189 | void (*thread)(void *, void *); | |
190 | void *data; | |
191 | struct work_struct inject; | |
ac6424b9 | 192 | wait_queue_entry_t wait; |
7e992d69 AM |
193 | poll_table pt; |
194 | struct work_struct shutdown; | |
195 | struct virqfd **pvirqfd; | |
196 | }; | |
197 | ||
7e992d69 AM |
198 | extern int vfio_virqfd_enable(void *opaque, |
199 | int (*handler)(void *, void *), | |
200 | void (*thread)(void *, void *), | |
201 | void *data, struct virqfd **pvirqfd, int fd); | |
202 | extern void vfio_virqfd_disable(struct virqfd **pvirqfd); | |
203 | ||
cba3345c | 204 | #endif /* VFIO_H */ |