]>
Commit | Line | Data |
---|---|---|
e2c7d025 EA |
1 | /* |
2 | * common header for vfio based device assignment support | |
3 | * | |
4 | * Copyright Red Hat, Inc. 2012 | |
5 | * | |
6 | * Authors: | |
7 | * Alex Williamson <[email protected]> | |
8 | * | |
9 | * This work is licensed under the terms of the GNU GPL, version 2. See | |
10 | * the COPYING file in the top-level directory. | |
11 | * | |
12 | * Based on qemu-kvm device-assignment: | |
13 | * Adapted for KVM by Qumranet. | |
14 | * Copyright (c) 2007, Neocleus, Alex Novik ([email protected]) | |
15 | * Copyright (c) 2007, Neocleus, Guy Zana ([email protected]) | |
16 | * Copyright (C) 2008, Qumranet, Amit Shah ([email protected]) | |
17 | * Copyright (C) 2008, Red Hat, Amit Shah ([email protected]) | |
18 | * Copyright (C) 2008, IBM, Muli Ben-Yehuda ([email protected]) | |
19 | */ | |
175de524 | 20 | |
e2c7d025 EA |
21 | #ifndef HW_VFIO_VFIO_COMMON_H |
22 | #define HW_VFIO_VFIO_COMMON_H | |
23 | ||
24 | #include "qemu-common.h" | |
e2c7d025 EA |
25 | #include "exec/memory.h" |
26 | #include "qemu/queue.h" | |
27 | #include "qemu/notify.h" | |
8b818e05 | 28 | #include "ui/console.h" |
46900226 AW |
29 | #ifdef CONFIG_LINUX |
30 | #include <linux/vfio.h> | |
31 | #endif | |
e2c7d025 | 32 | |
426ec904 EA |
33 | #define ERR_PREFIX "vfio error: %s: " |
34 | #define WARN_PREFIX "vfio warning: %s: " | |
35 | ||
e2c7d025 EA |
36 | enum { |
37 | VFIO_DEVICE_TYPE_PCI = 0, | |
0ea2730b | 38 | VFIO_DEVICE_TYPE_PLATFORM = 1, |
1dcac3e1 | 39 | VFIO_DEVICE_TYPE_CCW = 2, |
e2c7d025 EA |
40 | }; |
41 | ||
db0da029 AW |
42 | typedef struct VFIOMmap { |
43 | MemoryRegion mem; | |
44 | void *mmap; | |
45 | off_t offset; | |
46 | size_t size; | |
47 | } VFIOMmap; | |
48 | ||
e2c7d025 EA |
49 | typedef struct VFIORegion { |
50 | struct VFIODevice *vbasedev; | |
51 | off_t fd_offset; /* offset of region within device fd */ | |
db0da029 | 52 | MemoryRegion *mem; /* slow, read/write access */ |
e2c7d025 EA |
53 | size_t size; |
54 | uint32_t flags; /* VFIO region flags (rd/wr/mmap) */ | |
db0da029 AW |
55 | uint32_t nr_mmaps; |
56 | VFIOMmap *mmaps; | |
e2c7d025 EA |
57 | uint8_t nr; /* cache the region number for debug */ |
58 | } VFIORegion; | |
59 | ||
60 | typedef struct VFIOAddressSpace { | |
61 | AddressSpace *as; | |
62 | QLIST_HEAD(, VFIOContainer) containers; | |
63 | QLIST_ENTRY(VFIOAddressSpace) list; | |
64 | } VFIOAddressSpace; | |
65 | ||
66 | struct VFIOGroup; | |
67 | ||
e2c7d025 EA |
68 | typedef struct VFIOContainer { |
69 | VFIOAddressSpace *space; | |
70 | int fd; /* /dev/vfio/vfio, empowered by the attached groups */ | |
ee0bf0e5 | 71 | MemoryListener listener; |
318f67ce AK |
72 | MemoryListener prereg_listener; |
73 | unsigned iommu_type; | |
ee0bf0e5 DG |
74 | int error; |
75 | bool initialized; | |
3898aad3 DG |
76 | /* |
77 | * This assumes the host IOMMU can support only a single | |
78 | * contiguous IOVA window. We may need to generalize that in | |
79 | * future | |
80 | */ | |
e2c7d025 | 81 | QLIST_HEAD(, VFIOGuestIOMMU) giommu_list; |
f4ec5e26 | 82 | QLIST_HEAD(, VFIOHostDMAWindow) hostwin_list; |
e2c7d025 EA |
83 | QLIST_HEAD(, VFIOGroup) group_list; |
84 | QLIST_ENTRY(VFIOContainer) next; | |
85 | } VFIOContainer; | |
86 | ||
87 | typedef struct VFIOGuestIOMMU { | |
88 | VFIOContainer *container; | |
3df9d748 | 89 | IOMMUMemoryRegion *iommu; |
d78c19b5 | 90 | hwaddr iommu_offset; |
cdb30812 | 91 | IOMMUNotifier n; |
e2c7d025 EA |
92 | QLIST_ENTRY(VFIOGuestIOMMU) giommu_next; |
93 | } VFIOGuestIOMMU; | |
94 | ||
f4ec5e26 AK |
95 | typedef struct VFIOHostDMAWindow { |
96 | hwaddr min_iova; | |
97 | hwaddr max_iova; | |
98 | uint64_t iova_pgsizes; | |
99 | QLIST_ENTRY(VFIOHostDMAWindow) hostwin_next; | |
100 | } VFIOHostDMAWindow; | |
101 | ||
e2c7d025 EA |
102 | typedef struct VFIODeviceOps VFIODeviceOps; |
103 | ||
104 | typedef struct VFIODevice { | |
105 | QLIST_ENTRY(VFIODevice) next; | |
106 | struct VFIOGroup *group; | |
7df9381b | 107 | char *sysfsdev; |
e2c7d025 | 108 | char *name; |
7da624e2 | 109 | DeviceState *dev; |
e2c7d025 EA |
110 | int fd; |
111 | int type; | |
112 | bool reset_works; | |
113 | bool needs_reset; | |
5e15d79b | 114 | bool no_mmap; |
e2c7d025 EA |
115 | VFIODeviceOps *ops; |
116 | unsigned int num_irqs; | |
117 | unsigned int num_regions; | |
118 | unsigned int flags; | |
119 | } VFIODevice; | |
120 | ||
121 | struct VFIODeviceOps { | |
122 | void (*vfio_compute_needs_reset)(VFIODevice *vdev); | |
123 | int (*vfio_hot_reset_multi)(VFIODevice *vdev); | |
124 | void (*vfio_eoi)(VFIODevice *vdev); | |
e2c7d025 EA |
125 | }; |
126 | ||
127 | typedef struct VFIOGroup { | |
128 | int fd; | |
129 | int groupid; | |
130 | VFIOContainer *container; | |
131 | QLIST_HEAD(, VFIODevice) device_list; | |
132 | QLIST_ENTRY(VFIOGroup) next; | |
133 | QLIST_ENTRY(VFIOGroup) container_next; | |
134 | } VFIOGroup; | |
135 | ||
8b818e05 GH |
136 | typedef struct VFIODMABuf { |
137 | QemuDmaBuf buf; | |
138 | uint32_t pos_x, pos_y, pos_updates; | |
139 | uint32_t hot_x, hot_y, hot_updates; | |
140 | int dmabuf_id; | |
141 | QTAILQ_ENTRY(VFIODMABuf) next; | |
142 | } VFIODMABuf; | |
143 | ||
00195ba7 GH |
144 | typedef struct VFIODisplay { |
145 | QemuConsole *con; | |
146 | struct { | |
147 | VFIORegion buffer; | |
148 | DisplaySurface *surface; | |
149 | } region; | |
8b818e05 GH |
150 | struct { |
151 | QTAILQ_HEAD(, VFIODMABuf) bufs; | |
152 | VFIODMABuf *primary; | |
153 | VFIODMABuf *cursor; | |
154 | } dmabuf; | |
00195ba7 GH |
155 | } VFIODisplay; |
156 | ||
e2c7d025 EA |
157 | void vfio_put_base_device(VFIODevice *vbasedev); |
158 | void vfio_disable_irqindex(VFIODevice *vbasedev, int index); | |
159 | void vfio_unmask_single_irqindex(VFIODevice *vbasedev, int index); | |
160 | void vfio_mask_single_irqindex(VFIODevice *vbasedev, int index); | |
161 | void vfio_region_write(void *opaque, hwaddr addr, | |
162 | uint64_t data, unsigned size); | |
163 | uint64_t vfio_region_read(void *opaque, | |
164 | hwaddr addr, unsigned size); | |
db0da029 AW |
165 | int vfio_region_setup(Object *obj, VFIODevice *vbasedev, VFIORegion *region, |
166 | int index, const char *name); | |
167 | int vfio_region_mmap(VFIORegion *region); | |
168 | void vfio_region_mmaps_set_enabled(VFIORegion *region, bool enabled); | |
169 | void vfio_region_exit(VFIORegion *region); | |
170 | void vfio_region_finalize(VFIORegion *region); | |
e2c7d025 | 171 | void vfio_reset_handler(void *opaque); |
1b808d5b | 172 | VFIOGroup *vfio_get_group(int groupid, AddressSpace *as, Error **errp); |
e2c7d025 EA |
173 | void vfio_put_group(VFIOGroup *group); |
174 | int vfio_get_device(VFIOGroup *group, const char *name, | |
59f7d674 | 175 | VFIODevice *vbasedev, Error **errp); |
e2c7d025 EA |
176 | |
177 | extern const MemoryRegionOps vfio_region_ops; | |
e2c7d025 EA |
178 | extern QLIST_HEAD(vfio_group_head, VFIOGroup) vfio_group_list; |
179 | extern QLIST_HEAD(vfio_as_head, VFIOAddressSpace) vfio_address_spaces; | |
180 | ||
46900226 AW |
181 | #ifdef CONFIG_LINUX |
182 | int vfio_get_region_info(VFIODevice *vbasedev, int index, | |
183 | struct vfio_region_info **info); | |
e61a424f AW |
184 | int vfio_get_dev_region_info(VFIODevice *vbasedev, uint32_t type, |
185 | uint32_t subtype, struct vfio_region_info **info); | |
ae0215b2 | 186 | bool vfio_has_region_cap(VFIODevice *vbasedev, int region, uint16_t cap_type); |
46900226 | 187 | #endif |
318f67ce AK |
188 | extern const MemoryListener vfio_prereg_listener; |
189 | ||
2e4109de AK |
190 | int vfio_spapr_create_window(VFIOContainer *container, |
191 | MemoryRegionSection *section, | |
192 | hwaddr *pgsize); | |
193 | int vfio_spapr_remove_window(VFIOContainer *container, | |
194 | hwaddr offset_within_address_space); | |
195 | ||
175de524 | 196 | #endif /* HW_VFIO_VFIO_COMMON_H */ |