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