@@ -37,112 +37,7 @@
#include "hw/pci/pci.h"
#include "hw/pci/msi.h"
#include "kvm_i386.h"
-
-#define MSIX_PAGE_SIZE 0x1000
-
-/* From linux/ioport.h */
-#define IORESOURCE_IO 0x00000100 /* Resource type */
-#define IORESOURCE_MEM 0x00000200
-#define IORESOURCE_IRQ 0x00000400
-#define IORESOURCE_DMA 0x00000800
-#define IORESOURCE_PREFETCH 0x00002000 /* No side effects */
-#define IORESOURCE_MEM_64 0x00100000
-
-//#define DEVICE_ASSIGNMENT_DEBUG
-
-#ifdef DEVICE_ASSIGNMENT_DEBUG
-#define DEBUG(fmt, ...) \
- do { \
- fprintf(stderr, "%s: " fmt, __func__ , __VA_ARGS__); \
- } while (0)
-#else
-#define DEBUG(fmt, ...)
-#endif
-
-typedef struct PCIRegion {
- int type; /* Memory or port I/O */
- int valid;
- uint64_t base_addr;
- uint64_t size; /* size of the region */
- int resource_fd;
-} PCIRegion;
-
-typedef struct PCIDevRegions {
- uint8_t bus, dev, func; /* Bus inside domain, device and function */
- int irq; /* IRQ number */
- uint16_t region_number; /* number of active regions */
-
- /* Port I/O or MMIO Regions */
- PCIRegion regions[PCI_NUM_REGIONS - 1];
- int config_fd;
-} PCIDevRegions;
-
-typedef struct AssignedDevRegion {
- MemoryRegion container;
- MemoryRegion real_iomem;
- union {
- uint8_t *r_virtbase; /* mmapped access address for memory regions */
- uint32_t r_baseport; /* the base guest port for I/O regions */
- } u;
- pcibus_t e_size; /* emulated size of region in bytes */
- pcibus_t r_size; /* real size of region in bytes */
- PCIRegion *region;
-} AssignedDevRegion;
-
-#define ASSIGNED_DEVICE_PREFER_MSI_BIT 0
-#define ASSIGNED_DEVICE_SHARE_INTX_BIT 1
-
-#define ASSIGNED_DEVICE_PREFER_MSI_MASK (1 << ASSIGNED_DEVICE_PREFER_MSI_BIT)
-#define ASSIGNED_DEVICE_SHARE_INTX_MASK (1 << ASSIGNED_DEVICE_SHARE_INTX_BIT)
-
-typedef struct MSIXTableEntry {
- uint32_t addr_lo;
- uint32_t addr_hi;
- uint32_t data;
- uint32_t ctrl;
-} MSIXTableEntry;
-
-typedef enum AssignedIRQType {
- ASSIGNED_IRQ_NONE = 0,
- ASSIGNED_IRQ_INTX_HOST_INTX,
- ASSIGNED_IRQ_INTX_HOST_MSI,
- ASSIGNED_IRQ_MSI,
- ASSIGNED_IRQ_MSIX
-} AssignedIRQType;
-
-typedef struct AssignedDevice {
- PCIDevice dev;
- PCIHostDeviceAddress host;
- uint32_t dev_id;
- uint32_t features;
- int intpin;
- AssignedDevRegion v_addrs[PCI_NUM_REGIONS - 1];
- PCIDevRegions real_device;
- PCIINTxRoute intx_route;
- AssignedIRQType assigned_irq_type;
- struct {
-#define ASSIGNED_DEVICE_CAP_MSI (1 << 0)
-#define ASSIGNED_DEVICE_CAP_MSIX (1 << 1)
- uint32_t available;
-#define ASSIGNED_DEVICE_MSI_ENABLED (1 << 0)
-#define ASSIGNED_DEVICE_MSIX_ENABLED (1 << 1)
-#define ASSIGNED_DEVICE_MSIX_MASKED (1 << 2)
- uint32_t state;
- } cap;
- uint8_t emulate_config_read[PCI_CONFIG_SPACE_SIZE];
- uint8_t emulate_config_write[PCI_CONFIG_SPACE_SIZE];
- int msi_virq_nr;
- int *msi_virq;
- MSIXTableEntry *msix_table;
- hwaddr msix_table_addr;
- uint16_t msix_max;
- MemoryRegion mmio;
- char *configfd_name;
- int32_t bootindex;
-} AssignedDevice;
-
-#define TYPE_PCI_ASSIGN "kvm-pci-assign"
-#define PCI_ASSIGN(obj) OBJECT_CHECK(AssignedDevice, (obj), TYPE_PCI_ASSIGN)
+#include "pci-assign.h"
static void assigned_dev_update_irq_routing(PCIDevice *dev);
@@ -1044,7 +939,7 @@ static bool assigned_dev_msix_masked(MSIXTableEntry *entry)
* sure the physical MSI-X state tracks the guest's view, which is important
* for some VF/PF and PF/fw communication channels.
*/
-static bool assigned_dev_msix_skipped(MSIXTableEntry *entry)
+bool assigned_dev_msix_skipped(MSIXTableEntry *entry)
{
return !entry->data;
}
@@ -1114,7 +1009,7 @@ static int assigned_dev_update_msix_mmio(PCIDevice *pci_dev)
return r;
}
-static void assigned_dev_update_msix(PCIDevice *pci_dev)
+void assigned_dev_update_msix(PCIDevice *pci_dev)
{
AssignedDevice *assigned_dev = PCI_ASSIGN(pci_dev);
uint16_t ctrl_word = pci_get_word(pci_dev->config + pci_dev->msix_cap +
new file mode 100644
@@ -0,0 +1,109 @@
+#define MSIX_PAGE_SIZE 0x1000
+
+/* From linux/ioport.h */
+#define IORESOURCE_IO 0x00000100 /* Resource type */
+#define IORESOURCE_MEM 0x00000200
+#define IORESOURCE_IRQ 0x00000400
+#define IORESOURCE_DMA 0x00000800
+#define IORESOURCE_PREFETCH 0x00002000 /* No side effects */
+#define IORESOURCE_MEM_64 0x00100000
+
+//#define DEVICE_ASSIGNMENT_DEBUG
+
+#ifdef DEVICE_ASSIGNMENT_DEBUG
+#define DEBUG(fmt, ...) \
+ do { \
+ fprintf(stderr, "%s: " fmt, __func__ , __VA_ARGS__); \
+ } while (0)
+#else
+#define DEBUG(fmt, ...)
+#endif
+
+typedef struct PCIRegion {
+ int type; /* Memory or port I/O */
+ int valid;
+ uint64_t base_addr;
+ uint64_t size; /* size of the region */
+ int resource_fd;
+} PCIRegion;
+
+typedef struct PCIDevRegions {
+ uint8_t bus, dev, func; /* Bus inside domain, device and function */
+ int irq; /* IRQ number */
+ uint16_t region_number; /* number of active regions */
+
+ /* Port I/O or MMIO Regions */
+ PCIRegion regions[PCI_NUM_REGIONS - 1];
+ int config_fd;
+} PCIDevRegions;
+
+typedef struct AssignedDevRegion {
+ MemoryRegion container;
+ MemoryRegion real_iomem;
+ union {
+ uint8_t *r_virtbase; /* mmapped access address for memory regions */
+ uint32_t r_baseport; /* the base guest port for I/O regions */
+ } u;
+ pcibus_t e_size; /* emulated size of region in bytes */
+ pcibus_t r_size; /* real size of region in bytes */
+ PCIRegion *region;
+} AssignedDevRegion;
+
+#define ASSIGNED_DEVICE_PREFER_MSI_BIT 0
+#define ASSIGNED_DEVICE_SHARE_INTX_BIT 1
+
+#define ASSIGNED_DEVICE_PREFER_MSI_MASK (1 << ASSIGNED_DEVICE_PREFER_MSI_BIT)
+#define ASSIGNED_DEVICE_SHARE_INTX_MASK (1 << ASSIGNED_DEVICE_SHARE_INTX_BIT)
+
+typedef struct MSIXTableEntry {
+ uint32_t addr_lo;
+ uint32_t addr_hi;
+ uint32_t data;
+ uint32_t ctrl;
+} MSIXTableEntry;
+
+typedef enum AssignedIRQType {
+ ASSIGNED_IRQ_NONE = 0,
+ ASSIGNED_IRQ_INTX_HOST_INTX,
+ ASSIGNED_IRQ_INTX_HOST_MSI,
+ ASSIGNED_IRQ_MSI,
+ ASSIGNED_IRQ_MSIX
+} AssignedIRQType;
+
+typedef struct AssignedDevice {
+ PCIDevice dev;
+ PCIHostDeviceAddress host;
+ uint32_t dev_id;
+ uint32_t features;
+ int intpin;
+ AssignedDevRegion v_addrs[PCI_NUM_REGIONS - 1];
+ PCIDevRegions real_device;
+ PCIINTxRoute intx_route;
+ AssignedIRQType assigned_irq_type;
+ struct {
+#define ASSIGNED_DEVICE_CAP_MSI (1 << 0)
+#define ASSIGNED_DEVICE_CAP_MSIX (1 << 1)
+ uint32_t available;
+#define ASSIGNED_DEVICE_MSI_ENABLED (1 << 0)
+#define ASSIGNED_DEVICE_MSIX_ENABLED (1 << 1)
+#define ASSIGNED_DEVICE_MSIX_MASKED (1 << 2)
+ uint32_t state;
+ } cap;
+ uint8_t emulate_config_read[PCI_CONFIG_SPACE_SIZE];
+ uint8_t emulate_config_write[PCI_CONFIG_SPACE_SIZE];
+ int msi_virq_nr;
+ int *msi_virq;
+ MSIXTableEntry *msix_table;
+ hwaddr msix_table_addr;
+ uint16_t msix_max;
+ MemoryRegion mmio;
+ char *configfd_name;
+ int32_t bootindex;
+} AssignedDevice;
+
+#define TYPE_PCI_ASSIGN "kvm-pci-assign"
+#define PCI_ASSIGN(obj) OBJECT_CHECK(AssignedDevice, (obj), TYPE_PCI_ASSIGN)
+
+bool assigned_dev_msix_skipped(MSIXTableEntry *entry);
+void assigned_dev_update_msix(PCIDevice *pci_dev);
+
Signed-off-by: Lan Tianyu <tianyu.lan@intel.com> --- hw/i386/kvm/pci-assign.c | 111 ++--------------------------------------------- hw/i386/kvm/pci-assign.h | 109 ++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 112 insertions(+), 108 deletions(-) create mode 100644 hw/i386/kvm/pci-assign.h