1 | /* |
2 | * common header for vfio based device assignment support |
3 | * |
4 | * Copyright Red Hat, Inc. 2012 |
5 | * |
6 | * Authors: |
7 | * Alex Williamson <alex.williamson@redhat.com> |
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 (alex@neocleus.com) |
15 | * Copyright (c) 2007, Neocleus, Guy Zana (guy@neocleus.com) |
16 | * Copyright (C) 2008, Qumranet, Amit Shah (amit.shah@qumranet.com) |
17 | * Copyright (C) 2008, Red Hat, Amit Shah (amit.shah@redhat.com) |
18 | * Copyright (C) 2008, IBM, Muli Ben-Yehuda (muli@il.ibm.com) |
19 | */ |
20 | |
21 | #ifndef HW_VFIO_VFIO_COMMON_H |
22 | #define HW_VFIO_VFIO_COMMON_H |
23 | |
24 | #include "exec/memory.h" |
25 | #include "qemu/queue.h" |
26 | #include "qemu/notify.h" |
27 | #include "ui/console.h" |
28 | #include "hw/display/ramfb.h" |
29 | #ifdef CONFIG_LINUX |
30 | #include <linux/vfio.h> |
31 | #endif |
32 | |
33 | #define VFIO_MSG_PREFIX "vfio %s: " |
34 | |
35 | enum { |
36 | VFIO_DEVICE_TYPE_PCI = 0, |
37 | VFIO_DEVICE_TYPE_PLATFORM = 1, |
38 | VFIO_DEVICE_TYPE_CCW = 2, |
39 | VFIO_DEVICE_TYPE_AP = 3, |
40 | }; |
41 | |
42 | typedef struct VFIOMmap { |
43 | MemoryRegion mem; |
44 | void *mmap; |
45 | off_t offset; |
46 | size_t size; |
47 | } VFIOMmap; |
48 | |
49 | typedef struct VFIORegion { |
50 | struct VFIODevice *vbasedev; |
51 | off_t fd_offset; /* offset of region within device fd */ |
52 | MemoryRegion *mem; /* slow, read/write access */ |
53 | size_t size; |
54 | uint32_t flags; /* VFIO region flags (rd/wr/mmap) */ |
55 | uint32_t nr_mmaps; |
56 | VFIOMmap *mmaps; |
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 | |
68 | typedef struct VFIOContainer { |
69 | VFIOAddressSpace *space; |
70 | int fd; /* /dev/vfio/vfio, empowered by the attached groups */ |
71 | MemoryListener listener; |
72 | MemoryListener prereg_listener; |
73 | unsigned iommu_type; |
74 | int error; |
75 | bool initialized; |
76 | unsigned long pgsizes; |
77 | QLIST_HEAD(, VFIOGuestIOMMU) giommu_list; |
78 | QLIST_HEAD(, VFIOHostDMAWindow) hostwin_list; |
79 | QLIST_HEAD(, VFIOGroup) group_list; |
80 | QLIST_ENTRY(VFIOContainer) next; |
81 | } VFIOContainer; |
82 | |
83 | typedef struct VFIOGuestIOMMU { |
84 | VFIOContainer *container; |
85 | IOMMUMemoryRegion *iommu; |
86 | hwaddr iommu_offset; |
87 | IOMMUNotifier n; |
88 | QLIST_ENTRY(VFIOGuestIOMMU) giommu_next; |
89 | } VFIOGuestIOMMU; |
90 | |
91 | typedef struct VFIOHostDMAWindow { |
92 | hwaddr min_iova; |
93 | hwaddr max_iova; |
94 | uint64_t iova_pgsizes; |
95 | QLIST_ENTRY(VFIOHostDMAWindow) hostwin_next; |
96 | } VFIOHostDMAWindow; |
97 | |
98 | typedef struct VFIODeviceOps VFIODeviceOps; |
99 | |
100 | typedef struct VFIODevice { |
101 | QLIST_ENTRY(VFIODevice) next; |
102 | struct VFIOGroup *group; |
103 | char *sysfsdev; |
104 | char *name; |
105 | DeviceState *dev; |
106 | int fd; |
107 | int type; |
108 | bool reset_works; |
109 | bool needs_reset; |
110 | bool no_mmap; |
111 | bool balloon_allowed; |
112 | VFIODeviceOps *ops; |
113 | unsigned int num_irqs; |
114 | unsigned int num_regions; |
115 | unsigned int flags; |
116 | } VFIODevice; |
117 | |
118 | struct VFIODeviceOps { |
119 | void (*vfio_compute_needs_reset)(VFIODevice *vdev); |
120 | int (*vfio_hot_reset_multi)(VFIODevice *vdev); |
121 | void (*vfio_eoi)(VFIODevice *vdev); |
122 | }; |
123 | |
124 | typedef struct VFIOGroup { |
125 | int fd; |
126 | int groupid; |
127 | VFIOContainer *container; |
128 | QLIST_HEAD(, VFIODevice) device_list; |
129 | QLIST_ENTRY(VFIOGroup) next; |
130 | QLIST_ENTRY(VFIOGroup) container_next; |
131 | bool balloon_allowed; |
132 | } VFIOGroup; |
133 | |
134 | typedef struct VFIODMABuf { |
135 | QemuDmaBuf buf; |
136 | uint32_t pos_x, pos_y, pos_updates; |
137 | uint32_t hot_x, hot_y, hot_updates; |
138 | int dmabuf_id; |
139 | QTAILQ_ENTRY(VFIODMABuf) next; |
140 | } VFIODMABuf; |
141 | |
142 | typedef struct VFIODisplay { |
143 | QemuConsole *con; |
144 | RAMFBState *ramfb; |
145 | struct vfio_region_info *edid_info; |
146 | struct vfio_region_gfx_edid *edid_regs; |
147 | uint8_t *edid_blob; |
148 | QEMUTimer *edid_link_timer; |
149 | struct { |
150 | VFIORegion buffer; |
151 | DisplaySurface *surface; |
152 | } region; |
153 | struct { |
154 | QTAILQ_HEAD(, VFIODMABuf) bufs; |
155 | VFIODMABuf *primary; |
156 | VFIODMABuf *cursor; |
157 | } dmabuf; |
158 | } VFIODisplay; |
159 | |
160 | void vfio_put_base_device(VFIODevice *vbasedev); |
161 | void vfio_disable_irqindex(VFIODevice *vbasedev, int index); |
162 | void vfio_unmask_single_irqindex(VFIODevice *vbasedev, int index); |
163 | void vfio_mask_single_irqindex(VFIODevice *vbasedev, int index); |
164 | int vfio_set_irq_signaling(VFIODevice *vbasedev, int index, int subindex, |
165 | int action, int fd, Error **errp); |
166 | void vfio_region_write(void *opaque, hwaddr addr, |
167 | uint64_t data, unsigned size); |
168 | uint64_t vfio_region_read(void *opaque, |
169 | hwaddr addr, unsigned size); |
170 | int vfio_region_setup(Object *obj, VFIODevice *vbasedev, VFIORegion *region, |
171 | int index, const char *name); |
172 | int vfio_region_mmap(VFIORegion *region); |
173 | void vfio_region_mmaps_set_enabled(VFIORegion *region, bool enabled); |
174 | void vfio_region_exit(VFIORegion *region); |
175 | void vfio_region_finalize(VFIORegion *region); |
176 | void vfio_reset_handler(void *opaque); |
177 | VFIOGroup *vfio_get_group(int groupid, AddressSpace *as, Error **errp); |
178 | void vfio_put_group(VFIOGroup *group); |
179 | int vfio_get_device(VFIOGroup *group, const char *name, |
180 | VFIODevice *vbasedev, Error **errp); |
181 | |
182 | extern const MemoryRegionOps vfio_region_ops; |
183 | typedef QLIST_HEAD(VFIOGroupList, VFIOGroup) VFIOGroupList; |
184 | extern VFIOGroupList vfio_group_list; |
185 | |
186 | #ifdef CONFIG_LINUX |
187 | int vfio_get_region_info(VFIODevice *vbasedev, int index, |
188 | struct vfio_region_info **info); |
189 | int vfio_get_dev_region_info(VFIODevice *vbasedev, uint32_t type, |
190 | uint32_t subtype, struct vfio_region_info **info); |
191 | bool vfio_has_region_cap(VFIODevice *vbasedev, int region, uint16_t cap_type); |
192 | struct vfio_info_cap_header * |
193 | vfio_get_region_info_cap(struct vfio_region_info *info, uint16_t id); |
194 | #endif |
195 | extern const MemoryListener vfio_prereg_listener; |
196 | |
197 | int vfio_spapr_create_window(VFIOContainer *container, |
198 | MemoryRegionSection *section, |
199 | hwaddr *pgsize); |
200 | int vfio_spapr_remove_window(VFIOContainer *container, |
201 | hwaddr offset_within_address_space); |
202 | |
203 | #endif /* HW_VFIO_VFIO_COMMON_H */ |
204 | |