1 | /* |
2 | * vfio based device assignment support - PCI devices |
3 | * |
4 | * Copyright Red Hat, Inc. 2012-2015 |
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 | #ifndef HW_VFIO_VFIO_PCI_H |
13 | #define HW_VFIO_VFIO_PCI_H |
14 | |
15 | #include "exec/memory.h" |
16 | #include "hw/pci/pci.h" |
17 | #include "hw/vfio/vfio-common.h" |
18 | #include "qemu/event_notifier.h" |
19 | #include "qemu/queue.h" |
20 | #include "qemu/timer.h" |
21 | |
22 | #define PCI_ANY_ID (~0) |
23 | |
24 | struct VFIOPCIDevice; |
25 | |
26 | typedef struct VFIOIOEventFD { |
27 | QLIST_ENTRY(VFIOIOEventFD) next; |
28 | MemoryRegion *mr; |
29 | hwaddr addr; |
30 | unsigned size; |
31 | uint64_t data; |
32 | EventNotifier e; |
33 | VFIORegion *region; |
34 | hwaddr region_addr; |
35 | bool dynamic; /* Added runtime, removed on device reset */ |
36 | bool vfio; |
37 | } VFIOIOEventFD; |
38 | |
39 | typedef struct VFIOQuirk { |
40 | QLIST_ENTRY(VFIOQuirk) next; |
41 | void *data; |
42 | QLIST_HEAD(, VFIOIOEventFD) ioeventfds; |
43 | int nr_mem; |
44 | MemoryRegion *mem; |
45 | void (*reset)(struct VFIOPCIDevice *vdev, struct VFIOQuirk *quirk); |
46 | } VFIOQuirk; |
47 | |
48 | typedef struct VFIOBAR { |
49 | VFIORegion region; |
50 | MemoryRegion *mr; |
51 | size_t size; |
52 | uint8_t type; |
53 | bool ioport; |
54 | bool mem64; |
55 | QLIST_HEAD(, VFIOQuirk) quirks; |
56 | } VFIOBAR; |
57 | |
58 | typedef struct VFIOVGARegion { |
59 | MemoryRegion mem; |
60 | off_t offset; |
61 | int nr; |
62 | QLIST_HEAD(, VFIOQuirk) quirks; |
63 | } VFIOVGARegion; |
64 | |
65 | typedef struct VFIOVGA { |
66 | off_t fd_offset; |
67 | int fd; |
68 | VFIOVGARegion region[QEMU_PCI_VGA_NUM_REGIONS]; |
69 | } VFIOVGA; |
70 | |
71 | typedef struct VFIOINTx { |
72 | bool pending; /* interrupt pending */ |
73 | bool kvm_accel; /* set when QEMU bypass through KVM enabled */ |
74 | uint8_t pin; /* which pin to pull for qemu_set_irq */ |
75 | EventNotifier interrupt; /* eventfd triggered on interrupt */ |
76 | EventNotifier unmask; /* eventfd for unmask on QEMU bypass */ |
77 | PCIINTxRoute route; /* routing info for QEMU bypass */ |
78 | uint32_t mmap_timeout; /* delay to re-enable mmaps after interrupt */ |
79 | QEMUTimer *mmap_timer; /* enable mmaps after periods w/o interrupts */ |
80 | } VFIOINTx; |
81 | |
82 | typedef struct VFIOMSIVector { |
83 | /* |
84 | * Two interrupt paths are configured per vector. The first, is only used |
85 | * for interrupts injected via QEMU. This is typically the non-accel path, |
86 | * but may also be used when we want QEMU to handle masking and pending |
87 | * bits. The KVM path bypasses QEMU and is therefore higher performance, |
88 | * but requires masking at the device. virq is used to track the MSI route |
89 | * through KVM, thus kvm_interrupt is only available when virq is set to a |
90 | * valid (>= 0) value. |
91 | */ |
92 | EventNotifier interrupt; |
93 | EventNotifier kvm_interrupt; |
94 | struct VFIOPCIDevice *vdev; /* back pointer to device */ |
95 | int virq; |
96 | bool use; |
97 | } VFIOMSIVector; |
98 | |
99 | enum { |
100 | VFIO_INT_NONE = 0, |
101 | VFIO_INT_INTx = 1, |
102 | VFIO_INT_MSI = 2, |
103 | VFIO_INT_MSIX = 3, |
104 | }; |
105 | |
106 | /* Cache of MSI-X setup */ |
107 | typedef struct VFIOMSIXInfo { |
108 | uint8_t table_bar; |
109 | uint8_t pba_bar; |
110 | uint16_t entries; |
111 | uint32_t table_offset; |
112 | uint32_t pba_offset; |
113 | unsigned long *pending; |
114 | } VFIOMSIXInfo; |
115 | |
116 | typedef struct VFIOPCIDevice { |
117 | PCIDevice pdev; |
118 | VFIODevice vbasedev; |
119 | VFIOINTx intx; |
120 | unsigned int config_size; |
121 | uint8_t *emulated_config_bits; /* QEMU emulated bits, little-endian */ |
122 | off_t config_offset; /* Offset of config space region within device fd */ |
123 | unsigned int rom_size; |
124 | off_t rom_offset; /* Offset of ROM region within device fd */ |
125 | void *rom; |
126 | int msi_cap_size; |
127 | VFIOMSIVector *msi_vectors; |
128 | VFIOMSIXInfo *msix; |
129 | int nr_vectors; /* Number of MSI/MSIX vectors currently in use */ |
130 | int interrupt; /* Current interrupt type */ |
131 | VFIOBAR bars[PCI_NUM_REGIONS - 1]; /* No ROM */ |
132 | VFIOVGA *vga; /* 0xa0000, 0x3b0, 0x3c0 */ |
133 | void *igd_opregion; |
134 | PCIHostDeviceAddress host; |
135 | EventNotifier err_notifier; |
136 | EventNotifier req_notifier; |
137 | int (*resetfn)(struct VFIOPCIDevice *); |
138 | uint32_t vendor_id; |
139 | uint32_t device_id; |
140 | uint32_t sub_vendor_id; |
141 | uint32_t sub_device_id; |
142 | uint32_t features; |
143 | #define VFIO_FEATURE_ENABLE_VGA_BIT 0 |
144 | #define VFIO_FEATURE_ENABLE_VGA (1 << VFIO_FEATURE_ENABLE_VGA_BIT) |
145 | #define VFIO_FEATURE_ENABLE_REQ_BIT 1 |
146 | #define VFIO_FEATURE_ENABLE_REQ (1 << VFIO_FEATURE_ENABLE_REQ_BIT) |
147 | #define VFIO_FEATURE_ENABLE_IGD_OPREGION_BIT 2 |
148 | #define VFIO_FEATURE_ENABLE_IGD_OPREGION \ |
149 | (1 << VFIO_FEATURE_ENABLE_IGD_OPREGION_BIT) |
150 | OnOffAuto display; |
151 | uint32_t display_xres; |
152 | uint32_t display_yres; |
153 | int32_t bootindex; |
154 | uint32_t igd_gms; |
155 | OffAutoPCIBAR msix_relo; |
156 | uint8_t pm_cap; |
157 | uint8_t nv_gpudirect_clique; |
158 | bool pci_aer; |
159 | bool req_enabled; |
160 | bool has_flr; |
161 | bool has_pm_reset; |
162 | bool rom_read_failed; |
163 | bool no_kvm_intx; |
164 | bool no_kvm_msi; |
165 | bool no_kvm_msix; |
166 | bool no_geforce_quirks; |
167 | bool no_kvm_ioeventfd; |
168 | bool no_vfio_ioeventfd; |
169 | bool enable_ramfb; |
170 | VFIODisplay *dpy; |
171 | } VFIOPCIDevice; |
172 | |
173 | uint32_t vfio_pci_read_config(PCIDevice *pdev, uint32_t addr, int len); |
174 | void vfio_pci_write_config(PCIDevice *pdev, |
175 | uint32_t addr, uint32_t val, int len); |
176 | |
177 | uint64_t vfio_vga_read(void *opaque, hwaddr addr, unsigned size); |
178 | void vfio_vga_write(void *opaque, hwaddr addr, uint64_t data, unsigned size); |
179 | |
180 | bool vfio_blacklist_opt_rom(VFIOPCIDevice *vdev); |
181 | void vfio_vga_quirk_setup(VFIOPCIDevice *vdev); |
182 | void vfio_vga_quirk_exit(VFIOPCIDevice *vdev); |
183 | void vfio_vga_quirk_finalize(VFIOPCIDevice *vdev); |
184 | void vfio_bar_quirk_setup(VFIOPCIDevice *vdev, int nr); |
185 | void vfio_bar_quirk_exit(VFIOPCIDevice *vdev, int nr); |
186 | void vfio_bar_quirk_finalize(VFIOPCIDevice *vdev, int nr); |
187 | void vfio_setup_resetfn_quirk(VFIOPCIDevice *vdev); |
188 | int vfio_add_virt_caps(VFIOPCIDevice *vdev, Error **errp); |
189 | void vfio_quirk_reset(VFIOPCIDevice *vdev); |
190 | |
191 | extern const PropertyInfo qdev_prop_nv_gpudirect_clique; |
192 | |
193 | int vfio_populate_vga(VFIOPCIDevice *vdev, Error **errp); |
194 | |
195 | int vfio_pci_igd_opregion_init(VFIOPCIDevice *vdev, |
196 | struct vfio_region_info *info, |
197 | Error **errp); |
198 | int vfio_pci_nvidia_v100_ram_init(VFIOPCIDevice *vdev, Error **errp); |
199 | int vfio_pci_nvlink2_init(VFIOPCIDevice *vdev, Error **errp); |
200 | |
201 | void vfio_display_reset(VFIOPCIDevice *vdev); |
202 | int vfio_display_probe(VFIOPCIDevice *vdev, Error **errp); |
203 | void vfio_display_finalize(VFIOPCIDevice *vdev); |
204 | |
205 | #endif /* HW_VFIO_VFIO_PCI_H */ |
206 | |