]>
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 <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 | */ | |
175de524 | 20 | |
e2c7d025 EA |
21 | #ifndef HW_VFIO_VFIO_COMMON_H |
22 | #define HW_VFIO_VFIO_COMMON_H | |
23 | ||
24 | #include "qemu-common.h" | |
25 | #include "exec/address-spaces.h" | |
26 | #include "exec/memory.h" | |
27 | #include "qemu/queue.h" | |
28 | #include "qemu/notify.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 | /*#define DEBUG_VFIO*/ |
37 | #ifdef DEBUG_VFIO | |
38 | #define DPRINTF(fmt, ...) \ | |
39 | do { fprintf(stderr, "vfio: " fmt, ## __VA_ARGS__); } while (0) | |
40 | #else | |
41 | #define DPRINTF(fmt, ...) \ | |
42 | do { } while (0) | |
43 | #endif | |
44 | ||
e2c7d025 EA |
45 | enum { |
46 | VFIO_DEVICE_TYPE_PCI = 0, | |
0ea2730b | 47 | VFIO_DEVICE_TYPE_PLATFORM = 1, |
1dcac3e1 | 48 | VFIO_DEVICE_TYPE_CCW = 2, |
e2c7d025 EA |
49 | }; |
50 | ||
db0da029 AW |
51 | typedef struct VFIOMmap { |
52 | MemoryRegion mem; | |
53 | void *mmap; | |
54 | off_t offset; | |
55 | size_t size; | |
56 | } VFIOMmap; | |
57 | ||
e2c7d025 EA |
58 | typedef struct VFIORegion { |
59 | struct VFIODevice *vbasedev; | |
60 | off_t fd_offset; /* offset of region within device fd */ | |
db0da029 | 61 | MemoryRegion *mem; /* slow, read/write access */ |
e2c7d025 EA |
62 | size_t size; |
63 | uint32_t flags; /* VFIO region flags (rd/wr/mmap) */ | |
db0da029 AW |
64 | uint32_t nr_mmaps; |
65 | VFIOMmap *mmaps; | |
e2c7d025 EA |
66 | uint8_t nr; /* cache the region number for debug */ |
67 | } VFIORegion; | |
68 | ||
69 | typedef struct VFIOAddressSpace { | |
70 | AddressSpace *as; | |
71 | QLIST_HEAD(, VFIOContainer) containers; | |
72 | QLIST_ENTRY(VFIOAddressSpace) list; | |
73 | } VFIOAddressSpace; | |
74 | ||
75 | struct VFIOGroup; | |
76 | ||
e2c7d025 EA |
77 | typedef struct VFIOContainer { |
78 | VFIOAddressSpace *space; | |
79 | int fd; /* /dev/vfio/vfio, empowered by the attached groups */ | |
ee0bf0e5 | 80 | MemoryListener listener; |
318f67ce AK |
81 | MemoryListener prereg_listener; |
82 | unsigned iommu_type; | |
ee0bf0e5 DG |
83 | int error; |
84 | bool initialized; | |
3898aad3 DG |
85 | /* |
86 | * This assumes the host IOMMU can support only a single | |
87 | * contiguous IOVA window. We may need to generalize that in | |
88 | * future | |
89 | */ | |
e2c7d025 | 90 | QLIST_HEAD(, VFIOGuestIOMMU) giommu_list; |
f4ec5e26 | 91 | QLIST_HEAD(, VFIOHostDMAWindow) hostwin_list; |
e2c7d025 EA |
92 | QLIST_HEAD(, VFIOGroup) group_list; |
93 | QLIST_ENTRY(VFIOContainer) next; | |
94 | } VFIOContainer; | |
95 | ||
96 | typedef struct VFIOGuestIOMMU { | |
97 | VFIOContainer *container; | |
3df9d748 | 98 | IOMMUMemoryRegion *iommu; |
d78c19b5 | 99 | hwaddr iommu_offset; |
cdb30812 | 100 | IOMMUNotifier n; |
e2c7d025 EA |
101 | QLIST_ENTRY(VFIOGuestIOMMU) giommu_next; |
102 | } VFIOGuestIOMMU; | |
103 | ||
f4ec5e26 AK |
104 | typedef struct VFIOHostDMAWindow { |
105 | hwaddr min_iova; | |
106 | hwaddr max_iova; | |
107 | uint64_t iova_pgsizes; | |
108 | QLIST_ENTRY(VFIOHostDMAWindow) hostwin_next; | |
109 | } VFIOHostDMAWindow; | |
110 | ||
e2c7d025 EA |
111 | typedef struct VFIODeviceOps VFIODeviceOps; |
112 | ||
113 | typedef struct VFIODevice { | |
114 | QLIST_ENTRY(VFIODevice) next; | |
115 | struct VFIOGroup *group; | |
7df9381b | 116 | char *sysfsdev; |
e2c7d025 | 117 | char *name; |
7da624e2 | 118 | DeviceState *dev; |
e2c7d025 EA |
119 | int fd; |
120 | int type; | |
121 | bool reset_works; | |
122 | bool needs_reset; | |
5e15d79b | 123 | bool no_mmap; |
e2c7d025 EA |
124 | VFIODeviceOps *ops; |
125 | unsigned int num_irqs; | |
126 | unsigned int num_regions; | |
127 | unsigned int flags; | |
128 | } VFIODevice; | |
129 | ||
130 | struct VFIODeviceOps { | |
131 | void (*vfio_compute_needs_reset)(VFIODevice *vdev); | |
132 | int (*vfio_hot_reset_multi)(VFIODevice *vdev); | |
133 | void (*vfio_eoi)(VFIODevice *vdev); | |
e2c7d025 EA |
134 | }; |
135 | ||
136 | typedef struct VFIOGroup { | |
137 | int fd; | |
138 | int groupid; | |
139 | VFIOContainer *container; | |
140 | QLIST_HEAD(, VFIODevice) device_list; | |
141 | QLIST_ENTRY(VFIOGroup) next; | |
142 | QLIST_ENTRY(VFIOGroup) container_next; | |
143 | } VFIOGroup; | |
144 | ||
145 | void vfio_put_base_device(VFIODevice *vbasedev); | |
146 | void vfio_disable_irqindex(VFIODevice *vbasedev, int index); | |
147 | void vfio_unmask_single_irqindex(VFIODevice *vbasedev, int index); | |
148 | void vfio_mask_single_irqindex(VFIODevice *vbasedev, int index); | |
149 | void vfio_region_write(void *opaque, hwaddr addr, | |
150 | uint64_t data, unsigned size); | |
151 | uint64_t vfio_region_read(void *opaque, | |
152 | hwaddr addr, unsigned size); | |
db0da029 AW |
153 | int vfio_region_setup(Object *obj, VFIODevice *vbasedev, VFIORegion *region, |
154 | int index, const char *name); | |
155 | int vfio_region_mmap(VFIORegion *region); | |
156 | void vfio_region_mmaps_set_enabled(VFIORegion *region, bool enabled); | |
157 | void vfio_region_exit(VFIORegion *region); | |
158 | void vfio_region_finalize(VFIORegion *region); | |
e2c7d025 | 159 | void vfio_reset_handler(void *opaque); |
1b808d5b | 160 | VFIOGroup *vfio_get_group(int groupid, AddressSpace *as, Error **errp); |
e2c7d025 EA |
161 | void vfio_put_group(VFIOGroup *group); |
162 | int vfio_get_device(VFIOGroup *group, const char *name, | |
59f7d674 | 163 | VFIODevice *vbasedev, Error **errp); |
e2c7d025 EA |
164 | |
165 | extern const MemoryRegionOps vfio_region_ops; | |
e2c7d025 EA |
166 | extern QLIST_HEAD(vfio_group_head, VFIOGroup) vfio_group_list; |
167 | extern QLIST_HEAD(vfio_as_head, VFIOAddressSpace) vfio_address_spaces; | |
168 | ||
46900226 AW |
169 | #ifdef CONFIG_LINUX |
170 | int vfio_get_region_info(VFIODevice *vbasedev, int index, | |
171 | struct vfio_region_info **info); | |
e61a424f AW |
172 | int vfio_get_dev_region_info(VFIODevice *vbasedev, uint32_t type, |
173 | uint32_t subtype, struct vfio_region_info **info); | |
46900226 | 174 | #endif |
318f67ce AK |
175 | extern const MemoryListener vfio_prereg_listener; |
176 | ||
2e4109de AK |
177 | int vfio_spapr_create_window(VFIOContainer *container, |
178 | MemoryRegionSection *section, | |
179 | hwaddr *pgsize); | |
180 | int vfio_spapr_remove_window(VFIOContainer *container, | |
181 | hwaddr offset_within_address_space); | |
182 | ||
175de524 | 183 | #endif /* HW_VFIO_VFIO_COMMON_H */ |