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 "qemu-common.h" 16 #include "exec/memory.h" 17 #include "hw/pci/pci.h" 18 #include "hw/vfio/vfio-common.h" 19 #include "qemu/event_notifier.h" 20 #include "qemu/queue.h" 21 #include "qemu/timer.h" 22 23 #define PCI_ANY_ID (~0) 24 25 struct VFIOPCIDevice; 26 27 typedef struct VFIOQuirk { 28 QLIST_ENTRY(VFIOQuirk) next; 29 void *data; 30 int nr_mem; 31 MemoryRegion *mem; 32 } VFIOQuirk; 33 34 typedef struct VFIOBAR { 35 VFIORegion region; 36 bool ioport; 37 bool mem64; 38 QLIST_HEAD(, VFIOQuirk) quirks; 39 } VFIOBAR; 40 41 typedef struct VFIOVGARegion { 42 MemoryRegion mem; 43 off_t offset; 44 int nr; 45 QLIST_HEAD(, VFIOQuirk) quirks; 46 } VFIOVGARegion; 47 48 typedef struct VFIOVGA { 49 off_t fd_offset; 50 int fd; 51 VFIOVGARegion region[QEMU_PCI_VGA_NUM_REGIONS]; 52 } VFIOVGA; 53 54 typedef struct VFIOINTx { 55 bool pending; /* interrupt pending */ 56 bool kvm_accel; /* set when QEMU bypass through KVM enabled */ 57 uint8_t pin; /* which pin to pull for qemu_set_irq */ 58 EventNotifier interrupt; /* eventfd triggered on interrupt */ 59 EventNotifier unmask; /* eventfd for unmask on QEMU bypass */ 60 PCIINTxRoute route; /* routing info for QEMU bypass */ 61 uint32_t mmap_timeout; /* delay to re-enable mmaps after interrupt */ 62 QEMUTimer *mmap_timer; /* enable mmaps after periods w/o interrupts */ 63 } VFIOINTx; 64 65 typedef struct VFIOMSIVector { 66 /* 67 * Two interrupt paths are configured per vector. The first, is only used 68 * for interrupts injected via QEMU. This is typically the non-accel path, 69 * but may also be used when we want QEMU to handle masking and pending 70 * bits. The KVM path bypasses QEMU and is therefore higher performance, 71 * but requires masking at the device. virq is used to track the MSI route 72 * through KVM, thus kvm_interrupt is only available when virq is set to a 73 * valid (>= 0) value. 74 */ 75 EventNotifier interrupt; 76 EventNotifier kvm_interrupt; 77 struct VFIOPCIDevice *vdev; /* back pointer to device */ 78 int virq; 79 bool use; 80 } VFIOMSIVector; 81 82 enum { 83 VFIO_INT_NONE = 0, 84 VFIO_INT_INTx = 1, 85 VFIO_INT_MSI = 2, 86 VFIO_INT_MSIX = 3, 87 }; 88 89 /* Cache of MSI-X setup plus extra mmap and memory region for split BAR map */ 90 typedef struct VFIOMSIXInfo { 91 uint8_t table_bar; 92 uint8_t pba_bar; 93 uint16_t entries; 94 uint32_t table_offset; 95 uint32_t pba_offset; 96 MemoryRegion mmap_mem; 97 void *mmap; 98 } VFIOMSIXInfo; 99 100 typedef struct VFIOPCIDevice { 101 PCIDevice pdev; 102 VFIODevice vbasedev; 103 VFIOINTx intx; 104 unsigned int config_size; 105 uint8_t *emulated_config_bits; /* QEMU emulated bits, little-endian */ 106 off_t config_offset; /* Offset of config space region within device fd */ 107 unsigned int rom_size; 108 off_t rom_offset; /* Offset of ROM region within device fd */ 109 void *rom; 110 int msi_cap_size; 111 VFIOMSIVector *msi_vectors; 112 VFIOMSIXInfo *msix; 113 int nr_vectors; /* Number of MSI/MSIX vectors currently in use */ 114 int interrupt; /* Current interrupt type */ 115 VFIOBAR bars[PCI_NUM_REGIONS - 1]; /* No ROM */ 116 VFIOVGA vga; /* 0xa0000, 0x3b0, 0x3c0 */ 117 PCIHostDeviceAddress host; 118 EventNotifier err_notifier; 119 EventNotifier req_notifier; 120 int (*resetfn)(struct VFIOPCIDevice *); 121 uint32_t vendor_id; 122 uint32_t device_id; 123 uint32_t sub_vendor_id; 124 uint32_t sub_device_id; 125 uint32_t features; 126 #define VFIO_FEATURE_ENABLE_VGA_BIT 0 127 #define VFIO_FEATURE_ENABLE_VGA (1 << VFIO_FEATURE_ENABLE_VGA_BIT) 128 #define VFIO_FEATURE_ENABLE_REQ_BIT 1 129 #define VFIO_FEATURE_ENABLE_REQ (1 << VFIO_FEATURE_ENABLE_REQ_BIT) 130 int32_t bootindex; 131 uint8_t pm_cap; 132 bool has_vga; 133 bool pci_aer; 134 bool req_enabled; 135 bool has_flr; 136 bool has_pm_reset; 137 bool rom_read_failed; 138 bool no_kvm_intx; 139 bool no_kvm_msi; 140 bool no_kvm_msix; 141 } VFIOPCIDevice; 142 143 uint32_t vfio_pci_read_config(PCIDevice *pdev, uint32_t addr, int len); 144 void vfio_pci_write_config(PCIDevice *pdev, 145 uint32_t addr, uint32_t val, int len); 146 147 uint64_t vfio_vga_read(void *opaque, hwaddr addr, unsigned size); 148 void vfio_vga_write(void *opaque, hwaddr addr, uint64_t data, unsigned size); 149 150 bool vfio_blacklist_opt_rom(VFIOPCIDevice *vdev); 151 void vfio_vga_quirk_setup(VFIOPCIDevice *vdev); 152 void vfio_vga_quirk_teardown(VFIOPCIDevice *vdev); 153 void vfio_vga_quirk_free(VFIOPCIDevice *vdev); 154 void vfio_bar_quirk_setup(VFIOPCIDevice *vdev, int nr); 155 void vfio_bar_quirk_teardown(VFIOPCIDevice *vdev, int nr); 156 void vfio_bar_quirk_free(VFIOPCIDevice *vdev, int nr); 157 void vfio_setup_resetfn_quirk(VFIOPCIDevice *vdev); 158 159 #endif /* HW_VFIO_VFIO_PCI_H */ 160